From d9afdbd1830c139507d494d78ed16e90a2f72fc8 Mon Sep 17 00:00:00 2001 From: oaq Date: Sat, 17 Jan 2026 10:12:13 +1100 Subject: [PATCH] reformat using clang-format except for app/qtapp/ --- app/consapp/convbin/convbin.c | 1299 +- app/consapp/pos2kml/pos2kml.c | 249 +- app/consapp/rnx2rtkp/rnx2rtkp.c | 412 +- app/consapp/rtkrcv/rtkrcv.c | 3286 ++--- app/consapp/rtkrcv/vt.c | 671 +- app/consapp/rtkrcv/vt.h | 47 +- app/consapp/str2str/str2str.c | 807 +- app/winapp/appcmn/aboutdlg.cpp | 29 +- app/winapp/appcmn/aboutdlg.h | 49 +- app/winapp/appcmn/cmdoptdlg.cpp | 132 +- app/winapp/appcmn/cmdoptdlg.h | 57 +- app/winapp/appcmn/confdlg.cpp | 7 +- app/winapp/appcmn/confdlg.h | 21 +- app/winapp/appcmn/console.cpp | 192 +- app/winapp/appcmn/console.h | 62 +- app/winapp/appcmn/fileoptdlg.cpp | 219 +- app/winapp/appcmn/fileoptdlg.h | 72 +- app/winapp/appcmn/freqdlg.cpp | 7 +- app/winapp/appcmn/freqdlg.h | 145 +- app/winapp/appcmn/ftpoptdlg.cpp | 170 +- app/winapp/appcmn/ftpoptdlg.h | 74 +- app/winapp/appcmn/glofcndlg.cpp | 155 +- app/winapp/appcmn/glofcndlg.h | 224 +- app/winapp/appcmn/gmview.cpp | 179 +- app/winapp/appcmn/gmview.h | 49 +- app/winapp/appcmn/graph.cpp | 1513 +-- app/winapp/appcmn/graph.h | 146 +- app/winapp/appcmn/keydlg.cpp | 51 +- app/winapp/appcmn/keydlg.h | 97 +- app/winapp/appcmn/maskoptdlg.cpp | 98 +- app/winapp/appcmn/maskoptdlg.h | 141 +- app/winapp/appcmn/mntpoptdlg.cpp | 73 +- app/winapp/appcmn/mntpoptdlg.h | 93 +- app/winapp/appcmn/refdlg.cpp | 460 +- app/winapp/appcmn/refdlg.h | 72 +- app/winapp/appcmn/serioptdlg.cpp | 149 +- app/winapp/appcmn/serioptdlg.h | 60 +- app/winapp/appcmn/tcpoptdlg.cpp | 290 +- app/winapp/appcmn/tcpoptdlg.h | 64 +- app/winapp/appcmn/timedlg.cpp | 44 +- app/winapp/appcmn/timedlg.h | 22 +- app/winapp/appcmn/tspandlg.cpp | 387 +- app/winapp/appcmn/tspandlg.h | 99 +- app/winapp/appcmn/viewer.cpp | 190 +- app/winapp/appcmn/viewer.h | 76 +- app/winapp/appcmn/vieweropt.cpp | 61 +- app/winapp/appcmn/vieweropt.h | 53 +- app/winapp/rtkconv/codeopt.cpp | 984 +- app/winapp/rtkconv/codeopt.h | 278 +- app/winapp/rtkconv/convmain.cpp | 2158 ++-- app/winapp/rtkconv/convmain.h | 383 +- app/winapp/rtkconv/convopt.cpp | 368 +- app/winapp/rtkconv/convopt.h | 184 +- app/winapp/rtkconv/rtkconv.cpp | 63 +- app/winapp/rtkconv/startdlg.cpp | 188 +- app/winapp/rtkconv/startdlg.h | 54 +- app/winapp/rtkget/getmain.cpp | 1715 ++- app/winapp/rtkget/getmain.h | 342 +- app/winapp/rtkget/getoptdlg.cpp | 71 +- app/winapp/rtkget/getoptdlg.h | 69 +- app/winapp/rtkget/rtkget.cpp | 69 +- app/winapp/rtkget/staoptdlg.cpp | 85 +- app/winapp/rtkget/staoptdlg.h | 41 +- app/winapp/rtklaunch/launchmain.cpp | 387 +- app/winapp/rtklaunch/launchmain.h | 127 +- app/winapp/rtklaunch/launchoptdlg.cpp | 50 +- app/winapp/rtklaunch/launchoptdlg.h | 29 +- app/winapp/rtklaunch/rtklaunch.cpp | 57 +- app/winapp/rtknavi/instrdlg.cpp | 644 +- app/winapp/rtknavi/instrdlg.h | 190 +- app/winapp/rtknavi/logstrdlg.cpp | 385 +- app/winapp/rtknavi/logstrdlg.h | 120 +- app/winapp/rtknavi/mapdlg.cpp | 799 +- app/winapp/rtknavi/mapdlg.h | 129 +- app/winapp/rtknavi/markdlg.cpp | 198 +- app/winapp/rtknavi/markdlg.h | 77 +- app/winapp/rtknavi/mondlg.cpp | 4131 +++--- app/winapp/rtknavi/mondlg.h | 178 +- app/winapp/rtknavi/navimain.cpp | 5402 ++++---- app/winapp/rtknavi/navimain.h | 528 +- app/winapp/rtknavi/naviopt.cpp | 2367 ++-- app/winapp/rtknavi/naviopt.h | 613 +- app/winapp/rtknavi/outstrdlg.cpp | 311 +- app/winapp/rtknavi/outstrdlg.h | 106 +- app/winapp/rtknavi/rcvoptdlg.cpp | 15 +- app/winapp/rtknavi/rcvoptdlg.h | 25 +- app/winapp/rtknavi/rtknavi.cpp | 106 +- app/winapp/rtkplot/conndlg.cpp | 359 +- app/winapp/rtkplot/conndlg.h | 110 +- app/winapp/rtkplot/fileseldlg.cpp | 82 +- app/winapp/rtkplot/fileseldlg.h | 69 +- app/winapp/rtkplot/mapoptdlg.cpp | 306 +- app/winapp/rtkplot/mapoptdlg.h | 107 +- app/winapp/rtkplot/mapview.cpp | 548 +- app/winapp/rtkplot/mapview.h | 113 +- app/winapp/rtkplot/mapviewopt.cpp | 81 +- app/winapp/rtkplot/mapviewopt.h | 65 +- app/winapp/rtkplot/plotcmn.cpp | 1051 +- app/winapp/rtkplot/plotdata.cpp | 2813 ++--- app/winapp/rtkplot/plotdraw.cpp | 4402 +++---- app/winapp/rtkplot/plotinfo.cpp | 777 +- app/winapp/rtkplot/plotmain.cpp | 5183 ++++---- app/winapp/rtkplot/plotmain.h | 1306 +- app/winapp/rtkplot/plotopt.cpp | 545 +- app/winapp/rtkplot/plotopt.h | 305 +- app/winapp/rtkplot/pntdlg.cpp | 179 +- app/winapp/rtkplot/pntdlg.h | 65 +- app/winapp/rtkplot/rtkplot.cpp | 128 +- app/winapp/rtkplot/skydlg.cpp | 507 +- app/winapp/rtkplot/skydlg.h | 209 +- app/winapp/rtkplot/vmapdlg.cpp | 318 +- app/winapp/rtkplot/vmapdlg.h | 188 +- app/winapp/rtkpost/kmzconv.cpp | 508 +- app/winapp/rtkpost/kmzconv.h | 168 +- app/winapp/rtkpost/postmain.cpp | 3181 +++-- app/winapp/rtkpost/postmain.h | 457 +- app/winapp/rtkpost/postopt.cpp | 1970 ++- app/winapp/rtkpost/postopt.h | 591 +- app/winapp/rtkpost/rtkpost.cpp | 65 +- app/winapp/srctblbrows/browsmain.cpp | 946 +- app/winapp/srctblbrows/browsmain.h | 193 +- app/winapp/srctblbrows/srctblbrows.cpp | 57 +- app/winapp/srctblbrows/staoptdlg.cpp | 85 +- app/winapp/srctblbrows/staoptdlg.h | 41 +- app/winapp/strsvr/convdlg.cpp | 73 +- app/winapp/strsvr/convdlg.h | 52 +- app/winapp/strsvr/mondlg.cpp | 321 +- app/winapp/strsvr/mondlg.h | 73 +- app/winapp/strsvr/strsvr.cpp | 72 +- app/winapp/strsvr/svrmain.cpp | 1512 ++- app/winapp/strsvr/svrmain.h | 362 +- app/winapp/strsvr/svroptdlg.cpp | 247 +- app/winapp/strsvr/svroptdlg.h | 134 +- src/convgpx.c | 315 +- src/convkml.c | 415 +- src/convrnx.c | 2704 ++-- src/datum.c | 228 +- src/download.c | 1620 ++- src/ephemeris.c | 1670 +-- src/geoid.c | 15308 ++++++++++++----------- src/gis.c | 649 +- src/ionex.c | 883 +- src/lambda.c | 485 +- src/options.c | 1048 +- src/pntpos.c | 1378 +- src/postpos.c | 2747 ++-- src/ppp.c | 2350 ++-- src/ppp_ar.c | 40 +- src/preceph.c | 1407 +-- src/rcv/binex.c | 2600 ++-- src/rcv/comnav.c | 2298 ++-- src/rcv/crescent.c | 1196 +- src/rcv/javad.c | 3575 +++--- src/rcv/novatel.c | 2967 ++--- src/rcv/nvs.c | 1166 +- src/rcv/rt17.c | 2893 +++-- src/rcv/septentrio.c | 6986 ++++++----- src/rcv/skytraq.c | 1733 +-- src/rcv/swiftnav.c | 378 +- src/rcv/tersus.c | 1659 +-- src/rcv/ublox.c | 4225 ++++--- src/rcv/unicore.c | 1989 +-- src/rcvraw.c | 3003 +++-- src/rinex.c | 5696 ++++----- src/rtcm.c | 781 +- src/rtcm2.c | 873 +- src/rtcm3.c | 5839 +++++---- src/rtcm3e.c | 6045 +++++---- src/rtkcmn.c | 7253 +++++------ src/rtklib.h | 2965 +++-- src/rtkpos.c | 4308 +++---- src/rtksvr.c | 2076 ++- src/sbas.c | 1676 +-- src/solution.c | 3492 +++--- src/stream.c | 5855 +++++---- src/streamsvr.c | 1504 +-- src/tides.c | 91 +- src/tle.c | 1094 +- src/trace.c | 328 +- test/utest/t_atmos.c | 268 +- test/utest/t_coord.c | 156 +- test/utest/t_corrperf.c | 62 +- test/utest/t_filter.c | 57 +- test/utest/t_geoid.c | 297 +- test/utest/t_gloeph.c | 392 +- test/utest/t_ionex.c | 415 +- test/utest/t_lambda.c | 174 +- test/utest/t_matrix.c | 332 +- test/utest/t_misc.c | 393 +- test/utest/t_ppp.c | 132 +- test/utest/t_preceph.c | 375 +- test/utest/t_rinex.c | 336 +- test/utest/t_time.c | 585 +- test/utest/t_tle.c | 232 +- util/gencrc/crc16.c | 57 +- util/gencrc/crc24.c | 64 +- util/gencrc/gencrc.c | 132 +- util/gencrc/genmsk.c | 65 +- util/gencrc/genxor.c | 27 +- util/geniono/estiono.c | 416 +- util/geniono/gengrid.c | 284 +- util/geniono/geniono.c | 696 +- util/geniono/genstec.c | 694 +- util/geniono/rcvdcb.c | 552 +- util/logfile/margelog.c | 88 +- util/rnx2rtcm/rnx2rtcm.c | 6 +- util/simobs/simobs.c | 756 +- util/testeph/diffeph.c | 430 +- util/testeph/dumpssr.c | 237 +- util/testlex/convlex.c | 50 +- util/testlex/dumplex.c | 71 +- util/testlex/dumpssr.c | 237 +- util/testlex/outlexion.c | 231 +- 213 files changed, 100309 insertions(+), 96584 deletions(-) diff --git a/app/consapp/convbin/convbin.c b/app/consapp/convbin/convbin.c index 4ee502563..b5eb77a23 100644 --- a/app/consapp/convbin/convbin.c +++ b/app/consapp/convbin/convbin.c @@ -1,345 +1,372 @@ /*------------------------------------------------------------------------------ -* convbin.c : convert receiver binary log file to rinex obs/nav, sbas messages -* -* Copyright (C) 2007-2020 by T.TAKASU, All rights reserved. -* -* options : -DWIN32 use windows file path separator -* -* version : $Revision: 1.1 $ $Date: 2008/07/17 22:13:04 $ -* history : 2008/06/22 1.0 new -* 2009/06/17 1.1 support glonass -* 2009/12/19 1.2 fix bug on disable of glonass -* fix bug on improper header for rtcm2 and rtcm3 -* 2010/07/18 1.3 add option -v, -t, -h, -x -* 2011/01/15 1.4 add option -ro, -hc, -hm, -hn, -ht, -ho, -hr, -ha, -* -hp, -hd, -y, -c, -q -* support gw10 and javad receiver, galileo, qzss -* support rinex file name convention -* 2012/10/22 1.5 add option -scan, -oi, -ot, -ol -* change default rinex version to 2.11 -* fix bug on default output directory (/ -> .) -* support galileo nav (LNAV) output -* support compass -* 2012/11/19 1.6 fix bug on setting code mask in rinex options -* 2013/02/18 1.7 support binex -* 2013/05/19 1.8 support auto format for file path with wild-card -* 2014/02/08 1.9 add option -span -trace -mask -* 2014/08/26 1.10 add Trimble RT17 support -* 2014/12/26 1.11 add option -nomask -* 2016/01/23 1.12 enable septentrio -* 2016/05/25 1.13 fix bug on initializing output file paths in -* convbin() -* 2016/06/09 1.14 fix bug on output file with -v 3.02 -* 2016/07/01 1.15 support log format CMR/CMR+ -* 2016/07/31 1.16 add option -halfc -* 2017/05/26 1.17 add input format tersus -* 2017/06/06 1.18 fix bug on output beidou and irnss nav files -* add option -tt -* 2018/10/10 1.19 default options are changed. -* scan input file: off - on -* number of freq: 2 -> 3 -* add option -noscan -* 2020/11/30 1.20 include NavIC in default systems -* force option -scan -* delete option -noscan -* suppress warnings -*-----------------------------------------------------------------------------*/ + * convbin.c : convert receiver binary log file to rinex obs/nav, sbas messages + * + * Copyright (C) 2007-2020 by T.TAKASU, All rights reserved. + * + * options : -DWIN32 use windows file path separator + * + * version : $Revision: 1.1 $ $Date: 2008/07/17 22:13:04 $ + * history : 2008/06/22 1.0 new + * 2009/06/17 1.1 support glonass + * 2009/12/19 1.2 fix bug on disable of glonass + * fix bug on improper header for rtcm2 and rtcm3 + * 2010/07/18 1.3 add option -v, -t, -h, -x + * 2011/01/15 1.4 add option -ro, -hc, -hm, -hn, -ht, -ho, -hr, -ha, + * -hp, -hd, -y, -c, -q + * support gw10 and javad receiver, galileo, qzss + * support rinex file name convention + * 2012/10/22 1.5 add option -scan, -oi, -ot, -ol + * change default rinex version to 2.11 + * fix bug on default output directory (/ -> .) + * support galileo nav (LNAV) output + * support compass + * 2012/11/19 1.6 fix bug on setting code mask in rinex options + * 2013/02/18 1.7 support binex + * 2013/05/19 1.8 support auto format for file path with wild-card + * 2014/02/08 1.9 add option -span -trace -mask + * 2014/08/26 1.10 add Trimble RT17 support + * 2014/12/26 1.11 add option -nomask + * 2016/01/23 1.12 enable septentrio + * 2016/05/25 1.13 fix bug on initializing output file paths in + * convbin() + * 2016/06/09 1.14 fix bug on output file with -v 3.02 + * 2016/07/01 1.15 support log format CMR/CMR+ + * 2016/07/31 1.16 add option -halfc + * 2017/05/26 1.17 add input format tersus + * 2017/06/06 1.18 fix bug on output beidou and irnss nav files + * add option -tt + * 2018/10/10 1.19 default options are changed. + * scan input file: off - on + * number of freq: 2 -> 3 + * add option -noscan + * 2020/11/30 1.20 include NavIC in default systems + * force option -scan + * delete option -noscan + * suppress warnings + *-----------------------------------------------------------------------------*/ #define _POSIX_C_SOURCE 199506 +#include #include #include #include -#include #include + #include "rtklib.h" -#define PRGNAME "CONVBIN" +#define PRGNAME "CONVBIN" #define TRACEFILE "convbin.trace" -#define NOUTFILE 9 /* number of output files */ +#define NOUTFILE 9 /* number of output files */ /* help text -----------------------------------------------------------------*/ -static const char *help[]={ -"", -" Synopsis", -"", -" convbin [option ...] file", -"", -" Description", -"", -" Convert RTCM, receiver raw data log and RINEX file to RINEX and SBAS/LEX", -" message file. SBAS message file complies with RTKLIB SBAS/LEX message", -" format. It supports the following messages or files:", -"", -" RTCM 2 : Type 1, 3, 9, 14, 16, 17, 18, 19, 22", -" RTCM 3 : Type 1002, 1004, 1005, 1006, 1010, 1012, 1019, 1020", -" Type 1071-1127 (MSM except for compact msg)", -" NovAtel OEMV/4,OEMStar : RANGECMPB, RANGEB, RAWEPHEMB, IONUTCB, RAWWASSFRAMEB", -" u-blox LEA-4T/5T/6T/8/9: RXM-RAW, RXM-RAWX, RXM-SFRB", -" Swift Piksi Multi : ", -" Hemisphere : BIN76, BIN80, BIN94, BIN95, BIN96", -" SkyTraq S1315F : msg0xDD, msg0xE0, msg0xDC", -" GW10 : msg0x08, msg0x03, msg0x27, msg0x20", -" Javad : [R*],[r*],[*R],[*r],[P*],[p*],[*P],[*p],[D*],[*d],", -" [E*],[*E],[F*],[TC],[GE],[NE],[EN],[QE],[UO],[IO],", -" [WD]", -" NVS : BINR", -" BINEX : big-endian, regular CRC, forward record (0xE2)", -" 0x01-01,0x01-02,0x01-03,0x01-04,0x01-06,0x7f-05", -" Trimble : RT17", -" Septentrio : SBF", -" RINEX : OBS, NAV, GNAV, HNAV, LNAV, QNAV", -"", -" Options [default]", -"", -" file input receiver binary log file", -" -ts y/m/d h:m:s start time [all]", -" -te y/m/d h:m:s end time [all]", -" -tr y/m/d h:m:s approximated time for RTCM", -" -ti tint observation data interval (s) [all]", -" -tt ttol observation data epoch tolerance (s) [0.005]", -" -span span time span (h) [all]", -" -r format log format type", -" rtcm2= RTCM 2", -" rtcm3= RTCM 3", -" nov = NovAtel OEM/4/V/6/7,OEMStar", -" ubx = ublox LEA-4T/5T/6T/7T/M8T/F9", -" sbp = Swift Navigation SBP", -" hemis= Hemisphere Eclipse/Crescent", -" stq = SkyTraq S1315F", -" javad= Javad GREIS", -" nvs = NVS NV08C BINR", -" binex= BINEX", -" rt17 = Trimble RT17", -" sbf = Septentrio SBF", -" unicore = Unicore binary data output", -" rinex= RINEX", -" -ro opt receiver options", -" -f freq number of frequencies [all]", -" -hc comment rinex header: comment line", -" -hm marker rinex header: marker name", -" -hn markno rinex header: marker number", -" -ht marktype rinex header: marker type", -" -ho observ rinex header: observer name and agency separated by /", -" -hr rec rinex header: receiver number, type and version separated by /", -" -ha ant rinex header: antenna number and type separated by /", -" -hp pos rinex header: approx position x/y/z separated by /", -" -hd delta rinex header: antenna delta h/e/n separated by /", -" -v ver rinex version [3.04]", -" -od include doppler frequency in rinex obs [off]", -" -os include snr in rinex obs [off]", -" -oi include iono correction in rinex nav header [off]", -" -ot include time correction in rinex nav header [off]", -" -ol include leap seconds in rinex nav header [off]", -" -halfc half-cycle ambiguity correction [off]", -" -sortsats sort observations by the RTKLib satellite index [off]", -" -mask [sig[,...]] signal mask(s) (sig={G|R|E|J|S|C|I}L{1C|1P|1W|...})", -" -nomask [sig[,...]] signal no mask (same as above)", -" -x sat exclude satellite", -" -y sys exclude systems (G:GPS,R:GLO,E:GAL,J:QZS,S:SBS,C:BDS,I:IRN)", -" --glofcn [-7 to 6][,...]] GLONASS fcn for R01 to R32", -" -d dir output directory [same as input file]", -" -c staid use RINEX file name convention with staid [off]", -" -o ofile output RINEX OBS file", -" -n nfile output RINEX NAV file", -" -g gfile output RINEX GNAV file", -" -h hfile output RINEX HNAV file", -" -q qfile output RINEX QNAV file", -" -l lfile output RINEX LNAV file", -" -b cfile output RINEX CNAV file", -" -i ifile output RINEX INAV file", -" -s sfile output SBAS message file", -" -trace level output trace level [off]", -"", -" If any output file specified, default output files (.obs,", -" .nav, .gnav, .hnav, .qnav, .lnav,", -" .cnav, .inav and .sbs) are used. To obtain week number info", -" for RTCM file, use -tr option to specify the approximated log start time.", -" Without -tr option, the program obtains the week number from the time-tag file", -" (if it exists) or the last modified time of the log file instead.", -"", -" If receiver type is not specified, type is recognized by the input", -" file extension as follows.", -" *.rtcm2 RTCM 2", -" *.rtcm3 RTCM 3", -" *.gps NovAtel OEM4/V/6/7,OEMStar", -" *.ubx u-blox LEA-4T/5T/6T/7T/M8T/F9", -" *.sbp Swift Navigation SBP", -" *.bin Hemisphere Eclipse/Crescent", -" *.stq SkyTraq S1315F", -" *.jps Javad GREIS", -" *.bnx,*binex BINEX", -" *.rt17 Trimble RT17", -" *.sbf Septentrio SBF", -" *.unc Unicore binary data output", -" *.obs,*.*o RINEX OBS", -" *.rnx RINEX OBS", -" *.nav,*.*n RINEX NAV", +static const char *help[] = { + "", + " Synopsis", + "", + " convbin [option ...] file", + "", + " Description", + "", + " Convert RTCM, receiver raw data log and RINEX file to RINEX and SBAS/LEX", + " message file. SBAS message file complies with RTKLIB SBAS/LEX message", + " format. It supports the following messages or files:", + "", + " RTCM 2 : Type 1, 3, 9, 14, 16, 17, 18, 19, 22", + " RTCM 3 : Type 1002, 1004, 1005, 1006, 1010, 1012, 1019, 1020", + " Type 1071-1127 (MSM except for compact msg)", + " NovAtel OEMV/4,OEMStar : RANGECMPB, RANGEB, RAWEPHEMB, IONUTCB, RAWWASSFRAMEB", + " u-blox LEA-4T/5T/6T/8/9: RXM-RAW, RXM-RAWX, RXM-SFRB", + " Swift Piksi Multi : ", + " Hemisphere : BIN76, BIN80, BIN94, BIN95, BIN96", + " SkyTraq S1315F : msg0xDD, msg0xE0, msg0xDC", + " GW10 : msg0x08, msg0x03, msg0x27, msg0x20", + " Javad : [R*],[r*],[*R],[*r],[P*],[p*],[*P],[*p],[D*],[*d],", + " [E*],[*E],[F*],[TC],[GE],[NE],[EN],[QE],[UO],[IO],", + " [WD]", + " NVS : BINR", + " BINEX : big-endian, regular CRC, forward record (0xE2)", + " 0x01-01,0x01-02,0x01-03,0x01-04,0x01-06,0x7f-05", + " Trimble : RT17", + " Septentrio : SBF", + " RINEX : OBS, NAV, GNAV, HNAV, LNAV, QNAV", + "", + " Options [default]", + "", + " file input receiver binary log file", + " -ts y/m/d h:m:s start time [all]", + " -te y/m/d h:m:s end time [all]", + " -tr y/m/d h:m:s approximated time for RTCM", + " -ti tint observation data interval (s) [all]", + " -tt ttol observation data epoch tolerance (s) [0.005]", + " -span span time span (h) [all]", + " -r format log format type", + " rtcm2= RTCM 2", + " rtcm3= RTCM 3", + " nov = NovAtel OEM/4/V/6/7,OEMStar", + " ubx = ublox LEA-4T/5T/6T/7T/M8T/F9", + " sbp = Swift Navigation SBP", + " hemis= Hemisphere Eclipse/Crescent", + " stq = SkyTraq S1315F", + " javad= Javad GREIS", + " nvs = NVS NV08C BINR", + " binex= BINEX", + " rt17 = Trimble RT17", + " sbf = Septentrio SBF", + " unicore = Unicore binary data output", + " rinex= RINEX", + " -ro opt receiver options", + " -f freq number of frequencies [all]", + " -hc comment rinex header: comment line", + " -hm marker rinex header: marker name", + " -hn markno rinex header: marker number", + " -ht marktype rinex header: marker type", + " -ho observ rinex header: observer name and agency separated by /", + " -hr rec rinex header: receiver number, type and version separated by /", + " -ha ant rinex header: antenna number and type separated by /", + " -hp pos rinex header: approx position x/y/z separated by /", + " -hd delta rinex header: antenna delta h/e/n separated by /", + " -v ver rinex version [3.04]", + " -od include doppler frequency in rinex obs [off]", + " -os include snr in rinex obs [off]", + " -oi include iono correction in rinex nav header [off]", + " -ot include time correction in rinex nav header [off]", + " -ol include leap seconds in rinex nav header [off]", + " -halfc half-cycle ambiguity correction [off]", + " -sortsats sort observations by the RTKLib satellite index [off]", + " -mask [sig[,...]] signal mask(s) (sig={G|R|E|J|S|C|I}L{1C|1P|1W|...})", + " -nomask [sig[,...]] signal no mask (same as above)", + " -x sat exclude satellite", + " -y sys exclude systems (G:GPS,R:GLO,E:GAL,J:QZS,S:SBS,C:BDS,I:IRN)", + " --glofcn [-7 to 6][,...]] GLONASS fcn for R01 to R32", + " -d dir output directory [same as input file]", + " -c staid use RINEX file name convention with staid [off]", + " -o ofile output RINEX OBS file", + " -n nfile output RINEX NAV file", + " -g gfile output RINEX GNAV file", + " -h hfile output RINEX HNAV file", + " -q qfile output RINEX QNAV file", + " -l lfile output RINEX LNAV file", + " -b cfile output RINEX CNAV file", + " -i ifile output RINEX INAV file", + " -s sfile output SBAS message file", + " -trace level output trace level [off]", + "", + " If any output file specified, default output files (.obs,", + " .nav, .gnav, .hnav, .qnav, .lnav,", + " .cnav, .inav and .sbs) are used. To obtain week number info", + " for RTCM file, use -tr option to specify the approximated log start time.", + " Without -tr option, the program obtains the week number from the time-tag file", + " (if it exists) or the last modified time of the log file instead.", + "", + " If receiver type is not specified, type is recognized by the input", + " file extension as follows.", + " *.rtcm2 RTCM 2", + " *.rtcm3 RTCM 3", + " *.gps NovAtel OEM4/V/6/7,OEMStar", + " *.ubx u-blox LEA-4T/5T/6T/7T/M8T/F9", + " *.sbp Swift Navigation SBP", + " *.bin Hemisphere Eclipse/Crescent", + " *.stq SkyTraq S1315F", + " *.jps Javad GREIS", + " *.bnx,*binex BINEX", + " *.rt17 Trimble RT17", + " *.sbf Septentrio SBF", + " *.unc Unicore binary data output", + " *.obs,*.*o RINEX OBS", + " *.rnx RINEX OBS", + " *.nav,*.*n RINEX NAV", }; /* print help ----------------------------------------------------------------*/ -static void printhelp(void) -{ - int i; - for (i=0;i<(int)(sizeof(help)/sizeof(*help));i++) fprintf(stderr,"%s\n",help[i]); - exit(0); +static void printhelp(void) { + int i; + for (i = 0; i < (int)(sizeof(help) / sizeof(*help)); i++) fprintf(stderr, "%s\n", help[i]); + exit(0); } /* show message --------------------------------------------------------------*/ -extern int showmsg(const char *format, ...) -{ - va_list arg; - va_start(arg,format); vfprintf(stderr,format,arg); va_end(arg); - fprintf(stderr,*format?"\r":"\n"); - return 0; +extern int showmsg(const char *format, ...) { + va_list arg; + va_start(arg, format); + vfprintf(stderr, format, arg); + va_end(arg); + fprintf(stderr, *format ? "\r" : "\n"); + return 0; } /* convert main --------------------------------------------------------------*/ -static int convbin(int format, rnxopt_t *opt, const char *ifile, char **file, - char *dir) -{ - int i,def; - static char work[1024],ofile_[NOUTFILE][1024]={"","","","","","","","",""}; - char ifile_[1024],*ofile[NOUTFILE],*p; - char *extnav=(opt->rnxver<=299||opt->navsys==SYS_GPS)?"N":"P"; - char *extlog="sbs"; - - /* replace wild-card (*) in input file by 0 */ - strcpy(ifile_,ifile); - for (p=ifile_;*p;p++) if (*p=='*') *p='0'; - - def=!file[0]&&!file[1]&&!file[2]&&!file[3]&&!file[4]&&!file[5]&&!file[6]&& - !file[7]&&!file[8]; - - for (i=0;istaid) { - strcpy(ofile[0],"%r%n0.%yO"); - } - else if (def) { - strcpy(ofile[0],ifile_); - if ((p=strrchr(ofile[0],'.'))) strcpy(p,".obs"); - else strcat(ofile[0],".obs"); - } - if (file[1]) strcpy(ofile[1],file[1]); - else if (*opt->staid) { - strcpy(ofile[1],"%r%n0.%y"); - strcat(ofile[1],extnav); - } - else if (def) { - strcpy(ofile[1],ifile_); - if ((p=strrchr(ofile[1],'.'))) strcpy(p,".nav"); - else strcat(ofile[1],".nav"); - } - if (file[2]) strcpy(ofile[2],file[2]); - else if (opt->rnxver<=299&&*opt->staid) { - strcpy(ofile[2],"%r%n0.%yG"); - } - else if (opt->rnxver<=299&&def) { - strcpy(ofile[2],ifile_); - if ((p=strrchr(ofile[2],'.'))) strcpy(p,".gnav"); - else strcat(ofile[2],".gnav"); - } - if (file[3]) strcpy(ofile[3],file[3]); - else if (opt->rnxver<=299&&*opt->staid) { - strcpy(ofile[3],"%r%n0.%yH"); - } - else if (opt->rnxver<=299&&def) { - strcpy(ofile[3],ifile_); - if ((p=strrchr(ofile[3],'.'))) strcpy(p,".hnav"); - else strcat(ofile[3],".hnav"); - } - if (file[4]) strcpy(ofile[4],file[4]); - else if (opt->rnxver<=299&&*opt->staid) { - strcpy(ofile[4],"%r%n0.%yQ"); - } - else if (opt->rnxver<=299&&def) { - strcpy(ofile[4],ifile_); - if ((p=strrchr(ofile[4],'.'))) strcpy(p,".qnav"); - else strcat(ofile[4],".qnav"); - } - if (file[5]) strcpy(ofile[5],file[5]); - else if (opt->rnxver<=299&&*opt->staid) { - strcpy(ofile[5],"%r%n0.%yL"); - } - else if (opt->rnxver<=299&&def) { - strcpy(ofile[5],ifile_); - if ((p=strrchr(ofile[5],'.'))) strcpy(p,".lnav"); - else strcat(ofile[5],".lnav"); - } - if (file[6]) strcpy(ofile[6],file[6]); - else if (opt->rnxver<=299&&*opt->staid) { - strcpy(ofile[6],"%r%n0.%yC"); - } - else if (opt->rnxver<=299&&def) { - strcpy(ofile[6],ifile_); - if ((p=strrchr(ofile[6],'.'))) strcpy(p,".cnav"); - else strcat(ofile[6],".cnav"); - } - if (file[7]) strcpy(ofile[7],file[7]); - else if (opt->rnxver<=299&&*opt->staid) { - strcpy(ofile[7],"%r%n0.%yI"); - } - else if (opt->rnxver<=299&&def) { - strcpy(ofile[7],ifile_); - if ((p=strrchr(ofile[7],'.'))) strcpy(p,".inav"); - else strcat(ofile[7],".inav"); - } - if (file[8]) strcpy(ofile[8],file[8]); - else if (*opt->staid) { - strcpy(ofile[8],"%r%n0_%y."); - strcat(ofile[8],extlog); - } - else if (def) { - strcpy(ofile[8],ifile_); - if ((p=strrchr(ofile[8],'.'))) strcpy(p,"."); - else strcat(ofile[8],"."); - strcat(ofile[8],extlog); - } - for (i=0;irinex obs : %s\n",ofile[0]); - if (*ofile[1]) fprintf(stderr,"->rinex nav : %s\n",ofile[1]); - if (*ofile[2]) fprintf(stderr,"->rinex gnav: %s\n",ofile[2]); - if (*ofile[3]) fprintf(stderr,"->rinex hnav: %s\n",ofile[3]); - if (*ofile[4]) fprintf(stderr,"->rinex qnav: %s\n",ofile[4]); - if (*ofile[5]) fprintf(stderr,"->rinex lnav: %s\n",ofile[5]); - if (*ofile[6]) fprintf(stderr,"->rinex cnav: %s\n",ofile[6]); - if (*ofile[7]) fprintf(stderr,"->rinex inav: %s\n",ofile[7]); - if (*ofile[8]) fprintf(stderr,"->sbas log : %s\n",ofile[8]); - - if (!convrnx(format,opt,ifile,ofile)) { - fprintf(stderr,"\n"); - return 0; - } - fprintf(stderr,"\n"); - return 1; +static int convbin(int format, rnxopt_t *opt, const char *ifile, char **file, char *dir) { + int i, def; + static char work[1024], ofile_[NOUTFILE][1024] = {"", "", "", "", "", "", "", "", ""}; + char ifile_[1024], *ofile[NOUTFILE], *p; + char *extnav = (opt->rnxver <= 299 || opt->navsys == SYS_GPS) ? "N" : "P"; + char *extlog = "sbs"; + + /* replace wild-card (*) in input file by 0 */ + strcpy(ifile_, ifile); + for (p = ifile_; *p; p++) + if (*p == '*') *p = '0'; + + def = !file[0] && !file[1] && !file[2] && !file[3] && !file[4] && !file[5] && !file[6] && + !file[7] && !file[8]; + + for (i = 0; i < NOUTFILE; i++) ofile[i] = ofile_[i]; + + if (file[0]) + strcpy(ofile[0], file[0]); + else if (*opt->staid) { + strcpy(ofile[0], "%r%n0.%yO"); + } else if (def) { + strcpy(ofile[0], ifile_); + if ((p = strrchr(ofile[0], '.'))) + strcpy(p, ".obs"); + else + strcat(ofile[0], ".obs"); + } + if (file[1]) + strcpy(ofile[1], file[1]); + else if (*opt->staid) { + strcpy(ofile[1], "%r%n0.%y"); + strcat(ofile[1], extnav); + } else if (def) { + strcpy(ofile[1], ifile_); + if ((p = strrchr(ofile[1], '.'))) + strcpy(p, ".nav"); + else + strcat(ofile[1], ".nav"); + } + if (file[2]) + strcpy(ofile[2], file[2]); + else if (opt->rnxver <= 299 && *opt->staid) { + strcpy(ofile[2], "%r%n0.%yG"); + } else if (opt->rnxver <= 299 && def) { + strcpy(ofile[2], ifile_); + if ((p = strrchr(ofile[2], '.'))) + strcpy(p, ".gnav"); + else + strcat(ofile[2], ".gnav"); + } + if (file[3]) + strcpy(ofile[3], file[3]); + else if (opt->rnxver <= 299 && *opt->staid) { + strcpy(ofile[3], "%r%n0.%yH"); + } else if (opt->rnxver <= 299 && def) { + strcpy(ofile[3], ifile_); + if ((p = strrchr(ofile[3], '.'))) + strcpy(p, ".hnav"); + else + strcat(ofile[3], ".hnav"); + } + if (file[4]) + strcpy(ofile[4], file[4]); + else if (opt->rnxver <= 299 && *opt->staid) { + strcpy(ofile[4], "%r%n0.%yQ"); + } else if (opt->rnxver <= 299 && def) { + strcpy(ofile[4], ifile_); + if ((p = strrchr(ofile[4], '.'))) + strcpy(p, ".qnav"); + else + strcat(ofile[4], ".qnav"); + } + if (file[5]) + strcpy(ofile[5], file[5]); + else if (opt->rnxver <= 299 && *opt->staid) { + strcpy(ofile[5], "%r%n0.%yL"); + } else if (opt->rnxver <= 299 && def) { + strcpy(ofile[5], ifile_); + if ((p = strrchr(ofile[5], '.'))) + strcpy(p, ".lnav"); + else + strcat(ofile[5], ".lnav"); + } + if (file[6]) + strcpy(ofile[6], file[6]); + else if (opt->rnxver <= 299 && *opt->staid) { + strcpy(ofile[6], "%r%n0.%yC"); + } else if (opt->rnxver <= 299 && def) { + strcpy(ofile[6], ifile_); + if ((p = strrchr(ofile[6], '.'))) + strcpy(p, ".cnav"); + else + strcat(ofile[6], ".cnav"); + } + if (file[7]) + strcpy(ofile[7], file[7]); + else if (opt->rnxver <= 299 && *opt->staid) { + strcpy(ofile[7], "%r%n0.%yI"); + } else if (opt->rnxver <= 299 && def) { + strcpy(ofile[7], ifile_); + if ((p = strrchr(ofile[7], '.'))) + strcpy(p, ".inav"); + else + strcat(ofile[7], ".inav"); + } + if (file[8]) + strcpy(ofile[8], file[8]); + else if (*opt->staid) { + strcpy(ofile[8], "%r%n0_%y."); + strcat(ofile[8], extlog); + } else if (def) { + strcpy(ofile[8], ifile_); + if ((p = strrchr(ofile[8], '.'))) + strcpy(p, "."); + else + strcat(ofile[8], "."); + strcat(ofile[8], extlog); + } + for (i = 0; i < NOUTFILE; i++) { + if (!*dir || !*ofile[i]) continue; + if ((p = strrchr(ofile[i], RTKLIB_FILEPATHSEP))) + strcpy(work, p + 1); + else + strcpy(work, ofile[i]); + sprintf(ofile[i], "%s%c%s", dir, RTKLIB_FILEPATHSEP, work); + } + fprintf(stderr, "input file : %s (%s)\n", ifile, formatstrs[format]); + + if (*ofile[0]) fprintf(stderr, "->rinex obs : %s\n", ofile[0]); + if (*ofile[1]) fprintf(stderr, "->rinex nav : %s\n", ofile[1]); + if (*ofile[2]) fprintf(stderr, "->rinex gnav: %s\n", ofile[2]); + if (*ofile[3]) fprintf(stderr, "->rinex hnav: %s\n", ofile[3]); + if (*ofile[4]) fprintf(stderr, "->rinex qnav: %s\n", ofile[4]); + if (*ofile[5]) fprintf(stderr, "->rinex lnav: %s\n", ofile[5]); + if (*ofile[6]) fprintf(stderr, "->rinex cnav: %s\n", ofile[6]); + if (*ofile[7]) fprintf(stderr, "->rinex inav: %s\n", ofile[7]); + if (*ofile[8]) fprintf(stderr, "->sbas log : %s\n", ofile[8]); + + if (!convrnx(format, opt, ifile, ofile)) { + fprintf(stderr, "\n"); + return 0; + } + fprintf(stderr, "\n"); + return 1; } /* set signal mask -----------------------------------------------------------*/ -static void setmask(const char *argv, rnxopt_t *opt, int mask) -{ - char buff[1024],*p; - int i; - - strcpy(buff,argv); - char *r; - for (p=strtok_r(buff,",",&r);p;p=strtok_r(NULL,",",&r)) { - if (strlen(p)<4||p[1]!='L') continue; - if (p[0]=='G') i=RNX_SYS_GPS; - else if (p[0]=='R') i=RNX_SYS_GLO; - else if (p[0]=='E') i=RNX_SYS_GAL; - else if (p[0]=='J') i=RNX_SYS_QZS; - else if (p[0]=='S') i=RNX_SYS_SBS; - else if (p[0]=='C') i=RNX_SYS_CMP; - else if (p[0]=='I') i=RNX_SYS_IRN; - else continue; - int code=obs2code(p+2); - if (code != CODE_NONE) { - opt->mask[i][code-1]=mask?'1':'0'; - } +static void setmask(const char *argv, rnxopt_t *opt, int mask) { + char buff[1024], *p; + int i; + + strcpy(buff, argv); + char *r; + for (p = strtok_r(buff, ",", &r); p; p = strtok_r(NULL, ",", &r)) { + if (strlen(p) < 4 || p[1] != 'L') continue; + if (p[0] == 'G') + i = RNX_SYS_GPS; + else if (p[0] == 'R') + i = RNX_SYS_GLO; + else if (p[0] == 'E') + i = RNX_SYS_GAL; + else if (p[0] == 'J') + i = RNX_SYS_QZS; + else if (p[0] == 'S') + i = RNX_SYS_SBS; + else if (p[0] == 'C') + i = RNX_SYS_CMP; + else if (p[0] == 'I') + i = RNX_SYS_IRN; + else + continue; + int code = obs2code(p + 2); + if (code != CODE_NONE) { + opt->mask[i][code - 1] = mask ? '1' : '0'; } + } } // Set GLONASS fcn ----------------------------------------------------------- static void setglofcn(const char *argv, rnxopt_t *opt) { @@ -376,323 +403,341 @@ static void setglofcn(const char *argv, rnxopt_t *opt) { } } /* get start time of input file -----------------------------------------------*/ -static int get_filetime(const char *file, gtime_t *time) -{ - FILE *fp; - uint32_t time_time; - uint8_t buff[64]; - char path[1024],*paths[1],path_tag[1024]; +static int get_filetime(const char *file, gtime_t *time) { + FILE *fp; + uint32_t time_time; + uint8_t buff[64]; + char path[1024], *paths[1], path_tag[1024]; - paths[0]=path; - - if (!expath(file,paths,1)) return 0; - - /* get start time of time-tag file */ - sprintf(path_tag,"%.1019s.tag",path); - if ((fp=fopen(path_tag,"rb"))) { - if (fread(buff,64,1,fp)==1&&!strncmp((char *)buff,"TIMETAG",7)&& - fread(&time_time,4,1,fp)==1) { - time->time=time_time; - time->sec=0.0; - fclose(fp); - return 1; - } - fclose(fp); - } - /* Get modified time of input file. */ - struct stat st; - if (!stat(path, &st)) { - struct tm tm; - if (gmtime_r(&st.st_mtime, &tm)) { - double ep[6]; - ep[0] = tm.tm_year + 1900; - ep[1] = tm.tm_mon + 1; - ep[2] = tm.tm_mday; - ep[3] = tm.tm_hour; - ep[4] = tm.tm_min; - ep[5] = tm.tm_sec; - *time = utc2gpst(epoch2time(ep)); - return 1; - } + paths[0] = path; + + if (!expath(file, paths, 1)) return 0; + + /* get start time of time-tag file */ + sprintf(path_tag, "%.1019s.tag", path); + if ((fp = fopen(path_tag, "rb"))) { + if (fread(buff, 64, 1, fp) == 1 && !strncmp((char *)buff, "TIMETAG", 7) && + fread(&time_time, 4, 1, fp) == 1) { + time->time = time_time; + time->sec = 0.0; + fclose(fp); + return 1; + } + fclose(fp); + } + /* Get modified time of input file. */ + struct stat st; + if (!stat(path, &st)) { + struct tm tm; + if (gmtime_r(&st.st_mtime, &tm)) { + double ep[6]; + ep[0] = tm.tm_year + 1900; + ep[1] = tm.tm_mon + 1; + ep[2] = tm.tm_mday; + ep[3] = tm.tm_hour; + ep[4] = tm.tm_min; + ep[5] = tm.tm_sec; + *time = utc2gpst(epoch2time(ep)); + return 1; } - return 0; + } + return 0; } /* parse command line options ------------------------------------------------*/ -static int cmdopts(int argc, char **argv, rnxopt_t *opt, char **ifile, - char **ofile, char **dir, int *trace) -{ - double eps[]={1980,1,1,0,0,0},epe[]={2037,12,31,0,0,0}; - double epr[]={2010,1,1,0,0,0},span=0.0; - int i,j,k,sat,nf=6,format=-1; - char *p,*sys,*fmt="",*paths[1],path[1024],buff[256]; - - opt->rnxver=304; - opt->obstype=OBSTYPE_PR|OBSTYPE_CP; - opt->navsys=SYS_GPS|SYS_GLO|SYS_GAL|SYS_QZS|SYS_SBS|SYS_CMP|SYS_IRN; - opt->ttol = 0.005; - - for (i=0;imask[i][j]='1'; - opt->mask[i][MAXCODE]='\0'; - } - - for (i=1;its=epoch2time(eps); - } - else if (!strcmp(argv[i],"-te")&&i+2te=epoch2time(epe); - } - else if (!strcmp(argv[i],"-tr")&&i+2trtcm=epoch2time(epr); - } - else if (!strcmp(argv[i],"-ti")&&i+1tint=atof(argv[++i]); - } - else if (!strcmp(argv[i],"-tt")&&i+1ttol=atof(argv[++i]); - } - else if (!strcmp(argv[i],"-span")&&i+1rcvopt,argv[++i]); - } - else if (!strcmp(argv[i],"-f" )&&i+1marker,argv[++i]); - } - else if (!strcmp(argv[i],"-hn")&&i+1markerno,argv[++i]); - } - else if (!strcmp(argv[i],"-ht")&&i+1markertype,argv[++i]); - } - else if (!strcmp(argv[i],"-ho")&&i+1name[j],p); - } - } - else if (!strcmp(argv[i],"-hr")&&i+1rec[j],p); - } - } - else if (!strcmp(argv[i],"-ha")&&i+1ant[j],p); - } - } - else if (!strcmp(argv[i],"-hp")&&i+1apppos[j]=atof(p); - } - } - else if (!strcmp(argv[i],"-hd")&&i+1antdel[j]=atof(p); - } - } - else if (!strcmp(argv[i],"-v" )&&i+1rnxver=(int)(atof(argv[++i])*100.0); - } - else if (!strcmp(argv[i],"-od")) { - opt->obstype|=OBSTYPE_DOP; - } - else if (!strcmp(argv[i],"-os")) { - opt->obstype|=OBSTYPE_SNR; - } - else if (!strcmp(argv[i],"-oi")) { - opt->outiono=1; - } - else if (!strcmp(argv[i],"-ot")) { - opt->outtime=1; - } - else if (!strcmp(argv[i],"-ol")) { - opt->outleaps=1; - } - else if (!strcmp(argv[i],"-scan")) { - /* obsolete */ ; - } - else if (!strcmp(argv[i],"-halfc")) { - opt->halfcyc=1; - } - else if (!strcmp(argv[i],"-sortsats")) { - opt->sortsats=1; - } - else if (!strcmp(argv[i],"-mask")&&i+1mask[j][k]='0'; - opt->mask[j][MAXCODE]='\0'; - } - setmask(argv[++i],opt,1); - } - else if (!strcmp(argv[i],"-nomask")&&i+1exsats[sat-1]=1; - } - else if (!strcmp(argv[i],"-y" )&&i+1navsys&=~SYS_GPS; - else if (!strcmp(sys,"R")) opt->navsys&=~SYS_GLO; - else if (!strcmp(sys,"E")) opt->navsys&=~SYS_GAL; - else if (!strcmp(sys,"J")) opt->navsys&=~SYS_QZS; - else if (!strcmp(sys,"S")) opt->navsys&=~SYS_SBS; - else if (!strcmp(sys,"C")) opt->navsys&=~SYS_CMP; - else if (!strcmp(sys,"I")) opt->navsys&=~SYS_IRN; - } - else if (!strcmp(argv[i], "--glofcn") && i + 1 < argc) { - setglofcn(argv[++i], opt); - } - else if (!strcmp(argv[i],"-d" )&&i+1staid,argv[++i]); - } - else if (!strcmp(argv[i],"-o" )&&i+10.0&&opt->ts.time) { - opt->te=timeadd(opt->ts,span*3600.0-1e-3); - } - if (nf>=1) opt->freqtype|=FREQTYPE_L1; - if (nf>=2) opt->freqtype|=FREQTYPE_L2; - if (nf>=3) opt->freqtype|=FREQTYPE_L3; - if (nf>=4) opt->freqtype|=FREQTYPE_L4; - if (nf>=5) opt->freqtype|=FREQTYPE_L5; - if (nf>=6) opt->freqtype|=FREQTYPE_L6; - if (nf>=7) opt->freqtype|=FREQTYPE_ALL; - - if (opt->trtcm.time == 0) { - // Use the start or end time if supplied. Otherwise use the file time. - if (opt->ts.time != 0) opt->trtcm = opt->ts; - else if (opt->te.time != 0) opt->trtcm = opt->te; - else get_filetime(*ifile, &opt->trtcm); - } - if (*fmt) { - if (!strcmp(fmt,"rtcm2")) format=STRFMT_RTCM2; - else if (!strcmp(fmt,"rtcm3")) format=STRFMT_RTCM3; - else if (!strcmp(fmt,"nov" )) format=STRFMT_OEM4; +static int cmdopts(int argc, char **argv, rnxopt_t *opt, char **ifile, char **ofile, char **dir, + int *trace) { + double eps[] = {1980, 1, 1, 0, 0, 0}, epe[] = {2037, 12, 31, 0, 0, 0}; + double epr[] = {2010, 1, 1, 0, 0, 0}, span = 0.0; + int i, j, k, sat, nf = 6, format = -1; + char *p, *sys, *fmt = "", *paths[1], path[1024], buff[256]; + + opt->rnxver = 304; + opt->obstype = OBSTYPE_PR | OBSTYPE_CP; + opt->navsys = SYS_GPS | SYS_GLO | SYS_GAL | SYS_QZS | SYS_SBS | SYS_CMP | SYS_IRN; + opt->ttol = 0.005; + + for (i = 0; i < RNX_NUMSYS; i++) { + for (j = 0; j < MAXCODE; j++) opt->mask[i][j] = '1'; + opt->mask[i][MAXCODE] = '\0'; + } + + for (i = 1; i < argc; i++) { + if (!strcmp(argv[i], "-ts") && i + 2 < argc) { + sscanf(argv[++i], "%lf/%lf/%lf", eps, eps + 1, eps + 2); + sscanf(argv[++i], "%lf:%lf:%lf", eps + 3, eps + 4, eps + 5); + opt->ts = epoch2time(eps); + } else if (!strcmp(argv[i], "-te") && i + 2 < argc) { + sscanf(argv[++i], "%lf/%lf/%lf", epe, epe + 1, epe + 2); + sscanf(argv[++i], "%lf:%lf:%lf", epe + 3, epe + 4, epe + 5); + opt->te = epoch2time(epe); + } else if (!strcmp(argv[i], "-tr") && i + 2 < argc) { + sscanf(argv[++i], "%lf/%lf/%lf", epr, epr + 1, epr + 2); + sscanf(argv[++i], "%lf:%lf:%lf", epr + 3, epr + 4, epr + 5); + opt->trtcm = epoch2time(epr); + } else if (!strcmp(argv[i], "-ti") && i + 1 < argc) { + opt->tint = atof(argv[++i]); + } else if (!strcmp(argv[i], "-tt") && i + 1 < argc) { + opt->ttol = atof(argv[++i]); + } else if (!strcmp(argv[i], "-span") && i + 1 < argc) { + span = atof(argv[++i]); + } else if (!strcmp(argv[i], "-r") && i + 1 < argc) { + fmt = argv[++i]; + } else if (!strcmp(argv[i], "-ro") && i + 1 < argc) { + strcpy(opt->rcvopt, argv[++i]); + } else if (!strcmp(argv[i], "-f") && i + 1 < argc) { + nf = atoi(argv[++i]); + } else if (!strcmp(argv[i], "-hc") && i + 1 < argc) { + rnxcomment(opt, argv[++i]); + } else if (!strcmp(argv[i], "-hm") && i + 1 < argc) { + strcpy(opt->marker, argv[++i]); + } else if (!strcmp(argv[i], "-hn") && i + 1 < argc) { + strcpy(opt->markerno, argv[++i]); + } else if (!strcmp(argv[i], "-ht") && i + 1 < argc) { + strcpy(opt->markertype, argv[++i]); + } else if (!strcmp(argv[i], "-ho") && i + 1 < argc) { + strcpy(buff, argv[++i]); + char *r; + for (j = 0, p = strtok_r(buff, "/", &r); j < 2 && p; j++, p = strtok_r(NULL, "/", &r)) { + strcpy(opt->name[j], p); + } + } else if (!strcmp(argv[i], "-hr") && i + 1 < argc) { + strcpy(buff, argv[++i]); + char *r; + for (j = 0, p = strtok_r(buff, "/", &r); j < 3 && p; j++, p = strtok_r(NULL, "/", &r)) { + strcpy(opt->rec[j], p); + } + } else if (!strcmp(argv[i], "-ha") && i + 1 < argc) { + strcpy(buff, argv[++i]); + char *r; + for (j = 0, p = strtok_r(buff, "/", &r); j < 3 && p; j++, p = strtok_r(NULL, "/", &r)) { + strcpy(opt->ant[j], p); + } + } else if (!strcmp(argv[i], "-hp") && i + 1 < argc) { + strcpy(buff, argv[++i]); + char *r; + for (j = 0, p = strtok_r(buff, "/", &r); j < 3 && p; j++, p = strtok_r(NULL, "/", &r)) { + opt->apppos[j] = atof(p); + } + } else if (!strcmp(argv[i], "-hd") && i + 1 < argc) { + strcpy(buff, argv[++i]); + char *r; + for (j = 0, p = strtok_r(buff, "/", &r); j < 3 && p; j++, p = strtok_r(NULL, "/", &r)) { + opt->antdel[j] = atof(p); + } + } else if (!strcmp(argv[i], "-v") && i + 1 < argc) { + opt->rnxver = (int)(atof(argv[++i]) * 100.0); + } else if (!strcmp(argv[i], "-od")) { + opt->obstype |= OBSTYPE_DOP; + } else if (!strcmp(argv[i], "-os")) { + opt->obstype |= OBSTYPE_SNR; + } else if (!strcmp(argv[i], "-oi")) { + opt->outiono = 1; + } else if (!strcmp(argv[i], "-ot")) { + opt->outtime = 1; + } else if (!strcmp(argv[i], "-ol")) { + opt->outleaps = 1; + } else if (!strcmp(argv[i], "-scan")) { + /* obsolete */; + } else if (!strcmp(argv[i], "-halfc")) { + opt->halfcyc = 1; + } else if (!strcmp(argv[i], "-sortsats")) { + opt->sortsats = 1; + } else if (!strcmp(argv[i], "-mask") && i + 1 < argc) { + for (j = 0; j < RNX_NUMSYS; j++) { + for (k = 0; k < MAXCODE; k++) opt->mask[j][k] = '0'; + opt->mask[j][MAXCODE] = '\0'; + } + setmask(argv[++i], opt, 1); + } else if (!strcmp(argv[i], "-nomask") && i + 1 < argc) { + setmask(argv[++i], opt, 0); + } else if (!strcmp(argv[i], "-x") && i + 1 < argc) { + if ((sat = satid2no(argv[++i]))) opt->exsats[sat - 1] = 1; + } else if (!strcmp(argv[i], "-y") && i + 1 < argc) { + sys = argv[++i]; + if (!strcmp(sys, "G")) + opt->navsys &= ~SYS_GPS; + else if (!strcmp(sys, "R")) + opt->navsys &= ~SYS_GLO; + else if (!strcmp(sys, "E")) + opt->navsys &= ~SYS_GAL; + else if (!strcmp(sys, "J")) + opt->navsys &= ~SYS_QZS; + else if (!strcmp(sys, "S")) + opt->navsys &= ~SYS_SBS; + else if (!strcmp(sys, "C")) + opt->navsys &= ~SYS_CMP; + else if (!strcmp(sys, "I")) + opt->navsys &= ~SYS_IRN; + } else if (!strcmp(argv[i], "--glofcn") && i + 1 < argc) { + setglofcn(argv[++i], opt); + } else if (!strcmp(argv[i], "-d") && i + 1 < argc) { + *dir = argv[++i]; + } else if (!strcmp(argv[i], "-c") && i + 1 < argc) { + strcpy(opt->staid, argv[++i]); + } else if (!strcmp(argv[i], "-o") && i + 1 < argc) + ofile[0] = argv[++i]; + else if (!strcmp(argv[i], "-n") && i + 1 < argc) + ofile[1] = argv[++i]; + else if (!strcmp(argv[i], "-g") && i + 1 < argc) + ofile[2] = argv[++i]; + else if (!strcmp(argv[i], "-h") && i + 1 < argc) + ofile[3] = argv[++i]; + else if (!strcmp(argv[i], "-q") && i + 1 < argc) + ofile[4] = argv[++i]; + else if (!strcmp(argv[i], "-l") && i + 1 < argc) + ofile[5] = argv[++i]; + else if (!strcmp(argv[i], "-b") && i + 1 < argc) + ofile[6] = argv[++i]; + else if (!strcmp(argv[i], "-i") && i + 1 < argc) + ofile[7] = argv[++i]; + else if (!strcmp(argv[i], "-s") && i + 1 < argc) + ofile[8] = argv[++i]; + else if (!strcmp(argv[i], "-trace") && i + 1 < argc) { + *trace = atoi(argv[++i]); + } else if (!strcmp(argv[i], "--version")) { + fprintf(stderr, "convbin RTKLIB %s %s\n", VER_RTKLIB, PATCH_LEVEL); + exit(0); + } else if (!strncmp(argv[i], "-", 1)) + printhelp(); + + else + *ifile = argv[i]; + } + if (span > 0.0 && opt->ts.time) { + opt->te = timeadd(opt->ts, span * 3600.0 - 1e-3); + } + if (nf >= 1) opt->freqtype |= FREQTYPE_L1; + if (nf >= 2) opt->freqtype |= FREQTYPE_L2; + if (nf >= 3) opt->freqtype |= FREQTYPE_L3; + if (nf >= 4) opt->freqtype |= FREQTYPE_L4; + if (nf >= 5) opt->freqtype |= FREQTYPE_L5; + if (nf >= 6) opt->freqtype |= FREQTYPE_L6; + if (nf >= 7) opt->freqtype |= FREQTYPE_ALL; + + if (opt->trtcm.time == 0) { + // Use the start or end time if supplied. Otherwise use the file time. + if (opt->ts.time != 0) + opt->trtcm = opt->ts; + else if (opt->te.time != 0) + opt->trtcm = opt->te; + else + get_filetime(*ifile, &opt->trtcm); + } + if (*fmt) { + if (!strcmp(fmt, "rtcm2")) + format = STRFMT_RTCM2; + else if (!strcmp(fmt, "rtcm3")) + format = STRFMT_RTCM3; + else if (!strcmp(fmt, "nov")) + format = STRFMT_OEM4; #ifdef RTK_DISABLED - else if (!strcmp(fmt,"cnav" )) format=STRFMT_CNAV; + else if (!strcmp(fmt, "cnav")) + format = STRFMT_CNAV; #endif - else if (!strcmp(fmt,"ubx" )) format=STRFMT_UBX; - else if (!strcmp(fmt,"sbp" )) format=STRFMT_SBP; - else if (!strcmp(fmt,"hemis")) format=STRFMT_CRES; - else if (!strcmp(fmt,"stq" )) format=STRFMT_STQ; - else if (!strcmp(fmt,"javad")) format=STRFMT_JAVAD; - else if (!strcmp(fmt,"nvs" )) format=STRFMT_NVS; - else if (!strcmp(fmt,"binex")) format=STRFMT_BINEX; - else if (!strcmp(fmt,"rt17" )) format=STRFMT_RT17; - else if (!strcmp(fmt,"sbf" )) format=STRFMT_SEPT; - else if (!strcmp(fmt,"unicore")) format=STRFMT_UNICORE; + else if (!strcmp(fmt, "ubx")) + format = STRFMT_UBX; + else if (!strcmp(fmt, "sbp")) + format = STRFMT_SBP; + else if (!strcmp(fmt, "hemis")) + format = STRFMT_CRES; + else if (!strcmp(fmt, "stq")) + format = STRFMT_STQ; + else if (!strcmp(fmt, "javad")) + format = STRFMT_JAVAD; + else if (!strcmp(fmt, "nvs")) + format = STRFMT_NVS; + else if (!strcmp(fmt, "binex")) + format = STRFMT_BINEX; + else if (!strcmp(fmt, "rt17")) + format = STRFMT_RT17; + else if (!strcmp(fmt, "sbf")) + format = STRFMT_SEPT; + else if (!strcmp(fmt, "unicore")) + format = STRFMT_UNICORE; #ifdef RTK_DISABLED - else if (!strcmp(fmt,"tersus")) format=STRFMT_TERSUS; + else if (!strcmp(fmt, "tersus")) + format = STRFMT_TERSUS; #endif - else if (!strcmp(fmt,"rinex")) format=STRFMT_RINEX; - } - else { - paths[0]=path; - if (!expath(*ifile,paths,1)||!(p=strrchr(path,'.'))) return -1; - if (!strcmp(p,".rtcm2")) format=STRFMT_RTCM2; - else if (!strcmp(p,".rtcm3")) format=STRFMT_RTCM3; - else if (!strcmp(p,".gps" )) format=STRFMT_OEM4; + else if (!strcmp(fmt, "rinex")) + format = STRFMT_RINEX; + } else { + paths[0] = path; + if (!expath(*ifile, paths, 1) || !(p = strrchr(path, '.'))) return -1; + if (!strcmp(p, ".rtcm2")) + format = STRFMT_RTCM2; + else if (!strcmp(p, ".rtcm3")) + format = STRFMT_RTCM3; + else if (!strcmp(p, ".gps")) + format = STRFMT_OEM4; #ifdef RTK_DISABLED - else if (!strcmp(p,"cnav" )) format=STRFMT_CNAV + else if (!strcmp(p, "cnav")) + format = STRFMT_CNAV #endif - else if (!strcmp(p,".ubx" )) format=STRFMT_UBX; - else if (!strcmp(p,".sbp" )) format=STRFMT_SBP; - else if (!strcmp(p,".bin" )) format=STRFMT_CRES; - else if (!strcmp(p,".stq" )) format=STRFMT_STQ; - else if (!strcmp(p,".jps" )) format=STRFMT_JAVAD; - else if (!strcmp(p,".bnx" )) format=STRFMT_BINEX; - else if (!strcmp(p,".binex")) format=STRFMT_BINEX; - else if (!strcmp(p,".rt17" )) format=STRFMT_RT17; - else if (!strcmp(p,".sbf" )) format=STRFMT_SEPT; - else if (!strcmp(p,".unc" )) format=STRFMT_UNICORE; + else if (!strcmp(p, ".ubx")) format = STRFMT_UBX; + else if (!strcmp(p, ".sbp")) + format = STRFMT_SBP; + else if (!strcmp(p, ".bin")) + format = STRFMT_CRES; + else if (!strcmp(p, ".stq")) + format = STRFMT_STQ; + else if (!strcmp(p, ".jps")) + format = STRFMT_JAVAD; + else if (!strcmp(p, ".bnx")) + format = STRFMT_BINEX; + else if (!strcmp(p, ".binex")) + format = STRFMT_BINEX; + else if (!strcmp(p, ".rt17")) + format = STRFMT_RT17; + else if (!strcmp(p, ".sbf")) + format = STRFMT_SEPT; + else if (!strcmp(p, ".unc")) + format = STRFMT_UNICORE; #ifdef RTK_DISABLED - else if (!strcmp(p,".trs" )) format=STRFMT_TERSUS; + else if (!strcmp(p, ".trs")) + format = STRFMT_TERSUS; #endif - else if (!strcmp(p,".obs" )) format=STRFMT_RINEX; - else if (!strcmp(p+3,"o" )) format=STRFMT_RINEX; - else if (!strcmp(p+3,"O" )) format=STRFMT_RINEX; - else if (!strcmp(p,".rnx" )) format=STRFMT_RINEX; - else if (!strcmp(p,".nav" )) format=STRFMT_RINEX; - else if (!strcmp(p+3,"n" )) format=STRFMT_RINEX; - else if (!strcmp(p+3,"N" )) format=STRFMT_RINEX; - } - return format; + else if (!strcmp(p, ".obs")) + format = STRFMT_RINEX; + else if (!strcmp(p + 3, "o")) + format = STRFMT_RINEX; + else if (!strcmp(p + 3, "O")) + format = STRFMT_RINEX; + else if (!strcmp(p, ".rnx")) + format = STRFMT_RINEX; + else if (!strcmp(p, ".nav")) + format = STRFMT_RINEX; + else if (!strcmp(p + 3, "n")) + format = STRFMT_RINEX; + else if (!strcmp(p + 3, "N")) + format = STRFMT_RINEX; + } + return format; } /* main ----------------------------------------------------------------------*/ -int main(int argc, char **argv) -{ - rnxopt_t opt={{0}}; - int format,trace=0,stat; - char *ifile="",*ofile[NOUTFILE]={0},*dir=""; - - /* parse command line options */ - format=cmdopts(argc,argv,&opt,&ifile,ofile,&dir,&trace); - - if (!*ifile) { - fprintf(stderr,"no input file\n"); - return EXIT_FAILURE; - } - if (format<0) { - fprintf(stderr,"input format can not be recognized\n"); - return EXIT_FAILURE; - } - sprintf(opt.prog,"%s %s %s",PRGNAME,VER_RTKLIB,PATCH_LEVEL); - if (trace>0) { - traceopen(TRACEFILE); - tracelevel(trace); - } - stat=convbin(format,&opt,ifile,ofile,dir); - - traceclose(); - - return stat?0:EXIT_FAILURE; +int main(int argc, char **argv) { + rnxopt_t opt = {{0}}; + int format, trace = 0, stat; + char *ifile = "", *ofile[NOUTFILE] = {0}, *dir = ""; + + /* parse command line options */ + format = cmdopts(argc, argv, &opt, &ifile, ofile, &dir, &trace); + + if (!*ifile) { + fprintf(stderr, "no input file\n"); + return EXIT_FAILURE; + } + if (format < 0) { + fprintf(stderr, "input format can not be recognized\n"); + return EXIT_FAILURE; + } + sprintf(opt.prog, "%s %s %s", PRGNAME, VER_RTKLIB, PATCH_LEVEL); + if (trace > 0) { + traceopen(TRACEFILE); + tracelevel(trace); + } + stat = convbin(format, &opt, ifile, ofile, dir); + + traceclose(); + + return stat ? 0 : EXIT_FAILURE; } diff --git a/app/consapp/pos2kml/pos2kml.c b/app/consapp/pos2kml/pos2kml.c index 597c90d52..b512ca208 100644 --- a/app/consapp/pos2kml/pos2kml.c +++ b/app/consapp/pos2kml/pos2kml.c @@ -1,127 +1,144 @@ /*------------------------------------------------------------------------------ -* pos2kml.c : convert positions to google earth KML or GPX file -* -* Copyright (C) 2007-2016 by T.TAKASU, All rights reserved. -* -* version : $Revision: 1.1 $ $Date: 2008/07/17 21:54:53 $ -* history : 2007/01/20 1.0 new -* 2007/03/15 1.1 modify color sequence -* 2007/04/03 1.2 add geodetic height option -* support input of NMEA GGA sentence -* delete altitude info for track -* add time stamp option -* separate readsol.c file -* 2008/07/18 1.3 support change of convkml() arguments -* 2016/06/11 1.4 add option -gpx for gpx conversion -*-----------------------------------------------------------------------------*/ + * pos2kml.c : convert positions to google earth KML or GPX file + * + * Copyright (C) 2007-2016 by T.TAKASU, All rights reserved. + * + * version : $Revision: 1.1 $ $Date: 2008/07/17 21:54:53 $ + * history : 2007/01/20 1.0 new + * 2007/03/15 1.1 modify color sequence + * 2007/04/03 1.2 add geodetic height option + * support input of NMEA GGA sentence + * delete altitude info for track + * add time stamp option + * separate readsol.c file + * 2008/07/18 1.3 support change of convkml() arguments + * 2016/06/11 1.4 add option -gpx for gpx conversion + *-----------------------------------------------------------------------------*/ #include + #include "rtklib.h" /* help text -----------------------------------------------------------------*/ -static const char *help[]={ -"", -" usage: pos2kml [option]... file [...]", -"", -" Read solution file(s) and convert it to Google Earth KML file or GPX file.", -" Each line in the input file shall contain fields of time, position fields ", -" (latitude/longitude/height or x/y/z-ecef), and quality flag(option). The line", -" started with '%', '#', ';' is treated as comment. Command options are as ", -" follows. ([]:default)", -"", -" -h print help", -" -o file output file [infile + .kml]", -" -c color track color (0:off,1:white,2:green,3:orange,4:red,5:yellow) [5]", -" -p color point color (0:off,1:white,2:green,3:orange,4:red,5:by qflag) [5]", -" -a output altitude information [off]", -" -ag output geodetic altitude [off]", -" -tg output time stamp of gpst [off]", -" -tu output time stamp of utc [gpst]", -" -i tint output time interval (s) (0:all) [0]", -" -q qflg output q-flags (0:all) [0]", -" -m output a single mean position [false]", -" -n output point name [none]", -" -lonlat CSV format order longitude / latitude [latitude/longitude]", -" -f n e h add north/east/height offset to position (m) [0 0 0]", -" -gpx output GPX file" -" -csv output CSV file" -}; +static const char *help[] = { + "", + " usage: pos2kml [option]... file [...]", + "", + " Read solution file(s) and convert it to Google Earth KML file or GPX file.", + " Each line in the input file shall contain fields of time, position fields ", + " (latitude/longitude/height or x/y/z-ecef), and quality flag(option). The line", + " started with '%', '#', ';' is treated as comment. Command options are as ", + " follows. ([]:default)", + "", + " -h print help", + " -o file output file [infile + .kml]", + " -c color track color (0:off,1:white,2:green,3:orange,4:red,5:yellow) [5]", + " -p color point color (0:off,1:white,2:green,3:orange,4:red,5:by qflag) [5]", + " -a output altitude information [off]", + " -ag output geodetic altitude [off]", + " -tg output time stamp of gpst [off]", + " -tu output time stamp of utc [gpst]", + " -i tint output time interval (s) (0:all) [0]", + " -q qflg output q-flags (0:all) [0]", + " -m output a single mean position [false]", + " -n output point name [none]", + " -lonlat CSV format order longitude / latitude [latitude/longitude]", + " -f n e h add north/east/height offset to position (m) [0 0 0]", + " -gpx output GPX file" + " -csv output CSV file"}; /* print help ----------------------------------------------------------------*/ -static void printhelp(void) -{ - int i; - for (i=0;i<(int)(sizeof(help)/sizeof(*help));i++) fprintf(stderr,"%s\n",help[i]); - exit(0); +static void printhelp(void) { + int i; + for (i = 0; i < (int)(sizeof(help) / sizeof(*help)); i++) fprintf(stderr, "%s\n", help[i]); + exit(0); } /* pos2kml main --------------------------------------------------------------*/ -int main(int argc, char **argv) -{ - int i,j,n,outalt=0,outtime=0,qflg=0,tcolor=5,pcolor=5,gpx=0,csv=0,stat; - int mean=0,csvorder=0; - char *infile[32],*outfile="",*name=NULL; - double offset[3]={0.0},tint=0.0,es[6]={2000,1,1},ee[6]={2000,1,1}; - gtime_t ts={0},te={0}; - - for (i=1,n=0;i + #include "rtklib.h" -#define PROGNAME "rnx2rtkp" /* program name */ -#define MAXFILE 16 /* max number of input files */ +#define PROGNAME "rnx2rtkp" /* program name */ +#define MAXFILE 16 /* max number of input files */ /* help text -----------------------------------------------------------------*/ -static const char *help[]={ -"", -" usage: rnx2rtkp [option]... file file [...]", -"", -" Read RINEX OBS/NAV/GNAV/HNAV/CLK, SP3, SBAS message log files and compute ", -" receiver (rover) positions and output position solutions.", -" The first RINEX OBS file shall contain receiver (rover) observations. For the", -" relative mode, the second RINEX OBS file shall contain reference", -" (base station) receiver observations. At least one RINEX NAV/GNAV/HNAV", -" file shall be included in input files. To use SP3 precise ephemeris, specify", -" the path in the files. The extension of the SP3 file shall be .sp3 or .eph.", -" All of the input file paths can include wild-cards (*). To avoid command", -" line deployment of wild-cards, use \"...\" for paths with wild-cards.", -" Command line options are as follows ([]:default). A maximum number of", -" input files is currently set to 16. With -k option, the", -" processing options are input from the configuration file. In this case,", -" command line options precede options in the configuration file.", -"", -" -? print help", -" -k file input options from configuration file [off]", -" -o file set output file [stdout]", -" -ts ds ts start day/time (ds=y/m/d ts=h:m:s) [obs start time]", -" -te de te end day/time (de=y/m/d te=h:m:s) [obs end time]", -" -ti tint time interval (sec) [all]", -" -p mode mode (0:single,1:dgps,2:kinematic,3:static,4:static-start,", -" 5:moving-base,6:fixed,7:ppp-kinematic,8:ppp-static,9:ppp-fixed) [2]", -" -m mask elevation mask angle (deg) [15]", -" -sys s[,s...] nav system(s) (s=G:GPS,R:GLO,E:GAL,J:QZS,C:BDS,I:IRN) [G|R]", -" -f freq number of frequencies for relative mode (1:L1,2:L1+L2,3:L1+L2+L5) [2]", -" -v thres validation threshold for integer ambiguity (0.0:no AR) [3.0]", -" -b backward solutions [off]", -" -c forward/backward combined solutions [off]", -" -i instantaneous integer ambiguity resolution [off]", -" -h fix and hold for integer ambiguity resolution [off]", -" -bl bl,std baseline distance and stdev", -" -e output x/y/z-ecef position [latitude/longitude/height]", -" -a output e/n/u-baseline [latitude/longitude/height]", -" -n output NMEA-0183 GGA sentence [off]", -" -g output latitude/longitude in the form of ddd mm ss.ss' [ddd.ddd]", -" -t output time in the form of yyyy/mm/dd hh:mm:ss.ss [sssss.ss]", -" -u output time in utc [gpst]", -" -d col number of decimals in time [3]", -" -s sep field separator [' ']", -" -r x y z reference (base) receiver ecef pos (m) [average of single pos]", -" rover receiver ecef pos (m) for fixed or ppp-fixed mode", -" -l lat lon hgt reference (base) receiver latitude/longitude/height (deg/m)", -" rover latitude/longitude/height for fixed or ppp-fixed mode", -" -y level output solution status (0:off,1:states,2:residuals) [0]", -" -x level debug trace level (0:off) [0]", -" --rover list rover names for processing, separated by a space", -" --base list base names for processing, separated by a space", -" --version display release version", +static const char *help[] = { + "", + " usage: rnx2rtkp [option]... file file [...]", + "", + " Read RINEX OBS/NAV/GNAV/HNAV/CLK, SP3, SBAS message log files and compute ", + " receiver (rover) positions and output position solutions.", + " The first RINEX OBS file shall contain receiver (rover) observations. For the", + " relative mode, the second RINEX OBS file shall contain reference", + " (base station) receiver observations. At least one RINEX NAV/GNAV/HNAV", + " file shall be included in input files. To use SP3 precise ephemeris, specify", + " the path in the files. The extension of the SP3 file shall be .sp3 or .eph.", + " All of the input file paths can include wild-cards (*). To avoid command", + " line deployment of wild-cards, use \"...\" for paths with wild-cards.", + " Command line options are as follows ([]:default). A maximum number of", + " input files is currently set to 16. With -k option, the", + " processing options are input from the configuration file. In this case,", + " command line options precede options in the configuration file.", + "", + " -? print help", + " -k file input options from configuration file [off]", + " -o file set output file [stdout]", + " -ts ds ts start day/time (ds=y/m/d ts=h:m:s) [obs start time]", + " -te de te end day/time (de=y/m/d te=h:m:s) [obs end time]", + " -ti tint time interval (sec) [all]", + " -p mode mode (0:single,1:dgps,2:kinematic,3:static,4:static-start,", + " 5:moving-base,6:fixed,7:ppp-kinematic,8:ppp-static,9:ppp-fixed) [2]", + " -m mask elevation mask angle (deg) [15]", + " -sys s[,s...] nav system(s) (s=G:GPS,R:GLO,E:GAL,J:QZS,C:BDS,I:IRN) [G|R]", + " -f freq number of frequencies for relative mode (1:L1,2:L1+L2,3:L1+L2+L5) [2]", + " -v thres validation threshold for integer ambiguity (0.0:no AR) [3.0]", + " -b backward solutions [off]", + " -c forward/backward combined solutions [off]", + " -i instantaneous integer ambiguity resolution [off]", + " -h fix and hold for integer ambiguity resolution [off]", + " -bl bl,std baseline distance and stdev", + " -e output x/y/z-ecef position [latitude/longitude/height]", + " -a output e/n/u-baseline [latitude/longitude/height]", + " -n output NMEA-0183 GGA sentence [off]", + " -g output latitude/longitude in the form of ddd mm ss.ss' [ddd.ddd]", + " -t output time in the form of yyyy/mm/dd hh:mm:ss.ss [sssss.ss]", + " -u output time in utc [gpst]", + " -d col number of decimals in time [3]", + " -s sep field separator [' ']", + " -r x y z reference (base) receiver ecef pos (m) [average of single pos]", + " rover receiver ecef pos (m) for fixed or ppp-fixed mode", + " -l lat lon hgt reference (base) receiver latitude/longitude/height (deg/m)", + " rover latitude/longitude/height for fixed or ppp-fixed mode", + " -y level output solution status (0:off,1:states,2:residuals) [0]", + " -x level debug trace level (0:off) [0]", + " --rover list rover names for processing, separated by a space", + " --base list base names for processing, separated by a space", + " --version display release version", }; /* show message --------------------------------------------------------------*/ -extern int showmsg(const char *format, ...) -{ - va_list arg; - va_start(arg,format); vfprintf(stderr,format,arg); va_end(arg); - fprintf(stderr,"\r"); - return 0; +extern int showmsg(const char *format, ...) { + va_list arg; + va_start(arg, format); + vfprintf(stderr, format, arg); + va_end(arg); + fprintf(stderr, "\r"); + return 0; } extern void settspan(gtime_t ts, gtime_t te) {} extern void settime(gtime_t time) {} /* print help ----------------------------------------------------------------*/ -static void printhelp(void) -{ - int i; - for (i=0;i<(int)(sizeof(help)/sizeof(*help));i++) fprintf(stderr,"%s\n",help[i]); - exit(0); +static void printhelp(void) { + int i; + for (i = 0; i < (int)(sizeof(help) / sizeof(*help)); i++) fprintf(stderr, "%s\n", help[i]); + exit(0); } /* rnx2rtkp main -------------------------------------------------------------*/ -int main(int argc, char **argv) -{ - prcopt_t prcopt=prcopt_default; - solopt_t solopt=solopt_default; - filopt_t filopt={""}; - gtime_t ts={0},te={0}; - double tint=0.0,es[]={2000,1,1,0,0,0},ee[]={2000,12,31,23,59,59},pos[3]; - int i,j,n,ret; - const char *infile[MAXFILE],*outfile="",*p; - const char *rover = "", *base = ""; +int main(int argc, char **argv) { + prcopt_t prcopt = prcopt_default; + solopt_t solopt = solopt_default; + filopt_t filopt = {""}; + gtime_t ts = {0}, te = {0}; + double tint = 0.0, es[] = {2000, 1, 1, 0, 0, 0}, ee[] = {2000, 12, 31, 23, 59, 59}, pos[3]; + int i, j, n, ret; + const char *infile[MAXFILE], *outfile = "", *p; + const char *rover = "", *base = ""; - prcopt.mode =PMODE_KINEMA; - prcopt.navsys=0; - prcopt.refpos=POSOPT_SINGLE; - prcopt.glomodear=GLO_ARMODE_ON; - solopt.timef=0; - sprintf(solopt.prog ,"%s ver.%s %s",PROGNAME,VER_RTKLIB,PATCH_LEVEL); + prcopt.mode = PMODE_KINEMA; + prcopt.navsys = 0; + prcopt.refpos = POSOPT_SINGLE; + prcopt.glomodear = GLO_ARMODE_ON; + solopt.timef = 0; + sprintf(solopt.prog, "%s ver.%s %s", PROGNAME, VER_RTKLIB, PATCH_LEVEL); - /* load options from configuration file */ - for (i=1;i 0) { - if (*filopt.trace == '\0') - sprintf(filopt.trace, "%s.trace", PROGNAME); - traceopen(filopt.trace); - tracelevel(solopt.trace); - } - ret=postpos(ts,te,tint,0.0,&prcopt,&solopt,&filopt,infile,n,outfile,rover,base); + if (!(p = strchr(p, ','))) break; + } + } else if (!strcmp(argv[i], "-m") && i + 1 < argc) + prcopt.elmin = atof(argv[++i]) * D2R; + else if (!strcmp(argv[i], "-v") && i + 1 < argc) + prcopt.thresar[0] = atof(argv[++i]); + else if (!strcmp(argv[i], "-s") && i + 1 < argc) + strcpy(solopt.sep, argv[++i]); + else if (!strcmp(argv[i], "-d") && i + 1 < argc) + solopt.timeu = atoi(argv[++i]); + else if (!strcmp(argv[i], "-b")) + prcopt.soltype = 1; + else if (!strcmp(argv[i], "-c")) + prcopt.soltype = 2; + else if (!strcmp(argv[i], "-i")) + prcopt.modear = 2; + else if (!strcmp(argv[i], "-h")) + prcopt.modear = 3; + else if (!strcmp(argv[i], "-t")) + solopt.timef = 1; + else if (!strcmp(argv[i], "-u")) + solopt.times = TIMES_UTC; + else if (!strcmp(argv[i], "-e")) + solopt.posf = SOLF_XYZ; + else if (!strcmp(argv[i], "-a")) + solopt.posf = SOLF_ENU; + else if (!strcmp(argv[i], "-n")) + solopt.posf = SOLF_NMEA; + else if (!strcmp(argv[i], "-g")) + solopt.degf = 1; + else if (!strcmp(argv[i], "-bl") && i + 2 < argc) { + for (j = 0; j < 2; j++) prcopt.baseline[j] = atof(argv[++i]); + } else if (!strcmp(argv[i], "-r") && i + 3 < argc) { + prcopt.refpos = prcopt.rovpos = POSOPT_POS_XYZ; + for (j = 0; j < 3; j++) prcopt.rb[j] = atof(argv[++i]); + matcpy(prcopt.ru, prcopt.rb, 3, 1); + } else if (!strcmp(argv[i], "-l") && i + 3 < argc) { + prcopt.refpos = prcopt.rovpos = POSOPT_POS_LLH; + for (j = 0; j < 3; j++) pos[j] = atof(argv[++i]); + for (j = 0; j < 2; j++) pos[j] *= D2R; + pos2ecef(pos, prcopt.rb); + matcpy(prcopt.ru, prcopt.rb, 3, 1); + } else if (!strcmp(argv[i], "--rover") && i + 1 < argc) + rover = argv[++i]; + else if (!strcmp(argv[i], "--base") && i + 1 < argc) + base = argv[++i]; + else if (!strcmp(argv[i], "-y") && i + 1 < argc) + solopt.sstat = atoi(argv[++i]); + else if (!strcmp(argv[i], "-x") && i + 1 < argc) + solopt.trace = atoi(argv[++i]); + else if (!strcmp(argv[i], "--version")) { + fprintf(stderr, "rnx2rtkp RTKLIB %s %s\n", VER_RTKLIB, PATCH_LEVEL); + exit(0); + } else if (*argv[i] == '-') + printhelp(); + else if (n < MAXFILE) + infile[n++] = argv[i]; + } + if (!prcopt.navsys) { + prcopt.navsys = SYS_GPS | SYS_GLO; + } + if (n <= 0) { + showmsg("error : no input file"); + return EXIT_FAILURE; + } + if (solopt.trace > 0) { + if (*filopt.trace == '\0') sprintf(filopt.trace, "%s.trace", PROGNAME); + traceopen(filopt.trace); + tracelevel(solopt.trace); + } + ret = postpos(ts, te, tint, 0.0, &prcopt, &solopt, &filopt, infile, n, outfile, rover, base); - if (!ret) fprintf(stderr,"%40s\r",""); - return ret?EXIT_FAILURE:0; + if (!ret) fprintf(stderr, "%40s\r", ""); + return ret ? EXIT_FAILURE : 0; } diff --git a/app/consapp/rtkrcv/rtkrcv.c b/app/consapp/rtkrcv/rtkrcv.c index 2cb1f2b3c..5b9f0239f 100644 --- a/app/consapp/rtkrcv/rtkrcv.c +++ b/app/consapp/rtkrcv/rtkrcv.c @@ -1,132 +1,132 @@ /*------------------------------------------------------------------------------ -* rtkrcv.c : rtk-gps/gnss receiver console ap -* -* Copyright (C) 2009-2015 by T.TAKASU, All rights reserved. -* -* notes : -* current version does not support win32 without pthread library -* -* version : $Revision:$ $Date:$ -* history : 2009/12/13 1.0 new -* 2010/07/18 1.1 add option -m -* 2010/08/12 1.2 fix bug on ftp/http -* 2011/01/22 1.3 add option misc-proxyaddr,misc-fswapmargin -* 2011/08/19 1.4 fix bug on size of arg solopt arg for rtksvrstart() -* 2012/11/03 1.5 fix bug on setting output format -* 2013/06/30 1.6 add "nvs" option for inpstr*-format -* 2014/02/10 1.7 fix bug on printing obs data -* add print of status, glonass nav data -* ignore SIGHUP -* 2014/04/27 1.8 add "binex" option for inpstr*-format -* 2014/08/10 1.9 fix cpu overload with abnormal telnet shutdown -* 2014/08/26 1.10 support input format "rt17" -* change file paths of solution status and debug trace -* 2015/01/10 1.11 add line editing and command history -* separate codes for virtual console to vt.c -* 2015/05/22 1.12 fix bug on sp3 id in inpstr*-format options -* 2015/07/31 1.13 accept 4:stat for outstr1-format or outstr2-format -* add reading satellite dcb -* 2015/12/14 1.14 add option -sta for station name (#339) -* 2015/12/25 1.15 fix bug on -sta option (#339) -* 2015/01/26 1.16 support septentrio -* 2016/07/01 1.17 support CMR/CMR+ -* 2016/08/20 1.18 add output of patch level with version -* 2016/09/05 1.19 support ntrip caster for output stream -* 2016/09/19 1.20 support multiple remote console connections -* add option -w -* 2017/09/01 1.21 add command ssr -*-----------------------------------------------------------------------------*/ + * rtkrcv.c : rtk-gps/gnss receiver console ap + * + * Copyright (C) 2009-2015 by T.TAKASU, All rights reserved. + * + * notes : + * current version does not support win32 without pthread library + * + * version : $Revision:$ $Date:$ + * history : 2009/12/13 1.0 new + * 2010/07/18 1.1 add option -m + * 2010/08/12 1.2 fix bug on ftp/http + * 2011/01/22 1.3 add option misc-proxyaddr,misc-fswapmargin + * 2011/08/19 1.4 fix bug on size of arg solopt arg for rtksvrstart() + * 2012/11/03 1.5 fix bug on setting output format + * 2013/06/30 1.6 add "nvs" option for inpstr*-format + * 2014/02/10 1.7 fix bug on printing obs data + * add print of status, glonass nav data + * ignore SIGHUP + * 2014/04/27 1.8 add "binex" option for inpstr*-format + * 2014/08/10 1.9 fix cpu overload with abnormal telnet shutdown + * 2014/08/26 1.10 support input format "rt17" + * change file paths of solution status and debug trace + * 2015/01/10 1.11 add line editing and command history + * separate codes for virtual console to vt.c + * 2015/05/22 1.12 fix bug on sp3 id in inpstr*-format options + * 2015/07/31 1.13 accept 4:stat for outstr1-format or outstr2-format + * add reading satellite dcb + * 2015/12/14 1.14 add option -sta for station name (#339) + * 2015/12/25 1.15 fix bug on -sta option (#339) + * 2015/01/26 1.16 support septentrio + * 2016/07/01 1.17 support CMR/CMR+ + * 2016/08/20 1.18 add output of patch level with version + * 2016/09/05 1.19 support ntrip caster for output stream + * 2016/09/19 1.20 support multiple remote console connections + * add option -w + * 2017/09/01 1.21 add command ssr + *-----------------------------------------------------------------------------*/ #define _POSIX_C_SOURCE 199506 -#include -#include -#include +#include +#include #include -#include -#include -#include -#include +#include #include #include -#include -#include -#include +#include +#include +#include +#include +#include +#include +#include + #include "rtklib.h" #include "vt.h" -#define PRGNAME "rtkrcv" /* program name */ -#define CMDPROMPT "rtkrcv> " /* command prompt */ -#define MAXCON 32 /* max number of consoles */ -#define MAXARG 10 /* max number of args in a command */ -#define MAXCMD 256 /* max length of a command */ -#define MAXSTR 1024 /* max length of a stream */ -#define OPTSDIR "." /* default config directory */ -#define OPTSFILE "rtkrcv.conf" /* default config file */ -#define NAVIFILE "rtkrcv.nav" /* navigation save file */ -#define STATFILE "rtkrcv_%Y%m%d%h%M.stat" /* solution status file */ -#define TRACEFILE "rtkrcv_%Y%m%d%h%M.trace" /* debug trace file */ -#define LOGFILE "rtkrcv_%Y%m%d%h%M.log" /* Deamon log file */ -#define INTKEEPALIVE 1000 /* keep alive interval (ms) */ - -#define ESC_CLEAR "\033[H\033[2J" /* ansi/vt100 escape: erase screen */ -#define ESC_RESET "\033[0m" /* ansi/vt100: reset attribute */ -#define ESC_BOLD "\033[1m" /* ansi/vt100: bold */ - -#define SQRT(x) ((x)<=0.0||(x)!=(x)?0.0:sqrt(x)) +#define PRGNAME "rtkrcv" /* program name */ +#define CMDPROMPT "rtkrcv> " /* command prompt */ +#define MAXCON 32 /* max number of consoles */ +#define MAXARG 10 /* max number of args in a command */ +#define MAXCMD 256 /* max length of a command */ +#define MAXSTR 1024 /* max length of a stream */ +#define OPTSDIR "." /* default config directory */ +#define OPTSFILE "rtkrcv.conf" /* default config file */ +#define NAVIFILE "rtkrcv.nav" /* navigation save file */ +#define STATFILE "rtkrcv_%Y%m%d%h%M.stat" /* solution status file */ +#define TRACEFILE "rtkrcv_%Y%m%d%h%M.trace" /* debug trace file */ +#define LOGFILE "rtkrcv_%Y%m%d%h%M.log" /* Deamon log file */ +#define INTKEEPALIVE 1000 /* keep alive interval (ms) */ + +#define ESC_CLEAR "\033[H\033[2J" /* ansi/vt100 escape: erase screen */ +#define ESC_RESET "\033[0m" /* ansi/vt100: reset attribute */ +#define ESC_BOLD "\033[1m" /* ansi/vt100: bold */ + +#define SQRT(x) ((x) <= 0.0 || (x) != (x) ? 0.0 : sqrt(x)) /* type definitions ----------------------------------------------------------*/ -typedef struct { /* console type */ - int state; /* state (0:stop,1:run) */ - vt_t *vt; /* virtual terminal */ - pthread_t thread; /* console thread */ +typedef struct { /* console type */ + int state; /* state (0:stop,1:run) */ + vt_t *vt; /* virtual terminal */ + pthread_t thread; /* console thread */ } con_t; /* global variables ----------------------------------------------------------*/ -static rtksvr_t svr; /* rtk server struct */ -static stream_t moni; /* monitor stream */ - -static int intflg =0; /* interrupt flag (2:shutdown) */ - -static char passwd[MAXSTR]="admin"; /* login password */ -static int timetype =0; /* time format (0:gpst,1:utc,2:jst,3:tow) */ -static int soltype =0; /* sol format (0:dms,1:deg,2:xyz,3:enu,4:pyl) */ -static int solflag =2; /* sol flag (1:std+2:age/ratio/ns) */ -static int strtype[]={ /* stream types */ - STR_SERIAL,STR_NONE,STR_NONE,STR_NONE,STR_NONE,STR_NONE,STR_NONE,STR_NONE -}; -static char strpath[8][MAXSTR]={"","","","","","","",""}; /* stream paths */ -static int strfmt[]={ /* stream formats */ - STRFMT_UBX,STRFMT_RTCM3,STRFMT_SP3,SOLF_LLH,SOLF_NMEA -}; -static char rcvopt[3][256]={""}; /* Receiver options */ -static int svrcycle =10; /* server cycle (ms) */ -static int timeout =10000; /* timeout time (ms) */ -static int reconnect =10000; /* reconnect interval (ms) */ -static int nmeacycle =5000; /* nmea request cycle (ms) */ -static int buffsize =32768; /* input buffer size (bytes) */ -static int navmsgsel =0; /* navigation message select */ -static char proxyaddr[256]=""; /* http/ntrip proxy */ -static int nmeareq =0; /* nmea request type (0:off,1:lat/lon,2:single) */ -static double nmeapos[] ={0,0,0}; /* nmea position (lat/lon/height) (deg,m) */ -static char rcvcmds[3][MAXSTR]={""}; /* receiver commands files */ +static rtksvr_t svr; /* rtk server struct */ +static stream_t moni; /* monitor stream */ + +static int intflg = 0; /* interrupt flag (2:shutdown) */ + +static char passwd[MAXSTR] = "admin"; /* login password */ +static int timetype = 0; /* time format (0:gpst,1:utc,2:jst,3:tow) */ +static int soltype = 0; /* sol format (0:dms,1:deg,2:xyz,3:enu,4:pyl) */ +static int solflag = 2; /* sol flag (1:std+2:age/ratio/ns) */ +static int strtype[] = { /* stream types */ + STR_SERIAL, STR_NONE, STR_NONE, STR_NONE, + STR_NONE, STR_NONE, STR_NONE, STR_NONE}; +static char strpath[8][MAXSTR] = {"", "", "", "", "", "", "", ""}; /* stream paths */ +static int strfmt[] = { /* stream formats */ + STRFMT_UBX, STRFMT_RTCM3, STRFMT_SP3, SOLF_LLH, SOLF_NMEA}; +static char rcvopt[3][256] = {""}; /* Receiver options */ +static int svrcycle = 10; /* server cycle (ms) */ +static int timeout = 10000; /* timeout time (ms) */ +static int reconnect = 10000; /* reconnect interval (ms) */ +static int nmeacycle = 5000; /* nmea request cycle (ms) */ +static int buffsize = 32768; /* input buffer size (bytes) */ +static int navmsgsel = 0; /* navigation message select */ +static char proxyaddr[256] = ""; /* http/ntrip proxy */ +static int nmeareq = 0; /* nmea request type (0:off,1:lat/lon,2:single) */ +static double nmeapos[] = {0, 0, 0}; /* nmea position (lat/lon/height) (deg,m) */ +static char rcvcmds[3][MAXSTR] = {""}; /* receiver commands files */ #ifdef RTKSHELLCMDS -static char startcmd[MAXSTR]=""; /* start command */ -static char stopcmd [MAXSTR]=""; /* stop command */ +static char startcmd[MAXSTR] = ""; /* start command */ +static char stopcmd[MAXSTR] = ""; /* stop command */ #endif -static int modflgr[256] ={0}; /* modified flags of receiver options */ -static int modflgs[256] ={0}; /* modified flags of system options */ -static int moniport =0; /* monitor port */ -static int keepalive =0; /* keep alive flag */ -static int start =0; /* auto start */ -static int fswapmargin =30; /* file swap margin (s) */ -static char sta_name[256]=""; /* station name */ - -static prcopt_t prcopt; /* processing options */ -static solopt_t solopt[2]={{0}}; /* solution options */ -static filopt_t filopt ={""}; /* file options */ +static int modflgr[256] = {0}; /* modified flags of receiver options */ +static int modflgs[256] = {0}; /* modified flags of system options */ +static int moniport = 0; /* monitor port */ +static int keepalive = 0; /* keep alive flag */ +static int start = 0; /* auto start */ +static int fswapmargin = 30; /* file swap margin (s) */ +static char sta_name[256] = ""; /* station name */ + +static prcopt_t prcopt; /* processing options */ +static solopt_t solopt[2] = {{0}}; /* solution options */ +static filopt_t filopt = {""}; /* file options */ /* help text -----------------------------------------------------------------*/ -static const char *usage[]={ +static const char *usage[] = { "usage: rtkrcv [-s][-p port][-d dev][-o file][-w pwd][-r level][-t level][-sta sta]", "options", " -s start RTK server on program startup", @@ -140,234 +140,223 @@ static const char *usage[]={ " -t level debug trace level (0:off,1-5:on)", " -sta sta station name for receiver dcb", " --deamon detach from the console", - " --version print the version and exit" -}; -static const char *helptxt[]={ - "start : start rtk server", - "stop : stop rtk server", - "restart : restart rtk sever", - "solution [cycle] : show solution", - "status [cycle] : show rtk status", - "satellite [-n] [cycle]: show satellite status", - "observ [-n] [cycle] : show observation data", - "navidata [cycle] : show navigation data", - "stream [cycle] : show stream status", - "ssr [cycle] : show ssr corrections", - "error : show error/warning messages", - "option [opt] : show option(s)", - "set opt [val] : set option", - "mark [name] [comment] : log a marker", - "mode ['g'|'s'|'f'|n] : set the processing mode", - "load [file] : load options from file", - "save [file] : save options to file", - "log [file|off] : start/stop log to file", - "help|? [path] : print help", - "exit|ctr-D : logout console (only for telnet)", - "shutdown : shutdown rtk server", - "" -}; -static const char *pathopts[]={ /* path options help */ - "stream path formats", - "serial : port[:bit_rate[:byte[:parity(n|o|e)[:stopb[:fctr(off|on)[#port]]]]]]]", - "file : path[::T[::+offset][::xspeed]]", - "tcpsvr : :port", - "tcpcli : addr:port", - "ntripsvr : [passwd@]addr:port/mntpnt[:str]", - "ntripcli : user:passwd@addr:port/mntpnt", - "ntripcas : user:passwd@:[port]/mpoint[:srctbl]", - "ftp : user:passwd@addr/path[::T=poff,tint,off,rint]", - "http : addr/path[::T=poff,tint,off,rint]", - "" -}; + " --version print the version and exit"}; +static const char *helptxt[] = {"start : start rtk server", + "stop : stop rtk server", + "restart : restart rtk sever", + "solution [cycle] : show solution", + "status [cycle] : show rtk status", + "satellite [-n] [cycle]: show satellite status", + "observ [-n] [cycle] : show observation data", + "navidata [cycle] : show navigation data", + "stream [cycle] : show stream status", + "ssr [cycle] : show ssr corrections", + "error : show error/warning messages", + "option [opt] : show option(s)", + "set opt [val] : set option", + "mark [name] [comment] : log a marker", + "mode ['g'|'s'|'f'|n] : set the processing mode", + "load [file] : load options from file", + "save [file] : save options to file", + "log [file|off] : start/stop log to file", + "help|? [path] : print help", + "exit|ctr-D : logout console (only for telnet)", + "shutdown : shutdown rtk server", + ""}; +static const char *pathopts[] = + {/* path options help */ + "stream path formats", + "serial : port[:bit_rate[:byte[:parity(n|o|e)[:stopb[:fctr(off|on)[#port]]]]]]]", + "file : path[::T[::+offset][::xspeed]]", + "tcpsvr : :port", + "tcpcli : addr:port", + "ntripsvr : [passwd@]addr:port/mntpnt[:str]", + "ntripcli : user:passwd@addr:port/mntpnt", + "ntripcas : user:passwd@:[port]/mpoint[:srctbl]", + "ftp : user:passwd@addr/path[::T=poff,tint,off,rint]", + "http : addr/path[::T=poff,tint,off,rint]", + ""}; /* receiver options table ----------------------------------------------------*/ -#define TIMOPT "0:gpst,1:utc,2:jst,3:tow" -#define CONOPT "0:dms,1:deg,2:xyz,3:enu,4:pyl" -#define FLGOPT "0:off,1:std+2:age/ratio/ns" -#define ISTOPT "0:off,1:serial,2:file,3:tcpsvr,4:tcpcli,6:ntripcli,7:ftp,8:http" -#define OSTOPT "0:off,1:serial,2:file,3:tcpsvr,4:tcpcli,5:ntripsvr,9:ntripcas,11:udpcli" -#define FMTOPT "0:rtcm2,1:rtcm3,2:oem4,4:ubx,5:swift,6:hemis,7:skytraq,8:javad,9:nvs,10:binex,11:rt17,12:sbf,14:unicore,15:rinex,16:sp3,17:clk" -#define NMEOPT "0:off,1:latlon,2:single" -#define SOLOPT "0:llh,1:xyz,2:enu,3:nmea,4:stat" -#define MSGOPT "0:all,1:rover,2:base,3:corr" - -static opt_t rcvopts[]={ - {"console-passwd", 2, (void *)passwd, "" }, - {"console-timetype",3, (void *)&timetype, TIMOPT }, - {"console-soltype", 3, (void *)&soltype, CONOPT }, - {"console-solflag", 0, (void *)&solflag, FLGOPT }, - - {"inpstr1-type", 3, (void *)&strtype[0], ISTOPT }, - {"inpstr2-type", 3, (void *)&strtype[1], ISTOPT }, - {"inpstr3-type", 3, (void *)&strtype[2], ISTOPT }, - {"inpstr1-path", 2, (void *)strpath [0], "" }, - {"inpstr2-path", 2, (void *)strpath [1], "" }, - {"inpstr3-path", 2, (void *)strpath [2], "" }, - {"inpstr1-format", 3, (void *)&strfmt [0], FMTOPT }, - {"inpstr2-format", 3, (void *)&strfmt [1], FMTOPT }, - {"inpstr3-format", 3, (void *)&strfmt [2], FMTOPT }, - {"inpstr1-rcvopt", 2, (void *)rcvopt[0], "" }, - {"inpstr2-rcvopt", 2, (void *)rcvopt[1], "" }, - {"inpstr3-rcvopt", 2, (void *)rcvopt[2], "" }, - {"inpstr2-nmeareq", 3, (void *)&nmeareq, NMEOPT }, - {"inpstr2-nmealat", 1, (void *)&nmeapos[0], "deg" }, - {"inpstr2-nmealon", 1, (void *)&nmeapos[1], "deg" }, - {"inpstr2-nmeahgt", 1, (void *)&nmeapos[2], "m" }, - {"outstr1-type", 3, (void *)&strtype[3], OSTOPT }, - {"outstr2-type", 3, (void *)&strtype[4], OSTOPT }, - {"outstr1-path", 2, (void *)strpath [3], "" }, - {"outstr2-path", 2, (void *)strpath [4], "" }, - {"outstr1-format", 3, (void *)&strfmt [3], SOLOPT }, - {"outstr2-format", 3, (void *)&strfmt [4], SOLOPT }, - {"logstr1-type", 3, (void *)&strtype[5], OSTOPT }, - {"logstr2-type", 3, (void *)&strtype[6], OSTOPT }, - {"logstr3-type", 3, (void *)&strtype[7], OSTOPT }, - {"logstr1-path", 2, (void *)strpath [5], "" }, - {"logstr2-path", 2, (void *)strpath [6], "" }, - {"logstr3-path", 2, (void *)strpath [7], "" }, - - {"misc-svrcycle", 0, (void *)&svrcycle, "ms" }, - {"misc-timeout", 0, (void *)&timeout, "ms" }, - {"misc-reconnect", 0, (void *)&reconnect, "ms" }, - {"misc-nmeacycle", 0, (void *)&nmeacycle, "ms" }, - {"misc-buffsize", 0, (void *)&buffsize, "bytes"}, - {"misc-navmsgsel", 3, (void *)&navmsgsel, MSGOPT }, - {"misc-proxyaddr", 2, (void *)proxyaddr, "" }, - {"misc-fswapmargin",0, (void *)&fswapmargin, "s" }, - +#define TIMOPT "0:gpst,1:utc,2:jst,3:tow" +#define CONOPT "0:dms,1:deg,2:xyz,3:enu,4:pyl" +#define FLGOPT "0:off,1:std+2:age/ratio/ns" +#define ISTOPT "0:off,1:serial,2:file,3:tcpsvr,4:tcpcli,6:ntripcli,7:ftp,8:http" +#define OSTOPT "0:off,1:serial,2:file,3:tcpsvr,4:tcpcli,5:ntripsvr,9:ntripcas,11:udpcli" +#define FMTOPT \ + "0:rtcm2,1:rtcm3,2:oem4,4:ubx,5:swift,6:hemis,7:skytraq,8:javad,9:nvs,10:binex,11:rt17,12:sbf," \ + "14:unicore,15:rinex,16:sp3,17:clk" +#define NMEOPT "0:off,1:latlon,2:single" +#define SOLOPT "0:llh,1:xyz,2:enu,3:nmea,4:stat" +#define MSGOPT "0:all,1:rover,2:base,3:corr" + +static opt_t rcvopts[] = {{"console-passwd", 2, (void *)passwd, ""}, + {"console-timetype", 3, (void *)&timetype, TIMOPT}, + {"console-soltype", 3, (void *)&soltype, CONOPT}, + {"console-solflag", 0, (void *)&solflag, FLGOPT}, + + {"inpstr1-type", 3, (void *)&strtype[0], ISTOPT}, + {"inpstr2-type", 3, (void *)&strtype[1], ISTOPT}, + {"inpstr3-type", 3, (void *)&strtype[2], ISTOPT}, + {"inpstr1-path", 2, (void *)strpath[0], ""}, + {"inpstr2-path", 2, (void *)strpath[1], ""}, + {"inpstr3-path", 2, (void *)strpath[2], ""}, + {"inpstr1-format", 3, (void *)&strfmt[0], FMTOPT}, + {"inpstr2-format", 3, (void *)&strfmt[1], FMTOPT}, + {"inpstr3-format", 3, (void *)&strfmt[2], FMTOPT}, + {"inpstr1-rcvopt", 2, (void *)rcvopt[0], ""}, + {"inpstr2-rcvopt", 2, (void *)rcvopt[1], ""}, + {"inpstr3-rcvopt", 2, (void *)rcvopt[2], ""}, + {"inpstr2-nmeareq", 3, (void *)&nmeareq, NMEOPT}, + {"inpstr2-nmealat", 1, (void *)&nmeapos[0], "deg"}, + {"inpstr2-nmealon", 1, (void *)&nmeapos[1], "deg"}, + {"inpstr2-nmeahgt", 1, (void *)&nmeapos[2], "m"}, + {"outstr1-type", 3, (void *)&strtype[3], OSTOPT}, + {"outstr2-type", 3, (void *)&strtype[4], OSTOPT}, + {"outstr1-path", 2, (void *)strpath[3], ""}, + {"outstr2-path", 2, (void *)strpath[4], ""}, + {"outstr1-format", 3, (void *)&strfmt[3], SOLOPT}, + {"outstr2-format", 3, (void *)&strfmt[4], SOLOPT}, + {"logstr1-type", 3, (void *)&strtype[5], OSTOPT}, + {"logstr2-type", 3, (void *)&strtype[6], OSTOPT}, + {"logstr3-type", 3, (void *)&strtype[7], OSTOPT}, + {"logstr1-path", 2, (void *)strpath[5], ""}, + {"logstr2-path", 2, (void *)strpath[6], ""}, + {"logstr3-path", 2, (void *)strpath[7], ""}, + + {"misc-svrcycle", 0, (void *)&svrcycle, "ms"}, + {"misc-timeout", 0, (void *)&timeout, "ms"}, + {"misc-reconnect", 0, (void *)&reconnect, "ms"}, + {"misc-nmeacycle", 0, (void *)&nmeacycle, "ms"}, + {"misc-buffsize", 0, (void *)&buffsize, "bytes"}, + {"misc-navmsgsel", 3, (void *)&navmsgsel, MSGOPT}, + {"misc-proxyaddr", 2, (void *)proxyaddr, ""}, + {"misc-fswapmargin", 0, (void *)&fswapmargin, "s"}, + #ifdef RTKSHELLCMDS - {"misc-startcmd", 2, (void *)startcmd, "" }, - {"misc-stopcmd", 2, (void *)stopcmd, "" }, + {"misc-startcmd", 2, (void *)startcmd, ""}, + {"misc-stopcmd", 2, (void *)stopcmd, ""}, #endif - - {"file-cmdfile1", 2, (void *)rcvcmds[0], "" }, - {"file-cmdfile2", 2, (void *)rcvcmds[1], "" }, - {"file-cmdfile3", 2, (void *)rcvcmds[2], "" }, - - {"",0,NULL,""} -}; + + {"file-cmdfile1", 2, (void *)rcvcmds[0], ""}, + {"file-cmdfile2", 2, (void *)rcvcmds[1], ""}, + {"file-cmdfile3", 2, (void *)rcvcmds[2], ""}, + + {"", 0, NULL, ""}}; /* print usage ---------------------------------------------------------------*/ -static void printusage(void) -{ - int i; - for (i=0;i<(int)(sizeof(usage)/sizeof(*usage));i++) { - fprintf(stderr,"%s\n",usage[i]); - } - exit(0); +static void printusage(void) { + int i; + for (i = 0; i < (int)(sizeof(usage) / sizeof(*usage)); i++) { + fprintf(stderr, "%s\n", usage[i]); + } + exit(0); } /* external stop signal ------------------------------------------------------*/ -static void sigshut(int sig) -{ - trace(3,"sigshut: sig=%d\n",sig); - - intflg=1; +static void sigshut(int sig) { + trace(3, "sigshut: sig=%d\n", sig); + + intflg = 1; } /* discard space characters at tail ------------------------------------------*/ -static void chop(char *str) -{ - char *p; - for (p=str+strlen(str)-1;p>=str&&!isgraph((int)*p);p--) *p='\0'; +static void chop(char *str) { + char *p; + for (p = str + strlen(str) - 1; p >= str && !isgraph((int)*p); p--) *p = '\0'; } /* thread to send keep alive for monitor port --------------------------------*/ -static void *sendkeepalive(void *arg) -{ - trace(3,"sendkeepalive: start\n"); - - while (keepalive) { - strwrite(&moni,(uint8_t *)"\r",1); - sleepms(INTKEEPALIVE); - } - trace(3,"sendkeepalive: stop\n"); - return NULL; +static void *sendkeepalive(void *arg) { + trace(3, "sendkeepalive: start\n"); + + while (keepalive) { + strwrite(&moni, (uint8_t *)"\r", 1); + sleepms(INTKEEPALIVE); + } + trace(3, "sendkeepalive: stop\n"); + return NULL; } /* open monitor port ---------------------------------------------------------*/ -static int openmoni(int port) -{ - pthread_t thread; - char path[64]; - - trace(3,"openmomi: port=%d\n",port); - - sprintf(path,":%d",port); - if (!stropen(&moni,STR_TCPSVR,STR_MODE_RW,path)) return 0; - strsettimeout(&moni,timeout,reconnect); - keepalive=1; - pthread_create(&thread,NULL,sendkeepalive,NULL); - return 1; +static int openmoni(int port) { + pthread_t thread; + char path[64]; + + trace(3, "openmomi: port=%d\n", port); + + sprintf(path, ":%d", port); + if (!stropen(&moni, STR_TCPSVR, STR_MODE_RW, path)) return 0; + strsettimeout(&moni, timeout, reconnect); + keepalive = 1; + pthread_create(&thread, NULL, sendkeepalive, NULL); + return 1; } /* close monitor port --------------------------------------------------------*/ -static void closemoni(void) -{ - trace(3,"closemoni:\n"); - keepalive=0; - - /* send disconnect message */ - strwrite(&moni,(uint8_t *)MSG_DISCONN,strlen(MSG_DISCONN)); - - /* wait fin from clients */ - sleepms(1000); - - strclose(&moni); +static void closemoni(void) { + trace(3, "closemoni:\n"); + keepalive = 0; + + /* send disconnect message */ + strwrite(&moni, (uint8_t *)MSG_DISCONN, strlen(MSG_DISCONN)); + + /* wait fin from clients */ + sleepms(1000); + + strclose(&moni); } /* confirm overwrite ---------------------------------------------------------*/ -static int confwrite(vt_t *vt, const char *file) -{ - FILE *fp; - char buff[MAXSTR],*p; - - strcpy(buff,file); - if ((p=strstr(buff,"::"))) *p='\0'; /* omit options in path */ - if (!vt->state||!(fp=fopen(buff,"r"))) return 1; /* no existing file */ - fclose(fp); - vt_printf(vt,"overwrite %-16s ? (y/n): ",buff); - if (!vt_gets(vt,buff,sizeof(buff))||vt->brk) return 0; - return toupper((int)buff[0])=='Y'; +static int confwrite(vt_t *vt, const char *file) { + FILE *fp; + char buff[MAXSTR], *p; + + strcpy(buff, file); + if ((p = strstr(buff, "::"))) *p = '\0'; /* omit options in path */ + if (!vt->state || !(fp = fopen(buff, "r"))) return 1; /* no existing file */ + fclose(fp); + vt_printf(vt, "overwrite %-16s ? (y/n): ", buff); + if (!vt_gets(vt, buff, sizeof(buff)) || vt->brk) return 0; + return toupper((int)buff[0]) == 'Y'; } /* login ---------------------------------------------------------------------*/ -static int login(vt_t *vt) -{ - char buff[256]; - - trace(3,"login: passwd=%s type=%d\n",passwd,vt->type); - - if (!*passwd||!vt->type) return 1; - - while (!(intflg&2)) { - if (!vt_printf(vt,"password: ",PRGNAME)) return 0; - vt->blind=1; - if (!vt_gets(vt,buff,sizeof(buff))||vt->brk) { - vt->blind=0; - return 0; - } - vt->blind=0; - if (!strcmp(buff,passwd)) break; - vt_printf(vt,"\ninvalid password\n"); - } - return 1; +static int login(vt_t *vt) { + char buff[256]; + + trace(3, "login: passwd=%s type=%d\n", passwd, vt->type); + + if (!*passwd || !vt->type) return 1; + + while (!(intflg & 2)) { + if (!vt_printf(vt, "password: ", PRGNAME)) return 0; + vt->blind = 1; + if (!vt_gets(vt, buff, sizeof(buff)) || vt->brk) { + vt->blind = 0; + return 0; + } + vt->blind = 0; + if (!strcmp(buff, passwd)) break; + vt_printf(vt, "\ninvalid password\n"); + } + return 1; } /* read receiver commands ----------------------------------------------------*/ -static int readcmd(const char *file, char *cmd, int type) -{ - FILE *fp; - char buff[MAXSTR],*p=cmd; - int i=0; - - trace(3,"readcmd: file=%s\n",file); - - if (!(fp=fopen(file,"r"))) return 0; - - while (fgets(buff,sizeof(buff),fp)) { - if (*buff=='@') i++; - else if (i==type&&p+strlen(buff)+1pcvr[0] = opt->pcvr[1] = pcv0; @@ -380,7 +369,7 @@ static void readant(vt_t *vt, prcopt_t *opt, nav_t *nav, pcvs_t *pcvsr) { if (!pcv) { vt_printf(vt, "no antenna %s in %s", opt->anttype[i], filopt.rcvantp); continue; - } + } opt->pcvr[i] = *pcv; } } else @@ -402,7 +391,7 @@ static void readant(vt_t *vt, prcopt_t *opt, nav_t *nav, pcvs_t *pcvsr) { #endif continue; } - nav->pcvs[i]=*pcv; + nav->pcvs[i] = *pcv; #ifdef TRACE found[i] = 1; #endif @@ -429,873 +418,883 @@ static void readant(vt_t *vt, prcopt_t *opt, nav_t *nav, pcvs_t *pcvsr) { } } /* start rtk server ----------------------------------------------------------*/ -static int startsvr(vt_t *vt) -{ - static sta_t sta[MAXRCV]={{""}}; - double pos[3],npos[3]; - char s1[3][MAXRCVCMD]={"","",""},*cmds[]={NULL,NULL,NULL}; - char s2[3][MAXRCVCMD]={"","",""},*cmds_periodic[]={NULL,NULL,NULL}; - char *ropts[]={rcvopt[0],rcvopt[1],rcvopt[2]}; - char *paths[]={ - strpath[0],strpath[1],strpath[2],strpath[3],strpath[4],strpath[5], - strpath[6],strpath[7] - }; - char errmsg[2048]=""; - int i,stropt[8]={0}; - - trace(3,"startsvr:\n"); - - /* read start commands from command files */ - for (i=0;i<3;i++) { - if (!*rcvcmds[i]) continue; - if (!readcmd(rcvcmds[i],s1[i],0)) { - vt_printf(vt,"no command file: %s\n",rcvcmds[i]); - } - else cmds[i]=s1[i]; - if (!readcmd(rcvcmds[i],s2[i],2)) { - vt_printf(vt,"no command file: %s\n",rcvcmds[i]); - } - else cmds_periodic[i]=s2[i]; - } - /* confirm overwrite */ - if (vt!=NULL) { - for (i=3;i<8;i++) { - if (strtype[i]==STR_FILE&&!confwrite(vt,strpath[i])) return 0; - } - } - if (prcopt.refpos==POSOPT_RTCM) { /* rtcm */ - for (i=0;i<3;i++) prcopt.rb[i]=0.0; - } - pos[0]=nmeapos[0]*D2R; - pos[1]=nmeapos[1]*D2R; - pos[2]=nmeapos[2]; - pos2ecef(pos,npos); - - /* read antenna file */ - readant(vt,&prcopt,&svr.nav,&svr.pcvsr); - - /* read dcb file */ - if (*filopt.dcb) { - strcpy(sta[0].name,sta_name); - readdcb(filopt.dcb,&svr.nav,sta); - } - /* open geoid data file */ - if (solopt[0].geoid>0&&!opengeoid(solopt[0].geoid,filopt.geoid)) { - trace(2,"geoid data open error: %s\n",filopt.geoid); - vt_printf(vt,"geoid data open error: %s\n",filopt.geoid); +static int startsvr(vt_t *vt) { + static sta_t sta[MAXRCV] = {{""}}; + double pos[3], npos[3]; + char s1[3][MAXRCVCMD] = {"", "", ""}, *cmds[] = {NULL, NULL, NULL}; + char s2[3][MAXRCVCMD] = {"", "", ""}, *cmds_periodic[] = {NULL, NULL, NULL}; + char *ropts[] = {rcvopt[0], rcvopt[1], rcvopt[2]}; + char *paths[] = {strpath[0], strpath[1], strpath[2], strpath[3], + strpath[4], strpath[5], strpath[6], strpath[7]}; + char errmsg[2048] = ""; + int i, stropt[8] = {0}; + + trace(3, "startsvr:\n"); + + /* read start commands from command files */ + for (i = 0; i < 3; i++) { + if (!*rcvcmds[i]) continue; + if (!readcmd(rcvcmds[i], s1[i], 0)) { + vt_printf(vt, "no command file: %s\n", rcvcmds[i]); + } else + cmds[i] = s1[i]; + if (!readcmd(rcvcmds[i], s2[i], 2)) { + vt_printf(vt, "no command file: %s\n", rcvcmds[i]); + } else + cmds_periodic[i] = s2[i]; + } + /* confirm overwrite */ + if (vt != NULL) { + for (i = 3; i < 8; i++) { + if (strtype[i] == STR_FILE && !confwrite(vt, strpath[i])) return 0; } - for (i=0;*rcvopts[i].name;i++) modflgr[i]=0; - for (i=0;*sysopts[i].name;i++) modflgs[i]=0; - - /* set stream options */ - stropt[0]=timeout; - stropt[1]=reconnect; - stropt[2]=1000; - stropt[3]=buffsize; - stropt[4]=fswapmargin; - strsetopt(stropt); - - /* set ftp/http directory and proxy */ - strsetdir(filopt.tempdir); - strsetproxy(proxyaddr); - + } + if (prcopt.refpos == POSOPT_RTCM) { /* rtcm */ + for (i = 0; i < 3; i++) prcopt.rb[i] = 0.0; + } + pos[0] = nmeapos[0] * D2R; + pos[1] = nmeapos[1] * D2R; + pos[2] = nmeapos[2]; + pos2ecef(pos, npos); + + /* read antenna file */ + readant(vt, &prcopt, &svr.nav, &svr.pcvsr); + + /* read dcb file */ + if (*filopt.dcb) { + strcpy(sta[0].name, sta_name); + readdcb(filopt.dcb, &svr.nav, sta); + } + /* open geoid data file */ + if (solopt[0].geoid > 0 && !opengeoid(solopt[0].geoid, filopt.geoid)) { + trace(2, "geoid data open error: %s\n", filopt.geoid); + vt_printf(vt, "geoid data open error: %s\n", filopt.geoid); + } + for (i = 0; *rcvopts[i].name; i++) modflgr[i] = 0; + for (i = 0; *sysopts[i].name; i++) modflgs[i] = 0; + + /* set stream options */ + stropt[0] = timeout; + stropt[1] = reconnect; + stropt[2] = 1000; + stropt[3] = buffsize; + stropt[4] = fswapmargin; + strsetopt(stropt); + + /* set ftp/http directory and proxy */ + strsetdir(filopt.tempdir); + strsetproxy(proxyaddr); + #ifdef RTKSHELLCMDS - /* execute start command */ - int ret; - if (*startcmd&&(ret=system(startcmd))) { - trace(2,"command exec error: %s (%d)\n",startcmd,ret); - vt_printf(vt,"command exec error: %s (%d)\n",startcmd,ret); - } + /* execute start command */ + int ret; + if (*startcmd && (ret = system(startcmd))) { + trace(2, "command exec error: %s (%d)\n", startcmd, ret); + vt_printf(vt, "command exec error: %s (%d)\n", startcmd, ret); + } #endif - solopt[0].posf=strfmt[3]; - solopt[1].posf=strfmt[4]; - - /* start rtk server */ - if (!rtksvrstart(&svr,svrcycle,buffsize,strtype,(const char **)paths,strfmt,navmsgsel, - (const char **)cmds,(const char **)cmds_periodic,(const char **)ropts,nmeacycle,nmeareq,npos,&prcopt, - solopt,&moni,errmsg)) { - trace(2,"rtk server start error (%s)\n",errmsg); - vt_printf(vt,"rtk server start error (%s)\n",errmsg); - free_pcvs(&svr.pcvsr); - return 0; - } - return 1; + solopt[0].posf = strfmt[3]; + solopt[1].posf = strfmt[4]; + + /* start rtk server */ + if (!rtksvrstart(&svr, svrcycle, buffsize, strtype, (const char **)paths, strfmt, navmsgsel, + (const char **)cmds, (const char **)cmds_periodic, (const char **)ropts, + nmeacycle, nmeareq, npos, &prcopt, solopt, &moni, errmsg)) { + trace(2, "rtk server start error (%s)\n", errmsg); + vt_printf(vt, "rtk server start error (%s)\n", errmsg); + free_pcvs(&svr.pcvsr); + return 0; + } + return 1; } /* stop rtk server -----------------------------------------------------------*/ -static void stopsvr(vt_t *vt) -{ - char s[3][MAXRCVCMD]={"","",""},*cmds[]={NULL,NULL,NULL}; - int i; - - trace(3,"stopsvr:\n"); - - if (!svr.state) return; - - /* read stop commands from command files */ - for (i=0;i<3;i++) { - if (!*rcvcmds[i]) continue; - if (!readcmd(rcvcmds[i],s[i],1)) { - vt_printf(vt,"no command file: %s\n",rcvcmds[i]); - } - else cmds[i]=s[i]; - } - /* stop rtk server */ - rtksvrstop(&svr,(const char **)cmds); - +static void stopsvr(vt_t *vt) { + char s[3][MAXRCVCMD] = {"", "", ""}, *cmds[] = {NULL, NULL, NULL}; + int i; + + trace(3, "stopsvr:\n"); + + if (!svr.state) return; + + /* read stop commands from command files */ + for (i = 0; i < 3; i++) { + if (!*rcvcmds[i]) continue; + if (!readcmd(rcvcmds[i], s[i], 1)) { + vt_printf(vt, "no command file: %s\n", rcvcmds[i]); + } else + cmds[i] = s[i]; + } + /* stop rtk server */ + rtksvrstop(&svr, (const char **)cmds); + #ifdef RTKSHELLCMDS - /* execute stop command */ - int ret; - if (*stopcmd&&(ret=system(stopcmd))) { - trace(2,"command exec error: %s (%d)\n",stopcmd,ret); - vt_printf(vt,"command exec error: %s (%d)\n",stopcmd,ret); - } + /* execute stop command */ + int ret; + if (*stopcmd && (ret = system(stopcmd))) { + trace(2, "command exec error: %s (%d)\n", stopcmd, ret); + vt_printf(vt, "command exec error: %s (%d)\n", stopcmd, ret); + } #endif - if (solopt[0].geoid>0) closegeoid(); + if (solopt[0].geoid > 0) closegeoid(); - free_pcvs(&svr.pcvsr); + free_pcvs(&svr.pcvsr); - vt_printf(vt,"stop rtk server\n"); + vt_printf(vt, "stop rtk server\n"); } /* print time ----------------------------------------------------------------*/ -static void prtime(vt_t *vt, gtime_t time) -{ - double tow; - int week; - char tstr[40]=""; - - if (timetype==1) { - time2str(gpst2utc(time),tstr,2); - } - else if (timetype==2) { - time2str(timeadd(gpst2utc(time),9*3600.0),tstr,2); - } - else if (timetype==3) { - tow=time2gpst(time,&week); snprintf(tstr,sizeof(tstr)," %04d %9.2f",week,tow); - } - else time2str(time,tstr,1); - vt_printf(vt,"%s ",tstr); +static void prtime(vt_t *vt, gtime_t time) { + double tow; + int week; + char tstr[40] = ""; + + if (timetype == 1) { + time2str(gpst2utc(time), tstr, 2); + } else if (timetype == 2) { + time2str(timeadd(gpst2utc(time), 9 * 3600.0), tstr, 2); + } else if (timetype == 3) { + tow = time2gpst(time, &week); + snprintf(tstr, sizeof(tstr), " %04d %9.2f", week, tow); + } else + time2str(time, tstr, 1); + vt_printf(vt, "%s ", tstr); } /* print solution ------------------------------------------------------------*/ -static void prsolution(vt_t *vt, const sol_t *sol, const double *rb) -{ - const char *solstr[]={"------","FIX","FLOAT","SBAS","DGPS","SINGLE","PPP",""}; - double pos[3]={0},Qr[9],Qe[9]={0},dms1[3]={0},dms2[3]={0},bl[3]={0}; - double enu[3]={0},pitch=0.0,yaw=0.0,len; - int i; - - trace(4,"prsolution:\n"); - - if (sol->time.time==0||!sol->stat) return; - prtime(vt,sol->time); - vt_printf(vt,"(%-6s)",solstr[sol->stat]); - - if (norm(sol->rr,3)>0.0&&norm(rb,3)>0.0) { - for (i=0;i<3;i++) bl[i]=sol->rr[i]-rb[i]; - } - len=norm(bl,3); - Qr[0]=sol->qr[0]; - Qr[4]=sol->qr[1]; - Qr[8]=sol->qr[2]; - Qr[1]=Qr[3]=sol->qr[3]; - Qr[5]=Qr[7]=sol->qr[4]; - Qr[2]=Qr[6]=sol->qr[5]; - - if (soltype==0) { - if (norm(sol->rr,3)>0.0) { - ecef2pos(sol->rr,pos); - covenu(pos,Qr,Qe); - deg2dms(pos[0]*R2D,dms1,4); - deg2dms(pos[1]*R2D,dms2,4); - if (solopt[0].height==1) pos[2]-=geoidh(pos); /* geodetic */ - } - vt_printf(vt," %s:%2.0f %02.0f %07.4f",pos[0]<0?"S":"N",fabs(dms1[0]),dms1[1],dms1[2]); - vt_printf(vt," %s:%3.0f %02.0f %07.4f",pos[1]<0?"W":"E",fabs(dms2[0]),dms2[1],dms2[2]); - vt_printf(vt," H:%8.3f",pos[2]); - if (solflag&1) { - vt_printf(vt," (N:%6.3f E:%6.3f U:%6.3f)",SQRT(Qe[4]),SQRT(Qe[0]),SQRT(Qe[8])); - } - } - else if (soltype==1) { - if (norm(sol->rr,3)>0.0) { - ecef2pos(sol->rr,pos); - covenu(pos,Qr,Qe); - if (solopt[0].height==1) pos[2]-=geoidh(pos); /* geodetic */ - } - vt_printf(vt," %s:%11.8f",pos[0]<0.0?"S":"N",fabs(pos[0])*R2D); - vt_printf(vt," %s:%12.8f",pos[1]<0.0?"W":"E",fabs(pos[1])*R2D); - vt_printf(vt," H:%8.3f",pos[2]); - if (solflag&1) { - vt_printf(vt," (E:%6.3f N:%6.3f U:%6.3fm)",SQRT(Qe[0]),SQRT(Qe[4]),SQRT(Qe[8])); - } - } - else if (soltype==2) { - vt_printf(vt," X:%12.3f",sol->rr[0]); - vt_printf(vt," Y:%12.3f",sol->rr[1]); - vt_printf(vt," Z:%12.3f",sol->rr[2]); - if (solflag&1) { - vt_printf(vt," (X:%6.3f Y:%6.3f Z:%6.3f)",SQRT(Qr[0]),SQRT(Qr[4]),SQRT(Qr[8])); - } - } - else if (soltype==3) { - if (len>0.0) { - ecef2pos(rb,pos); - ecef2enu(pos,bl,enu); - covenu(pos,Qr,Qe); - } - vt_printf(vt," E:%12.3f",enu[0]); - vt_printf(vt," N:%12.3f",enu[1]); - vt_printf(vt," U:%12.3f",enu[2]); - if (solflag&1) { - vt_printf(vt," (E:%6.3f N:%6.3f U:%6.3f)",SQRT(Qe[0]),SQRT(Qe[4]),SQRT(Qe[8])); - } - } - else if (soltype==4) { - if (len>0.0) { - ecef2pos(rb,pos); - ecef2enu(pos,bl,enu); - covenu(pos,Qr,Qe); - pitch=asin(enu[2]/len); - yaw=atan2(enu[0],enu[1]); if (yaw<0.0) yaw+=2.0*PI; - } - vt_printf(vt," P:%12.3f",pitch*R2D); - vt_printf(vt," Y:%12.3f",yaw*R2D); - vt_printf(vt," L:%12.3f",len); - if (solflag&1) { - vt_printf(vt," (E:%6.3f N:%6.3f U:%6.3f)",SQRT(Qe[0]),SQRT(Qe[4]),SQRT(Qe[8])); - } - } - if (solflag&2) { - vt_printf(vt," A:%4.1f R:%5.1f N:%2d",sol->age,sol->ratio,sol->ns); +static void prsolution(vt_t *vt, const sol_t *sol, const double *rb) { + const char *solstr[] = {"------", "FIX", "FLOAT", "SBAS", "DGPS", "SINGLE", "PPP", ""}; + double pos[3] = {0}, Qr[9], Qe[9] = {0}, dms1[3] = {0}, dms2[3] = {0}, bl[3] = {0}; + double enu[3] = {0}, pitch = 0.0, yaw = 0.0, len; + int i; + + trace(4, "prsolution:\n"); + + if (sol->time.time == 0 || !sol->stat) return; + prtime(vt, sol->time); + vt_printf(vt, "(%-6s)", solstr[sol->stat]); + + if (norm(sol->rr, 3) > 0.0 && norm(rb, 3) > 0.0) { + for (i = 0; i < 3; i++) bl[i] = sol->rr[i] - rb[i]; + } + len = norm(bl, 3); + Qr[0] = sol->qr[0]; + Qr[4] = sol->qr[1]; + Qr[8] = sol->qr[2]; + Qr[1] = Qr[3] = sol->qr[3]; + Qr[5] = Qr[7] = sol->qr[4]; + Qr[2] = Qr[6] = sol->qr[5]; + + if (soltype == 0) { + if (norm(sol->rr, 3) > 0.0) { + ecef2pos(sol->rr, pos); + covenu(pos, Qr, Qe); + deg2dms(pos[0] * R2D, dms1, 4); + deg2dms(pos[1] * R2D, dms2, 4); + if (solopt[0].height == 1) pos[2] -= geoidh(pos); /* geodetic */ + } + vt_printf(vt, " %s:%2.0f %02.0f %07.4f", pos[0] < 0 ? "S" : "N", fabs(dms1[0]), dms1[1], + dms1[2]); + vt_printf(vt, " %s:%3.0f %02.0f %07.4f", pos[1] < 0 ? "W" : "E", fabs(dms2[0]), dms2[1], + dms2[2]); + vt_printf(vt, " H:%8.3f", pos[2]); + if (solflag & 1) { + vt_printf(vt, " (N:%6.3f E:%6.3f U:%6.3f)", SQRT(Qe[4]), SQRT(Qe[0]), SQRT(Qe[8])); + } + } else if (soltype == 1) { + if (norm(sol->rr, 3) > 0.0) { + ecef2pos(sol->rr, pos); + covenu(pos, Qr, Qe); + if (solopt[0].height == 1) pos[2] -= geoidh(pos); /* geodetic */ + } + vt_printf(vt, " %s:%11.8f", pos[0] < 0.0 ? "S" : "N", fabs(pos[0]) * R2D); + vt_printf(vt, " %s:%12.8f", pos[1] < 0.0 ? "W" : "E", fabs(pos[1]) * R2D); + vt_printf(vt, " H:%8.3f", pos[2]); + if (solflag & 1) { + vt_printf(vt, " (E:%6.3f N:%6.3f U:%6.3fm)", SQRT(Qe[0]), SQRT(Qe[4]), SQRT(Qe[8])); + } + } else if (soltype == 2) { + vt_printf(vt, " X:%12.3f", sol->rr[0]); + vt_printf(vt, " Y:%12.3f", sol->rr[1]); + vt_printf(vt, " Z:%12.3f", sol->rr[2]); + if (solflag & 1) { + vt_printf(vt, " (X:%6.3f Y:%6.3f Z:%6.3f)", SQRT(Qr[0]), SQRT(Qr[4]), SQRT(Qr[8])); + } + } else if (soltype == 3) { + if (len > 0.0) { + ecef2pos(rb, pos); + ecef2enu(pos, bl, enu); + covenu(pos, Qr, Qe); + } + vt_printf(vt, " E:%12.3f", enu[0]); + vt_printf(vt, " N:%12.3f", enu[1]); + vt_printf(vt, " U:%12.3f", enu[2]); + if (solflag & 1) { + vt_printf(vt, " (E:%6.3f N:%6.3f U:%6.3f)", SQRT(Qe[0]), SQRT(Qe[4]), SQRT(Qe[8])); + } + } else if (soltype == 4) { + if (len > 0.0) { + ecef2pos(rb, pos); + ecef2enu(pos, bl, enu); + covenu(pos, Qr, Qe); + pitch = asin(enu[2] / len); + yaw = atan2(enu[0], enu[1]); + if (yaw < 0.0) yaw += 2.0 * PI; + } + vt_printf(vt, " P:%12.3f", pitch * R2D); + vt_printf(vt, " Y:%12.3f", yaw * R2D); + vt_printf(vt, " L:%12.3f", len); + if (solflag & 1) { + vt_printf(vt, " (E:%6.3f N:%6.3f U:%6.3f)", SQRT(Qe[0]), SQRT(Qe[4]), SQRT(Qe[8])); } - vt_printf(vt,"\n"); + } + if (solflag & 2) { + vt_printf(vt, " A:%4.1f R:%5.1f N:%2d", sol->age, sol->ratio, sol->ns); + } + vt_printf(vt, "\n"); } /* print status --------------------------------------------------------------*/ -static void prstatus(vt_t *vt) -{ - const char *svrstate[]={"stop","run"},*type[]={"rover","base","corr"}; - const char *sol[]={"-","fix","float","SBAS","DGPS","single","PPP",""}; - const char *mode[]={ - "single","DGPS","kinematic","static","static-start","moving-base","fixed", - "PPP-kinema","PPP-static" - }; - gtime_t eventime={0}; - const char *freq[]={"-","L1","L1+L2","L1+L2+E5b","L1+L2+E5b+L5","5","6","7"}; - rtcm_t rtcm[3]; - pthread_t thread; - int i,j,n,cycle,state,rtkstat,nsat0,nsat1,prcout,rcvcount,tmcount,timevalid,nave; - int cputime,nb[3]={0},nmsg[3][10]={{0}}; - char tstr[40],tmstr[40],s[1024],*p; - double runtime,rt[3]={0},dop[4]={0},rr[3],bl1=0.0,bl2=0.0; - double azel[MAXSAT*2],pos[3],vel[3],*del; - - trace(4,"prstatus:\n"); - - rtk_t *rtk = (rtk_t *)malloc(sizeof(rtk_t)); - if (rtk == NULL) return; +static void prstatus(vt_t *vt) { + const char *svrstate[] = {"stop", "run"}, *type[] = {"rover", "base", "corr"}; + const char *sol[] = {"-", "fix", "float", "SBAS", "DGPS", "single", "PPP", ""}; + const char *mode[] = {"single", "DGPS", "kinematic", "static", "static-start", + "moving-base", "fixed", "PPP-kinema", "PPP-static"}; + gtime_t eventime = {0}; + const char *freq[] = {"-", "L1", "L1+L2", "L1+L2+E5b", "L1+L2+E5b+L5", "5", "6", "7"}; + rtcm_t rtcm[3]; + pthread_t thread; + int i, j, n, cycle, state, rtkstat, nsat0, nsat1, prcout, rcvcount, tmcount, timevalid, nave; + int cputime, nb[3] = {0}, nmsg[3][10] = {{0}}; + char tstr[40], tmstr[40], s[1024], *p; + double runtime, rt[3] = {0}, dop[4] = {0}, rr[3], bl1 = 0.0, bl2 = 0.0; + double azel[MAXSAT * 2], pos[3], vel[3], *del; - rtksvrlock(&svr); - *rtk=svr.rtk; - thread=svr.thread; - cycle=svr.cycle; - state=svr.state; - rtkstat=svr.rtk.sol.stat; - nsat0=svr.obs[0][0].n; - nsat1=svr.obs[1][0].n; - rcvcount = svr.raw[0].obs.rcvcount; - tmcount = svr.raw[0].obs.tmcount; - cputime=svr.cputime; - prcout=svr.prcout; - nave=svr.nave; - for (i=0;i<3;i++) nb[i]=svr.nb[i]; - for (i=0;i<3;i++) for (j=0;j<10;j++) { - nmsg[i][j]=svr.nmsg[i][j]; - } - if (svr.state) { - runtime=(double)(tickget()-svr.tick)/1000.0; - rt[0]=floor(runtime/3600.0); runtime-=rt[0]*3600.0; - rt[1]=floor(runtime/60.0); rt[2]=runtime-rt[1]*60.0; - } - for (i=0;i<3;i++) rtcm[i]=svr.rtcm[i]; - if (svr.raw[0].obs.data != NULL) { - timevalid = svr.raw[0].obs.data[0].timevalid; - eventime = svr.raw[0].obs.data[0].eventime; - } - time2str(eventime,tmstr,9); - rtksvrunlock(&svr); - - for (i=n=0;iopt.mode==PMODE_SINGLE&&!rtk->ssat[i].vs) continue; - if (rtk->opt.mode!=PMODE_SINGLE&&!rtk->ssat[i].vsat[0]) continue; - azel[ n*2]=rtk->ssat[i].azel[0]; - azel[1+n*2]=rtk->ssat[i].azel[1]; - n++; - } - dops(n,azel,0.0,dop); - - vt_printf(vt,"\n%s%-28s: %s%s\n",ESC_BOLD,"Parameter","Value",ESC_RESET); - vt_printf(vt,"%-28s: %s %s\n","rtklib version",VER_RTKLIB,PATCH_LEVEL); - vt_printf(vt,"%-28s: %lx\n","rtk server thread",(unsigned long)thread); - vt_printf(vt,"%-28s: %s\n","rtk server state",svrstate[state]); - vt_printf(vt,"%-28s: %d\n","processing cycle (ms)",cycle); - vt_printf(vt,"%-28s: %s\n","positioning mode",mode[rtk->opt.mode]); - vt_printf(vt,"%-28s: %s\n","frequencies",freq[rtk->opt.nf]); - vt_printf(vt,"%-28s: %02.0f:%02.0f:%04.1f\n","accumulated time to run",rt[0],rt[1],rt[2]); - vt_printf(vt,"%-28s: %d\n","cpu time for a cycle (ms)",cputime); - vt_printf(vt,"%-28s: %d\n","missing obs data count",prcout); - vt_printf(vt,"%-28s: %d,%d\n","bytes in input buffer",nb[0],nb[1]); - for (i=0;i<3;i++) { - sprintf(s,"# of input data %s",type[i]); - vt_printf(vt,"%-28s: obs(%d),nav(%d),gnav(%d),ion(%d),sbs(%d),pos(%d),dgps(%d),ssr(%d),err(%d)\n", - s,nmsg[i][0],nmsg[i][1],nmsg[i][6],nmsg[i][2],nmsg[i][3], - nmsg[i][4],nmsg[i][5],nmsg[i][7],nmsg[i][9]); + trace(4, "prstatus:\n"); + + rtk_t *rtk = (rtk_t *)malloc(sizeof(rtk_t)); + if (rtk == NULL) return; + + rtksvrlock(&svr); + *rtk = svr.rtk; + thread = svr.thread; + cycle = svr.cycle; + state = svr.state; + rtkstat = svr.rtk.sol.stat; + nsat0 = svr.obs[0][0].n; + nsat1 = svr.obs[1][0].n; + rcvcount = svr.raw[0].obs.rcvcount; + tmcount = svr.raw[0].obs.tmcount; + cputime = svr.cputime; + prcout = svr.prcout; + nave = svr.nave; + for (i = 0; i < 3; i++) nb[i] = svr.nb[i]; + for (i = 0; i < 3; i++) + for (j = 0; j < 10; j++) { + nmsg[i][j] = svr.nmsg[i][j]; + } + if (svr.state) { + runtime = (double)(tickget() - svr.tick) / 1000.0; + rt[0] = floor(runtime / 3600.0); + runtime -= rt[0] * 3600.0; + rt[1] = floor(runtime / 60.0); + rt[2] = runtime - rt[1] * 60.0; + } + for (i = 0; i < 3; i++) rtcm[i] = svr.rtcm[i]; + if (svr.raw[0].obs.data != NULL) { + timevalid = svr.raw[0].obs.data[0].timevalid; + eventime = svr.raw[0].obs.data[0].eventime; + } + time2str(eventime, tmstr, 9); + rtksvrunlock(&svr); + + for (i = n = 0; i < MAXSAT; i++) { + if (rtk->opt.mode == PMODE_SINGLE && !rtk->ssat[i].vs) continue; + if (rtk->opt.mode != PMODE_SINGLE && !rtk->ssat[i].vsat[0]) continue; + azel[n * 2] = rtk->ssat[i].azel[0]; + azel[1 + n * 2] = rtk->ssat[i].azel[1]; + n++; + } + dops(n, azel, 0.0, dop); + + vt_printf(vt, "\n%s%-28s: %s%s\n", ESC_BOLD, "Parameter", "Value", ESC_RESET); + vt_printf(vt, "%-28s: %s %s\n", "rtklib version", VER_RTKLIB, PATCH_LEVEL); + vt_printf(vt, "%-28s: %lx\n", "rtk server thread", (unsigned long)thread); + vt_printf(vt, "%-28s: %s\n", "rtk server state", svrstate[state]); + vt_printf(vt, "%-28s: %d\n", "processing cycle (ms)", cycle); + vt_printf(vt, "%-28s: %s\n", "positioning mode", mode[rtk->opt.mode]); + vt_printf(vt, "%-28s: %s\n", "frequencies", freq[rtk->opt.nf]); + vt_printf(vt, "%-28s: %02.0f:%02.0f:%04.1f\n", "accumulated time to run", rt[0], rt[1], rt[2]); + vt_printf(vt, "%-28s: %d\n", "cpu time for a cycle (ms)", cputime); + vt_printf(vt, "%-28s: %d\n", "missing obs data count", prcout); + vt_printf(vt, "%-28s: %d,%d\n", "bytes in input buffer", nb[0], nb[1]); + for (i = 0; i < 3; i++) { + sprintf(s, "# of input data %s", type[i]); + vt_printf(vt, + "%-28s: obs(%d),nav(%d),gnav(%d),ion(%d),sbs(%d),pos(%d),dgps(%d),ssr(%d),err(%d)\n", + s, nmsg[i][0], nmsg[i][1], nmsg[i][6], nmsg[i][2], nmsg[i][3], nmsg[i][4], nmsg[i][5], + nmsg[i][7], nmsg[i][9]); + } + for (i = 0; i < 3; i++) { + p = s; + *p = '\0'; + for (j = 1; j < 100; j++) { + if (rtcm[i].nmsg2[j] == 0) continue; + p += sprintf(p, "%s%d(%d)", p > s ? "," : "", j, rtcm[i].nmsg2[j]); } - for (i=0;i<3;i++) { - p=s; *p='\0'; - for (j=1;j<100;j++) { - if (rtcm[i].nmsg2[j]==0) continue; - p+=sprintf(p,"%s%d(%d)",p>s?",":"",j,rtcm[i].nmsg2[j]); - } - if (rtcm[i].nmsg2[0]>0) { - sprintf(p,"%sother2(%d)",p>s?",":"",rtcm[i].nmsg2[0]); - } - for (j=1;j<300;j++) { - if (rtcm[i].nmsg3[j]==0) continue; - p+=sprintf(p,"%s%d(%d)",p>s?",":"",j+1000,rtcm[i].nmsg3[j]); - } - if (rtcm[i].nmsg3[0]>0) { - sprintf(p,"%sother3(%d)",p>s?",":"",rtcm[i].nmsg3[0]); - } - vt_printf(vt,"%-15s %-9s: %s\n","# of rtcm messages",type[i],s); + if (rtcm[i].nmsg2[0] > 0) { + sprintf(p, "%sother2(%d)", p > s ? "," : "", rtcm[i].nmsg2[0]); } - vt_printf(vt,"%-28s: %s\n","solution status",sol[rtkstat]); - time2str(rtk->sol.time,tstr,9); - vt_printf(vt,"%-28s: %s\n","time of receiver clock rover",rtk->sol.time.time?tstr:"-"); - vt_printf(vt,"%-28s: %.3f,%.3f,%.3f,%.3f\n","time sys offset (ns)",rtk->sol.dtr[1]*1e9, - rtk->sol.dtr[2]*1e9,rtk->sol.dtr[3]*1e9,rtk->sol.dtr[4]*1e9); - vt_printf(vt,"%-28s: %.3f\n","solution interval (s)",rtk->tt); - vt_printf(vt,"%-28s: %.3f\n","age of differential (s)",rtk->sol.age); - vt_printf(vt,"%-28s: %.3f\n","ratio for ar validation",rtk->sol.ratio); - vt_printf(vt,"%-28s: %d\n","# of satellites rover",nsat0); - vt_printf(vt,"%-28s: %d\n","# of satellites base",nsat1); - vt_printf(vt,"%-28s: %d\n","# of valid satellites",rtk->sol.ns); - vt_printf(vt,"%-28s: %.1f,%.1f,%.1f,%.1f\n","GDOP/PDOP/HDOP/VDOP",dop[0],dop[1],dop[2],dop[3]); - vt_printf(vt,"%-28s: %d\n","# of real estimated states",rtk->na); - vt_printf(vt,"%-28s: %d\n","# of all estimated states",rtk->nx); - vt_printf(vt,"%-28s: %.3f,%.3f,%.3f\n","pos xyz single (m) rover", - rtk->sol.rr[0],rtk->sol.rr[1],rtk->sol.rr[2]); - if (norm(rtk->sol.rr,3)>0.0) ecef2pos(rtk->sol.rr,pos); else pos[0]=pos[1]=pos[2]=0.0; - vt_printf(vt,"%-28s: %.8f,%.8f,%.3f\n","pos llh single (deg,m) rover", - pos[0]*R2D,pos[1]*R2D,pos[2]); - ecef2enu(pos,rtk->sol.rr+3,vel); - vt_printf(vt,"%-28s: %.3f,%.3f,%.3f\n","vel enu (m/s) rover",vel[0],vel[1],vel[2]); - vt_printf(vt,"%-28s: %.3f,%.3f,%.3f\n","pos xyz float (m) rover", - rtk->x?rtk->x[0]:0,rtk->x?rtk->x[1]:0,rtk->x?rtk->x[2]:0); - vt_printf(vt,"%-28s: %.3f,%.3f,%.3f\n","pos xyz float std (m) rover", - rtk->P?SQRT(rtk->P[0]):0,rtk->P?SQRT(rtk->P[1+1*rtk->nx]):0,rtk->P?SQRT(rtk->P[2+2*rtk->nx]):0); - vt_printf(vt,"%-28s: %.3f,%.3f,%.3f\n","pos xyz fixed (m) rover", - rtk->xa?rtk->xa[0]:0,rtk->xa?rtk->xa[1]:0,rtk->xa?rtk->xa[2]:0); - vt_printf(vt,"%-28s: %.3f,%.3f,%.3f\n","pos xyz fixed std (m) rover", - rtk->Pa?SQRT(rtk->Pa[0]):0,rtk->Pa?SQRT(rtk->Pa[1+1*rtk->na]):0,rtk->Pa?SQRT(rtk->Pa[2+2*rtk->na]):0); - vt_printf(vt,"%-28s: %.3f,%.3f,%.3f\n","pos xyz (m) base", - rtk->rb[0],rtk->rb[1],rtk->rb[2]); - if (norm(rtk->rb,3)>0.0) ecef2pos(rtk->rb,pos); else pos[0]=pos[1]=pos[2]=0.0; - vt_printf(vt,"%-28s: %.8f,%.8f,%.3f\n","pos llh (deg,m) base", - pos[0]*R2D,pos[1]*R2D,pos[2]); - vt_printf(vt,"%-28s: %d\n","# of average single pos base",nave); - vt_printf(vt,"%-28s: %s\n","ant type rover",rtk->opt.pcvr[0].type); - del=rtk->opt.antdel[0]; - vt_printf(vt,"%-28s: %.4f %.4f %.4f\n","ant delta rover",del[0],del[1],del[2]); - vt_printf(vt,"%-28s: %s\n","ant type base" ,rtk->opt.pcvr[1].type); - del=rtk->opt.antdel[1]; - vt_printf(vt,"%-28s: %.4f %.4f %.4f\n","ant delta base",del[0],del[1],del[2]); - ecef2enu(pos,rtk->rb+3,vel); - vt_printf(vt,"%-28s: %.3f,%.3f,%.3f\n","vel enu (m/s) base", - vel[0],vel[1],vel[2]); - if (rtk->opt.mode>0&&rtk->x&&norm(rtk->x,3)>0.0) { - for (i=0;i<3;i++) rr[i]=rtk->x[i]-rtk->rb[i]; - bl1=norm(rr,3); + for (j = 1; j < 300; j++) { + if (rtcm[i].nmsg3[j] == 0) continue; + p += sprintf(p, "%s%d(%d)", p > s ? "," : "", j + 1000, rtcm[i].nmsg3[j]); } - if (rtk->opt.mode>0&&rtk->xa&&norm(rtk->xa,3)>0.0) { - for (i=0;i<3;i++) rr[i]=rtk->xa[i]-rtk->rb[i]; - bl2=norm(rr,3); + if (rtcm[i].nmsg3[0] > 0) { + sprintf(p, "%sother3(%d)", p > s ? "," : "", rtcm[i].nmsg3[0]); } - vt_printf(vt,"%-28s: %.3f\n","baseline length float (m)",bl1); - vt_printf(vt,"%-28s: %.3f\n","baseline length fixed (m)",bl2); - vt_printf(vt,"%-28s: %s\n","last time mark",tmcount ? tmstr : "-"); - vt_printf(vt,"%-28s: %d\n","receiver time mark count",rcvcount); - vt_printf(vt,"%-28s: %d\n","rtklib time mark count",tmcount); - free(rtk); + vt_printf(vt, "%-15s %-9s: %s\n", "# of rtcm messages", type[i], s); + } + vt_printf(vt, "%-28s: %s\n", "solution status", sol[rtkstat]); + time2str(rtk->sol.time, tstr, 9); + vt_printf(vt, "%-28s: %s\n", "time of receiver clock rover", rtk->sol.time.time ? tstr : "-"); + vt_printf(vt, "%-28s: %.3f,%.3f,%.3f,%.3f\n", "time sys offset (ns)", rtk->sol.dtr[1] * 1e9, + rtk->sol.dtr[2] * 1e9, rtk->sol.dtr[3] * 1e9, rtk->sol.dtr[4] * 1e9); + vt_printf(vt, "%-28s: %.3f\n", "solution interval (s)", rtk->tt); + vt_printf(vt, "%-28s: %.3f\n", "age of differential (s)", rtk->sol.age); + vt_printf(vt, "%-28s: %.3f\n", "ratio for ar validation", rtk->sol.ratio); + vt_printf(vt, "%-28s: %d\n", "# of satellites rover", nsat0); + vt_printf(vt, "%-28s: %d\n", "# of satellites base", nsat1); + vt_printf(vt, "%-28s: %d\n", "# of valid satellites", rtk->sol.ns); + vt_printf(vt, "%-28s: %.1f,%.1f,%.1f,%.1f\n", "GDOP/PDOP/HDOP/VDOP", dop[0], dop[1], dop[2], + dop[3]); + vt_printf(vt, "%-28s: %d\n", "# of real estimated states", rtk->na); + vt_printf(vt, "%-28s: %d\n", "# of all estimated states", rtk->nx); + vt_printf(vt, "%-28s: %.3f,%.3f,%.3f\n", "pos xyz single (m) rover", rtk->sol.rr[0], + rtk->sol.rr[1], rtk->sol.rr[2]); + if (norm(rtk->sol.rr, 3) > 0.0) + ecef2pos(rtk->sol.rr, pos); + else + pos[0] = pos[1] = pos[2] = 0.0; + vt_printf(vt, "%-28s: %.8f,%.8f,%.3f\n", "pos llh single (deg,m) rover", pos[0] * R2D, + pos[1] * R2D, pos[2]); + ecef2enu(pos, rtk->sol.rr + 3, vel); + vt_printf(vt, "%-28s: %.3f,%.3f,%.3f\n", "vel enu (m/s) rover", vel[0], vel[1], vel[2]); + vt_printf(vt, "%-28s: %.3f,%.3f,%.3f\n", "pos xyz float (m) rover", rtk->x ? rtk->x[0] : 0, + rtk->x ? rtk->x[1] : 0, rtk->x ? rtk->x[2] : 0); + vt_printf(vt, "%-28s: %.3f,%.3f,%.3f\n", "pos xyz float std (m) rover", + rtk->P ? SQRT(rtk->P[0]) : 0, rtk->P ? SQRT(rtk->P[1 + 1 * rtk->nx]) : 0, + rtk->P ? SQRT(rtk->P[2 + 2 * rtk->nx]) : 0); + vt_printf(vt, "%-28s: %.3f,%.3f,%.3f\n", "pos xyz fixed (m) rover", rtk->xa ? rtk->xa[0] : 0, + rtk->xa ? rtk->xa[1] : 0, rtk->xa ? rtk->xa[2] : 0); + vt_printf(vt, "%-28s: %.3f,%.3f,%.3f\n", "pos xyz fixed std (m) rover", + rtk->Pa ? SQRT(rtk->Pa[0]) : 0, rtk->Pa ? SQRT(rtk->Pa[1 + 1 * rtk->na]) : 0, + rtk->Pa ? SQRT(rtk->Pa[2 + 2 * rtk->na]) : 0); + vt_printf(vt, "%-28s: %.3f,%.3f,%.3f\n", "pos xyz (m) base", rtk->rb[0], rtk->rb[1], rtk->rb[2]); + if (norm(rtk->rb, 3) > 0.0) + ecef2pos(rtk->rb, pos); + else + pos[0] = pos[1] = pos[2] = 0.0; + vt_printf(vt, "%-28s: %.8f,%.8f,%.3f\n", "pos llh (deg,m) base", pos[0] * R2D, pos[1] * R2D, + pos[2]); + vt_printf(vt, "%-28s: %d\n", "# of average single pos base", nave); + vt_printf(vt, "%-28s: %s\n", "ant type rover", rtk->opt.pcvr[0].type); + del = rtk->opt.antdel[0]; + vt_printf(vt, "%-28s: %.4f %.4f %.4f\n", "ant delta rover", del[0], del[1], del[2]); + vt_printf(vt, "%-28s: %s\n", "ant type base", rtk->opt.pcvr[1].type); + del = rtk->opt.antdel[1]; + vt_printf(vt, "%-28s: %.4f %.4f %.4f\n", "ant delta base", del[0], del[1], del[2]); + ecef2enu(pos, rtk->rb + 3, vel); + vt_printf(vt, "%-28s: %.3f,%.3f,%.3f\n", "vel enu (m/s) base", vel[0], vel[1], vel[2]); + if (rtk->opt.mode > 0 && rtk->x && norm(rtk->x, 3) > 0.0) { + for (i = 0; i < 3; i++) rr[i] = rtk->x[i] - rtk->rb[i]; + bl1 = norm(rr, 3); + } + if (rtk->opt.mode > 0 && rtk->xa && norm(rtk->xa, 3) > 0.0) { + for (i = 0; i < 3; i++) rr[i] = rtk->xa[i] - rtk->rb[i]; + bl2 = norm(rr, 3); + } + vt_printf(vt, "%-28s: %.3f\n", "baseline length float (m)", bl1); + vt_printf(vt, "%-28s: %.3f\n", "baseline length fixed (m)", bl2); + vt_printf(vt, "%-28s: %s\n", "last time mark", tmcount ? tmstr : "-"); + vt_printf(vt, "%-28s: %d\n", "receiver time mark count", rcvcount); + vt_printf(vt, "%-28s: %d\n", "rtklib time mark count", tmcount); + free(rtk); } /* print satellite -----------------------------------------------------------*/ -static void prsatellite(vt_t *vt, int nf) -{ - double az,el; - char id[8]; - int i,j,fix,frq[]={1,2,5,7,8,6}; - - trace(4,"prsatellite:\n"); - - rtk_t *rtk = (rtk_t *)malloc(sizeof(rtk_t)); - if (rtk == NULL) return; +static void prsatellite(vt_t *vt, int nf) { + double az, el; + char id[8]; + int i, j, fix, frq[] = {1, 2, 5, 7, 8, 6}; - rtksvrlock(&svr); - *rtk=svr.rtk; - rtksvrunlock(&svr); - if (nf<=0||nf>NFREQ) nf=NFREQ; - vt_printf(vt,"\n%s%3s %2s %5s %4s",ESC_BOLD,"SAT","C1","Az","El"); - for (j=0;jssat[i].azel[1]<=0.0) continue; - satno2id(i+1,id); - vt_printf(vt,"%3s %2s",id,rtk->ssat[i].vs?"OK":"-"); - az=rtk->ssat[i].azel[0]*R2D; if (az<0.0) az+=360.0; - el=rtk->ssat[i].azel[1]*R2D; - vt_printf(vt," %5.1f %4.1f",az,el); - for (j=0;jssat[i].vsat[j]?"OK":"-"); - for (j=0;jssat[i].fix[j]; - vt_printf(vt," %5s",fix==1?"FLOAT":(fix==2?"FIX":(fix==3?"HOLD":"-"))); - } - for (j=0;jssat[i].resp[j]); - for (j=0;jssat[i].resc[j]); - for (j=0;jssat[i].slipc[j]); - for (j=0;jssat[i].lock [j]); - for (j=0;jssat[i].rejc [j]); - vt_printf(vt,"\n"); - } - free(rtk); + trace(4, "prsatellite:\n"); + + rtk_t *rtk = (rtk_t *)malloc(sizeof(rtk_t)); + if (rtk == NULL) return; + + rtksvrlock(&svr); + *rtk = svr.rtk; + rtksvrunlock(&svr); + if (nf <= 0 || nf > NFREQ) nf = NFREQ; + vt_printf(vt, "\n%s%3s %2s %5s %4s", ESC_BOLD, "SAT", "C1", "Az", "El"); + for (j = 0; j < nf; j++) vt_printf(vt, " L%d", frq[j]); + for (j = 0; j < nf; j++) vt_printf(vt, " Fix%d", frq[j]); + for (j = 0; j < nf; j++) vt_printf(vt, " P%dRes", frq[j]); + for (j = 0; j < nf; j++) vt_printf(vt, " L%dRes", frq[j]); + for (j = 0; j < nf; j++) vt_printf(vt, " Sl%d", frq[j]); + for (j = 0; j < nf; j++) vt_printf(vt, " Lock%d", frq[j]); + for (j = 0; j < nf; j++) vt_printf(vt, " Rj%d", frq[j]); + vt_printf(vt, "%s\n", ESC_RESET); + + for (i = 0; i < MAXSAT; i++) { + if (rtk->ssat[i].azel[1] <= 0.0) continue; + satno2id(i + 1, id); + vt_printf(vt, "%3s %2s", id, rtk->ssat[i].vs ? "OK" : "-"); + az = rtk->ssat[i].azel[0] * R2D; + if (az < 0.0) az += 360.0; + el = rtk->ssat[i].azel[1] * R2D; + vt_printf(vt, " %5.1f %4.1f", az, el); + for (j = 0; j < nf; j++) vt_printf(vt, " %2s", rtk->ssat[i].vsat[j] ? "OK" : "-"); + for (j = 0; j < nf; j++) { + fix = rtk->ssat[i].fix[j]; + vt_printf(vt, " %5s", fix == 1 ? "FLOAT" : (fix == 2 ? "FIX" : (fix == 3 ? "HOLD" : "-"))); + } + for (j = 0; j < nf; j++) vt_printf(vt, "%7.3f", rtk->ssat[i].resp[j]); + for (j = 0; j < nf; j++) vt_printf(vt, "%8.4f", rtk->ssat[i].resc[j]); + for (j = 0; j < nf; j++) vt_printf(vt, " %4d", rtk->ssat[i].slipc[j]); + for (j = 0; j < nf; j++) vt_printf(vt, " %6d", rtk->ssat[i].lock[j]); + for (j = 0; j < nf; j++) vt_printf(vt, " %3d", rtk->ssat[i].rejc[j]); + vt_printf(vt, "\n"); + } + free(rtk); } /* print observation data ----------------------------------------------------*/ -static void probserv(vt_t *vt, int nf) -{ - char tstr[40],id[8]; - int i,j,n=0,frq[]={1,2,5,7,8,6,9}; - - trace(4,"probserv:\n"); - - obsd_t *obs = (obsd_t *)calloc(MAXOBS * 2, sizeof(obsd_t)); - if (obs == NULL) { - trace(1, "probserv obsd_t alloc failed\n"); - return; - } +static void probserv(vt_t *vt, int nf) { + char tstr[40], id[8]; + int i, j, n = 0, frq[] = {1, 2, 5, 7, 8, 6, 9}; - rtksvrlock(&svr); - for (i=0;iNFREQ) nf=NFREQ; - vt_printf(vt,"\n%s%-22s %3s %s",ESC_BOLD," TIME(GPST)","SAT","R"); - for (i=0;i NFREQ) nf = NFREQ; + vt_printf(vt, "\n%s%-22s %3s %s", ESC_BOLD, " TIME(GPST)", "SAT", "R"); + for (i = 0; i < nf; i++) vt_printf(vt, " P%d(m)", frq[i]); + for (i = 0; i < nf; i++) vt_printf(vt, " L%d(cyc)", frq[i]); + for (i = 0; i < nf; i++) vt_printf(vt, " D%d(Hz)", frq[i]); + for (i = 0; i < nf; i++) vt_printf(vt, " S%d", frq[i]); + vt_printf(vt, " LLI%s\n", ESC_RESET); + for (i = 0; i < n; i++) { + time2str(obs[i].time, tstr, 2); + satno2id(obs[i].sat, id); + vt_printf(vt, "%s %3s %d", tstr, id, obs[i].rcv); + for (j = 0; j < nf; j++) vt_printf(vt, "%13.3f", obs[i].P[j]); + for (j = 0; j < nf; j++) vt_printf(vt, "%14.3f", obs[i].L[j]); + for (j = 0; j < nf; j++) vt_printf(vt, "%8.1f", obs[i].D[j]); + for (j = 0; j < nf; j++) vt_printf(vt, "%3.0f", obs[i].SNR[j]); + for (j = 0; j < nf; j++) vt_printf(vt, "%2d", obs[i].LLI[j]); + vt_printf(vt, "\n"); + } + free(obs); } /* print navigation data -----------------------------------------------------*/ -static void prnavidata(vt_t *vt) -{ - eph_t eph[MAXSAT]; - geph_t geph[MAXPRNGLO]; - double ion[8],utc[8]; - gtime_t time; - char id[8],s1[64],s2[64],s3[64]; - int i,valid,prn; - - trace(4,"prnavidata:\n"); - - rtksvrlock(&svr); - time=svr.rtk.sol.time; - for (i=0;i0) { - svr.rtk.errbuf[n]='\0'; - vt_puts(vt,svr.rtk.errbuf); - svr.rtk.neb=0; - } - rtksvrunlock(&svr); +static void prerror(vt_t *vt) { + int n; + + trace(4, "prerror:\n"); + + rtksvrlock(&svr); + if ((n = svr.rtk.neb) > 0) { + svr.rtk.errbuf[n] = '\0'; + vt_puts(vt, svr.rtk.errbuf); + svr.rtk.neb = 0; + } + rtksvrunlock(&svr); } /* print stream --------------------------------------------------------------*/ -static void prstream(vt_t *vt) -{ - const char *ch[]={ - "input rover","input base","input corr","output sol1","output sol2", - "log rover","log base","log corr","monitor" - }; - const char *type[]={ - "-","serial","file","tcpsvr","tcpcli","ntrips","ntripc","ftp", - "http","ntripcas","udpsvr","udpcli","membuf" - }; - const char *fmt[]={"rtcm2","rtcm3","oem4","","ubx","swift","hemis","skytreq", - "javad","nvs","binex","rt17","sbf","","unicore","sp3",""}; - const char *sol[]={"llh","xyz","enu","nmea","stat","-"}; - stream_t stream[9]; - int i,format[9]={0}; - - trace(4,"prstream:\n"); - - rtksvrlock(&svr); - for (i=0;i<8;i++) stream[i]=svr.stream[i]; - for (i=0;i<3;i++) format[i]=svr.format[i]; - for (i=3;i<5;i++) format[i]=svr.solopt[i-3].posf; - stream[8]=moni; - format[8]=SOLF_LLH; - rtksvrunlock(&svr); - - vt_printf(vt,"\n%s%-12s %-8s %-5s %s %10s %7s %10s %7s %-24s %s%s\n",ESC_BOLD, - "Stream","Type","Fmt","S","In-byte","In-bps","Out-byte","Out-bps", - "Path","Message",ESC_RESET); - for (i=0;i<9;i++) { - vt_printf(vt,"%-12s %-8s %-5s %s %10d %7d %10d %7d %-24.24s %s\n", - ch[i],type[stream[i].type],i<3?fmt[format[i]]:(i<5||i==8?sol[format[i]]:"-"), - stream[i].state<0?"E":(stream[i].state?"C":"-"), - stream[i].inb,stream[i].inr,stream[i].outb,stream[i].outr, - stream[i].path,stream[i].msg); - } +static void prstream(vt_t *vt) { + const char *ch[] = {"input rover", "input base", "input corr", "output sol1", "output sol2", + "log rover", "log base", "log corr", "monitor"}; + const char *type[] = {"-", "serial", "file", "tcpsvr", "tcpcli", "ntrips", "ntripc", + "ftp", "http", "ntripcas", "udpsvr", "udpcli", "membuf"}; + const char *fmt[] = {"rtcm2", "rtcm3", "oem4", "", "ubx", "swift", + "hemis", "skytreq", "javad", "nvs", "binex", "rt17", + "sbf", "", "unicore", "sp3", ""}; + const char *sol[] = {"llh", "xyz", "enu", "nmea", "stat", "-"}; + stream_t stream[9]; + int i, format[9] = {0}; + + trace(4, "prstream:\n"); + + rtksvrlock(&svr); + for (i = 0; i < 8; i++) stream[i] = svr.stream[i]; + for (i = 0; i < 3; i++) format[i] = svr.format[i]; + for (i = 3; i < 5; i++) format[i] = svr.solopt[i - 3].posf; + stream[8] = moni; + format[8] = SOLF_LLH; + rtksvrunlock(&svr); + + vt_printf(vt, "\n%s%-12s %-8s %-5s %s %10s %7s %10s %7s %-24s %s%s\n", ESC_BOLD, "Stream", "Type", + "Fmt", "S", "In-byte", "In-bps", "Out-byte", "Out-bps", "Path", "Message", ESC_RESET); + for (i = 0; i < 9; i++) { + vt_printf(vt, "%-12s %-8s %-5s %s %10d %7d %10d %7d %-24.24s %s\n", ch[i], type[stream[i].type], + i < 3 ? fmt[format[i]] : (i < 5 || i == 8 ? sol[format[i]] : "-"), + stream[i].state < 0 ? "E" : (stream[i].state ? "C" : "-"), stream[i].inb, + stream[i].inr, stream[i].outb, stream[i].outr, stream[i].path, stream[i].msg); + } } /* print ssr correction ------------------------------------------------------*/ -static void prssr(vt_t *vt) -{ - static char buff[128*MAXSAT]; - gtime_t time; - ssr_t ssr[MAXSAT]; - int i,valid; - char tstr[40],id[8],*p=buff; - - rtksvrlock(&svr); - time=svr.rtk.sol.time; - for (i=0;i1) cycle=(int)(atof(args[1])*1000.0); - - if (cycle>0) svr.nsol=0; - - while (!vt_chkbrk(vt)) { - rtksvrlock(&svr); - for (i=0;i0) sleepms(cycle); else return; - } +static void cmd_solution(char **args, int narg, vt_t *vt) { + int i, cycle = 0; + + trace(3, "cmd_solution:\n"); + + if (narg > 1) cycle = (int)(atof(args[1]) * 1000.0); + + if (cycle > 0) svr.nsol = 0; + + while (!vt_chkbrk(vt)) { + rtksvrlock(&svr); + for (i = 0; i < svr.nsol; i++) prsolution(vt, &svr.solbuf[i], svr.rtk.rb); + svr.nsol = 0; + rtksvrunlock(&svr); + if (cycle > 0) + sleepms(cycle); + else + return; + } } /* status command ------------------------------------------------------------*/ -static void cmd_status(char **args, int narg, vt_t *vt) -{ - int cycle=0; - - trace(3,"cmd_status:\n"); - - if (narg>1) cycle=(int)(atof(args[1])*1000.0); - - while (!vt_chkbrk(vt)) { - if (cycle>0) vt_printf(vt,ESC_CLEAR); - prstatus(vt); - if (cycle>0) sleepms(cycle); else return; - } - vt_printf(vt,"\n"); +static void cmd_status(char **args, int narg, vt_t *vt) { + int cycle = 0; + + trace(3, "cmd_status:\n"); + + if (narg > 1) cycle = (int)(atof(args[1]) * 1000.0); + + while (!vt_chkbrk(vt)) { + if (cycle > 0) vt_printf(vt, ESC_CLEAR); + prstatus(vt); + if (cycle > 0) + sleepms(cycle); + else + return; + } + vt_printf(vt, "\n"); } /* satellite command ---------------------------------------------------------*/ -static void cmd_satellite(char **args, int narg, vt_t *vt) -{ - int i,nf=2,cycle=0; - - trace(3,"cmd_satellite:\n"); - - for (i=1;i0) vt_printf(vt,ESC_CLEAR); - prsatellite(vt,nf); - if (cycle>0) sleepms(cycle); else return; - } - vt_printf(vt,"\n"); +static void cmd_satellite(char **args, int narg, vt_t *vt) { + int i, nf = 2, cycle = 0; + + trace(3, "cmd_satellite:\n"); + + for (i = 1; i < narg; i++) { + if (sscanf(args[i], "-%d", &nf) < 1) cycle = (int)(atof(args[i]) * 1000.0); + } + while (!vt_chkbrk(vt)) { + if (cycle > 0) vt_printf(vt, ESC_CLEAR); + prsatellite(vt, nf); + if (cycle > 0) + sleepms(cycle); + else + return; + } + vt_printf(vt, "\n"); } /* observ command ------------------------------------------------------------*/ -static void cmd_observ(char **args, int narg, vt_t *vt) -{ - int i,nf=2,cycle=0; - - trace(3,"cmd_observ:\n"); - - for (i=1;i0) vt_printf(vt,ESC_CLEAR); - probserv(vt,nf); - if (cycle>0) sleepms(cycle); else return; - } - vt_printf(vt,"\n"); +static void cmd_observ(char **args, int narg, vt_t *vt) { + int i, nf = 2, cycle = 0; + + trace(3, "cmd_observ:\n"); + + for (i = 1; i < narg; i++) { + if (sscanf(args[i], "-%d", &nf) < 1) cycle = (int)(atof(args[i]) * 1000.0); + } + while (!vt_chkbrk(vt)) { + if (cycle > 0) vt_printf(vt, ESC_CLEAR); + probserv(vt, nf); + if (cycle > 0) + sleepms(cycle); + else + return; + } + vt_printf(vt, "\n"); } /* navidata command ----------------------------------------------------------*/ -static void cmd_navidata(char **args, int narg, vt_t *vt) -{ - int cycle=0; - - trace(3,"cmd_navidata:\n"); - - if (narg>1) cycle=(int)(atof(args[1])*1000.0); - - while (!vt_chkbrk(vt)) { - if (cycle>0) vt_printf(vt,ESC_CLEAR); - prnavidata(vt); - if (cycle>0) sleepms(cycle); else return; - } - vt_printf(vt,"\n"); +static void cmd_navidata(char **args, int narg, vt_t *vt) { + int cycle = 0; + + trace(3, "cmd_navidata:\n"); + + if (narg > 1) cycle = (int)(atof(args[1]) * 1000.0); + + while (!vt_chkbrk(vt)) { + if (cycle > 0) vt_printf(vt, ESC_CLEAR); + prnavidata(vt); + if (cycle > 0) + sleepms(cycle); + else + return; + } + vt_printf(vt, "\n"); } /* error command -------------------------------------------------------------*/ -static void cmd_error(char **args, int narg, vt_t *vt) -{ - trace(3,"cmd_error:\n"); - - rtksvrlock(&svr); - svr.rtk.neb=0; - rtksvrunlock(&svr); - - while (!vt_chkbrk(vt)) { - prerror(vt); - sleepms(100); - } - vt_printf(vt,"\n"); +static void cmd_error(char **args, int narg, vt_t *vt) { + trace(3, "cmd_error:\n"); + + rtksvrlock(&svr); + svr.rtk.neb = 0; + rtksvrunlock(&svr); + + while (!vt_chkbrk(vt)) { + prerror(vt); + sleepms(100); + } + vt_printf(vt, "\n"); } /* stream command ------------------------------------------------------------*/ -static void cmd_stream(char **args, int narg, vt_t *vt) -{ - int cycle=0; - - trace(3,"cmd_stream:\n"); - - if (narg>1) cycle=(int)(atof(args[1])*1000.0); - - while (!vt_chkbrk(vt)) { - if (cycle>0) vt_printf(vt,ESC_CLEAR); - prstream(vt); - if (cycle>0) sleepms(cycle); else return; - } - vt_printf(vt,"\n"); +static void cmd_stream(char **args, int narg, vt_t *vt) { + int cycle = 0; + + trace(3, "cmd_stream:\n"); + + if (narg > 1) cycle = (int)(atof(args[1]) * 1000.0); + + while (!vt_chkbrk(vt)) { + if (cycle > 0) vt_printf(vt, ESC_CLEAR); + prstream(vt); + if (cycle > 0) + sleepms(cycle); + else + return; + } + vt_printf(vt, "\n"); } /* ssr command ---------------------------------------------------------------*/ -static void cmd_ssr(char **args, int narg, vt_t *vt) -{ - int cycle=0; - - trace(3,"cmd_ssr:\n"); - - if (narg>1) cycle=(int)(atof(args[1])*1000.0); - - while (!vt_chkbrk(vt)) { - if (cycle>0) vt_printf(vt,ESC_CLEAR); - prssr(vt); - if (cycle>0) sleepms(cycle); else return; - } - vt_printf(vt,"\n"); +static void cmd_ssr(char **args, int narg, vt_t *vt) { + int cycle = 0; + + trace(3, "cmd_ssr:\n"); + + if (narg > 1) cycle = (int)(atof(args[1]) * 1000.0); + + while (!vt_chkbrk(vt)) { + if (cycle > 0) vt_printf(vt, ESC_CLEAR); + prssr(vt); + if (cycle > 0) + sleepms(cycle); + else + return; + } + vt_printf(vt, "\n"); } /* option command ------------------------------------------------------------*/ -static void cmd_option(char **args, int narg, vt_t *vt) -{ - char buff[MAXSTR],*p; - int i,n; - - trace(3,"cmd_option:\n"); - - for (i=0;*rcvopts[i].name;i++) { - if (narg>=2&&!strstr(rcvopts[i].name,args[1])) continue; - p=buff; - p+=sprintf(p,"%-18s =",rcvopts[i].name); - p+=opt2str(rcvopts+i,p); - if (*rcvopts[i].comment) { - if ((n=(int)(buff+30-p))>0) p+=sprintf(p,"%*s",n,""); - p+=sprintf(p," # (%s)",rcvopts[i].comment); - } - vt_printf(vt,"%s%s\n",modflgr[i]?"*":" ",buff); - } - for (i=0;*sysopts[i].name;i++) { - if (narg>=2&&!strstr(sysopts[i].name,args[1])) continue; - p=buff; - p+=sprintf(p,"%-18s =",sysopts[i].name); - p+=opt2str(sysopts+i,p); - if (*sysopts[i].comment) { - if ((n=(int)(buff+30-p))>0) p+=sprintf(p,"%*s",n,""); - p+=sprintf(p," # (%s)",sysopts[i].comment); - } - vt_printf(vt,"%s%s\n",modflgs[i]?"*":" ",buff); - } +static void cmd_option(char **args, int narg, vt_t *vt) { + char buff[MAXSTR], *p; + int i, n; + + trace(3, "cmd_option:\n"); + + for (i = 0; *rcvopts[i].name; i++) { + if (narg >= 2 && !strstr(rcvopts[i].name, args[1])) continue; + p = buff; + p += sprintf(p, "%-18s =", rcvopts[i].name); + p += opt2str(rcvopts + i, p); + if (*rcvopts[i].comment) { + if ((n = (int)(buff + 30 - p)) > 0) p += sprintf(p, "%*s", n, ""); + p += sprintf(p, " # (%s)", rcvopts[i].comment); + } + vt_printf(vt, "%s%s\n", modflgr[i] ? "*" : " ", buff); + } + for (i = 0; *sysopts[i].name; i++) { + if (narg >= 2 && !strstr(sysopts[i].name, args[1])) continue; + p = buff; + p += sprintf(p, "%-18s =", sysopts[i].name); + p += opt2str(sysopts + i, p); + if (*sysopts[i].comment) { + if ((n = (int)(buff + 30 - p)) > 0) p += sprintf(p, "%*s", n, ""); + p += sprintf(p, " # (%s)", sysopts[i].comment); + } + vt_printf(vt, "%s%s\n", modflgs[i] ? "*" : " ", buff); + } } /* set command ---------------------------------------------------------------*/ -static void cmd_set(char **args, int narg, vt_t *vt) -{ - opt_t *opt; - int *modf; - char buff[MAXSTR]; - - trace(3,"cmd_set:\n"); - - if (narg<2) { - vt_printf(vt,"specify option type\n"); - return; - } - if ((opt=searchopt(args[1],rcvopts))) { - modf=modflgr+(int)(opt-rcvopts); - } - else if ((opt=searchopt(args[1],sysopts))) { - modf=modflgs+(int)(opt-sysopts); - } - else { - vt_printf(vt,"no option type: %s\n",args[1]); - return; - } - if (narg<3) { - vt_printf(vt,"%s",opt->name); - if (*opt->comment) vt_printf(vt," (%s)",opt->comment); - vt_printf(vt,": "); - if (!vt_gets(vt,buff,sizeof(buff))||vt->brk) return; - } - else strcpy(buff,args[2]); - - chop(buff); - if (!str2opt(opt,buff)) { - vt_printf(vt,"invalid option value: %s %s\n",opt->name,buff); - return; - } - getsysopts(&prcopt,solopt,&filopt); - solopt[1]=solopt[0]; - - vt_printf(vt,"option %s changed.",opt->name); - if (strncmp(opt->name,"console",7)) { - *modf=1; - vt_printf(vt," restart to enable it"); - } - vt_printf(vt,"\n"); +static void cmd_set(char **args, int narg, vt_t *vt) { + opt_t *opt; + int *modf; + char buff[MAXSTR]; + + trace(3, "cmd_set:\n"); + + if (narg < 2) { + vt_printf(vt, "specify option type\n"); + return; + } + if ((opt = searchopt(args[1], rcvopts))) { + modf = modflgr + (int)(opt - rcvopts); + } else if ((opt = searchopt(args[1], sysopts))) { + modf = modflgs + (int)(opt - sysopts); + } else { + vt_printf(vt, "no option type: %s\n", args[1]); + return; + } + if (narg < 3) { + vt_printf(vt, "%s", opt->name); + if (*opt->comment) vt_printf(vt, " (%s)", opt->comment); + vt_printf(vt, ": "); + if (!vt_gets(vt, buff, sizeof(buff)) || vt->brk) return; + } else + strcpy(buff, args[2]); + + chop(buff); + if (!str2opt(opt, buff)) { + vt_printf(vt, "invalid option value: %s %s\n", opt->name, buff); + return; + } + getsysopts(&prcopt, solopt, &filopt); + solopt[1] = solopt[0]; + + vt_printf(vt, "option %s changed.", opt->name); + if (strncmp(opt->name, "console", 7)) { + *modf = 1; + vt_printf(vt, " restart to enable it"); + } + vt_printf(vt, "\n"); } /* Mark command ------------------------------------------------------------*/ -static void cmd_mark(char **args, int narg, vt_t *vt) -{ - trace(3,"cmd_mark:\n"); +static void cmd_mark(char **args, int narg, vt_t *vt) { + trace(3, "cmd_mark:\n"); // Remember the marker name so that it can be repeated, and default // to replacement by a counter. @@ -1303,10 +1302,8 @@ static void cmd_mark(char **args, int narg, vt_t *vt) static char markername[128] = "%r"; char markercomment[256] = {0}; - if (narg > 1) - snprintf(markername, sizeof(markername), "%s", args[1]); - if (narg > 2) - snprintf(markercomment, sizeof(markercomment), "%s", args[2]); + if (narg > 1) snprintf(markername, sizeof(markername), "%s", args[1]); + if (narg > 2) snprintf(markercomment, sizeof(markercomment), "%s", args[2]); char nmarker_str[32]; snprintf(nmarker_str, sizeof(nmarker_str), "%03d", nmarker); @@ -1319,7 +1316,7 @@ static void cmd_mark(char **args, int narg, vt_t *vt) } /* Mode command --------------------------------------------------------------*/ static void cmd_mode(char **args, int narg, vt_t *vt) { - const char *mode[] = {"single", "DGPS", "kinematic", "static", "static-start", + const char *mode[] = {"single", "DGPS", "kinematic", "static", "static-start", "moving-base", "fixed", "PPP-kinematic", "PPP-static", "PPP-fixed"}; trace(3, "cmd_mode:\n"); @@ -1337,19 +1334,22 @@ static void cmd_mode(char **args, int narg, vt_t *vt) { if (args[1][0] == 'G' || args[1][0] == 'g') { // Go - if (pmode == PMODE_KINEMA || pmode == PMODE_STATIC || pmode == PMODE_STATIC_START || pmode == PMODE_FIXED) + if (pmode == PMODE_KINEMA || pmode == PMODE_STATIC || pmode == PMODE_STATIC_START || + pmode == PMODE_FIXED) pmode = PMODE_KINEMA; else if (pmode == PMODE_PPP_KINEMA || pmode == PMODE_PPP_STATIC || pmode == PMODE_PPP_FIXED) pmode = PMODE_PPP_KINEMA; } else if (args[1][0] == 'S' || args[1][0] == 's') { // Stop - if (pmode == PMODE_KINEMA || pmode == PMODE_STATIC || pmode == PMODE_STATIC_START || pmode == PMODE_FIXED) + if (pmode == PMODE_KINEMA || pmode == PMODE_STATIC || pmode == PMODE_STATIC_START || + pmode == PMODE_FIXED) pmode = PMODE_STATIC; else if (pmode == PMODE_PPP_KINEMA || pmode == PMODE_PPP_STATIC || pmode == PMODE_PPP_FIXED) pmode = PMODE_PPP_KINEMA; } else if (args[1][0] == 'F' || args[1][0] == 'f') { // Fixed - if (pmode == PMODE_KINEMA || pmode == PMODE_STATIC || pmode == PMODE_STATIC_START || pmode == PMODE_FIXED) + if (pmode == PMODE_KINEMA || pmode == PMODE_STATIC || pmode == PMODE_STATIC_START || + pmode == PMODE_FIXED) pmode = PMODE_FIXED; else if (pmode == PMODE_PPP_KINEMA || pmode == PMODE_PPP_STATIC || pmode == PMODE_PPP_FIXED) pmode = PMODE_PPP_FIXED; @@ -1370,536 +1370,568 @@ static void cmd_mode(char **args, int narg, vt_t *vt) { vt_printf(vt, "%-28s: %s\n", "positioning mode", mode[pmode]); } /* load command --------------------------------------------------------------*/ -static void cmd_load(char **args, int narg, vt_t *vt) -{ - char file[MAXSTR]=""; - - trace(3,"cmd_load:\n"); - - if (narg>=2) { - strcpy(file,args[1]); - } - else { - sprintf(file,"%s/%s",OPTSDIR,OPTSFILE); - } - resetsysopts(); - if (!loadopts(file,sysopts)) { - vt_printf(vt,"no options file: %s\n",file); - return; - } - getsysopts(&prcopt,solopt,&filopt); - solopt[1]=solopt[0]; - - if (!loadopts(file,rcvopts)) { - vt_printf(vt,"no options file: %s\n",file); - return; - } - vt_printf(vt,"options loaded from %s. restart to enable them\n",file); +static void cmd_load(char **args, int narg, vt_t *vt) { + char file[MAXSTR] = ""; + + trace(3, "cmd_load:\n"); + + if (narg >= 2) { + strcpy(file, args[1]); + } else { + sprintf(file, "%s/%s", OPTSDIR, OPTSFILE); + } + resetsysopts(); + if (!loadopts(file, sysopts)) { + vt_printf(vt, "no options file: %s\n", file); + return; + } + getsysopts(&prcopt, solopt, &filopt); + solopt[1] = solopt[0]; + + if (!loadopts(file, rcvopts)) { + vt_printf(vt, "no options file: %s\n", file); + return; + } + vt_printf(vt, "options loaded from %s. restart to enable them\n", file); } /* save command --------------------------------------------------------------*/ -static void cmd_save(char **args, int narg, vt_t *vt) -{ - char file[MAXSTR]="",comment[256],s[40]; - - trace(3,"cmd_save:\n"); - - if (narg>=2) { - strcpy(file,args[1]); - } - else { - sprintf(file,"%s/%s",OPTSDIR,OPTSFILE); - } - if (!confwrite(vt,file)) return; - time2str(utc2gpst(timeget()),s,0); - sprintf(comment,"%s options (%s, v.%s %s)",PRGNAME,s,VER_RTKLIB,PATCH_LEVEL); - setsysopts(&prcopt,solopt,&filopt); - if (!saveopts(file,"w",comment,rcvopts)||!saveopts(file,"a",NULL,sysopts)) { - vt_printf(vt,"options save error: %s\n",file); - return; - } - vt_printf(vt,"options saved to %s\n",file); +static void cmd_save(char **args, int narg, vt_t *vt) { + char file[MAXSTR] = "", comment[256], s[40]; + + trace(3, "cmd_save:\n"); + + if (narg >= 2) { + strcpy(file, args[1]); + } else { + sprintf(file, "%s/%s", OPTSDIR, OPTSFILE); + } + if (!confwrite(vt, file)) return; + time2str(utc2gpst(timeget()), s, 0); + sprintf(comment, "%s options (%s, v.%s %s)", PRGNAME, s, VER_RTKLIB, PATCH_LEVEL); + setsysopts(&prcopt, solopt, &filopt); + if (!saveopts(file, "w", comment, rcvopts) || !saveopts(file, "a", NULL, sysopts)) { + vt_printf(vt, "options save error: %s\n", file); + return; + } + vt_printf(vt, "options saved to %s\n", file); } /* log command ---------------------------------------------------------------*/ -static void cmd_log(char **args, int narg, vt_t *vt) -{ - trace(3,"cmd_log:\n"); - - if (narg<2) { - vt_printf(vt,"specify log file\n"); - return; - } - if (!strcmp(args[1],"off")) { - vt_closelog(vt); - vt_printf(vt,"log off\n"); - return; - } - if (!confwrite(vt,args[1])) return; - - if (!vt_openlog(vt,args[1])) { - vt_printf(vt,"log open error: %s\n",args[1]); - return; - } - vt_printf(vt,"log on: %s\n",args[1]); +static void cmd_log(char **args, int narg, vt_t *vt) { + trace(3, "cmd_log:\n"); + + if (narg < 2) { + vt_printf(vt, "specify log file\n"); + return; + } + if (!strcmp(args[1], "off")) { + vt_closelog(vt); + vt_printf(vt, "log off\n"); + return; + } + if (!confwrite(vt, args[1])) return; + + if (!vt_openlog(vt, args[1])) { + vt_printf(vt, "log open error: %s\n", args[1]); + return; + } + vt_printf(vt, "log on: %s\n", args[1]); } /* help command --------------------------------------------------------------*/ -static void cmd_help(char **args, int narg, vt_t *vt) -{ - char str[]="path"; - int i; - - if (narg<2) { - vt_printf(vt,"%s (ver.%s %s)\n",PRGNAME,VER_RTKLIB,PATCH_LEVEL); - for (i=0;*helptxt[i];i++) vt_printf(vt,"%s\n",helptxt[i]); - } - else if (strstr(str,args[1])==str) { - for (i=0;*pathopts[i];i++) vt_printf(vt,"%s\n",pathopts[i]); - } - else { - vt_printf(vt,"unknown help: %s\n",args[1]); - } +static void cmd_help(char **args, int narg, vt_t *vt) { + char str[] = "path"; + int i; + + if (narg < 2) { + vt_printf(vt, "%s (ver.%s %s)\n", PRGNAME, VER_RTKLIB, PATCH_LEVEL); + for (i = 0; *helptxt[i]; i++) vt_printf(vt, "%s\n", helptxt[i]); + } else if (strstr(str, args[1]) == str) { + for (i = 0; *pathopts[i]; i++) vt_printf(vt, "%s\n", pathopts[i]); + } else { + vt_printf(vt, "unknown help: %s\n", args[1]); + } } /* console thread ------------------------------------------------------------*/ -static void *con_thread(void *arg) -{ - const char *cmds[]={ - "start","stop","restart","solution","status","satellite","observ", - "navidata","stream","ssr","error","option","set", - "mark","mode","load","save","log","help","?","exit","shutdown","" - }; - con_t *con=(con_t *)arg; - int i,j,narg; - char buff[MAXCMD],*args[MAXARG],*p; - - trace(3,"console_thread:\n"); - - vt_printf(con->vt,"\n%s** %s ver.%s %s console (h:help) **%s\n",ESC_BOLD, - PRGNAME,VER_RTKLIB,PATCH_LEVEL,ESC_RESET); - - if (!login(con->vt)) { - vt_close(con->vt); - con->state=0; - return NULL; +static void *con_thread(void *arg) { + const char *cmds[] = {"start", "stop", "restart", "solution", "status", "satellite", + "observ", "navidata", "stream", "ssr", "error", "option", + "set", "mark", "mode", "load", "save", "log", + "help", "?", "exit", "shutdown", ""}; + con_t *con = (con_t *)arg; + int i, j, narg; + char buff[MAXCMD], *args[MAXARG], *p; + + trace(3, "console_thread:\n"); + + vt_printf(con->vt, "\n%s** %s ver.%s %s console (h:help) **%s\n", ESC_BOLD, PRGNAME, VER_RTKLIB, + PATCH_LEVEL, ESC_RESET); + + if (!login(con->vt)) { + vt_close(con->vt); + con->state = 0; + return NULL; + } + + /* auto start if option set */ + if (start & 1) { /* start with console */ + cmd_start(NULL, 0, con->vt); + start = 0; + } + + while (con->state) { + /* output prompt */ + if (!vt_puts(con->vt, CMDPROMPT)) { + con->state = 0; + break; } - - /* auto start if option set */ - if (start&1) { /* start with console */ - cmd_start(NULL,0,con->vt); - start=0; + + /* input command */ + if (!vt_gets(con->vt, buff, sizeof(buff))) break; + + /* parse command */ + narg = 0; + char *r; + for (p = strtok_r(buff, " \t\n", &r); p && narg < MAXARG; p = strtok_r(NULL, " \t\n", &r)) { + args[narg++] = p; } - - while (con->state) { - - /* output prompt */ - if (!vt_puts(con->vt,CMDPROMPT)) { - con->state = 0; - break; - } - - /* input command */ - if (!vt_gets(con->vt,buff,sizeof(buff))) break; - - /* parse command */ - narg=0; - char *r; - for (p=strtok_r(buff," \t\n",&r);p&&nargvt); break; - case 1: cmd_stop (args,narg,con->vt); break; - case 2: cmd_restart (args,narg,con->vt); break; - case 3: cmd_solution (args,narg,con->vt); break; - case 4: cmd_status (args,narg,con->vt); break; - case 5: cmd_satellite(args,narg,con->vt); break; - case 6: cmd_observ (args,narg,con->vt); break; - case 7: cmd_navidata (args,narg,con->vt); break; - case 8: cmd_stream (args,narg,con->vt); break; - case 9: cmd_ssr (args,narg,con->vt); break; - case 10: cmd_error (args,narg,con->vt); break; - case 11: cmd_option (args,narg,con->vt); break; - case 12: cmd_set (args,narg,con->vt); break; - case 13: cmd_mark (args,narg,con->vt); break; - case 14: cmd_mode (args,narg,con->vt); break; - case 15: cmd_load (args,narg,con->vt); break; - case 16: cmd_save (args,narg,con->vt); break; - case 17: cmd_log (args,narg,con->vt); break; - case 18: cmd_help (args,narg,con->vt); break; - case 19: cmd_help (args,narg,con->vt); break; - case 20: /* exit */ - if (con->vt->type) con->state=0; - break; - case 21: /* shutdown */ - if (!strcmp(args[0],"shutdown")) { - vt_printf(con->vt,"rtk server shutdown ...\n"); - sleepms(1000); - intflg=1; - con->state=0; - } - break; - default: - vt_printf(con->vt,"unknown command: %s.\n",args[0]); - break; + if (narg == 0) continue; + + for (i = 0, j = -1; *cmds[i]; i++) { + if (strstr(cmds[i], args[0]) == cmds[i]) j = i; + } + switch (j) { + case 0: + cmd_start(args, narg, con->vt); + break; + case 1: + cmd_stop(args, narg, con->vt); + break; + case 2: + cmd_restart(args, narg, con->vt); + break; + case 3: + cmd_solution(args, narg, con->vt); + break; + case 4: + cmd_status(args, narg, con->vt); + break; + case 5: + cmd_satellite(args, narg, con->vt); + break; + case 6: + cmd_observ(args, narg, con->vt); + break; + case 7: + cmd_navidata(args, narg, con->vt); + break; + case 8: + cmd_stream(args, narg, con->vt); + break; + case 9: + cmd_ssr(args, narg, con->vt); + break; + case 10: + cmd_error(args, narg, con->vt); + break; + case 11: + cmd_option(args, narg, con->vt); + break; + case 12: + cmd_set(args, narg, con->vt); + break; + case 13: + cmd_mark(args, narg, con->vt); + break; + case 14: + cmd_mode(args, narg, con->vt); + break; + case 15: + cmd_load(args, narg, con->vt); + break; + case 16: + cmd_save(args, narg, con->vt); + break; + case 17: + cmd_log(args, narg, con->vt); + break; + case 18: + cmd_help(args, narg, con->vt); + break; + case 19: + cmd_help(args, narg, con->vt); + break; + case 20: /* exit */ + if (con->vt->type) con->state = 0; + break; + case 21: /* shutdown */ + if (!strcmp(args[0], "shutdown")) { + vt_printf(con->vt, "rtk server shutdown ...\n"); + sleepms(1000); + intflg = 1; + con->state = 0; } + break; + default: + vt_printf(con->vt, "unknown command: %s.\n", args[0]); + break; } - vt_close(con->vt); - con->vt = NULL; - return NULL; + } + vt_close(con->vt); + con->vt = NULL; + return NULL; } /* open console --------------------------------------------------------------*/ -static con_t *con_open(int sock, const char *dev) -{ - con_t *con; - - trace(3,"con_open: sock=%d dev=%s\n",sock,dev); - - if (!(con=(con_t *)malloc(sizeof(con_t)))) return NULL; - - if (!(con->vt=vt_open(sock,dev))) { - free(con); - return NULL; - } - /* start console thread */ - con->state=1; - if (pthread_create(&con->thread,NULL,con_thread,con)) { - free(con); - return NULL; - } - return con; +static con_t *con_open(int sock, const char *dev) { + con_t *con; + + trace(3, "con_open: sock=%d dev=%s\n", sock, dev); + + if (!(con = (con_t *)malloc(sizeof(con_t)))) return NULL; + + if (!(con->vt = vt_open(sock, dev))) { + free(con); + return NULL; + } + /* start console thread */ + con->state = 1; + if (pthread_create(&con->thread, NULL, con_thread, con)) { + free(con); + return NULL; + } + return con; } /* close console -------------------------------------------------------------*/ -static void con_close(con_t *con) -{ - trace(3,"con_close:\n"); - - if (!con) return; - con->state=0; - pthread_join(con->thread,NULL); - free(con); +static void con_close(con_t *con) { + trace(3, "con_close:\n"); + + if (!con) return; + con->state = 0; + pthread_join(con->thread, NULL); + free(con); } /* open socket for remote console --------------------------------------------*/ -static int open_sock(int port) -{ - struct sockaddr_in addr; - int sock,on=1; - - trace(3,"open_sock: port=%d\n",port); - - if ((sock=socket(AF_INET,SOCK_STREAM,0))<0) { - fprintf(stderr,"socket error (%d)\n",errno); - return 0; - } - setsockopt(sock,SOL_SOCKET,SO_REUSEADDR,(const char *)&on,sizeof(on)); - memset(&addr,0,sizeof(addr)); - addr.sin_family=AF_INET; - addr.sin_port=htons(port); - - if (bind(sock,(struct sockaddr *)&addr,sizeof(addr))<0) { - fprintf(stderr,"bind error (%d)\n",errno); - close(sock); - return -1; - } - listen(sock,5); - return sock; +static int open_sock(int port) { + struct sockaddr_in addr; + int sock, on = 1; + + trace(3, "open_sock: port=%d\n", port); + + if ((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0) { + fprintf(stderr, "socket error (%d)\n", errno); + return 0; + } + setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (const char *)&on, sizeof(on)); + memset(&addr, 0, sizeof(addr)); + addr.sin_family = AF_INET; + addr.sin_port = htons(port); + + if (bind(sock, (struct sockaddr *)&addr, sizeof(addr)) < 0) { + fprintf(stderr, "bind error (%d)\n", errno); + close(sock); + return -1; + } + listen(sock, 5); + return sock; } /* accept remote console connection ------------------------------------------*/ -static void accept_sock(int ssock, con_t **con) -{ - struct timeval tv={0}; - struct sockaddr_in addr; - socklen_t len=sizeof(addr); - fd_set rs; - int i,sock; - - if (ssock<=0) return; - - trace(4,"accept_sock: ssock=%d\n",ssock); - - for (i=1;istate) continue; - con_close(con[i]); - con[i]=NULL; - } - FD_ZERO(&rs); - FD_SET(ssock,&rs); - if (select(ssock+1,&rs,NULL,NULL,&tv)<=0) { - return; - } - if ((sock=accept(ssock,(struct sockaddr *)&addr,&len))<=0) { - return; - } - for (i=1;istate) continue; + con_close(con[i]); + con[i] = NULL; + } + FD_ZERO(&rs); + FD_SET(ssock, &rs); + if (select(ssock + 1, &rs, NULL, NULL, &tv) <= 0) { + return; + } + if ((sock = accept(ssock, (struct sockaddr *)&addr, &len)) <= 0) { + return; + } + for (i = 1; i < MAXCON; i++) { + if (con[i]) continue; + + con[i] = con_open(sock, ""); + + trace(3, "remote console connected: addr=%s\n", inet_ntoa(addr.sin_addr)); + return; + } + close(sock); + trace(2, "remote console connection refused. addr=%s\n", inet_ntoa(addr.sin_addr)); } -static void deamonise(void) -{ +static void deamonise(void) { #ifndef WIN32 - /* In case we were not started in the background, fork and let the parent - * exit. Guarantees that the child is not a process group leader. */ - int childpid = fork(); - if (childpid < 0) { - perror("fork\n"); - _exit(1); - } else if (childpid > 0) { - /* parent */ - _exit(0); - } + /* In case we were not started in the background, fork and let the parent + * exit. Guarantees that the child is not a process group leader. */ + int childpid = fork(); + if (childpid < 0) { + perror("fork\n"); + _exit(1); + } else if (childpid > 0) { + /* parent */ + _exit(0); + } - /* Make ourselves the leader of a new process group with no controlling - * terminal. */ - if (setsid() < 0) { - perror("setsid\n"); - _exit(1); - } + /* Make ourselves the leader of a new process group with no controlling + * terminal. */ + if (setsid() < 0) { + perror("setsid\n"); + _exit(1); + } - for (int fd = 0; fd < 10; fd++) close(fd); + for (int fd = 0; fd < 10; fd++) close(fd); - open("/dev/null", O_RDWR); - gtime_t time = utc2gpst(timeget()); - char path[1024]; - reppath(LOGFILE, path, time, "", ""); - open(path, O_WRONLY|O_CREAT|O_TRUNC, 0666); - dup(1); + open("/dev/null", O_RDWR); + gtime_t time = utc2gpst(timeget()); + char path[1024]; + reppath(LOGFILE, path, time, "", ""); + open(path, O_WRONLY | O_CREAT | O_TRUNC, 0666); + dup(1); #endif } /* rtkrcv main ----------------------------------------------------------------- -* synopsis -* rtkrcv [-s][-nc][-p port][-d dev][-o file][-r level][-t level][-sta sta] -* -* description -* A command line version of the real-time positioning AP by rtklib. To start -* or stop RTK server, to configure options or to print solution/status, -* login a console and input commands. As default, /dev/tty is used for the -* console. Use -p option for network login with telnet protocol. To show -* the available commands, type ? or help on the console. With -p option, -* multiple telnet console logins are allowed. The initial processing options -* are loaded from default file rtkrcv.conf. To change the file, use -o -* option. To configure the processing options, edit the options file or use -* set, load or save command on the console. To shutdown the program, use -* shutdown command on the console or send USR2 signal to the process. -* -* The --deamon option implies no console. When used with -s or -nc the RTK -* server is started on program startup. A telnet console can be used with -* this option to start and control the RTK server. -* -* option -* -s start RTK server on program startup -* -nc start RTK server on program startup with no console -* -p port port number for telnet console -* -m port port number for monitor stream -* -d dev terminal device for console -* -o file processing options file -* -w pwd login password for remote console ("": no password) -* -r level output solution status file (0:off,1:states,2:residuals) -* -t level debug trace level (0:off,1-5:on) -* -sta sta station name for receiver dcb -* --deamon detach from the console -* --version prints the version and exits -* -* command -* start -* Start RTK server. No need the command if the program runs with -s -* option. -* -* stop -* Stop RTK server. -* -* restart -* Restart RTK server. If the processing options are set, execute the -* command to enable the changes. -* -* solution [cycle] -* Show solutions. Without option, only one solution is shown. With -* option, the solution is displayed at intervals of cycle (s). To stop -* cyclic display, send break (ctr-C). -* -* status [cycle] -* Show RTK status. Use option cycle for cyclic display. -* -* satellite [-n] [cycle] -* Show satellite status. Use option cycle for cyclic display. Option -n -* specify number of frequencies. -* -* observ [-n] [cycle] -* Show observation data. Use option cycle for cyclic display. Option -n -* specify number of frequencies. -* -* navidata [cycle] -* Show navigation data. Use option cycle for cyclic display. -* -* stream [cycle] -* Show stream status. Use option cycle for cyclic display. -* -* error -* Show error/warning messages. To stop messages, send break (ctr-C). -* -* option [opt] -* Show the values of processing options. Without option, all options are -* displayed. With option, only pattern-matched options are displayed. -* -* set opt [val] -* Set the value of a processing option to val. With out option val, -* prompt message is shown to input the value. The change of the -* processing option is not enabled before RTK server is restarted. -* -* mark [name] [comment] -* Log a marker. -* -* mode ['g'|'s'|'f'|n] -* Set the processing mode. Either 'g' or 'go' for kinematic mode, -* 's' or 'stop' for static mode or 'f' or 'fixed' for fixed mode. -* An internal mode number is also accepted but not all mode changes -* are smoothly handled. -* -* load [file] -* Load processing options from file. Without option, default file -* rtkrcv.conf is used. To enable the changes, restart RTK server. -* -* save [file] -* Save current processing options to file. Without option, default file -* rtkrcv.conf is used. -* -* log [file|off] -* Record console log to file. To stop recording the log, use option off. -* -* help|? [path] -* Show the command list. With option path, the stream path options are -* shown. -* -* exit -* Exit and logout console. The status of RTK server is not affected by -* the command. -* -* shutdown -* Shutdown RTK server and exit the program. -* -* notes -* Short form of a command is allowed. In case of the short form, the -* command is distinguished according to header characters. -* -* The -r argument only affects the status file. The status output streams -* take their level from the out-outstat option. -* -*-----------------------------------------------------------------------------*/ -int main(int argc, char **argv) -{ - con_t *con[MAXCON]={0}; - int i,port=0,outstat=0,trace=0,sock=0; - char *dev="",file[MAXSTR]=""; - int deamon=0; - - for (i=1;i0) { - traceopen(TRACEFILE); - tracelevel(trace); - } - /* initialize rtk server and monitor port */ - rtksvrinit(&svr); - strinit(&moni); - - /* load options file */ - if (!*file) sprintf(file,"%s/%s",OPTSDIR,OPTSFILE); - - resetsysopts(); - if (!loadopts(file,rcvopts)||!loadopts(file,sysopts)) { - fprintf(stderr,"no options file: %s. defaults used\n",file); - } - getsysopts(&prcopt,solopt,&filopt); - /* Copy the system options for the second output solution stream */ - solopt[1]=solopt[0]; - - /* read navigation data */ - if (!readnav(NAVIFILE,&svr.nav)) { - fprintf(stderr,"no navigation data: %s\n",NAVIFILE); - } - if (outstat>0) { - rtkopenstat(STATFILE,outstat); - } - /* open monitor port */ - if (moniport>0&&!openmoni(moniport)) { - fprintf(stderr,"monitor port open error: %d\n",moniport); - } - if (port) { - /* open socket for remote console */ - if ((sock=open_sock(port))<=0) { - fprintf(stderr,"console open error port=%d\n",port); - if (moniport>0) closemoni(); - if (outstat>0) rtkclosestat(); - traceclose(); - return EXIT_FAILURE; - } - } - if (start&2) { /* Start without console */ - startsvr(NULL); - } else if (!deamon) { - /* open device for local console */ - if (!(con[0]=con_open(0,dev))) { - fprintf(stderr,"console open error dev=%s\n",dev); - if (moniport>0) closemoni(); - if (outstat>0) rtkclosestat(); - traceclose(); - return EXIT_FAILURE; - } - } - signal(SIGINT, sigshut); /* keyboard interrupt */ - signal(SIGTERM,sigshut); /* external shutdown signal */ - signal(SIGUSR2,sigshut); - signal(SIGHUP ,SIG_IGN); - signal(SIGPIPE,SIG_IGN); - - while (!intflg) { - /* accept remote console connection */ - accept_sock(sock,con); - sleepms(100); - } - /* stop rtk server */ - stopsvr(NULL); - - /* close consoles */ - for (i=0;i 0) { + traceopen(TRACEFILE); + tracelevel(trace); + } + /* initialize rtk server and monitor port */ + rtksvrinit(&svr); + strinit(&moni); + + /* load options file */ + if (!*file) sprintf(file, "%s/%s", OPTSDIR, OPTSFILE); + + resetsysopts(); + if (!loadopts(file, rcvopts) || !loadopts(file, sysopts)) { + fprintf(stderr, "no options file: %s. defaults used\n", file); + } + getsysopts(&prcopt, solopt, &filopt); + /* Copy the system options for the second output solution stream */ + solopt[1] = solopt[0]; + + /* read navigation data */ + if (!readnav(NAVIFILE, &svr.nav)) { + fprintf(stderr, "no navigation data: %s\n", NAVIFILE); + } + if (outstat > 0) { + rtkopenstat(STATFILE, outstat); + } + /* open monitor port */ + if (moniport > 0 && !openmoni(moniport)) { + fprintf(stderr, "monitor port open error: %d\n", moniport); + } + if (port) { + /* open socket for remote console */ + if ((sock = open_sock(port)) <= 0) { + fprintf(stderr, "console open error port=%d\n", port); + if (moniport > 0) closemoni(); + if (outstat > 0) rtkclosestat(); + traceclose(); + return EXIT_FAILURE; } - if (moniport>0) closemoni(); - if (outstat>0) rtkclosestat(); - - /* save navigation data */ - if (!savenav(NAVIFILE,&svr.nav)) { - fprintf(stderr,"navigation data save error: %s\n",NAVIFILE); + } + if (start & 2) { /* Start without console */ + startsvr(NULL); + } else if (!deamon) { + /* open device for local console */ + if (!(con[0] = con_open(0, dev))) { + fprintf(stderr, "console open error dev=%s\n", dev); + if (moniport > 0) closemoni(); + if (outstat > 0) rtkclosestat(); + traceclose(); + return EXIT_FAILURE; } - traceclose(); - return 0; + } + signal(SIGINT, sigshut); /* keyboard interrupt */ + signal(SIGTERM, sigshut); /* external shutdown signal */ + signal(SIGUSR2, sigshut); + signal(SIGHUP, SIG_IGN); + signal(SIGPIPE, SIG_IGN); + + while (!intflg) { + /* accept remote console connection */ + accept_sock(sock, con); + sleepms(100); + } + /* stop rtk server */ + stopsvr(NULL); + + /* close consoles */ + for (i = 0; i < MAXCON; i++) { + con_close(con[i]); + } + if (moniport > 0) closemoni(); + if (outstat > 0) rtkclosestat(); + + /* save navigation data */ + if (!savenav(NAVIFILE, &svr.nav)) { + fprintf(stderr, "navigation data save error: %s\n", NAVIFILE); + } + traceclose(); + return 0; } diff --git a/app/consapp/rtkrcv/vt.c b/app/consapp/rtkrcv/vt.c index 5e9069330..144368aa6 100644 --- a/app/consapp/rtkrcv/vt.c +++ b/app/consapp/rtkrcv/vt.c @@ -1,415 +1,386 @@ /*------------------------------------------------------------------------------ -* vt.c : virtual console -* -* Copyright (C) 2014-2016 by T.TAKASU, All rights reserved. -* -* version : $Revision:$ $Date:$ -* history : 2015/01/11 1.0 separated from rtkrcv.c -* 2016/09/19 1.1 change api vt_open() -*-----------------------------------------------------------------------------*/ + * vt.c : virtual console + * + * Copyright (C) 2014-2016 by T.TAKASU, All rights reserved. + * + * version : $Revision:$ $Date:$ + * history : 2015/01/11 1.0 separated from rtkrcv.c + * 2016/09/19 1.1 change api vt_open() + *-----------------------------------------------------------------------------*/ #ifndef WIN32 #define _POSIX_C_SOURCE 2 #endif +#include +#include #include #include -#include -#include #ifdef WIN32 #include #else -#include +#include +#include #include -#include -#include -#include -#include +#include #include #include -#include -#include -#include +#include +#include +#include +#include #include +#include #endif #include "vt.h" -#define DEF_DEV "/dev/tty" /* default console device */ +#define DEF_DEV "/dev/tty" /* default console device */ -#define C_DEL (char)0x7F /* delete */ -#define C_ESC (char)0x1B /* escape */ -#define C_CTRC (char)0x03 /* interrupt (ctrl-c) */ -#define C_CTRD (char)0x04 /* logout (ctrl-d) */ -#define C_ECHO (char)1 /* telnet echo */ -#define C_SUPPGA (char)3 /* telnet suppress go ahead */ -#define C_BRK (char)243 /* telnet break */ -#define C_IP (char)244 /* telnet interrupt */ -#define C_EC (char)247 /* telnet erase character */ -#define C_EL (char)248 /* telnet erase line */ -#define C_WILL (char)251 /* telnet option negotiation */ -#define C_WONT (char)252 /* telnet option negotiation */ -#define C_DO (char)253 /* telnet option negotiation */ -#define C_DONT (char)254 /* telnet option negotiation */ -#define C_IAC (char)255 /* telnet interpret as command */ +#define C_DEL (char)0x7F /* delete */ +#define C_ESC (char)0x1B /* escape */ +#define C_CTRC (char)0x03 /* interrupt (ctrl-c) */ +#define C_CTRD (char)0x04 /* logout (ctrl-d) */ +#define C_ECHO (char)1 /* telnet echo */ +#define C_SUPPGA (char)3 /* telnet suppress go ahead */ +#define C_BRK (char)243 /* telnet break */ +#define C_IP (char)244 /* telnet interrupt */ +#define C_EC (char)247 /* telnet erase character */ +#define C_EL (char)248 /* telnet erase line */ +#define C_WILL (char)251 /* telnet option negotiation */ +#define C_WONT (char)252 /* telnet option negotiation */ +#define C_DO (char)253 /* telnet option negotiation */ +#define C_DONT (char)254 /* telnet option negotiation */ +#define C_IAC (char)255 /* telnet interpret as command */ /* open virtual console -------------------------------------------------------- -* open virtual console -* args : vt_t *vt I virtual console -* int sock I socket (0:use device) -* char *dev I device ("": standard tty) -* return : virtual console (NULL: error) -*-----------------------------------------------------------------------------*/ -extern vt_t *vt_open(int sock, const char *dev) -{ - const char mode[]={C_IAC,C_WILL,C_SUPPGA,C_IAC,C_WILL,C_ECHO}; - struct termios tio={0}; - vt_t *vt; - int i; - - trace(3,"vt_open: sock=%d dev=%s\n",sock,dev); - - if (!(vt=(vt_t *)malloc(sizeof(vt_t)))) { - return NULL; - } - vt->type=vt->n=vt->nesc=vt->cur=vt->cur_h=vt->brk=vt->blind=0; - vt->logfp=NULL; - for (i=0;ihist[i]=NULL; - } - if (!sock) { - if ((vt->in=vt->out=open(*dev?dev:DEF_DEV,O_RDWR))<0) { - free(vt); - return 0; - } - /* set terminal mode echo-off */ - tcgetattr(vt->in,&vt->tio); - tcsetattr(vt->in,TCSANOW,&tio); + * open virtual console + * args : vt_t *vt I virtual console + * int sock I socket (0:use device) + * char *dev I device ("": standard tty) + * return : virtual console (NULL: error) + *-----------------------------------------------------------------------------*/ +extern vt_t *vt_open(int sock, const char *dev) { + const char mode[] = {C_IAC, C_WILL, C_SUPPGA, C_IAC, C_WILL, C_ECHO}; + struct termios tio = {0}; + vt_t *vt; + int i; + + trace(3, "vt_open: sock=%d dev=%s\n", sock, dev); + + if (!(vt = (vt_t *)malloc(sizeof(vt_t)))) { + return NULL; + } + vt->type = vt->n = vt->nesc = vt->cur = vt->cur_h = vt->brk = vt->blind = 0; + vt->logfp = NULL; + for (i = 0; i < MAXHIST; i++) { + vt->hist[i] = NULL; + } + if (!sock) { + if ((vt->in = vt->out = open(*dev ? dev : DEF_DEV, O_RDWR)) < 0) { + free(vt); + return 0; } - else { - vt->type=1; - vt->in=vt->out=sock; - - /* send telnet character mode */ - if (write(sock,mode,6)!=6) { - free(vt); - return NULL; - } + /* set terminal mode echo-off */ + tcgetattr(vt->in, &vt->tio); + tcsetattr(vt->in, TCSANOW, &tio); + } else { + vt->type = 1; + vt->in = vt->out = sock; + + /* send telnet character mode */ + if (write(sock, mode, 6) != 6) { + free(vt); + return NULL; } - vt->state=1; - return vt; + } + vt->state = 1; + return vt; } /* close virtual console ------------------------------------------------------- -* close virtual console -* args : vt_t *vt I virtual console -* return : none -*-----------------------------------------------------------------------------*/ -extern void vt_close(vt_t *vt) -{ - int i; - - trace(3,"vt_close:\n"); - - /* restore terminal mode */ - if (!vt->type) { - tcsetattr(vt->in,TCSANOW,&vt->tio); - } - close(vt->in); - if (vt->logfp) fclose(vt->logfp); - for (i=0;ihist[i]); - } - vt->state=0; - free(vt); + * close virtual console + * args : vt_t *vt I virtual console + * return : none + *-----------------------------------------------------------------------------*/ +extern void vt_close(vt_t *vt) { + int i; + + trace(3, "vt_close:\n"); + + /* restore terminal mode */ + if (!vt->type) { + tcsetattr(vt->in, TCSANOW, &vt->tio); + } + close(vt->in); + if (vt->logfp) fclose(vt->logfp); + for (i = 0; i < MAXHIST; i++) { + free(vt->hist[i]); + } + vt->state = 0; + free(vt); } /* clear line buffer ---------------------------------------------------------*/ -static int clear_buff(vt_t *vt) -{ - char buff[MAXBUFF*3],*p=buff; - int i,len=strlen(vt->buff); - for (i=0;icur;i++) *p++='\b'; - for (i=0;in=vt->nesc=vt->cur=0; - return write(vt->out,buff,p-buff)==p-buff; +static int clear_buff(vt_t *vt) { + char buff[MAXBUFF * 3], *p = buff; + int i, len = strlen(vt->buff); + for (i = 0; i < vt->cur; i++) *p++ = '\b'; + for (i = 0; i < len; i++) *p++ = ' '; + for (i = 0; i < len; i++) *p++ = '\b'; + vt->n = vt->nesc = vt->cur = 0; + return write(vt->out, buff, p - buff) == p - buff; } /* refresh line buffer -------------------------------------------------------*/ -static int ref_buff(vt_t *vt) -{ - char buff[MAXBUFF*3],*p=buff; - int i; - for (i=vt->cur;in;i++) *p++=vt->buff[i]; - *p++=' '; - for (;i>=vt->cur;i--) *p++='\b'; - return write(vt->out,buff,p-buff)==p-buff; +static int ref_buff(vt_t *vt) { + char buff[MAXBUFF * 3], *p = buff; + int i; + for (i = vt->cur; i < vt->n; i++) *p++ = vt->buff[i]; + *p++ = ' '; + for (; i >= vt->cur; i--) *p++ = '\b'; + return write(vt->out, buff, p - buff) == p - buff; } /* move cursor right ---------------------------------------------------------*/ -static int right_cur(vt_t *vt) -{ - if (vt->cur>=vt->n) return 1; - if (write(vt->out,vt->buff+vt->cur,1)<1) return 0; - vt->cur++; - return 1; +static int right_cur(vt_t *vt) { + if (vt->cur >= vt->n) return 1; + if (write(vt->out, vt->buff + vt->cur, 1) < 1) return 0; + vt->cur++; + return 1; } /* move cursor left ----------------------------------------------------------*/ -static int left_cur(vt_t *vt) -{ - if (vt->cur<=0) return 1; - vt->cur--; - return write(vt->out,"\b",1)==1; +static int left_cur(vt_t *vt) { + if (vt->cur <= 0) return 1; + vt->cur--; + return write(vt->out, "\b", 1) == 1; } /* delete character before cursor --------------------------------------------*/ -static int del_cur(vt_t *vt) -{ - int i; - if (vt->cur<=0) return 1; - for (i=vt->cur;in;i++) vt->buff[i-1]=vt->buff[i]; - vt->n--; - return left_cur(vt)&&ref_buff(vt); +static int del_cur(vt_t *vt) { + int i; + if (vt->cur <= 0) return 1; + for (i = vt->cur; i < vt->n; i++) vt->buff[i - 1] = vt->buff[i]; + vt->n--; + return left_cur(vt) && ref_buff(vt); } /* insert character after cursor ---------------------------------------------*/ -static int ins_cur(vt_t *vt, char c) -{ - int i; - if (vt->n>=MAXBUFF) return 1; - for (i=vt->n++;i>vt->cur;i--) vt->buff[i]=vt->buff[i-1]; - vt->buff[vt->cur++]=c; - if (write(vt->out,vt->blind?"*":&c,1)<1) return 0; - return ref_buff(vt); +static int ins_cur(vt_t *vt, char c) { + int i; + if (vt->n >= MAXBUFF) return 1; + for (i = vt->n++; i > vt->cur; i--) vt->buff[i] = vt->buff[i - 1]; + vt->buff[vt->cur++] = c; + if (write(vt->out, vt->blind ? "*" : &c, 1) < 1) return 0; + return ref_buff(vt); } /* add history ---------------------------------------------------------------*/ -static int hist_add(vt_t *vt, const char *buff) -{ - int len=vt->n; - if (len<=0) return 1; - free(vt->hist[MAXHIST-1]); - for (int i=MAXHIST-1;i>0;i--) vt->hist[i]=vt->hist[i-1]; - if (!(vt->hist[0]=(char *)malloc(len+1))) return 0; - strcpy(vt->hist[0],buff); - return 1; +static int hist_add(vt_t *vt, const char *buff) { + int len = vt->n; + if (len <= 0) return 1; + free(vt->hist[MAXHIST - 1]); + for (int i = MAXHIST - 1; i > 0; i--) vt->hist[i] = vt->hist[i - 1]; + if (!(vt->hist[0] = (char *)malloc(len + 1))) return 0; + strcpy(vt->hist[0], buff); + return 1; } /* call previous history -----------------------------------------------------*/ -static int hist_prev(vt_t *vt) -{ - char *p; - if (vt->cur_h>=MAXHIST||!vt->hist[vt->cur_h]) return 1; - if (!clear_buff(vt)) return 0; - for (p=vt->hist[vt->cur_h++];*p;p++) if (!ins_cur(vt,*p)) return 0; - return 1; +static int hist_prev(vt_t *vt) { + char *p; + if (vt->cur_h >= MAXHIST || !vt->hist[vt->cur_h]) return 1; + if (!clear_buff(vt)) return 0; + for (p = vt->hist[vt->cur_h++]; *p; p++) + if (!ins_cur(vt, *p)) return 0; + return 1; } /* call next history ---------------------------------------------------------*/ -static int hist_next(vt_t *vt) -{ - char *p; - if (!clear_buff(vt)) return 0; - if (vt->cur_h==0||!vt->hist[vt->cur_h-1]) return 1; - for (p=vt->hist[--vt->cur_h];*p;p++) if (!ins_cur(vt,*p)) return 0; - return 1; +static int hist_next(vt_t *vt) { + char *p; + if (!clear_buff(vt)) return 0; + if (vt->cur_h == 0 || !vt->hist[vt->cur_h - 1]) return 1; + for (p = vt->hist[--vt->cur_h]; *p; p++) + if (!ins_cur(vt, *p)) return 0; + return 1; } /* handle telnet sequence ----------------------------------------------------*/ -static int seq_telnet(vt_t *vt) -{ - char msg[3]={C_IAC}; - - if (vt->esc[1]==C_WILL) { /* option negotiation */ - if (vt->nesc<3) return 1; - msg[1]=vt->esc[2]==C_ECHO||vt->esc[2]==C_SUPPGA?C_DO:C_DONT; - msg[2]=vt->esc[2]; - if (write(vt->out,msg,3)<3) return 0; - } - else if (vt->esc[1]==C_DO) { /* option negotiation */ - if (vt->nesc<3) return 1; - msg[1]=vt->esc[2]==C_ECHO||vt->esc[2]==C_SUPPGA?C_WILL:C_WONT; - msg[2]=vt->esc[2]; - if (write(vt->out,msg,3)<3) return 0; - } - else if (vt->esc[1]==C_WONT||vt->esc[1]==C_DONT) { /* option negotiation */ - if (vt->nesc<3) return 1; - msg[1]=vt->esc[1]==C_WONT?C_DONT:C_WONT; - msg[2]=vt->esc[2]; - if (write(vt->out,msg,3)<3) return 0; - } - else if (vt->esc[1]==C_BRK||vt->esc[1]==C_IP) { /* break or interrupt */ - vt->brk=1; - } - else if (vt->esc[1]==C_EC) { /* erase character */ - del_cur(vt); - } - else if (vt->esc[1]==C_EL) { /* erase line */ - clear_buff(vt); - } - vt->nesc=0; - return 1; +static int seq_telnet(vt_t *vt) { + char msg[3] = {C_IAC}; + + if (vt->esc[1] == C_WILL) { /* option negotiation */ + if (vt->nesc < 3) return 1; + msg[1] = vt->esc[2] == C_ECHO || vt->esc[2] == C_SUPPGA ? C_DO : C_DONT; + msg[2] = vt->esc[2]; + if (write(vt->out, msg, 3) < 3) return 0; + } else if (vt->esc[1] == C_DO) { /* option negotiation */ + if (vt->nesc < 3) return 1; + msg[1] = vt->esc[2] == C_ECHO || vt->esc[2] == C_SUPPGA ? C_WILL : C_WONT; + msg[2] = vt->esc[2]; + if (write(vt->out, msg, 3) < 3) return 0; + } else if (vt->esc[1] == C_WONT || vt->esc[1] == C_DONT) { /* option negotiation */ + if (vt->nesc < 3) return 1; + msg[1] = vt->esc[1] == C_WONT ? C_DONT : C_WONT; + msg[2] = vt->esc[2]; + if (write(vt->out, msg, 3) < 3) return 0; + } else if (vt->esc[1] == C_BRK || vt->esc[1] == C_IP) { /* break or interrupt */ + vt->brk = 1; + } else if (vt->esc[1] == C_EC) { /* erase character */ + del_cur(vt); + } else if (vt->esc[1] == C_EL) { /* erase line */ + clear_buff(vt); + } + vt->nesc = 0; + return 1; } /* handle escape sequence ----------------------------------------------------*/ -static int seq_esc(vt_t *vt) -{ - if (vt->nesc<3) return 1; - vt->nesc=0; - if (vt->esc[1]=='['||vt->esc[1]=='O') { - if (vt->esc[2]=='A') return hist_prev(vt); /* cursor up */ - if (vt->esc[2]=='B') return hist_next(vt); /* cursor down */ - if (vt->esc[2]=='C') return right_cur(vt); /* cursor right */ - if (vt->esc[2]=='D') return left_cur (vt); /* cursor left */ - } - return 1; +static int seq_esc(vt_t *vt) { + if (vt->nesc < 3) return 1; + vt->nesc = 0; + if (vt->esc[1] == '[' || vt->esc[1] == 'O') { + if (vt->esc[2] == 'A') return hist_prev(vt); /* cursor up */ + if (vt->esc[2] == 'B') return hist_next(vt); /* cursor down */ + if (vt->esc[2] == 'C') return right_cur(vt); /* cursor right */ + if (vt->esc[2] == 'D') return left_cur(vt); /* cursor left */ + } + return 1; } /* get character from console -------------------------------------------------- -* get a character from virtual console with timeout -* args : vt_t *vt I virtual console -* char *c O character -* return : status (1:ok,0:error) -* notes : if no input, return ok with *c='\0' -*-----------------------------------------------------------------------------*/ -extern int vt_getc(vt_t *vt, char *c) -{ - struct timeval tv={0,1000}; /* timeout (us) */ - fd_set rs; - int stat; - - *c='\0'; - - if (!vt||!vt->state) return 0; - - /* read character with timeout */ - FD_ZERO(&rs); - FD_SET(vt->in,&rs); - if (!(stat=select(vt->in+1,&rs,NULL,NULL,&tv))) return 1; /* no data */ - if (stat<0||read(vt->in,c,1)!=1) return 0; /* error */ - - if ((vt->type&&*c==C_IAC)||*c==C_ESC) { /* escape or telnet */ - vt->esc[0]=*c; *c='\0'; - vt->nesc=1; - } - else if (vt->nesc>0&&vt->esc[0]==C_IAC) { /* telnet sequence */ - vt->esc[vt->nesc++]=*c; *c='\0'; - if (!seq_telnet(vt)) return 0; - } - else if (vt->nesc>0&&vt->esc[0]==C_ESC) { /* escape sequence */ - vt->esc[vt->nesc++]=*c; *c='\0'; - if (!seq_esc(vt)) return 0; - } - else if (*c=='\b'||*c==C_DEL) { /* backspace or delete */ - if (!del_cur(vt)) return 0; - } - else if (*c==C_CTRC) { /* interrupt (ctrl-c) */ - vt->brk=1; - if (!vt_puts(vt,"^C\n")) return 0; - } - else if (isprint(*c)) { /* printable character */ - if (!ins_cur(vt,*c)) return 0; - } - return 1; + * get a character from virtual console with timeout + * args : vt_t *vt I virtual console + * char *c O character + * return : status (1:ok,0:error) + * notes : if no input, return ok with *c='\0' + *-----------------------------------------------------------------------------*/ +extern int vt_getc(vt_t *vt, char *c) { + struct timeval tv = {0, 1000}; /* timeout (us) */ + fd_set rs; + int stat; + + *c = '\0'; + + if (!vt || !vt->state) return 0; + + /* read character with timeout */ + FD_ZERO(&rs); + FD_SET(vt->in, &rs); + if (!(stat = select(vt->in + 1, &rs, NULL, NULL, &tv))) return 1; /* no data */ + if (stat < 0 || read(vt->in, c, 1) != 1) return 0; /* error */ + + if ((vt->type && *c == C_IAC) || *c == C_ESC) { /* escape or telnet */ + vt->esc[0] = *c; + *c = '\0'; + vt->nesc = 1; + } else if (vt->nesc > 0 && vt->esc[0] == C_IAC) { /* telnet sequence */ + vt->esc[vt->nesc++] = *c; + *c = '\0'; + if (!seq_telnet(vt)) return 0; + } else if (vt->nesc > 0 && vt->esc[0] == C_ESC) { /* escape sequence */ + vt->esc[vt->nesc++] = *c; + *c = '\0'; + if (!seq_esc(vt)) return 0; + } else if (*c == '\b' || *c == C_DEL) { /* backspace or delete */ + if (!del_cur(vt)) return 0; + } else if (*c == C_CTRC) { /* interrupt (ctrl-c) */ + vt->brk = 1; + if (!vt_puts(vt, "^C\n")) return 0; + } else if (isprint(*c)) { /* printable character */ + if (!ins_cur(vt, *c)) return 0; + } + return 1; } /* get line from console ------------------------------------------------------- -* get line from virtual console -* args : vt_t *vt I virtual console -* char *buff O buffer -* in n I buffer size -* return : status (1:ok,0:no input) -*-----------------------------------------------------------------------------*/ -extern int vt_gets(vt_t *vt, char *buff, int n) -{ - char c; - - buff[0]='\0'; - - if (!vt||!vt->state) return 0; - - vt->n=vt->cur=vt->nesc=vt->brk=0; - - while (vt->state) { - if (!vt_getc(vt,&c)) return 0; - - if (c==C_CTRD&&vt->n==0) { /* logout */ - vt->state=0; - } - else if (vt->brk) { /* break */ - return vt_puts(vt,"\n"); - } - else if (c=='\r') { /* end of line */ - vt->buff[vt->n]='\0'; - strncpy(buff,vt->buff,n-1); - buff[n-1]='\0'; - if (!vt->blind) hist_add(vt,buff); - return vt_putc(vt,'\n'); - } + * get line from virtual console + * args : vt_t *vt I virtual console + * char *buff O buffer + * in n I buffer size + * return : status (1:ok,0:no input) + *-----------------------------------------------------------------------------*/ +extern int vt_gets(vt_t *vt, char *buff, int n) { + char c; + + buff[0] = '\0'; + + if (!vt || !vt->state) return 0; + + vt->n = vt->cur = vt->nesc = vt->brk = 0; + + while (vt->state) { + if (!vt_getc(vt, &c)) return 0; + + if (c == C_CTRD && vt->n == 0) { /* logout */ + vt->state = 0; + } else if (vt->brk) { /* break */ + return vt_puts(vt, "\n"); + } else if (c == '\r') { /* end of line */ + vt->buff[vt->n] = '\0'; + strncpy(buff, vt->buff, n - 1); + buff[n - 1] = '\0'; + if (!vt->blind) hist_add(vt, buff); + return vt_putc(vt, '\n'); } - return 0; + } + return 0; } /* put character to console --------------------------------------------------*/ -static int vt_putchar(vt_t *vt, char c) -{ - if (!vt||!vt->state) return 0; - if (vt->logfp) fwrite(&c,1,1,vt->logfp); - return write(vt->out,&c,1)==1; +static int vt_putchar(vt_t *vt, char c) { + if (!vt || !vt->state) return 0; + if (vt->logfp) fwrite(&c, 1, 1, vt->logfp); + return write(vt->out, &c, 1) == 1; } /* put character to console ---------------------------------------------------- -* put a character to virtual console -* args : vt_t *vt I virtual console -* char c I character -* return : status (1:ok,0:error) -*-----------------------------------------------------------------------------*/ -extern int vt_putc(vt_t *vt, char c) -{ - if (c=='\n'&&!vt_putchar(vt,'\r')) return 0; - return vt_putchar(vt,c); + * put a character to virtual console + * args : vt_t *vt I virtual console + * char c I character + * return : status (1:ok,0:error) + *-----------------------------------------------------------------------------*/ +extern int vt_putc(vt_t *vt, char c) { + if (c == '\n' && !vt_putchar(vt, '\r')) return 0; + return vt_putchar(vt, c); } /* put strings to console ------------------------------------------------------ -* put strings to virtual console -* args : vt_t *vt I virtual console -* char *buff I strings -* return : status (1:ok,0:error) -*-----------------------------------------------------------------------------*/ -extern int vt_puts(vt_t *vt, const char *buff) -{ - const char *p; - for (p=buff;*p;p++) if (!vt_putc(vt,*p)) return 0; - return 1; + * put strings to virtual console + * args : vt_t *vt I virtual console + * char *buff I strings + * return : status (1:ok,0:error) + *-----------------------------------------------------------------------------*/ +extern int vt_puts(vt_t *vt, const char *buff) { + const char *p; + for (p = buff; *p; p++) + if (!vt_putc(vt, *p)) return 0; + return 1; } /* print to console with formatting -------------------------------------------- -* print to virtual console with formatting -* args : vt_t *vt I virtual console -* char *format I format (same as sfprintf) -* ... I variable arguments -* return : status (1:ok,0:error) -*-----------------------------------------------------------------------------*/ -extern int vt_printf(vt_t *vt, const char *format, ...) -{ - va_list ap; - char buff[MAXBUFF+1]; - va_start(ap,format); - vsprintf(buff,format,ap); - va_end(ap); - return vt_puts(vt,buff); + * print to virtual console with formatting + * args : vt_t *vt I virtual console + * char *format I format (same as sfprintf) + * ... I variable arguments + * return : status (1:ok,0:error) + *-----------------------------------------------------------------------------*/ +extern int vt_printf(vt_t *vt, const char *format, ...) { + va_list ap; + char buff[MAXBUFF + 1]; + va_start(ap, format); + vsprintf(buff, format, ap); + va_end(ap); + return vt_puts(vt, buff); } /* check break on console ------------------------------------------------------ -* check break on virtual console -* args : vt_t *vt I virtual console -* return : status (1:break,0:no break) -*-----------------------------------------------------------------------------*/ -extern int vt_chkbrk(vt_t *vt) -{ - char c; - vt->brk=0; - return !vt_getc(vt,&c)||vt->brk; + * check break on virtual console + * args : vt_t *vt I virtual console + * return : status (1:break,0:no break) + *-----------------------------------------------------------------------------*/ +extern int vt_chkbrk(vt_t *vt) { + char c; + vt->brk = 0; + return !vt_getc(vt, &c) || vt->brk; } /* open console log ------------------------------------------------------------ -* open console log for virtual console -* args : vt_t *vt I virtual console -* char *file I log file path -* return : status (1:ok,0:error) -*-----------------------------------------------------------------------------*/ -extern int vt_openlog(vt_t *vt, const char *file) -{ - if (!vt||!vt->state||!(vt->logfp=fopen(file,"w"))) return 0; - return 1; + * open console log for virtual console + * args : vt_t *vt I virtual console + * char *file I log file path + * return : status (1:ok,0:error) + *-----------------------------------------------------------------------------*/ +extern int vt_openlog(vt_t *vt, const char *file) { + if (!vt || !vt->state || !(vt->logfp = fopen(file, "w"))) return 0; + return 1; } /* close console log ----------------------------------------------------------- -* close console log for virtual console -* args : vt_t *vt I virtual console -* return : none -*-----------------------------------------------------------------------------*/ -extern void vt_closelog(vt_t *vt) -{ - if (!vt||!vt->state||!vt->logfp) return; - fclose(vt->logfp); - vt->logfp=NULL; + * close console log for virtual console + * args : vt_t *vt I virtual console + * return : none + *-----------------------------------------------------------------------------*/ +extern void vt_closelog(vt_t *vt) { + if (!vt || !vt->state || !vt->logfp) return; + fclose(vt->logfp); + vt->logfp = NULL; } diff --git a/app/consapp/rtkrcv/vt.h b/app/consapp/rtkrcv/vt.h index c7bf15b70..3ad06a0e4 100644 --- a/app/consapp/rtkrcv/vt.h +++ b/app/consapp/rtkrcv/vt.h @@ -1,34 +1,35 @@ /*------------------------------------------------------------------------------ -* vt.h : header file for virtual console -* -* Copyright (C) 2015 by T.TAKASU, All rights reserved. -* -* version : $Revision:$ $Date:$ -* history : 2015/01/11 1.0 separated from rtkrcv.c -*-----------------------------------------------------------------------------*/ + * vt.h : header file for virtual console + * + * Copyright (C) 2015 by T.TAKASU, All rights reserved. + * + * version : $Revision:$ $Date:$ + * history : 2015/01/11 1.0 separated from rtkrcv.c + *-----------------------------------------------------------------------------*/ #ifndef VT_H #define VT_H #include + #include "rtklib.h" -#define MAXBUFF 4096 /* size of line buffer */ -#define MAXHIST 256 /* size of history buffer */ +#define MAXBUFF 4096 /* size of line buffer */ +#define MAXHIST 256 /* size of history buffer */ /* type definitions ----------------------------------------------------------*/ -typedef struct vt_tag { /* virtual console type */ - int state; /* state(0:close,1:open) */ - int type; /* type (0:dev,1:telnet) */ - int in,out; /* input/output file descriptor */ - int n,nesc; /* number of line buffer/escape */ - int cur; /* cursor position */ - int cur_h; /* current history */ - int brk; /* break status */ - int blind; /* blind inpu mode */ - struct termios tio; /* original terminal attribute */ - char buff[MAXBUFF]; /* line buffer */ - char esc[8]; /* escape buffer */ - char *hist[MAXHIST]; /* history buffer */ - FILE *logfp; /* log file pointer */ +typedef struct vt_tag { /* virtual console type */ + int state; /* state(0:close,1:open) */ + int type; /* type (0:dev,1:telnet) */ + int in, out; /* input/output file descriptor */ + int n, nesc; /* number of line buffer/escape */ + int cur; /* cursor position */ + int cur_h; /* current history */ + int brk; /* break status */ + int blind; /* blind inpu mode */ + struct termios tio; /* original terminal attribute */ + char buff[MAXBUFF]; /* line buffer */ + char esc[8]; /* escape buffer */ + char *hist[MAXHIST]; /* history buffer */ + FILE *logfp; /* log file pointer */ } vt_t; /* function prototypes -------------------------------------------------------*/ diff --git a/app/consapp/str2str/str2str.c b/app/consapp/str2str/str2str.c index f5554e919..b632287b6 100644 --- a/app/consapp/str2str/str2str.c +++ b/app/consapp/str2str/str2str.c @@ -1,212 +1,232 @@ /*------------------------------------------------------------------------------ -* str2str.c : console version of stream server -* -* Copyright (C) 2007-2020 by T.TAKASU, All rights reserved. -* -* version : $Revision: 1.1 $ $Date: 2008/07/17 21:54:53 $ -* history : 2009/06/17 1.0 new -* 2011/05/29 1.1 add -f, -l and -x option -* 2011/11/29 1.2 fix bug on recognize ntrips:// (rtklib_2.4.1_p4) -* 2012/12/25 1.3 add format conversion functions -* add -msg, -opt and -sta options -* modify -p option -* 2013/01/25 1.4 fix bug on showing message -* 2014/02/21 1.5 ignore SIG_HUP -* 2014/08/10 1.5 fix bug on showing message -* 2014/08/26 1.6 support input format gw10, binex and rt17 -* 2014/10/14 1.7 use stdin or stdout if option -in or -out omitted -* 2014/11/08 1.8 add option -a, -i and -o -* 2015/03/23 1.9 fix bug on parsing of command line options -* 2016/01/23 1.10 enable septentrio -* 2016/01/26 1.11 fix bug on station position by -p option (#126) -* add option -px -* 2016/07/01 1.12 support CMR/CMR+ -* 2016/07/23 1.13 add option -c1 -c2 -c3 -c4 -* 2016/09/03 1.14 support ntrip caster -* add option -ft,-fl -* 2016/09/06 1.15 add reload source table by USR2 signal -* 2016/09/17 1.16 add option -b -* 2017/05/26 1.17 add input format tersus -* 2020/11/30 1.18 support api change strsvrstart(),strsvrstat() -*-----------------------------------------------------------------------------*/ + * str2str.c : console version of stream server + * + * Copyright (C) 2007-2020 by T.TAKASU, All rights reserved. + * + * version : $Revision: 1.1 $ $Date: 2008/07/17 21:54:53 $ + * history : 2009/06/17 1.0 new + * 2011/05/29 1.1 add -f, -l and -x option + * 2011/11/29 1.2 fix bug on recognize ntrips:// (rtklib_2.4.1_p4) + * 2012/12/25 1.3 add format conversion functions + * add -msg, -opt and -sta options + * modify -p option + * 2013/01/25 1.4 fix bug on showing message + * 2014/02/21 1.5 ignore SIG_HUP + * 2014/08/10 1.5 fix bug on showing message + * 2014/08/26 1.6 support input format gw10, binex and rt17 + * 2014/10/14 1.7 use stdin or stdout if option -in or -out omitted + * 2014/11/08 1.8 add option -a, -i and -o + * 2015/03/23 1.9 fix bug on parsing of command line options + * 2016/01/23 1.10 enable septentrio + * 2016/01/26 1.11 fix bug on station position by -p option (#126) + * add option -px + * 2016/07/01 1.12 support CMR/CMR+ + * 2016/07/23 1.13 add option -c1 -c2 -c3 -c4 + * 2016/09/03 1.14 support ntrip caster + * add option -ft,-fl + * 2016/09/06 1.15 add reload source table by USR2 signal + * 2016/09/17 1.16 add option -b + * 2017/05/26 1.17 add input format tersus + * 2020/11/30 1.18 support api change strsvrstart(),strsvrstat() + *-----------------------------------------------------------------------------*/ #define _POSIX_C_SOURCE 199506 #include #include #include + #include "rtklib.h" -#define PRGNAME "str2str" /* program name */ -#define MAXSTR 5 /* max number of streams */ -#define TRACEFILE "str2str_%Y%m%d%h%M.trace" /* Debug trace file */ -#define LOGFILE "str2str_%Y%m%d%h%M.log" /* Deamon log file */ +#define PRGNAME "str2str" /* program name */ +#define MAXSTR 5 /* max number of streams */ +#define TRACEFILE "str2str_%Y%m%d%h%M.trace" /* Debug trace file */ +#define LOGFILE "str2str_%Y%m%d%h%M.log" /* Deamon log file */ /* global variables ----------------------------------------------------------*/ -static strsvr_t strsvr; /* stream server */ -static volatile int intrflg=0; /* interrupt flag */ +static strsvr_t strsvr; /* stream server */ +static volatile int intrflg = 0; /* interrupt flag */ /* help text -----------------------------------------------------------------*/ -static const char *help[]={ -"", -" usage: str2str [-in stream] [[-msg ...] -out stream [-out stream...]] [options]", -"", -" Input data from a stream and divide and output them to multiple streams.", -" The input stream can be serial, tcp client, tcp server, ntrip client, or", -" a file. The output stream can be serial, tcp client, tcp server, ntrip", -" server, or a file. str2str is a resident type application. To stop it, type", -" ctr-c in the console if run in the foreground or send signal SIGINT for a", -" background process. If both of the input stream and the output stream have a", -" #format then the format of the input messages are converted to the output", -" format. To specify the output messages use the -msg option before the", -" respective -out options. To specify the log file use the -log option before", -" a respective -in or -out option, and the streams should have separate", -" log files. If the options -in or -out are omitted then stdin for input or", -" stdout for output are used. If the stream for the option -in or -out is null," -" the stdin or stdout are used. Command options are as follows.", -"", -" -in stream[#format] input stream path and format", -" -out stream[#format] output stream path and format", -"", -" stream path", -" serial : serial://port[:brate[:bsize[:parity[:stopb[:fctr]]]]][#tcp_port]", -" tcp server : tcpsvr://:port", -" tcp client : tcpcli://addr[:port]", -" ntrip client : ntrip://[user[:passwd]@]addr[:port][/mntpnt]", -" ntrip server : ntrips://[:passwd@]addr[:port]/mntpnt[:str] (only out)", -" ntrip caster : ntripc://[user:passwd@][:port]/mntpnt[:srctbl] (only out)", -" udp server : udpsvr://:port (only in)", -" udp client : udpcli://addr:port (only out)", -" file : [file://]path[::T][::+start][::xseppd][::S=swap]", -"", -" format", -" rtcm2 : RTCM 2 (only in)", -" rtcm3 : RTCM 3", -" nov : NovAtel OEMV/4/6,OEMStar (only in)", -" ubx : ublox LEA-4T/5T/6T/8/9 (only in)", -" swiftnav : SwiftNav Piksi Multi", -" hemis : Hemisphere Eclipse/Crescent (only in)", -" stq : SkyTraq S1315F (only in)", -" javad : Javad (only in)", -" nvs : NVS BINR (only in)", -" binex : BINEX (only in)", -" rt17 : Trimble RT17 (only in)", -" sbf : Septentrio SBF (only in)", -" unicore : Unicore (only in)", -"", -" -msg \"type[(tint)][,type[(tint)]...]\"", -" rtcm message types and output intervals (s)", -" -log file input log file or output return log file" -" -sta sta station id", -" -opt opt receiver dependent options", -" -s msec timeout time (ms) [10000]", -" -r msec reconnect interval (ms) [10000]", -" -n msec nmea request cycle (m) [0]", -" -f sec file swap margin (s) [30]", -" -c file input commands file [no]", -" -c1 file output 1 commands file [no]", -" -c2 file output 2 commands file [no]", -" -c3 file output 3 commands file [no]", -" -c4 file output 4 commands file [no]", -" -p lat lon hgt station position (latitude/longitude/height) (deg,m)", -" -px x y z station position (x/y/z-ecef) (m)", -" -a antinfo antenna info (separated by ,)", -" -i rcvinfo receiver info (separated by ,)", -" -o e n u antenna offset (e,n,u) (m)", -" -l local_dir ftp/http local directory []", -" -x proxy_addr http/ntrip proxy address [no]", -" -b str_no relay back messages from output str to input str [no]", -" -t level trace level [0]", -" -fl file log file [str2str.trace]", -" --deamon detach from the console", -" --version print version", -" -h print help", -"", -" command file cheat sheet:", -" - # begins a comment, empty lines are ignored", -" - @ separates sections: first startup commands, then stop commands, then periodic commands", -" - binary commands begin with !", -" - WAIT sleep for milliseconds (max 3 seconds)", -" - BRATE set the bitrate, defaults to 115200", -" - UBX send a UBX command (space separated; messages like CFG-MSG, followed by integer decimal (not hex) arguments)", -" - STQ send Skytraq commands", -" - NVS send Nvs commands", -" - HEX send hex messages", -" - other string lines (like NMEA commands) are send as is", +static const char *help[] = { + "", + " usage: str2str [-in stream] [[-msg ...] -out stream [-out stream...]] [options]", + "", + " Input data from a stream and divide and output them to multiple streams.", + " The input stream can be serial, tcp client, tcp server, ntrip client, or", + " a file. The output stream can be serial, tcp client, tcp server, ntrip", + " server, or a file. str2str is a resident type application. To stop it, type", + " ctr-c in the console if run in the foreground or send signal SIGINT for a", + " background process. If both of the input stream and the output stream have a", + " #format then the format of the input messages are converted to the output", + " format. To specify the output messages use the -msg option before the", + " respective -out options. To specify the log file use the -log option before", + " a respective -in or -out option, and the streams should have separate", + " log files. If the options -in or -out are omitted then stdin for input or", + " stdout for output are used. If the stream for the option -in or -out is null," + " the stdin or stdout are used. Command options are as follows.", + "", + " -in stream[#format] input stream path and format", + " -out stream[#format] output stream path and format", + "", + " stream path", + " serial : serial://port[:brate[:bsize[:parity[:stopb[:fctr]]]]][#tcp_port]", + " tcp server : tcpsvr://:port", + " tcp client : tcpcli://addr[:port]", + " ntrip client : ntrip://[user[:passwd]@]addr[:port][/mntpnt]", + " ntrip server : ntrips://[:passwd@]addr[:port]/mntpnt[:str] (only out)", + " ntrip caster : ntripc://[user:passwd@][:port]/mntpnt[:srctbl] (only out)", + " udp server : udpsvr://:port (only in)", + " udp client : udpcli://addr:port (only out)", + " file : [file://]path[::T][::+start][::xseppd][::S=swap]", + "", + " format", + " rtcm2 : RTCM 2 (only in)", + " rtcm3 : RTCM 3", + " nov : NovAtel OEMV/4/6,OEMStar (only in)", + " ubx : ublox LEA-4T/5T/6T/8/9 (only in)", + " swiftnav : SwiftNav Piksi Multi", + " hemis : Hemisphere Eclipse/Crescent (only in)", + " stq : SkyTraq S1315F (only in)", + " javad : Javad (only in)", + " nvs : NVS BINR (only in)", + " binex : BINEX (only in)", + " rt17 : Trimble RT17 (only in)", + " sbf : Septentrio SBF (only in)", + " unicore : Unicore (only in)", + "", + " -msg \"type[(tint)][,type[(tint)]...]\"", + " rtcm message types and output intervals (s)", + " -log file input log file or output return log file" + " -sta sta station id", + " -opt opt receiver dependent options", + " -s msec timeout time (ms) [10000]", + " -r msec reconnect interval (ms) [10000]", + " -n msec nmea request cycle (m) [0]", + " -f sec file swap margin (s) [30]", + " -c file input commands file [no]", + " -c1 file output 1 commands file [no]", + " -c2 file output 2 commands file [no]", + " -c3 file output 3 commands file [no]", + " -c4 file output 4 commands file [no]", + " -p lat lon hgt station position (latitude/longitude/height) (deg,m)", + " -px x y z station position (x/y/z-ecef) (m)", + " -a antinfo antenna info (separated by ,)", + " -i rcvinfo receiver info (separated by ,)", + " -o e n u antenna offset (e,n,u) (m)", + " -l local_dir ftp/http local directory []", + " -x proxy_addr http/ntrip proxy address [no]", + " -b str_no relay back messages from output str to input str [no]", + " -t level trace level [0]", + " -fl file log file [str2str.trace]", + " --deamon detach from the console", + " --version print version", + " -h print help", + "", + " command file cheat sheet:", + " - # begins a comment, empty lines are ignored", + " - @ separates sections: first startup commands, then stop commands, then periodic " + "commands", + " - binary commands begin with !", + " - WAIT sleep for milliseconds (max 3 seconds)", + " - BRATE set the bitrate, defaults to 115200", + " - UBX send a UBX command (space separated; messages like CFG-MSG, followed by integer " + "decimal (not hex) arguments)", + " - STQ send Skytraq commands", + " - NVS send Nvs commands", + " - HEX send hex messages", + " - other string lines (like NMEA commands) are send as is", }; /* print help ----------------------------------------------------------------*/ -static void printhelp(void) -{ - int i; - for (i=0;i 0) { - /* parent */ - _exit(0); - } + /* In case we were not started in the background, fork and let the parent + * exit. Guarantees that the child is not a process group leader. */ + int childpid = fork(); + if (childpid < 0) { + perror("fork\n"); + _exit(1); + } else if (childpid > 0) { + /* parent */ + _exit(0); + } - /* Make ourselves the leader of a new process group with no controlling - * terminal. */ - if (setsid() < 0) { - perror("setsid\n"); - _exit(1); - } + /* Make ourselves the leader of a new process group with no controlling + * terminal. */ + if (setsid() < 0) { + perror("setsid\n"); + _exit(1); + } - for (int fd = 0; fd < 10; fd++) close(fd); + for (int fd = 0; fd < 10; fd++) close(fd); - open("/dev/null", O_RDWR); - gtime_t time = utc2gpst(timeget()); - char path[1024]; - reppath(LOGFILE, path, time, "", ""); - open(path, O_WRONLY|O_CREAT|O_TRUNC, 0666); - dup(1); + open("/dev/null", O_RDWR); + gtime_t time = utc2gpst(timeget()); + char path[1024]; + reppath(LOGFILE, path, time, "", ""); + open(path, O_WRONLY | O_CREAT | O_TRUNC, 0666); + dup(1); #endif } /* str2str -------------------------------------------------------------------*/ -int main(int argc, char **argv) -{ - static char cmd_strs[MAXSTR][MAXRCVCMD]={"","","","",""}; - static char cmd_periodic_strs[MAXSTR][MAXRCVCMD]={"","","","",""}; - const char ss[]={'E','-','W','C','C'}; - strconv_t *conv[MAXSTR]={NULL}; - double pos[3],stapos[3]={0},stadel[3]={0}; - static char s1[MAXSTR][MAXSTRPATH]={{0}}; - char *paths[MAXSTR]; - char *cmdfile[MAXSTR]={"","","","",""},*cmds[MAXSTR],*cmds_periodic[MAXSTR]; - char *local="",*proxy="",*opt="",buff[256],*p; - char strmsg[MAXSTRMSG]="",*antinfo="",*rcvinfo=""; - char *ant[]={"","",""},*rcv[]={"","",""},*logfile=""; - int i,j,n=0,dispint=5000,trlevel=0,opts[]={10000,10000,2000,32768,10,0,30,0}; - int types[MAXSTR]={STR_FILE,STR_FILE},stat[MAXSTR]={0},log_stat[MAXSTR]={0}; - int byte[MAXSTR]={0},bps[MAXSTR]={0},fmts[MAXSTR]={0},sta=0; - int deamon=0; - const char *msg = "1004,1019"; // Current messages. - const char *msgs[MAXSTR]; // Messages per output stream. - const char *log = ""; // Log for the next input or output stream. - const char *logs[MAXSTR]; - - for (i=0;iout.sta.antdes,ant[0]); - strcpy(conv[i]->out.sta.antsno,ant[1]); - conv[i]->out.sta.antsetup=atoi(ant[2]); - strcpy(buff,rcvinfo); - for (p=strtok_r(buff,",",&r),j=0;p&&j<3;p=strtok_r(NULL,",",&r)) rcv[j++]=p; - strcpy(conv[i]->out.sta.rectype,rcv[0]); - strcpy(conv[i]->out.sta.recver ,rcv[1]); - strcpy(conv[i]->out.sta.recsno ,rcv[2]); - matcpy(conv[i]->out.sta.pos,stapos,3,1); - matcpy(conv[i]->out.sta.del,stadel,3,1); - } - if (deamon) deamonise(); - signal(SIGTERM,sigfunc); - signal(SIGINT ,sigfunc); - signal(SIGHUP ,SIG_IGN); - signal(SIGPIPE,SIG_IGN); - - strsvrinit(&strsvr,n+1); - - if (trlevel>0) { - traceopen(*logfile?logfile:TRACEFILE); - tracelevel(trlevel); + for (i = 0; i < n; i++) { + if (fmts[i + 1] <= 0) continue; + if (fmts[i + 1] != STRFMT_RTCM3) { + fprintf(stderr, "unsupported output format\n"); + return EXIT_FAILURE; } - fprintf(stderr,"stream server start\n"); - - strsetdir(local); - strsetproxy(proxy); - - for (i=0;iout.sta.antdes, ant[0]); + strcpy(conv[i]->out.sta.antsno, ant[1]); + conv[i]->out.sta.antsetup = atoi(ant[2]); + strcpy(buff, rcvinfo); + for (p = strtok_r(buff, ",", &r), j = 0; p && j < 3; p = strtok_r(NULL, ",", &r)) rcv[j++] = p; + strcpy(conv[i]->out.sta.rectype, rcv[0]); + strcpy(conv[i]->out.sta.recver, rcv[1]); + strcpy(conv[i]->out.sta.recsno, rcv[2]); + matcpy(conv[i]->out.sta.pos, stapos, 3, 1); + matcpy(conv[i]->out.sta.del, stadel, 3, 1); + } + if (deamon) deamonise(); + signal(SIGTERM, sigfunc); + signal(SIGINT, sigfunc); + signal(SIGHUP, SIG_IGN); + signal(SIGPIPE, SIG_IGN); - char tstr[40]; - time2str(utc2gpst(timeget()),tstr,0); - fprintf(stderr,"%s [%s] %10d B %7d bps %s\n", - tstr,buff,byte[0],bps[0],strmsg); - - sleepms(dispint); - } - for (i=0;i0) { - traceclose(); - } - fprintf(stderr,"stream server stop\n"); - return 0; + strsvrinit(&strsvr, n + 1); + + if (trlevel > 0) { + traceopen(*logfile ? logfile : TRACEFILE); + tracelevel(trlevel); + } + fprintf(stderr, "stream server start\n"); + + strsetdir(local); + strsetproxy(proxy); + + for (i = 0; i < MAXSTR; i++) { + if (*cmdfile[i]) readcmd(cmdfile[i], cmds[i], sizeof(cmd_strs[0]), 0); + if (*cmdfile[i]) readcmd(cmdfile[i], cmds_periodic[i], sizeof(cmd_periodic_strs[0]), 2); + } + /* start stream server */ + if (!strsvrstart(&strsvr, opts, types, (const char **)paths, (const char **)logs, conv, + (const char **)cmds, (const char **)cmds_periodic, stapos)) { + fprintf(stderr, "stream server start error\n"); + return EXIT_FAILURE; + } + for (intrflg = 0; !intrflg;) { + /* get stream server status */ + strsvrstat(&strsvr, stat, log_stat, byte, bps, strmsg); + + /* show stream server status */ + for (i = 0, p = buff; i < MAXSTR; i++) p += sprintf(p, "%c", ss[stat[i] + 1]); + + char tstr[40]; + time2str(utc2gpst(timeget()), tstr, 0); + fprintf(stderr, "%s [%s] %10d B %7d bps %s\n", tstr, buff, byte[0], bps[0], strmsg); + + sleepms(dispint); + } + for (i = 0; i < MAXSTR; i++) { + if (*cmdfile[i]) readcmd(cmdfile[i], cmds[i], sizeof(cmd_strs[0]), 1); + } + /* stop stream server */ + strsvrstop(&strsvr, (const char **)cmds); + + for (i = 0; i < n; i++) { + strconvfree(conv[i]); + } + if (trlevel > 0) { + traceclose(); + } + fprintf(stderr, "stream server stop\n"); + return 0; } diff --git a/app/winapp/appcmn/aboutdlg.cpp b/app/winapp/appcmn/aboutdlg.cpp index 3954bc92f..31ebe2f95 100644 --- a/app/winapp/appcmn/aboutdlg.cpp +++ b/app/winapp/appcmn/aboutdlg.cpp @@ -2,31 +2,24 @@ #include #pragma hdrstop -#include "rtklib.h" #include "aboutdlg.h" + +#include "rtklib.h" //--------------------------------------------------------------------------- #pragma package(smart_init) #pragma resource "*.dfm" TAboutDialog *AboutDialog; //--------------------------------------------------------------------------- -__fastcall TAboutDialog::TAboutDialog(TComponent* Owner) - : TForm(Owner) -{ -} +__fastcall TAboutDialog::TAboutDialog(TComponent *Owner) : TForm(Owner) {} //--------------------------------------------------------------------------- -void __fastcall TAboutDialog::FormShow(TObject *Sender) -{ - TImage *icon[]={Icon1,Icon2,Icon3,Icon4,Icon5,Icon6,Icon7,Icon8}; - AnsiString s; - if (IconIndex>0) icon[IconIndex-1]->Visible=true; - LabelAbout->Caption=About; - LabelVer->Caption=s.sprintf("with RTKLIB-%s %s",VER_RTKLIB,PATCH_LEVEL); - LabelCopyright->Caption=COPYRIGHT_RTKLIB; +void __fastcall TAboutDialog::FormShow(TObject *Sender) { + TImage *icon[] = {Icon1, Icon2, Icon3, Icon4, Icon5, Icon6, Icon7, Icon8}; + AnsiString s; + if (IconIndex > 0) icon[IconIndex - 1]->Visible = true; + LabelAbout->Caption = About; + LabelVer->Caption = s.sprintf("with RTKLIB-%s %s", VER_RTKLIB, PATCH_LEVEL); + LabelCopyright->Caption = COPYRIGHT_RTKLIB; } //--------------------------------------------------------------------------- -void __fastcall TAboutDialog::BtnOkClick(TObject *Sender) -{ - Close(); -} +void __fastcall TAboutDialog::BtnOkClick(TObject *Sender) { Close(); } //--------------------------------------------------------------------------- - diff --git a/app/winapp/appcmn/aboutdlg.h b/app/winapp/appcmn/aboutdlg.h index 420b60bee..2a7e6fd1c 100644 --- a/app/winapp/appcmn/aboutdlg.h +++ b/app/winapp/appcmn/aboutdlg.h @@ -4,35 +4,34 @@ //--------------------------------------------------------------------------- #include #include -#include -#include #include +#include #include +#include #include //--------------------------------------------------------------------------- -class TAboutDialog : public TForm -{ -__published: - TLabel *LabelVer; - TLabel *LabelAbout; - TLabel *LabelCopyright; - TImage *Icon4; - TImage *Icon1; - TImage *Icon2; - TImage *Icon3; - TImage *Icon5; - TImage *Icon6; - TImage *Icon7; - TPanel *Panel1; - TImage *Icon8; - TSpeedButton *BtnOk; - void __fastcall FormShow(TObject *Sender); - void __fastcall BtnOkClick(TObject *Sender); -private: -public: - int IconIndex; - AnsiString About; - __fastcall TAboutDialog(TComponent* Owner); +class TAboutDialog : public TForm { + __published : TLabel *LabelVer; + TLabel *LabelAbout; + TLabel *LabelCopyright; + TImage *Icon4; + TImage *Icon1; + TImage *Icon2; + TImage *Icon3; + TImage *Icon5; + TImage *Icon6; + TImage *Icon7; + TPanel *Panel1; + TImage *Icon8; + TSpeedButton *BtnOk; + void __fastcall FormShow(TObject *Sender); + void __fastcall BtnOkClick(TObject *Sender); + + private: + public: + int IconIndex; + AnsiString About; + __fastcall TAboutDialog(TComponent *Owner); }; //--------------------------------------------------------------------------- extern PACKAGE TAboutDialog *AboutDialog; diff --git a/app/winapp/appcmn/cmdoptdlg.cpp b/app/winapp/appcmn/cmdoptdlg.cpp index 5a848e1fe..51a6d7952 100644 --- a/app/winapp/appcmn/cmdoptdlg.cpp +++ b/app/winapp/appcmn/cmdoptdlg.cpp @@ -1,6 +1,6 @@ //--------------------------------------------------------------------------- -#include #include +#include #pragma hdrstop #include "cmdoptdlg.h" @@ -10,86 +10,78 @@ #pragma resource "*.dfm" TCmdOptDialog *CmdOptDialog; //--------------------------------------------------------------------------- -__fastcall TCmdOptDialog::TCmdOptDialog(TComponent* Owner) - : TForm(Owner) -{ - CmdEna[0]=CmdEna[1]=1; +__fastcall TCmdOptDialog::TCmdOptDialog(TComponent *Owner) : TForm(Owner) { + CmdEna[0] = CmdEna[1] = 1; } //--------------------------------------------------------------------------- -void __fastcall TCmdOptDialog::FormShow(TObject *Sender) -{ - OpenCmd->Text=Cmds[0]; - CloseCmd->Text=Cmds[1]; - PeriodicCmd->Text=Cmds[2]; - ChkOpenCmd->Checked=CmdEna[0];; - ChkCloseCmd->Checked=CmdEna[1];; - ChkPeriodicCmd->Checked=CmdEna[2];; - UpdateEnable(); +void __fastcall TCmdOptDialog::FormShow(TObject *Sender) { + OpenCmd->Text = Cmds[0]; + CloseCmd->Text = Cmds[1]; + PeriodicCmd->Text = Cmds[2]; + ChkOpenCmd->Checked = CmdEna[0]; + ; + ChkCloseCmd->Checked = CmdEna[1]; + ; + ChkPeriodicCmd->Checked = CmdEna[2]; + ; + UpdateEnable(); } //--------------------------------------------------------------------------- -void __fastcall TCmdOptDialog::BtnOkClick(TObject *Sender) -{ - Cmds[0]=OpenCmd->Text; - Cmds[1]=CloseCmd->Text; - Cmds[2]=PeriodicCmd->Text; - CmdEna[0]=ChkOpenCmd->Checked; - CmdEna[1]=ChkCloseCmd->Checked; - CmdEna[2]=ChkPeriodicCmd->Checked; +void __fastcall TCmdOptDialog::BtnOkClick(TObject *Sender) { + Cmds[0] = OpenCmd->Text; + Cmds[1] = CloseCmd->Text; + Cmds[2] = PeriodicCmd->Text; + CmdEna[0] = ChkOpenCmd->Checked; + CmdEna[1] = ChkCloseCmd->Checked; + CmdEna[2] = ChkPeriodicCmd->Checked; } //--------------------------------------------------------------------------- -void __fastcall TCmdOptDialog::BtnLoadClick(TObject *Sender) -{ - AnsiString OpenDialog_FileName; - TMemo *cmd[]={OpenCmd,CloseCmd,PeriodicCmd}; - FILE *fp; - char buff[1024]; - int n=0; - if (!OpenDialog->Execute()) return; - OpenDialog_FileName=OpenDialog->FileName; - if (!(fp=fopen(OpenDialog_FileName.c_str(),"r"))) return; - cmd[0]->Text=""; - cmd[1]->Text=""; - cmd[2]->Text=""; - for (n=0;fgets(buff,sizeof(buff),fp)&&n<3;) { - if (buff[0]=='@') {n++; continue;} - if (buff[strlen(buff)-1]=='\n') buff[strlen(buff)-1]='\0'; - cmd[n]->Text=cmd[n]->Text+buff+"\r\n"; - } - fclose(fp); +void __fastcall TCmdOptDialog::BtnLoadClick(TObject *Sender) { + AnsiString OpenDialog_FileName; + TMemo *cmd[] = {OpenCmd, CloseCmd, PeriodicCmd}; + FILE *fp; + char buff[1024]; + int n = 0; + if (!OpenDialog->Execute()) return; + OpenDialog_FileName = OpenDialog->FileName; + if (!(fp = fopen(OpenDialog_FileName.c_str(), "r"))) return; + cmd[0]->Text = ""; + cmd[1]->Text = ""; + cmd[2]->Text = ""; + for (n = 0; fgets(buff, sizeof(buff), fp) && n < 3;) { + if (buff[0] == '@') { + n++; + continue; + } + if (buff[strlen(buff) - 1] == '\n') buff[strlen(buff) - 1] = '\0'; + cmd[n]->Text = cmd[n]->Text + buff + "\r\n"; + } + fclose(fp); } //--------------------------------------------------------------------------- -void __fastcall TCmdOptDialog::BtnSaveClick(TObject *Sender) -{ - AnsiString SaveDialog_FileName; - AnsiString OpenCmd_Text=OpenCmd->Text,CloseCmd_Text=CloseCmd->Text; - AnsiString PeriodicCmd_Text=PeriodicCmd->Text; - FILE *fp; - if (!SaveDialog->Execute()) return; - SaveDialog_FileName=SaveDialog->FileName; - if (!(fp=fopen(SaveDialog_FileName.c_str(),"w"))) return; - fprintf(fp,"%s",OpenCmd_Text.c_str()); - fprintf(fp,"\n@\n"); - fprintf(fp,"%s",CloseCmd_Text.c_str()); - fprintf(fp,"\n@\n"); - fprintf(fp,"%s",PeriodicCmd_Text.c_str()); - fclose(fp); +void __fastcall TCmdOptDialog::BtnSaveClick(TObject *Sender) { + AnsiString SaveDialog_FileName; + AnsiString OpenCmd_Text = OpenCmd->Text, CloseCmd_Text = CloseCmd->Text; + AnsiString PeriodicCmd_Text = PeriodicCmd->Text; + FILE *fp; + if (!SaveDialog->Execute()) return; + SaveDialog_FileName = SaveDialog->FileName; + if (!(fp = fopen(SaveDialog_FileName.c_str(), "w"))) return; + fprintf(fp, "%s", OpenCmd_Text.c_str()); + fprintf(fp, "\n@\n"); + fprintf(fp, "%s", CloseCmd_Text.c_str()); + fprintf(fp, "\n@\n"); + fprintf(fp, "%s", PeriodicCmd_Text.c_str()); + fclose(fp); } //--------------------------------------------------------------------------- -void __fastcall TCmdOptDialog::ChkCloseCmdClick(TObject *Sender) -{ - UpdateEnable(); -} +void __fastcall TCmdOptDialog::ChkCloseCmdClick(TObject *Sender) { UpdateEnable(); } //--------------------------------------------------------------------------- -void __fastcall TCmdOptDialog::ChkOpenCmdClick(TObject *Sender) -{ - UpdateEnable(); -} +void __fastcall TCmdOptDialog::ChkOpenCmdClick(TObject *Sender) { UpdateEnable(); } //--------------------------------------------------------------------------- -void __fastcall TCmdOptDialog::UpdateEnable(void) -{ - OpenCmd->Enabled=ChkOpenCmd->Checked; - CloseCmd->Enabled=ChkCloseCmd->Checked; - PeriodicCmd->Enabled=ChkPeriodicCmd->Checked; +void __fastcall TCmdOptDialog::UpdateEnable(void) { + OpenCmd->Enabled = ChkOpenCmd->Checked; + CloseCmd->Enabled = ChkCloseCmd->Checked; + PeriodicCmd->Enabled = ChkPeriodicCmd->Checked; } //--------------------------------------------------------------------------- - diff --git a/app/winapp/appcmn/cmdoptdlg.h b/app/winapp/appcmn/cmdoptdlg.h index f57d3856e..45139aa5e 100644 --- a/app/winapp/appcmn/cmdoptdlg.h +++ b/app/winapp/appcmn/cmdoptdlg.h @@ -4,37 +4,36 @@ //--------------------------------------------------------------------------- #include #include -#include -#include #include +#include +#include //--------------------------------------------------------------------------- -class TCmdOptDialog : public TForm -{ -__published: - TButton *BtnOk; - TButton *BtnCancel; - TMemo *OpenCmd; - TMemo *CloseCmd; - TCheckBox *ChkOpenCmd; - TCheckBox *ChkCloseCmd; - TButton *BtnLoad; - TButton *BtnSave; - TSaveDialog *SaveDialog; - TOpenDialog *OpenDialog; - TCheckBox *ChkPeriodicCmd; - TMemo *PeriodicCmd; - void __fastcall FormShow(TObject *Sender); - void __fastcall BtnOkClick(TObject *Sender); - void __fastcall ChkCloseCmdClick(TObject *Sender); - void __fastcall ChkOpenCmdClick(TObject *Sender); - void __fastcall UpdateEnable(void); - void __fastcall BtnLoadClick(TObject *Sender); - void __fastcall BtnSaveClick(TObject *Sender); -private: -public: - AnsiString Cmds[3]; - int CmdEna[3]; - __fastcall TCmdOptDialog(TComponent* Owner); +class TCmdOptDialog : public TForm { + __published : TButton *BtnOk; + TButton *BtnCancel; + TMemo *OpenCmd; + TMemo *CloseCmd; + TCheckBox *ChkOpenCmd; + TCheckBox *ChkCloseCmd; + TButton *BtnLoad; + TButton *BtnSave; + TSaveDialog *SaveDialog; + TOpenDialog *OpenDialog; + TCheckBox *ChkPeriodicCmd; + TMemo *PeriodicCmd; + void __fastcall FormShow(TObject *Sender); + void __fastcall BtnOkClick(TObject *Sender); + void __fastcall ChkCloseCmdClick(TObject *Sender); + void __fastcall ChkOpenCmdClick(TObject *Sender); + void __fastcall UpdateEnable(void); + void __fastcall BtnLoadClick(TObject *Sender); + void __fastcall BtnSaveClick(TObject *Sender); + + private: + public: + AnsiString Cmds[3]; + int CmdEna[3]; + __fastcall TCmdOptDialog(TComponent *Owner); }; //--------------------------------------------------------------------------- extern PACKAGE TCmdOptDialog *CmdOptDialog; diff --git a/app/winapp/appcmn/confdlg.cpp b/app/winapp/appcmn/confdlg.cpp index 3504faa3f..4087eefe4 100644 --- a/app/winapp/appcmn/confdlg.cpp +++ b/app/winapp/appcmn/confdlg.cpp @@ -6,10 +6,7 @@ //--------------------------------------------------------------------------- #pragma package(smart_init) #pragma resource "*.dfm" -TConfDialog *ConfDialog; +TConfDialog* ConfDialog; //--------------------------------------------------------------------------- -__fastcall TConfDialog::TConfDialog(TComponent* Owner) - : TForm(Owner) -{ -} +__fastcall TConfDialog::TConfDialog(TComponent* Owner) : TForm(Owner) {} //--------------------------------------------------------------------------- diff --git a/app/winapp/appcmn/confdlg.h b/app/winapp/appcmn/confdlg.h index 34a3d235c..3c882ab6a 100644 --- a/app/winapp/appcmn/confdlg.h +++ b/app/winapp/appcmn/confdlg.h @@ -4,19 +4,18 @@ //--------------------------------------------------------------------------- #include #include -#include #include +#include //--------------------------------------------------------------------------- -class TConfDialog : public TForm -{ -__published: - TButton *BtnOverwrite; - TButton *BtnCancel; - TLabel *Label1; - TLabel *Label2; -private: -public: - __fastcall TConfDialog(TComponent* Owner); +class TConfDialog : public TForm { + __published : TButton *BtnOverwrite; + TButton *BtnCancel; + TLabel *Label1; + TLabel *Label2; + + private: + public: + __fastcall TConfDialog(TComponent *Owner); }; //--------------------------------------------------------------------------- extern PACKAGE TConfDialog *ConfDialog; diff --git a/app/winapp/appcmn/console.cpp b/app/winapp/appcmn/console.cpp index 48b7296d6..f71feb1d3 100644 --- a/app/winapp/appcmn/console.cpp +++ b/app/winapp/appcmn/console.cpp @@ -1,7 +1,7 @@ //--------------------------------------------------------------------------- -#include #include #include +#include #pragma hdrstop #include "console.h" @@ -9,129 +9,113 @@ #pragma package(smart_init) #pragma resource "*.dfm" -#define MAXLEN 256 -#define MAXLINE 2048 -#define TOPMARGIN 2 -#define LEFTMARGIN 3 +#define MAXLEN 256 +#define MAXLINE 2048 +#define TOPMARGIN 2 +#define LEFTMARGIN 3 TConsole *Console; //--------------------------------------------------------------------------- -__fastcall TConsole::TConsole(TComponent* Owner) - : TForm(Owner) -{ - ConBuff=new TStringList; - ConBuff->Add(""); - DoubleBuffered=true; - Stop=0; - ScrollPos=0; +__fastcall TConsole::TConsole(TComponent *Owner) : TForm(Owner) { + ConBuff = new TStringList; + ConBuff->Add(""); + DoubleBuffered = true; + Stop = 0; + ScrollPos = 0; } //--------------------------------------------------------------------------- -void __fastcall TConsole::ConsolePaint(TObject *Sender) -{ - TCanvas *c=Console->Canvas; - TSize off=c->TextExtent(" "); - int n,m,p,y=TOPMARGIN; - - c->Brush->Style=bsSolid; - c->Brush->Color=clWhite; - c->FillRect(Console->ClientRect); - - n=ConBuff->Count; if (ConBuff->Strings[n-1]=="") n--; - m=(Console->Height-TOPMARGIN*2)/off.cy; - p=m>=n?0:n-m-ScrollPos; - - for (int i=p<0?0:p;iCount;i++,y+=off.cy) { - if (y+off.cy>Console->Height-TOPMARGIN) break; - c->Font->Color=iTextOut(LEFTMARGIN,y,ConBuff->Strings[i]); - } - Scroll->Max=n<=m?m-1:n-m; - Scroll->Position=Scroll->Max-ScrollPos; +void __fastcall TConsole::ConsolePaint(TObject *Sender) { + TCanvas *c = Console->Canvas; + TSize off = c->TextExtent(" "); + int n, m, p, y = TOPMARGIN; + + c->Brush->Style = bsSolid; + c->Brush->Color = clWhite; + c->FillRect(Console->ClientRect); + + n = ConBuff->Count; + if (ConBuff->Strings[n - 1] == "") n--; + m = (Console->Height - TOPMARGIN * 2) / off.cy; + p = m >= n ? 0 : n - m - ScrollPos; + + for (int i = p < 0 ? 0 : p; i < ConBuff->Count; i++, y += off.cy) { + if (y + off.cy > Console->Height - TOPMARGIN) break; + c->Font->Color = i < n - 1 ? clGray : clBlack; + c->TextOut(LEFTMARGIN, y, ConBuff->Strings[i]); + } + Scroll->Max = n <= m ? m - 1 : n - m; + Scroll->Position = Scroll->Max - ScrollPos; } //--------------------------------------------------------------------------- -void __fastcall TConsole::ScrollChange(TObject *Sender) -{ - ScrollPos=Scroll->Max-Scroll->Position; - Console->Invalidate(); +void __fastcall TConsole::ScrollChange(TObject *Sender) { + ScrollPos = Scroll->Max - Scroll->Position; + Console->Invalidate(); } //--------------------------------------------------------------------------- -void __fastcall TConsole::FormResize(TObject *Sender) -{ - Console->Invalidate(); -} +void __fastcall TConsole::FormResize(TObject *Sender) { Console->Invalidate(); } //--------------------------------------------------------------------------- -void __fastcall TConsole::BtnCloseClick(TObject *Sender) -{ - Close(); -} +void __fastcall TConsole::BtnCloseClick(TObject *Sender) { Close(); } //--------------------------------------------------------------------------- -void __fastcall TConsole::BtnAscClick(TObject *Sender) -{ - if (ConBuff->Strings[ConBuff->Count-1]!="") ConBuff->Add(""); - Console->Invalidate(); +void __fastcall TConsole::BtnAscClick(TObject *Sender) { + if (ConBuff->Strings[ConBuff->Count - 1] != "") ConBuff->Add(""); + Console->Invalidate(); } //--------------------------------------------------------------------------- -void __fastcall TConsole::BtnHexClick(TObject *Sender) -{ - if (ConBuff->Strings[ConBuff->Count-1]!="") ConBuff->Add(""); - Console->Invalidate(); +void __fastcall TConsole::BtnHexClick(TObject *Sender) { + if (ConBuff->Strings[ConBuff->Count - 1] != "") ConBuff->Add(""); + Console->Invalidate(); } //--------------------------------------------------------------------------- -void __fastcall TConsole::BtnClearClick(TObject *Sender) -{ - ConBuff->Clear(); - ConBuff->Add(""); - Console->Invalidate(); +void __fastcall TConsole::BtnClearClick(TObject *Sender) { + ConBuff->Clear(); + ConBuff->Add(""); + Console->Invalidate(); } //--------------------------------------------------------------------------- -void __fastcall TConsole::BtnStopClick(TObject *Sender) -{ - Stop=!Stop; - BtnStop->Down=Stop; +void __fastcall TConsole::BtnStopClick(TObject *Sender) { + Stop = !Stop; + BtnStop->Down = Stop; } //--------------------------------------------------------------------------- -void __fastcall TConsole::BtnDownClick(TObject *Sender) -{ - ScrollPos=0; - Console->Invalidate(); +void __fastcall TConsole::BtnDownClick(TObject *Sender) { + ScrollPos = 0; + Console->Invalidate(); } //--------------------------------------------------------------------------- -void __fastcall TConsole::AddMsg(uint8_t *msg, int n) -{ - AnsiString str; - char buff[MAXLEN+16],*p=buff,c; - int mode=BtnAsc->Down; - - if (n<=0||Stop) return; - - str=ConBuff->Strings[ConBuff->Count-1]; - p+=sprintf(p,"%s",str.c_str()); - - for (int i=0;i= MAXLEN) add = 1; - } - } - else { - if (strlen(buff) % 17 == 16) strcat(p++, " "); - p+=sprintf(p,"%02X",msg[i]); - if (p-buff>=67) add = 1; - } - - if (add) { - ConBuff->Strings[ConBuff->Count-1]=buff; - ConBuff->Add(""); - *(p=buff)=0; - if (ConBuff->Count>=MAXLINE) ConBuff->Delete(0); - } - } - ConBuff->Strings[ConBuff->Count-1]=buff; - Console->Invalidate(); +void __fastcall TConsole::AddMsg(uint8_t *msg, int n) { + AnsiString str; + char buff[MAXLEN + 16], *p = buff, c; + int mode = BtnAsc->Down; + + if (n <= 0 || Stop) return; + + str = ConBuff->Strings[ConBuff->Count - 1]; + p += sprintf(p, "%s", str.c_str()); + + for (int i = 0; i < n; i++) { + int add = 0; + if (mode) { + if (msg[i] == '\r') continue; + if (msg[i] == '\n') + add = 1; + else { + p += sprintf(p, "%c", isprint(msg[i]) ? msg[i] : '.'); + if (p - buff >= MAXLEN) add = 1; + } + } else { + if (strlen(buff) % 17 == 16) strcat(p++, " "); + p += sprintf(p, "%02X", msg[i]); + if (p - buff >= 67) add = 1; + } + + if (add) { + ConBuff->Strings[ConBuff->Count - 1] = buff; + ConBuff->Add(""); + *(p = buff) = 0; + if (ConBuff->Count >= MAXLINE) ConBuff->Delete(0); + } + } + ConBuff->Strings[ConBuff->Count - 1] = buff; + Console->Invalidate(); } //--------------------------------------------------------------------------- - diff --git a/app/winapp/appcmn/console.h b/app/winapp/appcmn/console.h index 38e4605d7..e2f786e4e 100644 --- a/app/winapp/appcmn/console.h +++ b/app/winapp/appcmn/console.h @@ -2,42 +2,42 @@ #ifndef consoleH #define consoleH //--------------------------------------------------------------------------- +#include #include #include -#include -#include #include -#include +#include +#include //--------------------------------------------------------------------------- -class TConsole : public TForm -{ -__published: - TPanel *Panel1; - TPanel *Panel2; - TButton *BtnClose; - TSpeedButton *BtnAsc; - TSpeedButton *BtnHex; - TSpeedButton *BtnClear; - TPaintBox *Console; - TScrollBar *Scroll; - TSpeedButton *BtnDown; - TSpeedButton *BtnStop; - void __fastcall BtnCloseClick(TObject *Sender); - void __fastcall BtnClearClick(TObject *Sender); - void __fastcall ConsolePaint(TObject *Sender); - void __fastcall ScrollChange(TObject *Sender); - void __fastcall FormResize(TObject *Sender); - void __fastcall BtnAscClick(TObject *Sender); - void __fastcall BtnHexClick(TObject *Sender); - void __fastcall BtnDownClick(TObject *Sender); - void __fastcall BtnStopClick(TObject *Sender); -private: - TStringList *ConBuff; - int Stop,ScrollPos; -public: - __fastcall TConsole(TComponent* Owner); - void __fastcall AddMsg(uint8_t *buff, int n); +class TConsole : public TForm { + __published : TPanel *Panel1; + TPanel *Panel2; + TButton *BtnClose; + TSpeedButton *BtnAsc; + TSpeedButton *BtnHex; + TSpeedButton *BtnClear; + TPaintBox *Console; + TScrollBar *Scroll; + TSpeedButton *BtnDown; + TSpeedButton *BtnStop; + void __fastcall BtnCloseClick(TObject *Sender); + void __fastcall BtnClearClick(TObject *Sender); + void __fastcall ConsolePaint(TObject *Sender); + void __fastcall ScrollChange(TObject *Sender); + void __fastcall FormResize(TObject *Sender); + void __fastcall BtnAscClick(TObject *Sender); + void __fastcall BtnHexClick(TObject *Sender); + void __fastcall BtnDownClick(TObject *Sender); + void __fastcall BtnStopClick(TObject *Sender); + + private: + TStringList *ConBuff; + int Stop, ScrollPos; + + public: + __fastcall TConsole(TComponent *Owner); + void __fastcall AddMsg(uint8_t *buff, int n); }; //--------------------------------------------------------------------------- extern PACKAGE TConsole *Console; diff --git a/app/winapp/appcmn/fileoptdlg.cpp b/app/winapp/appcmn/fileoptdlg.cpp index 3a0da84ff..57887a81f 100644 --- a/app/winapp/appcmn/fileoptdlg.cpp +++ b/app/winapp/appcmn/fileoptdlg.cpp @@ -1,136 +1,127 @@ //--------------------------------------------------------------------------- -#include #include +#include #pragma hdrstop -#include "keydlg.h" #include "fileoptdlg.h" + +#include "keydlg.h" //--------------------------------------------------------------------------- #pragma package(smart_init) #pragma resource "*.dfm" TFileOptDialog *FileOptDialog; //--------------------------------------------------------------------------- -__fastcall TFileOptDialog::TFileOptDialog(TComponent* Owner) - : TForm(Owner) -{ - Opt=0; - PathEna=0; +__fastcall TFileOptDialog::TFileOptDialog(TComponent *Owner) : TForm(Owner) { + Opt = 0; + PathEna = 0; } //--------------------------------------------------------------------------- -void __fastcall TFileOptDialog::FormShow(TObject *Sender) -{ - AnsiString s; - double speed=1.0,start=0.0,intv=0.0; - char buff[1024]; - char *p; - int size_fpos=4; - strcpy(buff,Path.c_str()); - - ChkTimeTag->Caption=Opt?"TimeTag":"Time"; - Label1 ->Visible=Opt!=2; - PathEnable->Visible=Opt==2; - PathEnable->Checked=Opt!=2||PathEna; - TimeSpeed->Visible=!Opt; - TimeStart->Visible=!Opt; - Label1 ->Caption=Opt?"Output File Path":"Input File Path"; - Label2 ->Visible=!Opt; - Label3 ->Visible=!Opt; - Label4 ->Visible=Opt; - Label5 ->Visible=Opt; - SwapIntv ->Visible=Opt; - BtnKey ->Visible=Opt; - ChkTimeTag->Checked=false; - SwapIntv ->Text=""; - if (!Opt) { // input - for (p=buff;(p=strstr(p,"::"));p+=2) { - if (*(p+2)=='T') ChkTimeTag->Checked=true; - else if (*(p+2)=='+') sscanf(p+2,"+%lf",&start); - else if (*(p+2)=='x') sscanf(p+2,"x%lf",&speed); - else if (*(p+2)=='P') sscanf(p+2,"P=%d",&size_fpos); - } - if (start<=0.0) start=0.0; - if (speed<=0.0) speed=1.0; - TimeSpeed->Text=s.sprintf("x%g",speed); - TimeStart->Text=s.sprintf("%g", start); - Chk64Bit->Checked=size_fpos==8; - if ((p=strstr(buff,"::"))) *p='\0'; - FilePath->Text=buff; - } - else { // output - for (p=buff;(p=strstr(p,"::"));p+=2) { - if (*(p+2)=='T') ChkTimeTag->Checked=true; - else if (*(p+2)=='S') sscanf(p+2,"S=%lf",&intv); - } - if (intv>0.0) SwapIntv->Text=s.sprintf("%.3g",intv); - if ((p=strstr(buff,"::"))) *p='\0'; - FilePath->Text=buff; - } - UpdateEnable(); +void __fastcall TFileOptDialog::FormShow(TObject *Sender) { + AnsiString s; + double speed = 1.0, start = 0.0, intv = 0.0; + char buff[1024]; + char *p; + int size_fpos = 4; + strcpy(buff, Path.c_str()); + + ChkTimeTag->Caption = Opt ? "TimeTag" : "Time"; + Label1->Visible = Opt != 2; + PathEnable->Visible = Opt == 2; + PathEnable->Checked = Opt != 2 || PathEna; + TimeSpeed->Visible = !Opt; + TimeStart->Visible = !Opt; + Label1->Caption = Opt ? "Output File Path" : "Input File Path"; + Label2->Visible = !Opt; + Label3->Visible = !Opt; + Label4->Visible = Opt; + Label5->Visible = Opt; + SwapIntv->Visible = Opt; + BtnKey->Visible = Opt; + ChkTimeTag->Checked = false; + SwapIntv->Text = ""; + if (!Opt) { // input + for (p = buff; (p = strstr(p, "::")); p += 2) { + if (*(p + 2) == 'T') + ChkTimeTag->Checked = true; + else if (*(p + 2) == '+') + sscanf(p + 2, "+%lf", &start); + else if (*(p + 2) == 'x') + sscanf(p + 2, "x%lf", &speed); + else if (*(p + 2) == 'P') + sscanf(p + 2, "P=%d", &size_fpos); + } + if (start <= 0.0) start = 0.0; + if (speed <= 0.0) speed = 1.0; + TimeSpeed->Text = s.sprintf("x%g", speed); + TimeStart->Text = s.sprintf("%g", start); + Chk64Bit->Checked = size_fpos == 8; + if ((p = strstr(buff, "::"))) *p = '\0'; + FilePath->Text = buff; + } else { // output + for (p = buff; (p = strstr(p, "::")); p += 2) { + if (*(p + 2) == 'T') + ChkTimeTag->Checked = true; + else if (*(p + 2) == 'S') + sscanf(p + 2, "S=%lf", &intv); + } + if (intv > 0.0) SwapIntv->Text = s.sprintf("%.3g", intv); + if ((p = strstr(buff, "::"))) *p = '\0'; + FilePath->Text = buff; + } + UpdateEnable(); } //--------------------------------------------------------------------------- -void __fastcall TFileOptDialog::BtnOkClick(TObject *Sender) -{ - AnsiString str; - double swap; - - if (!Opt) { // input - Path=FilePath->Text; - if (ChkTimeTag->Checked) { - Path=Path+"::T"+"::"+TimeSpeed->Text+"::+"+TimeStart->Text; - } - if (Chk64Bit->Checked) { - Path=Path+"::P=8"; - } - } - else { // output - Path=FilePath->Text; - if (ChkTimeTag->Checked) Path+="::T"; - str=SwapIntv->Text; - if (sscanf(str.c_str(),"%lf",&swap)>=1) { - Path+="::S="+str; - } - PathEna=PathEnable->Checked; - } +void __fastcall TFileOptDialog::BtnOkClick(TObject *Sender) { + AnsiString str; + double swap; + + if (!Opt) { // input + Path = FilePath->Text; + if (ChkTimeTag->Checked) { + Path = Path + "::T" + "::" + TimeSpeed->Text + "::+" + TimeStart->Text; + } + if (Chk64Bit->Checked) { + Path = Path + "::P=8"; + } + } else { // output + Path = FilePath->Text; + if (ChkTimeTag->Checked) Path += "::T"; + str = SwapIntv->Text; + if (sscanf(str.c_str(), "%lf", &swap) >= 1) { + Path += "::S=" + str; + } + PathEna = PathEnable->Checked; + } } //--------------------------------------------------------------------------- -void __fastcall TFileOptDialog::BtnFilePathClick(TObject *Sender) -{ - if (!Opt) { - OpenDialog->FileName=FilePath->Text; - if (!OpenDialog->Execute()) return; - FilePath->Text=OpenDialog->FileName; - } - else { - SaveDialog->FileName=FilePath->Text; - if (!SaveDialog->Execute()) return; - FilePath->Text=SaveDialog->FileName; - } +void __fastcall TFileOptDialog::BtnFilePathClick(TObject *Sender) { + if (!Opt) { + OpenDialog->FileName = FilePath->Text; + if (!OpenDialog->Execute()) return; + FilePath->Text = OpenDialog->FileName; + } else { + SaveDialog->FileName = FilePath->Text; + if (!SaveDialog->Execute()) return; + FilePath->Text = SaveDialog->FileName; + } } //--------------------------------------------------------------------------- -void __fastcall TFileOptDialog::ChkTimeTagClick(TObject *Sender) -{ - UpdateEnable(); -} +void __fastcall TFileOptDialog::ChkTimeTagClick(TObject *Sender) { UpdateEnable(); } //--------------------------------------------------------------------------- -void __fastcall TFileOptDialog::BtnKeyClick(TObject *Sender) -{ - KeyDialog->ShowModal(); -} +void __fastcall TFileOptDialog::BtnKeyClick(TObject *Sender) { KeyDialog->ShowModal(); } //--------------------------------------------------------------------------- -void __fastcall TFileOptDialog::UpdateEnable(void) -{ - FilePath ->Enabled=PathEnable->Checked; - BtnFilePath->Enabled=PathEnable->Checked; - TimeSpeed->Enabled=ChkTimeTag->Checked; - TimeStart->Enabled=ChkTimeTag->Checked; - Chk64Bit ->Enabled=ChkTimeTag->Checked; - Label2 ->Enabled=ChkTimeTag->Checked; - Label3 ->Enabled=ChkTimeTag->Checked; - SwapIntv ->Enabled=PathEnable->Checked; - Label4 ->Enabled=PathEnable->Checked; - Label5 ->Enabled=PathEnable->Checked; - ChkTimeTag->Enabled=PathEnable->Checked; - //BtnKey ->Enabled=PathEnable->Checked; +void __fastcall TFileOptDialog::UpdateEnable(void) { + FilePath->Enabled = PathEnable->Checked; + BtnFilePath->Enabled = PathEnable->Checked; + TimeSpeed->Enabled = ChkTimeTag->Checked; + TimeStart->Enabled = ChkTimeTag->Checked; + Chk64Bit->Enabled = ChkTimeTag->Checked; + Label2->Enabled = ChkTimeTag->Checked; + Label3->Enabled = ChkTimeTag->Checked; + SwapIntv->Enabled = PathEnable->Checked; + Label4->Enabled = PathEnable->Checked; + Label5->Enabled = PathEnable->Checked; + ChkTimeTag->Enabled = PathEnable->Checked; + // BtnKey ->Enabled=PathEnable->Checked; } //--------------------------------------------------------------------------- - diff --git a/app/winapp/appcmn/fileoptdlg.h b/app/winapp/appcmn/fileoptdlg.h index 055606788..c811915e3 100644 --- a/app/winapp/appcmn/fileoptdlg.h +++ b/app/winapp/appcmn/fileoptdlg.h @@ -2,47 +2,47 @@ #ifndef fileoptdlgH #define fileoptdlgH //--------------------------------------------------------------------------- +#include #include #include -#include -#include #include #include -#include +#include +#include //--------------------------------------------------------------------------- -class TFileOptDialog : public TForm -{ -__published: - TButton *BtnCancel; - TButton *BtnOk; - TSaveDialog *SaveDialog; - TPanel *Panel1; - TButton *BtnFilePath; - TEdit *FilePath; - TLabel *Label1; - TCheckBox *ChkTimeTag; - TComboBox *TimeSpeed; - TEdit *TimeStart; - TLabel *Label2; - TLabel *Label3; - TLabel *Label4; - TComboBox *SwapIntv; - TLabel *Label5; - TSpeedButton *BtnKey; - TOpenDialog *OpenDialog; - TCheckBox *Chk64Bit; - TCheckBox *PathEnable; - void __fastcall BtnFilePathClick(TObject *Sender); - void __fastcall BtnOkClick(TObject *Sender); - void __fastcall FormShow(TObject *Sender); - void __fastcall ChkTimeTagClick(TObject *Sender); - void __fastcall BtnKeyClick(TObject *Sender); -private: - void __fastcall UpdateEnable(void); -public: - int Opt,PathEna; - AnsiString Path; - __fastcall TFileOptDialog(TComponent* Owner); +class TFileOptDialog : public TForm { + __published : TButton *BtnCancel; + TButton *BtnOk; + TSaveDialog *SaveDialog; + TPanel *Panel1; + TButton *BtnFilePath; + TEdit *FilePath; + TLabel *Label1; + TCheckBox *ChkTimeTag; + TComboBox *TimeSpeed; + TEdit *TimeStart; + TLabel *Label2; + TLabel *Label3; + TLabel *Label4; + TComboBox *SwapIntv; + TLabel *Label5; + TSpeedButton *BtnKey; + TOpenDialog *OpenDialog; + TCheckBox *Chk64Bit; + TCheckBox *PathEnable; + void __fastcall BtnFilePathClick(TObject *Sender); + void __fastcall BtnOkClick(TObject *Sender); + void __fastcall FormShow(TObject *Sender); + void __fastcall ChkTimeTagClick(TObject *Sender); + void __fastcall BtnKeyClick(TObject *Sender); + + private: + void __fastcall UpdateEnable(void); + + public: + int Opt, PathEna; + AnsiString Path; + __fastcall TFileOptDialog(TComponent *Owner); }; //--------------------------------------------------------------------------- extern PACKAGE TFileOptDialog *FileOptDialog; diff --git a/app/winapp/appcmn/freqdlg.cpp b/app/winapp/appcmn/freqdlg.cpp index 91c59ade2..e3696a822 100644 --- a/app/winapp/appcmn/freqdlg.cpp +++ b/app/winapp/appcmn/freqdlg.cpp @@ -7,10 +7,7 @@ //--------------------------------------------------------------------------- #pragma package(smart_init) #pragma resource "*.dfm" -TFreqDialog *FreqDialog; +TFreqDialog* FreqDialog; //--------------------------------------------------------------------------- -__fastcall TFreqDialog::TFreqDialog(TComponent* Owner) - : TForm(Owner) -{ -} +__fastcall TFreqDialog::TFreqDialog(TComponent* Owner) : TForm(Owner) {} //--------------------------------------------------------------------------- diff --git a/app/winapp/appcmn/freqdlg.h b/app/winapp/appcmn/freqdlg.h index 0e6d32554..83afa95c0 100644 --- a/app/winapp/appcmn/freqdlg.h +++ b/app/winapp/appcmn/freqdlg.h @@ -5,81 +5,80 @@ //--------------------------------------------------------------------------- #include #include -#include -#include #include +#include +#include //--------------------------------------------------------------------------- -class TFreqDialog : public TForm -{ -__published: - TButton *BtnOk; - TPanel *Panel1; - TPanel *Panel2; - TLabel *Label3; - TPanel *Panel3; - TLabel *Label5; - TPanel *Panel4; - TLabel *Label7; - TPanel *Panel5; - TLabel *Label9; - TPanel *Panel6; - TLabel *Label11; - TPanel *Panel7; - TPanel *Panel8; - TLabel *Label1; - TPanel *Panel9; - TLabel *Label14; - TPanel *Panel10; - TPanel *Panel11; - TPanel *Panel12; - TPanel *Panel13; - TPanel *Panel14; - TPanel *Panel15; - TPanel *Panel16; - TPanel *Panel17; - TPanel *Panel18; - TPanel *Panel19; - TPanel *Panel20; - TPanel *Panel21; - TPanel *Panel22; - TPanel *Panel23; - TPanel *Panel24; - TPanel *Panel25; - TPanel *Panel26; - TPanel *Panel27; - TPanel *Panel28; - TPanel *Panel29; - TPanel *Panel30; - TPanel *Panel31; - TPanel *Panel32; - TPanel *Panel33; - TPanel *Panel34; - TPanel *Panel35; - TPanel *Panel36; - TPanel *Panel37; - TPanel *Panel38; - TPanel *Panel39; - TPanel *Panel45; - TPanel *Panel46; - TPanel *Panel47; - TPanel *Panel48; - TPanel *Panel49; - TPanel *Panel50; - TPanel *Panel51; - TPanel *Panel52; - TPanel *Panel53; - TPanel *Panel54; - TPanel *Panel55; - TPanel *Panel56; - TPanel *Panel57; - TPanel *Panel58; - TPanel *Panel59; - TPanel *Panel60; - TPanel *Panel61; - TPanel *Panel62; -private: -public: - __fastcall TFreqDialog(TComponent* Owner); +class TFreqDialog : public TForm { + __published : TButton *BtnOk; + TPanel *Panel1; + TPanel *Panel2; + TLabel *Label3; + TPanel *Panel3; + TLabel *Label5; + TPanel *Panel4; + TLabel *Label7; + TPanel *Panel5; + TLabel *Label9; + TPanel *Panel6; + TLabel *Label11; + TPanel *Panel7; + TPanel *Panel8; + TLabel *Label1; + TPanel *Panel9; + TLabel *Label14; + TPanel *Panel10; + TPanel *Panel11; + TPanel *Panel12; + TPanel *Panel13; + TPanel *Panel14; + TPanel *Panel15; + TPanel *Panel16; + TPanel *Panel17; + TPanel *Panel18; + TPanel *Panel19; + TPanel *Panel20; + TPanel *Panel21; + TPanel *Panel22; + TPanel *Panel23; + TPanel *Panel24; + TPanel *Panel25; + TPanel *Panel26; + TPanel *Panel27; + TPanel *Panel28; + TPanel *Panel29; + TPanel *Panel30; + TPanel *Panel31; + TPanel *Panel32; + TPanel *Panel33; + TPanel *Panel34; + TPanel *Panel35; + TPanel *Panel36; + TPanel *Panel37; + TPanel *Panel38; + TPanel *Panel39; + TPanel *Panel45; + TPanel *Panel46; + TPanel *Panel47; + TPanel *Panel48; + TPanel *Panel49; + TPanel *Panel50; + TPanel *Panel51; + TPanel *Panel52; + TPanel *Panel53; + TPanel *Panel54; + TPanel *Panel55; + TPanel *Panel56; + TPanel *Panel57; + TPanel *Panel58; + TPanel *Panel59; + TPanel *Panel60; + TPanel *Panel61; + TPanel *Panel62; + + private: + public: + __fastcall TFreqDialog(TComponent *Owner); }; //--------------------------------------------------------------------------- extern PACKAGE TFreqDialog *FreqDialog; diff --git a/app/winapp/appcmn/ftpoptdlg.cpp b/app/winapp/appcmn/ftpoptdlg.cpp index 808f273af..3115a9cae 100644 --- a/app/winapp/appcmn/ftpoptdlg.cpp +++ b/app/winapp/appcmn/ftpoptdlg.cpp @@ -1,114 +1,104 @@ //--------------------------------------------------------------------------- -#include #include +#include #pragma hdrstop -#include "rtklib.h" #include "ftpoptdlg.h" + #include "keydlg.h" +#include "rtklib.h" //--------------------------------------------------------------------------- #pragma package(smart_init) #pragma resource "*.dfm" TFtpOptDialog *FtpOptDialog; //--------------------------------------------------------------------------- -__fastcall TFtpOptDialog::TFtpOptDialog(TComponent* Owner) - : TForm(Owner) -{ -} +__fastcall TFtpOptDialog::TFtpOptDialog(TComponent *Owner) : TForm(Owner) {} //--------------------------------------------------------------------------- -void __fastcall TFtpOptDialog::FormShow(TObject *Sender) -{ - AnsiString s,cap[]={"FTP Option","HTTP Option"}; - char buff[2048],*p,*q; - char *addr,*file=(char *)"",*user=(char *)"",*passwd=(char *)""; - int topts[4]={0,3600,0,0}; - - Caption=cap[Opt]; - - strcpy(buff,Path.c_str()); - - if ((p=strchr(buff,'/'))) { - if ((q=strstr(p+1,"::"))) { - *q='\0'; - sscanf(q+2,"T=%d,%d,%d,%d",topts,topts+1,topts+2,topts+3); - } - file=p+1; - *p='\0'; +void __fastcall TFtpOptDialog::FormShow(TObject *Sender) { + AnsiString s, cap[] = {"FTP Option", "HTTP Option"}; + char buff[2048], *p, *q; + char *addr, *file = (char *)"", *user = (char *)"", *passwd = (char *)""; + int topts[4] = {0, 3600, 0, 0}; + + Caption = cap[Opt]; + + strcpy(buff, Path.c_str()); + + if ((p = strchr(buff, '/'))) { + if ((q = strstr(p + 1, "::"))) { + *q = '\0'; + sscanf(q + 2, "T=%d,%d,%d,%d", topts, topts + 1, topts + 2, topts + 3); } - if ((p=strrchr(buff,'@'))) { - *p++='\0'; - if ((q=strchr(buff,':'))) { - *q='\0'; passwd=q+1; - } - user=buff; + file = p + 1; + *p = '\0'; + } + if ((p = strrchr(buff, '@'))) { + *p++ = '\0'; + if ((q = strchr(buff, ':'))) { + *q = '\0'; + passwd = q + 1; } - else p=buff; - addr=p; - - Addr->Text=s.sprintf("%s/%s",addr,file); - User->Text=user; - Passwd->Text=passwd; - PathOffset ->Text=s.sprintf("%.2g",topts[0]/3600.0); - Interval ->Text=s.sprintf("%.2g",topts[1]/3600.0); - Offset ->Text=s.sprintf("%.2g",topts[2]/3600.0); - RetryInterval->Text=s.sprintf("%d",topts[3]); - Addr->Items->Clear(); - for (int i=0;iItems->Add(History[i]); - } - UpdateEnable(); + user = buff; + } else + p = buff; + addr = p; + + Addr->Text = s.sprintf("%s/%s", addr, file); + User->Text = user; + Passwd->Text = passwd; + PathOffset->Text = s.sprintf("%.2g", topts[0] / 3600.0); + Interval->Text = s.sprintf("%.2g", topts[1] / 3600.0); + Offset->Text = s.sprintf("%.2g", topts[2] / 3600.0); + RetryInterval->Text = s.sprintf("%d", topts[3]); + Addr->Items->Clear(); + for (int i = 0; i < MAXHIST; i++) { + if (History[i] != "") Addr->Items->Add(History[i]); + } + UpdateEnable(); } //--------------------------------------------------------------------------- -void __fastcall TFtpOptDialog::BtnOkClick(TObject *Sender) -{ - AnsiString PathOffset_Text=PathOffset->Text; - AnsiString Interval_Text=Interval->Text; - AnsiString Offset_Text=Offset->Text; - AnsiString RetryInterval_Text=RetryInterval->Text; - AnsiString User_Text=User->Text,Passwd_Text=Passwd->Text; - AnsiString Addr_Text=Addr->Text,s; - int topts[4]; - - topts[0]=(int)(atof(PathOffset_Text.c_str())*3600.0); - topts[1]=(int)(atof(Interval_Text.c_str())*3600.0); - topts[2]=(int)(atof(Offset_Text.c_str())*3600.0); - topts[3]=atoi(RetryInterval_Text.c_str()); - - Path=s.sprintf("%s:%s@%s::T=%d,%d,%d,%d",User_Text.c_str(), - Passwd_Text.c_str(),Addr_Text.c_str(), - topts[0],topts[1],topts[2],topts[3]); - - AddHist(Addr,History); +void __fastcall TFtpOptDialog::BtnOkClick(TObject *Sender) { + AnsiString PathOffset_Text = PathOffset->Text; + AnsiString Interval_Text = Interval->Text; + AnsiString Offset_Text = Offset->Text; + AnsiString RetryInterval_Text = RetryInterval->Text; + AnsiString User_Text = User->Text, Passwd_Text = Passwd->Text; + AnsiString Addr_Text = Addr->Text, s; + int topts[4]; + + topts[0] = (int)(atof(PathOffset_Text.c_str()) * 3600.0); + topts[1] = (int)(atof(Interval_Text.c_str()) * 3600.0); + topts[2] = (int)(atof(Offset_Text.c_str()) * 3600.0); + topts[3] = atoi(RetryInterval_Text.c_str()); + + Path = s.sprintf("%s:%s@%s::T=%d,%d,%d,%d", User_Text.c_str(), Passwd_Text.c_str(), + Addr_Text.c_str(), topts[0], topts[1], topts[2], topts[3]); + + AddHist(Addr, History); } //--------------------------------------------------------------------------- -void __fastcall TFtpOptDialog::BtnKeyClick(TObject *Sender) -{ - KeyDialog->Show(); -} +void __fastcall TFtpOptDialog::BtnKeyClick(TObject *Sender) { KeyDialog->Show(); } //--------------------------------------------------------------------------- -void __fastcall TFtpOptDialog::AddHist(TComboBox *list, AnsiString *hist) -{ - for (int i=0;iText!=hist[i]) continue; - for (int j=i+1;j0;i--) hist[i]=hist[i-1]; - hist[0]=list->Text; - - list->Clear(); - for (int i=0;iItems->Add(hist[i]); - } +void __fastcall TFtpOptDialog::AddHist(TComboBox *list, AnsiString *hist) { + for (int i = 0; i < MAXHIST; i++) { + if (list->Text != hist[i]) continue; + for (int j = i + 1; j < MAXHIST; j++) hist[j - 1] = hist[j]; + hist[MAXHIST - 1] = ""; + } + for (int i = MAXHIST - 1; i > 0; i--) hist[i] = hist[i - 1]; + hist[0] = list->Text; + + list->Clear(); + for (int i = 0; i < MAXHIST; i++) { + if (hist[i] != "") list->Items->Add(hist[i]); + } } //--------------------------------------------------------------------------- -void __fastcall TFtpOptDialog::UpdateEnable(void) -{ - User ->Enabled=Opt==0; - Passwd ->Enabled=Opt==0; - LabelUser ->Enabled=Opt==0; - LabelPasswd->Enabled=Opt==0; +void __fastcall TFtpOptDialog::UpdateEnable(void) { + User->Enabled = Opt == 0; + Passwd->Enabled = Opt == 0; + LabelUser->Enabled = Opt == 0; + LabelPasswd->Enabled = Opt == 0; } //--------------------------------------------------------------------------- - diff --git a/app/winapp/appcmn/ftpoptdlg.h b/app/winapp/appcmn/ftpoptdlg.h index a6d108ede..de6baaa0f 100644 --- a/app/winapp/appcmn/ftpoptdlg.h +++ b/app/winapp/appcmn/ftpoptdlg.h @@ -2,49 +2,49 @@ #ifndef ftpoptdlgH #define ftpoptdlgH //--------------------------------------------------------------------------- +#include #include #include -#include #include -#include +#include -#define MAXHIST 10 +#define MAXHIST 10 //--------------------------------------------------------------------------- -class TFtpOptDialog : public TForm -{ -__published: - TButton *BtnCancel; - TButton *BtnOk; - TEdit *User; - TEdit *Passwd; - TLabel *LabelUser; - TLabel *LabelPasswd; - TComboBox *Addr; - TLabel *Label1; - TComboBox *Interval; - TLabel *Label2; - TLabel *Label3; - TComboBox *Offset; - TLabel *Label4; - TEdit *RetryInterval; - TLabel *Label5; - TLabel *Label6; - TLabel *Label7; - TSpeedButton *BtnKey; - TLabel *Label8; - TComboBox *PathOffset; - TLabel *Label9; - void __fastcall FormShow(TObject *Sender); - void __fastcall BtnOkClick(TObject *Sender); - void __fastcall BtnKeyClick(TObject *Sender); -private: - void __fastcall AddHist(TComboBox *list, AnsiString *hist); - void __fastcall UpdateEnable(void); -public: - int Opt; - AnsiString Path,History[MAXHIST],MntpHist[MAXHIST]; - __fastcall TFtpOptDialog(TComponent* Owner); +class TFtpOptDialog : public TForm { + __published : TButton *BtnCancel; + TButton *BtnOk; + TEdit *User; + TEdit *Passwd; + TLabel *LabelUser; + TLabel *LabelPasswd; + TComboBox *Addr; + TLabel *Label1; + TComboBox *Interval; + TLabel *Label2; + TLabel *Label3; + TComboBox *Offset; + TLabel *Label4; + TEdit *RetryInterval; + TLabel *Label5; + TLabel *Label6; + TLabel *Label7; + TSpeedButton *BtnKey; + TLabel *Label8; + TComboBox *PathOffset; + TLabel *Label9; + void __fastcall FormShow(TObject *Sender); + void __fastcall BtnOkClick(TObject *Sender); + void __fastcall BtnKeyClick(TObject *Sender); + + private: + void __fastcall AddHist(TComboBox *list, AnsiString *hist); + void __fastcall UpdateEnable(void); + + public: + int Opt; + AnsiString Path, History[MAXHIST], MntpHist[MAXHIST]; + __fastcall TFtpOptDialog(TComponent *Owner); }; //--------------------------------------------------------------------------- extern PACKAGE TFtpOptDialog *FtpOptDialog; diff --git a/app/winapp/appcmn/glofcndlg.cpp b/app/winapp/appcmn/glofcndlg.cpp index 94ecfa910..5297ea3e8 100644 --- a/app/winapp/appcmn/glofcndlg.cpp +++ b/app/winapp/appcmn/glofcndlg.cpp @@ -3,111 +3,100 @@ #include #pragma hdrstop -#include "rtklib.h" #include "glofcndlg.h" + +#include "rtklib.h" //--------------------------------------------------------------------------- #pragma package(smart_init) #pragma resource "*.dfm" TGloFcnDialog *GloFcnDialog; //--------------------------------------------------------------------------- -__fastcall TGloFcnDialog::TGloFcnDialog(TComponent* Owner) - : TForm(Owner) -{ - EnaGloFcn=0; +__fastcall TGloFcnDialog::TGloFcnDialog(TComponent *Owner) : TForm(Owner) { + EnaGloFcn = 0; - for (int i=0;i<27;i++) { - GloFcn[i]=0; - } + for (int i = 0; i < 27; i++) { + GloFcn[i] = 0; + } } //--------------------------------------------------------------------------- -void __fastcall TGloFcnDialog::FormShow(TObject *Sender) -{ - AnsiString text; +void __fastcall TGloFcnDialog::FormShow(TObject *Sender) { + AnsiString text; - EnaFcn->Checked=EnaGloFcn; + EnaFcn->Checked = EnaGloFcn; - for (int i=0;i<27;i++) { - if (GloFcn[i]) GetFcn(i+1)->Text=text.sprintf("%d",GloFcn[i]-8); - else GetFcn(i+1)->Text=""; - } - UpdateEnable(); + for (int i = 0; i < 27; i++) { + if (GloFcn[i]) + GetFcn(i + 1)->Text = text.sprintf("%d", GloFcn[i] - 8); + else + GetFcn(i + 1)->Text = ""; + } + UpdateEnable(); } //--------------------------------------------------------------------------- -void __fastcall TGloFcnDialog::BtnOkClick(TObject *Sender) -{ - AnsiString text; - int no; - - EnaGloFcn=EnaFcn->Checked; - - for (int i=0;i<27;i++) { - text=GetFcn(i+1)->Text; - if (sscanf(text.c_str(),"%d",&no)==1&&no>=-7&&no<=6) { - GloFcn[i]=no+8; - } - else GloFcn[i]=0; // GLONASS FCN+8 (0:none) - } +void __fastcall TGloFcnDialog::BtnOkClick(TObject *Sender) { + AnsiString text; + int no; + + EnaGloFcn = EnaFcn->Checked; + + for (int i = 0; i < 27; i++) { + text = GetFcn(i + 1)->Text; + if (sscanf(text.c_str(), "%d", &no) == 1 && no >= -7 && no <= 6) { + GloFcn[i] = no + 8; + } else + GloFcn[i] = 0; // GLONASS FCN+8 (0:none) + } } //--------------------------------------------------------------------------- -void __fastcall TGloFcnDialog::BtnReadClick(TObject *Sender) -{ - if (!OpenDialog->Execute()) return; - - nav_t *nav = static_cast(calloc(1, sizeof(nav_t))); - if (nav == NULL) { - trace(1, "TGloFcnDialog::BtnReadClick nav alloc failed\n"); - return; - } +void __fastcall TGloFcnDialog::BtnReadClick(TObject *Sender) { + if (!OpenDialog->Execute()) return; + + nav_t *nav = static_cast(calloc(1, sizeof(nav_t))); + if (nav == NULL) { + trace(1, "TGloFcnDialog::BtnReadClick nav alloc failed\n"); + return; + } - AnsiString file=OpenDialog->FileName; - - if (!readrnx(file.c_str(),0,"",NULL,nav,NULL)) { - free(nav); - return; - } - - for (int i=0;ing;i++) { - int prn; - if (satsys(nav->geph[i].sat,&prn)!=SYS_GLO) continue; - AnsiString text; - GetFcn(prn)->Text=text.sprintf("%d",nav->geph[i].frq); - } - freenav(nav,0xFF); - free(nav); + AnsiString file = OpenDialog->FileName; + + if (!readrnx(file.c_str(), 0, "", NULL, nav, NULL)) { + free(nav); + return; + } + + for (int i = 0; i < nav->ng; i++) { + int prn; + if (satsys(nav->geph[i].sat, &prn) != SYS_GLO) continue; + AnsiString text; + GetFcn(prn)->Text = text.sprintf("%d", nav->geph[i].frq); + } + freenav(nav, 0xFF); + free(nav); } //--------------------------------------------------------------------------- -void __fastcall TGloFcnDialog::BtnClearClick(TObject *Sender) -{ - for (int i=0;i<27;i++) { - GetFcn(i+1)->Text=""; - } +void __fastcall TGloFcnDialog::BtnClearClick(TObject *Sender) { + for (int i = 0; i < 27; i++) { + GetFcn(i + 1)->Text = ""; + } } //--------------------------------------------------------------------------- -void __fastcall TGloFcnDialog::EnaFcnClick(TObject *Sender) -{ - UpdateEnable(); -} +void __fastcall TGloFcnDialog::EnaFcnClick(TObject *Sender) { UpdateEnable(); } //--------------------------------------------------------------------------- -void __fastcall TGloFcnDialog::UpdateEnable(void) -{ - BtnClear->Enabled=EnaFcn->Checked; - BtnRead ->Enabled=EnaFcn->Checked; - Label21 ->Enabled=EnaFcn->Checked; - Label22 ->Enabled=EnaFcn->Checked; - - for (int i=0;i<27;i++) { - GetFcn(i+1)->Enabled=EnaFcn->Checked; - } +void __fastcall TGloFcnDialog::UpdateEnable(void) { + BtnClear->Enabled = EnaFcn->Checked; + BtnRead->Enabled = EnaFcn->Checked; + Label21->Enabled = EnaFcn->Checked; + Label22->Enabled = EnaFcn->Checked; + + for (int i = 0; i < 27; i++) { + GetFcn(i + 1)->Enabled = EnaFcn->Checked; + } } //--------------------------------------------------------------------------- -TEdit * __fastcall TGloFcnDialog::GetFcn(int prn) -{ - TEdit *fcn[]={ - Fcn01,Fcn02,Fcn03,Fcn04,Fcn05,Fcn06,Fcn07,Fcn08,Fcn09,Fcn10, - Fcn11,Fcn12,Fcn13,Fcn14,Fcn15,Fcn16,Fcn17,Fcn18,Fcn19,Fcn20, - Fcn21,Fcn22,Fcn23,Fcn24,Fcn25,Fcn26,Fcn27 - }; - return fcn[prn-1]; +TEdit *__fastcall TGloFcnDialog::GetFcn(int prn) { + TEdit *fcn[] = {Fcn01, Fcn02, Fcn03, Fcn04, Fcn05, Fcn06, Fcn07, Fcn08, Fcn09, + Fcn10, Fcn11, Fcn12, Fcn13, Fcn14, Fcn15, Fcn16, Fcn17, Fcn18, + Fcn19, Fcn20, Fcn21, Fcn22, Fcn23, Fcn24, Fcn25, Fcn26, Fcn27}; + return fcn[prn - 1]; } //--------------------------------------------------------------------------- - diff --git a/app/winapp/appcmn/glofcndlg.h b/app/winapp/appcmn/glofcndlg.h index 61a0b7a61..e9e39da28 100644 --- a/app/winapp/appcmn/glofcndlg.h +++ b/app/winapp/appcmn/glofcndlg.h @@ -5,121 +5,121 @@ //--------------------------------------------------------------------------- #include #include -#include -#include -#include #include +#include +#include +#include //--------------------------------------------------------------------------- -class TGloFcnDialog : public TForm -{ -__published: - TButton *BtnOk; - TButton *BtnCancel; - TPanel *Panel1; - TLabel *Label1; - TEdit *Fcn10; - TPanel *Panel2; - TPanel *Panel3; - TPanel *Panel4; - TLabel *Label2; - TEdit *Fcn09; - TPanel *Panel5; - TLabel *Label3; - TEdit *Fcn08; - TPanel *Panel6; - TLabel *Label4; - TEdit *Fcn07; - TPanel *Panel7; - TLabel *Label5; - TEdit *Fcn06; - TPanel *Panel8; - TLabel *Label6; - TEdit *Fcn05; - TPanel *Panel9; - TLabel *Label7; - TEdit *Fcn04; - TPanel *Panel10; - TLabel *Label8; - TEdit *Fcn03; - TPanel *Panel11; - TLabel *Label9; - TEdit *Fcn02; - TPanel *Panel12; - TLabel *Label10; - TEdit *Fcn01; - TPanel *Panel13; - TPanel *Panel14; - TLabel *Label11; - TEdit *Fcn20; - TPanel *Panel15; - TPanel *Panel16; - TLabel *Label12; - TEdit *Fcn19; - TPanel *Panel17; - TLabel *Label13; - TEdit *Fcn18; - TPanel *Panel18; - TLabel *Label14; - TEdit *Fcn17; - TPanel *Panel19; - TLabel *Label15; - TEdit *Fcn16; - TPanel *Panel20; - TLabel *Label16; - TEdit *Fcn15; - TPanel *Panel21; - TLabel *Label17; - TEdit *Fcn14; - TPanel *Panel22; - TLabel *Label18; - TEdit *Fcn13; - TPanel *Panel23; - TLabel *Label19; - TEdit *Fcn12; - TPanel *Panel24; - TLabel *Label20; - TEdit *Fcn11; - TPanel *Panel25; - TPanel *Panel27; - TPanel *Panel30; - TLabel *Label24; - TEdit *Fcn27; - TPanel *Panel31; - TLabel *Label25; - TEdit *Fcn26; - TPanel *Panel32; - TLabel *Label26; - TEdit *Fcn25; - TPanel *Panel33; - TLabel *Label27; - TEdit *Fcn24; - TPanel *Panel34; - TLabel *Label28; - TEdit *Fcn23; - TPanel *Panel35; - TLabel *Label29; - TEdit *Fcn22; - TPanel *Panel36; - TLabel *Label30; - TEdit *Fcn21; - TButton *BtnRead; - TOpenDialog *OpenDialog; - TButton *BtnClear; - TLabel *Label21; - TLabel *Label22; - TCheckBox *EnaFcn; - void __fastcall FormShow(TObject *Sender); - void __fastcall BtnOkClick(TObject *Sender); - void __fastcall BtnReadClick(TObject *Sender); - void __fastcall BtnClearClick(TObject *Sender); - void __fastcall EnaFcnClick(TObject *Sender); -private: - void __fastcall UpdateEnable(void); - TEdit * __fastcall GetFcn(int prn); -public: - __fastcall TGloFcnDialog(TComponent* Owner); +class TGloFcnDialog : public TForm { + __published : TButton *BtnOk; + TButton *BtnCancel; + TPanel *Panel1; + TLabel *Label1; + TEdit *Fcn10; + TPanel *Panel2; + TPanel *Panel3; + TPanel *Panel4; + TLabel *Label2; + TEdit *Fcn09; + TPanel *Panel5; + TLabel *Label3; + TEdit *Fcn08; + TPanel *Panel6; + TLabel *Label4; + TEdit *Fcn07; + TPanel *Panel7; + TLabel *Label5; + TEdit *Fcn06; + TPanel *Panel8; + TLabel *Label6; + TEdit *Fcn05; + TPanel *Panel9; + TLabel *Label7; + TEdit *Fcn04; + TPanel *Panel10; + TLabel *Label8; + TEdit *Fcn03; + TPanel *Panel11; + TLabel *Label9; + TEdit *Fcn02; + TPanel *Panel12; + TLabel *Label10; + TEdit *Fcn01; + TPanel *Panel13; + TPanel *Panel14; + TLabel *Label11; + TEdit *Fcn20; + TPanel *Panel15; + TPanel *Panel16; + TLabel *Label12; + TEdit *Fcn19; + TPanel *Panel17; + TLabel *Label13; + TEdit *Fcn18; + TPanel *Panel18; + TLabel *Label14; + TEdit *Fcn17; + TPanel *Panel19; + TLabel *Label15; + TEdit *Fcn16; + TPanel *Panel20; + TLabel *Label16; + TEdit *Fcn15; + TPanel *Panel21; + TLabel *Label17; + TEdit *Fcn14; + TPanel *Panel22; + TLabel *Label18; + TEdit *Fcn13; + TPanel *Panel23; + TLabel *Label19; + TEdit *Fcn12; + TPanel *Panel24; + TLabel *Label20; + TEdit *Fcn11; + TPanel *Panel25; + TPanel *Panel27; + TPanel *Panel30; + TLabel *Label24; + TEdit *Fcn27; + TPanel *Panel31; + TLabel *Label25; + TEdit *Fcn26; + TPanel *Panel32; + TLabel *Label26; + TEdit *Fcn25; + TPanel *Panel33; + TLabel *Label27; + TEdit *Fcn24; + TPanel *Panel34; + TLabel *Label28; + TEdit *Fcn23; + TPanel *Panel35; + TLabel *Label29; + TEdit *Fcn22; + TPanel *Panel36; + TLabel *Label30; + TEdit *Fcn21; + TButton *BtnRead; + TOpenDialog *OpenDialog; + TButton *BtnClear; + TLabel *Label21; + TLabel *Label22; + TCheckBox *EnaFcn; + void __fastcall FormShow(TObject *Sender); + void __fastcall BtnOkClick(TObject *Sender); + void __fastcall BtnReadClick(TObject *Sender); + void __fastcall BtnClearClick(TObject *Sender); + void __fastcall EnaFcnClick(TObject *Sender); + + private: + void __fastcall UpdateEnable(void); + TEdit *__fastcall GetFcn(int prn); + + public: + __fastcall TGloFcnDialog(TComponent *Owner); - int EnaGloFcn,GloFcn[27]; + int EnaGloFcn, GloFcn[27]; }; //--------------------------------------------------------------------------- extern PACKAGE TGloFcnDialog *GloFcnDialog; diff --git a/app/winapp/appcmn/gmview.cpp b/app/winapp/appcmn/gmview.cpp index 9550ae0fd..d5821a30a 100644 --- a/app/winapp/appcmn/gmview.cpp +++ b/app/winapp/appcmn/gmview.cpp @@ -3,129 +3,106 @@ //--------------------------------------------------------------------------- #include #pragma hdrstop -#include #include "gmview.h" -#define RTKLIB_GM "rtklib_gmap.htm" +#include + +#define RTKLIB_GM "rtklib_gmap.htm" //--------------------------------------------------------------------------- #pragma package(smart_init) #pragma resource "*.dfm" TGoogleMapView *GoogleMapView; //--------------------------------------------------------------------------- -__fastcall TGoogleMapView::TGoogleMapView(TComponent* Owner) - : TForm(Owner) -{ -} +__fastcall TGoogleMapView::TGoogleMapView(TComponent *Owner) : TForm(Owner) {} //--------------------------------------------------------------------------- -void __fastcall TGoogleMapView::FormShow(TObject *Sender) -{ - UnicodeString url; - AnsiString exe,dir=".",file; - char *p,*q; - - exe=Application->ExeName; // exe directory - p=exe.c_str(); - if ((q=strrchr(p,'\\'))) { - dir=exe.SubString(1,q-p); - } - url="file://"+dir+"\\"+RTKLIB_GM; - - WebBrowser->Navigate(url.c_str()); +void __fastcall TGoogleMapView::FormShow(TObject *Sender) { + UnicodeString url; + AnsiString exe, dir = ".", file; + char *p, *q; + + exe = Application->ExeName; // exe directory + p = exe.c_str(); + if ((q = strrchr(p, '\\'))) { + dir = exe.SubString(1, q - p); + } + url = "file://" + dir + "\\" + RTKLIB_GM; + + WebBrowser->Navigate(url.c_str()); } //--------------------------------------------------------------------------- -int __fastcall TGoogleMapView::GetState(void) -{ - IHTMLDocument3 *doc=NULL; - IHTMLElement *ele1=NULL; - VARIANT var; - int state; - - if (!WebBrowser->Document) return 0; - WebBrowser->Document->QueryInterface(IID_IHTMLDocument3,(void **)&doc); - if (!doc) return 0; - BSTR bstr1=SysAllocString(L"state"); - doc->getElementById(bstr1,&ele1); - SysFreeString(bstr1); - doc->Release(); - if (!ele1) return 0; - - VariantInit(&var); - BSTR bstr2=SysAllocString(L"value"); - if (ele1->getAttribute(bstr2,0,&var)!=S_OK) { - SysFreeString(bstr2); - VariantClear(&var); - return 0; - } +int __fastcall TGoogleMapView::GetState(void) { + IHTMLDocument3 *doc = NULL; + IHTMLElement *ele1 = NULL; + VARIANT var; + int state; + + if (!WebBrowser->Document) return 0; + WebBrowser->Document->QueryInterface(IID_IHTMLDocument3, (void **)&doc); + if (!doc) return 0; + BSTR bstr1 = SysAllocString(L"state"); + doc->getElementById(bstr1, &ele1); + SysFreeString(bstr1); + doc->Release(); + if (!ele1) return 0; + + VariantInit(&var); + BSTR bstr2 = SysAllocString(L"value"); + if (ele1->getAttribute(bstr2, 0, &var) != S_OK) { SysFreeString(bstr2); - swscanf(var.bstrVal,L"%d",&state); - VariantClear(&var); - return state; + VariantClear(&var); + return 0; + } + SysFreeString(bstr2); + swscanf(var.bstrVal, L"%d", &state); + VariantClear(&var); + return state; } //--------------------------------------------------------------------------- -void __fastcall TGoogleMapView::BtnCloseClick(TObject *Sender) -{ - Close(); -} +void __fastcall TGoogleMapView::BtnCloseClick(TObject *Sender) { Close(); } //--------------------------------------------------------------------------- -void __fastcall TGoogleMapView::BtnHomeClick(TObject *Sender) -{ - ShowHome(); -} +void __fastcall TGoogleMapView::BtnHomeClick(TObject *Sender) { ShowHome(); } //--------------------------------------------------------------------------- -void __fastcall TGoogleMapView::ShowHome(void) -{ - ExecFunc("ShowHome()"); -} +void __fastcall TGoogleMapView::ShowHome(void) { ExecFunc("ShowHome()"); } //--------------------------------------------------------------------------- -void __fastcall TGoogleMapView::ClearMark(void) -{ - ExecFunc("ClearMark()"); -} +void __fastcall TGoogleMapView::ClearMark(void) { ExecFunc("ClearMark()"); } //--------------------------------------------------------------------------- -void __fastcall TGoogleMapView::AddMark(double lat, double lon, - AnsiString title, AnsiString msg) -{ - AnsiString f; - if (lon>=180.0) lon-=360.0; - ExecFunc(f.sprintf("AddMark(%.7f,%.7f,\"%s\",\"%s\")",lat,lon,title.c_str(),msg.c_str())); +void __fastcall TGoogleMapView::AddMark(double lat, double lon, AnsiString title, AnsiString msg) { + AnsiString f; + if (lon >= 180.0) lon -= 360.0; + ExecFunc(f.sprintf("AddMark(%.7f,%.7f,\"%s\",\"%s\")", lat, lon, title.c_str(), msg.c_str())); } //--------------------------------------------------------------------------- -void __fastcall TGoogleMapView::PosMark(double lat, double lon, - AnsiString title) -{ - AnsiString f; - ExecFunc(f.sprintf("PosMark(%.7f,%.7f,\"%s\")",lat,lon,title.c_str())); +void __fastcall TGoogleMapView::PosMark(double lat, double lon, AnsiString title) { + AnsiString f; + ExecFunc(f.sprintf("PosMark(%.7f,%.7f,\"%s\")", lat, lon, title.c_str())); } //--------------------------------------------------------------------------- -void __fastcall TGoogleMapView::HighlightMark(AnsiString title) -{ - AnsiString f; - ExecFunc(f.sprintf("HighlightMark(\"%s\")",title.c_str())); +void __fastcall TGoogleMapView::HighlightMark(AnsiString title) { + AnsiString f; + ExecFunc(f.sprintf("HighlightMark(\"%s\")", title.c_str())); } //--------------------------------------------------------------------------- -void __fastcall TGoogleMapView::ExecFunc(AnsiString func) -{ - IHTMLWindow2 *win; - IHTMLDocument2 *doc=NULL; - VARIANT var; - HRESULT hr; - wchar_t func_w[1024]={0}; - - if (!WebBrowser->Document) return; - WebBrowser->Document->QueryInterface(IID_IHTMLDocument2,(void **)&doc); - if (!doc) return; - hr=doc->get_parentWindow(&win); - doc->Release(); - if (hr!=S_OK) return; - - VariantInit(&var); - ::MultiByteToWideChar(CP_UTF8,0,func.c_str(),-1,func_w,512); - BSTR bstr1=SysAllocString(func_w); - BSTR bstr2=SysAllocString(L"javascript"); - hr=win->execScript(bstr1,bstr2,&var); - SysFreeString(bstr1); - SysFreeString(bstr2); - VariantClear(&var); +void __fastcall TGoogleMapView::ExecFunc(AnsiString func) { + IHTMLWindow2 *win; + IHTMLDocument2 *doc = NULL; + VARIANT var; + HRESULT hr; + wchar_t func_w[1024] = {0}; + + if (!WebBrowser->Document) return; + WebBrowser->Document->QueryInterface(IID_IHTMLDocument2, (void **)&doc); + if (!doc) return; + hr = doc->get_parentWindow(&win); + doc->Release(); + if (hr != S_OK) return; + + VariantInit(&var); + ::MultiByteToWideChar(CP_UTF8, 0, func.c_str(), -1, func_w, 512); + BSTR bstr1 = SysAllocString(func_w); + BSTR bstr2 = SysAllocString(L"javascript"); + hr = win->execScript(bstr1, bstr2, &var); + SysFreeString(bstr1); + SysFreeString(bstr2); + VariantClear(&var); } //--------------------------------------------------------------------------- - diff --git a/app/winapp/appcmn/gmview.h b/app/winapp/appcmn/gmview.h index cba2efff2..75bf8ed24 100644 --- a/app/winapp/appcmn/gmview.h +++ b/app/winapp/appcmn/gmview.h @@ -3,37 +3,36 @@ #define gmviewH //--------------------------------------------------------------------------- #include +#include #include -#include -#include -#include "SHDocVw_OCX.h" #include +#include #include -#include +#include + +#include "SHDocVw_OCX.h" //--------------------------------------------------------------------------- -class TGoogleMapView : public TForm -{ -__published: - TPanel *Panel1; - TPanel *Panel2; - TButton *BtnClose; - TSpeedButton *BtnHome; - TCppWebBrowser *WebBrowser; - void __fastcall BtnCloseClick(TObject *Sender); - void __fastcall BtnHomeClick(TObject *Sender); - void __fastcall FormShow(TObject *Sender); +class TGoogleMapView : public TForm { + __published : TPanel *Panel1; + TPanel *Panel2; + TButton *BtnClose; + TSpeedButton *BtnHome; + TCppWebBrowser *WebBrowser; + void __fastcall BtnCloseClick(TObject *Sender); + void __fastcall BtnHomeClick(TObject *Sender); + void __fastcall FormShow(TObject *Sender); -private: - void __fastcall ExecFunc(AnsiString func); + private: + void __fastcall ExecFunc(AnsiString func); -public: - __fastcall TGoogleMapView(TComponent* Owner); - void __fastcall ShowHome(void); - int __fastcall GetState(void); - void __fastcall ClearMark(void); - void __fastcall AddMark(double lat, double lon, AnsiString title, AnsiString msg); - void __fastcall PosMark(double lat, double lon, AnsiString title); - void __fastcall HighlightMark(AnsiString title); + public: + __fastcall TGoogleMapView(TComponent *Owner); + void __fastcall ShowHome(void); + int __fastcall GetState(void); + void __fastcall ClearMark(void); + void __fastcall AddMark(double lat, double lon, AnsiString title, AnsiString msg); + void __fastcall PosMark(double lat, double lon, AnsiString title); + void __fastcall HighlightMark(AnsiString title); }; //--------------------------------------------------------------------------- extern PACKAGE TGoogleMapView *GoogleMapView; diff --git a/app/winapp/appcmn/graph.cpp b/app/winapp/appcmn/graph.cpp index 723272980..55fde5214 100644 --- a/app/winapp/appcmn/graph.cpp +++ b/app/winapp/appcmn/graph.cpp @@ -1,760 +1,813 @@ //--------------------------------------------------------------------------- // graph.cpp: graph plot subfunctions //--------------------------------------------------------------------------- -#include #include +#include #pragma hdrstop -#include "rtklib.h" #include "graph.h" -#define MINSIZE 10 // min width/height -#define MINSCALE 2E-5 // min scale factor (pixel/unit) -#define MAXSCALE 1E7 // max scale factor (pixel/unit) -#define MAXCIRCLES 100 // max number of circles -#define SIZEORIGIN 6 +#include "rtklib.h" + +#define MINSIZE 10 // min width/height +#define MINSCALE 2E-5 // min scale factor (pixel/unit) +#define MAXSCALE 1E7 // max scale factor (pixel/unit) +#define MAXCIRCLES 100 // max number of circles +#define SIZEORIGIN 6 -#define SQR(x) ((x)*(x)) -#define MIN(x,y) ((x)<(y)?(x):(y)) -#define MAX(x,y) ((x)>(y)?(x):(y)) +#define SQR(x) ((x) * (x)) +#define MIN(x, y) ((x) < (y) ? (x) : (y)) +#define MAX(x, y) ((x) > (y) ? (x) : (y)) // constructor -------------------------------------------------------------- -TGraph::TGraph(TPaintBox *parent) -{ - TPoint point; - Canvas=parent->Canvas; - X=Y=0; - SetSize(parent->Width,parent->Height); - XCent =YCent =0.0; // center coordinate (unit) - XScale=YScale=0.02; // scale factor (unit/pixel) - Box=1; // show box (0:off,1:on) - Fit=1; // fit scale on resize (0:off,1:on): - XGrid=YGrid=1; // show grid (0:off,1:on) - XTick=YTick=0.0; // grid interval (unit) (0:auto) - XLPos=YLPos=1; // grid label pos (0:off,1:outer,2:inner, - // 3:outer-rot,4:inner-rot,5/6:time,7:axis) - Week=0; // gpsweek no. for time label - Title=XLabel=YLabel=""; // lable string ("":no label) - Color[0]=parent->Color; // background color - Color[1]=clGray; // grid color - Color[2]=clBlack; // title/label color - - p_=point; mark_=0; color_=clBlack; size_=0; rot_=0; -} -TGraph::TGraph(TImage *parent) -{ - TPoint point; - Canvas=parent->Canvas; - X=Y=0; - SetSize(parent->Width,parent->Height); - XCent =YCent =0.0; // center coordinate (unit) - XScale=YScale=0.02; // scale factor (unit/pixel) - Box=1; // show box (0:off,1:on) - Fit=1; // fit scale on resize (0:off,1:on): - XGrid=YGrid=1; // show grid (0:off,1:on) - XTick=YTick=0.0; // grid interval (unit) (0:auto) - XLPos=YLPos=1; // grid label pos (0:off,1:outer,2:inner, - // 3:outer-rot,4:inner-rot,5/6:time,7:axis) - Week=0; // gpsweek no. for time label - Title=XLabel=YLabel=""; // lable string ("":no label) - Color[0]=clWhite; // background color - Color[1]=clGray; // grid color - Color[2]=clBlack; // title/label color - - p_=point; mark_=0; color_=clBlack; size_=0; rot_=0; +TGraph::TGraph(TPaintBox *parent) { + TPoint point; + Canvas = parent->Canvas; + X = Y = 0; + SetSize(parent->Width, parent->Height); + XCent = YCent = 0.0; // center coordinate (unit) + XScale = YScale = 0.02; // scale factor (unit/pixel) + Box = 1; // show box (0:off,1:on) + Fit = 1; // fit scale on resize (0:off,1:on): + XGrid = YGrid = 1; // show grid (0:off,1:on) + XTick = YTick = 0.0; // grid interval (unit) (0:auto) + XLPos = YLPos = 1; // grid label pos (0:off,1:outer,2:inner, + // 3:outer-rot,4:inner-rot,5/6:time,7:axis) + Week = 0; // gpsweek no. for time label + Title = XLabel = YLabel = ""; // lable string ("":no label) + Color[0] = parent->Color; // background color + Color[1] = clGray; // grid color + Color[2] = clBlack; // title/label color + + p_ = point; + mark_ = 0; + color_ = clBlack; + size_ = 0; + rot_ = 0; +} +TGraph::TGraph(TImage *parent) { + TPoint point; + Canvas = parent->Canvas; + X = Y = 0; + SetSize(parent->Width, parent->Height); + XCent = YCent = 0.0; // center coordinate (unit) + XScale = YScale = 0.02; // scale factor (unit/pixel) + Box = 1; // show box (0:off,1:on) + Fit = 1; // fit scale on resize (0:off,1:on): + XGrid = YGrid = 1; // show grid (0:off,1:on) + XTick = YTick = 0.0; // grid interval (unit) (0:auto) + XLPos = YLPos = 1; // grid label pos (0:off,1:outer,2:inner, + // 3:outer-rot,4:inner-rot,5/6:time,7:axis) + Week = 0; // gpsweek no. for time label + Title = XLabel = YLabel = ""; // lable string ("":no label) + Color[0] = clWhite; // background color + Color[1] = clGray; // grid color + Color[2] = clBlack; // title/label color + + p_ = point; + mark_ = 0; + color_ = clBlack; + size_ = 0; + rot_ = 0; } // -------------------------------------------------------------------------- -void TGraph::SetSize(int width, int height) -{ - Width =width; - Height=height; +void TGraph::SetSize(int width, int height) { + Width = width; + Height = height; } // -------------------------------------------------------------------------- -int TGraph::IsInArea(TPoint &p) -{ - return X<=p.x&&p.x 1E6) x= 1E6; - if (y<-1E6) y=-1E6; - else if (y> 1E6) y= 1E6; - p.x=(int)floor(x+0.5); - p.y=(int)floor(y+0.5); - return X-xt 1E6) + x = 1E6; + if (y < -1E6) + y = -1E6; + else if (y > 1E6) + y = 1E6; + p.x = (int)floor(x + 0.5); + p.y = (int)floor(y + 0.5); + return X - xt < x && x < X + Width - 1 + xt && Y - xt < y && y < Y + Height - 1 + xt; +} +//--------------------------------------------------------------------------- +void TGraph::ToPos(TPoint p, double &x, double &y) { + x = XCent + (p.x - X - (Width - 1) / 2.0) * XScale; + y = YCent - (p.y - Y - (Height - 1) / 2.0) * YScale; +} +//--------------------------------------------------------------------------- +void TGraph::SetPos(TPoint p1, TPoint p2) { + int w = p2.x - p1.x + 1, h = p2.y - p1.y + 1; + if (w < MINSIZE) w = MINSIZE; + if (h < MINSIZE) h = MINSIZE; + if (Fit) { + XScale *= (double)(Width - 1) / (w - 1); + YScale *= (double)(Height - 1) / (h - 1); + } + X = p1.x; + Y = p1.y; + Width = w; + Height = h; }; //--------------------------------------------------------------------------- -void TGraph::GetPos(TPoint &p1, TPoint &p2) -{ - p1.x=X; p1.y=Y; p2.x=X+Width-1; p2.y=Y+Height-1; +void TGraph::GetPos(TPoint &p1, TPoint &p2) { + p1.x = X; + p1.y = Y; + p2.x = X + Width - 1; + p2.y = Y + Height - 1; }; //--------------------------------------------------------------------------- -void TGraph::SetCent(double x, double y) -{ - XCent=x; YCent=y; +void TGraph::SetCent(double x, double y) { + XCent = x; + YCent = y; } //--------------------------------------------------------------------------- -void TGraph::GetCent(double &x, double &y) -{ - x=XCent; y=YCent; +void TGraph::GetCent(double &x, double &y) { + x = XCent; + y = YCent; } //--------------------------------------------------------------------------- -void TGraph::SetRight(double x, double y) -{ -// XCent=x-(double)(Width-1)*XScale*0.5; YCent=y; - XCent=x-(double)(Width-13)*XScale*0.5; YCent=y; +void TGraph::SetRight(double x, double y) { + // XCent=x-(double)(Width-1)*XScale*0.5; YCent=y; + XCent = x - (double)(Width - 13) * XScale * 0.5; + YCent = y; } //--------------------------------------------------------------------------- -void TGraph::GetRight(double &x, double &y) -{ -// x=XCent+(double)(Width-1)*XScale*0.5; y=YCent; - x=XCent+(double)(Width-13)*XScale*0.5; y=YCent; +void TGraph::GetRight(double &x, double &y) { + // x=XCent+(double)(Width-1)*XScale*0.5; y=YCent; + x = XCent + (double)(Width - 13) * XScale * 0.5; + y = YCent; +} +//--------------------------------------------------------------------------- +void TGraph::SetScale(double xs, double ys) { + if (xs < MINSCALE) + xs = MINSCALE; + else if (MAXSCALE < xs) + xs = MAXSCALE; + if (ys < MINSCALE) + ys = MINSCALE; + else if (MAXSCALE < ys) + ys = MAXSCALE; + XScale = xs; + YScale = ys; +} +//--------------------------------------------------------------------------- +void TGraph::GetScale(double &xs, double &ys) { + xs = XScale; + ys = YScale; +} +//--------------------------------------------------------------------------- +void TGraph::SetLim(const double *xl, const double *yl) { + if (xl[0] < xl[1]) { + XCent = (xl[0] + xl[1]) / 2.0; + XScale = (xl[1] - xl[0]) / (Width - 1); + } + if (yl[0] < yl[1]) { + YCent = (yl[0] + yl[1]) / 2.0; + YScale = (yl[1] - yl[0]) / (Height - 1); + } +} +//--------------------------------------------------------------------------- +void TGraph::GetLim(double *xl, double *yl) { + TPoint p0(X, Y), p1(X + Width - 1, Y + Height - 1); + ToPos(p0, xl[0], yl[1]); + ToPos(p1, xl[1], yl[0]); +} +//--------------------------------------------------------------------------- +void TGraph::SetTick(double xt, double yt) { + XTick = xt; + YTick = yt; +} +//--------------------------------------------------------------------------- +void TGraph::GetTick(double &xt, double &yt) { + xt = XTick > 0.0 ? XTick : (XLPos == 5 || XLPos == 6 ? AutoTickTime(XScale) : AutoTick(XScale)); + yt = YTick > 0.0 ? YTick : AutoTick(YScale); +} +//--------------------------------------------------------------------------- +double TGraph::AutoTick(double scale) { + double t[] = {1.0, 2.0, 5.0, 10.0}, tick = 30.0 * scale; + double order = pow(10.0, floor(log10(tick))); + for (int i = 0; i < 4; i++) + if (tick <= t[i] * order) return t[i] * order; + return 10.0; +} +//--------------------------------------------------------------------------- +double TGraph::AutoTickTime(double scale) { + double t[] = {0.1, 0.2, 0.5, 1.0, 3.0, 6.0, + 12.0, 30.0, 60.0, 300.0, 900.0, 1800.0, + 3600.0, 7200.0, 10800.0, 21600.0, 43200.0, 86400.0, + 86400.0 * 2, 86400.0 * 7, 86400.0 * 14, 86400.0 * 35, 86400.0 * 70}; + double tick = 60.0 * scale; + for (int i = 0; i < (int)(sizeof(t) / sizeof(*t)); i++) + if (tick <= t[i]) return t[i]; + return 86400.0 * 140; +} +//--------------------------------------------------------------------------- +AnsiString TGraph::NumText(double x, double dx) { + AnsiString s; + int n = (int)(0.9 - log10(dx)); + return s.sprintf("%.*f", n < 0 ? 0 : n, x); +} +//--------------------------------------------------------------------------- +AnsiString TGraph::TimeText(double x, double dx) { + AnsiString s; + char str[40]; + time2str(gpst2time(Week, x), str, 1); + int b = dx < 86400.0 ? 11 : (dx < 86400.0 * 30 ? 5 : 2), w = dx < 60.0 ? (dx < 1.0 ? 10 : 8) : 5; + return s.sprintf("%*.*s", w, w, str + b); +} +//--------------------------------------------------------------------------- +void TGraph::DrawGrid(double xt, double yt) { + TCanvas *c = Canvas; + double xl[2], yl[2]; + TPoint p; + GetLim(xl, yl); + c->Pen->Color = Color[1]; + c->Brush->Style = bsClear; + if (XGrid) { + for (int i = (int)ceil(xl[0] / xt); i * xt <= xl[1]; i++) { + ToPoint(i * xt, 0.0, p); + c->Pen->Style = i != 0 ? psDot : psSolid; + c->MoveTo(p.x, Y); + c->LineTo(p.x, Y + Height - 1); + } + } + if (YGrid) { + for (int i = (int)ceil(yl[0] / yt); i * yt <= yl[1]; i++) { + ToPoint(0.0, i * yt, p); + c->Pen->Style = i != 0 ? psDot : psSolid; + c->MoveTo(X, p.y); + c->LineTo(X + Width - 1, p.y); + } + } + DrawMark(0.0, 0.0, 0, Color[1], SIZEORIGIN, 0); +} +//--------------------------------------------------------------------------- +void TGraph::DrawGridLabel(double xt, double yt) { + double xl[2], yl[2]; + TPoint p; + GetLim(xl, yl); + if (XLPos) { + for (int i = (int)ceil(xl[0] / xt); i * xt <= xl[1]; i++) { + if (XLPos <= 4) { + ToPoint(i * xt, yl[0], p); + if (XLPos == 1) p.y -= 1; + int ha = XLPos <= 2 ? 0 : (XLPos == 3 ? 2 : 1), va = XLPos >= 3 ? 0 : (XLPos == 1 ? 2 : 1); + DrawText(p, NumText(i * xt, xt), Color[2], ha, va, XLPos >= 3 ? 90 : 0); + } else if (XLPos == 6) { + ToPoint(i * xt, yl[0], p); + DrawText(p, TimeText(i * xt, xt), Color[2], 0, 2, 0); + } else if (XLPos == 7) { + if (i == 0) continue; + ToPoint(i * xt, 0.0, p); + DrawText(p, NumText(i * xt, xt), Color[2], 0, 2, 0); + } + } + } + if (YLPos) { + for (int i = (int)ceil(yl[0] / yt); i * yt <= yl[1]; i++) { + if (YLPos <= 4) { + ToPoint(xl[0], i * yt, p); + int ha = YLPos >= 3 ? 0 : (YLPos == 1 ? 2 : 1), va = YLPos <= 2 ? 0 : (YLPos == 3 ? 1 : 2); + DrawText(p, NumText(i * yt, yt), Color[2], ha, va, YLPos >= 3 ? 90 : 0); + } else if (YLPos == 7) { + if (i == 0) continue; + ToPoint(0.0, i * yt, p); + p.x += 2; + DrawText(p, NumText(i * yt, yt), Color[2], 1, 0, 0); + } + } + } +} +//--------------------------------------------------------------------------- +void TGraph::DrawBox(void) { + TCanvas *c = Canvas; + if (Box) { + c->Pen->Color = Color[1]; + c->Pen->Style = psSolid; + c->Brush->Style = bsClear; + c->Rectangle(X, Y, X + Width - 1, Y + Height - 1); + } +} +//--------------------------------------------------------------------------- +void TGraph::DrawLabel(void) { + if (XLabel != "") { + TPoint p(X + Width / 2, Y + Height + (XLPos % 2 ? 10 : 2)); + DrawText(p, XLabel, Color[2], 0, 2, 0); + } + if (YLabel != "") { + TPoint p(X - (YLPos % 2 ? 20 : 2), Y + Height / 2); + DrawText(p, YLabel, Color[2], 0, 1, 90); + } + if (Title != "") { + TPoint p(X + Width / 2, Y - 1); + DrawText(p, Title, Color[2], 0, 1, 0); + } +} +//--------------------------------------------------------------------------- +void TGraph::DrawAxis(int label, int glabel) { + TCanvas *c = Canvas; + double xt, yt; + GetTick(xt, yt); + c->Pen->Color = Color[0]; + c->Pen->Style = psSolid; + c->Brush->Color = Color[0]; + c->Brush->Style = bsSolid; + DrawGrid(xt, yt); + if (xt / XScale < 50.0 && XLPos <= 2) xt *= XLPos == 5 ? 4.0 : 2.0; + if (yt / YScale < 50.0 && YLPos >= 3) yt *= 2.0; + if (glabel) DrawGridLabel(xt, yt); + DrawBox(); + if (label) DrawLabel(); +} +//--------------------------------------------------------------------------- +void TGraph::RotPoint(TPoint *ps, int n, TPoint pc, int rot, TPoint *pr) { + double cos_rot = cos(rot * D2R), sin_rot = sin(rot * D2R); + + for (int i = 0; i < n; i++) { + pr[i].x = pc.x + (int)floor(ps[i].x * cos_rot - ps[i].y * sin_rot + 0.5); + pr[i].y = pc.y - (int)floor(ps[i].x * sin_rot + ps[i].y * cos_rot + 0.5); + } } //--------------------------------------------------------------------------- -void TGraph::SetScale(double xs, double ys) -{ - if (xs0.0?XTick:(XLPos==5||XLPos==6?AutoTickTime(XScale):AutoTick(XScale)); - yt=YTick>0.0?YTick:AutoTick(YScale); -} -//--------------------------------------------------------------------------- -double TGraph::AutoTick(double scale) -{ - double t[]={1.0,2.0,5.0,10.0},tick=30.0*scale; - double order=pow(10.0,floor(log10(tick))); - for (int i=0;i<4;i++) if (tick<=t[i]*order) return t[i]*order; - return 10.0; -} -//--------------------------------------------------------------------------- -double TGraph::AutoTickTime(double scale) -{ - double t[]={0.1,0.2,0.5,1.0,3.0,6.0,12.0,30.0,60.0,300.0,900.0,1800.0,3600.0, - 7200.0,10800.0,21600.0,43200.0,86400.0,86400.0*2,86400.0*7,86400.0*14, - 86400.0*35,86400.0*70}; - double tick=60.0*scale; - for (int i=0;i<(int)(sizeof(t)/sizeof(*t));i++) if (tick<=t[i]) return t[i]; - return 86400.0*140; -} -//--------------------------------------------------------------------------- -AnsiString TGraph::NumText(double x, double dx) -{ - AnsiString s; - int n=(int)(0.9-log10(dx)); - return s.sprintf("%.*f",n<0?0:n,x); -} -//--------------------------------------------------------------------------- -AnsiString TGraph::TimeText(double x, double dx) -{ - AnsiString s; - char str[40]; - time2str(gpst2time(Week,x),str,1); - int b=dx<86400.0?11:(dx<86400.0*30?5:2),w=dx<60.0?(dx<1.0?10:8):5; - return s.sprintf("%*.*s",w,w,str+b); -} -//--------------------------------------------------------------------------- -void TGraph::DrawGrid(double xt, double yt) -{ - TCanvas *c=Canvas; - double xl[2],yl[2]; - TPoint p; - GetLim(xl,yl); - c->Pen->Color=Color[1]; c->Brush->Style=bsClear; - if (XGrid) { - for (int i=(int)ceil(xl[0]/xt);i*xt<=xl[1];i++) { - ToPoint(i*xt,0.0,p); - c->Pen->Style=i!=0?psDot:psSolid; - c->MoveTo(p.x,Y); c->LineTo(p.x,Y+Height-1); - } - } - if (YGrid) { - for (int i=(int)ceil(yl[0]/yt);i*yt<=yl[1];i++) { - ToPoint(0.0,i*yt,p); - c->Pen->Style=i!=0?psDot:psSolid; - c->MoveTo(X,p.y); c->LineTo(X+Width-1,p.y); - } - } - DrawMark(0.0,0.0,0,Color[1],SIZEORIGIN,0); -} -//--------------------------------------------------------------------------- -void TGraph::DrawGridLabel(double xt, double yt) -{ - double xl[2],yl[2]; - TPoint p; - GetLim(xl,yl); - if (XLPos) { - for (int i=(int)ceil(xl[0]/xt);i*xt<=xl[1];i++) { - if (XLPos<=4) { - ToPoint(i*xt,yl[0],p); if (XLPos==1) p.y-=1; - int ha=XLPos<=2?0:(XLPos==3?2:1),va=XLPos>=3?0:(XLPos==1?2:1); - DrawText(p,NumText(i*xt,xt),Color[2],ha,va,XLPos>=3?90:0); - } - else if (XLPos==6) { - ToPoint(i*xt,yl[0],p); - DrawText(p,TimeText(i*xt,xt),Color[2],0,2,0); - } - else if (XLPos==7) { - if (i==0) continue; - ToPoint(i*xt,0.0,p); - DrawText(p,NumText(i*xt,xt),Color[2],0,2,0); - } - } - } - if (YLPos) { - for (int i=(int)ceil(yl[0]/yt);i*yt<=yl[1];i++) { - if (YLPos<=4) { - ToPoint(xl[0],i*yt,p); - int ha=YLPos>=3?0:(YLPos==1?2:1),va=YLPos<=2?0:(YLPos==3?1:2); - DrawText(p,NumText(i*yt,yt),Color[2],ha,va,YLPos>=3?90:0); - } - else if (YLPos==7) { - if (i==0) continue; - ToPoint(0.0,i*yt,p); p.x+=2; - DrawText(p,NumText(i*yt,yt),Color[2],1,0,0); - } - } - } -} -//--------------------------------------------------------------------------- -void TGraph::DrawBox(void) -{ - TCanvas *c=Canvas; - if (Box) { - c->Pen->Color=Color[1]; c->Pen->Style=psSolid; c->Brush->Style=bsClear; - c->Rectangle(X,Y,X+Width-1,Y+Height-1); - } -} -//--------------------------------------------------------------------------- -void TGraph::DrawLabel(void) -{ - if (XLabel!="") { - TPoint p(X+Width/2,Y+Height+(XLPos%2?10:2)); - DrawText(p,XLabel,Color[2],0,2,0); - } - if (YLabel!="") { - TPoint p(X-(YLPos%2?20:2),Y+Height/2); - DrawText(p,YLabel,Color[2],0,1,90); - } - if (Title!="") { - TPoint p(X+Width/2,Y-1); - DrawText(p,Title,Color[2],0,1,0); - } -} -//--------------------------------------------------------------------------- -void TGraph::DrawAxis(int label, int glabel) -{ - TCanvas *c=Canvas; - double xt,yt; - GetTick(xt,yt); - c->Pen->Color=Color[0]; c->Pen->Style=psSolid; - c->Brush->Color=Color[0]; c->Brush->Style=bsSolid; - DrawGrid(xt,yt); - if (xt/XScale<50.0&&XLPos<=2) xt*=XLPos==5?4.0:2.0; - if (yt/YScale<50.0&&YLPos>=3) yt*=2.0; - if (glabel) DrawGridLabel(xt,yt); - DrawBox(); - if (label) DrawLabel(); -} -//--------------------------------------------------------------------------- -void TGraph::RotPoint(TPoint *ps, int n, TPoint pc, int rot, TPoint *pr) -{ - double cos_rot=cos(rot*D2R),sin_rot=sin(rot*D2R); - - for (int i=0;i), - // 11: hscale, 12: vscale, 13: compass) - // rot = rotation angle (deg) - - // if the same mark already drawn, skip it +void TGraph::DrawMark(TPoint p, int mark, TColor color, int size, int rot) { + // mark = mark ( 0: dot (.), 1: circle (o), 2: rect (#), 3: cross (x) + // 4: line (-), 5: plus (+), 10: arrow (->), + // 11: hscale, 12: vscale, 13: compass) + // rot = rotation angle (deg) + + // if the same mark already drawn, skip it #ifdef RTK_DISABLED - if (p.x==p_.x&&p.y==p_.y&&mark==mark_&&color==color_&&size==size_&& - rot==rot_) { - return; - } - p_=p; mark_=mark; color_=color; size_=size; rot_=rot; + if (p.x == p_.x && p.y == p_.y && mark == mark_ && color == color_ && size == size_ && + rot == rot_) { + return; + } + p_ = p; + mark_ = mark; + color_ = color; + size_ = size; + rot_ = rot; #endif - - TCanvas *c=Canvas; - if (size<1) size=1; - int n,s=size/2; - int x1=p.x-s,x2=x1+size+1,y1=p.y-s,y2=y1+size+1; - int xs1[]={-7,0,-7,0},ys1[]={2,0,-2,0}; - int xs2[]={-1,-1,-1,1,1,1},ys2[]={-1,1,0,0,-1,1}; - int xs3[]={3,-4,0,0,0,-8,8},ys3[]={0,5,20,-20,-10,-10,-10}; - int xs4[]={0,0,0,1,-1},ys4[]={1,-1,0,0,0}; - TPoint ps[32],pr[32],pd(0,size/2+12),pt; - c->Pen->Color=color; c->Pen->Style=psSolid; c->Brush->Color=color; - switch (mark) { - case 0: // dot - c->Brush->Style=bsSolid; - c->Ellipse(x1,y1,x2,y2); - return; - case 1: // circle - c->Brush->Style=bsClear; - c->Ellipse(x1,y1,x2,y2); - return; - case 2: // rectangle - c->Brush->Style=bsClear; - c->Rectangle(x1,y1,x2,y2); - return; - case 3: // cross - c->Brush->Style=bsClear; - c->MoveTo(x1,y1); c->LineTo(x2,y2); - c->MoveTo(x1,y2); c->LineTo(x2,y1); - return; - case 4: // line - n=2; - ps[0].x=-size/2; ps[0].y=0; ps[1].x=size/2; ps[1].y=0; - break; - case 5: // plus - n=5; - for (int i=0;iBrush->Style=bsClear; - RotPoint(ps,n,p,rot,pr); - DrawPoly(pr,n,color,0); -} -//--------------------------------------------------------------------------- -void TGraph::DrawMark(double x, double y, int mark, TColor color, int size, - int rot) -{ - TPoint p; - if (ToPoint(x,y,p)) DrawMark(p,mark,color,size,rot); -} -//--------------------------------------------------------------------------- -void TGraph::DrawMark(TPoint p, int mark, TColor color, TColor bgcolor, - int size, int rot) -{ - TPoint p1; - p1=p; p1.x--; DrawMark(p1,mark,bgcolor,size,rot); // draw with hemming - p1=p; p1.x++; DrawMark(p1,mark,bgcolor,size,rot); - p1=p; p1.y--; DrawMark(p1,mark,bgcolor,size,rot); - p1=p; p1.y++; DrawMark(p1,mark,bgcolor,size,rot); - DrawMark(p,mark,color,size,rot); -} -//--------------------------------------------------------------------------- -void TGraph::DrawMark(double x, double y, int mark, TColor color, - TColor bgcolor, int size, int rot) -{ - TPoint p; - if (ToPoint(x,y,p)) DrawMark(p,mark,color,bgcolor,size,rot); -} -//--------------------------------------------------------------------------- -void TGraph::DrawMarks(const double *x, const double *y, const TColor *color, - int n, int mark, int size, int rot) -{ - TPoint p,pp; - for (int i=0;iFont->Name; - c->Font->Name=font; - LOGFONT lf={0}; - lf.lfHeight=c->Font->Height; - lf.lfCharSet=c->Font->Charset; - strcpy(lf.lfFaceName,font.c_str()); - lf.lfEscapement=lf.lfOrientation=rot*10; - c->Font->Handle=CreateFontIndirect(&lf); - TSize off=c->TextExtent(u_str); - TPoint ps,pr; - ps.x=ha==0?(-off.cx+1)/2:(ha==1?3:-off.cx-3); - ps.y=va==0?(off.cy+1)/2:(va==1?off.cy+1:-2); - RotPoint(&ps,1,p,rot,&pr); - c->Brush->Style=bsClear; - c->Font->Color=color; - c->TextOut(pr.x,pr.y,u_str); - c->Font->Name=font_prev; -} -//--------------------------------------------------------------------------- -void TGraph::DrawText(TPoint p, UTF8String str, TColor color, int ha, int va, - int rot) -{ - TCanvas *c=Canvas; - AnsiString font=c->Font->Name; - - DrawText(p,str,color,ha,va,rot,font); -} -//--------------------------------------------------------------------------- -void TGraph::DrawText(double x, double y, UTF8String str, TColor color, - int ha, int va, int rot, AnsiString font) -{ - TPoint p; - ToPoint(x,y,p); - DrawText(p,str,color,ha,va,rot,font); -} -//--------------------------------------------------------------------------- -void TGraph::DrawText(double x, double y, UTF8String str, TColor color, - int ha, int va, int rot) -{ - TPoint p; - ToPoint(x,y,p); - DrawText(p,str,color,ha,va,rot); -} -//--------------------------------------------------------------------------- -void TGraph::DrawText(TPoint p, UTF8String str, TColor color, TColor bgcolor, - int ha, int va, int rot) -{ - TPoint p1; - p1=p; p1.x--; DrawText(p1,str,bgcolor,ha,va,rot); // draw with hemming - p1=p; p1.x++; DrawText(p1,str,bgcolor,ha,va,rot); - p1=p; p1.y--; DrawText(p1,str,bgcolor,ha,va,rot); - p1=p; p1.y++; DrawText(p1,str,bgcolor,ha,va,rot); - DrawText(p,str,color,ha,va,rot); -} -//--------------------------------------------------------------------------- -void TGraph::DrawText(double x, double y, UTF8String str, TColor color, - TColor bgcolor, int ha, int va, int rot) -{ - TPoint p; - ToPoint(x,y,p); - DrawText(p,str,color,bgcolor,ha,va,rot); -} -//--------------------------------------------------------------------------- -void TGraph::DrawCircle(TPoint p, TColor color, int rx, int ry, int style) -{ - TCanvas *c=Canvas; - TPenStyle ps[]={psSolid,psDot,psDash,psDashDot,psDashDotDot}; - int x1=p.x-rx,x2=p.x+rx,y1=p.y-ry,y2=p.y+ry; - c->Pen->Color=color; c->Pen->Style=ps[style]; c->Brush->Style=bsClear; - // Guard against a large radius which for which this implementation - // appears to be very slow and to invoke memory corruption. - if (x2 - x1 >= 32768 || y2 - y1 >= 32768) return; - c->Ellipse(x1,y1,x2,y2); -} -//--------------------------------------------------------------------------- -void TGraph::DrawCircle(double x, double y, TColor color, double rx, - double ry, int style) -{ - TPoint p; - ToPoint(x,y,p); - DrawCircle(p,color,(int)(rx/XScale+0.5),(int)(ry/YScale+0.5),style); -} -//--------------------------------------------------------------------------- -void TGraph::DrawCircles(int label) -{ - TCanvas *c=Canvas; - TPoint p; - double xl[2],yl[2],xt,yt,r[4],rmin=1E99,rmax=0.0; - int imin,imax; - GetLim(xl,yl); - GetTick(xt,yt); - r[0]=sqrt(SQR(xl[0])+SQR(yl[0])); - r[1]=sqrt(SQR(xl[0])+SQR(yl[1])); - r[2]=sqrt(SQR(xl[1])+SQR(yl[0])); - r[3]=sqrt(SQR(xl[1])+SQR(yl[1])); - for (int i=0;i<4;i++) { - if (r[i]rmax) rmax=r[i]; - } - if (xl[0]<=0.0&&xl[1]>=0.0&&yl[0]<=0.0&&yl[1]>=0.0) { - imin=0; - imax=(int)ceil(rmax/xt); - } - else if (xl[0]<=0.0&&xl[1]>=0.0) { - imin=(int)floor((yl[1]<0.0?-yl[1]:yl[0])/xt); - imax=(int)ceil(rmax/xt); - } - else if (yl[0]<=0.0&&yl[1]>=0.0) { - imin=(int)floor((xl[1]<0.0?-xl[1]:xl[0])/xt); - imax=(int)ceil(rmax/xt); - } - else { - imin=(int)floor(rmin/xt); - imax=(int)ceil(rmax/xt); - } - for (int i=imin;i<=imax;i++) { - DrawCircle(0.0,0.0,Color[1],i*xt,i*xt,1); - } - ToPoint(0.0,0.0,p); - c->Pen->Style=psSolid; - c->MoveTo(p.x,Y); c->LineTo(p.x,Y+Height-1); - c->MoveTo(X,p.y); c->LineTo(X+Width-1,p.y); - DrawMark(0.0,0.0,0,Color[1],SIZEORIGIN,0); - if (xt/XScale<50.0) xt*=2.0; - if (yt/YScale<50.0) yt*=2.0; - if (label) DrawGridLabel(xt,yt); - DrawBox(); -} -//--------------------------------------------------------------------------- -int TGraph::OnAxis(TPoint p) -{ - // area code : 5 4 6 - // 1 0 2 - // 9 8 10 - int xmin=X,xmax=X+Width-1,ymin=Y,ymax=Y+Height-1; - return (p.xx==p1->x) return 0; - y=p0->y+(p1->y-p0->y)*(xmin-p0->x)/(p1->x-p0->x); - if (ymin<=y&&y<=ymax) {p0->x=xmin; p0->y=y; return 1;} - } - if (area&2) { // right - if (p0->x==p1->x) return 0; - y=p0->y+(p1->y-p0->y)*(xmax-p0->x)/(p1->x-p0->x); - if (ymin<=y&&y<=ymax) {p0->x=xmax; p0->y=y; return 1;} - } - if (area&4) { // upper - if (p0->y==p1->y) return 0; - x=p0->x+(p1->x-p0->x)*(ymin-p0->y)/(p1->y-p0->y); - if (xmin<=x&&x<=xmax) {p0->x=x; p0->y=ymin; return 1;} - } - if (area&8) { // lower - if (p0->y==p1->y) return 0; - x=p0->x+(p1->x-p0->x)*(ymax-p0->y)/(p1->y-p0->y); - if (xmin<=x&&x<=xmax) {p0->x=x; p0->y=ymax; return 1;} - } - return 0; -} -//--------------------------------------------------------------------------- -void TGraph::DrawPolyline(TPoint *p, int n) -{ - // avoid overflow of points - for (int i=0;iPolyline(p,n-i>30000?30000:n-i-1); - } -} -//--------------------------------------------------------------------------- -void TGraph::DrawPoly(TPoint *p, int n, TColor color, int style) -{ - TCanvas *c=Canvas; - TPenStyle ps[]={psSolid,psDot,psDash,psDashDot,psDashDotDot}; - c->Pen->Color=color; c->Pen->Style=ps[style]; c->Brush->Style=bsClear; - int i,j,area0=11,area1; - for (i=j=0;j30000) return; // # of points overflow - for (int i=0;ixmax) xmax=p[i].x; - if (p[i].yymax) ymax=p[i].y; - } - if (xmaxX+Width-1||ymaxY+Height-1) { - return; - } - c->Pen->Color=color1; - c->Pen->Style=ps[style]; - c->Brush->Style=bsSolid; - c->Brush->Color=color2; - c->Polygon(p,n-1); -} -//--------------------------------------------------------------------------- -void TGraph::DrawPatch(double *x, double *y, int n, TColor color1, - TColor color2, int style) -{ - TPoint *p=new TPoint[n]; - for (int i=0;iPen->Color=color1; c->Brush->Style=bsClear; - AnsiString s,dir[]={"N","E","S","W"}; - TPoint ps; - int r=size/2; - for (int el=0;el<90;el+=15) { - int ys=r-r*el/90; - c->Pen->Style=el==0?psSolid:psDot; - c->Ellipse(p.x-ys,p.y-ys,p.x+ys,p.y+ys); - if (el<=0) continue; - ps.x=p.x; ps.y=p.y-ys; - s.sprintf("%d",el); - DrawText(ps,s,color2,1,0,0); - } - c->Pen->Style=psDot; c->Font->Color=color2; - for (int az=0,i=0;az<360;az+=30) { - ps.x=p.x+(int)( r*sin(az*D2R)+0.5); - ps.y=p.y+(int)(-r*cos(az*D2R)+0.5); - c->MoveTo(p.x,p.y); c->LineTo(ps.x,ps.y); - ps.x+= 3*sin(az*D2R); - ps.y+=-3*cos(az*D2R); - s.sprintf("%d",az); if (!(az%90)) s=dir[i++]; - DrawText(ps,s,color2,0,1,-az); - } -} -//--------------------------------------------------------------------------- -void TGraph::DrawSkyPlot(double x, double y, TColor color1, TColor color2, - double size) -{ - TPoint p; - ToPoint(x,y,p); - DrawSkyPlot(p,color1,color2,size/XScale); -} -//--------------------------------------------------------------------------- -void TGraph::DrawSkyPlot(TPoint p, TColor color1, TColor color2, - TColor bgcolor, int size) -{ - TCanvas *c=Canvas; - c->Pen->Color=color1; c->Brush->Style=bsClear; - AnsiString s,dir[]={"N","E","S","W"}; - TPoint ps; - int n,r=size/2; - - for (int el=0;el<90;el+=15) { - int ys=r-r*el/90; - c->Pen->Style=el==0?psSolid:psDot; - c->Ellipse(p.x-ys,p.y-ys,p.x+ys,p.y+ys); - if (el<=0) continue; - ps.x=p.x; ps.y=p.y-ys; - s.sprintf("%d",el); - DrawText(ps,s,color2,bgcolor,1,0,0); - } - c->Pen->Style=psDot; c->Font->Color=color2; - for (int az=0,i=0;az<360;az+=30) { - ps.x=p.x+(int)( r*sin(az*D2R)+0.5); - ps.y=p.y+(int)(-r*cos(az*D2R)+0.5); - c->MoveTo(p.x,p.y); c->LineTo(ps.x,ps.y); - ps.x+= 3*sin(az*D2R); - ps.y+=-3*cos(az*D2R); - s.sprintf("%d",az); if (!(az%90)) s=dir[i++]; - DrawText(ps,s,color2,bgcolor,0,1,-az); - } -} -//--------------------------------------------------------------------------- -void TGraph::DrawSkyPlot(double x, double y, TColor color1, TColor color2, - TColor bgcolor, double size) -{ - TPoint p; - ToPoint(x,y,p); - DrawSkyPlot(p,color1,color2,bgcolor,size/XScale); + + TCanvas *c = Canvas; + if (size < 1) size = 1; + int n, s = size / 2; + int x1 = p.x - s, x2 = x1 + size + 1, y1 = p.y - s, y2 = y1 + size + 1; + int xs1[] = {-7, 0, -7, 0}, ys1[] = {2, 0, -2, 0}; + int xs2[] = {-1, -1, -1, 1, 1, 1}, ys2[] = {-1, 1, 0, 0, -1, 1}; + int xs3[] = {3, -4, 0, 0, 0, -8, 8}, ys3[] = {0, 5, 20, -20, -10, -10, -10}; + int xs4[] = {0, 0, 0, 1, -1}, ys4[] = {1, -1, 0, 0, 0}; + TPoint ps[32], pr[32], pd(0, size / 2 + 12), pt; + c->Pen->Color = color; + c->Pen->Style = psSolid; + c->Brush->Color = color; + switch (mark) { + case 0: // dot + c->Brush->Style = bsSolid; + c->Ellipse(x1, y1, x2, y2); + return; + case 1: // circle + c->Brush->Style = bsClear; + c->Ellipse(x1, y1, x2, y2); + return; + case 2: // rectangle + c->Brush->Style = bsClear; + c->Rectangle(x1, y1, x2, y2); + return; + case 3: // cross + c->Brush->Style = bsClear; + c->MoveTo(x1, y1); + c->LineTo(x2, y2); + c->MoveTo(x1, y2); + c->LineTo(x2, y1); + return; + case 4: // line + n = 2; + ps[0].x = -size / 2; + ps[0].y = 0; + ps[1].x = size / 2; + ps[1].y = 0; + break; + case 5: // plus + n = 5; + for (int i = 0; i < n; i++) { + ps[i].x = xs4[i] * s; + ps[i].y = ys4[i] * s; + } + break; + case 10: // arrow + n = 6; + ps[0].x = -size / 2; + ps[0].y = 0; + ps[1].x = size / 2; + ps[1].y = 0; + for (int i = 2; i < n; i++) { + ps[i].x = size / 2 + xs1[i - 2]; + ps[i].y = ys1[i - 2]; + } + break; + case 11: // hscale + case 12: // vscale + n = 6; + for (int i = 0; i < n; i++) { + int x = xs2[i] * size / 2, y = ys2[i] * 5; + ps[i].x = mark == 11 ? x : y; + ps[i].y = mark == 11 ? y : x; + } + break; + case 13: // compass + n = 7; + for (int i = 0; i < n; i++) { + ps[i].x = xs3[i] * size / 40; + ps[i].y = ys3[i] * size / 40; + } + RotPoint(&pd, 1, p, rot, &pt); + DrawText(pt, "N", color, 0, 0, rot); + break; + default: + return; + } + c->Brush->Style = bsClear; + RotPoint(ps, n, p, rot, pr); + DrawPoly(pr, n, color, 0); +} +//--------------------------------------------------------------------------- +void TGraph::DrawMark(double x, double y, int mark, TColor color, int size, int rot) { + TPoint p; + if (ToPoint(x, y, p)) DrawMark(p, mark, color, size, rot); +} +//--------------------------------------------------------------------------- +void TGraph::DrawMark(TPoint p, int mark, TColor color, TColor bgcolor, int size, int rot) { + TPoint p1; + p1 = p; + p1.x--; + DrawMark(p1, mark, bgcolor, size, rot); // draw with hemming + p1 = p; + p1.x++; + DrawMark(p1, mark, bgcolor, size, rot); + p1 = p; + p1.y--; + DrawMark(p1, mark, bgcolor, size, rot); + p1 = p; + p1.y++; + DrawMark(p1, mark, bgcolor, size, rot); + DrawMark(p, mark, color, size, rot); +} +//--------------------------------------------------------------------------- +void TGraph::DrawMark(double x, double y, int mark, TColor color, TColor bgcolor, int size, + int rot) { + TPoint p; + if (ToPoint(x, y, p)) DrawMark(p, mark, color, bgcolor, size, rot); +} +//--------------------------------------------------------------------------- +void TGraph::DrawMarks(const double *x, const double *y, const TColor *color, int n, int mark, + int size, int rot) { + TPoint p, pp; + for (int i = 0; i < n; i++) { + if (!ToPoint(x[i], y[i], p) || (pp.x == p.x && pp.y == p.y)) continue; + DrawMark(p, mark, color[i], size, rot); + pp = p; + } +} +//--------------------------------------------------------------------------- +void TGraph::DrawText(TPoint p, UTF8String str, TColor color, int ha, int va, int rot, + AnsiString font) { + // str = UTF-8 string + // ha = horizontal alignment (0: center, 1: left, 2: right) + // va = vertical alignment (0: center, 1: bottom, 2: top ) + // rot = rotation angle (deg) + + AnsiString font_prev; + UnicodeString u_str(str); + + TCanvas *c = Canvas; + font_prev = c->Font->Name; + c->Font->Name = font; + LOGFONT lf = {0}; + lf.lfHeight = c->Font->Height; + lf.lfCharSet = c->Font->Charset; + strcpy(lf.lfFaceName, font.c_str()); + lf.lfEscapement = lf.lfOrientation = rot * 10; + c->Font->Handle = CreateFontIndirect(&lf); + TSize off = c->TextExtent(u_str); + TPoint ps, pr; + ps.x = ha == 0 ? (-off.cx + 1) / 2 : (ha == 1 ? 3 : -off.cx - 3); + ps.y = va == 0 ? (off.cy + 1) / 2 : (va == 1 ? off.cy + 1 : -2); + RotPoint(&ps, 1, p, rot, &pr); + c->Brush->Style = bsClear; + c->Font->Color = color; + c->TextOut(pr.x, pr.y, u_str); + c->Font->Name = font_prev; +} +//--------------------------------------------------------------------------- +void TGraph::DrawText(TPoint p, UTF8String str, TColor color, int ha, int va, int rot) { + TCanvas *c = Canvas; + AnsiString font = c->Font->Name; + + DrawText(p, str, color, ha, va, rot, font); +} +//--------------------------------------------------------------------------- +void TGraph::DrawText(double x, double y, UTF8String str, TColor color, int ha, int va, int rot, + AnsiString font) { + TPoint p; + ToPoint(x, y, p); + DrawText(p, str, color, ha, va, rot, font); +} +//--------------------------------------------------------------------------- +void TGraph::DrawText(double x, double y, UTF8String str, TColor color, int ha, int va, int rot) { + TPoint p; + ToPoint(x, y, p); + DrawText(p, str, color, ha, va, rot); +} +//--------------------------------------------------------------------------- +void TGraph::DrawText(TPoint p, UTF8String str, TColor color, TColor bgcolor, int ha, int va, + int rot) { + TPoint p1; + p1 = p; + p1.x--; + DrawText(p1, str, bgcolor, ha, va, rot); // draw with hemming + p1 = p; + p1.x++; + DrawText(p1, str, bgcolor, ha, va, rot); + p1 = p; + p1.y--; + DrawText(p1, str, bgcolor, ha, va, rot); + p1 = p; + p1.y++; + DrawText(p1, str, bgcolor, ha, va, rot); + DrawText(p, str, color, ha, va, rot); +} +//--------------------------------------------------------------------------- +void TGraph::DrawText(double x, double y, UTF8String str, TColor color, TColor bgcolor, int ha, + int va, int rot) { + TPoint p; + ToPoint(x, y, p); + DrawText(p, str, color, bgcolor, ha, va, rot); +} +//--------------------------------------------------------------------------- +void TGraph::DrawCircle(TPoint p, TColor color, int rx, int ry, int style) { + TCanvas *c = Canvas; + TPenStyle ps[] = {psSolid, psDot, psDash, psDashDot, psDashDotDot}; + int x1 = p.x - rx, x2 = p.x + rx, y1 = p.y - ry, y2 = p.y + ry; + c->Pen->Color = color; + c->Pen->Style = ps[style]; + c->Brush->Style = bsClear; + // Guard against a large radius which for which this implementation + // appears to be very slow and to invoke memory corruption. + if (x2 - x1 >= 32768 || y2 - y1 >= 32768) return; + c->Ellipse(x1, y1, x2, y2); +} +//--------------------------------------------------------------------------- +void TGraph::DrawCircle(double x, double y, TColor color, double rx, double ry, int style) { + TPoint p; + ToPoint(x, y, p); + DrawCircle(p, color, (int)(rx / XScale + 0.5), (int)(ry / YScale + 0.5), style); +} +//--------------------------------------------------------------------------- +void TGraph::DrawCircles(int label) { + TCanvas *c = Canvas; + TPoint p; + double xl[2], yl[2], xt, yt, r[4], rmin = 1E99, rmax = 0.0; + int imin, imax; + GetLim(xl, yl); + GetTick(xt, yt); + r[0] = sqrt(SQR(xl[0]) + SQR(yl[0])); + r[1] = sqrt(SQR(xl[0]) + SQR(yl[1])); + r[2] = sqrt(SQR(xl[1]) + SQR(yl[0])); + r[3] = sqrt(SQR(xl[1]) + SQR(yl[1])); + for (int i = 0; i < 4; i++) { + if (r[i] < rmin) rmin = r[i]; + if (r[i] > rmax) rmax = r[i]; + } + if (xl[0] <= 0.0 && xl[1] >= 0.0 && yl[0] <= 0.0 && yl[1] >= 0.0) { + imin = 0; + imax = (int)ceil(rmax / xt); + } else if (xl[0] <= 0.0 && xl[1] >= 0.0) { + imin = (int)floor((yl[1] < 0.0 ? -yl[1] : yl[0]) / xt); + imax = (int)ceil(rmax / xt); + } else if (yl[0] <= 0.0 && yl[1] >= 0.0) { + imin = (int)floor((xl[1] < 0.0 ? -xl[1] : xl[0]) / xt); + imax = (int)ceil(rmax / xt); + } else { + imin = (int)floor(rmin / xt); + imax = (int)ceil(rmax / xt); + } + for (int i = imin; i <= imax; i++) { + DrawCircle(0.0, 0.0, Color[1], i * xt, i * xt, 1); + } + ToPoint(0.0, 0.0, p); + c->Pen->Style = psSolid; + c->MoveTo(p.x, Y); + c->LineTo(p.x, Y + Height - 1); + c->MoveTo(X, p.y); + c->LineTo(X + Width - 1, p.y); + DrawMark(0.0, 0.0, 0, Color[1], SIZEORIGIN, 0); + if (xt / XScale < 50.0) xt *= 2.0; + if (yt / YScale < 50.0) yt *= 2.0; + if (label) DrawGridLabel(xt, yt); + DrawBox(); +} +//--------------------------------------------------------------------------- +int TGraph::OnAxis(TPoint p) { + // area code : 5 4 6 + // 1 0 2 + // 9 8 10 + int xmin = X, xmax = X + Width - 1, ymin = Y, ymax = Y + Height - 1; + return (p.x < xmin ? 1 : (p.x <= xmax ? 0 : 2)) + (p.y < ymin ? 4 : (p.y <= ymax ? 0 : 8)); +} +//--------------------------------------------------------------------------- +int TGraph::ClipPoint(TPoint *p0, int area, TPoint *p1) { + int x, y, xmin = X, xmax = X + Width - 1, ymin = Y, ymax = Y + Height - 1; + if (area & 1) { // left + if (p0->x == p1->x) return 0; + y = p0->y + (p1->y - p0->y) * (xmin - p0->x) / (p1->x - p0->x); + if (ymin <= y && y <= ymax) { + p0->x = xmin; + p0->y = y; + return 1; + } + } + if (area & 2) { // right + if (p0->x == p1->x) return 0; + y = p0->y + (p1->y - p0->y) * (xmax - p0->x) / (p1->x - p0->x); + if (ymin <= y && y <= ymax) { + p0->x = xmax; + p0->y = y; + return 1; + } + } + if (area & 4) { // upper + if (p0->y == p1->y) return 0; + x = p0->x + (p1->x - p0->x) * (ymin - p0->y) / (p1->y - p0->y); + if (xmin <= x && x <= xmax) { + p0->x = x; + p0->y = ymin; + return 1; + } + } + if (area & 8) { // lower + if (p0->y == p1->y) return 0; + x = p0->x + (p1->x - p0->x) * (ymax - p0->y) / (p1->y - p0->y); + if (xmin <= x && x <= xmax) { + p0->x = x; + p0->y = ymax; + return 1; + } + } + return 0; +} +//--------------------------------------------------------------------------- +void TGraph::DrawPolyline(TPoint *p, int n) { + // avoid overflow of points + for (int i = 0; i < n - 1; i += 30000, p += 30000) { + Canvas->Polyline(p, n - i > 30000 ? 30000 : n - i - 1); + } +} +//--------------------------------------------------------------------------- +void TGraph::DrawPoly(TPoint *p, int n, TColor color, int style) { + TCanvas *c = Canvas; + TPenStyle ps[] = {psSolid, psDot, psDash, psDashDot, psDashDotDot}; + c->Pen->Color = color; + c->Pen->Style = ps[style]; + c->Brush->Style = bsClear; + int i, j, area0 = 11, area1; + for (i = j = 0; j < n; j++, area0 = area1) { + if ((area1 = OnAxis(p[j])) == area0) continue; + if (!area1) + i = j; + else if (!area0) + DrawPolyline(p + i, j - i); + if (j <= 0 || (area0 & area1)) continue; + TPoint pc[2] = {p[j - 1], p[j]}; + if (area0 && !ClipPoint(pc, area0, p + j)) continue; + if (area1 && !ClipPoint(pc + 1, area1, p + j - 1)) continue; + DrawPolyline(pc, 2); + } + if (!area0) DrawPolyline(p + i, j - i); +} +//--------------------------------------------------------------------------- +void TGraph::DrawPoly(double *x, double *y, int n, TColor color, int style) { + TPoint *p = new TPoint[n]; + int m = 0; + for (int i = 0; i < n; i++) { + ToPoint(x[i], y[i], p[m]); + if (m == 0 || p[m - 1].x != p[m].x || p[m - 1].y != p[m].y) m++; + } + DrawPoly(p, m, color, style); + delete[] p; +} +//--------------------------------------------------------------------------- +void TGraph::DrawPatch(TPoint *p, int n, TColor color1, TColor color2, int style) { + TCanvas *c = Canvas; + TPenStyle ps[] = {psSolid, psDot, psDash, psDashDot, psDashDotDot}; + int i, xmin = 1000000, xmax = 0, ymin = 1000000, ymax = 0; + + if (n > 30000) return; // # of points overflow + for (int i = 0; i < n - 1; i++) { + if (p[i].x < xmin) xmin = p[i].x; + if (p[i].x > xmax) xmax = p[i].x; + if (p[i].y < ymin) ymin = p[i].y; + if (p[i].y > ymax) ymax = p[i].y; + } + if (xmax < X || xmin > X + Width - 1 || ymax < Y || ymin > Y + Height - 1) { + return; + } + c->Pen->Color = color1; + c->Pen->Style = ps[style]; + c->Brush->Style = bsSolid; + c->Brush->Color = color2; + c->Polygon(p, n - 1); +} +//--------------------------------------------------------------------------- +void TGraph::DrawPatch(double *x, double *y, int n, TColor color1, TColor color2, int style) { + TPoint *p = new TPoint[n]; + for (int i = 0; i < n; i++) { + ToPoint(x[i], y[i], p[i]); + } + DrawPatch(p, n, color1, color2, style); + delete[] p; +} +//--------------------------------------------------------------------------- +void TGraph::DrawSkyPlot(TPoint p, TColor color1, TColor color2, int size) { + TCanvas *c = Canvas; + c->Pen->Color = color1; + c->Brush->Style = bsClear; + AnsiString s, dir[] = {"N", "E", "S", "W"}; + TPoint ps; + int r = size / 2; + for (int el = 0; el < 90; el += 15) { + int ys = r - r * el / 90; + c->Pen->Style = el == 0 ? psSolid : psDot; + c->Ellipse(p.x - ys, p.y - ys, p.x + ys, p.y + ys); + if (el <= 0) continue; + ps.x = p.x; + ps.y = p.y - ys; + s.sprintf("%d", el); + DrawText(ps, s, color2, 1, 0, 0); + } + c->Pen->Style = psDot; + c->Font->Color = color2; + for (int az = 0, i = 0; az < 360; az += 30) { + ps.x = p.x + (int)(r * sin(az * D2R) + 0.5); + ps.y = p.y + (int)(-r * cos(az * D2R) + 0.5); + c->MoveTo(p.x, p.y); + c->LineTo(ps.x, ps.y); + ps.x += 3 * sin(az * D2R); + ps.y += -3 * cos(az * D2R); + s.sprintf("%d", az); + if (!(az % 90)) s = dir[i++]; + DrawText(ps, s, color2, 0, 1, -az); + } +} +//--------------------------------------------------------------------------- +void TGraph::DrawSkyPlot(double x, double y, TColor color1, TColor color2, double size) { + TPoint p; + ToPoint(x, y, p); + DrawSkyPlot(p, color1, color2, size / XScale); +} +//--------------------------------------------------------------------------- +void TGraph::DrawSkyPlot(TPoint p, TColor color1, TColor color2, TColor bgcolor, int size) { + TCanvas *c = Canvas; + c->Pen->Color = color1; + c->Brush->Style = bsClear; + AnsiString s, dir[] = {"N", "E", "S", "W"}; + TPoint ps; + int n, r = size / 2; + + for (int el = 0; el < 90; el += 15) { + int ys = r - r * el / 90; + c->Pen->Style = el == 0 ? psSolid : psDot; + c->Ellipse(p.x - ys, p.y - ys, p.x + ys, p.y + ys); + if (el <= 0) continue; + ps.x = p.x; + ps.y = p.y - ys; + s.sprintf("%d", el); + DrawText(ps, s, color2, bgcolor, 1, 0, 0); + } + c->Pen->Style = psDot; + c->Font->Color = color2; + for (int az = 0, i = 0; az < 360; az += 30) { + ps.x = p.x + (int)(r * sin(az * D2R) + 0.5); + ps.y = p.y + (int)(-r * cos(az * D2R) + 0.5); + c->MoveTo(p.x, p.y); + c->LineTo(ps.x, ps.y); + ps.x += 3 * sin(az * D2R); + ps.y += -3 * cos(az * D2R); + s.sprintf("%d", az); + if (!(az % 90)) s = dir[i++]; + DrawText(ps, s, color2, bgcolor, 0, 1, -az); + } +} +//--------------------------------------------------------------------------- +void TGraph::DrawSkyPlot(double x, double y, TColor color1, TColor color2, TColor bgcolor, + double size) { + TPoint p; + ToPoint(x, y, p); + DrawSkyPlot(p, color1, color2, bgcolor, size / XScale); } //--------------------------------------------------------------------------- diff --git a/app/winapp/appcmn/graph.h b/app/winapp/appcmn/graph.h index 2a45c8122..9540a68dc 100644 --- a/app/winapp/appcmn/graph.h +++ b/app/winapp/appcmn/graph.h @@ -4,84 +4,78 @@ //--------------------------------------------------------------------------- #include #include -#include #include +#include -class TGraph // graph class +class TGraph // graph class { -private: - TCanvas *Canvas; - int X,Y,Width,Height; - double XCent,YCent,XScale,YScale,XTick,YTick; - double AutoTick(double scale); - double AutoTickTime(double scale); - void DrawBox(void); - void DrawLabel(void); - void DrawGrid(double xt, double yt); - void DrawGridLabel(double xt, double yt); - void RotPoint(TPoint *ps, int n, TPoint pc, int rot, TPoint *pr); - int ClipPoint(TPoint *p0, int area, TPoint *p1); - TPoint p_; - int mark_,size_,rot_; - TColor color_; -public: - int Box,Fit,XGrid,YGrid,XLPos,YLPos,Week; - UTF8String Title,XLabel,YLabel; - TColor Color[3]; - TGraph(TPaintBox *parent); - TGraph(TImage *parent); - int IsInArea(TPoint &p); - int ToPoint(double x, double y, TPoint &p); - int OnAxis(TPoint p); - AnsiString NumText(double x, double dx); - AnsiString TimeText(double x, double dx); - void ToPos(TPoint p, double &x, double &y); - void SetSize(int width, int height); - void SetPos(TPoint p1, TPoint p2); - void GetPos(TPoint &p1, TPoint &p2); - void SetCent(double x, double y); - void GetCent(double &x, double &y); - void SetRight(double x, double y); - void GetRight(double &x, double &y); - void SetScale(double xs, double ys); - void GetScale(double &xs, double &ys); - void SetLim(const double *xl, const double *yl); - void GetLim(double *xl, double *yl); - void SetTick(double xt, double yt); - void GetTick(double &xt, double &yt); - void DrawAxis(int label, int glabel); - void DrawMark(TPoint p, int mark, TColor color, int size, int rot); - void DrawMark(double x, double y, int mark, TColor color, int size, int rot); - void DrawMark(TPoint p, int mark, TColor color, TColor bgcolor, int size, - int rot); - void DrawMark(double x, double y, int mark, TColor color, TColor bgcolor, - int size, int rot); - void DrawMarks(const double *x, const double *y, const TColor *color, int n, - int mark, int size, int rot); - void DrawCircle(TPoint p, TColor color, int rx, int ry, int style); - void DrawCircle(double x, double y, TColor color, double rx, double ry, int style); - void DrawCircles(int label); - void DrawText(double x, double y, UTF8String str, TColor color, int ha, - int va, int rot); - void DrawText(double x, double y, UTF8String str, TColor color, int ha, - int va, int rot, AnsiString font); - void DrawText(TPoint p, UTF8String str, TColor color, int ha, int va, - int rot); - void DrawText(TPoint p, UTF8String str, TColor color, int ha, int va, - int rot, AnsiString font); - void DrawText(double x, double y, UTF8String str, TColor color, TColor bgcolor, - int ha, int va, int rot); - void DrawText(TPoint p, UTF8String str, TColor color, TColor bgcolor, - int ha, int va, int rot); - void DrawPoly(TPoint *p, int n, TColor color, int style); - void DrawPoly(double *x, double *y, int n, TColor color, int style); - void DrawPolyline(TPoint *p, int n); - void DrawPatch(TPoint *p, int n, TColor color1, TColor color2, int style); - void DrawPatch(double *x, double *y, int n, TColor color1, TColor color2, int style); - void DrawSkyPlot(TPoint p, TColor color1, TColor color2, int size); - void DrawSkyPlot(double x, double y, TColor color1, TColor color2, double size); - void DrawSkyPlot(TPoint p, TColor color1, TColor color2, TColor bgcolor, int size); - void DrawSkyPlot(double x, double y, TColor color1, TColor color2, TColor bgcolor, - double size); + private: + TCanvas *Canvas; + int X, Y, Width, Height; + double XCent, YCent, XScale, YScale, XTick, YTick; + double AutoTick(double scale); + double AutoTickTime(double scale); + void DrawBox(void); + void DrawLabel(void); + void DrawGrid(double xt, double yt); + void DrawGridLabel(double xt, double yt); + void RotPoint(TPoint *ps, int n, TPoint pc, int rot, TPoint *pr); + int ClipPoint(TPoint *p0, int area, TPoint *p1); + TPoint p_; + int mark_, size_, rot_; + TColor color_; + + public: + int Box, Fit, XGrid, YGrid, XLPos, YLPos, Week; + UTF8String Title, XLabel, YLabel; + TColor Color[3]; + TGraph(TPaintBox *parent); + TGraph(TImage *parent); + int IsInArea(TPoint &p); + int ToPoint(double x, double y, TPoint &p); + int OnAxis(TPoint p); + AnsiString NumText(double x, double dx); + AnsiString TimeText(double x, double dx); + void ToPos(TPoint p, double &x, double &y); + void SetSize(int width, int height); + void SetPos(TPoint p1, TPoint p2); + void GetPos(TPoint &p1, TPoint &p2); + void SetCent(double x, double y); + void GetCent(double &x, double &y); + void SetRight(double x, double y); + void GetRight(double &x, double &y); + void SetScale(double xs, double ys); + void GetScale(double &xs, double &ys); + void SetLim(const double *xl, const double *yl); + void GetLim(double *xl, double *yl); + void SetTick(double xt, double yt); + void GetTick(double &xt, double &yt); + void DrawAxis(int label, int glabel); + void DrawMark(TPoint p, int mark, TColor color, int size, int rot); + void DrawMark(double x, double y, int mark, TColor color, int size, int rot); + void DrawMark(TPoint p, int mark, TColor color, TColor bgcolor, int size, int rot); + void DrawMark(double x, double y, int mark, TColor color, TColor bgcolor, int size, int rot); + void DrawMarks(const double *x, const double *y, const TColor *color, int n, int mark, int size, + int rot); + void DrawCircle(TPoint p, TColor color, int rx, int ry, int style); + void DrawCircle(double x, double y, TColor color, double rx, double ry, int style); + void DrawCircles(int label); + void DrawText(double x, double y, UTF8String str, TColor color, int ha, int va, int rot); + void DrawText(double x, double y, UTF8String str, TColor color, int ha, int va, int rot, + AnsiString font); + void DrawText(TPoint p, UTF8String str, TColor color, int ha, int va, int rot); + void DrawText(TPoint p, UTF8String str, TColor color, int ha, int va, int rot, AnsiString font); + void DrawText(double x, double y, UTF8String str, TColor color, TColor bgcolor, int ha, int va, + int rot); + void DrawText(TPoint p, UTF8String str, TColor color, TColor bgcolor, int ha, int va, int rot); + void DrawPoly(TPoint *p, int n, TColor color, int style); + void DrawPoly(double *x, double *y, int n, TColor color, int style); + void DrawPolyline(TPoint *p, int n); + void DrawPatch(TPoint *p, int n, TColor color1, TColor color2, int style); + void DrawPatch(double *x, double *y, int n, TColor color1, TColor color2, int style); + void DrawSkyPlot(TPoint p, TColor color1, TColor color2, int size); + void DrawSkyPlot(double x, double y, TColor color1, TColor color2, double size); + void DrawSkyPlot(TPoint p, TColor color1, TColor color2, TColor bgcolor, int size); + void DrawSkyPlot(double x, double y, TColor color1, TColor color2, TColor bgcolor, double size); }; #endif diff --git a/app/winapp/appcmn/keydlg.cpp b/app/winapp/appcmn/keydlg.cpp index fb20d23c3..837843022 100644 --- a/app/winapp/appcmn/keydlg.cpp +++ b/app/winapp/appcmn/keydlg.cpp @@ -8,37 +8,28 @@ #pragma resource "*.dfm" TKeyDialog *KeyDialog; //--------------------------------------------------------------------------- -__fastcall TKeyDialog::TKeyDialog(TComponent* Owner) - : TForm(Owner) -{ - Flag=0; -} +__fastcall TKeyDialog::TKeyDialog(TComponent *Owner) : TForm(Owner) { Flag = 0; } //--------------------------------------------------------------------------- -void __fastcall TKeyDialog::FormShow(TObject *Sender) -{ - Label10->Visible=Flag!=3; - Label21->Visible=Flag!=3; - Label23->Visible=Flag!=3; - Label24->Visible=Flag!=3; - Label25->Visible=Flag!=3; - Label26->Visible=Flag!=3; - Label27->Visible=Flag!=3; - Label28->Visible=Flag!=3; - Label29->Visible=Flag>=1; - Label30->Visible=Flag>=1; - Label31->Visible=Flag==2; - Label32->Visible=Flag==2; - Label33->Visible=Flag==3; - Label34->Visible=Flag==3; - Label35->Visible=Flag==3; - Label36->Visible=Flag==3; - Label37->Visible=Flag==3; - Label38->Visible=Flag==3; +void __fastcall TKeyDialog::FormShow(TObject *Sender) { + Label10->Visible = Flag != 3; + Label21->Visible = Flag != 3; + Label23->Visible = Flag != 3; + Label24->Visible = Flag != 3; + Label25->Visible = Flag != 3; + Label26->Visible = Flag != 3; + Label27->Visible = Flag != 3; + Label28->Visible = Flag != 3; + Label29->Visible = Flag >= 1; + Label30->Visible = Flag >= 1; + Label31->Visible = Flag == 2; + Label32->Visible = Flag == 2; + Label33->Visible = Flag == 3; + Label34->Visible = Flag == 3; + Label35->Visible = Flag == 3; + Label36->Visible = Flag == 3; + Label37->Visible = Flag == 3; + Label38->Visible = Flag == 3; } //--------------------------------------------------------------------------- -void __fastcall TKeyDialog::BtnOkClick(TObject *Sender) -{ - Close(); -} +void __fastcall TKeyDialog::BtnOkClick(TObject *Sender) { Close(); } //--------------------------------------------------------------------------- - diff --git a/app/winapp/appcmn/keydlg.h b/app/winapp/appcmn/keydlg.h index b68996d47..4bcde8eb1 100644 --- a/app/winapp/appcmn/keydlg.h +++ b/app/winapp/appcmn/keydlg.h @@ -5,57 +5,56 @@ //--------------------------------------------------------------------------- #include #include -#include #include +#include //--------------------------------------------------------------------------- -class TKeyDialog : public TForm -{ -__published: - TLabel *Label1; - TLabel *Label2; - TLabel *Label3; - TLabel *Label4; - TLabel *Label5; - TLabel *Label6; - TLabel *Label7; - TLabel *Label8; - TLabel *Label9; - TLabel *Label10; - TLabel *Label11; - TLabel *Label12; - TLabel *Label13; - TLabel *Label14; - TLabel *Label15; - TLabel *Label16; - TLabel *Label17; - TLabel *Label18; - TLabel *Label19; - TLabel *Label20; - TLabel *Label21; - TLabel *Label22; - TButton *BtnOk; - TLabel *Label23; - TLabel *Label24; - TLabel *Label25; - TLabel *Label26; - TLabel *Label27; - TLabel *Label28; - TLabel *Label29; - TLabel *Label30; - TLabel *Label31; - TLabel *Label32; - TLabel *Label33; - TLabel *Label34; - TLabel *Label35; - TLabel *Label36; - TLabel *Label37; - TLabel *Label38; - void __fastcall BtnOkClick(TObject *Sender); - void __fastcall FormShow(TObject *Sender); -private: -public: - int Flag; - __fastcall TKeyDialog(TComponent* Owner); +class TKeyDialog : public TForm { + __published : TLabel *Label1; + TLabel *Label2; + TLabel *Label3; + TLabel *Label4; + TLabel *Label5; + TLabel *Label6; + TLabel *Label7; + TLabel *Label8; + TLabel *Label9; + TLabel *Label10; + TLabel *Label11; + TLabel *Label12; + TLabel *Label13; + TLabel *Label14; + TLabel *Label15; + TLabel *Label16; + TLabel *Label17; + TLabel *Label18; + TLabel *Label19; + TLabel *Label20; + TLabel *Label21; + TLabel *Label22; + TButton *BtnOk; + TLabel *Label23; + TLabel *Label24; + TLabel *Label25; + TLabel *Label26; + TLabel *Label27; + TLabel *Label28; + TLabel *Label29; + TLabel *Label30; + TLabel *Label31; + TLabel *Label32; + TLabel *Label33; + TLabel *Label34; + TLabel *Label35; + TLabel *Label36; + TLabel *Label37; + TLabel *Label38; + void __fastcall BtnOkClick(TObject *Sender); + void __fastcall FormShow(TObject *Sender); + + private: + public: + int Flag; + __fastcall TKeyDialog(TComponent *Owner); }; //--------------------------------------------------------------------------- extern PACKAGE TKeyDialog *KeyDialog; diff --git a/app/winapp/appcmn/maskoptdlg.cpp b/app/winapp/appcmn/maskoptdlg.cpp index 2be4e512b..e3622ce86 100644 --- a/app/winapp/appcmn/maskoptdlg.cpp +++ b/app/winapp/appcmn/maskoptdlg.cpp @@ -8,64 +8,56 @@ #pragma resource "*.dfm" TMaskOptDialog *MaskOptDialog; //--------------------------------------------------------------------------- -__fastcall TMaskOptDialog::TMaskOptDialog(TComponent* Owner) - : TForm(Owner) -{ - Mask.ena[0]=0; - Mask.ena[1]=0; - for (int i=0;i<4;i++) for (int j=0;j<9;j++) { - Mask.mask[i][j]=35.0; - } +__fastcall TMaskOptDialog::TMaskOptDialog(TComponent *Owner) : TForm(Owner) { + Mask.ena[0] = 0; + Mask.ena[1] = 0; + for (int i = 0; i < 4; i++) + for (int j = 0; j < 9; j++) { + Mask.mask[i][j] = 35.0; + } } //--------------------------------------------------------------------------- -void __fastcall TMaskOptDialog::FormShow(TObject *Sender) -{ - TEdit *mask[][9]={ - {Mask_1_1,Mask_1_2,Mask_1_3,Mask_1_4,Mask_1_5,Mask_1_6,Mask_1_7,Mask_1_8,Mask_1_9}, - {Mask_2_1,Mask_2_2,Mask_2_3,Mask_2_4,Mask_2_5,Mask_2_6,Mask_2_7,Mask_2_8,Mask_2_9}, - {Mask_3_1,Mask_3_2,Mask_3_3,Mask_3_4,Mask_3_5,Mask_3_6,Mask_3_7,Mask_3_8,Mask_3_9}, - {Mask_4_1,Mask_4_2,Mask_4_3,Mask_4_4,Mask_4_5,Mask_4_6,Mask_4_7,Mask_4_8,Mask_4_9} - }; - AnsiString s; - MaskEna1->Checked=Mask.ena[0]; - MaskEna2->Checked=Mask.ena[1]; - for (int i=0;i<4;i++) for (int j=0;j<9;j++) { - mask[i][j]->Text=s.sprintf("%.0f",Mask.mask[i][j]); - } - UpdateEnable(); +void __fastcall TMaskOptDialog::FormShow(TObject *Sender) { + TEdit *mask[][9] = { + {Mask_1_1, Mask_1_2, Mask_1_3, Mask_1_4, Mask_1_5, Mask_1_6, Mask_1_7, Mask_1_8, Mask_1_9}, + {Mask_2_1, Mask_2_2, Mask_2_3, Mask_2_4, Mask_2_5, Mask_2_6, Mask_2_7, Mask_2_8, Mask_2_9}, + {Mask_3_1, Mask_3_2, Mask_3_3, Mask_3_4, Mask_3_5, Mask_3_6, Mask_3_7, Mask_3_8, Mask_3_9}, + {Mask_4_1, Mask_4_2, Mask_4_3, Mask_4_4, Mask_4_5, Mask_4_6, Mask_4_7, Mask_4_8, Mask_4_9}}; + AnsiString s; + MaskEna1->Checked = Mask.ena[0]; + MaskEna2->Checked = Mask.ena[1]; + for (int i = 0; i < 4; i++) + for (int j = 0; j < 9; j++) { + mask[i][j]->Text = s.sprintf("%.0f", Mask.mask[i][j]); + } + UpdateEnable(); } //--------------------------------------------------------------------------- -void __fastcall TMaskOptDialog::BtnOkClick(TObject *Sender) -{ - TEdit *mask[][9]={ - {Mask_1_1,Mask_1_2,Mask_1_3,Mask_1_4,Mask_1_5,Mask_1_6,Mask_1_7,Mask_1_8,Mask_1_9}, - {Mask_2_1,Mask_2_2,Mask_2_3,Mask_2_4,Mask_2_5,Mask_2_6,Mask_2_7,Mask_2_8,Mask_2_9}, - {Mask_3_1,Mask_3_2,Mask_3_3,Mask_3_4,Mask_3_5,Mask_3_6,Mask_3_7,Mask_3_8,Mask_3_9}, - {Mask_4_1,Mask_4_2,Mask_4_3,Mask_4_4,Mask_4_5,Mask_4_6,Mask_4_7,Mask_4_8,Mask_4_9} - }; - Mask.ena[0]=MaskEna1->Checked; - Mask.ena[1]=MaskEna2->Checked; - for (int i=0;i<4;i++) for (int j=0;j<9;j++) { - Mask.mask[i][j]=mask[i][j]->Text.ToDouble(); - } +void __fastcall TMaskOptDialog::BtnOkClick(TObject *Sender) { + TEdit *mask[][9] = { + {Mask_1_1, Mask_1_2, Mask_1_3, Mask_1_4, Mask_1_5, Mask_1_6, Mask_1_7, Mask_1_8, Mask_1_9}, + {Mask_2_1, Mask_2_2, Mask_2_3, Mask_2_4, Mask_2_5, Mask_2_6, Mask_2_7, Mask_2_8, Mask_2_9}, + {Mask_3_1, Mask_3_2, Mask_3_3, Mask_3_4, Mask_3_5, Mask_3_6, Mask_3_7, Mask_3_8, Mask_3_9}, + {Mask_4_1, Mask_4_2, Mask_4_3, Mask_4_4, Mask_4_5, Mask_4_6, Mask_4_7, Mask_4_8, Mask_4_9}}; + Mask.ena[0] = MaskEna1->Checked; + Mask.ena[1] = MaskEna2->Checked; + for (int i = 0; i < 4; i++) + for (int j = 0; j < 9; j++) { + Mask.mask[i][j] = mask[i][j]->Text.ToDouble(); + } } //--------------------------------------------------------------------------- -void __fastcall TMaskOptDialog::MaskEna1Click(TObject *Sender) -{ - UpdateEnable(); +void __fastcall TMaskOptDialog::MaskEna1Click(TObject *Sender) { UpdateEnable(); } +//--------------------------------------------------------------------------- +void __fastcall TMaskOptDialog::UpdateEnable(void) { + TEdit *mask[][9] = { + {Mask_1_1, Mask_1_2, Mask_1_3, Mask_1_4, Mask_1_5, Mask_1_6, Mask_1_7, Mask_1_8, Mask_1_9}, + {Mask_2_1, Mask_2_2, Mask_2_3, Mask_2_4, Mask_2_5, Mask_2_6, Mask_2_7, Mask_2_8, Mask_2_9}, + {Mask_3_1, Mask_3_2, Mask_3_3, Mask_3_4, Mask_3_5, Mask_3_6, Mask_3_7, Mask_3_8, Mask_3_9}, + {Mask_4_1, Mask_4_2, Mask_4_3, Mask_4_4, Mask_4_5, Mask_4_6, Mask_4_7, Mask_4_8, Mask_4_9}}; + for (int i = 0; i < 4; i++) + for (int j = 0; j < 9; j++) { + mask[i][j]->Enabled = MaskEna1->Checked || MaskEna2->Checked; + } } //--------------------------------------------------------------------------- -void __fastcall TMaskOptDialog::UpdateEnable(void) -{ - TEdit *mask[][9]={ - {Mask_1_1,Mask_1_2,Mask_1_3,Mask_1_4,Mask_1_5,Mask_1_6,Mask_1_7,Mask_1_8,Mask_1_9}, - {Mask_2_1,Mask_2_2,Mask_2_3,Mask_2_4,Mask_2_5,Mask_2_6,Mask_2_7,Mask_2_8,Mask_2_9}, - {Mask_3_1,Mask_3_2,Mask_3_3,Mask_3_4,Mask_3_5,Mask_3_6,Mask_3_7,Mask_3_8,Mask_3_9}, - {Mask_4_1,Mask_4_2,Mask_4_3,Mask_4_4,Mask_4_5,Mask_4_6,Mask_4_7,Mask_4_8,Mask_4_9} - }; - for (int i=0;i<4;i++) for (int j=0;j<9;j++) { - mask[i][j]->Enabled=MaskEna1->Checked||MaskEna2->Checked; - } -} -//--------------------------------------------------------------------------- - diff --git a/app/winapp/appcmn/maskoptdlg.h b/app/winapp/appcmn/maskoptdlg.h index 714af1132..f7f943ae6 100644 --- a/app/winapp/appcmn/maskoptdlg.h +++ b/app/winapp/appcmn/maskoptdlg.h @@ -4,80 +4,81 @@ //--------------------------------------------------------------------------- #include #include -#include -#include #include +#include +#include + #include "rtklib.h" //--------------------------------------------------------------------------- -class TMaskOptDialog : public TForm -{ -__published: - TButton *BtnOk; - TCheckBox *MaskEna1; - TLabel *Label3; - TPanel *Panel1; - TLabel *Label1; - TEdit *Mask_1_1; - TEdit *Mask_1_2; - TEdit *Mask_1_3; - TLabel *Label6; - TEdit *Mask_1_4; - TEdit *Mask_1_5; - TEdit *Mask_1_6; - TEdit *Mask_1_7; - TEdit *Mask_1_8; - TEdit *Mask_1_9; - TLabel *Label4; - TLabel *Label5; - TLabel *Label7; - TLabel *Label8; - TLabel *Label9; - TLabel *Label10; - TLabel *Label11; - TLabel *Label12; - TPanel *Panel2; - TLabel *Label13; - TEdit *Mask_2_1; - TEdit *Mask_2_2; - TEdit *Mask_2_3; - TEdit *Mask_2_4; - TEdit *Mask_2_5; - TEdit *Mask_2_6; - TEdit *Mask_2_7; - TEdit *Mask_2_8; - TEdit *Mask_2_9; - TPanel *Panel3; - TLabel *Label14; - TEdit *Mask_3_1; - TEdit *Mask_3_2; - TEdit *Mask_3_3; - TEdit *Mask_3_4; - TEdit *Mask_3_5; - TEdit *Mask_3_6; - TEdit *Mask_3_7; - TEdit *Mask_3_8; - TEdit *Mask_3_9; - TCheckBox *MaskEna2; - TPanel *Panel4; - TLabel *Label15; - TEdit *Mask_4_1; - TEdit *Mask_4_2; - TEdit *Mask_4_3; - TEdit *Mask_4_4; - TEdit *Mask_4_5; - TEdit *Mask_4_6; - TEdit *Mask_4_7; - TEdit *Mask_4_8; - TEdit *Mask_4_9; - void __fastcall FormShow(TObject *Sender); - void __fastcall BtnOkClick(TObject *Sender); - void __fastcall MaskEna1Click(TObject *Sender); -private: - void __fastcall UpdateEnable(void); -public: - snrmask_t Mask; - __fastcall TMaskOptDialog(TComponent* Owner); +class TMaskOptDialog : public TForm { + __published : TButton *BtnOk; + TCheckBox *MaskEna1; + TLabel *Label3; + TPanel *Panel1; + TLabel *Label1; + TEdit *Mask_1_1; + TEdit *Mask_1_2; + TEdit *Mask_1_3; + TLabel *Label6; + TEdit *Mask_1_4; + TEdit *Mask_1_5; + TEdit *Mask_1_6; + TEdit *Mask_1_7; + TEdit *Mask_1_8; + TEdit *Mask_1_9; + TLabel *Label4; + TLabel *Label5; + TLabel *Label7; + TLabel *Label8; + TLabel *Label9; + TLabel *Label10; + TLabel *Label11; + TLabel *Label12; + TPanel *Panel2; + TLabel *Label13; + TEdit *Mask_2_1; + TEdit *Mask_2_2; + TEdit *Mask_2_3; + TEdit *Mask_2_4; + TEdit *Mask_2_5; + TEdit *Mask_2_6; + TEdit *Mask_2_7; + TEdit *Mask_2_8; + TEdit *Mask_2_9; + TPanel *Panel3; + TLabel *Label14; + TEdit *Mask_3_1; + TEdit *Mask_3_2; + TEdit *Mask_3_3; + TEdit *Mask_3_4; + TEdit *Mask_3_5; + TEdit *Mask_3_6; + TEdit *Mask_3_7; + TEdit *Mask_3_8; + TEdit *Mask_3_9; + TCheckBox *MaskEna2; + TPanel *Panel4; + TLabel *Label15; + TEdit *Mask_4_1; + TEdit *Mask_4_2; + TEdit *Mask_4_3; + TEdit *Mask_4_4; + TEdit *Mask_4_5; + TEdit *Mask_4_6; + TEdit *Mask_4_7; + TEdit *Mask_4_8; + TEdit *Mask_4_9; + void __fastcall FormShow(TObject *Sender); + void __fastcall BtnOkClick(TObject *Sender); + void __fastcall MaskEna1Click(TObject *Sender); + + private: + void __fastcall UpdateEnable(void); + + public: + snrmask_t Mask; + __fastcall TMaskOptDialog(TComponent *Owner); }; //--------------------------------------------------------------------------- extern PACKAGE TMaskOptDialog *MaskOptDialog; diff --git a/app/winapp/appcmn/mntpoptdlg.cpp b/app/winapp/appcmn/mntpoptdlg.cpp index 4fc16369e..15e067a64 100644 --- a/app/winapp/appcmn/mntpoptdlg.cpp +++ b/app/winapp/appcmn/mntpoptdlg.cpp @@ -1,54 +1,53 @@ //--------------------------------------------------------------------------- -#include #include +#include #pragma hdrstop -#include "rtklib.h" #include "mntpoptdlg.h" + +#include "rtklib.h" //--------------------------------------------------------------------------- #pragma package(smart_init) #pragma resource "*.dfm" TMntpOptDialog *MntpOptDialog; //--------------------------------------------------------------------------- -__fastcall TMntpOptDialog::TMntpOptDialog(TComponent* Owner) - : TForm(Owner) -{ -} +__fastcall TMntpOptDialog::TMntpOptDialog(TComponent *Owner) : TForm(Owner) {} //--------------------------------------------------------------------------- -void __fastcall TMntpOptDialog::FormShow(TObject *Sender) -{ - TEdit *edit[]={ - SrcTbl1,SrcTbl2,SrcTbl3,NULL,SrcTbl5,SrcTbl6,SrcTbl7,SrcTbl8,SrcTbl9, - NULL,NULL,SrcTbl12,SrcTbl13,NULL,NULL,SrcTbl16 - }; - TComboBox *box[]={ - NULL,NULL,NULL,SrcTbl4,NULL,NULL,NULL,NULL,NULL,SrcTbl10,SrcTbl11,NULL, - NULL,SrcTbl14,SrcTbl15,NULL - }; - AnsiString str=MntpStr; - char buff[2048],*p=buff,*q; - - MntPntE->Text=MntPnt; +void __fastcall TMntpOptDialog::FormShow(TObject *Sender) { + TEdit *edit[] = {SrcTbl1, SrcTbl2, SrcTbl3, NULL, SrcTbl5, SrcTbl6, SrcTbl7, SrcTbl8, + SrcTbl9, NULL, NULL, SrcTbl12, SrcTbl13, NULL, NULL, SrcTbl16}; + TComboBox *box[] = {NULL, NULL, NULL, SrcTbl4, NULL, NULL, NULL, NULL, + NULL, SrcTbl10, SrcTbl11, NULL, NULL, SrcTbl14, SrcTbl15, NULL}; + AnsiString str = MntpStr; + char buff[2048], *p = buff, *q; + + MntPntE->Text = MntPnt; + + sprintf(buff, "%.2047s", str.c_str()); - sprintf(buff,"%.2047s",str.c_str()); - - for (int i=0;i<16;i++) { - if (edit[i]) edit[i]->Text=""; else box[i]->ItemIndex=0; - } - for (int i=0;*p&&i<16;i++,p=q+1) { - if ((q=strchr(p,';'))) *q='\0'; - if (edit[i]) edit[i]->Text=p; else box[i]->Text=p; - if (!q) break; - } + for (int i = 0; i < 16; i++) { + if (edit[i]) + edit[i]->Text = ""; + else + box[i]->ItemIndex = 0; + } + for (int i = 0; *p && i < 16; i++, p = q + 1) { + if ((q = strchr(p, ';'))) *q = '\0'; + if (edit[i]) + edit[i]->Text = p; + else + box[i]->Text = p; + if (!q) break; + } } //--------------------------------------------------------------------------- -void __fastcall TMntpOptDialog::BtnOkClick(TObject *Sender) -{ - MntPnt=MntPntE->Text; - MntpStr=SrcTbl1->Text+";"+SrcTbl2->Text+";"+SrcTbl3->Text+";"+SrcTbl4->Text+";"+ - SrcTbl5->Text+";"+SrcTbl6->Text+";"+SrcTbl7->Text+";"+SrcTbl8->Text+";"+ - SrcTbl9->Text+";"+SrcTbl10->Text+";"+SrcTbl11->Text+";"+SrcTbl12->Text+";"+ - SrcTbl13->Text+";"+SrcTbl14->Text+";"+SrcTbl15->Text+";"+SrcTbl16->Text; +void __fastcall TMntpOptDialog::BtnOkClick(TObject *Sender) { + MntPnt = MntPntE->Text; + MntpStr = SrcTbl1->Text + ";" + SrcTbl2->Text + ";" + SrcTbl3->Text + ";" + SrcTbl4->Text + ";" + + SrcTbl5->Text + ";" + SrcTbl6->Text + ";" + SrcTbl7->Text + ";" + SrcTbl8->Text + ";" + + SrcTbl9->Text + ";" + SrcTbl10->Text + ";" + SrcTbl11->Text + ";" + SrcTbl12->Text + + ";" + SrcTbl13->Text + ";" + SrcTbl14->Text + ";" + SrcTbl15->Text + ";" + + SrcTbl16->Text; } //--------------------------------------------------------------------------- diff --git a/app/winapp/appcmn/mntpoptdlg.h b/app/winapp/appcmn/mntpoptdlg.h index eec9f796c..3d783c25b 100644 --- a/app/winapp/appcmn/mntpoptdlg.h +++ b/app/winapp/appcmn/mntpoptdlg.h @@ -4,57 +4,56 @@ //--------------------------------------------------------------------------- #include #include -#include #include +#include -#define MAXHIST 10 +#define MAXHIST 10 //--------------------------------------------------------------------------- -class TMntpOptDialog : public TForm -{ -__published: - TButton *BtnCancel; - TButton *BtnOk; - TLabel *Label14; - TEdit *SrcTbl1; - TEdit *SrcTbl2; - TEdit *SrcTbl3; - TEdit *SrcTbl5; - TEdit *SrcTbl6; - TEdit *SrcTbl7; - TEdit *SrcTbl8; - TEdit *SrcTbl9; - TLabel *Label15; - TLabel *Label16; - TEdit *SrcTbl12; - TLabel *Label1; - TLabel *Label2; - TLabel *Label3; - TLabel *Label4; - TComboBox *SrcTbl4; - TComboBox *SrcTbl10; - TLabel *Label5; - TLabel *Label6; - TComboBox *SrcTbl11; - TLabel *Label7; - TLabel *Label8; - TLabel *Label9; - TEdit *SrcTbl13; - TLabel *Label10; - TComboBox *SrcTbl14; - TLabel *Label11; - TLabel *Label12; - TComboBox *SrcTbl15; - TLabel *Label13; - TEdit *SrcTbl16; - TEdit *MntPntE; - TLabel *Label17; - void __fastcall FormShow(TObject *Sender); - void __fastcall BtnOkClick(TObject *Sender); -private: -public: - AnsiString MntPnt,MntpStr; - __fastcall TMntpOptDialog(TComponent* Owner); +class TMntpOptDialog : public TForm { + __published : TButton *BtnCancel; + TButton *BtnOk; + TLabel *Label14; + TEdit *SrcTbl1; + TEdit *SrcTbl2; + TEdit *SrcTbl3; + TEdit *SrcTbl5; + TEdit *SrcTbl6; + TEdit *SrcTbl7; + TEdit *SrcTbl8; + TEdit *SrcTbl9; + TLabel *Label15; + TLabel *Label16; + TEdit *SrcTbl12; + TLabel *Label1; + TLabel *Label2; + TLabel *Label3; + TLabel *Label4; + TComboBox *SrcTbl4; + TComboBox *SrcTbl10; + TLabel *Label5; + TLabel *Label6; + TComboBox *SrcTbl11; + TLabel *Label7; + TLabel *Label8; + TLabel *Label9; + TEdit *SrcTbl13; + TLabel *Label10; + TComboBox *SrcTbl14; + TLabel *Label11; + TLabel *Label12; + TComboBox *SrcTbl15; + TLabel *Label13; + TEdit *SrcTbl16; + TEdit *MntPntE; + TLabel *Label17; + void __fastcall FormShow(TObject *Sender); + void __fastcall BtnOkClick(TObject *Sender); + + private: + public: + AnsiString MntPnt, MntpStr; + __fastcall TMntpOptDialog(TComponent *Owner); }; //--------------------------------------------------------------------------- extern PACKAGE TMntpOptDialog *MntpOptDialog; diff --git a/app/winapp/appcmn/refdlg.cpp b/app/winapp/appcmn/refdlg.cpp index bc0376f55..570372cf1 100644 --- a/app/winapp/appcmn/refdlg.cpp +++ b/app/winapp/appcmn/refdlg.cpp @@ -1,271 +1,253 @@ //--------------------------------------------------------------------------- -#include #include +#include #pragma hdrstop #include "refdlg.h" + #include "rtklib.h" //--------------------------------------------------------------------------- #pragma package(smart_init) #pragma resource "*.dfm" TRefDialog *RefDialog; -#define CHARDEG "\302\260" // character code of degree (UTF-8) -#define STALIST_WIDTH 470 // width of StaList (px) +#define CHARDEG "\302\260" // character code of degree (UTF-8) +#define STALIST_WIDTH 470 // width of StaList (px) //--------------------------------------------------------------------------- -static double str2dbl(AnsiString str) -{ - double val=0.0; - sscanf(str.c_str(),"%lf",&val); - return val; +static double str2dbl(AnsiString str) { + double val = 0.0; + sscanf(str.c_str(), "%lf", &val); + return val; } //--------------------------------------------------------------------------- -__fastcall TRefDialog::TRefDialog(TComponent* Owner) - : TForm(Owner) -{ - Opt=0; - Pos[0]=Pos[1]=Pos[2]=RovPos[0]=RovPos[1]=RovPos[2]=0.0; +__fastcall TRefDialog::TRefDialog(TComponent *Owner) : TForm(Owner) { + Opt = 0; + Pos[0] = Pos[1] = Pos[2] = RovPos[0] = RovPos[1] = RovPos[2] = 0.0; } //--------------------------------------------------------------------------- -void __fastcall TRefDialog::FormShow(TObject *Sender) -{ - UTF8String s; - double scale; - int width[]={30,80,90,65,50,80,55}; - - BtnLoad->Visible=Opt; +void __fastcall TRefDialog::FormShow(TObject *Sender) { + UTF8String s; + double scale; + int width[] = {30, 80, 90, 65, 50, 80, 55}; - scale=(double)StaList->Width/STALIST_WIDTH; - - for (int i=0;i<7;i++) { - StaList->ColWidths[i]=(int)(width[i]*scale); - } - StaList->Cells[0][0]=" No"; - StaList->Cells[1][0]=s.sprintf(" Latitude (%s)" ,CHARDEG); - StaList->Cells[2][0]=s.sprintf(" Longitude (%s)",CHARDEG); - StaList->Cells[3][0]=" Height(m)"; - StaList->Cells[4][0]=" Id"; - StaList->Cells[5][0]=" Name"; - StaList->Cells[6][0]=" Dist(km)"; - LoadList(); - if (norm(RovPos,3)>0.0) SortList(6); -} -//--------------------------------------------------------------------------- -void __fastcall TRefDialog::StaListMouseDown(TObject *Sender, - TMouseButton Button, TShiftState Shift, int X, int Y) -{ - int col,row; + BtnLoad->Visible = Opt; - StaList->MouseToCell(X,Y,col,row); - if (row==0) SortList(col); -} -//--------------------------------------------------------------------------- -void __fastcall TRefDialog::StaListDblClick(TObject *Sender) -{ - ModalResult=InputRef()?mrOk:mrCancel; -} -//--------------------------------------------------------------------------- -void __fastcall TRefDialog::BtnOKClick(TObject *Sender) -{ - ModalResult=InputRef()?mrOk:mrCancel; -} -//--------------------------------------------------------------------------- -void __fastcall TRefDialog::BtnLoadClick(TObject *Sender) -{ - OpenDialog->FileName=StaPosFile; - if (OpenDialog->Execute()!=mrOk) return; - StaPosFile=OpenDialog->FileName; - LoadList(); -} -//--------------------------------------------------------------------------- -void __fastcall TRefDialog::BtnFindClick(TObject *Sender) -{ - FindList(); -} -//--------------------------------------------------------------------------- -void __fastcall TRefDialog::FindStrKeyPress(TObject *Sender, char &Key) -{ - if (Key=='\r') FindList(); -} -//--------------------------------------------------------------------------- -void __fastcall TRefDialog::FindList(void) -{ - TGridRect r=StaList->Selection; - int i,j,n=StaList->RowCount; - int nmax=StaList->Height/StaList->DefaultRowHeight-1; - AnsiString str=FindStr->Text; - - if (n<=1) return; - i=r.Top<0||r.Top>=n?0:r.Top; - j=(i>=n)?1:i+1; - - for (;;) { - if (StaList->Cells[4][j].Pos(str)>0|| - StaList->Cells[5][j].Pos(str)>0) { - r.Top=j; - r.Bottom=j; - r.Left=0; - r.Right=6; - StaList->Selection=r; - - if (jTopRow+1||j>=StaList->TopRow+nmax) { - if (jTopRow=1; - else if (j>=n-nmax) StaList->TopRow=n-nmax; - else StaList->TopRow=j-nmax/2; - } - break; - } - if (i==j) break; - if (++j>=n) j=1; - } + scale = (double)StaList->Width / STALIST_WIDTH; + + for (int i = 0; i < 7; i++) { + StaList->ColWidths[i] = (int)(width[i] * scale); + } + StaList->Cells[0][0] = " No"; + StaList->Cells[1][0] = s.sprintf(" Latitude (%s)", CHARDEG); + StaList->Cells[2][0] = s.sprintf(" Longitude (%s)", CHARDEG); + StaList->Cells[3][0] = " Height(m)"; + StaList->Cells[4][0] = " Id"; + StaList->Cells[5][0] = " Name"; + StaList->Cells[6][0] = " Dist(km)"; + LoadList(); + if (norm(RovPos, 3) > 0.0) SortList(6); +} +//--------------------------------------------------------------------------- +void __fastcall TRefDialog::StaListMouseDown(TObject *Sender, TMouseButton Button, + TShiftState Shift, int X, int Y) { + int col, row; + + StaList->MouseToCell(X, Y, col, row); + if (row == 0) SortList(col); } //--------------------------------------------------------------------------- -void __fastcall TRefDialog::LoadList(void) -{ - FILE *fp; - char buff[256]="",code[256],name[256],*p; - double pos[3]; - int format,n=0; - - // check format - if (!(fp=fopen(StaPosFile.c_str(),"r"))) return; - fgets(buff,sizeof(buff),fp); - format=strstr(buff,"%=SNX")==buff; - fclose(fp); - - if (format) { - LoadSinex(); - return; - } - if (!(fp=fopen(StaPosFile.c_str(),"r"))) return; - - while (fgets(buff,sizeof(buff),fp)) { - if ((p=strchr(buff,'%'))) *p='\0'; - pos[0]=pos[1]=pos[2]=0.0; - code[0]='\0'; - name[0]='\0'; - if (sscanf(buff,"%lf %lf %lf %255s %255s",pos,pos+1,pos+2,code, - name)<3) continue; - StaList->RowCount=++n+1; - AddRef(n,pos,code,name); - } - if (n==0) { - StaList->RowCount=2; - for (int i=0;iColCount;i++) StaList->Cells[i][1]=""; - } - fclose(fp); - UpdateDist(); - Caption=StaPosFile; +void __fastcall TRefDialog::StaListDblClick(TObject *Sender) { + ModalResult = InputRef() ? mrOk : mrCancel; } //--------------------------------------------------------------------------- -void __fastcall TRefDialog::LoadSinex(void) -{ - FILE *fp; - char buff[256],code[256]; - double rr[3],pos[3]; - int n=0,sol=0; - - if (!(fp=fopen(StaPosFile.c_str(),"r"))) return; - - while (fgets(buff,sizeof(buff),fp)) { - if (strstr(buff,"+SOLUTION/ESTIMATE")) sol=1; - else if (strstr(buff,"-SOLUTION/ESTIMATE")) sol=0; - if (!sol||strlen(buff)<68) continue; - if (!strncmp(buff+7,"STAX",4)) { - if (sscanf(buff+47,"%lf",rr)<1) continue; - strncpy(code,buff+14,4); code[4]='\0'; - } - else if (!strncmp(buff+7,"STAY",4)) { - if (sscanf(buff+47,"%lf",rr+1)<1) continue; - if (strncmp(code,buff+14,4)) continue; - } - else if (!strncmp(buff+7,"STAZ",4)) { - if (sscanf(buff+47,"%lf",rr+2)<1) continue; - if (strncmp(code,buff+14,4)) continue; - ecef2pos(rr,pos); - pos[0]*=R2D; - pos[1]*=R2D; - StaList->RowCount=++n+1; - AddRef(n,pos,code,""); - } - } - if (n==0) { - StaList->RowCount=2; - for (int i=0;iColCount;i++) StaList->Cells[i][1]=""; - } - fclose(fp); - UpdateDist(); - Caption=StaPosFile; +void __fastcall TRefDialog::BtnOKClick(TObject *Sender) { + ModalResult = InputRef() ? mrOk : mrCancel; } //--------------------------------------------------------------------------- -void __fastcall TRefDialog::SortList(int col) -{ - for (int i=1;iRowCount;i++) { - int j=i; - for (int k=i+1;kRowCount;k++) { - AnsiString s1=StaList->Cells[col][j]; - AnsiString s2=StaList->Cells[col][k]; - if (strcmp(s1.c_str(),s2.c_str())>0) j=k; - } - if (j==i) continue; - for (int k=0;kColCount;k++) { - AnsiString s=StaList->Cells[k][i]; - StaList->Cells[k][i]=StaList->Cells[k][j]; - StaList->Cells[k][j]=s; - } - } +void __fastcall TRefDialog::BtnLoadClick(TObject *Sender) { + OpenDialog->FileName = StaPosFile; + if (OpenDialog->Execute() != mrOk) return; + StaPosFile = OpenDialog->FileName; + LoadList(); } //--------------------------------------------------------------------------- -void __fastcall TRefDialog::AddRef(int n, double *pos, const char *code, - const char *name) -{ - AnsiString s; - - int i=StaList->RowCount; - StaList->Cells[0][i-1]=s.sprintf("%4d",n); - StaList->Cells[1][i-1]=s.sprintf("%13.9f",pos[0]); - StaList->Cells[2][i-1]=s.sprintf("%14.9f",pos[1]); - StaList->Cells[3][i-1]=s.sprintf("%10.4f",pos[2]); - StaList->Cells[4][i-1]=code; - StaList->Cells[5][i-1]=name; - StaList->Cells[6][i-1]=""; -} +void __fastcall TRefDialog::BtnFindClick(TObject *Sender) { FindList(); } //--------------------------------------------------------------------------- -int __fastcall TRefDialog::InputRef(void) -{ - int n=StaList->RowCount; - - TGridRect r=StaList->Selection; - if (r.Top<1||n<=r.Top) return 0; - Pos[0]=str2dbl(StaList->Cells[1][r.Top]); - Pos[1]=str2dbl(StaList->Cells[2][r.Top]); - Pos[2]=str2dbl(StaList->Cells[3][r.Top]); - StaId =StaList->Cells[4][r.Top]; - StaName=StaList->Cells[5][r.Top]; - return 1; +void __fastcall TRefDialog::FindStrKeyPress(TObject *Sender, char &Key) { + if (Key == '\r') FindList(); } //--------------------------------------------------------------------------- -void __fastcall TRefDialog::UpdateDist(void) -{ - AnsiString s; - double pos[3],ru[3],rr[3]; - - matcpy(pos,RovPos,3,1); - if (norm(pos,3)<=0.0) return; - pos[0]*=D2R; - pos[1]*=D2R; - pos2ecef(pos,ru); - - for (int i=1;iRowCount;i++) { - if (StaList->Cells[1][i]=="") continue; - pos[0]=str2dbl(StaList->Cells[1][i])*D2R; - pos[1]=str2dbl(StaList->Cells[2][i])*D2R; - pos[2]=str2dbl(StaList->Cells[3][i]); - pos2ecef(pos,rr); - for (int j=0;j<3;j++) rr[j]-=ru[j]; - StaList->Cells[6][i]=s.sprintf("%6.1f",norm(rr,3)/1E3); - } +void __fastcall TRefDialog::FindList(void) { + TGridRect r = StaList->Selection; + int i, j, n = StaList->RowCount; + int nmax = StaList->Height / StaList->DefaultRowHeight - 1; + AnsiString str = FindStr->Text; + + if (n <= 1) return; + i = r.Top < 0 || r.Top >= n ? 0 : r.Top; + j = (i >= n) ? 1 : i + 1; + + for (;;) { + if (StaList->Cells[4][j].Pos(str) > 0 || StaList->Cells[5][j].Pos(str) > 0) { + r.Top = j; + r.Bottom = j; + r.Left = 0; + r.Right = 6; + StaList->Selection = r; + + if (j < StaList->TopRow + 1 || j >= StaList->TopRow + nmax) { + if (j < nmax - 1) + StaList->TopRow = 1; + else if (j >= n - nmax) + StaList->TopRow = n - nmax; + else + StaList->TopRow = j - nmax / 2; + } + break; + } + if (i == j) break; + if (++j >= n) j = 1; + } +} +//--------------------------------------------------------------------------- +void __fastcall TRefDialog::LoadList(void) { + FILE *fp; + char buff[256] = "", code[256], name[256], *p; + double pos[3]; + int format, n = 0; + + // check format + if (!(fp = fopen(StaPosFile.c_str(), "r"))) return; + fgets(buff, sizeof(buff), fp); + format = strstr(buff, "%=SNX") == buff; + fclose(fp); + + if (format) { + LoadSinex(); + return; + } + if (!(fp = fopen(StaPosFile.c_str(), "r"))) return; + + while (fgets(buff, sizeof(buff), fp)) { + if ((p = strchr(buff, '%'))) *p = '\0'; + pos[0] = pos[1] = pos[2] = 0.0; + code[0] = '\0'; + name[0] = '\0'; + if (sscanf(buff, "%lf %lf %lf %255s %255s", pos, pos + 1, pos + 2, code, name) < 3) continue; + StaList->RowCount = ++n + 1; + AddRef(n, pos, code, name); + } + if (n == 0) { + StaList->RowCount = 2; + for (int i = 0; i < StaList->ColCount; i++) StaList->Cells[i][1] = ""; + } + fclose(fp); + UpdateDist(); + Caption = StaPosFile; +} +//--------------------------------------------------------------------------- +void __fastcall TRefDialog::LoadSinex(void) { + FILE *fp; + char buff[256], code[256]; + double rr[3], pos[3]; + int n = 0, sol = 0; + + if (!(fp = fopen(StaPosFile.c_str(), "r"))) return; + + while (fgets(buff, sizeof(buff), fp)) { + if (strstr(buff, "+SOLUTION/ESTIMATE")) + sol = 1; + else if (strstr(buff, "-SOLUTION/ESTIMATE")) + sol = 0; + if (!sol || strlen(buff) < 68) continue; + if (!strncmp(buff + 7, "STAX", 4)) { + if (sscanf(buff + 47, "%lf", rr) < 1) continue; + strncpy(code, buff + 14, 4); + code[4] = '\0'; + } else if (!strncmp(buff + 7, "STAY", 4)) { + if (sscanf(buff + 47, "%lf", rr + 1) < 1) continue; + if (strncmp(code, buff + 14, 4)) continue; + } else if (!strncmp(buff + 7, "STAZ", 4)) { + if (sscanf(buff + 47, "%lf", rr + 2) < 1) continue; + if (strncmp(code, buff + 14, 4)) continue; + ecef2pos(rr, pos); + pos[0] *= R2D; + pos[1] *= R2D; + StaList->RowCount = ++n + 1; + AddRef(n, pos, code, ""); + } + } + if (n == 0) { + StaList->RowCount = 2; + for (int i = 0; i < StaList->ColCount; i++) StaList->Cells[i][1] = ""; + } + fclose(fp); + UpdateDist(); + Caption = StaPosFile; +} +//--------------------------------------------------------------------------- +void __fastcall TRefDialog::SortList(int col) { + for (int i = 1; i < StaList->RowCount; i++) { + int j = i; + for (int k = i + 1; k < StaList->RowCount; k++) { + AnsiString s1 = StaList->Cells[col][j]; + AnsiString s2 = StaList->Cells[col][k]; + if (strcmp(s1.c_str(), s2.c_str()) > 0) j = k; + } + if (j == i) continue; + for (int k = 0; k < StaList->ColCount; k++) { + AnsiString s = StaList->Cells[k][i]; + StaList->Cells[k][i] = StaList->Cells[k][j]; + StaList->Cells[k][j] = s; + } + } +} +//--------------------------------------------------------------------------- +void __fastcall TRefDialog::AddRef(int n, double *pos, const char *code, const char *name) { + AnsiString s; + + int i = StaList->RowCount; + StaList->Cells[0][i - 1] = s.sprintf("%4d", n); + StaList->Cells[1][i - 1] = s.sprintf("%13.9f", pos[0]); + StaList->Cells[2][i - 1] = s.sprintf("%14.9f", pos[1]); + StaList->Cells[3][i - 1] = s.sprintf("%10.4f", pos[2]); + StaList->Cells[4][i - 1] = code; + StaList->Cells[5][i - 1] = name; + StaList->Cells[6][i - 1] = ""; +} +//--------------------------------------------------------------------------- +int __fastcall TRefDialog::InputRef(void) { + int n = StaList->RowCount; + + TGridRect r = StaList->Selection; + if (r.Top < 1 || n <= r.Top) return 0; + Pos[0] = str2dbl(StaList->Cells[1][r.Top]); + Pos[1] = str2dbl(StaList->Cells[2][r.Top]); + Pos[2] = str2dbl(StaList->Cells[3][r.Top]); + StaId = StaList->Cells[4][r.Top]; + StaName = StaList->Cells[5][r.Top]; + return 1; +} +//--------------------------------------------------------------------------- +void __fastcall TRefDialog::UpdateDist(void) { + AnsiString s; + double pos[3], ru[3], rr[3]; + + matcpy(pos, RovPos, 3, 1); + if (norm(pos, 3) <= 0.0) return; + pos[0] *= D2R; + pos[1] *= D2R; + pos2ecef(pos, ru); + + for (int i = 1; i < StaList->RowCount; i++) { + if (StaList->Cells[1][i] == "") continue; + pos[0] = str2dbl(StaList->Cells[1][i]) * D2R; + pos[1] = str2dbl(StaList->Cells[2][i]) * D2R; + pos[2] = str2dbl(StaList->Cells[3][i]); + pos2ecef(pos, rr); + for (int j = 0; j < 3; j++) rr[j] -= ru[j]; + StaList->Cells[6][i] = s.sprintf("%6.1f", norm(rr, 3) / 1E3); + } } //--------------------------------------------------------------------------- - diff --git a/app/winapp/appcmn/refdlg.h b/app/winapp/appcmn/refdlg.h index eed730247..9c9e6be76 100644 --- a/app/winapp/appcmn/refdlg.h +++ b/app/winapp/appcmn/refdlg.h @@ -4,45 +4,45 @@ //--------------------------------------------------------------------------- #include #include -#include -#include -#include #include #include +#include +#include +#include //--------------------------------------------------------------------------- -class TRefDialog : public TForm -{ -__published: - TStringGrid *StaList; - TButton *BtnLoad; - TOpenDialog *OpenDialog; - TPanel *Panel1; - TPanel *Panel2; - TButton *BtnOK; - TButton *BtnCancel; - TButton *BtnFind; - TEdit *FindStr; - void __fastcall FormShow(TObject *Sender); - void __fastcall BtnOKClick(TObject *Sender); - void __fastcall StaListDblClick(TObject *Sender); - void __fastcall StaListMouseDown(TObject *Sender, TMouseButton Button, - TShiftState Shift, int X, int Y); - void __fastcall BtnLoadClick(TObject *Sender); - void __fastcall BtnFindClick(TObject *Sender); - void __fastcall FindStrKeyPress(TObject *Sender, char &Key); -private: - void __fastcall FindList(void); - void __fastcall LoadList(void); - void __fastcall LoadSinex(void); - void __fastcall SortList(int col); - void __fastcall AddRef(int n, double *pos, const char *code, const char *name); - int __fastcall InputRef(void); - void __fastcall UpdateDist(void); -public: - AnsiString StaPosFile,StaId,StaName; - int Opt,FontScale; - double Pos[3],RovPos[3]; - __fastcall TRefDialog(TComponent* Owner); +class TRefDialog : public TForm { + __published : TStringGrid *StaList; + TButton *BtnLoad; + TOpenDialog *OpenDialog; + TPanel *Panel1; + TPanel *Panel2; + TButton *BtnOK; + TButton *BtnCancel; + TButton *BtnFind; + TEdit *FindStr; + void __fastcall FormShow(TObject *Sender); + void __fastcall BtnOKClick(TObject *Sender); + void __fastcall StaListDblClick(TObject *Sender); + void __fastcall StaListMouseDown(TObject *Sender, TMouseButton Button, TShiftState Shift, int X, + int Y); + void __fastcall BtnLoadClick(TObject *Sender); + void __fastcall BtnFindClick(TObject *Sender); + void __fastcall FindStrKeyPress(TObject *Sender, char &Key); + + private: + void __fastcall FindList(void); + void __fastcall LoadList(void); + void __fastcall LoadSinex(void); + void __fastcall SortList(int col); + void __fastcall AddRef(int n, double *pos, const char *code, const char *name); + int __fastcall InputRef(void); + void __fastcall UpdateDist(void); + + public: + AnsiString StaPosFile, StaId, StaName; + int Opt, FontScale; + double Pos[3], RovPos[3]; + __fastcall TRefDialog(TComponent *Owner); }; //--------------------------------------------------------------------------- extern PACKAGE TRefDialog *RefDialog; diff --git a/app/winapp/appcmn/serioptdlg.cpp b/app/winapp/appcmn/serioptdlg.cpp index 137b0f740..3fdbef870 100644 --- a/app/winapp/appcmn/serioptdlg.cpp +++ b/app/winapp/appcmn/serioptdlg.cpp @@ -1,95 +1,96 @@ //--------------------------------------------------------------------------- -#include #include +#include #pragma hdrstop -#include "cmdoptdlg.h" #include "serioptdlg.h" -#define MAXCOMNO 299 // maximun com number +#include "cmdoptdlg.h" + +#define MAXCOMNO 299 // maximun com number //--------------------------------------------------------------------------- #pragma package(smart_init) #pragma resource "*.dfm" TSerialOptDialog *SerialOptDialog; //--------------------------------------------------------------------------- -__fastcall TSerialOptDialog::TSerialOptDialog(TComponent* Owner) - : TForm(Owner) -{ - Opt=0; -} +__fastcall TSerialOptDialog::TSerialOptDialog(TComponent *Owner) : TForm(Owner) { Opt = 0; } //--------------------------------------------------------------------------- -void __fastcall TSerialOptDialog::FormShow(TObject *Sender) -{ - AnsiString s; - char *p,*q,path[1024]; - int port; - - UpdatePortList(); - strcpy(path,Path.c_str()); - if (!(q=strchr(p=path,':'))) return; else *q='\0'; - Port->Text=p; - if (!(q=strchr(p=q+1,':'))) return; else *q='\0'; - BitRate->Text=p; - if (!(q=strchr(p=q+1,':'))) return; else *q='\0'; - ByteSize->ItemIndex=!strcmp(p,"7")?0:1; - if (!(q=strchr(p=q+1,':'))) return; else *q='\0'; - Parity->ItemIndex=!strcmp(p,"n")?0:(!strcmp(p,"e")?1:2); - if (!(q=strchr(p=q+1,':'))) return; else *q='\0'; - StopBits->ItemIndex=!strcmp(p,"1")?0:1; - p=q+1; - FlowCtr->ItemIndex=!strcmp(p,"off")?0:(!strcmp(p,"xon")?1:2); - - if ((q=strchr(p=q+1,'#'))&&sscanf(q,"#%d",&port)==1) { - OutTcpPort->Checked=true; - TcpPort->Text=s.sprintf("%d",port); - } - else { - OutTcpPort->Checked=false; - TcpPort->Text=""; - } - OutTcpPort->Enabled=Opt; - TcpPort ->Enabled=Opt; - UpdateEnable(); +void __fastcall TSerialOptDialog::FormShow(TObject *Sender) { + AnsiString s; + char *p, *q, path[1024]; + int port; + + UpdatePortList(); + strcpy(path, Path.c_str()); + if (!(q = strchr(p = path, ':'))) + return; + else + *q = '\0'; + Port->Text = p; + if (!(q = strchr(p = q + 1, ':'))) + return; + else + *q = '\0'; + BitRate->Text = p; + if (!(q = strchr(p = q + 1, ':'))) + return; + else + *q = '\0'; + ByteSize->ItemIndex = !strcmp(p, "7") ? 0 : 1; + if (!(q = strchr(p = q + 1, ':'))) + return; + else + *q = '\0'; + Parity->ItemIndex = !strcmp(p, "n") ? 0 : (!strcmp(p, "e") ? 1 : 2); + if (!(q = strchr(p = q + 1, ':'))) + return; + else + *q = '\0'; + StopBits->ItemIndex = !strcmp(p, "1") ? 0 : 1; + p = q + 1; + FlowCtr->ItemIndex = !strcmp(p, "off") ? 0 : (!strcmp(p, "xon") ? 1 : 2); + + if ((q = strchr(p = q + 1, '#')) && sscanf(q, "#%d", &port) == 1) { + OutTcpPort->Checked = true; + TcpPort->Text = s.sprintf("%d", port); + } else { + OutTcpPort->Checked = false; + TcpPort->Text = ""; + } + OutTcpPort->Enabled = Opt; + TcpPort->Enabled = Opt; + UpdateEnable(); } //--------------------------------------------------------------------------- -void __fastcall TSerialOptDialog::BtnOkClick(TObject *Sender) -{ - const char *parity[]={"n","e","o"},*fctr[]={"off","rts"}; - AnsiString s,Port_Text=Port->Text,BitRate_Text=BitRate->Text; - AnsiString TcpPort_Text=TcpPort->Text; - int port; - Path=s.sprintf("%s:%s:%d:%s:%d:%s",Port_Text.c_str(),BitRate_Text.c_str(), - ByteSize->ItemIndex?8:7,parity[Parity->ItemIndex], - StopBits->ItemIndex?2:1,fctr[FlowCtr->ItemIndex]); - if (OutTcpPort->Checked&&sscanf(TcpPort_Text.c_str(),"%d",&port)==1) { - Path+=s.sprintf("#%d",port); - } +void __fastcall TSerialOptDialog::BtnOkClick(TObject *Sender) { + const char *parity[] = {"n", "e", "o"}, *fctr[] = {"off", "rts"}; + AnsiString s, Port_Text = Port->Text, BitRate_Text = BitRate->Text; + AnsiString TcpPort_Text = TcpPort->Text; + int port; + Path = s.sprintf("%s:%s:%d:%s:%d:%s", Port_Text.c_str(), BitRate_Text.c_str(), + ByteSize->ItemIndex ? 8 : 7, parity[Parity->ItemIndex], + StopBits->ItemIndex ? 2 : 1, fctr[FlowCtr->ItemIndex]); + if (OutTcpPort->Checked && sscanf(TcpPort_Text.c_str(), "%d", &port) == 1) { + Path += s.sprintf("#%d", port); + } } //--------------------------------------------------------------------------- -void __fastcall TSerialOptDialog::UpdatePortList(void) -{ - HANDLE h; - char port[64]; - - Port->Items->Clear(); - for (int i=1;i<=MAXCOMNO;i++) { - sprintf(port,"\\\\.\\COM%d",i); - h=CreateFile(port,GENERIC_READ|GENERIC_WRITE,0,0,OPEN_EXISTING,0,NULL); - if (h==INVALID_HANDLE_VALUE) continue; - Port->Items->Add(port+4); - CloseHandle(h); - } +void __fastcall TSerialOptDialog::UpdatePortList(void) { + HANDLE h; + char port[64]; + + Port->Items->Clear(); + for (int i = 1; i <= MAXCOMNO; i++) { + sprintf(port, "\\\\.\\COM%d", i); + h = CreateFile(port, GENERIC_READ | GENERIC_WRITE, 0, 0, OPEN_EXISTING, 0, NULL); + if (h == INVALID_HANDLE_VALUE) continue; + Port->Items->Add(port + 4); + CloseHandle(h); + } } //--------------------------------------------------------------------------- -void __fastcall TSerialOptDialog::UpdateEnable(void) -{ - TcpPort->Enabled=OutTcpPort->Checked; -} +void __fastcall TSerialOptDialog::UpdateEnable(void) { TcpPort->Enabled = OutTcpPort->Checked; } //--------------------------------------------------------------------------- -void __fastcall TSerialOptDialog::OutTcpPortClick(TObject *Sender) -{ - UpdateEnable(); -} +void __fastcall TSerialOptDialog::OutTcpPortClick(TObject *Sender) { UpdateEnable(); } //--------------------------------------------------------------------------- - diff --git a/app/winapp/appcmn/serioptdlg.h b/app/winapp/appcmn/serioptdlg.h index c805a05a2..5ab88306c 100644 --- a/app/winapp/appcmn/serioptdlg.h +++ b/app/winapp/appcmn/serioptdlg.h @@ -4,38 +4,38 @@ //--------------------------------------------------------------------------- #include #include -#include #include +#include //--------------------------------------------------------------------------- -class TSerialOptDialog : public TForm -{ -__published: - TButton *BtnOk; - TButton *BtnCancel; - TComboBox *BitRate; - TLabel *Label1; - TLabel *Label3; - TComboBox *Port; - TLabel *Label2; - TComboBox *ByteSize; - TLabel *Label4; - TComboBox *Parity; - TLabel *Label5; - TComboBox *StopBits; - TLabel *Label8; - TComboBox *FlowCtr; - TCheckBox *OutTcpPort; - TEdit *TcpPort; - void __fastcall FormShow(TObject *Sender); - void __fastcall BtnOkClick(TObject *Sender); - void __fastcall OutTcpPortClick(TObject *Sender); -private: - void __fastcall UpdatePortList(void); - void __fastcall UpdateEnable(void); -public: - AnsiString Path,Cmds[2]; - int Opt,CmdEna[2]; - __fastcall TSerialOptDialog(TComponent* Owner); +class TSerialOptDialog : public TForm { + __published : TButton *BtnOk; + TButton *BtnCancel; + TComboBox *BitRate; + TLabel *Label1; + TLabel *Label3; + TComboBox *Port; + TLabel *Label2; + TComboBox *ByteSize; + TLabel *Label4; + TComboBox *Parity; + TLabel *Label5; + TComboBox *StopBits; + TLabel *Label8; + TComboBox *FlowCtr; + TCheckBox *OutTcpPort; + TEdit *TcpPort; + void __fastcall FormShow(TObject *Sender); + void __fastcall BtnOkClick(TObject *Sender); + void __fastcall OutTcpPortClick(TObject *Sender); + + private: + void __fastcall UpdatePortList(void); + void __fastcall UpdateEnable(void); + + public: + AnsiString Path, Cmds[2]; + int Opt, CmdEna[2]; + __fastcall TSerialOptDialog(TComponent *Owner); }; //--------------------------------------------------------------------------- extern PACKAGE TSerialOptDialog *SerialOptDialog; diff --git a/app/winapp/appcmn/tcpoptdlg.cpp b/app/winapp/appcmn/tcpoptdlg.cpp index 387e9f103..1ea531840 100644 --- a/app/winapp/appcmn/tcpoptdlg.cpp +++ b/app/winapp/appcmn/tcpoptdlg.cpp @@ -1,179 +1,171 @@ //--------------------------------------------------------------------------- -#include #include +#include #pragma hdrstop -#include "rtklib.h" #include "tcpoptdlg.h" + #include "mntpoptdlg.h" +#include "rtklib.h" //--------------------------------------------------------------------------- #pragma package(smart_init) #pragma resource "*.dfm" TTcpOptDialog *TcpOptDialog; -#define NTRIP_TIMEOUT 5000 // response timeout (ms) -#define NTRIP_CYCLE 50 // processing cycle (ms) -#define MAXSRCTBL 512000 // max source table size (bytes) -#define ENDSRCTBL "ENDSOURCETABLE" // end marker of table -#define MAXLINE 1024 // max line size (byte) +#define NTRIP_TIMEOUT 5000 // response timeout (ms) +#define NTRIP_CYCLE 50 // processing cycle (ms) +#define MAXSRCTBL 512000 // max source table size (bytes) +#define ENDSRCTBL "ENDSOURCETABLE" // end marker of table +#define MAXLINE 1024 // max line size (byte) static char buff[MAXSRCTBL]; //--------------------------------------------------------------------------- -__fastcall TTcpOptDialog::TTcpOptDialog(TComponent* Owner) - : TForm(Owner) -{ -} +__fastcall TTcpOptDialog::TTcpOptDialog(TComponent *Owner) : TForm(Owner) {} //--------------------------------------------------------------------------- -void __fastcall TTcpOptDialog::FormShow(TObject *Sender) -{ - char buff[2048],*p,*q; - char *port=(char *)"",*mntpnt=(char *)"",*user=(char *)""; - char *passwd=(char *)"",*str=(char *)""; - const char *ti[]={"TCP Server Options ","TCP Client Options", - "NTRIP Server Options","NTRIP Client Options", - "NTRIP Caster Options", - "NTRIP Caster Server Options", "UDP Server Options", - "UDP Client Options"}; - - strcpy(buff,Path.c_str()); - - if (!(p=strchr(buff,'@'))) p=buff; - - if ((p=strchr(p,'/'))) { - if ((q=strchr(p+1,':'))) { - *q='\0'; str=q+1; - } - *p='\0'; mntpnt=p+1; - } - if ((p=strrchr(buff,'@'))) { - *p++='\0'; - if ((q=strchr(buff,':'))) { - *q='\0'; passwd=q+1; - } - user=buff; - } - else p=buff; - - if ((q=strchr(p,':'))) { - *q='\0'; port=q+1; - } - Caption=ti[Opt]; - LabelAddr ->Caption=(Opt>=2&&Opt<=5)?"NTRIP Caster Address":"Server Address"; - LabelAddr ->Enabled=(Opt>=1&&Opt<=3)||Opt==7; - Addr ->Enabled=(Opt>=1&&Opt<=3)||Opt==7; - LabelMntPnt->Enabled=(Opt>=2&&Opt<=4); - MntPnt ->Enabled=(Opt>=2&&Opt<=4); - LabelUser ->Enabled=(Opt>=3&&Opt<=4); - User ->Enabled=(Opt>=3&&Opt<=4); - LabelPasswd->Enabled=(Opt>=2&&Opt<=5); - Passwd ->Enabled=(Opt>=2&&Opt<=5); - BtnNtrip ->Visible=(Opt==3); - BtnBrows ->Visible=(Opt==3); - BtnMountp ->Visible=(Opt==2||Opt==4); - - Addr ->Text=p; - Port ->Text=port; - MntPnt->Text=mntpnt; - User ->Text=user; - Passwd->Text=passwd; - if (Opt==2||Opt==4) { - MntpStr=str; - } - Addr->Items->Clear(); - for (int i=0;iItems->Add(History[i]); - } +void __fastcall TTcpOptDialog::FormShow(TObject *Sender) { + char buff[2048], *p, *q; + char *port = (char *)"", *mntpnt = (char *)"", *user = (char *)""; + char *passwd = (char *)"", *str = (char *)""; + const char *ti[] = {"TCP Server Options ", "TCP Client Options", "NTRIP Server Options", + "NTRIP Client Options", "NTRIP Caster Options", "NTRIP Caster Server Options", + "UDP Server Options", "UDP Client Options"}; + + strcpy(buff, Path.c_str()); + + if (!(p = strchr(buff, '@'))) p = buff; + + if ((p = strchr(p, '/'))) { + if ((q = strchr(p + 1, ':'))) { + *q = '\0'; + str = q + 1; + } + *p = '\0'; + mntpnt = p + 1; + } + if ((p = strrchr(buff, '@'))) { + *p++ = '\0'; + if ((q = strchr(buff, ':'))) { + *q = '\0'; + passwd = q + 1; + } + user = buff; + } else + p = buff; + + if ((q = strchr(p, ':'))) { + *q = '\0'; + port = q + 1; + } + Caption = ti[Opt]; + LabelAddr->Caption = (Opt >= 2 && Opt <= 5) ? "NTRIP Caster Address" : "Server Address"; + LabelAddr->Enabled = (Opt >= 1 && Opt <= 3) || Opt == 7; + Addr->Enabled = (Opt >= 1 && Opt <= 3) || Opt == 7; + LabelMntPnt->Enabled = (Opt >= 2 && Opt <= 4); + MntPnt->Enabled = (Opt >= 2 && Opt <= 4); + LabelUser->Enabled = (Opt >= 3 && Opt <= 4); + User->Enabled = (Opt >= 3 && Opt <= 4); + LabelPasswd->Enabled = (Opt >= 2 && Opt <= 5); + Passwd->Enabled = (Opt >= 2 && Opt <= 5); + BtnNtrip->Visible = (Opt == 3); + BtnBrows->Visible = (Opt == 3); + BtnMountp->Visible = (Opt == 2 || Opt == 4); + + Addr->Text = p; + Port->Text = port; + MntPnt->Text = mntpnt; + User->Text = user; + Passwd->Text = passwd; + if (Opt == 2 || Opt == 4) { + MntpStr = str; + } + Addr->Items->Clear(); + for (int i = 0; i < MAXHIST; i++) { + if (History[i] != "") Addr->Items->Add(History[i]); + } } //--------------------------------------------------------------------------- -void __fastcall TTcpOptDialog::BtnOkClick(TObject *Sender) -{ - AnsiString User_Text=User->Text,Passwd_Text=Passwd->Text; - AnsiString Addr_Text=Addr->Text,Port_Text=Port->Text; - AnsiString MntPnt_Text=MntPnt->Text,s; - - Path=s.sprintf("%s:%s@%s:%s/%s:%s",User_Text.c_str(),Passwd_Text.c_str(), - Addr_Text.c_str(),Port_Text.c_str(),MntPnt_Text.c_str(), - MntpStr.c_str()); - AddHist(Addr,History); +void __fastcall TTcpOptDialog::BtnOkClick(TObject *Sender) { + AnsiString User_Text = User->Text, Passwd_Text = Passwd->Text; + AnsiString Addr_Text = Addr->Text, Port_Text = Port->Text; + AnsiString MntPnt_Text = MntPnt->Text, s; + + Path = s.sprintf("%s:%s@%s:%s/%s:%s", User_Text.c_str(), Passwd_Text.c_str(), Addr_Text.c_str(), + Port_Text.c_str(), MntPnt_Text.c_str(), MntpStr.c_str()); + AddHist(Addr, History); } //--------------------------------------------------------------------------- -void __fastcall TTcpOptDialog::AddHist(TComboBox *list, AnsiString *hist) -{ - for (int i=0;iText!=hist[i]) continue; - for (int j=i+1;j0;i--) hist[i]=hist[i-1]; - hist[0]=list->Text; - - list->Clear(); - for (int i=0;iItems->Add(hist[i]); - } +void __fastcall TTcpOptDialog::AddHist(TComboBox *list, AnsiString *hist) { + for (int i = 0; i < MAXHIST; i++) { + if (list->Text != hist[i]) continue; + for (int j = i + 1; j < MAXHIST; j++) hist[j - 1] = hist[j]; + hist[MAXHIST - 1] = ""; + } + for (int i = MAXHIST - 1; i > 0; i--) hist[i] = hist[i - 1]; + hist[0] = list->Text; + + list->Clear(); + for (int i = 0; i < MAXHIST; i++) { + if (hist[i] != "") list->Items->Add(hist[i]); + } } //--------------------------------------------------------------------------- -void __fastcall TTcpOptDialog::BtnNtripClick(TObject *Sender) -{ - TButton *btn=(TButton *)Sender; - AnsiString path=Addr->Text+":"+Port->Text; - stream_t str; - uint32_t tick=tickget(); - char *p=buff,msg[MAXSTRMSG],mntpnt[256]; - - strinit(&str); - if (!stropen(&str,STR_NTRIPCLI,STR_MODE_R,path.c_str())) return; - - btn->Enabled=false; - *p='\0'; - while (pNTRIP_TIMEOUT) break; - } - strclose(&str); - - MntPnt->Clear(); - for (p=buff;(p=strstr(p,"STR;"));p+=4) { - if (sscanf(p,"STR;%255[^;]",mntpnt)==1) { - MntPnt->AddItem(mntpnt,NULL); - } - } - btn->Enabled=true; +void __fastcall TTcpOptDialog::BtnNtripClick(TObject *Sender) { + TButton *btn = (TButton *)Sender; + AnsiString path = Addr->Text + ":" + Port->Text; + stream_t str; + uint32_t tick = tickget(); + char *p = buff, msg[MAXSTRMSG], mntpnt[256]; + + strinit(&str); + if (!stropen(&str, STR_NTRIPCLI, STR_MODE_R, path.c_str())) return; + + btn->Enabled = false; + *p = '\0'; + while (p < buff + MAXSRCTBL - 1) { + p += strread(&str, (uint8_t *)p, buff + MAXSRCTBL - p - 1); + *p = '\0'; + sleepms(NTRIP_CYCLE); + if (strstr(buff, ENDSRCTBL)) break; + if ((int)(tickget() - tick) > NTRIP_TIMEOUT) break; + } + strclose(&str); + + MntPnt->Clear(); + for (p = buff; (p = strstr(p, "STR;")); p += 4) { + if (sscanf(p, "STR;%255[^;]", mntpnt) == 1) { + MntPnt->AddItem(mntpnt, NULL); + } + } + btn->Enabled = true; } //--------------------------------------------------------------------------- -void __fastcall TTcpOptDialog::BtnBrowsClick(TObject *Sender) -{ - AnsiString Addr_Text=Addr->Text; - AnsiString Port_Text=Port->Text; - if (Port_Text!="") Addr_Text+=":"+Port_Text; - ExecCmd("srctblbrows "+Addr_Text,1); +void __fastcall TTcpOptDialog::BtnBrowsClick(TObject *Sender) { + AnsiString Addr_Text = Addr->Text; + AnsiString Port_Text = Port->Text; + if (Port_Text != "") Addr_Text += ":" + Port_Text; + ExecCmd("srctblbrows " + Addr_Text, 1); } //--------------------------------------------------------------------------- -void __fastcall TTcpOptDialog::BtnMountpClick(TObject *Sender) -{ - MntpOptDialog->MntPnt=MntPnt->Text; - MntpOptDialog->MntpStr=MntpStr; - if (MntpOptDialog->ShowModal()!=mrOk) return; - MntPnt->Text=MntpOptDialog->MntPnt; - MntpStr=MntpOptDialog->MntpStr; +void __fastcall TTcpOptDialog::BtnMountpClick(TObject *Sender) { + MntpOptDialog->MntPnt = MntPnt->Text; + MntpOptDialog->MntpStr = MntpStr; + if (MntpOptDialog->ShowModal() != mrOk) return; + MntPnt->Text = MntpOptDialog->MntPnt; + MntpStr = MntpOptDialog->MntpStr; } //--------------------------------------------------------------------------- -int __fastcall TTcpOptDialog::ExecCmd(AnsiString cmd, int show) -{ - PROCESS_INFORMATION info; - STARTUPINFO si={0}; - si.cb=sizeof(si); - char *p=cmd.c_str(); - - if (!CreateProcess(NULL,p,NULL,NULL,false,show?0:CREATE_NO_WINDOW,NULL, - NULL,&si,&info)) return 0; - CloseHandle(info.hProcess); - CloseHandle(info.hThread); - return 1; +int __fastcall TTcpOptDialog::ExecCmd(AnsiString cmd, int show) { + PROCESS_INFORMATION info; + STARTUPINFO si = {0}; + si.cb = sizeof(si); + char *p = cmd.c_str(); + + if (!CreateProcess(NULL, p, NULL, NULL, false, show ? 0 : CREATE_NO_WINDOW, NULL, NULL, &si, + &info)) + return 0; + CloseHandle(info.hProcess); + CloseHandle(info.hThread); + return 1; } //--------------------------------------------------------------------------- - diff --git a/app/winapp/appcmn/tcpoptdlg.h b/app/winapp/appcmn/tcpoptdlg.h index 820dfab2a..4607e3ace 100644 --- a/app/winapp/appcmn/tcpoptdlg.h +++ b/app/winapp/appcmn/tcpoptdlg.h @@ -4,42 +4,42 @@ //--------------------------------------------------------------------------- #include #include -#include #include +#include -#define MAXHIST 10 +#define MAXHIST 10 //--------------------------------------------------------------------------- -class TTcpOptDialog : public TForm -{ -__published: - TButton *BtnCancel; - TButton *BtnOk; - TEdit *Port; - TLabel *LabelAddr; - TLabel *LabelPort; - TEdit *User; - TEdit *Passwd; - TLabel *LabelUser; - TLabel *LabelPasswd; - TLabel *LabelMntPnt; - TComboBox *Addr; - TComboBox *MntPnt; - TButton *BtnNtrip; - TButton *BtnMountp; - TButton *BtnBrows; - void __fastcall FormShow(TObject *Sender); - void __fastcall BtnOkClick(TObject *Sender); - void __fastcall BtnNtripClick(TObject *Sender); - void __fastcall BtnMountpClick(TObject *Sender); - void __fastcall BtnBrowsClick(TObject *Sender); -private: - int __fastcall ExecCmd(AnsiString cmd, int show); - void __fastcall AddHist(TComboBox *list, AnsiString *hist); -public: - int Opt; - AnsiString Path,MntpStr,History[MAXHIST]; - __fastcall TTcpOptDialog(TComponent* Owner); +class TTcpOptDialog : public TForm { + __published : TButton *BtnCancel; + TButton *BtnOk; + TEdit *Port; + TLabel *LabelAddr; + TLabel *LabelPort; + TEdit *User; + TEdit *Passwd; + TLabel *LabelUser; + TLabel *LabelPasswd; + TLabel *LabelMntPnt; + TComboBox *Addr; + TComboBox *MntPnt; + TButton *BtnNtrip; + TButton *BtnMountp; + TButton *BtnBrows; + void __fastcall FormShow(TObject *Sender); + void __fastcall BtnOkClick(TObject *Sender); + void __fastcall BtnNtripClick(TObject *Sender); + void __fastcall BtnMountpClick(TObject *Sender); + void __fastcall BtnBrowsClick(TObject *Sender); + + private: + int __fastcall ExecCmd(AnsiString cmd, int show); + void __fastcall AddHist(TComboBox *list, AnsiString *hist); + + public: + int Opt; + AnsiString Path, MntpStr, History[MAXHIST]; + __fastcall TTcpOptDialog(TComponent *Owner); }; //--------------------------------------------------------------------------- extern PACKAGE TTcpOptDialog *TcpOptDialog; diff --git a/app/winapp/appcmn/timedlg.cpp b/app/winapp/appcmn/timedlg.cpp index 371ad4048..c8ee756f5 100644 --- a/app/winapp/appcmn/timedlg.cpp +++ b/app/winapp/appcmn/timedlg.cpp @@ -8,30 +8,26 @@ #pragma resource "*.dfm" TTimeDialog *TimeDialog; //--------------------------------------------------------------------------- -__fastcall TTimeDialog::TTimeDialog(TComponent* Owner) - : TForm(Owner) -{ -} +__fastcall TTimeDialog::TTimeDialog(TComponent *Owner) : TForm(Owner) {} //--------------------------------------------------------------------------- -void __fastcall TTimeDialog::FormShow(TObject *Sender) -{ - gtime_t utc; - double tow,doy; - int week; - char msg[1024],s1[40],s2[40],*p=msg; - utc=gpst2utc(Time); - time2str(Time,s1,0); - time2str(utc,s2,0); - tow=time2gpst(Time,&week); - doy=time2doy(Time); - p+=sprintf(p,"%s GPST\n",s1); - p+=sprintf(p,"%s UTC\n\n",s2); - p+=sprintf(p,"GPS Week: %d\n",week); - p+=sprintf(p,"GPS Time: %.0f s\n",tow); - p+=sprintf(p,"Day of Year: %03d\n",(int)floor(doy)); - p+=sprintf(p,"Day of Week: %d\n",(int)floor(tow/86400.0)); - p+=sprintf(p,"Time of Day: %.0f s\n",fmod(tow,86400.0)); - sprintf(p,"Leap Seconds: %.0f s\n",timediff(Time,utc)); - Message->Caption=msg; +void __fastcall TTimeDialog::FormShow(TObject *Sender) { + gtime_t utc; + double tow, doy; + int week; + char msg[1024], s1[40], s2[40], *p = msg; + utc = gpst2utc(Time); + time2str(Time, s1, 0); + time2str(utc, s2, 0); + tow = time2gpst(Time, &week); + doy = time2doy(Time); + p += sprintf(p, "%s GPST\n", s1); + p += sprintf(p, "%s UTC\n\n", s2); + p += sprintf(p, "GPS Week: %d\n", week); + p += sprintf(p, "GPS Time: %.0f s\n", tow); + p += sprintf(p, "Day of Year: %03d\n", (int)floor(doy)); + p += sprintf(p, "Day of Week: %d\n", (int)floor(tow / 86400.0)); + p += sprintf(p, "Time of Day: %.0f s\n", fmod(tow, 86400.0)); + sprintf(p, "Leap Seconds: %.0f s\n", timediff(Time, utc)); + Message->Caption = msg; } //--------------------------------------------------------------------------- diff --git a/app/winapp/appcmn/timedlg.h b/app/winapp/appcmn/timedlg.h index cb3754a20..26d5964b5 100644 --- a/app/winapp/appcmn/timedlg.h +++ b/app/winapp/appcmn/timedlg.h @@ -4,20 +4,20 @@ //--------------------------------------------------------------------------- #include #include -#include #include +#include + #include "rtklib.h" //--------------------------------------------------------------------------- -class TTimeDialog : public TForm -{ -__published: - TButton *BtnOk; - TLabel *Message; - void __fastcall FormShow(TObject *Sender); -private: -public: - gtime_t Time; - __fastcall TTimeDialog(TComponent* Owner); +class TTimeDialog : public TForm { + __published : TButton *BtnOk; + TLabel *Message; + void __fastcall FormShow(TObject *Sender); + + private: + public: + gtime_t Time; + __fastcall TTimeDialog(TComponent *Owner); }; //--------------------------------------------------------------------------- extern PACKAGE TTimeDialog *TimeDialog; diff --git a/app/winapp/appcmn/tspandlg.cpp b/app/winapp/appcmn/tspandlg.cpp index b58aa7d33..a85c101f8 100644 --- a/app/winapp/appcmn/tspandlg.cpp +++ b/app/winapp/appcmn/tspandlg.cpp @@ -2,220 +2,231 @@ #include #pragma hdrstop -#include "rtklib.h" +#include "tspandlg.h" + #include "plotmain.h" +#include "rtklib.h" #include "timedlg.h" -#include "tspandlg.h" //--------------------------------------------------------------------------- #pragma package(smart_init) #pragma resource "*.dfm" TSpanDialog *SpanDialog; //--------------------------------------------------------------------------- -static double str2dbl(AnsiString str) -{ - double val=0.0; - sscanf(str.c_str(),"%lf",&val); - return val; -} -//--------------------------------------------------------------------------- -__fastcall TSpanDialog::TSpanDialog(TComponent* Owner) - : TForm(Owner) -{ - for (int i=0;i<3;i++) { - TimeEna[i]=true; - TimeVal[i]=true; - } -} -//--------------------------------------------------------------------------- -void __fastcall TSpanDialog::FormShow(TObject *Sender) -{ - char ts[40],te[40]; - AnsiString s; - TimeStartF->Checked=TimeEna[0]; - TimeEndF ->Checked=TimeEna[1]; - TimeIntF ->Checked=TimeEna[2]; - time2str(TimeStart,ts,0); ts[10]='\0'; - time2str(TimeEnd, te,0); te[10]='\0'; - TimeY1->Text=ts; - TimeH1->Text=ts+11; - TimeY2->Text=te; - TimeH2->Text=te+11; - EditTimeInt->Text=s.sprintf("%g",TimeInt); - UpdateEnable(); -} -//--------------------------------------------------------------------------- -void __fastcall TSpanDialog::BtnOkClick(TObject *Sender) -{ - AnsiString TimeY1_Text=TimeY1->Text,TimeH1_Text=TimeH1->Text; - AnsiString TimeY2_Text=TimeY2->Text,TimeH2_Text=TimeH2->Text; - AnsiString EditTimeInt_Text=EditTimeInt->Text; - double eps[]={2000,1,1,0,0,0},epe[]={2000,1,1,0,0,0}; - - TimeEna[0]=TimeStartF->Checked; - TimeEna[1]=TimeEndF ->Checked; - TimeEna[2]=TimeIntF ->Checked; - sscanf(TimeY1_Text.c_str(),"%lf/%lf/%lf",eps,eps+1,eps+2); - sscanf(TimeH1_Text.c_str(),"%lf:%lf:%lf",eps+3,eps+4,eps+5); - sscanf(TimeY2_Text.c_str(),"%lf/%lf/%lf",epe,epe+1,epe+2); - sscanf(TimeH2_Text.c_str(),"%lf:%lf:%lf",epe+3,epe+4,epe+5); - TimeStart=epoch2time(eps); - TimeEnd=epoch2time(epe); - TimeInt=str2dbl(EditTimeInt_Text); -} -//--------------------------------------------------------------------------- -void __fastcall TSpanDialog::TimeStartFClick(TObject *Sender) -{ - UpdateEnable(); -} -//--------------------------------------------------------------------------- -void __fastcall TSpanDialog::TimeEndFClick(TObject *Sender) -{ - UpdateEnable(); -} -//--------------------------------------------------------------------------- -void __fastcall TSpanDialog::TimeIntFClick(TObject *Sender) -{ - UpdateEnable(); -} -//--------------------------------------------------------------------------- -void __fastcall TSpanDialog::TimeY1UDChangingEx(TObject *Sender, - bool &AllowChange, int NewValue, TUpDownDirection Direction) -{ - AnsiString TimeY1_Text=TimeY1->Text,s; - double ep[]={2000,1,1,0,0,0}; - int p=TimeY1->SelStart,ud=Direction==updUp?1:-1; - sscanf(TimeY1_Text.c_str(),"%lf/%lf/%lf",ep,ep+1,ep+2); - if (412) {ep[0]++; ep[1]-=12;} - } - else if (p>7||p==0) ep[2]+=ud; else ep[0]+=ud; - time2epoch(epoch2time(ep),ep); - TimeY1->Text=s.sprintf("%04.0f/%02.0f/%02.0f",ep[0],ep[1],ep[2]); - TimeY1->SelStart=p>7||p==0?10:(p>4?7:4); -} -//--------------------------------------------------------------------------- -void __fastcall TSpanDialog::TimeH1UDChangingEx(TObject *Sender, - bool &AllowChange, int NewValue, TUpDownDirection Direction) -{ - AnsiString TimeH1_Text=TimeH1->Text,s; - int hms[3]={0},sec,p=TimeH1->SelStart,ud=Direction==updUp?1:-1; - sscanf(TimeH1_Text.c_str(),"%d:%d:%d",hms,hms+1,hms+2); - if (p>5||p==0) hms[2]+=ud; else if (p>2) hms[1]+=ud; else hms[0]+=ud; - sec=hms[0]*3600+hms[1]*60+hms[2]; - if (sec<0) sec+=86400; else if (sec>=86400) sec-=86400; - TimeH1->Text=s.sprintf("%02d:%02d:%02d",sec/3600,(sec%3600)/60,sec%60); - TimeH1->SelStart=p>5||p==0?8:(p>2?5:2); -} -//--------------------------------------------------------------------------- -void __fastcall TSpanDialog::TimeY2UDChangingEx(TObject *Sender, - bool &AllowChange, int NewValue, TUpDownDirection Direction) -{ - AnsiString TimeY2_Text=TimeY2->Text,s; - double ep[]={2000,1,1,0,0,0}; - int p=TimeY2->SelStart,ud=Direction==updUp?1:-1; - sscanf(TimeY2_Text.c_str(),"%lf/%lf/%lf",ep,ep+1,ep+2); - if (412) {ep[0]++; ep[1]-=12;} - } - else if (p>7||p==0) ep[2]+=ud; else ep[0]+=ud; - time2epoch(epoch2time(ep),ep); - TimeY2->Text=s.sprintf("%04.0f/%02.0f/%02.0f",ep[0],ep[1],ep[2]); - TimeY2->SelStart=p>7||p==0?10:(p>4?7:4); -} -//--------------------------------------------------------------------------- -void __fastcall TSpanDialog::TimeH2UDChangingEx(TObject *Sender, - bool &AllowChange, int NewValue, TUpDownDirection Direction) -{ - AnsiString TimeH2_Text=TimeH2->Text,s; - int hms[3]={0},sec,p=TimeH2->SelStart,ud=Direction==updUp?1:-1; - sscanf(TimeH2_Text.c_str(),"%d:%d:%d",hms,hms+1,hms+2); - if (p>5||p==0) hms[2]+=ud; else if (p>2) hms[1]+=ud; else hms[0]+=ud; - sec=hms[0]*3600+hms[1]*60+hms[2]; - if (sec<0) sec+=86400; else if (sec>=86400) sec-=86400; - TimeH2->Text=s.sprintf("%02d:%02d:%02d",sec/3600,(sec%3600)/60,sec%60); - TimeH2->SelStart=p>5||p==0?8:(p>2?5:2); +static double str2dbl(AnsiString str) { + double val = 0.0; + sscanf(str.c_str(), "%lf", &val); + return val; +} +//--------------------------------------------------------------------------- +__fastcall TSpanDialog::TSpanDialog(TComponent *Owner) : TForm(Owner) { + for (int i = 0; i < 3; i++) { + TimeEna[i] = true; + TimeVal[i] = true; + } +} +//--------------------------------------------------------------------------- +void __fastcall TSpanDialog::FormShow(TObject *Sender) { + char ts[40], te[40]; + AnsiString s; + TimeStartF->Checked = TimeEna[0]; + TimeEndF->Checked = TimeEna[1]; + TimeIntF->Checked = TimeEna[2]; + time2str(TimeStart, ts, 0); + ts[10] = '\0'; + time2str(TimeEnd, te, 0); + te[10] = '\0'; + TimeY1->Text = ts; + TimeH1->Text = ts + 11; + TimeY2->Text = te; + TimeH2->Text = te + 11; + EditTimeInt->Text = s.sprintf("%g", TimeInt); + UpdateEnable(); +} +//--------------------------------------------------------------------------- +void __fastcall TSpanDialog::BtnOkClick(TObject *Sender) { + AnsiString TimeY1_Text = TimeY1->Text, TimeH1_Text = TimeH1->Text; + AnsiString TimeY2_Text = TimeY2->Text, TimeH2_Text = TimeH2->Text; + AnsiString EditTimeInt_Text = EditTimeInt->Text; + double eps[] = {2000, 1, 1, 0, 0, 0}, epe[] = {2000, 1, 1, 0, 0, 0}; + + TimeEna[0] = TimeStartF->Checked; + TimeEna[1] = TimeEndF->Checked; + TimeEna[2] = TimeIntF->Checked; + sscanf(TimeY1_Text.c_str(), "%lf/%lf/%lf", eps, eps + 1, eps + 2); + sscanf(TimeH1_Text.c_str(), "%lf:%lf:%lf", eps + 3, eps + 4, eps + 5); + sscanf(TimeY2_Text.c_str(), "%lf/%lf/%lf", epe, epe + 1, epe + 2); + sscanf(TimeH2_Text.c_str(), "%lf:%lf:%lf", epe + 3, epe + 4, epe + 5); + TimeStart = epoch2time(eps); + TimeEnd = epoch2time(epe); + TimeInt = str2dbl(EditTimeInt_Text); +} +//--------------------------------------------------------------------------- +void __fastcall TSpanDialog::TimeStartFClick(TObject *Sender) { UpdateEnable(); } +//--------------------------------------------------------------------------- +void __fastcall TSpanDialog::TimeEndFClick(TObject *Sender) { UpdateEnable(); } +//--------------------------------------------------------------------------- +void __fastcall TSpanDialog::TimeIntFClick(TObject *Sender) { UpdateEnable(); } +//--------------------------------------------------------------------------- +void __fastcall TSpanDialog::TimeY1UDChangingEx(TObject *Sender, bool &AllowChange, int NewValue, + TUpDownDirection Direction) { + AnsiString TimeY1_Text = TimeY1->Text, s; + double ep[] = {2000, 1, 1, 0, 0, 0}; + int p = TimeY1->SelStart, ud = Direction == updUp ? 1 : -1; + sscanf(TimeY1_Text.c_str(), "%lf/%lf/%lf", ep, ep + 1, ep + 2); + if (4 < p && p < 8) { + ep[1] += ud; + if (ep[1] <= 0) { + ep[0]--; + ep[1] += 12; + } else if (ep[1] > 12) { + ep[0]++; + ep[1] -= 12; + } + } else if (p > 7 || p == 0) + ep[2] += ud; + else + ep[0] += ud; + time2epoch(epoch2time(ep), ep); + TimeY1->Text = s.sprintf("%04.0f/%02.0f/%02.0f", ep[0], ep[1], ep[2]); + TimeY1->SelStart = p > 7 || p == 0 ? 10 : (p > 4 ? 7 : 4); +} +//--------------------------------------------------------------------------- +void __fastcall TSpanDialog::TimeH1UDChangingEx(TObject *Sender, bool &AllowChange, int NewValue, + TUpDownDirection Direction) { + AnsiString TimeH1_Text = TimeH1->Text, s; + int hms[3] = {0}, sec, p = TimeH1->SelStart, ud = Direction == updUp ? 1 : -1; + sscanf(TimeH1_Text.c_str(), "%d:%d:%d", hms, hms + 1, hms + 2); + if (p > 5 || p == 0) + hms[2] += ud; + else if (p > 2) + hms[1] += ud; + else + hms[0] += ud; + sec = hms[0] * 3600 + hms[1] * 60 + hms[2]; + if (sec < 0) + sec += 86400; + else if (sec >= 86400) + sec -= 86400; + TimeH1->Text = s.sprintf("%02d:%02d:%02d", sec / 3600, (sec % 3600) / 60, sec % 60); + TimeH1->SelStart = p > 5 || p == 0 ? 8 : (p > 2 ? 5 : 2); +} +//--------------------------------------------------------------------------- +void __fastcall TSpanDialog::TimeY2UDChangingEx(TObject *Sender, bool &AllowChange, int NewValue, + TUpDownDirection Direction) { + AnsiString TimeY2_Text = TimeY2->Text, s; + double ep[] = {2000, 1, 1, 0, 0, 0}; + int p = TimeY2->SelStart, ud = Direction == updUp ? 1 : -1; + sscanf(TimeY2_Text.c_str(), "%lf/%lf/%lf", ep, ep + 1, ep + 2); + if (4 < p && p < 8) { + ep[1] += ud; + if (ep[1] <= 0) { + ep[0]--; + ep[1] += 12; + } else if (ep[1] > 12) { + ep[0]++; + ep[1] -= 12; + } + } else if (p > 7 || p == 0) + ep[2] += ud; + else + ep[0] += ud; + time2epoch(epoch2time(ep), ep); + TimeY2->Text = s.sprintf("%04.0f/%02.0f/%02.0f", ep[0], ep[1], ep[2]); + TimeY2->SelStart = p > 7 || p == 0 ? 10 : (p > 4 ? 7 : 4); +} +//--------------------------------------------------------------------------- +void __fastcall TSpanDialog::TimeH2UDChangingEx(TObject *Sender, bool &AllowChange, int NewValue, + TUpDownDirection Direction) { + AnsiString TimeH2_Text = TimeH2->Text, s; + int hms[3] = {0}, sec, p = TimeH2->SelStart, ud = Direction == updUp ? 1 : -1; + sscanf(TimeH2_Text.c_str(), "%d:%d:%d", hms, hms + 1, hms + 2); + if (p > 5 || p == 0) + hms[2] += ud; + else if (p > 2) + hms[1] += ud; + else + hms[0] += ud; + sec = hms[0] * 3600 + hms[1] * 60 + hms[2]; + if (sec < 0) + sec += 86400; + else if (sec >= 86400) + sec -= 86400; + TimeH2->Text = s.sprintf("%02d:%02d:%02d", sec / 3600, (sec % 3600) / 60, sec % 60); + TimeH2->SelStart = p > 5 || p == 0 ? 8 : (p > 2 ? 5 : 2); } //--------------------------------------------------------------------------- void __fastcall TSpanDialog::TimeY1KeyDown(TObject *Sender, WORD &Key, TShiftState Shift) { - bool allowchange; - if (Key==VK_UP||Key==VK_DOWN) { - TimeY1UDChangingEx(Sender,allowchange,0,Key==VK_UP?updUp:updDown); - Key=0; - } + bool allowchange; + if (Key == VK_UP || Key == VK_DOWN) { + TimeY1UDChangingEx(Sender, allowchange, 0, Key == VK_UP ? updUp : updDown); + Key = 0; + } } //--------------------------------------------------------------------------- void __fastcall TSpanDialog::TimeH1KeyDown(TObject *Sender, WORD &Key, TShiftState Shift) { - bool allowchange; - if (Key==VK_UP||Key==VK_DOWN) { - TimeH1UDChangingEx(Sender,allowchange,0,Key==VK_UP?updUp:updDown); - Key=0; - } + bool allowchange; + if (Key == VK_UP || Key == VK_DOWN) { + TimeH1UDChangingEx(Sender, allowchange, 0, Key == VK_UP ? updUp : updDown); + Key = 0; + } } //--------------------------------------------------------------------------- void __fastcall TSpanDialog::TimeY2KeyDown(TObject *Sender, WORD &Key, TShiftState Shift) { - bool allowchange; - if (Key==VK_UP||Key==VK_DOWN) { - TimeY2UDChangingEx(Sender,allowchange,0,Key==VK_UP?updUp:updDown); - Key=0; - } + bool allowchange; + if (Key == VK_UP || Key == VK_DOWN) { + TimeY2UDChangingEx(Sender, allowchange, 0, Key == VK_UP ? updUp : updDown); + Key = 0; + } } //--------------------------------------------------------------------------- void __fastcall TSpanDialog::TimeH2KeyDown(TObject *Sender, WORD &Key, TShiftState Shift) { - bool allowchange; - if (Key==VK_UP||Key==VK_DOWN) { - TimeH2UDChangingEx(Sender,allowchange,0,Key==VK_UP?updUp:updDown); - Key=0; - } + bool allowchange; + if (Key == VK_UP || Key == VK_DOWN) { + TimeH2UDChangingEx(Sender, allowchange, 0, Key == VK_UP ? updUp : updDown); + Key = 0; + } +} +//--------------------------------------------------------------------------- +void __fastcall TSpanDialog::UpdateEnable(void) { + TimeY1->Enabled = TimeStartF->Checked && TimeVal[0]; + TimeH1->Enabled = TimeStartF->Checked && TimeVal[0]; + TimeY2->Enabled = TimeEndF->Checked && TimeVal[1]; + TimeH2->Enabled = TimeEndF->Checked && TimeVal[1]; + TimeY1UD->Enabled = TimeStartF->Checked && TimeVal[0]; + TimeH1UD->Enabled = TimeStartF->Checked && TimeVal[0]; + TimeY2UD->Enabled = TimeEndF->Checked && TimeVal[1]; + TimeH2UD->Enabled = TimeEndF->Checked && TimeVal[1]; + EditTimeInt->Enabled = TimeIntF->Checked && TimeVal[2]; + BtnTime1->Enabled = TimeStartF->Checked && TimeVal[0]; + BtnTime2->Enabled = TimeEndF->Checked && TimeVal[1]; + TimeStartF->Enabled = TimeVal[0] == 1; + TimeEndF->Enabled = TimeVal[1] == 1; + TimeIntF->Enabled = TimeVal[2] == 1; +} +//--------------------------------------------------------------------------- +void __fastcall TSpanDialog::BtnTime1Click(TObject *Sender) { + AnsiString TimeY1_Text = TimeY1->Text, TimeH1_Text = TimeH1->Text; + double ep[] = {2000, 1, 1, 0, 0, 0}; + sscanf(TimeY1_Text.c_str(), "%lf/%lf/%lf", ep, ep + 1, ep + 2); + sscanf(TimeH1_Text.c_str(), "%lf:%lf:%lf", ep + 3, ep + 4, ep + 5); + TimeDialog->Time = epoch2time(ep); + TimeDialog->ShowModal(); +} +//--------------------------------------------------------------------------- +void __fastcall TSpanDialog::BtnTime2Click(TObject *Sender) { + AnsiString TimeY2_Text = TimeY2->Text, TimeH2_Text = TimeH2->Text; + double ep[] = {2000, 1, 1, 0, 0, 0}; + sscanf(TimeY2_Text.c_str(), "%lf/%lf/%lf", ep, ep + 1, ep + 2); + sscanf(TimeH2_Text.c_str(), "%lf:%lf:%lf", ep + 3, ep + 4, ep + 5); + TimeDialog->Time = epoch2time(ep); + TimeDialog->ShowModal(); } //--------------------------------------------------------------------------- -void __fastcall TSpanDialog::UpdateEnable(void) -{ - TimeY1 ->Enabled =TimeStartF->Checked&&TimeVal[0]; - TimeH1 ->Enabled =TimeStartF->Checked&&TimeVal[0]; - TimeY2 ->Enabled =TimeEndF ->Checked&&TimeVal[1]; - TimeH2 ->Enabled =TimeEndF ->Checked&&TimeVal[1]; - TimeY1UD->Enabled =TimeStartF->Checked&&TimeVal[0]; - TimeH1UD->Enabled =TimeStartF->Checked&&TimeVal[0]; - TimeY2UD->Enabled =TimeEndF ->Checked&&TimeVal[1]; - TimeH2UD->Enabled =TimeEndF ->Checked&&TimeVal[1]; - EditTimeInt->Enabled=TimeIntF ->Checked&&TimeVal[2]; - BtnTime1->Enabled =TimeStartF->Checked&&TimeVal[0]; - BtnTime2->Enabled =TimeEndF ->Checked&&TimeVal[1]; - TimeStartF->Enabled =TimeVal[0]==1; - TimeEndF ->Enabled =TimeVal[1]==1; - TimeIntF ->Enabled =TimeVal[2]==1; -} -//--------------------------------------------------------------------------- -void __fastcall TSpanDialog::BtnTime1Click(TObject *Sender) -{ - AnsiString TimeY1_Text=TimeY1->Text,TimeH1_Text=TimeH1->Text; - double ep[]={2000,1,1,0,0,0}; - sscanf(TimeY1_Text.c_str(),"%lf/%lf/%lf",ep,ep+1,ep+2); - sscanf(TimeH1_Text.c_str(),"%lf:%lf:%lf",ep+3,ep+4,ep+5); - TimeDialog->Time=epoch2time(ep); - TimeDialog->ShowModal(); -} -//--------------------------------------------------------------------------- -void __fastcall TSpanDialog::BtnTime2Click(TObject *Sender) -{ - AnsiString TimeY2_Text=TimeY2->Text,TimeH2_Text=TimeH2->Text; - double ep[]={2000,1,1,0,0,0}; - sscanf(TimeY2_Text.c_str(),"%lf/%lf/%lf",ep,ep+1,ep+2); - sscanf(TimeH2_Text.c_str(),"%lf:%lf:%lf",ep+3,ep+4,ep+5); - TimeDialog->Time=epoch2time(ep); - TimeDialog->ShowModal(); -} -//--------------------------------------------------------------------------- - diff --git a/app/winapp/appcmn/tspandlg.h b/app/winapp/appcmn/tspandlg.h index ebb3ed258..a51d43245 100644 --- a/app/winapp/appcmn/tspandlg.h +++ b/app/winapp/appcmn/tspandlg.h @@ -2,60 +2,61 @@ #ifndef tspandlgH #define tspandlgH //--------------------------------------------------------------------------- +#include #include -#include -#include -#include #include +#include #include -#include +#include +#include + #include "rtklib.h" //--------------------------------------------------------------------------- -class TSpanDialog : public TForm -{ -__published: - TButton *BtnCancel; - TButton *BtnOk; - TCheckBox *TimeStartF; - TCheckBox *TimeEndF; - TCheckBox *TimeIntF; - TEdit *TimeY2; - TEdit *TimeY1; - TUpDown *TimeY1UD; - TUpDown *TimeY2UD; - TEdit *TimeH2; - TEdit *TimeH1; - TUpDown *TimeH1UD; - TUpDown *TimeH2UD; - TSpeedButton *BtnTime2; - TSpeedButton *BtnTime1; - TComboBox *EditTimeInt; - void __fastcall BtnOkClick(TObject *Sender); - void __fastcall TimeStartFClick(TObject *Sender); - void __fastcall TimeEndFClick(TObject *Sender); - void __fastcall TimeIntFClick(TObject *Sender); - void __fastcall TimeY1UDChangingEx(TObject *Sender, bool &AllowChange, - int NewValue, TUpDownDirection Direction); - void __fastcall TimeH1UDChangingEx(TObject *Sender, bool &AllowChange, - int NewValue, TUpDownDirection Direction); - void __fastcall TimeY2UDChangingEx(TObject *Sender, bool &AllowChange, - int NewValue, TUpDownDirection Direction); - void __fastcall TimeH2UDChangingEx(TObject *Sender, bool &AllowChange, - int NewValue, TUpDownDirection Direction); - void __fastcall FormShow(TObject *Sender); - void __fastcall BtnTime1Click(TObject *Sender); - void __fastcall BtnTime2Click(TObject *Sender); - void __fastcall TimeY1KeyDown(TObject *Sender, WORD &Key, TShiftState Shift); - void __fastcall TimeH2KeyDown(TObject *Sender, WORD &Key, TShiftState Shift); - void __fastcall TimeH1KeyDown(TObject *Sender, WORD &Key, TShiftState Shift); - void __fastcall TimeY2KeyDown(TObject *Sender, WORD &Key, TShiftState Shift); -private: - void __fastcall UpdateEnable(void); -public: - int TimeEna[3],TimeVal[3]; - gtime_t TimeStart,TimeEnd; - double TimeInt; - __fastcall TSpanDialog(TComponent* Owner); +class TSpanDialog : public TForm { + __published : TButton *BtnCancel; + TButton *BtnOk; + TCheckBox *TimeStartF; + TCheckBox *TimeEndF; + TCheckBox *TimeIntF; + TEdit *TimeY2; + TEdit *TimeY1; + TUpDown *TimeY1UD; + TUpDown *TimeY2UD; + TEdit *TimeH2; + TEdit *TimeH1; + TUpDown *TimeH1UD; + TUpDown *TimeH2UD; + TSpeedButton *BtnTime2; + TSpeedButton *BtnTime1; + TComboBox *EditTimeInt; + void __fastcall BtnOkClick(TObject *Sender); + void __fastcall TimeStartFClick(TObject *Sender); + void __fastcall TimeEndFClick(TObject *Sender); + void __fastcall TimeIntFClick(TObject *Sender); + void __fastcall TimeY1UDChangingEx(TObject *Sender, bool &AllowChange, int NewValue, + TUpDownDirection Direction); + void __fastcall TimeH1UDChangingEx(TObject *Sender, bool &AllowChange, int NewValue, + TUpDownDirection Direction); + void __fastcall TimeY2UDChangingEx(TObject *Sender, bool &AllowChange, int NewValue, + TUpDownDirection Direction); + void __fastcall TimeH2UDChangingEx(TObject *Sender, bool &AllowChange, int NewValue, + TUpDownDirection Direction); + void __fastcall FormShow(TObject *Sender); + void __fastcall BtnTime1Click(TObject *Sender); + void __fastcall BtnTime2Click(TObject *Sender); + void __fastcall TimeY1KeyDown(TObject *Sender, WORD &Key, TShiftState Shift); + void __fastcall TimeH2KeyDown(TObject *Sender, WORD &Key, TShiftState Shift); + void __fastcall TimeH1KeyDown(TObject *Sender, WORD &Key, TShiftState Shift); + void __fastcall TimeY2KeyDown(TObject *Sender, WORD &Key, TShiftState Shift); + + private: + void __fastcall UpdateEnable(void); + + public: + int TimeEna[3], TimeVal[3]; + gtime_t TimeStart, TimeEnd; + double TimeInt; + __fastcall TSpanDialog(TComponent *Owner); }; //--------------------------------------------------------------------------- extern PACKAGE TSpanDialog *SpanDialog; diff --git a/app/winapp/appcmn/viewer.cpp b/app/winapp/appcmn/viewer.cpp index ac94dc4f9..e9e4956fd 100644 --- a/app/winapp/appcmn/viewer.cpp +++ b/app/winapp/appcmn/viewer.cpp @@ -3,137 +3,113 @@ #include #pragma hdrstop -#include "rtklib.h" #include "viewer.h" + +#include "rtklib.h" #include "vieweropt.h" //--------------------------------------------------------------------------- #pragma package(smart_init) #pragma resource "*.dfm" TTextViewer *TextViewer; -TColor TTextViewer::Color1,TTextViewer::Color2; +TColor TTextViewer::Color1, TTextViewer::Color2; TFont *TTextViewer::FontD; //--------------------------------------------------------------------------- -__fastcall TTextViewer::TTextViewer(TComponent* Owner) - : TForm(Owner) -{ - Option=1; -} +__fastcall TTextViewer::TTextViewer(TComponent *Owner) : TForm(Owner) { Option = 1; } //--------------------------------------------------------------------------- -void __fastcall TTextViewer::FormShow(TObject *Sender) -{ - if (Option==0) { - BtnReload->Visible=false; - BtnRead ->Visible=false; - } - else if (Option==2) { - BtnReload->Visible=false; - BtnRead ->Caption="Save..."; - } - UpdateText(); +void __fastcall TTextViewer::FormShow(TObject *Sender) { + if (Option == 0) { + BtnReload->Visible = false; + BtnRead->Visible = false; + } else if (Option == 2) { + BtnReload->Visible = false; + BtnRead->Caption = "Save..."; + } + UpdateText(); } //--------------------------------------------------------------------------- -void __fastcall TTextViewer::BtnReloadClick(TObject *Sender) -{ - Read(File); -} +void __fastcall TTextViewer::BtnReloadClick(TObject *Sender) { Read(File); } //--------------------------------------------------------------------------- -void __fastcall TTextViewer::BtnReadClick(TObject *Sender) -{ - if (BtnRead->Caption=="Save...") { - SaveDialog->FileName=File; - if (!SaveDialog->Execute()) return; - Save(SaveDialog->FileName); - } - else { - OpenDialog->FileName=File; - if (!OpenDialog->Execute()) return; - Read(OpenDialog->FileName); - } +void __fastcall TTextViewer::BtnReadClick(TObject *Sender) { + if (BtnRead->Caption == "Save...") { + SaveDialog->FileName = File; + if (!SaveDialog->Execute()) return; + Save(SaveDialog->FileName); + } else { + OpenDialog->FileName = File; + if (!OpenDialog->Execute()) return; + Read(OpenDialog->FileName); + } } //--------------------------------------------------------------------------- -void __fastcall TTextViewer::BtnOptClick(TObject *Sender) -{ - ViewerOptDialog->Left=Left+Width/2-ViewerOptDialog->Width/2; - ViewerOptDialog->Top=Top+Height/2-ViewerOptDialog->Height/2; - if (ViewerOptDialog->ShowModal()!=mrOk) return; - UpdateText(); +void __fastcall TTextViewer::BtnOptClick(TObject *Sender) { + ViewerOptDialog->Left = Left + Width / 2 - ViewerOptDialog->Width / 2; + ViewerOptDialog->Top = Top + Height / 2 - ViewerOptDialog->Height / 2; + if (ViewerOptDialog->ShowModal() != mrOk) return; + UpdateText(); } //--------------------------------------------------------------------------- -void __fastcall TTextViewer::BtnCloseClick(TObject *Sender) -{ - Release(); -} +void __fastcall TTextViewer::BtnCloseClick(TObject *Sender) { Release(); } //--------------------------------------------------------------------------- -void __fastcall TTextViewer::BtnFindClick(TObject *Sender) -{ - TSearchTypes opt; - UnicodeString str=FindStr->Text; - int p; - - if (Text->SelLength>0) { - p=Text->SelStart+1; - } - else { - p=0; - } - p=Text->FindText(str,p,Text->Text.Length()-p,opt); - - if (p>=0) { - Text->SelStart=p; - Text->SelLength=str.Length(); - } - else { - Text->SelStart=0; - Text->SelLength=0; - } +void __fastcall TTextViewer::BtnFindClick(TObject *Sender) { + TSearchTypes opt; + UnicodeString str = FindStr->Text; + int p; + + if (Text->SelLength > 0) { + p = Text->SelStart + 1; + } else { + p = 0; + } + p = Text->FindText(str, p, Text->Text.Length() - p, opt); + + if (p >= 0) { + Text->SelStart = p; + Text->SelLength = str.Length(); + } else { + Text->SelStart = 0; + Text->SelLength = 0; + } } //--------------------------------------------------------------------------- -void __fastcall TTextViewer::FindStrKeyPress(TObject *Sender, char &Key) -{ - if (Key=='\r') BtnFindClick(Sender); +void __fastcall TTextViewer::FindStrKeyPress(TObject *Sender, char &Key) { + if (Key == '\r') BtnFindClick(Sender); } //--------------------------------------------------------------------------- -void __fastcall TTextViewer::Read(AnsiString file) -{ - char s[1024],*path[]={s}; - - if (expath(file.c_str(),path,1)<1) return; - - Screen->Cursor=crHourGlass; - try { - file=path[0]; - Text->Lines->LoadFromFile(file); - } - catch (...) { - Screen->Cursor=crDefault; - return; - } - Screen->Cursor=crDefault; - Caption=file; - File=file; - Text->SelStart=0; - Text->SelLength=0; +void __fastcall TTextViewer::Read(AnsiString file) { + char s[1024], *path[] = {s}; + + if (expath(file.c_str(), path, 1) < 1) return; + + Screen->Cursor = crHourGlass; + try { + file = path[0]; + Text->Lines->LoadFromFile(file); + } catch (...) { + Screen->Cursor = crDefault; + return; + } + Screen->Cursor = crDefault; + Caption = file; + File = file; + Text->SelStart = 0; + Text->SelLength = 0; } //--------------------------------------------------------------------------- -void __fastcall TTextViewer::Save(AnsiString file) -{ - Screen->Cursor=crHourGlass; - try { - Text->Lines->SaveToFile(file); - } - catch (...) { - Screen->Cursor=crDefault; - return; - } - Screen->Cursor=crDefault; - File=file; +void __fastcall TTextViewer::Save(AnsiString file) { + Screen->Cursor = crHourGlass; + try { + Text->Lines->SaveToFile(file); + } catch (...) { + Screen->Cursor = crDefault; + return; + } + Screen->Cursor = crDefault; + File = file; } //--------------------------------------------------------------------------- -void __fastcall TTextViewer::UpdateText(void) -{ - Text->Font=FontD; - Text->Font->Color=Color1; - Text->Color=Color2; +void __fastcall TTextViewer::UpdateText(void) { + Text->Font = FontD; + Text->Font->Color = Color1; + Text->Color = Color2; } //--------------------------------------------------------------------------- - diff --git a/app/winapp/appcmn/viewer.h b/app/winapp/appcmn/viewer.h index 75232999f..1560c9cb4 100644 --- a/app/winapp/appcmn/viewer.h +++ b/app/winapp/appcmn/viewer.h @@ -2,50 +2,50 @@ #ifndef viewerH #define viewerH //--------------------------------------------------------------------------- +#include #include +#include #include -#include -#include -#include #include -#include -#include +#include +#include +#include -#define MAXLINE 1000000 +#define MAXLINE 1000000 //--------------------------------------------------------------------------- -class TTextViewer : public TForm -{ -__published: - TPanel *Panel1; - TButton *BtnClose; - TPanel *Panel2; - TButton *BtnRead; - TOpenDialog *OpenDialog; - TButton *BtnOpt; - TSpeedButton *BtnReload; - TRichEdit *Text; - TSaveDialog *SaveDialog; - TEdit *FindStr; - TButton *BtnFind; - void __fastcall BtnCloseClick(TObject *Sender); - void __fastcall BtnReadClick(TObject *Sender); - void __fastcall BtnOptClick(TObject *Sender); - void __fastcall FormShow(TObject *Sender); - void __fastcall BtnReloadClick(TObject *Sender); - void __fastcall BtnFindClick(TObject *Sender); - void __fastcall FindStrKeyPress(TObject *Sender, char &Key); -private: - AnsiString File; - - void __fastcall UpdateText(void); -public: - int Option; - static TColor Color1,Color2; - static TFont *FontD; - __fastcall TTextViewer(TComponent* Owner); - void __fastcall Read(AnsiString file); - void __fastcall Save(AnsiString file); +class TTextViewer : public TForm { + __published : TPanel *Panel1; + TButton *BtnClose; + TPanel *Panel2; + TButton *BtnRead; + TOpenDialog *OpenDialog; + TButton *BtnOpt; + TSpeedButton *BtnReload; + TRichEdit *Text; + TSaveDialog *SaveDialog; + TEdit *FindStr; + TButton *BtnFind; + void __fastcall BtnCloseClick(TObject *Sender); + void __fastcall BtnReadClick(TObject *Sender); + void __fastcall BtnOptClick(TObject *Sender); + void __fastcall FormShow(TObject *Sender); + void __fastcall BtnReloadClick(TObject *Sender); + void __fastcall BtnFindClick(TObject *Sender); + void __fastcall FindStrKeyPress(TObject *Sender, char &Key); + + private: + AnsiString File; + + void __fastcall UpdateText(void); + + public: + int Option; + static TColor Color1, Color2; + static TFont *FontD; + __fastcall TTextViewer(TComponent *Owner); + void __fastcall Read(AnsiString file); + void __fastcall Save(AnsiString file); }; //--------------------------------------------------------------------------- extern PACKAGE TTextViewer *TextViewer; diff --git a/app/winapp/appcmn/vieweropt.cpp b/app/winapp/appcmn/vieweropt.cpp index 69cf9a550..9a8220c16 100644 --- a/app/winapp/appcmn/vieweropt.cpp +++ b/app/winapp/appcmn/vieweropt.cpp @@ -2,54 +2,47 @@ #include #pragma hdrstop -#include "viewer.h" #include "vieweropt.h" + +#include "viewer.h" //--------------------------------------------------------------------------- #pragma package(smart_init) #pragma resource "*.dfm" TViewerOptDialog *ViewerOptDialog; //--------------------------------------------------------------------------- -__fastcall TViewerOptDialog::TViewerOptDialog(TComponent* Owner) - : TForm(Owner) -{ -} +__fastcall TViewerOptDialog::TViewerOptDialog(TComponent *Owner) : TForm(Owner) {} //--------------------------------------------------------------------------- -void __fastcall TViewerOptDialog::FormShow(TObject *Sender) -{ - AnsiString s; - FontLabel->Font->Assign(TTextViewer::FontD); - FontLabel->Caption=FontLabel->Font->Name+s.sprintf(" %dpt",FontLabel->Font->Size); - Color1->Color=TTextViewer::Color1; - Color2->Color=TTextViewer::Color2; +void __fastcall TViewerOptDialog::FormShow(TObject *Sender) { + AnsiString s; + FontLabel->Font->Assign(TTextViewer::FontD); + FontLabel->Caption = FontLabel->Font->Name + s.sprintf(" %dpt", FontLabel->Font->Size); + Color1->Color = TTextViewer::Color1; + Color2->Color = TTextViewer::Color2; } //--------------------------------------------------------------------------- -void __fastcall TViewerOptDialog::BtnOkClick(TObject *Sender) -{ - TTextViewer::FontD->Assign(FontLabel->Font); - TTextViewer::Color1=Color1->Color; - TTextViewer::Color2=Color2->Color; +void __fastcall TViewerOptDialog::BtnOkClick(TObject *Sender) { + TTextViewer::FontD->Assign(FontLabel->Font); + TTextViewer::Color1 = Color1->Color; + TTextViewer::Color2 = Color2->Color; } //--------------------------------------------------------------------------- -void __fastcall TViewerOptDialog::BtnColor1Click(TObject *Sender) -{ - ColorDialog->Color=Color1->Color; - if (!ColorDialog->Execute()) return; - Color1->Color=ColorDialog->Color; +void __fastcall TViewerOptDialog::BtnColor1Click(TObject *Sender) { + ColorDialog->Color = Color1->Color; + if (!ColorDialog->Execute()) return; + Color1->Color = ColorDialog->Color; } //--------------------------------------------------------------------------- -void __fastcall TViewerOptDialog::BtnColor2Click(TObject *Sender) -{ - ColorDialog->Color=Color2->Color; - if (!ColorDialog->Execute()) return; - Color2->Color=ColorDialog->Color; +void __fastcall TViewerOptDialog::BtnColor2Click(TObject *Sender) { + ColorDialog->Color = Color2->Color; + if (!ColorDialog->Execute()) return; + Color2->Color = ColorDialog->Color; } //--------------------------------------------------------------------------- -void __fastcall TViewerOptDialog::BtnFontClick(TObject *Sender) -{ - AnsiString s; - FontDialog->Font=FontLabel->Font; - if (!FontDialog->Execute()) return; - FontLabel->Font=FontDialog->Font; - FontLabel->Caption=FontLabel->Font->Name+s.sprintf(" %dpt",FontLabel->Font->Size); +void __fastcall TViewerOptDialog::BtnFontClick(TObject *Sender) { + AnsiString s; + FontDialog->Font = FontLabel->Font; + if (!FontDialog->Execute()) return; + FontLabel->Font = FontDialog->Font; + FontLabel->Caption = FontLabel->Font->Name + s.sprintf(" %dpt", FontLabel->Font->Size); } //--------------------------------------------------------------------------- diff --git a/app/winapp/appcmn/vieweropt.h b/app/winapp/appcmn/vieweropt.h index f3a3d39e6..c3caba8d8 100644 --- a/app/winapp/appcmn/vieweropt.h +++ b/app/winapp/appcmn/vieweropt.h @@ -5,35 +5,34 @@ //--------------------------------------------------------------------------- #include #include -#include -#include -#include #include +#include +#include +#include //--------------------------------------------------------------------------- -class TViewerOptDialog : public TForm -{ -__published: - TButton *BtnOk; - TButton *BtnCancel; - TLabel *Label6; - TPanel *Color1; - TButton *BtnColor1; - TLabel *Label1; - TPanel *Color2; - TButton *BtnColor2; - TLabel *Label15; - TLabel *FontLabel; - TButton *BtnFont; - TColorDialog *ColorDialog; - TFontDialog *FontDialog; - void __fastcall BtnColor1Click(TObject *Sender); - void __fastcall BtnColor2Click(TObject *Sender); - void __fastcall BtnFontClick(TObject *Sender); - void __fastcall BtnOkClick(TObject *Sender); - void __fastcall FormShow(TObject *Sender); -private: -public: - __fastcall TViewerOptDialog(TComponent* Owner); +class TViewerOptDialog : public TForm { + __published : TButton *BtnOk; + TButton *BtnCancel; + TLabel *Label6; + TPanel *Color1; + TButton *BtnColor1; + TLabel *Label1; + TPanel *Color2; + TButton *BtnColor2; + TLabel *Label15; + TLabel *FontLabel; + TButton *BtnFont; + TColorDialog *ColorDialog; + TFontDialog *FontDialog; + void __fastcall BtnColor1Click(TObject *Sender); + void __fastcall BtnColor2Click(TObject *Sender); + void __fastcall BtnFontClick(TObject *Sender); + void __fastcall BtnOkClick(TObject *Sender); + void __fastcall FormShow(TObject *Sender); + + private: + public: + __fastcall TViewerOptDialog(TComponent *Owner); }; //--------------------------------------------------------------------------- extern PACKAGE TViewerOptDialog *ViewerOptDialog; diff --git a/app/winapp/rtkconv/codeopt.cpp b/app/winapp/rtkconv/codeopt.cpp index e67a05d75..7d33d9bda 100644 --- a/app/winapp/rtkconv/codeopt.cpp +++ b/app/winapp/rtkconv/codeopt.cpp @@ -2,513 +2,507 @@ #include #pragma hdrstop -#include "rtklib.h" -#include "convopt.h" #include "codeopt.h" + +#include "convopt.h" +#include "rtklib.h" //--------------------------------------------------------------------------- #pragma package(smart_init) #pragma resource "*.dfm" TCodeOptDialog *CodeOptDialog; //--------------------------------------------------------------------------- -__fastcall TCodeOptDialog::TCodeOptDialog(TComponent* Owner) - : TForm(Owner) -{ -} +__fastcall TCodeOptDialog::TCodeOptDialog(TComponent *Owner) : TForm(Owner) {} //--------------------------------------------------------------------------- -void __fastcall TCodeOptDialog::FormShow(TObject *Sender) -{ - char mask[7][MAXCODE+1]={""}; - - for (int i=0;i<7;i++) strcpy(mask[i],ConvOptDialog->CodeMask[i].c_str()); - G01->Checked=mask[0][ 0]=='1'; - G02->Checked=mask[0][ 1]=='1'; - G03->Checked=mask[0][ 2]=='1'; - G04->Checked=mask[0][ 3]=='1'; - G05->Checked=mask[0][ 4]=='1'; - G06->Checked=mask[0][ 5]=='1'; - G07->Checked=mask[0][ 6]=='1'; - G08->Checked=mask[0][ 7]=='1'; - G12->Checked=mask[0][11]=='1'; - G14->Checked=mask[0][13]=='1'; - G15->Checked=mask[0][14]=='1'; - G16->Checked=mask[0][15]=='1'; - G17->Checked=mask[0][16]=='1'; - G18->Checked=mask[0][17]=='1'; - G19->Checked=mask[0][18]=='1'; - G20->Checked=mask[0][19]=='1'; - G21->Checked=mask[0][20]=='1'; - G22->Checked=mask[0][21]=='1'; - G23->Checked=mask[0][22]=='1'; - G24->Checked=mask[0][23]=='1'; - G25->Checked=mask[0][24]=='1'; - G26->Checked=mask[0][25]=='1'; - R01->Checked=mask[1][ 0]=='1'; - R02->Checked=mask[1][ 1]=='1'; - R14->Checked=mask[1][13]=='1'; - R19->Checked=mask[1][18]=='1'; - R44->Checked=mask[1][43]=='1'; - R45->Checked=mask[1][44]=='1'; - R46->Checked=mask[1][45]=='1'; - R66->Checked=mask[1][65]=='1'; // - R67->Checked=mask[1][66]=='1'; // - R68->Checked=mask[1][67]=='1'; // - R30->Checked=mask[1][29]=='1'; // - R31->Checked=mask[1][30]=='1'; // - R33->Checked=mask[1][32]=='1'; // - E01->Checked=mask[2][ 0]=='1'; - E10->Checked=mask[2][ 9]=='1'; - E11->Checked=mask[2][10]=='1'; - E12->Checked=mask[2][11]=='1'; - E13->Checked=mask[2][12]=='1'; - E24->Checked=mask[2][23]=='1'; - E25->Checked=mask[2][24]=='1'; - E26->Checked=mask[2][25]=='1'; - E27->Checked=mask[2][26]=='1'; - E28->Checked=mask[2][27]=='1'; - E29->Checked=mask[2][28]=='1'; - E30->Checked=mask[2][29]=='1'; - E31->Checked=mask[2][30]=='1'; - E32->Checked=mask[2][31]=='1'; - E33->Checked=mask[2][32]=='1'; - E34->Checked=mask[2][33]=='1'; - E37->Checked=mask[2][36]=='1'; - E38->Checked=mask[2][37]=='1'; - E39->Checked=mask[2][38]=='1'; - J01->Checked=mask[3][ 0]=='1'; - J07->Checked=mask[3][ 6]=='1'; - J08->Checked=mask[3][ 7]=='1'; - J09->Checked=mask[3][ 8]=='1'; - J11->Checked=mask[3][10]=='1'; - J12->Checked=mask[3][11]=='1'; - J13->Checked=mask[3][12]=='1'; - J16->Checked=mask[3][15]=='1'; - J17->Checked=mask[3][16]=='1'; - J18->Checked=mask[3][17]=='1'; - J24->Checked=mask[3][23]=='1'; - J25->Checked=mask[3][24]=='1'; - J26->Checked=mask[3][25]=='1'; - J57->Checked=mask[3][56]=='1'; // - J58->Checked=mask[3][57]=='1'; // - J59->Checked=mask[3][58]=='1'; // - J60->Checked=mask[3][59]=='1'; // - J34->Checked=mask[3][33]=='1'; // - J35->Checked=mask[3][34]=='1'; - J36->Checked=mask[3][35]=='1'; - J33->Checked=mask[3][32]=='1'; - C40->Checked=mask[5][39]=='1'; // - C41->Checked=mask[5][40]=='1'; // - C18->Checked=mask[5][17]=='1'; // - C27->Checked=mask[5][26]=='1'; - C28->Checked=mask[5][27]=='1'; - C29->Checked=mask[5][28]=='1'; - C42->Checked=mask[5][41]=='1'; - C43->Checked=mask[5][42]=='1'; - C33->Checked=mask[5][32]=='1'; - C56->Checked=mask[5][55]=='1'; // - C02->Checked=mask[5][ 1]=='1'; // - C12->Checked=mask[5][11]=='1'; // - C07->Checked=mask[5][ 6]=='1'; // - C08->Checked=mask[5][ 7]=='1'; // - C13->Checked=mask[5][12]=='1'; // - C57->Checked=mask[5][56]=='1'; // - C58->Checked=mask[5][57]=='1'; // - C26->Checked=mask[5][25]=='1'; // - C61->Checked=mask[5][60]=='1'; // - C62->Checked=mask[5][61]=='1'; // - C63->Checked=mask[5][62]=='1'; // - C64->Checked=mask[5][63]=='1'; // - C65->Checked=mask[5][64]=='1'; // - C39->Checked=mask[5][38]=='1'; // - C69->Checked=mask[5][68]=='1'; // - C70->Checked=mask[5][69]=='1'; // - C34->Checked=mask[5][33]=='1'; // - I49->Checked=mask[6][48]=='1'; - I50->Checked=mask[6][49]=='1'; - I51->Checked=mask[6][50]=='1'; - I26->Checked=mask[6][25]=='1'; - I52->Checked=mask[6][51]=='1'; - I53->Checked=mask[6][52]=='1'; - I54->Checked=mask[6][53]=='1'; - I55->Checked=mask[6][54]=='1'; - I56->Checked=mask[6][55]=='1'; - I02->Checked=mask[6][1]=='1'; - I12->Checked=mask[6][11]=='1'; - S01->Checked=mask[4][ 0]=='1'; - S24->Checked=mask[4][23]=='1'; - S25->Checked=mask[4][24]=='1'; - S26->Checked=mask[4][25]=='1'; - - UpdateEnable(); +void __fastcall TCodeOptDialog::FormShow(TObject *Sender) { + char mask[7][MAXCODE + 1] = {""}; + + for (int i = 0; i < 7; i++) strcpy(mask[i], ConvOptDialog->CodeMask[i].c_str()); + G01->Checked = mask[0][0] == '1'; + G02->Checked = mask[0][1] == '1'; + G03->Checked = mask[0][2] == '1'; + G04->Checked = mask[0][3] == '1'; + G05->Checked = mask[0][4] == '1'; + G06->Checked = mask[0][5] == '1'; + G07->Checked = mask[0][6] == '1'; + G08->Checked = mask[0][7] == '1'; + G12->Checked = mask[0][11] == '1'; + G14->Checked = mask[0][13] == '1'; + G15->Checked = mask[0][14] == '1'; + G16->Checked = mask[0][15] == '1'; + G17->Checked = mask[0][16] == '1'; + G18->Checked = mask[0][17] == '1'; + G19->Checked = mask[0][18] == '1'; + G20->Checked = mask[0][19] == '1'; + G21->Checked = mask[0][20] == '1'; + G22->Checked = mask[0][21] == '1'; + G23->Checked = mask[0][22] == '1'; + G24->Checked = mask[0][23] == '1'; + G25->Checked = mask[0][24] == '1'; + G26->Checked = mask[0][25] == '1'; + R01->Checked = mask[1][0] == '1'; + R02->Checked = mask[1][1] == '1'; + R14->Checked = mask[1][13] == '1'; + R19->Checked = mask[1][18] == '1'; + R44->Checked = mask[1][43] == '1'; + R45->Checked = mask[1][44] == '1'; + R46->Checked = mask[1][45] == '1'; + R66->Checked = mask[1][65] == '1'; // + R67->Checked = mask[1][66] == '1'; // + R68->Checked = mask[1][67] == '1'; // + R30->Checked = mask[1][29] == '1'; // + R31->Checked = mask[1][30] == '1'; // + R33->Checked = mask[1][32] == '1'; // + E01->Checked = mask[2][0] == '1'; + E10->Checked = mask[2][9] == '1'; + E11->Checked = mask[2][10] == '1'; + E12->Checked = mask[2][11] == '1'; + E13->Checked = mask[2][12] == '1'; + E24->Checked = mask[2][23] == '1'; + E25->Checked = mask[2][24] == '1'; + E26->Checked = mask[2][25] == '1'; + E27->Checked = mask[2][26] == '1'; + E28->Checked = mask[2][27] == '1'; + E29->Checked = mask[2][28] == '1'; + E30->Checked = mask[2][29] == '1'; + E31->Checked = mask[2][30] == '1'; + E32->Checked = mask[2][31] == '1'; + E33->Checked = mask[2][32] == '1'; + E34->Checked = mask[2][33] == '1'; + E37->Checked = mask[2][36] == '1'; + E38->Checked = mask[2][37] == '1'; + E39->Checked = mask[2][38] == '1'; + J01->Checked = mask[3][0] == '1'; + J07->Checked = mask[3][6] == '1'; + J08->Checked = mask[3][7] == '1'; + J09->Checked = mask[3][8] == '1'; + J11->Checked = mask[3][10] == '1'; + J12->Checked = mask[3][11] == '1'; + J13->Checked = mask[3][12] == '1'; + J16->Checked = mask[3][15] == '1'; + J17->Checked = mask[3][16] == '1'; + J18->Checked = mask[3][17] == '1'; + J24->Checked = mask[3][23] == '1'; + J25->Checked = mask[3][24] == '1'; + J26->Checked = mask[3][25] == '1'; + J57->Checked = mask[3][56] == '1'; // + J58->Checked = mask[3][57] == '1'; // + J59->Checked = mask[3][58] == '1'; // + J60->Checked = mask[3][59] == '1'; // + J34->Checked = mask[3][33] == '1'; // + J35->Checked = mask[3][34] == '1'; + J36->Checked = mask[3][35] == '1'; + J33->Checked = mask[3][32] == '1'; + C40->Checked = mask[5][39] == '1'; // + C41->Checked = mask[5][40] == '1'; // + C18->Checked = mask[5][17] == '1'; // + C27->Checked = mask[5][26] == '1'; + C28->Checked = mask[5][27] == '1'; + C29->Checked = mask[5][28] == '1'; + C42->Checked = mask[5][41] == '1'; + C43->Checked = mask[5][42] == '1'; + C33->Checked = mask[5][32] == '1'; + C56->Checked = mask[5][55] == '1'; // + C02->Checked = mask[5][1] == '1'; // + C12->Checked = mask[5][11] == '1'; // + C07->Checked = mask[5][6] == '1'; // + C08->Checked = mask[5][7] == '1'; // + C13->Checked = mask[5][12] == '1'; // + C57->Checked = mask[5][56] == '1'; // + C58->Checked = mask[5][57] == '1'; // + C26->Checked = mask[5][25] == '1'; // + C61->Checked = mask[5][60] == '1'; // + C62->Checked = mask[5][61] == '1'; // + C63->Checked = mask[5][62] == '1'; // + C64->Checked = mask[5][63] == '1'; // + C65->Checked = mask[5][64] == '1'; // + C39->Checked = mask[5][38] == '1'; // + C69->Checked = mask[5][68] == '1'; // + C70->Checked = mask[5][69] == '1'; // + C34->Checked = mask[5][33] == '1'; // + I49->Checked = mask[6][48] == '1'; + I50->Checked = mask[6][49] == '1'; + I51->Checked = mask[6][50] == '1'; + I26->Checked = mask[6][25] == '1'; + I52->Checked = mask[6][51] == '1'; + I53->Checked = mask[6][52] == '1'; + I54->Checked = mask[6][53] == '1'; + I55->Checked = mask[6][54] == '1'; + I56->Checked = mask[6][55] == '1'; + I02->Checked = mask[6][1] == '1'; + I12->Checked = mask[6][11] == '1'; + S01->Checked = mask[4][0] == '1'; + S24->Checked = mask[4][23] == '1'; + S25->Checked = mask[4][24] == '1'; + S26->Checked = mask[4][25] == '1'; + + UpdateEnable(); } //--------------------------------------------------------------------------- -void __fastcall TCodeOptDialog::BtnOkClick(TObject *Sender) -{ - char mask[7][MAXCODE+1]={""}; - - for (int i=0;i<7;i++) for (int j=0;jChecked) mask[0][ 0]='1'; - if (G02->Checked) mask[0][ 1]='1'; - if (G03->Checked) mask[0][ 2]='1'; - if (G04->Checked) mask[0][ 3]='1'; - if (G05->Checked) mask[0][ 4]='1'; - if (G06->Checked) mask[0][ 5]='1'; - if (G07->Checked) mask[0][ 6]='1'; - if (G08->Checked) mask[0][ 7]='1'; - if (G12->Checked) mask[0][11]='1'; - if (G14->Checked) mask[0][13]='1'; - if (G15->Checked) mask[0][14]='1'; - if (G16->Checked) mask[0][15]='1'; - if (G17->Checked) mask[0][16]='1'; - if (G18->Checked) mask[0][17]='1'; - if (G19->Checked) mask[0][18]='1'; - if (G20->Checked) mask[0][19]='1'; - if (G21->Checked) mask[0][20]='1'; - if (G22->Checked) mask[0][21]='1'; - if (G23->Checked) mask[0][22]='1'; - if (G24->Checked) mask[0][23]='1'; - if (G25->Checked) mask[0][24]='1'; - if (G26->Checked) mask[0][25]='1'; - if (R01->Checked) mask[1][ 0]='1'; - if (R02->Checked) mask[1][ 1]='1'; - if (R14->Checked) mask[1][13]='1'; - if (R19->Checked) mask[1][18]='1'; - if (R44->Checked) mask[1][43]='1'; - if (R45->Checked) mask[1][44]='1'; - if (R46->Checked) mask[1][45]='1'; - if (R66->Checked) mask[1][65]='1'; // - if (R67->Checked) mask[1][66]='1'; // - if (R68->Checked) mask[1][67]='1'; // - if (R30->Checked) mask[1][29]='1'; // - if (R31->Checked) mask[1][30]='1'; // - if (R33->Checked) mask[1][32]='1'; // - if (E01->Checked) mask[2][ 0]='1'; - if (E10->Checked) mask[2][ 9]='1'; - if (E11->Checked) mask[2][10]='1'; - if (E12->Checked) mask[2][11]='1'; - if (E13->Checked) mask[2][12]='1'; - if (E24->Checked) mask[2][23]='1'; - if (E25->Checked) mask[2][24]='1'; - if (E26->Checked) mask[2][25]='1'; - if (E27->Checked) mask[2][26]='1'; - if (E28->Checked) mask[2][27]='1'; - if (E29->Checked) mask[2][28]='1'; - if (E30->Checked) mask[2][29]='1'; - if (E31->Checked) mask[2][30]='1'; - if (E32->Checked) mask[2][31]='1'; - if (E33->Checked) mask[2][32]='1'; - if (E34->Checked) mask[2][33]='1'; - if (E37->Checked) mask[2][36]='1'; - if (E38->Checked) mask[2][37]='1'; - if (E39->Checked) mask[2][38]='1'; - if (J01->Checked) mask[3][ 0]='1'; - if (J07->Checked) mask[3][ 6]='1'; - if (J08->Checked) mask[3][ 7]='1'; - if (J09->Checked) mask[3][ 8]='1'; - if (J11->Checked) mask[3][10]='1'; - if (J12->Checked) mask[3][11]='1'; - if (J13->Checked) mask[3][12]='1'; - if (J16->Checked) mask[3][15]='1'; - if (J17->Checked) mask[3][16]='1'; - if (J18->Checked) mask[3][17]='1'; - if (J24->Checked) mask[3][23]='1'; - if (J25->Checked) mask[3][24]='1'; - if (J26->Checked) mask[3][25]='1'; - if (J57->Checked) mask[3][56]='1'; // - if (J58->Checked) mask[3][57]='1'; // - if (J59->Checked) mask[3][58]='1'; // - if (J60->Checked) mask[3][59]='1'; // - if (J34->Checked) mask[3][33]='1'; // - if (J35->Checked) mask[3][34]='1'; - if (J36->Checked) mask[3][35]='1'; - if (J33->Checked) mask[3][32]='1'; - if (C40->Checked) mask[5][39]='1'; // - if (C41->Checked) mask[5][40]='1'; // - if (C18->Checked) mask[5][17]='1'; // - if (C27->Checked) mask[5][26]='1'; - if (C28->Checked) mask[5][27]='1'; - if (C29->Checked) mask[5][28]='1'; - if (C42->Checked) mask[5][41]='1'; - if (C43->Checked) mask[5][42]='1'; - if (C33->Checked) mask[5][32]='1'; - if (C56->Checked) mask[5][55]='1'; // - if (C02->Checked) mask[5][ 1]='1'; // - if (C12->Checked) mask[5][11]='1'; // - if (C07->Checked) mask[5][ 6]='1'; // - if (C08->Checked) mask[5][ 7]='1'; // - if (C13->Checked) mask[5][12]='1'; // - if (C57->Checked) mask[5][56]='1'; // - if (C58->Checked) mask[5][57]='1'; // - if (C26->Checked) mask[5][25]='1'; // - if (C61->Checked) mask[5][60]='1'; // - if (C62->Checked) mask[5][61]='1'; // - if (C63->Checked) mask[5][62]='1'; // - if (C64->Checked) mask[5][63]='1'; // - if (C65->Checked) mask[5][64]='1'; // - if (C39->Checked) mask[5][38]='1'; // - if (C69->Checked) mask[5][68]='1'; // - if (C70->Checked) mask[5][69]='1'; // - if (C34->Checked) mask[5][33]='1'; // - if (I49->Checked) mask[6][48]='1'; - if (I50->Checked) mask[6][49]='1'; - if (I51->Checked) mask[6][50]='1'; - if (I26->Checked) mask[6][25]='1'; - if (I52->Checked) mask[6][51]='1'; - if (I53->Checked) mask[6][52]='1'; - if (I54->Checked) mask[6][53]='1'; - if (I55->Checked) mask[6][54]='1'; - if (I56->Checked) mask[6][55]='1'; - if (I02->Checked) mask[6][ 1]='1'; - if (I12->Checked) mask[6][11]='1'; - if (S01->Checked) mask[4][ 0]='1'; - if (S24->Checked) mask[4][23]='1'; - if (S25->Checked) mask[4][24]='1'; - if (S26->Checked) mask[4][25]='1'; - for (int i=0;i<7;i++) ConvOptDialog->CodeMask[i]=mask[i]; +void __fastcall TCodeOptDialog::BtnOkClick(TObject *Sender) { + char mask[7][MAXCODE + 1] = {""}; + + for (int i = 0; i < 7; i++) + for (int j = 0; j < MAXCODE; j++) mask[i][j] = '0'; + if (G01->Checked) mask[0][0] = '1'; + if (G02->Checked) mask[0][1] = '1'; + if (G03->Checked) mask[0][2] = '1'; + if (G04->Checked) mask[0][3] = '1'; + if (G05->Checked) mask[0][4] = '1'; + if (G06->Checked) mask[0][5] = '1'; + if (G07->Checked) mask[0][6] = '1'; + if (G08->Checked) mask[0][7] = '1'; + if (G12->Checked) mask[0][11] = '1'; + if (G14->Checked) mask[0][13] = '1'; + if (G15->Checked) mask[0][14] = '1'; + if (G16->Checked) mask[0][15] = '1'; + if (G17->Checked) mask[0][16] = '1'; + if (G18->Checked) mask[0][17] = '1'; + if (G19->Checked) mask[0][18] = '1'; + if (G20->Checked) mask[0][19] = '1'; + if (G21->Checked) mask[0][20] = '1'; + if (G22->Checked) mask[0][21] = '1'; + if (G23->Checked) mask[0][22] = '1'; + if (G24->Checked) mask[0][23] = '1'; + if (G25->Checked) mask[0][24] = '1'; + if (G26->Checked) mask[0][25] = '1'; + if (R01->Checked) mask[1][0] = '1'; + if (R02->Checked) mask[1][1] = '1'; + if (R14->Checked) mask[1][13] = '1'; + if (R19->Checked) mask[1][18] = '1'; + if (R44->Checked) mask[1][43] = '1'; + if (R45->Checked) mask[1][44] = '1'; + if (R46->Checked) mask[1][45] = '1'; + if (R66->Checked) mask[1][65] = '1'; // + if (R67->Checked) mask[1][66] = '1'; // + if (R68->Checked) mask[1][67] = '1'; // + if (R30->Checked) mask[1][29] = '1'; // + if (R31->Checked) mask[1][30] = '1'; // + if (R33->Checked) mask[1][32] = '1'; // + if (E01->Checked) mask[2][0] = '1'; + if (E10->Checked) mask[2][9] = '1'; + if (E11->Checked) mask[2][10] = '1'; + if (E12->Checked) mask[2][11] = '1'; + if (E13->Checked) mask[2][12] = '1'; + if (E24->Checked) mask[2][23] = '1'; + if (E25->Checked) mask[2][24] = '1'; + if (E26->Checked) mask[2][25] = '1'; + if (E27->Checked) mask[2][26] = '1'; + if (E28->Checked) mask[2][27] = '1'; + if (E29->Checked) mask[2][28] = '1'; + if (E30->Checked) mask[2][29] = '1'; + if (E31->Checked) mask[2][30] = '1'; + if (E32->Checked) mask[2][31] = '1'; + if (E33->Checked) mask[2][32] = '1'; + if (E34->Checked) mask[2][33] = '1'; + if (E37->Checked) mask[2][36] = '1'; + if (E38->Checked) mask[2][37] = '1'; + if (E39->Checked) mask[2][38] = '1'; + if (J01->Checked) mask[3][0] = '1'; + if (J07->Checked) mask[3][6] = '1'; + if (J08->Checked) mask[3][7] = '1'; + if (J09->Checked) mask[3][8] = '1'; + if (J11->Checked) mask[3][10] = '1'; + if (J12->Checked) mask[3][11] = '1'; + if (J13->Checked) mask[3][12] = '1'; + if (J16->Checked) mask[3][15] = '1'; + if (J17->Checked) mask[3][16] = '1'; + if (J18->Checked) mask[3][17] = '1'; + if (J24->Checked) mask[3][23] = '1'; + if (J25->Checked) mask[3][24] = '1'; + if (J26->Checked) mask[3][25] = '1'; + if (J57->Checked) mask[3][56] = '1'; // + if (J58->Checked) mask[3][57] = '1'; // + if (J59->Checked) mask[3][58] = '1'; // + if (J60->Checked) mask[3][59] = '1'; // + if (J34->Checked) mask[3][33] = '1'; // + if (J35->Checked) mask[3][34] = '1'; + if (J36->Checked) mask[3][35] = '1'; + if (J33->Checked) mask[3][32] = '1'; + if (C40->Checked) mask[5][39] = '1'; // + if (C41->Checked) mask[5][40] = '1'; // + if (C18->Checked) mask[5][17] = '1'; // + if (C27->Checked) mask[5][26] = '1'; + if (C28->Checked) mask[5][27] = '1'; + if (C29->Checked) mask[5][28] = '1'; + if (C42->Checked) mask[5][41] = '1'; + if (C43->Checked) mask[5][42] = '1'; + if (C33->Checked) mask[5][32] = '1'; + if (C56->Checked) mask[5][55] = '1'; // + if (C02->Checked) mask[5][1] = '1'; // + if (C12->Checked) mask[5][11] = '1'; // + if (C07->Checked) mask[5][6] = '1'; // + if (C08->Checked) mask[5][7] = '1'; // + if (C13->Checked) mask[5][12] = '1'; // + if (C57->Checked) mask[5][56] = '1'; // + if (C58->Checked) mask[5][57] = '1'; // + if (C26->Checked) mask[5][25] = '1'; // + if (C61->Checked) mask[5][60] = '1'; // + if (C62->Checked) mask[5][61] = '1'; // + if (C63->Checked) mask[5][62] = '1'; // + if (C64->Checked) mask[5][63] = '1'; // + if (C65->Checked) mask[5][64] = '1'; // + if (C39->Checked) mask[5][38] = '1'; // + if (C69->Checked) mask[5][68] = '1'; // + if (C70->Checked) mask[5][69] = '1'; // + if (C34->Checked) mask[5][33] = '1'; // + if (I49->Checked) mask[6][48] = '1'; + if (I50->Checked) mask[6][49] = '1'; + if (I51->Checked) mask[6][50] = '1'; + if (I26->Checked) mask[6][25] = '1'; + if (I52->Checked) mask[6][51] = '1'; + if (I53->Checked) mask[6][52] = '1'; + if (I54->Checked) mask[6][53] = '1'; + if (I55->Checked) mask[6][54] = '1'; + if (I56->Checked) mask[6][55] = '1'; + if (I02->Checked) mask[6][1] = '1'; + if (I12->Checked) mask[6][11] = '1'; + if (S01->Checked) mask[4][0] = '1'; + if (S24->Checked) mask[4][23] = '1'; + if (S25->Checked) mask[4][24] = '1'; + if (S26->Checked) mask[4][25] = '1'; + for (int i = 0; i < 7; i++) ConvOptDialog->CodeMask[i] = mask[i]; } //--------------------------------------------------------------------------- -void __fastcall TCodeOptDialog::BtnSetAllClick(TObject *Sender) -{ - int set=BtnSetAll->Caption=="Set All"; - - G01->Checked=set; - G02->Checked=set; - G03->Checked=set; - G04->Checked=set; - G05->Checked=set; - G06->Checked=set; - G07->Checked=set; - G08->Checked=set; - G12->Checked=set; - G14->Checked=set; - G15->Checked=set; - G16->Checked=set; - G17->Checked=set; - G18->Checked=set; - G19->Checked=set; - G20->Checked=set; - G21->Checked=set; - G22->Checked=set; - G23->Checked=set; - G24->Checked=set; - G25->Checked=set; - G26->Checked=set; - R01->Checked=set; - R02->Checked=set; - R14->Checked=set; - R19->Checked=set; - R44->Checked=set; - R45->Checked=set; - R46->Checked=set; - R66->Checked=set; // - R67->Checked=set; // - R68->Checked=set; // - R30->Checked=set; // - R31->Checked=set; // - R33->Checked=set; // - E01->Checked=set; - E10->Checked=set; - E11->Checked=set; - E12->Checked=set; - E13->Checked=set; - E24->Checked=set; - E25->Checked=set; - E26->Checked=set; - E27->Checked=set; - E28->Checked=set; - E29->Checked=set; - E30->Checked=set; - E31->Checked=set; - E32->Checked=set; - E33->Checked=set; - E34->Checked=set; - E37->Checked=set; - E38->Checked=set; - E39->Checked=set; - J01->Checked=set; - J07->Checked=set; - J08->Checked=set; - J09->Checked=set; - J11->Checked=set; - J12->Checked=set; - J13->Checked=set; - J16->Checked=set; - J17->Checked=set; - J18->Checked=set; - J24->Checked=set; - J25->Checked=set; - J26->Checked=set; - J57->Checked=set; // - J58->Checked=set; // - J59->Checked=set; // - J60->Checked=set; // - J34->Checked=set; // - J35->Checked=set; - J36->Checked=set; - J33->Checked=set; - C40->Checked=set; // - C41->Checked=set; // - C18->Checked=set; // - C27->Checked=set; - C28->Checked=set; - C29->Checked=set; - C42->Checked=set; - C43->Checked=set; - C33->Checked=set; - C56->Checked=set; // - C02->Checked=set; // - C12->Checked=set; // - C07->Checked=set; // - C08->Checked=set; // - C13->Checked=set; // - C57->Checked=set; // - C58->Checked=set; // - C26->Checked=set; // - C61->Checked=set; // - C62->Checked=set; // - C63->Checked=set; // - C64->Checked=set; // - C65->Checked=set; // - C39->Checked=set; // - C69->Checked=set; // - C70->Checked=set; // - C34->Checked=set; // - I49->Checked=set; - I50->Checked=set; - I51->Checked=set; - I26->Checked=set; - I52->Checked=set; - I53->Checked=set; - I54->Checked=set; - I55->Checked=set; - I56->Checked=set; - I02->Checked=set; - I12->Checked=set; - S01->Checked=set; - S24->Checked=set; - S25->Checked=set; - S26->Checked=set; - BtnSetAll->Caption=BtnSetAll->Caption=="Set All"?"Unset All":"Set All"; +void __fastcall TCodeOptDialog::BtnSetAllClick(TObject *Sender) { + int set = BtnSetAll->Caption == "Set All"; + + G01->Checked = set; + G02->Checked = set; + G03->Checked = set; + G04->Checked = set; + G05->Checked = set; + G06->Checked = set; + G07->Checked = set; + G08->Checked = set; + G12->Checked = set; + G14->Checked = set; + G15->Checked = set; + G16->Checked = set; + G17->Checked = set; + G18->Checked = set; + G19->Checked = set; + G20->Checked = set; + G21->Checked = set; + G22->Checked = set; + G23->Checked = set; + G24->Checked = set; + G25->Checked = set; + G26->Checked = set; + R01->Checked = set; + R02->Checked = set; + R14->Checked = set; + R19->Checked = set; + R44->Checked = set; + R45->Checked = set; + R46->Checked = set; + R66->Checked = set; // + R67->Checked = set; // + R68->Checked = set; // + R30->Checked = set; // + R31->Checked = set; // + R33->Checked = set; // + E01->Checked = set; + E10->Checked = set; + E11->Checked = set; + E12->Checked = set; + E13->Checked = set; + E24->Checked = set; + E25->Checked = set; + E26->Checked = set; + E27->Checked = set; + E28->Checked = set; + E29->Checked = set; + E30->Checked = set; + E31->Checked = set; + E32->Checked = set; + E33->Checked = set; + E34->Checked = set; + E37->Checked = set; + E38->Checked = set; + E39->Checked = set; + J01->Checked = set; + J07->Checked = set; + J08->Checked = set; + J09->Checked = set; + J11->Checked = set; + J12->Checked = set; + J13->Checked = set; + J16->Checked = set; + J17->Checked = set; + J18->Checked = set; + J24->Checked = set; + J25->Checked = set; + J26->Checked = set; + J57->Checked = set; // + J58->Checked = set; // + J59->Checked = set; // + J60->Checked = set; // + J34->Checked = set; // + J35->Checked = set; + J36->Checked = set; + J33->Checked = set; + C40->Checked = set; // + C41->Checked = set; // + C18->Checked = set; // + C27->Checked = set; + C28->Checked = set; + C29->Checked = set; + C42->Checked = set; + C43->Checked = set; + C33->Checked = set; + C56->Checked = set; // + C02->Checked = set; // + C12->Checked = set; // + C07->Checked = set; // + C08->Checked = set; // + C13->Checked = set; // + C57->Checked = set; // + C58->Checked = set; // + C26->Checked = set; // + C61->Checked = set; // + C62->Checked = set; // + C63->Checked = set; // + C64->Checked = set; // + C65->Checked = set; // + C39->Checked = set; // + C69->Checked = set; // + C70->Checked = set; // + C34->Checked = set; // + I49->Checked = set; + I50->Checked = set; + I51->Checked = set; + I26->Checked = set; + I52->Checked = set; + I53->Checked = set; + I54->Checked = set; + I55->Checked = set; + I56->Checked = set; + I02->Checked = set; + I12->Checked = set; + S01->Checked = set; + S24->Checked = set; + S25->Checked = set; + S26->Checked = set; + BtnSetAll->Caption = BtnSetAll->Caption == "Set All" ? "Unset All" : "Set All"; } //--------------------------------------------------------------------------- -void __fastcall TCodeOptDialog::UpdateEnable(void) -{ - G01->Enabled=(NavSys&SYS_GPS)&&(FreqType&FREQTYPE_L1); - G02->Enabled=(NavSys&SYS_GPS)&&(FreqType&FREQTYPE_L1); - G03->Enabled=(NavSys&SYS_GPS)&&(FreqType&FREQTYPE_L1); - G04->Enabled=(NavSys&SYS_GPS)&&(FreqType&FREQTYPE_L1); - G05->Enabled=(NavSys&SYS_GPS)&&(FreqType&FREQTYPE_L1); - G06->Enabled=(NavSys&SYS_GPS)&&(FreqType&FREQTYPE_L1); - G07->Enabled=(NavSys&SYS_GPS)&&(FreqType&FREQTYPE_L1); - G08->Enabled=(NavSys&SYS_GPS)&&(FreqType&FREQTYPE_L1); - G12->Enabled=(NavSys&SYS_GPS)&&(FreqType&FREQTYPE_L1); - G14->Enabled=(NavSys&SYS_GPS)&&(FreqType&FREQTYPE_L2); - G15->Enabled=(NavSys&SYS_GPS)&&(FreqType&FREQTYPE_L2); - G16->Enabled=(NavSys&SYS_GPS)&&(FreqType&FREQTYPE_L2); - G17->Enabled=(NavSys&SYS_GPS)&&(FreqType&FREQTYPE_L2); - G18->Enabled=(NavSys&SYS_GPS)&&(FreqType&FREQTYPE_L2); - G19->Enabled=(NavSys&SYS_GPS)&&(FreqType&FREQTYPE_L2); - G20->Enabled=(NavSys&SYS_GPS)&&(FreqType&FREQTYPE_L2); - G21->Enabled=(NavSys&SYS_GPS)&&(FreqType&FREQTYPE_L2); - G22->Enabled=(NavSys&SYS_GPS)&&(FreqType&FREQTYPE_L2); - G23->Enabled=(NavSys&SYS_GPS)&&(FreqType&FREQTYPE_L2); - G24->Enabled=(NavSys&SYS_GPS)&&(FreqType&FREQTYPE_L3); - G25->Enabled=(NavSys&SYS_GPS)&&(FreqType&FREQTYPE_L3); - G26->Enabled=(NavSys&SYS_GPS)&&(FreqType&FREQTYPE_L3); - R01->Enabled=(NavSys&SYS_GLO)&&(FreqType&FREQTYPE_L1); - R02->Enabled=(NavSys&SYS_GLO)&&(FreqType&FREQTYPE_L1); - R14->Enabled=(NavSys&SYS_GLO)&&(FreqType&FREQTYPE_L2); - R19->Enabled=(NavSys&SYS_GLO)&&(FreqType&FREQTYPE_L2); - R44->Enabled=(NavSys&SYS_GLO)&&(FreqType&FREQTYPE_L3); - R45->Enabled=(NavSys&SYS_GLO)&&(FreqType&FREQTYPE_L3); - R46->Enabled=(NavSys&SYS_GLO)&&(FreqType&FREQTYPE_L3); - R66->Enabled=(NavSys&SYS_GLO)&&(FreqType&FREQTYPE_L1); // - R67->Enabled=(NavSys&SYS_GLO)&&(FreqType&FREQTYPE_L1); // - R68->Enabled=(NavSys&SYS_GLO)&&(FreqType&FREQTYPE_L1); // - R30->Enabled=(NavSys&SYS_GLO)&&(FreqType&FREQTYPE_L2); // - R31->Enabled=(NavSys&SYS_GLO)&&(FreqType&FREQTYPE_L2); // - R33->Enabled=(NavSys&SYS_GLO)&&(FreqType&FREQTYPE_L2); // - E01->Enabled=(NavSys&SYS_GAL)&&(FreqType&FREQTYPE_L1); - E10->Enabled=(NavSys&SYS_GAL)&&(FreqType&FREQTYPE_L1); - E11->Enabled=(NavSys&SYS_GAL)&&(FreqType&FREQTYPE_L1); - E12->Enabled=(NavSys&SYS_GAL)&&(FreqType&FREQTYPE_L1); - E13->Enabled=(NavSys&SYS_GAL)&&(FreqType&FREQTYPE_L1); - E24->Enabled=(NavSys&SYS_GAL)&&(FreqType&FREQTYPE_L3); - E25->Enabled=(NavSys&SYS_GAL)&&(FreqType&FREQTYPE_L3); - E26->Enabled=(NavSys&SYS_GAL)&&(FreqType&FREQTYPE_L3); - E27->Enabled=(NavSys&SYS_GAL)&&(FreqType&FREQTYPE_L2); - E28->Enabled=(NavSys&SYS_GAL)&&(FreqType&FREQTYPE_L2); - E29->Enabled=(NavSys&SYS_GAL)&&(FreqType&FREQTYPE_L2); - E30->Enabled=(NavSys&SYS_GAL)&&(FreqType&FREQTYPE_L4); - E31->Enabled=(NavSys&SYS_GAL)&&(FreqType&FREQTYPE_L4); - E32->Enabled=(NavSys&SYS_GAL)&&(FreqType&FREQTYPE_L4); - E33->Enabled=(NavSys&SYS_GAL)&&(FreqType&FREQTYPE_L4); - E34->Enabled=(NavSys&SYS_GAL)&&(FreqType&FREQTYPE_L4); - E37->Enabled=(NavSys&SYS_GAL)&&(FreqType&FREQTYPE_L5); - E38->Enabled=(NavSys&SYS_GAL)&&(FreqType&FREQTYPE_L5); - E39->Enabled=(NavSys&SYS_GAL)&&(FreqType&FREQTYPE_L5); - J01->Enabled=(NavSys&SYS_QZS)&&(FreqType&FREQTYPE_L1); - J07->Enabled=(NavSys&SYS_QZS)&&(FreqType&FREQTYPE_L1); - J08->Enabled=(NavSys&SYS_QZS)&&(FreqType&FREQTYPE_L1); - J09->Enabled=(NavSys&SYS_QZS)&&(FreqType&FREQTYPE_L1); - J11->Enabled=(NavSys&SYS_QZS)&&(FreqType&FREQTYPE_L1); - J12->Enabled=(NavSys&SYS_QZS)&&(FreqType&FREQTYPE_L1); - J13->Enabled=(NavSys&SYS_QZS)&&(FreqType&FREQTYPE_L1); - J16->Enabled=(NavSys&SYS_QZS)&&(FreqType&FREQTYPE_L2); - J17->Enabled=(NavSys&SYS_QZS)&&(FreqType&FREQTYPE_L2); - J18->Enabled=(NavSys&SYS_QZS)&&(FreqType&FREQTYPE_L2); - J24->Enabled=(NavSys&SYS_QZS)&&(FreqType&FREQTYPE_L3); - J25->Enabled=(NavSys&SYS_QZS)&&(FreqType&FREQTYPE_L3); - J26->Enabled=(NavSys&SYS_QZS)&&(FreqType&FREQTYPE_L3); - J57->Enabled=(NavSys&SYS_QZS)&&(FreqType&FREQTYPE_L3); // - J58->Enabled=(NavSys&SYS_QZS)&&(FreqType&FREQTYPE_L3); // - J59->Enabled=(NavSys&SYS_QZS)&&(FreqType&FREQTYPE_L3); // - J60->Enabled=(NavSys&SYS_QZS)&&(FreqType&FREQTYPE_L4); // - J34->Enabled=(NavSys&SYS_QZS)&&(FreqType&FREQTYPE_L4); // - J35->Enabled=(NavSys&SYS_QZS)&&(FreqType&FREQTYPE_L4); - J36->Enabled=(NavSys&SYS_QZS)&&(FreqType&FREQTYPE_L4); - J33->Enabled=(NavSys&SYS_QZS)&&(FreqType&FREQTYPE_L4); - C40->Enabled=(NavSys&SYS_CMP)&&(FreqType&FREQTYPE_L1); // - C41->Enabled=(NavSys&SYS_CMP)&&(FreqType&FREQTYPE_L1); // - C18->Enabled=(NavSys&SYS_CMP)&&(FreqType&FREQTYPE_L1); // - C27->Enabled=(NavSys&SYS_CMP)&&(FreqType&FREQTYPE_L2); - C28->Enabled=(NavSys&SYS_CMP)&&(FreqType&FREQTYPE_L2); - C29->Enabled=(NavSys&SYS_CMP)&&(FreqType&FREQTYPE_L2); - C42->Enabled=(NavSys&SYS_CMP)&&(FreqType&FREQTYPE_L4); - C43->Enabled=(NavSys&SYS_CMP)&&(FreqType&FREQTYPE_L4); - C33->Enabled=(NavSys&SYS_CMP)&&(FreqType&FREQTYPE_L4); - C56->Enabled=(NavSys&SYS_CMP)&&(FreqType&FREQTYPE_L5); // - C02->Enabled=(NavSys&SYS_CMP)&&(FreqType&FREQTYPE_L5); // - C12->Enabled=(NavSys&SYS_CMP)&&(FreqType&FREQTYPE_L5); // - C07->Enabled=(NavSys&SYS_CMP)&&(FreqType&FREQTYPE_L5); // - C08->Enabled=(NavSys&SYS_CMP)&&(FreqType&FREQTYPE_L5); // - C13->Enabled=(NavSys&SYS_CMP)&&(FreqType&FREQTYPE_L5); // - C57->Enabled=(NavSys&SYS_CMP)&&(FreqType&FREQTYPE_L3); // - C58->Enabled=(NavSys&SYS_CMP)&&(FreqType&FREQTYPE_L3); // - C26->Enabled=(NavSys&SYS_CMP)&&(FreqType&FREQTYPE_L3); // - C61->Enabled=(NavSys&SYS_CMP)&&(FreqType&FREQTYPE_L2); // - C62->Enabled=(NavSys&SYS_CMP)&&(FreqType&FREQTYPE_L2); // - C63->Enabled=(NavSys&SYS_CMP)&&(FreqType&FREQTYPE_L2); // - C64->Enabled=(NavSys&SYS_CMP)&&(FreqType&FREQTYPE_L6); // - C65->Enabled=(NavSys&SYS_CMP)&&(FreqType&FREQTYPE_L6); // - C39->Enabled=(NavSys&SYS_CMP)&&(FreqType&FREQTYPE_L6); // - C69->Enabled=(NavSys&SYS_CMP)&&(FreqType&FREQTYPE_L4); // - C70->Enabled=(NavSys&SYS_CMP)&&(FreqType&FREQTYPE_L4); // - C34->Enabled=(NavSys&SYS_CMP)&&(FreqType&FREQTYPE_L4); // - I49->Enabled=(NavSys&SYS_IRN)&&(FreqType&FREQTYPE_L1); - I50->Enabled=(NavSys&SYS_IRN)&&(FreqType&FREQTYPE_L1); - I51->Enabled=(NavSys&SYS_IRN)&&(FreqType&FREQTYPE_L1); - I26->Enabled=(NavSys&SYS_IRN)&&(FreqType&FREQTYPE_L1); - I52->Enabled=(NavSys&SYS_IRN)&&(FreqType&FREQTYPE_L2); - I53->Enabled=(NavSys&SYS_IRN)&&(FreqType&FREQTYPE_L2); - I54->Enabled=(NavSys&SYS_IRN)&&(FreqType&FREQTYPE_L2); - I55->Enabled=(NavSys&SYS_IRN)&&(FreqType&FREQTYPE_L2); - I56->Enabled=(NavSys&SYS_IRN)&&(FreqType&FREQTYPE_L2); - I02->Enabled=(NavSys&SYS_IRN)&&(FreqType&FREQTYPE_L3); - I12->Enabled=(NavSys&SYS_IRN)&&(FreqType&FREQTYPE_L3); - S01->Enabled=(NavSys&SYS_SBS)&&(FreqType&FREQTYPE_L1); - S24->Enabled=(NavSys&SYS_SBS)&&(FreqType&FREQTYPE_L3); - S25->Enabled=(NavSys&SYS_SBS)&&(FreqType&FREQTYPE_L3); - S26->Enabled=(NavSys&SYS_SBS)&&(FreqType&FREQTYPE_L3); +void __fastcall TCodeOptDialog::UpdateEnable(void) { + G01->Enabled = (NavSys & SYS_GPS) && (FreqType & FREQTYPE_L1); + G02->Enabled = (NavSys & SYS_GPS) && (FreqType & FREQTYPE_L1); + G03->Enabled = (NavSys & SYS_GPS) && (FreqType & FREQTYPE_L1); + G04->Enabled = (NavSys & SYS_GPS) && (FreqType & FREQTYPE_L1); + G05->Enabled = (NavSys & SYS_GPS) && (FreqType & FREQTYPE_L1); + G06->Enabled = (NavSys & SYS_GPS) && (FreqType & FREQTYPE_L1); + G07->Enabled = (NavSys & SYS_GPS) && (FreqType & FREQTYPE_L1); + G08->Enabled = (NavSys & SYS_GPS) && (FreqType & FREQTYPE_L1); + G12->Enabled = (NavSys & SYS_GPS) && (FreqType & FREQTYPE_L1); + G14->Enabled = (NavSys & SYS_GPS) && (FreqType & FREQTYPE_L2); + G15->Enabled = (NavSys & SYS_GPS) && (FreqType & FREQTYPE_L2); + G16->Enabled = (NavSys & SYS_GPS) && (FreqType & FREQTYPE_L2); + G17->Enabled = (NavSys & SYS_GPS) && (FreqType & FREQTYPE_L2); + G18->Enabled = (NavSys & SYS_GPS) && (FreqType & FREQTYPE_L2); + G19->Enabled = (NavSys & SYS_GPS) && (FreqType & FREQTYPE_L2); + G20->Enabled = (NavSys & SYS_GPS) && (FreqType & FREQTYPE_L2); + G21->Enabled = (NavSys & SYS_GPS) && (FreqType & FREQTYPE_L2); + G22->Enabled = (NavSys & SYS_GPS) && (FreqType & FREQTYPE_L2); + G23->Enabled = (NavSys & SYS_GPS) && (FreqType & FREQTYPE_L2); + G24->Enabled = (NavSys & SYS_GPS) && (FreqType & FREQTYPE_L3); + G25->Enabled = (NavSys & SYS_GPS) && (FreqType & FREQTYPE_L3); + G26->Enabled = (NavSys & SYS_GPS) && (FreqType & FREQTYPE_L3); + R01->Enabled = (NavSys & SYS_GLO) && (FreqType & FREQTYPE_L1); + R02->Enabled = (NavSys & SYS_GLO) && (FreqType & FREQTYPE_L1); + R14->Enabled = (NavSys & SYS_GLO) && (FreqType & FREQTYPE_L2); + R19->Enabled = (NavSys & SYS_GLO) && (FreqType & FREQTYPE_L2); + R44->Enabled = (NavSys & SYS_GLO) && (FreqType & FREQTYPE_L3); + R45->Enabled = (NavSys & SYS_GLO) && (FreqType & FREQTYPE_L3); + R46->Enabled = (NavSys & SYS_GLO) && (FreqType & FREQTYPE_L3); + R66->Enabled = (NavSys & SYS_GLO) && (FreqType & FREQTYPE_L1); // + R67->Enabled = (NavSys & SYS_GLO) && (FreqType & FREQTYPE_L1); // + R68->Enabled = (NavSys & SYS_GLO) && (FreqType & FREQTYPE_L1); // + R30->Enabled = (NavSys & SYS_GLO) && (FreqType & FREQTYPE_L2); // + R31->Enabled = (NavSys & SYS_GLO) && (FreqType & FREQTYPE_L2); // + R33->Enabled = (NavSys & SYS_GLO) && (FreqType & FREQTYPE_L2); // + E01->Enabled = (NavSys & SYS_GAL) && (FreqType & FREQTYPE_L1); + E10->Enabled = (NavSys & SYS_GAL) && (FreqType & FREQTYPE_L1); + E11->Enabled = (NavSys & SYS_GAL) && (FreqType & FREQTYPE_L1); + E12->Enabled = (NavSys & SYS_GAL) && (FreqType & FREQTYPE_L1); + E13->Enabled = (NavSys & SYS_GAL) && (FreqType & FREQTYPE_L1); + E24->Enabled = (NavSys & SYS_GAL) && (FreqType & FREQTYPE_L3); + E25->Enabled = (NavSys & SYS_GAL) && (FreqType & FREQTYPE_L3); + E26->Enabled = (NavSys & SYS_GAL) && (FreqType & FREQTYPE_L3); + E27->Enabled = (NavSys & SYS_GAL) && (FreqType & FREQTYPE_L2); + E28->Enabled = (NavSys & SYS_GAL) && (FreqType & FREQTYPE_L2); + E29->Enabled = (NavSys & SYS_GAL) && (FreqType & FREQTYPE_L2); + E30->Enabled = (NavSys & SYS_GAL) && (FreqType & FREQTYPE_L4); + E31->Enabled = (NavSys & SYS_GAL) && (FreqType & FREQTYPE_L4); + E32->Enabled = (NavSys & SYS_GAL) && (FreqType & FREQTYPE_L4); + E33->Enabled = (NavSys & SYS_GAL) && (FreqType & FREQTYPE_L4); + E34->Enabled = (NavSys & SYS_GAL) && (FreqType & FREQTYPE_L4); + E37->Enabled = (NavSys & SYS_GAL) && (FreqType & FREQTYPE_L5); + E38->Enabled = (NavSys & SYS_GAL) && (FreqType & FREQTYPE_L5); + E39->Enabled = (NavSys & SYS_GAL) && (FreqType & FREQTYPE_L5); + J01->Enabled = (NavSys & SYS_QZS) && (FreqType & FREQTYPE_L1); + J07->Enabled = (NavSys & SYS_QZS) && (FreqType & FREQTYPE_L1); + J08->Enabled = (NavSys & SYS_QZS) && (FreqType & FREQTYPE_L1); + J09->Enabled = (NavSys & SYS_QZS) && (FreqType & FREQTYPE_L1); + J11->Enabled = (NavSys & SYS_QZS) && (FreqType & FREQTYPE_L1); + J12->Enabled = (NavSys & SYS_QZS) && (FreqType & FREQTYPE_L1); + J13->Enabled = (NavSys & SYS_QZS) && (FreqType & FREQTYPE_L1); + J16->Enabled = (NavSys & SYS_QZS) && (FreqType & FREQTYPE_L2); + J17->Enabled = (NavSys & SYS_QZS) && (FreqType & FREQTYPE_L2); + J18->Enabled = (NavSys & SYS_QZS) && (FreqType & FREQTYPE_L2); + J24->Enabled = (NavSys & SYS_QZS) && (FreqType & FREQTYPE_L3); + J25->Enabled = (NavSys & SYS_QZS) && (FreqType & FREQTYPE_L3); + J26->Enabled = (NavSys & SYS_QZS) && (FreqType & FREQTYPE_L3); + J57->Enabled = (NavSys & SYS_QZS) && (FreqType & FREQTYPE_L3); // + J58->Enabled = (NavSys & SYS_QZS) && (FreqType & FREQTYPE_L3); // + J59->Enabled = (NavSys & SYS_QZS) && (FreqType & FREQTYPE_L3); // + J60->Enabled = (NavSys & SYS_QZS) && (FreqType & FREQTYPE_L4); // + J34->Enabled = (NavSys & SYS_QZS) && (FreqType & FREQTYPE_L4); // + J35->Enabled = (NavSys & SYS_QZS) && (FreqType & FREQTYPE_L4); + J36->Enabled = (NavSys & SYS_QZS) && (FreqType & FREQTYPE_L4); + J33->Enabled = (NavSys & SYS_QZS) && (FreqType & FREQTYPE_L4); + C40->Enabled = (NavSys & SYS_CMP) && (FreqType & FREQTYPE_L1); // + C41->Enabled = (NavSys & SYS_CMP) && (FreqType & FREQTYPE_L1); // + C18->Enabled = (NavSys & SYS_CMP) && (FreqType & FREQTYPE_L1); // + C27->Enabled = (NavSys & SYS_CMP) && (FreqType & FREQTYPE_L2); + C28->Enabled = (NavSys & SYS_CMP) && (FreqType & FREQTYPE_L2); + C29->Enabled = (NavSys & SYS_CMP) && (FreqType & FREQTYPE_L2); + C42->Enabled = (NavSys & SYS_CMP) && (FreqType & FREQTYPE_L4); + C43->Enabled = (NavSys & SYS_CMP) && (FreqType & FREQTYPE_L4); + C33->Enabled = (NavSys & SYS_CMP) && (FreqType & FREQTYPE_L4); + C56->Enabled = (NavSys & SYS_CMP) && (FreqType & FREQTYPE_L5); // + C02->Enabled = (NavSys & SYS_CMP) && (FreqType & FREQTYPE_L5); // + C12->Enabled = (NavSys & SYS_CMP) && (FreqType & FREQTYPE_L5); // + C07->Enabled = (NavSys & SYS_CMP) && (FreqType & FREQTYPE_L5); // + C08->Enabled = (NavSys & SYS_CMP) && (FreqType & FREQTYPE_L5); // + C13->Enabled = (NavSys & SYS_CMP) && (FreqType & FREQTYPE_L5); // + C57->Enabled = (NavSys & SYS_CMP) && (FreqType & FREQTYPE_L3); // + C58->Enabled = (NavSys & SYS_CMP) && (FreqType & FREQTYPE_L3); // + C26->Enabled = (NavSys & SYS_CMP) && (FreqType & FREQTYPE_L3); // + C61->Enabled = (NavSys & SYS_CMP) && (FreqType & FREQTYPE_L2); // + C62->Enabled = (NavSys & SYS_CMP) && (FreqType & FREQTYPE_L2); // + C63->Enabled = (NavSys & SYS_CMP) && (FreqType & FREQTYPE_L2); // + C64->Enabled = (NavSys & SYS_CMP) && (FreqType & FREQTYPE_L6); // + C65->Enabled = (NavSys & SYS_CMP) && (FreqType & FREQTYPE_L6); // + C39->Enabled = (NavSys & SYS_CMP) && (FreqType & FREQTYPE_L6); // + C69->Enabled = (NavSys & SYS_CMP) && (FreqType & FREQTYPE_L4); // + C70->Enabled = (NavSys & SYS_CMP) && (FreqType & FREQTYPE_L4); // + C34->Enabled = (NavSys & SYS_CMP) && (FreqType & FREQTYPE_L4); // + I49->Enabled = (NavSys & SYS_IRN) && (FreqType & FREQTYPE_L1); + I50->Enabled = (NavSys & SYS_IRN) && (FreqType & FREQTYPE_L1); + I51->Enabled = (NavSys & SYS_IRN) && (FreqType & FREQTYPE_L1); + I26->Enabled = (NavSys & SYS_IRN) && (FreqType & FREQTYPE_L1); + I52->Enabled = (NavSys & SYS_IRN) && (FreqType & FREQTYPE_L2); + I53->Enabled = (NavSys & SYS_IRN) && (FreqType & FREQTYPE_L2); + I54->Enabled = (NavSys & SYS_IRN) && (FreqType & FREQTYPE_L2); + I55->Enabled = (NavSys & SYS_IRN) && (FreqType & FREQTYPE_L2); + I56->Enabled = (NavSys & SYS_IRN) && (FreqType & FREQTYPE_L2); + I02->Enabled = (NavSys & SYS_IRN) && (FreqType & FREQTYPE_L3); + I12->Enabled = (NavSys & SYS_IRN) && (FreqType & FREQTYPE_L3); + S01->Enabled = (NavSys & SYS_SBS) && (FreqType & FREQTYPE_L1); + S24->Enabled = (NavSys & SYS_SBS) && (FreqType & FREQTYPE_L3); + S25->Enabled = (NavSys & SYS_SBS) && (FreqType & FREQTYPE_L3); + S26->Enabled = (NavSys & SYS_SBS) && (FreqType & FREQTYPE_L3); } //--------------------------------------------------------------------------- - diff --git a/app/winapp/rtkconv/codeopt.h b/app/winapp/rtkconv/codeopt.h index 87303b60e..72a429f45 100644 --- a/app/winapp/rtkconv/codeopt.h +++ b/app/winapp/rtkconv/codeopt.h @@ -4,147 +4,147 @@ //--------------------------------------------------------------------------- #include #include -#include #include +#include //--------------------------------------------------------------------------- -class TCodeOptDialog : public TForm -{ -__published: - TButton *BtnOk; - TButton *BtnCancel; - TGroupBox *GroupBox1; - TCheckBox *G01; - TCheckBox *G02; - TCheckBox *G03; - TCheckBox *G04; - TCheckBox *G06; - TCheckBox *G07; - TCheckBox *G05; - TCheckBox *G14; - TCheckBox *G15; - TCheckBox *G16; - TCheckBox *G17; - TCheckBox *G19; - TCheckBox *G20; - TCheckBox *G18; - TCheckBox *G22; - TCheckBox *G24; - TCheckBox *G25; - TCheckBox *G26; - TGroupBox *GroupBox2; - TCheckBox *R01; - TCheckBox *R02; - TCheckBox *R14; - TCheckBox *R19; - TGroupBox *GroupBox3; - TCheckBox *E01; - TCheckBox *E10; - TCheckBox *E11; - TCheckBox *E12; - TCheckBox *E13; - TCheckBox *E24; - TCheckBox *E25; - TCheckBox *E26; - TCheckBox *E27; - TCheckBox *E28; - TCheckBox *E29; - TCheckBox *E30; - TCheckBox *E32; - TCheckBox *E33; - TCheckBox *E31; - TCheckBox *E37; - TCheckBox *E38; - TCheckBox *E39; - TGroupBox *GroupBox4; - TCheckBox *J01; - TCheckBox *J07; - TCheckBox *J08; - TCheckBox *J09; - TCheckBox *J11; - TCheckBox *J12; - TCheckBox *J13; - TCheckBox *J16; - TCheckBox *J17; - TCheckBox *J18; - TCheckBox *J24; - TCheckBox *J26; - TCheckBox *J35; - TCheckBox *J25; - TGroupBox *GroupBox5; - TCheckBox *S01; - TCheckBox *S24; - TCheckBox *S25; - TCheckBox *S26; - TCheckBox *J36; - TCheckBox *G21; - TCheckBox *G08; - TCheckBox *G12; - TCheckBox *G23; - TCheckBox *E34; - TButton *BtnSetAll; - TCheckBox *J33; - TGroupBox *GroupBox6; - TCheckBox *C40; - TCheckBox *C42; - TCheckBox *C27; - TCheckBox *C28; - TCheckBox *C29; - TCheckBox *C41; - TCheckBox *C18; - TCheckBox *C43; - TCheckBox *C33; - TCheckBox *R44; - TCheckBox *R46; - TCheckBox *R45; - TGroupBox *GroupBox7; - TCheckBox *I49; - TCheckBox *I54; - TCheckBox *I26; - TCheckBox *I52; - TCheckBox *I53; - TCheckBox *I50; - TCheckBox *I51; - TCheckBox *I55; - TCheckBox *I56; - TCheckBox *I02; - TCheckBox *I12; - TCheckBox *R66; - TCheckBox *R67; - TCheckBox *R68; - TCheckBox *R30; - TCheckBox *R31; - TCheckBox *R33; - TCheckBox *J57; - TCheckBox *J58; - TCheckBox *J59; - TCheckBox *J60; - TCheckBox *J34; - TCheckBox *C56; - TCheckBox *C02; - TCheckBox *C12; - TCheckBox *C07; - TCheckBox *C08; - TCheckBox *C13; - TCheckBox *C57; - TCheckBox *C58; - TCheckBox *C26; - TCheckBox *C61; - TCheckBox *C62; - TCheckBox *C63; - TCheckBox *C64; - TCheckBox *C65; - TCheckBox *C39; - TCheckBox *C69; - TCheckBox *C70; - TCheckBox *C34; - void __fastcall FormShow(TObject *Sender); - void __fastcall BtnOkClick(TObject *Sender); - void __fastcall BtnSetAllClick(TObject *Sender); -private: - void __fastcall UpdateEnable(void); -public: - int NavSys,FreqType; - __fastcall TCodeOptDialog(TComponent* Owner); +class TCodeOptDialog : public TForm { + __published : TButton *BtnOk; + TButton *BtnCancel; + TGroupBox *GroupBox1; + TCheckBox *G01; + TCheckBox *G02; + TCheckBox *G03; + TCheckBox *G04; + TCheckBox *G06; + TCheckBox *G07; + TCheckBox *G05; + TCheckBox *G14; + TCheckBox *G15; + TCheckBox *G16; + TCheckBox *G17; + TCheckBox *G19; + TCheckBox *G20; + TCheckBox *G18; + TCheckBox *G22; + TCheckBox *G24; + TCheckBox *G25; + TCheckBox *G26; + TGroupBox *GroupBox2; + TCheckBox *R01; + TCheckBox *R02; + TCheckBox *R14; + TCheckBox *R19; + TGroupBox *GroupBox3; + TCheckBox *E01; + TCheckBox *E10; + TCheckBox *E11; + TCheckBox *E12; + TCheckBox *E13; + TCheckBox *E24; + TCheckBox *E25; + TCheckBox *E26; + TCheckBox *E27; + TCheckBox *E28; + TCheckBox *E29; + TCheckBox *E30; + TCheckBox *E32; + TCheckBox *E33; + TCheckBox *E31; + TCheckBox *E37; + TCheckBox *E38; + TCheckBox *E39; + TGroupBox *GroupBox4; + TCheckBox *J01; + TCheckBox *J07; + TCheckBox *J08; + TCheckBox *J09; + TCheckBox *J11; + TCheckBox *J12; + TCheckBox *J13; + TCheckBox *J16; + TCheckBox *J17; + TCheckBox *J18; + TCheckBox *J24; + TCheckBox *J26; + TCheckBox *J35; + TCheckBox *J25; + TGroupBox *GroupBox5; + TCheckBox *S01; + TCheckBox *S24; + TCheckBox *S25; + TCheckBox *S26; + TCheckBox *J36; + TCheckBox *G21; + TCheckBox *G08; + TCheckBox *G12; + TCheckBox *G23; + TCheckBox *E34; + TButton *BtnSetAll; + TCheckBox *J33; + TGroupBox *GroupBox6; + TCheckBox *C40; + TCheckBox *C42; + TCheckBox *C27; + TCheckBox *C28; + TCheckBox *C29; + TCheckBox *C41; + TCheckBox *C18; + TCheckBox *C43; + TCheckBox *C33; + TCheckBox *R44; + TCheckBox *R46; + TCheckBox *R45; + TGroupBox *GroupBox7; + TCheckBox *I49; + TCheckBox *I54; + TCheckBox *I26; + TCheckBox *I52; + TCheckBox *I53; + TCheckBox *I50; + TCheckBox *I51; + TCheckBox *I55; + TCheckBox *I56; + TCheckBox *I02; + TCheckBox *I12; + TCheckBox *R66; + TCheckBox *R67; + TCheckBox *R68; + TCheckBox *R30; + TCheckBox *R31; + TCheckBox *R33; + TCheckBox *J57; + TCheckBox *J58; + TCheckBox *J59; + TCheckBox *J60; + TCheckBox *J34; + TCheckBox *C56; + TCheckBox *C02; + TCheckBox *C12; + TCheckBox *C07; + TCheckBox *C08; + TCheckBox *C13; + TCheckBox *C57; + TCheckBox *C58; + TCheckBox *C26; + TCheckBox *C61; + TCheckBox *C62; + TCheckBox *C63; + TCheckBox *C64; + TCheckBox *C65; + TCheckBox *C39; + TCheckBox *C69; + TCheckBox *C70; + TCheckBox *C34; + void __fastcall FormShow(TObject *Sender); + void __fastcall BtnOkClick(TObject *Sender); + void __fastcall BtnSetAllClick(TObject *Sender); + + private: + void __fastcall UpdateEnable(void); + + public: + int NavSys, FreqType; + __fastcall TCodeOptDialog(TComponent *Owner); }; //---------------------------------------------------------------------- extern PACKAGE TCodeOptDialog *CodeOptDialog; diff --git a/app/winapp/rtkconv/convmain.cpp b/app/winapp/rtkconv/convmain.cpp index df004f4fa..4b0d380e5 100644 --- a/app/winapp/rtkconv/convmain.cpp +++ b/app/winapp/rtkconv/convmain.cpp @@ -24,14 +24,15 @@ #pragma hdrstop #include "convmain.h" -#include "timedlg.h" -#include "confdlg.h" + #include "aboutdlg.h" -#include "startdlg.h" -#include "keydlg.h" +#include "confdlg.h" #include "convopt.h" -#include "viewer.h" +#include "keydlg.h" #include "rtklib.h" +#include "startdlg.h" +#include "timedlg.h" +#include "viewer.h" //--------------------------------------------------------------------------- #pragma package(smart_init) @@ -39,1232 +40,1209 @@ TMainWindow *MainWindow; -#define PRGNAME "RTKCONV" // program name -#define MAXHIST 20 // max number of histories -#define TSTARTMARGIN 60.0 // time margin for file name replacement -#define TRACEFILE "rtkconv.trace" // trace file +#define PRGNAME "RTKCONV" // program name +#define MAXHIST 20 // max number of histories +#define TSTARTMARGIN 60.0 // time margin for file name replacement +#define TRACEFILE "rtkconv.trace" // trace file -static int abortf=0; +static int abortf = 0; // show message in message area --------------------------------------------- extern "C" { -extern int showmsg(const char *format,...) -{ - static int i=0; - va_list arg; - char buff[1024]; - va_start(arg,format); vsprintf(buff,format,arg); va_end(arg); - MainWindow->Message->Caption=buff; - if (++i%100==0) Application->ProcessMessages(); - return abortf; +extern int showmsg(const char *format, ...) { + static int i = 0; + va_list arg; + char buff[1024]; + va_start(arg, format); + vsprintf(buff, format, arg); + va_end(arg); + MainWindow->Message->Caption = buff; + if (++i % 100 == 0) Application->ProcessMessages(); + return abortf; } } // constructor -------------------------------------------------------------- -__fastcall TMainWindow::TMainWindow(TComponent* Owner) - : TForm(Owner) -{ - gtime_t time0={0}; - int i; - char file[1024]="rtkconv.exe",*p; - - ::GetModuleFileName(NULL,file,sizeof(file)); - if (!(p=strrchr(file,'.'))) p=file+strlen(file); - strcpy(p,".ini"); - IniFile=file; - - DoubleBuffered=true; - Format->Items->Clear(); - Format->Items->Add("Auto"); - for (i=0;i<=MAXRCVFMT;i++) { - Format->Items->Add(formatstrs[i]); - } - Format->Items->Add(formatstrs[STRFMT_RINEX]); - RnxTime=time0; - EventEna=0; +__fastcall TMainWindow::TMainWindow(TComponent *Owner) : TForm(Owner) { + gtime_t time0 = {0}; + int i; + char file[1024] = "rtkconv.exe", *p; + + ::GetModuleFileName(NULL, file, sizeof(file)); + if (!(p = strrchr(file, '.'))) p = file + strlen(file); + strcpy(p, ".ini"); + IniFile = file; + + DoubleBuffered = true; + Format->Items->Clear(); + Format->Items->Add("Auto"); + for (i = 0; i <= MAXRCVFMT; i++) { + Format->Items->Add(formatstrs[i]); + } + Format->Items->Add(formatstrs[STRFMT_RINEX]); + RnxTime = time0; + EventEna = 0; } // callback on form create -------------------------------------------------- -void __fastcall TMainWindow::FormCreate(TObject *Sender) -{ - AnsiString s; - - Caption=s.sprintf("%s-%s %s",PRGNAME,VER_RTKLIB,PATCH_LEVEL); - - ::DragAcceptFiles(Handle,true); +void __fastcall TMainWindow::FormCreate(TObject *Sender) { + AnsiString s; + + Caption = s.sprintf("%s-%s %s", PRGNAME, VER_RTKLIB, PATCH_LEVEL); + + ::DragAcceptFiles(Handle, true); } // callback on form show ---------------------------------------------------- -void __fastcall TMainWindow::FormShow(TObject *Sender) -{ - char *p,*argv[32],buff[1024]; - int argc=0; - - strcpy(buff,GetCommandLine()); - - for (p=buff;*p&&argc<32;p++) { - if (*p==' ') continue; - if (*p=='"') { - argv[argc++]=p+1; - if (!(p=strchr(p+1,'"'))) break; - } - else { - argv[argc++]=p; - if (!(p=strchr(p+1,' '))) break; - } - *p='\0'; - } - for (int i=1;iWidth-4)/5; - - for (int i=0;i<5;i++) { - btns[i]->Width=w-2; - btns[i]->Left=i*w+2; - } - BtnAbort->Width=BtnConvert->Width; - BtnAbort->Left =BtnConvert->Left; +void __fastcall TMainWindow::Panel4Resize(TObject *Sender) { + TBitBtn *btns[] = {BtnPlot, BtnPost, BtnOptions, BtnConvert, BtnExit}; + int w = (Panel4->Width - 4) / 5; + + for (int i = 0; i < 5; i++) { + btns[i]->Width = w - 2; + btns[i]->Left = i * w + 2; + } + BtnAbort->Width = BtnConvert->Width; + BtnAbort->Left = BtnConvert->Left; } // callback on panel2 resize ------------------------------------------------ -void __fastcall TMainWindow::Panel2Resize(TObject *Sender) -{ - TButton *btns1[]={ - BtnOutFile1,BtnOutFile2,BtnOutFile3,BtnOutFile4,BtnOutFile5, - BtnOutFile6,BtnOutFile7,BtnOutFile8,BtnOutFile9 - }; - TSpeedButton *btns2[]={ - BtnOutFileView1,BtnOutFileView2,BtnOutFileView3,BtnOutFileView4, - BtnOutFileView5,BtnOutFileView6,BtnOutFileView7,BtnOutFileView8, - BtnOutFileView9 - }; - TEdit *inps[]={ - OutFile1,OutFile2,OutFile3,OutFile4,OutFile5,OutFile6,OutFile7, - OutFile8,OutFile9 - }; - int w=Panel2->Width; - - BtnInFile->Left=w-BtnInFile->Width-5; - BtnInFileView->Left=w-BtnInFile->Width-BtnInFileView->Width-5; - InFile->Width=w-BtnInFile->Width-BtnInFileView->Width-6-InFile->Left; - - Format->Left=w-Format->Width-5; - LabelFormat->Left=Format->Left+3; - BtnOutDir->Left=w-BtnOutDir->Width-Format->Width-6; - OutDir->Width=w-BtnOutDir->Width-Format->Width-7-OutDir->Left; - - for (int i=0;i<9;i++) { - btns1[i]->Left=w-btns1[i]->Width-5; - btns2[i]->Left=w-btns1[i]->Width-btns2[i]->Width-5; - inps[i]->Width=w-btns1[i]->Width-btns2[i]->Width-6-inps[i]->Left; - } - DisableHighlight(); +void __fastcall TMainWindow::Panel2Resize(TObject *Sender) { + TButton *btns1[] = {BtnOutFile1, BtnOutFile2, BtnOutFile3, BtnOutFile4, BtnOutFile5, + BtnOutFile6, BtnOutFile7, BtnOutFile8, BtnOutFile9}; + TSpeedButton *btns2[] = {BtnOutFileView1, BtnOutFileView2, BtnOutFileView3, + BtnOutFileView4, BtnOutFileView5, BtnOutFileView6, + BtnOutFileView7, BtnOutFileView8, BtnOutFileView9}; + TEdit *inps[] = {OutFile1, OutFile2, OutFile3, OutFile4, OutFile5, + OutFile6, OutFile7, OutFile8, OutFile9}; + int w = Panel2->Width; + + BtnInFile->Left = w - BtnInFile->Width - 5; + BtnInFileView->Left = w - BtnInFile->Width - BtnInFileView->Width - 5; + InFile->Width = w - BtnInFile->Width - BtnInFileView->Width - 6 - InFile->Left; + + Format->Left = w - Format->Width - 5; + LabelFormat->Left = Format->Left + 3; + BtnOutDir->Left = w - BtnOutDir->Width - Format->Width - 6; + OutDir->Width = w - BtnOutDir->Width - Format->Width - 7 - OutDir->Left; + + for (int i = 0; i < 9; i++) { + btns1[i]->Left = w - btns1[i]->Width - 5; + btns2[i]->Left = w - btns1[i]->Width - btns2[i]->Width - 5; + inps[i]->Width = w - btns1[i]->Width - btns2[i]->Width - 6 - inps[i]->Left; + } + DisableHighlight(); } // set output file paths ---------------------------------------------------- -void __fastcall TMainWindow::SetOutFiles(AnsiString infile) -{ - TEdit *edit[]={ - OutFile1,OutFile2,OutFile3,OutFile4,OutFile5,OutFile6,OutFile7, - OutFile8,OutFile9 - }; - AnsiString Format_Text=Format->Text; - AnsiString OutDir_Text=OutDir->Text; - char *ifile,ofile[10][1024],*p; - - if (!EventEna) return; - - ifile=infile.c_str(); - if (OutDirEna->Checked) { - if ((p=strrchr(ifile,'\\'))) p++; else p=ifile; - sprintf(ofile[0],"%s\\%s",OutDir_Text.c_str(),p); - } - else { - strcpy(ofile[0],ifile); - } - for (p=ofile[0];*p;p++) { - if (*p=='*'||*p=='?') *p='0'; - } - if (!RnxFile) { - if ((p=strrchr(ofile[0],'.'))) *p='\0'; - sprintf(ofile[1],"%s.obs" ,ofile[0]); - sprintf(ofile[2],"%s.nav" ,ofile[0]); - sprintf(ofile[3],"%s.gnav",ofile[0]); - sprintf(ofile[4],"%s.hnav",ofile[0]); - sprintf(ofile[5],"%s.qnav",ofile[0]); - sprintf(ofile[6],"%s.lnav",ofile[0]); - sprintf(ofile[7],"%s.cnav",ofile[0]); - sprintf(ofile[8],"%s.inav",ofile[0]); - sprintf(ofile[9],"%s.sbs" ,ofile[0]); - } - else { - if ((p=strrchr(ofile[0],'\\'))) *(p+1)='\0'; - else ofile[0][0]='\0'; - sprintf(ofile[1],"%s%%r%%n0.%%yO",ofile[0]); - if (RnxVer>=3&&NavSys&&(NavSys!=SYS_GPS)) { /* ver.3 and mixed system */ - sprintf(ofile[2],"%s%%r%%n0.%%yP",ofile[0]); - } - else { - sprintf(ofile[2],"%s%%r%%n0.%%yN",ofile[0]); - } - sprintf(ofile[3],"%s%%r%%n0.%%yG",ofile[0]); - sprintf(ofile[4],"%s%%r%%n0.%%yH",ofile[0]); - sprintf(ofile[5],"%s%%r%%n0.%%yQ",ofile[0]); - sprintf(ofile[6],"%s%%r%%n0.%%yL",ofile[0]); - sprintf(ofile[7],"%s%%r%%n0.%%yC",ofile[0]); - sprintf(ofile[8],"%s%%r%%n0.%%yI",ofile[0]); - sprintf(ofile[9],"%s%%r%%n0_%%y.sbs",ofile[0]); - } - for (int i=0;i<9;i++) { - if (!strcmp(ofile[i+1],ifile)) strcat(ofile[i+1],"_"); - AnsiString ustr=ofile[i+1]; - edit[i]->Text=ustr; - } +void __fastcall TMainWindow::SetOutFiles(AnsiString infile) { + TEdit *edit[] = {OutFile1, OutFile2, OutFile3, OutFile4, OutFile5, + OutFile6, OutFile7, OutFile8, OutFile9}; + AnsiString Format_Text = Format->Text; + AnsiString OutDir_Text = OutDir->Text; + char *ifile, ofile[10][1024], *p; + + if (!EventEna) return; + + ifile = infile.c_str(); + if (OutDirEna->Checked) { + if ((p = strrchr(ifile, '\\'))) + p++; + else + p = ifile; + sprintf(ofile[0], "%s\\%s", OutDir_Text.c_str(), p); + } else { + strcpy(ofile[0], ifile); + } + for (p = ofile[0]; *p; p++) { + if (*p == '*' || *p == '?') *p = '0'; + } + if (!RnxFile) { + if ((p = strrchr(ofile[0], '.'))) *p = '\0'; + sprintf(ofile[1], "%s.obs", ofile[0]); + sprintf(ofile[2], "%s.nav", ofile[0]); + sprintf(ofile[3], "%s.gnav", ofile[0]); + sprintf(ofile[4], "%s.hnav", ofile[0]); + sprintf(ofile[5], "%s.qnav", ofile[0]); + sprintf(ofile[6], "%s.lnav", ofile[0]); + sprintf(ofile[7], "%s.cnav", ofile[0]); + sprintf(ofile[8], "%s.inav", ofile[0]); + sprintf(ofile[9], "%s.sbs", ofile[0]); + } else { + if ((p = strrchr(ofile[0], '\\'))) + *(p + 1) = '\0'; + else + ofile[0][0] = '\0'; + sprintf(ofile[1], "%s%%r%%n0.%%yO", ofile[0]); + if (RnxVer >= 3 && NavSys && (NavSys != SYS_GPS)) { /* ver.3 and mixed system */ + sprintf(ofile[2], "%s%%r%%n0.%%yP", ofile[0]); + } else { + sprintf(ofile[2], "%s%%r%%n0.%%yN", ofile[0]); + } + sprintf(ofile[3], "%s%%r%%n0.%%yG", ofile[0]); + sprintf(ofile[4], "%s%%r%%n0.%%yH", ofile[0]); + sprintf(ofile[5], "%s%%r%%n0.%%yQ", ofile[0]); + sprintf(ofile[6], "%s%%r%%n0.%%yL", ofile[0]); + sprintf(ofile[7], "%s%%r%%n0.%%yC", ofile[0]); + sprintf(ofile[8], "%s%%r%%n0.%%yI", ofile[0]); + sprintf(ofile[9], "%s%%r%%n0_%%y.sbs", ofile[0]); + } + for (int i = 0; i < 9; i++) { + if (!strcmp(ofile[i + 1], ifile)) strcat(ofile[i + 1], "_"); + AnsiString ustr = ofile[i + 1]; + edit[i]->Text = ustr; + } } // callback on file drag and drop ------------------------------------------- -void __fastcall TMainWindow::DropFiles(TWMDropFiles msg) -{ - char str[1024]; - - if (DragQueryFile((HDROP)msg.Drop,0xFFFFFFFF,NULL,0)<=0) return; - DragQueryFile((HDROP)msg.Drop,0,str,sizeof(str)); - InFile->Text=str; - SetOutFiles(InFile->Text); +void __fastcall TMainWindow::DropFiles(TWMDropFiles msg) { + char str[1024]; + + if (DragQueryFile((HDROP)msg.Drop, 0xFFFFFFFF, NULL, 0) <= 0) return; + DragQueryFile((HDROP)msg.Drop, 0, str, sizeof(str)); + InFile->Text = str; + SetOutFiles(InFile->Text); } // add history -------------------------------------------------------------- -void __fastcall TMainWindow::AddHist(TComboBox *combo) -{ - AnsiString hist=combo->Text; - if (hist=="") return; - TStrings *list=combo->Items; - int i=list->IndexOf(hist); - if (i>=0) list->Delete(i); - list->Insert(0,hist); - for (int i=list->Count-1;i>=MAXHIST;i--) list->Delete(i); - combo->ItemIndex=0; +void __fastcall TMainWindow::AddHist(TComboBox *combo) { + AnsiString hist = combo->Text; + if (hist == "") return; + TStrings *list = combo->Items; + int i = list->IndexOf(hist); + if (i >= 0) list->Delete(i); + list->Insert(0, hist); + for (int i = list->Count - 1; i >= MAXHIST; i--) list->Delete(i); + combo->ItemIndex = 0; } // read histroy from ini-file ----------------------------------------------- -TStringList * __fastcall TMainWindow::ReadList(TIniFile *ini, AnsiString cat, - AnsiString key) -{ - TStringList *list=new TStringList; - AnsiString s,item; - int i; - - for (i=0;i<100;i++) { - item=ini->ReadString(cat,s.sprintf("%s_%03d",key.c_str(),i),""); - if (item!=""&&list->IndexOf(item)<0) list->Add(item); - } - return list; +TStringList *__fastcall TMainWindow::ReadList(TIniFile *ini, AnsiString cat, AnsiString key) { + TStringList *list = new TStringList; + AnsiString s, item; + int i; + + for (i = 0; i < 100; i++) { + item = ini->ReadString(cat, s.sprintf("%s_%03d", key.c_str(), i), ""); + if (item != "" && list->IndexOf(item) < 0) list->Add(item); + } + return list; } // save history to ini-file ------------------------------------------------- -void __fastcall TMainWindow::WriteList(TIniFile *ini, AnsiString cat, - AnsiString key, TStrings *list) -{ - AnsiString s; - int i; - - for (i=0;iCount;i++) { - ini->WriteString(cat,s.sprintf("%s_%03d",key.c_str(),i),list->Strings[i]); - } +void __fastcall TMainWindow::WriteList(TIniFile *ini, AnsiString cat, AnsiString key, + TStrings *list) { + AnsiString s; + int i; + + for (i = 0; i < list->Count; i++) { + ini->WriteString(cat, s.sprintf("%s_%03d", key.c_str(), i), list->Strings[i]); + } } // callback on button-plot -------------------------------------------------- -void __fastcall TMainWindow::BtnPlotClick(TObject *Sender) -{ - AnsiString file1=OutFile1->Text; - AnsiString file2=OutFile2->Text; - AnsiString file3=OutFile3->Text; - AnsiString file4=OutFile4->Text; - AnsiString file5=OutFile5->Text; - AnsiString file6=OutFile6->Text; - AnsiString file7=OutFile7->Text; - AnsiString file8=OutFile8->Text; - AnsiString file9=OutFile9->Text; - AnsiString file[]={file1,file2,file3,file4,file5,file6,file7,file8,file9}; - AnsiString cmd1="rtkplot",cmd2="..\\..\\..\\bin\\rtkplot",opts=" -r"; - TCheckBox *cb[]={ - OutFileEna1,OutFileEna2,OutFileEna3,OutFileEna4,OutFileEna5,OutFileEna6, - OutFileEna7,OutFileEna8,OutFileEna9 - }; - int i,ena[9]; - - for (i=0;i<9;i++) ena[i]=cb[i]->Enabled&&cb[i]->Checked; - - for (i=0;i<9;i++) { - if (ena[i]) opts=opts+" \""+RepPath(file[i])+"\""; - } - if (opts==" -r") return; - - if (!ExecCmd(cmd1+opts)&&!ExecCmd(cmd2+opts)) { - Message->Caption="error : rtkplot execution"; - } +void __fastcall TMainWindow::BtnPlotClick(TObject *Sender) { + AnsiString file1 = OutFile1->Text; + AnsiString file2 = OutFile2->Text; + AnsiString file3 = OutFile3->Text; + AnsiString file4 = OutFile4->Text; + AnsiString file5 = OutFile5->Text; + AnsiString file6 = OutFile6->Text; + AnsiString file7 = OutFile7->Text; + AnsiString file8 = OutFile8->Text; + AnsiString file9 = OutFile9->Text; + AnsiString file[] = {file1, file2, file3, file4, file5, file6, file7, file8, file9}; + AnsiString cmd1 = "rtkplot", cmd2 = "..\\..\\..\\bin\\rtkplot", opts = " -r"; + TCheckBox *cb[] = {OutFileEna1, OutFileEna2, OutFileEna3, OutFileEna4, OutFileEna5, + OutFileEna6, OutFileEna7, OutFileEna8, OutFileEna9}; + int i, ena[9]; + + for (i = 0; i < 9; i++) ena[i] = cb[i]->Enabled && cb[i]->Checked; + + for (i = 0; i < 9; i++) { + if (ena[i]) opts = opts + " \"" + RepPath(file[i]) + "\""; + } + if (opts == " -r") return; + + if (!ExecCmd(cmd1 + opts) && !ExecCmd(cmd2 + opts)) { + Message->Caption = "error : rtkplot execution"; + } } // callback on button-post-proc --------------------------------------------- -void __fastcall TMainWindow::BtnPostClick(TObject *Sender) -{ - AnsiString path2="..\\..\\..\\bin\\"; - AnsiString cmd1=CmdPostExe,cmd2=path2+CmdPostExe,opts=" "; - - if (!OutFileEna1->Checked) return; - - opts=opts+" -r \""+OutFile1->Text+"\""; - opts=opts+" -n \"\" -n \"\" -n \"\""; - - if (OutFileEna9->Checked) { - opts=opts+" -n \""+OutFile9->Text+"\""; - } - if (TimeStartF->Checked) opts=opts+" -ts "+TimeY1->Text+" "+TimeH1->Text; - if (TimeEndF ->Checked) opts=opts+" -te "+TimeY2->Text+" "+TimeH2->Text; - if (TimeIntF ->Checked) opts=opts+" -ti "+TimeInt->Text; - if (TimeUnitF ->Checked) opts=opts+" -tu "+TimeUnit->Text; - - if (!ExecCmd(cmd1+opts)&&!ExecCmd(cmd2+opts)) { - Message->Caption="error : rtkpost execution"; - } +void __fastcall TMainWindow::BtnPostClick(TObject *Sender) { + AnsiString path2 = "..\\..\\..\\bin\\"; + AnsiString cmd1 = CmdPostExe, cmd2 = path2 + CmdPostExe, opts = " "; + + if (!OutFileEna1->Checked) return; + + opts = opts + " -r \"" + OutFile1->Text + "\""; + opts = opts + " -n \"\" -n \"\" -n \"\""; + + if (OutFileEna9->Checked) { + opts = opts + " -n \"" + OutFile9->Text + "\""; + } + if (TimeStartF->Checked) opts = opts + " -ts " + TimeY1->Text + " " + TimeH1->Text; + if (TimeEndF->Checked) opts = opts + " -te " + TimeY2->Text + " " + TimeH2->Text; + if (TimeIntF->Checked) opts = opts + " -ti " + TimeInt->Text; + if (TimeUnitF->Checked) opts = opts + " -tu " + TimeUnit->Text; + + if (!ExecCmd(cmd1 + opts) && !ExecCmd(cmd2 + opts)) { + Message->Caption = "error : rtkpost execution"; + } } // callback on button-options ----------------------------------------------- -void __fastcall TMainWindow::BtnOptionsClick(TObject *Sender) -{ - int rnxfile=RnxFile; - if (ConvOptDialog->ShowModal()!=mrOk) return; - if (RnxFile!=rnxfile) { - SetOutFiles(InFile->Text); - } - UpdateEnable(); +void __fastcall TMainWindow::BtnOptionsClick(TObject *Sender) { + int rnxfile = RnxFile; + if (ConvOptDialog->ShowModal() != mrOk) return; + if (RnxFile != rnxfile) { + SetOutFiles(InFile->Text); + } + UpdateEnable(); } //--------------------------------------------------------------------------- -void __fastcall TMainWindow::BtnAbortClick(TObject *Sender) -{ - abortf=1; -} +void __fastcall TMainWindow::BtnAbortClick(TObject *Sender) { abortf = 1; } // callback on button-convert ----------------------------------------------- -void __fastcall TMainWindow::BtnConvertClick(TObject *Sender) -{ - ConvertFile(); -} +void __fastcall TMainWindow::BtnConvertClick(TObject *Sender) { ConvertFile(); } // callback on button-exit -------------------------------------------------- -void __fastcall TMainWindow::BtnExitClick(TObject *Sender) -{ - Close(); -} +void __fastcall TMainWindow::BtnExitClick(TObject *Sender) { Close(); } // callbck on button-time-1 ------------------------------------------------- -void __fastcall TMainWindow::BtnTime1Click(TObject *Sender) -{ - gtime_t ts={0},te={0}; - double tint=0.0,tunit=0.0; - GetTime(&ts,&te,&tint,&tunit); - TimeDialog->Time=ts; - TimeDialog->ShowModal(); +void __fastcall TMainWindow::BtnTime1Click(TObject *Sender) { + gtime_t ts = {0}, te = {0}; + double tint = 0.0, tunit = 0.0; + GetTime(&ts, &te, &tint, &tunit); + TimeDialog->Time = ts; + TimeDialog->ShowModal(); } // callbck on button-time-2 ------------------------------------------------- -void __fastcall TMainWindow::BtnTime2Click(TObject *Sender) -{ - gtime_t ts={0},te={0}; - double tint=0.0,tunit=0.0; - GetTime(&ts,&te,&tint,&tunit); - TimeDialog->Time=te; - TimeDialog->ShowModal(); +void __fastcall TMainWindow::BtnTime2Click(TObject *Sender) { + gtime_t ts = {0}, te = {0}; + double tint = 0.0, tunit = 0.0; + GetTime(&ts, &te, &tint, &tunit); + TimeDialog->Time = te; + TimeDialog->ShowModal(); } // callback on button-input-file -------------------------------------------- -void __fastcall TMainWindow::BtnInFileClick(TObject *Sender) -{ - OpenDialog->Title="Input RTCM, RCV RAW or RINEX File"; - OpenDialog->FileName=""; - if (!OpenDialog->Execute()) return; - InFile->Text=OpenDialog->FileName; - SetOutFiles(InFile->Text); +void __fastcall TMainWindow::BtnInFileClick(TObject *Sender) { + OpenDialog->Title = "Input RTCM, RCV RAW or RINEX File"; + OpenDialog->FileName = ""; + if (!OpenDialog->Execute()) return; + InFile->Text = OpenDialog->FileName; + SetOutFiles(InFile->Text); } // callback on output-directory change -------------------------------------- -void __fastcall TMainWindow::OutDirChange(TObject *Sender) -{ - SetOutFiles(InFile->Text); -} +void __fastcall TMainWindow::OutDirChange(TObject *Sender) { SetOutFiles(InFile->Text); } // callback on button-output-directory -------------------------------------- -void __fastcall TMainWindow::BtnOutDirClick(TObject *Sender) -{ - UnicodeString dir=OutDir->Text; - TSelectDirExtOpts opt=TSelectDirExtOpts()<Text=dir; +void __fastcall TMainWindow::BtnOutDirClick(TObject *Sender) { + UnicodeString dir = OutDir->Text; + TSelectDirExtOpts opt = TSelectDirExtOpts() << sdNewUI << sdNewFolder; + if (!SelectDirectory(L"Output Directory", L"", dir, opt)) return; + OutDir->Text = dir; } // callback on button-keyword ----------------------------------------------- -void __fastcall TMainWindow::BtnKeyClick(TObject *Sender) -{ - KeyDialog->Flag=1; - KeyDialog->Show(); +void __fastcall TMainWindow::BtnKeyClick(TObject *Sender) { + KeyDialog->Flag = 1; + KeyDialog->Show(); } // callback on button-output-file-1 ----------------------------------------- -void __fastcall TMainWindow::BtnOutFile1Click(TObject *Sender) -{ - OpenDialog2->Title="Output RINEX OBS File"; - OpenDialog2->FileName=""; - OpenDialog2->FilterIndex=2; - if (!OpenDialog2->Execute()) return; - OutFile1->Text=OpenDialog2->FileName; +void __fastcall TMainWindow::BtnOutFile1Click(TObject *Sender) { + OpenDialog2->Title = "Output RINEX OBS File"; + OpenDialog2->FileName = ""; + OpenDialog2->FilterIndex = 2; + if (!OpenDialog2->Execute()) return; + OutFile1->Text = OpenDialog2->FileName; } // callback on button-output-file-2 ----------------------------------------- -void __fastcall TMainWindow::BtnOutFile2Click(TObject *Sender) -{ - OpenDialog2->Title="Output RINEX NAV File"; - OpenDialog2->FileName=""; - OpenDialog2->FilterIndex=3; - if (!OpenDialog2->Execute()) return; - OutFile2->Text=OpenDialog2->FileName; +void __fastcall TMainWindow::BtnOutFile2Click(TObject *Sender) { + OpenDialog2->Title = "Output RINEX NAV File"; + OpenDialog2->FileName = ""; + OpenDialog2->FilterIndex = 3; + if (!OpenDialog2->Execute()) return; + OutFile2->Text = OpenDialog2->FileName; } // callback on button-output-file-3 ----------------------------------------- -void __fastcall TMainWindow::BtnOutFile3Click(TObject *Sender) -{ - OpenDialog2->Title="Output RINEX GNAV File"; - OpenDialog2->FileName=""; - OpenDialog2->FilterIndex=4; - if (!OpenDialog2->Execute()) return; - OutFile3->Text=OpenDialog2->FileName; +void __fastcall TMainWindow::BtnOutFile3Click(TObject *Sender) { + OpenDialog2->Title = "Output RINEX GNAV File"; + OpenDialog2->FileName = ""; + OpenDialog2->FilterIndex = 4; + if (!OpenDialog2->Execute()) return; + OutFile3->Text = OpenDialog2->FileName; } // callback on button-output-file-4 ----------------------------------------- -void __fastcall TMainWindow::BtnOutFile4Click(TObject *Sender) -{ - OpenDialog2->Title="Output RINEX HNAV File"; - OpenDialog2->FileName=""; - OpenDialog2->FilterIndex=5; - if (!OpenDialog2->Execute()) return; - OutFile4->Text=OpenDialog2->FileName; +void __fastcall TMainWindow::BtnOutFile4Click(TObject *Sender) { + OpenDialog2->Title = "Output RINEX HNAV File"; + OpenDialog2->FileName = ""; + OpenDialog2->FilterIndex = 5; + if (!OpenDialog2->Execute()) return; + OutFile4->Text = OpenDialog2->FileName; } // callback on button-output-file-5 ----------------------------------------- -void __fastcall TMainWindow::BtnOutFile5Click(TObject *Sender) -{ - OpenDialog2->Title="Output RINEX QNAV File"; - OpenDialog2->FileName=""; - OpenDialog2->FilterIndex=6; - if (!OpenDialog2->Execute()) return; - OutFile5->Text=OpenDialog2->FileName; +void __fastcall TMainWindow::BtnOutFile5Click(TObject *Sender) { + OpenDialog2->Title = "Output RINEX QNAV File"; + OpenDialog2->FileName = ""; + OpenDialog2->FilterIndex = 6; + if (!OpenDialog2->Execute()) return; + OutFile5->Text = OpenDialog2->FileName; } // callback on button-output-file-6 ----------------------------------------- -void __fastcall TMainWindow::BtnOutFile6Click(TObject *Sender) -{ - OpenDialog2->Title="Output RINEX LNAV File"; - OpenDialog2->FileName=""; - OpenDialog2->FilterIndex=7; - if (!OpenDialog2->Execute()) return; - OutFile6->Text=OpenDialog2->FileName; +void __fastcall TMainWindow::BtnOutFile6Click(TObject *Sender) { + OpenDialog2->Title = "Output RINEX LNAV File"; + OpenDialog2->FileName = ""; + OpenDialog2->FilterIndex = 7; + if (!OpenDialog2->Execute()) return; + OutFile6->Text = OpenDialog2->FileName; } // callback on button-output-file-7 ----------------------------------------- -void __fastcall TMainWindow::BtnOutFile7Click(TObject *Sender) -{ - OpenDialog2->Title="Output RINEX CNAV File"; - OpenDialog2->FileName=""; - OpenDialog2->FilterIndex=8; - if (!OpenDialog2->Execute()) return; - OutFile7->Text=OpenDialog2->FileName; +void __fastcall TMainWindow::BtnOutFile7Click(TObject *Sender) { + OpenDialog2->Title = "Output RINEX CNAV File"; + OpenDialog2->FileName = ""; + OpenDialog2->FilterIndex = 8; + if (!OpenDialog2->Execute()) return; + OutFile7->Text = OpenDialog2->FileName; } // callback on button-output-file-8 ----------------------------------------- -void __fastcall TMainWindow::BtnOutFile8Click(TObject *Sender) -{ - OpenDialog2->Title="Output RINEX INAV File"; - OpenDialog2->FileName=""; - OpenDialog2->FilterIndex=9; - if (!OpenDialog2->Execute()) return; - OutFile8->Text=OpenDialog2->FileName; +void __fastcall TMainWindow::BtnOutFile8Click(TObject *Sender) { + OpenDialog2->Title = "Output RINEX INAV File"; + OpenDialog2->FileName = ""; + OpenDialog2->FilterIndex = 9; + if (!OpenDialog2->Execute()) return; + OutFile8->Text = OpenDialog2->FileName; } // callback on button-output-file-9 ----------------------------------------- -void __fastcall TMainWindow::BtnOutFile9Click(TObject *Sender) -{ - OpenDialog2->Title="Output SBAS/LEX Log File"; - OpenDialog2->FileName=""; - OpenDialog2->FilterIndex=10; - if (!OpenDialog2->Execute()) return; - OutFile9->Text=OpenDialog2->FileName; +void __fastcall TMainWindow::BtnOutFile9Click(TObject *Sender) { + OpenDialog2->Title = "Output SBAS/LEX Log File"; + OpenDialog2->FileName = ""; + OpenDialog2->FilterIndex = 10; + if (!OpenDialog2->Execute()) return; + OutFile9->Text = OpenDialog2->FileName; } // callback on button-view-input-file ---------------------------------------- -void __fastcall TMainWindow::BtnInFileViewClick(TObject *Sender) -{ - TTextViewer *viewer=new TTextViewer(Application); - AnsiString InFile_Text=InFile->Text; - char *ext=strrchr(InFile_Text.c_str(),'.'); - if (!*ext||strlen(ext)<4) return; - if (!strcmp(ext,".obs" )||!strcmp(ext,".OBS" )||!strcmp(ext,".nav")|| - !strcmp(ext,".NAV" )||!strcmp(ext+2,"nav")||!strcmp(ext,"NAV" )|| - !strcmp(ext+3,"o" )||!strcmp(ext+3,"O" )||!strcmp(ext+3,"n" )|| - !strcmp(ext+3,"N" )||!strcmp(ext+3,"p" )||!strcmp(ext+3,"P" )|| - !strcmp(ext+3,"g" )||!strcmp(ext+3,"G" )||!strcmp(ext+3,"h" )|| - !strcmp(ext+3,"H" )||!strcmp(ext+3,"q" )||!strcmp(ext+3,"Q" )|| - !strcmp(ext+3,"l" )||!strcmp(ext+3,"L" )||!strcmp(ext+3,"c" )|| - !strcmp(ext+3,"C" )||!strcmp(ext+3,"I" )||!strcmp(ext+3,"i" )|| - !strcmp(ext,".rnx" )||!strcmp(ext,".RNX")) { - viewer->Show(); - viewer->Read(RepPath(InFile_Text)); - } +void __fastcall TMainWindow::BtnInFileViewClick(TObject *Sender) { + TTextViewer *viewer = new TTextViewer(Application); + AnsiString InFile_Text = InFile->Text; + char *ext = strrchr(InFile_Text.c_str(), '.'); + if (!*ext || strlen(ext) < 4) return; + if (!strcmp(ext, ".obs") || !strcmp(ext, ".OBS") || !strcmp(ext, ".nav") || + !strcmp(ext, ".NAV") || !strcmp(ext + 2, "nav") || !strcmp(ext, "NAV") || + !strcmp(ext + 3, "o") || !strcmp(ext + 3, "O") || !strcmp(ext + 3, "n") || + !strcmp(ext + 3, "N") || !strcmp(ext + 3, "p") || !strcmp(ext + 3, "P") || + !strcmp(ext + 3, "g") || !strcmp(ext + 3, "G") || !strcmp(ext + 3, "h") || + !strcmp(ext + 3, "H") || !strcmp(ext + 3, "q") || !strcmp(ext + 3, "Q") || + !strcmp(ext + 3, "l") || !strcmp(ext + 3, "L") || !strcmp(ext + 3, "c") || + !strcmp(ext + 3, "C") || !strcmp(ext + 3, "I") || !strcmp(ext + 3, "i") || + !strcmp(ext, ".rnx") || !strcmp(ext, ".RNX")) { + viewer->Show(); + viewer->Read(RepPath(InFile_Text)); + } } // callback on button-view-file-1 ------------------------------------------- -void __fastcall TMainWindow::BtnOutFileView1Click(TObject *Sender) -{ - TTextViewer *viewer=new TTextViewer(Application); - AnsiString OutFile1_Text=OutFile1->Text; - viewer->Show(); - viewer->Read(RepPath(OutFile1_Text)); +void __fastcall TMainWindow::BtnOutFileView1Click(TObject *Sender) { + TTextViewer *viewer = new TTextViewer(Application); + AnsiString OutFile1_Text = OutFile1->Text; + viewer->Show(); + viewer->Read(RepPath(OutFile1_Text)); } // callback on button-view-file-2 ------------------------------------------- -void __fastcall TMainWindow::BtnOutFileView2Click(TObject *Sender) -{ - TTextViewer *viewer=new TTextViewer(Application); - AnsiString OutFile2_Text=OutFile2->Text; - viewer->Show(); - viewer->Read(RepPath(OutFile2_Text)); +void __fastcall TMainWindow::BtnOutFileView2Click(TObject *Sender) { + TTextViewer *viewer = new TTextViewer(Application); + AnsiString OutFile2_Text = OutFile2->Text; + viewer->Show(); + viewer->Read(RepPath(OutFile2_Text)); } // callback on button-view-file-3 ------------------------------------------- -void __fastcall TMainWindow::BtnOutFileView3Click(TObject *Sender) -{ - TTextViewer *viewer=new TTextViewer(Application); - AnsiString OutFile3_Text=OutFile3->Text; - viewer->Show(); - viewer->Read(RepPath(OutFile3_Text)); +void __fastcall TMainWindow::BtnOutFileView3Click(TObject *Sender) { + TTextViewer *viewer = new TTextViewer(Application); + AnsiString OutFile3_Text = OutFile3->Text; + viewer->Show(); + viewer->Read(RepPath(OutFile3_Text)); } // callback on button-view-file-4 ------------------------------------------- -void __fastcall TMainWindow::BtnOutFileView4Click(TObject *Sender) -{ - TTextViewer *viewer=new TTextViewer(Application); - AnsiString OutFile4_Text=OutFile4->Text; - viewer->Show(); - viewer->Read(RepPath(OutFile4_Text)); +void __fastcall TMainWindow::BtnOutFileView4Click(TObject *Sender) { + TTextViewer *viewer = new TTextViewer(Application); + AnsiString OutFile4_Text = OutFile4->Text; + viewer->Show(); + viewer->Read(RepPath(OutFile4_Text)); } // callback on button-view-file-5 ------------------------------------------- -void __fastcall TMainWindow::BtnOutFileView5Click(TObject *Sender) -{ - TTextViewer *viewer=new TTextViewer(Application); - AnsiString OutFile5_Text=OutFile5->Text; - viewer->Show(); - viewer->Read(RepPath(OutFile5_Text)); +void __fastcall TMainWindow::BtnOutFileView5Click(TObject *Sender) { + TTextViewer *viewer = new TTextViewer(Application); + AnsiString OutFile5_Text = OutFile5->Text; + viewer->Show(); + viewer->Read(RepPath(OutFile5_Text)); } // callback on button-view-file-6 ------------------------------------------- -void __fastcall TMainWindow::BtnOutFileView6Click(TObject *Sender) -{ - TTextViewer *viewer=new TTextViewer(Application); - AnsiString OutFile6_Text=OutFile6->Text; - viewer->Show(); - viewer->Read(RepPath(OutFile6_Text)); +void __fastcall TMainWindow::BtnOutFileView6Click(TObject *Sender) { + TTextViewer *viewer = new TTextViewer(Application); + AnsiString OutFile6_Text = OutFile6->Text; + viewer->Show(); + viewer->Read(RepPath(OutFile6_Text)); } // callback on button-view-file-7 ------------------------------------------- -void __fastcall TMainWindow::BtnOutFileView7Click(TObject *Sender) -{ - TTextViewer *viewer=new TTextViewer(Application); - AnsiString OutFile7_Text=OutFile7->Text; - viewer->Show(); - viewer->Read(RepPath(OutFile7_Text)); +void __fastcall TMainWindow::BtnOutFileView7Click(TObject *Sender) { + TTextViewer *viewer = new TTextViewer(Application); + AnsiString OutFile7_Text = OutFile7->Text; + viewer->Show(); + viewer->Read(RepPath(OutFile7_Text)); } // callback on button-view-file-8 ------------------------------------------- -void __fastcall TMainWindow::BtnOutFileView8Click(TObject *Sender) -{ - TTextViewer *viewer=new TTextViewer(Application); - AnsiString OutFile8_Text=OutFile8->Text; - viewer->Show(); - viewer->Read(RepPath(OutFile8_Text)); +void __fastcall TMainWindow::BtnOutFileView8Click(TObject *Sender) { + TTextViewer *viewer = new TTextViewer(Application); + AnsiString OutFile8_Text = OutFile8->Text; + viewer->Show(); + viewer->Read(RepPath(OutFile8_Text)); } // callback on button-view-file-9 ------------------------------------------- -void __fastcall TMainWindow::BtnOutFileView9Click(TObject *Sender) -{ - TTextViewer *viewer=new TTextViewer(Application); - AnsiString OutFile9_Text=OutFile9->Text; - viewer->Show(); - viewer->Read(RepPath(OutFile9_Text)); +void __fastcall TMainWindow::BtnOutFileView9Click(TObject *Sender) { + TTextViewer *viewer = new TTextViewer(Application); + AnsiString OutFile9_Text = OutFile9->Text; + viewer->Show(); + viewer->Read(RepPath(OutFile9_Text)); } // callback on button-about ------------------------------------------------- -void __fastcall TMainWindow::BtnAboutClick(TObject *Sender) -{ - AboutDialog->About=PRGNAME; - AboutDialog->IconIndex=3; - AboutDialog->ShowModal(); +void __fastcall TMainWindow::BtnAboutClick(TObject *Sender) { + AboutDialog->About = PRGNAME; + AboutDialog->IconIndex = 3; + AboutDialog->ShowModal(); } // callback on button-time-start -------------------------------------------- -void __fastcall TMainWindow::TimeStartFClick(TObject *Sender) -{ - if (TimeStartF->Checked && TimeEndF->Checked) { - // Initialize the start time to the end time if the start - // time has just been enabled and is out of order. - gtime_t ts={0},te={0}; - double tint=0.0,tunit=0.0; - GetTime(&ts,&te,&tint,&tunit); - if (timediff(te, ts) < 0.0) { - TimeY1->Text = TimeY2->Text; - TimeH1->Text = TimeH2->Text; - } - } - UpdateEnable(); +void __fastcall TMainWindow::TimeStartFClick(TObject *Sender) { + if (TimeStartF->Checked && TimeEndF->Checked) { + // Initialize the start time to the end time if the start + // time has just been enabled and is out of order. + gtime_t ts = {0}, te = {0}; + double tint = 0.0, tunit = 0.0; + GetTime(&ts, &te, &tint, &tunit); + if (timediff(te, ts) < 0.0) { + TimeY1->Text = TimeY2->Text; + TimeH1->Text = TimeH2->Text; + } + } + UpdateEnable(); } // callback on button-time-end ---------------------------------------------- -void __fastcall TMainWindow::TimeEndFClick(TObject *Sender) -{ - if (TimeStartF->Checked && TimeEndF->Checked) { - // Initialize the end time to the start time if the end time - // has just been enabled and is out of order. - gtime_t ts={0},te={0}; - double tint=0.0,tunit=0.0; - GetTime(&ts,&te,&tint,&tunit); - if (timediff(te, ts) < 0.0) { - TimeY2->Text = TimeY1->Text; - TimeH2->Text = TimeH1->Text; - } - } - UpdateEnable(); +void __fastcall TMainWindow::TimeEndFClick(TObject *Sender) { + if (TimeStartF->Checked && TimeEndF->Checked) { + // Initialize the end time to the start time if the end time + // has just been enabled and is out of order. + gtime_t ts = {0}, te = {0}; + double tint = 0.0, tunit = 0.0; + GetTime(&ts, &te, &tint, &tunit); + if (timediff(te, ts) < 0.0) { + TimeY2->Text = TimeY1->Text; + TimeH2->Text = TimeH1->Text; + } + } + UpdateEnable(); } // callback on button-time-interval ----------------------------------------- -void __fastcall TMainWindow::TimeIntFClick(TObject *Sender) -{ - UpdateEnable(); -} +void __fastcall TMainWindow::TimeIntFClick(TObject *Sender) { UpdateEnable(); } // callback on output-file check/uncheck ------------------------------------ -void __fastcall TMainWindow::OutDirEnaClick(TObject *Sender) -{ - SetOutFiles(InFile->Text); - UpdateEnable(); +void __fastcall TMainWindow::OutDirEnaClick(TObject *Sender) { + SetOutFiles(InFile->Text); + UpdateEnable(); } // callback on input-file-change -------------------------------------------- -void __fastcall TMainWindow::InFileChange(TObject *Sender) -{ - SetOutFiles(InFile->Text); -} +void __fastcall TMainWindow::InFileChange(TObject *Sender) { SetOutFiles(InFile->Text); } //------------------------------------------------------------------- -void __fastcall TMainWindow::InFileCloseUp(TObject *Sender) -{ - DisableHighlight(); -} +void __fastcall TMainWindow::InFileCloseUp(TObject *Sender) { DisableHighlight(); } // callback on format change ------------------------------------------------ -void __fastcall TMainWindow::FormatChange(TObject *Sender) -{ - UpdateEnable(); -} +void __fastcall TMainWindow::FormatChange(TObject *Sender) { UpdateEnable(); } // get time ----------------------------------------------------------------- -void __fastcall TMainWindow::GetTime(gtime_t *ts, gtime_t *te, double *tint, - double *tunit) -{ - AnsiString TimeY1_Text=TimeY1->Text,TimeH1_Text=TimeH1->Text; - AnsiString TimeY2_Text=TimeY2->Text,TimeH2_Text=TimeH2->Text; - AnsiString TimeInt_Text=TimeInt->Text,TimeUnit_Text=TimeUnit->Text; - double eps[]={2000,1,1,0,0,0},epe[]={2000,1,1,0,0,0}; - - if (TimeStartF->Checked) { - sscanf(TimeY1_Text.c_str(),"%lf/%lf/%lf",eps,eps+1,eps+2); - sscanf(TimeH1_Text.c_str(),"%lf:%lf:%lf",eps+3,eps+4,eps+5); - *ts=epoch2time(eps); - } - if (TimeEndF->Checked) { - sscanf(TimeY2_Text.c_str(),"%lf/%lf/%lf",epe,epe+1,epe+2); - sscanf(TimeH2_Text.c_str(),"%lf:%lf:%lf",epe+3,epe+4,epe+5); - *te=epoch2time(epe); - } - if (TimeIntF->Checked) { - sscanf(TimeInt_Text.c_str(),"%lf",tint); - } - if (TimeUnitF->Checked) { - if (sscanf(TimeUnit_Text.c_str(),"%lf",tunit)>=1) *tunit*=3600.0; - } +void __fastcall TMainWindow::GetTime(gtime_t *ts, gtime_t *te, double *tint, double *tunit) { + AnsiString TimeY1_Text = TimeY1->Text, TimeH1_Text = TimeH1->Text; + AnsiString TimeY2_Text = TimeY2->Text, TimeH2_Text = TimeH2->Text; + AnsiString TimeInt_Text = TimeInt->Text, TimeUnit_Text = TimeUnit->Text; + double eps[] = {2000, 1, 1, 0, 0, 0}, epe[] = {2000, 1, 1, 0, 0, 0}; + + if (TimeStartF->Checked) { + sscanf(TimeY1_Text.c_str(), "%lf/%lf/%lf", eps, eps + 1, eps + 2); + sscanf(TimeH1_Text.c_str(), "%lf:%lf:%lf", eps + 3, eps + 4, eps + 5); + *ts = epoch2time(eps); + } + if (TimeEndF->Checked) { + sscanf(TimeY2_Text.c_str(), "%lf/%lf/%lf", epe, epe + 1, epe + 2); + sscanf(TimeH2_Text.c_str(), "%lf:%lf:%lf", epe + 3, epe + 4, epe + 5); + *te = epoch2time(epe); + } + if (TimeIntF->Checked) { + sscanf(TimeInt_Text.c_str(), "%lf", tint); + } + if (TimeUnitF->Checked) { + if (sscanf(TimeUnit_Text.c_str(), "%lf", tunit) >= 1) *tunit *= 3600.0; + } } // callback on time-start-ymd change ---------------------------------------- -void __fastcall TMainWindow::TimeY1UDChangingEx(TObject *Sender, - bool &AllowChange, int NewValue, TUpDownDirection Direction) -{ - AnsiString TimeY1_Text=TimeY1->Text,s; - double ep[]={2000,1,1,0,0,0}; - int p=TimeY1->SelStart,ud=Direction==updUp?1:-1; - sscanf(TimeY1_Text.c_str(),"%lf/%lf/%lf",ep,ep+1,ep+2); - if (412) {ep[0]++; ep[1]-=12;} - } - else if (p>7||p==0) ep[2]+=ud; else ep[0]+=ud; - time2epoch(epoch2time(ep),ep); - TimeY1->Text=s.sprintf("%04.0f/%02.0f/%02.0f",ep[0],ep[1],ep[2]); - TimeY1->SelStart=p>7||p==0?10:(p>4?7:4); +void __fastcall TMainWindow::TimeY1UDChangingEx(TObject *Sender, bool &AllowChange, int NewValue, + TUpDownDirection Direction) { + AnsiString TimeY1_Text = TimeY1->Text, s; + double ep[] = {2000, 1, 1, 0, 0, 0}; + int p = TimeY1->SelStart, ud = Direction == updUp ? 1 : -1; + sscanf(TimeY1_Text.c_str(), "%lf/%lf/%lf", ep, ep + 1, ep + 2); + if (4 < p && p < 8) { + ep[1] += ud; + if (ep[1] <= 0) { + ep[0]--; + ep[1] += 12; + } else if (ep[1] > 12) { + ep[0]++; + ep[1] -= 12; + } + } else if (p > 7 || p == 0) + ep[2] += ud; + else + ep[0] += ud; + time2epoch(epoch2time(ep), ep); + TimeY1->Text = s.sprintf("%04.0f/%02.0f/%02.0f", ep[0], ep[1], ep[2]); + TimeY1->SelStart = p > 7 || p == 0 ? 10 : (p > 4 ? 7 : 4); } // callback on time-start-hms change ---------------------------------------- -void __fastcall TMainWindow::TimeH1UDChangingEx(TObject *Sender, - bool &AllowChange, int NewValue, TUpDownDirection Direction) -{ - AnsiString TimeH1_Text=TimeH1->Text,s; - int hms[3]={0},sec,p=TimeH1->SelStart,ud=Direction==updUp?1:-1; - sscanf(TimeH1_Text.c_str(),"%d:%d:%d",hms,hms+1,hms+2); - if (p>5||p==0) hms[2]+=ud; else if (p>2) hms[1]+=ud; else hms[0]+=ud; - sec=hms[0]*3600+hms[1]*60+hms[2]; - if (sec<0) sec+=86400; else if (sec>=86400) sec-=86400; - TimeH1->Text=s.sprintf("%02d:%02d:%02d",sec/3600,(sec%3600)/60,sec%60); - TimeH1->SelStart=p>5||p==0?8:(p>2?5:2); +void __fastcall TMainWindow::TimeH1UDChangingEx(TObject *Sender, bool &AllowChange, int NewValue, + TUpDownDirection Direction) { + AnsiString TimeH1_Text = TimeH1->Text, s; + int hms[3] = {0}, sec, p = TimeH1->SelStart, ud = Direction == updUp ? 1 : -1; + sscanf(TimeH1_Text.c_str(), "%d:%d:%d", hms, hms + 1, hms + 2); + if (p > 5 || p == 0) + hms[2] += ud; + else if (p > 2) + hms[1] += ud; + else + hms[0] += ud; + sec = hms[0] * 3600 + hms[1] * 60 + hms[2]; + if (sec < 0) + sec += 86400; + else if (sec >= 86400) + sec -= 86400; + TimeH1->Text = s.sprintf("%02d:%02d:%02d", sec / 3600, (sec % 3600) / 60, sec % 60); + TimeH1->SelStart = p > 5 || p == 0 ? 8 : (p > 2 ? 5 : 2); } // callback on time-end-ymd change ------------------------------------------ -void __fastcall TMainWindow::TimeY2UDChangingEx(TObject *Sender, - bool &AllowChange, int NewValue, TUpDownDirection Direction) -{ - AnsiString TimeY2_Text=TimeY2->Text,s; - double ep[]={2000,1,1,0,0,0}; - int p=TimeY2->SelStart,ud=Direction==updUp?1:-1; - sscanf(TimeY2_Text.c_str(),"%lf/%lf/%lf",ep,ep+1,ep+2); - if (412) {ep[0]++; ep[1]-=12;} - } - else if (p>7||p==0) ep[2]+=ud; else ep[0]+=ud; - time2epoch(epoch2time(ep),ep); - TimeY2->Text=s.sprintf("%04.0f/%02.0f/%02.0f",ep[0],ep[1],ep[2]); - TimeY2->SelStart=p>7||p==0?10:(p>4?7:4); +void __fastcall TMainWindow::TimeY2UDChangingEx(TObject *Sender, bool &AllowChange, int NewValue, + TUpDownDirection Direction) { + AnsiString TimeY2_Text = TimeY2->Text, s; + double ep[] = {2000, 1, 1, 0, 0, 0}; + int p = TimeY2->SelStart, ud = Direction == updUp ? 1 : -1; + sscanf(TimeY2_Text.c_str(), "%lf/%lf/%lf", ep, ep + 1, ep + 2); + if (4 < p && p < 8) { + ep[1] += ud; + if (ep[1] <= 0) { + ep[0]--; + ep[1] += 12; + } else if (ep[1] > 12) { + ep[0]++; + ep[1] -= 12; + } + } else if (p > 7 || p == 0) + ep[2] += ud; + else + ep[0] += ud; + time2epoch(epoch2time(ep), ep); + TimeY2->Text = s.sprintf("%04.0f/%02.0f/%02.0f", ep[0], ep[1], ep[2]); + TimeY2->SelStart = p > 7 || p == 0 ? 10 : (p > 4 ? 7 : 4); } // callback on time-end-hms change ------------------------------------------ -void __fastcall TMainWindow::TimeH2UDChangingEx(TObject *Sender, - bool &AllowChange, int NewValue, TUpDownDirection Direction) -{ - AnsiString TimeH2_Text=TimeH2->Text,s; - int hms[3]={0},sec,p=TimeH2->SelStart,ud=Direction==updUp?1:-1; - sscanf(TimeH2_Text.c_str(),"%d:%d:%d",hms,hms+1,hms+2); - if (p>5||p==0) hms[2]+=ud; else if (p>2) hms[1]+=ud; else hms[0]+=ud; - sec=hms[0]*3600+hms[1]*60+hms[2]; - if (sec<0) sec+=86400; else if (sec>=86400) sec-=86400; - TimeH2->Text=s.sprintf("%02d:%02d:%02d",sec/3600,(sec%3600)/60,sec%60); - TimeH2->SelStart=p>5||p==0?8:(p>2?5:2); +void __fastcall TMainWindow::TimeH2UDChangingEx(TObject *Sender, bool &AllowChange, int NewValue, + TUpDownDirection Direction) { + AnsiString TimeH2_Text = TimeH2->Text, s; + int hms[3] = {0}, sec, p = TimeH2->SelStart, ud = Direction == updUp ? 1 : -1; + sscanf(TimeH2_Text.c_str(), "%d:%d:%d", hms, hms + 1, hms + 2); + if (p > 5 || p == 0) + hms[2] += ud; + else if (p > 2) + hms[1] += ud; + else + hms[0] += ud; + sec = hms[0] * 3600 + hms[1] * 60 + hms[2]; + if (sec < 0) + sec += 86400; + else if (sec >= 86400) + sec -= 86400; + TimeH2->Text = s.sprintf("%02d:%02d:%02d", sec / 3600, (sec % 3600) / 60, sec % 60); + TimeH2->SelStart = p > 5 || p == 0 ? 8 : (p > 2 ? 5 : 2); } // callback on time-start-ymd key press ------------------------------------- -void __fastcall TMainWindow::TimeY1KeyDown(TObject *Sender, WORD &Key, TShiftState Shift) -{ - bool allowchange; - if (Key==VK_UP||Key==VK_DOWN) { - TimeY1UDChangingEx(Sender,allowchange,0,Key==VK_UP?updUp:updDown); - Key=0; - } +void __fastcall TMainWindow::TimeY1KeyDown(TObject *Sender, WORD &Key, TShiftState Shift) { + bool allowchange; + if (Key == VK_UP || Key == VK_DOWN) { + TimeY1UDChangingEx(Sender, allowchange, 0, Key == VK_UP ? updUp : updDown); + Key = 0; + } } // callback on time-start-hms key press ------------------------------------- void __fastcall TMainWindow::TimeH1KeyDown(TObject *Sender, WORD &Key, TShiftState Shift) { - bool allowchange; - if (Key==VK_UP||Key==VK_DOWN) { - TimeH1UDChangingEx(Sender,allowchange,0,Key==VK_UP?updUp:updDown); - Key=0; - } + bool allowchange; + if (Key == VK_UP || Key == VK_DOWN) { + TimeH1UDChangingEx(Sender, allowchange, 0, Key == VK_UP ? updUp : updDown); + Key = 0; + } } // callback on time-end-ymd key press --------------------------------------- void __fastcall TMainWindow::TimeY2KeyDown(TObject *Sender, WORD &Key, TShiftState Shift) { - bool allowchange; - if (Key==VK_UP||Key==VK_DOWN) { - TimeY2UDChangingEx(Sender,allowchange,0,Key==VK_UP?updUp:updDown); - Key=0; - } + bool allowchange; + if (Key == VK_UP || Key == VK_DOWN) { + TimeY2UDChangingEx(Sender, allowchange, 0, Key == VK_UP ? updUp : updDown); + Key = 0; + } } // callback on time-end-hms key press --------------------------------------- void __fastcall TMainWindow::TimeH2KeyDown(TObject *Sender, WORD &Key, TShiftState Shift) { - bool allowchange; - if (Key==VK_UP||Key==VK_DOWN) { - TimeH2UDChangingEx(Sender,allowchange,0,Key==VK_UP?updUp:updDown); - Key=0; - } + bool allowchange; + if (Key == VK_UP || Key == VK_DOWN) { + TimeH2UDChangingEx(Sender, allowchange, 0, Key == VK_UP ? updUp : updDown); + Key = 0; + } } // replace keywords in file path -------------------------------------------- -AnsiString __fastcall TMainWindow::RepPath(AnsiString File) -{ - AnsiString Path; - char path[1024]; - reppath(File.c_str(),path,timeadd(RnxTime,TSTARTMARGIN),RnxCode.c_str(),""); - return Path=path; +AnsiString __fastcall TMainWindow::RepPath(AnsiString File) { + AnsiString Path; + char path[1024]; + reppath(File.c_str(), path, timeadd(RnxTime, TSTARTMARGIN), RnxCode.c_str(), ""); + return Path = path; } // execute command ---------------------------------------------------------- -int __fastcall TMainWindow::ExecCmd(AnsiString cmd) -{ - PROCESS_INFORMATION info; - STARTUPINFO si={0}; - si.cb=sizeof(si); - char *p=cmd.c_str(); - if (!CreateProcess(NULL,p,NULL,NULL,false,0,NULL,NULL,&si,&info)) return 0; - CloseHandle(info.hProcess); - CloseHandle(info.hThread); - return 1; +int __fastcall TMainWindow::ExecCmd(AnsiString cmd) { + PROCESS_INFORMATION info; + STARTUPINFO si = {0}; + si.cb = sizeof(si); + char *p = cmd.c_str(); + if (!CreateProcess(NULL, p, NULL, NULL, false, 0, NULL, NULL, &si, &info)) return 0; + CloseHandle(info.hProcess); + CloseHandle(info.hThread); + return 1; } // undate enable/disable of widgets ----------------------------------------- -void __fastcall TMainWindow::UpdateEnable(void) -{ - AnsiString FormatText=Format->Text; - int rnx=strstr(FormatText.c_str(),"RINEX")!=NULL; - int sep_nav=(RnxVer<3||SepNav); - - TimeY1 ->Enabled=TimeStartF ->Checked; - TimeH1 ->Enabled=TimeStartF ->Checked; - TimeY1UD ->Enabled=TimeStartF ->Checked; - TimeH1UD ->Enabled=TimeStartF ->Checked; - BtnTime1 ->Enabled=TimeStartF ->Checked; - TimeY2 ->Enabled=TimeEndF ->Checked; - TimeH2 ->Enabled=TimeEndF ->Checked; - TimeY2UD ->Enabled=TimeEndF ->Checked; - TimeH2UD ->Enabled=TimeEndF ->Checked; - BtnTime2 ->Enabled=TimeEndF ->Checked; - TimeInt ->Enabled=TimeIntF ->Checked; - LabelTimeInt ->Enabled=TimeInt ->Enabled; - TimeUnitF ->Enabled=TimeStartF->Checked&&TimeEndF->Checked; - TimeUnit ->Enabled=TimeStartF->Checked&&TimeEndF->Checked&&TimeUnitF->Checked; - LabelTimeUnit ->Enabled=TimeUnit ->Enabled; - OutFileEna3 ->Enabled=sep_nav&&(NavSys&SYS_GLO); - OutFileEna4 ->Enabled=sep_nav&&(NavSys&SYS_SBS); - OutFileEna5 ->Enabled=sep_nav&&(NavSys&SYS_QZS)&&RnxVer>=5; - OutFileEna6 ->Enabled=sep_nav&&(NavSys&SYS_GAL)&&RnxVer>=2; - OutFileEna7 ->Enabled=sep_nav&&(NavSys&SYS_CMP)&&RnxVer>=4; - OutFileEna8 ->Enabled=sep_nav&&(NavSys&SYS_IRN)&&RnxVer>=6; - OutFileEna9 ->Enabled=!rnx; - OutDir ->Enabled=OutDirEna ->Checked; - LabelOutDir ->Enabled=OutDirEna ->Checked; - OutFile1 ->Enabled=OutFileEna1->Checked; - OutFile2 ->Enabled=OutFileEna2->Checked; - OutFile3 ->Enabled=OutFileEna3->Checked&&OutFileEna3->Enabled; - OutFile4 ->Enabled=OutFileEna4->Checked&&OutFileEna4->Enabled; - OutFile5 ->Enabled=OutFileEna5->Checked&&OutFileEna5->Enabled; - OutFile6 ->Enabled=OutFileEna6->Checked&&OutFileEna6->Enabled; - OutFile7 ->Enabled=OutFileEna7->Checked&&OutFileEna7->Enabled; - OutFile8 ->Enabled=OutFileEna8->Checked&&OutFileEna8->Enabled; - OutFile9 ->Enabled=OutFileEna9->Checked&&!rnx; - BtnOutDir ->Enabled=OutDirEna ->Checked; - BtnOutFile1 ->Enabled=OutFile1->Enabled; - BtnOutFile2 ->Enabled=OutFile2->Enabled; - BtnOutFile3 ->Enabled=OutFile3->Enabled; - BtnOutFile4 ->Enabled=OutFile4->Enabled; - BtnOutFile5 ->Enabled=OutFile5->Enabled; - BtnOutFile6 ->Enabled=OutFile6->Enabled; - BtnOutFile7 ->Enabled=OutFile7->Enabled; - BtnOutFile8 ->Enabled=OutFile8->Enabled; - BtnOutFile9 ->Enabled=OutFile9->Enabled; - BtnOutFileView1->Enabled=OutFile1->Enabled; - BtnOutFileView2->Enabled=OutFile2->Enabled; - BtnOutFileView3->Enabled=OutFile3->Enabled; - BtnOutFileView4->Enabled=OutFile4->Enabled; - BtnOutFileView5->Enabled=OutFile5->Enabled; - BtnOutFileView6->Enabled=OutFile6->Enabled; - BtnOutFileView7->Enabled=OutFile7->Enabled; - BtnOutFileView8->Enabled=OutFile8->Enabled; - BtnOutFileView9->Enabled=OutFile9->Enabled; +void __fastcall TMainWindow::UpdateEnable(void) { + AnsiString FormatText = Format->Text; + int rnx = strstr(FormatText.c_str(), "RINEX") != NULL; + int sep_nav = (RnxVer < 3 || SepNav); + + TimeY1->Enabled = TimeStartF->Checked; + TimeH1->Enabled = TimeStartF->Checked; + TimeY1UD->Enabled = TimeStartF->Checked; + TimeH1UD->Enabled = TimeStartF->Checked; + BtnTime1->Enabled = TimeStartF->Checked; + TimeY2->Enabled = TimeEndF->Checked; + TimeH2->Enabled = TimeEndF->Checked; + TimeY2UD->Enabled = TimeEndF->Checked; + TimeH2UD->Enabled = TimeEndF->Checked; + BtnTime2->Enabled = TimeEndF->Checked; + TimeInt->Enabled = TimeIntF->Checked; + LabelTimeInt->Enabled = TimeInt->Enabled; + TimeUnitF->Enabled = TimeStartF->Checked && TimeEndF->Checked; + TimeUnit->Enabled = TimeStartF->Checked && TimeEndF->Checked && TimeUnitF->Checked; + LabelTimeUnit->Enabled = TimeUnit->Enabled; + OutFileEna3->Enabled = sep_nav && (NavSys & SYS_GLO); + OutFileEna4->Enabled = sep_nav && (NavSys & SYS_SBS); + OutFileEna5->Enabled = sep_nav && (NavSys & SYS_QZS) && RnxVer >= 5; + OutFileEna6->Enabled = sep_nav && (NavSys & SYS_GAL) && RnxVer >= 2; + OutFileEna7->Enabled = sep_nav && (NavSys & SYS_CMP) && RnxVer >= 4; + OutFileEna8->Enabled = sep_nav && (NavSys & SYS_IRN) && RnxVer >= 6; + OutFileEna9->Enabled = !rnx; + OutDir->Enabled = OutDirEna->Checked; + LabelOutDir->Enabled = OutDirEna->Checked; + OutFile1->Enabled = OutFileEna1->Checked; + OutFile2->Enabled = OutFileEna2->Checked; + OutFile3->Enabled = OutFileEna3->Checked && OutFileEna3->Enabled; + OutFile4->Enabled = OutFileEna4->Checked && OutFileEna4->Enabled; + OutFile5->Enabled = OutFileEna5->Checked && OutFileEna5->Enabled; + OutFile6->Enabled = OutFileEna6->Checked && OutFileEna6->Enabled; + OutFile7->Enabled = OutFileEna7->Checked && OutFileEna7->Enabled; + OutFile8->Enabled = OutFileEna8->Checked && OutFileEna8->Enabled; + OutFile9->Enabled = OutFileEna9->Checked && !rnx; + BtnOutDir->Enabled = OutDirEna->Checked; + BtnOutFile1->Enabled = OutFile1->Enabled; + BtnOutFile2->Enabled = OutFile2->Enabled; + BtnOutFile3->Enabled = OutFile3->Enabled; + BtnOutFile4->Enabled = OutFile4->Enabled; + BtnOutFile5->Enabled = OutFile5->Enabled; + BtnOutFile6->Enabled = OutFile6->Enabled; + BtnOutFile7->Enabled = OutFile7->Enabled; + BtnOutFile8->Enabled = OutFile8->Enabled; + BtnOutFile9->Enabled = OutFile9->Enabled; + BtnOutFileView1->Enabled = OutFile1->Enabled; + BtnOutFileView2->Enabled = OutFile2->Enabled; + BtnOutFileView3->Enabled = OutFile3->Enabled; + BtnOutFileView4->Enabled = OutFile4->Enabled; + BtnOutFileView5->Enabled = OutFile5->Enabled; + BtnOutFileView6->Enabled = OutFile6->Enabled; + BtnOutFileView7->Enabled = OutFile7->Enabled; + BtnOutFileView8->Enabled = OutFile8->Enabled; + BtnOutFileView9->Enabled = OutFile9->Enabled; } // disable highlight of combo box ------------------------------------------- -void __fastcall TMainWindow::DisableHighlight(void) -{ - ::PostMessage(InFile ->Handle,CB_SETEDITSEL,-1,0); - ::PostMessage(TimeInt->Handle,CB_SETEDITSEL,-1,0); +void __fastcall TMainWindow::DisableHighlight(void) { + ::PostMessage(InFile->Handle, CB_SETEDITSEL, -1, 0); + ::PostMessage(TimeInt->Handle, CB_SETEDITSEL, -1, 0); } // convert file ------------------------------------------------------------- -void __fastcall TMainWindow::ConvertFile(void) -{ - rnxopt_t rnxopt={0}; - AnsiString InFile_Text=InFile->Text; - AnsiString OutFile1_Text=OutFile1->Text,OutFile2_Text=OutFile2->Text; - AnsiString OutFile3_Text=OutFile3->Text,OutFile4_Text=OutFile4->Text; - AnsiString OutFile5_Text=OutFile5->Text,OutFile6_Text=OutFile6->Text; - AnsiString OutFile7_Text=OutFile7->Text,OutFile8_Text=OutFile8->Text; - AnsiString OutFile9_Text=OutFile9->Text; - int i,format,sat; - char file[1024]="",*ofile[9],ofile_[9][1024]={""},*p; - char buff[256],tstr[40]; - const int RNXVER[]={210,211,212,300,301,302,303,304,305,400,401,402}; - FILE *fp; - - for (i=0;i<9;i++) ofile[i]=ofile_[i]; - - // recognize input file format - strcpy(file,InFile_Text.c_str()); - if (!(p=strrchr(file,'.'))) p=file; - if (Format->ItemIndex==0) { // auto - if (!strcmp(p,".rtcm2")) format=STRFMT_RTCM2; - else if (!strcmp(p,".rtcm3")) format=STRFMT_RTCM3; - else if (!strcmp(p,".gps" )) format=STRFMT_OEM4; - else if (!strcmp(p,".ubx" )) format=STRFMT_UBX; - else if (!strcmp(p,".sbp" )) format=STRFMT_SBP; - else if (!strcmp(p,".bin" )) format=STRFMT_CRES; - else if (!strcmp(p,".jps" )) format=STRFMT_JAVAD; - else if (!strcmp(p,".bnx" )) format=STRFMT_BINEX; - else if (!strcmp(p,".binex")) format=STRFMT_BINEX; - else if (!strcmp(p,".rt17" )) format=STRFMT_RT17; - else if (!strcmp(p,".sbf" )) format=STRFMT_SEPT; - else if (!strcmp(p,".unc" )) format=STRFMT_UNICORE; +void __fastcall TMainWindow::ConvertFile(void) { + rnxopt_t rnxopt = {0}; + AnsiString InFile_Text = InFile->Text; + AnsiString OutFile1_Text = OutFile1->Text, OutFile2_Text = OutFile2->Text; + AnsiString OutFile3_Text = OutFile3->Text, OutFile4_Text = OutFile4->Text; + AnsiString OutFile5_Text = OutFile5->Text, OutFile6_Text = OutFile6->Text; + AnsiString OutFile7_Text = OutFile7->Text, OutFile8_Text = OutFile8->Text; + AnsiString OutFile9_Text = OutFile9->Text; + int i, format, sat; + char file[1024] = "", *ofile[9], ofile_[9][1024] = {""}, *p; + char buff[256], tstr[40]; + const int RNXVER[] = {210, 211, 212, 300, 301, 302, 303, 304, 305, 400, 401, 402}; + FILE *fp; + + for (i = 0; i < 9; i++) ofile[i] = ofile_[i]; + + // recognize input file format + strcpy(file, InFile_Text.c_str()); + if (!(p = strrchr(file, '.'))) p = file; + if (Format->ItemIndex == 0) { // auto + if (!strcmp(p, ".rtcm2")) + format = STRFMT_RTCM2; + else if (!strcmp(p, ".rtcm3")) + format = STRFMT_RTCM3; + else if (!strcmp(p, ".gps")) + format = STRFMT_OEM4; + else if (!strcmp(p, ".ubx")) + format = STRFMT_UBX; + else if (!strcmp(p, ".sbp")) + format = STRFMT_SBP; + else if (!strcmp(p, ".bin")) + format = STRFMT_CRES; + else if (!strcmp(p, ".jps")) + format = STRFMT_JAVAD; + else if (!strcmp(p, ".bnx")) + format = STRFMT_BINEX; + else if (!strcmp(p, ".binex")) + format = STRFMT_BINEX; + else if (!strcmp(p, ".rt17")) + format = STRFMT_RT17; + else if (!strcmp(p, ".sbf")) + format = STRFMT_SEPT; + else if (!strcmp(p, ".unc")) + format = STRFMT_UNICORE; #ifdef RTK_DISABLED - else if (!strcmp(p,".trs" )) format=STRFMT_TERSUS; - else if (!strcmp(p,".cnb" )) format=STRFMT_CNAV; + else if (!strcmp(p, ".trs")) + format = STRFMT_TERSUS; + else if (!strcmp(p, ".cnb")) + format = STRFMT_CNAV; #endif - else if (!strcmp(p,".obs" )) format=STRFMT_RINEX; - else if (!strcmp(p,".OBS" )) format=STRFMT_RINEX; - else if (!strcmp(p,".nav" )) format=STRFMT_RINEX; - else if (!strcmp(p,".NAV" )) format=STRFMT_RINEX; - else if (!strcmp(p+2,"nav" )) format=STRFMT_RINEX; - else if (!strcmp(p+2,"NAV" )) format=STRFMT_RINEX; - else if (!strcmp(p+3,"o" )) format=STRFMT_RINEX; - else if (!strcmp(p+3,"O" )) format=STRFMT_RINEX; - else if (!strcmp(p+3,"n" )) format=STRFMT_RINEX; - else if (!strcmp(p+3,"N" )) format=STRFMT_RINEX; - else if (!strcmp(p+3,"p" )) format=STRFMT_RINEX; - else if (!strcmp(p+3,"P" )) format=STRFMT_RINEX; - else if (!strcmp(p+3,"g" )) format=STRFMT_RINEX; - else if (!strcmp(p+3,"G" )) format=STRFMT_RINEX; - else if (!strcmp(p+3,"h" )) format=STRFMT_RINEX; - else if (!strcmp(p+3,"H" )) format=STRFMT_RINEX; - else if (!strcmp(p+3,"q" )) format=STRFMT_RINEX; - else if (!strcmp(p+3,"Q" )) format=STRFMT_RINEX; - else if (!strcmp(p+3,"l" )) format=STRFMT_RINEX; - else if (!strcmp(p+3,"L" )) format=STRFMT_RINEX; - else if (!strcmp(p+3,"c" )) format=STRFMT_RINEX; - else if (!strcmp(p+3,"C" )) format=STRFMT_RINEX; - else if (!strcmp(p+3,"i" )) format=STRFMT_RINEX; - else if (!strcmp(p+3,"I" )) format=STRFMT_RINEX; - else if (!strcmp(p,".rnx" )) format=STRFMT_RINEX; - else if (!strcmp(p,".RNX" )) format=STRFMT_RINEX; - else { - showmsg("file format can not be recognized"); - return; - } - } - else { - for (i=0;formatstrs[i];i++) { - if (Format->Text==formatstrs[i]) break; - } - if (formatstrs[i]) format=i; else return; - } - rnxopt.rnxver=RNXVER[RnxVer]; - - if (format==STRFMT_RTCM2||format==STRFMT_RTCM3||format==STRFMT_RT17) { - - // input start date/time for rtcm 2, rtcm 3, RT17 or CMR - StartDialog->FileName=file; - if (StartDialog->ShowModal()!=mrOk) return; - rnxopt.trtcm=StartDialog->Time; - } - if (OutFile1->Enabled&&OutFileEna1->Checked) strcpy(ofile[0],OutFile1_Text.c_str()); - if (OutFile2->Enabled&&OutFileEna2->Checked) strcpy(ofile[1],OutFile2_Text.c_str()); - if (OutFile3->Enabled&&OutFileEna3->Checked) strcpy(ofile[2],OutFile3_Text.c_str()); - if (OutFile4->Enabled&&OutFileEna4->Checked) strcpy(ofile[3],OutFile4_Text.c_str()); - if (OutFile5->Enabled&&OutFileEna5->Checked) strcpy(ofile[4],OutFile5_Text.c_str()); - if (OutFile6->Enabled&&OutFileEna6->Checked) strcpy(ofile[5],OutFile6_Text.c_str()); - if (OutFile7->Enabled&&OutFileEna7->Checked) strcpy(ofile[6],OutFile7_Text.c_str()); - if (OutFile8->Enabled&&OutFileEna8->Checked) strcpy(ofile[7],OutFile8_Text.c_str()); - if (OutFile9->Enabled&&OutFileEna9->Checked) strcpy(ofile[8],OutFile9_Text.c_str()); - - // check overwrite output file - for (i=0;i<9;i++) { - if (!*ofile[i]||!(fp=fopen(ofile[i],"r"))) continue; - fclose(fp); - ConfDialog->Label2->Caption=ofile[i]; - if (ConfDialog->ShowModal()!=mrOk) return; - } - GetTime(&rnxopt.ts,&rnxopt.te,&rnxopt.tint,&rnxopt.tunit); - strncpy(rnxopt.staid,RnxCode.c_str(),31); - sprintf(rnxopt.prog,"%s-%s %s",PRGNAME,VER_RTKLIB,PATCH_LEVEL); - strncpy(rnxopt.runby,RunBy.c_str(),31); - strncpy(rnxopt.marker,Marker.c_str(),63); - strncpy(rnxopt.markerno,MarkerNo.c_str(),31); - strncpy(rnxopt.markertype,MarkerType.c_str(),31); - for (i=0;i<2;i++) strncpy(rnxopt.name[i],Name[i].c_str(),31); - for (i=0;i<3;i++) strncpy(rnxopt.rec [i],Rec [i].c_str(),31); - for (i=0;i<3;i++) strncpy(rnxopt.ant [i],Ant [i].c_str(),31); - if (AutoPos) { - for (i=0;i<3;i++) rnxopt.apppos[i]=AppPos[i]; - } - for (i=0;i<3;i++) rnxopt.antdel[i]=AntDel[i]; - strncpy(rnxopt.rcvopt,RcvOption.c_str(),255); - rnxopt.navsys=NavSys; - rnxopt.obstype=ObsType; - rnxopt.freqtype=FreqType; - for (i=0;i<2;i++) rnxcomment(&rnxopt, "%s", Comment[i].c_str()); - for (i=0;iVisible=false; - BtnAbort ->Visible=true; - Panel1 ->Enabled=false; - Panel2 ->Enabled=false; - BtnPlot ->Enabled=false; - BtnPost ->Enabled=false; - BtnOptions ->Enabled=false; - BtnExit ->Enabled=false; - Format ->Enabled=false; - BtnKey ->Enabled=false; - LabelInFile ->Enabled=false; - LabelOutDir ->Enabled=false; - LabelOutFile->Enabled=false; - LabelFormat ->Enabled=false; - Message ->Caption=""; - - if (TraceLevel>0) { - traceopen(TRACEFILE); - tracelevel(TraceLevel); - } - // convert to rinex - (void)convrnx(format,&rnxopt,file,ofile); - - if (TraceLevel>0) { - traceclose(); - } - BtnAbort ->Visible=false; - BtnConvert ->Visible=true; - Panel1 ->Enabled=true; - Panel2 ->Enabled=true; - BtnPlot ->Enabled=true; - BtnPost ->Enabled=true; - BtnOptions ->Enabled=true; - BtnExit ->Enabled=true; - Format ->Enabled=true; - BtnKey ->Enabled=true; - LabelInFile ->Enabled=true; - LabelOutDir ->Enabled=true; - LabelOutFile->Enabled=true; - LabelFormat ->Enabled=true; - + else if (!strcmp(p, ".obs")) + format = STRFMT_RINEX; + else if (!strcmp(p, ".OBS")) + format = STRFMT_RINEX; + else if (!strcmp(p, ".nav")) + format = STRFMT_RINEX; + else if (!strcmp(p, ".NAV")) + format = STRFMT_RINEX; + else if (!strcmp(p + 2, "nav")) + format = STRFMT_RINEX; + else if (!strcmp(p + 2, "NAV")) + format = STRFMT_RINEX; + else if (!strcmp(p + 3, "o")) + format = STRFMT_RINEX; + else if (!strcmp(p + 3, "O")) + format = STRFMT_RINEX; + else if (!strcmp(p + 3, "n")) + format = STRFMT_RINEX; + else if (!strcmp(p + 3, "N")) + format = STRFMT_RINEX; + else if (!strcmp(p + 3, "p")) + format = STRFMT_RINEX; + else if (!strcmp(p + 3, "P")) + format = STRFMT_RINEX; + else if (!strcmp(p + 3, "g")) + format = STRFMT_RINEX; + else if (!strcmp(p + 3, "G")) + format = STRFMT_RINEX; + else if (!strcmp(p + 3, "h")) + format = STRFMT_RINEX; + else if (!strcmp(p + 3, "H")) + format = STRFMT_RINEX; + else if (!strcmp(p + 3, "q")) + format = STRFMT_RINEX; + else if (!strcmp(p + 3, "Q")) + format = STRFMT_RINEX; + else if (!strcmp(p + 3, "l")) + format = STRFMT_RINEX; + else if (!strcmp(p + 3, "L")) + format = STRFMT_RINEX; + else if (!strcmp(p + 3, "c")) + format = STRFMT_RINEX; + else if (!strcmp(p + 3, "C")) + format = STRFMT_RINEX; + else if (!strcmp(p + 3, "i")) + format = STRFMT_RINEX; + else if (!strcmp(p + 3, "I")) + format = STRFMT_RINEX; + else if (!strcmp(p, ".rnx")) + format = STRFMT_RINEX; + else if (!strcmp(p, ".RNX")) + format = STRFMT_RINEX; + else { + showmsg("file format can not be recognized"); + return; + } + } else { + for (i = 0; formatstrs[i]; i++) { + if (Format->Text == formatstrs[i]) break; + } + if (formatstrs[i]) + format = i; + else + return; + } + rnxopt.rnxver = RNXVER[RnxVer]; + + if (format == STRFMT_RTCM2 || format == STRFMT_RTCM3 || format == STRFMT_RT17) { + // input start date/time for rtcm 2, rtcm 3, RT17 or CMR + StartDialog->FileName = file; + if (StartDialog->ShowModal() != mrOk) return; + rnxopt.trtcm = StartDialog->Time; + } + if (OutFile1->Enabled && OutFileEna1->Checked) strcpy(ofile[0], OutFile1_Text.c_str()); + if (OutFile2->Enabled && OutFileEna2->Checked) strcpy(ofile[1], OutFile2_Text.c_str()); + if (OutFile3->Enabled && OutFileEna3->Checked) strcpy(ofile[2], OutFile3_Text.c_str()); + if (OutFile4->Enabled && OutFileEna4->Checked) strcpy(ofile[3], OutFile4_Text.c_str()); + if (OutFile5->Enabled && OutFileEna5->Checked) strcpy(ofile[4], OutFile5_Text.c_str()); + if (OutFile6->Enabled && OutFileEna6->Checked) strcpy(ofile[5], OutFile6_Text.c_str()); + if (OutFile7->Enabled && OutFileEna7->Checked) strcpy(ofile[6], OutFile7_Text.c_str()); + if (OutFile8->Enabled && OutFileEna8->Checked) strcpy(ofile[7], OutFile8_Text.c_str()); + if (OutFile9->Enabled && OutFileEna9->Checked) strcpy(ofile[8], OutFile9_Text.c_str()); + + // check overwrite output file + for (i = 0; i < 9; i++) { + if (!*ofile[i] || !(fp = fopen(ofile[i], "r"))) continue; + fclose(fp); + ConfDialog->Label2->Caption = ofile[i]; + if (ConfDialog->ShowModal() != mrOk) return; + } + GetTime(&rnxopt.ts, &rnxopt.te, &rnxopt.tint, &rnxopt.tunit); + strncpy(rnxopt.staid, RnxCode.c_str(), 31); + sprintf(rnxopt.prog, "%s-%s %s", PRGNAME, VER_RTKLIB, PATCH_LEVEL); + strncpy(rnxopt.runby, RunBy.c_str(), 31); + strncpy(rnxopt.marker, Marker.c_str(), 63); + strncpy(rnxopt.markerno, MarkerNo.c_str(), 31); + strncpy(rnxopt.markertype, MarkerType.c_str(), 31); + for (i = 0; i < 2; i++) strncpy(rnxopt.name[i], Name[i].c_str(), 31); + for (i = 0; i < 3; i++) strncpy(rnxopt.rec[i], Rec[i].c_str(), 31); + for (i = 0; i < 3; i++) strncpy(rnxopt.ant[i], Ant[i].c_str(), 31); + if (AutoPos) { + for (i = 0; i < 3; i++) rnxopt.apppos[i] = AppPos[i]; + } + for (i = 0; i < 3; i++) rnxopt.antdel[i] = AntDel[i]; + strncpy(rnxopt.rcvopt, RcvOption.c_str(), 255); + rnxopt.navsys = NavSys; + rnxopt.obstype = ObsType; + rnxopt.freqtype = FreqType; + for (i = 0; i < 2; i++) rnxcomment(&rnxopt, "%s", Comment[i].c_str()); + for (i = 0; i < RNX_NUMSYS; i++) { + /* strncpy is appropriate here, the elements are accessed randomly */ + strncpy(rnxopt.mask[i], CodeMask[i].c_str(), sizeof(rnxopt.mask[i])); + rnxopt.mask[i][MAXCODE] = '\0'; + } + rnxopt.autopos = AutoPos; + rnxopt.phshift = PhaseShift; + rnxopt.halfcyc = HalfCyc; + rnxopt.sortsats = SortSats; + rnxopt.outiono = OutIono; + rnxopt.outtime = OutTime; + rnxopt.outleaps = OutLeaps; + rnxopt.sep_nav = SepNav; + rnxopt.ttol = TimeTol; + if (EnaGloFcn) { + for (i = 0; i < MAXPRNGLO; i++) rnxopt.glofcn[i] = GloFcn[i]; + } + strcpy(buff, ExSats.c_str()); + for (p = strtok(buff, " "); p; p = strtok(NULL, " ")) { + if (!(sat = satid2no(p))) continue; + rnxopt.exsats[sat - 1] = 1; + } + abortf = 0; + BtnConvert->Visible = false; + BtnAbort->Visible = true; + Panel1->Enabled = false; + Panel2->Enabled = false; + BtnPlot->Enabled = false; + BtnPost->Enabled = false; + BtnOptions->Enabled = false; + BtnExit->Enabled = false; + Format->Enabled = false; + BtnKey->Enabled = false; + LabelInFile->Enabled = false; + LabelOutDir->Enabled = false; + LabelOutFile->Enabled = false; + LabelFormat->Enabled = false; + Message->Caption = ""; + + if (TraceLevel > 0) { + traceopen(TRACEFILE); + tracelevel(TraceLevel); + } + // convert to rinex + (void)convrnx(format, &rnxopt, file, ofile); + + if (TraceLevel > 0) { + traceclose(); + } + BtnAbort->Visible = false; + BtnConvert->Visible = true; + Panel1->Enabled = true; + Panel2->Enabled = true; + BtnPlot->Enabled = true; + BtnPost->Enabled = true; + BtnOptions->Enabled = true; + BtnExit->Enabled = true; + Format->Enabled = true; + BtnKey->Enabled = true; + LabelInFile->Enabled = true; + LabelOutDir->Enabled = true; + LabelOutFile->Enabled = true; + LabelFormat->Enabled = true; + #ifdef RTK_DISABLED - // set time-start/end if time not specified - if (!TimeStartF->Checked&&rnxopt.tstart.time!=0) { - time2str(rnxopt.tstart,tstr,0); - tstr[10]='\0'; - TimeY1->Text=tstr; - TimeH1->Text=tstr+11; - } - if (!TimeEndF->Checked&&rnxopt.tend.time!=0) { - time2str(rnxopt.tend,tstr,0); - tstr[10]='\0'; - TimeY2->Text=tstr; - TimeH2->Text=tstr+11; - } + // set time-start/end if time not specified + if (!TimeStartF->Checked && rnxopt.tstart.time != 0) { + time2str(rnxopt.tstart, tstr, 0); + tstr[10] = '\0'; + TimeY1->Text = tstr; + TimeH1->Text = tstr + 11; + } + if (!TimeEndF->Checked && rnxopt.tend.time != 0) { + time2str(rnxopt.tend, tstr, 0); + tstr[10] = '\0'; + TimeY2->Text = tstr; + TimeH2->Text = tstr + 11; + } #endif - RnxTime=rnxopt.tstart; - - AddHist(InFile); + RnxTime = rnxopt.tstart; + + AddHist(InFile); } // load options ------------------------------------------------------------- -void __fastcall TMainWindow::LoadOpt(void) -{ - TIniFile *ini=new TIniFile(IniFile); - AnsiString opt,mask= - "1111111111111111111111111111111111111111111111111111111111111111111111"; - - RnxVer =ini->ReadInteger("opt","rnxver", 7); - RnxFile =ini->ReadInteger("opt","rnxfile", 0); - RnxCode =ini->ReadString ("opt","rnxcode","0000"); - RunBy =ini->ReadString ("opt","runby", ""); - Marker =ini->ReadString ("opt","marker", ""); - MarkerNo =ini->ReadString ("opt","markerno", ""); - MarkerType =ini->ReadString ("opt","markertype", ""); - Name[0] =ini->ReadString ("opt","name0", ""); - Name[1] =ini->ReadString ("opt","name1", ""); - Rec[0] =ini->ReadString ("opt","rec0", ""); - Rec[1] =ini->ReadString ("opt","rec1", ""); - Rec[2] =ini->ReadString ("opt","rec2", ""); - Ant[0] =ini->ReadString ("opt","ant0", ""); - Ant[1] =ini->ReadString ("opt","ant1", ""); - Ant[2] =ini->ReadString ("opt","ant2", ""); - AppPos[0] =ini->ReadFloat ("opt","apppos0", 0.0); - AppPos[1] =ini->ReadFloat ("opt","apppos1", 0.0); - AppPos[2] =ini->ReadFloat ("opt","apppos2", 0.0); - AntDel[0] =ini->ReadFloat ("opt","antdel0", 0.0); - AntDel[1] =ini->ReadFloat ("opt","antdel1", 0.0); - AntDel[2] =ini->ReadFloat ("opt","antdel2", 0.0); - Comment[0] =ini->ReadString ("opt","comment0", ""); - Comment[1] =ini->ReadString ("opt","comment1", ""); - RcvOption =ini->ReadString ("opt","rcvoption", ""); - NavSys =ini->ReadInteger("opt","navsys", 0x7F); - ObsType =ini->ReadInteger("opt","obstype", OBSTYPE_ALL); - FreqType =ini->ReadInteger("opt","freqtype", FREQTYPE_ALL); - ExSats =ini->ReadString ("opt","exsats", ""); - TraceLevel =ini->ReadInteger("opt","tracelevel", 0); - RnxTime.time =ini->ReadInteger("opt","rnxtime", 0); - CodeMask[0] =ini->ReadString ("opt","codemask_1",mask); - CodeMask[1] =ini->ReadString ("opt","codemask_2",mask); - CodeMask[2] =ini->ReadString ("opt","codemask_3",mask); - CodeMask[3] =ini->ReadString ("opt","codemask_4",mask); - CodeMask[4] =ini->ReadString ("opt","codemask_5",mask); - CodeMask[5] =ini->ReadString ("opt","codemask_6",mask); - CodeMask[6] =ini->ReadString ("opt","codemask_7",mask); - AutoPos =ini->ReadInteger("opt","autopos", 0); - PhaseShift =ini->ReadInteger("opt","phaseshift", 0); - HalfCyc =ini->ReadInteger("opt","halfcyc", 0); - SortSats =ini->ReadInteger("opt","sortsats", 0); - OutIono =ini->ReadInteger("opt","outiono", 0); - OutTime =ini->ReadInteger("opt","outtime", 0); - OutLeaps =ini->ReadInteger("opt","outleaps", 0); - SepNav =ini->ReadInteger("opt","sepnav", 0); - TimeTol =ini->ReadFloat ("opt","timetol", 0.005); - EnaGloFcn =ini->ReadInteger("opt","glofcnena", 0); - for (int i=0;i<27;i++) { - opt.sprintf("glofcn%02d",i+1); - GloFcn[i]=ini->ReadInteger("opt",opt,0); - } - TimeStartF ->Checked=ini->ReadInteger("set","timestartf", 0); - TimeEndF ->Checked=ini->ReadInteger("set","timeendf", 0); - TimeIntF ->Checked=ini->ReadInteger("set","timeintf", 0); - TimeY1 ->Text =ini->ReadString ("set","timey1", "2025/01/01"); - TimeH1 ->Text =ini->ReadString ("set","timeh1", "00:00:00" ); - TimeY2 ->Text =ini->ReadString ("set","timey2", "2025/01/01"); - TimeH2 ->Text =ini->ReadString ("set","timeh2", "00:00:00" ); - TimeInt ->Text =ini->ReadString ("set","timeint", "1"); - TimeUnitF ->Checked=ini->ReadInteger("set","timeunitf", 0); - TimeUnit ->Text =ini->ReadString ("set","timeunit", "24"); - InFile ->Text =ini->ReadString ("set","infile", ""); - OutDir ->Text =ini->ReadString ("set","outdir", ""); - OutFile1 ->Text =ini->ReadString ("set","outfile1", ""); - OutFile2 ->Text =ini->ReadString ("set","outfile2", ""); - OutFile3 ->Text =ini->ReadString ("set","outfile3", ""); - OutFile4 ->Text =ini->ReadString ("set","outfile4", ""); - OutFile5 ->Text =ini->ReadString ("set","outfile5", ""); - OutFile6 ->Text =ini->ReadString ("set","outfile6", ""); - OutFile7 ->Text =ini->ReadString ("set","outfile7", ""); - OutFile8 ->Text =ini->ReadString ("set","outfile8", ""); - OutFile9 ->Text =ini->ReadString ("set","outfile9", ""); - OutDirEna ->Checked=ini->ReadInteger("set","outdirena", 0); - OutFileEna1->Checked=ini->ReadInteger("set","outfileena1", 1); - OutFileEna2->Checked=ini->ReadInteger("set","outfileena2", 1); - OutFileEna3->Checked=ini->ReadInteger("set","outfileena3", 0); - OutFileEna4->Checked=ini->ReadInteger("set","outfileena4", 0); - OutFileEna5->Checked=ini->ReadInteger("set","outfileena5", 0); - OutFileEna6->Checked=ini->ReadInteger("set","outfileena6", 0); - OutFileEna7->Checked=ini->ReadInteger("set","outfileena7", 0); - OutFileEna8->Checked=ini->ReadInteger("set","outfileena8", 0); - OutFileEna9->Checked=ini->ReadInteger("set","outfileena9", 0); - Format ->ItemIndex=ini->ReadInteger("set","format", 0); - - InFile->Items=ReadList(ini,"hist","inputfile"); - - TTextViewer::Color1=(TColor)ini->ReadInteger("viewer","color1",(int)clBlack); - TTextViewer::Color2=(TColor)ini->ReadInteger("viewer","color2",(int)clWhite); - TTextViewer::FontD=new TFont; - TTextViewer::FontD->Name=ini->ReadString ("viewer","fontname","Courier New"); - TTextViewer::FontD->Size=ini->ReadInteger("viewer","fontsize",9); - - CmdPostExe =ini->ReadString ("set","cmdpostexe","rtkpost"); - Width =ini->ReadInteger ("window","width", 488); - - delete ini; - - UpdateEnable(); +void __fastcall TMainWindow::LoadOpt(void) { + TIniFile *ini = new TIniFile(IniFile); + AnsiString opt, mask = "1111111111111111111111111111111111111111111111111111111111111111111111"; + + RnxVer = ini->ReadInteger("opt", "rnxver", 7); + RnxFile = ini->ReadInteger("opt", "rnxfile", 0); + RnxCode = ini->ReadString("opt", "rnxcode", "0000"); + RunBy = ini->ReadString("opt", "runby", ""); + Marker = ini->ReadString("opt", "marker", ""); + MarkerNo = ini->ReadString("opt", "markerno", ""); + MarkerType = ini->ReadString("opt", "markertype", ""); + Name[0] = ini->ReadString("opt", "name0", ""); + Name[1] = ini->ReadString("opt", "name1", ""); + Rec[0] = ini->ReadString("opt", "rec0", ""); + Rec[1] = ini->ReadString("opt", "rec1", ""); + Rec[2] = ini->ReadString("opt", "rec2", ""); + Ant[0] = ini->ReadString("opt", "ant0", ""); + Ant[1] = ini->ReadString("opt", "ant1", ""); + Ant[2] = ini->ReadString("opt", "ant2", ""); + AppPos[0] = ini->ReadFloat("opt", "apppos0", 0.0); + AppPos[1] = ini->ReadFloat("opt", "apppos1", 0.0); + AppPos[2] = ini->ReadFloat("opt", "apppos2", 0.0); + AntDel[0] = ini->ReadFloat("opt", "antdel0", 0.0); + AntDel[1] = ini->ReadFloat("opt", "antdel1", 0.0); + AntDel[2] = ini->ReadFloat("opt", "antdel2", 0.0); + Comment[0] = ini->ReadString("opt", "comment0", ""); + Comment[1] = ini->ReadString("opt", "comment1", ""); + RcvOption = ini->ReadString("opt", "rcvoption", ""); + NavSys = ini->ReadInteger("opt", "navsys", 0x7F); + ObsType = ini->ReadInteger("opt", "obstype", OBSTYPE_ALL); + FreqType = ini->ReadInteger("opt", "freqtype", FREQTYPE_ALL); + ExSats = ini->ReadString("opt", "exsats", ""); + TraceLevel = ini->ReadInteger("opt", "tracelevel", 0); + RnxTime.time = ini->ReadInteger("opt", "rnxtime", 0); + CodeMask[0] = ini->ReadString("opt", "codemask_1", mask); + CodeMask[1] = ini->ReadString("opt", "codemask_2", mask); + CodeMask[2] = ini->ReadString("opt", "codemask_3", mask); + CodeMask[3] = ini->ReadString("opt", "codemask_4", mask); + CodeMask[4] = ini->ReadString("opt", "codemask_5", mask); + CodeMask[5] = ini->ReadString("opt", "codemask_6", mask); + CodeMask[6] = ini->ReadString("opt", "codemask_7", mask); + AutoPos = ini->ReadInteger("opt", "autopos", 0); + PhaseShift = ini->ReadInteger("opt", "phaseshift", 0); + HalfCyc = ini->ReadInteger("opt", "halfcyc", 0); + SortSats = ini->ReadInteger("opt", "sortsats", 0); + OutIono = ini->ReadInteger("opt", "outiono", 0); + OutTime = ini->ReadInteger("opt", "outtime", 0); + OutLeaps = ini->ReadInteger("opt", "outleaps", 0); + SepNav = ini->ReadInteger("opt", "sepnav", 0); + TimeTol = ini->ReadFloat("opt", "timetol", 0.005); + EnaGloFcn = ini->ReadInteger("opt", "glofcnena", 0); + for (int i = 0; i < 27; i++) { + opt.sprintf("glofcn%02d", i + 1); + GloFcn[i] = ini->ReadInteger("opt", opt, 0); + } + TimeStartF->Checked = ini->ReadInteger("set", "timestartf", 0); + TimeEndF->Checked = ini->ReadInteger("set", "timeendf", 0); + TimeIntF->Checked = ini->ReadInteger("set", "timeintf", 0); + TimeY1->Text = ini->ReadString("set", "timey1", "2025/01/01"); + TimeH1->Text = ini->ReadString("set", "timeh1", "00:00:00"); + TimeY2->Text = ini->ReadString("set", "timey2", "2025/01/01"); + TimeH2->Text = ini->ReadString("set", "timeh2", "00:00:00"); + TimeInt->Text = ini->ReadString("set", "timeint", "1"); + TimeUnitF->Checked = ini->ReadInteger("set", "timeunitf", 0); + TimeUnit->Text = ini->ReadString("set", "timeunit", "24"); + InFile->Text = ini->ReadString("set", "infile", ""); + OutDir->Text = ini->ReadString("set", "outdir", ""); + OutFile1->Text = ini->ReadString("set", "outfile1", ""); + OutFile2->Text = ini->ReadString("set", "outfile2", ""); + OutFile3->Text = ini->ReadString("set", "outfile3", ""); + OutFile4->Text = ini->ReadString("set", "outfile4", ""); + OutFile5->Text = ini->ReadString("set", "outfile5", ""); + OutFile6->Text = ini->ReadString("set", "outfile6", ""); + OutFile7->Text = ini->ReadString("set", "outfile7", ""); + OutFile8->Text = ini->ReadString("set", "outfile8", ""); + OutFile9->Text = ini->ReadString("set", "outfile9", ""); + OutDirEna->Checked = ini->ReadInteger("set", "outdirena", 0); + OutFileEna1->Checked = ini->ReadInteger("set", "outfileena1", 1); + OutFileEna2->Checked = ini->ReadInteger("set", "outfileena2", 1); + OutFileEna3->Checked = ini->ReadInteger("set", "outfileena3", 0); + OutFileEna4->Checked = ini->ReadInteger("set", "outfileena4", 0); + OutFileEna5->Checked = ini->ReadInteger("set", "outfileena5", 0); + OutFileEna6->Checked = ini->ReadInteger("set", "outfileena6", 0); + OutFileEna7->Checked = ini->ReadInteger("set", "outfileena7", 0); + OutFileEna8->Checked = ini->ReadInteger("set", "outfileena8", 0); + OutFileEna9->Checked = ini->ReadInteger("set", "outfileena9", 0); + Format->ItemIndex = ini->ReadInteger("set", "format", 0); + + InFile->Items = ReadList(ini, "hist", "inputfile"); + + TTextViewer::Color1 = (TColor)ini->ReadInteger("viewer", "color1", (int)clBlack); + TTextViewer::Color2 = (TColor)ini->ReadInteger("viewer", "color2", (int)clWhite); + TTextViewer::FontD = new TFont; + TTextViewer::FontD->Name = ini->ReadString("viewer", "fontname", "Courier New"); + TTextViewer::FontD->Size = ini->ReadInteger("viewer", "fontsize", 9); + + CmdPostExe = ini->ReadString("set", "cmdpostexe", "rtkpost"); + Width = ini->ReadInteger("window", "width", 488); + + delete ini; + + UpdateEnable(); } // save options ------------------------------------------------------------- -void __fastcall TMainWindow::SaveOpt(void) -{ - TIniFile *ini=new TIniFile(IniFile); - AnsiString opt; - - ini->WriteInteger("opt","rnxver", RnxVer); - ini->WriteInteger("opt","rnxfile", RnxFile); - ini->WriteString ("opt","rnxcode", RnxCode); - ini->WriteString ("opt","runby", RunBy); - ini->WriteString ("opt","marker", Marker); - ini->WriteString ("opt","markerno", MarkerNo); - ini->WriteString ("opt","markertype", MarkerType); - ini->WriteString ("opt","name0", Name[0]); - ini->WriteString ("opt","name1", Name[1]); - ini->WriteString ("opt","rec0", Rec[0]); - ini->WriteString ("opt","rec1", Rec[1]); - ini->WriteString ("opt","rec2", Rec[2]); - ini->WriteString ("opt","ant0", Ant[0]); - ini->WriteString ("opt","ant1", Ant[1]); - ini->WriteString ("opt","ant2", Ant[2]); - ini->WriteFloat ("opt","apppos0", AppPos[0]); - ini->WriteFloat ("opt","apppos1", AppPos[1]); - ini->WriteFloat ("opt","apppos2", AppPos[2]); - ini->WriteFloat ("opt","antdel0", AntDel[0]); - ini->WriteFloat ("opt","antdel1", AntDel[1]); - ini->WriteFloat ("opt","antdel2", AntDel[2]); - ini->WriteString ("opt","comment0", Comment[0]); - ini->WriteString ("opt","comment1", Comment[1]); - ini->WriteString ("opt","rcvoption", RcvOption); - ini->WriteInteger("opt","navsys", NavSys); - ini->WriteInteger("opt","obstype", ObsType); - ini->WriteInteger("opt","freqtype", FreqType); - ini->WriteString ("opt","exsats", ExSats); - ini->WriteInteger("opt","tracelevel", TraceLevel); - ini->WriteInteger("opt","rnxtime",(int)RnxTime.time); - ini->WriteString ("opt","codemask_1", CodeMask[0]); - ini->WriteString ("opt","codemask_2", CodeMask[1]); - ini->WriteString ("opt","codemask_3", CodeMask[2]); - ini->WriteString ("opt","codemask_4", CodeMask[3]); - ini->WriteString ("opt","codemask_5", CodeMask[4]); - ini->WriteString ("opt","codemask_6", CodeMask[5]); - ini->WriteString ("opt","codemask_7", CodeMask[6]); - ini->WriteInteger("opt","autopos", AutoPos); - ini->WriteInteger("opt","phaseshift", PhaseShift); - ini->WriteInteger("opt","halfcyc", HalfCyc); - ini->WriteInteger("opt","sortsats", SortSats); - ini->WriteInteger("opt","outiono", OutIono); - ini->WriteInteger("opt","outtime", OutTime); - ini->WriteInteger("opt","outleaps", OutLeaps); - ini->WriteInteger("opt","sepnav", SepNav); - ini->WriteFloat ("opt","timetol", TimeTol); - ini->WriteInteger("opt","glofcnena", EnaGloFcn); - for (int i=0;i<27;i++) { - opt.sprintf("glofcn%02d",i+1); - ini->WriteInteger("opt",opt,GloFcn[i]); - } - ini->WriteInteger("set","timestartf", TimeStartF ->Checked); - ini->WriteInteger("set","timeendf", TimeEndF ->Checked); - ini->WriteInteger("set","timeintf", TimeIntF ->Checked); - ini->WriteString ("set","timey1", TimeY1 ->Text); - ini->WriteString ("set","timeh1", TimeH1 ->Text); - ini->WriteString ("set","timey2", TimeY2 ->Text); - ini->WriteString ("set","timeh2", TimeH2 ->Text); - ini->WriteString ("set","timeint", TimeInt ->Text); - ini->WriteInteger("set","timeunitf", TimeUnitF ->Checked); - ini->WriteString ("set","timeunit", TimeUnit ->Text); - ini->WriteString ("set","infile", InFile ->Text); - ini->WriteString ("set","outdir", OutDir ->Text); - ini->WriteString ("set","outfile1", OutFile1 ->Text); - ini->WriteString ("set","outfile2", OutFile2 ->Text); - ini->WriteString ("set","outfile3", OutFile3 ->Text); - ini->WriteString ("set","outfile4", OutFile4 ->Text); - ini->WriteString ("set","outfile5", OutFile5 ->Text); - ini->WriteString ("set","outfile6", OutFile6 ->Text); - ini->WriteString ("set","outfile7", OutFile7 ->Text); - ini->WriteString ("set","outfile8", OutFile8 ->Text); - ini->WriteString ("set","outfile9", OutFile9 ->Text); - ini->WriteInteger("set","outdirena", OutDirEna ->Checked); - ini->WriteInteger("set","outfileena1",OutFileEna1->Checked); - ini->WriteInteger("set","outfileena2",OutFileEna2->Checked); - ini->WriteInteger("set","outfileena3",OutFileEna3->Checked); - ini->WriteInteger("set","outfileena4",OutFileEna4->Checked); - ini->WriteInteger("set","outfileena5",OutFileEna5->Checked); - ini->WriteInteger("set","outfileena6",OutFileEna6->Checked); - ini->WriteInteger("set","outfileena7",OutFileEna7->Checked); - ini->WriteInteger("set","outfileena8",OutFileEna8->Checked); - ini->WriteInteger("set","outfileena9",OutFileEna9->Checked); - ini->WriteInteger("set","format", Format ->ItemIndex); - - WriteList(ini,"hist","inputfile",InFile->Items); - - ini->WriteInteger("viewer","color1", (int)TTextViewer::Color1); - ini->WriteInteger("viewer","color2", (int)TTextViewer::Color2); - ini->WriteString ("viewer","fontname",TTextViewer::FontD->Name); - ini->WriteInteger("viewer","fontsize",TTextViewer::FontD->Size); - ini->WriteInteger("window","width", Width); - delete ini; +void __fastcall TMainWindow::SaveOpt(void) { + TIniFile *ini = new TIniFile(IniFile); + AnsiString opt; + + ini->WriteInteger("opt", "rnxver", RnxVer); + ini->WriteInteger("opt", "rnxfile", RnxFile); + ini->WriteString("opt", "rnxcode", RnxCode); + ini->WriteString("opt", "runby", RunBy); + ini->WriteString("opt", "marker", Marker); + ini->WriteString("opt", "markerno", MarkerNo); + ini->WriteString("opt", "markertype", MarkerType); + ini->WriteString("opt", "name0", Name[0]); + ini->WriteString("opt", "name1", Name[1]); + ini->WriteString("opt", "rec0", Rec[0]); + ini->WriteString("opt", "rec1", Rec[1]); + ini->WriteString("opt", "rec2", Rec[2]); + ini->WriteString("opt", "ant0", Ant[0]); + ini->WriteString("opt", "ant1", Ant[1]); + ini->WriteString("opt", "ant2", Ant[2]); + ini->WriteFloat("opt", "apppos0", AppPos[0]); + ini->WriteFloat("opt", "apppos1", AppPos[1]); + ini->WriteFloat("opt", "apppos2", AppPos[2]); + ini->WriteFloat("opt", "antdel0", AntDel[0]); + ini->WriteFloat("opt", "antdel1", AntDel[1]); + ini->WriteFloat("opt", "antdel2", AntDel[2]); + ini->WriteString("opt", "comment0", Comment[0]); + ini->WriteString("opt", "comment1", Comment[1]); + ini->WriteString("opt", "rcvoption", RcvOption); + ini->WriteInteger("opt", "navsys", NavSys); + ini->WriteInteger("opt", "obstype", ObsType); + ini->WriteInteger("opt", "freqtype", FreqType); + ini->WriteString("opt", "exsats", ExSats); + ini->WriteInteger("opt", "tracelevel", TraceLevel); + ini->WriteInteger("opt", "rnxtime", (int)RnxTime.time); + ini->WriteString("opt", "codemask_1", CodeMask[0]); + ini->WriteString("opt", "codemask_2", CodeMask[1]); + ini->WriteString("opt", "codemask_3", CodeMask[2]); + ini->WriteString("opt", "codemask_4", CodeMask[3]); + ini->WriteString("opt", "codemask_5", CodeMask[4]); + ini->WriteString("opt", "codemask_6", CodeMask[5]); + ini->WriteString("opt", "codemask_7", CodeMask[6]); + ini->WriteInteger("opt", "autopos", AutoPos); + ini->WriteInteger("opt", "phaseshift", PhaseShift); + ini->WriteInteger("opt", "halfcyc", HalfCyc); + ini->WriteInteger("opt", "sortsats", SortSats); + ini->WriteInteger("opt", "outiono", OutIono); + ini->WriteInteger("opt", "outtime", OutTime); + ini->WriteInteger("opt", "outleaps", OutLeaps); + ini->WriteInteger("opt", "sepnav", SepNav); + ini->WriteFloat("opt", "timetol", TimeTol); + ini->WriteInteger("opt", "glofcnena", EnaGloFcn); + for (int i = 0; i < 27; i++) { + opt.sprintf("glofcn%02d", i + 1); + ini->WriteInteger("opt", opt, GloFcn[i]); + } + ini->WriteInteger("set", "timestartf", TimeStartF->Checked); + ini->WriteInteger("set", "timeendf", TimeEndF->Checked); + ini->WriteInteger("set", "timeintf", TimeIntF->Checked); + ini->WriteString("set", "timey1", TimeY1->Text); + ini->WriteString("set", "timeh1", TimeH1->Text); + ini->WriteString("set", "timey2", TimeY2->Text); + ini->WriteString("set", "timeh2", TimeH2->Text); + ini->WriteString("set", "timeint", TimeInt->Text); + ini->WriteInteger("set", "timeunitf", TimeUnitF->Checked); + ini->WriteString("set", "timeunit", TimeUnit->Text); + ini->WriteString("set", "infile", InFile->Text); + ini->WriteString("set", "outdir", OutDir->Text); + ini->WriteString("set", "outfile1", OutFile1->Text); + ini->WriteString("set", "outfile2", OutFile2->Text); + ini->WriteString("set", "outfile3", OutFile3->Text); + ini->WriteString("set", "outfile4", OutFile4->Text); + ini->WriteString("set", "outfile5", OutFile5->Text); + ini->WriteString("set", "outfile6", OutFile6->Text); + ini->WriteString("set", "outfile7", OutFile7->Text); + ini->WriteString("set", "outfile8", OutFile8->Text); + ini->WriteString("set", "outfile9", OutFile9->Text); + ini->WriteInteger("set", "outdirena", OutDirEna->Checked); + ini->WriteInteger("set", "outfileena1", OutFileEna1->Checked); + ini->WriteInteger("set", "outfileena2", OutFileEna2->Checked); + ini->WriteInteger("set", "outfileena3", OutFileEna3->Checked); + ini->WriteInteger("set", "outfileena4", OutFileEna4->Checked); + ini->WriteInteger("set", "outfileena5", OutFileEna5->Checked); + ini->WriteInteger("set", "outfileena6", OutFileEna6->Checked); + ini->WriteInteger("set", "outfileena7", OutFileEna7->Checked); + ini->WriteInteger("set", "outfileena8", OutFileEna8->Checked); + ini->WriteInteger("set", "outfileena9", OutFileEna9->Checked); + ini->WriteInteger("set", "format", Format->ItemIndex); + + WriteList(ini, "hist", "inputfile", InFile->Items); + + ini->WriteInteger("viewer", "color1", (int)TTextViewer::Color1); + ini->WriteInteger("viewer", "color2", (int)TTextViewer::Color2); + ini->WriteString("viewer", "fontname", TTextViewer::FontD->Name); + ini->WriteInteger("viewer", "fontsize", TTextViewer::FontD->Size); + ini->WriteInteger("window", "width", Width); + delete ini; } //--------------------------------------------------------------------------- - diff --git a/app/winapp/rtkconv/convmain.h b/app/winapp/rtkconv/convmain.h index c515df18e..b99a21af3 100644 --- a/app/winapp/rtkconv/convmain.h +++ b/app/winapp/rtkconv/convmain.h @@ -2,16 +2,16 @@ #ifndef convmainH #define convmainH //--------------------------------------------------------------------------- +#include #include +#include #include -#include -#include #include #include -#include -#include -#include #include +#include +#include +#include #ifdef TCPP #include #else @@ -20,195 +20,190 @@ #include "rtklib.h" //--------------------------------------------------------------------------- -class TMainWindow : public TForm -{ -__published: - TPanel *Panel1; - TPanel *Panel3; - TPanel *Panel2; - TButton *BtnInFile; - TButton *BtnOutFile1; - TButton *BtnOutFile2; - TButton *BtnOutFile4; - TButton *BtnOutFile3; - TSpeedButton *BtnAbout; - TSpeedButton *BtnTime1; - TSpeedButton *BtnTime2; - TSpeedButton *BtnOutFileView3; - TSpeedButton *BtnOutFileView1; - TSpeedButton *BtnOutFileView2; - TSpeedButton *BtnOutFileView4; - - TCheckBox *TimeStartF; - TCheckBox *TimeEndF; - TCheckBox *TimeIntF; - TCheckBox *OutFileEna1; - TCheckBox *OutFileEna2; - TCheckBox *OutFileEna3; - TCheckBox *OutFileEna4; - - TEdit *TimeY1; - TEdit *TimeH1; - TEdit *TimeY2; - TEdit *TimeH2; - TUpDown *TimeY1UD; - TUpDown *TimeH1UD; - TUpDown *TimeY2UD; - TUpDown *TimeH2UD; - - TLabel *LabelInFile; - TLabel *LabelOutFile; - TLabel *LabelTimeInt; - TLabel *LabelFormat; - TLabel *Message; - - TComboBox *TimeInt; - TComboBox *Format; - TEdit *OutFile1; - TEdit *OutFile2; - TEdit *OutFile3; - TEdit *OutFile4; - - TOpenDialog *OpenDialog; - TOpenDialog *OpenDialog2; - TCheckBox *OutFileEna5; - TEdit *OutFile5; - TSpeedButton *BtnOutFileView5; - TButton *BtnOutFile5; - TCheckBox *OutFileEna6; - TEdit *OutFile6; - TSpeedButton *BtnOutFileView6; - TButton *BtnOutFile6; - TComboBox *InFile; - TCheckBox *OutDirEna; - TEdit *OutDir; - TLabel *LabelOutDir; - TButton *BtnOutDir; - TSpeedButton *BtnKey; - TCheckBox *TimeUnitF; - TLabel *LabelTimeUnit; - TEdit *TimeUnit; - TCheckBox *OutFileEna7; - TEdit *OutFile7; - TSpeedButton *BtnOutFileView7; - TButton *BtnOutFile7; - TSpeedButton *BtnInFileView; - TPanel *Panel4; - TBitBtn *BtnAbort; - TBitBtn *BtnConvert; - TBitBtn *BtnOptions; - TBitBtn *BtnPlot; - TBitBtn *BtnPost; - TBitBtn *BtnExit; - TCheckBox *OutFileEna8; - TEdit *OutFile8; - TSpeedButton *BtnOutFileView8; - TButton *BtnOutFile8; - TCheckBox *OutFileEna9; - TEdit *OutFile9; - TSpeedButton *BtnOutFileView9; - TButton *BtnOutFile9; - TPanel *Panel5; - TPanel *Panel6; - TPanel *Panel7; - - void __fastcall FormCreate (TObject *Sender); - void __fastcall FormShow (TObject *Sender); - void __fastcall FormClose (TObject *Sender, TCloseAction &Action); - - void __fastcall BtnPlotClick (TObject *Sender); - void __fastcall BtnConvertClick (TObject *Sender); - void __fastcall BtnOptionsClick (TObject *Sender); - void __fastcall BtnExitClick (TObject *Sender); - void __fastcall BtnAboutClick (TObject *Sender); - void __fastcall BtnTime1Click (TObject *Sender); - void __fastcall BtnTime2Click (TObject *Sender); - void __fastcall BtnInFileClick (TObject *Sender); - void __fastcall BtnOutFile1Click (TObject *Sender); - void __fastcall BtnOutFile2Click (TObject *Sender); - void __fastcall BtnOutFile3Click (TObject *Sender); - void __fastcall BtnOutFile4Click (TObject *Sender); - void __fastcall BtnOutFileView1Click(TObject *Sender); - void __fastcall BtnOutFileView2Click(TObject *Sender); - void __fastcall BtnOutFileView3Click(TObject *Sender); - void __fastcall BtnOutFileView4Click(TObject *Sender); - - void __fastcall TimeStartFClick (TObject *Sender); - void __fastcall TimeEndFClick (TObject *Sender); - void __fastcall TimeIntFClick (TObject *Sender); - void __fastcall OutDirEnaClick (TObject *Sender); - void __fastcall InFileChange(TObject *Sender); - void __fastcall BtnOutFileView5Click(TObject *Sender); - void __fastcall BtnOutFile5Click(TObject *Sender); - void __fastcall FormatChange(TObject *Sender); - void __fastcall BtnOutFileView6Click(TObject *Sender); - void __fastcall BtnOutFile6Click(TObject *Sender); - void __fastcall OutDirChange(TObject *Sender); - void __fastcall BtnOutDirClick(TObject *Sender); - void __fastcall BtnKeyClick(TObject *Sender); - void __fastcall BtnPostClick(TObject *Sender); - void __fastcall BtnOutFile7Click(TObject *Sender); - void __fastcall BtnOutFileView7Click(TObject *Sender); - void __fastcall BtnInFileViewClick(TObject *Sender); - void __fastcall BtnAbortClick(TObject *Sender); - void __fastcall Panel4Resize(TObject *Sender); - void __fastcall Panel2Resize(TObject *Sender); - void __fastcall TimeY1KeyDown(TObject *Sender, WORD &Key, TShiftState Shift); - void __fastcall TimeH1KeyDown(TObject *Sender, WORD &Key, TShiftState Shift); - void __fastcall TimeY2KeyDown(TObject *Sender, WORD &Key, TShiftState Shift); - void __fastcall TimeH2KeyDown(TObject *Sender, WORD &Key, TShiftState Shift); - void __fastcall BtnOutFile8Click(TObject *Sender); - void __fastcall BtnOutFile9Click(TObject *Sender); - void __fastcall BtnOutFileView8Click(TObject *Sender); - void __fastcall BtnOutFileView9Click(TObject *Sender); - void __fastcall TimeY1UDChangingEx(TObject *Sender, bool &AllowChange, int NewValue, - TUpDownDirection Direction); - void __fastcall TimeH1UDChangingEx(TObject *Sender, bool &AllowChange, int NewValue, - TUpDownDirection Direction); - void __fastcall TimeY2UDChangingEx(TObject *Sender, bool &AllowChange, int NewValue, - TUpDownDirection Direction); - void __fastcall TimeH2UDChangingEx(TObject *Sender, bool &AllowChange, int NewValue, - TUpDownDirection Direction); - void __fastcall InFileCloseUp(TObject *Sender); - - -private: - AnsiString IniFile,CmdPostExe; - - void __fastcall DropFiles(TWMDropFiles msg); // for files drop - - TStringList * __fastcall ReadList(TIniFile *ini, AnsiString cat, - AnsiString key); - void __fastcall WriteList(TIniFile *ini, AnsiString cat, - AnsiString key, TStrings *list); - void __fastcall AddHist(TComboBox *combo); - - int __fastcall AutoFormat(AnsiString File); - void __fastcall ConvertFile(void); - void __fastcall SetOutFiles(AnsiString infile); - void __fastcall UpdateEnable(void); - void __fastcall DisableHighlight(void); - void __fastcall GetTime(gtime_t *ts, gtime_t *te, double *tint, double *tunit); - int __fastcall ExecCmd(AnsiString cmd); - AnsiString __fastcall RepPath(AnsiString File); - void __fastcall LoadOpt(void); - void __fastcall SaveOpt(void); - - BEGIN_MESSAGE_MAP - MESSAGE_HANDLER(WM_DROPFILES,TWMDropFiles,DropFiles); - END_MESSAGE_MAP(TForm); - -public: - gtime_t RnxTime; - AnsiString RunBy,Marker,MarkerNo,MarkerType,Name[2],Rec[3],Ant[3]; - AnsiString RnxCode,Comment[2],RcvOption,ExSats; - AnsiString CodeMask[7]; - double AppPos[3],AntDel[3],TimeTol; - int RnxVer,RnxFile,NavSys,ObsType,FreqType,TraceLevel,EventEna; - int AutoPos,PhaseShift,HalfCyc,SortSats,OutIono,OutTime,OutLeaps,SepNav; - int EnaGloFcn,GloFcn[27]; - - __fastcall TMainWindow(TComponent* Owner); +class TMainWindow : public TForm { + __published : TPanel *Panel1; + TPanel *Panel3; + TPanel *Panel2; + TButton *BtnInFile; + TButton *BtnOutFile1; + TButton *BtnOutFile2; + TButton *BtnOutFile4; + TButton *BtnOutFile3; + TSpeedButton *BtnAbout; + TSpeedButton *BtnTime1; + TSpeedButton *BtnTime2; + TSpeedButton *BtnOutFileView3; + TSpeedButton *BtnOutFileView1; + TSpeedButton *BtnOutFileView2; + TSpeedButton *BtnOutFileView4; + + TCheckBox *TimeStartF; + TCheckBox *TimeEndF; + TCheckBox *TimeIntF; + TCheckBox *OutFileEna1; + TCheckBox *OutFileEna2; + TCheckBox *OutFileEna3; + TCheckBox *OutFileEna4; + + TEdit *TimeY1; + TEdit *TimeH1; + TEdit *TimeY2; + TEdit *TimeH2; + TUpDown *TimeY1UD; + TUpDown *TimeH1UD; + TUpDown *TimeY2UD; + TUpDown *TimeH2UD; + + TLabel *LabelInFile; + TLabel *LabelOutFile; + TLabel *LabelTimeInt; + TLabel *LabelFormat; + TLabel *Message; + + TComboBox *TimeInt; + TComboBox *Format; + TEdit *OutFile1; + TEdit *OutFile2; + TEdit *OutFile3; + TEdit *OutFile4; + + TOpenDialog *OpenDialog; + TOpenDialog *OpenDialog2; + TCheckBox *OutFileEna5; + TEdit *OutFile5; + TSpeedButton *BtnOutFileView5; + TButton *BtnOutFile5; + TCheckBox *OutFileEna6; + TEdit *OutFile6; + TSpeedButton *BtnOutFileView6; + TButton *BtnOutFile6; + TComboBox *InFile; + TCheckBox *OutDirEna; + TEdit *OutDir; + TLabel *LabelOutDir; + TButton *BtnOutDir; + TSpeedButton *BtnKey; + TCheckBox *TimeUnitF; + TLabel *LabelTimeUnit; + TEdit *TimeUnit; + TCheckBox *OutFileEna7; + TEdit *OutFile7; + TSpeedButton *BtnOutFileView7; + TButton *BtnOutFile7; + TSpeedButton *BtnInFileView; + TPanel *Panel4; + TBitBtn *BtnAbort; + TBitBtn *BtnConvert; + TBitBtn *BtnOptions; + TBitBtn *BtnPlot; + TBitBtn *BtnPost; + TBitBtn *BtnExit; + TCheckBox *OutFileEna8; + TEdit *OutFile8; + TSpeedButton *BtnOutFileView8; + TButton *BtnOutFile8; + TCheckBox *OutFileEna9; + TEdit *OutFile9; + TSpeedButton *BtnOutFileView9; + TButton *BtnOutFile9; + TPanel *Panel5; + TPanel *Panel6; + TPanel *Panel7; + + void __fastcall FormCreate(TObject *Sender); + void __fastcall FormShow(TObject *Sender); + void __fastcall FormClose(TObject *Sender, TCloseAction &Action); + + void __fastcall BtnPlotClick(TObject *Sender); + void __fastcall BtnConvertClick(TObject *Sender); + void __fastcall BtnOptionsClick(TObject *Sender); + void __fastcall BtnExitClick(TObject *Sender); + void __fastcall BtnAboutClick(TObject *Sender); + void __fastcall BtnTime1Click(TObject *Sender); + void __fastcall BtnTime2Click(TObject *Sender); + void __fastcall BtnInFileClick(TObject *Sender); + void __fastcall BtnOutFile1Click(TObject *Sender); + void __fastcall BtnOutFile2Click(TObject *Sender); + void __fastcall BtnOutFile3Click(TObject *Sender); + void __fastcall BtnOutFile4Click(TObject *Sender); + void __fastcall BtnOutFileView1Click(TObject *Sender); + void __fastcall BtnOutFileView2Click(TObject *Sender); + void __fastcall BtnOutFileView3Click(TObject *Sender); + void __fastcall BtnOutFileView4Click(TObject *Sender); + + void __fastcall TimeStartFClick(TObject *Sender); + void __fastcall TimeEndFClick(TObject *Sender); + void __fastcall TimeIntFClick(TObject *Sender); + void __fastcall OutDirEnaClick(TObject *Sender); + void __fastcall InFileChange(TObject *Sender); + void __fastcall BtnOutFileView5Click(TObject *Sender); + void __fastcall BtnOutFile5Click(TObject *Sender); + void __fastcall FormatChange(TObject *Sender); + void __fastcall BtnOutFileView6Click(TObject *Sender); + void __fastcall BtnOutFile6Click(TObject *Sender); + void __fastcall OutDirChange(TObject *Sender); + void __fastcall BtnOutDirClick(TObject *Sender); + void __fastcall BtnKeyClick(TObject *Sender); + void __fastcall BtnPostClick(TObject *Sender); + void __fastcall BtnOutFile7Click(TObject *Sender); + void __fastcall BtnOutFileView7Click(TObject *Sender); + void __fastcall BtnInFileViewClick(TObject *Sender); + void __fastcall BtnAbortClick(TObject *Sender); + void __fastcall Panel4Resize(TObject *Sender); + void __fastcall Panel2Resize(TObject *Sender); + void __fastcall TimeY1KeyDown(TObject *Sender, WORD &Key, TShiftState Shift); + void __fastcall TimeH1KeyDown(TObject *Sender, WORD &Key, TShiftState Shift); + void __fastcall TimeY2KeyDown(TObject *Sender, WORD &Key, TShiftState Shift); + void __fastcall TimeH2KeyDown(TObject *Sender, WORD &Key, TShiftState Shift); + void __fastcall BtnOutFile8Click(TObject *Sender); + void __fastcall BtnOutFile9Click(TObject *Sender); + void __fastcall BtnOutFileView8Click(TObject *Sender); + void __fastcall BtnOutFileView9Click(TObject *Sender); + void __fastcall TimeY1UDChangingEx(TObject *Sender, bool &AllowChange, int NewValue, + TUpDownDirection Direction); + void __fastcall TimeH1UDChangingEx(TObject *Sender, bool &AllowChange, int NewValue, + TUpDownDirection Direction); + void __fastcall TimeY2UDChangingEx(TObject *Sender, bool &AllowChange, int NewValue, + TUpDownDirection Direction); + void __fastcall TimeH2UDChangingEx(TObject *Sender, bool &AllowChange, int NewValue, + TUpDownDirection Direction); + void __fastcall InFileCloseUp(TObject *Sender); + + private: + AnsiString IniFile, CmdPostExe; + + void __fastcall DropFiles(TWMDropFiles msg); // for files drop + + TStringList *__fastcall ReadList(TIniFile *ini, AnsiString cat, AnsiString key); + void __fastcall WriteList(TIniFile *ini, AnsiString cat, AnsiString key, TStrings *list); + void __fastcall AddHist(TComboBox *combo); + + int __fastcall AutoFormat(AnsiString File); + void __fastcall ConvertFile(void); + void __fastcall SetOutFiles(AnsiString infile); + void __fastcall UpdateEnable(void); + void __fastcall DisableHighlight(void); + void __fastcall GetTime(gtime_t *ts, gtime_t *te, double *tint, double *tunit); + int __fastcall ExecCmd(AnsiString cmd); + AnsiString __fastcall RepPath(AnsiString File); + void __fastcall LoadOpt(void); + void __fastcall SaveOpt(void); + + BEGIN_MESSAGE_MAP + MESSAGE_HANDLER(WM_DROPFILES, TWMDropFiles, DropFiles); + END_MESSAGE_MAP(TForm); + + public: + gtime_t RnxTime; + AnsiString RunBy, Marker, MarkerNo, MarkerType, Name[2], Rec[3], Ant[3]; + AnsiString RnxCode, Comment[2], RcvOption, ExSats; + AnsiString CodeMask[7]; + double AppPos[3], AntDel[3], TimeTol; + int RnxVer, RnxFile, NavSys, ObsType, FreqType, TraceLevel, EventEna; + int AutoPos, PhaseShift, HalfCyc, SortSats, OutIono, OutTime, OutLeaps, SepNav; + int EnaGloFcn, GloFcn[27]; + + __fastcall TMainWindow(TComponent *Owner); }; //--------------------------------------------------------------------------- extern PACKAGE TMainWindow *MainWindow; diff --git a/app/winapp/rtkconv/convopt.cpp b/app/winapp/rtkconv/convopt.cpp index 54dc71b62..5daf6a36d 100644 --- a/app/winapp/rtkconv/convopt.cpp +++ b/app/winapp/rtkconv/convopt.cpp @@ -2,9 +2,10 @@ #include #pragma hdrstop -#include "convmain.h" #include "convopt.h" + #include "codeopt.h" +#include "convmain.h" #include "freqdlg.h" #include "glofcndlg.h" //--------------------------------------------------------------------------- @@ -12,214 +13,193 @@ #pragma resource "*.dfm" TConvOptDialog *ConvOptDialog; //--------------------------------------------------------------------------- -static double str2dbl(AnsiString str) -{ - double val=0.0; - sscanf(str.c_str(),"%lf",&val); - return val; +static double str2dbl(AnsiString str) { + double val = 0.0; + sscanf(str.c_str(), "%lf", &val); + return val; } //--------------------------------------------------------------------------- -__fastcall TConvOptDialog::TConvOptDialog(TComponent* Owner) - : TForm(Owner) -{ - AnsiString s; - int glo=MAXPRNGLO,gal=MAXPRNGAL,qzs=MAXPRNQZS,cmp=MAXPRNCMP,irn=MAXPRNIRN; - if (glo<=0) Nav2->Enabled=false; - if (gal<=0) Nav3->Enabled=false; - if (qzs<=0) Nav4->Enabled=false; - if (cmp<=0) Nav6->Enabled=false; - if (irn<=0) Nav7->Enabled=false; - - UpdateEnable(); +__fastcall TConvOptDialog::TConvOptDialog(TComponent *Owner) : TForm(Owner) { + AnsiString s; + int glo = MAXPRNGLO, gal = MAXPRNGAL, qzs = MAXPRNQZS, cmp = MAXPRNCMP, irn = MAXPRNIRN; + if (glo <= 0) Nav2->Enabled = false; + if (gal <= 0) Nav3->Enabled = false; + if (qzs <= 0) Nav4->Enabled = false; + if (cmp <= 0) Nav6->Enabled = false; + if (irn <= 0) Nav7->Enabled = false; + + UpdateEnable(); } //--------------------------------------------------------------------------- -void __fastcall TConvOptDialog::FormShow(TObject *Sender) -{ - AnsiString s; - RnxVer->ItemIndex=MainWindow->RnxVer; - RnxFile->Checked=MainWindow->RnxFile; - RnxCode->Text=MainWindow->RnxCode; - RunBy->Text=MainWindow->RunBy; - Marker->Text=MainWindow->Marker; - MarkerNo->Text=MainWindow->MarkerNo; - MarkerType->Text=MainWindow->MarkerType; - Name0->Text=MainWindow->Name[0]; - Name1->Text=MainWindow->Name[1]; - Rec0->Text=MainWindow->Rec[0]; - Rec1->Text=MainWindow->Rec[1]; - Rec2->Text=MainWindow->Rec[2]; - Ant0->Text=MainWindow->Ant[0]; - Ant1->Text=MainWindow->Ant[1]; - AppPos0->Text=s.sprintf("%.4f",MainWindow->AppPos[0]); - AppPos1->Text=s.sprintf("%.4f",MainWindow->AppPos[1]); - AppPos2->Text=s.sprintf("%.4f",MainWindow->AppPos[2]); - AntDel0->Text=s.sprintf("%.4f",MainWindow->AntDel[0]); - AntDel1->Text=s.sprintf("%.4f",MainWindow->AntDel[1]); - AntDel2->Text=s.sprintf("%.4f",MainWindow->AntDel[2]); - Comment0->Text=MainWindow->Comment[0]; - Comment1->Text=MainWindow->Comment[1]; - RcvOption->Text=MainWindow->RcvOption; - for (int i=0;i<7;i++) CodeMask[i]=MainWindow->CodeMask[i]; - AutoPos->Checked=MainWindow->AutoPos; - PhaseShift->Checked=MainWindow->PhaseShift; - HalfCyc->Checked=MainWindow->HalfCyc; - SortSats->Checked=MainWindow->SortSats; - OutIono->Checked=MainWindow->OutIono; - OutTime->Checked=MainWindow->OutTime; - OutLeaps->Checked=MainWindow->OutLeaps; - GloFcnDialog->EnaGloFcn=MainWindow->EnaGloFcn; - for (int i=0;i<27;i++) { - GloFcnDialog->GloFcn[i]=MainWindow->GloFcn[i]; - } - Nav1->Checked=MainWindow->NavSys&SYS_GPS; - Nav2->Checked=MainWindow->NavSys&SYS_GLO; - Nav3->Checked=MainWindow->NavSys&SYS_GAL; - Nav4->Checked=MainWindow->NavSys&SYS_QZS; - Nav5->Checked=MainWindow->NavSys&SYS_SBS; - Nav6->Checked=MainWindow->NavSys&SYS_CMP; - Nav7->Checked=MainWindow->NavSys&SYS_IRN; - Obs1->Checked=MainWindow->ObsType&OBSTYPE_PR; - Obs2->Checked=MainWindow->ObsType&OBSTYPE_CP; - Obs3->Checked=MainWindow->ObsType&OBSTYPE_DOP; - Obs4->Checked=MainWindow->ObsType&OBSTYPE_SNR; - Freq1->Checked=MainWindow->FreqType&FREQTYPE_L1; - Freq2->Checked=MainWindow->FreqType&FREQTYPE_L2; - Freq3->Checked=MainWindow->FreqType&FREQTYPE_L3; - Freq4->Checked=MainWindow->FreqType&FREQTYPE_L4; - Freq5->Checked=MainWindow->FreqType&FREQTYPE_L5; - Freq6->Checked=MainWindow->FreqType&FREQTYPE_L6; - ExSats->Text=MainWindow->ExSats; - TraceLevel->ItemIndex=MainWindow->TraceLevel; - ChkSepNav->Checked=MainWindow->SepNav; - TimeTol->Text=s.sprintf("%.4g",MainWindow->TimeTol); - - UpdateEnable(); +void __fastcall TConvOptDialog::FormShow(TObject *Sender) { + AnsiString s; + RnxVer->ItemIndex = MainWindow->RnxVer; + RnxFile->Checked = MainWindow->RnxFile; + RnxCode->Text = MainWindow->RnxCode; + RunBy->Text = MainWindow->RunBy; + Marker->Text = MainWindow->Marker; + MarkerNo->Text = MainWindow->MarkerNo; + MarkerType->Text = MainWindow->MarkerType; + Name0->Text = MainWindow->Name[0]; + Name1->Text = MainWindow->Name[1]; + Rec0->Text = MainWindow->Rec[0]; + Rec1->Text = MainWindow->Rec[1]; + Rec2->Text = MainWindow->Rec[2]; + Ant0->Text = MainWindow->Ant[0]; + Ant1->Text = MainWindow->Ant[1]; + AppPos0->Text = s.sprintf("%.4f", MainWindow->AppPos[0]); + AppPos1->Text = s.sprintf("%.4f", MainWindow->AppPos[1]); + AppPos2->Text = s.sprintf("%.4f", MainWindow->AppPos[2]); + AntDel0->Text = s.sprintf("%.4f", MainWindow->AntDel[0]); + AntDel1->Text = s.sprintf("%.4f", MainWindow->AntDel[1]); + AntDel2->Text = s.sprintf("%.4f", MainWindow->AntDel[2]); + Comment0->Text = MainWindow->Comment[0]; + Comment1->Text = MainWindow->Comment[1]; + RcvOption->Text = MainWindow->RcvOption; + for (int i = 0; i < 7; i++) CodeMask[i] = MainWindow->CodeMask[i]; + AutoPos->Checked = MainWindow->AutoPos; + PhaseShift->Checked = MainWindow->PhaseShift; + HalfCyc->Checked = MainWindow->HalfCyc; + SortSats->Checked = MainWindow->SortSats; + OutIono->Checked = MainWindow->OutIono; + OutTime->Checked = MainWindow->OutTime; + OutLeaps->Checked = MainWindow->OutLeaps; + GloFcnDialog->EnaGloFcn = MainWindow->EnaGloFcn; + for (int i = 0; i < 27; i++) { + GloFcnDialog->GloFcn[i] = MainWindow->GloFcn[i]; + } + Nav1->Checked = MainWindow->NavSys & SYS_GPS; + Nav2->Checked = MainWindow->NavSys & SYS_GLO; + Nav3->Checked = MainWindow->NavSys & SYS_GAL; + Nav4->Checked = MainWindow->NavSys & SYS_QZS; + Nav5->Checked = MainWindow->NavSys & SYS_SBS; + Nav6->Checked = MainWindow->NavSys & SYS_CMP; + Nav7->Checked = MainWindow->NavSys & SYS_IRN; + Obs1->Checked = MainWindow->ObsType & OBSTYPE_PR; + Obs2->Checked = MainWindow->ObsType & OBSTYPE_CP; + Obs3->Checked = MainWindow->ObsType & OBSTYPE_DOP; + Obs4->Checked = MainWindow->ObsType & OBSTYPE_SNR; + Freq1->Checked = MainWindow->FreqType & FREQTYPE_L1; + Freq2->Checked = MainWindow->FreqType & FREQTYPE_L2; + Freq3->Checked = MainWindow->FreqType & FREQTYPE_L3; + Freq4->Checked = MainWindow->FreqType & FREQTYPE_L4; + Freq5->Checked = MainWindow->FreqType & FREQTYPE_L5; + Freq6->Checked = MainWindow->FreqType & FREQTYPE_L6; + ExSats->Text = MainWindow->ExSats; + TraceLevel->ItemIndex = MainWindow->TraceLevel; + ChkSepNav->Checked = MainWindow->SepNav; + TimeTol->Text = s.sprintf("%.4g", MainWindow->TimeTol); + + UpdateEnable(); } //--------------------------------------------------------------------------- -void __fastcall TConvOptDialog::BtnOkClick(TObject *Sender) -{ - MainWindow->RnxVer=RnxVer->ItemIndex; - MainWindow->RnxFile=RnxFile->Checked; - MainWindow->RnxCode=RnxCode->Text; - MainWindow->RunBy=RunBy->Text; - MainWindow->Marker=Marker->Text; - MainWindow->MarkerNo=MarkerNo->Text; - MainWindow->MarkerType=MarkerType->Text; - MainWindow->Name[0]=Name0->Text; - MainWindow->Name[1]=Name1->Text; - MainWindow->Rec[0]=Rec0->Text; - MainWindow->Rec[1]=Rec1->Text; - MainWindow->Rec[2]=Rec2->Text; - MainWindow->Ant[0]=Ant0->Text; - MainWindow->Ant[1]=Ant1->Text; - MainWindow->AppPos[0]=str2dbl(AppPos0->Text); - MainWindow->AppPos[1]=str2dbl(AppPos1->Text); - MainWindow->AppPos[2]=str2dbl(AppPos2->Text); - MainWindow->AntDel[0]=str2dbl(AntDel0->Text); - MainWindow->AntDel[1]=str2dbl(AntDel1->Text); - MainWindow->AntDel[2]=str2dbl(AntDel2->Text); - MainWindow->Comment[0]=Comment0->Text; - MainWindow->Comment[1]=Comment1->Text; - MainWindow->RcvOption=RcvOption->Text; - for (int i=0;i<7;i++) MainWindow->CodeMask[i]=CodeMask[i]; - MainWindow->AutoPos=AutoPos->Checked; - MainWindow->PhaseShift=PhaseShift->Checked; - MainWindow->HalfCyc=HalfCyc->Checked; - MainWindow->SortSats=SortSats->Checked; - MainWindow->OutIono=OutIono->Checked; - MainWindow->OutTime=OutTime->Checked; - MainWindow->OutLeaps=OutLeaps->Checked; - MainWindow->EnaGloFcn=GloFcnDialog->EnaGloFcn; - for (int i=0;i<27;i++) { - MainWindow->GloFcn[i]=GloFcnDialog->GloFcn[i]; - } - int navsys=0,obstype=0,freqtype=0; - if (Nav1->Checked) navsys|=SYS_GPS; - if (Nav2->Checked) navsys|=SYS_GLO; - if (Nav3->Checked) navsys|=SYS_GAL; - if (Nav4->Checked) navsys|=SYS_QZS; - if (Nav5->Checked) navsys|=SYS_SBS; - if (Nav6->Checked) navsys|=SYS_CMP; - if (Nav7->Checked) navsys|=SYS_IRN; - if (Obs1->Checked) obstype|=OBSTYPE_PR; - if (Obs2->Checked) obstype|=OBSTYPE_CP; - if (Obs3->Checked) obstype|=OBSTYPE_DOP; - if (Obs4->Checked) obstype|=OBSTYPE_SNR; - if (Freq1->Checked) freqtype|=FREQTYPE_L1; - if (Freq2->Checked) freqtype|=FREQTYPE_L2; - if (Freq3->Checked) freqtype|=FREQTYPE_L3; - if (Freq4->Checked) freqtype|=FREQTYPE_L4; - if (Freq5->Checked) freqtype|=FREQTYPE_L5; - if (Freq6->Checked) freqtype|=FREQTYPE_L6; - MainWindow->NavSys=navsys; - MainWindow->ObsType=obstype; - MainWindow->FreqType=freqtype; - MainWindow->ExSats=ExSats->Text; - MainWindow->TraceLevel=TraceLevel->ItemIndex; - MainWindow->SepNav=ChkSepNav->Checked; - MainWindow->TimeTol=str2dbl(TimeTol->Text); +void __fastcall TConvOptDialog::BtnOkClick(TObject *Sender) { + MainWindow->RnxVer = RnxVer->ItemIndex; + MainWindow->RnxFile = RnxFile->Checked; + MainWindow->RnxCode = RnxCode->Text; + MainWindow->RunBy = RunBy->Text; + MainWindow->Marker = Marker->Text; + MainWindow->MarkerNo = MarkerNo->Text; + MainWindow->MarkerType = MarkerType->Text; + MainWindow->Name[0] = Name0->Text; + MainWindow->Name[1] = Name1->Text; + MainWindow->Rec[0] = Rec0->Text; + MainWindow->Rec[1] = Rec1->Text; + MainWindow->Rec[2] = Rec2->Text; + MainWindow->Ant[0] = Ant0->Text; + MainWindow->Ant[1] = Ant1->Text; + MainWindow->AppPos[0] = str2dbl(AppPos0->Text); + MainWindow->AppPos[1] = str2dbl(AppPos1->Text); + MainWindow->AppPos[2] = str2dbl(AppPos2->Text); + MainWindow->AntDel[0] = str2dbl(AntDel0->Text); + MainWindow->AntDel[1] = str2dbl(AntDel1->Text); + MainWindow->AntDel[2] = str2dbl(AntDel2->Text); + MainWindow->Comment[0] = Comment0->Text; + MainWindow->Comment[1] = Comment1->Text; + MainWindow->RcvOption = RcvOption->Text; + for (int i = 0; i < 7; i++) MainWindow->CodeMask[i] = CodeMask[i]; + MainWindow->AutoPos = AutoPos->Checked; + MainWindow->PhaseShift = PhaseShift->Checked; + MainWindow->HalfCyc = HalfCyc->Checked; + MainWindow->SortSats = SortSats->Checked; + MainWindow->OutIono = OutIono->Checked; + MainWindow->OutTime = OutTime->Checked; + MainWindow->OutLeaps = OutLeaps->Checked; + MainWindow->EnaGloFcn = GloFcnDialog->EnaGloFcn; + for (int i = 0; i < 27; i++) { + MainWindow->GloFcn[i] = GloFcnDialog->GloFcn[i]; + } + int navsys = 0, obstype = 0, freqtype = 0; + if (Nav1->Checked) navsys |= SYS_GPS; + if (Nav2->Checked) navsys |= SYS_GLO; + if (Nav3->Checked) navsys |= SYS_GAL; + if (Nav4->Checked) navsys |= SYS_QZS; + if (Nav5->Checked) navsys |= SYS_SBS; + if (Nav6->Checked) navsys |= SYS_CMP; + if (Nav7->Checked) navsys |= SYS_IRN; + if (Obs1->Checked) obstype |= OBSTYPE_PR; + if (Obs2->Checked) obstype |= OBSTYPE_CP; + if (Obs3->Checked) obstype |= OBSTYPE_DOP; + if (Obs4->Checked) obstype |= OBSTYPE_SNR; + if (Freq1->Checked) freqtype |= FREQTYPE_L1; + if (Freq2->Checked) freqtype |= FREQTYPE_L2; + if (Freq3->Checked) freqtype |= FREQTYPE_L3; + if (Freq4->Checked) freqtype |= FREQTYPE_L4; + if (Freq5->Checked) freqtype |= FREQTYPE_L5; + if (Freq6->Checked) freqtype |= FREQTYPE_L6; + MainWindow->NavSys = navsys; + MainWindow->ObsType = obstype; + MainWindow->FreqType = freqtype; + MainWindow->ExSats = ExSats->Text; + MainWindow->TraceLevel = TraceLevel->ItemIndex; + MainWindow->SepNav = ChkSepNav->Checked; + MainWindow->TimeTol = str2dbl(TimeTol->Text); } //--------------------------------------------------------------------------- -void __fastcall TConvOptDialog::RnxFileClick(TObject *Sender) -{ - UpdateEnable(); -} +void __fastcall TConvOptDialog::RnxFileClick(TObject *Sender) { UpdateEnable(); } //--------------------------------------------------------------------------- -void __fastcall TConvOptDialog::RnxVerChange(TObject *Sender) -{ - UpdateEnable(); -} +void __fastcall TConvOptDialog::RnxVerChange(TObject *Sender) { UpdateEnable(); } //--------------------------------------------------------------------------- -void __fastcall TConvOptDialog::AutoPosClick(TObject *Sender) -{ - UpdateEnable(); -} +void __fastcall TConvOptDialog::AutoPosClick(TObject *Sender) { UpdateEnable(); } //--------------------------------------------------------------------------- -void __fastcall TConvOptDialog::BtnFreqClick(TObject *Sender) -{ - FreqDialog->ShowModal(); -} +void __fastcall TConvOptDialog::BtnFreqClick(TObject *Sender) { FreqDialog->ShowModal(); } //--------------------------------------------------------------------------- -void __fastcall TConvOptDialog::BtnMaskClick(TObject *Sender) -{ - CodeOptDialog->NavSys=0; - CodeOptDialog->FreqType=0; - if (Nav1->Checked) CodeOptDialog->NavSys|=SYS_GPS; - if (Nav2->Checked) CodeOptDialog->NavSys|=SYS_GLO; - if (Nav3->Checked) CodeOptDialog->NavSys|=SYS_GAL; - if (Nav4->Checked) CodeOptDialog->NavSys|=SYS_QZS; - if (Nav5->Checked) CodeOptDialog->NavSys|=SYS_SBS; - if (Nav6->Checked) CodeOptDialog->NavSys|=SYS_CMP; - if (Nav7->Checked) CodeOptDialog->NavSys|=SYS_IRN; - if (Freq1->Checked) CodeOptDialog->FreqType|=FREQTYPE_L1; - if (Freq2->Checked) CodeOptDialog->FreqType|=FREQTYPE_L2; - if (Freq3->Checked) CodeOptDialog->FreqType|=FREQTYPE_L3; - if (Freq4->Checked) CodeOptDialog->FreqType|=FREQTYPE_L4; - if (Freq5->Checked) CodeOptDialog->FreqType|=FREQTYPE_L5; - if (Freq6->Checked) CodeOptDialog->FreqType|=FREQTYPE_L6; - CodeOptDialog->ShowModal(); +void __fastcall TConvOptDialog::BtnMaskClick(TObject *Sender) { + CodeOptDialog->NavSys = 0; + CodeOptDialog->FreqType = 0; + if (Nav1->Checked) CodeOptDialog->NavSys |= SYS_GPS; + if (Nav2->Checked) CodeOptDialog->NavSys |= SYS_GLO; + if (Nav3->Checked) CodeOptDialog->NavSys |= SYS_GAL; + if (Nav4->Checked) CodeOptDialog->NavSys |= SYS_QZS; + if (Nav5->Checked) CodeOptDialog->NavSys |= SYS_SBS; + if (Nav6->Checked) CodeOptDialog->NavSys |= SYS_CMP; + if (Nav7->Checked) CodeOptDialog->NavSys |= SYS_IRN; + if (Freq1->Checked) CodeOptDialog->FreqType |= FREQTYPE_L1; + if (Freq2->Checked) CodeOptDialog->FreqType |= FREQTYPE_L2; + if (Freq3->Checked) CodeOptDialog->FreqType |= FREQTYPE_L3; + if (Freq4->Checked) CodeOptDialog->FreqType |= FREQTYPE_L4; + if (Freq5->Checked) CodeOptDialog->FreqType |= FREQTYPE_L5; + if (Freq6->Checked) CodeOptDialog->FreqType |= FREQTYPE_L6; + CodeOptDialog->ShowModal(); } //--------------------------------------------------------------------------- -void __fastcall TConvOptDialog::UpdateEnable(void) -{ - AppPos0->Enabled=AutoPos->Checked; - AppPos1->Enabled=AutoPos->Checked; - AppPos2->Enabled=AutoPos->Checked; - ChkSepNav->Enabled=RnxVer->ItemIndex>=3; - Nav3->Enabled=RnxVer->ItemIndex>=1; - Nav4->Enabled=RnxVer->ItemIndex>=5; - Nav6->Enabled=RnxVer->ItemIndex==2||RnxVer->ItemIndex>=4; - Nav7->Enabled=RnxVer->ItemIndex>=6; - Freq3->Enabled=RnxVer->ItemIndex>=1; - Freq4->Enabled=RnxVer->ItemIndex>=1; - Freq5->Enabled=RnxVer->ItemIndex>=1; - Freq6->Enabled=RnxVer->ItemIndex>=1; - PhaseShift->Enabled=RnxVer->ItemIndex>=4; +void __fastcall TConvOptDialog::UpdateEnable(void) { + AppPos0->Enabled = AutoPos->Checked; + AppPos1->Enabled = AutoPos->Checked; + AppPos2->Enabled = AutoPos->Checked; + ChkSepNav->Enabled = RnxVer->ItemIndex >= 3; + Nav3->Enabled = RnxVer->ItemIndex >= 1; + Nav4->Enabled = RnxVer->ItemIndex >= 5; + Nav6->Enabled = RnxVer->ItemIndex == 2 || RnxVer->ItemIndex >= 4; + Nav7->Enabled = RnxVer->ItemIndex >= 6; + Freq3->Enabled = RnxVer->ItemIndex >= 1; + Freq4->Enabled = RnxVer->ItemIndex >= 1; + Freq5->Enabled = RnxVer->ItemIndex >= 1; + Freq6->Enabled = RnxVer->ItemIndex >= 1; + PhaseShift->Enabled = RnxVer->ItemIndex >= 4; } //--------------------------------------------------------------------------- -void __fastcall TConvOptDialog::BtnFcnClick(TObject *Sender) -{ - if (GloFcnDialog->ShowModal()!=mrOk) return; +void __fastcall TConvOptDialog::BtnFcnClick(TObject *Sender) { + if (GloFcnDialog->ShowModal() != mrOk) return; } //--------------------------------------------------------------------------- - diff --git a/app/winapp/rtkconv/convopt.h b/app/winapp/rtkconv/convopt.h index 3841e890d..4a64ff908 100644 --- a/app/winapp/rtkconv/convopt.h +++ b/app/winapp/rtkconv/convopt.h @@ -4,101 +4,101 @@ //--------------------------------------------------------------------------- #include #include -#include -#include #include +#include +#include #include //--------------------------------------------------------------------------- -class TConvOptDialog : public TForm -{ -__published: - TButton *BtnOk; - TButton *BtnCancel; - TGroupBox *GroupBox1; - TLabel *Label1; - TEdit *Marker; - TLabel *Label2; - TEdit *RunBy; - TEdit *Name0; - TEdit *Name1; - TEdit *Rec2; - TEdit *Rec1; - TEdit *Rec0; - TLabel *Label4; - TLabel *Label5; - TEdit *Ant0; - TEdit *Ant1; - TEdit *AppPos2; - TEdit *AntDel2; - TEdit *AppPos1; - TEdit *AntDel1; - TEdit *AppPos0; - TEdit *AntDel0; - TLabel *Label6; - TLabel *Label7; - TLabel *Label10; - TEdit *Comment0; - TEdit *Comment1; - TGroupBox *GroupBox2; - TCheckBox *Nav1; - TCheckBox *Nav2; - TCheckBox *Nav3; - TCheckBox *Nav4; - TGroupBox *GroupBox3; - TCheckBox *Obs2; - TCheckBox *Obs3; - TCheckBox *Obs4; - TGroupBox *GroupBox4; - TCheckBox *Freq1; - TCheckBox *Freq2; - TCheckBox *Freq3; - TCheckBox *Freq4; - TCheckBox *Freq5; - TCheckBox *Freq6; - TCheckBox *Obs1; - TCheckBox *Nav5; - TComboBox *TraceLevel; - TLabel *Label3; - TLabel *Label8; - TEdit *RcvOption; - TLabel *Label9; - TComboBox *RnxVer; - TCheckBox *Nav6; - TEdit *MarkerType; - TEdit *MarkerNo; - TEdit *ExSats; - TLabel *Label11; - TCheckBox *RnxFile; - TLabel *Label12; - TEdit *RnxCode; - TCheckBox *OutIono; - TCheckBox *OutTime; - TCheckBox *OutLeaps; - TCheckBox *AutoPos; - TButton *BtnMask; - TCheckBox *Nav7; - TCheckBox *HalfCyc; - TCheckBox *SortSats; - TCheckBox *ChkSepNav; - TLabel *Label13; - TEdit *TimeTol; - TCheckBox *PhaseShift; - TSpeedButton *BtnFreq; - TButton *BtnFcn; - void __fastcall FormShow(TObject *Sender); - void __fastcall BtnOkClick(TObject *Sender); - void __fastcall RnxFileClick(TObject *Sender); - void __fastcall BtnMaskClick(TObject *Sender); - void __fastcall RnxVerChange(TObject *Sender); - void __fastcall AutoPosClick(TObject *Sender); - void __fastcall BtnFreqClick(TObject *Sender); - void __fastcall BtnFcnClick(TObject *Sender); -private: - void __fastcall UpdateEnable(void); -public: - AnsiString CodeMask[7]; - - __fastcall TConvOptDialog(TComponent* Owner); +class TConvOptDialog : public TForm { + __published : TButton *BtnOk; + TButton *BtnCancel; + TGroupBox *GroupBox1; + TLabel *Label1; + TEdit *Marker; + TLabel *Label2; + TEdit *RunBy; + TEdit *Name0; + TEdit *Name1; + TEdit *Rec2; + TEdit *Rec1; + TEdit *Rec0; + TLabel *Label4; + TLabel *Label5; + TEdit *Ant0; + TEdit *Ant1; + TEdit *AppPos2; + TEdit *AntDel2; + TEdit *AppPos1; + TEdit *AntDel1; + TEdit *AppPos0; + TEdit *AntDel0; + TLabel *Label6; + TLabel *Label7; + TLabel *Label10; + TEdit *Comment0; + TEdit *Comment1; + TGroupBox *GroupBox2; + TCheckBox *Nav1; + TCheckBox *Nav2; + TCheckBox *Nav3; + TCheckBox *Nav4; + TGroupBox *GroupBox3; + TCheckBox *Obs2; + TCheckBox *Obs3; + TCheckBox *Obs4; + TGroupBox *GroupBox4; + TCheckBox *Freq1; + TCheckBox *Freq2; + TCheckBox *Freq3; + TCheckBox *Freq4; + TCheckBox *Freq5; + TCheckBox *Freq6; + TCheckBox *Obs1; + TCheckBox *Nav5; + TComboBox *TraceLevel; + TLabel *Label3; + TLabel *Label8; + TEdit *RcvOption; + TLabel *Label9; + TComboBox *RnxVer; + TCheckBox *Nav6; + TEdit *MarkerType; + TEdit *MarkerNo; + TEdit *ExSats; + TLabel *Label11; + TCheckBox *RnxFile; + TLabel *Label12; + TEdit *RnxCode; + TCheckBox *OutIono; + TCheckBox *OutTime; + TCheckBox *OutLeaps; + TCheckBox *AutoPos; + TButton *BtnMask; + TCheckBox *Nav7; + TCheckBox *HalfCyc; + TCheckBox *SortSats; + TCheckBox *ChkSepNav; + TLabel *Label13; + TEdit *TimeTol; + TCheckBox *PhaseShift; + TSpeedButton *BtnFreq; + TButton *BtnFcn; + void __fastcall FormShow(TObject *Sender); + void __fastcall BtnOkClick(TObject *Sender); + void __fastcall RnxFileClick(TObject *Sender); + void __fastcall BtnMaskClick(TObject *Sender); + void __fastcall RnxVerChange(TObject *Sender); + void __fastcall AutoPosClick(TObject *Sender); + void __fastcall BtnFreqClick(TObject *Sender); + void __fastcall BtnFcnClick(TObject *Sender); + + private: + void __fastcall UpdateEnable(void); + + public: + AnsiString CodeMask[7]; + + __fastcall TConvOptDialog(TComponent *Owner); }; //--------------------------------------------------------------------------- extern PACKAGE TConvOptDialog *ConvOptDialog; diff --git a/app/winapp/rtkconv/rtkconv.cpp b/app/winapp/rtkconv/rtkconv.cpp index f042e93ae..85f2bf777 100644 --- a/app/winapp/rtkconv/rtkconv.cpp +++ b/app/winapp/rtkconv/rtkconv.cpp @@ -16,41 +16,32 @@ USEFORM("..\appcmn\keydlg.cpp", KeyDialog); USEFORM("convopt.cpp", ConvOptDialog); USEFORM("startdlg.cpp", StartDialog); //--------------------------------------------------------------------------- -int WINAPI WinMain(HINSTANCE, HINSTANCE, LPSTR, int) -{ - try - { - Application->Initialize(); - Application->Title = "RTKCONV"; - Application->CreateForm(__classid(TMainWindow), &MainWindow); - Application->CreateForm(__classid(TConvOptDialog), &ConvOptDialog); - Application->CreateForm(__classid(TTextViewer), &TextViewer); - Application->CreateForm(__classid(TViewerOptDialog), &ViewerOptDialog); - Application->CreateForm(__classid(TAboutDialog), &AboutDialog); - Application->CreateForm(__classid(TTimeDialog), &TimeDialog); - Application->CreateForm(__classid(TConfDialog), &ConfDialog); - Application->CreateForm(__classid(TStartDialog), &StartDialog); - Application->CreateForm(__classid(TKeyDialog), &KeyDialog); - Application->CreateForm(__classid(TCodeOptDialog), &CodeOptDialog); - Application->CreateForm(__classid(TFreqDialog), &FreqDialog); - Application->CreateForm(__classid(TGloFcnDialog), &GloFcnDialog); - Application->Run(); - } - catch (Exception &exception) - { - Application->ShowException(&exception); - } - catch (...) - { - try - { - throw Exception(""); - } - catch (Exception &exception) - { - Application->ShowException(&exception); - } - } - return 0; +int WINAPI WinMain(HINSTANCE, HINSTANCE, LPSTR, int) { + try { + Application->Initialize(); + Application->Title = "RTKCONV"; + Application->CreateForm(__classid(TMainWindow), &MainWindow); + Application->CreateForm(__classid(TConvOptDialog), &ConvOptDialog); + Application->CreateForm(__classid(TTextViewer), &TextViewer); + Application->CreateForm(__classid(TViewerOptDialog), &ViewerOptDialog); + Application->CreateForm(__classid(TAboutDialog), &AboutDialog); + Application->CreateForm(__classid(TTimeDialog), &TimeDialog); + Application->CreateForm(__classid(TConfDialog), &ConfDialog); + Application->CreateForm(__classid(TStartDialog), &StartDialog); + Application->CreateForm(__classid(TKeyDialog), &KeyDialog); + Application->CreateForm(__classid(TCodeOptDialog), &CodeOptDialog); + Application->CreateForm(__classid(TFreqDialog), &FreqDialog); + Application->CreateForm(__classid(TGloFcnDialog), &GloFcnDialog); + Application->Run(); + } catch (Exception &exception) { + Application->ShowException(&exception); + } catch (...) { + try { + throw Exception(""); + } catch (Exception &exception) { + Application->ShowException(&exception); + } + } + return 0; } //--------------------------------------------------------------------------- diff --git a/app/winapp/rtkconv/startdlg.cpp b/app/winapp/rtkconv/startdlg.cpp index 0fd0aba78..b33f1912e 100644 --- a/app/winapp/rtkconv/startdlg.cpp +++ b/app/winapp/rtkconv/startdlg.cpp @@ -2,111 +2,119 @@ #include #pragma hdrstop -#include "rtklib.h" #include "startdlg.h" + +#include "rtklib.h" //--------------------------------------------------------------------------- #pragma package(smart_init) #pragma resource "*.dfm" TStartDialog *StartDialog; //--------------------------------------------------------------------------- -__fastcall TStartDialog::TStartDialog(TComponent* Owner) - : TForm(Owner) -{ - Time.time=0; - Time.sec=0.0; +__fastcall TStartDialog::TStartDialog(TComponent *Owner) : TForm(Owner) { + Time.time = 0; + Time.sec = 0.0; } //--------------------------------------------------------------------------- -void __fastcall TStartDialog::FormShow(TObject *Sender) -{ - AnsiString file=FileName; - FILE *fp; - uint32_t time=0; - uint8_t buff[80]={0}; - char tstr[40],path_tag[1024],path[1024],*paths[1]; - - if (Time.time==0) { - Time=utc2gpst(timeget()); - } - // read time tag file if exists - paths[0]=path; - if (expath(file.c_str(),paths,1)) { - sprintf(path_tag,"%s.tag",path); - if ((fp=fopen(path_tag,"rb"))) { - fread(buff,64,1,fp); - if (!strncmp((char *)buff,"TIMETAG",7)&&fread(&time,4,1,fp)) { - Time.time=time; - } - fclose(fp); - } - } - time2str(Time,tstr,0); - tstr[10]='\0'; - TimeY1->Text=tstr; - TimeH1->Text=tstr+11; +void __fastcall TStartDialog::FormShow(TObject *Sender) { + AnsiString file = FileName; + FILE *fp; + uint32_t time = 0; + uint8_t buff[80] = {0}; + char tstr[40], path_tag[1024], path[1024], *paths[1]; + + if (Time.time == 0) { + Time = utc2gpst(timeget()); + } + // read time tag file if exists + paths[0] = path; + if (expath(file.c_str(), paths, 1)) { + sprintf(path_tag, "%s.tag", path); + if ((fp = fopen(path_tag, "rb"))) { + fread(buff, 64, 1, fp); + if (!strncmp((char *)buff, "TIMETAG", 7) && fread(&time, 4, 1, fp)) { + Time.time = time; + } + fclose(fp); + } + } + time2str(Time, tstr, 0); + tstr[10] = '\0'; + TimeY1->Text = tstr; + TimeH1->Text = tstr + 11; } //--------------------------------------------------------------------------- -void __fastcall TStartDialog::BtnOkClick(TObject *Sender) -{ - AnsiString TimeY1_Text=TimeY1->Text,TimeH1_Text=TimeH1->Text; - double ep[]={2000,1,1,0,0,0}; - sscanf(TimeY1_Text.c_str(),"%lf/%lf/%lf",ep,ep+1,ep+2); - sscanf(TimeH1_Text.c_str(),"%lf:%lf:%lf",ep+3,ep+4,ep+5); - Time=epoch2time(ep); +void __fastcall TStartDialog::BtnOkClick(TObject *Sender) { + AnsiString TimeY1_Text = TimeY1->Text, TimeH1_Text = TimeH1->Text; + double ep[] = {2000, 1, 1, 0, 0, 0}; + sscanf(TimeY1_Text.c_str(), "%lf/%lf/%lf", ep, ep + 1, ep + 2); + sscanf(TimeH1_Text.c_str(), "%lf:%lf:%lf", ep + 3, ep + 4, ep + 5); + Time = epoch2time(ep); } //--------------------------------------------------------------------------- -void __fastcall TStartDialog::TimeY1UDChangingEx(TObject *Sender, bool &AllowChange, - int NewValue, TUpDownDirection Direction) -{ - AnsiString TimeY1_Text=TimeY1->Text,s; - double ep[]={2000,1,1,0,0,0}; - int p=TimeY1->SelStart,ud=Direction==updUp?1:-1; - sscanf(TimeY1_Text.c_str(),"%lf/%lf/%lf",ep,ep+1,ep+2); - if (412) {ep[0]++; ep[1]-=12;} - } - else if (p>7||p==0) ep[2]+=ud; else ep[0]+=ud; - time2epoch(epoch2time(ep),ep); - TimeY1->Text=s.sprintf("%04.0f/%02.0f/%02.0f",ep[0],ep[1],ep[2]); - TimeY1->SelStart=p>7||p==0?10:(p>4?7:4); +void __fastcall TStartDialog::TimeY1UDChangingEx(TObject *Sender, bool &AllowChange, int NewValue, + TUpDownDirection Direction) { + AnsiString TimeY1_Text = TimeY1->Text, s; + double ep[] = {2000, 1, 1, 0, 0, 0}; + int p = TimeY1->SelStart, ud = Direction == updUp ? 1 : -1; + sscanf(TimeY1_Text.c_str(), "%lf/%lf/%lf", ep, ep + 1, ep + 2); + if (4 < p && p < 8) { + ep[1] += ud; + if (ep[1] <= 0) { + ep[0]--; + ep[1] += 12; + } else if (ep[1] > 12) { + ep[0]++; + ep[1] -= 12; + } + } else if (p > 7 || p == 0) + ep[2] += ud; + else + ep[0] += ud; + time2epoch(epoch2time(ep), ep); + TimeY1->Text = s.sprintf("%04.0f/%02.0f/%02.0f", ep[0], ep[1], ep[2]); + TimeY1->SelStart = p > 7 || p == 0 ? 10 : (p > 4 ? 7 : 4); } //--------------------------------------------------------------------------- -void __fastcall TStartDialog::TimeH1UDChangingEx(TObject *Sender, bool &AllowChange, - int NewValue, TUpDownDirection Direction) -{ - AnsiString TimeH1_Text=TimeH1->Text,s; - int hms[3]={0},sec,p=TimeH1->SelStart,ud=Direction==updUp?1:-1; - sscanf(TimeH1_Text.c_str(),"%d:%d:%d",hms,hms+1,hms+2); - if (p>5||p==0) hms[2]+=ud; else if (p>2) hms[1]+=ud; else hms[0]+=ud; - sec=hms[0]*3600+hms[1]*60+hms[2]; - if (sec<0) sec+=86400; else if (sec>=86400) sec-=86400; - TimeH1->Text=s.sprintf("%02d:%02d:%02d",sec/3600,(sec%3600)/60,sec%60); - TimeH1->SelStart=p>5||p==0?8:(p>2?5:2); +void __fastcall TStartDialog::TimeH1UDChangingEx(TObject *Sender, bool &AllowChange, int NewValue, + TUpDownDirection Direction) { + AnsiString TimeH1_Text = TimeH1->Text, s; + int hms[3] = {0}, sec, p = TimeH1->SelStart, ud = Direction == updUp ? 1 : -1; + sscanf(TimeH1_Text.c_str(), "%d:%d:%d", hms, hms + 1, hms + 2); + if (p > 5 || p == 0) + hms[2] += ud; + else if (p > 2) + hms[1] += ud; + else + hms[0] += ud; + sec = hms[0] * 3600 + hms[1] * 60 + hms[2]; + if (sec < 0) + sec += 86400; + else if (sec >= 86400) + sec -= 86400; + TimeH1->Text = s.sprintf("%02d:%02d:%02d", sec / 3600, (sec % 3600) / 60, sec % 60); + TimeH1->SelStart = p > 5 || p == 0 ? 8 : (p > 2 ? 5 : 2); } //--------------------------------------------------------------------------- -void __fastcall TStartDialog::BtnFileTimeClick(TObject *Sender) -{ - FILETIME tc,ta,tw; - SYSTEMTIME st; - AnsiString s,file=FileName; - HANDLE h; - char path[1024],*paths[1]; - - // extend wild-card and get first file - paths[0]=path; - if (expath(file.c_str(),paths,1)) { - FileName=path; - } - if ((h=CreateFile(FileName,GENERIC_READ,0,NULL,OPEN_EXISTING, - FILE_ATTRIBUTE_NORMAL,0))==INVALID_HANDLE_VALUE) { - return; - } - GetFileTime(h,&tc,&ta,&tw); - CloseHandle(h); - FileTimeToSystemTime(&tc,&st); // file create time - TimeY1->Text=s.sprintf("%04d/%02d/%02d",st.wYear,st.wMonth,st.wDay); - TimeH1->Text=s.sprintf("%02d:%02d:%02d",st.wHour,st.wMinute,st.wSecond); +void __fastcall TStartDialog::BtnFileTimeClick(TObject *Sender) { + FILETIME tc, ta, tw; + SYSTEMTIME st; + AnsiString s, file = FileName; + HANDLE h; + char path[1024], *paths[1]; + + // extend wild-card and get first file + paths[0] = path; + if (expath(file.c_str(), paths, 1)) { + FileName = path; + } + if ((h = CreateFile(FileName, GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0)) == + INVALID_HANDLE_VALUE) { + return; + } + GetFileTime(h, &tc, &ta, &tw); + CloseHandle(h); + FileTimeToSystemTime(&tc, &st); // file create time + TimeY1->Text = s.sprintf("%04d/%02d/%02d", st.wYear, st.wMonth, st.wDay); + TimeH1->Text = s.sprintf("%02d:%02d:%02d", st.wHour, st.wMinute, st.wSecond); } //--------------------------------------------------------------------------- - diff --git a/app/winapp/rtkconv/startdlg.h b/app/winapp/rtkconv/startdlg.h index 6314394f3..527b27bdf 100644 --- a/app/winapp/rtkconv/startdlg.h +++ b/app/winapp/rtkconv/startdlg.h @@ -3,37 +3,37 @@ #define startdlgH //--------------------------------------------------------------------------- #include -#include -#include -#include #include +#include #include +#include +#include + #include "rtklib.h" //--------------------------------------------------------------------------- -class TStartDialog : public TForm -{ -__published: - TButton *BtnOk; - TButton *BtnCancel; - TPanel *Panel1; - TEdit *TimeY1; - TUpDown *TimeY1UD; - TEdit *TimeH1; - TUpDown *TimeH1UD; - TLabel *Label1; - TButton *BtnFileTime; - void __fastcall FormShow(TObject *Sender); - void __fastcall BtnOkClick(TObject *Sender); - void __fastcall BtnFileTimeClick(TObject *Sender); - void __fastcall TimeH1UDChangingEx(TObject *Sender, bool &AllowChange, int NewValue, - TUpDownDirection Direction); - void __fastcall TimeY1UDChangingEx(TObject *Sender, bool &AllowChange, int NewValue, - TUpDownDirection Direction); -private: -public: - const char *FileName; - gtime_t Time; - __fastcall TStartDialog(TComponent* Owner); +class TStartDialog : public TForm { + __published : TButton *BtnOk; + TButton *BtnCancel; + TPanel *Panel1; + TEdit *TimeY1; + TUpDown *TimeY1UD; + TEdit *TimeH1; + TUpDown *TimeH1UD; + TLabel *Label1; + TButton *BtnFileTime; + void __fastcall FormShow(TObject *Sender); + void __fastcall BtnOkClick(TObject *Sender); + void __fastcall BtnFileTimeClick(TObject *Sender); + void __fastcall TimeH1UDChangingEx(TObject *Sender, bool &AllowChange, int NewValue, + TUpDownDirection Direction); + void __fastcall TimeY1UDChangingEx(TObject *Sender, bool &AllowChange, int NewValue, + TUpDownDirection Direction); + + private: + public: + const char *FileName; + gtime_t Time; + __fastcall TStartDialog(TComponent *Owner); }; //--------------------------------------------------------------------------- extern PACKAGE TStartDialog *StartDialog; diff --git a/app/winapp/rtkget/getmain.cpp b/app/winapp/rtkget/getmain.cpp index 5d5bdf92c..7a0b9905d 100644 --- a/app/winapp/rtkget/getmain.cpp +++ b/app/winapp/rtkget/getmain.cpp @@ -15,13 +15,14 @@ #pragma hdrstop -#include "rtklib.h" -#include "timedlg.h" -#include "keydlg.h" -#include "aboutdlg.h" #include "getmain.h" + +#include "aboutdlg.h" #include "getoptdlg.h" +#include "keydlg.h" +#include "rtklib.h" #include "staoptdlg.h" +#include "timedlg.h" #include "viewer.h" //--------------------------------------------------------------------------- @@ -29,954 +30,916 @@ #pragma resource "*.dfm" TMainForm *MainForm; -#define PRGNAME "RTKGET" // program name +#define PRGNAME "RTKGET" // program name -#define URL_FILE "..\\data\\URL_LIST.txt" -#define TEST_FILE "rtkget_test.txt" -#define TRACE_FILE "rtkget.trace" +#define URL_FILE "..\\data\\URL_LIST.txt" +#define TEST_FILE "rtkget_test.txt" +#define TRACE_FILE "rtkget.trace" -#define MAX_URL 2048 +#define MAX_URL 2048 #define MAX_URL_SEL 64 -#define MAX_STA 2048 -#define MAX_HIST 16 +#define MAX_STA 2048 +#define MAX_HIST 16 -#define MAX(x,y) ((x)>(y)?(x):(y)) +#define MAX(x, y) ((x) > (y) ? (x) : (y)) -static int abortf=0; // abort flag +static int abortf = 0; // abort flag // show message in message area --------------------------------------------- extern "C" { -extern int showmsg(const char *format,...) -{ - va_list arg; - AnsiString str; - char buff[1024],buff2[10224],*p,*q; - int len; - - va_start(arg,format); - vsprintf(buff,format,arg); - va_end(arg); - - if ((p=strstr(buff,"STAT="))) { - str=MainForm->MsgLabel3->Caption; - len=strlen(str.c_str()); - q=buff2; - q+=sprintf(q,"%s",str.c_str()+MAX(len-66,0)); - if (*(q-1)=='_') q--; - sprintf(q,"%s",p+5); - MainForm->MsgLabel3->Caption=buff2; - } - else if ((p=strstr(buff,"->"))) { - *p='\0'; - MainForm->MsgLabel1->Caption=buff; - MainForm->MsgLabel2->Caption=p+2; - } - Application->ProcessMessages(); - return abortf; -} -} -//--------------------------------------------------------------------------- -__fastcall TMainForm::TMainForm(TComponent* Owner) - : TForm(Owner) -{ - DoubleBuffered=true; - - Types =new TStringList; - Urls =new TStringList; - Locals =new TStringList; - - TimerCnt=0; - - LogViewer=NULL; -} -//--------------------------------------------------------------------------- -void __fastcall TMainForm::FormCreate(TObject *Sender) -{ - AnsiString str; - char *p,*argv[32],buff[1024],file[1024]="rtkget.exe"; - int argc=0; - - ::GetModuleFileName(NULL,file,sizeof(file)); - if (!(p=strrchr(file,'.'))) p=file+strlen(file); - strcpy(p,".ini"); - IniFile=file; - - Caption=str.sprintf("%s-%s %s",PRGNAME,VER_RTKLIB,PATCH_LEVEL); - - strcpy(buff,GetCommandLine()); - - for (p=buff;*p&&argc<32;p++) { - if (*p==' ') continue; - if (*p=='"') { - argv[argc++]=p+1; - if (!(p=strchr(p+1,'"'))) break; - } - else { - argv[argc++]=p; - if (!(p=strchr(p+1,' '))) break; - } - *p='\0'; - } - for (int i=1;i0) { - traceopen(TRACE_FILE); - tracelevel(TraceLevel); - } +extern int showmsg(const char *format, ...) { + va_list arg; + AnsiString str; + char buff[1024], buff2[10224], *p, *q; + int len; + + va_start(arg, format); + vsprintf(buff, format, arg); + va_end(arg); + + if ((p = strstr(buff, "STAT="))) { + str = MainForm->MsgLabel3->Caption; + len = strlen(str.c_str()); + q = buff2; + q += sprintf(q, "%s", str.c_str() + MAX(len - 66, 0)); + if (*(q - 1) == '_') q--; + sprintf(q, "%s", p + 5); + MainForm->MsgLabel3->Caption = buff2; + } else if ((p = strstr(buff, "->"))) { + *p = '\0'; + MainForm->MsgLabel1->Caption = buff; + MainForm->MsgLabel2->Caption = p + 2; + } + Application->ProcessMessages(); + return abortf; +} +} +//--------------------------------------------------------------------------- +__fastcall TMainForm::TMainForm(TComponent *Owner) : TForm(Owner) { + DoubleBuffered = true; + + Types = new TStringList; + Urls = new TStringList; + Locals = new TStringList; + + TimerCnt = 0; + + LogViewer = NULL; } //--------------------------------------------------------------------------- -void __fastcall TMainForm::FormShow(TObject *Sender) -{ - ::DragAcceptFiles(Handle,true); +void __fastcall TMainForm::FormCreate(TObject *Sender) { + AnsiString str; + char *p, *argv[32], buff[1024], file[1024] = "rtkget.exe"; + int argc = 0; + + ::GetModuleFileName(NULL, file, sizeof(file)); + if (!(p = strrchr(file, '.'))) p = file + strlen(file); + strcpy(p, ".ini"); + IniFile = file; + + Caption = str.sprintf("%s-%s %s", PRGNAME, VER_RTKLIB, PATCH_LEVEL); + + strcpy(buff, GetCommandLine()); + + for (p = buff; *p && argc < 32; p++) { + if (*p == ' ') continue; + if (*p == '"') { + argv[argc++] = p + 1; + if (!(p = strchr(p + 1, '"'))) break; + } else { + argv[argc++] = p; + if (!(p = strchr(p + 1, ' '))) break; + } + *p = '\0'; + } + for (int i = 1; i < argc; i++) { + if (!strcmp(argv[i], "-i") && i + 1 < argc) IniFile = argv[++i]; + } + for (int i = 1; i < argc; i++) { + if (!strcmp(argv[i], "-t") && i + 1 < argc) Caption = argv[++i]; + } + LoadOpt(); + LoadUrl(UrlFile); + UpdateType(); + UpdateEnable(); + + if (TraceLevel > 0) { + traceopen(TRACE_FILE); + tracelevel(TraceLevel); + } } //--------------------------------------------------------------------------- -void __fastcall TMainForm::FormClose(TObject *Sender, TCloseAction &Action) -{ - traceclose(); - SaveOpt(); -} +void __fastcall TMainForm::FormShow(TObject *Sender) { ::DragAcceptFiles(Handle, true); } //--------------------------------------------------------------------------- -void __fastcall TMainForm::Panel3Resize(TObject *Sender) -{ - TButton *btn[]={ - BtnFile,BtnLog,BtnOpts,BtnTest,BtnDownload,BtnExit - }; - int w=(((TPanel *)Sender)->Width-4)/6; - - for (int i=0;i<6;i++) { - btn[i]->Width=w-2; - btn[i]->Left=w*i+2; - } +void __fastcall TMainForm::FormClose(TObject *Sender, TCloseAction &Action) { + traceclose(); + SaveOpt(); } //--------------------------------------------------------------------------- -void __fastcall TMainForm::Panel2Resize(TObject *Sender) -{ - int w=((TPanel *)Sender)->Width; +void __fastcall TMainForm::Panel3Resize(TObject *Sender) { + TButton *btn[] = {BtnFile, BtnLog, BtnOpts, BtnTest, BtnDownload, BtnExit}; + int w = (((TPanel *)Sender)->Width - 4) / 6; - Panel5->Width=w*140/502; - Panel9->Width=w*140/502; - ::PostMessage(Dir ->Handle,CB_SETEDITSEL,-1,0); - ::PostMessage(TimeInt->Handle,CB_SETEDITSEL,-1,0); + for (int i = 0; i < 6; i++) { + btn[i]->Width = w - 2; + btn[i]->Left = w * i + 2; + } } //--------------------------------------------------------------------------- -void __fastcall TMainForm::Panel6Resize(TObject *Sender) -{ - int w=((TPanel *)Sender)->Width; - - SubType->Width=(w-2)/2; +void __fastcall TMainForm::Panel2Resize(TObject *Sender) { + int w = ((TPanel *)Sender)->Width; + + Panel5->Width = w * 140 / 502; + Panel9->Width = w * 140 / 502; + ::PostMessage(Dir->Handle, CB_SETEDITSEL, -1, 0); + ::PostMessage(TimeInt->Handle, CB_SETEDITSEL, -1, 0); } //--------------------------------------------------------------------------- -void __fastcall TMainForm::BtnFileClick(TObject *Sender) -{ - AnsiString cmd="explorer",opt="",str; - gtime_t ts,te; - double ti; - char path[1024]="."; - str=LocalDir->Checked?Dir->Text:MsgLabel2->Caption; - GetTime(&ts,&te,&ti); - if (str!="") reppath(str.c_str(),path,ts,"",""); - opt.sprintf(" /root,\"%s\" /select,\"%s\"",path,path); - ExecCmd(cmd+opt); +void __fastcall TMainForm::Panel6Resize(TObject *Sender) { + int w = ((TPanel *)Sender)->Width; + + SubType->Width = (w - 2) / 2; +} +//--------------------------------------------------------------------------- +void __fastcall TMainForm::BtnFileClick(TObject *Sender) { + AnsiString cmd = "explorer", opt = "", str; + gtime_t ts, te; + double ti; + char path[1024] = "."; + str = LocalDir->Checked ? Dir->Text : MsgLabel2->Caption; + GetTime(&ts, &te, &ti); + if (str != "") reppath(str.c_str(), path, ts, "", ""); + opt.sprintf(" /root,\"%s\" /select,\"%s\"", path, path); + ExecCmd(cmd + opt); +} +//--------------------------------------------------------------------------- +void __fastcall TMainForm::BtnLogClick(TObject *Sender) { + if (LogFile == "") return; + if (!LogViewer) { + LogViewer = new TTextViewer(Application); + } + LogViewer->Caption = LogFile; + LogViewer->Show(); + LogViewer->Read(LogFile); +} +//--------------------------------------------------------------------------- +void __fastcall TMainForm::BtnTestClick(TObject *Sender) { + TTextViewer *viewer; + TImage *img[] = {Image1, Image2, Image3, Image4, Image5, Image6, Image7, Image8}; + AnsiString str; + FILE *fp; + url_t urls[MAX_URL_SEL]; + gtime_t ts, te; + double ti; + char *stas[MAX_STA]; + const char *dir = ""; + int i, nsta, nurl; + + if (BtnTest->Caption == "&Abort") { + BtnTest->Enabled = false; + abortf = 1; + return; + } + GetTime(&ts, &te, &ti); + nurl = SelectUrl(urls); + if (timediff(ts, te) > 0.0 || nurl <= 0) { + MsgLabel3->Caption = "no local data"; + return; + } + if (!(fp = fopen(TEST_FILE, "w"))) return; + + for (i = 0; i < MAX_STA; i++) stas[i] = new char[16]; + + nsta = SelectSta(stas); + + if (LocalDir->Checked) { + str = Dir->Text; + dir = str.c_str(); + } + PanelEnable(0); + BtnTest->Enabled = true; + BtnTest->Caption = "&Abort"; + MsgLabel1->Font->Color = clGray; + MsgLabel3->Caption = ""; + abortf = 0; + Application->ProcessMessages(); + + dl_test(ts, te, ti, urls, nurl, (const char **)stas, nsta, dir, NCol, DateFormat, fp); + + BtnTest->Caption = "&Test..."; + MsgLabel1->Font->Color = clBlack; + MsgLabel3->Caption = ""; + PanelEnable(1); + UpdateMsg(); + UpdateEnable(); + + fclose(fp); + + viewer = new TTextViewer(Application); + viewer->Option = 2; + viewer->Read(TEST_FILE); + viewer->Caption = "Local File Test"; + viewer->Show(); + + remove(TEST_FILE); + + for (i = 0; i < MAX_STA; i++) delete[] stas[i]; + + if (Dir->Enabled) AddHist(Dir); } //--------------------------------------------------------------------------- -void __fastcall TMainForm::BtnLogClick(TObject *Sender) -{ - if (LogFile=="") return; - if (!LogViewer) { - LogViewer=new TTextViewer(Application); - } - LogViewer->Caption=LogFile; - LogViewer->Show(); +void __fastcall TMainForm::BtnOptsClick(TObject *Sender) { + AnsiString urlfile = UrlFile; + + if (DownOptDialog->ShowModal() != mrOk) return; + + if (UrlFile == urlfile) return; + + LoadUrl(UrlFile); + UpdateType(); +} +//--------------------------------------------------------------------------- +void __fastcall TMainForm::BtnDownloadClick(TObject *Sender) { + TImage *img[] = {Image1, Image2, Image3, Image4, Image5, Image6, Image7, Image8}; + AnsiString str, usr, pwd, proxy; + FILE *fp = NULL; + url_t urls[MAX_URL_SEL]; + gtime_t ts, te; + double ti; + char *stas[MAX_STA], msg[1024], path[1024]; + const char *dir = ""; + int i, nsta, nurl, seqnos = 0, seqnoe = 0, opts = 0; + + if (BtnDownload->Caption == "&Abort") { + BtnDownload->Enabled = false; + abortf = 1; + return; + } + GetTime(&ts, &te, &ti); + + str = Number->Text; + if (sscanf(str.c_str(), "%d-%d", &seqnos, &seqnoe) == 1) seqnoe = seqnos; + + nurl = SelectUrl(urls); + if (timediff(ts, te) > 0.0 || nurl <= 0) { + MsgLabel3->Caption = "no download data"; + return; + } + for (i = 0; i < MAX_STA; i++) stas[i] = new char[16]; + + nsta = SelectSta(stas); + usr = FtpLogin->Text; + pwd = FtpPasswd->Text; + proxy = ProxyAddr; + + if (!SkipExist->Checked) opts |= DLOPT_FORCE; + if (!UnZip->Checked) opts |= DLOPT_KEEPCMP; + if (HoldErr) opts |= DLOPT_HOLDERR; + if (HoldList) opts |= DLOPT_HOLDLST; + + if (LocalDir->Checked) { + str = Dir->Text; + dir = str.c_str(); + } + if (LogFile != "") { + reppath(LogFile.c_str(), path, utc2gpst(timeget()), "", ""); + fp = fopen(path, LogAppend ? "a" : "w"); + } + abortf = 0; + PanelEnable(0); + BtnDownload->Enabled = true; + BtnDownload->Caption = "&Abort"; + MsgLabel3->Caption = ""; + Timer->Enabled = true; + Application->ProcessMessages(); + + dl_exec(ts, te, ti, seqnos, seqnoe, urls, nurl, (const char **)stas, nsta, dir, usr.c_str(), + pwd.c_str(), proxy.c_str(), opts, msg, fp); + + PanelEnable(1); + UpdateEnable(); + BtnDownload->Caption = "&Download"; + MsgLabel3->Caption = msg; + Timer->Enabled = false; + for (i = 0; i < 8; i++) img[i]->Visible = false; + + UpdateMsg(); + UpdateEnable(); + + if (LogFile != "") { + fclose(fp); + } + for (i = 0; i < MAX_STA; i++) delete[] stas[i]; + + if (Dir->Enabled) AddHist(Dir); + + if (LogFile != "" && LogViewer) { LogViewer->Read(LogFile); + } } //--------------------------------------------------------------------------- -void __fastcall TMainForm::BtnTestClick(TObject *Sender) -{ - TTextViewer *viewer; - TImage *img[]={Image1,Image2,Image3,Image4,Image5,Image6,Image7,Image8}; - AnsiString str; - FILE *fp; - url_t urls[MAX_URL_SEL]; - gtime_t ts,te; - double ti; - char *stas[MAX_STA]; - const char *dir=""; - int i,nsta,nurl; - - if (BtnTest->Caption=="&Abort") { - BtnTest->Enabled=false; - abortf=1; - return; - } - GetTime(&ts,&te,&ti); - nurl=SelectUrl(urls); - if (timediff(ts,te)>0.0||nurl<=0) { - MsgLabel3->Caption="no local data"; - return; - } - if (!(fp=fopen(TEST_FILE,"w"))) return; - - for (i=0;iChecked) { - str=Dir->Text; - dir=str.c_str(); - } - PanelEnable(0); - BtnTest->Enabled=true; - BtnTest->Caption="&Abort"; - MsgLabel1->Font->Color=clGray; - MsgLabel3->Caption=""; - abortf=0; - Application->ProcessMessages(); - - dl_test(ts,te,ti,urls,nurl,(const char **)stas,nsta,dir,NCol,DateFormat,fp); - - BtnTest->Caption="&Test..."; - MsgLabel1->Font->Color=clBlack; - MsgLabel3->Caption=""; - PanelEnable(1); - UpdateMsg(); - UpdateEnable(); - - fclose(fp); - - viewer=new TTextViewer(Application); - viewer->Option=2; - viewer->Read(TEST_FILE); - viewer->Caption="Local File Test"; - viewer->Show(); - - remove(TEST_FILE); - - for (i=0;iEnabled) AddHist(Dir); -} -//--------------------------------------------------------------------------- -void __fastcall TMainForm::BtnOptsClick(TObject *Sender) -{ - AnsiString urlfile=UrlFile; - - if (DownOptDialog->ShowModal()!=mrOk) return; - - if (UrlFile==urlfile) return; - - LoadUrl(UrlFile); - UpdateType(); -} -//--------------------------------------------------------------------------- -void __fastcall TMainForm::BtnDownloadClick(TObject *Sender) -{ - TImage *img[]={Image1,Image2,Image3,Image4,Image5,Image6,Image7,Image8}; - AnsiString str,usr,pwd,proxy; - FILE *fp=NULL; - url_t urls[MAX_URL_SEL]; - gtime_t ts,te; - double ti; - char *stas[MAX_STA],msg[1024],path[1024]; - const char *dir=""; - int i,nsta,nurl,seqnos=0,seqnoe=0,opts=0; - - if (BtnDownload->Caption=="&Abort") { - BtnDownload->Enabled=false; - abortf=1; - return; - } - GetTime(&ts,&te,&ti); - - str=Number->Text; - if (sscanf(str.c_str(),"%d-%d",&seqnos,&seqnoe)==1) seqnoe=seqnos; - - nurl=SelectUrl(urls); - if (timediff(ts,te)>0.0||nurl<=0) { - MsgLabel3->Caption="no download data"; - return; - } - for (i=0;iText; - pwd=FtpPasswd->Text; - proxy=ProxyAddr; - - if (!SkipExist->Checked) opts|=DLOPT_FORCE; - if (!UnZip ->Checked) opts|=DLOPT_KEEPCMP; - if (HoldErr ) opts|=DLOPT_HOLDERR; - if (HoldList) opts|=DLOPT_HOLDLST; - - if (LocalDir->Checked) { - str=Dir->Text; - dir=str.c_str(); - } - if (LogFile!="") { - reppath(LogFile.c_str(),path,utc2gpst(timeget()),"",""); - fp=fopen(path,LogAppend?"a":"w"); - } - abortf=0; - PanelEnable(0); - BtnDownload->Enabled=true; - BtnDownload->Caption="&Abort"; - MsgLabel3->Caption=""; - Timer->Enabled=true; - Application->ProcessMessages(); - - dl_exec(ts,te,ti,seqnos,seqnoe,urls,nurl,(const char **)stas,nsta,dir,usr.c_str(), - pwd.c_str(),proxy.c_str(),opts,msg,fp); - - PanelEnable(1); - UpdateEnable(); - BtnDownload->Caption="&Download"; - MsgLabel3->Caption=msg; - Timer->Enabled=false; - for (i=0;i<8;i++) img[i]->Visible=false; - - UpdateMsg(); - UpdateEnable(); - - if (LogFile!="") { - fclose(fp); - } - for (i=0;iEnabled) AddHist(Dir); - - if (LogFile!=""&&LogViewer) { - LogViewer->Read(LogFile); - } -} +void __fastcall TMainForm::BtnExitClick(TObject *Sender) { Close(); } //--------------------------------------------------------------------------- -void __fastcall TMainForm::BtnExitClick(TObject *Sender) -{ - Close(); +void __fastcall TMainForm::BtnStasClick(TObject *Sender) { + if (StaListDialog->ShowModal() != mrOk) return; + UpdateStaList(); + BtnAll->Caption = "A"; } //--------------------------------------------------------------------------- -void __fastcall TMainForm::BtnStasClick(TObject *Sender) -{ - if (StaListDialog->ShowModal()!=mrOk) return; - UpdateStaList(); - BtnAll->Caption="A"; +void __fastcall TMainForm::BtnDirClick(TObject *Sender) { + UnicodeString dir = Dir->Text; + TSelectDirExtOpts opt = TSelectDirExtOpts() << sdNewUI << sdNewFolder; + if (!SelectDirectory(L"Output Directory", L"", dir, opt)) return; + Dir->Text = dir; } //--------------------------------------------------------------------------- -void __fastcall TMainForm::BtnDirClick(TObject *Sender) -{ - UnicodeString dir=Dir->Text; - TSelectDirExtOpts opt=TSelectDirExtOpts()<Text=dir; -} +void __fastcall TMainForm::DirChange(TObject *Sender) { UpdateMsg(); } //--------------------------------------------------------------------------- -void __fastcall TMainForm::DirChange(TObject *Sender) -{ - UpdateMsg(); +void __fastcall TMainForm::BtnTime1Click(TObject *Sender) { + AnsiString TimeY1_Text = TimeY1->Text, TimeH1_Text = TimeH1->Text; + double ep[] = {2000, 1, 1, 0, 0, 0}; + sscanf(TimeY1_Text.c_str(), "%lf/%lf/%lf", ep, ep + 1, ep + 2); + sscanf(TimeH1_Text.c_str(), "%lf:%lf:%lf", ep + 3, ep + 4, ep + 5); + TimeDialog->Time = epoch2time(ep); + TimeDialog->ShowModal(); } //--------------------------------------------------------------------------- -void __fastcall TMainForm::BtnTime1Click(TObject *Sender) -{ - AnsiString TimeY1_Text=TimeY1->Text,TimeH1_Text=TimeH1->Text; - double ep[]={2000,1,1,0,0,0}; - sscanf(TimeY1_Text.c_str(),"%lf/%lf/%lf",ep,ep+1,ep+2); - sscanf(TimeH1_Text.c_str(),"%lf:%lf:%lf",ep+3,ep+4,ep+5); - TimeDialog->Time=epoch2time(ep); - TimeDialog->ShowModal(); +void __fastcall TMainForm::BtnTime2Click(TObject *Sender) { + AnsiString TimeY2_Text = TimeY2->Text, TimeH2_Text = TimeH2->Text; + double ep[] = {2000, 1, 1, 0, 0, 0}; + sscanf(TimeY2_Text.c_str(), "%lf/%lf/%lf", ep, ep + 1, ep + 2); + sscanf(TimeH2_Text.c_str(), "%lf:%lf:%lf", ep + 3, ep + 4, ep + 5); + TimeDialog->Time = epoch2time(ep); + TimeDialog->ShowModal(); } //--------------------------------------------------------------------------- -void __fastcall TMainForm::BtnTime2Click(TObject *Sender) -{ - AnsiString TimeY2_Text=TimeY2->Text,TimeH2_Text=TimeH2->Text; - double ep[]={2000,1,1,0,0,0}; - sscanf(TimeY2_Text.c_str(),"%lf/%lf/%lf",ep,ep+1,ep+2); - sscanf(TimeH2_Text.c_str(),"%lf:%lf:%lf",ep+3,ep+4,ep+5); - TimeDialog->Time=epoch2time(ep); - TimeDialog->ShowModal(); +void __fastcall TMainForm::BtnAllClick(TObject *Sender) { + AnsiString str; + int i, n = 0; + + StaList->Visible = false; + for (i = StaList->Count - 1; i >= 0; i--) { + StaList->Selected[i] = BtnAll->Caption == "A"; + if (StaList->Selected[i]) n++; + } + StaList->Visible = true; + BtnAll->Caption = BtnAll->Caption == "A" ? "C" : "A"; + LabelSta->Caption = str.sprintf("Stations (%d)", n); } //--------------------------------------------------------------------------- -void __fastcall TMainForm::BtnAllClick(TObject *Sender) -{ - AnsiString str; - int i,n=0; - - StaList->Visible=false; - for (i=StaList->Count-1;i>=0;i--) { - StaList->Selected[i]=BtnAll->Caption=="A"; - if (StaList->Selected[i]) n++; - } - StaList->Visible=true; - BtnAll->Caption=BtnAll->Caption=="A"?"C":"A"; - LabelSta->Caption=str.sprintf("Stations (%d)",n); -} -//--------------------------------------------------------------------------- -void __fastcall TMainForm::BtnKeywordClick(TObject *Sender) -{ - KeyDialog->Flag=3; - KeyDialog->Show(); -} -//--------------------------------------------------------------------------- -void __fastcall TMainForm::BtnHelpClick(TObject *Sender) -{ - AnsiString prog=PRGNAME; - AboutDialog->About=prog; - AboutDialog->IconIndex=8; - AboutDialog->ShowModal(); -} -//--------------------------------------------------------------------------- -void __fastcall TMainForm::DropFiles(TWMDropFiles msg) -{ - AnsiString file; - POINT point={0}; - int x,y; - char str[1024]; - - if (DragQueryFile((HDROP)msg.Drop,0xFFFFFFFF,NULL,0)<=0) return; - DragQueryFile((HDROP)msg.Drop,0,str,sizeof(str)); - if (!DragQueryPoint((HDROP)msg.Drop,&point)) return; - - x=point.x; - y=point.y; - - if (StaList->Left<=x&&xLeft+StaList->Width&& - StaList->Top <=y&&yTop +StaList->Height) { - LoadSta(file=str); - } +void __fastcall TMainForm::BtnKeywordClick(TObject *Sender) { + KeyDialog->Flag = 3; + KeyDialog->Show(); } //--------------------------------------------------------------------------- -void __fastcall TMainForm::BtnTrayClick(TObject *Sender) -{ - Visible=false; - TrayIcon->Visible=true; +void __fastcall TMainForm::BtnHelpClick(TObject *Sender) { + AnsiString prog = PRGNAME; + AboutDialog->About = prog; + AboutDialog->IconIndex = 8; + AboutDialog->ShowModal(); } //--------------------------------------------------------------------------- -void __fastcall TMainForm::TrayIconDblClick(TObject *Sender) -{ - Visible=true; - TrayIcon->Visible=false; +void __fastcall TMainForm::DropFiles(TWMDropFiles msg) { + AnsiString file; + POINT point = {0}; + int x, y; + char str[1024]; + + if (DragQueryFile((HDROP)msg.Drop, 0xFFFFFFFF, NULL, 0) <= 0) return; + DragQueryFile((HDROP)msg.Drop, 0, str, sizeof(str)); + if (!DragQueryPoint((HDROP)msg.Drop, &point)) return; + + x = point.x; + y = point.y; + + if (StaList->Left <= x && x < StaList->Left + StaList->Width && StaList->Top <= y && + y < StaList->Top + StaList->Height) { + LoadSta(file = str); + } } //--------------------------------------------------------------------------- -void __fastcall TMainForm::HidePasswdClick(TObject *Sender) -{ - UpdateEnable(); +void __fastcall TMainForm::BtnTrayClick(TObject *Sender) { + Visible = false; + TrayIcon->Visible = true; } //--------------------------------------------------------------------------- -void __fastcall TMainForm::LocalDirClick(TObject *Sender) -{ - UpdateMsg(); - UpdateEnable(); +void __fastcall TMainForm::TrayIconDblClick(TObject *Sender) { + Visible = true; + TrayIcon->Visible = false; } //--------------------------------------------------------------------------- -void __fastcall TMainForm::DataTypeChange(TObject *Sender) -{ - UpdateType(); -} +void __fastcall TMainForm::HidePasswdClick(TObject *Sender) { UpdateEnable(); } //--------------------------------------------------------------------------- -void __fastcall TMainForm::DataListClick(TObject *Sender) -{ - UpdateMsg(); - MsgLabel3->Caption=""; +void __fastcall TMainForm::LocalDirClick(TObject *Sender) { + UpdateMsg(); + UpdateEnable(); } //--------------------------------------------------------------------------- -void __fastcall TMainForm::StaListClick(TObject *Sender) -{ - UpdateStaList(); +void __fastcall TMainForm::DataTypeChange(TObject *Sender) { UpdateType(); } +//--------------------------------------------------------------------------- +void __fastcall TMainForm::DataListClick(TObject *Sender) { + UpdateMsg(); + MsgLabel3->Caption = ""; } //--------------------------------------------------------------------------- -void __fastcall TMainForm::TimeY1UDChangingEx(TObject *Sender, bool &AllowChange, - int NewValue, TUpDownDirection Direction) -{ - AnsiString s,TimeY1_Text=TimeY1->Text; - double ep[]={2000,1,1,0,0,0}; - int p=TimeY1->SelStart,ud=Direction==updUp?1:-1; - - sscanf(TimeY1_Text.c_str(),"%lf/%lf/%lf",ep,ep+1,ep+2); - if (412) {ep[0]++; ep[1]-=12;} - } - else if (p>7||p==0) ep[2]+=ud; else ep[0]+=ud; - time2epoch(epoch2time(ep),ep); - TimeY1->Text=s.sprintf("%04.0f/%02.0f/%02.0f",ep[0],ep[1],ep[2]); - TimeY1->SelStart=p>7||p==0?10:(p>4?7:4); -} -//--------------------------------------------------------------------------- -void __fastcall TMainForm::TimeH1UDChangingEx(TObject *Sender, bool &AllowChange, - int NewValue, TUpDownDirection Direction) -{ - AnsiString s,TimeH1_Text=TimeH1->Text; - int hms[3]={0},sec,p=TimeH1->SelStart,ud=Direction==updUp?1:-1; - - sscanf(TimeH1_Text.c_str(),"%d:%d",hms,hms+1); - if (p>5||p==0) hms[2]+=ud; else if (p>2) hms[1]+=ud; else hms[0]+=ud; - sec=hms[0]*3600+hms[1]*60+hms[2]; - if (sec<0) sec+=86400; else if (sec>=86400) sec-=86400; - TimeH1->Text=s.sprintf("%02d:%02d",sec/3600,(sec%3600)/60); - TimeH1->SelStart=p>5||p==0?8:(p>2?5:2); -} -//--------------------------------------------------------------------------- -void __fastcall TMainForm::TimeY2UDChangingEx(TObject *Sender, bool &AllowChange, - int NewValue, TUpDownDirection Direction) -{ - AnsiString s,TimeY2_Text=TimeY2->Text; - double ep[]={2000,1,1,0,0,0}; - int p=TimeY2->SelStart,ud=Direction==updUp?1:-1; - - sscanf(TimeY2_Text.c_str(),"%lf/%lf/%lf",ep,ep+1,ep+2); - if (412) {ep[0]++; ep[1]-=12;} - } - else if (p>7||p==0) ep[2]+=ud; else ep[0]+=ud; - time2epoch(epoch2time(ep),ep); - TimeY2->Text=s.sprintf("%04.0f/%02.0f/%02.0f",ep[0],ep[1],ep[2]); - TimeY2->SelStart=p>7||p==0?10:(p>4?7:4); -} -//--------------------------------------------------------------------------- -void __fastcall TMainForm::TimeH2UDChangingEx(TObject *Sender, bool &AllowChange, - int NewValue, TUpDownDirection Direction) -{ - AnsiString s,TimeH2_Text=TimeH2->Text; - int hms[3]={0},sec,p=TimeH2->SelStart,ud=Direction==updUp?1:-1; - - sscanf(TimeH2_Text.c_str(),"%d:%d",hms,hms+1); - if (p>5||p==0) hms[2]+=ud; else if (p>2) hms[1]+=ud; else hms[0]+=ud; - sec=hms[0]*3600+hms[1]*60+hms[2]; - if (sec<0) sec+=86400; else if (sec>=86400) sec-=86400; - TimeH2->Text=s.sprintf("%02d:%02d",sec/3600,(sec%3600)/60); - TimeH2->SelStart=p>5||p==0?8:(p>2?5:2); -} -//--------------------------------------------------------------------------- -void __fastcall TMainForm::TimerTimer(TObject *Sender) -{ - TImage *img[]={Image1,Image2,Image3,Image4,Image5,Image6,Image7,Image8}; - - for (int i=0;i<8;i++) { - img[i]->Visible=false; - } - for (int i=0;i<8;i++) { - if (i==TimerCnt%8) img[i]->Visible=true; - } - TimerCnt++; -} -//--------------------------------------------------------------------------- -void __fastcall TMainForm::LoadOpt(void) -{ - TIniFile *ini=new TIniFile(IniFile); - AnsiString stas,s; - char buff[8192],*p; - - TimeY1->Text =ini->ReadString ("opt","startd","2025/01/01"); - TimeH1->Text =ini->ReadString ("opt","starth", "00:00"); - TimeY2->Text =ini->ReadString ("opt","endd", "2025/01/01"); - TimeH2->Text =ini->ReadString ("opt","endh", "00:00"); - TimeInt->Text =ini->ReadString ("opt","timeint", "24H"); - Number->Text =ini->ReadString ("opt","number", "0"); - UrlFile =ini->ReadString ("opt","urlfile", ""); - LogFile =ini->ReadString ("opt","logfile", ""); - Stations =ini->ReadString ("opt","stations", ""); - ProxyAddr =ini->ReadString ("opt","proxyaddr", ""); - FtpLogin ->Text =ini->ReadString ("opt","login", "anonymous"); - FtpPasswd ->Text =ini->ReadString ("opt","passwd", "user@"); - UnZip ->Checked=ini->ReadInteger("opt","unzip", 1); - SkipExist ->Checked=ini->ReadInteger("opt","skipexist", 1); - HidePasswd->Checked=ini->ReadInteger("opt","hidepasswd", 0); - HoldErr =ini->ReadInteger("opt","holderr", 0); - HoldList =ini->ReadInteger("opt","holdlist", 0); - NCol =ini->ReadInteger("opt","ncol", 35); - LogAppend =ini->ReadInteger("opt","logappend", 0); - DateFormat =ini->ReadInteger("opt","dateformat", 0); - TraceLevel =ini->ReadInteger("opt","tracelevel", 0); - LocalDir ->Checked=ini->ReadInteger("opt","localdirena", 0); - Dir ->Text =ini->ReadString ("opt","localdir", ""); - DataType ->Text =ini->ReadString ("opt","datatype", ""); - Width =ini->ReadInteger("window","width", 532); - Height =ini->ReadInteger("window","height", 388); - StaList->Clear(); - for (int i=0;i<10;i++) { - stas=ini->ReadString("sta",s.sprintf("station%d",i),""); - strcpy(buff,stas.c_str()); - for (p=strtok(buff,",");p;p=strtok(NULL,",")) { - StaList->Items->Add(p); - } - } - ReadHist(ini,"dir",Dir->Items); - TTextViewer::Color1=(TColor)ini->ReadInteger("viewer","color1",(int)clBlack); - TTextViewer::Color2=(TColor)ini->ReadInteger("viewer","color2",(int)clWhite); - TTextViewer::FontD=new TFont; - TTextViewer::FontD->Name=ini->ReadString ("viewer","fontname","Courier New"); - TTextViewer::FontD->Size=ini->ReadInteger("viewer","fontsize",9); - delete ini; -} -//--------------------------------------------------------------------------- -void __fastcall TMainForm::SaveOpt(void) -{ - TIniFile *ini=new TIniFile(IniFile); - AnsiString sta,s; - char buff[8192]="",*p; - - ini->WriteString ("opt","startd", TimeY1->Text ); - ini->WriteString ("opt","starth", TimeH1->Text ); - ini->WriteString ("opt","endd", TimeY2->Text ); - ini->WriteString ("opt","endh", TimeH2->Text ); - ini->WriteString ("opt","timeint", TimeInt->Text ); - ini->WriteString ("opt","number", Number->Text ); - ini->WriteString ("opt","urlfile", UrlFile ); - ini->WriteString ("opt","logfile", LogFile ); - ini->WriteString ("opt","stations", Stations ); - ini->WriteString ("opt","proxyaddr", ProxyAddr ); - ini->WriteString ("opt","login", FtpLogin ->Text ); - ini->WriteString ("opt","passwd", FtpPasswd ->Text ); - ini->WriteInteger("opt","unzip", UnZip ->Checked); - ini->WriteInteger("opt","skipexist", SkipExist ->Checked); - ini->WriteInteger("opt","hidepasswd", HidePasswd->Checked); - ini->WriteInteger("opt","holderr", HoldErr ); - ini->WriteInteger("opt","holdlist", HoldList ); - ini->WriteInteger("opt","ncol", NCol ); - ini->WriteInteger("opt","logappend", LogAppend ); - ini->WriteInteger("opt","dateformat", DateFormat ); - ini->WriteInteger("opt","tracelevel", TraceLevel ); - ini->WriteInteger("opt","localdirena",LocalDir ->Checked ); - ini->WriteString ("opt","localdir", Dir ->Text ); - ini->WriteString ("opt","datatype", DataType ->Text ); - ini->WriteInteger("window","width", Width ); - ini->WriteInteger("window","height", Height ); - for (int i=0,j=0;i<10;i++) { - p=buff; *p='\0'; - for (int k=0;k<256&&jCount;k++) { - sta=StaList->Items->Strings[j++]; - p+=sprintf(p,"%s%s",k==0?"":",",sta.c_str()); - } - ini->WriteString ("sta",s.sprintf("station%d",i),buff); - } - WriteHist(ini,"dir",Dir->Items); - ini->WriteInteger("viewer","color1", (int)TTextViewer::Color1); - ini->WriteInteger("viewer","color2", (int)TTextViewer::Color2); - ini->WriteString ("viewer","fontname",TTextViewer::FontD->Name); - ini->WriteInteger("viewer","fontsize",TTextViewer::FontD->Size); - delete ini; -} -//--------------------------------------------------------------------------- -void __fastcall TMainForm::LoadUrl(AnsiString file) -{ - url_t *urls; - char *p,*subtype,sel[]="*",*sels[]={sel}; - int i,j,n; - - urls=new url_t [MAX_URL]; - - Types ->Clear(); - Urls ->Clear(); - Locals ->Clear(); - DataType->Clear(); - SubType ->Clear(); - DataList->Clear(); - DataType->Items->Add("ALL"); - SubType ->Items->Add(""); - - if (file=="") file=URL_FILE; // default url - - n=dl_readurls(file.c_str(),(const char **)sels,1,urls,MAX_URL); - - for (i=0;iAdd(urls[i].type); - Urls ->Add(urls[i].path); - Locals->Add(urls[i].dir ); - - if (!(p=strchr(urls[i].type,'_'))) continue; - *p='\0'; - for (j=0;jItems->Count;j++) { - if (DataType->Items->Strings[j]==urls[i].type) break; - } - if (j>=DataType->Items->Count) { - DataType->Items->Add(urls[i].type); - } - subtype=p+1; - if ((p=strchr(subtype,'_'))) *p='\0'; - for (j=0;jItems->Count;j++) { - if (SubType->Items->Strings[j]==subtype) break; - } - if (j>=SubType->Items->Count) { - SubType->Items->Add(subtype); - } +void __fastcall TMainForm::StaListClick(TObject *Sender) { UpdateStaList(); } +//--------------------------------------------------------------------------- +void __fastcall TMainForm::TimeY1UDChangingEx(TObject *Sender, bool &AllowChange, int NewValue, + TUpDownDirection Direction) { + AnsiString s, TimeY1_Text = TimeY1->Text; + double ep[] = {2000, 1, 1, 0, 0, 0}; + int p = TimeY1->SelStart, ud = Direction == updUp ? 1 : -1; + + sscanf(TimeY1_Text.c_str(), "%lf/%lf/%lf", ep, ep + 1, ep + 2); + if (4 < p && p < 8) { + ep[1] += ud; + if (ep[1] <= 0) { + ep[0]--; + ep[1] += 12; + } else if (ep[1] > 12) { + ep[0]++; + ep[1] -= 12; + } + } else if (p > 7 || p == 0) + ep[2] += ud; + else + ep[0] += ud; + time2epoch(epoch2time(ep), ep); + TimeY1->Text = s.sprintf("%04.0f/%02.0f/%02.0f", ep[0], ep[1], ep[2]); + TimeY1->SelStart = p > 7 || p == 0 ? 10 : (p > 4 ? 7 : 4); +} +//--------------------------------------------------------------------------- +void __fastcall TMainForm::TimeH1UDChangingEx(TObject *Sender, bool &AllowChange, int NewValue, + TUpDownDirection Direction) { + AnsiString s, TimeH1_Text = TimeH1->Text; + int hms[3] = {0}, sec, p = TimeH1->SelStart, ud = Direction == updUp ? 1 : -1; + + sscanf(TimeH1_Text.c_str(), "%d:%d", hms, hms + 1); + if (p > 5 || p == 0) + hms[2] += ud; + else if (p > 2) + hms[1] += ud; + else + hms[0] += ud; + sec = hms[0] * 3600 + hms[1] * 60 + hms[2]; + if (sec < 0) + sec += 86400; + else if (sec >= 86400) + sec -= 86400; + TimeH1->Text = s.sprintf("%02d:%02d", sec / 3600, (sec % 3600) / 60); + TimeH1->SelStart = p > 5 || p == 0 ? 8 : (p > 2 ? 5 : 2); +} +//--------------------------------------------------------------------------- +void __fastcall TMainForm::TimeY2UDChangingEx(TObject *Sender, bool &AllowChange, int NewValue, + TUpDownDirection Direction) { + AnsiString s, TimeY2_Text = TimeY2->Text; + double ep[] = {2000, 1, 1, 0, 0, 0}; + int p = TimeY2->SelStart, ud = Direction == updUp ? 1 : -1; + + sscanf(TimeY2_Text.c_str(), "%lf/%lf/%lf", ep, ep + 1, ep + 2); + if (4 < p && p < 8) { + ep[1] += ud; + if (ep[1] <= 0) { + ep[0]--; + ep[1] += 12; + } else if (ep[1] > 12) { + ep[0]++; + ep[1] -= 12; + } + } else if (p > 7 || p == 0) + ep[2] += ud; + else + ep[0] += ud; + time2epoch(epoch2time(ep), ep); + TimeY2->Text = s.sprintf("%04.0f/%02.0f/%02.0f", ep[0], ep[1], ep[2]); + TimeY2->SelStart = p > 7 || p == 0 ? 10 : (p > 4 ? 7 : 4); +} +//--------------------------------------------------------------------------- +void __fastcall TMainForm::TimeH2UDChangingEx(TObject *Sender, bool &AllowChange, int NewValue, + TUpDownDirection Direction) { + AnsiString s, TimeH2_Text = TimeH2->Text; + int hms[3] = {0}, sec, p = TimeH2->SelStart, ud = Direction == updUp ? 1 : -1; + + sscanf(TimeH2_Text.c_str(), "%d:%d", hms, hms + 1); + if (p > 5 || p == 0) + hms[2] += ud; + else if (p > 2) + hms[1] += ud; + else + hms[0] += ud; + sec = hms[0] * 3600 + hms[1] * 60 + hms[2]; + if (sec < 0) + sec += 86400; + else if (sec >= 86400) + sec -= 86400; + TimeH2->Text = s.sprintf("%02d:%02d", sec / 3600, (sec % 3600) / 60); + TimeH2->SelStart = p > 5 || p == 0 ? 8 : (p > 2 ? 5 : 2); +} +//--------------------------------------------------------------------------- +void __fastcall TMainForm::TimerTimer(TObject *Sender) { + TImage *img[] = {Image1, Image2, Image3, Image4, Image5, Image6, Image7, Image8}; + + for (int i = 0; i < 8; i++) { + img[i]->Visible = false; + } + for (int i = 0; i < 8; i++) { + if (i == TimerCnt % 8) img[i]->Visible = true; + } + TimerCnt++; +} +//--------------------------------------------------------------------------- +void __fastcall TMainForm::LoadOpt(void) { + TIniFile *ini = new TIniFile(IniFile); + AnsiString stas, s; + char buff[8192], *p; + + TimeY1->Text = ini->ReadString("opt", "startd", "2025/01/01"); + TimeH1->Text = ini->ReadString("opt", "starth", "00:00"); + TimeY2->Text = ini->ReadString("opt", "endd", "2025/01/01"); + TimeH2->Text = ini->ReadString("opt", "endh", "00:00"); + TimeInt->Text = ini->ReadString("opt", "timeint", "24H"); + Number->Text = ini->ReadString("opt", "number", "0"); + UrlFile = ini->ReadString("opt", "urlfile", ""); + LogFile = ini->ReadString("opt", "logfile", ""); + Stations = ini->ReadString("opt", "stations", ""); + ProxyAddr = ini->ReadString("opt", "proxyaddr", ""); + FtpLogin->Text = ini->ReadString("opt", "login", "anonymous"); + FtpPasswd->Text = ini->ReadString("opt", "passwd", "user@"); + UnZip->Checked = ini->ReadInteger("opt", "unzip", 1); + SkipExist->Checked = ini->ReadInteger("opt", "skipexist", 1); + HidePasswd->Checked = ini->ReadInteger("opt", "hidepasswd", 0); + HoldErr = ini->ReadInteger("opt", "holderr", 0); + HoldList = ini->ReadInteger("opt", "holdlist", 0); + NCol = ini->ReadInteger("opt", "ncol", 35); + LogAppend = ini->ReadInteger("opt", "logappend", 0); + DateFormat = ini->ReadInteger("opt", "dateformat", 0); + TraceLevel = ini->ReadInteger("opt", "tracelevel", 0); + LocalDir->Checked = ini->ReadInteger("opt", "localdirena", 0); + Dir->Text = ini->ReadString("opt", "localdir", ""); + DataType->Text = ini->ReadString("opt", "datatype", ""); + Width = ini->ReadInteger("window", "width", 532); + Height = ini->ReadInteger("window", "height", 388); + StaList->Clear(); + for (int i = 0; i < 10; i++) { + stas = ini->ReadString("sta", s.sprintf("station%d", i), ""); + strcpy(buff, stas.c_str()); + for (p = strtok(buff, ","); p; p = strtok(NULL, ",")) { + StaList->Items->Add(p); + } + } + ReadHist(ini, "dir", Dir->Items); + TTextViewer::Color1 = (TColor)ini->ReadInteger("viewer", "color1", (int)clBlack); + TTextViewer::Color2 = (TColor)ini->ReadInteger("viewer", "color2", (int)clWhite); + TTextViewer::FontD = new TFont; + TTextViewer::FontD->Name = ini->ReadString("viewer", "fontname", "Courier New"); + TTextViewer::FontD->Size = ini->ReadInteger("viewer", "fontsize", 9); + delete ini; +} +//--------------------------------------------------------------------------- +void __fastcall TMainForm::SaveOpt(void) { + TIniFile *ini = new TIniFile(IniFile); + AnsiString sta, s; + char buff[8192] = "", *p; + + ini->WriteString("opt", "startd", TimeY1->Text); + ini->WriteString("opt", "starth", TimeH1->Text); + ini->WriteString("opt", "endd", TimeY2->Text); + ini->WriteString("opt", "endh", TimeH2->Text); + ini->WriteString("opt", "timeint", TimeInt->Text); + ini->WriteString("opt", "number", Number->Text); + ini->WriteString("opt", "urlfile", UrlFile); + ini->WriteString("opt", "logfile", LogFile); + ini->WriteString("opt", "stations", Stations); + ini->WriteString("opt", "proxyaddr", ProxyAddr); + ini->WriteString("opt", "login", FtpLogin->Text); + ini->WriteString("opt", "passwd", FtpPasswd->Text); + ini->WriteInteger("opt", "unzip", UnZip->Checked); + ini->WriteInteger("opt", "skipexist", SkipExist->Checked); + ini->WriteInteger("opt", "hidepasswd", HidePasswd->Checked); + ini->WriteInteger("opt", "holderr", HoldErr); + ini->WriteInteger("opt", "holdlist", HoldList); + ini->WriteInteger("opt", "ncol", NCol); + ini->WriteInteger("opt", "logappend", LogAppend); + ini->WriteInteger("opt", "dateformat", DateFormat); + ini->WriteInteger("opt", "tracelevel", TraceLevel); + ini->WriteInteger("opt", "localdirena", LocalDir->Checked); + ini->WriteString("opt", "localdir", Dir->Text); + ini->WriteString("opt", "datatype", DataType->Text); + ini->WriteInteger("window", "width", Width); + ini->WriteInteger("window", "height", Height); + for (int i = 0, j = 0; i < 10; i++) { + p = buff; + *p = '\0'; + for (int k = 0; k < 256 && j < StaList->Count; k++) { + sta = StaList->Items->Strings[j++]; + p += sprintf(p, "%s%s", k == 0 ? "" : ",", sta.c_str()); + } + ini->WriteString("sta", s.sprintf("station%d", i), buff); + } + WriteHist(ini, "dir", Dir->Items); + ini->WriteInteger("viewer", "color1", (int)TTextViewer::Color1); + ini->WriteInteger("viewer", "color2", (int)TTextViewer::Color2); + ini->WriteString("viewer", "fontname", TTextViewer::FontD->Name); + ini->WriteInteger("viewer", "fontsize", TTextViewer::FontD->Size); + delete ini; +} +//--------------------------------------------------------------------------- +void __fastcall TMainForm::LoadUrl(AnsiString file) { + url_t *urls; + char *p, *subtype, sel[] = "*", *sels[] = {sel}; + int i, j, n; + + urls = new url_t[MAX_URL]; + + Types->Clear(); + Urls->Clear(); + Locals->Clear(); + DataType->Clear(); + SubType->Clear(); + DataList->Clear(); + DataType->Items->Add("ALL"); + SubType->Items->Add(""); + + if (file == "") file = URL_FILE; // default url + + n = dl_readurls(file.c_str(), (const char **)sels, 1, urls, MAX_URL); + + for (i = 0; i < n; i++) { + Types->Add(urls[i].type); + Urls->Add(urls[i].path); + Locals->Add(urls[i].dir); + + if (!(p = strchr(urls[i].type, '_'))) continue; + *p = '\0'; + for (j = 0; j < DataType->Items->Count; j++) { + if (DataType->Items->Strings[j] == urls[i].type) break; } - DataType->ItemIndex=0; - SubType ->ItemIndex=0; - - delete [] urls; -} -//--------------------------------------------------------------------------- -void __fastcall TMainForm::LoadSta(AnsiString file) -{ - FILE *fp; - char buff[4096],*p; - - if (!(fp=fopen(file.c_str(),"r"))) return; - - StaList->Clear(); - - while (fgets(buff,sizeof(buff),fp)) { - if ((p=strchr(buff,'#'))) *p='\0'; - for (p=strtok(buff," ,\r\n");p;p=strtok(NULL," ,\r\n")) { - StaList->Items->Add(p); - } + if (j >= DataType->Items->Count) { + DataType->Items->Add(urls[i].type); } - fclose(fp); - UpdateStaList(); - BtnAll->Caption="A"; -} -//--------------------------------------------------------------------------- -void __fastcall TMainForm::GetTime(gtime_t *ts, gtime_t *te, double *ti) -{ - AnsiString str; - double eps[6]={2010,1,1},epe[6]={2010,1,1},val; - char unit[32]=""; - - str=TimeY1->Text; sscanf(str.c_str(),"%lf/%lf/%lf",eps,eps+1,eps+2); - str=TimeH1->Text; sscanf(str.c_str(),"%lf:%lf" ,eps+3,eps+4 ); - str=TimeY2->Text; sscanf(str.c_str(),"%lf/%lf/%lf",epe,epe+1,epe+2); - str=TimeH2->Text; sscanf(str.c_str(),"%lf:%lf" ,epe+3,epe+4 ); - - *ts=epoch2time(eps); - *te=epoch2time(epe); - *ti=86400.0; - - str=TimeInt->Text; - if (sscanf(str.c_str(),"%lf%31s",&val,unit)>=1) { - if (!strcmp(unit,"day")) *ti=val*86400.0; - else if (!strcmp(unit,"min")) *ti=val*60.0; - else *ti=val*3600.0; + subtype = p + 1; + if ((p = strchr(subtype, '_'))) *p = '\0'; + for (j = 0; j < SubType->Items->Count; j++) { + if (SubType->Items->Strings[j] == subtype) break; } - if (TimeInt->Text=="-") { - *te=*ts; + if (j >= SubType->Items->Count) { + SubType->Items->Add(subtype); } + } + DataType->ItemIndex = 0; + SubType->ItemIndex = 0; + + delete[] urls; } //--------------------------------------------------------------------------- -int __fastcall TMainForm::SelectUrl(url_t *urls) -{ - AnsiString str,file=UrlFile; - char *types[MAX_URL_SEL]; - int i,nurl=0; - - for (i=0;iCount&&nurlSelected[i]) continue; - str=DataList->Items->Strings[i]; - strcpy(types[nurl++],str.c_str()); - } - if (UrlFile=="") file=URL_FILE; - - nurl=dl_readurls(file.c_str(),(const char **)types,nurl,urls,MAX_URL_SEL); - - for (i=0;iCount&&nstaSelected[i]) continue; - str=StaList->Items->Strings[i]; - len=strlen(str.c_str()); - if ((p=strchr(str.c_str(),' '))) len=(int)(p-str.c_str()); - if (len>15) len=15; - strncpy(stas[nsta],str.c_str(),len); - stas[nsta++][len]='\0'; - } - return nsta; -} -//--------------------------------------------------------------------------- -void __fastcall TMainForm::UpdateType(void) -{ - AnsiString str; - char buff[256],*p; - const char *type,*subtype; - int i; - - DataList->Clear(); - - for (i=0;iCount;i++) { - str=Types->Strings[i]; - strcpy(buff,str.c_str()); - type=subtype=""; - if ((p=strchr(buff,'_'))) { - type=buff; subtype=p+1; *p='\0'; - } - if (p&&(p=strchr(p+1,'_'))) *p='\0'; - if (DataType->Text!="ALL"&&DataType->Text!=type) continue; - if (SubType ->Text!=""&&SubType ->Text!=subtype) continue; - DataList->Items->Add(Types->Strings[i]); - } - MsgLabel1->Caption=""; - MsgLabel2->Caption=""; -} -//--------------------------------------------------------------------------- -void __fastcall TMainForm::UpdateMsg(void) -{ - int i,j,n=0; - - for (i=0;iCount;i++) { - if (!DataList->Selected[i]) continue; - for (j=0;jCount;j++) { - if (DataList->Items->Strings[i]!=Types->Strings[j]) continue; - MsgLabel1->Caption=Urls->Strings[j]; - MsgLabel2->Caption=LocalDir->Checked?Dir->Text:Locals->Strings[j]; - Msg1->Hint=MsgLabel1->Caption; - Msg2->Hint=MsgLabel2->Caption; - n++; - break; - } - } - if (n>=2) { - MsgLabel1->Caption=MsgLabel1->Caption+" ..."; - MsgLabel2->Caption=MsgLabel2->Caption+" ..."; +void __fastcall TMainForm::LoadSta(AnsiString file) { + FILE *fp; + char buff[4096], *p; + + if (!(fp = fopen(file.c_str(), "r"))) return; + + StaList->Clear(); + + while (fgets(buff, sizeof(buff), fp)) { + if ((p = strchr(buff, '#'))) *p = '\0'; + for (p = strtok(buff, " ,\r\n"); p; p = strtok(NULL, " ,\r\n")) { + StaList->Items->Add(p); } + } + fclose(fp); + UpdateStaList(); + BtnAll->Caption = "A"; } //--------------------------------------------------------------------------- -void __fastcall TMainForm::UpdateStaList(void) -{ - AnsiString str; - int i,n=0; - - for (i=0;iCount;i++) { - if (StaList->Selected[i]) n++; - } - LabelSta->Caption=str.sprintf("Stations (%d)",n); -} -//--------------------------------------------------------------------------- -void __fastcall TMainForm::UpdateEnable(void) -{ - Dir ->Enabled=LocalDir->Checked; - BtnDir->Enabled=LocalDir->Checked; - FtpPasswd->PasswordChar=HidePasswd->Checked?'*':'\0'; - Label3 ->Enabled=TimeInt->Text!="-"; - TimeY2 ->Enabled=TimeInt->Text!="-"; - TimeY2UD->Enabled=TimeInt->Text!="-"; - TimeH2 ->Enabled=TimeInt->Text!="-"; - TimeH2UD->Enabled=TimeInt->Text!="-"; - BtnTime2->Enabled=TimeInt->Text!="-"; -} -//--------------------------------------------------------------------------- -void __fastcall TMainForm::PanelEnable(int ena) -{ - Panel2 ->Enabled=ena; - BtnFile ->Enabled=ena; - BtnLog ->Enabled=ena; - BtnOpts ->Enabled=ena; - BtnTest ->Enabled=ena; - BtnDownload->Enabled=ena; - BtnExit ->Enabled=ena; +void __fastcall TMainForm::GetTime(gtime_t *ts, gtime_t *te, double *ti) { + AnsiString str; + double eps[6] = {2010, 1, 1}, epe[6] = {2010, 1, 1}, val; + char unit[32] = ""; + + str = TimeY1->Text; + sscanf(str.c_str(), "%lf/%lf/%lf", eps, eps + 1, eps + 2); + str = TimeH1->Text; + sscanf(str.c_str(), "%lf:%lf", eps + 3, eps + 4); + str = TimeY2->Text; + sscanf(str.c_str(), "%lf/%lf/%lf", epe, epe + 1, epe + 2); + str = TimeH2->Text; + sscanf(str.c_str(), "%lf:%lf", epe + 3, epe + 4); + + *ts = epoch2time(eps); + *te = epoch2time(epe); + *ti = 86400.0; + + str = TimeInt->Text; + if (sscanf(str.c_str(), "%lf%31s", &val, unit) >= 1) { + if (!strcmp(unit, "day")) + *ti = val * 86400.0; + else if (!strcmp(unit, "min")) + *ti = val * 60.0; + else + *ti = val * 3600.0; + } + if (TimeInt->Text == "-") { + *te = *ts; + } +} +//--------------------------------------------------------------------------- +int __fastcall TMainForm::SelectUrl(url_t *urls) { + AnsiString str, file = UrlFile; + char *types[MAX_URL_SEL]; + int i, nurl = 0; + + for (i = 0; i < MAX_URL_SEL; i++) types[i] = new char[64]; + + for (i = 0; i < DataList->Count && nurl < MAX_URL_SEL; i++) { + if (!DataList->Selected[i]) continue; + str = DataList->Items->Strings[i]; + strcpy(types[nurl++], str.c_str()); + } + if (UrlFile == "") file = URL_FILE; + + nurl = dl_readurls(file.c_str(), (const char **)types, nurl, urls, MAX_URL_SEL); + + for (i = 0; i < MAX_URL_SEL; i++) delete[] types[i]; + + return nurl; +} +//--------------------------------------------------------------------------- +int __fastcall TMainForm::SelectSta(char **stas) { + AnsiString str; + char *p; + int i, nsta = 0, len; + + for (i = 0; i < StaList->Count && nsta < MAX_STA; i++) { + if (!StaList->Selected[i]) continue; + str = StaList->Items->Strings[i]; + len = strlen(str.c_str()); + if ((p = strchr(str.c_str(), ' '))) len = (int)(p - str.c_str()); + if (len > 15) len = 15; + strncpy(stas[nsta], str.c_str(), len); + stas[nsta++][len] = '\0'; + } + return nsta; +} +//--------------------------------------------------------------------------- +void __fastcall TMainForm::UpdateType(void) { + AnsiString str; + char buff[256], *p; + const char *type, *subtype; + int i; + + DataList->Clear(); + + for (i = 0; i < Types->Count; i++) { + str = Types->Strings[i]; + strcpy(buff, str.c_str()); + type = subtype = ""; + if ((p = strchr(buff, '_'))) { + type = buff; + subtype = p + 1; + *p = '\0'; + } + if (p && (p = strchr(p + 1, '_'))) *p = '\0'; + if (DataType->Text != "ALL" && DataType->Text != type) continue; + if (SubType->Text != "" && SubType->Text != subtype) continue; + DataList->Items->Add(Types->Strings[i]); + } + MsgLabel1->Caption = ""; + MsgLabel2->Caption = ""; +} +//--------------------------------------------------------------------------- +void __fastcall TMainForm::UpdateMsg(void) { + int i, j, n = 0; + + for (i = 0; i < DataList->Count; i++) { + if (!DataList->Selected[i]) continue; + for (j = 0; j < Types->Count; j++) { + if (DataList->Items->Strings[i] != Types->Strings[j]) continue; + MsgLabel1->Caption = Urls->Strings[j]; + MsgLabel2->Caption = LocalDir->Checked ? Dir->Text : Locals->Strings[j]; + Msg1->Hint = MsgLabel1->Caption; + Msg2->Hint = MsgLabel2->Caption; + n++; + break; + } + } + if (n >= 2) { + MsgLabel1->Caption = MsgLabel1->Caption + " ..."; + MsgLabel2->Caption = MsgLabel2->Caption + " ..."; + } +} +//--------------------------------------------------------------------------- +void __fastcall TMainForm::UpdateStaList(void) { + AnsiString str; + int i, n = 0; + + for (i = 0; i < StaList->Count; i++) { + if (StaList->Selected[i]) n++; + } + LabelSta->Caption = str.sprintf("Stations (%d)", n); +} +//--------------------------------------------------------------------------- +void __fastcall TMainForm::UpdateEnable(void) { + Dir->Enabled = LocalDir->Checked; + BtnDir->Enabled = LocalDir->Checked; + FtpPasswd->PasswordChar = HidePasswd->Checked ? '*' : '\0'; + Label3->Enabled = TimeInt->Text != "-"; + TimeY2->Enabled = TimeInt->Text != "-"; + TimeY2UD->Enabled = TimeInt->Text != "-"; + TimeH2->Enabled = TimeInt->Text != "-"; + TimeH2UD->Enabled = TimeInt->Text != "-"; + BtnTime2->Enabled = TimeInt->Text != "-"; +} +//--------------------------------------------------------------------------- +void __fastcall TMainForm::PanelEnable(int ena) { + Panel2->Enabled = ena; + BtnFile->Enabled = ena; + BtnLog->Enabled = ena; + BtnOpts->Enabled = ena; + BtnTest->Enabled = ena; + BtnDownload->Enabled = ena; + BtnExit->Enabled = ena; } // -------------------------------------------------------------------------- -void __fastcall TMainForm::ReadHist(TIniFile *ini, AnsiString key, TStrings *list) -{ - AnsiString s,item; - int i; - - list->Clear(); - - for (i=0;iReadString("history",s.sprintf("%s_%03d",key.c_str(),i),""); - if (item!="") list->Add(item); - } +void __fastcall TMainForm::ReadHist(TIniFile *ini, AnsiString key, TStrings *list) { + AnsiString s, item; + int i; + + list->Clear(); + + for (i = 0; i < MAX_HIST; i++) { + item = ini->ReadString("history", s.sprintf("%s_%03d", key.c_str(), i), ""); + if (item != "") list->Add(item); + } } // -------------------------------------------------------------------------- -void __fastcall TMainForm::WriteHist(TIniFile *ini, AnsiString key, TStrings *list) -{ - AnsiString s; - int i; - - for (i=0;iCount;i++) { - ini->WriteString("history",s.sprintf("%s_%03d",key.c_str(),i),list->Strings[i]); - } +void __fastcall TMainForm::WriteHist(TIniFile *ini, AnsiString key, TStrings *list) { + AnsiString s; + int i; + + for (i = 0; i < list->Count; i++) { + ini->WriteString("history", s.sprintf("%s_%03d", key.c_str(), i), list->Strings[i]); + } } // -------------------------------------------------------------------------- -void __fastcall TMainForm::AddHist(TComboBox *combo) -{ - AnsiString hist=combo->Text; - if (hist=="") return; - TStrings *list=combo->Items; - int i=list->IndexOf(hist); - if (i>=0) list->Delete(i); - list->Insert(0,hist); - for (int i=list->Count-1;i>=MAX_HIST;i--) list->Delete(i); - combo->ItemIndex=0; -} -//--------------------------------------------------------------------------- -int __fastcall TMainForm::ExecCmd(AnsiString cmd) -{ - PROCESS_INFORMATION info; - STARTUPINFO si={0}; - si.cb=sizeof(si); - char *p=cmd.c_str(); - if (!CreateProcess(NULL,p,NULL,NULL,false,0,NULL,NULL,&si,&info)) return 0; - CloseHandle(info.hProcess); - CloseHandle(info.hThread); - return 1; +void __fastcall TMainForm::AddHist(TComboBox *combo) { + AnsiString hist = combo->Text; + if (hist == "") return; + TStrings *list = combo->Items; + int i = list->IndexOf(hist); + if (i >= 0) list->Delete(i); + list->Insert(0, hist); + for (int i = list->Count - 1; i >= MAX_HIST; i--) list->Delete(i); + combo->ItemIndex = 0; +} +//--------------------------------------------------------------------------- +int __fastcall TMainForm::ExecCmd(AnsiString cmd) { + PROCESS_INFORMATION info; + STARTUPINFO si = {0}; + si.cb = sizeof(si); + char *p = cmd.c_str(); + if (!CreateProcess(NULL, p, NULL, NULL, false, 0, NULL, NULL, &si, &info)) return 0; + CloseHandle(info.hProcess); + CloseHandle(info.hThread); + return 1; } //--ComboCloseUp--------------------------------------------------------------- -void __fastcall TMainForm::ComboCloseUp(TObject *Sender) -{ - TComboBox *combo=(TComboBox *)Sender; - - ::PostMessage(combo->Handle,CB_SETEDITSEL,-1,0); -} -//--------------------------------------------------------------------------- -void __fastcall TMainForm::TimeY1KeyDown(TObject *Sender, WORD &Key, TShiftState Shift) -{ - bool allowchange; - if (Key==VK_UP||Key==VK_DOWN) { - TimeY1UDChangingEx(Sender,allowchange,0,Key==VK_UP?updUp:updDown); - Key=0; - } +void __fastcall TMainForm::ComboCloseUp(TObject *Sender) { + TComboBox *combo = (TComboBox *)Sender; + + ::PostMessage(combo->Handle, CB_SETEDITSEL, -1, 0); } //--------------------------------------------------------------------------- -void __fastcall TMainForm::TimeH1KeyDown(TObject *Sender, WORD &Key, TShiftState Shift) -{ - bool allowchange; - if (Key==VK_UP||Key==VK_DOWN) { - TimeH1UDChangingEx(Sender,allowchange,0,Key==VK_UP?updUp:updDown); - Key=0; - } +void __fastcall TMainForm::TimeY1KeyDown(TObject *Sender, WORD &Key, TShiftState Shift) { + bool allowchange; + if (Key == VK_UP || Key == VK_DOWN) { + TimeY1UDChangingEx(Sender, allowchange, 0, Key == VK_UP ? updUp : updDown); + Key = 0; + } } //--------------------------------------------------------------------------- -void __fastcall TMainForm::TimeH2KeyDown(TObject *Sender, WORD &Key, TShiftState Shift) -{ - bool allowchange; - if (Key==VK_UP||Key==VK_DOWN) { - TimeH2UDChangingEx(Sender,allowchange,0,Key==VK_UP?updUp:updDown); - Key=0; - } +void __fastcall TMainForm::TimeH1KeyDown(TObject *Sender, WORD &Key, TShiftState Shift) { + bool allowchange; + if (Key == VK_UP || Key == VK_DOWN) { + TimeH1UDChangingEx(Sender, allowchange, 0, Key == VK_UP ? updUp : updDown); + Key = 0; + } } //--------------------------------------------------------------------------- -void __fastcall TMainForm::TimeY2KeyDown(TObject *Sender, WORD &Key, TShiftState Shift) -{ - bool allowchange; - if (Key==VK_UP||Key==VK_DOWN) { - TimeY2UDChangingEx(Sender,allowchange,0,Key==VK_UP?updUp:updDown); - Key=0; - } +void __fastcall TMainForm::TimeH2KeyDown(TObject *Sender, WORD &Key, TShiftState Shift) { + bool allowchange; + if (Key == VK_UP || Key == VK_DOWN) { + TimeH2UDChangingEx(Sender, allowchange, 0, Key == VK_UP ? updUp : updDown); + Key = 0; + } } //--------------------------------------------------------------------------- -void __fastcall TMainForm::TimeIntChange(TObject *Sender) -{ - UpdateEnable(); +void __fastcall TMainForm::TimeY2KeyDown(TObject *Sender, WORD &Key, TShiftState Shift) { + bool allowchange; + if (Key == VK_UP || Key == VK_DOWN) { + TimeY2UDChangingEx(Sender, allowchange, 0, Key == VK_UP ? updUp : updDown); + Key = 0; + } } //--------------------------------------------------------------------------- - - +void __fastcall TMainForm::TimeIntChange(TObject *Sender) { UpdateEnable(); } +//--------------------------------------------------------------------------- diff --git a/app/winapp/rtkget/getmain.h b/app/winapp/rtkget/getmain.h index 6a886067d..1ba9e93a2 100644 --- a/app/winapp/rtkget/getmain.h +++ b/app/winapp/rtkget/getmain.h @@ -2,14 +2,14 @@ #ifndef getmainH #define getmainH //--------------------------------------------------------------------------- -#include -#include -#include -#include #include +#include #include +#include #include #include +#include +#include #include #include #ifdef TCPP @@ -17,177 +17,175 @@ #else #include #endif -#include "viewer.h" #include "rtklib.h" +#include "viewer.h" //--------------------------------------------------------------------------- -class TMainForm : public TForm -{ -__published: - TPanel *Panel2; - TPanel *Panel3; - TPanel *Msg1; - TPanel *Msg3; - TButton *BtnDir; - TListBox *DataList; - TComboBox *DataType; - TPanel *Msg2; - TLabel *LabelSta; - TOpenDialog *OpenDialog; - TListBox *StaList; - TPanel *Panel4; - TLabel *Label4; - TEdit *FtpLogin; - TEdit *FtpPasswd; - TLabel *Label8; - TSaveDialog *SaveDialog; - TButton *BtnStas; - TCheckBox *HidePasswd; - TTimer *Timer; - TImage *Image1; - TImage *Image2; - TImage *Image3; - TImage *Image4; - TTrayIcon *TrayIcon; - TComboBox *SubType; - TSpeedButton *BtnTray; - TSpeedButton *BtnHelp; - TImage *Image5; - TImage *Image6; - TImage *Image7; - TImage *Image8; - TButton *BtnAll; - TComboBox *Dir; - TLabel *MsgLabel2; - TLabel *MsgLabel1; - TLabel *MsgLabel3; - TButton *BtnFile; - TButton *BtnLog; - TButton *BtnOpts; - TButton *BtnTest; - TButton *BtnDownload; - TButton *BtnExit; - TPanel *Panel5; - TPanel *Panel6; - TPanel *Panel7; - TPanel *Panel8; - TPanel *Panel9; - TPanel *Panel10; - TPanel *Panel11; - TPanel *Panel12; - TLabel *Label1; - TEdit *TimeY1; - TUpDown *TimeY1UD; - TEdit *TimeH1; - TUpDown *TimeH1UD; - TSpeedButton *BtnTime1; - TPanel *Panel13; - TLabel *Label3; - TEdit *TimeY2; - TUpDown *TimeY2UD; - TEdit *TimeH2; - TUpDown *TimeH2UD; - TSpeedButton *BtnTime2; - TPanel *Panel14; - TLabel *Label7; - TComboBox *TimeInt; - TEdit *Number; - TLabel *Label2; - TPanel *Panel15; - TPanel *Panel1; - TCheckBox *SkipExist; - TCheckBox *UnZip; - TCheckBox *LocalDir; - TSpeedButton *BtnKeyword; - TPanel *Panel16; - TPanel *Panel17; - TPanel *Panel18; - - void __fastcall TimeY1UDChangingEx(TObject *Sender, bool &AllowChange, - int NewValue, TUpDownDirection Direction); - void __fastcall TimeH1UDChangingEx(TObject *Sender, bool &AllowChange, - int NewValue, TUpDownDirection Direction); - void __fastcall TimeY2UDChangingEx(TObject *Sender, bool &AllowChange, - int NewValue, TUpDownDirection Direction); - void __fastcall TimeH2UDChangingEx(TObject *Sender, bool &AllowChange, - int NewValue, TUpDownDirection Direction); - void __fastcall BtnExitClick(TObject *Sender); - void __fastcall BtnOptsClick(TObject *Sender); - void __fastcall BtnLogClick(TObject *Sender); - void __fastcall BtnDownloadClick(TObject *Sender); - void __fastcall DataTypeChange(TObject *Sender); - void __fastcall FormShow(TObject *Sender); - void __fastcall FormClose(TObject *Sender, TCloseAction &Action); - void __fastcall BtnFileClick(TObject *Sender); - void __fastcall DataListClick(TObject *Sender); - void __fastcall BtnDirClick(TObject *Sender); - void __fastcall LocalDirClick(TObject *Sender); - void __fastcall BtnStasClick(TObject *Sender); - void __fastcall BtnTime1Click(TObject *Sender); - void __fastcall BtnTime2Click(TObject *Sender); - void __fastcall BtnKeywordClick(TObject *Sender); - void __fastcall BtnHelpClick(TObject *Sender); - void __fastcall HidePasswdClick(TObject *Sender); - void __fastcall TimerTimer(TObject *Sender); - void __fastcall BtnTrayClick(TObject *Sender); - void __fastcall TrayIconDblClick(TObject *Sender); - void __fastcall BtnTestClick(TObject *Sender); - void __fastcall StaListClick(TObject *Sender); - void __fastcall FormCreate(TObject *Sender); - void __fastcall BtnAllClick(TObject *Sender); - void __fastcall DirChange(TObject *Sender); - void __fastcall Panel3Resize(TObject *Sender); - void __fastcall Panel2Resize(TObject *Sender); - void __fastcall Panel6Resize(TObject *Sender); - void __fastcall ComboCloseUp(TObject *Sender); - void __fastcall TimeY1KeyDown(TObject *Sender, WORD &Key, TShiftState Shift); - void __fastcall TimeH1KeyDown(TObject *Sender, WORD &Key, TShiftState Shift); - void __fastcall TimeH2KeyDown(TObject *Sender, WORD &Key, TShiftState Shift); - void __fastcall TimeY2KeyDown(TObject *Sender, WORD &Key, TShiftState Shift); - void __fastcall TimeIntChange(TObject *Sender); - -private: - TTextViewer *LogViewer; - TStringList *Types; - TStringList *Urls; - TStringList *Locals; - - void __fastcall DropFiles(TWMDropFiles msg); - void __fastcall LoadOpt(void); - void __fastcall SaveOpt(void); - void __fastcall UpdateType(void); - void __fastcall UpdateMsg(void); - void __fastcall UpdateStaList(void); - void __fastcall UpdateEnable(void); - void __fastcall PanelEnable(int ena); - void __fastcall GetTime(gtime_t *ts, gtime_t *te, double *ti); - int __fastcall SelectUrl(url_t *urls); - int __fastcall SelectSta(char **stas); - void __fastcall LoadUrl(AnsiString file); - void __fastcall LoadSta(AnsiString file); - int __fastcall ExecCmd(AnsiString cmd); - void __fastcall ReadHist(TIniFile *ini, AnsiString key, TStrings *list); - void __fastcall WriteHist(TIniFile *ini, AnsiString key, TStrings *list); - void __fastcall AddHist(TComboBox *combo); - - BEGIN_MESSAGE_MAP - MESSAGE_HANDLER(WM_DROPFILES,TWMDropFiles,DropFiles); - END_MESSAGE_MAP(TForm); - -public: - AnsiString IniFile; - AnsiString UrlFile; - AnsiString LogFile; - AnsiString Stations; - AnsiString ProxyAddr; - int HoldErr; - int HoldList; - int NCol; - int DateFormat; - int TraceLevel; - int LogAppend; - int TimerCnt; - __fastcall TMainForm(TComponent* Owner); +class TMainForm : public TForm { + __published : TPanel *Panel2; + TPanel *Panel3; + TPanel *Msg1; + TPanel *Msg3; + TButton *BtnDir; + TListBox *DataList; + TComboBox *DataType; + TPanel *Msg2; + TLabel *LabelSta; + TOpenDialog *OpenDialog; + TListBox *StaList; + TPanel *Panel4; + TLabel *Label4; + TEdit *FtpLogin; + TEdit *FtpPasswd; + TLabel *Label8; + TSaveDialog *SaveDialog; + TButton *BtnStas; + TCheckBox *HidePasswd; + TTimer *Timer; + TImage *Image1; + TImage *Image2; + TImage *Image3; + TImage *Image4; + TTrayIcon *TrayIcon; + TComboBox *SubType; + TSpeedButton *BtnTray; + TSpeedButton *BtnHelp; + TImage *Image5; + TImage *Image6; + TImage *Image7; + TImage *Image8; + TButton *BtnAll; + TComboBox *Dir; + TLabel *MsgLabel2; + TLabel *MsgLabel1; + TLabel *MsgLabel3; + TButton *BtnFile; + TButton *BtnLog; + TButton *BtnOpts; + TButton *BtnTest; + TButton *BtnDownload; + TButton *BtnExit; + TPanel *Panel5; + TPanel *Panel6; + TPanel *Panel7; + TPanel *Panel8; + TPanel *Panel9; + TPanel *Panel10; + TPanel *Panel11; + TPanel *Panel12; + TLabel *Label1; + TEdit *TimeY1; + TUpDown *TimeY1UD; + TEdit *TimeH1; + TUpDown *TimeH1UD; + TSpeedButton *BtnTime1; + TPanel *Panel13; + TLabel *Label3; + TEdit *TimeY2; + TUpDown *TimeY2UD; + TEdit *TimeH2; + TUpDown *TimeH2UD; + TSpeedButton *BtnTime2; + TPanel *Panel14; + TLabel *Label7; + TComboBox *TimeInt; + TEdit *Number; + TLabel *Label2; + TPanel *Panel15; + TPanel *Panel1; + TCheckBox *SkipExist; + TCheckBox *UnZip; + TCheckBox *LocalDir; + TSpeedButton *BtnKeyword; + TPanel *Panel16; + TPanel *Panel17; + TPanel *Panel18; + + void __fastcall TimeY1UDChangingEx(TObject *Sender, bool &AllowChange, int NewValue, + TUpDownDirection Direction); + void __fastcall TimeH1UDChangingEx(TObject *Sender, bool &AllowChange, int NewValue, + TUpDownDirection Direction); + void __fastcall TimeY2UDChangingEx(TObject *Sender, bool &AllowChange, int NewValue, + TUpDownDirection Direction); + void __fastcall TimeH2UDChangingEx(TObject *Sender, bool &AllowChange, int NewValue, + TUpDownDirection Direction); + void __fastcall BtnExitClick(TObject *Sender); + void __fastcall BtnOptsClick(TObject *Sender); + void __fastcall BtnLogClick(TObject *Sender); + void __fastcall BtnDownloadClick(TObject *Sender); + void __fastcall DataTypeChange(TObject *Sender); + void __fastcall FormShow(TObject *Sender); + void __fastcall FormClose(TObject *Sender, TCloseAction &Action); + void __fastcall BtnFileClick(TObject *Sender); + void __fastcall DataListClick(TObject *Sender); + void __fastcall BtnDirClick(TObject *Sender); + void __fastcall LocalDirClick(TObject *Sender); + void __fastcall BtnStasClick(TObject *Sender); + void __fastcall BtnTime1Click(TObject *Sender); + void __fastcall BtnTime2Click(TObject *Sender); + void __fastcall BtnKeywordClick(TObject *Sender); + void __fastcall BtnHelpClick(TObject *Sender); + void __fastcall HidePasswdClick(TObject *Sender); + void __fastcall TimerTimer(TObject *Sender); + void __fastcall BtnTrayClick(TObject *Sender); + void __fastcall TrayIconDblClick(TObject *Sender); + void __fastcall BtnTestClick(TObject *Sender); + void __fastcall StaListClick(TObject *Sender); + void __fastcall FormCreate(TObject *Sender); + void __fastcall BtnAllClick(TObject *Sender); + void __fastcall DirChange(TObject *Sender); + void __fastcall Panel3Resize(TObject *Sender); + void __fastcall Panel2Resize(TObject *Sender); + void __fastcall Panel6Resize(TObject *Sender); + void __fastcall ComboCloseUp(TObject *Sender); + void __fastcall TimeY1KeyDown(TObject *Sender, WORD &Key, TShiftState Shift); + void __fastcall TimeH1KeyDown(TObject *Sender, WORD &Key, TShiftState Shift); + void __fastcall TimeH2KeyDown(TObject *Sender, WORD &Key, TShiftState Shift); + void __fastcall TimeY2KeyDown(TObject *Sender, WORD &Key, TShiftState Shift); + void __fastcall TimeIntChange(TObject *Sender); + + private: + TTextViewer *LogViewer; + TStringList *Types; + TStringList *Urls; + TStringList *Locals; + + void __fastcall DropFiles(TWMDropFiles msg); + void __fastcall LoadOpt(void); + void __fastcall SaveOpt(void); + void __fastcall UpdateType(void); + void __fastcall UpdateMsg(void); + void __fastcall UpdateStaList(void); + void __fastcall UpdateEnable(void); + void __fastcall PanelEnable(int ena); + void __fastcall GetTime(gtime_t *ts, gtime_t *te, double *ti); + int __fastcall SelectUrl(url_t *urls); + int __fastcall SelectSta(char **stas); + void __fastcall LoadUrl(AnsiString file); + void __fastcall LoadSta(AnsiString file); + int __fastcall ExecCmd(AnsiString cmd); + void __fastcall ReadHist(TIniFile *ini, AnsiString key, TStrings *list); + void __fastcall WriteHist(TIniFile *ini, AnsiString key, TStrings *list); + void __fastcall AddHist(TComboBox *combo); + + BEGIN_MESSAGE_MAP + MESSAGE_HANDLER(WM_DROPFILES, TWMDropFiles, DropFiles); + END_MESSAGE_MAP(TForm); + + public: + AnsiString IniFile; + AnsiString UrlFile; + AnsiString LogFile; + AnsiString Stations; + AnsiString ProxyAddr; + int HoldErr; + int HoldList; + int NCol; + int DateFormat; + int TraceLevel; + int LogAppend; + int TimerCnt; + __fastcall TMainForm(TComponent *Owner); }; //--------------------------------------------------------------------------- extern PACKAGE TMainForm *MainForm; diff --git a/app/winapp/rtkget/getoptdlg.cpp b/app/winapp/rtkget/getoptdlg.cpp index 32e5d30e7..472647dd6 100644 --- a/app/winapp/rtkget/getoptdlg.cpp +++ b/app/winapp/rtkget/getoptdlg.cpp @@ -3,57 +3,50 @@ #pragma hdrstop #include "getoptdlg.h" + #include "getmain.h" //--------------------------------------------------------------------------- #pragma package(smart_init) #pragma resource "*.dfm" TDownOptDialog *DownOptDialog; //--------------------------------------------------------------------------- -__fastcall TDownOptDialog::TDownOptDialog(TComponent* Owner) - : TForm(Owner) -{ -} +__fastcall TDownOptDialog::TDownOptDialog(TComponent *Owner) : TForm(Owner) {} //--------------------------------------------------------------------------- -void __fastcall TDownOptDialog::BtnUrlFileClick(TObject *Sender) -{ - OpenDialog->Title="GNSS Data URL File"; - OpenDialog->FileName=""; - if (!OpenDialog->Execute()) return; - UrlFile->Text=OpenDialog->FileName; +void __fastcall TDownOptDialog::BtnUrlFileClick(TObject *Sender) { + OpenDialog->Title = "GNSS Data URL File"; + OpenDialog->FileName = ""; + if (!OpenDialog->Execute()) return; + UrlFile->Text = OpenDialog->FileName; } //--------------------------------------------------------------------------- -void __fastcall TDownOptDialog::BtnLogFileClick(TObject *Sender) -{ - SaveDialog->Title="Download Log File"; - SaveDialog->FileName=""; - if (!SaveDialog->Execute()) return; - LogFile->Text=SaveDialog->FileName; +void __fastcall TDownOptDialog::BtnLogFileClick(TObject *Sender) { + SaveDialog->Title = "Download Log File"; + SaveDialog->FileName = ""; + if (!SaveDialog->Execute()) return; + LogFile->Text = SaveDialog->FileName; } //--------------------------------------------------------------------------- -void __fastcall TDownOptDialog::FormShow(TObject *Sender) -{ - HoldErr ->Checked=MainForm->HoldErr; - HoldList ->Checked=MainForm->HoldList; - NCol ->Text =UnicodeString(MainForm->NCol); - Proxy ->Text =MainForm->ProxyAddr; - UrlFile ->Text =MainForm->UrlFile; - LogFile ->Text =MainForm->LogFile; - LogAppend->Checked=MainForm->LogAppend; - DateFormat->ItemIndex=MainForm->DateFormat; - TraceLevel->ItemIndex=MainForm->TraceLevel; +void __fastcall TDownOptDialog::FormShow(TObject *Sender) { + HoldErr->Checked = MainForm->HoldErr; + HoldList->Checked = MainForm->HoldList; + NCol->Text = UnicodeString(MainForm->NCol); + Proxy->Text = MainForm->ProxyAddr; + UrlFile->Text = MainForm->UrlFile; + LogFile->Text = MainForm->LogFile; + LogAppend->Checked = MainForm->LogAppend; + DateFormat->ItemIndex = MainForm->DateFormat; + TraceLevel->ItemIndex = MainForm->TraceLevel; } //--------------------------------------------------------------------------- -void __fastcall TDownOptDialog::BtnOkClick(TObject *Sender) -{ - MainForm->HoldErr =HoldErr ->Checked; - MainForm->HoldList =HoldList ->Checked; - MainForm->NCol =NCol ->Text.ToInt(); - MainForm->ProxyAddr=Proxy ->Text; - MainForm->UrlFile =UrlFile ->Text; - MainForm->LogFile =LogFile ->Text; - MainForm->LogAppend=LogAppend->Checked; - MainForm->DateFormat=DateFormat->ItemIndex; - MainForm->TraceLevel=TraceLevel->ItemIndex; +void __fastcall TDownOptDialog::BtnOkClick(TObject *Sender) { + MainForm->HoldErr = HoldErr->Checked; + MainForm->HoldList = HoldList->Checked; + MainForm->NCol = NCol->Text.ToInt(); + MainForm->ProxyAddr = Proxy->Text; + MainForm->UrlFile = UrlFile->Text; + MainForm->LogFile = LogFile->Text; + MainForm->LogAppend = LogAppend->Checked; + MainForm->DateFormat = DateFormat->ItemIndex; + MainForm->TraceLevel = TraceLevel->ItemIndex; } //--------------------------------------------------------------------------- - diff --git a/app/winapp/rtkget/getoptdlg.h b/app/winapp/rtkget/getoptdlg.h index fdf8d4381..fd236453c 100644 --- a/app/winapp/rtkget/getoptdlg.h +++ b/app/winapp/rtkget/getoptdlg.h @@ -4,43 +4,42 @@ //--------------------------------------------------------------------------- #include #include -#include -#include -#include #include +#include +#include +#include //--------------------------------------------------------------------------- -class TDownOptDialog : public TForm -{ -__published: - TButton *BtnOk; - TButton *BtnCancel; - TPanel *Panel1; - TEdit *Proxy; - TEdit *UrlFile; - TButton *BtnUrlFile; - TLabel *Label1; - TOpenDialog *OpenDialog; - TLabel *Label2; - TComboBox *TraceLevel; - TLabel *Label3; - TLabel *Label4; - TEdit *LogFile; - TButton *BtnLogFile; - TCheckBox *LogAppend; - TSaveDialog *SaveDialog; - TCheckBox *HoldErr; - TCheckBox *HoldList; - TLabel *Label5; - TComboBox *DateFormat; - TLabel *Label6; - TEdit *NCol; - void __fastcall FormShow(TObject *Sender); - void __fastcall BtnOkClick(TObject *Sender); - void __fastcall BtnUrlFileClick(TObject *Sender); - void __fastcall BtnLogFileClick(TObject *Sender); -private: -public: - __fastcall TDownOptDialog(TComponent* Owner); +class TDownOptDialog : public TForm { + __published : TButton *BtnOk; + TButton *BtnCancel; + TPanel *Panel1; + TEdit *Proxy; + TEdit *UrlFile; + TButton *BtnUrlFile; + TLabel *Label1; + TOpenDialog *OpenDialog; + TLabel *Label2; + TComboBox *TraceLevel; + TLabel *Label3; + TLabel *Label4; + TEdit *LogFile; + TButton *BtnLogFile; + TCheckBox *LogAppend; + TSaveDialog *SaveDialog; + TCheckBox *HoldErr; + TCheckBox *HoldList; + TLabel *Label5; + TComboBox *DateFormat; + TLabel *Label6; + TEdit *NCol; + void __fastcall FormShow(TObject *Sender); + void __fastcall BtnOkClick(TObject *Sender); + void __fastcall BtnUrlFileClick(TObject *Sender); + void __fastcall BtnLogFileClick(TObject *Sender); + + private: + public: + __fastcall TDownOptDialog(TComponent *Owner); }; //--------------------------------------------------------------------------- extern PACKAGE TDownOptDialog *DownOptDialog; diff --git a/app/winapp/rtkget/rtkget.cpp b/app/winapp/rtkget/rtkget.cpp index 9147407d0..1710996ce 100644 --- a/app/winapp/rtkget/rtkget.cpp +++ b/app/winapp/rtkget/rtkget.cpp @@ -4,22 +4,6 @@ #pragma hdrstop //--------------------------------------------------------------------------- - - - - - - - - - - - - - - - - USEFORM("staoptdlg.cpp", StaListDialog); USEFORM("getoptdlg.cpp", DownOptDialog); USEFORM("..\appcmn\timedlg.cpp", TimeDialog); @@ -29,36 +13,27 @@ USEFORM("getmain.cpp", MainForm); USEFORM("..\appcmn\vieweropt.cpp", ViewerOptDialog); USEFORM("..\appcmn\viewer.cpp", TextViewer); //--------------------------------------------------------------------------- -int WINAPI WinMain(HINSTANCE, HINSTANCE, LPSTR, int) -{ - try - { - Application->Initialize(); - Application->CreateForm(__classid(TMainForm), &MainForm); - Application->CreateForm(__classid(TDownOptDialog), &DownOptDialog); - Application->CreateForm(__classid(TTimeDialog), &TimeDialog); - Application->CreateForm(__classid(TKeyDialog), &KeyDialog); - Application->CreateForm(__classid(TAboutDialog), &AboutDialog); - Application->CreateForm(__classid(TTextViewer), &TextViewer); - Application->CreateForm(__classid(TViewerOptDialog), &ViewerOptDialog); - Application->CreateForm(__classid(TStaListDialog), &StaListDialog); - Application->Run(); - } - catch (Exception &exception) - { - Application->ShowException(&exception); - } - catch (...) - { - try - { - throw Exception(""); - } - catch (Exception &exception) - { - Application->ShowException(&exception); - } - } - return 0; +int WINAPI WinMain(HINSTANCE, HINSTANCE, LPSTR, int) { + try { + Application->Initialize(); + Application->CreateForm(__classid(TMainForm), &MainForm); + Application->CreateForm(__classid(TDownOptDialog), &DownOptDialog); + Application->CreateForm(__classid(TTimeDialog), &TimeDialog); + Application->CreateForm(__classid(TKeyDialog), &KeyDialog); + Application->CreateForm(__classid(TAboutDialog), &AboutDialog); + Application->CreateForm(__classid(TTextViewer), &TextViewer); + Application->CreateForm(__classid(TViewerOptDialog), &ViewerOptDialog); + Application->CreateForm(__classid(TStaListDialog), &StaListDialog); + Application->Run(); + } catch (Exception &exception) { + Application->ShowException(&exception); + } catch (...) { + try { + throw Exception(""); + } catch (Exception &exception) { + Application->ShowException(&exception); + } + } + return 0; } //--------------------------------------------------------------------------- diff --git a/app/winapp/rtkget/staoptdlg.cpp b/app/winapp/rtkget/staoptdlg.cpp index 7a727da48..17f5fcab5 100644 --- a/app/winapp/rtkget/staoptdlg.cpp +++ b/app/winapp/rtkget/staoptdlg.cpp @@ -2,65 +2,58 @@ #include #pragma hdrstop -#include "getmain.h" #include "staoptdlg.h" + +#include "getmain.h" //--------------------------------------------------------------------------- #pragma package(smart_init) #pragma resource "*.dfm" TStaListDialog *StaListDialog; //--------------------------------------------------------------------------- -__fastcall TStaListDialog::TStaListDialog(TComponent* Owner) - : TForm(Owner) -{ -} +__fastcall TStaListDialog::TStaListDialog(TComponent *Owner) : TForm(Owner) {} //--------------------------------------------------------------------------- -void __fastcall TStaListDialog::FormShow(TObject *Sender) -{ - StaList->Clear(); - - for (int i=0;iStaList->Items->Count;i++) { - StaList->Lines->Add(MainForm->StaList->Items->Strings[i]); - } +void __fastcall TStaListDialog::FormShow(TObject *Sender) { + StaList->Clear(); + + for (int i = 0; i < MainForm->StaList->Items->Count; i++) { + StaList->Lines->Add(MainForm->StaList->Items->Strings[i]); + } } //--------------------------------------------------------------------------- -void __fastcall TStaListDialog::BtnOkClick(TObject *Sender) -{ - MainForm->StaList->Clear(); - - for (int i=0;iLines->Count;i++) { - MainForm->StaList->Items->Add(StaList->Lines->Strings[i]); - } +void __fastcall TStaListDialog::BtnOkClick(TObject *Sender) { + MainForm->StaList->Clear(); + + for (int i = 0; i < StaList->Lines->Count; i++) { + MainForm->StaList->Items->Add(StaList->Lines->Strings[i]); + } } //--------------------------------------------------------------------------- -void __fastcall TStaListDialog::BtnLoadClick(TObject *Sender) -{ - AnsiString file; - FILE *fp; - char buff[1024],*p; - - if (!OpenDialog->Execute()) return; - - file=OpenDialog->FileName; - - if (!(fp=fopen(file.c_str(),"r"))) return; - - StaList->Clear(); - StaList->Visible=false; - - while (fgets(buff,sizeof(buff),fp)) { - if ((p=strchr(buff,'#'))) *p='\0'; - for (p=strtok(buff," ,\r\n");p;p=strtok(NULL," ,\r\n")) { - StaList->Lines->Add(p); - } +void __fastcall TStaListDialog::BtnLoadClick(TObject *Sender) { + AnsiString file; + FILE *fp; + char buff[1024], *p; + + if (!OpenDialog->Execute()) return; + + file = OpenDialog->FileName; + + if (!(fp = fopen(file.c_str(), "r"))) return; + + StaList->Clear(); + StaList->Visible = false; + + while (fgets(buff, sizeof(buff), fp)) { + if ((p = strchr(buff, '#'))) *p = '\0'; + for (p = strtok(buff, " ,\r\n"); p; p = strtok(NULL, " ,\r\n")) { + StaList->Lines->Add(p); } - fclose(fp); - StaList->Visible=true; + } + fclose(fp); + StaList->Visible = true; } //--------------------------------------------------------------------------- -void __fastcall TStaListDialog::BtnSaveClick(TObject *Sender) -{ - if (!SaveDialog->Execute()) return; - StaList->Lines->SaveToFile(SaveDialog->FileName); +void __fastcall TStaListDialog::BtnSaveClick(TObject *Sender) { + if (!SaveDialog->Execute()) return; + StaList->Lines->SaveToFile(SaveDialog->FileName); } //--------------------------------------------------------------------------- - diff --git a/app/winapp/rtkget/staoptdlg.h b/app/winapp/rtkget/staoptdlg.h index 1d8633237..898867714 100644 --- a/app/winapp/rtkget/staoptdlg.h +++ b/app/winapp/rtkget/staoptdlg.h @@ -4,29 +4,28 @@ //--------------------------------------------------------------------------- #include #include -#include -#include -#include #include +#include +#include +#include //--------------------------------------------------------------------------- -class TStaListDialog : public TForm -{ -__published: - TPanel *Panel1; - TButton *BtnLoad; - TButton *BtnSave; - TButton *BtnOk; - TButton *BtnCancel; - TMemo *StaList; - TOpenDialog *OpenDialog; - TSaveDialog *SaveDialog; - void __fastcall BtnLoadClick(TObject *Sender); - void __fastcall BtnOkClick(TObject *Sender); - void __fastcall FormShow(TObject *Sender); - void __fastcall BtnSaveClick(TObject *Sender); -private: -public: - __fastcall TStaListDialog(TComponent* Owner); +class TStaListDialog : public TForm { + __published : TPanel *Panel1; + TButton *BtnLoad; + TButton *BtnSave; + TButton *BtnOk; + TButton *BtnCancel; + TMemo *StaList; + TOpenDialog *OpenDialog; + TSaveDialog *SaveDialog; + void __fastcall BtnLoadClick(TObject *Sender); + void __fastcall BtnOkClick(TObject *Sender); + void __fastcall FormShow(TObject *Sender); + void __fastcall BtnSaveClick(TObject *Sender); + + private: + public: + __fastcall TStaListDialog(TComponent *Owner); }; //--------------------------------------------------------------------------- extern PACKAGE TStaListDialog *StaListDialog; diff --git a/app/winapp/rtklaunch/launchmain.cpp b/app/winapp/rtklaunch/launchmain.cpp index 87a9a6aa3..5fab0a058 100644 --- a/app/winapp/rtklaunch/launchmain.cpp +++ b/app/winapp/rtklaunch/launchmain.cpp @@ -19,274 +19,233 @@ // add commandline option -trace //--------------------------------------------------------------------------- #include + #include #pragma hdrstop -#include "rtklib.h" #include "launchmain.h" + #include "launchoptdlg.h" +#include "rtklib.h" //--------------------------------------------------------------------------- #pragma package(smart_init) #pragma resource "*.dfm" TMainForm *MainForm; -#define BTN_SIZE 42 -#define BTN_COUNT 7 -#define MAX(x,y) ((x)>(y)?(x):(y)) -#define TRACE_FILE "rtklaunch.trace" +#define BTN_SIZE 42 +#define BTN_COUNT 7 +#define MAX(x, y) ((x) > (y) ? (x) : (y)) +#define TRACE_FILE "rtklaunch.trace" //--------------------------------------------------------------------------- -__fastcall TMainForm::TMainForm(TComponent* Owner) - : TForm(Owner) -{ - char file[1024]="rtklaunch.exe",buff[1024],*argv[32],*p; - int i,argc=0,tray=0; - - ::GetModuleFileName(NULL,file,sizeof(file)); - if (!(p=strrchr(file,'.'))) p=file+strlen(file); - strcpy(p,".ini"); - IniFile=file; - Option=0; - Minimize=0; - Trace=0; - - TIniFile *ini=new TIniFile(IniFile); - Left =ini->ReadInteger("pos","left", 0); - Top =ini->ReadInteger("pos","top", 0); - Width =ini->ReadInteger("pos","width", 310); - Height=ini->ReadInteger("pos","height", 79); - Option=ini->ReadInteger("pos","option", 0); - Minimize=ini->ReadInteger("pos","minimize",0); - delete ini; - - // move window inside main-screen - TRect rect; - ::SystemParametersInfo(SPI_GETWORKAREA,0,&rect,0); - if (Top<0) Top=0; - if (Top+Height>rect.Height()) Top=rect.Height()-Height; - if (Left<0) Left=0; - if (Left+Width>rect.Width()) Left=rect.Width()-Width; +__fastcall TMainForm::TMainForm(TComponent *Owner) : TForm(Owner) { + char file[1024] = "rtklaunch.exe", buff[1024], *argv[32], *p; + int i, argc = 0, tray = 0; - Caption="RTKLIB-" VER_RTKLIB " " PATCH_LEVEL; - BtnRtklib->Hint="RTKLIB-" VER_RTKLIB " " PATCH_LEVEL; - TrayIcon->Hint=Caption; - Panel1->Constraints->MinWidth=BTN_SIZE+2; - Panel1->Constraints->MaxWidth=BTN_SIZE*BTN_COUNT+2; - - strcpy(buff,GetCommandLine()); - for (p=strtok(buff," ");p&&argc<32;p=strtok(NULL," ")) { - argv[argc++]=p; - } - for (i=1;i=1) { - traceopen(TRACE_FILE); - tracelevel(Trace); - } - UpdatePanel(); - - if (tray) { - Application->ShowMainForm=false; - TrayIcon->Visible=true; - } - trace(2,"screen: width=%d height=%d\n",rect.Width(),rect.Height()); - trace(2,"window: left=%d top=%d width=%d height=%d\n",Left,Top,Width,Height); -} -//--------------------------------------------------------------------------- -void __fastcall TMainForm::FormClose(TObject *Sender, TCloseAction &Action) -{ - TIniFile *ini=new TIniFile(IniFile); - ini->WriteInteger("pos","left", Left); - ini->WriteInteger("pos","top", Top); - ini->WriteInteger("pos","width", Width); - ini->WriteInteger("pos","height",Height); - ini->WriteInteger("pos","option",Option); - ini->WriteInteger("pos","minimize",Minimize); - delete ini; + ::GetModuleFileName(NULL, file, sizeof(file)); + if (!(p = strrchr(file, '.'))) p = file + strlen(file); + strcpy(p, ".ini"); + IniFile = file; + Option = 0; + Minimize = 0; + Trace = 0; - if (Trace>=1) { - traceclose(); - } + TIniFile *ini = new TIniFile(IniFile); + Left = ini->ReadInteger("pos", "left", 0); + Top = ini->ReadInteger("pos", "top", 0); + Width = ini->ReadInteger("pos", "width", 310); + Height = ini->ReadInteger("pos", "height", 79); + Option = ini->ReadInteger("pos", "option", 0); + Minimize = ini->ReadInteger("pos", "minimize", 0); + delete ini; + + // move window inside main-screen + TRect rect; + ::SystemParametersInfo(SPI_GETWORKAREA, 0, &rect, 0); + if (Top < 0) Top = 0; + if (Top + Height > rect.Height()) Top = rect.Height() - Height; + if (Left < 0) Left = 0; + if (Left + Width > rect.Width()) Left = rect.Width() - Width; + + Caption = "RTKLIB-" VER_RTKLIB " " PATCH_LEVEL; + BtnRtklib->Hint = "RTKLIB-" VER_RTKLIB " " PATCH_LEVEL; + TrayIcon->Hint = Caption; + Panel1->Constraints->MinWidth = BTN_SIZE + 2; + Panel1->Constraints->MaxWidth = BTN_SIZE * BTN_COUNT + 2; + + strcpy(buff, GetCommandLine()); + for (p = strtok(buff, " "); p && argc < 32; p = strtok(NULL, " ")) { + argv[argc++] = p; + } + for (i = 1; i < argc; i++) { + if (!strcmp(argv[i], "-t") && i + 1 < argc) + Caption = argv[++i]; + else if (!strcmp(argv[i], "-tray")) + tray = 1; + else if (!strcmp(argv[i], "-min")) + Minimize = 1; + else if (!strcmp(argv[i], "-trace") && i + 1 < argc) + Trace = atoi(argv[++i]); + } + if (Trace >= 1) { + traceopen(TRACE_FILE); + tracelevel(Trace); + } + UpdatePanel(); + + if (tray) { + Application->ShowMainForm = false; + TrayIcon->Visible = true; + } + trace(2, "screen: width=%d height=%d\n", rect.Width(), rect.Height()); + trace(2, "window: left=%d top=%d width=%d height=%d\n", Left, Top, Width, Height); +} +//--------------------------------------------------------------------------- +void __fastcall TMainForm::FormClose(TObject *Sender, TCloseAction &Action) { + TIniFile *ini = new TIniFile(IniFile); + ini->WriteInteger("pos", "left", Left); + ini->WriteInteger("pos", "top", Top); + ini->WriteInteger("pos", "width", Width); + ini->WriteInteger("pos", "height", Height); + ini->WriteInteger("pos", "option", Option); + ini->WriteInteger("pos", "minimize", Minimize); + delete ini; + + if (Trace >= 1) { + traceclose(); + } } //--------------------------------------------------------------------------- -void __fastcall TMainForm::BtnPlotClick(TObject *Sender) -{ - UnicodeString cmd1="rtkplot",cmd2="..\\..\\..\\bin\\rtkplot",opts=""; - - if (!ExecCmd(cmd1+opts)) ExecCmd(cmd2+opts); +void __fastcall TMainForm::BtnPlotClick(TObject *Sender) { + UnicodeString cmd1 = "rtkplot", cmd2 = "..\\..\\..\\bin\\rtkplot", opts = ""; + + if (!ExecCmd(cmd1 + opts)) ExecCmd(cmd2 + opts); } //--------------------------------------------------------------------------- -void __fastcall TMainForm::BtnConvClick(TObject *Sender) -{ - UnicodeString cmd1="rtkconv",cmd2="..\\..\\..\\bin\\rtkconv",opts=""; - - if (!ExecCmd(cmd1+opts)) ExecCmd(cmd2+opts); +void __fastcall TMainForm::BtnConvClick(TObject *Sender) { + UnicodeString cmd1 = "rtkconv", cmd2 = "..\\..\\..\\bin\\rtkconv", opts = ""; + + if (!ExecCmd(cmd1 + opts)) ExecCmd(cmd2 + opts); } //--------------------------------------------------------------------------- -void __fastcall TMainForm::BtnStrClick(TObject *Sender) -{ - UnicodeString cmd1="strsvr",cmd2="..\\..\\..\\bin\\strsvr",opts=""; - - if (!ExecCmd(cmd1+opts)) ExecCmd(cmd2+opts); +void __fastcall TMainForm::BtnStrClick(TObject *Sender) { + UnicodeString cmd1 = "strsvr", cmd2 = "..\\..\\..\\bin\\strsvr", opts = ""; + + if (!ExecCmd(cmd1 + opts)) ExecCmd(cmd2 + opts); } //--------------------------------------------------------------------------- -void __fastcall TMainForm::BtnPostClick(TObject *Sender) -{ - UnicodeString cmd1="rtkpost",cmd2="..\\..\\..\\bin\\rtkpost",opts=""; - - if (!ExecCmd(cmd1+opts)) ExecCmd(cmd2+opts); +void __fastcall TMainForm::BtnPostClick(TObject *Sender) { + UnicodeString cmd1 = "rtkpost", cmd2 = "..\\..\\..\\bin\\rtkpost", opts = ""; + + if (!ExecCmd(cmd1 + opts)) ExecCmd(cmd2 + opts); } //--------------------------------------------------------------------------- -void __fastcall TMainForm::BtnNtripClick(TObject *Sender) -{ - UnicodeString cmd1="srctblbrows",cmd2="..\\..\\..\\bin\\srctblbrows",opts=""; - - if (!ExecCmd(cmd1+opts)) ExecCmd(cmd2+opts); +void __fastcall TMainForm::BtnNtripClick(TObject *Sender) { + UnicodeString cmd1 = "srctblbrows", cmd2 = "..\\..\\..\\bin\\srctblbrows", opts = ""; + + if (!ExecCmd(cmd1 + opts)) ExecCmd(cmd2 + opts); } //--------------------------------------------------------------------------- -void __fastcall TMainForm::BtnNaviClick(TObject *Sender) -{ - UnicodeString cmd1="rtknavi",cmd2="..\\..\\..\\bin\\rtknavi",opts=""; - - if (!ExecCmd(cmd1+opts)) ExecCmd(cmd2+opts); +void __fastcall TMainForm::BtnNaviClick(TObject *Sender) { + UnicodeString cmd1 = "rtknavi", cmd2 = "..\\..\\..\\bin\\rtknavi", opts = ""; + + if (!ExecCmd(cmd1 + opts)) ExecCmd(cmd2 + opts); } //--------------------------------------------------------------------------- -void __fastcall TMainForm::BtnGetClick(TObject *Sender) -{ - UnicodeString cmd1="rtkget",cmd2="..\\..\\..\\bin\\rtkget",opts=""; - - if (!ExecCmd(cmd1+opts)) ExecCmd(cmd2+opts); +void __fastcall TMainForm::BtnGetClick(TObject *Sender) { + UnicodeString cmd1 = "rtkget", cmd2 = "..\\..\\..\\bin\\rtkget", opts = ""; + + if (!ExecCmd(cmd1 + opts)) ExecCmd(cmd2 + opts); } //--------------------------------------------------------------------------- -int __fastcall TMainForm::ExecCmd(AnsiString cmd) -{ - PROCESS_INFORMATION info; - STARTUPINFO si={0}; - si.cb=sizeof(si); - char *p=cmd.c_str(); - if (!CreateProcess(NULL,p,NULL,NULL,false,0,NULL,NULL,&si,&info)) return 0; - CloseHandle(info.hProcess); - CloseHandle(info.hThread); - return 1; +int __fastcall TMainForm::ExecCmd(AnsiString cmd) { + PROCESS_INFORMATION info; + STARTUPINFO si = {0}; + si.cb = sizeof(si); + char *p = cmd.c_str(); + if (!CreateProcess(NULL, p, NULL, NULL, false, 0, NULL, NULL, &si, &info)) return 0; + CloseHandle(info.hProcess); + CloseHandle(info.hThread); + return 1; } //--------------------------------------------------------------------------- -void __fastcall TMainForm::BtnTrayClick(TObject *Sender) -{ - Visible=false; - TrayIcon->Visible=true; +void __fastcall TMainForm::BtnTrayClick(TObject *Sender) { + Visible = false; + TrayIcon->Visible = true; } //--------------------------------------------------------------------------- -void __fastcall TMainForm::TrayIconDblClick(TObject *Sender) -{ - Visible=true; - TrayIcon->Visible=false; +void __fastcall TMainForm::TrayIconDblClick(TObject *Sender) { + Visible = true; + TrayIcon->Visible = false; } //--------------------------------------------------------------------------- -void __fastcall TMainForm::MenuExpandClick(TObject *Sender) -{ - Visible=true; - TrayIcon->Visible=false; - Minimize=0; - UpdatePanel(); +void __fastcall TMainForm::MenuExpandClick(TObject *Sender) { + Visible = true; + TrayIcon->Visible = false; + Minimize = 0; + UpdatePanel(); } //--------------------------------------------------------------------------- -void __fastcall TMainForm::MenuPlotClick(TObject *Sender) -{ - BtnPlotClick(Sender); -} +void __fastcall TMainForm::MenuPlotClick(TObject *Sender) { BtnPlotClick(Sender); } //--------------------------------------------------------------------------- -void __fastcall TMainForm::MenuConvClick(TObject *Sender) -{ - BtnConvClick(Sender); -} +void __fastcall TMainForm::MenuConvClick(TObject *Sender) { BtnConvClick(Sender); } //--------------------------------------------------------------------------- -void __fastcall TMainForm::MenuStrClick(TObject *Sender) -{ - BtnStrClick(Sender); -} +void __fastcall TMainForm::MenuStrClick(TObject *Sender) { BtnStrClick(Sender); } //--------------------------------------------------------------------------- -void __fastcall TMainForm::MenuPostClick(TObject *Sender) -{ - BtnPostClick(Sender); -} +void __fastcall TMainForm::MenuPostClick(TObject *Sender) { BtnPostClick(Sender); } //--------------------------------------------------------------------------- -void __fastcall TMainForm::MenuNtripClick(TObject *Sender) -{ - BtnNtripClick(Sender); -} +void __fastcall TMainForm::MenuNtripClick(TObject *Sender) { BtnNtripClick(Sender); } //--------------------------------------------------------------------------- -void __fastcall TMainForm::MenuNaviClick(TObject *Sender) -{ - BtnNaviClick(Sender); -} +void __fastcall TMainForm::MenuNaviClick(TObject *Sender) { BtnNaviClick(Sender); } //--------------------------------------------------------------------------- -void __fastcall TMainForm::MenuGetClick(TObject *Sender) -{ - BtnGetClick(Sender); -} +void __fastcall TMainForm::MenuGetClick(TObject *Sender) { BtnGetClick(Sender); } //--------------------------------------------------------------------------- -void __fastcall TMainForm::MenuExitClick(TObject *Sender) -{ - Close(); -} +void __fastcall TMainForm::MenuExitClick(TObject *Sender) { Close(); } //--------------------------------------------------------------------------- -void __fastcall TMainForm::Panel1Resize(TObject *Sender) -{ - TSpeedButton *btn[]={ - BtnPlot,BtnConv,BtnStr,BtnPost,BtnNtrip,BtnNavi,BtnGet - }; - int i,j,k,n,m,h; - int btn_size=BtnPlot->Width; +void __fastcall TMainForm::Panel1Resize(TObject *Sender) { + TSpeedButton *btn[] = {BtnPlot, BtnConv, BtnStr, BtnPost, BtnNtrip, BtnNavi, BtnGet}; + int i, j, k, n, m, h; + int btn_size = BtnPlot->Width; + + if (Minimize) return; + n = MAX(1, Panel1->ClientWidth / btn_size); + m = (BTN_COUNT - 1) / n + 1; + h = btn_size * m + 2; + Panel1->Constraints->MinHeight = h; + Panel1->Constraints->MaxHeight = h; + Panel1->Constraints->MinWidth = btn_size + 2; + Panel1->Constraints->MaxWidth = btn_size * BTN_COUNT + 2; - if (Minimize) return; - n=MAX(1,Panel1->ClientWidth/btn_size); - m=(BTN_COUNT-1)/n+1; - h=btn_size*m+2; - Panel1->Constraints->MinHeight=h; - Panel1->Constraints->MaxHeight=h; - Panel1->Constraints->MinWidth=btn_size+2; - Panel1->Constraints->MaxWidth=btn_size*BTN_COUNT+2; - - for (i=k=0;kTop =btn_size*i+1; - btn[k]->Left=btn_size*j+1; - btn[k]->Height=btn_size; - btn[k]->Width =btn_size; + for (i = k = 0; k < BTN_COUNT; i++) + for (j = 0; j < n && k < BTN_COUNT; j++, k++) { + btn[k]->Top = btn_size * i + 1; + btn[k]->Left = btn_size * j + 1; + btn[k]->Height = btn_size; + btn[k]->Width = btn_size; } - BtnTray->Left=Panel1->ClientWidth -BtnTray->Width; - BtnTray->Top =Panel1->ClientHeight-BtnTray->Height; + BtnTray->Left = Panel1->ClientWidth - BtnTray->Width; + BtnTray->Top = Panel1->ClientHeight - BtnTray->Height; } //--------------------------------------------------------------------------- -void __fastcall TMainForm::UpdatePanel(void) -{ - if (Minimize) { - BorderStyle=bsToolWindow; - Panel1->Visible=false; - Panel2->Visible=true; - AutoSize=true; - } - else { - BorderStyle=bsSizeToolWin; - Panel1->Visible=true; - Panel2->Visible=false; - AutoSize=false; - } +void __fastcall TMainForm::UpdatePanel(void) { + if (Minimize) { + BorderStyle = bsToolWindow; + Panel1->Visible = false; + Panel2->Visible = true; + AutoSize = true; + } else { + BorderStyle = bsSizeToolWin; + Panel1->Visible = true; + Panel2->Visible = false; + AutoSize = false; + } } //--------------------------------------------------------------------------- void __fastcall TMainForm::BtnRtklibMouseDown(TObject *Sender, TMouseButton Button, - TShiftState Shift, int X, int Y) -{ - PopupMenu->Popup(Left+X,Top+Y); + TShiftState Shift, int X, int Y) { + PopupMenu->Popup(Left + X, Top + Y); } //--------------------------------------------------------------------------- -void __fastcall TMainForm::BtnExitClick(TObject *Sender) -{ - Close(); -} +void __fastcall TMainForm::BtnExitClick(TObject *Sender) { Close(); } //--------------------------------------------------------------------------- - diff --git a/app/winapp/rtklaunch/launchmain.h b/app/winapp/rtklaunch/launchmain.h index 777809589..a6b2c417d 100644 --- a/app/winapp/rtklaunch/launchmain.h +++ b/app/winapp/rtklaunch/launchmain.h @@ -3,76 +3,75 @@ #define launchmainH //--------------------------------------------------------------------------- #include +#include #include -#include -#include #include +#include #include -#include #include +#include //--------------------------------------------------------------------------- -class TMainForm : public TForm -{ -__published: - TSpeedButton *BtnPlot; - TSpeedButton *BtnNavi; - TSpeedButton *BtnNtrip; - TSpeedButton *BtnPost; - TSpeedButton *BtnStr; - TSpeedButton *BtnConv; - TSpeedButton *BtnGet; - TTrayIcon *TrayIcon; - TPopupMenu *PopupMenu; - TMenuItem *MenuPlot; - TMenuItem *MenuConv; - TMenuItem *MenuStr; - TMenuItem *MenuPost; - TMenuItem *MenuNtrip; - TMenuItem *MenuNavi; - TMenuItem *MenuGet; - TMenuItem *N1; - TMenuItem *MenuExit; - TPanel *BtnTray; - TMenuItem *MenuExpand; - TMenuItem *N2; - TPanel *Panel1; - TSpeedButton *BtnRtklib; - TPanel *Panel2; - TPanel *BtnExit; - - void __fastcall BtnPlotClick(TObject *Sender); - void __fastcall BtnConvClick(TObject *Sender); - void __fastcall BtnStrClick(TObject *Sender); - void __fastcall BtnPostClick(TObject *Sender); - void __fastcall BtnNtripClick(TObject *Sender); - void __fastcall BtnNaviClick(TObject *Sender); - void __fastcall BtnGetClick(TObject *Sender); - void __fastcall FormClose(TObject *Sender, TCloseAction &Action); - void __fastcall BtnTrayClick(TObject *Sender); - void __fastcall TrayIconDblClick(TObject *Sender); - void __fastcall MenuPlotClick(TObject *Sender); - void __fastcall MenuConvClick(TObject *Sender); - void __fastcall MenuStrClick(TObject *Sender); - void __fastcall MenuPostClick(TObject *Sender); - void __fastcall MenuNtripClick(TObject *Sender); - void __fastcall MenuNaviClick(TObject *Sender); - void __fastcall MenuGetClick(TObject *Sender); - void __fastcall MenuExitClick(TObject *Sender); - void __fastcall MenuExpandClick(TObject *Sender); - void __fastcall Panel1Resize(TObject *Sender); - void __fastcall BtnRtklibMouseDown(TObject *Sender, TMouseButton Button, TShiftState Shift, - int X, int Y); - void __fastcall BtnExitClick(TObject *Sender); +class TMainForm : public TForm { + __published : TSpeedButton *BtnPlot; + TSpeedButton *BtnNavi; + TSpeedButton *BtnNtrip; + TSpeedButton *BtnPost; + TSpeedButton *BtnStr; + TSpeedButton *BtnConv; + TSpeedButton *BtnGet; + TTrayIcon *TrayIcon; + TPopupMenu *PopupMenu; + TMenuItem *MenuPlot; + TMenuItem *MenuConv; + TMenuItem *MenuStr; + TMenuItem *MenuPost; + TMenuItem *MenuNtrip; + TMenuItem *MenuNavi; + TMenuItem *MenuGet; + TMenuItem *N1; + TMenuItem *MenuExit; + TPanel *BtnTray; + TMenuItem *MenuExpand; + TMenuItem *N2; + TPanel *Panel1; + TSpeedButton *BtnRtklib; + TPanel *Panel2; + TPanel *BtnExit; + + void __fastcall BtnPlotClick(TObject *Sender); + void __fastcall BtnConvClick(TObject *Sender); + void __fastcall BtnStrClick(TObject *Sender); + void __fastcall BtnPostClick(TObject *Sender); + void __fastcall BtnNtripClick(TObject *Sender); + void __fastcall BtnNaviClick(TObject *Sender); + void __fastcall BtnGetClick(TObject *Sender); + void __fastcall FormClose(TObject *Sender, TCloseAction &Action); + void __fastcall BtnTrayClick(TObject *Sender); + void __fastcall TrayIconDblClick(TObject *Sender); + void __fastcall MenuPlotClick(TObject *Sender); + void __fastcall MenuConvClick(TObject *Sender); + void __fastcall MenuStrClick(TObject *Sender); + void __fastcall MenuPostClick(TObject *Sender); + void __fastcall MenuNtripClick(TObject *Sender); + void __fastcall MenuNaviClick(TObject *Sender); + void __fastcall MenuGetClick(TObject *Sender); + void __fastcall MenuExitClick(TObject *Sender); + void __fastcall MenuExpandClick(TObject *Sender); + void __fastcall Panel1Resize(TObject *Sender); + void __fastcall BtnRtklibMouseDown(TObject *Sender, TMouseButton Button, TShiftState Shift, int X, + int Y); + void __fastcall BtnExitClick(TObject *Sender); + + private: + AnsiString IniFile; + int Tray, Trace; + + void __fastcall UpdatePanel(void); + int __fastcall ExecCmd(AnsiString cmd); -private: - AnsiString IniFile; - int Tray,Trace; - - void __fastcall UpdatePanel(void); - int __fastcall ExecCmd(AnsiString cmd); -public: - int Option,Minimize; - __fastcall TMainForm(TComponent* Owner); + public: + int Option, Minimize; + __fastcall TMainForm(TComponent *Owner); }; //--------------------------------------------------------------------------- extern PACKAGE TMainForm *MainForm; diff --git a/app/winapp/rtklaunch/launchoptdlg.cpp b/app/winapp/rtklaunch/launchoptdlg.cpp index ca035ce12..9225816f4 100644 --- a/app/winapp/rtklaunch/launchoptdlg.cpp +++ b/app/winapp/rtklaunch/launchoptdlg.cpp @@ -3,43 +3,35 @@ #include #pragma hdrstop -#include "launchmain.h" #include "launchoptdlg.h" + +#include "launchmain.h" //--------------------------------------------------------------------------- #pragma package(smart_init) #pragma resource "*.dfm" TLaunchOptDialog *LaunchOptDialog; //--------------------------------------------------------------------------- -__fastcall TLaunchOptDialog::TLaunchOptDialog(TComponent* Owner) - : TForm(Owner) -{ -} +__fastcall TLaunchOptDialog::TLaunchOptDialog(TComponent *Owner) : TForm(Owner) {} //--------------------------------------------------------------------------- -void __fastcall TLaunchOptDialog::FormShow(TObject *Sender) -{ - if (MainForm->Option==1) { - OptMkl->Checked=true; - } - else if (MainForm->Option==2) { - OptWin64->Checked=true; - } - else { - OptNormal->Checked=true; - } - Minimize->Checked=MainForm->Minimize; +void __fastcall TLaunchOptDialog::FormShow(TObject *Sender) { + if (MainForm->Option == 1) { + OptMkl->Checked = true; + } else if (MainForm->Option == 2) { + OptWin64->Checked = true; + } else { + OptNormal->Checked = true; + } + Minimize->Checked = MainForm->Minimize; } //--------------------------------------------------------------------------- -void __fastcall TLaunchOptDialog::BtnOkClick(TObject *Sender) -{ - if (OptMkl->Checked) { - MainForm->Option=1; - } - else if (OptWin64->Checked) { - MainForm->Option=2; - } - else { - MainForm->Option=0; - } - MainForm->Minimize=Minimize->Checked; +void __fastcall TLaunchOptDialog::BtnOkClick(TObject *Sender) { + if (OptMkl->Checked) { + MainForm->Option = 1; + } else if (OptWin64->Checked) { + MainForm->Option = 2; + } else { + MainForm->Option = 0; + } + MainForm->Minimize = Minimize->Checked; } //--------------------------------------------------------------------------- diff --git a/app/winapp/rtklaunch/launchoptdlg.h b/app/winapp/rtklaunch/launchoptdlg.h index daaeb560b..baf7b8f7c 100644 --- a/app/winapp/rtklaunch/launchoptdlg.h +++ b/app/winapp/rtklaunch/launchoptdlg.h @@ -5,23 +5,22 @@ //--------------------------------------------------------------------------- #include #include -#include #include +#include //--------------------------------------------------------------------------- -class TLaunchOptDialog : public TForm -{ -__published: - TRadioButton *OptMkl; - TRadioButton *OptWin64; - TButton *BtnCancel; - TButton *BtnOk; - TRadioButton *OptNormal; - TCheckBox *Minimize; - void __fastcall FormShow(TObject *Sender); - void __fastcall BtnOkClick(TObject *Sender); -private: -public: - __fastcall TLaunchOptDialog(TComponent* Owner); +class TLaunchOptDialog : public TForm { + __published : TRadioButton *OptMkl; + TRadioButton *OptWin64; + TButton *BtnCancel; + TButton *BtnOk; + TRadioButton *OptNormal; + TCheckBox *Minimize; + void __fastcall FormShow(TObject *Sender); + void __fastcall BtnOkClick(TObject *Sender); + + private: + public: + __fastcall TLaunchOptDialog(TComponent *Owner); }; //--------------------------------------------------------------------------- extern PACKAGE TLaunchOptDialog *LaunchOptDialog; diff --git a/app/winapp/rtklaunch/rtklaunch.cpp b/app/winapp/rtklaunch/rtklaunch.cpp index 763a9228e..a62c8eda8 100644 --- a/app/winapp/rtklaunch/rtklaunch.cpp +++ b/app/winapp/rtklaunch/rtklaunch.cpp @@ -7,47 +7,24 @@ #include #include - - - - - - - - - - - - - - USEFORM("launchmain.cpp", MainForm); //--------------------------------------------------------------------------- -int WINAPI _tWinMain(HINSTANCE, HINSTANCE, LPTSTR, int) -{ - try - { - Application->Initialize(); - Application->MainFormOnTaskBar = true; - Application->Title = "RTKLAUNCH"; - Application->CreateForm(__classid(TMainForm), &MainForm); - Application->Run(); - } - catch (Exception &exception) - { - Application->ShowException(&exception); - } - catch (...) - { - try - { - throw Exception(""); - } - catch (Exception &exception) - { - Application->ShowException(&exception); - } - } - return 0; +int WINAPI _tWinMain(HINSTANCE, HINSTANCE, LPTSTR, int) { + try { + Application->Initialize(); + Application->MainFormOnTaskBar = true; + Application->Title = "RTKLAUNCH"; + Application->CreateForm(__classid(TMainForm), &MainForm); + Application->Run(); + } catch (Exception &exception) { + Application->ShowException(&exception); + } catch (...) { + try { + throw Exception(""); + } catch (Exception &exception) { + Application->ShowException(&exception); + } + } + return 0; } //--------------------------------------------------------------------------- diff --git a/app/winapp/rtknavi/instrdlg.cpp b/app/winapp/rtknavi/instrdlg.cpp index 404a58c9c..fd18cfb52 100644 --- a/app/winapp/rtknavi/instrdlg.cpp +++ b/app/winapp/rtknavi/instrdlg.cpp @@ -2,399 +2,379 @@ #include #pragma hdrstop -#include "rtklib.h" -#include "refdlg.h" -#include "navimain.h" -#include "serioptdlg.h" +#include "instrdlg.h" + #include "cmdoptdlg.h" #include "fileoptdlg.h" -#include "tcpoptdlg.h" #include "ftpoptdlg.h" +#include "navimain.h" #include "rcvoptdlg.h" -#include "instrdlg.h" +#include "refdlg.h" +#include "rtklib.h" +#include "serioptdlg.h" +#include "tcpoptdlg.h" //--------------------------------------------------------------------------- #pragma package(smart_init) #pragma resource "*.dfm" TInputStrDialog *InputStrDialog; //--------------------------------------------------------------------------- -static double str2dbl(AnsiString str) -{ - double val=0.0; - sscanf(str.c_str(),"%lf",&val); - return val; +static double str2dbl(AnsiString str) { + double val = 0.0; + sscanf(str.c_str(), "%lf", &val); + return val; } //--------------------------------------------------------------------------- -__fastcall TInputStrDialog::TInputStrDialog(TComponent* Owner) - : TForm(Owner) -{ - int i; - Format1->Items->Clear(); - Format2->Items->Clear(); - NRcv=0; - for (i=0;i<=MAXRCVFMT;i++) { - Format1->Items->Add(formatstrs[i]); - Format2->Items->Add(formatstrs[i]); - Format3->Items->Add(formatstrs[i]); - NRcv++; - } - Format3->Items->Add("SP3"); - Format3->Items->Add("CLK"); +__fastcall TInputStrDialog::TInputStrDialog(TComponent *Owner) : TForm(Owner) { + int i; + Format1->Items->Clear(); + Format2->Items->Clear(); + NRcv = 0; + for (i = 0; i <= MAXRCVFMT; i++) { + Format1->Items->Add(formatstrs[i]); + Format2->Items->Add(formatstrs[i]); + Format3->Items->Add(formatstrs[i]); + NRcv++; + } + Format3->Items->Add("SP3"); + Format3->Items->Add("CLK"); } //--------------------------------------------------------------------------- -void __fastcall TInputStrDialog::FormShow(TObject *Sender) -{ - AnsiString s; - StreamC1 ->Checked =StreamC[0]; - StreamC2 ->Checked =StreamC[1]; - StreamC3 ->Checked =StreamC[2]; - Stream1 ->ItemIndex=Stream[0]; - Stream2 ->ItemIndex=Stream[1]; - Stream3 ->ItemIndex=Stream[2]; - Format1 ->ItemIndex=Format[0]; - Format2 ->ItemIndex=Format[1]ItemIndex=Format[2]Text =GetFilePath(Paths[0][2]); - FilePath2 ->Text =GetFilePath(Paths[1][2]); - FilePath3 ->Text =GetFilePath(Paths[2][2]); - NmeaReqL ->ItemIndex=NmeaReq; - TimeTagC ->Checked =TimeTag; - TimeSpeedL->Text =TimeSpeed; - TimeStartE->Text =TimeStart; - Chk64Bit ->Checked =Time64Bit; - NmeaPos1 ->Text =s.sprintf("%.9f",NmeaPos[0]); - NmeaPos2 ->Text =s.sprintf("%.9f",NmeaPos[1]); - NmeaPos3 ->Text =s.sprintf("%.3f",NmeaPos[2]); - EditMaxBL ->Text =s.sprintf("%.0f",MaxBL); - EditResetCmd->Text =ResetCmd; - UpdateEnable(); +void __fastcall TInputStrDialog::FormShow(TObject *Sender) { + AnsiString s; + StreamC1->Checked = StreamC[0]; + StreamC2->Checked = StreamC[1]; + StreamC3->Checked = StreamC[2]; + Stream1->ItemIndex = Stream[0]; + Stream2->ItemIndex = Stream[1]; + Stream3->ItemIndex = Stream[2]; + Format1->ItemIndex = Format[0]; + Format2->ItemIndex = Format[1] < NRcv ? Format[1] : NRcv + Format[1] - STRFMT_SP3; + Format3->ItemIndex = Format[2] < NRcv ? Format[2] : NRcv + Format[2] - STRFMT_SP3; + FilePath1->Text = GetFilePath(Paths[0][2]); + FilePath2->Text = GetFilePath(Paths[1][2]); + FilePath3->Text = GetFilePath(Paths[2][2]); + NmeaReqL->ItemIndex = NmeaReq; + TimeTagC->Checked = TimeTag; + TimeSpeedL->Text = TimeSpeed; + TimeStartE->Text = TimeStart; + Chk64Bit->Checked = Time64Bit; + NmeaPos1->Text = s.sprintf("%.9f", NmeaPos[0]); + NmeaPos2->Text = s.sprintf("%.9f", NmeaPos[1]); + NmeaPos3->Text = s.sprintf("%.3f", NmeaPos[2]); + EditMaxBL->Text = s.sprintf("%.0f", MaxBL); + EditResetCmd->Text = ResetCmd; + UpdateEnable(); } //--------------------------------------------------------------------------- -void __fastcall TInputStrDialog::BtnOkClick(TObject *Sender) -{ - StreamC[0] =StreamC1 ->Checked; - StreamC[1] =StreamC2 ->Checked; - StreamC[2] =StreamC3 ->Checked; - Stream[0] =Stream1 ->ItemIndex; - Stream[1] =Stream2 ->ItemIndex; - Stream[2] =Stream3 ->ItemIndex; - Format[0] =Format1 ->ItemIndex; - Format[1] =Format2->ItemIndexItemIndex:STRFMT_SP3+Format2->ItemIndex-NRcv; - Format[2] =Format3->ItemIndexItemIndex:STRFMT_SP3+Format3->ItemIndex-NRcv; - Paths[0][2]=SetFilePath(FilePath1->Text); - Paths[1][2]=SetFilePath(FilePath2->Text); - Paths[2][2]=SetFilePath(FilePath3->Text); - NmeaReq =NmeaReqL ->ItemIndex; - TimeTag =TimeTagC ->Checked; - TimeSpeed =TimeSpeedL->Text; - TimeStart =TimeStartE->Text; - Time64Bit =Chk64Bit ->Checked; - NmeaPos[0] =str2dbl(NmeaPos1->Text); - NmeaPos[1] =str2dbl(NmeaPos2->Text); - NmeaPos[2] =str2dbl(NmeaPos3->Text); - MaxBL =str2dbl(EditMaxBL->Text); - ResetCmd =EditResetCmd->Text; +void __fastcall TInputStrDialog::BtnOkClick(TObject *Sender) { + StreamC[0] = StreamC1->Checked; + StreamC[1] = StreamC2->Checked; + StreamC[2] = StreamC3->Checked; + Stream[0] = Stream1->ItemIndex; + Stream[1] = Stream2->ItemIndex; + Stream[2] = Stream3->ItemIndex; + Format[0] = Format1->ItemIndex; + Format[1] = + Format2->ItemIndex < NRcv ? Format2->ItemIndex : STRFMT_SP3 + Format2->ItemIndex - NRcv; + Format[2] = + Format3->ItemIndex < NRcv ? Format3->ItemIndex : STRFMT_SP3 + Format3->ItemIndex - NRcv; + Paths[0][2] = SetFilePath(FilePath1->Text); + Paths[1][2] = SetFilePath(FilePath2->Text); + Paths[2][2] = SetFilePath(FilePath3->Text); + NmeaReq = NmeaReqL->ItemIndex; + TimeTag = TimeTagC->Checked; + TimeSpeed = TimeSpeedL->Text; + TimeStart = TimeStartE->Text; + Time64Bit = Chk64Bit->Checked; + NmeaPos[0] = str2dbl(NmeaPos1->Text); + NmeaPos[1] = str2dbl(NmeaPos2->Text); + NmeaPos[2] = str2dbl(NmeaPos3->Text); + MaxBL = str2dbl(EditMaxBL->Text); + ResetCmd = EditResetCmd->Text; } //--------------------------------------------------------------------------- -void __fastcall TInputStrDialog::StreamC1Click(TObject *Sender) -{ - UpdateEnable(); -} +void __fastcall TInputStrDialog::StreamC1Click(TObject *Sender) { UpdateEnable(); } //--------------------------------------------------------------------------- -void __fastcall TInputStrDialog::StreamC2Click(TObject *Sender) -{ - UpdateEnable(); -} +void __fastcall TInputStrDialog::StreamC2Click(TObject *Sender) { UpdateEnable(); } //--------------------------------------------------------------------------- -void __fastcall TInputStrDialog::Stream1Change(TObject *Sender) -{ - UpdateEnable(); -} +void __fastcall TInputStrDialog::Stream1Change(TObject *Sender) { UpdateEnable(); } //--------------------------------------------------------------------------- -void __fastcall TInputStrDialog::Stream2Change(TObject *Sender) -{ - UpdateEnable(); -} +void __fastcall TInputStrDialog::Stream2Change(TObject *Sender) { UpdateEnable(); } //--------------------------------------------------------------------------- -void __fastcall TInputStrDialog::Stream3Change(TObject *Sender) -{ - UpdateEnable(); -} +void __fastcall TInputStrDialog::Stream3Change(TObject *Sender) { UpdateEnable(); } //--------------------------------------------------------------------------- -void __fastcall TInputStrDialog::NmeaReqCClick(TObject *Sender) -{ - UpdateEnable(); -} +void __fastcall TInputStrDialog::NmeaReqCClick(TObject *Sender) { UpdateEnable(); } //--------------------------------------------------------------------------- -void __fastcall TInputStrDialog::TimeTagCClick(TObject *Sender) -{ - UpdateEnable(); -} +void __fastcall TInputStrDialog::TimeTagCClick(TObject *Sender) { UpdateEnable(); } //--------------------------------------------------------------------------- -void __fastcall TInputStrDialog::NmeaReqLChange(TObject *Sender) -{ - UpdateEnable(); -} +void __fastcall TInputStrDialog::NmeaReqLChange(TObject *Sender) { UpdateEnable(); } //--------------------------------------------------------------------------- -AnsiString __fastcall TInputStrDialog::GetFilePath(AnsiString path) -{ - char *p,*q,buff[1024]; - strcpy(buff,path.c_str()); - if ((p=strstr(buff,"::"))) *p='\0'; - return (path=buff); +AnsiString __fastcall TInputStrDialog::GetFilePath(AnsiString path) { + char *p, *q, buff[1024]; + strcpy(buff, path.c_str()); + if ((p = strstr(buff, "::"))) *p = '\0'; + return (path = buff); } //--------------------------------------------------------------------------- -AnsiString __fastcall TInputStrDialog::SetFilePath(AnsiString path) -{ - if (TimeTagC->Checked ) path+="::T"; - if (TimeStartE->Text!="0" ) path+="::+"+TimeStartE->Text; - path+="::"+TimeSpeedL->Text; - if (Chk64Bit->Checked ) path+="::P=8"; - return path; +AnsiString __fastcall TInputStrDialog::SetFilePath(AnsiString path) { + if (TimeTagC->Checked) path += "::T"; + if (TimeStartE->Text != "0") path += "::+" + TimeStartE->Text; + path += "::" + TimeSpeedL->Text; + if (Chk64Bit->Checked) path += "::P=8"; + return path; } //--------------------------------------------------------------------------- -void __fastcall TInputStrDialog::BtnStr1Click(TObject *Sender) -{ - switch (Stream1->ItemIndex) { - case 0: SerialOpt(0,0); break; - case 1: TcpOpt(0,1); break; - case 2: TcpOpt(0,0); break; - case 3: TcpOpt(0,3); break; - } +void __fastcall TInputStrDialog::BtnStr1Click(TObject *Sender) { + switch (Stream1->ItemIndex) { + case 0: + SerialOpt(0, 0); + break; + case 1: + TcpOpt(0, 1); + break; + case 2: + TcpOpt(0, 0); + break; + case 3: + TcpOpt(0, 3); + break; + } } //--------------------------------------------------------------------------- -void __fastcall TInputStrDialog::BtnStr2Click(TObject *Sender) -{ - switch (Stream2->ItemIndex) { - case 0: SerialOpt(1,0); break; - case 1: TcpOpt(1,1); break; - case 2: TcpOpt(1,0); break; - case 3: TcpOpt(1,3); break; - case 5: FtpOpt(1,0); break; - case 6: FtpOpt(1,1); break; - } +void __fastcall TInputStrDialog::BtnStr2Click(TObject *Sender) { + switch (Stream2->ItemIndex) { + case 0: + SerialOpt(1, 0); + break; + case 1: + TcpOpt(1, 1); + break; + case 2: + TcpOpt(1, 0); + break; + case 3: + TcpOpt(1, 3); + break; + case 5: + FtpOpt(1, 0); + break; + case 6: + FtpOpt(1, 1); + break; + } } //--------------------------------------------------------------------------- -void __fastcall TInputStrDialog::BtnStr3Click(TObject *Sender) -{ - switch (Stream3->ItemIndex) { - case 0: SerialOpt(2,0); break; - case 1: TcpOpt(2,1); break; - case 2: TcpOpt(2,0); break; - case 3: TcpOpt(2,3); break; - case 5: FtpOpt(2,0); break; - case 6: FtpOpt(2,1); break; - } +void __fastcall TInputStrDialog::BtnStr3Click(TObject *Sender) { + switch (Stream3->ItemIndex) { + case 0: + SerialOpt(2, 0); + break; + case 1: + TcpOpt(2, 1); + break; + case 2: + TcpOpt(2, 0); + break; + case 3: + TcpOpt(2, 3); + break; + case 5: + FtpOpt(2, 0); + break; + case 6: + FtpOpt(2, 1); + break; + } } //--------------------------------------------------------------------------- -void __fastcall TInputStrDialog::BtnCmd1Click(TObject *Sender) -{ - for (int i=0;i<3;i++) { - if (Stream1->ItemIndex==0) { - CmdOptDialog->Cmds [i]=Cmds [0][i]; - CmdOptDialog->CmdEna[i]=CmdEna[0][i]; - } - else { - CmdOptDialog->Cmds [i]=CmdsTcp [0][i]; - CmdOptDialog->CmdEna[i]=CmdEnaTcp[0][i]; - } - } - if (CmdOptDialog->ShowModal()!=mrOk) return; - for (int i=0;i<3;i++) { - if (Stream1->ItemIndex==0) { - Cmds [0][i]=CmdOptDialog->Cmds [i]; - CmdEna[0][i]=CmdOptDialog->CmdEna[i]; - } - else { - CmdsTcp [0][i]=CmdOptDialog->Cmds [i]; - CmdEnaTcp[0][i]=CmdOptDialog->CmdEna[i]; - } - } +void __fastcall TInputStrDialog::BtnCmd1Click(TObject *Sender) { + for (int i = 0; i < 3; i++) { + if (Stream1->ItemIndex == 0) { + CmdOptDialog->Cmds[i] = Cmds[0][i]; + CmdOptDialog->CmdEna[i] = CmdEna[0][i]; + } else { + CmdOptDialog->Cmds[i] = CmdsTcp[0][i]; + CmdOptDialog->CmdEna[i] = CmdEnaTcp[0][i]; + } + } + if (CmdOptDialog->ShowModal() != mrOk) return; + for (int i = 0; i < 3; i++) { + if (Stream1->ItemIndex == 0) { + Cmds[0][i] = CmdOptDialog->Cmds[i]; + CmdEna[0][i] = CmdOptDialog->CmdEna[i]; + } else { + CmdsTcp[0][i] = CmdOptDialog->Cmds[i]; + CmdEnaTcp[0][i] = CmdOptDialog->CmdEna[i]; + } + } } //--------------------------------------------------------------------------- -void __fastcall TInputStrDialog::BtnCmd2Click(TObject *Sender) -{ - for (int i=0;i<3;i++) { - if (Stream2->ItemIndex==0) { - CmdOptDialog->Cmds [i]=Cmds [1][i]; - CmdOptDialog->CmdEna[i]=CmdEna[1][i]; - } - else { - CmdOptDialog->Cmds [i]=CmdsTcp [1][i]; - CmdOptDialog->CmdEna[i]=CmdEnaTcp[1][i]; - } - } - if (CmdOptDialog->ShowModal()!=mrOk) return; - for (int i=0;i<3;i++) { - if (Stream2->ItemIndex==0) { - Cmds [1][i]=CmdOptDialog->Cmds [i]; - CmdEna[1][i]=CmdOptDialog->CmdEna[i]; - } - else { - CmdsTcp [1][i]=CmdOptDialog->Cmds [i]; - CmdEnaTcp[1][i]=CmdOptDialog->CmdEna[i]; - } - } +void __fastcall TInputStrDialog::BtnCmd2Click(TObject *Sender) { + for (int i = 0; i < 3; i++) { + if (Stream2->ItemIndex == 0) { + CmdOptDialog->Cmds[i] = Cmds[1][i]; + CmdOptDialog->CmdEna[i] = CmdEna[1][i]; + } else { + CmdOptDialog->Cmds[i] = CmdsTcp[1][i]; + CmdOptDialog->CmdEna[i] = CmdEnaTcp[1][i]; + } + } + if (CmdOptDialog->ShowModal() != mrOk) return; + for (int i = 0; i < 3; i++) { + if (Stream2->ItemIndex == 0) { + Cmds[1][i] = CmdOptDialog->Cmds[i]; + CmdEna[1][i] = CmdOptDialog->CmdEna[i]; + } else { + CmdsTcp[1][i] = CmdOptDialog->Cmds[i]; + CmdEnaTcp[1][i] = CmdOptDialog->CmdEna[i]; + } + } } //--------------------------------------------------------------------------- -void __fastcall TInputStrDialog::BtnCmd3Click(TObject *Sender) -{ - for (int i=0;i<3;i++) { - if (Stream3->ItemIndex==0) { - CmdOptDialog->Cmds [i]=Cmds [2][i]; - CmdOptDialog->CmdEna[i]=CmdEna[2][i]; - } - else { - CmdOptDialog->Cmds [i]=CmdsTcp [2][i]; - CmdOptDialog->CmdEna[i]=CmdEnaTcp[2][i]; - } - } - if (CmdOptDialog->ShowModal()!=mrOk) return; - for (int i=0;i<3;i++) { - if (Stream3->ItemIndex==0) { - Cmds [2][i]=CmdOptDialog->Cmds [i]; - CmdEna[2][i]=CmdOptDialog->CmdEna[i]; - } - else { - CmdsTcp [2][i]=CmdOptDialog->Cmds [i]; - CmdEnaTcp[2][i]=CmdOptDialog->CmdEna[i]; - } - } +void __fastcall TInputStrDialog::BtnCmd3Click(TObject *Sender) { + for (int i = 0; i < 3; i++) { + if (Stream3->ItemIndex == 0) { + CmdOptDialog->Cmds[i] = Cmds[2][i]; + CmdOptDialog->CmdEna[i] = CmdEna[2][i]; + } else { + CmdOptDialog->Cmds[i] = CmdsTcp[2][i]; + CmdOptDialog->CmdEna[i] = CmdEnaTcp[2][i]; + } + } + if (CmdOptDialog->ShowModal() != mrOk) return; + for (int i = 0; i < 3; i++) { + if (Stream3->ItemIndex == 0) { + Cmds[2][i] = CmdOptDialog->Cmds[i]; + CmdEna[2][i] = CmdOptDialog->CmdEna[i]; + } else { + CmdsTcp[2][i] = CmdOptDialog->Cmds[i]; + CmdEnaTcp[2][i] = CmdOptDialog->CmdEna[i]; + } + } } //--------------------------------------------------------------------------- -void __fastcall TInputStrDialog::BtnRcvOpt1Click(TObject *Sender) -{ - RcvOptDialog->Option=RcvOpt[0]; - if (RcvOptDialog->ShowModal()!=mrOk) return; - RcvOpt[0]=RcvOptDialog->Option; +void __fastcall TInputStrDialog::BtnRcvOpt1Click(TObject *Sender) { + RcvOptDialog->Option = RcvOpt[0]; + if (RcvOptDialog->ShowModal() != mrOk) return; + RcvOpt[0] = RcvOptDialog->Option; } //--------------------------------------------------------------------------- -void __fastcall TInputStrDialog::BtnRcvOpt2Click(TObject *Sender) -{ - RcvOptDialog->Option=RcvOpt[1]; - if (RcvOptDialog->ShowModal()!=mrOk) return; - RcvOpt[1]=RcvOptDialog->Option; +void __fastcall TInputStrDialog::BtnRcvOpt2Click(TObject *Sender) { + RcvOptDialog->Option = RcvOpt[1]; + if (RcvOptDialog->ShowModal() != mrOk) return; + RcvOpt[1] = RcvOptDialog->Option; } //--------------------------------------------------------------------------- -void __fastcall TInputStrDialog::BtnRcvOpt3Click(TObject *Sender) -{ - RcvOptDialog->Option=RcvOpt[2]; - if (RcvOptDialog->ShowModal()!=mrOk) return; - RcvOpt[2]=RcvOptDialog->Option; +void __fastcall TInputStrDialog::BtnRcvOpt3Click(TObject *Sender) { + RcvOptDialog->Option = RcvOpt[2]; + if (RcvOptDialog->ShowModal() != mrOk) return; + RcvOpt[2] = RcvOptDialog->Option; } //--------------------------------------------------------------------------- -void __fastcall TInputStrDialog::BtnPosClick(TObject *Sender) -{ - AnsiString s; - RefDialog->RovPos[0]=str2dbl(NmeaPos1->Text); - RefDialog->RovPos[1]=str2dbl(NmeaPos2->Text); - RefDialog->RovPos[2]=str2dbl(NmeaPos3->Text); - RefDialog->StaPosFile=MainForm->StaPosFileF; - if (RefDialog->ShowModal()!=mrOk) return; - NmeaPos1->Text=s.sprintf("%.9f",RefDialog->Pos[0]); - NmeaPos2->Text=s.sprintf("%.9f",RefDialog->Pos[1]); - NmeaPos3->Text=s.sprintf("%.3f",RefDialog->Pos[2]); +void __fastcall TInputStrDialog::BtnPosClick(TObject *Sender) { + AnsiString s; + RefDialog->RovPos[0] = str2dbl(NmeaPos1->Text); + RefDialog->RovPos[1] = str2dbl(NmeaPos2->Text); + RefDialog->RovPos[2] = str2dbl(NmeaPos3->Text); + RefDialog->StaPosFile = MainForm->StaPosFileF; + if (RefDialog->ShowModal() != mrOk) return; + NmeaPos1->Text = s.sprintf("%.9f", RefDialog->Pos[0]); + NmeaPos2->Text = s.sprintf("%.9f", RefDialog->Pos[1]); + NmeaPos3->Text = s.sprintf("%.3f", RefDialog->Pos[2]); } //--------------------------------------------------------------------------- -void __fastcall TInputStrDialog::SerialOpt(int index, int opt) -{ - SerialOptDialog->Path=Paths[index][0]; - SerialOptDialog->Opt=opt; - if (SerialOptDialog->ShowModal()!=mrOk) return; - Paths[index][0]=SerialOptDialog->Path; +void __fastcall TInputStrDialog::SerialOpt(int index, int opt) { + SerialOptDialog->Path = Paths[index][0]; + SerialOptDialog->Opt = opt; + if (SerialOptDialog->ShowModal() != mrOk) return; + Paths[index][0] = SerialOptDialog->Path; } //--------------------------------------------------------------------------- -void __fastcall TInputStrDialog::BtnFile1Click(TObject *Sender) -{ - //OpenDialog->FileName=FilePath1->Text; - if (!OpenDialog->Execute()) return; - FilePath1->Text=OpenDialog->FileName; +void __fastcall TInputStrDialog::BtnFile1Click(TObject *Sender) { + // OpenDialog->FileName=FilePath1->Text; + if (!OpenDialog->Execute()) return; + FilePath1->Text = OpenDialog->FileName; } //--------------------------------------------------------------------------- -void __fastcall TInputStrDialog::BtnFile2Click(TObject *Sender) -{ - //OpenDialog->FileName=FilePath2->Text; - if (!OpenDialog->Execute()) return; - FilePath2->Text=OpenDialog->FileName; +void __fastcall TInputStrDialog::BtnFile2Click(TObject *Sender) { + // OpenDialog->FileName=FilePath2->Text; + if (!OpenDialog->Execute()) return; + FilePath2->Text = OpenDialog->FileName; } //--------------------------------------------------------------------------- -void __fastcall TInputStrDialog::BtnFile3Click(TObject *Sender) -{ - //OpenDialog->FileName=FilePath3->Text; - if (!OpenDialog->Execute()) return; - FilePath3->Text=OpenDialog->FileName; +void __fastcall TInputStrDialog::BtnFile3Click(TObject *Sender) { + // OpenDialog->FileName=FilePath3->Text; + if (!OpenDialog->Execute()) return; + FilePath3->Text = OpenDialog->FileName; } //--------------------------------------------------------------------------- -void __fastcall TInputStrDialog::TcpOpt(int index, int opt) -{ - TcpOptDialog->Path=Paths[index][1]; - TcpOptDialog->Opt=opt; - for (int i=0;i<10;i++) { - TcpOptDialog->History[i]=History[i]; - } - if (TcpOptDialog->ShowModal()!=mrOk) return; - Paths[index][1]=TcpOptDialog->Path; - for (int i=0;i<10;i++) { - History[i]=TcpOptDialog->History[i]; - } +void __fastcall TInputStrDialog::TcpOpt(int index, int opt) { + TcpOptDialog->Path = Paths[index][1]; + TcpOptDialog->Opt = opt; + for (int i = 0; i < 10; i++) { + TcpOptDialog->History[i] = History[i]; + } + if (TcpOptDialog->ShowModal() != mrOk) return; + Paths[index][1] = TcpOptDialog->Path; + for (int i = 0; i < 10; i++) { + History[i] = TcpOptDialog->History[i]; + } } //--------------------------------------------------------------------------- -void __fastcall TInputStrDialog::FtpOpt(int index, int opt) -{ - FtpOptDialog->Path=Paths[index][3]; - FtpOptDialog->Opt=opt; - if (FtpOptDialog->ShowModal()!=mrOk) return; - Paths[index][3]=FtpOptDialog->Path; +void __fastcall TInputStrDialog::FtpOpt(int index, int opt) { + FtpOptDialog->Path = Paths[index][3]; + FtpOptDialog->Opt = opt; + if (FtpOptDialog->ShowModal() != mrOk) return; + Paths[index][3] = FtpOptDialog->Path; } //--------------------------------------------------------------------------- -void __fastcall TInputStrDialog::UpdateEnable(void) -{ - int ena1=(StreamC1->Checked&&Stream1->ItemIndex==4)|| - (StreamC2->Checked&&Stream2->ItemIndex==4)|| - (StreamC3->Checked&&Stream3->ItemIndex==4); - int ena2=StreamC2->Checked&&Stream2->ItemIndex<=3; - - Stream1 ->Enabled=StreamC1->Checked; - Stream2 ->Enabled=StreamC2->Checked; - Stream3 ->Enabled=StreamC3->Checked; - BtnStr1 ->Enabled=StreamC1->Checked&&Stream1->ItemIndex!=4; - BtnStr2 ->Enabled=StreamC2->Checked&&Stream2->ItemIndex!=4; - BtnStr3 ->Enabled=StreamC3->Checked&&Stream3->ItemIndex!=4; - BtnCmd1 ->Enabled=StreamC1->Checked&&Stream1->ItemIndex!=4; - BtnCmd2 ->Enabled=StreamC2->Checked&&Stream2->ItemIndex!=4; - BtnCmd3 ->Enabled=StreamC3->Checked&&Stream3->ItemIndex!=4; - Format1 ->Enabled=StreamC1->Checked; - Format2 ->Enabled=StreamC2->Checked; - Format3 ->Enabled=StreamC3->Checked; - BtnRcvOpt1->Enabled=StreamC1->Checked; - BtnRcvOpt2->Enabled=StreamC2->Checked; - BtnRcvOpt3->Enabled=StreamC3->Checked; - - LabelNmea ->Enabled=ena2; - NmeaReqL ->Enabled=ena2; - NmeaPos1 ->Enabled=ena2&&NmeaReqL->ItemIndex==1; - NmeaPos2 ->Enabled=ena2&&NmeaReqL->ItemIndex==1; - NmeaPos3 ->Enabled=ena2&&NmeaReqL->ItemIndex==1; - BtnPos ->Enabled=ena2&&NmeaReqL->ItemIndex==1; - LabelResetCmd->Enabled=ena2&&NmeaReqL->ItemIndex==3; - EditResetCmd->Enabled=ena2&&NmeaReqL->ItemIndex==3; - LabelMaxBL->Enabled=ena2&&NmeaReqL->ItemIndex==3; - EditMaxBL ->Enabled=ena2&&NmeaReqL->ItemIndex==3; - LabelKm ->Enabled=ena2&&NmeaReqL->ItemIndex==3; - - LabelF1 ->Enabled=ena1; - FilePath1 ->Enabled=StreamC1->Checked&&Stream1->ItemIndex==4; - FilePath2 ->Enabled=StreamC2->Checked&&Stream2->ItemIndex==4; - FilePath3 ->Enabled=StreamC3->Checked&&Stream3->ItemIndex==4; - BtnFile1 ->Enabled=StreamC1->Checked&&Stream1->ItemIndex==4; - BtnFile2 ->Enabled=StreamC2->Checked&&Stream2->ItemIndex==4; - BtnFile3 ->Enabled=StreamC3->Checked&&Stream3->ItemIndex==4; - TimeTagC ->Enabled=ena1; - TimeStartE->Enabled=ena1&&TimeTagC->Checked; - TimeSpeedL->Enabled=ena1&&TimeTagC->Checked; - LabelF2 ->Enabled=ena1&&TimeTagC->Checked; - LabelF3 ->Enabled=ena1&&TimeTagC->Checked; - Chk64Bit ->Enabled=ena1&&TimeTagC->Checked; +void __fastcall TInputStrDialog::UpdateEnable(void) { + int ena1 = (StreamC1->Checked && Stream1->ItemIndex == 4) || + (StreamC2->Checked && Stream2->ItemIndex == 4) || + (StreamC3->Checked && Stream3->ItemIndex == 4); + int ena2 = StreamC2->Checked && Stream2->ItemIndex <= 3; + + Stream1->Enabled = StreamC1->Checked; + Stream2->Enabled = StreamC2->Checked; + Stream3->Enabled = StreamC3->Checked; + BtnStr1->Enabled = StreamC1->Checked && Stream1->ItemIndex != 4; + BtnStr2->Enabled = StreamC2->Checked && Stream2->ItemIndex != 4; + BtnStr3->Enabled = StreamC3->Checked && Stream3->ItemIndex != 4; + BtnCmd1->Enabled = StreamC1->Checked && Stream1->ItemIndex != 4; + BtnCmd2->Enabled = StreamC2->Checked && Stream2->ItemIndex != 4; + BtnCmd3->Enabled = StreamC3->Checked && Stream3->ItemIndex != 4; + Format1->Enabled = StreamC1->Checked; + Format2->Enabled = StreamC2->Checked; + Format3->Enabled = StreamC3->Checked; + BtnRcvOpt1->Enabled = StreamC1->Checked; + BtnRcvOpt2->Enabled = StreamC2->Checked; + BtnRcvOpt3->Enabled = StreamC3->Checked; + + LabelNmea->Enabled = ena2; + NmeaReqL->Enabled = ena2; + NmeaPos1->Enabled = ena2 && NmeaReqL->ItemIndex == 1; + NmeaPos2->Enabled = ena2 && NmeaReqL->ItemIndex == 1; + NmeaPos3->Enabled = ena2 && NmeaReqL->ItemIndex == 1; + BtnPos->Enabled = ena2 && NmeaReqL->ItemIndex == 1; + LabelResetCmd->Enabled = ena2 && NmeaReqL->ItemIndex == 3; + EditResetCmd->Enabled = ena2 && NmeaReqL->ItemIndex == 3; + LabelMaxBL->Enabled = ena2 && NmeaReqL->ItemIndex == 3; + EditMaxBL->Enabled = ena2 && NmeaReqL->ItemIndex == 3; + LabelKm->Enabled = ena2 && NmeaReqL->ItemIndex == 3; + + LabelF1->Enabled = ena1; + FilePath1->Enabled = StreamC1->Checked && Stream1->ItemIndex == 4; + FilePath2->Enabled = StreamC2->Checked && Stream2->ItemIndex == 4; + FilePath3->Enabled = StreamC3->Checked && Stream3->ItemIndex == 4; + BtnFile1->Enabled = StreamC1->Checked && Stream1->ItemIndex == 4; + BtnFile2->Enabled = StreamC2->Checked && Stream2->ItemIndex == 4; + BtnFile3->Enabled = StreamC3->Checked && Stream3->ItemIndex == 4; + TimeTagC->Enabled = ena1; + TimeStartE->Enabled = ena1 && TimeTagC->Checked; + TimeSpeedL->Enabled = ena1 && TimeTagC->Checked; + LabelF2->Enabled = ena1 && TimeTagC->Checked; + LabelF3->Enabled = ena1 && TimeTagC->Checked; + Chk64Bit->Enabled = ena1 && TimeTagC->Checked; } //--------------------------------------------------------------------------- - diff --git a/app/winapp/rtknavi/instrdlg.h b/app/winapp/rtknavi/instrdlg.h index 1edfc91ef..c2832f27a 100644 --- a/app/winapp/rtknavi/instrdlg.h +++ b/app/winapp/rtknavi/instrdlg.h @@ -4,103 +4,103 @@ //--------------------------------------------------------------------------- #include #include -#include -#include -#include #include +#include +#include +#include //--------------------------------------------------------------------------- -class TInputStrDialog : public TForm -{ -__published: - TButton *BtnCancel; - TButton *BtnOk; - TComboBox *Stream1; - TLabel *Label5; - TButton *BtnStr1; - TLabel *Label6; - TComboBox *Stream2; - TButton *BtnStr2; - TLabel *Label10; - TComboBox *Format1; - TLabel *Label7; - TComboBox *Format2; - TButton *BtnCmd1; - TButton *BtnCmd2; - TLabel *Label11; - TLabel *LabelF1; - TEdit *FilePath1; - TEdit *FilePath2; - TCheckBox *TimeTagC; - TEdit *TimeStartE; - TButton *BtnFile1; - TButton *BtnFile2; - TComboBox *NmeaReqL; - TOpenDialog *OpenDialog; - TComboBox *TimeSpeedL; - TLabel *LabelF2; - TLabel *LabelF3; - TEdit *NmeaPos1; - TEdit *NmeaPos2; - TButton *BtnPos; - TLabel *LabelNmea; - TCheckBox *StreamC1; - TCheckBox *StreamC2; - TEdit *FilePath3; - TButton *BtnFile3; - TCheckBox *StreamC3; - TComboBox *Stream3; - TButton *BtnStr3; - TComboBox *Format3; - TButton *BtnCmd3; - TButton *BtnRcvOpt1; - TButton *BtnRcvOpt2; - TButton *BtnRcvOpt3; - TLabel *Label1; - TEdit *NmeaPos3; - TEdit *EditResetCmd; - TLabel *LabelResetCmd; - TEdit *EditMaxBL; - TLabel *LabelMaxBL; - TLabel *LabelKm; - TCheckBox *Chk64Bit; - void __fastcall BtnOkClick(TObject *Sender); - void __fastcall FormShow(TObject *Sender); - void __fastcall BtnStr1Click(TObject *Sender); - void __fastcall BtnStr2Click(TObject *Sender); - void __fastcall Stream1Change(TObject *Sender); - void __fastcall Stream2Change(TObject *Sender); - void __fastcall BtnCmd1Click(TObject *Sender); - void __fastcall BtnCmd2Click(TObject *Sender); - void __fastcall TimeTagCClick(TObject *Sender); - void __fastcall NmeaReqCClick(TObject *Sender); - void __fastcall BtnFile1Click(TObject *Sender); - void __fastcall BtnFile2Click(TObject *Sender); - void __fastcall NmeaReqLChange(TObject *Sender); - void __fastcall BtnPosClick(TObject *Sender); - void __fastcall StreamC1Click(TObject *Sender); - void __fastcall StreamC2Click(TObject *Sender); - void __fastcall Stream3Change(TObject *Sender); - void __fastcall BtnStr3Click(TObject *Sender); - void __fastcall BtnFile3Click(TObject *Sender); - void __fastcall BtnCmd3Click(TObject *Sender); - void __fastcall BtnRcvOpt1Click(TObject *Sender); - void __fastcall BtnRcvOpt2Click(TObject *Sender); - void __fastcall BtnRcvOpt3Click(TObject *Sender); -private: - AnsiString __fastcall GetFilePath(AnsiString path); - AnsiString __fastcall SetFilePath(AnsiString path); - void __fastcall SerialOpt(int index, int opt); - void __fastcall TcpOpt(int index, int opt); - void __fastcall FtpOpt(int index, int opt); - void __fastcall UpdateEnable(void); -public: - int StreamC[3],Stream[3],Format[3],CmdEna[3][3],CmdEnaTcp[3][3]; - int NmeaReq,TimeTag,Time64Bit,NRcv; - double NmeaPos[3],MaxBL; - AnsiString Paths[3][4],Cmds[3][3],CmdsTcp[3][3],TimeStart,TimeSpeed; - AnsiString RcvOpt[3],ResetCmd; - AnsiString History[10]; - __fastcall TInputStrDialog(TComponent* Owner); +class TInputStrDialog : public TForm { + __published : TButton *BtnCancel; + TButton *BtnOk; + TComboBox *Stream1; + TLabel *Label5; + TButton *BtnStr1; + TLabel *Label6; + TComboBox *Stream2; + TButton *BtnStr2; + TLabel *Label10; + TComboBox *Format1; + TLabel *Label7; + TComboBox *Format2; + TButton *BtnCmd1; + TButton *BtnCmd2; + TLabel *Label11; + TLabel *LabelF1; + TEdit *FilePath1; + TEdit *FilePath2; + TCheckBox *TimeTagC; + TEdit *TimeStartE; + TButton *BtnFile1; + TButton *BtnFile2; + TComboBox *NmeaReqL; + TOpenDialog *OpenDialog; + TComboBox *TimeSpeedL; + TLabel *LabelF2; + TLabel *LabelF3; + TEdit *NmeaPos1; + TEdit *NmeaPos2; + TButton *BtnPos; + TLabel *LabelNmea; + TCheckBox *StreamC1; + TCheckBox *StreamC2; + TEdit *FilePath3; + TButton *BtnFile3; + TCheckBox *StreamC3; + TComboBox *Stream3; + TButton *BtnStr3; + TComboBox *Format3; + TButton *BtnCmd3; + TButton *BtnRcvOpt1; + TButton *BtnRcvOpt2; + TButton *BtnRcvOpt3; + TLabel *Label1; + TEdit *NmeaPos3; + TEdit *EditResetCmd; + TLabel *LabelResetCmd; + TEdit *EditMaxBL; + TLabel *LabelMaxBL; + TLabel *LabelKm; + TCheckBox *Chk64Bit; + void __fastcall BtnOkClick(TObject *Sender); + void __fastcall FormShow(TObject *Sender); + void __fastcall BtnStr1Click(TObject *Sender); + void __fastcall BtnStr2Click(TObject *Sender); + void __fastcall Stream1Change(TObject *Sender); + void __fastcall Stream2Change(TObject *Sender); + void __fastcall BtnCmd1Click(TObject *Sender); + void __fastcall BtnCmd2Click(TObject *Sender); + void __fastcall TimeTagCClick(TObject *Sender); + void __fastcall NmeaReqCClick(TObject *Sender); + void __fastcall BtnFile1Click(TObject *Sender); + void __fastcall BtnFile2Click(TObject *Sender); + void __fastcall NmeaReqLChange(TObject *Sender); + void __fastcall BtnPosClick(TObject *Sender); + void __fastcall StreamC1Click(TObject *Sender); + void __fastcall StreamC2Click(TObject *Sender); + void __fastcall Stream3Change(TObject *Sender); + void __fastcall BtnStr3Click(TObject *Sender); + void __fastcall BtnFile3Click(TObject *Sender); + void __fastcall BtnCmd3Click(TObject *Sender); + void __fastcall BtnRcvOpt1Click(TObject *Sender); + void __fastcall BtnRcvOpt2Click(TObject *Sender); + void __fastcall BtnRcvOpt3Click(TObject *Sender); + + private: + AnsiString __fastcall GetFilePath(AnsiString path); + AnsiString __fastcall SetFilePath(AnsiString path); + void __fastcall SerialOpt(int index, int opt); + void __fastcall TcpOpt(int index, int opt); + void __fastcall FtpOpt(int index, int opt); + void __fastcall UpdateEnable(void); + + public: + int StreamC[3], Stream[3], Format[3], CmdEna[3][3], CmdEnaTcp[3][3]; + int NmeaReq, TimeTag, Time64Bit, NRcv; + double NmeaPos[3], MaxBL; + AnsiString Paths[3][4], Cmds[3][3], CmdsTcp[3][3], TimeStart, TimeSpeed; + AnsiString RcvOpt[3], ResetCmd; + AnsiString History[10]; + __fastcall TInputStrDialog(TComponent *Owner); }; //--------------------------------------------------------------------------- extern PACKAGE TInputStrDialog *InputStrDialog; diff --git a/app/winapp/rtknavi/logstrdlg.cpp b/app/winapp/rtknavi/logstrdlg.cpp index b7d86ccb7..157df59fd 100644 --- a/app/winapp/rtknavi/logstrdlg.cpp +++ b/app/winapp/rtknavi/logstrdlg.cpp @@ -2,209 +2,202 @@ #include #pragma hdrstop -#include "rtklib.h" -#include "serioptdlg.h" +#include "logstrdlg.h" + #include "cmdoptdlg.h" #include "fileoptdlg.h" -#include "tcpoptdlg.h" -#include "logstrdlg.h" #include "keydlg.h" +#include "rtklib.h" +#include "serioptdlg.h" +#include "tcpoptdlg.h" //--------------------------------------------------------------------------- #pragma package(smart_init) #pragma resource "*.dfm" TLogStrDialog *LogStrDialog; //--------------------------------------------------------------------------- -__fastcall TLogStrDialog::TLogStrDialog(TComponent* Owner) - : TForm(Owner) -{ -} -//--------------------------------------------------------------------------- -void __fastcall TLogStrDialog::FormShow(TObject *Sender) -{ - Stream1C ->Checked =StreamC[0]; - Stream2C ->Checked =StreamC[1]; - Stream3C ->Checked =StreamC[2]; - Stream1 ->ItemIndex=Stream[0]; - Stream2 ->ItemIndex=Stream[1]; - Stream3 ->ItemIndex=Stream[2]; - FilePath1->Text =GetFilePath(Paths[0][2]); - FilePath2->Text =GetFilePath(Paths[1][2]); - FilePath3->Text =GetFilePath(Paths[2][2]); - SwapIntv ->Text =SwapInterval; - TimeTagC ->Checked =LogTimeTag; - UpdateEnable(); -} -//--------------------------------------------------------------------------- -void __fastcall TLogStrDialog::BtnOkClick(TObject *Sender) -{ - StreamC [0]=Stream1C->Checked; - StreamC [1]=Stream2C->Checked; - StreamC [2]=Stream3C->Checked; - Stream [0]=Stream1 ->ItemIndex; - Stream [1]=Stream2 ->ItemIndex; - Stream [2]=Stream3 ->ItemIndex; - Paths[0][2]=SetFilePath(FilePath1->Text); - Paths[1][2]=SetFilePath(FilePath2->Text); - Paths[2][2]=SetFilePath(FilePath3->Text); - SwapInterval=SwapIntv->Text; - LogTimeTag =TimeTagC->Checked; -} -//--------------------------------------------------------------------------- -void __fastcall TLogStrDialog::BtnFile1Click(TObject *Sender) -{ - SaveDialog->FileName=FilePath1->Text; - if (!SaveDialog->Execute()) return; - FilePath1->Text=SaveDialog->FileName; -} -//--------------------------------------------------------------------------- -void __fastcall TLogStrDialog::BtnFile2Click(TObject *Sender) -{ - SaveDialog->FileName=FilePath2->Text; - if (!SaveDialog->Execute()) return; - FilePath2->Text=SaveDialog->FileName; -} -//--------------------------------------------------------------------------- -void __fastcall TLogStrDialog::BtnFile3Click(TObject *Sender) -{ - SaveDialog->FileName=FilePath3->Text; - if (!SaveDialog->Execute()) return; - FilePath3->Text=SaveDialog->FileName; -} -//--------------------------------------------------------------------------- -void __fastcall TLogStrDialog::Stream1Change(TObject *Sender) -{ - UpdateEnable(); -} -//--------------------------------------------------------------------------- -void __fastcall TLogStrDialog::Stream2Change(TObject *Sender) -{ - UpdateEnable(); -} -//--------------------------------------------------------------------------- -void __fastcall TLogStrDialog::Stream3CClick(TObject *Sender) -{ - UpdateEnable(); +__fastcall TLogStrDialog::TLogStrDialog(TComponent *Owner) : TForm(Owner) {} +//--------------------------------------------------------------------------- +void __fastcall TLogStrDialog::FormShow(TObject *Sender) { + Stream1C->Checked = StreamC[0]; + Stream2C->Checked = StreamC[1]; + Stream3C->Checked = StreamC[2]; + Stream1->ItemIndex = Stream[0]; + Stream2->ItemIndex = Stream[1]; + Stream3->ItemIndex = Stream[2]; + FilePath1->Text = GetFilePath(Paths[0][2]); + FilePath2->Text = GetFilePath(Paths[1][2]); + FilePath3->Text = GetFilePath(Paths[2][2]); + SwapIntv->Text = SwapInterval; + TimeTagC->Checked = LogTimeTag; + UpdateEnable(); +} +//--------------------------------------------------------------------------- +void __fastcall TLogStrDialog::BtnOkClick(TObject *Sender) { + StreamC[0] = Stream1C->Checked; + StreamC[1] = Stream2C->Checked; + StreamC[2] = Stream3C->Checked; + Stream[0] = Stream1->ItemIndex; + Stream[1] = Stream2->ItemIndex; + Stream[2] = Stream3->ItemIndex; + Paths[0][2] = SetFilePath(FilePath1->Text); + Paths[1][2] = SetFilePath(FilePath2->Text); + Paths[2][2] = SetFilePath(FilePath3->Text); + SwapInterval = SwapIntv->Text; + LogTimeTag = TimeTagC->Checked; +} +//--------------------------------------------------------------------------- +void __fastcall TLogStrDialog::BtnFile1Click(TObject *Sender) { + SaveDialog->FileName = FilePath1->Text; + if (!SaveDialog->Execute()) return; + FilePath1->Text = SaveDialog->FileName; +} +//--------------------------------------------------------------------------- +void __fastcall TLogStrDialog::BtnFile2Click(TObject *Sender) { + SaveDialog->FileName = FilePath2->Text; + if (!SaveDialog->Execute()) return; + FilePath2->Text = SaveDialog->FileName; +} +//--------------------------------------------------------------------------- +void __fastcall TLogStrDialog::BtnFile3Click(TObject *Sender) { + SaveDialog->FileName = FilePath3->Text; + if (!SaveDialog->Execute()) return; + FilePath3->Text = SaveDialog->FileName; +} +//--------------------------------------------------------------------------- +void __fastcall TLogStrDialog::Stream1Change(TObject *Sender) { UpdateEnable(); } +//--------------------------------------------------------------------------- +void __fastcall TLogStrDialog::Stream2Change(TObject *Sender) { UpdateEnable(); } +//--------------------------------------------------------------------------- +void __fastcall TLogStrDialog::Stream3CClick(TObject *Sender) { UpdateEnable(); } +//--------------------------------------------------------------------------- +void __fastcall TLogStrDialog::Stream1CClick(TObject *Sender) { UpdateEnable(); } +//--------------------------------------------------------------------------- +void __fastcall TLogStrDialog::Stream2CClick(TObject *Sender) { UpdateEnable(); } +//--------------------------------------------------------------------------- +void __fastcall TLogStrDialog::Stream3Change(TObject *Sender) { UpdateEnable(); } +//--------------------------------------------------------------------------- +void __fastcall TLogStrDialog::BtnKeyClick(TObject *Sender) { KeyDialog->ShowModal(); } +//--------------------------------------------------------------------------- +void __fastcall TLogStrDialog::BtnStr1Click(TObject *Sender) { + switch (Stream1->ItemIndex) { + case 0: + SerialOpt(0, 0); + break; + case 1: + TcpOpt(0, 1); + break; + case 2: + TcpOpt(0, 0); + break; + case 3: + TcpOpt(0, 2); + break; + case 4: + TcpOpt(0, 4); + break; + } +} +//--------------------------------------------------------------------------- +void __fastcall TLogStrDialog::BtnStr2Click(TObject *Sender) { + switch (Stream2->ItemIndex) { + case 0: + SerialOpt(1, 0); + break; + case 1: + TcpOpt(1, 1); + break; + case 2: + TcpOpt(1, 0); + break; + case 3: + TcpOpt(1, 2); + break; + case 4: + TcpOpt(1, 4); + break; + } +} +//--------------------------------------------------------------------------- +void __fastcall TLogStrDialog::BtnStr3Click(TObject *Sender) { + switch (Stream3->ItemIndex) { + case 0: + SerialOpt(2, 0); + break; + case 1: + TcpOpt(2, 1); + break; + case 2: + TcpOpt(2, 0); + break; + case 3: + TcpOpt(2, 2); + break; + case 4: + TcpOpt(2, 4); + break; + } +} +//--------------------------------------------------------------------------- +AnsiString __fastcall TLogStrDialog::GetFilePath(AnsiString path) { + char *p, *q, buff[1024]; + strcpy(buff, path.c_str()); + if ((p = strstr(buff, "::"))) *p = '\0'; + return (path = buff); +} +//--------------------------------------------------------------------------- +AnsiString __fastcall TLogStrDialog::SetFilePath(AnsiString path) { + AnsiString str; + double swap; + if (TimeTagC->Checked) path += "::T"; + str = SwapIntv->Text; + if (sscanf(str.c_str(), "%lf", &swap) >= 1) { + path += "::S=" + str; + } + return path; +} +//--------------------------------------------------------------------------- +void __fastcall TLogStrDialog::SerialOpt(int index, int opt) { + SerialOptDialog->Path = Paths[index][0]; + SerialOptDialog->Opt = opt; + if (SerialOptDialog->ShowModal() != mrOk) return; + Paths[index][0] = SerialOptDialog->Path; +} +//--------------------------------------------------------------------------- +void __fastcall TLogStrDialog::TcpOpt(int index, int opt) { + TcpOptDialog->Path = Paths[index][1]; + TcpOptDialog->Opt = opt; + for (int i = 0; i < 10; i++) { + TcpOptDialog->History[i] = History[i]; + } + if (TcpOptDialog->ShowModal() != mrOk) return; + Paths[index][1] = TcpOptDialog->Path; + for (int i = 0; i < 10; i++) { + History[i] = TcpOptDialog->History[i]; + } +} +//--------------------------------------------------------------------------- +void __fastcall TLogStrDialog::UpdateEnable(void) { + int ena = (Stream1C->Checked && Stream1->ItemIndex == 5) || + (Stream2C->Checked && Stream2->ItemIndex == 5) || + (Stream3C->Checked && Stream3->ItemIndex == 5); + Stream1->Enabled = Stream1C->Checked; + Stream2->Enabled = Stream2C->Checked; + Stream3->Enabled = Stream3C->Checked; + BtnStr1->Enabled = Stream1C->Checked && Stream1->ItemIndex <= 4; + BtnStr2->Enabled = Stream2C->Checked && Stream2->ItemIndex <= 4; + BtnStr3->Enabled = Stream3C->Checked && Stream3->ItemIndex <= 4; + FilePath1->Enabled = Stream1C->Checked && Stream1->ItemIndex == 5; + FilePath2->Enabled = Stream2C->Checked && Stream2->ItemIndex == 5; + FilePath3->Enabled = Stream3C->Checked && Stream3->ItemIndex == 5; + BtnFile1->Enabled = Stream1C->Checked && Stream1->ItemIndex == 5; + BtnFile2->Enabled = Stream2C->Checked && Stream2->ItemIndex == 5; + BtnFile3->Enabled = Stream3C->Checked && Stream3->ItemIndex == 5; + Label1->Enabled = ena; + Label2->Enabled = ena; + LabelF1->Enabled = ena; + TimeTagC->Enabled = ena; + SwapIntv->Enabled = ena; + BtnKey->Enabled = ena; + OutEventC->Enabled = FilePath1->Enabled; } //--------------------------------------------------------------------------- -void __fastcall TLogStrDialog::Stream1CClick(TObject *Sender) -{ - UpdateEnable(); -} -//--------------------------------------------------------------------------- -void __fastcall TLogStrDialog::Stream2CClick(TObject *Sender) -{ - UpdateEnable(); -} -//--------------------------------------------------------------------------- -void __fastcall TLogStrDialog::Stream3Change(TObject *Sender) -{ - UpdateEnable(); -} -//--------------------------------------------------------------------------- -void __fastcall TLogStrDialog::BtnKeyClick(TObject *Sender) -{ - KeyDialog->ShowModal(); -} -//--------------------------------------------------------------------------- -void __fastcall TLogStrDialog::BtnStr1Click(TObject *Sender) -{ - switch (Stream1->ItemIndex) { - case 0: SerialOpt(0,0); break; - case 1: TcpOpt(0,1); break; - case 2: TcpOpt(0,0); break; - case 3: TcpOpt(0,2); break; - case 4: TcpOpt(0,4); break; - } -} -//--------------------------------------------------------------------------- -void __fastcall TLogStrDialog::BtnStr2Click(TObject *Sender) -{ - switch (Stream2->ItemIndex) { - case 0: SerialOpt(1,0); break; - case 1: TcpOpt(1,1); break; - case 2: TcpOpt(1,0); break; - case 3: TcpOpt(1,2); break; - case 4: TcpOpt(1,4); break; - } -} -//--------------------------------------------------------------------------- -void __fastcall TLogStrDialog::BtnStr3Click(TObject *Sender) -{ - switch (Stream3->ItemIndex) { - case 0: SerialOpt(2,0); break; - case 1: TcpOpt(2,1); break; - case 2: TcpOpt(2,0); break; - case 3: TcpOpt(2,2); break; - case 4: TcpOpt(2,4); break; - } -} -//--------------------------------------------------------------------------- -AnsiString __fastcall TLogStrDialog::GetFilePath(AnsiString path) -{ - char *p,*q,buff[1024]; - strcpy(buff,path.c_str()); - if ((p=strstr(buff,"::"))) *p='\0'; - return (path=buff); -} -//--------------------------------------------------------------------------- -AnsiString __fastcall TLogStrDialog::SetFilePath(AnsiString path) -{ - AnsiString str; - double swap; - if (TimeTagC->Checked) path+="::T"; - str=SwapIntv->Text; - if (sscanf(str.c_str(),"%lf",&swap)>=1) { - path+="::S="+str; - } - return path; -} -//--------------------------------------------------------------------------- -void __fastcall TLogStrDialog::SerialOpt(int index, int opt) -{ - SerialOptDialog->Path=Paths[index][0]; - SerialOptDialog->Opt=opt; - if (SerialOptDialog->ShowModal()!=mrOk) return; - Paths[index][0]=SerialOptDialog->Path; -} -//--------------------------------------------------------------------------- -void __fastcall TLogStrDialog::TcpOpt(int index, int opt) -{ - TcpOptDialog->Path=Paths[index][1]; - TcpOptDialog->Opt=opt; - for (int i=0;i<10;i++) { - TcpOptDialog->History[i]=History[i]; - } - if (TcpOptDialog->ShowModal()!=mrOk) return; - Paths[index][1]=TcpOptDialog->Path; - for (int i=0;i<10;i++) { - History[i]=TcpOptDialog->History[i]; - } -} -//--------------------------------------------------------------------------- -void __fastcall TLogStrDialog::UpdateEnable(void) -{ - int ena=(Stream1C->Checked&&Stream1->ItemIndex==5)|| - (Stream2C->Checked&&Stream2->ItemIndex==5)|| - (Stream3C->Checked&&Stream3->ItemIndex==5); - Stream1 ->Enabled=Stream1C->Checked; - Stream2 ->Enabled=Stream2C->Checked; - Stream3 ->Enabled=Stream3C->Checked; - BtnStr1 ->Enabled=Stream1C->Checked&&Stream1->ItemIndex<=4; - BtnStr2 ->Enabled=Stream2C->Checked&&Stream2->ItemIndex<=4; - BtnStr3 ->Enabled=Stream3C->Checked&&Stream3->ItemIndex<=4; - FilePath1->Enabled=Stream1C->Checked&&Stream1->ItemIndex==5; - FilePath2->Enabled=Stream2C->Checked&&Stream2->ItemIndex==5; - FilePath3->Enabled=Stream3C->Checked&&Stream3->ItemIndex==5; - BtnFile1 ->Enabled=Stream1C->Checked&&Stream1->ItemIndex==5; - BtnFile2 ->Enabled=Stream2C->Checked&&Stream2->ItemIndex==5; - BtnFile3 ->Enabled=Stream3C->Checked&&Stream3->ItemIndex==5; - Label1 ->Enabled=ena; - Label2 ->Enabled=ena; - LabelF1 ->Enabled=ena; - TimeTagC ->Enabled=ena; - SwapIntv ->Enabled=ena; - BtnKey ->Enabled=ena; - OutEventC->Enabled=FilePath1->Enabled; -} -//--------------------------------------------------------------------------- - diff --git a/app/winapp/rtknavi/logstrdlg.h b/app/winapp/rtknavi/logstrdlg.h index f37d9a38a..2c8bcd85a 100644 --- a/app/winapp/rtknavi/logstrdlg.h +++ b/app/winapp/rtknavi/logstrdlg.h @@ -2,70 +2,70 @@ #ifndef logstrdlgH #define logstrdlgH //--------------------------------------------------------------------------- +#include #include #include -#include -#include #include -#include +#include +#include //--------------------------------------------------------------------------- -class TLogStrDialog : public TForm -{ -__published: - TButton *BtnCancel; - TButton *BtnOk; - TLabel *Label5; - TLabel *Label6; - TLabel *Label10; - TComboBox *Stream1; - TComboBox *Stream2; - TButton *BtnStr1; - TButton *BtnStr2; - TEdit *FilePath1; - TEdit *FilePath2; - TButton *BtnFile1; - TButton *BtnFile2; - TLabel *LabelF1; - TSaveDialog *SaveDialog; - TCheckBox *TimeTagC; - TCheckBox *Stream1C; - TCheckBox *Stream2C; - TSpeedButton *BtnKey; - TCheckBox *Stream3C; - TComboBox *Stream3; - TButton *BtnStr3; - TEdit *FilePath3; - TButton *BtnFile3; - TComboBox *SwapIntv; - TLabel *Label1; - TLabel *Label2; - TCheckBox *OutEventC; - void __fastcall BtnOkClick(TObject *Sender); - void __fastcall FormShow(TObject *Sender); - void __fastcall Stream1Change(TObject *Sender); - void __fastcall Stream2Change(TObject *Sender); - void __fastcall BtnStr1Click(TObject *Sender); - void __fastcall BtnStr2Click(TObject *Sender); - void __fastcall BtnFile1Click(TObject *Sender); - void __fastcall BtnFile2Click(TObject *Sender); - void __fastcall Stream1CClick(TObject *Sender); - void __fastcall Stream2CClick(TObject *Sender); - void __fastcall BtnKeyClick(TObject *Sender); - void __fastcall BtnStr3Click(TObject *Sender); - void __fastcall BtnFile3Click(TObject *Sender); - void __fastcall Stream3CClick(TObject *Sender); - void __fastcall Stream3Change(TObject *Sender); -private: - AnsiString __fastcall GetFilePath(AnsiString path); - AnsiString __fastcall SetFilePath(AnsiString path); - void __fastcall SerialOpt(int index, int opt); - void __fastcall TcpOpt(int index, int opt); - void __fastcall UpdateEnable(void); -public: - int StreamC[3],Stream[3],LogTimeTag,LogAppend; - AnsiString Paths[3][4],SwapInterval; - AnsiString History[10]; - __fastcall TLogStrDialog(TComponent* Owner); +class TLogStrDialog : public TForm { + __published : TButton *BtnCancel; + TButton *BtnOk; + TLabel *Label5; + TLabel *Label6; + TLabel *Label10; + TComboBox *Stream1; + TComboBox *Stream2; + TButton *BtnStr1; + TButton *BtnStr2; + TEdit *FilePath1; + TEdit *FilePath2; + TButton *BtnFile1; + TButton *BtnFile2; + TLabel *LabelF1; + TSaveDialog *SaveDialog; + TCheckBox *TimeTagC; + TCheckBox *Stream1C; + TCheckBox *Stream2C; + TSpeedButton *BtnKey; + TCheckBox *Stream3C; + TComboBox *Stream3; + TButton *BtnStr3; + TEdit *FilePath3; + TButton *BtnFile3; + TComboBox *SwapIntv; + TLabel *Label1; + TLabel *Label2; + TCheckBox *OutEventC; + void __fastcall BtnOkClick(TObject *Sender); + void __fastcall FormShow(TObject *Sender); + void __fastcall Stream1Change(TObject *Sender); + void __fastcall Stream2Change(TObject *Sender); + void __fastcall BtnStr1Click(TObject *Sender); + void __fastcall BtnStr2Click(TObject *Sender); + void __fastcall BtnFile1Click(TObject *Sender); + void __fastcall BtnFile2Click(TObject *Sender); + void __fastcall Stream1CClick(TObject *Sender); + void __fastcall Stream2CClick(TObject *Sender); + void __fastcall BtnKeyClick(TObject *Sender); + void __fastcall BtnStr3Click(TObject *Sender); + void __fastcall BtnFile3Click(TObject *Sender); + void __fastcall Stream3CClick(TObject *Sender); + void __fastcall Stream3Change(TObject *Sender); + + private: + AnsiString __fastcall GetFilePath(AnsiString path); + AnsiString __fastcall SetFilePath(AnsiString path); + void __fastcall SerialOpt(int index, int opt); + void __fastcall TcpOpt(int index, int opt); + void __fastcall UpdateEnable(void); + + public: + int StreamC[3], Stream[3], LogTimeTag, LogAppend; + AnsiString Paths[3][4], SwapInterval; + AnsiString History[10]; + __fastcall TLogStrDialog(TComponent *Owner); }; //--------------------------------------------------------------------------- extern PACKAGE TLogStrDialog *LogStrDialog; diff --git a/app/winapp/rtknavi/mapdlg.cpp b/app/winapp/rtknavi/mapdlg.cpp index 0d0241c99..19b4049e1 100644 --- a/app/winapp/rtknavi/mapdlg.cpp +++ b/app/winapp/rtknavi/mapdlg.cpp @@ -2,477 +2,456 @@ #include #pragma hdrstop -#include "rtklib.h" +#include "mapdlg.h" + #include "navimain.h" #include "pntdlg.h" -#include "mapdlg.h" +#include "rtklib.h" //--------------------------------------------------------------------------- #pragma package(smart_init) #pragma resource "*.dfm" TMapDialog *MapDialog; -#define CHARDEG "\260" // character code of degree -#define CLORANGE (TColor)0x00AAFF -#define CLLGRAY (TColor)0xDDDDDD -#define SOLSIZE 13 // solution cycle size on map -#define PNTSIZE 10 // point cycle size on map -#define HISSIZE 4 // history cycle size on map -#define VELSIZE 40 // velocity cycle size on map -#define GRPHEIGHT 70 // vertical graph height -#define GRPHMARGIN 60 // vertical graph horizontal margin +#define CHARDEG "\260" // character code of degree +#define CLORANGE (TColor)0x00AAFF +#define CLLGRAY (TColor)0xDDDDDD +#define SOLSIZE 13 // solution cycle size on map +#define PNTSIZE 10 // point cycle size on map +#define HISSIZE 4 // history cycle size on map +#define VELSIZE 40 // velocity cycle size on map +#define GRPHEIGHT 70 // vertical graph height +#define GRPHMARGIN 60 // vertical graph horizontal margin //--------------------------------------------------------------------------- -__fastcall TMapDialog::TMapDialog(TComponent* Owner) - : TForm(Owner) -{ - Plot=new Graphics::TBitmap; - Scale=6; - PntIndex=0; - DoubleBuffered=true; - for (int i=0;i<3;i++) { - RefPos[i]=CurrentPos[i]=CentPos[i]=0.0; - } - RefName="Start Point"; +__fastcall TMapDialog::TMapDialog(TComponent *Owner) : TForm(Owner) { + Plot = new Graphics::TBitmap; + Scale = 6; + PntIndex = 0; + DoubleBuffered = true; + for (int i = 0; i < 3; i++) { + RefPos[i] = CurrentPos[i] = CentPos[i] = 0.0; + } + RefName = "Start Point"; } //--------------------------------------------------------------------------- -void __fastcall TMapDialog::FormShow(TObject *Sender) -{ - UpdatePntList(); - UpdateEnable(); +void __fastcall TMapDialog::FormShow(TObject *Sender) { + UpdatePntList(); + UpdateEnable(); } //--------------------------------------------------------------------------- -void __fastcall TMapDialog::BtnCloseClick(TObject *Sender) -{ - Close(); -} +void __fastcall TMapDialog::BtnCloseClick(TObject *Sender) { Close(); } //--------------------------------------------------------------------------- -void __fastcall TMapDialog::BtnShrinkClick(TObject *Sender) -{ - if (ScaleUpdateMap(); +void __fastcall TMapDialog::BtnShrinkClick(TObject *Sender) { + if (Scale < MAXSCALE) Scale++; + MainForm->UpdateMap(); } //--------------------------------------------------------------------------- -void __fastcall TMapDialog::BtnExpandClick(TObject *Sender) -{ - if (Scale>0) Scale--; - MainForm->UpdateMap(); +void __fastcall TMapDialog::BtnExpandClick(TObject *Sender) { + if (Scale > 0) Scale--; + MainForm->UpdateMap(); } //--------------------------------------------------------------------------- -void __fastcall TMapDialog::BtnPntClick(TObject *Sender) -{ - UpdateEnable(); -} +void __fastcall TMapDialog::BtnPntClick(TObject *Sender) { UpdateEnable(); } //--------------------------------------------------------------------------- -void __fastcall TMapDialog::PntListChange(TObject *Sender) -{ - PntIndex=PntList->ItemIndex; - MainForm->UpdateMap(); +void __fastcall TMapDialog::PntListChange(TObject *Sender) { + PntIndex = PntList->ItemIndex; + MainForm->UpdateMap(); } //--------------------------------------------------------------------------- -void __fastcall TMapDialog::BtnCenterClick(TObject *Sender) -{ - if (!BtnCenter->Down) { - for (int i=0;i<3;i++) CentPos[i]=CurrentPos[i]; - } - MainForm->UpdateMap(); +void __fastcall TMapDialog::BtnCenterClick(TObject *Sender) { + if (!BtnCenter->Down) { + for (int i = 0; i < 3; i++) CentPos[i] = CurrentPos[i]; + } + MainForm->UpdateMap(); } //--------------------------------------------------------------------------- -void __fastcall TMapDialog::BtnTrackClick(TObject *Sender) -{ - MainForm->UpdateMap(); -} +void __fastcall TMapDialog::BtnTrackClick(TObject *Sender) { MainForm->UpdateMap(); } //--------------------------------------------------------------------------- -void __fastcall TMapDialog::BtnPntDlgClick(TObject *Sender) -{ - PntDialog->Left=Left+Width/2-PntDialog->Width/2; - PntDialog->Top=Top+Height/2-PntDialog->Height/2; - if (PntDialog->ShowModal()!=mrOk) return; - UpdatePntList(); - MainForm->UpdateMap(); +void __fastcall TMapDialog::BtnPntDlgClick(TObject *Sender) { + PntDialog->Left = Left + Width / 2 - PntDialog->Width / 2; + PntDialog->Top = Top + Height / 2 - PntDialog->Height / 2; + if (PntDialog->ShowModal() != mrOk) return; + UpdatePntList(); + MainForm->UpdateMap(); } //--------------------------------------------------------------------------- -void __fastcall TMapDialog::FormResize(TObject *Sender) -{ - Plot->SetSize(Disp->ClientWidth,Disp->ClientHeight); - MainForm->UpdateMap(); +void __fastcall TMapDialog::FormResize(TObject *Sender) { + Plot->SetSize(Disp->ClientWidth, Disp->ClientHeight); + MainForm->UpdateMap(); } //--------------------------------------------------------------------------- -void __fastcall TMapDialog::DispMouseDown(TObject *Sender, TMouseButton Button, - TShiftState Shift, int X, int Y) -{ - if (BtnCenter->Down||!Shift.Contains(ssLeft)) return; - Drag=1; - X0=X; - Y0=Y; - for (int i=0;i<3;i++) CentPos0[i]=CentPos[i]; - Screen->Cursor=crSizeAll; +void __fastcall TMapDialog::DispMouseDown(TObject *Sender, TMouseButton Button, TShiftState Shift, + int X, int Y) { + if (BtnCenter->Down || !Shift.Contains(ssLeft)) return; + Drag = 1; + X0 = X; + Y0 = Y; + for (int i = 0; i < 3; i++) CentPos0[i] = CentPos[i]; + Screen->Cursor = crSizeAll; } //--------------------------------------------------------------------------- -void __fastcall TMapDialog::DispMouseMove(TObject *Sender, TShiftState Shift, - int X, int Y) -{ - double sc[]={ - 0.01,0.02,0.05,0.1,0.2,0.5,1,2,5,10,20,50,100,200,500,1000,2000,5000,10000 - }; - double rr[3],posr[3],enu[3],fact=40.0/sc[Scale]; - if (!Drag) return; - enu[0]=(X0-X)/fact; - enu[1]=(Y-Y0)/fact; - enu[2]=0.0; - ecef2pos(RefPos,posr); - enu2ecef(posr,enu,rr); - for (int i=0;i<3;i++) CentPos[i]=CentPos0[i]+rr[i]; - MainForm->UpdateMap(); +void __fastcall TMapDialog::DispMouseMove(TObject *Sender, TShiftState Shift, int X, int Y) { + double sc[] = {0.01, 0.02, 0.05, 0.1, 0.2, 0.5, 1, 2, 5, 10, + 20, 50, 100, 200, 500, 1000, 2000, 5000, 10000}; + double rr[3], posr[3], enu[3], fact = 40.0 / sc[Scale]; + if (!Drag) return; + enu[0] = (X0 - X) / fact; + enu[1] = (Y - Y0) / fact; + enu[2] = 0.0; + ecef2pos(RefPos, posr); + enu2ecef(posr, enu, rr); + for (int i = 0; i < 3; i++) CentPos[i] = CentPos0[i] + rr[i]; + MainForm->UpdateMap(); } //--------------------------------------------------------------------------- -void __fastcall TMapDialog::DispMouseUp(TObject *Sender, TMouseButton Button, - TShiftState Shift, int X, int Y) -{ - if (Drag) Screen->Cursor=crDefault; - Drag=0; +void __fastcall TMapDialog::DispMouseUp(TObject *Sender, TMouseButton Button, TShiftState Shift, + int X, int Y) { + if (Drag) Screen->Cursor = crDefault; + Drag = 0; } //--------------------------------------------------------------------------- -void __fastcall TMapDialog::DispPaint(TObject *Sender) -{ - TRect r=Disp->ClientRect; - Disp->Canvas->CopyRect(r,Plot->Canvas,r); +void __fastcall TMapDialog::DispPaint(TObject *Sender) { + TRect r = Disp->ClientRect; + Disp->Canvas->CopyRect(r, Plot->Canvas, r); } //--------------------------------------------------------------------------- -void __fastcall TMapDialog::ResetRef(void) -{ - RefName="Start Point"; - UpdatePntList(); - for (int i=0;i<3;i++) RefPos[i]=0.0; +void __fastcall TMapDialog::ResetRef(void) { + RefName = "Start Point"; + UpdatePntList(); + for (int i = 0; i < 3; i++) RefPos[i] = 0.0; } //--------------------------------------------------------------------------- -void __fastcall TMapDialog::UpdateMap(const double *sol, const double *ref, - const double *vel, const int *stat, int psol, int psols, int psole, - int nsol, AnsiString *solstr, int currentstat) -{ - TColor color[]={clWhite,clGreen,CLORANGE,clFuchsia,clBlue,clRed,clTeal}; - TCanvas *c=Plot->Canvas; - AnsiString s; - TPoint p0; - double pos[3],posr[3],rr[3],enu[3],enuv[3],dr[3],dir,*pntpos; - int gint[]={20,20,16,20,20,16,20,20,16,20,20,16,20,20,16,20,20,16,20}; - int ng[]={10,5,5,10,5,5,10,5,5,10,5,5,10,5,5,10,5,5,10}; - TColor colsol=color[stat[psol]]; - - TRect r(0,0,Plot->Width,Plot->Height); - c->Brush->Style=bsSolid; - c->Brush->Color=clWhite; - c->FillRect(r); - - for (int i=0;i<3;i++) { - CurrentPos[i]=sol[i+psol*3]; - } - if (norm(RefPos,3)<=0.0) { - if (ref&&norm(ref+psol,3)>0.0) { - RefName="Base Station"; - for (int i=0;i<3;i++) RefPos[i]=ref[i+psol*3]; - UpdatePntList(); - } - else { - for (int i=0;i<3;i++) RefPos[i]=CurrentPos[i]; - } - } - ecef2pos(RefPos,posr); - ecef2enu(posr,vel+psol*3,enuv); - - DrawGrid(PosToPoint(RefPos),gint[Scale],ng[Scale],CLLGRAY,clSilver); - - if (BtnPnt->Down) { - for (int i=0;iNMapPnt+1;i++) { - DrawPoint(i==0?RefPos:MainForm->PntPos[i-1],PntList->Items->Strings[i], - i==PntIndex?clGray:clSilver); - } - } - if (BtnTrack->Down) { - TPoint *p =new TPoint[nsol]; - TColor *col=new TColor[nsol]; - int n=0; - for (int i=psols;i!=psole;) { - p[n]=PosToPoint(sol+i*3); - col[n++]=color[stat[i]]; - if (++i>=nsol) i=0; - } - c->Pen->Color=CLLGRAY; - c->Pen->Style=psSolid; - c->Polyline(p,n-1); - for (int i=0;iPen->Color=clBlack; - c->MoveTo(p0.x-SOLSIZE/2-4,p0.y); c->LineTo(p0.x+SOLSIZE/2+4,p0.y); - c->MoveTo(p0.x,p0.y-SOLSIZE/2-4); c->LineTo(p0.x,p0.y+SOLSIZE/2+4); - DrawCircle(p0,SOLSIZE+4,clBlack,clWhite); - DrawCircle(p0,SOLSIZE,clBlack,color[currentstat]); - - DrawVel(enuv); - DrawScale(); - - c->Brush->Style=bsSolid; - c->Brush->Color=clWhite; - DrawText(6,1,solstr[0],currentstat?colsol:clGray,0); - TSize off=c->TextExtent(solstr[2]); - DrawText(Plot->Width-off.cx-6,1,solstr[2],clGray,0); - DrawText(50,1,solstr[1],clBlack,0); - - if (BtnPnt->Down) { - pntpos=PntIndex>0?MainForm->PntPos[PntIndex-1]:RefPos; - for (int i=0;i<3;i++) { - rr[i]=pntpos[i]-CurrentPos[i]; - } - ecef2pos(pntpos,pos); - ecef2enu(posr,rr,enu); - dir=norm(enu,2)<1E-9?0.0:atan2(enu[0],enu[1])*R2D; - if (dir<0.0) dir+=360.0; - s.sprintf("To %s: Distance %.3fm Direction %.1f%s", - PntList->Items->Strings[PntIndex].c_str(),norm(enu,2),dir,CHARDEG); - int y=Plot->Height-off.cy/2-2; - if (BtnGraph->Down) y-=GRPHEIGHT+2; - DrawText(Plot->Width/2,y,s,clGray,1); - } - if (BtnGraph->Down) { - DrawVertGraph(sol,stat,psol,psols,psole, nsol,currentstat); - } - Disp->Invalidate(); +void __fastcall TMapDialog::UpdateMap(const double *sol, const double *ref, const double *vel, + const int *stat, int psol, int psols, int psole, int nsol, + AnsiString *solstr, int currentstat) { + TColor color[] = {clWhite, clGreen, CLORANGE, clFuchsia, clBlue, clRed, clTeal}; + TCanvas *c = Plot->Canvas; + AnsiString s; + TPoint p0; + double pos[3], posr[3], rr[3], enu[3], enuv[3], dr[3], dir, *pntpos; + int gint[] = {20, 20, 16, 20, 20, 16, 20, 20, 16, 20, 20, 16, 20, 20, 16, 20, 20, 16, 20}; + int ng[] = {10, 5, 5, 10, 5, 5, 10, 5, 5, 10, 5, 5, 10, 5, 5, 10, 5, 5, 10}; + TColor colsol = color[stat[psol]]; + + TRect r(0, 0, Plot->Width, Plot->Height); + c->Brush->Style = bsSolid; + c->Brush->Color = clWhite; + c->FillRect(r); + + for (int i = 0; i < 3; i++) { + CurrentPos[i] = sol[i + psol * 3]; + } + if (norm(RefPos, 3) <= 0.0) { + if (ref && norm(ref + psol, 3) > 0.0) { + RefName = "Base Station"; + for (int i = 0; i < 3; i++) RefPos[i] = ref[i + psol * 3]; + UpdatePntList(); + } else { + for (int i = 0; i < 3; i++) RefPos[i] = CurrentPos[i]; + } + } + ecef2pos(RefPos, posr); + ecef2enu(posr, vel + psol * 3, enuv); + + DrawGrid(PosToPoint(RefPos), gint[Scale], ng[Scale], CLLGRAY, clSilver); + + if (BtnPnt->Down) { + for (int i = 0; i < MainForm->NMapPnt + 1; i++) { + DrawPoint(i == 0 ? RefPos : MainForm->PntPos[i - 1], PntList->Items->Strings[i], + i == PntIndex ? clGray : clSilver); + } + } + if (BtnTrack->Down) { + TPoint *p = new TPoint[nsol]; + TColor *col = new TColor[nsol]; + int n = 0; + for (int i = psols; i != psole;) { + p[n] = PosToPoint(sol + i * 3); + col[n++] = color[stat[i]]; + if (++i >= nsol) i = 0; + } + c->Pen->Color = CLLGRAY; + c->Pen->Style = psSolid; + c->Polyline(p, n - 1); + for (int i = 0; i < n; i++) { + DrawCircle(p[i], HISSIZE, col[i], col[i]); + } + delete[] p; + delete[] col; + } + p0 = PosToPoint(CurrentPos); + c->Pen->Color = clBlack; + c->MoveTo(p0.x - SOLSIZE / 2 - 4, p0.y); + c->LineTo(p0.x + SOLSIZE / 2 + 4, p0.y); + c->MoveTo(p0.x, p0.y - SOLSIZE / 2 - 4); + c->LineTo(p0.x, p0.y + SOLSIZE / 2 + 4); + DrawCircle(p0, SOLSIZE + 4, clBlack, clWhite); + DrawCircle(p0, SOLSIZE, clBlack, color[currentstat]); + + DrawVel(enuv); + DrawScale(); + + c->Brush->Style = bsSolid; + c->Brush->Color = clWhite; + DrawText(6, 1, solstr[0], currentstat ? colsol : clGray, 0); + TSize off = c->TextExtent(solstr[2]); + DrawText(Plot->Width - off.cx - 6, 1, solstr[2], clGray, 0); + DrawText(50, 1, solstr[1], clBlack, 0); + + if (BtnPnt->Down) { + pntpos = PntIndex > 0 ? MainForm->PntPos[PntIndex - 1] : RefPos; + for (int i = 0; i < 3; i++) { + rr[i] = pntpos[i] - CurrentPos[i]; + } + ecef2pos(pntpos, pos); + ecef2enu(posr, rr, enu); + dir = norm(enu, 2) < 1E-9 ? 0.0 : atan2(enu[0], enu[1]) * R2D; + if (dir < 0.0) dir += 360.0; + s.sprintf("To %s: Distance %.3fm Direction %.1f%s", PntList->Items->Strings[PntIndex].c_str(), + norm(enu, 2), dir, CHARDEG); + int y = Plot->Height - off.cy / 2 - 2; + if (BtnGraph->Down) y -= GRPHEIGHT + 2; + DrawText(Plot->Width / 2, y, s, clGray, 1); + } + if (BtnGraph->Down) { + DrawVertGraph(sol, stat, psol, psols, psole, nsol, currentstat); + } + Disp->Invalidate(); } //--------------------------------------------------------------------------- -void __fastcall TMapDialog::DrawVertGraph(const double *sol, - const int *stat, int psol, int psols, int psole, int nsol, int currentstat) -{ - TColor color[]={clWhite,clGreen,CLORANGE,clFuchsia,clBlue,clRed}; - TCanvas *c=Plot->Canvas; - TRect rg(GRPHMARGIN,Plot->Height-GRPHEIGHT-2,Plot->Width-GRPHMARGIN,Plot->Height-2); - TPoint *p=new TPoint[nsol],p0; - TColor *col=new TColor[nsol]; - int n=0,m=0; - - for (int i=psols;i!=psole;) { - n++; if (++i>=nsol) i=0; - } - for (int i=psols;i!=psole;) { - p[m]=PosToGraphP(sol+i*3,sol+psol*3,nsol-n+m,nsol,rg); - if (i==psol) p0=p[m]; - col[m++]=color[stat[i]]; - if (++i>=nsol) i=0; - } - c->Brush->Style=bsSolid; - c->Brush->Color=clWhite; - c->FillRect(rg); - c->Pen->Color=clSilver; - c->Pen->Style=psSolid; - c->Rectangle(rg); - c->MoveTo(rg.Left,(rg.Top+rg.Bottom)/2); - c->LineTo(rg.Right,(rg.Top+rg.Bottom)/2); - c->Pen->Color=clSilver; - c->MoveTo(p0.x,rg.Bottom); c->LineTo(p0.x,rg.Top); - for (int i=0;iMoveTo(x,y-HISSIZE); c->LineTo(x,y+HISSIZE); - } - int i,j; - for (i=0;iPolyline(p+i,j-i-1); - for (;jCanvas; + TRect rg(GRPHMARGIN, Plot->Height - GRPHEIGHT - 2, Plot->Width - GRPHMARGIN, Plot->Height - 2); + TPoint *p = new TPoint[nsol], p0; + TColor *col = new TColor[nsol]; + int n = 0, m = 0; + + for (int i = psols; i != psole;) { + n++; + if (++i >= nsol) i = 0; + } + for (int i = psols; i != psole;) { + p[m] = PosToGraphP(sol + i * 3, sol + psol * 3, nsol - n + m, nsol, rg); + if (i == psol) p0 = p[m]; + col[m++] = color[stat[i]]; + if (++i >= nsol) i = 0; + } + c->Brush->Style = bsSolid; + c->Brush->Color = clWhite; + c->FillRect(rg); + c->Pen->Color = clSilver; + c->Pen->Style = psSolid; + c->Rectangle(rg); + c->MoveTo(rg.Left, (rg.Top + rg.Bottom) / 2); + c->LineTo(rg.Right, (rg.Top + rg.Bottom) / 2); + c->Pen->Color = clSilver; + c->MoveTo(p0.x, rg.Bottom); + c->LineTo(p0.x, rg.Top); + for (int i = 0; i < nsol; i++) { + if (i % 100) continue; + int x = rg.Left + (rg.Right - rg.Left) * ((nsol + i - psole) % nsol) / nsol; + int y = (rg.Top + rg.Bottom) / 2; + c->MoveTo(x, y - HISSIZE); + c->LineTo(x, y + HISSIZE); + } + int i, j; + for (i = 0; i < m; i = j) { + for (j = i; j < m; j++) { + if (p[j].y < rg.Top + HISSIZE / 2 || rg.Bottom - HISSIZE / 2 < p[j].y) break; + } + if (i < j) c->Polyline(p + i, j - i - 1); + for (; j < m; j++) { + if (rg.Top + HISSIZE / 2 <= p[j].y && p[j].y <= rg.Bottom - HISSIZE / 2) break; + } + } + for (int i = 0; i < m; i++) { + if (p[i].y < rg.Top + HISSIZE / 2 || rg.Bottom - HISSIZE / 2 < p[i].y) continue; + DrawCircle(p[i], HISSIZE, col[i], col[i]); + } + DrawCircle(p0, HISSIZE + 6, clBlack, color[currentstat]); + delete[] p; + delete[] col; } //--------------------------------------------------------------------------- -TPoint __fastcall TMapDialog::PosToPoint(const double *pos) -{ - double sc[]={ - 0.01,0.02,0.05,0.1,0.2,0.5,1,2,5,10,20,50,100,200,500,1000,2000,5000,10000 - }; - double rr[3],posr[3],enu[3],fact=40.0/sc[Scale]; - TPoint p; - ecef2pos(RefPos,posr); - for (int i=0;i<3;i++) rr[i]=pos[i]-RefPos[i]; - ecef2enu(posr,rr,enu); - p.x=Plot->Width /2+(int)(enu[0]*fact+0.5); - p.y=Plot->Height/2-(int)(enu[1]*fact+0.5); - if (BtnCenter->Down) { - for (int i=0;i<3;i++) rr[i]=CurrentPos[i]-RefPos[i]; - ecef2enu(posr,rr,enu); - p.x-=(int)(enu[0]*fact+0.5); - p.y+=(int)(enu[1]*fact+0.5); - } - else if (norm(CentPos,3)>0.0) { - for (int i=0;i<3;i++) rr[i]=CentPos[i]-RefPos[i]; - ecef2enu(posr,rr,enu); - p.x-=(int)(enu[0]*fact+0.5); - p.y+=(int)(enu[1]*fact+0.5); - } - return p; +TPoint __fastcall TMapDialog::PosToPoint(const double *pos) { + double sc[] = {0.01, 0.02, 0.05, 0.1, 0.2, 0.5, 1, 2, 5, 10, + 20, 50, 100, 200, 500, 1000, 2000, 5000, 10000}; + double rr[3], posr[3], enu[3], fact = 40.0 / sc[Scale]; + TPoint p; + ecef2pos(RefPos, posr); + for (int i = 0; i < 3; i++) rr[i] = pos[i] - RefPos[i]; + ecef2enu(posr, rr, enu); + p.x = Plot->Width / 2 + (int)(enu[0] * fact + 0.5); + p.y = Plot->Height / 2 - (int)(enu[1] * fact + 0.5); + if (BtnCenter->Down) { + for (int i = 0; i < 3; i++) rr[i] = CurrentPos[i] - RefPos[i]; + ecef2enu(posr, rr, enu); + p.x -= (int)(enu[0] * fact + 0.5); + p.y += (int)(enu[1] * fact + 0.5); + } else if (norm(CentPos, 3) > 0.0) { + for (int i = 0; i < 3; i++) rr[i] = CentPos[i] - RefPos[i]; + ecef2enu(posr, rr, enu); + p.x -= (int)(enu[0] * fact + 0.5); + p.y += (int)(enu[1] * fact + 0.5); + } + return p; } //--------------------------------------------------------------------------- -TPoint __fastcall TMapDialog::PosToGraphP(const double *pos, - const double *ref, int index, int npos, TRect rect) -{ - double sc[]={ - 0.01,0.02,0.05,0.1,0.2,0.5,1,2,5,10,20,50,100,200,500,1000,2000,5000,10000 - }; - double rr[3],posr[3],enu[3],fact=40.0/sc[Scale]; - TPoint p; - ecef2pos(ref,posr); - for (int i=0;i<3;i++) rr[i]=pos[i]-ref[i]; - ecef2enu(posr,rr,enu); - p.x=rect.Left+(int)((rect.Right-rect.Left)*index/(npos-1.0)+0.5); - p.y=(rect.Top+rect.Bottom)/2-(int)(enu[2]*fact+0.5); - return p; +TPoint __fastcall TMapDialog::PosToGraphP(const double *pos, const double *ref, int index, int npos, + TRect rect) { + double sc[] = {0.01, 0.02, 0.05, 0.1, 0.2, 0.5, 1, 2, 5, 10, + 20, 50, 100, 200, 500, 1000, 2000, 5000, 10000}; + double rr[3], posr[3], enu[3], fact = 40.0 / sc[Scale]; + TPoint p; + ecef2pos(ref, posr); + for (int i = 0; i < 3; i++) rr[i] = pos[i] - ref[i]; + ecef2enu(posr, rr, enu); + p.x = rect.Left + (int)((rect.Right - rect.Left) * index / (npos - 1.0) + 0.5); + p.y = (rect.Top + rect.Bottom) / 2 - (int)(enu[2] * fact + 0.5); + return p; } //--------------------------------------------------------------------------- -void __fastcall TMapDialog::DrawPoint(const double *pos, AnsiString name, - TColor color) -{ - TCanvas *c=Plot->Canvas; - TPoint p=PosToPoint(pos); - TSize off=c->TextExtent(name); - c->Brush->Style=bsSolid; - DrawCircle(p,PNTSIZE,color,color); - c->Pen->Color=color; - c->MoveTo(p.x-PNTSIZE/2-4,p.y); c->LineTo(p.x+PNTSIZE/2+4,p.y); - c->MoveTo(p.x,p.y-PNTSIZE/2-4); c->LineTo(p.x,p.y+PNTSIZE/2+4); - c->Brush->Style=bsClear; - DrawText(p.x,p.y+PNTSIZE/2+off.cy/2+1,name,color,1); +void __fastcall TMapDialog::DrawPoint(const double *pos, AnsiString name, TColor color) { + TCanvas *c = Plot->Canvas; + TPoint p = PosToPoint(pos); + TSize off = c->TextExtent(name); + c->Brush->Style = bsSolid; + DrawCircle(p, PNTSIZE, color, color); + c->Pen->Color = color; + c->MoveTo(p.x - PNTSIZE / 2 - 4, p.y); + c->LineTo(p.x + PNTSIZE / 2 + 4, p.y); + c->MoveTo(p.x, p.y - PNTSIZE / 2 - 4); + c->LineTo(p.x, p.y + PNTSIZE / 2 + 4); + c->Brush->Style = bsClear; + DrawText(p.x, p.y + PNTSIZE / 2 + off.cy / 2 + 1, name, color, 1); } //--------------------------------------------------------------------------- -void __fastcall TMapDialog::DrawVel(const double *vel) -{ - TCanvas *c=Plot->Canvas; - AnsiString s; - double v,ang; - TPoint p; - TColor color=clGray; - - p.x=VELSIZE/2+10; - p.y=Plot->Height-VELSIZE/2-15; - c->Brush->Style=bsClear; - if ((v=norm(vel,3))>1.0) { - ang=atan2(vel[0],vel[1])*R2D; - DrawArrow(p,VELSIZE-2,(int)ang,color); - } - DrawCircle(p,VELSIZE,color,(TColor)-1); - DrawCircle(p,9,color,clWhite); - DrawText(p.x,p.y-VELSIZE/2-7,"N",color,1); - DrawText(p.x,p.y+VELSIZE/2+7,s.sprintf("%.0f km/h",v*3.6),color,1); +void __fastcall TMapDialog::DrawVel(const double *vel) { + TCanvas *c = Plot->Canvas; + AnsiString s; + double v, ang; + TPoint p; + TColor color = clGray; + + p.x = VELSIZE / 2 + 10; + p.y = Plot->Height - VELSIZE / 2 - 15; + c->Brush->Style = bsClear; + if ((v = norm(vel, 3)) > 1.0) { + ang = atan2(vel[0], vel[1]) * R2D; + DrawArrow(p, VELSIZE - 2, (int)ang, color); + } + DrawCircle(p, VELSIZE, color, (TColor)-1); + DrawCircle(p, 9, color, clWhite); + DrawText(p.x, p.y - VELSIZE / 2 - 7, "N", color, 1); + DrawText(p.x, p.y + VELSIZE / 2 + 7, s.sprintf("%.0f km/h", v * 3.6), color, 1); } //--------------------------------------------------------------------------- -void __fastcall TMapDialog::DrawScale(void) -{ - TCanvas *c=Plot->Canvas; - AnsiString s; - double sc[]={ - 0.01,0.02,0.05,0.1,0.2,0.5,1,2,5,10,20,50,100,200,500,1000,2000,5000,10000 - }; - int pc[][2]={{-20,-4},{-20,4},{-20,0},{20,0},{20,-4},{20,4}}; - int x=Plot->Width-35,y=Plot->Height-15; - TPoint p[6]; - - for (int i=0;i<6;i++) { - p[i].x=x+pc[i][0]; - p[i].y=y+pc[i][1]; - } - c->Pen->Color=clGray; - c->Polyline(p,5); - c->Brush->Style=bsClear; - char *unit="m"; - double sf=sc[Scale]; - if (sf<1.0) {sf*=100.0; unit="cm";} - else if (sf>=1000.0) {sf/=1000.0; unit="km";} - DrawText(x,y-10,s.sprintf("%.0f %s",sf,unit),clGray,1); +void __fastcall TMapDialog::DrawScale(void) { + TCanvas *c = Plot->Canvas; + AnsiString s; + double sc[] = {0.01, 0.02, 0.05, 0.1, 0.2, 0.5, 1, 2, 5, 10, + 20, 50, 100, 200, 500, 1000, 2000, 5000, 10000}; + int pc[][2] = {{-20, -4}, {-20, 4}, {-20, 0}, {20, 0}, {20, -4}, {20, 4}}; + int x = Plot->Width - 35, y = Plot->Height - 15; + TPoint p[6]; + + for (int i = 0; i < 6; i++) { + p[i].x = x + pc[i][0]; + p[i].y = y + pc[i][1]; + } + c->Pen->Color = clGray; + c->Polyline(p, 5); + c->Brush->Style = bsClear; + char *unit = "m"; + double sf = sc[Scale]; + if (sf < 1.0) { + sf *= 100.0; + unit = "cm"; + } else if (sf >= 1000.0) { + sf /= 1000.0; + unit = "km"; + } + DrawText(x, y - 10, s.sprintf("%.0f %s", sf, unit), clGray, 1); } //--------------------------------------------------------------------------- -void __fastcall TMapDialog::DrawCircle(TPoint p, int r, TColor color1, - TColor color2) -{ - TCanvas *c=Plot->Canvas; - int x1=p.x-r/2,x2=x1+r,y1=p.y-r/2,y2=y1+r; - c->Pen->Color=color1; c->Pen->Style=psSolid; c->Pen->Width=1; - if (color2!=-1) { - c->Brush->Color=color2; c->Brush->Style=bsSolid; - } - else { - c->Brush->Style=bsClear; - } - c->Ellipse(x1,y1,x2,y2); +void __fastcall TMapDialog::DrawCircle(TPoint p, int r, TColor color1, TColor color2) { + TCanvas *c = Plot->Canvas; + int x1 = p.x - r / 2, x2 = x1 + r, y1 = p.y - r / 2, y2 = y1 + r; + c->Pen->Color = color1; + c->Pen->Style = psSolid; + c->Pen->Width = 1; + if (color2 != -1) { + c->Brush->Color = color2; + c->Brush->Style = bsSolid; + } else { + c->Brush->Style = bsClear; + } + c->Ellipse(x1, y1, x2, y2); } //--------------------------------------------------------------------------- -void __fastcall TMapDialog::DrawGrid(TPoint p, int gint, int ng, - TColor color1, TColor color2) -{ - TCanvas *c=Plot->Canvas; - int i,w=Plot->Width,h=Plot->Height,x,y; - for (i=-p.x/gint;i<=(w-p.x)/gint;i++) { - c->Pen->Color=i%ng?color1:color2; - c->MoveTo(p.x+i*gint,0); c->LineTo(p.x+i*gint,h); - } - for (i=-p.y/gint;i<=(h-p.y)/gint;i++) { - c->Pen->Color=i%ng?color1:color2; - c->MoveTo(0,p.y+i*gint); c->LineTo(w,p.y+i*gint); - } +void __fastcall TMapDialog::DrawGrid(TPoint p, int gint, int ng, TColor color1, TColor color2) { + TCanvas *c = Plot->Canvas; + int i, w = Plot->Width, h = Plot->Height, x, y; + for (i = -p.x / gint; i <= (w - p.x) / gint; i++) { + c->Pen->Color = i % ng ? color1 : color2; + c->MoveTo(p.x + i * gint, 0); + c->LineTo(p.x + i * gint, h); + } + for (i = -p.y / gint; i <= (h - p.y) / gint; i++) { + c->Pen->Color = i % ng ? color1 : color2; + c->MoveTo(0, p.y + i * gint); + c->LineTo(w, p.y + i * gint); + } } //--------------------------------------------------------------------------- -void __fastcall TMapDialog::DrawText(int x, int y, AnsiString s, - TColor color, int align) -{ - TCanvas *c=Plot->Canvas; - TSize off=c->TextExtent(s); - c->Font->Charset=ANSI_CHARSET; - if (align==1) {x-=off.cx/2; y-=off.cy/2;} else if (align==2) x-=off.cx; - c->Font->Color=color; - c->TextOut(x,y,s); +void __fastcall TMapDialog::DrawText(int x, int y, AnsiString s, TColor color, int align) { + TCanvas *c = Plot->Canvas; + TSize off = c->TextExtent(s); + c->Font->Charset = ANSI_CHARSET; + if (align == 1) { + x -= off.cx / 2; + y -= off.cy / 2; + } else if (align == 2) + x -= off.cx; + c->Font->Color = color; + c->TextOut(x, y, s); } //--------------------------------------------------------------------------- -void __fastcall TMapDialog::DrawArrow(TPoint p, int siz, int ang, - TColor color) -{ - TCanvas *c=Plot->Canvas; - TPoint p1[6],p2[6]; - p1[0].x=p1[1].x=0; p1[2].x=3; p1[3].x=0; p1[4].x=-3; p1[5].x=0; - p1[0].y=-siz/2; p1[1].y=siz/2; p1[2].y=p1[4].y=p1[1].y-6; - p1[3].y=p1[5].y=siz/2; - - for (int i=0;i<6;i++) { - p2[i].x=p.x+(int)(p1[i].x*cos(-ang*D2R)-p1[i].y*sin(-ang*D2R)+0.5); - p2[i].y=p.y-(int)(p1[i].x*sin(-ang*D2R)+p1[i].y*cos(-ang*D2R)+0.5); - } - c->Pen->Color=color; - c->Polyline(p2,5); +void __fastcall TMapDialog::DrawArrow(TPoint p, int siz, int ang, TColor color) { + TCanvas *c = Plot->Canvas; + TPoint p1[6], p2[6]; + p1[0].x = p1[1].x = 0; + p1[2].x = 3; + p1[3].x = 0; + p1[4].x = -3; + p1[5].x = 0; + p1[0].y = -siz / 2; + p1[1].y = siz / 2; + p1[2].y = p1[4].y = p1[1].y - 6; + p1[3].y = p1[5].y = siz / 2; + + for (int i = 0; i < 6; i++) { + p2[i].x = p.x + (int)(p1[i].x * cos(-ang * D2R) - p1[i].y * sin(-ang * D2R) + 0.5); + p2[i].y = p.y - (int)(p1[i].x * sin(-ang * D2R) + p1[i].y * cos(-ang * D2R) + 0.5); + } + c->Pen->Color = color; + c->Polyline(p2, 5); } //--------------------------------------------------------------------------- -void __fastcall TMapDialog::UpdatePntList(void) -{ - PntList->Items->Clear(); - PntList->Items->Add(RefName); - for (int i=0;iNMapPnt;i++) { - PntList->Items->Add(MainForm->PntName[i]); - } - if (PntIndex>=PntList->Items->Count) PntIndex--; - PntList->ItemIndex=PntIndex; +void __fastcall TMapDialog::UpdatePntList(void) { + PntList->Items->Clear(); + PntList->Items->Add(RefName); + for (int i = 0; i < MainForm->NMapPnt; i++) { + PntList->Items->Add(MainForm->PntName[i]); + } + if (PntIndex >= PntList->Items->Count) PntIndex--; + PntList->ItemIndex = PntIndex; } //--------------------------------------------------------------------------- -void __fastcall TMapDialog::UpdateEnable(void) -{ - PntList ->Enabled=BtnPnt->Down; - BtnPntDlg->Enabled=BtnPnt->Down; +void __fastcall TMapDialog::UpdateEnable(void) { + PntList->Enabled = BtnPnt->Down; + BtnPntDlg->Enabled = BtnPnt->Down; } //--------------------------------------------------------------------------- diff --git a/app/winapp/rtknavi/mapdlg.h b/app/winapp/rtknavi/mapdlg.h index 11afd0e26..441a3b2e8 100644 --- a/app/winapp/rtknavi/mapdlg.h +++ b/app/winapp/rtknavi/mapdlg.h @@ -2,78 +2,73 @@ #ifndef mapdlgH #define mapdlgH //--------------------------------------------------------------------------- +#include #include #include -#include -#include #include -#include +#include +#include //--------------------------------------------------------------------------- -class TMapDialog : public TForm -{ -__published: - TPanel *Panel1; - TPanel *Panel3; - TButton *BtnClose; - TSpeedButton *BtnCenter; - TSpeedButton *BtnTrack; - TSpeedButton *BtnPnt; - TSpeedButton *BtnPntDlg; - TPaintBox *Disp; - TComboBox *PntList; - TSpeedButton *BtnExpand; - TSpeedButton *BtnShrink; - TSpeedButton *BtnGraph; - void __fastcall FormShow(TObject *Sender); - void __fastcall FormResize(TObject *Sender); - void __fastcall DispPaint(TObject *Sender); - void __fastcall BtnCloseClick(TObject *Sender); - void __fastcall BtnShrinkClick(TObject *Sender); - void __fastcall BtnExpandClick(TObject *Sender); - void __fastcall BtnPntDlgClick(TObject *Sender); - void __fastcall BtnCenterClick(TObject *Sender); - void __fastcall BtnTrackClick(TObject *Sender); - void __fastcall BtnPntClick(TObject *Sender); - void __fastcall PntListChange(TObject *Sender); - void __fastcall DispMouseDown(TObject *Sender, TMouseButton Button, - TShiftState Shift, int X, int Y); - void __fastcall DispMouseMove(TObject *Sender, TShiftState Shift, int X, - int Y); - void __fastcall DispMouseUp(TObject *Sender, TMouseButton Button, - TShiftState Shift, int X, int Y); -private: - Graphics::TBitmap *Plot; - AnsiString RefName; - double CentPos0[3]; - int Scale,PntIndex,Drag,X0,Y0; - - void __fastcall DrawVertGraph(const double *sol, - const int *stat, int psol, int psols, int psole, int nsol, int currentstat); - TPoint __fastcall PosToPoint(const double *pos); - TPoint __fastcall PosToGraphP(const double *pos, const double *ref, - int index, int npos, TRect rect); - void __fastcall DrawPoint(const double *pos, AnsiString name, - TColor color); - void __fastcall DrawVel(const double *vel); - void __fastcall DrawScale(void); - void __fastcall DrawCircle(TPoint p, int r, TColor color1, - TColor color2); - void __fastcall DrawGrid(TPoint p, int gint, int ng, TColor color1, - TColor color2); - void __fastcall DrawText(int x, int y, AnsiString s, TColor color, - int align); - void __fastcall DrawArrow(TPoint p, int siz, int ang, TColor color); - void __fastcall UpdatePntList(void); - void __fastcall UpdateEnable(void); -public: - double CurrentPos[3],RefPos[3],CentPos[3]; - - void __fastcall ResetRef(void); - void __fastcall UpdateMap(const double *sol, const double *solref, - const double *vel, const int *stat, int psol, int psols, int psole, - int nsol, AnsiString *solstr, int currentstat); - __fastcall TMapDialog(TComponent* Owner); +class TMapDialog : public TForm { + __published : TPanel *Panel1; + TPanel *Panel3; + TButton *BtnClose; + TSpeedButton *BtnCenter; + TSpeedButton *BtnTrack; + TSpeedButton *BtnPnt; + TSpeedButton *BtnPntDlg; + TPaintBox *Disp; + TComboBox *PntList; + TSpeedButton *BtnExpand; + TSpeedButton *BtnShrink; + TSpeedButton *BtnGraph; + void __fastcall FormShow(TObject *Sender); + void __fastcall FormResize(TObject *Sender); + void __fastcall DispPaint(TObject *Sender); + void __fastcall BtnCloseClick(TObject *Sender); + void __fastcall BtnShrinkClick(TObject *Sender); + void __fastcall BtnExpandClick(TObject *Sender); + void __fastcall BtnPntDlgClick(TObject *Sender); + void __fastcall BtnCenterClick(TObject *Sender); + void __fastcall BtnTrackClick(TObject *Sender); + void __fastcall BtnPntClick(TObject *Sender); + void __fastcall PntListChange(TObject *Sender); + void __fastcall DispMouseDown(TObject *Sender, TMouseButton Button, TShiftState Shift, int X, + int Y); + void __fastcall DispMouseMove(TObject *Sender, TShiftState Shift, int X, int Y); + void __fastcall DispMouseUp(TObject *Sender, TMouseButton Button, TShiftState Shift, int X, + int Y); + + private: + Graphics::TBitmap *Plot; + AnsiString RefName; + double CentPos0[3]; + int Scale, PntIndex, Drag, X0, Y0; + + void __fastcall DrawVertGraph(const double *sol, const int *stat, int psol, int psols, int psole, + int nsol, int currentstat); + TPoint __fastcall PosToPoint(const double *pos); + TPoint __fastcall PosToGraphP(const double *pos, const double *ref, int index, int npos, + TRect rect); + void __fastcall DrawPoint(const double *pos, AnsiString name, TColor color); + void __fastcall DrawVel(const double *vel); + void __fastcall DrawScale(void); + void __fastcall DrawCircle(TPoint p, int r, TColor color1, TColor color2); + void __fastcall DrawGrid(TPoint p, int gint, int ng, TColor color1, TColor color2); + void __fastcall DrawText(int x, int y, AnsiString s, TColor color, int align); + void __fastcall DrawArrow(TPoint p, int siz, int ang, TColor color); + void __fastcall UpdatePntList(void); + void __fastcall UpdateEnable(void); + + public: + double CurrentPos[3], RefPos[3], CentPos[3]; + + void __fastcall ResetRef(void); + void __fastcall UpdateMap(const double *sol, const double *solref, const double *vel, + const int *stat, int psol, int psols, int psole, int nsol, + AnsiString *solstr, int currentstat); + __fastcall TMapDialog(TComponent *Owner); }; //--------------------------------------------------------------------------- extern PACKAGE TMapDialog *MapDialog; diff --git a/app/winapp/rtknavi/markdlg.cpp b/app/winapp/rtknavi/markdlg.cpp index c0dfd7d40..782391c74 100644 --- a/app/winapp/rtknavi/markdlg.cpp +++ b/app/winapp/rtknavi/markdlg.cpp @@ -3,11 +3,12 @@ #include #pragma hdrstop -#include "rtklib.h" -#include "keydlg.h" #include "markdlg.h" -#include "refdlg.h" + +#include "keydlg.h" #include "naviopt.h" +#include "refdlg.h" +#include "rtklib.h" //--------------------------------------------------------------------------- #pragma package(smart_init) @@ -17,126 +18,101 @@ TMarkDialog *MarkDialog; extern rtksvr_t rtksvr; //--------------------------------------------------------------------------- -__fastcall TMarkDialog::TMarkDialog(TComponent* Owner) - : TForm(Owner) -{ - AnsiString s; - NMark=1; - FixPos[0]=FixPos[1]=FixPos[2]=0.0; - Label1->Caption=s.sprintf("%%r=%03d",NMark); +__fastcall TMarkDialog::TMarkDialog(TComponent *Owner) : TForm(Owner) { + AnsiString s; + NMark = 1; + FixPos[0] = FixPos[1] = FixPos[2] = 0.0; + Label1->Caption = s.sprintf("%%r=%03d", NMark); } //--------------------------------------------------------------------------- -void __fastcall TMarkDialog::BtnCancelClick(TObject *Sender) -{ - Close(); -} +void __fastcall TMarkDialog::BtnCancelClick(TObject *Sender) { Close(); } //--------------------------------------------------------------------------- -void __fastcall TMarkDialog::BtnOkClick(TObject *Sender) -{ - AnsiString s; - AnsiString marker=MarkerName->Text; - AnsiString comment=MarkerComment->Text; - char str1[32],str2[1024]; - - if (RadioGo->Checked) { - if (PosMode==PMODE_STATIC||PosMode==PMODE_FIXED) { - PosMode=PMODE_KINEMA; - } - else if (PosMode==PMODE_PPP_STATIC||PosMode==PMODE_PPP_FIXED) { - PosMode=PMODE_PPP_KINEMA; - } - } - else if (RadioStop->Checked) { - if (PosMode==PMODE_KINEMA||PosMode==PMODE_FIXED) { - PosMode=PMODE_STATIC; - } - else if (PosMode==PMODE_PPP_KINEMA||PosMode==PMODE_PPP_FIXED) { - PosMode=PMODE_PPP_STATIC; - } - } - else if (RadioFix->Checked) { - if (PosMode==PMODE_KINEMA||PosMode==PMODE_STATIC) { - PosMode=PMODE_FIXED; - } - else if (PosMode==PMODE_PPP_KINEMA||PosMode==PMODE_PPP_STATIC) { - PosMode=PMODE_PPP_FIXED; - } - } - if (ChkMarkerName->Checked) { - sprintf(str1,"%03d",NMark); - reppath(marker.c_str(),str2,utc2gpst(timeget()),str1,""); - rtksvrmark(&rtksvr,str2,comment.c_str()); - NMark++; - Label1->Caption=s.sprintf("%%r=%03d",NMark); - } - Marker=marker; - Comment=comment; +void __fastcall TMarkDialog::BtnOkClick(TObject *Sender) { + AnsiString s; + AnsiString marker = MarkerName->Text; + AnsiString comment = MarkerComment->Text; + char str1[32], str2[1024]; + + if (RadioGo->Checked) { + if (PosMode == PMODE_STATIC || PosMode == PMODE_FIXED) { + PosMode = PMODE_KINEMA; + } else if (PosMode == PMODE_PPP_STATIC || PosMode == PMODE_PPP_FIXED) { + PosMode = PMODE_PPP_KINEMA; + } + } else if (RadioStop->Checked) { + if (PosMode == PMODE_KINEMA || PosMode == PMODE_FIXED) { + PosMode = PMODE_STATIC; + } else if (PosMode == PMODE_PPP_KINEMA || PosMode == PMODE_PPP_FIXED) { + PosMode = PMODE_PPP_STATIC; + } + } else if (RadioFix->Checked) { + if (PosMode == PMODE_KINEMA || PosMode == PMODE_STATIC) { + PosMode = PMODE_FIXED; + } else if (PosMode == PMODE_PPP_KINEMA || PosMode == PMODE_PPP_STATIC) { + PosMode = PMODE_PPP_FIXED; + } + } + if (ChkMarkerName->Checked) { + sprintf(str1, "%03d", NMark); + reppath(marker.c_str(), str2, utc2gpst(timeget()), str1, ""); + rtksvrmark(&rtksvr, str2, comment.c_str()); + NMark++; + Label1->Caption = s.sprintf("%%r=%03d", NMark); + } + Marker = marker; + Comment = comment; } //--------------------------------------------------------------------------- -void __fastcall TMarkDialog::ChkMarkerNameClick(TObject *Sender) -{ - UpdateEnable(); -} +void __fastcall TMarkDialog::ChkMarkerNameClick(TObject *Sender) { UpdateEnable(); } //--------------------------------------------------------------------------- -void __fastcall TMarkDialog::FormShow(TObject *Sender) -{ - MarkerName->Text=Marker; - MarkerComment->Text=Comment; - - if (PosMode==PMODE_STATIC||PosMode==PMODE_PPP_STATIC) { - RadioStop->Checked=true; - } - else if (PosMode==PMODE_KINEMA||PosMode==PMODE_PPP_KINEMA) { - RadioGo->Checked=true; - } - else { - RadioStop->Checked=false; - RadioGo ->Checked=false; - } - UpdateEnable(); +void __fastcall TMarkDialog::FormShow(TObject *Sender) { + MarkerName->Text = Marker; + MarkerComment->Text = Comment; + + if (PosMode == PMODE_STATIC || PosMode == PMODE_PPP_STATIC) { + RadioStop->Checked = true; + } else if (PosMode == PMODE_KINEMA || PosMode == PMODE_PPP_KINEMA) { + RadioGo->Checked = true; + } else { + RadioStop->Checked = false; + RadioGo->Checked = false; + } + UpdateEnable(); } //--------------------------------------------------------------------------- -void __fastcall TMarkDialog::UpdateEnable(void) -{ - bool ena=PosMode==PMODE_STATIC||PosMode==PMODE_PPP_STATIC|| - PosMode==PMODE_KINEMA||PosMode==PMODE_PPP_KINEMA|| - PosMode==PMODE_FIXED ||PosMode==PMODE_PPP_FIXED; - RadioStop->Enabled=ena; - RadioGo ->Enabled=ena; - RadioFix ->Enabled=ena; - LabelPosMode->Enabled=ena; - EditLat->Enabled=RadioFix->Checked; - EditLon->Enabled=RadioFix->Checked; - EditHgt->Enabled=RadioFix->Checked; - BtnPos->Enabled=RadioFix->Checked; - LabelPos->Enabled=RadioFix->Checked; - MarkerName->Enabled=ChkMarkerName->Checked; +void __fastcall TMarkDialog::UpdateEnable(void) { + bool ena = PosMode == PMODE_STATIC || PosMode == PMODE_PPP_STATIC || PosMode == PMODE_KINEMA || + PosMode == PMODE_PPP_KINEMA || PosMode == PMODE_FIXED || PosMode == PMODE_PPP_FIXED; + RadioStop->Enabled = ena; + RadioGo->Enabled = ena; + RadioFix->Enabled = ena; + LabelPosMode->Enabled = ena; + EditLat->Enabled = RadioFix->Checked; + EditLon->Enabled = RadioFix->Checked; + EditHgt->Enabled = RadioFix->Checked; + BtnPos->Enabled = RadioFix->Checked; + LabelPos->Enabled = RadioFix->Checked; + MarkerName->Enabled = ChkMarkerName->Checked; } //--------------------------------------------------------------------------- -void __fastcall TMarkDialog::BtnRepDlgClick(TObject *Sender) -{ - KeyDialog->Caption="Keyword Replacement in Marker Name"; - KeyDialog->ShowModal(); +void __fastcall TMarkDialog::BtnRepDlgClick(TObject *Sender) { + KeyDialog->Caption = "Keyword Replacement in Marker Name"; + KeyDialog->ShowModal(); } //--------------------------------------------------------------------------- -void __fastcall TMarkDialog::RadioGoClick(TObject *Sender) -{ - UpdateEnable(); -} +void __fastcall TMarkDialog::RadioGoClick(TObject *Sender) { UpdateEnable(); } //--------------------------------------------------------------------------- -void __fastcall TMarkDialog::BtnPosClick(TObject *Sender) -{ - AnsiString s; - RefDialog->Pos[0]=EditLat->Text.ToDouble(); - RefDialog->Pos[1]=EditLon->Text.ToDouble(); - RefDialog->Pos[2]=EditHgt->Text.ToDouble(); - RefDialog->StaPosFile=OptDialog->StaPosFileF; - RefDialog->Left=Left+Width/2-RefDialog->Width/2; - RefDialog->Top=Top+Height/2-RefDialog->Height/2; - if (RefDialog->ShowModal()!=mrOk) return; - EditLat->Text=s.sprintf("%.9f",RefDialog->Pos[0]); - EditLon->Text=s.sprintf("%.9f",RefDialog->Pos[1]); - EditHgt->Text=s.sprintf("%.4f",RefDialog->Pos[2]); +void __fastcall TMarkDialog::BtnPosClick(TObject *Sender) { + AnsiString s; + RefDialog->Pos[0] = EditLat->Text.ToDouble(); + RefDialog->Pos[1] = EditLon->Text.ToDouble(); + RefDialog->Pos[2] = EditHgt->Text.ToDouble(); + RefDialog->StaPosFile = OptDialog->StaPosFileF; + RefDialog->Left = Left + Width / 2 - RefDialog->Width / 2; + RefDialog->Top = Top + Height / 2 - RefDialog->Height / 2; + if (RefDialog->ShowModal() != mrOk) return; + EditLat->Text = s.sprintf("%.9f", RefDialog->Pos[0]); + EditLon->Text = s.sprintf("%.9f", RefDialog->Pos[1]); + EditHgt->Text = s.sprintf("%.4f", RefDialog->Pos[2]); } //--------------------------------------------------------------------------- - diff --git a/app/winapp/rtknavi/markdlg.h b/app/winapp/rtknavi/markdlg.h index 10ad04fd1..06e827e1f 100644 --- a/app/winapp/rtknavi/markdlg.h +++ b/app/winapp/rtknavi/markdlg.h @@ -4,48 +4,47 @@ #define markdlgH //--------------------------------------------------------------------------- #include +#include #include -#include -#include #include -#include +#include +#include //--------------------------------------------------------------------------- -class TMarkDialog : public TForm -{ -__published: - TButton *BtnOk; - TButton *BtnCancel; - TLabel *Label2; - TRadioButton *RadioStop; - TRadioButton *RadioGo; - TLabel *LabelPosMode; - TComboBox *MarkerName; - TCheckBox *ChkMarkerName; - TEdit *MarkerComment; - TLabel *Label1; - TSpeedButton *BtnRepDlg; - TRadioButton *RadioFix; - TEdit *EditLat; - TEdit *EditLon; - TEdit *EditHgt; - TLabel *LabelPos; - TButton *BtnPos; - void __fastcall BtnCancelClick(TObject *Sender); - void __fastcall BtnOkClick(TObject *Sender); - void __fastcall ChkMarkerNameClick(TObject *Sender); - void __fastcall FormShow(TObject *Sender); - void __fastcall BtnRepDlgClick(TObject *Sender); - void __fastcall RadioGoClick(TObject *Sender); - void __fastcall BtnPosClick(TObject *Sender); -private: - void __fastcall UpdateEnable(void); -public: - AnsiString Marker,Comment; - double FixPos[3]; - int PosMode,NMark; - - __fastcall TMarkDialog(TComponent* Owner); - +class TMarkDialog : public TForm { + __published : TButton *BtnOk; + TButton *BtnCancel; + TLabel *Label2; + TRadioButton *RadioStop; + TRadioButton *RadioGo; + TLabel *LabelPosMode; + TComboBox *MarkerName; + TCheckBox *ChkMarkerName; + TEdit *MarkerComment; + TLabel *Label1; + TSpeedButton *BtnRepDlg; + TRadioButton *RadioFix; + TEdit *EditLat; + TEdit *EditLon; + TEdit *EditHgt; + TLabel *LabelPos; + TButton *BtnPos; + void __fastcall BtnCancelClick(TObject *Sender); + void __fastcall BtnOkClick(TObject *Sender); + void __fastcall ChkMarkerNameClick(TObject *Sender); + void __fastcall FormShow(TObject *Sender); + void __fastcall BtnRepDlgClick(TObject *Sender); + void __fastcall RadioGoClick(TObject *Sender); + void __fastcall BtnPosClick(TObject *Sender); + + private: + void __fastcall UpdateEnable(void); + + public: + AnsiString Marker, Comment; + double FixPos[3]; + int PosMode, NMark; + + __fastcall TMarkDialog(TComponent *Owner); }; //--------------------------------------------------------------------------- extern PACKAGE TMarkDialog *MarkDialog; diff --git a/app/winapp/rtknavi/mondlg.cpp b/app/winapp/rtknavi/mondlg.cpp index b9e71bfbe..58740faaa 100644 --- a/app/winapp/rtknavi/mondlg.cpp +++ b/app/winapp/rtknavi/mondlg.cpp @@ -2,2119 +2,2268 @@ #include #pragma hdrstop -#include "rtklib.h" #include "mondlg.h" + #include + +#include "rtklib.h" //--------------------------------------------------------------------------- #pragma package(smart_init) #pragma resource "*.dfm" -#define SQRT(x) ((x)<0.0||(x)!=(x)?0.0:sqrt(x)) -#define TOPMARGIN 2 -#define LEFTMARGIN 3 -#define MAXLINE 2048 -#define MAXLEN 256 -#define TYPE_WIDTH 90 +#define SQRT(x) ((x) < 0.0 || (x) != (x) ? 0.0 : sqrt(x)) +#define TOPMARGIN 2 +#define LEFTMARGIN 3 +#define MAXLINE 2048 +#define MAXLEN 256 +#define TYPE_WIDTH 90 -#define NMONITEM 17 +#define NMONITEM 17 //--------------------------------------------------------------------------- -extern rtksvr_t rtksvr; // rtk server struct -extern stream_t monistr; // monitor stream +extern rtksvr_t rtksvr; // rtk server struct +extern stream_t monistr; // monitor stream -static const int sys_tbl[]={ - SYS_ALL,SYS_GPS,SYS_GLO,SYS_GAL,SYS_QZS,SYS_CMP,SYS_IRN,SYS_SBS -}; +static const int sys_tbl[] = {SYS_ALL, SYS_GPS, SYS_GLO, SYS_GAL, + SYS_QZS, SYS_CMP, SYS_IRN, SYS_SBS}; //--------------------------------------------------------------------------- -__fastcall TMonitorDialog::TMonitorDialog(TComponent* Owner) - : TForm(Owner) -{ - int i; - - ScrollPos=0; - ObsMode=0; - ConFmt=-1; - ConBuff=new TStringList; - ConBuff->Add(""); - DoubleBuffered=true; - Str1=Str2=0; - - for (i=0;i<=MAXRCVFMT;i++) { - SelFmt->Items->Add(formatstrs[i]); - } - init_rtcm(&rtcm); - init_raw(&raw,-1); +__fastcall TMonitorDialog::TMonitorDialog(TComponent *Owner) : TForm(Owner) { + int i; + + ScrollPos = 0; + ObsMode = 0; + ConFmt = -1; + ConBuff = new TStringList; + ConBuff->Add(""); + DoubleBuffered = true; + Str1 = Str2 = 0; + + for (i = 0; i <= MAXRCVFMT; i++) { + SelFmt->Items->Add(formatstrs[i]); + } + init_rtcm(&rtcm); + init_raw(&raw, -1); } //--------------------------------------------------------------------------- -void __fastcall TMonitorDialog::FormShow(TObject *Sender) -{ - TypeF=Type->ItemIndex; - Label->Caption=""; - ClearTable(); +void __fastcall TMonitorDialog::FormShow(TObject *Sender) { + TypeF = Type->ItemIndex; + Label->Caption = ""; + ClearTable(); } //--------------------------------------------------------------------------- -void __fastcall TMonitorDialog::FormClose(TObject *Sender, TCloseAction &Action) -{ - free_rtcm(&rtcm); - free_raw(&raw); - Release(); +void __fastcall TMonitorDialog::FormClose(TObject *Sender, TCloseAction &Action) { + free_rtcm(&rtcm); + free_raw(&raw); + Release(); } //--------------------------------------------------------------------------- -void __fastcall TMonitorDialog::BtnCloseClick(TObject *Sender) -{ - Close(); -} +void __fastcall TMonitorDialog::BtnCloseClick(TObject *Sender) { Close(); } //--------------------------------------------------------------------------- -void __fastcall TMonitorDialog::TypeChange(TObject *Sender) -{ - int index; - - TypeF=Type->ItemIndex; - index=TypeF-NMONITEM; - - if (0<=index) { - rtksvrlock(&rtksvr); - if (index<2) rtksvr.npb[index ]=0; - else if (index<4) rtksvr.nsb[index-2]=0; - else rtksvr.rtk.neb=0; - rtksvrunlock(&rtksvr); - } - ClearTable(); - Label->Caption=""; - ConBuff->Clear(); - ConBuff->Add(""); - Console->Invalidate(); +void __fastcall TMonitorDialog::TypeChange(TObject *Sender) { + int index; + + TypeF = Type->ItemIndex; + index = TypeF - NMONITEM; + + if (0 <= index) { + rtksvrlock(&rtksvr); + if (index < 2) + rtksvr.npb[index] = 0; + else if (index < 4) + rtksvr.nsb[index - 2] = 0; + else + rtksvr.rtk.neb = 0; + rtksvrunlock(&rtksvr); + } + ClearTable(); + Label->Caption = ""; + ConBuff->Clear(); + ConBuff->Add(""); + Console->Invalidate(); } //--------------------------------------------------------------------------- -void __fastcall TMonitorDialog::SelFmtChange(TObject *Sender) -{ - AddConsole((uint8_t *)"\n",1,1); - - if (ConFmt>=3&&ConFmt<17) { - free_raw(&raw); - } - ConFmt=SelFmt->ItemIndex; - - if (ConFmt>=3&&ConFmt<17) { - init_raw(&raw,ConFmt-2); - } +void __fastcall TMonitorDialog::SelFmtChange(TObject *Sender) { + AddConsole((uint8_t *)"\n", 1, 1); + + if (ConFmt >= 3 && ConFmt < 17) { + free_raw(&raw); + } + ConFmt = SelFmt->ItemIndex; + + if (ConFmt >= 3 && ConFmt < 17) { + init_raw(&raw, ConFmt - 2); + } } //--------------------------------------------------------------------------- -void __fastcall TMonitorDialog::SelStrChange(TObject *Sender) -{ - Str1=SelStr->ItemIndex; - ConBuff->Clear(); - ConBuff->Add(""); - Console->Invalidate(); +void __fastcall TMonitorDialog::SelStrChange(TObject *Sender) { + Str1 = SelStr->ItemIndex; + ConBuff->Clear(); + ConBuff->Add(""); + Console->Invalidate(); } //--------------------------------------------------------------------------- -void __fastcall TMonitorDialog::SelStr2Change(TObject *Sender) -{ - Str2=SelStr2->ItemIndex; - ConBuff->Clear(); - ConBuff->Add(""); - Console->Invalidate(); +void __fastcall TMonitorDialog::SelStr2Change(TObject *Sender) { + Str2 = SelStr2->ItemIndex; + ConBuff->Clear(); + ConBuff->Add(""); + Console->Invalidate(); } //--------------------------------------------------------------------------- -void __fastcall TMonitorDialog::Timer1Timer(TObject *Sender) -{ - if (!Visible) return; - switch (TypeF) { - case 0: ShowRtk(); break; - case 1: ShowObs(); break; - case 2: ShowNav(); break; - case 3: ShowIonUtc(); break; - case 4: ShowStr(); break; - case 5: ShowSat(); break; - case 6: ShowEst(); break; - case 7: ShowCov(); break; - case 8: ShowSbsMsg(); break; - case 9: ShowSbsLong(); break; - case 10: ShowSbsIono(); break; - case 11: ShowSbsFast(); break; - case 12: ShowRtcm(); break; - case 13: ShowRtcmDgps(); break; - case 14: ShowRtcmSsr(); break; - case 15: ShowRefSta(); break; - } +void __fastcall TMonitorDialog::Timer1Timer(TObject *Sender) { + if (!Visible) return; + switch (TypeF) { + case 0: + ShowRtk(); + break; + case 1: + ShowObs(); + break; + case 2: + ShowNav(); + break; + case 3: + ShowIonUtc(); + break; + case 4: + ShowStr(); + break; + case 5: + ShowSat(); + break; + case 6: + ShowEst(); + break; + case 7: + ShowCov(); + break; + case 8: + ShowSbsMsg(); + break; + case 9: + ShowSbsLong(); + break; + case 10: + ShowSbsIono(); + break; + case 11: + ShowSbsFast(); + break; + case 12: + ShowRtcm(); + break; + case 13: + ShowRtcmDgps(); + break; + case 14: + ShowRtcmSsr(); + break; + case 15: + ShowRefSta(); + break; + } } //--------------------------------------------------------------------------- -void __fastcall TMonitorDialog::ClearTable(void) -{ - int console=0; - - FontScale=Type->Width*96/TYPE_WIDTH; - - switch (TypeF) { - case 0: SetRtk(); break; - case 1: SetObs(); break; - case 2: ; break; - case 3: SetIonUtc(); break; - case 4: SetStr(); break; - case 5: SetSat(); break; - case 6: SetEst(); break; - case 7: SetCov(); break; - case 8: SetSbsMsg(); break; - case 9: SetSbsLong(); break; - case 10: SetSbsIono(); break; - case 11: SetSbsFast(); break; - case 12: SetRtcm(); break; - case 13: SetRtcmDgps(); break; - case 14: SetRtcmSsr(); break; - case 15: SetRefSta(); break; - default: console=1; break; - } - Console ->Visible=console; - Scroll ->Visible=console; - Panel2 ->Visible=console; - Tbl ->Visible=!console; - SelObs ->Visible=TypeF==1; - SelSys ->Visible=TypeF==1||TypeF==5; - SelSys2 ->Visible=TypeF==2||TypeF==14; - SelSat ->Visible=TypeF==2||TypeF==5; - SelStr ->Visible=TypeF==12||TypeF==14||TypeF==15||TypeF==16; - SelStr2 ->Visible=TypeF==17; - SelFmt ->Visible=TypeF==16; - SelEph ->Visible=TypeF==2; - SelStr ->Left=(TypeF==14)?SelSys->Left+SelSys->Width+1:Type->Left+Type->Width+1; +void __fastcall TMonitorDialog::ClearTable(void) { + int console = 0; + + FontScale = Type->Width * 96 / TYPE_WIDTH; + + switch (TypeF) { + case 0: + SetRtk(); + break; + case 1: + SetObs(); + break; + case 2:; + break; + case 3: + SetIonUtc(); + break; + case 4: + SetStr(); + break; + case 5: + SetSat(); + break; + case 6: + SetEst(); + break; + case 7: + SetCov(); + break; + case 8: + SetSbsMsg(); + break; + case 9: + SetSbsLong(); + break; + case 10: + SetSbsIono(); + break; + case 11: + SetSbsFast(); + break; + case 12: + SetRtcm(); + break; + case 13: + SetRtcmDgps(); + break; + case 14: + SetRtcmSsr(); + break; + case 15: + SetRefSta(); + break; + default: + console = 1; + break; + } + Console->Visible = console; + Scroll->Visible = console; + Panel2->Visible = console; + Tbl->Visible = !console; + SelObs->Visible = TypeF == 1; + SelSys->Visible = TypeF == 1 || TypeF == 5; + SelSys2->Visible = TypeF == 2 || TypeF == 14; + SelSat->Visible = TypeF == 2 || TypeF == 5; + SelStr->Visible = TypeF == 12 || TypeF == 14 || TypeF == 15 || TypeF == 16; + SelStr2->Visible = TypeF == 17; + SelFmt->Visible = TypeF == 16; + SelEph->Visible = TypeF == 2; + SelStr->Left = (TypeF == 14) ? SelSys->Left + SelSys->Width + 1 : Type->Left + Type->Width + 1; } //--------------------------------------------------------------------------- -void __fastcall TMonitorDialog::Timer2Timer(TObject *Sender) -{ - uint8_t *msg; - char buff[256]; - int i,n,len; - - if (TypeF<16) return; - - rtksvrlock(&rtksvr); - - if (TypeF==16) { // input buffer - len=rtksvr.npb[Str1]; - if (len>0&&(msg=(uint8_t *)malloc(len))) { - memcpy(msg,rtksvr.pbuf[Str1],len); - rtksvr.npb[Str1]=0; - } - } - else if (TypeF==17) { // solution buffer - len=rtksvr.nsb[Str2]; - if (len>0&&(msg=(uint8_t *)malloc(len))) { - memcpy(msg,rtksvr.sbuf[Str2],len); - rtksvr.nsb[Str2]=0; - } - } - else { // error message buffer - len=rtksvr.rtk.neb; - if (len>0&&(msg=(uint8_t *)malloc(len))) { - memcpy(msg,rtksvr.rtk.errbuf,len); - rtksvr.rtk.neb=0; - } - } - rtksvrunlock(&rtksvr); - - if (len<=0||!msg) return; - - rtcm.outtype=raw.outtype=1; - - if (TypeF>=17) { - AddConsole(msg,len,1); - } - else if (ConFmt<2) { - AddConsole(msg,len,ConFmt); - } - else if (ConFmt==2) { - for (i=0;iInvalidate(); +void __fastcall TMonitorDialog::Timer2Timer(TObject *Sender) { + uint8_t *msg; + char buff[256]; + int i, n, len; + + if (TypeF < 16) return; + + rtksvrlock(&rtksvr); + + if (TypeF == 16) { // input buffer + len = rtksvr.npb[Str1]; + if (len > 0 && (msg = (uint8_t *)malloc(len))) { + memcpy(msg, rtksvr.pbuf[Str1], len); + rtksvr.npb[Str1] = 0; + } + } else if (TypeF == 17) { // solution buffer + len = rtksvr.nsb[Str2]; + if (len > 0 && (msg = (uint8_t *)malloc(len))) { + memcpy(msg, rtksvr.sbuf[Str2], len); + rtksvr.nsb[Str2] = 0; + } + } else { // error message buffer + len = rtksvr.rtk.neb; + if (len > 0 && (msg = (uint8_t *)malloc(len))) { + memcpy(msg, rtksvr.rtk.errbuf, len); + rtksvr.rtk.neb = 0; + } + } + rtksvrunlock(&rtksvr); + + if (len <= 0 || !msg) return; + + rtcm.outtype = raw.outtype = 1; + + if (TypeF >= 17) { + AddConsole(msg, len, 1); + } else if (ConFmt < 2) { + AddConsole(msg, len, ConFmt); + } else if (ConFmt == 2) { + for (i = 0; i < len; i++) { + input_rtcm2(&rtcm, msg[i]); + if (rtcm.msgtype[0]) { + n = sprintf(buff, "%s\n", rtcm.msgtype); + AddConsole((uint8_t *)buff, n, 1); + rtcm.msgtype[0] = '\0'; + } + } + } else if (ConFmt == 3) { + for (i = 0; i < len; i++) { + input_rtcm3(&rtcm, msg[i]); + if (rtcm.msgtype[0]) { + n = sprintf(buff, "%s\n", rtcm.msgtype); + AddConsole((uint8_t *)buff, n, 1); + rtcm.msgtype[0] = '\0'; + } + } + } else if (ConFmt < 17) { + for (i = 0; i < len; i++) { + input_raw(&raw, ConFmt - 2, msg[i]); + if (raw.msgtype[0]) { + n = sprintf(buff, "%s\n", raw.msgtype); + AddConsole((uint8_t *)buff, n, 1); + raw.msgtype[0] = '\0'; + } + } + } + free(msg); + Console->Invalidate(); } //--------------------------------------------------------------------------- -void __fastcall TMonitorDialog::AddConsole(uint8_t *msg, int len, int mode) -{ - AnsiString ConBuff_Str=ConBuff->Strings[ConBuff->Count-1]; - char buff[MAXLEN+16],*p=buff; - - if (BtnPause->Down) return; - - p+=sprintf(p,"%s",ConBuff_Str.c_str()); - - for (int i=0;i= MAXLEN) add = 1; - } - } - else { - if (strlen(buff) % 17 == 16) strcat(p++, " "); - p+=sprintf(p,"%02X",msg[i]); - if (p-buff>=67) add = 1; - } - - if (add) { - ConBuff->Strings[ConBuff->Count-1]=buff; - ConBuff->Add(""); - *(p=buff)=0; - if (ConBuff->Count>=MAXLINE) ConBuff->Delete(0); - } - } - ConBuff->Strings[ConBuff->Count-1]=buff; - if (BtnDown->Down) ScrollPos=0; +void __fastcall TMonitorDialog::AddConsole(uint8_t *msg, int len, int mode) { + AnsiString ConBuff_Str = ConBuff->Strings[ConBuff->Count - 1]; + char buff[MAXLEN + 16], *p = buff; + + if (BtnPause->Down) return; + + p += sprintf(p, "%s", ConBuff_Str.c_str()); + + for (int i = 0; i < len; i++) { + int add = 0; + if (mode) { + if (msg[i] == '\r') continue; + if (msg[i] == '\n') + add = 1; + else { + p += sprintf(p, "%c", isprint(msg[i]) ? msg[i] : '.'); + if (p - buff >= MAXLEN) add = 1; + } + } else { + if (strlen(buff) % 17 == 16) strcat(p++, " "); + p += sprintf(p, "%02X", msg[i]); + if (p - buff >= 67) add = 1; + } + + if (add) { + ConBuff->Strings[ConBuff->Count - 1] = buff; + ConBuff->Add(""); + *(p = buff) = 0; + if (ConBuff->Count >= MAXLINE) ConBuff->Delete(0); + } + } + ConBuff->Strings[ConBuff->Count - 1] = buff; + if (BtnDown->Down) ScrollPos = 0; } //--------------------------------------------------------------------------- -void __fastcall TMonitorDialog::ConsolePaint(TObject *Sender) -{ - TCanvas *c=Console->Canvas; - TSize off=c->TextExtent(" "); - int n,m,p,y=TOPMARGIN; - - c->Brush->Style=bsSolid; - c->Brush->Color=clWhite; - c->FillRect(Console->ClientRect); - - n=ConBuff->Count; - if (ConBuff->Strings[n-1]=="") n--; - m=(Console->Height-TOPMARGIN*2)/off.cy; - p=m>=n?0:n-m-ScrollPos; - - for (int i=p<0?0:p;iCount;i++,y+=off.cy) { - if (y+off.cy>Console->Height-TOPMARGIN) break; - c->Font->Color=iTextOut(LEFTMARGIN,y,ConBuff->Strings[i]); - } - Scroll->Max=n<=m?m-1:n-m; - Scroll->Position=Scroll->Max-ScrollPos; +void __fastcall TMonitorDialog::ConsolePaint(TObject *Sender) { + TCanvas *c = Console->Canvas; + TSize off = c->TextExtent(" "); + int n, m, p, y = TOPMARGIN; + + c->Brush->Style = bsSolid; + c->Brush->Color = clWhite; + c->FillRect(Console->ClientRect); + + n = ConBuff->Count; + if (ConBuff->Strings[n - 1] == "") n--; + m = (Console->Height - TOPMARGIN * 2) / off.cy; + p = m >= n ? 0 : n - m - ScrollPos; + + for (int i = p < 0 ? 0 : p; i < ConBuff->Count; i++, y += off.cy) { + if (y + off.cy > Console->Height - TOPMARGIN) break; + c->Font->Color = i < n - 1 ? clGray : clBlack; + c->TextOut(LEFTMARGIN, y, ConBuff->Strings[i]); + } + Scroll->Max = n <= m ? m - 1 : n - m; + Scroll->Position = Scroll->Max - ScrollPos; } //--------------------------------------------------------------------------- -void __fastcall TMonitorDialog::ScrollChange(TObject *Sender) -{ - ScrollPos=Scroll->Max-Scroll->Position; - Console->Invalidate(); +void __fastcall TMonitorDialog::ScrollChange(TObject *Sender) { + ScrollPos = Scroll->Max - Scroll->Position; + Console->Invalidate(); } //--------------------------------------------------------------------------- -void __fastcall TMonitorDialog::BtnDownClick(TObject *Sender) -{ - if (BtnDown->Down) ScrollPos=0; - Console->Invalidate(); +void __fastcall TMonitorDialog::BtnDownClick(TObject *Sender) { + if (BtnDown->Down) ScrollPos = 0; + Console->Invalidate(); } //--------------------------------------------------------------------------- -void __fastcall TMonitorDialog::BtnClearClick(TObject *Sender) -{ - ConBuff->Clear(); - ConBuff->Add(""); - Console->Invalidate(); +void __fastcall TMonitorDialog::BtnClearClick(TObject *Sender) { + ConBuff->Clear(); + ConBuff->Add(""); + Console->Invalidate(); } //--------------------------------------------------------------------------- -void __fastcall TMonitorDialog::SelObsChange(TObject *Sender) -{ - ObsMode=SelObs->ItemIndex; - SetObs(); - ShowObs(); +void __fastcall TMonitorDialog::SelObsChange(TObject *Sender) { + ObsMode = SelObs->ItemIndex; + SetObs(); + ShowObs(); } //--------------------------------------------------------------------------- -void __fastcall TMonitorDialog::SetRtk(void) -{ - AnsiString label[]={"Parameter","Value"}; - int width[]={220,380}; - - Tbl->ColCount=2; - Tbl->RowCount=2; - for (int i=0;iColCount;i++) { - Tbl->ColWidths[i]=width[i]*FontScale/96; - Tbl->Cells[i][0]=label[i]; - Tbl->Cells[i][1]=""; - } +void __fastcall TMonitorDialog::SetRtk(void) { + AnsiString label[] = {"Parameter", "Value"}; + int width[] = {220, 380}; + + Tbl->ColCount = 2; + Tbl->RowCount = 2; + for (int i = 0; i < Tbl->ColCount; i++) { + Tbl->ColWidths[i] = width[i] * FontScale / 96; + Tbl->Cells[i][0] = label[i]; + Tbl->Cells[i][1] = ""; + } } //--------------------------------------------------------------------------- -void __fastcall TMonitorDialog::ShowRtk(void) -{ - AnsiString s,exsats,navsys=""; - AnsiString svrstate[]={"Stop","Run"}; - AnsiString sol[]={"-","Fix","Float","SBAS","DGPS","Single","PPP",""}; - AnsiString mode[]={"Single","DGPS","Kinematic","Static","Static-Start","Moving-Base", - "Fixed","PPP-Kinematic","PPP-Static",""}; - AnsiString freq[]={"-","L1","L1+L2","L1+L2+L3","L1+L2+L3+L4","L1+L2+L3+L4+L5",""}; - double *del,*off,runtime,rt[3]={0},dop[4]={0}; - double azel[MAXSAT*2],pos[3],vel[3],rr[3]={0},enu[3]={0}; - int i,j,k,thread,cycle,state,rtkstat,nsat0,nsat1,prcout,nave; - int cputime,nb[3]={0},nmsg[3][10]={{0}},ne; - char tstr[40],*ant,id[8],s1[40]="-",s2[40]="-",s3[40]="-"; - char file[1024]=""; - const char *ionoopt[]={"OFF","Broadcast","SBAS","Dual-Frequency","Estimate STEC","IONEX TEC","QZSS LEX",""}; - const char *tropopt[]={"OFF","Saastamoinen","SBAS","Estimate ZTD","Estimate ZTD+Grad",""}; - const char *ephopt []={"Broadcast","Precise","Broadcast+SBAS","Broadcat+SSR APC","Broadcast+SSR CoM","QZSS LEX",""}; - - rtk_t *rtk = static_cast(malloc(sizeof(rtk_t))); - if (rtk == NULL) return; - - rtksvrlock(&rtksvr); // lock - - *rtk=rtksvr.rtk; - thread=(int)rtksvr.thread; - cycle=rtksvr.cycle; - state=rtksvr.state; - rtkstat=rtksvr.rtk.sol.stat; - nsat0=rtksvr.obs[0][0].n; - nsat1=rtksvr.obs[1][0].n; - cputime=rtksvr.cputime; - prcout =rtksvr.prcout; - nave=rtksvr.nave; - for (i=0;i<3;i++) nb[i]=rtksvr.nb[i]; - for (i=0;i<3;i++) for (j=0;j<10;j++) { - nmsg[i][j]=rtksvr.nmsg[i][j]; - } - if (rtksvr.state) { - runtime=(double)(tickget()-rtksvr.tick)/1000.0; - rt[0]=floor(runtime/3600.0); runtime-=rt[0]*3600.0; - rt[1]=floor(runtime/60.0); rt[2]=runtime-rt[1]*60.0; - } - if ((ne=rtksvr.nav.ne)>0) { - time2str(rtksvr.nav.peph[ 0].time,s1,0); - time2str(rtksvr.nav.peph[ne-1].time,s2,0); - time2str(rtksvr.ftime[2],s3,0); - } - strcpy(file,rtksvr.files[2]); - - rtksvrunlock(&rtksvr); // unlock - - for (j=k=0;jopt.mode==PMODE_SINGLE&&!rtk->ssat[j].vs) continue; - if (rtk->opt.mode!=PMODE_SINGLE&&!rtk->ssat[j].vsat[0]) continue; - azel[ k*2]=rtk->ssat[j].azel[0]; - azel[1+k*2]=rtk->ssat[j].azel[1]; - k++; - } - dops(k,azel,0.0,dop); - - if (rtk->opt.navsys&SYS_GPS) navsys=navsys+"GPS "; - if (rtk->opt.navsys&SYS_GLO) navsys=navsys+"GLONASS "; - if (rtk->opt.navsys&SYS_GAL) navsys=navsys+"Galileo "; - if (rtk->opt.navsys&SYS_QZS) navsys=navsys+"QZSS "; - if (rtk->opt.navsys&SYS_CMP) navsys=navsys+"BDS "; - if (rtk->opt.navsys&SYS_IRN) navsys=navsys+"NavIC "; - if (rtk->opt.navsys&SYS_SBS) navsys=navsys+"SBAS "; - - Label->Caption=""; - Tbl->RowCount=55+NFREQ*2; - - i=1; - Tbl->Cells[0][i ]="RTKLIB Version"; - Tbl->Cells[1][i++]=s.sprintf("%s %s",VER_RTKLIB,PATCH_LEVEL); - - Tbl->Cells[0][i ]="RTK Server Thread"; - Tbl->Cells[1][i++]=s.sprintf("%d",thread); - - Tbl->Cells[0][i ]="RTK Server State"; - Tbl->Cells[1][i++]=svrstate[state]; - - Tbl->Cells[0][i ]="Processing Cycle (ms)"; - Tbl->Cells[1][i++]=s.sprintf("%d",cycle); - - Tbl->Cells[0][i ]="Positioning Mode"; - Tbl->Cells[1][i++]=mode[rtk->opt.mode]; - - Tbl->Cells[0][i ]="Frequencies"; - Tbl->Cells[1][i++]=freq[rtk->opt.nf]; - - Tbl->Cells[0][i ]="Elevation Mask (deg)"; - Tbl->Cells[1][i++]=s.sprintf("%.0f",rtk->opt.elmin*R2D); - - Tbl->Cells[0][i ]="SNR Mask L1 (dBHz)"; - Tbl->Cells[1][i++]=!rtk->opt.snrmask.ena[0]?s.sprintf(""): - s.sprintf("%.0f, %.0f, %.0f, %.0f, %.0f, %.0f, %.0f, %.0f, %.0f", - rtk->opt.snrmask.mask[0][0],rtk->opt.snrmask.mask[0][1],rtk->opt.snrmask.mask[0][2], - rtk->opt.snrmask.mask[0][3],rtk->opt.snrmask.mask[0][4],rtk->opt.snrmask.mask[0][5], - rtk->opt.snrmask.mask[0][6],rtk->opt.snrmask.mask[0][7],rtk->opt.snrmask.mask[0][8]); - - Tbl->Cells[0][i ]="SNR Mask L2 (dBHz)"; - Tbl->Cells[1][i++]=!rtk->opt.snrmask.ena[0]?s.sprintf(""): - s.sprintf("%.0f, %.0f, %.0f, %.0f, %.0f, %.0f, %.0f, %.0f, %.0f", - rtk->opt.snrmask.mask[1][0],rtk->opt.snrmask.mask[1][1],rtk->opt.snrmask.mask[1][2], - rtk->opt.snrmask.mask[1][3],rtk->opt.snrmask.mask[1][4],rtk->opt.snrmask.mask[1][5], - rtk->opt.snrmask.mask[1][6],rtk->opt.snrmask.mask[1][7],rtk->opt.snrmask.mask[1][8]); - - Tbl->Cells[0][i ]="SNR Mask L5 (dBHz)"; - Tbl->Cells[1][i++]=!rtk->opt.snrmask.ena[0]?s.sprintf(""): - s.sprintf("%.0f, %.0f, %.0f, %.0f, %.0f, %.0f, %.0f, %.0f, %.0f", - rtk->opt.snrmask.mask[2][0],rtk->opt.snrmask.mask[2][1],rtk->opt.snrmask.mask[2][2], - rtk->opt.snrmask.mask[2][3],rtk->opt.snrmask.mask[2][4],rtk->opt.snrmask.mask[2][5], - rtk->opt.snrmask.mask[2][6],rtk->opt.snrmask.mask[2][7],rtk->opt.snrmask.mask[2][8]); - - Tbl->Cells[0][i ]="SNR Mask L6 (dBHz)"; - Tbl->Cells[1][i++]=!rtk->opt.snrmask.ena[0]?s.sprintf(""): - s.sprintf("%.0f, %.0f, %.0f, %.0f, %.0f, %.0f, %.0f, %.0f, %.0f", - rtk->opt.snrmask.mask[3][0],rtk->opt.snrmask.mask[3][1],rtk->opt.snrmask.mask[3][2], - rtk->opt.snrmask.mask[3][3],rtk->opt.snrmask.mask[3][4],rtk->opt.snrmask.mask[3][5], - rtk->opt.snrmask.mask[3][6],rtk->opt.snrmask.mask[3][7],rtk->opt.snrmask.mask[3][8]); - Tbl->Cells[0][i ]="Rec Dynamic/Earth Tides Correction"; - Tbl->Cells[1][i++]=s.sprintf("%s, %s",rtk->opt.dynamics?"ON":"OFF",rtk->opt.tidecorr?"ON":"OFF"); - - Tbl->Cells[0][i ]="Ionosphere/Troposphere Model"; - Tbl->Cells[1][i++]=s.sprintf("%s, %s",ionoopt[rtk->opt.ionoopt],tropopt[rtk->opt.tropopt]); - - Tbl->Cells[0][i ]="Satellite Ephemeris"; - Tbl->Cells[1][i++]=ephopt[rtk->opt.sateph]; - - for (j=1;j<=MAXSAT;j++) { - if (!rtk->opt.exsats[j-1]) continue; - satno2id(j,id); - if (rtk->opt.exsats[j-1]==2) exsats=exsats+"+"; - exsats=exsats+id+" "; - } - Tbl->Cells[0][i ]="Excluded Satellites"; - Tbl->Cells[1][i++]=exsats; - - Tbl->Cells[0][i ]="Navi Systems"; - Tbl->Cells[1][i++]=navsys; - - Tbl->Cells[0][i ]="Accumulated Time to Run"; - Tbl->Cells[1][i++]=s.sprintf("%02.0f:%02.0f:%04.1f",rt[0],rt[1],rt[2]); - - Tbl->Cells[0][i ]="CPU Time for a Processing Cycle (ms)"; - Tbl->Cells[1][i++]=s.sprintf("%d",cputime); - - Tbl->Cells[0][i ]="Missing Obs Data Count"; - Tbl->Cells[1][i++]=s.sprintf("%d",prcout); - - Tbl->Cells[0][i ]="Bytes in Input Buffer"; - Tbl->Cells[1][i++]=s.sprintf("%d, %d, %d",nb[0],nb[1],nb[2]); - - Tbl->Cells[0][i ]="# of Input Data Rover"; - Tbl->Cells[1][i++]=s.sprintf("Obs(%d), Nav(%d), Ion(%d), Sbs(%d), Pos(%d), Dgps(%d), Ssr(%d), Err(%d)", - nmsg[0][0],nmsg[0][1]+nmsg[0][6],nmsg[0][2],nmsg[0][3], - nmsg[0][4],nmsg[0][5],nmsg[0][7],nmsg[0][9]); - - Tbl->Cells[0][i ]="# of Input Data Base Station"; - Tbl->Cells[1][i++]=s.sprintf("Obs(%d), Nav(%d), Ion(%d), Sbs(%d), Pos(%d), Dgps(%d), Ssr(%d), Err(%d)", - nmsg[1][0],nmsg[1][1]+nmsg[1][6],nmsg[1][2],nmsg[1][3], - nmsg[1][4],nmsg[1][5],nmsg[1][7],nmsg[1][9]); - - Tbl->Cells[0][i ]="# of Input Data Ephemeris"; - Tbl->Cells[1][i++]=s.sprintf("Obs(%d), Nav(%d), Ion(%d), Sbs(%d), Pos(%d), Dgps(%d), Ssr(%d), Err(%d)", - nmsg[2][0],nmsg[2][1]+nmsg[2][6],nmsg[2][2],nmsg[2][3], - nmsg[2][4],nmsg[2][5],nmsg[2][7],nmsg[2][9]); - - Tbl->Cells[0][i ]="Solution Status"; - Tbl->Cells[1][i++]=sol[rtkstat]; - - time2str(rtk->sol.time,tstr,9); - Tbl->Cells[0][i ] ="Time of Receiver Clock Rover"; - Tbl->Cells[1][i++]=rtk->sol.time.time?tstr:"-"; - - Tbl->Cells[0][i ] ="Time Sytem Offset/Receiver Bias (GLO-GPS,GAL-GPS,BDS-GPS,IRN-GPS) (ns)"; - Tbl->Cells[1][i++]=s.sprintf("%.3f, %.3f, %.3f, %.3f",rtk->sol.dtr[1]*1E9,rtk->sol.dtr[2]*1E9, - rtk->sol.dtr[3]*1E9,rtk->sol.dtr[4]*1E9); - - Tbl->Cells[0][i ]="Solution Interval (s)"; - Tbl->Cells[1][i++]=s.sprintf("%.3f",rtk->tt); - - Tbl->Cells[0][i ]="Age of Differential (s)"; - Tbl->Cells[1][i++] =s.sprintf("%.3f",rtk->sol.age); - - Tbl->Cells[0][i ]="Ratio for AR Validation"; - Tbl->Cells[1][i++]=s.sprintf("%.3f",rtk->sol.ratio); - - Tbl->Cells[0][i ]="# of Satellites Rover"; - Tbl->Cells[1][i++]=s.sprintf("%d",nsat0); - - Tbl->Cells[0][i ]="# of Satellites Base Station"; - Tbl->Cells[1][i++]=s.sprintf("%d",nsat1); - - Tbl->Cells[0][i ]="# of Valid Satellites"; - Tbl->Cells[1][i++]=s.sprintf("%d",rtk->sol.ns); - - Tbl->Cells[0][i ]="GDOP/PDOP/HDOP/VDOP"; - Tbl->Cells[1][i++]=s.sprintf("%.1f, %.1f, %.1f, %.1f",dop[0],dop[1],dop[2],dop[3]); - - Tbl->Cells[0][i ]="# of Real Estimated States"; - Tbl->Cells[1][i++]=s.sprintf("%d",rtk->na); - - Tbl->Cells[0][i ]="# of All Estimated States"; - Tbl->Cells[1][i++]=s.sprintf("%d",rtk->nx); - - Tbl->Cells[0][i ]="Pos X/Y/Z Single (m) Rover"; - Tbl->Cells[1][i++]=s.sprintf("%.3f, %.3f, %.3f",rtk->sol.rr[0],rtk->sol.rr[1],rtk->sol.rr[2]); - - if (norm(rtk->sol.rr,3)>0.0) ecef2pos(rtk->sol.rr,pos); else pos[0]=pos[1]=pos[2]=0.0; - Tbl->Cells[0][i ]="Lat/Lon/Height Single (deg,m) Rover"; - Tbl->Cells[1][i++]=s.sprintf("%.8f, %.8f, %.3f",pos[0]*R2D,pos[1]*R2D,pos[2]); - - ecef2enu(pos,rtk->sol.rr+3,vel); - Tbl->Cells[0][i ]="Vel E/N/U (m/s) Rover"; - Tbl->Cells[1][i++]=s.sprintf("%.3f, %.3f, %.3f",vel[0],vel[1],vel[2]); - - Tbl->Cells[0][i ]="Pos X/Y/Z Float (m) Rover"; - Tbl->Cells[1][i++]=s.sprintf("%.3f, %.3f, %.3f", - rtk->x?rtk->x[0]:0,rtk->x?rtk->x[1]:0,rtk->x?rtk->x[2]:0); - - Tbl->Cells[0][i ]="Pos X/Y/Z Float Std (m) Rover"; - Tbl->Cells[1][i++]=s.sprintf("%.3f, %.3f, %.3f", - rtk->P?SQRT(rtk->P[0]):0,rtk->P?SQRT(rtk->P[1+1*rtk->nx]):0,rtk->P?SQRT(rtk->P[2+2*rtk->nx]):0); - - Tbl->Cells[0][i ]="Pos X/Y/Z Fixed (m) Rover"; - Tbl->Cells[1][i++]=s.sprintf("%.3f, %.3f, %.3f", - rtk->xa?rtk->xa[0]:0,rtk->xa?rtk->xa[1]:0,rtk->xa?rtk->xa[2]:0); - - Tbl->Cells[0][i ]="Pos X/Y/Z Fixed Std (m) Rover"; - Tbl->Cells[1][i++]=s.sprintf("%.3f, %.3f, %.3f", - rtk->Pa?SQRT(rtk->Pa[0]):0,rtk->Pa?SQRT(rtk->Pa[1+1*rtk->na]):0,rtk->Pa?SQRT(rtk->Pa[2+2*rtk->na]):0); - - Tbl->Cells[0][i ]="Pos X/Y/Z (m) Base Station"; - Tbl->Cells[1][i++]=s.sprintf("%.3f, %.3f, %.3f",rtk->rb[0],rtk->rb[1],rtk->rb[2]); - - if (norm(rtk->rb,3)>0.0) ecef2pos(rtk->rb,pos); else pos[0]=pos[1]=pos[2]=0.0; - Tbl->Cells[0][i ]="Lat/Lon/Height (deg,m) Base Station"; - Tbl->Cells[1][i++]=s.sprintf("%.8f, %.8f, %.3f",pos[0]*R2D,pos[1]*R2D,pos[2]); - - ecef2enu(pos,rtk->rb+3,vel); - Tbl->Cells[0][i ]="Vel E/N/U (m/s) Base Station"; - Tbl->Cells[1][i++]=s.sprintf("%.3f, %.3f, %.3f",vel[0],vel[1],vel[2]); - - if (norm(rtk->rb,3)>0.0) { - for (k=0;k<3;k++) rr[k]=rtk->sol.rr[k]-rtk->rb[k]; - ecef2enu(pos,rr,enu); - } - Tbl->Cells[0][i ]="Baseline Length/E/N/U (m) Rover-Base Station"; - Tbl->Cells[1][i++]=s.sprintf("%.3f, %.3f, %.3f, %.3f",norm(rr,3),enu[0],enu[1],enu[2]); - - Tbl->Cells[0][i ]="# of Averaging Single Pos Base Station"; - Tbl->Cells[1][i++]=s.sprintf("%d",nave); - - Tbl->Cells[0][i ]="Antenna Type Rover"; - Tbl->Cells[1][i++]=rtk->opt.pcvr[0].type; - - for (j=0;jopt.pcvr[0].off[j]; - Tbl->Cells[0][i ]=s.sprintf("Ant Phase Center L%d E/N/U (m) Rover",j+1); - Tbl->Cells[1][i++]=s.sprintf("%.3f, %.3f, %.3f",off[0],off[1],off[2]); - } - del=rtk->opt.antdel[0]; - Tbl->Cells[0][i ]="Ant Delta E/N/U (m) Rover"; - Tbl->Cells[1][i++]=s.sprintf("%.3f, %.3f, %.3f",del[0],del[1],del[2]); - - Tbl->Cells[0][i ]="Antenna Type Base Station"; - Tbl->Cells[1][i++]=rtk->opt.pcvr[1].type; - - for (j=0;jopt.pcvr[1].off[0]; - Tbl->Cells[0][i ]=s.sprintf("Ant Phase Center L%d E/N/U (m) Base Station",j+1); - Tbl->Cells[1][i++]=s.sprintf("%.3f, %.3f, %.3f",off[0],off[1],off[2]); - } - del=rtk->opt.antdel[1]; - Tbl->Cells[0][i ]="Ant Delta E/N/U (m) Base Station"; - Tbl->Cells[1][i++]=s.sprintf("%.3f, %.3f, %.3f",del[0],del[1],del[2]); - - Tbl->Cells[0][i ]="Precise Ephemeris Time/# of Epoch"; - Tbl->Cells[1][i++]=s.sprintf("%s-%s (%d)",s1,s2,ne); - - Tbl->Cells[0][i ]="Precise Ephemeris Download Time"; - Tbl->Cells[1][i++]=s3; - - Tbl->Cells[0][i ]="Precise Ephemeris Download File"; - Tbl->Cells[1][i++]=file; - free(rtk); +void __fastcall TMonitorDialog::ShowRtk(void) { + AnsiString s, exsats, navsys = ""; + AnsiString svrstate[] = {"Stop", "Run"}; + AnsiString sol[] = {"-", "Fix", "Float", "SBAS", "DGPS", "Single", "PPP", ""}; + AnsiString mode[] = {"Single", "DGPS", "Kinematic", "Static", "Static-Start", + "Moving-Base", "Fixed", "PPP-Kinematic", "PPP-Static", ""}; + AnsiString freq[] = {"-", "L1", "L1+L2", "L1+L2+L3", "L1+L2+L3+L4", "L1+L2+L3+L4+L5", ""}; + double *del, *off, runtime, rt[3] = {0}, dop[4] = {0}; + double azel[MAXSAT * 2], pos[3], vel[3], rr[3] = {0}, enu[3] = {0}; + int i, j, k, thread, cycle, state, rtkstat, nsat0, nsat1, prcout, nave; + int cputime, nb[3] = {0}, nmsg[3][10] = {{0}}, ne; + char tstr[40], *ant, id[8], s1[40] = "-", s2[40] = "-", s3[40] = "-"; + char file[1024] = ""; + const char *ionoopt[] = {"OFF", "Broadcast", "SBAS", "Dual-Frequency", + "Estimate STEC", "IONEX TEC", "QZSS LEX", ""}; + const char *tropopt[] = {"OFF", "Saastamoinen", "SBAS", "Estimate ZTD", "Estimate ZTD+Grad", ""}; + const char *ephopt[] = { + "Broadcast", "Precise", "Broadcast+SBAS", "Broadcat+SSR APC", "Broadcast+SSR CoM", + "QZSS LEX", ""}; + + rtk_t *rtk = static_cast(malloc(sizeof(rtk_t))); + if (rtk == NULL) return; + + rtksvrlock(&rtksvr); // lock + + *rtk = rtksvr.rtk; + thread = (int)rtksvr.thread; + cycle = rtksvr.cycle; + state = rtksvr.state; + rtkstat = rtksvr.rtk.sol.stat; + nsat0 = rtksvr.obs[0][0].n; + nsat1 = rtksvr.obs[1][0].n; + cputime = rtksvr.cputime; + prcout = rtksvr.prcout; + nave = rtksvr.nave; + for (i = 0; i < 3; i++) nb[i] = rtksvr.nb[i]; + for (i = 0; i < 3; i++) + for (j = 0; j < 10; j++) { + nmsg[i][j] = rtksvr.nmsg[i][j]; + } + if (rtksvr.state) { + runtime = (double)(tickget() - rtksvr.tick) / 1000.0; + rt[0] = floor(runtime / 3600.0); + runtime -= rt[0] * 3600.0; + rt[1] = floor(runtime / 60.0); + rt[2] = runtime - rt[1] * 60.0; + } + if ((ne = rtksvr.nav.ne) > 0) { + time2str(rtksvr.nav.peph[0].time, s1, 0); + time2str(rtksvr.nav.peph[ne - 1].time, s2, 0); + time2str(rtksvr.ftime[2], s3, 0); + } + strcpy(file, rtksvr.files[2]); + + rtksvrunlock(&rtksvr); // unlock + + for (j = k = 0; j < MAXSAT; j++) { + if (rtk->opt.mode == PMODE_SINGLE && !rtk->ssat[j].vs) continue; + if (rtk->opt.mode != PMODE_SINGLE && !rtk->ssat[j].vsat[0]) continue; + azel[k * 2] = rtk->ssat[j].azel[0]; + azel[1 + k * 2] = rtk->ssat[j].azel[1]; + k++; + } + dops(k, azel, 0.0, dop); + + if (rtk->opt.navsys & SYS_GPS) navsys = navsys + "GPS "; + if (rtk->opt.navsys & SYS_GLO) navsys = navsys + "GLONASS "; + if (rtk->opt.navsys & SYS_GAL) navsys = navsys + "Galileo "; + if (rtk->opt.navsys & SYS_QZS) navsys = navsys + "QZSS "; + if (rtk->opt.navsys & SYS_CMP) navsys = navsys + "BDS "; + if (rtk->opt.navsys & SYS_IRN) navsys = navsys + "NavIC "; + if (rtk->opt.navsys & SYS_SBS) navsys = navsys + "SBAS "; + + Label->Caption = ""; + Tbl->RowCount = 55 + NFREQ * 2; + + i = 1; + Tbl->Cells[0][i] = "RTKLIB Version"; + Tbl->Cells[1][i++] = s.sprintf("%s %s", VER_RTKLIB, PATCH_LEVEL); + + Tbl->Cells[0][i] = "RTK Server Thread"; + Tbl->Cells[1][i++] = s.sprintf("%d", thread); + + Tbl->Cells[0][i] = "RTK Server State"; + Tbl->Cells[1][i++] = svrstate[state]; + + Tbl->Cells[0][i] = "Processing Cycle (ms)"; + Tbl->Cells[1][i++] = s.sprintf("%d", cycle); + + Tbl->Cells[0][i] = "Positioning Mode"; + Tbl->Cells[1][i++] = mode[rtk->opt.mode]; + + Tbl->Cells[0][i] = "Frequencies"; + Tbl->Cells[1][i++] = freq[rtk->opt.nf]; + + Tbl->Cells[0][i] = "Elevation Mask (deg)"; + Tbl->Cells[1][i++] = s.sprintf("%.0f", rtk->opt.elmin * R2D); + + Tbl->Cells[0][i] = "SNR Mask L1 (dBHz)"; + Tbl->Cells[1][i++] = !rtk->opt.snrmask.ena[0] + ? s.sprintf("") + : s.sprintf("%.0f, %.0f, %.0f, %.0f, %.0f, %.0f, %.0f, %.0f, %.0f", + rtk->opt.snrmask.mask[0][0], rtk->opt.snrmask.mask[0][1], + rtk->opt.snrmask.mask[0][2], rtk->opt.snrmask.mask[0][3], + rtk->opt.snrmask.mask[0][4], rtk->opt.snrmask.mask[0][5], + rtk->opt.snrmask.mask[0][6], rtk->opt.snrmask.mask[0][7], + rtk->opt.snrmask.mask[0][8]); + + Tbl->Cells[0][i] = "SNR Mask L2 (dBHz)"; + Tbl->Cells[1][i++] = !rtk->opt.snrmask.ena[0] + ? s.sprintf("") + : s.sprintf("%.0f, %.0f, %.0f, %.0f, %.0f, %.0f, %.0f, %.0f, %.0f", + rtk->opt.snrmask.mask[1][0], rtk->opt.snrmask.mask[1][1], + rtk->opt.snrmask.mask[1][2], rtk->opt.snrmask.mask[1][3], + rtk->opt.snrmask.mask[1][4], rtk->opt.snrmask.mask[1][5], + rtk->opt.snrmask.mask[1][6], rtk->opt.snrmask.mask[1][7], + rtk->opt.snrmask.mask[1][8]); + + Tbl->Cells[0][i] = "SNR Mask L5 (dBHz)"; + Tbl->Cells[1][i++] = !rtk->opt.snrmask.ena[0] + ? s.sprintf("") + : s.sprintf("%.0f, %.0f, %.0f, %.0f, %.0f, %.0f, %.0f, %.0f, %.0f", + rtk->opt.snrmask.mask[2][0], rtk->opt.snrmask.mask[2][1], + rtk->opt.snrmask.mask[2][2], rtk->opt.snrmask.mask[2][3], + rtk->opt.snrmask.mask[2][4], rtk->opt.snrmask.mask[2][5], + rtk->opt.snrmask.mask[2][6], rtk->opt.snrmask.mask[2][7], + rtk->opt.snrmask.mask[2][8]); + + Tbl->Cells[0][i] = "SNR Mask L6 (dBHz)"; + Tbl->Cells[1][i++] = !rtk->opt.snrmask.ena[0] + ? s.sprintf("") + : s.sprintf("%.0f, %.0f, %.0f, %.0f, %.0f, %.0f, %.0f, %.0f, %.0f", + rtk->opt.snrmask.mask[3][0], rtk->opt.snrmask.mask[3][1], + rtk->opt.snrmask.mask[3][2], rtk->opt.snrmask.mask[3][3], + rtk->opt.snrmask.mask[3][4], rtk->opt.snrmask.mask[3][5], + rtk->opt.snrmask.mask[3][6], rtk->opt.snrmask.mask[3][7], + rtk->opt.snrmask.mask[3][8]); + Tbl->Cells[0][i] = "Rec Dynamic/Earth Tides Correction"; + Tbl->Cells[1][i++] = + s.sprintf("%s, %s", rtk->opt.dynamics ? "ON" : "OFF", rtk->opt.tidecorr ? "ON" : "OFF"); + + Tbl->Cells[0][i] = "Ionosphere/Troposphere Model"; + Tbl->Cells[1][i++] = s.sprintf("%s, %s", ionoopt[rtk->opt.ionoopt], tropopt[rtk->opt.tropopt]); + + Tbl->Cells[0][i] = "Satellite Ephemeris"; + Tbl->Cells[1][i++] = ephopt[rtk->opt.sateph]; + + for (j = 1; j <= MAXSAT; j++) { + if (!rtk->opt.exsats[j - 1]) continue; + satno2id(j, id); + if (rtk->opt.exsats[j - 1] == 2) exsats = exsats + "+"; + exsats = exsats + id + " "; + } + Tbl->Cells[0][i] = "Excluded Satellites"; + Tbl->Cells[1][i++] = exsats; + + Tbl->Cells[0][i] = "Navi Systems"; + Tbl->Cells[1][i++] = navsys; + + Tbl->Cells[0][i] = "Accumulated Time to Run"; + Tbl->Cells[1][i++] = s.sprintf("%02.0f:%02.0f:%04.1f", rt[0], rt[1], rt[2]); + + Tbl->Cells[0][i] = "CPU Time for a Processing Cycle (ms)"; + Tbl->Cells[1][i++] = s.sprintf("%d", cputime); + + Tbl->Cells[0][i] = "Missing Obs Data Count"; + Tbl->Cells[1][i++] = s.sprintf("%d", prcout); + + Tbl->Cells[0][i] = "Bytes in Input Buffer"; + Tbl->Cells[1][i++] = s.sprintf("%d, %d, %d", nb[0], nb[1], nb[2]); + + Tbl->Cells[0][i] = "# of Input Data Rover"; + Tbl->Cells[1][i++] = + s.sprintf("Obs(%d), Nav(%d), Ion(%d), Sbs(%d), Pos(%d), Dgps(%d), Ssr(%d), Err(%d)", + nmsg[0][0], nmsg[0][1] + nmsg[0][6], nmsg[0][2], nmsg[0][3], nmsg[0][4], nmsg[0][5], + nmsg[0][7], nmsg[0][9]); + + Tbl->Cells[0][i] = "# of Input Data Base Station"; + Tbl->Cells[1][i++] = + s.sprintf("Obs(%d), Nav(%d), Ion(%d), Sbs(%d), Pos(%d), Dgps(%d), Ssr(%d), Err(%d)", + nmsg[1][0], nmsg[1][1] + nmsg[1][6], nmsg[1][2], nmsg[1][3], nmsg[1][4], nmsg[1][5], + nmsg[1][7], nmsg[1][9]); + + Tbl->Cells[0][i] = "# of Input Data Ephemeris"; + Tbl->Cells[1][i++] = + s.sprintf("Obs(%d), Nav(%d), Ion(%d), Sbs(%d), Pos(%d), Dgps(%d), Ssr(%d), Err(%d)", + nmsg[2][0], nmsg[2][1] + nmsg[2][6], nmsg[2][2], nmsg[2][3], nmsg[2][4], nmsg[2][5], + nmsg[2][7], nmsg[2][9]); + + Tbl->Cells[0][i] = "Solution Status"; + Tbl->Cells[1][i++] = sol[rtkstat]; + + time2str(rtk->sol.time, tstr, 9); + Tbl->Cells[0][i] = "Time of Receiver Clock Rover"; + Tbl->Cells[1][i++] = rtk->sol.time.time ? tstr : "-"; + + Tbl->Cells[0][i] = "Time Sytem Offset/Receiver Bias (GLO-GPS,GAL-GPS,BDS-GPS,IRN-GPS) (ns)"; + Tbl->Cells[1][i++] = + s.sprintf("%.3f, %.3f, %.3f, %.3f", rtk->sol.dtr[1] * 1E9, rtk->sol.dtr[2] * 1E9, + rtk->sol.dtr[3] * 1E9, rtk->sol.dtr[4] * 1E9); + + Tbl->Cells[0][i] = "Solution Interval (s)"; + Tbl->Cells[1][i++] = s.sprintf("%.3f", rtk->tt); + + Tbl->Cells[0][i] = "Age of Differential (s)"; + Tbl->Cells[1][i++] = s.sprintf("%.3f", rtk->sol.age); + + Tbl->Cells[0][i] = "Ratio for AR Validation"; + Tbl->Cells[1][i++] = s.sprintf("%.3f", rtk->sol.ratio); + + Tbl->Cells[0][i] = "# of Satellites Rover"; + Tbl->Cells[1][i++] = s.sprintf("%d", nsat0); + + Tbl->Cells[0][i] = "# of Satellites Base Station"; + Tbl->Cells[1][i++] = s.sprintf("%d", nsat1); + + Tbl->Cells[0][i] = "# of Valid Satellites"; + Tbl->Cells[1][i++] = s.sprintf("%d", rtk->sol.ns); + + Tbl->Cells[0][i] = "GDOP/PDOP/HDOP/VDOP"; + Tbl->Cells[1][i++] = s.sprintf("%.1f, %.1f, %.1f, %.1f", dop[0], dop[1], dop[2], dop[3]); + + Tbl->Cells[0][i] = "# of Real Estimated States"; + Tbl->Cells[1][i++] = s.sprintf("%d", rtk->na); + + Tbl->Cells[0][i] = "# of All Estimated States"; + Tbl->Cells[1][i++] = s.sprintf("%d", rtk->nx); + + Tbl->Cells[0][i] = "Pos X/Y/Z Single (m) Rover"; + Tbl->Cells[1][i++] = + s.sprintf("%.3f, %.3f, %.3f", rtk->sol.rr[0], rtk->sol.rr[1], rtk->sol.rr[2]); + + if (norm(rtk->sol.rr, 3) > 0.0) + ecef2pos(rtk->sol.rr, pos); + else + pos[0] = pos[1] = pos[2] = 0.0; + Tbl->Cells[0][i] = "Lat/Lon/Height Single (deg,m) Rover"; + Tbl->Cells[1][i++] = s.sprintf("%.8f, %.8f, %.3f", pos[0] * R2D, pos[1] * R2D, pos[2]); + + ecef2enu(pos, rtk->sol.rr + 3, vel); + Tbl->Cells[0][i] = "Vel E/N/U (m/s) Rover"; + Tbl->Cells[1][i++] = s.sprintf("%.3f, %.3f, %.3f", vel[0], vel[1], vel[2]); + + Tbl->Cells[0][i] = "Pos X/Y/Z Float (m) Rover"; + Tbl->Cells[1][i++] = s.sprintf("%.3f, %.3f, %.3f", rtk->x ? rtk->x[0] : 0, rtk->x ? rtk->x[1] : 0, + rtk->x ? rtk->x[2] : 0); + + Tbl->Cells[0][i] = "Pos X/Y/Z Float Std (m) Rover"; + Tbl->Cells[1][i++] = s.sprintf("%.3f, %.3f, %.3f", rtk->P ? SQRT(rtk->P[0]) : 0, + rtk->P ? SQRT(rtk->P[1 + 1 * rtk->nx]) : 0, + rtk->P ? SQRT(rtk->P[2 + 2 * rtk->nx]) : 0); + + Tbl->Cells[0][i] = "Pos X/Y/Z Fixed (m) Rover"; + Tbl->Cells[1][i++] = s.sprintf("%.3f, %.3f, %.3f", rtk->xa ? rtk->xa[0] : 0, + rtk->xa ? rtk->xa[1] : 0, rtk->xa ? rtk->xa[2] : 0); + + Tbl->Cells[0][i] = "Pos X/Y/Z Fixed Std (m) Rover"; + Tbl->Cells[1][i++] = s.sprintf("%.3f, %.3f, %.3f", rtk->Pa ? SQRT(rtk->Pa[0]) : 0, + rtk->Pa ? SQRT(rtk->Pa[1 + 1 * rtk->na]) : 0, + rtk->Pa ? SQRT(rtk->Pa[2 + 2 * rtk->na]) : 0); + + Tbl->Cells[0][i] = "Pos X/Y/Z (m) Base Station"; + Tbl->Cells[1][i++] = s.sprintf("%.3f, %.3f, %.3f", rtk->rb[0], rtk->rb[1], rtk->rb[2]); + + if (norm(rtk->rb, 3) > 0.0) + ecef2pos(rtk->rb, pos); + else + pos[0] = pos[1] = pos[2] = 0.0; + Tbl->Cells[0][i] = "Lat/Lon/Height (deg,m) Base Station"; + Tbl->Cells[1][i++] = s.sprintf("%.8f, %.8f, %.3f", pos[0] * R2D, pos[1] * R2D, pos[2]); + + ecef2enu(pos, rtk->rb + 3, vel); + Tbl->Cells[0][i] = "Vel E/N/U (m/s) Base Station"; + Tbl->Cells[1][i++] = s.sprintf("%.3f, %.3f, %.3f", vel[0], vel[1], vel[2]); + + if (norm(rtk->rb, 3) > 0.0) { + for (k = 0; k < 3; k++) rr[k] = rtk->sol.rr[k] - rtk->rb[k]; + ecef2enu(pos, rr, enu); + } + Tbl->Cells[0][i] = "Baseline Length/E/N/U (m) Rover-Base Station"; + Tbl->Cells[1][i++] = s.sprintf("%.3f, %.3f, %.3f, %.3f", norm(rr, 3), enu[0], enu[1], enu[2]); + + Tbl->Cells[0][i] = "# of Averaging Single Pos Base Station"; + Tbl->Cells[1][i++] = s.sprintf("%d", nave); + + Tbl->Cells[0][i] = "Antenna Type Rover"; + Tbl->Cells[1][i++] = rtk->opt.pcvr[0].type; + + for (j = 0; j < NFREQ; j++) { + off = rtk->opt.pcvr[0].off[j]; + Tbl->Cells[0][i] = s.sprintf("Ant Phase Center L%d E/N/U (m) Rover", j + 1); + Tbl->Cells[1][i++] = s.sprintf("%.3f, %.3f, %.3f", off[0], off[1], off[2]); + } + del = rtk->opt.antdel[0]; + Tbl->Cells[0][i] = "Ant Delta E/N/U (m) Rover"; + Tbl->Cells[1][i++] = s.sprintf("%.3f, %.3f, %.3f", del[0], del[1], del[2]); + + Tbl->Cells[0][i] = "Antenna Type Base Station"; + Tbl->Cells[1][i++] = rtk->opt.pcvr[1].type; + + for (j = 0; j < NFREQ; j++) { + off = rtk->opt.pcvr[1].off[0]; + Tbl->Cells[0][i] = s.sprintf("Ant Phase Center L%d E/N/U (m) Base Station", j + 1); + Tbl->Cells[1][i++] = s.sprintf("%.3f, %.3f, %.3f", off[0], off[1], off[2]); + } + del = rtk->opt.antdel[1]; + Tbl->Cells[0][i] = "Ant Delta E/N/U (m) Base Station"; + Tbl->Cells[1][i++] = s.sprintf("%.3f, %.3f, %.3f", del[0], del[1], del[2]); + + Tbl->Cells[0][i] = "Precise Ephemeris Time/# of Epoch"; + Tbl->Cells[1][i++] = s.sprintf("%s-%s (%d)", s1, s2, ne); + + Tbl->Cells[0][i] = "Precise Ephemeris Download Time"; + Tbl->Cells[1][i++] = s3; + + Tbl->Cells[0][i] = "Precise Ephemeris Download File"; + Tbl->Cells[1][i++] = file; + free(rtk); } //--------------------------------------------------------------------------- -void __fastcall TMonitorDialog::SetSat(void) -{ - int i,j=0; - AnsiString s,label[]={ - "SAT","Status","Azimuth (deg)","Elevation (deg)","LG (m)","PHW(cyc)", - "P1-P2(m)","P1-C1(m)","P2-C2(m)" - }; - int width[]={25,30,45,45,60,40,40,40,40},nfreq; - - rtksvrlock(&rtksvr); - nfreq=rtksvr.rtk.opt.nf; - rtksvrunlock(&rtksvr); - - Tbl->ColCount=9+nfreq*8; - Tbl->RowCount=2; - for (i=0;i<4;i++) { - Tbl->ColWidths [j]=width[i]*FontScale/96; - Tbl->Cells[j ][0]=label[i]; - Tbl->Cells[j++][1]=""; - } - for (i=0;iColWidths [j]=30*FontScale/96; - Tbl->Cells[j ][0]=s.sprintf("L%d",i+1); - Tbl->Cells[j++][1]=""; - } - for (i=0;iColWidths [j]=40*FontScale/96; - Tbl->Cells[j ][0]=s.sprintf("Fix%d",i+1); - Tbl->Cells[j++][1]=""; - } - for (i=0;iColWidths [j]=45*FontScale/96; - Tbl->Cells[j ][0]=s.sprintf("P%d Residual(m)",i+1); - Tbl->Cells[j++][1]=""; - } - for (i=0;iColWidths [j]=45*FontScale/96; - Tbl->Cells[j ][0]=s.sprintf("L%d Residual(m)",i+1); - Tbl->Cells[j++][1]=""; - } - for (i=0;iColWidths [j]=45*FontScale/96; - Tbl->Cells[j ][0]=s.sprintf("Slip%d",i+1); - Tbl->Cells[j++][1]=""; - } - for (i=0;iColWidths [j]=45*FontScale/96; - Tbl->Cells[j ][0]=s.sprintf("Lock%d",i+1); - Tbl->Cells[j++][1]=""; - } - for (i=0;iColWidths [j]=45*FontScale/96; - Tbl->Cells[j ][0]=s.sprintf("Outage%d",i+1); - Tbl->Cells[j++][1]=""; - } - for (i=0;iColWidths [j]=45*FontScale/96; - Tbl->Cells[j ][0]=s.sprintf("Reject%d",i+1); - Tbl->Cells[j++][1]=""; - } - for (i=4;i<9;i++) { - Tbl->ColWidths [j]=width[i]*FontScale/96; - Tbl->Cells[j ][0]=label[i]; - Tbl->Cells[j++][1]=""; - } +void __fastcall TMonitorDialog::SetSat(void) { + int i, j = 0; + AnsiString s, label[] = {"SAT", "Status", "Azimuth (deg)", "Elevation (deg)", "LG (m)", + "PHW(cyc)", "P1-P2(m)", "P1-C1(m)", "P2-C2(m)"}; + int width[] = {25, 30, 45, 45, 60, 40, 40, 40, 40}, nfreq; + + rtksvrlock(&rtksvr); + nfreq = rtksvr.rtk.opt.nf; + rtksvrunlock(&rtksvr); + + Tbl->ColCount = 9 + nfreq * 8; + Tbl->RowCount = 2; + for (i = 0; i < 4; i++) { + Tbl->ColWidths[j] = width[i] * FontScale / 96; + Tbl->Cells[j][0] = label[i]; + Tbl->Cells[j++][1] = ""; + } + for (i = 0; i < nfreq; i++) { + Tbl->ColWidths[j] = 30 * FontScale / 96; + Tbl->Cells[j][0] = s.sprintf("L%d", i + 1); + Tbl->Cells[j++][1] = ""; + } + for (i = 0; i < nfreq; i++) { + Tbl->ColWidths[j] = 40 * FontScale / 96; + Tbl->Cells[j][0] = s.sprintf("Fix%d", i + 1); + Tbl->Cells[j++][1] = ""; + } + for (i = 0; i < nfreq; i++) { + Tbl->ColWidths[j] = 45 * FontScale / 96; + Tbl->Cells[j][0] = s.sprintf("P%d Residual(m)", i + 1); + Tbl->Cells[j++][1] = ""; + } + for (i = 0; i < nfreq; i++) { + Tbl->ColWidths[j] = 45 * FontScale / 96; + Tbl->Cells[j][0] = s.sprintf("L%d Residual(m)", i + 1); + Tbl->Cells[j++][1] = ""; + } + for (i = 0; i < nfreq; i++) { + Tbl->ColWidths[j] = 45 * FontScale / 96; + Tbl->Cells[j][0] = s.sprintf("Slip%d", i + 1); + Tbl->Cells[j++][1] = ""; + } + for (i = 0; i < nfreq; i++) { + Tbl->ColWidths[j] = 45 * FontScale / 96; + Tbl->Cells[j][0] = s.sprintf("Lock%d", i + 1); + Tbl->Cells[j++][1] = ""; + } + for (i = 0; i < nfreq; i++) { + Tbl->ColWidths[j] = 45 * FontScale / 96; + Tbl->Cells[j][0] = s.sprintf("Outage%d", i + 1); + Tbl->Cells[j++][1] = ""; + } + for (i = 0; i < nfreq; i++) { + Tbl->ColWidths[j] = 45 * FontScale / 96; + Tbl->Cells[j][0] = s.sprintf("Reject%d", i + 1); + Tbl->Cells[j++][1] = ""; + } + for (i = 4; i < 9; i++) { + Tbl->ColWidths[j] = width[i] * FontScale / 96; + Tbl->Cells[j][0] = label[i]; + Tbl->Cells[j++][1] = ""; + } } //--------------------------------------------------------------------------- -void __fastcall TMonitorDialog::ShowSat(void) -{ - ssat_t *ssat; - AnsiString s; - int i,j,k,n,fix,prn,pmode,nfreq,sys=sys_tbl[SelSys->ItemIndex]; - int vsat[MAXSAT]={0}; - char id[8]; - double az,el,cbias[MAXSAT][2]; - - rtk_t *rtk = static_cast(malloc(sizeof(rtk_t))); - if (rtk == NULL) return; - - SetSat(); - - rtksvrlock(&rtksvr); - *rtk=rtksvr.rtk; - for (i=0;iCaption=""; - - for (i=0;issat+i; - vsat[i]=ssat->vs; - } - for (i=0,n=1;issat+i; - if (SelSat->ItemIndex==1&&!vsat[i]) continue; - n++; - } - if (n<2) { - Tbl->RowCount=2; - for (i=0;iColCount;i++) Tbl->Cells[i][1]=""; - free(rtk); - return; - } - Tbl->RowCount=n; - - for (i=0,n=1;issat+i; - if (SelSat->ItemIndex==1&&!vsat[i]) continue; - satno2id(i+1,id); - Tbl->Cells[j++][n]=id; - Tbl->Cells[j++][n]=ssat->vs?"OK":"-"; - az=ssat->azel[0]*R2D; if (az<0.0) az+=360.0; - el=ssat->azel[1]*R2D; - Tbl->Cells[j++][n]=s.sprintf("%.1f",az); - Tbl->Cells[j++][n]=s.sprintf("%.1f",el); - for (k=0;kCells[j++][n]=ssat->vsat[k]?"OK":"-"; - } - for (k=0;kfix[k]; - Tbl->Cells[j++][n]=fix==1?"FLOAT":(fix==2?"FIX":(fix==3?"HOLD":"-")); - } - for (k=0;kCells[j++][n]=s.sprintf("%.2f",ssat->resp[k]); - } - for (k=0;kCells[j++][n]=s.sprintf("%.4f",ssat->resc[k]); - } - for (k=0;kCells[j++][n]=s.sprintf("%d",ssat->slipc[k]); - } - for (k=0;kCells[j++][n]=s.sprintf("%d",ssat->lock[k]); - } - for (k=0;kCells[j++][n]=s.sprintf("%d",ssat->outc[k]); - } - for (k=0;kCells[j++][n]=s.sprintf("%d",ssat->rejc[k]); - } - Tbl->Cells[j++][n]=s.sprintf("%.3f",ssat->gf[0]); - Tbl->Cells[j++][n]=s.sprintf("%.2f",ssat->phw); - Tbl->Cells[j++][n]=s.sprintf("%.2f",cbias[i][0]); - Tbl->Cells[j++][n]=s.sprintf("%.2f",cbias[i][1]); - Tbl->Cells[j++][n]=s.sprintf("%.2f",0); - n++; - } - free(rtk); +void __fastcall TMonitorDialog::ShowSat(void) { + ssat_t *ssat; + AnsiString s; + int i, j, k, n, fix, prn, pmode, nfreq, sys = sys_tbl[SelSys->ItemIndex]; + int vsat[MAXSAT] = {0}; + char id[8]; + double az, el, cbias[MAXSAT][2]; + + rtk_t *rtk = static_cast(malloc(sizeof(rtk_t))); + if (rtk == NULL) return; + + SetSat(); + + rtksvrlock(&rtksvr); + *rtk = rtksvr.rtk; + for (i = 0; i < MAXSAT; i++) + for (j = 0; j < 2; j++) { + cbias[i][j] = rtksvr.nav.cbias[i][j][0]; + } + pmode = rtksvr.rtk.opt.mode; + nfreq = rtksvr.rtk.opt.nf; + rtksvrunlock(&rtksvr); + + Label->Caption = ""; + + for (i = 0; i < MAXSAT; i++) { + ssat = rtk->ssat + i; + vsat[i] = ssat->vs; + } + for (i = 0, n = 1; i < MAXSAT; i++) { + if (!(satsys(i + 1, NULL) & sys)) continue; + ssat = rtk->ssat + i; + if (SelSat->ItemIndex == 1 && !vsat[i]) continue; + n++; + } + if (n < 2) { + Tbl->RowCount = 2; + for (i = 0; i < Tbl->ColCount; i++) Tbl->Cells[i][1] = ""; + free(rtk); + return; + } + Tbl->RowCount = n; + + for (i = 0, n = 1; i < MAXSAT; i++) { + if (!(satsys(i + 1, NULL) & sys)) continue; + j = 0; + ssat = rtk->ssat + i; + if (SelSat->ItemIndex == 1 && !vsat[i]) continue; + satno2id(i + 1, id); + Tbl->Cells[j++][n] = id; + Tbl->Cells[j++][n] = ssat->vs ? "OK" : "-"; + az = ssat->azel[0] * R2D; + if (az < 0.0) az += 360.0; + el = ssat->azel[1] * R2D; + Tbl->Cells[j++][n] = s.sprintf("%.1f", az); + Tbl->Cells[j++][n] = s.sprintf("%.1f", el); + for (k = 0; k < nfreq; k++) { + Tbl->Cells[j++][n] = ssat->vsat[k] ? "OK" : "-"; + } + for (k = 0; k < nfreq; k++) { + fix = ssat->fix[k]; + Tbl->Cells[j++][n] = fix == 1 ? "FLOAT" : (fix == 2 ? "FIX" : (fix == 3 ? "HOLD" : "-")); + } + for (k = 0; k < nfreq; k++) { + Tbl->Cells[j++][n] = s.sprintf("%.2f", ssat->resp[k]); + } + for (k = 0; k < nfreq; k++) { + Tbl->Cells[j++][n] = s.sprintf("%.4f", ssat->resc[k]); + } + for (k = 0; k < nfreq; k++) { + Tbl->Cells[j++][n] = s.sprintf("%d", ssat->slipc[k]); + } + for (k = 0; k < nfreq; k++) { + Tbl->Cells[j++][n] = s.sprintf("%d", ssat->lock[k]); + } + for (k = 0; k < nfreq; k++) { + Tbl->Cells[j++][n] = s.sprintf("%d", ssat->outc[k]); + } + for (k = 0; k < nfreq; k++) { + Tbl->Cells[j++][n] = s.sprintf("%d", ssat->rejc[k]); + } + Tbl->Cells[j++][n] = s.sprintf("%.3f", ssat->gf[0]); + Tbl->Cells[j++][n] = s.sprintf("%.2f", ssat->phw); + Tbl->Cells[j++][n] = s.sprintf("%.2f", cbias[i][0]); + Tbl->Cells[j++][n] = s.sprintf("%.2f", cbias[i][1]); + Tbl->Cells[j++][n] = s.sprintf("%.2f", 0); + n++; + } + free(rtk); } //--------------------------------------------------------------------------- -void __fastcall TMonitorDialog::SetEst(void) -{ - AnsiString label[]={ - "State","Estimate Float","Std Float","Estimate Fixed","Std Fixed" - }; - int i,width[]={40,100,100,100,100}; - - Tbl->ColCount=5; - Tbl->RowCount=2; - for (i=0;iColCount;i++) { - Tbl->ColWidths[i]=width[i]*FontScale/96; - Tbl->Cells[i][0]=label[i]; - Tbl->Cells[i][1]=""; - } +void __fastcall TMonitorDialog::SetEst(void) { + AnsiString label[] = {"State", "Estimate Float", "Std Float", "Estimate Fixed", "Std Fixed"}; + int i, width[] = {40, 100, 100, 100, 100}; + + Tbl->ColCount = 5; + Tbl->RowCount = 2; + for (i = 0; i < Tbl->ColCount; i++) { + Tbl->ColWidths[i] = width[i] * FontScale / 96; + Tbl->Cells[i][0] = label[i]; + Tbl->Cells[i][1] = ""; + } } //--------------------------------------------------------------------------- -void __fastcall TMonitorDialog::ShowEst(void) -{ - gtime_t time; - int i,nx,na,n; - double *x,*P=NULL,*xa=NULL,*Pa=NULL; - AnsiString s,s0="-"; - char tstr[40]; - - rtksvrlock(&rtksvr); - - time=rtksvr.rtk.sol.time; - nx=rtksvr.rtk.nx; - na=rtksvr.rtk.na; - if ((x =(double *)malloc(sizeof(double)*nx))&& - (P =(double *)malloc(sizeof(double)*nx*nx))&& - (xa=(double *)malloc(sizeof(double)*na))&& - (Pa=(double *)malloc(sizeof(double)*na*na))) { - memcpy(x ,rtksvr.rtk.x ,sizeof(double)*nx); - memcpy(P ,rtksvr.rtk.P ,sizeof(double)*nx*nx); - memcpy(xa,rtksvr.rtk.xa,sizeof(double)*na); - memcpy(Pa,rtksvr.rtk.Pa,sizeof(double)*na*na); - } - else { - rtksvrunlock(&rtksvr); - free(x); free(P); free(xa); free(Pa); - return; - } - rtksvrunlock(&rtksvr); - - for (i=0,n=1;iItemIndex==1&&x[i]==0.0) continue; - n++; - } - if (n<2) { - Tbl->RowCount=2; - for (i=0;iColCount;i++) Tbl->Cells[i][1]=""; - return; - } - Tbl->RowCount=n; - - time2str(time,tstr,9); - Label->Caption=time.time?s.sprintf("Time: %s",tstr):s0; - for (i=0,n=1;iItemIndex==1&&x[i]==0.0) continue; - Tbl->Cells[j++][n]=s.sprintf("X_%d",i+1); - Tbl->Cells[j++][n]=x[i]==0.0?s0:s.sprintf("%.3f",x[i]); - Tbl->Cells[j++][n]=P[i+i*nx]==0.0?s0:s.sprintf("%.3f",SQRT(P[i+i*nx])); - Tbl->Cells[j++][n]=i>=na||xa[i]==0?s0:s.sprintf("%.3f",xa[i]); - Tbl->Cells[j++][n]=i>=na||Pa[i+i*na]==0.0?s0:s.sprintf("%.3f",SQRT(Pa[i+i*na])); - n++; - } - free(x); free(P); free(xa); free(Pa); +void __fastcall TMonitorDialog::ShowEst(void) { + gtime_t time; + int i, nx, na, n; + double *x, *P = NULL, *xa = NULL, *Pa = NULL; + AnsiString s, s0 = "-"; + char tstr[40]; + + rtksvrlock(&rtksvr); + + time = rtksvr.rtk.sol.time; + nx = rtksvr.rtk.nx; + na = rtksvr.rtk.na; + if ((x = (double *)malloc(sizeof(double) * nx)) && + (P = (double *)malloc(sizeof(double) * nx * nx)) && + (xa = (double *)malloc(sizeof(double) * na)) && + (Pa = (double *)malloc(sizeof(double) * na * na))) { + memcpy(x, rtksvr.rtk.x, sizeof(double) * nx); + memcpy(P, rtksvr.rtk.P, sizeof(double) * nx * nx); + memcpy(xa, rtksvr.rtk.xa, sizeof(double) * na); + memcpy(Pa, rtksvr.rtk.Pa, sizeof(double) * na * na); + } else { + rtksvrunlock(&rtksvr); + free(x); + free(P); + free(xa); + free(Pa); + return; + } + rtksvrunlock(&rtksvr); + + for (i = 0, n = 1; i < nx; i++) { + if (SelSat->ItemIndex == 1 && x[i] == 0.0) continue; + n++; + } + if (n < 2) { + Tbl->RowCount = 2; + for (i = 0; i < Tbl->ColCount; i++) Tbl->Cells[i][1] = ""; + return; + } + Tbl->RowCount = n; + + time2str(time, tstr, 9); + Label->Caption = time.time ? s.sprintf("Time: %s", tstr) : s0; + for (i = 0, n = 1; i < nx; i++) { + int j = 0; + if (SelSat->ItemIndex == 1 && x[i] == 0.0) continue; + Tbl->Cells[j++][n] = s.sprintf("X_%d", i + 1); + Tbl->Cells[j++][n] = x[i] == 0.0 ? s0 : s.sprintf("%.3f", x[i]); + Tbl->Cells[j++][n] = P[i + i * nx] == 0.0 ? s0 : s.sprintf("%.3f", SQRT(P[i + i * nx])); + Tbl->Cells[j++][n] = i >= na || xa[i] == 0 ? s0 : s.sprintf("%.3f", xa[i]); + Tbl->Cells[j++][n] = + i >= na || Pa[i + i * na] == 0.0 ? s0 : s.sprintf("%.3f", SQRT(Pa[i + i * na])); + n++; + } + free(x); + free(P); + free(xa); + free(Pa); } //--------------------------------------------------------------------------- -void __fastcall TMonitorDialog::SetCov(void) -{ - int i; - - Tbl->ColCount=2; - Tbl->RowCount=2; - for (i=0;i<2;i++) { - Tbl->ColWidths[i]=(i==0?35:45)*FontScale/96; - Tbl->Cells[i][0]=""; - Tbl->Cells[i][1]=""; - } +void __fastcall TMonitorDialog::SetCov(void) { + int i; + + Tbl->ColCount = 2; + Tbl->RowCount = 2; + for (i = 0; i < 2; i++) { + Tbl->ColWidths[i] = (i == 0 ? 35 : 45) * FontScale / 96; + Tbl->Cells[i][0] = ""; + Tbl->Cells[i][1] = ""; + } } //--------------------------------------------------------------------------- -void __fastcall TMonitorDialog::ShowCov(void) -{ - gtime_t time; - int i,j,nx,n,m; - double *x,*P=NULL; - AnsiString s,s0="-"; - char tstr[40]; - - rtksvrlock(&rtksvr); - - time=rtksvr.rtk.sol.time; - nx=rtksvr.rtk.nx; - if ((x =(double *)malloc(sizeof(double)*nx))&& - (P =(double *)malloc(sizeof(double)*nx*nx))) { - memcpy(x ,rtksvr.rtk.x ,sizeof(double)*nx); - memcpy(P ,rtksvr.rtk.P ,sizeof(double)*nx*nx); - } - else { - rtksvrunlock(&rtksvr); - free(x); free(P); - return; - } - rtksvrunlock(&rtksvr); - - for (i=0,n=1;iItemIndex==1&&(x[i]==0.0||P[i+i*nx]==0.0)) continue; - n++; - } - if (n<2) { - Tbl->ColCount=2; - Tbl->RowCount=2; - Tbl->Cells[1][1]=""; - return; - } - Tbl->ColCount=n; - Tbl->RowCount=n; - - time2str(time,tstr,9); - Label->Caption=time.time?s.sprintf("Time: %s",tstr):s0; - for (i=0,n=1;iItemIndex==1&&(x[i]==0.0||P[i+i*nx]==0.0)) continue; - Tbl->ColWidths[n]=45*FontScale/96; - Tbl->Cells[0][n]=s.sprintf("X_%d",i+1); - Tbl->Cells[n][0]=s.sprintf("X_%d",i+1); - for (j=0,m=1;jItemIndex==1&&(x[j]==0.0||P[j+j*nx]==0.0)) continue; - Tbl->Cells[m][n]= - P[i+j*nx]==0.0?s0:s.sprintf("%.5f",SQRT(P[i+j*nx])); - m++; - } - n++; - } - free(x); free(P); +void __fastcall TMonitorDialog::ShowCov(void) { + gtime_t time; + int i, j, nx, n, m; + double *x, *P = NULL; + AnsiString s, s0 = "-"; + char tstr[40]; + + rtksvrlock(&rtksvr); + + time = rtksvr.rtk.sol.time; + nx = rtksvr.rtk.nx; + if ((x = (double *)malloc(sizeof(double) * nx)) && + (P = (double *)malloc(sizeof(double) * nx * nx))) { + memcpy(x, rtksvr.rtk.x, sizeof(double) * nx); + memcpy(P, rtksvr.rtk.P, sizeof(double) * nx * nx); + } else { + rtksvrunlock(&rtksvr); + free(x); + free(P); + return; + } + rtksvrunlock(&rtksvr); + + for (i = 0, n = 1; i < nx; i++) { + if (SelSat->ItemIndex == 1 && (x[i] == 0.0 || P[i + i * nx] == 0.0)) continue; + n++; + } + if (n < 2) { + Tbl->ColCount = 2; + Tbl->RowCount = 2; + Tbl->Cells[1][1] = ""; + return; + } + Tbl->ColCount = n; + Tbl->RowCount = n; + + time2str(time, tstr, 9); + Label->Caption = time.time ? s.sprintf("Time: %s", tstr) : s0; + for (i = 0, n = 1; i < nx; i++) { + if (SelSat->ItemIndex == 1 && (x[i] == 0.0 || P[i + i * nx] == 0.0)) continue; + Tbl->ColWidths[n] = 45 * FontScale / 96; + Tbl->Cells[0][n] = s.sprintf("X_%d", i + 1); + Tbl->Cells[n][0] = s.sprintf("X_%d", i + 1); + for (j = 0, m = 1; j < nx; j++) { + if (SelSat->ItemIndex == 1 && (x[j] == 0.0 || P[j + j * nx] == 0.0)) continue; + Tbl->Cells[m][n] = P[i + j * nx] == 0.0 ? s0 : s.sprintf("%.5f", SQRT(P[i + j * nx])); + m++; + } + n++; + } + free(x); + free(P); } //--------------------------------------------------------------------------- -void __fastcall TMonitorDialog::SetObs(void) -{ - AnsiString s,label[]={"Trcv (GPST)","SAT","STR"}; - int i,j=0,width[]={135,25,25}; - int nex=ObsMode?NEXOBS:0; - - Tbl->ColCount=3+(NFREQ+nex)*6; - Tbl->RowCount=2; - for (i=0;i<3;i++) { - Tbl->ColWidths [j]=width[i]*FontScale/96; - Tbl->Cells[j ][0]=label[i]; - Tbl->Cells[j++][1]=""; - } - for (i=0;iColWidths [j]=22*FontScale/96; - Tbl->Cells[j ][0]=iCells[j++][1]=""; - } - for (i=0;iColWidths [j]=30*FontScale/96; - Tbl->Cells[j ][0]=iCells[j++][1]=""; - } - for (i=0;iColWidths [j]=80*FontScale/96; - Tbl->Cells[j ][0]=iCells[j++][1]=""; - } - for (i=0;iColWidths [j]=85*FontScale/96; - Tbl->Cells[j ][0]=iCells[j++][1]=""; - } - for (i=0;iColWidths [j]=60*FontScale/96; - Tbl->Cells[j ][0]=iCells[j++][1]=""; - } - for (i=0;iColWidths [j]=15*FontScale/96; - Tbl->Cells[j ][0]="I"; - Tbl->Cells[j++][1]=""; - } +void __fastcall TMonitorDialog::SetObs(void) { + AnsiString s, label[] = {"Trcv (GPST)", "SAT", "STR"}; + int i, j = 0, width[] = {135, 25, 25}; + int nex = ObsMode ? NEXOBS : 0; + + Tbl->ColCount = 3 + (NFREQ + nex) * 6; + Tbl->RowCount = 2; + for (i = 0; i < 3; i++) { + Tbl->ColWidths[j] = width[i] * FontScale / 96; + Tbl->Cells[j][0] = label[i]; + Tbl->Cells[j++][1] = ""; + } + for (i = 0; i < NFREQ + nex; i++) { + Tbl->ColWidths[j] = 22 * FontScale / 96; + Tbl->Cells[j][0] = i < NFREQ ? s.sprintf("C%d", i + 1) : s.sprintf("CX%d", i - NFREQ + 1); + Tbl->Cells[j++][1] = ""; + } + for (i = 0; i < NFREQ + nex; i++) { + Tbl->ColWidths[j] = 30 * FontScale / 96; + Tbl->Cells[j][0] = i < NFREQ ? s.sprintf("S%d", i + 1) : s.sprintf("SX%d", i - NFREQ + 1); + Tbl->Cells[j++][1] = ""; + } + for (i = 0; i < NFREQ + nex; i++) { + Tbl->ColWidths[j] = 80 * FontScale / 96; + Tbl->Cells[j][0] = + i < NFREQ ? s.sprintf("P%d (m)", i + 1) : s.sprintf("PX%d (m)", i - NFREQ + 1); + Tbl->Cells[j++][1] = ""; + } + for (i = 0; i < NFREQ + nex; i++) { + Tbl->ColWidths[j] = 85 * FontScale / 96; + Tbl->Cells[j][0] = + i < NFREQ ? s.sprintf("L%d (cycle)", i + 1) : s.sprintf("LX%d (cycle)", i - NFREQ + 1); + Tbl->Cells[j++][1] = ""; + } + for (i = 0; i < NFREQ + nex; i++) { + Tbl->ColWidths[j] = 60 * FontScale / 96; + Tbl->Cells[j][0] = + i < NFREQ ? s.sprintf("D%d (Hz)", i + 1) : s.sprintf("DX%d (Hz)", i - NFREQ + 1); + Tbl->Cells[j++][1] = ""; + } + for (i = 0; i < NFREQ + nex; i++) { + Tbl->ColWidths[j] = 15 * FontScale / 96; + Tbl->Cells[j][0] = "I"; + Tbl->Cells[j++][1] = ""; + } } //--------------------------------------------------------------------------- -void __fastcall TMonitorDialog::ShowObs(void) -{ - AnsiString s; - char tstr[40],id[8],*code; - int i,j,k,n=0,nex=ObsMode?NEXOBS:0,sys=sys_tbl[SelSys->ItemIndex]; - - obsd_t *obs = static_cast(calloc(MAXOBS * 2, sizeof(obsd_t))); - if (obs == NULL) { - trace(1, "TMonitorDialog::ShowObs obsd_t alloc failed\n"); - return; - } - - rtksvrlock(&rtksvr); - for (i=0;iRowCount=n+1<2?2:n+1; - Label->Caption=""; - - for (i=0;iColCount;i++) Tbl->Cells[i][1]=""; - for (i=0;iCells[j++][i+1]=tstr; - satno2id(obs[i].sat,id); - Tbl->Cells[j++][i+1]=id; - Tbl->Cells[j++][i+1]=s.sprintf("(%d)",obs[i].rcv); - for (k=0;kCells[j++][i+1]=s.sprintf("%s",code); - else Tbl->Cells[j++][i+1]="-"; - } - for (k=0;kCells[j++][i+1]=s.sprintf("%.1f",obs[i].SNR[k]); - else Tbl->Cells[j++][i+1]=s.sprintf("-"); - } - for (k=0;kCells[j++][i+1]=s.sprintf("%.3f",obs[i].P[k]); - } - for (k=0;kCells[j++][i+1]=s.sprintf("%.3f",obs[i].L[k]); - } - for (k=0;kCells[j++][i+1]=s.sprintf("%.3f",obs[i].D[k]); - } - for (k=0;kCells[j++][i+1]=s.sprintf("%d",obs[i].LLI[k]); - } - } - free(obs); +void __fastcall TMonitorDialog::ShowObs(void) { + AnsiString s; + char tstr[40], id[8], *code; + int i, j, k, n = 0, nex = ObsMode ? NEXOBS : 0, sys = sys_tbl[SelSys->ItemIndex]; + + obsd_t *obs = static_cast(calloc(MAXOBS * 2, sizeof(obsd_t))); + if (obs == NULL) { + trace(1, "TMonitorDialog::ShowObs obsd_t alloc failed\n"); + return; + } + + rtksvrlock(&rtksvr); + for (i = 0; i < rtksvr.obs[0][0].n && n < MAXOBS * 2; i++) { + if (!(satsys(rtksvr.obs[0][0].data[i].sat, NULL) & sys)) continue; + obs[n++] = rtksvr.obs[0][0].data[i]; + } + for (i = 0; i < rtksvr.obs[1][0].n && n < MAXOBS * 2; i++) { + if (!(satsys(rtksvr.obs[1][0].data[i].sat, NULL) & sys)) continue; + obs[n++] = rtksvr.obs[1][0].data[i]; + } + rtksvrunlock(&rtksvr); + + Tbl->RowCount = n + 1 < 2 ? 2 : n + 1; + Label->Caption = ""; + + for (i = 0; i < Tbl->ColCount; i++) Tbl->Cells[i][1] = ""; + for (i = 0; i < n; i++) { + j = 0; + time2str(obs[i].time, tstr, 3); + Tbl->Cells[j++][i + 1] = tstr; + satno2id(obs[i].sat, id); + Tbl->Cells[j++][i + 1] = id; + Tbl->Cells[j++][i + 1] = s.sprintf("(%d)", obs[i].rcv); + for (k = 0; k < NFREQ + nex; k++) { + code = code2obs(obs[i].code[k]); + if (*code) + Tbl->Cells[j++][i + 1] = s.sprintf("%s", code); + else + Tbl->Cells[j++][i + 1] = "-"; + } + for (k = 0; k < NFREQ + nex; k++) { + if (obs[i].SNR[k]) + Tbl->Cells[j++][i + 1] = s.sprintf("%.1f", obs[i].SNR[k]); + else + Tbl->Cells[j++][i + 1] = s.sprintf("-"); + } + for (k = 0; k < NFREQ + nex; k++) { + Tbl->Cells[j++][i + 1] = s.sprintf("%.3f", obs[i].P[k]); + } + for (k = 0; k < NFREQ + nex; k++) { + Tbl->Cells[j++][i + 1] = s.sprintf("%.3f", obs[i].L[k]); + } + for (k = 0; k < NFREQ + nex; k++) { + Tbl->Cells[j++][i + 1] = s.sprintf("%.3f", obs[i].D[k]); + } + for (k = 0; k < NFREQ + nex; k++) { + Tbl->Cells[j++][i + 1] = s.sprintf("%d", obs[i].LLI[k]); + } + } + free(obs); } //--------------------------------------------------------------------------- -void __fastcall TMonitorDialog::SetNav(void) -{ - UTF8String label[]={ - "SAT","PRN","Status","IODE","IODC","URA","SVH","Toe","Toc","Ttrans", - "A (m)","e","i0 (\302\260)","\316\2510 (\302\260)","\317\211 (\302\260)", - "M0 (\302\260)","\316\224n (\302\260/s)","\316\251dot (\302\260/s)", - "IDOT (\302\260/s)","Af0 (ns)","Af1 (ns/s)","Af2 (ns/s2)","TGD1 (ns)", - "TGD2 (ns)","Cuc (rad)","Cus (rad)","Crc (m)","Crs (m)","Cic (rad)", - "Cis (rad)","Code","Flag", - }; - int i,width[]={ - 25,25,30,30,30,25,25,115,115,115, 80,80,60,60,60,60,70,70,70,70, - 50,50,50,50,70,70,50,50,70, 70,30,30 - }; - Tbl->ColCount=32; - Tbl->RowCount=2; - for (i=0;iColCount;i++) { - Tbl->ColWidths[i]=width[i]*FontScale/96; - Tbl->Cells[i][0]=label[i]; - Tbl->Cells[i][1]=""; - } +void __fastcall TMonitorDialog::SetNav(void) { + UTF8String label[] = { + "SAT", + "PRN", + "Status", + "IODE", + "IODC", + "URA", + "SVH", + "Toe", + "Toc", + "Ttrans", + "A (m)", + "e", + "i0 (\302\260)", + "\316\2510 (\302\260)", + "\317\211 (\302\260)", + "M0 (\302\260)", + "\316\224n (\302\260/s)", + "\316\251dot (\302\260/s)", + "IDOT (\302\260/s)", + "Af0 (ns)", + "Af1 (ns/s)", + "Af2 (ns/s2)", + "TGD1 (ns)", + "TGD2 (ns)", + "Cuc (rad)", + "Cus (rad)", + "Crc (m)", + "Crs (m)", + "Cic (rad)", + "Cis (rad)", + "Code", + "Flag", + }; + int i, width[] = {25, 25, 30, 30, 30, 25, 25, 115, 115, 115, 80, 80, 60, 60, 60, 60, + 70, 70, 70, 70, 50, 50, 50, 50, 70, 70, 50, 50, 70, 70, 30, 30}; + Tbl->ColCount = 32; + Tbl->RowCount = 2; + for (i = 0; i < Tbl->ColCount; i++) { + Tbl->ColWidths[i] = width[i] * FontScale / 96; + Tbl->Cells[i][0] = label[i]; + Tbl->Cells[i][1] = ""; + } } //--------------------------------------------------------------------------- -void __fastcall TMonitorDialog::ShowNav(void) -{ - eph_t eph[MAXSAT]; - gtime_t time; - AnsiString s; - char tstr[40],id[8]; - int i,j,k,n,valid,prn,off=SelEph->ItemIndex*MAXSAT; - int sys=sys_tbl[SelSys2->ItemIndex+1]; - - if (sys==SYS_GLO) { - SetGnav(); - ShowGnav(); - return; - } - if (sys==SYS_SBS) { - SetSbsNav(); - ShowSbsNav(); - return; - } - SetNav(); - - rtksvrlock(&rtksvr); - time=rtksvr.rtk.sol.time; - for (i=0;iCaption=(SelEph->ItemIndex%2)?"F/NAV":"I/NAV"; - } - else { - Label->Caption=""; - } - for (k=0,n=1;kItemIndex==1&&!valid) continue; - n++; - } - if (n<2) { - Tbl->RowCount=2; - for (i=0;iColCount;i++) Tbl->Cells[i][1]=""; - return; - } - Tbl->RowCount=n; - - for (k=0,n=1;kItemIndex==1&&!valid) continue; - satno2id(k+1,id); - Tbl->Cells[j++][n]=id; - Tbl->Cells[j++][n]=s.sprintf("%d",prn); - Tbl->Cells[j++][n]=valid?"OK":"-"; - if (eph[k].iode<0) s="-"; else s.sprintf("%d",eph[k].iode); - Tbl->Cells[j++][n]=s; - if (eph[k].iodc<0) s="-"; else s.sprintf("%d",eph[k].iodc); - Tbl->Cells[j++][n]=s; - Tbl->Cells[j++][n]=s.sprintf("%d",eph[k].sva); - Tbl->Cells[j++][n]=s.sprintf("%03x",eph[k].svh); - if (eph[k].toe.time!=0) time2str(eph[k].toe,tstr,0); else strcpy(tstr,"-"); - Tbl->Cells[j++][n]=tstr; - if (eph[k].toc.time!=0) time2str(eph[k].toc,tstr,0); else strcpy(tstr,"-"); - Tbl->Cells[j++][n]=tstr; - if (eph[k].ttr.time!=0) time2str(eph[k].ttr,tstr,0); else strcpy(tstr,"-"); - Tbl->Cells[j++][n]=tstr; - Tbl->Cells[j++][n]=s.sprintf("%.3f",eph[k].A); - Tbl->Cells[j++][n]=s.sprintf("%.8f",eph[k].e); - Tbl->Cells[j++][n]=s.sprintf("%.5f",eph[k].i0 *R2D); - Tbl->Cells[j++][n]=s.sprintf("%.5f",eph[k].OMG0*R2D); - Tbl->Cells[j++][n]=s.sprintf("%.5f",eph[k].omg *R2D); - Tbl->Cells[j++][n]=s.sprintf("%.5f",eph[k].M0 *R2D); - Tbl->Cells[j++][n]=s.sprintf("%.4E",eph[k].deln*R2D); - Tbl->Cells[j++][n]=s.sprintf("%.4E",eph[k].OMGd*R2D); - Tbl->Cells[j++][n]=s.sprintf("%.4E",eph[k].idot*R2D); - Tbl->Cells[j++][n]=s.sprintf("%.2f",eph[k].f0*1E9); - Tbl->Cells[j++][n]=s.sprintf("%.4f",eph[k].f1*1E9); - Tbl->Cells[j++][n]=s.sprintf("%.4f",eph[k].f2*1E9); - Tbl->Cells[j++][n]=s.sprintf("%.2f",eph[k].tgd[0]*1E9); - Tbl->Cells[j++][n]=s.sprintf("%.2f",eph[k].tgd[1]*1E9); - - Tbl->Cells[j++][n]=s.sprintf("%.4E",eph[k].cuc); - Tbl->Cells[j++][n]=s.sprintf("%.4E",eph[k].cus); - Tbl->Cells[j++][n]=s.sprintf("%.3f",eph[k].crc); - Tbl->Cells[j++][n]=s.sprintf("%.3f",eph[k].crs); - Tbl->Cells[j++][n]=s.sprintf("%.4E",eph[k].cic); - Tbl->Cells[j++][n]=s.sprintf("%.4E",eph[k].cis); - Tbl->Cells[j++][n]=s.sprintf("%03x",eph[k].code); - Tbl->Cells[j++][n]=s.sprintf("%02x",eph[k].flag); - n++; - } +void __fastcall TMonitorDialog::ShowNav(void) { + eph_t eph[MAXSAT]; + gtime_t time; + AnsiString s; + char tstr[40], id[8]; + int i, j, k, n, valid, prn, off = SelEph->ItemIndex * MAXSAT; + int sys = sys_tbl[SelSys2->ItemIndex + 1]; + + if (sys == SYS_GLO) { + SetGnav(); + ShowGnav(); + return; + } + if (sys == SYS_SBS) { + SetSbsNav(); + ShowSbsNav(); + return; + } + SetNav(); + + rtksvrlock(&rtksvr); + time = rtksvr.rtk.sol.time; + for (i = 0; i < MAXSAT; i++) eph[i] = rtksvr.nav.eph[i + off]; + rtksvrunlock(&rtksvr); + + if (sys == SYS_GAL) { + Label->Caption = (SelEph->ItemIndex % 2) ? "F/NAV" : "I/NAV"; + } else { + Label->Caption = ""; + } + for (k = 0, n = 1; k < MAXSAT; k++) { + int ssys = satsys(k + 1, &prn); + if (!(ssys & sys)) continue; + // Mask QZS LEX health. + valid = eph[k].toe.time != 0 && fabs(timediff(time, eph[k].toe)) <= MAXDTOE && + (ssys == SYS_QZS ? (eph[k].svh & 0xfe) == 0 : eph[k].svh == 0); + if (SelSat->ItemIndex == 1 && !valid) continue; + n++; + } + if (n < 2) { + Tbl->RowCount = 2; + for (i = 0; i < Tbl->ColCount; i++) Tbl->Cells[i][1] = ""; + return; + } + Tbl->RowCount = n; + + for (k = 0, n = 1; k < MAXSAT; k++) { + j = 0; + int ssys = satsys(k + 1, &prn); + if (!(ssys & sys)) continue; + // Mask QZS LEX health. + valid = eph[k].toe.time != 0 && fabs(timediff(time, eph[k].toe)) <= MAXDTOE && + (ssys == SYS_QZS ? (eph[k].svh & 0xfe) == 0 : eph[k].svh == 0); + if (SelSat->ItemIndex == 1 && !valid) continue; + satno2id(k + 1, id); + Tbl->Cells[j++][n] = id; + Tbl->Cells[j++][n] = s.sprintf("%d", prn); + Tbl->Cells[j++][n] = valid ? "OK" : "-"; + if (eph[k].iode < 0) + s = "-"; + else + s.sprintf("%d", eph[k].iode); + Tbl->Cells[j++][n] = s; + if (eph[k].iodc < 0) + s = "-"; + else + s.sprintf("%d", eph[k].iodc); + Tbl->Cells[j++][n] = s; + Tbl->Cells[j++][n] = s.sprintf("%d", eph[k].sva); + Tbl->Cells[j++][n] = s.sprintf("%03x", eph[k].svh); + if (eph[k].toe.time != 0) + time2str(eph[k].toe, tstr, 0); + else + strcpy(tstr, "-"); + Tbl->Cells[j++][n] = tstr; + if (eph[k].toc.time != 0) + time2str(eph[k].toc, tstr, 0); + else + strcpy(tstr, "-"); + Tbl->Cells[j++][n] = tstr; + if (eph[k].ttr.time != 0) + time2str(eph[k].ttr, tstr, 0); + else + strcpy(tstr, "-"); + Tbl->Cells[j++][n] = tstr; + Tbl->Cells[j++][n] = s.sprintf("%.3f", eph[k].A); + Tbl->Cells[j++][n] = s.sprintf("%.8f", eph[k].e); + Tbl->Cells[j++][n] = s.sprintf("%.5f", eph[k].i0 * R2D); + Tbl->Cells[j++][n] = s.sprintf("%.5f", eph[k].OMG0 * R2D); + Tbl->Cells[j++][n] = s.sprintf("%.5f", eph[k].omg * R2D); + Tbl->Cells[j++][n] = s.sprintf("%.5f", eph[k].M0 * R2D); + Tbl->Cells[j++][n] = s.sprintf("%.4E", eph[k].deln * R2D); + Tbl->Cells[j++][n] = s.sprintf("%.4E", eph[k].OMGd * R2D); + Tbl->Cells[j++][n] = s.sprintf("%.4E", eph[k].idot * R2D); + Tbl->Cells[j++][n] = s.sprintf("%.2f", eph[k].f0 * 1E9); + Tbl->Cells[j++][n] = s.sprintf("%.4f", eph[k].f1 * 1E9); + Tbl->Cells[j++][n] = s.sprintf("%.4f", eph[k].f2 * 1E9); + Tbl->Cells[j++][n] = s.sprintf("%.2f", eph[k].tgd[0] * 1E9); + Tbl->Cells[j++][n] = s.sprintf("%.2f", eph[k].tgd[1] * 1E9); + + Tbl->Cells[j++][n] = s.sprintf("%.4E", eph[k].cuc); + Tbl->Cells[j++][n] = s.sprintf("%.4E", eph[k].cus); + Tbl->Cells[j++][n] = s.sprintf("%.3f", eph[k].crc); + Tbl->Cells[j++][n] = s.sprintf("%.3f", eph[k].crs); + Tbl->Cells[j++][n] = s.sprintf("%.4E", eph[k].cic); + Tbl->Cells[j++][n] = s.sprintf("%.4E", eph[k].cis); + Tbl->Cells[j++][n] = s.sprintf("%03x", eph[k].code); + Tbl->Cells[j++][n] = s.sprintf("%02x", eph[k].flag); + n++; + } } //--------------------------------------------------------------------------- -void __fastcall TMonitorDialog::SetGnav(void) -{ - UTF8String label[]={ - "SAT","PRN","Status","IOD","FCN","SVH","Age (days)","Toe","Tof", - "X (m)","Y (m)","Z (m)","Vx (m/s)","Vy (m/s)","Vz (m/s)", - "Ax (m/s\302\262)","Ay (m/s\302\262)","Az (m/s\302\262)", - "\317\204 (ns)","\316\263 (ns/s)","\316\224\317\204 (ns)" - }; - int i,width[]={ - 25,25,30,30,30,25,25,115,115,75,75,75,70,70,70,65,65,65,70,60,50 - }; - Tbl->ColCount=21; - Tbl->RowCount=2; - for (i=0;iColCount;i++) { - Tbl->ColWidths[i]=width[i]*FontScale/96; - Tbl->Cells[i][0]=label[i]; - Tbl->Cells[i][1]=""; - } +void __fastcall TMonitorDialog::SetGnav(void) { + UTF8String label[] = {"SAT", + "PRN", + "Status", + "IOD", + "FCN", + "SVH", + "Age (days)", + "Toe", + "Tof", + "X (m)", + "Y (m)", + "Z (m)", + "Vx (m/s)", + "Vy (m/s)", + "Vz (m/s)", + "Ax (m/s\302\262)", + "Ay (m/s\302\262)", + "Az (m/s\302\262)", + "\317\204 (ns)", + "\316\263 (ns/s)", + "\316\224\317\204 (ns)"}; + int i, width[] = {25, 25, 30, 30, 30, 25, 25, 115, 115, 75, 75, + 75, 70, 70, 70, 65, 65, 65, 70, 60, 50}; + Tbl->ColCount = 21; + Tbl->RowCount = 2; + for (i = 0; i < Tbl->ColCount; i++) { + Tbl->ColWidths[i] = width[i] * FontScale / 96; + Tbl->Cells[i][0] = label[i]; + Tbl->Cells[i][1] = ""; + } } //--------------------------------------------------------------------------- -void __fastcall TMonitorDialog::ShowGnav(void) -{ - geph_t geph[NSATGLO]; - gtime_t time; - AnsiString s; - char tstr[40],id[8]; - int i,j,n,valid,prn,off=SelEph->ItemIndex?NSATGLO:0; - - rtksvrlock(&rtksvr); - time=rtksvr.rtk.sol.time; - for (i=0;iCaption=""; - - for (i=0,n=1;iItemIndex==1&&!valid) continue; - n++; - } - if (n<2) { - Tbl->RowCount=2; - for (i=0;iColCount;i++) Tbl->Cells[i][1]=""; - return; - } - Tbl->RowCount=n; - - for (i=0,n=1;iItemIndex==1&&!valid) continue; - prn=MINPRNGLO+i; - satno2id(satno(SYS_GLO,prn),id); - Tbl->Cells[j++][n]=id; - Tbl->Cells[j++][n]=s.sprintf("%d",prn); - Tbl->Cells[j++][n]=valid?"OK":"-"; - if (geph[i].iode<0) s="-"; else s.sprintf("%d",geph[i].iode); - Tbl->Cells[j++][n]=s; - Tbl->Cells[j++][n]=s.sprintf("%d",geph[i].frq); - Tbl->Cells[j++][n]=s.sprintf("%02x",geph[i].svh); - Tbl->Cells[j++][n]=s.sprintf("%d",geph[i].age); - if (geph[i].toe.time!=0) time2str(geph[i].toe,tstr,0); else strcpy(tstr,"-"); - Tbl->Cells[j++][n]=tstr; - if (geph[i].tof.time!=0) time2str(geph[i].tof,tstr,0); else strcpy(tstr,"-"); - Tbl->Cells[j++][n]=tstr; - Tbl->Cells[j++][n]=s.sprintf("%.2f",geph[i].pos[0]); - Tbl->Cells[j++][n]=s.sprintf("%.2f",geph[i].pos[1]); - Tbl->Cells[j++][n]=s.sprintf("%.2f",geph[i].pos[2]); - Tbl->Cells[j++][n]=s.sprintf("%.5f",geph[i].vel[0]); - Tbl->Cells[j++][n]=s.sprintf("%.5f",geph[i].vel[1]); - Tbl->Cells[j++][n]=s.sprintf("%.5f",geph[i].vel[2]); - Tbl->Cells[j++][n]=s.sprintf("%.7f",geph[i].acc[0]); - Tbl->Cells[j++][n]=s.sprintf("%.7f",geph[i].acc[1]); - Tbl->Cells[j++][n]=s.sprintf("%.7f",geph[i].acc[2]); - Tbl->Cells[j++][n]=s.sprintf("%.2f",geph[i].taun*1E9); - Tbl->Cells[j++][n]=s.sprintf("%.4f",geph[i].gamn*1E9); - Tbl->Cells[j++][n]=s.sprintf("%.2f",geph[i].dtaun*1E9); - n++; - } +void __fastcall TMonitorDialog::ShowGnav(void) { + geph_t geph[NSATGLO]; + gtime_t time; + AnsiString s; + char tstr[40], id[8]; + int i, j, n, valid, prn, off = SelEph->ItemIndex ? NSATGLO : 0; + + rtksvrlock(&rtksvr); + time = rtksvr.rtk.sol.time; + for (i = 0; i < NSATGLO; i++) geph[i] = rtksvr.nav.geph[i + off]; + rtksvrunlock(&rtksvr); + + Label->Caption = ""; + + for (i = 0, n = 1; i < NSATGLO; i++) { + valid = geph[i].toe.time != 0 && fabs(timediff(time, geph[i].toe)) <= MAXDTOE_GLO && + (geph[i].svh & 9) == 0 && (geph[i].svh & 6) != 4; + if (SelSat->ItemIndex == 1 && !valid) continue; + n++; + } + if (n < 2) { + Tbl->RowCount = 2; + for (i = 0; i < Tbl->ColCount; i++) Tbl->Cells[i][1] = ""; + return; + } + Tbl->RowCount = n; + + for (i = 0, n = 1; i < NSATGLO; i++) { + j = 0; + valid = geph[i].toe.time != 0 && fabs(timediff(time, geph[i].toe)) <= MAXDTOE_GLO && + (geph[i].svh & 9) == 0 && (geph[i].svh & 6) != 4; + if (SelSat->ItemIndex == 1 && !valid) continue; + prn = MINPRNGLO + i; + satno2id(satno(SYS_GLO, prn), id); + Tbl->Cells[j++][n] = id; + Tbl->Cells[j++][n] = s.sprintf("%d", prn); + Tbl->Cells[j++][n] = valid ? "OK" : "-"; + if (geph[i].iode < 0) + s = "-"; + else + s.sprintf("%d", geph[i].iode); + Tbl->Cells[j++][n] = s; + Tbl->Cells[j++][n] = s.sprintf("%d", geph[i].frq); + Tbl->Cells[j++][n] = s.sprintf("%02x", geph[i].svh); + Tbl->Cells[j++][n] = s.sprintf("%d", geph[i].age); + if (geph[i].toe.time != 0) + time2str(geph[i].toe, tstr, 0); + else + strcpy(tstr, "-"); + Tbl->Cells[j++][n] = tstr; + if (geph[i].tof.time != 0) + time2str(geph[i].tof, tstr, 0); + else + strcpy(tstr, "-"); + Tbl->Cells[j++][n] = tstr; + Tbl->Cells[j++][n] = s.sprintf("%.2f", geph[i].pos[0]); + Tbl->Cells[j++][n] = s.sprintf("%.2f", geph[i].pos[1]); + Tbl->Cells[j++][n] = s.sprintf("%.2f", geph[i].pos[2]); + Tbl->Cells[j++][n] = s.sprintf("%.5f", geph[i].vel[0]); + Tbl->Cells[j++][n] = s.sprintf("%.5f", geph[i].vel[1]); + Tbl->Cells[j++][n] = s.sprintf("%.5f", geph[i].vel[2]); + Tbl->Cells[j++][n] = s.sprintf("%.7f", geph[i].acc[0]); + Tbl->Cells[j++][n] = s.sprintf("%.7f", geph[i].acc[1]); + Tbl->Cells[j++][n] = s.sprintf("%.7f", geph[i].acc[2]); + Tbl->Cells[j++][n] = s.sprintf("%.2f", geph[i].taun * 1E9); + Tbl->Cells[j++][n] = s.sprintf("%.4f", geph[i].gamn * 1E9); + Tbl->Cells[j++][n] = s.sprintf("%.2f", geph[i].dtaun * 1E9); + n++; + } } //--------------------------------------------------------------------------- -void __fastcall TMonitorDialog::SetSbsNav(void) -{ - UTF8String label[]={ - "SAT","PRN","Status","T0","Tof","SVH","URA","X (m)","Y (m)","Z (m)", - "Vx (m/s)","Vy (m/s)","Vz (m/s)","Ax (m/s\302\262)","Ay (m/s\302\262)", - "Az (m/s\302\262)","Af0 (ns)","Af1 (ns/s)" - }; - int i,width[]={25,25,30,115,115,30,30,75,75,75,70,70,70,65,65,65,60,60}; - - Tbl->ColCount=18; - Tbl->RowCount=2; - for (i=0;iColCount;i++) { - Tbl->ColWidths[i]=width[i]*FontScale/96; - Tbl->Cells[i][0]=label[i]; - Tbl->Cells[i][1]=""; - } +void __fastcall TMonitorDialog::SetSbsNav(void) { + UTF8String label[] = {"SAT", + "PRN", + "Status", + "T0", + "Tof", + "SVH", + "URA", + "X (m)", + "Y (m)", + "Z (m)", + "Vx (m/s)", + "Vy (m/s)", + "Vz (m/s)", + "Ax (m/s\302\262)", + "Ay (m/s\302\262)", + "Az (m/s\302\262)", + "Af0 (ns)", + "Af1 (ns/s)"}; + int i, width[] = {25, 25, 30, 115, 115, 30, 30, 75, 75, 75, 70, 70, 70, 65, 65, 65, 60, 60}; + + Tbl->ColCount = 18; + Tbl->RowCount = 2; + for (i = 0; i < Tbl->ColCount; i++) { + Tbl->ColWidths[i] = width[i] * FontScale / 96; + Tbl->Cells[i][0] = label[i]; + Tbl->Cells[i][1] = ""; + } } //--------------------------------------------------------------------------- -void __fastcall TMonitorDialog::ShowSbsNav(void) -{ - AnsiString s,s0="-"; - seph_t seph[MAXPRNSBS-MINPRNSBS+1]={0}; - gtime_t time; - int i,j,n,valid,prn,off=SelEph->ItemIndex?NSATSBS:0; - char tstr[40],id[8]; - - rtksvrlock(&rtksvr); // lock - time=rtksvr.rtk.sol.time; - for (int i=0;iCaption=""; - - for (i=0,n=1;iItemIndex==1&&!valid) continue; - n++; - } - if (n<2) { - Tbl->RowCount=2; - for (i=0;iColCount;i++) Tbl->Cells[i][1]=""; - return; - } - Tbl->RowCount=n; - - for (i=0,n=1;iItemIndex==1&&!valid) continue; - prn=MINPRNSBS+i; - satno2id(satno(SYS_SBS,prn),id); - Tbl->Cells[j++][n]=id; - Tbl->Cells[j++][n]=s.sprintf("%d",prn); - Tbl->Cells[j++][n]=valid?"OK":"-"; - if (seph[i].t0.time) time2str(seph[i].t0,tstr,0); - else strcpy(tstr,"-"); - Tbl->Cells[j++][n]=tstr; - if (seph[i].tof.time) time2str(seph[i].tof,tstr,0); - else strcpy(tstr,"-"); - Tbl->Cells[j++][n]=tstr; - Tbl->Cells[j++][n]=s.sprintf("%02x",seph[i].svh); - Tbl->Cells[j++][n]=s.sprintf("%d", seph[i].sva); - Tbl->Cells[j++][n]=s.sprintf("%.2f",seph[i].pos[0]); - Tbl->Cells[j++][n]=s.sprintf("%.2f",seph[i].pos[1]); - Tbl->Cells[j++][n]=s.sprintf("%.2f",seph[i].pos[2]); - Tbl->Cells[j++][n]=s.sprintf("%.6f",seph[i].vel[0]); - Tbl->Cells[j++][n]=s.sprintf("%.6f",seph[i].vel[1]); - Tbl->Cells[j++][n]=s.sprintf("%.6f",seph[i].vel[2]); - Tbl->Cells[j++][n]=s.sprintf("%.7f",seph[i].acc[0]); - Tbl->Cells[j++][n]=s.sprintf("%.7f",seph[i].acc[1]); - Tbl->Cells[j++][n]=s.sprintf("%.7f",seph[i].acc[2]); - Tbl->Cells[j++][n]=s.sprintf("%.2f",seph[i].af0*1E9); - Tbl->Cells[j++][n]=s.sprintf("%.4f",seph[i].af1*1E9); - n++; - } +void __fastcall TMonitorDialog::ShowSbsNav(void) { + AnsiString s, s0 = "-"; + seph_t seph[MAXPRNSBS - MINPRNSBS + 1] = {0}; + gtime_t time; + int i, j, n, valid, prn, off = SelEph->ItemIndex ? NSATSBS : 0; + char tstr[40], id[8]; + + rtksvrlock(&rtksvr); // lock + time = rtksvr.rtk.sol.time; + for (int i = 0; i < NSATSBS; i++) { + seph[i] = rtksvr.nav.seph[i + off]; + } + rtksvrunlock(&rtksvr); // unlock + + Label->Caption = ""; + + for (i = 0, n = 1; i < NSATSBS; i++) { + valid = fabs(timediff(time, seph[i].t0)) <= MAXDTOE_SBS && seph[i].t0.time && seph[i].svh == 0; + if (SelSat->ItemIndex == 1 && !valid) continue; + n++; + } + if (n < 2) { + Tbl->RowCount = 2; + for (i = 0; i < Tbl->ColCount; i++) Tbl->Cells[i][1] = ""; + return; + } + Tbl->RowCount = n; + + for (i = 0, n = 1; i < NSATSBS; i++) { + j = 0; + valid = fabs(timediff(time, seph[i].t0)) <= MAXDTOE_SBS && seph[i].t0.time && seph[i].svh == 0; + if (SelSat->ItemIndex == 1 && !valid) continue; + prn = MINPRNSBS + i; + satno2id(satno(SYS_SBS, prn), id); + Tbl->Cells[j++][n] = id; + Tbl->Cells[j++][n] = s.sprintf("%d", prn); + Tbl->Cells[j++][n] = valid ? "OK" : "-"; + if (seph[i].t0.time) + time2str(seph[i].t0, tstr, 0); + else + strcpy(tstr, "-"); + Tbl->Cells[j++][n] = tstr; + if (seph[i].tof.time) + time2str(seph[i].tof, tstr, 0); + else + strcpy(tstr, "-"); + Tbl->Cells[j++][n] = tstr; + Tbl->Cells[j++][n] = s.sprintf("%02x", seph[i].svh); + Tbl->Cells[j++][n] = s.sprintf("%d", seph[i].sva); + Tbl->Cells[j++][n] = s.sprintf("%.2f", seph[i].pos[0]); + Tbl->Cells[j++][n] = s.sprintf("%.2f", seph[i].pos[1]); + Tbl->Cells[j++][n] = s.sprintf("%.2f", seph[i].pos[2]); + Tbl->Cells[j++][n] = s.sprintf("%.6f", seph[i].vel[0]); + Tbl->Cells[j++][n] = s.sprintf("%.6f", seph[i].vel[1]); + Tbl->Cells[j++][n] = s.sprintf("%.6f", seph[i].vel[2]); + Tbl->Cells[j++][n] = s.sprintf("%.7f", seph[i].acc[0]); + Tbl->Cells[j++][n] = s.sprintf("%.7f", seph[i].acc[1]); + Tbl->Cells[j++][n] = s.sprintf("%.7f", seph[i].acc[2]); + Tbl->Cells[j++][n] = s.sprintf("%.2f", seph[i].af0 * 1E9); + Tbl->Cells[j++][n] = s.sprintf("%.4f", seph[i].af1 * 1E9); + n++; + } } //--------------------------------------------------------------------------- -void __fastcall TMonitorDialog::SetIonUtc(void) -{ - AnsiString label[]={"Parameter","Value"}; - int i,width[]={270,330}; - - Tbl->ColCount=2; - Tbl->RowCount=2; - for (i=0;iColCount;i++) { - Tbl->ColWidths[i]=width[i]*FontScale/96; - Tbl->Cells[i][0]=label[i]; - Tbl->Cells[i][1]=""; - } +void __fastcall TMonitorDialog::SetIonUtc(void) { + AnsiString label[] = {"Parameter", "Value"}; + int i, width[] = {270, 330}; + + Tbl->ColCount = 2; + Tbl->RowCount = 2; + for (i = 0; i < Tbl->ColCount; i++) { + Tbl->ColWidths[i] = width[i] * FontScale / 96; + Tbl->Cells[i][0] = label[i]; + Tbl->Cells[i][1] = ""; + } } //--------------------------------------------------------------------------- -void __fastcall TMonitorDialog::ShowIonUtc(void) -{ - double utc_gps[8],utc_glo[8],utc_gal[8],utc_qzs[8],utc_cmp[8],utc_irn[9]; - double ion_gps[8],ion_gal[4],ion_qzs[8],ion_cmp[8],ion_irn[8]; - gtime_t time; - AnsiString s; - double tow=0.0; - char tstr[40]; - int i,j,k,leaps,week=0; - - rtksvrlock(&rtksvr); - time=rtksvr.rtk.sol.time; - for (i=0;i<8;i++) utc_gps[i]=rtksvr.nav.utc_gps[i]; - for (i=0;i<8;i++) utc_glo[i]=rtksvr.nav.utc_glo[i]; - for (i=0;i<8;i++) utc_gal[i]=rtksvr.nav.utc_gal[i]; - for (i=0;i<8;i++) utc_qzs[i]=rtksvr.nav.utc_qzs[i]; - for (i=0;i<8;i++) utc_cmp[i]=rtksvr.nav.utc_cmp[i]; - for (i=0;i<9;i++) utc_irn[i]=rtksvr.nav.utc_irn[i]; - for (i=0;i<8;i++) ion_gps[i]=rtksvr.nav.ion_gps[i]; - for (i=0;i<4;i++) ion_gal[i]=rtksvr.nav.ion_gal[i]; - for (i=0;i<8;i++) ion_qzs[i]=rtksvr.nav.ion_qzs[i]; - for (i=0;i<8;i++) ion_cmp[i]=rtksvr.nav.ion_cmp[i]; - for (i=0;i<8;i++) ion_irn[i]=rtksvr.nav.ion_irn[i]; - rtksvrunlock(&rtksvr); - - Label->Caption=""; - - Tbl->RowCount=21; - i=1; - - time2str(timeget(),tstr,3); - Tbl->Cells[0][i ]="CPU Time (UTC)"; - Tbl->Cells[1][i++]=s.sprintf("%s",tstr); - - if (time.time!=0) time2str(gpst2utc(time),tstr,3); else strcpy(tstr,"-"); - Tbl->Cells[0][i ]="Receiver Time (UTC)"; - Tbl->Cells[1][i++]=s.sprintf("%s",tstr); - - if (time.time!=0) time2str(time,tstr,3); else strcpy(tstr,"-"); - Tbl->Cells[0][i ]="Receiver Time (GPST)"; - Tbl->Cells[1][i++]=s.sprintf("%s",tstr); - - if (time.time!=0) tow=time2gpst(time,&week); - Tbl->Cells[0][i ]="GPS Week/Time (s)"; - Tbl->Cells[1][i++]=s.sprintf("%d, %.3f",week,tow); - - Tbl->Cells[0][i ]="Leap Seconds dt_LS(s), WN_LSF,DN, dt_LSF(s)"; - Tbl->Cells[1][i++]=s.sprintf("%.0f, %.0f, %.0f, %.0f",utc_gps[4],utc_gps[5], - utc_gps[6],utc_gps[7]); - - Tbl->Cells[0][i ]="GPST-UTC Ref Week, Time(s), A0(ns), A1(ns/s)"; - Tbl->Cells[1][i++]=s.sprintf("%.0f, %.0f, %.3f, %.5E",utc_gps[3],utc_gps[2], - utc_gps[0]*1E9,utc_gps[1]*1E9); - - Tbl->Cells[0][i ]="GLOT-UTC Tau_C, Tau_GPS(ns)"; - Tbl->Cells[1][i++]=s.sprintf("%.9f, %.3f",utc_glo[0],utc_glo[1]*1E9); - - Tbl->Cells[0][i ]="GST-UTC Ref Week, Time(s), A0(ns), A1(ns/s)"; - Tbl->Cells[1][i++]=s.sprintf("%.0f, %.0f, %.3f, %.5E",utc_gal[3],utc_gal[2], - utc_gal[0]*1E9,utc_gal[1]*1E9); - - Tbl->Cells[0][i ]="QZSST-UTC Ref Week, Time(s), A0(ns), A1(ns/s)"; - Tbl->Cells[1][i++]=s.sprintf("%.0f, %.0f, %.3f, %.5E",utc_qzs[3],utc_qzs[2], - utc_qzs[0]*1E9,utc_qzs[1]*1E9); - - Tbl->Cells[0][i ]="BDST-UTC Ref Week, Time(s), A0(ns), A1(ns/s)"; - Tbl->Cells[1][i++]=s.sprintf("%.0f, %.0f, %.3f, %.5E",utc_cmp[3],utc_cmp[2], - utc_cmp[0]*1E9,utc_cmp[1]*1E9); - - Tbl->Cells[0][i ]="IRNT-UTC Ref Week,Time(s), A0(ns), A1(ns/s), A2(ns/s2)"; - Tbl->Cells[1][i++]=s.sprintf("%.0f, %.0f, %.3f, %.5E, %.5E",utc_irn[3], - utc_irn[2],utc_irn[0]*1E9,utc_irn[1]*1E9, - utc_irn[8]*1E9); - - Tbl->Cells[0][i ]="GPS Iono Parameters Alpha0-3"; - Tbl->Cells[1][i++]=s.sprintf("%.5E, %.5E, %.5E, %.5E", - ion_gps[0],ion_gps[1],ion_gps[2],ion_gps[3]); - - Tbl->Cells[0][i ]="GPS Iono Parameters Beta0-3"; - Tbl->Cells[1][i++]=s.sprintf("%.5E, %.5E, %.5E, %.5E", - ion_gps[4],ion_gps[5],ion_gps[6],ion_gps[7]); - - Tbl->Cells[0][i ]="Galileo Iono Parameters 0-2"; - Tbl->Cells[1][i++]=s.sprintf("%.5E, %.5E, %.5E",ion_gal[0],ion_gal[1], - ion_gal[2]); - - Tbl->Cells[0][i ]="QZSS Iono Parameters Alpha0-3"; - Tbl->Cells[1][i++]=s.sprintf("%.5E, %.5E, %.5E, %.5E", - ion_qzs[0],ion_qzs[1],ion_qzs[2],ion_qzs[3]); - - Tbl->Cells[0][i ]="QZSS Iono Parameters Beta0-3"; - Tbl->Cells[1][i++]=s.sprintf("%.5E, %.5E, %.5E, %.5E", - ion_qzs[4],ion_qzs[5],ion_qzs[6],ion_qzs[7]); - - Tbl->Cells[0][i ]="BDS Iono Parameters Alpha0-3"; - Tbl->Cells[1][i++]=s.sprintf("%.5E, %.5E, %.5E, %.5E", - ion_cmp[0],ion_cmp[1],ion_cmp[2],ion_cmp[3]); - - Tbl->Cells[0][i ]="BDS Iono Parameters Beta0-3"; - Tbl->Cells[1][i++]=s.sprintf("%.5E, %.5E, %.5E, %.5E", - ion_cmp[4],ion_cmp[5],ion_cmp[6],ion_cmp[7]); - - Tbl->Cells[0][i ]="NavIC Iono Parameters Alpha0-3"; - Tbl->Cells[1][i++]=s.sprintf("%.5E, %.5E, %.5E, %.5E", - ion_irn[0],ion_irn[1],ion_irn[2],ion_irn[3]); - - Tbl->Cells[0][i ]="NavIC Iono Parameters Beta0-3"; - Tbl->Cells[1][i++]=s.sprintf("%.5E, %.5E, %.5E, %.5E", - ion_irn[4],ion_irn[5],ion_irn[6],ion_irn[7]); +void __fastcall TMonitorDialog::ShowIonUtc(void) { + double utc_gps[8], utc_glo[8], utc_gal[8], utc_qzs[8], utc_cmp[8], utc_irn[9]; + double ion_gps[8], ion_gal[4], ion_qzs[8], ion_cmp[8], ion_irn[8]; + gtime_t time; + AnsiString s; + double tow = 0.0; + char tstr[40]; + int i, j, k, leaps, week = 0; + + rtksvrlock(&rtksvr); + time = rtksvr.rtk.sol.time; + for (i = 0; i < 8; i++) utc_gps[i] = rtksvr.nav.utc_gps[i]; + for (i = 0; i < 8; i++) utc_glo[i] = rtksvr.nav.utc_glo[i]; + for (i = 0; i < 8; i++) utc_gal[i] = rtksvr.nav.utc_gal[i]; + for (i = 0; i < 8; i++) utc_qzs[i] = rtksvr.nav.utc_qzs[i]; + for (i = 0; i < 8; i++) utc_cmp[i] = rtksvr.nav.utc_cmp[i]; + for (i = 0; i < 9; i++) utc_irn[i] = rtksvr.nav.utc_irn[i]; + for (i = 0; i < 8; i++) ion_gps[i] = rtksvr.nav.ion_gps[i]; + for (i = 0; i < 4; i++) ion_gal[i] = rtksvr.nav.ion_gal[i]; + for (i = 0; i < 8; i++) ion_qzs[i] = rtksvr.nav.ion_qzs[i]; + for (i = 0; i < 8; i++) ion_cmp[i] = rtksvr.nav.ion_cmp[i]; + for (i = 0; i < 8; i++) ion_irn[i] = rtksvr.nav.ion_irn[i]; + rtksvrunlock(&rtksvr); + + Label->Caption = ""; + + Tbl->RowCount = 21; + i = 1; + + time2str(timeget(), tstr, 3); + Tbl->Cells[0][i] = "CPU Time (UTC)"; + Tbl->Cells[1][i++] = s.sprintf("%s", tstr); + + if (time.time != 0) + time2str(gpst2utc(time), tstr, 3); + else + strcpy(tstr, "-"); + Tbl->Cells[0][i] = "Receiver Time (UTC)"; + Tbl->Cells[1][i++] = s.sprintf("%s", tstr); + + if (time.time != 0) + time2str(time, tstr, 3); + else + strcpy(tstr, "-"); + Tbl->Cells[0][i] = "Receiver Time (GPST)"; + Tbl->Cells[1][i++] = s.sprintf("%s", tstr); + + if (time.time != 0) tow = time2gpst(time, &week); + Tbl->Cells[0][i] = "GPS Week/Time (s)"; + Tbl->Cells[1][i++] = s.sprintf("%d, %.3f", week, tow); + + Tbl->Cells[0][i] = "Leap Seconds dt_LS(s), WN_LSF,DN, dt_LSF(s)"; + Tbl->Cells[1][i++] = + s.sprintf("%.0f, %.0f, %.0f, %.0f", utc_gps[4], utc_gps[5], utc_gps[6], utc_gps[7]); + + Tbl->Cells[0][i] = "GPST-UTC Ref Week, Time(s), A0(ns), A1(ns/s)"; + Tbl->Cells[1][i++] = s.sprintf("%.0f, %.0f, %.3f, %.5E", utc_gps[3], utc_gps[2], utc_gps[0] * 1E9, + utc_gps[1] * 1E9); + + Tbl->Cells[0][i] = "GLOT-UTC Tau_C, Tau_GPS(ns)"; + Tbl->Cells[1][i++] = s.sprintf("%.9f, %.3f", utc_glo[0], utc_glo[1] * 1E9); + + Tbl->Cells[0][i] = "GST-UTC Ref Week, Time(s), A0(ns), A1(ns/s)"; + Tbl->Cells[1][i++] = s.sprintf("%.0f, %.0f, %.3f, %.5E", utc_gal[3], utc_gal[2], utc_gal[0] * 1E9, + utc_gal[1] * 1E9); + + Tbl->Cells[0][i] = "QZSST-UTC Ref Week, Time(s), A0(ns), A1(ns/s)"; + Tbl->Cells[1][i++] = s.sprintf("%.0f, %.0f, %.3f, %.5E", utc_qzs[3], utc_qzs[2], utc_qzs[0] * 1E9, + utc_qzs[1] * 1E9); + + Tbl->Cells[0][i] = "BDST-UTC Ref Week, Time(s), A0(ns), A1(ns/s)"; + Tbl->Cells[1][i++] = s.sprintf("%.0f, %.0f, %.3f, %.5E", utc_cmp[3], utc_cmp[2], utc_cmp[0] * 1E9, + utc_cmp[1] * 1E9); + + Tbl->Cells[0][i] = "IRNT-UTC Ref Week,Time(s), A0(ns), A1(ns/s), A2(ns/s2)"; + Tbl->Cells[1][i++] = s.sprintf("%.0f, %.0f, %.3f, %.5E, %.5E", utc_irn[3], utc_irn[2], + utc_irn[0] * 1E9, utc_irn[1] * 1E9, utc_irn[8] * 1E9); + + Tbl->Cells[0][i] = "GPS Iono Parameters Alpha0-3"; + Tbl->Cells[1][i++] = + s.sprintf("%.5E, %.5E, %.5E, %.5E", ion_gps[0], ion_gps[1], ion_gps[2], ion_gps[3]); + + Tbl->Cells[0][i] = "GPS Iono Parameters Beta0-3"; + Tbl->Cells[1][i++] = + s.sprintf("%.5E, %.5E, %.5E, %.5E", ion_gps[4], ion_gps[5], ion_gps[6], ion_gps[7]); + + Tbl->Cells[0][i] = "Galileo Iono Parameters 0-2"; + Tbl->Cells[1][i++] = s.sprintf("%.5E, %.5E, %.5E", ion_gal[0], ion_gal[1], ion_gal[2]); + + Tbl->Cells[0][i] = "QZSS Iono Parameters Alpha0-3"; + Tbl->Cells[1][i++] = + s.sprintf("%.5E, %.5E, %.5E, %.5E", ion_qzs[0], ion_qzs[1], ion_qzs[2], ion_qzs[3]); + + Tbl->Cells[0][i] = "QZSS Iono Parameters Beta0-3"; + Tbl->Cells[1][i++] = + s.sprintf("%.5E, %.5E, %.5E, %.5E", ion_qzs[4], ion_qzs[5], ion_qzs[6], ion_qzs[7]); + + Tbl->Cells[0][i] = "BDS Iono Parameters Alpha0-3"; + Tbl->Cells[1][i++] = + s.sprintf("%.5E, %.5E, %.5E, %.5E", ion_cmp[0], ion_cmp[1], ion_cmp[2], ion_cmp[3]); + + Tbl->Cells[0][i] = "BDS Iono Parameters Beta0-3"; + Tbl->Cells[1][i++] = + s.sprintf("%.5E, %.5E, %.5E, %.5E", ion_cmp[4], ion_cmp[5], ion_cmp[6], ion_cmp[7]); + + Tbl->Cells[0][i] = "NavIC Iono Parameters Alpha0-3"; + Tbl->Cells[1][i++] = + s.sprintf("%.5E, %.5E, %.5E, %.5E", ion_irn[0], ion_irn[1], ion_irn[2], ion_irn[3]); + + Tbl->Cells[0][i] = "NavIC Iono Parameters Beta0-3"; + Tbl->Cells[1][i++] = + s.sprintf("%.5E, %.5E, %.5E, %.5E", ion_irn[4], ion_irn[5], ion_irn[6], ion_irn[7]); } //--------------------------------------------------------------------------- -void __fastcall TMonitorDialog::SetStr(void) -{ - AnsiString label[]={ - "STR","Stream","Type","Format","Mode","State","Input(bytes)","Input(bps)", - "Output(bytes)","Output(bps)","Path","Message" - }; - int i,width[]={25,95,70,80,35,35,70,70,70,70,220,220}; - - Tbl->ColCount=12; - Tbl->RowCount=2; - for (i=0;iColCount;i++) { - Tbl->ColWidths[i]=width[i]*FontScale/96; - Tbl->Cells[i][0]=label[i]; - Tbl->Cells[i][1]=""; - } +void __fastcall TMonitorDialog::SetStr(void) { + AnsiString label[] = {"STR", "Stream", "Type", "Format", + "Mode", "State", "Input(bytes)", "Input(bps)", + "Output(bytes)", "Output(bps)", "Path", "Message"}; + int i, width[] = {25, 95, 70, 80, 35, 35, 70, 70, 70, 70, 220, 220}; + + Tbl->ColCount = 12; + Tbl->RowCount = 2; + for (i = 0; i < Tbl->ColCount; i++) { + Tbl->ColWidths[i] = width[i] * FontScale / 96; + Tbl->Cells[i][0] = label[i]; + Tbl->Cells[i][1] = ""; + } } //--------------------------------------------------------------------------- -void __fastcall TMonitorDialog::ShowStr(void) -{ - AnsiString ch[]={ - "Input Rover","Input Base","Input Correction","Output Solution 1", - "Output Solution 2","Log Rover","Log Base","Log Correction", - "Monitor" - }; - AnsiString type[]={ - "-","Serial","File","TCP Server","TCP Client","NTRIP Server", - "NTRIP Client","FTP","HTTP","NTRIP Caster","UDP Server", - "UDP Client","" - }; - AnsiString outformat[]={ - "Lat/Lon/Height","X/Y/Z-ECEF","E/N/U-Baseline","NMEA-0183", - "Solution stats","GSI F1/F2" - }; - AnsiString state[]={"Error","-","OK"}; - AnsiString s,mode,form; - stream_t stream[9]; - int i,j,format[9]={0}; - char path[MAXSTRPATH]="",*p,*q,*pp; - - rtksvrlock(&rtksvr); // lock - for (i=0;i<8;i++) stream[i]=rtksvr.stream[i]; - for (i=0;i<3;i++) format[i]=rtksvr.format[i]; - for (i=3;i<5;i++) format[i]=rtksvr.solopt[i-3].posf; - stream[8]=monistr; - format[8]=SOLF_LLH; - rtksvrunlock(&rtksvr); // unlock - - Tbl->RowCount=10; - Label->Caption=""; - for (i=0;i<9;i++) { - j=0; - Tbl->Cells[j++][i+1]=s.sprintf("(%d)",i+1); - Tbl->Cells[j++][i+1]=ch[i]; - Tbl->Cells[j++][i+1]=type[stream[i].type]; - if (!stream[i].type) form="-"; - else if (i<3) form=formatstrs[format[i]]; - else if (i<5||i==8) form=outformat[format[i]]; - else form="-"; - Tbl->Cells[j++][i+1]=form; - if (stream[i].mode&STR_MODE_R) mode="R"; else mode=""; - if (stream[i].mode&STR_MODE_W) mode=mode+(mode==""?"":"/")+"W"; - Tbl->Cells[j++][i+1]=mode; - Tbl->Cells[j++][i+1]=state[stream[i].state+1]; - Tbl->Cells[j++][i+1]=s.sprintf("%d",stream[i].inb); - Tbl->Cells[j++][i+1]=s.sprintf("%d",stream[i].inr); - Tbl->Cells[j++][i+1]=s.sprintf("%d",stream[i].outb); - Tbl->Cells[j++][i+1]=s.sprintf("%d",stream[i].outr); - strcpy(path,stream[i].path); - pp=path; - if ((p=strchr(path,'@'))) { - for (q=p-1;q>=path;q--) if (*q==':') break; - if (q>=path) for (q++;qCells[j++][i+1]=pp; - Tbl->Cells[j++][i+1]=stream[i].msg; - } +void __fastcall TMonitorDialog::ShowStr(void) { + AnsiString ch[] = {"Input Rover", "Input Base", "Input Correction", + "Output Solution 1", "Output Solution 2", "Log Rover", + "Log Base", "Log Correction", "Monitor"}; + AnsiString type[] = {"-", + "Serial", + "File", + "TCP Server", + "TCP Client", + "NTRIP Server", + "NTRIP Client", + "FTP", + "HTTP", + "NTRIP Caster", + "UDP Server", + "UDP Client", + ""}; + AnsiString outformat[] = {"Lat/Lon/Height", "X/Y/Z-ECEF", "E/N/U-Baseline", + "NMEA-0183", "Solution stats", "GSI F1/F2"}; + AnsiString state[] = {"Error", "-", "OK"}; + AnsiString s, mode, form; + stream_t stream[9]; + int i, j, format[9] = {0}; + char path[MAXSTRPATH] = "", *p, *q, *pp; + + rtksvrlock(&rtksvr); // lock + for (i = 0; i < 8; i++) stream[i] = rtksvr.stream[i]; + for (i = 0; i < 3; i++) format[i] = rtksvr.format[i]; + for (i = 3; i < 5; i++) format[i] = rtksvr.solopt[i - 3].posf; + stream[8] = monistr; + format[8] = SOLF_LLH; + rtksvrunlock(&rtksvr); // unlock + + Tbl->RowCount = 10; + Label->Caption = ""; + for (i = 0; i < 9; i++) { + j = 0; + Tbl->Cells[j++][i + 1] = s.sprintf("(%d)", i + 1); + Tbl->Cells[j++][i + 1] = ch[i]; + Tbl->Cells[j++][i + 1] = type[stream[i].type]; + if (!stream[i].type) + form = "-"; + else if (i < 3) + form = formatstrs[format[i]]; + else if (i < 5 || i == 8) + form = outformat[format[i]]; + else + form = "-"; + Tbl->Cells[j++][i + 1] = form; + if (stream[i].mode & STR_MODE_R) + mode = "R"; + else + mode = ""; + if (stream[i].mode & STR_MODE_W) mode = mode + (mode == "" ? "" : "/") + "W"; + Tbl->Cells[j++][i + 1] = mode; + Tbl->Cells[j++][i + 1] = state[stream[i].state + 1]; + Tbl->Cells[j++][i + 1] = s.sprintf("%d", stream[i].inb); + Tbl->Cells[j++][i + 1] = s.sprintf("%d", stream[i].inr); + Tbl->Cells[j++][i + 1] = s.sprintf("%d", stream[i].outb); + Tbl->Cells[j++][i + 1] = s.sprintf("%d", stream[i].outr); + strcpy(path, stream[i].path); + pp = path; + if ((p = strchr(path, '@'))) { + for (q = p - 1; q >= path; q--) + if (*q == ':') break; + if (q >= path) + for (q++; q < p; q++) *q = '*'; + } + if (stream[i].type == STR_TCPCLI || stream[i].type == STR_TCPSVR) { + if ((p = strchr(path, '/'))) *p = '\0'; + if ((p = strchr(path, '@'))) pp = p + 1; + if (stream[i].type == STR_TCPSVR) { + if ((p = strchr(pp, ':'))) + pp = p + 1; + else + pp = (char *)""; + } + } + Tbl->Cells[j++][i + 1] = pp; + Tbl->Cells[j++][i + 1] = stream[i].msg; + } } //--------------------------------------------------------------------------- -void __fastcall TMonitorDialog::SetSbsMsg(void) -{ - AnsiString label[]={ - "Trcv","PRN","STR","Type","Message","Contents" - }; - int i,width[]={115,25,25,25,420,200}; - - Tbl->ColCount=6; - Tbl->RowCount=2; - for (i=0;iColCount;i++) { - Tbl->ColWidths[i]=width[i]*FontScale/96; - Tbl->Cells[i][0]=label[i]; - Tbl->Cells[i][1]=""; - } +void __fastcall TMonitorDialog::SetSbsMsg(void) { + AnsiString label[] = {"Trcv", "PRN", "STR", "Type", "Message", "Contents"}; + int i, width[] = {115, 25, 25, 25, 420, 200}; + + Tbl->ColCount = 6; + Tbl->RowCount = 2; + for (i = 0; i < Tbl->ColCount; i++) { + Tbl->ColWidths[i] = width[i] * FontScale / 96; + Tbl->Cells[i][0] = label[i]; + Tbl->Cells[i][1] = ""; + } } //--------------------------------------------------------------------------- -void __fastcall TMonitorDialog::ShowSbsMsg(void) -{ - AnsiString s; - sbsmsg_t msg[MAXSBSMSG]; - const char *content[]={ - "For Testing","PRN Mask","Fast Corrections","Fast Corrections", - "Fast Corrections","Fast Corrections","Integrity Information", - "Fast Correction Degradation Factor","GEO Navigation Message", - "Degradation Parameters","WAAS Network Time/UTC Offset Parameters", - "GEO Satellite Almanacs","Ionospheric Grid Point Masks", - "Mixed Fast Corrections/Long Term Satellite Error Corrections", - "Long Term Satellite Error Corrections","Ionospheric Delay Corrections", - "WAAS Service Messages","Clock-Ephemeris Covariance Matrix Message", - "Internal Test Message","Null Message", - "QZSS: DC Report (JMA)","QZSS: DC Report (Other)", - "QZSS: Monitoring Station Info","QZSS: PRN Mask", - "QZSS: Data Issue Number","QZSS: DGPS Correction", - "QZSS: Satellite Health", - "" - }; - const int id[]={0,1,2,3,4,5,6,7,9,10,12,17,18,24,25,26,27,28,62,63, - 43,44,47,48,49,50,51,-1}; - char str[256],*p; - int i,j,k,n,type,prn; - - - rtksvrlock(&rtksvr); // lock - for (i=n=0;iRowCount=n<=0?2:n+1; - Label->Caption=""; - for (i=0;iCells[j++][i+1]=str; - Tbl->Cells[j++][i+1]=s.sprintf("%d",prn); - Tbl->Cells[j++][i+1]=s.sprintf("(%d)",msg[i].rcv); - type=msg[i].msg[1]>>2; - Tbl->Cells[j++][i+1]=s.sprintf("%d",type); - p=str; - for (k=0;k<29;k++) p+=sprintf(p,"%02X",msg[i].msg[k]); - Tbl->Cells[j++][i+1]=str; - for (k=0;id[k]>=0;k++) if (type==id[k]) break; - Tbl->Cells[j++][i+1]=id[k]<0?"?":content[k]; - } +void __fastcall TMonitorDialog::ShowSbsMsg(void) { + AnsiString s; + sbsmsg_t msg[MAXSBSMSG]; + const char *content[] = {"For Testing", + "PRN Mask", + "Fast Corrections", + "Fast Corrections", + "Fast Corrections", + "Fast Corrections", + "Integrity Information", + "Fast Correction Degradation Factor", + "GEO Navigation Message", + "Degradation Parameters", + "WAAS Network Time/UTC Offset Parameters", + "GEO Satellite Almanacs", + "Ionospheric Grid Point Masks", + "Mixed Fast Corrections/Long Term Satellite Error Corrections", + "Long Term Satellite Error Corrections", + "Ionospheric Delay Corrections", + "WAAS Service Messages", + "Clock-Ephemeris Covariance Matrix Message", + "Internal Test Message", + "Null Message", + "QZSS: DC Report (JMA)", + "QZSS: DC Report (Other)", + "QZSS: Monitoring Station Info", + "QZSS: PRN Mask", + "QZSS: Data Issue Number", + "QZSS: DGPS Correction", + "QZSS: Satellite Health", + ""}; + const int id[] = {0, 1, 2, 3, 4, 5, 6, 7, 9, 10, 12, 17, 18, 24, + 25, 26, 27, 28, 62, 63, 43, 44, 47, 48, 49, 50, 51, -1}; + char str[256], *p; + int i, j, k, n, type, prn; + + rtksvrlock(&rtksvr); // lock + for (i = n = 0; i < rtksvr.nsbs; i++) { + msg[n++] = rtksvr.sbsmsg[i]; + } + rtksvrunlock(&rtksvr); // unlock + + Tbl->RowCount = n <= 0 ? 2 : n + 1; + Label->Caption = ""; + for (i = 0; i < n; i++) { + j = 0; + prn = msg[i].prn; + time2str(gpst2time(msg[i].week, msg[i].tow), str, 0); + Tbl->Cells[j++][i + 1] = str; + Tbl->Cells[j++][i + 1] = s.sprintf("%d", prn); + Tbl->Cells[j++][i + 1] = s.sprintf("(%d)", msg[i].rcv); + type = msg[i].msg[1] >> 2; + Tbl->Cells[j++][i + 1] = s.sprintf("%d", type); + p = str; + for (k = 0; k < 29; k++) p += sprintf(p, "%02X", msg[i].msg[k]); + Tbl->Cells[j++][i + 1] = str; + for (k = 0; id[k] >= 0; k++) + if (type == id[k]) break; + Tbl->Cells[j++][i + 1] = id[k] < 0 ? "?" : content[k]; + } } //--------------------------------------------------------------------------- -void __fastcall TMonitorDialog::SetSbsLong(void) -{ - AnsiString label[]={ - "SAT","Status","IODE","dX (m)","dY (m)","dZ (m)","dVX (m/s)", - "dVY (m/s)","dVZ (m/s)","daf0 (ns)","daf1 (ns/s)","T0" - }; - int i,width[]={25,30,30,55,55,55,55,55,55,55,55,115}; - - Tbl->ColCount=12; - Tbl->RowCount=2; - for (i=0;iColCount;i++) { - Tbl->ColWidths[i]=width[i]*FontScale/96; - Tbl->Cells[i][0]=label[i]; - Tbl->Cells[i][1]=""; - } +void __fastcall TMonitorDialog::SetSbsLong(void) { + AnsiString label[] = {"SAT", "Status", "IODE", "dX (m)", "dY (m)", "dZ (m)", + "dVX (m/s)", "dVY (m/s)", "dVZ (m/s)", "daf0 (ns)", "daf1 (ns/s)", "T0"}; + int i, width[] = {25, 30, 30, 55, 55, 55, 55, 55, 55, 55, 55, 115}; + + Tbl->ColCount = 12; + Tbl->RowCount = 2; + for (i = 0; i < Tbl->ColCount; i++) { + Tbl->ColWidths[i] = width[i] * FontScale / 96; + Tbl->Cells[i][0] = label[i]; + Tbl->Cells[i][1] = ""; + } } //--------------------------------------------------------------------------- -void __fastcall TMonitorDialog::ShowSbsLong(void) -{ - AnsiString s; - sbssat_t sbssat; - sbssatp_t *satp; - gtime_t time; - int i,j,n,valid; - char tstr[40],id[8]; - - rtksvrlock(&rtksvr); // lock - time=rtksvr.rtk.sol.time; - sbssat=rtksvr.nav.sbssat; - rtksvrunlock(&rtksvr); // unlock - - Label->Caption=""; - Tbl->RowCount=sbssat.nsat<=0?1:sbssat.nsat+1; - Label->Caption=s.sprintf("IODP:%2d System Latency:%2d s", - sbssat.iodp,sbssat.tlat); - for (i=0;ilcorr.t0)<=MAXSBSAGEL&&satp->lcorr.t0.time; - satno2id(satp->sat,id); - Tbl->Cells[j++][i+1]=id; - Tbl->Cells[j++][i+1]=valid?"OK":"-"; - Tbl->Cells[j++][i+1]=s.sprintf("%d",satp->lcorr.iode); - Tbl->Cells[j++][i+1]=s.sprintf("%.3f",satp->lcorr.dpos[0]); - Tbl->Cells[j++][i+1]=s.sprintf("%.3f",satp->lcorr.dpos[1]); - Tbl->Cells[j++][i+1]=s.sprintf("%.3f",satp->lcorr.dpos[2]); - Tbl->Cells[j++][i+1]=s.sprintf("%.4f",satp->lcorr.dvel[0]); - Tbl->Cells[j++][i+1]=s.sprintf("%.4f",satp->lcorr.dvel[1]); - Tbl->Cells[j++][i+1]=s.sprintf("%.4f",satp->lcorr.dvel[2]); - Tbl->Cells[j++][i+1]=s.sprintf("%.3f",satp->lcorr.daf0*1E9); - Tbl->Cells[j++][i+1]=s.sprintf("%.4f",satp->lcorr.daf1*1E9); - if (satp->lcorr.t0.time) time2str(satp->lcorr.t0,tstr,0); - else strcpy(tstr,"-"); - Tbl->Cells[j++][i+1]=tstr; - } +void __fastcall TMonitorDialog::ShowSbsLong(void) { + AnsiString s; + sbssat_t sbssat; + sbssatp_t *satp; + gtime_t time; + int i, j, n, valid; + char tstr[40], id[8]; + + rtksvrlock(&rtksvr); // lock + time = rtksvr.rtk.sol.time; + sbssat = rtksvr.nav.sbssat; + rtksvrunlock(&rtksvr); // unlock + + Label->Caption = ""; + Tbl->RowCount = sbssat.nsat <= 0 ? 1 : sbssat.nsat + 1; + Label->Caption = s.sprintf("IODP:%2d System Latency:%2d s", sbssat.iodp, sbssat.tlat); + for (i = 0; i < sbssat.nsat; i++) { + j = 0; + satp = sbssat.sat + i; + valid = timediff(time, satp->lcorr.t0) <= MAXSBSAGEL && satp->lcorr.t0.time; + satno2id(satp->sat, id); + Tbl->Cells[j++][i + 1] = id; + Tbl->Cells[j++][i + 1] = valid ? "OK" : "-"; + Tbl->Cells[j++][i + 1] = s.sprintf("%d", satp->lcorr.iode); + Tbl->Cells[j++][i + 1] = s.sprintf("%.3f", satp->lcorr.dpos[0]); + Tbl->Cells[j++][i + 1] = s.sprintf("%.3f", satp->lcorr.dpos[1]); + Tbl->Cells[j++][i + 1] = s.sprintf("%.3f", satp->lcorr.dpos[2]); + Tbl->Cells[j++][i + 1] = s.sprintf("%.4f", satp->lcorr.dvel[0]); + Tbl->Cells[j++][i + 1] = s.sprintf("%.4f", satp->lcorr.dvel[1]); + Tbl->Cells[j++][i + 1] = s.sprintf("%.4f", satp->lcorr.dvel[2]); + Tbl->Cells[j++][i + 1] = s.sprintf("%.3f", satp->lcorr.daf0 * 1E9); + Tbl->Cells[j++][i + 1] = s.sprintf("%.4f", satp->lcorr.daf1 * 1E9); + if (satp->lcorr.t0.time) + time2str(satp->lcorr.t0, tstr, 0); + else + strcpy(tstr, "-"); + Tbl->Cells[j++][i + 1] = tstr; + } } //--------------------------------------------------------------------------- -void __fastcall TMonitorDialog::SetSbsIono(void) -{ - AnsiString label[]={ - "IODI","Lat (deg)","Lon (deg)","GIVEI","Delay (m)","T0" - }; - int i,width[]={30,50,50,30,60,115}; - - Tbl->ColCount=6; - Tbl->RowCount=2; - for (i=0;iColCount;i++) { - Tbl->ColWidths[i]=width[i]*FontScale/96; - Tbl->Cells[i][0]=label[i]; - Tbl->Cells[i][1]=""; - } +void __fastcall TMonitorDialog::SetSbsIono(void) { + AnsiString label[] = {"IODI", "Lat (deg)", "Lon (deg)", "GIVEI", "Delay (m)", "T0"}; + int i, width[] = {30, 50, 50, 30, 60, 115}; + + Tbl->ColCount = 6; + Tbl->RowCount = 2; + for (i = 0; i < Tbl->ColCount; i++) { + Tbl->ColWidths[i] = width[i] * FontScale / 96; + Tbl->Cells[i][0] = label[i]; + Tbl->Cells[i][1] = ""; + } } //--------------------------------------------------------------------------- -void __fastcall TMonitorDialog::ShowSbsIono(void) -{ - AnsiString s,s0="-"; - sbsion_t sbsion[MAXBAND+1],*ion; - char tstr[40]; - int i,j,k,n=0; - - rtksvrlock(&rtksvr); // lock - for (i=0;i<=MAXBAND;i++) sbsion[i]=rtksvr.nav.sbsion[i]; - rtksvrunlock(&rtksvr); // unlock - - Label->Caption=""; - for (i=0;inigp;j++) { - k=0; - Tbl->Cells[k++][n+1]=s.sprintf("%d",ion->iodi); - Tbl->Cells[k++][n+1]=s.sprintf("%d",ion->igp[j].lat); - Tbl->Cells[k++][n+1]=s.sprintf("%d",ion->igp[j].lon); - Tbl->Cells[k++][n+1]=ion->igp[j].give?s.sprintf("%d",ion->igp[j].give-1):s0; - Tbl->Cells[k++][n+1]=s.sprintf("%.3f",ion->igp[j].delay); - if (ion->igp[j].t0.time) time2str(ion->igp[j].t0,tstr,0); - else strcpy(tstr,"-"); - Tbl->Cells[k++][n+1]=tstr; - n++; - } - } - Tbl->RowCount=n<=0?2:n+1; +void __fastcall TMonitorDialog::ShowSbsIono(void) { + AnsiString s, s0 = "-"; + sbsion_t sbsion[MAXBAND + 1], *ion; + char tstr[40]; + int i, j, k, n = 0; + + rtksvrlock(&rtksvr); // lock + for (i = 0; i <= MAXBAND; i++) sbsion[i] = rtksvr.nav.sbsion[i]; + rtksvrunlock(&rtksvr); // unlock + + Label->Caption = ""; + for (i = 0; i < MAXBAND + 1; i++) { + ion = sbsion + i; + for (j = 0; j < ion->nigp; j++) { + k = 0; + Tbl->Cells[k++][n + 1] = s.sprintf("%d", ion->iodi); + Tbl->Cells[k++][n + 1] = s.sprintf("%d", ion->igp[j].lat); + Tbl->Cells[k++][n + 1] = s.sprintf("%d", ion->igp[j].lon); + Tbl->Cells[k++][n + 1] = ion->igp[j].give ? s.sprintf("%d", ion->igp[j].give - 1) : s0; + Tbl->Cells[k++][n + 1] = s.sprintf("%.3f", ion->igp[j].delay); + if (ion->igp[j].t0.time) + time2str(ion->igp[j].t0, tstr, 0); + else + strcpy(tstr, "-"); + Tbl->Cells[k++][n + 1] = tstr; + n++; + } + } + Tbl->RowCount = n <= 0 ? 2 : n + 1; } //--------------------------------------------------------------------------- -void __fastcall TMonitorDialog::SetSbsFast(void) -{ - AnsiString label[]={ - "SAT","Status","PRC (m)","RRC (m)","IODF","UDREI","AI","Tof" - }; - int i,width[]={25,30,60,60,30,30,30,115}; - - Tbl->ColCount=8; - Tbl->RowCount=2; - for (i=0;iColCount;i++) { - Tbl->ColWidths[i]=width[i]*FontScale/96; - Tbl->Cells[i][0]=label[i]; - Tbl->Cells[i][1]=""; - } +void __fastcall TMonitorDialog::SetSbsFast(void) { + AnsiString label[] = {"SAT", "Status", "PRC (m)", "RRC (m)", "IODF", "UDREI", "AI", "Tof"}; + int i, width[] = {25, 30, 60, 60, 30, 30, 30, 115}; + + Tbl->ColCount = 8; + Tbl->RowCount = 2; + for (i = 0; i < Tbl->ColCount; i++) { + Tbl->ColWidths[i] = width[i] * FontScale / 96; + Tbl->Cells[i][0] = label[i]; + Tbl->Cells[i][1] = ""; + } } //--------------------------------------------------------------------------- -void __fastcall TMonitorDialog::ShowSbsFast(void) -{ - AnsiString s,s0="-"; - sbssat_t sbssat; - sbssatp_t *satp; - gtime_t time; - int i,j,n,valid; - char tstr[40],id[8]; - - rtksvrlock(&rtksvr); // lock - time=rtksvr.rtk.sol.time; - sbssat=rtksvr.nav.sbssat; - rtksvrunlock(&rtksvr); // unlock - - Label->Caption=""; - Tbl->RowCount=sbssat.nsat<=0?1:sbssat.nsat+1; - //Label->Caption=s.sprintf("IODP:%2d System Latency:%2d s",sbssat.iodp,sbssat.tlat); - for (i=0;ifcorr.t0))<=MAXSBSAGEF&&satp->fcorr.t0.time&& - 0<=satp->fcorr.udre-1&&satp->fcorr.udre-1<14; - satno2id(satp->sat,id); - Tbl->Cells[j++][i+1]=id; - Tbl->Cells[j++][i+1]=valid?"OK":"-"; - Tbl->Cells[j++][i+1]=s.sprintf("%.3f",satp->fcorr.prc); - Tbl->Cells[j++][i+1]=s.sprintf("%.4f",satp->fcorr.rrc); - Tbl->Cells[j++][i+1]=s.sprintf("%d",satp->fcorr.iodf); - Tbl->Cells[j++][i+1]=satp->fcorr.udre?s.sprintf("%d",satp->fcorr.udre-1):s0; - Tbl->Cells[j++][i+1]=s.sprintf("%d",satp->fcorr.ai); - if (satp->fcorr.t0.time) time2str(satp->fcorr.t0,tstr,0); - else strcpy(tstr,"-"); - Tbl->Cells[j++][i+1]=tstr; - } +void __fastcall TMonitorDialog::ShowSbsFast(void) { + AnsiString s, s0 = "-"; + sbssat_t sbssat; + sbssatp_t *satp; + gtime_t time; + int i, j, n, valid; + char tstr[40], id[8]; + + rtksvrlock(&rtksvr); // lock + time = rtksvr.rtk.sol.time; + sbssat = rtksvr.nav.sbssat; + rtksvrunlock(&rtksvr); // unlock + + Label->Caption = ""; + Tbl->RowCount = sbssat.nsat <= 0 ? 1 : sbssat.nsat + 1; + // Label->Caption=s.sprintf("IODP:%2d System Latency:%2d s",sbssat.iodp,sbssat.tlat); + for (i = 0; i < sbssat.nsat; i++) { + j = 0; + satp = sbssat.sat + i; + valid = fabs(timediff(time, satp->fcorr.t0)) <= MAXSBSAGEF && satp->fcorr.t0.time && + 0 <= satp->fcorr.udre - 1 && satp->fcorr.udre - 1 < 14; + satno2id(satp->sat, id); + Tbl->Cells[j++][i + 1] = id; + Tbl->Cells[j++][i + 1] = valid ? "OK" : "-"; + Tbl->Cells[j++][i + 1] = s.sprintf("%.3f", satp->fcorr.prc); + Tbl->Cells[j++][i + 1] = s.sprintf("%.4f", satp->fcorr.rrc); + Tbl->Cells[j++][i + 1] = s.sprintf("%d", satp->fcorr.iodf); + Tbl->Cells[j++][i + 1] = satp->fcorr.udre ? s.sprintf("%d", satp->fcorr.udre - 1) : s0; + Tbl->Cells[j++][i + 1] = s.sprintf("%d", satp->fcorr.ai); + if (satp->fcorr.t0.time) + time2str(satp->fcorr.t0, tstr, 0); + else + strcpy(tstr, "-"); + Tbl->Cells[j++][i + 1] = tstr; + } } //--------------------------------------------------------------------------- -void __fastcall TMonitorDialog::SetRtcm(void) -{ - AnsiString label[]={"Parameter","Value"}; - int i,width[]={220,520}; - - Tbl->ColCount=2; - Tbl->RowCount=2; - for (i=0;iColCount;i++) { - Tbl->ColWidths[i]=width[i]*FontScale/96; - Tbl->Cells[i][0]=label[i]; - Tbl->Cells[i][1]=""; - } +void __fastcall TMonitorDialog::SetRtcm(void) { + AnsiString label[] = {"Parameter", "Value"}; + int i, width[] = {220, 520}; + + Tbl->ColCount = 2; + Tbl->RowCount = 2; + for (i = 0; i < Tbl->ColCount; i++) { + Tbl->ColWidths[i] = width[i] * FontScale / 96; + Tbl->Cells[i][0] = label[i]; + Tbl->Cells[i][1] = ""; + } } //--------------------------------------------------------------------------- -void __fastcall TMonitorDialog::ShowRtcm(void) -{ - AnsiString s; - static rtcm_t rtcm; - double pos[3]={0}; - int i=1,j,format; - char tstr[40]="-",mstr1[1024]="",mstr2[1024]="",*p1=mstr1,*p2=mstr2; - - rtksvrlock(&rtksvr); - format=rtksvr.format[Str1]; - rtcm=rtksvr.rtcm[Str1]; - rtksvrunlock(&rtksvr); - - if (rtcm.time.time) time2str(rtcm.time,tstr,3); - - for (j=1;j<100;j++) { - if (rtcm.nmsg2[j]==0) continue; - p1+=sprintf(p1,"%s%d (%d)",p1>mstr1?",":"",j,rtcm.nmsg2[j]); - } - if (rtcm.nmsg2[0]>0) { - sprintf(p1,"%sother (%d)",p1>mstr1?",":"",rtcm.nmsg2[0]); - } - for (j=1;j<300;j++) { - if (rtcm.nmsg3[j]==0) continue; - p2+=sprintf(p2,"%s%d(%d)",p2>mstr2?",":"",j+1000,rtcm.nmsg3[j]); - } - for (j=300;j<399;j++) { - if (rtcm.nmsg3[j]==0) continue; - p2+=sprintf(p2,"%s%d(%d)",p2>mstr2?",":"",j+3770,rtcm.nmsg3[j]); - } - if (rtcm.nmsg3[0]>0) { - sprintf(p2,"%sother(%d)",p2>mstr2?",":"",rtcm.nmsg3[0]); - } - Label->Caption=""; - - Tbl->RowCount=16; - - Tbl->Cells[0][i ]="Format"; - Tbl->Cells[1][i++]=format==STRFMT_RTCM2?"RTCM 2":"RTCM 3"; - - Tbl->Cells[0][i ]="Message Time"; - Tbl->Cells[1][i++]=tstr; - - Tbl->Cells[0][i ]="Station ID"; - Tbl->Cells[1][i++]=s.sprintf("%d",rtcm.staid); - - Tbl->Cells[0][i ]="Station Health"; - Tbl->Cells[1][i++]=s.sprintf("%d",rtcm.stah); - - Tbl->Cells[0][i ]="Sequence No"; - Tbl->Cells[1][i++]=s.sprintf("%d",rtcm.seqno); - - Tbl->Cells[0][i ]="RTCM Special Message"; - Tbl->Cells[1][i++]=rtcm.msg; - - Tbl->Cells[0][i ]="Last Message"; - Tbl->Cells[1][i++]=rtcm.msgtype; - - Tbl->Cells[0][i ]="# of RTCM Messages"; - Tbl->Cells[1][i++]=format==STRFMT_RTCM2?mstr1:mstr2; - - Tbl->Cells[0][i ]="MSM Signals for GPS"; - Tbl->Cells[1][i++]=rtcm.msmtype[0]; - - Tbl->Cells[0][i ]="MSM Signals for GLONASS"; - Tbl->Cells[1][i++]=rtcm.msmtype[1]; - - Tbl->Cells[0][i ]="MSM Signals for Galileo"; - Tbl->Cells[1][i++]=rtcm.msmtype[2]; - - Tbl->Cells[0][i ]="MSM Signals for QZSS"; - Tbl->Cells[1][i++]=rtcm.msmtype[3]; - - Tbl->Cells[0][i ]="MSM Signals for SBAS"; - Tbl->Cells[1][i++]=rtcm.msmtype[4]; - - Tbl->Cells[0][i ]="MSM Signals for BDS"; - Tbl->Cells[1][i++]=rtcm.msmtype[5]; - - Tbl->Cells[0][i ]="MSM Signals for NavIC"; - Tbl->Cells[1][i++]=rtcm.msmtype[6]; +void __fastcall TMonitorDialog::ShowRtcm(void) { + AnsiString s; + static rtcm_t rtcm; + double pos[3] = {0}; + int i = 1, j, format; + char tstr[40] = "-", mstr1[1024] = "", mstr2[1024] = "", *p1 = mstr1, *p2 = mstr2; + + rtksvrlock(&rtksvr); + format = rtksvr.format[Str1]; + rtcm = rtksvr.rtcm[Str1]; + rtksvrunlock(&rtksvr); + + if (rtcm.time.time) time2str(rtcm.time, tstr, 3); + + for (j = 1; j < 100; j++) { + if (rtcm.nmsg2[j] == 0) continue; + p1 += sprintf(p1, "%s%d (%d)", p1 > mstr1 ? "," : "", j, rtcm.nmsg2[j]); + } + if (rtcm.nmsg2[0] > 0) { + sprintf(p1, "%sother (%d)", p1 > mstr1 ? "," : "", rtcm.nmsg2[0]); + } + for (j = 1; j < 300; j++) { + if (rtcm.nmsg3[j] == 0) continue; + p2 += sprintf(p2, "%s%d(%d)", p2 > mstr2 ? "," : "", j + 1000, rtcm.nmsg3[j]); + } + for (j = 300; j < 399; j++) { + if (rtcm.nmsg3[j] == 0) continue; + p2 += sprintf(p2, "%s%d(%d)", p2 > mstr2 ? "," : "", j + 3770, rtcm.nmsg3[j]); + } + if (rtcm.nmsg3[0] > 0) { + sprintf(p2, "%sother(%d)", p2 > mstr2 ? "," : "", rtcm.nmsg3[0]); + } + Label->Caption = ""; + + Tbl->RowCount = 16; + + Tbl->Cells[0][i] = "Format"; + Tbl->Cells[1][i++] = format == STRFMT_RTCM2 ? "RTCM 2" : "RTCM 3"; + + Tbl->Cells[0][i] = "Message Time"; + Tbl->Cells[1][i++] = tstr; + + Tbl->Cells[0][i] = "Station ID"; + Tbl->Cells[1][i++] = s.sprintf("%d", rtcm.staid); + + Tbl->Cells[0][i] = "Station Health"; + Tbl->Cells[1][i++] = s.sprintf("%d", rtcm.stah); + + Tbl->Cells[0][i] = "Sequence No"; + Tbl->Cells[1][i++] = s.sprintf("%d", rtcm.seqno); + + Tbl->Cells[0][i] = "RTCM Special Message"; + Tbl->Cells[1][i++] = rtcm.msg; + + Tbl->Cells[0][i] = "Last Message"; + Tbl->Cells[1][i++] = rtcm.msgtype; + + Tbl->Cells[0][i] = "# of RTCM Messages"; + Tbl->Cells[1][i++] = format == STRFMT_RTCM2 ? mstr1 : mstr2; + + Tbl->Cells[0][i] = "MSM Signals for GPS"; + Tbl->Cells[1][i++] = rtcm.msmtype[0]; + + Tbl->Cells[0][i] = "MSM Signals for GLONASS"; + Tbl->Cells[1][i++] = rtcm.msmtype[1]; + + Tbl->Cells[0][i] = "MSM Signals for Galileo"; + Tbl->Cells[1][i++] = rtcm.msmtype[2]; + + Tbl->Cells[0][i] = "MSM Signals for QZSS"; + Tbl->Cells[1][i++] = rtcm.msmtype[3]; + + Tbl->Cells[0][i] = "MSM Signals for SBAS"; + Tbl->Cells[1][i++] = rtcm.msmtype[4]; + + Tbl->Cells[0][i] = "MSM Signals for BDS"; + Tbl->Cells[1][i++] = rtcm.msmtype[5]; + + Tbl->Cells[0][i] = "MSM Signals for NavIC"; + Tbl->Cells[1][i++] = rtcm.msmtype[6]; } //--------------------------------------------------------------------------- -void __fastcall TMonitorDialog::SetRtcmDgps(void) -{ - AnsiString label[]={ - "SAT","Status","PRC (m)","RRC (m)","IOD","UDRE","T0" - }; - int i,width[]={25,30,60,60,30,30,115}; - - Tbl->ColCount=7; - Tbl->RowCount=2; - for (i=0;iColCount;i++) { - Tbl->ColWidths[i]=width[i]*FontScale/96; - Tbl->Cells[i][0]=label[i]; - Tbl->Cells[i][1]=""; - } +void __fastcall TMonitorDialog::SetRtcmDgps(void) { + AnsiString label[] = {"SAT", "Status", "PRC (m)", "RRC (m)", "IOD", "UDRE", "T0"}; + int i, width[] = {25, 30, 60, 60, 30, 30, 115}; + + Tbl->ColCount = 7; + Tbl->RowCount = 2; + for (i = 0; i < Tbl->ColCount; i++) { + Tbl->ColWidths[i] = width[i] * FontScale / 96; + Tbl->Cells[i][0] = label[i]; + Tbl->Cells[i][1] = ""; + } } //--------------------------------------------------------------------------- -void __fastcall TMonitorDialog::ShowRtcmDgps(void) -{ - AnsiString s; - gtime_t time; - dgps_t dgps[MAXSAT]; - int i,j,valid; - char tstr[40],id[8]; - - rtksvrlock(&rtksvr); - time=rtksvr.rtk.sol.time; - for (i=0;iCaption=""; - Tbl->RowCount=MAXSAT+1; - - for (i=0;iRowCount;i++) { - j=0; - satno2id(i+1,id); - valid=dgps[i].t0.time&&fabs(timediff(time,dgps[i].t0))<=1800.0; - Tbl->Cells[j++][i+1]=id; - Tbl->Cells[j++][i+1]=valid?"OK":"-"; - Tbl->Cells[j++][i+1]=s.sprintf("%.3f",dgps[i].prc); - Tbl->Cells[j++][i+1]=s.sprintf("%.4f",dgps[i].rrc); - Tbl->Cells[j++][i+1]=s.sprintf("%d",dgps[i].iod); - Tbl->Cells[j++][i+1]=s.sprintf("%d",dgps[i].udre); - if (dgps[i].t0.time) time2str(dgps[i].t0,tstr,0); else strcpy(tstr,"-"); - Tbl->Cells[j++][i+1]=tstr; - } +void __fastcall TMonitorDialog::ShowRtcmDgps(void) { + AnsiString s; + gtime_t time; + dgps_t dgps[MAXSAT]; + int i, j, valid; + char tstr[40], id[8]; + + rtksvrlock(&rtksvr); + time = rtksvr.rtk.sol.time; + for (i = 0; i < MAXSAT; i++) dgps[i] = rtksvr.nav.dgps[i]; + rtksvrunlock(&rtksvr); + + Label->Caption = ""; + Tbl->RowCount = MAXSAT + 1; + + for (i = 0; i < Tbl->RowCount; i++) { + j = 0; + satno2id(i + 1, id); + valid = dgps[i].t0.time && fabs(timediff(time, dgps[i].t0)) <= 1800.0; + Tbl->Cells[j++][i + 1] = id; + Tbl->Cells[j++][i + 1] = valid ? "OK" : "-"; + Tbl->Cells[j++][i + 1] = s.sprintf("%.3f", dgps[i].prc); + Tbl->Cells[j++][i + 1] = s.sprintf("%.4f", dgps[i].rrc); + Tbl->Cells[j++][i + 1] = s.sprintf("%d", dgps[i].iod); + Tbl->Cells[j++][i + 1] = s.sprintf("%d", dgps[i].udre); + if (dgps[i].t0.time) + time2str(dgps[i].t0, tstr, 0); + else + strcpy(tstr, "-"); + Tbl->Cells[j++][i + 1] = tstr; + } } //--------------------------------------------------------------------------- -void __fastcall TMonitorDialog::SetRtcmSsr(void) -{ - AnsiString s,label[]={ - "SAT","Status","UDI(s)","UDHR(s)","IOD","URA","Datum","T0", - "D0-A(m)","D0-C(m)","D0-R(m)","D1-A(mm/s)","D1-C(mm/s)","D1-R(mm/s)", - "C0(m)","C1(mm/s)","C2(mm/s2)","C-HR(m)","Code Bias(m)", - "Phase Bias(m)" - }; - int i,width[]={ - 25,30,30,30,30,25,15,115,50,50,50,50,50,50,50,50,50,50,180,180 - }; - char *code; - - Tbl->ColCount=20; - Tbl->RowCount=2; - for (i=0;i<20;i++) { - Tbl->ColWidths[i]=width[i]*FontScale/96; - Tbl->Cells[i][0]=label[i]; - Tbl->Cells[i][1]=""; - } +void __fastcall TMonitorDialog::SetRtcmSsr(void) { + AnsiString s, label[] = {"SAT", "Status", "UDI(s)", "UDHR(s)", "IOD", + "URA", "Datum", "T0", "D0-A(m)", "D0-C(m)", + "D0-R(m)", "D1-A(mm/s)", "D1-C(mm/s)", "D1-R(mm/s)", "C0(m)", + "C1(mm/s)", "C2(mm/s2)", "C-HR(m)", "Code Bias(m)", "Phase Bias(m)"}; + int i, + width[] = {25, 30, 30, 30, 30, 25, 15, 115, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 180, 180}; + char *code; + + Tbl->ColCount = 20; + Tbl->RowCount = 2; + for (i = 0; i < 20; i++) { + Tbl->ColWidths[i] = width[i] * FontScale / 96; + Tbl->Cells[i][0] = label[i]; + Tbl->Cells[i][1] = ""; + } } //--------------------------------------------------------------------------- -void __fastcall TMonitorDialog::ShowRtcmSsr(void) -{ - AnsiString s; - gtime_t time; - ssr_t ssr[MAXSAT]; - int i,j,k,n,valid,sat[MAXSAT],sys=sys_tbl[SelSys2->ItemIndex+1]; - char tstr[40],id[8],buff[256]="",*p; - - rtksvrlock(&rtksvr); - time=rtksvr.rtk.sol.time; - for (i=n=0;iCaption=""; - Tbl->RowCount=n+1; - - for (i=0;iCells[j++][i+1]=id; - valid=ssr[i].t0[0].time&&fabs(timediff(time,ssr[i].t0[0]))<=1800.0; - Tbl->Cells[j++][i+1]=valid?"OK":"-"; - Tbl->Cells[j++][i+1]=s.sprintf("%.0f",ssr[i].udi[0]); - Tbl->Cells[j++][i+1]=s.sprintf("%.0f",ssr[i].udi[2]); - Tbl->Cells[j++][i+1]=s.sprintf("%d",ssr[i].iode); - Tbl->Cells[j++][i+1]=s.sprintf("%d",ssr[i].ura); - Tbl->Cells[j++][i+1]=s.sprintf("%d",ssr[i].refd); - if (ssr[i].t0[0].time) time2str(ssr[i].t0[0],tstr,0); else strcpy(tstr,"-"); - Tbl->Cells[j++][i+1]=tstr; - for (k=0;k<3;k++) { - Tbl->Cells[j++][i+1]=s.sprintf("%.3f",ssr[i].deph[k]); - } - for (k=0;k<3;k++) { - Tbl->Cells[j++][i+1]=s.sprintf("%.3f",ssr[i].ddeph[k]*1E3); - } - Tbl->Cells[j++][i+1]=s.sprintf("%.3f",ssr[i].dclk[0]); - Tbl->Cells[j++][i+1]=s.sprintf("%.3f",ssr[i].dclk[1]*1E3); - Tbl->Cells[j++][i+1]=s.sprintf("%.5f",ssr[i].dclk[2]*1E3); - Tbl->Cells[j++][i+1]=s.sprintf("%.3f",ssr[i].hrclk); - buff[0]='\0'; - for (p=buff,k=0;kCells[j++][i+1]=buff; - buff[0]='\0'; - for (p=buff,k=0;kCells[j++][i+1]=buff; - } +void __fastcall TMonitorDialog::ShowRtcmSsr(void) { + AnsiString s; + gtime_t time; + ssr_t ssr[MAXSAT]; + int i, j, k, n, valid, sat[MAXSAT], sys = sys_tbl[SelSys2->ItemIndex + 1]; + char tstr[40], id[8], buff[256] = "", *p; + + rtksvrlock(&rtksvr); + time = rtksvr.rtk.sol.time; + for (i = n = 0; i < MAXSAT; i++) { + if (!(satsys(i + 1, NULL) & sys)) continue; + ssr[n] = rtksvr.rtcm[Str1].ssr[i]; + sat[n++] = i + 1; + } + rtksvrunlock(&rtksvr); + + Label->Caption = ""; + Tbl->RowCount = n + 1; + + for (i = 0; i < n; i++) { + j = 0; + satno2id(sat[i], id); + Tbl->Cells[j++][i + 1] = id; + valid = ssr[i].t0[0].time && fabs(timediff(time, ssr[i].t0[0])) <= 1800.0; + Tbl->Cells[j++][i + 1] = valid ? "OK" : "-"; + Tbl->Cells[j++][i + 1] = s.sprintf("%.0f", ssr[i].udi[0]); + Tbl->Cells[j++][i + 1] = s.sprintf("%.0f", ssr[i].udi[2]); + Tbl->Cells[j++][i + 1] = s.sprintf("%d", ssr[i].iode); + Tbl->Cells[j++][i + 1] = s.sprintf("%d", ssr[i].ura); + Tbl->Cells[j++][i + 1] = s.sprintf("%d", ssr[i].refd); + if (ssr[i].t0[0].time) + time2str(ssr[i].t0[0], tstr, 0); + else + strcpy(tstr, "-"); + Tbl->Cells[j++][i + 1] = tstr; + for (k = 0; k < 3; k++) { + Tbl->Cells[j++][i + 1] = s.sprintf("%.3f", ssr[i].deph[k]); + } + for (k = 0; k < 3; k++) { + Tbl->Cells[j++][i + 1] = s.sprintf("%.3f", ssr[i].ddeph[k] * 1E3); + } + Tbl->Cells[j++][i + 1] = s.sprintf("%.3f", ssr[i].dclk[0]); + Tbl->Cells[j++][i + 1] = s.sprintf("%.3f", ssr[i].dclk[1] * 1E3); + Tbl->Cells[j++][i + 1] = s.sprintf("%.5f", ssr[i].dclk[2] * 1E3); + Tbl->Cells[j++][i + 1] = s.sprintf("%.3f", ssr[i].hrclk); + buff[0] = '\0'; + for (p = buff, k = 0; k < MAXCODE; k++) { + if (ssr[i].cbias[k] == 0.0) continue; + p += sprintf(p, "%s:%.3f ", code2obs(k + 1), ssr[i].cbias[k]); + } + Tbl->Cells[j++][i + 1] = buff; + buff[0] = '\0'; + for (p = buff, k = 0; k < MAXCODE; k++) { + if (ssr[i].pbias[k] == 0.0) continue; + p += sprintf(p, "%s:%.3f ", code2obs(k + 1), ssr[i].pbias[k]); + } + Tbl->Cells[j++][i + 1] = buff; + } } //--------------------------------------------------------------------------- -void __fastcall TMonitorDialog::SetRefSta(void) -{ - AnsiString label[]={"Parameter","Value"}; - int i,width[]={220,520}; - - Tbl->ColCount=2; - Tbl->RowCount=2; - for (i=0;iColCount;i++) { - Tbl->ColWidths[i]=width[i]*FontScale/96; - Tbl->Cells[i][0]=label[i]; - Tbl->Cells[i][1]=""; - } +void __fastcall TMonitorDialog::SetRefSta(void) { + AnsiString label[] = {"Parameter", "Value"}; + int i, width[] = {220, 520}; + + Tbl->ColCount = 2; + Tbl->RowCount = 2; + for (i = 0; i < Tbl->ColCount; i++) { + Tbl->ColWidths[i] = width[i] * FontScale / 96; + Tbl->Cells[i][0] = label[i]; + Tbl->Cells[i][1] = ""; + } } //--------------------------------------------------------------------------- -void __fastcall TMonitorDialog::ShowRefSta(void) -{ - AnsiString s; - gtime_t time; - sta_t sta; - double pos[3]={0}; - int i=1,format; - char tstr[40]="-"; - - rtksvrlock(&rtksvr); - format=rtksvr.format[Str1]; - if (format==STRFMT_RTCM2||format==STRFMT_RTCM3) { - time=rtksvr.rtcm[Str1].time; - sta=rtksvr.rtcm[Str1].sta; - } - else { - time=rtksvr.raw[Str1].time; - sta=rtksvr.raw[Str1].sta; - } - rtksvrunlock(&rtksvr); - - Label->Caption=""; - - Tbl->RowCount=17; - - Tbl->Cells[0][i ]="Format"; - Tbl->Cells[1][i++]=formatstrs[format]; - - if (time.time) time2str(time,tstr,3); - Tbl->Cells[0][i ]="Message Time"; - Tbl->Cells[1][i++]=tstr; - - Tbl->Cells[0][i ]="Station Pos X/Y/Z (m)"; - Tbl->Cells[1][i++]=s.sprintf("%.3f,%.3f,%.3f",sta.pos[0],sta.pos[1],sta.pos[2]); - - if (norm(sta.pos,3)>0.0) ecef2pos(sta.pos,pos); - Tbl->Cells[0][i ]="Station Lat/Lon/Height (deg,m)"; - Tbl->Cells[1][i++]=s.sprintf("%.8f,%.8f,%.3f",pos[0]*R2D,pos[1]*R2D,pos[2]); - - Tbl->Cells[0][i ]="ITRF Realization Year"; - Tbl->Cells[1][i++]=s.sprintf("%d",sta.itrf); - - Tbl->Cells[0][i ]="Antenna Delta Type"; - Tbl->Cells[1][i++]=sta.deltype?"X/Y/Z":"E/N/U"; - - Tbl->Cells[0][i ]="Antenna Delta (m)"; - Tbl->Cells[1][i++]=s.sprintf("%.3f,%.3f,%.3f",sta.del[0],sta.del[1],sta.del[2]); - - Tbl->Cells[0][i ]="Antenna Height (m)"; - Tbl->Cells[1][i++]=s.sprintf("%.3f",sta.hgt); - - Tbl->Cells[0][i ]="Antenna Descriptor"; - Tbl->Cells[1][i++]=sta.antdes; - - Tbl->Cells[0][i ]="Antenna Setup Id"; - Tbl->Cells[1][i++]=s.sprintf("%d",sta.antsetup); - - Tbl->Cells[0][i ]="Antenna Serial No"; - Tbl->Cells[1][i++]=sta.antsno; - - Tbl->Cells[0][i ]="Receiver Type Descriptor"; - Tbl->Cells[1][i++]=sta.rectype; - - Tbl->Cells[0][i ]="Receiver Firmware Version"; - Tbl->Cells[1][i++]=sta.recver; - - Tbl->Cells[0][i ]="Receiver Serial No"; - Tbl->Cells[1][i++]=sta.recsno; - - Tbl->Cells[0][i ]="GLONASS Code-Phase Alignment"; - Tbl->Cells[1][i++]=sta.glo_cp_align?"Aligned":"Not aligned"; - - Tbl->Cells[0][i ]="GLONASS Code-Phase Bias C1/P1/C2/P2 (m)"; - Tbl->Cells[1][i++]=s.sprintf("%.2f, %.2f, %.2f, %.2f",sta.glo_cp_bias[0], - sta.glo_cp_bias[1],sta.glo_cp_bias[2], - sta.glo_cp_bias[3]); +void __fastcall TMonitorDialog::ShowRefSta(void) { + AnsiString s; + gtime_t time; + sta_t sta; + double pos[3] = {0}; + int i = 1, format; + char tstr[40] = "-"; + + rtksvrlock(&rtksvr); + format = rtksvr.format[Str1]; + if (format == STRFMT_RTCM2 || format == STRFMT_RTCM3) { + time = rtksvr.rtcm[Str1].time; + sta = rtksvr.rtcm[Str1].sta; + } else { + time = rtksvr.raw[Str1].time; + sta = rtksvr.raw[Str1].sta; + } + rtksvrunlock(&rtksvr); + + Label->Caption = ""; + + Tbl->RowCount = 17; + + Tbl->Cells[0][i] = "Format"; + Tbl->Cells[1][i++] = formatstrs[format]; + + if (time.time) time2str(time, tstr, 3); + Tbl->Cells[0][i] = "Message Time"; + Tbl->Cells[1][i++] = tstr; + + Tbl->Cells[0][i] = "Station Pos X/Y/Z (m)"; + Tbl->Cells[1][i++] = s.sprintf("%.3f,%.3f,%.3f", sta.pos[0], sta.pos[1], sta.pos[2]); + + if (norm(sta.pos, 3) > 0.0) ecef2pos(sta.pos, pos); + Tbl->Cells[0][i] = "Station Lat/Lon/Height (deg,m)"; + Tbl->Cells[1][i++] = s.sprintf("%.8f,%.8f,%.3f", pos[0] * R2D, pos[1] * R2D, pos[2]); + + Tbl->Cells[0][i] = "ITRF Realization Year"; + Tbl->Cells[1][i++] = s.sprintf("%d", sta.itrf); + + Tbl->Cells[0][i] = "Antenna Delta Type"; + Tbl->Cells[1][i++] = sta.deltype ? "X/Y/Z" : "E/N/U"; + + Tbl->Cells[0][i] = "Antenna Delta (m)"; + Tbl->Cells[1][i++] = s.sprintf("%.3f,%.3f,%.3f", sta.del[0], sta.del[1], sta.del[2]); + + Tbl->Cells[0][i] = "Antenna Height (m)"; + Tbl->Cells[1][i++] = s.sprintf("%.3f", sta.hgt); + + Tbl->Cells[0][i] = "Antenna Descriptor"; + Tbl->Cells[1][i++] = sta.antdes; + + Tbl->Cells[0][i] = "Antenna Setup Id"; + Tbl->Cells[1][i++] = s.sprintf("%d", sta.antsetup); + + Tbl->Cells[0][i] = "Antenna Serial No"; + Tbl->Cells[1][i++] = sta.antsno; + + Tbl->Cells[0][i] = "Receiver Type Descriptor"; + Tbl->Cells[1][i++] = sta.rectype; + + Tbl->Cells[0][i] = "Receiver Firmware Version"; + Tbl->Cells[1][i++] = sta.recver; + + Tbl->Cells[0][i] = "Receiver Serial No"; + Tbl->Cells[1][i++] = sta.recsno; + + Tbl->Cells[0][i] = "GLONASS Code-Phase Alignment"; + Tbl->Cells[1][i++] = sta.glo_cp_align ? "Aligned" : "Not aligned"; + + Tbl->Cells[0][i] = "GLONASS Code-Phase Bias C1/P1/C2/P2 (m)"; + Tbl->Cells[1][i++] = s.sprintf("%.2f, %.2f, %.2f, %.2f", sta.glo_cp_bias[0], sta.glo_cp_bias[1], + sta.glo_cp_bias[2], sta.glo_cp_bias[3]); } //--------------------------------------------------------------------------- -void __fastcall TMonitorDialog::BtnCopyClick(TObject *Sender) -{ - AnsiString text; - - if (Console->Visible) { - for (int i = 0; i < ConBuff->Count; i++) { - if (i > 0) text += "\r\n"; - text += ConBuff->Strings[i]; - } - } else { - - for (int col = 0; col < Tbl->ColCount; col++) { - if (col > 0) text += "\t"; - text += Tbl->Cells[col][0]; - } - text += "\r\n"; +void __fastcall TMonitorDialog::BtnCopyClick(TObject *Sender) { + AnsiString text; - for (int row = 1; row < Tbl->RowCount; row++) { - for (int col = 0; col < Tbl->ColCount; col++) { - if (col > 0) text += "\t"; - text += Tbl->Cells[col][row]; - } - if (row < Tbl->RowCount - 1) { - text += "\r\n"; - } - } + if (Console->Visible) { + for (int i = 0; i < ConBuff->Count; i++) { + if (i > 0) text += "\r\n"; + text += ConBuff->Strings[i]; + } + } else { + for (int col = 0; col < Tbl->ColCount; col++) { + if (col > 0) text += "\t"; + text += Tbl->Cells[col][0]; } + text += "\r\n"; - if (text.Length() > 0) { - Clipboard()->AsText = text; - // ShowMessage("Copied to clipboard"); - } + for (int row = 1; row < Tbl->RowCount; row++) { + for (int col = 0; col < Tbl->ColCount; col++) { + if (col > 0) text += "\t"; + text += Tbl->Cells[col][row]; + } + if (row < Tbl->RowCount - 1) { + text += "\r\n"; + } + } + } + if (text.Length() > 0) { + Clipboard()->AsText = text; + // ShowMessage("Copied to clipboard"); + } } //--------------------------------------------------------------------------- - diff --git a/app/winapp/rtknavi/mondlg.h b/app/winapp/rtknavi/mondlg.h index f2daed796..a0ece1195 100644 --- a/app/winapp/rtknavi/mondlg.h +++ b/app/winapp/rtknavi/mondlg.h @@ -2,100 +2,100 @@ #ifndef mondlgH #define mondlgH //--------------------------------------------------------------------------- +#include #include #include -#include -#include #include +#include #include -#include +#include //--------------------------------------------------------------------------- -class TMonitorDialog : public TForm -{ -__published: - TStringGrid *Tbl; - TPanel *Panel1; - TButton *BtnClose; - TTimer *Timer1; - TLabel *Label; - TComboBox *Type; - TPaintBox *Console; - TTimer *Timer2; - TScrollBar *Scroll; - TSpeedButton *BtnPause; - TSpeedButton *BtnDown; - TSpeedButton *BtnClear; - TComboBox *SelEph; - TComboBox *SelStr; - TComboBox *SelSat; - TComboBox *SelObs; - TComboBox *SelFmt; - TComboBox *SelSys; - TComboBox *SelSys2; - TComboBox *SelStr2; - TPanel *Panel2; - void __fastcall FormShow(TObject *Sender); - void __fastcall FormClose(TObject *Sender, TCloseAction &Action); - void __fastcall ConsolePaint(TObject *Sender); - void __fastcall BtnCloseClick(TObject *Sender); - void __fastcall BtnDownClick(TObject *Sender); - void __fastcall BtnClearClick(TObject *Sender); - void __fastcall TypeChange(TObject *Sender); - void __fastcall Timer1Timer(TObject *Sender); - void __fastcall Timer2Timer(TObject *Sender); - void __fastcall ScrollChange(TObject *Sender); - void __fastcall SelObsChange(TObject *Sender); - void __fastcall SelFmtChange(TObject *Sender); - void __fastcall SelStrChange(TObject *Sender); - void __fastcall SelStr2Change(TObject *Sender); - void __fastcall BtnCopyClick(TObject *Sender); -private: - int TypeF,ConFmt,Str1,Str2,ScrollPos,FontScale,ObsMode; - TStringList *ConBuff; - rtcm_t rtcm; - raw_t raw; - - void __fastcall ClearTable(void); - void __fastcall SetRtk(void); - void __fastcall SetSat(void); - void __fastcall SetEst(void); - void __fastcall SetCov(void); - void __fastcall SetObs(void); - void __fastcall SetNav(void); - void __fastcall SetGnav(void); - void __fastcall SetStr(void); - void __fastcall SetSbsMsg(void); - void __fastcall SetSbsLong(void); - void __fastcall SetSbsIono(void); - void __fastcall SetSbsFast(void); - void __fastcall SetSbsNav(void); - void __fastcall SetIonUtc(void); - void __fastcall SetRtcm(void); - void __fastcall SetRtcmDgps(void); - void __fastcall SetRtcmSsr(void); - void __fastcall SetRefSta(void); - void __fastcall ShowRtk(void); - void __fastcall ShowSat(void); - void __fastcall ShowEst(void); - void __fastcall ShowCov(void); - void __fastcall ShowObs(void); - void __fastcall ShowNav(void); - void __fastcall ShowGnav(void); - void __fastcall ShowSbsMsg(void); - void __fastcall ShowIonUtc(void); - void __fastcall ShowStr(void); - void __fastcall ShowSbsLong(void); - void __fastcall ShowSbsIono(void); - void __fastcall ShowSbsFast(void); - void __fastcall ShowSbsNav(void); - void __fastcall ShowRtcm(void); - void __fastcall ShowRtcmDgps(void); - void __fastcall ShowRtcmSsr(void); - void __fastcall ShowRefSta(void); - void __fastcall AddConsole(uint8_t *msg, int len, int mode); - void __fastcall ViewConsole(void); -public: - __fastcall TMonitorDialog(TComponent* Owner); +class TMonitorDialog : public TForm { + __published : TStringGrid *Tbl; + TPanel *Panel1; + TButton *BtnClose; + TTimer *Timer1; + TLabel *Label; + TComboBox *Type; + TPaintBox *Console; + TTimer *Timer2; + TScrollBar *Scroll; + TSpeedButton *BtnPause; + TSpeedButton *BtnDown; + TSpeedButton *BtnClear; + TComboBox *SelEph; + TComboBox *SelStr; + TComboBox *SelSat; + TComboBox *SelObs; + TComboBox *SelFmt; + TComboBox *SelSys; + TComboBox *SelSys2; + TComboBox *SelStr2; + TPanel *Panel2; + void __fastcall FormShow(TObject *Sender); + void __fastcall FormClose(TObject *Sender, TCloseAction &Action); + void __fastcall ConsolePaint(TObject *Sender); + void __fastcall BtnCloseClick(TObject *Sender); + void __fastcall BtnDownClick(TObject *Sender); + void __fastcall BtnClearClick(TObject *Sender); + void __fastcall TypeChange(TObject *Sender); + void __fastcall Timer1Timer(TObject *Sender); + void __fastcall Timer2Timer(TObject *Sender); + void __fastcall ScrollChange(TObject *Sender); + void __fastcall SelObsChange(TObject *Sender); + void __fastcall SelFmtChange(TObject *Sender); + void __fastcall SelStrChange(TObject *Sender); + void __fastcall SelStr2Change(TObject *Sender); + void __fastcall BtnCopyClick(TObject *Sender); + + private: + int TypeF, ConFmt, Str1, Str2, ScrollPos, FontScale, ObsMode; + TStringList *ConBuff; + rtcm_t rtcm; + raw_t raw; + + void __fastcall ClearTable(void); + void __fastcall SetRtk(void); + void __fastcall SetSat(void); + void __fastcall SetEst(void); + void __fastcall SetCov(void); + void __fastcall SetObs(void); + void __fastcall SetNav(void); + void __fastcall SetGnav(void); + void __fastcall SetStr(void); + void __fastcall SetSbsMsg(void); + void __fastcall SetSbsLong(void); + void __fastcall SetSbsIono(void); + void __fastcall SetSbsFast(void); + void __fastcall SetSbsNav(void); + void __fastcall SetIonUtc(void); + void __fastcall SetRtcm(void); + void __fastcall SetRtcmDgps(void); + void __fastcall SetRtcmSsr(void); + void __fastcall SetRefSta(void); + void __fastcall ShowRtk(void); + void __fastcall ShowSat(void); + void __fastcall ShowEst(void); + void __fastcall ShowCov(void); + void __fastcall ShowObs(void); + void __fastcall ShowNav(void); + void __fastcall ShowGnav(void); + void __fastcall ShowSbsMsg(void); + void __fastcall ShowIonUtc(void); + void __fastcall ShowStr(void); + void __fastcall ShowSbsLong(void); + void __fastcall ShowSbsIono(void); + void __fastcall ShowSbsFast(void); + void __fastcall ShowSbsNav(void); + void __fastcall ShowRtcm(void); + void __fastcall ShowRtcmDgps(void); + void __fastcall ShowRtcmSsr(void); + void __fastcall ShowRefSta(void); + void __fastcall AddConsole(uint8_t *msg, int len, int mode); + void __fastcall ViewConsole(void); + + public: + __fastcall TMonitorDialog(TComponent *Owner); }; //--------------------------------------------------------------------------- #endif diff --git a/app/winapp/rtknavi/navimain.cpp b/app/winapp/rtknavi/navimain.cpp index a0ce89240..bfa99cd5e 100644 --- a/app/winapp/rtknavi/navimain.cpp +++ b/app/winapp/rtknavi/navimain.cpp @@ -27,2926 +27,2894 @@ // clang-format off #include // clang-format on -#include +#include #include #include -#include + +#include #pragma hdrstop -#include "rtklib.h" +#include "navimain.h" + +#include "aboutdlg.h" +#include "confdlg.h" +#include "graph.h" #include "instrdlg.h" -#include "outstrdlg.h" #include "logstrdlg.h" +#include "markdlg.h" #include "mondlg.h" +#include "naviopt.h" +#include "outstrdlg.h" +#include "rtklib.h" #include "tcpoptdlg.h" -#include "confdlg.h" -#include "aboutdlg.h" -#include "markdlg.h" #include "viewer.h" -#include "naviopt.h" -#include "navimain.h" -#include "graph.h" //--------------------------------------------------------------------------- #pragma package(smart_init) #pragma resource "*.dfm" TMainForm *MainForm; -#define PRGNAME "RTKNAVI" // program name -#define TRACEFILE "rtknavi_%Y%m%d%h%M.trace" // debug trace file -#define STATFILE "rtknavi_%Y%m%d%h%M.stat" // solution status file -#define CLORANGE (TColor)0x00AAFF -#define CLLGRAY (TColor)0xDDDDDD -#define CHARDEG "\302\260" // character code of degree -#define MINSNR 10 // minimum snr -#define MAXSNR 60 // maximum snr -#define KEYF6 0x75 // code of function key F6 -#define KEYF7 0x76 // code of function key F7 -#define KEYF8 0x77 // code of function key F8 -#define KEYF9 0x78 // code of function key F9 -#define KEYF10 0x79 // code of function key F10 +#define PRGNAME "RTKNAVI" // program name +#define TRACEFILE "rtknavi_%Y%m%d%h%M.trace" // debug trace file +#define STATFILE "rtknavi_%Y%m%d%h%M.stat" // solution status file +#define CLORANGE (TColor)0x00AAFF +#define CLLGRAY (TColor)0xDDDDDD +#define CHARDEG "\302\260" // character code of degree +#define MINSNR 10 // minimum snr +#define MAXSNR 60 // maximum snr +#define KEYF6 0x75 // code of function key F6 +#define KEYF7 0x76 // code of function key F7 +#define KEYF8 0x77 // code of function key F8 +#define KEYF9 0x78 // code of function key F9 +#define KEYF10 0x79 // code of function key F10 #define PANELFONTNAME "Tahoma" #define PANELFONTSIZE 8 #define POSFONTNAME "Palatino Linotype" #define POSFONTSIZE 10 -#define MINBLLEN 0.01 // minimum baseline length to show +#define MINBLLEN 0.01 // minimum baseline length to show -#define KACYCLE 5000 // keep alive cycle (ms) -#define TIMEOUT 10000 // inactive timeout time (ms) -#define DEFAULTPORT 52001 // default monitor port number -#define MAXPORTOFF 9 // max port number offset -#define MAXTRKSCALE 26 // track scale -#define SPLITTER_WIDTH 6 // splitter width -#define MAXPANELMODE 7 // max panel mode +#define KACYCLE 5000 // keep alive cycle (ms) +#define TIMEOUT 10000 // inactive timeout time (ms) +#define DEFAULTPORT 52001 // default monitor port number +#define MAXPORTOFF 9 // max port number offset +#define MAXTRKSCALE 26 // track scale +#define SPLITTER_WIDTH 6 // splitter width +#define MAXPANELMODE 7 // max panel mode -#define SQRT(x) ((x)<0.0||(x)!=(x)?0.0:sqrt(x)) -#define MIN(x,y) ((x)<(y)?(x):(y)) +#define SQRT(x) ((x) < 0.0 || (x) != (x) ? 0.0 : sqrt(x)) +#define MIN(x, y) ((x) < (y) ? (x) : (y)) //--------------------------------------------------------------------------- -rtksvr_t rtksvr; // rtk server struct -stream_t monistr; // monitor stream +rtksvr_t rtksvr; // rtk server struct +stream_t monistr; // monitor stream // show message in message area --------------------------------------------- extern "C" { -extern int showmsg(const char *format,...) {return 0;} +extern int showmsg(const char *format, ...) { return 0; } } // convert degree to deg-min-sec -------------------------------------------- -static void degtodms(double deg, double *dms) -{ - double sgn=1.0; - if (deg<0.0) {deg=-deg; sgn=-1.0;} - dms[0]=floor(deg); - dms[1]=floor((deg-dms[0])*60.0); - dms[2]=(deg-dms[0]-dms[1]/60.0)*3600; - dms[0]*=sgn; +static void degtodms(double deg, double *dms) { + double sgn = 1.0; + if (deg < 0.0) { + deg = -deg; + sgn = -1.0; + } + dms[0] = floor(deg); + dms[1] = floor((deg - dms[0]) * 60.0); + dms[2] = (deg - dms[0] - dms[1] / 60.0) * 3600; + dms[0] *= sgn; } // execute command ---------------------------------------------------------- -int __fastcall TMainForm::ExecCmd(AnsiString cmd, int show) -{ - PROCESS_INFORMATION info; - STARTUPINFO si={0}; - si.cb=sizeof(si); - char *p=cmd.c_str(); - if (!CreateProcess(NULL,p,NULL,NULL,false,show?0:CREATE_NO_WINDOW,NULL, - NULL,&si,&info)) return 0; - CloseHandle(info.hProcess); - CloseHandle(info.hThread); - return 1; +int __fastcall TMainForm::ExecCmd(AnsiString cmd, int show) { + PROCESS_INFORMATION info; + STARTUPINFO si = {0}; + si.cb = sizeof(si); + char *p = cmd.c_str(); + if (!CreateProcess(NULL, p, NULL, NULL, false, show ? 0 : CREATE_NO_WINDOW, NULL, NULL, &si, + &info)) + return 0; + CloseHandle(info.hProcess); + CloseHandle(info.hThread); + return 1; } // constructor -------------------------------------------------------------- -__fastcall TMainForm::TMainForm(TComponent* Owner) - : TForm(Owner) -{ - SvrCycle=SvrBuffSize=0; - SolBuffSize=1000; - for (int i=0;i<8;i++) { - StreamC[i]=Stream[i]=Format[i]=CmdEna[i][0]=CmdEna[i][1]=CmdEna[i][2]=0; - } - for (int i=0;i<3;i++) { - CmdEna[i][0]=CmdEna[i][1]=CmdEna[i][2]=0; - } - TimeSys=SolType=PlotType1=PlotType2=FreqType1=FreqType2=0; - TrkType1=TrkType2=0; - TrkScale1=TrkScale2=5; - BLMode1=BLMode2=BLMode3=BLMode4=0; - PSol=PSolS=PSolE=Nsat[0]=Nsat[1]=0; - NMapPnt=0; - OpenPort=0; - Time=NULL; - SolStat=Nvsat=NULL; - SolCurrentStat=0; - SolRov=SolRef=Qr=VelRov=Age=Ratio=NULL; - for (int i=0;i<2;i++) for (int j=0;jShowMainForm=false; - TrayIcon->Visible=true; - } +void __fastcall TMainForm::FormCreate(TObject *Sender) { + char *p, *argv[32], buff[1024], file[1024] = "rtknavi.exe"; + int argc = 0, tasktray = 0; + + trace(3, "FormCreate\n"); + + ::GetModuleFileName(NULL, file, sizeof(file)); + if (!(p = strrchr(file, '.'))) p = file + strlen(file); + strcpy(p, ".ini"); + IniFile = file; + + InitSolBuff(); + SetTrayIcon(1); + strinitcom(); + + strcpy(buff, GetCommandLine()); + + for (p = buff; *p && argc < 32; p++) { + if (*p == ' ') continue; + if (*p == '"') { + argv[argc++] = p + 1; + if (!(p = strchr(p + 1, '"'))) break; + } else { + argv[argc++] = p; + if (!(p = strchr(p + 1, ' '))) break; + } + *p = '\0'; + } + for (int i = 1; i < argc; i++) { + if (!strcmp(argv[i], "-i") && i + 1 < argc) IniFile = argv[++i]; + } + for (int i = 1; i < argc; i++) { + if (!strcmp(argv[i], "-t") && i + 1 < argc) + Caption = argv[++i]; + else if (!strcmp(argv[i], "-auto")) + AutoRun = 1; + else if (!strcmp(argv[i], "-tray")) + tasktray = 1; + } + if (tasktray) { + Application->ShowMainForm = false; + TrayIcon->Visible = true; + } } // callback on form show ---------------------------------------------------- -void __fastcall TMainForm::FormShow(TObject *Sender) -{ - trace(3,"FormShow\n"); - - LoadOpt(); - LoadNav(&rtksvr.nav); - OpenMoniPort(MoniPort); - - UpdatePanel(); - UpdateTimeSys(); - UpdateSolType(); - UpdateFont(); - UpdatePos(); - UpdateEnable(); - - if (AutoRun) { - SvrStart(); - } - Timer->Enabled=true; +void __fastcall TMainForm::FormShow(TObject *Sender) { + trace(3, "FormShow\n"); + + LoadOpt(); + LoadNav(&rtksvr.nav); + OpenMoniPort(MoniPort); + + UpdatePanel(); + UpdateTimeSys(); + UpdateSolType(); + UpdateFont(); + UpdatePos(); + UpdateEnable(); + + if (AutoRun) { + SvrStart(); + } + Timer->Enabled = true; } // callback on form close --------------------------------------------------- -void __fastcall TMainForm::FormClose(TObject *Sender, TCloseAction &Action) -{ - trace(3,"FormClose\n"); - - Timer->Enabled=false; - if (OpenPort>0) { - // send disconnect message - strwrite(&monistr,(uint8_t *)MSG_DISCONN,strlen(MSG_DISCONN)); - - strclose(&monistr); - } - SaveOpt(); - SaveNav(&rtksvr.nav); +void __fastcall TMainForm::FormClose(TObject *Sender, TCloseAction &Action) { + trace(3, "FormClose\n"); + + Timer->Enabled = false; + if (OpenPort > 0) { + // send disconnect message + strwrite(&monistr, (uint8_t *)MSG_DISCONN, strlen(MSG_DISCONN)); + + strclose(&monistr); + } + SaveOpt(); + SaveNav(&rtksvr.nav); } // callback panel 21 resize -------------------------------------------------- -void __fastcall TMainForm::Panel21Resize(TObject *Sender) -{ - trace(3,"Panel21Resize\n"); - - BtnSolType->Left=Panel21->Width-BtnSolType->Width-2; +void __fastcall TMainForm::Panel21Resize(TObject *Sender) { + trace(3, "Panel21Resize\n"); + + BtnSolType->Left = Panel21->Width - BtnSolType->Width - 2; } // callback panel 211 resize ------------------------------------------------- -void __fastcall TMainForm::Panel211Resize(TObject *Sender) -{ - int h=abs(Pos1->Font->Height)-2,w=Panel211->Width; - int y0,y1,y2,y3,y4,y5; - - trace(3,"Panel211Resize\n"); - - y2=Panel211->Height/2-h/2-6; - y1=y2-h-10; y3=y2+h+10; y0=y1-h-12; y4=y3+h+10; y5=y4+14; - - PlabelA ->Top=y0+2; Solution->Top=y0+5-h/2; IndSol->Top=y0+4; - Plabel1 ->Top=y1; Pos1->Top=y1; - Plabel2 ->Top=y2; Pos2->Top=y2; - Plabel3 ->Top=y3; Pos3->Top=y3; - LabelStd ->Top=y4; - LabelNSat->Top=y5; - Solution->Left=40; Solution->Width=w-72; IndSol->Left=w-24; - Plabel1->Left=14; Pos1->Left=30; Pos1->Width=w-42; - Plabel2->Left=14; Pos2->Left=30; Pos2->Width=w-42; - Plabel3->Left=14; Pos3->Left=30; Pos3->Width=w-42; - LabelStd ->Left=2; LabelStd ->Width=w-4; - LabelNSat->Left=2; LabelNSat->Width=w-4; - UpdatePos(); +void __fastcall TMainForm::Panel211Resize(TObject *Sender) { + int h = abs(Pos1->Font->Height) - 2, w = Panel211->Width; + int y0, y1, y2, y3, y4, y5; + + trace(3, "Panel211Resize\n"); + + y2 = Panel211->Height / 2 - h / 2 - 6; + y1 = y2 - h - 10; + y3 = y2 + h + 10; + y0 = y1 - h - 12; + y4 = y3 + h + 10; + y5 = y4 + 14; + + PlabelA->Top = y0 + 2; + Solution->Top = y0 + 5 - h / 2; + IndSol->Top = y0 + 4; + Plabel1->Top = y1; + Pos1->Top = y1; + Plabel2->Top = y2; + Pos2->Top = y2; + Plabel3->Top = y3; + Pos3->Top = y3; + LabelStd->Top = y4; + LabelNSat->Top = y5; + Solution->Left = 40; + Solution->Width = w - 72; + IndSol->Left = w - 24; + Plabel1->Left = 14; + Pos1->Left = 30; + Pos1->Width = w - 42; + Plabel2->Left = 14; + Pos2->Left = 30; + Pos2->Width = w - 42; + Plabel3->Left = 14; + Pos3->Left = 30; + Pos3->Width = w - 42; + LabelStd->Left = 2; + LabelStd->Width = w - 4; + LabelNSat->Left = 2; + LabelNSat->Width = w - 4; + UpdatePos(); } // callback panel 22 resize --------------------------------------------------- -void __fastcall TMainForm::Panel22Resize(TObject *Sender) -{ - TPanel *panel=(TPanel *)Sender; - - trace(3,"Panel22Resize\n"); - - BtnPlotType1->Left=panel->Width-BtnPlotType1->Width-2; - BtnFreqType1->Left=BtnPlotType1->Left-BtnFreqType1->Width-2; - UpdatePlot(); +void __fastcall TMainForm::Panel22Resize(TObject *Sender) { + TPanel *panel = (TPanel *)Sender; + + trace(3, "Panel22Resize\n"); + + BtnPlotType1->Left = panel->Width - BtnPlotType1->Width - 2; + BtnFreqType1->Left = BtnPlotType1->Left - BtnFreqType1->Width - 2; + UpdatePlot(); } // callback panel 23 resize --------------------------------------------------- -void __fastcall TMainForm::Panel23Resize(TObject *Sender) -{ - TPanel *panel=(TPanel *)Sender; - - trace(3,"Panel23Resize\n"); - - BtnPlotType2->Left=panel->Width-BtnPlotType2->Width-2; - BtnFreqType2->Left=BtnPlotType2->Left-BtnFreqType2->Width-2; - UpdatePlot(); +void __fastcall TMainForm::Panel23Resize(TObject *Sender) { + TPanel *panel = (TPanel *)Sender; + + trace(3, "Panel23Resize\n"); + + BtnPlotType2->Left = panel->Width - BtnPlotType2->Width - 2; + BtnFreqType2->Left = BtnPlotType2->Left - BtnFreqType2->Width - 2; + UpdatePlot(); } // callback panel 24 resize --------------------------------------------------- -void __fastcall TMainForm::Panel24Resize(TObject *Sender) -{ - TPanel *panel=(TPanel *)Sender; - - trace(3,"Panel24Resize\n"); - - BtnPlotType3->Left=panel->Width-BtnPlotType3->Width-2; - BtnFreqType3->Left=BtnPlotType3->Left-BtnFreqType3->Width-2; - UpdatePlot(); +void __fastcall TMainForm::Panel24Resize(TObject *Sender) { + TPanel *panel = (TPanel *)Sender; + + trace(3, "Panel24Resize\n"); + + BtnPlotType3->Left = panel->Width - BtnPlotType3->Width - 2; + BtnFreqType3->Left = BtnPlotType3->Left - BtnFreqType3->Width - 2; + UpdatePlot(); } // callback panel 25 resize --------------------------------------------------- -void __fastcall TMainForm::Panel25Resize(TObject *Sender) -{ - TPanel *panel=(TPanel *)Sender; - - trace(3,"Panel25Resize\n"); - - BtnPlotType4->Left=panel->Width-BtnPlotType4->Width-2; - BtnFreqType4->Left=BtnPlotType4->Left-BtnFreqType4->Width-2; - UpdatePlot(); +void __fastcall TMainForm::Panel25Resize(TObject *Sender) { + TPanel *panel = (TPanel *)Sender; + + trace(3, "Panel25Resize\n"); + + BtnPlotType4->Left = panel->Width - BtnPlotType4->Width - 2; + BtnFreqType4->Left = BtnPlotType4->Left - BtnFreqType4->Width - 2; + UpdatePlot(); } // callback panel 4 resize -------------------------------------------------- -void __fastcall TMainForm::Panel4Resize(TObject *Sender) -{ - TBitBtn *btn[]={BtnStart,BtnMark,BtnPlot,BtnOpt,BtnExit}; - TPanel *panel=(TPanel *)Sender; - int w=(panel->Width-2)/5,h=panel->Height; - for (int i=0;i<5;i++) { - btn[i]->Left=w*i+2; - btn[i]->Top=0; - btn[i]->Width=w-4; - btn[i]->Height=h-2; - } - BtnStop->Left =BtnStart->Left; - BtnStop->Top =BtnStart->Top; - BtnStop->Width =BtnStart->Width; - BtnStop->Height=BtnStart->Height; +void __fastcall TMainForm::Panel4Resize(TObject *Sender) { + TBitBtn *btn[] = {BtnStart, BtnMark, BtnPlot, BtnOpt, BtnExit}; + TPanel *panel = (TPanel *)Sender; + int w = (panel->Width - 2) / 5, h = panel->Height; + for (int i = 0; i < 5; i++) { + btn[i]->Left = w * i + 2; + btn[i]->Top = 0; + btn[i]->Width = w - 4; + btn[i]->Height = h - 2; + } + BtnStop->Left = BtnStart->Left; + BtnStop->Top = BtnStart->Top; + BtnStop->Width = BtnStart->Width; + BtnStop->Height = BtnStart->Height; } // callback panel 5 resize -------------------------------------------------- -void __fastcall TMainForm::Panel5Resize(TObject *Sender) -{ - BtnSolType2->Left=BtnSolType2->Parent->Width-BtnSolType2->Width-2; +void __fastcall TMainForm::Panel5Resize(TObject *Sender) { + BtnSolType2->Left = BtnSolType2->Parent->Width - BtnSolType2->Width - 2; } // update panel ------------------------------------------------------------- -void __fastcall TMainForm::UpdatePanel(void) -{ - Panel21->Align=alNone; - Panel22->Align=alNone; - Panel23->Align=alNone; - Panel24->Align=alNone; - Panel25->Align=alNone; - Splitter1->Align=alNone; - Splitter2->Align=alNone; - Splitter3->Align=alNone; - Splitter4->Align=alNone; - - if (PanelMode<=3) { - Panel21->Visible=true; - Panel5 ->Visible=false; - } - else { - Panel21->Visible=false; - Panel5 ->Visible=true; - } - if (PanelMode==0||PanelMode==4) { - Panel22->Visible=true; - Panel23->Visible=false; - Panel24->Visible=false; - Panel25->Visible=false; - } - else if (PanelMode==1||PanelMode==5) { - Panel22->Visible=true; - Panel23->Visible=true; - Panel24->Visible=false; - Panel25->Visible=false; - } - else if (PanelMode==2||PanelMode==6) { - Panel22->Visible=true; - Panel23->Visible=true; - Panel24->Visible=true; - Panel25->Visible=false; - } - else { - Panel22->Visible=true; - Panel23->Visible=true; - Panel24->Visible=true; - Panel25->Visible=true; - } - Splitter1->Visible=Panel21->Visible&&Panel22->Visible; - Splitter2->Visible=Panel22->Visible&&Panel23->Visible; - Splitter3->Visible=Panel23->Visible&&Panel24->Visible; - Splitter4->Visible=Panel24->Visible&&Panel25->Visible; - - if (PanelStack==0) { // horizontal - - Splitter1->Width=SPLITTER_WIDTH; - Splitter2->Width=SPLITTER_WIDTH; - Splitter3->Width=SPLITTER_WIDTH; - Splitter4->Width=SPLITTER_WIDTH; - Panel21->Left=0; - Splitter1->Left=Panel21->Left+Panel21->Width; - Panel22->Left=Splitter1->Left+Splitter1->Width; - Splitter2->Left=Panel22->Left+Panel22->Width; - Panel23->Left=Splitter2->Left+Splitter2->Width; - Splitter3->Left=Panel23->Left+Panel23->Width; - Panel24->Left=Splitter3->Left+Splitter3->Width; - Splitter4->Left=Panel24->Left+Panel24->Width; - Panel25->Left=Splitter4->Left+Splitter4->Width; - Panel21->Align=Panel22->Visible?alLeft:alClient; - Splitter1->Align=alLeft; - Panel22->Align=Panel23->Visible?alLeft:alClient; - Splitter2->Align=alLeft; - Panel23->Align=Panel24->Visible?alLeft:alClient; - Splitter3->Align=alLeft; - Panel24->Align=Panel25->Visible?alLeft:alClient; - Splitter4->Align=alLeft; - Panel25->Align=alClient; - } - else { // vertical - Splitter1->Height=SPLITTER_WIDTH; - Splitter2->Height=SPLITTER_WIDTH; - Splitter3->Height=SPLITTER_WIDTH; - Splitter4->Height=SPLITTER_WIDTH; - Panel21->Top=0; - Splitter1->Top=Panel21->Top+Panel21->Height; - Panel22->Top=Splitter1->Top+Splitter1->Height; - Splitter2->Top=Panel22->Top+Panel22->Height; - Panel23->Top=Splitter2->Top+Splitter2->Height; - Splitter3->Top=Panel23->Top+Panel23->Height; - Panel24->Top=Splitter3->Top+Splitter3->Height; - Splitter4->Top=Panel24->Top+Panel24->Height; - Panel25->Top=Splitter4->Top+Splitter4->Height; - Panel21->Align=Panel22->Visible?alTop:alClient; - Splitter1->Align=alTop; - Panel22->Align=Panel23->Visible?alTop:alClient; - Splitter2->Align=alTop; - Panel23->Align=Panel24->Visible?alTop:alClient; - Splitter3->Align=alTop; - Panel24->Align=Panel25->Visible?alTop:alClient; - Splitter4->Align=alTop; - Panel25->Align=alClient; - } +void __fastcall TMainForm::UpdatePanel(void) { + Panel21->Align = alNone; + Panel22->Align = alNone; + Panel23->Align = alNone; + Panel24->Align = alNone; + Panel25->Align = alNone; + Splitter1->Align = alNone; + Splitter2->Align = alNone; + Splitter3->Align = alNone; + Splitter4->Align = alNone; + + if (PanelMode <= 3) { + Panel21->Visible = true; + Panel5->Visible = false; + } else { + Panel21->Visible = false; + Panel5->Visible = true; + } + if (PanelMode == 0 || PanelMode == 4) { + Panel22->Visible = true; + Panel23->Visible = false; + Panel24->Visible = false; + Panel25->Visible = false; + } else if (PanelMode == 1 || PanelMode == 5) { + Panel22->Visible = true; + Panel23->Visible = true; + Panel24->Visible = false; + Panel25->Visible = false; + } else if (PanelMode == 2 || PanelMode == 6) { + Panel22->Visible = true; + Panel23->Visible = true; + Panel24->Visible = true; + Panel25->Visible = false; + } else { + Panel22->Visible = true; + Panel23->Visible = true; + Panel24->Visible = true; + Panel25->Visible = true; + } + Splitter1->Visible = Panel21->Visible && Panel22->Visible; + Splitter2->Visible = Panel22->Visible && Panel23->Visible; + Splitter3->Visible = Panel23->Visible && Panel24->Visible; + Splitter4->Visible = Panel24->Visible && Panel25->Visible; + + if (PanelStack == 0) { // horizontal + + Splitter1->Width = SPLITTER_WIDTH; + Splitter2->Width = SPLITTER_WIDTH; + Splitter3->Width = SPLITTER_WIDTH; + Splitter4->Width = SPLITTER_WIDTH; + Panel21->Left = 0; + Splitter1->Left = Panel21->Left + Panel21->Width; + Panel22->Left = Splitter1->Left + Splitter1->Width; + Splitter2->Left = Panel22->Left + Panel22->Width; + Panel23->Left = Splitter2->Left + Splitter2->Width; + Splitter3->Left = Panel23->Left + Panel23->Width; + Panel24->Left = Splitter3->Left + Splitter3->Width; + Splitter4->Left = Panel24->Left + Panel24->Width; + Panel25->Left = Splitter4->Left + Splitter4->Width; + Panel21->Align = Panel22->Visible ? alLeft : alClient; + Splitter1->Align = alLeft; + Panel22->Align = Panel23->Visible ? alLeft : alClient; + Splitter2->Align = alLeft; + Panel23->Align = Panel24->Visible ? alLeft : alClient; + Splitter3->Align = alLeft; + Panel24->Align = Panel25->Visible ? alLeft : alClient; + Splitter4->Align = alLeft; + Panel25->Align = alClient; + } else { // vertical + Splitter1->Height = SPLITTER_WIDTH; + Splitter2->Height = SPLITTER_WIDTH; + Splitter3->Height = SPLITTER_WIDTH; + Splitter4->Height = SPLITTER_WIDTH; + Panel21->Top = 0; + Splitter1->Top = Panel21->Top + Panel21->Height; + Panel22->Top = Splitter1->Top + Splitter1->Height; + Splitter2->Top = Panel22->Top + Panel22->Height; + Panel23->Top = Splitter2->Top + Splitter2->Height; + Splitter3->Top = Panel23->Top + Panel23->Height; + Panel24->Top = Splitter3->Top + Splitter3->Height; + Splitter4->Top = Panel24->Top + Panel24->Height; + Panel25->Top = Splitter4->Top + Splitter4->Height; + Panel21->Align = Panel22->Visible ? alTop : alClient; + Splitter1->Align = alTop; + Panel22->Align = Panel23->Visible ? alTop : alClient; + Splitter2->Align = alTop; + Panel23->Align = Panel24->Visible ? alTop : alClient; + Splitter3->Align = alTop; + Panel24->Align = Panel25->Visible ? alTop : alClient; + Splitter4->Align = alTop; + Panel25->Align = alClient; + } } // update enabled ----------------------------------------------------------- -void __fastcall TMainForm::UpdateEnable(void) -{ - BtnExpand1->Visible=PlotType1==6; - BtnShrink1->Visible=PlotType1==6; - BtnExpand2->Visible=PlotType2==6; - BtnShrink2->Visible=PlotType2==6; - BtnExpand3->Visible=PlotType3==6; - BtnShrink3->Visible=PlotType3==6; - BtnExpand4->Visible=PlotType4==6; - BtnShrink4->Visible=PlotType4==6; +void __fastcall TMainForm::UpdateEnable(void) { + BtnExpand1->Visible = PlotType1 == 6; + BtnShrink1->Visible = PlotType1 == 6; + BtnExpand2->Visible = PlotType2 == 6; + BtnShrink2->Visible = PlotType2 == 6; + BtnExpand3->Visible = PlotType3 == 6; + BtnShrink3->Visible = PlotType3 == 6; + BtnExpand4->Visible = PlotType4 == 6; + BtnShrink4->Visible = PlotType4 == 6; } // callback on button-exit -------------------------------------------------- -void __fastcall TMainForm::BtnExitClick(TObject *Sender) -{ - trace(3,"BtnExitClick\n"); - - Close(); +void __fastcall TMainForm::BtnExitClick(TObject *Sender) { + trace(3, "BtnExitClick\n"); + + Close(); } // callback on button-start ------------------------------------------------- -void __fastcall TMainForm::BtnStartClick(TObject *Sender) -{ - trace(3,"BtnStartClick\n"); - - SvrStart(); +void __fastcall TMainForm::BtnStartClick(TObject *Sender) { + trace(3, "BtnStartClick\n"); + + SvrStart(); } // callback on button-stop -------------------------------------------------- -void __fastcall TMainForm::BtnStopClick(TObject *Sender) -{ - trace(3,"BtnStopClick\n"); - - SvrStop(); +void __fastcall TMainForm::BtnStopClick(TObject *Sender) { + trace(3, "BtnStopClick\n"); + + SvrStop(); } // callback on button-plot -------------------------------------------------- -void __fastcall TMainForm::BtnPlotClick(TObject *Sender) -{ - AnsiString cmd,Ansi_Caption=Caption; - - trace(3,"BtnPlotClick\n"); - - if (OpenPort<=0) { - ShowMessage("monitor port not open"); - return; - } - cmd.sprintf("rtkplot -p tcpcli://localhost:%d -t \"%s %s\"",OpenPort, - Ansi_Caption.c_str(),": RTKPLOT"); - if (!ExecCmd(cmd,1)) { - ShowMessage("error : rtkplot execution"); - } +void __fastcall TMainForm::BtnPlotClick(TObject *Sender) { + AnsiString cmd, Ansi_Caption = Caption; + + trace(3, "BtnPlotClick\n"); + + if (OpenPort <= 0) { + ShowMessage("monitor port not open"); + return; + } + cmd.sprintf("rtkplot -p tcpcli://localhost:%d -t \"%s %s\"", OpenPort, Ansi_Caption.c_str(), + ": RTKPLOT"); + if (!ExecCmd(cmd, 1)) { + ShowMessage("error : rtkplot execution"); + } } // callback on button-options ----------------------------------------------- -void __fastcall TMainForm::BtnOptClick(TObject *Sender) -{ - int i,chgmoni=0,panelstack=PanelStack; - - trace(3,"BtnOptClick\n"); - - OptDialog->PrcOpt =PrcOpt; - OptDialog->SolOpt =SolOpt; - OptDialog->BaselineC =BaselineC; - OptDialog->Baseline[0]=Baseline[0]; - OptDialog->Baseline[1]=Baseline[1]; - - OptDialog->RovPosTypeF=RovPosTypeF; - OptDialog->RefPosTypeF=RefPosTypeF; - OptDialog->RovAntPcvF =RovAntPcvF; - OptDialog->RefAntPcvF =RefAntPcvF; - OptDialog->RovAntF =RovAntF; - OptDialog->RefAntF =RefAntF; - - OptDialog->SatPcvFileF=SatPcvFileF; - OptDialog->AntPcvFileF=AntPcvFileF; - OptDialog->StaPosFileF=StaPosFileF; - OptDialog->GeoidDataFileF=GeoidDataFileF; - OptDialog->DCBFileF =DCBFileF; - OptDialog->EOPFileF =EOPFileF; - OptDialog->LocalDirectory=LocalDirectory; - - OptDialog->SvrCycle =SvrCycle; - OptDialog->TimeoutTime=TimeoutTime; - OptDialog->ReconTime =ReconTime; - OptDialog->NmeaCycle =NmeaCycle; - OptDialog->FileSwapMargin=FileSwapMargin; - OptDialog->SvrBuffSize=SvrBuffSize; - OptDialog->SolBuffSize=SolBuffSize; - OptDialog->SavedSol =SavedSol; - OptDialog->NavSelect =NavSelect; - OptDialog->DgpsCorr =DgpsCorr; - OptDialog->SbasCorr =SbasCorr; - OptDialog->ExSats =ExSats; - OptDialog->ProxyAddr =ProxyAddr; - OptDialog->MoniPort =MoniPort; - OptDialog->PanelStack =PanelStack; - - for (i=0;i<3;i++) { - OptDialog->RovAntDel[i]=RovAntDel[i]; - OptDialog->RefAntDel[i]=RefAntDel[i]; - OptDialog->RovPos [i]=RovPos [i]; - OptDialog->RefPos [i]=RefPos [i]; - } - OptDialog->PanelFont->Assign(PanelFont); - OptDialog->PosFont->Assign(PosFont); - - if (OptDialog->ShowModal()!=mrOk) return; - - PrcOpt =OptDialog->PrcOpt; - SolOpt =OptDialog->SolOpt; - BaselineC =OptDialog->BaselineC; - Baseline[0]=OptDialog->Baseline[0]; - Baseline[1]=OptDialog->Baseline[1]; - - RovPosTypeF=OptDialog->RovPosTypeF; - RefPosTypeF=OptDialog->RefPosTypeF; - RovAntPcvF =OptDialog->RovAntPcvF; - RefAntPcvF =OptDialog->RefAntPcvF; - RovAntF =OptDialog->RovAntF; - RefAntF =OptDialog->RefAntF; - - SatPcvFileF=OptDialog->SatPcvFileF; - AntPcvFileF=OptDialog->AntPcvFileF; - StaPosFileF=OptDialog->StaPosFileF; - GeoidDataFileF=OptDialog->GeoidDataFileF; - DCBFileF =OptDialog->DCBFileF; - EOPFileF =OptDialog->EOPFileF; - LocalDirectory=OptDialog->LocalDirectory; - - SvrCycle =OptDialog->SvrCycle; - TimeoutTime=OptDialog->TimeoutTime; - ReconTime =OptDialog->ReconTime; - NmeaCycle =OptDialog->NmeaCycle; - FileSwapMargin=OptDialog->FileSwapMargin; - SvrBuffSize=OptDialog->SvrBuffSize; - SavedSol =OptDialog->SavedSol; - NavSelect =OptDialog->NavSelect; - DgpsCorr =OptDialog->DgpsCorr; - SbasCorr =OptDialog->SbasCorr; - ExSats =OptDialog->ExSats; - ProxyAddr =OptDialog->ProxyAddr; - if (MoniPort!=OptDialog->MoniPort) chgmoni=1; - MoniPort =OptDialog->MoniPort; - PanelStack =OptDialog->PanelStack; - PanelFont->Assign(OptDialog->PanelFont); - PosFont->Assign(OptDialog->PosFont); - UpdateFont(); - if (panelstack==0&&PanelStack==1) { - Panel21->Width=170; - Panel22->Width=170; - Panel23->Width=170; - } - UpdatePanel(); - if (SolBuffSize!=OptDialog->SolBuffSize) { - SolBuffSize=OptDialog->SolBuffSize; - InitSolBuff(); - UpdateTime(); - UpdatePos(); - UpdatePlot(); - } - for (i=0;i<3;i++) { - RovAntDel[i]=OptDialog->RovAntDel[i]; - RefAntDel[i]=OptDialog->RefAntDel[i]; - RovPos [i]=OptDialog->RovPos [i]; - RefPos [i]=OptDialog->RefPos [i]; - } - if (!chgmoni) return; - - // send disconnect message - if (OpenPort>0) { - strwrite(&monistr,(uint8_t *)MSG_DISCONN,strlen(MSG_DISCONN)); - - strclose(&monistr); - } - // reopen monitor stream - OpenMoniPort(MoniPort); +void __fastcall TMainForm::BtnOptClick(TObject *Sender) { + int i, chgmoni = 0, panelstack = PanelStack; + + trace(3, "BtnOptClick\n"); + + OptDialog->PrcOpt = PrcOpt; + OptDialog->SolOpt = SolOpt; + OptDialog->BaselineC = BaselineC; + OptDialog->Baseline[0] = Baseline[0]; + OptDialog->Baseline[1] = Baseline[1]; + + OptDialog->RovPosTypeF = RovPosTypeF; + OptDialog->RefPosTypeF = RefPosTypeF; + OptDialog->RovAntPcvF = RovAntPcvF; + OptDialog->RefAntPcvF = RefAntPcvF; + OptDialog->RovAntF = RovAntF; + OptDialog->RefAntF = RefAntF; + + OptDialog->SatPcvFileF = SatPcvFileF; + OptDialog->AntPcvFileF = AntPcvFileF; + OptDialog->StaPosFileF = StaPosFileF; + OptDialog->GeoidDataFileF = GeoidDataFileF; + OptDialog->DCBFileF = DCBFileF; + OptDialog->EOPFileF = EOPFileF; + OptDialog->LocalDirectory = LocalDirectory; + + OptDialog->SvrCycle = SvrCycle; + OptDialog->TimeoutTime = TimeoutTime; + OptDialog->ReconTime = ReconTime; + OptDialog->NmeaCycle = NmeaCycle; + OptDialog->FileSwapMargin = FileSwapMargin; + OptDialog->SvrBuffSize = SvrBuffSize; + OptDialog->SolBuffSize = SolBuffSize; + OptDialog->SavedSol = SavedSol; + OptDialog->NavSelect = NavSelect; + OptDialog->DgpsCorr = DgpsCorr; + OptDialog->SbasCorr = SbasCorr; + OptDialog->ExSats = ExSats; + OptDialog->ProxyAddr = ProxyAddr; + OptDialog->MoniPort = MoniPort; + OptDialog->PanelStack = PanelStack; + + for (i = 0; i < 3; i++) { + OptDialog->RovAntDel[i] = RovAntDel[i]; + OptDialog->RefAntDel[i] = RefAntDel[i]; + OptDialog->RovPos[i] = RovPos[i]; + OptDialog->RefPos[i] = RefPos[i]; + } + OptDialog->PanelFont->Assign(PanelFont); + OptDialog->PosFont->Assign(PosFont); + + if (OptDialog->ShowModal() != mrOk) return; + + PrcOpt = OptDialog->PrcOpt; + SolOpt = OptDialog->SolOpt; + BaselineC = OptDialog->BaselineC; + Baseline[0] = OptDialog->Baseline[0]; + Baseline[1] = OptDialog->Baseline[1]; + + RovPosTypeF = OptDialog->RovPosTypeF; + RefPosTypeF = OptDialog->RefPosTypeF; + RovAntPcvF = OptDialog->RovAntPcvF; + RefAntPcvF = OptDialog->RefAntPcvF; + RovAntF = OptDialog->RovAntF; + RefAntF = OptDialog->RefAntF; + + SatPcvFileF = OptDialog->SatPcvFileF; + AntPcvFileF = OptDialog->AntPcvFileF; + StaPosFileF = OptDialog->StaPosFileF; + GeoidDataFileF = OptDialog->GeoidDataFileF; + DCBFileF = OptDialog->DCBFileF; + EOPFileF = OptDialog->EOPFileF; + LocalDirectory = OptDialog->LocalDirectory; + + SvrCycle = OptDialog->SvrCycle; + TimeoutTime = OptDialog->TimeoutTime; + ReconTime = OptDialog->ReconTime; + NmeaCycle = OptDialog->NmeaCycle; + FileSwapMargin = OptDialog->FileSwapMargin; + SvrBuffSize = OptDialog->SvrBuffSize; + SavedSol = OptDialog->SavedSol; + NavSelect = OptDialog->NavSelect; + DgpsCorr = OptDialog->DgpsCorr; + SbasCorr = OptDialog->SbasCorr; + ExSats = OptDialog->ExSats; + ProxyAddr = OptDialog->ProxyAddr; + if (MoniPort != OptDialog->MoniPort) chgmoni = 1; + MoniPort = OptDialog->MoniPort; + PanelStack = OptDialog->PanelStack; + PanelFont->Assign(OptDialog->PanelFont); + PosFont->Assign(OptDialog->PosFont); + UpdateFont(); + if (panelstack == 0 && PanelStack == 1) { + Panel21->Width = 170; + Panel22->Width = 170; + Panel23->Width = 170; + } + UpdatePanel(); + if (SolBuffSize != OptDialog->SolBuffSize) { + SolBuffSize = OptDialog->SolBuffSize; + InitSolBuff(); + UpdateTime(); + UpdatePos(); + UpdatePlot(); + } + for (i = 0; i < 3; i++) { + RovAntDel[i] = OptDialog->RovAntDel[i]; + RefAntDel[i] = OptDialog->RefAntDel[i]; + RovPos[i] = OptDialog->RovPos[i]; + RefPos[i] = OptDialog->RefPos[i]; + } + if (!chgmoni) return; + + // send disconnect message + if (OpenPort > 0) { + strwrite(&monistr, (uint8_t *)MSG_DISCONN, strlen(MSG_DISCONN)); + + strclose(&monistr); + } + // reopen monitor stream + OpenMoniPort(MoniPort); } // callback on button-input-streams ----------------------------------------- -void __fastcall TMainForm::BtnInputStrClick(TObject *Sender) -{ - int i,j; - - trace(3,"BtnInputStrClick\n"); - - for (i=0;i<3;i++) { - InputStrDialog->StreamC[i]=StreamC[i]; - InputStrDialog->Stream [i]=Stream [i]; - InputStrDialog->Format [i]=Format [i]; - InputStrDialog->RcvOpt [i]=RcvOpt [i]; - - /* Paths[0]:serial,[1]:tcp,[2]:file,[3]:ftp */ - for (j=0;j<4;j++) InputStrDialog->Paths[i][j]=Paths[i][j]; - } - for (i=0;i<3;i++) for (j=0;j<3;j++) { - InputStrDialog->CmdEna [i][j]=CmdEna [i][j]; - InputStrDialog->Cmds [i][j]=Cmds [i][j]; - InputStrDialog->CmdEnaTcp[i][j]=CmdEnaTcp[i][j]; - InputStrDialog->CmdsTcp [i][j]=CmdsTcp [i][j]; - } - for (i=0;i<10;i++) { - InputStrDialog->History [i]=History [i]; - } - InputStrDialog->NmeaReq =NmeaReq; - InputStrDialog->TimeTag =InTimeTag; - InputStrDialog->TimeSpeed =InTimeSpeed; - InputStrDialog->TimeStart =InTimeStart; - InputStrDialog->Time64Bit =InTime64Bit; - InputStrDialog->NmeaPos[0]=NmeaPos[0]; - InputStrDialog->NmeaPos[1]=NmeaPos[1]; - InputStrDialog->NmeaPos[2]=NmeaPos[2]; - InputStrDialog->ResetCmd =ResetCmd; - InputStrDialog->MaxBL =MaxBL; - - if (InputStrDialog->ShowModal()!=mrOk) return; - - for (i=0;i<3;i++) { - StreamC[i]=InputStrDialog->StreamC[i]; - Stream [i]=InputStrDialog->Stream[i]; - Format [i]=InputStrDialog->Format[i]; - RcvOpt [i]=InputStrDialog->RcvOpt[i]; - for (j=0;j<4;j++) Paths[i][j]=InputStrDialog->Paths[i][j]; - } - for (i=0;i<3;i++) for (j=0;j<3;j++) { - CmdEna [i][j]=InputStrDialog->CmdEna [i][j]; - Cmds [i][j]=InputStrDialog->Cmds [i][j]; - CmdEnaTcp[i][j]=InputStrDialog->CmdEnaTcp[i][j]; - CmdsTcp [i][j]=InputStrDialog->CmdsTcp [i][j]; - } - for (i=0;i<10;i++) { - History [i]=InputStrDialog->History [i]; - } - NmeaReq=InputStrDialog->NmeaReq; - InTimeTag =InputStrDialog->TimeTag; - InTimeSpeed=InputStrDialog->TimeSpeed; - InTimeStart=InputStrDialog->TimeStart; - InTime64Bit=InputStrDialog->Time64Bit; - NmeaPos[0] =InputStrDialog->NmeaPos[0]; - NmeaPos[1] =InputStrDialog->NmeaPos[1]; - NmeaPos[2] =InputStrDialog->NmeaPos[2]; - ResetCmd =InputStrDialog->ResetCmd; - MaxBL =InputStrDialog->MaxBL; +void __fastcall TMainForm::BtnInputStrClick(TObject *Sender) { + int i, j; + + trace(3, "BtnInputStrClick\n"); + + for (i = 0; i < 3; i++) { + InputStrDialog->StreamC[i] = StreamC[i]; + InputStrDialog->Stream[i] = Stream[i]; + InputStrDialog->Format[i] = Format[i]; + InputStrDialog->RcvOpt[i] = RcvOpt[i]; + + /* Paths[0]:serial,[1]:tcp,[2]:file,[3]:ftp */ + for (j = 0; j < 4; j++) InputStrDialog->Paths[i][j] = Paths[i][j]; + } + for (i = 0; i < 3; i++) + for (j = 0; j < 3; j++) { + InputStrDialog->CmdEna[i][j] = CmdEna[i][j]; + InputStrDialog->Cmds[i][j] = Cmds[i][j]; + InputStrDialog->CmdEnaTcp[i][j] = CmdEnaTcp[i][j]; + InputStrDialog->CmdsTcp[i][j] = CmdsTcp[i][j]; + } + for (i = 0; i < 10; i++) { + InputStrDialog->History[i] = History[i]; + } + InputStrDialog->NmeaReq = NmeaReq; + InputStrDialog->TimeTag = InTimeTag; + InputStrDialog->TimeSpeed = InTimeSpeed; + InputStrDialog->TimeStart = InTimeStart; + InputStrDialog->Time64Bit = InTime64Bit; + InputStrDialog->NmeaPos[0] = NmeaPos[0]; + InputStrDialog->NmeaPos[1] = NmeaPos[1]; + InputStrDialog->NmeaPos[2] = NmeaPos[2]; + InputStrDialog->ResetCmd = ResetCmd; + InputStrDialog->MaxBL = MaxBL; + + if (InputStrDialog->ShowModal() != mrOk) return; + + for (i = 0; i < 3; i++) { + StreamC[i] = InputStrDialog->StreamC[i]; + Stream[i] = InputStrDialog->Stream[i]; + Format[i] = InputStrDialog->Format[i]; + RcvOpt[i] = InputStrDialog->RcvOpt[i]; + for (j = 0; j < 4; j++) Paths[i][j] = InputStrDialog->Paths[i][j]; + } + for (i = 0; i < 3; i++) + for (j = 0; j < 3; j++) { + CmdEna[i][j] = InputStrDialog->CmdEna[i][j]; + Cmds[i][j] = InputStrDialog->Cmds[i][j]; + CmdEnaTcp[i][j] = InputStrDialog->CmdEnaTcp[i][j]; + CmdsTcp[i][j] = InputStrDialog->CmdsTcp[i][j]; + } + for (i = 0; i < 10; i++) { + History[i] = InputStrDialog->History[i]; + } + NmeaReq = InputStrDialog->NmeaReq; + InTimeTag = InputStrDialog->TimeTag; + InTimeSpeed = InputStrDialog->TimeSpeed; + InTimeStart = InputStrDialog->TimeStart; + InTime64Bit = InputStrDialog->Time64Bit; + NmeaPos[0] = InputStrDialog->NmeaPos[0]; + NmeaPos[1] = InputStrDialog->NmeaPos[1]; + NmeaPos[2] = InputStrDialog->NmeaPos[2]; + ResetCmd = InputStrDialog->ResetCmd; + MaxBL = InputStrDialog->MaxBL; } // confirm overwrite -------------------------------------------------------- -int __fastcall TMainForm::ConfOverwrite(const char *path) -{ - AnsiString s; - FILE *fp; - int itype[]={ - STR_SERIAL,STR_TCPCLI,STR_TCPSVR,STR_NTRIPCLI,STR_FILE,STR_FTP,STR_HTTP - }; - int i; - char buff1[1024],buff2[1024],*p; - - trace(3,"ConfOverwrite\n"); - - strcpy(buff1,path); - - if ((p=strstr(buff1,"::"))) *p='\0'; - - if (!(fp=fopen(buff1,"r"))) return 1; // file not exists - fclose(fp); - - // check overwrite input files - for (i=0;i<3;i++) { - if (!StreamC[i]||itype[Stream[i]]!=STR_FILE) continue; - - strcpy(buff2,Paths[i][2].c_str()); - if ((p=strstr(buff2,"::"))) *p='\0'; - - if (!strcmp(buff1,buff2)) { - Message->Caption=s.sprintf("invalid output %s",buff1); - Message->Hint=Message->Caption; - return 0; - } +int __fastcall TMainForm::ConfOverwrite(const char *path) { + AnsiString s; + FILE *fp; + int itype[] = {STR_SERIAL, STR_TCPCLI, STR_TCPSVR, STR_NTRIPCLI, STR_FILE, STR_FTP, STR_HTTP}; + int i; + char buff1[1024], buff2[1024], *p; + + trace(3, "ConfOverwrite\n"); + + strcpy(buff1, path); + + if ((p = strstr(buff1, "::"))) *p = '\0'; + + if (!(fp = fopen(buff1, "r"))) return 1; // file not exists + fclose(fp); + + // check overwrite input files + for (i = 0; i < 3; i++) { + if (!StreamC[i] || itype[Stream[i]] != STR_FILE) continue; + + strcpy(buff2, Paths[i][2].c_str()); + if ((p = strstr(buff2, "::"))) *p = '\0'; + + if (!strcmp(buff1, buff2)) { + Message->Caption = s.sprintf("invalid output %s", buff1); + Message->Hint = Message->Caption; + return 0; } - ConfDialog->Label2->Caption=buff1; - - return ConfDialog->ShowModal()==mrOk; + } + ConfDialog->Label2->Caption = buff1; + + return ConfDialog->ShowModal() == mrOk; } // callback on button-output-streams ---------------------------------------- -void __fastcall TMainForm::BtnOutputStrClick(TObject *Sender) -{ - int otype[]={ - STR_SERIAL,STR_TCPCLI,STR_TCPSVR,STR_NTRIPSVR,STR_NTRIPCAS,STR_FILE - }; - int i,j,str,update[2]={0}; - char *path; - - trace(3,"BtnOutputStrClick\n"); - - for (i=3;i<5;i++) { - OutputStrDialog->StreamC[i-3]=StreamC[i]; - OutputStrDialog->Stream [i-3]=Stream[i]; - OutputStrDialog->Format [i-3]=Format[i]; - for (j=0;j<4;j++) OutputStrDialog->Paths[i-3][j]=Paths[i][j]; - } - for (i=0;i<10;i++) { - OutputStrDialog->History [i]=History [i]; - } - OutputStrDialog->OutTimeTag=OutTimeTag; - OutputStrDialog->OutAppend =OutAppend; - OutputStrDialog->SwapInterval=OutSwapInterval; - - if (OutputStrDialog->ShowModal()!=mrOk) return; - - for (i=3;i<5;i++) { - if (StreamC[i]!=OutputStrDialog->StreamC[i-3]|| - Stream [i]!=OutputStrDialog->Stream[i-3]|| - Format [i]!=OutputStrDialog->Format[i-3]|| - Paths[i][0]!=OutputStrDialog->Paths[i-3][0]|| - Paths[i][1]!=OutputStrDialog->Paths[i-3][1]|| - Paths[i][2]!=OutputStrDialog->Paths[i-3][2]|| - Paths[i][3]!=OutputStrDialog->Paths[i-3][3]) update[i-3]=1; - StreamC[i]=OutputStrDialog->StreamC[i-3]; - Stream [i]=OutputStrDialog->Stream[i-3]; - Format [i]=OutputStrDialog->Format[i-3]; - for (j=0;j<4;j++) Paths[i][j]=OutputStrDialog->Paths[i-3][j]; - } - for (i=0;i<10;i++) { - History [i]=OutputStrDialog->History [i]; - } - OutTimeTag=OutputStrDialog->OutTimeTag; - OutAppend =OutputStrDialog->OutAppend; - OutSwapInterval=OutputStrDialog->SwapInterval; - - if (BtnStart->Enabled) return; - - for (i=3;i<5;i++) { - if (!update[i-3]) continue; - - rtksvrclosestr(&rtksvr,i); - - if (!StreamC[i]) continue; - - str=otype[Stream[i]]; - if (str==STR_SERIAL) path=Paths[i][0].c_str(); - else if (str==STR_FILE ) path=Paths[i][2].c_str(); - else if (str==STR_FTP||str==STR_HTTP) path=Paths[i][3].c_str(); - else path=Paths[i][1].c_str(); - if (str==STR_FILE&&!ConfOverwrite(path)) { - StreamC[i]=0; - continue; - } - SolOpt.posf=Format[i]; - rtksvropenstr(&rtksvr,i,str,path,&SolOpt,&PrcOpt); - } +void __fastcall TMainForm::BtnOutputStrClick(TObject *Sender) { + int otype[] = {STR_SERIAL, STR_TCPCLI, STR_TCPSVR, STR_NTRIPSVR, STR_NTRIPCAS, STR_FILE}; + int i, j, str, update[2] = {0}; + char *path; + + trace(3, "BtnOutputStrClick\n"); + + for (i = 3; i < 5; i++) { + OutputStrDialog->StreamC[i - 3] = StreamC[i]; + OutputStrDialog->Stream[i - 3] = Stream[i]; + OutputStrDialog->Format[i - 3] = Format[i]; + for (j = 0; j < 4; j++) OutputStrDialog->Paths[i - 3][j] = Paths[i][j]; + } + for (i = 0; i < 10; i++) { + OutputStrDialog->History[i] = History[i]; + } + OutputStrDialog->OutTimeTag = OutTimeTag; + OutputStrDialog->OutAppend = OutAppend; + OutputStrDialog->SwapInterval = OutSwapInterval; + + if (OutputStrDialog->ShowModal() != mrOk) return; + + for (i = 3; i < 5; i++) { + if (StreamC[i] != OutputStrDialog->StreamC[i - 3] || + Stream[i] != OutputStrDialog->Stream[i - 3] || + Format[i] != OutputStrDialog->Format[i - 3] || + Paths[i][0] != OutputStrDialog->Paths[i - 3][0] || + Paths[i][1] != OutputStrDialog->Paths[i - 3][1] || + Paths[i][2] != OutputStrDialog->Paths[i - 3][2] || + Paths[i][3] != OutputStrDialog->Paths[i - 3][3]) + update[i - 3] = 1; + StreamC[i] = OutputStrDialog->StreamC[i - 3]; + Stream[i] = OutputStrDialog->Stream[i - 3]; + Format[i] = OutputStrDialog->Format[i - 3]; + for (j = 0; j < 4; j++) Paths[i][j] = OutputStrDialog->Paths[i - 3][j]; + } + for (i = 0; i < 10; i++) { + History[i] = OutputStrDialog->History[i]; + } + OutTimeTag = OutputStrDialog->OutTimeTag; + OutAppend = OutputStrDialog->OutAppend; + OutSwapInterval = OutputStrDialog->SwapInterval; + + if (BtnStart->Enabled) return; + + for (i = 3; i < 5; i++) { + if (!update[i - 3]) continue; + + rtksvrclosestr(&rtksvr, i); + + if (!StreamC[i]) continue; + + str = otype[Stream[i]]; + if (str == STR_SERIAL) + path = Paths[i][0].c_str(); + else if (str == STR_FILE) + path = Paths[i][2].c_str(); + else if (str == STR_FTP || str == STR_HTTP) + path = Paths[i][3].c_str(); + else + path = Paths[i][1].c_str(); + if (str == STR_FILE && !ConfOverwrite(path)) { + StreamC[i] = 0; + continue; + } + SolOpt.posf = Format[i]; + rtksvropenstr(&rtksvr, i, str, path, &SolOpt, &PrcOpt); + } } // callback on button-log-streams ------------------------------------------- -void __fastcall TMainForm::BtnLogStrClick(TObject *Sender) -{ - int otype[]={ - STR_SERIAL,STR_TCPCLI,STR_TCPSVR,STR_NTRIPSVR,STR_NTRIPCAS,STR_FILE - }; - int i,j,str,update[3]={0}; - char *path; - - trace(3,"BtnLogStrClick\n"); - - for (i=5;i<8;i++) { - LogStrDialog->StreamC[i-5]=StreamC[i]; - LogStrDialog->Stream [i-5]=Stream [i]; - for (j=0;j<4;j++) LogStrDialog->Paths[i-5][j]=Paths[i][j]; - } - for (i=0;i<10;i++) { - LogStrDialog->History [i]=History [i]; - } - LogStrDialog->LogTimeTag=LogTimeTag; - LogStrDialog->LogAppend =LogAppend; - LogStrDialog->SwapInterval=LogSwapInterval; - - if (LogStrDialog->ShowModal()!=mrOk) return; - - for (i=5;i<8;i++) { - if (StreamC[i]!=OutputStrDialog->StreamC[i-5]|| - Stream [i]!=OutputStrDialog->Stream[i-5]|| - Paths[i][0]!=OutputStrDialog->Paths[i-3][0]|| - Paths[i][1]!=OutputStrDialog->Paths[i-3][1]|| - Paths[i][2]!=OutputStrDialog->Paths[i-3][2]|| - Paths[i][3]!=OutputStrDialog->Paths[i-3][3]) update[i-5]=1; - StreamC[i]=LogStrDialog->StreamC[i-5]; - Stream [i]=LogStrDialog->Stream [i-5]; - for (j=0;j<4;j++) Paths[i][j]=LogStrDialog->Paths[i-5][j]; - } - for (i=0;i<10;i++) { - History [i]=LogStrDialog->History [i]; - } - LogTimeTag=LogStrDialog->LogTimeTag; - LogAppend =LogStrDialog->LogAppend; - LogSwapInterval=LogStrDialog->SwapInterval; - - if (BtnStart->Enabled) return; - - for (i=5;i<8;i++) { - if (!update[i-5]) continue; - - rtksvrclosestr(&rtksvr,i); - - if (!StreamC[i]) continue; - - str=otype[Stream[i]]; - if (str==STR_SERIAL) path=Paths[i][0].c_str(); - else if (str==STR_FILE ) path=Paths[i][2].c_str(); - else if (str==STR_FTP||str==STR_HTTP) path=Paths[i][3].c_str(); - else path=Paths[i][1].c_str(); - if (str==STR_FILE&&!ConfOverwrite(path)) { - StreamC[i]=0; - continue; - } - rtksvropenstr(&rtksvr,i,str,path,&SolOpt,&PrcOpt); - } +void __fastcall TMainForm::BtnLogStrClick(TObject *Sender) { + int otype[] = {STR_SERIAL, STR_TCPCLI, STR_TCPSVR, STR_NTRIPSVR, STR_NTRIPCAS, STR_FILE}; + int i, j, str, update[3] = {0}; + char *path; + + trace(3, "BtnLogStrClick\n"); + + for (i = 5; i < 8; i++) { + LogStrDialog->StreamC[i - 5] = StreamC[i]; + LogStrDialog->Stream[i - 5] = Stream[i]; + for (j = 0; j < 4; j++) LogStrDialog->Paths[i - 5][j] = Paths[i][j]; + } + for (i = 0; i < 10; i++) { + LogStrDialog->History[i] = History[i]; + } + LogStrDialog->LogTimeTag = LogTimeTag; + LogStrDialog->LogAppend = LogAppend; + LogStrDialog->SwapInterval = LogSwapInterval; + + if (LogStrDialog->ShowModal() != mrOk) return; + + for (i = 5; i < 8; i++) { + if (StreamC[i] != OutputStrDialog->StreamC[i - 5] || + Stream[i] != OutputStrDialog->Stream[i - 5] || + Paths[i][0] != OutputStrDialog->Paths[i - 3][0] || + Paths[i][1] != OutputStrDialog->Paths[i - 3][1] || + Paths[i][2] != OutputStrDialog->Paths[i - 3][2] || + Paths[i][3] != OutputStrDialog->Paths[i - 3][3]) + update[i - 5] = 1; + StreamC[i] = LogStrDialog->StreamC[i - 5]; + Stream[i] = LogStrDialog->Stream[i - 5]; + for (j = 0; j < 4; j++) Paths[i][j] = LogStrDialog->Paths[i - 5][j]; + } + for (i = 0; i < 10; i++) { + History[i] = LogStrDialog->History[i]; + } + LogTimeTag = LogStrDialog->LogTimeTag; + LogAppend = LogStrDialog->LogAppend; + LogSwapInterval = LogStrDialog->SwapInterval; + + if (BtnStart->Enabled) return; + + for (i = 5; i < 8; i++) { + if (!update[i - 5]) continue; + + rtksvrclosestr(&rtksvr, i); + + if (!StreamC[i]) continue; + + str = otype[Stream[i]]; + if (str == STR_SERIAL) + path = Paths[i][0].c_str(); + else if (str == STR_FILE) + path = Paths[i][2].c_str(); + else if (str == STR_FTP || str == STR_HTTP) + path = Paths[i][3].c_str(); + else + path = Paths[i][1].c_str(); + if (str == STR_FILE && !ConfOverwrite(path)) { + StreamC[i] = 0; + continue; + } + rtksvropenstr(&rtksvr, i, str, path, &SolOpt, &PrcOpt); + } } // callback on button-solution-show ----------------------------------------- -void __fastcall TMainForm::BtnPanelClick(TObject *Sender) -{ - trace(3,"BtnPanelClick\n"); - - if (++PanelMode>MAXPANELMODE) PanelMode=0; - UpdatePanel(); +void __fastcall TMainForm::BtnPanelClick(TObject *Sender) { + trace(3, "BtnPanelClick\n"); + + if (++PanelMode > MAXPANELMODE) PanelMode = 0; + UpdatePanel(); } // callback on button-plot-type-1 ------------------------------------------- -void __fastcall TMainForm::BtnTimeSysClick(TObject *Sender) -{ - trace(3,"BtnTimeSysClick\n"); - - if (++TimeSys>3) TimeSys=0; - UpdateTimeSys(); +void __fastcall TMainForm::BtnTimeSysClick(TObject *Sender) { + trace(3, "BtnTimeSysClick\n"); + + if (++TimeSys > 3) TimeSys = 0; + UpdateTimeSys(); } // callback on button-solution-type ----------------------------------------- -void __fastcall TMainForm::BtnSolTypeClick(TObject *Sender) -{ - trace(3,"BtnSolTypeClick\n"); - - if (++SolType>4) SolType=0; - UpdateSolType(); +void __fastcall TMainForm::BtnSolTypeClick(TObject *Sender) { + trace(3, "BtnSolTypeClick\n"); + + if (++SolType > 4) SolType = 0; + UpdateSolType(); } // callback on button-plottype-1 -------------------------------------------- -void __fastcall TMainForm::BtnPlotType1Click(TObject *Sender) -{ - trace(3,"BtnPlotType1Click\n"); - - if (++PlotType1>6) PlotType1=0; - UpdatePlot(); - UpdatePos(); - UpdateEnable(); +void __fastcall TMainForm::BtnPlotType1Click(TObject *Sender) { + trace(3, "BtnPlotType1Click\n"); + + if (++PlotType1 > 6) PlotType1 = 0; + UpdatePlot(); + UpdatePos(); + UpdateEnable(); } // callback on button-plottype-2 -------------------------------------------- -void __fastcall TMainForm::BtnPlotType2Click(TObject *Sender) -{ - trace(3,"BtnPlotType2Click\n"); - - if (++PlotType2>6) PlotType2=0; - UpdatePlot(); - UpdatePos(); - UpdateEnable(); +void __fastcall TMainForm::BtnPlotType2Click(TObject *Sender) { + trace(3, "BtnPlotType2Click\n"); + + if (++PlotType2 > 6) PlotType2 = 0; + UpdatePlot(); + UpdatePos(); + UpdateEnable(); } //--------------------------------------------------------------------------- -void __fastcall TMainForm::BtnPlotType3Click(TObject *Sender) -{ - trace(3,"BtnPlotType3Click\n"); - - if (++PlotType3>6) PlotType3=0; - UpdatePlot(); - UpdatePos(); - UpdateEnable(); +void __fastcall TMainForm::BtnPlotType3Click(TObject *Sender) { + trace(3, "BtnPlotType3Click\n"); + + if (++PlotType3 > 6) PlotType3 = 0; + UpdatePlot(); + UpdatePos(); + UpdateEnable(); } //--------------------------------------------------------------------------- -void __fastcall TMainForm::BtnPlotType4Click(TObject *Sender) -{ - trace(3,"BtnPlotType4Click\n"); - - if (++PlotType4>6) PlotType4=0; - UpdatePlot(); - UpdatePos(); - UpdateEnable(); +void __fastcall TMainForm::BtnPlotType4Click(TObject *Sender) { + trace(3, "BtnPlotType4Click\n"); + + if (++PlotType4 > 6) PlotType4 = 0; + UpdatePlot(); + UpdatePos(); + UpdateEnable(); } // callback on button frequency-type-1 -------------------------------------- -void __fastcall TMainForm::BtnFreqType1Click(TObject *Sender) -{ - trace(3,"BtnFreqType1Click\n"); - - if (PlotType1==6) { - if (++TrkType1>1) TrkType1=0; - UpdatePlot(); - } - else if (PlotType1==5) { - if (++BLMode1>1) BLMode1=0; - UpdatePlot(); - } - else { - if (++FreqType1>NFREQ+1) FreqType1=0; - UpdateSolType(); - } +void __fastcall TMainForm::BtnFreqType1Click(TObject *Sender) { + trace(3, "BtnFreqType1Click\n"); + + if (PlotType1 == 6) { + if (++TrkType1 > 1) TrkType1 = 0; + UpdatePlot(); + } else if (PlotType1 == 5) { + if (++BLMode1 > 1) BLMode1 = 0; + UpdatePlot(); + } else { + if (++FreqType1 > NFREQ + 1) FreqType1 = 0; + UpdateSolType(); + } } // callback on button frequency-type-2 -------------------------------------- -void __fastcall TMainForm::BtnFreqType2Click(TObject *Sender) -{ - trace(3,"BtnFreqType2Click\n"); - - if (PlotType2==6) { - if (++TrkType2>1) TrkType2=0; - UpdatePlot(); - } - else if (PlotType2==5) { - if (++BLMode2>1) BLMode2=0; - UpdatePlot(); - } - else { - if (++FreqType2>NFREQ+1) FreqType2=0; - UpdateSolType(); - } +void __fastcall TMainForm::BtnFreqType2Click(TObject *Sender) { + trace(3, "BtnFreqType2Click\n"); + + if (PlotType2 == 6) { + if (++TrkType2 > 1) TrkType2 = 0; + UpdatePlot(); + } else if (PlotType2 == 5) { + if (++BLMode2 > 1) BLMode2 = 0; + UpdatePlot(); + } else { + if (++FreqType2 > NFREQ + 1) FreqType2 = 0; + UpdateSolType(); + } } //--------------------------------------------------------------------------- -void __fastcall TMainForm::BtnFreqType3Click(TObject *Sender) -{ - trace(3,"BtnFreqType3Click\n"); - - if (PlotType3==6) { - if (++TrkType3>1) TrkType3=0; - UpdatePlot(); - } - else if (PlotType3==5) { - if (++BLMode3>1) BLMode3=0; - UpdatePlot(); - } - else { - if (++FreqType3>NFREQ+1) FreqType3=0; - UpdateSolType(); - } +void __fastcall TMainForm::BtnFreqType3Click(TObject *Sender) { + trace(3, "BtnFreqType3Click\n"); + + if (PlotType3 == 6) { + if (++TrkType3 > 1) TrkType3 = 0; + UpdatePlot(); + } else if (PlotType3 == 5) { + if (++BLMode3 > 1) BLMode3 = 0; + UpdatePlot(); + } else { + if (++FreqType3 > NFREQ + 1) FreqType3 = 0; + UpdateSolType(); + } } //--------------------------------------------------------------------------- -void __fastcall TMainForm::BtnFreqType4Click(TObject *Sender) -{ - trace(3,"BtnFreqType4Click\n"); - - if (PlotType4==6) { - if (++TrkType4>1) TrkType4=0; - UpdatePlot(); - } - else if (PlotType4==5) { - if (++BLMode4>1) BLMode4=0; - UpdatePlot(); - } - else { - if (++FreqType4>NFREQ+1) FreqType4=0; - UpdateSolType(); - } +void __fastcall TMainForm::BtnFreqType4Click(TObject *Sender) { + trace(3, "BtnFreqType4Click\n"); + + if (PlotType4 == 6) { + if (++TrkType4 > 1) TrkType4 = 0; + UpdatePlot(); + } else if (PlotType4 == 5) { + if (++BLMode4 > 1) BLMode4 = 0; + UpdatePlot(); + } else { + if (++FreqType4 > NFREQ + 1) FreqType4 = 0; + UpdateSolType(); + } } // callback on button expand-1 ---------------------------------------------- -void __fastcall TMainForm::BtnExpand1Click(TObject *Sender) -{ - if (TrkScale1<=0) return; - TrkScale1--; - UpdatePlot(); +void __fastcall TMainForm::BtnExpand1Click(TObject *Sender) { + if (TrkScale1 <= 0) return; + TrkScale1--; + UpdatePlot(); } // callback on button shrink-1 ---------------------------------------------- -void __fastcall TMainForm::BtnShrink1Click(TObject *Sender) -{ - if (TrkScale1>=MAXTRKSCALE) return; - TrkScale1++; - UpdatePlot(); +void __fastcall TMainForm::BtnShrink1Click(TObject *Sender) { + if (TrkScale1 >= MAXTRKSCALE) return; + TrkScale1++; + UpdatePlot(); } // callback on button expand-2 ---------------------------------------------- -void __fastcall TMainForm::BtnExpand2Click(TObject *Sender) -{ - if (TrkScale2<=0) return; - TrkScale2--; - UpdatePlot(); +void __fastcall TMainForm::BtnExpand2Click(TObject *Sender) { + if (TrkScale2 <= 0) return; + TrkScale2--; + UpdatePlot(); } // callback on button shrink-2 ---------------------------------------------- -void __fastcall TMainForm::BtnShrink2Click(TObject *Sender) -{ - if (TrkScale2>=MAXTRKSCALE) return; - TrkScale2++; - UpdatePlot(); +void __fastcall TMainForm::BtnShrink2Click(TObject *Sender) { + if (TrkScale2 >= MAXTRKSCALE) return; + TrkScale2++; + UpdatePlot(); } // callback on button-rtk-monitor ------------------------------------------- -void __fastcall TMainForm::BtnMonitorClick(TObject *Sender) -{ - TMonitorDialog *monitor=new TMonitorDialog(Application); - - trace(3,"BtnMonitorClick\n"); - - monitor->Caption=Caption+": RTK Monitor"; - monitor->Show(); +void __fastcall TMainForm::BtnMonitorClick(TObject *Sender) { + TMonitorDialog *monitor = new TMonitorDialog(Application); + + trace(3, "BtnMonitorClick\n"); + + monitor->Caption = Caption + ": RTK Monitor"; + monitor->Show(); } // callback on scroll-solution change --------------------------------------- -void __fastcall TMainForm::ScbSolChange(TObject *Sender) -{ - trace(3,"ScbSolChange\n"); - - PSol=PSolS+ScbSol->Position; - if (PSol>=SolBuffSize) PSol-=SolBuffSize; - UpdateTime(); - UpdatePos(); - UpdatePlot(); +void __fastcall TMainForm::ScbSolChange(TObject *Sender) { + trace(3, "ScbSolChange\n"); + + PSol = PSolS + ScbSol->Position; + if (PSol >= SolBuffSize) PSol -= SolBuffSize; + UpdateTime(); + UpdatePos(); + UpdatePlot(); } // callback on button-save -------------------------------------------------- -void __fastcall TMainForm::BtnSaveClick(TObject *Sender) -{ - trace(3,"BtnSaveClick\n"); - - SaveLog(); +void __fastcall TMainForm::BtnSaveClick(TObject *Sender) { + trace(3, "BtnSaveClick\n"); + + SaveLog(); } // callback on button-about ------------------------------------------------- -void __fastcall TMainForm::BtnAboutClick(TObject *Sender) -{ - AnsiString prog=PRGNAME; - - trace(3,"BtnAboutClick\n"); - - AboutDialog->About=prog; - AboutDialog->IconIndex=5; - AboutDialog->ShowModal(); +void __fastcall TMainForm::BtnAboutClick(TObject *Sender) { + AnsiString prog = PRGNAME; + + trace(3, "BtnAboutClick\n"); + + AboutDialog->About = prog; + AboutDialog->IconIndex = 5; + AboutDialog->ShowModal(); } // callback on button-tasktray ---------------------------------------------- -void __fastcall TMainForm::BtnTaskTrayClick(TObject *Sender) -{ - trace(3,"BtnTaskTrayClick\n"); - - Visible=false; - TrayIcon->Hint=Caption; - TrayIcon->Visible=true; +void __fastcall TMainForm::BtnTaskTrayClick(TObject *Sender) { + trace(3, "BtnTaskTrayClick\n"); + + Visible = false; + TrayIcon->Hint = Caption; + TrayIcon->Visible = true; } // callback on button-tasktray ---------------------------------------------- -void __fastcall TMainForm::TrayIconDblClick(TObject *Sender) -{ - trace(3,"TaskIconDblClick\n"); - - Visible=true; - TrayIcon->Visible=false; +void __fastcall TMainForm::TrayIconDblClick(TObject *Sender) { + trace(3, "TaskIconDblClick\n"); + + Visible = true; + TrayIcon->Visible = false; } // callback on menu-expand -------------------------------------------------- -void __fastcall TMainForm::MenuExpandClick(TObject *Sender) -{ - trace(3,"MenuExpandClick\n"); - - Visible=true; - TrayIcon->Visible=false; +void __fastcall TMainForm::MenuExpandClick(TObject *Sender) { + trace(3, "MenuExpandClick\n"); + + Visible = true; + TrayIcon->Visible = false; } // callback on menu-start --------------------------------------------------- -void __fastcall TMainForm::MenuStartClick(TObject *Sender) -{ - trace(3,"MenuStartClick\n"); - - BtnStartClick(Sender); +void __fastcall TMainForm::MenuStartClick(TObject *Sender) { + trace(3, "MenuStartClick\n"); + + BtnStartClick(Sender); } // callback on menu-stop ---------------------------------------------------- -void __fastcall TMainForm::MenuStopClick(TObject *Sender) -{ - trace(3,"MenuStopClick\n"); - - BtnStopClick(Sender); +void __fastcall TMainForm::MenuStopClick(TObject *Sender) { + trace(3, "MenuStopClick\n"); + + BtnStopClick(Sender); } // callback on menu-monitor ------------------------------------------------- -void __fastcall TMainForm::MenuMonitorClick(TObject *Sender) -{ - trace(3,"MenuMonitorClick\n"); - - BtnMonitorClick(Sender); +void __fastcall TMainForm::MenuMonitorClick(TObject *Sender) { + trace(3, "MenuMonitorClick\n"); + + BtnMonitorClick(Sender); } // callback on menu-plot ---------------------------------------------------- -void __fastcall TMainForm::MenuPlotClick(TObject *Sender) -{ - trace(3,"MenuPlotClick\n"); - - BtnPlotClick(Sender); +void __fastcall TMainForm::MenuPlotClick(TObject *Sender) { + trace(3, "MenuPlotClick\n"); + + BtnPlotClick(Sender); } // callback on menu-exit ---------------------------------------------------- -void __fastcall TMainForm::MenuExitClick(TObject *Sender) -{ - trace(3,"MenuExitClick\n"); - - BtnExitClick(Sender); +void __fastcall TMainForm::MenuExitClick(TObject *Sender) { + trace(3, "MenuExitClick\n"); + + BtnExitClick(Sender); } // start rtk server --------------------------------------------------------- -void __fastcall TMainForm::SvrStart(void) -{ - AnsiString s; - solopt_t solopt[2]; - double pos[3],nmeapos[3]; - int itype[]={ - STR_SERIAL,STR_TCPCLI,STR_TCPSVR,STR_NTRIPCLI,STR_FILE,STR_FTP,STR_HTTP - }; - int otype[]={ - STR_SERIAL,STR_TCPCLI,STR_TCPSVR,STR_NTRIPSVR,STR_NTRIPCAS,STR_FILE - }; - int i,strs[MAXSTRRTK]={0},sat,ex,stropt[8]={0}; - char *paths[8],*cmds[3]={0},*cmds_periodic[3]={0},*rcvopts[3]={0}; - char buff[1024],*p; - char file[1024],*type,errmsg[20148]; - FILE *fp; - gtime_t time=timeget(); - pcvs_t pcvs={0}; - pcv_t pcv0={0}; - - trace(3,"SvrStart\n"); - - Message->Caption=""; Message->Hint=""; - - if (SolOpt.trace>0) { - traceopen(TRACEFILE); - tracelevel(SolOpt.trace); - } - if (RovPosTypeF<=2) { // LLH,XYZ - PrcOpt.rovpos = RovPosTypeF < 2 ? POSOPT_POS_LLH : POSOPT_POS_XYZ; - PrcOpt.ru[0]=RovPos[0]; - PrcOpt.ru[1]=RovPos[1]; - PrcOpt.ru[2]=RovPos[2]; - } - else { // RTCM position - PrcOpt.rovpos=POSOPT_RTCM; - for (i=0;i<3;i++) PrcOpt.ru[i]=0.0; - } - if (RefPosTypeF<=2) { // LLH,XYZ - PrcOpt.refpos = RefPosTypeF < 2 ? POSOPT_POS_LLH : POSOPT_POS_XYZ; - PrcOpt.rb[0]=RefPos[0]; - PrcOpt.rb[1]=RefPos[1]; - PrcOpt.rb[2]=RefPos[2]; - } - else if (RefPosTypeF==3) { // RTCM/Raw position - PrcOpt.refpos=POSOPT_RTCM; - for (i=0;i<3;i++) PrcOpt.rb[i]=0.0; - } - else { // average of single position - PrcOpt.refpos=POSOPT_SINGLE; - for (i=0;i<3;i++) PrcOpt.rb[i]=0.0; - } - for (i=0;i0) traceclose(); - Message->Caption=s.sprintf("rcv ant file read error %s",AntPcvFileF.c_str()); - Message->Hint=Message->Caption; - return; - } - PrcOpt.pcvr[0]=PrcOpt.pcvr[1]=pcv0; // initialize antenna PCV - - for (i=0;i<3;i++) PrcOpt.antdel[0][i]=RovAntDel[i]; - if (RovAntPcvF) strcpy(PrcOpt.anttype[0], RovAntF.c_str()); - if (RovAntPcvF && RovAntF != "" && RovAntF != "*") { - type=RovAntF.c_str(); - pcv_t *pcv=searchpcv(0,type,time,&rtksvr.pcvsr); - if (pcv) { - PrcOpt.pcvr[0]=*pcv; - } - else { - Message->Caption=s.sprintf("no antenna pcv %s",type); - Message->Hint=Message->Caption; - } - } +void __fastcall TMainForm::SvrStart(void) { + AnsiString s; + solopt_t solopt[2]; + double pos[3], nmeapos[3]; + int itype[] = {STR_SERIAL, STR_TCPCLI, STR_TCPSVR, STR_NTRIPCLI, STR_FILE, STR_FTP, STR_HTTP}; + int otype[] = {STR_SERIAL, STR_TCPCLI, STR_TCPSVR, STR_NTRIPSVR, STR_NTRIPCAS, STR_FILE}; + int i, strs[MAXSTRRTK] = {0}, sat, ex, stropt[8] = {0}; + char *paths[8], *cmds[3] = {0}, *cmds_periodic[3] = {0}, *rcvopts[3] = {0}; + char buff[1024], *p; + char file[1024], *type, errmsg[20148]; + FILE *fp; + gtime_t time = timeget(); + pcvs_t pcvs = {0}; + pcv_t pcv0 = {0}; - for (i=0;i<3;i++) PrcOpt.antdel[1][i]=RefAntDel[i]; - if (RefAntPcvF) strcpy(PrcOpt.anttype[1], RefAntF.c_str()); - if (RefAntPcvF && RefAntF != "" && RefAntF != "*") { - type=RefAntF.c_str(); - pcv_t *pcv=searchpcv(0,type,time,&rtksvr.pcvsr); - if (pcv) { - PrcOpt.pcvr[1]=*pcv; - } - else { - Message->Caption=s.sprintf("no antenna pcv %s",type); - Message->Hint=Message->Caption; - } - } + trace(3, "SvrStart\n"); - if (PrcOpt.sateph==EPHOPT_PREC||PrcOpt.sateph==EPHOPT_SSRCOM||PrcOpt.mode>=PMODE_PPP_KINEMA) { - if (SatPcvFileF!=""&&!readpcv(SatPcvFileF.c_str(),&pcvs)) { - if (SolOpt.trace>0) traceclose(); - free_pcvs(&rtksvr.pcvsr); - Message->Caption=s.sprintf("sat ant file read error %s",SatPcvFileF.c_str()); - Message->Hint=Message->Caption; - return; - } - for (i=0;i0) traceclose(); - free_pcvs(&rtksvr.pcvsr); - return; - } - } - if (SolOpt.sstat>0) { - rtkopenstat(STATFILE,SolOpt.sstat); - } - if (SolOpt.geoid>0&&GeoidDataFileF!="") { - opengeoid(SolOpt.geoid,GeoidDataFileF.c_str()); - } - if (DCBFileF!="") { - readdcb(DCBFileF.c_str(),&rtksvr.nav,NULL); - } - for (i=0;i<2;i++) { - solopt[i]=SolOpt; - solopt[i].posf=Format[i+3]; - } - stropt[0]=TimeoutTime; - stropt[1]=ReconTime; - stropt[2]=1000; - stropt[3]=SvrBuffSize; - stropt[4]=FileSwapMargin; - strsetopt(stropt); - strcpy(rtksvr.cmd_reset,ResetCmd.c_str()); - rtksvr.bl_reset=MaxBL; - - // start rtk server - if (!rtksvrstart(&rtksvr,SvrCycle,SvrBuffSize,strs,(const char **)paths,Format, - NavSelect,(const char **)cmds,(const char **)cmds_periodic, - (const char **)rcvopts,NmeaCycle,NmeaReq,nmeapos,&PrcOpt, - solopt,&monistr,errmsg)) { - trace(2,"rtksvrstart error %s\n",errmsg); - if (SolOpt.trace>0) traceclose(); - free_pcvs(&rtksvr.pcvsr); - return; - } - PSol=PSolS=PSolE=0; - SolStat[0]=Nvsat[0]=0; - for (i=0;i<3;i++) SolRov[i]=SolRef[i]=VelRov[i]=0.0; - for (i=0;i<9;i++) Qr[i]=0.0; - Age[0]=Ratio[0]=0.0; - Nsat[0]=Nsat[1]=0; - UpdatePos(); - UpdatePlot(); - BtnStart ->Visible=false; - BtnStart ->Enabled=false; - BtnOpt ->Enabled=false; - BtnExit ->Enabled=false; - BtnInputStr ->Enabled=false; - MenuStart ->Enabled=false; - MenuExit ->Enabled=false; - ScbSol ->Enabled=false; - BtnStop ->Visible=true; - MenuStop ->Enabled=true; - Svr->Color=CLORANGE; - SetTrayIcon(0); + Message->Caption = ""; + Message->Hint = ""; + + if (SolOpt.trace > 0) { + traceopen(TRACEFILE); + tracelevel(SolOpt.trace); + } + if (RovPosTypeF <= 2) { // LLH,XYZ + PrcOpt.rovpos = RovPosTypeF < 2 ? POSOPT_POS_LLH : POSOPT_POS_XYZ; + PrcOpt.ru[0] = RovPos[0]; + PrcOpt.ru[1] = RovPos[1]; + PrcOpt.ru[2] = RovPos[2]; + } else { // RTCM position + PrcOpt.rovpos = POSOPT_RTCM; + for (i = 0; i < 3; i++) PrcOpt.ru[i] = 0.0; + } + if (RefPosTypeF <= 2) { // LLH,XYZ + PrcOpt.refpos = RefPosTypeF < 2 ? POSOPT_POS_LLH : POSOPT_POS_XYZ; + PrcOpt.rb[0] = RefPos[0]; + PrcOpt.rb[1] = RefPos[1]; + PrcOpt.rb[2] = RefPos[2]; + } else if (RefPosTypeF == 3) { // RTCM/Raw position + PrcOpt.refpos = POSOPT_RTCM; + for (i = 0; i < 3; i++) PrcOpt.rb[i] = 0.0; + } else { // average of single position + PrcOpt.refpos = POSOPT_SINGLE; + for (i = 0; i < 3; i++) PrcOpt.rb[i] = 0.0; + } + for (i = 0; i < MAXSAT; i++) { + PrcOpt.exsats[i] = 0; + } + if (ExSats != "") { // excluded satellites + strcpy(buff, ExSats.c_str()); + for (p = strtok(buff, " "); p; p = strtok(NULL, " ")) { + if (*p == '+') { + ex = 2; + p++; + } else + ex = 1; + if (!(sat = satid2no(p))) continue; + PrcOpt.exsats[sat - 1] = ex; + } + } + if ((RovAntPcvF || RefAntPcvF) && AntPcvFileF != "" && + !readpcv(AntPcvFileF.c_str(), &rtksvr.pcvsr)) { + if (SolOpt.trace > 0) traceclose(); + Message->Caption = s.sprintf("rcv ant file read error %s", AntPcvFileF.c_str()); + Message->Hint = Message->Caption; + return; + } + PrcOpt.pcvr[0] = PrcOpt.pcvr[1] = pcv0; // initialize antenna PCV + + for (i = 0; i < 3; i++) PrcOpt.antdel[0][i] = RovAntDel[i]; + if (RovAntPcvF) strcpy(PrcOpt.anttype[0], RovAntF.c_str()); + if (RovAntPcvF && RovAntF != "" && RovAntF != "*") { + type = RovAntF.c_str(); + pcv_t *pcv = searchpcv(0, type, time, &rtksvr.pcvsr); + if (pcv) { + PrcOpt.pcvr[0] = *pcv; + } else { + Message->Caption = s.sprintf("no antenna pcv %s", type); + Message->Hint = Message->Caption; + } + } + + for (i = 0; i < 3; i++) PrcOpt.antdel[1][i] = RefAntDel[i]; + if (RefAntPcvF) strcpy(PrcOpt.anttype[1], RefAntF.c_str()); + if (RefAntPcvF && RefAntF != "" && RefAntF != "*") { + type = RefAntF.c_str(); + pcv_t *pcv = searchpcv(0, type, time, &rtksvr.pcvsr); + if (pcv) { + PrcOpt.pcvr[1] = *pcv; + } else { + Message->Caption = s.sprintf("no antenna pcv %s", type); + Message->Hint = Message->Caption; + } + } + + if (PrcOpt.sateph == EPHOPT_PREC || PrcOpt.sateph == EPHOPT_SSRCOM || + PrcOpt.mode >= PMODE_PPP_KINEMA) { + if (SatPcvFileF != "" && !readpcv(SatPcvFileF.c_str(), &pcvs)) { + if (SolOpt.trace > 0) traceclose(); + free_pcvs(&rtksvr.pcvsr); + Message->Caption = s.sprintf("sat ant file read error %s", SatPcvFileF.c_str()); + Message->Hint = Message->Caption; + return; + } + for (i = 0; i < MAXSAT; i++) { + pcv_t *pcv = searchpcv(i + 1, "", time, &pcvs); + if (!pcv) continue; + rtksvr.nav.pcvs[i] = *pcv; + } + free_pcvs(&pcvs); + } + if (BaselineC) { + PrcOpt.baseline[0] = Baseline[0]; + PrcOpt.baseline[1] = Baseline[1]; + } else { + PrcOpt.baseline[0] = 0.0; + PrcOpt.baseline[1] = 0.0; + } + for (i = 0; i < 3; i++) strs[i] = StreamC[i] ? itype[Stream[i]] : STR_NONE; + for (i = 3; i < 5; i++) strs[i] = StreamC[i] ? otype[Stream[i]] : STR_NONE; + for (i = 5; i < 8; i++) strs[i] = StreamC[i] ? otype[Stream[i]] : STR_NONE; + for (i = 0; i < 8; i++) { + if (strs[i] == STR_NONE) + paths[i] = (char *)""; + else if (strs[i] == STR_SERIAL) + paths[i] = Paths[i][0].c_str(); + else if (strs[i] == STR_FILE) + paths[i] = Paths[i][2].c_str(); + else if (strs[i] == STR_FTP || strs[i] == STR_HTTP) + paths[i] = Paths[i][3].c_str(); + else + paths[i] = Paths[i][1].c_str(); + } + for (i = 0; i < 3; i++) { + if (strs[i] == STR_SERIAL) { + if (CmdEna[i][0]) cmds[i] = Cmds[i][0].c_str(); + if (CmdEna[i][2]) cmds_periodic[i] = Cmds[i][2].c_str(); + } else if (strs[i] == STR_TCPCLI || strs[i] == STR_TCPSVR || strs[i] == STR_NTRIPCLI) { + if (CmdEnaTcp[i][0]) cmds[i] = CmdsTcp[i][0].c_str(); + if (CmdEnaTcp[i][2]) cmds_periodic[i] = CmdsTcp[i][2].c_str(); + } + rcvopts[i] = RcvOpt[i].c_str(); + } + NmeaCycle = NmeaCycle < 1000 ? 1000 : NmeaCycle; + pos[0] = NmeaPos[0] * D2R; + pos[1] = NmeaPos[1] * D2R; + pos[2] = NmeaPos[2]; + pos2ecef(pos, nmeapos); + + strsetdir(LocalDirectory.c_str()); + strsetproxy(ProxyAddr.c_str()); + + for (i = 3; i < 8; i++) { + if (strs[i] == STR_FILE && !ConfOverwrite(paths[i])) { + if (SolOpt.trace > 0) traceclose(); + free_pcvs(&rtksvr.pcvsr); + return; + } + } + if (SolOpt.sstat > 0) { + rtkopenstat(STATFILE, SolOpt.sstat); + } + if (SolOpt.geoid > 0 && GeoidDataFileF != "") { + opengeoid(SolOpt.geoid, GeoidDataFileF.c_str()); + } + if (DCBFileF != "") { + readdcb(DCBFileF.c_str(), &rtksvr.nav, NULL); + } + for (i = 0; i < 2; i++) { + solopt[i] = SolOpt; + solopt[i].posf = Format[i + 3]; + } + stropt[0] = TimeoutTime; + stropt[1] = ReconTime; + stropt[2] = 1000; + stropt[3] = SvrBuffSize; + stropt[4] = FileSwapMargin; + strsetopt(stropt); + strcpy(rtksvr.cmd_reset, ResetCmd.c_str()); + rtksvr.bl_reset = MaxBL; + + // start rtk server + if (!rtksvrstart(&rtksvr, SvrCycle, SvrBuffSize, strs, (const char **)paths, Format, NavSelect, + (const char **)cmds, (const char **)cmds_periodic, (const char **)rcvopts, + NmeaCycle, NmeaReq, nmeapos, &PrcOpt, solopt, &monistr, errmsg)) { + trace(2, "rtksvrstart error %s\n", errmsg); + if (SolOpt.trace > 0) traceclose(); + free_pcvs(&rtksvr.pcvsr); + return; + } + PSol = PSolS = PSolE = 0; + SolStat[0] = Nvsat[0] = 0; + for (i = 0; i < 3; i++) SolRov[i] = SolRef[i] = VelRov[i] = 0.0; + for (i = 0; i < 9; i++) Qr[i] = 0.0; + Age[0] = Ratio[0] = 0.0; + Nsat[0] = Nsat[1] = 0; + UpdatePos(); + UpdatePlot(); + BtnStart->Visible = false; + BtnStart->Enabled = false; + BtnOpt->Enabled = false; + BtnExit->Enabled = false; + BtnInputStr->Enabled = false; + MenuStart->Enabled = false; + MenuExit->Enabled = false; + ScbSol->Enabled = false; + BtnStop->Visible = true; + MenuStop->Enabled = true; + Svr->Color = CLORANGE; + SetTrayIcon(0); } // stop rtk server ---------------------------------------------------------- -void __fastcall TMainForm::SvrStop(void) -{ - char *cmds[3]={0}; - int i,n,m,str; - - trace(3,"SvrStop\n"); - - for (i=0;i<3;i++) { - str=rtksvr.stream[i].type; - - if (str==STR_SERIAL) { - if (CmdEna[i][1]) cmds[i]=Cmds[i][1].c_str(); - } - else if (str==STR_TCPCLI||str==STR_TCPSVR||str==STR_NTRIPCLI) { - if (CmdEnaTcp[i][1]) cmds[i]=CmdsTcp[i][1].c_str(); - } - } - rtksvrstop(&rtksvr,(const char **)cmds); - - free_pcvs(&rtksvr.pcvsr); +void __fastcall TMainForm::SvrStop(void) { + char *cmds[3] = {0}; + int i, n, m, str; - BtnStart ->Visible=true; - BtnStart ->Enabled=true; - BtnOpt ->Enabled=true; - BtnExit ->Enabled=true; - BtnInputStr ->Enabled=true; - MenuStart ->Enabled=true; - MenuExit ->Enabled=true; - ScbSol ->Enabled=true; - BtnStop ->Visible=false; - MenuStop ->Enabled=false; - Svr->Color=clWindow; - SetTrayIcon(1); - - LabelTime->Font->Color=clGray; - IndSol->Color=clWhite; - n=PSolE-PSolS; if (n<0) n+=SolBuffSize; - m=PSol-PSolS; if (m<0) m+=SolBuffSize; - if (n>0) { - ScbSol->Max=n-1; ScbSol->Position=m; + trace(3, "SvrStop\n"); + + for (i = 0; i < 3; i++) { + str = rtksvr.stream[i].type; + + if (str == STR_SERIAL) { + if (CmdEna[i][1]) cmds[i] = Cmds[i][1].c_str(); + } else if (str == STR_TCPCLI || str == STR_TCPSVR || str == STR_NTRIPCLI) { + if (CmdEnaTcp[i][1]) cmds[i] = CmdsTcp[i][1].c_str(); } - Message->Caption=""; Message->Hint=""; - - if (SolOpt.trace>0) traceclose(); - if (SolOpt.sstat>0) rtkclosestat(); - if (OutputGeoidF>0&&GeoidDataFileF!="") closegeoid(); + } + rtksvrstop(&rtksvr, (const char **)cmds); + + free_pcvs(&rtksvr.pcvsr); + + BtnStart->Visible = true; + BtnStart->Enabled = true; + BtnOpt->Enabled = true; + BtnExit->Enabled = true; + BtnInputStr->Enabled = true; + MenuStart->Enabled = true; + MenuExit->Enabled = true; + ScbSol->Enabled = true; + BtnStop->Visible = false; + MenuStop->Enabled = false; + Svr->Color = clWindow; + SetTrayIcon(1); + + LabelTime->Font->Color = clGray; + IndSol->Color = clWhite; + n = PSolE - PSolS; + if (n < 0) n += SolBuffSize; + m = PSol - PSolS; + if (m < 0) m += SolBuffSize; + if (n > 0) { + ScbSol->Max = n - 1; + ScbSol->Position = m; + } + Message->Caption = ""; + Message->Hint = ""; + + if (SolOpt.trace > 0) traceclose(); + if (SolOpt.sstat > 0) rtkclosestat(); + if (OutputGeoidF > 0 && GeoidDataFileF != "") closegeoid(); } // callback on interval timer ----------------------------------------------- -void __fastcall TMainForm::TimerTimer(TObject *Sender) -{ - sol_t *sol; - int i,update=0; - uint8_t buff[8]; - - trace(4,"TimerTimer\n"); - - TimerCycle++; - - rtksvrlock(&rtksvr); - - for (i=0;istat,sol->time,sol->rr,sol->qr,rtksvr.rtk.rb,sol->ns, - sol->age,sol->ratio); - update=1; - } - rtksvr.nsol=0; - SolCurrentStat=rtksvr.state?rtksvr.rtk.sol.stat:0; - - rtksvrunlock(&rtksvr); - - if (update) { - UpdateTime(); - UpdatePos(); - TimerInact=0; - } - else { - if (++TimerInact*Timer->Interval>TIMEOUT) SolCurrentStat=0; - } - if (SolCurrentStat) { - Svr->Color=clLime; - LabelTime->Font->Color=clBlack; - } - else { - IndSol->Color=clWhite; - Solution->Font->Color=clGray; - Svr->Color=rtksvr.state?clGreen:clWindow; - } - if (!(TimerCycle%5)) UpdatePlot(); - UpdateStr(); - - // keep alive for monitor port - if (!(TimerCycle%(KACYCLE/Timer->Interval))&&OpenPort) { - buff[0]='\r'; - strwrite(&monistr,buff,1); - } +void __fastcall TMainForm::TimerTimer(TObject *Sender) { + sol_t *sol; + int i, update = 0; + uint8_t buff[8]; + + trace(4, "TimerTimer\n"); + + TimerCycle++; + + rtksvrlock(&rtksvr); + + for (i = 0; i < rtksvr.nsol; i++) { + sol = rtksvr.solbuf + i; + UpdateLog(sol->stat, sol->time, sol->rr, sol->qr, rtksvr.rtk.rb, sol->ns, sol->age, sol->ratio); + update = 1; + } + rtksvr.nsol = 0; + SolCurrentStat = rtksvr.state ? rtksvr.rtk.sol.stat : 0; + + rtksvrunlock(&rtksvr); + + if (update) { + UpdateTime(); + UpdatePos(); + TimerInact = 0; + } else { + if (++TimerInact * Timer->Interval > TIMEOUT) SolCurrentStat = 0; + } + if (SolCurrentStat) { + Svr->Color = clLime; + LabelTime->Font->Color = clBlack; + } else { + IndSol->Color = clWhite; + Solution->Font->Color = clGray; + Svr->Color = rtksvr.state ? clGreen : clWindow; + } + if (!(TimerCycle % 5)) UpdatePlot(); + UpdateStr(); + + // keep alive for monitor port + if (!(TimerCycle % (KACYCLE / Timer->Interval)) && OpenPort) { + buff[0] = '\r'; + strwrite(&monistr, buff, 1); + } } // update time-system ------------------------------------------------------- -void __fastcall TMainForm::UpdateTimeSys(void) -{ - AnsiString label[]={"GPST","UTC","LT","GPST"}; - - trace(3,"UpdateTimeSys\n"); - - BtnTimeSys->Caption=label[TimeSys]; - UpdateTime(); +void __fastcall TMainForm::UpdateTimeSys(void) { + AnsiString label[] = {"GPST", "UTC", "LT", "GPST"}; + + trace(3, "UpdateTimeSys\n"); + + BtnTimeSys->Caption = label[TimeSys]; + UpdateTime(); } // update solution type ----------------------------------------------------- -void __fastcall TMainForm::UpdateSolType(void) -{ - AnsiString label[]={ - "Lat/Lon/Height","Lat/Lon/Height","X/Y/Z-ECEF","E/N/U-Baseline", - "Pitch/Yaw/Length-Baseline","" - }; - trace(3,"UpdateSolType\n"); - - Plabel0->Caption=label[SolType]; - UpdatePos(); +void __fastcall TMainForm::UpdateSolType(void) { + AnsiString label[] = {"Lat/Lon/Height", + "Lat/Lon/Height", + "X/Y/Z-ECEF", + "E/N/U-Baseline", + "Pitch/Yaw/Length-Baseline", + ""}; + trace(3, "UpdateSolType\n"); + + Plabel0->Caption = label[SolType]; + UpdatePos(); } // update log --------------------------------------------------------------- -void __fastcall TMainForm::UpdateLog(int stat, gtime_t time, double *rr, - float *qr, double *rb, int ns, double age, double ratio) -{ - int i,ena; - - if (!stat) return; - - trace(4,"UpdateLog\n"); - - SolStat[PSolE]=stat; Time[PSolE]=time; Nvsat[PSolE]=ns; Age[PSolE]=age; - Ratio[PSolE]=ratio; - for (i=0;i<3;i++) { - SolRov[i+PSolE*3]=rr[i]; - SolRef[i+PSolE*3]=rb[i]; - VelRov[i+PSolE*3]=rr[i+3]; - } - Qr[ PSolE*9]=qr[0]; - Qr[4+PSolE*9]=qr[1]; - Qr[8+PSolE*9]=qr[2]; - Qr[1+PSolE*9]=Qr[3+PSolE*9]=qr[3]; - Qr[5+PSolE*9]=Qr[7+PSolE*9]=qr[4]; - Qr[2+PSolE*9]=Qr[6+PSolE*9]=qr[5]; - - PSol=PSolE; - if (++PSolE>=SolBuffSize) PSolE=0; - if (PSolE==PSolS&&++PSolS>=SolBuffSize) PSolS=0; +void __fastcall TMainForm::UpdateLog(int stat, gtime_t time, double *rr, float *qr, double *rb, + int ns, double age, double ratio) { + int i, ena; + + if (!stat) return; + + trace(4, "UpdateLog\n"); + + SolStat[PSolE] = stat; + Time[PSolE] = time; + Nvsat[PSolE] = ns; + Age[PSolE] = age; + Ratio[PSolE] = ratio; + for (i = 0; i < 3; i++) { + SolRov[i + PSolE * 3] = rr[i]; + SolRef[i + PSolE * 3] = rb[i]; + VelRov[i + PSolE * 3] = rr[i + 3]; + } + Qr[PSolE * 9] = qr[0]; + Qr[4 + PSolE * 9] = qr[1]; + Qr[8 + PSolE * 9] = qr[2]; + Qr[1 + PSolE * 9] = Qr[3 + PSolE * 9] = qr[3]; + Qr[5 + PSolE * 9] = Qr[7 + PSolE * 9] = qr[4]; + Qr[2 + PSolE * 9] = Qr[6 + PSolE * 9] = qr[5]; + + PSol = PSolE; + if (++PSolE >= SolBuffSize) PSolE = 0; + if (PSolE == PSolS && ++PSolS >= SolBuffSize) PSolS = 0; } // update font -------------------------------------------------------------- -void __fastcall TMainForm::UpdateFont(void) -{ - TLabel *label[]={ - PlabelA,Plabel1,Plabel2,Plabel3,Pos1,Pos2,Pos3,Solution,LabelStd,LabelNSat - }; - TColor color=label[7]->Font->Color; - int i; - - trace(4,"UpdateFont\n"); - - for (i=0;i<10;i++) label[i]->Font->Assign(PosFont); - label[0]->Font->Size=9; label[7]->Font->Color=color; - label[8]->Font->Size=8; label[8]->Font->Color=clGray; - label[9]->Font->Size=8; label[9]->Font->Color=clGray; +void __fastcall TMainForm::UpdateFont(void) { + TLabel *label[] = {PlabelA, Plabel1, Plabel2, Plabel3, Pos1, + Pos2, Pos3, Solution, LabelStd, LabelNSat}; + TColor color = label[7]->Font->Color; + int i; + + trace(4, "UpdateFont\n"); + + for (i = 0; i < 10; i++) label[i]->Font->Assign(PosFont); + label[0]->Font->Size = 9; + label[7]->Font->Color = color; + label[8]->Font->Size = 8; + label[8]->Font->Color = clGray; + label[9]->Font->Size = 8; + label[9]->Font->Color = clGray; } // update time -------------------------------------------------------------- -void __fastcall TMainForm::UpdateTime(void) -{ - gtime_t time=Time[PSol]; - struct tm *t; - double tow; - int week; - char tstr[40]; - - trace(4,"UpdateTime\n"); - - if (TimeSys==0) time2str(time,tstr,1); - else if (TimeSys==1) time2str(gpst2utc(time),tstr,1); - else if (TimeSys==2) { - time=gpst2utc(time); - if (!(t=localtime(&time.time))) strcpy(tstr,"2000/01/01 00:00:00.0"); - else snprintf(tstr,sizeof(tstr),"%04d/%02d/%02d %02d:%02d:%02d.%d",t->tm_year+1900, - t->tm_mon+1,t->tm_mday,t->tm_hour,t->tm_min,t->tm_sec, - (int)(time.sec*10)); - } - else if (TimeSys==3) { - tow=time2gpst(time,&week); sprintf(tstr,"week %04d %8.1f s",week,tow); - } - LabelTime->Caption=tstr; +void __fastcall TMainForm::UpdateTime(void) { + gtime_t time = Time[PSol]; + struct tm *t; + double tow; + int week; + char tstr[40]; + + trace(4, "UpdateTime\n"); + + if (TimeSys == 0) + time2str(time, tstr, 1); + else if (TimeSys == 1) + time2str(gpst2utc(time), tstr, 1); + else if (TimeSys == 2) { + time = gpst2utc(time); + if (!(t = localtime(&time.time))) + strcpy(tstr, "2000/01/01 00:00:00.0"); + else + snprintf(tstr, sizeof(tstr), "%04d/%02d/%02d %02d:%02d:%02d.%d", t->tm_year + 1900, + t->tm_mon + 1, t->tm_mday, t->tm_hour, t->tm_min, t->tm_sec, (int)(time.sec * 10)); + } else if (TimeSys == 3) { + tow = time2gpst(time, &week); + sprintf(tstr, "week %04d %8.1f s", week, tow); + } + LabelTime->Caption = tstr; } // update solution display -------------------------------------------------- -void __fastcall TMainForm::UpdatePos(void) -{ - TLabel *label[]={Plabel1,Plabel2,Plabel3,Pos1,Pos2,Pos3,LabelStd,LabelNSat}; - UTF8String sol[]={"----","FIX","FLOAT","SBAS","DGPS","SINGLE","PPP"}; - UTF8String s[9],ext=""; - TColor color[]={clSilver,clGreen,CLORANGE,clFuchsia,clBlue,clRed,clTeal}; - gtime_t time; - double *rr=SolRov+PSol*3,*rb=SolRef+PSol*3,*qr=Qr+PSol*9,pos[3]={0},Qe[9]={0}; - double dms1[3]={0},dms2[3]={0},bl[3]={0},enu[3]={0},pitch=0.0,yaw=0.0,len; - int i,stat=SolStat[PSol]; - - trace(4,"UpdatePos\n"); - - if (rtksvr.rtk.opt.mode==PMODE_STATIC||rtksvr.rtk.opt.mode==PMODE_PPP_STATIC) { - ext=" (S)"; - } - else if (rtksvr.rtk.opt.mode==PMODE_FIXED||rtksvr.rtk.opt.mode==PMODE_PPP_FIXED) { - ext=" (F)"; - } - PlabelA->Caption="Solution"+ext+":"; - Solution->Caption=sol[stat]; - Solution->Font->Color=rtksvr.state?color[stat]:clGray; - IndSol->Color=rtksvr.state&&stat?color[stat]:clWhite; - if (norm(rr,3)>0.0&&norm(rb,3)>0.0) { - for (i=0;i<3;i++) bl[i]=rr[i]-rb[i]; - } - len=norm(bl,3); - if (SolType==0) { - if (norm(rr,3)>0.0) { - ecef2pos(rr,pos); covenu(pos,qr,Qe); - degtodms(pos[0]*R2D,dms1); - degtodms(pos[1]*R2D,dms2); - if (SolOpt.height==1) pos[2]-=geoidh(pos); /* geodetic */ - } - s[0]=pos[0]<0?"S:":"N:"; s[1]=pos[1]<0?"W:":"E:"; - s[2]=SolOpt.height==1?"H:":"He:"; - s[3].sprintf("%.0f%s %02.0f' %07.4f\"",fabs(dms1[0]),CHARDEG,dms1[1],dms1[2]); - s[4].sprintf("%.0f%s %02.0f' %07.4f\"",fabs(dms2[0]),CHARDEG,dms2[1],dms2[2]); - s[5].sprintf("%.3f m",pos[2]); - s[6].sprintf("N:%6.3f E:%6.3f U:%6.3f m",SQRT(Qe[4]),SQRT(Qe[0]),SQRT(Qe[8])); - } - else if (SolType==1) { - if (norm(rr,3)>0.0) { - ecef2pos(rr,pos); covenu(pos,qr,Qe); - if (SolOpt.height==1) pos[2]-=geoidh(pos); /* geodetic */ - } - s[0]=pos[0]<0?"S:":"N:"; s[1]=pos[1]<0?"W:":"E:"; - s[2]=SolOpt.height==1?"H:":"He:"; - s[3].sprintf("%.8f %s",fabs(pos[0])*R2D,CHARDEG); - s[4].sprintf("%.8f %s",fabs(pos[1])*R2D,CHARDEG); - s[5].sprintf("%.3f m",pos[2]); - s[6].sprintf("E:%6.3f N:%6.3f U:%6.3f m",SQRT(Qe[0]),SQRT(Qe[4]),SQRT(Qe[8])); - } - else if (SolType==2) { - s[0]="X:"; s[1]="Y:"; s[2]="Z:"; - s[3].sprintf("%.3f m",rr[0]); - s[4].sprintf("%.3f m",rr[1]); - s[5].sprintf("%.3f m",rr[2]); - s[6].sprintf("X:%6.3f Y:%6.3f Z:%6.3f m",SQRT(qr[0]),SQRT(qr[4]),SQRT(qr[8])); - } - else if (SolType==3) { - if (len>0.0) { - ecef2pos(rb,pos); ecef2enu(pos,bl,enu); covenu(pos,qr,Qe); - } - s[0]="E:"; s[1]="N:"; s[2]="U:"; - s[3].sprintf("%.3f m",enu[0]); - s[4].sprintf("%.3f m",enu[1]); - s[5].sprintf("%.3f m",enu[2]); - s[6].sprintf("E:%6.3f N:%6.3f U:%6.3f m",SQRT(Qe[0]),SQRT(Qe[4]),SQRT(Qe[8])); - } - else { - if (len>0.0) { - ecef2pos(rb,pos); ecef2enu(pos,bl,enu); covenu(pos,qr,Qe); - pitch=asin(enu[2]/len); - yaw=atan2(enu[0],enu[1]); if (yaw<0.0) yaw+=2.0*PI; - } - s[0]="P:"; s[1]="Y:"; s[2]="L:"; - s[3].sprintf("%.3f %s",pitch*R2D,CHARDEG); - s[4].sprintf("%.3f %s",yaw*R2D,CHARDEG); - s[5].sprintf("%.3f m",len); - s[6].sprintf("E:%6.3f N:%6.3f U:%6.3f m",SQRT(Qe[0]),SQRT(Qe[4]),SQRT(Qe[8])); - } - s[7].sprintf("Age:%4.1f s Ratio:%4.1f #Sat:%2d",Age[PSol],Ratio[PSol],Nvsat[PSol]); - if (Ratio[PSol]>0.0) s[8].sprintf(" R:%4.1f",Ratio[PSol]); - - for (i=0;i<8;i++) label[i]->Caption=s[i]; - for (i=3;i<6;i++) { - label[i]->Font->Color=PrcOpt.mode==PMODE_MOVEB&&SolType<=2?clGray:clBlack; - } - IndQ->Color=IndSol->Color; - SolS->Caption=Solution->Caption; - SolS->Font->Color=Solution->Font->Color; - SolQ->Caption=ext+L" "+label[0]->Caption+L" "+label[3]->Caption+L" "+ - label[1]->Caption+L" "+label[4]->Caption+L" "+ - label[2]->Caption+L" "+label[5]->Caption+s[8]; +void __fastcall TMainForm::UpdatePos(void) { + TLabel *label[] = {Plabel1, Plabel2, Plabel3, Pos1, Pos2, Pos3, LabelStd, LabelNSat}; + UTF8String sol[] = {"----", "FIX", "FLOAT", "SBAS", "DGPS", "SINGLE", "PPP"}; + UTF8String s[9], ext = ""; + TColor color[] = {clSilver, clGreen, CLORANGE, clFuchsia, clBlue, clRed, clTeal}; + gtime_t time; + double *rr = SolRov + PSol * 3, *rb = SolRef + PSol * 3, *qr = Qr + PSol * 9, pos[3] = {0}, + Qe[9] = {0}; + double dms1[3] = {0}, dms2[3] = {0}, bl[3] = {0}, enu[3] = {0}, pitch = 0.0, yaw = 0.0, len; + int i, stat = SolStat[PSol]; + + trace(4, "UpdatePos\n"); + + if (rtksvr.rtk.opt.mode == PMODE_STATIC || rtksvr.rtk.opt.mode == PMODE_PPP_STATIC) { + ext = " (S)"; + } else if (rtksvr.rtk.opt.mode == PMODE_FIXED || rtksvr.rtk.opt.mode == PMODE_PPP_FIXED) { + ext = " (F)"; + } + PlabelA->Caption = "Solution" + ext + ":"; + Solution->Caption = sol[stat]; + Solution->Font->Color = rtksvr.state ? color[stat] : clGray; + IndSol->Color = rtksvr.state && stat ? color[stat] : clWhite; + if (norm(rr, 3) > 0.0 && norm(rb, 3) > 0.0) { + for (i = 0; i < 3; i++) bl[i] = rr[i] - rb[i]; + } + len = norm(bl, 3); + if (SolType == 0) { + if (norm(rr, 3) > 0.0) { + ecef2pos(rr, pos); + covenu(pos, qr, Qe); + degtodms(pos[0] * R2D, dms1); + degtodms(pos[1] * R2D, dms2); + if (SolOpt.height == 1) pos[2] -= geoidh(pos); /* geodetic */ + } + s[0] = pos[0] < 0 ? "S:" : "N:"; + s[1] = pos[1] < 0 ? "W:" : "E:"; + s[2] = SolOpt.height == 1 ? "H:" : "He:"; + s[3].sprintf("%.0f%s %02.0f' %07.4f\"", fabs(dms1[0]), CHARDEG, dms1[1], dms1[2]); + s[4].sprintf("%.0f%s %02.0f' %07.4f\"", fabs(dms2[0]), CHARDEG, dms2[1], dms2[2]); + s[5].sprintf("%.3f m", pos[2]); + s[6].sprintf("N:%6.3f E:%6.3f U:%6.3f m", SQRT(Qe[4]), SQRT(Qe[0]), SQRT(Qe[8])); + } else if (SolType == 1) { + if (norm(rr, 3) > 0.0) { + ecef2pos(rr, pos); + covenu(pos, qr, Qe); + if (SolOpt.height == 1) pos[2] -= geoidh(pos); /* geodetic */ + } + s[0] = pos[0] < 0 ? "S:" : "N:"; + s[1] = pos[1] < 0 ? "W:" : "E:"; + s[2] = SolOpt.height == 1 ? "H:" : "He:"; + s[3].sprintf("%.8f %s", fabs(pos[0]) * R2D, CHARDEG); + s[4].sprintf("%.8f %s", fabs(pos[1]) * R2D, CHARDEG); + s[5].sprintf("%.3f m", pos[2]); + s[6].sprintf("E:%6.3f N:%6.3f U:%6.3f m", SQRT(Qe[0]), SQRT(Qe[4]), SQRT(Qe[8])); + } else if (SolType == 2) { + s[0] = "X:"; + s[1] = "Y:"; + s[2] = "Z:"; + s[3].sprintf("%.3f m", rr[0]); + s[4].sprintf("%.3f m", rr[1]); + s[5].sprintf("%.3f m", rr[2]); + s[6].sprintf("X:%6.3f Y:%6.3f Z:%6.3f m", SQRT(qr[0]), SQRT(qr[4]), SQRT(qr[8])); + } else if (SolType == 3) { + if (len > 0.0) { + ecef2pos(rb, pos); + ecef2enu(pos, bl, enu); + covenu(pos, qr, Qe); + } + s[0] = "E:"; + s[1] = "N:"; + s[2] = "U:"; + s[3].sprintf("%.3f m", enu[0]); + s[4].sprintf("%.3f m", enu[1]); + s[5].sprintf("%.3f m", enu[2]); + s[6].sprintf("E:%6.3f N:%6.3f U:%6.3f m", SQRT(Qe[0]), SQRT(Qe[4]), SQRT(Qe[8])); + } else { + if (len > 0.0) { + ecef2pos(rb, pos); + ecef2enu(pos, bl, enu); + covenu(pos, qr, Qe); + pitch = asin(enu[2] / len); + yaw = atan2(enu[0], enu[1]); + if (yaw < 0.0) yaw += 2.0 * PI; + } + s[0] = "P:"; + s[1] = "Y:"; + s[2] = "L:"; + s[3].sprintf("%.3f %s", pitch * R2D, CHARDEG); + s[4].sprintf("%.3f %s", yaw * R2D, CHARDEG); + s[5].sprintf("%.3f m", len); + s[6].sprintf("E:%6.3f N:%6.3f U:%6.3f m", SQRT(Qe[0]), SQRT(Qe[4]), SQRT(Qe[8])); + } + s[7].sprintf("Age:%4.1f s Ratio:%4.1f #Sat:%2d", Age[PSol], Ratio[PSol], Nvsat[PSol]); + if (Ratio[PSol] > 0.0) s[8].sprintf(" R:%4.1f", Ratio[PSol]); + + for (i = 0; i < 8; i++) label[i]->Caption = s[i]; + for (i = 3; i < 6; i++) { + label[i]->Font->Color = PrcOpt.mode == PMODE_MOVEB && SolType <= 2 ? clGray : clBlack; + } + IndQ->Color = IndSol->Color; + SolS->Caption = Solution->Caption; + SolS->Font->Color = Solution->Font->Color; + SolQ->Caption = ext + L" " + label[0]->Caption + L" " + label[3]->Caption + L" " + + label[1]->Caption + L" " + label[4]->Caption + L" " + label[2]->Caption + L" " + + label[5]->Caption + s[8]; } // update stream status indicators ------------------------------------------ -void __fastcall TMainForm::UpdateStr(void) -{ - TColor color[]={clRed,clWindow,CLORANGE,clGreen,clLime}; - TPanel *ind[MAXSTRRTK]={Str1,Str2,Str3,Str4,Str5,Str6,Str7,Str8}; - int i,sstat[MAXSTRRTK]={0}; - char msg[MAXSTRMSG]=""; - - trace(4,"UpdateStr\n"); - - rtksvrsstat(&rtksvr,sstat,msg); - for (i=0;iColor=color[sstat[i]+1]; - if (sstat[i]) { - Message->Caption=msg; - Message->Hint=Message->Caption; - } +void __fastcall TMainForm::UpdateStr(void) { + TColor color[] = {clRed, clWindow, CLORANGE, clGreen, clLime}; + TPanel *ind[MAXSTRRTK] = {Str1, Str2, Str3, Str4, Str5, Str6, Str7, Str8}; + int i, sstat[MAXSTRRTK] = {0}; + char msg[MAXSTRMSG] = ""; + + trace(4, "UpdateStr\n"); + + rtksvrsstat(&rtksvr, sstat, msg); + for (i = 0; i < MAXSTRRTK; i++) { + ind[i]->Color = color[sstat[i] + 1]; + if (sstat[i]) { + Message->Caption = msg; + Message->Hint = Message->Caption; } + } } // draw solution plot ------------------------------------------------------- -void __fastcall TMainForm::DrawPlot(TImage *plot, int type, int freq) -{ - UTF8String s1,s2,fstr[NFREQ+2]; - gtime_t time; - TCanvas *c=plot->Canvas; - TLabel *label[]={Plabel1,Plabel2,Plabel3,Pos1,Pos2,Pos3}; - int w=plot->Parent->Width-2,h=plot->Parent->Height-2; - int i,j,x,sat[2][MAXSAT],ns[2],snr[2][MAXSAT][NFREQ],vsat[2][MAXSAT]; - int *snr0[MAXSAT],*snr1[MAXSAT],tm=PanelFont->Size*3/2; - char name[16]; - double az[2][MAXSAT],el[2][MAXSAT],rr[3],rs[6],e[3],pos[3],azel[2]; - - trace(4,"DrawPlot\n"); - - for (i=0;i0) { - Nsat[i]=ns[i]; - for (int j=0;jBrush->Style=bsSolid; - c->Brush->Color=clWhite; - c->FillRect(plot->ClientRect); - x=4; - if (type==0) { // snr plot rover+base - if (w<=3*h) { // vertical - DrawSnr(c,w,(h-tm)/2,0,tm,0,freq); - DrawSnr(c,w,(h-tm)/2,0,tm+(h-tm)/2,1,freq); - s1="Rover:Base "+fstr[freq]+" SNR (dBHz)"; - DrawText(c,x,1,s1,clGray,1,2); - } - else { // horizontal - DrawSnr(c,w/2,h-tm,0 ,tm,0,freq); - DrawSnr(c,w/2,h-tm,w/2,tm,1,freq); - s1="Rover "+fstr[freq]+" SNR (dBHz)"; - s2="Base "+fstr[freq]+" SNR (dBHz)"; - DrawText(c,x,1,s1,clGray,1,2); - DrawText(c,w/2+x,1,s2,clGray,1,2); - } - } - else if (type==1) { // snr plot rover - DrawSnr(c,w,h-tm,0,tm,0,freq); - s1="Rover "+fstr[freq]+" SNR (dBHz)"; - DrawText(c,x,1,s1,clGray,1,2); - } - else if (type==2) { // skyplot rover - DrawSat(c,w,h,0,0,0,freq); - s1="Rover "+fstr[freq]; - DrawText(c,x,1,s1,clGray,1,2); - } - else if (type==3) { // skyplot+snr plot rover - s1="Rover "+fstr[freq]; - s2="SNR (dBHz)"; - if (w>=h*2) { // horizontal - DrawSat(c,h,h,0,0,0,freq); - DrawSnr(c,w-h,h-tm,h,tm,0,freq); - DrawText(c,x,1,s1,clGray,1,2); - DrawText(c,x+h,1,s2,clGray,1,2); - } - else { // vertical - DrawSat(c,w,h/2,0,0,0,freq); - DrawSnr(c,w,(h-tm)/2,0,tm+(h-tm)/2,1,freq); - DrawText(c,x,1,s1,clGray,1,2); - } - } - else if (type==4) { // skyplot rover+base - s1="Rover "+fstr[freq]; - s2="Base "+fstr[freq]; - if (w>=h) { // horizontal - DrawSat(c,w/2,h,0 ,0,0,freq); - DrawSat(c,w/2,h,w/2,0,1,freq); - DrawText(c,x,1,s1,clGray,1,2); - DrawText(c,x+w/2,1,s2,clGray,1,2); +void __fastcall TMainForm::DrawPlot(TImage *plot, int type, int freq) { + UTF8String s1, s2, fstr[NFREQ + 2]; + gtime_t time; + TCanvas *c = plot->Canvas; + TLabel *label[] = {Plabel1, Plabel2, Plabel3, Pos1, Pos2, Pos3}; + int w = plot->Parent->Width - 2, h = plot->Parent->Height - 2; + int i, j, x, sat[2][MAXSAT], ns[2], snr[2][MAXSAT][NFREQ], vsat[2][MAXSAT]; + int *snr0[MAXSAT], *snr1[MAXSAT], tm = PanelFont->Size * 3 / 2; + char name[16]; + double az[2][MAXSAT], el[2][MAXSAT], rr[3], rs[6], e[3], pos[3], azel[2]; + + trace(4, "DrawPlot\n"); + + for (i = 0; i < NFREQ; i++) { + fstr[i + 1] = s1.sprintf("L%d", i + 1); + } + fstr[i + 1] = " SYS"; + + for (i = 0; i < MAXSAT; i++) { + snr0[i] = snr[0][i]; + snr1[i] = snr[1][i]; + } + ns[0] = rtksvrostat(&rtksvr, 0, &time, sat[0], az[0], el[0], snr0, vsat[0]); + ns[1] = rtksvrostat(&rtksvr, 1, &time, sat[1], az[1], el[1], snr1, vsat[1]); + + rtksvrlock(&rtksvr); + matcpy(rr, rtksvr.rtk.sol.rr, 3, 1); + ecef2pos(rr, pos); + rtksvrunlock(&rtksvr); + + for (i = 0; i < 2; i++) { + if (ns[i] > 0) { + Nsat[i] = ns[i]; + for (int j = 0; j < ns[i]; j++) { + Sat[i][j] = sat[i][j]; + Az[i][j] = az[i][j]; + El[i][j] = el[i][j]; + for (int k = 0; k < NFREQ; k++) { + Snr[i][j][k] = snr[i][j][k]; } - else { // vertical - DrawSat(c,w,h/2,0,0 ,0,freq); - DrawSat(c,w,h/2,0,h/2,1,freq); - DrawText(c,x,1,s1,clGray,1,2); - DrawText(c,x,h/2+1,s2,clGray,1,2); + Vsat[i][j] = vsat[i][j]; + } + } else { + for (j = 0; j < Nsat[i]; j++) { + Vsat[i][j] = 0; + for (int k = 0; k < NFREQ; k++) { + Snr[i][j][k] = 0; } + } } - else if (type==5) { // baseline plot - DrawBL(plot,w,h); - DrawText(c,x,1,"Baseline",clGray,1,2); - } - else if (type==6) { // track plot - DrawTrk(plot); - DrawText(c,x,3,"Gnd Trk",clGray,1,2); - } + } + c->Brush->Style = bsSolid; + c->Brush->Color = clWhite; + c->FillRect(plot->ClientRect); + x = 4; + if (type == 0) { // snr plot rover+base + if (w <= 3 * h) { // vertical + DrawSnr(c, w, (h - tm) / 2, 0, tm, 0, freq); + DrawSnr(c, w, (h - tm) / 2, 0, tm + (h - tm) / 2, 1, freq); + s1 = "Rover:Base " + fstr[freq] + " SNR (dBHz)"; + DrawText(c, x, 1, s1, clGray, 1, 2); + } else { // horizontal + DrawSnr(c, w / 2, h - tm, 0, tm, 0, freq); + DrawSnr(c, w / 2, h - tm, w / 2, tm, 1, freq); + s1 = "Rover " + fstr[freq] + " SNR (dBHz)"; + s2 = "Base " + fstr[freq] + " SNR (dBHz)"; + DrawText(c, x, 1, s1, clGray, 1, 2); + DrawText(c, w / 2 + x, 1, s2, clGray, 1, 2); + } + } else if (type == 1) { // snr plot rover + DrawSnr(c, w, h - tm, 0, tm, 0, freq); + s1 = "Rover " + fstr[freq] + " SNR (dBHz)"; + DrawText(c, x, 1, s1, clGray, 1, 2); + } else if (type == 2) { // skyplot rover + DrawSat(c, w, h, 0, 0, 0, freq); + s1 = "Rover " + fstr[freq]; + DrawText(c, x, 1, s1, clGray, 1, 2); + } else if (type == 3) { // skyplot+snr plot rover + s1 = "Rover " + fstr[freq]; + s2 = "SNR (dBHz)"; + if (w >= h * 2) { // horizontal + DrawSat(c, h, h, 0, 0, 0, freq); + DrawSnr(c, w - h, h - tm, h, tm, 0, freq); + DrawText(c, x, 1, s1, clGray, 1, 2); + DrawText(c, x + h, 1, s2, clGray, 1, 2); + } else { // vertical + DrawSat(c, w, h / 2, 0, 0, 0, freq); + DrawSnr(c, w, (h - tm) / 2, 0, tm + (h - tm) / 2, 1, freq); + DrawText(c, x, 1, s1, clGray, 1, 2); + } + } else if (type == 4) { // skyplot rover+base + s1 = "Rover " + fstr[freq]; + s2 = "Base " + fstr[freq]; + if (w >= h) { // horizontal + DrawSat(c, w / 2, h, 0, 0, 0, freq); + DrawSat(c, w / 2, h, w / 2, 0, 1, freq); + DrawText(c, x, 1, s1, clGray, 1, 2); + DrawText(c, x + w / 2, 1, s2, clGray, 1, 2); + } else { // vertical + DrawSat(c, w, h / 2, 0, 0, 0, freq); + DrawSat(c, w, h / 2, 0, h / 2, 1, freq); + DrawText(c, x, 1, s1, clGray, 1, 2); + DrawText(c, x, h / 2 + 1, s2, clGray, 1, 2); + } + } else if (type == 5) { // baseline plot + DrawBL(plot, w, h); + DrawText(c, x, 1, "Baseline", clGray, 1, 2); + } else if (type == 6) { // track plot + DrawTrk(plot); + DrawText(c, x, 3, "Gnd Trk", clGray, 1, 2); + } } // update solution plot ------------------------------------------------------ -void __fastcall TMainForm::UpdatePlot(void) -{ - if (Panel22->Visible) { - DrawPlot(Plot1,PlotType1,FreqType1); - Disp1->Canvas->CopyRect(Panel22->ClientRect,Plot1->Canvas,Panel22->ClientRect); - } - if (Panel23->Visible) { - DrawPlot(Plot2,PlotType2,FreqType2); - Disp2->Canvas->CopyRect(Panel23->ClientRect,Plot2->Canvas,Panel23->ClientRect); - } - if (Panel24->Visible) { - DrawPlot(Plot3,PlotType3,FreqType3); - Disp3->Canvas->CopyRect(Panel24->ClientRect,Plot3->Canvas,Panel24->ClientRect); - } - if (Panel25->Visible) { - DrawPlot(Plot4,PlotType4,FreqType4); - Disp4->Canvas->CopyRect(Panel25->ClientRect,Plot4->Canvas,Panel25->ClientRect); - } +void __fastcall TMainForm::UpdatePlot(void) { + if (Panel22->Visible) { + DrawPlot(Plot1, PlotType1, FreqType1); + Disp1->Canvas->CopyRect(Panel22->ClientRect, Plot1->Canvas, Panel22->ClientRect); + } + if (Panel23->Visible) { + DrawPlot(Plot2, PlotType2, FreqType2); + Disp2->Canvas->CopyRect(Panel23->ClientRect, Plot2->Canvas, Panel23->ClientRect); + } + if (Panel24->Visible) { + DrawPlot(Plot3, PlotType3, FreqType3); + Disp3->Canvas->CopyRect(Panel24->ClientRect, Plot3->Canvas, Panel24->ClientRect); + } + if (Panel25->Visible) { + DrawPlot(Plot4, PlotType4, FreqType4); + Disp4->Canvas->CopyRect(Panel25->ClientRect, Plot4->Canvas, Panel25->ClientRect); + } } // snr color ---------------------------------------------------------------- -TColor __fastcall TMainForm::SnrColor(int snr) -{ - TColor color[]={clGreen,CLORANGE,clFuchsia,clBlue,clRed,clGray}; - uint32_t c1,c2,r1,r2,g1,g2,b1,b2; - double a; - int i; - - if (snr<25) return color[5]; - if (snr<27) return color[4]; - if (snr>47) return color[0]; - a=(snr-27.5)/5.0; - i=(int)a; a-=i; - c1=(uint32_t)color[3-i]; - c2=(uint32_t)color[4-i]; - r1=c1&0xFF; g1=(c1>>8)&0xFF; b1=(c1>>16)&0xFF; - r2=c2&0xFF; g2=(c2>>8)&0xFF; b2=(c2>>16)&0xFF; - r1=(uint32_t)(a*r1+(1.0-a)*r2)&0xFF; - g1=(uint32_t)(a*g1+(1.0-a)*g2)&0xFF; - b1=(uint32_t)(a*b1+(1.0-a)*b2)&0xFF; - - return (TColor)((b1<<16)+(g1<<8)+r1); +TColor __fastcall TMainForm::SnrColor(int snr) { + TColor color[] = {clGreen, CLORANGE, clFuchsia, clBlue, clRed, clGray}; + uint32_t c1, c2, r1, r2, g1, g2, b1, b2; + double a; + int i; + + if (snr < 25) return color[5]; + if (snr < 27) return color[4]; + if (snr > 47) return color[0]; + a = (snr - 27.5) / 5.0; + i = (int)a; + a -= i; + c1 = (uint32_t)color[3 - i]; + c2 = (uint32_t)color[4 - i]; + r1 = c1 & 0xFF; + g1 = (c1 >> 8) & 0xFF; + b1 = (c1 >> 16) & 0xFF; + r2 = c2 & 0xFF; + g2 = (c2 >> 8) & 0xFF; + b2 = (c2 >> 16) & 0xFF; + r1 = (uint32_t)(a * r1 + (1.0 - a) * r2) & 0xFF; + g1 = (uint32_t)(a * g1 + (1.0 - a) * g2) & 0xFF; + b1 = (uint32_t)(a * b1 + (1.0 - a) * b2) & 0xFF; + + return (TColor)((b1 << 16) + (g1 << 8) + r1); } // draw snr plot ------------------------------------------------------------ -void __fastcall TMainForm::DrawSnr(TCanvas *c, int w, int h, int x0, int y0, - int index, int freq) -{ - static const TColor color[]={ - (TColor)0x00008000,(TColor)0x00008080,(TColor)0x00A000A0, - (TColor)0x00800000,(TColor)0x00000080,(TColor)0x00808000, - (TColor)0x00808080 - }; - static const TColor color_sys[]={ - clGreen,(TColor)0xAAFF,clFuchsia,clBlue,clRed,clTeal,clGray - }; - UTF8String s; - int i,j,k,l,n,x1,x2,y1,y2,y3,k1,tm,bm,hh,ww,www,snr[NFREQ+1],mask[7]={0}; - char id[8],sys[]="GREJCIS",*q; - - trace(4,"DrawSnr: w=%d h=%d x0=%d y0=%d index=%d freq=%d\n",w,h,x0,y0,index,freq); - - tm=PanelFont->Size*3/4; - bm=PanelFont->Size*7/4; - y0+=tm; - hh=h-tm-bm; - c->Pen->Color=clSilver; - for (snr[0]=MINSNR+10;snr[0]MoveTo(x0+2,y1); c->LineTo(x0+w-2,y1); - DrawText(c,x0+w-4,y1,s.sprintf("%d",snr[0]),clGray,2,0); - } - y1=y0+hh; - TRect b(x0+2,y0,x0+w-2,y1); - c->Pen->Color=clGray; - c->Brush->Style=bsClear; - c->Rectangle(b); - - for (i=0;iNFREQ)&&snr[j+1]>snr[0])) { - snr[0]=snr[j+1]; - } - } - for (j=0;j0) y2-=(snr[k]-MINSNR)*hh/(MAXSNR-MINSNR)-y3; - y2=y2<2?2:(y1Brush->Style=bsSolid; - c->Brush->Color=freqBrush->Color=clSilver; - c->Rectangle(r1); - } - else { - c->Pen->Color=jBrush->Style=bsClear; - c->Rectangle(r1); - } - } - DrawText(c,x1+www/2,y1,(s=id+1),color[l],0,2); - mask[l]=1; +void __fastcall TMainForm::DrawSnr(TCanvas *c, int w, int h, int x0, int y0, int index, int freq) { + static const TColor color[] = {(TColor)0x00008000, (TColor)0x00008080, (TColor)0x00A000A0, + (TColor)0x00800000, (TColor)0x00000080, (TColor)0x00808000, + (TColor)0x00808080}; + static const TColor color_sys[] = {clGreen, (TColor)0xAAFF, clFuchsia, clBlue, + clRed, clTeal, clGray}; + UTF8String s; + int i, j, k, l, n, x1, x2, y1, y2, y3, k1, tm, bm, hh, ww, www, snr[NFREQ + 1], mask[7] = {0}; + char id[8], sys[] = "GREJCIS", *q; + + trace(4, "DrawSnr: w=%d h=%d x0=%d y0=%d index=%d freq=%d\n", w, h, x0, y0, index, freq); + + tm = PanelFont->Size * 3 / 4; + bm = PanelFont->Size * 7 / 4; + y0 += tm; + hh = h - tm - bm; + c->Pen->Color = clSilver; + for (snr[0] = MINSNR + 10; snr[0] < MAXSNR; snr[0] += 10) { + y1 = y0 + hh - (snr[0] - MINSNR) * hh / (MAXSNR - MINSNR); + c->MoveTo(x0 + 2, y1); + c->LineTo(x0 + w - 2, y1); + DrawText(c, x0 + w - 4, y1, s.sprintf("%d", snr[0]), clGray, 2, 0); + } + y1 = y0 + hh; + TRect b(x0 + 2, y0, x0 + w - 2, y1); + c->Pen->Color = clGray; + c->Brush->Style = bsClear; + c->Rectangle(b); + + for (i = 0; i < Nsat[index] && i < MAXSAT; i++) { + ww = (w - 16) / Nsat[index]; + www = ww - 2 < 8 ? ww - 2 : 8; + x1 = x0 + i * (w - 16) / Nsat[index] + ww / 2; + satno2id(Sat[index][i], id); + l = (q = strchr(sys, id[0])) ? (int)(q - sys) : 6; + + for (j = snr[0] = 0; j < NFREQ; j++) { + snr[j + 1] = Snr[index][i][j]; + if ((freq && freq == j + 1) || ((!freq || freq > NFREQ) && snr[j + 1] > snr[0])) { + snr[0] = snr[j + 1]; + } } - for (i=n=0;i<7;i++) if (mask[i]) n++; - for (i=j=0;i<7;i++) { - if (!mask[i]) continue; - sprintf(id,"%c",sys[i]); - DrawText(c,x0+w-tm*3/2+PanelFont->Size*9/8*(-n+j++),y0+tm,(s=id),color[i],0,2); + for (j = 0; j < NFREQ + 2; j++) { + k = j < NFREQ + 1 ? j : 0; + y3 = j < NFREQ + 1 ? 0 : 2; + y2 = y1 - y3; + if (snr[k] > 0) y2 -= (snr[k] - MINSNR) * hh / (MAXSNR - MINSNR) - y3; + y2 = y2 < 2 ? 2 : (y1 < y2 ? y1 : y2); + + TRect r1(x1, y1, x1 + www, y2); + if (j == 0) { + c->Brush->Style = bsSolid; + c->Brush->Color = freq < NFREQ + 1 ? SnrColor(snr[k]) : color_sys[l]; + if (!Vsat[index][i]) c->Brush->Color = clSilver; + c->Rectangle(r1); + } else { + c->Pen->Color = j < NFREQ + 1 ? clSilver : clGray; + c->Brush->Style = bsClear; + c->Rectangle(r1); + } } + DrawText(c, x1 + www / 2, y1, (s = id + 1), color[l], 0, 2); + mask[l] = 1; + } + for (i = n = 0; i < 7; i++) + if (mask[i]) n++; + for (i = j = 0; i < 7; i++) { + if (!mask[i]) continue; + sprintf(id, "%c", sys[i]); + DrawText(c, x0 + w - tm * 3 / 2 + PanelFont->Size * 9 / 8 * (-n + j++), y0 + tm, (s = id), + color[i], 0, 2); + } } // draw satellites in skyplot ----------------------------------------------- -void __fastcall TMainForm::DrawSat(TCanvas *c, int w, int h, int x0, int y0, - int index, int freq) -{ - static const TColor color_sys[]={ - clGreen,(TColor)0xAAFF,clFuchsia,clBlue,clRed,clTeal,clGray - }; - TColor color_text; - UTF8String s; - TPoint p(w/2,h/2); - double r=MIN(w*0.95,h*0.95)/2,azel[MAXSAT*2],dop[4]; - int i,j,k,l,d,x[MAXSAT],y[MAXSAT],snr[NFREQ+1],ns=0; - char id[8],sys[]="GREJCIS",*q; - - trace(4,"DrawSat: w=%d h=%d index=%d freq=%d\n",w,h,index,freq); - - DrawSky(c,w,h,x0,y0); - - for (i=0,k=Nsat[index]-1;iNFREQ)&&snr[j+1]>snr[0])) { - snr[0]=snr[j+1]; // max snr - } - } - if (Vsat[index][k]&&(freq>NFREQ||snr[freq]>0)) { - azel[ns*2]=Az[index][k]; azel[1+ns*2]=El[index][k]; - ns++; - } - satno2id(Sat[index][k],id); - l=(q=strchr(sys,id[0]))?(int)(q-sys):6; - x[i]=(int)(p.x+r*(90-El[index][k]*R2D)/90*sin(Az[index][k]))+x0; - y[i]=(int)(p.y-r*(90-El[index][k]*R2D)/90*cos(Az[index][k]))+y0; - d=PanelFont->Size*3/2; - c->Brush->Color=!Vsat[index][k]?clSilver: - (freqBrush->Style=bsSolid; - c->Pen->Color=clGray; - color_text=clWhite; - if (freqBrush->Style=bsClear; - c->Pen->Color=clSilver; - color_text=clSilver; - } - c->Ellipse(x[i]-d,y[i]-d,x[i]+d+1,y[i]+d+1); - c->Brush->Style=bsClear; - DrawText(c,x[i],y[i],s=id,color_text,0,0); +void __fastcall TMainForm::DrawSat(TCanvas *c, int w, int h, int x0, int y0, int index, int freq) { + static const TColor color_sys[] = {clGreen, (TColor)0xAAFF, clFuchsia, clBlue, + clRed, clTeal, clGray}; + TColor color_text; + UTF8String s; + TPoint p(w / 2, h / 2); + double r = MIN(w * 0.95, h * 0.95) / 2, azel[MAXSAT * 2], dop[4]; + int i, j, k, l, d, x[MAXSAT], y[MAXSAT], snr[NFREQ + 1], ns = 0; + char id[8], sys[] = "GREJCIS", *q; + + trace(4, "DrawSat: w=%d h=%d index=%d freq=%d\n", w, h, index, freq); + + DrawSky(c, w, h, x0, y0); + + for (i = 0, k = Nsat[index] - 1; i < Nsat[index] && i < MAXSAT; i++, k--) { + if (El[index][k] <= 0.0) continue; + for (j = snr[0] = 0; j < NFREQ; j++) { + snr[j + 1] = Snr[index][k][j]; + if ((freq && freq == j + 1) || ((!freq || freq > NFREQ) && snr[j + 1] > snr[0])) { + snr[0] = snr[j + 1]; // max snr + } } - c->Brush->Style=bsClear; - dops(ns,azel,0.0,dop); - DrawText(c,x0+3,y0+h,s.sprintf("#Sat:%2d/%2d",ns,Nsat[index]),clGray,1,1); - DrawText(c,x0+w-3,y0+h,s.sprintf("GDOP: %.1f",dop[0]),clGray,2,1); + if (Vsat[index][k] && (freq > NFREQ || snr[freq] > 0)) { + azel[ns * 2] = Az[index][k]; + azel[1 + ns * 2] = El[index][k]; + ns++; + } + satno2id(Sat[index][k], id); + l = (q = strchr(sys, id[0])) ? (int)(q - sys) : 6; + x[i] = (int)(p.x + r * (90 - El[index][k] * R2D) / 90 * sin(Az[index][k])) + x0; + y[i] = (int)(p.y - r * (90 - El[index][k] * R2D) / 90 * cos(Az[index][k])) + y0; + d = PanelFont->Size * 3 / 2; + c->Brush->Color = + !Vsat[index][k] ? clSilver : (freq < NFREQ + 1 ? SnrColor(snr[freq]) : color_sys[l]); + c->Brush->Style = bsSolid; + c->Pen->Color = clGray; + color_text = clWhite; + if (freq < NFREQ + 1 && snr[freq] <= 0) { + c->Brush->Style = bsClear; + c->Pen->Color = clSilver; + color_text = clSilver; + } + c->Ellipse(x[i] - d, y[i] - d, x[i] + d + 1, y[i] + d + 1); + c->Brush->Style = bsClear; + DrawText(c, x[i], y[i], s = id, color_text, 0, 0); + } + c->Brush->Style = bsClear; + dops(ns, azel, 0.0, dop); + DrawText(c, x0 + 3, y0 + h, s.sprintf("#Sat:%2d/%2d", ns, Nsat[index]), clGray, 1, 1); + DrawText(c, x0 + w - 3, y0 + h, s.sprintf("GDOP: %.1f", dop[0]), clGray, 2, 1); } // draw baseline plot ------------------------------------------------------- -void __fastcall TMainForm::DrawBL(TImage *plot, int w, int h) -{ - TCanvas *c=plot->Canvas; - TColor color[]={clSilver,clGreen,CLORANGE,clFuchsia,clBlue,clRed,clTeal}; - UTF8String s,label[]={"N","E","S","W"}; - TPoint p(w/2,h/2),p1,p2,pp; - double r=MIN(w*0.95,h*0.95)/2; - double *rr=SolRov+PSol*3,*rb=SolRef+PSol*3; - double bl[3]={0},pos[3],enu[3],len=0.0,pitch=0.0,yaw=0.0; - double cp,q,az=0.0; - TColor col=clWhite; - int i,d1=10,d2=16,d3=10,cy=0,sy=0,cya=0,sya=0,a,x1,x2,y1,y2,r1,digit,mode; - - trace(4,"DrawBL: w=%d h=%d\n",w,h); - - if (plot->Name=="Plot1") mode=BLMode1; - else if (plot->Name=="Plot2") mode=BLMode2; - else if (plot->Name=="Plot3") mode=BLMode3; - else mode=BLMode4; - - if (PMODE_DGPS<=PrcOpt.mode&&PrcOpt.mode<=PMODE_FIXED) { - col=rtksvr.state&&SolStat[PSol]&&SolCurrentStat?color[SolStat[PSol]]:clWhite; - - if (norm(rr,3)>0.0&&norm(rb,3)>0.0) { - for (i=0;i<3;i++) bl[i]=rr[i]-rb[i]; - } - if ((len=norm(bl,3))>0.0) { - ecef2pos(rb,pos); ecef2enu(pos,bl,enu); - pitch=asin(enu[2]/len); - yaw=atan2(enu[0],enu[1]); if (yaw<0.0) yaw+=2.0*PI; - if (mode) az=yaw; - } - } - if (len>=MINBLLEN) { - cp =cos(pitch); - cy =(int)((r-d1-d2/2)*cp*cos(yaw-az)); - sy =(int)((r-d1-d2/2)*cp*sin(yaw-az)); - cya=(int)(((r-d1-d2/2)*cp-d2/2-4)*cos(yaw-az)); - sya=(int)(((r-d1-d2/2)*cp-d2/2-4)*sin(yaw-az)); - } - p1.x=p.x-sy; p1.y=p.y+cy; // base - p2.x=p.x+sy; p2.y=p.y-cy; // rover - - c->Pen->Color=clGray; - c->Ellipse(p.x-r,p.y-r,p.x+r+1,p.y+r+1); - r1=(int)(r-d1/2); - c->Ellipse(p.x-r1,p.y-r1,p.x+r1+1,p.y+r1+1); - c->Brush->Style=bsSolid; - - pp=pitch<0.0?p2:p1; - c->Pen->Color=clSilver; - c->MoveTo(p.x,p.y); c->LineTo(pp.x,pp.y); - if (pitch<0.0) { - c->Brush->Color=clWhite; - c->Ellipse(pp.x-d2/2,pp.y-d2/2,pp.x+d2/2+1,pp.y+d2/2+1); - DrawArrow(c,p.x+sya,p.y-cya,d3,(int)((yaw-az)*R2D),clSilver); - } - c->Brush->Color=col; - c->Ellipse(pp.x-d2/2+2,pp.y-d2/2+2,pp.x+d2/2-1,pp.y+d2/2-1); - for (a=0;a<360;a+=5) { - q=a%90==0?0:(a%30==0?r-d1*3:(a%10==0?r-d1*2:r-d1)); - x1=(int)(r*sin(a*D2R-az)); - y1=(int)(r*cos(a*D2R-az)); - x2=(int)(q*sin(a*D2R-az)); - y2=(int)(q*cos(a*D2R-az)); - c->Pen->Color=clSilver; - c->MoveTo(p.x+x1,p.y-y1); - c->LineTo(p.x+x2,p.y-y2); - c->Brush->Color=clWhite; - if (a%90==0) { - DrawText(c,p.x+x1,p.y-y1,label[a/90],clGray,0,0); - } - if (a==0) { - x1=(int)((r-d1*3/2)*sin(a*D2R-az)); - y1=(int)((r-d1*3/2)*cos(a*D2R-az)); - DrawArrow(c,p.x+x1,p.y-y1,d3,-(int)(az*R2D),clSilver); - } - } - pp=pitch>=0.0?p2:p1; - c->Pen->Color=clGray; - c->MoveTo(p.x,p.y); c->LineTo(pp.x,pp.y); - if (pitch>=0.0) { - c->Brush->Color=clWhite; - c->Ellipse(pp.x-d2/2,pp.y-d2/2,pp.x+d2/2+1,pp.y+d2/2+1); - DrawArrow(c,p.x+sya,p.y-cya,d3,(int)((yaw-az)*R2D),clGray); - } - c->Brush->Color=col; - c->Ellipse(pp.x-d2/2+2,pp.y-d2/2+2,pp.x+d2/2-1,pp.y+d2/2-1); - c->Brush->Color=clWhite; - digit=len<1000.0?3:(len<10000.0?2:(len<100000.0?1:0)); - DrawText(c,p.x,p.y,s.sprintf("%.*f m",digit,len),clGray,0,0); - DrawText(c,3, h,s.sprintf("Y: %.1f%s",yaw*R2D,CHARDEG),clGray,1,1); - DrawText(c,w-3,h,s.sprintf("P: %.1f%s",pitch*R2D,CHARDEG),clGray,2,1); +void __fastcall TMainForm::DrawBL(TImage *plot, int w, int h) { + TCanvas *c = plot->Canvas; + TColor color[] = {clSilver, clGreen, CLORANGE, clFuchsia, clBlue, clRed, clTeal}; + UTF8String s, label[] = {"N", "E", "S", "W"}; + TPoint p(w / 2, h / 2), p1, p2, pp; + double r = MIN(w * 0.95, h * 0.95) / 2; + double *rr = SolRov + PSol * 3, *rb = SolRef + PSol * 3; + double bl[3] = {0}, pos[3], enu[3], len = 0.0, pitch = 0.0, yaw = 0.0; + double cp, q, az = 0.0; + TColor col = clWhite; + int i, d1 = 10, d2 = 16, d3 = 10, cy = 0, sy = 0, cya = 0, sya = 0, a, x1, x2, y1, y2, r1, digit, + mode; + + trace(4, "DrawBL: w=%d h=%d\n", w, h); + + if (plot->Name == "Plot1") + mode = BLMode1; + else if (plot->Name == "Plot2") + mode = BLMode2; + else if (plot->Name == "Plot3") + mode = BLMode3; + else + mode = BLMode4; + + if (PMODE_DGPS <= PrcOpt.mode && PrcOpt.mode <= PMODE_FIXED) { + col = rtksvr.state && SolStat[PSol] && SolCurrentStat ? color[SolStat[PSol]] : clWhite; + + if (norm(rr, 3) > 0.0 && norm(rb, 3) > 0.0) { + for (i = 0; i < 3; i++) bl[i] = rr[i] - rb[i]; + } + if ((len = norm(bl, 3)) > 0.0) { + ecef2pos(rb, pos); + ecef2enu(pos, bl, enu); + pitch = asin(enu[2] / len); + yaw = atan2(enu[0], enu[1]); + if (yaw < 0.0) yaw += 2.0 * PI; + if (mode) az = yaw; + } + } + if (len >= MINBLLEN) { + cp = cos(pitch); + cy = (int)((r - d1 - d2 / 2) * cp * cos(yaw - az)); + sy = (int)((r - d1 - d2 / 2) * cp * sin(yaw - az)); + cya = (int)(((r - d1 - d2 / 2) * cp - d2 / 2 - 4) * cos(yaw - az)); + sya = (int)(((r - d1 - d2 / 2) * cp - d2 / 2 - 4) * sin(yaw - az)); + } + p1.x = p.x - sy; + p1.y = p.y + cy; // base + p2.x = p.x + sy; + p2.y = p.y - cy; // rover + + c->Pen->Color = clGray; + c->Ellipse(p.x - r, p.y - r, p.x + r + 1, p.y + r + 1); + r1 = (int)(r - d1 / 2); + c->Ellipse(p.x - r1, p.y - r1, p.x + r1 + 1, p.y + r1 + 1); + c->Brush->Style = bsSolid; + + pp = pitch < 0.0 ? p2 : p1; + c->Pen->Color = clSilver; + c->MoveTo(p.x, p.y); + c->LineTo(pp.x, pp.y); + if (pitch < 0.0) { + c->Brush->Color = clWhite; + c->Ellipse(pp.x - d2 / 2, pp.y - d2 / 2, pp.x + d2 / 2 + 1, pp.y + d2 / 2 + 1); + DrawArrow(c, p.x + sya, p.y - cya, d3, (int)((yaw - az) * R2D), clSilver); + } + c->Brush->Color = col; + c->Ellipse(pp.x - d2 / 2 + 2, pp.y - d2 / 2 + 2, pp.x + d2 / 2 - 1, pp.y + d2 / 2 - 1); + for (a = 0; a < 360; a += 5) { + q = a % 90 == 0 ? 0 : (a % 30 == 0 ? r - d1 * 3 : (a % 10 == 0 ? r - d1 * 2 : r - d1)); + x1 = (int)(r * sin(a * D2R - az)); + y1 = (int)(r * cos(a * D2R - az)); + x2 = (int)(q * sin(a * D2R - az)); + y2 = (int)(q * cos(a * D2R - az)); + c->Pen->Color = clSilver; + c->MoveTo(p.x + x1, p.y - y1); + c->LineTo(p.x + x2, p.y - y2); + c->Brush->Color = clWhite; + if (a % 90 == 0) { + DrawText(c, p.x + x1, p.y - y1, label[a / 90], clGray, 0, 0); + } + if (a == 0) { + x1 = (int)((r - d1 * 3 / 2) * sin(a * D2R - az)); + y1 = (int)((r - d1 * 3 / 2) * cos(a * D2R - az)); + DrawArrow(c, p.x + x1, p.y - y1, d3, -(int)(az * R2D), clSilver); + } + } + pp = pitch >= 0.0 ? p2 : p1; + c->Pen->Color = clGray; + c->MoveTo(p.x, p.y); + c->LineTo(pp.x, pp.y); + if (pitch >= 0.0) { + c->Brush->Color = clWhite; + c->Ellipse(pp.x - d2 / 2, pp.y - d2 / 2, pp.x + d2 / 2 + 1, pp.y + d2 / 2 + 1); + DrawArrow(c, p.x + sya, p.y - cya, d3, (int)((yaw - az) * R2D), clGray); + } + c->Brush->Color = col; + c->Ellipse(pp.x - d2 / 2 + 2, pp.y - d2 / 2 + 2, pp.x + d2 / 2 - 1, pp.y + d2 / 2 - 1); + c->Brush->Color = clWhite; + digit = len < 1000.0 ? 3 : (len < 10000.0 ? 2 : (len < 100000.0 ? 1 : 0)); + DrawText(c, p.x, p.y, s.sprintf("%.*f m", digit, len), clGray, 0, 0); + DrawText(c, 3, h, s.sprintf("Y: %.1f%s", yaw * R2D, CHARDEG), clGray, 1, 1); + DrawText(c, w - 3, h, s.sprintf("P: %.1f%s", pitch * R2D, CHARDEG), clGray, 2, 1); } // draw track plot ---------------------------------------------------------- -void __fastcall TMainForm::DrawTrk(TImage *plot) -{ - TColor mcolor[]={clSilver,clGreen,CLORANGE,clFuchsia,clBlue,clRed,clTeal}; - TGraph *graph = new TGraph(plot); - TColor *c; - TPoint p1,p2; - UTF8String label; - double scale[]={ - 0.000021,0.000047,0.0001,0.00021,0.00047,0.001,0.0021,0.0047,0.01,0.021,0.047,0.1,0.21,0.47, - 1.0,2.1,4.7,10.0,21.0,47.0,100.0,210.0,470.0,1000.0,2100.0,4700.0, - 10000.0 - }; - double *x,*y,xt,yt,sx,sy,ref[3],pos[3],dr[3],enu[3]; - int i,j,k,n=0,type,scl; - - trace(3,"DrawTrk\n"); - - type=plot->Name=="Plot1"?TrkType1 :TrkType2 ; - scl =plot->Name=="Plot1"?TrkScale1:TrkScale2; - - x=new double[SolBuffSize]; - y=new double[SolBuffSize]; - c=new TColor[SolBuffSize]; - - if (norm(TrkOri,3)<1E-6) { - if (norm(SolRef+PSol*3,3)>1E-6) { - matcpy(TrkOri,SolRef+PSol*3,3,1); - } - else { - matcpy(TrkOri,SolRov+PSol*3,3,1); - } - } - if (norm(SolRef+PSol*3,3)>1E-6) { - matcpy(ref,SolRef+PSol*3,3,1); - } - else { - matcpy(ref,TrkOri,3,1); - } - ecef2pos(ref,pos); - for (i=k=PSolS;i!=PSolE;) { - for (j=0;j<3;j++) dr[j]=SolRov[j+i*3]-ref[j]; - if (i==PSol) k=n; - ecef2enu(pos,dr,enu); - x[n]=enu[0]; - y[n]=enu[1]; - c[n++]=mcolor[SolStat[i]]; - if (++i>=SolBuffSize) i=0; - } - graph->SetSize(plot->Parent->Width,plot->Parent->Height); - graph->SetScale(scale[scl],scale[scl]); - graph->Color[1]=clSilver; - - if (n>0) { - graph->SetCent(x[k],y[k]); - } - if (type==1) { - graph->XLPos=7; - graph->YLPos=7; - graph->DrawCircles(0); - } - else { - graph->XLPos=2; - graph->YLPos=4; - graph->DrawAxis(0,0); - } - graph->DrawPoly(x,y,n,clSilver,0); - graph->DrawMarks(x,y,c,n,0,3,0); - if (n>0) { - graph->ToPoint(x[k],y[k],p1); - graph->DrawMark(p1,0,clWhite,18,0); - graph->DrawMark(p1,1,rtksvr.state?clBlack:clGray,16,0); - graph->DrawMark(p1,5,rtksvr.state?clBlack:clGray,20,0); - graph->DrawMark(p1,0,rtksvr.state?clBlack:clGray,12,0); - graph->DrawMark(p1,0,rtksvr.state?c[k]:clWhite,10,0); - } - // scale - graph->GetPos(p1,p2); - graph->GetTick(xt,yt); - graph->GetScale(sx,sy); - p2.x-=35; - p2.y-=12; - graph->DrawMark(p2,11,clGray,(int)(xt/sx+0.5),0); - p2.y-=2; - if (xt<0.01 ) label.sprintf("%.0f mm",xt*1000.0); - else if (xt<1.0 ) label.sprintf("%.0f cm",xt*100.0); - else if (xt<1000.0) label.sprintf("%.0f m" ,xt); - else label.sprintf("%.0f km",xt/1000.0); - graph->DrawText(p2,label,clGray,clWhite,0,1,0); - - // ref position - if (norm(ref,3)>1E-6) { - p1.x+=2; - p1.y=p2.y+11; - label.sprintf("%.9f%s %.9f%s",pos[0]*R2D,CHARDEG,pos[1]*R2D,CHARDEG); - graph->DrawText(p1,label,clGray,clWhite,1,1,0); - } - delete graph; - delete [] x; - delete [] y; - delete [] c; +void __fastcall TMainForm::DrawTrk(TImage *plot) { + TColor mcolor[] = {clSilver, clGreen, CLORANGE, clFuchsia, clBlue, clRed, clTeal}; + TGraph *graph = new TGraph(plot); + TColor *c; + TPoint p1, p2; + UTF8String label; + double scale[] = {0.000021, 0.000047, 0.0001, 0.00021, 0.00047, 0.001, 0.0021, 0.0047, 0.01, + 0.021, 0.047, 0.1, 0.21, 0.47, 1.0, 2.1, 4.7, 10.0, + 21.0, 47.0, 100.0, 210.0, 470.0, 1000.0, 2100.0, 4700.0, 10000.0}; + double *x, *y, xt, yt, sx, sy, ref[3], pos[3], dr[3], enu[3]; + int i, j, k, n = 0, type, scl; + + trace(3, "DrawTrk\n"); + + type = plot->Name == "Plot1" ? TrkType1 : TrkType2; + scl = plot->Name == "Plot1" ? TrkScale1 : TrkScale2; + + x = new double[SolBuffSize]; + y = new double[SolBuffSize]; + c = new TColor[SolBuffSize]; + + if (norm(TrkOri, 3) < 1E-6) { + if (norm(SolRef + PSol * 3, 3) > 1E-6) { + matcpy(TrkOri, SolRef + PSol * 3, 3, 1); + } else { + matcpy(TrkOri, SolRov + PSol * 3, 3, 1); + } + } + if (norm(SolRef + PSol * 3, 3) > 1E-6) { + matcpy(ref, SolRef + PSol * 3, 3, 1); + } else { + matcpy(ref, TrkOri, 3, 1); + } + ecef2pos(ref, pos); + for (i = k = PSolS; i != PSolE;) { + for (j = 0; j < 3; j++) dr[j] = SolRov[j + i * 3] - ref[j]; + if (i == PSol) k = n; + ecef2enu(pos, dr, enu); + x[n] = enu[0]; + y[n] = enu[1]; + c[n++] = mcolor[SolStat[i]]; + if (++i >= SolBuffSize) i = 0; + } + graph->SetSize(plot->Parent->Width, plot->Parent->Height); + graph->SetScale(scale[scl], scale[scl]); + graph->Color[1] = clSilver; + + if (n > 0) { + graph->SetCent(x[k], y[k]); + } + if (type == 1) { + graph->XLPos = 7; + graph->YLPos = 7; + graph->DrawCircles(0); + } else { + graph->XLPos = 2; + graph->YLPos = 4; + graph->DrawAxis(0, 0); + } + graph->DrawPoly(x, y, n, clSilver, 0); + graph->DrawMarks(x, y, c, n, 0, 3, 0); + if (n > 0) { + graph->ToPoint(x[k], y[k], p1); + graph->DrawMark(p1, 0, clWhite, 18, 0); + graph->DrawMark(p1, 1, rtksvr.state ? clBlack : clGray, 16, 0); + graph->DrawMark(p1, 5, rtksvr.state ? clBlack : clGray, 20, 0); + graph->DrawMark(p1, 0, rtksvr.state ? clBlack : clGray, 12, 0); + graph->DrawMark(p1, 0, rtksvr.state ? c[k] : clWhite, 10, 0); + } + // scale + graph->GetPos(p1, p2); + graph->GetTick(xt, yt); + graph->GetScale(sx, sy); + p2.x -= 35; + p2.y -= 12; + graph->DrawMark(p2, 11, clGray, (int)(xt / sx + 0.5), 0); + p2.y -= 2; + if (xt < 0.01) + label.sprintf("%.0f mm", xt * 1000.0); + else if (xt < 1.0) + label.sprintf("%.0f cm", xt * 100.0); + else if (xt < 1000.0) + label.sprintf("%.0f m", xt); + else + label.sprintf("%.0f km", xt / 1000.0); + graph->DrawText(p2, label, clGray, clWhite, 0, 1, 0); + + // ref position + if (norm(ref, 3) > 1E-6) { + p1.x += 2; + p1.y = p2.y + 11; + label.sprintf("%.9f%s %.9f%s", pos[0] * R2D, CHARDEG, pos[1] * R2D, CHARDEG); + graph->DrawText(p1, label, clGray, clWhite, 1, 1, 0); + } + delete graph; + delete[] x; + delete[] y; + delete[] c; } // draw skyplot ------------------------------------------------------------- -void __fastcall TMainForm::DrawSky(TCanvas *c, int w, int h, int x0, int y0) -{ - UTF8String label[]={"N","E","S","W"}; - TPoint p(x0+w/2,y0+h/2); - double r=MIN(w*0.95,h*0.95)/2; - int a,e,d,x,y; - - c->Brush->Color=clWhite; - c->Brush->Style=bsSolid; - for (e=0;e<90;e+=30) { - d=(int)(r*(90-e)/90); - c->Pen->Color=e==0?clGray:clSilver; - c->Ellipse(p.x-d,p.y-d,p.x+d+1,p.y+d+1); - } - for (a=0;a<360;a+=45) { - x=(int)(r*sin(a*D2R)); - y=(int)(r*cos(a*D2R)); - c->Pen->Color=clSilver; - c->MoveTo(p.x,p.y); c->LineTo(p.x+x,p.y-y); - if (a%90==0) DrawText(c,p.x+x,p.y-y,label[a/90],clGray,0,0); - } +void __fastcall TMainForm::DrawSky(TCanvas *c, int w, int h, int x0, int y0) { + UTF8String label[] = {"N", "E", "S", "W"}; + TPoint p(x0 + w / 2, y0 + h / 2); + double r = MIN(w * 0.95, h * 0.95) / 2; + int a, e, d, x, y; + + c->Brush->Color = clWhite; + c->Brush->Style = bsSolid; + for (e = 0; e < 90; e += 30) { + d = (int)(r * (90 - e) / 90); + c->Pen->Color = e == 0 ? clGray : clSilver; + c->Ellipse(p.x - d, p.y - d, p.x + d + 1, p.y + d + 1); + } + for (a = 0; a < 360; a += 45) { + x = (int)(r * sin(a * D2R)); + y = (int)(r * cos(a * D2R)); + c->Pen->Color = clSilver; + c->MoveTo(p.x, p.y); + c->LineTo(p.x + x, p.y - y); + if (a % 90 == 0) DrawText(c, p.x + x, p.y - y, label[a / 90], clGray, 0, 0); + } } // draw text ---------------------------------------------------------------- -void __fastcall TMainForm::DrawText(TCanvas *c, int x, int y, UTF8String s, - TColor color, int ha, int va) -{ - // ha = horizontal alignment (0: center, 1: left, 2: right) - // va = vertical alignment (0: center, 1: bottom, 2: top ) - c->Font->Assign(PanelFont); - c->Font->Color=color; - TSize off=c->TextExtent(s); - if (ha==0) x-=off.cx/2; - else if (ha==2) x-=off.cx; - if (va==0) y-=off.cy/2; - else if (va==1) y-=off.cy; - c->TextOut(x,y,s); +void __fastcall TMainForm::DrawText(TCanvas *c, int x, int y, UTF8String s, TColor color, int ha, + int va) { + // ha = horizontal alignment (0: center, 1: left, 2: right) + // va = vertical alignment (0: center, 1: bottom, 2: top ) + c->Font->Assign(PanelFont); + c->Font->Color = color; + TSize off = c->TextExtent(s); + if (ha == 0) + x -= off.cx / 2; + else if (ha == 2) + x -= off.cx; + if (va == 0) + y -= off.cy / 2; + else if (va == 1) + y -= off.cy; + c->TextOut(x, y, s); } // draw arrow --------------------------------------------------------------- -void __fastcall TMainForm::DrawArrow(TCanvas *c, int x, int y, int siz, - int ang, TColor color) -{ - TPoint p1[4],p2[4]; - int i; - - p1[0].x=0; p1[1].x=siz/2; p1[2].x=-siz/2; p1[3].x=0; - p1[0].y=siz/2; p1[1].y=p1[2].y=-siz/2; p1[3].y=siz/2; - - for (i=0;i<4;i++) { - p2[i].x=x+(int)(p1[i].x*cos(-ang*D2R)-p1[i].y*sin(-ang*D2R)+0.5); - p2[i].y=y-(int)(p1[i].x*sin(-ang*D2R)+p1[i].y*cos(-ang*D2R)+0.5); - } - c->Brush->Style=bsSolid; - c->Brush->Color=color; - c->Pen->Color=color; - c->Polygon(p2,3); +void __fastcall TMainForm::DrawArrow(TCanvas *c, int x, int y, int siz, int ang, TColor color) { + TPoint p1[4], p2[4]; + int i; + + p1[0].x = 0; + p1[1].x = siz / 2; + p1[2].x = -siz / 2; + p1[3].x = 0; + p1[0].y = siz / 2; + p1[1].y = p1[2].y = -siz / 2; + p1[3].y = siz / 2; + + for (i = 0; i < 4; i++) { + p2[i].x = x + (int)(p1[i].x * cos(-ang * D2R) - p1[i].y * sin(-ang * D2R) + 0.5); + p2[i].y = y - (int)(p1[i].x * sin(-ang * D2R) + p1[i].y * cos(-ang * D2R) + 0.5); + } + c->Brush->Style = bsSolid; + c->Brush->Color = color; + c->Pen->Color = color; + c->Polygon(p2, 3); } // open monitor port -------------------------------------------------------- -void __fastcall TMainForm::OpenMoniPort(int port) -{ - AnsiString s; - int i; - char path[64]; - - if (port<=0) return; - - trace(3,"OpenMoniPort: port=%d\n",port); - - for (i=0;i<=MAXPORTOFF;i++) { - - sprintf(path,":%d",port+i); - - if (stropen(&monistr,STR_TCPSVR,STR_MODE_RW,path)) { - strsettimeout(&monistr,TimeoutTime,ReconTime); - if (i>0) Caption=s.sprintf("%s-%s %s (%d)",PRGNAME,VER_RTKLIB,PATCH_LEVEL,i+1); - OpenPort=port+i; - return; - } +void __fastcall TMainForm::OpenMoniPort(int port) { + AnsiString s; + int i; + char path[64]; + + if (port <= 0) return; + + trace(3, "OpenMoniPort: port=%d\n", port); + + for (i = 0; i <= MAXPORTOFF; i++) { + sprintf(path, ":%d", port + i); + + if (stropen(&monistr, STR_TCPSVR, STR_MODE_RW, path)) { + strsettimeout(&monistr, TimeoutTime, ReconTime); + if (i > 0) Caption = s.sprintf("%s-%s %s (%d)", PRGNAME, VER_RTKLIB, PATCH_LEVEL, i + 1); + OpenPort = port + i; + return; } - ShowMessage(s.sprintf("monitor port %d-%d open error",port,port+MAXPORTOFF)); - OpenPort=0; + } + ShowMessage(s.sprintf("monitor port %d-%d open error", port, port + MAXPORTOFF)); + OpenPort = 0; } // initialize solution buffer ----------------------------------------------- -void __fastcall TMainForm::InitSolBuff(void) -{ - double ep[]={2000,1,1,0,0,0}; - int i,j; - - trace(3,"InitSolBuff\n"); - - delete [] Time; delete [] SolStat; delete [] Nvsat; delete [] SolRov; - delete [] SolRef; delete [] Qr; delete [] VelRov; delete [] Age; - delete [] Ratio; - - if (SolBuffSize<=0) SolBuffSize=1; - Time =new gtime_t[SolBuffSize]; - SolStat=new int[SolBuffSize]; - Nvsat =new int[SolBuffSize]; - SolRov =new double[SolBuffSize*3]; - SolRef =new double[SolBuffSize*3]; - VelRov =new double[SolBuffSize*3]; - Qr =new double[SolBuffSize*9]; - Age =new double[SolBuffSize]; - Ratio =new double[SolBuffSize]; - PSol=PSolS=PSolE=0; - for (i=0;iMax=0; ScbSol->Position=0; +void __fastcall TMainForm::InitSolBuff(void) { + double ep[] = {2000, 1, 1, 0, 0, 0}; + int i, j; + + trace(3, "InitSolBuff\n"); + + delete[] Time; + delete[] SolStat; + delete[] Nvsat; + delete[] SolRov; + delete[] SolRef; + delete[] Qr; + delete[] VelRov; + delete[] Age; + delete[] Ratio; + + if (SolBuffSize <= 0) SolBuffSize = 1; + Time = new gtime_t[SolBuffSize]; + SolStat = new int[SolBuffSize]; + Nvsat = new int[SolBuffSize]; + SolRov = new double[SolBuffSize * 3]; + SolRef = new double[SolBuffSize * 3]; + VelRov = new double[SolBuffSize * 3]; + Qr = new double[SolBuffSize * 9]; + Age = new double[SolBuffSize]; + Ratio = new double[SolBuffSize]; + PSol = PSolS = PSolE = 0; + for (i = 0; i < SolBuffSize; i++) { + Time[i] = epoch2time(ep); + SolStat[i] = Nvsat[i] = 0; + for (j = 0; j < 3; j++) SolRov[j + i * 3] = SolRef[j + i * 3] = VelRov[j + i * 3] = 0.0; + for (j = 0; j < 9; j++) Qr[j + i * 9] = 0.0; + Age[i] = Ratio[i] = 0.0; + } + ScbSol->Max = 0; + ScbSol->Position = 0; } // save log file ------------------------------------------------------------ -void __fastcall TMainForm::SaveLog(void) -{ - AnsiString SaveDialog_FileName=SaveDialog->FileName; - FILE *fp; - int posf[]={SOLF_LLH,SOLF_LLH,SOLF_XYZ,SOLF_ENU,SOLF_ENU,SOLF_LLH}; - solopt_t opt; - sol_t sol={0}; - double ep[6],pos[3]; - char file[1024]; - int i; - - trace(3,"SaveLog\n"); - - time2epoch(timeget(),ep); - sprintf(file,"rtk_%04.0f%02.0f%02.0f%02.0f%02.0f%02.0f.txt", - ep[0],ep[1],ep[2],ep[3],ep[4],ep[5]); - SaveDialog->FileName=file; - if (!SaveDialog->Execute()) return; - if (!(fp=fopen(SaveDialog_FileName.c_str(),"wt"))) { - Message->Caption="log file open error"; - Message->Hint=Message->Caption; - return; - } - opt=SolOpt; - opt.posf=posf[SolType]; - if (SolOpt.outhead) { - fprintf(fp,"%% program : %s-%s %s\n",PRGNAME,VER_RTKLIB,PATCH_LEVEL); - if (PrcOpt.mode>=PMODE_DGPS && PrcOpt.mode<=PMODE_FIXED) { - ecef2pos(PrcOpt.rb,pos); - fprintf(fp,"%% ref pos :%13.9f %14.9f %10.4f\n",pos[0]*R2D, - pos[1]*R2D,pos[2]); - } - fprintf(fp,"%%\n"); - } - outsolhead(fp,&opt); - for (i=PSolS;i!=PSolE;) { - sol.time=Time[i]; - matcpy(sol.rr,SolRov+i*3,3,1); - sol.stat=SolStat[i]; - sol.ns=Nvsat[i]; - sol.ratio=Ratio[i]; - sol.age=Age[i]; - outsol(fp,&sol,SolRef+i*3,&opt); - if (++i>=SolBuffSize) i=0; - } - fclose(fp); +void __fastcall TMainForm::SaveLog(void) { + AnsiString SaveDialog_FileName = SaveDialog->FileName; + FILE *fp; + int posf[] = {SOLF_LLH, SOLF_LLH, SOLF_XYZ, SOLF_ENU, SOLF_ENU, SOLF_LLH}; + solopt_t opt; + sol_t sol = {0}; + double ep[6], pos[3]; + char file[1024]; + int i; + + trace(3, "SaveLog\n"); + + time2epoch(timeget(), ep); + sprintf(file, "rtk_%04.0f%02.0f%02.0f%02.0f%02.0f%02.0f.txt", ep[0], ep[1], ep[2], ep[3], ep[4], + ep[5]); + SaveDialog->FileName = file; + if (!SaveDialog->Execute()) return; + if (!(fp = fopen(SaveDialog_FileName.c_str(), "wt"))) { + Message->Caption = "log file open error"; + Message->Hint = Message->Caption; + return; + } + opt = SolOpt; + opt.posf = posf[SolType]; + if (SolOpt.outhead) { + fprintf(fp, "%% program : %s-%s %s\n", PRGNAME, VER_RTKLIB, PATCH_LEVEL); + if (PrcOpt.mode >= PMODE_DGPS && PrcOpt.mode <= PMODE_FIXED) { + ecef2pos(PrcOpt.rb, pos); + fprintf(fp, "%% ref pos :%13.9f %14.9f %10.4f\n", pos[0] * R2D, pos[1] * R2D, pos[2]); + } + fprintf(fp, "%%\n"); + } + outsolhead(fp, &opt); + for (i = PSolS; i != PSolE;) { + sol.time = Time[i]; + matcpy(sol.rr, SolRov + i * 3, 3, 1); + sol.stat = SolStat[i]; + sol.ns = Nvsat[i]; + sol.ratio = Ratio[i]; + sol.age = Age[i]; + outsol(fp, &sol, SolRef + i * 3, &opt); + if (++i >= SolBuffSize) i = 0; + } + fclose(fp); } // load navigation data ----------------------------------------------------- -void __fastcall TMainForm::LoadNav(nav_t *nav) -{ - TIniFile *ini=new TIniFile(IniFile); - AnsiString str,s; - eph_t eph0={0}; - char buff[2049],id[32],*p; - long toe_time,toc_time,ttr_time; - int i; - - trace(3,"LoadNav\n"); - - for (i=0;iReadString("navi",s.sprintf("eph_%02d",i),""))=="") continue; - nav->eph[i]=eph0; - strcpy(buff,str.c_str()); - if (!(p=strchr(buff,','))) continue; - *p='\0'; - if (!(nav->eph[i].sat=satid2no(buff))) continue; - sscanf(p+1,"%d,%d,%d,%d,%ld,%ld,%ld,%lf,%lf,%lf,%lf,%lf,%lf,%lf,%lf,%lf,%lf,%lf,%lf,%lf,%lf,%lf,%lf,%lf,%lf,%lf,%lf,%lf,%d,%d,%lf", - &nav->eph[i].iode, - &nav->eph[i].iodc, - &nav->eph[i].sva , - &nav->eph[i].svh , - &toe_time, - &toc_time, - &ttr_time, - &nav->eph[i].A , - &nav->eph[i].e , - &nav->eph[i].i0 , - &nav->eph[i].OMG0, - &nav->eph[i].omg , - &nav->eph[i].M0 , - &nav->eph[i].deln, - &nav->eph[i].OMGd, - &nav->eph[i].idot, - &nav->eph[i].crc , - &nav->eph[i].crs , - &nav->eph[i].cuc , - &nav->eph[i].cus , - &nav->eph[i].cic , - &nav->eph[i].cis , - &nav->eph[i].toes, - &nav->eph[i].fit , - &nav->eph[i].f0 , - &nav->eph[i].f1 , - &nav->eph[i].f2 , - &nav->eph[i].tgd[0], - &nav->eph[i].code, - &nav->eph[i].flag, - &nav->eph[i].tgd[1]); - nav->eph[i].toe.time=toe_time; - nav->eph[i].toc.time=toc_time; - nav->eph[i].ttr.time=ttr_time; - } - str=ini->ReadString("navi","ion",""); - for (i=0;i<8;i++) nav->ion_gps[i]=0.0; - sscanf(str.c_str(),"%lf,%lf,%lf,%lf,%lf,%lf,%lf,%lf", - nav->ion_gps ,nav->ion_gps+1,nav->ion_gps+2,nav->ion_gps+3, - nav->ion_gps+4,nav->ion_gps+5,nav->ion_gps+6,nav->ion_gps+7); - - str=ini->ReadString("navi","utc",""); - for (i=0;i<8;i++) nav->utc_gps[i]=0.0; - sscanf(str.c_str(),"%lf,%lf,%lf,%lf,%lf,%lf,%lf,%lf", - nav->utc_gps,nav->utc_gps+1,nav->utc_gps+2,nav->utc_gps+3, - nav->utc_gps+4,nav->utc_gps+5,nav->utc_gps+6,nav->utc_gps+7); - - delete ini; +void __fastcall TMainForm::LoadNav(nav_t *nav) { + TIniFile *ini = new TIniFile(IniFile); + AnsiString str, s; + eph_t eph0 = {0}; + char buff[2049], id[32], *p; + long toe_time, toc_time, ttr_time; + int i; + + trace(3, "LoadNav\n"); + + for (i = 0; i < MAXSAT * 2; i++) { + if ((str = ini->ReadString("navi", s.sprintf("eph_%02d", i), "")) == "") continue; + nav->eph[i] = eph0; + strcpy(buff, str.c_str()); + if (!(p = strchr(buff, ','))) continue; + *p = '\0'; + if (!(nav->eph[i].sat = satid2no(buff))) continue; + sscanf(p + 1, + "%d,%d,%d,%d,%ld,%ld,%ld,%lf,%lf,%lf,%lf,%lf,%lf,%lf,%lf,%lf,%lf,%lf,%lf,%lf,%lf,%lf,%" + "lf,%lf,%lf,%lf,%lf,%lf,%d,%d,%lf", + &nav->eph[i].iode, &nav->eph[i].iodc, &nav->eph[i].sva, &nav->eph[i].svh, &toe_time, + &toc_time, &ttr_time, &nav->eph[i].A, &nav->eph[i].e, &nav->eph[i].i0, &nav->eph[i].OMG0, + &nav->eph[i].omg, &nav->eph[i].M0, &nav->eph[i].deln, &nav->eph[i].OMGd, + &nav->eph[i].idot, &nav->eph[i].crc, &nav->eph[i].crs, &nav->eph[i].cuc, + &nav->eph[i].cus, &nav->eph[i].cic, &nav->eph[i].cis, &nav->eph[i].toes, + &nav->eph[i].fit, &nav->eph[i].f0, &nav->eph[i].f1, &nav->eph[i].f2, &nav->eph[i].tgd[0], + &nav->eph[i].code, &nav->eph[i].flag, &nav->eph[i].tgd[1]); + nav->eph[i].toe.time = toe_time; + nav->eph[i].toc.time = toc_time; + nav->eph[i].ttr.time = ttr_time; + } + str = ini->ReadString("navi", "ion", ""); + for (i = 0; i < 8; i++) nav->ion_gps[i] = 0.0; + sscanf(str.c_str(), "%lf,%lf,%lf,%lf,%lf,%lf,%lf,%lf", nav->ion_gps, nav->ion_gps + 1, + nav->ion_gps + 2, nav->ion_gps + 3, nav->ion_gps + 4, nav->ion_gps + 5, nav->ion_gps + 6, + nav->ion_gps + 7); + + str = ini->ReadString("navi", "utc", ""); + for (i = 0; i < 8; i++) nav->utc_gps[i] = 0.0; + sscanf(str.c_str(), "%lf,%lf,%lf,%lf,%lf,%lf,%lf,%lf", nav->utc_gps, nav->utc_gps + 1, + nav->utc_gps + 2, nav->utc_gps + 3, nav->utc_gps + 4, nav->utc_gps + 5, nav->utc_gps + 6, + nav->utc_gps + 7); + + delete ini; } // save navigation data ----------------------------------------------------- -void __fastcall TMainForm::SaveNav(nav_t *nav) -{ - TIniFile *ini=new TIniFile(IniFile); - AnsiString str,s; - char id[8]; - int i; - - trace(3,"SaveNav\n"); - - for (i=0;ieph[i].ttr.time==0) continue; - str=""; - satno2id(nav->eph[i].sat,id); - str=str+s.sprintf("%s,",id); - str=str+s.sprintf("%d,",nav->eph[i].iode); - str=str+s.sprintf("%d,",nav->eph[i].iodc); - str=str+s.sprintf("%d,",nav->eph[i].sva); - str=str+s.sprintf("%d,",nav->eph[i].svh); - str=str+s.sprintf("%d,",(int)nav->eph[i].toe.time); - str=str+s.sprintf("%d,",(int)nav->eph[i].toc.time); - str=str+s.sprintf("%d,",(int)nav->eph[i].ttr.time); - str=str+s.sprintf("%.14E,",nav->eph[i].A); - str=str+s.sprintf("%.14E,",nav->eph[i].e); - str=str+s.sprintf("%.14E,",nav->eph[i].i0); - str=str+s.sprintf("%.14E,",nav->eph[i].OMG0); - str=str+s.sprintf("%.14E,",nav->eph[i].omg); - str=str+s.sprintf("%.14E,",nav->eph[i].M0); - str=str+s.sprintf("%.14E,",nav->eph[i].deln); - str=str+s.sprintf("%.14E,",nav->eph[i].OMGd); - str=str+s.sprintf("%.14E,",nav->eph[i].idot); - str=str+s.sprintf("%.14E,",nav->eph[i].crc); - str=str+s.sprintf("%.14E,",nav->eph[i].crs); - str=str+s.sprintf("%.14E,",nav->eph[i].cuc); - str=str+s.sprintf("%.14E,",nav->eph[i].cus); - str=str+s.sprintf("%.14E,",nav->eph[i].cic); - str=str+s.sprintf("%.14E,",nav->eph[i].cis); - str=str+s.sprintf("%.14E,",nav->eph[i].toes); - str=str+s.sprintf("%.14E,",nav->eph[i].fit); - str=str+s.sprintf("%.14E,",nav->eph[i].f0); - str=str+s.sprintf("%.14E,",nav->eph[i].f1); - str=str+s.sprintf("%.14E,",nav->eph[i].f2); - str=str+s.sprintf("%.14E,",nav->eph[i].tgd[0]); - str=str+s.sprintf("%d,",nav->eph[i].code); - str=str+s.sprintf("%d,",nav->eph[i].flag); - str=str+s.sprintf("%.14E,",nav->eph[i].tgd[1]); - ini->WriteString("navi",s.sprintf("eph_%02d",i),str); - } - str=""; - for (i=0;i<8;i++) str=str+s.sprintf("%.14E,",nav->ion_gps[i]); - ini->WriteString("navi","ion",str); - - str=""; - for (i=0;i<8;i++) str=str+s.sprintf("%.14E,",nav->utc_gps[i]); - ini->WriteString("navi","utc",str); - - delete ini; +void __fastcall TMainForm::SaveNav(nav_t *nav) { + TIniFile *ini = new TIniFile(IniFile); + AnsiString str, s; + char id[8]; + int i; + + trace(3, "SaveNav\n"); + + for (i = 0; i < MAXSAT * 2; i++) { + if (nav->eph[i].ttr.time == 0) continue; + str = ""; + satno2id(nav->eph[i].sat, id); + str = str + s.sprintf("%s,", id); + str = str + s.sprintf("%d,", nav->eph[i].iode); + str = str + s.sprintf("%d,", nav->eph[i].iodc); + str = str + s.sprintf("%d,", nav->eph[i].sva); + str = str + s.sprintf("%d,", nav->eph[i].svh); + str = str + s.sprintf("%d,", (int)nav->eph[i].toe.time); + str = str + s.sprintf("%d,", (int)nav->eph[i].toc.time); + str = str + s.sprintf("%d,", (int)nav->eph[i].ttr.time); + str = str + s.sprintf("%.14E,", nav->eph[i].A); + str = str + s.sprintf("%.14E,", nav->eph[i].e); + str = str + s.sprintf("%.14E,", nav->eph[i].i0); + str = str + s.sprintf("%.14E,", nav->eph[i].OMG0); + str = str + s.sprintf("%.14E,", nav->eph[i].omg); + str = str + s.sprintf("%.14E,", nav->eph[i].M0); + str = str + s.sprintf("%.14E,", nav->eph[i].deln); + str = str + s.sprintf("%.14E,", nav->eph[i].OMGd); + str = str + s.sprintf("%.14E,", nav->eph[i].idot); + str = str + s.sprintf("%.14E,", nav->eph[i].crc); + str = str + s.sprintf("%.14E,", nav->eph[i].crs); + str = str + s.sprintf("%.14E,", nav->eph[i].cuc); + str = str + s.sprintf("%.14E,", nav->eph[i].cus); + str = str + s.sprintf("%.14E,", nav->eph[i].cic); + str = str + s.sprintf("%.14E,", nav->eph[i].cis); + str = str + s.sprintf("%.14E,", nav->eph[i].toes); + str = str + s.sprintf("%.14E,", nav->eph[i].fit); + str = str + s.sprintf("%.14E,", nav->eph[i].f0); + str = str + s.sprintf("%.14E,", nav->eph[i].f1); + str = str + s.sprintf("%.14E,", nav->eph[i].f2); + str = str + s.sprintf("%.14E,", nav->eph[i].tgd[0]); + str = str + s.sprintf("%d,", nav->eph[i].code); + str = str + s.sprintf("%d,", nav->eph[i].flag); + str = str + s.sprintf("%.14E,", nav->eph[i].tgd[1]); + ini->WriteString("navi", s.sprintf("eph_%02d", i), str); + } + str = ""; + for (i = 0; i < 8; i++) str = str + s.sprintf("%.14E,", nav->ion_gps[i]); + ini->WriteString("navi", "ion", str); + + str = ""; + for (i = 0; i < 8; i++) str = str + s.sprintf("%.14E,", nav->utc_gps[i]); + ini->WriteString("navi", "utc", str); + + delete ini; } // set tray icon ------------------------------------------------------------ -void __fastcall TMainForm::SetTrayIcon(int index) -{ - TIcon *icon=new TIcon; - ImageList->GetIcon(index,icon); - TrayIcon->Icon=icon; - delete icon; +void __fastcall TMainForm::SetTrayIcon(int index) { + TIcon *icon = new TIcon; + ImageList->GetIcon(index, icon); + TrayIcon->Icon = icon; + delete icon; } // load option from ini file ------------------------------------------------ -void __fastcall TMainForm::LoadOpt(void) -{ - TIniFile *ini=new TIniFile(IniFile); - AnsiString s; - int i,j,no,strno[]={0,1,6,2,3,4,5,7}; - char *p; - - trace(3,"LoadOpt\n"); - - for (i=0;i<8;i++) { - no=strno[i]; - StreamC[i]=ini->ReadInteger("stream",s.sprintf("streamc%d",no),0); - Stream [i]=ini->ReadInteger("stream",s.sprintf("stream%d", no),0); - Format [i]=ini->ReadInteger("stream",s.sprintf("format%d", no),0); - for (j=0;j<4;j++) { - Paths[i][j]=ini->ReadString("stream",s.sprintf("path_%d_%d",no,j),""); - } - } - for (i=0;i<3;i++) { - RcvOpt [i]=ini->ReadString("stream",s.sprintf("rcvopt%d",i+1),""); - } - for (i=0;i<3;i++) for (j=0;j<3;j++) { - Cmds[i][j]=ini->ReadString("serial",s.sprintf("cmd_%d_%d",i,j),""); - CmdEna[i][j]=ini->ReadInteger("serial",s.sprintf("cmdena_%d_%d",i,j),0); - for (p=Cmds[i][j].c_str();*p;p++) { - if ((p=strstr(p,"@@"))) strncpy(p,"\r\n",2); else break; - } - } - for (i=0;i<3;i++) for (j=0;j<3;j++) { - CmdsTcp[i][j]=ini->ReadString("tcpip",s.sprintf("cmd_%d_%d",i,j),""); - CmdEnaTcp[i][j]=ini->ReadInteger("tcpip",s.sprintf("cmdena_%d_%d",i,j),0); - for (p=CmdsTcp[i][j].c_str();*p;p++) { - if ((p=strstr(p,"@@"))) strncpy(p,"\r\n",2); else break; - } - } - PrcOpt.mode =ini->ReadInteger("prcopt", "mode", 2); - PrcOpt.nf =ini->ReadInteger("prcopt", "nf", NFREQ); - PrcOpt.elmin =ini->ReadFloat ("prcopt", "elmin", 15.0*D2R); - PrcOpt.snrmask.ena[0]=ini->ReadInteger("prcopt","snrmask_ena1",0); - PrcOpt.snrmask.ena[1]=ini->ReadInteger("prcopt","snrmask_ena2",0); - for (i=0;iReadFloat("prcopt",s.sprintf("snrmask_%d_%d",i+1,j+1),35.0); - } - PrcOpt.dynamics =ini->ReadInteger("prcopt", "dynamics", 1); - PrcOpt.tidecorr =ini->ReadInteger("prcopt", "tidecorr", 0); - PrcOpt.modear =ini->ReadInteger("prcopt", "modear", 1); - PrcOpt.glomodear=ini->ReadInteger("prcopt", "glomodear", 0); - PrcOpt.bdsmodear=ini->ReadInteger("prcopt", "bdsmodear", 1); - PrcOpt.maxout =ini->ReadInteger("prcopt", "maxout", 20); - PrcOpt.minlock =ini->ReadInteger("prcopt", "minlock", 0); - PrcOpt.minfix =ini->ReadInteger("prcopt", "minfix", 20); - PrcOpt.ionoopt =ini->ReadInteger("prcopt", "ionoopt",IONOOPT_BRDC); - PrcOpt.tropopt =ini->ReadInteger("prcopt", "tropopt",TROPOPT_SAAS); - PrcOpt.sateph =ini->ReadInteger("prcopt", "ephopt", EPHOPT_BRDC); - PrcOpt.armaxiter=ini->ReadInteger("prcopt", "ariter", 1); - PrcOpt.minfixsats=ini->ReadInteger("prcopt", "minfixsats", 4); - PrcOpt.minholdsats=ini->ReadInteger("prcopt", "minholdsats", 5); - PrcOpt.mindropsats=ini->ReadInteger("prcopt", "mindropsats", 10); - PrcOpt.niter =ini->ReadInteger("prcopt", "niter", 1); - PrcOpt.eratio[0]=ini->ReadFloat ("prcopt", "eratio0", 300.0); - PrcOpt.eratio[1]=ini->ReadFloat ("prcopt", "eratio1", 300.0); - PrcOpt.eratio[2]=ini->ReadFloat ("prcopt", "eratio2", 300.0); - PrcOpt.eratio[3]=ini->ReadFloat ("prcopt", "eratio3", 300.0); - PrcOpt.err[1] =ini->ReadFloat ("prcopt", "err1", 0.003); - PrcOpt.err[2] =ini->ReadFloat ("prcopt", "err2", 0.003); - PrcOpt.err[3] =ini->ReadFloat ("prcopt", "err3", 0.0); - PrcOpt.err[4] =ini->ReadFloat ("prcopt", "err4", 1.0); - PrcOpt.err[5] =ini->ReadFloat ("prcopt", "err5", 52.0); - PrcOpt.err[6] =ini->ReadFloat ("prcopt", "err6", 0.0); - PrcOpt.err[7] =ini->ReadFloat ("prcopt", "err7", 0.0); - PrcOpt.prn[0] =ini->ReadFloat ("prcopt", "prn0", 1E-4); - PrcOpt.prn[1] =ini->ReadFloat ("prcopt", "prn1", 1E-3); - PrcOpt.prn[2] =ini->ReadFloat ("prcopt", "prn2", 1E-4); - PrcOpt.prn[3] =ini->ReadFloat ("prcopt", "prn3", 3.0); - PrcOpt.prn[4] =ini->ReadFloat ("prcopt", "prn4", 1.0); - PrcOpt.sclkstab =ini->ReadFloat ("prcopt", "sclkstab", 5E-12); - PrcOpt.thresar[0]=ini->ReadFloat ("prcopt", "thresar", 3.0); - PrcOpt.thresar[5]=ini->ReadFloat ("prcopt", "thresarmin", 3.0); - PrcOpt.thresar[6]=ini->ReadFloat ("prcopt", "thresarmax", 3.0); - PrcOpt.thresar[1]=ini->ReadFloat ("prcopt", "thresar1", 0.1); - PrcOpt.thresar[2]=ini->ReadFloat ("prcopt", "thresar2", 0.0); - PrcOpt.thresar[3]=ini->ReadFloat ("prcopt", "thresar3", 1E-9); - PrcOpt.thresar[4]=ini->ReadFloat ("prcopt", "thresar4", 1E-5); - PrcOpt.elmaskar =ini->ReadFloat ("prcopt", "elmaskar", 15.0*D2R); - PrcOpt.elmaskhold=ini->ReadFloat ("prcopt", "elmaskhold",15.0*D2R); - PrcOpt.thresdop=ini->ReadFloat ("prcopt", "thresdop", 0.00); - PrcOpt.thresslip=ini->ReadFloat ("prcopt", "thresslip", 0.05); - PrcOpt.maxtdiff =ini->ReadFloat ("prcopt", "maxtdiff", 30.0); - PrcOpt.maxinno[0]=ini->ReadFloat ("prcopt", "maxphase", 5.0); - PrcOpt.maxinno[1]=ini->ReadFloat ("prcopt", "maxcode", 30.0); - PrcOpt.varholdamb=ini->ReadFloat ("prcopt", "varholdamb", 0.1); - PrcOpt.gainholdamb=ini->ReadFloat("prcopt", "gainholdamb", 0.01); - PrcOpt.syncsol =ini->ReadInteger("prcopt", "syncsol", 0); - PrcOpt.arfilter =ini->ReadInteger("prcopt", "arfilter", 1); - ExSats =ini->ReadString ("prcopt", "exsats", ""); - PrcOpt.navsys =ini->ReadInteger("prcopt", "navsys",SYS_GPS|SYS_GLO|SYS_GAL|SYS_QZS|SYS_CMP); - PrcOpt.posopt[0]=ini->ReadInteger("prcopt", "posopt1", 0); - PrcOpt.posopt[1]=ini->ReadInteger("prcopt", "posopt2", 0); - PrcOpt.posopt[2]=ini->ReadInteger("prcopt", "posopt3", 0); - PrcOpt.posopt[3]=ini->ReadInteger("prcopt", "posopt4", 0); - PrcOpt.posopt[4]=ini->ReadInteger("prcopt", "posopt5", 0); - PrcOpt.posopt[5]=ini->ReadInteger("prcopt", "posopt6", 0); - PrcOpt.maxaveep =ini->ReadInteger("prcopt", "maxaveep", 1); - PrcOpt.initrst =ini->ReadInteger("prcopt", "initrst", 1); - - BaselineC =ini->ReadInteger("prcopt", "baselinec", 0); - Baseline[0] =ini->ReadFloat ("prcopt", "baseline1", 0.0); - Baseline[1] =ini->ReadFloat ("prcopt", "baseline2", 0.0); - - SolOpt.posf =ini->ReadInteger("solopt", "posf", 0); - SolOpt.times =ini->ReadInteger("solopt", "times", 0); - SolOpt.timef =ini->ReadInteger("solopt", "timef", 1); - SolOpt.timeu =ini->ReadInteger("solopt", "timeu", 3); - SolOpt.degf =ini->ReadInteger("solopt", "degf", 0); - s=ini->ReadString("solopt","sep"," "); - strcpy(SolOpt.sep,s.c_str()); - SolOpt.outhead =ini->ReadInteger("solopt", "outhead", 1); - SolOpt.outopt =ini->ReadInteger("solopt", "outopt", 1); - SolOpt.outvel =ini->ReadInteger("solopt", "outvel", 0); - PrcOpt.outsingle=ini->ReadInteger("prcopt", "outsingle", 0); - SolOpt.maxsolstd=ini->ReadFloat ("solopt", "maxsolstd", 0.0); - SolOpt.datum =ini->ReadInteger("solopt", "datum", 0); - SolOpt.height =ini->ReadInteger("solopt", "height", 0); - SolOpt.geoid =ini->ReadInteger("solopt", "geoid", 0); - SolOpt.nmeaintv[0]=ini->ReadFloat("solopt", "nmeaintv1", 0.0); - SolOpt.nmeaintv[1]=ini->ReadFloat("solopt", "nmeaintv2", 0.0); - SolOpt.sstat =ini->ReadInteger("setting","debugstatus", 2); - SolOpt.trace =ini->ReadInteger("setting","debugtrace", 0); - - RovPosTypeF =ini->ReadInteger("setting","rovpostype", 0); - RefPosTypeF =ini->ReadInteger("setting","refpostype", 5); - RovAntPcvF =ini->ReadInteger("setting","rovantpcv", 0); - RefAntPcvF =ini->ReadInteger("setting","refantpcv", 0); - RovAntF =ini->ReadString ("setting","rovant", ""); - RefAntF =ini->ReadString ("setting","refant", ""); - SatPcvFileF =ini->ReadString ("setting","satpcvfile", ""); - AntPcvFileF =ini->ReadString ("setting","antpcvfile", ""); - StaPosFileF =ini->ReadString ("setting","staposfile", ""); - GeoidDataFileF =ini->ReadString ("setting","geoiddatafile", ""); - DCBFileF =ini->ReadString ("setting","dcbfile", ""); - EOPFileF =ini->ReadString ("setting","eopfile", ""); - LocalDirectory =ini->ReadString ("setting","localdirectory","C:\\Temp"); - - SvrCycle =ini->ReadInteger("setting","svrcycle", 10); - TimeoutTime =ini->ReadInteger("setting","timeouttime", 10000); - ReconTime =ini->ReadInteger("setting","recontime", 10000); - NmeaCycle =ini->ReadInteger("setting","nmeacycle", 5000); - SvrBuffSize =ini->ReadInteger("setting","svrbuffsize", 32768); - SolBuffSize =ini->ReadInteger("setting","solbuffsize", 1000); - SavedSol =ini->ReadInteger("setting","savedsol", 100); - NavSelect =ini->ReadInteger("setting","navselect", 0); - PrcOpt.sbassatsel=ini->ReadInteger("setting","sbassat", 0); - DgpsCorr =ini->ReadInteger("setting","dgpscorr", 0); - SbasCorr =ini->ReadInteger("setting","sbascorr", 0); - - NmeaReq =ini->ReadInteger("setting","nmeareq", 0); - InTimeTag =ini->ReadInteger("setting","intimetag", 0); - InTimeSpeed =ini->ReadString ("setting","intimespeed", "x1"); - InTimeStart =ini->ReadString ("setting","intimestart", "0"); - InTime64Bit =ini->ReadInteger("setting","intime64bit", 0); - OutTimeTag =ini->ReadInteger("setting","outtimetag", 0); - OutAppend =ini->ReadInteger("setting","outappend", 0); - OutSwapInterval =ini->ReadString ("setting","outswapinterval",""); - LogTimeTag =ini->ReadInteger("setting","logtimetag", 0); - LogAppend =ini->ReadInteger("setting","logappend", 0); - LogSwapInterval =ini->ReadString ("setting","logswapinterval",""); - NmeaPos[0] =ini->ReadFloat ("setting","nmeapos1", 0.0); - NmeaPos[1] =ini->ReadFloat ("setting","nmeapos2", 0.0); - NmeaPos[2] =ini->ReadFloat ("setting","nmeapos3", 0.0); - ResetCmd =ini->ReadString ("setting","resetcmd", ""); - MaxBL =ini->ReadFloat ("setting","maxbl", 10.0); - FileSwapMargin =ini->ReadInteger("setting","fswapmargin", 30); - - TimeSys =ini->ReadInteger("setting","timesys", 0); - SolType =ini->ReadInteger("setting","soltype", 3); - PlotType1 =ini->ReadInteger("setting","plottype", 0); - PlotType2 =ini->ReadInteger("setting","plottype2", 6); - PlotType3 =ini->ReadInteger("setting","plottype3", 0); - PlotType4 =ini->ReadInteger("setting","plottype4", 0); - PanelMode =ini->ReadInteger("setting","panelmode", 1); - ProxyAddr =ini->ReadString ("setting","proxyaddr", ""); - MoniPort =ini->ReadInteger("setting","moniport",DEFAULTPORT); - PanelStack =ini->ReadInteger("setting","panelstack", 0); - TrkType1 =ini->ReadInteger("setting","trktype1", 0); - TrkType2 =ini->ReadInteger("setting","trktype2", 0); - TrkType3 =ini->ReadInteger("setting","trktype3", 0); - TrkType4 =ini->ReadInteger("setting","trktype4", 0); - TrkScale1 =ini->ReadInteger("setting","trkscale1", 5); - TrkScale2 =ini->ReadInteger("setting","trkscale2", 5); - TrkScale3 =ini->ReadInteger("setting","trkscale3", 5); - TrkScale4 =ini->ReadInteger("setting","trkscale4", 5); - FreqType1 =ini->ReadInteger("setting","freqtype1", 0); - FreqType2 =ini->ReadInteger("setting","freqtype2", 0); - FreqType3 =ini->ReadInteger("setting","freqtype3", 0); - FreqType4 =ini->ReadInteger("setting","freqtype4", 0); - BLMode1 =ini->ReadInteger("setting","blmode1", 0); - BLMode2 =ini->ReadInteger("setting","blmode2", 0); - BLMode3 =ini->ReadInteger("setting","blmode3", 0); - BLMode4 =ini->ReadInteger("setting","blmode4", 0); - MarkerName =ini->ReadString ("setting","markername", ""); - MarkerComment =ini->ReadString ("setting","markercomment", ""); - - for (i=0;i<3;i++) { - RovAntDel[i]=ini->ReadFloat("setting",s.sprintf("rovantdel_%d",i),0.0); - RefAntDel[i]=ini->ReadFloat("setting",s.sprintf("refantdel_%d",i),0.0); - RovPos [i]=ini->ReadFloat("setting",s.sprintf("rovpos_%d", i),0.0); - RefPos [i]=ini->ReadFloat("setting",s.sprintf("refpos_%d", i),0.0); - } - for (i=0;i<10;i++) { - History[i]=ini->ReadString ("tcpopt",s.sprintf("history%d", i),""); - } - NMapPnt =ini->ReadInteger("mapopt","nmappnt",0); - for (i=0;iReadString("mapopt",s.sprintf("pntname%d",i+1),""); - AnsiString pos=ini->ReadString("mapopt",s.sprintf("pntpos%d",i+1),"0,0,0"); - PntPos[i][0]=PntPos[i][1]=PntPos[i][2]=0.0; - sscanf(pos.c_str(),"%lf,%lf,%lf",PntPos[i],PntPos[i]+1,PntPos[i]+2); - } - PanelFont->Name=ini->ReadString ("setting","panelfontname",PANELFONTNAME); - PanelFont->Size=ini->ReadInteger("setting","panelfontsize",PANELFONTSIZE); - PanelFont->Color=(TColor)ini->ReadInteger("setting","panelfontcolor",(int)clBlack); - PosFont->Name=ini->ReadString ("setting","posfontname",POSFONTNAME); - PosFont->Size=ini->ReadInteger("setting","posfontsize",POSFONTSIZE); - PosFont->Color=(TColor)ini->ReadInteger("setting","posfontcolor",(int)clBlack); - if (ini->ReadInteger("setting","posfontbold", 0)) PosFont->Style=PosFont->Style<ReadInteger("setting","posfontitalic",0)) PosFont->Style=PosFont->Style<Charset=ANSI_CHARSET; - PosFont->Charset=ANSI_CHARSET; - - TTextViewer::Color1=(TColor)ini->ReadInteger("viewer","color1",(int)clBlack); - TTextViewer::Color2=(TColor)ini->ReadInteger("viewer","color2",(int)clWhite); - TTextViewer::FontD=new TFont; - TTextViewer::FontD->Name=ini->ReadString ("viewer","fontname","Courier New"); - TTextViewer::FontD->Size=ini->ReadInteger("viewer","fontsize",9); - - UpdatePanel(); - - if (PanelStack==0) { - Panel21->Width=ini->ReadInteger("window","splitpos" ,185); - Panel22->Width=ini->ReadInteger("window","splitpos1",247); - Panel23->Width=ini->ReadInteger("window","splitpos2",262); - Panel24->Width=ini->ReadInteger("window","splitpos3",185); - Panel25->Width=ini->ReadInteger("window","splitpos4",185); - Panel21->Height=185; - Panel22->Height=185; - Panel23->Height=185; - Panel24->Height=185; - Panel25->Height=185; +void __fastcall TMainForm::LoadOpt(void) { + TIniFile *ini = new TIniFile(IniFile); + AnsiString s; + int i, j, no, strno[] = {0, 1, 6, 2, 3, 4, 5, 7}; + char *p; + + trace(3, "LoadOpt\n"); + + for (i = 0; i < 8; i++) { + no = strno[i]; + StreamC[i] = ini->ReadInteger("stream", s.sprintf("streamc%d", no), 0); + Stream[i] = ini->ReadInteger("stream", s.sprintf("stream%d", no), 0); + Format[i] = ini->ReadInteger("stream", s.sprintf("format%d", no), 0); + for (j = 0; j < 4; j++) { + Paths[i][j] = ini->ReadString("stream", s.sprintf("path_%d_%d", no, j), ""); + } + } + for (i = 0; i < 3; i++) { + RcvOpt[i] = ini->ReadString("stream", s.sprintf("rcvopt%d", i + 1), ""); + } + for (i = 0; i < 3; i++) + for (j = 0; j < 3; j++) { + Cmds[i][j] = ini->ReadString("serial", s.sprintf("cmd_%d_%d", i, j), ""); + CmdEna[i][j] = ini->ReadInteger("serial", s.sprintf("cmdena_%d_%d", i, j), 0); + for (p = Cmds[i][j].c_str(); *p; p++) { + if ((p = strstr(p, "@@"))) + strncpy(p, "\r\n", 2); + else + break; + } } - else { - Panel21->Height=ini->ReadInteger("window","splitpos" ,185); - Panel22->Height=ini->ReadInteger("window","splitpos1",247); - Panel23->Height=ini->ReadInteger("window","splitpos2",262); - Panel24->Height=ini->ReadInteger("window","splitpos3",185); - Panel25->Height=ini->ReadInteger("window","splitpos4",185); - Panel21->Width=185; - Panel22->Width=185; - Panel23->Width=185; - Panel24->Width=185; + for (i = 0; i < 3; i++) + for (j = 0; j < 3; j++) { + CmdsTcp[i][j] = ini->ReadString("tcpip", s.sprintf("cmd_%d_%d", i, j), ""); + CmdEnaTcp[i][j] = ini->ReadInteger("tcpip", s.sprintf("cmdena_%d_%d", i, j), 0); + for (p = CmdsTcp[i][j].c_str(); *p; p++) { + if ((p = strstr(p, "@@"))) + strncpy(p, "\r\n", 2); + else + break; + } } - Width =ini->ReadInteger("window","width", 724); - Height =ini->ReadInteger("window","height", 570); - delete ini; + PrcOpt.mode = ini->ReadInteger("prcopt", "mode", 2); + PrcOpt.nf = ini->ReadInteger("prcopt", "nf", NFREQ); + PrcOpt.elmin = ini->ReadFloat("prcopt", "elmin", 15.0 * D2R); + PrcOpt.snrmask.ena[0] = ini->ReadInteger("prcopt", "snrmask_ena1", 0); + PrcOpt.snrmask.ena[1] = ini->ReadInteger("prcopt", "snrmask_ena2", 0); + for (i = 0; i < NFREQ; i++) + for (j = 0; j < 9; j++) { + PrcOpt.snrmask.mask[i][j] = + ini->ReadFloat("prcopt", s.sprintf("snrmask_%d_%d", i + 1, j + 1), 35.0); + } + PrcOpt.dynamics = ini->ReadInteger("prcopt", "dynamics", 1); + PrcOpt.tidecorr = ini->ReadInteger("prcopt", "tidecorr", 0); + PrcOpt.modear = ini->ReadInteger("prcopt", "modear", 1); + PrcOpt.glomodear = ini->ReadInteger("prcopt", "glomodear", 0); + PrcOpt.bdsmodear = ini->ReadInteger("prcopt", "bdsmodear", 1); + PrcOpt.maxout = ini->ReadInteger("prcopt", "maxout", 20); + PrcOpt.minlock = ini->ReadInteger("prcopt", "minlock", 0); + PrcOpt.minfix = ini->ReadInteger("prcopt", "minfix", 20); + PrcOpt.ionoopt = ini->ReadInteger("prcopt", "ionoopt", IONOOPT_BRDC); + PrcOpt.tropopt = ini->ReadInteger("prcopt", "tropopt", TROPOPT_SAAS); + PrcOpt.sateph = ini->ReadInteger("prcopt", "ephopt", EPHOPT_BRDC); + PrcOpt.armaxiter = ini->ReadInteger("prcopt", "ariter", 1); + PrcOpt.minfixsats = ini->ReadInteger("prcopt", "minfixsats", 4); + PrcOpt.minholdsats = ini->ReadInteger("prcopt", "minholdsats", 5); + PrcOpt.mindropsats = ini->ReadInteger("prcopt", "mindropsats", 10); + PrcOpt.niter = ini->ReadInteger("prcopt", "niter", 1); + PrcOpt.eratio[0] = ini->ReadFloat("prcopt", "eratio0", 300.0); + PrcOpt.eratio[1] = ini->ReadFloat("prcopt", "eratio1", 300.0); + PrcOpt.eratio[2] = ini->ReadFloat("prcopt", "eratio2", 300.0); + PrcOpt.eratio[3] = ini->ReadFloat("prcopt", "eratio3", 300.0); + PrcOpt.err[1] = ini->ReadFloat("prcopt", "err1", 0.003); + PrcOpt.err[2] = ini->ReadFloat("prcopt", "err2", 0.003); + PrcOpt.err[3] = ini->ReadFloat("prcopt", "err3", 0.0); + PrcOpt.err[4] = ini->ReadFloat("prcopt", "err4", 1.0); + PrcOpt.err[5] = ini->ReadFloat("prcopt", "err5", 52.0); + PrcOpt.err[6] = ini->ReadFloat("prcopt", "err6", 0.0); + PrcOpt.err[7] = ini->ReadFloat("prcopt", "err7", 0.0); + PrcOpt.prn[0] = ini->ReadFloat("prcopt", "prn0", 1E-4); + PrcOpt.prn[1] = ini->ReadFloat("prcopt", "prn1", 1E-3); + PrcOpt.prn[2] = ini->ReadFloat("prcopt", "prn2", 1E-4); + PrcOpt.prn[3] = ini->ReadFloat("prcopt", "prn3", 3.0); + PrcOpt.prn[4] = ini->ReadFloat("prcopt", "prn4", 1.0); + PrcOpt.sclkstab = ini->ReadFloat("prcopt", "sclkstab", 5E-12); + PrcOpt.thresar[0] = ini->ReadFloat("prcopt", "thresar", 3.0); + PrcOpt.thresar[5] = ini->ReadFloat("prcopt", "thresarmin", 3.0); + PrcOpt.thresar[6] = ini->ReadFloat("prcopt", "thresarmax", 3.0); + PrcOpt.thresar[1] = ini->ReadFloat("prcopt", "thresar1", 0.1); + PrcOpt.thresar[2] = ini->ReadFloat("prcopt", "thresar2", 0.0); + PrcOpt.thresar[3] = ini->ReadFloat("prcopt", "thresar3", 1E-9); + PrcOpt.thresar[4] = ini->ReadFloat("prcopt", "thresar4", 1E-5); + PrcOpt.elmaskar = ini->ReadFloat("prcopt", "elmaskar", 15.0 * D2R); + PrcOpt.elmaskhold = ini->ReadFloat("prcopt", "elmaskhold", 15.0 * D2R); + PrcOpt.thresdop = ini->ReadFloat("prcopt", "thresdop", 0.00); + PrcOpt.thresslip = ini->ReadFloat("prcopt", "thresslip", 0.05); + PrcOpt.maxtdiff = ini->ReadFloat("prcopt", "maxtdiff", 30.0); + PrcOpt.maxinno[0] = ini->ReadFloat("prcopt", "maxphase", 5.0); + PrcOpt.maxinno[1] = ini->ReadFloat("prcopt", "maxcode", 30.0); + PrcOpt.varholdamb = ini->ReadFloat("prcopt", "varholdamb", 0.1); + PrcOpt.gainholdamb = ini->ReadFloat("prcopt", "gainholdamb", 0.01); + PrcOpt.syncsol = ini->ReadInteger("prcopt", "syncsol", 0); + PrcOpt.arfilter = ini->ReadInteger("prcopt", "arfilter", 1); + ExSats = ini->ReadString("prcopt", "exsats", ""); + PrcOpt.navsys = + ini->ReadInteger("prcopt", "navsys", SYS_GPS | SYS_GLO | SYS_GAL | SYS_QZS | SYS_CMP); + PrcOpt.posopt[0] = ini->ReadInteger("prcopt", "posopt1", 0); + PrcOpt.posopt[1] = ini->ReadInteger("prcopt", "posopt2", 0); + PrcOpt.posopt[2] = ini->ReadInteger("prcopt", "posopt3", 0); + PrcOpt.posopt[3] = ini->ReadInteger("prcopt", "posopt4", 0); + PrcOpt.posopt[4] = ini->ReadInteger("prcopt", "posopt5", 0); + PrcOpt.posopt[5] = ini->ReadInteger("prcopt", "posopt6", 0); + PrcOpt.maxaveep = ini->ReadInteger("prcopt", "maxaveep", 1); + PrcOpt.initrst = ini->ReadInteger("prcopt", "initrst", 1); + + BaselineC = ini->ReadInteger("prcopt", "baselinec", 0); + Baseline[0] = ini->ReadFloat("prcopt", "baseline1", 0.0); + Baseline[1] = ini->ReadFloat("prcopt", "baseline2", 0.0); + + SolOpt.posf = ini->ReadInteger("solopt", "posf", 0); + SolOpt.times = ini->ReadInteger("solopt", "times", 0); + SolOpt.timef = ini->ReadInteger("solopt", "timef", 1); + SolOpt.timeu = ini->ReadInteger("solopt", "timeu", 3); + SolOpt.degf = ini->ReadInteger("solopt", "degf", 0); + s = ini->ReadString("solopt", "sep", " "); + strcpy(SolOpt.sep, s.c_str()); + SolOpt.outhead = ini->ReadInteger("solopt", "outhead", 1); + SolOpt.outopt = ini->ReadInteger("solopt", "outopt", 1); + SolOpt.outvel = ini->ReadInteger("solopt", "outvel", 0); + PrcOpt.outsingle = ini->ReadInteger("prcopt", "outsingle", 0); + SolOpt.maxsolstd = ini->ReadFloat("solopt", "maxsolstd", 0.0); + SolOpt.datum = ini->ReadInteger("solopt", "datum", 0); + SolOpt.height = ini->ReadInteger("solopt", "height", 0); + SolOpt.geoid = ini->ReadInteger("solopt", "geoid", 0); + SolOpt.nmeaintv[0] = ini->ReadFloat("solopt", "nmeaintv1", 0.0); + SolOpt.nmeaintv[1] = ini->ReadFloat("solopt", "nmeaintv2", 0.0); + SolOpt.sstat = ini->ReadInteger("setting", "debugstatus", 2); + SolOpt.trace = ini->ReadInteger("setting", "debugtrace", 0); + + RovPosTypeF = ini->ReadInteger("setting", "rovpostype", 0); + RefPosTypeF = ini->ReadInteger("setting", "refpostype", 5); + RovAntPcvF = ini->ReadInteger("setting", "rovantpcv", 0); + RefAntPcvF = ini->ReadInteger("setting", "refantpcv", 0); + RovAntF = ini->ReadString("setting", "rovant", ""); + RefAntF = ini->ReadString("setting", "refant", ""); + SatPcvFileF = ini->ReadString("setting", "satpcvfile", ""); + AntPcvFileF = ini->ReadString("setting", "antpcvfile", ""); + StaPosFileF = ini->ReadString("setting", "staposfile", ""); + GeoidDataFileF = ini->ReadString("setting", "geoiddatafile", ""); + DCBFileF = ini->ReadString("setting", "dcbfile", ""); + EOPFileF = ini->ReadString("setting", "eopfile", ""); + LocalDirectory = ini->ReadString("setting", "localdirectory", "C:\\Temp"); + + SvrCycle = ini->ReadInteger("setting", "svrcycle", 10); + TimeoutTime = ini->ReadInteger("setting", "timeouttime", 10000); + ReconTime = ini->ReadInteger("setting", "recontime", 10000); + NmeaCycle = ini->ReadInteger("setting", "nmeacycle", 5000); + SvrBuffSize = ini->ReadInteger("setting", "svrbuffsize", 32768); + SolBuffSize = ini->ReadInteger("setting", "solbuffsize", 1000); + SavedSol = ini->ReadInteger("setting", "savedsol", 100); + NavSelect = ini->ReadInteger("setting", "navselect", 0); + PrcOpt.sbassatsel = ini->ReadInteger("setting", "sbassat", 0); + DgpsCorr = ini->ReadInteger("setting", "dgpscorr", 0); + SbasCorr = ini->ReadInteger("setting", "sbascorr", 0); + + NmeaReq = ini->ReadInteger("setting", "nmeareq", 0); + InTimeTag = ini->ReadInteger("setting", "intimetag", 0); + InTimeSpeed = ini->ReadString("setting", "intimespeed", "x1"); + InTimeStart = ini->ReadString("setting", "intimestart", "0"); + InTime64Bit = ini->ReadInteger("setting", "intime64bit", 0); + OutTimeTag = ini->ReadInteger("setting", "outtimetag", 0); + OutAppend = ini->ReadInteger("setting", "outappend", 0); + OutSwapInterval = ini->ReadString("setting", "outswapinterval", ""); + LogTimeTag = ini->ReadInteger("setting", "logtimetag", 0); + LogAppend = ini->ReadInteger("setting", "logappend", 0); + LogSwapInterval = ini->ReadString("setting", "logswapinterval", ""); + NmeaPos[0] = ini->ReadFloat("setting", "nmeapos1", 0.0); + NmeaPos[1] = ini->ReadFloat("setting", "nmeapos2", 0.0); + NmeaPos[2] = ini->ReadFloat("setting", "nmeapos3", 0.0); + ResetCmd = ini->ReadString("setting", "resetcmd", ""); + MaxBL = ini->ReadFloat("setting", "maxbl", 10.0); + FileSwapMargin = ini->ReadInteger("setting", "fswapmargin", 30); + + TimeSys = ini->ReadInteger("setting", "timesys", 0); + SolType = ini->ReadInteger("setting", "soltype", 3); + PlotType1 = ini->ReadInteger("setting", "plottype", 0); + PlotType2 = ini->ReadInteger("setting", "plottype2", 6); + PlotType3 = ini->ReadInteger("setting", "plottype3", 0); + PlotType4 = ini->ReadInteger("setting", "plottype4", 0); + PanelMode = ini->ReadInteger("setting", "panelmode", 1); + ProxyAddr = ini->ReadString("setting", "proxyaddr", ""); + MoniPort = ini->ReadInteger("setting", "moniport", DEFAULTPORT); + PanelStack = ini->ReadInteger("setting", "panelstack", 0); + TrkType1 = ini->ReadInteger("setting", "trktype1", 0); + TrkType2 = ini->ReadInteger("setting", "trktype2", 0); + TrkType3 = ini->ReadInteger("setting", "trktype3", 0); + TrkType4 = ini->ReadInteger("setting", "trktype4", 0); + TrkScale1 = ini->ReadInteger("setting", "trkscale1", 5); + TrkScale2 = ini->ReadInteger("setting", "trkscale2", 5); + TrkScale3 = ini->ReadInteger("setting", "trkscale3", 5); + TrkScale4 = ini->ReadInteger("setting", "trkscale4", 5); + FreqType1 = ini->ReadInteger("setting", "freqtype1", 0); + FreqType2 = ini->ReadInteger("setting", "freqtype2", 0); + FreqType3 = ini->ReadInteger("setting", "freqtype3", 0); + FreqType4 = ini->ReadInteger("setting", "freqtype4", 0); + BLMode1 = ini->ReadInteger("setting", "blmode1", 0); + BLMode2 = ini->ReadInteger("setting", "blmode2", 0); + BLMode3 = ini->ReadInteger("setting", "blmode3", 0); + BLMode4 = ini->ReadInteger("setting", "blmode4", 0); + MarkerName = ini->ReadString("setting", "markername", ""); + MarkerComment = ini->ReadString("setting", "markercomment", ""); + + for (i = 0; i < 3; i++) { + RovAntDel[i] = ini->ReadFloat("setting", s.sprintf("rovantdel_%d", i), 0.0); + RefAntDel[i] = ini->ReadFloat("setting", s.sprintf("refantdel_%d", i), 0.0); + RovPos[i] = ini->ReadFloat("setting", s.sprintf("rovpos_%d", i), 0.0); + RefPos[i] = ini->ReadFloat("setting", s.sprintf("refpos_%d", i), 0.0); + } + for (i = 0; i < 10; i++) { + History[i] = ini->ReadString("tcpopt", s.sprintf("history%d", i), ""); + } + NMapPnt = ini->ReadInteger("mapopt", "nmappnt", 0); + for (i = 0; i < NMapPnt; i++) { + PntName[i] = ini->ReadString("mapopt", s.sprintf("pntname%d", i + 1), ""); + AnsiString pos = ini->ReadString("mapopt", s.sprintf("pntpos%d", i + 1), "0,0,0"); + PntPos[i][0] = PntPos[i][1] = PntPos[i][2] = 0.0; + sscanf(pos.c_str(), "%lf,%lf,%lf", PntPos[i], PntPos[i] + 1, PntPos[i] + 2); + } + PanelFont->Name = ini->ReadString("setting", "panelfontname", PANELFONTNAME); + PanelFont->Size = ini->ReadInteger("setting", "panelfontsize", PANELFONTSIZE); + PanelFont->Color = (TColor)ini->ReadInteger("setting", "panelfontcolor", (int)clBlack); + PosFont->Name = ini->ReadString("setting", "posfontname", POSFONTNAME); + PosFont->Size = ini->ReadInteger("setting", "posfontsize", POSFONTSIZE); + PosFont->Color = (TColor)ini->ReadInteger("setting", "posfontcolor", (int)clBlack); + if (ini->ReadInteger("setting", "posfontbold", 0)) PosFont->Style = PosFont->Style << fsBold; + if (ini->ReadInteger("setting", "posfontitalic", 0)) PosFont->Style = PosFont->Style << fsItalic; + PanelFont->Charset = ANSI_CHARSET; + PosFont->Charset = ANSI_CHARSET; + + TTextViewer::Color1 = (TColor)ini->ReadInteger("viewer", "color1", (int)clBlack); + TTextViewer::Color2 = (TColor)ini->ReadInteger("viewer", "color2", (int)clWhite); + TTextViewer::FontD = new TFont; + TTextViewer::FontD->Name = ini->ReadString("viewer", "fontname", "Courier New"); + TTextViewer::FontD->Size = ini->ReadInteger("viewer", "fontsize", 9); + + UpdatePanel(); + + if (PanelStack == 0) { + Panel21->Width = ini->ReadInteger("window", "splitpos", 185); + Panel22->Width = ini->ReadInteger("window", "splitpos1", 247); + Panel23->Width = ini->ReadInteger("window", "splitpos2", 262); + Panel24->Width = ini->ReadInteger("window", "splitpos3", 185); + Panel25->Width = ini->ReadInteger("window", "splitpos4", 185); + Panel21->Height = 185; + Panel22->Height = 185; + Panel23->Height = 185; + Panel24->Height = 185; + Panel25->Height = 185; + } else { + Panel21->Height = ini->ReadInteger("window", "splitpos", 185); + Panel22->Height = ini->ReadInteger("window", "splitpos1", 247); + Panel23->Height = ini->ReadInteger("window", "splitpos2", 262); + Panel24->Height = ini->ReadInteger("window", "splitpos3", 185); + Panel25->Height = ini->ReadInteger("window", "splitpos4", 185); + Panel21->Width = 185; + Panel22->Width = 185; + Panel23->Width = 185; + Panel24->Width = 185; + } + Width = ini->ReadInteger("window", "width", 724); + Height = ini->ReadInteger("window", "height", 570); + delete ini; } // save option to ini file -------------------------------------------------- -void __fastcall TMainForm::SaveOpt(void) -{ - TIniFile *ini=new TIniFile(IniFile); - AnsiString s; - int i,j,no,strno[]={0,1,6,2,3,4,5,7}; - char *p; - - trace(3,"SaveOpt\n"); - - for (i=0;i<8;i++) { - no=strno[i]; - ini->WriteInteger("stream",s.sprintf("streamc%d",no),StreamC[i]); - ini->WriteInteger("stream",s.sprintf("stream%d" ,no),Stream [i]); - ini->WriteInteger("stream",s.sprintf("format%d" ,no),Format [i]); - for (j=0;j<4;j++) { - ini->WriteString("stream",s.sprintf("path_%d_%d",no,j),Paths[i][j]); - } - } - for (i=0;i<3;i++) { - ini->WriteString("stream",s.sprintf("rcvopt%d",i+1),RcvOpt[i]); - } - for (i=0;i<3;i++) for (j=0;j<3;j++) { - for (p=Cmds[i][j].c_str();*p;p++) { - if ((p=strstr(p,"\r\n"))) strncpy(p,"@@",2); else break; - } - ini->WriteString ("serial",s.sprintf("cmd_%d_%d" ,i,j),Cmds [i][j]); - ini->WriteInteger("serial",s.sprintf("cmdena_%d_%d",i,j),CmdEna[i][j]); - } - for (i=0;i<3;i++) for (j=0;j<3;j++) { - for (p=CmdsTcp[i][j].c_str();*p;p++) { - if ((p=strstr(p,"\r\n"))) strncpy(p,"@@",2); else break; - } - ini->WriteString ("tcpip",s.sprintf("cmd_%d_%d" ,i,j),CmdsTcp [i][j]); - ini->WriteInteger("tcpip",s.sprintf("cmdena_%d_%d",i,j),CmdEnaTcp[i][j]); - } - ini->WriteInteger("prcopt", "mode", PrcOpt.mode ); - ini->WriteInteger("prcopt", "nf", PrcOpt.nf ); - ini->WriteFloat ("prcopt", "elmin", PrcOpt.elmin ); - ini->WriteFloat ("prcopt", "snrmask_ena1",PrcOpt.snrmask.ena[0]); - ini->WriteFloat ("prcopt", "snrmask_ena2",PrcOpt.snrmask.ena[1]); - for (i=0;iWriteFloat("prcopt",s.sprintf("snrmask_%d_%d",i+1,j+1), - PrcOpt.snrmask.mask[i][j]); - } - ini->WriteInteger("prcopt", "dynamics", PrcOpt.dynamics ); - ini->WriteInteger("prcopt", "tidecorr", PrcOpt.tidecorr ); - ini->WriteInteger("prcopt", "modear", PrcOpt.modear ); - ini->WriteInteger("prcopt", "glomodear", PrcOpt.glomodear ); - ini->WriteInteger("prcopt", "bdsmodear", PrcOpt.bdsmodear ); - ini->WriteInteger("prcopt", "maxout", PrcOpt.maxout ); - ini->WriteInteger("prcopt", "minlock", PrcOpt.minlock ); - ini->WriteInteger("prcopt", "minfix", PrcOpt.minfix ); - ini->WriteInteger("prcopt", "ionoopt", PrcOpt.ionoopt ); - ini->WriteInteger("prcopt", "tropopt", PrcOpt.tropopt ); - ini->WriteInteger("prcopt", "ephopt", PrcOpt.sateph ); - ini->WriteInteger("prcopt", "ariter", PrcOpt.armaxiter ); - ini->WriteInteger("prcopt", "minfixsats", PrcOpt.minfixsats ); - ini->WriteInteger("prcopt", "minholdsats",PrcOpt.minholdsats ); - ini->WriteInteger("prcopt", "mindropsats",PrcOpt.mindropsats ); - ini->WriteInteger("prcopt", "niter", PrcOpt.niter ); - ini->WriteFloat ("prcopt", "eratio0", PrcOpt.eratio[0] ); - ini->WriteFloat ("prcopt", "eratio1", PrcOpt.eratio[1] ); - ini->WriteFloat ("prcopt", "eratio2", PrcOpt.eratio[2] ); - ini->WriteFloat ("prcopt", "eratio3", PrcOpt.eratio[3] ); - ini->WriteFloat ("prcopt", "err1", PrcOpt.err[1] ); - ini->WriteFloat ("prcopt", "err2", PrcOpt.err[2] ); - ini->WriteFloat ("prcopt", "err3", PrcOpt.err[3] ); - ini->WriteFloat ("prcopt", "err4", PrcOpt.err[4] ); - ini->WriteFloat ("prcopt", "prn0", PrcOpt.prn[0] ); - ini->WriteFloat ("prcopt", "prn1", PrcOpt.prn[1] ); - ini->WriteFloat ("prcopt", "prn2", PrcOpt.prn[2] ); - ini->WriteFloat ("prcopt", "prn3", PrcOpt.prn[3] ); - ini->WriteFloat ("prcopt", "prn4", PrcOpt.prn[4] ); - ini->WriteFloat ("prcopt", "sclkstab", PrcOpt.sclkstab ); - ini->WriteFloat ("prcopt", "thresar", PrcOpt.thresar[0] ); - ini->WriteFloat ("prcopt", "thresar1", PrcOpt.thresar[1] ); - ini->WriteFloat ("prcopt", "thresar2", PrcOpt.thresar[2] ); - ini->WriteFloat ("prcopt", "thresar3", PrcOpt.thresar[3] ); - ini->WriteFloat ("prcopt", "thresar4", PrcOpt.thresar[4] ); - ini->WriteFloat ("prcopt", "thresarmin", PrcOpt.thresar[5] ); - ini->WriteFloat ("prcopt", "thresarmax", PrcOpt.thresar[6] ); - ini->WriteFloat ("prcopt", "elmaskar", PrcOpt.elmaskar ); - ini->WriteFloat ("prcopt", "elmaskhold", PrcOpt.elmaskhold ); - ini->WriteFloat ("prcopt", "thresslip", PrcOpt.thresslip ); - ini->WriteFloat ("prcopt", "thresdop", PrcOpt.thresdop ); - ini->WriteFloat ("prcopt", "maxtdiff", PrcOpt.maxtdiff ); - ini->WriteFloat ("prcopt", "maxphase", PrcOpt.maxinno[0] ); - ini->WriteFloat ("prcopt", "maxcode", PrcOpt.maxinno[1] ); - ini->WriteFloat ("prcopt", "varholdamb", PrcOpt.varholdamb ); - ini->WriteFloat ("prcopt", "gainholdamb",PrcOpt.gainholdamb ); - ini->WriteInteger("prcopt", "syncsol", PrcOpt.syncsol ); - ini->WriteInteger("prcopt", "arfilter", PrcOpt.arfilter ); - ini->WriteString ("prcopt", "exsats", ExSats ); - ini->WriteInteger("prcopt", "navsys", PrcOpt.navsys ); - ini->WriteInteger("prcopt", "posopt1", PrcOpt.posopt[0] ); - ini->WriteInteger("prcopt", "posopt2", PrcOpt.posopt[1] ); - ini->WriteInteger("prcopt", "posopt3", PrcOpt.posopt[2] ); - ini->WriteInteger("prcopt", "posopt4", PrcOpt.posopt[3] ); - ini->WriteInteger("prcopt", "posopt5", PrcOpt.posopt[4] ); - ini->WriteInteger("prcopt", "posopt6", PrcOpt.posopt[5] ); - ini->WriteInteger("prcopt", "maxaveep", PrcOpt.maxaveep ); - ini->WriteInteger("prcopt", "initrst", PrcOpt.initrst ); - - ini->WriteFloat ("prcopt", "baselinec", BaselineC ); - ini->WriteFloat ("prcopt", "baseline1", Baseline[0] ); - ini->WriteFloat ("prcopt", "baseline2", Baseline[1] ); - - ini->WriteInteger("solopt", "posf", SolOpt.posf ); - ini->WriteInteger("solopt", "times", SolOpt.times ); - ini->WriteInteger("solopt", "timef", SolOpt.timef ); - ini->WriteInteger("solopt", "timeu", SolOpt.timeu ); - ini->WriteInteger("solopt", "degf", SolOpt.degf ); - ini->WriteString ("solopt", "sep", SolOpt.sep ); - ini->WriteInteger("solopt", "outhead", SolOpt.outhead ); - ini->WriteInteger("solopt", "outopt", SolOpt.outopt ); - ini->WriteInteger("solopt", "outvel", SolOpt.outvel ); - ini->WriteInteger("prcopt", "outsingle", PrcOpt.outsingle ); - ini->WriteFloat ("solopt", "maxsolstd", SolOpt.maxsolstd ); - ini->WriteInteger("solopt", "datum", SolOpt.datum ); - ini->WriteInteger("solopt", "height", SolOpt.height ); - ini->WriteInteger("solopt", "geoid", SolOpt.geoid ); - ini->WriteFloat ("solopt", "nmeaintv1", SolOpt.nmeaintv[0] ); - ini->WriteFloat ("solopt", "nmeaintv2", SolOpt.nmeaintv[1] ); - ini->WriteInteger("setting","debugstatus",SolOpt.sstat ); - ini->WriteInteger("setting","debugtrace", SolOpt.trace ); - - ini->WriteInteger("setting","rovpostype", RovPosTypeF ); - ini->WriteInteger("setting","refpostype", RefPosTypeF ); - ini->WriteInteger("setting","rovantpcv", RovAntPcvF ); - ini->WriteInteger("setting","refantpcv", RefAntPcvF ); - ini->WriteString ("setting","rovant", RovAntF ); - ini->WriteString ("setting","refant", RefAntF ); - ini->WriteString ("setting","satpcvfile", SatPcvFileF ); - ini->WriteString ("setting","antpcvfile", AntPcvFileF ); - ini->WriteString ("setting","staposfile", StaPosFileF ); - ini->WriteString ("setting","geoiddatafile",GeoidDataFileF ); - ini->WriteString ("setting","dcbfile", DCBFileF ); - ini->WriteString ("setting","eopfile", EOPFileF ); - ini->WriteString ("setting","localdirectory",LocalDirectory ); - - ini->WriteInteger("setting","svrcycle", SvrCycle ); - ini->WriteInteger("setting","timeouttime",TimeoutTime ); - ini->WriteInteger("setting","recontime", ReconTime ); - ini->WriteInteger("setting","nmeacycle", NmeaCycle ); - ini->WriteInteger("setting","svrbuffsize",SvrBuffSize ); - ini->WriteInteger("setting","solbuffsize",SolBuffSize ); - ini->WriteInteger("setting","savedsol", SavedSol ); - ini->WriteInteger("setting","navselect", NavSelect ); - ini->WriteInteger("setting","sbassat", PrcOpt.sbassatsel ); - ini->WriteInteger("setting","dgpscorr", DgpsCorr ); - ini->WriteInteger("setting","sbascorr", SbasCorr ); - - ini->WriteInteger("setting","nmeareq", NmeaReq ); - ini->WriteInteger("setting","intimetag", InTimeTag ); - ini->WriteString ("setting","intimespeed",InTimeSpeed ); - ini->WriteString ("setting","intimestart",InTimeStart ); - ini->WriteInteger("setting","intime64bit",InTime64Bit ); - ini->WriteInteger("setting","outtimetag", OutTimeTag ); - ini->WriteInteger("setting","outappend", OutAppend ); - ini->WriteString ("setting","outswapinterval",OutSwapInterval); - ini->WriteInteger("setting","logtimetag", LogTimeTag ); - ini->WriteInteger("setting","logappend", LogAppend ); - ini->WriteString ("setting","logswapinterval",LogSwapInterval); - ini->WriteFloat ("setting","nmeapos1", NmeaPos[0] ); - ini->WriteFloat ("setting","nmeapos2", NmeaPos[1] ); - ini->WriteFloat ("setting","nmeapos3", NmeaPos[2] ); - ini->WriteString ("setting","resetcmd", ResetCmd ); - ini->WriteFloat ("setting","maxbl", MaxBL ); - ini->WriteInteger("setting","fswapmargin",FileSwapMargin ); - - ini->WriteInteger("setting","timesys", TimeSys ); - ini->WriteInteger("setting","soltype", SolType ); - ini->WriteInteger("setting","plottype", PlotType1 ); - ini->WriteInteger("setting","plottype2", PlotType2 ); - ini->WriteInteger("setting","plottype3", PlotType3 ); - ini->WriteInteger("setting","plottype4", PlotType4 ); - ini->WriteInteger("setting","panelmode", PanelMode ); - ini->WriteString ("setting","proxyaddr", ProxyAddr ); - ini->WriteInteger("setting","moniport", MoniPort ); - ini->WriteInteger("setting","panelstack", PanelStack ); - ini->WriteInteger("setting","trktype1", TrkType1 ); - ini->WriteInteger("setting","trktype2", TrkType2 ); - ini->WriteInteger("setting","trktype3", TrkType3 ); - ini->WriteInteger("setting","trktype4", TrkType4 ); - ini->WriteInteger("setting","trkscale1", TrkScale1 ); - ini->WriteInteger("setting","trkscale2", TrkScale2 ); - ini->WriteInteger("setting","trkscale3", TrkScale3 ); - ini->WriteInteger("setting","trkscale4", TrkScale4 ); - ini->WriteInteger("setting","freqtype1", FreqType1 ); - ini->WriteInteger("setting","freqtype2", FreqType2 ); - ini->WriteInteger("setting","freqtype3", FreqType3 ); - ini->WriteInteger("setting","freqtype4", FreqType4 ); - ini->WriteInteger("setting","blmode1", BLMode1 ); - ini->WriteInteger("setting","blmode2", BLMode2 ); - ini->WriteInteger("setting","blmode3", BLMode3 ); - ini->WriteInteger("setting","blmode4", BLMode4 ); - ini->WriteString ("setting","markername", MarkerName ); - ini->WriteString ("setting","markercomment",MarkerComment ); - - for (i=0;i<3;i++) { - ini->WriteFloat("setting",s.sprintf("rovantdel_%d",i),RovAntDel[i]); - ini->WriteFloat("setting",s.sprintf("refantdel_%d",i),RefAntDel[i]); - ini->WriteFloat("setting",s.sprintf("rovpos_%d",i), RovPos[i]); - ini->WriteFloat("setting",s.sprintf("refpos_%d",i), RefPos[i]); - } - for (i=0;i<10;i++) { - ini->WriteString("tcpopt",s.sprintf("history%d" ,i),History [i]); - } - ini->WriteInteger("mapopt","nmappnt",NMapPnt); - for (i=0;iWriteString("mapopt",s1.sprintf("pntname%d",i+1),PntName[i]); - ini->WriteString("mapopt",s1.sprintf("pntpos%d" ,i+1), - s2.sprintf("%.4f,%.4f,%.4f",PntPos[i][0],PntPos[i][1],PntPos[i][2])); - } - ini->WriteString ("setting","panelfontname", PanelFont->Name); - ini->WriteInteger("setting","panelfontsize", PanelFont->Size); - ini->WriteInteger("setting","panelfontcolor",(int)PanelFont->Color); - ini->WriteString ("setting","posfontname", PosFont->Name ); - ini->WriteInteger("setting","posfontsize", PosFont->Size ); - ini->WriteInteger("setting","posfontcolor",(int)PosFont->Color); - ini->WriteInteger("setting","posfontbold", PosFont->Style.Contains(fsBold)); - ini->WriteInteger("setting","posfontitalic",PosFont->Style.Contains(fsItalic)); - - ini->WriteInteger("viewer","color1", (int)TTextViewer::Color1); - ini->WriteInteger("viewer","color2", (int)TTextViewer::Color2); - ini->WriteString ("viewer","fontname",TTextViewer::FontD->Name); - ini->WriteInteger("viewer","fontsize",TTextViewer::FontD->Size); - - ini->WriteInteger("window","width", Width); - ini->WriteInteger("window","height", Height); - if (PanelStack==0) { - ini->WriteInteger("window","splitpos", Panel21->Width); - ini->WriteInteger("window","splitpos1",Panel22->Width); - ini->WriteInteger("window","splitpos2",Panel23->Width); - ini->WriteInteger("window","splitpos3",Panel24->Width); - ini->WriteInteger("window","splitpos4",Panel25->Width); - } - else { - ini->WriteInteger("window","splitpos", Panel21->Height); - ini->WriteInteger("window","splitpos1",Panel22->Height); - ini->WriteInteger("window","splitpos2",Panel23->Height); - ini->WriteInteger("window","splitpos3",Panel24->Height); - ini->WriteInteger("window","splitpos4",Panel25->Height); - } - delete ini; +void __fastcall TMainForm::SaveOpt(void) { + TIniFile *ini = new TIniFile(IniFile); + AnsiString s; + int i, j, no, strno[] = {0, 1, 6, 2, 3, 4, 5, 7}; + char *p; + + trace(3, "SaveOpt\n"); + + for (i = 0; i < 8; i++) { + no = strno[i]; + ini->WriteInteger("stream", s.sprintf("streamc%d", no), StreamC[i]); + ini->WriteInteger("stream", s.sprintf("stream%d", no), Stream[i]); + ini->WriteInteger("stream", s.sprintf("format%d", no), Format[i]); + for (j = 0; j < 4; j++) { + ini->WriteString("stream", s.sprintf("path_%d_%d", no, j), Paths[i][j]); + } + } + for (i = 0; i < 3; i++) { + ini->WriteString("stream", s.sprintf("rcvopt%d", i + 1), RcvOpt[i]); + } + for (i = 0; i < 3; i++) + for (j = 0; j < 3; j++) { + for (p = Cmds[i][j].c_str(); *p; p++) { + if ((p = strstr(p, "\r\n"))) + strncpy(p, "@@", 2); + else + break; + } + ini->WriteString("serial", s.sprintf("cmd_%d_%d", i, j), Cmds[i][j]); + ini->WriteInteger("serial", s.sprintf("cmdena_%d_%d", i, j), CmdEna[i][j]); + } + for (i = 0; i < 3; i++) + for (j = 0; j < 3; j++) { + for (p = CmdsTcp[i][j].c_str(); *p; p++) { + if ((p = strstr(p, "\r\n"))) + strncpy(p, "@@", 2); + else + break; + } + ini->WriteString("tcpip", s.sprintf("cmd_%d_%d", i, j), CmdsTcp[i][j]); + ini->WriteInteger("tcpip", s.sprintf("cmdena_%d_%d", i, j), CmdEnaTcp[i][j]); + } + ini->WriteInteger("prcopt", "mode", PrcOpt.mode); + ini->WriteInteger("prcopt", "nf", PrcOpt.nf); + ini->WriteFloat("prcopt", "elmin", PrcOpt.elmin); + ini->WriteFloat("prcopt", "snrmask_ena1", PrcOpt.snrmask.ena[0]); + ini->WriteFloat("prcopt", "snrmask_ena2", PrcOpt.snrmask.ena[1]); + for (i = 0; i < NFREQ; i++) + for (j = 0; j < 9; j++) { + ini->WriteFloat("prcopt", s.sprintf("snrmask_%d_%d", i + 1, j + 1), + PrcOpt.snrmask.mask[i][j]); + } + ini->WriteInteger("prcopt", "dynamics", PrcOpt.dynamics); + ini->WriteInteger("prcopt", "tidecorr", PrcOpt.tidecorr); + ini->WriteInteger("prcopt", "modear", PrcOpt.modear); + ini->WriteInteger("prcopt", "glomodear", PrcOpt.glomodear); + ini->WriteInteger("prcopt", "bdsmodear", PrcOpt.bdsmodear); + ini->WriteInteger("prcopt", "maxout", PrcOpt.maxout); + ini->WriteInteger("prcopt", "minlock", PrcOpt.minlock); + ini->WriteInteger("prcopt", "minfix", PrcOpt.minfix); + ini->WriteInteger("prcopt", "ionoopt", PrcOpt.ionoopt); + ini->WriteInteger("prcopt", "tropopt", PrcOpt.tropopt); + ini->WriteInteger("prcopt", "ephopt", PrcOpt.sateph); + ini->WriteInteger("prcopt", "ariter", PrcOpt.armaxiter); + ini->WriteInteger("prcopt", "minfixsats", PrcOpt.minfixsats); + ini->WriteInteger("prcopt", "minholdsats", PrcOpt.minholdsats); + ini->WriteInteger("prcopt", "mindropsats", PrcOpt.mindropsats); + ini->WriteInteger("prcopt", "niter", PrcOpt.niter); + ini->WriteFloat("prcopt", "eratio0", PrcOpt.eratio[0]); + ini->WriteFloat("prcopt", "eratio1", PrcOpt.eratio[1]); + ini->WriteFloat("prcopt", "eratio2", PrcOpt.eratio[2]); + ini->WriteFloat("prcopt", "eratio3", PrcOpt.eratio[3]); + ini->WriteFloat("prcopt", "err1", PrcOpt.err[1]); + ini->WriteFloat("prcopt", "err2", PrcOpt.err[2]); + ini->WriteFloat("prcopt", "err3", PrcOpt.err[3]); + ini->WriteFloat("prcopt", "err4", PrcOpt.err[4]); + ini->WriteFloat("prcopt", "prn0", PrcOpt.prn[0]); + ini->WriteFloat("prcopt", "prn1", PrcOpt.prn[1]); + ini->WriteFloat("prcopt", "prn2", PrcOpt.prn[2]); + ini->WriteFloat("prcopt", "prn3", PrcOpt.prn[3]); + ini->WriteFloat("prcopt", "prn4", PrcOpt.prn[4]); + ini->WriteFloat("prcopt", "sclkstab", PrcOpt.sclkstab); + ini->WriteFloat("prcopt", "thresar", PrcOpt.thresar[0]); + ini->WriteFloat("prcopt", "thresar1", PrcOpt.thresar[1]); + ini->WriteFloat("prcopt", "thresar2", PrcOpt.thresar[2]); + ini->WriteFloat("prcopt", "thresar3", PrcOpt.thresar[3]); + ini->WriteFloat("prcopt", "thresar4", PrcOpt.thresar[4]); + ini->WriteFloat("prcopt", "thresarmin", PrcOpt.thresar[5]); + ini->WriteFloat("prcopt", "thresarmax", PrcOpt.thresar[6]); + ini->WriteFloat("prcopt", "elmaskar", PrcOpt.elmaskar); + ini->WriteFloat("prcopt", "elmaskhold", PrcOpt.elmaskhold); + ini->WriteFloat("prcopt", "thresslip", PrcOpt.thresslip); + ini->WriteFloat("prcopt", "thresdop", PrcOpt.thresdop); + ini->WriteFloat("prcopt", "maxtdiff", PrcOpt.maxtdiff); + ini->WriteFloat("prcopt", "maxphase", PrcOpt.maxinno[0]); + ini->WriteFloat("prcopt", "maxcode", PrcOpt.maxinno[1]); + ini->WriteFloat("prcopt", "varholdamb", PrcOpt.varholdamb); + ini->WriteFloat("prcopt", "gainholdamb", PrcOpt.gainholdamb); + ini->WriteInteger("prcopt", "syncsol", PrcOpt.syncsol); + ini->WriteInteger("prcopt", "arfilter", PrcOpt.arfilter); + ini->WriteString("prcopt", "exsats", ExSats); + ini->WriteInteger("prcopt", "navsys", PrcOpt.navsys); + ini->WriteInteger("prcopt", "posopt1", PrcOpt.posopt[0]); + ini->WriteInteger("prcopt", "posopt2", PrcOpt.posopt[1]); + ini->WriteInteger("prcopt", "posopt3", PrcOpt.posopt[2]); + ini->WriteInteger("prcopt", "posopt4", PrcOpt.posopt[3]); + ini->WriteInteger("prcopt", "posopt5", PrcOpt.posopt[4]); + ini->WriteInteger("prcopt", "posopt6", PrcOpt.posopt[5]); + ini->WriteInteger("prcopt", "maxaveep", PrcOpt.maxaveep); + ini->WriteInteger("prcopt", "initrst", PrcOpt.initrst); + + ini->WriteFloat("prcopt", "baselinec", BaselineC); + ini->WriteFloat("prcopt", "baseline1", Baseline[0]); + ini->WriteFloat("prcopt", "baseline2", Baseline[1]); + + ini->WriteInteger("solopt", "posf", SolOpt.posf); + ini->WriteInteger("solopt", "times", SolOpt.times); + ini->WriteInteger("solopt", "timef", SolOpt.timef); + ini->WriteInteger("solopt", "timeu", SolOpt.timeu); + ini->WriteInteger("solopt", "degf", SolOpt.degf); + ini->WriteString("solopt", "sep", SolOpt.sep); + ini->WriteInteger("solopt", "outhead", SolOpt.outhead); + ini->WriteInteger("solopt", "outopt", SolOpt.outopt); + ini->WriteInteger("solopt", "outvel", SolOpt.outvel); + ini->WriteInteger("prcopt", "outsingle", PrcOpt.outsingle); + ini->WriteFloat("solopt", "maxsolstd", SolOpt.maxsolstd); + ini->WriteInteger("solopt", "datum", SolOpt.datum); + ini->WriteInteger("solopt", "height", SolOpt.height); + ini->WriteInteger("solopt", "geoid", SolOpt.geoid); + ini->WriteFloat("solopt", "nmeaintv1", SolOpt.nmeaintv[0]); + ini->WriteFloat("solopt", "nmeaintv2", SolOpt.nmeaintv[1]); + ini->WriteInteger("setting", "debugstatus", SolOpt.sstat); + ini->WriteInteger("setting", "debugtrace", SolOpt.trace); + + ini->WriteInteger("setting", "rovpostype", RovPosTypeF); + ini->WriteInteger("setting", "refpostype", RefPosTypeF); + ini->WriteInteger("setting", "rovantpcv", RovAntPcvF); + ini->WriteInteger("setting", "refantpcv", RefAntPcvF); + ini->WriteString("setting", "rovant", RovAntF); + ini->WriteString("setting", "refant", RefAntF); + ini->WriteString("setting", "satpcvfile", SatPcvFileF); + ini->WriteString("setting", "antpcvfile", AntPcvFileF); + ini->WriteString("setting", "staposfile", StaPosFileF); + ini->WriteString("setting", "geoiddatafile", GeoidDataFileF); + ini->WriteString("setting", "dcbfile", DCBFileF); + ini->WriteString("setting", "eopfile", EOPFileF); + ini->WriteString("setting", "localdirectory", LocalDirectory); + + ini->WriteInteger("setting", "svrcycle", SvrCycle); + ini->WriteInteger("setting", "timeouttime", TimeoutTime); + ini->WriteInteger("setting", "recontime", ReconTime); + ini->WriteInteger("setting", "nmeacycle", NmeaCycle); + ini->WriteInteger("setting", "svrbuffsize", SvrBuffSize); + ini->WriteInteger("setting", "solbuffsize", SolBuffSize); + ini->WriteInteger("setting", "savedsol", SavedSol); + ini->WriteInteger("setting", "navselect", NavSelect); + ini->WriteInteger("setting", "sbassat", PrcOpt.sbassatsel); + ini->WriteInteger("setting", "dgpscorr", DgpsCorr); + ini->WriteInteger("setting", "sbascorr", SbasCorr); + + ini->WriteInteger("setting", "nmeareq", NmeaReq); + ini->WriteInteger("setting", "intimetag", InTimeTag); + ini->WriteString("setting", "intimespeed", InTimeSpeed); + ini->WriteString("setting", "intimestart", InTimeStart); + ini->WriteInteger("setting", "intime64bit", InTime64Bit); + ini->WriteInteger("setting", "outtimetag", OutTimeTag); + ini->WriteInteger("setting", "outappend", OutAppend); + ini->WriteString("setting", "outswapinterval", OutSwapInterval); + ini->WriteInteger("setting", "logtimetag", LogTimeTag); + ini->WriteInteger("setting", "logappend", LogAppend); + ini->WriteString("setting", "logswapinterval", LogSwapInterval); + ini->WriteFloat("setting", "nmeapos1", NmeaPos[0]); + ini->WriteFloat("setting", "nmeapos2", NmeaPos[1]); + ini->WriteFloat("setting", "nmeapos3", NmeaPos[2]); + ini->WriteString("setting", "resetcmd", ResetCmd); + ini->WriteFloat("setting", "maxbl", MaxBL); + ini->WriteInteger("setting", "fswapmargin", FileSwapMargin); + + ini->WriteInteger("setting", "timesys", TimeSys); + ini->WriteInteger("setting", "soltype", SolType); + ini->WriteInteger("setting", "plottype", PlotType1); + ini->WriteInteger("setting", "plottype2", PlotType2); + ini->WriteInteger("setting", "plottype3", PlotType3); + ini->WriteInteger("setting", "plottype4", PlotType4); + ini->WriteInteger("setting", "panelmode", PanelMode); + ini->WriteString("setting", "proxyaddr", ProxyAddr); + ini->WriteInteger("setting", "moniport", MoniPort); + ini->WriteInteger("setting", "panelstack", PanelStack); + ini->WriteInteger("setting", "trktype1", TrkType1); + ini->WriteInteger("setting", "trktype2", TrkType2); + ini->WriteInteger("setting", "trktype3", TrkType3); + ini->WriteInteger("setting", "trktype4", TrkType4); + ini->WriteInteger("setting", "trkscale1", TrkScale1); + ini->WriteInteger("setting", "trkscale2", TrkScale2); + ini->WriteInteger("setting", "trkscale3", TrkScale3); + ini->WriteInteger("setting", "trkscale4", TrkScale4); + ini->WriteInteger("setting", "freqtype1", FreqType1); + ini->WriteInteger("setting", "freqtype2", FreqType2); + ini->WriteInteger("setting", "freqtype3", FreqType3); + ini->WriteInteger("setting", "freqtype4", FreqType4); + ini->WriteInteger("setting", "blmode1", BLMode1); + ini->WriteInteger("setting", "blmode2", BLMode2); + ini->WriteInteger("setting", "blmode3", BLMode3); + ini->WriteInteger("setting", "blmode4", BLMode4); + ini->WriteString("setting", "markername", MarkerName); + ini->WriteString("setting", "markercomment", MarkerComment); + + for (i = 0; i < 3; i++) { + ini->WriteFloat("setting", s.sprintf("rovantdel_%d", i), RovAntDel[i]); + ini->WriteFloat("setting", s.sprintf("refantdel_%d", i), RefAntDel[i]); + ini->WriteFloat("setting", s.sprintf("rovpos_%d", i), RovPos[i]); + ini->WriteFloat("setting", s.sprintf("refpos_%d", i), RefPos[i]); + } + for (i = 0; i < 10; i++) { + ini->WriteString("tcpopt", s.sprintf("history%d", i), History[i]); + } + ini->WriteInteger("mapopt", "nmappnt", NMapPnt); + for (i = 0; i < NMapPnt; i++) { + AnsiString s1, s2; + ini->WriteString("mapopt", s1.sprintf("pntname%d", i + 1), PntName[i]); + ini->WriteString("mapopt", s1.sprintf("pntpos%d", i + 1), + s2.sprintf("%.4f,%.4f,%.4f", PntPos[i][0], PntPos[i][1], PntPos[i][2])); + } + ini->WriteString("setting", "panelfontname", PanelFont->Name); + ini->WriteInteger("setting", "panelfontsize", PanelFont->Size); + ini->WriteInteger("setting", "panelfontcolor", (int)PanelFont->Color); + ini->WriteString("setting", "posfontname", PosFont->Name); + ini->WriteInteger("setting", "posfontsize", PosFont->Size); + ini->WriteInteger("setting", "posfontcolor", (int)PosFont->Color); + ini->WriteInteger("setting", "posfontbold", PosFont->Style.Contains(fsBold)); + ini->WriteInteger("setting", "posfontitalic", PosFont->Style.Contains(fsItalic)); + + ini->WriteInteger("viewer", "color1", (int)TTextViewer::Color1); + ini->WriteInteger("viewer", "color2", (int)TTextViewer::Color2); + ini->WriteString("viewer", "fontname", TTextViewer::FontD->Name); + ini->WriteInteger("viewer", "fontsize", TTextViewer::FontD->Size); + + ini->WriteInteger("window", "width", Width); + ini->WriteInteger("window", "height", Height); + if (PanelStack == 0) { + ini->WriteInteger("window", "splitpos", Panel21->Width); + ini->WriteInteger("window", "splitpos1", Panel22->Width); + ini->WriteInteger("window", "splitpos2", Panel23->Width); + ini->WriteInteger("window", "splitpos3", Panel24->Width); + ini->WriteInteger("window", "splitpos4", Panel25->Width); + } else { + ini->WriteInteger("window", "splitpos", Panel21->Height); + ini->WriteInteger("window", "splitpos1", Panel22->Height); + ini->WriteInteger("window", "splitpos2", Panel23->Height); + ini->WriteInteger("window", "splitpos3", Panel24->Height); + ini->WriteInteger("window", "splitpos4", Panel25->Height); + } + delete ini; } //--------------------------------------------------------------------------- -void __fastcall TMainForm::BtnMarkClick(TObject *Sender) -{ - MarkDialog->PosMode=rtksvr.rtk.opt.mode; - MarkDialog->Marker=MarkerName; - MarkDialog->Comment=MarkerComment; - if (MarkDialog->ShowModal()!=mrOk) return; - rtksvr.rtk.opt.mode=MarkDialog->PosMode; - MarkerName=MarkDialog->Marker; - MarkerComment=MarkDialog->Comment; - UpdatePos(); +void __fastcall TMainForm::BtnMarkClick(TObject *Sender) { + MarkDialog->PosMode = rtksvr.rtk.opt.mode; + MarkDialog->Marker = MarkerName; + MarkDialog->Comment = MarkerComment; + if (MarkDialog->ShowModal() != mrOk) return; + rtksvr.rtk.opt.mode = MarkDialog->PosMode; + MarkerName = MarkDialog->Marker; + MarkerComment = MarkDialog->Comment; + UpdatePos(); } //--------------------------------------------------------------------------- - diff --git a/app/winapp/rtknavi/navimain.h b/app/winapp/rtknavi/navimain.h index 4135aa8d2..6af89a66e 100644 --- a/app/winapp/rtknavi/navimain.h +++ b/app/winapp/rtknavi/navimain.h @@ -2,282 +2,280 @@ #ifndef navimainH #define navimainH //--------------------------------------------------------------------------- +#include #include +#include #include -#include -#include +#include #include -#include +#include #include -#include -#include #include #include +#include +#include #include "rtklib.h" -#include -#define MAXSCALE 18 -#define MAXMAPPNT 10 +#define MAXSCALE 18 +#define MAXMAPPNT 10 //--------------------------------------------------------------------------- -class TMainForm : public TForm -{ -__published: - TPanel *Panel1; - TPanel *Panel2; - TPanel *Panel3; - TPanel *Panel11; - - TLabel *LabelTime; - TLabel *Message; - - TPopupMenu *PopupMenu; - TMenuItem *MenuMonitor; - TMenuItem *MenuExpand; - TMenuItem *N1; - TMenuItem *MenuStart; - TMenuItem *MenuPlot; - TMenuItem *N2; - TMenuItem *MenuExit; - TMenuItem *MenuStop; - - TSpeedButton *BtnTimeSys; - - TTrayIcon *TrayIcon; - - TSaveDialog *SaveDialog; - - TImageList *ImageList; - - TTimer *Timer; - TPanel *Panel4; - TSpeedButton *BtnTaskTray; - TSpeedButton *BtnAbout; - TSpeedButton *BtnMonitor; - TPanel *Panel12; - TImage *Image1; - TImage *Image2; - TPanel *Str1; - TPanel *Str2; - TPanel *Str3; - TPanel *Str4; - TPanel *Str5; - TPanel *Str6; - TPanel *Str7; - TPanel *Str8; - TPanel *Svr; - TPanel *Panel122; - TSpeedButton *BtnOutputStr; - TPanel *Panel123; - TSpeedButton *BtnLogStr; - TPanel *Panel121; - TSpeedButton *BtnInputStr; - TPanel *Panel21; - TPanel *Panel211; - TLabel *LabelNSat; - TLabel *LabelStd; - TLabel *Plabel1; - TLabel *Plabel2; - TLabel *Plabel3; - TLabel *PlabelA; - TLabel *Pos1; - TLabel *Pos2; - TLabel *Pos3; - TLabel *Solution; - TPanel *IndSol; - TPanel *Panel213; - TScrollBar *ScbSol; - TButton *BtnSave; - TPanel *Panel212; - TLabel *Plabel0; - TSplitter *Splitter1; - TPanel *Panel22; - TImage *Plot1; - TSpeedButton *BtnFreqType1; - TSplitter *Splitter2; - TPanel *Panel23; - TImage *Disp2; - TImage *Plot2; - TSpeedButton *BtnFreqType2; - TImage *Disp1; - TSpeedButton *BtnSolType; - TSpeedButton *BtnPlotType1; - TSpeedButton *BtnPlotType2; - TSpeedButton *BtnPanel; - TPanel *Pane6; - TPanel *Panel5; - TPanel *IndQ; - TLabel *SolS; - TLabel *SolQ; - TSpeedButton *BtnSolType2; - TBitBtn *BtnStart; - TBitBtn *BtnMark; - TBitBtn *BtnPlot; - TBitBtn *BtnOpt; - TBitBtn *BtnExit; - TBitBtn *BtnStop; - TSpeedButton *BtnExpand1; - TSpeedButton *BtnShrink1; - TSpeedButton *BtnExpand2; - TSpeedButton *BtnShrink2; - TPanel *Panel24; - TImage *Disp3; - TImage *Plot3; - TSpeedButton *BtnFreqType3; - TSpeedButton *BtnPlotType3; - TSpeedButton *BtnExpand3; - TSpeedButton *BtnShrink3; - TPanel *Panel25; - TImage *Disp4; - TImage *Plot4; - TSpeedButton *BtnFreqType4; - TSpeedButton *BtnPlotType4; - TSpeedButton *BtnExpand4; - TSpeedButton *BtnShrink4; - TSplitter *Splitter3; - TSplitter *Splitter4; - - void __fastcall FormCreate (TObject *Sender); - void __fastcall FormShow (TObject *Sender); - void __fastcall FormClose (TObject *Sender, TCloseAction &Action); - - void __fastcall TimerTimer (TObject *Sender); - - void __fastcall BtnStartClick (TObject *Sender); - void __fastcall BtnStopClick (TObject *Sender); - void __fastcall BtnPlotClick (TObject *Sender); - void __fastcall BtnOptClick (TObject *Sender); - void __fastcall BtnExitClick (TObject *Sender); - - void __fastcall BtnTimeSysClick (TObject *Sender); - void __fastcall BtnInputStrClick (TObject *Sender); - void __fastcall BtnOutputStrClick (TObject *Sender); - void __fastcall BtnLogStrClick (TObject *Sender); - void __fastcall BtnSolTypeClick (TObject *Sender); - void __fastcall BtnPlotType1Click (TObject *Sender); - - void __fastcall BtnMonitorClick (TObject *Sender); - void __fastcall BtnSaveClick (TObject *Sender); - void __fastcall BtnAboutClick (TObject *Sender); - void __fastcall BtnTaskTrayClick (TObject *Sender); - - void __fastcall MenuExpandClick (TObject *Sender); - void __fastcall MenuStartClick (TObject *Sender); - void __fastcall MenuStopClick (TObject *Sender); - void __fastcall MenuPlotClick (TObject *Sender); - void __fastcall MenuMonitorClick (TObject *Sender); - void __fastcall MenuExitClick (TObject *Sender); - - void __fastcall ScbSolChange (TObject *Sender); - - void __fastcall TrayIconDblClick (TObject *Sender); - void __fastcall BtnFreqType1Click(TObject *Sender); - void __fastcall Panel22Resize(TObject *Sender); - void __fastcall Panel4Resize(TObject *Sender); - void __fastcall Panel21Resize(TObject *Sender); - void __fastcall Panel23Resize(TObject *Sender); - void __fastcall BtnPanelClick(TObject *Sender); - void __fastcall BtnPlotType2Click(TObject *Sender); - void __fastcall BtnFreqType2Click(TObject *Sender); - void __fastcall Panel211Resize(TObject *Sender); - void __fastcall Panel5Resize(TObject *Sender); - void __fastcall BtnExpand1Click(TObject *Sender); - void __fastcall BtnShrink1Click(TObject *Sender); - void __fastcall BtnExpand2Click(TObject *Sender); - void __fastcall BtnShrink2Click(TObject *Sender); - void __fastcall BtnMarkClick(TObject *Sender); - void __fastcall Panel24Resize(TObject *Sender); - void __fastcall Panel25Resize(TObject *Sender); - void __fastcall BtnPlotType3Click(TObject *Sender); - void __fastcall BtnFreqType3Click(TObject *Sender); - void __fastcall BtnPlotType4Click(TObject *Sender); - void __fastcall BtnFreqType4Click(TObject *Sender); -private: - void __fastcall UpdateLog (int stat, gtime_t time, double *rr, float *qr, - double *rb, int ns, double age, double ratio); - void __fastcall SvrStart (void); - void __fastcall SvrStop (void); - void __fastcall UpdatePanel (void); - void __fastcall UpdateTimeSys(void); - void __fastcall UpdateSolType(void); - void __fastcall UpdateFont (void); - void __fastcall UpdateTime (void); - void __fastcall UpdatePos (void); - void __fastcall UpdateStr (void); - void __fastcall DrawPlot (TImage *plot, int type, int freq); - void __fastcall UpdatePlot (void); - void __fastcall UpdateEnable (void); - void __fastcall ChangePlot (void); - int __fastcall ConfOverwrite(const char *path); - - void __fastcall DrawSnr (TCanvas *c, int w, int h, int x0, int y0, int index, int freq); - void __fastcall DrawSat (TCanvas *c, int w, int h, int x0, int y0, int index, int freq); - void __fastcall DrawBL (TImage *plot, int w, int h); - void __fastcall DrawTrk (TImage *plot); - void __fastcall DrawSky (TCanvas *c, int w, int h, int x0, int y0); - void __fastcall DrawText (TCanvas *c, int x, int y, UTF8String s, - TColor color, int ha, int va); - void __fastcall DrawArrow (TCanvas *c, int x, int y, int siz, - int ang, TColor color); - void __fastcall OpenMoniPort (int port); - void __fastcall InitSolBuff (void); - void __fastcall SaveLog (void); - void __fastcall LoadNav (nav_t *nav); - void __fastcall SaveNav (nav_t *nav); - void __fastcall LoadOpt (void); - void __fastcall SaveOpt (void); - void __fastcall SetTrayIcon (int index); - int __fastcall ExecCmd (AnsiString cmd, int show); - TColor __fastcall SnrColor (int snr); -public: - AnsiString IniFile; - - int TimerCycle,TimerInact; - int PanelStack,PanelMode; - int SvrCycle,SvrBuffSize,Scale,SolBuffSize,NavSelect,SavedSol; - int NmeaReq,NmeaCycle,InTimeTag,InTime64Bit; - int OutTimeTag,OutAppend,LogTimeTag,LogAppend; - int TimeoutTime,ReconTime,SbasCorr,DgpsCorr,TideCorr,FileSwapMargin; - int Stream[MAXSTRRTK],StreamC[MAXSTRRTK],Format[MAXSTRRTK]; - int CmdEna[3][3],CmdEnaTcp[3][3]; - int TimeSys,SolType; - int PlotType1,FreqType1,PlotType2,FreqType2; - int PlotType3,FreqType3,PlotType4,FreqType4; - int TrkType1,TrkType2,TrkType3,TrkType4; - int TrkScale1,TrkScale2,TrkScale3,TrkScale4; - int BLMode1,BLMode2,BLMode3,BLMode4; - int MoniPort,OpenPort,AutoRun; - - int PSol,PSolS,PSolE,Nsat[2],SolCurrentStat; - int Sat[2][MAXSAT],Snr[2][MAXSAT][NFREQ],Vsat[2][MAXSAT]; - double Az[2][MAXSAT],El[2][MAXSAT]; - gtime_t *Time; - int *SolStat,*Nvsat; - double *SolRov,*SolRef,*Qr,*VelRov,*Age,*Ratio; - double TrkOri[3],MaxBL; - AnsiString Paths[MAXSTRRTK][4],Cmds[3][3],CmdsTcp[3][3]; - AnsiString InTimeStart,InTimeSpeed,ExSats; - AnsiString RcvOpt[3],ProxyAddr; - AnsiString OutSwapInterval,LogSwapInterval,ResetCmd; - prcopt_t PrcOpt; - solopt_t SolOpt; - TFont *PanelFont,*PosFont; - int OutputGeoidF,BaselineC; - int RovPosTypeF,RefPosTypeF,RovAntPcvF,RefAntPcvF; - AnsiString RovAntF,RefAntF,SatPcvFileF,AntPcvFileF; - double RovAntDel[3],RefAntDel[3],RovPos[3],RefPos[3],NmeaPos[3]; - double Baseline[2]; - AnsiString History[10],MntpHist[10]; - - AnsiString GeoidDataFileF,StaPosFileF,DCBFileF,EOPFileF,BLQFileF; - AnsiString LocalDirectory,PntName[MAXMAPPNT]; - double PntPos[MAXMAPPNT][3]; - int NMapPnt; - - AnsiString MarkerName,MarkerComment; - - __fastcall TMainForm(TComponent* Owner); +class TMainForm : public TForm { + __published : TPanel *Panel1; + TPanel *Panel2; + TPanel *Panel3; + TPanel *Panel11; + + TLabel *LabelTime; + TLabel *Message; + + TPopupMenu *PopupMenu; + TMenuItem *MenuMonitor; + TMenuItem *MenuExpand; + TMenuItem *N1; + TMenuItem *MenuStart; + TMenuItem *MenuPlot; + TMenuItem *N2; + TMenuItem *MenuExit; + TMenuItem *MenuStop; + + TSpeedButton *BtnTimeSys; + + TTrayIcon *TrayIcon; + + TSaveDialog *SaveDialog; + + TImageList *ImageList; + + TTimer *Timer; + TPanel *Panel4; + TSpeedButton *BtnTaskTray; + TSpeedButton *BtnAbout; + TSpeedButton *BtnMonitor; + TPanel *Panel12; + TImage *Image1; + TImage *Image2; + TPanel *Str1; + TPanel *Str2; + TPanel *Str3; + TPanel *Str4; + TPanel *Str5; + TPanel *Str6; + TPanel *Str7; + TPanel *Str8; + TPanel *Svr; + TPanel *Panel122; + TSpeedButton *BtnOutputStr; + TPanel *Panel123; + TSpeedButton *BtnLogStr; + TPanel *Panel121; + TSpeedButton *BtnInputStr; + TPanel *Panel21; + TPanel *Panel211; + TLabel *LabelNSat; + TLabel *LabelStd; + TLabel *Plabel1; + TLabel *Plabel2; + TLabel *Plabel3; + TLabel *PlabelA; + TLabel *Pos1; + TLabel *Pos2; + TLabel *Pos3; + TLabel *Solution; + TPanel *IndSol; + TPanel *Panel213; + TScrollBar *ScbSol; + TButton *BtnSave; + TPanel *Panel212; + TLabel *Plabel0; + TSplitter *Splitter1; + TPanel *Panel22; + TImage *Plot1; + TSpeedButton *BtnFreqType1; + TSplitter *Splitter2; + TPanel *Panel23; + TImage *Disp2; + TImage *Plot2; + TSpeedButton *BtnFreqType2; + TImage *Disp1; + TSpeedButton *BtnSolType; + TSpeedButton *BtnPlotType1; + TSpeedButton *BtnPlotType2; + TSpeedButton *BtnPanel; + TPanel *Pane6; + TPanel *Panel5; + TPanel *IndQ; + TLabel *SolS; + TLabel *SolQ; + TSpeedButton *BtnSolType2; + TBitBtn *BtnStart; + TBitBtn *BtnMark; + TBitBtn *BtnPlot; + TBitBtn *BtnOpt; + TBitBtn *BtnExit; + TBitBtn *BtnStop; + TSpeedButton *BtnExpand1; + TSpeedButton *BtnShrink1; + TSpeedButton *BtnExpand2; + TSpeedButton *BtnShrink2; + TPanel *Panel24; + TImage *Disp3; + TImage *Plot3; + TSpeedButton *BtnFreqType3; + TSpeedButton *BtnPlotType3; + TSpeedButton *BtnExpand3; + TSpeedButton *BtnShrink3; + TPanel *Panel25; + TImage *Disp4; + TImage *Plot4; + TSpeedButton *BtnFreqType4; + TSpeedButton *BtnPlotType4; + TSpeedButton *BtnExpand4; + TSpeedButton *BtnShrink4; + TSplitter *Splitter3; + TSplitter *Splitter4; + + void __fastcall FormCreate(TObject *Sender); + void __fastcall FormShow(TObject *Sender); + void __fastcall FormClose(TObject *Sender, TCloseAction &Action); + + void __fastcall TimerTimer(TObject *Sender); + + void __fastcall BtnStartClick(TObject *Sender); + void __fastcall BtnStopClick(TObject *Sender); + void __fastcall BtnPlotClick(TObject *Sender); + void __fastcall BtnOptClick(TObject *Sender); + void __fastcall BtnExitClick(TObject *Sender); + + void __fastcall BtnTimeSysClick(TObject *Sender); + void __fastcall BtnInputStrClick(TObject *Sender); + void __fastcall BtnOutputStrClick(TObject *Sender); + void __fastcall BtnLogStrClick(TObject *Sender); + void __fastcall BtnSolTypeClick(TObject *Sender); + void __fastcall BtnPlotType1Click(TObject *Sender); + + void __fastcall BtnMonitorClick(TObject *Sender); + void __fastcall BtnSaveClick(TObject *Sender); + void __fastcall BtnAboutClick(TObject *Sender); + void __fastcall BtnTaskTrayClick(TObject *Sender); + + void __fastcall MenuExpandClick(TObject *Sender); + void __fastcall MenuStartClick(TObject *Sender); + void __fastcall MenuStopClick(TObject *Sender); + void __fastcall MenuPlotClick(TObject *Sender); + void __fastcall MenuMonitorClick(TObject *Sender); + void __fastcall MenuExitClick(TObject *Sender); + + void __fastcall ScbSolChange(TObject *Sender); + + void __fastcall TrayIconDblClick(TObject *Sender); + void __fastcall BtnFreqType1Click(TObject *Sender); + void __fastcall Panel22Resize(TObject *Sender); + void __fastcall Panel4Resize(TObject *Sender); + void __fastcall Panel21Resize(TObject *Sender); + void __fastcall Panel23Resize(TObject *Sender); + void __fastcall BtnPanelClick(TObject *Sender); + void __fastcall BtnPlotType2Click(TObject *Sender); + void __fastcall BtnFreqType2Click(TObject *Sender); + void __fastcall Panel211Resize(TObject *Sender); + void __fastcall Panel5Resize(TObject *Sender); + void __fastcall BtnExpand1Click(TObject *Sender); + void __fastcall BtnShrink1Click(TObject *Sender); + void __fastcall BtnExpand2Click(TObject *Sender); + void __fastcall BtnShrink2Click(TObject *Sender); + void __fastcall BtnMarkClick(TObject *Sender); + void __fastcall Panel24Resize(TObject *Sender); + void __fastcall Panel25Resize(TObject *Sender); + void __fastcall BtnPlotType3Click(TObject *Sender); + void __fastcall BtnFreqType3Click(TObject *Sender); + void __fastcall BtnPlotType4Click(TObject *Sender); + void __fastcall BtnFreqType4Click(TObject *Sender); + + private: + void __fastcall UpdateLog(int stat, gtime_t time, double *rr, float *qr, double *rb, int ns, + double age, double ratio); + void __fastcall SvrStart(void); + void __fastcall SvrStop(void); + void __fastcall UpdatePanel(void); + void __fastcall UpdateTimeSys(void); + void __fastcall UpdateSolType(void); + void __fastcall UpdateFont(void); + void __fastcall UpdateTime(void); + void __fastcall UpdatePos(void); + void __fastcall UpdateStr(void); + void __fastcall DrawPlot(TImage *plot, int type, int freq); + void __fastcall UpdatePlot(void); + void __fastcall UpdateEnable(void); + void __fastcall ChangePlot(void); + int __fastcall ConfOverwrite(const char *path); + + void __fastcall DrawSnr(TCanvas *c, int w, int h, int x0, int y0, int index, int freq); + void __fastcall DrawSat(TCanvas *c, int w, int h, int x0, int y0, int index, int freq); + void __fastcall DrawBL(TImage *plot, int w, int h); + void __fastcall DrawTrk(TImage *plot); + void __fastcall DrawSky(TCanvas *c, int w, int h, int x0, int y0); + void __fastcall DrawText(TCanvas *c, int x, int y, UTF8String s, TColor color, int ha, int va); + void __fastcall DrawArrow(TCanvas *c, int x, int y, int siz, int ang, TColor color); + void __fastcall OpenMoniPort(int port); + void __fastcall InitSolBuff(void); + void __fastcall SaveLog(void); + void __fastcall LoadNav(nav_t *nav); + void __fastcall SaveNav(nav_t *nav); + void __fastcall LoadOpt(void); + void __fastcall SaveOpt(void); + void __fastcall SetTrayIcon(int index); + int __fastcall ExecCmd(AnsiString cmd, int show); + TColor __fastcall SnrColor(int snr); + + public: + AnsiString IniFile; + + int TimerCycle, TimerInact; + int PanelStack, PanelMode; + int SvrCycle, SvrBuffSize, Scale, SolBuffSize, NavSelect, SavedSol; + int NmeaReq, NmeaCycle, InTimeTag, InTime64Bit; + int OutTimeTag, OutAppend, LogTimeTag, LogAppend; + int TimeoutTime, ReconTime, SbasCorr, DgpsCorr, TideCorr, FileSwapMargin; + int Stream[MAXSTRRTK], StreamC[MAXSTRRTK], Format[MAXSTRRTK]; + int CmdEna[3][3], CmdEnaTcp[3][3]; + int TimeSys, SolType; + int PlotType1, FreqType1, PlotType2, FreqType2; + int PlotType3, FreqType3, PlotType4, FreqType4; + int TrkType1, TrkType2, TrkType3, TrkType4; + int TrkScale1, TrkScale2, TrkScale3, TrkScale4; + int BLMode1, BLMode2, BLMode3, BLMode4; + int MoniPort, OpenPort, AutoRun; + + int PSol, PSolS, PSolE, Nsat[2], SolCurrentStat; + int Sat[2][MAXSAT], Snr[2][MAXSAT][NFREQ], Vsat[2][MAXSAT]; + double Az[2][MAXSAT], El[2][MAXSAT]; + gtime_t *Time; + int *SolStat, *Nvsat; + double *SolRov, *SolRef, *Qr, *VelRov, *Age, *Ratio; + double TrkOri[3], MaxBL; + AnsiString Paths[MAXSTRRTK][4], Cmds[3][3], CmdsTcp[3][3]; + AnsiString InTimeStart, InTimeSpeed, ExSats; + AnsiString RcvOpt[3], ProxyAddr; + AnsiString OutSwapInterval, LogSwapInterval, ResetCmd; + prcopt_t PrcOpt; + solopt_t SolOpt; + TFont *PanelFont, *PosFont; + int OutputGeoidF, BaselineC; + int RovPosTypeF, RefPosTypeF, RovAntPcvF, RefAntPcvF; + AnsiString RovAntF, RefAntF, SatPcvFileF, AntPcvFileF; + double RovAntDel[3], RefAntDel[3], RovPos[3], RefPos[3], NmeaPos[3]; + double Baseline[2]; + AnsiString History[10], MntpHist[10]; + + AnsiString GeoidDataFileF, StaPosFileF, DCBFileF, EOPFileF, BLQFileF; + AnsiString LocalDirectory, PntName[MAXMAPPNT]; + double PntPos[MAXMAPPNT][3]; + int NMapPnt; + + AnsiString MarkerName, MarkerComment; + + __fastcall TMainForm(TComponent *Owner); }; //--------------------------------------------------------------------------- extern PACKAGE TMainForm *MainForm; diff --git a/app/winapp/rtknavi/naviopt.cpp b/app/winapp/rtknavi/naviopt.cpp index 78fa19289..02f6e920d 100644 --- a/app/winapp/rtknavi/naviopt.cpp +++ b/app/winapp/rtknavi/naviopt.cpp @@ -2,1332 +2,1235 @@ #include #pragma hdrstop -#include "rtklib.h" #include "naviopt.h" -#include "viewer.h" -#include "refdlg.h" -#include "navimain.h" -#include "maskoptdlg.h" + #include "freqdlg.h" +#include "maskoptdlg.h" +#include "navimain.h" +#include "refdlg.h" +#include "rtklib.h" +#include "viewer.h" //--------------------------------------------------------------------------- #pragma package(smart_init) #pragma resource "*.dfm" TOptDialog *OptDialog; -#define MAXSTR 1024 /* max length of a string */ +#define MAXSTR 1024 /* max length of a string */ //--------------------------------------------------------------------------- -static double str2dbl(AnsiString str) -{ - double val=0.0; - sscanf(str.c_str(),"%lf",&val); - return val; +static double str2dbl(AnsiString str) { + double val = 0.0; + sscanf(str.c_str(), "%lf", &val); + return val; } // receiver options table --------------------------------------------------- -static int strtype[]={ /* stream types */ - STR_NONE,STR_NONE,STR_NONE,STR_NONE,STR_NONE,STR_NONE,STR_NONE,STR_NONE -}; -static char strpath[8][MAXSTR]={""}; /* stream paths */ -static int strfmt[]={ /* stream formats */ - STRFMT_RTCM3,STRFMT_RTCM3,STRFMT_SP3,SOLF_LLH,SOLF_NMEA,0,0,0 -}; -static int svrcycle =10; /* server cycle (ms) */ -static int timeout =10000; /* timeout time (ms) */ -static int reconnect =10000; /* reconnect interval (ms) */ -static int nmeacycle =5000; /* nmea request cycle (ms) */ -static int fswapmargin =30; /* file swap marign (s) */ -static int buffsize =32768; /* input buffer size (bytes) */ -static int navmsgsel =0; /* navigation mesaage select */ -static int nmeareq =0; /* nmea request type (0:off,1:lat/lon,2:single) */ -static double nmeapos[] ={0,0}; /* nmea position (lat/lon) (deg) */ -static char proxyaddr[MAXSTR]=""; /* proxy address */ - -#define TIMOPT "0:gpst,1:utc,2:jst,3:tow" -#define CONOPT "0:dms,1:deg,2:xyz,3:enu,4:pyl" -#define FLGOPT "0:off,1:std+2:age/ratio/ns" -#define ISTOPT "0:off,1:serial,2:file,3:tcpsvr,4:tcpcli,6:ntripcli,7:ftp,8:http" -#define OSTOPT "0:off,1:serial,2:file,3:tcpsvr,4:tcpcli,5:ntripsvr,9:ntripcas" -#define FMTOPT "0:rtcm2,1:rtcm3,2:oem4,4:ubx,5:swift,6:hemis,7:skytraq,8:javad,9:nvs,10:binex,11:rt17,12:sbf,14:unicore,15:rinex,16:sp3,17:clk" -#define NMEOPT "0:off,1:latlon,2:single" -#define SOLOPT "0:llh,1:xyz,2:enu,3:nmea,4:stat" -#define MSGOPT "0:all,1:rover,2:base,3:corr" - -static opt_t rcvopts[]={ - {"inpstr1-type", 3, (void *)&strtype[0], ISTOPT }, - {"inpstr2-type", 3, (void *)&strtype[1], ISTOPT }, - {"inpstr3-type", 3, (void *)&strtype[2], ISTOPT }, - {"inpstr1-path", 2, (void *)strpath [0], "" }, - {"inpstr2-path", 2, (void *)strpath [1], "" }, - {"inpstr3-path", 2, (void *)strpath [2], "" }, - {"inpstr1-format", 3, (void *)&strfmt [0], FMTOPT }, - {"inpstr2-format", 3, (void *)&strfmt [1], FMTOPT }, - {"inpstr3-format", 3, (void *)&strfmt [2], FMTOPT }, - {"inpstr2-nmeareq", 3, (void *)&nmeareq, NMEOPT }, - {"inpstr2-nmealat", 1, (void *)&nmeapos[0], "deg" }, - {"inpstr2-nmealon", 1, (void *)&nmeapos[1], "deg" }, - {"outstr1-type", 3, (void *)&strtype[3], OSTOPT }, - {"outstr2-type", 3, (void *)&strtype[4], OSTOPT }, - {"outstr1-path", 2, (void *)strpath [3], "" }, - {"outstr2-path", 2, (void *)strpath [4], "" }, - {"outstr1-format", 3, (void *)&strfmt [3], SOLOPT }, - {"outstr2-format", 3, (void *)&strfmt [4], SOLOPT }, - {"logstr1-type", 3, (void *)&strtype[5], OSTOPT }, - {"logstr2-type", 3, (void *)&strtype[6], OSTOPT }, - {"logstr3-type", 3, (void *)&strtype[7], OSTOPT }, - {"logstr1-path", 2, (void *)strpath [5], "" }, - {"logstr2-path", 2, (void *)strpath [6], "" }, - {"logstr3-path", 2, (void *)strpath [7], "" }, - - {"misc-svrcycle", 0, (void *)&svrcycle, "ms" }, - {"misc-timeout", 0, (void *)&timeout, "ms" }, - {"misc-reconnect", 0, (void *)&reconnect, "ms" }, - {"misc-nmeacycle", 0, (void *)&nmeacycle, "ms" }, - {"misc-buffsize", 0, (void *)&buffsize, "bytes"}, - {"misc-navmsgsel", 3, (void *)&navmsgsel, MSGOPT }, - {"misc-proxyaddr", 2, (void *)proxyaddr, "" }, - {"misc-fswapmargin",0, (void *)&fswapmargin, "s" }, - - {"",0,NULL,""} -}; +static int strtype[] = {/* stream types */ + STR_NONE, STR_NONE, STR_NONE, STR_NONE, + STR_NONE, STR_NONE, STR_NONE, STR_NONE}; +static char strpath[8][MAXSTR] = {""}; /* stream paths */ +static int strfmt[] = { /* stream formats */ + STRFMT_RTCM3, STRFMT_RTCM3, STRFMT_SP3, SOLF_LLH, SOLF_NMEA, 0, 0, 0}; +static int svrcycle = 10; /* server cycle (ms) */ +static int timeout = 10000; /* timeout time (ms) */ +static int reconnect = 10000; /* reconnect interval (ms) */ +static int nmeacycle = 5000; /* nmea request cycle (ms) */ +static int fswapmargin = 30; /* file swap marign (s) */ +static int buffsize = 32768; /* input buffer size (bytes) */ +static int navmsgsel = 0; /* navigation mesaage select */ +static int nmeareq = 0; /* nmea request type (0:off,1:lat/lon,2:single) */ +static double nmeapos[] = {0, 0}; /* nmea position (lat/lon) (deg) */ +static char proxyaddr[MAXSTR] = ""; /* proxy address */ + +#define TIMOPT "0:gpst,1:utc,2:jst,3:tow" +#define CONOPT "0:dms,1:deg,2:xyz,3:enu,4:pyl" +#define FLGOPT "0:off,1:std+2:age/ratio/ns" +#define ISTOPT "0:off,1:serial,2:file,3:tcpsvr,4:tcpcli,6:ntripcli,7:ftp,8:http" +#define OSTOPT "0:off,1:serial,2:file,3:tcpsvr,4:tcpcli,5:ntripsvr,9:ntripcas" +#define FMTOPT \ + "0:rtcm2,1:rtcm3,2:oem4,4:ubx,5:swift,6:hemis,7:skytraq,8:javad,9:nvs,10:binex,11:rt17,12:sbf," \ + "14:unicore,15:rinex,16:sp3,17:clk" +#define NMEOPT "0:off,1:latlon,2:single" +#define SOLOPT "0:llh,1:xyz,2:enu,3:nmea,4:stat" +#define MSGOPT "0:all,1:rover,2:base,3:corr" + +static opt_t rcvopts[] = {{"inpstr1-type", 3, (void *)&strtype[0], ISTOPT}, + {"inpstr2-type", 3, (void *)&strtype[1], ISTOPT}, + {"inpstr3-type", 3, (void *)&strtype[2], ISTOPT}, + {"inpstr1-path", 2, (void *)strpath[0], ""}, + {"inpstr2-path", 2, (void *)strpath[1], ""}, + {"inpstr3-path", 2, (void *)strpath[2], ""}, + {"inpstr1-format", 3, (void *)&strfmt[0], FMTOPT}, + {"inpstr2-format", 3, (void *)&strfmt[1], FMTOPT}, + {"inpstr3-format", 3, (void *)&strfmt[2], FMTOPT}, + {"inpstr2-nmeareq", 3, (void *)&nmeareq, NMEOPT}, + {"inpstr2-nmealat", 1, (void *)&nmeapos[0], "deg"}, + {"inpstr2-nmealon", 1, (void *)&nmeapos[1], "deg"}, + {"outstr1-type", 3, (void *)&strtype[3], OSTOPT}, + {"outstr2-type", 3, (void *)&strtype[4], OSTOPT}, + {"outstr1-path", 2, (void *)strpath[3], ""}, + {"outstr2-path", 2, (void *)strpath[4], ""}, + {"outstr1-format", 3, (void *)&strfmt[3], SOLOPT}, + {"outstr2-format", 3, (void *)&strfmt[4], SOLOPT}, + {"logstr1-type", 3, (void *)&strtype[5], OSTOPT}, + {"logstr2-type", 3, (void *)&strtype[6], OSTOPT}, + {"logstr3-type", 3, (void *)&strtype[7], OSTOPT}, + {"logstr1-path", 2, (void *)strpath[5], ""}, + {"logstr2-path", 2, (void *)strpath[6], ""}, + {"logstr3-path", 2, (void *)strpath[7], ""}, + + {"misc-svrcycle", 0, (void *)&svrcycle, "ms"}, + {"misc-timeout", 0, (void *)&timeout, "ms"}, + {"misc-reconnect", 0, (void *)&reconnect, "ms"}, + {"misc-nmeacycle", 0, (void *)&nmeacycle, "ms"}, + {"misc-buffsize", 0, (void *)&buffsize, "bytes"}, + {"misc-navmsgsel", 3, (void *)&navmsgsel, MSGOPT}, + {"misc-proxyaddr", 2, (void *)proxyaddr, ""}, + {"misc-fswapmargin", 0, (void *)&fswapmargin, "s"}, + + {"", 0, NULL, ""}}; //--------------------------------------------------------------------------- -__fastcall TOptDialog::TOptDialog(TComponent* Owner) - : TForm(Owner) -{ - AnsiString label,s; - int nglo=MAXPRNGLO,ngal=MAXPRNGAL,nqzs=MAXPRNQZS; - int ncmp=MAXPRNCMP,nirn=MAXPRNIRN; - - PrcOpt=prcopt_default; - SolOpt=solopt_default; - UpdateEnable(); - PanelFont=new TFont; - PosFont=new TFont; - - Freq->Items->Clear(); - for (int i=0;i0?"+":"")+s.sprintf("L%d",i + 1); - Freq->Items->Add(label); - } - if (nglo<=0) NavSys2->Enabled=false; - if (ngal<=0) NavSys3->Enabled=false; - if (nqzs<=0) NavSys4->Enabled=false; - if (ncmp<=0) NavSys6->Enabled=false; - if (nirn<=0) NavSys7->Enabled=false; - UpdateEnable(); +__fastcall TOptDialog::TOptDialog(TComponent *Owner) : TForm(Owner) { + AnsiString label, s; + int nglo = MAXPRNGLO, ngal = MAXPRNGAL, nqzs = MAXPRNQZS; + int ncmp = MAXPRNCMP, nirn = MAXPRNIRN; + + PrcOpt = prcopt_default; + SolOpt = solopt_default; + UpdateEnable(); + PanelFont = new TFont; + PosFont = new TFont; + + Freq->Items->Clear(); + for (int i = 0; i < NFREQ; i++) { + label = label + (i > 0 ? "+" : "") + s.sprintf("L%d", i + 1); + Freq->Items->Add(label); + } + if (nglo <= 0) NavSys2->Enabled = false; + if (ngal <= 0) NavSys3->Enabled = false; + if (nqzs <= 0) NavSys4->Enabled = false; + if (ncmp <= 0) NavSys6->Enabled = false; + if (nirn <= 0) NavSys7->Enabled = false; + UpdateEnable(); } //--------------------------------------------------------------------------- -void __fastcall TOptDialog::FormShow(TObject *Sender) -{ - GetOpt(); -} +void __fastcall TOptDialog::FormShow(TObject *Sender) { GetOpt(); } //--------------------------------------------------------------------------- -void __fastcall TOptDialog::BtnOkClick(TObject *Sender) -{ - SetOpt(); -} +void __fastcall TOptDialog::BtnOkClick(TObject *Sender) { SetOpt(); } //--------------------------------------------------------------------------- -void __fastcall TOptDialog::BtnLoadClick(TObject *Sender) -{ - OpenDialog->Title="Load Options"; - OpenDialog->FilterIndex=4; - if (!OpenDialog->Execute()) return; - LoadOpt(OpenDialog->FileName); +void __fastcall TOptDialog::BtnLoadClick(TObject *Sender) { + OpenDialog->Title = "Load Options"; + OpenDialog->FilterIndex = 4; + if (!OpenDialog->Execute()) return; + LoadOpt(OpenDialog->FileName); } //--------------------------------------------------------------------------- -void __fastcall TOptDialog::BtnSaveClick(TObject *Sender) -{ - AnsiString file; - SaveDialog->Title="Save Options"; - SaveDialog->FilterIndex=2; - if (!SaveDialog->Execute()) return; - file=SaveDialog->FileName; - if (!strrchr(file.c_str(),'.')) file=file+".conf"; - SaveOpt(file); +void __fastcall TOptDialog::BtnSaveClick(TObject *Sender) { + AnsiString file; + SaveDialog->Title = "Save Options"; + SaveDialog->FilterIndex = 2; + if (!SaveDialog->Execute()) return; + file = SaveDialog->FileName; + if (!strrchr(file.c_str(), '.')) file = file + ".conf"; + SaveOpt(file); } //--------------------------------------------------------------------------- -void __fastcall TOptDialog::BtnStaPosViewClick(TObject *Sender) -{ - if (StaPosFile->Text=="") return; - TTextViewer *viewer=new TTextViewer(Application); - viewer->Show(); - viewer->Read(StaPosFile->Text); +void __fastcall TOptDialog::BtnStaPosViewClick(TObject *Sender) { + if (StaPosFile->Text == "") return; + TTextViewer *viewer = new TTextViewer(Application); + viewer->Show(); + viewer->Read(StaPosFile->Text); } //--------------------------------------------------------------------------- -void __fastcall TOptDialog::BtnStaPosFileClick(TObject *Sender) -{ - OpenDialog->Title="Station Position File"; - OpenDialog->FilterIndex=3; - if (!OpenDialog->Execute()) return; - StaPosFile->Text=OpenDialog->FileName; +void __fastcall TOptDialog::BtnStaPosFileClick(TObject *Sender) { + OpenDialog->Title = "Station Position File"; + OpenDialog->FilterIndex = 3; + if (!OpenDialog->Execute()) return; + StaPosFile->Text = OpenDialog->FileName; } //--------------------------------------------------------------------------- -void __fastcall TOptDialog::BtnSnrMaskClick(TObject *Sender) -{ - MaskOptDialog->Mask=PrcOpt.snrmask; - if (MaskOptDialog->ShowModal()!=mrOk) return; - PrcOpt.snrmask=MaskOptDialog->Mask; +void __fastcall TOptDialog::BtnSnrMaskClick(TObject *Sender) { + MaskOptDialog->Mask = PrcOpt.snrmask; + if (MaskOptDialog->ShowModal() != mrOk) return; + PrcOpt.snrmask = MaskOptDialog->Mask; } //--------------------------------------------------------------------------- -void __fastcall TOptDialog::RovPosTypePChange(TObject *Sender) -{ - TEdit *edit[]={RovPos1,RovPos2,RovPos3}; - double pos[3]; - GetPos(RovPosTypeF,edit,pos); - SetPos(RovPosTypeP->ItemIndex,edit,pos); - RovPosTypeF=RovPosTypeP->ItemIndex; - UpdateEnable(); +void __fastcall TOptDialog::RovPosTypePChange(TObject *Sender) { + TEdit *edit[] = {RovPos1, RovPos2, RovPos3}; + double pos[3]; + GetPos(RovPosTypeF, edit, pos); + SetPos(RovPosTypeP->ItemIndex, edit, pos); + RovPosTypeF = RovPosTypeP->ItemIndex; + UpdateEnable(); } //--------------------------------------------------------------------------- -void __fastcall TOptDialog::RefPosTypePChange(TObject *Sender) -{ - TEdit *edit[]={RefPos1,RefPos2,RefPos3}; - double pos[3]; - GetPos(RefPosTypeF,edit,pos); - SetPos(RefPosTypeP->ItemIndex,edit,pos); - RefPosTypeF=RefPosTypeP->ItemIndex; - UpdateEnable(); +void __fastcall TOptDialog::RefPosTypePChange(TObject *Sender) { + TEdit *edit[] = {RefPos1, RefPos2, RefPos3}; + double pos[3]; + GetPos(RefPosTypeF, edit, pos); + SetPos(RefPosTypeP->ItemIndex, edit, pos); + RefPosTypeF = RefPosTypeP->ItemIndex; + UpdateEnable(); } //--------------------------------------------------------------------------- -void __fastcall TOptDialog::BtnRovPosClick(TObject *Sender) -{ - TEdit *edit[]={RovPos1,RovPos2,RovPos3}; - double p[3],pos[3]; - GetPos(RovPosTypeP->ItemIndex,edit,p); - ecef2pos(p,pos); - RefDialog->RovPos[0]=pos[0]*R2D; - RefDialog->RovPos[1]=pos[1]*R2D; - RefDialog->Pos[2]=pos[2]; - RefDialog->StaPosFile=StaPosFile->Text; - RefDialog->Left=Left+Width/2-RefDialog->Width/2; - RefDialog->Top=Top+Height/2-RefDialog->Height/2; - if (RefDialog->ShowModal()!=mrOk) return; - pos[0]=RefDialog->Pos[0]*D2R; - pos[1]=RefDialog->Pos[1]*D2R; - pos[2]=RefDialog->Pos[2]; - pos2ecef(pos,p); - SetPos(RovPosTypeP->ItemIndex,edit,p); +void __fastcall TOptDialog::BtnRovPosClick(TObject *Sender) { + TEdit *edit[] = {RovPos1, RovPos2, RovPos3}; + double p[3], pos[3]; + GetPos(RovPosTypeP->ItemIndex, edit, p); + ecef2pos(p, pos); + RefDialog->RovPos[0] = pos[0] * R2D; + RefDialog->RovPos[1] = pos[1] * R2D; + RefDialog->Pos[2] = pos[2]; + RefDialog->StaPosFile = StaPosFile->Text; + RefDialog->Left = Left + Width / 2 - RefDialog->Width / 2; + RefDialog->Top = Top + Height / 2 - RefDialog->Height / 2; + if (RefDialog->ShowModal() != mrOk) return; + pos[0] = RefDialog->Pos[0] * D2R; + pos[1] = RefDialog->Pos[1] * D2R; + pos[2] = RefDialog->Pos[2]; + pos2ecef(pos, p); + SetPos(RovPosTypeP->ItemIndex, edit, p); } //--------------------------------------------------------------------------- -void __fastcall TOptDialog::BtnRefPosClick(TObject *Sender) -{ - TEdit *edit[]={RefPos1,RefPos2,RefPos3}; - double p[3],pos[3]; - GetPos(RefPosTypeP->ItemIndex,edit,p); - ecef2pos(p,pos); - RefDialog->RovPos[0]=pos[0]*R2D; - RefDialog->RovPos[1]=pos[1]*R2D; - RefDialog->RovPos[2]=pos[2]; - RefDialog->StaPosFile=StaPosFile->Text; - RefDialog->Left=Left+Width/2-RefDialog->Width/2; - RefDialog->Top=Top+Height/2-RefDialog->Height/2; - if (RefDialog->ShowModal()!=mrOk) return; - pos[0]=RefDialog->Pos[0]*D2R; - pos[1]=RefDialog->Pos[1]*D2R; - pos[2]=RefDialog->Pos[2]; - pos2ecef(pos,p); - SetPos(RefPosTypeP->ItemIndex,edit,p); +void __fastcall TOptDialog::BtnRefPosClick(TObject *Sender) { + TEdit *edit[] = {RefPos1, RefPos2, RefPos3}; + double p[3], pos[3]; + GetPos(RefPosTypeP->ItemIndex, edit, p); + ecef2pos(p, pos); + RefDialog->RovPos[0] = pos[0] * R2D; + RefDialog->RovPos[1] = pos[1] * R2D; + RefDialog->RovPos[2] = pos[2]; + RefDialog->StaPosFile = StaPosFile->Text; + RefDialog->Left = Left + Width / 2 - RefDialog->Width / 2; + RefDialog->Top = Top + Height / 2 - RefDialog->Height / 2; + if (RefDialog->ShowModal() != mrOk) return; + pos[0] = RefDialog->Pos[0] * D2R; + pos[1] = RefDialog->Pos[1] * D2R; + pos[2] = RefDialog->Pos[2]; + pos2ecef(pos, p); + SetPos(RefPosTypeP->ItemIndex, edit, p); } //--------------------------------------------------------------------------- -void __fastcall TOptDialog::BtnSatPcvViewClick(TObject *Sender) -{ - if (SatPcvFile->Text=="") return; - TTextViewer *viewer=new TTextViewer(Application); - viewer->Show(); - viewer->Read(SatPcvFile->Text); +void __fastcall TOptDialog::BtnSatPcvViewClick(TObject *Sender) { + if (SatPcvFile->Text == "") return; + TTextViewer *viewer = new TTextViewer(Application); + viewer->Show(); + viewer->Read(SatPcvFile->Text); } //--------------------------------------------------------------------------- -void __fastcall TOptDialog::BtnSatPcvFileClick(TObject *Sender) -{ - OpenDialog->Title="Satellite Antenna PCV File"; - OpenDialog->FilterIndex=2; - if (!OpenDialog->Execute()) return; - SatPcvFile->Text=OpenDialog->FileName; +void __fastcall TOptDialog::BtnSatPcvFileClick(TObject *Sender) { + OpenDialog->Title = "Satellite Antenna PCV File"; + OpenDialog->FilterIndex = 2; + if (!OpenDialog->Execute()) return; + SatPcvFile->Text = OpenDialog->FileName; } //--------------------------------------------------------------------------- -void __fastcall TOptDialog::BtnAntPcvViewClick(TObject *Sender) -{ - if (AntPcvFile->Text=="") return; - TTextViewer *viewer=new TTextViewer(Application); - viewer->Show(); - viewer->Read(AntPcvFile->Text); +void __fastcall TOptDialog::BtnAntPcvViewClick(TObject *Sender) { + if (AntPcvFile->Text == "") return; + TTextViewer *viewer = new TTextViewer(Application); + viewer->Show(); + viewer->Read(AntPcvFile->Text); } //--------------------------------------------------------------------------- -void __fastcall TOptDialog::BtnAntPcvFileClick(TObject *Sender) -{ - OpenDialog->Title="Receiver Antenna PCV File"; - OpenDialog->FilterIndex=2; - if (!OpenDialog->Execute()) return; - AntPcvFile->Text=OpenDialog->FileName; +void __fastcall TOptDialog::BtnAntPcvFileClick(TObject *Sender) { + OpenDialog->Title = "Receiver Antenna PCV File"; + OpenDialog->FilterIndex = 2; + if (!OpenDialog->Execute()) return; + AntPcvFile->Text = OpenDialog->FileName; } //--------------------------------------------------------------------------- -void __fastcall TOptDialog::BtnGeoidDataFileClick(TObject *Sender) -{ - OpenDialog->Title="Geoid Data File"; - OpenDialog->FilterIndex=1; - if (!OpenDialog->Execute()) return; - GeoidDataFile->Text=OpenDialog->FileName; +void __fastcall TOptDialog::BtnGeoidDataFileClick(TObject *Sender) { + OpenDialog->Title = "Geoid Data File"; + OpenDialog->FilterIndex = 1; + if (!OpenDialog->Execute()) return; + GeoidDataFile->Text = OpenDialog->FileName; } //--------------------------------------------------------------------------- -void __fastcall TOptDialog::BtnDCBFileClick(TObject *Sender) -{ - OpenDialog->Title="DCB Data File"; - OpenDialog->FilterIndex=5; - if (!OpenDialog->Execute()) return; - DCBFile->Text=OpenDialog->FileName; +void __fastcall TOptDialog::BtnDCBFileClick(TObject *Sender) { + OpenDialog->Title = "DCB Data File"; + OpenDialog->FilterIndex = 5; + if (!OpenDialog->Execute()) return; + DCBFile->Text = OpenDialog->FileName; } //--------------------------------------------------------------------------- -void __fastcall TOptDialog::BtnEOPFileClick(TObject *Sender) -{ - OpenDialog->Title="EOP Data File"; - OpenDialog->FilterIndex=6; - if (!OpenDialog->Execute()) return; - EOPFile->Text=OpenDialog->FileName; +void __fastcall TOptDialog::BtnEOPFileClick(TObject *Sender) { + OpenDialog->Title = "EOP Data File"; + OpenDialog->FilterIndex = 6; + if (!OpenDialog->Execute()) return; + EOPFile->Text = OpenDialog->FileName; } //--------------------------------------------------------------------------- -void __fastcall TOptDialog::BtnDCBViewClick(TObject *Sender) -{ - if (DCBFile->Text=="") return; - TTextViewer *viewer=new TTextViewer(Application); - viewer->Show(); - viewer->Read(DCBFile->Text); +void __fastcall TOptDialog::BtnDCBViewClick(TObject *Sender) { + if (DCBFile->Text == "") return; + TTextViewer *viewer = new TTextViewer(Application); + viewer->Show(); + viewer->Read(DCBFile->Text); } //--------------------------------------------------------------------------- -void __fastcall TOptDialog::BtnEOPViewClick(TObject *Sender) -{ - if (EOPFile->Text=="") return; - TTextViewer *viewer=new TTextViewer(Application); - viewer->Show(); - viewer->Read(EOPFile->Text); +void __fastcall TOptDialog::BtnEOPViewClick(TObject *Sender) { + if (EOPFile->Text == "") return; + TTextViewer *viewer = new TTextViewer(Application); + viewer->Show(); + viewer->Read(EOPFile->Text); } //--------------------------------------------------------------------------- -void __fastcall TOptDialog::BtnBLQFileClick(TObject *Sender) -{ - OpenDialog->Title="Ocean Tide Loading BLQ File"; - OpenDialog->FilterIndex=7; - if (!OpenDialog->Execute()) return; - BLQFile->Text=OpenDialog->FileName; +void __fastcall TOptDialog::BtnBLQFileClick(TObject *Sender) { + OpenDialog->Title = "Ocean Tide Loading BLQ File"; + OpenDialog->FilterIndex = 7; + if (!OpenDialog->Execute()) return; + BLQFile->Text = OpenDialog->FileName; } //--------------------------------------------------------------------------- -void __fastcall TOptDialog::BtnBLQViewClick(TObject *Sender) -{ - if (BLQFile->Text=="") return; - TTextViewer *viewer=new TTextViewer(Application); - viewer->Show(); - viewer->Read(BLQFile->Text); +void __fastcall TOptDialog::BtnBLQViewClick(TObject *Sender) { + if (BLQFile->Text == "") return; + TTextViewer *viewer = new TTextViewer(Application); + viewer->Show(); + viewer->Read(BLQFile->Text); } -void __fastcall TOptDialog::BtnLocalDirClick(TObject *Sender) -{ - UnicodeString dir=LocalDir->Text; - TSelectDirExtOpts opt=TSelectDirExtOpts()<Text=dir; +void __fastcall TOptDialog::BtnLocalDirClick(TObject *Sender) { + UnicodeString dir = LocalDir->Text; + TSelectDirExtOpts opt = TSelectDirExtOpts() << sdNewUI << sdNewFolder; + if (!SelectDirectory(L"FTP/HTTP Local Directory", L"", dir, opt)) return; + LocalDir->Text = dir; } //--------------------------------------------------------------------------- -void __fastcall TOptDialog::BtnFont1Click(TObject *Sender) -{ - UTF8String s; - FontDialog->Font=FontLabel1->Font; - if (!FontDialog->Execute()) return; - FontLabel1->Font=FontDialog->Font; - FontLabel1->Caption=FontLabel1->Font->Name+s.sprintf(" %dpt",FontLabel1->Font->Size); +void __fastcall TOptDialog::BtnFont1Click(TObject *Sender) { + UTF8String s; + FontDialog->Font = FontLabel1->Font; + if (!FontDialog->Execute()) return; + FontLabel1->Font = FontDialog->Font; + FontLabel1->Caption = FontLabel1->Font->Name + s.sprintf(" %dpt", FontLabel1->Font->Size); } //--------------------------------------------------------------------------- -void __fastcall TOptDialog::BtnFont2Click(TObject *Sender) -{ - UTF8String s; - FontDialog->Font=FontLabel2->Font; - if (!FontDialog->Execute()) return; - FontLabel2->Font=FontDialog->Font; - FontLabel2->Caption=FontLabel2->Font->Name+s.sprintf(" %dpt",FontLabel2->Font->Size); +void __fastcall TOptDialog::BtnFont2Click(TObject *Sender) { + UTF8String s; + FontDialog->Font = FontLabel2->Font; + if (!FontDialog->Execute()) return; + FontLabel2->Font = FontDialog->Font; + FontLabel2->Caption = FontLabel2->Font->Name + s.sprintf(" %dpt", FontLabel2->Font->Size); } //--------------------------------------------------------------------------- -void __fastcall TOptDialog::FreqChange(TObject *Sender) -{ - UpdateEnable(); -} +void __fastcall TOptDialog::FreqChange(TObject *Sender) { UpdateEnable(); } //--------------------------------------------------------------------------- -void __fastcall TOptDialog::NavSys2Click(TObject *Sender) -{ - UpdateEnable(); -} +void __fastcall TOptDialog::NavSys2Click(TObject *Sender) { UpdateEnable(); } //--------------------------------------------------------------------------- -void __fastcall TOptDialog::BaselineConstClick(TObject *Sender) -{ - UpdateEnable(); -} +void __fastcall TOptDialog::BaselineConstClick(TObject *Sender) { UpdateEnable(); } //--------------------------------------------------------------------------- -void __fastcall TOptDialog::SolFormatChange(TObject *Sender) -{ - UpdateEnable(); -} +void __fastcall TOptDialog::SolFormatChange(TObject *Sender) { UpdateEnable(); } //--------------------------------------------------------------------------- -void __fastcall TOptDialog::PosModeChange(TObject *Sender) -{ - UpdateEnable(); -} +void __fastcall TOptDialog::PosModeChange(TObject *Sender) { UpdateEnable(); } //--------------------------------------------------------------------------- -void __fastcall TOptDialog::AmbResChange(TObject *Sender) -{ - UpdateEnable(); -} +void __fastcall TOptDialog::AmbResChange(TObject *Sender) { UpdateEnable(); } //--------------------------------------------------------------------------- -void __fastcall TOptDialog::RovAntPcvClick(TObject *Sender) -{ - UpdateEnable(); -} +void __fastcall TOptDialog::RovAntPcvClick(TObject *Sender) { UpdateEnable(); } //--------------------------------------------------------------------------- -void __fastcall TOptDialog::SatClkCorrClick(TObject *Sender) -{ - UpdateEnable(); -} +void __fastcall TOptDialog::SatClkCorrClick(TObject *Sender) { UpdateEnable(); } //--------------------------------------------------------------------------- -void __fastcall TOptDialog::IntpRefObsClick(TObject *Sender) -{ - UpdateEnable(); -} +void __fastcall TOptDialog::IntpRefObsClick(TObject *Sender) { UpdateEnable(); } //--------------------------------------------------------------------------- -void __fastcall TOptDialog::RovPosClick(TObject *Sender) -{ - UpdateEnable(); -} +void __fastcall TOptDialog::RovPosClick(TObject *Sender) { UpdateEnable(); } //--------------------------------------------------------------------------- -void __fastcall TOptDialog::RefPosClick(TObject *Sender) -{ - UpdateEnable(); -} +void __fastcall TOptDialog::RefPosClick(TObject *Sender) { UpdateEnable(); } //--------------------------------------------------------------------------- -void __fastcall TOptDialog::OutputHeightClick(TObject *Sender) -{ - UpdateEnable(); -} +void __fastcall TOptDialog::OutputHeightClick(TObject *Sender) { UpdateEnable(); } //--------------------------------------------------------------------------- -void __fastcall TOptDialog::NmeaReqCClick(TObject *Sender) -{ - UpdateEnable(); -} +void __fastcall TOptDialog::NmeaReqCClick(TObject *Sender) { UpdateEnable(); } //--------------------------------------------------------------------------- -void __fastcall TOptDialog::DgpsCorrLChange(TObject *Sender) -{ - UpdateEnable(); -} +void __fastcall TOptDialog::DgpsCorrLChange(TObject *Sender) { UpdateEnable(); } //--------------------------------------------------------------------------- -void __fastcall TOptDialog::GetOpt(void) -{ - TEdit *editu[]={RovPos1,RovPos2,RovPos3}; - TEdit *editr[]={RefPos1,RefPos2,RefPos3}; - AnsiString s; - - PosMode ->ItemIndex=PrcOpt.mode; - Freq ->ItemIndex=PrcOpt.nf-1>NFREQ-1?NFREQ-1:PrcOpt.nf-1; - ElMask ->Text =s.sprintf("%.0f",PrcOpt.elmin*R2D); - DynamicModel ->ItemIndex=PrcOpt.dynamics; - TideCorr ->ItemIndex=PrcOpt.tidecorr > 1 ? 2 : PrcOpt.tidecorr; - IonoOpt ->ItemIndex=PrcOpt.ionoopt; - TropOpt ->ItemIndex=PrcOpt.tropopt; - SatEphem ->ItemIndex=PrcOpt.sateph; - AmbRes ->ItemIndex=PrcOpt.modear; - GloAmbRes ->ItemIndex=PrcOpt.glomodear; - BdsAmbRes ->ItemIndex=PrcOpt.bdsmodear; - ValidThresAR ->Text =s.sprintf("%.1f",PrcOpt.thresar[0]); - MaxPosVarAR ->Text =s.sprintf("%.3f",PrcOpt.thresar[1]); - GloHwBias ->Text =s.sprintf("%.3f",PrcOpt.thresar[2]); - ValidThresARMin->Text =s.sprintf("%.1f",PrcOpt.thresar[5]); - ValidThresARMax->Text =s.sprintf("%.1f",PrcOpt.thresar[6]); - OutCntResetAmb->Text =s.sprintf("%d", PrcOpt.maxout); - LockCntFixAmb->Text =s.sprintf("%d", PrcOpt.minlock); - FixCntHoldAmb->Text =s.sprintf("%d", PrcOpt.minfix); - ElMaskAR ->Text =s.sprintf("%.0f",PrcOpt.elmaskar*R2D); - ElMaskHold ->Text =s.sprintf("%.0f",PrcOpt.elmaskhold*R2D); - MaxAgeDiff ->Text =s.sprintf("%.1f",PrcOpt.maxtdiff); - RejectCode ->Text =s.sprintf("%.1f",PrcOpt.maxinno[1]); - RejectPhase ->Text =s.sprintf("%.1f",PrcOpt.maxinno[0]); - VarHoldAmb ->Text =s.sprintf("%.4f",PrcOpt.varholdamb); - GainHoldAmb ->Text =s.sprintf("%.4f",PrcOpt.gainholdamb); - SlipThres ->Text =s.sprintf("%.3f",PrcOpt.thresslip); - DopThres ->Text =s.sprintf("%.3f",PrcOpt.thresdop); - ARIter ->Text =s.sprintf("%d", PrcOpt.armaxiter); - NumIter ->Text =s.sprintf("%d", PrcOpt.niter); - MinFixSats ->Text =s.sprintf("%d", PrcOpt.minfixsats); - MinHoldSats ->Text =s.sprintf("%d", PrcOpt.minholdsats); - MinDropSats ->Text =s.sprintf("%d", PrcOpt.mindropsats); - SyncSol ->ItemIndex=PrcOpt.syncsol; - ARFilter ->ItemIndex=PrcOpt.arfilter; - ExSatsE ->Text =ExSats; - NavSys1 ->Checked =PrcOpt.navsys&SYS_GPS; - NavSys2 ->Checked =PrcOpt.navsys&SYS_GLO; - NavSys3 ->Checked =PrcOpt.navsys&SYS_GAL; - NavSys4 ->Checked =PrcOpt.navsys&SYS_QZS; - NavSys5 ->Checked =PrcOpt.navsys&SYS_SBS; - NavSys6 ->Checked =PrcOpt.navsys&SYS_CMP; - NavSys7 ->Checked =PrcOpt.navsys&SYS_IRN; - PosOpt1 ->Checked =PrcOpt.posopt[0]; - PosOpt2 ->Checked =PrcOpt.posopt[1]; - PosOpt3 ->Checked =PrcOpt.posopt[2]; - PosOpt4 ->Checked =PrcOpt.posopt[3]; - PosOpt5 ->Checked =PrcOpt.posopt[4]; - - SolFormat ->ItemIndex=SolOpt.posf; - TimeFormat ->ItemIndex=SolOpt.timef==0?0:SolOpt.times+1; - TimeDecimal ->Text =s.sprintf("%d",SolOpt.timeu); - LatLonFormat ->ItemIndex=SolOpt.degf; - FieldSep ->Text =SolOpt.sep; - OutputHead ->ItemIndex=SolOpt.outhead; - OutputOpt ->ItemIndex=SolOpt.outopt; - OutputVel ->ItemIndex=SolOpt.outvel; - OutputSingle ->ItemIndex=PrcOpt.outsingle; - MaxSolStd ->Text =s.sprintf("%.2g",SolOpt.maxsolstd); - OutputDatum ->ItemIndex=SolOpt.datum; - OutputHeight ->ItemIndex=SolOpt.height; - OutputGeoid ->ItemIndex=SolOpt.geoid; - NmeaIntv1 ->Text =s.sprintf("%.2g",SolOpt.nmeaintv[0]); - NmeaIntv2 ->Text =s.sprintf("%.2g",SolOpt.nmeaintv[1]); - DebugStatus ->ItemIndex=SolOpt.sstat; - DebugTrace ->ItemIndex=SolOpt.trace; - - BaselineConst->Checked =BaselineC; - BaselineLen->Text =s.sprintf("%.3f",Baseline[0]); - BaselineSig->Text =s.sprintf("%.3f",Baseline[1]); - - MeasErrR1 ->Text =s.sprintf("%.1f",PrcOpt.eratio[0]); - MeasErrR2 ->Text =s.sprintf("%.1f",PrcOpt.eratio[1]); - MeasErrR5 ->Text =s.sprintf("%.1f",PrcOpt.eratio[2]); - MeasErrR6 ->Text =s.sprintf("%.1f",PrcOpt.eratio[3]); - MeasErr2 ->Text =s.sprintf("%.3f",PrcOpt.err[1]); - MeasErr3 ->Text =s.sprintf("%.3f",PrcOpt.err[2]); - MeasErr4 ->Text =s.sprintf("%.3f",PrcOpt.err[3]); - MeasErr5 ->Text =s.sprintf("%.3f",PrcOpt.err[4]); - MeasErr6 ->Text =s.sprintf("%.3f",PrcOpt.err[5]); - MeasErr7 ->Text =s.sprintf("%.3f",PrcOpt.err[6]); - MeasErr8 ->Text =s.sprintf("%.3f",PrcOpt.err[7]); - PrNoise1 ->Text =s.sprintf("%.2E",PrcOpt.prn[0]); - PrNoise2 ->Text =s.sprintf("%.2E",PrcOpt.prn[1]); - PrNoise3 ->Text =s.sprintf("%.2E",PrcOpt.prn[2]); - PrNoise4 ->Text =s.sprintf("%.2E",PrcOpt.prn[3]); - PrNoise5 ->Text =s.sprintf("%.2E",PrcOpt.prn[4]); - SatClkStab ->Text =s.sprintf("%.2E",PrcOpt.sclkstab); - MaxAveEp ->Text =s.sprintf("%d",PrcOpt.maxaveep); - ChkInitRestart->Checked =PrcOpt.initrst; - - RovPosTypeP ->ItemIndex=RovPosTypeF; - RefPosTypeP ->ItemIndex=RefPosTypeF; - RovAntPcv ->Checked =RovAntPcvF; - RefAntPcv ->Checked =RefAntPcvF; - RovAnt ->Text =RovAntF; - RefAnt ->Text =RefAntF; - RovAntE ->Text =s.sprintf("%.4f",RovAntDel[0]); - RovAntN ->Text =s.sprintf("%.4f",RovAntDel[1]); - RovAntU ->Text =s.sprintf("%.4f",RovAntDel[2]); - RefAntE ->Text =s.sprintf("%.4f",RefAntDel[0]); - RefAntN ->Text =s.sprintf("%.4f",RefAntDel[1]); - RefAntU ->Text =s.sprintf("%.4f",RefAntDel[2]); - SetPos(RovPosTypeP->ItemIndex,editu,RovPos); - SetPos(RefPosTypeP->ItemIndex,editr,RefPos); - - SatPcvFile ->Text =SatPcvFileF; - AntPcvFile ->Text =AntPcvFileF; - StaPosFile ->Text =StaPosFileF; - GeoidDataFile->Text =GeoidDataFileF; - DCBFile ->Text =DCBFileF; - EOPFile ->Text =EOPFileF; - BLQFile ->Text =BLQFileF; - LocalDir ->Text =LocalDirectory; - ReadAntList(); - - SvrCycleE ->Text =s.sprintf("%d",SvrCycle); - TimeoutTimeE ->Text =s.sprintf("%d",TimeoutTime); - ReconTimeE ->Text =s.sprintf("%d",ReconTime); - NmeaCycleE ->Text =s.sprintf("%d",NmeaCycle); - FileSwapMarginE->Text =s.sprintf("%d",FileSwapMargin); - SvrBuffSizeE ->Text =s.sprintf("%d",SvrBuffSize); - SolBuffSizeE ->Text =s.sprintf("%d",SolBuffSize); - SavedSolE ->Text =s.sprintf("%d",SavedSol); - NavSelectS ->ItemIndex=NavSelect; - SbasSatE ->Text =s.sprintf("%d",PrcOpt.sbassatsel); - ProxyAddrE ->Text =ProxyAddr; - MoniPortE ->Text =s.sprintf("%d",MoniPort); - SolBuffSizeE ->Text =s.sprintf("%d",SolBuffSize); - PanelStackE ->ItemIndex=PanelStack; - - FontLabel1->Font->Assign(PanelFont); - FontLabel1->Caption=FontLabel1->Font->Name+s.sprintf(" %dpt",FontLabel1->Font->Size); - FontLabel2->Font->Assign(PosFont); - FontLabel2->Caption=FontLabel2->Font->Name+s.sprintf(" %dpt",FontLabel2->Font->Size); - UpdateEnable(); +void __fastcall TOptDialog::GetOpt(void) { + TEdit *editu[] = {RovPos1, RovPos2, RovPos3}; + TEdit *editr[] = {RefPos1, RefPos2, RefPos3}; + AnsiString s; + + PosMode->ItemIndex = PrcOpt.mode; + Freq->ItemIndex = PrcOpt.nf - 1 > NFREQ - 1 ? NFREQ - 1 : PrcOpt.nf - 1; + ElMask->Text = s.sprintf("%.0f", PrcOpt.elmin * R2D); + DynamicModel->ItemIndex = PrcOpt.dynamics; + TideCorr->ItemIndex = PrcOpt.tidecorr > 1 ? 2 : PrcOpt.tidecorr; + IonoOpt->ItemIndex = PrcOpt.ionoopt; + TropOpt->ItemIndex = PrcOpt.tropopt; + SatEphem->ItemIndex = PrcOpt.sateph; + AmbRes->ItemIndex = PrcOpt.modear; + GloAmbRes->ItemIndex = PrcOpt.glomodear; + BdsAmbRes->ItemIndex = PrcOpt.bdsmodear; + ValidThresAR->Text = s.sprintf("%.1f", PrcOpt.thresar[0]); + MaxPosVarAR->Text = s.sprintf("%.3f", PrcOpt.thresar[1]); + GloHwBias->Text = s.sprintf("%.3f", PrcOpt.thresar[2]); + ValidThresARMin->Text = s.sprintf("%.1f", PrcOpt.thresar[5]); + ValidThresARMax->Text = s.sprintf("%.1f", PrcOpt.thresar[6]); + OutCntResetAmb->Text = s.sprintf("%d", PrcOpt.maxout); + LockCntFixAmb->Text = s.sprintf("%d", PrcOpt.minlock); + FixCntHoldAmb->Text = s.sprintf("%d", PrcOpt.minfix); + ElMaskAR->Text = s.sprintf("%.0f", PrcOpt.elmaskar * R2D); + ElMaskHold->Text = s.sprintf("%.0f", PrcOpt.elmaskhold * R2D); + MaxAgeDiff->Text = s.sprintf("%.1f", PrcOpt.maxtdiff); + RejectCode->Text = s.sprintf("%.1f", PrcOpt.maxinno[1]); + RejectPhase->Text = s.sprintf("%.1f", PrcOpt.maxinno[0]); + VarHoldAmb->Text = s.sprintf("%.4f", PrcOpt.varholdamb); + GainHoldAmb->Text = s.sprintf("%.4f", PrcOpt.gainholdamb); + SlipThres->Text = s.sprintf("%.3f", PrcOpt.thresslip); + DopThres->Text = s.sprintf("%.3f", PrcOpt.thresdop); + ARIter->Text = s.sprintf("%d", PrcOpt.armaxiter); + NumIter->Text = s.sprintf("%d", PrcOpt.niter); + MinFixSats->Text = s.sprintf("%d", PrcOpt.minfixsats); + MinHoldSats->Text = s.sprintf("%d", PrcOpt.minholdsats); + MinDropSats->Text = s.sprintf("%d", PrcOpt.mindropsats); + SyncSol->ItemIndex = PrcOpt.syncsol; + ARFilter->ItemIndex = PrcOpt.arfilter; + ExSatsE->Text = ExSats; + NavSys1->Checked = PrcOpt.navsys & SYS_GPS; + NavSys2->Checked = PrcOpt.navsys & SYS_GLO; + NavSys3->Checked = PrcOpt.navsys & SYS_GAL; + NavSys4->Checked = PrcOpt.navsys & SYS_QZS; + NavSys5->Checked = PrcOpt.navsys & SYS_SBS; + NavSys6->Checked = PrcOpt.navsys & SYS_CMP; + NavSys7->Checked = PrcOpt.navsys & SYS_IRN; + PosOpt1->Checked = PrcOpt.posopt[0]; + PosOpt2->Checked = PrcOpt.posopt[1]; + PosOpt3->Checked = PrcOpt.posopt[2]; + PosOpt4->Checked = PrcOpt.posopt[3]; + PosOpt5->Checked = PrcOpt.posopt[4]; + + SolFormat->ItemIndex = SolOpt.posf; + TimeFormat->ItemIndex = SolOpt.timef == 0 ? 0 : SolOpt.times + 1; + TimeDecimal->Text = s.sprintf("%d", SolOpt.timeu); + LatLonFormat->ItemIndex = SolOpt.degf; + FieldSep->Text = SolOpt.sep; + OutputHead->ItemIndex = SolOpt.outhead; + OutputOpt->ItemIndex = SolOpt.outopt; + OutputVel->ItemIndex = SolOpt.outvel; + OutputSingle->ItemIndex = PrcOpt.outsingle; + MaxSolStd->Text = s.sprintf("%.2g", SolOpt.maxsolstd); + OutputDatum->ItemIndex = SolOpt.datum; + OutputHeight->ItemIndex = SolOpt.height; + OutputGeoid->ItemIndex = SolOpt.geoid; + NmeaIntv1->Text = s.sprintf("%.2g", SolOpt.nmeaintv[0]); + NmeaIntv2->Text = s.sprintf("%.2g", SolOpt.nmeaintv[1]); + DebugStatus->ItemIndex = SolOpt.sstat; + DebugTrace->ItemIndex = SolOpt.trace; + + BaselineConst->Checked = BaselineC; + BaselineLen->Text = s.sprintf("%.3f", Baseline[0]); + BaselineSig->Text = s.sprintf("%.3f", Baseline[1]); + + MeasErrR1->Text = s.sprintf("%.1f", PrcOpt.eratio[0]); + MeasErrR2->Text = s.sprintf("%.1f", PrcOpt.eratio[1]); + MeasErrR5->Text = s.sprintf("%.1f", PrcOpt.eratio[2]); + MeasErrR6->Text = s.sprintf("%.1f", PrcOpt.eratio[3]); + MeasErr2->Text = s.sprintf("%.3f", PrcOpt.err[1]); + MeasErr3->Text = s.sprintf("%.3f", PrcOpt.err[2]); + MeasErr4->Text = s.sprintf("%.3f", PrcOpt.err[3]); + MeasErr5->Text = s.sprintf("%.3f", PrcOpt.err[4]); + MeasErr6->Text = s.sprintf("%.3f", PrcOpt.err[5]); + MeasErr7->Text = s.sprintf("%.3f", PrcOpt.err[6]); + MeasErr8->Text = s.sprintf("%.3f", PrcOpt.err[7]); + PrNoise1->Text = s.sprintf("%.2E", PrcOpt.prn[0]); + PrNoise2->Text = s.sprintf("%.2E", PrcOpt.prn[1]); + PrNoise3->Text = s.sprintf("%.2E", PrcOpt.prn[2]); + PrNoise4->Text = s.sprintf("%.2E", PrcOpt.prn[3]); + PrNoise5->Text = s.sprintf("%.2E", PrcOpt.prn[4]); + SatClkStab->Text = s.sprintf("%.2E", PrcOpt.sclkstab); + MaxAveEp->Text = s.sprintf("%d", PrcOpt.maxaveep); + ChkInitRestart->Checked = PrcOpt.initrst; + + RovPosTypeP->ItemIndex = RovPosTypeF; + RefPosTypeP->ItemIndex = RefPosTypeF; + RovAntPcv->Checked = RovAntPcvF; + RefAntPcv->Checked = RefAntPcvF; + RovAnt->Text = RovAntF; + RefAnt->Text = RefAntF; + RovAntE->Text = s.sprintf("%.4f", RovAntDel[0]); + RovAntN->Text = s.sprintf("%.4f", RovAntDel[1]); + RovAntU->Text = s.sprintf("%.4f", RovAntDel[2]); + RefAntE->Text = s.sprintf("%.4f", RefAntDel[0]); + RefAntN->Text = s.sprintf("%.4f", RefAntDel[1]); + RefAntU->Text = s.sprintf("%.4f", RefAntDel[2]); + SetPos(RovPosTypeP->ItemIndex, editu, RovPos); + SetPos(RefPosTypeP->ItemIndex, editr, RefPos); + + SatPcvFile->Text = SatPcvFileF; + AntPcvFile->Text = AntPcvFileF; + StaPosFile->Text = StaPosFileF; + GeoidDataFile->Text = GeoidDataFileF; + DCBFile->Text = DCBFileF; + EOPFile->Text = EOPFileF; + BLQFile->Text = BLQFileF; + LocalDir->Text = LocalDirectory; + ReadAntList(); + + SvrCycleE->Text = s.sprintf("%d", SvrCycle); + TimeoutTimeE->Text = s.sprintf("%d", TimeoutTime); + ReconTimeE->Text = s.sprintf("%d", ReconTime); + NmeaCycleE->Text = s.sprintf("%d", NmeaCycle); + FileSwapMarginE->Text = s.sprintf("%d", FileSwapMargin); + SvrBuffSizeE->Text = s.sprintf("%d", SvrBuffSize); + SolBuffSizeE->Text = s.sprintf("%d", SolBuffSize); + SavedSolE->Text = s.sprintf("%d", SavedSol); + NavSelectS->ItemIndex = NavSelect; + SbasSatE->Text = s.sprintf("%d", PrcOpt.sbassatsel); + ProxyAddrE->Text = ProxyAddr; + MoniPortE->Text = s.sprintf("%d", MoniPort); + SolBuffSizeE->Text = s.sprintf("%d", SolBuffSize); + PanelStackE->ItemIndex = PanelStack; + + FontLabel1->Font->Assign(PanelFont); + FontLabel1->Caption = FontLabel1->Font->Name + s.sprintf(" %dpt", FontLabel1->Font->Size); + FontLabel2->Font->Assign(PosFont); + FontLabel2->Caption = FontLabel2->Font->Name + s.sprintf(" %dpt", FontLabel2->Font->Size); + UpdateEnable(); } //--------------------------------------------------------------------------- -void __fastcall TOptDialog::SetOpt(void) -{ - AnsiString FieldSep_Text=FieldSep->Text; - TEdit *editu[]={RovPos1,RovPos2,RovPos3}; - TEdit *editr[]={RefPos1,RefPos2,RefPos3}; - - PrcOpt.mode =PosMode ->ItemIndex; - PrcOpt.nf =Freq ->ItemIndex+1; - PrcOpt.elmin =str2dbl(ElMask ->Text)*D2R; - PrcOpt.dynamics =DynamicModel->ItemIndex; - PrcOpt.tidecorr =TideCorr ->ItemIndex; - if (PrcOpt.tidecorr > 1) PrcOpt.tidecorr = 7; - PrcOpt.ionoopt =IonoOpt ->ItemIndex; - PrcOpt.tropopt =TropOpt ->ItemIndex; - PrcOpt.sateph =SatEphem ->ItemIndex; - PrcOpt.modear =AmbRes ->ItemIndex; - PrcOpt.glomodear =GloAmbRes ->ItemIndex; - PrcOpt.bdsmodear =BdsAmbRes ->ItemIndex; - PrcOpt.thresar[0]=str2dbl(ValidThresAR->Text); - PrcOpt.thresar[1]=str2dbl(MaxPosVarAR->Text); - PrcOpt.thresar[2]=str2dbl(GloHwBias->Text); - PrcOpt.thresar[5]=str2dbl(ValidThresARMin->Text); - PrcOpt.thresar[6]=str2dbl(ValidThresARMax->Text); - PrcOpt.maxout =OutCntResetAmb->Text.ToInt(); - PrcOpt.minlock =LockCntFixAmb->Text.ToInt(); - PrcOpt.minfix =FixCntHoldAmb->Text.ToInt(); - PrcOpt.elmaskar =str2dbl(ElMaskAR ->Text)*D2R; - PrcOpt.elmaskhold=str2dbl(ElMaskHold ->Text)*D2R; - PrcOpt.maxtdiff =str2dbl(MaxAgeDiff ->Text); - PrcOpt.maxinno[1]=str2dbl(RejectCode ->Text); - PrcOpt.maxinno[0]=str2dbl(RejectPhase->Text); - PrcOpt.varholdamb=str2dbl(VarHoldAmb->Text); - PrcOpt.gainholdamb=str2dbl(GainHoldAmb->Text); - PrcOpt.thresslip =str2dbl(SlipThres ->Text); - PrcOpt.thresdop =str2dbl(DopThres ->Text); - PrcOpt.armaxiter =ARIter ->Text.ToInt(); - PrcOpt.minfixsats =MinFixSats ->Text.ToInt(); - PrcOpt.minholdsats =MinHoldSats->Text.ToInt(); - PrcOpt.mindropsats =MinDropSats->Text.ToInt(); - PrcOpt.niter =NumIter ->Text.ToInt(); - PrcOpt.syncsol =SyncSol ->ItemIndex; - PrcOpt.arfilter =ARFilter ->ItemIndex; - ExSats =ExSatsE ->Text; - PrcOpt.navsys =0; - if (NavSys1->Checked) PrcOpt.navsys|=SYS_GPS; - if (NavSys2->Checked) PrcOpt.navsys|=SYS_GLO; - if (NavSys3->Checked) PrcOpt.navsys|=SYS_GAL; - if (NavSys4->Checked) PrcOpt.navsys|=SYS_QZS; - if (NavSys5->Checked) PrcOpt.navsys|=SYS_SBS; - if (NavSys6->Checked) PrcOpt.navsys|=SYS_CMP; - if (NavSys7->Checked) PrcOpt.navsys|=SYS_IRN; - PrcOpt.posopt[0] =PosOpt1 ->Checked; - PrcOpt.posopt[1] =PosOpt2 ->Checked; - PrcOpt.posopt[2] =PosOpt3 ->Checked; - PrcOpt.posopt[3] =PosOpt4 ->Checked; - PrcOpt.posopt[4] =PosOpt5 ->Checked; - PrcOpt.posopt[5] =PosOpt6 ->Checked; - - SolOpt.posf =SolFormat ->ItemIndex; - SolOpt.timef =TimeFormat->ItemIndex==0?0:1; - SolOpt.times =TimeFormat->ItemIndex==0?TIMES_GPST:(TimeFormat->ItemIndex-1); - SolOpt.timeu =(int)str2dbl(TimeDecimal->Text); - SolOpt.degf =LatLonFormat->ItemIndex; - strcpy(SolOpt.sep,FieldSep_Text.c_str()); - SolOpt.outhead =OutputHead ->ItemIndex; - SolOpt.outopt =OutputOpt ->ItemIndex; - SolOpt.outvel =OutputVel ->ItemIndex; - PrcOpt.outsingle =OutputSingle->ItemIndex; - SolOpt.maxsolstd =str2dbl(MaxSolStd->Text); - SolOpt.datum =OutputDatum ->ItemIndex; - SolOpt.height =OutputHeight->ItemIndex; - SolOpt.geoid =OutputGeoid ->ItemIndex; - SolOpt.nmeaintv[0]=str2dbl(NmeaIntv1->Text); - SolOpt.nmeaintv[1]=str2dbl(NmeaIntv2->Text); - SolOpt.sstat =DebugStatus ->ItemIndex; - SolOpt.trace =DebugTrace ->ItemIndex; - - BaselineC =BaselineConst->Checked; - Baseline[0] =str2dbl(BaselineLen->Text); - Baseline[1] =str2dbl(BaselineSig->Text); - - PrcOpt.eratio[0] =str2dbl(MeasErrR1 ->Text); - PrcOpt.eratio[1] =str2dbl(MeasErrR2 ->Text); - PrcOpt.eratio[2] =str2dbl(MeasErrR5 ->Text); - PrcOpt.eratio[3] =str2dbl(MeasErrR6 ->Text); - PrcOpt.err[1] =str2dbl(MeasErr2 ->Text); - PrcOpt.err[2] =str2dbl(MeasErr3 ->Text); - PrcOpt.err[3] =str2dbl(MeasErr4 ->Text); - PrcOpt.err[4] =str2dbl(MeasErr5 ->Text); - PrcOpt.err[5] =str2dbl(MeasErr6 ->Text); - PrcOpt.err[6] =str2dbl(MeasErr7 ->Text); - PrcOpt.err[7] =str2dbl(MeasErr8 ->Text); - PrcOpt.prn[0] =str2dbl(PrNoise1 ->Text); - PrcOpt.prn[1] =str2dbl(PrNoise2 ->Text); - PrcOpt.prn[2] =str2dbl(PrNoise3 ->Text); - PrcOpt.prn[3] =str2dbl(PrNoise4 ->Text); - PrcOpt.prn[4] =str2dbl(PrNoise5 ->Text); - PrcOpt.sclkstab =str2dbl(SatClkStab->Text); - PrcOpt.maxaveep =MaxAveEp->Text.ToInt(); - PrcOpt.initrst =ChkInitRestart->Checked; - - RovPosTypeF =RovPosTypeP ->ItemIndex; - RefPosTypeF =RefPosTypeP ->ItemIndex; - RovAntPcvF =RovAntPcv ->Checked; - RefAntPcvF =RefAntPcv ->Checked; - RovAntF =RovAnt ->Text; - RefAntF =RefAnt ->Text; - RovAntDel[0] =str2dbl(RovAntE ->Text); - RovAntDel[1] =str2dbl(RovAntN ->Text); - RovAntDel[2] =str2dbl(RovAntU ->Text); - RefAntDel[0] =str2dbl(RefAntE ->Text); - RefAntDel[1] =str2dbl(RefAntN ->Text); - RefAntDel[2] =str2dbl(RefAntU ->Text); - GetPos(RovPosTypeP->ItemIndex,editu,RovPos); - GetPos(RefPosTypeP->ItemIndex,editr,RefPos); - - SatPcvFileF =SatPcvFile ->Text; - AntPcvFileF =AntPcvFile ->Text; - StaPosFileF =StaPosFile ->Text; - GeoidDataFileF =GeoidDataFile->Text; - DCBFileF =DCBFile ->Text; - EOPFileF =EOPFile ->Text; - BLQFileF =BLQFile ->Text; - LocalDirectory =LocalDir ->Text; - - SvrCycle =SvrCycleE ->Text.ToInt(); - TimeoutTime =TimeoutTimeE->Text.ToInt(); - ReconTime =ReconTimeE ->Text.ToInt(); - NmeaCycle =NmeaCycleE ->Text.ToInt(); - FileSwapMargin =FileSwapMarginE->Text.ToInt(); - SvrBuffSize =SvrBuffSizeE->Text.ToInt(); - SolBuffSize =SolBuffSizeE->Text.ToInt(); - SavedSol =SavedSolE ->Text.ToInt(); - NavSelect =NavSelectS ->ItemIndex; - PrcOpt.sbassatsel=SbasSatE ->Text.ToInt(); - ProxyAddr =ProxyAddrE ->Text; - MoniPort =MoniPortE ->Text.ToInt(); - PanelStack =PanelStackE ->ItemIndex; - - PanelFont->Assign(FontLabel1->Font); - PosFont ->Assign(FontLabel2->Font); - UpdateEnable(); +void __fastcall TOptDialog::SetOpt(void) { + AnsiString FieldSep_Text = FieldSep->Text; + TEdit *editu[] = {RovPos1, RovPos2, RovPos3}; + TEdit *editr[] = {RefPos1, RefPos2, RefPos3}; + + PrcOpt.mode = PosMode->ItemIndex; + PrcOpt.nf = Freq->ItemIndex + 1; + PrcOpt.elmin = str2dbl(ElMask->Text) * D2R; + PrcOpt.dynamics = DynamicModel->ItemIndex; + PrcOpt.tidecorr = TideCorr->ItemIndex; + if (PrcOpt.tidecorr > 1) PrcOpt.tidecorr = 7; + PrcOpt.ionoopt = IonoOpt->ItemIndex; + PrcOpt.tropopt = TropOpt->ItemIndex; + PrcOpt.sateph = SatEphem->ItemIndex; + PrcOpt.modear = AmbRes->ItemIndex; + PrcOpt.glomodear = GloAmbRes->ItemIndex; + PrcOpt.bdsmodear = BdsAmbRes->ItemIndex; + PrcOpt.thresar[0] = str2dbl(ValidThresAR->Text); + PrcOpt.thresar[1] = str2dbl(MaxPosVarAR->Text); + PrcOpt.thresar[2] = str2dbl(GloHwBias->Text); + PrcOpt.thresar[5] = str2dbl(ValidThresARMin->Text); + PrcOpt.thresar[6] = str2dbl(ValidThresARMax->Text); + PrcOpt.maxout = OutCntResetAmb->Text.ToInt(); + PrcOpt.minlock = LockCntFixAmb->Text.ToInt(); + PrcOpt.minfix = FixCntHoldAmb->Text.ToInt(); + PrcOpt.elmaskar = str2dbl(ElMaskAR->Text) * D2R; + PrcOpt.elmaskhold = str2dbl(ElMaskHold->Text) * D2R; + PrcOpt.maxtdiff = str2dbl(MaxAgeDiff->Text); + PrcOpt.maxinno[1] = str2dbl(RejectCode->Text); + PrcOpt.maxinno[0] = str2dbl(RejectPhase->Text); + PrcOpt.varholdamb = str2dbl(VarHoldAmb->Text); + PrcOpt.gainholdamb = str2dbl(GainHoldAmb->Text); + PrcOpt.thresslip = str2dbl(SlipThres->Text); + PrcOpt.thresdop = str2dbl(DopThres->Text); + PrcOpt.armaxiter = ARIter->Text.ToInt(); + PrcOpt.minfixsats = MinFixSats->Text.ToInt(); + PrcOpt.minholdsats = MinHoldSats->Text.ToInt(); + PrcOpt.mindropsats = MinDropSats->Text.ToInt(); + PrcOpt.niter = NumIter->Text.ToInt(); + PrcOpt.syncsol = SyncSol->ItemIndex; + PrcOpt.arfilter = ARFilter->ItemIndex; + ExSats = ExSatsE->Text; + PrcOpt.navsys = 0; + if (NavSys1->Checked) PrcOpt.navsys |= SYS_GPS; + if (NavSys2->Checked) PrcOpt.navsys |= SYS_GLO; + if (NavSys3->Checked) PrcOpt.navsys |= SYS_GAL; + if (NavSys4->Checked) PrcOpt.navsys |= SYS_QZS; + if (NavSys5->Checked) PrcOpt.navsys |= SYS_SBS; + if (NavSys6->Checked) PrcOpt.navsys |= SYS_CMP; + if (NavSys7->Checked) PrcOpt.navsys |= SYS_IRN; + PrcOpt.posopt[0] = PosOpt1->Checked; + PrcOpt.posopt[1] = PosOpt2->Checked; + PrcOpt.posopt[2] = PosOpt3->Checked; + PrcOpt.posopt[3] = PosOpt4->Checked; + PrcOpt.posopt[4] = PosOpt5->Checked; + PrcOpt.posopt[5] = PosOpt6->Checked; + + SolOpt.posf = SolFormat->ItemIndex; + SolOpt.timef = TimeFormat->ItemIndex == 0 ? 0 : 1; + SolOpt.times = TimeFormat->ItemIndex == 0 ? TIMES_GPST : (TimeFormat->ItemIndex - 1); + SolOpt.timeu = (int)str2dbl(TimeDecimal->Text); + SolOpt.degf = LatLonFormat->ItemIndex; + strcpy(SolOpt.sep, FieldSep_Text.c_str()); + SolOpt.outhead = OutputHead->ItemIndex; + SolOpt.outopt = OutputOpt->ItemIndex; + SolOpt.outvel = OutputVel->ItemIndex; + PrcOpt.outsingle = OutputSingle->ItemIndex; + SolOpt.maxsolstd = str2dbl(MaxSolStd->Text); + SolOpt.datum = OutputDatum->ItemIndex; + SolOpt.height = OutputHeight->ItemIndex; + SolOpt.geoid = OutputGeoid->ItemIndex; + SolOpt.nmeaintv[0] = str2dbl(NmeaIntv1->Text); + SolOpt.nmeaintv[1] = str2dbl(NmeaIntv2->Text); + SolOpt.sstat = DebugStatus->ItemIndex; + SolOpt.trace = DebugTrace->ItemIndex; + + BaselineC = BaselineConst->Checked; + Baseline[0] = str2dbl(BaselineLen->Text); + Baseline[1] = str2dbl(BaselineSig->Text); + + PrcOpt.eratio[0] = str2dbl(MeasErrR1->Text); + PrcOpt.eratio[1] = str2dbl(MeasErrR2->Text); + PrcOpt.eratio[2] = str2dbl(MeasErrR5->Text); + PrcOpt.eratio[3] = str2dbl(MeasErrR6->Text); + PrcOpt.err[1] = str2dbl(MeasErr2->Text); + PrcOpt.err[2] = str2dbl(MeasErr3->Text); + PrcOpt.err[3] = str2dbl(MeasErr4->Text); + PrcOpt.err[4] = str2dbl(MeasErr5->Text); + PrcOpt.err[5] = str2dbl(MeasErr6->Text); + PrcOpt.err[6] = str2dbl(MeasErr7->Text); + PrcOpt.err[7] = str2dbl(MeasErr8->Text); + PrcOpt.prn[0] = str2dbl(PrNoise1->Text); + PrcOpt.prn[1] = str2dbl(PrNoise2->Text); + PrcOpt.prn[2] = str2dbl(PrNoise3->Text); + PrcOpt.prn[3] = str2dbl(PrNoise4->Text); + PrcOpt.prn[4] = str2dbl(PrNoise5->Text); + PrcOpt.sclkstab = str2dbl(SatClkStab->Text); + PrcOpt.maxaveep = MaxAveEp->Text.ToInt(); + PrcOpt.initrst = ChkInitRestart->Checked; + + RovPosTypeF = RovPosTypeP->ItemIndex; + RefPosTypeF = RefPosTypeP->ItemIndex; + RovAntPcvF = RovAntPcv->Checked; + RefAntPcvF = RefAntPcv->Checked; + RovAntF = RovAnt->Text; + RefAntF = RefAnt->Text; + RovAntDel[0] = str2dbl(RovAntE->Text); + RovAntDel[1] = str2dbl(RovAntN->Text); + RovAntDel[2] = str2dbl(RovAntU->Text); + RefAntDel[0] = str2dbl(RefAntE->Text); + RefAntDel[1] = str2dbl(RefAntN->Text); + RefAntDel[2] = str2dbl(RefAntU->Text); + GetPos(RovPosTypeP->ItemIndex, editu, RovPos); + GetPos(RefPosTypeP->ItemIndex, editr, RefPos); + + SatPcvFileF = SatPcvFile->Text; + AntPcvFileF = AntPcvFile->Text; + StaPosFileF = StaPosFile->Text; + GeoidDataFileF = GeoidDataFile->Text; + DCBFileF = DCBFile->Text; + EOPFileF = EOPFile->Text; + BLQFileF = BLQFile->Text; + LocalDirectory = LocalDir->Text; + + SvrCycle = SvrCycleE->Text.ToInt(); + TimeoutTime = TimeoutTimeE->Text.ToInt(); + ReconTime = ReconTimeE->Text.ToInt(); + NmeaCycle = NmeaCycleE->Text.ToInt(); + FileSwapMargin = FileSwapMarginE->Text.ToInt(); + SvrBuffSize = SvrBuffSizeE->Text.ToInt(); + SolBuffSize = SolBuffSizeE->Text.ToInt(); + SavedSol = SavedSolE->Text.ToInt(); + NavSelect = NavSelectS->ItemIndex; + PrcOpt.sbassatsel = SbasSatE->Text.ToInt(); + ProxyAddr = ProxyAddrE->Text; + MoniPort = MoniPortE->Text.ToInt(); + PanelStack = PanelStackE->ItemIndex; + + PanelFont->Assign(FontLabel1->Font); + PosFont->Assign(FontLabel2->Font); + UpdateEnable(); } //--------------------------------------------------------------------------- -void __fastcall TOptDialog::LoadOpt(AnsiString file) -{ - int itype[]={STR_SERIAL,STR_TCPCLI,STR_TCPSVR,STR_NTRIPCLI,STR_FILE,STR_FTP,STR_HTTP}; - int otype[]={STR_SERIAL,STR_TCPCLI,STR_TCPSVR,STR_NTRIPSVR,STR_NTRIPCAS,STR_FILE}; - int num_itype=7,num_otype=6; - TEdit *editu[]={RovPos1,RovPos2,RovPos3}; - TEdit *editr[]={RefPos1,RefPos2,RefPos3}; - AnsiString s; - char buff[1024]="",*p,id[8]; - int sat; - prcopt_t prcopt=prcopt_default; - solopt_t solopt=solopt_default; - filopt_t filopt={""}; - - resetsysopts(); - if (!loadopts(file.c_str(),sysopts)|| - !loadopts(file.c_str(),rcvopts)) return; - getsysopts(&prcopt,&solopt,&filopt); - - for (int i=0;i<8;i++) { - MainForm->StreamC[i]=strtype[i]!=STR_NONE; - MainForm->Stream[i]=STR_NONE; - for (int j=0;j<(i<3?num_itype:num_otype);j++) { - if (strtype[i]!=(i<3?itype[j]:otype[j])) continue; - MainForm->Stream[i]=j; - break; - } - if (i<5) MainForm->Format[i]=strfmt[i]; - - if (strtype[i]==STR_SERIAL) { - MainForm->Paths[i][0]=strpath[i]; - } - else if (strtype[i]==STR_FILE) { - MainForm->Paths[i][2]=strpath[i]; - } - else if (strtype[i]<=STR_NTRIPCLI) { - MainForm->Paths[i][1]=strpath[i]; - } - else if (strtype[i]<=STR_HTTP) { - MainForm->Paths[i][3]=strpath[i]; - } - } - MainForm->NmeaReq=nmeareq; - MainForm->NmeaPos[0]=nmeapos[0]; - MainForm->NmeaPos[1]=nmeapos[1]; - - SbasSatE ->Text =s.sprintf("%d",prcopt.sbassatsel); - - PosMode ->ItemIndex =prcopt.mode; - Freq ->ItemIndex =prcopt.nf>NFREQ-1?NFREQ-1:prcopt.nf-1; - ElMask ->Text =s.sprintf("%.0f",prcopt.elmin*R2D); - PrcOpt.snrmask =prcopt.snrmask; - DynamicModel ->ItemIndex =prcopt.dynamics; - TideCorr ->ItemIndex =prcopt.tidecorr > 1 ? 2 : prcopt.tidecorr; - IonoOpt ->ItemIndex =prcopt.ionoopt; - TropOpt ->ItemIndex =prcopt.tropopt; - SatEphem ->ItemIndex =prcopt.sateph; - ExSatsE ->Text =""; - for (sat=1,p=buff;sat<=MAXSAT;sat++) { - if (!prcopt.exsats[sat-1]) continue; - satno2id(sat,id); - p+=sprintf(p,"%s%s%s",p==buff?"":" ",prcopt.exsats[sat-1]==2?"+":"",id); - } - ExSatsE ->Text =buff; - NavSys1 ->Checked =prcopt.navsys&SYS_GPS; - NavSys2 ->Checked =prcopt.navsys&SYS_GLO; - NavSys3 ->Checked =prcopt.navsys&SYS_GAL; - NavSys4 ->Checked =prcopt.navsys&SYS_QZS; - NavSys5 ->Checked =prcopt.navsys&SYS_SBS; - NavSys6 ->Checked =prcopt.navsys&SYS_CMP; - NavSys7 ->Checked =prcopt.navsys&SYS_IRN; - PosOpt1 ->Checked =prcopt.posopt[0]; - PosOpt2 ->Checked =prcopt.posopt[1]; - PosOpt3 ->Checked =prcopt.posopt[2]; - PosOpt4 ->Checked =prcopt.posopt[3]; - PosOpt5 ->Checked =prcopt.posopt[4]; - PosOpt6 ->Checked =prcopt.posopt[5]; - - AmbRes ->ItemIndex =prcopt.modear; - GloAmbRes ->ItemIndex =prcopt.glomodear; - BdsAmbRes ->ItemIndex =prcopt.bdsmodear; - ValidThresAR ->Text =s.sprintf("%.1f",prcopt.thresar[0]); - MaxPosVarAR ->Text =s.sprintf("%.3f",prcopt.thresar[1]); - GloHwBias ->Text =s.sprintf("%.3f",prcopt.thresar[2]); - ValidThresARMin->Text =s.sprintf("%.1f",prcopt.thresar[5]); - ValidThresARMax->Text =s.sprintf("%.1f",prcopt.thresar[6]); - OutCntResetAmb->Text =s.sprintf("%d" ,prcopt.maxout ); - FixCntHoldAmb->Text =s.sprintf("%d" ,prcopt.minfix ); - LockCntFixAmb->Text =s.sprintf("%d" ,prcopt.minlock ); - ElMaskAR ->Text =s.sprintf("%.0f",prcopt.elmaskar*R2D); - ElMaskHold ->Text =s.sprintf("%.0f",prcopt.elmaskhold*R2D); - MaxAgeDiff ->Text =s.sprintf("%.1f",prcopt.maxtdiff ); - RejectCode ->Text =s.sprintf("%.1f",prcopt.maxinno[1]); - RejectPhase ->Text =s.sprintf("%.1f",prcopt.maxinno[0]); - VarHoldAmb ->Text =s.sprintf("%.4f",prcopt.varholdamb); - GainHoldAmb ->Text =s.sprintf("%.4f",prcopt.gainholdamb); - SlipThres ->Text =s.sprintf("%.3f",prcopt.thresslip); - DopThres ->Text =s.sprintf("%.3f",prcopt.thresdop); - ARIter ->Text =s.sprintf("%d", prcopt.armaxiter); - MinFixSats ->Text =s.sprintf("%d", prcopt.minfixsats); - MinHoldSats ->Text =s.sprintf("%d", prcopt.minholdsats); - MinDropSats ->Text =s.sprintf("%d", prcopt.mindropsats); - NumIter ->Text =s.sprintf("%d", prcopt.niter ); - SyncSol ->ItemIndex =prcopt.syncsol; - ARFilter ->ItemIndex =prcopt.arfilter; - BaselineLen ->Text =s.sprintf("%.3f",prcopt.baseline[0]); - BaselineSig ->Text =s.sprintf("%.3f",prcopt.baseline[1]); - BaselineConst->Checked =prcopt.baseline[0]>0.0; - - SolFormat ->ItemIndex =solopt.posf; - TimeFormat ->ItemIndex =solopt.timef==0?0:solopt.times+1; - TimeDecimal ->Text =s.sprintf("%d",solopt.timeu); - LatLonFormat ->ItemIndex =solopt.degf; - FieldSep ->Text =solopt.sep; - OutputHead ->ItemIndex =solopt.outhead; - OutputOpt ->ItemIndex =solopt.outopt; - OutputVel ->ItemIndex =solopt.outvel; - OutputSingle ->ItemIndex =prcopt.outsingle; - MaxSolStd ->Text =s.sprintf("%.2g",solopt.maxsolstd); - OutputDatum ->ItemIndex =solopt.datum; - OutputHeight ->ItemIndex =solopt.height; - OutputGeoid ->ItemIndex =solopt.geoid; - NmeaIntv1 ->Text =s.sprintf("%.2g",solopt.nmeaintv[0]); - NmeaIntv2 ->Text =s.sprintf("%.2g",solopt.nmeaintv[1]); - DebugTrace ->ItemIndex =solopt.trace; - DebugStatus ->ItemIndex =solopt.sstat; - - MeasErrR1 ->Text =s.sprintf("%.1f",prcopt.eratio[0]); - MeasErrR2 ->Text =s.sprintf("%.1f",prcopt.eratio[1]); - MeasErrR5 ->Text =s.sprintf("%.1f",prcopt.eratio[2]); - MeasErrR6 ->Text =s.sprintf("%.1f",prcopt.eratio[3]); - MeasErr2 ->Text =s.sprintf("%.3f",prcopt.err[1]); - MeasErr3 ->Text =s.sprintf("%.3f",prcopt.err[2]); - MeasErr4 ->Text =s.sprintf("%.3f",prcopt.err[3]); - MeasErr5 ->Text =s.sprintf("%.3f",prcopt.err[4]); - MeasErr6 ->Text =s.sprintf("%.3f",prcopt.err[5]); - MeasErr7 ->Text =s.sprintf("%.3f",prcopt.err[6]); - MeasErr8 ->Text =s.sprintf("%.3f",prcopt.err[7]); - SatClkStab ->Text =s.sprintf("%.2E",prcopt.sclkstab); - PrNoise1 ->Text =s.sprintf("%.2E",prcopt.prn[0]); - PrNoise2 ->Text =s.sprintf("%.2E",prcopt.prn[1]); - PrNoise3 ->Text =s.sprintf("%.2E",prcopt.prn[2]); - PrNoise4 ->Text =s.sprintf("%.2E",prcopt.prn[3]); - PrNoise5 ->Text =s.sprintf("%.2E",prcopt.prn[4]); - - RovAntPcv ->Checked =*prcopt.anttype[0]; - RefAntPcv ->Checked =*prcopt.anttype[1]; - RovAnt ->Text =prcopt.anttype[0]; - RefAnt ->Text =prcopt.anttype[1]; - RovAntE ->Text =s.sprintf("%.4f",prcopt.antdel[0][0]); - RovAntN ->Text =s.sprintf("%.4f",prcopt.antdel[0][1]); - RovAntU ->Text =s.sprintf("%.4f",prcopt.antdel[0][2]); - RefAntE ->Text =s.sprintf("%.4f",prcopt.antdel[1][0]); - RefAntN ->Text =s.sprintf("%.4f",prcopt.antdel[1][1]); - RefAntU ->Text =s.sprintf("%.4f",prcopt.antdel[1][2]); - MaxAveEp ->Text =s.sprintf("%d",prcopt.maxaveep); - ChkInitRestart->Checked =prcopt.initrst; - - RovPosTypeP ->ItemIndex =0; - if (prcopt.rovpos == POSOPT_POS_LLH) RovPosTypeP->ItemIndex = 0; - else if (prcopt.rovpos == POSOPT_POS_XYZ) RovPosTypeP->ItemIndex = 2; - else if (prcopt.rovpos == POSOPT_RTCM) RovPosTypeP->ItemIndex= 3; - - RefPosTypeP ->ItemIndex =0; - if (prcopt.refpos == POSOPT_POS_LLH) RefPosTypeP->ItemIndex = 0; - else if (prcopt.refpos == POSOPT_POS_XYZ) RefPosTypeP->ItemIndex = 2; - else if (prcopt.refpos==POSOPT_RTCM ) RefPosTypeP->ItemIndex=3; - else if (prcopt.refpos==POSOPT_SINGLE) RefPosTypeP->ItemIndex=4; - - RovPosTypeF =RovPosTypeP->ItemIndex; - RefPosTypeF =RefPosTypeP->ItemIndex; - SetPos(RovPosTypeP->ItemIndex,editu,prcopt.ru); - SetPos(RefPosTypeP->ItemIndex,editr,prcopt.rb); - - SatPcvFile ->Text =filopt.satantp; - AntPcvFile ->Text =filopt.rcvantp; - StaPosFile ->Text =filopt.stapos; - GeoidDataFile->Text =filopt.geoid; - DCBFile ->Text =filopt.dcb; - EOPFile ->Text =filopt.eop; - BLQFile ->Text =filopt.blq; - LocalDir ->Text =filopt.tempdir; - - ProxyAddrE ->Text =proxyaddr; - - ReadAntList(); - UpdateEnable(); +void __fastcall TOptDialog::LoadOpt(AnsiString file) { + int itype[] = {STR_SERIAL, STR_TCPCLI, STR_TCPSVR, STR_NTRIPCLI, STR_FILE, STR_FTP, STR_HTTP}; + int otype[] = {STR_SERIAL, STR_TCPCLI, STR_TCPSVR, STR_NTRIPSVR, STR_NTRIPCAS, STR_FILE}; + int num_itype = 7, num_otype = 6; + TEdit *editu[] = {RovPos1, RovPos2, RovPos3}; + TEdit *editr[] = {RefPos1, RefPos2, RefPos3}; + AnsiString s; + char buff[1024] = "", *p, id[8]; + int sat; + prcopt_t prcopt = prcopt_default; + solopt_t solopt = solopt_default; + filopt_t filopt = {""}; + + resetsysopts(); + if (!loadopts(file.c_str(), sysopts) || !loadopts(file.c_str(), rcvopts)) return; + getsysopts(&prcopt, &solopt, &filopt); + + for (int i = 0; i < 8; i++) { + MainForm->StreamC[i] = strtype[i] != STR_NONE; + MainForm->Stream[i] = STR_NONE; + for (int j = 0; j < (i < 3 ? num_itype : num_otype); j++) { + if (strtype[i] != (i < 3 ? itype[j] : otype[j])) continue; + MainForm->Stream[i] = j; + break; + } + if (i < 5) MainForm->Format[i] = strfmt[i]; + + if (strtype[i] == STR_SERIAL) { + MainForm->Paths[i][0] = strpath[i]; + } else if (strtype[i] == STR_FILE) { + MainForm->Paths[i][2] = strpath[i]; + } else if (strtype[i] <= STR_NTRIPCLI) { + MainForm->Paths[i][1] = strpath[i]; + } else if (strtype[i] <= STR_HTTP) { + MainForm->Paths[i][3] = strpath[i]; + } + } + MainForm->NmeaReq = nmeareq; + MainForm->NmeaPos[0] = nmeapos[0]; + MainForm->NmeaPos[1] = nmeapos[1]; + + SbasSatE->Text = s.sprintf("%d", prcopt.sbassatsel); + + PosMode->ItemIndex = prcopt.mode; + Freq->ItemIndex = prcopt.nf > NFREQ - 1 ? NFREQ - 1 : prcopt.nf - 1; + ElMask->Text = s.sprintf("%.0f", prcopt.elmin * R2D); + PrcOpt.snrmask = prcopt.snrmask; + DynamicModel->ItemIndex = prcopt.dynamics; + TideCorr->ItemIndex = prcopt.tidecorr > 1 ? 2 : prcopt.tidecorr; + IonoOpt->ItemIndex = prcopt.ionoopt; + TropOpt->ItemIndex = prcopt.tropopt; + SatEphem->ItemIndex = prcopt.sateph; + ExSatsE->Text = ""; + for (sat = 1, p = buff; sat <= MAXSAT; sat++) { + if (!prcopt.exsats[sat - 1]) continue; + satno2id(sat, id); + p += sprintf(p, "%s%s%s", p == buff ? "" : " ", prcopt.exsats[sat - 1] == 2 ? "+" : "", id); + } + ExSatsE->Text = buff; + NavSys1->Checked = prcopt.navsys & SYS_GPS; + NavSys2->Checked = prcopt.navsys & SYS_GLO; + NavSys3->Checked = prcopt.navsys & SYS_GAL; + NavSys4->Checked = prcopt.navsys & SYS_QZS; + NavSys5->Checked = prcopt.navsys & SYS_SBS; + NavSys6->Checked = prcopt.navsys & SYS_CMP; + NavSys7->Checked = prcopt.navsys & SYS_IRN; + PosOpt1->Checked = prcopt.posopt[0]; + PosOpt2->Checked = prcopt.posopt[1]; + PosOpt3->Checked = prcopt.posopt[2]; + PosOpt4->Checked = prcopt.posopt[3]; + PosOpt5->Checked = prcopt.posopt[4]; + PosOpt6->Checked = prcopt.posopt[5]; + + AmbRes->ItemIndex = prcopt.modear; + GloAmbRes->ItemIndex = prcopt.glomodear; + BdsAmbRes->ItemIndex = prcopt.bdsmodear; + ValidThresAR->Text = s.sprintf("%.1f", prcopt.thresar[0]); + MaxPosVarAR->Text = s.sprintf("%.3f", prcopt.thresar[1]); + GloHwBias->Text = s.sprintf("%.3f", prcopt.thresar[2]); + ValidThresARMin->Text = s.sprintf("%.1f", prcopt.thresar[5]); + ValidThresARMax->Text = s.sprintf("%.1f", prcopt.thresar[6]); + OutCntResetAmb->Text = s.sprintf("%d", prcopt.maxout); + FixCntHoldAmb->Text = s.sprintf("%d", prcopt.minfix); + LockCntFixAmb->Text = s.sprintf("%d", prcopt.minlock); + ElMaskAR->Text = s.sprintf("%.0f", prcopt.elmaskar * R2D); + ElMaskHold->Text = s.sprintf("%.0f", prcopt.elmaskhold * R2D); + MaxAgeDiff->Text = s.sprintf("%.1f", prcopt.maxtdiff); + RejectCode->Text = s.sprintf("%.1f", prcopt.maxinno[1]); + RejectPhase->Text = s.sprintf("%.1f", prcopt.maxinno[0]); + VarHoldAmb->Text = s.sprintf("%.4f", prcopt.varholdamb); + GainHoldAmb->Text = s.sprintf("%.4f", prcopt.gainholdamb); + SlipThres->Text = s.sprintf("%.3f", prcopt.thresslip); + DopThres->Text = s.sprintf("%.3f", prcopt.thresdop); + ARIter->Text = s.sprintf("%d", prcopt.armaxiter); + MinFixSats->Text = s.sprintf("%d", prcopt.minfixsats); + MinHoldSats->Text = s.sprintf("%d", prcopt.minholdsats); + MinDropSats->Text = s.sprintf("%d", prcopt.mindropsats); + NumIter->Text = s.sprintf("%d", prcopt.niter); + SyncSol->ItemIndex = prcopt.syncsol; + ARFilter->ItemIndex = prcopt.arfilter; + BaselineLen->Text = s.sprintf("%.3f", prcopt.baseline[0]); + BaselineSig->Text = s.sprintf("%.3f", prcopt.baseline[1]); + BaselineConst->Checked = prcopt.baseline[0] > 0.0; + + SolFormat->ItemIndex = solopt.posf; + TimeFormat->ItemIndex = solopt.timef == 0 ? 0 : solopt.times + 1; + TimeDecimal->Text = s.sprintf("%d", solopt.timeu); + LatLonFormat->ItemIndex = solopt.degf; + FieldSep->Text = solopt.sep; + OutputHead->ItemIndex = solopt.outhead; + OutputOpt->ItemIndex = solopt.outopt; + OutputVel->ItemIndex = solopt.outvel; + OutputSingle->ItemIndex = prcopt.outsingle; + MaxSolStd->Text = s.sprintf("%.2g", solopt.maxsolstd); + OutputDatum->ItemIndex = solopt.datum; + OutputHeight->ItemIndex = solopt.height; + OutputGeoid->ItemIndex = solopt.geoid; + NmeaIntv1->Text = s.sprintf("%.2g", solopt.nmeaintv[0]); + NmeaIntv2->Text = s.sprintf("%.2g", solopt.nmeaintv[1]); + DebugTrace->ItemIndex = solopt.trace; + DebugStatus->ItemIndex = solopt.sstat; + + MeasErrR1->Text = s.sprintf("%.1f", prcopt.eratio[0]); + MeasErrR2->Text = s.sprintf("%.1f", prcopt.eratio[1]); + MeasErrR5->Text = s.sprintf("%.1f", prcopt.eratio[2]); + MeasErrR6->Text = s.sprintf("%.1f", prcopt.eratio[3]); + MeasErr2->Text = s.sprintf("%.3f", prcopt.err[1]); + MeasErr3->Text = s.sprintf("%.3f", prcopt.err[2]); + MeasErr4->Text = s.sprintf("%.3f", prcopt.err[3]); + MeasErr5->Text = s.sprintf("%.3f", prcopt.err[4]); + MeasErr6->Text = s.sprintf("%.3f", prcopt.err[5]); + MeasErr7->Text = s.sprintf("%.3f", prcopt.err[6]); + MeasErr8->Text = s.sprintf("%.3f", prcopt.err[7]); + SatClkStab->Text = s.sprintf("%.2E", prcopt.sclkstab); + PrNoise1->Text = s.sprintf("%.2E", prcopt.prn[0]); + PrNoise2->Text = s.sprintf("%.2E", prcopt.prn[1]); + PrNoise3->Text = s.sprintf("%.2E", prcopt.prn[2]); + PrNoise4->Text = s.sprintf("%.2E", prcopt.prn[3]); + PrNoise5->Text = s.sprintf("%.2E", prcopt.prn[4]); + + RovAntPcv->Checked = *prcopt.anttype[0]; + RefAntPcv->Checked = *prcopt.anttype[1]; + RovAnt->Text = prcopt.anttype[0]; + RefAnt->Text = prcopt.anttype[1]; + RovAntE->Text = s.sprintf("%.4f", prcopt.antdel[0][0]); + RovAntN->Text = s.sprintf("%.4f", prcopt.antdel[0][1]); + RovAntU->Text = s.sprintf("%.4f", prcopt.antdel[0][2]); + RefAntE->Text = s.sprintf("%.4f", prcopt.antdel[1][0]); + RefAntN->Text = s.sprintf("%.4f", prcopt.antdel[1][1]); + RefAntU->Text = s.sprintf("%.4f", prcopt.antdel[1][2]); + MaxAveEp->Text = s.sprintf("%d", prcopt.maxaveep); + ChkInitRestart->Checked = prcopt.initrst; + + RovPosTypeP->ItemIndex = 0; + if (prcopt.rovpos == POSOPT_POS_LLH) + RovPosTypeP->ItemIndex = 0; + else if (prcopt.rovpos == POSOPT_POS_XYZ) + RovPosTypeP->ItemIndex = 2; + else if (prcopt.rovpos == POSOPT_RTCM) + RovPosTypeP->ItemIndex = 3; + + RefPosTypeP->ItemIndex = 0; + if (prcopt.refpos == POSOPT_POS_LLH) + RefPosTypeP->ItemIndex = 0; + else if (prcopt.refpos == POSOPT_POS_XYZ) + RefPosTypeP->ItemIndex = 2; + else if (prcopt.refpos == POSOPT_RTCM) + RefPosTypeP->ItemIndex = 3; + else if (prcopt.refpos == POSOPT_SINGLE) + RefPosTypeP->ItemIndex = 4; + + RovPosTypeF = RovPosTypeP->ItemIndex; + RefPosTypeF = RefPosTypeP->ItemIndex; + SetPos(RovPosTypeP->ItemIndex, editu, prcopt.ru); + SetPos(RefPosTypeP->ItemIndex, editr, prcopt.rb); + + SatPcvFile->Text = filopt.satantp; + AntPcvFile->Text = filopt.rcvantp; + StaPosFile->Text = filopt.stapos; + GeoidDataFile->Text = filopt.geoid; + DCBFile->Text = filopt.dcb; + EOPFile->Text = filopt.eop; + BLQFile->Text = filopt.blq; + LocalDir->Text = filopt.tempdir; + + ProxyAddrE->Text = proxyaddr; + + ReadAntList(); + UpdateEnable(); } //---j------------------------------------------------------------------------ -void __fastcall TOptDialog::SaveOpt(AnsiString file) -{ - AnsiString ProxyAddrE_Text=ProxyAddrE->Text; - AnsiString ExSatsE_Text=ExSatsE->Text; - AnsiString FieldSep_Text=FieldSep->Text; - AnsiString RovAnt_Text=RovAnt->Text,RefAnt_Text=RefAnt->Text; - AnsiString SatPcvFile_Text=SatPcvFile->Text; - AnsiString AntPcvFile_Text=AntPcvFile->Text; - AnsiString StaPosFile_Text=StaPosFile->Text; - AnsiString GeoidDataFile_Text=GeoidDataFile->Text; - AnsiString DCBFile_Text=DCBFile->Text; - AnsiString EOPFile_Text=EOPFile->Text; - AnsiString BLQFile_Text=BLQFile->Text; - AnsiString LocalDir_Text=LocalDir->Text; - int itype[]={STR_SERIAL,STR_TCPCLI,STR_TCPSVR,STR_NTRIPCLI,STR_FILE,STR_FTP,STR_HTTP}; - int otype[]={STR_SERIAL,STR_TCPCLI,STR_TCPSVR,STR_NTRIPSVR,STR_NTRIPCAS,STR_FILE}; - TEdit *editu[]={RovPos1,RovPos2,RovPos3}; - TEdit *editr[]={RefPos1,RefPos2,RefPos3}; - char buff[1024],*p,*q,id[32],comment[256],s[40]; - int sat,ex; - prcopt_t prcopt=prcopt_default; - solopt_t solopt=solopt_default; - filopt_t filopt={""}; - - for (int i=0;i<8;i++) { - strtype[i]=i<3?itype[MainForm->Stream[i]]:otype[MainForm->Stream[i]]; - strfmt[i]=MainForm->Format[i]; - - if (!MainForm->StreamC[i]) { - strtype[i]=STR_NONE; - strcpy(strpath[i],""); - } - else if (strtype[i]==STR_SERIAL) { - strcpy(strpath[i],MainForm->Paths[i][0].c_str()); - } - else if (strtype[i]==STR_FILE) { - strcpy(strpath[i],MainForm->Paths[i][2].c_str()); - } - else if (strtype[i]==STR_TCPSVR) { - strcpy(buff,MainForm->Paths[i][1].c_str()); - if ((p=strchr(buff,'/'))) *p='\0'; - if ((p=strrchr(buff,':'))) { - strcpy(strpath[i],p); - } - else { - strcpy(strpath[i],""); - } - } - else if (strtype[i]==STR_TCPCLI) { - strcpy(buff,MainForm->Paths[i][1].c_str()); - if ((p=strchr(buff,'/'))) *p='\0'; - if ((p=strrchr(buff,'@'))) { - strcpy(strpath[i],p+1); - } - else { - strcpy(strpath[i],buff); - } - } - else if (strtype[i]==STR_NTRIPSVR) { - strcpy(buff,MainForm->Paths[i][1].c_str()); - if ((p=strchr(buff,':'))&&strchr(p+1,'@')) { - strcpy(strpath[i],p); - } - else { - strcpy(strpath[i],buff); - } - } - else if (strtype[i]==STR_NTRIPCLI) { - strcpy(buff,MainForm->Paths[i][1].c_str()); - if ((p=strchr(buff,'/'))&&(q=strchr(p+1,':'))) *q='\0'; - strcpy(strpath[i],buff); - } - else if (strtype[i]==STR_NTRIPCAS) { - strcpy(buff,MainForm->Paths[i][1].c_str()); - if ((p=strchr(buff,'/'))&&(q=strchr(p+1,':'))) *q='\0'; - if ((p=strchr(buff,'@'))) { - *(p+1)='\0'; - strcpy(strpath[i],buff); - } - if ((p=strchr(p?p+2:buff,':'))) { - strcat(strpath[i],p); - } - } - else if (strtype[i]==STR_FTP||strtype[i]==STR_HTTP) { - strcpy(strpath[i],MainForm->Paths[i][3].c_str()); - } - } - nmeareq =MainForm->NmeaReq; - nmeapos[0]=MainForm->NmeaPos[0]; - nmeapos[1]=MainForm->NmeaPos[1]; - - svrcycle =SvrCycleE ->Text.ToInt(); - timeout =TimeoutTimeE->Text.ToInt(); - reconnect =ReconTimeE ->Text.ToInt(); - nmeacycle =NmeaCycleE ->Text.ToInt(); - buffsize =SvrBuffSizeE->Text.ToInt(); - navmsgsel =NavSelectS ->ItemIndex; - strcpy(proxyaddr,ProxyAddrE_Text.c_str()); - fswapmargin =FileSwapMarginE->Text.ToInt(); - prcopt.sbassatsel=SbasSatE->Text.ToInt(); - - prcopt.mode =PosMode ->ItemIndex; - prcopt.nf =Freq ->ItemIndex+1; - prcopt.elmin =str2dbl(ElMask ->Text)*D2R; - prcopt.snrmask =PrcOpt.snrmask; - prcopt.dynamics =DynamicModel->ItemIndex; - prcopt.tidecorr =TideCorr ->ItemIndex; - if (prcopt.tidecorr > 1) prcopt.tidecorr = 7; - prcopt.ionoopt =IonoOpt ->ItemIndex; - prcopt.tropopt =TropOpt ->ItemIndex; - prcopt.sateph =SatEphem ->ItemIndex; - if (ExSatsE->Text!="") { - strcpy(buff,ExSatsE_Text.c_str()); - for (p=strtok(buff," ");p;p=strtok(NULL," ")) { - if (*p=='+') {ex=2; p++;} else ex=1; - if (!(sat=satid2no(p))) continue; - prcopt.exsats[sat-1]=ex; - } - } - prcopt.navsys = (NavSys1->Checked?SYS_GPS:0)| - (NavSys2->Checked?SYS_GLO:0)| - (NavSys3->Checked?SYS_GAL:0)| - (NavSys4->Checked?SYS_QZS:0)| - (NavSys5->Checked?SYS_SBS:0)| - (NavSys6->Checked?SYS_CMP:0)| - (NavSys7->Checked?SYS_IRN:0); - prcopt.posopt[0]=PosOpt1->Checked; - prcopt.posopt[1]=PosOpt2->Checked; - prcopt.posopt[2]=PosOpt3->Checked; - prcopt.posopt[3]=PosOpt4->Checked; - prcopt.posopt[4]=PosOpt5->Checked; - prcopt.posopt[5]=PosOpt6->Checked; - - prcopt.modear =AmbRes ->ItemIndex; - prcopt.glomodear=GloAmbRes ->ItemIndex; - prcopt.bdsmodear=BdsAmbRes ->ItemIndex; - prcopt.thresar[0]=str2dbl(ValidThresAR->Text); - prcopt.thresar[1]=str2dbl(MaxPosVarAR->Text); - prcopt.thresar[2]=str2dbl(GloHwBias->Text); - prcopt.thresar[5]=str2dbl(ValidThresARMin->Text); - prcopt.thresar[6]=str2dbl(ValidThresARMax->Text); - prcopt.maxout =str2dbl(OutCntResetAmb->Text); - prcopt.minfix =str2dbl(FixCntHoldAmb->Text); - prcopt.minlock =str2dbl(LockCntFixAmb->Text); - prcopt.elmaskar =str2dbl(ElMaskAR ->Text)*D2R; - prcopt.elmaskhold=str2dbl(ElMaskHold->Text)*D2R; - prcopt.maxtdiff =str2dbl(MaxAgeDiff ->Text); - prcopt.maxinno[1] =str2dbl(RejectCode ->Text); - prcopt.maxinno[0] =str2dbl(RejectPhase->Text); - prcopt.varholdamb=str2dbl(VarHoldAmb->Text); - prcopt.gainholdamb=str2dbl(GainHoldAmb->Text); - prcopt.thresslip=str2dbl(SlipThres ->Text); - prcopt.thresdop=str2dbl(DopThres ->Text); - prcopt.armaxiter=str2dbl(ARIter ->Text); - prcopt.minfixsats=str2dbl(MinFixSats ->Text); - prcopt.minholdsats=str2dbl(MinHoldSats ->Text); - prcopt.mindropsats=str2dbl(MinDropSats ->Text); - prcopt.niter =str2dbl(NumIter ->Text); - prcopt.syncsol =SyncSol->ItemIndex; - prcopt.arfilter =ARFilter->ItemIndex; - if (prcopt.mode==PMODE_MOVEB&&BaselineConst->Checked) { - prcopt.baseline[0]=str2dbl(BaselineLen->Text); - prcopt.baseline[1]=str2dbl(BaselineSig->Text); - } - solopt.posf =SolFormat ->ItemIndex; - solopt.timef =TimeFormat ->ItemIndex==0?0:1; - solopt.times =TimeFormat ->ItemIndex==0?TIMES_GPST:(TimeFormat->ItemIndex-1); - solopt.timeu =str2dbl(TimeDecimal ->Text); - solopt.degf =LatLonFormat->ItemIndex; - strcpy(solopt.sep,FieldSep_Text.c_str()); - solopt.outhead =OutputHead ->ItemIndex; - solopt.outopt =OutputOpt ->ItemIndex; - solopt.outvel =OutputVel ->ItemIndex; - prcopt.outsingle=OutputSingle->ItemIndex; - solopt.maxsolstd=str2dbl(MaxSolStd->Text); - solopt.datum =OutputDatum ->ItemIndex; - solopt.height =OutputHeight->ItemIndex; - solopt.geoid =OutputGeoid ->ItemIndex; - solopt.nmeaintv[0]=str2dbl(NmeaIntv1->Text); - solopt.nmeaintv[1]=str2dbl(NmeaIntv2->Text); - solopt.trace =DebugTrace ->ItemIndex; - solopt.sstat =DebugStatus ->ItemIndex; - - prcopt.eratio[0]=str2dbl(MeasErrR1->Text); - prcopt.eratio[1]=str2dbl(MeasErrR2->Text); - prcopt.eratio[2]=str2dbl(MeasErrR5->Text); - prcopt.eratio[3]=str2dbl(MeasErrR6->Text); - prcopt.err[1] =str2dbl(MeasErr2->Text); - prcopt.err[2] =str2dbl(MeasErr3->Text); - prcopt.err[3] =str2dbl(MeasErr4->Text); - prcopt.err[4] =str2dbl(MeasErr5->Text); - prcopt.err[5] =str2dbl(MeasErr6->Text); - prcopt.err[6] =str2dbl(MeasErr7->Text); - prcopt.err[7] =str2dbl(MeasErr8->Text); - prcopt.sclkstab =str2dbl(SatClkStab->Text); - prcopt.prn[0] =str2dbl(PrNoise1->Text); - prcopt.prn[1] =str2dbl(PrNoise2->Text); - prcopt.prn[2] =str2dbl(PrNoise3->Text); - prcopt.prn[3] =str2dbl(PrNoise4->Text); - prcopt.prn[4] =str2dbl(PrNoise5->Text); - - if (RovAntPcv->Checked) strcpy(prcopt.anttype[0],RovAnt_Text.c_str()); - if (RefAntPcv->Checked) strcpy(prcopt.anttype[1],RefAnt_Text.c_str()); - prcopt.antdel[0][0]=str2dbl(RovAntE->Text); - prcopt.antdel[0][1]=str2dbl(RovAntN->Text); - prcopt.antdel[0][2]=str2dbl(RovAntU->Text); - prcopt.antdel[1][0]=str2dbl(RefAntE->Text); - prcopt.antdel[1][1]=str2dbl(RefAntN->Text); - prcopt.antdel[1][2]=str2dbl(RefAntU->Text); - prcopt.maxaveep=MaxAveEp->Text.ToInt(); - prcopt.initrst=ChkInitRestart->Checked; - - prcopt.rovpos = POSOPT_POS_LLH; - if (RovPosTypeP->ItemIndex < 2) prcopt.rovpos = POSOPT_POS_LLH; - else if (RovPosTypeP->ItemIndex == 2) prcopt.rovpos = POSOPT_POS_XYZ; - else if (RovPosTypeP->ItemIndex == 3) prcopt.rovpos = POSOPT_RTCM; - - prcopt.refpos = POSOPT_POS_LLH; - if (RefPosTypeP->ItemIndex < 2) prcopt.refpos = POSOPT_POS_LLH; - else if (RefPosTypeP->ItemIndex == 2) prcopt.refpos = POSOPT_POS_XYZ; - else if (RefPosTypeP->ItemIndex == 3) prcopt.refpos=POSOPT_RTCM; - else if (RefPosTypeP->ItemIndex==4) prcopt.refpos=POSOPT_SINGLE; - - if (prcopt.rovpos == POSOPT_POS_LLH || prcopt.rovpos == POSOPT_POS_XYZ) - GetPos(RovPosTypeP->ItemIndex, editu, prcopt.ru); - if (prcopt.refpos == POSOPT_POS_LLH || prcopt.refpos == POSOPT_POS_XYZ) - GetPos(RefPosTypeP->ItemIndex, editr, prcopt.rb); - - strcpy(filopt.satantp,SatPcvFile_Text.c_str()); - strcpy(filopt.rcvantp,AntPcvFile_Text.c_str()); - strcpy(filopt.stapos, StaPosFile_Text.c_str()); - strcpy(filopt.geoid, GeoidDataFile_Text.c_str()); - strcpy(filopt.dcb, DCBFile_Text.c_str()); - strcpy(filopt.eop, EOPFile_Text.c_str()); - strcpy(filopt.blq, BLQFile_Text.c_str()); - strcpy(filopt.tempdir,LocalDir_Text.c_str()); - - time2str(utc2gpst(timeget()),s,0); - sprintf(comment,"RTKNAVI options (%s-%s %s)",s,VER_RTKLIB,PATCH_LEVEL); - setsysopts(&prcopt,&solopt,&filopt); - if (!saveopts(file.c_str(),"w",comment,sysopts)|| - !saveopts(file.c_str(),"a","",rcvopts)) return; +void __fastcall TOptDialog::SaveOpt(AnsiString file) { + AnsiString ProxyAddrE_Text = ProxyAddrE->Text; + AnsiString ExSatsE_Text = ExSatsE->Text; + AnsiString FieldSep_Text = FieldSep->Text; + AnsiString RovAnt_Text = RovAnt->Text, RefAnt_Text = RefAnt->Text; + AnsiString SatPcvFile_Text = SatPcvFile->Text; + AnsiString AntPcvFile_Text = AntPcvFile->Text; + AnsiString StaPosFile_Text = StaPosFile->Text; + AnsiString GeoidDataFile_Text = GeoidDataFile->Text; + AnsiString DCBFile_Text = DCBFile->Text; + AnsiString EOPFile_Text = EOPFile->Text; + AnsiString BLQFile_Text = BLQFile->Text; + AnsiString LocalDir_Text = LocalDir->Text; + int itype[] = {STR_SERIAL, STR_TCPCLI, STR_TCPSVR, STR_NTRIPCLI, STR_FILE, STR_FTP, STR_HTTP}; + int otype[] = {STR_SERIAL, STR_TCPCLI, STR_TCPSVR, STR_NTRIPSVR, STR_NTRIPCAS, STR_FILE}; + TEdit *editu[] = {RovPos1, RovPos2, RovPos3}; + TEdit *editr[] = {RefPos1, RefPos2, RefPos3}; + char buff[1024], *p, *q, id[32], comment[256], s[40]; + int sat, ex; + prcopt_t prcopt = prcopt_default; + solopt_t solopt = solopt_default; + filopt_t filopt = {""}; + + for (int i = 0; i < 8; i++) { + strtype[i] = i < 3 ? itype[MainForm->Stream[i]] : otype[MainForm->Stream[i]]; + strfmt[i] = MainForm->Format[i]; + + if (!MainForm->StreamC[i]) { + strtype[i] = STR_NONE; + strcpy(strpath[i], ""); + } else if (strtype[i] == STR_SERIAL) { + strcpy(strpath[i], MainForm->Paths[i][0].c_str()); + } else if (strtype[i] == STR_FILE) { + strcpy(strpath[i], MainForm->Paths[i][2].c_str()); + } else if (strtype[i] == STR_TCPSVR) { + strcpy(buff, MainForm->Paths[i][1].c_str()); + if ((p = strchr(buff, '/'))) *p = '\0'; + if ((p = strrchr(buff, ':'))) { + strcpy(strpath[i], p); + } else { + strcpy(strpath[i], ""); + } + } else if (strtype[i] == STR_TCPCLI) { + strcpy(buff, MainForm->Paths[i][1].c_str()); + if ((p = strchr(buff, '/'))) *p = '\0'; + if ((p = strrchr(buff, '@'))) { + strcpy(strpath[i], p + 1); + } else { + strcpy(strpath[i], buff); + } + } else if (strtype[i] == STR_NTRIPSVR) { + strcpy(buff, MainForm->Paths[i][1].c_str()); + if ((p = strchr(buff, ':')) && strchr(p + 1, '@')) { + strcpy(strpath[i], p); + } else { + strcpy(strpath[i], buff); + } + } else if (strtype[i] == STR_NTRIPCLI) { + strcpy(buff, MainForm->Paths[i][1].c_str()); + if ((p = strchr(buff, '/')) && (q = strchr(p + 1, ':'))) *q = '\0'; + strcpy(strpath[i], buff); + } else if (strtype[i] == STR_NTRIPCAS) { + strcpy(buff, MainForm->Paths[i][1].c_str()); + if ((p = strchr(buff, '/')) && (q = strchr(p + 1, ':'))) *q = '\0'; + if ((p = strchr(buff, '@'))) { + *(p + 1) = '\0'; + strcpy(strpath[i], buff); + } + if ((p = strchr(p ? p + 2 : buff, ':'))) { + strcat(strpath[i], p); + } + } else if (strtype[i] == STR_FTP || strtype[i] == STR_HTTP) { + strcpy(strpath[i], MainForm->Paths[i][3].c_str()); + } + } + nmeareq = MainForm->NmeaReq; + nmeapos[0] = MainForm->NmeaPos[0]; + nmeapos[1] = MainForm->NmeaPos[1]; + + svrcycle = SvrCycleE->Text.ToInt(); + timeout = TimeoutTimeE->Text.ToInt(); + reconnect = ReconTimeE->Text.ToInt(); + nmeacycle = NmeaCycleE->Text.ToInt(); + buffsize = SvrBuffSizeE->Text.ToInt(); + navmsgsel = NavSelectS->ItemIndex; + strcpy(proxyaddr, ProxyAddrE_Text.c_str()); + fswapmargin = FileSwapMarginE->Text.ToInt(); + prcopt.sbassatsel = SbasSatE->Text.ToInt(); + + prcopt.mode = PosMode->ItemIndex; + prcopt.nf = Freq->ItemIndex + 1; + prcopt.elmin = str2dbl(ElMask->Text) * D2R; + prcopt.snrmask = PrcOpt.snrmask; + prcopt.dynamics = DynamicModel->ItemIndex; + prcopt.tidecorr = TideCorr->ItemIndex; + if (prcopt.tidecorr > 1) prcopt.tidecorr = 7; + prcopt.ionoopt = IonoOpt->ItemIndex; + prcopt.tropopt = TropOpt->ItemIndex; + prcopt.sateph = SatEphem->ItemIndex; + if (ExSatsE->Text != "") { + strcpy(buff, ExSatsE_Text.c_str()); + for (p = strtok(buff, " "); p; p = strtok(NULL, " ")) { + if (*p == '+') { + ex = 2; + p++; + } else + ex = 1; + if (!(sat = satid2no(p))) continue; + prcopt.exsats[sat - 1] = ex; + } + } + prcopt.navsys = (NavSys1->Checked ? SYS_GPS : 0) | (NavSys2->Checked ? SYS_GLO : 0) | + (NavSys3->Checked ? SYS_GAL : 0) | (NavSys4->Checked ? SYS_QZS : 0) | + (NavSys5->Checked ? SYS_SBS : 0) | (NavSys6->Checked ? SYS_CMP : 0) | + (NavSys7->Checked ? SYS_IRN : 0); + prcopt.posopt[0] = PosOpt1->Checked; + prcopt.posopt[1] = PosOpt2->Checked; + prcopt.posopt[2] = PosOpt3->Checked; + prcopt.posopt[3] = PosOpt4->Checked; + prcopt.posopt[4] = PosOpt5->Checked; + prcopt.posopt[5] = PosOpt6->Checked; + + prcopt.modear = AmbRes->ItemIndex; + prcopt.glomodear = GloAmbRes->ItemIndex; + prcopt.bdsmodear = BdsAmbRes->ItemIndex; + prcopt.thresar[0] = str2dbl(ValidThresAR->Text); + prcopt.thresar[1] = str2dbl(MaxPosVarAR->Text); + prcopt.thresar[2] = str2dbl(GloHwBias->Text); + prcopt.thresar[5] = str2dbl(ValidThresARMin->Text); + prcopt.thresar[6] = str2dbl(ValidThresARMax->Text); + prcopt.maxout = str2dbl(OutCntResetAmb->Text); + prcopt.minfix = str2dbl(FixCntHoldAmb->Text); + prcopt.minlock = str2dbl(LockCntFixAmb->Text); + prcopt.elmaskar = str2dbl(ElMaskAR->Text) * D2R; + prcopt.elmaskhold = str2dbl(ElMaskHold->Text) * D2R; + prcopt.maxtdiff = str2dbl(MaxAgeDiff->Text); + prcopt.maxinno[1] = str2dbl(RejectCode->Text); + prcopt.maxinno[0] = str2dbl(RejectPhase->Text); + prcopt.varholdamb = str2dbl(VarHoldAmb->Text); + prcopt.gainholdamb = str2dbl(GainHoldAmb->Text); + prcopt.thresslip = str2dbl(SlipThres->Text); + prcopt.thresdop = str2dbl(DopThres->Text); + prcopt.armaxiter = str2dbl(ARIter->Text); + prcopt.minfixsats = str2dbl(MinFixSats->Text); + prcopt.minholdsats = str2dbl(MinHoldSats->Text); + prcopt.mindropsats = str2dbl(MinDropSats->Text); + prcopt.niter = str2dbl(NumIter->Text); + prcopt.syncsol = SyncSol->ItemIndex; + prcopt.arfilter = ARFilter->ItemIndex; + if (prcopt.mode == PMODE_MOVEB && BaselineConst->Checked) { + prcopt.baseline[0] = str2dbl(BaselineLen->Text); + prcopt.baseline[1] = str2dbl(BaselineSig->Text); + } + solopt.posf = SolFormat->ItemIndex; + solopt.timef = TimeFormat->ItemIndex == 0 ? 0 : 1; + solopt.times = TimeFormat->ItemIndex == 0 ? TIMES_GPST : (TimeFormat->ItemIndex - 1); + solopt.timeu = str2dbl(TimeDecimal->Text); + solopt.degf = LatLonFormat->ItemIndex; + strcpy(solopt.sep, FieldSep_Text.c_str()); + solopt.outhead = OutputHead->ItemIndex; + solopt.outopt = OutputOpt->ItemIndex; + solopt.outvel = OutputVel->ItemIndex; + prcopt.outsingle = OutputSingle->ItemIndex; + solopt.maxsolstd = str2dbl(MaxSolStd->Text); + solopt.datum = OutputDatum->ItemIndex; + solopt.height = OutputHeight->ItemIndex; + solopt.geoid = OutputGeoid->ItemIndex; + solopt.nmeaintv[0] = str2dbl(NmeaIntv1->Text); + solopt.nmeaintv[1] = str2dbl(NmeaIntv2->Text); + solopt.trace = DebugTrace->ItemIndex; + solopt.sstat = DebugStatus->ItemIndex; + + prcopt.eratio[0] = str2dbl(MeasErrR1->Text); + prcopt.eratio[1] = str2dbl(MeasErrR2->Text); + prcopt.eratio[2] = str2dbl(MeasErrR5->Text); + prcopt.eratio[3] = str2dbl(MeasErrR6->Text); + prcopt.err[1] = str2dbl(MeasErr2->Text); + prcopt.err[2] = str2dbl(MeasErr3->Text); + prcopt.err[3] = str2dbl(MeasErr4->Text); + prcopt.err[4] = str2dbl(MeasErr5->Text); + prcopt.err[5] = str2dbl(MeasErr6->Text); + prcopt.err[6] = str2dbl(MeasErr7->Text); + prcopt.err[7] = str2dbl(MeasErr8->Text); + prcopt.sclkstab = str2dbl(SatClkStab->Text); + prcopt.prn[0] = str2dbl(PrNoise1->Text); + prcopt.prn[1] = str2dbl(PrNoise2->Text); + prcopt.prn[2] = str2dbl(PrNoise3->Text); + prcopt.prn[3] = str2dbl(PrNoise4->Text); + prcopt.prn[4] = str2dbl(PrNoise5->Text); + + if (RovAntPcv->Checked) strcpy(prcopt.anttype[0], RovAnt_Text.c_str()); + if (RefAntPcv->Checked) strcpy(prcopt.anttype[1], RefAnt_Text.c_str()); + prcopt.antdel[0][0] = str2dbl(RovAntE->Text); + prcopt.antdel[0][1] = str2dbl(RovAntN->Text); + prcopt.antdel[0][2] = str2dbl(RovAntU->Text); + prcopt.antdel[1][0] = str2dbl(RefAntE->Text); + prcopt.antdel[1][1] = str2dbl(RefAntN->Text); + prcopt.antdel[1][2] = str2dbl(RefAntU->Text); + prcopt.maxaveep = MaxAveEp->Text.ToInt(); + prcopt.initrst = ChkInitRestart->Checked; + + prcopt.rovpos = POSOPT_POS_LLH; + if (RovPosTypeP->ItemIndex < 2) + prcopt.rovpos = POSOPT_POS_LLH; + else if (RovPosTypeP->ItemIndex == 2) + prcopt.rovpos = POSOPT_POS_XYZ; + else if (RovPosTypeP->ItemIndex == 3) + prcopt.rovpos = POSOPT_RTCM; + + prcopt.refpos = POSOPT_POS_LLH; + if (RefPosTypeP->ItemIndex < 2) + prcopt.refpos = POSOPT_POS_LLH; + else if (RefPosTypeP->ItemIndex == 2) + prcopt.refpos = POSOPT_POS_XYZ; + else if (RefPosTypeP->ItemIndex == 3) + prcopt.refpos = POSOPT_RTCM; + else if (RefPosTypeP->ItemIndex == 4) + prcopt.refpos = POSOPT_SINGLE; + + if (prcopt.rovpos == POSOPT_POS_LLH || prcopt.rovpos == POSOPT_POS_XYZ) + GetPos(RovPosTypeP->ItemIndex, editu, prcopt.ru); + if (prcopt.refpos == POSOPT_POS_LLH || prcopt.refpos == POSOPT_POS_XYZ) + GetPos(RefPosTypeP->ItemIndex, editr, prcopt.rb); + + strcpy(filopt.satantp, SatPcvFile_Text.c_str()); + strcpy(filopt.rcvantp, AntPcvFile_Text.c_str()); + strcpy(filopt.stapos, StaPosFile_Text.c_str()); + strcpy(filopt.geoid, GeoidDataFile_Text.c_str()); + strcpy(filopt.dcb, DCBFile_Text.c_str()); + strcpy(filopt.eop, EOPFile_Text.c_str()); + strcpy(filopt.blq, BLQFile_Text.c_str()); + strcpy(filopt.tempdir, LocalDir_Text.c_str()); + + time2str(utc2gpst(timeget()), s, 0); + sprintf(comment, "RTKNAVI options (%s-%s %s)", s, VER_RTKLIB, PATCH_LEVEL); + setsysopts(&prcopt, &solopt, &filopt); + if (!saveopts(file.c_str(), "w", comment, sysopts) || !saveopts(file.c_str(), "a", "", rcvopts)) + return; } //--------------------------------------------------------------------------- -void __fastcall TOptDialog::UpdateEnable(void) -{ - int rel=PMODE_DGPS<=PosMode->ItemIndex&&PosMode->ItemIndex<=PMODE_FIXED; - int rtk=PMODE_KINEMA<=PosMode->ItemIndex&&PosMode->ItemIndex<=PMODE_FIXED; - int ppp=PosMode->ItemIndex>=PMODE_PPP_KINEMA; - int prec=ppp||rtk; - int ar=rtk; - - Freq ->Enabled=prec; - DynamicModel ->Enabled=prec; - TideCorr ->Enabled=prec; - PosOpt1 ->Enabled=rel||ppp; - PosOpt2 ->Enabled=rel||ppp; - PosOpt3 ->Enabled=ppp; - PosOpt4 ->Enabled=ppp; - PosOpt6 ->Enabled=ppp; - - AmbRes ->Enabled=ar; - GloAmbRes ->Enabled=ar&&AmbRes->ItemIndex>0&&NavSys2->Checked; - BdsAmbRes ->Enabled=ar&&AmbRes->ItemIndex>0&&NavSys6->Checked; - ValidThresAR ->Enabled=ar&&AmbRes->ItemIndex>=1&&AmbRes->ItemIndex<4; - ValidThresARMin->Enabled=ar&&AmbRes->ItemIndex>=1&&AmbRes->ItemIndex<4; - ValidThresARMax->Enabled=ar&&AmbRes->ItemIndex>=1&&AmbRes->ItemIndex<4; - MaxPosVarAR ->Enabled=ar; - GloHwBias ->Enabled=rtk&&GloAmbRes->ItemIndex==2; - LockCntFixAmb ->Enabled=ar&&AmbRes->ItemIndex>=1; - ElMaskAR ->Enabled=ar&&AmbRes->ItemIndex>=1; - OutCntResetAmb ->Enabled=prec; - FixCntHoldAmb ->Enabled=ar&&AmbRes->ItemIndex==3; - ElMaskHold ->Enabled=ar&&AmbRes->ItemIndex==3; - SlipThres ->Enabled=prec; - DopThres ->Enabled=rtk; - MaxAgeDiff ->Enabled=rel; - RejectPhase ->Enabled=rel||ppp; - RejectCode ->Enabled=rel||ppp; - VarHoldAmb ->Enabled=ar&&AmbRes->ItemIndex==3; - GainHoldAmb ->Enabled=ar&&AmbRes->ItemIndex==3; - ARIter ->Enabled=False; - MinFixSats ->Enabled=ar; - MinHoldSats ->Enabled=ar; - MinDropSats ->Enabled=ar; - NumIter ->Enabled=rel||ppp; - SyncSol ->Enabled=rel||ppp; - ARFilter ->Enabled=ar; - BaselineConst ->Enabled=PosMode->ItemIndex==PMODE_MOVEB; - BaselineLen ->Enabled=BaselineConst->Checked&&PosMode->ItemIndex==PMODE_MOVEB; - BaselineSig ->Enabled=BaselineConst->Checked&&PosMode->ItemIndex==PMODE_MOVEB; - - OutputHead ->Enabled=SolFormat->ItemIndex<3; - OutputOpt ->Enabled=SolFormat->ItemIndex<3; - TimeFormat ->Enabled=SolFormat->ItemIndex<3; - TimeDecimal ->Enabled=SolFormat->ItemIndex<3; - LatLonFormat ->Enabled=SolFormat->ItemIndex==0; - FieldSep ->Enabled=SolFormat->ItemIndex<3; - OutputSingle ->Enabled=PosMode->ItemIndex!=0; - OutputDatum ->Enabled=SolFormat->ItemIndex==0; - OutputHeight ->Enabled=SolFormat->ItemIndex==0; - OutputGeoid ->Enabled=SolFormat->ItemIndex==0&&OutputHeight->ItemIndex==1; - - // For rtknavi the delta can be supplied even when antenna selection - // is automated, in which case the delta fills in until overwritten - // when the antenna and it's delta are known. - RovAntPcv ->Enabled=rel||ppp; - RovAnt ->Enabled=(rel||ppp)&&RovAntPcv->Checked; - RefAntPcv ->Enabled=rel; - RefAnt ->Enabled=rel&&RefAntPcv->Checked; - RefAntE ->Enabled=rel; - RefAntN ->Enabled=rel; - RefAntU ->Enabled=rel; - LabelRefAntD ->Enabled=rel; - - RovPosTypeP ->Enabled=PosMode->ItemIndex==PMODE_FIXED||PosMode->ItemIndex==PMODE_PPP_FIXED; - RovPos1 ->Enabled=RovPosTypeP->Enabled&&RovPosTypeP->ItemIndex<=2; - RovPos2 ->Enabled=RovPosTypeP->Enabled&&RovPosTypeP->ItemIndex<=2; - RovPos3 ->Enabled=RovPosTypeP->Enabled&&RovPosTypeP->ItemIndex<=2; - BtnRovPos ->Enabled=RovPosTypeP->Enabled&&RovPosTypeP->ItemIndex<=2; - - RefPosTypeP ->Enabled=rel&&PosMode->ItemIndex!=PMODE_MOVEB; - RefPos1 ->Enabled=RefPosTypeP->Enabled&&RefPosTypeP->ItemIndex<=2; - RefPos2 ->Enabled=RefPosTypeP->Enabled&&RefPosTypeP->ItemIndex<=2; - RefPos3 ->Enabled=RefPosTypeP->Enabled&&RefPosTypeP->ItemIndex<=2; - BtnRefPos ->Enabled=RefPosTypeP->Enabled&&RefPosTypeP->ItemIndex<=2; - - LabelMaxAveEp ->Enabled=RefPosTypeP->ItemIndex==4; - MaxAveEp ->Enabled=RefPosTypeP->ItemIndex==4; - ChkInitRestart ->Enabled=RefPosTypeP->ItemIndex==4; - -// SbasSatE ->Enabled=PosMode->ItemIndex==0; +void __fastcall TOptDialog::UpdateEnable(void) { + int rel = PMODE_DGPS <= PosMode->ItemIndex && PosMode->ItemIndex <= PMODE_FIXED; + int rtk = PMODE_KINEMA <= PosMode->ItemIndex && PosMode->ItemIndex <= PMODE_FIXED; + int ppp = PosMode->ItemIndex >= PMODE_PPP_KINEMA; + int prec = ppp || rtk; + int ar = rtk; + + Freq->Enabled = prec; + DynamicModel->Enabled = prec; + TideCorr->Enabled = prec; + PosOpt1->Enabled = rel || ppp; + PosOpt2->Enabled = rel || ppp; + PosOpt3->Enabled = ppp; + PosOpt4->Enabled = ppp; + PosOpt6->Enabled = ppp; + + AmbRes->Enabled = ar; + GloAmbRes->Enabled = ar && AmbRes->ItemIndex > 0 && NavSys2->Checked; + BdsAmbRes->Enabled = ar && AmbRes->ItemIndex > 0 && NavSys6->Checked; + ValidThresAR->Enabled = ar && AmbRes->ItemIndex >= 1 && AmbRes->ItemIndex < 4; + ValidThresARMin->Enabled = ar && AmbRes->ItemIndex >= 1 && AmbRes->ItemIndex < 4; + ValidThresARMax->Enabled = ar && AmbRes->ItemIndex >= 1 && AmbRes->ItemIndex < 4; + MaxPosVarAR->Enabled = ar; + GloHwBias->Enabled = rtk && GloAmbRes->ItemIndex == 2; + LockCntFixAmb->Enabled = ar && AmbRes->ItemIndex >= 1; + ElMaskAR->Enabled = ar && AmbRes->ItemIndex >= 1; + OutCntResetAmb->Enabled = prec; + FixCntHoldAmb->Enabled = ar && AmbRes->ItemIndex == 3; + ElMaskHold->Enabled = ar && AmbRes->ItemIndex == 3; + SlipThres->Enabled = prec; + DopThres->Enabled = rtk; + MaxAgeDiff->Enabled = rel; + RejectPhase->Enabled = rel || ppp; + RejectCode->Enabled = rel || ppp; + VarHoldAmb->Enabled = ar && AmbRes->ItemIndex == 3; + GainHoldAmb->Enabled = ar && AmbRes->ItemIndex == 3; + ARIter->Enabled = False; + MinFixSats->Enabled = ar; + MinHoldSats->Enabled = ar; + MinDropSats->Enabled = ar; + NumIter->Enabled = rel || ppp; + SyncSol->Enabled = rel || ppp; + ARFilter->Enabled = ar; + BaselineConst->Enabled = PosMode->ItemIndex == PMODE_MOVEB; + BaselineLen->Enabled = BaselineConst->Checked && PosMode->ItemIndex == PMODE_MOVEB; + BaselineSig->Enabled = BaselineConst->Checked && PosMode->ItemIndex == PMODE_MOVEB; + + OutputHead->Enabled = SolFormat->ItemIndex < 3; + OutputOpt->Enabled = SolFormat->ItemIndex < 3; + TimeFormat->Enabled = SolFormat->ItemIndex < 3; + TimeDecimal->Enabled = SolFormat->ItemIndex < 3; + LatLonFormat->Enabled = SolFormat->ItemIndex == 0; + FieldSep->Enabled = SolFormat->ItemIndex < 3; + OutputSingle->Enabled = PosMode->ItemIndex != 0; + OutputDatum->Enabled = SolFormat->ItemIndex == 0; + OutputHeight->Enabled = SolFormat->ItemIndex == 0; + OutputGeoid->Enabled = SolFormat->ItemIndex == 0 && OutputHeight->ItemIndex == 1; + + // For rtknavi the delta can be supplied even when antenna selection + // is automated, in which case the delta fills in until overwritten + // when the antenna and it's delta are known. + RovAntPcv->Enabled = rel || ppp; + RovAnt->Enabled = (rel || ppp) && RovAntPcv->Checked; + RefAntPcv->Enabled = rel; + RefAnt->Enabled = rel && RefAntPcv->Checked; + RefAntE->Enabled = rel; + RefAntN->Enabled = rel; + RefAntU->Enabled = rel; + LabelRefAntD->Enabled = rel; + + RovPosTypeP->Enabled = PosMode->ItemIndex == PMODE_FIXED || PosMode->ItemIndex == PMODE_PPP_FIXED; + RovPos1->Enabled = RovPosTypeP->Enabled && RovPosTypeP->ItemIndex <= 2; + RovPos2->Enabled = RovPosTypeP->Enabled && RovPosTypeP->ItemIndex <= 2; + RovPos3->Enabled = RovPosTypeP->Enabled && RovPosTypeP->ItemIndex <= 2; + BtnRovPos->Enabled = RovPosTypeP->Enabled && RovPosTypeP->ItemIndex <= 2; + + RefPosTypeP->Enabled = rel && PosMode->ItemIndex != PMODE_MOVEB; + RefPos1->Enabled = RefPosTypeP->Enabled && RefPosTypeP->ItemIndex <= 2; + RefPos2->Enabled = RefPosTypeP->Enabled && RefPosTypeP->ItemIndex <= 2; + RefPos3->Enabled = RefPosTypeP->Enabled && RefPosTypeP->ItemIndex <= 2; + BtnRefPos->Enabled = RefPosTypeP->Enabled && RefPosTypeP->ItemIndex <= 2; + + LabelMaxAveEp->Enabled = RefPosTypeP->ItemIndex == 4; + MaxAveEp->Enabled = RefPosTypeP->ItemIndex == 4; + ChkInitRestart->Enabled = RefPosTypeP->ItemIndex == 4; + + // SbasSatE ->Enabled=PosMode->ItemIndex==0; } //--------------------------------------------------------------------------- -void __fastcall TOptDialog::GetPos(int type, TEdit **edit, double *pos) -{ - AnsiString edit0_Text=edit[0]->Text; - AnsiString edit1_Text=edit[1]->Text; - double p[3]={0},dms1[3]={0},dms2[3]={0}; - - if (type==1) { /* lat/lon/height dms/m */ - sscanf(edit0_Text.c_str(),"%lf %lf %lf",dms1,dms1+1,dms1+2); - sscanf(edit1_Text.c_str(),"%lf %lf %lf",dms2,dms2+1,dms2+2); - p[0]=(dms1[0]<0?-1:1)*(fabs(dms1[0])+dms1[1]/60+dms1[2]/3600)*D2R; - p[1]=(dms2[0]<0?-1:1)*(fabs(dms2[0])+dms2[1]/60+dms2[2]/3600)*D2R; - p[2]=str2dbl(edit[2]->Text); - pos2ecef(p,pos); - } - else if (type==2) { /* x/y/z-ecef */ - pos[0]=str2dbl(edit[0]->Text); - pos[1]=str2dbl(edit[1]->Text); - pos[2]=str2dbl(edit[2]->Text); - } - else { - p[0]=str2dbl(edit[0]->Text)*D2R; - p[1]=str2dbl(edit[1]->Text)*D2R; - p[2]=str2dbl(edit[2]->Text); - pos2ecef(p,pos); - } +void __fastcall TOptDialog::GetPos(int type, TEdit **edit, double *pos) { + AnsiString edit0_Text = edit[0]->Text; + AnsiString edit1_Text = edit[1]->Text; + double p[3] = {0}, dms1[3] = {0}, dms2[3] = {0}; + + if (type == 1) { /* lat/lon/height dms/m */ + sscanf(edit0_Text.c_str(), "%lf %lf %lf", dms1, dms1 + 1, dms1 + 2); + sscanf(edit1_Text.c_str(), "%lf %lf %lf", dms2, dms2 + 1, dms2 + 2); + p[0] = (dms1[0] < 0 ? -1 : 1) * (fabs(dms1[0]) + dms1[1] / 60 + dms1[2] / 3600) * D2R; + p[1] = (dms2[0] < 0 ? -1 : 1) * (fabs(dms2[0]) + dms2[1] / 60 + dms2[2] / 3600) * D2R; + p[2] = str2dbl(edit[2]->Text); + pos2ecef(p, pos); + } else if (type == 2) { /* x/y/z-ecef */ + pos[0] = str2dbl(edit[0]->Text); + pos[1] = str2dbl(edit[1]->Text); + pos[2] = str2dbl(edit[2]->Text); + } else { + p[0] = str2dbl(edit[0]->Text) * D2R; + p[1] = str2dbl(edit[1]->Text) * D2R; + p[2] = str2dbl(edit[2]->Text); + pos2ecef(p, pos); + } } //--------------------------------------------------------------------------- -void __fastcall TOptDialog::SetPos(int type, TEdit **edit, double *pos) -{ - AnsiString s; - double p[3],dms1[3],dms2[3],s1,s2; - - if (type==1) { /* lat/lon/height dms/m */ - ecef2pos(pos,p); s1=p[0]<0?-1:1; s2=p[1]<0?-1:1; - p[0]=fabs(p[0])*R2D+1E-12; p[1]=fabs(p[1])*R2D+1E-12; - dms1[0]=floor(p[0]); p[0]=(p[0]-dms1[0])*60.0; - dms1[1]=floor(p[0]); dms1[2]=(p[0]-dms1[1])*60.0; - dms2[0]=floor(p[1]); p[1]=(p[1]-dms2[0])*60.0; - dms2[1]=floor(p[1]); dms2[2]=(p[1]-dms2[1])*60.0; - edit[0]->Text=s.sprintf("%.0f %02.0f %09.6f",s1*dms1[0],dms1[1],dms1[2]); - edit[1]->Text=s.sprintf("%.0f %02.0f %09.6f",s2*dms2[0],dms2[1],dms2[2]); - edit[2]->Text=s.sprintf("%.4f",p[2]); - } - else if (type==2) { /* x/y/z-ecef */ - edit[0]->Text=s.sprintf("%.4f",pos[0]); - edit[1]->Text=s.sprintf("%.4f",pos[1]); - edit[2]->Text=s.sprintf("%.4f",pos[2]); - } - else { - ecef2pos(pos,p); - edit[0]->Text=s.sprintf("%.9f",p[0]*R2D); - edit[1]->Text=s.sprintf("%.9f",p[1]*R2D); - edit[2]->Text=s.sprintf("%.4f",p[2]); - } +void __fastcall TOptDialog::SetPos(int type, TEdit **edit, double *pos) { + AnsiString s; + double p[3], dms1[3], dms2[3], s1, s2; + + if (type == 1) { /* lat/lon/height dms/m */ + ecef2pos(pos, p); + s1 = p[0] < 0 ? -1 : 1; + s2 = p[1] < 0 ? -1 : 1; + p[0] = fabs(p[0]) * R2D + 1E-12; + p[1] = fabs(p[1]) * R2D + 1E-12; + dms1[0] = floor(p[0]); + p[0] = (p[0] - dms1[0]) * 60.0; + dms1[1] = floor(p[0]); + dms1[2] = (p[0] - dms1[1]) * 60.0; + dms2[0] = floor(p[1]); + p[1] = (p[1] - dms2[0]) * 60.0; + dms2[1] = floor(p[1]); + dms2[2] = (p[1] - dms2[1]) * 60.0; + edit[0]->Text = s.sprintf("%.0f %02.0f %09.6f", s1 * dms1[0], dms1[1], dms1[2]); + edit[1]->Text = s.sprintf("%.0f %02.0f %09.6f", s2 * dms2[0], dms2[1], dms2[2]); + edit[2]->Text = s.sprintf("%.4f", p[2]); + } else if (type == 2) { /* x/y/z-ecef */ + edit[0]->Text = s.sprintf("%.4f", pos[0]); + edit[1]->Text = s.sprintf("%.4f", pos[1]); + edit[2]->Text = s.sprintf("%.4f", pos[2]); + } else { + ecef2pos(pos, p); + edit[0]->Text = s.sprintf("%.9f", p[0] * R2D); + edit[1]->Text = s.sprintf("%.9f", p[1] * R2D); + edit[2]->Text = s.sprintf("%.4f", p[2]); + } } //--------------------------------------------------------------------------- -void __fastcall TOptDialog::ReadAntList(void) -{ - AnsiString AntPcvFile_Text=AntPcvFile->Text; - TStringList *list; - pcvs_t pcvs={0}; - char *p; - - list=new TStringList; - list->Add(""); - list->Add("*"); - - if (readpcv(AntPcvFile_Text.c_str(),&pcvs)) { - for (int i=0;i0&&!strcmp(pcvs.pcv[i].type,pcvs.pcv[i-1].type)) continue; - list->Add(pcvs.pcv[i].type); - } - free_pcvs(&pcvs); - } - RovAnt->Items=list; - RefAnt->Items=list; +void __fastcall TOptDialog::ReadAntList(void) { + AnsiString AntPcvFile_Text = AntPcvFile->Text; + TStringList *list; + pcvs_t pcvs = {0}; + char *p; + + list = new TStringList; + list->Add(""); + list->Add("*"); + + if (readpcv(AntPcvFile_Text.c_str(), &pcvs)) { + for (int i = 0; i < pcvs.n; i++) { + if (pcvs.pcv[i].sat) continue; + if ((p = strchr(pcvs.pcv[i].type, ' '))) *p = '\0'; + if (i > 0 && !strcmp(pcvs.pcv[i].type, pcvs.pcv[i - 1].type)) continue; + list->Add(pcvs.pcv[i].type); + } + free_pcvs(&pcvs); + } + RovAnt->Items = list; + RefAnt->Items = list; } //--------------------------------------------------------------------------- -void __fastcall TOptDialog::NavSys6Click(TObject *Sender) -{ - UpdateEnable(); -} +void __fastcall TOptDialog::NavSys6Click(TObject *Sender) { UpdateEnable(); } //--------------------------------------------------------------------------- - -void __fastcall TOptDialog::ObsWeightChange(TObject *Sender) -{ - UpdateEnable(); -} +void __fastcall TOptDialog::ObsWeightChange(TObject *Sender) { UpdateEnable(); } //--------------------------------------------------------------------------- -void __fastcall TOptDialog::BtnFreqClick(TObject *Sender) -{ - FreqDialog->ShowModal(); -} +void __fastcall TOptDialog::BtnFreqClick(TObject *Sender) { FreqDialog->ShowModal(); } //--------------------------------------------------------------------------- -void __fastcall TOptDialog::RefAntClick(TObject *Sender) -{ - UpdateEnable(); -} +void __fastcall TOptDialog::RefAntClick(TObject *Sender) { UpdateEnable(); } //--------------------------------------------------------------------------- -void __fastcall TOptDialog::RovAntClick(TObject *Sender) -{ - UpdateEnable(); -} +void __fastcall TOptDialog::RovAntClick(TObject *Sender) { UpdateEnable(); } //--------------------------------------------------------------------------- - - diff --git a/app/winapp/rtknavi/naviopt.h b/app/winapp/rtknavi/naviopt.h index 81b298347..4d8572e63 100644 --- a/app/winapp/rtknavi/naviopt.h +++ b/app/winapp/rtknavi/naviopt.h @@ -2,318 +2,319 @@ #ifndef navioptH #define navioptH //--------------------------------------------------------------------------- +#include #include +#include #include -#include -#include -#include #include -#include +#include #include -#include +#include +#include + #include "rtklib.h" //--------------------------------------------------------------------------- -class TOptDialog : public TForm -{ -__published: - TButton *BtnCancel; - TButton *BtnOk; - TOpenDialog *OpenDialog; - TButton *BtnSave; - TButton *BtnLoad; - TSaveDialog *SaveDialog; - TPageControl *Options; - TTabSheet *TabSheet1; - TLabel *Label3; - TLabel *Label9; - TLabel *Label8; - TLabel *LabelPosMode; - TLabel *LabelFreq; - TLabel *LabelElMask; - TLabel *Label32; - TLabel *Label35; - TComboBox *DynamicModel; - TComboBox *IonoOpt; - TComboBox *TropOpt; - TComboBox *PosMode; - TComboBox *Freq; - TComboBox *SatEphem; - TEdit *ExSatsE; - TTabSheet *TabSheet2; - TLabel *Label25; - TLabel *Label24; - TLabel *Label13; - TLabel *LabelHold; - TLabel *Label22; - TLabel *Label14; - TLabel *Label11; - TLabel *Label37; - TComboBox *AmbRes; - TEdit *ValidThresAR; - TEdit *LockCntFixAmb; - TEdit *OutCntResetAmb; - TEdit *ElMaskAR; - TEdit *SlipThres; - TEdit *MaxAgeDiff; - TEdit *RejectPhase; - TEdit *NumIter; - TTabSheet *TabSheet3; - TLabel *LabelSolFormat; - TLabel *LabelTimeFormat; - TLabel *LabelLatLonFormat; - TLabel *LabelFieldSep; - TLabel *Label2; - TLabel *Label18; - TLabel *Label20; - TLabel *Label36; - TComboBox *SolFormat; - TComboBox *TimeFormat; - TComboBox *LatLonFormat; - TEdit *FieldSep; - TComboBox *OutputDatum; - TComboBox *OutputHeight; - TComboBox *OutputGeoid; - TComboBox *OutputHead; - TComboBox *OutputOpt; - TComboBox *DebugTrace; - TTabSheet *TabSheet4; - TLabel *Label29; - TGroupBox *GroupBox3; - TLabel *Label6; - TLabel *Label7; - TLabel *Label16; - TEdit *MeasErrR1; - TEdit *MeasErr2; - TEdit *MeasErr3; - TEdit *MeasErr4; - TGroupBox *GroupBox4; - TLabel *Label26; - TLabel *Label27; - TLabel *Label28; - TEdit *PrNoise1; - TEdit *PrNoise2; - TEdit *PrNoise3; - TEdit *SatClkStab; - TTabSheet *TabSheet5; - TGroupBox *GroupRovAnt; - TLabel *LabelRovAntD; - TEdit *RovAntE; - TEdit *RovAntN; - TEdit *RovAntU; - TEdit *RovPos1; - TEdit *RovPos2; - TEdit *RovPos3; - TButton *BtnRovPos; - TCheckBox *RovAntPcv; - TComboBox *RovAnt; - TComboBox *RovPosTypeP; - TGroupBox *GroupRefAnt; - TLabel *LabelRefAntD; - TEdit *RefAntE; - TEdit *RefAntN; - TEdit *RefAntU; - TEdit *RefPos1; - TEdit *RefPos2; - TEdit *RefPos3; - TButton *BtnRefPos; - TCheckBox *RefAntPcv; - TComboBox *RefAnt; - TComboBox *RefPosTypeP; - TTabSheet *TabSheet7; - TLabel *Label1; - TSpeedButton *BtnAntPcvView; - TLabel *Label38; - TSpeedButton *BtnSatPcvView; - TEdit *AntPcvFile; - TButton *BtnAntPcvFile; - TButton *BtnDCBFile; - TEdit *DCBFile; - TEdit *SatPcvFile; - TButton *BtnSatPcvFile; - TTabSheet *TabSheet8; - TLabel *Label19; - TEdit *SvrCycleE; - TEdit *SvrBuffSizeE; - TLabel *Label40; - TButton *BtnFont2; - TLabel *FontLabel2; - TFontDialog *FontDialog; - TLabel *Label41; - TEdit *SolBuffSizeE; - TLabel *Label42; - TComboBox *NavSelectS; - TEdit *SbasSatE; - TLabel *Label5; - TEdit *SavedSolE; - TEdit *NmeaCycleE; - TCheckBox *NavSys2; - TCheckBox *NavSys3; - TCheckBox *NavSys4; - TCheckBox *NavSys1; - TLabel *Label46; - TLabel *Label44; - TEdit *TimeoutTimeE; - TEdit *ReconTimeE; - TCheckBox *NavSys5; - TComboBox *GloAmbRes; - TCheckBox *BaselineConst; - TEdit *BaselineLen; - TEdit *BaselineSig; - TEdit *TimeDecimal; - TComboBox *DebugStatus; - TLabel *Label10; - TLabel *Label33; - TEdit *PrNoise4; - TEdit *PrNoise5; - TLabel *Label48; - TEdit *GeoidDataFile; - TButton *BtnGeoidDataFile; - TLabel *Label17; - TEdit *NmeaIntv1; - TEdit *NmeaIntv2; - TLabel *Label31; - TEdit *LocalDir; - TButton *BtnLocalDir; - TComboBox *TideCorr; - TEdit *FixCntHoldAmb; - TEdit *MoniPortE; - TCheckBox *NavSys6; - TSpeedButton *BtnDCBView; - TLabel *Label21; - TComboBox *SolStatic; - TEdit *StaPosFile; - TLabel *Label30; - TSpeedButton *BtnStaPosView; - TButton *BtnStaPosFile; - TLabel *Label34; - TEdit *BLQFile; - TSpeedButton *BtnBLQFileView; - TButton *BtnBLQFile; - TEdit *MeasErrR2; - TEdit *ElMaskHold; - TEdit *FileSwapMarginE; - TEdit *RejectCode; - TLabel *Label45; - TEdit *ProxyAddrE; - TLabel *Label23; - TEdit *EOPFile; - TButton *BtnEOPFile; - TSpeedButton *BtnEOPView; - TComboBox *ElMask; - TCheckBox *PosOpt1; - TCheckBox *PosOpt2; - TCheckBox *PosOpt3; - TCheckBox *PosOpt4; - TCheckBox *PosOpt5; - TButton *BtnSnrMask; - TComboBox *SyncSol; - TLabel *Label43; - TComboBox *PanelStackE; - TComboBox *BdsAmbRes; - TCheckBox *PosOpt6; - TLabel *LabelMaxAveEp; - TEdit *MaxAveEp; - TCheckBox *ChkInitRestart; - TCheckBox *NavSys7; - TComboBox *OutputSingle; - TEdit *MaxSolStd; - TComboBox *OutputVel; - TSpeedButton *BtnFreq; - TLabel *Label49; - TLabel *FontLabel1; - TButton *BtnFont1; - TEdit *MinFixSats; - TEdit *MinHoldSats; - TComboBox *ARFilter; - TEdit *MaxPosVarAR; - TLabel *Label50; - TEdit *MinDropSats; - TEdit *VarHoldAmb; - TEdit *GainHoldAmb; - TLabel *Label51; - TLabel *Label52; - TEdit *GloHwBias; - TEdit *MeasErr7; - TEdit *ARIter; - TLabel *Label15; - TEdit *ValidThresARMin; - TEdit *ValidThresARMax; - TEdit *DopThres; - TEdit *MeasErrR5; - TEdit *MeasErrR6; - TLabel *Label12; - TEdit *MeasErr6; - TEdit *MeasErr8; - TEdit *MeasErr5; - TLabel *Label53; - void __fastcall BtnOkClick(TObject *Sender); - void __fastcall RovAntPcvClick(TObject *Sender); - void __fastcall FormShow(TObject *Sender); - void __fastcall BtnAntPcvFileClick(TObject *Sender); - void __fastcall BtnDCBFileClick(TObject *Sender); - void __fastcall BtnDCBViewClick(TObject *Sender); - void __fastcall BtnAntPcvViewClick(TObject *Sender); - void __fastcall AmbResChange(TObject *Sender); - void __fastcall SatClkCorrClick(TObject *Sender); - void __fastcall PosModeChange(TObject *Sender); - void __fastcall SolFormatChange(TObject *Sender); - void __fastcall BtnLoadClick(TObject *Sender); - void __fastcall BtnSaveClick(TObject *Sender); - void __fastcall IntpRefObsClick(TObject *Sender); - void __fastcall FreqChange(TObject *Sender); - void __fastcall BtnRefPosClick(TObject *Sender); - void __fastcall BtnRovPosClick(TObject *Sender); - void __fastcall RovPosClick(TObject *Sender); - void __fastcall RefPosClick(TObject *Sender); - void __fastcall BtnStaPosViewClick(TObject *Sender); - void __fastcall BtnStaPosFileClick(TObject *Sender); - void __fastcall OutputHeightClick(TObject *Sender); - void __fastcall RefPosTypePChange(TObject *Sender); - void __fastcall RovPosTypePChange(TObject *Sender); - void __fastcall GetPos(int type, TEdit **edit, double *pos); - void __fastcall SetPos(int type, TEdit **edit, double *pos); - void __fastcall BtnFont2Click(TObject *Sender); - void __fastcall NmeaReqCClick(TObject *Sender); - void __fastcall DgpsCorrLChange(TObject *Sender); - void __fastcall BtnGeoidDataFileClick(TObject *Sender); - void __fastcall NavSys2Click(TObject *Sender); - void __fastcall BaselineConstClick(TObject *Sender); - void __fastcall BtnSatPcvViewClick(TObject *Sender); - void __fastcall BtnSatPcvFileClick(TObject *Sender); - void __fastcall BtnLocalDirClick(TObject *Sender); - void __fastcall BtnEOPFileClick(TObject *Sender); - void __fastcall BtnEOPViewClick(TObject *Sender); - void __fastcall BtnBLQFileClick(TObject *Sender); - void __fastcall BtnBLQViewClick(TObject *Sender); - void __fastcall BtnSnrMaskClick(TObject *Sender); - void __fastcall NavSys6Click(TObject *Sender); - void __fastcall ObsWeightChange(TObject *Sender); - void __fastcall BtnFreqClick(TObject *Sender); - void __fastcall BtnFont1Click(TObject *Sender); - void __fastcall RefAntClick(TObject *Sender); - void __fastcall RovAntClick(TObject *Sender); -private: - void __fastcall GetOpt(void); - void __fastcall SetOpt(void); - void __fastcall LoadOpt(AnsiString file); - void __fastcall SaveOpt(AnsiString file); - void __fastcall ReadAntList(void); - void __fastcall UpdateEnable(void); -public: - prcopt_t PrcOpt; - solopt_t SolOpt; - TFont *PanelFont,*PosFont; - int SvrCycle,SvrBuffSize,SolBuffSize,NavSelect,SavedSol; - int NmeaReq,NmeaCycle,TimeoutTime,ReconTime,DgpsCorr,SbasCorr; - int RovPosTypeF,RefPosTypeF,RovAntPcvF,RefAntPcvF,BaselineC; - int MoniPort,FileSwapMargin,PanelStack; - AnsiString ExSats,LocalDirectory; - AnsiString RovAntF,RefAntF,SatPcvFileF,AntPcvFileF,StaPosFileF; - AnsiString GeoidDataFileF,DCBFileF,EOPFileF,BLQFileF; - AnsiString ProxyAddr; - double RovAntDel[3],RefAntDel[3],RovPos[3],RefPos[3]; - double Baseline[2],NmeaIntv[2]; - __fastcall TOptDialog(TComponent* Owner); +class TOptDialog : public TForm { + __published : TButton *BtnCancel; + TButton *BtnOk; + TOpenDialog *OpenDialog; + TButton *BtnSave; + TButton *BtnLoad; + TSaveDialog *SaveDialog; + TPageControl *Options; + TTabSheet *TabSheet1; + TLabel *Label3; + TLabel *Label9; + TLabel *Label8; + TLabel *LabelPosMode; + TLabel *LabelFreq; + TLabel *LabelElMask; + TLabel *Label32; + TLabel *Label35; + TComboBox *DynamicModel; + TComboBox *IonoOpt; + TComboBox *TropOpt; + TComboBox *PosMode; + TComboBox *Freq; + TComboBox *SatEphem; + TEdit *ExSatsE; + TTabSheet *TabSheet2; + TLabel *Label25; + TLabel *Label24; + TLabel *Label13; + TLabel *LabelHold; + TLabel *Label22; + TLabel *Label14; + TLabel *Label11; + TLabel *Label37; + TComboBox *AmbRes; + TEdit *ValidThresAR; + TEdit *LockCntFixAmb; + TEdit *OutCntResetAmb; + TEdit *ElMaskAR; + TEdit *SlipThres; + TEdit *MaxAgeDiff; + TEdit *RejectPhase; + TEdit *NumIter; + TTabSheet *TabSheet3; + TLabel *LabelSolFormat; + TLabel *LabelTimeFormat; + TLabel *LabelLatLonFormat; + TLabel *LabelFieldSep; + TLabel *Label2; + TLabel *Label18; + TLabel *Label20; + TLabel *Label36; + TComboBox *SolFormat; + TComboBox *TimeFormat; + TComboBox *LatLonFormat; + TEdit *FieldSep; + TComboBox *OutputDatum; + TComboBox *OutputHeight; + TComboBox *OutputGeoid; + TComboBox *OutputHead; + TComboBox *OutputOpt; + TComboBox *DebugTrace; + TTabSheet *TabSheet4; + TLabel *Label29; + TGroupBox *GroupBox3; + TLabel *Label6; + TLabel *Label7; + TLabel *Label16; + TEdit *MeasErrR1; + TEdit *MeasErr2; + TEdit *MeasErr3; + TEdit *MeasErr4; + TGroupBox *GroupBox4; + TLabel *Label26; + TLabel *Label27; + TLabel *Label28; + TEdit *PrNoise1; + TEdit *PrNoise2; + TEdit *PrNoise3; + TEdit *SatClkStab; + TTabSheet *TabSheet5; + TGroupBox *GroupRovAnt; + TLabel *LabelRovAntD; + TEdit *RovAntE; + TEdit *RovAntN; + TEdit *RovAntU; + TEdit *RovPos1; + TEdit *RovPos2; + TEdit *RovPos3; + TButton *BtnRovPos; + TCheckBox *RovAntPcv; + TComboBox *RovAnt; + TComboBox *RovPosTypeP; + TGroupBox *GroupRefAnt; + TLabel *LabelRefAntD; + TEdit *RefAntE; + TEdit *RefAntN; + TEdit *RefAntU; + TEdit *RefPos1; + TEdit *RefPos2; + TEdit *RefPos3; + TButton *BtnRefPos; + TCheckBox *RefAntPcv; + TComboBox *RefAnt; + TComboBox *RefPosTypeP; + TTabSheet *TabSheet7; + TLabel *Label1; + TSpeedButton *BtnAntPcvView; + TLabel *Label38; + TSpeedButton *BtnSatPcvView; + TEdit *AntPcvFile; + TButton *BtnAntPcvFile; + TButton *BtnDCBFile; + TEdit *DCBFile; + TEdit *SatPcvFile; + TButton *BtnSatPcvFile; + TTabSheet *TabSheet8; + TLabel *Label19; + TEdit *SvrCycleE; + TEdit *SvrBuffSizeE; + TLabel *Label40; + TButton *BtnFont2; + TLabel *FontLabel2; + TFontDialog *FontDialog; + TLabel *Label41; + TEdit *SolBuffSizeE; + TLabel *Label42; + TComboBox *NavSelectS; + TEdit *SbasSatE; + TLabel *Label5; + TEdit *SavedSolE; + TEdit *NmeaCycleE; + TCheckBox *NavSys2; + TCheckBox *NavSys3; + TCheckBox *NavSys4; + TCheckBox *NavSys1; + TLabel *Label46; + TLabel *Label44; + TEdit *TimeoutTimeE; + TEdit *ReconTimeE; + TCheckBox *NavSys5; + TComboBox *GloAmbRes; + TCheckBox *BaselineConst; + TEdit *BaselineLen; + TEdit *BaselineSig; + TEdit *TimeDecimal; + TComboBox *DebugStatus; + TLabel *Label10; + TLabel *Label33; + TEdit *PrNoise4; + TEdit *PrNoise5; + TLabel *Label48; + TEdit *GeoidDataFile; + TButton *BtnGeoidDataFile; + TLabel *Label17; + TEdit *NmeaIntv1; + TEdit *NmeaIntv2; + TLabel *Label31; + TEdit *LocalDir; + TButton *BtnLocalDir; + TComboBox *TideCorr; + TEdit *FixCntHoldAmb; + TEdit *MoniPortE; + TCheckBox *NavSys6; + TSpeedButton *BtnDCBView; + TLabel *Label21; + TComboBox *SolStatic; + TEdit *StaPosFile; + TLabel *Label30; + TSpeedButton *BtnStaPosView; + TButton *BtnStaPosFile; + TLabel *Label34; + TEdit *BLQFile; + TSpeedButton *BtnBLQFileView; + TButton *BtnBLQFile; + TEdit *MeasErrR2; + TEdit *ElMaskHold; + TEdit *FileSwapMarginE; + TEdit *RejectCode; + TLabel *Label45; + TEdit *ProxyAddrE; + TLabel *Label23; + TEdit *EOPFile; + TButton *BtnEOPFile; + TSpeedButton *BtnEOPView; + TComboBox *ElMask; + TCheckBox *PosOpt1; + TCheckBox *PosOpt2; + TCheckBox *PosOpt3; + TCheckBox *PosOpt4; + TCheckBox *PosOpt5; + TButton *BtnSnrMask; + TComboBox *SyncSol; + TLabel *Label43; + TComboBox *PanelStackE; + TComboBox *BdsAmbRes; + TCheckBox *PosOpt6; + TLabel *LabelMaxAveEp; + TEdit *MaxAveEp; + TCheckBox *ChkInitRestart; + TCheckBox *NavSys7; + TComboBox *OutputSingle; + TEdit *MaxSolStd; + TComboBox *OutputVel; + TSpeedButton *BtnFreq; + TLabel *Label49; + TLabel *FontLabel1; + TButton *BtnFont1; + TEdit *MinFixSats; + TEdit *MinHoldSats; + TComboBox *ARFilter; + TEdit *MaxPosVarAR; + TLabel *Label50; + TEdit *MinDropSats; + TEdit *VarHoldAmb; + TEdit *GainHoldAmb; + TLabel *Label51; + TLabel *Label52; + TEdit *GloHwBias; + TEdit *MeasErr7; + TEdit *ARIter; + TLabel *Label15; + TEdit *ValidThresARMin; + TEdit *ValidThresARMax; + TEdit *DopThres; + TEdit *MeasErrR5; + TEdit *MeasErrR6; + TLabel *Label12; + TEdit *MeasErr6; + TEdit *MeasErr8; + TEdit *MeasErr5; + TLabel *Label53; + void __fastcall BtnOkClick(TObject *Sender); + void __fastcall RovAntPcvClick(TObject *Sender); + void __fastcall FormShow(TObject *Sender); + void __fastcall BtnAntPcvFileClick(TObject *Sender); + void __fastcall BtnDCBFileClick(TObject *Sender); + void __fastcall BtnDCBViewClick(TObject *Sender); + void __fastcall BtnAntPcvViewClick(TObject *Sender); + void __fastcall AmbResChange(TObject *Sender); + void __fastcall SatClkCorrClick(TObject *Sender); + void __fastcall PosModeChange(TObject *Sender); + void __fastcall SolFormatChange(TObject *Sender); + void __fastcall BtnLoadClick(TObject *Sender); + void __fastcall BtnSaveClick(TObject *Sender); + void __fastcall IntpRefObsClick(TObject *Sender); + void __fastcall FreqChange(TObject *Sender); + void __fastcall BtnRefPosClick(TObject *Sender); + void __fastcall BtnRovPosClick(TObject *Sender); + void __fastcall RovPosClick(TObject *Sender); + void __fastcall RefPosClick(TObject *Sender); + void __fastcall BtnStaPosViewClick(TObject *Sender); + void __fastcall BtnStaPosFileClick(TObject *Sender); + void __fastcall OutputHeightClick(TObject *Sender); + void __fastcall RefPosTypePChange(TObject *Sender); + void __fastcall RovPosTypePChange(TObject *Sender); + void __fastcall GetPos(int type, TEdit **edit, double *pos); + void __fastcall SetPos(int type, TEdit **edit, double *pos); + void __fastcall BtnFont2Click(TObject *Sender); + void __fastcall NmeaReqCClick(TObject *Sender); + void __fastcall DgpsCorrLChange(TObject *Sender); + void __fastcall BtnGeoidDataFileClick(TObject *Sender); + void __fastcall NavSys2Click(TObject *Sender); + void __fastcall BaselineConstClick(TObject *Sender); + void __fastcall BtnSatPcvViewClick(TObject *Sender); + void __fastcall BtnSatPcvFileClick(TObject *Sender); + void __fastcall BtnLocalDirClick(TObject *Sender); + void __fastcall BtnEOPFileClick(TObject *Sender); + void __fastcall BtnEOPViewClick(TObject *Sender); + void __fastcall BtnBLQFileClick(TObject *Sender); + void __fastcall BtnBLQViewClick(TObject *Sender); + void __fastcall BtnSnrMaskClick(TObject *Sender); + void __fastcall NavSys6Click(TObject *Sender); + void __fastcall ObsWeightChange(TObject *Sender); + void __fastcall BtnFreqClick(TObject *Sender); + void __fastcall BtnFont1Click(TObject *Sender); + void __fastcall RefAntClick(TObject *Sender); + void __fastcall RovAntClick(TObject *Sender); + + private: + void __fastcall GetOpt(void); + void __fastcall SetOpt(void); + void __fastcall LoadOpt(AnsiString file); + void __fastcall SaveOpt(AnsiString file); + void __fastcall ReadAntList(void); + void __fastcall UpdateEnable(void); + + public: + prcopt_t PrcOpt; + solopt_t SolOpt; + TFont *PanelFont, *PosFont; + int SvrCycle, SvrBuffSize, SolBuffSize, NavSelect, SavedSol; + int NmeaReq, NmeaCycle, TimeoutTime, ReconTime, DgpsCorr, SbasCorr; + int RovPosTypeF, RefPosTypeF, RovAntPcvF, RefAntPcvF, BaselineC; + int MoniPort, FileSwapMargin, PanelStack; + AnsiString ExSats, LocalDirectory; + AnsiString RovAntF, RefAntF, SatPcvFileF, AntPcvFileF, StaPosFileF; + AnsiString GeoidDataFileF, DCBFileF, EOPFileF, BLQFileF; + AnsiString ProxyAddr; + double RovAntDel[3], RefAntDel[3], RovPos[3], RefPos[3]; + double Baseline[2], NmeaIntv[2]; + __fastcall TOptDialog(TComponent *Owner); }; //--------------------------------------------------------------------------- extern PACKAGE TOptDialog *OptDialog; diff --git a/app/winapp/rtknavi/outstrdlg.cpp b/app/winapp/rtknavi/outstrdlg.cpp index d986fcad5..79cd0d079 100644 --- a/app/winapp/rtknavi/outstrdlg.cpp +++ b/app/winapp/rtknavi/outstrdlg.cpp @@ -2,173 +2,164 @@ #include #pragma hdrstop -#include "rtklib.h" -#include "serioptdlg.h" +#include "outstrdlg.h" + #include "cmdoptdlg.h" #include "fileoptdlg.h" -#include "tcpoptdlg.h" -#include "outstrdlg.h" #include "keydlg.h" +#include "rtklib.h" +#include "serioptdlg.h" +#include "tcpoptdlg.h" //--------------------------------------------------------------------------- #pragma package(smart_init) #pragma resource "*.dfm" TOutputStrDialog *OutputStrDialog; //--------------------------------------------------------------------------- -__fastcall TOutputStrDialog::TOutputStrDialog(TComponent* Owner) - : TForm(Owner) -{ -} -//--------------------------------------------------------------------------- -void __fastcall TOutputStrDialog::FormShow(TObject *Sender) -{ - Stream1C ->Checked =StreamC[0]; - Stream2C ->Checked =StreamC[1]; - Stream1 ->ItemIndex=Stream[0]; - Stream2 ->ItemIndex=Stream[1]; - Format1 ->ItemIndex=Format[0]; - Format2 ->ItemIndex=Format[1]; - FilePath1->Text =GetFilePath(Paths[0][2]); - FilePath2->Text =GetFilePath(Paths[1][2]); - SwapIntv->Text =SwapInterval; - TimeTagC ->Checked =OutTimeTag; - UpdateEnable(); -} -//--------------------------------------------------------------------------- -void __fastcall TOutputStrDialog::BtnOkClick(TObject *Sender) -{ - StreamC[0] =Stream1C->Checked; - StreamC[1] =Stream2C->Checked; - Stream[0] =Stream1->ItemIndex; - Stream[1] =Stream2->ItemIndex; - Format[0] =Format1->ItemIndex; - Format[1] =Format2->ItemIndex; - Paths [0][2]=SetFilePath(FilePath1->Text); - Paths [1][2]=SetFilePath(FilePath2->Text); - SwapInterval=SwapIntv->Text; - OutTimeTag =TimeTagC->Checked; -} -//--------------------------------------------------------------------------- -void __fastcall TOutputStrDialog::BtnFile1Click(TObject *Sender) -{ - SaveDialog->FileName=FilePath1->Text; - if (!SaveDialog->Execute()) return; - FilePath1->Text=SaveDialog->FileName; -} -//--------------------------------------------------------------------------- -void __fastcall TOutputStrDialog::BtnFile2Click(TObject *Sender) -{ - SaveDialog->FileName=FilePath2->Text; - if (!SaveDialog->Execute()) return; - FilePath2->Text=SaveDialog->FileName; -} -//--------------------------------------------------------------------------- -void __fastcall TOutputStrDialog::Stream1Change(TObject *Sender) -{ - UpdateEnable(); -} -//--------------------------------------------------------------------------- -void __fastcall TOutputStrDialog::Stream2Change(TObject *Sender) -{ - UpdateEnable(); +__fastcall TOutputStrDialog::TOutputStrDialog(TComponent *Owner) : TForm(Owner) {} +//--------------------------------------------------------------------------- +void __fastcall TOutputStrDialog::FormShow(TObject *Sender) { + Stream1C->Checked = StreamC[0]; + Stream2C->Checked = StreamC[1]; + Stream1->ItemIndex = Stream[0]; + Stream2->ItemIndex = Stream[1]; + Format1->ItemIndex = Format[0]; + Format2->ItemIndex = Format[1]; + FilePath1->Text = GetFilePath(Paths[0][2]); + FilePath2->Text = GetFilePath(Paths[1][2]); + SwapIntv->Text = SwapInterval; + TimeTagC->Checked = OutTimeTag; + UpdateEnable(); +} +//--------------------------------------------------------------------------- +void __fastcall TOutputStrDialog::BtnOkClick(TObject *Sender) { + StreamC[0] = Stream1C->Checked; + StreamC[1] = Stream2C->Checked; + Stream[0] = Stream1->ItemIndex; + Stream[1] = Stream2->ItemIndex; + Format[0] = Format1->ItemIndex; + Format[1] = Format2->ItemIndex; + Paths[0][2] = SetFilePath(FilePath1->Text); + Paths[1][2] = SetFilePath(FilePath2->Text); + SwapInterval = SwapIntv->Text; + OutTimeTag = TimeTagC->Checked; +} +//--------------------------------------------------------------------------- +void __fastcall TOutputStrDialog::BtnFile1Click(TObject *Sender) { + SaveDialog->FileName = FilePath1->Text; + if (!SaveDialog->Execute()) return; + FilePath1->Text = SaveDialog->FileName; +} +//--------------------------------------------------------------------------- +void __fastcall TOutputStrDialog::BtnFile2Click(TObject *Sender) { + SaveDialog->FileName = FilePath2->Text; + if (!SaveDialog->Execute()) return; + FilePath2->Text = SaveDialog->FileName; +} +//--------------------------------------------------------------------------- +void __fastcall TOutputStrDialog::Stream1Change(TObject *Sender) { UpdateEnable(); } +//--------------------------------------------------------------------------- +void __fastcall TOutputStrDialog::Stream2Change(TObject *Sender) { UpdateEnable(); } +//--------------------------------------------------------------------------- +void __fastcall TOutputStrDialog::Stream1CClick(TObject *Sender) { UpdateEnable(); } +//--------------------------------------------------------------------------- +void __fastcall TOutputStrDialog::Stream2CClick(TObject *Sender) { UpdateEnable(); } +//--------------------------------------------------------------------------- +void __fastcall TOutputStrDialog::BtnKeyClick(TObject *Sender) { KeyDialog->ShowModal(); } +//--------------------------------------------------------------------------- +void __fastcall TOutputStrDialog::BtnStr1Click(TObject *Sender) { + switch (Stream1->ItemIndex) { + case 0: + SerialOpt(0, 0); + break; + case 1: + TcpOpt(0, 1); + break; + case 2: + TcpOpt(0, 0); + break; + case 3: + TcpOpt(0, 2); + break; + case 4: + TcpOpt(0, 4); + break; + } +} +//--------------------------------------------------------------------------- +void __fastcall TOutputStrDialog::BtnStr2Click(TObject *Sender) { + switch (Stream2->ItemIndex) { + case 0: + SerialOpt(1, 0); + break; + case 1: + TcpOpt(1, 1); + break; + case 2: + TcpOpt(1, 0); + break; + case 3: + TcpOpt(1, 2); + break; + case 4: + TcpOpt(1, 4); + break; + } +} +//--------------------------------------------------------------------------- +AnsiString __fastcall TOutputStrDialog::GetFilePath(AnsiString path) { + char *p, *q, buff[1024]; + strcpy(buff, path.c_str()); + if ((p = strstr(buff, "::"))) *p = '\0'; + return (path = buff); +} +//--------------------------------------------------------------------------- +AnsiString __fastcall TOutputStrDialog::SetFilePath(AnsiString path) { + AnsiString str; + double swap; + if (TimeTagC->Checked) path += "::T"; + str = SwapIntv->Text; + if (sscanf(str.c_str(), "%lf", &swap) >= 1) { + path += "::S=" + str; + } + return path; +} +//--------------------------------------------------------------------------- +void __fastcall TOutputStrDialog::SerialOpt(int index, int opt) { + SerialOptDialog->Path = Paths[index][0]; + SerialOptDialog->Opt = opt; + if (SerialOptDialog->ShowModal() != mrOk) return; + Paths[index][0] = SerialOptDialog->Path; +} +//--------------------------------------------------------------------------- +void __fastcall TOutputStrDialog::TcpOpt(int index, int opt) { + TcpOptDialog->Path = Paths[index][1]; + TcpOptDialog->Opt = opt; + for (int i = 0; i < 10; i++) { + TcpOptDialog->History[i] = History[i]; + } + if (TcpOptDialog->ShowModal() != mrOk) return; + Paths[index][1] = TcpOptDialog->Path; + for (int i = 0; i < 10; i++) { + History[i] = TcpOptDialog->History[i]; + } +} +//--------------------------------------------------------------------------- +void __fastcall TOutputStrDialog::UpdateEnable(void) { + int ena = (Stream1C->Checked && Stream1->ItemIndex == 5) || + (Stream2C->Checked && Stream2->ItemIndex == 5); + Stream1->Enabled = Stream1C->Checked; + Stream2->Enabled = Stream2C->Checked; + BtnStr1->Enabled = Stream1C->Checked && Stream1->ItemIndex <= 4; + BtnStr2->Enabled = Stream2C->Checked && Stream2->ItemIndex <= 4; + FilePath1->Enabled = Stream1C->Checked && Stream1->ItemIndex == 5; + FilePath2->Enabled = Stream2C->Checked && Stream2->ItemIndex == 5; + BtnFile1->Enabled = Stream1C->Checked && Stream1->ItemIndex == 5; + BtnFile2->Enabled = Stream2C->Checked && Stream2->ItemIndex == 5; + LabelF1->Enabled = ena; + Label1->Enabled = ena; + Label2->Enabled = ena; + TimeTagC->Enabled = ena; + SwapIntv->Enabled = ena; + BtnKey->Enabled = ena; } //--------------------------------------------------------------------------- -void __fastcall TOutputStrDialog::Stream1CClick(TObject *Sender) -{ - UpdateEnable(); -} -//--------------------------------------------------------------------------- -void __fastcall TOutputStrDialog::Stream2CClick(TObject *Sender) -{ - UpdateEnable(); -} -//--------------------------------------------------------------------------- -void __fastcall TOutputStrDialog::BtnKeyClick(TObject *Sender) -{ - KeyDialog->ShowModal(); -} -//--------------------------------------------------------------------------- -void __fastcall TOutputStrDialog::BtnStr1Click(TObject *Sender) -{ - switch (Stream1->ItemIndex) { - case 0: SerialOpt(0,0); break; - case 1: TcpOpt(0,1); break; - case 2: TcpOpt(0,0); break; - case 3: TcpOpt(0,2); break; - case 4: TcpOpt(0,4); break; - } -} -//--------------------------------------------------------------------------- -void __fastcall TOutputStrDialog::BtnStr2Click(TObject *Sender) -{ - switch (Stream2->ItemIndex) { - case 0: SerialOpt(1,0); break; - case 1: TcpOpt(1,1); break; - case 2: TcpOpt(1,0); break; - case 3: TcpOpt(1,2); break; - case 4: TcpOpt(1,4); break; - } -} -//--------------------------------------------------------------------------- -AnsiString __fastcall TOutputStrDialog::GetFilePath(AnsiString path) -{ - char *p,*q,buff[1024]; - strcpy(buff,path.c_str()); - if ((p=strstr(buff,"::"))) *p='\0'; - return (path=buff); -} -//--------------------------------------------------------------------------- -AnsiString __fastcall TOutputStrDialog::SetFilePath(AnsiString path) -{ - AnsiString str; - double swap; - if (TimeTagC->Checked) path+="::T"; - str=SwapIntv->Text; - if (sscanf(str.c_str(),"%lf",&swap)>=1) { - path+="::S="+str; - } - return path; -} -//--------------------------------------------------------------------------- -void __fastcall TOutputStrDialog::SerialOpt(int index, int opt) -{ - SerialOptDialog->Path=Paths[index][0]; - SerialOptDialog->Opt=opt; - if (SerialOptDialog->ShowModal()!=mrOk) return; - Paths[index][0]=SerialOptDialog->Path; -} -//--------------------------------------------------------------------------- -void __fastcall TOutputStrDialog::TcpOpt(int index, int opt) -{ - TcpOptDialog->Path=Paths[index][1]; - TcpOptDialog->Opt=opt; - for (int i=0;i<10;i++) { - TcpOptDialog->History[i]=History[i]; - } - if (TcpOptDialog->ShowModal()!=mrOk) return; - Paths[index][1]=TcpOptDialog->Path; - for (int i=0;i<10;i++) { - History[i]=TcpOptDialog->History[i]; - } -} -//--------------------------------------------------------------------------- -void __fastcall TOutputStrDialog::UpdateEnable(void) -{ - int ena=(Stream1C->Checked&&Stream1->ItemIndex==5)|| - (Stream2C->Checked&&Stream2->ItemIndex==5); - Stream1 ->Enabled=Stream1C->Checked; - Stream2 ->Enabled=Stream2C->Checked; - BtnStr1 ->Enabled=Stream1C->Checked&&Stream1->ItemIndex<=4; - BtnStr2 ->Enabled=Stream2C->Checked&&Stream2->ItemIndex<=4; - FilePath1->Enabled=Stream1C->Checked&&Stream1->ItemIndex==5; - FilePath2->Enabled=Stream2C->Checked&&Stream2->ItemIndex==5; - BtnFile1 ->Enabled=Stream1C->Checked&&Stream1->ItemIndex==5; - BtnFile2 ->Enabled=Stream2C->Checked&&Stream2->ItemIndex==5; - LabelF1 ->Enabled=ena; - Label1 ->Enabled=ena; - Label2 ->Enabled=ena; - TimeTagC ->Enabled=ena; - SwapIntv ->Enabled=ena; - BtnKey ->Enabled=ena; -} -//--------------------------------------------------------------------------- - diff --git a/app/winapp/rtknavi/outstrdlg.h b/app/winapp/rtknavi/outstrdlg.h index 31f6cc729..9958c0284 100644 --- a/app/winapp/rtknavi/outstrdlg.h +++ b/app/winapp/rtknavi/outstrdlg.h @@ -2,63 +2,63 @@ #ifndef outstrdlgH #define outstrdlgH //--------------------------------------------------------------------------- +#include #include #include -#include -#include #include -#include +#include +#include //--------------------------------------------------------------------------- -class TOutputStrDialog : public TForm -{ -__published: - TButton *BtnCancel; - TButton *BtnOk; - TLabel *Label5; - TLabel *Label6; - TComboBox *Stream1; - TButton *BtnStr1; - TButton *BtnStr2; - TComboBox *Stream2; - TLabel *Label10; - TLabel *Label7; - TComboBox *Format1; - TComboBox *Format2; - TButton *BtnFile1; - TEdit *FilePath1; - TEdit *FilePath2; - TButton *BtnFile2; - TLabel *LabelF1; - TSaveDialog *SaveDialog; - TCheckBox *TimeTagC; - TCheckBox *Stream1C; - TCheckBox *Stream2C; - TSpeedButton *BtnKey; - TLabel *Label1; - TComboBox *SwapIntv; - TLabel *Label2; - void __fastcall BtnOkClick(TObject *Sender); - void __fastcall FormShow(TObject *Sender); - void __fastcall BtnStr1Click(TObject *Sender); - void __fastcall BtnStr2Click(TObject *Sender); - void __fastcall Stream1Change(TObject *Sender); - void __fastcall Stream2Change(TObject *Sender); - void __fastcall BtnFile1Click(TObject *Sender); - void __fastcall BtnFile2Click(TObject *Sender); - void __fastcall Stream1CClick(TObject *Sender); - void __fastcall Stream2CClick(TObject *Sender); - void __fastcall BtnKeyClick(TObject *Sender); -private: - AnsiString __fastcall GetFilePath(AnsiString path); - AnsiString __fastcall SetFilePath(AnsiString path); - void __fastcall SerialOpt(int index, int opt); - void __fastcall TcpOpt(int index, int opt); - void __fastcall UpdateEnable(void); -public: - int StreamC[2],Stream[2],Format[2],OutTimeTag,OutAppend; - AnsiString Paths[2][4],SwapInterval; - AnsiString History[10]; - __fastcall TOutputStrDialog(TComponent* Owner); +class TOutputStrDialog : public TForm { + __published : TButton *BtnCancel; + TButton *BtnOk; + TLabel *Label5; + TLabel *Label6; + TComboBox *Stream1; + TButton *BtnStr1; + TButton *BtnStr2; + TComboBox *Stream2; + TLabel *Label10; + TLabel *Label7; + TComboBox *Format1; + TComboBox *Format2; + TButton *BtnFile1; + TEdit *FilePath1; + TEdit *FilePath2; + TButton *BtnFile2; + TLabel *LabelF1; + TSaveDialog *SaveDialog; + TCheckBox *TimeTagC; + TCheckBox *Stream1C; + TCheckBox *Stream2C; + TSpeedButton *BtnKey; + TLabel *Label1; + TComboBox *SwapIntv; + TLabel *Label2; + void __fastcall BtnOkClick(TObject *Sender); + void __fastcall FormShow(TObject *Sender); + void __fastcall BtnStr1Click(TObject *Sender); + void __fastcall BtnStr2Click(TObject *Sender); + void __fastcall Stream1Change(TObject *Sender); + void __fastcall Stream2Change(TObject *Sender); + void __fastcall BtnFile1Click(TObject *Sender); + void __fastcall BtnFile2Click(TObject *Sender); + void __fastcall Stream1CClick(TObject *Sender); + void __fastcall Stream2CClick(TObject *Sender); + void __fastcall BtnKeyClick(TObject *Sender); + + private: + AnsiString __fastcall GetFilePath(AnsiString path); + AnsiString __fastcall SetFilePath(AnsiString path); + void __fastcall SerialOpt(int index, int opt); + void __fastcall TcpOpt(int index, int opt); + void __fastcall UpdateEnable(void); + + public: + int StreamC[2], Stream[2], Format[2], OutTimeTag, OutAppend; + AnsiString Paths[2][4], SwapInterval; + AnsiString History[10]; + __fastcall TOutputStrDialog(TComponent *Owner); }; //--------------------------------------------------------------------------- extern PACKAGE TOutputStrDialog *OutputStrDialog; diff --git a/app/winapp/rtknavi/rcvoptdlg.cpp b/app/winapp/rtknavi/rcvoptdlg.cpp index 16dc32c92..935627c20 100644 --- a/app/winapp/rtknavi/rcvoptdlg.cpp +++ b/app/winapp/rtknavi/rcvoptdlg.cpp @@ -8,18 +8,9 @@ #pragma resource "*.dfm" TRcvOptDialog *RcvOptDialog; //--------------------------------------------------------------------------- -__fastcall TRcvOptDialog::TRcvOptDialog(TComponent* Owner) - : TForm(Owner) -{ -} +__fastcall TRcvOptDialog::TRcvOptDialog(TComponent *Owner) : TForm(Owner) {} //--------------------------------------------------------------------------- -void __fastcall TRcvOptDialog::FormShow(TObject *Sender) -{ - OptionE->Text=Option; -} +void __fastcall TRcvOptDialog::FormShow(TObject *Sender) { OptionE->Text = Option; } //--------------------------------------------------------------------------- -void __fastcall TRcvOptDialog::BtnOkClick(TObject *Sender) -{ - Option=OptionE->Text; -} +void __fastcall TRcvOptDialog::BtnOkClick(TObject *Sender) { Option = OptionE->Text; } //--------------------------------------------------------------------------- diff --git a/app/winapp/rtknavi/rcvoptdlg.h b/app/winapp/rtknavi/rcvoptdlg.h index 78d1e2ca2..71af39b11 100644 --- a/app/winapp/rtknavi/rcvoptdlg.h +++ b/app/winapp/rtknavi/rcvoptdlg.h @@ -4,21 +4,20 @@ //--------------------------------------------------------------------------- #include #include -#include #include +#include //--------------------------------------------------------------------------- -class TRcvOptDialog : public TForm -{ -__published: - TButton *BtnOk; - TButton *BnCancel; - TEdit *OptionE; - void __fastcall FormShow(TObject *Sender); - void __fastcall BtnOkClick(TObject *Sender); -private: -public: - AnsiString Option; - __fastcall TRcvOptDialog(TComponent* Owner); +class TRcvOptDialog : public TForm { + __published : TButton *BtnOk; + TButton *BnCancel; + TEdit *OptionE; + void __fastcall FormShow(TObject *Sender); + void __fastcall BtnOkClick(TObject *Sender); + + private: + public: + AnsiString Option; + __fastcall TRcvOptDialog(TComponent *Owner); }; //--------------------------------------------------------------------------- extern PACKAGE TRcvOptDialog *RcvOptDialog; diff --git a/app/winapp/rtknavi/rtknavi.cpp b/app/winapp/rtknavi/rtknavi.cpp index 265956625..771f06152 100644 --- a/app/winapp/rtknavi/rtknavi.cpp +++ b/app/winapp/rtknavi/rtknavi.cpp @@ -4,31 +4,6 @@ #pragma hdrstop //--------------------------------------------------------------------------- - - - - - - - - - - - - - - - - - - - - - - - - - #include #include USEFORM("..\appcmn\refdlg.cpp", RefDialog); @@ -54,50 +29,41 @@ USEFORM("outstrdlg.cpp", OutputStrDialog); USEFORM("naviopt.cpp", OptDialog); USEFORM("navimain.cpp", MainForm); //--------------------------------------------------------------------------- -int WINAPI WinMain(HINSTANCE, HINSTANCE, LPSTR, int) -{ - try - { - Application->Initialize(); - Application->Title = "RTKNAVI"; - Application->CreateForm(__classid(TMainForm), &MainForm); - Application->CreateForm(__classid(TSerialOptDialog), &SerialOptDialog); - Application->CreateForm(__classid(TFtpOptDialog), &FtpOptDialog); - Application->CreateForm(__classid(TFileOptDialog), &FileOptDialog); - Application->CreateForm(__classid(TAboutDialog), &AboutDialog); - Application->CreateForm(__classid(TViewerOptDialog), &ViewerOptDialog); - Application->CreateForm(__classid(TTextViewer), &TextViewer); - Application->CreateForm(__classid(TTcpOptDialog), &TcpOptDialog); - Application->CreateForm(__classid(TRefDialog), &RefDialog); - Application->CreateForm(__classid(TMaskOptDialog), &MaskOptDialog); - Application->CreateForm(__classid(TKeyDialog), &KeyDialog); - Application->CreateForm(__classid(TConfDialog), &ConfDialog); - Application->CreateForm(__classid(TCmdOptDialog), &CmdOptDialog); - Application->CreateForm(__classid(TMntpOptDialog), &MntpOptDialog); - Application->CreateForm(__classid(TOptDialog), &OptDialog); - Application->CreateForm(__classid(TOutputStrDialog), &OutputStrDialog); - Application->CreateForm(__classid(TLogStrDialog), &LogStrDialog); - Application->CreateForm(__classid(TInputStrDialog), &InputStrDialog); - Application->CreateForm(__classid(TRcvOptDialog), &RcvOptDialog); - Application->CreateForm(__classid(TMarkDialog), &MarkDialog); - Application->CreateForm(__classid(TFreqDialog), &FreqDialog); - Application->Run(); - } - catch (Exception &exception) - { - Application->ShowException(&exception); - } - catch (...) - { - try - { - throw Exception(""); - } - catch (Exception &exception) - { - Application->ShowException(&exception); - } - } - return 0; +int WINAPI WinMain(HINSTANCE, HINSTANCE, LPSTR, int) { + try { + Application->Initialize(); + Application->Title = "RTKNAVI"; + Application->CreateForm(__classid(TMainForm), &MainForm); + Application->CreateForm(__classid(TSerialOptDialog), &SerialOptDialog); + Application->CreateForm(__classid(TFtpOptDialog), &FtpOptDialog); + Application->CreateForm(__classid(TFileOptDialog), &FileOptDialog); + Application->CreateForm(__classid(TAboutDialog), &AboutDialog); + Application->CreateForm(__classid(TViewerOptDialog), &ViewerOptDialog); + Application->CreateForm(__classid(TTextViewer), &TextViewer); + Application->CreateForm(__classid(TTcpOptDialog), &TcpOptDialog); + Application->CreateForm(__classid(TRefDialog), &RefDialog); + Application->CreateForm(__classid(TMaskOptDialog), &MaskOptDialog); + Application->CreateForm(__classid(TKeyDialog), &KeyDialog); + Application->CreateForm(__classid(TConfDialog), &ConfDialog); + Application->CreateForm(__classid(TCmdOptDialog), &CmdOptDialog); + Application->CreateForm(__classid(TMntpOptDialog), &MntpOptDialog); + Application->CreateForm(__classid(TOptDialog), &OptDialog); + Application->CreateForm(__classid(TOutputStrDialog), &OutputStrDialog); + Application->CreateForm(__classid(TLogStrDialog), &LogStrDialog); + Application->CreateForm(__classid(TInputStrDialog), &InputStrDialog); + Application->CreateForm(__classid(TRcvOptDialog), &RcvOptDialog); + Application->CreateForm(__classid(TMarkDialog), &MarkDialog); + Application->CreateForm(__classid(TFreqDialog), &FreqDialog); + Application->Run(); + } catch (Exception &exception) { + Application->ShowException(&exception); + } catch (...) { + try { + throw Exception(""); + } catch (Exception &exception) { + Application->ShowException(&exception); + } + } + return 0; } //--------------------------------------------------------------------------- diff --git a/app/winapp/rtkplot/conndlg.cpp b/app/winapp/rtkplot/conndlg.cpp index 501c69294..7bd07310a 100644 --- a/app/winapp/rtkplot/conndlg.cpp +++ b/app/winapp/rtkplot/conndlg.cpp @@ -2,196 +2,189 @@ #include #pragma hdrstop +#include "conndlg.h" + +#include "cmdoptdlg.h" +#include "fileoptdlg.h" #include "rtklib.h" #include "serioptdlg.h" -#include "fileoptdlg.h" #include "tcpoptdlg.h" -#include "cmdoptdlg.h" -#include "conndlg.h" //--------------------------------------------------------------------------- #pragma package(smart_init) #pragma resource "*.dfm" TConnectDialog *ConnectDialog; //--------------------------------------------------------------------------- -__fastcall TConnectDialog::TConnectDialog(TComponent* Owner) - : TForm(Owner) -{ - Stream1=Stream2=Format1=Format2=0; - CmdEna1[0]=CmdEna1[1]=CmdEna2[0]=CmdEna2[1]=0; -} -//--------------------------------------------------------------------------- -void __fastcall TConnectDialog::FormShow(TObject *Sender) -{ - AnsiString s; - int str[]={STR_NONE,STR_SERIAL,STR_TCPCLI,STR_TCPSVR,STR_NTRIPCLI,STR_FILE}; - for (int i=0;i<6;i++) { - if (str[i]==Stream1) SelStream1->ItemIndex=i; - if (str[i]==Stream2) SelStream2->ItemIndex=i; - } - SolFormat1->ItemIndex=Format1; - SolFormat2->ItemIndex=Format2; - TimeFormS->ItemIndex=TimeForm; - DegFormS ->ItemIndex=DegForm; - FieldSepS->Text =FieldSep; - TimeOutTimeE->Text=s.sprintf("%d",TimeOutTime); - ReConnTimeE ->Text=s.sprintf("%d",ReConnTime); - UpdateEnable(); -} -//--------------------------------------------------------------------------- -void __fastcall TConnectDialog::BtnOkClick(TObject *Sender) -{ - int str[]={STR_NONE,STR_SERIAL,STR_TCPCLI,STR_TCPSVR,STR_NTRIPCLI,STR_FILE}; - Stream1=str[SelStream1->ItemIndex]; - Stream2=str[SelStream2->ItemIndex]; - Format1=SolFormat1->ItemIndex; - Format2=SolFormat2->ItemIndex; - TimeForm=TimeFormS->ItemIndex; - DegForm =DegFormS ->ItemIndex; - FieldSep=FieldSepS->Text; - TimeOutTime=TimeOutTimeE->Text.ToInt(); - ReConnTime =ReConnTimeE ->Text.ToInt(); -} -//--------------------------------------------------------------------------- -void __fastcall TConnectDialog::BtnOpt1Click(TObject *Sender) -{ - switch (SelStream1->ItemIndex) { - case 1: SerialOpt1(0); break; - case 2: TcpOpt1 (1); break; - case 3: TcpOpt1 (0); break; - case 4: TcpOpt1 (3); break; - case 5: FileOpt1(0); break; - } -} -//--------------------------------------------------------------------------- -void __fastcall TConnectDialog::BtnOpt2Click(TObject *Sender) -{ - switch (SelStream2->ItemIndex) { - case 1: SerialOpt2(0); break; - case 2: TcpOpt2 (1); break; - case 3: TcpOpt2 (0); break; - case 4: TcpOpt2 (3); break; - case 5: FileOpt2(0); break; - } -} -//--------------------------------------------------------------------------- -void __fastcall TConnectDialog::BtnCmd1Click(TObject *Sender) -{ - CmdOptDialog->Cmds [0]=Cmds1 [0]; - CmdOptDialog->Cmds [1]=Cmds1 [1]; - CmdOptDialog->CmdEna[0]=CmdEna1[0]; - CmdOptDialog->CmdEna[1]=CmdEna1[1]; - if (CmdOptDialog->ShowModal()!=mrOk) return; - Cmds1 [0]=CmdOptDialog->Cmds [0]; - Cmds1 [1]=CmdOptDialog->Cmds [1]; - CmdEna1[0]=CmdOptDialog->CmdEna[0]; - CmdEna1[1]=CmdOptDialog->CmdEna[1]; -} -//--------------------------------------------------------------------------- -void __fastcall TConnectDialog::BtnCmd2Click(TObject *Sender) -{ - CmdOptDialog->Cmds [0]=Cmds2 [0]; - CmdOptDialog->Cmds [1]=Cmds2 [1]; - CmdOptDialog->CmdEna[0]=CmdEna2[0]; - CmdOptDialog->CmdEna[1]=CmdEna2[1]; - if (CmdOptDialog->ShowModal()!=mrOk) return; - Cmds2 [0]=CmdOptDialog->Cmds [0]; - Cmds2 [1]=CmdOptDialog->Cmds [1]; - CmdEna2[0]=CmdOptDialog->CmdEna[0]; - CmdEna2[1]=CmdOptDialog->CmdEna[1]; -} -//--------------------------------------------------------------------------- -void __fastcall TConnectDialog::SelStream1Change(TObject *Sender) -{ - UpdateEnable(); +__fastcall TConnectDialog::TConnectDialog(TComponent *Owner) : TForm(Owner) { + Stream1 = Stream2 = Format1 = Format2 = 0; + CmdEna1[0] = CmdEna1[1] = CmdEna2[0] = CmdEna2[1] = 0; +} +//--------------------------------------------------------------------------- +void __fastcall TConnectDialog::FormShow(TObject *Sender) { + AnsiString s; + int str[] = {STR_NONE, STR_SERIAL, STR_TCPCLI, STR_TCPSVR, STR_NTRIPCLI, STR_FILE}; + for (int i = 0; i < 6; i++) { + if (str[i] == Stream1) SelStream1->ItemIndex = i; + if (str[i] == Stream2) SelStream2->ItemIndex = i; + } + SolFormat1->ItemIndex = Format1; + SolFormat2->ItemIndex = Format2; + TimeFormS->ItemIndex = TimeForm; + DegFormS->ItemIndex = DegForm; + FieldSepS->Text = FieldSep; + TimeOutTimeE->Text = s.sprintf("%d", TimeOutTime); + ReConnTimeE->Text = s.sprintf("%d", ReConnTime); + UpdateEnable(); +} +//--------------------------------------------------------------------------- +void __fastcall TConnectDialog::BtnOkClick(TObject *Sender) { + int str[] = {STR_NONE, STR_SERIAL, STR_TCPCLI, STR_TCPSVR, STR_NTRIPCLI, STR_FILE}; + Stream1 = str[SelStream1->ItemIndex]; + Stream2 = str[SelStream2->ItemIndex]; + Format1 = SolFormat1->ItemIndex; + Format2 = SolFormat2->ItemIndex; + TimeForm = TimeFormS->ItemIndex; + DegForm = DegFormS->ItemIndex; + FieldSep = FieldSepS->Text; + TimeOutTime = TimeOutTimeE->Text.ToInt(); + ReConnTime = ReConnTimeE->Text.ToInt(); +} +//--------------------------------------------------------------------------- +void __fastcall TConnectDialog::BtnOpt1Click(TObject *Sender) { + switch (SelStream1->ItemIndex) { + case 1: + SerialOpt1(0); + break; + case 2: + TcpOpt1(1); + break; + case 3: + TcpOpt1(0); + break; + case 4: + TcpOpt1(3); + break; + case 5: + FileOpt1(0); + break; + } +} +//--------------------------------------------------------------------------- +void __fastcall TConnectDialog::BtnOpt2Click(TObject *Sender) { + switch (SelStream2->ItemIndex) { + case 1: + SerialOpt2(0); + break; + case 2: + TcpOpt2(1); + break; + case 3: + TcpOpt2(0); + break; + case 4: + TcpOpt2(3); + break; + case 5: + FileOpt2(0); + break; + } +} +//--------------------------------------------------------------------------- +void __fastcall TConnectDialog::BtnCmd1Click(TObject *Sender) { + CmdOptDialog->Cmds[0] = Cmds1[0]; + CmdOptDialog->Cmds[1] = Cmds1[1]; + CmdOptDialog->CmdEna[0] = CmdEna1[0]; + CmdOptDialog->CmdEna[1] = CmdEna1[1]; + if (CmdOptDialog->ShowModal() != mrOk) return; + Cmds1[0] = CmdOptDialog->Cmds[0]; + Cmds1[1] = CmdOptDialog->Cmds[1]; + CmdEna1[0] = CmdOptDialog->CmdEna[0]; + CmdEna1[1] = CmdOptDialog->CmdEna[1]; +} +//--------------------------------------------------------------------------- +void __fastcall TConnectDialog::BtnCmd2Click(TObject *Sender) { + CmdOptDialog->Cmds[0] = Cmds2[0]; + CmdOptDialog->Cmds[1] = Cmds2[1]; + CmdOptDialog->CmdEna[0] = CmdEna2[0]; + CmdOptDialog->CmdEna[1] = CmdEna2[1]; + if (CmdOptDialog->ShowModal() != mrOk) return; + Cmds2[0] = CmdOptDialog->Cmds[0]; + Cmds2[1] = CmdOptDialog->Cmds[1]; + CmdEna2[0] = CmdOptDialog->CmdEna[0]; + CmdEna2[1] = CmdOptDialog->CmdEna[1]; +} +//--------------------------------------------------------------------------- +void __fastcall TConnectDialog::SelStream1Change(TObject *Sender) { UpdateEnable(); } +//--------------------------------------------------------------------------- +void __fastcall TConnectDialog::SelStream2Change(TObject *Sender) { UpdateEnable(); } +//--------------------------------------------------------------------------- +void __fastcall TConnectDialog::SolFormat1Change(TObject *Sender) { UpdateEnable(); } +//--------------------------------------------------------------------------- +void __fastcall TConnectDialog::SolFormat2Change(TObject *Sender) { UpdateEnable(); } +//--------------------------------------------------------------------------- +void __fastcall TConnectDialog::SerialOpt1(int opt) { + SerialOptDialog->Path = Paths1[0]; + SerialOptDialog->Opt = opt; + if (SerialOptDialog->ShowModal() != mrOk) return; + Paths1[0] = SerialOptDialog->Path; +} +//--------------------------------------------------------------------------- +void __fastcall TConnectDialog::SerialOpt2(int opt) { + SerialOptDialog->Path = Paths2[0]; + SerialOptDialog->Opt = opt; + if (SerialOptDialog->ShowModal() != mrOk) return; + Paths2[0] = SerialOptDialog->Path; +} +//--------------------------------------------------------------------------- +void __fastcall TConnectDialog::TcpOpt1(int opt) { + TcpOptDialog->Path = Paths1[1]; + TcpOptDialog->Opt = opt; + for (int i = 0; i < MAXHIST; i++) TcpOptDialog->History[i] = TcpHistory[i]; + if (TcpOptDialog->ShowModal() != mrOk) return; + Paths1[1] = TcpOptDialog->Path; + for (int i = 0; i < MAXHIST; i++) TcpHistory[i] = TcpOptDialog->History[i]; +} +//--------------------------------------------------------------------------- +void __fastcall TConnectDialog::TcpOpt2(int opt) { + TcpOptDialog->Path = Paths2[1]; + TcpOptDialog->Opt = opt; + for (int i = 0; i < MAXHIST; i++) TcpOptDialog->History[i] = TcpHistory[i]; + if (TcpOptDialog->ShowModal() != mrOk) return; + Paths2[1] = TcpOptDialog->Path; + for (int i = 0; i < MAXHIST; i++) TcpHistory[i] = TcpOptDialog->History[i]; +} +//--------------------------------------------------------------------------- +void __fastcall TConnectDialog::FileOpt1(int opt) { + FileOptDialog->Path = Paths1[2]; + FileOptDialog->Opt = opt; + if (FileOptDialog->ShowModal() != mrOk) return; + Paths1[2] = FileOptDialog->Path; +} +//--------------------------------------------------------------------------- +void __fastcall TConnectDialog::FileOpt2(int opt) { + FileOptDialog->Path = Paths2[2]; + FileOptDialog->Opt = opt; + if (FileOptDialog->ShowModal() != mrOk) return; + Paths2[2] = FileOptDialog->Path; +} +//--------------------------------------------------------------------------- +void __fastcall TConnectDialog::UpdateEnable(void) { + BtnOpt1->Enabled = SelStream1->ItemIndex > 0; + BtnOpt2->Enabled = SelStream2->ItemIndex > 0; + BtnCmd1->Enabled = SelStream1->ItemIndex == 1; + BtnCmd2->Enabled = SelStream2->ItemIndex == 1; + SolFormat1->Enabled = SelStream1->ItemIndex > 0; + SolFormat2->Enabled = SelStream2->ItemIndex > 0; + TimeFormS->Enabled = SolFormat1->ItemIndex != 3 || SolFormat2->ItemIndex != 3; + DegFormS->Enabled = SolFormat1->ItemIndex == 0 || SolFormat2->ItemIndex == 0; + FieldSepS->Enabled = SolFormat1->ItemIndex != 3 || SolFormat2->ItemIndex != 3; + Label5->Enabled = SolFormat1->ItemIndex != 3 || SolFormat2->ItemIndex != 3; + Label6->Enabled = SolFormat1->ItemIndex == 0 || SolFormat2->ItemIndex == 0; + Label7->Enabled = SolFormat1->ItemIndex != 3 || SolFormat2->ItemIndex != 3; + Label8->Enabled = (2 <= SelStream1->ItemIndex && SelStream1->ItemIndex <= 4) || + (2 <= SelStream2->ItemIndex && SelStream2->ItemIndex <= 4); + TimeOutTimeE->Enabled = (2 <= SelStream1->ItemIndex && SelStream1->ItemIndex <= 4) || + (2 <= SelStream2->ItemIndex && SelStream2->ItemIndex <= 4); + ReConnTimeE->Enabled = (2 <= SelStream1->ItemIndex && SelStream1->ItemIndex <= 4) || + (2 <= SelStream2->ItemIndex && SelStream2->ItemIndex <= 4); } //--------------------------------------------------------------------------- -void __fastcall TConnectDialog::SelStream2Change(TObject *Sender) -{ - UpdateEnable(); -} -//--------------------------------------------------------------------------- -void __fastcall TConnectDialog::SolFormat1Change(TObject *Sender) -{ - UpdateEnable(); -} -//--------------------------------------------------------------------------- -void __fastcall TConnectDialog::SolFormat2Change(TObject *Sender) -{ - UpdateEnable(); -} -//--------------------------------------------------------------------------- -void __fastcall TConnectDialog::SerialOpt1(int opt) -{ - SerialOptDialog->Path=Paths1[0]; - SerialOptDialog->Opt=opt; - if (SerialOptDialog->ShowModal()!=mrOk) return; - Paths1[0]=SerialOptDialog->Path; -} -//--------------------------------------------------------------------------- -void __fastcall TConnectDialog::SerialOpt2(int opt) -{ - SerialOptDialog->Path=Paths2[0]; - SerialOptDialog->Opt=opt; - if (SerialOptDialog->ShowModal()!=mrOk) return; - Paths2[0]=SerialOptDialog->Path; -} -//--------------------------------------------------------------------------- -void __fastcall TConnectDialog::TcpOpt1(int opt) -{ - TcpOptDialog->Path=Paths1[1]; - TcpOptDialog->Opt=opt; - for (int i=0;iHistory[i]=TcpHistory[i]; - if (TcpOptDialog->ShowModal()!=mrOk) return; - Paths1[1]=TcpOptDialog->Path; - for (int i=0;iHistory[i]; -} -//--------------------------------------------------------------------------- -void __fastcall TConnectDialog::TcpOpt2(int opt) -{ - TcpOptDialog->Path=Paths2[1]; - TcpOptDialog->Opt=opt; - for (int i=0;iHistory[i]=TcpHistory[i]; - if (TcpOptDialog->ShowModal()!=mrOk) return; - Paths2[1]=TcpOptDialog->Path; - for (int i=0;iHistory[i]; -} -//--------------------------------------------------------------------------- -void __fastcall TConnectDialog::FileOpt1(int opt) -{ - FileOptDialog->Path=Paths1[2]; - FileOptDialog->Opt=opt; - if (FileOptDialog->ShowModal()!=mrOk) return; - Paths1[2]=FileOptDialog->Path; -} -//--------------------------------------------------------------------------- -void __fastcall TConnectDialog::FileOpt2(int opt) -{ - FileOptDialog->Path=Paths2[2]; - FileOptDialog->Opt=opt; - if (FileOptDialog->ShowModal()!=mrOk) return; - Paths2[2]=FileOptDialog->Path; -} -//--------------------------------------------------------------------------- -void __fastcall TConnectDialog::UpdateEnable(void) -{ - BtnOpt1 ->Enabled=SelStream1->ItemIndex>0; - BtnOpt2 ->Enabled=SelStream2->ItemIndex>0; - BtnCmd1 ->Enabled=SelStream1->ItemIndex==1; - BtnCmd2 ->Enabled=SelStream2->ItemIndex==1; - SolFormat1 ->Enabled=SelStream1->ItemIndex>0; - SolFormat2 ->Enabled=SelStream2->ItemIndex>0; - TimeFormS ->Enabled=SolFormat1->ItemIndex!=3||SolFormat2->ItemIndex!=3; - DegFormS ->Enabled=SolFormat1->ItemIndex==0||SolFormat2->ItemIndex==0; - FieldSepS ->Enabled=SolFormat1->ItemIndex!=3||SolFormat2->ItemIndex!=3; - Label5 ->Enabled=SolFormat1->ItemIndex!=3||SolFormat2->ItemIndex!=3; - Label6 ->Enabled=SolFormat1->ItemIndex==0||SolFormat2->ItemIndex==0; - Label7 ->Enabled=SolFormat1->ItemIndex!=3||SolFormat2->ItemIndex!=3; - Label8 ->Enabled=(2<=SelStream1->ItemIndex&&SelStream1->ItemIndex<=4)|| - (2<=SelStream2->ItemIndex&&SelStream2->ItemIndex<=4); - TimeOutTimeE->Enabled=(2<=SelStream1->ItemIndex&&SelStream1->ItemIndex<=4)|| - (2<=SelStream2->ItemIndex&&SelStream2->ItemIndex<=4); - ReConnTimeE ->Enabled=(2<=SelStream1->ItemIndex&&SelStream1->ItemIndex<=4)|| - (2<=SelStream2->ItemIndex&&SelStream2->ItemIndex<=4); -} -//--------------------------------------------------------------------------- - diff --git a/app/winapp/rtkplot/conndlg.h b/app/winapp/rtkplot/conndlg.h index 5a1ca254e..79e46c2d2 100644 --- a/app/winapp/rtkplot/conndlg.h +++ b/app/winapp/rtkplot/conndlg.h @@ -4,65 +4,65 @@ //--------------------------------------------------------------------------- #include #include -#include #include +#include -#define MAXHIST 10 +#define MAXHIST 10 //--------------------------------------------------------------------------- -class TConnectDialog : public TForm -{ -__published: - TButton *BtnOk; - TButton *BtnCancel; - TComboBox *SelStream1; - TButton *BtnOpt1; - TLabel *Label1; - TLabel *Label2; - TComboBox *SolFormat1; - TButton *BtnCmd1; - TLabel *Label3; - TLabel *Label4; - TComboBox *TimeFormS; - TComboBox *DegFormS; - TLabel *Label5; - TLabel *Label6; - TEdit *FieldSepS; - TLabel *Label7; - TEdit *TimeOutTimeE; - TEdit *ReConnTimeE; - TLabel *Label8; - TComboBox *SelStream2; - TButton *BtnOpt2; - TButton *BtnCmd2; - TComboBox *SolFormat2; - TLabel *Label9; - TLabel *Label10; - void __fastcall BtnOpt1Click(TObject *Sender); - void __fastcall BtnOkClick(TObject *Sender); - void __fastcall FormShow(TObject *Sender); - void __fastcall BtnCmd1Click(TObject *Sender); - void __fastcall SelStream1Change(TObject *Sender); - void __fastcall SolFormat1Change(TObject *Sender); - void __fastcall BtnOpt2Click(TObject *Sender); - void __fastcall BtnCmd2Click(TObject *Sender); - void __fastcall SolFormat2Change(TObject *Sender); - void __fastcall SelStream2Change(TObject *Sender); -private: - void __fastcall SerialOpt1(int opt); - void __fastcall SerialOpt2(int opt); - void __fastcall TcpOpt1(int opt); - void __fastcall TcpOpt2(int opt); - void __fastcall FileOpt1(int opt); - void __fastcall FileOpt2(int opt); - void __fastcall UpdateEnable(void); -public: - int Stream1,Stream2,Format1,Format2,CmdEna1[2],CmdEna2[2]; - int TimeForm,DegForm,TimeOutTime,ReConnTime; - AnsiString Path,Paths1[4],Paths2[4]; - AnsiString TcpHistory[MAXHIST]; - AnsiString Cmds1[2],Cmds2[2],FieldSep; - __fastcall TConnectDialog(TComponent* Owner); +class TConnectDialog : public TForm { + __published : TButton *BtnOk; + TButton *BtnCancel; + TComboBox *SelStream1; + TButton *BtnOpt1; + TLabel *Label1; + TLabel *Label2; + TComboBox *SolFormat1; + TButton *BtnCmd1; + TLabel *Label3; + TLabel *Label4; + TComboBox *TimeFormS; + TComboBox *DegFormS; + TLabel *Label5; + TLabel *Label6; + TEdit *FieldSepS; + TLabel *Label7; + TEdit *TimeOutTimeE; + TEdit *ReConnTimeE; + TLabel *Label8; + TComboBox *SelStream2; + TButton *BtnOpt2; + TButton *BtnCmd2; + TComboBox *SolFormat2; + TLabel *Label9; + TLabel *Label10; + void __fastcall BtnOpt1Click(TObject *Sender); + void __fastcall BtnOkClick(TObject *Sender); + void __fastcall FormShow(TObject *Sender); + void __fastcall BtnCmd1Click(TObject *Sender); + void __fastcall SelStream1Change(TObject *Sender); + void __fastcall SolFormat1Change(TObject *Sender); + void __fastcall BtnOpt2Click(TObject *Sender); + void __fastcall BtnCmd2Click(TObject *Sender); + void __fastcall SolFormat2Change(TObject *Sender); + void __fastcall SelStream2Change(TObject *Sender); + + private: + void __fastcall SerialOpt1(int opt); + void __fastcall SerialOpt2(int opt); + void __fastcall TcpOpt1(int opt); + void __fastcall TcpOpt2(int opt); + void __fastcall FileOpt1(int opt); + void __fastcall FileOpt2(int opt); + void __fastcall UpdateEnable(void); + + public: + int Stream1, Stream2, Format1, Format2, CmdEna1[2], CmdEna2[2]; + int TimeForm, DegForm, TimeOutTime, ReConnTime; + AnsiString Path, Paths1[4], Paths2[4]; + AnsiString TcpHistory[MAXHIST]; + AnsiString Cmds1[2], Cmds2[2], FieldSep; + __fastcall TConnectDialog(TComponent *Owner); }; //--------------------------------------------------------------------------- extern PACKAGE TConnectDialog *ConnectDialog; diff --git a/app/winapp/rtkplot/fileseldlg.cpp b/app/winapp/rtkplot/fileseldlg.cpp index f1139415d..3c6f97a40 100644 --- a/app/winapp/rtkplot/fileseldlg.cpp +++ b/app/winapp/rtkplot/fileseldlg.cpp @@ -2,9 +2,10 @@ #include #pragma hdrstop -#include "plotmain.h" #include "fileseldlg.h" +#include "plotmain.h" + //--------------------------------------------------------------------------- #pragma package(smart_init) #pragma resource "*.dfm" @@ -12,73 +13,48 @@ TFileSelDialog *FileSelDialog; //--------------------------------------------------------------------------- -__fastcall TFileSelDialog::TFileSelDialog(TComponent* Owner) - : TForm(Owner) -{ -} +__fastcall TFileSelDialog::TFileSelDialog(TComponent *Owner) : TForm(Owner) {} //--------------------------------------------------------------------------- -void __fastcall TFileSelDialog::FormShow(TObject *Sender) -{ - DirSel->Directory=Dir; - Panel5->Visible=false; +void __fastcall TFileSelDialog::FormShow(TObject *Sender) { + DirSel->Directory = Dir; + Panel5->Visible = false; } //--------------------------------------------------------------------------- -void __fastcall TFileSelDialog::FormResize(TObject *Sender) -{ - Panel5->Width=Width-16; -} +void __fastcall TFileSelDialog::FormResize(TObject *Sender) { Panel5->Width = Width - 16; } //--------------------------------------------------------------------------- -void __fastcall TFileSelDialog::DriveSelClick(TObject *Sender) -{ - Panel5->Visible=false; -} +void __fastcall TFileSelDialog::DriveSelClick(TObject *Sender) { Panel5->Visible = false; } //--------------------------------------------------------------------------- -void __fastcall TFileSelDialog::DirLabelClick(TObject *Sender) -{ - Panel5->Visible=!Panel5->Visible; +void __fastcall TFileSelDialog::DirLabelClick(TObject *Sender) { + Panel5->Visible = !Panel5->Visible; } //--------------------------------------------------------------------------- -void __fastcall TFileSelDialog::Panel4Click(TObject *Sender) -{ - Panel5->Visible=!Panel5->Visible; -} +void __fastcall TFileSelDialog::Panel4Click(TObject *Sender) { Panel5->Visible = !Panel5->Visible; } //--------------------------------------------------------------------------- -void __fastcall TFileSelDialog::BtnDirSelClick(TObject *Sender) -{ - Panel5->Visible=!Panel5->Visible; +void __fastcall TFileSelDialog::BtnDirSelClick(TObject *Sender) { + Panel5->Visible = !Panel5->Visible; } //--------------------------------------------------------------------------- -void __fastcall TFileSelDialog::DirSelChange(TObject *Sender) -{ - Dir=DirSel->Directory; - Panel5->Height=DirSel->Count*DirSel->ItemHeight+8; - if (Panel5->Height>312) Panel5->Height=312; - Panel5->Visible=false; +void __fastcall TFileSelDialog::DirSelChange(TObject *Sender) { + Dir = DirSel->Directory; + Panel5->Height = DirSel->Count * DirSel->ItemHeight + 8; + if (Panel5->Height > 312) Panel5->Height = 312; + Panel5->Visible = false; } //--------------------------------------------------------------------------- -void __fastcall TFileSelDialog::FileListClick(TObject *Sender) -{ - TStringList *file=new TStringList; - file->Add(FileList->FileName); - Plot->ReadSol(file,0); - delete file; - Panel5->Visible=false; +void __fastcall TFileSelDialog::FileListClick(TObject *Sender) { + TStringList *file = new TStringList; + file->Add(FileList->FileName); + Plot->ReadSol(file, 0); + delete file; + Panel5->Visible = false; } //--------------------------------------------------------------------------- -void __fastcall TFileSelDialog::FileListMouseDown(TObject *Sender, - TMouseButton Button, TShiftState Shift, int X, int Y) -{ - Panel5->Visible=false; +void __fastcall TFileSelDialog::FileListMouseDown(TObject *Sender, TMouseButton Button, + TShiftState Shift, int X, int Y) { + Panel5->Visible = false; } //--------------------------------------------------------------------------- -void __fastcall TFileSelDialog::FilterClick(TObject *Sender) -{ - Panel5->Visible=false; -} +void __fastcall TFileSelDialog::FilterClick(TObject *Sender) { Panel5->Visible = false; } //--------------------------------------------------------------------------- -void __fastcall TFileSelDialog::BtnUpdateClick(TObject *Sender) -{ - FileList->Update(); -} +void __fastcall TFileSelDialog::BtnUpdateClick(TObject *Sender) { FileList->Update(); } //--------------------------------------------------------------------------- - diff --git a/app/winapp/rtkplot/fileseldlg.h b/app/winapp/rtkplot/fileseldlg.h index 742c2160e..0583d9a95 100644 --- a/app/winapp/rtkplot/fileseldlg.h +++ b/app/winapp/rtkplot/fileseldlg.h @@ -3,47 +3,46 @@ #define fileseldlgH //--------------------------------------------------------------------------- +#include #include +#include #include -#include -#include #include #include -#include -#include +#include +#include //--------------------------------------------------------------------------- -class TFileSelDialog : public TForm -{ -__published: - TPanel *Panel1; - TDriveComboBox *DriveSel; - TPanel *Panel2; - TDirectoryListBox *DirSel; - TFileListBox *FileList; - TPanel *Panel3; - TFilterComboBox *Filter; - TLabel *DirLabel; - TBitBtn *BtnDirSel; - TPanel *Panel4; - TPanel *Panel5; - TSpeedButton *BtnUpdate; - void __fastcall FileListClick(TObject *Sender); - void __fastcall FormShow(TObject *Sender); - void __fastcall DirSelChange(TObject *Sender); - void __fastcall BtnDirSelClick(TObject *Sender); - void __fastcall FormResize(TObject *Sender); - void __fastcall DriveSelClick(TObject *Sender); - void __fastcall DirLabelClick(TObject *Sender); - void __fastcall FilterClick(TObject *Sender); - void __fastcall Panel4Click(TObject *Sender); - void __fastcall FileListMouseDown(TObject *Sender, TMouseButton Button, - TShiftState Shift, int X, int Y); - void __fastcall BtnUpdateClick(TObject *Sender); -private: -public: - AnsiString Dir; - __fastcall TFileSelDialog(TComponent* Owner); +class TFileSelDialog : public TForm { + __published : TPanel *Panel1; + TDriveComboBox *DriveSel; + TPanel *Panel2; + TDirectoryListBox *DirSel; + TFileListBox *FileList; + TPanel *Panel3; + TFilterComboBox *Filter; + TLabel *DirLabel; + TBitBtn *BtnDirSel; + TPanel *Panel4; + TPanel *Panel5; + TSpeedButton *BtnUpdate; + void __fastcall FileListClick(TObject *Sender); + void __fastcall FormShow(TObject *Sender); + void __fastcall DirSelChange(TObject *Sender); + void __fastcall BtnDirSelClick(TObject *Sender); + void __fastcall FormResize(TObject *Sender); + void __fastcall DriveSelClick(TObject *Sender); + void __fastcall DirLabelClick(TObject *Sender); + void __fastcall FilterClick(TObject *Sender); + void __fastcall Panel4Click(TObject *Sender); + void __fastcall FileListMouseDown(TObject *Sender, TMouseButton Button, TShiftState Shift, int X, + int Y); + void __fastcall BtnUpdateClick(TObject *Sender); + + private: + public: + AnsiString Dir; + __fastcall TFileSelDialog(TComponent *Owner); }; //--------------------------------------------------------------------------- extern PACKAGE TFileSelDialog *FileSelDialog; diff --git a/app/winapp/rtkplot/mapoptdlg.cpp b/app/winapp/rtkplot/mapoptdlg.cpp index 5872033ee..0b52b4e10 100644 --- a/app/winapp/rtkplot/mapoptdlg.cpp +++ b/app/winapp/rtkplot/mapoptdlg.cpp @@ -1,195 +1,189 @@ //--------------------------------------------------------------------------- -#include #include +#include + #include "rtklib.h" #pragma hdrstop -#include "plotmain.h" #include "mapoptdlg.h" + #include "confdlg.h" +#include "plotmain.h" -#define INC_LATLON 0.000001 -#define INC_SCALE 0.0001 +#define INC_LATLON 0.000001 +#define INC_SCALE 0.0001 //--------------------------------------------------------------------------- #pragma package(smart_init) #pragma resource "*.dfm" TMapOptDialog *MapOptDialog; //--------------------------------------------------------------------------- -static double str2dbl(AnsiString str) -{ - double val=0.0; - sscanf(str.c_str(),"%lf",&val); - return val; -} -//--------------------------------------------------------------------------- -__fastcall TMapOptDialog::TMapOptDialog(TComponent* Owner) - : TForm(Owner) -{ -} -//--------------------------------------------------------------------------- -void __fastcall TMapOptDialog::FormShow(TObject *Sender) -{ - UpdateField(); - UpdateEnable(); -} -//--------------------------------------------------------------------------- -void __fastcall TMapOptDialog::BtnSaveClick(TObject *Sender) -{ - FILE *fp; - AnsiString file=Plot->MapImageFile; - if (file=="") return; - file=file+".tag"; - if ((fp=fopen(file.c_str(),"r"))) { - fclose(fp); - ConfDialog->Label1->Caption="File exists. Overwrite it?"; - ConfDialog->Label2->Caption=file; - if (ConfDialog->ShowModal()!=mrOk) return; - } - if (!(fp=fopen(file.c_str(),"w"))) return; - fprintf(fp,"%% map image tag file: rtkplot-%s %s\n\n",VER_RTKLIB,PATCH_LEVEL); - fprintf(fp,"scalex = %.6g\n",Plot->MapScaleX ); - fprintf(fp,"scaley = %.6g\n",Plot->MapScaleEq?Plot->MapScaleX:Plot->MapScaleY); - fprintf(fp,"scaleeq = %d\n" ,Plot->MapScaleEq); - fprintf(fp,"lat = %.9g\n",Plot->MapLat ); - fprintf(fp,"lon = %.9g\n",Plot->MapLon ); - fclose(fp); -} -//--------------------------------------------------------------------------- -void __fastcall TMapOptDialog::BtnCenterClick(TObject *Sender) -{ - AnsiString s; - double rr[3],pos[3]; - if (!Plot->GetCenterPos(rr)) return; - ecef2pos(rr,pos); - Lat->Text=s.sprintf("%.7f",pos[0]*R2D); - Lon->Text=s.sprintf("%.7f",pos[1]*R2D); - UpdateMap(); -} -//--------------------------------------------------------------------------- -void __fastcall TMapOptDialog::BtnUpdateClick(TObject *Sender) -{ - UpdateMap(); -} -//--------------------------------------------------------------------------- -void __fastcall TMapOptDialog::BtnCloseClick(TObject *Sender) -{ - Close(); -} -//--------------------------------------------------------------------------- -void __fastcall TMapOptDialog::ScaleEqClick(TObject *Sender) -{ - UpdateMap(); - UpdateEnable(); -} -//--------------------------------------------------------------------------- -void __fastcall TMapOptDialog::ScaleXUpDownChangingEx(TObject *Sender, - bool &AllowChange, int NewValue, TUpDownDirection Direction) -{ - AnsiString s; - double scale=str2dbl(ScaleX->Text); - if (Direction==updUp) scale+=INC_SCALE; else scale-=INC_SCALE; - ScaleX->Text=s.sprintf("%.5f",scale); - UpdateMap(); -} -//--------------------------------------------------------------------------- -void __fastcall TMapOptDialog::ScaleYUpDownChangingEx(TObject *Sender, - bool &AllowChange, int NewValue, TUpDownDirection Direction) -{ - AnsiString s; - double scale=str2dbl(ScaleY->Text); - if (Direction==updUp) scale+=INC_SCALE; else scale-=INC_SCALE; - ScaleY->Text=s.sprintf("%.5f",scale); - UpdateMap(); -} -//--------------------------------------------------------------------------- -void __fastcall TMapOptDialog::LatUpDownChangingEx(TObject *Sender, - bool &AllowChange, int NewValue, TUpDownDirection Direction) -{ - AnsiString s; - double lat=str2dbl(Lat->Text); - if (Direction==updUp) lat+=INC_LATLON; else lat-=INC_LATLON; - Lat->Text=s.sprintf("%.7f",lat); - UpdateMap(); -} -//--------------------------------------------------------------------------- -void __fastcall TMapOptDialog::LonUpDownChangingEx(TObject *Sender, - bool &AllowChange, int NewValue, TUpDownDirection Direction) -{ - AnsiString s; - double lon=str2dbl(Lon->Text); - if (Direction==updUp) lon+=INC_LATLON; else lon-=INC_LATLON; - Lon->Text=s.sprintf("%.7f",lon); - UpdateMap(); +static double str2dbl(AnsiString str) { + double val = 0.0; + sscanf(str.c_str(), "%lf", &val); + return val; +} +//--------------------------------------------------------------------------- +__fastcall TMapOptDialog::TMapOptDialog(TComponent *Owner) : TForm(Owner) {} +//--------------------------------------------------------------------------- +void __fastcall TMapOptDialog::FormShow(TObject *Sender) { + UpdateField(); + UpdateEnable(); +} +//--------------------------------------------------------------------------- +void __fastcall TMapOptDialog::BtnSaveClick(TObject *Sender) { + FILE *fp; + AnsiString file = Plot->MapImageFile; + if (file == "") return; + file = file + ".tag"; + if ((fp = fopen(file.c_str(), "r"))) { + fclose(fp); + ConfDialog->Label1->Caption = "File exists. Overwrite it?"; + ConfDialog->Label2->Caption = file; + if (ConfDialog->ShowModal() != mrOk) return; + } + if (!(fp = fopen(file.c_str(), "w"))) return; + fprintf(fp, "%% map image tag file: rtkplot-%s %s\n\n", VER_RTKLIB, PATCH_LEVEL); + fprintf(fp, "scalex = %.6g\n", Plot->MapScaleX); + fprintf(fp, "scaley = %.6g\n", Plot->MapScaleEq ? Plot->MapScaleX : Plot->MapScaleY); + fprintf(fp, "scaleeq = %d\n", Plot->MapScaleEq); + fprintf(fp, "lat = %.9g\n", Plot->MapLat); + fprintf(fp, "lon = %.9g\n", Plot->MapLon); + fclose(fp); +} +//--------------------------------------------------------------------------- +void __fastcall TMapOptDialog::BtnCenterClick(TObject *Sender) { + AnsiString s; + double rr[3], pos[3]; + if (!Plot->GetCenterPos(rr)) return; + ecef2pos(rr, pos); + Lat->Text = s.sprintf("%.7f", pos[0] * R2D); + Lon->Text = s.sprintf("%.7f", pos[1] * R2D); + UpdateMap(); +} +//--------------------------------------------------------------------------- +void __fastcall TMapOptDialog::BtnUpdateClick(TObject *Sender) { UpdateMap(); } +//--------------------------------------------------------------------------- +void __fastcall TMapOptDialog::BtnCloseClick(TObject *Sender) { Close(); } +//--------------------------------------------------------------------------- +void __fastcall TMapOptDialog::ScaleEqClick(TObject *Sender) { + UpdateMap(); + UpdateEnable(); +} +//--------------------------------------------------------------------------- +void __fastcall TMapOptDialog::ScaleXUpDownChangingEx(TObject *Sender, bool &AllowChange, + int NewValue, TUpDownDirection Direction) { + AnsiString s; + double scale = str2dbl(ScaleX->Text); + if (Direction == updUp) + scale += INC_SCALE; + else + scale -= INC_SCALE; + ScaleX->Text = s.sprintf("%.5f", scale); + UpdateMap(); +} +//--------------------------------------------------------------------------- +void __fastcall TMapOptDialog::ScaleYUpDownChangingEx(TObject *Sender, bool &AllowChange, + int NewValue, TUpDownDirection Direction) { + AnsiString s; + double scale = str2dbl(ScaleY->Text); + if (Direction == updUp) + scale += INC_SCALE; + else + scale -= INC_SCALE; + ScaleY->Text = s.sprintf("%.5f", scale); + UpdateMap(); +} +//--------------------------------------------------------------------------- +void __fastcall TMapOptDialog::LatUpDownChangingEx(TObject *Sender, bool &AllowChange, int NewValue, + TUpDownDirection Direction) { + AnsiString s; + double lat = str2dbl(Lat->Text); + if (Direction == updUp) + lat += INC_LATLON; + else + lat -= INC_LATLON; + Lat->Text = s.sprintf("%.7f", lat); + UpdateMap(); +} +//--------------------------------------------------------------------------- +void __fastcall TMapOptDialog::LonUpDownChangingEx(TObject *Sender, bool &AllowChange, int NewValue, + TUpDownDirection Direction) { + AnsiString s; + double lon = str2dbl(Lon->Text); + if (Direction == updUp) + lon += INC_LATLON; + else + lon -= INC_LATLON; + Lon->Text = s.sprintf("%.7f", lon); + UpdateMap(); } //--------------------------------------------------------------------------- void __fastcall TMapOptDialog::ScaleXKeyDown(TObject *Sender, WORD &Key, TShiftState Shift) { - bool allowchange; - if (Key==VK_UP||Key==VK_DOWN||Key==VK_RIGHT||Key==VK_LEFT) { - ScaleXUpDownChangingEx(Sender,allowchange,0,Key==VK_UP||Key==VK_RIGHT?updUp:updDown); - Key=0; - } + bool allowchange; + if (Key == VK_UP || Key == VK_DOWN || Key == VK_RIGHT || Key == VK_LEFT) { + ScaleXUpDownChangingEx(Sender, allowchange, 0, + Key == VK_UP || Key == VK_RIGHT ? updUp : updDown); + Key = 0; + } } //--------------------------------------------------------------------------- void __fastcall TMapOptDialog::ScaleYKeyDown(TObject *Sender, WORD &Key, TShiftState Shift) { - bool allowchange; - if (Key==VK_UP||Key==VK_DOWN||Key==VK_RIGHT||Key==VK_LEFT) { - ScaleYUpDownChangingEx(Sender,allowchange,0,Key==VK_UP||Key==VK_RIGHT?updUp:updDown); - Key=0; - } + bool allowchange; + if (Key == VK_UP || Key == VK_DOWN || Key == VK_RIGHT || Key == VK_LEFT) { + ScaleYUpDownChangingEx(Sender, allowchange, 0, + Key == VK_UP || Key == VK_RIGHT ? updUp : updDown); + Key = 0; + } } //--------------------------------------------------------------------------- void __fastcall TMapOptDialog::LatKeyDown(TObject *Sender, WORD &Key, TShiftState Shift) { - bool allowchange; - if (Key==VK_UP||Key==VK_DOWN||Key==VK_RIGHT||Key==VK_LEFT) { - LatUpDownChangingEx(Sender,allowchange,0,Key==VK_UP||Key==VK_RIGHT?updUp:updDown); - Key=0; - } + bool allowchange; + if (Key == VK_UP || Key == VK_DOWN || Key == VK_RIGHT || Key == VK_LEFT) { + LatUpDownChangingEx(Sender, allowchange, 0, Key == VK_UP || Key == VK_RIGHT ? updUp : updDown); + Key = 0; + } } //--------------------------------------------------------------------------- void __fastcall TMapOptDialog::LonKeyDown(TObject *Sender, WORD &Key, TShiftState Shift) { - bool allowchange; - if (Key==VK_UP||Key==VK_DOWN||Key==VK_RIGHT||Key==VK_LEFT) { - LonUpDownChangingEx(Sender,allowchange,0,Key==VK_UP||Key==VK_RIGHT?updUp:updDown); - Key=0; - } + bool allowchange; + if (Key == VK_UP || Key == VK_DOWN || Key == VK_RIGHT || Key == VK_LEFT) { + LonUpDownChangingEx(Sender, allowchange, 0, Key == VK_UP || Key == VK_RIGHT ? updUp : updDown); + Key = 0; + } } //--------------------------------------------------------------------------- -void __fastcall TMapOptDialog::UpdateField(void) -{ - AnsiString s; - Caption=Plot->MapImageFile; - MapSize1->Text=s.sprintf("%d",Plot->MapSize[0]); - MapSize2->Text=s.sprintf("%d",Plot->MapSize[1]); - ScaleX->Text=s.sprintf("%.5f",Plot->MapScaleX); - ScaleY->Text=s.sprintf("%.5f",Plot->MapScaleY); - Lat->Text=s.sprintf("%.7f",Plot->MapLat); - Lon->Text=s.sprintf("%.7f",Plot->MapLon); - ScaleEq->Checked=Plot->MapScaleEq; -} -//--------------------------------------------------------------------------- -void __fastcall TMapOptDialog::UpdateMap(void) -{ - Plot->MapScaleX=str2dbl(ScaleX->Text); - Plot->MapScaleY=str2dbl(ScaleY->Text); - Plot->MapLat=str2dbl(Lat->Text); - Plot->MapLon=str2dbl(Lon->Text); - Plot->MapScaleEq=ScaleEq->Checked; - Plot->UpdatePlot(); +void __fastcall TMapOptDialog::UpdateField(void) { + AnsiString s; + Caption = Plot->MapImageFile; + MapSize1->Text = s.sprintf("%d", Plot->MapSize[0]); + MapSize2->Text = s.sprintf("%d", Plot->MapSize[1]); + ScaleX->Text = s.sprintf("%.5f", Plot->MapScaleX); + ScaleY->Text = s.sprintf("%.5f", Plot->MapScaleY); + Lat->Text = s.sprintf("%.7f", Plot->MapLat); + Lon->Text = s.sprintf("%.7f", Plot->MapLon); + ScaleEq->Checked = Plot->MapScaleEq; } //--------------------------------------------------------------------------- -void __fastcall TMapOptDialog::UpdateEnable(void) -{ - ScaleY ->Enabled=!ScaleEq->Checked; - ScaleYUpDown->Enabled=!ScaleEq->Checked; -} +void __fastcall TMapOptDialog::UpdateMap(void) { + Plot->MapScaleX = str2dbl(ScaleX->Text); + Plot->MapScaleY = str2dbl(ScaleY->Text); + Plot->MapLat = str2dbl(Lat->Text); + Plot->MapLon = str2dbl(Lon->Text); + Plot->MapScaleEq = ScaleEq->Checked; + Plot->UpdatePlot(); +} +//--------------------------------------------------------------------------- +void __fastcall TMapOptDialog::UpdateEnable(void) { + ScaleY->Enabled = !ScaleEq->Checked; + ScaleYUpDown->Enabled = !ScaleEq->Checked; +} //--------------------------------------------------------------------------- - diff --git a/app/winapp/rtkplot/mapoptdlg.h b/app/winapp/rtkplot/mapoptdlg.h index 30158b737..f27bb2a6b 100644 --- a/app/winapp/rtkplot/mapoptdlg.h +++ b/app/winapp/rtkplot/mapoptdlg.h @@ -2,64 +2,63 @@ #ifndef mapoptdlgH #define mapoptdlgH //--------------------------------------------------------------------------- +#include #include -#include -#include -#include #include +#include #include -#include +#include +#include //--------------------------------------------------------------------------- -class TMapOptDialog : public TForm -{ -__published: - TButton *BtnClose; - TButton *BtnCenter; - TButton *BtnSave; - TButton *BtnUpdate; - TPanel *Panel1; - TLabel *Label1; - TEdit *MapSize1; - TEdit *MapSize2; - TPanel *Panel2; - TEdit *ScaleX; - TUpDown *ScaleXUpDown; - TEdit *ScaleY; - TUpDown *ScaleYUpDown; - TEdit *Lat; - TUpDown *LatUpDown; - TEdit *Lon; - TUpDown *LonUpDown; - TLabel *Label5; - TLabel *Label6; - TCheckBox *ScaleEq; - TLabel *Label2; - void __fastcall FormShow(TObject *Sender); - void __fastcall ScaleXUpDownChangingEx(TObject *Sender, bool &AllowChange, - int NewValue, TUpDownDirection Direction); - void __fastcall LatUpDownChangingEx(TObject *Sender, bool &AllowChange, - int NewValue, TUpDownDirection Direction); - void __fastcall LonUpDownChangingEx(TObject *Sender, bool &AllowChange, - int NewValue, TUpDownDirection Direction); - void __fastcall BtnCloseClick(TObject *Sender); - void __fastcall BtnUpdateClick(TObject *Sender); - void __fastcall BtnSaveClick(TObject *Sender); - void __fastcall ScaleYUpDownChangingEx(TObject *Sender, bool &AllowChange, - int NewValue, TUpDownDirection Direction); - void __fastcall BtnCenterClick(TObject *Sender); - void __fastcall ScaleEqClick(TObject *Sender); - void __fastcall LonKeyDown(TObject *Sender, WORD &Key, TShiftState Shift); - void __fastcall LatKeyDown(TObject *Sender, WORD &Key, TShiftState Shift); - void __fastcall ScaleXKeyDown(TObject *Sender, WORD &Key, TShiftState Shift); - void __fastcall ScaleYKeyDown(TObject *Sender, WORD &Key, TShiftState Shift); -private: - void __fastcall UpdateMap(void); - void __fastcall UpdatePlot(void); - void __fastcall UpdateEnable(void); - -public: - __fastcall TMapOptDialog(TComponent* Owner); - void __fastcall UpdateField(void); +class TMapOptDialog : public TForm { + __published : TButton *BtnClose; + TButton *BtnCenter; + TButton *BtnSave; + TButton *BtnUpdate; + TPanel *Panel1; + TLabel *Label1; + TEdit *MapSize1; + TEdit *MapSize2; + TPanel *Panel2; + TEdit *ScaleX; + TUpDown *ScaleXUpDown; + TEdit *ScaleY; + TUpDown *ScaleYUpDown; + TEdit *Lat; + TUpDown *LatUpDown; + TEdit *Lon; + TUpDown *LonUpDown; + TLabel *Label5; + TLabel *Label6; + TCheckBox *ScaleEq; + TLabel *Label2; + void __fastcall FormShow(TObject *Sender); + void __fastcall ScaleXUpDownChangingEx(TObject *Sender, bool &AllowChange, int NewValue, + TUpDownDirection Direction); + void __fastcall LatUpDownChangingEx(TObject *Sender, bool &AllowChange, int NewValue, + TUpDownDirection Direction); + void __fastcall LonUpDownChangingEx(TObject *Sender, bool &AllowChange, int NewValue, + TUpDownDirection Direction); + void __fastcall BtnCloseClick(TObject *Sender); + void __fastcall BtnUpdateClick(TObject *Sender); + void __fastcall BtnSaveClick(TObject *Sender); + void __fastcall ScaleYUpDownChangingEx(TObject *Sender, bool &AllowChange, int NewValue, + TUpDownDirection Direction); + void __fastcall BtnCenterClick(TObject *Sender); + void __fastcall ScaleEqClick(TObject *Sender); + void __fastcall LonKeyDown(TObject *Sender, WORD &Key, TShiftState Shift); + void __fastcall LatKeyDown(TObject *Sender, WORD &Key, TShiftState Shift); + void __fastcall ScaleXKeyDown(TObject *Sender, WORD &Key, TShiftState Shift); + void __fastcall ScaleYKeyDown(TObject *Sender, WORD &Key, TShiftState Shift); + + private: + void __fastcall UpdateMap(void); + void __fastcall UpdatePlot(void); + void __fastcall UpdateEnable(void); + + public: + __fastcall TMapOptDialog(TComponent *Owner); + void __fastcall UpdateField(void); }; //--------------------------------------------------------------------------- extern PACKAGE TMapOptDialog *MapOptDialog; diff --git a/app/winapp/rtkplot/mapview.cpp b/app/winapp/rtkplot/mapview.cpp index f2bed7349..75008bef9 100644 --- a/app/winapp/rtkplot/mapview.cpp +++ b/app/winapp/rtkplot/mapview.cpp @@ -3,19 +3,21 @@ //--------------------------------------------------------------------------- #include #pragma hdrstop -#include -#include "rtklib.h" #include "mapview.h" + +#include + #include "mapviewopt.h" #include "plotmain.h" +#include "rtklib.h" #define RTKLIB_GM_TEMP "rtkplot_gm.htm" #define RTKLIB_GM_FILE "rtkplot_gm_a.htm" #define RTKLIB_LL_TEMP "rtkplot_ll.htm" #define RTKLIB_LL_FILE "rtkplot_ll_a.htm" -#define URL_GM_API "http://maps.google.com/maps/api/js" -#define MAP_OPACITY 0.8 -#define INIT_ZOOM 12 // initial zoom level +#define URL_GM_API "http://maps.google.com/maps/api/js" +#define MAP_OPACITY 0.8 +#define INIT_ZOOM 12 // initial zoom level //--------------------------------------------------------------------------- #pragma package(smart_init) @@ -24,344 +26,308 @@ TMapView *MapView; //--------------------------------------------------------------------------- -__fastcall TMapView::TMapView(TComponent* Owner) - : TForm(Owner) -{ - MapSel=0; - Lat=Lon=0.0; - for (int i=0;i<2;i++) { - MapState[0]=MapState[1]=0; - MarkState[0]=MarkState[1]=0; - MarkPos[i][0]=MarkPos[i][1]=0.0; - } +__fastcall TMapView::TMapView(TComponent *Owner) : TForm(Owner) { + MapSel = 0; + Lat = Lon = 0.0; + for (int i = 0; i < 2; i++) { + MapState[0] = MapState[1] = 0; + MarkState[0] = MarkState[1] = 0; + MarkPos[i][0] = MarkPos[i][1] = 0.0; + } } //--------------------------------------------------------------------------- -void __fastcall TMapView::FormShow(TObject *Sender) -{ - MapSel1->Checked=!MapSel; - MapSel2->Checked=MapSel; - SelectMap(MapSel); - ShowMap(MapSel); +void __fastcall TMapView::FormShow(TObject *Sender) { + MapSel1->Checked = !MapSel; + MapSel2->Checked = MapSel; + SelectMap(MapSel); + ShowMap(MapSel); } //--------------------------------------------------------------------------- -void __fastcall TMapView::BtnCloseClick(TObject *Sender) -{ - Close(); -} +void __fastcall TMapView::BtnCloseClick(TObject *Sender) { Close(); } //--------------------------------------------------------------------------- -void __fastcall TMapView::MapSel1Click(TObject *Sender) -{ - SelectMap(0); -} +void __fastcall TMapView::MapSel1Click(TObject *Sender) { SelectMap(0); } //--------------------------------------------------------------------------- -void __fastcall TMapView::MapSel2Click(TObject *Sender) -{ - SelectMap(1); -} +void __fastcall TMapView::MapSel2Click(TObject *Sender) { SelectMap(1); } //--------------------------------------------------------------------------- -void __fastcall TMapView::BtnOptClick(TObject *Sender) -{ - MapViewOptDialog->Top=Top+Height/2-MapViewOptDialog->Height/2; - MapViewOptDialog->Left=Left+Width/2-MapViewOptDialog->Width/2; - - MapViewOptDialog->ApiKey=Plot->ApiKey; - for (int i=0;i<6;i++) for (int j=0;j<3;j++) { - MapViewOptDialog->MapStrs[i][j]=Plot->MapStrs[i][j]; +void __fastcall TMapView::BtnOptClick(TObject *Sender) { + MapViewOptDialog->Top = Top + Height / 2 - MapViewOptDialog->Height / 2; + MapViewOptDialog->Left = Left + Width / 2 - MapViewOptDialog->Width / 2; + + MapViewOptDialog->ApiKey = Plot->ApiKey; + for (int i = 0; i < 6; i++) + for (int j = 0; j < 3; j++) { + MapViewOptDialog->MapStrs[i][j] = Plot->MapStrs[i][j]; } - if (MapViewOptDialog->ShowModal()!=mrOk) return; - - Plot->ApiKey=MapViewOptDialog->ApiKey; - for (int i=0;i<6;i++) for (int j=0;j<3;j++) { - Plot->MapStrs[i][j]=MapViewOptDialog->MapStrs[i][j]; + if (MapViewOptDialog->ShowModal() != mrOk) return; + + Plot->ApiKey = MapViewOptDialog->ApiKey; + for (int i = 0; i < 6; i++) + for (int j = 0; j < 3; j++) { + Plot->MapStrs[i][j] = MapViewOptDialog->MapStrs[i][j]; } - MapState[0]=MapState[1]=0; - ShowMap(MapSel); + MapState[0] = MapState[1] = 0; + ShowMap(MapSel); } //--------------------------------------------------------------------------- -void __fastcall TMapView::BtnZoomOutClick(TObject *Sender) -{ - ExecFunc(MapSel,"ZoomOut()"); -} +void __fastcall TMapView::BtnZoomOutClick(TObject *Sender) { ExecFunc(MapSel, "ZoomOut()"); } //--------------------------------------------------------------------------- -void __fastcall TMapView::BtnZoomInClick(TObject *Sender) -{ - ExecFunc(MapSel,"ZoomIn()"); -} +void __fastcall TMapView::BtnZoomInClick(TObject *Sender) { ExecFunc(MapSel, "ZoomIn()"); } //--------------------------------------------------------------------------- -void __fastcall TMapView::BtnSyncClick(TObject *Sender) -{ - if (BtnSync->Down) { - SetCent(Lat,Lon); - } +void __fastcall TMapView::BtnSyncClick(TObject *Sender) { + if (BtnSync->Down) { + SetCent(Lat, Lon); + } } //--------------------------------------------------------------------------- -void __fastcall TMapView::FormResize(TObject *Sender) -{ - if (BtnSync->Down) { - SetCent(Lat,Lon); - } +void __fastcall TMapView::FormResize(TObject *Sender) { + if (BtnSync->Down) { + SetCent(Lat, Lon); + } } //--------------------------------------------------------------------------- -void __fastcall TMapView::ShowMap(int map) -{ - if (!map&&!MapState[0]) { - ShowMapLL(); - } - else if (map&&!MapState[1]) { - ShowMapGM(); - } - else { - UpdateMap(); - } +void __fastcall TMapView::ShowMap(int map) { + if (!map && !MapState[0]) { + ShowMapLL(); + } else if (map && !MapState[1]) { + ShowMapGM(); + } else { + UpdateMap(); + } } //--------------------------------------------------------------------------- -void __fastcall TMapView::ShowMapLL(void) -{ - AnsiString exe,dir=".",ifile,ofile; - FILE *ifp,*ofp; - char *p,*q,buff[1024]; - int i,j; - - exe=Application->ExeName; // exe directory - p=exe.c_str(); - if ((q=strrchr(p,'\\'))) { - dir=exe.SubString(1,q-p); - } - ifile=dir+"\\"+RTKLIB_LL_TEMP; - ofile=dir+"\\"+RTKLIB_LL_FILE; - - if (!(ifp=fopen(ifile.c_str(),"r"))) { - return; - } - if (!(ofp=fopen(ofile.c_str(),"w"))) { - fclose(ifp); - return; - } - while (fgets(buff,sizeof(buff),ifp)) { - fputs(buff,ofp); - if (!strstr(buff,"// start map tiles")) continue; - for (i=0,j=1;i<6;i++) { - if (Plot->MapStrs[i][0]=="") continue; - UTF8String title=Plot->MapStrs[i][0]; - UTF8String url =Plot->MapStrs[i][1]; - UTF8String attr =Plot->MapStrs[i][2]; +void __fastcall TMapView::ShowMapLL(void) { + AnsiString exe, dir = ".", ifile, ofile; + FILE *ifp, *ofp; + char *p, *q, buff[1024]; + int i, j; - fprintf(ofp,"var tile%d = L.tileLayer('%s', {\n",j,url.c_str()); - fprintf(ofp," attribution: \"%s\",\n", - attr.c_str(),title.c_str()); - fprintf(ofp," opacity: %.1f});\n",MAP_OPACITY); - j++; - } - fprintf(ofp,"var basemaps = {"); - for (i=0,j=1;i<6;i++) { - if (Plot->MapStrs[i][0]=="") continue; - UTF8String title=Plot->MapStrs[i][0]; - fprintf(ofp,"%s\"%s\":tile%d",(j==1)?"":",",title.c_str(),j); - j++; - } - fprintf(ofp,"};\n"); - } + exe = Application->ExeName; // exe directory + p = exe.c_str(); + if ((q = strrchr(p, '\\'))) { + dir = exe.SubString(1, q - p); + } + ifile = dir + "\\" + RTKLIB_LL_TEMP; + ofile = dir + "\\" + RTKLIB_LL_FILE; + + if (!(ifp = fopen(ifile.c_str(), "r"))) { + return; + } + if (!(ofp = fopen(ofile.c_str(), "w"))) { fclose(ifp); - fclose(ofp); + return; + } + while (fgets(buff, sizeof(buff), ifp)) { + fputs(buff, ofp); + if (!strstr(buff, "// start map tiles")) continue; + for (i = 0, j = 1; i < 6; i++) { + if (Plot->MapStrs[i][0] == "") continue; + UTF8String title = Plot->MapStrs[i][0]; + UTF8String url = Plot->MapStrs[i][1]; + UTF8String attr = Plot->MapStrs[i][2]; + + fprintf(ofp, "var tile%d = L.tileLayer('%s', {\n", j, url.c_str()); + fprintf(ofp, " attribution: \"%s\",\n", attr.c_str(), + title.c_str()); + fprintf(ofp, " opacity: %.1f});\n", MAP_OPACITY); + j++; + } + fprintf(ofp, "var basemaps = {"); + for (i = 0, j = 1; i < 6; i++) { + if (Plot->MapStrs[i][0] == "") continue; + UTF8String title = Plot->MapStrs[i][0]; + fprintf(ofp, "%s\"%s\":tile%d", (j == 1) ? "" : ",", title.c_str(), j); + j++; + } + fprintf(ofp, "};\n"); + } + fclose(ifp); + fclose(ofp); - UnicodeString url="file://"+ofile; - Browser1->Navigate(url.c_str()); - Timer1->Enabled=true; + UnicodeString url = "file://" + ofile; + Browser1->Navigate(url.c_str()); + Timer1->Enabled = true; } //--------------------------------------------------------------------------- -void __fastcall TMapView::Timer1Timer(TObject *Sender) -{ - if (!GetState(0)) return; - MapState[0]=1; - SetView(0,Lat,Lon,INIT_ZOOM); - AddMark(0,1,MarkPos[0][0],MarkPos[0][1],MarkState[0]); - AddMark(0,2,MarkPos[1][0],MarkPos[1][1],MarkState[1]); - Timer1->Enabled=false; +void __fastcall TMapView::Timer1Timer(TObject *Sender) { + if (!GetState(0)) return; + MapState[0] = 1; + SetView(0, Lat, Lon, INIT_ZOOM); + AddMark(0, 1, MarkPos[0][0], MarkPos[0][1], MarkState[0]); + AddMark(0, 2, MarkPos[1][0], MarkPos[1][1], MarkState[1]); + Timer1->Enabled = false; } //--------------------------------------------------------------------------- -void __fastcall TMapView::ShowMapGM(void) -{ - AnsiString exe,dir=".",ifile,ofile; - FILE *ifp, *ofp; - char *p,*q,*key=Plot->ApiKey.c_str(),buff[1024]; - - exe=Application->ExeName; // exe directory - p=exe.c_str(); - if ((q=strrchr(p,'\\'))) { - dir=exe.SubString(1,q-p); - } - ifile=dir+"\\"+RTKLIB_GM_TEMP; - ofile=dir+"\\"+RTKLIB_GM_FILE; - - if (!(ifp=fopen(ifile.c_str(),"r"))) { - return; - } - if (!(ofp=fopen(ofile.c_str(),"w"))) { - fclose(ifp); - return; - } - while (fgets(buff,sizeof(buff),ifp)) { - if (*key&&(p=strstr(buff,URL_GM_API))) { - p+=strlen(URL_GM_API); - *p++='\0'; - fprintf(ofp,"%s?key=%s&%s",buff,key,p); - } - else { - fputs(buff,ofp); - } - } +void __fastcall TMapView::ShowMapGM(void) { + AnsiString exe, dir = ".", ifile, ofile; + FILE *ifp, *ofp; + char *p, *q, *key = Plot->ApiKey.c_str(), buff[1024]; + + exe = Application->ExeName; // exe directory + p = exe.c_str(); + if ((q = strrchr(p, '\\'))) { + dir = exe.SubString(1, q - p); + } + ifile = dir + "\\" + RTKLIB_GM_TEMP; + ofile = dir + "\\" + RTKLIB_GM_FILE; + + if (!(ifp = fopen(ifile.c_str(), "r"))) { + return; + } + if (!(ofp = fopen(ofile.c_str(), "w"))) { fclose(ifp); - fclose(ofp); - - UnicodeString url="file://"+ofile; - Browser2->Navigate(url.c_str()); - Timer2->Enabled=true; + return; + } + while (fgets(buff, sizeof(buff), ifp)) { + if (*key && (p = strstr(buff, URL_GM_API))) { + p += strlen(URL_GM_API); + *p++ = '\0'; + fprintf(ofp, "%s?key=%s&%s", buff, key, p); + } else { + fputs(buff, ofp); + } + } + fclose(ifp); + fclose(ofp); + + UnicodeString url = "file://" + ofile; + Browser2->Navigate(url.c_str()); + Timer2->Enabled = true; } //--------------------------------------------------------------------------- -void __fastcall TMapView::Timer2Timer(TObject *Sender) -{ - if (!GetState(1)) return; - MapState[1]=1; - SetView(1,Lat,Lon,INIT_ZOOM); - AddMark(1,1,MarkPos[0][0],MarkPos[0][1],MarkState[0]); - AddMark(1,2,MarkPos[1][0],MarkPos[1][1],MarkState[1]); - Timer2->Enabled=false; +void __fastcall TMapView::Timer2Timer(TObject *Sender) { + if (!GetState(1)) return; + MapState[1] = 1; + SetView(1, Lat, Lon, INIT_ZOOM); + AddMark(1, 1, MarkPos[0][0], MarkPos[0][1], MarkState[0]); + AddMark(1, 2, MarkPos[1][0], MarkPos[1][1], MarkState[1]); + Timer2->Enabled = false; } //--------------------------------------------------------------------------- -void __fastcall TMapView::SetView(int map, double lat, double lon, int zoom) -{ - UTF8String func; +void __fastcall TMapView::SetView(int map, double lat, double lon, int zoom) { + UTF8String func; - ExecFunc(map,func.sprintf("SetView(%.9f,%.9f,%d)",lat,lon,zoom)); + ExecFunc(map, func.sprintf("SetView(%.9f,%.9f,%d)", lat, lon, zoom)); } //--------------------------------------------------------------------------- -void __fastcall TMapView::AddMark(int map, int index, double lat, double lon, - int state) -{ - UTF8String func; +void __fastcall TMapView::AddMark(int map, int index, double lat, double lon, int state) { + UTF8String func; - func.sprintf("AddMark(%.9f,%.9f,'SOL%d','SOLUTION %d')",lat,lon,index,index); - ExecFunc(map,func); - if (state) func.sprintf("ShowMark('SOL%d')",index); - else func.sprintf("HideMark('SOL%d')",index); - ExecFunc(map,func); -} -//--------------------------------------------------------------------------- -void __fastcall TMapView::UpdateMap(void) -{ - SetCent(Lat,Lon); - for (int i=0;i<2;i++) { - SetMark(i+1,MarkPos[i][0],MarkPos[i][1]); - if (MarkState[i]) ShowMark(i+1); else HideMark(i+1); - } + func.sprintf("AddMark(%.9f,%.9f,'SOL%d','SOLUTION %d')", lat, lon, index, index); + ExecFunc(map, func); + if (state) + func.sprintf("ShowMark('SOL%d')", index); + else + func.sprintf("HideMark('SOL%d')", index); + ExecFunc(map, func); } //--------------------------------------------------------------------------- -void __fastcall TMapView::SelectMap(int map) -{ - if (!map) { - Panel22->Visible=false; - Panel21->Visible=true; - } - else { - Panel21->Visible=false; - Panel22->Visible=true; - } - MapSel=map; - ShowMap(map); +void __fastcall TMapView::UpdateMap(void) { + SetCent(Lat, Lon); + for (int i = 0; i < 2; i++) { + SetMark(i + 1, MarkPos[i][0], MarkPos[i][1]); + if (MarkState[i]) + ShowMark(i + 1); + else + HideMark(i + 1); + } } //--------------------------------------------------------------------------- -void __fastcall TMapView::SetCent(double lat, double lon) -{ - UTF8String func; - - Lat=lat; - Lon=lon; - if (BtnSync->Down) { - ExecFunc(MapSel,func.sprintf("SetCent(%.9f,%.9f)",lat,lon)); - } +void __fastcall TMapView::SelectMap(int map) { + if (!map) { + Panel22->Visible = false; + Panel21->Visible = true; + } else { + Panel21->Visible = false; + Panel22->Visible = true; + } + MapSel = map; + ShowMap(map); } //--------------------------------------------------------------------------- -void __fastcall TMapView::SetMark(int index, double lat, double lon) -{ - UTF8String func; - - MarkPos[index-1][0]=lat; - MarkPos[index-1][1]=lon; - func.sprintf("PosMark(%.9f,%.9f,'SOL%d')",lat,lon,index); - ExecFunc(MapSel,func); +void __fastcall TMapView::SetCent(double lat, double lon) { + UTF8String func; + + Lat = lat; + Lon = lon; + if (BtnSync->Down) { + ExecFunc(MapSel, func.sprintf("SetCent(%.9f,%.9f)", lat, lon)); + } } //--------------------------------------------------------------------------- -void __fastcall TMapView::ShowMark(int index) -{ - UTF8String func; - - MarkState[index-1]=1; - ExecFunc(MapSel,func.sprintf("ShowMark('SOL%d')",index)); +void __fastcall TMapView::SetMark(int index, double lat, double lon) { + UTF8String func; + + MarkPos[index - 1][0] = lat; + MarkPos[index - 1][1] = lon; + func.sprintf("PosMark(%.9f,%.9f,'SOL%d')", lat, lon, index); + ExecFunc(MapSel, func); } //--------------------------------------------------------------------------- -void __fastcall TMapView::HideMark(int index) -{ - UTF8String func; - - MarkState[index-1]=0; - ExecFunc(MapSel,func.sprintf("HideMark('SOL%d')",index)); +void __fastcall TMapView::ShowMark(int index) { + UTF8String func; + + MarkState[index - 1] = 1; + ExecFunc(MapSel, func.sprintf("ShowMark('SOL%d')", index)); } //--------------------------------------------------------------------------- -int __fastcall TMapView::GetState(int map) -{ - TCppWebBrowser *browser[]={Browser1,Browser2}; - IHTMLDocument3 *doc=NULL; - IHTMLElement *ele1=NULL; - VARIANT var; - int state=0; - - if (!browser[map]->Document) return 0; - browser[map]->Document->QueryInterface(IID_IHTMLDocument3,(void **)&doc); - if (!doc) return 0; - BSTR bstr1=SysAllocString(L"state"); - doc->getElementById(bstr1,&ele1); - SysFreeString(bstr1); - doc->Release(); - if (!ele1) return 0; - - VariantInit(&var); - BSTR bstr2=SysAllocString(L"value"); - if (ele1->getAttribute(bstr2,0,&var)!=S_OK) { - SysFreeString(bstr2); - VariantClear(&var); - return 0; - } - SysFreeString(bstr2); - swscanf(var.bstrVal,L"%d",&state); - VariantClear(&var); - return state; +void __fastcall TMapView::HideMark(int index) { + UTF8String func; + + MarkState[index - 1] = 0; + ExecFunc(MapSel, func.sprintf("HideMark('SOL%d')", index)); } //--------------------------------------------------------------------------- -int __fastcall TMapView::ExecFunc(int map, UTF8String func) -{ - TCppWebBrowser *browser[]={Browser1,Browser2}; - IHTMLWindow2 *win; - IHTMLDocument2 *doc=NULL; - VARIANT var; - HRESULT hr; - wchar_t func_w[1024]={0}; - - if (!browser[map]->Document) return 0; - browser[map]->Document->QueryInterface(IID_IHTMLDocument2,(void **)&doc); - if (!doc) return 0; - hr=doc->get_parentWindow(&win); - doc->Release(); - if (hr!=S_OK) return 0; - - VariantInit(&var); - ::MultiByteToWideChar(CP_UTF8,0,func.c_str(),-1,func_w,512); - BSTR bstr1=SysAllocString(func_w); - BSTR bstr2=SysAllocString(L"javascript"); - hr=win->execScript(bstr1,bstr2,&var); +int __fastcall TMapView::GetState(int map) { + TCppWebBrowser *browser[] = {Browser1, Browser2}; + IHTMLDocument3 *doc = NULL; + IHTMLElement *ele1 = NULL; + VARIANT var; + int state = 0; + + if (!browser[map]->Document) return 0; + browser[map]->Document->QueryInterface(IID_IHTMLDocument3, (void **)&doc); + if (!doc) return 0; + BSTR bstr1 = SysAllocString(L"state"); + doc->getElementById(bstr1, &ele1); + SysFreeString(bstr1); + doc->Release(); + if (!ele1) return 0; + + VariantInit(&var); + BSTR bstr2 = SysAllocString(L"value"); + if (ele1->getAttribute(bstr2, 0, &var) != S_OK) { SysFreeString(bstr2); VariantClear(&var); - return 1; + return 0; + } + SysFreeString(bstr2); + swscanf(var.bstrVal, L"%d", &state); + VariantClear(&var); + return state; } //--------------------------------------------------------------------------- +int __fastcall TMapView::ExecFunc(int map, UTF8String func) { + TCppWebBrowser *browser[] = {Browser1, Browser2}; + IHTMLWindow2 *win; + IHTMLDocument2 *doc = NULL; + VARIANT var; + HRESULT hr; + wchar_t func_w[1024] = {0}; + if (!browser[map]->Document) return 0; + browser[map]->Document->QueryInterface(IID_IHTMLDocument2, (void **)&doc); + if (!doc) return 0; + hr = doc->get_parentWindow(&win); + doc->Release(); + if (hr != S_OK) return 0; + VariantInit(&var); + ::MultiByteToWideChar(CP_UTF8, 0, func.c_str(), -1, func_w, 512); + BSTR bstr1 = SysAllocString(func_w); + BSTR bstr2 = SysAllocString(L"javascript"); + hr = win->execScript(bstr1, bstr2, &var); + SysFreeString(bstr2); + VariantClear(&var); + return 1; +} +//--------------------------------------------------------------------------- diff --git a/app/winapp/rtkplot/mapview.h b/app/winapp/rtkplot/mapview.h index e70470919..958bb52cd 100644 --- a/app/winapp/rtkplot/mapview.h +++ b/app/winapp/rtkplot/mapview.h @@ -3,71 +3,68 @@ #define mapviewH //--------------------------------------------------------------------------- #include +#include #include -#include -#include -#include "SHDocVw_OCX.h" #include +#include #include -#include +#include + +#include "SHDocVw_OCX.h" //--------------------------------------------------------------------------- -class TMapView : public TForm -{ -__published: - TPanel *Panel1; - TPanel *Panel2; - TCppWebBrowser *Browser1; - TPanel *Panel5; - TButton *BtnClose; - TTimer *Timer1; - TSpeedButton *BtnSync; - TSpeedButton *BtnZoomIn; - TSpeedButton *BtnZoomOut; - TButton *BtnOpt; - TCppWebBrowser *Browser2; - TRadioButton *MapSel1; - TRadioButton *MapSel2; - TPanel *Panel3; - TTimer *Timer2; - TPanel *Panel21; - TPanel *Panel22; - void __fastcall BtnCloseClick(TObject *Sender); - void __fastcall Timer1Timer(TObject *Sender); - void __fastcall BtnZoomOutClick(TObject *Sender); - void __fastcall BtnZoomInClick(TObject *Sender); - void __fastcall BtnSyncClick(TObject *Sender); - void __fastcall FormResize(TObject *Sender); - void __fastcall FormShow(TObject *Sender); - void __fastcall BtnOptClick(TObject *Sender); - void __fastcall MapSel1Click(TObject *Sender); - void __fastcall MapSel2Click(TObject *Sender); - void __fastcall Timer2Timer(TObject *Sender); +class TMapView : public TForm { + __published : TPanel *Panel1; + TPanel *Panel2; + TCppWebBrowser *Browser1; + TPanel *Panel5; + TButton *BtnClose; + TTimer *Timer1; + TSpeedButton *BtnSync; + TSpeedButton *BtnZoomIn; + TSpeedButton *BtnZoomOut; + TButton *BtnOpt; + TCppWebBrowser *Browser2; + TRadioButton *MapSel1; + TRadioButton *MapSel2; + TPanel *Panel3; + TTimer *Timer2; + TPanel *Panel21; + TPanel *Panel22; + void __fastcall BtnCloseClick(TObject *Sender); + void __fastcall Timer1Timer(TObject *Sender); + void __fastcall BtnZoomOutClick(TObject *Sender); + void __fastcall BtnZoomInClick(TObject *Sender); + void __fastcall BtnSyncClick(TObject *Sender); + void __fastcall FormResize(TObject *Sender); + void __fastcall FormShow(TObject *Sender); + void __fastcall BtnOptClick(TObject *Sender); + void __fastcall MapSel1Click(TObject *Sender); + void __fastcall MapSel2Click(TObject *Sender); + void __fastcall Timer2Timer(TObject *Sender); + + private: + int MapState[2], MarkState[2]; + double Lat, Lon; + double MarkPos[2][2]; + void __fastcall ShowMapLL(void); + void __fastcall ShowMapGM(void); + void __fastcall ShowMap(int map); + void __fastcall SetView(int map, double lat, double lon, int zoom); + void __fastcall AddMark(int map, int index, double lat, double lon, int state); + void __fastcall UpdateMap(void); + void __fastcall SelectMap(int map); + int __fastcall GetState(int map); + int __fastcall ExecFunc(int map, UTF8String func); -private: - int MapState[2],MarkState[2]; - double Lat,Lon; - double MarkPos[2][2]; - - void __fastcall ShowMapLL(void); - void __fastcall ShowMapGM(void); - void __fastcall ShowMap(int map); - void __fastcall SetView(int map, double lat, double lon, int zoom); - void __fastcall AddMark(int map, int index, double lat, double lon, - int state); - void __fastcall UpdateMap(void); - void __fastcall SelectMap(int map); - int __fastcall GetState(int map); - int __fastcall ExecFunc(int map, UTF8String func); + public: + int MapSel; -public: - int MapSel; - - __fastcall TMapView(TComponent* Owner); - void __fastcall SetCent(double lat, double lon); - void __fastcall SetMark(int index, double lat, double lon); - void __fastcall ShowMark(int index); - void __fastcall HideMark(int index); + __fastcall TMapView(TComponent *Owner); + void __fastcall SetCent(double lat, double lon); + void __fastcall SetMark(int index, double lat, double lon); + void __fastcall ShowMark(int index); + void __fastcall HideMark(int index); }; //--------------------------------------------------------------------------- extern PACKAGE TMapView *MapView; diff --git a/app/winapp/rtkplot/mapviewopt.cpp b/app/winapp/rtkplot/mapviewopt.cpp index 891e1cb2b..4becaba7c 100644 --- a/app/winapp/rtkplot/mapviewopt.cpp +++ b/app/winapp/rtkplot/mapviewopt.cpp @@ -3,64 +3,49 @@ #include #pragma hdrstop -#include "viewer.h" #include "mapviewopt.h" + +#include "viewer.h" //--------------------------------------------------------------------------- #pragma package(smart_init) #pragma resource "*.dfm" TMapViewOptDialog *MapViewOptDialog; //--------------------------------------------------------------------------- -__fastcall TMapViewOptDialog::TMapViewOptDialog(TComponent* Owner) - : TForm(Owner) -{ -} +__fastcall TMapViewOptDialog::TMapViewOptDialog(TComponent *Owner) : TForm(Owner) {} //--------------------------------------------------------------------------- -void __fastcall TMapViewOptDialog::FormShow(TObject *Sender) -{ - TEdit *titles[]={ - MapTitle1,MapTitle2,MapTitle3,MapTitle4,MapTitle5,MapTitle6 - }; - TEdit *tiles[]={ - MapTile1,MapTile2,MapTile3,MapTile4,MapTile5,MapTile6 - }; - for (int i=0;i<6;i++) { - titles[i]->Text=MapStrs[i][0]; - tiles [i]->Text=MapStrs[i][1]; - } - EditApiKey->Text=ApiKey; +void __fastcall TMapViewOptDialog::FormShow(TObject *Sender) { + TEdit *titles[] = {MapTitle1, MapTitle2, MapTitle3, MapTitle4, MapTitle5, MapTitle6}; + TEdit *tiles[] = {MapTile1, MapTile2, MapTile3, MapTile4, MapTile5, MapTile6}; + for (int i = 0; i < 6; i++) { + titles[i]->Text = MapStrs[i][0]; + tiles[i]->Text = MapStrs[i][1]; + } + EditApiKey->Text = ApiKey; } //--------------------------------------------------------------------------- -void __fastcall TMapViewOptDialog::BtnOkClick(TObject *Sender) -{ - TEdit *titles[]={ - MapTitle1,MapTitle2,MapTitle3,MapTitle4,MapTitle5,MapTitle6 - }; - TEdit *tiles[]={ - MapTile1,MapTile2,MapTile3,MapTile4,MapTile5,MapTile6 - }; - for (int i=0;i<6;i++) { - MapStrs[i][0]=titles[i]->Text; - MapStrs[i][1]=tiles [i]->Text; - } - ApiKey=EditApiKey->Text; +void __fastcall TMapViewOptDialog::BtnOkClick(TObject *Sender) { + TEdit *titles[] = {MapTitle1, MapTitle2, MapTitle3, MapTitle4, MapTitle5, MapTitle6}; + TEdit *tiles[] = {MapTile1, MapTile2, MapTile3, MapTile4, MapTile5, MapTile6}; + for (int i = 0; i < 6; i++) { + MapStrs[i][0] = titles[i]->Text; + MapStrs[i][1] = tiles[i]->Text; + } + ApiKey = EditApiKey->Text; } //--------------------------------------------------------------------------- -void __fastcall TMapViewOptDialog::BtnNotesClick(TObject *Sender) -{ - AnsiString file; - TTextViewer *viewer; - char dir[1024],*p; - - ::GetModuleFileName(NULL,dir,sizeof(dir)); - if ((p=strrchr(dir,'\\'))) *p='\0'; - file=dir; - file+="\\gmview_notes.txt"; - viewer=new TTextViewer(Application); - viewer->Caption=file; - viewer->Option=0; - viewer->Show(); - viewer->Read(file); +void __fastcall TMapViewOptDialog::BtnNotesClick(TObject *Sender) { + AnsiString file; + TTextViewer *viewer; + char dir[1024], *p; + + ::GetModuleFileName(NULL, dir, sizeof(dir)); + if ((p = strrchr(dir, '\\'))) *p = '\0'; + file = dir; + file += "\\gmview_notes.txt"; + viewer = new TTextViewer(Application); + viewer->Caption = file; + viewer->Option = 0; + viewer->Show(); + viewer->Read(file); } //--------------------------------------------------------------------------- - - diff --git a/app/winapp/rtkplot/mapviewopt.h b/app/winapp/rtkplot/mapviewopt.h index d8396a344..c00c5a166 100644 --- a/app/winapp/rtkplot/mapviewopt.h +++ b/app/winapp/rtkplot/mapviewopt.h @@ -4,42 +4,41 @@ #define mapviewoptH //--------------------------------------------------------------------------- #include +#include #include -#include #include -#include +#include //--------------------------------------------------------------------------- -class TMapViewOptDialog : public TForm -{ -__published: - TButton *BtnCancel; - TEdit *EditApiKey; - TButton *BtnOk; - TLabel *Label1; - TEdit *MapTitle1; - TEdit *MapTile1; - TLabel *Label2; - TLabel *Label3; - TEdit *MapTitle2; - TEdit *MapTile2; - TEdit *MapTitle3; - TEdit *MapTile3; - TEdit *MapTitle4; - TEdit *MapTile4; - TLabel *Label5; - TEdit *MapTitle5; - TEdit *MapTile5; - TEdit *MapTitle6; - TEdit *MapTile6; - TSpeedButton *BtnNotes; - void __fastcall FormShow(TObject *Sender); - void __fastcall BtnOkClick(TObject *Sender); - void __fastcall BtnNotesClick(TObject *Sender); -private: -public: - UTF8String MapStrs[6][3]; - UTF8String ApiKey; - __fastcall TMapViewOptDialog(TComponent* Owner); +class TMapViewOptDialog : public TForm { + __published : TButton *BtnCancel; + TEdit *EditApiKey; + TButton *BtnOk; + TLabel *Label1; + TEdit *MapTitle1; + TEdit *MapTile1; + TLabel *Label2; + TLabel *Label3; + TEdit *MapTitle2; + TEdit *MapTile2; + TEdit *MapTitle3; + TEdit *MapTile3; + TEdit *MapTitle4; + TEdit *MapTile4; + TLabel *Label5; + TEdit *MapTitle5; + TEdit *MapTile5; + TEdit *MapTitle6; + TEdit *MapTile6; + TSpeedButton *BtnNotes; + void __fastcall FormShow(TObject *Sender); + void __fastcall BtnOkClick(TObject *Sender); + void __fastcall BtnNotesClick(TObject *Sender); + + private: + public: + UTF8String MapStrs[6][3]; + UTF8String ApiKey; + __fastcall TMapViewOptDialog(TComponent *Owner); }; //--------------------------------------------------------------------------- extern PACKAGE TMapViewOptDialog *MapViewOptDialog; diff --git a/app/winapp/rtkplot/plotcmn.cpp b/app/winapp/rtkplot/plotcmn.cpp index 921f5ae71..96380f6ba 100644 --- a/app/winapp/rtkplot/plotcmn.cpp +++ b/app/winapp/rtkplot/plotcmn.cpp @@ -1,603 +1,584 @@ //--------------------------------------------------------------------------- // plotcmn.c: rtkplot common functions //--------------------------------------------------------------------------- -#include "rtklib.h" #include "plotmain.h" +#include "rtklib.h" -#define SQR(x) ((x)*(x)) +#define SQR(x) ((x) * (x)) //--------------------------------------------------------------------------- extern "C" { -int showmsg(const char *format,...) {return 0;} +int showmsg(const char *format, ...) { return 0; } } //--------------------------------------------------------------------------- -const char *PTypes[]={ - "Gnd Trk","Position","Velocity","Accel","NSat","Skyplot","DOP/NSat", - "Residuals","Resid-EL","Sat Vis","Skyplot obs","DOP/NSat obs","SNR/MP/EL", - "SNR/MP-EL","MP-Skyplot","" -}; +const char *PTypes[] = {"Gnd Trk", "Position", "Velocity", "Accel", + "NSat", "Skyplot", "DOP/NSat", "Residuals", + "Resid-EL", "Sat Vis", "Skyplot obs", "DOP/NSat obs", + "SNR/MP/EL", "SNR/MP-EL", "MP-Skyplot", ""}; // show message in status-bar ----------------------------------------------- -void __fastcall TPlot::ShowMsg(UTF8String msg) -{ - Message1->Caption=msg; - Panel21->Repaint(); +void __fastcall TPlot::ShowMsg(UTF8String msg) { + Message1->Caption = msg; + Panel21->Repaint(); } // execute command ---------------------------------------------------------- -int __fastcall TPlot::ExecCmd(AnsiString cmd) -{ - PROCESS_INFORMATION info; - STARTUPINFO si={0}; - si.cb=sizeof(si); - char *p=cmd.c_str(); - - if (!CreateProcess(NULL,p,NULL,NULL,false,CREATE_NO_WINDOW,NULL,NULL,&si, - &info)) return 0; - CloseHandle(info.hProcess); - CloseHandle(info.hThread); - return 1; +int __fastcall TPlot::ExecCmd(AnsiString cmd) { + PROCESS_INFORMATION info; + STARTUPINFO si = {0}; + si.cb = sizeof(si); + char *p = cmd.c_str(); + + if (!CreateProcess(NULL, p, NULL, NULL, false, CREATE_NO_WINDOW, NULL, NULL, &si, &info)) + return 0; + CloseHandle(info.hProcess); + CloseHandle(info.hThread); + return 1; } // get time span and time interval ------------------------------------------ -void __fastcall TPlot::TimeSpan(gtime_t *ts, gtime_t *te, double *tint) -{ - gtime_t t0={0}; - - trace(3,"TimeSpan\n"); - - *ts=*te=t0; *tint=0.0; - if (TimeEna[0]) *ts=TimeStart; - if (TimeEna[1]) *te=TimeEnd; - if (TimeEna[2]) *tint=TimeInt; +void __fastcall TPlot::TimeSpan(gtime_t *ts, gtime_t *te, double *tint) { + gtime_t t0 = {0}; + + trace(3, "TimeSpan\n"); + + *ts = *te = t0; + *tint = 0.0; + if (TimeEna[0]) *ts = TimeStart; + if (TimeEna[1]) *te = TimeEnd; + if (TimeEna[2]) *tint = TimeInt; } // get position regarding time ---------------------------------------------- -double __fastcall TPlot::TimePos(gtime_t time) -{ - double tow; - int week; - - if (TimeLabel<=1) { // www/ssss or gpst - tow=time2gpst(time,&week); - } - else if (TimeLabel==2) { // UTC - tow=time2gpst(gpst2utc(time),&week); - } - else { // JST - tow=time2gpst(timeadd(gpst2utc(time),9*3600.0),&week); - } - return tow+(week-Week)*86400.0*7; +double __fastcall TPlot::TimePos(gtime_t time) { + double tow; + int week; + + if (TimeLabel <= 1) { // www/ssss or gpst + tow = time2gpst(time, &week); + } else if (TimeLabel == 2) { // UTC + tow = time2gpst(gpst2utc(time), &week); + } else { // JST + tow = time2gpst(timeadd(gpst2utc(time), 9 * 3600.0), &week); + } + return tow + (week - Week) * 86400.0 * 7; } // show legand in status-bar ------------------------------------------------ -void __fastcall TPlot::ShowLegend(UTF8String *msgs) -{ - TLabel *ql[]={QL1,QL2,QL3,QL4,QL5,QL6,QL7}; - int i,sel=!BtnSol1->Down&&BtnSol2->Down?1:0; - - trace(3,"ShowLegend\n"); - - for (i=0;i<7;i++) { - if (!msgs||msgs[i]=="") { - ql[i]->Caption=" "; ql[i]->Width=1; - } - else { - ql[i]->Caption=msgs[i]; - ql[i]->Font->Color=MColor[sel][i+1]; - } - } +void __fastcall TPlot::ShowLegend(UTF8String *msgs) { + TLabel *ql[] = {QL1, QL2, QL3, QL4, QL5, QL6, QL7}; + int i, sel = !BtnSol1->Down && BtnSol2->Down ? 1 : 0; + + trace(3, "ShowLegend\n"); + + for (i = 0; i < 7; i++) { + if (!msgs || msgs[i] == "") { + ql[i]->Caption = " "; + ql[i]->Width = 1; + } else { + ql[i]->Caption = msgs[i]; + ql[i]->Font->Color = MColor[sel][i + 1]; + } + } } // show observation legand in status-bar ------------------------------------------------ -void __fastcall TPlot::ShowObsLegend(UTF8String *msgs) -{ - TLabel *ql[]={QL1,QL2,QL3,QL4,QL5,QL6,QL7}; - int i,sel=!BtnSol1->Down&&BtnSol2->Down?1:0; - - trace(3,"ShowLegend\n"); - - for (i=0;i<7;i++) { - if (!msgs||msgs[i]=="") { - ql[i]->Caption=" "; ql[i]->Width=1; - } - else { - ql[i]->Caption=msgs[i]; - ql[i]->Font->Color=MColor[sel][3+i-(i>2?5:0)]; - } - } +void __fastcall TPlot::ShowObsLegend(UTF8String *msgs) { + TLabel *ql[] = {QL1, QL2, QL3, QL4, QL5, QL6, QL7}; + int i, sel = !BtnSol1->Down && BtnSol2->Down ? 1 : 0; + + trace(3, "ShowLegend\n"); + + for (i = 0; i < 7; i++) { + if (!msgs || msgs[i] == "") { + ql[i]->Caption = " "; + ql[i]->Width = 1; + } else { + ql[i]->Caption = msgs[i]; + ql[i]->Font->Color = MColor[sel][3 + i - (i > 2 ? 5 : 0)]; + } + } } // get current cursor position ---------------------------------------------- -int __fastcall TPlot::GetCurrentPos(double *rr) -{ - sol_t *data; - int i,sel=!BtnSol1->Down&&BtnSol2->Down?1:0; - - trace(3,"GetCurrentPos\n"); - - if (PLOT_OBS<=PlotType&&PlotType<=PLOT_DOP) return 0; - if (!(data=getsol(SolData+sel,SolIndex[sel]))) return 0; - if (data->type) return 0; - for (i=0;i<3;i++) rr[i]=data->rr[i]; - return 1; +int __fastcall TPlot::GetCurrentPos(double *rr) { + sol_t *data; + int i, sel = !BtnSol1->Down && BtnSol2->Down ? 1 : 0; + + trace(3, "GetCurrentPos\n"); + + if (PLOT_OBS <= PlotType && PlotType <= PLOT_DOP) return 0; + if (!(data = getsol(SolData + sel, SolIndex[sel]))) return 0; + if (data->type) return 0; + for (i = 0; i < 3; i++) rr[i] = data->rr[i]; + return 1; } // get center position of plot ---------------------------------------------- -int __fastcall TPlot::GetCenterPos(double *rr) -{ - double xc,yc,opos[3],pos[3],enu[3]={0},dr[3]; - int i,j; - - trace(3,"GetCenterPos\n"); - - if (PLOT_OBS<=PlotType&&PlotType<=PLOT_DOP&&PlotType!=PLOT_TRK) return 0; - if (norm(OPos,3)<=0.0) return 0; - GraphT->GetCent(xc,yc); - ecef2pos(OPos,opos); - enu[0]=xc; - enu[1]=yc; - for (i=0;i<6;i++) { - enu2ecef(opos,enu,dr); - for (j=0;j<3;j++) rr[j]=OPos[j]+dr[j]; - ecef2pos(rr,pos); - enu[2]-=pos[2]; - } - return 1; +int __fastcall TPlot::GetCenterPos(double *rr) { + double xc, yc, opos[3], pos[3], enu[3] = {0}, dr[3]; + int i, j; + + trace(3, "GetCenterPos\n"); + + if (PLOT_OBS <= PlotType && PlotType <= PLOT_DOP && PlotType != PLOT_TRK) return 0; + if (norm(OPos, 3) <= 0.0) return 0; + GraphT->GetCent(xc, yc); + ecef2pos(OPos, opos); + enu[0] = xc; + enu[1] = yc; + for (i = 0; i < 6; i++) { + enu2ecef(opos, enu, dr); + for (j = 0; j < 3; j++) rr[j] = OPos[j] + dr[j]; + ecef2pos(rr, pos); + enu[2] -= pos[2]; + } + return 1; } // get position, velocity or accel from solutions --------------------------- -TIMEPOS * __fastcall TPlot::SolToPos(solbuf_t *sol, int index, int qflag, int type) -{ - TIMEPOS *pos,*vel,*acc; - gtime_t ts={0}; - sol_t *data; - double tint,xyz[3],xyzs[4]; - int i; - - trace(3,"SolToPos: n=%d\n",sol->n); - - pos=new TIMEPOS(index<0?sol->n:3,1); - - if (index>=0) { - if (type==1&&index>sol->n-2) index=sol->n-2; - if (type==2&&index>sol->n-3) index=sol->n-3; - } - for (i=(index<0)?0:index;(data=getsol(sol,i));i++) { - - tint=TimeEna[2]?TimeInt:0.0; - - if (index<0&&!screent(data->time,ts,ts,tint)) continue; - if (qflag&&data->stat!=qflag) continue; - - PosToXyz(data->time,data->rr,data->type,xyz); - CovToXyz(data->rr,data->qr,data->type,xyzs); - if (xyz[2]<-RE_WGS84) continue; - - pos->t [pos->n]=data->time; - pos->x [pos->n]=xyz [0]; - pos->y [pos->n]=xyz [1]; - pos->z [pos->n]=xyz [2]; - pos->xs [pos->n]=xyzs[0]; // var x^2 - pos->ys [pos->n]=xyzs[1]; // var y^2 - pos->zs [pos->n]=xyzs[2]; // var z^2 - pos->xys[pos->n]=xyzs[3]; // cov xy - pos->q [pos->n]=data->stat; - pos->n++; - - if (index>=0&&pos->n>=3) break; - } - if (type!=1&&type!=2) return pos; // position - - vel=pos->tdiff(); - delete pos; - if (type==1) return vel; // velocity - - acc=vel->tdiff(); - delete vel; - return acc; // acceleration +TIMEPOS *__fastcall TPlot::SolToPos(solbuf_t *sol, int index, int qflag, int type) { + TIMEPOS *pos, *vel, *acc; + gtime_t ts = {0}; + sol_t *data; + double tint, xyz[3], xyzs[4]; + int i; + + trace(3, "SolToPos: n=%d\n", sol->n); + + pos = new TIMEPOS(index < 0 ? sol->n : 3, 1); + + if (index >= 0) { + if (type == 1 && index > sol->n - 2) index = sol->n - 2; + if (type == 2 && index > sol->n - 3) index = sol->n - 3; + } + for (i = (index < 0) ? 0 : index; (data = getsol(sol, i)); i++) { + tint = TimeEna[2] ? TimeInt : 0.0; + + if (index < 0 && !screent(data->time, ts, ts, tint)) continue; + if (qflag && data->stat != qflag) continue; + + PosToXyz(data->time, data->rr, data->type, xyz); + CovToXyz(data->rr, data->qr, data->type, xyzs); + if (xyz[2] < -RE_WGS84) continue; + + pos->t[pos->n] = data->time; + pos->x[pos->n] = xyz[0]; + pos->y[pos->n] = xyz[1]; + pos->z[pos->n] = xyz[2]; + pos->xs[pos->n] = xyzs[0]; // var x^2 + pos->ys[pos->n] = xyzs[1]; // var y^2 + pos->zs[pos->n] = xyzs[2]; // var z^2 + pos->xys[pos->n] = xyzs[3]; // cov xy + pos->q[pos->n] = data->stat; + pos->n++; + + if (index >= 0 && pos->n >= 3) break; + } + if (type != 1 && type != 2) return pos; // position + + vel = pos->tdiff(); + delete pos; + if (type == 1) return vel; // velocity + + acc = vel->tdiff(); + delete vel; + return acc; // acceleration } // get number of satellites, age and ratio from solutions ------------------- -TIMEPOS * __fastcall TPlot::SolToNsat(solbuf_t *sol, int index, int qflag) -{ - TIMEPOS *ns; - sol_t *data; - int i; - - trace(3,"SolToNsat: n=%d\n",sol->n); - - ns=new TIMEPOS(index<0?sol->n:3,1); - - for (i=(index<0)?0:index;(data=getsol(sol,i));i++) { - - if (qflag&&data->stat!=qflag) continue; - - ns->t[ns->n]=data->time; - ns->x[ns->n]=data->ns; - ns->y[ns->n]=data->age; - ns->z[ns->n]=data->ratio; - ns->q[ns->n]=data->stat; - ns->n++; - - if (index>=0&&i>=2) break; - } - return ns; +TIMEPOS *__fastcall TPlot::SolToNsat(solbuf_t *sol, int index, int qflag) { + TIMEPOS *ns; + sol_t *data; + int i; + + trace(3, "SolToNsat: n=%d\n", sol->n); + + ns = new TIMEPOS(index < 0 ? sol->n : 3, 1); + + for (i = (index < 0) ? 0 : index; (data = getsol(sol, i)); i++) { + if (qflag && data->stat != qflag) continue; + + ns->t[ns->n] = data->time; + ns->x[ns->n] = data->ns; + ns->y[ns->n] = data->age; + ns->z[ns->n] = data->ratio; + ns->q[ns->n] = data->stat; + ns->n++; + + if (index >= 0 && i >= 2) break; + } + return ns; } // transform solution to xyz-terms ------------------------------------------ -void __fastcall TPlot::PosToXyz(gtime_t time, const double *rr, int type, - double *xyz) -{ - double opos[3],pos[3],r[3],enu[3]; - int i; - - trace(4,"PosToXyz:\n"); - - if (type==0) { // xyz - for (i=0;i<3;i++) { - opos[i]=OPos[i]; - if (time.time==0.0||OEpoch.time==0.0) continue; - opos[i]+=OVel[i]*timediff(time,OEpoch); - } - for (i=0;i<3;i++) r[i]=rr[i]-opos[i]; - ecef2pos(opos,pos); - ecef2enu(pos,r,enu); - xyz[0]=enu[0]; - xyz[1]=enu[1]; - xyz[2]=enu[2]; - } - else { // enu - xyz[0]=rr[0]; - xyz[1]=rr[1]; - xyz[2]=rr[2]; - } +void __fastcall TPlot::PosToXyz(gtime_t time, const double *rr, int type, double *xyz) { + double opos[3], pos[3], r[3], enu[3]; + int i; + + trace(4, "PosToXyz:\n"); + + if (type == 0) { // xyz + for (i = 0; i < 3; i++) { + opos[i] = OPos[i]; + if (time.time == 0.0 || OEpoch.time == 0.0) continue; + opos[i] += OVel[i] * timediff(time, OEpoch); + } + for (i = 0; i < 3; i++) r[i] = rr[i] - opos[i]; + ecef2pos(opos, pos); + ecef2enu(pos, r, enu); + xyz[0] = enu[0]; + xyz[1] = enu[1]; + xyz[2] = enu[2]; + } else { // enu + xyz[0] = rr[0]; + xyz[1] = rr[1]; + xyz[2] = rr[2]; + } } // transform covariance to xyz-terms ---------------------------------------- -void __fastcall TPlot::CovToXyz(const double *rr, const float *qr, int type, - double *xyzs) -{ - double pos[3],P[9],Q[9]; - - trace(4,"CovToXyz:\n"); - - if (type==0) { // xyz - ecef2pos(rr,pos); - P[0]=qr[0]; - P[4]=qr[1]; - P[8]=qr[2]; - P[1]=P[3]=qr[3]; - P[5]=P[7]=qr[4]; - P[2]=P[6]=qr[5]; - covenu(pos,P,Q); - xyzs[0]=Q[0]; - xyzs[1]=Q[4]; - xyzs[2]=Q[8]; - xyzs[3]=Q[1]; - } - else { // enu - xyzs[0]=qr[0]; - xyzs[1]=qr[1]; - xyzs[2]=qr[2]; - xyzs[3]=qr[3]; - } +void __fastcall TPlot::CovToXyz(const double *rr, const float *qr, int type, double *xyzs) { + double pos[3], P[9], Q[9]; + + trace(4, "CovToXyz:\n"); + + if (type == 0) { // xyz + ecef2pos(rr, pos); + P[0] = qr[0]; + P[4] = qr[1]; + P[8] = qr[2]; + P[1] = P[3] = qr[3]; + P[5] = P[7] = qr[4]; + P[2] = P[6] = qr[5]; + covenu(pos, P, Q); + xyzs[0] = Q[0]; + xyzs[1] = Q[4]; + xyzs[2] = Q[8]; + xyzs[3] = Q[1]; + } else { // enu + xyzs[0] = qr[0]; + xyzs[1] = qr[1]; + xyzs[2] = qr[2]; + xyzs[3] = qr[3]; + } } // computes solution statistics --------------------------------------------- -void __fastcall TPlot::CalcStats(const double *x, int n, - double ref, double &ave, double &std, double &rms) -{ - double sum=0.0,sumsq=0.0; - int i; - - trace(3,"CalcStats: n=%d\n",n); - - if (n<=0) { - ave=std=rms=0.0; - return; - } - ave=std=rms=0.0; - - for (i=0;i1?SQRT((sumsq-2.0*sum*ave+ave*ave*n)/(n-1)):0.0; - rms=SQRT((sumsq-2.0*sum*ref+ref*ref*n)/n); +void __fastcall TPlot::CalcStats(const double *x, int n, double ref, double &ave, double &std, + double &rms) { + double sum = 0.0, sumsq = 0.0; + int i; + + trace(3, "CalcStats: n=%d\n", n); + + if (n <= 0) { + ave = std = rms = 0.0; + return; + } + ave = std = rms = 0.0; + + for (i = 0; i < n; i++) { + sum += x[i]; + sumsq += x[i] * x[i]; + } + ave = sum / n; + std = n > 1 ? SQRT((sumsq - 2.0 * sum * ave + ave * ave * n) / (n - 1)) : 0.0; + rms = SQRT((sumsq - 2.0 * sum * ref + ref * ref * n) / n); } // get system color --------------------------------------------------------- -TColor __fastcall TPlot::SysColor(int sat) -{ - switch (satsys(sat,NULL)) { - case SYS_GPS: return MColor[0][1]; - case SYS_GLO: return MColor[0][2]; - case SYS_GAL: return MColor[0][3]; - case SYS_QZS: return MColor[0][4]; - case SYS_CMP: return MColor[0][5]; - case SYS_IRN: return MColor[0][6]; - case SYS_SBS: return MColor[0][0]; - } - return MColor[0][0]; +TColor __fastcall TPlot::SysColor(int sat) { + switch (satsys(sat, NULL)) { + case SYS_GPS: + return MColor[0][1]; + case SYS_GLO: + return MColor[0][2]; + case SYS_GAL: + return MColor[0][3]; + case SYS_QZS: + return MColor[0][4]; + case SYS_CMP: + return MColor[0][5]; + case SYS_IRN: + return MColor[0][6]; + case SYS_SBS: + return MColor[0][0]; + } + return MColor[0][0]; } // get observation data color ----------------------------------------------- -TColor __fastcall TPlot::ObsColor(const obsd_t *obs, double az, double el) -{ - TColor color; - AnsiString text=ObsType->Text; - const char *obstype; - int i,n,freq; - - trace(4,"ObsColor\n"); - - if (!SatSel[obs->sat-1]) { - return clBlack; - } - if (PlotType==PLOT_SNR||PlotType==PLOT_SNRE) { - text=ObsType2->Text; - } - obstype=text.c_str(); - - if (SimObs) { - color=SysColor(obs->sat); - } - else if (!strcmp(obstype,"ALL")) { - for (i=n=0;iL[i]!=0.0||obs->P[i]!=0.0) n++; - } - if (n==0) { - return clBlack; - } - color=MColor[0][3-n+(n>2?5:0)]; - } - else if (sscanf(obstype,"L%1d",&freq)==1) { - freq-=freq>2?2:0; /* L1,L2,L5,L6 ... */ - if (obs->L[freq-1]==0.0&&obs->P[freq-1]==0.0) { - return clBlack; - } - color=SnrColor(obs->SNR[freq-1]); - } - else { - for (i=0;icode[i]),obstype)) break; - } - if (i>=NFREQ+NEXOBS) { - return clBlack; - } - if (obs->L[i]==0.0&&obs->P[i]==0.0) { - return clBlack; - } - color=SnrColor(obs->SNR[i]); - } - if (elText; + const char *obstype; + int i, n, freq; + + trace(4, "ObsColor\n"); + + if (!SatSel[obs->sat - 1]) { + return clBlack; + } + if (PlotType == PLOT_SNR || PlotType == PLOT_SNRE) { + text = ObsType2->Text; + } + obstype = text.c_str(); + + if (SimObs) { + color = SysColor(obs->sat); + } else if (!strcmp(obstype, "ALL")) { + for (i = n = 0; i < NFREQ + NEXOBS && n < 5; i++) { + if (obs->L[i] != 0.0 || obs->P[i] != 0.0) n++; + } + if (n == 0) { + return clBlack; + } + color = MColor[0][3 - n + (n > 2 ? 5 : 0)]; + } else if (sscanf(obstype, "L%1d", &freq) == 1) { + freq -= freq > 2 ? 2 : 0; /* L1,L2,L5,L6 ... */ + if (obs->L[freq - 1] == 0.0 && obs->P[freq - 1] == 0.0) { + return clBlack; + } + color = SnrColor(obs->SNR[freq - 1]); + } else { + for (i = 0; i < NFREQ + NEXOBS; i++) { + if (!strcmp(code2obs(obs->code[i]), obstype)) break; + } + if (i >= NFREQ + NEXOBS) { + return clBlack; + } + if (obs->L[i] == 0.0 && obs->P[i] == 0.0) { + return clBlack; + } + color = SnrColor(obs->SNR[i]); + } + if (el < ElMask * D2R || (ElMaskP && el < ElMaskData[(int)(az * R2D + 0.5)])) { + return HideLowSat ? clBlack : MColor[0][0]; + } + return color; } // get observation data color ----------------------------------------------- -TColor __fastcall TPlot::SnrColor(double snr) -{ - uint32_t c1,c2,r1,r2,g1,g2,b1,b2; - double a; - int i; - - if (snr<25.0) return MColor[0][7]; - if (snr<27.5) return MColor[0][5]; - if (snr>47.5) return MColor[0][1]; - a=(snr-27.5)/5.0; - i=(int)a; a-=i; - c1=(uint32_t)MColor[0][4-i]; - c2=(uint32_t)MColor[0][5-i]; - r1=c1&0xFF; g1=(c1>>8)&0xFF; b1=(c1>>16)&0xFF; - r2=c2&0xFF; g2=(c2>>8)&0xFF; b2=(c2>>16)&0xFF; - r1=(uint32_t)(a*r1+(1.0-a)*r2)&0xFF; - g1=(uint32_t)(a*g1+(1.0-a)*g2)&0xFF; - b1=(uint32_t)(a*b1+(1.0-a)*b2)&0xFF; - - return (TColor)((b1<<16)+(g1<<8)+r1); +TColor __fastcall TPlot::SnrColor(double snr) { + uint32_t c1, c2, r1, r2, g1, g2, b1, b2; + double a; + int i; + + if (snr < 25.0) return MColor[0][7]; + if (snr < 27.5) return MColor[0][5]; + if (snr > 47.5) return MColor[0][1]; + a = (snr - 27.5) / 5.0; + i = (int)a; + a -= i; + c1 = (uint32_t)MColor[0][4 - i]; + c2 = (uint32_t)MColor[0][5 - i]; + r1 = c1 & 0xFF; + g1 = (c1 >> 8) & 0xFF; + b1 = (c1 >> 16) & 0xFF; + r2 = c2 & 0xFF; + g2 = (c2 >> 8) & 0xFF; + b2 = (c2 >> 16) & 0xFF; + r1 = (uint32_t)(a * r1 + (1.0 - a) * r2) & 0xFF; + g1 = (uint32_t)(a * g1 + (1.0 - a) * g2) & 0xFF; + b1 = (uint32_t)(a * b1 + (1.0 - a) * b2) & 0xFF; + + return (TColor)((b1 << 16) + (g1 << 8) + r1); } // get mp color ------------------------------------------------------------- -TColor __fastcall TPlot::MpColor(double mp) -{ - TColor colors[5]; - uint32_t c1,c2,r1,r2,g1,g2,b1,b2; - double a; - int i; - - colors[4]=MColor[0][5]; /* mp> 0.6 */ - colors[3]=MColor[0][4]; /* 0.6>mp> 0.2 */ - colors[2]=MColor[0][3]; /* 0.2>mp>-0.2 */ - colors[1]=MColor[0][2]; /* -0.2>mp>-0.6 */ - colors[0]=MColor[0][1]; /* -0.6>mp */ - - if (mp>= 0.6) return colors[4]; - if (mp<=-0.6) return colors[0]; - a=mp/0.4+0.6; - i=(int)a; a-=i; - c1=(uint32_t)colors[i ]; - c2=(uint32_t)colors[i+1]; - r1=c1&0xFF; g1=(c1>>8)&0xFF; b1=(c1>>16)&0xFF; - r2=c2&0xFF; g2=(c2>>8)&0xFF; b2=(c2>>16)&0xFF; - r1=(uint32_t)(a*r1+(1.0-a)*r2)&0xFF; - g1=(uint32_t)(a*g1+(1.0-a)*g2)&0xFF; - b1=(uint32_t)(a*b1+(1.0-a)*b2)&0xFF; - - return (TColor)((b1<<16)+(g1<<8)+r1); +TColor __fastcall TPlot::MpColor(double mp) { + TColor colors[5]; + uint32_t c1, c2, r1, r2, g1, g2, b1, b2; + double a; + int i; + + colors[4] = MColor[0][5]; /* mp> 0.6 */ + colors[3] = MColor[0][4]; /* 0.6>mp> 0.2 */ + colors[2] = MColor[0][3]; /* 0.2>mp>-0.2 */ + colors[1] = MColor[0][2]; /* -0.2>mp>-0.6 */ + colors[0] = MColor[0][1]; /* -0.6>mp */ + + if (mp >= 0.6) return colors[4]; + if (mp <= -0.6) return colors[0]; + a = mp / 0.4 + 0.6; + i = (int)a; + a -= i; + c1 = (uint32_t)colors[i]; + c2 = (uint32_t)colors[i + 1]; + r1 = c1 & 0xFF; + g1 = (c1 >> 8) & 0xFF; + b1 = (c1 >> 16) & 0xFF; + r2 = c2 & 0xFF; + g2 = (c2 >> 8) & 0xFF; + b2 = (c2 >> 16) & 0xFF; + r1 = (uint32_t)(a * r1 + (1.0 - a) * r2) & 0xFF; + g1 = (uint32_t)(a * g1 + (1.0 - a) * g2) & 0xFF; + b1 = (uint32_t)(a * b1 + (1.0 - a) * b2) & 0xFF; + + return (TColor)((b1 << 16) + (g1 << 8) + r1); } // search solution by xy-position in plot ----------------------------------- -int __fastcall TPlot::SearchPos(int x, int y) -{ - sol_t *data; - TPoint p(x,y); - double xp,yp,xs,ys,r,xyz[3]; - int i,sel=!BtnSol1->Down&&BtnSol2->Down?1:0; - - trace(3,"SearchPos: x=%d y=%d\n",x,y); - - if (!BtnShowTrack->Down||(!BtnSol1->Down&&!BtnSol2->Down)) return -1; - - GraphT->ToPos(p,xp,yp); - GraphT->GetScale(xs,ys); - r=(MarkSize/2+2)*xs; - - for (i=0;(data=getsol(SolData+sel,i));i++) { - if (QFlag->ItemIndex&&data->stat!=QFlag->ItemIndex) continue; - - PosToXyz(data->time,data->rr,data->type,xyz); - if (xyz[2]<-RE_WGS84) continue; - - if (SQR(xp-xyz[0])+SQR(yp-xyz[1])<=SQR(r)) return i; - } - return -1; +int __fastcall TPlot::SearchPos(int x, int y) { + sol_t *data; + TPoint p(x, y); + double xp, yp, xs, ys, r, xyz[3]; + int i, sel = !BtnSol1->Down && BtnSol2->Down ? 1 : 0; + + trace(3, "SearchPos: x=%d y=%d\n", x, y); + + if (!BtnShowTrack->Down || (!BtnSol1->Down && !BtnSol2->Down)) return -1; + + GraphT->ToPos(p, xp, yp); + GraphT->GetScale(xs, ys); + r = (MarkSize / 2 + 2) * xs; + + for (i = 0; (data = getsol(SolData + sel, i)); i++) { + if (QFlag->ItemIndex && data->stat != QFlag->ItemIndex) continue; + + PosToXyz(data->time, data->rr, data->type, xyz); + if (xyz[2] < -RE_WGS84) continue; + + if (SQR(xp - xyz[0]) + SQR(yp - xyz[1]) <= SQR(r)) return i; + } + return -1; } // generate time-string ----------------------------------------------------- -void __fastcall TPlot::TimeStr(gtime_t time, int n, int tsys, char str[48]) -{ - struct tm *t; - char tstr[40]; - const char *label=""; - double tow; - int week; - - if (TimeLabel==0) { // www/ssss - tow=time2gpst(time,&week); - snprintf(tstr,sizeof(tstr),"%4d/%*.*fs",week,(n>0?6:5)+n,n,tow); - } - else if (TimeLabel==1) { // GPST - time2str(time,tstr,n); - label=" GPST"; - } - else if (TimeLabel==2) { // UTC - time2str(gpst2utc(time),tstr,n); - label=" UTC"; - } - else { // lt - time=gpst2utc(time); - if (!(t=localtime(&time.time))) strcpy(tstr,"2000/01/01 00:00:00.0"); - else snprintf(tstr,sizeof(tstr),"%04d/%02d/%02d %02d:%02d:%02d.%0*d",t->tm_year+1900, - t->tm_mon+1,t->tm_mday,t->tm_hour,t->tm_min,t->tm_sec, - n,(int)(time.sec*pow(10.0,n))); - label=" LT"; - } - snprintf(str,48,"%s%s",tstr,label); +void __fastcall TPlot::TimeStr(gtime_t time, int n, int tsys, char str[48]) { + struct tm *t; + char tstr[40]; + const char *label = ""; + double tow; + int week; + + if (TimeLabel == 0) { // www/ssss + tow = time2gpst(time, &week); + snprintf(tstr, sizeof(tstr), "%4d/%*.*fs", week, (n > 0 ? 6 : 5) + n, n, tow); + } else if (TimeLabel == 1) { // GPST + time2str(time, tstr, n); + label = " GPST"; + } else if (TimeLabel == 2) { // UTC + time2str(gpst2utc(time), tstr, n); + label = " UTC"; + } else { // lt + time = gpst2utc(time); + if (!(t = localtime(&time.time))) + strcpy(tstr, "2000/01/01 00:00:00.0"); + else + snprintf(tstr, sizeof(tstr), "%04d/%02d/%02d %02d:%02d:%02d.%0*d", t->tm_year + 1900, + t->tm_mon + 1, t->tm_mday, t->tm_hour, t->tm_min, t->tm_sec, n, + (int)(time.sec * pow(10.0, n))); + label = " LT"; + } + snprintf(str, 48, "%s%s", tstr, label); } // latitude/longitude/height string ----------------------------------------- -UTF8String __fastcall TPlot::LatLonStr(const double *pos, int ndec) -{ - UTF8String s; - double dms1[3],dms2[3]; - - if (LatLonFmt==0) { - s.sprintf("%*.*f" CHARDEG "%s %*.*f" CHARDEG "%s", - ndec+4,ndec,fabs(pos[0]*R2D),pos[0]<0.0?"S":"N", - ndec+5,ndec,fabs(pos[1]*R2D),pos[1]<0.0?"W":"E"); - } - else { - deg2dms(pos[0]*R2D,dms1,ndec-5); - deg2dms(pos[1]*R2D,dms2,ndec-5); - s.sprintf("%3.0f" CHARDEG "%02.0f'%0*.*f\"%s %4.0f" CHARDEG "%02.0f'%0*.*f\"%s", - fabs(dms1[0]),dms1[1],ndec-2,ndec-5,dms1[2],pos[0]<0.0?"S":"N", - fabs(dms2[0]),dms2[1],ndec-2,ndec-5,dms2[2],pos[1]<0.0?"W":"E"); - } - return s; +UTF8String __fastcall TPlot::LatLonStr(const double *pos, int ndec) { + UTF8String s; + double dms1[3], dms2[3]; + + if (LatLonFmt == 0) { + s.sprintf("%*.*f" CHARDEG "%s %*.*f" CHARDEG "%s", ndec + 4, ndec, fabs(pos[0] * R2D), + pos[0] < 0.0 ? "S" : "N", ndec + 5, ndec, fabs(pos[1] * R2D), + pos[1] < 0.0 ? "W" : "E"); + } else { + deg2dms(pos[0] * R2D, dms1, ndec - 5); + deg2dms(pos[1] * R2D, dms2, ndec - 5); + s.sprintf("%3.0f" CHARDEG "%02.0f'%0*.*f\"%s %4.0f" CHARDEG "%02.0f'%0*.*f\"%s", fabs(dms1[0]), + dms1[1], ndec - 2, ndec - 5, dms1[2], pos[0] < 0.0 ? "S" : "N", fabs(dms2[0]), + dms2[1], ndec - 2, ndec - 5, dms2[2], pos[1] < 0.0 ? "W" : "E"); + } + return s; } // convert unicode to UTF-8 ansistring -------------------------------------- -AnsiString __fastcall TPlot::U2A(UnicodeString str) -{ - AnsiString a_str(str); - return a_str; +AnsiString __fastcall TPlot::U2A(UnicodeString str) { + AnsiString a_str(str); + return a_str; } // convert UTF-8 ansi to unicodestring -------------------------------------- -UnicodeString __fastcall TPlot::A2U(AnsiString str) -{ - wchar_t buff[256]={0}; - ::MultiByteToWideChar(CP_UTF8,0,str.c_str(),-1,buff,512); - UnicodeString u_str(buff); - return u_str; +UnicodeString __fastcall TPlot::A2U(AnsiString str) { + wchar_t buff[256] = {0}; + ::MultiByteToWideChar(CP_UTF8, 0, str.c_str(), -1, buff, 512); + UnicodeString u_str(buff); + return u_str; } //--------------------------------------------------------------------------- // time-taged xyz-position class implementation //--------------------------------------------------------------------------- // constructor -------------------------------------------------------------- -TIMEPOS::TIMEPOS(int nmax, int sflg) -{ - nmax_=nmax; - n=0; - t=new gtime_t[nmax]; - x=new double [nmax]; - y=new double [nmax]; - z=new double [nmax]; - if (sflg) { - xs =new double [nmax]; - ys =new double [nmax]; - zs =new double [nmax]; - xys=new double [nmax]; - } - else xs=ys=zs=xys=NULL; - q=new int [nmax]; +TIMEPOS::TIMEPOS(int nmax, int sflg) { + nmax_ = nmax; + n = 0; + t = new gtime_t[nmax]; + x = new double[nmax]; + y = new double[nmax]; + z = new double[nmax]; + if (sflg) { + xs = new double[nmax]; + ys = new double[nmax]; + zs = new double[nmax]; + xys = new double[nmax]; + } else + xs = ys = zs = xys = NULL; + q = new int[nmax]; } // destructor --------------------------------------------------------------- -TIMEPOS::~TIMEPOS() -{ - delete [] t; - delete [] x; - delete [] y; - delete [] z; - if (xs) { - delete [] xs; - delete [] ys; - delete [] zs; - delete [] xys; - } - delete [] q; +TIMEPOS::~TIMEPOS() { + delete[] t; + delete[] x; + delete[] y; + delete[] z; + if (xs) { + delete[] xs; + delete[] ys; + delete[] zs; + delete[] xys; + } + delete[] q; } // xyz-position difference from previous ------------------------------------ -TIMEPOS * TIMEPOS::tdiff(void) -{ - TIMEPOS *pos=new TIMEPOS(n,1); - double tt; - int i; - - for (i=0;iMAXTDIFF) continue; - - pos->t[pos->n]=timeadd(t[i],tt/2.0); - pos->x[pos->n]=(x[i+1]-x[i])/tt; - pos->y[pos->n]=(y[i+1]-y[i])/tt; - pos->z[pos->n]=(z[i+1]-z[i])/tt; - if (xs) { - pos->xs [pos->n]=SQR(xs [i+1])+SQR(xs [i]); - pos->ys [pos->n]=SQR(ys [i+1])+SQR(ys [i]); - pos->zs [pos->n]=SQR(zs [i+1])+SQR(zs [i]); - pos->xys[pos->n]=SQR(xys[i+1])+SQR(xys[i]); - } - pos->q[pos->n]=MAX(q[i],q[i+1]); - pos->n++; - } - return pos; +TIMEPOS *TIMEPOS::tdiff(void) { + TIMEPOS *pos = new TIMEPOS(n, 1); + double tt; + int i; + + for (i = 0; i < n - 1; i++) { + tt = timediff(t[i + 1], t[i]); + + if (tt == 0.0 || fabs(tt) > MAXTDIFF) continue; + + pos->t[pos->n] = timeadd(t[i], tt / 2.0); + pos->x[pos->n] = (x[i + 1] - x[i]) / tt; + pos->y[pos->n] = (y[i + 1] - y[i]) / tt; + pos->z[pos->n] = (z[i + 1] - z[i]) / tt; + if (xs) { + pos->xs[pos->n] = SQR(xs[i + 1]) + SQR(xs[i]); + pos->ys[pos->n] = SQR(ys[i + 1]) + SQR(ys[i]); + pos->zs[pos->n] = SQR(zs[i + 1]) + SQR(zs[i]); + pos->xys[pos->n] = SQR(xys[i + 1]) + SQR(xys[i]); + } + pos->q[pos->n] = MAX(q[i], q[i + 1]); + pos->n++; + } + return pos; } // xyz-position difference between TIMEPOS ---------------------------------- -TIMEPOS *TIMEPOS::diff(const TIMEPOS *pos2, int qflag) -{ - TIMEPOS *pos1=this,*pos=new TIMEPOS(MIN(n,pos2->n),1); - double tt; - int i,j,q; - - for (i=0,j=0;in&&jn;i++,j++) { - - tt=timediff(pos1->t[i],pos2->t[j]); - - if (tt<-TTOL) {j--; continue;} - else if (tt> TTOL) {i--; continue;} - - pos->t[pos->n]=pos1->t[i]; - pos->x[pos->n]=pos1->x[i]-pos2->x[j]; - pos->y[pos->n]=pos1->y[i]-pos2->y[j]; - pos->z[pos->n]=pos1->z[i]-pos2->z[j]; - if (pos->xs) { - pos->xs [pos->n]=SQR(pos1->xs [i])+SQR(pos2->xs [j]); - pos->ys [pos->n]=SQR(pos1->ys [i])+SQR(pos2->ys [j]); - pos->zs [pos->n]=SQR(pos1->zs [i])+SQR(pos2->zs [j]); - pos->xys[pos->n]=SQR(pos1->xys[i])+SQR(pos2->xys[j]); - } - q=MAX(pos1->q[i],pos2->q[j]); - - if (!qflag||qflag==q) { - pos->q[pos->n++]=q; - } +TIMEPOS *TIMEPOS::diff(const TIMEPOS *pos2, int qflag) { + TIMEPOS *pos1 = this, *pos = new TIMEPOS(MIN(n, pos2->n), 1); + double tt; + int i, j, q; + + for (i = 0, j = 0; i < pos1->n && j < pos2->n; i++, j++) { + tt = timediff(pos1->t[i], pos2->t[j]); + + if (tt < -TTOL) { + j--; + continue; + } else if (tt > TTOL) { + i--; + continue; + } + + pos->t[pos->n] = pos1->t[i]; + pos->x[pos->n] = pos1->x[i] - pos2->x[j]; + pos->y[pos->n] = pos1->y[i] - pos2->y[j]; + pos->z[pos->n] = pos1->z[i] - pos2->z[j]; + if (pos->xs) { + pos->xs[pos->n] = SQR(pos1->xs[i]) + SQR(pos2->xs[j]); + pos->ys[pos->n] = SQR(pos1->ys[i]) + SQR(pos2->ys[j]); + pos->zs[pos->n] = SQR(pos1->zs[i]) + SQR(pos2->zs[j]); + pos->xys[pos->n] = SQR(pos1->xys[i]) + SQR(pos2->xys[j]); + } + q = MAX(pos1->q[i], pos2->q[j]); + + if (!qflag || qflag == q) { + pos->q[pos->n++] = q; } - return pos; + } + return pos; } //--------------------------------------------------------------------------- diff --git a/app/winapp/rtkplot/plotdata.cpp b/app/winapp/rtkplot/plotdata.cpp index 3a52ee869..af66db29e 100644 --- a/app/winapp/rtkplot/plotdata.cpp +++ b/app/winapp/rtkplot/plotdata.cpp @@ -1,1513 +1,1516 @@ //--------------------------------------------------------------------------- // plotdata : rtkplot data functions //--------------------------------------------------------------------------- -#include "rtklib.h" -#include "plotmain.h" #include "mapoptdlg.h" +#include "plotmain.h" #include "pntdlg.h" +#include "rtklib.h" #define HEADXML "\n" #define HEADGPX "\n" #define TAILGPX "" -#define MAX_SIMOBS 16384 // max genrated obs epochs -#define MAX_SKYIMG_R 2048 // max size of resampled sky image +#define MAX_SIMOBS 16384 // max genrated obs epochs +#define MAX_SKYIMG_R 2048 // max size of resampled sky image static char path_str[MAXNFILE][1024]; -static const char *XMLNS="http://www.topografix.com/GPX/1/1"; +static const char *XMLNS = "http://www.topografix.com/GPX/1/1"; // read solutions ----------------------------------------------------------- -void __fastcall TPlot::ReadSol(TStrings *files, int sel) -{ - FILETIME tc,ta,tw; - SYSTEMTIME st; - HANDLE h; - solbuf_t sol={0}; - AnsiString s; - gtime_t ts,te; - double tint,ep[6]; - int i,n=0; - char *paths[MAXNFILE]; - - trace(3,"ReadSol: sel=%d\n",sel); - - for (i=0;iCount<=0) return; - - ReadWaitStart(); - /* Set default to current date in case no date info in solution (e.g. GGA msgs)*/ - s=files->Strings[0]; - - if ((h=CreateFile(s.c_str(),GENERIC_READ,0,NULL,OPEN_EXISTING, - FILE_ATTRIBUTE_NORMAL,0))==INVALID_HANDLE_VALUE) { - return; - } - GetFileTime(h,&tc,&ta,&tw); - CloseHandle(h); - FileTimeToSystemTime(&tc,&st); // file create time - ep[0]=st.wYear; - ep[1]=st.wMonth; - ep[2]=st.wDay; - ep[3]=st.wHour; - ep[4]=st.wMinute; - ep[5]=st.wSecond; - sol.time=utc2gpst(epoch2time(ep)); - - for (i=0;iCount&&nStrings[i]).c_str()); - } - TimeSpan(&ts,&te,&tint); - - ShowMsg(s.sprintf("reading %s...",paths[0])); +void __fastcall TPlot::ReadSol(TStrings *files, int sel) { + FILETIME tc, ta, tw; + SYSTEMTIME st; + HANDLE h; + solbuf_t sol = {0}; + AnsiString s; + gtime_t ts, te; + double tint, ep[6]; + int i, n = 0; + char *paths[MAXNFILE]; + + trace(3, "ReadSol: sel=%d\n", sel); + + for (i = 0; i < MAXNFILE; i++) paths[i] = path_str[i]; + + if (files->Count <= 0) return; + + ReadWaitStart(); + /* Set default to current date in case no date info in solution (e.g. GGA msgs)*/ + s = files->Strings[0]; + + if ((h = CreateFile(s.c_str(), GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0)) == + INVALID_HANDLE_VALUE) { + return; + } + GetFileTime(h, &tc, &ta, &tw); + CloseHandle(h); + FileTimeToSystemTime(&tc, &st); // file create time + ep[0] = st.wYear; + ep[1] = st.wMonth; + ep[2] = st.wDay; + ep[3] = st.wHour; + ep[4] = st.wMinute; + ep[5] = st.wSecond; + sol.time = utc2gpst(epoch2time(ep)); + + for (i = 0; i < files->Count && n < MAXNFILE; i++) { + strcpy(paths[n++], U2A(files->Strings[i]).c_str()); + } + TimeSpan(&ts, &te, &tint); + + ShowMsg(s.sprintf("reading %s...", paths[0])); + ShowLegend(NULL); + + if (!readsolt((const char **)paths, n, ts, te, tint, SOLQ_NONE, 0, &sol)) { + ShowMsg(s.sprintf("no solution data : %s...", paths[0])); ShowLegend(NULL); - - if (!readsolt((const char **)paths,n,ts,te,tint,SOLQ_NONE,0,&sol)) { - ShowMsg(s.sprintf("no solution data : %s...",paths[0])); - ShowLegend(NULL); - ReadWaitEnd(); - return; - } - freesolbuf(SolData+sel); - SolData[sel]=sol; - - if (SolFiles[sel]!=files) { - SolFiles[sel]->Assign(files); - } - Caption=""; - - ReadSolStat(files,sel); - - for (i=0;i<2;i++) { - if (SolFiles[i]->Count==0) continue; - Caption=Caption+SolFiles[i]->Strings[0]+(SolFiles[i]->Count>1?"... ":" "); - } - BtnSol12->Down=False; - if (sel==0) BtnSol1->Down=true; - else BtnSol2->Down=true; - - if (sel==0||SolData[0].n<=0) { - if (SolData[sel].n > 0) - time2gpst(SolData[sel].data[0].time,&Week); - UpdateOrigin(); - } - SolIndex[0]=SolIndex[1]=ObsIndex=0; - TimeScroll->Position=0; - - GEDataState[sel]=0; - - if (PlotType>PLOT_NSAT) { - UpdateType(PLOT_TRK); - } - else { - UpdatePlotType(); - } - FitTime(); - if (AutoScale&&PlotType<=PLOT_SOLA) { - FitRange(1); - } - else { - SetRange(1,YRange); - } ReadWaitEnd(); - - UpdateTime(); - UpdatePlot(); - UpdateEnable(); + return; + } + freesolbuf(SolData + sel); + SolData[sel] = sol; + + if (SolFiles[sel] != files) { + SolFiles[sel]->Assign(files); + } + Caption = ""; + + ReadSolStat(files, sel); + + for (i = 0; i < 2; i++) { + if (SolFiles[i]->Count == 0) continue; + Caption = Caption + SolFiles[i]->Strings[0] + (SolFiles[i]->Count > 1 ? "... " : " "); + } + BtnSol12->Down = False; + if (sel == 0) + BtnSol1->Down = true; + else + BtnSol2->Down = true; + + if (sel == 0 || SolData[0].n <= 0) { + if (SolData[sel].n > 0) time2gpst(SolData[sel].data[0].time, &Week); + UpdateOrigin(); + } + SolIndex[0] = SolIndex[1] = ObsIndex = 0; + TimeScroll->Position = 0; + + GEDataState[sel] = 0; + + if (PlotType > PLOT_NSAT) { + UpdateType(PLOT_TRK); + } else { + UpdatePlotType(); + } + FitTime(); + if (AutoScale && PlotType <= PLOT_SOLA) { + FitRange(1); + } else { + SetRange(1, YRange); + } + ReadWaitEnd(); + + UpdateTime(); + UpdatePlot(); + UpdateEnable(); } // read solution status ----------------------------------------------------- -void __fastcall TPlot::ReadSolStat(TStrings *files, int sel) -{ - AnsiString s; - gtime_t ts,te; - double tint; - int i,n=0; - char *paths[MAXNFILE],id[32]; - - trace(3,"ReadSolStat\n"); - - freesolstatbuf(SolStat+sel); - - for (i=0;iCount&&nStrings[i]).c_str()); - } - ShowMsg(s.sprintf("reading %s...",paths[0])); - ShowLegend(NULL); - - readsolstatt((const char **)paths,n,ts,te,tint,SolStat+sel); - - UpdateSatList(); +void __fastcall TPlot::ReadSolStat(TStrings *files, int sel) { + AnsiString s; + gtime_t ts, te; + double tint; + int i, n = 0; + char *paths[MAXNFILE], id[32]; + + trace(3, "ReadSolStat\n"); + + freesolstatbuf(SolStat + sel); + + for (i = 0; i < MAXNFILE; i++) paths[i] = path_str[i]; + + TimeSpan(&ts, &te, &tint); + + for (i = 0; i < files->Count && n < MAXNFILE; i++) { + strcpy(paths[n++], U2A(files->Strings[i]).c_str()); + } + ShowMsg(s.sprintf("reading %s...", paths[0])); + ShowLegend(NULL); + + readsolstatt((const char **)paths, n, ts, te, tint, SolStat + sel); + + UpdateSatList(); } // read observation data ---------------------------------------------------- -void __fastcall TPlot::ReadObs(TStrings *files) -{ - obs_t obs={0}; - sta_t sta={0}; - AnsiString s; - char file[1024]; - int i,nobs; - - trace(3,"ReadObs\n"); - - if (files->Count<=0) return; - - ReadWaitStart(); - ShowLegend(NULL); - - nav_t *nav = static_cast(calloc(1, sizeof(nav_t))); - if (nav == NULL) { - trace(1, "TPlot::ReadObs nav alloc failed\n"); - return; - } +void __fastcall TPlot::ReadObs(TStrings *files) { + obs_t obs = {0}; + sta_t sta = {0}; + AnsiString s; + char file[1024]; + int i, nobs; - if ((nobs=ReadObsRnx(files,&obs,nav,&sta))<=0) { - ReadWaitEnd(); - free(nav); - return; - } - ClearObs(); - Obs=obs; - Nav=*nav; - free(nav); - Sta=sta; - SimObs=0; - UpdateObs(nobs); - UpdateMp(); - - if (ObsFiles!=files) { - ObsFiles->Assign(files); - } - NavFiles->Clear(); - - strcpy(file,U2A(files->Strings[0]).c_str()); - - Caption=s.sprintf("%s%s",file,files->Count>1?"...":""); - - BtnSol1->Down=true; - time2gpst(Obs.data[0].time,&Week); - SolIndex[0]=SolIndex[1]=ObsIndex=0; - - if (PlotTypeCount <= 0) return; + + ReadWaitStart(); + ShowLegend(NULL); + + nav_t *nav = static_cast(calloc(1, sizeof(nav_t))); + if (nav == NULL) { + trace(1, "TPlot::ReadObs nav alloc failed\n"); + return; + } + + if ((nobs = ReadObsRnx(files, &obs, nav, &sta)) <= 0) { ReadWaitEnd(); - UpdateObsType(); - UpdateTime(); - UpdatePlot(); - UpdateEnable(); + free(nav); + return; + } + ClearObs(); + Obs = obs; + Nav = *nav; + free(nav); + Sta = sta; + SimObs = 0; + UpdateObs(nobs); + UpdateMp(); + + if (ObsFiles != files) { + ObsFiles->Assign(files); + } + NavFiles->Clear(); + + strcpy(file, U2A(files->Strings[0]).c_str()); + + Caption = s.sprintf("%s%s", file, files->Count > 1 ? "..." : ""); + + BtnSol1->Down = true; + time2gpst(Obs.data[0].time, &Week); + SolIndex[0] = SolIndex[1] = ObsIndex = 0; + + if (PlotType < PLOT_OBS || PLOT_DOP < PlotType) { + UpdateType(PLOT_OBS); + } else { + UpdatePlotType(); + } + FitTime(); + + ReadWaitEnd(); + UpdateObsType(); + UpdateTime(); + UpdatePlot(); + UpdateEnable(); } // read observation data rinex ---------------------------------------------- -int __fastcall TPlot::ReadObsRnx(TStrings *files, obs_t *obs, nav_t *nav, - sta_t *sta) -{ - AnsiString s; - gtime_t ts,te; - double tint; - int i,n; - char obsfile[1024],navfile[1024]="",*p,*q,*opt=RnxOpts.c_str(); - - trace(3,"ReadObsRnx\n"); - - TimeSpan(&ts,&te,&tint); - - for (i=0;iCount;i++) { - strcpy(obsfile,U2A(files->Strings[i]).c_str()); - - ShowMsg(s.sprintf("reading obs data... %s",obsfile)); - Application->ProcessMessages(); - - if (readrnxt(obsfile,1,ts,te,tint,opt,obs,nav,sta)<0) { - ShowMsg("error: insufficient memory"); - return -1; - } - } - ShowMsg("reading nav data..."); +int __fastcall TPlot::ReadObsRnx(TStrings *files, obs_t *obs, nav_t *nav, sta_t *sta) { + AnsiString s; + gtime_t ts, te; + double tint; + int i, n; + char obsfile[1024], navfile[1024] = "", *p, *q, *opt = RnxOpts.c_str(); + + trace(3, "ReadObsRnx\n"); + + TimeSpan(&ts, &te, &tint); + + for (i = 0; i < files->Count; i++) { + strcpy(obsfile, U2A(files->Strings[i]).c_str()); + + ShowMsg(s.sprintf("reading obs data... %s", obsfile)); Application->ProcessMessages(); - - for (i=0;iCount;i++) { - strcpy(navfile,U2A(files->Strings[i]).c_str()); - - if (!(p=strrchr(navfile,'.'))) continue; - - if (!strcmp(p,".obs")||!strcmp(p,".OBS")) { - strcpy(p,".nav" ); readrnxt(navfile,1,ts,te,tint,opt,NULL,nav,NULL); - strcpy(p,".gnav"); readrnxt(navfile,1,ts,te,tint,opt,NULL,nav,NULL); - strcpy(p,".hnav"); readrnxt(navfile,1,ts,te,tint,opt,NULL,nav,NULL); - strcpy(p,".qnav"); readrnxt(navfile,1,ts,te,tint,opt,NULL,nav,NULL); - strcpy(p,".lnav"); readrnxt(navfile,1,ts,te,tint,opt,NULL,nav,NULL); - strcpy(p,".cnav"); readrnxt(navfile,1,ts,te,tint,opt,NULL,nav,NULL); - strcpy(p,".inav"); readrnxt(navfile,1,ts,te,tint,opt,NULL,nav,NULL); - } - else if (!strcmp(p+3,"o" )||!strcmp(p+3,"d" )|| - !strcmp(p+3,"O" )||!strcmp(p+3,"D" )) { - n=nav->n; - - strcpy(p+3,"N"); readrnxt(navfile,1,ts,te,tint,opt,NULL,nav,NULL); - strcpy(p+3,"G"); readrnxt(navfile,1,ts,te,tint,opt,NULL,nav,NULL); - strcpy(p+3,"H"); readrnxt(navfile,1,ts,te,tint,opt,NULL,nav,NULL); - strcpy(p+3,"Q"); readrnxt(navfile,1,ts,te,tint,opt,NULL,nav,NULL); - strcpy(p+3,"L"); readrnxt(navfile,1,ts,te,tint,opt,NULL,nav,NULL); - strcpy(p+3,"C"); readrnxt(navfile,1,ts,te,tint,opt,NULL,nav,NULL); - strcpy(p+3,"I"); readrnxt(navfile,1,ts,te,tint,opt,NULL,nav,NULL); - strcpy(p+3,"P"); readrnxt(navfile,1,ts,te,tint,opt,NULL,nav,NULL); - - if (nav->n>n||!(q=strrchr(navfile,'\\'))) continue; - - // read brdc navigation data - memcpy(q+1,"BRDC",4); - strcpy(p+3,"N"); readrnxt(navfile,1,ts,te,tint,opt,NULL,nav,NULL); - } - else if (!strcmp(p-1,"O.rnx" )&&(p=strrchr(navfile,'_'))) { /* rinex 3 */ - *p='\0'; - if (!(p=strrchr(navfile,'_'))) continue; - *p='\0'; - if (!(p=strrchr(navfile,'_'))) continue; - strcpy(p,"_*_*N.rnx"); - - n=nav->n; - readrnxt(navfile,1,ts,te,tint,opt,NULL,nav,NULL); - - if (nav->n>n||!(q=strrchr(navfile,'\\'))) continue; - - // read brdc navigation data - memcpy(q+1,"BRDC",4); - readrnxt(navfile,1,ts,te,tint,opt,NULL,nav,NULL); - } - } - if (obs->n<=0) { - ShowMsg(s.sprintf("no observation data: %s...",files->Strings[0].c_str())); - freenav(nav,0xFF); - return 0; + + if (readrnxt(obsfile, 1, ts, te, tint, opt, obs, nav, sta) < 0) { + ShowMsg("error: insufficient memory"); + return -1; } - uniqnav(nav); - return sortobs(obs); + } + ShowMsg("reading nav data..."); + Application->ProcessMessages(); + + for (i = 0; i < files->Count; i++) { + strcpy(navfile, U2A(files->Strings[i]).c_str()); + + if (!(p = strrchr(navfile, '.'))) continue; + + if (!strcmp(p, ".obs") || !strcmp(p, ".OBS")) { + strcpy(p, ".nav"); + readrnxt(navfile, 1, ts, te, tint, opt, NULL, nav, NULL); + strcpy(p, ".gnav"); + readrnxt(navfile, 1, ts, te, tint, opt, NULL, nav, NULL); + strcpy(p, ".hnav"); + readrnxt(navfile, 1, ts, te, tint, opt, NULL, nav, NULL); + strcpy(p, ".qnav"); + readrnxt(navfile, 1, ts, te, tint, opt, NULL, nav, NULL); + strcpy(p, ".lnav"); + readrnxt(navfile, 1, ts, te, tint, opt, NULL, nav, NULL); + strcpy(p, ".cnav"); + readrnxt(navfile, 1, ts, te, tint, opt, NULL, nav, NULL); + strcpy(p, ".inav"); + readrnxt(navfile, 1, ts, te, tint, opt, NULL, nav, NULL); + } else if (!strcmp(p + 3, "o") || !strcmp(p + 3, "d") || !strcmp(p + 3, "O") || + !strcmp(p + 3, "D")) { + n = nav->n; + + strcpy(p + 3, "N"); + readrnxt(navfile, 1, ts, te, tint, opt, NULL, nav, NULL); + strcpy(p + 3, "G"); + readrnxt(navfile, 1, ts, te, tint, opt, NULL, nav, NULL); + strcpy(p + 3, "H"); + readrnxt(navfile, 1, ts, te, tint, opt, NULL, nav, NULL); + strcpy(p + 3, "Q"); + readrnxt(navfile, 1, ts, te, tint, opt, NULL, nav, NULL); + strcpy(p + 3, "L"); + readrnxt(navfile, 1, ts, te, tint, opt, NULL, nav, NULL); + strcpy(p + 3, "C"); + readrnxt(navfile, 1, ts, te, tint, opt, NULL, nav, NULL); + strcpy(p + 3, "I"); + readrnxt(navfile, 1, ts, te, tint, opt, NULL, nav, NULL); + strcpy(p + 3, "P"); + readrnxt(navfile, 1, ts, te, tint, opt, NULL, nav, NULL); + + if (nav->n > n || !(q = strrchr(navfile, '\\'))) continue; + + // read brdc navigation data + memcpy(q + 1, "BRDC", 4); + strcpy(p + 3, "N"); + readrnxt(navfile, 1, ts, te, tint, opt, NULL, nav, NULL); + } else if (!strcmp(p - 1, "O.rnx") && (p = strrchr(navfile, '_'))) { /* rinex 3 */ + *p = '\0'; + if (!(p = strrchr(navfile, '_'))) continue; + *p = '\0'; + if (!(p = strrchr(navfile, '_'))) continue; + strcpy(p, "_*_*N.rnx"); + + n = nav->n; + readrnxt(navfile, 1, ts, te, tint, opt, NULL, nav, NULL); + + if (nav->n > n || !(q = strrchr(navfile, '\\'))) continue; + + // read brdc navigation data + memcpy(q + 1, "BRDC", 4); + readrnxt(navfile, 1, ts, te, tint, opt, NULL, nav, NULL); + } + } + if (obs->n <= 0) { + ShowMsg(s.sprintf("no observation data: %s...", files->Strings[0].c_str())); + freenav(nav, 0xFF); + return 0; + } + uniqnav(nav); + return sortobs(obs); } // read navigation data ----------------------------------------------------- -void __fastcall TPlot::ReadNav(TStrings *files) -{ - AnsiString s; - gtime_t ts,te; - double tint; - char navfile[1024],*opt=RnxOpts.c_str(); - int i; - - trace(3,"ReadNav\n"); - - if (files->Count<=0) return; - - ReadWaitStart(); - ShowLegend(NULL); - - TimeSpan(&ts,&te,&tint); - - freenav(&Nav,0xFF); - - ShowMsg("reading nav data..."); - Application->ProcessMessages(); - - for (i=0;iCount;i++) { - strcpy(navfile,U2A(files->Strings[i]).c_str()); - readrnxt(navfile,1,ts,te,tint,opt,NULL,&Nav,NULL); - } - uniqnav(&Nav); - - if (Nav.n<=0&&Nav.ng<=0&&Nav.ns<=0) { - ShowMsg(s.sprintf("no nav message: %s...",files->Strings[0].c_str())); - ReadWaitEnd(); - return; - } - if (NavFiles!=files) { - NavFiles->Assign(files); - } - UpdateObs(NObs); - UpdateMp(); +void __fastcall TPlot::ReadNav(TStrings *files) { + AnsiString s; + gtime_t ts, te; + double tint; + char navfile[1024], *opt = RnxOpts.c_str(); + int i; + + trace(3, "ReadNav\n"); + + if (files->Count <= 0) return; + + ReadWaitStart(); + ShowLegend(NULL); + + TimeSpan(&ts, &te, &tint); + + freenav(&Nav, 0xFF); + + ShowMsg("reading nav data..."); + Application->ProcessMessages(); + + for (i = 0; i < files->Count; i++) { + strcpy(navfile, U2A(files->Strings[i]).c_str()); + readrnxt(navfile, 1, ts, te, tint, opt, NULL, &Nav, NULL); + } + uniqnav(&Nav); + + if (Nav.n <= 0 && Nav.ng <= 0 && Nav.ns <= 0) { + ShowMsg(s.sprintf("no nav message: %s...", files->Strings[0].c_str())); ReadWaitEnd(); - - UpdatePlot(); - UpdateEnable(); + return; + } + if (NavFiles != files) { + NavFiles->Assign(files); + } + UpdateObs(NObs); + UpdateMp(); + ReadWaitEnd(); + + UpdatePlot(); + UpdateEnable(); } // read elevation mask data ------------------------------------------------- -void __fastcall TPlot::ReadElMaskData(AnsiString file) -{ - AnsiString s; - FILE *fp; - double az0=0.0,el0=0.0,az1,el1; - int i,j; - char buff[256]; - - trace(3,"ReadElMaskData\n"); - - for (i=0;i<=360;i++) ElMaskData[i]=0.0; - - if (!(fp=fopen(file.c_str(),"r"))) { - ShowMsg(s.sprintf("no el mask data: %s...",file.c_str())); - ShowLegend(NULL); - return; - } - while (fgets(buff,sizeof(buff),fp)) { - - if (buff[0]=='%'||sscanf(buff,"%lf %lf",&az1,&el1)<2) continue; - - if (az0ProcessMessages(); - - for (time=ts;timediff(time,te)<=0.0;time=timeadd(time,tint)) { - for (i=0;i=Obs.nmax) { - Obs.nmax=Obs.nmax<=0?4096:Obs.nmax*2; - Obs.data=(obsd_t *)realloc(Obs.data,sizeof(obsd_t)*Obs.nmax); - if (!Obs.data) { - Obs.n=Obs.nmax=0; - break; - } - } - data.time=time; - data.sat=i+1; - - for (j=0;jProcessMessages(); + + for (time = ts; timediff(time, te) <= 0.0; time = timeadd(time, tint)) { + for (i = 0; i < MAXSAT; i++) { + satno2id(i + 1, name); + if (!tle_pos(time, name, "", "", &TLEData, NULL, rs)) continue; + if ((r = geodist(rs, rr, e)) <= 0.0) continue; + if (satazel(pos, e, azel) <= 0.0) continue; + if (Obs.n >= Obs.nmax) { + Obs.nmax = Obs.nmax <= 0 ? 4096 : Obs.nmax * 2; + Obs.data = (obsd_t *)realloc(Obs.data, sizeof(obsd_t) * Obs.nmax); + if (!Obs.data) { + Obs.n = Obs.nmax = 0; + break; } - if (++nobs>=MAX_SIMOBS) break; - } - if (Obs.n<=0) { - ReadWaitEnd(); - ShowMsg("no satellite visibility"); - return; - } - UpdateObs(nobs); - - Caption="Satellite Visibility (Predicted)"; - BtnSol1->Down=true; - time2gpst(Obs.data[0].time,&Week); - SolIndex[0]=SolIndex[1]=ObsIndex=0; - if (PlotType= MAX_SIMOBS) break; + } + if (Obs.n <= 0) { ReadWaitEnd(); - UpdateObsType(); - UpdateTime(); - UpdatePlot(); - UpdateEnable(); + ShowMsg("no satellite visibility"); + return; + } + UpdateObs(nobs); + + Caption = "Satellite Visibility (Predicted)"; + BtnSol1->Down = true; + time2gpst(Obs.data[0].time, &Week); + SolIndex[0] = SolIndex[1] = ObsIndex = 0; + if (PlotType < PLOT_OBS || PLOT_DOP < PlotType) { + UpdateType(PLOT_OBS); + } else { + UpdatePlotType(); + } + FitTime(); + ReadWaitEnd(); + UpdateObsType(); + UpdateTime(); + UpdatePlot(); + UpdateEnable(); } // read map image data ------------------------------------------------------ -void __fastcall TPlot::ReadMapData(AnsiString file) -{ - TJPEGImage *image=new TJPEGImage; - AnsiString s; - double pos[3]; - - trace(3,"ReadMapData\n"); - - ShowMsg(s.sprintf("reading map image... %s",file.c_str())); - - try { - image->LoadFromFile(file); - } - catch (Exception &exception) { - ShowMsg(s.sprintf("map file read error: %s",file.c_str())); - ShowLegend(NULL); - return; - } - MapImage->Assign(image); - MapImageFile=file; - MapSize[0]=MapImage->Width; - MapSize[1]=MapImage->Height; - delete image; - - ReadMapTag(file); - if (norm(OPos,3)<=0.0&&(MapLat!=0.0||MapLon!=0.0)) { - pos[0]=MapLat*D2R; - pos[1]=MapLon*D2R; - pos[2]=0.0; - pos2ecef(pos,OPos); - } - BtnShowImg->Down=true; - - MapOptDialog->UpdateField(); - UpdateOrigin(); - UpdatePlot(); - UpdateEnable(); - ShowMsg(""); +void __fastcall TPlot::ReadMapData(AnsiString file) { + TJPEGImage *image = new TJPEGImage; + AnsiString s; + double pos[3]; + + trace(3, "ReadMapData\n"); + + ShowMsg(s.sprintf("reading map image... %s", file.c_str())); + + try { + image->LoadFromFile(file); + } catch (Exception &exception) { + ShowMsg(s.sprintf("map file read error: %s", file.c_str())); + ShowLegend(NULL); + return; + } + MapImage->Assign(image); + MapImageFile = file; + MapSize[0] = MapImage->Width; + MapSize[1] = MapImage->Height; + delete image; + + ReadMapTag(file); + if (norm(OPos, 3) <= 0.0 && (MapLat != 0.0 || MapLon != 0.0)) { + pos[0] = MapLat * D2R; + pos[1] = MapLon * D2R; + pos[2] = 0.0; + pos2ecef(pos, OPos); + } + BtnShowImg->Down = true; + + MapOptDialog->UpdateField(); + UpdateOrigin(); + UpdatePlot(); + UpdateEnable(); + ShowMsg(""); } // resample image pixel ----------------------------------------------------- -#define ResPixelNN(img1,x,y,b1,pix) {\ - int ix=(int)((x)+0.5),iy=(int)((y)+0.5);\ - BYTE *p=(img1)+ix*3+iy*(b1);\ - pix[0]=p[0]; pix[1]=p[1]; pix[2]=p[2];\ -} -#define ResPixelBL(img1,x,y,b1,pix) {\ - int ix=(int)(x),iy=(int)(y);\ - double dx1=(x)-ix,dy1=(y)-iy,dx2=1.0-dx1,dy2=1.0-dy1;\ - double a1=dx2*dy2,a2=dx2*dy1,a3=dx1*dy2,a4=dx1*dy1;\ - BYTE *p1=(img1)+ix*3+iy*(b1),*p2=p1+(b1);\ - pix[0]=(BYTE)(a1*p1[0]+a2*p2[0]+a3*p1[3]+a4*p2[3]);\ - pix[1]=(BYTE)(a1*p1[1]+a2*p2[1]+a3*p1[4]+a4*p2[4]);\ - pix[2]=(BYTE)(a1*p1[2]+a2*p2[2]+a3*p1[5]+a4*p2[5]);\ -} +#define ResPixelNN(img1, x, y, b1, pix) \ + { \ + int ix = (int)((x) + 0.5), iy = (int)((y) + 0.5); \ + BYTE *p = (img1) + ix * 3 + iy * (b1); \ + pix[0] = p[0]; \ + pix[1] = p[1]; \ + pix[2] = p[2]; \ + } +#define ResPixelBL(img1, x, y, b1, pix) \ + { \ + int ix = (int)(x), iy = (int)(y); \ + double dx1 = (x) - ix, dy1 = (y) - iy, dx2 = 1.0 - dx1, dy2 = 1.0 - dy1; \ + double a1 = dx2 * dy2, a2 = dx2 * dy1, a3 = dx1 * dy2, a4 = dx1 * dy1; \ + BYTE *p1 = (img1) + ix * 3 + iy * (b1), *p2 = p1 + (b1); \ + pix[0] = (BYTE)(a1 * p1[0] + a2 * p2[0] + a3 * p1[3] + a4 * p2[3]); \ + pix[1] = (BYTE)(a1 * p1[1] + a2 * p2[1] + a3 * p1[4] + a4 * p2[4]); \ + pix[2] = (BYTE)(a1 * p1[2] + a2 * p2[2] + a3 * p1[5] + a4 * p2[5]); \ + } // rotate coordinates roll-pitch-yaw ---------------------------------------- -static void RPY(const double *rpy, double *R) -{ - double sr=sin(-rpy[0]*D2R),cr=cos(-rpy[0]*D2R); - double sp=sin(-rpy[1]*D2R),cp=cos(-rpy[1]*D2R); - double sy=sin(-rpy[2]*D2R),cy=cos(-rpy[2]*D2R); - R[0]=cy*cr-sy*sp*sr; R[1]=-sy*cp; R[2]=cy*sr+sy*sp*cr; - R[3]=sy*cr+cy*sp*sr; R[4]=cy*cp; R[5]=sy*sr-cy*sp*cr; - R[6]=-cp*sr; R[7]=sp; R[8]=cp*cr; +static void RPY(const double *rpy, double *R) { + double sr = sin(-rpy[0] * D2R), cr = cos(-rpy[0] * D2R); + double sp = sin(-rpy[1] * D2R), cp = cos(-rpy[1] * D2R); + double sy = sin(-rpy[2] * D2R), cy = cos(-rpy[2] * D2R); + R[0] = cy * cr - sy * sp * sr; + R[1] = -sy * cp; + R[2] = cy * sr + sy * sp * cr; + R[3] = sy * cr + cy * sp * sr; + R[4] = cy * cp; + R[5] = sy * sr - cy * sp * cr; + R[6] = -cp * sr; + R[7] = sp; + R[8] = cp * cr; } // RGB -> YCrCb (ITU-R BT.601) ---------------------------------------------- -static void YCrCb(const BYTE *pix, double *Y) -{ - // R(0-255) G(0-255) B(0-255) - Y[0]=( 0.299*pix[0]+0.587*pix[1]+0.114*pix[2])/255; // Y (0-1) - Y[1]=( 0.500*pix[0]-0.419*pix[1]+0.081*pix[2])/255; // Cr (-.5-.5) - Y[2]=(-0.169*pix[0]-0.331*pix[1]+0.500*pix[2])/255; // Cb (-.5-.5) +static void YCrCb(const BYTE *pix, double *Y) { + // R(0-255) G(0-255) B(0-255) + Y[0] = (0.299 * pix[0] + 0.587 * pix[1] + 0.114 * pix[2]) / 255; // Y (0-1) + Y[1] = (0.500 * pix[0] - 0.419 * pix[1] + 0.081 * pix[2]) / 255; // Cr (-.5-.5) + Y[2] = (-0.169 * pix[0] - 0.331 * pix[1] + 0.500 * pix[2]) / 255; // Cb (-.5-.5) } // update sky image --------------------------------------------------------- -void __fastcall TPlot::UpdateSky(void) -{ - BITMAP bm1,bm2; - BYTE *pix; - double x,y,xp,yp,r,a,b,p[3],q[3],R[9]={0},dr,dist,Yz[3]={0},Y[3]; - int i,j,k,w1,h1,b1,w2,h2,b2,wz,nz=0; - - if (!GetObject(SkyImageI->Handle,sizeof(bm1),&bm1)|| - !GetObject(SkyImageR->Handle,sizeof(bm2),&bm2)|| - bm1.bmBitsPixel!=24) return; - w1=bm1.bmWidth; h1=bm1.bmHeight; b1=bm1.bmWidthBytes; - w2=bm2.bmWidth; h2=bm2.bmHeight; b2=bm2.bmWidthBytes; - - if (w1<=0||h1<=0||b11e-12) { - RPY(SkyFov,R); - } - if (SkyBinarize) { // average of zenith image - wz=h1/16; // sky area size - for (i=w1/2-wz;i<=w1/2+wz;i++) for (j=h1/2-wz;j<=h1/2+wz;j++) { - pix=(BYTE *)bm1.bmBits+i*3+j*b1; - YCrCb(pix,Y); - for (k=0;k<3;k++) Yz[k]+=Y[k]; - nz++; - } - if (nz>0) { - for (k=0;k<3;k++) Yz[k]/=nz; - } - } - for (j=0;j1.0) continue; - - // rotate coordinates roll-pitch-yaw - if (norm(SkyFov,3)>1e-12) { - if (r<1e-12) { - p[0]=p[1]=0.0; - p[2]=1.0; - } - else { - a=sin(r*PI/2.0); - p[0]=a*xp/r; - p[1]=a*yp/r; - p[2]=cos(r*PI/2.0); - } - q[0]=R[0]*p[0]+R[3]*p[1]+R[6]*p[2]; - q[1]=R[1]*p[0]+R[4]*p[1]+R[7]*p[2]; - q[2]=R[2]*p[0]+R[5]*p[1]+R[8]*p[2]; - if (q[2]>=1.0) { - xp=yp=r=0.0; - } - else { - r=acos(q[2])/(PI/2.0); - a=SQRT(SQR(q[0])+SQR(q[1])); - xp=r*q[0]/a; - yp=r*q[1]/a; - } - } - // correct lense distortion - if (SkyDestCorr) { - if (r<=0.0||r>=1.0) continue; - k=(int)(r*9.0); dr=r*9.0-k; - dist=k>8?SkyDest[9]:(1.0-dr)*SkyDest[k]+dr*SkyDest[k+1]; - xp*=dist/r; - yp*=dist/r; - } - else { - xp*=SkyScale; - yp*=SkyScale; - } - if (SkyFlip) xp=-xp; - x=SkyCent[0]+xp; - y=SkyCent[1]+yp; - if (x<0.0||x>=w1-1||y<0.0||y>=h1-1) continue; - pix=(BYTE *)bm2.bmBits+i*3+j*b2; - if (!SkyRes) { - ResPixelNN((BYTE *)bm1.bmBits,x,y,b1,pix) +void __fastcall TPlot::UpdateSky(void) { + BITMAP bm1, bm2; + BYTE *pix; + double x, y, xp, yp, r, a, b, p[3], q[3], R[9] = {0}, dr, dist, Yz[3] = {0}, Y[3]; + int i, j, k, w1, h1, b1, w2, h2, b2, wz, nz = 0; + + if (!GetObject(SkyImageI->Handle, sizeof(bm1), &bm1) || + !GetObject(SkyImageR->Handle, sizeof(bm2), &bm2) || bm1.bmBitsPixel != 24) + return; + w1 = bm1.bmWidth; + h1 = bm1.bmHeight; + b1 = bm1.bmWidthBytes; + w2 = bm2.bmWidth; + h2 = bm2.bmHeight; + b2 = bm2.bmWidthBytes; + + if (w1 <= 0 || h1 <= 0 || b1 < w1 * 3 || w2 <= 0 || h2 <= 0 || b2 < w2 * 3) return; + + memset(bm2.bmBits, 224, b2 * h2); // fill bitmap by silver + + if (norm(SkyFov, 3) > 1e-12) { + RPY(SkyFov, R); + } + if (SkyBinarize) { // average of zenith image + wz = h1 / 16; // sky area size + for (i = w1 / 2 - wz; i <= w1 / 2 + wz; i++) + for (j = h1 / 2 - wz; j <= h1 / 2 + wz; j++) { + pix = (BYTE *)bm1.bmBits + i * 3 + j * b1; + YCrCb(pix, Y); + for (k = 0; k < 3; k++) Yz[k] += Y[k]; + nz++; + } + if (nz > 0) { + for (k = 0; k < 3; k++) Yz[k] /= nz; + } + } + for (j = 0; j < h2; j++) + for (i = 0; i < w2; i++) { + xp = (w2 / 2.0 - i) / SkyScaleR; + yp = (j - h2 / 2.0) / SkyScaleR; + r = sqrt(SQR(xp) + SQR(yp)); + if (SkyElMask && r > 1.0) continue; + + // rotate coordinates roll-pitch-yaw + if (norm(SkyFov, 3) > 1e-12) { + if (r < 1e-12) { + p[0] = p[1] = 0.0; + p[2] = 1.0; + } else { + a = sin(r * PI / 2.0); + p[0] = a * xp / r; + p[1] = a * yp / r; + p[2] = cos(r * PI / 2.0); } - else { - ResPixelBL((BYTE *)bm1.bmBits,x,y,b1,pix) + q[0] = R[0] * p[0] + R[3] * p[1] + R[6] * p[2]; + q[1] = R[1] * p[0] + R[4] * p[1] + R[7] * p[2]; + q[2] = R[2] * p[0] + R[5] * p[1] + R[8] * p[2]; + if (q[2] >= 1.0) { + xp = yp = r = 0.0; + } else { + r = acos(q[2]) / (PI / 2.0); + a = SQRT(SQR(q[0]) + SQR(q[1])); + xp = r * q[0] / a; + yp = r * q[1] / a; } - if (SkyBinarize) { - YCrCb(pix,Y); - for (k=1;k<3;k++) Y[k]-=Yz[k]; - - // threshold by brightness and color-distance - if (Y[0]>SkyBinThres1&&norm(Y+1,2)= 1.0) continue; + k = (int)(r * 9.0); + dr = r * 9.0 - k; + dist = k > 8 ? SkyDest[9] : (1.0 - dr) * SkyDest[k] + dr * SkyDest[k + 1]; + xp *= dist / r; + yp *= dist / r; + } else { + xp *= SkyScale; + yp *= SkyScale; + } + if (SkyFlip) xp = -xp; + x = SkyCent[0] + xp; + y = SkyCent[1] + yp; + if (x < 0.0 || x >= w1 - 1 || y < 0.0 || y >= h1 - 1) continue; + pix = (BYTE *)bm2.bmBits + i * 3 + j * b2; + if (!SkyRes) { + ResPixelNN((BYTE *)bm1.bmBits, x, y, b1, pix) + } else { + ResPixelBL((BYTE *)bm1.bmBits, x, y, b1, pix) + } + if (SkyBinarize) { + YCrCb(pix, Y); + for (k = 1; k < 3; k++) Y[k] -= Yz[k]; + + // threshold by brightness and color-distance + if (Y[0] > SkyBinThres1 && norm(Y + 1, 2) < SkyBinThres2) { + pix[0] = pix[1] = pix[2] = 255; // sky + } else { + pix[0] = pix[1] = pix[2] = 96; // others } + } } - UpdatePlot(); + UpdatePlot(); } // read sky tag data -------------------------------------------------------- -void __fastcall TPlot::ReadSkyTag(AnsiString file) -{ - FILE *fp; - char buff[1024],*p; - - trace(3,"ReadSkyTag\n"); - - if (!(fp=fopen(file.c_str(),"r"))) return; - - while (fgets(buff,sizeof(buff),fp)) { - if (buff[0]=='\0'||buff[0]=='%'||buff[0]=='#') continue; - if (!(p=strchr(buff,'='))) continue; - *p='\0'; - if (strstr(buff,"centx" )==buff) sscanf(p+1,"%lf",SkyCent ); - else if (strstr(buff,"centy" )==buff) sscanf(p+1,"%lf",SkyCent+1 ); - else if (strstr(buff,"scale" )==buff) sscanf(p+1,"%lf",&SkyScale ); - else if (strstr(buff,"roll" )==buff) sscanf(p+1,"%lf",SkyFov ); - else if (strstr(buff,"pitch" )==buff) sscanf(p+1,"%lf",SkyFov+1 ); - else if (strstr(buff,"yaw" )==buff) sscanf(p+1,"%lf",SkyFov+2 ); - else if (strstr(buff,"destcorr")==buff) sscanf(p+1,"%d",&SkyDestCorr); - else if (strstr(buff,"elmask" )==buff) sscanf(p+1,"%d",&SkyElMask ); - else if (strstr(buff,"resample")==buff) sscanf(p+1,"%d",&SkyRes ); - else if (strstr(buff,"flip" )==buff) sscanf(p+1,"%d",&SkyFlip ); - else if (strstr(buff,"dest" )==buff) { - sscanf(p+1,"%lf %lf %lf %lf %lf %lf %lf %lf %lf",SkyDest+1, - SkyDest+2,SkyDest+3,SkyDest+4,SkyDest+5,SkyDest+6,SkyDest+7, - SkyDest+8,SkyDest+9); - } - else if (strstr(buff,"binarize")==buff) sscanf(p+1,"%d",&SkyBinarize); - else if (strstr(buff,"binthr1")==buff) sscanf(p+1,"%lf",&SkyBinThres1); - else if (strstr(buff,"binthr2")==buff) sscanf(p+1,"%lf",&SkyBinThres2); - } - fclose(fp); +void __fastcall TPlot::ReadSkyTag(AnsiString file) { + FILE *fp; + char buff[1024], *p; + + trace(3, "ReadSkyTag\n"); + + if (!(fp = fopen(file.c_str(), "r"))) return; + + while (fgets(buff, sizeof(buff), fp)) { + if (buff[0] == '\0' || buff[0] == '%' || buff[0] == '#') continue; + if (!(p = strchr(buff, '='))) continue; + *p = '\0'; + if (strstr(buff, "centx") == buff) + sscanf(p + 1, "%lf", SkyCent); + else if (strstr(buff, "centy") == buff) + sscanf(p + 1, "%lf", SkyCent + 1); + else if (strstr(buff, "scale") == buff) + sscanf(p + 1, "%lf", &SkyScale); + else if (strstr(buff, "roll") == buff) + sscanf(p + 1, "%lf", SkyFov); + else if (strstr(buff, "pitch") == buff) + sscanf(p + 1, "%lf", SkyFov + 1); + else if (strstr(buff, "yaw") == buff) + sscanf(p + 1, "%lf", SkyFov + 2); + else if (strstr(buff, "destcorr") == buff) + sscanf(p + 1, "%d", &SkyDestCorr); + else if (strstr(buff, "elmask") == buff) + sscanf(p + 1, "%d", &SkyElMask); + else if (strstr(buff, "resample") == buff) + sscanf(p + 1, "%d", &SkyRes); + else if (strstr(buff, "flip") == buff) + sscanf(p + 1, "%d", &SkyFlip); + else if (strstr(buff, "dest") == buff) { + sscanf(p + 1, "%lf %lf %lf %lf %lf %lf %lf %lf %lf", SkyDest + 1, SkyDest + 2, SkyDest + 3, + SkyDest + 4, SkyDest + 5, SkyDest + 6, SkyDest + 7, SkyDest + 8, SkyDest + 9); + } else if (strstr(buff, "binarize") == buff) + sscanf(p + 1, "%d", &SkyBinarize); + else if (strstr(buff, "binthr1") == buff) + sscanf(p + 1, "%lf", &SkyBinThres1); + else if (strstr(buff, "binthr2") == buff) + sscanf(p + 1, "%lf", &SkyBinThres2); + } + fclose(fp); } // read sky image data ------------------------------------------------------ -void __fastcall TPlot::ReadSkyData(AnsiString file) -{ - TJPEGImage *image=new TJPEGImage; - AnsiString s; - int i,w,h,wr; - - trace(3,"ReadSkyData\n"); - - ShowMsg(s.sprintf("reading sky image... %s",file.c_str())); - - try { - image->LoadFromFile(file); - } - catch (Exception &exception) { - ShowMsg(s.sprintf("sky image file read error: %s",file.c_str())); - ShowLegend(NULL); - return; - } - SkyImageI->Assign(image); - SkyImageR->Assign(image); - w=MAX(SkyImageI->Width,SkyImageI->Height); - h=MIN(SkyImageI->Width,SkyImageI->Height); - wr=MIN(w,MAX_SKYIMG_R); - SkyImageR->SetSize(wr,wr); - SkyImageFile=file; - SkySize[0]=SkyImageI->Width; - SkySize[1]=SkyImageI->Height; - SkyCent[0]=SkySize[0]/2.0; - SkyCent[1]=SkySize[1]/2.0; - SkyFov[0]=SkyFov[1]=SkyFov[2]=0.0; - SkyScale=h/2.0; - SkyScaleR=SkyScale*wr/w; - SkyDestCorr=SkyRes=SkyFlip=0; - SkyElMask=1; - for (i=0;i<10;i++) SkyDest[i]=0.0; - delete image; - - ReadSkyTag(file+".tag"); - - ShowMsg(""); - BtnShowImg->Down=true; - - UpdateSky(); +void __fastcall TPlot::ReadSkyData(AnsiString file) { + TJPEGImage *image = new TJPEGImage; + AnsiString s; + int i, w, h, wr; + + trace(3, "ReadSkyData\n"); + + ShowMsg(s.sprintf("reading sky image... %s", file.c_str())); + + try { + image->LoadFromFile(file); + } catch (Exception &exception) { + ShowMsg(s.sprintf("sky image file read error: %s", file.c_str())); + ShowLegend(NULL); + return; + } + SkyImageI->Assign(image); + SkyImageR->Assign(image); + w = MAX(SkyImageI->Width, SkyImageI->Height); + h = MIN(SkyImageI->Width, SkyImageI->Height); + wr = MIN(w, MAX_SKYIMG_R); + SkyImageR->SetSize(wr, wr); + SkyImageFile = file; + SkySize[0] = SkyImageI->Width; + SkySize[1] = SkyImageI->Height; + SkyCent[0] = SkySize[0] / 2.0; + SkyCent[1] = SkySize[1] / 2.0; + SkyFov[0] = SkyFov[1] = SkyFov[2] = 0.0; + SkyScale = h / 2.0; + SkyScaleR = SkyScale * wr / w; + SkyDestCorr = SkyRes = SkyFlip = 0; + SkyElMask = 1; + for (i = 0; i < 10; i++) SkyDest[i] = 0.0; + delete image; + + ReadSkyTag(file + ".tag"); + + ShowMsg(""); + BtnShowImg->Down = true; + + UpdateSky(); } // read map tag data -------------------------------------------------------- -void __fastcall TPlot::ReadMapTag(AnsiString file) -{ - FILE *fp; - char buff[1024],*p; - - trace(3,"ReadMapTag\n"); - - file=file+".tag"; - - if (!(fp=fopen(file.c_str(),"r"))) return; - - MapScaleX=MapScaleY=1.0; - MapScaleEq=0; - MapLat=MapLon=0.0; - - while (fgets(buff,sizeof(buff),fp)) { - if (buff[0]=='\0'||buff[0]=='%'||buff[0]=='#') continue; - if (!(p=strchr(buff,'='))) continue; - *p='\0'; - if (strstr(buff,"scalex" )==buff) sscanf(p+1,"%lf",&MapScaleX ); - else if (strstr(buff,"scaley" )==buff) sscanf(p+1,"%lf",&MapScaleY ); - else if (strstr(buff,"scaleeq")==buff) sscanf(p+1,"%d" ,&MapScaleEq); - else if (strstr(buff,"lat" )==buff) sscanf(p+1,"%lf",&MapLat ); - else if (strstr(buff,"lon" )==buff) sscanf(p+1,"%lf",&MapLon ); - } - fclose(fp); +void __fastcall TPlot::ReadMapTag(AnsiString file) { + FILE *fp; + char buff[1024], *p; + + trace(3, "ReadMapTag\n"); + + file = file + ".tag"; + + if (!(fp = fopen(file.c_str(), "r"))) return; + + MapScaleX = MapScaleY = 1.0; + MapScaleEq = 0; + MapLat = MapLon = 0.0; + + while (fgets(buff, sizeof(buff), fp)) { + if (buff[0] == '\0' || buff[0] == '%' || buff[0] == '#') continue; + if (!(p = strchr(buff, '='))) continue; + *p = '\0'; + if (strstr(buff, "scalex") == buff) + sscanf(p + 1, "%lf", &MapScaleX); + else if (strstr(buff, "scaley") == buff) + sscanf(p + 1, "%lf", &MapScaleY); + else if (strstr(buff, "scaleeq") == buff) + sscanf(p + 1, "%d", &MapScaleEq); + else if (strstr(buff, "lat") == buff) + sscanf(p + 1, "%lf", &MapLat); + else if (strstr(buff, "lon") == buff) + sscanf(p + 1, "%lf", &MapLon); + } + fclose(fp); } // read shapefile ----------------------------------------------------------- -void __fastcall TPlot::ReadShapeFile(TStrings *files) -{ - UnicodeString name; - AnsiString s; - double pos[3]; - char path[1024]; - int i,j; - - ReadWaitStart(); - - gis_free(&Gis); - - for (i=0;iCount&&iStrings[i]).c_str()); - ShowMsg(s.sprintf("reading shapefile... %s",path)); - gis_read(path,&Gis,i); - - name=files->Strings[i]; - while ((j=name.Pos(L"\\"))) { - name=name.SubString(j+1,name.Length()-j); - } - if ((j=name.Pos(L"."))) { - name=name.SubString(1,j-1); - } - strcpy(Gis.name[i],U2A(name).c_str()); +void __fastcall TPlot::ReadShapeFile(TStrings *files) { + UnicodeString name; + AnsiString s; + double pos[3]; + char path[1024]; + int i, j; + + ReadWaitStart(); + + gis_free(&Gis); + + for (i = 0; i < files->Count && i < MAXMAPLAYER; i++) { + strcpy(path, U2A(files->Strings[i]).c_str()); + ShowMsg(s.sprintf("reading shapefile... %s", path)); + gis_read(path, &Gis, i); + + name = files->Strings[i]; + while ((j = name.Pos(L"\\"))) { + name = name.SubString(j + 1, name.Length() - j); } - ReadWaitEnd(); - ShowMsg(""); - - BtnShowMap->Down=true; - - if (norm(OPos,3)<=0.0) { - pos[0]=(Gis.bound[0]+Gis.bound[1])/2.0; - pos[1]=(Gis.bound[2]+Gis.bound[3])/2.0; - pos[2]=0.0; - pos2ecef(pos,OPos); + if ((j = name.Pos(L"."))) { + name = name.SubString(1, j - 1); } - UpdateOrigin(); - UpdatePlot(); - UpdateEnable(); + strcpy(Gis.name[i], U2A(name).c_str()); + } + ReadWaitEnd(); + ShowMsg(""); + + BtnShowMap->Down = true; + + if (norm(OPos, 3) <= 0.0) { + pos[0] = (Gis.bound[0] + Gis.bound[1]) / 2.0; + pos[1] = (Gis.bound[2] + Gis.bound[3]) / 2.0; + pos[2] = 0.0; + pos2ecef(pos, OPos); + } + UpdateOrigin(); + UpdatePlot(); + UpdateEnable(); } // read GPX file ------------------------------------------------------------ -void __fastcall TPlot::ReadGpxFile(AnsiString file) -{ - AnsiString label1(L""))&&norm(pos,2)>0.0) { - sscanf(p+strlen(""),"%lf",pos+2); - } - else if ((p=strstr(buff,""))&&norm(pos,3)>0.0) { - sscanf(p+strlen(""),"%[^<]",name); - } - else if ((p=strstr(buff,label1.c_str()))&&norm(pos,3)>0.0&&!name[0]) { - sscanf(p+strlen(label1.c_str()),"%[^<]",name); - } - else if ((p=strstr(buff,label2.c_str()))&&norm(pos,3)>0.0&&!name[0]) { - sscanf(p+strlen(label2.c_str()),"%[^<]",name); - } - else if (strstr(buff,"")&&norm(pos,3)>0.0) { - PntPos[NWayPnt][0]=pos[0]; - PntPos[NWayPnt][1]=pos[1]; - PntPos[NWayPnt][2]=pos[2]; - PntName[NWayPnt++]=name; // UTF-8 - pos[0]=pos[1]=pos[2]=0.0; - name[0]='\0'; - } - } - fclose(fp); +void __fastcall TPlot::ReadGpxFile(AnsiString file) { + AnsiString label1(L"")) && norm(pos, 2) > 0.0) { + sscanf(p + strlen(""), "%lf", pos + 2); + } else if ((p = strstr(buff, "")) && norm(pos, 3) > 0.0) { + sscanf(p + strlen(""), "%[^<]", name); + } else if ((p = strstr(buff, label1.c_str())) && norm(pos, 3) > 0.0 && !name[0]) { + sscanf(p + strlen(label1.c_str()), "%[^<]", name); + } else if ((p = strstr(buff, label2.c_str())) && norm(pos, 3) > 0.0 && !name[0]) { + sscanf(p + strlen(label2.c_str()), "%[^<]", name); + } else if (strstr(buff, "") && norm(pos, 3) > 0.0) { + PntPos[NWayPnt][0] = pos[0]; + PntPos[NWayPnt][1] = pos[1]; + PntPos[NWayPnt][2] = pos[2]; + PntName[NWayPnt++] = name; // UTF-8 + pos[0] = pos[1] = pos[2] = 0.0; + name[0] = '\0'; + } + } + fclose(fp); } // read pos file ------------------------------------------------------------ -void __fastcall TPlot::ReadPosFile(AnsiString file) -{ - FILE *fp; - char buff[1024],id[256],name[256],*p; - double pos[3]={0}; - int n; - - if (!(fp=fopen(file.c_str(),"r"))) return; - - NWayPnt=0; - - while (fgets(buff,sizeof(buff),fp)&&NWayPnt=4) { - PntPos[NWayPnt][0]=pos[0]; - PntPos[NWayPnt][1]=pos[1]; - PntPos[NWayPnt][2]=pos[2]; - UnicodeString unicode_str=(n>=5)?name:id; - AnsiString utf8_str=unicode_str; - PntName[NWayPnt++]=utf8_str; - } - } - fclose(fp); +void __fastcall TPlot::ReadPosFile(AnsiString file) { + FILE *fp; + char buff[1024], id[256], name[256], *p; + double pos[3] = {0}; + int n; + + if (!(fp = fopen(file.c_str(), "r"))) return; + + NWayPnt = 0; + + while (fgets(buff, sizeof(buff), fp) && NWayPnt < MAXWAYPNT) { + if ((p = strchr(buff, '#'))) *p = '\0'; + + n = sscanf(buff, "%lf %lf %lf %255s %255s", pos, pos + 1, pos + 2, id, name); + + if (n >= 4) { + PntPos[NWayPnt][0] = pos[0]; + PntPos[NWayPnt][1] = pos[1]; + PntPos[NWayPnt][2] = pos[2]; + UnicodeString unicode_str = (n >= 5) ? name : id; + AnsiString utf8_str = unicode_str; + PntName[NWayPnt++] = utf8_str; + } + } + fclose(fp); } // read waypoint ------------------------------------------------------------ -void __fastcall TPlot::ReadWaypoint(AnsiString file) -{ - AnsiString s; - int type=0; - char *p; - - if ((p=strrchr(file.c_str(),'.'))&&!strcmp(p,".gpx")) type=1; - - ReadWaitStart(); - ShowMsg(s.sprintf("reading waypoint... %s",file.c_str())); - - if (type) ReadGpxFile(file); - else ReadPosFile(file); - - ReadWaitEnd(); - ShowMsg(""); - - BtnShowMap->Down=true; - - UpdatePlot(); - UpdateEnable(); - PntDialog->SetPoint(); +void __fastcall TPlot::ReadWaypoint(AnsiString file) { + AnsiString s; + int type = 0; + char *p; + + if ((p = strrchr(file.c_str(), '.')) && !strcmp(p, ".gpx")) type = 1; + + ReadWaitStart(); + ShowMsg(s.sprintf("reading waypoint... %s", file.c_str())); + + if (type) + ReadGpxFile(file); + else + ReadPosFile(file); + + ReadWaitEnd(); + ShowMsg(""); + + BtnShowMap->Down = true; + + UpdatePlot(); + UpdateEnable(); + PntDialog->SetPoint(); } // save GPX file ------------------------------------------------------------ -void __fastcall TPlot::SaveGpxFile(AnsiString file) -{ - FILE *fp; - int i; - - if (!(fp=fopen(file.c_str(),"w"))) return; - - fprintf(fp,HEADXML); - fprintf(fp,HEADGPX,"RTKLIB " VER_RTKLIB,XMLNS); - - for (i=0;i\n",PntPos[i][0], - PntPos[i][1]); - if (PntPos[i][2]!=0.0) { - fprintf(fp," %.4f\n",PntPos[i][2]); - } - AnsiString str(PntName[i]); - fprintf(fp," %s\n",str.c_str()); // UTF-8 - fprintf(fp,"\n"); - } - fprintf(fp,"%s\n",TAILGPX); - fclose(fp); +void __fastcall TPlot::SaveGpxFile(AnsiString file) { + FILE *fp; + int i; + + if (!(fp = fopen(file.c_str(), "w"))) return; + + fprintf(fp, HEADXML); + fprintf(fp, HEADGPX, "RTKLIB " VER_RTKLIB, XMLNS); + + for (i = 0; i < NWayPnt; i++) { + fprintf(fp, "\n", PntPos[i][0], PntPos[i][1]); + if (PntPos[i][2] != 0.0) { + fprintf(fp, " %.4f\n", PntPos[i][2]); + } + AnsiString str(PntName[i]); + fprintf(fp, " %s\n", str.c_str()); // UTF-8 + fprintf(fp, "\n"); + } + fprintf(fp, "%s\n", TAILGPX); + fclose(fp); } // save pos file ------------------------------------------------------------ -void __fastcall TPlot::SavePosFile(AnsiString file) -{ - FILE *fp; - int i; - - if (!(fp=fopen(file.c_str(),"w"))) return; - - fprintf(fp,"# WAYPOINTS by RTKLIB %s\n",VER_RTKLIB); - - for (i=0;i=%.0fdeg)\n",TimeLabel==0?13:19, - tlabel,"NSAT","GDOP","PDOP","HDOP","VDOP",ElMask); - - for (i=0;i=%.0fdeg)\n", TimeLabel == 0 ? 13 : 19, tlabel, + "NSAT", "GDOP", "PDOP", "HDOP", "VDOP", ElMask); + + for (i = 0; i < NObs; i++) { + ns = 0; + for (j = IndexObs[i]; j < Obs.n && j < IndexObs[i + 1]; j++) { + if (SatMask[Obs.data[j].sat - 1]) continue; + if (El[j] < ElMask * D2R) continue; + if (ElMaskP && El[j] < ElMaskData[(int)(Az[j] * R2D + 0.5)]) continue; + azel[ns * 2] = Az[j]; + azel[1 + ns * 2] = El[j]; + ns++; + } + if (ns <= 0) continue; + + dops(ns, azel, ElMask * D2R, dop); + + time = Obs.data[IndexObs[i]].time; + if (TimeLabel == 0) { + tow = time2gpst(time, &week); + snprintf(tstr, sizeof(tstr), "%4d %8.1f ", week, tow); + } else if (TimeLabel == 1) { + time2str(time, tstr, 1); + } else if (TimeLabel == 2) { + time2str(gpst2utc(time), tstr, 1); + } else { + time2str(timeadd(gpst2utc(time), 9 * 3600.0), tstr, 1); + } + fprintf(fp, "%s %6d %8.1f %8.1f %8.1f %8.1f\n", tstr, ns, dop[0], dop[1], dop[2], dop[3]); + } + fclose(fp); } // save snr and mp ------------------------------------------------------------- -void __fastcall TPlot::SaveSnrMp(AnsiString file) -{ - FILE *fp; - AnsiString ObsTypeText=ObsType2->Text; - gtime_t time; - double tow; - char sat[8],mp[32],tstr[40],*code=ObsTypeText.c_str()+1; - const char *tlabel; - int i,j,k,week; - - trace(3,"SaveSnrMp: file=%s\n",file.c_str()); - - if (!(fp=fopen(file.c_str(),"w"))) return; - - tlabel=TimeLabel<=1?"TIME (GPST)":(TimeLabel<=2?"TIME (UTC)":"TIME (JST)"); - - sprintf(mp,"%s MP(m)",ObsTypeText.c_str()); - fprintf(fp,"%% %-*s %6s %8s %8s %9s %10s\n",TimeLabel==0?13:19,tlabel,"SAT", - "AZ(deg)","EL(deg)","SNR(dBHz)",mp); - - for (i=0;i=NFREQ+NEXOBS) continue; - - time=Obs.data[j].time; - - if (TimeLabel==0) { - tow=time2gpst(time,&week); - snprintf(tstr,sizeof(tstr),"%4d %9.1f ",week,tow); - } - else if (TimeLabel==1) { - time2str(time,tstr,1); - } - else if (TimeLabel==2) { - time2str(gpst2utc(time),tstr,1); - } - else { - time2str(timeadd(gpst2utc(time),9*3600.0),tstr,1); - } - fprintf(fp,"%s %6s %8.1f %8.1f %9.2f %10.4f\n",tstr,sat,Az[j]*R2D, - El[j]*R2D,Obs.data[j].SNR[k],!Mp[k]?0.0:Mp[k][j]); - } - } - fclose(fp); +void __fastcall TPlot::SaveSnrMp(AnsiString file) { + FILE *fp; + AnsiString ObsTypeText = ObsType2->Text; + gtime_t time; + double tow; + char sat[8], mp[32], tstr[40], *code = ObsTypeText.c_str() + 1; + const char *tlabel; + int i, j, k, week; + + trace(3, "SaveSnrMp: file=%s\n", file.c_str()); + + if (!(fp = fopen(file.c_str(), "w"))) return; + + tlabel = TimeLabel <= 1 ? "TIME (GPST)" : (TimeLabel <= 2 ? "TIME (UTC)" : "TIME (JST)"); + + sprintf(mp, "%s MP(m)", ObsTypeText.c_str()); + fprintf(fp, "%% %-*s %6s %8s %8s %9s %10s\n", TimeLabel == 0 ? 13 : 19, tlabel, "SAT", "AZ(deg)", + "EL(deg)", "SNR(dBHz)", mp); + + for (i = 0; i < MAXSAT; i++) { + if (SatMask[i] || !SatSel[i]) continue; + satno2id(i + 1, sat); + + for (j = 0; j < Obs.n; j++) { + if (Obs.data[j].sat != i + 1) continue; + + for (k = 0; k < NFREQ + NEXOBS; k++) { + if (strchr(code2obs(Obs.data[j].code[k]), code[0])) break; + } + if (k >= NFREQ + NEXOBS) continue; + + time = Obs.data[j].time; + + if (TimeLabel == 0) { + tow = time2gpst(time, &week); + snprintf(tstr, sizeof(tstr), "%4d %9.1f ", week, tow); + } else if (TimeLabel == 1) { + time2str(time, tstr, 1); + } else if (TimeLabel == 2) { + time2str(gpst2utc(time), tstr, 1); + } else { + time2str(timeadd(gpst2utc(time), 9 * 3600.0), tstr, 1); + } + fprintf(fp, "%s %6s %8.1f %8.1f %9.2f %10.4f\n", tstr, sat, Az[j] * R2D, El[j] * R2D, + Obs.data[j].SNR[k], !Mp[k] ? 0.0 : Mp[k][j]); + } + } + fclose(fp); } // save elev mask -------------------------------------------------------------- -void __fastcall TPlot::SaveElMask(AnsiString file) -{ - FILE *fp; - double el,el0=0.0; - int az; - - trace(3,"SaveElMask: file=%s\n",file.c_str()); - - if (!(fp=fopen(file.c_str(),"w"))) return; - - fprintf(fp,"%% Elevation Mask\n"); - fprintf(fp,"%% AZ(deg) EL(deg)\n"); - - for (az=0;az<=360;az++) { - el=floor(ElMaskData[az]*R2D/0.1+0.5)*0.1; - if (el==el0) continue; - fprintf(fp,"%9.1f %6.1f\n",(double)az,el); - el0=el; - } - fclose(fp); +void __fastcall TPlot::SaveElMask(AnsiString file) { + FILE *fp; + double el, el0 = 0.0; + int az; + + trace(3, "SaveElMask: file=%s\n", file.c_str()); + + if (!(fp = fopen(file.c_str(), "w"))) return; + + fprintf(fp, "%% Elevation Mask\n"); + fprintf(fp, "%% AZ(deg) EL(deg)\n"); + + for (az = 0; az <= 360; az++) { + el = floor(ElMaskData[az] * R2D / 0.1 + 0.5) * 0.1; + if (el == el0) continue; + fprintf(fp, "%9.1f %6.1f\n", (double)az, el); + el0 = el; + } + fclose(fp); } // connect to external sources ---------------------------------------------- -void __fastcall TPlot::Connect(void) -{ - AnsiString s; - char *cmd,*path,buff[MAXSTRPATH],*p; - const char *name[2]={"",""}; - int i,mode=STR_MODE_R; - - trace(3,"Connect\n"); - - if (ConnectState) return; - - for (i=0;i<2;i++) { - if (RtStream[i]==STR_NONE ) continue; - else if (RtStream[i]==STR_SERIAL ) path=StrPaths[i][0].c_str(); - else if (RtStream[i]==STR_FILE ) path=StrPaths[i][2].c_str(); - else if (RtStream[i]<=STR_NTRIPCLI) path=StrPaths[i][1].c_str(); - else continue; - - if (RtStream[i]==STR_FILE||!SolData[i].cyclic||SolData[i].nmax!=RtBuffSize+1) { - Clear(); - initsolbuf(SolData+i,1,RtBuffSize+1); - } - if (RtStream[i]==STR_SERIAL) mode=STR_MODE_RW; - - strcpy(buff,path); - if ((p=strstr(buff,"::"))) *p='\0'; - if ((p=strstr(buff,"/:"))) *p='\0'; - if ((p=strstr(buff,"@"))) name[i]=p+1; else name[i]=buff; - - if (!stropen(Stream+i,RtStream[i],mode,path)) { - ShowMsg(s.sprintf("connect error: %s",name)); - ShowLegend(NULL); - trace(1,"stream open error: ch=%d type=%d path=%s\n",i+1,RtStream[i],path); - continue; - } - strsettimeout(Stream+i,RtTimeOutTime,RtReConnTime); - - if (StrCmdEna[i][0]) { - cmd=StrCmds[i][0].c_str(); - strwrite(Stream+i,(uint8_t *)cmd,strlen(cmd)); - } - ConnectState=1; +void __fastcall TPlot::Connect(void) { + AnsiString s; + char *cmd, *path, buff[MAXSTRPATH], *p; + const char *name[2] = {"", ""}; + int i, mode = STR_MODE_R; + + trace(3, "Connect\n"); + + if (ConnectState) return; + + for (i = 0; i < 2; i++) { + if (RtStream[i] == STR_NONE) + continue; + else if (RtStream[i] == STR_SERIAL) + path = StrPaths[i][0].c_str(); + else if (RtStream[i] == STR_FILE) + path = StrPaths[i][2].c_str(); + else if (RtStream[i] <= STR_NTRIPCLI) + path = StrPaths[i][1].c_str(); + else + continue; + + if (RtStream[i] == STR_FILE || !SolData[i].cyclic || SolData[i].nmax != RtBuffSize + 1) { + Clear(); + initsolbuf(SolData + i, 1, RtBuffSize + 1); } - if (!ConnectState) return; - - if (Title!="") Caption=Title; - else Caption=s.sprintf("CONNECT %s %s",name[0],name[1]); - - BtnConnect->Down=true; - BtnSol1 ->Down=*name[0]; - BtnSol2 ->Down=*name[1]; - BtnSol12 ->Down=false; - BtnShowTrack->Down=true; - BtnFixHoriz->Down=true; - BtnFixCent ->Down=true; - BtnReload->Visible=false; - StrStatus->Left=Panel11->Width-BtnOptions->Width; - StrStatus->Visible=true; - UpdateTime(); - UpdatePlot(); - UpdateEnable(); -} -// disconnect from external sources ----------------------------------------- -void __fastcall TPlot::Disconnect(void) -{ - AnsiString s; - char *cmd,caption[1024]; - int i; - - trace(3,"Disconnect\n"); - - if (!ConnectState) return; - - ConnectState=0; - - for (i=0;i<2;i++) { - if (StrCmdEna[i][1]) { - cmd=StrCmds[i][1].c_str(); - strwrite(Stream+i,(uint8_t *)cmd,strlen(cmd)); - } - strclose(Stream+i); + if (RtStream[i] == STR_SERIAL) mode = STR_MODE_RW; + + strcpy(buff, path); + if ((p = strstr(buff, "::"))) *p = '\0'; + if ((p = strstr(buff, "/:"))) *p = '\0'; + if ((p = strstr(buff, "@"))) + name[i] = p + 1; + else + name[i] = buff; + + if (!stropen(Stream + i, RtStream[i], mode, path)) { + ShowMsg(s.sprintf("connect error: %s", name)); + ShowLegend(NULL); + trace(1, "stream open error: ch=%d type=%d path=%s\n", i + 1, RtStream[i], path); + continue; } - strcpy(caption,U2A(Caption).c_str()); - - if (strstr(caption,"CONNECT")) { - Caption=s.sprintf("DISCONNECT%s",caption+7); + strsettimeout(Stream + i, RtTimeOutTime, RtReConnTime); + + if (StrCmdEna[i][0]) { + cmd = StrCmds[i][0].c_str(); + strwrite(Stream + i, (uint8_t *)cmd, strlen(cmd)); } - StrStatus->Visible=false; - BtnReload->Left=Panel11->Width-BtnOptions->Width; - BtnReload->Visible=true; - UpdateTime(); - UpdatePlot(); - UpdateEnable(); + ConnectState = 1; + } + if (!ConnectState) return; + + if (Title != "") + Caption = Title; + else + Caption = s.sprintf("CONNECT %s %s", name[0], name[1]); + + BtnConnect->Down = true; + BtnSol1->Down = *name[0]; + BtnSol2->Down = *name[1]; + BtnSol12->Down = false; + BtnShowTrack->Down = true; + BtnFixHoriz->Down = true; + BtnFixCent->Down = true; + BtnReload->Visible = false; + StrStatus->Left = Panel11->Width - BtnOptions->Width; + StrStatus->Visible = true; + UpdateTime(); + UpdatePlot(); + UpdateEnable(); +} +// disconnect from external sources ----------------------------------------- +void __fastcall TPlot::Disconnect(void) { + AnsiString s; + char *cmd, caption[1024]; + int i; + + trace(3, "Disconnect\n"); + + if (!ConnectState) return; + + ConnectState = 0; + + for (i = 0; i < 2; i++) { + if (StrCmdEna[i][1]) { + cmd = StrCmds[i][1].c_str(); + strwrite(Stream + i, (uint8_t *)cmd, strlen(cmd)); + } + strclose(Stream + i); + } + strcpy(caption, U2A(Caption).c_str()); + + if (strstr(caption, "CONNECT")) { + Caption = s.sprintf("DISCONNECT%s", caption + 7); + } + StrStatus->Visible = false; + BtnReload->Left = Panel11->Width - BtnOptions->Width; + BtnReload->Visible = true; + UpdateTime(); + UpdatePlot(); + UpdateEnable(); } // check observation data types --------------------------------------------- -int __fastcall TPlot::CheckObs(AnsiString file) -{ - char *p; - - trace(3,"CheckObs\n"); - - if (!(p=strrchr(file.c_str(),'.'))) return 0; - if (!strcmp(p,".z")||!strcmp(p,".gz")||!strcmp(p,".zip")|| - !strcmp(p,".Z")||!strcmp(p,".GZ")||!strcmp(p,".ZIP")) { - return *(p-1)=='o'||*(p-1)=='O'||*(p-1)=='d'||*(p-1)=='D'; - } - return !strcmp(p,".obs")||!strcmp(p,".OBS")|| - !strcmp(p,".rnx")||!strcmp(p,".RNX")|| - !strcmp(p+3,"o" )||!strcmp(p+3,"O" )|| - !strcmp(p+3,"d" )||!strcmp(p+3,"D" ); +int __fastcall TPlot::CheckObs(AnsiString file) { + char *p; + + trace(3, "CheckObs\n"); + + if (!(p = strrchr(file.c_str(), '.'))) return 0; + if (!strcmp(p, ".z") || !strcmp(p, ".gz") || !strcmp(p, ".zip") || !strcmp(p, ".Z") || + !strcmp(p, ".GZ") || !strcmp(p, ".ZIP")) { + return *(p - 1) == 'o' || *(p - 1) == 'O' || *(p - 1) == 'd' || *(p - 1) == 'D'; + } + return !strcmp(p, ".obs") || !strcmp(p, ".OBS") || !strcmp(p, ".rnx") || !strcmp(p, ".RNX") || + !strcmp(p + 3, "o") || !strcmp(p + 3, "O") || !strcmp(p + 3, "d") || !strcmp(p + 3, "D"); } // update observation data index, azimuth/elevation, satellite list --------- -void __fastcall TPlot::UpdateObs(int nobs) -{ - prcopt_t opt=prcopt_default; - double rr[3]={0}; - int per,per_=-1; - - trace(3,"UpdateObs\n"); - - delete [] IndexObs; IndexObs=NULL; - delete [] Az; Az=NULL; - delete [] El; El=NULL; - NObs=0; - if (nobs<=0) return; - - IndexObs=new int[nobs+1]; - Az=new double[Obs.n]; - El=new double[Obs.n]; - - ReadWaitStart(); - ShowLegend(NULL); - - for (int i=0,j=0;iTTOL) break; - } - IndexObs[NObs++]=i; - - if (RcvPos==0) { // single point position - sol_t sol={0}; - char msg[128]; - - opt.err[0]=900.0; - pntpos(Obs.data+i,j-i,&Nav,&opt,&sol,azel,NULL,msg); - matcpy(rr,sol.rr,3,1); - ecef2pos(rr,pos); - } - else if (RcvPos==1) { // lat/lon/height - matcpy(pos,OOPos,3,1); - pos2ecef(pos,rr); - } - else { // RINEX header position - matcpy(rr,Sta.pos,3,1); - ecef2pos(rr,pos); - } - for (int k=0;k0.0) { - satazel(pos,e,azel); - if (azel[0]<0.0) azel[0]+=2.0*PI; - } - else { - azel[0]=azel[1]=0.0; - } - Az[i+k]=azel[0]; - El[i+k]=azel[1]; - } - per=(i+1)*100/Obs.n; - if (per!=per_) { - AnsiString s; - ShowMsg(s.sprintf("updating azimuth/elevation... (%d%%)",(per_=per))); - Application->ProcessMessages(); - } +void __fastcall TPlot::UpdateObs(int nobs) { + prcopt_t opt = prcopt_default; + double rr[3] = {0}; + int per, per_ = -1; + + trace(3, "UpdateObs\n"); + + delete[] IndexObs; + IndexObs = NULL; + delete[] Az; + Az = NULL; + delete[] El; + El = NULL; + NObs = 0; + if (nobs <= 0) return; + + IndexObs = new int[nobs + 1]; + Az = new double[Obs.n]; + El = new double[Obs.n]; + + ReadWaitStart(); + ShowLegend(NULL); + + for (int i = 0, j = 0; i < Obs.n; i = j) { + gtime_t time = Obs.data[i].time; + double pos[3], azel[2 * MAXOBS]; + int svh; + + for (j = i; j < Obs.n; j++) { + if (timediff(Obs.data[j].time, time) > TTOL) break; } - IndexObs[NObs]=Obs.n; - - UpdateSatList(); - - ReadWaitEnd(); + IndexObs[NObs++] = i; + + if (RcvPos == 0) { // single point position + sol_t sol = {0}; + char msg[128]; + + opt.err[0] = 900.0; + pntpos(Obs.data + i, j - i, &Nav, &opt, &sol, azel, NULL, msg); + matcpy(rr, sol.rr, 3, 1); + ecef2pos(rr, pos); + } else if (RcvPos == 1) { // lat/lon/height + matcpy(pos, OOPos, 3, 1); + pos2ecef(pos, rr); + } else { // RINEX header position + matcpy(rr, Sta.pos, 3, 1); + ecef2pos(rr, pos); + } + for (int k = 0; k < j - i; k++) { + double e[3], rs[6], dts[2], var; + int sat = Obs.data[i + k].sat; + + if (SimObs) { + char name[8]; + satno2id(sat, name); + if (!tle_pos(time, name, "", "", &TLEData, NULL, rs)) continue; + } else { + if (!satpos(time, time, sat, EPHOPT_BRDC, &Nav, rs, dts, &var, &svh)) { + continue; + } + } + if (geodist(rs, rr, e) > 0.0) { + satazel(pos, e, azel); + if (azel[0] < 0.0) azel[0] += 2.0 * PI; + } else { + azel[0] = azel[1] = 0.0; + } + Az[i + k] = azel[0]; + El[i + k] = azel[1]; + } + per = (i + 1) * 100 / Obs.n; + if (per != per_) { + AnsiString s; + ShowMsg(s.sprintf("updating azimuth/elevation... (%d%%)", (per_ = per))); + Application->ProcessMessages(); + } + } + IndexObs[NObs] = Obs.n; + + UpdateSatList(); + + ReadWaitEnd(); } // update Multipath ------------------------------------------------------------ -void __fastcall TPlot::UpdateMp(void) -{ - trace(3,"UpdateMp\n"); - - for (int i=0;isat, data->code[j], &Nav); - if (data->L[j] == 0.0 || freq1 == 0.0 ) continue; - for (int k = j + 1; k < NFREQ + NEXOBS; k++) { - freq2 = sat2freq(data->sat, data->code[k], &Nav); - if (data->L[k] == 0.0 || freq2 == 0.0 || freq1 == freq2) continue; - I = -CLIGHT * (data->L[j] / freq1-data->L[k] / freq2) / (1.0 - SQR(freq1 / freq2)); - break; - } - break; - } - if (freq1 == 0.0 || freq2 == 0.0) continue; +void __fastcall TPlot::UpdateMp(void) { + trace(3, "UpdateMp\n"); - for (int j=0;jsat,data->code[j],&Nav); - if (data->P[j]==0.0||data->L[j]==0.0||freq==0.0) continue; - Mp[j][i]=data->P[j]-CLIGHT*data->L[j]/freq-2.0*SQR(freq1/freq)*I; - } - } - for (int sat=1;sat<=MAXSAT;sat++) { - for (int j=0;jsat!=sat) continue; - if ((data->LLI[j]&1)||(data->LLI[0]&1)||(data->LLI[1]&1)|| - fabs(Mp[j][i]-B)>5.0) { - for (int k=m;kProcessMessages(); + for (int i = 0; i < NFREQ + NEXOBS; i++) { + delete[] Mp[i]; + Mp[i] = NULL; + } + if (Obs.n <= 0) return; + + for (int i = 0; i < NFREQ + NEXOBS; i++) { + Mp[i] = new double[Obs.n]; + for (int j = 0; j < Obs.n; j++) Mp[i][j] = 0.0; + } + ReadWaitStart(); + ShowLegend(NULL); + + int per_ = -1; + for (int i = 0; i < Obs.n; i++) { + obsd_t *data = Obs.data + i; + // Choose two frequencies to calculate reference I. + double freq1 = 0.0, freq2 = 0.0, I = 0.0; + for (int j = 0; j < NFREQ + NEXOBS; j++) { + freq1 = sat2freq(data->sat, data->code[j], &Nav); + if (data->L[j] == 0.0 || freq1 == 0.0) continue; + for (int k = j + 1; k < NFREQ + NEXOBS; k++) { + freq2 = sat2freq(data->sat, data->code[k], &Nav); + if (data->L[k] == 0.0 || freq2 == 0.0 || freq1 == freq2) continue; + I = -CLIGHT * (data->L[j] / freq1 - data->L[k] / freq2) / (1.0 - SQR(freq1 / freq2)); + break; + } + break; + } + if (freq1 == 0.0 || freq2 == 0.0) continue; + + for (int j = 0; j < NFREQ + NEXOBS; j++) { + double freq = sat2freq(data->sat, data->code[j], &Nav); + if (data->P[j] == 0.0 || data->L[j] == 0.0 || freq == 0.0) continue; + Mp[j][i] = data->P[j] - CLIGHT * data->L[j] / freq - 2.0 * SQR(freq1 / freq) * I; + } + } + for (int sat = 1; sat <= MAXSAT; sat++) { + for (int j = 0; j < NFREQ + NEXOBS; j++) { + double B = 0.0; + int m = 0; + for (int i = 0, n = 0; i < Obs.n; i++) { + obsd_t *data = Obs.data + i; + if (data->sat != sat) continue; + if ((data->LLI[j] & 1) || (data->LLI[0] & 1) || (data->LLI[1] & 1) || + fabs(Mp[j][i] - B) > 5.0) { + for (int k = m; k < i; k++) { + if (Obs.data[k].sat == sat && Mp[j][k] != 0.0) Mp[j][k] -= B; + } + n = 0; + m = i; + B = 0.0; } - } - ReadWaitEnd(); + if (Mp[j][i] != 0.0) B += (Mp[j][i] - B) / ++n; + } + for (int k = m; k < Obs.n; k++) { + if (Obs.data[k].sat == sat && Mp[j][k] != 0.0) Mp[j][k] -= B; + } + } + int per = sat * 100 / MAXSAT; + if (per != per_) { + AnsiString s; + ShowMsg(s.sprintf("updating multipath... (%d%%)", (per_ = per))); + Application->ProcessMessages(); + } + } + ReadWaitEnd(); } // set connect path --------------------------------------------------------- -void __fastcall TPlot::ConnectPath(const char *path, int ch) -{ - const char *p; - - trace(3,"ConnectPath: path=%s ch=%d\n",path,ch); - - RtStream[ch]=STR_NONE; - - if (!(p=strstr(path,"://"))) return; - if (!strncmp(path,"serial",6)) RtStream[ch]=STR_SERIAL; - else if (!strncmp(path,"tcpsvr",6)) RtStream[ch]=STR_TCPSVR; - else if (!strncmp(path,"tcpcli",6)) RtStream[ch]=STR_TCPCLI; - else if (!strncmp(path,"ntrip", 5)) RtStream[ch]=STR_NTRIPCLI; - else if (!strncmp(path,"file", 4)) RtStream[ch]=STR_FILE; - else return; - - StrPaths[ch][1]=p+3; - RtFormat[ch]=SOLF_LLH; - RtTimeForm=0; - RtDegForm =0; - RtFieldSep=" "; - RtTimeOutTime=0; - RtReConnTime =10000; - - BtnShowTrack->Down=true; - BtnFixHoriz ->Down=true; - BtnFixVert ->Down=true; - BtnFixCent ->Down=true; +void __fastcall TPlot::ConnectPath(const char *path, int ch) { + const char *p; + + trace(3, "ConnectPath: path=%s ch=%d\n", path, ch); + + RtStream[ch] = STR_NONE; + + if (!(p = strstr(path, "://"))) return; + if (!strncmp(path, "serial", 6)) + RtStream[ch] = STR_SERIAL; + else if (!strncmp(path, "tcpsvr", 6)) + RtStream[ch] = STR_TCPSVR; + else if (!strncmp(path, "tcpcli", 6)) + RtStream[ch] = STR_TCPCLI; + else if (!strncmp(path, "ntrip", 5)) + RtStream[ch] = STR_NTRIPCLI; + else if (!strncmp(path, "file", 4)) + RtStream[ch] = STR_FILE; + else + return; + + StrPaths[ch][1] = p + 3; + RtFormat[ch] = SOLF_LLH; + RtTimeForm = 0; + RtDegForm = 0; + RtFieldSep = " "; + RtTimeOutTime = 0; + RtReConnTime = 10000; + + BtnShowTrack->Down = true; + BtnFixHoriz->Down = true; + BtnFixVert->Down = true; + BtnFixCent->Down = true; } // clear obs data -------------------------------------------------------------- -void __fastcall TPlot::ClearObs(void) -{ - sta_t sta0={0}; - int i; - - freeobs(&Obs); - freenav(&Nav,0xFF); - delete [] IndexObs; IndexObs=NULL; - delete [] Az; Az=NULL; - delete [] El; El=NULL; - for (i=0;iClear(); - NavFiles->Clear(); - NObs=0; - Sta=sta0; - ObsIndex=0; - SimObs=0; +void __fastcall TPlot::ClearObs(void) { + sta_t sta0 = {0}; + int i; + + freeobs(&Obs); + freenav(&Nav, 0xFF); + delete[] IndexObs; + IndexObs = NULL; + delete[] Az; + Az = NULL; + delete[] El; + El = NULL; + for (i = 0; i < NFREQ + NEXOBS; i++) { + delete[] Mp[i]; + Mp[i] = NULL; + } + ObsFiles->Clear(); + NavFiles->Clear(); + NObs = 0; + Sta = sta0; + ObsIndex = 0; + SimObs = 0; } // clear solution -------------------------------------------------------------- -void __fastcall TPlot::ClearSol(void) -{ - int i; - - for (i=0;i<2;i++) { - freesolbuf(SolData+i); - free(SolStat[i].data); - SolStat[i].n=0; - SolStat[i].data=NULL; - } - SolFiles[0]->Clear(); - SolFiles[1]->Clear(); - SolIndex[0]=SolIndex[1]=0; +void __fastcall TPlot::ClearSol(void) { + int i; + + for (i = 0; i < 2; i++) { + freesolbuf(SolData + i); + free(SolStat[i].data); + SolStat[i].n = 0; + SolStat[i].data = NULL; + } + SolFiles[0]->Clear(); + SolFiles[1]->Clear(); + SolIndex[0] = SolIndex[1] = 0; } // clear data ------------------------------------------------------------------ -void __fastcall TPlot::Clear(void) -{ - AnsiString s; - double ep[]={2010,1,1,0,0,0}; - int i; - - trace(3,"Clear\n"); - - Week=0; - - ClearObs(); - ClearSol(); - gis_free(&Gis); - - MapImage->Height=0; - MapImage->Width=0; - MapImageFile=""; - MapSize[0]=MapSize[1]=0; - - for (i=0;i<3;i++) { - TimeEna[i]=0; - } - TimeStart=TimeEnd=epoch2time(ep); - BtnAnimate->Down=false; - - if (PlotType>PLOT_NSAT) { - UpdateType(PLOT_TRK); - } - if (!ConnectState) { - initsolbuf(SolData ,0,0); - initsolbuf(SolData+1,0,0); - Caption=Title!=""?Title:s.sprintf("%s-%s %s",PRGNAME,VER_RTKLIB,PATCH_LEVEL); - } - else { - initsolbuf(SolData ,1,RtBuffSize+1); - initsolbuf(SolData+1,1,RtBuffSize+1); - } - for (i=0;i<=360;i++) ElMaskData[i]=0.0; - - NWayPnt=0; - SelWayPnt=-1; - - UpdateTime(); - UpdatePlot(); - UpdateEnable(); +void __fastcall TPlot::Clear(void) { + AnsiString s; + double ep[] = {2010, 1, 1, 0, 0, 0}; + int i; + + trace(3, "Clear\n"); + + Week = 0; + + ClearObs(); + ClearSol(); + gis_free(&Gis); + + MapImage->Height = 0; + MapImage->Width = 0; + MapImageFile = ""; + MapSize[0] = MapSize[1] = 0; + + for (i = 0; i < 3; i++) { + TimeEna[i] = 0; + } + TimeStart = TimeEnd = epoch2time(ep); + BtnAnimate->Down = false; + + if (PlotType > PLOT_NSAT) { + UpdateType(PLOT_TRK); + } + if (!ConnectState) { + initsolbuf(SolData, 0, 0); + initsolbuf(SolData + 1, 0, 0); + Caption = Title != "" ? Title : s.sprintf("%s-%s %s", PRGNAME, VER_RTKLIB, PATCH_LEVEL); + } else { + initsolbuf(SolData, 1, RtBuffSize + 1); + initsolbuf(SolData + 1, 1, RtBuffSize + 1); + } + for (i = 0; i <= 360; i++) ElMaskData[i] = 0.0; + + NWayPnt = 0; + SelWayPnt = -1; + + UpdateTime(); + UpdatePlot(); + UpdateEnable(); } // reload data -------------------------------------------------------------- -void __fastcall TPlot::Reload(void) -{ - TStrings *obsfiles,*navfiles; - - trace(3,"Reload\n"); - - if (SimObs) { - GenVisData(); - return; - } - obsfiles=new TStringList; - navfiles=new TStringList; - obsfiles->Assign(ObsFiles); - navfiles->Assign(NavFiles); - - ReadObs(obsfiles); - ReadNav(navfiles); - ReadSol(SolFiles[0],0); - ReadSol(SolFiles[1],1); - - delete obsfiles; - delete navfiles; +void __fastcall TPlot::Reload(void) { + TStrings *obsfiles, *navfiles; + + trace(3, "Reload\n"); + + if (SimObs) { + GenVisData(); + return; + } + obsfiles = new TStringList; + navfiles = new TStringList; + obsfiles->Assign(ObsFiles); + navfiles->Assign(NavFiles); + + ReadObs(obsfiles); + ReadNav(navfiles); + ReadSol(SolFiles[0], 0); + ReadSol(SolFiles[1], 1); + + delete obsfiles; + delete navfiles; } // read wait start ---------------------------------------------------------- -void __fastcall TPlot::ReadWaitStart(void) -{ - MenuFile->Enabled=false; - MenuEdit->Enabled=false; - MenuView->Enabled=false; - MenuHelp->Enabled=false; - Panel1->Enabled=false; - Disp->Enabled=false; - Screen->Cursor=crHourGlass; +void __fastcall TPlot::ReadWaitStart(void) { + MenuFile->Enabled = false; + MenuEdit->Enabled = false; + MenuView->Enabled = false; + MenuHelp->Enabled = false; + Panel1->Enabled = false; + Disp->Enabled = false; + Screen->Cursor = crHourGlass; } // read wait end ------------------------------------------------------------ -void __fastcall TPlot::ReadWaitEnd(void) -{ - MenuFile->Enabled=true; - MenuEdit->Enabled=true; - MenuView->Enabled=true; - MenuHelp->Enabled=true; - Panel1->Enabled=true; - Disp->Enabled=true; - Screen->Cursor=crDefault; +void __fastcall TPlot::ReadWaitEnd(void) { + MenuFile->Enabled = true; + MenuEdit->Enabled = true; + MenuView->Enabled = true; + MenuHelp->Enabled = true; + Panel1->Enabled = true; + Disp->Enabled = true; + Screen->Cursor = crDefault; } // -------------------------------------------------------------------------- diff --git a/app/winapp/rtkplot/plotdraw.cpp b/app/winapp/rtkplot/plotdraw.cpp index 30d393b96..6217c8327 100644 --- a/app/winapp/rtkplot/plotdraw.cpp +++ b/app/winapp/rtkplot/plotdraw.cpp @@ -2,1397 +2,1423 @@ // plotdraw.c: rtkplot draw functions //--------------------------------------------------------------------------- #include -#include "rtklib.h" -#include "plotmain.h" + #include "graph.h" -#include "refdlg.h" #include "mapview.h" +#include "plotmain.h" +#include "refdlg.h" +#include "rtklib.h" -#define MS_FONT "Consolas" // monospace font name -#define CHARGTE "\342\211\245" // grater equal charactor (UTF-8) -#define CHARMUL "\303\227" // multiply charactor (UTF-8) -#define COL_ELMASK clRed -#define ATAN2(x,y) ((x)*(x)+(y)*(y)>1E-12?atan2(x,y):0.0) +#define MS_FONT "Consolas" // monospace font name +#define CHARGTE "\342\211\245" // grater equal charactor (UTF-8) +#define CHARMUL "\303\227" // multiply charactor (UTF-8) +#define COL_ELMASK clRed +#define ATAN2(x, y) ((x) * (x) + (y) * (y) > 1E-12 ? atan2(x, y) : 0.0) // update plot -------------------------------------------------------------- -void __fastcall TPlot::UpdatePlot(void) -{ - trace(3,"UpdatePlot\n"); - - UpdateInfo(); - Refresh(); +void __fastcall TPlot::UpdatePlot(void) { + trace(3, "UpdatePlot\n"); + + UpdateInfo(); + Refresh(); } // refresh plot ------------------------------------------------------------- -void __fastcall TPlot::Refresh(void) -{ - trace(3,"Refresh\n"); - - Flush=1; - Disp->Invalidate(); +void __fastcall TPlot::Refresh(void) { + trace(3, "Refresh\n"); + + Flush = 1; + Disp->Invalidate(); } // draw plot ---------------------------------------------------------------- -void __fastcall TPlot::UpdateDisp(void) -{ - TCanvas *c=Disp->Canvas; - TRect r=Disp->ClientRect; - int level=Drag?0:1; - - trace(3,"UpdateDisp\n"); - - if (Flush) { - c->Pen ->Color=CColor[0]; - c->Brush->Color=CColor[0]; - c->Pen ->Style=psSolid; - c->Brush->Style=bsSolid; - c->FillRect(r); - - switch (PlotType) { - case PLOT_TRK : DrawTrk (level); break; - case PLOT_SOLP: DrawSol (level,0); break; - case PLOT_SOLV: DrawSol (level,1); break; - case PLOT_SOLA: DrawSol (level,2); break; - case PLOT_NSAT: DrawNsat(level); break; - case PLOT_OBS : DrawObs (level); break; - case PLOT_SKY : DrawSky (level); break; - case PLOT_SSKY : DrawSolSky (level); break; - case PLOT_DOP : DrawDop (level); break; - case PLOT_SDOP : DrawSolDop (level); break; - case PLOT_RES : DrawRes (level); break; - case PLOT_RESE: DrawResE(level); break; - case PLOT_SNR : DrawSnr (level); break; - case PLOT_SNRE: DrawSnrE(level); break; - case PLOT_MPS : DrawMpS (level); break; - } - Buff->SetSize(Disp->ClientWidth,Disp->ClientHeight); - Buff->Canvas->CopyRect(r,c,r); - } - else { - c->CopyRect(r,Buff->Canvas,r); - } - Flush=0; +void __fastcall TPlot::UpdateDisp(void) { + TCanvas *c = Disp->Canvas; + TRect r = Disp->ClientRect; + int level = Drag ? 0 : 1; + + trace(3, "UpdateDisp\n"); + + if (Flush) { + c->Pen->Color = CColor[0]; + c->Brush->Color = CColor[0]; + c->Pen->Style = psSolid; + c->Brush->Style = bsSolid; + c->FillRect(r); + + switch (PlotType) { + case PLOT_TRK: + DrawTrk(level); + break; + case PLOT_SOLP: + DrawSol(level, 0); + break; + case PLOT_SOLV: + DrawSol(level, 1); + break; + case PLOT_SOLA: + DrawSol(level, 2); + break; + case PLOT_NSAT: + DrawNsat(level); + break; + case PLOT_OBS: + DrawObs(level); + break; + case PLOT_SKY: + DrawSky(level); + break; + case PLOT_SSKY: + DrawSolSky(level); + break; + case PLOT_DOP: + DrawDop(level); + break; + case PLOT_SDOP: + DrawSolDop(level); + break; + case PLOT_RES: + DrawRes(level); + break; + case PLOT_RESE: + DrawResE(level); + break; + case PLOT_SNR: + DrawSnr(level); + break; + case PLOT_SNRE: + DrawSnrE(level); + break; + case PLOT_MPS: + DrawMpS(level); + break; + } + Buff->SetSize(Disp->ClientWidth, Disp->ClientHeight); + Buff->Canvas->CopyRect(r, c, r); + } else { + c->CopyRect(r, Buff->Canvas, r); + } + Flush = 0; } // draw track-plot ---------------------------------------------------------- -void __fastcall TPlot::DrawTrk(int level) -{ - UTF8String header,s; - TIMEPOS *pos,*pos1,*pos2,*vel; - gtime_t time1={0},time2={0}; - sol_t *sol; - TPoint p1,p2; - TColor color; - double xt,yt,sx,sy,opos[3],pnt[3],rr[3],enu[3]={0},cent[3]; - int i,j,index,sel=!BtnSol1->Down&&BtnSol2->Down?1:0,p=0; - - trace(3,"DrawTrk: level=%d\n",level); - - if (BtnShowTrack->Down&&BtnFixCent->Down) { - if (!BtnSol12->Down) { - pos=SolToPos(SolData+sel,SolIndex[sel],0,0); - if (pos->n>0) GraphT->SetCent(pos->x[0],pos->y[0]); - delete pos; - } - else { - pos1=SolToPos(SolData ,SolIndex[0],0,0); - pos2=SolToPos(SolData+1,SolIndex[1],0,0); - pos=pos1->diff(pos2,0); - if (pos->n>0) GraphT->SetCent(pos->x[0],pos->y[0]); - delete pos; - delete pos1; - delete pos2; - } - } - if (!BtnSol12->Down&&BtnShowImg->Down) { // image - DrawTrkImage(level); - } - if (BtnShowMap->Down) { // map - DrawTrkMap(level); +void __fastcall TPlot::DrawTrk(int level) { + UTF8String header, s; + TIMEPOS *pos, *pos1, *pos2, *vel; + gtime_t time1 = {0}, time2 = {0}; + sol_t *sol; + TPoint p1, p2; + TColor color; + double xt, yt, sx, sy, opos[3], pnt[3], rr[3], enu[3] = {0}, cent[3]; + int i, j, index, sel = !BtnSol1->Down && BtnSol2->Down ? 1 : 0, p = 0; + + trace(3, "DrawTrk: level=%d\n", level); + + if (BtnShowTrack->Down && BtnFixCent->Down) { + if (!BtnSol12->Down) { + pos = SolToPos(SolData + sel, SolIndex[sel], 0, 0); + if (pos->n > 0) GraphT->SetCent(pos->x[0], pos->y[0]); + delete pos; + } else { + pos1 = SolToPos(SolData, SolIndex[0], 0, 0); + pos2 = SolToPos(SolData + 1, SolIndex[1], 0, 0); + pos = pos1->diff(pos2, 0); + if (pos->n > 0) GraphT->SetCent(pos->x[0], pos->y[0]); + delete pos; + delete pos1; + delete pos2; } - if (BtnShowGrid->Down) { // grid - if (level) { // center + - GraphT->GetPos(p1,p2); - p1.x=(p1.x+p2.x)/2; - p1.y=(p1.y+p2.y)/2; - DrawMark(GraphT,p1,5,CColor[1],20,0); - } - if (ShowGLabel>=3) { // circles - GraphT->XLPos=7; GraphT->YLPos=7; - GraphT->DrawCircles(ShowGLabel==4); - } - else if (ShowGLabel>=1) { // grid - GraphT->XLPos=2; GraphT->YLPos=4; - GraphT->DrawAxis(ShowLabel,ShowGLabel==2); - } + } + if (!BtnSol12->Down && BtnShowImg->Down) { // image + DrawTrkImage(level); + } + if (BtnShowMap->Down) { // map + DrawTrkMap(level); + } + if (BtnShowGrid->Down) { // grid + if (level) { // center + + GraphT->GetPos(p1, p2); + p1.x = (p1.x + p2.x) / 2; + p1.y = (p1.y + p2.y) / 2; + DrawMark(GraphT, p1, 5, CColor[1], 20, 0); + } + if (ShowGLabel >= 3) { // circles + GraphT->XLPos = 7; + GraphT->YLPos = 7; + GraphT->DrawCircles(ShowGLabel == 4); + } else if (ShowGLabel >= 1) { // grid + GraphT->XLPos = 2; + GraphT->YLPos = 4; + GraphT->DrawAxis(ShowLabel, ShowGLabel == 2); } - if (norm(OPos,3)>0.0) { - ecef2pos(OPos,opos); - header="ORI="+LatLonStr(opos,9); - header+=s.sprintf(" %.4fm",opos[2]); + } + if (norm(OPos, 3) > 0.0) { + ecef2pos(OPos, opos); + header = "ORI=" + LatLonStr(opos, 9); + header += s.sprintf(" %.4fm", opos[2]); + } + if (BtnSol1->Down) { + pos = SolToPos(SolData, -1, QFlag->ItemIndex, 0); + DrawTrkPnt(pos, level, 0); + if (BtnShowMap->Down && norm(SolData[0].rb, 3) > 1E-3) { + DrawTrkPos(SolData[0].rb, 0, 8, CColor[2], "Base Station 1"); + } + DrawTrkStat(pos, header, p++); + header = ""; + delete pos; + } + if (BtnSol2->Down) { + pos = SolToPos(SolData + 1, -1, QFlag->ItemIndex, 0); + DrawTrkPnt(pos, level, 1); + if (BtnShowMap->Down && norm(SolData[1].rb, 3) > 1E-3) { + DrawTrkPos(SolData[1].rb, 0, 8, CColor[2], "Base Station 2"); + } + DrawTrkStat(pos, header, p++); + delete pos; + } + if (BtnSol12->Down) { + pos1 = SolToPos(SolData, -1, 0, 0); + pos2 = SolToPos(SolData + 1, -1, 0, 0); + pos = pos1->diff(pos2, QFlag->ItemIndex); + DrawTrkPnt(pos, level, 0); + DrawTrkStat(pos, "", p++); + delete pos; + delete pos1; + delete pos2; + } + if (BtnShowTrack->Down && BtnSol1->Down) { + pos = SolToPos(SolData, SolIndex[0], 0, 0); + + if ((sol = getsol(SolData, SolIndex[0]))) time1 = sol->time; + + if (pos->n) { + pos->n = 1; + DrawTrkError(pos, 0); + GraphT->ToPoint(pos->x[0], pos->y[0], p1); + GraphT->DrawMark(p1, 0, CColor[0], MarkSize * 2 + 12, 0); + GraphT->DrawMark(p1, 1, CColor[2], MarkSize * 2 + 10, 0); + GraphT->DrawMark(p1, 5, CColor[2], MarkSize * 2 + 14, 0); + GraphT->DrawMark(p1, 0, CColor[2], MarkSize * 2 + 6, 0); + GraphT->DrawMark(p1, 0, MColor[0][pos->q[0]], MarkSize * 2 + 4, 0); + if (BtnSol2->Down) { + p1.x += MarkSize + 8; + DrawLabel(GraphT, p1, "1", 1, 0); + } } - if (BtnSol1->Down) { - pos=SolToPos(SolData,-1,QFlag->ItemIndex,0); - DrawTrkPnt(pos,level,0); - if (BtnShowMap->Down&&norm(SolData[0].rb,3)>1E-3) { - DrawTrkPos(SolData[0].rb,0,8,CColor[2],"Base Station 1"); - } - DrawTrkStat(pos,header,p++); - header=""; - delete pos; - } - if (BtnSol2->Down) { - pos=SolToPos(SolData+1,-1,QFlag->ItemIndex,0); - DrawTrkPnt(pos,level,1); - if (BtnShowMap->Down&&norm(SolData[1].rb,3)>1E-3) { - DrawTrkPos(SolData[1].rb,0,8,CColor[2],"Base Station 2"); - } - DrawTrkStat(pos,header,p++); - delete pos; - } - if (BtnSol12->Down) { - pos1=SolToPos(SolData ,-1,0,0); - pos2=SolToPos(SolData+1,-1,0,0); - pos=pos1->diff(pos2,QFlag->ItemIndex); - DrawTrkPnt(pos,level,0); - DrawTrkStat(pos,"",p++); - delete pos; - delete pos1; - delete pos2; - } - if (BtnShowTrack->Down&&BtnSol1->Down) { - - pos=SolToPos(SolData,SolIndex[0],0,0); - - if ((sol=getsol(SolData,SolIndex[0]))) time1=sol->time; - - if (pos->n) { - pos->n=1; - DrawTrkError(pos,0); - GraphT->ToPoint(pos->x[0],pos->y[0],p1); - GraphT->DrawMark(p1,0,CColor[0],MarkSize*2+12,0); - GraphT->DrawMark(p1,1,CColor[2],MarkSize*2+10,0); - GraphT->DrawMark(p1,5,CColor[2],MarkSize*2+14,0); - GraphT->DrawMark(p1,0,CColor[2],MarkSize*2+6,0); - GraphT->DrawMark(p1,0,MColor[0][pos->q[0]],MarkSize*2+4,0); - if (BtnSol2->Down) { - p1.x+=MarkSize+8; - DrawLabel(GraphT,p1,"1",1,0); - } - } - delete pos; - } - if (BtnShowTrack->Down&&BtnSol2->Down) { - - pos=SolToPos(SolData+1,SolIndex[1],0,0); - - if ((sol=getsol(SolData+1,SolIndex[1]))) time2=sol->time; - - if (pos->n>0&&(time1.time==0||fabs(timediff(time1,time2))n=1; - DrawTrkError(pos,1); - GraphT->ToPoint(pos->x[0],pos->y[0],p1); - GraphT->DrawMark(p1,0,CColor[0],MarkSize*2+12,0); - GraphT->DrawMark(p1,1,CColor[1],MarkSize*2+10,0); - GraphT->DrawMark(p1,5,CColor[1],MarkSize*2+14,0); - GraphT->DrawMark(p1,0,CColor[2],MarkSize*2+6,0); - GraphT->DrawMark(p1,0,MColor[1][pos->q[0]],MarkSize*2+4,0); - if (BtnSol1->Down) { - p1.x+=MarkSize+8; - DrawLabel(GraphT,p1,"2",1,0); - } - } - delete pos; - } - if (BtnShowTrack->Down&&BtnSol12->Down) { - - pos1=SolToPos(SolData ,SolIndex[0],0,0); - pos2=SolToPos(SolData+1,SolIndex[1],0,0); - pos=pos1->diff(pos2,0); - - if (pos->n>0) { - pos->n=1; - DrawTrkError(pos,1); - GraphT->ToPoint(pos->x[0],pos->y[0],p1); - GraphT->DrawMark(p1,0,CColor[0],MarkSize*2+12,0); - GraphT->DrawMark(p1,1,CColor[2],MarkSize*2+10,0); - GraphT->DrawMark(p1,5,CColor[2],MarkSize*2+14,0); - GraphT->DrawMark(p1,0,CColor[2],MarkSize*2+6,0); - GraphT->DrawMark(p1,0,MColor[0][pos->q[0]],MarkSize*2+4,0); - } - delete pos; - delete pos1; - delete pos2; - } - if (level&&BtnShowMap->Down) { - for (i=0;i=0) { - pnt[0]=PntPos[SelWayPnt][0]*D2R; - pnt[1]=PntPos[SelWayPnt][1]*D2R; - pnt[2]=PntPos[SelWayPnt][2]; - pos2ecef(pnt,rr); - AnsiString str=PntName[SelWayPnt]; - DrawTrkPos(rr,0,16,clRed,str); - } + delete pos; + } + if (BtnShowTrack->Down && BtnSol2->Down) { + pos = SolToPos(SolData + 1, SolIndex[1], 0, 0); + + if ((sol = getsol(SolData + 1, SolIndex[1]))) time2 = sol->time; + + if (pos->n > 0 && (time1.time == 0 || fabs(timediff(time1, time2)) < DTTOL * 2.0)) { + pos->n = 1; + DrawTrkError(pos, 1); + GraphT->ToPoint(pos->x[0], pos->y[0], p1); + GraphT->DrawMark(p1, 0, CColor[0], MarkSize * 2 + 12, 0); + GraphT->DrawMark(p1, 1, CColor[1], MarkSize * 2 + 10, 0); + GraphT->DrawMark(p1, 5, CColor[1], MarkSize * 2 + 14, 0); + GraphT->DrawMark(p1, 0, CColor[2], MarkSize * 2 + 6, 0); + GraphT->DrawMark(p1, 0, MColor[1][pos->q[0]], MarkSize * 2 + 4, 0); + if (BtnSol1->Down) { + p1.x += MarkSize + 8; + DrawLabel(GraphT, p1, "2", 1, 0); + } } - if (ShowCompass) { - GraphT->GetPos(p1,p2); - p1.x+=SIZE_COMP/2+25; - p1.y+=SIZE_COMP/2+35; - DrawMark(GraphT,p1,13,CColor[2],SIZE_COMP,0); - } - if (ShowArrow&&BtnShowTrack->Down) { - vel=SolToPos(SolData+sel,SolIndex[sel],0,1); - DrawTrkVel(vel); - delete vel; - } - if (ShowScale) { - UTF8String label; - - GraphT->GetPos(p1,p2); - GraphT->GetTick(xt,yt); - GraphT->GetScale(sx,sy); - p2.x-=70; - p2.y-=25; - DrawMark(GraphT,p2,11,CColor[2],(int)(xt/sx+0.5),0); - p2.y-=3; - if (xt<0.0099) label.sprintf("%.0f mm",xt*1000.0); - else if (xt<0.999 ) label.sprintf("%.0f cm",xt*100.0); - else if (xt<999.0 ) label.sprintf("%.0f m" ,xt); - else label.sprintf("%.0f km",xt/1000.0); - DrawLabel(GraphT,p2,label,0,1); - } - if (!level) { // center + - GraphT->GetCent(xt,yt); - GraphT->ToPoint(xt,yt,p1); - DrawMark(GraphT,p1,5,CColor[2],20,0); - } - // update map view center - if (level) { - if (norm(OPos,3)>0.0) { - GraphT->GetCent(xt,yt); - GraphT->ToPoint(xt,yt,p1); - GraphT->ToPos(p1,enu[0],enu[1]); - ecef2pos(OPos,opos); - enu2ecef(opos,enu,rr); - for (i=0;i<3;i++) rr[i]+=OPos[i]; - ecef2pos(rr,cent); - MapView->SetCent(cent[0]*R2D,cent[1]*R2D); - } - Refresh_MapView(); + delete pos; + } + if (BtnShowTrack->Down && BtnSol12->Down) { + pos1 = SolToPos(SolData, SolIndex[0], 0, 0); + pos2 = SolToPos(SolData + 1, SolIndex[1], 0, 0); + pos = pos1->diff(pos2, 0); + + if (pos->n > 0) { + pos->n = 1; + DrawTrkError(pos, 1); + GraphT->ToPoint(pos->x[0], pos->y[0], p1); + GraphT->DrawMark(p1, 0, CColor[0], MarkSize * 2 + 12, 0); + GraphT->DrawMark(p1, 1, CColor[2], MarkSize * 2 + 10, 0); + GraphT->DrawMark(p1, 5, CColor[2], MarkSize * 2 + 14, 0); + GraphT->DrawMark(p1, 0, CColor[2], MarkSize * 2 + 6, 0); + GraphT->DrawMark(p1, 0, MColor[0][pos->q[0]], MarkSize * 2 + 4, 0); + } + delete pos; + delete pos1; + delete pos2; + } + if (level && BtnShowMap->Down) { + for (i = 0; i < NWayPnt; i++) { + if (i == SelWayPnt) continue; + pnt[0] = PntPos[i][0] * D2R; + pnt[1] = PntPos[i][1] * D2R; + pnt[2] = PntPos[i][2]; + pos2ecef(pnt, rr); + AnsiString str = PntName[i]; + DrawTrkPos(rr, 0, 8, CColor[2], str); + } + if (SelWayPnt >= 0) { + pnt[0] = PntPos[SelWayPnt][0] * D2R; + pnt[1] = PntPos[SelWayPnt][1] * D2R; + pnt[2] = PntPos[SelWayPnt][2]; + pos2ecef(pnt, rr); + AnsiString str = PntName[SelWayPnt]; + DrawTrkPos(rr, 0, 16, clRed, str); } + } + if (ShowCompass) { + GraphT->GetPos(p1, p2); + p1.x += SIZE_COMP / 2 + 25; + p1.y += SIZE_COMP / 2 + 35; + DrawMark(GraphT, p1, 13, CColor[2], SIZE_COMP, 0); + } + if (ShowArrow && BtnShowTrack->Down) { + vel = SolToPos(SolData + sel, SolIndex[sel], 0, 1); + DrawTrkVel(vel); + delete vel; + } + if (ShowScale) { + UTF8String label; + + GraphT->GetPos(p1, p2); + GraphT->GetTick(xt, yt); + GraphT->GetScale(sx, sy); + p2.x -= 70; + p2.y -= 25; + DrawMark(GraphT, p2, 11, CColor[2], (int)(xt / sx + 0.5), 0); + p2.y -= 3; + if (xt < 0.0099) + label.sprintf("%.0f mm", xt * 1000.0); + else if (xt < 0.999) + label.sprintf("%.0f cm", xt * 100.0); + else if (xt < 999.0) + label.sprintf("%.0f m", xt); + else + label.sprintf("%.0f km", xt / 1000.0); + DrawLabel(GraphT, p2, label, 0, 1); + } + if (!level) { // center + + GraphT->GetCent(xt, yt); + GraphT->ToPoint(xt, yt, p1); + DrawMark(GraphT, p1, 5, CColor[2], 20, 0); + } + // update map view center + if (level) { + if (norm(OPos, 3) > 0.0) { + GraphT->GetCent(xt, yt); + GraphT->ToPoint(xt, yt, p1); + GraphT->ToPos(p1, enu[0], enu[1]); + ecef2pos(OPos, opos); + enu2ecef(opos, enu, rr); + for (i = 0; i < 3; i++) rr[i] += OPos[i]; + ecef2pos(rr, cent); + MapView->SetCent(cent[0] * R2D, cent[1] * R2D); + } + Refresh_MapView(); + } } // draw map-image on track-plot --------------------------------------------- -void __fastcall TPlot::DrawTrkImage(int level) -{ - gtime_t time={0}; - TCanvas *c=Disp->Canvas; - TPoint p1,p2; - double pos[3]={0},rr[3],xyz[3]={0},x1,x2,y1,y2; - - trace(3,"DrawTrkImage: level=%d\n",level); - - pos[0]=MapLat*D2R; - pos[1]=MapLon*D2R; - pos2ecef(pos,rr); - if (norm(OPos,3)>0.0) { - PosToXyz(time,rr,0,xyz); - } - x1=xyz[0]-MapSize[0]*0.5*MapScaleX; - x2=xyz[0]+MapSize[0]*0.5*MapScaleX; - y1=xyz[1]-MapSize[1]*0.5*(MapScaleEq?MapScaleX:MapScaleY); - y2=xyz[1]+MapSize[1]*0.5*(MapScaleEq?MapScaleX:MapScaleY); - - GraphT->ToPoint(x1,y2,p1); - GraphT->ToPoint(x2,y1,p2); - TRect r(p1,p2); - c->StretchDraw(r,MapImage); +void __fastcall TPlot::DrawTrkImage(int level) { + gtime_t time = {0}; + TCanvas *c = Disp->Canvas; + TPoint p1, p2; + double pos[3] = {0}, rr[3], xyz[3] = {0}, x1, x2, y1, y2; + + trace(3, "DrawTrkImage: level=%d\n", level); + + pos[0] = MapLat * D2R; + pos[1] = MapLon * D2R; + pos2ecef(pos, rr); + if (norm(OPos, 3) > 0.0) { + PosToXyz(time, rr, 0, xyz); + } + x1 = xyz[0] - MapSize[0] * 0.5 * MapScaleX; + x2 = xyz[0] + MapSize[0] * 0.5 * MapScaleX; + y1 = xyz[1] - MapSize[1] * 0.5 * (MapScaleEq ? MapScaleX : MapScaleY); + y2 = xyz[1] + MapSize[1] * 0.5 * (MapScaleEq ? MapScaleX : MapScaleY); + + GraphT->ToPoint(x1, y2, p1); + GraphT->ToPoint(x2, y1, p2); + TRect r(p1, p2); + c->StretchDraw(r, MapImage); } // check in boundary -------------------------------------------------------- -#define P_IN_B(pos,bound) \ - (pos[0]>=bound[0]&&pos[0]<=bound[1]&&pos[1]>=bound[2]&&pos[1]<=bound[3]) +#define P_IN_B(pos, bound) \ + (pos[0] >= bound[0] && pos[0] <= bound[1] && pos[1] >= bound[2] && pos[1] <= bound[3]) -#define B_IN_B(bound1,bound2) \ - (bound1[0]<=bound2[1]&&bound1[1]>=bound2[0]&&bound1[2]<=bound2[3]&&bound1[3]>=bound2[2]) +#define B_IN_B(bound1, bound2) \ + (bound1[0] <= bound2[1] && bound1[1] >= bound2[0] && bound1[2] <= bound2[3] && \ + bound1[3] >= bound2[2]) // draw gis-map on track-plot ----------------------------------------------- -void __fastcall TPlot::DrawTrkMap(int level) -{ - gisd_t *data; - gis_pnt_t *pnt; - gis_poly_t *poly; - gis_polygon_t *polygon; - gtime_t time={0}; - TColor color; - TPoint *p,p1; - double xyz[3],S,xl[2],yl[2],enu[8][3]={{0}},opos[3],pos[3],rr[3]; - double bound[4]={PI/2.0,-PI/2.0,PI,-PI}; - int i,j,n,m; - - trace(3,"DrawTrkMap: level=%d\n",level); - - // get map boundary - GraphT->GetLim(xl,yl); - enu[0][0]=xl[0]; enu[0][1]=yl[0]; - enu[1][0]=xl[1]; enu[1][1]=yl[0]; - enu[2][0]=xl[0]; enu[2][1]=yl[1]; - enu[3][0]=xl[1]; enu[3][1]=yl[1]; - enu[4][0]=(xl[0]+xl[1])/2.0; enu[4][1]=yl[0]; - enu[5][0]=(xl[0]+xl[1])/2.0; enu[5][1]=yl[1]; - enu[6][0]=xl[0]; enu[6][1]=(yl[0]+yl[1])/2.0; - enu[7][0]=xl[1]; enu[7][1]=(yl[0]+yl[1])/2.0; - ecef2pos(OPos,opos); - for (i=0;i<8;i++) { - if (norm(enu[i],2)>=1000000.0) { - bound[0]=-PI/2.0; - bound[1]= PI/2.0; - bound[2]=-PI; - bound[3]= PI; - break; - } - enu2ecef(opos,enu[i],rr); - for (j=0;j<3;j++) rr[j]+=OPos[j]; - ecef2pos(rr,pos); - if (pos[0]bound[1]) bound[1]=pos[0]; // max lat - if (pos[1]bound[3]) bound[3]=pos[1]; // max lon - } - for (i=MAXMAPLAYER-1;i>=0;i--) { - if (!Gis.flag[i]) continue; - - for (data=Gis.data[i];data;data=data->next) { - if (data->type==1) { // point - pnt=(gis_pnt_t *)data->data; - if (!P_IN_B(pnt->pos,bound)) continue; - PosToXyz(time,pnt->pos,0,xyz); - if (xyz[2]<-RE_WGS84) continue; - GraphT->ToPoint(xyz[0],xyz[1],p1); - DrawMark(GraphT,p1,1,CColor[2],6,0); - DrawMark(GraphT,p1,0,CColor[2],2,0); - } - else if (level&&data->type==2) { // polyline - poly=(gis_poly_t *)data->data; - if ((n=poly->npnt)<=0||!B_IN_B(poly->bound,bound)) { - continue; - } - p=new TPoint [n]; - for (j=m=0;jpos+j*3,0,xyz); - if (xyz[2]<-RE_WGS84) { - if (m>1) { - GraphT->DrawPoly(p,m,MapColor[i],0); - m=0; - } - continue; - } - GraphT->ToPoint(xyz[0],xyz[1],p1); - if (m==0||p1.x!=p[m-1].x||p1.y!=p[m-1].y) { - p[m++]=p1; - } - } - GraphT->DrawPoly(p,m,MapColor[i],0); - delete [] p; - } - else if (level&&data->type==3) { // polygon - polygon=(gis_polygon_t *)data->data; - if ((n=polygon->npnt)<=0||!B_IN_B(polygon->bound,bound)) { - continue; - } - p=new TPoint [n]; - for (j=m=0;jpos+j*3,0,xyz); - if (xyz[2]<-RE_WGS84) { - continue; - } - GraphT->ToPoint(xyz[0],xyz[1],p1); - if (m==0||p1.x!=p[m-1].x||p1.y!=p[m-1].y) { - p[m++]=p1; - } - } - // judge hole - for (j=0,S=0.0;jDrawPatch(p,m,MapColor[i],color,0); - delete [] p; +void __fastcall TPlot::DrawTrkMap(int level) { + gisd_t *data; + gis_pnt_t *pnt; + gis_poly_t *poly; + gis_polygon_t *polygon; + gtime_t time = {0}; + TColor color; + TPoint *p, p1; + double xyz[3], S, xl[2], yl[2], enu[8][3] = {{0}}, opos[3], pos[3], rr[3]; + double bound[4] = {PI / 2.0, -PI / 2.0, PI, -PI}; + int i, j, n, m; + + trace(3, "DrawTrkMap: level=%d\n", level); + + // get map boundary + GraphT->GetLim(xl, yl); + enu[0][0] = xl[0]; + enu[0][1] = yl[0]; + enu[1][0] = xl[1]; + enu[1][1] = yl[0]; + enu[2][0] = xl[0]; + enu[2][1] = yl[1]; + enu[3][0] = xl[1]; + enu[3][1] = yl[1]; + enu[4][0] = (xl[0] + xl[1]) / 2.0; + enu[4][1] = yl[0]; + enu[5][0] = (xl[0] + xl[1]) / 2.0; + enu[5][1] = yl[1]; + enu[6][0] = xl[0]; + enu[6][1] = (yl[0] + yl[1]) / 2.0; + enu[7][0] = xl[1]; + enu[7][1] = (yl[0] + yl[1]) / 2.0; + ecef2pos(OPos, opos); + for (i = 0; i < 8; i++) { + if (norm(enu[i], 2) >= 1000000.0) { + bound[0] = -PI / 2.0; + bound[1] = PI / 2.0; + bound[2] = -PI; + bound[3] = PI; + break; + } + enu2ecef(opos, enu[i], rr); + for (j = 0; j < 3; j++) rr[j] += OPos[j]; + ecef2pos(rr, pos); + if (pos[0] < bound[0]) bound[0] = pos[0]; // min lat + if (pos[0] > bound[1]) bound[1] = pos[0]; // max lat + if (pos[1] < bound[2]) bound[2] = pos[1]; // min lon + if (pos[1] > bound[3]) bound[3] = pos[1]; // max lon + } + for (i = MAXMAPLAYER - 1; i >= 0; i--) { + if (!Gis.flag[i]) continue; + + for (data = Gis.data[i]; data; data = data->next) { + if (data->type == 1) { // point + pnt = (gis_pnt_t *)data->data; + if (!P_IN_B(pnt->pos, bound)) continue; + PosToXyz(time, pnt->pos, 0, xyz); + if (xyz[2] < -RE_WGS84) continue; + GraphT->ToPoint(xyz[0], xyz[1], p1); + DrawMark(GraphT, p1, 1, CColor[2], 6, 0); + DrawMark(GraphT, p1, 0, CColor[2], 2, 0); + } else if (level && data->type == 2) { // polyline + poly = (gis_poly_t *)data->data; + if ((n = poly->npnt) <= 0 || !B_IN_B(poly->bound, bound)) { + continue; + } + p = new TPoint[n]; + for (j = m = 0; j < n; j++) { + PosToXyz(time, poly->pos + j * 3, 0, xyz); + if (xyz[2] < -RE_WGS84) { + if (m > 1) { + GraphT->DrawPoly(p, m, MapColor[i], 0); + m = 0; } - } + continue; + } + GraphT->ToPoint(xyz[0], xyz[1], p1); + if (m == 0 || p1.x != p[m - 1].x || p1.y != p[m - 1].y) { + p[m++] = p1; + } + } + GraphT->DrawPoly(p, m, MapColor[i], 0); + delete[] p; + } else if (level && data->type == 3) { // polygon + polygon = (gis_polygon_t *)data->data; + if ((n = polygon->npnt) <= 0 || !B_IN_B(polygon->bound, bound)) { + continue; + } + p = new TPoint[n]; + for (j = m = 0; j < n; j++) { + PosToXyz(time, polygon->pos + j * 3, 0, xyz); + if (xyz[2] < -RE_WGS84) { + continue; + } + GraphT->ToPoint(xyz[0], xyz[1], p1); + if (m == 0 || p1.x != p[m - 1].x || p1.y != p[m - 1].y) { + p[m++] = p1; + } + } + // judge hole + for (j = 0, S = 0.0; j < m - 1; j++) { + S += (double)p[j].x * p[j + 1].y - (double)p[j + 1].x * p[j].y; + } + color = S < 0.0 ? CColor[0] : MapColorF[i]; + GraphT->DrawPatch(p, m, MapColor[i], color, 0); + delete[] p; + } } + } } // draw track-points on track-plot ------------------------------------------ -void __fastcall TPlot::DrawTrkPnt(const TIMEPOS *pos, int level, int style) -{ - TColor *color; - int i; - - trace(3,"DrawTrkPnt: level=%d style=%d\n",level,style); - - if (level) DrawTrkArrow(pos); - - if (level&&PlotStyle<=1&&!BtnShowTrack->Down) { // error circle - DrawTrkError(pos,style); - } - if (!(PlotStyle%2)) { - GraphT->DrawPoly(pos->x,pos->y,pos->n,CColor[3],style); - } - if (level&&PlotStyle<2) { - color=new TColor [pos->n]; - if (BtnShowImg->Down) { - for (i=0;in;i++) color[i]=CColor[0]; - GraphT->DrawMarks(pos->x,pos->y,color,pos->n,0,MarkSize+2,0); - } - for (i=0;in;i++) color[i]=MColor[style][pos->q[i]]; - GraphT->DrawMarks(pos->x,pos->y,color,pos->n,0,MarkSize,0); - delete [] color; +void __fastcall TPlot::DrawTrkPnt(const TIMEPOS *pos, int level, int style) { + TColor *color; + int i; + + trace(3, "DrawTrkPnt: level=%d style=%d\n", level, style); + + if (level) DrawTrkArrow(pos); + + if (level && PlotStyle <= 1 && !BtnShowTrack->Down) { // error circle + DrawTrkError(pos, style); + } + if (!(PlotStyle % 2)) { + GraphT->DrawPoly(pos->x, pos->y, pos->n, CColor[3], style); + } + if (level && PlotStyle < 2) { + color = new TColor[pos->n]; + if (BtnShowImg->Down) { + for (i = 0; i < pos->n; i++) color[i] = CColor[0]; + GraphT->DrawMarks(pos->x, pos->y, color, pos->n, 0, MarkSize + 2, 0); } + for (i = 0; i < pos->n; i++) color[i] = MColor[style][pos->q[i]]; + GraphT->DrawMarks(pos->x, pos->y, color, pos->n, 0, MarkSize, 0); + delete[] color; + } } // draw point with label on track-plot -------------------------------------- -void __fastcall TPlot::DrawTrkPos(const double *rr, int type, int siz, - TColor color, UTF8String label) -{ - gtime_t time={0}; - TPoint p1; - double xyz[3],xs,ys; - - trace(3,"DrawTrkPos: type=%d rr=%.3f %.3f %.3f\n",type,rr[0],rr[1],rr[2]); - - if (norm(rr,3)>0.0) { - GraphT->GetScale(xs,ys); - PosToXyz(time,rr,type,xyz); - GraphT->ToPoint(xyz[0],xyz[1],p1); - DrawMark(GraphT,p1,5,color,siz+6,0); - DrawMark(GraphT,p1,1,color,siz ,0); - DrawMark(GraphT,p1,1,color,siz-6,0); - p1.y+=10; - DrawLabel(GraphT,p1,label,0,2); - } +void __fastcall TPlot::DrawTrkPos(const double *rr, int type, int siz, TColor color, + UTF8String label) { + gtime_t time = {0}; + TPoint p1; + double xyz[3], xs, ys; + + trace(3, "DrawTrkPos: type=%d rr=%.3f %.3f %.3f\n", type, rr[0], rr[1], rr[2]); + + if (norm(rr, 3) > 0.0) { + GraphT->GetScale(xs, ys); + PosToXyz(time, rr, type, xyz); + GraphT->ToPoint(xyz[0], xyz[1], p1); + DrawMark(GraphT, p1, 5, color, siz + 6, 0); + DrawMark(GraphT, p1, 1, color, siz, 0); + DrawMark(GraphT, p1, 1, color, siz - 6, 0); + p1.y += 10; + DrawLabel(GraphT, p1, label, 0, 2); + } } // draw statistics on track-plot -------------------------------------------- -void __fastcall TPlot::DrawTrkStat(const TIMEPOS *pos, UTF8String header, int p) -{ - UTF8String s[6]; - TPoint p1,p2; - double *d,ave[4],std[4],rms[4],opos[3]; - int i,n=0,fonth=(int)(Disp->Font->Size*1.5); - - trace(3,"DrawTrkStat: p=%d\n",p); - - if (!ShowStats) return; - - if (p==0&&header!="") s[n++]=header; - - if (pos->n>0) { - d=new double[pos->n]; - for (i=0;in;i++) { - d[i]=SQRT(SQR(pos->x[i])+SQR(pos->y[i])); - } - CalcStats(pos->x,pos->n,0.0,ave[0],std[0],rms[0]); - CalcStats(pos->y,pos->n,0.0,ave[1],std[1],rms[1]); - CalcStats(pos->z,pos->n,0.0,ave[2],std[2],rms[2]); - CalcStats(d ,pos->n,0.0,ave[3],std[3],rms[3]); - s[n++].sprintf("AVE=E:%7.4fm N:%7.4fm U:%7.4fm",ave[0],ave[1],ave[2]); - s[n++].sprintf("STD=E:%7.4fm N:%7.4fm U:%7.4fm",std[0],std[1],std[2]); - s[n++].sprintf("RMS=E:%7.4fm N:%7.4fm U:%7.4fm 2D:%7.4fm", - rms[0],rms[1],rms[2],2.0*rms[3]); - delete [] d; - } - GraphT->GetPos(p1,p2); - p1.x=p2.x-10; - p1.y+=8+fonth*4*p; - for (i=0;iFont->Size * 1.5); + + trace(3, "DrawTrkStat: p=%d\n", p); + + if (!ShowStats) return; + + if (p == 0 && header != "") s[n++] = header; + + if (pos->n > 0) { + d = new double[pos->n]; + for (i = 0; i < pos->n; i++) { + d[i] = SQRT(SQR(pos->x[i]) + SQR(pos->y[i])); + } + CalcStats(pos->x, pos->n, 0.0, ave[0], std[0], rms[0]); + CalcStats(pos->y, pos->n, 0.0, ave[1], std[1], rms[1]); + CalcStats(pos->z, pos->n, 0.0, ave[2], std[2], rms[2]); + CalcStats(d, pos->n, 0.0, ave[3], std[3], rms[3]); + s[n++].sprintf("AVE=E:%7.4fm N:%7.4fm U:%7.4fm", ave[0], ave[1], ave[2]); + s[n++].sprintf("STD=E:%7.4fm N:%7.4fm U:%7.4fm", std[0], std[1], std[2]); + s[n++].sprintf("RMS=E:%7.4fm N:%7.4fm U:%7.4fm 2D:%7.4fm", rms[0], rms[1], rms[2], + 2.0 * rms[3]); + delete[] d; + } + GraphT->GetPos(p1, p2); + p1.x = p2.x - 10; + p1.y += 8 + fonth * 4 * p; + for (i = 0; i < n; i++, p1.y += fonth) { + DrawLabel(GraphT, p1, s[i], 2, 2); + } } // draw error-circle on track-plot ------------------------------------------ -void __fastcall TPlot::DrawTrkError(const TIMEPOS *pos, int style) -{ - const double sint[36]={ - 0.0000, 0.1736, 0.3420, 0.5000, 0.6428, 0.7660, 0.8660, 0.9397, 0.9848, - 1.0000, 0.9848, 0.9397, 0.8660, 0.7660, 0.6428, 0.5000, 0.3420, 0.1736, - 0.0000,-0.1736,-0.3420,-0.5000,-0.6428,-0.7660,-0.8660,-0.9397,-0.9848, - -1.0000,-0.9848,-0.9397,-0.8660,-0.7660,-0.6428,-0.5000,-0.3420,-0.1736 - }; - double xc[37],yc[37],a,b,s,c; - int i,j; - - trace(3,"DrawTrkError: style=%d\n",style); - - if (!ShowErr) return; - - for (i=0;in;i++) { - if (pos->xs[i]<=0.0||pos->ys[i]<=0.0) continue; - - a=pos->xys[i]/SQRT(pos->xs[i]); - - if ((b=pos->ys[i]-a*a)>=0.0) b=SQRT(b); else continue; - - for (j=0;j<37;j++) { - s=sint[j%36]; - c=sint[(45-j)%36]; - xc[j]=pos->x[i]+SQRT(pos->xs[i])*c; - yc[j]=pos->y[i]+a*c+b*s; - } - GraphT->DrawPoly(xc,yc,37,CColor[1],ShowErr==1?0:1); +void __fastcall TPlot::DrawTrkError(const TIMEPOS *pos, int style) { + const double sint[36] = {0.0000, 0.1736, 0.3420, 0.5000, 0.6428, 0.7660, 0.8660, 0.9397, + 0.9848, 1.0000, 0.9848, 0.9397, 0.8660, 0.7660, 0.6428, 0.5000, + 0.3420, 0.1736, 0.0000, -0.1736, -0.3420, -0.5000, -0.6428, -0.7660, + -0.8660, -0.9397, -0.9848, -1.0000, -0.9848, -0.9397, -0.8660, -0.7660, + -0.6428, -0.5000, -0.3420, -0.1736}; + double xc[37], yc[37], a, b, s, c; + int i, j; + + trace(3, "DrawTrkError: style=%d\n", style); + + if (!ShowErr) return; + + for (i = 0; i < pos->n; i++) { + if (pos->xs[i] <= 0.0 || pos->ys[i] <= 0.0) continue; + + a = pos->xys[i] / SQRT(pos->xs[i]); + + if ((b = pos->ys[i] - a * a) >= 0.0) + b = SQRT(b); + else + continue; + + for (j = 0; j < 37; j++) { + s = sint[j % 36]; + c = sint[(45 - j) % 36]; + xc[j] = pos->x[i] + SQRT(pos->xs[i]) * c; + yc[j] = pos->y[i] + a * c + b * s; } + GraphT->DrawPoly(xc, yc, 37, CColor[1], ShowErr == 1 ? 0 : 1); + } } // draw direction-arrow on track-plot --------------------------------------- -void __fastcall TPlot::DrawTrkArrow(const TIMEPOS *pos) -{ - TPoint p; - double tt,d[2],dist,dt,vel; - int i,off=8; - - trace(3,"DrawTrkArrow\n"); - - if (!ShowArrow) return; - - for (i=1;in-1;i++) { - tt=time2gpst(pos->t[i],NULL); - d[0]=pos->x[i+1]-pos->x[i-1]; - d[1]=pos->y[i+1]-pos->y[i-1]; - dist=norm(d,2); - dt=timediff(pos->t[i+1],pos->t[i-1]); - vel=dt==0.0?0.0:dist/dt; - - if (vel<0.5||fmod(tt+0.005,INTARROW)>=0.01) continue; - - GraphT->ToPoint(pos->x[i],pos->y[i],p); - p.x-=(int)(off*d[1]/dist); - p.y-=(int)(off*d[0]/dist); - DrawMark(GraphT,p,10,CColor[3],15,(int)(ATAN2(d[1],d[0])*R2D)); - } +void __fastcall TPlot::DrawTrkArrow(const TIMEPOS *pos) { + TPoint p; + double tt, d[2], dist, dt, vel; + int i, off = 8; + + trace(3, "DrawTrkArrow\n"); + + if (!ShowArrow) return; + + for (i = 1; i < pos->n - 1; i++) { + tt = time2gpst(pos->t[i], NULL); + d[0] = pos->x[i + 1] - pos->x[i - 1]; + d[1] = pos->y[i + 1] - pos->y[i - 1]; + dist = norm(d, 2); + dt = timediff(pos->t[i + 1], pos->t[i - 1]); + vel = dt == 0.0 ? 0.0 : dist / dt; + + if (vel < 0.5 || fmod(tt + 0.005, INTARROW) >= 0.01) continue; + + GraphT->ToPoint(pos->x[i], pos->y[i], p); + p.x -= (int)(off * d[1] / dist); + p.y -= (int)(off * d[0] / dist); + DrawMark(GraphT, p, 10, CColor[3], 15, (int)(ATAN2(d[1], d[0]) * R2D)); + } } // draw velocity-indicator on track-plot ------------------------------------ -void __fastcall TPlot::DrawTrkVel(const TIMEPOS *vel) -{ - UTF8String label; - TPoint p1,p2; - double v=0.0,dir=0.0; - - trace(3,"DrawTrkVel\n"); - - if (vel&&vel->n>0) { - if ((v=SQRT(SQR(vel->x[0])+SQR(vel->y[0])))>1.0) { - dir=ATAN2(vel->x[0],vel->y[0])*R2D; - } +void __fastcall TPlot::DrawTrkVel(const TIMEPOS *vel) { + UTF8String label; + TPoint p1, p2; + double v = 0.0, dir = 0.0; + + trace(3, "DrawTrkVel\n"); + + if (vel && vel->n > 0) { + if ((v = SQRT(SQR(vel->x[0]) + SQR(vel->y[0]))) > 1.0) { + dir = ATAN2(vel->x[0], vel->y[0]) * R2D; } - GraphT->GetPos(p1,p2); - p1.x+=SIZE_VELC/2+30; - p1.y=p2.y-SIZE_VELC/2-30; - DrawMark(GraphT,p1,1,CColor[2],SIZE_VELC,0); - p1.y+=SIZE_VELC/2; - label.sprintf("%.0f km/h",v*3600.0/1000.0); - DrawLabel(GraphT,p1,label,0,2); - p1.y-=SIZE_VELC/2; - if (v>=1.0) DrawMark(GraphT,p1,10,CColor[2],SIZE_VELC,90-(int)dir); - DrawMark(GraphT,p1,0,CColor[0],8,0); - DrawMark(GraphT,p1,1,CColor[2],8,0); + } + GraphT->GetPos(p1, p2); + p1.x += SIZE_VELC / 2 + 30; + p1.y = p2.y - SIZE_VELC / 2 - 30; + DrawMark(GraphT, p1, 1, CColor[2], SIZE_VELC, 0); + p1.y += SIZE_VELC / 2; + label.sprintf("%.0f km/h", v * 3600.0 / 1000.0); + DrawLabel(GraphT, p1, label, 0, 2); + p1.y -= SIZE_VELC / 2; + if (v >= 1.0) DrawMark(GraphT, p1, 10, CColor[2], SIZE_VELC, 90 - (int)dir); + DrawMark(GraphT, p1, 0, CColor[0], 8, 0); + DrawMark(GraphT, p1, 1, CColor[2], 8, 0); } // draw solution-plot ------------------------------------------------------- -void __fastcall TPlot::DrawSol(int level, int type) -{ - UTF8String label[]={"E-W","N-S","U-D"},unit[]={"m","m/s","m/s" CHARUP2}; - TSpeedButton *btn[]={BtnOn1,BtnOn2,BtnOn3}; - TIMEPOS *pos,*pos1,*pos2; - gtime_t time1={0},time2={0}; - TPoint p1,p2; - double xc,yc,xl[2],yl[2],off,y; - int i,j,k,sel=!BtnSol1->Down&&BtnSol2->Down?1:0,p=0; - - trace(3,"DrawSol: level=%d\n",level); - - if (BtnShowTrack->Down&&(BtnFixHoriz->Down||BtnFixVert->Down)) { - - pos=SolToPos(SolData+sel,SolIndex[sel],0,type); - - for (i=0;i<3&&pos->n>0;i++) { - GraphG[i]->GetCent(xc,yc); - if (BtnFixVert->Down) { - yc=i==0?pos->x[0]:(i==1?pos->y[0]:pos->z[0]); - } - if (BtnFixHoriz->Down) { - GraphG[i]->GetLim(xl,yl); - off=Xcent*(xl[1]-xl[0])/2.0; - GraphG[i]->SetCent(TimePos(pos->t[0])-off,yc); - } - else { - GraphG[i]->SetCent(xc,yc); - } - } - delete pos; +void __fastcall TPlot::DrawSol(int level, int type) { + UTF8String label[] = {"E-W", "N-S", "U-D"}, unit[] = {"m", "m/s", "m/s" CHARUP2}; + TSpeedButton *btn[] = {BtnOn1, BtnOn2, BtnOn3}; + TIMEPOS *pos, *pos1, *pos2; + gtime_t time1 = {0}, time2 = {0}; + TPoint p1, p2; + double xc, yc, xl[2], yl[2], off, y; + int i, j, k, sel = !BtnSol1->Down && BtnSol2->Down ? 1 : 0, p = 0; + + trace(3, "DrawSol: level=%d\n", level); + + if (BtnShowTrack->Down && (BtnFixHoriz->Down || BtnFixVert->Down)) { + pos = SolToPos(SolData + sel, SolIndex[sel], 0, type); + + for (i = 0; i < 3 && pos->n > 0; i++) { + GraphG[i]->GetCent(xc, yc); + if (BtnFixVert->Down) { + yc = i == 0 ? pos->x[0] : (i == 1 ? pos->y[0] : pos->z[0]); + } + if (BtnFixHoriz->Down) { + GraphG[i]->GetLim(xl, yl); + off = Xcent * (xl[1] - xl[0]) / 2.0; + GraphG[i]->SetCent(TimePos(pos->t[0]) - off, yc); + } else { + GraphG[i]->SetCent(xc, yc); + } } - j=-1; - for (i=0;i<3;i++) if (btn[i]->Down) j=i; - for (i=0;i<3;i++) { - if (!btn[i]->Down) continue; - GraphG[i]->XLPos=TimeLabel?(i==j?6:5):(i==j?1:0); - GraphG[i]->Week=Week; - GraphG[i]->DrawAxis(ShowLabel,ShowLabel); - } - if (BtnSol1->Down) { - pos=SolToPos(SolData,-1,QFlag->ItemIndex,type); - DrawSolPnt(pos,level,0); - DrawSolStat(pos,unit[type],p++); - delete pos; - } - if (BtnSol2->Down) { - pos=SolToPos(SolData+1,-1,QFlag->ItemIndex,type); - DrawSolPnt(pos,level,1); - DrawSolStat(pos,unit[type],p++); - delete pos; - } - if (BtnSol12->Down) { - pos1=SolToPos(SolData ,-1,0,type); - pos2=SolToPos(SolData+1,-1,0,type); - pos=pos1->diff(pos2,QFlag->ItemIndex); - DrawSolPnt(pos,level,0); - DrawSolStat(pos,unit[type],p++); - delete pos; - delete pos1; - delete pos2; - } - if (BtnShowTrack->Down&&(BtnSol1->Down||BtnSol2->Down||BtnSol12->Down)) { - - pos =SolToPos(SolData+sel,SolIndex[sel],0,type); - pos1=SolToPos(SolData ,SolIndex[0] ,0,type); - pos2=SolToPos(SolData+1 ,SolIndex[1] ,0,type); - if (pos1->n>0) time1=pos1->t[0]; - if (pos2->n>0) time2=pos2->t[0]; - - for (j=k=0;j<3&&pos->n>0;j++) { - - if (!btn[j]->Down) continue; - - GraphG[j]->GetLim(xl,yl); - xl[0]=xl[1]=TimePos(pos->t[0]); - GraphG[j]->DrawPoly(xl,yl,2,CColor[2],0); - - if (BtnSol2->Down&&pos2->n>0&&(time1.time==0||fabs(timediff(time1,time2))x[0]:(j==1?pos2->y[0]:pos2->z[0]); - GraphG[j]->DrawMark(xl[0],y,0,CColor[0],MarkSize*2+6,0); - GraphG[j]->DrawMark(xl[0],y,1,CColor[1],MarkSize*2+6,0); - GraphG[j]->DrawMark(xl[0],y,1,CColor[2],MarkSize*2+2,0); - GraphG[j]->DrawMark(xl[0],y,0,MColor[1][pos->q[0]],MarkSize*2,0); - if (BtnSol1->Down&&pos1->n>0&&GraphG[j]->ToPoint(xl[0],y,p1)) { - p1.x+=MarkSize+4; - DrawLabel(GraphG[j],p1,"2",1,0); - } - } - if (BtnSol1->Down&&pos1->n>0) { - xl[0]=xl[1]=TimePos(time1); - y=j==0?pos1->x[0]:(j==1?pos1->y[0]:pos1->z[0]); - GraphG[j]->DrawMark(xl[0],y,0,CColor[0],MarkSize*2+6,0); - GraphG[j]->DrawMark(xl[0],y,1,CColor[2],MarkSize*2+6,0); - GraphG[j]->DrawMark(xl[0],y,1,CColor[2],MarkSize*2+2,0); - GraphG[j]->DrawMark(xl[0],y,0,MColor[0][pos->q[0]],MarkSize*2,0); - if (BtnSol2->Down&&pos2->n>0&&GraphG[j]->ToPoint(xl[0],y,p1)) { - p1.x+=MarkSize+4; - DrawLabel(GraphG[j],p1,"1",1,0); - } - } - xl[0]=xl[1]=TimePos(pos->t[0]); - if (k++==0) { - GraphG[j]->DrawMark(xl[0],yl[1]-1E-6,0,CColor[2],5,0); - - if (!BtnFixHoriz->Down) { - GraphG[j]->DrawMark(xl[0],yl[1]-1E-6,1,CColor[2],9,0); - } - } + delete pos; + } + j = -1; + for (i = 0; i < 3; i++) + if (btn[i]->Down) j = i; + for (i = 0; i < 3; i++) { + if (!btn[i]->Down) continue; + GraphG[i]->XLPos = TimeLabel ? (i == j ? 6 : 5) : (i == j ? 1 : 0); + GraphG[i]->Week = Week; + GraphG[i]->DrawAxis(ShowLabel, ShowLabel); + } + if (BtnSol1->Down) { + pos = SolToPos(SolData, -1, QFlag->ItemIndex, type); + DrawSolPnt(pos, level, 0); + DrawSolStat(pos, unit[type], p++); + delete pos; + } + if (BtnSol2->Down) { + pos = SolToPos(SolData + 1, -1, QFlag->ItemIndex, type); + DrawSolPnt(pos, level, 1); + DrawSolStat(pos, unit[type], p++); + delete pos; + } + if (BtnSol12->Down) { + pos1 = SolToPos(SolData, -1, 0, type); + pos2 = SolToPos(SolData + 1, -1, 0, type); + pos = pos1->diff(pos2, QFlag->ItemIndex); + DrawSolPnt(pos, level, 0); + DrawSolStat(pos, unit[type], p++); + delete pos; + delete pos1; + delete pos2; + } + if (BtnShowTrack->Down && (BtnSol1->Down || BtnSol2->Down || BtnSol12->Down)) { + pos = SolToPos(SolData + sel, SolIndex[sel], 0, type); + pos1 = SolToPos(SolData, SolIndex[0], 0, type); + pos2 = SolToPos(SolData + 1, SolIndex[1], 0, type); + if (pos1->n > 0) time1 = pos1->t[0]; + if (pos2->n > 0) time2 = pos2->t[0]; + + for (j = k = 0; j < 3 && pos->n > 0; j++) { + if (!btn[j]->Down) continue; + + GraphG[j]->GetLim(xl, yl); + xl[0] = xl[1] = TimePos(pos->t[0]); + GraphG[j]->DrawPoly(xl, yl, 2, CColor[2], 0); + + if (BtnSol2->Down && pos2->n > 0 && + (time1.time == 0 || fabs(timediff(time1, time2)) < DTTOL * 2.0)) { + xl[0] = xl[1] = TimePos(time2); + y = j == 0 ? pos2->x[0] : (j == 1 ? pos2->y[0] : pos2->z[0]); + GraphG[j]->DrawMark(xl[0], y, 0, CColor[0], MarkSize * 2 + 6, 0); + GraphG[j]->DrawMark(xl[0], y, 1, CColor[1], MarkSize * 2 + 6, 0); + GraphG[j]->DrawMark(xl[0], y, 1, CColor[2], MarkSize * 2 + 2, 0); + GraphG[j]->DrawMark(xl[0], y, 0, MColor[1][pos->q[0]], MarkSize * 2, 0); + if (BtnSol1->Down && pos1->n > 0 && GraphG[j]->ToPoint(xl[0], y, p1)) { + p1.x += MarkSize + 4; + DrawLabel(GraphG[j], p1, "2", 1, 0); } - delete pos; - delete pos1; - delete pos2; - } - for (i=0;i<3;i++) { - if (!btn[i]->Down) continue; - GraphG[i]->GetPos(p1,p2); - p1.x+=5; p1.y+=3; - DrawLabel(GraphG[i],p1,label[i]+" ("+unit[type]+")",1,2); + } + if (BtnSol1->Down && pos1->n > 0) { + xl[0] = xl[1] = TimePos(time1); + y = j == 0 ? pos1->x[0] : (j == 1 ? pos1->y[0] : pos1->z[0]); + GraphG[j]->DrawMark(xl[0], y, 0, CColor[0], MarkSize * 2 + 6, 0); + GraphG[j]->DrawMark(xl[0], y, 1, CColor[2], MarkSize * 2 + 6, 0); + GraphG[j]->DrawMark(xl[0], y, 1, CColor[2], MarkSize * 2 + 2, 0); + GraphG[j]->DrawMark(xl[0], y, 0, MColor[0][pos->q[0]], MarkSize * 2, 0); + if (BtnSol2->Down && pos2->n > 0 && GraphG[j]->ToPoint(xl[0], y, p1)) { + p1.x += MarkSize + 4; + DrawLabel(GraphG[j], p1, "1", 1, 0); + } + } + xl[0] = xl[1] = TimePos(pos->t[0]); + if (k++ == 0) { + GraphG[j]->DrawMark(xl[0], yl[1] - 1E-6, 0, CColor[2], 5, 0); + + if (!BtnFixHoriz->Down) { + GraphG[j]->DrawMark(xl[0], yl[1] - 1E-6, 1, CColor[2], 9, 0); + } + } } + delete pos; + delete pos1; + delete pos2; + } + for (i = 0; i < 3; i++) { + if (!btn[i]->Down) continue; + GraphG[i]->GetPos(p1, p2); + p1.x += 5; + p1.y += 3; + DrawLabel(GraphG[i], p1, label[i] + " (" + unit[type] + ")", 1, 2); + } } // draw points and line on solution-plot ------------------------------------ -void __fastcall TPlot::DrawSolPnt(const TIMEPOS *pos, int level, int style) -{ - TSpeedButton *btn[]={BtnOn1,BtnOn2,BtnOn3}; - double *x,*y,*s,xs,ys,*yy; - int i,j; - - trace(3,"DrawSolPnt: level=%d style=%d\n",level,style); - - x=new double [pos->n]; - - for (i=0;in;i++) { - x[i]=TimePos(pos->t[i]); - } - for (i=0;i<3;i++) { - if (!btn[i]->Down) continue; - - y=i==0?pos->x :(i==1?pos->y :pos->z ); - s=i==0?pos->xs:(i==1?pos->ys:pos->zs); - - if (!level||!(PlotStyle%2)) { - DrawPolyS(GraphG[i],x,y,pos->n,CColor[3],style); - } - if (level&&ShowErr&&PlotType<=PLOT_SOLA&&PlotStyle<2) { - - GraphG[i]->GetScale(xs,ys); - - if (ShowErr==1) { - for (j=0;jn;j++) { - GraphG[i]->DrawMark(x[j],y[j],12,CColor[1],(int)(SQRT(s[j])*2.0/ys),0); - } - } - else { - yy=new double [pos->n]; - - for (j=0;jn;j++) yy[j]=y[j]-SQRT(s[j]); - DrawPolyS(GraphG[i],x,yy,pos->n,CColor[1],1); - - for (j=0;jn;j++) yy[j]=y[j]+SQRT(s[j]); - DrawPolyS(GraphG[i],x,yy,pos->n,CColor[1],1); - - delete [] yy; - } - } - if (level&&PlotStyle<2) { - TColor *color=new TColor[pos->n]; - for (j=0;jn;j++) color[j]=MColor[style][pos->q[j]]; - GraphG[i]->DrawMarks(x,y,color,pos->n,0,MarkSize,0); - delete [] color; +void __fastcall TPlot::DrawSolPnt(const TIMEPOS *pos, int level, int style) { + TSpeedButton *btn[] = {BtnOn1, BtnOn2, BtnOn3}; + double *x, *y, *s, xs, ys, *yy; + int i, j; + + trace(3, "DrawSolPnt: level=%d style=%d\n", level, style); + + x = new double[pos->n]; + + for (i = 0; i < pos->n; i++) { + x[i] = TimePos(pos->t[i]); + } + for (i = 0; i < 3; i++) { + if (!btn[i]->Down) continue; + + y = i == 0 ? pos->x : (i == 1 ? pos->y : pos->z); + s = i == 0 ? pos->xs : (i == 1 ? pos->ys : pos->zs); + + if (!level || !(PlotStyle % 2)) { + DrawPolyS(GraphG[i], x, y, pos->n, CColor[3], style); + } + if (level && ShowErr && PlotType <= PLOT_SOLA && PlotStyle < 2) { + GraphG[i]->GetScale(xs, ys); + + if (ShowErr == 1) { + for (j = 0; j < pos->n; j++) { + GraphG[i]->DrawMark(x[j], y[j], 12, CColor[1], (int)(SQRT(s[j]) * 2.0 / ys), 0); } + } else { + yy = new double[pos->n]; + + for (j = 0; j < pos->n; j++) yy[j] = y[j] - SQRT(s[j]); + DrawPolyS(GraphG[i], x, yy, pos->n, CColor[1], 1); + + for (j = 0; j < pos->n; j++) yy[j] = y[j] + SQRT(s[j]); + DrawPolyS(GraphG[i], x, yy, pos->n, CColor[1], 1); + + delete[] yy; + } } - delete [] x; + if (level && PlotStyle < 2) { + TColor *color = new TColor[pos->n]; + for (j = 0; j < pos->n; j++) color[j] = MColor[style][pos->q[j]]; + GraphG[i]->DrawMarks(x, y, color, pos->n, 0, MarkSize, 0); + delete[] color; + } + } + delete[] x; } // draw statistics on solution-plot ----------------------------------------- -void __fastcall TPlot::DrawSolStat(const TIMEPOS *pos, UTF8String unit, int p) -{ - TSpeedButton *btn[]={BtnOn1,BtnOn2,BtnOn3}; - TPoint p1,p2; - double ave,std,rms,*y,opos[3]; - int i,j=0,k=0,fonth=(int)(Disp->Font->Size*1.5); - char *u; - UTF8String label,s; - - trace(3,"DrawSolStat: p=%d\n",p); - - if (!ShowStats||pos->n<=0) return; - - for (i=0;i<3;i++) { - if (!btn[i]->Down) continue; - - y=i==0?pos->x:(i==1?pos->y:pos->z); - CalcStats(y,pos->n,0.0,ave,std,rms); - GraphG[i]->GetPos(p1,p2); - p1.x=p2.x-5; - p1.y+=3+fonth*(p+(!k++&&p>0?1:0)); - - if (j==0&&p==0) { - - if (norm(OPos,3)>0.0) { - ecef2pos(OPos,opos); - label="ORI="+LatLonStr(opos,9)+s.sprintf(" %.4fm",opos[2]); - DrawLabel(GraphG[j],p1,label,2,2); - j++; p1.y+=fonth; - } - } - u=unit.c_str(); - s.sprintf("AVE=%.4f%s STD=%.4f%s RMS=%.4f%s",ave,u,std,u,rms,u); - DrawLabel(GraphG[i],p1,s,2,2); +void __fastcall TPlot::DrawSolStat(const TIMEPOS *pos, UTF8String unit, int p) { + TSpeedButton *btn[] = {BtnOn1, BtnOn2, BtnOn3}; + TPoint p1, p2; + double ave, std, rms, *y, opos[3]; + int i, j = 0, k = 0, fonth = (int)(Disp->Font->Size * 1.5); + char *u; + UTF8String label, s; + + trace(3, "DrawSolStat: p=%d\n", p); + + if (!ShowStats || pos->n <= 0) return; + + for (i = 0; i < 3; i++) { + if (!btn[i]->Down) continue; + + y = i == 0 ? pos->x : (i == 1 ? pos->y : pos->z); + CalcStats(y, pos->n, 0.0, ave, std, rms); + GraphG[i]->GetPos(p1, p2); + p1.x = p2.x - 5; + p1.y += 3 + fonth * (p + (!k++ && p > 0 ? 1 : 0)); + + if (j == 0 && p == 0) { + if (norm(OPos, 3) > 0.0) { + ecef2pos(OPos, opos); + label = "ORI=" + LatLonStr(opos, 9) + s.sprintf(" %.4fm", opos[2]); + DrawLabel(GraphG[j], p1, label, 2, 2); + j++; + p1.y += fonth; + } } + u = unit.c_str(); + s.sprintf("AVE=%.4f%s STD=%.4f%s RMS=%.4f%s", ave, u, std, u, rms, u); + DrawLabel(GraphG[i], p1, s, 2, 2); + } } // draw number-of-satellite plot -------------------------------------------- -void __fastcall TPlot::DrawNsat(int level) -{ - UTF8String label[]={ - "# of Valid Satellites", - "Age of Differential (s)", - "Ratio Factor for AR Validation" - }; - TSpeedButton *btn[]={BtnOn1,BtnOn2,BtnOn3}; - TIMEPOS *ns; - TPoint p1,p2; - double xc,yc,y,xl[2],yl[2],off; - int i,j,k,sel=!BtnSol1->Down&&BtnSol2->Down?1:0; - - trace(3,"DrawNsat: level=%d\n",level); - - if (BtnShowTrack->Down&&BtnFixHoriz->Down) { - - ns=SolToNsat(SolData+sel,SolIndex[sel],0); - - for (i=0;i<3;i++) { - if (BtnFixHoriz->Down) { - GraphG[i]->GetLim(xl,yl); - off=Xcent*(xl[1]-xl[0])/2.0; - GraphG[i]->GetCent(xc,yc); - GraphG[i]->SetCent(TimePos(ns->t[0])-off,yc); - } - else { - GraphG[i]->GetRight(xc,yc); - GraphG[i]->SetRight(TimePos(ns->t[0]),yc); - } - } - delete ns; +void __fastcall TPlot::DrawNsat(int level) { + UTF8String label[] = {"# of Valid Satellites", "Age of Differential (s)", + "Ratio Factor for AR Validation"}; + TSpeedButton *btn[] = {BtnOn1, BtnOn2, BtnOn3}; + TIMEPOS *ns; + TPoint p1, p2; + double xc, yc, y, xl[2], yl[2], off; + int i, j, k, sel = !BtnSol1->Down && BtnSol2->Down ? 1 : 0; + + trace(3, "DrawNsat: level=%d\n", level); + + if (BtnShowTrack->Down && BtnFixHoriz->Down) { + ns = SolToNsat(SolData + sel, SolIndex[sel], 0); + + for (i = 0; i < 3; i++) { + if (BtnFixHoriz->Down) { + GraphG[i]->GetLim(xl, yl); + off = Xcent * (xl[1] - xl[0]) / 2.0; + GraphG[i]->GetCent(xc, yc); + GraphG[i]->SetCent(TimePos(ns->t[0]) - off, yc); + } else { + GraphG[i]->GetRight(xc, yc); + GraphG[i]->SetRight(TimePos(ns->t[0]), yc); + } } - j=-1; - for (i=0;i<3;i++) if (btn[i]->Down) j=i; - for (i=0;i<3;i++) { - if (!btn[i]->Down) continue; - GraphG[i]->XLPos=TimeLabel?(i==j?6:5):(i==j?1:0); - GraphG[i]->Week=Week; - GraphG[i]->DrawAxis(ShowLabel,ShowLabel); - } - if (BtnSol1->Down) { - ns=SolToNsat(SolData,-1,QFlag->ItemIndex); - DrawSolPnt(ns,level,0); - delete ns; - } - if (BtnSol2->Down) { - ns=SolToNsat(SolData+1,-1,QFlag->ItemIndex); - DrawSolPnt(ns,level,1); - delete ns; - } - if (BtnShowTrack->Down&&(BtnSol1->Down||BtnSol2->Down)) { - - ns=SolToNsat(SolData+sel,SolIndex[sel],0); - - for (j=k=0;j<3&&ns->n>0;j++) { - - if (!btn[j]->Down) continue; - - y=j==0?ns->x[0]:(j==1?ns->y[0]:ns->z[0]); - GraphG[j]->GetLim(xl,yl); - xl[0]=xl[1]=TimePos(ns->t[0]); - - GraphG[j]->DrawPoly(xl,yl,2,CColor[2],0); - GraphG[j]->DrawMark(xl[0],y,0,CColor[0],MarkSize*2+6,0); - GraphG[j]->DrawMark(xl[0],y,1,CColor[2],MarkSize*2+6,0); - GraphG[j]->DrawMark(xl[0],y,1,CColor[2],MarkSize*2+2,0); - GraphG[j]->DrawMark(xl[0],y,0,MColor[sel][ns->q[0]],MarkSize*2,0); - - if (k++==0) { - GraphG[j]->DrawMark(xl[0],yl[1]-1E-6,0,CColor[2],5,0); - - if (!BtnFixHoriz->Down) { - GraphG[j]->DrawMark(xl[0],yl[1]-1E-6,1,CColor[2],9,0); - } - } + delete ns; + } + j = -1; + for (i = 0; i < 3; i++) + if (btn[i]->Down) j = i; + for (i = 0; i < 3; i++) { + if (!btn[i]->Down) continue; + GraphG[i]->XLPos = TimeLabel ? (i == j ? 6 : 5) : (i == j ? 1 : 0); + GraphG[i]->Week = Week; + GraphG[i]->DrawAxis(ShowLabel, ShowLabel); + } + if (BtnSol1->Down) { + ns = SolToNsat(SolData, -1, QFlag->ItemIndex); + DrawSolPnt(ns, level, 0); + delete ns; + } + if (BtnSol2->Down) { + ns = SolToNsat(SolData + 1, -1, QFlag->ItemIndex); + DrawSolPnt(ns, level, 1); + delete ns; + } + if (BtnShowTrack->Down && (BtnSol1->Down || BtnSol2->Down)) { + ns = SolToNsat(SolData + sel, SolIndex[sel], 0); + + for (j = k = 0; j < 3 && ns->n > 0; j++) { + if (!btn[j]->Down) continue; + + y = j == 0 ? ns->x[0] : (j == 1 ? ns->y[0] : ns->z[0]); + GraphG[j]->GetLim(xl, yl); + xl[0] = xl[1] = TimePos(ns->t[0]); + + GraphG[j]->DrawPoly(xl, yl, 2, CColor[2], 0); + GraphG[j]->DrawMark(xl[0], y, 0, CColor[0], MarkSize * 2 + 6, 0); + GraphG[j]->DrawMark(xl[0], y, 1, CColor[2], MarkSize * 2 + 6, 0); + GraphG[j]->DrawMark(xl[0], y, 1, CColor[2], MarkSize * 2 + 2, 0); + GraphG[j]->DrawMark(xl[0], y, 0, MColor[sel][ns->q[0]], MarkSize * 2, 0); + + if (k++ == 0) { + GraphG[j]->DrawMark(xl[0], yl[1] - 1E-6, 0, CColor[2], 5, 0); + + if (!BtnFixHoriz->Down) { + GraphG[j]->DrawMark(xl[0], yl[1] - 1E-6, 1, CColor[2], 9, 0); } - delete ns; - } - for (i=0;i<3;i++) { - if (!btn[i]->Down) continue; - GraphG[i]->GetPos(p1,p2); - p1.x+=5; p1.y+=3; - DrawLabel(GraphG[i],p1,label[i],1,2); + } } + delete ns; + } + for (i = 0; i < 3; i++) { + if (!btn[i]->Down) continue; + GraphG[i]->GetPos(p1, p2); + p1.x += 5; + p1.y += 3; + DrawLabel(GraphG[i], p1, label[i], 1, 2); + } } // draw observation-data-plot ----------------------------------------------- -void __fastcall TPlot::DrawObs(int level) -{ - TPoint p1,p2,p; - gtime_t time; - obsd_t *obs; - double xs,ys,xt,xl[2],yl[2],tt[MAXSAT]={0},xp,xc,yc,yp[MAXSAT]={0}; - int i,j,m=0,sats[MAXSAT]={0},ind=ObsIndex,prn; - char id[8]; - - trace(3,"DrawObs: level=%d\n",level); - - for (i=0;iXLPos=TimeLabel?6:1; - GraphR->YLPos=0; - GraphR->Week=Week; - GraphR->GetLim(xl,yl); - yl[0]=0.5; - yl[1]=m>0?m+0.5:m+10.5; - GraphR->SetLim(xl,yl); - GraphR->SetTick(0.0,1.0); - - if (0<=ind&&indDown&&BtnFixHoriz->Down) { - xp=TimePos(Obs.data[IndexObs[ind]].time); - if (BtnFixHoriz->Down) { - double xl[2],yl[2],off; - GraphR->GetLim(xl,yl); - off=Xcent*(xl[1]-xl[0])/2.0; - GraphR->GetCent(xc,yc); - GraphR->SetCent(xp-off,yc); - } - else { - GraphR->GetRight(xc,yc); - GraphR->SetRight(xp,yc); - } +void __fastcall TPlot::DrawObs(int level) { + TPoint p1, p2, p; + gtime_t time; + obsd_t *obs; + double xs, ys, xt, xl[2], yl[2], tt[MAXSAT] = {0}, xp, xc, yc, yp[MAXSAT] = {0}; + int i, j, m = 0, sats[MAXSAT] = {0}, ind = ObsIndex, prn; + char id[8]; + + trace(3, "DrawObs: level=%d\n", level); + + for (i = 0; i < Obs.n; i++) { + if (SatMask[Obs.data[i].sat - 1]) continue; + sats[Obs.data[i].sat - 1] = 1; + } + for (i = 0; i < MAXSAT; i++) + if (sats[i]) m++; + + GraphR->XLPos = TimeLabel ? 6 : 1; + GraphR->YLPos = 0; + GraphR->Week = Week; + GraphR->GetLim(xl, yl); + yl[0] = 0.5; + yl[1] = m > 0 ? m + 0.5 : m + 10.5; + GraphR->SetLim(xl, yl); + GraphR->SetTick(0.0, 1.0); + + if (0 <= ind && ind < NObs && BtnShowTrack->Down && BtnFixHoriz->Down) { + xp = TimePos(Obs.data[IndexObs[ind]].time); + if (BtnFixHoriz->Down) { + double xl[2], yl[2], off; + GraphR->GetLim(xl, yl); + off = Xcent * (xl[1] - xl[0]) / 2.0; + GraphR->GetCent(xc, yc); + GraphR->SetCent(xp - off, yc); + } else { + GraphR->GetRight(xc, yc); + GraphR->SetRight(xp, yc); } - GraphR->DrawAxis(1,1); - GraphR->GetPos(p1,p2); - - for (i=0,j=0;iDrawText(p,label,CColor[2],2,0,0); - } - p1.x=Disp->Font->Size; - p1.y=(p1.y+p2.y)/2; - GraphR->DrawText(p1,"SATELLITE NO",CColor[2],0,0,90); - - if (!BtnSol1->Down) return; - - if (level&&PlotStyle<=2) { - DrawObsEphem(yp); - } - if (level&&PlotStyle<=2) { - GraphR->GetScale(xs,ys); - for (i=0;itime); - if (fabs(xt-tt[obs->sat-1])/xs>0.9) { - GraphR->DrawMark(xt,yp[obs->sat-1],0,PlotStyle<2?col:CColor[3], - PlotStyle<2?MarkSize:0,0); - tt[obs->sat-1]=xt; - } - } + } + GraphR->DrawAxis(1, 1); + GraphR->GetPos(p1, p2); + + for (i = 0, j = 0; i < MAXSAT; i++) { + if (!sats[i]) continue; + UTF8String label; + p.x = p1.x; + p.y = p1.y + (int)((p2.y - p1.y) * (j + 0.5) / m); + yp[i] = m - (j++); + satno2id(i + 1, id); + label = id; + GraphR->DrawText(p, label, CColor[2], 2, 0, 0); + } + p1.x = Disp->Font->Size; + p1.y = (p1.y + p2.y) / 2; + GraphR->DrawText(p1, "SATELLITE NO", CColor[2], 0, 0, 90); + + if (!BtnSol1->Down) return; + + if (level && PlotStyle <= 2) { + DrawObsEphem(yp); + } + if (level && PlotStyle <= 2) { + GraphR->GetScale(xs, ys); + for (i = 0; i < Obs.n; i++) { + obs = &Obs.data[i]; + TColor col = ObsColor(obs, Az[i], El[i]); + if (col == clBlack) continue; + + xt = TimePos(obs->time); + if (fabs(xt - tt[obs->sat - 1]) / xs > 0.9) { + GraphR->DrawMark(xt, yp[obs->sat - 1], 0, PlotStyle < 2 ? col : CColor[3], + PlotStyle < 2 ? MarkSize : 0, 0); + tt[obs->sat - 1] = xt; + } } - if (level&&PlotStyle<=2) { - DrawObsSlip(yp); - } - if (BtnShowTrack->Down&&0<=ind&&indGetLim(xl,yl); - xl[0]=xl[1]=TimePos(Obs.data[i].time); - GraphR->DrawPoly(xl,yl,2,CColor[2],0); - - for (;iDrawMark(xl[0],yp[obs->sat-1],0,col,MarkSize*2+2,0); - } - GraphR->DrawMark(xl[0],yl[1]-1E-6,0,CColor[2],5,0); - if (!BtnFixHoriz->Down) { - GraphR->DrawMark(xl[0],yl[1]-1E-6,1,CColor[2],9,0); - } + } + if (level && PlotStyle <= 2) { + DrawObsSlip(yp); + } + if (BtnShowTrack->Down && 0 <= ind && ind < NObs) { + i = IndexObs[ind]; + time = Obs.data[i].time; + + GraphR->GetLim(xl, yl); + xl[0] = xl[1] = TimePos(Obs.data[i].time); + GraphR->DrawPoly(xl, yl, 2, CColor[2], 0); + + for (; i < Obs.n && timediff(Obs.data[i].time, time) == 0.0; i++) { + obs = &Obs.data[i]; + TColor col = ObsColor(obs, Az[i], El[i]); + if (col == clBlack) continue; + GraphR->DrawMark(xl[0], yp[obs->sat - 1], 0, col, MarkSize * 2 + 2, 0); } + GraphR->DrawMark(xl[0], yl[1] - 1E-6, 0, CColor[2], 5, 0); + if (!BtnFixHoriz->Down) { + GraphR->DrawMark(xl[0], yl[1] - 1E-6, 1, CColor[2], 9, 0); + } + } } // generate observation-data-slips ------------------------------------------ -void __fastcall TPlot::GenObsSlip(int *LLI) -{ - AnsiString text=ObsType->Text; - const char *obstype=text.c_str(); - double gfp[MAXSAT][NFREQ+NEXOBS]={{0}}; - - for (int i=0;isat-1]) continue; - if (ElMaskP&&El[i]sat,obs->code[0],&Nav))==0.0) continue; - LLI[i]=obs->LLI[0]&2; - for (j=1;jLLI[j]&2; - if ((freq2=sat2freq(obs->sat,obs->code[j],&Nav))==0.0) continue; - gf=CLIGHT*(obs->L[0]/freq1-obs->L[j]/freq2); - if (fabs(gfp[obs->sat-1][j]-gf)>THRESLIP) LLI[i]|=1; - gfp[obs->sat-1][j]=gf; - } - } - else { - if (sscanf(obstype,"L%1d",&k)==1) { - j=k>2?k-3:k-1; /* L1,L2,L5,L6 ... */ - } - else { - for (j=0;jcode[j]),obstype)) break; - } - if (j>=NFREQ+NEXOBS) continue; - } - LLI[i]=obs->LLI[j]&2; - k=(j==0)?1:0; - if ((freq1=sat2freq(obs->sat,obs->code[k],&Nav))==0.0) continue; - if ((freq2=sat2freq(obs->sat,obs->code[j],&Nav))==0.0) continue; - gf=CLIGHT*(obs->L[k]/freq1-obs->L[j]/freq2); - if (fabs(gfp[obs->sat-1][j]-gf)>THRESLIP) LLI[i]|=1; - gfp[obs->sat-1][j]=gf; - } - } - else { - if (!strcmp(obstype,"ALL")) { - for (j=0;jLLI[j]; - } - } - else { - if (sscanf(obstype,"L%1d",&k)==1) { - j=k>2?k-3:k-1; /* L1,L2,L5,L6 ... */ - } - else { - for (j=0;jcode[j]),obstype)) break; - } - if (j>=NFREQ+NEXOBS) continue; - } - LLI[i]=obs->LLI[j]; - } - } +void __fastcall TPlot::GenObsSlip(int *LLI) { + AnsiString text = ObsType->Text; + const char *obstype = text.c_str(); + double gfp[MAXSAT][NFREQ + NEXOBS] = {{0}}; + + for (int i = 0; i < Obs.n; i++) { + obsd_t *obs = Obs.data + i; + int j, k; + + LLI[i] = 0; + if (El[i] < ElMask * D2R || !SatSel[obs->sat - 1]) continue; + if (ElMaskP && El[i] < ElMaskData[(int)(Az[i] * R2D + 0.5)]) continue; + + if (ShowSlip == 1) { // LG jump + double freq1, freq2, gf; + + if (!strcmp(obstype, "ALL")) { + if ((freq1 = sat2freq(obs->sat, obs->code[0], &Nav)) == 0.0) continue; + LLI[i] = obs->LLI[0] & 2; + for (j = 1; j < NFREQ + NEXOBS; j++) { + LLI[i] |= obs->LLI[j] & 2; + if ((freq2 = sat2freq(obs->sat, obs->code[j], &Nav)) == 0.0) continue; + gf = CLIGHT * (obs->L[0] / freq1 - obs->L[j] / freq2); + if (fabs(gfp[obs->sat - 1][j] - gf) > THRESLIP) LLI[i] |= 1; + gfp[obs->sat - 1][j] = gf; + } + } else { + if (sscanf(obstype, "L%1d", &k) == 1) { + j = k > 2 ? k - 3 : k - 1; /* L1,L2,L5,L6 ... */ + } else { + for (j = 0; j < NFREQ + NEXOBS; j++) { + if (!strcmp(code2obs(obs->code[j]), obstype)) break; + } + if (j >= NFREQ + NEXOBS) continue; + } + LLI[i] = obs->LLI[j] & 2; + k = (j == 0) ? 1 : 0; + if ((freq1 = sat2freq(obs->sat, obs->code[k], &Nav)) == 0.0) continue; + if ((freq2 = sat2freq(obs->sat, obs->code[j], &Nav)) == 0.0) continue; + gf = CLIGHT * (obs->L[k] / freq1 - obs->L[j] / freq2); + if (fabs(gfp[obs->sat - 1][j] - gf) > THRESLIP) LLI[i] |= 1; + gfp[obs->sat - 1][j] = gf; + } + } else { + if (!strcmp(obstype, "ALL")) { + for (j = 0; j < NFREQ + NEXOBS; j++) { + LLI[i] |= obs->LLI[j]; + } + } else { + if (sscanf(obstype, "L%1d", &k) == 1) { + j = k > 2 ? k - 3 : k - 1; /* L1,L2,L5,L6 ... */ + } else { + for (j = 0; j < NFREQ + NEXOBS; j++) { + if (!strcmp(code2obs(obs->code[j]), obstype)) break; + } + if (j >= NFREQ + NEXOBS) continue; + } + LLI[i] = obs->LLI[j]; + } } + } } // draw slip on observation-data-plot --------------------------------------- -void __fastcall TPlot::DrawObsSlip(double *yp) -{ - trace(3,"DrawObsSlip\n"); +void __fastcall TPlot::DrawObsSlip(double *yp) { + trace(3, "DrawObsSlip\n"); - if (Obs.n<=0||(!ShowSlip&&!ShowHalfC)) return; + if (Obs.n <= 0 || (!ShowSlip && !ShowHalfC)) return; - int *LLI=new int [Obs.n]; - - GenObsSlip(LLI); + int *LLI = new int[Obs.n]; - for (int i=0;iToPoint(TimePos(obs->time),yp[obs->sat-1],ps[0])) { - ps[1].x=ps[0].x; - ps[1].y=ps[0].y+MarkSize*3/2+1; - ps[0].y=ps[0].y-MarkSize*3/2; - if (ShowHalfC&&(LLI[i]&2)) GraphR->DrawPoly(ps,2,MColor[0][0],0); - if (ShowSlip &&(LLI[i]&1)) GraphR->DrawPoly(ps,2,MColor[0][5],0); - } + GenObsSlip(LLI); + + for (int i = 0; i < Obs.n; i++) { + if (!LLI[i]) continue; + TPoint ps[2]; + obsd_t *obs = Obs.data + i; + if (GraphR->ToPoint(TimePos(obs->time), yp[obs->sat - 1], ps[0])) { + ps[1].x = ps[0].x; + ps[1].y = ps[0].y + MarkSize * 3 / 2 + 1; + ps[0].y = ps[0].y - MarkSize * 3 / 2; + if (ShowHalfC && (LLI[i] & 2)) GraphR->DrawPoly(ps, 2, MColor[0][0], 0); + if (ShowSlip && (LLI[i] & 1)) GraphR->DrawPoly(ps, 2, MColor[0][5], 0); } - delete [] LLI; + } + delete[] LLI; } // draw ephemeris on observation-data-plot ---------------------------------- -void __fastcall TPlot::DrawObsEphem(double *yp) -{ - TPoint ps[3]; - int i,j,k,in,svh,off[MAXSAT]={0}; - - trace(3,"DrawObsEphem\n"); - - if (!ShowEph) return; - - for (i=0;iToPoint(TimePos(Nav.eph[j].ttr),yp[i],ps[0]); - in=GraphR->ToPoint(TimePos(Nav.eph[j].toe),yp[i],ps[2]); - ps[1]=ps[0]; - off[Nav.eph[j].sat-1]=off[Nav.eph[j].sat-1]?0:3; - - for (k=0;k<3;k++) ps[k].y+=MarkSize+2+off[Nav.eph[j].sat-1]; - ps[0].y-=2; - - svh=Nav.eph[j].svh; - // Mask QZS LEX health. - int health = satsys(i + 1, NULL) == SYS_QZS ? (svh & 0xfe) != 0 : svh != 0; - GraphR->DrawPoly(ps,3,health?MColor[0][5]:CColor[1],0); - - if (in) GraphR->DrawMark(ps[2],0,health?MColor[0][5]:CColor[1],health?4:3,0); - } - for (j=0;jToPoint(TimePos(Nav.geph[j].tof),yp[i],ps[0]); - in=GraphR->ToPoint(TimePos(Nav.geph[j].toe),yp[i],ps[2]); - ps[1]=ps[0]; - off[Nav.geph[j].sat-1]=off[Nav.geph[j].sat-1]?0:3; - for (k=0;k<3;k++) ps[k].y+=MarkSize+2+off[Nav.geph[j].sat-1]; - ps[0].y-=2; - - svh=Nav.geph[j].svh; - int health = (svh & 9) != 0 || (svh & 6) == 4; - GraphR->DrawPoly(ps,3,health?MColor[0][5]:CColor[1],0); - - if (in) GraphR->DrawMark(ps[2],0,Nav.geph[j].svh?MColor[0][5]:CColor[1], - Nav.geph[j].svh?4:3,0); - } - for (j=0;jToPoint(TimePos(Nav.seph[j].tof),yp[i],ps[0]); - in=GraphR->ToPoint(TimePos(Nav.seph[j].t0),yp[i],ps[2]); - ps[1]=ps[0]; - off[Nav.seph[j].sat-1]=off[Nav.seph[j].sat-1]?0:3; - for (k=0;k<3;k++) ps[k].y+=MarkSize+2+off[Nav.seph[j].sat-1]; - ps[0].y-=2; - - svh=Nav.seph[j].svh; - GraphR->DrawPoly(ps,3,svh?MColor[0][5]:CColor[1],0); - - if (in) GraphR->DrawMark(ps[2],0,Nav.seph[j].svh?MColor[0][5]:CColor[1], - Nav.seph[j].svh?4:3,0); - } +void __fastcall TPlot::DrawObsEphem(double *yp) { + TPoint ps[3]; + int i, j, k, in, svh, off[MAXSAT] = {0}; + + trace(3, "DrawObsEphem\n"); + + if (!ShowEph) return; + + for (i = 0; i < MAXSAT; i++) { + if (!SatSel[i]) continue; + for (j = 0; j < Nav.n; j++) { + if (Nav.eph[j].sat != i + 1) continue; + GraphR->ToPoint(TimePos(Nav.eph[j].ttr), yp[i], ps[0]); + in = GraphR->ToPoint(TimePos(Nav.eph[j].toe), yp[i], ps[2]); + ps[1] = ps[0]; + off[Nav.eph[j].sat - 1] = off[Nav.eph[j].sat - 1] ? 0 : 3; + + for (k = 0; k < 3; k++) ps[k].y += MarkSize + 2 + off[Nav.eph[j].sat - 1]; + ps[0].y -= 2; + + svh = Nav.eph[j].svh; + // Mask QZS LEX health. + int health = satsys(i + 1, NULL) == SYS_QZS ? (svh & 0xfe) != 0 : svh != 0; + GraphR->DrawPoly(ps, 3, health ? MColor[0][5] : CColor[1], 0); + + if (in) GraphR->DrawMark(ps[2], 0, health ? MColor[0][5] : CColor[1], health ? 4 : 3, 0); + } + for (j = 0; j < Nav.ng; j++) { + if (Nav.geph[j].sat != i + 1) continue; + GraphR->ToPoint(TimePos(Nav.geph[j].tof), yp[i], ps[0]); + in = GraphR->ToPoint(TimePos(Nav.geph[j].toe), yp[i], ps[2]); + ps[1] = ps[0]; + off[Nav.geph[j].sat - 1] = off[Nav.geph[j].sat - 1] ? 0 : 3; + for (k = 0; k < 3; k++) ps[k].y += MarkSize + 2 + off[Nav.geph[j].sat - 1]; + ps[0].y -= 2; + + svh = Nav.geph[j].svh; + int health = (svh & 9) != 0 || (svh & 6) == 4; + GraphR->DrawPoly(ps, 3, health ? MColor[0][5] : CColor[1], 0); + + if (in) + GraphR->DrawMark(ps[2], 0, Nav.geph[j].svh ? MColor[0][5] : CColor[1], + Nav.geph[j].svh ? 4 : 3, 0); + } + for (j = 0; j < Nav.ns; j++) { + if (Nav.seph[j].sat != i + 1) continue; + GraphR->ToPoint(TimePos(Nav.seph[j].tof), yp[i], ps[0]); + in = GraphR->ToPoint(TimePos(Nav.seph[j].t0), yp[i], ps[2]); + ps[1] = ps[0]; + off[Nav.seph[j].sat - 1] = off[Nav.seph[j].sat - 1] ? 0 : 3; + for (k = 0; k < 3; k++) ps[k].y += MarkSize + 2 + off[Nav.seph[j].sat - 1]; + ps[0].y -= 2; + + svh = Nav.seph[j].svh; + GraphR->DrawPoly(ps, 3, svh ? MColor[0][5] : CColor[1], 0); + + if (in) + GraphR->DrawMark(ps[2], 0, Nav.seph[j].svh ? MColor[0][5] : CColor[1], + Nav.seph[j].svh ? 4 : 3, 0); } + } } // draw sky-image on sky-plot ----------------------------------------------- -void __fastcall TPlot::DrawSkyImage(int level) -{ - TCanvas *c=Disp->Canvas; - TPoint p1,p2; - double xl[2],yl[2],r,s,mx[190],my[190]; - - trace(3,"DrawSkyImage: level=%d\n",level); - - if (SkySize[0]<=0||SkySize[1]<=0) return; - - GraphS->GetLim(xl,yl); - r=(xl[1]-xl[0]Width/2.0/SkyScaleR; - GraphS->ToPoint(-s,s,p1); - GraphS->ToPoint(s,-s,p2); - TRect rect(p1,p2); - c->StretchDraw(rect,SkyImageR); - - if (SkyElMask) { // elevation mask - int n=0; - - mx[n]=0.0; my[n++]=yl[1]; - for (int i=0;i<=180;i++) { - mx[n ]=r*sin(i*2.0*D2R); - my[n++]=r*cos(i*2.0*D2R); - } - mx[n]=0.0; my[n++]=yl[1]; - mx[n]=xl[0]; my[n++]=yl[1]; - mx[n]=xl[0]; my[n++]=yl[0]; - mx[n]=xl[1]; my[n++]=yl[0]; - mx[n]=xl[1]; my[n++]=yl[1]; - GraphS->DrawPatch(mx,my,n,CColor[0],CColor[0],0); - } +void __fastcall TPlot::DrawSkyImage(int level) { + TCanvas *c = Disp->Canvas; + TPoint p1, p2; + double xl[2], yl[2], r, s, mx[190], my[190]; + + trace(3, "DrawSkyImage: level=%d\n", level); + + if (SkySize[0] <= 0 || SkySize[1] <= 0) return; + + GraphS->GetLim(xl, yl); + r = (xl[1] - xl[0] < yl[1] - yl[0] ? xl[1] - xl[0] : yl[1] - yl[0]) * 0.45; + s = r * SkyImageR->Width / 2.0 / SkyScaleR; + GraphS->ToPoint(-s, s, p1); + GraphS->ToPoint(s, -s, p2); + TRect rect(p1, p2); + c->StretchDraw(rect, SkyImageR); + + if (SkyElMask) { // elevation mask + int n = 0; + + mx[n] = 0.0; + my[n++] = yl[1]; + for (int i = 0; i <= 180; i++) { + mx[n] = r * sin(i * 2.0 * D2R); + my[n++] = r * cos(i * 2.0 * D2R); + } + mx[n] = 0.0; + my[n++] = yl[1]; + mx[n] = xl[0]; + my[n++] = yl[1]; + mx[n] = xl[0]; + my[n++] = yl[0]; + mx[n] = xl[1]; + my[n++] = yl[0]; + mx[n] = xl[1]; + my[n++] = yl[1]; + GraphS->DrawPatch(mx, my, n, CColor[0], CColor[0], 0); + } } // draw sky-plot ------------------------------------------------------------ -void __fastcall TPlot::DrawSky(int level) -{ - TPoint p1,p2; - AnsiString text=ObsType->Text; - const char *obstype=text.c_str(); - obsd_t *obs; - gtime_t t[MAXSAT]={{0}}; - double p[MAXSAT][2]={{0}},gfp[MAXSAT][NFREQ+NEXOBS]={{0}},p0[MAXSAT][2]={{0}}; - double x,y,xp,yp,xs,ys,dt,dx,dy,xl[2],yl[2],r,gf,freq1,freq2; - int i,j,ind=ObsIndex,freq; - int hh=(int)(Disp->Font->Size*1.5),prn,color,slip; - - trace(3,"DrawSky: level=%d\n",level); - - GraphS->GetLim(xl,yl); - r=(xl[1]-xl[0]Down) { - DrawSkyImage(level); - } - if (BtnShowSkyplot->Down) { - GraphS->DrawSkyPlot(0.0,0.0,CColor[1],CColor[2],CColor[0],r*2.0); - } - if (!BtnSol1->Down) return; - - GraphS->GetScale(xs,ys); - - if (PlotStyle<=2) { - for (i=0;isat-1]||!SatSel[obs->sat-1]||El[i]<=0.0) continue; - TColor col=ObsColor(obs,Az[i],El[i]); - if (col==clBlack) continue; - - x =r*sin(Az[i])*(1.0-2.0*El[i]/PI); - y =r*cos(Az[i])*(1.0-2.0*El[i]/PI); - xp=p[obs->sat-1][0]; - yp=p[obs->sat-1][1]; - - if ((x-xp)*(x-xp)+(y-yp)*(y-yp)>=xs*xs) { - int siz=PlotStyle<2?MarkSize:1; - GraphS->DrawMark(x,y,0,PlotStyle<2?col:CColor[3],siz,0); - p[obs->sat-1][0]=x; - p[obs->sat-1][1]=y; - } - if (xp==0.0&&yp==0.0) { - p0[obs->sat-1][0]=x; - p0[obs->sat-1][1]=y; - } - } +void __fastcall TPlot::DrawSky(int level) { + TPoint p1, p2; + AnsiString text = ObsType->Text; + const char *obstype = text.c_str(); + obsd_t *obs; + gtime_t t[MAXSAT] = {{0}}; + double p[MAXSAT][2] = {{0}}, gfp[MAXSAT][NFREQ + NEXOBS] = {{0}}, p0[MAXSAT][2] = {{0}}; + double x, y, xp, yp, xs, ys, dt, dx, dy, xl[2], yl[2], r, gf, freq1, freq2; + int i, j, ind = ObsIndex, freq; + int hh = (int)(Disp->Font->Size * 1.5), prn, color, slip; + + trace(3, "DrawSky: level=%d\n", level); + + GraphS->GetLim(xl, yl); + r = (xl[1] - xl[0] < yl[1] - yl[0] ? xl[1] - xl[0] : yl[1] - yl[0]) * 0.45; + + if (BtnShowImg->Down) { + DrawSkyImage(level); + } + if (BtnShowSkyplot->Down) { + GraphS->DrawSkyPlot(0.0, 0.0, CColor[1], CColor[2], CColor[0], r * 2.0); + } + if (!BtnSol1->Down) return; + + GraphS->GetScale(xs, ys); + + if (PlotStyle <= 2) { + for (i = 0; i < Obs.n; i++) { + obs = &Obs.data[i]; + if (SatMask[obs->sat - 1] || !SatSel[obs->sat - 1] || El[i] <= 0.0) continue; + TColor col = ObsColor(obs, Az[i], El[i]); + if (col == clBlack) continue; + + x = r * sin(Az[i]) * (1.0 - 2.0 * El[i] / PI); + y = r * cos(Az[i]) * (1.0 - 2.0 * El[i] / PI); + xp = p[obs->sat - 1][0]; + yp = p[obs->sat - 1][1]; + + if ((x - xp) * (x - xp) + (y - yp) * (y - yp) >= xs * xs) { + int siz = PlotStyle < 2 ? MarkSize : 1; + GraphS->DrawMark(x, y, 0, PlotStyle < 2 ? col : CColor[3], siz, 0); + p[obs->sat - 1][0] = x; + p[obs->sat - 1][1] = y; + } + if (xp == 0.0 && yp == 0.0) { + p0[obs->sat - 1][0] = x; + p0[obs->sat - 1][1] = y; + } } - if ((PlotStyle==0||PlotStyle==2)&&!BtnShowTrack->Down) { - - for (i=0;iToPoint(p0[i][0],p0[i][1],pnt)) { - char id[8]; - satno2id(i+1,id); - UTF8String ustr=id; - DrawLabel(GraphS,pnt,ustr,1,0); - } - } + } + if ((PlotStyle == 0 || PlotStyle == 2) && !BtnShowTrack->Down) { + for (i = 0; i < MAXSAT; i++) { + if (p0[i][0] != 0.0 || p0[i][1] != 0.0) { + TPoint pnt; + if (GraphS->ToPoint(p0[i][0], p0[i][1], pnt)) { + char id[8]; + satno2id(i + 1, id); + UTF8String ustr = id; + DrawLabel(GraphS, pnt, ustr, 1, 0); } + } } - if (!level) return; - - if (ShowSlip&&PlotStyle<=2) { - int *LLI=new int [Obs.n]; - - GenObsSlip(LLI); - - for (i=0;itime,t[obs->sat-1]); - dx=x-p[obs->sat-1][0]; - dy=y-p[obs->sat-1][1]; - t[obs->sat-1]=obs->time; - p[obs->sat-1][0]=x; - p[obs->sat-1][1]=y; - if (fabs(dt)>300.0) continue; - GraphS->DrawMark(x,y,4,MColor[0][5],MarkSize*3+2,ATAN2(dy,dx)*R2D+90); - } - delete [] LLI; - } - if (ElMaskP) { - double *x=new double [361]; - double *y=new double [361]; - for (i=0;i<=360;i++) { - x[i]=r*sin(i*D2R)*(1.0-2.0*ElMaskData[i]/PI); - y[i]=r*cos(i*D2R)*(1.0-2.0*ElMaskData[i]/PI); - } - Disp->Canvas->Pen->Width=2; - GraphS->DrawPoly(x,y,361,COL_ELMASK,0); - Disp->Canvas->Pen->Width=1; - delete [] x; - delete [] y; - } - if (BtnShowTrack->Down&&0<=ind&&indsat-1]||!SatSel[obs->sat-1]||El[i]<=0.0) continue; - TColor col=ObsColor(obs,Az[i],El[i]); - if (col==clBlack) continue; - - x=r*sin(Az[i])*(1.0-2.0*El[i]/PI); - y=r*cos(Az[i])*(1.0-2.0*El[i]/PI); - - char id[8]; - satno2id(obs->sat,id); - UTF8String ustr=id; - GraphS->DrawMark(x,y,0,col,Disp->Font->Size*2+5,0); - GraphS->DrawMark(x,y,1,col==clBlack?MColor[0][0]:CColor[2],Disp->Font->Size*2+5,0); - GraphS->DrawText(x,y,ustr,CColor[0],0,0,0); - } + } + if (!level) return; + + if (ShowSlip && PlotStyle <= 2) { + int *LLI = new int[Obs.n]; + + GenObsSlip(LLI); + + for (i = 0; i < Obs.n; i++) { + if (!(LLI[i] & 1)) continue; + obs = Obs.data + i; + x = r * sin(Az[i]) * (1.0 - 2.0 * El[i] / PI); + y = r * cos(Az[i]) * (1.0 - 2.0 * El[i] / PI); + dt = timediff(obs->time, t[obs->sat - 1]); + dx = x - p[obs->sat - 1][0]; + dy = y - p[obs->sat - 1][1]; + t[obs->sat - 1] = obs->time; + p[obs->sat - 1][0] = x; + p[obs->sat - 1][1] = y; + if (fabs(dt) > 300.0) continue; + GraphS->DrawMark(x, y, 4, MColor[0][5], MarkSize * 3 + 2, ATAN2(dy, dx) * R2D + 90); } - GraphS->GetPos(p1,p2); - p1.x+=10; p1.y+=8; p2.x-=10; p2.y=p1.y; - - if (ShowStats&&!SimObs) { - UTF8String ustr; - ustr.sprintf("MARKER: %s %s %s",Sta.name,Sta.markerno,Sta.markertype); - DrawLabel(GraphS,p1,ustr,1,2); p1.y+=hh; - ustr.sprintf("REC: %s %s %s",Sta.rectype,Sta.recver,Sta.recsno); - DrawLabel(GraphS,p1,ustr,1,2); p1.y+=hh; - ustr.sprintf("ANT: %s %s",Sta.antdes,Sta.antsno); - DrawLabel(GraphS,p1,ustr,1,2); p1.y+=hh; - } - // show statistics - if (ShowStats&&BtnShowTrack->Down&&0<=ind&&indDrawText(p2,ustr,clBlack,2,2,0,MS_FONT); - p2.y+=3; - - for (i=IndexObs[ind];isat-1]||!SatSel[obs->sat-1]) continue; - if (HideLowSat&&El[i]sat,id); - ustr.sprintf("%-3s: ",id); - - if (!strcmp(obstype,"ALL")) { - for (j=0;jP[j]==0.0?"-":"C"; - ustr+=" "; - for (j=0;jL[j]==0.0?"-":"L"; - ustr+=" "; - for (j=0;jP[j]==0.0&&obs->L[j]==0.0) ustr+="-- "; - else ustr+=ss.sprintf("%02.0f ",obs->SNR[j]); - } - for (j=0;jL[j]==0.0) ustr+="-"; - else ustr+=ss.sprintf("%d",obs->LLI[j]); - } - } - else if (sscanf(obstype,"L%1d",&freq)==1) { - freq-=freq>2?2:0; /* L1,L2,L5,L6 ... */ - if (!obs->code[freq-1]) continue; - ustr+=ss.sprintf("%3s %s %s %s ",code2obs(obs->code[freq-1]), - obs->P[freq-1]==0.0?"-":"C",obs->L[freq-1]==0.0?"-":"L", - obs->D[freq-1]==0.0?"-":"D"); - if (obs->P[freq-1]==0.0&&obs->L[freq-1]==0.0) ustr+="---- "; - else ustr+=ss.sprintf("%4.1f ",obs->SNR[freq-1]); - if (obs->L[freq-1]==0.0) ustr+=" -"; - else ustr+=ss.sprintf("%2d",obs->LLI[freq-1]); - } - else { - for (j=0;jcode[j]),obstype)) break; - } - if (j>=NFREQ+NEXOBS) continue; - ustr+=ss.sprintf("%3s %s %s %s ",code2obs(obs->code[j]), - obs->P[j]==0.0?"-":"C",obs->L[j]==0.0?"-":"L", - obs->D[j]==0.0?"-":"D"); - if (obs->P[j]==0.0&&obs->L[j]==0.0) ustr+="---- "; - else ustr+=ss.sprintf("%4.1f ",obs->SNR[j]); - if (obs->L[j]==0.0) ustr+=" -"; - else ustr+=ss.sprintf("%2d",obs->LLI[j]); - } - TColor col=ObsColor(obs,Az[i],El[i]); - p2.y+=hh; - GraphS->DrawText(p2,ustr,col==clBlack?MColor[0][0]:col,2,2,0,MS_FONT); - } + delete[] LLI; + } + if (ElMaskP) { + double *x = new double[361]; + double *y = new double[361]; + for (i = 0; i <= 360; i++) { + x[i] = r * sin(i * D2R) * (1.0 - 2.0 * ElMaskData[i] / PI); + y[i] = r * cos(i * D2R) * (1.0 - 2.0 * ElMaskData[i] / PI); } - if (Nav.n<=0&&Nav.ng<=0&&!SimObs) { - GraphS->GetPos(p1,p2); - p2.x-=10; - p2.y-=3; - DrawLabel(GraphS,p2,"No Navigation Data",2,1); + Disp->Canvas->Pen->Width = 2; + GraphS->DrawPoly(x, y, 361, COL_ELMASK, 0); + Disp->Canvas->Pen->Width = 1; + delete[] x; + delete[] y; + } + if (BtnShowTrack->Down && 0 <= ind && ind < NObs) { + for (i = IndexObs[ind]; i < Obs.n && i < IndexObs[ind + 1]; i++) { + obs = &Obs.data[i]; + if (SatMask[obs->sat - 1] || !SatSel[obs->sat - 1] || El[i] <= 0.0) continue; + TColor col = ObsColor(obs, Az[i], El[i]); + if (col == clBlack) continue; + + x = r * sin(Az[i]) * (1.0 - 2.0 * El[i] / PI); + y = r * cos(Az[i]) * (1.0 - 2.0 * El[i] / PI); + + char id[8]; + satno2id(obs->sat, id); + UTF8String ustr = id; + GraphS->DrawMark(x, y, 0, col, Disp->Font->Size * 2 + 5, 0); + GraphS->DrawMark(x, y, 1, col == clBlack ? MColor[0][0] : CColor[2], Disp->Font->Size * 2 + 5, + 0); + GraphS->DrawText(x, y, ustr, CColor[0], 0, 0, 0); } + } + GraphS->GetPos(p1, p2); + p1.x += 10; + p1.y += 8; + p2.x -= 10; + p2.y = p1.y; + + if (ShowStats && !SimObs) { + UTF8String ustr; + ustr.sprintf("MARKER: %s %s %s", Sta.name, Sta.markerno, Sta.markertype); + DrawLabel(GraphS, p1, ustr, 1, 2); + p1.y += hh; + ustr.sprintf("REC: %s %s %s", Sta.rectype, Sta.recver, Sta.recsno); + DrawLabel(GraphS, p1, ustr, 1, 2); + p1.y += hh; + ustr.sprintf("ANT: %s %s", Sta.antdes, Sta.antsno); + DrawLabel(GraphS, p1, ustr, 1, 2); + p1.y += hh; + } + // show statistics + if (ShowStats && BtnShowTrack->Down && 0 <= ind && ind < NObs && !SimObs) { + UTF8String ustr, ss; + char id[8]; + + if (!strcmp(obstype, "ALL")) { + ustr.sprintf("%3s: %*s %*s%*s %*s", "SAT", NFREQ, "PR", NFREQ, "CP", NFREQ * 3, "CN0", NFREQ, + "LLI"); + } else { + ustr.sprintf("%3s: %3s %4s %3s %3s", "SAT", "SIG", "OBS", "CN0", "LLI"); + } + GraphS->DrawText(p2, ustr, clBlack, 2, 2, 0, MS_FONT); + p2.y += 3; + + for (i = IndexObs[ind]; i < Obs.n && i < IndexObs[ind + 1]; i++) { + obs = &Obs.data[i]; + if (SatMask[obs->sat - 1] || !SatSel[obs->sat - 1]) continue; + if (HideLowSat && El[i] < ElMask * D2R) continue; + if (HideLowSat && ElMaskP && El[i] < ElMaskData[(int)(Az[i] * R2D + 0.5)]) continue; + + satno2id(obs->sat, id); + ustr.sprintf("%-3s: ", id); + + if (!strcmp(obstype, "ALL")) { + for (j = 0; j < NFREQ; j++) ustr += obs->P[j] == 0.0 ? "-" : "C"; + ustr += " "; + for (j = 0; j < NFREQ; j++) ustr += obs->L[j] == 0.0 ? "-" : "L"; + ustr += " "; + for (j = 0; j < NFREQ; j++) { + if (obs->P[j] == 0.0 && obs->L[j] == 0.0) + ustr += "-- "; + else + ustr += ss.sprintf("%02.0f ", obs->SNR[j]); + } + for (j = 0; j < NFREQ; j++) { + if (obs->L[j] == 0.0) + ustr += "-"; + else + ustr += ss.sprintf("%d", obs->LLI[j]); + } + } else if (sscanf(obstype, "L%1d", &freq) == 1) { + freq -= freq > 2 ? 2 : 0; /* L1,L2,L5,L6 ... */ + if (!obs->code[freq - 1]) continue; + ustr += ss.sprintf("%3s %s %s %s ", code2obs(obs->code[freq - 1]), + obs->P[freq - 1] == 0.0 ? "-" : "C", obs->L[freq - 1] == 0.0 ? "-" : "L", + obs->D[freq - 1] == 0.0 ? "-" : "D"); + if (obs->P[freq - 1] == 0.0 && obs->L[freq - 1] == 0.0) + ustr += "---- "; + else + ustr += ss.sprintf("%4.1f ", obs->SNR[freq - 1]); + if (obs->L[freq - 1] == 0.0) + ustr += " -"; + else + ustr += ss.sprintf("%2d", obs->LLI[freq - 1]); + } else { + for (j = 0; j < NFREQ + NEXOBS; j++) { + if (!strcmp(code2obs(obs->code[j]), obstype)) break; + } + if (j >= NFREQ + NEXOBS) continue; + ustr += ss.sprintf("%3s %s %s %s ", code2obs(obs->code[j]), obs->P[j] == 0.0 ? "-" : "C", + obs->L[j] == 0.0 ? "-" : "L", obs->D[j] == 0.0 ? "-" : "D"); + if (obs->P[j] == 0.0 && obs->L[j] == 0.0) + ustr += "---- "; + else + ustr += ss.sprintf("%4.1f ", obs->SNR[j]); + if (obs->L[j] == 0.0) + ustr += " -"; + else + ustr += ss.sprintf("%2d", obs->LLI[j]); + } + TColor col = ObsColor(obs, Az[i], El[i]); + p2.y += hh; + GraphS->DrawText(p2, ustr, col == clBlack ? MColor[0][0] : col, 2, 2, 0, MS_FONT); + } + } + if (Nav.n <= 0 && Nav.ng <= 0 && !SimObs) { + GraphS->GetPos(p1, p2); + p2.x -= 10; + p2.y -= 3; + DrawLabel(GraphS, p2, "No Navigation Data", 2, 1); + } } // Draw sky-plot ------------------------------------------------------------ void __fastcall TPlot::DrawSolSky(int level) { @@ -1416,7 +1442,7 @@ void __fastcall TPlot::DrawSolSky(int level) { double p0[MAXSAT][2] = {{0}}; if (PlotStyle <= 2) { - double p[MAXSAT][2]={{0}}; + double p[MAXSAT][2] = {{0}}; for (int i = 0; i < sn; i++) { solstat_t *solstat = SolStat[sel].data + i; if (SatMask[solstat->sat - 1] || !SatSel[solstat->sat - 1]) continue; @@ -1511,172 +1537,167 @@ void __fastcall TPlot::DrawSolSky(int level) { if (BtnShowTrack->Down && 0 <= ind && ind < SolData[sel].n) { gtime_t t = SolData[sel].data[ind].time; - for (int i = 0; i < sn; i++) { - solstat_t *solstat = SolStat[sel].data + i; - if (timediff(solstat->time, t) < -DTTOL) continue; - if (timediff(solstat->time, t) > DTTOL) break; - if (SatMask[solstat->sat - 1] || !SatSel[solstat->sat - 1]) continue; - if (solstat->frq != frq || solstat->el <= 0.0) continue; + for (int i = 0; i < sn; i++) { + solstat_t *solstat = SolStat[sel].data + i; + if (timediff(solstat->time, t) < -DTTOL) continue; + if (timediff(solstat->time, t) > DTTOL) break; + if (SatMask[solstat->sat - 1] || !SatSel[solstat->sat - 1]) continue; + if (solstat->frq != frq || solstat->el <= 0.0) continue; + + TColor col = SnrColor(solstat->snr); + // Include satellites with invalid data but note this in the color. + if ((solstat->flag & 0x20) == 0) col = MColor[0][7]; + double azel[2]; + azel[0] = solstat->az; + azel[1] = solstat->el; + if (solstat->el < ElMask * D2R || + (ElMaskP && solstat->el < ElMaskData[(int)(solstat->az * R2D + 0.5)])) { + if (HideLowSat) continue; + col = MColor[0][0]; + } + + double x = r * sin(solstat->az) * (1.0 - 2.0 * solstat->el / PI); + double y = r * cos(solstat->az) * (1.0 - 2.0 * solstat->el / PI); + + char id[8]; + satno2id(solstat->sat, id); + UTF8String ustr = id; + GraphS->DrawMark(x, y, 0, col, Disp->Font->Size * 2 + 5, 0); + GraphS->DrawMark(x, y, 1, col == clBlack ? MColor[0][0] : CColor[2], Disp->Font->Size * 2 + 5, + 0); + GraphS->DrawText(x, y, ustr, CColor[0], 0, 0, 0); + } + } +} +// draw DOP and number-of-satellite plot ------------------------------------ +void __fastcall TPlot::DrawDop(int level) { + UTF8String label; + TPoint p1, p2; + gtime_t time; + double xp, xc, yc, xl[2], yl[2], azel[MAXSAT * 2], *dop, *x, *y; + int i, j, *ns, prn, n = 0; + int ind = ObsIndex, doptype = DopType->ItemIndex; + + trace(3, "DrawDop: level=%d\n", level); + + GraphR->XLPos = TimeLabel ? 6 : 1; + GraphR->YLPos = 1; + GraphR->Week = Week; + GraphR->GetLim(xl, yl); + yl[0] = 0.0; + yl[1] = MaxDop; + GraphR->SetLim(xl, yl); + GraphR->SetTick(0.0, 0.0); + + if (0 <= ind && ind < NObs && BtnShowTrack->Down && BtnFixHoriz->Down) { + double xl[2], yl[2], off; + GraphR->GetLim(xl, yl); + off = Xcent * (xl[1] - xl[0]) / 2.0; + xp = TimePos(Obs.data[IndexObs[ind]].time); + GraphR->GetCent(xc, yc); + GraphR->SetCent(xp - off, yc); + } + GraphR->DrawAxis(1, 1); + GraphR->GetPos(p1, p2); + p1.x = Disp->Font->Size; + p1.y = (p1.y + p2.y) / 2; + if (doptype == 0) { + label.sprintf("# OF SATELLITES / DOP %s 10 (EL %s %.0f%s)", CHARMUL, CHARGTE, ElMask, CHARDEG); + } else if (doptype == 1) { + label.sprintf("# OF SATELLITES (EL %s %.0f%s)", CHARGTE, ElMask, CHARDEG); + } else { + label.sprintf("DOP %s 10 (EL %s %.0f%s)", CHARMUL, CHARGTE, ElMask, CHARDEG); + } + GraphR->DrawText(p1, label, CColor[2], 0, 0, 90); + + if (!BtnSol1->Down) return; - TColor col = SnrColor(solstat->snr); - // Include satellites with invalid data but note this in the color. - if ((solstat->flag & 0x20) == 0) col = MColor[0][7]; - double azel[2]; - azel[0] = solstat->az; - azel[1] = solstat->el; - if (solstat->el < ElMask * D2R || - (ElMaskP && solstat->el < ElMaskData[(int)(solstat->az * R2D + 0.5)])) { - if (HideLowSat) continue; - col = MColor[0][0]; - } + x = new double[NObs]; + y = new double[NObs]; + dop = new double[NObs * 4]; + ns = new int[NObs]; - double x = r * sin(solstat->az) * (1.0 - 2.0 * solstat->el / PI); - double y = r * cos(solstat->az) * (1.0 - 2.0 * solstat->el / PI); + for (i = 0; i < NObs; i++) { + ns[n] = 0; + for (j = IndexObs[i]; j < Obs.n && j < IndexObs[i + 1]; j++) { + if (SatMask[Obs.data[j].sat - 1] || !SatSel[Obs.data[j].sat - 1]) continue; + if (El[j] < ElMask * D2R) continue; + if (ElMaskP && El[j] < ElMaskData[(int)(Az[j] * R2D + 0.5)]) continue; + azel[ns[n] * 2] = Az[j]; + azel[1 + ns[n] * 2] = El[j]; + ns[n]++; + } + dops(ns[n], azel, ElMask * D2R, dop + n * 4); + x[n++] = TimePos(Obs.data[IndexObs[i]].time); + } + for (i = 0; i < 4; i++) { + if (doptype != 0 && doptype != i + 2) continue; - char id[8]; - satno2id(solstat->sat, id); - UTF8String ustr = id; - GraphS->DrawMark(x, y, 0, col, Disp->Font->Size * 2 + 5, 0); - GraphS->DrawMark(x, y, 1, col == clBlack ? MColor[0][0] : CColor[2], Disp->Font->Size * 2 + 5, - 0); - GraphS->DrawText(x, y, ustr, CColor[0], 0, 0, 0); + for (j = 0; j < n; j++) y[j] = dop[i + j * 4] * 10.0; + + if (!(PlotStyle % 2)) { + DrawPolyS(GraphR, x, y, n, CColor[3], 0); + } + if (level && PlotStyle < 2) { + for (j = 0; j < n; j++) { + if (y[j] == 0.0) continue; + GraphR->DrawMark(x[j], y[j], 0, MColor[0][i + 2], MarkSize, 0); + } } } -} -// draw DOP and number-of-satellite plot ------------------------------------ -void __fastcall TPlot::DrawDop(int level) -{ - UTF8String label; - TPoint p1,p2; - gtime_t time; - double xp,xc,yc,xl[2],yl[2],azel[MAXSAT*2],*dop,*x,*y; - int i,j,*ns,prn,n=0; - int ind=ObsIndex,doptype=DopType->ItemIndex; - - trace(3,"DrawDop: level=%d\n",level); - - GraphR->XLPos=TimeLabel?6:1; - GraphR->YLPos=1; - GraphR->Week=Week; - GraphR->GetLim(xl,yl); - yl[0]=0.0; - yl[1]=MaxDop; - GraphR->SetLim(xl,yl); - GraphR->SetTick(0.0,0.0); - - if (0<=ind&&indDown&&BtnFixHoriz->Down) { - double xl[2],yl[2],off; - GraphR->GetLim(xl,yl); - off=Xcent*(xl[1]-xl[0])/2.0; - xp=TimePos(Obs.data[IndexObs[ind]].time); - GraphR->GetCent(xc,yc); - GraphR->SetCent(xp-off,yc); - } - GraphR->DrawAxis(1,1); - GraphR->GetPos(p1,p2); - p1.x=Disp->Font->Size; - p1.y=(p1.y+p2.y)/2; - if (doptype==0) { - label.sprintf("# OF SATELLITES / DOP %s 10 (EL %s %.0f%s)",CHARMUL, - CHARGTE,ElMask,CHARDEG); - } - else if (doptype==1) { - label.sprintf("# OF SATELLITES (EL %s %.0f%s)",CHARGTE,ElMask,CHARDEG); - } - else { - label.sprintf("DOP %s 10 (EL %s %.0f%s)",CHARMUL,CHARGTE,ElMask,CHARDEG); - } - GraphR->DrawText(p1,label,CColor[2],0,0,90); - - if (!BtnSol1->Down) return; - - x =new double[NObs]; - y =new double[NObs]; - dop=new double[NObs*4]; - ns =new int [NObs]; - - for (i=0;iDrawMark(x[j],y[j],0,MColor[0][i+2],MarkSize,0); - } - } + if (doptype == 0 || doptype == 1) { + for (i = 0; i < n; i++) y[i] = ns[i]; + + if (!(PlotStyle % 2)) { + DrawPolyS(GraphR, x, y, n, CColor[3], 1); } - if (doptype==0||doptype==1) { - for (i=0;iDrawMark(x[i],y[i],0,MColor[0][1],MarkSize,0); - } - } + if (level && PlotStyle < 2) { + for (i = 0; i < n; i++) { + GraphR->DrawMark(x[i], y[i], 0, MColor[0][1], MarkSize, 0); + } } - if (BtnShowTrack->Down&&0<=ind&&indGetLim(xl,yl); - xl[0]=xl[1]=TimePos(Obs.data[IndexObs[ind]].time); - - GraphR->DrawPoly(xl,yl,2,CColor[2],0); - - ns[0]=0; - for (i=IndexObs[ind];iDrawMark(xl[0],dop[i]*10.0,0,MColor[0][i+2],MarkSize*2+2,0); - } - if (doptype==0||doptype==1) { - GraphR->DrawMark(xl[0],ns[0],0,MColor[0][1],MarkSize*2+2,0); - } - GraphR->DrawMark(xl[0],yl[1]-1E-6,0,CColor[2],5,0); - if (!BtnFixHoriz->Down) { - GraphR->DrawMark(xl[0],yl[1]-1E-6,1,CColor[2],9,0); - } + } + if (BtnShowTrack->Down && 0 <= ind && ind < NObs) { + GraphR->GetLim(xl, yl); + xl[0] = xl[1] = TimePos(Obs.data[IndexObs[ind]].time); + + GraphR->DrawPoly(xl, yl, 2, CColor[2], 0); + + ns[0] = 0; + for (i = IndexObs[ind]; i < Obs.n && i < IndexObs[ind + 1]; i++) { + if (SatMask[Obs.data[i].sat - 1] || !SatSel[Obs.data[i].sat - 1]) continue; + if (El[i] < ElMask * D2R) continue; + if (ElMaskP && El[i] < ElMaskData[(int)(Az[i] * R2D + 0.5)]) continue; + azel[ns[0] * 2] = Az[i]; + azel[1 + ns[0] * 2] = El[i]; + ns[0]++; + } + dops(ns[0], azel, ElMask * D2R, dop); + + for (i = 0; i < 4; i++) { + if ((doptype != 0 && doptype != i + 2) || dop[i] <= 0.0) continue; + GraphR->DrawMark(xl[0], dop[i] * 10.0, 0, MColor[0][i + 2], MarkSize * 2 + 2, 0); } - else { - DrawDopStat(dop,ns,n); + if (doptype == 0 || doptype == 1) { + GraphR->DrawMark(xl[0], ns[0], 0, MColor[0][1], MarkSize * 2 + 2, 0); } - if (Nav.n<=0&&Nav.ng<=0&&(doptype==0||doptype>=2)&&!SimObs) { - GraphR->GetPos(p1,p2); - p2.x-=10; - p2.y-=3; - DrawLabel(GraphR,p2,"No Navigation Data",2,1); + GraphR->DrawMark(xl[0], yl[1] - 1E-6, 0, CColor[2], 5, 0); + if (!BtnFixHoriz->Down) { + GraphR->DrawMark(xl[0], yl[1] - 1E-6, 1, CColor[2], 9, 0); } - delete [] x; - delete [] y; - delete [] dop; - delete [] ns; + } else { + DrawDopStat(dop, ns, n); + } + if (Nav.n <= 0 && Nav.ng <= 0 && (doptype == 0 || doptype >= 2) && !SimObs) { + GraphR->GetPos(p1, p2); + p2.x -= 10; + p2.y -= 3; + DrawLabel(GraphR, p2, "No Navigation Data", 2, 1); + } + delete[] x; + delete[] y; + delete[] dop; + delete[] ns; } // Draw DOP and number-of-satellite plot ------------------------------------ void __fastcall TPlot::DrawSolDop(int level) { @@ -1836,777 +1857,784 @@ void __fastcall TPlot::DrawSolDop(int level) { delete[] ns; } // draw statistics on DOP and number-of-satellite plot ---------------------- -void __fastcall TPlot::DrawDopStat(double *dop, int *ns, int n) -{ - AnsiString s0[MAXOBS+2],s1[MAXOBS+2],s2[MAXOBS+2]; - double ave[4]={0}; - int nsat[MAXOBS]={0},ndop[4]={0},m=0; - - trace(3,"DrawDopStat: n=%d\n",n); - - if (!ShowStats) return; - - for (int i=0;iMaxDop) continue; - ave[i]+=dop[i+j*4]; - ndop[i]++; - } - if (ndop[i]>0) ave[i]/=ndop[i]; - } - if (DopType->ItemIndex==0||DopType->ItemIndex>=2) { - s2[m++].sprintf("AVE= GDOP:%4.1f PDOP:%4.1f HDOP:%4.1f VDOP:%4.1f", - ave[0],ave[1],ave[2],ave[3]); - s2[m++].sprintf("NDOP=%d(%4.1f%%) %d(%4.1f%%) %d(%4.1f%%) %d(%4.1f%%)", - ndop[0],n>0?ndop[0]*100.0/n:0.0, - ndop[1],n>0?ndop[1]*100.0/n:0.0, - ndop[2],n>0?ndop[2]*100.0/n:0.0, - ndop[3],n>0?ndop[3]*100.0/n:0.0); - } - if (DopType->ItemIndex<=1) { - for (int i=0,j=0;i MaxDop) continue; + ave[i] += dop[i + j * 4]; + ndop[i]++; } - TPoint p1,p2,p3,p4; - int fonth=(int)(Disp->Font->Size*1.5); - - GraphR->GetPos(p1,p2); - p1.x=p2.x-10; - p1.y+=8; - p2=p1; p2.x-=fonth*4; - p3=p2; p3.x-=fonth*8; - - for (int i=0;i 0) ave[i] /= ndop[i]; + } + if (DopType->ItemIndex == 0 || DopType->ItemIndex >= 2) { + s2[m++].sprintf("AVE= GDOP:%4.1f PDOP:%4.1f HDOP:%4.1f VDOP:%4.1f", ave[0], ave[1], ave[2], + ave[3]); + s2[m++].sprintf("NDOP=%d(%4.1f%%) %d(%4.1f%%) %d(%4.1f%%) %d(%4.1f%%)", ndop[0], + n > 0 ? ndop[0] * 100.0 / n : 0.0, ndop[1], n > 0 ? ndop[1] * 100.0 / n : 0.0, + ndop[2], n > 0 ? ndop[2] * 100.0 / n : 0.0, ndop[3], + n > 0 ? ndop[3] * 100.0 / n : 0.0); + } + if (DopType->ItemIndex <= 1) { + for (int i = 0, j = 0; i < MAXOBS; i++) { + if (nsat[i] <= 0) continue; + s0[m].sprintf("%s%2d:", j++ == 0 ? "NSAT= " : "", i); + s1[m].sprintf("%7d", nsat[i]); + s2[m++].sprintf("(%4.1f%%)", nsat[i] * 100.0 / n); } + } + TPoint p1, p2, p3, p4; + int fonth = (int)(Disp->Font->Size * 1.5); + + GraphR->GetPos(p1, p2); + p1.x = p2.x - 10; + p1.y += 8; + p2 = p1; + p2.x -= fonth * 4; + p3 = p2; + p3.x -= fonth * 8; + + for (int i = 0; i < m; i++) { + DrawLabel(GraphR, p3, s0[i], 2, 2); + DrawLabel(GraphR, p2, s1[i], 2, 2); + DrawLabel(GraphR, p1, s2[i], 2, 2); + p1.y += fonth; + p2.y += fonth; + p3.y += fonth; + } } // draw SNR, MP and elevation-plot --------------------------------------------- -void __fastcall TPlot::DrawSnr(int level) -{ - TSpeedButton *btn[]={BtnOn1,BtnOn2,BtnOn3}; - UTF8String label[]={"SNR","Multipath","Elevation"}; - UTF8String unit[]={"dBHz","m",CHARDEG}; - AnsiString s; - gtime_t time={0}; - - trace(3,"DrawSnr: level=%d\n",level); - - if (0<=ObsIndex&&ObsIndexDown) { - time=Obs.data[IndexObs[ObsIndex]].time; - } - if (0<=ObsIndex&&ObsIndexDown&&BtnFixHoriz->Down) { - double xc,yc,xp=TimePos(time); - double xl[2],yl[2]; - - GraphG[0]->GetLim(xl,yl); - xp-=Xcent*(xl[1]-xl[0])/2.0; - for (int i=0;i<3;i++) { - GraphG[i]->GetCent(xc,yc); - GraphG[i]->SetCent(xp,yc); - } +void __fastcall TPlot::DrawSnr(int level) { + TSpeedButton *btn[] = {BtnOn1, BtnOn2, BtnOn3}; + UTF8String label[] = {"SNR", "Multipath", "Elevation"}; + UTF8String unit[] = {"dBHz", "m", CHARDEG}; + AnsiString s; + gtime_t time = {0}; + + trace(3, "DrawSnr: level=%d\n", level); + + if (0 <= ObsIndex && ObsIndex < NObs && BtnShowTrack->Down) { + time = Obs.data[IndexObs[ObsIndex]].time; + } + if (0 <= ObsIndex && ObsIndex < NObs && BtnShowTrack->Down && BtnFixHoriz->Down) { + double xc, yc, xp = TimePos(time); + double xl[2], yl[2]; + + GraphG[0]->GetLim(xl, yl); + xp -= Xcent * (xl[1] - xl[0]) / 2.0; + for (int i = 0; i < 3; i++) { + GraphG[i]->GetCent(xc, yc); + GraphG[i]->SetCent(xp, yc); } - int j=0; - for (int i=0;i<3;i++) if (btn[i]->Down) j=i; - for (int i=0;i<3;i++) { - if (!btn[i]->Down) continue; - GraphG[i]->XLPos=TimeLabel?(i==j?6:5):(i==j?1:0); - GraphG[i]->Week=Week; - GraphG[i]->DrawAxis(ShowLabel,ShowLabel); - } - if (NObs>0&&BtnSol1->Down) { - AnsiString text=ObsType2->Text; - const char *obstype=text.c_str(); - double *x=new double[NObs]; - double *y=new double[NObs]; - TColor *col=new TColor[NObs]; - - for (int i=0,l=0;i<3;i++) { - TColor colp[MAXSAT]; - double yp[MAXSAT],ave=0.0,rms=0.0; - int np=0,nrms=0; - - if (!btn[i]->Down) continue; - - for (int sat=1,np=0;sat<=MAXSAT;sat++) { - if (SatMask[sat-1]||!SatSel[sat-1]) continue; - int n=0; - for (int j=0;jsat!=sat) continue; - if (sscanf(obstype,"L%1d",&freq)==1) { - k=freq>2?freq-3:freq-1; - } - else { - for (k=0;kcode[k]),obstype)) break; - } - if (k>=NFREQ+NEXOBS) continue; - } - if (obs->SNR[k]<=0.0) continue; - - x[n]=TimePos(obs->time); - if (i==0) { - y[n]=obs->SNR[k]; - col[n]=MColor[0][4]; - } - else if (i==1) { - if (!Mp[k]||Mp[k][j]==0.0) continue; - y[n]=Mp[k][j]; - col[n]=MColor[0][4]; - } - else { - y[n]=El[j]*R2D; - if (SimObs) col[n]=SysColor(obs->sat); - else col[n]=SnrColor(obs->SNR[k]); - if (El[j]>0.0&&El[j]time)==0.0&&np30.0) break; - DrawPolyS(GraphG[i],x+j,y+j,k-j,CColor[3],0); - } - } - if (level&&PlotStyle<2) { - for (int j=0;jDrawMark(x[j],y[j],0,col[j],MarkSize,0); - } - } - for (int j=0;j0&&ShowStats&&!BtnShowTrack->Down) { - TPoint p1,p2; - ave=ave/nrms; - rms=SQRT(rms/nrms); - GraphG[i]->GetPos(p1,p2); - p1.x=p2.x-8; p1.y+=3; - DrawLabel(GraphG[i],p1,s.sprintf("AVE=%.4fm RMS=%.4fm",ave,rms),2,2); - } - if (BtnShowTrack->Down&&0<=ObsIndex&&ObsIndexDown) { - if (!btn[i]->Down) continue; - TPoint p1,p2; - double xl[2],yl[2]; - GraphG[i]->GetLim(xl,yl); - xl[0]=xl[1]=TimePos(time); - GraphG[i]->DrawPoly(xl,yl,2,CColor[2],0); - - if (l++==0) { - GraphG[i]->DrawMark(xl[0],yl[1]-1E-6,0,CColor[2],5,0); - - if (!BtnFixHoriz->Down) { - GraphG[i]->DrawMark(xl[0],yl[1]-1E-6,1,CColor[2],9,0); - } - } - for (int k=0;kDrawMark(xl[0],yp[k],0,CColor[0],MarkSize*2+4,0); - GraphG[i]->DrawMark(xl[0],yp[k],0,colp[k],MarkSize*2+2,0); - } - if (np<=0||np>1||(i!=1&&yp[0]<=0.0)) continue; - GraphG[i]->GetPos(p1,p2); - p1.x=p2.x-8; p1.y+=3; - DrawLabel(GraphG[i],p1,s.sprintf("%.*f %s",i==1?4:1,yp[0],unit[i].c_str()),2,2); + } + int j = 0; + for (int i = 0; i < 3; i++) + if (btn[i]->Down) j = i; + for (int i = 0; i < 3; i++) { + if (!btn[i]->Down) continue; + GraphG[i]->XLPos = TimeLabel ? (i == j ? 6 : 5) : (i == j ? 1 : 0); + GraphG[i]->Week = Week; + GraphG[i]->DrawAxis(ShowLabel, ShowLabel); + } + if (NObs > 0 && BtnSol1->Down) { + AnsiString text = ObsType2->Text; + const char *obstype = text.c_str(); + double *x = new double[NObs]; + double *y = new double[NObs]; + TColor *col = new TColor[NObs]; + + for (int i = 0, l = 0; i < 3; i++) { + TColor colp[MAXSAT]; + double yp[MAXSAT], ave = 0.0, rms = 0.0; + int np = 0, nrms = 0; + + if (!btn[i]->Down) continue; + + for (int sat = 1, np = 0; sat <= MAXSAT; sat++) { + if (SatMask[sat - 1] || !SatSel[sat - 1]) continue; + int n = 0; + for (int j = 0; j < Obs.n; j++) { + obsd_t *obs = Obs.data + j; + int k, freq; + if (obs->sat != sat) continue; + if (sscanf(obstype, "L%1d", &freq) == 1) { + k = freq > 2 ? freq - 3 : freq - 1; + } else { + for (k = 0; k < NFREQ + NEXOBS; k++) { + if (!strcmp(code2obs(obs->code[k]), obstype)) break; } + if (k >= NFREQ + NEXOBS) continue; + } + if (obs->SNR[k] <= 0.0) continue; + + x[n] = TimePos(obs->time); + if (i == 0) { + y[n] = obs->SNR[k]; + col[n] = MColor[0][4]; + } else if (i == 1) { + if (!Mp[k] || Mp[k][j] == 0.0) continue; + y[n] = Mp[k][j]; + col[n] = MColor[0][4]; + } else { + y[n] = El[j] * R2D; + if (SimObs) + col[n] = SysColor(obs->sat); + else + col[n] = SnrColor(obs->SNR[k]); + if (El[j] > 0.0 && El[j] < ElMask * D2R) col[n] = MColor[0][0]; + } + if (timediff(time, obs->time) == 0.0 && np < MAXSAT) { + yp[np] = y[n]; + colp[np++] = col[n]; + } + if (n < NObs) n++; + } + if (!level || !(PlotStyle % 2)) { + for (int j = 0, k = 0; j < n; j = k) { + for (k = j + 1; k < n; k++) + if (fabs(y[k - 1] - y[k]) > 30.0) break; + DrawPolyS(GraphG[i], x + j, y + j, k - j, CColor[3], 0); + } + } + if (level && PlotStyle < 2) { + for (int j = 0; j < n; j++) { + if (i != 1 && y[j] <= 0.0) continue; + GraphG[i]->DrawMark(x[j], y[j], 0, col[j], MarkSize, 0); + } + } + for (int j = 0; j < n; j++) { + if (y[j] == 0.0) continue; + ave += y[j]; + rms += SQR(y[j]); + nrms++; } - delete [] x; - delete [] y; - delete [] col; - } - for (int i=0;i<3;i++) { + } + if (level && i == 1 && nrms > 0 && ShowStats && !BtnShowTrack->Down) { + TPoint p1, p2; + ave = ave / nrms; + rms = SQRT(rms / nrms); + GraphG[i]->GetPos(p1, p2); + p1.x = p2.x - 8; + p1.y += 3; + DrawLabel(GraphG[i], p1, s.sprintf("AVE=%.4fm RMS=%.4fm", ave, rms), 2, 2); + } + if (BtnShowTrack->Down && 0 <= ObsIndex && ObsIndex < NObs && BtnSol1->Down) { if (!btn[i]->Down) continue; - TPoint p1,p2; - GraphG[i]->GetPos(p1,p2); - p1.x+=5; p1.y+=3; - DrawLabel(GraphG[i],p1,s.sprintf("%s (%s)",label[i].c_str(),unit[i].c_str()),1,2); + TPoint p1, p2; + double xl[2], yl[2]; + GraphG[i]->GetLim(xl, yl); + xl[0] = xl[1] = TimePos(time); + GraphG[i]->DrawPoly(xl, yl, 2, CColor[2], 0); + + if (l++ == 0) { + GraphG[i]->DrawMark(xl[0], yl[1] - 1E-6, 0, CColor[2], 5, 0); + + if (!BtnFixHoriz->Down) { + GraphG[i]->DrawMark(xl[0], yl[1] - 1E-6, 1, CColor[2], 9, 0); + } + } + for (int k = 0; k < np; k++) { + if (i != 1 && yp[k] <= 0.0) continue; + GraphG[i]->DrawMark(xl[0], yp[k], 0, CColor[0], MarkSize * 2 + 4, 0); + GraphG[i]->DrawMark(xl[0], yp[k], 0, colp[k], MarkSize * 2 + 2, 0); + } + if (np <= 0 || np > 1 || (i != 1 && yp[0] <= 0.0)) continue; + GraphG[i]->GetPos(p1, p2); + p1.x = p2.x - 8; + p1.y += 3; + DrawLabel(GraphG[i], p1, s.sprintf("%.*f %s", i == 1 ? 4 : 1, yp[0], unit[i].c_str()), 2, + 2); + } } + delete[] x; + delete[] y; + delete[] col; + } + for (int i = 0; i < 3; i++) { + if (!btn[i]->Down) continue; + TPoint p1, p2; + GraphG[i]->GetPos(p1, p2); + p1.x += 5; + p1.y += 3; + DrawLabel(GraphG[i], p1, s.sprintf("%s (%s)", label[i].c_str(), unit[i].c_str()), 1, 2); + } } // draw SNR/MP to evation plot ---------------------------------------------- -void __fastcall TPlot::DrawSnrE(int level) -{ - TSpeedButton *btn[]={BtnOn1,BtnOn2,BtnOn3}; - UTF8String label[]={"SNR (dBHz)","Multipath (m)"}; - AnsiString s; - gtime_t time={0}; - double ave=0.0,rms=0.0; - int nrms=0; - - trace(3,"DrawSnrE: level=%d\n",level); - - int j=0; - for (int i=0;i<2;i++) if (btn[i]->Down) j=i; - for (int i=0;i<2;i++) { - TPoint p1,p2; - double xl[2]={-0.001,90.0},yl[2][2]={{10.0,65.0},{-MaxMP,MaxMP}}; - - if (!btn[i]->Down) continue; - GraphE[i]->XLPos=i==j?1:0; - GraphE[i]->YLPos=1; - GraphE[i]->SetLim(xl,yl[i]); - GraphE[i]->SetTick(0.0,0.0); - GraphE[i]->DrawAxis(1,1); - GraphE[i]->GetPos(p1,p2); - p1.x=Disp->Font->Size; - p1.y=(p1.y+p2.y)/2; - GraphE[i]->DrawText(p1,label[i],CColor[2],0,0,90); - if (i==j) { - UTF8String ustr="Elevation (" CHARDEG ")"; - p2.x-=8; p2.y-=6; - GraphE[i]->DrawText(p2,ustr,CColor[2],2,1,0); - } +void __fastcall TPlot::DrawSnrE(int level) { + TSpeedButton *btn[] = {BtnOn1, BtnOn2, BtnOn3}; + UTF8String label[] = {"SNR (dBHz)", "Multipath (m)"}; + AnsiString s; + gtime_t time = {0}; + double ave = 0.0, rms = 0.0; + int nrms = 0; + + trace(3, "DrawSnrE: level=%d\n", level); + + int j = 0; + for (int i = 0; i < 2; i++) + if (btn[i]->Down) j = i; + for (int i = 0; i < 2; i++) { + TPoint p1, p2; + double xl[2] = {-0.001, 90.0}, yl[2][2] = {{10.0, 65.0}, {-MaxMP, MaxMP}}; + + if (!btn[i]->Down) continue; + GraphE[i]->XLPos = i == j ? 1 : 0; + GraphE[i]->YLPos = 1; + GraphE[i]->SetLim(xl, yl[i]); + GraphE[i]->SetTick(0.0, 0.0); + GraphE[i]->DrawAxis(1, 1); + GraphE[i]->GetPos(p1, p2); + p1.x = Disp->Font->Size; + p1.y = (p1.y + p2.y) / 2; + GraphE[i]->DrawText(p1, label[i], CColor[2], 0, 0, 90); + if (i == j) { + UTF8String ustr = "Elevation (" CHARDEG ")"; + p2.x -= 8; + p2.y -= 6; + GraphE[i]->DrawText(p2, ustr, CColor[2], 2, 1, 0); } - if (0<=ObsIndex&&ObsIndexDown) { - time=Obs.data[IndexObs[ObsIndex]].time; + } + if (0 <= ObsIndex && ObsIndex < NObs && BtnShowTrack->Down) { + time = Obs.data[IndexObs[ObsIndex]].time; + } + if (NObs > 0 && BtnSol1->Down) { + TColor *col[2], colp[2][MAXSAT]; + AnsiString text = ObsType2->Text; + const char *obstype = text.c_str(); + double *x[2], *y[2], xp[2][MAXSAT], yp[2][MAXSAT]; + int n[2], np[2] = {0}; + + for (int i = 0; i < 2; i++) { + x[i] = new double[NObs], y[i] = new double[NObs]; + col[i] = new TColor[NObs]; } - if (NObs>0&&BtnSol1->Down) { - TColor *col[2],colp[2][MAXSAT]; - AnsiString text=ObsType2->Text; - const char *obstype=text.c_str(); - double *x[2],*y[2],xp[2][MAXSAT],yp[2][MAXSAT]; - int n[2],np[2]={0}; + for (int sat = 1; sat <= MAXSAT; sat++) { + if (SatMask[sat - 1] || !SatSel[sat - 1]) continue; + n[0] = n[1] = 0; - for (int i=0;i<2;i++) { - x[i]=new double[NObs], - y[i]=new double[NObs]; - col[i]=new TColor[NObs]; - } - for (int sat=1;sat<=MAXSAT;sat++) { - if (SatMask[sat-1]||!SatSel[sat-1]) continue; - n[0]=n[1]=0; - - for (int j=0;jsat!=sat||El[j]<=0.0) continue; - - if (sscanf(obstype,"L%1d",&freq)==1) { - k=freq>2?freq-3:freq-1; /* L1,L2,L5,L6 ... */ - } - else { - for (k=0;kcode[k]),obstype)) break; - } - if (k>=NFREQ+NEXOBS) continue; - } - if (obs->SNR[k]<=0.0) continue; - - x[0][n[0]]=x[1][n[1]]=El[j]*R2D; - y[0][n[0]]=obs->SNR[k]; - y[1][n[1]]=!Mp[k]?0.0:Mp[k][j]; - - col[0][n[0]]=col[1][n[1]]= - El[j]>0.0&&El[j]0.0) { - if (timediff(time,Obs.data[j].time)==0.0) { - xp[0][np[0]]=x[0][n[0]]; - yp[0][np[0]]=y[0][n[0]]; - colp[0][np[0]]=ObsColor(Obs.data+j,Az[j],El[j]); - if (np[0]=ElMask*D2R) { - ave+=y[1][n[1]]; - rms+=SQR(y[1][n[1]]); - nrms++; - } - if (timediff(time,Obs.data[j].time)==0.0) { - xp[1][np[1]]=x[1][n[1]]; - yp[1][np[1]]=y[1][n[1]]; - colp[1][np[1]]=ObsColor(Obs.data+j,Az[j],El[j]); - if (np[1]Down) continue; - DrawPolyS(GraphE[i],x[i],y[i],n[i],CColor[3],0); - } - } - if (level&&PlotStyle<2) { - for (int i=0;i<2;i++) { - if (!btn[i]->Down) continue; - for (int j=0;jDrawMark(x[i][j],y[i][j],0,col[i][j],MarkSize,0); - } - } - } + for (int j = 0; j < Obs.n; j++) { + obsd_t *obs = Obs.data + j; + int k, freq; + + if (obs->sat != sat || El[j] <= 0.0) continue; + + if (sscanf(obstype, "L%1d", &freq) == 1) { + k = freq > 2 ? freq - 3 : freq - 1; /* L1,L2,L5,L6 ... */ + } else { + for (k = 0; k < NFREQ + NEXOBS; k++) { + if (!strcmp(code2obs(obs->code[k]), obstype)) break; + } + if (k >= NFREQ + NEXOBS) continue; + } + if (obs->SNR[k] <= 0.0) continue; + + x[0][n[0]] = x[1][n[1]] = El[j] * R2D; + y[0][n[0]] = obs->SNR[k]; + y[1][n[1]] = !Mp[k] ? 0.0 : Mp[k][j]; + + col[0][n[0]] = col[1][n[1]] = + El[j] > 0.0 && El[j] < ElMask * D2R ? MColor[0][0] : MColor[0][4]; + + if (y[0][n[0]] > 0.0) { + if (timediff(time, Obs.data[j].time) == 0.0) { + xp[0][np[0]] = x[0][n[0]]; + yp[0][np[0]] = y[0][n[0]]; + colp[0][np[0]] = ObsColor(Obs.data + j, Az[j], El[j]); + if (np[0] < MAXSAT && colp[0][np[0]] != clBlack) np[0]++; + } + if (n[0] < NObs) n[0]++; + } + if (y[1][n[1]] != 0.0) { + if (El[j] >= ElMask * D2R) { + ave += y[1][n[1]]; + rms += SQR(y[1][n[1]]); + nrms++; + } + if (timediff(time, Obs.data[j].time) == 0.0) { + xp[1][np[1]] = x[1][n[1]]; + yp[1][np[1]] = y[1][n[1]]; + colp[1][np[1]] = ObsColor(Obs.data + j, Az[j], El[j]); + if (np[1] < MAXSAT && colp[1][np[1]] != clBlack) np[1]++; + } + if (n[1] < NObs) n[1]++; } - for (int i=0;i<2;i++) { - delete [] x[i]; - delete [] y[i]; - delete [] col[i]; + } + if (!level || !(PlotStyle % 2)) { + for (int i = 0; i < 2; i++) { + if (!btn[i]->Down) continue; + DrawPolyS(GraphE[i], x[i], y[i], n[i], CColor[3], 0); } - if (BtnShowTrack->Down&&0<=ObsIndex&&ObsIndexDown) { - for (int i=0;i<2;i++) { - if (!btn[i]->Down) continue; - for (int j=0;jDrawMark(xp[i][j],yp[i][j],0,CColor[0],MarkSize*2+8,0); - GraphE[i]->DrawMark(xp[i][j],yp[i][j],1,CColor[2],MarkSize*2+6,0); - GraphE[i]->DrawMark(xp[i][j],yp[i][j],0,colp[i][j],MarkSize*2+2,0); - } - } + } + if (level && PlotStyle < 2) { + for (int i = 0; i < 2; i++) { + if (!btn[i]->Down) continue; + for (int j = 0; j < n[i]; j++) { + GraphE[i]->DrawMark(x[i][j], y[i][j], 0, col[i][j], MarkSize, 0); + } } + } } - if (ShowStats) { - int i; - for (i=0;i<2;i++) if (btn[i]->Down) break; - if (i<2) { - TPoint p1,p2; - int hh=(int)(Disp->Font->Size*1.5); - - GraphE[i]->GetPos(p1,p2); - p1.x+=8; p1.y+=6; - s.sprintf("MARKER: %s %s %s",Sta.name,Sta.markerno,Sta.markertype); - DrawLabel(GraphE[i],p1,s,1,2); p1.y+=hh; - s.sprintf("REC: %s %s %s",Sta.rectype,Sta.recver,Sta.recsno); - DrawLabel(GraphE[i],p1,s,1,2); p1.y+=hh; - s.sprintf("ANT: %s %s",Sta.antdes,Sta.antsno); - DrawLabel(GraphE[i],p1,s,1,2); p1.y+=hh; - } - if (btn[1]->Down&&nrms>0&&!BtnShowTrack->Down) { - TPoint p1,p2; - ave=ave/nrms; - rms=SQRT(rms/nrms); - GraphE[1]->GetPos(p1,p2); - p1.x=p2.x-8; p1.y+=6; - DrawLabel(GraphE[1],p1,s.sprintf("AVE=%.4fm RMS=%.4fm",ave,rms),2,2); + for (int i = 0; i < 2; i++) { + delete[] x[i]; + delete[] y[i]; + delete[] col[i]; + } + if (BtnShowTrack->Down && 0 <= ObsIndex && ObsIndex < NObs && BtnSol1->Down) { + for (int i = 0; i < 2; i++) { + if (!btn[i]->Down) continue; + for (int j = 0; j < np[i]; j++) { + GraphE[i]->DrawMark(xp[i][j], yp[i][j], 0, CColor[0], MarkSize * 2 + 8, 0); + GraphE[i]->DrawMark(xp[i][j], yp[i][j], 1, CColor[2], MarkSize * 2 + 6, 0); + GraphE[i]->DrawMark(xp[i][j], yp[i][j], 0, colp[i][j], MarkSize * 2 + 2, 0); } + } + } + } + if (ShowStats) { + int i; + for (i = 0; i < 2; i++) + if (btn[i]->Down) break; + if (i < 2) { + TPoint p1, p2; + int hh = (int)(Disp->Font->Size * 1.5); + + GraphE[i]->GetPos(p1, p2); + p1.x += 8; + p1.y += 6; + s.sprintf("MARKER: %s %s %s", Sta.name, Sta.markerno, Sta.markertype); + DrawLabel(GraphE[i], p1, s, 1, 2); + p1.y += hh; + s.sprintf("REC: %s %s %s", Sta.rectype, Sta.recver, Sta.recsno); + DrawLabel(GraphE[i], p1, s, 1, 2); + p1.y += hh; + s.sprintf("ANT: %s %s", Sta.antdes, Sta.antsno); + DrawLabel(GraphE[i], p1, s, 1, 2); + p1.y += hh; + } + if (btn[1]->Down && nrms > 0 && !BtnShowTrack->Down) { + TPoint p1, p2; + ave = ave / nrms; + rms = SQRT(rms / nrms); + GraphE[1]->GetPos(p1, p2); + p1.x = p2.x - 8; + p1.y += 6; + DrawLabel(GraphE[1], p1, s.sprintf("AVE=%.4fm RMS=%.4fm", ave, rms), 2, 2); } + } } // draw MP-skyplot ---------------------------------------------------------- -void __fastcall TPlot::DrawMpS(int level) -{ - AnsiString text=ObsType2->Text; - const char *obstype=text.c_str(); - double r,xl[2],yl[2],xs,ys; - - trace(3,"DrawSnrS: level=%d\n",level); - - GraphS->GetLim(xl,yl); - r=(xl[1]-xl[0]Down) { - DrawSkyImage(level); - } - if (BtnShowSkyplot->Down) { - GraphS->DrawSkyPlot(0.0,0.0,CColor[1],CColor[2],CColor[0],r*2.0); - } - if (!BtnSol1->Down||NObs<=0||SimObs) return; - - GraphS->GetScale(xs,ys); - - for (int sat=1;sat<=MAXSAT;sat++) { - double p[MAXSAT][2]={{0}}; - - if (SatMask[sat-1]||!SatSel[sat-1]) continue; - - for (int i=0;isat!=sat||El[i]<=0.0) continue; - - if (sscanf(obstype,"L%1d",&freq)==1) { - j=freq>2?freq-3:freq-1; /* L1,L2,L5,L6 ... */ - } - else { - for (j=0;jcode[j]),obstype)) break; - } - if (j>=NFREQ+NEXOBS) continue; - } - double x=r*sin(Az[i])*(1.0-2.0*El[i]/PI); - double y=r*cos(Az[i])*(1.0-2.0*El[i]/PI); - double xp=p[sat-1][0]; - double yp=p[sat-1][1]; - TColor col=MpColor(!Mp[j]?0.0:Mp[j][i]); - - if ((x-xp)*(x-xp)+(y-yp)*(y-yp)>=xs*xs) { - int siz=PlotStyle<2?MarkSize:1; - GraphS->DrawMark(x,y,0,col,siz,0); - GraphS->DrawMark(x,y,0,PlotStyle<2?col:CColor[3],siz,0); - p[sat-1][0]=x; - p[sat-1][1]=y; - } +void __fastcall TPlot::DrawMpS(int level) { + AnsiString text = ObsType2->Text; + const char *obstype = text.c_str(); + double r, xl[2], yl[2], xs, ys; + + trace(3, "DrawSnrS: level=%d\n", level); + + GraphS->GetLim(xl, yl); + r = (xl[1] - xl[0] < yl[1] - yl[0] ? xl[1] - xl[0] : yl[1] - yl[0]) * 0.45; + + if (BtnShowImg->Down) { + DrawSkyImage(level); + } + if (BtnShowSkyplot->Down) { + GraphS->DrawSkyPlot(0.0, 0.0, CColor[1], CColor[2], CColor[0], r * 2.0); + } + if (!BtnSol1->Down || NObs <= 0 || SimObs) return; + + GraphS->GetScale(xs, ys); + + for (int sat = 1; sat <= MAXSAT; sat++) { + double p[MAXSAT][2] = {{0}}; + + if (SatMask[sat - 1] || !SatSel[sat - 1]) continue; + + for (int i = 0; i < Obs.n; i++) { + obsd_t *obs = Obs.data + i; + int j, freq; + + if (obs->sat != sat || El[i] <= 0.0) continue; + + if (sscanf(obstype, "L%1d", &freq) == 1) { + j = freq > 2 ? freq - 3 : freq - 1; /* L1,L2,L5,L6 ... */ + } else { + for (j = 0; j < NFREQ + NEXOBS; j++) { + if (!strcmp(code2obs(obs->code[j]), obstype)) break; } + if (j >= NFREQ + NEXOBS) continue; + } + double x = r * sin(Az[i]) * (1.0 - 2.0 * El[i] / PI); + double y = r * cos(Az[i]) * (1.0 - 2.0 * El[i] / PI); + double xp = p[sat - 1][0]; + double yp = p[sat - 1][1]; + TColor col = MpColor(!Mp[j] ? 0.0 : Mp[j][i]); + + if ((x - xp) * (x - xp) + (y - yp) * (y - yp) >= xs * xs) { + int siz = PlotStyle < 2 ? MarkSize : 1; + GraphS->DrawMark(x, y, 0, col, siz, 0); + GraphS->DrawMark(x, y, 0, PlotStyle < 2 ? col : CColor[3], siz, 0); + p[sat - 1][0] = x; + p[sat - 1][1] = y; + } } - if (BtnShowTrack->Down&&0<=ObsIndex&&ObsIndexsat-1]||!SatSel[obs->sat-1]||El[i]<=0.0) continue; - - if (sscanf(obstype,"L%1d",&freq)==1) { - j=freq>2?freq-3:freq-1; /* L1,L2,L5,L6 ... */ - } - else { - for (j=0;jcode[j]),obstype)) break; - } - if (j>=NFREQ+NEXOBS) continue; - } - TColor col=MpColor(!Mp[j]?0.0:Mp[j][i]); - double x=r*sin(Az[i])*(1.0-2.0*El[i]/PI); - double y=r*cos(Az[i])*(1.0-2.0*El[i]/PI); - UTF8String ustr; - char id[8]; - satno2id(obs->sat,id); - ustr=id; - GraphS->DrawMark(x,y,0,col,Disp->Font->Size*2+5,0); - GraphS->DrawMark(x,y,1,CColor[2],Disp->Font->Size*2+5,0); - GraphS->DrawText(x,y,ustr,CColor[0],0,0,0); + } + if (BtnShowTrack->Down && 0 <= ObsIndex && ObsIndex < NObs) { + for (int i = IndexObs[ObsIndex]; i < Obs.n && i < IndexObs[ObsIndex + 1]; i++) { + obsd_t *obs = Obs.data + i; + int j, freq; + + if (SatMask[obs->sat - 1] || !SatSel[obs->sat - 1] || El[i] <= 0.0) continue; + + if (sscanf(obstype, "L%1d", &freq) == 1) { + j = freq > 2 ? freq - 3 : freq - 1; /* L1,L2,L5,L6 ... */ + } else { + for (j = 0; j < NFREQ + NEXOBS; j++) { + if (!strcmp(code2obs(obs->code[j]), obstype)) break; } + if (j >= NFREQ + NEXOBS) continue; + } + TColor col = MpColor(!Mp[j] ? 0.0 : Mp[j][i]); + double x = r * sin(Az[i]) * (1.0 - 2.0 * El[i] / PI); + double y = r * cos(Az[i]) * (1.0 - 2.0 * El[i] / PI); + UTF8String ustr; + char id[8]; + satno2id(obs->sat, id); + ustr = id; + GraphS->DrawMark(x, y, 0, col, Disp->Font->Size * 2 + 5, 0); + GraphS->DrawMark(x, y, 1, CColor[2], Disp->Font->Size * 2 + 5, 0); + GraphS->DrawText(x, y, ustr, CColor[0], 0, 0, 0); } + } } // draw residuals and SNR/elevation plot ------------------------------------ -void __fastcall TPlot::DrawRes(int level) -{ - UTF8String label[]={ - "Pseudorange Residuals (m)", "Carrier-Phase Residuals (m)", - "Elevation Angle (" CHARDEG ") / SNR (dBHz)" - }; - TSpeedButton *btn[]={BtnOn1,BtnOn2,BtnOn3}; - int sel=!BtnSol1->Down&&BtnSol2->Down?1:0,ind=SolIndex[sel]; - int frq=FrqType->ItemIndex+1,n=SolStat[sel].n; - - trace(3,"DrawRes: level=%d\n",level); - - if (0<=ind&&indDown&&BtnFixHoriz->Down) { - gtime_t t=SolData[sel].data[ind].time; - - for (int i=0;i<3;i++) { - double off,xc,yc,xl[2],yl[2]; - - if (BtnFixHoriz->Down) { - GraphG[i]->GetLim(xl,yl); - off=Xcent*(xl[1]-xl[0])/2.0; - GraphG[i]->GetCent(xc,yc); - GraphG[i]->GetCent(xc,yc); - GraphG[i]->SetCent(TimePos(t)-off,yc); - } - else { - GraphG[i]->GetRight(xc,yc); - GraphG[i]->SetRight(TimePos(t),yc); - } - } +void __fastcall TPlot::DrawRes(int level) { + UTF8String label[] = {"Pseudorange Residuals (m)", "Carrier-Phase Residuals (m)", + "Elevation Angle (" CHARDEG ") / SNR (dBHz)"}; + TSpeedButton *btn[] = {BtnOn1, BtnOn2, BtnOn3}; + int sel = !BtnSol1->Down && BtnSol2->Down ? 1 : 0, ind = SolIndex[sel]; + int frq = FrqType->ItemIndex + 1, n = SolStat[sel].n; + + trace(3, "DrawRes: level=%d\n", level); + + if (0 <= ind && ind < SolData[sel].n && BtnShowTrack->Down && BtnFixHoriz->Down) { + gtime_t t = SolData[sel].data[ind].time; + + for (int i = 0; i < 3; i++) { + double off, xc, yc, xl[2], yl[2]; + + if (BtnFixHoriz->Down) { + GraphG[i]->GetLim(xl, yl); + off = Xcent * (xl[1] - xl[0]) / 2.0; + GraphG[i]->GetCent(xc, yc); + GraphG[i]->GetCent(xc, yc); + GraphG[i]->SetCent(TimePos(t) - off, yc); + } else { + GraphG[i]->GetRight(xc, yc); + GraphG[i]->SetRight(TimePos(t), yc); + } + } + } + int j = -1; + for (int i = 0; i < 3; i++) + if (btn[i]->Down) j = i; + for (int i = 0; i < 3; i++) { + if (!btn[i]->Down) continue; + GraphG[i]->XLPos = TimeLabel ? (i == j ? 6 : 5) : (i == j ? 1 : 0); + GraphG[i]->Week = Week; + GraphG[i]->DrawAxis(ShowLabel, ShowLabel); + } + if (n > 0 && ((sel == 0 && BtnSol1->Down) || (sel == 1 && BtnSol2->Down))) { + TColor *col[4]; + double *x[4], *y[4], res[2], sum[2] = {0}, sum2[2] = {0}; + int ns[2] = {0}; + + for (int i = 0; i < 4; i++) { + x[i] = new double[n], y[i] = new double[n]; + col[i] = new TColor[n]; } - int j=-1; - for (int i=0;i<3;i++) if (btn[i]->Down) j=i; - for (int i=0;i<3;i++) { + for (int sat = 1; sat <= MAXSAT; sat++) { + if (SatMask[sat - 1] || !SatSel[sat - 1]) continue; + + int m[4] = {0}; + + for (int i = 0; i < n; i++) { + solstat_t *p = SolStat[sel].data + i; + int q; + + if (p->sat != sat || p->frq != frq) continue; + + x[0][m[0]] = x[1][m[1]] = x[2][m[2]] = x[3][m[3]] = TimePos(p->time); + y[0][m[0]] = p->resp; + y[1][m[1]] = p->resc; + y[2][m[2]] = p->el * R2D; + y[3][m[3]] = p->snr; + if (!(p->flag >> 5)) + q = 0; // invalid + else if ((p->flag & 7) <= 1) + q = 2; // float + else if ((p->flag & 7) <= 3) + q = 1; // fixed + else + q = 6; // ppp + + col[0][m[0]] = MColor[0][q]; + col[1][m[1]] = ((p->flag >> 3) & 1) ? clRed : MColor[0][q]; + col[2][m[2]] = MColor[0][1]; + col[3][m[3]] = MColor[0][4]; + + if (p->resp != 0.0) { + sum[0] += p->resp; + sum2[0] += p->resp * p->resp; + ns[0]++; + } + if (p->resc != 0.0) { + sum[1] += p->resc; + sum2[1] += p->resc * p->resc; + ns[1]++; + } + m[0]++; + m[1]++; + m[2]++; + m[3]++; + } + for (int i = 0; i < 3; i++) { if (!btn[i]->Down) continue; - GraphG[i]->XLPos=TimeLabel?(i==j?6:5):(i==j?1:0); - GraphG[i]->Week=Week; - GraphG[i]->DrawAxis(ShowLabel,ShowLabel); - } - if (n>0&&((sel==0&&BtnSol1->Down)||(sel==1&&BtnSol2->Down))) { - TColor *col[4]; - double *x[4],*y[4],res[2],sum[2]={0},sum2[2]={0}; - int ns[2]={0}; - - for (int i=0;i<4;i++) { - x[i]=new double[n], - y[i]=new double[n]; - col[i]=new TColor[n]; - } - for (int sat=1;sat<=MAXSAT;sat++) { - if (SatMask[sat-1]||!SatSel[sat-1]) continue; - - int m[4]={0}; - - for (int i=0;isat!=sat||p->frq!=frq) continue; - - x[0][m[0]]=x[1][m[1]]=x[2][m[2]]=x[3][m[3]]=TimePos(p->time); - y[0][m[0]]=p->resp; - y[1][m[1]]=p->resc; - y[2][m[2]]=p->el*R2D; - y[3][m[3]]=p->snr; - if (!(p->flag>>5)) q=0; // invalid - else if ((p->flag&7)<=1) q=2; // float - else if ((p->flag&7)<=3) q=1; // fixed - else q=6; // ppp - - col[0][m[0]]=MColor[0][q]; - col[1][m[1]]=((p->flag>>3)&1)?clRed:MColor[0][q]; - col[2][m[2]]=MColor[0][1]; - col[3][m[3]]=MColor[0][4]; - - if (p->resp!=0.0) { - sum [0]+=p->resp; - sum2[0]+=p->resp*p->resp; - ns[0]++; - } - if (p->resc!=0.0) { - sum [1]+=p->resc; - sum2[1]+=p->resc*p->resc; - ns[1]++; - } - m[0]++; m[1]++; m[2]++; m[3]++; - } - for (int i=0;i<3;i++) { - if (!btn[i]->Down) continue; - if (!level||!(PlotStyle%2)) { - DrawPolyS(GraphG[i],x[i],y[i],m[i],CColor[3],0); - if (i==2) DrawPolyS(GraphG[i],x[3],y[3],m[3],CColor[3],0); - } - if (level&&PlotStyle<2) { - for (int j=0;jDrawMark(x[i][j],y[i][j],0,col[i][j],MarkSize,0); - } - if (i==2) { - for (int j=0;jDrawMark(x[3][j],y[3][j],0,col[3][j],MarkSize,0); - } - } - } - } - } - for (int i=0;i<4;i++) { - delete [] x[i]; - delete [] y[i]; - delete [] col[i]; - } - if (ShowStats) { - for (int i=0;i<2;i++) { - if (!btn[i]->Down) continue; - - AnsiString str; - TPoint p1,p2; - double ave,std,rms; - - ave=ns[i]<=0?0.0:sum[i]/ns[i]; - std=ns[i]<=1?0.0:SQRT((sum2[i]-2.0*sum[i]*ave+ns[i]*ave*ave)/(ns[i]-1)); - rms=ns[i]<=0?0.0:SQRT(sum2[i]/ns[i]); - GraphG[i]->GetPos(p1,p2); - p1.x=p2.x-5; - p1.y+=3; - str.sprintf("AVE=%.3fm STD=%.3fm RMS=%.3fm",ave,std,rms); - DrawLabel(GraphG[i],p1,str,2,2); - } - } - if (BtnShowTrack->Down&&0<=ind&&indDown||BtnSol2->Down)) { - for (int i=0,j=0;i<3;i++) { - if (!btn[i]->Down) continue; - - gtime_t t=SolData[sel].data[ind].time; - double xl[2],yl[2]; - - GraphG[i]->GetLim(xl,yl); - xl[0]=xl[1]=TimePos(t); - GraphG[i]->DrawPoly(xl,yl,2,ind==0?CColor[1]:CColor[2],0); - if (j++==0) { - GraphG[i]->DrawMark(xl[0],yl[1]-1E-6,0,CColor[2],5,0); - GraphG[i]->DrawMark(xl[0],yl[1]-1E-6,1,CColor[2],9,0); - } + if (!level || !(PlotStyle % 2)) { + DrawPolyS(GraphG[i], x[i], y[i], m[i], CColor[3], 0); + if (i == 2) DrawPolyS(GraphG[i], x[3], y[3], m[3], CColor[3], 0); + } + if (level && PlotStyle < 2) { + for (int j = 0; j < m[i]; j++) { + GraphG[i]->DrawMark(x[i][j], y[i][j], 0, col[i][j], MarkSize, 0); + } + if (i == 2) { + for (int j = 0; j < m[3]; j++) { + GraphG[i]->DrawMark(x[3][j], y[3][j], 0, col[3][j], MarkSize, 0); } + } } + } } - for (int i=0;i<3;i++) { + for (int i = 0; i < 4; i++) { + delete[] x[i]; + delete[] y[i]; + delete[] col[i]; + } + if (ShowStats) { + for (int i = 0; i < 2; i++) { if (!btn[i]->Down) continue; - TPoint p1,p2; - - GraphG[i]->GetPos(p1,p2); - p1.x+=5; p1.y+=3; - DrawLabel(GraphG[i],p1,label[i],1,2); + + AnsiString str; + TPoint p1, p2; + double ave, std, rms; + + ave = ns[i] <= 0 ? 0.0 : sum[i] / ns[i]; + std = ns[i] <= 1 ? 0.0 + : SQRT((sum2[i] - 2.0 * sum[i] * ave + ns[i] * ave * ave) / (ns[i] - 1)); + rms = ns[i] <= 0 ? 0.0 : SQRT(sum2[i] / ns[i]); + GraphG[i]->GetPos(p1, p2); + p1.x = p2.x - 5; + p1.y += 3; + str.sprintf("AVE=%.3fm STD=%.3fm RMS=%.3fm", ave, std, rms); + DrawLabel(GraphG[i], p1, str, 2, 2); + } } -} -// draw residuals - elevation plot ------------------------------------------ -void __fastcall TPlot::DrawResE(int level) -{ - TSpeedButton *btn[]={BtnOn1,BtnOn2,BtnOn3}; - UTF8String label[]={"Pseudorange Residuals (m)","Carrier-Phase Residuals (m)"}; - int j,sel=!BtnSol1->Down&&BtnSol2->Down?1:0,ind=SolIndex[sel]; - int frq=FrqType->ItemIndex+1,n=SolStat[sel].n; - - trace(3,"DrawResE: level=%d\n",level); - - j=0; - for (int i=0;i<2;i++) if (btn[i]->Down) j=i; - for (int i=0;i<2;i++) { + if (BtnShowTrack->Down && 0 <= ind && ind < SolData[sel].n && + (BtnSol1->Down || BtnSol2->Down)) { + for (int i = 0, j = 0; i < 3; i++) { if (!btn[i]->Down) continue; - TPoint p1,p2; - double xl[2]={-0.001,90.0}; - double yl[2][2]={{-MaxMP,MaxMP},{-MaxMP/100.0,MaxMP/100.0}}; - - GraphE[i]->XLPos=i==j?1:0; - GraphE[i]->YLPos=1; - GraphE[i]->SetLim(xl,yl[i]); - GraphE[i]->SetTick(0.0,0.0); - GraphE[i]->DrawAxis(1,1); - GraphE[i]->GetPos(p1,p2); - p1.x=Disp->Font->Size; - p1.y=(p1.y+p2.y)/2; - GraphE[i]->DrawText(p1,label[i],CColor[2],0,0,90); - if (i==j) { - UTF8String ustr="Elevation (" CHARDEG ")"; - p2.x-=8; p2.y-=6; - GraphE[i]->DrawText(p2,ustr,CColor[2],2,1,0); - } - } - if (n>0&&((sel==0&&BtnSol1->Down)||(sel==1&&BtnSol2->Down))) { - TColor *col[2]; - double *x[2],*y[2],sum[2]={0},sum2[2]={0}; - int ns[2]={0}; - - for (int i=0;i<2;i++) { - x [i]=new double[n], - y [i]=new double[n]; - col[i]=new TColor[n]; - } - for (int sat=1;sat<=MAXSAT;sat++) { - if (SatMask[sat-1]||!SatSel[sat-1]) continue; - int q,m[2]={0}; - - for (int i=0;isat!=sat||p->frq!=frq) continue; - - x[0][m[0]]=x[1][m[1]]=p->el*R2D; - y[0][m[0]]=p->resp; - y[1][m[1]]=p->resc; - if (!(p->flag>>5)) q=0; // invalid - else if ((p->flag&7)<=1) q=2; // float - else if ((p->flag&7)<=3) q=1; // fixed - else q=6; // ppp - - col[0][m[0]]=MColor[0][q]; - col[1][m[1]]=((p->flag>>3)&1)?clRed:MColor[0][q]; - - if (p->resp!=0.0) { - sum [0]+=p->resp; - sum2[0]+=p->resp*p->resp; - ns[0]++; - } - if (p->resc!=0.0) { - sum [1]+=p->resc; - sum2[1]+=p->resc*p->resc; - ns[1]++; - } - m[0]++; m[1]++; - } - for (int i=0;i<2;i++) { - if (!btn[i]->Down) continue; - if (!level||!(PlotStyle%2)) { - DrawPolyS(GraphE[i],x[i],y[i],m[i],CColor[3],0); - } - if (level&&PlotStyle<2) { - for (int j=0;jDrawMark(x[i][j],y[i][j],0,col[i][j],MarkSize,0); - } - } - } + gtime_t t = SolData[sel].data[ind].time; + double xl[2], yl[2]; + + GraphG[i]->GetLim(xl, yl); + xl[0] = xl[1] = TimePos(t); + GraphG[i]->DrawPoly(xl, yl, 2, ind == 0 ? CColor[1] : CColor[2], 0); + if (j++ == 0) { + GraphG[i]->DrawMark(xl[0], yl[1] - 1E-6, 0, CColor[2], 5, 0); + GraphG[i]->DrawMark(xl[0], yl[1] - 1E-6, 1, CColor[2], 9, 0); } - for (int i=0;i<2;i++) { - delete [] x[i]; - delete [] y[i]; - delete [] col[i]; + } + } + } + for (int i = 0; i < 3; i++) { + if (!btn[i]->Down) continue; + TPoint p1, p2; + + GraphG[i]->GetPos(p1, p2); + p1.x += 5; + p1.y += 3; + DrawLabel(GraphG[i], p1, label[i], 1, 2); + } +} +// draw residuals - elevation plot ------------------------------------------ +void __fastcall TPlot::DrawResE(int level) { + TSpeedButton *btn[] = {BtnOn1, BtnOn2, BtnOn3}; + UTF8String label[] = {"Pseudorange Residuals (m)", "Carrier-Phase Residuals (m)"}; + int j, sel = !BtnSol1->Down && BtnSol2->Down ? 1 : 0, ind = SolIndex[sel]; + int frq = FrqType->ItemIndex + 1, n = SolStat[sel].n; + + trace(3, "DrawResE: level=%d\n", level); + + j = 0; + for (int i = 0; i < 2; i++) + if (btn[i]->Down) j = i; + for (int i = 0; i < 2; i++) { + if (!btn[i]->Down) continue; + + TPoint p1, p2; + double xl[2] = {-0.001, 90.0}; + double yl[2][2] = {{-MaxMP, MaxMP}, {-MaxMP / 100.0, MaxMP / 100.0}}; + + GraphE[i]->XLPos = i == j ? 1 : 0; + GraphE[i]->YLPos = 1; + GraphE[i]->SetLim(xl, yl[i]); + GraphE[i]->SetTick(0.0, 0.0); + GraphE[i]->DrawAxis(1, 1); + GraphE[i]->GetPos(p1, p2); + p1.x = Disp->Font->Size; + p1.y = (p1.y + p2.y) / 2; + GraphE[i]->DrawText(p1, label[i], CColor[2], 0, 0, 90); + if (i == j) { + UTF8String ustr = "Elevation (" CHARDEG ")"; + p2.x -= 8; + p2.y -= 6; + GraphE[i]->DrawText(p2, ustr, CColor[2], 2, 1, 0); + } + } + if (n > 0 && ((sel == 0 && BtnSol1->Down) || (sel == 1 && BtnSol2->Down))) { + TColor *col[2]; + double *x[2], *y[2], sum[2] = {0}, sum2[2] = {0}; + int ns[2] = {0}; + + for (int i = 0; i < 2; i++) { + x[i] = new double[n], y[i] = new double[n]; + col[i] = new TColor[n]; + } + for (int sat = 1; sat <= MAXSAT; sat++) { + if (SatMask[sat - 1] || !SatSel[sat - 1]) continue; + int q, m[2] = {0}; + + for (int i = 0; i < n; i++) { + solstat_t *p = SolStat[sel].data + i; + if (p->sat != sat || p->frq != frq) continue; + + x[0][m[0]] = x[1][m[1]] = p->el * R2D; + y[0][m[0]] = p->resp; + y[1][m[1]] = p->resc; + if (!(p->flag >> 5)) + q = 0; // invalid + else if ((p->flag & 7) <= 1) + q = 2; // float + else if ((p->flag & 7) <= 3) + q = 1; // fixed + else + q = 6; // ppp + + col[0][m[0]] = MColor[0][q]; + col[1][m[1]] = ((p->flag >> 3) & 1) ? clRed : MColor[0][q]; + + if (p->resp != 0.0) { + sum[0] += p->resp; + sum2[0] += p->resp * p->resp; + ns[0]++; + } + if (p->resc != 0.0) { + sum[1] += p->resc; + sum2[1] += p->resc * p->resc; + ns[1]++; + } + m[0]++; + m[1]++; + } + for (int i = 0; i < 2; i++) { + if (!btn[i]->Down) continue; + if (!level || !(PlotStyle % 2)) { + DrawPolyS(GraphE[i], x[i], y[i], m[i], CColor[3], 0); } - if (ShowStats) { - for (int i=0;i<2;i++) { - if (!btn[i]->Down) continue; - - AnsiString str; - TPoint p1,p2; - double ave,std,rms; - - ave=ns[i]<=0?0.0:sum[i]/ns[i]; - std=ns[i]<=1?0.0:SQRT((sum2[i]-2.0*sum[i]*ave+ns[i]*ave*ave)/(ns[i]-1)); - rms=ns[i]<=0?0.0:SQRT(sum2[i]/ns[i]); - GraphE[i]->GetPos(p1,p2); - p1.x=p2.x-5; - p1.y+=3; - str.sprintf("AVE=%.3fm STD=%.3fm RMS=%.3fm",ave,std,rms); - DrawLabel(GraphG[i],p1,str,2,2); - } + if (level && PlotStyle < 2) { + for (int j = 0; j < m[i]; j++) { + GraphE[i]->DrawMark(x[i][j], y[i][j], 0, col[i][j], MarkSize, 0); + } } + } + } + for (int i = 0; i < 2; i++) { + delete[] x[i]; + delete[] y[i]; + delete[] col[i]; + } + if (ShowStats) { + for (int i = 0; i < 2; i++) { + if (!btn[i]->Down) continue; + + AnsiString str; + TPoint p1, p2; + double ave, std, rms; + + ave = ns[i] <= 0 ? 0.0 : sum[i] / ns[i]; + std = ns[i] <= 1 ? 0.0 + : SQRT((sum2[i] - 2.0 * sum[i] * ave + ns[i] * ave * ave) / (ns[i] - 1)); + rms = ns[i] <= 0 ? 0.0 : SQRT(sum2[i] / ns[i]); + GraphE[i]->GetPos(p1, p2); + p1.x = p2.x - 5; + p1.y += 3; + str.sprintf("AVE=%.3fm STD=%.3fm RMS=%.3fm", ave, std, rms); + DrawLabel(GraphG[i], p1, str, 2, 2); + } } + } } // draw polyline without time-gaps ------------------------------------------ -void __fastcall TPlot::DrawPolyS(TGraph *graph, double *x, double *y, int n, - TColor color, int style) -{ - int i,j; - - for (i=0;iTBRK) break; - graph->DrawPoly(x+i,y+i,j-i,color,style); - } +void __fastcall TPlot::DrawPolyS(TGraph *graph, double *x, double *y, int n, TColor color, + int style) { + int i, j; + + for (i = 0; i < n; i = j) { + for (j = i + 1; j < n; j++) + if (fabs(x[j] - x[j - 1]) > TBRK) break; + graph->DrawPoly(x + i, y + i, j - i, color, style); + } } // draw label with hemming -------------------------------------------------- -void __fastcall TPlot::DrawLabel(TGraph *g, TPoint p, UTF8String label, int ha, - int va) -{ - g->DrawText(p,label,CColor[2],CColor[0],ha,va,0); +void __fastcall TPlot::DrawLabel(TGraph *g, TPoint p, UTF8String label, int ha, int va) { + g->DrawText(p, label, CColor[2], CColor[0], ha, va, 0); } // draw mark with hemming --------------------------------------------------- -void __fastcall TPlot::DrawMark(TGraph *g, TPoint p, int mark, TColor color, - int size, int rot) -{ - g->DrawMark(p,mark,color,CColor[0],size,rot); +void __fastcall TPlot::DrawMark(TGraph *g, TPoint p, int mark, TColor color, int size, int rot) { + g->DrawMark(p, mark, color, CColor[0], size, rot); } // refresh map view --------------------------------------------------------- -void __fastcall TPlot::Refresh_MapView(void) -{ - sol_t *sol; - double pos[3]={0}; - - if (BtnShowTrack->Down) { - - if (BtnSol2->Down&&SolData[1].n>0&& - (sol=getsol(SolData+1,SolIndex[1]))) { - ecef2pos(sol->rr,pos); - MapView->SetMark(2,pos[0]*R2D,pos[1]*R2D); - MapView->ShowMark(2); - } - else { - MapView->HideMark(2); - } - if (BtnSol1->Down&&SolData[0].n>0&& - (sol=getsol(SolData,SolIndex[0]))) { - ecef2pos(sol->rr,pos); - MapView->SetMark(1,pos[0]*R2D,pos[1]*R2D); - MapView->ShowMark(1); - } - else { - MapView->HideMark(1); - } - } - else { - MapView->HideMark(1); - MapView->HideMark(2); +void __fastcall TPlot::Refresh_MapView(void) { + sol_t *sol; + double pos[3] = {0}; + + if (BtnShowTrack->Down) { + if (BtnSol2->Down && SolData[1].n > 0 && (sol = getsol(SolData + 1, SolIndex[1]))) { + ecef2pos(sol->rr, pos); + MapView->SetMark(2, pos[0] * R2D, pos[1] * R2D); + MapView->ShowMark(2); + } else { + MapView->HideMark(2); + } + if (BtnSol1->Down && SolData[0].n > 0 && (sol = getsol(SolData, SolIndex[0]))) { + ecef2pos(sol->rr, pos); + MapView->SetMark(1, pos[0] * R2D, pos[1] * R2D); + MapView->ShowMark(1); + } else { + MapView->HideMark(1); } + } else { + MapView->HideMark(1); + MapView->HideMark(2); + } } diff --git a/app/winapp/rtkplot/plotinfo.cpp b/app/winapp/rtkplot/plotinfo.cpp index 54255fde0..1326d92c8 100644 --- a/app/winapp/rtkplot/plotinfo.cpp +++ b/app/winapp/rtkplot/plotinfo.cpp @@ -2,426 +2,431 @@ // plotinfo.c: rtkplot info functions //--------------------------------------------------------------------------- #include -#include "rtklib.h" + #include "plotmain.h" +#include "rtklib.h" -#define ATAN2(x,y) ((x)*(x)+(y)*(y)>1E-12?atan2(x,y):0.0) +#define ATAN2(x, y) ((x) * (x) + (y) * (y) > 1E-12 ? atan2(x, y) : 0.0) // update information on status-bar ----------------------------------------- -void __fastcall TPlot::UpdateInfo(void) -{ - int showobs=(PLOT_OBS<=PlotType&&PlotType<=PLOT_DOP)|| - PlotType==PLOT_SNR||PlotType==PLOT_SNRE||PlotType==PLOT_MPS; - - trace(3,"UpdateInfo:\n"); - - if (BtnShowTrack->Down) { - if (showobs) UpdateTimeObs(); else UpdateTimeSol(); - } - else { - if (showobs) UpdateInfoObs(); else UpdateInfoSol(); - } +void __fastcall TPlot::UpdateInfo(void) { + int showobs = (PLOT_OBS <= PlotType && PlotType <= PLOT_DOP) || PlotType == PLOT_SNR || + PlotType == PLOT_SNRE || PlotType == PLOT_MPS; + + trace(3, "UpdateInfo:\n"); + + if (BtnShowTrack->Down) { + if (showobs) + UpdateTimeObs(); + else + UpdateTimeSol(); + } else { + if (showobs) + UpdateInfoObs(); + else + UpdateInfoSol(); + } } // update time-information for observation-data plot ------------------------ -void __fastcall TPlot::UpdateTimeObs(void) -{ - UTF8String msgs1[]={" #FRQ=5 "," 4 "," 3 "," 2 "," 1 ","",""}; - UTF8String msgs2[]={" SNR=...45.","..40.","..35.","..30.","..25 ",""," <25 "}; - UTF8String msgs3[]={" SYS=GPS ","GLO ","GAL ","QZS ","BDS ","IRN ","SBS "}; - UTF8String msgs4[]={" MP=..0.6","..0.3","..0.0..","-0.3..","-0.6..","",""}; - UTF8String msg,msgs[8],s; - double azel[MAXOBS*2],dop[4]={0}; - int i,ns=0,no=0,ind=ObsIndex; - char tstr[48]; - - trace(3,"UpdateTimeObs\n"); - - if (BtnSol1->Down&&0<=ind&&indDown && 0 <= ind && ind < NObs) { + for (i = IndexObs[ind]; i < Obs.n && i < IndexObs[ind + 1]; i++, no++) { + if (SatMask[Obs.data[i].sat - 1] || !SatSel[Obs.data[i].sat - 1]) continue; + if (El[i] < ElMask * D2R) continue; + if (ElMaskP && El[i] < ElMaskData[(int)(Az[i] * R2D + 0.5)]) continue; + azel[ns * 2] = Az[i]; + azel[1 + ns * 2] = El[i]; + ns++; } - if (ns>=0) { - dops(ns,azel,ElMask*D2R,dop); - - TimeStr(Obs.data[IndexObs[ind]].time,3,1,tstr); - msg.sprintf("[1]%s : N=%d ",tstr,no); - - if (PlotType==PLOT_DOP) { - msgs[0].sprintf("NSAT=%d",ns); - msgs[1].sprintf(" GDOP=%.1f",dop[0]); - msgs[2].sprintf(" PDOP=%.1f",dop[1]); - msgs[3].sprintf(" HDOP=%.1f",dop[2]); - msgs[4].sprintf(" VDOP=%.1f",dop[3]); - } - else if (PlotType<=PLOT_SKY&&ObsType->ItemIndex==0) { - msg+=s.sprintf("NSAT=%d ",ns); - for (i=0;i<7;i++) msgs[i]=SimObs?msgs3[i]:msgs1[i]; - } - else if (PlotType==PLOT_MPS) { - msg+=s.sprintf("NSAT=%d ",ns); - for (i=0;i<7;i++) msgs[i]=msgs4[i]; - } - else { - msg+=s.sprintf("NSAT=%d ",ns); - for (i=0;i<7;i++) msgs[i]=SimObs?msgs3[i]:msgs2[i]; - } + } + if (ns >= 0) { + dops(ns, azel, ElMask * D2R, dop); + + TimeStr(Obs.data[IndexObs[ind]].time, 3, 1, tstr); + msg.sprintf("[1]%s : N=%d ", tstr, no); + + if (PlotType == PLOT_DOP) { + msgs[0].sprintf("NSAT=%d", ns); + msgs[1].sprintf(" GDOP=%.1f", dop[0]); + msgs[2].sprintf(" PDOP=%.1f", dop[1]); + msgs[3].sprintf(" HDOP=%.1f", dop[2]); + msgs[4].sprintf(" VDOP=%.1f", dop[3]); + } else if (PlotType <= PLOT_SKY && ObsType->ItemIndex == 0) { + msg += s.sprintf("NSAT=%d ", ns); + for (i = 0; i < 7; i++) msgs[i] = SimObs ? msgs3[i] : msgs1[i]; + } else if (PlotType == PLOT_MPS) { + msg += s.sprintf("NSAT=%d ", ns); + for (i = 0; i < 7; i++) msgs[i] = msgs4[i]; + } else { + msg += s.sprintf("NSAT=%d ", ns); + for (i = 0; i < 7; i++) msgs[i] = SimObs ? msgs3[i] : msgs2[i]; } - ShowMsg(msg); - if (msgs[0]==msgs1[0]) ShowObsLegend(msgs); - else ShowLegend(msgs); + } + ShowMsg(msg); + if (msgs[0] == msgs1[0]) + ShowObsLegend(msgs); + else + ShowLegend(msgs); } // update time-information for solution plot -------------------------------- -void __fastcall TPlot::UpdateTimeSol(void) -{ - const char *unit[]={"m","m/s","m/s2"},*u; - const char *sol[]={"","FIX","FLOAT","SBAS","DGPS","Single","PPP"}; - UTF8String msg,msgs[8],s; - sol_t *data; - double xyz[3],pos[3],r,az,el; - int sel=BtnSol1->Down||!BtnSol2->Down?0:1,ind=SolIndex[sel]; - char tstr[48]; - - trace(3,"UpdateTimeSol\n"); - - if ((BtnSol1->Down||BtnSol2->Down||BtnSol12->Down)&& - (data=getsol(SolData+sel,ind))) { - - if (!ConnectState) msg.sprintf("[%d]",sel+1); else msg="[R]"; - - TimeStr(data->time,2,1,tstr); - msg+=tstr; - msg+=" : "; - - if (PLOT_SOLP<=PlotType&&PlotType<=PLOT_SOLA) { - TIMEPOS *p=SolToPos(SolData+sel,ind,0,PlotType-PLOT_SOLP); - u=unit[PlotType-PLOT_SOLP]; - msg+=s.sprintf("E=%7.4f%s N=%7.4f%s U=%7.4f%s Q=", - p->x[0],u,p->y[0],u,p->z[0],u); - delete p; - } - else if (PlotType==PLOT_NSAT) { - msg+=s.sprintf("NS=%d AGE=%.1f RATIO=%.1f Q=",data->ns,data->age, - data->ratio); - } - else if (!data->type) { - ecef2pos(data->rr,pos); - msg+=LatLonStr(pos,9)+s.sprintf(" %9.4fm Q=",pos[2]); - } - else { - r=norm(data->rr,3); - az=norm(data->rr,2)<=1E-12?0.0:atan2(data->rr[0],data->rr[1])*R2D; - el=r<=1E-12?0.0:asin(data->rr[2]/r)*R2D; - msg+=s.sprintf("B=%.3fm D=%6.2f" CHARDEG " %5.2f" CHARDEG " Q=", - r,az<0.0?az+360.0:az,el); - } - if (1<=data->stat&&data->stat<=6) { - msgs[data->stat-1]=s.sprintf("%d:%s",data->stat,sol[data->stat]); - } +void __fastcall TPlot::UpdateTimeSol(void) { + const char *unit[] = {"m", "m/s", "m/s2"}, *u; + const char *sol[] = {"", "FIX", "FLOAT", "SBAS", "DGPS", "Single", "PPP"}; + UTF8String msg, msgs[8], s; + sol_t *data; + double xyz[3], pos[3], r, az, el; + int sel = BtnSol1->Down || !BtnSol2->Down ? 0 : 1, ind = SolIndex[sel]; + char tstr[48]; + + trace(3, "UpdateTimeSol\n"); + + if ((BtnSol1->Down || BtnSol2->Down || BtnSol12->Down) && (data = getsol(SolData + sel, ind))) { + if (!ConnectState) + msg.sprintf("[%d]", sel + 1); + else + msg = "[R]"; + + TimeStr(data->time, 2, 1, tstr); + msg += tstr; + msg += " : "; + + if (PLOT_SOLP <= PlotType && PlotType <= PLOT_SOLA) { + TIMEPOS *p = SolToPos(SolData + sel, ind, 0, PlotType - PLOT_SOLP); + u = unit[PlotType - PLOT_SOLP]; + msg += s.sprintf("E=%7.4f%s N=%7.4f%s U=%7.4f%s Q=", p->x[0], u, p->y[0], u, p->z[0], u); + delete p; + } else if (PlotType == PLOT_NSAT) { + msg += s.sprintf("NS=%d AGE=%.1f RATIO=%.1f Q=", data->ns, data->age, data->ratio); + } else if (!data->type) { + ecef2pos(data->rr, pos); + msg += LatLonStr(pos, 9) + s.sprintf(" %9.4fm Q=", pos[2]); + } else { + r = norm(data->rr, 3); + az = norm(data->rr, 2) <= 1E-12 ? 0.0 : atan2(data->rr[0], data->rr[1]) * R2D; + el = r <= 1E-12 ? 0.0 : asin(data->rr[2] / r) * R2D; + msg += s.sprintf("B=%.3fm D=%6.2f" CHARDEG " %5.2f" CHARDEG " Q=", r, + az < 0.0 ? az + 360.0 : az, el); } - ShowMsg(msg); - ShowLegend(msgs); + if (1 <= data->stat && data->stat <= 6) { + msgs[data->stat - 1] = s.sprintf("%d:%s", data->stat, sol[data->stat]); + } + } + ShowMsg(msg); + ShowLegend(msgs); } // update statistics-information for observation-data plot ------------------ -void __fastcall TPlot::UpdateInfoObs(void) -{ - UTF8String msgs0[]={" NSAT"," GDOP"," PDOP"," HDOP"," VDOP","",""}; - UTF8String msgs1[]={" #FRQ= 5 "," 4 "," 3 "," 2 "," 1 ","",""}; - UTF8String msgs2[]={" SNR=...45.","..40.","..35.","..30.","..25 ",""," <25 "}; - UTF8String msgs3[]={" SYS=GPS ","GLO ","GAL ","QZS ","BDS ","IRN ","SBS "}; - UTF8String msgs4[]={" MP=..0.6","..0.3","..0.0..","-0.3..","-0.6..","",""}; - UTF8String msg,msgs[8]; - gtime_t ts={0},te={0},t,tp={0}; - int i,n=0,ne=0; - char s1[48],s2[48],*p; - - trace(3,"UpdateInfoObs:\n"); - - if (BtnSol1->Down) { - for (i=0;iTTOL) ne++; - n++; tp=t; - } +void __fastcall TPlot::UpdateInfoObs(void) { + UTF8String msgs0[] = {" NSAT", " GDOP", " PDOP", " HDOP", " VDOP", "", ""}; + UTF8String msgs1[] = {" #FRQ= 5 ", " 4 ", " 3 ", " 2 ", " 1 ", "", ""}; + UTF8String msgs2[] = {" SNR=...45.", "..40.", "..35.", "..30.", "..25 ", "", " <25 "}; + UTF8String msgs3[] = {" SYS=GPS ", "GLO ", "GAL ", "QZS ", "BDS ", "IRN ", "SBS "}; + UTF8String msgs4[] = {" MP=..0.6", "..0.3", "..0.0..", "-0.3..", "-0.6..", "", ""}; + UTF8String msg, msgs[8]; + gtime_t ts = {0}, te = {0}, t, tp = {0}; + int i, n = 0, ne = 0; + char s1[48], s2[48], *p; + + trace(3, "UpdateInfoObs:\n"); + + if (BtnSol1->Down) { + for (i = 0; i < Obs.n; i++) { + t = Obs.data[i].time; + if (ts.time == 0) ts = t; + te = t; + if (tp.time == 0 || timediff(t, tp) > TTOL) ne++; + n++; + tp = t; } - if (n>0) { - TimeStr(ts,0,0,s1); - TimeStr(te,0,1,s2); - if (TimeLabel&&(p=strrchr(s1,' '))) *p='\0'; - msg.sprintf("[1]%s-%s : EP=%d N=%d",s1,s2+(TimeLabel?5:0),ne,n); - - for (i=0;i<7;i++) { - if (PlotType==PLOT_DOP) { - msgs[i]=msgs0[i]; - } - else if (PlotType<=PLOT_SKY&&ObsType->ItemIndex==0) { - msgs[i]=SimObs?msgs3[i]:msgs1[i]; - } - else if (PlotType==PLOT_MPS) { - msgs[i]=msgs4[i]; - } - else { - msgs[i]=SimObs?msgs3[i]:msgs2[i]; - } - } + } + if (n > 0) { + TimeStr(ts, 0, 0, s1); + TimeStr(te, 0, 1, s2); + if (TimeLabel && (p = strrchr(s1, ' '))) *p = '\0'; + msg.sprintf("[1]%s-%s : EP=%d N=%d", s1, s2 + (TimeLabel ? 5 : 0), ne, n); + + for (i = 0; i < 7; i++) { + if (PlotType == PLOT_DOP) { + msgs[i] = msgs0[i]; + } else if (PlotType <= PLOT_SKY && ObsType->ItemIndex == 0) { + msgs[i] = SimObs ? msgs3[i] : msgs1[i]; + } else if (PlotType == PLOT_MPS) { + msgs[i] = msgs4[i]; + } else { + msgs[i] = SimObs ? msgs3[i] : msgs2[i]; + } } - ShowMsg(msg); - if (msgs[0]==msgs1[0]) ShowObsLegend(msgs); - else ShowLegend(msgs); + } + ShowMsg(msg); + if (msgs[0] == msgs1[0]) + ShowObsLegend(msgs); + else + ShowLegend(msgs); } // update statistics-information for solution plot -------------------------- -void __fastcall TPlot::UpdateInfoSol(void) -{ - UTF8String msg,msgs[8],s; - TIMEPOS *pos=NULL,*pos1,*pos2; - sol_t *data; - gtime_t ts={0},te={0}; - double r[3],b,bl[2]={1E9,0.0}; - int i,j,n=0,nq[8]={0},sel=BtnSol1->Down||!BtnSol2->Down?0:1; - char s1[48],s2[48],*p; - - trace(3,"UpdateInfoSol:\n"); - - if (BtnSol1->Down||BtnSol2->Down) { - pos=SolToPos(SolData+sel,-1,0,0); - } - else if (BtnSol12->Down) { - pos1=SolToPos(SolData ,-1,0,0); - pos2=SolToPos(SolData+1,-1,0,0); - pos=pos1->diff(pos2,0); - delete pos1; - delete pos2; - } - if (pos) { - for (i=0;in;i++) { - if (ts.time==0) ts=pos->t[i]; te=pos->t[i]; - nq[pos->q[i]]++; - n++; - } - delete pos; +void __fastcall TPlot::UpdateInfoSol(void) { + UTF8String msg, msgs[8], s; + TIMEPOS *pos = NULL, *pos1, *pos2; + sol_t *data; + gtime_t ts = {0}, te = {0}; + double r[3], b, bl[2] = {1E9, 0.0}; + int i, j, n = 0, nq[8] = {0}, sel = BtnSol1->Down || !BtnSol2->Down ? 0 : 1; + char s1[48], s2[48], *p; + + trace(3, "UpdateInfoSol:\n"); + + if (BtnSol1->Down || BtnSol2->Down) { + pos = SolToPos(SolData + sel, -1, 0, 0); + } else if (BtnSol12->Down) { + pos1 = SolToPos(SolData, -1, 0, 0); + pos2 = SolToPos(SolData + 1, -1, 0, 0); + pos = pos1->diff(pos2, 0); + delete pos1; + delete pos2; + } + if (pos) { + for (i = 0; i < pos->n; i++) { + if (ts.time == 0) ts = pos->t[i]; + te = pos->t[i]; + nq[pos->q[i]]++; + n++; } - for (i=0;(data=getsol(SolData+sel,i));i++) { - if (data->type) { - b=norm(data->rr,3); - } - else if (norm(SolData[sel].rb,3)>0.0) { - for (j=0;j<3;j++) r[j]=data->rr[j]-SolData[sel].rb[j]; - b=norm(r,3); - } - else b=0.0; - if (bbl[1]) bl[1]=b; + delete pos; + } + for (i = 0; (data = getsol(SolData + sel, i)); i++) { + if (data->type) { + b = norm(data->rr, 3); + } else if (norm(SolData[sel].rb, 3) > 0.0) { + for (j = 0; j < 3; j++) r[j] = data->rr[j] - SolData[sel].rb[j]; + b = norm(r, 3); + } else + b = 0.0; + if (b < bl[0]) bl[0] = b; + if (b > bl[1]) bl[1] = b; + } + if (n > 0) { + if (!ConnectState) + msg.sprintf("[%d]", sel + 1); + else + msg = "[R]"; + + TimeStr(ts, 0, 0, s1); + TimeStr(te, 0, 1, s2); + if (TimeLabel && (p = strrchr(s1, ' '))) *p = '\0'; + msg += s.sprintf("%s-%s : N=%d", s1, s2 + (TimeLabel ? 5 : 0), n); + + if (bl[0] + 100.0 < bl[1]) { + msg += s.sprintf(" B=%.1f-%.1fkm", bl[0] / 1E3, bl[1] / 1E3); + } else { + msg += s.sprintf(" B=%.1fkm", bl[0] / 1E3); } - if (n>0) { - if (!ConnectState) msg.sprintf("[%d]",sel+1); else msg="[R]"; - - TimeStr(ts,0,0,s1); - TimeStr(te,0,1,s2); - if (TimeLabel&&(p=strrchr(s1,' '))) *p='\0'; - msg+=s.sprintf("%s-%s : N=%d",s1,s2+(TimeLabel?5:0),n); - - if (bl[0]+100.0Clear(); - if (SolData[0].n>0||SolData[1].n>0|| - (NObs<=0&&SolStat[0].n<=0&&SolStat[1].n<=0)) { - PlotTypeS->AddItem(PTypes[PLOT_TRK ],NULL); - PlotTypeS->AddItem(PTypes[PLOT_SOLP],NULL); - PlotTypeS->AddItem(PTypes[PLOT_SOLV],NULL); - PlotTypeS->AddItem(PTypes[PLOT_SOLA],NULL); - PlotTypeS->AddItem(PTypes[PLOT_NSAT],NULL); - } - if (SolStat[0].n>0||SolStat[1].n>0) { - PlotTypeS->AddItem(PTypes[PLOT_SSKY],NULL); - PlotTypeS->AddItem(PTypes[PLOT_SDOP],NULL); - PlotTypeS->AddItem(PTypes[PLOT_RES ],NULL); - PlotTypeS->AddItem(PTypes[PLOT_RESE],NULL); - } - if (NObs>0) { - PlotTypeS->AddItem(PTypes[PLOT_OBS ],NULL); - PlotTypeS->AddItem(PTypes[PLOT_SKY ],NULL); - PlotTypeS->AddItem(PTypes[PLOT_DOP ],NULL); - } - if (NObs>0) { - PlotTypeS->AddItem(PTypes[PLOT_SNR ],NULL); - PlotTypeS->AddItem(PTypes[PLOT_SNRE],NULL); - PlotTypeS->AddItem(PTypes[PLOT_MPS ],NULL); - } - for (i=0;iItems->Count;i++) { - if (PlotTypeS->Items->Strings[i]!=PTypes[PlotType]) continue; - PlotTypeS->ItemIndex=i; - return; - } - PlotTypeS->ItemIndex=0; +void __fastcall TPlot::UpdatePlotType(void) { + int i; + + trace(3, "UpdatePlotType\n"); + + PlotTypeS->Clear(); + if (SolData[0].n > 0 || SolData[1].n > 0 || + (NObs <= 0 && SolStat[0].n <= 0 && SolStat[1].n <= 0)) { + PlotTypeS->AddItem(PTypes[PLOT_TRK], NULL); + PlotTypeS->AddItem(PTypes[PLOT_SOLP], NULL); + PlotTypeS->AddItem(PTypes[PLOT_SOLV], NULL); + PlotTypeS->AddItem(PTypes[PLOT_SOLA], NULL); + PlotTypeS->AddItem(PTypes[PLOT_NSAT], NULL); + } + if (SolStat[0].n > 0 || SolStat[1].n > 0) { + PlotTypeS->AddItem(PTypes[PLOT_SSKY], NULL); + PlotTypeS->AddItem(PTypes[PLOT_SDOP], NULL); + PlotTypeS->AddItem(PTypes[PLOT_RES], NULL); + PlotTypeS->AddItem(PTypes[PLOT_RESE], NULL); + } + if (NObs > 0) { + PlotTypeS->AddItem(PTypes[PLOT_OBS], NULL); + PlotTypeS->AddItem(PTypes[PLOT_SKY], NULL); + PlotTypeS->AddItem(PTypes[PLOT_DOP], NULL); + } + if (NObs > 0) { + PlotTypeS->AddItem(PTypes[PLOT_SNR], NULL); + PlotTypeS->AddItem(PTypes[PLOT_SNRE], NULL); + PlotTypeS->AddItem(PTypes[PLOT_MPS], NULL); + } + for (i = 0; i < PlotTypeS->Items->Count; i++) { + if (PlotTypeS->Items->Strings[i] != PTypes[PlotType]) continue; + PlotTypeS->ItemIndex = i; + return; + } + PlotTypeS->ItemIndex = 0; } // update satellite-list pull-down menu ------------------------------------- -void __fastcall TPlot::UpdateSatList(void) -{ - int i,j,sys,sysp=0,sat,smask[MAXSAT]={0}; - char s[8]; - - trace(3,"UpdateSatList\n"); - - for (i=0;i<2;i++) for (j=0;jItems->Clear(); - SatList->Items->Add("ALL"); - - for (sat=1;sat<=MAXSAT;sat++) { - if (SatMask[sat-1]||!smask[sat-1]) continue; - if ((sys=satsys(sat,NULL))==sysp) continue; - switch ((sysp=sys)) { - case SYS_GPS: strcpy(s,"G"); break; - case SYS_GLO: strcpy(s,"R"); break; - case SYS_GAL: strcpy(s,"E"); break; - case SYS_QZS: strcpy(s,"J"); break; - case SYS_CMP: strcpy(s,"C"); break; - case SYS_IRN: strcpy(s,"I"); break; - case SYS_SBS: strcpy(s,"S"); break; - } - SatList->Items->Add(s); +void __fastcall TPlot::UpdateSatList(void) { + int i, j, sys, sysp = 0, sat, smask[MAXSAT] = {0}; + char s[8]; + + trace(3, "UpdateSatList\n"); + + for (i = 0; i < 2; i++) + for (j = 0; j < SolStat[i].n; j++) { + sat = SolStat[i].data[j].sat; + if (1 <= sat && sat <= MAXSAT) smask[sat - 1] = 1; } - for (sat=1;sat<=MAXSAT;sat++) { - if (SatMask[sat-1]||!smask[sat-1]) continue; - satno2id(sat,s); - SatList->Items->Add(s); + for (j = 0; j < Obs.n; j++) { + sat = Obs.data[j].sat; + if (1 <= sat && sat <= MAXSAT) smask[sat - 1] = 1; + } + SatList->Items->Clear(); + SatList->Items->Add("ALL"); + + for (sat = 1; sat <= MAXSAT; sat++) { + if (SatMask[sat - 1] || !smask[sat - 1]) continue; + if ((sys = satsys(sat, NULL)) == sysp) continue; + switch ((sysp = sys)) { + case SYS_GPS: + strcpy(s, "G"); + break; + case SYS_GLO: + strcpy(s, "R"); + break; + case SYS_GAL: + strcpy(s, "E"); + break; + case SYS_QZS: + strcpy(s, "J"); + break; + case SYS_CMP: + strcpy(s, "C"); + break; + case SYS_IRN: + strcpy(s, "I"); + break; + case SYS_SBS: + strcpy(s, "S"); + break; } - SatList->ItemIndex=0; - - UpdateSatSel(); + SatList->Items->Add(s); + } + for (sat = 1; sat <= MAXSAT; sat++) { + if (SatMask[sat - 1] || !smask[sat - 1]) continue; + satno2id(sat, s); + SatList->Items->Add(s); + } + SatList->ItemIndex = 0; + + UpdateSatSel(); } // string compare -------------------------------------------------------------- -static int _strcmp(const void *str1, const void *str2) -{ - return strcmp(*(const char **)str1, *(const char **)str2); +static int _strcmp(const void *str1, const void *str2) { + return strcmp(*(const char **)str1, *(const char **)str2); } // update observation type pull-down menu -------------------------------------- -void __fastcall TPlot::UpdateObsType(void) -{ - UTF8String s; - char *obs,*codes[MAXCODE+1]; - int i,j,n=0,cmask[MAXCODE+1]={0},fmask[10]={0}; - const char *obstypes[] = {"L1/LC","L2/E5b","L5/E5a","L6","L7","L8"}; - - trace(3,"UpdateObsType\n"); - - for (i=0;iItems->Clear(); - ObsType2->Items->Clear(); - ObsType ->Items->Add("ALL"); - - for (i=0;iItems->Add(s.sprintf("%s",obstypes[i])); - ObsType2 ->Items->Add(s.sprintf("%s",obstypes[i])); - } - for (i=0;iItems->Add(s.sprintf("%s",codes[i])); - ObsType2->Items->Add(s.sprintf("%s",codes[i])); +void __fastcall TPlot::UpdateObsType(void) { + UTF8String s; + char *obs, *codes[MAXCODE + 1]; + int i, j, n = 0, cmask[MAXCODE + 1] = {0}, fmask[10] = {0}; + const char *obstypes[] = {"L1/LC", "L2/E5b", "L5/E5a", "L6", "L7", "L8"}; + + trace(3, "UpdateObsType\n"); + + for (i = 0; i < Obs.n; i++) + for (j = 0; j < NFREQ + NEXOBS; j++) { + cmask[Obs.data[i].code[j]] = 1; } - ObsType ->ItemIndex=0; - ObsType2->ItemIndex=0; + for (i = 1; i <= MAXCODE; i++) { + if (!cmask[i]) continue; + if (!*(obs = code2obs((uint8_t)i))) continue; + codes[n++] = obs; + } + qsort(codes, n, sizeof(char *), _strcmp); + + ObsType->Items->Clear(); + ObsType2->Items->Clear(); + ObsType->Items->Add("ALL"); + + for (i = 0; i < NFREQ; i++) { + ObsType->Items->Add(s.sprintf("%s", obstypes[i])); + ObsType2->Items->Add(s.sprintf("%s", obstypes[i])); + } + for (i = 0; i < n; i++) { + ObsType->Items->Add(s.sprintf("%s", codes[i])); + ObsType2->Items->Add(s.sprintf("%s", codes[i])); + } + ObsType->ItemIndex = 0; + ObsType2->ItemIndex = 0; } // update information for current-cursor position --------------------------- -void __fastcall TPlot::UpdatePoint(int x, int y) -{ - gtime_t time; - TPoint p(x,y); - double enu[3]={0},rr[3],pos[3],xx,yy,r,xl[2],yl[2],q[2],az,el,snr; - int i; - char tstr[48]; - UTF8String msg; - - trace(4,"UpdatePoint: x=%d y=%d\n",x,y); - - if (PlotType==PLOT_TRK) { // track-plot - - GraphT->ToPos(p,enu[0],enu[1]); - - if (PointType==1||norm(OPos,3)<=0.0) { - msg.sprintf("E:%+.4f m N:%+.4f m",enu[0],enu[1]); - } - else if (PointType==2) { - r=norm(enu,2); - az=r<=0.0?0.0:ATAN2(enu[0],enu[1])*R2D; - if (az<0.0) az+=360.0; - msg.sprintf("R:%.4f m D:%5.1f" CHARDEG,r,az); - } - else { - ecef2pos(OPos,pos); - enu2ecef(pos,enu,rr); - for (i=0;i<3;i++) rr[i]+=OPos[i]; - ecef2pos(rr,pos); - msg=LatLonStr(pos,8); - } - } - else if (PlotType==PLOT_SKY||PlotType==PLOT_SSKY||PlotType==PLOT_MPS) { // sky-plot - - GraphS->GetLim(xl,yl); - GraphS->ToPos(p,q[0],q[1]); - r=(xl[1]-xl[0]0.0) { - az=el>=90.0?0.0:ATAN2(q[0],q[1])*R2D; - if (az<0.0) az+=360.0; - msg.sprintf("AZ=%5.1f" CHARDEG " EL=%4.1f" CHARDEG,az,el); - } - } - else if (PlotType==PLOT_SNRE||PlotType==PLOT_RESE) { // snr-el-plot - GraphE[0]->ToPos(p,q[0],q[1]); - msg.sprintf("EL=%4.1f " CHARDEG,q[0]); +void __fastcall TPlot::UpdatePoint(int x, int y) { + gtime_t time; + TPoint p(x, y); + double enu[3] = {0}, rr[3], pos[3], xx, yy, r, xl[2], yl[2], q[2], az, el, snr; + int i; + char tstr[48]; + UTF8String msg; + + trace(4, "UpdatePoint: x=%d y=%d\n", x, y); + + if (PlotType == PLOT_TRK) { // track-plot + + GraphT->ToPos(p, enu[0], enu[1]); + + if (PointType == 1 || norm(OPos, 3) <= 0.0) { + msg.sprintf("E:%+.4f m N:%+.4f m", enu[0], enu[1]); + } else if (PointType == 2) { + r = norm(enu, 2); + az = r <= 0.0 ? 0.0 : ATAN2(enu[0], enu[1]) * R2D; + if (az < 0.0) az += 360.0; + msg.sprintf("R:%.4f m D:%5.1f" CHARDEG, r, az); + } else { + ecef2pos(OPos, pos); + enu2ecef(pos, enu, rr); + for (i = 0; i < 3; i++) rr[i] += OPos[i]; + ecef2pos(rr, pos); + msg = LatLonStr(pos, 8); } - else { - GraphG[0]->ToPos(p,xx,yy); - time=gpst2time(Week,xx); - if (TimeLabel==2) time=utc2gpst(time); // UTC - else if (TimeLabel==3) time=timeadd(gpst2utc(time),-9*3600.0); // JST - TimeStr(time,0,1,tstr); - msg=tstr; + } else if (PlotType == PLOT_SKY || PlotType == PLOT_SSKY || PlotType == PLOT_MPS) { // sky-plot + + GraphS->GetLim(xl, yl); + GraphS->ToPos(p, q[0], q[1]); + r = (xl[1] - xl[0] < yl[1] - yl[0] ? xl[1] - xl[0] : yl[1] - yl[0]) * 0.45; + + if ((el = 90.0 - 90.0 * norm(q, 2) / r) > 0.0) { + az = el >= 90.0 ? 0.0 : ATAN2(q[0], q[1]) * R2D; + if (az < 0.0) az += 360.0; + msg.sprintf("AZ=%5.1f" CHARDEG " EL=%4.1f" CHARDEG, az, el); } - Panel22->Visible=true; - Message2->Caption=msg; + } else if (PlotType == PLOT_SNRE || PlotType == PLOT_RESE) { // snr-el-plot + GraphE[0]->ToPos(p, q[0], q[1]); + msg.sprintf("EL=%4.1f " CHARDEG, q[0]); + } else { + GraphG[0]->ToPos(p, xx, yy); + time = gpst2time(Week, xx); + if (TimeLabel == 2) + time = utc2gpst(time); // UTC + else if (TimeLabel == 3) + time = timeadd(gpst2utc(time), -9 * 3600.0); // JST + TimeStr(time, 0, 1, tstr); + msg = tstr; + } + Panel22->Visible = true; + Message2->Caption = msg; } //--------------------------------------------------------------------------- diff --git a/app/winapp/rtkplot/plotmain.cpp b/app/winapp/rtkplot/plotmain.cpp index a147f6e8c..7fb0a3c21 100644 --- a/app/winapp/rtkplot/plotmain.cpp +++ b/app/winapp/rtkplot/plotmain.cpp @@ -14,8 +14,8 @@ // tcpcli://addr[:port] // ntrip://[user[:passwd]@]addr[:port][/mntpnt] // file://path -// -p1 path connect port 1 to path -// -p2 path connect port 2 to path +// -p1 path connect port 1 to path +// -p2 path connect port 2 to path // -x level debug trace level (0:off) // file solution files or rinex obs/nav file // @@ -36,2952 +36,2841 @@ // fix bug on MP computation for L3,L4,... freq. //--------------------------------------------------------------------------- #include -#include + #include +#include #pragma hdrstop #pragma package(smart_init) #pragma resource "*.dfm" -#include "rtklib.h" #include "plotmain.h" -#include "plotopt.h" -#include "refdlg.h" -#include "tspandlg.h" + #include "aboutdlg.h" -#include "fileseldlg.h" -#include "conndlg.h" #include "confdlg.h" +#include "conndlg.h" #include "console.h" -#include "pntdlg.h" -#include "mapoptdlg.h" -#include "skydlg.h" +#include "fileseldlg.h" #include "freqdlg.h" +#include "mapoptdlg.h" #include "mapview.h" +#include "plotopt.h" +#include "pntdlg.h" +#include "refdlg.h" +#include "rtklib.h" +#include "skydlg.h" +#include "tspandlg.h" #include "viewer.h" #include "vmapdlg.h" #pragma link "SHDocVw_OCX" -#define YLIM_AGE 10.0 // ylimit of age of differential -#define YLIM_RATIO 20.0 // ylimit of raito factor -#define MAXSHAPEFILE 16 // max number of shape files +#define YLIM_AGE 10.0 // ylimit of age of differential +#define YLIM_RATIO 20.0 // ylimit of raito factor +#define MAXSHAPEFILE 16 // max number of shape files // instance of TPLOT -------------------------------------------------------- TPlot *Plot; // constructor -------------------------------------------------------------- -__fastcall TPlot::TPlot(TComponent* Owner) : TForm(Owner) -{ - gtime_t t0={0}; - obs_t obs0={0}; - sta_t sta0={0}; - gis_t gis0={0}; - solstatbuf_t solstat0={0}; - AnsiString s; - double ep[]={2000,1,1,0,0,0},xl[2],yl[2]; - double xs[]={-DEFTSPAN/2,DEFTSPAN/2}; - char file[1024]="rtkplot.exe",*p; - - ::GetModuleFileName(NULL,file,sizeof(file)); - if (!(p=strrchr(file,'.'))) p=file+strlen(file); - strcpy(p,".ini"); - IniFile=file; - - FormWidth=FormHeight=0; - Drag=0; Xn=Yn=-1; NObs=0; - IndexObs=NULL; - Week=Flush=PlotType=0; - AnimCycle=1; - for (int i=0;i<2;i++) { - initsolbuf(SolData+i,0,0); - SolStat[i]=solstat0; - SolIndex[i]=0; - } +__fastcall TPlot::TPlot(TComponent *Owner) : TForm(Owner) { + gtime_t t0 = {0}; + obs_t obs0 = {0}; + sta_t sta0 = {0}; + gis_t gis0 = {0}; + solstatbuf_t solstat0 = {0}; + AnsiString s; + double ep[] = {2000, 1, 1, 0, 0, 0}, xl[2], yl[2]; + double xs[] = {-DEFTSPAN / 2, DEFTSPAN / 2}; + char file[1024] = "rtkplot.exe", *p; - obs0.data=NULL; obs0.n =obs0.nmax =0; - ObsIndex=0; - Obs=obs0; - memset(&Nav, 0, sizeof(Nav)); - Sta=sta0; - Gis=gis0; - SimObs=0; - - X0=Y0=Xc=Yc=Xs=Ys=Xcent=0.0; - MouseDownTick=0; - GEState=GEDataState[0]=GEDataState[1]=0; - GEHeading=0.0; - OEpoch=t0; - for (int i=0;i<3;i++) OPos[i]=OVel[i]=0.0; - Az=El=NULL; - for (int i=0;iFit=0; - - for (int i=0;i<3;i++) { - GraphG[i]=new TGraph(Disp); - GraphG[i]->XLPos=0; - GraphG[i]->GetLim(xl,yl); - GraphG[i]->SetLim(xs,yl); - } - GraphR=new TGraph(Disp); - for (int i=0;i<2;i++) { - GraphE[i]=new TGraph(Disp); - } - GraphS=new TGraph(Disp); - GraphR->GetLim(xl,yl); - GraphR->SetLim(xs,yl); - - MapSize[0]=MapSize[1]=0; - MapScaleX=MapScaleY=0.1; - MapScaleEq=0; - MapLat=MapLon=0.0; - PointType=0; - - NWayPnt=0; - SelWayPnt=-1; - - SkySize[0]=SkySize[1]=SkyCent[0]=SkyCent[1]=0; - SkyScale=SkyScaleR=240.0; - SkyFov[0]=SkyFov[1]=SkyFov[2]=0.0; - SkyElMask=1; - SkyDestCorr=SkyRes=SkyFlip=0; - for (int i=0;i<10;i++) SkyDest[i]=0.0; - SkyBinarize=0; - SkyBinThres1=0.3; - SkyBinThres2=0.1; - - for (int i=0;i<3;i++) TimeEna[i]=0; - TimeLabel=AutoScale=ShowStats=0; - ShowLabel=ShowGLabel=1; - ShowArrow=ShowSlip=ShowHalfC=ShowErr=ShowEph=0; - PlotStyle=MarkSize=Origin=RcvPos=0; - TimeInt=ElMask=YRange=0.0; - MaxDop=30.0; - MaxMP=10.0; - TimeStart=TimeEnd=epoch2time(ep); - DoubleBuffered=true; - Console1=new TConsole(Owner); - Console2=new TConsole(Owner); - - for (int i=0;i<361;i++) ElMaskData[i]=0.0; - - Trace=0; - ConnectState=OpenRaw=0; - RtConnType=0; - strinitcom(); - strinit(Stream ); - strinit(Stream+1); - - FrqType->Items->Clear(); - FrqType->Items->Add("L1/LC"); - if (NFREQ>=2) FrqType->Items->Add("L2/E5b"); - if (NFREQ>=3) FrqType->Items->Add("L5/E5a"); - if (NFREQ>=4) FrqType->Items->Add("L6"); - if (NFREQ>=5) FrqType->Items->Add("L7"); - if (NFREQ>=6) FrqType->Items->Add("L8"); - FrqType->ItemIndex=0; - - TLEData.n=TLEData.nmax=0; - TLEData.data=NULL; - - // set current directory as commend search path - AnsiString cd=GetCurrentDir(); - ::SetEnvironmentVariable("PATH",cd.c_str()); + ::GetModuleFileName(NULL, file, sizeof(file)); + if (!(p = strrchr(file, '.'))) p = file + strlen(file); + strcpy(p, ".ini"); + IniFile = file; + + FormWidth = FormHeight = 0; + Drag = 0; + Xn = Yn = -1; + NObs = 0; + IndexObs = NULL; + Week = Flush = PlotType = 0; + AnimCycle = 1; + for (int i = 0; i < 2; i++) { + initsolbuf(SolData + i, 0, 0); + SolStat[i] = solstat0; + SolIndex[i] = 0; + } + + obs0.data = NULL; + obs0.n = obs0.nmax = 0; + ObsIndex = 0; + Obs = obs0; + memset(&Nav, 0, sizeof(Nav)); + Sta = sta0; + Gis = gis0; + SimObs = 0; + + X0 = Y0 = Xc = Yc = Xs = Ys = Xcent = 0.0; + MouseDownTick = 0; + GEState = GEDataState[0] = GEDataState[1] = 0; + GEHeading = 0.0; + OEpoch = t0; + for (int i = 0; i < 3; i++) OPos[i] = OVel[i] = 0.0; + Az = El = NULL; + for (int i = 0; i < NFREQ + NEXOBS; i++) Mp[i] = NULL; + OpenFiles = new TStringList; + SolFiles[0] = new TStringList; + SolFiles[1] = new TStringList; + ObsFiles = new TStringList; + NavFiles = new TStringList; + Buff = new Graphics::TBitmap; + MapImage = new Graphics::TBitmap; + SkyImageI = new Graphics::TBitmap; + SkyImageR = new Graphics::TBitmap; + GraphT = new TGraph(Disp); + GraphT->Fit = 0; + + for (int i = 0; i < 3; i++) { + GraphG[i] = new TGraph(Disp); + GraphG[i]->XLPos = 0; + GraphG[i]->GetLim(xl, yl); + GraphG[i]->SetLim(xs, yl); + } + GraphR = new TGraph(Disp); + for (int i = 0; i < 2; i++) { + GraphE[i] = new TGraph(Disp); + } + GraphS = new TGraph(Disp); + GraphR->GetLim(xl, yl); + GraphR->SetLim(xs, yl); + + MapSize[0] = MapSize[1] = 0; + MapScaleX = MapScaleY = 0.1; + MapScaleEq = 0; + MapLat = MapLon = 0.0; + PointType = 0; + + NWayPnt = 0; + SelWayPnt = -1; + + SkySize[0] = SkySize[1] = SkyCent[0] = SkyCent[1] = 0; + SkyScale = SkyScaleR = 240.0; + SkyFov[0] = SkyFov[1] = SkyFov[2] = 0.0; + SkyElMask = 1; + SkyDestCorr = SkyRes = SkyFlip = 0; + for (int i = 0; i < 10; i++) SkyDest[i] = 0.0; + SkyBinarize = 0; + SkyBinThres1 = 0.3; + SkyBinThres2 = 0.1; + + for (int i = 0; i < 3; i++) TimeEna[i] = 0; + TimeLabel = AutoScale = ShowStats = 0; + ShowLabel = ShowGLabel = 1; + ShowArrow = ShowSlip = ShowHalfC = ShowErr = ShowEph = 0; + PlotStyle = MarkSize = Origin = RcvPos = 0; + TimeInt = ElMask = YRange = 0.0; + MaxDop = 30.0; + MaxMP = 10.0; + TimeStart = TimeEnd = epoch2time(ep); + DoubleBuffered = true; + Console1 = new TConsole(Owner); + Console2 = new TConsole(Owner); + + for (int i = 0; i < 361; i++) ElMaskData[i] = 0.0; + + Trace = 0; + ConnectState = OpenRaw = 0; + RtConnType = 0; + strinitcom(); + strinit(Stream); + strinit(Stream + 1); + + FrqType->Items->Clear(); + FrqType->Items->Add("L1/LC"); + if (NFREQ >= 2) FrqType->Items->Add("L2/E5b"); + if (NFREQ >= 3) FrqType->Items->Add("L5/E5a"); + if (NFREQ >= 4) FrqType->Items->Add("L6"); + if (NFREQ >= 5) FrqType->Items->Add("L7"); + if (NFREQ >= 6) FrqType->Items->Add("L8"); + FrqType->ItemIndex = 0; + + TLEData.n = TLEData.nmax = 0; + TLEData.data = NULL; + + // set current directory as commend search path + AnsiString cd = GetCurrentDir(); + ::SetEnvironmentVariable("PATH", cd.c_str()); } // callback on form-create -------------------------------------------------- -void __fastcall TPlot::FormCreate(TObject *Sender) -{ - ::DragAcceptFiles(Handle,true); -} +void __fastcall TPlot::FormCreate(TObject *Sender) { ::DragAcceptFiles(Handle, true); } // callback on form-show ---------------------------------------------------- -void __fastcall TPlot::FormShow(TObject *Sender) -{ - AnsiString cmd,s; - int i,argc=0; - char *p,*argv[32],buff[1024],str_path[256]; - const char *path1="",*path2=""; - - trace(3,"FormShow\n"); - - cmd=GetCommandLine(); - strcpy(buff,cmd.c_str()); - - for (p=buff;*p&&argc<32;p++) { - if (*p==' ') continue; - if (*p=='"') { - argv[argc++]=p+1; - if (!(p=strchr(p+1,'"'))) break; - } - else { - argv[argc++]=p; - if (!(p=strchr(p+1,' '))) break; - } - *p='\0'; - } - for (i=1;iAdd(argv[i]); - } - } - if (Trace>0) { - traceopen(TRACEFILE); - tracelevel(Trace); - } - LoadOpt(); - - UpdateType(PlotType>=PLOT_OBS?PLOT_TRK:PlotType); - - UpdateColor(); - UpdateSatMask(); - UpdateOrigin(); - - if (*path1||*path2) { - ConnectPath(path1,0); - ConnectPath(path2,1); - Connect(); - } - else if (OpenFiles->Count<=0) { - Caption=Title!=""?Title:s.sprintf("%s-%s %s",PRGNAME,VER_RTKLIB,PATCH_LEVEL); - } - if (ShapeFile!="") { - TStringList *files=new TStringList; - char *paths[MAXSHAPEFILE]; - for (int i=0;iAdd(paths[i]); - } - ReadShapeFile(files); - - for (int i=0;iChecked) { - Splitter1->Left=PanelBrowse->Width; - PanelBrowse->Visible=true; - Splitter1->Visible=true; - } +void __fastcall TPlot::FormShow(TObject *Sender) { + AnsiString cmd, s; + int i, argc = 0; + char *p, *argv[32], buff[1024], str_path[256]; + const char *path1 = "", *path2 = ""; + + trace(3, "FormShow\n"); + + cmd = GetCommandLine(); + strcpy(buff, cmd.c_str()); + + for (p = buff; *p && argc < 32; p++) { + if (*p == ' ') continue; + if (*p == '"') { + argv[argc++] = p + 1; + if (!(p = strchr(p + 1, '"'))) break; + } else { + argv[argc++] = p; + if (!(p = strchr(p + 1, ' '))) break; + } + *p = '\0'; + } + for (i = 1; i < argc; i++) { + if (!strcmp(argv[i], "-i") && i + 1 < argc) IniFile = argv[++i]; + } + LoadOpt(); + + for (i = 1; i < argc; i++) { + if (!strcmp(argv[i], "-r")) + OpenRaw = 1; + else if (!strcmp(argv[i], "-i") && i + 1 < argc) + ; + else if (!strcmp(argv[i], "-p") && i + 1 < argc) + path1 = argv[++i]; + else if (!strcmp(argv[i], "-p1") && i + 1 < argc) + path1 = argv[++i]; + else if (!strcmp(argv[i], "-p2") && i + 1 < argc) + path2 = argv[++i]; + else if (!strcmp(argv[i], "-t") && i + 1 < argc) + Title = argv[++i]; + else if (!strcmp(argv[i], "-x") && i + 1 < argc) + Trace = atoi(argv[++i]); else { - PanelBrowse->Visible=false; - Splitter1->Visible=false; + OpenFiles->Add(argv[i]); + } + } + if (Trace > 0) { + traceopen(TRACEFILE); + tracelevel(Trace); + } + LoadOpt(); + + UpdateType(PlotType >= PLOT_OBS ? PLOT_TRK : PlotType); + + UpdateColor(); + UpdateSatMask(); + UpdateOrigin(); + + if (*path1 || *path2) { + ConnectPath(path1, 0); + ConnectPath(path2, 1); + Connect(); + } else if (OpenFiles->Count <= 0) { + Caption = Title != "" ? Title : s.sprintf("%s-%s %s", PRGNAME, VER_RTKLIB, PATCH_LEVEL); + } + if (ShapeFile != "") { + TStringList *files = new TStringList; + char *paths[MAXSHAPEFILE]; + for (int i = 0; i < MAXSHAPEFILE; i++) { + paths[i] = new char[1024]; + } + int n = expath(ShapeFile.c_str(), paths, MAXSHAPEFILE); + + for (int i = 0; i < n; i++) { + files->Add(paths[i]); } - strinit(&StrTimeSync); - NStrBuff=0; - - if (TimeSyncOut) { - sprintf(str_path,":%d",TimeSyncPort); - stropen(&StrTimeSync,STR_TCPSVR,STR_MODE_RW,str_path); + ReadShapeFile(files); + + for (int i = 0; i < MAXSHAPEFILE; i++) { + delete[] paths[i]; } - Timer->Interval=RefCycle; - UpdatePlot(); - UpdateEnable(); + delete files; + } + if (TLEFile != "") { + tle_read(TLEFile.c_str(), &TLEData); + } + if (TLESatFile != "") { + tle_name_read(TLESatFile.c_str(), &TLEData); + } + if (MenuBrowse->Checked) { + Splitter1->Left = PanelBrowse->Width; + PanelBrowse->Visible = true; + Splitter1->Visible = true; + } else { + PanelBrowse->Visible = false; + Splitter1->Visible = false; + } + strinit(&StrTimeSync); + NStrBuff = 0; + + if (TimeSyncOut) { + sprintf(str_path, ":%d", TimeSyncPort); + stropen(&StrTimeSync, STR_TCPSVR, STR_MODE_RW, str_path); + } + Timer->Interval = RefCycle; + UpdatePlot(); + UpdateEnable(); } // callback on form-close --------------------------------------------------- -void __fastcall TPlot::FormClose(TObject *Sender, TCloseAction &Action) -{ - trace(3,"FormClose\n"); - - SaveOpt(); - - if (Trace>0) traceclose(); +void __fastcall TPlot::FormClose(TObject *Sender, TCloseAction &Action) { + trace(3, "FormClose\n"); + + SaveOpt(); + + if (Trace > 0) traceclose(); } // callback on form-activation ---------------------------------------------- -void __fastcall TPlot::FormActivate(TObject *Sender) -{ - trace(3,"FormActivate\n"); - - if (OpenFiles->Count>0) { - if (CheckObs(OpenFiles->Strings[0])||OpenRaw) ReadObs(OpenFiles); - else ReadSol(OpenFiles,0); - } +void __fastcall TPlot::FormActivate(TObject *Sender) { + trace(3, "FormActivate\n"); + + if (OpenFiles->Count > 0) { + if (CheckObs(OpenFiles->Strings[0]) || OpenRaw) + ReadObs(OpenFiles); + else + ReadSol(OpenFiles, 0); + } } // callback on form-resize -------------------------------------------------- -void __fastcall TPlot::FormResize(TObject *Sender) -{ - trace(3,"FormResize\n"); - - // suppress repeated resize callback - if (FormWidth==Width&&FormHeight==Height) return; - - UpdateSize(); - Refresh(); - - FormWidth =Width; - FormHeight=Height; +void __fastcall TPlot::FormResize(TObject *Sender) { + trace(3, "FormResize\n"); + + // suppress repeated resize callback + if (FormWidth == Width && FormHeight == Height) return; + + UpdateSize(); + Refresh(); + + FormWidth = Width; + FormHeight = Height; } // callback on drag-and-drop files ------------------------------------------ -void __fastcall TPlot::DropFiles(TWMDropFiles msg) -{ - TStringList *files=new TStringList; - AnsiString file; - int n; - char buff[1024],*ext; - - trace(3,"DropFiles\n"); - - if (ConnectState|| - (n=DragQueryFile((HDROP)msg.Drop,0xFFFFFFFF,NULL,0))<=0) { - delete files; - return; - } - for (int i=0;iAdd(buff); - } - file=files->Strings[0]; - - if (n==1&&(ext=strrchr(file.c_str(),'.'))&& - (!strcmp(ext,".jpg")||!strcmp(ext,".jpeg")|| - !strcmp(ext,".JPG")||!strcmp(ext,".JPEG"))) { - if (PlotType==PLOT_TRK) { - ReadMapData(file); - } - else if (PlotType==PLOT_SKY||PlotType==PLOT_SSKY||PlotType==PLOT_MPS) { - ReadSkyData(file); - } - } - else if (CheckObs(file)) { - ReadObs(files); - } - else if (!BtnSol1->Down&&BtnSol2->Down) { - ReadSol(files,1); - } - else { - ReadSol(files,0); - } +void __fastcall TPlot::DropFiles(TWMDropFiles msg) { + TStringList *files = new TStringList; + AnsiString file; + int n; + char buff[1024], *ext; + + trace(3, "DropFiles\n"); + + if (ConnectState || (n = DragQueryFile((HDROP)msg.Drop, 0xFFFFFFFF, NULL, 0)) <= 0) { delete files; + return; + } + for (int i = 0; i < n; i++) { + DragQueryFile((HDROP)msg.Drop, i, buff, sizeof(buff)); + files->Add(buff); + } + file = files->Strings[0]; + + if (n == 1 && (ext = strrchr(file.c_str(), '.')) && + (!strcmp(ext, ".jpg") || !strcmp(ext, ".jpeg") || !strcmp(ext, ".JPG") || + !strcmp(ext, ".JPEG"))) { + if (PlotType == PLOT_TRK) { + ReadMapData(file); + } else if (PlotType == PLOT_SKY || PlotType == PLOT_SSKY || PlotType == PLOT_MPS) { + ReadSkyData(file); + } + } else if (CheckObs(file)) { + ReadObs(files); + } else if (!BtnSol1->Down && BtnSol2->Down) { + ReadSol(files, 1); + } else { + ReadSol(files, 0); + } + delete files; } // callback on menu-open-solution-1 ----------------------------------------- -void __fastcall TPlot::MenuOpenSol1Click(TObject *Sender) -{ - trace(3,"MenuOpenSol1Click\n"); - - OpenSolDialog->Title="Open Solution 1"; - if (!OpenSolDialog->Execute()) return; - ReadSol(OpenSolDialog->Files,0); +void __fastcall TPlot::MenuOpenSol1Click(TObject *Sender) { + trace(3, "MenuOpenSol1Click\n"); + + OpenSolDialog->Title = "Open Solution 1"; + if (!OpenSolDialog->Execute()) return; + ReadSol(OpenSolDialog->Files, 0); } // callback on menu-open-solution-2 ----------------------------------------- -void __fastcall TPlot::MenuOpenSol2Click(TObject *Sender) -{ - trace(3,"MenuOpenSol2Click\n"); - - OpenSolDialog->Title="Open Solution 2"; - if (!OpenSolDialog->Execute()) return; - ReadSol(OpenSolDialog->Files,1); +void __fastcall TPlot::MenuOpenSol2Click(TObject *Sender) { + trace(3, "MenuOpenSol2Click\n"); + + OpenSolDialog->Title = "Open Solution 2"; + if (!OpenSolDialog->Execute()) return; + ReadSol(OpenSolDialog->Files, 1); } // callback on menu-open-map-image ------------------------------------------ -void __fastcall TPlot::MenuOpenMapImageClick(TObject *Sender) -{ - trace(3,"MenuOpenMapImageClick\n"); - - OpenMapDialog->Title="Open Map Image"; - OpenMapDialog->FileName=MapImageFile; - if (!OpenMapDialog->Execute()) return; - ReadMapData(OpenMapDialog->FileName); +void __fastcall TPlot::MenuOpenMapImageClick(TObject *Sender) { + trace(3, "MenuOpenMapImageClick\n"); + + OpenMapDialog->Title = "Open Map Image"; + OpenMapDialog->FileName = MapImageFile; + if (!OpenMapDialog->Execute()) return; + ReadMapData(OpenMapDialog->FileName); } // callback on menu-open-shapefile ------------------------------------------ -void __fastcall TPlot::MenuOpenShapeClick(TObject *Sender) -{ - trace(3,"MenuOpenShapeClick\n"); - - if (!OpenMapPathDialog->Execute()) return; - ReadShapeFile(OpenMapPathDialog->Files); +void __fastcall TPlot::MenuOpenShapeClick(TObject *Sender) { + trace(3, "MenuOpenShapeClick\n"); + + if (!OpenMapPathDialog->Execute()) return; + ReadShapeFile(OpenMapPathDialog->Files); } // callback on menu-open-sky-image ------------------------------------------ -void __fastcall TPlot::MenuOpenSkyImageClick(TObject *Sender) -{ - trace(3,"MenuOpenSkyImageClick\n"); - - OpenMapDialog->Title="Open Sky Image"; - OpenMapDialog->FileName=SkyImageFile; - if (!OpenMapDialog->Execute()) return; - ReadSkyData(OpenMapDialog->FileName); +void __fastcall TPlot::MenuOpenSkyImageClick(TObject *Sender) { + trace(3, "MenuOpenSkyImageClick\n"); + + OpenMapDialog->Title = "Open Sky Image"; + OpenMapDialog->FileName = SkyImageFile; + if (!OpenMapDialog->Execute()) return; + ReadSkyData(OpenMapDialog->FileName); } // callback on menu-oepn-waypoint ------------------------------------------- -void __fastcall TPlot::MenuOpenWaypointClick(TObject *Sender) -{ - trace(3,"MenuOpenWaypointClick\n"); - - if (!OpenWaypointDialog->Execute()) return; - ReadWaypoint(OpenWaypointDialog->FileName); +void __fastcall TPlot::MenuOpenWaypointClick(TObject *Sender) { + trace(3, "MenuOpenWaypointClick\n"); + + if (!OpenWaypointDialog->Execute()) return; + ReadWaypoint(OpenWaypointDialog->FileName); } // callback on menu-open-obs-data ------------------------------------------- -void __fastcall TPlot::MenuOpenObsClick(TObject *Sender) -{ - trace(3,"MenuOpenObsClick\n"); - - OpenObsDialog->FilterIndex=1; - if (!OpenObsDialog->Execute()) return; - ReadObs(OpenObsDialog->Files); +void __fastcall TPlot::MenuOpenObsClick(TObject *Sender) { + trace(3, "MenuOpenObsClick\n"); + + OpenObsDialog->FilterIndex = 1; + if (!OpenObsDialog->Execute()) return; + ReadObs(OpenObsDialog->Files); } // callback on menu-open-nav-data ------------------------------------------- -void __fastcall TPlot::MenuOpenNavClick(TObject *Sender) -{ - trace(3,"MenuOpenNavClick\n"); - - OpenObsDialog->FilterIndex=2; - if (!OpenObsDialog->Execute()) return; - ReadNav(OpenObsDialog->Files); +void __fastcall TPlot::MenuOpenNavClick(TObject *Sender) { + trace(3, "MenuOpenNavClick\n"); + + OpenObsDialog->FilterIndex = 2; + if (!OpenObsDialog->Execute()) return; + ReadNav(OpenObsDialog->Files); } // callback on menu-open-elev-mask ------------------------------------------ -void __fastcall TPlot::MenuOpenElevMaskClick(TObject *Sender) -{ - trace(3,"MenuOpenElevMaskClick\n"); - - if (!OpenElMaskDialog->Execute()) return; - ReadElMaskData(OpenElMaskDialog->FileName); +void __fastcall TPlot::MenuOpenElevMaskClick(TObject *Sender) { + trace(3, "MenuOpenElevMaskClick\n"); + + if (!OpenElMaskDialog->Execute()) return; + ReadElMaskData(OpenElMaskDialog->FileName); } // callback on menu-vis-analysis -------------------------------------------- -void __fastcall TPlot::MenuVisAnaClick(TObject *Sender) -{ - if (RcvPos!=1) { // lat/lon/height - ShowMsg("specify Receiver Position as Lat/Lon/Hgt"); - return; - } - if (SpanDialog->TimeStart.time==0) { - int week; - double tow=time2gpst(utc2gpst(timeget()),&week); - SpanDialog->TimeStart=gpst2time(week,floor(tow/3600.0)*3600.0); - SpanDialog->TimeEnd=timeadd(SpanDialog->TimeStart,86400.0); - SpanDialog->TimeInt=30.0; - } - SpanDialog->TimeEna[0]=SpanDialog->TimeEna[1]=SpanDialog->TimeEna[2]=1; - SpanDialog->TimeVal[0]=SpanDialog->TimeVal[1]=SpanDialog->TimeVal[2]=2; - - if (SpanDialog->ShowModal()==mrOk) { - TimeStart=SpanDialog->TimeStart; - TimeEnd=SpanDialog->TimeEnd; - TimeInt=SpanDialog->TimeInt; - GenVisData(); - } - SpanDialog->TimeVal[0]=SpanDialog->TimeVal[1]=SpanDialog->TimeVal[2]=1; +void __fastcall TPlot::MenuVisAnaClick(TObject *Sender) { + if (RcvPos != 1) { // lat/lon/height + ShowMsg("specify Receiver Position as Lat/Lon/Hgt"); + return; + } + if (SpanDialog->TimeStart.time == 0) { + int week; + double tow = time2gpst(utc2gpst(timeget()), &week); + SpanDialog->TimeStart = gpst2time(week, floor(tow / 3600.0) * 3600.0); + SpanDialog->TimeEnd = timeadd(SpanDialog->TimeStart, 86400.0); + SpanDialog->TimeInt = 30.0; + } + SpanDialog->TimeEna[0] = SpanDialog->TimeEna[1] = SpanDialog->TimeEna[2] = 1; + SpanDialog->TimeVal[0] = SpanDialog->TimeVal[1] = SpanDialog->TimeVal[2] = 2; + + if (SpanDialog->ShowModal() == mrOk) { + TimeStart = SpanDialog->TimeStart; + TimeEnd = SpanDialog->TimeEnd; + TimeInt = SpanDialog->TimeInt; + GenVisData(); + } + SpanDialog->TimeVal[0] = SpanDialog->TimeVal[1] = SpanDialog->TimeVal[2] = 1; } // callback on menu-save image ---------------------------------------------- -void __fastcall TPlot::MenuSaveImageClick(TObject *Sender) -{ - char file[1024],*ext; - - if (!SaveImageDialog->Execute()) return; - - strcpy(file,U2A(SaveImageDialog->FileName).c_str()); - - if ((ext=strrchr(file,'.'))&& - (!strcmp(ext,".jpg")||!strcmp(ext,".jpeg")|| - !strcmp(ext,".JPG")||!strcmp(ext,".JPEG"))) { - TJPEGImage *image=new TJPEGImage; - image->Assign(Buff); - image->SaveToFile(SaveImageDialog->FileName); - delete image; - } - else { - Buff->SaveToFile(SaveImageDialog->FileName); - } +void __fastcall TPlot::MenuSaveImageClick(TObject *Sender) { + char file[1024], *ext; + + if (!SaveImageDialog->Execute()) return; + + strcpy(file, U2A(SaveImageDialog->FileName).c_str()); + + if ((ext = strrchr(file, '.')) && (!strcmp(ext, ".jpg") || !strcmp(ext, ".jpeg") || + !strcmp(ext, ".JPG") || !strcmp(ext, ".JPEG"))) { + TJPEGImage *image = new TJPEGImage; + image->Assign(Buff); + image->SaveToFile(SaveImageDialog->FileName); + delete image; + } else { + Buff->SaveToFile(SaveImageDialog->FileName); + } } // callback on menu-save-waypoint ------------------------------------------- -void __fastcall TPlot::MenuSaveWaypointClick(TObject *Sender) -{ - trace(3,"MenuSaveWaypointClick\n"); - - if (!SaveWaypointDialog->Execute()) return; - - SaveWaypoint(SaveWaypointDialog->FileName); +void __fastcall TPlot::MenuSaveWaypointClick(TObject *Sender) { + trace(3, "MenuSaveWaypointClick\n"); + + if (!SaveWaypointDialog->Execute()) return; + + SaveWaypoint(SaveWaypointDialog->FileName); } // callback on menu-save-# of sats/dop -------------------------------------- -void __fastcall TPlot::MenuSaveDopClick(TObject *Sender) -{ - trace(3,"MenuSaveDopClick\n"); - - if (!SaveDialog->Execute()) return; - - SaveDop(SaveDialog->FileName); +void __fastcall TPlot::MenuSaveDopClick(TObject *Sender) { + trace(3, "MenuSaveDopClick\n"); + + if (!SaveDialog->Execute()) return; + + SaveDop(SaveDialog->FileName); } // callback on menu-save-snr,azel ------------------------------------------- -void __fastcall TPlot::MenuSaveSnrMpClick(TObject *Sender) -{ - trace(3,"MenuSaveSnrMpClick\n"); - - if (!SaveDialog->Execute()) return; - - SaveSnrMp(SaveDialog->FileName); +void __fastcall TPlot::MenuSaveSnrMpClick(TObject *Sender) { + trace(3, "MenuSaveSnrMpClick\n"); + + if (!SaveDialog->Execute()) return; + + SaveSnrMp(SaveDialog->FileName); } // callback on menu-save-elmask --------------------------------------------- -void __fastcall TPlot::MenuSaveElMaskClick(TObject *Sender) -{ - trace(3,"MenuSaveElMaskClick\n"); - - if (!SaveDialog->Execute()) return; - - SaveElMask(SaveDialog->FileName); +void __fastcall TPlot::MenuSaveElMaskClick(TObject *Sender) { + trace(3, "MenuSaveElMaskClick\n"); + + if (!SaveDialog->Execute()) return; + + SaveElMask(SaveDialog->FileName); } // callback on menu-connect ------------------------------------------------- -void __fastcall TPlot::MenuConnectClick(TObject *Sender) -{ - trace(3,"MenuConnectClick\n"); - - Connect(); +void __fastcall TPlot::MenuConnectClick(TObject *Sender) { + trace(3, "MenuConnectClick\n"); + + Connect(); } // callback on menu-disconnect ---------------------------------------------- -void __fastcall TPlot::MenuDisconnectClick(TObject *Sender) -{ - trace(3,"MenuDisconnectClick\n"); - - Disconnect(); +void __fastcall TPlot::MenuDisconnectClick(TObject *Sender) { + trace(3, "MenuDisconnectClick\n"); + + Disconnect(); } // callback on menu-connection-settings ------------------------------------- -void __fastcall TPlot::MenuPortClick(TObject *Sender) -{ - int i; - - trace(3,"MenuPortClick\n"); - - ConnectDialog->Stream1 =RtStream[0]; - ConnectDialog->Stream2 =RtStream[1]; - ConnectDialog->Format1 =RtFormat[0]; - ConnectDialog->Format2 =RtFormat[1]; - ConnectDialog->TimeForm=RtTimeForm; - ConnectDialog->DegForm =RtDegForm; - ConnectDialog->FieldSep=RtFieldSep; - ConnectDialog->TimeOutTime=RtTimeOutTime; - ConnectDialog->ReConnTime =RtReConnTime; - for (i=0;i< 3;i++) { - ConnectDialog->Paths1[i]=StrPaths[0][i]; - ConnectDialog->Paths2[i]=StrPaths[1][i]; - } - for (i=0;i< 2;i++) { - ConnectDialog->Cmds1 [i]=StrCmds[0][i]; - ConnectDialog->Cmds2 [i]=StrCmds[1][i]; - ConnectDialog->CmdEna1[i]=StrCmdEna[0][i]; - ConnectDialog->CmdEna2[i]=StrCmdEna[1][i]; - } - for (i=0;i<10;i++) ConnectDialog->TcpHistory [i]=StrHistory [i]; - - if (ConnectDialog->ShowModal()!=mrOk) return; - - RtStream[0]=ConnectDialog->Stream1; - RtStream[1]=ConnectDialog->Stream2; - RtFormat[0]=ConnectDialog->Format1; - RtFormat[1]=ConnectDialog->Format2; - RtTimeForm=ConnectDialog->TimeForm; - RtDegForm =ConnectDialog->DegForm; - RtFieldSep=ConnectDialog->FieldSep; - RtTimeOutTime=ConnectDialog->TimeOutTime; - RtReConnTime =ConnectDialog->ReConnTime; - for (i=0;i< 3;i++) { - StrPaths[0][i]=ConnectDialog->Paths1[i]; - StrPaths[1][i]=ConnectDialog->Paths2[i]; - } - for (i=0;i< 2;i++) { - StrCmds [0][i]=ConnectDialog->Cmds1 [i]; - StrCmds [1][i]=ConnectDialog->Cmds2 [i]; - StrCmdEna[0][i]=ConnectDialog->CmdEna1[i]; - StrCmdEna[1][i]=ConnectDialog->CmdEna2[i]; - } - for (i=0;i<10;i++) StrHistory [i]=ConnectDialog->TcpHistory [i]; +void __fastcall TPlot::MenuPortClick(TObject *Sender) { + int i; + + trace(3, "MenuPortClick\n"); + + ConnectDialog->Stream1 = RtStream[0]; + ConnectDialog->Stream2 = RtStream[1]; + ConnectDialog->Format1 = RtFormat[0]; + ConnectDialog->Format2 = RtFormat[1]; + ConnectDialog->TimeForm = RtTimeForm; + ConnectDialog->DegForm = RtDegForm; + ConnectDialog->FieldSep = RtFieldSep; + ConnectDialog->TimeOutTime = RtTimeOutTime; + ConnectDialog->ReConnTime = RtReConnTime; + for (i = 0; i < 3; i++) { + ConnectDialog->Paths1[i] = StrPaths[0][i]; + ConnectDialog->Paths2[i] = StrPaths[1][i]; + } + for (i = 0; i < 2; i++) { + ConnectDialog->Cmds1[i] = StrCmds[0][i]; + ConnectDialog->Cmds2[i] = StrCmds[1][i]; + ConnectDialog->CmdEna1[i] = StrCmdEna[0][i]; + ConnectDialog->CmdEna2[i] = StrCmdEna[1][i]; + } + for (i = 0; i < 10; i++) ConnectDialog->TcpHistory[i] = StrHistory[i]; + + if (ConnectDialog->ShowModal() != mrOk) return; + + RtStream[0] = ConnectDialog->Stream1; + RtStream[1] = ConnectDialog->Stream2; + RtFormat[0] = ConnectDialog->Format1; + RtFormat[1] = ConnectDialog->Format2; + RtTimeForm = ConnectDialog->TimeForm; + RtDegForm = ConnectDialog->DegForm; + RtFieldSep = ConnectDialog->FieldSep; + RtTimeOutTime = ConnectDialog->TimeOutTime; + RtReConnTime = ConnectDialog->ReConnTime; + for (i = 0; i < 3; i++) { + StrPaths[0][i] = ConnectDialog->Paths1[i]; + StrPaths[1][i] = ConnectDialog->Paths2[i]; + } + for (i = 0; i < 2; i++) { + StrCmds[0][i] = ConnectDialog->Cmds1[i]; + StrCmds[1][i] = ConnectDialog->Cmds2[i]; + StrCmdEna[0][i] = ConnectDialog->CmdEna1[i]; + StrCmdEna[1][i] = ConnectDialog->CmdEna2[i]; + } + for (i = 0; i < 10; i++) StrHistory[i] = ConnectDialog->TcpHistory[i]; } // callback on menu-reload -------------------------------------------------- -void __fastcall TPlot::MenuReloadClick(TObject *Sender) -{ - trace(3,"MenuReloadClick\n"); - - Reload(); +void __fastcall TPlot::MenuReloadClick(TObject *Sender) { + trace(3, "MenuReloadClick\n"); + + Reload(); } // callback on menu-clear --------------------------------------------------- -void __fastcall TPlot::MenuClearClick(TObject *Sender) -{ - trace(3,"MenuClearClick\n"); - - Clear(); +void __fastcall TPlot::MenuClearClick(TObject *Sender) { + trace(3, "MenuClearClick\n"); + + Clear(); } // callback on menu-exit----------------------------------------------------- -void __fastcall TPlot::MenuQuitClick(TObject *Sender) -{ - trace(3,"MenuQuitClick\n"); - - Close(); +void __fastcall TPlot::MenuQuitClick(TObject *Sender) { + trace(3, "MenuQuitClick\n"); + + Close(); } // callback on menu-time-span/interval -------------------------------------- -void __fastcall TPlot::MenuTimeClick(TObject *Sender) -{ - sol_t *sols,*sole; - int i; - - trace(3,"MenuTimeClick\n"); - - if (!TimeEna[0]) { - if (Obs.n>0) { - TimeStart=Obs.data[0].time; - } - else if (BtnSol2->Down&&SolData[1].n>0) { - sols=getsol(SolData+1,0); - TimeStart=sols->time; - } - else if (SolData[0].n>0) { - sols=getsol(SolData,0); - TimeStart=sols->time; - } - } - if (!TimeEna[1]) { - if (Obs.n>0) { - TimeEnd=Obs.data[Obs.n-1].time; - } - else if (BtnSol2->Down&&SolData[1].n>0) { - sole=getsol(SolData+1,SolData[1].n-1); - TimeEnd=sole->time; - } - else if (SolData[0].n>0) { - sole=getsol(SolData,SolData[0].n-1); - TimeEnd=sole->time; - } - } - for (i=0;i<3;i++) { - SpanDialog->TimeEna[i]=TimeEna[i]; - } - SpanDialog->TimeStart=TimeStart; - SpanDialog->TimeEnd =TimeEnd; - SpanDialog->TimeInt =TimeInt; - SpanDialog->TimeVal[0]=!ConnectState; - SpanDialog->TimeVal[1]=!ConnectState; - - if (SpanDialog->ShowModal()!=mrOk) return; - - if (TimeEna[0]!=SpanDialog->TimeEna[0]|| - TimeEna[1]!=SpanDialog->TimeEna[1]|| - TimeEna[2]!=SpanDialog->TimeEna[2]|| - timediff(TimeStart,SpanDialog->TimeStart)!=0.0|| - timediff(TimeEnd,SpanDialog->TimeEnd)!=0.0|| - TimeInt!=SpanDialog->TimeInt) { - - for (i=0;i<3;i++) TimeEna[i]=SpanDialog->TimeEna[i]; - - TimeStart=SpanDialog->TimeStart; - TimeEnd =SpanDialog->TimeEnd; - TimeInt =SpanDialog->TimeInt; - - Reload(); - } +void __fastcall TPlot::MenuTimeClick(TObject *Sender) { + sol_t *sols, *sole; + int i; + + trace(3, "MenuTimeClick\n"); + + if (!TimeEna[0]) { + if (Obs.n > 0) { + TimeStart = Obs.data[0].time; + } else if (BtnSol2->Down && SolData[1].n > 0) { + sols = getsol(SolData + 1, 0); + TimeStart = sols->time; + } else if (SolData[0].n > 0) { + sols = getsol(SolData, 0); + TimeStart = sols->time; + } + } + if (!TimeEna[1]) { + if (Obs.n > 0) { + TimeEnd = Obs.data[Obs.n - 1].time; + } else if (BtnSol2->Down && SolData[1].n > 0) { + sole = getsol(SolData + 1, SolData[1].n - 1); + TimeEnd = sole->time; + } else if (SolData[0].n > 0) { + sole = getsol(SolData, SolData[0].n - 1); + TimeEnd = sole->time; + } + } + for (i = 0; i < 3; i++) { + SpanDialog->TimeEna[i] = TimeEna[i]; + } + SpanDialog->TimeStart = TimeStart; + SpanDialog->TimeEnd = TimeEnd; + SpanDialog->TimeInt = TimeInt; + SpanDialog->TimeVal[0] = !ConnectState; + SpanDialog->TimeVal[1] = !ConnectState; + + if (SpanDialog->ShowModal() != mrOk) return; + + if (TimeEna[0] != SpanDialog->TimeEna[0] || TimeEna[1] != SpanDialog->TimeEna[1] || + TimeEna[2] != SpanDialog->TimeEna[2] || timediff(TimeStart, SpanDialog->TimeStart) != 0.0 || + timediff(TimeEnd, SpanDialog->TimeEnd) != 0.0 || TimeInt != SpanDialog->TimeInt) { + for (i = 0; i < 3; i++) TimeEna[i] = SpanDialog->TimeEna[i]; + + TimeStart = SpanDialog->TimeStart; + TimeEnd = SpanDialog->TimeEnd; + TimeInt = SpanDialog->TimeInt; + + Reload(); + } } // callback on menu-map-image ----------------------------------------------- -void __fastcall TPlot::MenuMapImgClick(TObject *Sender) -{ - trace(3,"MenuMapImgClick\n"); - - MapOptDialog->Show(); +void __fastcall TPlot::MenuMapImgClick(TObject *Sender) { + trace(3, "MenuMapImgClick\n"); + + MapOptDialog->Show(); } // callback on menu-sky image ----------------------------------------------- -void __fastcall TPlot::MenuSkyImgClick(TObject *Sender) -{ - trace(3,"MenuSkyImgClick\n"); - - SkyImgDialog->Show(); +void __fastcall TPlot::MenuSkyImgClick(TObject *Sender) { + trace(3, "MenuSkyImgClick\n"); + + SkyImgDialog->Show(); } // callback on menu-vec map ------------------------------------------------- -void __fastcall TPlot::MenuMapLayerClick(TObject *Sender) -{ - trace(3,"MenuMapLayerClick\n"); - - VecMapDialog->Show(); +void __fastcall TPlot::MenuMapLayerClick(TObject *Sender) { + trace(3, "MenuMapLayerClick\n"); + + VecMapDialog->Show(); } // callback on menu-solution-source ----------------------------------------- -void __fastcall TPlot::MenuSrcSolClick(TObject *Sender) -{ - TTextViewer *viewer=new TTextViewer(Application); - int sel=!BtnSol1->Down&&BtnSol2->Down; - - trace(3,"MenuSrcSolClick\n"); - - if (SolFiles[sel]->Count<=0) return; - viewer->Caption=SolFiles[sel]->Strings[0]; - viewer->Option=0; - viewer->Show(); - viewer->Read(SolFiles[sel]->Strings[0]); +void __fastcall TPlot::MenuSrcSolClick(TObject *Sender) { + TTextViewer *viewer = new TTextViewer(Application); + int sel = !BtnSol1->Down && BtnSol2->Down; + + trace(3, "MenuSrcSolClick\n"); + + if (SolFiles[sel]->Count <= 0) return; + viewer->Caption = SolFiles[sel]->Strings[0]; + viewer->Option = 0; + viewer->Show(); + viewer->Read(SolFiles[sel]->Strings[0]); } // callback on menu-obs-data-source ----------------------------------------- -void __fastcall TPlot::MenuSrcObsClick(TObject *Sender) -{ - TTextViewer *viewer; - AnsiString file; - char tmpfile[1024]; - int cstat; - - trace(3,"MenuSrcObsClick\n"); - - if (ObsFiles->Count<=0) return; - - file=ObsFiles->Strings[0]; - cstat=rtk_uncompress(file.c_str(),tmpfile); - viewer=new TTextViewer(Application); - viewer->Caption=ObsFiles->Strings[0]; - viewer->Option=0; - viewer->Show(); - viewer->Read(!cstat?file:tmpfile); - if (cstat) remove(tmpfile); +void __fastcall TPlot::MenuSrcObsClick(TObject *Sender) { + TTextViewer *viewer; + AnsiString file; + char tmpfile[1024]; + int cstat; + + trace(3, "MenuSrcObsClick\n"); + + if (ObsFiles->Count <= 0) return; + + file = ObsFiles->Strings[0]; + cstat = rtk_uncompress(file.c_str(), tmpfile); + viewer = new TTextViewer(Application); + viewer->Caption = ObsFiles->Strings[0]; + viewer->Option = 0; + viewer->Show(); + viewer->Read(!cstat ? file : tmpfile); + if (cstat) remove(tmpfile); } // callback on menu-copy-to-clipboard --------------------------------------- -void __fastcall TPlot::MenyCopyClick(TObject *Sender) -{ - trace(3,"MenuCopyClick\n"); - - Clipboard()->Assign(Buff); +void __fastcall TPlot::MenyCopyClick(TObject *Sender) { + trace(3, "MenuCopyClick\n"); + + Clipboard()->Assign(Buff); } // callback on menu-options ------------------------------------------------- -void __fastcall TPlot::MenuOptionsClick(TObject *Sender) -{ - AnsiString tlefile=TLEFile,tlesatfile=TLESatFile; - double oopos[3]; - int timesyncout=TimeSyncOut,rcvpos=RcvPos; - - trace(3,"MenuOptionsClick\n"); - - matcpy(oopos,OOPos,3,1); - PlotOptDialog->Left=Left+Width/2-PlotOptDialog->Width/2; - PlotOptDialog->Top=Top+Height/2-PlotOptDialog->Height/2; - PlotOptDialog->Plot=this; - - if (PlotOptDialog->ShowModal()!=mrOk) return; - - SaveOpt(); - - for (int i=0;i<3;i++) oopos[i]-=OOPos[i]; - - if (TLEFile!=tlefile) { - free(TLEData.data); - TLEData.data=NULL; - TLEData.n=TLEData.nmax=0; - tle_read(TLEFile.c_str(),&TLEData); - } - if (TLEFile!=tlefile||TLESatFile!=tlesatfile) { - tle_name_read(TLESatFile.c_str(),&TLEData); - } - if (rcvpos!=RcvPos||norm(oopos,3)>1E-3||TLEFile!=tlefile) { - if (SimObs) GenVisData(); else UpdateObs(NObs); - } - UpdateColor(); - UpdateSize(); - UpdateOrigin(); - UpdateInfo(); - UpdateSatMask(); - UpdateSatList(); - Refresh(); - Timer->Interval=RefCycle; - - for (int i=0;iCount;i++) { - AnsiString str=RangeList->Items->Strings[i]; - double range; - char unit[32]=""; - - if (sscanf(str.c_str(),"%lf%31s",&range,unit)<1) continue; - if (!strcmp(unit,"cm")) range*=0.01; - else if (!strcmp(unit,"km")) range*=1000.0; - if (range==YRange) { - RangeList->Selected[i]=true; - break; - } - } - if (!timesyncout&&TimeSyncOut) { - char path[256]; - sprintf(path,":%d",TimeSyncPort); - stropen(&StrTimeSync,STR_TCPSVR,STR_MODE_RW,path); - } - else if (timesyncout&&!TimeSyncOut) { - strclose(&StrTimeSync); - } +void __fastcall TPlot::MenuOptionsClick(TObject *Sender) { + AnsiString tlefile = TLEFile, tlesatfile = TLESatFile; + double oopos[3]; + int timesyncout = TimeSyncOut, rcvpos = RcvPos; + + trace(3, "MenuOptionsClick\n"); + + matcpy(oopos, OOPos, 3, 1); + PlotOptDialog->Left = Left + Width / 2 - PlotOptDialog->Width / 2; + PlotOptDialog->Top = Top + Height / 2 - PlotOptDialog->Height / 2; + PlotOptDialog->Plot = this; + + if (PlotOptDialog->ShowModal() != mrOk) return; + + SaveOpt(); + + for (int i = 0; i < 3; i++) oopos[i] -= OOPos[i]; + + if (TLEFile != tlefile) { + free(TLEData.data); + TLEData.data = NULL; + TLEData.n = TLEData.nmax = 0; + tle_read(TLEFile.c_str(), &TLEData); + } + if (TLEFile != tlefile || TLESatFile != tlesatfile) { + tle_name_read(TLESatFile.c_str(), &TLEData); + } + if (rcvpos != RcvPos || norm(oopos, 3) > 1E-3 || TLEFile != tlefile) { + if (SimObs) + GenVisData(); + else + UpdateObs(NObs); + } + UpdateColor(); + UpdateSize(); + UpdateOrigin(); + UpdateInfo(); + UpdateSatMask(); + UpdateSatList(); + Refresh(); + Timer->Interval = RefCycle; + + for (int i = 0; i < RangeList->Count; i++) { + AnsiString str = RangeList->Items->Strings[i]; + double range; + char unit[32] = ""; + + if (sscanf(str.c_str(), "%lf%31s", &range, unit) < 1) continue; + if (!strcmp(unit, "cm")) + range *= 0.01; + else if (!strcmp(unit, "km")) + range *= 1000.0; + if (range == YRange) { + RangeList->Selected[i] = true; + break; + } + } + if (!timesyncout && TimeSyncOut) { + char path[256]; + sprintf(path, ":%d", TimeSyncPort); + stropen(&StrTimeSync, STR_TCPSVR, STR_MODE_RW, path); + } else if (timesyncout && !TimeSyncOut) { + strclose(&StrTimeSync); + } } // callback on menu-show-tool-bar ------------------------------------------- -void __fastcall TPlot::MenuToolBarClick(TObject *Sender) -{ - trace(3,"MenuToolBarClick\n"); - - MenuToolBar->Checked=!MenuToolBar->Checked; - Panel1->Visible=MenuToolBar->Checked; - UpdateSize(); - Refresh(); +void __fastcall TPlot::MenuToolBarClick(TObject *Sender) { + trace(3, "MenuToolBarClick\n"); + + MenuToolBar->Checked = !MenuToolBar->Checked; + Panel1->Visible = MenuToolBar->Checked; + UpdateSize(); + Refresh(); } // callback on menu-show-status-bar ----------------------------------------- -void __fastcall TPlot::MenuStatusBarClick(TObject *Sender) -{ - trace(3,"MenuStatusBarClick\n"); - - MenuStatusBar->Checked=!MenuStatusBar->Checked; - Panel2->Visible=MenuStatusBar->Checked; - UpdateSize(); - Refresh(); +void __fastcall TPlot::MenuStatusBarClick(TObject *Sender) { + trace(3, "MenuStatusBarClick\n"); + + MenuStatusBar->Checked = !MenuStatusBar->Checked; + Panel2->Visible = MenuStatusBar->Checked; + UpdateSize(); + Refresh(); } // callback on menu-show-browse-panel --------------------------------------- -void __fastcall TPlot::MenuBrowseClick(TObject *Sender) -{ - trace(3,"MenuBrowseClick\n"); - - MenuBrowse->Checked=!MenuBrowse->Checked; - if (MenuBrowse->Checked) { - Splitter1->Left=PanelBrowse->Width; - PanelBrowse->Visible=true; - Splitter1->Visible=true; - } - else { - PanelBrowse->Visible=false; - Splitter1->Visible=false; - } - UpdateSize(); - Refresh(); +void __fastcall TPlot::MenuBrowseClick(TObject *Sender) { + trace(3, "MenuBrowseClick\n"); + + MenuBrowse->Checked = !MenuBrowse->Checked; + if (MenuBrowse->Checked) { + Splitter1->Left = PanelBrowse->Width; + PanelBrowse->Visible = true; + Splitter1->Visible = true; + } else { + PanelBrowse->Visible = false; + Splitter1->Visible = false; + } + UpdateSize(); + Refresh(); } // callback on menu-waypoints ----------------------------------------------- -void __fastcall TPlot::MenuWaypointClick(TObject *Sender) -{ - trace(3,"MenuWaypointClick\n"); - - PntDialog->Show(); +void __fastcall TPlot::MenuWaypointClick(TObject *Sender) { + trace(3, "MenuWaypointClick\n"); + + PntDialog->Show(); } // callback on menu-input-monitor-1 ----------------------------------------- -void __fastcall TPlot::MenuMonitor1Click(TObject *Sender) -{ - trace(3,"MenuMonitor1Click\n"); - - Console1->Caption="Monitor RT Input 1"; - Console1->Show(); +void __fastcall TPlot::MenuMonitor1Click(TObject *Sender) { + trace(3, "MenuMonitor1Click\n"); + + Console1->Caption = "Monitor RT Input 1"; + Console1->Show(); } // callback on menu-input-monitor-2 ----------------------------------------- -void __fastcall TPlot::MenuMonitor2Click(TObject *Sender) -{ - trace(3,"MenuMonitor2Click\n"); - - Console2->Caption="Monitor RT Input 2"; - Console2->Show(); +void __fastcall TPlot::MenuMonitor2Click(TObject *Sender) { + trace(3, "MenuMonitor2Click\n"); + + Console2->Caption = "Monitor RT Input 2"; + Console2->Show(); } // callback on menu-google-map-view ----------------------------------------- -void __fastcall TPlot::MenuMapViewClick(TObject *Sender) -{ - AnsiString s; - - MapView->Caption= - s.sprintf("%s-%s %s: Map View",PRGNAME,VER_RTKLIB,PATCH_LEVEL); - MapView->Show(); +void __fastcall TPlot::MenuMapViewClick(TObject *Sender) { + AnsiString s; + + MapView->Caption = s.sprintf("%s-%s %s: Map View", PRGNAME, VER_RTKLIB, PATCH_LEVEL); + MapView->Show(); } // callback on menu-center-origin ------------------------------------------- -void __fastcall TPlot::MenuCenterOriClick(TObject *Sender) -{ - trace(3,"MenuCenterOriClick\n"); - - SetRange(0,YRange); - Refresh(); +void __fastcall TPlot::MenuCenterOriClick(TObject *Sender) { + trace(3, "MenuCenterOriClick\n"); + + SetRange(0, YRange); + Refresh(); } // callback on menu-fit-horizontal ------------------------------------------ -void __fastcall TPlot::MenuFitHorizClick(TObject *Sender) -{ - trace(3,"MenuFitHorizClick\n"); - - if (PlotType==PLOT_TRK) FitRange(0); else FitTime(); - Refresh(); +void __fastcall TPlot::MenuFitHorizClick(TObject *Sender) { + trace(3, "MenuFitHorizClick\n"); + + if (PlotType == PLOT_TRK) + FitRange(0); + else + FitTime(); + Refresh(); } // callback on menu-fit-vertical -------------------------------------------- -void __fastcall TPlot::MenuFitVertClick(TObject *Sender) -{ - trace(3,"MenuFitVertClick\n"); - - FitRange(0); - Refresh(); +void __fastcall TPlot::MenuFitVertClick(TObject *Sender) { + trace(3, "MenuFitVertClick\n"); + + FitRange(0); + Refresh(); } // callback on menu-show-skyplot -------------------------------------------- -void __fastcall TPlot::MenuShowSkyplotClick(TObject *Sender) -{ - trace(3,"MenuShowSkyplotClick\n"); - - BtnShowSkyplot->Down=!BtnShowSkyplot->Down; - UpdatePlot(); - UpdateEnable(); +void __fastcall TPlot::MenuShowSkyplotClick(TObject *Sender) { + trace(3, "MenuShowSkyplotClick\n"); + + BtnShowSkyplot->Down = !BtnShowSkyplot->Down; + UpdatePlot(); + UpdateEnable(); } // callback on menu-show-grid ----------------------------------------------- -void __fastcall TPlot::MenuShowGridClick(TObject *Sender) -{ - trace(3,"MenuShowGrid\n"); - - BtnShowGrid->Down=!BtnShowGrid->Down; - UpdatePlot(); - UpdateEnable(); +void __fastcall TPlot::MenuShowGridClick(TObject *Sender) { + trace(3, "MenuShowGrid\n"); + + BtnShowGrid->Down = !BtnShowGrid->Down; + UpdatePlot(); + UpdateEnable(); } // callback on menu-show-map-image ------------------------------------------ -void __fastcall TPlot::MenuShowImgClick(TObject *Sender) -{ - trace(3,"MenuShowImgClick\n"); - - BtnShowImg->Down=!BtnShowImg->Down; - UpdatePlot(); - UpdateEnable(); +void __fastcall TPlot::MenuShowImgClick(TObject *Sender) { + trace(3, "MenuShowImgClick\n"); + + BtnShowImg->Down = !BtnShowImg->Down; + UpdatePlot(); + UpdateEnable(); } // callback on menu-show-track-points --------------------------------------- -void __fastcall TPlot::MenuShowTrackClick(TObject *Sender) -{ - trace(3,"MenuShowTrackClick\n"); - - BtnShowTrack->Down=!BtnShowTrack->Down; - if (!BtnShowTrack->Down) { - BtnFixHoriz->Down=false; - BtnFixVert ->Down=false; - } - UpdatePlot(); - UpdateEnable(); +void __fastcall TPlot::MenuShowTrackClick(TObject *Sender) { + trace(3, "MenuShowTrackClick\n"); + + BtnShowTrack->Down = !BtnShowTrack->Down; + if (!BtnShowTrack->Down) { + BtnFixHoriz->Down = false; + BtnFixVert->Down = false; + } + UpdatePlot(); + UpdateEnable(); } // callback on menu-fix-center ---------------------------------------------- -void __fastcall TPlot::MenuFixCentClick(TObject *Sender) -{ - trace(3,"MenuFixCentClick\n"); - - BtnFixCent->Down=!BtnFixCent->Down; - UpdatePlot(); - UpdateEnable(); +void __fastcall TPlot::MenuFixCentClick(TObject *Sender) { + trace(3, "MenuFixCentClick\n"); + + BtnFixCent->Down = !BtnFixCent->Down; + UpdatePlot(); + UpdateEnable(); } // callback on menu-fix-horizontal ------------------------------------------ -void __fastcall TPlot::MenuFixHorizClick(TObject *Sender) -{ - trace(3,"MenuFixHorizClick\n"); - - BtnFixHoriz->Down=!BtnFixHoriz->Down; - Xcent=0.0; - UpdatePlot(); - UpdateEnable(); +void __fastcall TPlot::MenuFixHorizClick(TObject *Sender) { + trace(3, "MenuFixHorizClick\n"); + + BtnFixHoriz->Down = !BtnFixHoriz->Down; + Xcent = 0.0; + UpdatePlot(); + UpdateEnable(); } // callback on menu-fix-vertical -------------------------------------------- -void __fastcall TPlot::MenuFixVertClick(TObject *Sender) -{ - trace(3,"MenuFixVertClick\n"); - - BtnFixVert->Down=!BtnFixVert->Down; - UpdatePlot(); - UpdateEnable(); +void __fastcall TPlot::MenuFixVertClick(TObject *Sender) { + trace(3, "MenuFixVertClick\n"); + + BtnFixVert->Down = !BtnFixVert->Down; + UpdatePlot(); + UpdateEnable(); } // callback on menu-show-map ------------------------------------------------ -void __fastcall TPlot::MenuShowMapClick(TObject *Sender) -{ - trace(3,"MenuShowPointClick\n"); - - BtnShowMap->Down=!BtnShowMap->Down; +void __fastcall TPlot::MenuShowMapClick(TObject *Sender) { + trace(3, "MenuShowPointClick\n"); + + BtnShowMap->Down = !BtnShowMap->Down; - UpdatePlot(); - UpdateEnable(); + UpdatePlot(); + UpdateEnable(); } // callback on menu-animation-start ----------------------------------------- -void __fastcall TPlot::MenuAnimStartClick(TObject *Sender) -{ - trace(3,"MenuAnimStartClick\n"); - - BtnAnimate->Down=true; +void __fastcall TPlot::MenuAnimStartClick(TObject *Sender) { + trace(3, "MenuAnimStartClick\n"); + + BtnAnimate->Down = true; } // callback on menu-animation-stop ------------------------------------------ -void __fastcall TPlot::MenuAnimStopClick(TObject *Sender) -{ - trace(3,"MenuAnimStopClick\n"); - - BtnAnimate->Down=false; +void __fastcall TPlot::MenuAnimStopClick(TObject *Sender) { + trace(3, "MenuAnimStopClick\n"); + + BtnAnimate->Down = false; } // callback on menu-windows-maximize ---------------------------------------- -void __fastcall TPlot::MenuMaxClick(TObject *Sender) -{ - TRect rect; - ::SystemParametersInfo(SPI_GETWORKAREA,0,&rect,0); - Top=rect.Top; - Left=rect.Left; - Width=rect.Width(); - Height=rect.Height(); - MapView->Hide(); +void __fastcall TPlot::MenuMaxClick(TObject *Sender) { + TRect rect; + ::SystemParametersInfo(SPI_GETWORKAREA, 0, &rect, 0); + Top = rect.Top; + Left = rect.Left; + Width = rect.Width(); + Height = rect.Height(); + MapView->Hide(); } // callback on menu-windows-plot-mapview ------------------------------------ -void __fastcall TPlot::MenuPlotMapViewClick(TObject *Sender) -{ - TRect rect; - ::SystemParametersInfo(SPI_GETWORKAREA,0,&rect,0); - Top=rect.Top; - Left=rect.Left; - Width=rect.Width()/2; - Height=rect.Height(); - MapView->Top=Top; - MapView->Left=Width; - MapView->Width=Width; - MapView->Height=Height; - MapView->Show(); +void __fastcall TPlot::MenuPlotMapViewClick(TObject *Sender) { + TRect rect; + ::SystemParametersInfo(SPI_GETWORKAREA, 0, &rect, 0); + Top = rect.Top; + Left = rect.Left; + Width = rect.Width() / 2; + Height = rect.Height(); + MapView->Top = Top; + MapView->Left = Width; + MapView->Width = Width; + MapView->Height = Height; + MapView->Show(); } void __fastcall TPlot::DispGesture(TObject *Sender, const TGestureEventInfo &EventInfo, - bool &Handled) -{ + bool &Handled) { #ifdef RTK_DISABLED - AnsiString s; - int b,e; - - b=EventInfo.Flags.Contains(gfBegin); - e=EventInfo.Flags.Contains(gfEnd); - - if (EventInfo.GestureID==Controls::igiZoom) { - s.sprintf("zoom: Location=%d,%d,Flag=%d,%d,Angle=%.1f,Disnance=%d", - EventInfo.Location.X,EventInfo.Location.Y,b,e, - EventInfo.Angle,EventInfo.Distance); - Message1->Caption=s; - } - else if (EventInfo.GestureID==Controls::igiPan) { - s.sprintf("pan: Location=%d,%d,Flag=%d,%d,Angle=%.1f,Disnance=%d", - EventInfo.Location.X,EventInfo.Location.Y,b,e, - EventInfo.Angle,EventInfo.Distance); - Message1->Caption=s; - } - else if (EventInfo.GestureID==Controls::igiRotate) { - s.sprintf("rotate: Location=%d,%d,Flag=%d,%d,Angle=%.1f,Disnance=%d", - EventInfo.Location.X,EventInfo.Location.Y,b,e, - EventInfo.Angle,EventInfo.Distance); - Message1->Caption=s; - } + AnsiString s; + int b, e; + + b = EventInfo.Flags.Contains(gfBegin); + e = EventInfo.Flags.Contains(gfEnd); + + if (EventInfo.GestureID == Controls::igiZoom) { + s.sprintf("zoom: Location=%d,%d,Flag=%d,%d,Angle=%.1f,Disnance=%d", EventInfo.Location.X, + EventInfo.Location.Y, b, e, EventInfo.Angle, EventInfo.Distance); + Message1->Caption = s; + } else if (EventInfo.GestureID == Controls::igiPan) { + s.sprintf("pan: Location=%d,%d,Flag=%d,%d,Angle=%.1f,Disnance=%d", EventInfo.Location.X, + EventInfo.Location.Y, b, e, EventInfo.Angle, EventInfo.Distance); + Message1->Caption = s; + } else if (EventInfo.GestureID == Controls::igiRotate) { + s.sprintf("rotate: Location=%d,%d,Flag=%d,%d,Angle=%.1f,Disnance=%d", EventInfo.Location.X, + EventInfo.Location.Y, b, e, EventInfo.Angle, EventInfo.Distance); + Message1->Caption = s; + } #endif } // callback on menu-about --------------------------------------------------- -void __fastcall TPlot::MenuAboutClick(TObject *Sender) -{ - trace(3,"MenuAboutClick\n"); - - AboutDialog->About=PRGNAME; - AboutDialog->IconIndex=2; - AboutDialog->ShowModal(); +void __fastcall TPlot::MenuAboutClick(TObject *Sender) { + trace(3, "MenuAboutClick\n"); + + AboutDialog->About = PRGNAME; + AboutDialog->IconIndex = 2; + AboutDialog->ShowModal(); } // callback on button-connect/disconnect ------------------------------------ -void __fastcall TPlot::BtnConnectClick(TObject *Sender) -{ - trace(3,"BtnConnectClick\n"); - - if (!ConnectState) MenuConnectClick(Sender); - else MenuDisconnectClick(Sender); +void __fastcall TPlot::BtnConnectClick(TObject *Sender) { + trace(3, "BtnConnectClick\n"); + + if (!ConnectState) + MenuConnectClick(Sender); + else + MenuDisconnectClick(Sender); } // callback on button-solution-1 -------------------------------------------- -void __fastcall TPlot::BtnSol1Click(TObject *Sender) -{ - trace(3,"BtnSol1Click\n"); - - BtnSol12->Down=false; - UpdateTime(); - UpdatePlot(); - UpdateEnable(); +void __fastcall TPlot::BtnSol1Click(TObject *Sender) { + trace(3, "BtnSol1Click\n"); + + BtnSol12->Down = false; + UpdateTime(); + UpdatePlot(); + UpdateEnable(); } // callback on button-solution-2 -------------------------------------------- -void __fastcall TPlot::BtnSol2Click(TObject *Sender) -{ - trace(3,"BtnSol2Click\n"); - - BtnSol12->Down=false; - UpdateTime(); - UpdatePlot(); - UpdateEnable(); +void __fastcall TPlot::BtnSol2Click(TObject *Sender) { + trace(3, "BtnSol2Click\n"); + + BtnSol12->Down = false; + UpdateTime(); + UpdatePlot(); + UpdateEnable(); } // callback on button-solution-1-2 ------------------------------------------ -void __fastcall TPlot::BtnSol12Click(TObject *Sender) -{ - trace(3,"BtnSol12Click\n"); - - BtnSol1->Down=false; - BtnSol2->Down=false; - UpdateTime(); - UpdatePlot(); - UpdateEnable(); +void __fastcall TPlot::BtnSol12Click(TObject *Sender) { + trace(3, "BtnSol12Click\n"); + + BtnSol1->Down = false; + BtnSol2->Down = false; + UpdateTime(); + UpdatePlot(); + UpdateEnable(); } // callback on button-solution-1 double-click ------------------------------- -void __fastcall TPlot::BtnSol1DblClick(TObject *Sender) -{ - trace(3,"BtnSol1DblClick\n"); - - MenuOpenSol1Click(Sender); +void __fastcall TPlot::BtnSol1DblClick(TObject *Sender) { + trace(3, "BtnSol1DblClick\n"); + + MenuOpenSol1Click(Sender); } // callback on button-solution-2 double-click ------------------------------- -void __fastcall TPlot::BtnSol2DblClick(TObject *Sender) -{ - trace(3,"BtnSol2DblClick\n"); - - MenuOpenSol2Click(Sender); +void __fastcall TPlot::BtnSol2DblClick(TObject *Sender) { + trace(3, "BtnSol2DblClick\n"); + + MenuOpenSol2Click(Sender); } // callback on button-show-map-image ---------------------------------------- -void __fastcall TPlot::BtnShowImgClick(TObject *Sender) -{ - trace(3,"BtnShowMapClick\n"); - - UpdateEnable(); - Refresh(); +void __fastcall TPlot::BtnShowImgClick(TObject *Sender) { + trace(3, "BtnShowMapClick\n"); + + UpdateEnable(); + Refresh(); } //--------------------------------------------------------------------------- -void __fastcall TPlot::BtnShowSkyplotClick(TObject *Sender) -{ - trace(3,"BtnShowSkyplotClick\n"); - - UpdateEnable(); - Refresh(); +void __fastcall TPlot::BtnShowSkyplotClick(TObject *Sender) { + trace(3, "BtnShowSkyplotClick\n"); + + UpdateEnable(); + Refresh(); } //--------------------------------------------------------------------------- -void __fastcall TPlot::BtnShowGridClick(TObject *Sender) -{ - trace(3,"BtnShowGridClick\n"); - - UpdateEnable(); - Refresh(); +void __fastcall TPlot::BtnShowGridClick(TObject *Sender) { + trace(3, "BtnShowGridClick\n"); + + UpdateEnable(); + Refresh(); } // callback on button-plot-1-onoff ------------------------------------------ -void __fastcall TPlot::BtnOn1Click(TObject *Sender) -{ - trace(3,"BtnOn1Click\n"); - - UpdateSize(); - Refresh(); +void __fastcall TPlot::BtnOn1Click(TObject *Sender) { + trace(3, "BtnOn1Click\n"); + + UpdateSize(); + Refresh(); } // callback on button-plot-2-onoff------------------------------------------- -void __fastcall TPlot::BtnOn2Click(TObject *Sender) -{ - trace(3,"BtnOn2Click\n"); - - UpdateSize(); - Refresh(); +void __fastcall TPlot::BtnOn2Click(TObject *Sender) { + trace(3, "BtnOn2Click\n"); + + UpdateSize(); + Refresh(); } // callback on button-plot-3-onoff ------------------------------------------ -void __fastcall TPlot::BtnOn3Click(TObject *Sender) -{ - trace(3,"BtnOn3Click\n"); - - UpdateSize(); - Refresh(); +void __fastcall TPlot::BtnOn3Click(TObject *Sender) { + trace(3, "BtnOn3Click\n"); + + UpdateSize(); + Refresh(); } // callback on button-range-list -------------------------------------------- -void __fastcall TPlot::BtnRangeListClick(TObject *Sender) -{ - TSpeedButton *btn=(TSpeedButton *)Sender; +void __fastcall TPlot::BtnRangeListClick(TObject *Sender) { + TSpeedButton *btn = (TSpeedButton *)Sender; + + trace(3, "BtnRangeListClick\n"); - trace(3,"BtnRangeListClick\n"); - - RangeList->Left=btn->Parent->Left+btn->Left+btn->Width-RangeList->Width; - RangeList->Height=RangeList->ItemHeight*RangeList->Items->Count+2; - RangeList->Visible=!RangeList->Visible; + RangeList->Left = btn->Parent->Left + btn->Left + btn->Width - RangeList->Width; + RangeList->Height = RangeList->ItemHeight * RangeList->Items->Count + 2; + RangeList->Visible = !RangeList->Visible; } // callback on button-range-list -------------------------------------------- -void __fastcall TPlot::RangeListClick(TObject *Sender) -{ - AnsiString str; - char unit[32]=""; - int i; - - trace(3,"RangeListClick\n"); - - RangeList->Visible=false; - if ((i=RangeList->ItemIndex)<0) return; - - str=RangeList->Items->Strings[i]; - if (sscanf(str.c_str(),"%lf%31s",&YRange,unit)<1) return; - if (!strcmp(unit,"cm")) YRange*=0.01; - else if (!strcmp(unit,"km")) YRange*=1000.0; - - SetRange(0,YRange); - UpdatePlot(); - UpdateEnable(); +void __fastcall TPlot::RangeListClick(TObject *Sender) { + AnsiString str; + char unit[32] = ""; + int i; + + trace(3, "RangeListClick\n"); + + RangeList->Visible = false; + if ((i = RangeList->ItemIndex) < 0) return; + + str = RangeList->Items->Strings[i]; + if (sscanf(str.c_str(), "%lf%31s", &YRange, unit) < 1) return; + if (!strcmp(unit, "cm")) + YRange *= 0.01; + else if (!strcmp(unit, "km")) + YRange *= 1000.0; + + SetRange(0, YRange); + UpdatePlot(); + UpdateEnable(); } // callback on button-center-origin ----------------------------------------- -void __fastcall TPlot::BtnCenterOriClick(TObject *Sender) -{ - trace(3,"BtnCenterOriClick\n"); - - RangeList->Visible=false; - MenuCenterOriClick(Sender); +void __fastcall TPlot::BtnCenterOriClick(TObject *Sender) { + trace(3, "BtnCenterOriClick\n"); + + RangeList->Visible = false; + MenuCenterOriClick(Sender); } // callback on button-fit-horzontal------------------------------------------ -void __fastcall TPlot::BtnFitHorizClick(TObject *Sender) -{ - trace(3,"BtnFitHorizClick\n"); - - MenuFitHorizClick(Sender); +void __fastcall TPlot::BtnFitHorizClick(TObject *Sender) { + trace(3, "BtnFitHorizClick\n"); + + MenuFitHorizClick(Sender); } // callback on button-fit-vertical ------------------------------------------ -void __fastcall TPlot::BtnFitVertClick(TObject *Sender) -{ - trace(3,"BtnFitVertClick\n"); - - MenuFitVertClick(Sender); +void __fastcall TPlot::BtnFitVertClick(TObject *Sender) { + trace(3, "BtnFitVertClick\n"); + + MenuFitVertClick(Sender); } // callback on button show-track-points ------------------------------------- -void __fastcall TPlot::BtnShowTrackClick(TObject *Sender) -{ - trace(3,"BtnShowTrackClick\n"); - - if (!BtnShowTrack->Down) { - BtnFixHoriz->Down=false; - BtnFixVert ->Down=false; - } - UpdatePlot(); - UpdateEnable(); +void __fastcall TPlot::BtnShowTrackClick(TObject *Sender) { + trace(3, "BtnShowTrackClick\n"); + + if (!BtnShowTrack->Down) { + BtnFixHoriz->Down = false; + BtnFixVert->Down = false; + } + UpdatePlot(); + UpdateEnable(); } // callback on button-fix-horizontal ---------------------------------------- -void __fastcall TPlot::BtnFixHorizClick(TObject *Sender) -{ - trace(3,"BtnFixHorizClick\n"); - - Xcent=0.0; - UpdatePlot(); - UpdateEnable(); +void __fastcall TPlot::BtnFixHorizClick(TObject *Sender) { + trace(3, "BtnFixHorizClick\n"); + + Xcent = 0.0; + UpdatePlot(); + UpdateEnable(); } // callback on button-fix-vertical ------------------------------------------ -void __fastcall TPlot::BtnFixVertClick(TObject *Sender) -{ - trace(3,"BtnFixVertClick\n"); - - UpdatePlot(); - UpdateEnable(); +void __fastcall TPlot::BtnFixVertClick(TObject *Sender) { + trace(3, "BtnFixVertClick\n"); + + UpdatePlot(); + UpdateEnable(); } // callback on button-fix-center -------------------------------------------- -void __fastcall TPlot::BtnFixCentClick(TObject *Sender) -{ - trace(3,"BtnFixCentClick\n"); - - UpdatePlot(); - UpdateEnable(); +void __fastcall TPlot::BtnFixCentClick(TObject *Sender) { + trace(3, "BtnFixCentClick\n"); + + UpdatePlot(); + UpdateEnable(); } // callback on button-show-waypoints ---------------------------------------- -void __fastcall TPlot::BtnShowMapClick(TObject *Sender) -{ - trace(3,"BtnShowPointClick\n"); - - UpdatePlot(); - UpdateEnable(); +void __fastcall TPlot::BtnShowMapClick(TObject *Sender) { + trace(3, "BtnShowPointClick\n"); + + UpdatePlot(); + UpdateEnable(); } // callback on button-options ----------------------------------------------- -void __fastcall TPlot::BtnOptionsClick(TObject *Sender) -{ - trace(3,"BtnOptionsClick\n"); - - MenuOptionsClick(Sender); +void __fastcall TPlot::BtnOptionsClick(TObject *Sender) { + trace(3, "BtnOptionsClick\n"); + + MenuOptionsClick(Sender); } // callback on button-gm-view ----------------------------------------------- -void __fastcall TPlot::BtnMapViewClick(TObject *Sender) -{ - trace(3,"BtnMapViewClick\n"); - - MenuMapViewClick(Sender); +void __fastcall TPlot::BtnMapViewClick(TObject *Sender) { + trace(3, "BtnMapViewClick\n"); + + MenuMapViewClick(Sender); } // callback on button-animation --------------------------------------------- -void __fastcall TPlot::BtnAnimateClick(TObject *Sender) -{ - trace(3,"BtnAnimateClick\n"); - - UpdateEnable(); +void __fastcall TPlot::BtnAnimateClick(TObject *Sender) { + trace(3, "BtnAnimateClick\n"); + + UpdateEnable(); } // callback on button-clear ------------------------------------------------- -void __fastcall TPlot::BtnClearClick(TObject *Sender) -{ - trace(3,"BtnClearClick\n"); - - MenuClearClick(Sender); +void __fastcall TPlot::BtnClearClick(TObject *Sender) { + trace(3, "BtnClearClick\n"); + + MenuClearClick(Sender); } // callback on button-reload ------------------------------------------------ -void __fastcall TPlot::BtnReloadClick(TObject *Sender) -{ - trace(3,"BtnReloadClick\n"); - - MenuReloadClick(Sender); +void __fastcall TPlot::BtnReloadClick(TObject *Sender) { + trace(3, "BtnReloadClick\n"); + + MenuReloadClick(Sender); } // callback on button-message 2 --------------------------------------------- -void __fastcall TPlot::BtnMessage2Click(TObject *Sender) -{ - if (++PointType>2) PointType=0; +void __fastcall TPlot::BtnMessage2Click(TObject *Sender) { + if (++PointType > 2) PointType = 0; } // callback on plot-type selection change ----------------------------------- -void __fastcall TPlot::PlotTypeSChange(TObject *Sender) -{ - int i; - - trace(3,"PlotTypeSChnage\n"); - - for (i=0;*PTypes[i];i++) { - if (PlotTypeS->Text==PTypes[i]) UpdateType(i); - } - UpdateTime(); - UpdatePlot(); - UpdateEnable(); +void __fastcall TPlot::PlotTypeSChange(TObject *Sender) { + int i; + + trace(3, "PlotTypeSChnage\n"); + + for (i = 0; *PTypes[i]; i++) { + if (PlotTypeS->Text == PTypes[i]) UpdateType(i); + } + UpdateTime(); + UpdatePlot(); + UpdateEnable(); } // callback on quality-flag selection change -------------------------------- -void __fastcall TPlot::QFlagChange(TObject *Sender) -{ - trace(3,"QFlagChange\n"); - - UpdatePlot(); - UpdateEnable(); +void __fastcall TPlot::QFlagChange(TObject *Sender) { + trace(3, "QFlagChange\n"); + + UpdatePlot(); + UpdateEnable(); } // callback on obs-type selection change ------------------------------------ -void __fastcall TPlot::ObsTypeChange(TObject *Sender) -{ - trace(3,"ObsTypeChange\n"); - - UpdatePlot(); - UpdateEnable(); +void __fastcall TPlot::ObsTypeChange(TObject *Sender) { + trace(3, "ObsTypeChange\n"); + + UpdatePlot(); + UpdateEnable(); } // callback on dop-type selection change ------------------------------------ -void __fastcall TPlot::DopTypeChange(TObject *Sender) -{ - trace(3,"DopTypeChange\n"); - - UpdatePlot(); - UpdateEnable(); +void __fastcall TPlot::DopTypeChange(TObject *Sender) { + trace(3, "DopTypeChange\n"); + + UpdatePlot(); + UpdateEnable(); } // callback on satellite-list selection change ------------------------------ -void __fastcall TPlot::SatListChange(TObject *Sender) -{ - trace(3,"SatListChange\n"); - - UpdateSatSel(); - UpdatePlot(); - UpdateEnable(); +void __fastcall TPlot::SatListChange(TObject *Sender) { + trace(3, "SatListChange\n"); + + UpdateSatSel(); + UpdatePlot(); + UpdateEnable(); } // callback on time scroll-bar change --------------------------------------- -void __fastcall TPlot::TimeScrollChange(TObject *Sender) -{ - int sel=!BtnSol1->Down&&BtnSol2->Down?1:0; - - trace(3,"TimeScrollChange\n"); - - if (PlotType<=PLOT_SDOP||PlotType==PLOT_RES) { - SolIndex[sel]=TimeScroll->Position; - } - else { - ObsIndex=TimeScroll->Position; - } - UpdatePlot(); +void __fastcall TPlot::TimeScrollChange(TObject *Sender) { + int sel = !BtnSol1->Down && BtnSol2->Down ? 1 : 0; + + trace(3, "TimeScrollChange\n"); + + if (PlotType <= PLOT_SDOP || PlotType == PLOT_RES) { + SolIndex[sel] = TimeScroll->Position; + } else { + ObsIndex = TimeScroll->Position; + } + UpdatePlot(); } // callback on paint -------------------------------------------------------- -void __fastcall TPlot::DispPaint(TObject *Sender) -{ - trace(3,"DispPaint\n"); - - UpdateDisp(); +void __fastcall TPlot::DispPaint(TObject *Sender) { + trace(3, "DispPaint\n"); + + UpdateDisp(); } // callback on mouse-down event --------------------------------------------- -void __fastcall TPlot::DispMouseDown(TObject *Sender, TMouseButton Button, - TShiftState Shift, int X, int Y) -{ - trace(3,"DispMouseDown: X=%d Y=%d\n",X,Y); - - X0=X; Y0=Y; Xcent0=Xcent; - - Drag=Shift.Contains(ssLeft)?1:(Shift.Contains(ssRight)?11:0); - - if (PlotType==PLOT_TRK) { - MouseDownTrk(X,Y); - } - else if (PlotType<=PLOT_SDOP||PlotType==PLOT_RES||PlotType==PLOT_SNR) { - MouseDownSol(X,Y); - } - else if (PlotType==PLOT_OBS||PlotType==PLOT_DOP) { - MouseDownObs(X,Y); - } - else Drag=0; - - RangeList->Visible=false; +void __fastcall TPlot::DispMouseDown(TObject *Sender, TMouseButton Button, TShiftState Shift, int X, + int Y) { + trace(3, "DispMouseDown: X=%d Y=%d\n", X, Y); + + X0 = X; + Y0 = Y; + Xcent0 = Xcent; + + Drag = Shift.Contains(ssLeft) ? 1 : (Shift.Contains(ssRight) ? 11 : 0); + + if (PlotType == PLOT_TRK) { + MouseDownTrk(X, Y); + } else if (PlotType <= PLOT_SDOP || PlotType == PLOT_RES || PlotType == PLOT_SNR) { + MouseDownSol(X, Y); + } else if (PlotType == PLOT_OBS || PlotType == PLOT_DOP) { + MouseDownObs(X, Y); + } else + Drag = 0; + + RangeList->Visible = false; } // callback on mouse-move event --------------------------------------------- -void __fastcall TPlot::DispMouseMove(TObject *Sender, TShiftState Shift, int X, int Y) -{ - double x,y,xs,ys,dx,dy,dxs,dys; - - if (X==Xn&&Y==Yn) return; - - trace(4,"DispMouseMove: X=%d Y=%d\n",X,Y); - - Xn=X; Yn=Y; - dx=(X0-X)*Xs; - dy=(Y-Y0)*Ys; - dxs=pow(2.0,(X0-X)/100.0); - dys=pow(2.0,(Y-Y0)/100.0); - - if (Drag==0) { - UpdatePoint(X,Y); - } - else if (PlotType==PLOT_TRK) { - MouseMoveTrk(X,Y,dx,dy,dxs,dys); - } - else if (PlotType<=PLOT_SDOP||PlotType==PLOT_RES||PlotType==PLOT_SNR) { - MouseMoveSol(X,Y,dx,dy,dxs,dys); - } - else if (PlotType==PLOT_OBS||PlotType==PLOT_DOP) { - MouseMoveObs(X,Y,dx,dy,dxs,dys); - } +void __fastcall TPlot::DispMouseMove(TObject *Sender, TShiftState Shift, int X, int Y) { + double x, y, xs, ys, dx, dy, dxs, dys; + + if (X == Xn && Y == Yn) return; + + trace(4, "DispMouseMove: X=%d Y=%d\n", X, Y); + + Xn = X; + Yn = Y; + dx = (X0 - X) * Xs; + dy = (Y - Y0) * Ys; + dxs = pow(2.0, (X0 - X) / 100.0); + dys = pow(2.0, (Y - Y0) / 100.0); + + if (Drag == 0) { + UpdatePoint(X, Y); + } else if (PlotType == PLOT_TRK) { + MouseMoveTrk(X, Y, dx, dy, dxs, dys); + } else if (PlotType <= PLOT_SDOP || PlotType == PLOT_RES || PlotType == PLOT_SNR) { + MouseMoveSol(X, Y, dx, dy, dxs, dys); + } else if (PlotType == PLOT_OBS || PlotType == PLOT_DOP) { + MouseMoveObs(X, Y, dx, dy, dxs, dys); + } } // callback on mouse-up event ----------------------------------------------- -void __fastcall TPlot::DispMouseUp(TObject *Sender, TMouseButton Button, - TShiftState Shift, int X, int Y) -{ - trace(3,"DispMouseUp: X=%d Y=%d\n",X,Y); - - Drag=0; - Screen->Cursor=crDefault; - Refresh(); - Refresh_MapView(); +void __fastcall TPlot::DispMouseUp(TObject *Sender, TMouseButton Button, TShiftState Shift, int X, + int Y) { + trace(3, "DispMouseUp: X=%d Y=%d\n", X, Y); + + Drag = 0; + Screen->Cursor = crDefault; + Refresh(); + Refresh_MapView(); } // callback on mouse-double-click ------------------------------------------- -void __fastcall TPlot::DispDblClick(TObject *Sender) -{ - TPoint p((int)X0,(int)Y0); - double x,y; - - trace(3,"DispDblClick X=%d Y=%d\n",p.x,p.y); - - if (BtnFixHoriz->Down) return; - - if (PlotType==PLOT_TRK) { - GraphT->ToPos(p,x,y); - GraphT->SetCent(x,y); - Refresh(); - Refresh_MapView(); - } - else if (PlotType<=PLOT_NSAT||PlotType==PLOT_RES||PlotType==PLOT_SNR) { - GraphG[0]->ToPos(p,x,y); - SetCentX(x); - Refresh(); - } - else if (PlotType==PLOT_OBS||PlotType==PLOT_DOP||PlotType==PLOT_SDOP) { - GraphR->ToPos(p,x,y); - SetCentX(x); - Refresh(); - } +void __fastcall TPlot::DispDblClick(TObject *Sender) { + TPoint p((int)X0, (int)Y0); + double x, y; + + trace(3, "DispDblClick X=%d Y=%d\n", p.x, p.y); + + if (BtnFixHoriz->Down) return; + + if (PlotType == PLOT_TRK) { + GraphT->ToPos(p, x, y); + GraphT->SetCent(x, y); + Refresh(); + Refresh_MapView(); + } else if (PlotType <= PLOT_NSAT || PlotType == PLOT_RES || PlotType == PLOT_SNR) { + GraphG[0]->ToPos(p, x, y); + SetCentX(x); + Refresh(); + } else if (PlotType == PLOT_OBS || PlotType == PLOT_DOP || PlotType == PLOT_SDOP) { + GraphR->ToPos(p, x, y); + SetCentX(x); + Refresh(); + } } // callback on mouse-leave event -------------------------------------------- -void __fastcall TPlot::DispMouseLeave(TObject *Sender) -{ - trace(3,"DispMouseLeave\n"); - - Xn=Yn=-1; - Panel22->Visible=false; - Message2->Caption=""; +void __fastcall TPlot::DispMouseLeave(TObject *Sender) { + trace(3, "DispMouseLeave\n"); + + Xn = Yn = -1; + Panel22->Visible = false; + Message2->Caption = ""; } // callback on mouse-down event on track-plot ------------------------------- -void __fastcall TPlot::MouseDownTrk(int X, int Y) -{ - int i,sel=!BtnSol1->Down&&BtnSol2->Down?1:0; - - trace(3,"MouseDownTrk: X=%d Y=%d\n",X,Y); - - if (Drag==1&&(i=SearchPos(X,Y))>=0) { - SolIndex[sel]=i; - UpdateTime(); - UpdateInfo(); - Drag=0; - Refresh(); - } - else { - GraphT->GetCent(Xc,Yc); - GraphT->GetScale(Xs,Ys); - Screen->Cursor=Drag==1?crSizeAll:crVSplit; - } +void __fastcall TPlot::MouseDownTrk(int X, int Y) { + int i, sel = !BtnSol1->Down && BtnSol2->Down ? 1 : 0; + + trace(3, "MouseDownTrk: X=%d Y=%d\n", X, Y); + + if (Drag == 1 && (i = SearchPos(X, Y)) >= 0) { + SolIndex[sel] = i; + UpdateTime(); + UpdateInfo(); + Drag = 0; + Refresh(); + } else { + GraphT->GetCent(Xc, Yc); + GraphT->GetScale(Xs, Ys); + Screen->Cursor = Drag == 1 ? crSizeAll : crVSplit; + } } // callback on mouse-down event on solution-plot ---------------------------- -void __fastcall TPlot::MouseDownSol(int X, int Y) -{ - TSpeedButton *btn[]={BtnOn1,BtnOn2,BtnOn3}; - TPoint pnt,p(X,Y); - gtime_t time={0}; - sol_t *data; - double x,xl[2],yl[2]; - int i,area=-1,sel=!BtnSol1->Down&&BtnSol2->Down?1:0; - - trace(3,"MouseDownSol: X=%d Y=%d\n",X,Y); - - if (PlotType==PLOT_SNR) { - if (0<=ObsIndex&&ObsIndextime; - } - if (time.time&&!BtnFixHoriz->Down) { - - x=TimePos(time); - - GraphG[0]->GetLim(xl,yl); - GraphG[0]->ToPoint(x,yl[1],pnt); - - if ((X-pnt.x)*(X-pnt.x)+(Y-pnt.y)*(Y-pnt.y)<25) { - Screen->Cursor=crSizeWE; - Drag=20; - Refresh(); - return; - } - } - for (i=0;i<3;i++) { - if (!btn[i]->Down||(i!=1&&PlotType==PLOT_SNR)) continue; - - GraphG[i]->GetCent(Xc,Yc); - GraphG[i]->GetScale(Xs,Ys); - area=GraphG[i]->OnAxis(p); - - if (Drag==1&&area==0) { - Screen->Cursor=crSizeAll; - Drag+=i; - return; - } - else if (area==1) { - Screen->Cursor=Drag==1?crSizeNS:crVSplit; - Drag+=i+4; - return; - } - else if (area==0) break; - } - if (area==0||area==8) { - Screen->Cursor=Drag==1?crSizeWE:crHSplit; - Drag+=3; - } - else Drag=0; +void __fastcall TPlot::MouseDownSol(int X, int Y) { + TSpeedButton *btn[] = {BtnOn1, BtnOn2, BtnOn3}; + TPoint pnt, p(X, Y); + gtime_t time = {0}; + sol_t *data; + double x, xl[2], yl[2]; + int i, area = -1, sel = !BtnSol1->Down && BtnSol2->Down ? 1 : 0; + + trace(3, "MouseDownSol: X=%d Y=%d\n", X, Y); + + if (PlotType == PLOT_SNR) { + if (0 <= ObsIndex && ObsIndex < NObs) time = Obs.data[IndexObs[ObsIndex]].time; + } else { + if ((data = getsol(SolData + sel, SolIndex[sel]))) time = data->time; + } + if (time.time && !BtnFixHoriz->Down) { + x = TimePos(time); + + GraphG[0]->GetLim(xl, yl); + GraphG[0]->ToPoint(x, yl[1], pnt); + + if ((X - pnt.x) * (X - pnt.x) + (Y - pnt.y) * (Y - pnt.y) < 25) { + Screen->Cursor = crSizeWE; + Drag = 20; + Refresh(); + return; + } + } + for (i = 0; i < 3; i++) { + if (!btn[i]->Down || (i != 1 && PlotType == PLOT_SNR)) continue; + + GraphG[i]->GetCent(Xc, Yc); + GraphG[i]->GetScale(Xs, Ys); + area = GraphG[i]->OnAxis(p); + + if (Drag == 1 && area == 0) { + Screen->Cursor = crSizeAll; + Drag += i; + return; + } else if (area == 1) { + Screen->Cursor = Drag == 1 ? crSizeNS : crVSplit; + Drag += i + 4; + return; + } else if (area == 0) + break; + } + if (area == 0 || area == 8) { + Screen->Cursor = Drag == 1 ? crSizeWE : crHSplit; + Drag += 3; + } else + Drag = 0; } // callback on mouse-down event on observation-data-plot -------------------- -void __fastcall TPlot::MouseDownObs(int X, int Y) -{ - TPoint pnt,p(X,Y); - double x,xl[2],yl[2]; - int area; - - trace(3,"MouseDownObs: X=%d Y=%d\n",X,Y); - - if (0<=ObsIndex&&ObsIndexDown) { - - x=TimePos(Obs.data[IndexObs[ObsIndex]].time); - - GraphR->GetLim(xl,yl); - GraphR->ToPoint(x,yl[1],pnt); - - if ((X-pnt.x)*(X-pnt.x)+(Y-pnt.y)*(Y-pnt.y)<25) { - Screen->Cursor=crSizeWE; - Drag=20; - Refresh(); - return; - } - } - GraphR->GetCent(Xc,Yc); - GraphR->GetScale(Xs,Ys); - area=GraphR->OnAxis(p); - - if (area==0||area==8) { - Screen->Cursor=Drag==1?crSizeWE:crHSplit; - Drag+=3; - } - else Drag=0; +void __fastcall TPlot::MouseDownObs(int X, int Y) { + TPoint pnt, p(X, Y); + double x, xl[2], yl[2]; + int area; + + trace(3, "MouseDownObs: X=%d Y=%d\n", X, Y); + + if (0 <= ObsIndex && ObsIndex < NObs && !BtnFixHoriz->Down) { + x = TimePos(Obs.data[IndexObs[ObsIndex]].time); + + GraphR->GetLim(xl, yl); + GraphR->ToPoint(x, yl[1], pnt); + + if ((X - pnt.x) * (X - pnt.x) + (Y - pnt.y) * (Y - pnt.y) < 25) { + Screen->Cursor = crSizeWE; + Drag = 20; + Refresh(); + return; + } + } + GraphR->GetCent(Xc, Yc); + GraphR->GetScale(Xs, Ys); + area = GraphR->OnAxis(p); + + if (area == 0 || area == 8) { + Screen->Cursor = Drag == 1 ? crSizeWE : crHSplit; + Drag += 3; + } else + Drag = 0; } // callback on mouse-move event on track-plot ------------------------------- -void __fastcall TPlot::MouseMoveTrk(int X, int Y, double dx, double dy, - double dxs, double dys) -{ - trace(4,"MouseMoveTrk: X=%d Y=%d\n",X,Y); - - if (Drag==1&&!BtnFixHoriz->Down) { - GraphT->SetCent(Xc+dx,Yc+dy); - } - else if (Drag>1) { - GraphT->SetScale(Xs*dys,Ys*dys); - } - BtnCenterOri->Down=false; - Refresh(); +void __fastcall TPlot::MouseMoveTrk(int X, int Y, double dx, double dy, double dxs, double dys) { + trace(4, "MouseMoveTrk: X=%d Y=%d\n", X, Y); + + if (Drag == 1 && !BtnFixHoriz->Down) { + GraphT->SetCent(Xc + dx, Yc + dy); + } else if (Drag > 1) { + GraphT->SetScale(Xs * dys, Ys * dys); + } + BtnCenterOri->Down = false; + Refresh(); } // callback on mouse-move event on solution-plot ---------------------------- -void __fastcall TPlot::MouseMoveSol(int X, int Y, double dx, double dy, - double dxs, double dys) -{ - TPoint p1,p2,p(X,Y); - double x,y,xs,ys; - int i,sel=!BtnSol1->Down&&BtnSol2->Down?1:0; - - trace(4,"MouseMoveSol: X=%d Y=%d\n",X,Y); - - if (Drag<=4) { - for (i=0;i<3;i++) { - GraphG[i]->GetCent(x,y); - if (!BtnFixHoriz->Down) { - x=Xc+dx; - } - if (!BtnFixVert->Down||!BtnFixVert->Enabled) { - y=i==Drag-1?Yc+dy:y; - } - GraphG[i]->SetCent(x,y); - SetCentX(x); - } - if (BtnFixHoriz->Down) { - GraphG[0]->GetPos(p1,p2); - Xcent=Xcent0+2.0*(X-X0)/(p2.x-p1.x); - if (Xcent> 1.0) Xcent= 1.0; - if (Xcent<-1.0) Xcent=-1.0; - } - } - else if (Drag<=7) { - GraphG[Drag-5]->GetCent(x,y); - if (!BtnFixVert->Down||!BtnFixVert->Enabled) { - y=Yc+dy; - } - GraphG[Drag-5]->SetCent(x,y); - } - else if (Drag<=14) { - for (i=0;i<3;i++) { - GraphG[i]->GetScale(xs,ys); - GraphG[i]->SetScale(Xs*dxs,ys); - } - SetScaleX(Xs*dxs); - } - else if (Drag<=17) { - GraphG[Drag-15]->GetScale(xs,ys); - GraphG[Drag-15]->SetScale(xs,Ys*dys); - } - else if (Drag==20) { - GraphG[0]->ToPos(p,x,y); - if (PlotType==PLOT_SNR) { - for (i=0;i=x) break; - } - ObsIndex=i=x) break; - } - SolIndex[sel]=iDown && BtnSol2->Down ? 1 : 0; + + trace(4, "MouseMoveSol: X=%d Y=%d\n", X, Y); + + if (Drag <= 4) { + for (i = 0; i < 3; i++) { + GraphG[i]->GetCent(x, y); + if (!BtnFixHoriz->Down) { + x = Xc + dx; + } + if (!BtnFixVert->Down || !BtnFixVert->Enabled) { + y = i == Drag - 1 ? Yc + dy : y; + } + GraphG[i]->SetCent(x, y); + SetCentX(x); + } + if (BtnFixHoriz->Down) { + GraphG[0]->GetPos(p1, p2); + Xcent = Xcent0 + 2.0 * (X - X0) / (p2.x - p1.x); + if (Xcent > 1.0) Xcent = 1.0; + if (Xcent < -1.0) Xcent = -1.0; + } + } else if (Drag <= 7) { + GraphG[Drag - 5]->GetCent(x, y); + if (!BtnFixVert->Down || !BtnFixVert->Enabled) { + y = Yc + dy; + } + GraphG[Drag - 5]->SetCent(x, y); + } else if (Drag <= 14) { + for (i = 0; i < 3; i++) { + GraphG[i]->GetScale(xs, ys); + GraphG[i]->SetScale(Xs * dxs, ys); + } + SetScaleX(Xs * dxs); + } else if (Drag <= 17) { + GraphG[Drag - 15]->GetScale(xs, ys); + GraphG[Drag - 15]->SetScale(xs, Ys * dys); + } else if (Drag == 20) { + GraphG[0]->ToPos(p, x, y); + if (PlotType == PLOT_SNR) { + for (i = 0; i < NObs; i++) { + if (TimePos(Obs.data[IndexObs[i]].time) >= x) break; + } + ObsIndex = i < NObs ? i : NObs - 1; + } else { + for (i = 0; i < SolData[sel].n; i++) { + if (TimePos(SolData[sel].data[i].time) >= x) break; + } + SolIndex[sel] = i < SolData[sel].n ? i : SolData[sel].n - 1; } - BtnCenterOri->Down=false; - Refresh(); + UpdateTime(); + } + BtnCenterOri->Down = false; + Refresh(); } // callback on mouse-move events on observataion-data-plot ------------------ -void __fastcall TPlot::MouseMoveObs(int X, int Y, double dx, double dy, - double dxs, double dys) -{ - TPoint p1,p2,p(X,Y); - double x,y,xs,ys; - int i; - - trace(4,"MouseMoveObs: X=%d Y=%d\n",X,Y); - - if (Drag<=4) { - GraphR->GetCent(x,y); - if (!BtnFixHoriz->Down) x=Xc+dx; - if (!BtnFixVert ->Down) y=Yc+dy; - GraphR->SetCent(x,y); - SetCentX(x); - - if (BtnFixHoriz->Down) { - GraphR->GetPos(p1,p2); - Xcent=Xcent0+2.0*(X-X0)/(p2.x-p1.x); - if (Xcent> 1.0) Xcent= 1.0; - if (Xcent<-1.0) Xcent=-1.0; - } - } - else if (Drag<=14) { - GraphR->GetScale(xs,ys); - GraphR->SetScale(Xs*dxs,ys); - SetScaleX(Xs*dxs); - } - else if (Drag==20) { - GraphR->ToPos(p,x,y); - for (i=0;i=x) break; - } - ObsIndex=iDown=false; - Refresh(); +void __fastcall TPlot::MouseMoveObs(int X, int Y, double dx, double dy, double dxs, double dys) { + TPoint p1, p2, p(X, Y); + double x, y, xs, ys; + int i; + + trace(4, "MouseMoveObs: X=%d Y=%d\n", X, Y); + + if (Drag <= 4) { + GraphR->GetCent(x, y); + if (!BtnFixHoriz->Down) x = Xc + dx; + if (!BtnFixVert->Down) y = Yc + dy; + GraphR->SetCent(x, y); + SetCentX(x); + + if (BtnFixHoriz->Down) { + GraphR->GetPos(p1, p2); + Xcent = Xcent0 + 2.0 * (X - X0) / (p2.x - p1.x); + if (Xcent > 1.0) Xcent = 1.0; + if (Xcent < -1.0) Xcent = -1.0; + } + } else if (Drag <= 14) { + GraphR->GetScale(xs, ys); + GraphR->SetScale(Xs * dxs, ys); + SetScaleX(Xs * dxs); + } else if (Drag == 20) { + GraphR->ToPos(p, x, y); + for (i = 0; i < NObs; i++) { + if (TimePos(Obs.data[IndexObs[i]].time) >= x) break; + } + ObsIndex = i < NObs ? i : NObs - 1; + UpdateTime(); + } + BtnCenterOri->Down = false; + Refresh(); } // callback on mouse-wheel events ------------------------------------------- -void __fastcall TPlot::MouseWheel(TObject *Sender, TShiftState Shift, - int WheelDelta, TPoint &MousePos, bool &Handled) -{ - TPoint p(Xn,Yn); - double xs,ys,ds=pow(2.0,-WheelDelta/1200.0); - int i,area=-1; - - Handled=true; - - trace(4,"MouseWheel: WheelDelta=%d\n",WheelDelta); - - if (Xn<0||Yn<0) return; - - if (PlotType==PLOT_TRK) { // track-plot - GraphT->GetScale(xs,ys); - GraphT->SetScale(xs*ds,ys*ds); - } - else if (PlotType<=PLOT_NSAT||PlotType==PLOT_RES||PlotType==PLOT_SNR) { - - for (i=0;i<3;i++) { - if (PlotType==PLOT_SNR&&i!=1) continue; - area=GraphG[i]->OnAxis(p); - if (area==0||area==1||area==2) { - GraphG[i]->GetScale(xs,ys); - GraphG[i]->SetScale(xs,ys*ds); - } - else if (area==0) break; - } - if (area==8) { - for (i=0;i<3;i++) { - GraphG[i]->GetScale(xs,ys); - GraphG[i]->SetScale(xs*ds,ys); - SetScaleX(xs*ds); - } - } - } - else if (PlotType==PLOT_OBS||PlotType==PLOT_DOP||PlotType==PLOT_SDOP) { - area=GraphR->OnAxis(p); - if (area==0||area==8) { - GraphR->GetScale(xs,ys); - GraphR->SetScale(xs*ds,ys); - SetScaleX(xs*ds); - } - } - else return; - - Refresh(); +void __fastcall TPlot::MouseWheel(TObject *Sender, TShiftState Shift, int WheelDelta, + TPoint &MousePos, bool &Handled) { + TPoint p(Xn, Yn); + double xs, ys, ds = pow(2.0, -WheelDelta / 1200.0); + int i, area = -1; + + Handled = true; + + trace(4, "MouseWheel: WheelDelta=%d\n", WheelDelta); + + if (Xn < 0 || Yn < 0) return; + + if (PlotType == PLOT_TRK) { // track-plot + GraphT->GetScale(xs, ys); + GraphT->SetScale(xs * ds, ys * ds); + } else if (PlotType <= PLOT_NSAT || PlotType == PLOT_RES || PlotType == PLOT_SNR) { + for (i = 0; i < 3; i++) { + if (PlotType == PLOT_SNR && i != 1) continue; + area = GraphG[i]->OnAxis(p); + if (area == 0 || area == 1 || area == 2) { + GraphG[i]->GetScale(xs, ys); + GraphG[i]->SetScale(xs, ys * ds); + } else if (area == 0) + break; + } + if (area == 8) { + for (i = 0; i < 3; i++) { + GraphG[i]->GetScale(xs, ys); + GraphG[i]->SetScale(xs * ds, ys); + SetScaleX(xs * ds); + } + } + } else if (PlotType == PLOT_OBS || PlotType == PLOT_DOP || PlotType == PLOT_SDOP) { + area = GraphR->OnAxis(p); + if (area == 0 || area == 8) { + GraphR->GetScale(xs, ys); + GraphR->SetScale(xs * ds, ys); + SetScaleX(xs * ds); + } + } else + return; + + Refresh(); } // callback on key-press events --------------------------------------------- -void __fastcall TPlot::CMDialogKey(Messages::TWMKey &Message) -{ - trace(3,"CMDialogKey:\n"); - - if (Message.CharCode!=VK_UP &&Message.CharCode!=VK_DOWN && - Message.CharCode!=VK_LEFT&&Message.CharCode!=VK_RIGHT) { - TForm::Dispatch(&Message); - } +void __fastcall TPlot::CMDialogKey(Messages::TWMKey &Message) { + trace(3, "CMDialogKey:\n"); + + if (Message.CharCode != VK_UP && Message.CharCode != VK_DOWN && Message.CharCode != VK_LEFT && + Message.CharCode != VK_RIGHT) { + TForm::Dispatch(&Message); + } } // callback on key-down events ---------------------------------------------- -void __fastcall TPlot::FormKeyDown(TObject *Sender, WORD &Key, - TShiftState Shift) -{ - double sfact=1.05,fact=Shift.Contains(ssShift)?1.0:10.0; - double xc,yc,yc1,yc2,yc3,xs,ys,ys1,ys2,ys3; - int key=Shift.Contains(ssCtrl)?10:0; - - trace(3,"FormKeyDown:\n"); - - switch (Key) { - case VK_UP : key+=1; break; - case VK_DOWN : key+=2; break; - case VK_LEFT : key+=3; break; - case VK_RIGHT: key+=4; break; - default: return; - } - if (Shift.Contains(ssAlt)) return; - - Key=0; // stop dispatch key event - - if (PlotType==PLOT_TRK) { - GraphT->GetCent(xc,yc); - GraphT->GetScale(xs,ys); - if (key== 1) {if (!BtnFixHoriz->Down) yc+=fact*ys;} - if (key== 2) {if (!BtnFixHoriz->Down) yc-=fact*ys;} - if (key== 3) {if (!BtnFixHoriz->Down) xc-=fact*xs;} - if (key== 4) {if (!BtnFixHoriz->Down) xc+=fact*xs;} - if (key==11) {xs/=sfact; ys/=sfact;} - if (key==12) {xs*=sfact; ys*=sfact;} - GraphT->SetCent(xc,yc); - GraphT->SetScale(xs,ys); - } - else if (PlotType<=PLOT_NSAT||PlotType==PLOT_RES) { - GraphG[0]->GetCent(xc,yc1); - GraphG[1]->GetCent(xc,yc2); - GraphG[2]->GetCent(xc,yc3); - GraphG[0]->GetScale(xs,ys1); - GraphG[1]->GetScale(xs,ys2); - GraphG[2]->GetScale(xs,ys3); - if (key== 1) {if (!BtnFixVert ->Down) yc1+=fact*ys1; yc2+=fact*ys2; yc3+=fact*ys3;} - if (key== 2) {if (!BtnFixVert ->Down) yc1-=fact*ys1; yc2-=fact*ys2; yc3-=fact*ys3;} - if (key== 3) {if (!BtnFixHoriz->Down) xc-=fact*xs;} - if (key== 4) {if (!BtnFixHoriz->Down) xc+=fact*xs;} - if (key==11) {ys1/=sfact; ys2/=sfact; ys3/=sfact;} - if (key==12) {ys1*=sfact; ys2*=sfact; ys3*=sfact;} - if (key==13) xs*=sfact; - if (key==14) xs/=sfact; - GraphG[0]->SetCent(xc,yc1); - GraphG[1]->SetCent(xc,yc2); - GraphG[2]->SetCent(xc,yc3); - GraphG[0]->SetScale(xs,ys1); - GraphG[1]->SetScale(xs,ys2); - GraphG[2]->SetScale(xs,ys3); - } - else if (PlotType==PLOT_OBS||PlotType==PLOT_DOP||PlotType==PLOT_SDOP||PlotType==PLOT_SNR) { - GraphR->GetCent(xc,yc); - GraphR->GetScale(xs,ys); - if (key== 1) {if (!BtnFixVert ->Down) yc+=fact*ys;} - if (key== 2) {if (!BtnFixVert ->Down) yc-=fact*ys;} - if (key== 3) {if (!BtnFixHoriz->Down) xc-=fact*xs;} - if (key== 4) {if (!BtnFixHoriz->Down) xc+=fact*xs;} - if (key==11) ys/=sfact; - if (key==12) xs*=sfact; - if (key==13) xs*=sfact; - if (key==14) xs/=sfact; - GraphR->SetCent(xc,yc); - GraphR->SetScale(xs,ys); - } - Refresh(); +void __fastcall TPlot::FormKeyDown(TObject *Sender, WORD &Key, TShiftState Shift) { + double sfact = 1.05, fact = Shift.Contains(ssShift) ? 1.0 : 10.0; + double xc, yc, yc1, yc2, yc3, xs, ys, ys1, ys2, ys3; + int key = Shift.Contains(ssCtrl) ? 10 : 0; + + trace(3, "FormKeyDown:\n"); + + switch (Key) { + case VK_UP: + key += 1; + break; + case VK_DOWN: + key += 2; + break; + case VK_LEFT: + key += 3; + break; + case VK_RIGHT: + key += 4; + break; + default: + return; + } + if (Shift.Contains(ssAlt)) return; + + Key = 0; // stop dispatch key event + + if (PlotType == PLOT_TRK) { + GraphT->GetCent(xc, yc); + GraphT->GetScale(xs, ys); + if (key == 1) { + if (!BtnFixHoriz->Down) yc += fact * ys; + } + if (key == 2) { + if (!BtnFixHoriz->Down) yc -= fact * ys; + } + if (key == 3) { + if (!BtnFixHoriz->Down) xc -= fact * xs; + } + if (key == 4) { + if (!BtnFixHoriz->Down) xc += fact * xs; + } + if (key == 11) { + xs /= sfact; + ys /= sfact; + } + if (key == 12) { + xs *= sfact; + ys *= sfact; + } + GraphT->SetCent(xc, yc); + GraphT->SetScale(xs, ys); + } else if (PlotType <= PLOT_NSAT || PlotType == PLOT_RES) { + GraphG[0]->GetCent(xc, yc1); + GraphG[1]->GetCent(xc, yc2); + GraphG[2]->GetCent(xc, yc3); + GraphG[0]->GetScale(xs, ys1); + GraphG[1]->GetScale(xs, ys2); + GraphG[2]->GetScale(xs, ys3); + if (key == 1) { + if (!BtnFixVert->Down) yc1 += fact * ys1; + yc2 += fact * ys2; + yc3 += fact * ys3; + } + if (key == 2) { + if (!BtnFixVert->Down) yc1 -= fact * ys1; + yc2 -= fact * ys2; + yc3 -= fact * ys3; + } + if (key == 3) { + if (!BtnFixHoriz->Down) xc -= fact * xs; + } + if (key == 4) { + if (!BtnFixHoriz->Down) xc += fact * xs; + } + if (key == 11) { + ys1 /= sfact; + ys2 /= sfact; + ys3 /= sfact; + } + if (key == 12) { + ys1 *= sfact; + ys2 *= sfact; + ys3 *= sfact; + } + if (key == 13) xs *= sfact; + if (key == 14) xs /= sfact; + GraphG[0]->SetCent(xc, yc1); + GraphG[1]->SetCent(xc, yc2); + GraphG[2]->SetCent(xc, yc3); + GraphG[0]->SetScale(xs, ys1); + GraphG[1]->SetScale(xs, ys2); + GraphG[2]->SetScale(xs, ys3); + } else if (PlotType == PLOT_OBS || PlotType == PLOT_DOP || PlotType == PLOT_SDOP || + PlotType == PLOT_SNR) { + GraphR->GetCent(xc, yc); + GraphR->GetScale(xs, ys); + if (key == 1) { + if (!BtnFixVert->Down) yc += fact * ys; + } + if (key == 2) { + if (!BtnFixVert->Down) yc -= fact * ys; + } + if (key == 3) { + if (!BtnFixHoriz->Down) xc -= fact * xs; + } + if (key == 4) { + if (!BtnFixHoriz->Down) xc += fact * xs; + } + if (key == 11) ys /= sfact; + if (key == 12) xs *= sfact; + if (key == 13) xs *= sfact; + if (key == 14) xs /= sfact; + GraphR->SetCent(xc, yc); + GraphR->SetScale(xs, ys); + } + Refresh(); } // callback on interval-timer ----------------------------------------------- -void __fastcall TPlot::TimerTimer(TObject *Sender) -{ - TColor color[]={clRed,clBtnFace,CLORANGE,clGreen,clLime}; - TPanel *strstatus[]={StrStatus1,StrStatus2}; - TConsole *console[]={Console1,Console2}; - AnsiString connectmsg="",s; - static uint8_t buff[16384]; - solopt_t opt=solopt_default; - sol_t *sol; - const gtime_t ts={0}; - gtime_t time={0}; - double tint=TimeEna[2]?TimeInt:0.0,pos[3],ep[6]; - int i,j,n,inb,inr,cycle,nmsg[2]={0},stat,istat; - int sel=!BtnSol1->Down&&BtnSol2->Down?1:0; - char msg[MAXSTRMSG]="",tstr[40]; - - trace(4,"TimeTimer\n"); - - if (!ConnectState) { - StrStatus1->Color=clBtnFace; - StrStatus2->Color=clBtnFace; - ConnectMsg->Caption=""; - } - if (ConnectState) { // real-time input mode - for (i=0;i<2;i++) { - opt.posf =RtFormat[i]; - opt.times=RtTimeForm==0?TIMES_GPST:(RtTimeForm - 1); - opt.timef=RtTimeForm>=1; - opt.degf =RtDegForm; - strcpy(opt.sep,RtFieldSep.c_str()); - strsum(Stream+i,&inb,&inr,NULL,NULL); - stat=strstat(Stream+i,msg); - strstatus[i]->Color=color[stat<3?stat+1:3]; - if (*msg&&strcmp(msg,"localhost")) { - connectmsg+=s.sprintf("(%d) %s ",i+1,msg); - } - while ((n=strread(Stream+i,buff,sizeof(buff)))>0) { - - for (j=0;jPLOT_NSAT) { - UpdateType(PLOT_TRK); - } - time2gpst(SolData[i].time,&Week); - UpdateOrigin(); - ecef2pos(SolData[i].data[0].rr,pos); - MapView->SetCent(pos[0]*R2D,pos[1]*R2D); - } - nmsg[i]++; - } - console[i]->AddMsg(buff,n); - } - if (nmsg[i]>0) { - strstatus[i]->Color=color[4]; - SolIndex[i]=SolData[i].n-1; - } - } - ConnectMsg->Caption=connectmsg; - - if (nmsg[0]<=0&&nmsg[1]<=0) return; - } - else if (BtnAnimate->Enabled&&BtnAnimate->Down) { // animation mode - cycle=AnimCycle<=0?1:AnimCycle; - - if (PlotType<=PLOT_SDOP||PlotType==PLOT_RES) { - SolIndex[sel]+=cycle; - if (SolIndex[sel]>=SolData[sel].n-1) { - SolIndex[sel]=SolData[sel].n-1; - BtnAnimate->Down=false; +void __fastcall TPlot::TimerTimer(TObject *Sender) { + TColor color[] = {clRed, clBtnFace, CLORANGE, clGreen, clLime}; + TPanel *strstatus[] = {StrStatus1, StrStatus2}; + TConsole *console[] = {Console1, Console2}; + AnsiString connectmsg = "", s; + static uint8_t buff[16384]; + solopt_t opt = solopt_default; + sol_t *sol; + const gtime_t ts = {0}; + gtime_t time = {0}; + double tint = TimeEna[2] ? TimeInt : 0.0, pos[3], ep[6]; + int i, j, n, inb, inr, cycle, nmsg[2] = {0}, stat, istat; + int sel = !BtnSol1->Down && BtnSol2->Down ? 1 : 0; + char msg[MAXSTRMSG] = "", tstr[40]; + + trace(4, "TimeTimer\n"); + + if (!ConnectState) { + StrStatus1->Color = clBtnFace; + StrStatus2->Color = clBtnFace; + ConnectMsg->Caption = ""; + } + if (ConnectState) { // real-time input mode + for (i = 0; i < 2; i++) { + opt.posf = RtFormat[i]; + opt.times = RtTimeForm == 0 ? TIMES_GPST : (RtTimeForm - 1); + opt.timef = RtTimeForm >= 1; + opt.degf = RtDegForm; + strcpy(opt.sep, RtFieldSep.c_str()); + strsum(Stream + i, &inb, &inr, NULL, NULL); + stat = strstat(Stream + i, msg); + strstatus[i]->Color = color[stat < 3 ? stat + 1 : 3]; + if (*msg && strcmp(msg, "localhost")) { + connectmsg += s.sprintf("(%d) %s ", i + 1, msg); + } + while ((n = strread(Stream + i, buff, sizeof(buff))) > 0) { + for (j = 0; j < n; j++) { + istat = inputsol(buff[j], ts, ts, tint, SOLQ_NONE, &opt, SolData + i); + if (istat == 0) continue; + if (istat < 0) { // disconnect received + Disconnect(); + return; + } + if (Week == 0 && SolData[i].n == 1) { // first data + if (PlotType > PLOT_NSAT) { + UpdateType(PLOT_TRK); } + time2gpst(SolData[i].time, &Week); + UpdateOrigin(); + ecef2pos(SolData[i].data[0].rr, pos); + MapView->SetCent(pos[0] * R2D, pos[1] * R2D); + } + nmsg[i]++; } - else { - ObsIndex+=cycle; - if (ObsIndex>=NObs-1) { - ObsIndex=NObs-1; - BtnAnimate->Down=false; - } + console[i]->AddMsg(buff, n); + } + if (nmsg[i] > 0) { + strstatus[i]->Color = color[4]; + SolIndex[i] = SolData[i].n - 1; + } + } + ConnectMsg->Caption = connectmsg; + + if (nmsg[0] <= 0 && nmsg[1] <= 0) return; + } else if (BtnAnimate->Enabled && BtnAnimate->Down) { // animation mode + cycle = AnimCycle <= 0 ? 1 : AnimCycle; + + if (PlotType <= PLOT_SDOP || PlotType == PLOT_RES) { + SolIndex[sel] += cycle; + if (SolIndex[sel] >= SolData[sel].n - 1) { + SolIndex[sel] = SolData[sel].n - 1; + BtnAnimate->Down = false; + } + } else { + ObsIndex += cycle; + if (ObsIndex >= NObs - 1) { + ObsIndex = NObs - 1; + BtnAnimate->Down = false; + } + } + } else if (TimeSyncOut) { // time sync + time.time = 0; + while (strread(&StrTimeSync, (uint8_t *)StrBuff + NStrBuff, 1)) { + if (++NStrBuff >= 1023) { + NStrBuff = 0; + continue; + } + if (StrBuff[NStrBuff - 1] == '\n') { + StrBuff[NStrBuff - 1] = '\0'; + if (sscanf(StrBuff, "%lf/%lf/%lf %lf:%lf:%lf", ep, ep + 1, ep + 2, ep + 3, ep + 4, + ep + 5) >= 6) { + time = epoch2time(ep); } - } - else if (TimeSyncOut) { // time sync - time.time = 0; - while (strread(&StrTimeSync, (uint8_t *)StrBuff+NStrBuff, 1)) { - if (++NStrBuff >= 1023) { - NStrBuff = 0; - continue; - } - if (StrBuff[NStrBuff-1]=='\n') { - StrBuff[NStrBuff-1]='\0'; - if (sscanf(StrBuff,"%lf/%lf/%lf %lf:%lf:%lf",ep,ep+1,ep+2, - ep+3,ep+4,ep+5)>=6) { - time=epoch2time(ep); - } - NStrBuff = 0; - } + NStrBuff = 0; + } + } + if (time.time && (PlotType <= PLOT_SDOP || PlotType <= PLOT_RES)) { + i = SolIndex[sel]; + if (!(sol = getsol(SolData + sel, i))) return; + double tt = timediff(sol->time, time); + if (tt < -DTTOL) { + for (; i < SolData[sel].n; i++) { + if (!(sol = getsol(SolData + sel, i))) continue; + if (timediff(sol->time, time) >= -DTTOL) { + i--; + break; + } } - if (time.time&&(PlotType<=PLOT_SDOP||PlotType<=PLOT_RES)) { - i=SolIndex[sel]; - if (!(sol=getsol(SolData+sel,i))) return; - double tt=timediff(sol->time,time); - if (tt<-DTTOL) { - for (;itime,time)>=-DTTOL) { - i--; - break; - } - } - } - else if (tt>DTTOL) { - for (;i>=0;i--) { - if (!(sol=getsol(SolData+sel,i))) continue; - if (timediff(sol->time,time)<=DTTOL) break; - } - } - SolIndex[sel]=MAX(0,MIN(SolData[sel].n-1,i)); + } else if (tt > DTTOL) { + for (; i >= 0; i--) { + if (!(sol = getsol(SolData + sel, i))) continue; + if (timediff(sol->time, time) <= DTTOL) break; } - else return; - } - else return; - - UpdateTime(); - UpdatePlot(); + } + SolIndex[sel] = MAX(0, MIN(SolData[sel].n - 1, i)); + } else + return; + } else + return; + + UpdateTime(); + UpdatePlot(); } // set center of x-axis ----------------------------------------------------- -void __fastcall TPlot::SetCentX(double c) -{ - double x,y; - int i; - - trace(3,"SetCentX: c=%.3f:\n",c); - - GraphR->GetCent(x,y); - GraphR->SetCent(c,y); - for (i=0;i<3;i++) { - GraphG[i]->GetCent(x,y); - GraphG[i]->SetCent(c,y); - } +void __fastcall TPlot::SetCentX(double c) { + double x, y; + int i; + + trace(3, "SetCentX: c=%.3f:\n", c); + + GraphR->GetCent(x, y); + GraphR->SetCent(c, y); + for (i = 0; i < 3; i++) { + GraphG[i]->GetCent(x, y); + GraphG[i]->SetCent(c, y); + } } // set scale of x-axis ------------------------------------------------------ -void __fastcall TPlot::SetScaleX(double s) -{ - double xs,ys; - int i; - - trace(3,"SetScaleX: s=%.3f:\n",s); - - GraphR->GetScale(xs,ys); - GraphR->SetScale(s ,ys); - for (i=0;i<3;i++) { - GraphG[i]->GetScale(xs,ys); - GraphG[i]->SetScale(s, ys); - } +void __fastcall TPlot::SetScaleX(double s) { + double xs, ys; + int i; + + trace(3, "SetScaleX: s=%.3f:\n", s); + + GraphR->GetScale(xs, ys); + GraphR->SetScale(s, ys); + for (i = 0; i < 3; i++) { + GraphG[i]->GetScale(xs, ys); + GraphG[i]->SetScale(s, ys); + } } // update plot-type with fit-range ------------------------------------------ -void __fastcall TPlot::UpdateType(int type) -{ - trace(3,"UpdateType: type=%d\n",type); - - PlotType=type; - - if (AutoScale&&PlotType<=PLOT_SOLA&&(SolData[0].n>0||SolData[1].n>0)) { - FitRange(0); - } - else { - SetRange(0,YRange); - } - UpdatePlotType(); +void __fastcall TPlot::UpdateType(int type) { + trace(3, "UpdateType: type=%d\n", type); + + PlotType = type; + + if (AutoScale && PlotType <= PLOT_SOLA && (SolData[0].n > 0 || SolData[1].n > 0)) { + FitRange(0); + } else { + SetRange(0, YRange); + } + UpdatePlotType(); } // update size of plot ------------------------------------------------------ -void __fastcall TPlot::UpdateSize(void) -{ - TSpeedButton *btn[]={BtnOn1,BtnOn2,BtnOn3}; - TPoint p1(0,0),p2(Disp->Width,Disp->Height); - double xs,ys,font_px=Disp->Font->Size*1.33; - int i,n,h,tmargin,bmargin,rmargin,lmargin; - - trace(3,"UpdateSize\n"); - - tmargin=(int)(font_px*0.9); // top margin (px) - bmargin=(int)(font_px*1.8); // bottom - rmargin=(int)(font_px*1.2); // right - lmargin=(int)(font_px*3.6); // left - - GraphT->SetPos(p1,p2); - GraphS->SetPos(p1,p2); - GraphS->GetScale(xs,ys); - xs=MAX(xs,ys); - GraphS->SetScale(xs,xs); - p1.x+=lmargin; p1.y+=tmargin; - p2.x-=rmargin; p2.y=p2.y-bmargin; - GraphR->SetPos(p1,p2); - - p1.y=tmargin; p2.y=p1.y; - for (i=n=0;i<3;i++) if (btn[i]->Down) n++; - for (i=0;i<3;i++) { - if (!btn[i]->Down||n<=0) continue; - h=(Disp->Height-tmargin-bmargin)/n; - p2.y+=h; - GraphG[i]->SetPos(p1,p2); - p1.y+=h; - } - p1.x+=(int)(font_px*1.2); - p1.y=tmargin; p2.y=p1.y; - for (i=n=0;i<2;i++) if (btn[i]->Down) n++; - for (i=0;i<2;i++) { - if (!btn[i]->Down||n<=0) continue; - h=(Disp->Height-tmargin-bmargin)/n; - p2.y+=h; - GraphE[i]->SetPos(p1,p2); - p1.y+=h; - } +void __fastcall TPlot::UpdateSize(void) { + TSpeedButton *btn[] = {BtnOn1, BtnOn2, BtnOn3}; + TPoint p1(0, 0), p2(Disp->Width, Disp->Height); + double xs, ys, font_px = Disp->Font->Size * 1.33; + int i, n, h, tmargin, bmargin, rmargin, lmargin; + + trace(3, "UpdateSize\n"); + + tmargin = (int)(font_px * 0.9); // top margin (px) + bmargin = (int)(font_px * 1.8); // bottom + rmargin = (int)(font_px * 1.2); // right + lmargin = (int)(font_px * 3.6); // left + + GraphT->SetPos(p1, p2); + GraphS->SetPos(p1, p2); + GraphS->GetScale(xs, ys); + xs = MAX(xs, ys); + GraphS->SetScale(xs, xs); + p1.x += lmargin; + p1.y += tmargin; + p2.x -= rmargin; + p2.y = p2.y - bmargin; + GraphR->SetPos(p1, p2); + + p1.y = tmargin; + p2.y = p1.y; + for (i = n = 0; i < 3; i++) + if (btn[i]->Down) n++; + for (i = 0; i < 3; i++) { + if (!btn[i]->Down || n <= 0) continue; + h = (Disp->Height - tmargin - bmargin) / n; + p2.y += h; + GraphG[i]->SetPos(p1, p2); + p1.y += h; + } + p1.x += (int)(font_px * 1.2); + p1.y = tmargin; + p2.y = p1.y; + for (i = n = 0; i < 2; i++) + if (btn[i]->Down) n++; + for (i = 0; i < 2; i++) { + if (!btn[i]->Down || n <= 0) continue; + h = (Disp->Height - tmargin - bmargin) / n; + p2.y += h; + GraphE[i]->SetPos(p1, p2); + p1.y += h; + } } // update colors on plot ---------------------------------------------------- -void __fastcall TPlot::UpdateColor(void) -{ - int i; - - trace(3,"UpdateColor\n"); - - for (i=0;i<3;i++) { - GraphT ->Color[i]=CColor[i]; - GraphR ->Color[i]=CColor[i]; - GraphS ->Color[i]=CColor[i]; - GraphG[0]->Color[i]=CColor[i]; - GraphG[1]->Color[i]=CColor[i]; - GraphG[2]->Color[i]=CColor[i]; - } - Disp->Font->Assign(Font); +void __fastcall TPlot::UpdateColor(void) { + int i; + + trace(3, "UpdateColor\n"); + + for (i = 0; i < 3; i++) { + GraphT->Color[i] = CColor[i]; + GraphR->Color[i] = CColor[i]; + GraphS->Color[i] = CColor[i]; + GraphG[0]->Color[i] = CColor[i]; + GraphG[1]->Color[i] = CColor[i]; + GraphG[2]->Color[i] = CColor[i]; + } + Disp->Font->Assign(Font); } // update time-cursor ------------------------------------------------------- -void __fastcall TPlot::UpdateTime(void) -{ - gtime_t time; - sol_t *sol; - double tt; - int i,j,sel=!BtnSol1->Down&&BtnSol2->Down?1:0; - - trace(3,"UpdateTime\n"); - - // time-cursor change on solution-plot - if (PlotType<=PLOT_SDOP||PlotType<=PLOT_RESE) { - TimeScroll->Max=MAX(1,SolData[sel].n-1); - TimeScroll->Position=SolIndex[sel]; - if (!(sol=getsol(SolData+sel,SolIndex[sel]))) return; - time=sol->time; - } - else if (NObs>0) { // time-cursor change on observation-data-plot - TimeScroll->Max=MAX(1,NObs-1); - TimeScroll->Position=ObsIndex; - time=Obs.data[IndexObs[ObsIndex]].time; - } - else return; - - // time-synchronization between solutions and observation-data - for (sel=0;sel<2;sel++) { - i=SolIndex[sel]; - if (!(sol=getsol(SolData+sel,i))) continue; - tt=timediff(sol->time,time); - if (tt<-DTTOL) { - for (;itime,time)>=-DTTOL) break; - } - } - else if (tt>DTTOL) { - for (;i>=0;i--) { - if (!(sol=getsol(SolData+sel,i))) continue; - if (timediff(sol->time,time)<=DTTOL) break; - } - } - SolIndex[sel]=MAX(0,MIN(SolData[sel].n-1,i)); - } - i=ObsIndex; - if (i<=NObs-1) { - tt=timediff(Obs.data[IndexObs[i]].time,time); - if (tt<-DTTOL) { - for (;i=-DTTOL) break; - } - } - else if (tt>DTTOL) { - for (;i>=0;i--) { - if (timediff(Obs.data[IndexObs[i]].time,time)<=DTTOL) break; - } - } - ObsIndex=MAX(0,MIN(NObs-1,i)); - } +void __fastcall TPlot::UpdateTime(void) { + gtime_t time; + sol_t *sol; + double tt; + int i, j, sel = !BtnSol1->Down && BtnSol2->Down ? 1 : 0; + + trace(3, "UpdateTime\n"); + + // time-cursor change on solution-plot + if (PlotType <= PLOT_SDOP || PlotType <= PLOT_RESE) { + TimeScroll->Max = MAX(1, SolData[sel].n - 1); + TimeScroll->Position = SolIndex[sel]; + if (!(sol = getsol(SolData + sel, SolIndex[sel]))) return; + time = sol->time; + } else if (NObs > 0) { // time-cursor change on observation-data-plot + TimeScroll->Max = MAX(1, NObs - 1); + TimeScroll->Position = ObsIndex; + time = Obs.data[IndexObs[ObsIndex]].time; + } else + return; + + // time-synchronization between solutions and observation-data + for (sel = 0; sel < 2; sel++) { + i = SolIndex[sel]; + if (!(sol = getsol(SolData + sel, i))) continue; + tt = timediff(sol->time, time); + if (tt < -DTTOL) { + for (; i < SolData[sel].n; i++) { + if (!(sol = getsol(SolData + sel, i))) continue; + if (timediff(sol->time, time) >= -DTTOL) break; + } + } else if (tt > DTTOL) { + for (; i >= 0; i--) { + if (!(sol = getsol(SolData + sel, i))) continue; + if (timediff(sol->time, time) <= DTTOL) break; + } + } + SolIndex[sel] = MAX(0, MIN(SolData[sel].n - 1, i)); + } + i = ObsIndex; + if (i <= NObs - 1) { + tt = timediff(Obs.data[IndexObs[i]].time, time); + if (tt < -DTTOL) { + for (; i < NObs; i++) { + if (timediff(Obs.data[IndexObs[i]].time, time) >= -DTTOL) break; + } + } else if (tt > DTTOL) { + for (; i >= 0; i--) { + if (timediff(Obs.data[IndexObs[i]].time, time) <= DTTOL) break; + } + } + ObsIndex = MAX(0, MIN(NObs - 1, i)); + } } // update origin of plot ---------------------------------------------------- -void __fastcall TPlot::UpdateOrigin(void) -{ - gtime_t time={0}; - sol_t *sol; - double opos[3]={0},pos[3],ovel[3]={0}; - int i,j,n=0,sel=!BtnSol1->Down&&BtnSol2->Down?1:0; - char file[1024],sta[16]="",*p; - - trace(3,"UpdateOrigin\n"); - - if (Origin==ORG_STARTPOS) { - if (!(sol=getsol(SolData,0))||sol->type!=0) return; - for (i=0;i<3;i++) opos[i]=sol->rr[i]; - } - else if (Origin==ORG_ENDPOS) { - if (!(sol=getsol(SolData,SolData[0].n-1))||sol->type!=0) return; - for (i=0;i<3;i++) opos[i]=sol->rr[i]; - } - else if (Origin==ORG_AVEPOS) { - for (i=0;(sol=getsol(SolData,i));i++) { - if (sol->type!=0) continue; - for (j=0;j<3;j++) opos[j]+=sol->rr[j]; - n++; - } - if (n>0) for (i=0;i<3;i++) opos[i]/=n; - } - else if (Origin==ORG_FITPOS) { - if (!FitPos(&time,opos,ovel)) return; - } - else if (Origin==ORG_REFPOS) { - if (norm(SolData[0].rb,3)>0.0) { - for (i=0;i<3;i++) opos[i]=SolData[0].rb[i]; - } - else { - if (!(sol=getsol(SolData,0))||sol->type!=0) return; - for (i=0;i<3;i++) opos[i]=sol->rr[i]; - } - } - else if (Origin==ORG_LLHPOS) { - pos2ecef(OOPos,opos); - } - else if (Origin==ORG_AUTOPOS) { - if (SolFiles[sel]->Count>0) { - - strcpy(file,U2A(SolFiles[sel]->Strings[0]).c_str()); - - if ((p=strrchr(file,'\\'))) strncpy(sta,p+1,4); - else strncpy(sta,file,4); - for (p=sta;*p;p++) *p=(char)toupper(*p); - - strcpy(file,U2A(RefDialog->StaPosFile).c_str()); - - ReadStaPos(file,sta,opos); - } - } - else if (Origin==ORG_IMGPOS) { - pos[0]=MapLat*D2R; - pos[1]=MapLon*D2R; - pos[2]=0.0; - pos2ecef(pos,opos); - } - else if (Origin==ORG_MAPPOS) { - pos[0]=(Gis.bound[0]+Gis.bound[1])/2.0; - pos[1]=(Gis.bound[2]+Gis.bound[3])/2.0; - pos[2]=0.0; - pos2ecef(pos,opos); - } - else if (Origin-ORG_PNTPOStype!=0) return; - for (i=0;i<3;i++) opos[i]=sol->rr[i]; - } - OEpoch=time; - for (i=0;i<3;i++) { - OPos[i]=opos[i]; - OVel[i]=ovel[i]; - } - Refresh_MapView(); +void __fastcall TPlot::UpdateOrigin(void) { + gtime_t time = {0}; + sol_t *sol; + double opos[3] = {0}, pos[3], ovel[3] = {0}; + int i, j, n = 0, sel = !BtnSol1->Down && BtnSol2->Down ? 1 : 0; + char file[1024], sta[16] = "", *p; + + trace(3, "UpdateOrigin\n"); + + if (Origin == ORG_STARTPOS) { + if (!(sol = getsol(SolData, 0)) || sol->type != 0) return; + for (i = 0; i < 3; i++) opos[i] = sol->rr[i]; + } else if (Origin == ORG_ENDPOS) { + if (!(sol = getsol(SolData, SolData[0].n - 1)) || sol->type != 0) return; + for (i = 0; i < 3; i++) opos[i] = sol->rr[i]; + } else if (Origin == ORG_AVEPOS) { + for (i = 0; (sol = getsol(SolData, i)); i++) { + if (sol->type != 0) continue; + for (j = 0; j < 3; j++) opos[j] += sol->rr[j]; + n++; + } + if (n > 0) + for (i = 0; i < 3; i++) opos[i] /= n; + } else if (Origin == ORG_FITPOS) { + if (!FitPos(&time, opos, ovel)) return; + } else if (Origin == ORG_REFPOS) { + if (norm(SolData[0].rb, 3) > 0.0) { + for (i = 0; i < 3; i++) opos[i] = SolData[0].rb[i]; + } else { + if (!(sol = getsol(SolData, 0)) || sol->type != 0) return; + for (i = 0; i < 3; i++) opos[i] = sol->rr[i]; + } + } else if (Origin == ORG_LLHPOS) { + pos2ecef(OOPos, opos); + } else if (Origin == ORG_AUTOPOS) { + if (SolFiles[sel]->Count > 0) { + strcpy(file, U2A(SolFiles[sel]->Strings[0]).c_str()); + + if ((p = strrchr(file, '\\'))) + strncpy(sta, p + 1, 4); + else + strncpy(sta, file, 4); + for (p = sta; *p; p++) *p = (char)toupper(*p); + + strcpy(file, U2A(RefDialog->StaPosFile).c_str()); + + ReadStaPos(file, sta, opos); + } + } else if (Origin == ORG_IMGPOS) { + pos[0] = MapLat * D2R; + pos[1] = MapLon * D2R; + pos[2] = 0.0; + pos2ecef(pos, opos); + } else if (Origin == ORG_MAPPOS) { + pos[0] = (Gis.bound[0] + Gis.bound[1]) / 2.0; + pos[1] = (Gis.bound[2] + Gis.bound[3]) / 2.0; + pos[2] = 0.0; + pos2ecef(pos, opos); + } else if (Origin - ORG_PNTPOS < MAXWAYPNT) { + for (i = 0; i < 3; i++) opos[i] = PntPos[Origin - ORG_PNTPOS][i]; + } + if (norm(opos, 3) <= 0.0) { + // default start position + if (!(sol = getsol(SolData, 0)) || sol->type != 0) return; + for (i = 0; i < 3; i++) opos[i] = sol->rr[i]; + } + OEpoch = time; + for (i = 0; i < 3; i++) { + OPos[i] = opos[i]; + OVel[i] = ovel[i]; + } + Refresh_MapView(); } // update satellite mask ---------------------------------------------------- -void __fastcall TPlot::UpdateSatMask(void) -{ - int sat,prn; - char buff[256],*p; - - trace(3,"UpdateSatMask\n"); - - for (sat=1;sat<=MAXSAT;sat++) SatMask[sat-1]=0; - for (sat=1;sat<=MAXSAT;sat++) { - if (!(satsys(sat,&prn)&NavSys)) SatMask[sat-1]=1; - } - if (ExSats!="") { - strcpy(buff,ExSats.c_str()); - - for (p=strtok(buff," ");p;p=strtok(NULL," ")) { - if (*p=='+'&&(sat=satid2no(p+1))) SatMask[sat-1]=0; // included - else if ((sat=satid2no(p))) SatMask[sat-1]=1; // excluded - } +void __fastcall TPlot::UpdateSatMask(void) { + int sat, prn; + char buff[256], *p; + + trace(3, "UpdateSatMask\n"); + + for (sat = 1; sat <= MAXSAT; sat++) SatMask[sat - 1] = 0; + for (sat = 1; sat <= MAXSAT; sat++) { + if (!(satsys(sat, &prn) & NavSys)) SatMask[sat - 1] = 1; + } + if (ExSats != "") { + strcpy(buff, ExSats.c_str()); + + for (p = strtok(buff, " "); p; p = strtok(NULL, " ")) { + if (*p == '+' && (sat = satid2no(p + 1))) + SatMask[sat - 1] = 0; // included + else if ((sat = satid2no(p))) + SatMask[sat - 1] = 1; // excluded } + } } // update satellite select --------------------------------------------------- -void __fastcall TPlot::UpdateSatSel(void) -{ - AnsiString SatListText=SatList->Text; - char id[8]; - int i,sys=0; - - if (SatListText=="G") sys=SYS_GPS; - else if (SatListText=="R") sys=SYS_GLO; - else if (SatListText=="E") sys=SYS_GAL; - else if (SatListText=="J") sys=SYS_QZS; - else if (SatListText=="C") sys=SYS_CMP; - else if (SatListText=="I") sys=SYS_IRN; - else if (SatListText=="S") sys=SYS_SBS; - for (i=0;iText; + char id[8]; + int i, sys = 0; + + if (SatListText == "G") + sys = SYS_GPS; + else if (SatListText == "R") + sys = SYS_GLO; + else if (SatListText == "E") + sys = SYS_GAL; + else if (SatListText == "J") + sys = SYS_QZS; + else if (SatListText == "C") + sys = SYS_CMP; + else if (SatListText == "I") + sys = SYS_IRN; + else if (SatListText == "S") + sys = SYS_SBS; + for (i = 0; i < MAXSAT; i++) { + satno2id(i + 1, id); + SatSel[i] = SatListText == "ALL" || SatListText == id || satsys(i + 1, NULL) == sys; + } } // update enable/disable of widgets ----------------------------------------- -void __fastcall TPlot::UpdateEnable(void) -{ - AnsiString s; - double range; - int i,data=BtnSol1->Down||BtnSol2->Down||BtnSol12->Down; - int plot=PLOT_SOLP<=PlotType&&PlotType<=PLOT_NSAT; - int sel=!BtnSol1->Down&&BtnSol2->Down?1:0; - - trace(3,"UpdateEnable\n"); - - Panel1 ->Visible=MenuToolBar ->Checked; - Panel2 ->Visible=MenuStatusBar->Checked; - - BtnConnect ->Down = ConnectState; - BtnSol1 ->Enabled=true; - BtnSol2 ->Enabled=PlotType<=PLOT_SDOP||PlotType==PLOT_RES||PlotType==PLOT_RESE; - BtnSol12 ->Enabled=!ConnectState&&PlotType<=PLOT_SOLA&&SolData[0].n>0&&SolData[1].n>0; - QFlag ->Visible=PlotType==PLOT_TRK ||PlotType==PLOT_SOLP|| - PlotType==PLOT_SOLV||PlotType==PLOT_SOLA|| - PlotType==PLOT_NSAT; - ObsType ->Visible=PlotType==PLOT_OBS||PlotType==PLOT_SKY; - ObsType2 ->Visible=PlotType==PLOT_SNR||PlotType==PLOT_SNRE||PlotType==PLOT_MPS; - FrqType ->Visible=PlotType==PLOT_SSKY||PlotType==PLOT_RES||PlotType==PLOT_RESE; - DopType ->Visible=PlotType==PLOT_DOP||PlotType==PLOT_SDOP; - SatList ->Visible=PlotType==PLOT_RES||PlotType==PLOT_RESE||PlotType>=PLOT_OBS|| - PlotType==PLOT_SSKY||PlotType==PLOT_SKY|| - PlotType==PLOT_SDOP||PlotType==PLOT_DOP|| - PlotType==PLOT_SNR||PlotType==PLOT_SNRE|| - PlotType==PLOT_MPS; - QFlag ->Enabled=data; - ObsType ->Enabled=data&&!SimObs; - ObsType2 ->Enabled=data&&!SimObs; - - Panel102 ->Visible=PlotType==PLOT_SOLP||PlotType==PLOT_SOLV|| - PlotType==PLOT_SOLA||PlotType==PLOT_NSAT|| - PlotType==PLOT_RES ||PlotType==PLOT_RESE|| - PlotType==PLOT_SNR ||PlotType==PLOT_SNRE; - BtnOn1 ->Enabled=plot||PlotType==PLOT_SNR||PlotType==PLOT_RES|| - PlotType==PLOT_RESE||PlotType==PLOT_SNRE; - BtnOn2 ->Enabled=plot||PlotType==PLOT_SNR||PlotType==PLOT_RES|| - PlotType==PLOT_RESE||PlotType==PLOT_SNRE; - BtnOn3 ->Enabled=plot||PlotType==PLOT_SNR||PlotType==PLOT_RES; - - BtnCenterOri ->Visible=PlotType==PLOT_TRK ||PlotType==PLOT_SOLP|| - PlotType==PLOT_SOLV||PlotType==PLOT_SOLA|| - PlotType==PLOT_NSAT; - BtnCenterOri ->Enabled=PlotType!=PLOT_NSAT; - BtnRangeList ->Visible=PlotType==PLOT_TRK ||PlotType==PLOT_SOLP|| - PlotType==PLOT_SOLV||PlotType==PLOT_SOLA|| - PlotType==PLOT_NSAT; - BtnRangeList ->Enabled=PlotType!=PLOT_NSAT; - - BtnFitHoriz ->Visible=PlotType==PLOT_SOLP||PlotType==PLOT_SOLV|| - PlotType==PLOT_SOLA||PlotType==PLOT_NSAT|| - PlotType==PLOT_RES ||PlotType==PLOT_OBS || - PlotType==PLOT_DOP ||PlotType==PLOT_SDOP|| - PlotType==PLOT_SNR ||PlotType==PLOT_SNRE; - BtnFitHoriz ->Enabled=data; - BtnFitVert ->Visible=PlotType==PLOT_TRK ||PlotType==PLOT_SOLP|| - PlotType==PLOT_SOLV||PlotType==PLOT_SOLA; - BtnFitVert ->Enabled=data; - BtnShowTrack ->Enabled=data; - BtnFixCent ->Visible=PlotType==PLOT_TRK; - BtnFixCent ->Enabled=data; - BtnFixHoriz ->Visible=PlotType==PLOT_SOLP||PlotType==PLOT_SOLV|| - PlotType==PLOT_SOLA||PlotType==PLOT_NSAT|| - PlotType==PLOT_RES ||PlotType==PLOT_OBS || - PlotType==PLOT_DOP ||PlotType==PLOT_DOP || - PlotType==PLOT_SNR; - BtnFixHoriz ->Enabled=data; - BtnFixVert ->Visible=PlotType==PLOT_SOLP||PlotType==PLOT_SOLV|| - PlotType==PLOT_SOLA; - BtnFixVert ->Enabled=data; - BtnShowGrid ->Visible=PlotType==PLOT_TRK; - BtnShowSkyplot ->Visible=PlotType==PLOT_SKY||PlotType==PLOT_MPS; - BtnShowMap ->Visible=PlotType==PLOT_TRK; - BtnShowMap ->Enabled=!BtnSol12->Down; - BtnShowImg ->Visible=PlotType==PLOT_TRK||PlotType==PLOT_SKY||PlotType==PLOT_SSKY|| - PlotType==PLOT_MPS; - BtnMapView ->Visible=PlotType==PLOT_TRK||PlotType==PLOT_SOLP; - Panel12 ->Visible=!ConnectState; - BtnAnimate ->Visible=data&&BtnShowTrack->Down; - TimeScroll ->Visible=data&&BtnShowTrack->Down; - TimeScroll ->Enabled=data&&BtnShowTrack->Down; - - if (!BtnShowTrack->Down) { - BtnFixHoriz->Enabled=false; - BtnFixVert ->Enabled=false; - BtnFixCent ->Enabled=false; - BtnAnimate ->Down =false; - } - BtnRangeList ->Left=BtnCenterOri ->Left+BtnCenterOri ->Width; - BtnFitHoriz ->Left=Panel104 ->Left+Panel104 ->Width; - BtnFitVert ->Left=BtnFitHoriz ->Left+BtnFitHoriz ->Width; - BtnShowTrack ->Left=BtnFitVert ->Left+BtnFitVert ->Width; - BtnFixCent ->Left=BtnShowTrack ->Left+BtnShowTrack ->Width; - BtnFixHoriz ->Left=BtnFixCent ->Left+BtnFixCent ->Width; - BtnFixVert ->Left=BtnFixHoriz ->Left+BtnFixHoriz ->Width; - BtnShowGrid ->Left=BtnFixVert ->Left+BtnFixVert ->Width; - BtnShowSkyplot ->Left=BtnShowGrid ->Left+BtnShowGrid ->Width; - BtnShowMap ->Left=BtnShowSkyplot->Left+BtnShowSkyplot->Width; - BtnShowImg ->Left=BtnShowMap ->Left+BtnShowMap ->Width; - BtnMapView ->Left=BtnShowImg ->Left+BtnShowImg ->Width; - - BtnFreq ->Left=BtnClear ->Left-BtnFreq ->Width; - - MenuMapImg ->Enabled=MapImage->Height>0; - MenuSkyImg ->Enabled=SkyImageI->Height>0; - MenuSrcSol ->Enabled=SolFiles[sel]->Count>0; - MenuSrcObs ->Enabled=ObsFiles->Count>0; - MenuMapLayer ->Enabled=true; - MenuShowTrack ->Enabled=BtnShowTrack->Enabled; - MenuFitHoriz ->Enabled=BtnFitHoriz ->Enabled; - MenuFitVert ->Enabled=BtnFitVert ->Enabled; - MenuCenterOri ->Enabled=BtnCenterOri->Enabled; - MenuFixCent ->Enabled=BtnFixCent ->Enabled; - MenuFixHoriz ->Enabled=BtnFixHoriz ->Enabled; - MenuFixVert ->Enabled=BtnFixVert ->Enabled; - MenuShowMap ->Enabled=BtnShowMap ->Enabled; - MenuShowImg ->Enabled=BtnShowImg ->Enabled; - MenuShowSkyplot->Enabled=BtnShowSkyplot->Visible; - MenuShowGrid ->Enabled=BtnShowGrid ->Visible; - MenuMapView ->Enabled=BtnMapView ->Enabled; - MenuShowTrack ->Checked=BtnShowTrack->Down; - MenuFixCent ->Checked=BtnFixCent ->Down; - MenuFixHoriz ->Checked=BtnFixHoriz ->Down; - MenuFixVert ->Checked=BtnFixVert ->Down; - MenuShowSkyplot->Checked=BtnShowSkyplot->Down; - MenuShowGrid ->Checked=BtnShowGrid ->Down; - MenuShowMap ->Checked=BtnShowMap ->Down; - MenuShowImg ->Checked=BtnShowImg ->Down; - MenuAnimStart ->Enabled=!ConnectState&&BtnAnimate->Enabled&&!BtnAnimate->Down; - MenuAnimStop ->Enabled=!ConnectState&&BtnAnimate->Enabled&& BtnAnimate->Down; - MenuOpenSol1 ->Enabled=!ConnectState; - MenuOpenSol2 ->Enabled=!ConnectState; - MenuConnect ->Enabled=!ConnectState; - MenuDisconnect ->Enabled= ConnectState; - MenuPort ->Enabled=!ConnectState; - MenuOpenObs ->Enabled=!ConnectState; - MenuOpenNav ->Enabled=!ConnectState; - MenuOpenElevMask->Enabled=!ConnectState; - MenuReload ->Enabled=!ConnectState; - - BtnReload ->Enabled=!ConnectState; - StrStatus ->Enabled= ConnectState; - BtnFreq ->Visible=FrqType->Visible||ObsType->Visible||ObsType2->Visible; - StrStatus ->Left=BtnOptions->Left-StrStatus->Width+1; +void __fastcall TPlot::UpdateEnable(void) { + AnsiString s; + double range; + int i, data = BtnSol1->Down || BtnSol2->Down || BtnSol12->Down; + int plot = PLOT_SOLP <= PlotType && PlotType <= PLOT_NSAT; + int sel = !BtnSol1->Down && BtnSol2->Down ? 1 : 0; + + trace(3, "UpdateEnable\n"); + + Panel1->Visible = MenuToolBar->Checked; + Panel2->Visible = MenuStatusBar->Checked; + + BtnConnect->Down = ConnectState; + BtnSol1->Enabled = true; + BtnSol2->Enabled = PlotType <= PLOT_SDOP || PlotType == PLOT_RES || PlotType == PLOT_RESE; + BtnSol12->Enabled = + !ConnectState && PlotType <= PLOT_SOLA && SolData[0].n > 0 && SolData[1].n > 0; + QFlag->Visible = PlotType == PLOT_TRK || PlotType == PLOT_SOLP || PlotType == PLOT_SOLV || + PlotType == PLOT_SOLA || PlotType == PLOT_NSAT; + ObsType->Visible = PlotType == PLOT_OBS || PlotType == PLOT_SKY; + ObsType2->Visible = PlotType == PLOT_SNR || PlotType == PLOT_SNRE || PlotType == PLOT_MPS; + FrqType->Visible = PlotType == PLOT_SSKY || PlotType == PLOT_RES || PlotType == PLOT_RESE; + DopType->Visible = PlotType == PLOT_DOP || PlotType == PLOT_SDOP; + SatList->Visible = PlotType == PLOT_RES || PlotType == PLOT_RESE || PlotType >= PLOT_OBS || + PlotType == PLOT_SSKY || PlotType == PLOT_SKY || PlotType == PLOT_SDOP || + PlotType == PLOT_DOP || PlotType == PLOT_SNR || PlotType == PLOT_SNRE || + PlotType == PLOT_MPS; + QFlag->Enabled = data; + ObsType->Enabled = data && !SimObs; + ObsType2->Enabled = data && !SimObs; + + Panel102->Visible = PlotType == PLOT_SOLP || PlotType == PLOT_SOLV || PlotType == PLOT_SOLA || + PlotType == PLOT_NSAT || PlotType == PLOT_RES || PlotType == PLOT_RESE || + PlotType == PLOT_SNR || PlotType == PLOT_SNRE; + BtnOn1->Enabled = plot || PlotType == PLOT_SNR || PlotType == PLOT_RES || PlotType == PLOT_RESE || + PlotType == PLOT_SNRE; + BtnOn2->Enabled = plot || PlotType == PLOT_SNR || PlotType == PLOT_RES || PlotType == PLOT_RESE || + PlotType == PLOT_SNRE; + BtnOn3->Enabled = plot || PlotType == PLOT_SNR || PlotType == PLOT_RES; + + BtnCenterOri->Visible = PlotType == PLOT_TRK || PlotType == PLOT_SOLP || PlotType == PLOT_SOLV || + PlotType == PLOT_SOLA || PlotType == PLOT_NSAT; + BtnCenterOri->Enabled = PlotType != PLOT_NSAT; + BtnRangeList->Visible = PlotType == PLOT_TRK || PlotType == PLOT_SOLP || PlotType == PLOT_SOLV || + PlotType == PLOT_SOLA || PlotType == PLOT_NSAT; + BtnRangeList->Enabled = PlotType != PLOT_NSAT; + + BtnFitHoriz->Visible = PlotType == PLOT_SOLP || PlotType == PLOT_SOLV || PlotType == PLOT_SOLA || + PlotType == PLOT_NSAT || PlotType == PLOT_RES || PlotType == PLOT_OBS || + PlotType == PLOT_DOP || PlotType == PLOT_SDOP || PlotType == PLOT_SNR || + PlotType == PLOT_SNRE; + BtnFitHoriz->Enabled = data; + BtnFitVert->Visible = PlotType == PLOT_TRK || PlotType == PLOT_SOLP || PlotType == PLOT_SOLV || + PlotType == PLOT_SOLA; + BtnFitVert->Enabled = data; + BtnShowTrack->Enabled = data; + BtnFixCent->Visible = PlotType == PLOT_TRK; + BtnFixCent->Enabled = data; + BtnFixHoriz->Visible = PlotType == PLOT_SOLP || PlotType == PLOT_SOLV || PlotType == PLOT_SOLA || + PlotType == PLOT_NSAT || PlotType == PLOT_RES || PlotType == PLOT_OBS || + PlotType == PLOT_DOP || PlotType == PLOT_DOP || PlotType == PLOT_SNR; + BtnFixHoriz->Enabled = data; + BtnFixVert->Visible = PlotType == PLOT_SOLP || PlotType == PLOT_SOLV || PlotType == PLOT_SOLA; + BtnFixVert->Enabled = data; + BtnShowGrid->Visible = PlotType == PLOT_TRK; + BtnShowSkyplot->Visible = PlotType == PLOT_SKY || PlotType == PLOT_MPS; + BtnShowMap->Visible = PlotType == PLOT_TRK; + BtnShowMap->Enabled = !BtnSol12->Down; + BtnShowImg->Visible = + PlotType == PLOT_TRK || PlotType == PLOT_SKY || PlotType == PLOT_SSKY || PlotType == PLOT_MPS; + BtnMapView->Visible = PlotType == PLOT_TRK || PlotType == PLOT_SOLP; + Panel12->Visible = !ConnectState; + BtnAnimate->Visible = data && BtnShowTrack->Down; + TimeScroll->Visible = data && BtnShowTrack->Down; + TimeScroll->Enabled = data && BtnShowTrack->Down; + + if (!BtnShowTrack->Down) { + BtnFixHoriz->Enabled = false; + BtnFixVert->Enabled = false; + BtnFixCent->Enabled = false; + BtnAnimate->Down = false; + } + BtnRangeList->Left = BtnCenterOri->Left + BtnCenterOri->Width; + BtnFitHoriz->Left = Panel104->Left + Panel104->Width; + BtnFitVert->Left = BtnFitHoriz->Left + BtnFitHoriz->Width; + BtnShowTrack->Left = BtnFitVert->Left + BtnFitVert->Width; + BtnFixCent->Left = BtnShowTrack->Left + BtnShowTrack->Width; + BtnFixHoriz->Left = BtnFixCent->Left + BtnFixCent->Width; + BtnFixVert->Left = BtnFixHoriz->Left + BtnFixHoriz->Width; + BtnShowGrid->Left = BtnFixVert->Left + BtnFixVert->Width; + BtnShowSkyplot->Left = BtnShowGrid->Left + BtnShowGrid->Width; + BtnShowMap->Left = BtnShowSkyplot->Left + BtnShowSkyplot->Width; + BtnShowImg->Left = BtnShowMap->Left + BtnShowMap->Width; + BtnMapView->Left = BtnShowImg->Left + BtnShowImg->Width; + + BtnFreq->Left = BtnClear->Left - BtnFreq->Width; + + MenuMapImg->Enabled = MapImage->Height > 0; + MenuSkyImg->Enabled = SkyImageI->Height > 0; + MenuSrcSol->Enabled = SolFiles[sel]->Count > 0; + MenuSrcObs->Enabled = ObsFiles->Count > 0; + MenuMapLayer->Enabled = true; + MenuShowTrack->Enabled = BtnShowTrack->Enabled; + MenuFitHoriz->Enabled = BtnFitHoriz->Enabled; + MenuFitVert->Enabled = BtnFitVert->Enabled; + MenuCenterOri->Enabled = BtnCenterOri->Enabled; + MenuFixCent->Enabled = BtnFixCent->Enabled; + MenuFixHoriz->Enabled = BtnFixHoriz->Enabled; + MenuFixVert->Enabled = BtnFixVert->Enabled; + MenuShowMap->Enabled = BtnShowMap->Enabled; + MenuShowImg->Enabled = BtnShowImg->Enabled; + MenuShowSkyplot->Enabled = BtnShowSkyplot->Visible; + MenuShowGrid->Enabled = BtnShowGrid->Visible; + MenuMapView->Enabled = BtnMapView->Enabled; + MenuShowTrack->Checked = BtnShowTrack->Down; + MenuFixCent->Checked = BtnFixCent->Down; + MenuFixHoriz->Checked = BtnFixHoriz->Down; + MenuFixVert->Checked = BtnFixVert->Down; + MenuShowSkyplot->Checked = BtnShowSkyplot->Down; + MenuShowGrid->Checked = BtnShowGrid->Down; + MenuShowMap->Checked = BtnShowMap->Down; + MenuShowImg->Checked = BtnShowImg->Down; + MenuAnimStart->Enabled = !ConnectState && BtnAnimate->Enabled && !BtnAnimate->Down; + MenuAnimStop->Enabled = !ConnectState && BtnAnimate->Enabled && BtnAnimate->Down; + MenuOpenSol1->Enabled = !ConnectState; + MenuOpenSol2->Enabled = !ConnectState; + MenuConnect->Enabled = !ConnectState; + MenuDisconnect->Enabled = ConnectState; + MenuPort->Enabled = !ConnectState; + MenuOpenObs->Enabled = !ConnectState; + MenuOpenNav->Enabled = !ConnectState; + MenuOpenElevMask->Enabled = !ConnectState; + MenuReload->Enabled = !ConnectState; + + BtnReload->Enabled = !ConnectState; + StrStatus->Enabled = ConnectState; + BtnFreq->Visible = FrqType->Visible || ObsType->Visible || ObsType2->Visible; + StrStatus->Left = BtnOptions->Left - StrStatus->Width + 1; } // linear-fitting of positions ---------------------------------------------- -int __fastcall TPlot::FitPos(gtime_t *time, double *opos, double *ovel) -{ - sol_t *sol; - int i,j; - double t,x[2],Ay[3][2]={{0}},AA[3][4]={{0}}; - - trace(3,"FitPos\n"); - - if (SolData[0].n<=0) return 0; - - for (i=0;(sol=getsol(SolData,i));i++) { - if (sol->type!=0) continue; - if (time->time==0) *time=sol->time; - t=timediff(sol->time,*time); - - for (j=0;j<3;j++) { - Ay[j][0]+=sol->rr[j]; - Ay[j][1]+=sol->rr[j]*t; - AA[j][0]+=1.0; - AA[j][1]+=t; - AA[j][2]+=t; - AA[j][3]+=t*t; - } - } - for (i=0;i<3;i++) { - if (solve("N",AA[i],Ay[i],2,1,x)) return 0; - opos[i]=x[0]; - ovel[i]=x[1]; - } - return 1; +int __fastcall TPlot::FitPos(gtime_t *time, double *opos, double *ovel) { + sol_t *sol; + int i, j; + double t, x[2], Ay[3][2] = {{0}}, AA[3][4] = {{0}}; + + trace(3, "FitPos\n"); + + if (SolData[0].n <= 0) return 0; + + for (i = 0; (sol = getsol(SolData, i)); i++) { + if (sol->type != 0) continue; + if (time->time == 0) *time = sol->time; + t = timediff(sol->time, *time); + + for (j = 0; j < 3; j++) { + Ay[j][0] += sol->rr[j]; + Ay[j][1] += sol->rr[j] * t; + AA[j][0] += 1.0; + AA[j][1] += t; + AA[j][2] += t; + AA[j][3] += t * t; + } + } + for (i = 0; i < 3; i++) { + if (solve("N", AA[i], Ay[i], 2, 1, x)) return 0; + opos[i] = x[0]; + ovel[i] = x[1]; + } + return 1; } // fit time-range of plot --------------------------------------------------- -void __fastcall TPlot::FitTime(void) -{ - sol_t *sols,*sole; - double tl[2]={86400.0*7,0.0},tp[2],xl[2],yl[2],zl[2]; - int sel=!BtnSol1->Down&&BtnSol2->Down?1:0; - - trace(3,"FitTime\n"); - - sols=getsol(SolData+sel,0); - sole=getsol(SolData+sel,SolData[sel].n-1); - - if (sols&&sole) { - tl[0]=MIN(tl[0],TimePos(sols->time)); - tl[1]=MAX(tl[1],TimePos(sole->time)); - } - if (Obs.n>0) { - tl[0]=MIN(tl[0],TimePos(Obs.data[0].time)); - tl[1]=MAX(tl[1],TimePos(Obs.data[Obs.n-1].time)); - } - if (TimeEna[0]) tl[0]=TimePos(TimeStart); - if (TimeEna[1]) tl[1]=TimePos(TimeEnd ); - - if (tl[0]==tl[1]) { - tl[0]=tl[0]-DEFTSPAN/2.0; - tl[1]=tl[0]+DEFTSPAN/2.0; - } - else if (tl[0]>tl[1]) { - tl[0]=-DEFTSPAN/2.0; - tl[1]= DEFTSPAN/2.0; - } - GraphG[0]->GetLim(tp,xl); - GraphG[1]->GetLim(tp,yl); - GraphG[2]->GetLim(tp,zl); - GraphG[0]->SetLim(tl,xl); - GraphG[1]->SetLim(tl,yl); - GraphG[2]->SetLim(tl,zl); - GraphR ->GetLim(tp,xl); - GraphR ->SetLim(tl,xl); +void __fastcall TPlot::FitTime(void) { + sol_t *sols, *sole; + double tl[2] = {86400.0 * 7, 0.0}, tp[2], xl[2], yl[2], zl[2]; + int sel = !BtnSol1->Down && BtnSol2->Down ? 1 : 0; + + trace(3, "FitTime\n"); + + sols = getsol(SolData + sel, 0); + sole = getsol(SolData + sel, SolData[sel].n - 1); + + if (sols && sole) { + tl[0] = MIN(tl[0], TimePos(sols->time)); + tl[1] = MAX(tl[1], TimePos(sole->time)); + } + if (Obs.n > 0) { + tl[0] = MIN(tl[0], TimePos(Obs.data[0].time)); + tl[1] = MAX(tl[1], TimePos(Obs.data[Obs.n - 1].time)); + } + if (TimeEna[0]) tl[0] = TimePos(TimeStart); + if (TimeEna[1]) tl[1] = TimePos(TimeEnd); + + if (tl[0] == tl[1]) { + tl[0] = tl[0] - DEFTSPAN / 2.0; + tl[1] = tl[0] + DEFTSPAN / 2.0; + } else if (tl[0] > tl[1]) { + tl[0] = -DEFTSPAN / 2.0; + tl[1] = DEFTSPAN / 2.0; + } + GraphG[0]->GetLim(tp, xl); + GraphG[1]->GetLim(tp, yl); + GraphG[2]->GetLim(tp, zl); + GraphG[0]->SetLim(tl, xl); + GraphG[1]->SetLim(tl, yl); + GraphG[2]->SetLim(tl, zl); + GraphR->GetLim(tp, xl); + GraphR->SetLim(tl, xl); } // set x/y-range of plot ---------------------------------------------------- -void __fastcall TPlot::SetRange(int all, double range) -{ - double xl[]={-range,range}; - double yl[]={-range,range}; - double zl[]={-range,range}; - double xs,ys,tl[2],xp[2],pos[3]; - int w,h; - - trace(3,"SetRange: all=%d range=%.3f\n",all,range); - - if (all||PlotType==PLOT_TRK) { - GraphT->SetLim(xl,yl); - GraphT->GetScale(xs,ys); - GraphT->SetScale(MAX(xs,ys),MAX(xs,ys)); - if (norm(OPos,3)>0.0) { - ecef2pos(OPos,pos); - MapView->SetCent(pos[0]*R2D,pos[1]*R2D); - } - } - if (PLOT_SOLP<=PlotType&&PlotType<=PLOT_SOLA) { - GraphG[0]->GetLim(tl,xp); - GraphG[0]->SetLim(tl,xl); - GraphG[1]->SetLim(tl,yl); - GraphG[2]->SetLim(tl,zl); - } - else if (PlotType==PLOT_NSAT) { - GraphG[0]->GetLim(tl,xp); - xl[0]=yl[0]=zl[0]=0.0; - xl[1]=MaxDop; - yl[1]=YLIM_AGE; - zl[1]=YLIM_RATIO; - GraphG[0]->SetLim(tl,xl); - GraphG[1]->SetLim(tl,yl); - GraphG[2]->SetLim(tl,zl); - } - else if (PlotTypeGetLim(tl,xp); - xl[0]=-MaxMP; xl[1]=MaxMP; - yl[0]=-MaxMP/100.0; yl[1]=MaxMP/100.0; - zl[0]= 0.0; zl[1]=90.0; - GraphG[0]->SetLim(tl,xl); - GraphG[1]->SetLim(tl,yl); - GraphG[2]->SetLim(tl,zl); - } - else { - GraphG[0]->GetLim(tl,xp); - xl[0]=10.0; xl[1]= 60.0; - yl[0]=-MaxMP; yl[1]=MaxMP; - zl[0]= 0.0; zl[1]= 90.0; - GraphG[0]->SetLim(tl,xl); - GraphG[1]->SetLim(tl,yl); - GraphG[2]->SetLim(tl,zl); - } +void __fastcall TPlot::SetRange(int all, double range) { + double xl[] = {-range, range}; + double yl[] = {-range, range}; + double zl[] = {-range, range}; + double xs, ys, tl[2], xp[2], pos[3]; + int w, h; + + trace(3, "SetRange: all=%d range=%.3f\n", all, range); + + if (all || PlotType == PLOT_TRK) { + GraphT->SetLim(xl, yl); + GraphT->GetScale(xs, ys); + GraphT->SetScale(MAX(xs, ys), MAX(xs, ys)); + if (norm(OPos, 3) > 0.0) { + ecef2pos(OPos, pos); + MapView->SetCent(pos[0] * R2D, pos[1] * R2D); + } + } + if (PLOT_SOLP <= PlotType && PlotType <= PLOT_SOLA) { + GraphG[0]->GetLim(tl, xp); + GraphG[0]->SetLim(tl, xl); + GraphG[1]->SetLim(tl, yl); + GraphG[2]->SetLim(tl, zl); + } else if (PlotType == PLOT_NSAT) { + GraphG[0]->GetLim(tl, xp); + xl[0] = yl[0] = zl[0] = 0.0; + xl[1] = MaxDop; + yl[1] = YLIM_AGE; + zl[1] = YLIM_RATIO; + GraphG[0]->SetLim(tl, xl); + GraphG[1]->SetLim(tl, yl); + GraphG[2]->SetLim(tl, zl); + } else if (PlotType < PLOT_SNR) { + GraphG[0]->GetLim(tl, xp); + xl[0] = -MaxMP; + xl[1] = MaxMP; + yl[0] = -MaxMP / 100.0; + yl[1] = MaxMP / 100.0; + zl[0] = 0.0; + zl[1] = 90.0; + GraphG[0]->SetLim(tl, xl); + GraphG[1]->SetLim(tl, yl); + GraphG[2]->SetLim(tl, zl); + } else { + GraphG[0]->GetLim(tl, xp); + xl[0] = 10.0; + xl[1] = 60.0; + yl[0] = -MaxMP; + yl[1] = MaxMP; + zl[0] = 0.0; + zl[1] = 90.0; + GraphG[0]->SetLim(tl, xl); + GraphG[1]->SetLim(tl, yl); + GraphG[2]->SetLim(tl, zl); + } } // fit x/y-range of plot ---------------------------------------------------- -void __fastcall TPlot::FitRange(int all) -{ - TIMEPOS *pos,*pos1,*pos2; - sol_t *data; - double xs,ys,xp[2],tl[2],xl[]={1E8,-1E8},yl[2]={1E8,-1E8},zl[2]={1E8,-1E8}; - double lat,lon,lats[2]={90,-90},lons[2]={180,-180},llh[3]; - int i,j,n,w,h,type=PlotType-PLOT_SOLP; - - trace(3,"FitRange: all=%d\n",all); - - BtnFixHoriz->Down=false; - MenuFixHoriz->Checked=false; - +void __fastcall TPlot::FitRange(int all) { + TIMEPOS *pos, *pos1, *pos2; + sol_t *data; + double xs, ys, xp[2], tl[2], xl[] = {1E8, -1E8}, yl[2] = {1E8, -1E8}, zl[2] = {1E8, -1E8}; + double lat, lon, lats[2] = {90, -90}, lons[2] = {180, -180}, llh[3]; + int i, j, n, w, h, type = PlotType - PLOT_SOLP; + + trace(3, "FitRange: all=%d\n", all); + + BtnFixHoriz->Down = false; + MenuFixHoriz->Checked = false; + + if (BtnSol1->Down) { + pos = SolToPos(SolData, -1, QFlag->ItemIndex, type); + + for (i = 0; i < pos->n; i++) { + xl[0] = MIN(xl[0], pos->x[i]); + yl[0] = MIN(yl[0], pos->y[i]); + zl[0] = MIN(zl[0], pos->z[i]); + xl[1] = MAX(xl[1], pos->x[i]); + yl[1] = MAX(yl[1], pos->y[i]); + zl[1] = MAX(zl[1], pos->z[i]); + } + delete pos; + } + if (BtnSol2->Down) { + pos = SolToPos(SolData + 1, -1, QFlag->ItemIndex, type); + + for (i = 0; i < pos->n; i++) { + xl[0] = MIN(xl[0], pos->x[i]); + yl[0] = MIN(yl[0], pos->y[i]); + zl[0] = MIN(zl[0], pos->z[i]); + xl[1] = MAX(xl[1], pos->x[i]); + yl[1] = MAX(yl[1], pos->y[i]); + zl[1] = MAX(zl[1], pos->z[i]); + } + delete pos; + } + if (BtnSol12->Down) { + pos1 = SolToPos(SolData, -1, 0, type); + pos2 = SolToPos(SolData + 1, -1, 0, type); + pos = pos1->diff(pos2, QFlag->ItemIndex); + + for (i = 0; i < pos->n; i++) { + xl[0] = MIN(xl[0], pos->x[i]); + yl[0] = MIN(yl[0], pos->y[i]); + zl[0] = MIN(zl[0], pos->z[i]); + xl[1] = MAX(xl[1], pos->x[i]); + yl[1] = MAX(yl[1], pos->y[i]); + zl[1] = MAX(zl[1], pos->z[i]); + } + delete pos1; + delete pos2; + delete pos; + } + // add margins + xl[0] -= 0.015; + xl[1] += 0.015; + yl[0] -= 0.015; + yl[1] += 0.015; + zl[0] -= 0.015; + zl[1] += 0.015; + + if (all || PlotType == PLOT_TRK) { + GraphT->SetLim(xl, yl); + GraphT->GetScale(xs, ys); + GraphT->SetScale(MAX(xs, ys), MAX(xs, ys)); + } + if (all || PlotType <= PLOT_SOLA || PlotType == PLOT_RES) { + GraphG[0]->GetLim(tl, xp); + GraphG[0]->SetLim(tl, xl); + GraphG[1]->SetLim(tl, yl); + GraphG[2]->SetLim(tl, zl); + } + if (all) { if (BtnSol1->Down) { - - pos=SolToPos(SolData,-1,QFlag->ItemIndex,type); - - for (i=0;in;i++) { - xl[0]=MIN(xl[0],pos->x[i]); - yl[0]=MIN(yl[0],pos->y[i]); - zl[0]=MIN(zl[0],pos->z[i]); - xl[1]=MAX(xl[1],pos->x[i]); - yl[1]=MAX(yl[1],pos->y[i]); - zl[1]=MAX(zl[1],pos->z[i]); - } - delete pos; + for (i = 0; (data = getsol(SolData, i)); i++) { + ecef2pos(data->rr, llh); + lats[0] = MIN(lats[0], llh[0] * R2D); + lons[0] = MIN(lons[0], llh[1] * R2D); + lats[1] = MAX(lats[1], llh[0] * R2D); + lons[1] = MAX(lons[1], llh[1] * R2D); + } } if (BtnSol2->Down) { - - pos=SolToPos(SolData+1,-1,QFlag->ItemIndex,type); - - for (i=0;in;i++) { - xl[0]=MIN(xl[0],pos->x[i]); - yl[0]=MIN(yl[0],pos->y[i]); - zl[0]=MIN(zl[0],pos->z[i]); - xl[1]=MAX(xl[1],pos->x[i]); - yl[1]=MAX(yl[1],pos->y[i]); - zl[1]=MAX(zl[1],pos->z[i]); - } - delete pos; - } - if (BtnSol12->Down) { - - pos1=SolToPos(SolData ,-1,0,type); - pos2=SolToPos(SolData+1,-1,0,type); - pos=pos1->diff(pos2,QFlag->ItemIndex); - - for (i=0;in;i++) { - xl[0]=MIN(xl[0],pos->x[i]); - yl[0]=MIN(yl[0],pos->y[i]); - zl[0]=MIN(zl[0],pos->z[i]); - xl[1]=MAX(xl[1],pos->x[i]); - yl[1]=MAX(yl[1],pos->y[i]); - zl[1]=MAX(zl[1],pos->z[i]); - } - delete pos1; - delete pos2; - delete pos; + for (i = 0; (data = getsol(SolData + 1, i)); i++) { + ecef2pos(data->rr, llh); + lats[0] = MIN(lats[0], llh[0] * R2D); + lons[0] = MIN(lons[0], llh[1] * R2D); + lats[1] = MAX(lats[1], llh[0] * R2D); + lons[1] = MAX(lons[1], llh[1] * R2D); + } } - // add margins - xl[0]-=0.015; - xl[1]+=0.015; - yl[0]-=0.015; - yl[1]+=0.015; - zl[0]-=0.015; - zl[1]+=0.015; - - if (all||PlotType==PLOT_TRK) { - GraphT->SetLim(xl,yl); - GraphT->GetScale(xs,ys); - GraphT->SetScale(MAX(xs,ys),MAX(xs,ys)); - } - if (all||PlotType<=PLOT_SOLA||PlotType==PLOT_RES) { - GraphG[0]->GetLim(tl,xp); - GraphG[0]->SetLim(tl,xl); - GraphG[1]->SetLim(tl,yl); - GraphG[2]->SetLim(tl,zl); - } - if (all) { - if (BtnSol1->Down) { - for (i=0;(data=getsol(SolData,i));i++) { - ecef2pos(data->rr,llh); - lats[0]=MIN(lats[0],llh[0]*R2D); - lons[0]=MIN(lons[0],llh[1]*R2D); - lats[1]=MAX(lats[1],llh[0]*R2D); - lons[1]=MAX(lons[1],llh[1]*R2D); - } - } - if (BtnSol2->Down) { - for (i=0;(data=getsol(SolData+1,i));i++) { - ecef2pos(data->rr,llh); - lats[0]=MIN(lats[0],llh[0]*R2D); - lons[0]=MIN(lons[0],llh[1]*R2D); - lats[1]=MAX(lats[1],llh[0]*R2D); - lons[1]=MAX(lons[1],llh[1]*R2D); - } - } - if (lats[0]<=lats[1]&&lons[0]<=lons[1]) { - lat=(lats[0]+lats[1])/2.0; - lon=(lons[0]+lons[1])/2.0; - } + if (lats[0] <= lats[1] && lons[0] <= lons[1]) { + lat = (lats[0] + lats[1]) / 2.0; + lon = (lons[0] + lons[1]) / 2.0; } + } } // set center of track plot ------------------------------------------------- -void __fastcall TPlot::SetTrkCent(double lat, double lon) -{ - gtime_t time={0}; - double pos[3]={0},rr[3],xyz[3]; - - if (PlotType!=PLOT_TRK) return; - pos[0]=lat*D2R; - pos[1]=lon*D2R; - pos2ecef(pos,rr); - PosToXyz(time,rr,0,xyz); - GraphT->SetCent(xyz[0],xyz[1]); - UpdatePlot(); +void __fastcall TPlot::SetTrkCent(double lat, double lon) { + gtime_t time = {0}; + double pos[3] = {0}, rr[3], xyz[3]; + + if (PlotType != PLOT_TRK) return; + pos[0] = lat * D2R; + pos[1] = lon * D2R; + pos2ecef(pos, rr); + PosToXyz(time, rr, 0, xyz); + GraphT->SetCent(xyz[0], xyz[1]); + UpdatePlot(); } // load options from ini-file ----------------------------------------------- -void __fastcall TPlot::LoadOpt(void) -{ - TIniFile *ini=new TIniFile(IniFile); - AnsiString s; - - trace(3,"LoadOpt\n"); - -// PlotType =ini->ReadInteger("plot","plottype", 0); - TimeLabel =ini->ReadInteger("plot","timelabel", 1); - LatLonFmt =ini->ReadInteger("plot","latlonfmt", 0); - AutoScale =ini->ReadInteger("plot","autoscale", 1); - ShowStats =ini->ReadInteger("plot","showstats", 0); - ShowLabel =ini->ReadInteger("plot","showlabel", 1); - ShowGLabel =ini->ReadInteger("plot","showglabel", 2); - ShowCompass =ini->ReadInteger("plot","showcompass", 0); - ShowScale =ini->ReadInteger("plot","showscale", 1); - ShowArrow =ini->ReadInteger("plot","showarrow", 0); - ShowSlip =ini->ReadInteger("plot","showslip", 2); - ShowHalfC =ini->ReadInteger("plot","showhalfc", 1); - ShowErr =ini->ReadInteger("plot","showerr", 0); - ShowEph =ini->ReadInteger("plot","showeph", 0); - PlotStyle =ini->ReadInteger("plot","plotstyle", 0); - MarkSize =ini->ReadInteger("plot","marksize", 2); - NavSys =ini->ReadInteger("plot","navsys", SYS_ALL); - AnimCycle =ini->ReadInteger("plot","animcycle", 10); - RefCycle =ini->ReadInteger("plot","refcycle", 100); - HideLowSat =ini->ReadInteger("plot","hidelowsat", 0); - ElMaskP =ini->ReadInteger("plot","elmaskp", 0); - ExSats =ini->ReadString ("plot","exsats", ""); - RtBuffSize =ini->ReadInteger("plot","rtbuffsize",10800); - TimeSyncOut =ini->ReadInteger("plot","timesyncout", 0); - TimeSyncPort =ini->ReadInteger("plot","timesyncport",10071); - RtStream[0] =ini->ReadInteger("plot","rtstream1", 0); - RtStream[1] =ini->ReadInteger("plot","rtstream2", 0); - RtFormat[0] =ini->ReadInteger("plot","rtformat1", 0); - RtFormat[1] =ini->ReadInteger("plot","rtformat2", 0); - RtTimeForm =ini->ReadInteger("plot","rttimeform", 0); - RtDegForm =ini->ReadInteger("plot","rtdegform", 0); - RtFieldSep =ini->ReadString ("plot","rtfieldsep", ""); - RtTimeOutTime=ini->ReadInteger("plot","rttimeouttime", 0); - RtReConnTime =ini->ReadInteger("plot","rtreconntime",10000); - - MColor[0][0]=(TColor)ini->ReadInteger("plot","mcolor0", (int)clSilver ); - MColor[0][1]=(TColor)ini->ReadInteger("plot","mcolor1", (int)clGreen ); - MColor[0][2]=(TColor)ini->ReadInteger("plot","mcolor2", 0x00AAFF ); - MColor[0][3]=(TColor)ini->ReadInteger("plot","mcolor3", (int)clFuchsia); - MColor[0][4]=(TColor)ini->ReadInteger("plot","mcolor4", (int)clBlue ); - MColor[0][5]=(TColor)ini->ReadInteger("plot","mcolor5", (int)clRed ); - MColor[0][6]=(TColor)ini->ReadInteger("plot","mcolor6", (int)clTeal ); - MColor[0][7]=(TColor)ini->ReadInteger("plot","mcolor7", (int)clGray ); - MColor[1][0]=(TColor)ini->ReadInteger("plot","mcolor8", (int)clSilver ); - MColor[1][1]=(TColor)ini->ReadInteger("plot","mcolor9", 0x804000 ); - MColor[1][2]=(TColor)ini->ReadInteger("plot","mcolor10", 0x008080 ); - MColor[1][3]=(TColor)ini->ReadInteger("plot","mcolor11", 0xFF0080 ); - MColor[1][4]=(TColor)ini->ReadInteger("plot","mcolor12", 0xFF8000 ); - MColor[1][5]=(TColor)ini->ReadInteger("plot","mcolor13", 0x8080FF ); - MColor[1][6]=(TColor)ini->ReadInteger("plot","mcolor14", 0xFF8080 ); - MColor[1][7]=(TColor)ini->ReadInteger("plot","mcolor15",(int)clGray ); - MapColor[0]=(TColor)ini->ReadInteger("plot","mapcolor1", clSilver ); - MapColor[1]=(TColor)ini->ReadInteger("plot","mapcolor2", clSilver ); - MapColor[2]=(TColor)ini->ReadInteger("plot","mapcolor3", 0xF0D0D0 ); - MapColor[3]=(TColor)ini->ReadInteger("plot","mapcolor4", 0xD0F0D0 ); - MapColor[4]=(TColor)ini->ReadInteger("plot","mapcolor5", 0xD0D0F0 ); - MapColor[5]=(TColor)ini->ReadInteger("plot","mapcolor6", 0xD0F0F0 ); - MapColor[6]=(TColor)ini->ReadInteger("plot","mapcolor7", 0xF8F8D0 ); - MapColor[7]=(TColor)ini->ReadInteger("plot","mapcolor8", 0xF0F0F0 ); - MapColor[8]=(TColor)ini->ReadInteger("plot","mapcolor9", 0xF0F0F0 ); - MapColor[9]=(TColor)ini->ReadInteger("plot","mapcolor10", 0xF0F0F0 ); - MapColor[10]=(TColor)ini->ReadInteger("plot","mapcolor11", 0xF0F0F0 ); - MapColor[11]=(TColor)ini->ReadInteger("plot","mapcolor12", 0xF0F0F0 ); - MapColorF[0]=(TColor)ini->ReadInteger("plot","mapcolorf1", clWhite ); - MapColorF[1]=(TColor)ini->ReadInteger("plot","mapcolorf2", clWhite ); - MapColorF[2]=(TColor)ini->ReadInteger("plot","mapcolorf3", clWhite ); - MapColorF[3]=(TColor)ini->ReadInteger("plot","mapcolorf4", clWhite ); - MapColorF[4]=(TColor)ini->ReadInteger("plot","mapcolorf5", clWhite ); - MapColorF[5]=(TColor)ini->ReadInteger("plot","mapcolorf6", clWhite ); - MapColorF[6]=(TColor)ini->ReadInteger("plot","mapcolorf7", clWhite ); - MapColorF[7]=(TColor)ini->ReadInteger("plot","mapcolorf8", clWhite ); - MapColorF[8]=(TColor)ini->ReadInteger("plot","mapcolorf9", clWhite ); - MapColorF[9]=(TColor)ini->ReadInteger("plot","mapcolorf10", clWhite ); - MapColorF[10]=(TColor)ini->ReadInteger("plot","mapcolorf11", clWhite ); - MapColorF[11]=(TColor)ini->ReadInteger("plot","mapcolorf12", clWhite ); - CColor[0]=(TColor)ini->ReadInteger("plot","color1", (int)clWhite ); - CColor[1]=(TColor)ini->ReadInteger("plot","color2", (int)clSilver ); - CColor[2]=(TColor)ini->ReadInteger("plot","color3", (int)clBlack ); - CColor[3]=(TColor)ini->ReadInteger("plot","color4", (int)clSilver ); - - RefDialog->StaPosFile=ini->ReadString ("plot","staposfile",""); - - ElMask =ini->ReadFloat ("plot","elmask", 0.0); - MaxDop =ini->ReadFloat ("plot","maxdop",30.0); - MaxMP =ini->ReadFloat ("plot","maxmp" ,10.0); - YRange =ini->ReadFloat ("plot","yrange", 5.0); - Origin =ini->ReadInteger("plot","orgin", 4); - RcvPos =ini->ReadInteger("plot","rcvpos", 0); - OOPos[0] =ini->ReadFloat ("plot","oopos1", 0); - OOPos[1] =ini->ReadFloat ("plot","oopos2", 0); - OOPos[2] =ini->ReadFloat ("plot","oopos3", 0); - ShapeFile =ini->ReadString ("plot","shapefile",""); - TLEFile =ini->ReadString ("plot","tlefile", ""); - TLESatFile=ini->ReadString ("plot","tlesatfile",""); - - FontName =ini->ReadString ("plot","fontname","Tahoma"); - FontSize =ini->ReadInteger("plot","fontsize",8); - Font->Charset=ANSI_CHARSET; - Font->Name=FontName; - Font->Size=FontSize; - - RnxOpts =ini->ReadString ("plot","rnxopts",""); - - MapApi =ini->ReadInteger("mapview","mapapi" , 0); - ApiKey =ini->ReadString ("mapview","apikey" ,""); - MapStrs[0][0]=ini->ReadString("mapview","mapstrs_0_0","OpenStreetMap"); - MapStrs[0][1]=ini->ReadString("mapview","mapstrs_0_1","https://tile.openstreetmap.org/{z}/{x}/{y}.png"); - MapStrs[0][2]=ini->ReadString("mapview","mapstrs_0_2","https://osm.org/copyright"); - for (int i=1;i<6;i++) for (int j=0;j<3;j++) { - MapStrs[i][j]=ini->ReadString("mapview",s.sprintf("mapstrs_%d_%d",i,j),""); - } - for (int i=0;i<2;i++) { - StrCmds [0][i]=ini->ReadString ("str",s.sprintf("strcmd1_%d", i),""); - StrCmds [1][i]=ini->ReadString ("str",s.sprintf("strcmd2_%d", i),""); - StrCmdEna[0][i]=ini->ReadInteger("str",s.sprintf("strcmdena1_%d", i), 0); - StrCmdEna[1][i]=ini->ReadInteger("str",s.sprintf("strcmdena2_%d", i), 0); - } - for (int i=0;i<3;i++) { - StrPaths[0][i]=ini->ReadString ("str",s.sprintf("strpath1_%d", i),""); - StrPaths[1][i]=ini->ReadString ("str",s.sprintf("strpath2_%d", i),""); - } - for (int i=0;i<10;i++) { - StrHistory [i]=ini->ReadString ("str",s.sprintf("strhistry_%d", i),""); - } - TTextViewer::Color1=(TColor)ini->ReadInteger("viewer","color1",(int)clBlack); - TTextViewer::Color2=(TColor)ini->ReadInteger("viewer","color2",(int)clWhite); - TTextViewer::FontD=new TFont; - TTextViewer::FontD->Name=ini->ReadString ("viewer","fontname","Consolas"); - TTextViewer::FontD->Size=ini->ReadInteger("viewer","fontsize",9); - - MenuBrowse->Checked=ini->ReadInteger("solbrows","show", 0); - PanelBrowse->Width =ini->ReadInteger("solbrows","split1", 100); - DirSel->Height =ini->ReadInteger("solbrows","split2", 150); - try { - DirSel->Directory =ini->ReadString ("solbrows","dir", "C:\\"); - } - catch (Exception &exception) { - ; +void __fastcall TPlot::LoadOpt(void) { + TIniFile *ini = new TIniFile(IniFile); + AnsiString s; + + trace(3, "LoadOpt\n"); + + // PlotType =ini->ReadInteger("plot","plottype", 0); + TimeLabel = ini->ReadInteger("plot", "timelabel", 1); + LatLonFmt = ini->ReadInteger("plot", "latlonfmt", 0); + AutoScale = ini->ReadInteger("plot", "autoscale", 1); + ShowStats = ini->ReadInteger("plot", "showstats", 0); + ShowLabel = ini->ReadInteger("plot", "showlabel", 1); + ShowGLabel = ini->ReadInteger("plot", "showglabel", 2); + ShowCompass = ini->ReadInteger("plot", "showcompass", 0); + ShowScale = ini->ReadInteger("plot", "showscale", 1); + ShowArrow = ini->ReadInteger("plot", "showarrow", 0); + ShowSlip = ini->ReadInteger("plot", "showslip", 2); + ShowHalfC = ini->ReadInteger("plot", "showhalfc", 1); + ShowErr = ini->ReadInteger("plot", "showerr", 0); + ShowEph = ini->ReadInteger("plot", "showeph", 0); + PlotStyle = ini->ReadInteger("plot", "plotstyle", 0); + MarkSize = ini->ReadInteger("plot", "marksize", 2); + NavSys = ini->ReadInteger("plot", "navsys", SYS_ALL); + AnimCycle = ini->ReadInteger("plot", "animcycle", 10); + RefCycle = ini->ReadInteger("plot", "refcycle", 100); + HideLowSat = ini->ReadInteger("plot", "hidelowsat", 0); + ElMaskP = ini->ReadInteger("plot", "elmaskp", 0); + ExSats = ini->ReadString("plot", "exsats", ""); + RtBuffSize = ini->ReadInteger("plot", "rtbuffsize", 10800); + TimeSyncOut = ini->ReadInteger("plot", "timesyncout", 0); + TimeSyncPort = ini->ReadInteger("plot", "timesyncport", 10071); + RtStream[0] = ini->ReadInteger("plot", "rtstream1", 0); + RtStream[1] = ini->ReadInteger("plot", "rtstream2", 0); + RtFormat[0] = ini->ReadInteger("plot", "rtformat1", 0); + RtFormat[1] = ini->ReadInteger("plot", "rtformat2", 0); + RtTimeForm = ini->ReadInteger("plot", "rttimeform", 0); + RtDegForm = ini->ReadInteger("plot", "rtdegform", 0); + RtFieldSep = ini->ReadString("plot", "rtfieldsep", ""); + RtTimeOutTime = ini->ReadInteger("plot", "rttimeouttime", 0); + RtReConnTime = ini->ReadInteger("plot", "rtreconntime", 10000); + + MColor[0][0] = (TColor)ini->ReadInteger("plot", "mcolor0", (int)clSilver); + MColor[0][1] = (TColor)ini->ReadInteger("plot", "mcolor1", (int)clGreen); + MColor[0][2] = (TColor)ini->ReadInteger("plot", "mcolor2", 0x00AAFF); + MColor[0][3] = (TColor)ini->ReadInteger("plot", "mcolor3", (int)clFuchsia); + MColor[0][4] = (TColor)ini->ReadInteger("plot", "mcolor4", (int)clBlue); + MColor[0][5] = (TColor)ini->ReadInteger("plot", "mcolor5", (int)clRed); + MColor[0][6] = (TColor)ini->ReadInteger("plot", "mcolor6", (int)clTeal); + MColor[0][7] = (TColor)ini->ReadInteger("plot", "mcolor7", (int)clGray); + MColor[1][0] = (TColor)ini->ReadInteger("plot", "mcolor8", (int)clSilver); + MColor[1][1] = (TColor)ini->ReadInteger("plot", "mcolor9", 0x804000); + MColor[1][2] = (TColor)ini->ReadInteger("plot", "mcolor10", 0x008080); + MColor[1][3] = (TColor)ini->ReadInteger("plot", "mcolor11", 0xFF0080); + MColor[1][4] = (TColor)ini->ReadInteger("plot", "mcolor12", 0xFF8000); + MColor[1][5] = (TColor)ini->ReadInteger("plot", "mcolor13", 0x8080FF); + MColor[1][6] = (TColor)ini->ReadInteger("plot", "mcolor14", 0xFF8080); + MColor[1][7] = (TColor)ini->ReadInteger("plot", "mcolor15", (int)clGray); + MapColor[0] = (TColor)ini->ReadInteger("plot", "mapcolor1", clSilver); + MapColor[1] = (TColor)ini->ReadInteger("plot", "mapcolor2", clSilver); + MapColor[2] = (TColor)ini->ReadInteger("plot", "mapcolor3", 0xF0D0D0); + MapColor[3] = (TColor)ini->ReadInteger("plot", "mapcolor4", 0xD0F0D0); + MapColor[4] = (TColor)ini->ReadInteger("plot", "mapcolor5", 0xD0D0F0); + MapColor[5] = (TColor)ini->ReadInteger("plot", "mapcolor6", 0xD0F0F0); + MapColor[6] = (TColor)ini->ReadInteger("plot", "mapcolor7", 0xF8F8D0); + MapColor[7] = (TColor)ini->ReadInteger("plot", "mapcolor8", 0xF0F0F0); + MapColor[8] = (TColor)ini->ReadInteger("plot", "mapcolor9", 0xF0F0F0); + MapColor[9] = (TColor)ini->ReadInteger("plot", "mapcolor10", 0xF0F0F0); + MapColor[10] = (TColor)ini->ReadInteger("plot", "mapcolor11", 0xF0F0F0); + MapColor[11] = (TColor)ini->ReadInteger("plot", "mapcolor12", 0xF0F0F0); + MapColorF[0] = (TColor)ini->ReadInteger("plot", "mapcolorf1", clWhite); + MapColorF[1] = (TColor)ini->ReadInteger("plot", "mapcolorf2", clWhite); + MapColorF[2] = (TColor)ini->ReadInteger("plot", "mapcolorf3", clWhite); + MapColorF[3] = (TColor)ini->ReadInteger("plot", "mapcolorf4", clWhite); + MapColorF[4] = (TColor)ini->ReadInteger("plot", "mapcolorf5", clWhite); + MapColorF[5] = (TColor)ini->ReadInteger("plot", "mapcolorf6", clWhite); + MapColorF[6] = (TColor)ini->ReadInteger("plot", "mapcolorf7", clWhite); + MapColorF[7] = (TColor)ini->ReadInteger("plot", "mapcolorf8", clWhite); + MapColorF[8] = (TColor)ini->ReadInteger("plot", "mapcolorf9", clWhite); + MapColorF[9] = (TColor)ini->ReadInteger("plot", "mapcolorf10", clWhite); + MapColorF[10] = (TColor)ini->ReadInteger("plot", "mapcolorf11", clWhite); + MapColorF[11] = (TColor)ini->ReadInteger("plot", "mapcolorf12", clWhite); + CColor[0] = (TColor)ini->ReadInteger("plot", "color1", (int)clWhite); + CColor[1] = (TColor)ini->ReadInteger("plot", "color2", (int)clSilver); + CColor[2] = (TColor)ini->ReadInteger("plot", "color3", (int)clBlack); + CColor[3] = (TColor)ini->ReadInteger("plot", "color4", (int)clSilver); + + RefDialog->StaPosFile = ini->ReadString("plot", "staposfile", ""); + + ElMask = ini->ReadFloat("plot", "elmask", 0.0); + MaxDop = ini->ReadFloat("plot", "maxdop", 30.0); + MaxMP = ini->ReadFloat("plot", "maxmp", 10.0); + YRange = ini->ReadFloat("plot", "yrange", 5.0); + Origin = ini->ReadInteger("plot", "orgin", 4); + RcvPos = ini->ReadInteger("plot", "rcvpos", 0); + OOPos[0] = ini->ReadFloat("plot", "oopos1", 0); + OOPos[1] = ini->ReadFloat("plot", "oopos2", 0); + OOPos[2] = ini->ReadFloat("plot", "oopos3", 0); + ShapeFile = ini->ReadString("plot", "shapefile", ""); + TLEFile = ini->ReadString("plot", "tlefile", ""); + TLESatFile = ini->ReadString("plot", "tlesatfile", ""); + + FontName = ini->ReadString("plot", "fontname", "Tahoma"); + FontSize = ini->ReadInteger("plot", "fontsize", 8); + Font->Charset = ANSI_CHARSET; + Font->Name = FontName; + Font->Size = FontSize; + + RnxOpts = ini->ReadString("plot", "rnxopts", ""); + + MapApi = ini->ReadInteger("mapview", "mapapi", 0); + ApiKey = ini->ReadString("mapview", "apikey", ""); + MapStrs[0][0] = ini->ReadString("mapview", "mapstrs_0_0", "OpenStreetMap"); + MapStrs[0][1] = + ini->ReadString("mapview", "mapstrs_0_1", "https://tile.openstreetmap.org/{z}/{x}/{y}.png"); + MapStrs[0][2] = ini->ReadString("mapview", "mapstrs_0_2", "https://osm.org/copyright"); + for (int i = 1; i < 6; i++) + for (int j = 0; j < 3; j++) { + MapStrs[i][j] = ini->ReadString("mapview", s.sprintf("mapstrs_%d_%d", i, j), ""); + } + for (int i = 0; i < 2; i++) { + StrCmds[0][i] = ini->ReadString("str", s.sprintf("strcmd1_%d", i), ""); + StrCmds[1][i] = ini->ReadString("str", s.sprintf("strcmd2_%d", i), ""); + StrCmdEna[0][i] = ini->ReadInteger("str", s.sprintf("strcmdena1_%d", i), 0); + StrCmdEna[1][i] = ini->ReadInteger("str", s.sprintf("strcmdena2_%d", i), 0); + } + for (int i = 0; i < 3; i++) { + StrPaths[0][i] = ini->ReadString("str", s.sprintf("strpath1_%d", i), ""); + StrPaths[1][i] = ini->ReadString("str", s.sprintf("strpath2_%d", i), ""); + } + for (int i = 0; i < 10; i++) { + StrHistory[i] = ini->ReadString("str", s.sprintf("strhistry_%d", i), ""); + } + TTextViewer::Color1 = (TColor)ini->ReadInteger("viewer", "color1", (int)clBlack); + TTextViewer::Color2 = (TColor)ini->ReadInteger("viewer", "color2", (int)clWhite); + TTextViewer::FontD = new TFont; + TTextViewer::FontD->Name = ini->ReadString("viewer", "fontname", "Consolas"); + TTextViewer::FontD->Size = ini->ReadInteger("viewer", "fontsize", 9); + + MenuBrowse->Checked = ini->ReadInteger("solbrows", "show", 0); + PanelBrowse->Width = ini->ReadInteger("solbrows", "split1", 100); + DirSel->Height = ini->ReadInteger("solbrows", "split2", 150); + try { + DirSel->Directory = ini->ReadString("solbrows", "dir", "C:\\"); + } catch (Exception &exception) { + ; + } + delete ini; + + for (int i = 0; i < RangeList->Count; i++) { + AnsiString s = RangeList->Items->Strings[i]; + double range; + char unit[32] = ""; + + if (sscanf(s.c_str(), "%lf%31s", &range, unit) < 1) continue; + if (!strcmp(unit, "cm")) + range *= 0.01; + else if (!strcmp(unit, "km")) + range *= 1000.0; + if (range == YRange) { + RangeList->Selected[i] = true; + break; } - delete ini; - - for (int i=0;iCount;i++) { - AnsiString s=RangeList->Items->Strings[i]; - double range; - char unit[32]=""; - - if (sscanf(s.c_str(),"%lf%31s",&range,unit)<1) continue; - if (!strcmp(unit,"cm")) range*=0.01; - else if (!strcmp(unit,"km")) range*=1000.0; - if (range==YRange) { - RangeList->Selected[i]=true; - break; - } - } + } } // save options to ini-file ------------------------------------------------- -void __fastcall TPlot::SaveOpt(void) -{ - TIniFile *ini=new TIniFile(IniFile); - AnsiString s; - - trace(3,"SaveOpt\n"); - -// ini->WriteInteger("plot","plottype", PlotType ); - ini->WriteInteger("plot","timelabel", TimeLabel ); - ini->WriteInteger("plot","latlonfmt", LatLonFmt ); - ini->WriteInteger("plot","autoscale", AutoScale ); - ini->WriteInteger("plot","showstats", ShowStats ); - ini->WriteInteger("plot","showlabel", ShowLabel ); - ini->WriteInteger("plot","showglabel", ShowGLabel ); - ini->WriteInteger("plot","showcompass", ShowCompass ); - ini->WriteInteger("plot","showscale", ShowScale ); - ini->WriteInteger("plot","showarrow", ShowArrow ); - ini->WriteInteger("plot","showslip", ShowSlip ); - ini->WriteInteger("plot","showhalfc", ShowHalfC ); - ini->WriteInteger("plot","showerr", ShowErr ); - ini->WriteInteger("plot","showeph", ShowEph ); - ini->WriteInteger("plot","plotstyle", PlotStyle ); - ini->WriteInteger("plot","marksize", MarkSize ); - ini->WriteInteger("plot","navsys", NavSys ); - ini->WriteInteger("plot","animcycle", AnimCycle ); - ini->WriteInteger("plot","refcycle", RefCycle ); - ini->WriteInteger("plot","hidelowsat", HideLowSat ); - ini->WriteInteger("plot","elmaskp", ElMaskP ); - ini->WriteString ("plot","exsats", ExSats ); - ini->WriteInteger("plot","rtbuffsize", RtBuffSize ); - ini->WriteInteger("plot","timesyncout", TimeSyncOut ); - ini->WriteInteger("plot","timesyncport", TimeSyncPort ); - ini->WriteInteger("plot","rtstream1", RtStream[0] ); - ini->WriteInteger("plot","rtstream2", RtStream[1] ); - ini->WriteInteger("plot","rtformat1", RtFormat[0] ); - ini->WriteInteger("plot","rtformat2", RtFormat[1] ); - ini->WriteInteger("plot","rttimeform", RtTimeForm ); - ini->WriteInteger("plot","rtdegform", RtDegForm ); - ini->WriteString ("plot","rtfieldsep", RtFieldSep ); - ini->WriteInteger("plot","rttimeouttime",RtTimeOutTime); - ini->WriteInteger("plot","rtreconntime", RtReConnTime ); - - ini->WriteInteger("plot","mcolor0", (int)MColor[0][0]); - ini->WriteInteger("plot","mcolor1", (int)MColor[0][1]); - ini->WriteInteger("plot","mcolor2", (int)MColor[0][2]); - ini->WriteInteger("plot","mcolor3", (int)MColor[0][3]); - ini->WriteInteger("plot","mcolor4", (int)MColor[0][4]); - ini->WriteInteger("plot","mcolor5", (int)MColor[0][5]); - ini->WriteInteger("plot","mcolor6", (int)MColor[0][6]); - ini->WriteInteger("plot","mcolor7", (int)MColor[0][7]); - ini->WriteInteger("plot","mcolor8", (int)MColor[0][0]); - ini->WriteInteger("plot","mcolor9", (int)MColor[1][1]); - ini->WriteInteger("plot","mcolor10", (int)MColor[1][2]); - ini->WriteInteger("plot","mcolor11", (int)MColor[1][3]); - ini->WriteInteger("plot","mcolor12", (int)MColor[1][4]); - ini->WriteInteger("plot","mcolor13", (int)MColor[1][5]); - ini->WriteInteger("plot","mcolor14", (int)MColor[1][6]); - ini->WriteInteger("plot","mcolor15", (int)MColor[1][7]); - ini->WriteInteger("plot","mapcolor1", (int)MapColor [0]); - ini->WriteInteger("plot","mapcolor2", (int)MapColor [1]); - ini->WriteInteger("plot","mapcolor3", (int)MapColor [2]); - ini->WriteInteger("plot","mapcolor4", (int)MapColor [3]); - ini->WriteInteger("plot","mapcolor5", (int)MapColor [4]); - ini->WriteInteger("plot","mapcolor6", (int)MapColor [5]); - ini->WriteInteger("plot","mapcolor7", (int)MapColor [6]); - ini->WriteInteger("plot","mapcolor8", (int)MapColor [7]); - ini->WriteInteger("plot","mapcolor9", (int)MapColor [8]); - ini->WriteInteger("plot","mapcolor10", (int)MapColor [9]); - ini->WriteInteger("plot","mapcolor11", (int)MapColor[10]); - ini->WriteInteger("plot","mapcolor12", (int)MapColor[11]); - ini->WriteInteger("plot","mapcolor1f", (int)MapColorF[0]); - ini->WriteInteger("plot","mapcolor2f", (int)MapColorF[1]); - ini->WriteInteger("plot","mapcolor3f", (int)MapColorF[2]); - ini->WriteInteger("plot","mapcolor4f", (int)MapColorF[3]); - ini->WriteInteger("plot","mapcolor5f", (int)MapColorF[4]); - ini->WriteInteger("plot","mapcolor6f", (int)MapColorF[5]); - ini->WriteInteger("plot","mapcolor7f", (int)MapColorF[6]); - ini->WriteInteger("plot","mapcolor8f", (int)MapColorF[7]); - ini->WriteInteger("plot","mapcolor9f", (int)MapColorF[8]); - ini->WriteInteger("plot","mapcolor10f", (int)MapColorF[9]); - ini->WriteInteger("plot","mapcolor11f", (int)MapColorF[10]); - ini->WriteInteger("plot","mapcolor12f", (int)MapColorF[11]); - ini->WriteInteger("plot","color1", (int)CColor[0]); - ini->WriteInteger("plot","color2", (int)CColor[1]); - ini->WriteInteger("plot","color3", (int)CColor[2]); - ini->WriteInteger("plot","color4", (int)CColor[3]); - - ini->WriteString ("plot","staposfile", RefDialog->StaPosFile); - - ini->WriteFloat ("plot","elmask", ElMask ); - ini->WriteFloat ("plot","maxdop", MaxDop ); - ini->WriteFloat ("plot","maxmp", MaxMP ); - ini->WriteFloat ("plot","yrange", YRange ); - ini->WriteInteger("plot","orgin", Origin ); - ini->WriteInteger("plot","rcvpos", RcvPos ); - ini->WriteFloat ("plot","oopos1", OOPos[0] ); - ini->WriteFloat ("plot","oopos2", OOPos[1] ); - ini->WriteFloat ("plot","oopos3", OOPos[2] ); - ini->WriteString ("plot","shapefile", ShapeFile ); - ini->WriteString ("plot","tlefile", TLEFile ); - ini->WriteString ("plot","tlesatfile", TLESatFile ); - - ini->WriteString ("plot","fontname", FontName ); - ini->WriteInteger("plot","fontsize", FontSize ); - - ini->WriteString ("plot","rnxopts", RnxOpts ); - - ini->WriteString ("mapview","apikey", ApiKey ); - ini->WriteInteger("mapview","mapapi", MapApi ); - for (int i=0;i<6;i++) for (int j=0;j<3;j++) { - ini->WriteString("mapview",s.sprintf("mapstrs_%d_%d",i,j),MapStrs[i][j]); - } - for (int i=0;i<2;i++) { - ini->WriteString ("str",s.sprintf("strcmd1_%d", i),StrCmds [0][i]); - ini->WriteString ("str",s.sprintf("strcmd2_%d", i),StrCmds [1][i]); - ini->WriteInteger("str",s.sprintf("strcmdena1_%d", i),StrCmdEna[0][i]); - ini->WriteInteger("str",s.sprintf("strcmdena2_%d", i),StrCmdEna[1][i]); - } - for (int i=0;i<3;i++) { - ini->WriteString ("str",s.sprintf("strpath1_%d", i),StrPaths[0][i]); - ini->WriteString ("str",s.sprintf("strpath2_%d", i),StrPaths[1][i]); - } - for (int i=0;i<12;i++) { - ini->WriteString ("str",s.sprintf("strhistry_%d", i),StrHistory [i]); - } - ini->WriteInteger("viewer","color1",(int)TTextViewer::Color1 ); - ini->WriteInteger("viewer","color2",(int)TTextViewer::Color2 ); - ini->WriteString ("viewer","fontname",TTextViewer::FontD->Name); - ini->WriteInteger("viewer","fontsize",TTextViewer::FontD->Size); - - ini->WriteInteger("solbrows","show", MenuBrowse->Checked); - ini->WriteInteger("solbrows","split1",PanelBrowse->Width); - ini->WriteInteger("solbrows","split2", DirSel->Height); - ini->WriteString ("solbrows","dir", DirSel->Directory); - - delete ini; +void __fastcall TPlot::SaveOpt(void) { + TIniFile *ini = new TIniFile(IniFile); + AnsiString s; + + trace(3, "SaveOpt\n"); + + // ini->WriteInteger("plot","plottype", PlotType ); + ini->WriteInteger("plot", "timelabel", TimeLabel); + ini->WriteInteger("plot", "latlonfmt", LatLonFmt); + ini->WriteInteger("plot", "autoscale", AutoScale); + ini->WriteInteger("plot", "showstats", ShowStats); + ini->WriteInteger("plot", "showlabel", ShowLabel); + ini->WriteInteger("plot", "showglabel", ShowGLabel); + ini->WriteInteger("plot", "showcompass", ShowCompass); + ini->WriteInteger("plot", "showscale", ShowScale); + ini->WriteInteger("plot", "showarrow", ShowArrow); + ini->WriteInteger("plot", "showslip", ShowSlip); + ini->WriteInteger("plot", "showhalfc", ShowHalfC); + ini->WriteInteger("plot", "showerr", ShowErr); + ini->WriteInteger("plot", "showeph", ShowEph); + ini->WriteInteger("plot", "plotstyle", PlotStyle); + ini->WriteInteger("plot", "marksize", MarkSize); + ini->WriteInteger("plot", "navsys", NavSys); + ini->WriteInteger("plot", "animcycle", AnimCycle); + ini->WriteInteger("plot", "refcycle", RefCycle); + ini->WriteInteger("plot", "hidelowsat", HideLowSat); + ini->WriteInteger("plot", "elmaskp", ElMaskP); + ini->WriteString("plot", "exsats", ExSats); + ini->WriteInteger("plot", "rtbuffsize", RtBuffSize); + ini->WriteInteger("plot", "timesyncout", TimeSyncOut); + ini->WriteInteger("plot", "timesyncport", TimeSyncPort); + ini->WriteInteger("plot", "rtstream1", RtStream[0]); + ini->WriteInteger("plot", "rtstream2", RtStream[1]); + ini->WriteInteger("plot", "rtformat1", RtFormat[0]); + ini->WriteInteger("plot", "rtformat2", RtFormat[1]); + ini->WriteInteger("plot", "rttimeform", RtTimeForm); + ini->WriteInteger("plot", "rtdegform", RtDegForm); + ini->WriteString("plot", "rtfieldsep", RtFieldSep); + ini->WriteInteger("plot", "rttimeouttime", RtTimeOutTime); + ini->WriteInteger("plot", "rtreconntime", RtReConnTime); + + ini->WriteInteger("plot", "mcolor0", (int)MColor[0][0]); + ini->WriteInteger("plot", "mcolor1", (int)MColor[0][1]); + ini->WriteInteger("plot", "mcolor2", (int)MColor[0][2]); + ini->WriteInteger("plot", "mcolor3", (int)MColor[0][3]); + ini->WriteInteger("plot", "mcolor4", (int)MColor[0][4]); + ini->WriteInteger("plot", "mcolor5", (int)MColor[0][5]); + ini->WriteInteger("plot", "mcolor6", (int)MColor[0][6]); + ini->WriteInteger("plot", "mcolor7", (int)MColor[0][7]); + ini->WriteInteger("plot", "mcolor8", (int)MColor[0][0]); + ini->WriteInteger("plot", "mcolor9", (int)MColor[1][1]); + ini->WriteInteger("plot", "mcolor10", (int)MColor[1][2]); + ini->WriteInteger("plot", "mcolor11", (int)MColor[1][3]); + ini->WriteInteger("plot", "mcolor12", (int)MColor[1][4]); + ini->WriteInteger("plot", "mcolor13", (int)MColor[1][5]); + ini->WriteInteger("plot", "mcolor14", (int)MColor[1][6]); + ini->WriteInteger("plot", "mcolor15", (int)MColor[1][7]); + ini->WriteInteger("plot", "mapcolor1", (int)MapColor[0]); + ini->WriteInteger("plot", "mapcolor2", (int)MapColor[1]); + ini->WriteInteger("plot", "mapcolor3", (int)MapColor[2]); + ini->WriteInteger("plot", "mapcolor4", (int)MapColor[3]); + ini->WriteInteger("plot", "mapcolor5", (int)MapColor[4]); + ini->WriteInteger("plot", "mapcolor6", (int)MapColor[5]); + ini->WriteInteger("plot", "mapcolor7", (int)MapColor[6]); + ini->WriteInteger("plot", "mapcolor8", (int)MapColor[7]); + ini->WriteInteger("plot", "mapcolor9", (int)MapColor[8]); + ini->WriteInteger("plot", "mapcolor10", (int)MapColor[9]); + ini->WriteInteger("plot", "mapcolor11", (int)MapColor[10]); + ini->WriteInteger("plot", "mapcolor12", (int)MapColor[11]); + ini->WriteInteger("plot", "mapcolor1f", (int)MapColorF[0]); + ini->WriteInteger("plot", "mapcolor2f", (int)MapColorF[1]); + ini->WriteInteger("plot", "mapcolor3f", (int)MapColorF[2]); + ini->WriteInteger("plot", "mapcolor4f", (int)MapColorF[3]); + ini->WriteInteger("plot", "mapcolor5f", (int)MapColorF[4]); + ini->WriteInteger("plot", "mapcolor6f", (int)MapColorF[5]); + ini->WriteInteger("plot", "mapcolor7f", (int)MapColorF[6]); + ini->WriteInteger("plot", "mapcolor8f", (int)MapColorF[7]); + ini->WriteInteger("plot", "mapcolor9f", (int)MapColorF[8]); + ini->WriteInteger("plot", "mapcolor10f", (int)MapColorF[9]); + ini->WriteInteger("plot", "mapcolor11f", (int)MapColorF[10]); + ini->WriteInteger("plot", "mapcolor12f", (int)MapColorF[11]); + ini->WriteInteger("plot", "color1", (int)CColor[0]); + ini->WriteInteger("plot", "color2", (int)CColor[1]); + ini->WriteInteger("plot", "color3", (int)CColor[2]); + ini->WriteInteger("plot", "color4", (int)CColor[3]); + + ini->WriteString("plot", "staposfile", RefDialog->StaPosFile); + + ini->WriteFloat("plot", "elmask", ElMask); + ini->WriteFloat("plot", "maxdop", MaxDop); + ini->WriteFloat("plot", "maxmp", MaxMP); + ini->WriteFloat("plot", "yrange", YRange); + ini->WriteInteger("plot", "orgin", Origin); + ini->WriteInteger("plot", "rcvpos", RcvPos); + ini->WriteFloat("plot", "oopos1", OOPos[0]); + ini->WriteFloat("plot", "oopos2", OOPos[1]); + ini->WriteFloat("plot", "oopos3", OOPos[2]); + ini->WriteString("plot", "shapefile", ShapeFile); + ini->WriteString("plot", "tlefile", TLEFile); + ini->WriteString("plot", "tlesatfile", TLESatFile); + + ini->WriteString("plot", "fontname", FontName); + ini->WriteInteger("plot", "fontsize", FontSize); + + ini->WriteString("plot", "rnxopts", RnxOpts); + + ini->WriteString("mapview", "apikey", ApiKey); + ini->WriteInteger("mapview", "mapapi", MapApi); + for (int i = 0; i < 6; i++) + for (int j = 0; j < 3; j++) { + ini->WriteString("mapview", s.sprintf("mapstrs_%d_%d", i, j), MapStrs[i][j]); + } + for (int i = 0; i < 2; i++) { + ini->WriteString("str", s.sprintf("strcmd1_%d", i), StrCmds[0][i]); + ini->WriteString("str", s.sprintf("strcmd2_%d", i), StrCmds[1][i]); + ini->WriteInteger("str", s.sprintf("strcmdena1_%d", i), StrCmdEna[0][i]); + ini->WriteInteger("str", s.sprintf("strcmdena2_%d", i), StrCmdEna[1][i]); + } + for (int i = 0; i < 3; i++) { + ini->WriteString("str", s.sprintf("strpath1_%d", i), StrPaths[0][i]); + ini->WriteString("str", s.sprintf("strpath2_%d", i), StrPaths[1][i]); + } + for (int i = 0; i < 12; i++) { + ini->WriteString("str", s.sprintf("strhistry_%d", i), StrHistory[i]); + } + ini->WriteInteger("viewer", "color1", (int)TTextViewer::Color1); + ini->WriteInteger("viewer", "color2", (int)TTextViewer::Color2); + ini->WriteString("viewer", "fontname", TTextViewer::FontD->Name); + ini->WriteInteger("viewer", "fontsize", TTextViewer::FontD->Size); + + ini->WriteInteger("solbrows", "show", MenuBrowse->Checked); + ini->WriteInteger("solbrows", "split1", PanelBrowse->Width); + ini->WriteInteger("solbrows", "split2", DirSel->Height); + ini->WriteString("solbrows", "dir", DirSel->Directory); + + delete ini; } //--------------------------------------------------------------------------- -void __fastcall TPlot::FileMaskChange(TObject *Sender) -{ - switch (FileMask->ItemIndex) { - case 0 : FileList->Mask="*.pos" ; break; - case 1 : FileList->Mask="*.nmea"; break; - case 2 : FileList->Mask="*.stat"; break; - default: FileList->Mask="*.*" ; break; - } +void __fastcall TPlot::FileMaskChange(TObject *Sender) { + switch (FileMask->ItemIndex) { + case 0: + FileList->Mask = "*.pos"; + break; + case 1: + FileList->Mask = "*.nmea"; + break; + case 2: + FileList->Mask = "*.stat"; + break; + default: + FileList->Mask = "*.*"; + break; + } } //--------------------------------------------------------------------------- -void __fastcall TPlot::FileListClick(TObject *Sender) -{ - TStringList *file=new TStringList; - file->Add(FileList->FileName); - Plot->ReadSol(file,0); - delete file; +void __fastcall TPlot::FileListClick(TObject *Sender) { + TStringList *file = new TStringList; + file->Add(FileList->FileName); + Plot->ReadSol(file, 0); + delete file; } //--------------------------------------------------------------------------- -void __fastcall TPlot::Splitter1Moved(TObject *Sender) -{ - UpdateSize(); - Refresh(); +void __fastcall TPlot::Splitter1Moved(TObject *Sender) { + UpdateSize(); + Refresh(); } //--------------------------------------------------------------------------- -void __fastcall TPlot::BtnUdListClick(TObject *Sender) -{ - FileList->Update(); -} +void __fastcall TPlot::BtnUdListClick(TObject *Sender) { FileList->Update(); } //--------------------------------------------------------------------------- -void __fastcall TPlot::BtnFreqClick(TObject *Sender) -{ - if (FreqDialog->ShowModal()==mrOk) return; +void __fastcall TPlot::BtnFreqClick(TObject *Sender) { + if (FreqDialog->ShowModal() == mrOk) return; } //--------------------------------------------------------------------------- - diff --git a/app/winapp/rtkplot/plotmain.h b/app/winapp/rtkplot/plotmain.h index c63f4f2a1..aa19798a2 100644 --- a/app/winapp/rtkplot/plotmain.h +++ b/app/winapp/rtkplot/plotmain.h @@ -2,678 +2,670 @@ #ifndef plotmainH #define plotmainH //--------------------------------------------------------------------------- +#include #include +#include #include -#include -#include -#include #include -#include -#include +#include +#include +#include #include +#include +#include +#include #include -#include "graph.h" + +#include "SHDocVw_OCX.h" #include "console.h" +#include "graph.h" #include "rtklib.h" -#include -#include "SHDocVw_OCX.h" -#include -#include -#define MAXNFILE 256 // max number of solution files -#define MAXSTRBUFF 1024 // max length of stream buffer -#define MAXWAYPNT 99 // max number of waypoints -#define MAXMAPPATH 4096 // max number of map paths -#define MAXMAPLAYER 12 // max number of map layers - -#define PRGNAME "RTKPLOT" // program name - -#define CHARDEG "\302\260" // character code of degree (UTF-8) -#define CHARUP2 "\302\262" // character code of ^2 (UTF-8) - -#define DEFTSPAN 600.0 // default time span (s) -#define INTARROW 60.0 // direction arrow interval (s) -#define MAXTDIFF 60.0 // max differential time (s) -#define DOPLIM 30.0 // dop view limit -#define TTOL DTTOL // time-differnce tolerance (s) -#define TBRK 300.0 // time to recognize break (s) -#define THRESLIP 0.1 // slip threshold of LG-jump (m) -#define SIZE_COMP 45 // compass size (pixels) -#define SIZE_VELC 45 // velocity circle size (pixels) -#define CLORANGE (TColor)0x00AAFF -#define MIN_RANGE_GE 10.0 // min range for GE view - -#define PLOT_TRK 0 // plot-type: track-plot -#define PLOT_SOLP 1 // plot-type: position-plot -#define PLOT_SOLV 2 // plot-type: velocity-plot -#define PLOT_SOLA 3 // plot-type: accel-plot -#define PLOT_NSAT 4 // plot-type: number-of-satellite-plot -#define PLOT_SSKY 5 // plot-type: sky-plot -#define PLOT_SDOP 6 // plot-type: dop-plot -#define PLOT_RES 7 // plot-type: residual-plot -#define PLOT_RESE 8 // plot-type: residual-elevation plot -#define PLOT_OBS 9 // plot-type: observation-data-plot -#define PLOT_SKY 10 // plot-type: sky-plot -#define PLOT_DOP 11 // plot-type: dop-plot -#define PLOT_SNR 12 // plot-type: snr/mp-plot -#define PLOT_SNRE 13 // plot-type: snr/mp-el-plot -#define PLOT_MPS 14 // plot-type: mp-skyplot - -#define ORG_STARTPOS 0 // plot-origin: start position -#define ORG_ENDPOS 1 // plot-origin: end position -#define ORG_AVEPOS 2 // plot-origin: average position -#define ORG_FITPOS 3 // plot-origin: linear-fit position -#define ORG_REFPOS 4 // plot-origin: reference position -#define ORG_LLHPOS 5 // plot-origin: lat/lon/hgt position -#define ORG_AUTOPOS 6 // plot-origin: auto-input position -#define ORG_IMGPOS 7 // plot-origin: image-center position -#define ORG_MAPPOS 8 // plot-origin: map center position -#define ORG_PNTPOS 9 // plot-origin: way-point position - -#define TRACEFILE "rtkplot.trace" // trace file -#define QCTMPFILE "rtkplot_qc.temp" // tempolary file for qc -#define QCERRFILE "rtkplot_qc.err" // error file for qc - -#define SQR(x) ((x)*(x)) -#define SQRT(x) ((x)<0.0||(x)!=(x)?0.0:sqrt(x)) -#define MAX(x,y) ((x)>(y)?(x):(y)) -#define MIN(x,y) ((x)<(y)?(x):(y)) +#define MAXNFILE 256 // max number of solution files +#define MAXSTRBUFF 1024 // max length of stream buffer +#define MAXWAYPNT 99 // max number of waypoints +#define MAXMAPPATH 4096 // max number of map paths +#define MAXMAPLAYER 12 // max number of map layers + +#define PRGNAME "RTKPLOT" // program name + +#define CHARDEG "\302\260" // character code of degree (UTF-8) +#define CHARUP2 "\302\262" // character code of ^2 (UTF-8) + +#define DEFTSPAN 600.0 // default time span (s) +#define INTARROW 60.0 // direction arrow interval (s) +#define MAXTDIFF 60.0 // max differential time (s) +#define DOPLIM 30.0 // dop view limit +#define TTOL DTTOL // time-differnce tolerance (s) +#define TBRK 300.0 // time to recognize break (s) +#define THRESLIP 0.1 // slip threshold of LG-jump (m) +#define SIZE_COMP 45 // compass size (pixels) +#define SIZE_VELC 45 // velocity circle size (pixels) +#define CLORANGE (TColor)0x00AAFF +#define MIN_RANGE_GE 10.0 // min range for GE view + +#define PLOT_TRK 0 // plot-type: track-plot +#define PLOT_SOLP 1 // plot-type: position-plot +#define PLOT_SOLV 2 // plot-type: velocity-plot +#define PLOT_SOLA 3 // plot-type: accel-plot +#define PLOT_NSAT 4 // plot-type: number-of-satellite-plot +#define PLOT_SSKY 5 // plot-type: sky-plot +#define PLOT_SDOP 6 // plot-type: dop-plot +#define PLOT_RES 7 // plot-type: residual-plot +#define PLOT_RESE 8 // plot-type: residual-elevation plot +#define PLOT_OBS 9 // plot-type: observation-data-plot +#define PLOT_SKY 10 // plot-type: sky-plot +#define PLOT_DOP 11 // plot-type: dop-plot +#define PLOT_SNR 12 // plot-type: snr/mp-plot +#define PLOT_SNRE 13 // plot-type: snr/mp-el-plot +#define PLOT_MPS 14 // plot-type: mp-skyplot + +#define ORG_STARTPOS 0 // plot-origin: start position +#define ORG_ENDPOS 1 // plot-origin: end position +#define ORG_AVEPOS 2 // plot-origin: average position +#define ORG_FITPOS 3 // plot-origin: linear-fit position +#define ORG_REFPOS 4 // plot-origin: reference position +#define ORG_LLHPOS 5 // plot-origin: lat/lon/hgt position +#define ORG_AUTOPOS 6 // plot-origin: auto-input position +#define ORG_IMGPOS 7 // plot-origin: image-center position +#define ORG_MAPPOS 8 // plot-origin: map center position +#define ORG_PNTPOS 9 // plot-origin: way-point position + +#define TRACEFILE "rtkplot.trace" // trace file +#define QCTMPFILE "rtkplot_qc.temp" // tempolary file for qc +#define QCERRFILE "rtkplot_qc.err" // error file for qc + +#define SQR(x) ((x) * (x)) +#define SQRT(x) ((x) < 0.0 || (x) != (x) ? 0.0 : sqrt(x)) +#define MAX(x, y) ((x) > (y) ? (x) : (y)) +#define MIN(x, y) ((x) < (y) ? (x) : (y)) extern const char *PTypes[]; // time-position class ------------------------------------------------------ -class TIMEPOS -{ -private: - int nmax_; -public: - int n; - gtime_t *t; - double *x,*y,*z,*xs,*ys,*zs,*xys; - int *q; - TIMEPOS(int nmax, int sflg); - ~TIMEPOS(); - TIMEPOS *tdiff(void); - TIMEPOS *diff(const TIMEPOS *pos2, int qflag); +class TIMEPOS { + private: + int nmax_; + + public: + int n; + gtime_t *t; + double *x, *y, *z, *xs, *ys, *zs, *xys; + int *q; + TIMEPOS(int nmax, int sflg); + ~TIMEPOS(); + TIMEPOS *tdiff(void); + TIMEPOS *diff(const TIMEPOS *pos2, int qflag); }; // rtkplot class ------------------------------------------------------------ -class TPlot : public TForm -{ -__published: - TPanel *Panel1; - TPanel *Panel10; - TPanel *Panel11; - TPanel *Panel12; - TPanel *Panel2; - TPanel *Panel21; - TPanel *Panel22; - TPanel *StrStatus1; - TPanel *StrStatus2; - TPaintBox *Disp; - - TComboBox *PlotTypeS; - TComboBox *QFlag; - TComboBox *ObsType; - TComboBox *DopType; - TComboBox *SatList; - TListBox *RangeList; - TSpeedButton *BtnConnect; - TSpeedButton *BtnSol1; - TSpeedButton *BtnSol2; - TSpeedButton *BtnSol12; - TSpeedButton *BtnOn1; - TSpeedButton *BtnOn2; - TSpeedButton *BtnOn3; - TSpeedButton *BtnRangeList; - TSpeedButton *BtnFitHoriz; - TSpeedButton *BtnFitVert; - TSpeedButton *BtnCenterOri; - TSpeedButton *BtnFixHoriz; - TSpeedButton *BtnFixVert; - TSpeedButton *BtnShowTrack; - TSpeedButton *BtnShowSkyplot; - TSpeedButton *BtnShowImg; - TSpeedButton *BtnShowMap; - TSpeedButton *BtnAnimate; - TSpeedButton *BtnClear; - TSpeedButton *BtnReload; - TScrollBar *TimeScroll; - - TLabel *ConnectMsg; - TLabel *Message1; - TLabel *Message2; - TLabel *QL1; - TLabel *QL2; - TLabel *QL3; - TLabel *QL4; - TLabel *QL5; - TLabel *QL6; - TLabel *QL7; - TMainMenu *hh; - - TMenuItem *MenuFile; - TMenuItem *MenuOpenSol1; - TMenuItem *MenuOpenSol2; - TMenuItem *MenuOpenMapImage; - TMenuItem *MenuOpenShape; - TMenuItem *MenuOpenObs; - TMenuItem *MenuOpenNav; - TMenuItem *MenuOpenElevMask; - TMenuItem *MenuConnect; - TMenuItem *MenuDisconnect; - TMenuItem *MenuPort; - TMenuItem *MenuReload; - TMenuItem *MenuClear; - TMenuItem *MenuQuit; - - TMenuItem *MenuEdit; - TMenuItem *MenuTime; - TMenuItem *MenuMapImg; - TMenuItem *MenuWaypnt; - TMenuItem *MenuSrcSol; - TMenuItem *MenuSrcObs; - TMenuItem *MenyCopy; - TMenuItem *MenuOptions; - - TMenuItem *MenuView; - TMenuItem *MenuToolBar; - TMenuItem *MenuStatusBar; - TMenuItem *MenuMonitor1; - TMenuItem *MenuMonitor2; - TMenuItem *MenuCenterOri; - TMenuItem *MenuFitHoriz; - TMenuItem *MenuFitVert; - TMenuItem *MenuShowTrack; - TMenuItem *MenuFixHoriz; - TMenuItem *MenuFixVert; - TMenuItem *MenuShowImg; - TMenuItem *MenuShowMap; - TMenuItem *MenuAnimStart; - TMenuItem *MenuAnimStop; - - TMenuItem *MenuHelp; - TMenuItem *MenuAbout; - - TMenuItem *N1; - TMenuItem *N2; - TMenuItem *N3; - TMenuItem *N5; - TMenuItem *N6; - TMenuItem *N7; - TMenuItem *N8; - TMenuItem *N9; - TMenuItem *N10; - TMenuItem *N11; - TMenuItem *N12; - TMenuItem *N13; - - TTimer *Timer; - - TOpenDialog *OpenSolDialog; - TOpenDialog *OpenObsDialog; - TOpenDialog *OpenElMaskDialog; - TOpenDialog *OpenMapPathDialog; - TOpenDialog *OpenMapDialog; - TMenuItem *N14; - TMenuItem *MenuSaveDop; - TSaveDialog *SaveDialog; - TMenuItem *MenuSaveImage; - TSavePictureDialog *SaveImageDialog; - TMenuItem *N15; - TComboBox *FrqType; - TComboBox *ObsType2; - TMenuItem *MenuVisAna; - TMenuItem *N16; - TSpeedButton *BtnOptions; - TSpeedButton *BtnFixCent; - TMenuItem *MenuFixCent; - TSpeedButton *BtnMapView; - TMenuItem *MenuSaveSnrMp; - TMenuItem *MenuMapView; - TMenuItem *MenuOpenSkyImage; - TMenuItem *MenuSkyImg; - TMenuItem *MenuShowSkyplot; - TMenuItem *Windows1; - TMenuItem *MenuMax; - TMenuItem *MenuPlotMapView; - TMenuItem *N17; - TPanel *Panel101; - TPanel *Panel102; - TPanel *Panel103; - TPanel *Panel104; - TMenuItem *MenuSaveElMask; - TMenuItem *MenuMapLayer; - TSpeedButton *BtnMessage2; - TMenuItem *MenuOpenWaypoint; - TMenuItem *MenuSaveWaypoint; - TOpenDialog *OpenWaypointDialog; - TSaveDialog *SaveWaypointDialog; - TPanel *Panel3; - TPanel *PanelBrowse; - TSplitter *Splitter1; - TDriveComboBox *DriveSel; - TDirectoryListBox *DirSel; - TSplitter *Splitter2; - TFileListBox *FileList; - TComboBox *FileMask; - TMenuItem *MenuBrowse; - TPanel *StrStatus; - TSpeedButton *BtnShowGrid; - TMenuItem *MenuShowGrid; - TPanel *Panel4; - TSpeedButton *BtnUdList; - TSpeedButton *BtnFreq; - - void __fastcall FormCreate (TObject *Sender); - void __fastcall FormShow (TObject *Sender); - void __fastcall FormResize (TObject *Sender); - void __fastcall FormActivate (TObject *Sender); - void __fastcall FormKeyDown (TObject *Sender, WORD &Key, TShiftState Shift); - - void __fastcall MenuOpenSol1Click (TObject *Sender); - void __fastcall MenuOpenSol2Click (TObject *Sender); - void __fastcall MenuOpenMapImageClick(TObject *Sender); - void __fastcall MenuOpenShapeClick (TObject *Sender); - void __fastcall MenuOpenObsClick (TObject *Sender); - void __fastcall MenuOpenNavClick (TObject *Sender); - void __fastcall MenuOpenElevMaskClick(TObject *Sender); - void __fastcall MenuConnectClick (TObject *Sender); - void __fastcall MenuDisconnectClick (TObject *Sender); - void __fastcall MenuPortClick (TObject *Sender); - void __fastcall MenuReloadClick (TObject *Sender); - void __fastcall MenuClearClick (TObject *Sender); - void __fastcall MenuQuitClick (TObject *Sender); - - void __fastcall MenuTimeClick (TObject *Sender); - void __fastcall MenuMapImgClick (TObject *Sender); - void __fastcall MenuWaypointClick (TObject *Sender); - void __fastcall MenuSrcSolClick (TObject *Sender); - void __fastcall MenuSrcObsClick (TObject *Sender); - void __fastcall MenyCopyClick (TObject *Sender); - void __fastcall MenuOptionsClick (TObject *Sender); - - void __fastcall MenuToolBarClick (TObject *Sender); - void __fastcall MenuStatusBarClick (TObject *Sender); - void __fastcall MenuMonitor1Click (TObject *Sender); - void __fastcall MenuMonitor2Click (TObject *Sender); - void __fastcall MenuCenterOriClick (TObject *Sender); - void __fastcall MenuFitHorizClick (TObject *Sender); - void __fastcall MenuFitVertClick (TObject *Sender); - void __fastcall MenuShowTrackClick (TObject *Sender); - void __fastcall MenuFixHorizClick (TObject *Sender); - void __fastcall MenuFixVertClick (TObject *Sender); - void __fastcall MenuShowImgClick (TObject *Sender); - void __fastcall MenuShowMapClick (TObject *Sender); - void __fastcall MenuAnimStartClick (TObject *Sender); - void __fastcall MenuAnimStopClick (TObject *Sender); - void __fastcall MenuAboutClick (TObject *Sender); - - void __fastcall BtnConnectClick (TObject *Sender); - void __fastcall BtnSol1Click (TObject *Sender); - void __fastcall BtnSol2Click (TObject *Sender); - void __fastcall BtnSol12Click (TObject *Sender); - void __fastcall BtnSol1DblClick (TObject *Sender); - void __fastcall BtnSol2DblClick (TObject *Sender); - void __fastcall BtnShowImgClick (TObject *Sender); - void __fastcall BtnOn1Click (TObject *Sender); - void __fastcall BtnOn2Click (TObject *Sender); - void __fastcall BtnOn3Click (TObject *Sender); - void __fastcall BtnRangeListClick (TObject *Sender); - void __fastcall RangeListClick (TObject *Sender); - void __fastcall BtnCenterOriClick (TObject *Sender); - void __fastcall BtnFitHorizClick (TObject *Sender); - void __fastcall BtnFitVertClick (TObject *Sender); - void __fastcall BtnShowTrackClick (TObject *Sender); - void __fastcall BtnFixHorizClick (TObject *Sender); - void __fastcall BtnFixVertClick (TObject *Sender); - void __fastcall BtnShowMapClick (TObject *Sender); - void __fastcall BtnAnimateClick (TObject *Sender); - void __fastcall BtnClearClick (TObject *Sender); - void __fastcall BtnReloadClick (TObject *Sender); - - void __fastcall PlotTypeSChange (TObject *Sender); - void __fastcall QFlagChange (TObject *Sender); - void __fastcall ObsTypeChange (TObject *Sender); - void __fastcall DopTypeChange (TObject *Sender); - void __fastcall SatListChange (TObject *Sender); - void __fastcall TimeScrollChange (TObject *Sender); - - void __fastcall TimerTimer (TObject *Sender); - - void __fastcall DispPaint (TObject *Sender); - void __fastcall DispMouseLeave (TObject *Sender); - void __fastcall DispMouseMove (TObject *Sender, TShiftState Shift, - int X, int Y); - void __fastcall DispMouseDown (TObject *Sender, TMouseButton Button, - TShiftState Shift, int X, int Y); - void __fastcall DispMouseUp (TObject *Sender, TMouseButton Button, - TShiftState Shift, int X, int Y); - void __fastcall MouseWheel (TObject *Sender, TShiftState Shift, - int WheelDelta, TPoint &MousePos, bool &Handled); - void __fastcall FormClose(TObject *Sender, TCloseAction &Action); - void __fastcall MenuSaveDopClick(TObject *Sender); - void __fastcall MenuSaveImageClick(TObject *Sender); - void __fastcall MenuVisAnaClick(TObject *Sender); - void __fastcall BtnOptionsClick(TObject *Sender); - void __fastcall BtnFixCentClick(TObject *Sender); - void __fastcall MenuFixCentClick(TObject *Sender); - void __fastcall BtnMapViewClick(TObject *Sender); - void __fastcall MenuMapViewClick(TObject *Sender); - void __fastcall MenuSaveSnrMpClick(TObject *Sender); - void __fastcall MenuOpenSkyImageClick(TObject *Sender); - void __fastcall MenuSkyImgClick(TObject *Sender); - void __fastcall MenuShowSkyplotClick(TObject *Sender); - void __fastcall BtnShowSkyplotClick(TObject *Sender); - void __fastcall MenuPlotMapViewClick(TObject *Sender); - void __fastcall MenuMaxClick(TObject *Sender); - void __fastcall DispGesture(TObject *Sender, const TGestureEventInfo &EventInfo, - bool &Handled); - void __fastcall MenuSaveElMaskClick(TObject *Sender); - void __fastcall MenuMapLayerClick(TObject *Sender); - void __fastcall BtnMessage2Click(TObject *Sender); - void __fastcall MenuOpenWaypointClick(TObject *Sender); - void __fastcall MenuSaveWaypointClick(TObject *Sender); - void __fastcall DispDblClick(TObject *Sender); - void __fastcall FileMaskChange(TObject *Sender); - void __fastcall FileListClick(TObject *Sender); - void __fastcall Splitter1Moved(TObject *Sender); - void __fastcall MenuBrowseClick(TObject *Sender); - void __fastcall MenuShowGridClick(TObject *Sender); - void __fastcall BtnShowGridClick(TObject *Sender); - void __fastcall BtnUdListClick(TObject *Sender); - void __fastcall BtnFreqClick(TObject *Sender); - - - -protected: - void __fastcall CMDialogKey(Messages::TWMKey &Message); - -private: - Graphics::TBitmap *Buff; - Graphics::TBitmap *MapImage; - Graphics::TBitmap *SkyImageI; - TGraph *GraphT; - TGraph *GraphG[3]; - TGraph *GraphR; - TGraph *GraphS; - TGraph *GraphE[2]; - TStrings *OpenFiles; - TStrings *SolFiles[2]; - TStrings *ObsFiles; - TStrings *NavFiles; - TConsole *Console1,*Console2; - - stream_t Stream[2]; - stream_t StrTimeSync; - solbuf_t SolData[2]; - solstatbuf_t SolStat[2]; - int SolIndex[2]; - obs_t Obs; - nav_t Nav; - sta_t Sta; - double *Az,*El,*Mp[NFREQ+NEXOBS]; - char StrBuff[1024]; - int NStrBuff; - - gtime_t OEpoch; - int FormWidth,FormHeight; - int ConnectState,OpenRaw; - int NObs,*IndexObs,ObsIndex; - int Week; - int Flush,PlotType; - int NSolF1,NSolF2,NObsF,NNavF; - int SatMask[MAXSAT],SatSel[MAXSAT]; - int SimObs; - - int Drag,Xn,Yn; - double X0,Y0,Xc,Yc,Xs,Ys,Xcent,Xcent0; - uint32_t MouseDownTick; - - int GEState,GEDataState[2]; - double GEHeading; - - void __fastcall DropFiles (TWMDropFiles msg); - - void __fastcall ReadSolStat (TStrings *files, int sel); - int __fastcall ReadObsRnx (TStrings *files, obs_t *obs, nav_t *nav, sta_t *sta); - void __fastcall ReadMapTag (AnsiString file); - void __fastcall ReadShapeFile(TStrings *files); - void __fastcall GenVisData (void); - void __fastcall SaveDop (AnsiString file); - void __fastcall SaveSnrMp (AnsiString file); - void __fastcall SaveElMask (AnsiString file); - void __fastcall Connect (void); - void __fastcall Disconnect (void); - void __fastcall ConnectPath (const char *path, int ch); - int __fastcall CheckObs (AnsiString file); - void __fastcall UpdateObs (int nobs); - void __fastcall UpdateMp (void); - void __fastcall ClearObs (void); - void __fastcall ClearSol (void); - void __fastcall Clear (void); - void __fastcall Refresh (void); - void __fastcall Reload (void); - void __fastcall ReadWaitStart(void); - void __fastcall ReadWaitEnd (void); - - void __fastcall UpdateDisp (void); - void __fastcall UpdateType (int type); - void __fastcall UpdatePlotType(void); - void __fastcall UpdateSatList(void); - void __fastcall UpdateObsType(void); - void __fastcall UpdateSize (void); - void __fastcall UpdateColor (void); - void __fastcall UpdateTime (void); - void __fastcall UpdateOrigin (void); - void __fastcall UpdateSatMask(void); - void __fastcall UpdateSatSel (void); - void __fastcall UpdateInfo (void); - void __fastcall UpdateTimeSol(void); - void __fastcall UpdateTimeObs(void); - void __fastcall UpdateInfoSol(void); - void __fastcall UpdateInfoObs(void); - void __fastcall UpdatePoint (int x, int y); - void __fastcall UpdateEnable (void); - void __fastcall FitTime (void); - void __fastcall SetRange (int all, double range); - void __fastcall FitRange (int all); - - void __fastcall SetCentX (double c); - void __fastcall SetScaleX (double s); - void __fastcall MouseDownTrk (int X, int Y); - void __fastcall MouseDownSol (int X, int Y); - void __fastcall MouseDownObs (int X, int Y); - void __fastcall MouseMoveTrk (int X, int Y, double dx, double dy, double dxs, double dys); - void __fastcall MouseMoveSol (int X, int Y, double dx, double dy, double dxs, double dys); - void __fastcall MouseMoveObs (int X, int Y, double dx, double dy, double dxs, double dys); - - void __fastcall DrawTrk (int level); - void __fastcall DrawTrkImage (int level); - void __fastcall DrawTrkMap (int level); - void __fastcall DrawTrkPnt (const TIMEPOS *pos, int level, int style); - void __fastcall DrawTrkPos (const double *rr, int type, int siz, TColor color, UTF8String label); - void __fastcall DrawTrkStat (const TIMEPOS *pos, UTF8String header, int p); - void __fastcall DrawTrkError (const TIMEPOS *pos, int style); - void __fastcall DrawTrkArrow (const TIMEPOS *pos); - void __fastcall DrawTrkVel (const TIMEPOS *vel); - void __fastcall DrawLabel (TGraph *g, TPoint p, UTF8String label, int ha, int va); - void __fastcall DrawMark (TGraph *g, TPoint p, int mark, TColor color, int size, - int rot); - void __fastcall DrawSol (int level, int type); - void __fastcall DrawSolPnt (const TIMEPOS *pos, int level, int style); - void __fastcall DrawSolStat (const TIMEPOS *pos, UTF8String unit, int p); - void __fastcall DrawNsat (int level); - void __fastcall DrawRes (int level); - void __fastcall DrawResE (int level); - void __fastcall DrawPolyS (TGraph *graph, double *x, double *y, int n, - TColor color, int style); - - void __fastcall DrawObs (int level); - void __fastcall DrawObsSlip (double *yp); - void __fastcall DrawObsEphem (double *yp); - void __fastcall DrawSkyImage (int level); - void __fastcall DrawSky (int level); - void __fastcall DrawSolSky (int level); - void __fastcall DrawDop (int level); - void __fastcall DrawSolDop (int level); - void __fastcall DrawDopStat (double *dop, int *ns, int n); - void __fastcall DrawSnr (int level); - void __fastcall DrawSnrE (int level); - void __fastcall DrawMpS (int level); - - AnsiString __fastcall U2A (UnicodeString str); - UnicodeString __fastcall A2U (AnsiString str); - - TIMEPOS * __fastcall SolToPos (solbuf_t *sol, int index, int qflag, int type); - TIMEPOS * __fastcall SolToNsat(solbuf_t *sol, int index, int qflag); - - void __fastcall PosToXyz (gtime_t time, const double *rr, int type, double *xyz); - void __fastcall CovToXyz (const double *rr, const float *qr, int type, - double *xyzs); - void __fastcall CalcStats (const double *x, int n, double ref, double &ave, - double &std, double &rms); - int __fastcall FitPos (gtime_t *time, double *opos, double *ovel); - - UTF8String __fastcall LatLonStr(const double *pos, int ndec); - TColor __fastcall ObsColor (const obsd_t *obs, double az, double el); - TColor __fastcall SysColor (int sat); - TColor __fastcall SnrColor (double snr); - TColor __fastcall MpColor (double mp); - void __fastcall ReadStaPos (const char *file, const char *sta, double *rr); - int __fastcall SearchPos (int x, int y); - void __fastcall TimeSpan (gtime_t *ts, gtime_t *te, double *tint); - double __fastcall TimePos (gtime_t time); - void __fastcall TimeStr(gtime_t time, int n, int tsys, char *str); - int __fastcall ExecCmd (AnsiString cmd); - void __fastcall ShowMsg (UTF8String msg); - void __fastcall ShowLegend (UTF8String *msgs); - void __fastcall ShowObsLegend (UTF8String *msgs); - void __fastcall LoadOpt (void); - void __fastcall SaveOpt (void); - - BEGIN_MESSAGE_MAP // for files drop, cursor key down event - MESSAGE_HANDLER(WM_DROPFILES,TWMDropFiles,DropFiles); - MESSAGE_HANDLER(CM_DIALOGKEY,TWMKey,CMDialogKey); - END_MESSAGE_MAP(TForm); - -public: - Graphics::TBitmap *SkyImageR; - AnsiString IniFile; - AnsiString MapImageFile; - AnsiString SkyImageFile; - AnsiString RnxOpts; - tle_t TLEData; - gis_t Gis; - - // connection settings - int RtStream[2]; - AnsiString RtPath1,RtPath2; - AnsiString StrPaths[2][3]; - AnsiString StrCmds[2][2]; - int StrCmdEna[2][2]; - int RtFormat[2]; - int RtConnType; - int RtTimeForm; - int RtDegForm; - AnsiString RtFieldSep; - int RtTimeOutTime; - int RtReConnTime; - double ElMaskData[361]; - - // time options - int TimeEna[3]; - gtime_t TimeStart; - gtime_t TimeEnd; - double TimeInt; - - // map image options - int MapSize[2],MapScaleEq; - double MapScaleX,MapScaleY; - double MapLat,MapLon; - int PointType; - - // sky image options - int SkySize[2],SkyDestCorr,SkyElMask,SkyRes,SkyFlip,SkyBinarize; - double SkyCent[2],SkyScale,SkyScaleR,SkyFov[3],SkyDest[10]; - double SkyBinThres1,SkyBinThres2; - - // plot options - int TimeLabel; - int LatLonFmt; - int ShowStats; - int ShowSlip; - int ShowHalfC; - int ShowEph; - double ElMask; - int ElMaskP; - int HideLowSat; - double MaxDop,MaxMP; - int NavSys; - AnsiString ExSats; - int ShowErr; - int ShowArrow; - int ShowGLabel; - int ShowLabel; - int ShowCompass; - int ShowScale; - int AutoScale; - double YRange; - int RtBuffSize; - int TimeSyncOut; - int TimeSyncPort; - int Origin; - int RcvPos; - double OOPos[3]; - TColor MColor[2][8]; // {{mark1 0-7},{mark2 0-7}} - TColor CColor[4]; // {background,grid,text,line} - TColor MapColor [MAXMAPLAYER]; // mapcolor line - TColor MapColorF[MAXMAPLAYER]; // mapcolor fill - int PlotStyle; - int MarkSize; - int AnimCycle; - int RefCycle; - int Trace; - AnsiString FontName; - int FontSize; - AnsiString ShapeFile; - AnsiString TLEFile; - AnsiString TLESatFile; - - // map view options - int MapApi; - AnsiString MapStrs[6][3],ApiKey; - - AnsiString Title; - UnicodeString PntName[MAXWAYPNT]; - double PntPos[MAXWAYPNT][3]; - int NWayPnt,SelWayPnt; - int OPosType; - double OPos[3],OVel[3]; - - AnsiString StrHistory[10]; - - __fastcall TPlot(TComponent* Owner); - void __fastcall ReadSol (TStrings *files, int sel); - void __fastcall ReadObs (TStrings *files); - void __fastcall ReadNav (TStrings *files); - void __fastcall ReadMapData(AnsiString file); - void __fastcall ReadSkyData(AnsiString file); - void __fastcall ReadSkyTag (AnsiString file); - void __fastcall ReadGpxFile(AnsiString file); - void __fastcall ReadPosFile(AnsiString file); - void __fastcall ReadWaypoint(AnsiString file); - void __fastcall SaveGpxFile(AnsiString file); - void __fastcall SavePosFile(AnsiString file); - void __fastcall SaveWaypoint(AnsiString file); - void __fastcall UpdateSky (void); - void __fastcall UpdatePlot (void); - void __fastcall GenObsSlip(int *LLI); - void __fastcall ReadElMaskData(AnsiString file); - int __fastcall GetCurrentPos(double *rr); - int __fastcall GetCenterPos(double *rr); - void __fastcall SetTrkCent(double lat, double lon); - void __fastcall Refresh_MapView(void); +class TPlot : public TForm { + __published : TPanel *Panel1; + TPanel *Panel10; + TPanel *Panel11; + TPanel *Panel12; + TPanel *Panel2; + TPanel *Panel21; + TPanel *Panel22; + TPanel *StrStatus1; + TPanel *StrStatus2; + TPaintBox *Disp; + + TComboBox *PlotTypeS; + TComboBox *QFlag; + TComboBox *ObsType; + TComboBox *DopType; + TComboBox *SatList; + TListBox *RangeList; + TSpeedButton *BtnConnect; + TSpeedButton *BtnSol1; + TSpeedButton *BtnSol2; + TSpeedButton *BtnSol12; + TSpeedButton *BtnOn1; + TSpeedButton *BtnOn2; + TSpeedButton *BtnOn3; + TSpeedButton *BtnRangeList; + TSpeedButton *BtnFitHoriz; + TSpeedButton *BtnFitVert; + TSpeedButton *BtnCenterOri; + TSpeedButton *BtnFixHoriz; + TSpeedButton *BtnFixVert; + TSpeedButton *BtnShowTrack; + TSpeedButton *BtnShowSkyplot; + TSpeedButton *BtnShowImg; + TSpeedButton *BtnShowMap; + TSpeedButton *BtnAnimate; + TSpeedButton *BtnClear; + TSpeedButton *BtnReload; + TScrollBar *TimeScroll; + + TLabel *ConnectMsg; + TLabel *Message1; + TLabel *Message2; + TLabel *QL1; + TLabel *QL2; + TLabel *QL3; + TLabel *QL4; + TLabel *QL5; + TLabel *QL6; + TLabel *QL7; + TMainMenu *hh; + + TMenuItem *MenuFile; + TMenuItem *MenuOpenSol1; + TMenuItem *MenuOpenSol2; + TMenuItem *MenuOpenMapImage; + TMenuItem *MenuOpenShape; + TMenuItem *MenuOpenObs; + TMenuItem *MenuOpenNav; + TMenuItem *MenuOpenElevMask; + TMenuItem *MenuConnect; + TMenuItem *MenuDisconnect; + TMenuItem *MenuPort; + TMenuItem *MenuReload; + TMenuItem *MenuClear; + TMenuItem *MenuQuit; + + TMenuItem *MenuEdit; + TMenuItem *MenuTime; + TMenuItem *MenuMapImg; + TMenuItem *MenuWaypnt; + TMenuItem *MenuSrcSol; + TMenuItem *MenuSrcObs; + TMenuItem *MenyCopy; + TMenuItem *MenuOptions; + + TMenuItem *MenuView; + TMenuItem *MenuToolBar; + TMenuItem *MenuStatusBar; + TMenuItem *MenuMonitor1; + TMenuItem *MenuMonitor2; + TMenuItem *MenuCenterOri; + TMenuItem *MenuFitHoriz; + TMenuItem *MenuFitVert; + TMenuItem *MenuShowTrack; + TMenuItem *MenuFixHoriz; + TMenuItem *MenuFixVert; + TMenuItem *MenuShowImg; + TMenuItem *MenuShowMap; + TMenuItem *MenuAnimStart; + TMenuItem *MenuAnimStop; + + TMenuItem *MenuHelp; + TMenuItem *MenuAbout; + + TMenuItem *N1; + TMenuItem *N2; + TMenuItem *N3; + TMenuItem *N5; + TMenuItem *N6; + TMenuItem *N7; + TMenuItem *N8; + TMenuItem *N9; + TMenuItem *N10; + TMenuItem *N11; + TMenuItem *N12; + TMenuItem *N13; + + TTimer *Timer; + + TOpenDialog *OpenSolDialog; + TOpenDialog *OpenObsDialog; + TOpenDialog *OpenElMaskDialog; + TOpenDialog *OpenMapPathDialog; + TOpenDialog *OpenMapDialog; + TMenuItem *N14; + TMenuItem *MenuSaveDop; + TSaveDialog *SaveDialog; + TMenuItem *MenuSaveImage; + TSavePictureDialog *SaveImageDialog; + TMenuItem *N15; + TComboBox *FrqType; + TComboBox *ObsType2; + TMenuItem *MenuVisAna; + TMenuItem *N16; + TSpeedButton *BtnOptions; + TSpeedButton *BtnFixCent; + TMenuItem *MenuFixCent; + TSpeedButton *BtnMapView; + TMenuItem *MenuSaveSnrMp; + TMenuItem *MenuMapView; + TMenuItem *MenuOpenSkyImage; + TMenuItem *MenuSkyImg; + TMenuItem *MenuShowSkyplot; + TMenuItem *Windows1; + TMenuItem *MenuMax; + TMenuItem *MenuPlotMapView; + TMenuItem *N17; + TPanel *Panel101; + TPanel *Panel102; + TPanel *Panel103; + TPanel *Panel104; + TMenuItem *MenuSaveElMask; + TMenuItem *MenuMapLayer; + TSpeedButton *BtnMessage2; + TMenuItem *MenuOpenWaypoint; + TMenuItem *MenuSaveWaypoint; + TOpenDialog *OpenWaypointDialog; + TSaveDialog *SaveWaypointDialog; + TPanel *Panel3; + TPanel *PanelBrowse; + TSplitter *Splitter1; + TDriveComboBox *DriveSel; + TDirectoryListBox *DirSel; + TSplitter *Splitter2; + TFileListBox *FileList; + TComboBox *FileMask; + TMenuItem *MenuBrowse; + TPanel *StrStatus; + TSpeedButton *BtnShowGrid; + TMenuItem *MenuShowGrid; + TPanel *Panel4; + TSpeedButton *BtnUdList; + TSpeedButton *BtnFreq; + + void __fastcall FormCreate(TObject *Sender); + void __fastcall FormShow(TObject *Sender); + void __fastcall FormResize(TObject *Sender); + void __fastcall FormActivate(TObject *Sender); + void __fastcall FormKeyDown(TObject *Sender, WORD &Key, TShiftState Shift); + + void __fastcall MenuOpenSol1Click(TObject *Sender); + void __fastcall MenuOpenSol2Click(TObject *Sender); + void __fastcall MenuOpenMapImageClick(TObject *Sender); + void __fastcall MenuOpenShapeClick(TObject *Sender); + void __fastcall MenuOpenObsClick(TObject *Sender); + void __fastcall MenuOpenNavClick(TObject *Sender); + void __fastcall MenuOpenElevMaskClick(TObject *Sender); + void __fastcall MenuConnectClick(TObject *Sender); + void __fastcall MenuDisconnectClick(TObject *Sender); + void __fastcall MenuPortClick(TObject *Sender); + void __fastcall MenuReloadClick(TObject *Sender); + void __fastcall MenuClearClick(TObject *Sender); + void __fastcall MenuQuitClick(TObject *Sender); + + void __fastcall MenuTimeClick(TObject *Sender); + void __fastcall MenuMapImgClick(TObject *Sender); + void __fastcall MenuWaypointClick(TObject *Sender); + void __fastcall MenuSrcSolClick(TObject *Sender); + void __fastcall MenuSrcObsClick(TObject *Sender); + void __fastcall MenyCopyClick(TObject *Sender); + void __fastcall MenuOptionsClick(TObject *Sender); + + void __fastcall MenuToolBarClick(TObject *Sender); + void __fastcall MenuStatusBarClick(TObject *Sender); + void __fastcall MenuMonitor1Click(TObject *Sender); + void __fastcall MenuMonitor2Click(TObject *Sender); + void __fastcall MenuCenterOriClick(TObject *Sender); + void __fastcall MenuFitHorizClick(TObject *Sender); + void __fastcall MenuFitVertClick(TObject *Sender); + void __fastcall MenuShowTrackClick(TObject *Sender); + void __fastcall MenuFixHorizClick(TObject *Sender); + void __fastcall MenuFixVertClick(TObject *Sender); + void __fastcall MenuShowImgClick(TObject *Sender); + void __fastcall MenuShowMapClick(TObject *Sender); + void __fastcall MenuAnimStartClick(TObject *Sender); + void __fastcall MenuAnimStopClick(TObject *Sender); + void __fastcall MenuAboutClick(TObject *Sender); + + void __fastcall BtnConnectClick(TObject *Sender); + void __fastcall BtnSol1Click(TObject *Sender); + void __fastcall BtnSol2Click(TObject *Sender); + void __fastcall BtnSol12Click(TObject *Sender); + void __fastcall BtnSol1DblClick(TObject *Sender); + void __fastcall BtnSol2DblClick(TObject *Sender); + void __fastcall BtnShowImgClick(TObject *Sender); + void __fastcall BtnOn1Click(TObject *Sender); + void __fastcall BtnOn2Click(TObject *Sender); + void __fastcall BtnOn3Click(TObject *Sender); + void __fastcall BtnRangeListClick(TObject *Sender); + void __fastcall RangeListClick(TObject *Sender); + void __fastcall BtnCenterOriClick(TObject *Sender); + void __fastcall BtnFitHorizClick(TObject *Sender); + void __fastcall BtnFitVertClick(TObject *Sender); + void __fastcall BtnShowTrackClick(TObject *Sender); + void __fastcall BtnFixHorizClick(TObject *Sender); + void __fastcall BtnFixVertClick(TObject *Sender); + void __fastcall BtnShowMapClick(TObject *Sender); + void __fastcall BtnAnimateClick(TObject *Sender); + void __fastcall BtnClearClick(TObject *Sender); + void __fastcall BtnReloadClick(TObject *Sender); + + void __fastcall PlotTypeSChange(TObject *Sender); + void __fastcall QFlagChange(TObject *Sender); + void __fastcall ObsTypeChange(TObject *Sender); + void __fastcall DopTypeChange(TObject *Sender); + void __fastcall SatListChange(TObject *Sender); + void __fastcall TimeScrollChange(TObject *Sender); + + void __fastcall TimerTimer(TObject *Sender); + + void __fastcall DispPaint(TObject *Sender); + void __fastcall DispMouseLeave(TObject *Sender); + void __fastcall DispMouseMove(TObject *Sender, TShiftState Shift, int X, int Y); + void __fastcall DispMouseDown(TObject *Sender, TMouseButton Button, TShiftState Shift, int X, + int Y); + void __fastcall DispMouseUp(TObject *Sender, TMouseButton Button, TShiftState Shift, int X, + int Y); + void __fastcall MouseWheel(TObject *Sender, TShiftState Shift, int WheelDelta, TPoint &MousePos, + bool &Handled); + void __fastcall FormClose(TObject *Sender, TCloseAction &Action); + void __fastcall MenuSaveDopClick(TObject *Sender); + void __fastcall MenuSaveImageClick(TObject *Sender); + void __fastcall MenuVisAnaClick(TObject *Sender); + void __fastcall BtnOptionsClick(TObject *Sender); + void __fastcall BtnFixCentClick(TObject *Sender); + void __fastcall MenuFixCentClick(TObject *Sender); + void __fastcall BtnMapViewClick(TObject *Sender); + void __fastcall MenuMapViewClick(TObject *Sender); + void __fastcall MenuSaveSnrMpClick(TObject *Sender); + void __fastcall MenuOpenSkyImageClick(TObject *Sender); + void __fastcall MenuSkyImgClick(TObject *Sender); + void __fastcall MenuShowSkyplotClick(TObject *Sender); + void __fastcall BtnShowSkyplotClick(TObject *Sender); + void __fastcall MenuPlotMapViewClick(TObject *Sender); + void __fastcall MenuMaxClick(TObject *Sender); + void __fastcall DispGesture(TObject *Sender, const TGestureEventInfo &EventInfo, bool &Handled); + void __fastcall MenuSaveElMaskClick(TObject *Sender); + void __fastcall MenuMapLayerClick(TObject *Sender); + void __fastcall BtnMessage2Click(TObject *Sender); + void __fastcall MenuOpenWaypointClick(TObject *Sender); + void __fastcall MenuSaveWaypointClick(TObject *Sender); + void __fastcall DispDblClick(TObject *Sender); + void __fastcall FileMaskChange(TObject *Sender); + void __fastcall FileListClick(TObject *Sender); + void __fastcall Splitter1Moved(TObject *Sender); + void __fastcall MenuBrowseClick(TObject *Sender); + void __fastcall MenuShowGridClick(TObject *Sender); + void __fastcall BtnShowGridClick(TObject *Sender); + void __fastcall BtnUdListClick(TObject *Sender); + void __fastcall BtnFreqClick(TObject *Sender); + + protected: + void __fastcall CMDialogKey(Messages::TWMKey &Message); + + private: + Graphics::TBitmap *Buff; + Graphics::TBitmap *MapImage; + Graphics::TBitmap *SkyImageI; + TGraph *GraphT; + TGraph *GraphG[3]; + TGraph *GraphR; + TGraph *GraphS; + TGraph *GraphE[2]; + TStrings *OpenFiles; + TStrings *SolFiles[2]; + TStrings *ObsFiles; + TStrings *NavFiles; + TConsole *Console1, *Console2; + + stream_t Stream[2]; + stream_t StrTimeSync; + solbuf_t SolData[2]; + solstatbuf_t SolStat[2]; + int SolIndex[2]; + obs_t Obs; + nav_t Nav; + sta_t Sta; + double *Az, *El, *Mp[NFREQ + NEXOBS]; + char StrBuff[1024]; + int NStrBuff; + + gtime_t OEpoch; + int FormWidth, FormHeight; + int ConnectState, OpenRaw; + int NObs, *IndexObs, ObsIndex; + int Week; + int Flush, PlotType; + int NSolF1, NSolF2, NObsF, NNavF; + int SatMask[MAXSAT], SatSel[MAXSAT]; + int SimObs; + + int Drag, Xn, Yn; + double X0, Y0, Xc, Yc, Xs, Ys, Xcent, Xcent0; + uint32_t MouseDownTick; + + int GEState, GEDataState[2]; + double GEHeading; + + void __fastcall DropFiles(TWMDropFiles msg); + + void __fastcall ReadSolStat(TStrings *files, int sel); + int __fastcall ReadObsRnx(TStrings *files, obs_t *obs, nav_t *nav, sta_t *sta); + void __fastcall ReadMapTag(AnsiString file); + void __fastcall ReadShapeFile(TStrings *files); + void __fastcall GenVisData(void); + void __fastcall SaveDop(AnsiString file); + void __fastcall SaveSnrMp(AnsiString file); + void __fastcall SaveElMask(AnsiString file); + void __fastcall Connect(void); + void __fastcall Disconnect(void); + void __fastcall ConnectPath(const char *path, int ch); + int __fastcall CheckObs(AnsiString file); + void __fastcall UpdateObs(int nobs); + void __fastcall UpdateMp(void); + void __fastcall ClearObs(void); + void __fastcall ClearSol(void); + void __fastcall Clear(void); + void __fastcall Refresh(void); + void __fastcall Reload(void); + void __fastcall ReadWaitStart(void); + void __fastcall ReadWaitEnd(void); + + void __fastcall UpdateDisp(void); + void __fastcall UpdateType(int type); + void __fastcall UpdatePlotType(void); + void __fastcall UpdateSatList(void); + void __fastcall UpdateObsType(void); + void __fastcall UpdateSize(void); + void __fastcall UpdateColor(void); + void __fastcall UpdateTime(void); + void __fastcall UpdateOrigin(void); + void __fastcall UpdateSatMask(void); + void __fastcall UpdateSatSel(void); + void __fastcall UpdateInfo(void); + void __fastcall UpdateTimeSol(void); + void __fastcall UpdateTimeObs(void); + void __fastcall UpdateInfoSol(void); + void __fastcall UpdateInfoObs(void); + void __fastcall UpdatePoint(int x, int y); + void __fastcall UpdateEnable(void); + void __fastcall FitTime(void); + void __fastcall SetRange(int all, double range); + void __fastcall FitRange(int all); + + void __fastcall SetCentX(double c); + void __fastcall SetScaleX(double s); + void __fastcall MouseDownTrk(int X, int Y); + void __fastcall MouseDownSol(int X, int Y); + void __fastcall MouseDownObs(int X, int Y); + void __fastcall MouseMoveTrk(int X, int Y, double dx, double dy, double dxs, double dys); + void __fastcall MouseMoveSol(int X, int Y, double dx, double dy, double dxs, double dys); + void __fastcall MouseMoveObs(int X, int Y, double dx, double dy, double dxs, double dys); + + void __fastcall DrawTrk(int level); + void __fastcall DrawTrkImage(int level); + void __fastcall DrawTrkMap(int level); + void __fastcall DrawTrkPnt(const TIMEPOS *pos, int level, int style); + void __fastcall DrawTrkPos(const double *rr, int type, int siz, TColor color, UTF8String label); + void __fastcall DrawTrkStat(const TIMEPOS *pos, UTF8String header, int p); + void __fastcall DrawTrkError(const TIMEPOS *pos, int style); + void __fastcall DrawTrkArrow(const TIMEPOS *pos); + void __fastcall DrawTrkVel(const TIMEPOS *vel); + void __fastcall DrawLabel(TGraph *g, TPoint p, UTF8String label, int ha, int va); + void __fastcall DrawMark(TGraph *g, TPoint p, int mark, TColor color, int size, int rot); + void __fastcall DrawSol(int level, int type); + void __fastcall DrawSolPnt(const TIMEPOS *pos, int level, int style); + void __fastcall DrawSolStat(const TIMEPOS *pos, UTF8String unit, int p); + void __fastcall DrawNsat(int level); + void __fastcall DrawRes(int level); + void __fastcall DrawResE(int level); + void __fastcall DrawPolyS(TGraph *graph, double *x, double *y, int n, TColor color, int style); + + void __fastcall DrawObs(int level); + void __fastcall DrawObsSlip(double *yp); + void __fastcall DrawObsEphem(double *yp); + void __fastcall DrawSkyImage(int level); + void __fastcall DrawSky(int level); + void __fastcall DrawSolSky(int level); + void __fastcall DrawDop(int level); + void __fastcall DrawSolDop(int level); + void __fastcall DrawDopStat(double *dop, int *ns, int n); + void __fastcall DrawSnr(int level); + void __fastcall DrawSnrE(int level); + void __fastcall DrawMpS(int level); + + AnsiString __fastcall U2A(UnicodeString str); + UnicodeString __fastcall A2U(AnsiString str); + + TIMEPOS *__fastcall SolToPos(solbuf_t *sol, int index, int qflag, int type); + TIMEPOS *__fastcall SolToNsat(solbuf_t *sol, int index, int qflag); + + void __fastcall PosToXyz(gtime_t time, const double *rr, int type, double *xyz); + void __fastcall CovToXyz(const double *rr, const float *qr, int type, double *xyzs); + void __fastcall CalcStats(const double *x, int n, double ref, double &ave, double &std, + double &rms); + int __fastcall FitPos(gtime_t *time, double *opos, double *ovel); + + UTF8String __fastcall LatLonStr(const double *pos, int ndec); + TColor __fastcall ObsColor(const obsd_t *obs, double az, double el); + TColor __fastcall SysColor(int sat); + TColor __fastcall SnrColor(double snr); + TColor __fastcall MpColor(double mp); + void __fastcall ReadStaPos(const char *file, const char *sta, double *rr); + int __fastcall SearchPos(int x, int y); + void __fastcall TimeSpan(gtime_t *ts, gtime_t *te, double *tint); + double __fastcall TimePos(gtime_t time); + void __fastcall TimeStr(gtime_t time, int n, int tsys, char *str); + int __fastcall ExecCmd(AnsiString cmd); + void __fastcall ShowMsg(UTF8String msg); + void __fastcall ShowLegend(UTF8String *msgs); + void __fastcall ShowObsLegend(UTF8String *msgs); + void __fastcall LoadOpt(void); + void __fastcall SaveOpt(void); + + BEGIN_MESSAGE_MAP // for files drop, cursor key down event + MESSAGE_HANDLER(WM_DROPFILES, TWMDropFiles, DropFiles); + MESSAGE_HANDLER(CM_DIALOGKEY, TWMKey, CMDialogKey); + END_MESSAGE_MAP(TForm); + + public: + Graphics::TBitmap *SkyImageR; + AnsiString IniFile; + AnsiString MapImageFile; + AnsiString SkyImageFile; + AnsiString RnxOpts; + tle_t TLEData; + gis_t Gis; + + // connection settings + int RtStream[2]; + AnsiString RtPath1, RtPath2; + AnsiString StrPaths[2][3]; + AnsiString StrCmds[2][2]; + int StrCmdEna[2][2]; + int RtFormat[2]; + int RtConnType; + int RtTimeForm; + int RtDegForm; + AnsiString RtFieldSep; + int RtTimeOutTime; + int RtReConnTime; + double ElMaskData[361]; + + // time options + int TimeEna[3]; + gtime_t TimeStart; + gtime_t TimeEnd; + double TimeInt; + + // map image options + int MapSize[2], MapScaleEq; + double MapScaleX, MapScaleY; + double MapLat, MapLon; + int PointType; + + // sky image options + int SkySize[2], SkyDestCorr, SkyElMask, SkyRes, SkyFlip, SkyBinarize; + double SkyCent[2], SkyScale, SkyScaleR, SkyFov[3], SkyDest[10]; + double SkyBinThres1, SkyBinThres2; + + // plot options + int TimeLabel; + int LatLonFmt; + int ShowStats; + int ShowSlip; + int ShowHalfC; + int ShowEph; + double ElMask; + int ElMaskP; + int HideLowSat; + double MaxDop, MaxMP; + int NavSys; + AnsiString ExSats; + int ShowErr; + int ShowArrow; + int ShowGLabel; + int ShowLabel; + int ShowCompass; + int ShowScale; + int AutoScale; + double YRange; + int RtBuffSize; + int TimeSyncOut; + int TimeSyncPort; + int Origin; + int RcvPos; + double OOPos[3]; + TColor MColor[2][8]; // {{mark1 0-7},{mark2 0-7}} + TColor CColor[4]; // {background,grid,text,line} + TColor MapColor[MAXMAPLAYER]; // mapcolor line + TColor MapColorF[MAXMAPLAYER]; // mapcolor fill + int PlotStyle; + int MarkSize; + int AnimCycle; + int RefCycle; + int Trace; + AnsiString FontName; + int FontSize; + AnsiString ShapeFile; + AnsiString TLEFile; + AnsiString TLESatFile; + + // map view options + int MapApi; + AnsiString MapStrs[6][3], ApiKey; + + AnsiString Title; + UnicodeString PntName[MAXWAYPNT]; + double PntPos[MAXWAYPNT][3]; + int NWayPnt, SelWayPnt; + int OPosType; + double OPos[3], OVel[3]; + + AnsiString StrHistory[10]; + + __fastcall TPlot(TComponent *Owner); + void __fastcall ReadSol(TStrings *files, int sel); + void __fastcall ReadObs(TStrings *files); + void __fastcall ReadNav(TStrings *files); + void __fastcall ReadMapData(AnsiString file); + void __fastcall ReadSkyData(AnsiString file); + void __fastcall ReadSkyTag(AnsiString file); + void __fastcall ReadGpxFile(AnsiString file); + void __fastcall ReadPosFile(AnsiString file); + void __fastcall ReadWaypoint(AnsiString file); + void __fastcall SaveGpxFile(AnsiString file); + void __fastcall SavePosFile(AnsiString file); + void __fastcall SaveWaypoint(AnsiString file); + void __fastcall UpdateSky(void); + void __fastcall UpdatePlot(void); + void __fastcall GenObsSlip(int *LLI); + void __fastcall ReadElMaskData(AnsiString file); + int __fastcall GetCurrentPos(double *rr); + int __fastcall GetCenterPos(double *rr); + void __fastcall SetTrkCent(double lat, double lon); + void __fastcall Refresh_MapView(void); }; //--------------------------------------------------------------------------- extern PACKAGE TPlot *Plot; diff --git a/app/winapp/rtkplot/plotopt.cpp b/app/winapp/rtkplot/plotopt.cpp index b37417e2a..94ecc6d54 100644 --- a/app/winapp/rtkplot/plotopt.cpp +++ b/app/winapp/rtkplot/plotopt.cpp @@ -2,342 +2,309 @@ #include #pragma hdrstop -#include "plotmain.h" #include "plotopt.h" + +#include "plotmain.h" #include "refdlg.h" -#include "viewer.h" #include "rtklib.h" +#include "viewer.h" //--------------------------------------------------------------------------- #pragma package(smart_init) #pragma resource "*.dfm" TPlotOptDialog *PlotOptDialog; //--------------------------------------------------------------------------- -static double str2dbl(AnsiString str) -{ - double val=0.0; - sscanf(str.c_str(),"%lf",&val); - return val; +static double str2dbl(AnsiString str) { + double val = 0.0; + sscanf(str.c_str(), "%lf", &val); + return val; } //--------------------------------------------------------------------------- -__fastcall TPlotOptDialog::TPlotOptDialog(TComponent* Owner) - : TForm(Owner) -{ - FontOpt=new TFont; -} +__fastcall TPlotOptDialog::TPlotOptDialog(TComponent *Owner) : TForm(Owner) { FontOpt = new TFont; } //--------------------------------------------------------------------------- -void __fastcall TPlotOptDialog::FormShow(TObject *Sender) -{ - char s1[64],s2[64]; - AnsiString s; - int marks[]={1,2,3,4,5,10,15,20}; - - TimeLabel ->ItemIndex=Plot->TimeLabel; - LatLonFmt ->ItemIndex=Plot->LatLonFmt; - AutoScale ->ItemIndex=Plot->AutoScale; - ShowStats ->ItemIndex=Plot->ShowStats; - ShowArrow ->ItemIndex=Plot->ShowArrow; - ShowSlip ->ItemIndex=Plot->ShowSlip; - ShowHalfC ->ItemIndex=Plot->ShowHalfC; - ShowErr ->ItemIndex=Plot->ShowErr; - ShowEph ->ItemIndex=Plot->ShowEph; - ShowLabel ->ItemIndex=Plot->ShowLabel; - ShowGLabel ->ItemIndex=Plot->ShowGLabel; - ShowScale ->ItemIndex=Plot->ShowScale; - ShowCompass->ItemIndex=Plot->ShowCompass; - PlotStyle ->ItemIndex=Plot->PlotStyle; - for (int i=0;i<8;i++) { - if (marks[i]==Plot->MarkSize) MarkSize->ItemIndex=i; - } - MColor1 ->Color=Plot->MColor[0][1]; - MColor2 ->Color=Plot->MColor[0][2]; - MColor3 ->Color=Plot->MColor[0][3]; - MColor4 ->Color=Plot->MColor[0][4]; - MColor5 ->Color=Plot->MColor[0][5]; - MColor6 ->Color=Plot->MColor[0][6]; - MColor7 ->Color=Plot->MColor[1][1]; - MColor8 ->Color=Plot->MColor[1][2]; - MColor9 ->Color=Plot->MColor[1][3]; - MColor10->Color=Plot->MColor[1][4]; - MColor11->Color=Plot->MColor[1][5]; - MColor12->Color=Plot->MColor[1][6]; - Color1 ->Color=Plot->CColor[0]; - Color2 ->Color=Plot->CColor[1]; - Color3 ->Color=Plot->CColor[2]; - Color4 ->Color=Plot->CColor[3]; - - //FontOpt->Assign(Plot->Font); - FontOpt->Name=Plot->FontName; - FontOpt->Size=Plot->FontSize; - UpdateFont(); - - ElMask ->Text=s.sprintf("%g",Plot->ElMask); - MaxDop ->Text=s.sprintf("%g",Plot->MaxDop); - MaxMP ->Text=s.sprintf("%g",Plot->MaxMP ); - Origin ->ItemIndex=Plot->Origin; - RcvPos ->ItemIndex=Plot->RcvPos; - RefPos1->Text=s.sprintf("%.9f",Plot->OOPos[0]*R2D); - RefPos2->Text=s.sprintf("%.9f",Plot->OOPos[1]*R2D); - RefPos3->Text=s.sprintf("%.4f",Plot->OOPos[2]); - NavSys1->Checked=Plot->NavSys&SYS_GPS; - NavSys2->Checked=Plot->NavSys&SYS_GLO; - NavSys3->Checked=Plot->NavSys&SYS_GAL; - NavSys4->Checked=Plot->NavSys&SYS_QZS; - NavSys5->Checked=Plot->NavSys&SYS_SBS; - NavSys6->Checked=Plot->NavSys&SYS_CMP; - NavSys7->Checked=Plot->NavSys&SYS_IRN; - AnimCycle->Text=s.sprintf("%d",Plot->AnimCycle); - RefCycle ->Text=s.sprintf("%d",Plot->RefCycle ); - HideLowSat->ItemIndex=Plot->HideLowSat; - ElMaskP->ItemIndex=Plot->ElMaskP; - ExSats->Text=Plot->ExSats; - BuffSize->Text=s.sprintf("%d",Plot->RtBuffSize); - ChkTimeSync->Checked=Plot->TimeSyncOut; - EditTimeSync->Text=s.sprintf("%d",Plot->TimeSyncPort); - RnxOpts->Text=Plot->RnxOpts; - ShapeFile->Text=Plot->ShapeFile; - TLEFile->Text=Plot->TLEFile; - TLESatFile->Text=Plot->TLESatFile; - - for (int i=0;iItems->Count;i++) { - double range; - char unit[32]=""; - - s=YRange->Items->Strings[i]; - if (sscanf(s.c_str(),"%lf%31s",&range,unit)<1) continue; - if (!strcmp(unit,"cm")) range*=0.01; - else if (!strcmp(unit,"km")) range*=1000.0; - if (range==Plot->YRange) { - YRange->ItemIndex=i; - break; - } +void __fastcall TPlotOptDialog::FormShow(TObject *Sender) { + char s1[64], s2[64]; + AnsiString s; + int marks[] = {1, 2, 3, 4, 5, 10, 15, 20}; + + TimeLabel->ItemIndex = Plot->TimeLabel; + LatLonFmt->ItemIndex = Plot->LatLonFmt; + AutoScale->ItemIndex = Plot->AutoScale; + ShowStats->ItemIndex = Plot->ShowStats; + ShowArrow->ItemIndex = Plot->ShowArrow; + ShowSlip->ItemIndex = Plot->ShowSlip; + ShowHalfC->ItemIndex = Plot->ShowHalfC; + ShowErr->ItemIndex = Plot->ShowErr; + ShowEph->ItemIndex = Plot->ShowEph; + ShowLabel->ItemIndex = Plot->ShowLabel; + ShowGLabel->ItemIndex = Plot->ShowGLabel; + ShowScale->ItemIndex = Plot->ShowScale; + ShowCompass->ItemIndex = Plot->ShowCompass; + PlotStyle->ItemIndex = Plot->PlotStyle; + for (int i = 0; i < 8; i++) { + if (marks[i] == Plot->MarkSize) MarkSize->ItemIndex = i; + } + MColor1->Color = Plot->MColor[0][1]; + MColor2->Color = Plot->MColor[0][2]; + MColor3->Color = Plot->MColor[0][3]; + MColor4->Color = Plot->MColor[0][4]; + MColor5->Color = Plot->MColor[0][5]; + MColor6->Color = Plot->MColor[0][6]; + MColor7->Color = Plot->MColor[1][1]; + MColor8->Color = Plot->MColor[1][2]; + MColor9->Color = Plot->MColor[1][3]; + MColor10->Color = Plot->MColor[1][4]; + MColor11->Color = Plot->MColor[1][5]; + MColor12->Color = Plot->MColor[1][6]; + Color1->Color = Plot->CColor[0]; + Color2->Color = Plot->CColor[1]; + Color3->Color = Plot->CColor[2]; + Color4->Color = Plot->CColor[3]; + + // FontOpt->Assign(Plot->Font); + FontOpt->Name = Plot->FontName; + FontOpt->Size = Plot->FontSize; + UpdateFont(); + + ElMask->Text = s.sprintf("%g", Plot->ElMask); + MaxDop->Text = s.sprintf("%g", Plot->MaxDop); + MaxMP->Text = s.sprintf("%g", Plot->MaxMP); + Origin->ItemIndex = Plot->Origin; + RcvPos->ItemIndex = Plot->RcvPos; + RefPos1->Text = s.sprintf("%.9f", Plot->OOPos[0] * R2D); + RefPos2->Text = s.sprintf("%.9f", Plot->OOPos[1] * R2D); + RefPos3->Text = s.sprintf("%.4f", Plot->OOPos[2]); + NavSys1->Checked = Plot->NavSys & SYS_GPS; + NavSys2->Checked = Plot->NavSys & SYS_GLO; + NavSys3->Checked = Plot->NavSys & SYS_GAL; + NavSys4->Checked = Plot->NavSys & SYS_QZS; + NavSys5->Checked = Plot->NavSys & SYS_SBS; + NavSys6->Checked = Plot->NavSys & SYS_CMP; + NavSys7->Checked = Plot->NavSys & SYS_IRN; + AnimCycle->Text = s.sprintf("%d", Plot->AnimCycle); + RefCycle->Text = s.sprintf("%d", Plot->RefCycle); + HideLowSat->ItemIndex = Plot->HideLowSat; + ElMaskP->ItemIndex = Plot->ElMaskP; + ExSats->Text = Plot->ExSats; + BuffSize->Text = s.sprintf("%d", Plot->RtBuffSize); + ChkTimeSync->Checked = Plot->TimeSyncOut; + EditTimeSync->Text = s.sprintf("%d", Plot->TimeSyncPort); + RnxOpts->Text = Plot->RnxOpts; + ShapeFile->Text = Plot->ShapeFile; + TLEFile->Text = Plot->TLEFile; + TLESatFile->Text = Plot->TLESatFile; + + for (int i = 0; i < YRange->Items->Count; i++) { + double range; + char unit[32] = ""; + + s = YRange->Items->Strings[i]; + if (sscanf(s.c_str(), "%lf%31s", &range, unit) < 1) continue; + if (!strcmp(unit, "cm")) + range *= 0.01; + else if (!strcmp(unit, "km")) + range *= 1000.0; + if (range == Plot->YRange) { + YRange->ItemIndex = i; + break; } - UpdateEnable(); + } + UpdateEnable(); } //--------------------------------------------------------------------------- -void __fastcall TPlotOptDialog::BtnOKClick(TObject *Sender) -{ - AnsiString s; - double range; - char unit[32]; - int marks[]={1,2,3,4,5,10,15,20}; - - Plot->TimeLabel =TimeLabel ->ItemIndex; - Plot->LatLonFmt =LatLonFmt ->ItemIndex; - Plot->AutoScale =AutoScale ->ItemIndex; - Plot->ShowStats =ShowStats ->ItemIndex; - Plot->ShowArrow =ShowArrow ->ItemIndex; - Plot->ShowSlip =ShowSlip ->ItemIndex; - Plot->ShowHalfC =ShowHalfC ->ItemIndex; - Plot->ShowErr =ShowErr ->ItemIndex; - Plot->ShowEph =ShowEph ->ItemIndex; - Plot->ShowLabel =ShowLabel ->ItemIndex; - Plot->ShowGLabel =ShowGLabel ->ItemIndex; - Plot->ShowScale =ShowScale ->ItemIndex; - Plot->ShowCompass=ShowCompass->ItemIndex; - Plot->PlotStyle =PlotStyle ->ItemIndex; - Plot->MarkSize=marks[MarkSize->ItemIndex]; - Plot->MColor[0][1]=MColor1 ->Color; - Plot->MColor[0][2]=MColor2 ->Color; - Plot->MColor[0][3]=MColor3 ->Color; - Plot->MColor[0][4]=MColor4 ->Color; - Plot->MColor[0][5]=MColor5 ->Color; - Plot->MColor[0][6]=MColor6 ->Color; - Plot->MColor[1][1]=MColor7 ->Color; - Plot->MColor[1][2]=MColor8 ->Color; - Plot->MColor[1][3]=MColor9 ->Color; - Plot->MColor[1][4]=MColor10->Color; - Plot->MColor[1][5]=MColor11->Color; - Plot->MColor[1][6]=MColor12->Color; - Plot->CColor[0]=Color1 ->Color; - Plot->CColor[1]=Color2 ->Color; - Plot->CColor[2]=Color3 ->Color; - Plot->CColor[3]=Color4 ->Color; - - Plot->FontName=FontOpt->Name; - Plot->FontSize=FontOpt->Size; - Plot->Font->Assign(FontOpt); +void __fastcall TPlotOptDialog::BtnOKClick(TObject *Sender) { + AnsiString s; + double range; + char unit[32]; + int marks[] = {1, 2, 3, 4, 5, 10, 15, 20}; - Plot->ElMask=str2dbl(ElMask->Text); - Plot->MaxDop=str2dbl(MaxDop->Text); - Plot->MaxMP =str2dbl(MaxMP ->Text); - Plot->YRange=str2dbl(YRange->Text); - Plot->Origin=Origin->ItemIndex; - Plot->RcvPos=RcvPos->ItemIndex; - Plot->OOPos[0]=str2dbl(RefPos1->Text)*D2R; - Plot->OOPos[1]=str2dbl(RefPos2->Text)*D2R; - Plot->OOPos[2]=str2dbl(RefPos3->Text); - Plot->NavSys=(NavSys1->Checked?SYS_GPS:0)| - (NavSys2->Checked?SYS_GLO:0)| - (NavSys3->Checked?SYS_GAL:0)| - (NavSys4->Checked?SYS_QZS:0)| - (NavSys5->Checked?SYS_SBS:0)| - (NavSys6->Checked?SYS_CMP:0)| - (NavSys7->Checked?SYS_IRN:0); - Plot->AnimCycle=AnimCycle->Text.ToInt(); - Plot->RefCycle =RefCycle ->Text.ToInt(); - Plot->HideLowSat=HideLowSat->ItemIndex; - Plot->ElMaskP=ElMaskP->ItemIndex; - Plot->RtBuffSize=(int)str2dbl(BuffSize->Text); - Plot->TimeSyncOut=ChkTimeSync->Checked; - Plot->TimeSyncPort=EditTimeSync->Text.ToInt(); - Plot->ExSats=ExSats->Text; - Plot->RnxOpts=RnxOpts->Text; - Plot->ShapeFile=ShapeFile->Text; - Plot->TLEFile=TLEFile->Text; - Plot->TLESatFile=TLESatFile->Text; + Plot->TimeLabel = TimeLabel->ItemIndex; + Plot->LatLonFmt = LatLonFmt->ItemIndex; + Plot->AutoScale = AutoScale->ItemIndex; + Plot->ShowStats = ShowStats->ItemIndex; + Plot->ShowArrow = ShowArrow->ItemIndex; + Plot->ShowSlip = ShowSlip->ItemIndex; + Plot->ShowHalfC = ShowHalfC->ItemIndex; + Plot->ShowErr = ShowErr->ItemIndex; + Plot->ShowEph = ShowEph->ItemIndex; + Plot->ShowLabel = ShowLabel->ItemIndex; + Plot->ShowGLabel = ShowGLabel->ItemIndex; + Plot->ShowScale = ShowScale->ItemIndex; + Plot->ShowCompass = ShowCompass->ItemIndex; + Plot->PlotStyle = PlotStyle->ItemIndex; + Plot->MarkSize = marks[MarkSize->ItemIndex]; + Plot->MColor[0][1] = MColor1->Color; + Plot->MColor[0][2] = MColor2->Color; + Plot->MColor[0][3] = MColor3->Color; + Plot->MColor[0][4] = MColor4->Color; + Plot->MColor[0][5] = MColor5->Color; + Plot->MColor[0][6] = MColor6->Color; + Plot->MColor[1][1] = MColor7->Color; + Plot->MColor[1][2] = MColor8->Color; + Plot->MColor[1][3] = MColor9->Color; + Plot->MColor[1][4] = MColor10->Color; + Plot->MColor[1][5] = MColor11->Color; + Plot->MColor[1][6] = MColor12->Color; + Plot->CColor[0] = Color1->Color; + Plot->CColor[1] = Color2->Color; + Plot->CColor[2] = Color3->Color; + Plot->CColor[3] = Color4->Color; - s=YRange->Text; - if (sscanf(s.c_str(),"%lf%31s",&range,unit)>=1) { - if (!strcmp(unit,"cm")) range*=0.01; - else if (!strcmp(unit,"km")) range*=1000.0; - Plot->YRange=range; - } + Plot->FontName = FontOpt->Name; + Plot->FontSize = FontOpt->Size; + Plot->Font->Assign(FontOpt); + + Plot->ElMask = str2dbl(ElMask->Text); + Plot->MaxDop = str2dbl(MaxDop->Text); + Plot->MaxMP = str2dbl(MaxMP->Text); + Plot->YRange = str2dbl(YRange->Text); + Plot->Origin = Origin->ItemIndex; + Plot->RcvPos = RcvPos->ItemIndex; + Plot->OOPos[0] = str2dbl(RefPos1->Text) * D2R; + Plot->OOPos[1] = str2dbl(RefPos2->Text) * D2R; + Plot->OOPos[2] = str2dbl(RefPos3->Text); + Plot->NavSys = (NavSys1->Checked ? SYS_GPS : 0) | (NavSys2->Checked ? SYS_GLO : 0) | + (NavSys3->Checked ? SYS_GAL : 0) | (NavSys4->Checked ? SYS_QZS : 0) | + (NavSys5->Checked ? SYS_SBS : 0) | (NavSys6->Checked ? SYS_CMP : 0) | + (NavSys7->Checked ? SYS_IRN : 0); + Plot->AnimCycle = AnimCycle->Text.ToInt(); + Plot->RefCycle = RefCycle->Text.ToInt(); + Plot->HideLowSat = HideLowSat->ItemIndex; + Plot->ElMaskP = ElMaskP->ItemIndex; + Plot->RtBuffSize = (int)str2dbl(BuffSize->Text); + Plot->TimeSyncOut = ChkTimeSync->Checked; + Plot->TimeSyncPort = EditTimeSync->Text.ToInt(); + Plot->ExSats = ExSats->Text; + Plot->RnxOpts = RnxOpts->Text; + Plot->ShapeFile = ShapeFile->Text; + Plot->TLEFile = TLEFile->Text; + Plot->TLESatFile = TLESatFile->Text; + + s = YRange->Text; + if (sscanf(s.c_str(), "%lf%31s", &range, unit) >= 1) { + if (!strcmp(unit, "cm")) + range *= 0.01; + else if (!strcmp(unit, "km")) + range *= 1000.0; + Plot->YRange = range; + } } //--------------------------------------------------------------------------- -void __fastcall TPlotOptDialog::MColorClick(TObject *Sender) -{ - TPanel *panel=(TPanel *)Sender; - ColorDialog->Color=panel->Color; - if (!ColorDialog->Execute()) return; - panel->Color=ColorDialog->Color; +void __fastcall TPlotOptDialog::MColorClick(TObject *Sender) { + TPanel *panel = (TPanel *)Sender; + ColorDialog->Color = panel->Color; + if (!ColorDialog->Execute()) return; + panel->Color = ColorDialog->Color; } //--------------------------------------------------------------------------- -void __fastcall TPlotOptDialog::BtnColor1Click(TObject *Sender) -{ - ColorDialog->Color=Color1->Color; - if (!ColorDialog->Execute()) return; - Color1->Color=ColorDialog->Color; +void __fastcall TPlotOptDialog::BtnColor1Click(TObject *Sender) { + ColorDialog->Color = Color1->Color; + if (!ColorDialog->Execute()) return; + Color1->Color = ColorDialog->Color; } //--------------------------------------------------------------------------- -void __fastcall TPlotOptDialog::BtnColor2Click(TObject *Sender) -{ - ColorDialog->Color=Color2->Color; - if (!ColorDialog->Execute()) return; - Color2->Color=ColorDialog->Color; +void __fastcall TPlotOptDialog::BtnColor2Click(TObject *Sender) { + ColorDialog->Color = Color2->Color; + if (!ColorDialog->Execute()) return; + Color2->Color = ColorDialog->Color; } //--------------------------------------------------------------------------- -void __fastcall TPlotOptDialog::BtnColor3Click(TObject *Sender) -{ - ColorDialog->Color=Color3->Color; - if (!ColorDialog->Execute()) return; - Color3->Color=ColorDialog->Color; +void __fastcall TPlotOptDialog::BtnColor3Click(TObject *Sender) { + ColorDialog->Color = Color3->Color; + if (!ColorDialog->Execute()) return; + Color3->Color = ColorDialog->Color; } //--------------------------------------------------------------------------- -void __fastcall TPlotOptDialog::BtnColor4Click(TObject *Sender) -{ - ColorDialog->Color=Color4->Color; - if (!ColorDialog->Execute()) return; - Color4->Color=ColorDialog->Color; +void __fastcall TPlotOptDialog::BtnColor4Click(TObject *Sender) { + ColorDialog->Color = Color4->Color; + if (!ColorDialog->Execute()) return; + Color4->Color = ColorDialog->Color; } //--------------------------------------------------------------------------- -void __fastcall TPlotOptDialog::BtnFontClick(TObject *Sender) -{ - FontDialog->Font=FontOpt; - if (!FontDialog->Execute()) return; - FontOpt=FontDialog->Font; - UpdateFont(); +void __fastcall TPlotOptDialog::BtnFontClick(TObject *Sender) { + FontDialog->Font = FontOpt; + if (!FontDialog->Execute()) return; + FontOpt = FontDialog->Font; + UpdateFont(); } //--------------------------------------------------------------------------- -void __fastcall TPlotOptDialog::BtnShapeFileClick(TObject *Sender) -{ - OpenDialog->FileName=ShapeFile->Text; - OpenDialog->FilterIndex=3; - if (!OpenDialog->Execute()) return; - ShapeFile->Text=OpenDialog->FileName; +void __fastcall TPlotOptDialog::BtnShapeFileClick(TObject *Sender) { + OpenDialog->FileName = ShapeFile->Text; + OpenDialog->FilterIndex = 3; + if (!OpenDialog->Execute()) return; + ShapeFile->Text = OpenDialog->FileName; } //--------------------------------------------------------------------------- -void __fastcall TPlotOptDialog::BtnTLEFileClick(TObject *Sender) -{ - OpenDialog->FileName=TLEFile->Text; - OpenDialog->FilterIndex=1; - if (!OpenDialog->Execute()) return; - TLEFile->Text=OpenDialog->FileName; +void __fastcall TPlotOptDialog::BtnTLEFileClick(TObject *Sender) { + OpenDialog->FileName = TLEFile->Text; + OpenDialog->FilterIndex = 1; + if (!OpenDialog->Execute()) return; + TLEFile->Text = OpenDialog->FileName; } //--------------------------------------------------------------------------- -void __fastcall TPlotOptDialog::BtnTLESatFileClick(TObject *Sender) -{ - OpenDialog->FileName=TLESatFile->Text; - OpenDialog->FilterIndex=1; - if (!OpenDialog->Execute()) return; - TLESatFile->Text=OpenDialog->FileName; +void __fastcall TPlotOptDialog::BtnTLESatFileClick(TObject *Sender) { + OpenDialog->FileName = TLESatFile->Text; + OpenDialog->FilterIndex = 1; + if (!OpenDialog->Execute()) return; + TLESatFile->Text = OpenDialog->FileName; } //--------------------------------------------------------------------------- -void __fastcall TPlotOptDialog::BtnRefPosClick(TObject *Sender) -{ - AnsiString s; - RefDialog->RovPos[0]=str2dbl(RefPos1->Text); - RefDialog->RovPos[1]=str2dbl(RefPos2->Text); - RefDialog->RovPos[2]=str2dbl(RefPos3->Text); - RefDialog->Left=Left+Width/2-RefDialog->Width/2; - RefDialog->Top=Top+Height/2-RefDialog->Height/2; - RefDialog->Opt=1; - if (RefDialog->ShowModal()!=mrOk) return; - RefPos1->Text=s.sprintf("%.9f",RefDialog->Pos[0]); - RefPos2->Text=s.sprintf("%.9f",RefDialog->Pos[1]); - RefPos3->Text=s.sprintf("%.4f",RefDialog->Pos[2]); +void __fastcall TPlotOptDialog::BtnRefPosClick(TObject *Sender) { + AnsiString s; + RefDialog->RovPos[0] = str2dbl(RefPos1->Text); + RefDialog->RovPos[1] = str2dbl(RefPos2->Text); + RefDialog->RovPos[2] = str2dbl(RefPos3->Text); + RefDialog->Left = Left + Width / 2 - RefDialog->Width / 2; + RefDialog->Top = Top + Height / 2 - RefDialog->Height / 2; + RefDialog->Opt = 1; + if (RefDialog->ShowModal() != mrOk) return; + RefPos1->Text = s.sprintf("%.9f", RefDialog->Pos[0]); + RefPos2->Text = s.sprintf("%.9f", RefDialog->Pos[1]); + RefPos3->Text = s.sprintf("%.4f", RefDialog->Pos[2]); } //--------------------------------------------------------------------------- -void __fastcall TPlotOptDialog::AutoScaleChange(TObject *Sender) -{ - UpdateEnable(); -} +void __fastcall TPlotOptDialog::AutoScaleChange(TObject *Sender) { UpdateEnable(); } //--------------------------------------------------------------------------- -void __fastcall TPlotOptDialog::OriginChange(TObject *Sender) -{ - UpdateEnable(); -} +void __fastcall TPlotOptDialog::OriginChange(TObject *Sender) { UpdateEnable(); } //--------------------------------------------------------------------------- -void __fastcall TPlotOptDialog::UpdateFont(void) -{ - AnsiString s; - FontLabel->Font->Assign(FontOpt); - FontLabel->Font->Size=LabelFont->Font->Size; - FontLabel->Caption=FontOpt->Name+s.sprintf(" %dpt",FontOpt->Size); +void __fastcall TPlotOptDialog::UpdateFont(void) { + AnsiString s; + FontLabel->Font->Assign(FontOpt); + FontLabel->Font->Size = LabelFont->Font->Size; + FontLabel->Caption = FontOpt->Name + s.sprintf(" %dpt", FontOpt->Size); } //--------------------------------------------------------------------------- -void __fastcall TPlotOptDialog::UpdateEnable(void) -{ - RefPos1 ->Enabled=Origin->ItemIndex==5||RcvPos->ItemIndex==1; - RefPos2 ->Enabled=Origin->ItemIndex==5||RcvPos->ItemIndex==1; - RefPos3 ->Enabled=Origin->ItemIndex==5||RcvPos->ItemIndex==1; - LabelRefPos->Enabled=Origin->ItemIndex==5||Origin->ItemIndex==6||RcvPos->ItemIndex==1; - BtnRefPos ->Enabled=Origin->ItemIndex==5||Origin->ItemIndex==6||RcvPos->ItemIndex==1; - EditTimeSync->Enabled=ChkTimeSync->Checked; +void __fastcall TPlotOptDialog::UpdateEnable(void) { + RefPos1->Enabled = Origin->ItemIndex == 5 || RcvPos->ItemIndex == 1; + RefPos2->Enabled = Origin->ItemIndex == 5 || RcvPos->ItemIndex == 1; + RefPos3->Enabled = Origin->ItemIndex == 5 || RcvPos->ItemIndex == 1; + LabelRefPos->Enabled = Origin->ItemIndex == 5 || Origin->ItemIndex == 6 || RcvPos->ItemIndex == 1; + BtnRefPos->Enabled = Origin->ItemIndex == 5 || Origin->ItemIndex == 6 || RcvPos->ItemIndex == 1; + EditTimeSync->Enabled = ChkTimeSync->Checked; } //--------------------------------------------------------------------------- -void __fastcall TPlotOptDialog::RcvPosChange(TObject *Sender) -{ - UpdateEnable(); -} +void __fastcall TPlotOptDialog::RcvPosChange(TObject *Sender) { UpdateEnable(); } //--------------------------------------------------------------------------- -void __fastcall TPlotOptDialog::BtnTLEViewClick(TObject *Sender) -{ - TTextViewer *viewer; - AnsiString file=TLEFile->Text; - - if (file=="") return; - viewer=new TTextViewer(Application); - viewer->Caption=file; - viewer->Show(); - viewer->Read(file); +void __fastcall TPlotOptDialog::BtnTLEViewClick(TObject *Sender) { + TTextViewer *viewer; + AnsiString file = TLEFile->Text; + + if (file == "") return; + viewer = new TTextViewer(Application); + viewer->Caption = file; + viewer->Show(); + viewer->Read(file); } //--------------------------------------------------------------------------- -void __fastcall TPlotOptDialog::BtnTLESatViewClick(TObject *Sender) -{ - TTextViewer *viewer; - AnsiString file=TLESatFile->Text; - - if (file=="") return; - viewer=new TTextViewer(Application); - viewer->Caption=file; - viewer->Show(); - viewer->Read(file); +void __fastcall TPlotOptDialog::BtnTLESatViewClick(TObject *Sender) { + TTextViewer *viewer; + AnsiString file = TLESatFile->Text; + + if (file == "") return; + viewer = new TTextViewer(Application); + viewer->Caption = file; + viewer->Show(); + viewer->Read(file); } //--------------------------------------------------------------------------- -void __fastcall TPlotOptDialog::ChkTimeSyncClick(TObject *Sender) -{ - UpdateEnable(); -} +void __fastcall TPlotOptDialog::ChkTimeSyncClick(TObject *Sender) { UpdateEnable(); } //--------------------------------------------------------------------------- - - diff --git a/app/winapp/rtkplot/plotopt.h b/app/winapp/rtkplot/plotopt.h index a990efd36..4aa2e56a6 100644 --- a/app/winapp/rtkplot/plotopt.h +++ b/app/winapp/rtkplot/plotopt.h @@ -4,163 +4,164 @@ #define plotoptH //--------------------------------------------------------------------------- #include +#include #include -#include -#include #include #include -#include -#include "plotmain.h" +#include +#include #include + +#include "plotmain.h" //--------------------------------------------------------------------------- -class TPlotOptDialog : public TForm -{ -__published: - TButton *BtnCancel; - TButton *BtnOK; - TComboBox *PlotStyle; - TComboBox *Origin; - TLabel *Label1; - TLabel *Label2; - TLabel *Label3; - TLabel *Label4; - TComboBox *ShowArrow; - TPanel *Panel2; - TColorDialog *ColorDialog; - TPanel *Color1; - TButton *BtnColor1; - TLabel *Label5; - TPanel *Color2; - TButton *BtnColor2; - TLabel *Label6; - TPanel *Color3; - TButton *BtnColor3; - TLabel *Label7; - TPanel *Color4; - TButton *BtnColor4; - TLabel *Label9; - TComboBox *ShowStats; - TLabel *Label8; - TLabel *Label10; - TLabel *Label12; - TComboBox *TimeLabel; - TLabel *Label13; - TComboBox *AutoScale; - TPanel *MColor1; - TLabel *Label14; - TPanel *MColor2; - TPanel *MColor3; - TPanel *MColor4; - TPanel *MColor5; - TButton *BtnFont; - TFontDialog *FontDialog; - TLabel *Msg; - TLabel *Label17; - TComboBox *ShowSlip; - TLabel *Label18; - TLabel *Label19; - TComboBox *ShowErr; - TComboBox *MarkSize; - TLabel *Label16; - TComboBox *ShowHalfC; - TComboBox *YRange; - TLabel *Label20; - TComboBox *ShowLabel; - TLabel *Label21; - TComboBox *ShowGLabel; - TLabel *Label22; - TComboBox *ShowScale; - TLabel *Label23; - TComboBox *ShowCompass; - TLabel *Label24; - TComboBox *ShowEph; - TGroupBox *GroupBox1; - TCheckBox *NavSys1; - TCheckBox *NavSys2; - TCheckBox *NavSys5; - TCheckBox *NavSys3; - TCheckBox *NavSys4; - TComboBox *ElMask; - TLabel *Label11; - TComboBox *AnimCycle; - TLabel *Label25; - TComboBox *HideLowSat; - TPanel *Panel1; - TLabel *FontLabel; - TLabel *LabelFont; - TLabel *Label26; - TComboBox *ElMaskP; - TLabel *LabelRefPos; - TEdit *RefPos1; - TEdit *RefPos2; - TEdit *RefPos3; - TButton *BtnRefPos; - TLabel *LabelExSats; - TEdit *ExSats; - TLabel *Label28; - TComboBox *MaxDop; - TEdit *BuffSize; - TLabel *Label29; - TOpenDialog *OpenDialog; - TLabel *Label27; - TEdit *RefCycle; - TPanel *MColor6; - TCheckBox *NavSys6; - TEdit *ShapeFile; - TLabel *Label30; - TLabel *Label31; - TComboBox *RcvPos; - TLabel *Label32; - TPanel *MColor7; - TPanel *MColor8; - TPanel *MColor9; - TPanel *MColor10; - TPanel *MColor11; - TPanel *MColor12; - TLabel *Label15; - TComboBox *LatLonFmt; - TLabel *Label33; - TEdit *RnxOpts; - TLabel *Label34; - TEdit *TLEFile; - TButton *BtnTLEFile; - TLabel *Label35; - TEdit *TLESatFile; - TButton *BtnTLESatFile; - TLabel *Label36; - TSpeedButton *BtnTLEView; - TSpeedButton *BtnTLESatView; - TLabel *Label37; - TComboBox *MaxMP; - TCheckBox *NavSys7; - TEdit *EditTimeSync; - TCheckBox *ChkTimeSync; - TButton *BtnShapeFile; - void __fastcall BtnOKClick(TObject *Sender); - void __fastcall FormShow(TObject *Sender); - void __fastcall BtnColor1Click(TObject *Sender); - void __fastcall BtnColor2Click(TObject *Sender); - void __fastcall BtnColor3Click(TObject *Sender); - void __fastcall BtnColor4Click(TObject *Sender); - void __fastcall BtnRefPosClick(TObject *Sender); - void __fastcall OriginChange(TObject *Sender); - void __fastcall AutoScaleChange(TObject *Sender); - void __fastcall MColorClick(TObject *Sender); - void __fastcall BtnFontClick(TObject *Sender); - void __fastcall RcvPosChange(TObject *Sender); - void __fastcall BtnTLEFileClick(TObject *Sender); - void __fastcall BtnTLESatFileClick(TObject *Sender); - void __fastcall BtnTLEViewClick(TObject *Sender); - void __fastcall BtnTLESatViewClick(TObject *Sender); - void __fastcall ChkTimeSyncClick(TObject *Sender); - void __fastcall BtnShapeFileClick(TObject *Sender); -private: - TFont *FontOpt; - void __fastcall UpdateFont(void); - void __fastcall UpdateEnable(void); -public: - TPlot *Plot; - __fastcall TPlotOptDialog(TComponent* Owner); +class TPlotOptDialog : public TForm { + __published : TButton *BtnCancel; + TButton *BtnOK; + TComboBox *PlotStyle; + TComboBox *Origin; + TLabel *Label1; + TLabel *Label2; + TLabel *Label3; + TLabel *Label4; + TComboBox *ShowArrow; + TPanel *Panel2; + TColorDialog *ColorDialog; + TPanel *Color1; + TButton *BtnColor1; + TLabel *Label5; + TPanel *Color2; + TButton *BtnColor2; + TLabel *Label6; + TPanel *Color3; + TButton *BtnColor3; + TLabel *Label7; + TPanel *Color4; + TButton *BtnColor4; + TLabel *Label9; + TComboBox *ShowStats; + TLabel *Label8; + TLabel *Label10; + TLabel *Label12; + TComboBox *TimeLabel; + TLabel *Label13; + TComboBox *AutoScale; + TPanel *MColor1; + TLabel *Label14; + TPanel *MColor2; + TPanel *MColor3; + TPanel *MColor4; + TPanel *MColor5; + TButton *BtnFont; + TFontDialog *FontDialog; + TLabel *Msg; + TLabel *Label17; + TComboBox *ShowSlip; + TLabel *Label18; + TLabel *Label19; + TComboBox *ShowErr; + TComboBox *MarkSize; + TLabel *Label16; + TComboBox *ShowHalfC; + TComboBox *YRange; + TLabel *Label20; + TComboBox *ShowLabel; + TLabel *Label21; + TComboBox *ShowGLabel; + TLabel *Label22; + TComboBox *ShowScale; + TLabel *Label23; + TComboBox *ShowCompass; + TLabel *Label24; + TComboBox *ShowEph; + TGroupBox *GroupBox1; + TCheckBox *NavSys1; + TCheckBox *NavSys2; + TCheckBox *NavSys5; + TCheckBox *NavSys3; + TCheckBox *NavSys4; + TComboBox *ElMask; + TLabel *Label11; + TComboBox *AnimCycle; + TLabel *Label25; + TComboBox *HideLowSat; + TPanel *Panel1; + TLabel *FontLabel; + TLabel *LabelFont; + TLabel *Label26; + TComboBox *ElMaskP; + TLabel *LabelRefPos; + TEdit *RefPos1; + TEdit *RefPos2; + TEdit *RefPos3; + TButton *BtnRefPos; + TLabel *LabelExSats; + TEdit *ExSats; + TLabel *Label28; + TComboBox *MaxDop; + TEdit *BuffSize; + TLabel *Label29; + TOpenDialog *OpenDialog; + TLabel *Label27; + TEdit *RefCycle; + TPanel *MColor6; + TCheckBox *NavSys6; + TEdit *ShapeFile; + TLabel *Label30; + TLabel *Label31; + TComboBox *RcvPos; + TLabel *Label32; + TPanel *MColor7; + TPanel *MColor8; + TPanel *MColor9; + TPanel *MColor10; + TPanel *MColor11; + TPanel *MColor12; + TLabel *Label15; + TComboBox *LatLonFmt; + TLabel *Label33; + TEdit *RnxOpts; + TLabel *Label34; + TEdit *TLEFile; + TButton *BtnTLEFile; + TLabel *Label35; + TEdit *TLESatFile; + TButton *BtnTLESatFile; + TLabel *Label36; + TSpeedButton *BtnTLEView; + TSpeedButton *BtnTLESatView; + TLabel *Label37; + TComboBox *MaxMP; + TCheckBox *NavSys7; + TEdit *EditTimeSync; + TCheckBox *ChkTimeSync; + TButton *BtnShapeFile; + void __fastcall BtnOKClick(TObject *Sender); + void __fastcall FormShow(TObject *Sender); + void __fastcall BtnColor1Click(TObject *Sender); + void __fastcall BtnColor2Click(TObject *Sender); + void __fastcall BtnColor3Click(TObject *Sender); + void __fastcall BtnColor4Click(TObject *Sender); + void __fastcall BtnRefPosClick(TObject *Sender); + void __fastcall OriginChange(TObject *Sender); + void __fastcall AutoScaleChange(TObject *Sender); + void __fastcall MColorClick(TObject *Sender); + void __fastcall BtnFontClick(TObject *Sender); + void __fastcall RcvPosChange(TObject *Sender); + void __fastcall BtnTLEFileClick(TObject *Sender); + void __fastcall BtnTLESatFileClick(TObject *Sender); + void __fastcall BtnTLEViewClick(TObject *Sender); + void __fastcall BtnTLESatViewClick(TObject *Sender); + void __fastcall ChkTimeSyncClick(TObject *Sender); + void __fastcall BtnShapeFileClick(TObject *Sender); + + private: + TFont *FontOpt; + void __fastcall UpdateFont(void); + void __fastcall UpdateEnable(void); + + public: + TPlot *Plot; + __fastcall TPlotOptDialog(TComponent *Owner); }; //--------------------------------------------------------------------------- extern PACKAGE TPlotOptDialog *PlotOptDialog; diff --git a/app/winapp/rtkplot/pntdlg.cpp b/app/winapp/rtkplot/pntdlg.cpp index 85a96b057..d3ec344b4 100644 --- a/app/winapp/rtkplot/pntdlg.cpp +++ b/app/winapp/rtkplot/pntdlg.cpp @@ -2,132 +2,117 @@ #include #pragma hdrstop -#include "rtklib.h" -#include "refdlg.h" #include "pntdlg.h" + #include "plotmain.h" +#include "refdlg.h" +#include "rtklib.h" -#define PNTLIST_WIDTH 372 +#define PNTLIST_WIDTH 372 //--------------------------------------------------------------------------- #pragma package(smart_init) #pragma resource "*.dfm" TPntDialog *PntDialog; //--------------------------------------------------------------------------- -static double str2dbl(AnsiString str) -{ - double val=0.0; - sscanf(str.c_str(),"%lf",&val); - return val; +static double str2dbl(AnsiString str) { + double val = 0.0; + sscanf(str.c_str(), "%lf", &val); + return val; } //--------------------------------------------------------------------------- -__fastcall TPntDialog::TPntDialog(TComponent* Owner) - : TForm(Owner) -{ - PntList->RowCount=MAXWAYPNT; +__fastcall TPntDialog::TPntDialog(TComponent *Owner) : TForm(Owner) { + PntList->RowCount = MAXWAYPNT; } //--------------------------------------------------------------------------- -void __fastcall TPntDialog::FormShow(TObject *Sender) -{ - double scale; - int width[]={90,90,80,90}; - - scale=(double)PntList->Width/PNTLIST_WIDTH; - - for (int i=0;i<4;i++) { - PntList->ColWidths[i]=(int)(width[i]*scale); - } - SetPoint(); +void __fastcall TPntDialog::FormShow(TObject *Sender) { + double scale; + int width[] = {90, 90, 80, 90}; + + scale = (double)PntList->Width / PNTLIST_WIDTH; + + for (int i = 0; i < 4; i++) { + PntList->ColWidths[i] = (int)(width[i] * scale); + } + SetPoint(); } //--------------------------------------------------------------------------- -void __fastcall TPntDialog::BtnAddClick(TObject *Sender) -{ - TGridRect r={0}; - AnsiString s; - int i; - double rr[3],pos[3]={0}; - for (i=0;iRowCount;i++) { - if (PntList->Cells[2][i]=="") break; - } - if (i>=PntList->RowCount) return; - if (!Plot->GetCenterPos(rr)) return; - if (norm(rr,3)<=0.0) return; - ecef2pos(rr,pos); - PntList->Cells[0][i]=s.sprintf("%.9f",pos[0]*R2D); - PntList->Cells[1][i]=s.sprintf("%.9f",pos[1]*R2D); - PntList->Cells[2][i]=s.sprintf("%.4f",pos[2]); - PntList->Cells[3][i]=s.sprintf("Point%02d",i+1); - UpdatePoint(); +void __fastcall TPntDialog::BtnAddClick(TObject *Sender) { + TGridRect r = {0}; + AnsiString s; + int i; + double rr[3], pos[3] = {0}; + for (i = 0; i < PntList->RowCount; i++) { + if (PntList->Cells[2][i] == "") break; + } + if (i >= PntList->RowCount) return; + if (!Plot->GetCenterPos(rr)) return; + if (norm(rr, 3) <= 0.0) return; + ecef2pos(rr, pos); + PntList->Cells[0][i] = s.sprintf("%.9f", pos[0] * R2D); + PntList->Cells[1][i] = s.sprintf("%.9f", pos[1] * R2D); + PntList->Cells[2][i] = s.sprintf("%.4f", pos[2]); + PntList->Cells[3][i] = s.sprintf("Point%02d", i + 1); + UpdatePoint(); } //--------------------------------------------------------------------------- -void __fastcall TPntDialog::BtnDelClick(TObject *Sender) -{ - int sel=PntList->Selection.Top; - - for (int i=sel;iRowCount;i++) { - for (int j=0;jColCount;j++) { - if (i+1>=PntList->RowCount) PntList->Cells[j][i]=""; - else PntList->Cells[j][i]=PntList->Cells[j][i+1]; - } - } - UpdatePoint(); +void __fastcall TPntDialog::BtnDelClick(TObject *Sender) { + int sel = PntList->Selection.Top; + + for (int i = sel; i < PntList->RowCount; i++) { + for (int j = 0; j < PntList->ColCount; j++) { + if (i + 1 >= PntList->RowCount) + PntList->Cells[j][i] = ""; + else + PntList->Cells[j][i] = PntList->Cells[j][i + 1]; + } + } + UpdatePoint(); } //--------------------------------------------------------------------------- -void __fastcall TPntDialog::BtnUpdateClick(TObject *Sender) -{ - UpdatePoint(); -} +void __fastcall TPntDialog::BtnUpdateClick(TObject *Sender) { UpdatePoint(); } //--------------------------------------------------------------------------- void __fastcall TPntDialog::PntListSetEditText(TObject *Sender, int ACol, int ARow, - const UnicodeString Value) -{ - UpdatePoint(); + const UnicodeString Value) { + UpdatePoint(); } //--------------------------------------------------------------------------- -void __fastcall TPntDialog::BtnCloseClick(TObject *Sender) -{ - Close(); -} +void __fastcall TPntDialog::BtnCloseClick(TObject *Sender) { Close(); } //--------------------------------------------------------------------------- -void __fastcall TPntDialog::UpdatePoint(void) -{ - int n=0; - - for (int i=0;iRowCount;i++) { - if (PntList->Cells[2][i]=="") continue; - Plot->PntPos[n][0]=str2dbl(PntList->Cells[0][i]); - Plot->PntPos[n][1]=str2dbl(PntList->Cells[1][i]); - Plot->PntPos[n][2]=str2dbl(PntList->Cells[2][i]); - Plot->PntName[n++]=PntList->Cells[3][i]; - } - Plot->NWayPnt=n; - Plot->UpdatePlot(); +void __fastcall TPntDialog::UpdatePoint(void) { + int n = 0; + + for (int i = 0; i < PntList->RowCount; i++) { + if (PntList->Cells[2][i] == "") continue; + Plot->PntPos[n][0] = str2dbl(PntList->Cells[0][i]); + Plot->PntPos[n][1] = str2dbl(PntList->Cells[1][i]); + Plot->PntPos[n][2] = str2dbl(PntList->Cells[2][i]); + Plot->PntName[n++] = PntList->Cells[3][i]; + } + Plot->NWayPnt = n; + Plot->UpdatePlot(); } //--------------------------------------------------------------------------- -void __fastcall TPntDialog::SetPoint(void) -{ - AnsiString s; - - for (int i=0;iNWayPnt;i++) { - PntList->Cells[0][i]=s.sprintf("%.9f",Plot->PntPos[i][0]); - PntList->Cells[1][i]=s.sprintf("%.9f",Plot->PntPos[i][1]); - PntList->Cells[2][i]=s.sprintf("%.4f",Plot->PntPos[i][2]); - PntList->Cells[3][i]=Plot->PntName[i]; - } +void __fastcall TPntDialog::SetPoint(void) { + AnsiString s; + + for (int i = 0; i < Plot->NWayPnt; i++) { + PntList->Cells[0][i] = s.sprintf("%.9f", Plot->PntPos[i][0]); + PntList->Cells[1][i] = s.sprintf("%.9f", Plot->PntPos[i][1]); + PntList->Cells[2][i] = s.sprintf("%.4f", Plot->PntPos[i][2]); + PntList->Cells[3][i] = Plot->PntName[i]; + } } //--------------------------------------------------------------------------- -void __fastcall TPntDialog::PntListClick(TObject *Sender) -{ - int sel=PntList->Selection.Top; - Plot->SelWayPnt=selNWayPnt?sel:-1; - Plot->UpdatePlot(); +void __fastcall TPntDialog::PntListClick(TObject *Sender) { + int sel = PntList->Selection.Top; + Plot->SelWayPnt = sel < Plot->NWayPnt ? sel : -1; + Plot->UpdatePlot(); } //--------------------------------------------------------------------------- -void __fastcall TPntDialog::PntListDblClick(TObject *Sender) -{ - int sel=PntList->Selection.Top; - if (sel>=Plot->NWayPnt) return; - Plot->SetTrkCent(Plot->PntPos[sel][0],Plot->PntPos[sel][1]); +void __fastcall TPntDialog::PntListDblClick(TObject *Sender) { + int sel = PntList->Selection.Top; + if (sel >= Plot->NWayPnt) return; + Plot->SetTrkCent(Plot->PntPos[sel][0], Plot->PntPos[sel][1]); } //--------------------------------------------------------------------------- - diff --git a/app/winapp/rtkplot/pntdlg.h b/app/winapp/rtkplot/pntdlg.h index b17518ad9..581d16a41 100644 --- a/app/winapp/rtkplot/pntdlg.h +++ b/app/winapp/rtkplot/pntdlg.h @@ -4,44 +4,43 @@ //--------------------------------------------------------------------------- #include #include -#include -#include +#include #include +#include #include -#include +#include //--------------------------------------------------------------------------- -class TPntDialog : public TForm -{ -__published: - TPanel *Panel1; - TLabel *Label2; - TLabel *Label1; - TLabel *Label3; - TButton *BtnDel; - TPanel *Panel2; - TStringGrid *PntList; - TButton *BtnClose; - TButton *BtnAdd; - TOpenDialog *OpenDialog; - TSaveDialog *SaveDialog; - TPanel *Panel3; - TLabel *Label4; - void __fastcall FormShow(TObject *Sender); - void __fastcall BtnDelClick(TObject *Sender); - void __fastcall BtnAddClick(TObject *Sender); - void __fastcall BtnCloseClick(TObject *Sender); - void __fastcall BtnUpdateClick(TObject *Sender); - void __fastcall PntListSetEditText(TObject *Sender, int ACol, int ARow, const UnicodeString Value); - void __fastcall PntListClick(TObject *Sender); - void __fastcall PntListDblClick(TObject *Sender); +class TPntDialog : public TForm { + __published : TPanel *Panel1; + TLabel *Label2; + TLabel *Label1; + TLabel *Label3; + TButton *BtnDel; + TPanel *Panel2; + TStringGrid *PntList; + TButton *BtnClose; + TButton *BtnAdd; + TOpenDialog *OpenDialog; + TSaveDialog *SaveDialog; + TPanel *Panel3; + TLabel *Label4; + void __fastcall FormShow(TObject *Sender); + void __fastcall BtnDelClick(TObject *Sender); + void __fastcall BtnAddClick(TObject *Sender); + void __fastcall BtnCloseClick(TObject *Sender); + void __fastcall BtnUpdateClick(TObject *Sender); + void __fastcall PntListSetEditText(TObject *Sender, int ACol, int ARow, + const UnicodeString Value); + void __fastcall PntListClick(TObject *Sender); + void __fastcall PntListDblClick(TObject *Sender); + private: + void __fastcall UpdatePoint(void); -private: - void __fastcall UpdatePoint(void); -public: - int FontScale; - __fastcall TPntDialog(TComponent* Owner); - void __fastcall SetPoint(void); + public: + int FontScale; + __fastcall TPntDialog(TComponent *Owner); + void __fastcall SetPoint(void); }; //--------------------------------------------------------------------------- extern PACKAGE TPntDialog *PntDialog; diff --git a/app/winapp/rtkplot/rtkplot.cpp b/app/winapp/rtkplot/rtkplot.cpp index 663b0bd78..87f8a62f3 100644 --- a/app/winapp/rtkplot/rtkplot.cpp +++ b/app/winapp/rtkplot/rtkplot.cpp @@ -4,44 +4,6 @@ #pragma hdrstop //--------------------------------------------------------------------------- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - USEFORM("vmapdlg.cpp", VecMapDialog); USEFORM("skydlg.cpp", SkyImgDialog); USEFORM("..\appcmn\refdlg.cpp", RefDialog); @@ -68,55 +30,45 @@ USEFORM("mapoptdlg.cpp", MapOptDialog); USEFORM("mapviewopt.cpp", MapViewOptDialog); USEFORM("mapview.cpp", MapView); //--------------------------------------------------------------------------- -int WINAPI WinMain(HINSTANCE, HINSTANCE, LPSTR, int) -{ - try - { - Application->Initialize(); - Application->Title = "RTKPLOT"; - Application->CreateForm(__classid(TPlot), &Plot); - Application->CreateForm(__classid(TPlotOptDialog), &PlotOptDialog); - Application->CreateForm(__classid(TRefDialog), &RefDialog); - Application->CreateForm(__classid(TAboutDialog), &AboutDialog); - Application->CreateForm(__classid(TSpanDialog), &SpanDialog); - Application->CreateForm(__classid(TTimeDialog), &TimeDialog); - Application->CreateForm(__classid(TConnectDialog), &ConnectDialog); - Application->CreateForm(__classid(TSerialOptDialog), &SerialOptDialog); - Application->CreateForm(__classid(TTcpOptDialog), &TcpOptDialog); - Application->CreateForm(__classid(TCmdOptDialog), &CmdOptDialog); - Application->CreateForm(__classid(TFileOptDialog), &FileOptDialog); - Application->CreateForm(__classid(TKeyDialog), &KeyDialog); - Application->CreateForm(__classid(TTextViewer), &TextViewer); - Application->CreateForm(__classid(TViewerOptDialog), &ViewerOptDialog); - Application->CreateForm(__classid(TPntDialog), &PntDialog); - Application->CreateForm(__classid(TConfDialog), &ConfDialog); - Application->CreateForm(__classid(TFtpOptDialog), &FtpOptDialog); - Application->CreateForm(__classid(TConsole), &Console); - Application->CreateForm(__classid(TMapOptDialog), &MapOptDialog); - Application->CreateForm(__classid(TSkyImgDialog), &SkyImgDialog); - Application->CreateForm(__classid(TVecMapDialog), &VecMapDialog); - Application->CreateForm(__classid(TMntpOptDialog), &MntpOptDialog); - Application->CreateForm(__classid(TFreqDialog), &FreqDialog); - Application->CreateForm(__classid(TMapViewOptDialog), &MapViewOptDialog); - Application->CreateForm(__classid(TMapView), &MapView); - Application->Run(); - } - catch (Exception &exception) - { - Application->ShowException(&exception); - } - catch (...) - { - try - { - throw Exception(""); - } - catch (Exception &exception) - { - Application->ShowException(&exception); - } - } - return 0; +int WINAPI WinMain(HINSTANCE, HINSTANCE, LPSTR, int) { + try { + Application->Initialize(); + Application->Title = "RTKPLOT"; + Application->CreateForm(__classid(TPlot), &Plot); + Application->CreateForm(__classid(TPlotOptDialog), &PlotOptDialog); + Application->CreateForm(__classid(TRefDialog), &RefDialog); + Application->CreateForm(__classid(TAboutDialog), &AboutDialog); + Application->CreateForm(__classid(TSpanDialog), &SpanDialog); + Application->CreateForm(__classid(TTimeDialog), &TimeDialog); + Application->CreateForm(__classid(TConnectDialog), &ConnectDialog); + Application->CreateForm(__classid(TSerialOptDialog), &SerialOptDialog); + Application->CreateForm(__classid(TTcpOptDialog), &TcpOptDialog); + Application->CreateForm(__classid(TCmdOptDialog), &CmdOptDialog); + Application->CreateForm(__classid(TFileOptDialog), &FileOptDialog); + Application->CreateForm(__classid(TKeyDialog), &KeyDialog); + Application->CreateForm(__classid(TTextViewer), &TextViewer); + Application->CreateForm(__classid(TViewerOptDialog), &ViewerOptDialog); + Application->CreateForm(__classid(TPntDialog), &PntDialog); + Application->CreateForm(__classid(TConfDialog), &ConfDialog); + Application->CreateForm(__classid(TFtpOptDialog), &FtpOptDialog); + Application->CreateForm(__classid(TConsole), &Console); + Application->CreateForm(__classid(TMapOptDialog), &MapOptDialog); + Application->CreateForm(__classid(TSkyImgDialog), &SkyImgDialog); + Application->CreateForm(__classid(TVecMapDialog), &VecMapDialog); + Application->CreateForm(__classid(TMntpOptDialog), &MntpOptDialog); + Application->CreateForm(__classid(TFreqDialog), &FreqDialog); + Application->CreateForm(__classid(TMapViewOptDialog), &MapViewOptDialog); + Application->CreateForm(__classid(TMapView), &MapView); + Application->Run(); + } catch (Exception &exception) { + Application->ShowException(&exception); + } catch (...) { + try { + throw Exception(""); + } catch (Exception &exception) { + Application->ShowException(&exception); + } + } + return 0; } //--------------------------------------------------------------------------- - diff --git a/app/winapp/rtkplot/skydlg.cpp b/app/winapp/rtkplot/skydlg.cpp index 2618c2fee..2a8c26d57 100644 --- a/app/winapp/rtkplot/skydlg.cpp +++ b/app/winapp/rtkplot/skydlg.cpp @@ -1,321 +1,332 @@ //--------------------------------------------------------------------------- -#include #include +#include + #include "rtklib.h" #pragma hdrstop -#include "plotmain.h" #include "skydlg.h" + #include "confdlg.h" +#include "plotmain.h" //--------------------------------------------------------------------------- #pragma package(smart_init) #pragma resource "*.dfm" TSkyImgDialog *SkyImgDialog; //--------------------------------------------------------------------------- -static double str2dbl(AnsiString str) -{ - double val=0.0; - sscanf(str.c_str(),"%lf",&val); - return val; +static double str2dbl(AnsiString str) { + double val = 0.0; + sscanf(str.c_str(), "%lf", &val); + return val; } //--------------------------------------------------------------------------- -__fastcall TSkyImgDialog::TSkyImgDialog(TComponent* Owner) - : TForm(Owner) -{ -} +__fastcall TSkyImgDialog::TSkyImgDialog(TComponent *Owner) : TForm(Owner) {} //--------------------------------------------------------------------------- -void __fastcall TSkyImgDialog::FormShow(TObject *Sender) -{ - UpdateField(); - UpdateEnable(); +void __fastcall TSkyImgDialog::FormShow(TObject *Sender) { + UpdateField(); + UpdateEnable(); } //--------------------------------------------------------------------------- -void __fastcall TSkyImgDialog::BtnSaveClick(TObject *Sender) -{ - FILE *fp; - AnsiString file=Plot->SkyImageFile; - if (file=="") return; - UpdateSky(); - file=file+".tag"; - if ((fp=fopen(file.c_str(),"r"))) { - fclose(fp); - ConfDialog->Label1->Caption="File exists. Overwrite it?"; - ConfDialog->Label2->Caption=file; - if (ConfDialog->ShowModal()!=mrOk) return; - } - if (!(fp=fopen(file.c_str(),"w"))) return; - fprintf(fp,"%% sky image tag file: rtkplot-%s %s\n\n",VER_RTKLIB,PATCH_LEVEL); - fprintf(fp,"centx = %.6g\n",Plot->SkyCent[0]); - fprintf(fp,"centy = %.6g\n",Plot->SkyCent[1]); - fprintf(fp,"scale = %.6g\n",Plot->SkyScale ); - fprintf(fp,"roll = %.6g\n",Plot->SkyFov[0] ); - fprintf(fp,"pitch = %.6g\n",Plot->SkyFov[1] ); - fprintf(fp,"yaw = %.6g\n",Plot->SkyFov[2] ); - fprintf(fp,"destcorr= %d\n" ,Plot->SkyDestCorr); - fprintf(fp,"resample= %d\n" ,Plot->SkyRes ); - fprintf(fp,"flip = %d\n" ,Plot->SkyFlip ); - fprintf(fp,"dest = %.6g %.6g %.6g %.6g %.6g %.6g %.6g %.6g %.6g\n", - Plot->SkyDest[1],Plot->SkyDest[2],Plot->SkyDest[3],Plot->SkyDest[4], - Plot->SkyDest[5],Plot->SkyDest[6],Plot->SkyDest[7],Plot->SkyDest[8], - Plot->SkyDest[9]); - fprintf(fp,"elmask = %d\n" ,Plot->SkyElMask ); - fprintf(fp,"binarize= %d\n" ,Plot->SkyBinarize); - fprintf(fp,"binthr1 = %.2f\n",Plot->SkyBinThres1); - fprintf(fp,"binthr2 = %.2f\n",Plot->SkyBinThres2); - fclose(fp); +void __fastcall TSkyImgDialog::BtnSaveClick(TObject *Sender) { + FILE *fp; + AnsiString file = Plot->SkyImageFile; + if (file == "") return; + UpdateSky(); + file = file + ".tag"; + if ((fp = fopen(file.c_str(), "r"))) { + fclose(fp); + ConfDialog->Label1->Caption = "File exists. Overwrite it?"; + ConfDialog->Label2->Caption = file; + if (ConfDialog->ShowModal() != mrOk) return; + } + if (!(fp = fopen(file.c_str(), "w"))) return; + fprintf(fp, "%% sky image tag file: rtkplot-%s %s\n\n", VER_RTKLIB, PATCH_LEVEL); + fprintf(fp, "centx = %.6g\n", Plot->SkyCent[0]); + fprintf(fp, "centy = %.6g\n", Plot->SkyCent[1]); + fprintf(fp, "scale = %.6g\n", Plot->SkyScale); + fprintf(fp, "roll = %.6g\n", Plot->SkyFov[0]); + fprintf(fp, "pitch = %.6g\n", Plot->SkyFov[1]); + fprintf(fp, "yaw = %.6g\n", Plot->SkyFov[2]); + fprintf(fp, "destcorr= %d\n", Plot->SkyDestCorr); + fprintf(fp, "resample= %d\n", Plot->SkyRes); + fprintf(fp, "flip = %d\n", Plot->SkyFlip); + fprintf(fp, "dest = %.6g %.6g %.6g %.6g %.6g %.6g %.6g %.6g %.6g\n", Plot->SkyDest[1], + Plot->SkyDest[2], Plot->SkyDest[3], Plot->SkyDest[4], Plot->SkyDest[5], Plot->SkyDest[6], + Plot->SkyDest[7], Plot->SkyDest[8], Plot->SkyDest[9]); + fprintf(fp, "elmask = %d\n", Plot->SkyElMask); + fprintf(fp, "binarize= %d\n", Plot->SkyBinarize); + fprintf(fp, "binthr1 = %.2f\n", Plot->SkyBinThres1); + fprintf(fp, "binthr2 = %.2f\n", Plot->SkyBinThres2); + fclose(fp); } //--------------------------------------------------------------------------- -void __fastcall TSkyImgDialog::BtnUpdateClick(TObject *Sender) -{ - UpdateSky(); -} +void __fastcall TSkyImgDialog::BtnUpdateClick(TObject *Sender) { UpdateSky(); } //--------------------------------------------------------------------------- -void __fastcall TSkyImgDialog::BtnCloseClick(TObject *Sender) -{ - Close(); -} +void __fastcall TSkyImgDialog::BtnCloseClick(TObject *Sender) { Close(); } //--------------------------------------------------------------------------- -void __fastcall TSkyImgDialog::UpdateField(void) -{ - AnsiString s; - Caption=Plot->SkyImageFile; - SkySize1->Text=s.sprintf("%d",Plot->SkySize[0]); - SkySize2->Text=s.sprintf("%d",Plot->SkySize[1]); - SkyCent1->Text=s.sprintf("%.2f",Plot->SkyCent[0]); - SkyCent2->Text=s.sprintf("%.2f",Plot->SkyCent[1]); - SkyScale->Text=s.sprintf("%.2f",Plot->SkyScale); - SkyFov1 ->Text=s.sprintf("%.2f",Plot->SkyFov[0]); - SkyFov2 ->Text=s.sprintf("%.2f",Plot->SkyFov[1]); - SkyFov3 ->Text=s.sprintf("%.2f",Plot->SkyFov[2]); - SkyDest1->Text=s.sprintf("%.1f",Plot->SkyDest[1]); - SkyDest2->Text=s.sprintf("%.1f",Plot->SkyDest[2]); - SkyDest3->Text=s.sprintf("%.1f",Plot->SkyDest[3]); - SkyDest4->Text=s.sprintf("%.1f",Plot->SkyDest[4]); - SkyDest5->Text=s.sprintf("%.1f",Plot->SkyDest[5]); - SkyDest6->Text=s.sprintf("%.1f",Plot->SkyDest[6]); - SkyDest7->Text=s.sprintf("%.1f",Plot->SkyDest[7]); - SkyDest8->Text=s.sprintf("%.1f",Plot->SkyDest[8]); - SkyDest9->Text=s.sprintf("%.1f",Plot->SkyDest[9]); - SkyElMask->Checked=Plot->SkyElMask; - SkyDestCorr->Checked=Plot->SkyDestCorr; - SkyRes->ItemIndex=Plot->SkyRes; - SkyFlip->Checked=Plot->SkyFlip; - SkyBinarize->Checked=Plot->SkyBinarize; - SkyBinThres1->Text=s.sprintf("%.2f",Plot->SkyBinThres1); - SkyBinThres2->Text=s.sprintf("%.2f",Plot->SkyBinThres2); +void __fastcall TSkyImgDialog::UpdateField(void) { + AnsiString s; + Caption = Plot->SkyImageFile; + SkySize1->Text = s.sprintf("%d", Plot->SkySize[0]); + SkySize2->Text = s.sprintf("%d", Plot->SkySize[1]); + SkyCent1->Text = s.sprintf("%.2f", Plot->SkyCent[0]); + SkyCent2->Text = s.sprintf("%.2f", Plot->SkyCent[1]); + SkyScale->Text = s.sprintf("%.2f", Plot->SkyScale); + SkyFov1->Text = s.sprintf("%.2f", Plot->SkyFov[0]); + SkyFov2->Text = s.sprintf("%.2f", Plot->SkyFov[1]); + SkyFov3->Text = s.sprintf("%.2f", Plot->SkyFov[2]); + SkyDest1->Text = s.sprintf("%.1f", Plot->SkyDest[1]); + SkyDest2->Text = s.sprintf("%.1f", Plot->SkyDest[2]); + SkyDest3->Text = s.sprintf("%.1f", Plot->SkyDest[3]); + SkyDest4->Text = s.sprintf("%.1f", Plot->SkyDest[4]); + SkyDest5->Text = s.sprintf("%.1f", Plot->SkyDest[5]); + SkyDest6->Text = s.sprintf("%.1f", Plot->SkyDest[6]); + SkyDest7->Text = s.sprintf("%.1f", Plot->SkyDest[7]); + SkyDest8->Text = s.sprintf("%.1f", Plot->SkyDest[8]); + SkyDest9->Text = s.sprintf("%.1f", Plot->SkyDest[9]); + SkyElMask->Checked = Plot->SkyElMask; + SkyDestCorr->Checked = Plot->SkyDestCorr; + SkyRes->ItemIndex = Plot->SkyRes; + SkyFlip->Checked = Plot->SkyFlip; + SkyBinarize->Checked = Plot->SkyBinarize; + SkyBinThres1->Text = s.sprintf("%.2f", Plot->SkyBinThres1); + SkyBinThres2->Text = s.sprintf("%.2f", Plot->SkyBinThres2); } //--------------------------------------------------------------------------- -void __fastcall TSkyImgDialog::UpdateSky(void) -{ - Plot->SkyCent[0]=str2dbl(SkyCent1->Text); - Plot->SkyCent[1]=str2dbl(SkyCent2->Text); - Plot->SkyScale=str2dbl(SkyScale->Text); - Plot->SkyFov[0]=str2dbl(SkyFov1->Text); - Plot->SkyFov[1]=str2dbl(SkyFov2->Text); - Plot->SkyFov[2]=str2dbl(SkyFov3->Text); - Plot->SkyDest[1]=str2dbl(SkyDest1->Text); - Plot->SkyDest[2]=str2dbl(SkyDest2->Text); - Plot->SkyDest[3]=str2dbl(SkyDest3->Text); - Plot->SkyDest[4]=str2dbl(SkyDest4->Text); - Plot->SkyDest[5]=str2dbl(SkyDest5->Text); - Plot->SkyDest[6]=str2dbl(SkyDest6->Text); - Plot->SkyDest[7]=str2dbl(SkyDest7->Text); - Plot->SkyDest[8]=str2dbl(SkyDest8->Text); - Plot->SkyDest[9]=str2dbl(SkyDest9->Text); - Plot->SkyElMask=SkyElMask->Checked; - Plot->SkyDestCorr=SkyDestCorr->Checked; - Plot->SkyRes=SkyRes->ItemIndex; - Plot->SkyFlip=SkyFlip->Checked; - Plot->SkyBinarize=SkyBinarize->Checked; - Plot->SkyBinThres1=str2dbl(SkyBinThres1->Text); - Plot->SkyBinThres2=str2dbl(SkyBinThres2->Text); - Plot->UpdateSky(); +void __fastcall TSkyImgDialog::UpdateSky(void) { + Plot->SkyCent[0] = str2dbl(SkyCent1->Text); + Plot->SkyCent[1] = str2dbl(SkyCent2->Text); + Plot->SkyScale = str2dbl(SkyScale->Text); + Plot->SkyFov[0] = str2dbl(SkyFov1->Text); + Plot->SkyFov[1] = str2dbl(SkyFov2->Text); + Plot->SkyFov[2] = str2dbl(SkyFov3->Text); + Plot->SkyDest[1] = str2dbl(SkyDest1->Text); + Plot->SkyDest[2] = str2dbl(SkyDest2->Text); + Plot->SkyDest[3] = str2dbl(SkyDest3->Text); + Plot->SkyDest[4] = str2dbl(SkyDest4->Text); + Plot->SkyDest[5] = str2dbl(SkyDest5->Text); + Plot->SkyDest[6] = str2dbl(SkyDest6->Text); + Plot->SkyDest[7] = str2dbl(SkyDest7->Text); + Plot->SkyDest[8] = str2dbl(SkyDest8->Text); + Plot->SkyDest[9] = str2dbl(SkyDest9->Text); + Plot->SkyElMask = SkyElMask->Checked; + Plot->SkyDestCorr = SkyDestCorr->Checked; + Plot->SkyRes = SkyRes->ItemIndex; + Plot->SkyFlip = SkyFlip->Checked; + Plot->SkyBinarize = SkyBinarize->Checked; + Plot->SkyBinThres1 = str2dbl(SkyBinThres1->Text); + Plot->SkyBinThres2 = str2dbl(SkyBinThres2->Text); + Plot->UpdateSky(); } //--------------------------------------------------------------------------- -void __fastcall TSkyImgDialog::UpdateEnable(void) -{ - SkyDest1->Enabled=SkyDestCorr->Checked; - SkyDest2->Enabled=SkyDestCorr->Checked; - SkyDest3->Enabled=SkyDestCorr->Checked; - SkyDest4->Enabled=SkyDestCorr->Checked; - SkyDest5->Enabled=SkyDestCorr->Checked; - SkyDest6->Enabled=SkyDestCorr->Checked; - SkyDest7->Enabled=SkyDestCorr->Checked; - SkyDest8->Enabled=SkyDestCorr->Checked; - SkyDest9->Enabled=SkyDestCorr->Checked; - SkyBinThres1->Enabled=SkyBinarize->Checked; - SkyBinThres2->Enabled=SkyBinarize->Checked; - SkyBinThres1UpDown->Enabled=SkyBinarize->Checked; - SkyBinThres2UpDown->Enabled=SkyBinarize->Checked; - BtnGenMask->Enabled=SkyBinarize->Checked; +void __fastcall TSkyImgDialog::UpdateEnable(void) { + SkyDest1->Enabled = SkyDestCorr->Checked; + SkyDest2->Enabled = SkyDestCorr->Checked; + SkyDest3->Enabled = SkyDestCorr->Checked; + SkyDest4->Enabled = SkyDestCorr->Checked; + SkyDest5->Enabled = SkyDestCorr->Checked; + SkyDest6->Enabled = SkyDestCorr->Checked; + SkyDest7->Enabled = SkyDestCorr->Checked; + SkyDest8->Enabled = SkyDestCorr->Checked; + SkyDest9->Enabled = SkyDestCorr->Checked; + SkyBinThres1->Enabled = SkyBinarize->Checked; + SkyBinThres2->Enabled = SkyBinarize->Checked; + SkyBinThres1UpDown->Enabled = SkyBinarize->Checked; + SkyBinThres2UpDown->Enabled = SkyBinarize->Checked; + BtnGenMask->Enabled = SkyBinarize->Checked; } //--------------------------------------------------------------------------- void __fastcall TSkyImgDialog::SkyFov2UpDownChangingEx(TObject *Sender, bool &AllowChange, - int NewValue, TUpDownDirection Direction) -{ - AnsiString s; - double fov=str2dbl(SkyFov2->Text); - fov=floor(fov+0.5); - if (Direction==updUp) fov+=1.0; else fov-=1.0; - if (fov<=-180.0) fov+=360.0; else if (fov>180.0) fov-=360.0; - SkyFov2->Text=s.sprintf("%.2f",fov); - UpdateSky(); + int NewValue, TUpDownDirection Direction) { + AnsiString s; + double fov = str2dbl(SkyFov2->Text); + fov = floor(fov + 0.5); + if (Direction == updUp) + fov += 1.0; + else + fov -= 1.0; + if (fov <= -180.0) + fov += 360.0; + else if (fov > 180.0) + fov -= 360.0; + SkyFov2->Text = s.sprintf("%.2f", fov); + UpdateSky(); } //--------------------------------------------------------------------------- void __fastcall TSkyImgDialog::SkyFov1UpDownChangingEx(TObject *Sender, bool &AllowChange, - int NewValue, TUpDownDirection Direction) -{ - AnsiString s; - double fov=str2dbl(SkyFov1->Text); - fov=floor(fov+0.5); - if (Direction==updUp) fov+=1.0; else fov-=1.0; - if (fov<=-180.0) fov+=360.0; else if (fov>180.0) fov-=360.0; - SkyFov1->Text=s.sprintf("%.2f",fov); - UpdateSky(); + int NewValue, TUpDownDirection Direction) { + AnsiString s; + double fov = str2dbl(SkyFov1->Text); + fov = floor(fov + 0.5); + if (Direction == updUp) + fov += 1.0; + else + fov -= 1.0; + if (fov <= -180.0) + fov += 360.0; + else if (fov > 180.0) + fov -= 360.0; + SkyFov1->Text = s.sprintf("%.2f", fov); + UpdateSky(); } //--------------------------------------------------------------------------- void __fastcall TSkyImgDialog::SkyFov3UpDownChangingEx(TObject *Sender, bool &AllowChange, - int NewValue, TUpDownDirection Direction) -{ - AnsiString s; - double fov=str2dbl(SkyFov3->Text); - fov=floor(fov+0.5); - if (Direction==updUp) fov+=1.0; else fov-=1.0; - if (fov<=-180.0) fov+=360.0; else if (fov>180.0) fov-=360.0; - SkyFov3->Text=s.sprintf("%.2f",fov); - UpdateSky(); + int NewValue, TUpDownDirection Direction) { + AnsiString s; + double fov = str2dbl(SkyFov3->Text); + fov = floor(fov + 0.5); + if (Direction == updUp) + fov += 1.0; + else + fov -= 1.0; + if (fov <= -180.0) + fov += 360.0; + else if (fov > 180.0) + fov -= 360.0; + SkyFov3->Text = s.sprintf("%.2f", fov); + UpdateSky(); } //--------------------------------------------------------------------------- void __fastcall TSkyImgDialog::SkyCent1UpDownChangingEx(TObject *Sender, bool &AllowChange, - int NewValue, TUpDownDirection Direction) -{ - AnsiString s; - double cent=str2dbl(SkyCent1->Text); - cent=floor(cent+0.5); - if (Direction==updUp) cent+=1.0; else cent-=1.0; - SkyCent1->Text=s.sprintf("%.2f",cent); - UpdateSky(); + int NewValue, TUpDownDirection Direction) { + AnsiString s; + double cent = str2dbl(SkyCent1->Text); + cent = floor(cent + 0.5); + if (Direction == updUp) + cent += 1.0; + else + cent -= 1.0; + SkyCent1->Text = s.sprintf("%.2f", cent); + UpdateSky(); } //--------------------------------------------------------------------------- void __fastcall TSkyImgDialog::SkyCent2UpDownChangingEx(TObject *Sender, bool &AllowChange, - int NewValue, TUpDownDirection Direction) -{ - AnsiString s; - double cent=str2dbl(SkyCent2->Text); - cent=floor(cent+0.5); - if (Direction==updUp) cent+=1.0; else cent-=1.0; - SkyCent2->Text=s.sprintf("%.2f",cent); - UpdateSky(); + int NewValue, TUpDownDirection Direction) { + AnsiString s; + double cent = str2dbl(SkyCent2->Text); + cent = floor(cent + 0.5); + if (Direction == updUp) + cent += 1.0; + else + cent -= 1.0; + SkyCent2->Text = s.sprintf("%.2f", cent); + UpdateSky(); } //--------------------------------------------------------------------------- void __fastcall TSkyImgDialog::SkyScaleUpDownChangingEx(TObject *Sender, bool &AllowChange, - int NewValue, TUpDownDirection Direction) -{ - AnsiString s; - double scale=str2dbl(SkyScale->Text); - scale=floor(scale+0.5); - if (Direction==updUp) scale+=1.0; else scale-=1.0; - if (scale<1.0) scale=1.0; - SkyScale->Text=s.sprintf("%.2f",scale); - UpdateSky(); + int NewValue, TUpDownDirection Direction) { + AnsiString s; + double scale = str2dbl(SkyScale->Text); + scale = floor(scale + 0.5); + if (Direction == updUp) + scale += 1.0; + else + scale -= 1.0; + if (scale < 1.0) scale = 1.0; + SkyScale->Text = s.sprintf("%.2f", scale); + UpdateSky(); } //--------------------------------------------------------------------------- void __fastcall TSkyImgDialog::SkyElMaskMouseUp(TObject *Sender, TMouseButton Button, - TShiftState Shift, int X, int Y) -{ - UpdateSky(); + TShiftState Shift, int X, int Y) { + UpdateSky(); } //--------------------------------------------------------------------------- void __fastcall TSkyImgDialog::SkyDestCorrMouseUp(TObject *Sender, TMouseButton Button, - TShiftState Shift, int X, int Y) -{ - UpdateSky(); - UpdateEnable(); + TShiftState Shift, int X, int Y) { + UpdateSky(); + UpdateEnable(); } //--------------------------------------------------------------------------- void __fastcall TSkyImgDialog::SkyFlipMouseUp(TObject *Sender, TMouseButton Button, - TShiftState Shift, int X, int Y) -{ - UpdateSky(); + TShiftState Shift, int X, int Y) { + UpdateSky(); } //--------------------------------------------------------------------------- -void __fastcall TSkyImgDialog::SkyResChange(TObject *Sender) -{ - UpdateSky(); -} +void __fastcall TSkyImgDialog::SkyResChange(TObject *Sender) { UpdateSky(); } //--------------------------------------------------------------------------- -void __fastcall TSkyImgDialog::BtnLoadClick(TObject *Sender) -{ - OpenTagDialog->Title="Open Tag"; - if (!OpenTagDialog->Execute()) return; - Plot->ReadSkyTag(OpenTagDialog->FileName); - UpdateField(); - Plot->UpdateSky(); +void __fastcall TSkyImgDialog::BtnLoadClick(TObject *Sender) { + OpenTagDialog->Title = "Open Tag"; + if (!OpenTagDialog->Execute()) return; + Plot->ReadSkyTag(OpenTagDialog->FileName); + UpdateField(); + Plot->UpdateSky(); } //--------------------------------------------------------------------------- -void __fastcall TSkyImgDialog::BtnGenMaskClick(TObject *Sender) -{ - BITMAP bm; - BYTE *img,*pix; - double r,ca,sa,el,el0; - int x,y,w,h,b,az,n; - - if (!GetObject(Plot->SkyImageR->Handle,sizeof(bm),&bm)) return; - w=bm.bmWidth; h=bm.bmHeight; b=bm.bmWidthBytes; - if (w<=0||h<=0||b=0.0;el-=0.1) { - r=(1.0-el/90.0)*Plot->SkyScaleR; - x=(int)floor(w/2.0+sa*r+0.5); - y=(int)floor(h/2.0+ca*r+0.5); - if (x<0||x>=w||y<0||y>=h) continue; - pix=img+x*3+y*b; - if (pix[0]<255&&pix[1]<255&&pix[2]<255) { - if (++n==1) el0=el; - if (n>=5) break; - } - else n=0; - } - Plot->ElMaskData[az]=el0==90.0?0.0:el0*D2R; +void __fastcall TSkyImgDialog::BtnGenMaskClick(TObject *Sender) { + BITMAP bm; + BYTE *img, *pix; + double r, ca, sa, el, el0; + int x, y, w, h, b, az, n; + + if (!GetObject(Plot->SkyImageR->Handle, sizeof(bm), &bm)) return; + w = bm.bmWidth; + h = bm.bmHeight; + b = bm.bmWidthBytes; + if (w <= 0 || h <= 0 || b < w * 3) return; + img = (BYTE *)bm.bmBits; + + for (az = 0; az <= 360; az++) { + ca = cos(az * D2R); + sa = sin(az * D2R); + for (el = 90.0, n = 0, el0 = 0.0; el >= 0.0; el -= 0.1) { + r = (1.0 - el / 90.0) * Plot->SkyScaleR; + x = (int)floor(w / 2.0 + sa * r + 0.5); + y = (int)floor(h / 2.0 + ca * r + 0.5); + if (x < 0 || x >= w || y < 0 || y >= h) continue; + pix = img + x * 3 + y * b; + if (pix[0] < 255 && pix[1] < 255 && pix[2] < 255) { + if (++n == 1) el0 = el; + if (n >= 5) break; + } else + n = 0; } - Plot->UpdateSky(); + Plot->ElMaskData[az] = el0 == 90.0 ? 0.0 : el0 * D2R; + } + Plot->UpdateSky(); } //--------------------------------------------------------------------------- void __fastcall TSkyImgDialog::SkyBinThres1UpDownChangingEx(TObject *Sender, bool &AllowChange, - short NewValue, TUpDownDirection Direction) -{ - AnsiString s; - double thres=str2dbl(SkyBinThres1->Text); - if (Direction==updUp) thres+=0.01; else thres-=0.01; - if (thres<=0.0) thres=0.0; else if (thres>1.0) thres=1.0; - SkyBinThres1->Text=s.sprintf("%.2f",thres); - UpdateSky(); + short NewValue, + TUpDownDirection Direction) { + AnsiString s; + double thres = str2dbl(SkyBinThres1->Text); + if (Direction == updUp) + thres += 0.01; + else + thres -= 0.01; + if (thres <= 0.0) + thres = 0.0; + else if (thres > 1.0) + thres = 1.0; + SkyBinThres1->Text = s.sprintf("%.2f", thres); + UpdateSky(); } //--------------------------------------------------------------------------- void __fastcall TSkyImgDialog::SkyBinThres2UpDownChangingEx(TObject *Sender, bool &AllowChange, - short NewValue, TUpDownDirection Direction) -{ - AnsiString s; - double thres=str2dbl(SkyBinThres2->Text); - if (Direction==updUp) thres+=0.01; else thres-=0.01; - if (thres<=0.0) thres=0.0; else if (thres>1.0) thres=1.0; - SkyBinThres2->Text=s.sprintf("%.2f",thres); - UpdateSky(); + short NewValue, + TUpDownDirection Direction) { + AnsiString s; + double thres = str2dbl(SkyBinThres2->Text); + if (Direction == updUp) + thres += 0.01; + else + thres -= 0.01; + if (thres <= 0.0) + thres = 0.0; + else if (thres > 1.0) + thres = 1.0; + SkyBinThres2->Text = s.sprintf("%.2f", thres); + UpdateSky(); } //--------------------------------------------------------------------------- void __fastcall TSkyImgDialog::SkyBinarizeMouseUp(TObject *Sender, TMouseButton Button, - TShiftState Shift, int X, int Y) -{ - UpdateSky(); - UpdateEnable(); + TShiftState Shift, int X, int Y) { + UpdateSky(); + UpdateEnable(); } //--------------------------------------------------------------------------- - diff --git a/app/winapp/rtkplot/skydlg.h b/app/winapp/rtkplot/skydlg.h index 7fadf2e0b..b1cfa0e72 100644 --- a/app/winapp/rtkplot/skydlg.h +++ b/app/winapp/rtkplot/skydlg.h @@ -2,116 +2,115 @@ #ifndef skydlgH #define skydlgH //--------------------------------------------------------------------------- +#include #include -#include -#include -#include #include +#include #include -#include +#include +#include #include //--------------------------------------------------------------------------- -class TSkyImgDialog : public TForm -{ -__published: - TButton *BtnClose; - TButton *BtnSave; - TButton *BtnUpdate; - TPanel *Panel1; - TLabel *Label1; - TEdit *SkySize1; - TEdit *SkySize2; - TPanel *Panel2; - TEdit *SkyFov1; - TUpDown *SkyFov1UpDown; - TEdit *SkyFov2; - TUpDown *SkyFov2UpDown; - TLabel *Label6; - TLabel *Label2; - TCheckBox *SkyElMask; - TLabel *Label3; - TLabel *Label4; - TEdit *SkyFov3; - TUpDown *SkyFov3UpDown; - TLabel *Label7; - TEdit *SkyCent1; - TEdit *SkyCent2; - TLabel *Label5; - TLabel *Label9; - TLabel *Label10; - TEdit *SkyScale; - TUpDown *SkyCent1UpDown; - TUpDown *SkyScaleUpDown; - TUpDown *SkyCent2UpDown; - TCheckBox *SkyDestCorr; - TEdit *SkyDest1; - TEdit *SkyDest2; - TEdit *SkyDest3; - TEdit *SkyDest4; - TEdit *SkyDest5; - TEdit *SkyDest6; - TEdit *SkyDest7; - TEdit *SkyDest8; - TLabel *Label11; - TLabel *Label12; - TLabel *Label13; - TLabel *Label14; - TLabel *Label15; - TLabel *Label16; - TLabel *Label17; - TLabel *Label18; - TLabel *Label8; - TComboBox *SkyRes; - TCheckBox *SkyFlip; - TButton *BtnLoad; - TOpenDialog *OpenTagDialog; - TEdit *SkyDest9; - TLabel *Label19; - TLabel *Label20; - TButton *BtnGenMask; - TCheckBox *SkyBinarize; - TEdit *SkyBinThres1; - TUpDown *SkyBinThres1UpDown; - TEdit *SkyBinThres2; - TUpDown *SkyBinThres2UpDown; - void __fastcall FormShow(TObject *Sender); - void __fastcall BtnCloseClick(TObject *Sender); - void __fastcall BtnUpdateClick(TObject *Sender); - void __fastcall BtnSaveClick(TObject *Sender); - void __fastcall SkyFov2UpDownChangingEx(TObject *Sender, bool &AllowChange, int NewValue, - TUpDownDirection Direction); - void __fastcall SkyFov1UpDownChangingEx(TObject *Sender, bool &AllowChange, int NewValue, - TUpDownDirection Direction); - void __fastcall SkyFov3UpDownChangingEx(TObject *Sender, bool &AllowChange, int NewValue, - TUpDownDirection Direction); - void __fastcall SkyCent1UpDownChangingEx(TObject *Sender, bool &AllowChange, int NewValue, - TUpDownDirection Direction); - void __fastcall SkyCent2UpDownChangingEx(TObject *Sender, bool &AllowChange, int NewValue, - TUpDownDirection Direction); - void __fastcall SkyScaleUpDownChangingEx(TObject *Sender, bool &AllowChange, int NewValue, - TUpDownDirection Direction); - void __fastcall SkyElMaskMouseUp(TObject *Sender, TMouseButton Button, TShiftState Shift, - int X, int Y); - void __fastcall SkyDestCorrMouseUp(TObject *Sender, TMouseButton Button, TShiftState Shift, - int X, int Y); - void __fastcall SkyFlipMouseUp(TObject *Sender, TMouseButton Button, TShiftState Shift, - int X, int Y); - void __fastcall SkyResChange(TObject *Sender); - void __fastcall BtnLoadClick(TObject *Sender); - void __fastcall BtnGenMaskClick(TObject *Sender); - void __fastcall SkyBinThres1UpDownChangingEx(TObject *Sender, bool &AllowChange, - short NewValue, TUpDownDirection Direction); - void __fastcall SkyBinThres2UpDownChangingEx(TObject *Sender, bool &AllowChange, - short NewValue, TUpDownDirection Direction); - void __fastcall SkyBinarizeMouseUp(TObject *Sender, TMouseButton Button, TShiftState Shift, - int X, int Y); -private: - void __fastcall UpdateSky(void); - void __fastcall UpdateEnable(void); - -public: - __fastcall TSkyImgDialog(TComponent* Owner); - void __fastcall UpdateField(void); +class TSkyImgDialog : public TForm { + __published : TButton *BtnClose; + TButton *BtnSave; + TButton *BtnUpdate; + TPanel *Panel1; + TLabel *Label1; + TEdit *SkySize1; + TEdit *SkySize2; + TPanel *Panel2; + TEdit *SkyFov1; + TUpDown *SkyFov1UpDown; + TEdit *SkyFov2; + TUpDown *SkyFov2UpDown; + TLabel *Label6; + TLabel *Label2; + TCheckBox *SkyElMask; + TLabel *Label3; + TLabel *Label4; + TEdit *SkyFov3; + TUpDown *SkyFov3UpDown; + TLabel *Label7; + TEdit *SkyCent1; + TEdit *SkyCent2; + TLabel *Label5; + TLabel *Label9; + TLabel *Label10; + TEdit *SkyScale; + TUpDown *SkyCent1UpDown; + TUpDown *SkyScaleUpDown; + TUpDown *SkyCent2UpDown; + TCheckBox *SkyDestCorr; + TEdit *SkyDest1; + TEdit *SkyDest2; + TEdit *SkyDest3; + TEdit *SkyDest4; + TEdit *SkyDest5; + TEdit *SkyDest6; + TEdit *SkyDest7; + TEdit *SkyDest8; + TLabel *Label11; + TLabel *Label12; + TLabel *Label13; + TLabel *Label14; + TLabel *Label15; + TLabel *Label16; + TLabel *Label17; + TLabel *Label18; + TLabel *Label8; + TComboBox *SkyRes; + TCheckBox *SkyFlip; + TButton *BtnLoad; + TOpenDialog *OpenTagDialog; + TEdit *SkyDest9; + TLabel *Label19; + TLabel *Label20; + TButton *BtnGenMask; + TCheckBox *SkyBinarize; + TEdit *SkyBinThres1; + TUpDown *SkyBinThres1UpDown; + TEdit *SkyBinThres2; + TUpDown *SkyBinThres2UpDown; + void __fastcall FormShow(TObject *Sender); + void __fastcall BtnCloseClick(TObject *Sender); + void __fastcall BtnUpdateClick(TObject *Sender); + void __fastcall BtnSaveClick(TObject *Sender); + void __fastcall SkyFov2UpDownChangingEx(TObject *Sender, bool &AllowChange, int NewValue, + TUpDownDirection Direction); + void __fastcall SkyFov1UpDownChangingEx(TObject *Sender, bool &AllowChange, int NewValue, + TUpDownDirection Direction); + void __fastcall SkyFov3UpDownChangingEx(TObject *Sender, bool &AllowChange, int NewValue, + TUpDownDirection Direction); + void __fastcall SkyCent1UpDownChangingEx(TObject *Sender, bool &AllowChange, int NewValue, + TUpDownDirection Direction); + void __fastcall SkyCent2UpDownChangingEx(TObject *Sender, bool &AllowChange, int NewValue, + TUpDownDirection Direction); + void __fastcall SkyScaleUpDownChangingEx(TObject *Sender, bool &AllowChange, int NewValue, + TUpDownDirection Direction); + void __fastcall SkyElMaskMouseUp(TObject *Sender, TMouseButton Button, TShiftState Shift, int X, + int Y); + void __fastcall SkyDestCorrMouseUp(TObject *Sender, TMouseButton Button, TShiftState Shift, int X, + int Y); + void __fastcall SkyFlipMouseUp(TObject *Sender, TMouseButton Button, TShiftState Shift, int X, + int Y); + void __fastcall SkyResChange(TObject *Sender); + void __fastcall BtnLoadClick(TObject *Sender); + void __fastcall BtnGenMaskClick(TObject *Sender); + void __fastcall SkyBinThres1UpDownChangingEx(TObject *Sender, bool &AllowChange, short NewValue, + TUpDownDirection Direction); + void __fastcall SkyBinThres2UpDownChangingEx(TObject *Sender, bool &AllowChange, short NewValue, + TUpDownDirection Direction); + void __fastcall SkyBinarizeMouseUp(TObject *Sender, TMouseButton Button, TShiftState Shift, int X, + int Y); + + private: + void __fastcall UpdateSky(void); + void __fastcall UpdateEnable(void); + + public: + __fastcall TSkyImgDialog(TComponent *Owner); + void __fastcall UpdateField(void); }; //--------------------------------------------------------------------------- extern PACKAGE TSkyImgDialog *SkyImgDialog; diff --git a/app/winapp/rtkplot/vmapdlg.cpp b/app/winapp/rtkplot/vmapdlg.cpp index 4250a7b05..d293d3eba 100644 --- a/app/winapp/rtkplot/vmapdlg.cpp +++ b/app/winapp/rtkplot/vmapdlg.cpp @@ -2,213 +2,163 @@ #include #pragma hdrstop -#include "plotmain.h" #include "vmapdlg.h" + +#include "plotmain.h" //--------------------------------------------------------------------------- #pragma package(smart_init) #pragma resource "*.dfm" TVecMapDialog *VecMapDialog; //--------------------------------------------------------------------------- -__fastcall TVecMapDialog::TVecMapDialog(TComponent* Owner) - : TForm(Owner) -{ -} +__fastcall TVecMapDialog::TVecMapDialog(TComponent *Owner) : TForm(Owner) {} //--------------------------------------------------------------------------- -void __fastcall TVecMapDialog::Layer1Click(TObject *Sender) -{ - TRadioButton *layer[]={ - Layer1,Layer2,Layer3,Layer4,Layer5,Layer6,Layer7,Layer8,Layer9, - Layer10,Layer11,Layer12 - }; - for (int i=0;iChecked=(layer[i]==(TRadioButton *)Sender); - } - UpdateMap(); +void __fastcall TVecMapDialog::Layer1Click(TObject *Sender) { + TRadioButton *layer[] = {Layer1, Layer2, Layer3, Layer4, Layer5, Layer6, + Layer7, Layer8, Layer9, Layer10, Layer11, Layer12}; + for (int i = 0; i < MAXMAPLAYER; i++) { + layer[i]->Checked = (layer[i] == (TRadioButton *)Sender); + } + UpdateMap(); } //--------------------------------------------------------------------------- -void __fastcall TVecMapDialog::BtnUpClick(TObject *Sender) -{ - TRadioButton *layer[]={ - Layer1,Layer2,Layer3,Layer4,Layer5,Layer6,Layer7,Layer8,Layer9, - Layer10,Layer11,Layer12 - }; - TPanel *color[]={ - Color1,Color2,Color3,Color4,Color5,Color6,Color7,Color8,Color9, - Color10,Color11,Color12 - }; - TPanel *colorf[]={ - Color1F,Color2F,Color3F,Color4F,Color5F,Color6F,Color7F,Color8F, - Color9F,Color10F,Color11F,Color12F - }; - TColor col; - gisd_t *data; - char name[256]; - int i,flag; - - for (i=0;iChecked) break; - } - if (i==0||i>=MAXMAPLAYER) return; - strcpy(name,Gis.name[i-1]); - strcpy(Gis.name[i-1],Gis.name[i]); - strcpy(Gis.name[i],name); - flag=Gis.flag[i-1]; - Gis.flag[i-1]=Gis.flag[i]; - Gis.flag[i]=flag; - data=Gis.data[i-1]; - Gis.data[i-1]=Gis.data[i]; - Gis.data[i]=data; - col=color[i-1]->Color; - color[i-1]->Color=color[i]->Color; - color[i]->Color=col; - col=colorf[i-1]->Color; - colorf[i-1]->Color=colorf[i]->Color; - colorf[i]->Color=col; - layer[i-1]->Checked=true; - layer[i]->Checked=false; - UpdateMap(); +void __fastcall TVecMapDialog::BtnUpClick(TObject *Sender) { + TRadioButton *layer[] = {Layer1, Layer2, Layer3, Layer4, Layer5, Layer6, + Layer7, Layer8, Layer9, Layer10, Layer11, Layer12}; + TPanel *color[] = {Color1, Color2, Color3, Color4, Color5, Color6, + Color7, Color8, Color9, Color10, Color11, Color12}; + TPanel *colorf[] = {Color1F, Color2F, Color3F, Color4F, Color5F, Color6F, + Color7F, Color8F, Color9F, Color10F, Color11F, Color12F}; + TColor col; + gisd_t *data; + char name[256]; + int i, flag; + + for (i = 0; i < MAXMAPLAYER; i++) { + if (layer[i]->Checked) break; + } + if (i == 0 || i >= MAXMAPLAYER) return; + strcpy(name, Gis.name[i - 1]); + strcpy(Gis.name[i - 1], Gis.name[i]); + strcpy(Gis.name[i], name); + flag = Gis.flag[i - 1]; + Gis.flag[i - 1] = Gis.flag[i]; + Gis.flag[i] = flag; + data = Gis.data[i - 1]; + Gis.data[i - 1] = Gis.data[i]; + Gis.data[i] = data; + col = color[i - 1]->Color; + color[i - 1]->Color = color[i]->Color; + color[i]->Color = col; + col = colorf[i - 1]->Color; + colorf[i - 1]->Color = colorf[i]->Color; + colorf[i]->Color = col; + layer[i - 1]->Checked = true; + layer[i]->Checked = false; + UpdateMap(); } //--------------------------------------------------------------------------- -void __fastcall TVecMapDialog::BtnDownClick(TObject *Sender) -{ - TRadioButton *layer[]={ - Layer1,Layer2,Layer3,Layer4,Layer5,Layer6,Layer7,Layer8,Layer9, - Layer10,Layer11,Layer12 - }; - TPanel *color[]={ - Color1,Color2,Color3,Color4,Color5,Color6,Color7,Color8,Color9, - Color10,Color11,Color12 - }; - TPanel *colorf[]={ - Color1F,Color2F,Color3F,Color4F,Color5F,Color6F,Color7F,Color8F, - Color9F,Color10F,Color11F,Color12F - }; - TColor col; - gisd_t *data; - char name[256]; - int i,flag; - - for (i=0;iChecked) break; - } - if (i==MAXMAPLAYER-1||i>=MAXMAPLAYER) return; - strcpy(name,Gis.name[i+1]); - strcpy(Gis.name[i+1],Gis.name[i]); - strcpy(Gis.name[i],name); - flag=Gis.flag[i+1]; - Gis.flag[i+1]=Gis.flag[i]; - Gis.flag[i]=flag; - data=Gis.data[i+1]; - Gis.data[i+1]=Gis.data[i]; - Gis.data[i]=data; - col=color[i+1]->Color; - color[i+1]->Color=color[i]->Color; - color[i]->Color=col; - col=colorf[i+1]->Color; - colorf[i+1]->Color=colorf[i]->Color; - colorf[i]->Color=col; - layer[i+1]->Checked=true; - layer[i]->Checked=false; - UpdateMap(); +void __fastcall TVecMapDialog::BtnDownClick(TObject *Sender) { + TRadioButton *layer[] = {Layer1, Layer2, Layer3, Layer4, Layer5, Layer6, + Layer7, Layer8, Layer9, Layer10, Layer11, Layer12}; + TPanel *color[] = {Color1, Color2, Color3, Color4, Color5, Color6, + Color7, Color8, Color9, Color10, Color11, Color12}; + TPanel *colorf[] = {Color1F, Color2F, Color3F, Color4F, Color5F, Color6F, + Color7F, Color8F, Color9F, Color10F, Color11F, Color12F}; + TColor col; + gisd_t *data; + char name[256]; + int i, flag; + + for (i = 0; i < MAXMAPLAYER; i++) { + if (layer[i]->Checked) break; + } + if (i == MAXMAPLAYER - 1 || i >= MAXMAPLAYER) return; + strcpy(name, Gis.name[i + 1]); + strcpy(Gis.name[i + 1], Gis.name[i]); + strcpy(Gis.name[i], name); + flag = Gis.flag[i + 1]; + Gis.flag[i + 1] = Gis.flag[i]; + Gis.flag[i] = flag; + data = Gis.data[i + 1]; + Gis.data[i + 1] = Gis.data[i]; + Gis.data[i] = data; + col = color[i + 1]->Color; + color[i + 1]->Color = color[i]->Color; + color[i]->Color = col; + col = colorf[i + 1]->Color; + colorf[i + 1]->Color = colorf[i]->Color; + colorf[i]->Color = col; + layer[i + 1]->Checked = true; + layer[i]->Checked = false; + UpdateMap(); } //--------------------------------------------------------------------------- -void __fastcall TVecMapDialog::BtnDeleteClick(TObject *Sender) -{ - ; -} +void __fastcall TVecMapDialog::BtnDeleteClick(TObject *Sender) { ; } //--------------------------------------------------------------------------- -void __fastcall TVecMapDialog::Vis1Click(TObject *Sender) -{ - TCheckBox *vis[]={ - Vis1,Vis2,Vis3,Vis4,Vis5,Vis6,Vis7,Vis8,Vis9,Vis10,Vis11,Vis12 - }; - for (int i=0;iChecked?1:0; - } - UpdateMap(); +void __fastcall TVecMapDialog::Vis1Click(TObject *Sender) { + TCheckBox *vis[] = {Vis1, Vis2, Vis3, Vis4, Vis5, Vis6, Vis7, Vis8, Vis9, Vis10, Vis11, Vis12}; + for (int i = 0; i < MAXMAPLAYER; i++) { + if ((TCheckBox *)Sender == vis[i]) Gis.flag[i] = vis[i]->Checked ? 1 : 0; + } + UpdateMap(); } //--------------------------------------------------------------------------- -void __fastcall TVecMapDialog::FormShow(TObject *Sender) -{ - TRadioButton *layer[]={ - Layer1,Layer2,Layer3,Layer4,Layer5,Layer6,Layer7,Layer8,Layer9, - Layer10,Layer11,Layer12 - }; - TPanel *color[]={ - Color1,Color2,Color3,Color4,Color5,Color6,Color7,Color8,Color9, - Color10,Color11,Color12 - }; - TPanel *colorf[]={ - Color1F,Color2F,Color3F,Color4F,Color5F,Color6F,Color7F,Color8F, - Color9F,Color10F,Color11F,Color12F - }; - Gis=Plot->Gis; - for (int i=0;iChecked=false; - color [i]->Color=Plot->MapColor [i]; - colorf[i]->Color=Plot->MapColorF[i]; - } - UpdateMap(); +void __fastcall TVecMapDialog::FormShow(TObject *Sender) { + TRadioButton *layer[] = {Layer1, Layer2, Layer3, Layer4, Layer5, Layer6, + Layer7, Layer8, Layer9, Layer10, Layer11, Layer12}; + TPanel *color[] = {Color1, Color2, Color3, Color4, Color5, Color6, + Color7, Color8, Color9, Color10, Color11, Color12}; + TPanel *colorf[] = {Color1F, Color2F, Color3F, Color4F, Color5F, Color6F, + Color7F, Color8F, Color9F, Color10F, Color11F, Color12F}; + Gis = Plot->Gis; + for (int i = 0; i < MAXMAPLAYER; i++) { + layer[i]->Checked = false; + color[i]->Color = Plot->MapColor[i]; + colorf[i]->Color = Plot->MapColorF[i]; + } + UpdateMap(); } //--------------------------------------------------------------------------- -void __fastcall TVecMapDialog::BtnApplyClick(TObject *Sender) -{ - UpdateMap(); -} +void __fastcall TVecMapDialog::BtnApplyClick(TObject *Sender) { UpdateMap(); } //--------------------------------------------------------------------------- -void __fastcall TVecMapDialog::BtnCloseClick(TObject *Sender) -{ - Close(); -} +void __fastcall TVecMapDialog::BtnCloseClick(TObject *Sender) { Close(); } //--------------------------------------------------------------------------- -void __fastcall TVecMapDialog::ColorClick(TObject *Sender) -{ - TPanel *color[]={ - Color1,Color2,Color3,Color4,Color5,Color6,Color7,Color8,Color9, - Color10,Color11,Color12,Color1F,Color2F,Color3F,Color4F,Color5F, - Color6F,Color7F,Color8F,Color9F,Color10F,Color11F,Color12F,NULL - }; - int i; +void __fastcall TVecMapDialog::ColorClick(TObject *Sender) { + TPanel *color[] = {Color1, Color2, Color3, Color4, Color5, Color6, Color7, + Color8, Color9, Color10, Color11, Color12, Color1F, Color2F, + Color3F, Color4F, Color5F, Color6F, Color7F, Color8F, Color9F, + Color10F, Color11F, Color12F, NULL}; + int i; - for (i=0;color[i];i++) { - if (color[i]==(TPanel *)Sender) break; - } - if (color[i]) { - ColorDialog->Color=color[i]->Color; - if (!ColorDialog->Execute()) return; - color[i]->Color=ColorDialog->Color; - UpdateMap(); - } + for (i = 0; color[i]; i++) { + if (color[i] == (TPanel *)Sender) break; + } + if (color[i]) { + ColorDialog->Color = color[i]->Color; + if (!ColorDialog->Execute()) return; + color[i]->Color = ColorDialog->Color; + UpdateMap(); + } } //--------------------------------------------------------------------------- -void __fastcall TVecMapDialog::UpdateMap(void) -{ - TRadioButton *layer[]={ - Layer1,Layer2,Layer3,Layer4,Layer5,Layer6,Layer7,Layer8,Layer9, - Layer10,Layer11,Layer12 - }; - TCheckBox *vis[]={ - Vis1,Vis2,Vis3,Vis4,Vis5,Vis6,Vis7,Vis8,Vis9,Vis10,Vis11,Vis12 - }; - for (int i=0;iCaption=Gis.name[i]; - vis[i]->Checked=Gis.flag[i]; - Plot->MapColor [i]=color [i]->Color; - Plot->MapColorF[i]=colorf[i]->Color; - } - Plot->Gis=Gis; - Plot->UpdatePlot(); +void __fastcall TVecMapDialog::UpdateMap(void) { + TRadioButton *layer[] = {Layer1, Layer2, Layer3, Layer4, Layer5, Layer6, + Layer7, Layer8, Layer9, Layer10, Layer11, Layer12}; + TCheckBox *vis[] = {Vis1, Vis2, Vis3, Vis4, Vis5, Vis6, Vis7, Vis8, Vis9, Vis10, Vis11, Vis12}; + for (int i = 0; i < MAXMAPLAYER; i++) { + } + TPanel *color[] = {Color1, Color2, Color3, Color4, Color5, Color6, + Color7, Color8, Color9, Color10, Color11, Color12}; + TPanel *colorf[] = {Color1F, Color2F, Color3F, Color4F, Color5F, Color6F, + Color7F, Color8F, Color9F, Color10F, Color11F, Color12F}; + for (int i = 0; i < MAXMAPLAYER; i++) { + layer[i]->Caption = Gis.name[i]; + vis[i]->Checked = Gis.flag[i]; + Plot->MapColor[i] = color[i]->Color; + Plot->MapColorF[i] = colorf[i]->Color; + } + Plot->Gis = Gis; + Plot->UpdatePlot(); } //--------------------------------------------------------------------------- - diff --git a/app/winapp/rtkplot/vmapdlg.h b/app/winapp/rtkplot/vmapdlg.h index 8e31e7b86..08fb3b810 100644 --- a/app/winapp/rtkplot/vmapdlg.h +++ b/app/winapp/rtkplot/vmapdlg.h @@ -3,104 +3,104 @@ #ifndef vmapdlgH #define vmapdlgH //--------------------------------------------------------------------------- -#include "rtklib.h" - #include -#include -#include -#include -#include #include +#include #include +#include +#include +#include + +#include "rtklib.h" //--------------------------------------------------------------------------- -class TVecMapDialog : public TForm -{ -__published: - TButton *BtnApply; - TButton *BtnClose; - TCheckBox *Vis1; - TLabel *Label1; - TPanel *Color1; - TLabel *Label2; - TPanel *Panel11; - TRadioButton *Layer1; - TLabel *Label3; - TPanel *Panel12; - TPanel *Color2; - TCheckBox *Vis2; - TRadioButton *Layer2; - TPanel *Panel13; - TPanel *Color3; - TCheckBox *Vis3; - TRadioButton *Layer3; - TPanel *Panel14; - TPanel *Color4; - TCheckBox *Vis4; - TRadioButton *Layer4; - TPanel *Panel15; - TPanel *Color5; - TCheckBox *Vis5; - TRadioButton *Layer5; - TPanel *Panel16; - TPanel *Color6; - TCheckBox *Vis6; - TRadioButton *Layer6; - TPanel *Panel17; - TPanel *Color7; - TCheckBox *Vis7; - TRadioButton *Layer7; - TPanel *Panel18; - TPanel *Color8; - TCheckBox *Vis8; - TRadioButton *Layer8; - TPanel *Panel19; - TPanel *Color9; - TCheckBox *Vis9; - TRadioButton *Layer9; - TPanel *Panel1A; - TPanel *Color10; - TCheckBox *Vis10; - TRadioButton *Layer10; - TBitBtn *BtnUp; - TBitBtn *BtnDown; - TPanel *Panel1; - TColorDialog *ColorDialog; - TPanel *Panel21; - TPanel *Panel1B; - TPanel *Color11; - TCheckBox *Vis11; - TRadioButton *Layer11; - TPanel *Panel22; - TPanel *Color12; - TCheckBox *Vis12; - TRadioButton *Layer12; - TLabel *Label4; - TPanel *Color1F; - TPanel *Color2F; - TPanel *Color3F; - TPanel *Color4F; - TPanel *Color5F; - TPanel *Color6F; - TPanel *Color7F; - TPanel *Color8F; - TPanel *Color9F; - TPanel *Color10F; - TPanel *Color11F; - TPanel *Color12F; - void __fastcall Layer1Click(TObject *Sender); - void __fastcall BtnUpClick(TObject *Sender); - void __fastcall BtnDownClick(TObject *Sender); - void __fastcall BtnDeleteClick(TObject *Sender); - void __fastcall FormShow(TObject *Sender); - void __fastcall BtnApplyClick(TObject *Sender); - void __fastcall Vis1Click(TObject *Sender); - void __fastcall ColorClick(TObject *Sender); - void __fastcall BtnCloseClick(TObject *Sender); -private: - gis_t Gis; - void __fastcall UpdateMap(void); -public: - __fastcall TVecMapDialog(TComponent* Owner); +class TVecMapDialog : public TForm { + __published : TButton *BtnApply; + TButton *BtnClose; + TCheckBox *Vis1; + TLabel *Label1; + TPanel *Color1; + TLabel *Label2; + TPanel *Panel11; + TRadioButton *Layer1; + TLabel *Label3; + TPanel *Panel12; + TPanel *Color2; + TCheckBox *Vis2; + TRadioButton *Layer2; + TPanel *Panel13; + TPanel *Color3; + TCheckBox *Vis3; + TRadioButton *Layer3; + TPanel *Panel14; + TPanel *Color4; + TCheckBox *Vis4; + TRadioButton *Layer4; + TPanel *Panel15; + TPanel *Color5; + TCheckBox *Vis5; + TRadioButton *Layer5; + TPanel *Panel16; + TPanel *Color6; + TCheckBox *Vis6; + TRadioButton *Layer6; + TPanel *Panel17; + TPanel *Color7; + TCheckBox *Vis7; + TRadioButton *Layer7; + TPanel *Panel18; + TPanel *Color8; + TCheckBox *Vis8; + TRadioButton *Layer8; + TPanel *Panel19; + TPanel *Color9; + TCheckBox *Vis9; + TRadioButton *Layer9; + TPanel *Panel1A; + TPanel *Color10; + TCheckBox *Vis10; + TRadioButton *Layer10; + TBitBtn *BtnUp; + TBitBtn *BtnDown; + TPanel *Panel1; + TColorDialog *ColorDialog; + TPanel *Panel21; + TPanel *Panel1B; + TPanel *Color11; + TCheckBox *Vis11; + TRadioButton *Layer11; + TPanel *Panel22; + TPanel *Color12; + TCheckBox *Vis12; + TRadioButton *Layer12; + TLabel *Label4; + TPanel *Color1F; + TPanel *Color2F; + TPanel *Color3F; + TPanel *Color4F; + TPanel *Color5F; + TPanel *Color6F; + TPanel *Color7F; + TPanel *Color8F; + TPanel *Color9F; + TPanel *Color10F; + TPanel *Color11F; + TPanel *Color12F; + void __fastcall Layer1Click(TObject *Sender); + void __fastcall BtnUpClick(TObject *Sender); + void __fastcall BtnDownClick(TObject *Sender); + void __fastcall BtnDeleteClick(TObject *Sender); + void __fastcall FormShow(TObject *Sender); + void __fastcall BtnApplyClick(TObject *Sender); + void __fastcall Vis1Click(TObject *Sender); + void __fastcall ColorClick(TObject *Sender); + void __fastcall BtnCloseClick(TObject *Sender); + + private: + gis_t Gis; + void __fastcall UpdateMap(void); + + public: + __fastcall TVecMapDialog(TComponent *Owner); }; //--------------------------------------------------------------------------- extern PACKAGE TVecMapDialog *VecMapDialog; diff --git a/app/winapp/rtkpost/kmzconv.cpp b/app/winapp/rtkpost/kmzconv.cpp index 8e322c343..a8cf219b4 100644 --- a/app/winapp/rtkpost/kmzconv.cpp +++ b/app/winapp/rtkpost/kmzconv.cpp @@ -1,320 +1,308 @@ //--------------------------------------------------------------------------- -#include #include #include +#include #pragma hdrstop -#include "postmain.h" #include "kmzconv.h" -#include "viewer.h" + +#include "postmain.h" #include "rtklib.h" +#include "viewer.h" //--------------------------------------------------------------------------- #pragma package(smart_init) #pragma resource "*.dfm" TConvDialog *ConvDialog; //--------------------------------------------------------------------------- -static double str2dbl(AnsiString str) -{ - double val=0.0; - sscanf(str.c_str(),"%lf",&val); - return val; +static double str2dbl(AnsiString str) { + double val = 0.0; + sscanf(str.c_str(), "%lf", &val); + return val; } //--------------------------------------------------------------------------- -void __fastcall TConvDialog::FormShow(TObject *Sender) -{ - FormatGPX->Checked=!FormatKML->Checked && !FormatCSV->Checked; - GoogleEarthFile->Text=MainForm->GoogleEarthFile; +void __fastcall TConvDialog::FormShow(TObject *Sender) { + FormatGPX->Checked = !FormatKML->Checked && !FormatCSV->Checked; + GoogleEarthFile->Text = MainForm->GoogleEarthFile; } //--------------------------------------------------------------------------- -__fastcall TConvDialog::TConvDialog(TComponent* Owner) - : TForm(Owner) -{ - UpdateEnable(); -} +__fastcall TConvDialog::TConvDialog(TComponent *Owner) : TForm(Owner) { UpdateEnable(); } //--------------------------------------------------------------------------- -void __fastcall TConvDialog::SetInput(AnsiString File) -{ - InputFile->Text=File; - UpdateOutFile(); +void __fastcall TConvDialog::SetInput(AnsiString File) { + InputFile->Text = File; + UpdateOutFile(); } //--------------------------------------------------------------------------- -void __fastcall TConvDialog::TimeSpanClick(TObject *Sender) -{ - UpdateEnable(); -} +void __fastcall TConvDialog::TimeSpanClick(TObject *Sender) { UpdateEnable(); } //--------------------------------------------------------------------------- -void __fastcall TConvDialog::AddOffsetClick(TObject *Sender) -{ - UpdateEnable(); -} +void __fastcall TConvDialog::AddOffsetClick(TObject *Sender) { UpdateEnable(); } //--------------------------------------------------------------------------- -void __fastcall TConvDialog::TimeIntFClick(TObject *Sender) -{ - UpdateEnable(); -} +void __fastcall TConvDialog::TimeIntFClick(TObject *Sender) { UpdateEnable(); } //--------------------------------------------------------------------------- -void __fastcall TConvDialog::SingleMeanFClick(TObject *Sender) -{ - UpdateEnable(); -} +void __fastcall TConvDialog::SingleMeanFClick(TObject *Sender) { UpdateEnable(); } //--------------------------------------------------------------------------- -void __fastcall TConvDialog::BtnInputFileClick(TObject *Sender) -{ - OpenDialog->FileName=InputFile->Text; - if (!OpenDialog->Execute()) return; - InputFile->Text=OpenDialog->FileName; +void __fastcall TConvDialog::BtnInputFileClick(TObject *Sender) { + OpenDialog->FileName = InputFile->Text; + if (!OpenDialog->Execute()) return; + InputFile->Text = OpenDialog->FileName; } //--------------------------------------------------------------------------- -void __fastcall TConvDialog::BtnGoogleClick(TObject *Sender) -{ - AnsiString OutputFile_Text=OutputFile->Text; - char cmd[1024]; - sprintf(cmd,"\"%s\" \"%s\"",MainForm->GoogleEarthFile.c_str(),OutputFile_Text.c_str()); - if (!ExecCmd(cmd)) ShowMsg("error : google earth execution"); +void __fastcall TConvDialog::BtnGoogleClick(TObject *Sender) { + AnsiString OutputFile_Text = OutputFile->Text; + char cmd[1024]; + sprintf(cmd, "\"%s\" \"%s\"", MainForm->GoogleEarthFile.c_str(), OutputFile_Text.c_str()); + if (!ExecCmd(cmd)) ShowMsg("error : google earth execution"); } //--------------------------------------------------------------------------- -void __fastcall TConvDialog::BtnConvertClick(TObject *Sender) -{ - AnsiString TimeY1_Text=TimeY1->Text,TimeH1_Text=TimeH1->Text; - AnsiString TimeY2_Text=TimeY2->Text,TimeH2_Text=TimeH2->Text; - AnsiString InputFile_Text=InputFile->Text,OutputFile_Text=OutputFile->Text; - int stat; - char cmd[1024],file[1024],kmlfile[1024],*p; - double offset[3]={0},es[6]={1970,1,1},ee[6]={2038,1,1},tint=0.0; - gtime_t ts={0},te={0}; - - ShowMsg(""); - if (InputFile->Text==""||OutputFile->Text=="") return; - ShowMsg("converting ..."); - if (TimeSpan->Checked) { - sscanf(TimeY1_Text.c_str(),"%lf/%lf/%lf",es ,es+1,es+2); - sscanf(TimeH1_Text.c_str(),"%lf:%lf:%lf",es+3,es+4,es+5); - sscanf(TimeY2_Text.c_str(),"%lf/%lf/%lf",ee ,ee+1,ee+2); - sscanf(TimeH2_Text.c_str(),"%lf:%lf:%lf",ee+3,ee+4,ee+5); - ts=epoch2time(es); - te=epoch2time(ee); - } - if (AddOffset->Checked) { - offset[0]=str2dbl(Offset1->Text); - offset[1]=str2dbl(Offset2->Text); - offset[2]=str2dbl(Offset3->Text); - } - if (TimeIntF->Checked) tint=str2dbl(TimeInt->Text); - int mean = SingleMeanF->Checked ? 1 : 0; - char *name = NULL; // TODO - int csvorder = 0; // TODO - strcpy(file,InputFile_Text.c_str()); - if (FormatKML->Checked) { - if (Compress->Checked) { - strcpy(kmlfile,file); - if (!(p=strrchr(kmlfile,'.'))) p=kmlfile+strlen(kmlfile); - strcpy(p,".kml"); - } - stat=convkml(file,Compress->Checked?kmlfile:OutputFile_Text.c_str(), - ts,te,tint,QFlags->ItemIndex,mean,name,offset, - TrackColor->ItemIndex,PointColor->ItemIndex, - OutputAlt->ItemIndex,OutputTime->ItemIndex); - } - else if (FormatCSV->Checked) { - stat=convcsv(file,Compress->Checked?kmlfile:OutputFile_Text.c_str(), - ts,te,tint,QFlags->ItemIndex,mean,name,offset, - OutputAlt->ItemIndex,OutputTime->ItemIndex, - csvorder); - } - else { - stat=convgpx(file,Compress->Checked?kmlfile:OutputFile_Text.c_str(), - ts,te,tint,QFlags->ItemIndex,mean,name,offset, - TrackColor->ItemIndex,PointColor->ItemIndex, - OutputAlt->ItemIndex,OutputTime->ItemIndex); - } - if (stat<0) { - if (stat==-1) ShowMsg("error : read input file"); - else if (stat==-2) ShowMsg("error : input file format"); - else if (stat==-3) ShowMsg("error : no data in input file"); - else ShowMsg("error : write kml file"); - return; - } - if (FormatKML->Checked&&Compress->Checked) { - sprintf(cmd,"zip.exe -j -m %s %s",OutputFile_Text.c_str(),kmlfile); - if (!ExecCmd(cmd)) { - ShowMsg("error : zip execution"); - return; - } - } - ShowMsg("done"); +void __fastcall TConvDialog::BtnConvertClick(TObject *Sender) { + AnsiString TimeY1_Text = TimeY1->Text, TimeH1_Text = TimeH1->Text; + AnsiString TimeY2_Text = TimeY2->Text, TimeH2_Text = TimeH2->Text; + AnsiString InputFile_Text = InputFile->Text, OutputFile_Text = OutputFile->Text; + int stat; + char cmd[1024], file[1024], kmlfile[1024], *p; + double offset[3] = {0}, es[6] = {1970, 1, 1}, ee[6] = {2038, 1, 1}, tint = 0.0; + gtime_t ts = {0}, te = {0}; + + ShowMsg(""); + if (InputFile->Text == "" || OutputFile->Text == "") return; + ShowMsg("converting ..."); + if (TimeSpan->Checked) { + sscanf(TimeY1_Text.c_str(), "%lf/%lf/%lf", es, es + 1, es + 2); + sscanf(TimeH1_Text.c_str(), "%lf:%lf:%lf", es + 3, es + 4, es + 5); + sscanf(TimeY2_Text.c_str(), "%lf/%lf/%lf", ee, ee + 1, ee + 2); + sscanf(TimeH2_Text.c_str(), "%lf:%lf:%lf", ee + 3, ee + 4, ee + 5); + ts = epoch2time(es); + te = epoch2time(ee); + } + if (AddOffset->Checked) { + offset[0] = str2dbl(Offset1->Text); + offset[1] = str2dbl(Offset2->Text); + offset[2] = str2dbl(Offset3->Text); + } + if (TimeIntF->Checked) tint = str2dbl(TimeInt->Text); + int mean = SingleMeanF->Checked ? 1 : 0; + char *name = NULL; // TODO + int csvorder = 0; // TODO + strcpy(file, InputFile_Text.c_str()); + if (FormatKML->Checked) { + if (Compress->Checked) { + strcpy(kmlfile, file); + if (!(p = strrchr(kmlfile, '.'))) p = kmlfile + strlen(kmlfile); + strcpy(p, ".kml"); + } + stat = convkml(file, Compress->Checked ? kmlfile : OutputFile_Text.c_str(), ts, te, tint, + QFlags->ItemIndex, mean, name, offset, TrackColor->ItemIndex, + PointColor->ItemIndex, OutputAlt->ItemIndex, OutputTime->ItemIndex); + } else if (FormatCSV->Checked) { + stat = convcsv(file, Compress->Checked ? kmlfile : OutputFile_Text.c_str(), ts, te, tint, + QFlags->ItemIndex, mean, name, offset, OutputAlt->ItemIndex, + OutputTime->ItemIndex, csvorder); + } else { + stat = convgpx(file, Compress->Checked ? kmlfile : OutputFile_Text.c_str(), ts, te, tint, + QFlags->ItemIndex, mean, name, offset, TrackColor->ItemIndex, + PointColor->ItemIndex, OutputAlt->ItemIndex, OutputTime->ItemIndex); + } + if (stat < 0) { + if (stat == -1) + ShowMsg("error : read input file"); + else if (stat == -2) + ShowMsg("error : input file format"); + else if (stat == -3) + ShowMsg("error : no data in input file"); + else + ShowMsg("error : write kml file"); + return; + } + if (FormatKML->Checked && Compress->Checked) { + sprintf(cmd, "zip.exe -j -m %s %s", OutputFile_Text.c_str(), kmlfile); + if (!ExecCmd(cmd)) { + ShowMsg("error : zip execution"); + return; + } + } + ShowMsg("done"); } //--------------------------------------------------------------------------- -void __fastcall TConvDialog::BtnCloseClick(TObject *Sender) -{ - Close(); -} +void __fastcall TConvDialog::BtnCloseClick(TObject *Sender) { Close(); } //--------------------------------------------------------------------------- -void __fastcall TConvDialog::CompressClick(TObject *Sender) -{ - UpdateOutFile(); -} +void __fastcall TConvDialog::CompressClick(TObject *Sender) { UpdateOutFile(); } //--------------------------------------------------------------------------- -void __fastcall TConvDialog::UpdateEnable(void) -{ - Offset1->Enabled=AddOffset->Checked; - Offset2->Enabled=AddOffset->Checked; - Offset3->Enabled=AddOffset->Checked; - TimeY1->Enabled=TimeSpan->Checked; - TimeH1->Enabled=TimeSpan->Checked; - TimeY2->Enabled=TimeSpan->Checked; - TimeH2->Enabled=TimeSpan->Checked; - TimeY1UD->Enabled=TimeSpan->Checked; - TimeH1UD->Enabled=TimeSpan->Checked; - TimeY2UD->Enabled=TimeSpan->Checked; - TimeH2UD->Enabled=TimeSpan->Checked; - TimeInt->Enabled=TimeIntF->Checked; - TrackColor->Enabled=!FormatCSV->Checked; - PointColor->Enabled=!FormatCSV->Checked; - BtnGoogle->Visible=FormatKML->Checked; - Compress->Visible=FormatKML->Checked; - GoogleEarthFile->Enabled=FormatKML->Checked; - BtnGoogleEarthFile->Enabled=FormatKML->Checked; +void __fastcall TConvDialog::UpdateEnable(void) { + Offset1->Enabled = AddOffset->Checked; + Offset2->Enabled = AddOffset->Checked; + Offset3->Enabled = AddOffset->Checked; + TimeY1->Enabled = TimeSpan->Checked; + TimeH1->Enabled = TimeSpan->Checked; + TimeY2->Enabled = TimeSpan->Checked; + TimeH2->Enabled = TimeSpan->Checked; + TimeY1UD->Enabled = TimeSpan->Checked; + TimeH1UD->Enabled = TimeSpan->Checked; + TimeY2UD->Enabled = TimeSpan->Checked; + TimeH2UD->Enabled = TimeSpan->Checked; + TimeInt->Enabled = TimeIntF->Checked; + TrackColor->Enabled = !FormatCSV->Checked; + PointColor->Enabled = !FormatCSV->Checked; + BtnGoogle->Visible = FormatKML->Checked; + Compress->Visible = FormatKML->Checked; + GoogleEarthFile->Enabled = FormatKML->Checked; + BtnGoogleEarthFile->Enabled = FormatKML->Checked; } //--------------------------------------------------------------------------- -int __fastcall TConvDialog::ExecCmd(char *cmd) -{ - STARTUPINFO si={0}; - PROCESS_INFORMATION info; - si.cb=sizeof(si); - if (!CreateProcess(NULL,cmd,NULL,NULL,false,CREATE_NO_WINDOW,NULL,NULL,&si, - &info)) return 0; - CloseHandle(info.hProcess); - CloseHandle(info.hThread); - return 1; +int __fastcall TConvDialog::ExecCmd(char *cmd) { + STARTUPINFO si = {0}; + PROCESS_INFORMATION info; + si.cb = sizeof(si); + if (!CreateProcess(NULL, cmd, NULL, NULL, false, CREATE_NO_WINDOW, NULL, NULL, &si, &info)) + return 0; + CloseHandle(info.hProcess); + CloseHandle(info.hThread); + return 1; } //--------------------------------------------------------------------------- -void __fastcall TConvDialog::ShowMsg(AnsiString msg) -{ - Message->Caption=msg; - if (strstr(msg.c_str(),"error")) Message->Font->Color=clRed; - else Message->Font->Color=clBlue; - Application->ProcessMessages(); +void __fastcall TConvDialog::ShowMsg(AnsiString msg) { + Message->Caption = msg; + if (strstr(msg.c_str(), "error")) + Message->Font->Color = clRed; + else + Message->Font->Color = clBlue; + Application->ProcessMessages(); } //--------------------------------------------------------------------------- -void __fastcall TConvDialog::InputFileChange(TObject *Sender) -{ - UpdateOutFile(); -} +void __fastcall TConvDialog::InputFileChange(TObject *Sender) { UpdateOutFile(); } //--------------------------------------------------------------------------- -void __fastcall TConvDialog::UpdateOutFile(void) -{ - AnsiString InputFile_Text=InputFile->Text; - char file[256],*p; - if (InputFile->Text=="") return; - strcpy(file,InputFile_Text.c_str()); - if (!(p=strrchr(file,'.'))) p=file+strlen(file); - strcpy(p,FormatGPX->Checked?".gpx":(FormatCSV->Checked?".csv":(Compress->Checked?".kmz":".kml"))); - OutputFile->Text=file; +void __fastcall TConvDialog::UpdateOutFile(void) { + AnsiString InputFile_Text = InputFile->Text; + char file[256], *p; + if (InputFile->Text == "") return; + strcpy(file, InputFile_Text.c_str()); + if (!(p = strrchr(file, '.'))) p = file + strlen(file); + strcpy(p, FormatGPX->Checked + ? ".gpx" + : (FormatCSV->Checked ? ".csv" : (Compress->Checked ? ".kmz" : ".kml"))); + OutputFile->Text = file; } //--------------------------------------------------------------------------- -void __fastcall TConvDialog::TimeY1UDChangingEx(TObject *Sender, - bool &AllowChange, int NewValue, TUpDownDirection Direction) -{ - AnsiString TimeY1_Text=TimeY1->Text,s; - double ep[]={2000,1,1,0,0,0}; - int p=TimeY1->SelStart,ud=Direction==updUp?1:-1; - sscanf(TimeY1_Text.c_str(),"%lf/%lf/%lf",ep,ep+1,ep+2); - if (412) {ep[0]++; ep[1]-=12;} - } - else if (p>7||p==0) ep[2]+=ud; else ep[0]+=ud; - time2epoch(epoch2time(ep),ep); - TimeY1->Text=s.sprintf("%04.0f/%02.0f/%02.0f",ep[0],ep[1],ep[2]); - TimeY1->SelStart=p>7||p==0?10:(p>4?7:4); +void __fastcall TConvDialog::TimeY1UDChangingEx(TObject *Sender, bool &AllowChange, int NewValue, + TUpDownDirection Direction) { + AnsiString TimeY1_Text = TimeY1->Text, s; + double ep[] = {2000, 1, 1, 0, 0, 0}; + int p = TimeY1->SelStart, ud = Direction == updUp ? 1 : -1; + sscanf(TimeY1_Text.c_str(), "%lf/%lf/%lf", ep, ep + 1, ep + 2); + if (4 < p && p < 8) { + ep[1] += ud; + if (ep[1] <= 0) { + ep[0]--; + ep[1] += 12; + } else if (ep[1] > 12) { + ep[0]++; + ep[1] -= 12; + } + } else if (p > 7 || p == 0) + ep[2] += ud; + else + ep[0] += ud; + time2epoch(epoch2time(ep), ep); + TimeY1->Text = s.sprintf("%04.0f/%02.0f/%02.0f", ep[0], ep[1], ep[2]); + TimeY1->SelStart = p > 7 || p == 0 ? 10 : (p > 4 ? 7 : 4); } //--------------------------------------------------------------------------- -void __fastcall TConvDialog::TimeH1UDChangingEx(TObject *Sender, - bool &AllowChange, int NewValue, TUpDownDirection Direction) -{ - AnsiString TimeH1_Text=TimeH1->Text,s; - int hms[3]={0},sec,p=TimeH1->SelStart,ud=Direction==updUp?1:-1; - sscanf(TimeH1_Text.c_str(),"%d:%d:%d",hms,hms+1,hms+2); - if (p>5||p==0) hms[2]+=ud; else if (p>2) hms[1]+=ud; else hms[0]+=ud; - sec=hms[0]*3600+hms[1]*60+hms[2]; - if (sec<0) sec+=86400; else if (sec>=86400) sec-=86400; - TimeH1->Text=s.sprintf("%02d:%02d:%02d",sec/3600,(sec%3600)/60,sec%60); - TimeH1->SelStart=p>5||p==0?8:(p>2?5:2); +void __fastcall TConvDialog::TimeH1UDChangingEx(TObject *Sender, bool &AllowChange, int NewValue, + TUpDownDirection Direction) { + AnsiString TimeH1_Text = TimeH1->Text, s; + int hms[3] = {0}, sec, p = TimeH1->SelStart, ud = Direction == updUp ? 1 : -1; + sscanf(TimeH1_Text.c_str(), "%d:%d:%d", hms, hms + 1, hms + 2); + if (p > 5 || p == 0) + hms[2] += ud; + else if (p > 2) + hms[1] += ud; + else + hms[0] += ud; + sec = hms[0] * 3600 + hms[1] * 60 + hms[2]; + if (sec < 0) + sec += 86400; + else if (sec >= 86400) + sec -= 86400; + TimeH1->Text = s.sprintf("%02d:%02d:%02d", sec / 3600, (sec % 3600) / 60, sec % 60); + TimeH1->SelStart = p > 5 || p == 0 ? 8 : (p > 2 ? 5 : 2); } //--------------------------------------------------------------------------- -void __fastcall TConvDialog::TimeY2UDChangingEx(TObject *Sender, - bool &AllowChange, int NewValue, TUpDownDirection Direction) -{ - AnsiString TimeY2_Text=TimeY2->Text,s; - double ep[]={2000,1,1,0,0,0}; - int p=TimeY2->SelStart,ud=Direction==updUp?1:-1; - sscanf(TimeY2_Text.c_str(),"%lf/%lf/%lf",ep,ep+1,ep+2); - if (412) {ep[0]++; ep[1]-=12;} - } - else if (p>7||p==0) ep[2]+=ud; else ep[0]+=ud; - time2epoch(epoch2time(ep),ep); - TimeY2->Text=s.sprintf("%04.0f/%02.0f/%02.0f",ep[0],ep[1],ep[2]); - TimeY2->SelStart=p>7||p==0?10:(p>4?7:4); +void __fastcall TConvDialog::TimeY2UDChangingEx(TObject *Sender, bool &AllowChange, int NewValue, + TUpDownDirection Direction) { + AnsiString TimeY2_Text = TimeY2->Text, s; + double ep[] = {2000, 1, 1, 0, 0, 0}; + int p = TimeY2->SelStart, ud = Direction == updUp ? 1 : -1; + sscanf(TimeY2_Text.c_str(), "%lf/%lf/%lf", ep, ep + 1, ep + 2); + if (4 < p && p < 8) { + ep[1] += ud; + if (ep[1] <= 0) { + ep[0]--; + ep[1] += 12; + } else if (ep[1] > 12) { + ep[0]++; + ep[1] -= 12; + } + } else if (p > 7 || p == 0) + ep[2] += ud; + else + ep[0] += ud; + time2epoch(epoch2time(ep), ep); + TimeY2->Text = s.sprintf("%04.0f/%02.0f/%02.0f", ep[0], ep[1], ep[2]); + TimeY2->SelStart = p > 7 || p == 0 ? 10 : (p > 4 ? 7 : 4); } //--------------------------------------------------------------------------- -void __fastcall TConvDialog::TimeH2UDChangingEx(TObject *Sender, - bool &AllowChange, int NewValue, TUpDownDirection Direction) -{ - AnsiString TimeH2_Text=TimeH2->Text,s; - int hms[3]={0},sec,p=TimeH2->SelStart,ud=Direction==updUp?1:-1; - sscanf(TimeH2_Text.c_str(),"%d:%d:%d",hms,hms+1,hms+2); - if (p>5||p==0) hms[2]+=ud; else if (p>2) hms[1]+=ud; else hms[0]+=ud; - sec=hms[0]*3600+hms[1]*60+hms[2]; - if (sec<0) sec+=86400; else if (sec>=86400) sec-=86400; - TimeH2->Text=s.sprintf("%02d:%02d:%02d",sec/3600,(sec%3600)/60,sec%60); - TimeH2->SelStart=p>5||p==0?8:(p>2?5:2); +void __fastcall TConvDialog::TimeH2UDChangingEx(TObject *Sender, bool &AllowChange, int NewValue, + TUpDownDirection Direction) { + AnsiString TimeH2_Text = TimeH2->Text, s; + int hms[3] = {0}, sec, p = TimeH2->SelStart, ud = Direction == updUp ? 1 : -1; + sscanf(TimeH2_Text.c_str(), "%d:%d:%d", hms, hms + 1, hms + 2); + if (p > 5 || p == 0) + hms[2] += ud; + else if (p > 2) + hms[1] += ud; + else + hms[0] += ud; + sec = hms[0] * 3600 + hms[1] * 60 + hms[2]; + if (sec < 0) + sec += 86400; + else if (sec >= 86400) + sec -= 86400; + TimeH2->Text = s.sprintf("%02d:%02d:%02d", sec / 3600, (sec % 3600) / 60, sec % 60); + TimeH2->SelStart = p > 5 || p == 0 ? 8 : (p > 2 ? 5 : 2); } //--------------------------------------------------------------------------- -void __fastcall TConvDialog::GoogleEarthFileChange(TObject *Sender) -{ - MainForm->GoogleEarthFile=GoogleEarthFile->Text; +void __fastcall TConvDialog::GoogleEarthFileChange(TObject *Sender) { + MainForm->GoogleEarthFile = GoogleEarthFile->Text; } //--------------------------------------------------------------------------- -void __fastcall TConvDialog::BtnGoogleEarthFileClick(TObject *Sender) -{ - OpenDialog->Title="Google Earth Exe File"; - OpenDialog->FilterIndex=8; - if (!OpenDialog->Execute()) return; - GoogleEarthFile->Text=OpenDialog->FileName; +void __fastcall TConvDialog::BtnGoogleEarthFileClick(TObject *Sender) { + OpenDialog->Title = "Google Earth Exe File"; + OpenDialog->FilterIndex = 8; + if (!OpenDialog->Execute()) return; + GoogleEarthFile->Text = OpenDialog->FileName; } //--------------------------------------------------------------------------- -void __fastcall TConvDialog::FormatKMLClick(TObject *Sender) -{ - UpdateOutFile(); - UpdateEnable(); +void __fastcall TConvDialog::FormatKMLClick(TObject *Sender) { + UpdateOutFile(); + UpdateEnable(); } //--------------------------------------------------------------------------- -void __fastcall TConvDialog::FormatCSVClick(TObject *Sender) -{ - UpdateOutFile(); - UpdateEnable(); +void __fastcall TConvDialog::FormatCSVClick(TObject *Sender) { + UpdateOutFile(); + UpdateEnable(); } //--------------------------------------------------------------------------- -void __fastcall TConvDialog::FormatGPXClick(TObject *Sender) -{ - UpdateOutFile(); - UpdateEnable(); +void __fastcall TConvDialog::FormatGPXClick(TObject *Sender) { + UpdateOutFile(); + UpdateEnable(); } //--------------------------------------------------------------------------- -void __fastcall TConvDialog::BtnViewClick(TObject *Sender) -{ - AnsiString file=OutputFile->Text; - TTextViewer *viewer; - - if (file=="") return; - viewer=new TTextViewer(Application); - viewer->Caption=file; - viewer->Show(); - viewer->Read(file); +void __fastcall TConvDialog::BtnViewClick(TObject *Sender) { + AnsiString file = OutputFile->Text; + TTextViewer *viewer; + + if (file == "") return; + viewer = new TTextViewer(Application); + viewer->Caption = file; + viewer->Show(); + viewer->Read(file); } //--------------------------------------------------------------------------- - diff --git a/app/winapp/rtkpost/kmzconv.h b/app/winapp/rtkpost/kmzconv.h index c91ad7d44..455b94fc6 100644 --- a/app/winapp/rtkpost/kmzconv.h +++ b/app/winapp/rtkpost/kmzconv.h @@ -4,94 +4,94 @@ #define kmzconvH //--------------------------------------------------------------------------- #include +#include #include -#include -#include -#include #include -#include +#include +#include +#include #include //--------------------------------------------------------------------------- -class TConvDialog : public TForm -{ -__published: - TButton *BtnClose; - TButton *BtnConvert; - TPanel *Panel1; - TLabel *Label1; - TComboBox *TrackColor; - TLabel *Label2; - TComboBox *PointColor; - TLabel *Label3; - TComboBox *OutputAlt; - TCheckBox *AddOffset; - TEdit *Offset1; - TEdit *Offset2; - TEdit *Offset3; - TButton *BtnGoogle; - TComboBox *OutputTime; - TLabel *Label4; - TLabel *Label5; - TEdit *TimeInt; - TEdit *TimeY1; - TEdit *TimeH1; - TCheckBox *TimeSpan; - TEdit *TimeY2; - TEdit *TimeH2; - TComboBox *QFlags; - TCheckBox *TimeIntF; - TCheckBox *SingleMeanF; - TEdit *OutputFile; - TEdit *InputFile; - TLabel *Label7; - TButton *BtnInputFile; - TOpenDialog *OpenDialog; - TPanel *Message; - TUpDown *TimeY1UD; - TUpDown *TimeH1UD; - TUpDown *TimeY2UD; - TUpDown *TimeH2UD; - TCheckBox *Compress; - TEdit *GoogleEarthFile; - TButton *BtnGoogleEarthFile; - TRadioButton *FormatKML; - TLabel *Label6; - TRadioButton *FormatCSV; - TRadioButton *FormatGPX; - TBitBtn *BtnView; - void __fastcall BtnCloseClick(TObject *Sender); - void __fastcall AddOffsetClick(TObject *Sender); - void __fastcall BtnConvertClick(TObject *Sender); - void __fastcall BtnGoogleClick(TObject *Sender); - void __fastcall TimeSpanClick(TObject *Sender); - void __fastcall TimeIntFClick(TObject *Sender); - void __fastcall SingleMeanFClick(TObject *Sender); - void __fastcall BtnInputFileClick(TObject *Sender); - void __fastcall InputFileChange(TObject *Sender); - void __fastcall TimeY1UDChangingEx(TObject *Sender, bool &AllowChange, - int NewValue, TUpDownDirection Direction); - void __fastcall TimeH1UDChangingEx(TObject *Sender, bool &AllowChange, - int NewValue, TUpDownDirection Direction); - void __fastcall TimeY2UDChangingEx(TObject *Sender, bool &AllowChange, - int NewValue, TUpDownDirection Direction); - void __fastcall TimeH2UDChangingEx(TObject *Sender, bool &AllowChange, - int NewValue, TUpDownDirection Direction); - void __fastcall CompressClick(TObject *Sender); - void __fastcall FormShow(TObject *Sender); - void __fastcall GoogleEarthFileChange(TObject *Sender); - void __fastcall BtnGoogleEarthFileClick(TObject *Sender); - void __fastcall FormatKMLClick(TObject *Sender); - void __fastcall FormatCSVClick(TObject *Sender); - void __fastcall FormatGPXClick(TObject *Sender); - void __fastcall BtnViewClick(TObject *Sender); -private: - int __fastcall ExecCmd(char *cmd); - void __fastcall UpdateEnable(void); - void __fastcall ShowMsg(AnsiString msg); - void __fastcall UpdateOutFile(void); -public: - __fastcall TConvDialog(TComponent* Owner); - void __fastcall SetInput(AnsiString File); +class TConvDialog : public TForm { + __published : TButton *BtnClose; + TButton *BtnConvert; + TPanel *Panel1; + TLabel *Label1; + TComboBox *TrackColor; + TLabel *Label2; + TComboBox *PointColor; + TLabel *Label3; + TComboBox *OutputAlt; + TCheckBox *AddOffset; + TEdit *Offset1; + TEdit *Offset2; + TEdit *Offset3; + TButton *BtnGoogle; + TComboBox *OutputTime; + TLabel *Label4; + TLabel *Label5; + TEdit *TimeInt; + TEdit *TimeY1; + TEdit *TimeH1; + TCheckBox *TimeSpan; + TEdit *TimeY2; + TEdit *TimeH2; + TComboBox *QFlags; + TCheckBox *TimeIntF; + TCheckBox *SingleMeanF; + TEdit *OutputFile; + TEdit *InputFile; + TLabel *Label7; + TButton *BtnInputFile; + TOpenDialog *OpenDialog; + TPanel *Message; + TUpDown *TimeY1UD; + TUpDown *TimeH1UD; + TUpDown *TimeY2UD; + TUpDown *TimeH2UD; + TCheckBox *Compress; + TEdit *GoogleEarthFile; + TButton *BtnGoogleEarthFile; + TRadioButton *FormatKML; + TLabel *Label6; + TRadioButton *FormatCSV; + TRadioButton *FormatGPX; + TBitBtn *BtnView; + void __fastcall BtnCloseClick(TObject *Sender); + void __fastcall AddOffsetClick(TObject *Sender); + void __fastcall BtnConvertClick(TObject *Sender); + void __fastcall BtnGoogleClick(TObject *Sender); + void __fastcall TimeSpanClick(TObject *Sender); + void __fastcall TimeIntFClick(TObject *Sender); + void __fastcall SingleMeanFClick(TObject *Sender); + void __fastcall BtnInputFileClick(TObject *Sender); + void __fastcall InputFileChange(TObject *Sender); + void __fastcall TimeY1UDChangingEx(TObject *Sender, bool &AllowChange, int NewValue, + TUpDownDirection Direction); + void __fastcall TimeH1UDChangingEx(TObject *Sender, bool &AllowChange, int NewValue, + TUpDownDirection Direction); + void __fastcall TimeY2UDChangingEx(TObject *Sender, bool &AllowChange, int NewValue, + TUpDownDirection Direction); + void __fastcall TimeH2UDChangingEx(TObject *Sender, bool &AllowChange, int NewValue, + TUpDownDirection Direction); + void __fastcall CompressClick(TObject *Sender); + void __fastcall FormShow(TObject *Sender); + void __fastcall GoogleEarthFileChange(TObject *Sender); + void __fastcall BtnGoogleEarthFileClick(TObject *Sender); + void __fastcall FormatKMLClick(TObject *Sender); + void __fastcall FormatCSVClick(TObject *Sender); + void __fastcall FormatGPXClick(TObject *Sender); + void __fastcall BtnViewClick(TObject *Sender); + + private: + int __fastcall ExecCmd(char *cmd); + void __fastcall UpdateEnable(void); + void __fastcall ShowMsg(AnsiString msg); + void __fastcall UpdateOutFile(void); + + public: + __fastcall TConvDialog(TComponent *Owner); + void __fastcall SetInput(AnsiString File); }; //--------------------------------------------------------------------------- extern PACKAGE TConvDialog *ConvDialog; diff --git a/app/winapp/rtkpost/postmain.cpp b/app/winapp/rtkpost/postmain.cpp index 1feccb1d3..434e1b2d1 100644 --- a/app/winapp/rtkpost/postmain.cpp +++ b/app/winapp/rtkpost/postmain.cpp @@ -28,22 +28,23 @@ // 2011/04/03 1.4 rtklib 2.4.2 // 2020/11/30 1.5 rtklib 2.4.3 //--------------------------------------------------------------------------- +#include #include #include #include -#include #include #pragma hdrstop -#include "rtklib.h" #include "postmain.h" -#include "postopt.h" + +#include "aboutdlg.h" +#include "confdlg.h" +#include "keydlg.h" #include "kmzconv.h" +#include "postopt.h" #include "refdlg.h" +#include "rtklib.h" #include "timedlg.h" -#include "confdlg.h" -#include "keydlg.h" -#include "aboutdlg.h" #include "viewer.h" #pragma package(smart_init) @@ -51,1793 +52,1757 @@ TMainForm *MainForm; -#define PRGNAME "RTKPOST" -#define MAXHIST 20 +#define PRGNAME "RTKPOST" +#define MAXHIST 20 #define GOOGLE_EARTH "C:\\Program Files\\Google\\Google Earth Pro\\client\\googleearth.exe" // global variables --------------------------------------------------------- -static gtime_t tstart_={0}; // time start for progress-bar -static gtime_t tend_ ={0}; // time end for progress-bar -static char rov_ [256]=""; // rover name -static char base_[256]=""; // base-station name +static gtime_t tstart_ = {0}; // time start for progress-bar +static gtime_t tend_ = {0}; // time end for progress-bar +static char rov_[256] = ""; // rover name +static char base_[256] = ""; // base-station name extern "C" { // show message in message area --------------------------------------------- -extern int showmsg(const char *format, ...) -{ - va_list arg; - char buff[1024]; - if (*format) { - va_start(arg,format); - vsprintf(buff,format,arg); - va_end(arg); - MainForm->ShowMsg(buff); - } - else Application->ProcessMessages(); - return MainForm->AbortFlag; +extern int showmsg(const char *format, ...) { + va_list arg; + char buff[1024]; + if (*format) { + va_start(arg, format); + vsprintf(buff, format, arg); + va_end(arg); + MainForm->ShowMsg(buff); + } else + Application->ProcessMessages(); + return MainForm->AbortFlag; } // set time span of progress bar -------------------------------------------- -extern void settspan(gtime_t ts, gtime_t te) -{ - tstart_=ts; - tend_ =te; +extern void settspan(gtime_t ts, gtime_t te) { + tstart_ = ts; + tend_ = te; } // set current time to show progress ---------------------------------------- -extern void settime(gtime_t time) -{ - static int i=0; - double tt; - if (tend_.time!=0&&tstart_.time!=0&&(tt=timediff(tend_,tstart_))>0.0) { - MainForm->Progress->Position=(int)(timediff(time,tstart_)/tt*100.0+0.5); - } - if (i++%23==0) Application->ProcessMessages(); +extern void settime(gtime_t time) { + static int i = 0; + double tt; + if (tend_.time != 0 && tstart_.time != 0 && (tt = timediff(tend_, tstart_)) > 0.0) { + MainForm->Progress->Position = (int)(timediff(time, tstart_) / tt * 100.0 + 0.5); + } + if (i++ % 23 == 0) Application->ProcessMessages(); } -} // extern "C" +} // extern "C" // convert string to double ------------------------------------------------- -static double str2dbl(AnsiString str) -{ - double val=0.0; - sscanf(str.c_str(),"%lf",&val); - return val; +static double str2dbl(AnsiString str) { + double val = 0.0; + sscanf(str.c_str(), "%lf", &val); + return val; } // constructor -------------------------------------------------------------- -__fastcall TMainForm::TMainForm(TComponent* Owner) - : TForm(Owner) -{ - char file[1024]="rtkpost.exe",*p; - int i; - - ::GetModuleFileName(NULL,file,sizeof(file)); - if (!(p=strrchr(file,'.'))) p=file+strlen(file); - strcpy(p,".ini"); - IniFile=file; - - DynamicModel=IonoOpt=TropOpt=RovAntPcv=RefAntPcv=AmbRes=0; - RovPosType=RefPosType=0; - OutCntResetAmb=5; LockCntFixAmb=5; FixCntHoldAmb=10; - MaxAgeDiff=30.0; RejectPhase=30.0; RejectCode=30.0; - MeasErrR1=MeasErrR2=MeasErrR5=MeasErrR6=100.0; - MeasErr2=0.004;MeasErr3=0.003; MeasErr4=1.0; - SatClkStab=1E-11; ValidThresAR=3.0; ValidThresARMin=3.0; ValidThresARMax=3.0; - RovAntE=RovAntN=RovAntU=RefAntE=RefAntN=RefAntU=0.0; - for (i=0;i<3;i++) RovPos[i]=0.0; - for (i=0;i<3;i++) RefPos[i]=0.0; - - DoubleBuffered=true; +__fastcall TMainForm::TMainForm(TComponent *Owner) : TForm(Owner) { + char file[1024] = "rtkpost.exe", *p; + int i; + + ::GetModuleFileName(NULL, file, sizeof(file)); + if (!(p = strrchr(file, '.'))) p = file + strlen(file); + strcpy(p, ".ini"); + IniFile = file; + + DynamicModel = IonoOpt = TropOpt = RovAntPcv = RefAntPcv = AmbRes = 0; + RovPosType = RefPosType = 0; + OutCntResetAmb = 5; + LockCntFixAmb = 5; + FixCntHoldAmb = 10; + MaxAgeDiff = 30.0; + RejectPhase = 30.0; + RejectCode = 30.0; + MeasErrR1 = MeasErrR2 = MeasErrR5 = MeasErrR6 = 100.0; + MeasErr2 = 0.004; + MeasErr3 = 0.003; + MeasErr4 = 1.0; + SatClkStab = 1E-11; + ValidThresAR = 3.0; + ValidThresARMin = 3.0; + ValidThresARMax = 3.0; + RovAntE = RovAntN = RovAntU = RefAntE = RefAntN = RefAntU = 0.0; + for (i = 0; i < 3; i++) RovPos[i] = 0.0; + for (i = 0; i < 3; i++) RefPos[i] = 0.0; + + DoubleBuffered = true; } // callback on form create -------------------------------------------------- -void __fastcall TMainForm::FormCreate(TObject *Sender) -{ - AnsiString s; - - Caption=s.sprintf("%s-%s %s",PRGNAME,VER_RTKLIB,PATCH_LEVEL); - - ::DragAcceptFiles(Handle,true); +void __fastcall TMainForm::FormCreate(TObject *Sender) { + AnsiString s; + + Caption = s.sprintf("%s-%s %s", PRGNAME, VER_RTKLIB, PATCH_LEVEL); + + ::DragAcceptFiles(Handle, true); } // callback on form show ---------------------------------------------------- -void __fastcall TMainForm::FormShow(TObject *Sender) -{ - TComboBox *ifile[]={InputFile3,InputFile4,InputFile5,InputFile6, - InputFile7,InputFile8,InputFile9,InputFile10}; - char *p,*argv[32],buff[1024]; - int argc=0,n=0,inputflag=0;; - - strcpy(buff,GetCommandLine()); - - for (p=buff;*p&&argc<32;p++) { - if (*p==' ') continue; - if (*p=='"') { - argv[argc++]=p+1; - if (!(p=strchr(p+1,'"'))) break; - } - else { - argv[argc++]=p; - if (!(p=strchr(p+1,' '))) break; - } - *p='\0'; - } - for (int i=1;iText=argv[++i]; - inputflag=1; - } - else if (!strcmp(argv[i],"-b")&&i+1Text=argv[++i]; - else if (!strcmp(argv[i],"-d")&&i+1Checked=true; - OutDir->Text=argv[++i]; - } - else if (!strcmp(argv[i],"-o")&&i+1Text=argv[++i]; - else if (!strcmp(argv[i],"-n")&&i+1Text=argv[++i]; - } - else if (!strcmp(argv[i],"-ts")&&i+2Checked=true; - TimeY1->Text=argv[++i]; TimeH1->Text=argv[++i]; - } - else if (!strcmp(argv[i],"-te")&&i+2Checked=true; - TimeY2->Text=argv[++i]; TimeH2->Text=argv[++i]; - } - else if (!strcmp(argv[i],"-ti")&&i+1Checked=true; - TimeInt->Text=argv[++i]; - } - else if (!strcmp(argv[i],"-tu")&&i+1Checked=true; - TimeUnit->Text=argv[++i]; - } - } - if (inputflag) SetOutFile(); - - UpdateEnable(); - DisableHighlight(); +void __fastcall TMainForm::FormShow(TObject *Sender) { + TComboBox *ifile[] = {InputFile3, InputFile4, InputFile5, InputFile6, + InputFile7, InputFile8, InputFile9, InputFile10}; + char *p, *argv[32], buff[1024]; + int argc = 0, n = 0, inputflag = 0; + ; + + strcpy(buff, GetCommandLine()); + + for (p = buff; *p && argc < 32; p++) { + if (*p == ' ') continue; + if (*p == '"') { + argv[argc++] = p + 1; + if (!(p = strchr(p + 1, '"'))) break; + } else { + argv[argc++] = p; + if (!(p = strchr(p + 1, ' '))) break; + } + *p = '\0'; + } + for (int i = 1; i < argc; i++) { // get ini file option + if (!strcmp(argv[i], "-i") && i + 1 < argc) IniFile = argv[++i]; + } + LoadOpt(); + + for (int i = 1; i < argc; i++) { + if (!strcmp(argv[i], "-t") && i + 1 < argc) + Caption = argv[++i]; + else if (!strcmp(argv[i], "-r") && i + 1 < argc) { + InputFile1->Text = argv[++i]; + inputflag = 1; + } else if (!strcmp(argv[i], "-b") && i + 1 < argc) + InputFile2->Text = argv[++i]; + else if (!strcmp(argv[i], "-d") && i + 1 < argc) { + OutDirEna->Checked = true; + OutDir->Text = argv[++i]; + } else if (!strcmp(argv[i], "-o") && i + 1 < argc) + OutputFile->Text = argv[++i]; + else if (!strcmp(argv[i], "-n") && i + 1 < argc) { + if (n < 8) ifile[n++]->Text = argv[++i]; + } else if (!strcmp(argv[i], "-ts") && i + 2 < argc) { + TimeStart->Checked = true; + TimeY1->Text = argv[++i]; + TimeH1->Text = argv[++i]; + } else if (!strcmp(argv[i], "-te") && i + 2 < argc) { + TimeEnd->Checked = true; + TimeY2->Text = argv[++i]; + TimeH2->Text = argv[++i]; + } else if (!strcmp(argv[i], "-ti") && i + 1 < argc) { + TimeIntF->Checked = true; + TimeInt->Text = argv[++i]; + } else if (!strcmp(argv[i], "-tu") && i + 1 < argc) { + TimeUnitF->Checked = true; + TimeUnit->Text = argv[++i]; + } + } + if (inputflag) SetOutFile(); + + UpdateEnable(); + DisableHighlight(); } // callback on form close --------------------------------------------------- -void __fastcall TMainForm::FormClose(TObject *Sender, TCloseAction &Action) -{ - SaveOpt(); -} +void __fastcall TMainForm::FormClose(TObject *Sender, TCloseAction &Action) { SaveOpt(); } // callback on drop files --------------------------------------------------- -void __fastcall TMainForm::DropFiles(TWMDropFiles msg) -{ - POINT point={0}; - int top,y; - char *p,file[1024]; - - if (DragQueryFile((HDROP)msg.Drop,0xFFFFFFFF,NULL,0)<=0) return; - DragQueryFile((HDROP)msg.Drop,0,file,sizeof(file)); - if (!DragQueryPoint((HDROP)msg.Drop,&point)) return; - - y=point.y; - top=Panel1->Top+Panel4->Top; - if (y<=top+InputFile1->Top+InputFile1->Height) { - InputFile1->Text=file; - SetOutFile(); - } - else if (y<=top+InputFile2->Top+InputFile2->Height) { - InputFile2->Text=file; - } - else if (y<=top+InputFile3->Top+InputFile3->Height) { - InputFile3->Text=file; - } - else if (y<=top+InputFile4->Top+InputFile4->Height) { - InputFile4->Text=file; - } - else if (y<=top+InputFile5->Top+InputFile5->Height) { - InputFile5->Text=file; - } - else if (y<=top+InputFile6->Top+InputFile6->Height) { - InputFile6->Text=file; - } - else if (y<=top+InputFile7->Top+InputFile7->Height) { - InputFile7->Text=file; - } - else if (y<=top+InputFile8->Top+InputFile8->Height) { - InputFile8->Text=file; - } - else if (y<=top+InputFile9->Top+InputFile9->Height) { - InputFile9->Text=file; - } - else if (y<=top+InputFile10->Top+InputFile10->Height) { - InputFile10->Text=file; - } +void __fastcall TMainForm::DropFiles(TWMDropFiles msg) { + POINT point = {0}; + int top, y; + char *p, file[1024]; + + if (DragQueryFile((HDROP)msg.Drop, 0xFFFFFFFF, NULL, 0) <= 0) return; + DragQueryFile((HDROP)msg.Drop, 0, file, sizeof(file)); + if (!DragQueryPoint((HDROP)msg.Drop, &point)) return; + + y = point.y; + top = Panel1->Top + Panel4->Top; + if (y <= top + InputFile1->Top + InputFile1->Height) { + InputFile1->Text = file; + SetOutFile(); + } else if (y <= top + InputFile2->Top + InputFile2->Height) { + InputFile2->Text = file; + } else if (y <= top + InputFile3->Top + InputFile3->Height) { + InputFile3->Text = file; + } else if (y <= top + InputFile4->Top + InputFile4->Height) { + InputFile4->Text = file; + } else if (y <= top + InputFile5->Top + InputFile5->Height) { + InputFile5->Text = file; + } else if (y <= top + InputFile6->Top + InputFile6->Height) { + InputFile6->Text = file; + } else if (y <= top + InputFile7->Top + InputFile7->Height) { + InputFile7->Text = file; + } else if (y <= top + InputFile8->Top + InputFile8->Height) { + InputFile8->Text = file; + } else if (y <= top + InputFile9->Top + InputFile9->Height) { + InputFile9->Text = file; + } else if (y <= top + InputFile10->Top + InputFile10->Height) { + InputFile10->Text = file; + } } // callback on button-plot -------------------------------------------------- -void __fastcall TMainForm::BtnPlotClick(TObject *Sender) -{ - AnsiString OutputFile_Text=OutputFile->Text; - AnsiString file=FilePath(OutputFile_Text); - AnsiString cmd1="rtkplot",cmd2="..\\..\\..\\bin\\rtkplot",opts=""; - - opts+=" \""+file+"\""; - - if (!ExecCmd(cmd1+opts,1)&&!ExecCmd(cmd2+opts,1)) { - ShowMsg((char *)"error : rtkplot execution"); - } +void __fastcall TMainForm::BtnPlotClick(TObject *Sender) { + AnsiString OutputFile_Text = OutputFile->Text; + AnsiString file = FilePath(OutputFile_Text); + AnsiString cmd1 = "rtkplot", cmd2 = "..\\..\\..\\bin\\rtkplot", opts = ""; + + opts += " \"" + file + "\""; + + if (!ExecCmd(cmd1 + opts, 1) && !ExecCmd(cmd2 + opts, 1)) { + ShowMsg((char *)"error : rtkplot execution"); + } } // callback on button-view -------------------------------------------------- -void __fastcall TMainForm::BtnViewClick(TObject *Sender) -{ - AnsiString OutputFile_Text=OutputFile->Text; - ViewFile(FilePath(OutputFile_Text)); +void __fastcall TMainForm::BtnViewClick(TObject *Sender) { + AnsiString OutputFile_Text = OutputFile->Text; + ViewFile(FilePath(OutputFile_Text)); } // callback on button-to-kml ------------------------------------------------ -void __fastcall TMainForm::BtnToKMLClick(TObject *Sender) -{ - AnsiString OutputFile_Text=OutputFile->Text; - ConvDialog->Show(); - ConvDialog->SetInput(FilePath(OutputFile_Text)); +void __fastcall TMainForm::BtnToKMLClick(TObject *Sender) { + AnsiString OutputFile_Text = OutputFile->Text; + ConvDialog->Show(); + ConvDialog->SetInput(FilePath(OutputFile_Text)); } // callback on button-options ----------------------------------------------- -void __fastcall TMainForm::BtnOptionClick(TObject *Sender) -{ - int format=SolFormat; - if (OptDialog->ShowModal()!=mrOk) return; - if ((format==SOLF_NMEA)!=(SolFormat==SOLF_NMEA)) { - SetOutFile(); - } - UpdateEnable(); +void __fastcall TMainForm::BtnOptionClick(TObject *Sender) { + int format = SolFormat; + if (OptDialog->ShowModal() != mrOk) return; + if ((format == SOLF_NMEA) != (SolFormat == SOLF_NMEA)) { + SetOutFile(); + } + UpdateEnable(); } // callback on button-execute ----------------------------------------------- -void __fastcall TMainForm::BtnExecClick(TObject *Sender) -{ - AnsiString OutputFile_Text=OutputFile->Text; - char *p; - - if (InputFile1->Text=="") { - showmsg((char *)"error : no rinex obs file (rover)"); - return; - } - if (InputFile2->Text==""&&PMODE_DGPS<=PosMode&&PosMode<=PMODE_FIXED) { - showmsg((char *)"error : no rinex obs file (base station)"); - return; - } - if (OutputFile->Text=="") { - showmsg((char *)"error : no output file"); - return; - } - if ((p=strrchr(OutputFile_Text.c_str(),'.'))) { - if (!strcmp(p,".obs")||!strcmp(p,".OBS")||!strcmp(p,".nav")|| - !strcmp(p,".NAV")||!strcmp(p,".gnav")||!strcmp(p,".GNAV")|| - !strcmp(p,".gz")||!strcmp(p,".Z")|| - !strcmp(p+3,"o")||!strcmp(p+3,"O")||!strcmp(p+3,"d")|| - !strcmp(p+3,"D")||!strcmp(p+3,"n")||!strcmp(p+3,"N")|| - !strcmp(p+3,"g")||!strcmp(p+3,"G")) { - showmsg((char *)"error : invalid extension of output file (%s)",p); - return; - } - } - showmsg((char *)""); - BtnExec ->Visible=false; - BtnAbort ->Visible=true; - AbortFlag=0; - BtnExit ->Enabled=false; - BtnView ->Enabled=false; - BtnToKML ->Enabled=false; - BtnPlot ->Enabled=false; - BtnOption->Enabled=false; - Panel1 ->Enabled=false; - - if (ExecProc()>=0) { - AddHist(InputFile1); - AddHist(InputFile2); - AddHist(InputFile3); - AddHist(InputFile4); - AddHist(InputFile5); - AddHist(InputFile6); - AddHist(InputFile7); - AddHist(InputFile8); - AddHist(InputFile9); - AddHist(InputFile10); - AddHist(OutputFile); - } - AnsiString Message_Caption=Message->Caption; - if (strstr(Message_Caption.c_str(),"processing")) { - showmsg((char *)"done"); - } - BtnAbort ->Visible=false; - BtnExec ->Visible=true; - BtnExec ->Enabled=true; - BtnExit ->Enabled=true; - BtnView ->Enabled=true; - BtnToKML ->Enabled=true; - BtnPlot ->Enabled=true; - BtnOption->Enabled=true; - Panel1 ->Enabled=true; +void __fastcall TMainForm::BtnExecClick(TObject *Sender) { + AnsiString OutputFile_Text = OutputFile->Text; + char *p; + + if (InputFile1->Text == "") { + showmsg((char *)"error : no rinex obs file (rover)"); + return; + } + if (InputFile2->Text == "" && PMODE_DGPS <= PosMode && PosMode <= PMODE_FIXED) { + showmsg((char *)"error : no rinex obs file (base station)"); + return; + } + if (OutputFile->Text == "") { + showmsg((char *)"error : no output file"); + return; + } + if ((p = strrchr(OutputFile_Text.c_str(), '.'))) { + if (!strcmp(p, ".obs") || !strcmp(p, ".OBS") || !strcmp(p, ".nav") || !strcmp(p, ".NAV") || + !strcmp(p, ".gnav") || !strcmp(p, ".GNAV") || !strcmp(p, ".gz") || !strcmp(p, ".Z") || + !strcmp(p + 3, "o") || !strcmp(p + 3, "O") || !strcmp(p + 3, "d") || !strcmp(p + 3, "D") || + !strcmp(p + 3, "n") || !strcmp(p + 3, "N") || !strcmp(p + 3, "g") || !strcmp(p + 3, "G")) { + showmsg((char *)"error : invalid extension of output file (%s)", p); + return; + } + } + showmsg((char *)""); + BtnExec->Visible = false; + BtnAbort->Visible = true; + AbortFlag = 0; + BtnExit->Enabled = false; + BtnView->Enabled = false; + BtnToKML->Enabled = false; + BtnPlot->Enabled = false; + BtnOption->Enabled = false; + Panel1->Enabled = false; + + if (ExecProc() >= 0) { + AddHist(InputFile1); + AddHist(InputFile2); + AddHist(InputFile3); + AddHist(InputFile4); + AddHist(InputFile5); + AddHist(InputFile6); + AddHist(InputFile7); + AddHist(InputFile8); + AddHist(InputFile9); + AddHist(InputFile10); + AddHist(OutputFile); + } + AnsiString Message_Caption = Message->Caption; + if (strstr(Message_Caption.c_str(), "processing")) { + showmsg((char *)"done"); + } + BtnAbort->Visible = false; + BtnExec->Visible = true; + BtnExec->Enabled = true; + BtnExit->Enabled = true; + BtnView->Enabled = true; + BtnToKML->Enabled = true; + BtnPlot->Enabled = true; + BtnOption->Enabled = true; + Panel1->Enabled = true; } // callback on button-abort ------------------------------------------------- -void __fastcall TMainForm::BtnAbortClick(TObject *Sender) -{ - AbortFlag=1; - showmsg((char *)"aborted"); +void __fastcall TMainForm::BtnAbortClick(TObject *Sender) { + AbortFlag = 1; + showmsg((char *)"aborted"); } // callback on button-exit -------------------------------------------------- -void __fastcall TMainForm::BtnExitClick(TObject *Sender) -{ - Close(); -} +void __fastcall TMainForm::BtnExitClick(TObject *Sender) { Close(); } // callback on button-about ------------------------------------------------- -void __fastcall TMainForm::BtnAboutClick(TObject *Sender) -{ - AnsiString prog=PRGNAME; +void __fastcall TMainForm::BtnAboutClick(TObject *Sender) { + AnsiString prog = PRGNAME; #ifdef _WIN64 - prog+="_WIN64"; + prog += "_WIN64"; #endif #ifdef MKL - prog+="_MKL"; + prog += "_MKL"; #endif - AboutDialog->About=prog; - AboutDialog->IconIndex=1; - AboutDialog->ShowModal(); + AboutDialog->About = prog; + AboutDialog->IconIndex = 1; + AboutDialog->ShowModal(); } // callback on button-time-1 ------------------------------------------------ -void __fastcall TMainForm::BtnTime1Click(TObject *Sender) -{ - TimeDialog->Time=GetTime1(); - TimeDialog->ShowModal(); +void __fastcall TMainForm::BtnTime1Click(TObject *Sender) { + TimeDialog->Time = GetTime1(); + TimeDialog->ShowModal(); } // callback on button-time-2 ------------------------------------------------ -void __fastcall TMainForm::BtnTime2Click(TObject *Sender) -{ - TimeDialog->Time=GetTime2(); - TimeDialog->ShowModal(); +void __fastcall TMainForm::BtnTime2Click(TObject *Sender) { + TimeDialog->Time = GetTime2(); + TimeDialog->ShowModal(); } // callback on button-inputfile-1 ------------------------------------------- -void __fastcall TMainForm::BtnInputFile1Click(TObject *Sender) -{ - char file[1024],*p; - - OpenDialog->Title="RINEX OBS (Rover) File"; - OpenDialog->FileName=""; - OpenDialog->FilterIndex=2; - if (!OpenDialog->Execute()) return; - InputFile1->Text=OpenDialog->FileName; - SetOutFile(); +void __fastcall TMainForm::BtnInputFile1Click(TObject *Sender) { + char file[1024], *p; + + OpenDialog->Title = "RINEX OBS (Rover) File"; + OpenDialog->FileName = ""; + OpenDialog->FilterIndex = 2; + if (!OpenDialog->Execute()) return; + InputFile1->Text = OpenDialog->FileName; + SetOutFile(); } // callback on button-inputfile-2 ------------------------------------------- -void __fastcall TMainForm::BtnInputFile2Click(TObject *Sender) -{ - OpenDialog->Title="RINEX OBS (Base Station) File"; - OpenDialog->FileName=""; - OpenDialog->FilterIndex=2; - if (!OpenDialog->Execute()) return; - InputFile2->Text=OpenDialog->FileName; +void __fastcall TMainForm::BtnInputFile2Click(TObject *Sender) { + OpenDialog->Title = "RINEX OBS (Base Station) File"; + OpenDialog->FileName = ""; + OpenDialog->FilterIndex = 2; + if (!OpenDialog->Execute()) return; + InputFile2->Text = OpenDialog->FileName; } // callback on button-inputfile-3 ------------------------------------------- -void __fastcall TMainForm::BtnInputFile3Click(TObject *Sender) -{ - OpenDialog->Title="RINEX NAV/CLK,SP3,FCB,IONEX or SBAS/EMS File"; - OpenDialog->FileName=""; - OpenDialog->FilterIndex=3; - if (!OpenDialog->Execute()) return; - InputFile3->Text=OpenDialog->FileName; +void __fastcall TMainForm::BtnInputFile3Click(TObject *Sender) { + OpenDialog->Title = "RINEX NAV/CLK,SP3,FCB,IONEX or SBAS/EMS File"; + OpenDialog->FileName = ""; + OpenDialog->FilterIndex = 3; + if (!OpenDialog->Execute()) return; + InputFile3->Text = OpenDialog->FileName; } // callback on button-inputfile-4 ------------------------------------------- -void __fastcall TMainForm::BtnInputFile4Click(TObject *Sender) -{ - OpenDialog->Title="RINEX NAV/CLK,SP3,FCB,IONEX or SBAS/EMS File"; - OpenDialog->FileName=""; - OpenDialog->FilterIndex=4; - if (!OpenDialog->Execute()) return; - InputFile4->Text=OpenDialog->FileName; +void __fastcall TMainForm::BtnInputFile4Click(TObject *Sender) { + OpenDialog->Title = "RINEX NAV/CLK,SP3,FCB,IONEX or SBAS/EMS File"; + OpenDialog->FileName = ""; + OpenDialog->FilterIndex = 4; + if (!OpenDialog->Execute()) return; + InputFile4->Text = OpenDialog->FileName; } // callback on button-inputfile-5 ------------------------------------------- -void __fastcall TMainForm::BtnInputFile5Click(TObject *Sender) -{ - OpenDialog->Title="RINEX NAV/CLK,SP3,FCB,IONEX or SBAS/EMS File"; - OpenDialog->FileName=""; - OpenDialog->FilterIndex=4; - if (!OpenDialog->Execute()) return; - InputFile5->Text=OpenDialog->FileName; +void __fastcall TMainForm::BtnInputFile5Click(TObject *Sender) { + OpenDialog->Title = "RINEX NAV/CLK,SP3,FCB,IONEX or SBAS/EMS File"; + OpenDialog->FileName = ""; + OpenDialog->FilterIndex = 4; + if (!OpenDialog->Execute()) return; + InputFile5->Text = OpenDialog->FileName; } // callback on button-inputfile-6 ------------------------------------------- -void __fastcall TMainForm::BtnInputFile6Click(TObject *Sender) -{ - OpenDialog->Title="RINEX NAV/CLK,SP3,FCB,IONEX or SBAS/EMS File"; - OpenDialog->FileName=""; - OpenDialog->FilterIndex=5; - if (!OpenDialog->Execute()) return; - InputFile6->Text=OpenDialog->FileName; +void __fastcall TMainForm::BtnInputFile6Click(TObject *Sender) { + OpenDialog->Title = "RINEX NAV/CLK,SP3,FCB,IONEX or SBAS/EMS File"; + OpenDialog->FileName = ""; + OpenDialog->FilterIndex = 5; + if (!OpenDialog->Execute()) return; + InputFile6->Text = OpenDialog->FileName; } // callback on button-inputfile-7 ------------------------------------------- -void __fastcall TMainForm::BtnInputFile7Click(TObject *Sender) -{ - OpenDialog->Title="File"; - OpenDialog->FileName=""; - OpenDialog->FilterIndex=1; - if (!OpenDialog->Execute()) return; - InputFile7->Text=OpenDialog->FileName; +void __fastcall TMainForm::BtnInputFile7Click(TObject *Sender) { + OpenDialog->Title = "File"; + OpenDialog->FileName = ""; + OpenDialog->FilterIndex = 1; + if (!OpenDialog->Execute()) return; + InputFile7->Text = OpenDialog->FileName; } // callback on button-inputfile-8 ------------------------------------------- -void __fastcall TMainForm::BtnInputFile8Click(TObject *Sender) -{ - OpenDialog->Title="File"; - OpenDialog->FileName=""; - OpenDialog->FilterIndex=1; - if (!OpenDialog->Execute()) return; - InputFile8->Text=OpenDialog->FileName; +void __fastcall TMainForm::BtnInputFile8Click(TObject *Sender) { + OpenDialog->Title = "File"; + OpenDialog->FileName = ""; + OpenDialog->FilterIndex = 1; + if (!OpenDialog->Execute()) return; + InputFile8->Text = OpenDialog->FileName; } // callback on button-inputfile-9 ------------------------------------------- -void __fastcall TMainForm::BtnInputFile9Click(TObject *Sender) -{ - OpenDialog->Title="File"; - OpenDialog->FileName=""; - OpenDialog->FilterIndex=1; - if (!OpenDialog->Execute()) return; - InputFile9->Text=OpenDialog->FileName; +void __fastcall TMainForm::BtnInputFile9Click(TObject *Sender) { + OpenDialog->Title = "File"; + OpenDialog->FileName = ""; + OpenDialog->FilterIndex = 1; + if (!OpenDialog->Execute()) return; + InputFile9->Text = OpenDialog->FileName; } // callback on button-inputfile-10 ------------------------------------------ -void __fastcall TMainForm::BtnInputFile10Click(TObject *Sender) -{ - OpenDialog->Title="File"; - OpenDialog->FileName=""; - OpenDialog->FilterIndex=1; - if (!OpenDialog->Execute()) return; - InputFile10->Text=OpenDialog->FileName; +void __fastcall TMainForm::BtnInputFile10Click(TObject *Sender) { + OpenDialog->Title = "File"; + OpenDialog->FileName = ""; + OpenDialog->FilterIndex = 1; + if (!OpenDialog->Execute()) return; + InputFile10->Text = OpenDialog->FileName; } // callback on button-outputfile -------------------------------------------- -void __fastcall TMainForm::BtnOutputFileClick(TObject *Sender) -{ - SaveDialog->Title="Output File"; - OpenDialog->FileName=""; - if (!SaveDialog->Execute()) return; - OutputFile->Text=SaveDialog->FileName; +void __fastcall TMainForm::BtnOutputFileClick(TObject *Sender) { + SaveDialog->Title = "Output File"; + OpenDialog->FileName = ""; + if (!SaveDialog->Execute()) return; + OutputFile->Text = SaveDialog->FileName; } // callback on button-inputview-1 ------------------------------------------- -void __fastcall TMainForm::BtnInputView1Click(TObject *Sender) -{ - AnsiString InputFile1_Text=InputFile1->Text; - ViewFile(FilePath(InputFile1_Text)); +void __fastcall TMainForm::BtnInputView1Click(TObject *Sender) { + AnsiString InputFile1_Text = InputFile1->Text; + ViewFile(FilePath(InputFile1_Text)); } // callback on button-inputview-2 ------------------------------------------- -void __fastcall TMainForm::BtnInputView2Click(TObject *Sender) -{ - AnsiString InputFile2_Text=InputFile2->Text; - ViewFile(FilePath(InputFile2_Text)); +void __fastcall TMainForm::BtnInputView2Click(TObject *Sender) { + AnsiString InputFile2_Text = InputFile2->Text; + ViewFile(FilePath(InputFile2_Text)); } // callback on button-inputview-3 ------------------------------------------- -void __fastcall TMainForm::BtnInputView3Click(TObject *Sender) -{ - AnsiString InputFile1_Text=InputFile1->Text; - AnsiString InputFile3_Text=InputFile3->Text; - AnsiString file=FilePath(InputFile3_Text); - char f[1024]; - - if (file=="") { - file=FilePath(InputFile1_Text); - if (!ObsToNav(file.c_str(),f)) return; - file=f; - } - ViewFile(file); +void __fastcall TMainForm::BtnInputView3Click(TObject *Sender) { + AnsiString InputFile1_Text = InputFile1->Text; + AnsiString InputFile3_Text = InputFile3->Text; + AnsiString file = FilePath(InputFile3_Text); + char f[1024]; + + if (file == "") { + file = FilePath(InputFile1_Text); + if (!ObsToNav(file.c_str(), f)) return; + file = f; + } + ViewFile(file); } // callback on button-inputview-4 ------------------------------------------- -void __fastcall TMainForm::BtnInputView4Click(TObject *Sender) -{ - AnsiString InputFile4_Text=InputFile4->Text; - ViewFile(FilePath(InputFile4_Text)); +void __fastcall TMainForm::BtnInputView4Click(TObject *Sender) { + AnsiString InputFile4_Text = InputFile4->Text; + ViewFile(FilePath(InputFile4_Text)); } // callback on button-inputview-5 ------------------------------------------- -void __fastcall TMainForm::BtnInputView5Click(TObject *Sender) -{ - AnsiString InputFile5_Text=InputFile5->Text; - ViewFile(FilePath(InputFile5_Text)); +void __fastcall TMainForm::BtnInputView5Click(TObject *Sender) { + AnsiString InputFile5_Text = InputFile5->Text; + ViewFile(FilePath(InputFile5_Text)); } // callback on button-inputview-6 ------------------------------------------- -void __fastcall TMainForm::BtnInputView6Click(TObject *Sender) -{ - AnsiString InputFile6_Text=InputFile6->Text; - ViewFile(FilePath(InputFile6_Text)); +void __fastcall TMainForm::BtnInputView6Click(TObject *Sender) { + AnsiString InputFile6_Text = InputFile6->Text; + ViewFile(FilePath(InputFile6_Text)); } // callback on button-inputview-7 ------------------------------------------- -void __fastcall TMainForm::BtnInputView7Click(TObject *Sender) -{ - AnsiString InputFile7_Text=InputFile7->Text; - ViewFile(FilePath(InputFile7_Text)); +void __fastcall TMainForm::BtnInputView7Click(TObject *Sender) { + AnsiString InputFile7_Text = InputFile7->Text; + ViewFile(FilePath(InputFile7_Text)); } // callback on button-inputview-8 ------------------------------------------- -void __fastcall TMainForm::BtnInputView8Click(TObject *Sender) -{ - AnsiString InputFile8_Text=InputFile8->Text; - ViewFile(FilePath(InputFile8_Text)); +void __fastcall TMainForm::BtnInputView8Click(TObject *Sender) { + AnsiString InputFile8_Text = InputFile8->Text; + ViewFile(FilePath(InputFile8_Text)); } // callback on button-inputview-9 ------------------------------------------- -void __fastcall TMainForm::BtnInputView9Click(TObject *Sender) -{ - AnsiString InputFile9_Text=InputFile9->Text; - ViewFile(FilePath(InputFile9_Text)); +void __fastcall TMainForm::BtnInputView9Click(TObject *Sender) { + AnsiString InputFile9_Text = InputFile9->Text; + ViewFile(FilePath(InputFile9_Text)); } // callback on button-inputview-10 ------------------------------------------ -void __fastcall TMainForm::BtnInputView10Click(TObject *Sender) -{ - AnsiString InputFile10_Text=InputFile10->Text; - ViewFile(FilePath(InputFile10_Text)); +void __fastcall TMainForm::BtnInputView10Click(TObject *Sender) { + AnsiString InputFile10_Text = InputFile10->Text; + ViewFile(FilePath(InputFile10_Text)); } // callback on button-outputview-1 ------------------------------------------ -void __fastcall TMainForm::BtnOutputView1Click(TObject *Sender) -{ - AnsiString OutputFile_Text=OutputFile->Text; - AnsiString file=FilePath(OutputFile_Text)+".stat"; - FILE *fp=fopen(file.c_str(),"r"); - if (fp) fclose(fp); else return; - ViewFile(file); +void __fastcall TMainForm::BtnOutputView1Click(TObject *Sender) { + AnsiString OutputFile_Text = OutputFile->Text; + AnsiString file = FilePath(OutputFile_Text) + ".stat"; + FILE *fp = fopen(file.c_str(), "r"); + if (fp) + fclose(fp); + else + return; + ViewFile(file); } // callback on button-outputview-2 ------------------------------------------ -void __fastcall TMainForm::BtnOutputView2Click(TObject *Sender) -{ - AnsiString OutputFile_Text=OutputFile->Text; - AnsiString file=FilePath(OutputFile_Text)+".trace"; - FILE *fp=fopen(file.c_str(),"r"); - if (fp) fclose(fp); else return; - ViewFile(file); +void __fastcall TMainForm::BtnOutputView2Click(TObject *Sender) { + AnsiString OutputFile_Text = OutputFile->Text; + AnsiString file = FilePath(OutputFile_Text) + ".trace"; + FILE *fp = fopen(file.c_str(), "r"); + if (fp) + fclose(fp); + else + return; + ViewFile(file); } // callback on button-inputplot-1 ------------------------------------------- -void __fastcall TMainForm::BtnInputPlot1Click(TObject *Sender) -{ - AnsiString InputFile1_Text=InputFile1->Text; - AnsiString InputFile2_Text=InputFile2->Text; - AnsiString InputFile3_Text=InputFile3->Text; - AnsiString InputFile4_Text=InputFile4->Text; - AnsiString InputFile5_Text=InputFile5->Text; - AnsiString InputFile6_Text=InputFile6->Text; - AnsiString InputFile7_Text=InputFile7->Text; - AnsiString InputFile8_Text=InputFile8->Text; - AnsiString InputFile9_Text=InputFile9->Text; - AnsiString InputFile10_Text=InputFile10->Text; - AnsiString files[10]; - AnsiString cmd1="rtkplot",cmd2="..\\..\\..\\bin\\rtkplot",opts=""; - char navfile[1024]; - - files[0]=FilePath(InputFile1_Text); /* obs rover */ - files[1]=FilePath(InputFile2_Text); /* obs base */ - files[2]=FilePath(InputFile3_Text); - files[3]=FilePath(InputFile4_Text); - files[4]=FilePath(InputFile5_Text); - files[5]=FilePath(InputFile6_Text); - files[6]=FilePath(InputFile7_Text); - files[7]=FilePath(InputFile8_Text); - files[8]=FilePath(InputFile9_Text); - files[9]=FilePath(InputFile10_Text); - - if (files[2]=="") { - if (ObsToNav(files[0].c_str(),navfile)) files[2]=navfile; - } - opts=" -r \""+files[0]+"\" \""+files[2]+"\" \""+files[3]+"\" \""+ - files[4]+"\" \""+files[5]+"\" \""+files[6]+"\" \""+files[7]+ - "\" \""+files[8]+"\" \""+files[9]+"\""; - - if (!ExecCmd(cmd1+opts,1)&&!ExecCmd(cmd2+opts,1)) { - ShowMsg((char *)"error : rtkplot execution"); - } +void __fastcall TMainForm::BtnInputPlot1Click(TObject *Sender) { + AnsiString InputFile1_Text = InputFile1->Text; + AnsiString InputFile2_Text = InputFile2->Text; + AnsiString InputFile3_Text = InputFile3->Text; + AnsiString InputFile4_Text = InputFile4->Text; + AnsiString InputFile5_Text = InputFile5->Text; + AnsiString InputFile6_Text = InputFile6->Text; + AnsiString InputFile7_Text = InputFile7->Text; + AnsiString InputFile8_Text = InputFile8->Text; + AnsiString InputFile9_Text = InputFile9->Text; + AnsiString InputFile10_Text = InputFile10->Text; + AnsiString files[10]; + AnsiString cmd1 = "rtkplot", cmd2 = "..\\..\\..\\bin\\rtkplot", opts = ""; + char navfile[1024]; + + files[0] = FilePath(InputFile1_Text); /* obs rover */ + files[1] = FilePath(InputFile2_Text); /* obs base */ + files[2] = FilePath(InputFile3_Text); + files[3] = FilePath(InputFile4_Text); + files[4] = FilePath(InputFile5_Text); + files[5] = FilePath(InputFile6_Text); + files[6] = FilePath(InputFile7_Text); + files[7] = FilePath(InputFile8_Text); + files[8] = FilePath(InputFile9_Text); + files[9] = FilePath(InputFile10_Text); + + if (files[2] == "") { + if (ObsToNav(files[0].c_str(), navfile)) files[2] = navfile; + } + opts = " -r \"" + files[0] + "\" \"" + files[2] + "\" \"" + files[3] + "\" \"" + files[4] + + "\" \"" + files[5] + "\" \"" + files[6] + "\" \"" + files[7] + "\" \"" + files[8] + + "\" \"" + files[9] + "\""; + + if (!ExecCmd(cmd1 + opts, 1) && !ExecCmd(cmd2 + opts, 1)) { + ShowMsg((char *)"error : rtkplot execution"); + } } // callback on button-inputplot-2 ------------------------------------------- -void __fastcall TMainForm::BtnInputPlot2Click(TObject *Sender) -{ - AnsiString InputFile1_Text=InputFile1->Text; - AnsiString InputFile2_Text=InputFile2->Text; - AnsiString InputFile3_Text=InputFile3->Text; - AnsiString InputFile4_Text=InputFile4->Text; - AnsiString InputFile5_Text=InputFile5->Text; - AnsiString InputFile6_Text=InputFile6->Text; - AnsiString InputFile7_Text=InputFile7->Text; - AnsiString InputFile8_Text=InputFile8->Text; - AnsiString InputFile9_Text=InputFile9->Text; - AnsiString InputFile10_Text=InputFile10->Text; - AnsiString files[10]; - AnsiString cmd1="rtkplot",cmd2="..\\..\\..\\bin\\rtkplot",opts=""; - char navfile[1024],gnavfile[1024]; - - files[0]=FilePath(InputFile1_Text); /* obs rover */ - files[1]=FilePath(InputFile2_Text); /* obs base */ - files[2]=FilePath(InputFile3_Text); - files[3]=FilePath(InputFile4_Text); - files[4]=FilePath(InputFile5_Text); - files[5]=FilePath(InputFile6_Text); - files[6]=FilePath(InputFile7_Text); - files[7]=FilePath(InputFile8_Text); - files[8]=FilePath(InputFile9_Text); - files[9]=FilePath(InputFile10_Text); - - if (files[2]=="") { - if (ObsToNav(files[0].c_str(),navfile)) files[2]=navfile; - } - opts=" -r \""+files[1]+"\" \""+files[2]+"\" \""+files[3]+"\" \""+ - files[4]+"\" \""+files[5]+"\" \""+files[6]+"\" \""+files[7]+ - "\" \""+files[8]+"\" \""+files[9]+"\""; - - if (!ExecCmd(cmd1+opts,1)&&!ExecCmd(cmd2+opts,1)) { - ShowMsg((char *)"error : rtkplot execution"); - } +void __fastcall TMainForm::BtnInputPlot2Click(TObject *Sender) { + AnsiString InputFile1_Text = InputFile1->Text; + AnsiString InputFile2_Text = InputFile2->Text; + AnsiString InputFile3_Text = InputFile3->Text; + AnsiString InputFile4_Text = InputFile4->Text; + AnsiString InputFile5_Text = InputFile5->Text; + AnsiString InputFile6_Text = InputFile6->Text; + AnsiString InputFile7_Text = InputFile7->Text; + AnsiString InputFile8_Text = InputFile8->Text; + AnsiString InputFile9_Text = InputFile9->Text; + AnsiString InputFile10_Text = InputFile10->Text; + AnsiString files[10]; + AnsiString cmd1 = "rtkplot", cmd2 = "..\\..\\..\\bin\\rtkplot", opts = ""; + char navfile[1024], gnavfile[1024]; + + files[0] = FilePath(InputFile1_Text); /* obs rover */ + files[1] = FilePath(InputFile2_Text); /* obs base */ + files[2] = FilePath(InputFile3_Text); + files[3] = FilePath(InputFile4_Text); + files[4] = FilePath(InputFile5_Text); + files[5] = FilePath(InputFile6_Text); + files[6] = FilePath(InputFile7_Text); + files[7] = FilePath(InputFile8_Text); + files[8] = FilePath(InputFile9_Text); + files[9] = FilePath(InputFile10_Text); + + if (files[2] == "") { + if (ObsToNav(files[0].c_str(), navfile)) files[2] = navfile; + } + opts = " -r \"" + files[1] + "\" \"" + files[2] + "\" \"" + files[3] + "\" \"" + files[4] + + "\" \"" + files[5] + "\" \"" + files[6] + "\" \"" + files[7] + "\" \"" + files[8] + + "\" \"" + files[9] + "\""; + + if (!ExecCmd(cmd1 + opts, 1) && !ExecCmd(cmd2 + opts, 1)) { + ShowMsg((char *)"error : rtkplot execution"); + } } // callback on button-output-directory -------------------------------------- -void __fastcall TMainForm::BtnOutDirClick(TObject *Sender) -{ +void __fastcall TMainForm::BtnOutDirClick(TObject *Sender) { #ifdef TCPP - AnsiString dir=OutDir->Text; - if (!SelectDirectory("Output Directory","",dir)) return; - OutDir->Text=dir; + AnsiString dir = OutDir->Text; + if (!SelectDirectory("Output Directory", "", dir)) return; + OutDir->Text = dir; #else - UnicodeString dir=OutDir->Text; - TSelectDirExtOpts opt=TSelectDirExtOpts()<Text=dir; + UnicodeString dir = OutDir->Text; + TSelectDirExtOpts opt = TSelectDirExtOpts() << sdNewUI << sdNewFolder; + if (!SelectDirectory(L"Output Directory", L"", dir, opt)) return; + OutDir->Text = dir; #endif } // callback on button keyword ----------------------------------------------- -void __fastcall TMainForm::BtnKeywordClick(TObject *Sender) -{ - KeyDialog->Flag=2; - KeyDialog->Show(); +void __fastcall TMainForm::BtnKeywordClick(TObject *Sender) { + KeyDialog->Flag = 2; + KeyDialog->Show(); } // callback on time-start/end check ----------------------------------------- -void __fastcall TMainForm::TimeStartClick(TObject *Sender) -{ - if (TimeStart->Checked && TimeEnd->Checked) { - // Initialize the start time to the end time if the start time - // has just been enabled and is out of order. - gtime_t ts=GetTime1(), te=GetTime2(); - if (timediff(te, ts) < 0.0) { - TimeY1->Text = TimeY2->Text; - TimeH1->Text = TimeH2->Text; - } - } - UpdateEnable(); -} -void __fastcall TMainForm::TimeEndClick(TObject *Sender) -{ - if (TimeStart->Checked && TimeEnd->Checked) { - // Initialize the end time to the start time if the end time has - // just been enabled and is out of order. - gtime_t ts=GetTime1(), te=GetTime2(); - if (timediff(te, ts) < 0.0) { - TimeY2->Text = TimeY1->Text; - TimeH2->Text = TimeH1->Text; - } - } - UpdateEnable(); +void __fastcall TMainForm::TimeStartClick(TObject *Sender) { + if (TimeStart->Checked && TimeEnd->Checked) { + // Initialize the start time to the end time if the start time + // has just been enabled and is out of order. + gtime_t ts = GetTime1(), te = GetTime2(); + if (timediff(te, ts) < 0.0) { + TimeY1->Text = TimeY2->Text; + TimeH1->Text = TimeH2->Text; + } + } + UpdateEnable(); +} +void __fastcall TMainForm::TimeEndClick(TObject *Sender) { + if (TimeStart->Checked && TimeEnd->Checked) { + // Initialize the end time to the start time if the end time has + // just been enabled and is out of order. + gtime_t ts = GetTime1(), te = GetTime2(); + if (timediff(te, ts) < 0.0) { + TimeY2->Text = TimeY1->Text; + TimeH2->Text = TimeH1->Text; + } + } + UpdateEnable(); } // callback on time-interval check ------------------------------------------ -void __fastcall TMainForm::TimeIntFClick(TObject *Sender) -{ - UpdateEnable(); -} +void __fastcall TMainForm::TimeIntFClick(TObject *Sender) { UpdateEnable(); } // callback on time-unit check ---------------------------------------------- -void __fastcall TMainForm::TimeUnitFClick(TObject *Sender) -{ - UpdateEnable(); -} +void __fastcall TMainForm::TimeUnitFClick(TObject *Sender) { UpdateEnable(); } // callback on time-ymd-1 updown -------------------------------------------- -void __fastcall TMainForm::TimeY1UDChangingEx(TObject *Sender, - bool &AllowChange, int NewValue, TUpDownDirection Direction) -{ - AnsiString TimeY1_Text=TimeY1->Text,s; - double ep[]={2000,1,1,0,0,0}; - int p=TimeY1->SelStart,ud=Direction==updUp?1:-1; - - sscanf(TimeY1_Text.c_str(),"%lf/%lf/%lf",ep,ep+1,ep+2); - if (412) {ep[0]++; ep[1]-=12;} - } - else if (p>7||p==0) ep[2]+=ud; else ep[0]+=ud; - time2epoch(epoch2time(ep),ep); - TimeY1->Text=s.sprintf("%04.0f/%02.0f/%02.0f",ep[0],ep[1],ep[2]); - TimeY1->SelStart=p>7||p==0?10:(p>4?7:4); +void __fastcall TMainForm::TimeY1UDChangingEx(TObject *Sender, bool &AllowChange, int NewValue, + TUpDownDirection Direction) { + AnsiString TimeY1_Text = TimeY1->Text, s; + double ep[] = {2000, 1, 1, 0, 0, 0}; + int p = TimeY1->SelStart, ud = Direction == updUp ? 1 : -1; + + sscanf(TimeY1_Text.c_str(), "%lf/%lf/%lf", ep, ep + 1, ep + 2); + if (4 < p && p < 8) { + ep[1] += ud; + if (ep[1] <= 0) { + ep[0]--; + ep[1] += 12; + } else if (ep[1] > 12) { + ep[0]++; + ep[1] -= 12; + } + } else if (p > 7 || p == 0) + ep[2] += ud; + else + ep[0] += ud; + time2epoch(epoch2time(ep), ep); + TimeY1->Text = s.sprintf("%04.0f/%02.0f/%02.0f", ep[0], ep[1], ep[2]); + TimeY1->SelStart = p > 7 || p == 0 ? 10 : (p > 4 ? 7 : 4); } // callback on time-hms-1 updown -------------------------------------------- -void __fastcall TMainForm::TimeH1UDChangingEx(TObject *Sender, - bool &AllowChange, int NewValue, TUpDownDirection Direction) -{ - AnsiString TimeH1_Text=TimeH1->Text,s; - int hms[3]={0},sec,p=TimeH1->SelStart,ud=Direction==updUp?1:-1; - - sscanf(TimeH1_Text.c_str(),"%d:%d:%d",hms,hms+1,hms+2); - if (p>5||p==0) hms[2]+=ud; else if (p>2) hms[1]+=ud; else hms[0]+=ud; - sec=hms[0]*3600+hms[1]*60+hms[2]; - if (sec<0) sec+=86400; else if (sec>=86400) sec-=86400; - TimeH1->Text=s.sprintf("%02d:%02d:%02d",sec/3600,(sec%3600)/60,sec%60); - TimeH1->SelStart=p>5||p==0?8:(p>2?5:2); +void __fastcall TMainForm::TimeH1UDChangingEx(TObject *Sender, bool &AllowChange, int NewValue, + TUpDownDirection Direction) { + AnsiString TimeH1_Text = TimeH1->Text, s; + int hms[3] = {0}, sec, p = TimeH1->SelStart, ud = Direction == updUp ? 1 : -1; + + sscanf(TimeH1_Text.c_str(), "%d:%d:%d", hms, hms + 1, hms + 2); + if (p > 5 || p == 0) + hms[2] += ud; + else if (p > 2) + hms[1] += ud; + else + hms[0] += ud; + sec = hms[0] * 3600 + hms[1] * 60 + hms[2]; + if (sec < 0) + sec += 86400; + else if (sec >= 86400) + sec -= 86400; + TimeH1->Text = s.sprintf("%02d:%02d:%02d", sec / 3600, (sec % 3600) / 60, sec % 60); + TimeH1->SelStart = p > 5 || p == 0 ? 8 : (p > 2 ? 5 : 2); } // callback on time-ymd-2 updown -------------------------------------------- -void __fastcall TMainForm::TimeY2UDChangingEx(TObject *Sender, - bool &AllowChange, int NewValue, TUpDownDirection Direction) -{ - AnsiString TimeY2_Text=TimeY2->Text,s; - double ep[]={2000,1,1,0,0,0}; - int p=TimeY2->SelStart,ud=Direction==updUp?1:-1; - - sscanf(TimeY2_Text.c_str(),"%lf/%lf/%lf",ep,ep+1,ep+2); - if (412) {ep[0]++; ep[1]-=12;} - } - else if (p>7||p==0) ep[2]+=ud; else ep[0]+=ud; - time2epoch(epoch2time(ep),ep); - TimeY2->Text=s.sprintf("%04.0f/%02.0f/%02.0f",ep[0],ep[1],ep[2]); - TimeY2->SelStart=p>7||p==0?10:(p>4?7:4); +void __fastcall TMainForm::TimeY2UDChangingEx(TObject *Sender, bool &AllowChange, int NewValue, + TUpDownDirection Direction) { + AnsiString TimeY2_Text = TimeY2->Text, s; + double ep[] = {2000, 1, 1, 0, 0, 0}; + int p = TimeY2->SelStart, ud = Direction == updUp ? 1 : -1; + + sscanf(TimeY2_Text.c_str(), "%lf/%lf/%lf", ep, ep + 1, ep + 2); + if (4 < p && p < 8) { + ep[1] += ud; + if (ep[1] <= 0) { + ep[0]--; + ep[1] += 12; + } else if (ep[1] > 12) { + ep[0]++; + ep[1] -= 12; + } + } else if (p > 7 || p == 0) + ep[2] += ud; + else + ep[0] += ud; + time2epoch(epoch2time(ep), ep); + TimeY2->Text = s.sprintf("%04.0f/%02.0f/%02.0f", ep[0], ep[1], ep[2]); + TimeY2->SelStart = p > 7 || p == 0 ? 10 : (p > 4 ? 7 : 4); } // callback on time-hms-2 updown -------------------------------------------- -void __fastcall TMainForm::TimeH2UDChangingEx(TObject *Sender, - bool &AllowChange, int NewValue, TUpDownDirection Direction) -{ - AnsiString TimeH2_Text=TimeH2->Text,s; - int hms[3]={0},sec,p=TimeH2->SelStart,ud=Direction==updUp?1:-1; - - sscanf(TimeH2_Text.c_str(),"%d:%d:%d",hms,hms+1,hms+2); - if (p>5||p==0) hms[2]+=ud; else if (p>2) hms[1]+=ud; else hms[0]+=ud; - sec=hms[0]*3600+hms[1]*60+hms[2]; - if (sec<0) sec+=86400; else if (sec>=86400) sec-=86400; - TimeH2->Text=s.sprintf("%02d:%02d:%02d",sec/3600,(sec%3600)/60,sec%60); - TimeH2->SelStart=p>5||p==0?8:(p>2?5:2); +void __fastcall TMainForm::TimeH2UDChangingEx(TObject *Sender, bool &AllowChange, int NewValue, + TUpDownDirection Direction) { + AnsiString TimeH2_Text = TimeH2->Text, s; + int hms[3] = {0}, sec, p = TimeH2->SelStart, ud = Direction == updUp ? 1 : -1; + + sscanf(TimeH2_Text.c_str(), "%d:%d:%d", hms, hms + 1, hms + 2); + if (p > 5 || p == 0) + hms[2] += ud; + else if (p > 2) + hms[1] += ud; + else + hms[0] += ud; + sec = hms[0] * 3600 + hms[1] * 60 + hms[2]; + if (sec < 0) + sec += 86400; + else if (sec >= 86400) + sec -= 86400; + TimeH2->Text = s.sprintf("%02d:%02d:%02d", sec / 3600, (sec % 3600) / 60, sec % 60); + TimeH2->SelStart = p > 5 || p == 0 ? 8 : (p > 2 ? 5 : 2); } //--------------------------------------------------------------------------- void __fastcall TMainForm::TimeY1KeyDown(TObject *Sender, WORD &Key, TShiftState Shift) { - bool allowchange; - if (Key==VK_UP||Key==VK_DOWN) { - TimeY1UDChangingEx(Sender,allowchange,0,Key==VK_UP?updUp:updDown); - Key=0; - } + bool allowchange; + if (Key == VK_UP || Key == VK_DOWN) { + TimeY1UDChangingEx(Sender, allowchange, 0, Key == VK_UP ? updUp : updDown); + Key = 0; + } } //--------------------------------------------------------------------------- void __fastcall TMainForm::TimeH1KeyDown(TObject *Sender, WORD &Key, TShiftState Shift) { - bool allowchange; - if (Key==VK_UP||Key==VK_DOWN) { - TimeH1UDChangingEx(Sender,allowchange,0,Key==VK_UP?updUp:updDown); - Key=0; - } + bool allowchange; + if (Key == VK_UP || Key == VK_DOWN) { + TimeH1UDChangingEx(Sender, allowchange, 0, Key == VK_UP ? updUp : updDown); + Key = 0; + } } //--------------------------------------------------------------------------- void __fastcall TMainForm::TimeY2KeyDown(TObject *Sender, WORD &Key, TShiftState Shift) { - bool allowchange; - if (Key==VK_UP||Key==VK_DOWN) { - TimeY2UDChangingEx(Sender,allowchange,0,Key==VK_UP?updUp:updDown); - Key=0; - } + bool allowchange; + if (Key == VK_UP || Key == VK_DOWN) { + TimeY2UDChangingEx(Sender, allowchange, 0, Key == VK_UP ? updUp : updDown); + Key = 0; + } } //--------------------------------------------------------------------------- void __fastcall TMainForm::TimeH2KeyDown(TObject *Sender, WORD &Key, TShiftState Shift) { - bool allowchange; - if (Key==VK_UP||Key==VK_DOWN) { - TimeH2UDChangingEx(Sender,allowchange,0,Key==VK_UP?updUp:updDown); - Key=0; - } + bool allowchange; + if (Key == VK_UP || Key == VK_DOWN) { + TimeH2UDChangingEx(Sender, allowchange, 0, Key == VK_UP ? updUp : updDown); + Key = 0; + } } // callback on inputfile-1 change ------------------------------------------- -void __fastcall TMainForm::InputFile1Change(TObject *Sender) -{ - SetOutFile(); -} +void __fastcall TMainForm::InputFile1Change(TObject *Sender) { SetOutFile(); } // callback on output-directory checked ------------------------------------- -void __fastcall TMainForm::OutDirEnaClick(TObject *Sender) -{ - UpdateEnable(); - SetOutFile(); +void __fastcall TMainForm::OutDirEnaClick(TObject *Sender) { + UpdateEnable(); + SetOutFile(); } // callback on output-directory change -------------------------------------- -void __fastcall TMainForm::OutDirChange(TObject *Sender) -{ - SetOutFile(); -} +void __fastcall TMainForm::OutDirChange(TObject *Sender) { SetOutFile(); } // set output file path ----------------------------------------------------- -void __fastcall TMainForm::SetOutFile(void) -{ - AnsiString InputFile1_Text=InputFile1->Text; - AnsiString OutDir_Text=OutDir->Text; - char *p,ofile[1024],ifile[1024]; - - if (InputFile1->Text=="") return; - - strcpy(ifile,InputFile1_Text.c_str()); - - if (OutDirEna->Checked) { - if ((p=strrchr(ifile,'\\'))) p++; else p=ifile; - sprintf(ofile,"%s\\%s",OutDir_Text.c_str(),p); - } - else { - strcpy(ofile,ifile); - } - if (!(p=strrchr(ofile,'.'))) p=ofile+strlen(ofile); - strcpy(p,SolFormat==SOLF_NMEA?".nmea":".pos"); - for (p=ofile;*p;p++) if (*p=='*') *p='0'; - OutputFile->Text=ofile; +void __fastcall TMainForm::SetOutFile(void) { + AnsiString InputFile1_Text = InputFile1->Text; + AnsiString OutDir_Text = OutDir->Text; + char *p, ofile[1024], ifile[1024]; + + if (InputFile1->Text == "") return; + + strcpy(ifile, InputFile1_Text.c_str()); + + if (OutDirEna->Checked) { + if ((p = strrchr(ifile, '\\'))) + p++; + else + p = ifile; + sprintf(ofile, "%s\\%s", OutDir_Text.c_str(), p); + } else { + strcpy(ofile, ifile); + } + if (!(p = strrchr(ofile, '.'))) p = ofile + strlen(ofile); + strcpy(p, SolFormat == SOLF_NMEA ? ".nmea" : ".pos"); + for (p = ofile; *p; p++) + if (*p == '*') *p = '0'; + OutputFile->Text = ofile; } // execute post-processing -------------------------------------------------- -int __fastcall TMainForm::ExecProc(void) -{ - AnsiString InputFile1_Text=InputFile1->Text,InputFile2_Text=InputFile2->Text; - AnsiString InputFile3_Text=InputFile3->Text,InputFile4_Text=InputFile4->Text; - AnsiString InputFile5_Text=InputFile5->Text,InputFile6_Text=InputFile6->Text; - AnsiString InputFile7_Text=InputFile7->Text,InputFile8_Text=InputFile8->Text; - AnsiString InputFile9_Text=InputFile9->Text,InputFile10_Text=InputFile10->Text; - AnsiString OutputFile_Text=OutputFile->Text; - FILE *fp; - prcopt_t prcopt=prcopt_default; - solopt_t solopt=solopt_default; - filopt_t filopt={""}; - gtime_t ts={0},te={0}; - double ti=0.0,tu=0.0; - int i,n=0,stat; - char infile_[10][1024]={""},*infile[10],outfile[1024]; - char *rov,*base,*p,*q,*r; - - // get processing options - if (TimeStart->Checked) ts=GetTime1(); - if (TimeEnd ->Checked) te=GetTime2(); - if (TimeIntF ->Checked) ti=str2dbl(TimeInt ->Text); - if (TimeUnitF->Checked) tu=str2dbl(TimeUnit->Text)*3600.0; - - if (!GetOption(prcopt,solopt,filopt)) return 0; - - // set input/output files - for (i=0;i<10;i++) infile[i]=infile_[i]; - - strcpy(infile[n++],InputFile1_Text.c_str()); - - if (PMODE_DGPS<=prcopt.mode&&prcopt.mode<=PMODE_FIXED) { - strcpy(infile[n++],InputFile2_Text.c_str()); - } - if (InputFile3->Text!="") { - strcpy(infile[n++],InputFile3_Text.c_str()); - } - else if (!ObsToNav(InputFile1_Text.c_str(),infile[n++])) { - showmsg((char *)"error: no navigation data"); - return 0; - } - if (InputFile4_Text!="") { - strcpy(infile[n++],InputFile4_Text.c_str()); - } - if (InputFile5_Text!="") { - strcpy(infile[n++],InputFile5_Text.c_str()); - } - if (InputFile6_Text!="") { - strcpy(infile[n++],InputFile6_Text.c_str()); - } - if (InputFile7_Text!="") { - strcpy(infile[n++],InputFile7_Text.c_str()); - } - if (InputFile8_Text!="") { - strcpy(infile[n++],InputFile8_Text.c_str()); - } - if (InputFile9_Text!="") { - strcpy(infile[n++],InputFile9_Text.c_str()); - } - if (InputFile10_Text!="") { - strcpy(infile[n++],InputFile10_Text.c_str()); - } - strcpy(outfile,OutputFile_Text.c_str()); - - // confirm overwrite - if (!TimeStart->Checked||!TimeEnd->Checked) { - if ((fp=fopen(outfile,"r"))) { - fclose(fp); - ConfDialog->Label2->Caption=outfile; - if (ConfDialog->ShowModal()!=mrOk) return 0; - } - } - // set rover and base station list - rov =new char [strlen(RovList .c_str())]; - base=new char [strlen(BaseList.c_str())]; - - for (p=RovList.c_str(),r=rov;*p;p=q+2) { - - if (!(q=strstr(p,"\r\n"))) { - if (*p!='#') strcpy(r,p); break; - } - else if (*p!='#') { - strncpy(r,p,q-p); r+=q-p; - strcpy(r++," "); - } - } - for (p=BaseList.c_str(),r=base;*p;p=q+2) { - - if (!(q=strstr(p,"\r\n"))) { - if (*p!='#') strcpy(r,p); break; - } - else if (*p!='#') { - strncpy(r,p,q-p); r+=q-p; - strcpy(r++," "); - } - } - Progress->Position=0; - showmsg((char *)"reading..."); - - // post processing positioning - if ((stat=postpos(ts,te,ti,tu,&prcopt,&solopt,&filopt,(const char **)infile,n,(const char *)outfile, - (const char *)rov,base))==1) { - showmsg((char *)"aborted"); - } - delete [] rov ; - delete [] base; - - return stat; +int __fastcall TMainForm::ExecProc(void) { + AnsiString InputFile1_Text = InputFile1->Text, InputFile2_Text = InputFile2->Text; + AnsiString InputFile3_Text = InputFile3->Text, InputFile4_Text = InputFile4->Text; + AnsiString InputFile5_Text = InputFile5->Text, InputFile6_Text = InputFile6->Text; + AnsiString InputFile7_Text = InputFile7->Text, InputFile8_Text = InputFile8->Text; + AnsiString InputFile9_Text = InputFile9->Text, InputFile10_Text = InputFile10->Text; + AnsiString OutputFile_Text = OutputFile->Text; + FILE *fp; + prcopt_t prcopt = prcopt_default; + solopt_t solopt = solopt_default; + filopt_t filopt = {""}; + gtime_t ts = {0}, te = {0}; + double ti = 0.0, tu = 0.0; + int i, n = 0, stat; + char infile_[10][1024] = {""}, *infile[10], outfile[1024]; + char *rov, *base, *p, *q, *r; + + // get processing options + if (TimeStart->Checked) ts = GetTime1(); + if (TimeEnd->Checked) te = GetTime2(); + if (TimeIntF->Checked) ti = str2dbl(TimeInt->Text); + if (TimeUnitF->Checked) tu = str2dbl(TimeUnit->Text) * 3600.0; + + if (!GetOption(prcopt, solopt, filopt)) return 0; + + // set input/output files + for (i = 0; i < 10; i++) infile[i] = infile_[i]; + + strcpy(infile[n++], InputFile1_Text.c_str()); + + if (PMODE_DGPS <= prcopt.mode && prcopt.mode <= PMODE_FIXED) { + strcpy(infile[n++], InputFile2_Text.c_str()); + } + if (InputFile3->Text != "") { + strcpy(infile[n++], InputFile3_Text.c_str()); + } else if (!ObsToNav(InputFile1_Text.c_str(), infile[n++])) { + showmsg((char *)"error: no navigation data"); + return 0; + } + if (InputFile4_Text != "") { + strcpy(infile[n++], InputFile4_Text.c_str()); + } + if (InputFile5_Text != "") { + strcpy(infile[n++], InputFile5_Text.c_str()); + } + if (InputFile6_Text != "") { + strcpy(infile[n++], InputFile6_Text.c_str()); + } + if (InputFile7_Text != "") { + strcpy(infile[n++], InputFile7_Text.c_str()); + } + if (InputFile8_Text != "") { + strcpy(infile[n++], InputFile8_Text.c_str()); + } + if (InputFile9_Text != "") { + strcpy(infile[n++], InputFile9_Text.c_str()); + } + if (InputFile10_Text != "") { + strcpy(infile[n++], InputFile10_Text.c_str()); + } + strcpy(outfile, OutputFile_Text.c_str()); + + // confirm overwrite + if (!TimeStart->Checked || !TimeEnd->Checked) { + if ((fp = fopen(outfile, "r"))) { + fclose(fp); + ConfDialog->Label2->Caption = outfile; + if (ConfDialog->ShowModal() != mrOk) return 0; + } + } + // set rover and base station list + rov = new char[strlen(RovList.c_str())]; + base = new char[strlen(BaseList.c_str())]; + + for (p = RovList.c_str(), r = rov; *p; p = q + 2) { + if (!(q = strstr(p, "\r\n"))) { + if (*p != '#') strcpy(r, p); + break; + } else if (*p != '#') { + strncpy(r, p, q - p); + r += q - p; + strcpy(r++, " "); + } + } + for (p = BaseList.c_str(), r = base; *p; p = q + 2) { + if (!(q = strstr(p, "\r\n"))) { + if (*p != '#') strcpy(r, p); + break; + } else if (*p != '#') { + strncpy(r, p, q - p); + r += q - p; + strcpy(r++, " "); + } + } + Progress->Position = 0; + showmsg((char *)"reading..."); + + // post processing positioning + if ((stat = postpos(ts, te, ti, tu, &prcopt, &solopt, &filopt, (const char **)infile, n, + (const char *)outfile, (const char *)rov, base)) == 1) { + showmsg((char *)"aborted"); + } + delete[] rov; + delete[] base; + + return stat; } // get processing and solution options -------------------------------------- -int __fastcall TMainForm::GetOption(prcopt_t &prcopt, solopt_t &solopt, - filopt_t &filopt) -{ - char buff[1024],id[32],*p; - int sat,ex; - int ppp=PosMode>=PMODE_PPP_KINEMA; - - // processing options - prcopt.mode =PosMode; - prcopt.soltype =Solution; - prcopt.nf =Freq+1; - prcopt.navsys =NavSys; - prcopt.elmin =ElMask*D2R; - prcopt.snrmask =SnrMask; - prcopt.sateph =SatEphem; - prcopt.modear =AmbRes; - prcopt.glomodear=GloAmbRes; - prcopt.bdsmodear=BdsAmbRes; - prcopt.maxout =OutCntResetAmb; - prcopt.minfix =FixCntHoldAmb; - prcopt.minlock =LockCntFixAmb; - prcopt.ionoopt =IonoOpt; - prcopt.tropopt =TropOpt; - prcopt.posopt[0]=PosOpt[0]; - prcopt.posopt[1]=PosOpt[1]; - prcopt.posopt[2]=PosOpt[2]; - prcopt.posopt[3]=PosOpt[3]; - prcopt.posopt[4]=PosOpt[4]; - prcopt.posopt[5]=PosOpt[5]; - prcopt.dynamics =DynamicModel; - prcopt.tidecorr =TideCorr; - if (prcopt.tidecorr > 1) prcopt.tidecorr = 7; - prcopt.armaxiter=ARIter; - prcopt.niter =NumIter; - prcopt.minfixsats=MinFixSats; - prcopt.minholdsats=MinHoldSats; - prcopt.mindropsats=MinDropSats; - prcopt.arfilter=ARFilter; - prcopt.intpref =IntpRefObs; - prcopt.sbassatsel=SbasSat; - prcopt.eratio[0]=MeasErrR1; - prcopt.eratio[1]=MeasErrR2; - prcopt.eratio[2]=MeasErrR5; - prcopt.eratio[3]=MeasErrR6; - prcopt.err[1] =MeasErr2; - prcopt.err[2] =MeasErr3; - prcopt.err[3] =MeasErr4; - prcopt.err[4] =MeasErr5; - prcopt.err[5] =MeasErr6; - prcopt.err[6] =MeasErr7; - prcopt.err[7] =MeasErr8; - prcopt.prn[0] =PrNoise1; - prcopt.prn[1] =PrNoise2; - prcopt.prn[2] =PrNoise3; - prcopt.prn[3] =PrNoise4; - prcopt.prn[4] =PrNoise5; - prcopt.sclkstab =SatClkStab; - prcopt.thresar[0]=ValidThresAR; - prcopt.thresar[1]=MaxPosVarAR; - prcopt.thresar[2]=GloHwBias; - prcopt.thresar[3]=ThresAR3; - prcopt.thresar[4]=ThresAR4; - prcopt.thresar[5]=ValidThresARMin; - prcopt.thresar[6]=ValidThresARMax; - prcopt.elmaskar =ElMaskAR*D2R; - prcopt.elmaskhold=ElMaskHold*D2R; - prcopt.thresslip=SlipThres; - prcopt.thresdop=DopThres; - prcopt.maxtdiff =MaxAgeDiff; - prcopt.maxinno[1]=RejectCode; - prcopt.maxinno[0]=RejectPhase; - prcopt.varholdamb=VarHoldAmb; - prcopt.gainholdamb=GainHoldAmb; - prcopt.outsingle=OutputSingle; - if (BaseLineConst) { - prcopt.baseline[0]=BaseLine[0]; - prcopt.baseline[1]=BaseLine[1]; - } - else { - prcopt.baseline[0]=0.0; - prcopt.baseline[1]=0.0; - } - for (int i=0;i<3;i++) prcopt.ru[i]=RovPos[i]; - if (RovPosType<=2) { - prcopt.rovpos = RovPosType < 2 ? POSOPT_POS_LLH : POSOPT_POS_XYZ; - } - else prcopt.rovpos=RovPosType-1; /* 1:single,2:posfile,3:rinex */ - - for (int i=0;i<3;i++) prcopt.rb[i]=RefPos[i]; - if (RefPosType<=2) { - prcopt.refpos = RefPosType < 2 ? POSOPT_POS_LLH : POSOPT_POS_XYZ; - } - else prcopt.refpos=RefPosType-1; - - prcopt.antdel[0][0]=RovAntE; - prcopt.antdel[0][1]=RovAntN; - prcopt.antdel[0][2]=RovAntU; - if (RovAntPcv) { - strcpy(prcopt.anttype[0],RovAnt.c_str()); - } - prcopt.antdel[1][0]=RefAntE; - prcopt.antdel[1][1]=RefAntN; - prcopt.antdel[1][2]=RefAntU; - if (RefAntPcv) { - strcpy(prcopt.anttype[1],RefAnt.c_str()); - } - if (ExSats!="") { // excluded satellites - strcpy(buff,ExSats.c_str()); - for (p=strtok(buff," ");p;p=strtok(NULL," ")) { - if (*p=='+') {ex=2; p++;} else ex=1; - if (!(sat=satid2no(p))) continue; - prcopt.exsats[sat-1]=ex; - } - } - strcpy(prcopt.rnxopt[0],RnxOpts1.c_str()); - strcpy(prcopt.rnxopt[1],RnxOpts2.c_str()); - strcpy(prcopt.pppopt,PPPOpts.c_str()); - - // solution options - solopt.posf =SolFormat; - solopt.times =TimeFormat==0?TIMES_GPST:(TimeFormat - 1); - solopt.timef =TimeFormat==0?0:1; - solopt.timeu =TimeDecimal<=0?0:TimeDecimal; - solopt.degf =LatLonFormat; - solopt.outhead =OutputHead; - solopt.outopt =OutputOpt; - solopt.outvel =OutputVel; - solopt.maxsolstd=MaxSolStd; - solopt.datum =OutputDatum; - solopt.height =OutputHeight; - solopt.geoid =OutputGeoid; - solopt.solstatic=SolStatic; - solopt.sstat =DebugStatus; - solopt.trace =DebugTrace; - strcpy(solopt.sep,FieldSep!=""?FieldSep.c_str():" "); - sprintf(solopt.prog,"%s-%s %s",PRGNAME,VER_RTKLIB,PATCH_LEVEL); - - // file options - strcpy(filopt.satantp,SatPcvFile.c_str()); - strcpy(filopt.rcvantp,AntPcvFile.c_str()); - strcpy(filopt.stapos, StaPosFile.c_str()); - strcpy(filopt.geoid, GeoidDataFile.c_str()); - strcpy(filopt.iono, IonoFile.c_str()); - strcpy(filopt.eop, EOPFile.c_str()); - strcpy(filopt.dcb, DCBFile.c_str()); - strcpy(filopt.blq, BLQFile.c_str()); - - return 1; +int __fastcall TMainForm::GetOption(prcopt_t &prcopt, solopt_t &solopt, filopt_t &filopt) { + char buff[1024], id[32], *p; + int sat, ex; + int ppp = PosMode >= PMODE_PPP_KINEMA; + + // processing options + prcopt.mode = PosMode; + prcopt.soltype = Solution; + prcopt.nf = Freq + 1; + prcopt.navsys = NavSys; + prcopt.elmin = ElMask * D2R; + prcopt.snrmask = SnrMask; + prcopt.sateph = SatEphem; + prcopt.modear = AmbRes; + prcopt.glomodear = GloAmbRes; + prcopt.bdsmodear = BdsAmbRes; + prcopt.maxout = OutCntResetAmb; + prcopt.minfix = FixCntHoldAmb; + prcopt.minlock = LockCntFixAmb; + prcopt.ionoopt = IonoOpt; + prcopt.tropopt = TropOpt; + prcopt.posopt[0] = PosOpt[0]; + prcopt.posopt[1] = PosOpt[1]; + prcopt.posopt[2] = PosOpt[2]; + prcopt.posopt[3] = PosOpt[3]; + prcopt.posopt[4] = PosOpt[4]; + prcopt.posopt[5] = PosOpt[5]; + prcopt.dynamics = DynamicModel; + prcopt.tidecorr = TideCorr; + if (prcopt.tidecorr > 1) prcopt.tidecorr = 7; + prcopt.armaxiter = ARIter; + prcopt.niter = NumIter; + prcopt.minfixsats = MinFixSats; + prcopt.minholdsats = MinHoldSats; + prcopt.mindropsats = MinDropSats; + prcopt.arfilter = ARFilter; + prcopt.intpref = IntpRefObs; + prcopt.sbassatsel = SbasSat; + prcopt.eratio[0] = MeasErrR1; + prcopt.eratio[1] = MeasErrR2; + prcopt.eratio[2] = MeasErrR5; + prcopt.eratio[3] = MeasErrR6; + prcopt.err[1] = MeasErr2; + prcopt.err[2] = MeasErr3; + prcopt.err[3] = MeasErr4; + prcopt.err[4] = MeasErr5; + prcopt.err[5] = MeasErr6; + prcopt.err[6] = MeasErr7; + prcopt.err[7] = MeasErr8; + prcopt.prn[0] = PrNoise1; + prcopt.prn[1] = PrNoise2; + prcopt.prn[2] = PrNoise3; + prcopt.prn[3] = PrNoise4; + prcopt.prn[4] = PrNoise5; + prcopt.sclkstab = SatClkStab; + prcopt.thresar[0] = ValidThresAR; + prcopt.thresar[1] = MaxPosVarAR; + prcopt.thresar[2] = GloHwBias; + prcopt.thresar[3] = ThresAR3; + prcopt.thresar[4] = ThresAR4; + prcopt.thresar[5] = ValidThresARMin; + prcopt.thresar[6] = ValidThresARMax; + prcopt.elmaskar = ElMaskAR * D2R; + prcopt.elmaskhold = ElMaskHold * D2R; + prcopt.thresslip = SlipThres; + prcopt.thresdop = DopThres; + prcopt.maxtdiff = MaxAgeDiff; + prcopt.maxinno[1] = RejectCode; + prcopt.maxinno[0] = RejectPhase; + prcopt.varholdamb = VarHoldAmb; + prcopt.gainholdamb = GainHoldAmb; + prcopt.outsingle = OutputSingle; + if (BaseLineConst) { + prcopt.baseline[0] = BaseLine[0]; + prcopt.baseline[1] = BaseLine[1]; + } else { + prcopt.baseline[0] = 0.0; + prcopt.baseline[1] = 0.0; + } + for (int i = 0; i < 3; i++) prcopt.ru[i] = RovPos[i]; + if (RovPosType <= 2) { + prcopt.rovpos = RovPosType < 2 ? POSOPT_POS_LLH : POSOPT_POS_XYZ; + } else + prcopt.rovpos = RovPosType - 1; /* 1:single,2:posfile,3:rinex */ + + for (int i = 0; i < 3; i++) prcopt.rb[i] = RefPos[i]; + if (RefPosType <= 2) { + prcopt.refpos = RefPosType < 2 ? POSOPT_POS_LLH : POSOPT_POS_XYZ; + } else + prcopt.refpos = RefPosType - 1; + + prcopt.antdel[0][0] = RovAntE; + prcopt.antdel[0][1] = RovAntN; + prcopt.antdel[0][2] = RovAntU; + if (RovAntPcv) { + strcpy(prcopt.anttype[0], RovAnt.c_str()); + } + prcopt.antdel[1][0] = RefAntE; + prcopt.antdel[1][1] = RefAntN; + prcopt.antdel[1][2] = RefAntU; + if (RefAntPcv) { + strcpy(prcopt.anttype[1], RefAnt.c_str()); + } + if (ExSats != "") { // excluded satellites + strcpy(buff, ExSats.c_str()); + for (p = strtok(buff, " "); p; p = strtok(NULL, " ")) { + if (*p == '+') { + ex = 2; + p++; + } else + ex = 1; + if (!(sat = satid2no(p))) continue; + prcopt.exsats[sat - 1] = ex; + } + } + strcpy(prcopt.rnxopt[0], RnxOpts1.c_str()); + strcpy(prcopt.rnxopt[1], RnxOpts2.c_str()); + strcpy(prcopt.pppopt, PPPOpts.c_str()); + + // solution options + solopt.posf = SolFormat; + solopt.times = TimeFormat == 0 ? TIMES_GPST : (TimeFormat - 1); + solopt.timef = TimeFormat == 0 ? 0 : 1; + solopt.timeu = TimeDecimal <= 0 ? 0 : TimeDecimal; + solopt.degf = LatLonFormat; + solopt.outhead = OutputHead; + solopt.outopt = OutputOpt; + solopt.outvel = OutputVel; + solopt.maxsolstd = MaxSolStd; + solopt.datum = OutputDatum; + solopt.height = OutputHeight; + solopt.geoid = OutputGeoid; + solopt.solstatic = SolStatic; + solopt.sstat = DebugStatus; + solopt.trace = DebugTrace; + strcpy(solopt.sep, FieldSep != "" ? FieldSep.c_str() : " "); + sprintf(solopt.prog, "%s-%s %s", PRGNAME, VER_RTKLIB, PATCH_LEVEL); + + // file options + strcpy(filopt.satantp, SatPcvFile.c_str()); + strcpy(filopt.rcvantp, AntPcvFile.c_str()); + strcpy(filopt.stapos, StaPosFile.c_str()); + strcpy(filopt.geoid, GeoidDataFile.c_str()); + strcpy(filopt.iono, IonoFile.c_str()); + strcpy(filopt.eop, EOPFile.c_str()); + strcpy(filopt.dcb, DCBFile.c_str()); + strcpy(filopt.blq, BLQFile.c_str()); + + return 1; } // observation file to nav file --------------------------------------------- -int __fastcall TMainForm::ObsToNav(const char *obsfile, char *navfile) -{ - char *p; - strcpy(navfile,obsfile); - if (!(p=strrchr(navfile,'.'))) return 0; - if (strlen(p)==4&&*(p+3)=='o') *(p+3)='*'; - else if (strlen(p)==4&&*(p+3)=='d') *(p+3)='*'; - else if (strlen(p)==4&&*(p+3)=='O') *(p+3)='*'; - else if (!strcmp(p,".obs")) strcpy(p,".*nav"); - else if (!strcmp(p,".OBS")) strcpy(p,".*NAV"); - else if (!strcmp(p,".gz")||!strcmp(p,".Z")) { - if (*(p-1)=='o') *(p-1)='*'; - else if (*(p-1)=='d') *(p-1)='*'; - else if (*(p-1)=='O') *(p-1)='*'; - else return 0; - } - else return 0; - return 1; +int __fastcall TMainForm::ObsToNav(const char *obsfile, char *navfile) { + char *p; + strcpy(navfile, obsfile); + if (!(p = strrchr(navfile, '.'))) return 0; + if (strlen(p) == 4 && *(p + 3) == 'o') + *(p + 3) = '*'; + else if (strlen(p) == 4 && *(p + 3) == 'd') + *(p + 3) = '*'; + else if (strlen(p) == 4 && *(p + 3) == 'O') + *(p + 3) = '*'; + else if (!strcmp(p, ".obs")) + strcpy(p, ".*nav"); + else if (!strcmp(p, ".OBS")) + strcpy(p, ".*NAV"); + else if (!strcmp(p, ".gz") || !strcmp(p, ".Z")) { + if (*(p - 1) == 'o') + *(p - 1) = '*'; + else if (*(p - 1) == 'd') + *(p - 1) = '*'; + else if (*(p - 1) == 'O') + *(p - 1) = '*'; + else + return 0; + } else + return 0; + return 1; } // replace file path with keywords ------------------------------------------ -AnsiString __fastcall TMainForm::FilePath(AnsiString file) -{ - AnsiString s; - gtime_t ts={0}; - char rov[256]="",base[256]="",path[1024],*p,*q; - - if (TimeStart->Checked) ts=GetTime1(); - - for (p=RovList.c_str();(q=strstr(p,"\r\n"));p=q+2) { - if (*p&&*p!='#') break; - } - if (!q) strcpy(rov,p); else strncpy(rov,p,q-p); - - for (p=BaseList.c_str();(q=strstr(p,"\r\n"));p=q+2) { - if (*p&&p[0]!='#') break; - } - if (!q) strcpy(base,p); else strncpy(base,p,q-p); - - reppath(file.c_str(),path,ts,rov,base); - - return (s=path); +AnsiString __fastcall TMainForm::FilePath(AnsiString file) { + AnsiString s; + gtime_t ts = {0}; + char rov[256] = "", base[256] = "", path[1024], *p, *q; + + if (TimeStart->Checked) ts = GetTime1(); + + for (p = RovList.c_str(); (q = strstr(p, "\r\n")); p = q + 2) { + if (*p && *p != '#') break; + } + if (!q) + strcpy(rov, p); + else + strncpy(rov, p, q - p); + + for (p = BaseList.c_str(); (q = strstr(p, "\r\n")); p = q + 2) { + if (*p && p[0] != '#') break; + } + if (!q) + strcpy(base, p); + else + strncpy(base, p, q - p); + + reppath(file.c_str(), path, ts, rov, base); + + return (s = path); } // read history ------------------------------------------------------------- -TStringList * __fastcall TMainForm::ReadList(TIniFile *ini, AnsiString cat, - AnsiString key) -{ - TStringList *list=new TStringList; - AnsiString s,item; - int i; - - for (i=0;i<100;i++) { - item=ini->ReadString(cat,s.sprintf("%s_%03d",key.c_str(),i),""); - if (item!=""&&list->IndexOf(item)<0) list->Add(item); - } - return list; +TStringList *__fastcall TMainForm::ReadList(TIniFile *ini, AnsiString cat, AnsiString key) { + TStringList *list = new TStringList; + AnsiString s, item; + int i; + + for (i = 0; i < 100; i++) { + item = ini->ReadString(cat, s.sprintf("%s_%03d", key.c_str(), i), ""); + if (item != "" && list->IndexOf(item) < 0) list->Add(item); + } + return list; } // write history ------------------------------------------------------------ -void __fastcall TMainForm::WriteList(TIniFile *ini, AnsiString cat, - AnsiString key, TStrings *list) -{ - AnsiString s; - int i; - - for (i=0;iCount;i++) { - ini->WriteString(cat,s.sprintf("%s_%03d",key.c_str(),i),list->Strings[i]); - } +void __fastcall TMainForm::WriteList(TIniFile *ini, AnsiString cat, AnsiString key, + TStrings *list) { + AnsiString s; + int i; + + for (i = 0; i < list->Count; i++) { + ini->WriteString(cat, s.sprintf("%s_%03d", key.c_str(), i), list->Strings[i]); + } } // add history -------------------------------------------------------------- -void __fastcall TMainForm::AddHist(TComboBox *combo) -{ - AnsiString hist=combo->Text; - if (hist=="") return; - TStrings *list=combo->Items; - int i=list->IndexOf(hist); - if (i>=0) list->Delete(i); - list->Insert(0,hist); - for (int i=list->Count-1;i>=MAXHIST;i--) list->Delete(i); - combo->ItemIndex=0; +void __fastcall TMainForm::AddHist(TComboBox *combo) { + AnsiString hist = combo->Text; + if (hist == "") return; + TStrings *list = combo->Items; + int i = list->IndexOf(hist); + if (i >= 0) list->Delete(i); + list->Insert(0, hist); + for (int i = list->Count - 1; i >= MAXHIST; i--) list->Delete(i); + combo->ItemIndex = 0; } // execute command ---------------------------------------------------------- -int __fastcall TMainForm::ExecCmd(AnsiString cmd, int show) -{ - PROCESS_INFORMATION info; - STARTUPINFO si={0}; - si.cb=sizeof(si); - char *p=cmd.c_str(); - - if (!CreateProcess(NULL,p,NULL,NULL,false,show?0:CREATE_NO_WINDOW,NULL, - NULL,&si,&info)) return 0; - CloseHandle(info.hProcess); - CloseHandle(info.hThread); - return 1; +int __fastcall TMainForm::ExecCmd(AnsiString cmd, int show) { + PROCESS_INFORMATION info; + STARTUPINFO si = {0}; + si.cb = sizeof(si); + char *p = cmd.c_str(); + + if (!CreateProcess(NULL, p, NULL, NULL, false, show ? 0 : CREATE_NO_WINDOW, NULL, NULL, &si, + &info)) + return 0; + CloseHandle(info.hProcess); + CloseHandle(info.hThread); + return 1; } // view file ---------------------------------------------------------------- -void __fastcall TMainForm::ViewFile(AnsiString file) -{ - TTextViewer *viewer; - AnsiString f; - char tmpfile[1024]; - int cstat; - - if (file=="") return; - cstat=rtk_uncompress(file.c_str(),tmpfile); - f=!cstat?file.c_str():tmpfile; - - viewer=new TTextViewer(Application); - viewer->Caption=file; - viewer->Show(); - viewer->Read(f); - if (cstat==1) remove(tmpfile); +void __fastcall TMainForm::ViewFile(AnsiString file) { + TTextViewer *viewer; + AnsiString f; + char tmpfile[1024]; + int cstat; + + if (file == "") return; + cstat = rtk_uncompress(file.c_str(), tmpfile); + f = !cstat ? file.c_str() : tmpfile; + + viewer = new TTextViewer(Application); + viewer->Caption = file; + viewer->Show(); + viewer->Read(f); + if (cstat == 1) remove(tmpfile); } // show message in message area --------------------------------------------- -void __fastcall TMainForm::ShowMsg(char *msg) -{ - Message->Caption=msg; -} +void __fastcall TMainForm::ShowMsg(char *msg) { Message->Caption = msg; } // get time from time-1 ----------------------------------------------------- -gtime_t _fastcall TMainForm::GetTime1(void) -{ - AnsiString TimeY1_Text=TimeY1->Text,TimeH1_Text=TimeH1->Text; - double ep[]={2000,1,1,0,0,0}; - - sscanf(TimeY1_Text.c_str(),"%lf/%lf/%lf",ep,ep+1,ep+2); - sscanf(TimeH1_Text.c_str(),"%lf:%lf:%lf",ep+3,ep+4,ep+5); - return epoch2time(ep); +gtime_t _fastcall TMainForm::GetTime1(void) { + AnsiString TimeY1_Text = TimeY1->Text, TimeH1_Text = TimeH1->Text; + double ep[] = {2000, 1, 1, 0, 0, 0}; + + sscanf(TimeY1_Text.c_str(), "%lf/%lf/%lf", ep, ep + 1, ep + 2); + sscanf(TimeH1_Text.c_str(), "%lf:%lf:%lf", ep + 3, ep + 4, ep + 5); + return epoch2time(ep); } // get time from time-2 ----------------------------------------------------- -gtime_t _fastcall TMainForm::GetTime2(void) -{ - AnsiString TimeY2_Text=TimeY2->Text,TimeH2_Text=TimeH2->Text; - double ep[]={2000,1,1,0,0,0}; - - sscanf(TimeY2_Text.c_str(),"%lf/%lf/%lf",ep,ep+1,ep+2); - sscanf(TimeH2_Text.c_str(),"%lf:%lf:%lf",ep+3,ep+4,ep+5); - return epoch2time(ep); +gtime_t _fastcall TMainForm::GetTime2(void) { + AnsiString TimeY2_Text = TimeY2->Text, TimeH2_Text = TimeH2->Text; + double ep[] = {2000, 1, 1, 0, 0, 0}; + + sscanf(TimeY2_Text.c_str(), "%lf/%lf/%lf", ep, ep + 1, ep + 2); + sscanf(TimeH2_Text.c_str(), "%lf:%lf:%lf", ep + 3, ep + 4, ep + 5); + return epoch2time(ep); } // set time to time-1 ------------------------------------------------------- -void _fastcall TMainForm::SetTime1(gtime_t time) -{ - AnsiString s; - double ep[6]; - - time2epoch(time,ep); - TimeY1->Text=s.sprintf("%04.0f/%02.0f/%02.0f",ep[0],ep[1],ep[2]); - TimeH1->Text=s.sprintf("%02.0f:%02.0f:%02.0f",ep[3],ep[4],ep[5]); - TimeY1->SelStart=10; TimeH1->SelStart=10; +void _fastcall TMainForm::SetTime1(gtime_t time) { + AnsiString s; + double ep[6]; + + time2epoch(time, ep); + TimeY1->Text = s.sprintf("%04.0f/%02.0f/%02.0f", ep[0], ep[1], ep[2]); + TimeH1->Text = s.sprintf("%02.0f:%02.0f:%02.0f", ep[3], ep[4], ep[5]); + TimeY1->SelStart = 10; + TimeH1->SelStart = 10; } // set time to time-2 ------------------------------------------------------- -void _fastcall TMainForm::SetTime2(gtime_t time) -{ - AnsiString s; - double ep[6]; - - time2epoch(time,ep); - TimeY2->Text=s.sprintf("%04.0f/%02.0f/%02.0f",ep[0],ep[1],ep[2]); - TimeH2->Text=s.sprintf("%02.0f:%02.0f:%02.0f",ep[3],ep[4],ep[5]); - TimeY2->SelStart=10; TimeH2->SelStart=10; +void _fastcall TMainForm::SetTime2(gtime_t time) { + AnsiString s; + double ep[6]; + + time2epoch(time, ep); + TimeY2->Text = s.sprintf("%04.0f/%02.0f/%02.0f", ep[0], ep[1], ep[2]); + TimeH2->Text = s.sprintf("%02.0f:%02.0f:%02.0f", ep[3], ep[4], ep[5]); + TimeY2->SelStart = 10; + TimeH2->SelStart = 10; } // update enable/disable of widgets ----------------------------------------- -void __fastcall TMainForm::UpdateEnable(void) -{ - int moder=PMODE_DGPS<=PosMode&&PosMode<=PMODE_FIXED; - - LabelInputFile1->Caption=moder?"RINEX OBS: Rover":"RINEX OBS"; - InputFile2 ->Enabled=moder; - BtnInputFile2 ->Enabled=moder; - BtnInputPlot2 ->Enabled=moder; - BtnInputView2 ->Enabled=moder; - BtnOutputView1 ->Enabled=DebugStatus>0; - BtnOutputView2 ->Enabled=DebugTrace >0; - LabelInputFile3->Enabled=moder; - TimeY1 ->Enabled=TimeStart->Checked; - TimeH1 ->Enabled=TimeStart->Checked; - TimeY1UD ->Enabled=TimeStart->Checked; - TimeH1UD ->Enabled=TimeStart->Checked; - BtnTime1 ->Enabled=TimeStart->Checked; - TimeY2 ->Enabled=TimeEnd ->Checked; - TimeH2 ->Enabled=TimeEnd ->Checked; - TimeY2UD ->Enabled=TimeEnd ->Checked; - TimeH2UD ->Enabled=TimeEnd ->Checked; - BtnTime2 ->Enabled=TimeEnd ->Checked; - TimeInt ->Enabled=TimeIntF ->Checked; - LabelTimeInt ->Enabled=TimeIntF ->Checked; - TimeUnitF ->Enabled=TimeStart->Checked&&TimeEnd ->Checked; - TimeUnit ->Enabled=TimeUnitF->Enabled&&TimeUnitF->Checked; - LabelTimeUnit ->Enabled=TimeUnitF->Enabled&&TimeUnitF->Checked; - OutDir ->Enabled=OutDirEna->Checked; - BtnOutDir ->Enabled=OutDirEna->Checked; - LabelOutDir ->Enabled=OutDirEna->Checked; +void __fastcall TMainForm::UpdateEnable(void) { + int moder = PMODE_DGPS <= PosMode && PosMode <= PMODE_FIXED; + + LabelInputFile1->Caption = moder ? "RINEX OBS: Rover" : "RINEX OBS"; + InputFile2->Enabled = moder; + BtnInputFile2->Enabled = moder; + BtnInputPlot2->Enabled = moder; + BtnInputView2->Enabled = moder; + BtnOutputView1->Enabled = DebugStatus > 0; + BtnOutputView2->Enabled = DebugTrace > 0; + LabelInputFile3->Enabled = moder; + TimeY1->Enabled = TimeStart->Checked; + TimeH1->Enabled = TimeStart->Checked; + TimeY1UD->Enabled = TimeStart->Checked; + TimeH1UD->Enabled = TimeStart->Checked; + BtnTime1->Enabled = TimeStart->Checked; + TimeY2->Enabled = TimeEnd->Checked; + TimeH2->Enabled = TimeEnd->Checked; + TimeY2UD->Enabled = TimeEnd->Checked; + TimeH2UD->Enabled = TimeEnd->Checked; + BtnTime2->Enabled = TimeEnd->Checked; + TimeInt->Enabled = TimeIntF->Checked; + LabelTimeInt->Enabled = TimeIntF->Checked; + TimeUnitF->Enabled = TimeStart->Checked && TimeEnd->Checked; + TimeUnit->Enabled = TimeUnitF->Enabled && TimeUnitF->Checked; + LabelTimeUnit->Enabled = TimeUnitF->Enabled && TimeUnitF->Checked; + OutDir->Enabled = OutDirEna->Checked; + BtnOutDir->Enabled = OutDirEna->Checked; + LabelOutDir->Enabled = OutDirEna->Checked; } // load options from ini file ----------------------------------------------- -void __fastcall TMainForm::LoadOpt(void) -{ - TIniFile *ini=new TIniFile(IniFile); - AnsiString s; - char *p; - - TimeStart->Checked =ini->ReadInteger("set","timestart", 0); - TimeEnd->Checked =ini->ReadInteger("set","timeend", 0); - TimeY1->Text =ini->ReadString ("set","timey1", "2000/01/01"); - TimeY1->Text =ini->ReadString ("set","timey1", "2000/01/01"); - TimeH1->Text =ini->ReadString ("set","timeh1", "00:00:00"); - TimeY2->Text =ini->ReadString ("set","timey2", "2000/01/01"); - TimeH2->Text =ini->ReadString ("set","timeh2", "00:00:00"); - TimeIntF ->Checked =ini->ReadInteger("set","timeintf", 0); - TimeInt->Text =ini->ReadString ("set","timeint", "0"); - TimeUnitF->Checked =ini->ReadInteger("set","timeunitf", 0); - TimeUnit->Text =ini->ReadString ("set","timeunit", "24"); - InputFile1->Text =ini->ReadString ("set","inputfile1", ""); - InputFile2->Text =ini->ReadString ("set","inputfile2", ""); - InputFile3->Text =ini->ReadString ("set","inputfile3", ""); - InputFile4->Text =ini->ReadString ("set","inputfile4", ""); - InputFile5->Text =ini->ReadString ("set","inputfile5", ""); - InputFile6->Text =ini->ReadString ("set","inputfile6", ""); - InputFile7->Text =ini->ReadString ("set","inputfile7", ""); - InputFile8->Text =ini->ReadString ("set","inputfile8", ""); - InputFile9->Text =ini->ReadString ("set","inputfile9", ""); - InputFile10->Text =ini->ReadString ("set","inputfile10", ""); - OutDirEna->Checked =ini->ReadInteger("set","outputdirena", 0); - OutDir->Text =ini->ReadString ("set","outputdir", ""); - OutputFile->Text =ini->ReadString ("set","outputfile", ""); - - InputFile1->Items =ReadList(ini,"hist","inputfile1"); - InputFile2->Items =ReadList(ini,"hist","inputfile2"); - InputFile3->Items =ReadList(ini,"hist","inputfile3"); - InputFile4->Items =ReadList(ini,"hist","inputfile4"); - InputFile5->Items =ReadList(ini,"hist","inputfile5"); - InputFile6->Items =ReadList(ini,"hist","inputfile6"); - InputFile7->Items =ReadList(ini,"hist","inputfile7"); - InputFile8->Items =ReadList(ini,"hist","inputfile8"); - InputFile9->Items =ReadList(ini,"hist","inputfile9"); - InputFile10->Items =ReadList(ini,"hist","inputfile10"); - OutputFile->Items =ReadList(ini,"hist","outputfile"); - - PosMode =ini->ReadInteger("opt","posmode", 2); - Freq =ini->ReadInteger("opt","freq", NFREQ-1); - Solution =ini->ReadInteger("opt","solution", 0); - ElMask =ini->ReadFloat ("opt","elmask", 15.0); - SnrMask.ena[0] =ini->ReadInteger("opt","snrmask_ena1", 0); - SnrMask.ena[1] =ini->ReadInteger("opt","snrmask_ena2", 0); - for (int i=0;iReadFloat("opt",s.sprintf("snrmask_%d_%d",i+1,j+1),35.0); - } - IonoOpt =ini->ReadInteger("opt","ionoopt", IONOOPT_BRDC); - TropOpt =ini->ReadInteger("opt","tropopt", TROPOPT_SAAS); - RcvBiasEst =ini->ReadInteger("opt","rcvbiasest", 0); - DynamicModel =ini->ReadInteger("opt","dynamicmodel", 1); - TideCorr =ini->ReadInteger("opt","tidecorr", 0); - SatEphem =ini->ReadInteger("opt","satephem", 0); - ExSats =ini->ReadString ("opt","exsats", ""); - NavSys =ini->ReadInteger("opt","navsys", SYS_GPS|SYS_GLO|SYS_GAL|SYS_QZS|SYS_CMP); - PosOpt[0] =ini->ReadInteger("opt","posopt1", 0); - PosOpt[1] =ini->ReadInteger("opt","posopt2", 0); - PosOpt[2] =ini->ReadInteger("opt","posopt3", 0); - PosOpt[3] =ini->ReadInteger("opt","posopt4", 0); - PosOpt[4] =ini->ReadInteger("opt","posopt5", 0); - PosOpt[5] =ini->ReadInteger("opt","posopt6", 0); - MapFunc =ini->ReadInteger("opt","mapfunc", 0); - - AmbRes =ini->ReadInteger("opt","ambres", 1); - GloAmbRes =ini->ReadInteger("opt","gloambres", 0); - BdsAmbRes =ini->ReadInteger("opt","bdsambres", 1); - ValidThresAR =ini->ReadFloat ("opt","validthresar", 3.0); - MaxPosVarAR =ini->ReadFloat ("opt","maxposvarar", 0.10); - GloHwBias =ini->ReadFloat ("opt","glohwbias", 0.00); - ThresAR3 =ini->ReadFloat ("opt","thresar3", 1E-9); - ThresAR4 =ini->ReadFloat ("opt","thresar4", 1E-5); - ValidThresARMin =ini->ReadFloat ("opt","validthresarmin", 3.0); - ValidThresARMax =ini->ReadFloat ("opt","validthresarmax", 3.0); - LockCntFixAmb =ini->ReadInteger("opt","lockcntfixamb", 0); - FixCntHoldAmb =ini->ReadInteger("opt","fixcntholdamb", 20); - ElMaskAR =ini->ReadFloat ("opt","elmaskar", 15.0); - ElMaskHold =ini->ReadFloat ("opt","elmaskhold", 15.0); - OutCntResetAmb =ini->ReadInteger("opt","outcntresetbias",20); - SlipThres =ini->ReadFloat ("opt","slipthres", 0.05); - DopThres =ini->ReadFloat ("opt","dopthres", 0.0); - MaxAgeDiff =ini->ReadFloat ("opt","maxagediff", 30.0); - RejectPhase =ini->ReadFloat ("opt","rejectphase", 5.0); - VarHoldAmb =ini->ReadFloat ("opt","varholdamb", 0.1); - GainHoldAmb =ini->ReadFloat ("opt","gainholdamb", 0.01); - RejectCode =ini->ReadFloat ("opt","rejectcode", 30.0); - ARIter =ini->ReadInteger("opt","ariter", 1); - NumIter =ini->ReadInteger("opt","numiter", 1); - MinFixSats =ini->ReadInteger("opt","minfixsats", 4); - MinHoldSats =ini->ReadInteger("opt","minholdsats", 5); - MinDropSats =ini->ReadInteger("opt","mindropsats", 10); - ARFilter =ini->ReadInteger("opt","arfilter", 1); - CodeSmooth =ini->ReadInteger("opt","codesmooth", 0); - BaseLine[0] =ini->ReadFloat ("opt","baselinelen", 0.0); - BaseLine[1] =ini->ReadFloat ("opt","baselinesig", 0.0); - BaseLineConst =ini->ReadInteger("opt","baselineconst", 0); - - SolFormat =ini->ReadInteger("opt","solformat", 0); - TimeFormat =ini->ReadInteger("opt","timeformat", 1); - TimeDecimal =ini->ReadInteger("opt","timedecimal", 3); - LatLonFormat =ini->ReadInteger("opt","latlonformat", 0); - FieldSep =ini->ReadString ("opt","fieldsep", ""); - OutputHead =ini->ReadInteger("opt","outputhead", 1); - OutputOpt =ini->ReadInteger("opt","outputopt", 1); - OutputVel =ini->ReadInteger("opt","outputvel", 0); - OutputSingle =ini->ReadInteger("opt","outputsingle", 0); - MaxSolStd =ini->ReadFloat ("opt","maxsolstd", 0.0); - OutputDatum =ini->ReadInteger("opt","outputdatum", 0); - OutputHeight =ini->ReadInteger("opt","outputheight", 0); - OutputGeoid =ini->ReadInteger("opt","outputgeoid", 0); - SolStatic =ini->ReadInteger("opt","solstatic", 0); - DebugTrace =ini->ReadInteger("opt","debugtrace", 0); - DebugStatus =ini->ReadInteger("opt","debugstatus", 2); - - MeasErrR1 =ini->ReadFloat ("opt","measeratio1",300.0); - MeasErrR2 =ini->ReadFloat ("opt","measeratio2",300.0); - MeasErrR5 =ini->ReadFloat ("opt","measeratio5",300.0); - MeasErrR6 =ini->ReadFloat ("opt","measeratio6",300.0); - MeasErr2 =ini->ReadFloat ("opt","measerr2", 0.003); - MeasErr3 =ini->ReadFloat ("opt","measerr3", 0.003); - MeasErr4 =ini->ReadFloat ("opt","measerr4", 0.000); - MeasErr5 =ini->ReadFloat ("opt","measerr5", 1.000); - MeasErr6 =ini->ReadFloat ("opt","measerr6", 52.00); - MeasErr7 =ini->ReadFloat ("opt","measerr7", 0.000); - MeasErr8 =ini->ReadFloat ("opt","measerr8", 0.000); - SatClkStab =ini->ReadFloat ("opt","satclkstab", 5E-12); - PrNoise1 =ini->ReadFloat ("opt","prnoise1", 1E-4); - PrNoise2 =ini->ReadFloat ("opt","prnoise2", 1E-3); - PrNoise3 =ini->ReadFloat ("opt","prnoise3", 1E-4); - PrNoise4 =ini->ReadFloat ("opt","prnoise4", 3.0); - PrNoise5 =ini->ReadFloat ("opt","prnoise5", 1.0); - - RovPosType =ini->ReadInteger("opt","rovpostype", 0); - RefPosType =ini->ReadInteger("opt","refpostype", 5); - RovPos[0] =ini->ReadFloat ("opt","rovpos1", 0.0); - RovPos[1] =ini->ReadFloat ("opt","rovpos2", 0.0); - RovPos[2] =ini->ReadFloat ("opt","rovpos3", 0.0); - RefPos[0] =ini->ReadFloat ("opt","refpos1", 0.0); - RefPos[1] =ini->ReadFloat ("opt","refpos2", 0.0); - RefPos[2] =ini->ReadFloat ("opt","refpos3", 0.0); - RovAntPcv =ini->ReadInteger("opt","rovantpcv", 0); - RefAntPcv =ini->ReadInteger("opt","refantpcv", 0); - RovAnt =ini->ReadString ("opt","rovant", ""); - RefAnt =ini->ReadString ("opt","refant", ""); - RovAntE =ini->ReadFloat ("opt","rovante", 0.0); - RovAntN =ini->ReadFloat ("opt","rovantn", 0.0); - RovAntU =ini->ReadFloat ("opt","rovantu", 0.0); - RefAntE =ini->ReadFloat ("opt","refante", 0.0); - RefAntN =ini->ReadFloat ("opt","refantn", 0.0); - RefAntU =ini->ReadFloat ("opt","refantu", 0.0); - - RnxOpts1 =ini->ReadString ("opt","rnxopts1", ""); - RnxOpts2 =ini->ReadString ("opt","rnxopts2", ""); - PPPOpts =ini->ReadString ("opt","pppopts", ""); - - AntPcvFile =ini->ReadString ("opt","antpcvfile", ""); - IntpRefObs =ini->ReadInteger("opt","intprefobs", 1); - SbasSat =ini->ReadInteger("opt","sbassat", 0); - NetRSCorr =ini->ReadInteger("opt","netrscorr", 0); - SatClkCorr =ini->ReadInteger("opt","satclkcorr", 0); - SbasCorr =ini->ReadInteger("opt","sbascorr", 0); - SbasCorr1 =ini->ReadInteger("opt","sbascorr1", 0); - SbasCorr2 =ini->ReadInteger("opt","sbascorr2", 0); - SbasCorr3 =ini->ReadInteger("opt","sbascorr3", 0); - SbasCorr4 =ini->ReadInteger("opt","sbascorr4", 0); - SbasCorrFile =ini->ReadString ("opt","sbascorrfile", ""); - PrecEphFile =ini->ReadString ("opt","precephfile", ""); - SatPcvFile =ini->ReadString ("opt","satpcvfile", ""); - StaPosFile =ini->ReadString ("opt","staposfile", ""); - GeoidDataFile =ini->ReadString ("opt","geoiddatafile", ""); - IonoFile =ini->ReadString ("opt","ionofile", ""); - EOPFile =ini->ReadString ("opt","eopfile", ""); - DCBFile =ini->ReadString ("opt","dcbfile", ""); - BLQFile =ini->ReadString ("opt","blqfile", ""); - GoogleEarthFile =ini->ReadString ("opt","googleearthfile",GOOGLE_EARTH); - - RovList=""; - for (int i=0;i<10;i++) { - RovList +=ini->ReadString("opt",s.sprintf("rovlist%d",i+1),""); - } - BaseList=""; - for (int i=0;i<10;i++) { - BaseList+=ini->ReadString("opt",s.sprintf("baselist%d",i+1),""); - } - for (p=RovList.c_str();*p;p++) { - if ((p=strstr(p,"@@"))) strncpy(p,"\r\n",2); else break; - } - for (p=BaseList.c_str();*p;p++) { - if ((p=strstr(p,"@@"))) strncpy(p,"\r\n",2); else break; - } - ConvDialog->TimeSpan ->Checked =ini->ReadInteger("conv","timespan", 0); - ConvDialog->TimeIntF ->Checked =ini->ReadInteger("conv","timeintf", 0); - ConvDialog->TimeY1 ->Text =ini->ReadString ("conv","timey1","2000/01/01"); - ConvDialog->TimeH1 ->Text =ini->ReadString ("conv","timeh1","00:00:00" ); - ConvDialog->TimeY2 ->Text =ini->ReadString ("conv","timey2","2000/01/01"); - ConvDialog->TimeH2 ->Text =ini->ReadString ("conv","timeh2","00:00:00" ); - ConvDialog->TimeInt ->Text =ini->ReadString ("conv","timeint", "0"); - ConvDialog->SingleMeanF->Checked =ini->ReadInteger("conv","mean", 0); - ConvDialog->TrackColor->ItemIndex=ini->ReadInteger("conv","trackcolor",5); - ConvDialog->PointColor->ItemIndex=ini->ReadInteger("conv","pointcolor",5); - ConvDialog->OutputAlt ->ItemIndex=ini->ReadInteger("conv","outputalt", 0); - ConvDialog->OutputTime->ItemIndex=ini->ReadInteger("conv","outputtime",0); - ConvDialog->AddOffset ->Checked =ini->ReadInteger("conv","addoffset", 0); - ConvDialog->Offset1 ->Text =ini->ReadString ("conv","offset1", "0"); - ConvDialog->Offset2 ->Text =ini->ReadString ("conv","offset2", "0"); - ConvDialog->Offset3 ->Text =ini->ReadString ("conv","offset3", "0"); - ConvDialog->Compress ->Checked =ini->ReadInteger("conv","compress", 0); - int format = ini->ReadInteger("conv","format", 0); - ConvDialog->FormatKML ->Checked = format == 0; - ConvDialog->FormatCSV ->Checked = format == 1; - ConvDialog->FormatGPX ->Checked = format != 0 && format != 1; - - TTextViewer::Color1=(TColor)ini->ReadInteger("viewer","color1",(int)clBlack); - TTextViewer::Color2=(TColor)ini->ReadInteger("viewer","color2",(int)clWhite); - TTextViewer::FontD=new TFont; - TTextViewer::FontD->Name=ini->ReadString ("viewer","fontname","Courier New"); - TTextViewer::FontD->Size=ini->ReadInteger("viewer","fontsize",9); - Width=ini->ReadInteger("window","width",486); - delete ini; +void __fastcall TMainForm::LoadOpt(void) { + TIniFile *ini = new TIniFile(IniFile); + AnsiString s; + char *p; + + TimeStart->Checked = ini->ReadInteger("set", "timestart", 0); + TimeEnd->Checked = ini->ReadInteger("set", "timeend", 0); + TimeY1->Text = ini->ReadString("set", "timey1", "2000/01/01"); + TimeY1->Text = ini->ReadString("set", "timey1", "2000/01/01"); + TimeH1->Text = ini->ReadString("set", "timeh1", "00:00:00"); + TimeY2->Text = ini->ReadString("set", "timey2", "2000/01/01"); + TimeH2->Text = ini->ReadString("set", "timeh2", "00:00:00"); + TimeIntF->Checked = ini->ReadInteger("set", "timeintf", 0); + TimeInt->Text = ini->ReadString("set", "timeint", "0"); + TimeUnitF->Checked = ini->ReadInteger("set", "timeunitf", 0); + TimeUnit->Text = ini->ReadString("set", "timeunit", "24"); + InputFile1->Text = ini->ReadString("set", "inputfile1", ""); + InputFile2->Text = ini->ReadString("set", "inputfile2", ""); + InputFile3->Text = ini->ReadString("set", "inputfile3", ""); + InputFile4->Text = ini->ReadString("set", "inputfile4", ""); + InputFile5->Text = ini->ReadString("set", "inputfile5", ""); + InputFile6->Text = ini->ReadString("set", "inputfile6", ""); + InputFile7->Text = ini->ReadString("set", "inputfile7", ""); + InputFile8->Text = ini->ReadString("set", "inputfile8", ""); + InputFile9->Text = ini->ReadString("set", "inputfile9", ""); + InputFile10->Text = ini->ReadString("set", "inputfile10", ""); + OutDirEna->Checked = ini->ReadInteger("set", "outputdirena", 0); + OutDir->Text = ini->ReadString("set", "outputdir", ""); + OutputFile->Text = ini->ReadString("set", "outputfile", ""); + + InputFile1->Items = ReadList(ini, "hist", "inputfile1"); + InputFile2->Items = ReadList(ini, "hist", "inputfile2"); + InputFile3->Items = ReadList(ini, "hist", "inputfile3"); + InputFile4->Items = ReadList(ini, "hist", "inputfile4"); + InputFile5->Items = ReadList(ini, "hist", "inputfile5"); + InputFile6->Items = ReadList(ini, "hist", "inputfile6"); + InputFile7->Items = ReadList(ini, "hist", "inputfile7"); + InputFile8->Items = ReadList(ini, "hist", "inputfile8"); + InputFile9->Items = ReadList(ini, "hist", "inputfile9"); + InputFile10->Items = ReadList(ini, "hist", "inputfile10"); + OutputFile->Items = ReadList(ini, "hist", "outputfile"); + + PosMode = ini->ReadInteger("opt", "posmode", 2); + Freq = ini->ReadInteger("opt", "freq", NFREQ - 1); + Solution = ini->ReadInteger("opt", "solution", 0); + ElMask = ini->ReadFloat("opt", "elmask", 15.0); + SnrMask.ena[0] = ini->ReadInteger("opt", "snrmask_ena1", 0); + SnrMask.ena[1] = ini->ReadInteger("opt", "snrmask_ena2", 0); + for (int i = 0; i < NFREQ; i++) + for (int j = 0; j < 9; j++) { + SnrMask.mask[i][j] = ini->ReadFloat("opt", s.sprintf("snrmask_%d_%d", i + 1, j + 1), 35.0); + } + IonoOpt = ini->ReadInteger("opt", "ionoopt", IONOOPT_BRDC); + TropOpt = ini->ReadInteger("opt", "tropopt", TROPOPT_SAAS); + RcvBiasEst = ini->ReadInteger("opt", "rcvbiasest", 0); + DynamicModel = ini->ReadInteger("opt", "dynamicmodel", 1); + TideCorr = ini->ReadInteger("opt", "tidecorr", 0); + SatEphem = ini->ReadInteger("opt", "satephem", 0); + ExSats = ini->ReadString("opt", "exsats", ""); + NavSys = ini->ReadInteger("opt", "navsys", SYS_GPS | SYS_GLO | SYS_GAL | SYS_QZS | SYS_CMP); + PosOpt[0] = ini->ReadInteger("opt", "posopt1", 0); + PosOpt[1] = ini->ReadInteger("opt", "posopt2", 0); + PosOpt[2] = ini->ReadInteger("opt", "posopt3", 0); + PosOpt[3] = ini->ReadInteger("opt", "posopt4", 0); + PosOpt[4] = ini->ReadInteger("opt", "posopt5", 0); + PosOpt[5] = ini->ReadInteger("opt", "posopt6", 0); + MapFunc = ini->ReadInteger("opt", "mapfunc", 0); + + AmbRes = ini->ReadInteger("opt", "ambres", 1); + GloAmbRes = ini->ReadInteger("opt", "gloambres", 0); + BdsAmbRes = ini->ReadInteger("opt", "bdsambres", 1); + ValidThresAR = ini->ReadFloat("opt", "validthresar", 3.0); + MaxPosVarAR = ini->ReadFloat("opt", "maxposvarar", 0.10); + GloHwBias = ini->ReadFloat("opt", "glohwbias", 0.00); + ThresAR3 = ini->ReadFloat("opt", "thresar3", 1E-9); + ThresAR4 = ini->ReadFloat("opt", "thresar4", 1E-5); + ValidThresARMin = ini->ReadFloat("opt", "validthresarmin", 3.0); + ValidThresARMax = ini->ReadFloat("opt", "validthresarmax", 3.0); + LockCntFixAmb = ini->ReadInteger("opt", "lockcntfixamb", 0); + FixCntHoldAmb = ini->ReadInteger("opt", "fixcntholdamb", 20); + ElMaskAR = ini->ReadFloat("opt", "elmaskar", 15.0); + ElMaskHold = ini->ReadFloat("opt", "elmaskhold", 15.0); + OutCntResetAmb = ini->ReadInteger("opt", "outcntresetbias", 20); + SlipThres = ini->ReadFloat("opt", "slipthres", 0.05); + DopThres = ini->ReadFloat("opt", "dopthres", 0.0); + MaxAgeDiff = ini->ReadFloat("opt", "maxagediff", 30.0); + RejectPhase = ini->ReadFloat("opt", "rejectphase", 5.0); + VarHoldAmb = ini->ReadFloat("opt", "varholdamb", 0.1); + GainHoldAmb = ini->ReadFloat("opt", "gainholdamb", 0.01); + RejectCode = ini->ReadFloat("opt", "rejectcode", 30.0); + ARIter = ini->ReadInteger("opt", "ariter", 1); + NumIter = ini->ReadInteger("opt", "numiter", 1); + MinFixSats = ini->ReadInteger("opt", "minfixsats", 4); + MinHoldSats = ini->ReadInteger("opt", "minholdsats", 5); + MinDropSats = ini->ReadInteger("opt", "mindropsats", 10); + ARFilter = ini->ReadInteger("opt", "arfilter", 1); + CodeSmooth = ini->ReadInteger("opt", "codesmooth", 0); + BaseLine[0] = ini->ReadFloat("opt", "baselinelen", 0.0); + BaseLine[1] = ini->ReadFloat("opt", "baselinesig", 0.0); + BaseLineConst = ini->ReadInteger("opt", "baselineconst", 0); + + SolFormat = ini->ReadInteger("opt", "solformat", 0); + TimeFormat = ini->ReadInteger("opt", "timeformat", 1); + TimeDecimal = ini->ReadInteger("opt", "timedecimal", 3); + LatLonFormat = ini->ReadInteger("opt", "latlonformat", 0); + FieldSep = ini->ReadString("opt", "fieldsep", ""); + OutputHead = ini->ReadInteger("opt", "outputhead", 1); + OutputOpt = ini->ReadInteger("opt", "outputopt", 1); + OutputVel = ini->ReadInteger("opt", "outputvel", 0); + OutputSingle = ini->ReadInteger("opt", "outputsingle", 0); + MaxSolStd = ini->ReadFloat("opt", "maxsolstd", 0.0); + OutputDatum = ini->ReadInteger("opt", "outputdatum", 0); + OutputHeight = ini->ReadInteger("opt", "outputheight", 0); + OutputGeoid = ini->ReadInteger("opt", "outputgeoid", 0); + SolStatic = ini->ReadInteger("opt", "solstatic", 0); + DebugTrace = ini->ReadInteger("opt", "debugtrace", 0); + DebugStatus = ini->ReadInteger("opt", "debugstatus", 2); + + MeasErrR1 = ini->ReadFloat("opt", "measeratio1", 300.0); + MeasErrR2 = ini->ReadFloat("opt", "measeratio2", 300.0); + MeasErrR5 = ini->ReadFloat("opt", "measeratio5", 300.0); + MeasErrR6 = ini->ReadFloat("opt", "measeratio6", 300.0); + MeasErr2 = ini->ReadFloat("opt", "measerr2", 0.003); + MeasErr3 = ini->ReadFloat("opt", "measerr3", 0.003); + MeasErr4 = ini->ReadFloat("opt", "measerr4", 0.000); + MeasErr5 = ini->ReadFloat("opt", "measerr5", 1.000); + MeasErr6 = ini->ReadFloat("opt", "measerr6", 52.00); + MeasErr7 = ini->ReadFloat("opt", "measerr7", 0.000); + MeasErr8 = ini->ReadFloat("opt", "measerr8", 0.000); + SatClkStab = ini->ReadFloat("opt", "satclkstab", 5E-12); + PrNoise1 = ini->ReadFloat("opt", "prnoise1", 1E-4); + PrNoise2 = ini->ReadFloat("opt", "prnoise2", 1E-3); + PrNoise3 = ini->ReadFloat("opt", "prnoise3", 1E-4); + PrNoise4 = ini->ReadFloat("opt", "prnoise4", 3.0); + PrNoise5 = ini->ReadFloat("opt", "prnoise5", 1.0); + + RovPosType = ini->ReadInteger("opt", "rovpostype", 0); + RefPosType = ini->ReadInteger("opt", "refpostype", 5); + RovPos[0] = ini->ReadFloat("opt", "rovpos1", 0.0); + RovPos[1] = ini->ReadFloat("opt", "rovpos2", 0.0); + RovPos[2] = ini->ReadFloat("opt", "rovpos3", 0.0); + RefPos[0] = ini->ReadFloat("opt", "refpos1", 0.0); + RefPos[1] = ini->ReadFloat("opt", "refpos2", 0.0); + RefPos[2] = ini->ReadFloat("opt", "refpos3", 0.0); + RovAntPcv = ini->ReadInteger("opt", "rovantpcv", 0); + RefAntPcv = ini->ReadInteger("opt", "refantpcv", 0); + RovAnt = ini->ReadString("opt", "rovant", ""); + RefAnt = ini->ReadString("opt", "refant", ""); + RovAntE = ini->ReadFloat("opt", "rovante", 0.0); + RovAntN = ini->ReadFloat("opt", "rovantn", 0.0); + RovAntU = ini->ReadFloat("opt", "rovantu", 0.0); + RefAntE = ini->ReadFloat("opt", "refante", 0.0); + RefAntN = ini->ReadFloat("opt", "refantn", 0.0); + RefAntU = ini->ReadFloat("opt", "refantu", 0.0); + + RnxOpts1 = ini->ReadString("opt", "rnxopts1", ""); + RnxOpts2 = ini->ReadString("opt", "rnxopts2", ""); + PPPOpts = ini->ReadString("opt", "pppopts", ""); + + AntPcvFile = ini->ReadString("opt", "antpcvfile", ""); + IntpRefObs = ini->ReadInteger("opt", "intprefobs", 1); + SbasSat = ini->ReadInteger("opt", "sbassat", 0); + NetRSCorr = ini->ReadInteger("opt", "netrscorr", 0); + SatClkCorr = ini->ReadInteger("opt", "satclkcorr", 0); + SbasCorr = ini->ReadInteger("opt", "sbascorr", 0); + SbasCorr1 = ini->ReadInteger("opt", "sbascorr1", 0); + SbasCorr2 = ini->ReadInteger("opt", "sbascorr2", 0); + SbasCorr3 = ini->ReadInteger("opt", "sbascorr3", 0); + SbasCorr4 = ini->ReadInteger("opt", "sbascorr4", 0); + SbasCorrFile = ini->ReadString("opt", "sbascorrfile", ""); + PrecEphFile = ini->ReadString("opt", "precephfile", ""); + SatPcvFile = ini->ReadString("opt", "satpcvfile", ""); + StaPosFile = ini->ReadString("opt", "staposfile", ""); + GeoidDataFile = ini->ReadString("opt", "geoiddatafile", ""); + IonoFile = ini->ReadString("opt", "ionofile", ""); + EOPFile = ini->ReadString("opt", "eopfile", ""); + DCBFile = ini->ReadString("opt", "dcbfile", ""); + BLQFile = ini->ReadString("opt", "blqfile", ""); + GoogleEarthFile = ini->ReadString("opt", "googleearthfile", GOOGLE_EARTH); + + RovList = ""; + for (int i = 0; i < 10; i++) { + RovList += ini->ReadString("opt", s.sprintf("rovlist%d", i + 1), ""); + } + BaseList = ""; + for (int i = 0; i < 10; i++) { + BaseList += ini->ReadString("opt", s.sprintf("baselist%d", i + 1), ""); + } + for (p = RovList.c_str(); *p; p++) { + if ((p = strstr(p, "@@"))) + strncpy(p, "\r\n", 2); + else + break; + } + for (p = BaseList.c_str(); *p; p++) { + if ((p = strstr(p, "@@"))) + strncpy(p, "\r\n", 2); + else + break; + } + ConvDialog->TimeSpan->Checked = ini->ReadInteger("conv", "timespan", 0); + ConvDialog->TimeIntF->Checked = ini->ReadInteger("conv", "timeintf", 0); + ConvDialog->TimeY1->Text = ini->ReadString("conv", "timey1", "2000/01/01"); + ConvDialog->TimeH1->Text = ini->ReadString("conv", "timeh1", "00:00:00"); + ConvDialog->TimeY2->Text = ini->ReadString("conv", "timey2", "2000/01/01"); + ConvDialog->TimeH2->Text = ini->ReadString("conv", "timeh2", "00:00:00"); + ConvDialog->TimeInt->Text = ini->ReadString("conv", "timeint", "0"); + ConvDialog->SingleMeanF->Checked = ini->ReadInteger("conv", "mean", 0); + ConvDialog->TrackColor->ItemIndex = ini->ReadInteger("conv", "trackcolor", 5); + ConvDialog->PointColor->ItemIndex = ini->ReadInteger("conv", "pointcolor", 5); + ConvDialog->OutputAlt->ItemIndex = ini->ReadInteger("conv", "outputalt", 0); + ConvDialog->OutputTime->ItemIndex = ini->ReadInteger("conv", "outputtime", 0); + ConvDialog->AddOffset->Checked = ini->ReadInteger("conv", "addoffset", 0); + ConvDialog->Offset1->Text = ini->ReadString("conv", "offset1", "0"); + ConvDialog->Offset2->Text = ini->ReadString("conv", "offset2", "0"); + ConvDialog->Offset3->Text = ini->ReadString("conv", "offset3", "0"); + ConvDialog->Compress->Checked = ini->ReadInteger("conv", "compress", 0); + int format = ini->ReadInteger("conv", "format", 0); + ConvDialog->FormatKML->Checked = format == 0; + ConvDialog->FormatCSV->Checked = format == 1; + ConvDialog->FormatGPX->Checked = format != 0 && format != 1; + + TTextViewer::Color1 = (TColor)ini->ReadInteger("viewer", "color1", (int)clBlack); + TTextViewer::Color2 = (TColor)ini->ReadInteger("viewer", "color2", (int)clWhite); + TTextViewer::FontD = new TFont; + TTextViewer::FontD->Name = ini->ReadString("viewer", "fontname", "Courier New"); + TTextViewer::FontD->Size = ini->ReadInteger("viewer", "fontsize", 9); + Width = ini->ReadInteger("window", "width", 486); + delete ini; } // disable highlight of combo-boxes ----------------------------------------- -void __fastcall TMainForm::DisableHighlight(void) -{ - ::PostMessage(InputFile1->Handle,CB_SETEDITSEL,-1,0); - ::PostMessage(InputFile2->Handle,CB_SETEDITSEL,-1,0); - ::PostMessage(InputFile3->Handle,CB_SETEDITSEL,-1,0); - ::PostMessage(InputFile4->Handle,CB_SETEDITSEL,-1,0); - ::PostMessage(InputFile5->Handle,CB_SETEDITSEL,-1,0); - ::PostMessage(InputFile6->Handle,CB_SETEDITSEL,-1,0); - ::PostMessage(InputFile7->Handle,CB_SETEDITSEL,-1,0); - ::PostMessage(InputFile8->Handle,CB_SETEDITSEL,-1,0); - ::PostMessage(InputFile9->Handle,CB_SETEDITSEL,-1,0); - ::PostMessage(InputFile10->Handle,CB_SETEDITSEL,-1,0); - ::PostMessage(OutputFile->Handle,CB_SETEDITSEL,-1,0); - ::PostMessage(TimeInt ->Handle,CB_SETEDITSEL,-1,0); +void __fastcall TMainForm::DisableHighlight(void) { + ::PostMessage(InputFile1->Handle, CB_SETEDITSEL, -1, 0); + ::PostMessage(InputFile2->Handle, CB_SETEDITSEL, -1, 0); + ::PostMessage(InputFile3->Handle, CB_SETEDITSEL, -1, 0); + ::PostMessage(InputFile4->Handle, CB_SETEDITSEL, -1, 0); + ::PostMessage(InputFile5->Handle, CB_SETEDITSEL, -1, 0); + ::PostMessage(InputFile6->Handle, CB_SETEDITSEL, -1, 0); + ::PostMessage(InputFile7->Handle, CB_SETEDITSEL, -1, 0); + ::PostMessage(InputFile8->Handle, CB_SETEDITSEL, -1, 0); + ::PostMessage(InputFile9->Handle, CB_SETEDITSEL, -1, 0); + ::PostMessage(InputFile10->Handle, CB_SETEDITSEL, -1, 0); + ::PostMessage(OutputFile->Handle, CB_SETEDITSEL, -1, 0); + ::PostMessage(TimeInt->Handle, CB_SETEDITSEL, -1, 0); } // save options to ini file ------------------------------------------------- -void __fastcall TMainForm::SaveOpt(void) -{ - TIniFile *ini=new TIniFile(IniFile); - AnsiString s; - char *p; - - ini->WriteInteger("set","timestart", TimeStart ->Checked?1:0); - ini->WriteInteger("set","timeend", TimeEnd ->Checked?1:0); - ini->WriteString ("set","timey1", TimeY1 ->Text); - ini->WriteString ("set","timeh1", TimeH1 ->Text); - ini->WriteString ("set","timey2", TimeY2 ->Text); - ini->WriteString ("set","timeh2", TimeH2 ->Text); - ini->WriteInteger("set","timeintf", TimeIntF ->Checked?1:0); - ini->WriteString ("set","timeint", TimeInt ->Text); - ini->WriteInteger("set","timeunitf", TimeUnitF ->Checked?1:0); - ini->WriteString ("set","timeunit", TimeUnit ->Text); - ini->WriteString ("set","inputfile1", InputFile1->Text); - ini->WriteString ("set","inputfile2", InputFile2->Text); - ini->WriteString ("set","inputfile3", InputFile3->Text); - ini->WriteString ("set","inputfile4", InputFile4->Text); - ini->WriteString ("set","inputfile5", InputFile5->Text); - ini->WriteString ("set","inputfile6", InputFile6->Text); - ini->WriteString ("set","inputfile7", InputFile7->Text); - ini->WriteString ("set","inputfile8", InputFile8->Text); - ini->WriteString ("set","inputfile9", InputFile9->Text); - ini->WriteString ("set","inputfile10", InputFile10->Text); - ini->WriteInteger("set","outputdirena",OutDirEna ->Checked); - ini->WriteString ("set","outputdir", OutDir ->Text); - ini->WriteString ("set","outputfile", OutputFile->Text); - - WriteList(ini,"hist","inputfile1", InputFile1->Items); - WriteList(ini,"hist","inputfile2", InputFile2->Items); - WriteList(ini,"hist","inputfile3", InputFile3->Items); - WriteList(ini,"hist","inputfile4", InputFile4->Items); - WriteList(ini,"hist","inputfile5", InputFile5->Items); - WriteList(ini,"hist","inputfile6", InputFile6->Items); - WriteList(ini,"hist","inputfile7", InputFile7->Items); - WriteList(ini,"hist","inputfile8", InputFile8->Items); - WriteList(ini,"hist","inputfile9", InputFile9->Items); - WriteList(ini,"hist","inputfile10", InputFile10->Items); - WriteList(ini,"hist","outputfile", OutputFile->Items); - - ini->WriteInteger("opt","posmode", PosMode ); - ini->WriteInteger("opt","freq", Freq ); - ini->WriteInteger("opt","solution", Solution ); - ini->WriteFloat ("opt","elmask", ElMask ); - ini->WriteInteger("opt","snrmask_ena1",SnrMask.ena[0]); - ini->WriteInteger("opt","snrmask_ena2",SnrMask.ena[1]); - for (int i=0;iWriteFloat("opt",s.sprintf("snrmask_%d_%d",i+1,j+1), - SnrMask.mask[i][j]); - } - ini->WriteInteger("opt","ionoopt", IonoOpt ); - ini->WriteInteger("opt","tropopt", TropOpt ); - ini->WriteInteger("opt","rcvbiasest", RcvBiasEst ); - ini->WriteInteger("opt","dynamicmodel",DynamicModel); - ini->WriteInteger("opt","tidecorr", TideCorr ); - ini->WriteInteger("opt","satephem", SatEphem ); - ini->WriteString ("opt","exsats", ExSats ); - ini->WriteInteger("opt","navsys", NavSys ); - ini->WriteInteger("opt","posopt1", PosOpt[0] ); - ini->WriteInteger("opt","posopt2", PosOpt[1] ); - ini->WriteInteger("opt","posopt3", PosOpt[2] ); - ini->WriteInteger("opt","posopt4", PosOpt[3] ); - ini->WriteInteger("opt","posopt5", PosOpt[4] ); - ini->WriteInteger("opt","posopt6", PosOpt[5] ); - ini->WriteInteger("opt","mapfunc", MapFunc ); - - ini->WriteInteger("opt","ambres", AmbRes ); - ini->WriteInteger("opt","gloambres", GloAmbRes ); - ini->WriteInteger("opt","bdsambres", BdsAmbRes ); - ini->WriteFloat ("opt","validthresar",ValidThresAR); - ini->WriteFloat ("opt","maxposvarar", MaxPosVarAR ); - ini->WriteFloat ("opt","glohwbias", GloHwBias ); - ini->WriteFloat ("opt","thresar3", ThresAR3 ); - ini->WriteFloat ("opt","thresar4", ThresAR4 ); - ini->WriteFloat ("opt","validthresarmin",ValidThresARMin); - ini->WriteFloat ("opt","validthresarmax",ValidThresARMax); - ini->WriteInteger("opt","lockcntfixamb",LockCntFixAmb); - ini->WriteInteger("opt","fixcntholdamb",FixCntHoldAmb); - ini->WriteFloat ("opt","elmaskar", ElMaskAR ); - ini->WriteFloat ("opt","elmaskhold", ElMaskHold ); - ini->WriteInteger("opt","outcntresetbias",OutCntResetAmb); - ini->WriteFloat ("opt","slipthres", SlipThres ); - ini->WriteFloat ("opt","dopthres", DopThres ); - ini->WriteFloat ("opt","maxagediff", MaxAgeDiff ); - ini->WriteFloat ("opt","rejectcode", RejectCode ); - ini->WriteFloat ("opt","rejectphase", RejectPhase ); - ini->WriteFloat ("opt","varholdamb", VarHoldAmb ); - ini->WriteFloat ("opt","gainholdamb", GainHoldAmb ); - ini->WriteInteger("opt","ariter", ARIter ); - ini->WriteInteger("opt","numiter", NumIter ); - ini->WriteInteger("opt","minfixsats", MinFixSats ); - ini->WriteInteger("opt","minholdsats", MinHoldSats ); - ini->WriteInteger("opt","mindropsats", MinDropSats ); - ini->WriteInteger("opt","arfilter", ARFilter ); - ini->WriteInteger("opt","codesmooth", CodeSmooth ); - ini->WriteFloat ("opt","baselinelen", BaseLine[0] ); - ini->WriteFloat ("opt","baselinesig", BaseLine[1] ); - ini->WriteInteger("opt","baselineconst",BaseLineConst); - - ini->WriteInteger("opt","solformat", SolFormat ); - ini->WriteInteger("opt","timeformat", TimeFormat ); - ini->WriteInteger("opt","timedecimal", TimeDecimal ); - ini->WriteInteger("opt","latlonformat",LatLonFormat); - ini->WriteString ("opt","fieldsep", FieldSep ); - ini->WriteInteger("opt","outputhead", OutputHead ); - ini->WriteInteger("opt","outputopt", OutputOpt ); - ini->WriteInteger("opt","outputvel", OutputVel ); - ini->WriteInteger("opt","outputsingle",OutputSingle); - ini->WriteFloat ("opt","maxsolstd", MaxSolStd ); - ini->WriteInteger("opt","outputdatum", OutputDatum ); - ini->WriteInteger("opt","outputheight",OutputHeight); - ini->WriteInteger("opt","outputgeoid", OutputGeoid ); - ini->WriteInteger("opt","solstatic", SolStatic ); - ini->WriteInteger("opt","debugtrace", DebugTrace ); - ini->WriteInteger("opt","debugstatus", DebugStatus ); - - ini->WriteFloat ("opt","measeratio1", MeasErrR1 ); - ini->WriteFloat ("opt","measeratio2", MeasErrR2 ); - ini->WriteFloat ("opt","measeratio5", MeasErrR5 ); - ini->WriteFloat ("opt","measeratio6", MeasErrR6 ); - ini->WriteFloat ("opt","measerr2", MeasErr2 ); - ini->WriteFloat ("opt","measerr3", MeasErr3 ); - ini->WriteFloat ("opt","measerr4", MeasErr4 ); - ini->WriteFloat ("opt","measerr5", MeasErr5 ); - ini->WriteFloat ("opt","measerr6", MeasErr6 ); - ini->WriteFloat ("opt","measerr7", MeasErr7 ); - ini->WriteFloat ("opt","measerr8", MeasErr8 ); - ini->WriteFloat ("opt","satclkstab", SatClkStab ); - ini->WriteFloat ("opt","prnoise1", PrNoise1 ); - ini->WriteFloat ("opt","prnoise2", PrNoise2 ); - ini->WriteFloat ("opt","prnoise3", PrNoise3 ); - ini->WriteFloat ("opt","prnoise4", PrNoise4 ); - ini->WriteFloat ("opt","prnoise5", PrNoise5 ); - - ini->WriteInteger("opt","rovpostype", RovPosType ); - ini->WriteInteger("opt","refpostype", RefPosType ); - ini->WriteFloat ("opt","rovpos1", RovPos[0] ); - ini->WriteFloat ("opt","rovpos2", RovPos[1] ); - ini->WriteFloat ("opt","rovpos3", RovPos[2] ); - ini->WriteFloat ("opt","refpos1", RefPos[0] ); - ini->WriteFloat ("opt","refpos2", RefPos[1] ); - ini->WriteFloat ("opt","refpos3", RefPos[2] ); - ini->WriteInteger("opt","rovantpcv", RovAntPcv ); - ini->WriteInteger("opt","refantpcv", RefAntPcv ); - ini->WriteString ("opt","rovant", RovAnt ); - ini->WriteString ("opt","refant", RefAnt ); - ini->WriteFloat ("opt","rovante", RovAntE ); - ini->WriteFloat ("opt","rovantn", RovAntN ); - ini->WriteFloat ("opt","rovantu", RovAntU ); - ini->WriteFloat ("opt","refante", RefAntE ); - ini->WriteFloat ("opt","refantn", RefAntN ); - ini->WriteFloat ("opt","refantu", RefAntU ); - - ini->WriteString ("opt","rnxopts1", RnxOpts1 ); - ini->WriteString ("opt","rnxopts2", RnxOpts2 ); - ini->WriteString ("opt","pppopts", PPPOpts ); - - ini->WriteString ("opt","antpcvfile", AntPcvFile ); - ini->WriteInteger("opt","intprefobs", IntpRefObs ); - ini->WriteInteger("opt","sbassat", SbasSat ); - ini->WriteInteger("opt","netrscorr", NetRSCorr ); - ini->WriteInteger("opt","satclkcorr", SatClkCorr ); - ini->WriteInteger("opt","sbascorr", SbasCorr ); - ini->WriteInteger("opt","sbascorr1", SbasCorr1 ); - ini->WriteInteger("opt","sbascorr2", SbasCorr2 ); - ini->WriteInteger("opt","sbascorr3", SbasCorr3 ); - ini->WriteInteger("opt","sbascorr4", SbasCorr4 ); - ini->WriteString ("opt","sbascorrfile",SbasCorrFile); - ini->WriteString ("opt","precephfile", PrecEphFile ); - ini->WriteString ("opt","satpcvfile", SatPcvFile ); - ini->WriteString ("opt","staposfile", StaPosFile ); - ini->WriteString ("opt","geoiddatafile",GeoidDataFile); - ini->WriteString ("opt","ionofile", IonoFile ); - ini->WriteString ("opt","eopfile", EOPFile ); - ini->WriteString ("opt","dcbfile", DCBFile ); - ini->WriteString ("opt","blqfile", BLQFile ); - ini->WriteString ("opt","googleearthfile",GoogleEarthFile); - - for (p=RovList.c_str();*p;p++) { - if ((p=strstr(p,"\r\n"))) strncpy(p,"@@",2); else break; - } - for (int i=0;i<10;i++) { - ini->WriteString("opt",s.sprintf("rovlist%d",i+1),RovList.SubString(i*2000,2000)); - } - for (p=BaseList.c_str();*p;p++) { - if ((p=strstr(p,"\r\n"))) strncpy(p,"@@",2); else break; - } - for (int i=0;i<10;i++) { - ini->WriteString("opt",s.sprintf("baselist%d",i+1),BaseList.SubString(i*2000,2000)); - } - ini->WriteInteger("conv","timespan", ConvDialog->TimeSpan ->Checked ); - ini->WriteString ("conv","timey1", ConvDialog->TimeY1 ->Text ); - ini->WriteString ("conv","timeh1", ConvDialog->TimeH1 ->Text ); - ini->WriteString ("conv","timey2", ConvDialog->TimeY2 ->Text ); - ini->WriteString ("conv","timeh2", ConvDialog->TimeH2 ->Text ); - ini->WriteInteger("conv","timeintf", ConvDialog->TimeIntF ->Checked ); - ini->WriteString ("conv","timeint", ConvDialog->TimeInt ->Text ); - ini->WriteInteger("conv","mean", ConvDialog->SingleMeanF->Checked ); - ini->WriteInteger("conv","trackcolor", ConvDialog->TrackColor->ItemIndex); - ini->WriteInteger("conv","pointcolor", ConvDialog->PointColor->ItemIndex); - ini->WriteInteger("conv","outputalt", ConvDialog->OutputAlt ->ItemIndex); - ini->WriteInteger("conv","outputtime", ConvDialog->OutputTime->ItemIndex); - ini->WriteInteger("conv","addoffset", ConvDialog->AddOffset ->Checked ); - ini->WriteString ("conv","offset1", ConvDialog->Offset1 ->Text ); - ini->WriteString ("conv","offset2", ConvDialog->Offset2 ->Text ); - ini->WriteString ("conv","offset3", ConvDialog->Offset3 ->Text ); - ini->WriteInteger("conv","compress", ConvDialog->Compress ->Checked ); - ini->WriteInteger("conv","format", ConvDialog->FormatKML ->Checked ? 0 : (ConvDialog->FormatCSV ->Checked ? 1 : 2)); - - ini->WriteInteger("viewer","color1",(int)TTextViewer::Color1 ); - ini->WriteInteger("viewer","color2",(int)TTextViewer::Color2 ); - ini->WriteString ("viewer","fontname",TTextViewer::FontD->Name); - ini->WriteInteger("viewer","fontsize",TTextViewer::FontD->Size); - - ini->WriteInteger("window","width",Width); - delete ini; +void __fastcall TMainForm::SaveOpt(void) { + TIniFile *ini = new TIniFile(IniFile); + AnsiString s; + char *p; + + ini->WriteInteger("set", "timestart", TimeStart->Checked ? 1 : 0); + ini->WriteInteger("set", "timeend", TimeEnd->Checked ? 1 : 0); + ini->WriteString("set", "timey1", TimeY1->Text); + ini->WriteString("set", "timeh1", TimeH1->Text); + ini->WriteString("set", "timey2", TimeY2->Text); + ini->WriteString("set", "timeh2", TimeH2->Text); + ini->WriteInteger("set", "timeintf", TimeIntF->Checked ? 1 : 0); + ini->WriteString("set", "timeint", TimeInt->Text); + ini->WriteInteger("set", "timeunitf", TimeUnitF->Checked ? 1 : 0); + ini->WriteString("set", "timeunit", TimeUnit->Text); + ini->WriteString("set", "inputfile1", InputFile1->Text); + ini->WriteString("set", "inputfile2", InputFile2->Text); + ini->WriteString("set", "inputfile3", InputFile3->Text); + ini->WriteString("set", "inputfile4", InputFile4->Text); + ini->WriteString("set", "inputfile5", InputFile5->Text); + ini->WriteString("set", "inputfile6", InputFile6->Text); + ini->WriteString("set", "inputfile7", InputFile7->Text); + ini->WriteString("set", "inputfile8", InputFile8->Text); + ini->WriteString("set", "inputfile9", InputFile9->Text); + ini->WriteString("set", "inputfile10", InputFile10->Text); + ini->WriteInteger("set", "outputdirena", OutDirEna->Checked); + ini->WriteString("set", "outputdir", OutDir->Text); + ini->WriteString("set", "outputfile", OutputFile->Text); + + WriteList(ini, "hist", "inputfile1", InputFile1->Items); + WriteList(ini, "hist", "inputfile2", InputFile2->Items); + WriteList(ini, "hist", "inputfile3", InputFile3->Items); + WriteList(ini, "hist", "inputfile4", InputFile4->Items); + WriteList(ini, "hist", "inputfile5", InputFile5->Items); + WriteList(ini, "hist", "inputfile6", InputFile6->Items); + WriteList(ini, "hist", "inputfile7", InputFile7->Items); + WriteList(ini, "hist", "inputfile8", InputFile8->Items); + WriteList(ini, "hist", "inputfile9", InputFile9->Items); + WriteList(ini, "hist", "inputfile10", InputFile10->Items); + WriteList(ini, "hist", "outputfile", OutputFile->Items); + + ini->WriteInteger("opt", "posmode", PosMode); + ini->WriteInteger("opt", "freq", Freq); + ini->WriteInteger("opt", "solution", Solution); + ini->WriteFloat("opt", "elmask", ElMask); + ini->WriteInteger("opt", "snrmask_ena1", SnrMask.ena[0]); + ini->WriteInteger("opt", "snrmask_ena2", SnrMask.ena[1]); + for (int i = 0; i < NFREQ; i++) + for (int j = 0; j < 9; j++) { + ini->WriteFloat("opt", s.sprintf("snrmask_%d_%d", i + 1, j + 1), SnrMask.mask[i][j]); + } + ini->WriteInteger("opt", "ionoopt", IonoOpt); + ini->WriteInteger("opt", "tropopt", TropOpt); + ini->WriteInteger("opt", "rcvbiasest", RcvBiasEst); + ini->WriteInteger("opt", "dynamicmodel", DynamicModel); + ini->WriteInteger("opt", "tidecorr", TideCorr); + ini->WriteInteger("opt", "satephem", SatEphem); + ini->WriteString("opt", "exsats", ExSats); + ini->WriteInteger("opt", "navsys", NavSys); + ini->WriteInteger("opt", "posopt1", PosOpt[0]); + ini->WriteInteger("opt", "posopt2", PosOpt[1]); + ini->WriteInteger("opt", "posopt3", PosOpt[2]); + ini->WriteInteger("opt", "posopt4", PosOpt[3]); + ini->WriteInteger("opt", "posopt5", PosOpt[4]); + ini->WriteInteger("opt", "posopt6", PosOpt[5]); + ini->WriteInteger("opt", "mapfunc", MapFunc); + + ini->WriteInteger("opt", "ambres", AmbRes); + ini->WriteInteger("opt", "gloambres", GloAmbRes); + ini->WriteInteger("opt", "bdsambres", BdsAmbRes); + ini->WriteFloat("opt", "validthresar", ValidThresAR); + ini->WriteFloat("opt", "maxposvarar", MaxPosVarAR); + ini->WriteFloat("opt", "glohwbias", GloHwBias); + ini->WriteFloat("opt", "thresar3", ThresAR3); + ini->WriteFloat("opt", "thresar4", ThresAR4); + ini->WriteFloat("opt", "validthresarmin", ValidThresARMin); + ini->WriteFloat("opt", "validthresarmax", ValidThresARMax); + ini->WriteInteger("opt", "lockcntfixamb", LockCntFixAmb); + ini->WriteInteger("opt", "fixcntholdamb", FixCntHoldAmb); + ini->WriteFloat("opt", "elmaskar", ElMaskAR); + ini->WriteFloat("opt", "elmaskhold", ElMaskHold); + ini->WriteInteger("opt", "outcntresetbias", OutCntResetAmb); + ini->WriteFloat("opt", "slipthres", SlipThres); + ini->WriteFloat("opt", "dopthres", DopThres); + ini->WriteFloat("opt", "maxagediff", MaxAgeDiff); + ini->WriteFloat("opt", "rejectcode", RejectCode); + ini->WriteFloat("opt", "rejectphase", RejectPhase); + ini->WriteFloat("opt", "varholdamb", VarHoldAmb); + ini->WriteFloat("opt", "gainholdamb", GainHoldAmb); + ini->WriteInteger("opt", "ariter", ARIter); + ini->WriteInteger("opt", "numiter", NumIter); + ini->WriteInteger("opt", "minfixsats", MinFixSats); + ini->WriteInteger("opt", "minholdsats", MinHoldSats); + ini->WriteInteger("opt", "mindropsats", MinDropSats); + ini->WriteInteger("opt", "arfilter", ARFilter); + ini->WriteInteger("opt", "codesmooth", CodeSmooth); + ini->WriteFloat("opt", "baselinelen", BaseLine[0]); + ini->WriteFloat("opt", "baselinesig", BaseLine[1]); + ini->WriteInteger("opt", "baselineconst", BaseLineConst); + + ini->WriteInteger("opt", "solformat", SolFormat); + ini->WriteInteger("opt", "timeformat", TimeFormat); + ini->WriteInteger("opt", "timedecimal", TimeDecimal); + ini->WriteInteger("opt", "latlonformat", LatLonFormat); + ini->WriteString("opt", "fieldsep", FieldSep); + ini->WriteInteger("opt", "outputhead", OutputHead); + ini->WriteInteger("opt", "outputopt", OutputOpt); + ini->WriteInteger("opt", "outputvel", OutputVel); + ini->WriteInteger("opt", "outputsingle", OutputSingle); + ini->WriteFloat("opt", "maxsolstd", MaxSolStd); + ini->WriteInteger("opt", "outputdatum", OutputDatum); + ini->WriteInteger("opt", "outputheight", OutputHeight); + ini->WriteInteger("opt", "outputgeoid", OutputGeoid); + ini->WriteInteger("opt", "solstatic", SolStatic); + ini->WriteInteger("opt", "debugtrace", DebugTrace); + ini->WriteInteger("opt", "debugstatus", DebugStatus); + + ini->WriteFloat("opt", "measeratio1", MeasErrR1); + ini->WriteFloat("opt", "measeratio2", MeasErrR2); + ini->WriteFloat("opt", "measeratio5", MeasErrR5); + ini->WriteFloat("opt", "measeratio6", MeasErrR6); + ini->WriteFloat("opt", "measerr2", MeasErr2); + ini->WriteFloat("opt", "measerr3", MeasErr3); + ini->WriteFloat("opt", "measerr4", MeasErr4); + ini->WriteFloat("opt", "measerr5", MeasErr5); + ini->WriteFloat("opt", "measerr6", MeasErr6); + ini->WriteFloat("opt", "measerr7", MeasErr7); + ini->WriteFloat("opt", "measerr8", MeasErr8); + ini->WriteFloat("opt", "satclkstab", SatClkStab); + ini->WriteFloat("opt", "prnoise1", PrNoise1); + ini->WriteFloat("opt", "prnoise2", PrNoise2); + ini->WriteFloat("opt", "prnoise3", PrNoise3); + ini->WriteFloat("opt", "prnoise4", PrNoise4); + ini->WriteFloat("opt", "prnoise5", PrNoise5); + + ini->WriteInteger("opt", "rovpostype", RovPosType); + ini->WriteInteger("opt", "refpostype", RefPosType); + ini->WriteFloat("opt", "rovpos1", RovPos[0]); + ini->WriteFloat("opt", "rovpos2", RovPos[1]); + ini->WriteFloat("opt", "rovpos3", RovPos[2]); + ini->WriteFloat("opt", "refpos1", RefPos[0]); + ini->WriteFloat("opt", "refpos2", RefPos[1]); + ini->WriteFloat("opt", "refpos3", RefPos[2]); + ini->WriteInteger("opt", "rovantpcv", RovAntPcv); + ini->WriteInteger("opt", "refantpcv", RefAntPcv); + ini->WriteString("opt", "rovant", RovAnt); + ini->WriteString("opt", "refant", RefAnt); + ini->WriteFloat("opt", "rovante", RovAntE); + ini->WriteFloat("opt", "rovantn", RovAntN); + ini->WriteFloat("opt", "rovantu", RovAntU); + ini->WriteFloat("opt", "refante", RefAntE); + ini->WriteFloat("opt", "refantn", RefAntN); + ini->WriteFloat("opt", "refantu", RefAntU); + + ini->WriteString("opt", "rnxopts1", RnxOpts1); + ini->WriteString("opt", "rnxopts2", RnxOpts2); + ini->WriteString("opt", "pppopts", PPPOpts); + + ini->WriteString("opt", "antpcvfile", AntPcvFile); + ini->WriteInteger("opt", "intprefobs", IntpRefObs); + ini->WriteInteger("opt", "sbassat", SbasSat); + ini->WriteInteger("opt", "netrscorr", NetRSCorr); + ini->WriteInteger("opt", "satclkcorr", SatClkCorr); + ini->WriteInteger("opt", "sbascorr", SbasCorr); + ini->WriteInteger("opt", "sbascorr1", SbasCorr1); + ini->WriteInteger("opt", "sbascorr2", SbasCorr2); + ini->WriteInteger("opt", "sbascorr3", SbasCorr3); + ini->WriteInteger("opt", "sbascorr4", SbasCorr4); + ini->WriteString("opt", "sbascorrfile", SbasCorrFile); + ini->WriteString("opt", "precephfile", PrecEphFile); + ini->WriteString("opt", "satpcvfile", SatPcvFile); + ini->WriteString("opt", "staposfile", StaPosFile); + ini->WriteString("opt", "geoiddatafile", GeoidDataFile); + ini->WriteString("opt", "ionofile", IonoFile); + ini->WriteString("opt", "eopfile", EOPFile); + ini->WriteString("opt", "dcbfile", DCBFile); + ini->WriteString("opt", "blqfile", BLQFile); + ini->WriteString("opt", "googleearthfile", GoogleEarthFile); + + for (p = RovList.c_str(); *p; p++) { + if ((p = strstr(p, "\r\n"))) + strncpy(p, "@@", 2); + else + break; + } + for (int i = 0; i < 10; i++) { + ini->WriteString("opt", s.sprintf("rovlist%d", i + 1), RovList.SubString(i * 2000, 2000)); + } + for (p = BaseList.c_str(); *p; p++) { + if ((p = strstr(p, "\r\n"))) + strncpy(p, "@@", 2); + else + break; + } + for (int i = 0; i < 10; i++) { + ini->WriteString("opt", s.sprintf("baselist%d", i + 1), BaseList.SubString(i * 2000, 2000)); + } + ini->WriteInteger("conv", "timespan", ConvDialog->TimeSpan->Checked); + ini->WriteString("conv", "timey1", ConvDialog->TimeY1->Text); + ini->WriteString("conv", "timeh1", ConvDialog->TimeH1->Text); + ini->WriteString("conv", "timey2", ConvDialog->TimeY2->Text); + ini->WriteString("conv", "timeh2", ConvDialog->TimeH2->Text); + ini->WriteInteger("conv", "timeintf", ConvDialog->TimeIntF->Checked); + ini->WriteString("conv", "timeint", ConvDialog->TimeInt->Text); + ini->WriteInteger("conv", "mean", ConvDialog->SingleMeanF->Checked); + ini->WriteInteger("conv", "trackcolor", ConvDialog->TrackColor->ItemIndex); + ini->WriteInteger("conv", "pointcolor", ConvDialog->PointColor->ItemIndex); + ini->WriteInteger("conv", "outputalt", ConvDialog->OutputAlt->ItemIndex); + ini->WriteInteger("conv", "outputtime", ConvDialog->OutputTime->ItemIndex); + ini->WriteInteger("conv", "addoffset", ConvDialog->AddOffset->Checked); + ini->WriteString("conv", "offset1", ConvDialog->Offset1->Text); + ini->WriteString("conv", "offset2", ConvDialog->Offset2->Text); + ini->WriteString("conv", "offset3", ConvDialog->Offset3->Text); + ini->WriteInteger("conv", "compress", ConvDialog->Compress->Checked); + ini->WriteInteger("conv", "format", + ConvDialog->FormatKML->Checked ? 0 : (ConvDialog->FormatCSV->Checked ? 1 : 2)); + + ini->WriteInteger("viewer", "color1", (int)TTextViewer::Color1); + ini->WriteInteger("viewer", "color2", (int)TTextViewer::Color2); + ini->WriteString("viewer", "fontname", TTextViewer::FontD->Name); + ini->WriteInteger("viewer", "fontsize", TTextViewer::FontD->Size); + + ini->WriteInteger("window", "width", Width); + delete ini; } //--------------------------------------------------------------------------- -void __fastcall TMainForm::Panel4Resize(TObject *Sender) -{ - TButton *btns[]={ - BtnInputFile1,BtnInputFile2,BtnInputFile3,BtnInputFile4, - BtnInputFile5,BtnInputFile6,BtnInputFile7,BtnInputFile8, - BtnInputFile9,BtnInputFile10 - }; - TComboBox *boxes[]={ - InputFile1,InputFile2,InputFile3,InputFile4,InputFile5, - InputFile6,InputFile7,InputFile8,InputFile9,InputFile10 - }; - int w=Panel4->Width; - - for (int i=0;i<10;i++) { - btns[i]->Left=w-btns[i]->Width-5; - boxes[i]->Width=w-btns[i]->Width-boxes[i]->Left-6; - } - BtnInputView1->Left=InputFile1->Left+InputFile1->Width-BtnInputView1->Width; - BtnInputPlot1->Left=BtnInputView1->Left-BtnInputPlot1->Width; - BtnInputView2->Left=InputFile2->Left+InputFile2->Width-BtnInputView2->Width; - BtnInputPlot2->Left=BtnInputView2->Left-BtnInputPlot2->Width; - BtnInputView10->Left=InputFile3->Left+InputFile3->Width-BtnInputView10->Width; - BtnInputView9->Left=BtnInputView10->Left-BtnInputView9->Width; - BtnInputView8->Left=BtnInputView9->Left-BtnInputView8->Width; - BtnInputView7->Left=BtnInputView8->Left-BtnInputView7->Width; - BtnInputView6->Left=BtnInputView7->Left-BtnInputView6->Width; - BtnInputView5->Left=BtnInputView6->Left-BtnInputView5->Width; - BtnInputView4->Left=BtnInputView5->Left-BtnInputView4->Width; - BtnInputView3->Left=BtnInputView4->Left-BtnInputView3->Width; - - DisableHighlight(); +void __fastcall TMainForm::Panel4Resize(TObject *Sender) { + TButton *btns[] = {BtnInputFile1, BtnInputFile2, BtnInputFile3, BtnInputFile4, BtnInputFile5, + BtnInputFile6, BtnInputFile7, BtnInputFile8, BtnInputFile9, BtnInputFile10}; + TComboBox *boxes[] = {InputFile1, InputFile2, InputFile3, InputFile4, InputFile5, + InputFile6, InputFile7, InputFile8, InputFile9, InputFile10}; + int w = Panel4->Width; + + for (int i = 0; i < 10; i++) { + btns[i]->Left = w - btns[i]->Width - 5; + boxes[i]->Width = w - btns[i]->Width - boxes[i]->Left - 6; + } + BtnInputView1->Left = InputFile1->Left + InputFile1->Width - BtnInputView1->Width; + BtnInputPlot1->Left = BtnInputView1->Left - BtnInputPlot1->Width; + BtnInputView2->Left = InputFile2->Left + InputFile2->Width - BtnInputView2->Width; + BtnInputPlot2->Left = BtnInputView2->Left - BtnInputPlot2->Width; + BtnInputView10->Left = InputFile3->Left + InputFile3->Width - BtnInputView10->Width; + BtnInputView9->Left = BtnInputView10->Left - BtnInputView9->Width; + BtnInputView8->Left = BtnInputView9->Left - BtnInputView8->Width; + BtnInputView7->Left = BtnInputView8->Left - BtnInputView7->Width; + BtnInputView6->Left = BtnInputView7->Left - BtnInputView6->Width; + BtnInputView5->Left = BtnInputView6->Left - BtnInputView5->Width; + BtnInputView4->Left = BtnInputView5->Left - BtnInputView4->Width; + BtnInputView3->Left = BtnInputView4->Left - BtnInputView3->Width; + + DisableHighlight(); } //--------------------------------------------------------------------------- -void __fastcall TMainForm::Panel5Resize(TObject *Sender) -{ - int w=Panel5->Width; - - BtnOutDir->Left=w-BtnOutDir->Width-5; - OutDir->Width=w-BtnOutDir->Width-OutDir->Left-6; - BtnOutputFile->Left=w-BtnOutputFile->Width-5; - OutputFile->Width=w-BtnOutputFile->Width-OutputFile->Left-6; - - DisableHighlight(); +void __fastcall TMainForm::Panel5Resize(TObject *Sender) { + int w = Panel5->Width; + + BtnOutDir->Left = w - BtnOutDir->Width - 5; + OutDir->Width = w - BtnOutDir->Width - OutDir->Left - 6; + BtnOutputFile->Left = w - BtnOutputFile->Width - 5; + OutputFile->Width = w - BtnOutputFile->Width - OutputFile->Left - 6; + + DisableHighlight(); } //--------------------------------------------------------------------------- -void __fastcall TMainForm::Panel2Resize(TObject *Sender) -{ - TBitBtn *btns[]={ - BtnPlot,BtnView,BtnToKML,BtnOption,BtnExec,BtnExit - }; - int w=(Panel2->Width-4)/6; - - for (int i=0;i<6;i++) { - btns[i]->Width=w-2; - btns[i]->Left=i*w+2; - } - BtnAbort->Width=BtnExec->Width; - BtnAbort->Left =BtnExec->Left; +void __fastcall TMainForm::Panel2Resize(TObject *Sender) { + TBitBtn *btns[] = {BtnPlot, BtnView, BtnToKML, BtnOption, BtnExec, BtnExit}; + int w = (Panel2->Width - 4) / 6; + + for (int i = 0; i < 6; i++) { + btns[i]->Width = w - 2; + btns[i]->Left = i * w + 2; + } + BtnAbort->Width = BtnExec->Width; + BtnAbort->Left = BtnExec->Left; } //--------------------------------------------------------------------------- -void __fastcall TMainForm::ComboCloseUp(TObject *Sender) -{ - TComboBox *combo=(TComboBox *)Sender; +void __fastcall TMainForm::ComboCloseUp(TObject *Sender) { + TComboBox *combo = (TComboBox *)Sender; - ::PostMessage(combo->Handle,CB_SETEDITSEL,-1,0); + ::PostMessage(combo->Handle, CB_SETEDITSEL, -1, 0); } //--------------------------------------------------------------------------- - diff --git a/app/winapp/rtkpost/postmain.h b/app/winapp/rtkpost/postmain.h index 67a0e6417..14e6eaa7e 100644 --- a/app/winapp/rtkpost/postmain.h +++ b/app/winapp/rtkpost/postmain.h @@ -2,15 +2,15 @@ #ifndef postmainH #define postmainH //--------------------------------------------------------------------------- +#include #include +#include #include -#include -#include -#include #include -#include -#include +#include #include +#include +#include #ifdef TCPP #include #else @@ -19,231 +19,228 @@ #include "rtklib.h" //--------------------------------------------------------------------------- -class TMainForm : public TForm -{ -__published: - TPanel *Panel1; - TPanel *Panel2; - TPanel *Panel3; - TPanel *Panel4; - TPanel *Panel5; - TPanel *Message; - TButton *BtnInputFile1; - TButton *BtnInputFile3; - TButton *BtnInputFile2; - TButton *BtnInputFile4; - TButton *BtnInputFile5; - TButton *BtnOutputFile; - - TSpeedButton *BtnTime1; - TSpeedButton *BtnTime2; - TSpeedButton *BtnInputPlot1; - TSpeedButton *BtnInputView1; - TSpeedButton *BtnInputView3; - TSpeedButton *BtnInputPlot2; - TSpeedButton *BtnInputView2; - TSpeedButton *BtnInputView4; - TSpeedButton *BtnInputView5; - TSpeedButton *BtnAbout; - TSpeedButton *BtnKeyword; - - TCheckBox *TimeStart; - TCheckBox *TimeEnd; - TCheckBox *TimeIntF; - TCheckBox *TimeUnitF; - TEdit *TimeY1; - TEdit *TimeH1; - TEdit *TimeY2; - TEdit *TimeH2; - TEdit *TimeUnit; - TUpDown *TimeY1UD; - TUpDown *TimeH1UD; - TUpDown *TimeY2UD; - TUpDown *TimeH2UD; - TComboBox *TimeInt; - TComboBox *InputFile1; - TComboBox *InputFile3; - TComboBox *InputFile2; - TComboBox *InputFile4; - TComboBox *InputFile5; - TComboBox *OutputFile; - - TOpenDialog *OpenDialog; - TSaveDialog *SaveDialog; - - TProgressBar *Progress; - - TLabel *Label1; - TLabel *LabelInputFile1; - TLabel *LabelInputFile2; - TLabel *LabelInputFile3; - TLabel *LabelTimeInt; - TLabel *LabelTimeUnit; - TEdit *OutDir; - TCheckBox *OutDirEna; - TButton *BtnOutDir; - TSpeedButton *BtnOutputView2; - TSpeedButton *BtnOutputView1; - TLabel *LabelOutDir; - TComboBox *InputFile6; - TButton *BtnInputFile6; - TSpeedButton *BtnInputView6; - TComboBox *InputFile7; - TButton *BtnInputFile7; - TSpeedButton *BtnInputView7; - TComboBox *InputFile8; - TButton *BtnInputFile8; - TSpeedButton *BtnInputView8; - TComboBox *InputFile9; - TButton *BtnInputFile9; - TSpeedButton *BtnInputView9; - TComboBox *InputFile10; - TButton *BtnInputFile10; - TSpeedButton *BtnInputView10; - TBitBtn *BtnView; - TBitBtn *BtnOption; - TBitBtn *BtnExec; - TBitBtn *BtnAbort; - TBitBtn *BtnPlot; - TBitBtn *BtnToKML; - TBitBtn *BtnExit; - TLabel *Debug; - - void __fastcall FormCreate (TObject *Sender); - void __fastcall FormShow (TObject *Sender); - void __fastcall FormClose (TObject *Sender, TCloseAction &Action); - - void __fastcall BtnPlotClick (TObject *Sender); - void __fastcall BtnViewClick (TObject *Sender); - void __fastcall BtnToKMLClick (TObject *Sender); - void __fastcall BtnOptionClick (TObject *Sender); - void __fastcall BtnExecClick (TObject *Sender); - void __fastcall BtnExitClick (TObject *Sender); - void __fastcall BtnAboutClick (TObject *Sender); - - void __fastcall BtnTime1Click (TObject *Sender); - void __fastcall BtnTime2Click (TObject *Sender); - void __fastcall BtnInputFile1Click (TObject *Sender); - void __fastcall BtnInputFile3Click (TObject *Sender); - void __fastcall BtnInputFile2Click (TObject *Sender); - void __fastcall BtnInputFile4Click (TObject *Sender); - void __fastcall BtnInputFile5Click (TObject *Sender); - void __fastcall BtnOutputFileClick (TObject *Sender); - void __fastcall BtnInputView1Click (TObject *Sender); - void __fastcall BtnInputView3Click (TObject *Sender); - void __fastcall BtnInputView2Click (TObject *Sender); - void __fastcall BtnInputView4Click (TObject *Sender); - void __fastcall BtnInputView5Click (TObject *Sender); - void __fastcall BtnOutputView1Click(TObject *Sender); - void __fastcall BtnOutputView2Click(TObject *Sender); - void __fastcall BtnInputPlot1Click (TObject *Sender); - void __fastcall BtnInputPlot2Click (TObject *Sender); - void __fastcall BtnKeywordClick (TObject *Sender); - - void __fastcall TimeStartClick (TObject *Sender); - void __fastcall TimeEndClick (TObject *Sender); - void __fastcall TimeIntFClick (TObject *Sender); - void __fastcall TimeUnitFClick (TObject *Sender); - void __fastcall InputFile1Change (TObject *Sender); - void __fastcall OutDirEnaClick(TObject *Sender); - void __fastcall BtnOutDirClick(TObject *Sender); - void __fastcall OutDirChange(TObject *Sender); - void __fastcall BtnInputFile6Click(TObject *Sender); - void __fastcall BtnInputView6Click(TObject *Sender); - void __fastcall BtnInputFile7Click(TObject *Sender); - void __fastcall BtnInputView7Click(TObject *Sender); - void __fastcall BtnInputFile8Click(TObject *Sender); - void __fastcall BtnInputView8Click(TObject *Sender); - void __fastcall BtnInputFile9Click(TObject *Sender); - void __fastcall BtnInputView9Click(TObject *Sender); - void __fastcall BtnInputFile10Click(TObject *Sender); - void __fastcall BtnInputView10Click(TObject *Sender); - void __fastcall BtnAbortClick(TObject *Sender); - void __fastcall Panel4Resize(TObject *Sender); - void __fastcall Panel5Resize(TObject *Sender); - void __fastcall Panel2Resize(TObject *Sender); - void __fastcall TimeY1KeyDown(TObject *Sender, WORD &Key, TShiftState Shift); - void __fastcall TimeH1KeyDown(TObject *Sender, WORD &Key, TShiftState Shift); - void __fastcall TimeY2KeyDown(TObject *Sender, WORD &Key, TShiftState Shift); - void __fastcall TimeH2KeyDown(TObject *Sender, WORD &Key, TShiftState Shift); - void __fastcall TimeY1UDChangingEx(TObject *Sender, bool &AllowChange, int NewValue, - TUpDownDirection Direction); - void __fastcall TimeH1UDChangingEx(TObject *Sender, bool &AllowChange, int NewValue, - TUpDownDirection Direction); - void __fastcall TimeY2UDChangingEx(TObject *Sender, bool &AllowChange, int NewValue, - TUpDownDirection Direction); - void __fastcall TimeH2UDChangingEx(TObject *Sender, bool &AllowChange, int NewValue, - TUpDownDirection Direction); - void __fastcall ComboCloseUp(TObject *Sender); - -private: - void __fastcall DropFiles (TWMDropFiles msg); // for files drop - - int __fastcall ExecProc (void); - - int __fastcall GetOption(prcopt_t &prcopt, solopt_t &solopt, filopt_t &filopt); - - int __fastcall ObsToNav (const char *obsfile, char *navfile); - - AnsiString __fastcall FilePath(AnsiString file); - TStringList * __fastcall ReadList(TIniFile *ini, AnsiString cat, - AnsiString key); - void __fastcall WriteList(TIniFile *ini, AnsiString cat, - AnsiString key, TStrings *list); - void __fastcall AddHist (TComboBox *combo); - int __fastcall ExecCmd(AnsiString cmd, int show); - - gtime_t __fastcall GetTime1(void); - gtime_t __fastcall GetTime2(void); - void __fastcall SetOutFile(void); - void __fastcall SetTime1(gtime_t time); - void __fastcall SetTime2(gtime_t time); - void __fastcall UpdateEnable(void); - void __fastcall DisableHighlight(void); - void __fastcall LoadOpt(void); - void __fastcall SaveOpt(void); - - BEGIN_MESSAGE_MAP - MESSAGE_HANDLER(WM_DROPFILES,TWMDropFiles,DropFiles); - END_MESSAGE_MAP(TForm); -public: - AnsiString IniFile; - int AbortFlag; - - // options - int PosMode,Freq,Solution,DynamicModel,IonoOpt,TropOpt,RcvBiasEst; - int ARIter,MinFixSats,MinHoldSats,MinDropSats,ARFilter; - int NumIter,CodeSmooth,TideCorr; - int OutCntResetAmb,FixCntHoldAmb,LockCntFixAmb,RovPosType,RefPosType; - int SatEphem,NavSys; - int RovAntPcv,RefAntPcv,AmbRes,GloAmbRes,BdsAmbRes; - int OutputHead,OutputOpt,OutputVel,OutputSingle,OutputDatum; - int OutputHeight,OutputGeoid,DebugTrace,DebugStatus,BaseLineConst; - int SolFormat,TimeFormat,LatLonFormat,IntpRefObs,NetRSCorr,SatClkCorr; - int SbasCorr,SbasCorr1,SbasCorr2,SbasCorr3,SbasCorr4,TimeDecimal; - int SolStatic,SbasSat,MapFunc; - int PosOpt[6]; - double ElMask,MaxAgeDiff,VarHoldAmb,GainHoldAmb,RejectCode,RejectPhase; - double MeasErrR1,MeasErrR2,MeasErrR5,MeasErrR6; - double MeasErr2,MeasErr3,MeasErr4,MeasErr5,MeasErr6,MeasErr7,MeasErr8; - double SatClkStab,RovAntE,RovAntN,RovAntU,RefAntE,RefAntN,RefAntU; - double PrNoise1,PrNoise2,PrNoise3,PrNoise4,PrNoise5; - double ValidThresAR,ElMaskAR,ElMaskHold,SlipThres,DopThres; - double MaxPosVarAR,GloHwBias,ThresAR3,ThresAR4,ValidThresARMin,ValidThresARMax; - double RovPos[3],RefPos[3],BaseLine[2]; - double MaxSolStd; - snrmask_t SnrMask; - - AnsiString RnxOpts1,RnxOpts2,PPPOpts; - AnsiString FieldSep,RovAnt,RefAnt,AntPcvFile,StaPosFile,PrecEphFile; - AnsiString NetRSCorrFile1,NetRSCorrFile2,SatClkCorrFile,GoogleEarthFile; - AnsiString GeoidDataFile,IonoFile,DCBFile,EOPFile,BLQFile; - AnsiString SbasCorrFile,SatPcvFile,ExSats; - AnsiString RovList,BaseList; - - void __fastcall ViewFile(AnsiString file); - void __fastcall ShowMsg(char *msg); - __fastcall TMainForm(TComponent* Owner); +class TMainForm : public TForm { + __published : TPanel *Panel1; + TPanel *Panel2; + TPanel *Panel3; + TPanel *Panel4; + TPanel *Panel5; + TPanel *Message; + TButton *BtnInputFile1; + TButton *BtnInputFile3; + TButton *BtnInputFile2; + TButton *BtnInputFile4; + TButton *BtnInputFile5; + TButton *BtnOutputFile; + + TSpeedButton *BtnTime1; + TSpeedButton *BtnTime2; + TSpeedButton *BtnInputPlot1; + TSpeedButton *BtnInputView1; + TSpeedButton *BtnInputView3; + TSpeedButton *BtnInputPlot2; + TSpeedButton *BtnInputView2; + TSpeedButton *BtnInputView4; + TSpeedButton *BtnInputView5; + TSpeedButton *BtnAbout; + TSpeedButton *BtnKeyword; + + TCheckBox *TimeStart; + TCheckBox *TimeEnd; + TCheckBox *TimeIntF; + TCheckBox *TimeUnitF; + TEdit *TimeY1; + TEdit *TimeH1; + TEdit *TimeY2; + TEdit *TimeH2; + TEdit *TimeUnit; + TUpDown *TimeY1UD; + TUpDown *TimeH1UD; + TUpDown *TimeY2UD; + TUpDown *TimeH2UD; + TComboBox *TimeInt; + TComboBox *InputFile1; + TComboBox *InputFile3; + TComboBox *InputFile2; + TComboBox *InputFile4; + TComboBox *InputFile5; + TComboBox *OutputFile; + + TOpenDialog *OpenDialog; + TSaveDialog *SaveDialog; + + TProgressBar *Progress; + + TLabel *Label1; + TLabel *LabelInputFile1; + TLabel *LabelInputFile2; + TLabel *LabelInputFile3; + TLabel *LabelTimeInt; + TLabel *LabelTimeUnit; + TEdit *OutDir; + TCheckBox *OutDirEna; + TButton *BtnOutDir; + TSpeedButton *BtnOutputView2; + TSpeedButton *BtnOutputView1; + TLabel *LabelOutDir; + TComboBox *InputFile6; + TButton *BtnInputFile6; + TSpeedButton *BtnInputView6; + TComboBox *InputFile7; + TButton *BtnInputFile7; + TSpeedButton *BtnInputView7; + TComboBox *InputFile8; + TButton *BtnInputFile8; + TSpeedButton *BtnInputView8; + TComboBox *InputFile9; + TButton *BtnInputFile9; + TSpeedButton *BtnInputView9; + TComboBox *InputFile10; + TButton *BtnInputFile10; + TSpeedButton *BtnInputView10; + TBitBtn *BtnView; + TBitBtn *BtnOption; + TBitBtn *BtnExec; + TBitBtn *BtnAbort; + TBitBtn *BtnPlot; + TBitBtn *BtnToKML; + TBitBtn *BtnExit; + TLabel *Debug; + + void __fastcall FormCreate(TObject *Sender); + void __fastcall FormShow(TObject *Sender); + void __fastcall FormClose(TObject *Sender, TCloseAction &Action); + + void __fastcall BtnPlotClick(TObject *Sender); + void __fastcall BtnViewClick(TObject *Sender); + void __fastcall BtnToKMLClick(TObject *Sender); + void __fastcall BtnOptionClick(TObject *Sender); + void __fastcall BtnExecClick(TObject *Sender); + void __fastcall BtnExitClick(TObject *Sender); + void __fastcall BtnAboutClick(TObject *Sender); + + void __fastcall BtnTime1Click(TObject *Sender); + void __fastcall BtnTime2Click(TObject *Sender); + void __fastcall BtnInputFile1Click(TObject *Sender); + void __fastcall BtnInputFile3Click(TObject *Sender); + void __fastcall BtnInputFile2Click(TObject *Sender); + void __fastcall BtnInputFile4Click(TObject *Sender); + void __fastcall BtnInputFile5Click(TObject *Sender); + void __fastcall BtnOutputFileClick(TObject *Sender); + void __fastcall BtnInputView1Click(TObject *Sender); + void __fastcall BtnInputView3Click(TObject *Sender); + void __fastcall BtnInputView2Click(TObject *Sender); + void __fastcall BtnInputView4Click(TObject *Sender); + void __fastcall BtnInputView5Click(TObject *Sender); + void __fastcall BtnOutputView1Click(TObject *Sender); + void __fastcall BtnOutputView2Click(TObject *Sender); + void __fastcall BtnInputPlot1Click(TObject *Sender); + void __fastcall BtnInputPlot2Click(TObject *Sender); + void __fastcall BtnKeywordClick(TObject *Sender); + + void __fastcall TimeStartClick(TObject *Sender); + void __fastcall TimeEndClick(TObject *Sender); + void __fastcall TimeIntFClick(TObject *Sender); + void __fastcall TimeUnitFClick(TObject *Sender); + void __fastcall InputFile1Change(TObject *Sender); + void __fastcall OutDirEnaClick(TObject *Sender); + void __fastcall BtnOutDirClick(TObject *Sender); + void __fastcall OutDirChange(TObject *Sender); + void __fastcall BtnInputFile6Click(TObject *Sender); + void __fastcall BtnInputView6Click(TObject *Sender); + void __fastcall BtnInputFile7Click(TObject *Sender); + void __fastcall BtnInputView7Click(TObject *Sender); + void __fastcall BtnInputFile8Click(TObject *Sender); + void __fastcall BtnInputView8Click(TObject *Sender); + void __fastcall BtnInputFile9Click(TObject *Sender); + void __fastcall BtnInputView9Click(TObject *Sender); + void __fastcall BtnInputFile10Click(TObject *Sender); + void __fastcall BtnInputView10Click(TObject *Sender); + void __fastcall BtnAbortClick(TObject *Sender); + void __fastcall Panel4Resize(TObject *Sender); + void __fastcall Panel5Resize(TObject *Sender); + void __fastcall Panel2Resize(TObject *Sender); + void __fastcall TimeY1KeyDown(TObject *Sender, WORD &Key, TShiftState Shift); + void __fastcall TimeH1KeyDown(TObject *Sender, WORD &Key, TShiftState Shift); + void __fastcall TimeY2KeyDown(TObject *Sender, WORD &Key, TShiftState Shift); + void __fastcall TimeH2KeyDown(TObject *Sender, WORD &Key, TShiftState Shift); + void __fastcall TimeY1UDChangingEx(TObject *Sender, bool &AllowChange, int NewValue, + TUpDownDirection Direction); + void __fastcall TimeH1UDChangingEx(TObject *Sender, bool &AllowChange, int NewValue, + TUpDownDirection Direction); + void __fastcall TimeY2UDChangingEx(TObject *Sender, bool &AllowChange, int NewValue, + TUpDownDirection Direction); + void __fastcall TimeH2UDChangingEx(TObject *Sender, bool &AllowChange, int NewValue, + TUpDownDirection Direction); + void __fastcall ComboCloseUp(TObject *Sender); + + private: + void __fastcall DropFiles(TWMDropFiles msg); // for files drop + + int __fastcall ExecProc(void); + + int __fastcall GetOption(prcopt_t &prcopt, solopt_t &solopt, filopt_t &filopt); + + int __fastcall ObsToNav(const char *obsfile, char *navfile); + + AnsiString __fastcall FilePath(AnsiString file); + TStringList *__fastcall ReadList(TIniFile *ini, AnsiString cat, AnsiString key); + void __fastcall WriteList(TIniFile *ini, AnsiString cat, AnsiString key, TStrings *list); + void __fastcall AddHist(TComboBox *combo); + int __fastcall ExecCmd(AnsiString cmd, int show); + + gtime_t __fastcall GetTime1(void); + gtime_t __fastcall GetTime2(void); + void __fastcall SetOutFile(void); + void __fastcall SetTime1(gtime_t time); + void __fastcall SetTime2(gtime_t time); + void __fastcall UpdateEnable(void); + void __fastcall DisableHighlight(void); + void __fastcall LoadOpt(void); + void __fastcall SaveOpt(void); + + BEGIN_MESSAGE_MAP + MESSAGE_HANDLER(WM_DROPFILES, TWMDropFiles, DropFiles); + END_MESSAGE_MAP(TForm); + + public: + AnsiString IniFile; + int AbortFlag; + + // options + int PosMode, Freq, Solution, DynamicModel, IonoOpt, TropOpt, RcvBiasEst; + int ARIter, MinFixSats, MinHoldSats, MinDropSats, ARFilter; + int NumIter, CodeSmooth, TideCorr; + int OutCntResetAmb, FixCntHoldAmb, LockCntFixAmb, RovPosType, RefPosType; + int SatEphem, NavSys; + int RovAntPcv, RefAntPcv, AmbRes, GloAmbRes, BdsAmbRes; + int OutputHead, OutputOpt, OutputVel, OutputSingle, OutputDatum; + int OutputHeight, OutputGeoid, DebugTrace, DebugStatus, BaseLineConst; + int SolFormat, TimeFormat, LatLonFormat, IntpRefObs, NetRSCorr, SatClkCorr; + int SbasCorr, SbasCorr1, SbasCorr2, SbasCorr3, SbasCorr4, TimeDecimal; + int SolStatic, SbasSat, MapFunc; + int PosOpt[6]; + double ElMask, MaxAgeDiff, VarHoldAmb, GainHoldAmb, RejectCode, RejectPhase; + double MeasErrR1, MeasErrR2, MeasErrR5, MeasErrR6; + double MeasErr2, MeasErr3, MeasErr4, MeasErr5, MeasErr6, MeasErr7, MeasErr8; + double SatClkStab, RovAntE, RovAntN, RovAntU, RefAntE, RefAntN, RefAntU; + double PrNoise1, PrNoise2, PrNoise3, PrNoise4, PrNoise5; + double ValidThresAR, ElMaskAR, ElMaskHold, SlipThres, DopThres; + double MaxPosVarAR, GloHwBias, ThresAR3, ThresAR4, ValidThresARMin, ValidThresARMax; + double RovPos[3], RefPos[3], BaseLine[2]; + double MaxSolStd; + snrmask_t SnrMask; + + AnsiString RnxOpts1, RnxOpts2, PPPOpts; + AnsiString FieldSep, RovAnt, RefAnt, AntPcvFile, StaPosFile, PrecEphFile; + AnsiString NetRSCorrFile1, NetRSCorrFile2, SatClkCorrFile, GoogleEarthFile; + AnsiString GeoidDataFile, IonoFile, DCBFile, EOPFile, BLQFile; + AnsiString SbasCorrFile, SatPcvFile, ExSats; + AnsiString RovList, BaseList; + + void __fastcall ViewFile(AnsiString file); + void __fastcall ShowMsg(char *msg); + __fastcall TMainForm(TComponent *Owner); }; //--------------------------------------------------------------------------- extern PACKAGE TMainForm *MainForm; diff --git a/app/winapp/rtkpost/postopt.cpp b/app/winapp/rtkpost/postopt.cpp index eec8cfaa6..cab8af201 100644 --- a/app/winapp/rtkpost/postopt.cpp +++ b/app/winapp/rtkpost/postopt.cpp @@ -2,1147 +2,1039 @@ #include #pragma hdrstop -#include "postmain.h" #include "postopt.h" + +#include "freqdlg.h" #include "keydlg.h" -#include "viewer.h" -#include "refdlg.h" #include "maskoptdlg.h" -#include "freqdlg.h" +#include "postmain.h" +#include "refdlg.h" +#include "viewer.h" //--------------------------------------------------------------------------- #pragma package(smart_init) #pragma resource "*.dfm" TOptDialog *OptDialog; //--------------------------------------------------------------------------- -static double str2dbl(AnsiString str) -{ - double val=0.0; - sscanf(str.c_str(),"%lf",&val); - return val; +static double str2dbl(AnsiString str) { + double val = 0.0; + sscanf(str.c_str(), "%lf", &val); + return val; } //--------------------------------------------------------------------------- -__fastcall TOptDialog::TOptDialog(TComponent* Owner) - : TForm(Owner) -{ - AnsiString label,s; - int nglo=MAXPRNGLO,ngal=MAXPRNGAL,nqzs=MAXPRNQZS,ncmp=MAXPRNCMP; - int nirn=MAXPRNIRN; - - Freq->Items->Clear(); - for (int i=0;i0?"+":"")+s.sprintf("L%d",i + 1); - Freq->Items->Add(label); - } +__fastcall TOptDialog::TOptDialog(TComponent *Owner) : TForm(Owner) { + AnsiString label, s; + int nglo = MAXPRNGLO, ngal = MAXPRNGAL, nqzs = MAXPRNQZS, ncmp = MAXPRNCMP; + int nirn = MAXPRNIRN; + + Freq->Items->Clear(); + for (int i = 0; i < NFREQ; i++) { + label = label + (i > 0 ? "+" : "") + s.sprintf("L%d", i + 1); + Freq->Items->Add(label); + } - if (nglo<=0) NavSys2->Enabled=false; - if (ngal<=0) NavSys3->Enabled=false; - if (nqzs<=0) NavSys4->Enabled=false; - if (ncmp<=0) NavSys6->Enabled=false; - if (nirn<=0) NavSys7->Enabled=false; - UpdateEnable(); + if (nglo <= 0) NavSys2->Enabled = false; + if (ngal <= 0) NavSys3->Enabled = false; + if (nqzs <= 0) NavSys4->Enabled = false; + if (ncmp <= 0) NavSys6->Enabled = false; + if (nirn <= 0) NavSys7->Enabled = false; + UpdateEnable(); } //--------------------------------------------------------------------------- -void __fastcall TOptDialog::FormShow(TObject *Sender) -{ - GetOpt(); -} +void __fastcall TOptDialog::FormShow(TObject *Sender) { GetOpt(); } //--------------------------------------------------------------------------- -void __fastcall TOptDialog::BtnOkClick(TObject *Sender) -{ - SetOpt(); -} +void __fastcall TOptDialog::BtnOkClick(TObject *Sender) { SetOpt(); } //--------------------------------------------------------------------------- -void __fastcall TOptDialog::BtnLoadClick(TObject *Sender) -{ - OpenDialog->Title="Load Options"; - OpenDialog->FilterIndex=4; - if (!OpenDialog->Execute()) return; - LoadOpt(OpenDialog->FileName); +void __fastcall TOptDialog::BtnLoadClick(TObject *Sender) { + OpenDialog->Title = "Load Options"; + OpenDialog->FilterIndex = 4; + if (!OpenDialog->Execute()) return; + LoadOpt(OpenDialog->FileName); } //--------------------------------------------------------------------------- -void __fastcall TOptDialog::BtnSaveClick(TObject *Sender) -{ - AnsiString file; - SaveDialog->Title="Save Options"; - SaveDialog->FilterIndex=2; - if (!SaveDialog->Execute()) return; - file=SaveDialog->FileName; - if (!strrchr(file.c_str(),'.')) file=file+".conf"; - SaveOpt(file); +void __fastcall TOptDialog::BtnSaveClick(TObject *Sender) { + AnsiString file; + SaveDialog->Title = "Save Options"; + SaveDialog->FilterIndex = 2; + if (!SaveDialog->Execute()) return; + file = SaveDialog->FileName; + if (!strrchr(file.c_str(), '.')) file = file + ".conf"; + SaveOpt(file); } //--------------------------------------------------------------------------- -void __fastcall TOptDialog::BtnStaPosViewClick(TObject *Sender) -{ - if (StaPosFile->Text=="") return; - TTextViewer *viewer=new TTextViewer(Application); - viewer->Show(); - viewer->Read(StaPosFile->Text); +void __fastcall TOptDialog::BtnStaPosViewClick(TObject *Sender) { + if (StaPosFile->Text == "") return; + TTextViewer *viewer = new TTextViewer(Application); + viewer->Show(); + viewer->Read(StaPosFile->Text); } //--------------------------------------------------------------------------- -void __fastcall TOptDialog::BtnStaPosFileClick(TObject *Sender) -{ - OpenDialog->Title="Station Position File"; - OpenDialog->FilterIndex=3; - if (!OpenDialog->Execute()) return; - StaPosFile->Text=OpenDialog->FileName; +void __fastcall TOptDialog::BtnStaPosFileClick(TObject *Sender) { + OpenDialog->Title = "Station Position File"; + OpenDialog->FilterIndex = 3; + if (!OpenDialog->Execute()) return; + StaPosFile->Text = OpenDialog->FileName; } //--------------------------------------------------------------------------- -void __fastcall TOptDialog::RovPosTypeChange(TObject *Sender) -{ - TEdit *edit[]={RovPos1,RovPos2,RovPos3}; - double pos[3]; - GetPos(RovPosTypeP,edit,pos); - SetPos(RovPosType->ItemIndex,edit,pos); - RovPosTypeP=RovPosType->ItemIndex; - UpdateEnable(); +void __fastcall TOptDialog::RovPosTypeChange(TObject *Sender) { + TEdit *edit[] = {RovPos1, RovPos2, RovPos3}; + double pos[3]; + GetPos(RovPosTypeP, edit, pos); + SetPos(RovPosType->ItemIndex, edit, pos); + RovPosTypeP = RovPosType->ItemIndex; + UpdateEnable(); } //--------------------------------------------------------------------------- -void __fastcall TOptDialog::RefPosTypeChange(TObject *Sender) -{ - TEdit *edit[]={RefPos1,RefPos2,RefPos3}; - double pos[3]; - GetPos(RefPosTypeP,edit,pos); - SetPos(RefPosType->ItemIndex,edit,pos); - RefPosTypeP=RefPosType->ItemIndex; - UpdateEnable(); +void __fastcall TOptDialog::RefPosTypeChange(TObject *Sender) { + TEdit *edit[] = {RefPos1, RefPos2, RefPos3}; + double pos[3]; + GetPos(RefPosTypeP, edit, pos); + SetPos(RefPosType->ItemIndex, edit, pos); + RefPosTypeP = RefPosType->ItemIndex; + UpdateEnable(); } //--------------------------------------------------------------------------- -void __fastcall TOptDialog::BtnRovPosClick(TObject *Sender) -{ - TEdit *edit[]={RovPos1,RovPos2,RovPos3}; - double p[3],pos[3]; - GetPos(RovPosType->ItemIndex,edit,p); - ecef2pos(p,pos); - RefDialog->RovPos[0]=pos[0]*R2D; - RefDialog->RovPos[1]=pos[1]*R2D; - RefDialog->Pos[2]=pos[2]; - RefDialog->StaPosFile=StaPosFile->Text; - RefDialog->Left=Left+Width/2-RefDialog->Width/2; - RefDialog->Top=Top+Height/2-RefDialog->Height/2; - if (RefDialog->ShowModal()!=mrOk) return; - pos[0]=RefDialog->Pos[0]*D2R; - pos[1]=RefDialog->Pos[1]*D2R; - pos[2]=RefDialog->Pos[2]; - pos2ecef(pos,p); - SetPos(RovPosType->ItemIndex,edit,p); +void __fastcall TOptDialog::BtnRovPosClick(TObject *Sender) { + TEdit *edit[] = {RovPos1, RovPos2, RovPos3}; + double p[3], pos[3]; + GetPos(RovPosType->ItemIndex, edit, p); + ecef2pos(p, pos); + RefDialog->RovPos[0] = pos[0] * R2D; + RefDialog->RovPos[1] = pos[1] * R2D; + RefDialog->Pos[2] = pos[2]; + RefDialog->StaPosFile = StaPosFile->Text; + RefDialog->Left = Left + Width / 2 - RefDialog->Width / 2; + RefDialog->Top = Top + Height / 2 - RefDialog->Height / 2; + if (RefDialog->ShowModal() != mrOk) return; + pos[0] = RefDialog->Pos[0] * D2R; + pos[1] = RefDialog->Pos[1] * D2R; + pos[2] = RefDialog->Pos[2]; + pos2ecef(pos, p); + SetPos(RovPosType->ItemIndex, edit, p); } //--------------------------------------------------------------------------- -void __fastcall TOptDialog::BtnRefPosClick(TObject *Sender) -{ - TEdit *edit[]={RefPos1,RefPos2,RefPos3}; - double p[3],pos[3]; - GetPos(RefPosType->ItemIndex,edit,p); - ecef2pos(p,pos); - RefDialog->RovPos[0]=pos[0]*R2D; - RefDialog->RovPos[1]=pos[1]*R2D; - RefDialog->RovPos[2]=pos[2]; - RefDialog->StaPosFile=StaPosFile->Text; - RefDialog->Left=Left+Width/2-RefDialog->Width/2; - RefDialog->Top=Top+Height/2-RefDialog->Height/2; - if (RefDialog->ShowModal()!=mrOk) return; - pos[0]=RefDialog->Pos[0]*D2R; - pos[1]=RefDialog->Pos[1]*D2R; - pos[2]=RefDialog->Pos[2]; - pos2ecef(pos,p); - SetPos(RefPosType->ItemIndex,edit,p); +void __fastcall TOptDialog::BtnRefPosClick(TObject *Sender) { + TEdit *edit[] = {RefPos1, RefPos2, RefPos3}; + double p[3], pos[3]; + GetPos(RefPosType->ItemIndex, edit, p); + ecef2pos(p, pos); + RefDialog->RovPos[0] = pos[0] * R2D; + RefDialog->RovPos[1] = pos[1] * R2D; + RefDialog->RovPos[2] = pos[2]; + RefDialog->StaPosFile = StaPosFile->Text; + RefDialog->Left = Left + Width / 2 - RefDialog->Width / 2; + RefDialog->Top = Top + Height / 2 - RefDialog->Height / 2; + if (RefDialog->ShowModal() != mrOk) return; + pos[0] = RefDialog->Pos[0] * D2R; + pos[1] = RefDialog->Pos[1] * D2R; + pos[2] = RefDialog->Pos[2]; + pos2ecef(pos, p); + SetPos(RefPosType->ItemIndex, edit, p); } //--------------------------------------------------------------------------- -void __fastcall TOptDialog::BtnSatPcvViewClick(TObject *Sender) -{ - if (SatPcvFile->Text=="") return; - TTextViewer *viewer=new TTextViewer(Application); - viewer->Show(); - viewer->Read(SatPcvFile->Text); +void __fastcall TOptDialog::BtnSatPcvViewClick(TObject *Sender) { + if (SatPcvFile->Text == "") return; + TTextViewer *viewer = new TTextViewer(Application); + viewer->Show(); + viewer->Read(SatPcvFile->Text); } //--------------------------------------------------------------------------- -void __fastcall TOptDialog::BtnSatPcvFileClick(TObject *Sender) -{ - OpenDialog->Title="Satellite Antenna PCV File"; - OpenDialog->FilterIndex=2; - if (!OpenDialog->Execute()) return; - SatPcvFile->Text=OpenDialog->FileName; +void __fastcall TOptDialog::BtnSatPcvFileClick(TObject *Sender) { + OpenDialog->Title = "Satellite Antenna PCV File"; + OpenDialog->FilterIndex = 2; + if (!OpenDialog->Execute()) return; + SatPcvFile->Text = OpenDialog->FileName; } //--------------------------------------------------------------------------- -void __fastcall TOptDialog::BtnAntPcvViewClick(TObject *Sender) -{ - if (AntPcvFile->Text=="") return; - TTextViewer *viewer=new TTextViewer(Application); - viewer->Show(); - viewer->Read(AntPcvFile->Text); +void __fastcall TOptDialog::BtnAntPcvViewClick(TObject *Sender) { + if (AntPcvFile->Text == "") return; + TTextViewer *viewer = new TTextViewer(Application); + viewer->Show(); + viewer->Read(AntPcvFile->Text); } //--------------------------------------------------------------------------- -void __fastcall TOptDialog::BtnAntPcvFileClick(TObject *Sender) -{ - OpenDialog->Title="Receiver Antenna PCV File"; - OpenDialog->FilterIndex=2; - if (!OpenDialog->Execute()) return; - AntPcvFile->Text=OpenDialog->FileName; +void __fastcall TOptDialog::BtnAntPcvFileClick(TObject *Sender) { + OpenDialog->Title = "Receiver Antenna PCV File"; + OpenDialog->FilterIndex = 2; + if (!OpenDialog->Execute()) return; + AntPcvFile->Text = OpenDialog->FileName; } //--------------------------------------------------------------------------- -void __fastcall TOptDialog::BtnGeoidDataFileClick(TObject *Sender) -{ - OpenDialog->Title="Geoid Data File"; - OpenDialog->FilterIndex=1; - if (!OpenDialog->Execute()) return; - GeoidDataFile->Text=OpenDialog->FileName; +void __fastcall TOptDialog::BtnGeoidDataFileClick(TObject *Sender) { + OpenDialog->Title = "Geoid Data File"; + OpenDialog->FilterIndex = 1; + if (!OpenDialog->Execute()) return; + GeoidDataFile->Text = OpenDialog->FileName; } //--------------------------------------------------------------------------- -void __fastcall TOptDialog::BtnDCBFileClick(TObject *Sender) -{ - OpenDialog->Title="DCB Data File"; - OpenDialog->FilterIndex=5; - if (!OpenDialog->Execute()) return; - DCBFile->Text=OpenDialog->FileName; +void __fastcall TOptDialog::BtnDCBFileClick(TObject *Sender) { + OpenDialog->Title = "DCB Data File"; + OpenDialog->FilterIndex = 5; + if (!OpenDialog->Execute()) return; + DCBFile->Text = OpenDialog->FileName; } //--------------------------------------------------------------------------- -void __fastcall TOptDialog::BtnDCBViewClick(TObject *Sender) -{ - AnsiString DCBFile_Text=DCBFile->Text; - if (DCBFile->Text=="") return; - TTextViewer *viewer=new TTextViewer(Application); - viewer->Show(); - viewer->Read(DCBFile_Text); +void __fastcall TOptDialog::BtnDCBViewClick(TObject *Sender) { + AnsiString DCBFile_Text = DCBFile->Text; + if (DCBFile->Text == "") return; + TTextViewer *viewer = new TTextViewer(Application); + viewer->Show(); + viewer->Read(DCBFile_Text); } //--------------------------------------------------------------------------- -void __fastcall TOptDialog::BtnEOPFileClick(TObject *Sender) -{ - OpenDialog->Title="EOP Data File"; - OpenDialog->FilterIndex=6; - if (!OpenDialog->Execute()) return; - EOPFile->Text=OpenDialog->FileName; +void __fastcall TOptDialog::BtnEOPFileClick(TObject *Sender) { + OpenDialog->Title = "EOP Data File"; + OpenDialog->FilterIndex = 6; + if (!OpenDialog->Execute()) return; + EOPFile->Text = OpenDialog->FileName; } //--------------------------------------------------------------------------- -void __fastcall TOptDialog::BtnEOPViewClick(TObject *Sender) -{ - AnsiString EOPFile_Text=EOPFile->Text; - if (EOPFile->Text=="") return; - TTextViewer *viewer=new TTextViewer(Application); - viewer->Show(); - viewer->Read(EOPFile_Text); +void __fastcall TOptDialog::BtnEOPViewClick(TObject *Sender) { + AnsiString EOPFile_Text = EOPFile->Text; + if (EOPFile->Text == "") return; + TTextViewer *viewer = new TTextViewer(Application); + viewer->Show(); + viewer->Read(EOPFile_Text); } //--------------------------------------------------------------------------- -void __fastcall TOptDialog::BtnBLQFileClick(TObject *Sender) -{ - OpenDialog->Title="Ocean Tide Loding BLQ File"; - OpenDialog->FilterIndex=7; - if (!OpenDialog->Execute()) return; - BLQFile->Text=OpenDialog->FileName; +void __fastcall TOptDialog::BtnBLQFileClick(TObject *Sender) { + OpenDialog->Title = "Ocean Tide Loding BLQ File"; + OpenDialog->FilterIndex = 7; + if (!OpenDialog->Execute()) return; + BLQFile->Text = OpenDialog->FileName; } //--------------------------------------------------------------------------- -void __fastcall TOptDialog::BtnBLQFileViewClick(TObject *Sender) -{ - AnsiString BLQFile_Text=BLQFile->Text; - if (BLQFile->Text=="") return; - TTextViewer *viewer=new TTextViewer(Application); - viewer->Show(); - viewer->Read(BLQFile_Text); +void __fastcall TOptDialog::BtnBLQFileViewClick(TObject *Sender) { + AnsiString BLQFile_Text = BLQFile->Text; + if (BLQFile->Text == "") return; + TTextViewer *viewer = new TTextViewer(Application); + viewer->Show(); + viewer->Read(BLQFile_Text); } //--------------------------------------------------------------------------- -void __fastcall TOptDialog::BtnIonoFileClick(TObject *Sender) -{ - OpenDialog->Title="Ionosphere Data File"; - OpenDialog->FilterIndex=8; - if (!OpenDialog->Execute()) return; - IonoFile->Text=OpenDialog->FileName; +void __fastcall TOptDialog::BtnIonoFileClick(TObject *Sender) { + OpenDialog->Title = "Ionosphere Data File"; + OpenDialog->FilterIndex = 8; + if (!OpenDialog->Execute()) return; + IonoFile->Text = OpenDialog->FileName; } //--------------------------------------------------------------------------- -void __fastcall TOptDialog::FreqChange(TObject *Sender) -{ - UpdateEnable(); -} +void __fastcall TOptDialog::FreqChange(TObject *Sender) { UpdateEnable(); } //--------------------------------------------------------------------------- -void __fastcall TOptDialog::IonoOptChange(TObject *Sender) -{ - UpdateEnable(); -} +void __fastcall TOptDialog::IonoOptChange(TObject *Sender) { UpdateEnable(); } //--------------------------------------------------------------------------- -void __fastcall TOptDialog::TropOptChange(TObject *Sender) -{ - UpdateEnable(); -} +void __fastcall TOptDialog::TropOptChange(TObject *Sender) { UpdateEnable(); } //--------------------------------------------------------------------------- -void __fastcall TOptDialog::DynamicModelChange(TObject *Sender) -{ - UpdateEnable(); -} +void __fastcall TOptDialog::DynamicModelChange(TObject *Sender) { UpdateEnable(); } //--------------------------------------------------------------------------- -void __fastcall TOptDialog::SatEphemChange(TObject *Sender) -{ - UpdateEnable(); -} +void __fastcall TOptDialog::SatEphemChange(TObject *Sender) { UpdateEnable(); } //--------------------------------------------------------------------------- -void __fastcall TOptDialog::SolFormatChange(TObject *Sender) -{ - UpdateEnable(); -} +void __fastcall TOptDialog::SolFormatChange(TObject *Sender) { UpdateEnable(); } //--------------------------------------------------------------------------- -void __fastcall TOptDialog::PosModeChange(TObject *Sender) -{ - UpdateEnable(); -} +void __fastcall TOptDialog::PosModeChange(TObject *Sender) { UpdateEnable(); } //--------------------------------------------------------------------------- -void __fastcall TOptDialog::SatEphemClick(TObject *Sender) -{ - UpdateEnable(); -} +void __fastcall TOptDialog::SatEphemClick(TObject *Sender) { UpdateEnable(); } //--------------------------------------------------------------------------- -void __fastcall TOptDialog::NavSys2Click(TObject *Sender) -{ - UpdateEnable(); -} +void __fastcall TOptDialog::NavSys2Click(TObject *Sender) { UpdateEnable(); } //--------------------------------------------------------------------------- -void __fastcall TOptDialog::AmbResChange(TObject *Sender) -{ - UpdateEnable(); -} +void __fastcall TOptDialog::AmbResChange(TObject *Sender) { UpdateEnable(); } //--------------------------------------------------------------------------- -void __fastcall TOptDialog::RovAntPcvClick(TObject *Sender) -{ - UpdateEnable(); -} +void __fastcall TOptDialog::RovAntPcvClick(TObject *Sender) { UpdateEnable(); } //--------------------------------------------------------------------------- -void __fastcall TOptDialog::NetRSCorrClick(TObject *Sender) -{ - UpdateEnable(); -} +void __fastcall TOptDialog::NetRSCorrClick(TObject *Sender) { UpdateEnable(); } //--------------------------------------------------------------------------- -void __fastcall TOptDialog::SatClkCorrClick(TObject *Sender) -{ - UpdateEnable(); -} +void __fastcall TOptDialog::SatClkCorrClick(TObject *Sender) { UpdateEnable(); } //--------------------------------------------------------------------------- -void __fastcall TOptDialog::RovPosClick(TObject *Sender) -{ - UpdateEnable(); -} +void __fastcall TOptDialog::RovPosClick(TObject *Sender) { UpdateEnable(); } //--------------------------------------------------------------------------- -void __fastcall TOptDialog::RefPosClick(TObject *Sender) -{ - UpdateEnable(); -} +void __fastcall TOptDialog::RefPosClick(TObject *Sender) { UpdateEnable(); } //--------------------------------------------------------------------------- -void __fastcall TOptDialog::SbasCorrClick(TObject *Sender) -{ - UpdateEnable(); -} +void __fastcall TOptDialog::SbasCorrClick(TObject *Sender) { UpdateEnable(); } //--------------------------------------------------------------------------- -void __fastcall TOptDialog::OutputHeightClick(TObject *Sender) -{ - UpdateEnable(); -} +void __fastcall TOptDialog::OutputHeightClick(TObject *Sender) { UpdateEnable(); } //--------------------------------------------------------------------------- -void __fastcall TOptDialog::BaselineConstClick(TObject *Sender) -{ - UpdateEnable(); -} +void __fastcall TOptDialog::BaselineConstClick(TObject *Sender) { UpdateEnable(); } //--------------------------------------------------------------------------- -void __fastcall TOptDialog::RovAntClick(TObject *Sender) -{ - UpdateEnable(); -} +void __fastcall TOptDialog::RovAntClick(TObject *Sender) { UpdateEnable(); } //--------------------------------------------------------------------------- -void __fastcall TOptDialog::RefAntClick(TObject *Sender) -{ - UpdateEnable(); -} +void __fastcall TOptDialog::RefAntClick(TObject *Sender) { UpdateEnable(); } //--------------------------------------------------------------------------- -void __fastcall TOptDialog::GetOpt(void) -{ - TEdit *editu[]={RovPos1,RovPos2,RovPos3}; - TEdit *editr[]={RefPos1,RefPos2,RefPos3}; - AnsiString s; - PosMode ->ItemIndex =MainForm->PosMode; - Freq ->ItemIndex =MainForm->Freq; - Solution ->ItemIndex =MainForm->Solution; - ElMask ->Text =s.sprintf("%.0f",MainForm->ElMask); - SnrMask =MainForm->SnrMask; - DynamicModel ->ItemIndex =MainForm->DynamicModel; - TideCorr ->ItemIndex =MainForm->TideCorr; - IonoOpt ->ItemIndex =MainForm->IonoOpt; - TropOpt ->ItemIndex =MainForm->TropOpt; - SatEphem ->ItemIndex =MainForm->SatEphem; - ExSats ->Text =MainForm->ExSats; - NavSys1 ->Checked =MainForm->NavSys&SYS_GPS; - NavSys2 ->Checked =MainForm->NavSys&SYS_GLO; - NavSys3 ->Checked =MainForm->NavSys&SYS_GAL; - NavSys4 ->Checked =MainForm->NavSys&SYS_QZS; - NavSys5 ->Checked =MainForm->NavSys&SYS_SBS; - NavSys6 ->Checked =MainForm->NavSys&SYS_CMP; - NavSys7 ->Checked =MainForm->NavSys&SYS_IRN; - PosOpt1 ->Checked =MainForm->PosOpt[0]; - PosOpt2 ->Checked =MainForm->PosOpt[1]; - PosOpt3 ->Checked =MainForm->PosOpt[2]; - PosOpt4 ->Checked =MainForm->PosOpt[3]; - PosOpt5 ->Checked =MainForm->PosOpt[4]; - PosOpt6 ->Checked =MainForm->PosOpt[5]; - - AmbRes ->ItemIndex =MainForm->AmbRes; - GloAmbRes ->ItemIndex =MainForm->GloAmbRes; - BdsAmbRes ->ItemIndex =MainForm->BdsAmbRes; - ValidThresAR ->Text =s.sprintf("%.3g",MainForm->ValidThresAR); - ValidThresARMin->Text =s.sprintf("%.3g",MainForm->ValidThresARMin); - ValidThresARMax->Text =s.sprintf("%.3g",MainForm->ValidThresARMax); - GloHwBias ->Text =s.sprintf("%.3g",MainForm->GloHwBias); - OutCntResetAmb->Text =s.sprintf("%d",MainForm->OutCntResetAmb); - FixCntHoldAmb->Text =s.sprintf("%d",MainForm->FixCntHoldAmb); - LockCntFixAmb->Text =s.sprintf("%d",MainForm->LockCntFixAmb); - ElMaskAR ->Text =s.sprintf("%.0f",MainForm->ElMaskAR); - ElMaskHold ->Text =s.sprintf("%.0f",MainForm->ElMaskHold); - MaxAgeDiff ->Text =s.sprintf("%.1f",MainForm->MaxAgeDiff); - RejectCode ->Text =s.sprintf("%.1f",MainForm->RejectCode); - RejectPhase ->Text =s.sprintf("%.1f",MainForm->RejectPhase); - VarHoldAmb ->Text =s.sprintf("%.4f",MainForm->VarHoldAmb); - GainHoldAmb ->Text =s.sprintf("%.4f",MainForm->GainHoldAmb); - SlipThres ->Text =s.sprintf("%.3f",MainForm->SlipThres); - DopThres ->Text =s.sprintf("%.3f",MainForm->DopThres); - //ARIter ->Text =s.sprintf("%d", MainForm->ARIter); - NumIter ->Text =s.sprintf("%d", MainForm->NumIter); - MinFixSats ->Text =s.sprintf("%d", MainForm->MinFixSats); - MinHoldSats ->Text =s.sprintf("%d", MainForm->MinHoldSats); - MinDropSats ->Text =s.sprintf("%d", MainForm->MinDropSats); - MaxPosVarAR ->Text =s.sprintf("%.4f",MainForm->MaxPosVarAR); - ARFilter ->ItemIndex =MainForm->ARFilter; - BaselineLen ->Text =s.sprintf("%.3f",MainForm->BaseLine[0]); - BaselineSig ->Text =s.sprintf("%.3f",MainForm->BaseLine[1]); - BaselineConst->Checked =MainForm->BaseLineConst; - - SolFormat ->ItemIndex =MainForm->SolFormat; - TimeFormat ->ItemIndex =MainForm->TimeFormat; - TimeDecimal ->Text =s.sprintf("%d",MainForm->TimeDecimal); - LatLonFormat ->ItemIndex =MainForm->LatLonFormat; - FieldSep ->Text =MainForm->FieldSep; - OutputHead ->ItemIndex =MainForm->OutputHead; - OutputOpt ->ItemIndex =MainForm->OutputOpt; - OutputVel ->ItemIndex =MainForm->OutputVel; - OutputSingle ->ItemIndex =MainForm->OutputSingle; - MaxSolStd ->Text =s.sprintf("%.2g",MainForm->MaxSolStd); - OutputDatum ->ItemIndex =MainForm->OutputDatum; - OutputHeight ->ItemIndex =MainForm->OutputHeight; - OutputGeoid ->ItemIndex =MainForm->OutputGeoid; - SolStatic ->ItemIndex =MainForm->SolStatic; - DebugTrace ->ItemIndex =MainForm->DebugTrace; - DebugStatus ->ItemIndex =MainForm->DebugStatus; - - MeasErrR1 ->Text =s.sprintf("%.1f",MainForm->MeasErrR1); - MeasErrR2 ->Text =s.sprintf("%.1f",MainForm->MeasErrR2); - MeasErrR5 ->Text =s.sprintf("%.1f",MainForm->MeasErrR5); - MeasErrR6 ->Text =s.sprintf("%.1f",MainForm->MeasErrR6); - MeasErr2 ->Text =s.sprintf("%.3f",MainForm->MeasErr2); - MeasErr3 ->Text =s.sprintf("%.3f",MainForm->MeasErr3); - MeasErr4 ->Text =s.sprintf("%.3f",MainForm->MeasErr4); - MeasErr5 ->Text =s.sprintf("%.3f",MainForm->MeasErr5); - MeasErr6 ->Text =s.sprintf("%.3f",MainForm->MeasErr6); - MeasErr7 ->Text =s.sprintf("%.3f",MainForm->MeasErr7); - MeasErr8 ->Text =s.sprintf("%.3f",MainForm->MeasErr8); - SatClkStab ->Text =s.sprintf("%.2E",MainForm->SatClkStab); - PrNoise1 ->Text =s.sprintf("%.2E",MainForm->PrNoise1); - PrNoise2 ->Text =s.sprintf("%.2E",MainForm->PrNoise2); - PrNoise3 ->Text =s.sprintf("%.2E",MainForm->PrNoise3); - PrNoise4 ->Text =s.sprintf("%.2E",MainForm->PrNoise4); - PrNoise5 ->Text =s.sprintf("%.2E",MainForm->PrNoise5); - - RovAntPcv ->Checked =MainForm->RovAntPcv; - RefAntPcv ->Checked =MainForm->RefAntPcv; - RovAnt ->Text =MainForm->RovAnt; - RefAnt ->Text =MainForm->RefAnt; - RovAntE ->Text =s.sprintf("%.4f",MainForm->RovAntE); - RovAntN ->Text =s.sprintf("%.4f",MainForm->RovAntN); - RovAntU ->Text =s.sprintf("%.4f",MainForm->RovAntU); - RefAntE ->Text =s.sprintf("%.4f",MainForm->RefAntE); - RefAntN ->Text =s.sprintf("%.4f",MainForm->RefAntN); - RefAntU ->Text =s.sprintf("%.4f",MainForm->RefAntU); - AntPcvFile ->Text =MainForm->AntPcvFile; - - RnxOpts1 ->Text =MainForm->RnxOpts1; - RnxOpts2 ->Text =MainForm->RnxOpts2; - PPPOpts ->Text =MainForm->PPPOpts; - - IntpRefObs ->ItemIndex =MainForm->IntpRefObs; - SbasSat ->Text =s.sprintf("%d",MainForm->SbasSat); - SatPcvFile ->Text =MainForm->SatPcvFile; - StaPosFile ->Text =MainForm->StaPosFile; - GeoidDataFile->Text =MainForm->GeoidDataFile; - EOPFile ->Text =MainForm->EOPFile; - DCBFile ->Text =MainForm->DCBFile; - BLQFile ->Text =MainForm->BLQFile; - IonoFile ->Text =MainForm->IonoFile; - RovPosType ->ItemIndex =MainForm->RovPosType; - RefPosType ->ItemIndex =MainForm->RefPosType; - RovPosTypeP =RovPosType->ItemIndex; - RefPosTypeP =RefPosType->ItemIndex; - SetPos(RovPosType->ItemIndex,editu,MainForm->RovPos); - SetPos(RefPosType->ItemIndex,editr,MainForm->RefPos); - ReadAntList(); - - RovList ->Text =MainForm->RovList; - BaseList ->Text =MainForm->BaseList; - - UpdateEnable(); +void __fastcall TOptDialog::GetOpt(void) { + TEdit *editu[] = {RovPos1, RovPos2, RovPos3}; + TEdit *editr[] = {RefPos1, RefPos2, RefPos3}; + AnsiString s; + PosMode->ItemIndex = MainForm->PosMode; + Freq->ItemIndex = MainForm->Freq; + Solution->ItemIndex = MainForm->Solution; + ElMask->Text = s.sprintf("%.0f", MainForm->ElMask); + SnrMask = MainForm->SnrMask; + DynamicModel->ItemIndex = MainForm->DynamicModel; + TideCorr->ItemIndex = MainForm->TideCorr; + IonoOpt->ItemIndex = MainForm->IonoOpt; + TropOpt->ItemIndex = MainForm->TropOpt; + SatEphem->ItemIndex = MainForm->SatEphem; + ExSats->Text = MainForm->ExSats; + NavSys1->Checked = MainForm->NavSys & SYS_GPS; + NavSys2->Checked = MainForm->NavSys & SYS_GLO; + NavSys3->Checked = MainForm->NavSys & SYS_GAL; + NavSys4->Checked = MainForm->NavSys & SYS_QZS; + NavSys5->Checked = MainForm->NavSys & SYS_SBS; + NavSys6->Checked = MainForm->NavSys & SYS_CMP; + NavSys7->Checked = MainForm->NavSys & SYS_IRN; + PosOpt1->Checked = MainForm->PosOpt[0]; + PosOpt2->Checked = MainForm->PosOpt[1]; + PosOpt3->Checked = MainForm->PosOpt[2]; + PosOpt4->Checked = MainForm->PosOpt[3]; + PosOpt5->Checked = MainForm->PosOpt[4]; + PosOpt6->Checked = MainForm->PosOpt[5]; + + AmbRes->ItemIndex = MainForm->AmbRes; + GloAmbRes->ItemIndex = MainForm->GloAmbRes; + BdsAmbRes->ItemIndex = MainForm->BdsAmbRes; + ValidThresAR->Text = s.sprintf("%.3g", MainForm->ValidThresAR); + ValidThresARMin->Text = s.sprintf("%.3g", MainForm->ValidThresARMin); + ValidThresARMax->Text = s.sprintf("%.3g", MainForm->ValidThresARMax); + GloHwBias->Text = s.sprintf("%.3g", MainForm->GloHwBias); + OutCntResetAmb->Text = s.sprintf("%d", MainForm->OutCntResetAmb); + FixCntHoldAmb->Text = s.sprintf("%d", MainForm->FixCntHoldAmb); + LockCntFixAmb->Text = s.sprintf("%d", MainForm->LockCntFixAmb); + ElMaskAR->Text = s.sprintf("%.0f", MainForm->ElMaskAR); + ElMaskHold->Text = s.sprintf("%.0f", MainForm->ElMaskHold); + MaxAgeDiff->Text = s.sprintf("%.1f", MainForm->MaxAgeDiff); + RejectCode->Text = s.sprintf("%.1f", MainForm->RejectCode); + RejectPhase->Text = s.sprintf("%.1f", MainForm->RejectPhase); + VarHoldAmb->Text = s.sprintf("%.4f", MainForm->VarHoldAmb); + GainHoldAmb->Text = s.sprintf("%.4f", MainForm->GainHoldAmb); + SlipThres->Text = s.sprintf("%.3f", MainForm->SlipThres); + DopThres->Text = s.sprintf("%.3f", MainForm->DopThres); + // ARIter ->Text =s.sprintf("%d", MainForm->ARIter); + NumIter->Text = s.sprintf("%d", MainForm->NumIter); + MinFixSats->Text = s.sprintf("%d", MainForm->MinFixSats); + MinHoldSats->Text = s.sprintf("%d", MainForm->MinHoldSats); + MinDropSats->Text = s.sprintf("%d", MainForm->MinDropSats); + MaxPosVarAR->Text = s.sprintf("%.4f", MainForm->MaxPosVarAR); + ARFilter->ItemIndex = MainForm->ARFilter; + BaselineLen->Text = s.sprintf("%.3f", MainForm->BaseLine[0]); + BaselineSig->Text = s.sprintf("%.3f", MainForm->BaseLine[1]); + BaselineConst->Checked = MainForm->BaseLineConst; + + SolFormat->ItemIndex = MainForm->SolFormat; + TimeFormat->ItemIndex = MainForm->TimeFormat; + TimeDecimal->Text = s.sprintf("%d", MainForm->TimeDecimal); + LatLonFormat->ItemIndex = MainForm->LatLonFormat; + FieldSep->Text = MainForm->FieldSep; + OutputHead->ItemIndex = MainForm->OutputHead; + OutputOpt->ItemIndex = MainForm->OutputOpt; + OutputVel->ItemIndex = MainForm->OutputVel; + OutputSingle->ItemIndex = MainForm->OutputSingle; + MaxSolStd->Text = s.sprintf("%.2g", MainForm->MaxSolStd); + OutputDatum->ItemIndex = MainForm->OutputDatum; + OutputHeight->ItemIndex = MainForm->OutputHeight; + OutputGeoid->ItemIndex = MainForm->OutputGeoid; + SolStatic->ItemIndex = MainForm->SolStatic; + DebugTrace->ItemIndex = MainForm->DebugTrace; + DebugStatus->ItemIndex = MainForm->DebugStatus; + + MeasErrR1->Text = s.sprintf("%.1f", MainForm->MeasErrR1); + MeasErrR2->Text = s.sprintf("%.1f", MainForm->MeasErrR2); + MeasErrR5->Text = s.sprintf("%.1f", MainForm->MeasErrR5); + MeasErrR6->Text = s.sprintf("%.1f", MainForm->MeasErrR6); + MeasErr2->Text = s.sprintf("%.3f", MainForm->MeasErr2); + MeasErr3->Text = s.sprintf("%.3f", MainForm->MeasErr3); + MeasErr4->Text = s.sprintf("%.3f", MainForm->MeasErr4); + MeasErr5->Text = s.sprintf("%.3f", MainForm->MeasErr5); + MeasErr6->Text = s.sprintf("%.3f", MainForm->MeasErr6); + MeasErr7->Text = s.sprintf("%.3f", MainForm->MeasErr7); + MeasErr8->Text = s.sprintf("%.3f", MainForm->MeasErr8); + SatClkStab->Text = s.sprintf("%.2E", MainForm->SatClkStab); + PrNoise1->Text = s.sprintf("%.2E", MainForm->PrNoise1); + PrNoise2->Text = s.sprintf("%.2E", MainForm->PrNoise2); + PrNoise3->Text = s.sprintf("%.2E", MainForm->PrNoise3); + PrNoise4->Text = s.sprintf("%.2E", MainForm->PrNoise4); + PrNoise5->Text = s.sprintf("%.2E", MainForm->PrNoise5); + + RovAntPcv->Checked = MainForm->RovAntPcv; + RefAntPcv->Checked = MainForm->RefAntPcv; + RovAnt->Text = MainForm->RovAnt; + RefAnt->Text = MainForm->RefAnt; + RovAntE->Text = s.sprintf("%.4f", MainForm->RovAntE); + RovAntN->Text = s.sprintf("%.4f", MainForm->RovAntN); + RovAntU->Text = s.sprintf("%.4f", MainForm->RovAntU); + RefAntE->Text = s.sprintf("%.4f", MainForm->RefAntE); + RefAntN->Text = s.sprintf("%.4f", MainForm->RefAntN); + RefAntU->Text = s.sprintf("%.4f", MainForm->RefAntU); + AntPcvFile->Text = MainForm->AntPcvFile; + + RnxOpts1->Text = MainForm->RnxOpts1; + RnxOpts2->Text = MainForm->RnxOpts2; + PPPOpts->Text = MainForm->PPPOpts; + + IntpRefObs->ItemIndex = MainForm->IntpRefObs; + SbasSat->Text = s.sprintf("%d", MainForm->SbasSat); + SatPcvFile->Text = MainForm->SatPcvFile; + StaPosFile->Text = MainForm->StaPosFile; + GeoidDataFile->Text = MainForm->GeoidDataFile; + EOPFile->Text = MainForm->EOPFile; + DCBFile->Text = MainForm->DCBFile; + BLQFile->Text = MainForm->BLQFile; + IonoFile->Text = MainForm->IonoFile; + RovPosType->ItemIndex = MainForm->RovPosType; + RefPosType->ItemIndex = MainForm->RefPosType; + RovPosTypeP = RovPosType->ItemIndex; + RefPosTypeP = RefPosType->ItemIndex; + SetPos(RovPosType->ItemIndex, editu, MainForm->RovPos); + SetPos(RefPosType->ItemIndex, editr, MainForm->RefPos); + ReadAntList(); + + RovList->Text = MainForm->RovList; + BaseList->Text = MainForm->BaseList; + + UpdateEnable(); } //--------------------------------------------------------------------------- -void __fastcall TOptDialog::SetOpt(void) -{ - TEdit *editu[]={RovPos1,RovPos2,RovPos3}; - TEdit *editr[]={RefPos1,RefPos2,RefPos3}; - - MainForm->PosMode =PosMode ->ItemIndex; - MainForm->Freq =Freq ->ItemIndex; - MainForm->Solution =Solution ->ItemIndex; - MainForm->ElMask =str2dbl(ElMask ->Text); - MainForm->SnrMask =SnrMask; - MainForm->DynamicModel =DynamicModel->ItemIndex; - MainForm->TideCorr =TideCorr ->ItemIndex; - MainForm->IonoOpt =IonoOpt ->ItemIndex; - MainForm->TropOpt =TropOpt ->ItemIndex; - MainForm->SatEphem =SatEphem ->ItemIndex; - MainForm->ExSats =ExSats ->Text; - MainForm->NavSys =0; - if (NavSys1->Checked) MainForm->NavSys|=SYS_GPS; - if (NavSys2->Checked) MainForm->NavSys|=SYS_GLO; - if (NavSys3->Checked) MainForm->NavSys|=SYS_GAL; - if (NavSys4->Checked) MainForm->NavSys|=SYS_QZS; - if (NavSys5->Checked) MainForm->NavSys|=SYS_SBS; - if (NavSys6->Checked) MainForm->NavSys|=SYS_CMP; - if (NavSys7->Checked) MainForm->NavSys|=SYS_IRN; - MainForm->PosOpt[0] =PosOpt1 ->Checked; - MainForm->PosOpt[1] =PosOpt2 ->Checked; - MainForm->PosOpt[2] =PosOpt3 ->Checked; - MainForm->PosOpt[3] =PosOpt4 ->Checked; - MainForm->PosOpt[4] =PosOpt5 ->Checked; - MainForm->PosOpt[5] =PosOpt6 ->Checked; - - MainForm->AmbRes =AmbRes ->ItemIndex; - MainForm->GloAmbRes =GloAmbRes ->ItemIndex; - MainForm->BdsAmbRes =BdsAmbRes ->ItemIndex; - MainForm->ValidThresAR =str2dbl(ValidThresAR->Text); - MainForm->ValidThresARMin=str2dbl(ValidThresARMin->Text); - MainForm->ValidThresARMax=str2dbl(ValidThresARMax->Text); - MainForm->GloHwBias =str2dbl(GloHwBias->Text); - MainForm->OutCntResetAmb=OutCntResetAmb->Text.ToInt(); - MainForm->FixCntHoldAmb =FixCntHoldAmb->Text.ToInt(); - MainForm->OutCntResetAmb=OutCntResetAmb->Text.ToInt(); - MainForm->LockCntFixAmb =LockCntFixAmb->Text.ToInt(); - MainForm->ElMaskAR =ElMaskAR ->Text.ToInt(); - MainForm->ElMaskHold =ElMaskHold ->Text.ToInt(); - MainForm->MaxAgeDiff =str2dbl(MaxAgeDiff ->Text); - MainForm->RejectCode =str2dbl(RejectCode ->Text); - MainForm->RejectPhase =str2dbl(RejectPhase->Text); - MainForm->VarHoldAmb =str2dbl(VarHoldAmb->Text); - MainForm->GainHoldAmb =str2dbl(GainHoldAmb->Text); - MainForm->SlipThres =str2dbl(SlipThres ->Text); - MainForm->DopThres =str2dbl(DopThres ->Text); - MainForm->NumIter =NumIter ->Text.ToInt(); - MainForm->MinFixSats =MinFixSats ->Text.ToInt(); - MainForm->MinHoldSats =MinHoldSats ->Text.ToInt(); - MainForm->MinDropSats =MinDropSats ->Text.ToInt(); - MainForm->ARFilter =ARFilter ->ItemIndex; - MainForm->MaxPosVarAR =str2dbl(MaxPosVarAR->Text); - MainForm->BaseLine[0] =str2dbl(BaselineLen->Text); - MainForm->BaseLine[1] =str2dbl(BaselineSig->Text); - MainForm->BaseLineConst =BaselineConst->Checked; - - MainForm->SolFormat =SolFormat ->ItemIndex; - MainForm->TimeFormat =TimeFormat ->ItemIndex; - MainForm->TimeDecimal =str2dbl(TimeDecimal->Text); - MainForm->LatLonFormat =LatLonFormat->ItemIndex; - MainForm->FieldSep =FieldSep ->Text; - MainForm->OutputHead =OutputHead ->ItemIndex; - MainForm->OutputOpt =OutputOpt ->ItemIndex; - MainForm->OutputVel =OutputVel ->ItemIndex; - MainForm->OutputSingle =OutputSingle->ItemIndex; - MainForm->MaxSolStd =str2dbl(MaxSolStd->Text); - MainForm->OutputDatum =OutputDatum->ItemIndex; - MainForm->OutputHeight =OutputHeight->ItemIndex; - MainForm->OutputGeoid =OutputGeoid->ItemIndex; - MainForm->SolStatic =SolStatic ->ItemIndex; - MainForm->DebugTrace =DebugTrace ->ItemIndex; - MainForm->DebugStatus =DebugStatus->ItemIndex; - - MainForm->MeasErrR1 =str2dbl(MeasErrR1 ->Text); - MainForm->MeasErrR2 =str2dbl(MeasErrR2 ->Text); - MainForm->MeasErrR5 =str2dbl(MeasErrR5 ->Text); - MainForm->MeasErrR6 =str2dbl(MeasErrR6 ->Text); - MainForm->MeasErr2 =str2dbl(MeasErr2 ->Text); - MainForm->MeasErr3 =str2dbl(MeasErr3 ->Text); - MainForm->MeasErr4 =str2dbl(MeasErr4 ->Text); - MainForm->MeasErr5 =str2dbl(MeasErr5 ->Text); - MainForm->MeasErr6 =str2dbl(MeasErr6 ->Text); - MainForm->MeasErr7 =str2dbl(MeasErr7 ->Text); - MainForm->MeasErr8 =str2dbl(MeasErr8 ->Text); - MainForm->SatClkStab =str2dbl(SatClkStab ->Text); - MainForm->PrNoise1 =str2dbl(PrNoise1 ->Text); - MainForm->PrNoise2 =str2dbl(PrNoise2 ->Text); - MainForm->PrNoise3 =str2dbl(PrNoise3 ->Text); - MainForm->PrNoise4 =str2dbl(PrNoise4 ->Text); - MainForm->PrNoise5 =str2dbl(PrNoise5 ->Text); - - MainForm->RovAntPcv =RovAntPcv ->Checked; - MainForm->RefAntPcv =RefAntPcv ->Checked; - MainForm->RovAnt =RovAnt ->Text; - MainForm->RefAnt =RefAnt ->Text; - MainForm->RovAntE =str2dbl(RovAntE ->Text); - MainForm->RovAntN =str2dbl(RovAntN ->Text); - MainForm->RovAntU =str2dbl(RovAntU ->Text); - MainForm->RefAntE =str2dbl(RefAntE ->Text); - MainForm->RefAntN =str2dbl(RefAntN ->Text); - MainForm->RefAntU =str2dbl(RefAntU ->Text); - - MainForm->RnxOpts1 =RnxOpts1 ->Text; - MainForm->RnxOpts2 =RnxOpts2 ->Text; - MainForm->PPPOpts =PPPOpts ->Text; - - MainForm->IntpRefObs =IntpRefObs ->ItemIndex; - MainForm->SbasSat =SbasSat ->Text.ToInt(); - MainForm->AntPcvFile =AntPcvFile ->Text; - MainForm->SatPcvFile =SatPcvFile ->Text; - MainForm->StaPosFile =StaPosFile ->Text; - MainForm->GeoidDataFile=GeoidDataFile->Text; - MainForm->EOPFile =EOPFile ->Text; - MainForm->DCBFile =DCBFile ->Text; - MainForm->BLQFile =BLQFile ->Text; - MainForm->IonoFile =IonoFile ->Text; - MainForm->RovPosType =RovPosType ->ItemIndex; - MainForm->RefPosType =RefPosType ->ItemIndex; - GetPos(RovPosType->ItemIndex,editu,MainForm->RovPos); - GetPos(RefPosType->ItemIndex,editr,MainForm->RefPos); - - MainForm->RovList =RovList ->Text; - MainForm->BaseList =BaseList ->Text; - - UpdateEnable(); +void __fastcall TOptDialog::SetOpt(void) { + TEdit *editu[] = {RovPos1, RovPos2, RovPos3}; + TEdit *editr[] = {RefPos1, RefPos2, RefPos3}; + + MainForm->PosMode = PosMode->ItemIndex; + MainForm->Freq = Freq->ItemIndex; + MainForm->Solution = Solution->ItemIndex; + MainForm->ElMask = str2dbl(ElMask->Text); + MainForm->SnrMask = SnrMask; + MainForm->DynamicModel = DynamicModel->ItemIndex; + MainForm->TideCorr = TideCorr->ItemIndex; + MainForm->IonoOpt = IonoOpt->ItemIndex; + MainForm->TropOpt = TropOpt->ItemIndex; + MainForm->SatEphem = SatEphem->ItemIndex; + MainForm->ExSats = ExSats->Text; + MainForm->NavSys = 0; + if (NavSys1->Checked) MainForm->NavSys |= SYS_GPS; + if (NavSys2->Checked) MainForm->NavSys |= SYS_GLO; + if (NavSys3->Checked) MainForm->NavSys |= SYS_GAL; + if (NavSys4->Checked) MainForm->NavSys |= SYS_QZS; + if (NavSys5->Checked) MainForm->NavSys |= SYS_SBS; + if (NavSys6->Checked) MainForm->NavSys |= SYS_CMP; + if (NavSys7->Checked) MainForm->NavSys |= SYS_IRN; + MainForm->PosOpt[0] = PosOpt1->Checked; + MainForm->PosOpt[1] = PosOpt2->Checked; + MainForm->PosOpt[2] = PosOpt3->Checked; + MainForm->PosOpt[3] = PosOpt4->Checked; + MainForm->PosOpt[4] = PosOpt5->Checked; + MainForm->PosOpt[5] = PosOpt6->Checked; + + MainForm->AmbRes = AmbRes->ItemIndex; + MainForm->GloAmbRes = GloAmbRes->ItemIndex; + MainForm->BdsAmbRes = BdsAmbRes->ItemIndex; + MainForm->ValidThresAR = str2dbl(ValidThresAR->Text); + MainForm->ValidThresARMin = str2dbl(ValidThresARMin->Text); + MainForm->ValidThresARMax = str2dbl(ValidThresARMax->Text); + MainForm->GloHwBias = str2dbl(GloHwBias->Text); + MainForm->OutCntResetAmb = OutCntResetAmb->Text.ToInt(); + MainForm->FixCntHoldAmb = FixCntHoldAmb->Text.ToInt(); + MainForm->OutCntResetAmb = OutCntResetAmb->Text.ToInt(); + MainForm->LockCntFixAmb = LockCntFixAmb->Text.ToInt(); + MainForm->ElMaskAR = ElMaskAR->Text.ToInt(); + MainForm->ElMaskHold = ElMaskHold->Text.ToInt(); + MainForm->MaxAgeDiff = str2dbl(MaxAgeDiff->Text); + MainForm->RejectCode = str2dbl(RejectCode->Text); + MainForm->RejectPhase = str2dbl(RejectPhase->Text); + MainForm->VarHoldAmb = str2dbl(VarHoldAmb->Text); + MainForm->GainHoldAmb = str2dbl(GainHoldAmb->Text); + MainForm->SlipThres = str2dbl(SlipThres->Text); + MainForm->DopThres = str2dbl(DopThres->Text); + MainForm->NumIter = NumIter->Text.ToInt(); + MainForm->MinFixSats = MinFixSats->Text.ToInt(); + MainForm->MinHoldSats = MinHoldSats->Text.ToInt(); + MainForm->MinDropSats = MinDropSats->Text.ToInt(); + MainForm->ARFilter = ARFilter->ItemIndex; + MainForm->MaxPosVarAR = str2dbl(MaxPosVarAR->Text); + MainForm->BaseLine[0] = str2dbl(BaselineLen->Text); + MainForm->BaseLine[1] = str2dbl(BaselineSig->Text); + MainForm->BaseLineConst = BaselineConst->Checked; + + MainForm->SolFormat = SolFormat->ItemIndex; + MainForm->TimeFormat = TimeFormat->ItemIndex; + MainForm->TimeDecimal = str2dbl(TimeDecimal->Text); + MainForm->LatLonFormat = LatLonFormat->ItemIndex; + MainForm->FieldSep = FieldSep->Text; + MainForm->OutputHead = OutputHead->ItemIndex; + MainForm->OutputOpt = OutputOpt->ItemIndex; + MainForm->OutputVel = OutputVel->ItemIndex; + MainForm->OutputSingle = OutputSingle->ItemIndex; + MainForm->MaxSolStd = str2dbl(MaxSolStd->Text); + MainForm->OutputDatum = OutputDatum->ItemIndex; + MainForm->OutputHeight = OutputHeight->ItemIndex; + MainForm->OutputGeoid = OutputGeoid->ItemIndex; + MainForm->SolStatic = SolStatic->ItemIndex; + MainForm->DebugTrace = DebugTrace->ItemIndex; + MainForm->DebugStatus = DebugStatus->ItemIndex; + + MainForm->MeasErrR1 = str2dbl(MeasErrR1->Text); + MainForm->MeasErrR2 = str2dbl(MeasErrR2->Text); + MainForm->MeasErrR5 = str2dbl(MeasErrR5->Text); + MainForm->MeasErrR6 = str2dbl(MeasErrR6->Text); + MainForm->MeasErr2 = str2dbl(MeasErr2->Text); + MainForm->MeasErr3 = str2dbl(MeasErr3->Text); + MainForm->MeasErr4 = str2dbl(MeasErr4->Text); + MainForm->MeasErr5 = str2dbl(MeasErr5->Text); + MainForm->MeasErr6 = str2dbl(MeasErr6->Text); + MainForm->MeasErr7 = str2dbl(MeasErr7->Text); + MainForm->MeasErr8 = str2dbl(MeasErr8->Text); + MainForm->SatClkStab = str2dbl(SatClkStab->Text); + MainForm->PrNoise1 = str2dbl(PrNoise1->Text); + MainForm->PrNoise2 = str2dbl(PrNoise2->Text); + MainForm->PrNoise3 = str2dbl(PrNoise3->Text); + MainForm->PrNoise4 = str2dbl(PrNoise4->Text); + MainForm->PrNoise5 = str2dbl(PrNoise5->Text); + + MainForm->RovAntPcv = RovAntPcv->Checked; + MainForm->RefAntPcv = RefAntPcv->Checked; + MainForm->RovAnt = RovAnt->Text; + MainForm->RefAnt = RefAnt->Text; + MainForm->RovAntE = str2dbl(RovAntE->Text); + MainForm->RovAntN = str2dbl(RovAntN->Text); + MainForm->RovAntU = str2dbl(RovAntU->Text); + MainForm->RefAntE = str2dbl(RefAntE->Text); + MainForm->RefAntN = str2dbl(RefAntN->Text); + MainForm->RefAntU = str2dbl(RefAntU->Text); + + MainForm->RnxOpts1 = RnxOpts1->Text; + MainForm->RnxOpts2 = RnxOpts2->Text; + MainForm->PPPOpts = PPPOpts->Text; + + MainForm->IntpRefObs = IntpRefObs->ItemIndex; + MainForm->SbasSat = SbasSat->Text.ToInt(); + MainForm->AntPcvFile = AntPcvFile->Text; + MainForm->SatPcvFile = SatPcvFile->Text; + MainForm->StaPosFile = StaPosFile->Text; + MainForm->GeoidDataFile = GeoidDataFile->Text; + MainForm->EOPFile = EOPFile->Text; + MainForm->DCBFile = DCBFile->Text; + MainForm->BLQFile = BLQFile->Text; + MainForm->IonoFile = IonoFile->Text; + MainForm->RovPosType = RovPosType->ItemIndex; + MainForm->RefPosType = RefPosType->ItemIndex; + GetPos(RovPosType->ItemIndex, editu, MainForm->RovPos); + GetPos(RefPosType->ItemIndex, editr, MainForm->RefPos); + + MainForm->RovList = RovList->Text; + MainForm->BaseList = BaseList->Text; + + UpdateEnable(); } //--------------------------------------------------------------------------- -void __fastcall TOptDialog::LoadOpt(AnsiString file) -{ +void __fastcall TOptDialog::LoadOpt(AnsiString file) { + int ppp = PosMode->ItemIndex >= PMODE_PPP_KINEMA; + + TEdit *editu[] = {RovPos1, RovPos2, RovPos3}; + TEdit *editr[] = {RefPos1, RefPos2, RefPos3}; + AnsiString s; + char buff[1024] = "", *p, id[8]; + int sat; + prcopt_t prcopt = prcopt_default; + solopt_t solopt = solopt_default; + filopt_t filopt = {""}; + + resetsysopts(); + if (!loadopts(file.c_str(), sysopts)) return; + getsysopts(&prcopt, &solopt, &filopt); + + PosMode->ItemIndex = prcopt.mode; + Freq->ItemIndex = prcopt.nf > NFREQ - 1 ? NFREQ - 1 : prcopt.nf - 1; + Solution->ItemIndex = prcopt.soltype; + ElMask->Text = s.sprintf("%.0f", prcopt.elmin * R2D); + SnrMask = prcopt.snrmask; + DynamicModel->ItemIndex = prcopt.dynamics; + TideCorr->ItemIndex = prcopt.tidecorr > 1 ? 2 : prcopt.tidecorr; + IonoOpt->ItemIndex = prcopt.ionoopt; + TropOpt->ItemIndex = prcopt.tropopt; + SatEphem->ItemIndex = prcopt.sateph; + ExSats->Text = ""; + for (sat = 1, p = buff; sat <= MAXSAT; sat++) { + if (!prcopt.exsats[sat - 1]) continue; + satno2id(sat, id); + p += sprintf(p, "%s%s%s", p == buff ? "" : " ", prcopt.exsats[sat - 1] == 2 ? "+" : "", id); + } + ExSats->Text = buff; + NavSys1->Checked = prcopt.navsys & SYS_GPS; + NavSys2->Checked = prcopt.navsys & SYS_GLO; + NavSys3->Checked = prcopt.navsys & SYS_GAL; + NavSys4->Checked = prcopt.navsys & SYS_QZS; + NavSys5->Checked = prcopt.navsys & SYS_SBS; + NavSys6->Checked = prcopt.navsys & SYS_CMP; + NavSys7->Checked = prcopt.navsys & SYS_IRN; + PosOpt1->Checked = prcopt.posopt[0]; + PosOpt2->Checked = prcopt.posopt[1]; + PosOpt3->Checked = prcopt.posopt[2]; + PosOpt4->Checked = prcopt.posopt[3]; + PosOpt5->Checked = prcopt.posopt[4]; + PosOpt6->Checked = prcopt.posopt[5]; + + AmbRes->ItemIndex = prcopt.modear; + GloAmbRes->ItemIndex = prcopt.glomodear; + BdsAmbRes->ItemIndex = prcopt.bdsmodear; + ValidThresAR->Text = s.sprintf("%.3g", prcopt.thresar[0]); + MaxPosVarAR->Text = s.sprintf("%.3g", prcopt.thresar[1]); + GloHwBias->Text = s.sprintf("%.3g", prcopt.thresar[2]); + ValidThresARMin->Text = s.sprintf("%.3g", prcopt.thresar[5]); + ValidThresARMax->Text = s.sprintf("%.3g", prcopt.thresar[6]); + OutCntResetAmb->Text = s.sprintf("%d", prcopt.maxout); + FixCntHoldAmb->Text = s.sprintf("%d", prcopt.minfix); + LockCntFixAmb->Text = s.sprintf("%d", prcopt.minlock); + ElMaskAR->Text = s.sprintf("%.0f", prcopt.elmaskar * R2D); + ElMaskHold->Text = s.sprintf("%.0f", prcopt.elmaskhold * R2D); + MaxAgeDiff->Text = s.sprintf("%.1f", prcopt.maxtdiff); + RejectCode->Text = s.sprintf("%.1f", prcopt.maxinno[1]); + RejectPhase->Text = s.sprintf("%.1f", prcopt.maxinno[0]); + VarHoldAmb->Text = s.sprintf("%.5f", prcopt.varholdamb); + GainHoldAmb->Text = s.sprintf("%.5f", prcopt.gainholdamb); + SlipThres->Text = s.sprintf("%.3f", prcopt.thresslip); + DopThres->Text = s.sprintf("%.3f", prcopt.thresdop); + // ARIter ->Text =s.sprintf("%d", prcopt.armaxiter); + MinFixSats->Text = s.sprintf("%d", prcopt.minfixsats); + MinHoldSats->Text = s.sprintf("%d", prcopt.minholdsats); + MinDropSats->Text = s.sprintf("%d", prcopt.mindropsats); + ARFilter->ItemIndex = prcopt.arfilter; + NumIter->Text = s.sprintf("%d", prcopt.niter); + BaselineLen->Text = s.sprintf("%.3f", prcopt.baseline[0]); + BaselineSig->Text = s.sprintf("%.3f", prcopt.baseline[1]); + BaselineConst->Checked = prcopt.baseline[0] > 0.0; - int ppp=PosMode->ItemIndex>=PMODE_PPP_KINEMA; + SolFormat->ItemIndex = solopt.posf; + TimeFormat->ItemIndex = solopt.timef == 0 ? 0 : solopt.times + 1; + TimeDecimal->Text = s.sprintf("%d", solopt.timeu); + LatLonFormat->ItemIndex = solopt.degf; + FieldSep->Text = solopt.sep; + OutputHead->ItemIndex = solopt.outhead; + OutputOpt->ItemIndex = solopt.outopt; + OutputVel->ItemIndex = solopt.outvel; + OutputSingle->ItemIndex = prcopt.outsingle; + MaxSolStd->Text = s.sprintf("%.2g", solopt.maxsolstd); + OutputDatum->ItemIndex = solopt.datum; + OutputHeight->ItemIndex = solopt.height; + OutputGeoid->ItemIndex = solopt.geoid; + SolStatic->ItemIndex = solopt.solstatic; + NmeaIntv1->Text = s.sprintf("%.2g", solopt.nmeaintv[0]); + NmeaIntv2->Text = s.sprintf("%.2g", solopt.nmeaintv[1]); + DebugTrace->ItemIndex = solopt.trace; + DebugStatus->ItemIndex = solopt.sstat; - TEdit *editu[]={RovPos1,RovPos2,RovPos3}; - TEdit *editr[]={RefPos1,RefPos2,RefPos3}; - AnsiString s; - char buff[1024]="",*p,id[8]; - int sat; - prcopt_t prcopt=prcopt_default; - solopt_t solopt=solopt_default; - filopt_t filopt={""}; - - resetsysopts(); - if (!loadopts(file.c_str(),sysopts)) return; - getsysopts(&prcopt,&solopt,&filopt); - - PosMode ->ItemIndex =prcopt.mode; - Freq ->ItemIndex =prcopt.nf>NFREQ-1?NFREQ-1:prcopt.nf-1; - Solution ->ItemIndex =prcopt.soltype; - ElMask ->Text =s.sprintf("%.0f",prcopt.elmin*R2D); - SnrMask =prcopt.snrmask; - DynamicModel ->ItemIndex =prcopt.dynamics; - TideCorr ->ItemIndex =prcopt.tidecorr > 1 ? 2 : prcopt.tidecorr; - IonoOpt ->ItemIndex =prcopt.ionoopt; - TropOpt ->ItemIndex =prcopt.tropopt; - SatEphem ->ItemIndex =prcopt.sateph; - ExSats ->Text =""; - for (sat=1,p=buff;sat<=MAXSAT;sat++) { - if (!prcopt.exsats[sat-1]) continue; - satno2id(sat,id); - p+=sprintf(p,"%s%s%s",p==buff?"":" ",prcopt.exsats[sat-1]==2?"+":"",id); - } - ExSats ->Text =buff; - NavSys1 ->Checked =prcopt.navsys&SYS_GPS; - NavSys2 ->Checked =prcopt.navsys&SYS_GLO; - NavSys3 ->Checked =prcopt.navsys&SYS_GAL; - NavSys4 ->Checked =prcopt.navsys&SYS_QZS; - NavSys5 ->Checked =prcopt.navsys&SYS_SBS; - NavSys6 ->Checked =prcopt.navsys&SYS_CMP; - NavSys7 ->Checked =prcopt.navsys&SYS_IRN; - PosOpt1 ->Checked =prcopt.posopt[0]; - PosOpt2 ->Checked =prcopt.posopt[1]; - PosOpt3 ->Checked =prcopt.posopt[2]; - PosOpt4 ->Checked =prcopt.posopt[3]; - PosOpt5 ->Checked =prcopt.posopt[4]; - PosOpt6 ->Checked =prcopt.posopt[5]; - - AmbRes ->ItemIndex =prcopt.modear; - GloAmbRes ->ItemIndex =prcopt.glomodear; - BdsAmbRes ->ItemIndex =prcopt.bdsmodear; - ValidThresAR ->Text =s.sprintf("%.3g",prcopt.thresar[0]); - MaxPosVarAR ->Text =s.sprintf("%.3g",prcopt.thresar[1]); - GloHwBias ->Text =s.sprintf("%.3g",prcopt.thresar[2]); - ValidThresARMin->Text =s.sprintf("%.3g",prcopt.thresar[5]); - ValidThresARMax->Text =s.sprintf("%.3g",prcopt.thresar[6]); - OutCntResetAmb->Text =s.sprintf("%d" ,prcopt.maxout ); - FixCntHoldAmb->Text =s.sprintf("%d" ,prcopt.minfix ); - LockCntFixAmb ->Text =s.sprintf("%d" ,prcopt.minlock ); - ElMaskAR ->Text =s.sprintf("%.0f",prcopt.elmaskar*R2D); - ElMaskHold ->Text =s.sprintf("%.0f",prcopt.elmaskhold*R2D); - MaxAgeDiff ->Text =s.sprintf("%.1f",prcopt.maxtdiff ); - RejectCode ->Text =s.sprintf("%.1f",prcopt.maxinno[1] ); - RejectPhase ->Text =s.sprintf("%.1f",prcopt.maxinno[0] ); - VarHoldAmb ->Text =s.sprintf("%.5f",prcopt.varholdamb); - GainHoldAmb ->Text =s.sprintf("%.5f",prcopt.gainholdamb); - SlipThres ->Text =s.sprintf("%.3f",prcopt.thresslip); - DopThres ->Text =s.sprintf("%.3f",prcopt.thresdop); - //ARIter ->Text =s.sprintf("%d", prcopt.armaxiter); - MinFixSats ->Text =s.sprintf("%d", prcopt.minfixsats); - MinHoldSats ->Text =s.sprintf("%d", prcopt.minholdsats); - MinDropSats ->Text =s.sprintf("%d", prcopt.mindropsats); - ARFilter ->ItemIndex =prcopt.arfilter; - NumIter ->Text =s.sprintf("%d", prcopt.niter ); - BaselineLen ->Text =s.sprintf("%.3f",prcopt.baseline[0]); - BaselineSig ->Text =s.sprintf("%.3f",prcopt.baseline[1]); - BaselineConst->Checked =prcopt.baseline[0]>0.0; - - SolFormat ->ItemIndex =solopt.posf; - TimeFormat ->ItemIndex =solopt.timef==0?0:solopt.times+1; - TimeDecimal ->Text =s.sprintf("%d",solopt.timeu); - LatLonFormat ->ItemIndex =solopt.degf; - FieldSep ->Text =solopt.sep; - OutputHead ->ItemIndex =solopt.outhead; - OutputOpt ->ItemIndex =solopt.outopt; - OutputVel ->ItemIndex =solopt.outvel; - OutputSingle ->ItemIndex =prcopt.outsingle; - MaxSolStd ->Text =s.sprintf("%.2g",solopt.maxsolstd); - OutputDatum ->ItemIndex =solopt.datum; - OutputHeight ->ItemIndex =solopt.height; - OutputGeoid ->ItemIndex =solopt.geoid; - SolStatic ->ItemIndex =solopt.solstatic; - NmeaIntv1 ->Text =s.sprintf("%.2g",solopt.nmeaintv[0]); - NmeaIntv2 ->Text =s.sprintf("%.2g",solopt.nmeaintv[1]); - DebugTrace ->ItemIndex =solopt.trace; - DebugStatus ->ItemIndex =solopt.sstat; - - MeasErrR1 ->Text =s.sprintf("%.1f",prcopt.eratio[0]); - MeasErrR2 ->Text =s.sprintf("%.1f",prcopt.eratio[1]); - MeasErrR5 ->Text =s.sprintf("%.1f",prcopt.eratio[2]); - MeasErrR6 ->Text =s.sprintf("%.1f",prcopt.eratio[3]); - MeasErr2 ->Text =s.sprintf("%.3f",prcopt.err[1]); - MeasErr3 ->Text =s.sprintf("%.3f",prcopt.err[2]); - MeasErr4 ->Text =s.sprintf("%.3f",prcopt.err[3]); - MeasErr5 ->Text =s.sprintf("%.3f",prcopt.err[4]); - MeasErr6 ->Text =s.sprintf("%.3f",prcopt.err[5]); - MeasErr7 ->Text =s.sprintf("%.3f",prcopt.err[6]); - MeasErr8 ->Text =s.sprintf("%.3f",prcopt.err[7]); - SatClkStab ->Text =s.sprintf("%.2E",prcopt.sclkstab); - PrNoise1 ->Text =s.sprintf("%.2E",prcopt.prn[0]); - PrNoise2 ->Text =s.sprintf("%.2E",prcopt.prn[1]); - PrNoise3 ->Text =s.sprintf("%.2E",prcopt.prn[2]); - PrNoise4 ->Text =s.sprintf("%.2E",prcopt.prn[3]); - PrNoise5 ->Text =s.sprintf("%.2E",prcopt.prn[4]); - - RovAntPcv ->Checked =*prcopt.anttype[0]; - RefAntPcv ->Checked =*prcopt.anttype[1]; - RovAnt ->Text =prcopt.anttype[0]; - RefAnt ->Text =prcopt.anttype[1]; - RovAntE ->Text =s.sprintf("%.4f",prcopt.antdel[0][0]); - RovAntN ->Text =s.sprintf("%.4f",prcopt.antdel[0][1]); - RovAntU ->Text =s.sprintf("%.4f",prcopt.antdel[0][2]); - RefAntE ->Text =s.sprintf("%.4f",prcopt.antdel[1][0]); - RefAntN ->Text =s.sprintf("%.4f",prcopt.antdel[1][1]); - RefAntU ->Text =s.sprintf("%.4f",prcopt.antdel[1][2]); - - RnxOpts1 ->Text =prcopt.rnxopt[0]; - RnxOpts2 ->Text =prcopt.rnxopt[1]; - PPPOpts ->Text =prcopt.pppopt; - - IntpRefObs ->ItemIndex =prcopt.intpref; - SbasSat ->Text =s.sprintf("%d",prcopt.sbassatsel); - RovPosType->ItemIndex = prcopt.rovpos == POSOPT_POS_LLH ? 0 : prcopt.rovpos == POSOPT_POS_XYZ ? 2 : prcopt.rovpos + 1; - RefPosType->ItemIndex = prcopt.refpos == POSOPT_POS_LLH ? 0 : prcopt.refpos == POSOPT_POS_XYZ ? 2 : prcopt.refpos + 1; - RovPosTypeP =RovPosType->ItemIndex; - RefPosTypeP =RefPosType->ItemIndex; - SetPos(RovPosType->ItemIndex,editu,prcopt.ru); - SetPos(RefPosType->ItemIndex,editr,prcopt.rb); - - SatPcvFile ->Text =filopt.satantp; - AntPcvFile ->Text =filopt.rcvantp; - StaPosFile ->Text =filopt.stapos; - GeoidDataFile->Text =filopt.geoid; - EOPFile ->Text =filopt.eop; - DCBFile ->Text =filopt.dcb; - BLQFile ->Text =filopt.blq; - IonoFile ->Text =filopt.iono; - - ReadAntList(); - UpdateEnable(); + MeasErrR1->Text = s.sprintf("%.1f", prcopt.eratio[0]); + MeasErrR2->Text = s.sprintf("%.1f", prcopt.eratio[1]); + MeasErrR5->Text = s.sprintf("%.1f", prcopt.eratio[2]); + MeasErrR6->Text = s.sprintf("%.1f", prcopt.eratio[3]); + MeasErr2->Text = s.sprintf("%.3f", prcopt.err[1]); + MeasErr3->Text = s.sprintf("%.3f", prcopt.err[2]); + MeasErr4->Text = s.sprintf("%.3f", prcopt.err[3]); + MeasErr5->Text = s.sprintf("%.3f", prcopt.err[4]); + MeasErr6->Text = s.sprintf("%.3f", prcopt.err[5]); + MeasErr7->Text = s.sprintf("%.3f", prcopt.err[6]); + MeasErr8->Text = s.sprintf("%.3f", prcopt.err[7]); + SatClkStab->Text = s.sprintf("%.2E", prcopt.sclkstab); + PrNoise1->Text = s.sprintf("%.2E", prcopt.prn[0]); + PrNoise2->Text = s.sprintf("%.2E", prcopt.prn[1]); + PrNoise3->Text = s.sprintf("%.2E", prcopt.prn[2]); + PrNoise4->Text = s.sprintf("%.2E", prcopt.prn[3]); + PrNoise5->Text = s.sprintf("%.2E", prcopt.prn[4]); + + RovAntPcv->Checked = *prcopt.anttype[0]; + RefAntPcv->Checked = *prcopt.anttype[1]; + RovAnt->Text = prcopt.anttype[0]; + RefAnt->Text = prcopt.anttype[1]; + RovAntE->Text = s.sprintf("%.4f", prcopt.antdel[0][0]); + RovAntN->Text = s.sprintf("%.4f", prcopt.antdel[0][1]); + RovAntU->Text = s.sprintf("%.4f", prcopt.antdel[0][2]); + RefAntE->Text = s.sprintf("%.4f", prcopt.antdel[1][0]); + RefAntN->Text = s.sprintf("%.4f", prcopt.antdel[1][1]); + RefAntU->Text = s.sprintf("%.4f", prcopt.antdel[1][2]); + + RnxOpts1->Text = prcopt.rnxopt[0]; + RnxOpts2->Text = prcopt.rnxopt[1]; + PPPOpts->Text = prcopt.pppopt; + + IntpRefObs->ItemIndex = prcopt.intpref; + SbasSat->Text = s.sprintf("%d", prcopt.sbassatsel); + RovPosType->ItemIndex = prcopt.rovpos == POSOPT_POS_LLH ? 0 + : prcopt.rovpos == POSOPT_POS_XYZ ? 2 + : prcopt.rovpos + 1; + RefPosType->ItemIndex = prcopt.refpos == POSOPT_POS_LLH ? 0 + : prcopt.refpos == POSOPT_POS_XYZ ? 2 + : prcopt.refpos + 1; + RovPosTypeP = RovPosType->ItemIndex; + RefPosTypeP = RefPosType->ItemIndex; + SetPos(RovPosType->ItemIndex, editu, prcopt.ru); + SetPos(RefPosType->ItemIndex, editr, prcopt.rb); + + SatPcvFile->Text = filopt.satantp; + AntPcvFile->Text = filopt.rcvantp; + StaPosFile->Text = filopt.stapos; + GeoidDataFile->Text = filopt.geoid; + EOPFile->Text = filopt.eop; + DCBFile->Text = filopt.dcb; + BLQFile->Text = filopt.blq; + IonoFile->Text = filopt.iono; + + ReadAntList(); + UpdateEnable(); } //--------------------------------------------------------------------------- -void __fastcall TOptDialog::SaveOpt(AnsiString file) -{ +void __fastcall TOptDialog::SaveOpt(AnsiString file) { + int ppp = PosMode->ItemIndex >= PMODE_PPP_KINEMA; + + AnsiString ExSats_Text = ExSats->Text, FieldSep_Text = FieldSep->Text; + AnsiString RovAnt_Text = RovAnt->Text, RefAnt_Text = RefAnt->Text; + AnsiString SatPcvFile_Text = SatPcvFile->Text; + AnsiString AntPcvFile_Text = AntPcvFile->Text; + AnsiString StaPosFile_Text = StaPosFile->Text; + AnsiString GeoidDataFile_Text = GeoidDataFile->Text; + AnsiString EOPFile_Text = EOPFile->Text; + AnsiString DCBFile_Text = DCBFile->Text; + AnsiString BLQFile_Text = BLQFile->Text; + AnsiString IonoFile_Text = IonoFile->Text; + AnsiString RnxOpts1_Text = RnxOpts1->Text; + AnsiString RnxOpts2_Text = RnxOpts2->Text; + AnsiString PPPOpts_Text = PPPOpts->Text; + TEdit *editu[] = {RovPos1, RovPos2, RovPos3}; + TEdit *editr[] = {RefPos1, RefPos2, RefPos3}; + char buff[1024], *p, id[32], comment[256], s[40]; + int sat, ex; + prcopt_t prcopt = prcopt_default; + solopt_t solopt = solopt_default; + filopt_t filopt = {""}; + + prcopt.mode = PosMode->ItemIndex; + prcopt.nf = Freq->ItemIndex + 1; + prcopt.soltype = Solution->ItemIndex; + prcopt.elmin = str2dbl(ElMask->Text) * D2R; + prcopt.snrmask = SnrMask; + prcopt.dynamics = DynamicModel->ItemIndex; + prcopt.tidecorr = TideCorr->ItemIndex; + if (prcopt.tidecorr > 1) prcopt.tidecorr = 7; + prcopt.ionoopt = IonoOpt->ItemIndex; + prcopt.tropopt = TropOpt->ItemIndex; + prcopt.sateph = SatEphem->ItemIndex; + if (ExSats->Text != "") { + strcpy(buff, ExSats_Text.c_str()); + for (p = strtok(buff, " "); p; p = strtok(NULL, " ")) { + if (*p == '+') { + ex = 2; + p++; + } else + ex = 1; + if (!(sat = satid2no(p))) continue; + prcopt.exsats[sat - 1] = ex; + } + } + prcopt.navsys = (NavSys1->Checked ? SYS_GPS : 0) | (NavSys2->Checked ? SYS_GLO : 0) | + (NavSys3->Checked ? SYS_GAL : 0) | (NavSys4->Checked ? SYS_QZS : 0) | + (NavSys5->Checked ? SYS_SBS : 0) | (NavSys6->Checked ? SYS_CMP : 0) | + (NavSys7->Checked ? SYS_IRN : 0); + prcopt.posopt[0] = PosOpt1->Checked; + prcopt.posopt[1] = PosOpt2->Checked; + prcopt.posopt[2] = PosOpt3->Checked; + prcopt.posopt[3] = PosOpt4->Checked; + prcopt.posopt[4] = PosOpt5->Checked; + prcopt.posopt[5] = PosOpt6->Checked; + // prcopt.mapfunc =MapFunc ->ItemIndex; + + prcopt.modear = AmbRes->ItemIndex; + prcopt.glomodear = GloAmbRes->ItemIndex; + prcopt.bdsmodear = BdsAmbRes->ItemIndex; + prcopt.thresar[0] = str2dbl(ValidThresAR->Text); + prcopt.thresar[1] = str2dbl(MaxPosVarAR->Text); + prcopt.thresar[2] = str2dbl(GloHwBias->Text); + prcopt.thresar[5] = str2dbl(ValidThresARMin->Text); + prcopt.thresar[6] = str2dbl(ValidThresARMax->Text); + prcopt.maxout = str2dbl(OutCntResetAmb->Text); + prcopt.minfix = str2dbl(FixCntHoldAmb->Text); + prcopt.minlock = str2dbl(LockCntFixAmb->Text); + prcopt.elmaskar = str2dbl(ElMaskAR->Text) * D2R; + prcopt.elmaskhold = str2dbl(ElMaskHold->Text) * D2R; + prcopt.maxtdiff = str2dbl(MaxAgeDiff->Text); + prcopt.maxinno[1] = str2dbl(RejectCode->Text); + prcopt.maxinno[0] = str2dbl(RejectPhase->Text); + prcopt.varholdamb = str2dbl(VarHoldAmb->Text); + prcopt.gainholdamb = str2dbl(GainHoldAmb->Text); + prcopt.thresslip = str2dbl(SlipThres->Text); + prcopt.thresdop = str2dbl(DopThres->Text); + // prcopt.armaxiter=str2dbl(ARIter ->Text); + prcopt.minfixsats = str2dbl(MinFixSats->Text); + prcopt.minholdsats = str2dbl(MinHoldSats->Text); + prcopt.mindropsats = str2dbl(MinDropSats->Text); + prcopt.arfilter = ARFilter->ItemIndex; + prcopt.niter = str2dbl(NumIter->Text); + if (BaselineConst->Checked) { + prcopt.baseline[0] = str2dbl(BaselineLen->Text); + prcopt.baseline[1] = str2dbl(BaselineSig->Text); + } + solopt.posf = SolFormat->ItemIndex; + solopt.timef = TimeFormat->ItemIndex == 0 ? 0 : 1; + solopt.times = TimeFormat->ItemIndex == 0 ? TIMES_GPST : (TimeFormat->ItemIndex - 1); + solopt.timeu = str2dbl(TimeDecimal->Text); + solopt.degf = LatLonFormat->ItemIndex; + strcpy(solopt.sep, FieldSep_Text.c_str()); + solopt.outhead = OutputHead->ItemIndex; + solopt.outopt = OutputOpt->ItemIndex; + solopt.outvel = OutputVel->ItemIndex; + prcopt.outsingle = OutputSingle->ItemIndex; + solopt.maxsolstd = str2dbl(MaxSolStd->Text); + solopt.datum = OutputDatum->ItemIndex; + solopt.height = OutputHeight->ItemIndex; + solopt.geoid = OutputGeoid->ItemIndex; + solopt.solstatic = SolStatic->ItemIndex; + solopt.nmeaintv[0] = str2dbl(NmeaIntv1->Text); + solopt.nmeaintv[1] = str2dbl(NmeaIntv2->Text); + solopt.trace = DebugTrace->ItemIndex; + solopt.sstat = DebugStatus->ItemIndex; + + prcopt.eratio[0] = str2dbl(MeasErrR1->Text); + prcopt.eratio[1] = str2dbl(MeasErrR2->Text); + prcopt.eratio[2] = str2dbl(MeasErrR5->Text); + prcopt.eratio[3] = str2dbl(MeasErrR6->Text); + prcopt.err[1] = str2dbl(MeasErr2->Text); + prcopt.err[2] = str2dbl(MeasErr3->Text); + prcopt.err[3] = str2dbl(MeasErr4->Text); + prcopt.err[4] = str2dbl(MeasErr5->Text); + prcopt.err[5] = str2dbl(MeasErr6->Text); + prcopt.err[6] = str2dbl(MeasErr7->Text); + prcopt.err[7] = str2dbl(MeasErr8->Text); + prcopt.sclkstab = str2dbl(SatClkStab->Text); + prcopt.prn[0] = str2dbl(PrNoise1->Text); + prcopt.prn[1] = str2dbl(PrNoise2->Text); + prcopt.prn[2] = str2dbl(PrNoise3->Text); + prcopt.prn[3] = str2dbl(PrNoise4->Text); + prcopt.prn[4] = str2dbl(PrNoise5->Text); + + if (RovAntPcv->Checked) strcpy(prcopt.anttype[0], RovAnt_Text.c_str()); + if (RefAntPcv->Checked) strcpy(prcopt.anttype[1], RefAnt_Text.c_str()); + prcopt.antdel[0][0] = str2dbl(RovAntE->Text); + prcopt.antdel[0][1] = str2dbl(RovAntN->Text); + prcopt.antdel[0][2] = str2dbl(RovAntU->Text); + prcopt.antdel[1][0] = str2dbl(RefAntE->Text); + prcopt.antdel[1][1] = str2dbl(RefAntN->Text); + prcopt.antdel[1][2] = str2dbl(RefAntU->Text); -int ppp=PosMode->ItemIndex>=PMODE_PPP_KINEMA; + prcopt.intpref = IntpRefObs->ItemIndex; + prcopt.sbassatsel = SbasSat->Text.ToInt(); + prcopt.rovpos = RovPosType->ItemIndex < 2 ? POSOPT_POS_LLH + : RovPosType->ItemIndex == 2 ? POSOPT_POS_XYZ + : (RovPosType->ItemIndex - 1); + prcopt.refpos = RefPosType->ItemIndex < 2 ? POSOPT_POS_LLH + : RefPosType->ItemIndex == 2 ? POSOPT_POS_XYZ + : (RefPosType->ItemIndex - 1); + if (prcopt.rovpos == POSOPT_POS_LLH || prcopt.rovpos == POSOPT_POS_XYZ) + GetPos(RovPosType->ItemIndex, editu, prcopt.ru); + if (prcopt.refpos == POSOPT_POS_LLH || prcopt.refpos == POSOPT_POS_XYZ) + GetPos(RefPosType->ItemIndex, editr, prcopt.rb); - AnsiString ExSats_Text=ExSats->Text,FieldSep_Text=FieldSep->Text; - AnsiString RovAnt_Text=RovAnt->Text,RefAnt_Text=RefAnt->Text; - AnsiString SatPcvFile_Text=SatPcvFile->Text; - AnsiString AntPcvFile_Text=AntPcvFile->Text; - AnsiString StaPosFile_Text=StaPosFile->Text; - AnsiString GeoidDataFile_Text=GeoidDataFile->Text; - AnsiString EOPFile_Text=EOPFile->Text; - AnsiString DCBFile_Text=DCBFile->Text; - AnsiString BLQFile_Text=BLQFile->Text; - AnsiString IonoFile_Text=IonoFile->Text; - AnsiString RnxOpts1_Text=RnxOpts1->Text; - AnsiString RnxOpts2_Text=RnxOpts2->Text; - AnsiString PPPOpts_Text=PPPOpts->Text; - TEdit *editu[]={RovPos1,RovPos2,RovPos3}; - TEdit *editr[]={RefPos1,RefPos2,RefPos3}; - char buff[1024],*p,id[32],comment[256],s[40]; - int sat,ex; - prcopt_t prcopt=prcopt_default; - solopt_t solopt=solopt_default; - filopt_t filopt={""}; - - prcopt.mode =PosMode ->ItemIndex; - prcopt.nf =Freq ->ItemIndex+1; - prcopt.soltype =Solution ->ItemIndex; - prcopt.elmin =str2dbl(ElMask ->Text)*D2R; - prcopt.snrmask =SnrMask; - prcopt.dynamics =DynamicModel->ItemIndex; - prcopt.tidecorr =TideCorr ->ItemIndex; - if (prcopt.tidecorr > 1) prcopt.tidecorr = 7; - prcopt.ionoopt =IonoOpt ->ItemIndex; - prcopt.tropopt =TropOpt ->ItemIndex; - prcopt.sateph =SatEphem ->ItemIndex; - if (ExSats->Text!="") { - strcpy(buff,ExSats_Text.c_str()); - for (p=strtok(buff," ");p;p=strtok(NULL," ")) { - if (*p=='+') {ex=2; p++;} else ex=1; - if (!(sat=satid2no(p))) continue; - prcopt.exsats[sat-1]=ex; - } - } - prcopt.navsys = (NavSys1->Checked?SYS_GPS:0)| - (NavSys2->Checked?SYS_GLO:0)| - (NavSys3->Checked?SYS_GAL:0)| - (NavSys4->Checked?SYS_QZS:0)| - (NavSys5->Checked?SYS_SBS:0)| - (NavSys6->Checked?SYS_CMP:0)| - (NavSys7->Checked?SYS_IRN:0); - prcopt.posopt[0]=PosOpt1 ->Checked; - prcopt.posopt[1]=PosOpt2 ->Checked; - prcopt.posopt[2]=PosOpt3 ->Checked; - prcopt.posopt[3]=PosOpt4 ->Checked; - prcopt.posopt[4]=PosOpt5 ->Checked; - prcopt.posopt[5]=PosOpt6 ->Checked; -// prcopt.mapfunc =MapFunc ->ItemIndex; - - prcopt.modear =AmbRes ->ItemIndex; - prcopt.glomodear=GloAmbRes ->ItemIndex; - prcopt.bdsmodear=BdsAmbRes ->ItemIndex; - prcopt.thresar[0]=str2dbl(ValidThresAR->Text); - prcopt.thresar[1]=str2dbl(MaxPosVarAR->Text); - prcopt.thresar[2]=str2dbl(GloHwBias->Text); - prcopt.thresar[5]=str2dbl(ValidThresARMin->Text); - prcopt.thresar[6]=str2dbl(ValidThresARMax->Text); - prcopt.maxout =str2dbl(OutCntResetAmb->Text); - prcopt.minfix =str2dbl(FixCntHoldAmb->Text); - prcopt.minlock =str2dbl(LockCntFixAmb->Text); - prcopt.elmaskar =str2dbl(ElMaskAR ->Text)*D2R; - prcopt.elmaskhold=str2dbl(ElMaskHold->Text)*D2R; - prcopt.maxtdiff =str2dbl(MaxAgeDiff ->Text); - prcopt.maxinno[1]=str2dbl(RejectCode ->Text); - prcopt.maxinno[0]=str2dbl(RejectPhase->Text); - prcopt.varholdamb=str2dbl(VarHoldAmb->Text); - prcopt.gainholdamb=str2dbl(GainHoldAmb->Text); - prcopt.thresslip=str2dbl(SlipThres ->Text); - prcopt.thresdop=str2dbl(DopThres ->Text); - //prcopt.armaxiter=str2dbl(ARIter ->Text); - prcopt.minfixsats=str2dbl(MinFixSats->Text); - prcopt.minholdsats=str2dbl(MinHoldSats->Text); - prcopt.mindropsats=str2dbl(MinDropSats->Text); - prcopt.arfilter =ARFilter->ItemIndex; - prcopt.niter =str2dbl(NumIter ->Text); - if (BaselineConst->Checked) { - prcopt.baseline[0]=str2dbl(BaselineLen->Text); - prcopt.baseline[1]=str2dbl(BaselineSig->Text); - } - solopt.posf =SolFormat ->ItemIndex; - solopt.timef =TimeFormat ->ItemIndex==0?0:1; - solopt.times =TimeFormat ->ItemIndex==0?TIMES_GPST:(TimeFormat->ItemIndex - 1); - solopt.timeu =str2dbl(TimeDecimal ->Text); - solopt.degf =LatLonFormat->ItemIndex; - strcpy(solopt.sep,FieldSep_Text.c_str()); - solopt.outhead =OutputHead ->ItemIndex; - solopt.outopt =OutputOpt ->ItemIndex; - solopt.outvel =OutputVel ->ItemIndex; - prcopt.outsingle=OutputSingle->ItemIndex; - solopt.maxsolstd=str2dbl(MaxSolStd->Text); - solopt.datum =OutputDatum ->ItemIndex; - solopt.height =OutputHeight->ItemIndex; - solopt.geoid =OutputGeoid ->ItemIndex; - solopt.solstatic=SolStatic ->ItemIndex; - solopt.nmeaintv[0]=str2dbl(NmeaIntv1->Text); - solopt.nmeaintv[1]=str2dbl(NmeaIntv2->Text); - solopt.trace =DebugTrace ->ItemIndex; - solopt.sstat =DebugStatus ->ItemIndex; - - prcopt.eratio[0]=str2dbl(MeasErrR1->Text); - prcopt.eratio[1]=str2dbl(MeasErrR2->Text); - prcopt.eratio[2]=str2dbl(MeasErrR5->Text); - prcopt.eratio[3]=str2dbl(MeasErrR6->Text); - prcopt.err[1] =str2dbl(MeasErr2->Text); - prcopt.err[2] =str2dbl(MeasErr3->Text); - prcopt.err[3] =str2dbl(MeasErr4->Text); - prcopt.err[4] =str2dbl(MeasErr5->Text); - prcopt.err[5] =str2dbl(MeasErr6->Text); - prcopt.err[6] =str2dbl(MeasErr7->Text); - prcopt.err[7] =str2dbl(MeasErr8->Text); - prcopt.sclkstab =str2dbl(SatClkStab->Text); - prcopt.prn[0] =str2dbl(PrNoise1->Text); - prcopt.prn[1] =str2dbl(PrNoise2->Text); - prcopt.prn[2] =str2dbl(PrNoise3->Text); - prcopt.prn[3] =str2dbl(PrNoise4->Text); - prcopt.prn[4] =str2dbl(PrNoise5->Text); - - if (RovAntPcv->Checked) strcpy(prcopt.anttype[0],RovAnt_Text.c_str()); - if (RefAntPcv->Checked) strcpy(prcopt.anttype[1],RefAnt_Text.c_str()); - prcopt.antdel[0][0]=str2dbl(RovAntE->Text); - prcopt.antdel[0][1]=str2dbl(RovAntN->Text); - prcopt.antdel[0][2]=str2dbl(RovAntU->Text); - prcopt.antdel[1][0]=str2dbl(RefAntE->Text); - prcopt.antdel[1][1]=str2dbl(RefAntN->Text); - prcopt.antdel[1][2]=str2dbl(RefAntU->Text); - - prcopt.intpref =IntpRefObs->ItemIndex; - prcopt.sbassatsel=SbasSat->Text.ToInt(); - prcopt.rovpos = RovPosType->ItemIndex < 2 ? POSOPT_POS_LLH : RovPosType->ItemIndex == 2 ? POSOPT_POS_XYZ : (RovPosType->ItemIndex - 1); - prcopt.refpos = RefPosType->ItemIndex < 2 ? POSOPT_POS_LLH : RefPosType->ItemIndex == 2 ? POSOPT_POS_XYZ : (RefPosType->ItemIndex - 1); - if (prcopt.rovpos == POSOPT_POS_LLH || prcopt.rovpos == POSOPT_POS_XYZ) - GetPos(RovPosType->ItemIndex, editu, prcopt.ru); - if (prcopt.refpos == POSOPT_POS_LLH || prcopt.refpos == POSOPT_POS_XYZ) - GetPos(RefPosType->ItemIndex, editr, prcopt.rb); - - strcpy(prcopt.rnxopt[0],RnxOpts1_Text.c_str()); - strcpy(prcopt.rnxopt[1],RnxOpts2_Text.c_str()); - strcpy(prcopt.pppopt,PPPOpts_Text.c_str()); - - strcpy(filopt.satantp,SatPcvFile_Text.c_str()); - strcpy(filopt.rcvantp,AntPcvFile_Text.c_str()); - strcpy(filopt.stapos, StaPosFile_Text.c_str()); - strcpy(filopt.geoid, GeoidDataFile_Text.c_str()); - strcpy(filopt.eop, EOPFile_Text.c_str()); - strcpy(filopt.dcb, DCBFile_Text.c_str()); - strcpy(filopt.blq, BLQFile_Text.c_str()); - strcpy(filopt.iono, IonoFile_Text.c_str()); - - time2str(utc2gpst(timeget()),s,0); - sprintf(comment,"rtkpost options (%s-%s %s)",s,VER_RTKLIB,PATCH_LEVEL); - setsysopts(&prcopt,&solopt,&filopt); - if (!saveopts(file.c_str(),"w",comment,sysopts)) return; + strcpy(prcopt.rnxopt[0], RnxOpts1_Text.c_str()); + strcpy(prcopt.rnxopt[1], RnxOpts2_Text.c_str()); + strcpy(prcopt.pppopt, PPPOpts_Text.c_str()); + + strcpy(filopt.satantp, SatPcvFile_Text.c_str()); + strcpy(filopt.rcvantp, AntPcvFile_Text.c_str()); + strcpy(filopt.stapos, StaPosFile_Text.c_str()); + strcpy(filopt.geoid, GeoidDataFile_Text.c_str()); + strcpy(filopt.eop, EOPFile_Text.c_str()); + strcpy(filopt.dcb, DCBFile_Text.c_str()); + strcpy(filopt.blq, BLQFile_Text.c_str()); + strcpy(filopt.iono, IonoFile_Text.c_str()); + + time2str(utc2gpst(timeget()), s, 0); + sprintf(comment, "rtkpost options (%s-%s %s)", s, VER_RTKLIB, PATCH_LEVEL); + setsysopts(&prcopt, &solopt, &filopt); + if (!saveopts(file.c_str(), "w", comment, sysopts)) return; } //--------------------------------------------------------------------------- -void __fastcall TOptDialog::UpdateEnable(void) -{ - int rel=PMODE_DGPS<=PosMode->ItemIndex&&PosMode->ItemIndex<=PMODE_FIXED; - int rtk=PMODE_KINEMA<=PosMode->ItemIndex&&PosMode->ItemIndex<=PMODE_FIXED; - int ppp=PosMode->ItemIndex>=PMODE_PPP_KINEMA; - int ar=rtk||ppp; - - Freq ->Enabled=rel||ppp; - Solution ->Enabled=rel||ppp; - DynamicModel ->Enabled=PosMode->ItemIndex==PMODE_KINEMA|| - PosMode->ItemIndex==PMODE_PPP_KINEMA; - TideCorr ->Enabled=rel||ppp; - //IonoOpt ->Enabled=!ppp; - PosOpt1 ->Enabled=rel||ppp; - PosOpt2 ->Enabled=rel||ppp; - PosOpt3 ->Enabled=ppp; - PosOpt4 ->Enabled=ppp; - PosOpt6 ->Enabled=ppp; +void __fastcall TOptDialog::UpdateEnable(void) { + int rel = PMODE_DGPS <= PosMode->ItemIndex && PosMode->ItemIndex <= PMODE_FIXED; + int rtk = PMODE_KINEMA <= PosMode->ItemIndex && PosMode->ItemIndex <= PMODE_FIXED; + int ppp = PosMode->ItemIndex >= PMODE_PPP_KINEMA; + int ar = rtk || ppp; + + Freq->Enabled = rel || ppp; + Solution->Enabled = rel || ppp; + DynamicModel->Enabled = + PosMode->ItemIndex == PMODE_KINEMA || PosMode->ItemIndex == PMODE_PPP_KINEMA; + TideCorr->Enabled = rel || ppp; + // IonoOpt ->Enabled=!ppp; + PosOpt1->Enabled = rel || ppp; + PosOpt2->Enabled = rel || ppp; + PosOpt3->Enabled = ppp; + PosOpt4->Enabled = ppp; + PosOpt6->Enabled = ppp; + + AmbRes->Enabled = ar; + GloAmbRes->Enabled = ar && AmbRes->ItemIndex > 0 && NavSys2->Checked; + BdsAmbRes->Enabled = ar && AmbRes->ItemIndex > 0 && NavSys6->Checked; + ValidThresAR->Enabled = ar && AmbRes->ItemIndex >= 1 && AmbRes->ItemIndex < 4; + ValidThresARMin->Enabled = ar && AmbRes->ItemIndex >= 1 && AmbRes->ItemIndex < 4; + ValidThresARMax->Enabled = ar && AmbRes->ItemIndex >= 1 && AmbRes->ItemIndex < 4; + GloHwBias->Enabled = ar && GloAmbRes->ItemIndex == 2; + LockCntFixAmb->Enabled = ar && AmbRes->ItemIndex >= 1; + ElMaskAR->Enabled = ar && AmbRes->ItemIndex >= 1; + OutCntResetAmb->Enabled = ar || ppp; + FixCntHoldAmb->Enabled = ar && AmbRes->ItemIndex == 3; + ElMaskHold->Enabled = ar && AmbRes->ItemIndex == 3; + SlipThres->Enabled = rtk || ppp; + DopThres->Enabled = rtk || ppp; + MaxAgeDiff->Enabled = rel; + RejectPhase->Enabled = rel || ppp; + RejectCode->Enabled = rel || ppp; + VarHoldAmb->Enabled = ar; + GainHoldAmb->Enabled = ar && AmbRes->ItemIndex == 3; + // ARIter ->Enabled=ppp; + // MeasErr5 ->Enabled= 0; + NumIter->Enabled = rel || ppp; + MinFixSats->Enabled = ar; + MinHoldSats->Enabled = ar; + MinDropSats->Enabled = rel; + MaxPosVarAR->Enabled = ar && !ppp; + ARFilter->Enabled = ar; + BaselineConst->Enabled = rel; + BaselineLen->Enabled = BaselineConst->Checked; + BaselineSig->Enabled = BaselineConst->Checked; + + OutputHead->Enabled = SolFormat->ItemIndex < 3; + OutputOpt->Enabled = SolFormat->ItemIndex < 3; + TimeFormat->Enabled = SolFormat->ItemIndex < 3; + TimeDecimal->Enabled = SolFormat->ItemIndex < 3; + LatLonFormat->Enabled = SolFormat->ItemIndex == 0; + FieldSep->Enabled = SolFormat->ItemIndex < 3; + OutputSingle->Enabled = PosMode->ItemIndex != 0; + OutputDatum->Enabled = SolFormat->ItemIndex == 0; + OutputHeight->Enabled = SolFormat->ItemIndex == 0; + OutputGeoid->Enabled = SolFormat->ItemIndex == 0 && OutputHeight->ItemIndex == 1; + SolStatic->Enabled = PosMode->ItemIndex == PMODE_STATIC || PosMode->ItemIndex == PMODE_PPP_STATIC; + + // For rtkpost, and when setting the antenna and delta automatically, + // this should occur before processing, so disable the delta setting + // here in that case. + RovAntPcv->Enabled = rel || ppp; + RovAnt->Enabled = (rel || ppp) && RovAntPcv->Checked; + int rovp = !RovAntPcv->Checked || RovAnt->Text != "*"; + RovAntE->Enabled = (rel || ppp) && rovp; + RovAntN->Enabled = (rel || ppp) && rovp; + RovAntU->Enabled = (rel || ppp) && rovp; + LabelRovAntD->Enabled = (rel || ppp) && rovp; + RefAntPcv->Enabled = rel; + RefAnt->Enabled = rel && RefAntPcv->Checked; + int refp = !RefAntPcv->Checked || RefAnt->Text != "*"; + RefAntE->Enabled = rel && refp; + RefAntN->Enabled = rel && refp; + RefAntU->Enabled = rel && refp; + LabelRefAntD->Enabled = rel && refp; - AmbRes ->Enabled=ar; - GloAmbRes ->Enabled=ar&&AmbRes->ItemIndex>0&&NavSys2->Checked; - BdsAmbRes ->Enabled=ar&&AmbRes->ItemIndex>0&&NavSys6->Checked; - ValidThresAR ->Enabled=ar&&AmbRes->ItemIndex>=1&&AmbRes->ItemIndex<4; - ValidThresARMin->Enabled=ar&&AmbRes->ItemIndex>=1&&AmbRes->ItemIndex<4; - ValidThresARMax->Enabled=ar&&AmbRes->ItemIndex>=1&&AmbRes->ItemIndex<4; - GloHwBias ->Enabled=ar&&GloAmbRes->ItemIndex==2; - LockCntFixAmb ->Enabled=ar&&AmbRes->ItemIndex>=1; - ElMaskAR ->Enabled=ar&&AmbRes->ItemIndex>=1; - OutCntResetAmb ->Enabled=ar||ppp; - FixCntHoldAmb ->Enabled=ar&&AmbRes->ItemIndex==3; - ElMaskHold ->Enabled=ar&&AmbRes->ItemIndex==3; - SlipThres ->Enabled=rtk||ppp; - DopThres ->Enabled=rtk||ppp; - MaxAgeDiff ->Enabled=rel; - RejectPhase ->Enabled=rel||ppp; - RejectCode ->Enabled=rel||ppp; - VarHoldAmb ->Enabled=ar; - GainHoldAmb ->Enabled=ar&&AmbRes->ItemIndex==3; - //ARIter ->Enabled=ppp; - //MeasErr5 ->Enabled= 0; - NumIter ->Enabled=rel||ppp; - MinFixSats ->Enabled=ar; - MinHoldSats ->Enabled=ar; - MinDropSats ->Enabled=rel; - MaxPosVarAR ->Enabled=ar&&!ppp; - ARFilter ->Enabled=ar; - BaselineConst ->Enabled=rel; - BaselineLen ->Enabled=BaselineConst->Checked; - BaselineSig ->Enabled=BaselineConst->Checked; - - OutputHead ->Enabled=SolFormat->ItemIndex<3; - OutputOpt ->Enabled=SolFormat->ItemIndex<3; - TimeFormat ->Enabled=SolFormat->ItemIndex<3; - TimeDecimal ->Enabled=SolFormat->ItemIndex<3; - LatLonFormat ->Enabled=SolFormat->ItemIndex==0; - FieldSep ->Enabled=SolFormat->ItemIndex<3; - OutputSingle ->Enabled=PosMode->ItemIndex!=0; - OutputDatum ->Enabled=SolFormat->ItemIndex==0; - OutputHeight ->Enabled=SolFormat->ItemIndex==0; - OutputGeoid ->Enabled=SolFormat->ItemIndex==0&&OutputHeight->ItemIndex==1; - SolStatic ->Enabled=PosMode->ItemIndex==PMODE_STATIC|| - PosMode ->ItemIndex==PMODE_PPP_STATIC; - - // For rtkpost, and when setting the antenna and delta automatically, - // this should occur before processing, so disable the delta setting - // here in that case. - RovAntPcv ->Enabled=rel||ppp; - RovAnt ->Enabled=(rel||ppp)&&RovAntPcv->Checked; - int rovp = !RovAntPcv->Checked || RovAnt->Text != "*"; - RovAntE ->Enabled=(rel||ppp)&&rovp; - RovAntN ->Enabled=(rel||ppp)&&rovp; - RovAntU ->Enabled=(rel||ppp)&&rovp; - LabelRovAntD ->Enabled=(rel||ppp)&&rovp; - RefAntPcv ->Enabled=rel; - RefAnt ->Enabled=rel&&RefAntPcv->Checked; - int refp = !RefAntPcv->Checked || RefAnt->Text != "*"; - RefAntE ->Enabled=rel&&refp; - RefAntN ->Enabled=rel&&refp; - RefAntU ->Enabled=rel&&refp; - LabelRefAntD ->Enabled=rel&&refp; - - RovPosType ->Enabled=PosMode->ItemIndex==PMODE_FIXED||PosMode->ItemIndex==PMODE_PPP_FIXED; - RovPos1 ->Enabled=RovPosType->Enabled&&RovPosType->ItemIndex<=2; - RovPos2 ->Enabled=RovPosType->Enabled&&RovPosType->ItemIndex<=2; - RovPos3 ->Enabled=RovPosType->Enabled&&RovPosType->ItemIndex<=2; - BtnRovPos ->Enabled=RovPosType->Enabled&&RovPosType->ItemIndex<=2; - - RefPosType ->Enabled=rel&&PosMode->ItemIndex!=PMODE_MOVEB; - RefPos1 ->Enabled=RefPosType->Enabled&&RefPosType->ItemIndex<=2; - RefPos2 ->Enabled=RefPosType->Enabled&&RefPosType->ItemIndex<=2; - RefPos3 ->Enabled=RefPosType->Enabled&&RefPosType->ItemIndex<=2; - BtnRefPos ->Enabled=RefPosType->Enabled&&RefPosType->ItemIndex<=2; + RovPosType->Enabled = PosMode->ItemIndex == PMODE_FIXED || PosMode->ItemIndex == PMODE_PPP_FIXED; + RovPos1->Enabled = RovPosType->Enabled && RovPosType->ItemIndex <= 2; + RovPos2->Enabled = RovPosType->Enabled && RovPosType->ItemIndex <= 2; + RovPos3->Enabled = RovPosType->Enabled && RovPosType->ItemIndex <= 2; + BtnRovPos->Enabled = RovPosType->Enabled && RovPosType->ItemIndex <= 2; + + RefPosType->Enabled = rel && PosMode->ItemIndex != PMODE_MOVEB; + RefPos1->Enabled = RefPosType->Enabled && RefPosType->ItemIndex <= 2; + RefPos2->Enabled = RefPosType->Enabled && RefPosType->ItemIndex <= 2; + RefPos3->Enabled = RefPosType->Enabled && RefPosType->ItemIndex <= 2; + BtnRefPos->Enabled = RefPosType->Enabled && RefPosType->ItemIndex <= 2; } //--------------------------------------------------------------------------- -void __fastcall TOptDialog::GetPos(int type, TEdit **edit, double *pos) -{ - AnsiString edit0_Text=edit[0]->Text; - AnsiString edit1_Text=edit[1]->Text; - double p[3]={0},dms1[3]={0},dms2[3]={0}; - - if (type==1) { /* lat/lon/height dms/m */ - sscanf(edit0_Text.c_str(),"%lf %lf %lf",dms1,dms1+1,dms1+2); - sscanf(edit1_Text.c_str(),"%lf %lf %lf",dms2,dms2+1,dms2+2); - p[0]=(dms1[0]<0?-1:1)*(fabs(dms1[0])+dms1[1]/60+dms1[2]/3600)*D2R; - p[1]=(dms2[0]<0?-1:1)*(fabs(dms2[0])+dms2[1]/60+dms2[2]/3600)*D2R; - p[2]=str2dbl(edit[2]->Text); - pos2ecef(p,pos); - } - else if (type==2) { /* x/y/z-ecef */ - pos[0]=str2dbl(edit[0]->Text); - pos[1]=str2dbl(edit[1]->Text); - pos[2]=str2dbl(edit[2]->Text); - } - else { - p[0]=str2dbl(edit[0]->Text)*D2R; - p[1]=str2dbl(edit[1]->Text)*D2R; - p[2]=str2dbl(edit[2]->Text); - pos2ecef(p,pos); - } +void __fastcall TOptDialog::GetPos(int type, TEdit **edit, double *pos) { + AnsiString edit0_Text = edit[0]->Text; + AnsiString edit1_Text = edit[1]->Text; + double p[3] = {0}, dms1[3] = {0}, dms2[3] = {0}; + + if (type == 1) { /* lat/lon/height dms/m */ + sscanf(edit0_Text.c_str(), "%lf %lf %lf", dms1, dms1 + 1, dms1 + 2); + sscanf(edit1_Text.c_str(), "%lf %lf %lf", dms2, dms2 + 1, dms2 + 2); + p[0] = (dms1[0] < 0 ? -1 : 1) * (fabs(dms1[0]) + dms1[1] / 60 + dms1[2] / 3600) * D2R; + p[1] = (dms2[0] < 0 ? -1 : 1) * (fabs(dms2[0]) + dms2[1] / 60 + dms2[2] / 3600) * D2R; + p[2] = str2dbl(edit[2]->Text); + pos2ecef(p, pos); + } else if (type == 2) { /* x/y/z-ecef */ + pos[0] = str2dbl(edit[0]->Text); + pos[1] = str2dbl(edit[1]->Text); + pos[2] = str2dbl(edit[2]->Text); + } else { + p[0] = str2dbl(edit[0]->Text) * D2R; + p[1] = str2dbl(edit[1]->Text) * D2R; + p[2] = str2dbl(edit[2]->Text); + pos2ecef(p, pos); + } } //--------------------------------------------------------------------------- -void __fastcall TOptDialog::SetPos(int type, TEdit **edit, double *pos) -{ - AnsiString s; - double p[3],dms1[3],dms2[3],s1,s2; - - if (type==1) { /* lat/lon/height dms/m */ - ecef2pos(pos,p); s1=p[0]<0?-1:1; s2=p[1]<0?-1:1; - p[0]=fabs(p[0])*R2D+1E-12; p[1]=fabs(p[1])*R2D+1E-12; - dms1[0]=floor(p[0]); p[0]=(p[0]-dms1[0])*60.0; - dms1[1]=floor(p[0]); dms1[2]=(p[0]-dms1[1])*60.0; - dms2[0]=floor(p[1]); p[1]=(p[1]-dms2[0])*60.0; - dms2[1]=floor(p[1]); dms2[2]=(p[1]-dms2[1])*60.0; - edit[0]->Text=s.sprintf("%.0f %02.0f %09.6f",s1*dms1[0],dms1[1],dms1[2]); - edit[1]->Text=s.sprintf("%.0f %02.0f %09.6f",s2*dms2[0],dms2[1],dms2[2]); - edit[2]->Text=s.sprintf("%.4f",p[2]); - } - else if (type==2) { /* x/y/z-ecef */ - edit[0]->Text=s.sprintf("%.4f",pos[0]); - edit[1]->Text=s.sprintf("%.4f",pos[1]); - edit[2]->Text=s.sprintf("%.4f",pos[2]); - } - else { - ecef2pos(pos,p); - edit[0]->Text=s.sprintf("%.9f",p[0]*R2D); - edit[1]->Text=s.sprintf("%.9f",p[1]*R2D); - edit[2]->Text=s.sprintf("%.4f",p[2]); - } +void __fastcall TOptDialog::SetPos(int type, TEdit **edit, double *pos) { + AnsiString s; + double p[3], dms1[3], dms2[3], s1, s2; + + if (type == 1) { /* lat/lon/height dms/m */ + ecef2pos(pos, p); + s1 = p[0] < 0 ? -1 : 1; + s2 = p[1] < 0 ? -1 : 1; + p[0] = fabs(p[0]) * R2D + 1E-12; + p[1] = fabs(p[1]) * R2D + 1E-12; + dms1[0] = floor(p[0]); + p[0] = (p[0] - dms1[0]) * 60.0; + dms1[1] = floor(p[0]); + dms1[2] = (p[0] - dms1[1]) * 60.0; + dms2[0] = floor(p[1]); + p[1] = (p[1] - dms2[0]) * 60.0; + dms2[1] = floor(p[1]); + dms2[2] = (p[1] - dms2[1]) * 60.0; + edit[0]->Text = s.sprintf("%.0f %02.0f %09.6f", s1 * dms1[0], dms1[1], dms1[2]); + edit[1]->Text = s.sprintf("%.0f %02.0f %09.6f", s2 * dms2[0], dms2[1], dms2[2]); + edit[2]->Text = s.sprintf("%.4f", p[2]); + } else if (type == 2) { /* x/y/z-ecef */ + edit[0]->Text = s.sprintf("%.4f", pos[0]); + edit[1]->Text = s.sprintf("%.4f", pos[1]); + edit[2]->Text = s.sprintf("%.4f", pos[2]); + } else { + ecef2pos(pos, p); + edit[0]->Text = s.sprintf("%.9f", p[0] * R2D); + edit[1]->Text = s.sprintf("%.9f", p[1] * R2D); + edit[2]->Text = s.sprintf("%.4f", p[2]); + } } //--------------------------------------------------------------------------- -void __fastcall TOptDialog::ReadAntList(void) -{ - AnsiString AntPcvFile_Text=AntPcvFile->Text; - TStringList *list; - pcvs_t pcvs={0}; - char *p; - - list=new TStringList; - list->Add(""); - list->Add("*"); - - if (readpcv(AntPcvFile_Text.c_str(),&pcvs)) { - for (int i=0;i0&&!strcmp(pcvs.pcv[i].type,pcvs.pcv[i-1].type)) continue; - list->Add(pcvs.pcv[i].type); - } - free_pcvs(&pcvs); - } - RovAnt->Items=list; - RefAnt->Items=list; +void __fastcall TOptDialog::ReadAntList(void) { + AnsiString AntPcvFile_Text = AntPcvFile->Text; + TStringList *list; + pcvs_t pcvs = {0}; + char *p; + + list = new TStringList; + list->Add(""); + list->Add("*"); + + if (readpcv(AntPcvFile_Text.c_str(), &pcvs)) { + for (int i = 0; i < pcvs.n; i++) { + if (pcvs.pcv[i].sat) continue; + if ((p = strchr(pcvs.pcv[i].type, ' '))) *p = '\0'; + if (i > 0 && !strcmp(pcvs.pcv[i].type, pcvs.pcv[i - 1].type)) continue; + list->Add(pcvs.pcv[i].type); + } + free_pcvs(&pcvs); + } + RovAnt->Items = list; + RefAnt->Items = list; } //--------------------------------------------------------------------------- -void __fastcall TOptDialog::BtnHelpClick(TObject *Sender) -{ - KeyDialog->Flag=2; - KeyDialog->Show(); +void __fastcall TOptDialog::BtnHelpClick(TObject *Sender) { + KeyDialog->Flag = 2; + KeyDialog->Show(); } //--------------------------------------------------------------------------- -void __fastcall TOptDialog::ExtEna0Click(TObject *Sender) -{ - UpdateEnable(); -} +void __fastcall TOptDialog::ExtEna0Click(TObject *Sender) { UpdateEnable(); } //--------------------------------------------------------------------------- -void __fastcall TOptDialog::ExtEna1Click(TObject *Sender) -{ - UpdateEnable(); -} +void __fastcall TOptDialog::ExtEna1Click(TObject *Sender) { UpdateEnable(); } //--------------------------------------------------------------------------- -void __fastcall TOptDialog::ExtEna2Click(TObject *Sender) -{ - UpdateEnable(); -} +void __fastcall TOptDialog::ExtEna2Click(TObject *Sender) { UpdateEnable(); } //--------------------------------------------------------------------------- -void __fastcall TOptDialog::BtnSnrMaskClick(TObject *Sender) -{ - MaskOptDialog->Mask=SnrMask; - if (MaskOptDialog->ShowModal()!=mrOk) return; - SnrMask=MaskOptDialog->Mask; +void __fastcall TOptDialog::BtnSnrMaskClick(TObject *Sender) { + MaskOptDialog->Mask = SnrMask; + if (MaskOptDialog->ShowModal() != mrOk) return; + SnrMask = MaskOptDialog->Mask; } //--------------------------------------------------------------------------- -void __fastcall TOptDialog::NavSys6Click(TObject *Sender) -{ - UpdateEnable(); -} +void __fastcall TOptDialog::NavSys6Click(TObject *Sender) { UpdateEnable(); } //--------------------------------------------------------------------------- -void __fastcall TOptDialog::BtnFreqClick(TObject *Sender) -{ - FreqDialog->ShowModal(); -} +void __fastcall TOptDialog::BtnFreqClick(TObject *Sender) { FreqDialog->ShowModal(); } //--------------------------------------------------------------------------- - - - - diff --git a/app/winapp/rtkpost/postopt.h b/app/winapp/rtkpost/postopt.h index 8aecde250..bc363ad1e 100644 --- a/app/winapp/rtkpost/postopt.h +++ b/app/winapp/rtkpost/postopt.h @@ -2,308 +2,307 @@ #ifndef postoptH #define postoptH //--------------------------------------------------------------------------- +#include #include +#include #include -#include -#include -#include #include -#include -#include +#include +#include +#include + #include "rtklib.h" //--------------------------------------------------------------------------- -class TOptDialog : public TForm -{ -__published: - TButton *BtnCancel; - TButton *BtnOk; - TOpenDialog *OpenDialog; - TButton *BtnSave; - TButton *BtnLoad; - TSaveDialog *SaveDialog; - TPageControl *Misc; - TTabSheet *TabSheet1; - TLabel *Label3; - TLabel *Label8; - TLabel *LabelPosMode; - TLabel *Label5; - TLabel *LabelFreq; - TLabel *LabelElMask; - TLabel *Label32; - TLabel *Label35; - TComboBox *DynamicModel; - TComboBox *IonoOpt; - TComboBox *TropOpt; - TComboBox *PosMode; - TComboBox *Freq; - TComboBox *Solution; - TComboBox *SatEphem; - TEdit *ExSats; - TCheckBox *NavSys1; - TCheckBox *NavSys2; - TCheckBox *NavSys3; - TCheckBox *NavSys4; - TTabSheet *TabSheet2; - TLabel *Label25; - TLabel *LabelRatio; - TLabel *Label13; - TLabel *LabelHold; - TLabel *Label22; - TLabel *Label14; - TLabel *Label11; - TLabel *Label37; - TComboBox *AmbRes; - TEdit *ValidThresAR; - TEdit *LockCntFixAmb; - TEdit *OutCntResetAmb; - TEdit *ElMaskAR; - TEdit *SlipThres; - TEdit *MaxAgeDiff; - TEdit *RejectPhase; - TEdit *NumIter; - TTabSheet *TabSheet3; - TLabel *LabelSolFormat; - TLabel *LabelTimeFormat; - TLabel *LabelLatLonFormat; - TLabel *LabelFieldSep; - TLabel *Label2; - TLabel *Label18; - TLabel *Label20; - TLabel *Label36; - TComboBox *SolFormat; - TComboBox *TimeFormat; - TComboBox *LatLonFormat; - TEdit *FieldSep; - TComboBox *OutputDatum; - TComboBox *OutputHeight; - TComboBox *OutputGeoid; - TComboBox *OutputHead; - TComboBox *OutputOpt; - TComboBox *DebugTrace; - TTabSheet *TabSheet4; - TLabel *Label29; - TGroupBox *GroupBox3; - TLabel *Label6; - TLabel *Label7; - TLabel *Label16; - TEdit *MeasErrR1; - TEdit *MeasErr2; - TEdit *MeasErr3; - TEdit *MeasErr4; - TGroupBox *GroupBox4; - TLabel *Label26; - TLabel *Label27; - TLabel *Label28; - TEdit *PrNoise1; - TEdit *PrNoise2; - TEdit *PrNoise3; - TEdit *SatClkStab; - TTabSheet *TabSheet5; - TGroupBox *GroupRovAnt; - TLabel *LabelRovAntD; - TEdit *RovAntE; - TEdit *RovAntN; - TEdit *RovAntU; - TEdit *RovPos1; - TEdit *RovPos2; - TEdit *RovPos3; - TButton *BtnRovPos; - TCheckBox *RovAntPcv; - TComboBox *RovAnt; - TComboBox *RovPosType; - TGroupBox *GroupRefAnt; - TLabel *LabelRefAntD; - TEdit *RefAntE; - TEdit *RefAntN; - TEdit *RefAntU; - TEdit *RefPos1; - TEdit *RefPos2; - TEdit *RefPos3; - TButton *BtnRefPos; - TCheckBox *RefAntPcv; - TComboBox *RefAnt; - TComboBox *RefPosType; - TTabSheet *TabSheet7; - TLabel *Label1; - TSpeedButton *BtnAntPcvView; - TLabel *Label38; - TSpeedButton *BtnSatPcvView; - TEdit *AntPcvFile; - TButton *BtnAntPcvFile; - TButton *BtnIonoFile; - TEdit *IonoFile; - TEdit *SatPcvFile; - TButton *BtnSatPcvFile; - TTabSheet *TabSheet6; - TMemo *RovList; - TLabel *Label19; - TMemo *BaseList; - TCheckBox *NavSys5; - TLabel *Label63; - TEdit *GeoidDataFile; - TButton *BtnGeoidDataFile; - TEdit *BaselineLen; - TEdit *BaselineSig; - TLabel *Label64; - TCheckBox *BaselineConst; - TLabel *Label10; - TEdit *PrNoise4; - TEdit *PrNoise5; - TComboBox *DebugStatus; - TComboBox *GloAmbRes; - TEdit *TimeDecimal; - TComboBox *TideCorr; - TEdit *FixCntHoldAmb; - TCheckBox *NavSys6; - TLabel *Label15; - TEdit *DCBFile; - TButton *BtnDCBFile; - TLabel *Label21; - TEdit *NmeaIntv1; - TEdit *NmeaIntv2; - TSpeedButton *BtnDCBView; - TLabel *Label31; - TComboBox *SolStatic; - TEdit *StaPosFile; - TLabel *Label30; - TSpeedButton *BtnStaPosView; - TButton *BtnStaPosFile; - TLabel *Label34; - TEdit *BLQFile; - TSpeedButton *BtnBLQFileView; - TButton *BtnBLQFile; - TEdit *MeasErrR2; - TEdit *ElMaskHold; - TEdit *RejectCode; - TLabel *Label39; - TLabel *Label40; - TComboBox *IntpRefObs; - TEdit *SbasSat; - TLabel *Label41; - TLabel *Label42; - TComboBox *ComboBox1; - TLabel *Label44; - TLabel *Label45; - TPanel *Panel1; - TSpeedButton *BtnHelp; - TLabel *Label46; - TLabel *Label62; - TLabel *Label43; - TLabel *Label65; - TComboBox *ElMask; - TEdit *EOPFile; - TButton *BtnEOPFile; - TSpeedButton *BtnEOPView; - TLabel *Label17; - TEdit *RnxOpts1; - TLabel *Label60; - TLabel *Label12; - TEdit *RnxOpts2; - TLabel *Label9; - TCheckBox *PosOpt1; - TCheckBox *PosOpt3; - TCheckBox *PosOpt2; - TCheckBox *PosOpt4; - TButton *BtnSnrMask; - TCheckBox *PosOpt5; - TComboBox *SyncSol; - TComboBox *BdsAmbRes; - TCheckBox *PosOpt6; - TLabel *Label23; - TEdit *PPPOpts; - TCheckBox *NavSys7; - TComboBox *OutputSingle; - TEdit *MaxSolStd; - TComboBox *OutputVel; - TLabel *Label49; - TLabel *Label50; - TEdit *MinFixSats; - TEdit *MinHoldSats; - TEdit *MaxPosVarAR; - TComboBox *ARFilter; - TLabel *Label33; - TLabel *Label47; - TEdit *VarHoldAmb; - TEdit *GainHoldAmb; - TEdit *MinDropSats; - TEdit *GloHwBias; - TLabel *Label48; - TEdit *ValidThresARMin; - TEdit *ValidThresARMax; - TEdit *MeasErrR5; - TEdit *MeasErrR6; - TEdit *MeasErr8; - TLabel *Label51; - TEdit *MeasErr7; - TEdit *MeasErr6; - TEdit *DopThres; - TLabel *Label52; - TEdit *MeasErr5; - void __fastcall BtnOkClick(TObject *Sender); - void __fastcall RovAntPcvClick(TObject *Sender); - void __fastcall FormShow(TObject *Sender); - void __fastcall BtnAntPcvFileClick(TObject *Sender); - void __fastcall BtnIonoFileClick(TObject *Sender); - void __fastcall BtnAntPcvViewClick(TObject *Sender); - void __fastcall AmbResChange(TObject *Sender); - void __fastcall NetRSCorrClick(TObject *Sender); - void __fastcall SatClkCorrClick(TObject *Sender); - void __fastcall PosModeChange(TObject *Sender); - void __fastcall SolFormatChange(TObject *Sender); - void __fastcall BtnLoadClick(TObject *Sender); - void __fastcall BtnSaveClick(TObject *Sender); - void __fastcall FreqChange(TObject *Sender); - void __fastcall BtnRefPosClick(TObject *Sender); - void __fastcall BtnRovPosClick(TObject *Sender); - void __fastcall RovPosClick(TObject *Sender); - void __fastcall RefPosClick(TObject *Sender); - void __fastcall BtnStaPosViewClick(TObject *Sender); - void __fastcall BtnStaPosFileClick(TObject *Sender); - void __fastcall SbasCorrClick(TObject *Sender); - void __fastcall OutputHeightClick(TObject *Sender); - void __fastcall RefPosTypeChange(TObject *Sender); - void __fastcall RovPosTypeChange(TObject *Sender); - void __fastcall GetPos(int type, TEdit **edit, double *pos); - void __fastcall SetPos(int type, TEdit **edit, double *pos); - void __fastcall BtnSatPcvFileClick(TObject *Sender); - void __fastcall BtnSatPcvViewClick(TObject *Sender); - void __fastcall SatEphemClick(TObject *Sender); - void __fastcall BtnGeoidDataFileClick(TObject *Sender); - void __fastcall BaselineConstClick(TObject *Sender); - void __fastcall NavSys2Click(TObject *Sender); - void __fastcall IonoOptChange(TObject *Sender); - void __fastcall TropOptChange(TObject *Sender); - void __fastcall DynamicModelChange(TObject *Sender); - void __fastcall SatEphemChange(TObject *Sender); - void __fastcall RovAntClick(TObject *Sender); - void __fastcall RefAntClick(TObject *Sender); - void __fastcall BtnDCBViewClick(TObject *Sender); - void __fastcall BtnDCBFileClick(TObject *Sender); - void __fastcall BtnHelpClick(TObject *Sender); - void __fastcall ExtEna0Click(TObject *Sender); - void __fastcall ExtEna1Click(TObject *Sender); - void __fastcall ExtEna2Click(TObject *Sender); - void __fastcall BtnBLQFileViewClick(TObject *Sender); - void __fastcall BtnBLQFileClick(TObject *Sender); - void __fastcall BtnEOPFileClick(TObject *Sender); - void __fastcall BtnEOPViewClick(TObject *Sender); - void __fastcall BtnSnrMaskClick(TObject *Sender); - void __fastcall NavSys6Click(TObject *Sender); - void __fastcall BtnFreqClick(TObject *Sender); +class TOptDialog : public TForm { + __published : TButton *BtnCancel; + TButton *BtnOk; + TOpenDialog *OpenDialog; + TButton *BtnSave; + TButton *BtnLoad; + TSaveDialog *SaveDialog; + TPageControl *Misc; + TTabSheet *TabSheet1; + TLabel *Label3; + TLabel *Label8; + TLabel *LabelPosMode; + TLabel *Label5; + TLabel *LabelFreq; + TLabel *LabelElMask; + TLabel *Label32; + TLabel *Label35; + TComboBox *DynamicModel; + TComboBox *IonoOpt; + TComboBox *TropOpt; + TComboBox *PosMode; + TComboBox *Freq; + TComboBox *Solution; + TComboBox *SatEphem; + TEdit *ExSats; + TCheckBox *NavSys1; + TCheckBox *NavSys2; + TCheckBox *NavSys3; + TCheckBox *NavSys4; + TTabSheet *TabSheet2; + TLabel *Label25; + TLabel *LabelRatio; + TLabel *Label13; + TLabel *LabelHold; + TLabel *Label22; + TLabel *Label14; + TLabel *Label11; + TLabel *Label37; + TComboBox *AmbRes; + TEdit *ValidThresAR; + TEdit *LockCntFixAmb; + TEdit *OutCntResetAmb; + TEdit *ElMaskAR; + TEdit *SlipThres; + TEdit *MaxAgeDiff; + TEdit *RejectPhase; + TEdit *NumIter; + TTabSheet *TabSheet3; + TLabel *LabelSolFormat; + TLabel *LabelTimeFormat; + TLabel *LabelLatLonFormat; + TLabel *LabelFieldSep; + TLabel *Label2; + TLabel *Label18; + TLabel *Label20; + TLabel *Label36; + TComboBox *SolFormat; + TComboBox *TimeFormat; + TComboBox *LatLonFormat; + TEdit *FieldSep; + TComboBox *OutputDatum; + TComboBox *OutputHeight; + TComboBox *OutputGeoid; + TComboBox *OutputHead; + TComboBox *OutputOpt; + TComboBox *DebugTrace; + TTabSheet *TabSheet4; + TLabel *Label29; + TGroupBox *GroupBox3; + TLabel *Label6; + TLabel *Label7; + TLabel *Label16; + TEdit *MeasErrR1; + TEdit *MeasErr2; + TEdit *MeasErr3; + TEdit *MeasErr4; + TGroupBox *GroupBox4; + TLabel *Label26; + TLabel *Label27; + TLabel *Label28; + TEdit *PrNoise1; + TEdit *PrNoise2; + TEdit *PrNoise3; + TEdit *SatClkStab; + TTabSheet *TabSheet5; + TGroupBox *GroupRovAnt; + TLabel *LabelRovAntD; + TEdit *RovAntE; + TEdit *RovAntN; + TEdit *RovAntU; + TEdit *RovPos1; + TEdit *RovPos2; + TEdit *RovPos3; + TButton *BtnRovPos; + TCheckBox *RovAntPcv; + TComboBox *RovAnt; + TComboBox *RovPosType; + TGroupBox *GroupRefAnt; + TLabel *LabelRefAntD; + TEdit *RefAntE; + TEdit *RefAntN; + TEdit *RefAntU; + TEdit *RefPos1; + TEdit *RefPos2; + TEdit *RefPos3; + TButton *BtnRefPos; + TCheckBox *RefAntPcv; + TComboBox *RefAnt; + TComboBox *RefPosType; + TTabSheet *TabSheet7; + TLabel *Label1; + TSpeedButton *BtnAntPcvView; + TLabel *Label38; + TSpeedButton *BtnSatPcvView; + TEdit *AntPcvFile; + TButton *BtnAntPcvFile; + TButton *BtnIonoFile; + TEdit *IonoFile; + TEdit *SatPcvFile; + TButton *BtnSatPcvFile; + TTabSheet *TabSheet6; + TMemo *RovList; + TLabel *Label19; + TMemo *BaseList; + TCheckBox *NavSys5; + TLabel *Label63; + TEdit *GeoidDataFile; + TButton *BtnGeoidDataFile; + TEdit *BaselineLen; + TEdit *BaselineSig; + TLabel *Label64; + TCheckBox *BaselineConst; + TLabel *Label10; + TEdit *PrNoise4; + TEdit *PrNoise5; + TComboBox *DebugStatus; + TComboBox *GloAmbRes; + TEdit *TimeDecimal; + TComboBox *TideCorr; + TEdit *FixCntHoldAmb; + TCheckBox *NavSys6; + TLabel *Label15; + TEdit *DCBFile; + TButton *BtnDCBFile; + TLabel *Label21; + TEdit *NmeaIntv1; + TEdit *NmeaIntv2; + TSpeedButton *BtnDCBView; + TLabel *Label31; + TComboBox *SolStatic; + TEdit *StaPosFile; + TLabel *Label30; + TSpeedButton *BtnStaPosView; + TButton *BtnStaPosFile; + TLabel *Label34; + TEdit *BLQFile; + TSpeedButton *BtnBLQFileView; + TButton *BtnBLQFile; + TEdit *MeasErrR2; + TEdit *ElMaskHold; + TEdit *RejectCode; + TLabel *Label39; + TLabel *Label40; + TComboBox *IntpRefObs; + TEdit *SbasSat; + TLabel *Label41; + TLabel *Label42; + TComboBox *ComboBox1; + TLabel *Label44; + TLabel *Label45; + TPanel *Panel1; + TSpeedButton *BtnHelp; + TLabel *Label46; + TLabel *Label62; + TLabel *Label43; + TLabel *Label65; + TComboBox *ElMask; + TEdit *EOPFile; + TButton *BtnEOPFile; + TSpeedButton *BtnEOPView; + TLabel *Label17; + TEdit *RnxOpts1; + TLabel *Label60; + TLabel *Label12; + TEdit *RnxOpts2; + TLabel *Label9; + TCheckBox *PosOpt1; + TCheckBox *PosOpt3; + TCheckBox *PosOpt2; + TCheckBox *PosOpt4; + TButton *BtnSnrMask; + TCheckBox *PosOpt5; + TComboBox *SyncSol; + TComboBox *BdsAmbRes; + TCheckBox *PosOpt6; + TLabel *Label23; + TEdit *PPPOpts; + TCheckBox *NavSys7; + TComboBox *OutputSingle; + TEdit *MaxSolStd; + TComboBox *OutputVel; + TLabel *Label49; + TLabel *Label50; + TEdit *MinFixSats; + TEdit *MinHoldSats; + TEdit *MaxPosVarAR; + TComboBox *ARFilter; + TLabel *Label33; + TLabel *Label47; + TEdit *VarHoldAmb; + TEdit *GainHoldAmb; + TEdit *MinDropSats; + TEdit *GloHwBias; + TLabel *Label48; + TEdit *ValidThresARMin; + TEdit *ValidThresARMax; + TEdit *MeasErrR5; + TEdit *MeasErrR6; + TEdit *MeasErr8; + TLabel *Label51; + TEdit *MeasErr7; + TEdit *MeasErr6; + TEdit *DopThres; + TLabel *Label52; + TEdit *MeasErr5; + void __fastcall BtnOkClick(TObject *Sender); + void __fastcall RovAntPcvClick(TObject *Sender); + void __fastcall FormShow(TObject *Sender); + void __fastcall BtnAntPcvFileClick(TObject *Sender); + void __fastcall BtnIonoFileClick(TObject *Sender); + void __fastcall BtnAntPcvViewClick(TObject *Sender); + void __fastcall AmbResChange(TObject *Sender); + void __fastcall NetRSCorrClick(TObject *Sender); + void __fastcall SatClkCorrClick(TObject *Sender); + void __fastcall PosModeChange(TObject *Sender); + void __fastcall SolFormatChange(TObject *Sender); + void __fastcall BtnLoadClick(TObject *Sender); + void __fastcall BtnSaveClick(TObject *Sender); + void __fastcall FreqChange(TObject *Sender); + void __fastcall BtnRefPosClick(TObject *Sender); + void __fastcall BtnRovPosClick(TObject *Sender); + void __fastcall RovPosClick(TObject *Sender); + void __fastcall RefPosClick(TObject *Sender); + void __fastcall BtnStaPosViewClick(TObject *Sender); + void __fastcall BtnStaPosFileClick(TObject *Sender); + void __fastcall SbasCorrClick(TObject *Sender); + void __fastcall OutputHeightClick(TObject *Sender); + void __fastcall RefPosTypeChange(TObject *Sender); + void __fastcall RovPosTypeChange(TObject *Sender); + void __fastcall GetPos(int type, TEdit **edit, double *pos); + void __fastcall SetPos(int type, TEdit **edit, double *pos); + void __fastcall BtnSatPcvFileClick(TObject *Sender); + void __fastcall BtnSatPcvViewClick(TObject *Sender); + void __fastcall SatEphemClick(TObject *Sender); + void __fastcall BtnGeoidDataFileClick(TObject *Sender); + void __fastcall BaselineConstClick(TObject *Sender); + void __fastcall NavSys2Click(TObject *Sender); + void __fastcall IonoOptChange(TObject *Sender); + void __fastcall TropOptChange(TObject *Sender); + void __fastcall DynamicModelChange(TObject *Sender); + void __fastcall SatEphemChange(TObject *Sender); + void __fastcall RovAntClick(TObject *Sender); + void __fastcall RefAntClick(TObject *Sender); + void __fastcall BtnDCBViewClick(TObject *Sender); + void __fastcall BtnDCBFileClick(TObject *Sender); + void __fastcall BtnHelpClick(TObject *Sender); + void __fastcall ExtEna0Click(TObject *Sender); + void __fastcall ExtEna1Click(TObject *Sender); + void __fastcall ExtEna2Click(TObject *Sender); + void __fastcall BtnBLQFileViewClick(TObject *Sender); + void __fastcall BtnBLQFileClick(TObject *Sender); + void __fastcall BtnEOPFileClick(TObject *Sender); + void __fastcall BtnEOPViewClick(TObject *Sender); + void __fastcall BtnSnrMaskClick(TObject *Sender); + void __fastcall NavSys6Click(TObject *Sender); + void __fastcall BtnFreqClick(TObject *Sender); + + private: + snrmask_t SnrMask; + int RovPosTypeP, RefPosTypeP; + void __fastcall GetOpt(void); + void __fastcall SetOpt(void); + void __fastcall LoadOpt(AnsiString file); + void __fastcall SaveOpt(AnsiString file); + void __fastcall ReadAntList(void); + void __fastcall UpdateEnable(void); + void __fastcall UpdateEnableExtErr(void); -private: - snrmask_t SnrMask; - int RovPosTypeP,RefPosTypeP; - void __fastcall GetOpt(void); - void __fastcall SetOpt(void); - void __fastcall LoadOpt(AnsiString file); - void __fastcall SaveOpt(AnsiString file); - void __fastcall ReadAntList(void); - void __fastcall UpdateEnable(void); - void __fastcall UpdateEnableExtErr(void); -public: - - __fastcall TOptDialog(TComponent* Owner); + public: + __fastcall TOptDialog(TComponent *Owner); }; //--------------------------------------------------------------------------- extern PACKAGE TOptDialog *OptDialog; diff --git a/app/winapp/rtkpost/rtkpost.cpp b/app/winapp/rtkpost/rtkpost.cpp index e651721cf..880f434bf 100644 --- a/app/winapp/rtkpost/rtkpost.cpp +++ b/app/winapp/rtkpost/rtkpost.cpp @@ -17,42 +17,33 @@ USEFORM("..\appcmn\maskoptdlg.cpp", MaskOptDialog); USEFORM("postmain.cpp", MainForm); USEFORM("postopt.cpp", OptDialog); //--------------------------------------------------------------------------- -int WINAPI WinMain(HINSTANCE, HINSTANCE, LPSTR, int) -{ - try - { - Application->Initialize(); - Application->Title = "RTKPOST"; - Application->CreateForm(__classid(TMainForm), &MainForm); - Application->CreateForm(__classid(TOptDialog), &OptDialog); - Application->CreateForm(__classid(TConvDialog), &ConvDialog); - Application->CreateForm(__classid(TOptDialog), &OptDialog); - Application->CreateForm(__classid(TTextViewer), &TextViewer); - Application->CreateForm(__classid(TViewerOptDialog), &ViewerOptDialog); - Application->CreateForm(__classid(TRefDialog), &RefDialog); - Application->CreateForm(__classid(TTimeDialog), &TimeDialog); - Application->CreateForm(__classid(TConfDialog), &ConfDialog); - Application->CreateForm(__classid(TAboutDialog), &AboutDialog); - Application->CreateForm(__classid(TKeyDialog), &KeyDialog); - Application->CreateForm(__classid(TMaskOptDialog), &MaskOptDialog); - Application->CreateForm(__classid(TFreqDialog), &FreqDialog); - Application->Run(); - } - catch (Exception &exception) - { - Application->ShowException(&exception); - } - catch (...) - { - try - { - throw Exception(""); - } - catch (Exception &exception) - { - Application->ShowException(&exception); - } - } - return 0; +int WINAPI WinMain(HINSTANCE, HINSTANCE, LPSTR, int) { + try { + Application->Initialize(); + Application->Title = "RTKPOST"; + Application->CreateForm(__classid(TMainForm), &MainForm); + Application->CreateForm(__classid(TOptDialog), &OptDialog); + Application->CreateForm(__classid(TConvDialog), &ConvDialog); + Application->CreateForm(__classid(TOptDialog), &OptDialog); + Application->CreateForm(__classid(TTextViewer), &TextViewer); + Application->CreateForm(__classid(TViewerOptDialog), &ViewerOptDialog); + Application->CreateForm(__classid(TRefDialog), &RefDialog); + Application->CreateForm(__classid(TTimeDialog), &TimeDialog); + Application->CreateForm(__classid(TConfDialog), &ConfDialog); + Application->CreateForm(__classid(TAboutDialog), &AboutDialog); + Application->CreateForm(__classid(TKeyDialog), &KeyDialog); + Application->CreateForm(__classid(TMaskOptDialog), &MaskOptDialog); + Application->CreateForm(__classid(TFreqDialog), &FreqDialog); + Application->Run(); + } catch (Exception &exception) { + Application->ShowException(&exception); + } catch (...) { + try { + throw Exception(""); + } catch (Exception &exception) { + Application->ShowException(&exception); + } + } + return 0; } //--------------------------------------------------------------------------- diff --git a/app/winapp/srctblbrows/browsmain.cpp b/app/winapp/srctblbrows/browsmain.cpp index f21413c40..560a5a834 100644 --- a/app/winapp/srctblbrows/browsmain.cpp +++ b/app/winapp/srctblbrows/browsmain.cpp @@ -1,576 +1,544 @@ //--------------------------------------------------------------------------- #include + #include #pragma hdrstop -#include "rtklib.h" +#include "browsmain.h" + #include "aboutdlg.h" #include "gmview.h" -#include "browsmain.h" +#include "rtklib.h" #include "staoptdlg.h" //--------------------------------------------------------------------------- #pragma package(smart_init) #pragma resource "*.dfm" TMainForm *MainForm; -#define PRGNAME "NTRIP Browser" -#define NTRIP_HOME "rtcm-ntrip.org:2101" // caster list home -#define NTRIP_TIMEOUT 10000 // response timeout (ms) -#define NTRIP_CYCLE 50 // processing cycle (ms) -#define MAXSRCTBL 512000 // max source table size (bytes) -#define ENDSRCTBL "ENDSOURCETABLE" // end marker of table -#define MAXLINE 1024 // max line size (byte) -#define ADDRESS_WIDTH 184 // width of Address (px) +#define PRGNAME "NTRIP Browser" +#define NTRIP_HOME "rtcm-ntrip.org:2101" // caster list home +#define NTRIP_TIMEOUT 10000 // response timeout (ms) +#define NTRIP_CYCLE 50 // processing cycle (ms) +#define MAXSRCTBL 512000 // max source table size (bytes) +#define ENDSRCTBL "ENDSOURCETABLE" // end marker of table +#define MAXLINE 1024 // max line size (byte) +#define ADDRESS_WIDTH 184 // width of Address (px) -static char buff[MAXSRCTBL]; // source table buffer +static char buff[MAXSRCTBL]; // source table buffer //--------------------------------------------------------------------------- -static double str2dbl(AnsiString str) -{ - double val=0.0; - sscanf(str.c_str(),"%lf",&val); - return val; +static double str2dbl(AnsiString str) { + double val = 0.0; + sscanf(str.c_str(), "%lf", &val); + return val; } /* get source table -------------------------------------------------------*/ -static char *getsrctbl(const char *path) -{ - static int lock=0; - AnsiString s; - stream_t str; - char *p=buff,msg[MAXSTRMSG]=""; - int ns,stat; - uint32_t tick=tickget(); - - if (lock) return NULL; else lock=1; - - strinit(&str); - if (!stropen(&str,STR_NTRIPCLI,STR_MODE_R,path)) { - lock=0; - MainForm->ShowMsg("stream open error"); - return NULL; - } - MainForm->ShowMsg("connecting..."); - - while(pShowMsg(msg); - if (stat<=0) break; - if (strstr(buff,ENDSRCTBL)) break; - if ((int)(tickget()-tick)>NTRIP_TIMEOUT) { - MainForm->ShowMsg("response timeout"); - break; - } - } - strclose(&str); - lock=0; - return buff; -} -//--------------------------------------------------------------------------- -__fastcall TMainForm::TMainForm(TComponent* Owner) - : TForm(Owner) -{ - char file[1024]="srctblbrows.exe",*p; - - ::GetModuleFileName(NULL,file,sizeof(file)); - if (!(p=strrchr(file,'.'))) p=file+strlen(file); - strcpy(p,".ini"); - IniFile=file; - - strinitcom(); - - StaList=new TStringList; +static char *getsrctbl(const char *path) { + static int lock = 0; + AnsiString s; + stream_t str; + char *p = buff, msg[MAXSTRMSG] = ""; + int ns, stat; + uint32_t tick = tickget(); + + if (lock) + return NULL; + else + lock = 1; + + strinit(&str); + if (!stropen(&str, STR_NTRIPCLI, STR_MODE_R, path)) { + lock = 0; + MainForm->ShowMsg("stream open error"); + return NULL; + } + MainForm->ShowMsg("connecting..."); + + while (p < buff + MAXSRCTBL - 1) { + ns = strread(&str, (uint8_t *)p, buff + MAXSRCTBL - p - 1); + p += ns; + *p = '\0'; + Sleep(NTRIP_CYCLE); + stat = strstat(&str, msg); + MainForm->ShowMsg(msg); + if (stat <= 0) break; + if (strstr(buff, ENDSRCTBL)) break; + if ((int)(tickget() - tick) > NTRIP_TIMEOUT) { + MainForm->ShowMsg("response timeout"); + break; + } + } + strclose(&str); + lock = 0; + return buff; } //--------------------------------------------------------------------------- -void __fastcall TMainForm::FormShow(TObject *Sender) -{ - AnsiString colw0="30,74,116,56,244,18,52,62,28,50,50,18,18,120,28,18,18,40,300,"; - AnsiString colw1="30,112,40,96,126,18,28,50,50,160,40,600,0,0,0,0,0,0,0,"; - AnsiString colw2="30,80,126,18,18,300,300,300,600,0,0,0,0,0,0,0,0,0,0,"; - TIniFile *ini=new TIniFile(IniFile); - AnsiString title,list,colw,cmd,url="",s,stas; - double scale; - int i,w,argc=0; - char *p,*q,buff[8192],*argv[32]; - - scale=(double)Address->Width/ADDRESS_WIDTH; - - cmd=GetCommandLine(); - strcpy(buff,cmd.c_str()); - +__fastcall TMainForm::TMainForm(TComponent *Owner) : TForm(Owner) { + char file[1024] = "srctblbrows.exe", *p; + + ::GetModuleFileName(NULL, file, sizeof(file)); + if (!(p = strrchr(file, '.'))) p = file + strlen(file); + strcpy(p, ".ini"); + IniFile = file; + + strinitcom(); + + StaList = new TStringList; +} +//--------------------------------------------------------------------------- +void __fastcall TMainForm::FormShow(TObject *Sender) { + AnsiString colw0 = "30,74,116,56,244,18,52,62,28,50,50,18,18,120,28,18,18,40,300,"; + AnsiString colw1 = "30,112,40,96,126,18,28,50,50,160,40,600,0,0,0,0,0,0,0,"; + AnsiString colw2 = "30,80,126,18,18,300,300,300,600,0,0,0,0,0,0,0,0,0,0,"; + TIniFile *ini = new TIniFile(IniFile); + AnsiString title, list, colw, cmd, url = "", s, stas; + double scale; + int i, w, argc = 0; + char *p, *q, buff[8192], *argv[32]; + + scale = (double)Address->Width / ADDRESS_WIDTH; + + cmd = GetCommandLine(); + strcpy(buff, cmd.c_str()); + + char *sptr; + for (p = strtok_r(buff, " ", &sptr); p && argc < 32; p = strtok_r(NULL, " ", &sptr)) { + argv[argc++] = p; + } + if (argc >= 2) url = argv[1]; + + Caption = title.sprintf("%s-%s %s", PRGNAME, VER_RTKLIB, PATCH_LEVEL); + + // There appears to be a line length limit of around 2048 characters + // for the init files and that can truncate this loaded list. + list = ini->ReadString("srctbl", "addrlist", ""); + for (p = list.c_str(); *p;) { + if (!(q = strchr(p, '@'))) break; + if (q - p > (int)sizeof(buff) - 1) continue; + strncpy(buff, p, q - p); + buff[q - p] = '\0'; + p = q + 1; + Address->AddItem(buff, NULL); + } + if (url != "") { + Address->Text = url; + } else { + Address->Text = ini->ReadString("srctbl", "address", ""); + } + colw = ini->ReadString("srctbl", "colwidth0", colw0); + for (i = 0, p = colw.c_str(); i < 19 && *p; i++, p = q + 1) { + if (!(q = strchr(p, ','))) + break; + else + *q = '\0'; + Table0->ColWidths[i] = (int)(atoi(p) * scale); + } + colw = ini->ReadString("srctbl", "colwidth1", colw1); + for (i = 0, p = colw.c_str(); i < 19 && *p; i++, p = q + 1) { + if (!(q = strchr(p, ','))) + break; + else + *q = '\0'; + Table1->ColWidths[i] = (int)(atoi(p) * scale); + } + colw = ini->ReadString("srctbl", "colwidth2", colw2); + for (i = 0, p = colw.c_str(); i < 19 && *p; i++, p = q + 1) { + if (!(q = strchr(p, ','))) + break; + else + *q = '\0'; + Table2->ColWidths[i] = (int)(atoi(p) * scale); + } + StaList->Clear(); + for (int i = 0; i < 10; i++) { + stas = ini->ReadString("sta", s.sprintf("station%d", i), ""); + strcpy(buff, stas.c_str()); char *sptr; - for (p=strtok_r(buff," ",&sptr);p&&argc<32;p=strtok_r(NULL," ",&sptr)) { - argv[argc++]=p; - } - if (argc>=2) url=argv[1]; - - Caption=title.sprintf("%s-%s %s",PRGNAME,VER_RTKLIB,PATCH_LEVEL); - - // There appears to be a line length limit of around 2048 characters - // for the init files and that can truncate this loaded list. - list=ini->ReadString("srctbl","addrlist",""); - for (p=list.c_str();*p;) { - if (!(q=strchr(p,'@'))) break; - if (q-p>(int)sizeof(buff)-1) continue; - strncpy(buff,p,q-p); buff[q-p]='\0'; p=q+1; - Address->AddItem(buff,NULL); - } - if (url!="") { - Address->Text=url; + for (p = strtok_r(buff, ",", &sptr); p; p = strtok_r(NULL, ",", &sptr)) { + StaList->Add(p); } - else { - Address->Text=ini->ReadString("srctbl","address",""); - } - colw=ini->ReadString("srctbl","colwidth0",colw0); - for (i=0,p=colw.c_str();i<19&&*p;i++,p=q+1) { - if (!(q=strchr(p,','))) break; else *q='\0'; - Table0->ColWidths[i]=(int)(atoi(p)*scale); - } - colw=ini->ReadString("srctbl","colwidth1",colw1); - for (i=0,p=colw.c_str();i<19&&*p;i++,p=q+1) { - if (!(q=strchr(p,','))) break; else *q='\0'; - Table1->ColWidths[i]=(int)(atoi(p)*scale); - } - colw=ini->ReadString("srctbl","colwidth2",colw2); - for (i=0,p=colw.c_str();i<19&&*p;i++,p=q+1) { - if (!(q=strchr(p,','))) break; else *q='\0'; - Table2->ColWidths[i]=(int)(atoi(p)*scale); - } - StaList->Clear(); - for (int i=0;i<10;i++) { - stas=ini->ReadString("sta",s.sprintf("station%d",i),""); - strcpy(buff,stas.c_str()); - char *sptr; - for (p=strtok_r(buff,",",&sptr);p;p=strtok_r(NULL,",",&sptr)) { - StaList->Add(p); - } - } - delete ini; - - ShowTable(); - UpdateEnable(); - ::PostMessage(Address->Handle,CB_SETEDITSEL,-1,0); + } + delete ini; + + ShowTable(); + UpdateEnable(); + ::PostMessage(Address->Handle, CB_SETEDITSEL, -1, 0); - if (url!="") Timer1->Enabled=true; + if (url != "") Timer1->Enabled = true; } //--------------------------------------------------------------------------- -void __fastcall TMainForm::Timer1Timer(TObject *Sender) -{ - UpdateTable(); - Timer1->Enabled=false; +void __fastcall TMainForm::Timer1Timer(TObject *Sender) { + UpdateTable(); + Timer1->Enabled = false; } //--------------------------------------------------------------------------- -void __fastcall TMainForm::FormClose(TObject *Sender, TCloseAction &Action) -{ - TIniFile *ini=new TIniFile(IniFile); - AnsiString s,list,colw,sta; - double scale; - char buff[8192]="",*p; - - scale=(double)Address->Width/ADDRESS_WIDTH; - - ini->WriteString("srctbl","address",Address->Text); - for (int i=0;iItems->Count;i++) { - list=list+Address->Items->Strings[i]+"@"; - } - ini->WriteString("srctbl","addrlist",list); - colw=""; - for (int i=0;iColCount;i++) { - colw=colw+s.sprintf("%d,",(int)(Table0->ColWidths[i]/scale)); - } - ini->WriteString("srctbl","colwidth0",colw); - colw=""; - for (int i=0;iColCount;i++) { - colw=colw+s.sprintf("%d,",(int)(Table1->ColWidths[i]/scale)); - } - ini->WriteString("srctbl","colwidth1",colw); - colw=""; - for (int i=0;iColCount;i++) { - colw=colw+s.sprintf("%d,",(int)(Table2->ColWidths[i]/scale)); - } - ini->WriteString("srctbl","colwidth2",colw); - - for (int i=0,j=0;i<10;i++) { - p=buff; *p='\0'; - for (int k=0;k<256&&jCount;k++) { - sta=StaList->Strings[j++]; - p+=sprintf(p,"%s%s",k==0?"":",",sta.c_str()); - } - ini->WriteString ("sta",s.sprintf("station%d",i),buff); +void __fastcall TMainForm::FormClose(TObject *Sender, TCloseAction &Action) { + TIniFile *ini = new TIniFile(IniFile); + AnsiString s, list, colw, sta; + double scale; + char buff[8192] = "", *p; + + scale = (double)Address->Width / ADDRESS_WIDTH; + + ini->WriteString("srctbl", "address", Address->Text); + for (int i = 0; i < Address->Items->Count; i++) { + list = list + Address->Items->Strings[i] + "@"; + } + ini->WriteString("srctbl", "addrlist", list); + colw = ""; + for (int i = 0; i < Table0->ColCount; i++) { + colw = colw + s.sprintf("%d,", (int)(Table0->ColWidths[i] / scale)); + } + ini->WriteString("srctbl", "colwidth0", colw); + colw = ""; + for (int i = 0; i < Table1->ColCount; i++) { + colw = colw + s.sprintf("%d,", (int)(Table1->ColWidths[i] / scale)); + } + ini->WriteString("srctbl", "colwidth1", colw); + colw = ""; + for (int i = 0; i < Table2->ColCount; i++) { + colw = colw + s.sprintf("%d,", (int)(Table2->ColWidths[i] / scale)); + } + ini->WriteString("srctbl", "colwidth2", colw); + + for (int i = 0, j = 0; i < 10; i++) { + p = buff; + *p = '\0'; + for (int k = 0; k < 256 && j < StaList->Count; k++) { + sta = StaList->Strings[j++]; + p += sprintf(p, "%s%s", k == 0 ? "" : ",", sta.c_str()); } - delete ini; + ini->WriteString("sta", s.sprintf("station%d", i), buff); + } + delete ini; } //--------------------------------------------------------------------------- -void __fastcall TMainForm::MenuOpenClick(TObject *Sender) -{ - FILE *fp; - AnsiString OpenDialog_FileName=OpenDialog->FileName; - char buff[2048]; - if (!OpenDialog->Execute()) return; - SrcTable=""; - if (!(fp=fopen(OpenDialog_FileName.c_str(),"rb"))) return; - while (fgets(buff,sizeof(buff),fp)) { - SrcTable+=buff; - } - fclose(fp); - AddrCaster=Address->Text; - ShowTable(); - ShowMsg("source table loaded"); +void __fastcall TMainForm::MenuOpenClick(TObject *Sender) { + FILE *fp; + AnsiString OpenDialog_FileName = OpenDialog->FileName; + char buff[2048]; + if (!OpenDialog->Execute()) return; + SrcTable = ""; + if (!(fp = fopen(OpenDialog_FileName.c_str(), "rb"))) return; + while (fgets(buff, sizeof(buff), fp)) { + SrcTable += buff; + } + fclose(fp); + AddrCaster = Address->Text; + ShowTable(); + ShowMsg("source table loaded"); } //--------------------------------------------------------------------------- -void __fastcall TMainForm::MenuSaveClick(TObject *Sender) -{ - FILE *fp; - AnsiString SaveDialog_FileName=SaveDialog->FileName; - if (!SaveDialog->Execute()) return; - if (!(fp=fopen(SaveDialog_FileName.c_str(),"wb"))) return; - fwrite(SrcTable.c_str(),1,SrcTable.Length(),fp); - fclose(fp); - ShowMsg("source table saved"); +void __fastcall TMainForm::MenuSaveClick(TObject *Sender) { + FILE *fp; + AnsiString SaveDialog_FileName = SaveDialog->FileName; + if (!SaveDialog->Execute()) return; + if (!(fp = fopen(SaveDialog_FileName.c_str(), "wb"))) return; + fwrite(SrcTable.c_str(), 1, SrcTable.Length(), fp); + fclose(fp); + ShowMsg("source table saved"); } //--------------------------------------------------------------------------- -void __fastcall TMainForm::MenuQuitClick(TObject *Sender) -{ - Close(); -} +void __fastcall TMainForm::MenuQuitClick(TObject *Sender) { Close(); } //--------------------------------------------------------------------------- -void __fastcall TMainForm::MenuUpdateCasterClick(TObject *Sender) -{ - UpdateCaster(); -} +void __fastcall TMainForm::MenuUpdateCasterClick(TObject *Sender) { UpdateCaster(); } //--------------------------------------------------------------------------- -void __fastcall TMainForm::MenuUpdateTableClick(TObject *Sender) -{ - UpdateTable(); -} +void __fastcall TMainForm::MenuUpdateTableClick(TObject *Sender) { UpdateTable(); } //--------------------------------------------------------------------------- -void __fastcall TMainForm::MenuViewStrClick(TObject *Sender) -{ - TypeStr->Down=true; - ShowTable(); +void __fastcall TMainForm::MenuViewStrClick(TObject *Sender) { + TypeStr->Down = true; + ShowTable(); } //--------------------------------------------------------------------------- -void __fastcall TMainForm::MenuViewCasClick(TObject *Sender) -{ - TypeCas->Down=true; - ShowTable(); +void __fastcall TMainForm::MenuViewCasClick(TObject *Sender) { + TypeCas->Down = true; + ShowTable(); } //--------------------------------------------------------------------------- -void __fastcall TMainForm::MenuViewNetClick(TObject *Sender) -{ - TypeNet->Down=true; - ShowTable(); +void __fastcall TMainForm::MenuViewNetClick(TObject *Sender) { + TypeNet->Down = true; + ShowTable(); } //--------------------------------------------------------------------------- -void __fastcall TMainForm::MenuViewSrcClick(TObject *Sender) -{ - TypeSrc->Down=true; - ShowTable(); +void __fastcall TMainForm::MenuViewSrcClick(TObject *Sender) { + TypeSrc->Down = true; + ShowTable(); } //--------------------------------------------------------------------------- -void __fastcall TMainForm::MenuAboutClick(TObject *Sender) -{ - AboutDialog->About=PRGNAME; - AboutDialog->IconIndex=7; - AboutDialog->ShowModal(); +void __fastcall TMainForm::MenuAboutClick(TObject *Sender) { + AboutDialog->About = PRGNAME; + AboutDialog->IconIndex = 7; + AboutDialog->ShowModal(); } //--------------------------------------------------------------------------- -void __fastcall TMainForm::BtnMapClick(TObject *Sender) -{ - Timer2->Enabled=true; - GoogleMapView->Show(); +void __fastcall TMainForm::BtnMapClick(TObject *Sender) { + Timer2->Enabled = true; + GoogleMapView->Show(); } //--------------------------------------------------------------------------- -void __fastcall TMainForm::Table0SelectCell(TObject *Sender, int ACol, int ARow, bool &CanSelect) -{ - AnsiString title; - if (0RowCount) { - title=Table0->Cells[1][ARow]; - GoogleMapView->HighlightMark(title); - GoogleMapView->Caption="NTRIP Data Stream Map: "+Address->Text+"/"+title; - } +void __fastcall TMainForm::Table0SelectCell(TObject *Sender, int ACol, int ARow, bool &CanSelect) { + AnsiString title; + if (0 < ARow && ARow < Table0->RowCount) { + title = Table0->Cells[1][ARow]; + GoogleMapView->HighlightMark(title); + GoogleMapView->Caption = "NTRIP Data Stream Map: " + Address->Text + "/" + title; + } } //--------------------------------------------------------------------------- -void __fastcall TMainForm::BtnListClick(TObject *Sender) -{ - UpdateCaster(); -} +void __fastcall TMainForm::BtnListClick(TObject *Sender) { UpdateCaster(); } //--------------------------------------------------------------------------- -void __fastcall TMainForm::BtnUpdateClick(TObject *Sender) -{ - UpdateTable(); -} +void __fastcall TMainForm::BtnUpdateClick(TObject *Sender) { UpdateTable(); } //--------------------------------------------------------------------------- -void __fastcall TMainForm::TypeStrClick(TObject *Sender) -{ - ShowTable(); -} +void __fastcall TMainForm::TypeStrClick(TObject *Sender) { ShowTable(); } //--------------------------------------------------------------------------- -void __fastcall TMainForm::TypeCasClick(TObject *Sender) -{ - ShowTable(); -} +void __fastcall TMainForm::TypeCasClick(TObject *Sender) { ShowTable(); } //--------------------------------------------------------------------------- -void __fastcall TMainForm::TypeNetClick(TObject *Sender) -{ - ShowTable(); -} +void __fastcall TMainForm::TypeNetClick(TObject *Sender) { ShowTable(); } //--------------------------------------------------------------------------- -void __fastcall TMainForm::TypeSrcClick(TObject *Sender) -{ - ShowTable(); -} +void __fastcall TMainForm::TypeSrcClick(TObject *Sender) { ShowTable(); } //--------------------------------------------------------------------------- -void __fastcall TMainForm::AddressKeyPress(TObject *Sender, char &Key) -{ - if (Key=='\r') UpdateTable(); +void __fastcall TMainForm::AddressKeyPress(TObject *Sender, char &Key) { + if (Key == '\r') UpdateTable(); } //--------------------------------------------------------------------------- -void __fastcall TMainForm::AddressChange(TObject *Sender) -{ - ShowTable(); -} +void __fastcall TMainForm::AddressChange(TObject *Sender) { ShowTable(); } //--------------------------------------------------------------------------- -void __fastcall TMainForm::TypeChange(TObject *Sender) -{ - ShowTable(); -} +void __fastcall TMainForm::TypeChange(TObject *Sender) { ShowTable(); } //--------------------------------------------------------------------------- -void __fastcall TMainForm::Timer2Timer(TObject *Sender) -{ - if (!GoogleMapView->GetState()) return; - UpdateMap(); - Timer2->Enabled=false; +void __fastcall TMainForm::Timer2Timer(TObject *Sender) { + if (!GoogleMapView->GetState()) return; + UpdateMap(); + Timer2->Enabled = false; } //--------------------------------------------------------------------------- -void __fastcall TMainForm::Table0MouseDown(TObject *Sender, - TMouseButton Button, TShiftState Shift, int X, int Y) -{ - AnsiString title; - double lat,lon; - int col,row; - Table0->MouseToCell(X,Y,col,row); - if (row==0) SortTable(Table0,col); +void __fastcall TMainForm::Table0MouseDown(TObject *Sender, TMouseButton Button, TShiftState Shift, + int X, int Y) { + AnsiString title; + double lat, lon; + int col, row; + Table0->MouseToCell(X, Y, col, row); + if (row == 0) SortTable(Table0, col); } //--------------------------------------------------------------------------- -void __fastcall TMainForm::Table1MouseDown(TObject *Sender, - TMouseButton Button, TShiftState Shift, int X, int Y) -{ - int col,row; - Table1->MouseToCell(X,Y,col,row); - if (row==0) SortTable(Table1,col); +void __fastcall TMainForm::Table1MouseDown(TObject *Sender, TMouseButton Button, TShiftState Shift, + int X, int Y) { + int col, row; + Table1->MouseToCell(X, Y, col, row); + if (row == 0) SortTable(Table1, col); } //--------------------------------------------------------------------------- -void __fastcall TMainForm::Table2MouseDown(TObject *Sender, - TMouseButton Button, TShiftState Shift, int X, int Y) -{ - int col,row; - Table2->MouseToCell(X,Y,col,row); - if (row==0) SortTable(Table2,col); +void __fastcall TMainForm::Table2MouseDown(TObject *Sender, TMouseButton Button, TShiftState Shift, + int X, int Y) { + int col, row; + Table2->MouseToCell(X, Y, col, row); + if (row == 0) SortTable(Table2, col); } //--------------------------------------------------------------------------- -void __fastcall TMainForm::UpdateCaster(void) -{ - AnsiString Address_Text=Address->Text; - AnsiString text,item[3]; - char buff[MAXLINE],*p,*q,*r,*srctbl; - const char *addr=NTRIP_HOME; - int i,n; - - if (Address_Text!="") addr=Address_Text.c_str(); - - if (!(srctbl=getsrctbl(addr))) return; - - text=Address->Text; Address->Clear(); Address->Text=text; - Address->AddItem("",NULL); - for (p=srctbl;*p;p=q+1) { - if (!(q=strchr(p,'\n'))) break; - n=q-pAddItem(item[1]+":"+item[2],NULL); - } - if (Address->Items->Count>1) Address->Text=Address->Items->Strings[1]; +void __fastcall TMainForm::UpdateCaster(void) { + AnsiString Address_Text = Address->Text; + AnsiString text, item[3]; + char buff[MAXLINE], *p, *q, *r, *srctbl; + const char *addr = NTRIP_HOME; + int i, n; -} -//--------------------------------------------------------------------------- -void __fastcall TMainForm::UpdateTable(void) -{ - AnsiString Address_Text=Address->Text; - char *srctbl; - const char *addr=NTRIP_HOME; + if (Address_Text != "") addr = Address_Text.c_str(); - if (Address_Text!="") addr=Address_Text.c_str(); + if (!(srctbl = getsrctbl(addr))) return; - if ((srctbl=getsrctbl(addr))) { - SrcTable=srctbl; - AddrCaster=Address->Text; - } - ShowTable(); -} -//--------------------------------------------------------------------------- -void __fastcall TMainForm::ShowTable(void) -{ - const char *ti[][19]={ - {"No","Mountpoint","ID","Format","Format-Details","Carrier","Nav-System", - "Network","Country","Latitude","Longitude","NMEA","Solution", - "Generator","Compr-Encrp","Authentication","Fee","Bitrate",""}, - {"No","Host","Port","ID","Operator","NMEA","Country","Latitude","Longitude", - "Fallback_Host","Fallback_Port","","","","","","","",""}, - {"No","ID","Operator","Authentication","Fee","Web-Net","Web-Str","Web-Reg", - "","","","","","","","","","",""} - }; - TStringGrid *table[]={Table0,Table1,Table2}; - TMenuItem *menu[]={MenuViewStr,MenuViewCas,MenuViewNet,MenuViewSrc}; - char buff[MAXLINE],no[16],*p,*q,*r,*s; - int i,j,n,ns,type; - - Table3->Visible=false; for (i=0;i<3;i++) table[i]->Visible=false; - - type=TypeStr->Down?0:(TypeCas->Down?1:(TypeNet->Down?2:3)); - for (i=0;i<4;i++) menu[i]->Checked=i==type; - - if (type==3) { - Table3->Visible=true; - Table3->Text=""; - } - else { - table[type]->Visible=true; - table[type]->RowCount=2; - for (i=0;i<18;i++) { - table[type]->Cells[i][0]=ti[type][i]; - table[type]->Cells[i][1]=""; - } - } - if (AddrCaster!=Address->Text) return; - if (type==3) { - Table3->Text=SrcTable; - return; - } - for (p=SrcTable.c_str(),ns=0;*p;p=q+1) { - if (!(q=strchr(p,'\n'))) break; - switch (type) { - case 0: if (!strncmp(p,"STR",3)) ns++; break; - case 1: if (!strncmp(p,"CAS",3)) ns++; break; - case 2: if (!strncmp(p,"NET",3)) ns++; break; - } - } - if (ns<=0) return; - table[type]->RowCount=ns+1; - for (p=SrcTable.c_str(),j=1;*p;p=q+1) { - if (!(q=strchr(p,'\n'))) break; - n=q-p 0 && p[n - 1] == '\r') n--; - strncpy(buff,p,n); buff[n]='\0'; - switch (type) { - case 0: if (!strncmp(buff,"STR",3)) break; else continue; - case 1: if (!strncmp(buff,"CAS",3)) break; else continue; - case 2: if (!strncmp(buff,"NET",3)) break; else continue; - } - sprintf(no,"%d",j); - table[type]->Cells[0][j]=no; - - for (i=0,r=buff;i<19&&*r;i++) { - - if ((s=strchr(r,';'))) { - *s='\0'; if (i>0) table[type]->Cells[i][j]=r; r=s+1; - } - else { - if (i>0) table[type]->Cells[i][j]=r; - break; - } - } - j++; - } - UpdateMap(); + text = Address->Text; + Address->Clear(); + Address->Text = text; + Address->AddItem("", NULL); + for (p = srctbl; *p; p = q + 1) { + if (!(q = strchr(p, '\n'))) break; + n = q - p < MAXLINE - 1 ? q - p : MAXLINE - 1; + strncpy(buff, p, n); + buff[n] = '\0'; + if (strncmp(buff, "CAS", 3)) continue; + char *sptr; + for (i = 0, r = strtok_r(buff, ";", &sptr); i < 3 && r; i++, r = strtok_r(NULL, ";", &sptr)) + item[i] = r; + Address->AddItem(item[1] + ":" + item[2], NULL); + } + if (Address->Items->Count > 1) Address->Text = Address->Items->Strings[1]; } //--------------------------------------------------------------------------- -void __fastcall TMainForm::SortTable(TStringGrid *table, int col) -{ - double v1,v2; - for (int i=1;iRowCount;i++) { - int j=i; - for (int k=i+1;kRowCount;k++) { - AnsiString Cell1=table->Cells[col][j]; - AnsiString Cell2=table->Cells[col][k]; - char *s1=Cell1.c_str(); - char *s2=Cell2.c_str(); - if (sscanf(s1,"%lf",&v1)&&sscanf(s2,"%lf",&v2)) { - if (v1>v2) j=k; - } - else if (strcmp(s1,s2)>0) j=k; - } - if (j==i) continue; - for (int k=0;kColCount;k++) { - AnsiString s=table->Cells[k][i]; - table->Cells[k][i]=table->Cells[k][j]; - table->Cells[k][j]=s; - } - } +void __fastcall TMainForm::UpdateTable(void) { + AnsiString Address_Text = Address->Text; + char *srctbl; + const char *addr = NTRIP_HOME; + + if (Address_Text != "") addr = Address_Text.c_str(); + + if ((srctbl = getsrctbl(addr))) { + SrcTable = srctbl; + AddrCaster = Address->Text; + } + ShowTable(); +} +//--------------------------------------------------------------------------- +void __fastcall TMainForm::ShowTable(void) { + const char *ti[][19] = { + {"No", "Mountpoint", "ID", "Format", "Format-Details", "Carrier", "Nav-System", "Network", + "Country", "Latitude", "Longitude", "NMEA", "Solution", "Generator", "Compr-Encrp", + "Authentication", "Fee", "Bitrate", ""}, + {"No", "Host", "Port", "ID", "Operator", "NMEA", "Country", "Latitude", "Longitude", + "Fallback_Host", "Fallback_Port", "", "", "", "", "", "", "", ""}, + {"No", "ID", "Operator", "Authentication", "Fee", "Web-Net", "Web-Str", "Web-Reg", "", "", "", + "", "", "", "", "", "", "", ""}}; + TStringGrid *table[] = {Table0, Table1, Table2}; + TMenuItem *menu[] = {MenuViewStr, MenuViewCas, MenuViewNet, MenuViewSrc}; + char buff[MAXLINE], no[16], *p, *q, *r, *s; + int i, j, n, ns, type; + + Table3->Visible = false; + for (i = 0; i < 3; i++) table[i]->Visible = false; + + type = TypeStr->Down ? 0 : (TypeCas->Down ? 1 : (TypeNet->Down ? 2 : 3)); + for (i = 0; i < 4; i++) menu[i]->Checked = i == type; + + if (type == 3) { + Table3->Visible = true; + Table3->Text = ""; + } else { + table[type]->Visible = true; + table[type]->RowCount = 2; + for (i = 0; i < 18; i++) { + table[type]->Cells[i][0] = ti[type][i]; + table[type]->Cells[i][1] = ""; + } + } + if (AddrCaster != Address->Text) return; + if (type == 3) { + Table3->Text = SrcTable; + return; + } + for (p = SrcTable.c_str(), ns = 0; *p; p = q + 1) { + if (!(q = strchr(p, '\n'))) break; + switch (type) { + case 0: + if (!strncmp(p, "STR", 3)) ns++; + break; + case 1: + if (!strncmp(p, "CAS", 3)) ns++; + break; + case 2: + if (!strncmp(p, "NET", 3)) ns++; + break; + } + } + if (ns <= 0) return; + table[type]->RowCount = ns + 1; + for (p = SrcTable.c_str(), j = 1; *p; p = q + 1) { + if (!(q = strchr(p, '\n'))) break; + n = q - p < MAXLINE - 1 ? q - p : MAXLINE - 1; + // Strip a trailing carriage return. + if (n > 0 && p[n - 1] == '\r') n--; + strncpy(buff, p, n); + buff[n] = '\0'; + switch (type) { + case 0: + if (!strncmp(buff, "STR", 3)) + break; + else + continue; + case 1: + if (!strncmp(buff, "CAS", 3)) + break; + else + continue; + case 2: + if (!strncmp(buff, "NET", 3)) + break; + else + continue; + } + sprintf(no, "%d", j); + table[type]->Cells[0][j] = no; + + for (i = 0, r = buff; i < 19 && *r; i++) { + if ((s = strchr(r, ';'))) { + *s = '\0'; + if (i > 0) table[type]->Cells[i][j] = r; + r = s + 1; + } else { + if (i > 0) table[type]->Cells[i][j] = r; + break; + } + } + j++; + } + UpdateMap(); +} +//--------------------------------------------------------------------------- +void __fastcall TMainForm::SortTable(TStringGrid *table, int col) { + double v1, v2; + for (int i = 1; i < table->RowCount; i++) { + int j = i; + for (int k = i + 1; k < table->RowCount; k++) { + AnsiString Cell1 = table->Cells[col][j]; + AnsiString Cell2 = table->Cells[col][k]; + char *s1 = Cell1.c_str(); + char *s2 = Cell2.c_str(); + if (sscanf(s1, "%lf", &v1) && sscanf(s2, "%lf", &v2)) { + if (v1 > v2) j = k; + } else if (strcmp(s1, s2) > 0) + j = k; + } + if (j == i) continue; + for (int k = 0; k < table->ColCount; k++) { + AnsiString s = table->Cells[k][i]; + table->Cells[k][i] = table->Cells[k][j]; + table->Cells[k][j] = s; + } + } } //--------------------------------------------------------------------------- -void __fastcall TMainForm::ShowMsg(const char *msg) -{ - AnsiString str=msg; - Message->Caption=str; - Application->ProcessMessages(); +void __fastcall TMainForm::ShowMsg(const char *msg) { + AnsiString str = msg; + Message->Caption = str; + Application->ProcessMessages(); } //--------------------------------------------------------------------------- -void __fastcall TMainForm::UpdateMap(void) -{ - AnsiString title,msg,LatText,LonText; - double lat,lon; - - if (Address->Text=="") { - GoogleMapView->Caption="NTRIP Data Stream Map"; - } - else { - GoogleMapView->Caption="NTRIP Data Stream Map: "+Address->Text; - } - GoogleMapView->ClearMark(); - - for (int i=1;iRowCount;i++) { - if (Table0->Cells[9][i]=="") continue; - LatText=Table0->Cells[9][i]; - LonText=Table0->Cells[10][i]; - lat=str2dbl(LatText); - lon=str2dbl(LonText); - title=Table0->Cells[1][i]; - msg=""+Table0->Cells[1][i]+": "+Table0->Cells[2][i]+" ("+Table0->Cells[8][i]+")
"+ - "Format: "+Table0->Cells[3][i]+", "+Table0->Cells[4][i]+",
"+ - "Nav-Sys: "+Table0->Cells[6][i]+"
"+ - "Network: "+Table0->Cells[7][i]+"
"+ - "Latitude/Longitude: "+Table0->Cells[9][i]+", "+Table0->Cells[10][i]+"
"+ - "Generator: "+Table0->Cells[13][i]; - GoogleMapView->AddMark(lat,lon,title,msg); - } +void __fastcall TMainForm::UpdateMap(void) { + AnsiString title, msg, LatText, LonText; + double lat, lon; + + if (Address->Text == "") { + GoogleMapView->Caption = "NTRIP Data Stream Map"; + } else { + GoogleMapView->Caption = "NTRIP Data Stream Map: " + Address->Text; + } + GoogleMapView->ClearMark(); + + for (int i = 1; i < Table0->RowCount; i++) { + if (Table0->Cells[9][i] == "") continue; + LatText = Table0->Cells[9][i]; + LonText = Table0->Cells[10][i]; + lat = str2dbl(LatText); + lon = str2dbl(LonText); + title = Table0->Cells[1][i]; + msg = "" + Table0->Cells[1][i] + ": " + Table0->Cells[2][i] + " (" + + Table0->Cells[8][i] + ")
" + "Format: " + Table0->Cells[3][i] + ", " + + Table0->Cells[4][i] + ",
" + "Nav-Sys: " + Table0->Cells[6][i] + "
" + + "Network: " + Table0->Cells[7][i] + "
" + + "Latitude/Longitude: " + Table0->Cells[9][i] + ", " + Table0->Cells[10][i] + "
" + + "Generator: " + Table0->Cells[13][i]; + GoogleMapView->AddMark(lat, lon, title, msg); + } } //--------------------------------------------------------------------------- -void __fastcall TMainForm::BtnStaClick(TObject *Sender) -{ - if (StaListDialog->ShowModal()!=mrOk) return; +void __fastcall TMainForm::BtnStaClick(TObject *Sender) { + if (StaListDialog->ShowModal() != mrOk) return; } //--------------------------------------------------------------------------- -void __fastcall TMainForm::UpdateEnable(void) -{ - BtnSta->Enabled=StaMask->Checked; -} +void __fastcall TMainForm::UpdateEnable(void) { BtnSta->Enabled = StaMask->Checked; } //--------------------------------------------------------------------------- -void __fastcall TMainForm::StaMaskClick(TObject *Sender) -{ - UpdateEnable(); -} +void __fastcall TMainForm::StaMaskClick(TObject *Sender) { UpdateEnable(); } //--------------------------------------------------------------------------- -void __fastcall TMainForm::AddressCloseUp(TObject *Sender) -{ - TComboBox *combo=(TComboBox *)Sender; +void __fastcall TMainForm::AddressCloseUp(TObject *Sender) { + TComboBox *combo = (TComboBox *)Sender; - ::PostMessage(combo->Handle,CB_SETEDITSEL,-1,0); + ::PostMessage(combo->Handle, CB_SETEDITSEL, -1, 0); } //--------------------------------------------------------------------------- - diff --git a/app/winapp/srctblbrows/browsmain.h b/app/winapp/srctblbrows/browsmain.h index 4236d495a..80e01dfa3 100644 --- a/app/winapp/srctblbrows/browsmain.h +++ b/app/winapp/srctblbrows/browsmain.h @@ -2,111 +2,110 @@ #ifndef browsmainH #define browsmainH //--------------------------------------------------------------------------- +#include #include +#include #include -#include -#include +#include #include +#include #include -#include -#include -#include #include +#include //--------------------------------------------------------------------------- -class TMainForm : public TForm -{ -__published: - TPanel *Panel1; - TStringGrid *Table0; - TComboBox *Address; - TStringGrid *Table1; - TStringGrid *Table2; - TMemo *Table3; - TSpeedButton *BtnList; - TSpeedButton *BtnUpdate; - TSaveDialog *SaveDialog; - TOpenDialog *OpenDialog; - TMainMenu *MainMenu; - TMenuItem *File1; - TMenuItem *MenuOpen; - TMenuItem *MenuSave; - TMenuItem *N1; - TMenuItem *MenuQuit; - TMenuItem *Edit1; - TMenuItem *View1; - TMenuItem *MenuUpdateCaster; - TMenuItem *N2; - TMenuItem *MenuUpdateTable; - TMenuItem *Help1; - TMenuItem *MenuViewStr; - TMenuItem *MenuViewCas; - TMenuItem *MenuViewNet; - TMenuItem *N3; - TMenuItem *MenuViewSrc; - TMenuItem *MenuAbout; - TSpeedButton *TypeStr; - TSpeedButton *TypeCas; - TSpeedButton *TypeNet; - TSpeedButton *TypeSrc; - TPanel *Panel2; - TLabel *Message; - TPanel *Panel3; - TSpeedButton *BtnMap; - TTimer *Timer2; - TComboBox *FiltFmt; - TCheckBox *StaMask; - TButton *BtnSta; - TTimer *Timer1; - - void __fastcall FormShow(TObject *Sender); - void __fastcall BtnUpdateClick(TObject *Sender); - void __fastcall TypeChange(TObject *Sender); - void __fastcall BtnListClick(TObject *Sender); - void __fastcall AddressChange(TObject *Sender); - void __fastcall FormClose(TObject *Sender, TCloseAction &Action); - void __fastcall Table1MouseDown(TObject *Sender, TMouseButton Button, - TShiftState Shift, int X, int Y); - void __fastcall Table2MouseDown(TObject *Sender, TMouseButton Button, - TShiftState Shift, int X, int Y); - void __fastcall Table0MouseDown(TObject *Sender, TMouseButton Button, - TShiftState Shift, int X, int Y); - void __fastcall AddressKeyPress(TObject *Sender, char &Key); - void __fastcall MenuOpenClick(TObject *Sender); - void __fastcall MenuSaveClick(TObject *Sender); - void __fastcall MenuQuitClick(TObject *Sender); - void __fastcall MenuUpdateCasterClick(TObject *Sender); - void __fastcall MenuUpdateTableClick(TObject *Sender); - void __fastcall MenuViewStrClick(TObject *Sender); - void __fastcall MenuViewCasClick(TObject *Sender); - void __fastcall MenuViewNetClick(TObject *Sender); - void __fastcall MenuViewSrcClick(TObject *Sender); - void __fastcall MenuAboutClick(TObject *Sender); - void __fastcall TypeStrClick(TObject *Sender); - void __fastcall TypeCasClick(TObject *Sender); - void __fastcall TypeNetClick(TObject *Sender); - void __fastcall TypeSrcClick(TObject *Sender); - void __fastcall BtnMapClick(TObject *Sender); - void __fastcall Timer2Timer(TObject *Sender); - void __fastcall Table0SelectCell(TObject *Sender, int ACol, int ARow, bool &CanSelect); - void __fastcall BtnStaClick(TObject *Sender); - void __fastcall StaMaskClick(TObject *Sender); - void __fastcall AddressCloseUp(TObject *Sender); - void __fastcall Timer1Timer(TObject *Sender); +class TMainForm : public TForm { + __published : TPanel *Panel1; + TStringGrid *Table0; + TComboBox *Address; + TStringGrid *Table1; + TStringGrid *Table2; + TMemo *Table3; + TSpeedButton *BtnList; + TSpeedButton *BtnUpdate; + TSaveDialog *SaveDialog; + TOpenDialog *OpenDialog; + TMainMenu *MainMenu; + TMenuItem *File1; + TMenuItem *MenuOpen; + TMenuItem *MenuSave; + TMenuItem *N1; + TMenuItem *MenuQuit; + TMenuItem *Edit1; + TMenuItem *View1; + TMenuItem *MenuUpdateCaster; + TMenuItem *N2; + TMenuItem *MenuUpdateTable; + TMenuItem *Help1; + TMenuItem *MenuViewStr; + TMenuItem *MenuViewCas; + TMenuItem *MenuViewNet; + TMenuItem *N3; + TMenuItem *MenuViewSrc; + TMenuItem *MenuAbout; + TSpeedButton *TypeStr; + TSpeedButton *TypeCas; + TSpeedButton *TypeNet; + TSpeedButton *TypeSrc; + TPanel *Panel2; + TLabel *Message; + TPanel *Panel3; + TSpeedButton *BtnMap; + TTimer *Timer2; + TComboBox *FiltFmt; + TCheckBox *StaMask; + TButton *BtnSta; + TTimer *Timer1; + + void __fastcall FormShow(TObject *Sender); + void __fastcall BtnUpdateClick(TObject *Sender); + void __fastcall TypeChange(TObject *Sender); + void __fastcall BtnListClick(TObject *Sender); + void __fastcall AddressChange(TObject *Sender); + void __fastcall FormClose(TObject *Sender, TCloseAction &Action); + void __fastcall Table1MouseDown(TObject *Sender, TMouseButton Button, TShiftState Shift, int X, + int Y); + void __fastcall Table2MouseDown(TObject *Sender, TMouseButton Button, TShiftState Shift, int X, + int Y); + void __fastcall Table0MouseDown(TObject *Sender, TMouseButton Button, TShiftState Shift, int X, + int Y); + void __fastcall AddressKeyPress(TObject *Sender, char &Key); + void __fastcall MenuOpenClick(TObject *Sender); + void __fastcall MenuSaveClick(TObject *Sender); + void __fastcall MenuQuitClick(TObject *Sender); + void __fastcall MenuUpdateCasterClick(TObject *Sender); + void __fastcall MenuUpdateTableClick(TObject *Sender); + void __fastcall MenuViewStrClick(TObject *Sender); + void __fastcall MenuViewCasClick(TObject *Sender); + void __fastcall MenuViewNetClick(TObject *Sender); + void __fastcall MenuViewSrcClick(TObject *Sender); + void __fastcall MenuAboutClick(TObject *Sender); + void __fastcall TypeStrClick(TObject *Sender); + void __fastcall TypeCasClick(TObject *Sender); + void __fastcall TypeNetClick(TObject *Sender); + void __fastcall TypeSrcClick(TObject *Sender); + void __fastcall BtnMapClick(TObject *Sender); + void __fastcall Timer2Timer(TObject *Sender); + void __fastcall Table0SelectCell(TObject *Sender, int ACol, int ARow, bool &CanSelect); + void __fastcall BtnStaClick(TObject *Sender); + void __fastcall StaMaskClick(TObject *Sender); + void __fastcall AddressCloseUp(TObject *Sender); + void __fastcall Timer1Timer(TObject *Sender); + + private: + AnsiString AddrList, AddrCaster, SrcTable, IniFile; + int FontScale; + void __fastcall UpdateCaster(void); + void __fastcall UpdateTable(void); + void __fastcall UpdateMap(void); + void __fastcall UpdateEnable(void); + void __fastcall ShowTable(void); + void __fastcall SortTable(TStringGrid *table, int col); -private: - AnsiString AddrList,AddrCaster,SrcTable,IniFile; - int FontScale; - void __fastcall UpdateCaster(void); - void __fastcall UpdateTable(void); - void __fastcall UpdateMap(void); - void __fastcall UpdateEnable(void); - void __fastcall ShowTable(void); - void __fastcall SortTable(TStringGrid *table, int col); -public: - TStringList *StaList; + public: + TStringList *StaList; - void __fastcall ShowMsg(const char *msg); - __fastcall TMainForm(TComponent* Owner); + void __fastcall ShowMsg(const char *msg); + __fastcall TMainForm(TComponent *Owner); }; //--------------------------------------------------------------------------- extern PACKAGE TMainForm *MainForm; diff --git a/app/winapp/srctblbrows/srctblbrows.cpp b/app/winapp/srctblbrows/srctblbrows.cpp index d3bd463eb..254445405 100644 --- a/app/winapp/srctblbrows/srctblbrows.cpp +++ b/app/winapp/srctblbrows/srctblbrows.cpp @@ -4,48 +4,29 @@ #pragma hdrstop //--------------------------------------------------------------------------- - - - - - - - - - - USEFORM("staoptdlg.cpp", StaListDialog); USEFORM("..\appcmn\aboutdlg.cpp", AboutDialog); USEFORM("..\appcmn\gmview.cpp", GoogleMapView); USEFORM("browsmain.cpp", MainForm); //--------------------------------------------------------------------------- -int WINAPI WinMain(HINSTANCE, HINSTANCE, LPSTR, int) -{ - try - { - Application->Initialize(); - Application->Title = "NTRIP Source Table Browser"; - Application->CreateForm(__classid(TMainForm), &MainForm); - Application->CreateForm(__classid(TAboutDialog), &AboutDialog); - Application->CreateForm(__classid(TGoogleMapView), &GoogleMapView); - Application->CreateForm(__classid(TStaListDialog), &StaListDialog); - Application->Run(); - } - catch (Exception &exception) - { - Application->ShowException(&exception); - } - catch (...) - { - try - { - throw Exception(""); - } - catch (Exception &exception) - { - Application->ShowException(&exception); - } - } - return 0; +int WINAPI WinMain(HINSTANCE, HINSTANCE, LPSTR, int) { + try { + Application->Initialize(); + Application->Title = "NTRIP Source Table Browser"; + Application->CreateForm(__classid(TMainForm), &MainForm); + Application->CreateForm(__classid(TAboutDialog), &AboutDialog); + Application->CreateForm(__classid(TGoogleMapView), &GoogleMapView); + Application->CreateForm(__classid(TStaListDialog), &StaListDialog); + Application->Run(); + } catch (Exception &exception) { + Application->ShowException(&exception); + } catch (...) { + try { + throw Exception(""); + } catch (Exception &exception) { + Application->ShowException(&exception); + } + } + return 0; } //--------------------------------------------------------------------------- diff --git a/app/winapp/srctblbrows/staoptdlg.cpp b/app/winapp/srctblbrows/staoptdlg.cpp index 7638ecbbd..570ab0ddd 100644 --- a/app/winapp/srctblbrows/staoptdlg.cpp +++ b/app/winapp/srctblbrows/staoptdlg.cpp @@ -3,65 +3,58 @@ #include #pragma hdrstop -#include "browsmain.h" #include "staoptdlg.h" + +#include "browsmain.h" //--------------------------------------------------------------------------- #pragma package(smart_init) #pragma resource "*.dfm" TStaListDialog *StaListDialog; //--------------------------------------------------------------------------- -__fastcall TStaListDialog::TStaListDialog(TComponent* Owner) - : TForm(Owner) -{ -} +__fastcall TStaListDialog::TStaListDialog(TComponent *Owner) : TForm(Owner) {} //--------------------------------------------------------------------------- -void __fastcall TStaListDialog::FormShow(TObject *Sender) -{ - StaList->Clear(); - - for (int i=0;iStaList->Count;i++) { - StaList->Lines->Add(MainForm->StaList->Strings[i]); - } +void __fastcall TStaListDialog::FormShow(TObject *Sender) { + StaList->Clear(); + + for (int i = 0; i < MainForm->StaList->Count; i++) { + StaList->Lines->Add(MainForm->StaList->Strings[i]); + } } //--------------------------------------------------------------------------- -void __fastcall TStaListDialog::BtnOkClick(TObject *Sender) -{ - MainForm->StaList->Clear(); - - for (int i=0;iLines->Count;i++) { - MainForm->StaList->Add(StaList->Lines->Strings[i]); - } +void __fastcall TStaListDialog::BtnOkClick(TObject *Sender) { + MainForm->StaList->Clear(); + + for (int i = 0; i < StaList->Lines->Count; i++) { + MainForm->StaList->Add(StaList->Lines->Strings[i]); + } } //--------------------------------------------------------------------------- -void __fastcall TStaListDialog::BtnLoadClick(TObject *Sender) -{ - AnsiString file; - FILE *fp; - char buff[1024],*p; - - if (!OpenDialog->Execute()) return; - - file=OpenDialog->FileName; - - if (!(fp=fopen(file.c_str(),"r"))) return; - - StaList->Clear(); - StaList->Visible=false; - - while (fgets(buff,sizeof(buff),fp)) { - if ((p=strchr(buff,'#'))) *p='\0'; - for (p=strtok(buff," ,\r\n");p;p=strtok(NULL," ,\r\n")) { - StaList->Lines->Add(p); - } +void __fastcall TStaListDialog::BtnLoadClick(TObject *Sender) { + AnsiString file; + FILE *fp; + char buff[1024], *p; + + if (!OpenDialog->Execute()) return; + + file = OpenDialog->FileName; + + if (!(fp = fopen(file.c_str(), "r"))) return; + + StaList->Clear(); + StaList->Visible = false; + + while (fgets(buff, sizeof(buff), fp)) { + if ((p = strchr(buff, '#'))) *p = '\0'; + for (p = strtok(buff, " ,\r\n"); p; p = strtok(NULL, " ,\r\n")) { + StaList->Lines->Add(p); } - fclose(fp); - StaList->Visible=true; + } + fclose(fp); + StaList->Visible = true; } //--------------------------------------------------------------------------- -void __fastcall TStaListDialog::BtnSaveClick(TObject *Sender) -{ - if (!SaveDialog->Execute()) return; - StaList->Lines->SaveToFile(SaveDialog->FileName); +void __fastcall TStaListDialog::BtnSaveClick(TObject *Sender) { + if (!SaveDialog->Execute()) return; + StaList->Lines->SaveToFile(SaveDialog->FileName); } //--------------------------------------------------------------------------- - diff --git a/app/winapp/srctblbrows/staoptdlg.h b/app/winapp/srctblbrows/staoptdlg.h index 1d8633237..898867714 100644 --- a/app/winapp/srctblbrows/staoptdlg.h +++ b/app/winapp/srctblbrows/staoptdlg.h @@ -4,29 +4,28 @@ //--------------------------------------------------------------------------- #include #include -#include -#include -#include #include +#include +#include +#include //--------------------------------------------------------------------------- -class TStaListDialog : public TForm -{ -__published: - TPanel *Panel1; - TButton *BtnLoad; - TButton *BtnSave; - TButton *BtnOk; - TButton *BtnCancel; - TMemo *StaList; - TOpenDialog *OpenDialog; - TSaveDialog *SaveDialog; - void __fastcall BtnLoadClick(TObject *Sender); - void __fastcall BtnOkClick(TObject *Sender); - void __fastcall FormShow(TObject *Sender); - void __fastcall BtnSaveClick(TObject *Sender); -private: -public: - __fastcall TStaListDialog(TComponent* Owner); +class TStaListDialog : public TForm { + __published : TPanel *Panel1; + TButton *BtnLoad; + TButton *BtnSave; + TButton *BtnOk; + TButton *BtnCancel; + TMemo *StaList; + TOpenDialog *OpenDialog; + TSaveDialog *SaveDialog; + void __fastcall BtnLoadClick(TObject *Sender); + void __fastcall BtnOkClick(TObject *Sender); + void __fastcall FormShow(TObject *Sender); + void __fastcall BtnSaveClick(TObject *Sender); + + private: + public: + __fastcall TStaListDialog(TComponent *Owner); }; //--------------------------------------------------------------------------- extern PACKAGE TStaListDialog *StaListDialog; diff --git a/app/winapp/strsvr/convdlg.cpp b/app/winapp/strsvr/convdlg.cpp index 2510ec610..c9360c1c0 100644 --- a/app/winapp/strsvr/convdlg.cpp +++ b/app/winapp/strsvr/convdlg.cpp @@ -2,61 +2,52 @@ #include #pragma hdrstop -#include "rtklib.h" #include "convdlg.h" + +#include "rtklib.h" //--------------------------------------------------------------------------- #pragma package(smart_init) #pragma resource "*.dfm" TConvDialog *ConvDialog; //--------------------------------------------------------------------------- -static double str2dbl(AnsiString str) -{ - double val=0.0; - sscanf(str.c_str(),"%lf",&val); - return val; +static double str2dbl(AnsiString str) { + double val = 0.0; + sscanf(str.c_str(), "%lf", &val); + return val; } //--------------------------------------------------------------------------- -__fastcall TConvDialog::TConvDialog(TComponent* Owner) - : TForm(Owner) -{ - int i; - for (i=0;i<=MAXRCVFMT;i++) { - InFormat->Items->Add(formatstrs[i]); - } - InFormat->ItemIndex=0; +__fastcall TConvDialog::TConvDialog(TComponent *Owner) : TForm(Owner) { + int i; + for (i = 0; i <= MAXRCVFMT; i++) { + InFormat->Items->Add(formatstrs[i]); + } + InFormat->ItemIndex = 0; } //--------------------------------------------------------------------------- -void __fastcall TConvDialog::FormShow(TObject *Sender) -{ - AnsiString s; - Conversion->Checked=ConvEna; - InFormat ->ItemIndex=ConvInp; - OutFormat->ItemIndex=ConvOut; - OutMsgs->Text=ConvMsg; - Options->Text=ConvOpt; - UpdateEnable(); +void __fastcall TConvDialog::FormShow(TObject *Sender) { + AnsiString s; + Conversion->Checked = ConvEna; + InFormat->ItemIndex = ConvInp; + OutFormat->ItemIndex = ConvOut; + OutMsgs->Text = ConvMsg; + Options->Text = ConvOpt; + UpdateEnable(); } //--------------------------------------------------------------------------- -void __fastcall TConvDialog::BtnOkClick(TObject *Sender) -{ - ConvEna=Conversion->Checked; - ConvInp=InFormat->ItemIndex; - ConvOut=OutFormat->ItemIndex; - ConvMsg=OutMsgs->Text; - ConvOpt=Options->Text; +void __fastcall TConvDialog::BtnOkClick(TObject *Sender) { + ConvEna = Conversion->Checked; + ConvInp = InFormat->ItemIndex; + ConvOut = OutFormat->ItemIndex; + ConvMsg = OutMsgs->Text; + ConvOpt = Options->Text; } //--------------------------------------------------------------------------- -void __fastcall TConvDialog::ConversionClick(TObject *Sender) -{ - UpdateEnable(); -} +void __fastcall TConvDialog::ConversionClick(TObject *Sender) { UpdateEnable(); } //--------------------------------------------------------------------------- -void __fastcall TConvDialog::UpdateEnable(void) -{ - InFormat ->Enabled=Conversion->Checked; - OutFormat->Enabled=Conversion->Checked; - OutMsgs ->Enabled=Conversion->Checked; - Options ->Enabled=Conversion->Checked; +void __fastcall TConvDialog::UpdateEnable(void) { + InFormat->Enabled = Conversion->Checked; + OutFormat->Enabled = Conversion->Checked; + OutMsgs->Enabled = Conversion->Checked; + Options->Enabled = Conversion->Checked; } //--------------------------------------------------------------------------- - diff --git a/app/winapp/strsvr/convdlg.h b/app/winapp/strsvr/convdlg.h index 381447cb7..a44a5773f 100644 --- a/app/winapp/strsvr/convdlg.h +++ b/app/winapp/strsvr/convdlg.h @@ -4,35 +4,35 @@ //--------------------------------------------------------------------------- #include #include -#include -#include #include +#include +#include #include //--------------------------------------------------------------------------- -class TConvDialog : public TForm -{ -__published: - TButton *BtnOk; - TButton *BtnCancel; - TCheckBox *Conversion; - TComboBox *InFormat; - TComboBox *OutFormat; - TLabel *Label2; - TLabel *Label10; - TEdit *Options; - TLabel *Label4; - TEdit *OutMsgs; - void __fastcall BtnOkClick(TObject *Sender); - void __fastcall ConversionClick(TObject *Sender); - void __fastcall FormShow(TObject *Sender); -private: - void __fastcall UpdateEnable(void); -public: - AnsiString ConvMsg,ConvOpt,AntType,RcvType; - int ConvEna,ConvInp,ConvOut,StaId; - double AntPos[3],AntOff[3]; - - __fastcall TConvDialog(TComponent* Owner); +class TConvDialog : public TForm { + __published : TButton *BtnOk; + TButton *BtnCancel; + TCheckBox *Conversion; + TComboBox *InFormat; + TComboBox *OutFormat; + TLabel *Label2; + TLabel *Label10; + TEdit *Options; + TLabel *Label4; + TEdit *OutMsgs; + void __fastcall BtnOkClick(TObject *Sender); + void __fastcall ConversionClick(TObject *Sender); + void __fastcall FormShow(TObject *Sender); + + private: + void __fastcall UpdateEnable(void); + + public: + AnsiString ConvMsg, ConvOpt, AntType, RcvType; + int ConvEna, ConvInp, ConvOut, StaId; + double AntPos[3], AntOff[3]; + + __fastcall TConvDialog(TComponent *Owner); }; //--------------------------------------------------------------------------- extern PACKAGE TConvDialog *ConvDialog; diff --git a/app/winapp/strsvr/mondlg.cpp b/app/winapp/strsvr/mondlg.cpp index 631c12d86..4774e762d 100644 --- a/app/winapp/strsvr/mondlg.cpp +++ b/app/winapp/strsvr/mondlg.cpp @@ -1,7 +1,8 @@ //--------------------------------------------------------------------------- -#include #include #include +#include + #include #pragma hdrstop @@ -10,199 +11,177 @@ #pragma package(smart_init) #pragma resource "*.dfm" -#define MAXLEN 200 -#define MAXLINE 2048 -#define TOPMARGIN 2 -#define LEFTMARGIN 3 +#define MAXLEN 200 +#define MAXLINE 2048 +#define TOPMARGIN 2 +#define LEFTMARGIN 3 TStrMonDialog *StrMonDialog; //--------------------------------------------------------------------------- -__fastcall TStrMonDialog::TStrMonDialog(TComponent* Owner) - : TForm(Owner) -{ - ConBuff=new TStringList; - ConBuff->Add(""); - DoubleBuffered=true; - Stop=0; - ScrollPos=0; - StrFmt=0; - for (int i=0;i<=MAXRCVFMT;i++) { - SelFmt->Items->Add(formatstrs[i]); - } - memset(&rtcm,0,sizeof(rtcm)); - memset(&raw,0,sizeof(raw)); - rtcm.outtype=raw.outtype=1; +__fastcall TStrMonDialog::TStrMonDialog(TComponent *Owner) : TForm(Owner) { + ConBuff = new TStringList; + ConBuff->Add(""); + DoubleBuffered = true; + Stop = 0; + ScrollPos = 0; + StrFmt = 0; + for (int i = 0; i <= MAXRCVFMT; i++) { + SelFmt->Items->Add(formatstrs[i]); + } + memset(&rtcm, 0, sizeof(rtcm)); + memset(&raw, 0, sizeof(raw)); + rtcm.outtype = raw.outtype = 1; } //--------------------------------------------------------------------------- -void __fastcall TStrMonDialog::FormResize(TObject *Sender) -{ - Console->Invalidate(); -} +void __fastcall TStrMonDialog::FormResize(TObject *Sender) { Console->Invalidate(); } //--------------------------------------------------------------------------- -void __fastcall TStrMonDialog::BtnCloseClick(TObject *Sender) -{ - Close(); -} +void __fastcall TStrMonDialog::BtnCloseClick(TObject *Sender) { Close(); } -void __fastcall TStrMonDialog::BtnCopyClick(TObject *Sender) -{ - Clipboard()->AsText = ConBuff->Text; +void __fastcall TStrMonDialog::BtnCopyClick(TObject *Sender) { + Clipboard()->AsText = ConBuff->Text; } //--------------------------------------------------------------------------- -void __fastcall TStrMonDialog::SelFmtChange(TObject *Sender) -{ - if (StrFmt-3==STRFMT_RTCM2||StrFmt-3==STRFMT_RTCM3) { - free_rtcm(&rtcm); - } - else if (StrFmt>=3) { - free_raw(&raw); - } - StrFmt=SelFmt->ItemIndex; - ConBuff->Clear(); - ConBuff->Add(""); - - if (StrFmt-3==STRFMT_RTCM2||StrFmt-3==STRFMT_RTCM3) { - init_rtcm(&rtcm); - rtcm.outtype=1; - } - else if (StrFmt>=3) { - init_raw(&raw,StrFmt-2); - raw.outtype=1; - } - Console->Invalidate(); +void __fastcall TStrMonDialog::SelFmtChange(TObject *Sender) { + if (StrFmt - 3 == STRFMT_RTCM2 || StrFmt - 3 == STRFMT_RTCM3) { + free_rtcm(&rtcm); + } else if (StrFmt >= 3) { + free_raw(&raw); + } + StrFmt = SelFmt->ItemIndex; + ConBuff->Clear(); + ConBuff->Add(""); + + if (StrFmt - 3 == STRFMT_RTCM2 || StrFmt - 3 == STRFMT_RTCM3) { + init_rtcm(&rtcm); + rtcm.outtype = 1; + } else if (StrFmt >= 3) { + init_raw(&raw, StrFmt - 2); + raw.outtype = 1; + } + Console->Invalidate(); } //--------------------------------------------------------------------------- -void __fastcall TStrMonDialog::AddMsg(uint8_t *msg, int len) -{ - char buff[256]; - int i,n; - - if (len<=0) return; - - else if (StrFmt-3==STRFMT_RTCM2) { - for (i=0;i=3) { // raw - for (i=0;i=1) { // HEX/ASC - AddConsole(msg,len,StrFmt-1); - } - else { // Streams - ConBuff->Clear(); - ConBuff->Add(""); - AddConsole(msg,len,1); - } +void __fastcall TStrMonDialog::AddMsg(uint8_t *msg, int len) { + char buff[256]; + int i, n; + + if (len <= 0) + return; + + else if (StrFmt - 3 == STRFMT_RTCM2) { + for (i = 0; i < len; i++) { + input_rtcm2(&rtcm, msg[i]); + if (rtcm.msgtype[0]) { + n = sprintf(buff, "%s\n", rtcm.msgtype); + AddConsole((uint8_t *)buff, n, 1); + rtcm.msgtype[0] = '\0'; + } + } + } else if (StrFmt - 3 == STRFMT_RTCM3) { + for (i = 0; i < len; i++) { + input_rtcm3(&rtcm, msg[i]); + if (rtcm.msgtype[0]) { + n = sprintf(buff, "%s\n", rtcm.msgtype); + AddConsole((uint8_t *)buff, n, 1); + rtcm.msgtype[0] = '\0'; + } + } + } else if (StrFmt >= 3) { // raw + for (i = 0; i < len; i++) { + input_raw(&raw, StrFmt - 3, msg[i]); + if (raw.msgtype[0]) { + n = sprintf(buff, "%s\n", raw.msgtype); + AddConsole((uint8_t *)buff, n, 1); + raw.msgtype[0] = '\0'; + } + } + } else if (StrFmt >= 1) { // HEX/ASC + AddConsole(msg, len, StrFmt - 1); + } else { // Streams + ConBuff->Clear(); + ConBuff->Add(""); + AddConsole(msg, len, 1); + } } //--------------------------------------------------------------------------- -void __fastcall TStrMonDialog::AddConsole(uint8_t *msg, int n, int mode) -{ - AnsiString str=ConBuff->Strings[ConBuff->Count-1]; - char buff[MAXLEN+16],*p=buff,c; - - if (n<=0||Stop) return; - - p+=sprintf(p,"%s",str.c_str()); - - for (int i=0;i= MAXLEN) add = 1; - } - } - else { - if (strlen(buff) % 17 == 16) strcat(p++, " "); - p+=sprintf(p,"%02X",msg[i]); - if (p-buff>=67) add = 1; - } - - if (add) { - ConBuff->Strings[ConBuff->Count-1]=buff; - ConBuff->Add(""); - *(p=buff)=0; - if (ConBuff->Count>=MAXLINE) ConBuff->Delete(0); - } - } - ConBuff->Strings[ConBuff->Count-1]=buff; - Console->Invalidate(); +void __fastcall TStrMonDialog::AddConsole(uint8_t *msg, int n, int mode) { + AnsiString str = ConBuff->Strings[ConBuff->Count - 1]; + char buff[MAXLEN + 16], *p = buff, c; + + if (n <= 0 || Stop) return; + + p += sprintf(p, "%s", str.c_str()); + + for (int i = 0; i < n; i++) { + int add = 0; + if (mode) { + if (msg[i] == '\r') continue; + if (msg[i] == '\n') + add = 1; + else { + p += sprintf(p, "%c", isprint(msg[i]) ? msg[i] : '.'); + if (p - buff >= MAXLEN) add = 1; + } + } else { + if (strlen(buff) % 17 == 16) strcat(p++, " "); + p += sprintf(p, "%02X", msg[i]); + if (p - buff >= 67) add = 1; + } + + if (add) { + ConBuff->Strings[ConBuff->Count - 1] = buff; + ConBuff->Add(""); + *(p = buff) = 0; + if (ConBuff->Count >= MAXLINE) ConBuff->Delete(0); + } + } + ConBuff->Strings[ConBuff->Count - 1] = buff; + Console->Invalidate(); } //--------------------------------------------------------------------------- -void __fastcall TStrMonDialog::ConsolePaint(TObject *Sender) -{ - TCanvas *c=Console->Canvas; - TSize off=c->TextExtent(" "); - int n,m,p,y=TOPMARGIN; - - c->Brush->Style=bsSolid; - c->Brush->Color=clWhite; - c->FillRect(Console->ClientRect); - - n=ConBuff->Count; if (ConBuff->Strings[n-1]=="") n--; - m=(Console->Height-TOPMARGIN*2)/off.cy; - p=m>=n?0:n-m-ScrollPos; - - for (int i=p<0?0:p;iCount;i++,y+=off.cy) { - if (y+off.cy>Console->Height-TOPMARGIN) break; - //c->Font->Color=iFont->Color=clBlack; - c->TextOut(LEFTMARGIN,y,ConBuff->Strings[i]); - } - Scroll->Max=n<=m?m-1:n-m; - Scroll->Position=Scroll->Max-ScrollPos; +void __fastcall TStrMonDialog::ConsolePaint(TObject *Sender) { + TCanvas *c = Console->Canvas; + TSize off = c->TextExtent(" "); + int n, m, p, y = TOPMARGIN; + + c->Brush->Style = bsSolid; + c->Brush->Color = clWhite; + c->FillRect(Console->ClientRect); + + n = ConBuff->Count; + if (ConBuff->Strings[n - 1] == "") n--; + m = (Console->Height - TOPMARGIN * 2) / off.cy; + p = m >= n ? 0 : n - m - ScrollPos; + + for (int i = p < 0 ? 0 : p; i < ConBuff->Count; i++, y += off.cy) { + if (y + off.cy > Console->Height - TOPMARGIN) break; + // c->Font->Color=iFont->Color = clBlack; + c->TextOut(LEFTMARGIN, y, ConBuff->Strings[i]); + } + Scroll->Max = n <= m ? m - 1 : n - m; + Scroll->Position = Scroll->Max - ScrollPos; } //--------------------------------------------------------------------------- -void __fastcall TStrMonDialog::ScrollChange(TObject *Sender) -{ - ScrollPos=Scroll->Max-Scroll->Position; - Console->Invalidate(); +void __fastcall TStrMonDialog::ScrollChange(TObject *Sender) { + ScrollPos = Scroll->Max - Scroll->Position; + Console->Invalidate(); } //--------------------------------------------------------------------------- -void __fastcall TStrMonDialog::BtnClearClick(TObject *Sender) -{ - ConBuff->Clear(); - ConBuff->Add(""); - Console->Invalidate(); +void __fastcall TStrMonDialog::BtnClearClick(TObject *Sender) { + ConBuff->Clear(); + ConBuff->Add(""); + Console->Invalidate(); } //--------------------------------------------------------------------------- -void __fastcall TStrMonDialog::BtnStopClick(TObject *Sender) -{ - Stop=!Stop; - BtnStop->Down=Stop; +void __fastcall TStrMonDialog::BtnStopClick(TObject *Sender) { + Stop = !Stop; + BtnStop->Down = Stop; } //--------------------------------------------------------------------------- -void __fastcall TStrMonDialog::BtnDownClick(TObject *Sender) -{ - ScrollPos=0; - Console->Invalidate(); +void __fastcall TStrMonDialog::BtnDownClick(TObject *Sender) { + ScrollPos = 0; + Console->Invalidate(); } //--------------------------------------------------------------------------- - diff --git a/app/winapp/strsvr/mondlg.h b/app/winapp/strsvr/mondlg.h index 0d19db54c..abe001213 100644 --- a/app/winapp/strsvr/mondlg.h +++ b/app/winapp/strsvr/mondlg.h @@ -2,49 +2,50 @@ #ifndef mondlgH #define mondlgH //--------------------------------------------------------------------------- +#include #include #include -#include -#include #include -#include +#include +#include + #include "rtklib.h" -#define MAX_MSG_BUFF 4096 +#define MAX_MSG_BUFF 4096 //--------------------------------------------------------------------------- -class TStrMonDialog : public TForm -{ -__published: - TPanel *Panel1; - TPanel *Panel2; - TButton *BtnClose; - TSpeedButton *BtnClear; - TPaintBox *Console; - TScrollBar *Scroll; - TSpeedButton *BtnDown; - TSpeedButton *BtnStop; - TComboBox *SelFmt; - void __fastcall BtnCloseClick(TObject *Sender); - void __fastcall BtnCopyClick(TObject *Sender); - void __fastcall BtnClearClick(TObject *Sender); - void __fastcall ConsolePaint(TObject *Sender); - void __fastcall ScrollChange(TObject *Sender); - void __fastcall FormResize(TObject *Sender); - void __fastcall BtnDownClick(TObject *Sender); - void __fastcall BtnStopClick(TObject *Sender); - void __fastcall SelFmtChange(TObject *Sender); -private: - TStringList *ConBuff; - int Stop,ScrollPos; - rtcm_t rtcm; - raw_t raw; - - void __fastcall AddConsole(uint8_t *msg, int len, int mode); -public: - int StrFmt; - __fastcall TStrMonDialog(TComponent* Owner); - void __fastcall AddMsg(uint8_t *buff, int n); +class TStrMonDialog : public TForm { + __published : TPanel *Panel1; + TPanel *Panel2; + TButton *BtnClose; + TSpeedButton *BtnClear; + TPaintBox *Console; + TScrollBar *Scroll; + TSpeedButton *BtnDown; + TSpeedButton *BtnStop; + TComboBox *SelFmt; + void __fastcall BtnCloseClick(TObject *Sender); + void __fastcall BtnCopyClick(TObject *Sender); + void __fastcall BtnClearClick(TObject *Sender); + void __fastcall ConsolePaint(TObject *Sender); + void __fastcall ScrollChange(TObject *Sender); + void __fastcall FormResize(TObject *Sender); + void __fastcall BtnDownClick(TObject *Sender); + void __fastcall BtnStopClick(TObject *Sender); + void __fastcall SelFmtChange(TObject *Sender); + + private: + TStringList *ConBuff; + int Stop, ScrollPos; + rtcm_t rtcm; + raw_t raw; + + void __fastcall AddConsole(uint8_t *msg, int len, int mode); + + public: + int StrFmt; + __fastcall TStrMonDialog(TComponent *Owner); + void __fastcall AddMsg(uint8_t *buff, int n); }; //--------------------------------------------------------------------------- extern PACKAGE TStrMonDialog *StrMonDialog; diff --git a/app/winapp/strsvr/strsvr.cpp b/app/winapp/strsvr/strsvr.cpp index c838adf3a..55c08fe83 100644 --- a/app/winapp/strsvr/strsvr.cpp +++ b/app/winapp/strsvr/strsvr.cpp @@ -3,7 +3,6 @@ #pragma hdrstop //--------------------------------------------------------------------------- - USEFORM("..\appcmn\keydlg.cpp", KeyDialog); USEFORM("..\appcmn\mntpoptdlg.cpp", MntpOptDialog); USEFORM("..\appcmn\refdlg.cpp", RefDialog); @@ -21,45 +20,36 @@ USEFORM("..\appcmn\vieweropt.cpp", ViewerOptDialog); USEFORM("convdlg.cpp", ConvDialog); USEFORM("mondlg.cpp", StrMonDialog); //--------------------------------------------------------------------------- -int WINAPI WinMain(HINSTANCE, HINSTANCE, LPSTR, int) -{ - try - { - Application->Initialize(); - Application->Title = "STRSVR"; - Application->CreateForm(__classid(TMainForm), &MainForm); - Application->CreateForm(__classid(TSvrOptDialog), &SvrOptDialog); - Application->CreateForm(__classid(TCmdOptDialog), &CmdOptDialog); - Application->CreateForm(__classid(TFileOptDialog), &FileOptDialog); - Application->CreateForm(__classid(TSerialOptDialog), &SerialOptDialog); - Application->CreateForm(__classid(TFtpOptDialog), &FtpOptDialog); - Application->CreateForm(__classid(TAboutDialog), &AboutDialog); - Application->CreateForm(__classid(TConfDialog), &ConfDialog); - Application->CreateForm(__classid(TRefDialog), &RefDialog); - Application->CreateForm(__classid(TTcpOptDialog), &TcpOptDialog); - Application->CreateForm(__classid(TKeyDialog), &KeyDialog); - Application->CreateForm(__classid(TConvDialog), &ConvDialog); - Application->CreateForm(__classid(TStrMonDialog), &StrMonDialog); - Application->CreateForm(__classid(TTextViewer), &TextViewer); - Application->CreateForm(__classid(TViewerOptDialog), &ViewerOptDialog); - Application->CreateForm(__classid(TMntpOptDialog), &MntpOptDialog); - Application->Run(); - } - catch (Exception &exception) - { - Application->ShowException(&exception); - } - catch (...) - { - try - { - throw Exception(""); - } - catch (Exception &exception) - { - Application->ShowException(&exception); - } - } - return 0; +int WINAPI WinMain(HINSTANCE, HINSTANCE, LPSTR, int) { + try { + Application->Initialize(); + Application->Title = "STRSVR"; + Application->CreateForm(__classid(TMainForm), &MainForm); + Application->CreateForm(__classid(TSvrOptDialog), &SvrOptDialog); + Application->CreateForm(__classid(TCmdOptDialog), &CmdOptDialog); + Application->CreateForm(__classid(TFileOptDialog), &FileOptDialog); + Application->CreateForm(__classid(TSerialOptDialog), &SerialOptDialog); + Application->CreateForm(__classid(TFtpOptDialog), &FtpOptDialog); + Application->CreateForm(__classid(TAboutDialog), &AboutDialog); + Application->CreateForm(__classid(TConfDialog), &ConfDialog); + Application->CreateForm(__classid(TRefDialog), &RefDialog); + Application->CreateForm(__classid(TTcpOptDialog), &TcpOptDialog); + Application->CreateForm(__classid(TKeyDialog), &KeyDialog); + Application->CreateForm(__classid(TConvDialog), &ConvDialog); + Application->CreateForm(__classid(TStrMonDialog), &StrMonDialog); + Application->CreateForm(__classid(TTextViewer), &TextViewer); + Application->CreateForm(__classid(TViewerOptDialog), &ViewerOptDialog); + Application->CreateForm(__classid(TMntpOptDialog), &MntpOptDialog); + Application->Run(); + } catch (Exception &exception) { + Application->ShowException(&exception); + } catch (...) { + try { + throw Exception(""); + } catch (Exception &exception) { + Application->ShowException(&exception); + } + } + return 0; } //--------------------------------------------------------------------------- diff --git a/app/winapp/strsvr/svrmain.cpp b/app/winapp/strsvr/svrmain.cpp index b6fdbfbd5..054be128e 100644 --- a/app/winapp/strsvr/svrmain.cpp +++ b/app/winapp/strsvr/svrmain.cpp @@ -22,862 +22,840 @@ // clang-format off #include // clang-format on -#include #include #include + +#include #pragma hdrstop -#include "rtklib.h" -#include "svroptdlg.h" -#include "serioptdlg.h" -#include "fileoptdlg.h" -#include "tcpoptdlg.h" -#include "ftpoptdlg.h" -#include "confdlg.h" +#include "svrmain.h" + +#include "aboutdlg.h" #include "cmdoptdlg.h" +#include "confdlg.h" #include "convdlg.h" -#include "aboutdlg.h" -#include "refdlg.h" +#include "fileoptdlg.h" +#include "ftpoptdlg.h" #include "mondlg.h" -#include "svrmain.h" +#include "refdlg.h" +#include "rtklib.h" +#include "serioptdlg.h" +#include "svroptdlg.h" +#include "tcpoptdlg.h" //--------------------------------------------------------------------------- #pragma package(smart_init) #pragma resource "*.dfm" TMainForm *MainForm; -#define PRGNAME "STRSVR" // program name -#define TRACEFILE "strsvr.trace" // debug trace file -#define CLORANGE (TColor)0x00AAFF +#define PRGNAME "STRSVR" // program name +#define TRACEFILE "strsvr.trace" // debug trace file +#define CLORANGE (TColor)0x00AAFF -#define MIN(x,y) ((x)<(y)?(x):(y)) -#define MAX(x,y) ((x)>(y)?(x):(y)) +#define MIN(x, y) ((x) < (y) ? (x) : (y)) +#define MAX(x, y) ((x) > (y) ? (x) : (y)) static strsvr_t strsvr; // number to comma-separated number ----------------------------------------- -static void num2cnum(int num, char *str) -{ - char buff[256],*p=buff,*q=str; - int i,n; - n=sprintf(buff,"%u",(uint32_t)num); - for (i=0;iShowMainForm=false; - TrayIcon->Visible=true; - } - if (autorun) { - SvrStart(); - } +void __fastcall TMainForm::FormCreate(TObject *Sender) { + AnsiString s; + int argc = 0, autorun = 0, tasktray = 0; + char *p, *argv[32], buff[1024]; + + strsvrinit(&strsvr, MAXSTR - 1); + + Caption = s.sprintf("%s-%s %s", PRGNAME, VER_RTKLIB, PATCH_LEVEL); + + strcpy(buff, GetCommandLine()); + + for (p = buff; *p && argc < 32; p++) { + if (*p == ' ') continue; + if (*p == '"') { + argv[argc++] = p + 1; + if (!(p = strchr(p + 1, '"'))) break; + } else { + argv[argc++] = p; + if (!(p = strchr(p + 1, ' '))) break; + } + *p = '\0'; + } + for (int i = 1; i < argc; i++) { + if (!strcmp(argv[i], "-i") && i + 1 < argc) IniFile = argv[++i]; + } + LoadOpt(); + + for (int i = 1; i < argc; i++) { + if (!strcmp(argv[i], "-t") && i + 1 < argc) + Caption = argv[++i]; + else if (!strcmp(argv[i], "-auto")) + autorun = 1; + else if (!strcmp(argv[i], "-tray")) + tasktray = 1; + } + SetTrayIcon(0); + + if (tasktray) { + Application->ShowMainForm = false; + TrayIcon->Visible = true; + } + if (autorun) { + SvrStart(); + } } // callback on form show ---------------------------------------------------- -void __fastcall TMainForm::FormShow(TObject *Sender) -{ - ; -} -void __fastcall TMainForm::FormClose(TObject *Sender, TCloseAction &Action) -{ - SaveOpt(); -} +void __fastcall TMainForm::FormShow(TObject *Sender) { ; } +void __fastcall TMainForm::FormClose(TObject *Sender, TCloseAction &Action) { SaveOpt(); } // callback on button-exit -------------------------------------------------- -void __fastcall TMainForm::BtnExitClick(TObject *Sender) -{ - Close(); -} +void __fastcall TMainForm::BtnExitClick(TObject *Sender) { Close(); } // callback on button-start ------------------------------------------------- -void __fastcall TMainForm::BtnStartClick(TObject *Sender) -{ - SvrStart(); -} +void __fastcall TMainForm::BtnStartClick(TObject *Sender) { SvrStart(); } // callback on button-stop -------------------------------------------------- -void __fastcall TMainForm::BtnStopClick(TObject *Sender) -{ - SvrStop(); -} +void __fastcall TMainForm::BtnStopClick(TObject *Sender) { SvrStop(); } // callback on button-options ----------------------------------------------- -void __fastcall TMainForm::BtnOptClick(TObject *Sender) -{ - for (int i=0;i<6;i++) SvrOptDialog->SvrOpt[i]=SvrOpt[i]; - for (int i=0;i<3;i++) SvrOptDialog->AntPos[i]=AntPos[i]; - for (int i=0;i<3;i++) SvrOptDialog->AntOff[i]=AntOff[i]; - SvrOptDialog->TraceLevel=TraceLevel; - SvrOptDialog->NmeaReq=NmeaReq; - SvrOptDialog->FileSwapMargin=FileSwapMargin; - SvrOptDialog->RelayBack=RelayBack; - SvrOptDialog->ProgBarRange=ProgBarRange; - SvrOptDialog->StaPosFile=StaPosFile; - SvrOptDialog->ExeDirectory=ExeDirectory; - SvrOptDialog->LocalDirectory=LocalDirectory; - SvrOptDialog->ProxyAddress=ProxyAddress; - SvrOptDialog->StaId=StaId; - SvrOptDialog->StaSel=StaSel; - SvrOptDialog->AntType=AntType; - SvrOptDialog->RcvType=RcvType; - SvrOptDialog->LogFile=LogFile; - - if (SvrOptDialog->ShowModal()!=mrOk) return; - - for (int i=0;i<6;i++) SvrOpt[i]=SvrOptDialog->SvrOpt[i]; - for (int i=0;i<3;i++) AntPos[i]=SvrOptDialog->AntPos[i]; - for (int i=0;i<3;i++) AntOff[i]=SvrOptDialog->AntOff[i]; - TraceLevel=SvrOptDialog->TraceLevel; - NmeaReq=SvrOptDialog->NmeaReq; - FileSwapMargin=SvrOptDialog->FileSwapMargin; - RelayBack=SvrOptDialog->RelayBack; - ProgBarRange=SvrOptDialog->ProgBarRange; - StaPosFile=SvrOptDialog->StaPosFile; - ExeDirectory=SvrOptDialog->ExeDirectory; - LocalDirectory=SvrOptDialog->LocalDirectory; - ProxyAddress=SvrOptDialog->ProxyAddress; - StaId=SvrOptDialog->StaId; - StaSel=SvrOptDialog->StaSel; - AntType=SvrOptDialog->AntType; - RcvType=SvrOptDialog->RcvType; - LogFile=SvrOptDialog->LogFile; +void __fastcall TMainForm::BtnOptClick(TObject *Sender) { + for (int i = 0; i < 6; i++) SvrOptDialog->SvrOpt[i] = SvrOpt[i]; + for (int i = 0; i < 3; i++) SvrOptDialog->AntPos[i] = AntPos[i]; + for (int i = 0; i < 3; i++) SvrOptDialog->AntOff[i] = AntOff[i]; + SvrOptDialog->TraceLevel = TraceLevel; + SvrOptDialog->NmeaReq = NmeaReq; + SvrOptDialog->FileSwapMargin = FileSwapMargin; + SvrOptDialog->RelayBack = RelayBack; + SvrOptDialog->ProgBarRange = ProgBarRange; + SvrOptDialog->StaPosFile = StaPosFile; + SvrOptDialog->ExeDirectory = ExeDirectory; + SvrOptDialog->LocalDirectory = LocalDirectory; + SvrOptDialog->ProxyAddress = ProxyAddress; + SvrOptDialog->StaId = StaId; + SvrOptDialog->StaSel = StaSel; + SvrOptDialog->AntType = AntType; + SvrOptDialog->RcvType = RcvType; + SvrOptDialog->LogFile = LogFile; + + if (SvrOptDialog->ShowModal() != mrOk) return; + + for (int i = 0; i < 6; i++) SvrOpt[i] = SvrOptDialog->SvrOpt[i]; + for (int i = 0; i < 3; i++) AntPos[i] = SvrOptDialog->AntPos[i]; + for (int i = 0; i < 3; i++) AntOff[i] = SvrOptDialog->AntOff[i]; + TraceLevel = SvrOptDialog->TraceLevel; + NmeaReq = SvrOptDialog->NmeaReq; + FileSwapMargin = SvrOptDialog->FileSwapMargin; + RelayBack = SvrOptDialog->RelayBack; + ProgBarRange = SvrOptDialog->ProgBarRange; + StaPosFile = SvrOptDialog->StaPosFile; + ExeDirectory = SvrOptDialog->ExeDirectory; + LocalDirectory = SvrOptDialog->LocalDirectory; + ProxyAddress = SvrOptDialog->ProxyAddress; + StaId = SvrOptDialog->StaId; + StaSel = SvrOptDialog->StaSel; + AntType = SvrOptDialog->AntType; + RcvType = SvrOptDialog->RcvType; + LogFile = SvrOptDialog->LogFile; } // callback on button-input-opt --------------------------------------------- -void __fastcall TMainForm::BtnInputClick(TObject *Sender) -{ - switch (Input->ItemIndex) { - case 0: SerialOpt (0,0); break; - case 1: TcpCliOpt (0,1); break; - case 2: TcpSvrOpt (0,2); break; - case 3: NtripCliOpt(0,3); break; - case 4: UdpSvrOpt (0,4); break; - case 5: FileOpt (0,5); break; - } +void __fastcall TMainForm::BtnInputClick(TObject *Sender) { + switch (Input->ItemIndex) { + case 0: + SerialOpt(0, 0); + break; + case 1: + TcpCliOpt(0, 1); + break; + case 2: + TcpSvrOpt(0, 2); + break; + case 3: + NtripCliOpt(0, 3); + break; + case 4: + UdpSvrOpt(0, 4); + break; + case 5: + FileOpt(0, 5); + break; + } } // callback on button-cmd --------------------------------------------------- -void __fastcall TMainForm::BtnCmdClick(TObject *Sender) -{ - TButton *btn[]={BtnCmd,BtnCmd1,BtnCmd2,BtnCmd3,BtnCmd4,BtnCmd5,BtnCmd6}; - TComboBox *type[]={Input,Output1,Output2,Output3,Output4,Output5,Output6}; - AnsiString s; - int i,j; - - for (i=0;i=MAXSTR) return; - - for (j=0;j<3;j++) { - if (type[i]->Text=="Serial") { - CmdOptDialog->Cmds[j]=Cmds[i][j]; - CmdOptDialog->CmdEna[j]=CmdEna[i][j]; - } - else { - CmdOptDialog->Cmds[j]=CmdsTcp[i][j]; - CmdOptDialog->CmdEna[j]=CmdEnaTcp[i][j]; - } - } - if (i==0) CmdOptDialog->Caption=s.sprintf("Input Serial/TCP Commands"); - else CmdOptDialog->Caption=s.sprintf("Output%d Serial/TCP Commands",i); - if (CmdOptDialog->ShowModal()!=mrOk) return; - for (j=0;j<3;j++) { - if (type[i]->Text=="Serial") { - Cmds[i][j]=CmdOptDialog->Cmds[j]; - CmdEna[i][j]=CmdOptDialog->CmdEna[j]; - } - else { - CmdsTcp[i][j]=CmdOptDialog->Cmds[j]; - CmdEnaTcp[i][j]=CmdOptDialog->CmdEna[j]; - } - } +void __fastcall TMainForm::BtnCmdClick(TObject *Sender) { + TButton *btn[] = {BtnCmd, BtnCmd1, BtnCmd2, BtnCmd3, BtnCmd4, BtnCmd5, BtnCmd6}; + TComboBox *type[] = {Input, Output1, Output2, Output3, Output4, Output5, Output6}; + AnsiString s; + int i, j; + + for (i = 0; i < MAXSTR; i++) { + if (btn[i] == (TButton *)Sender) break; + } + if (i >= MAXSTR) return; + + for (j = 0; j < 3; j++) { + if (type[i]->Text == "Serial") { + CmdOptDialog->Cmds[j] = Cmds[i][j]; + CmdOptDialog->CmdEna[j] = CmdEna[i][j]; + } else { + CmdOptDialog->Cmds[j] = CmdsTcp[i][j]; + CmdOptDialog->CmdEna[j] = CmdEnaTcp[i][j]; + } + } + if (i == 0) + CmdOptDialog->Caption = s.sprintf("Input Serial/TCP Commands"); + else + CmdOptDialog->Caption = s.sprintf("Output%d Serial/TCP Commands", i); + if (CmdOptDialog->ShowModal() != mrOk) return; + for (j = 0; j < 3; j++) { + if (type[i]->Text == "Serial") { + Cmds[i][j] = CmdOptDialog->Cmds[j]; + CmdEna[i][j] = CmdOptDialog->CmdEna[j]; + } else { + CmdsTcp[i][j] = CmdOptDialog->Cmds[j]; + CmdEnaTcp[i][j] = CmdOptDialog->CmdEna[j]; + } + } } // callback on button-output-opt -------------------------------------------- -void __fastcall TMainForm::BtnOutputClick(TObject *Sender) -{ - TButton *btn[]={BtnOutput1,BtnOutput2,BtnOutput3,BtnOutput4,BtnOutput5,BtnOutput6}; - TComboBox *type[]={Output1,Output2,Output3,Output4,Output5,Output6}; - int i; - - for (i=0;i=MAXSTR-1) return; - - switch (type[i]->ItemIndex) { - case 1: SerialOpt (i+1,0); break; - case 2: TcpCliOpt (i+1,1); break; - case 3: TcpSvrOpt (i+1,2); break; - case 4: NtripSvrOpt(i+1,3); break; - case 5: NtripCasOpt(i+1,4); break; - case 6: UdpCliOpt (i+1,5); break; - case 7: FileOpt (i+1,6); break; - } +void __fastcall TMainForm::BtnOutputClick(TObject *Sender) { + TButton *btn[] = {BtnOutput1, BtnOutput2, BtnOutput3, BtnOutput4, BtnOutput5, BtnOutput6}; + TComboBox *type[] = {Output1, Output2, Output3, Output4, Output5, Output6}; + int i; + + for (i = 0; i < MAXSTR - 1; i++) { + if ((TButton *)Sender == btn[i]) break; + } + if (i >= MAXSTR - 1) return; + + switch (type[i]->ItemIndex) { + case 1: + SerialOpt(i + 1, 0); + break; + case 2: + TcpCliOpt(i + 1, 1); + break; + case 3: + TcpSvrOpt(i + 1, 2); + break; + case 4: + NtripSvrOpt(i + 1, 3); + break; + case 5: + NtripCasOpt(i + 1, 4); + break; + case 6: + UdpCliOpt(i + 1, 5); + break; + case 7: + FileOpt(i + 1, 6); + break; + } } // callback on button-conv -------------------------------------------------- -void __fastcall TMainForm::BtnConvClick(TObject *Sender) -{ - TButton *btn[]={BtnConv1,BtnConv2,BtnConv3,BtnConv4,BtnConv5,BtnConv6}; - AnsiString s; - int i; - - for (i=0;i=MAXSTR-1) return; - - ConvDialog->ConvEna=ConvEna[i]; - ConvDialog->ConvInp=ConvInp[i]; - ConvDialog->ConvOut=ConvOut[i]; - ConvDialog->ConvMsg=ConvMsg[i]; - ConvDialog->ConvOpt=ConvOpt[i]; - ConvDialog->Caption=s.sprintf("Output%d Conversion Options",i+1); - if (ConvDialog->ShowModal()!=mrOk) return; - ConvEna[i]=ConvDialog->ConvEna; - ConvInp[i]=ConvDialog->ConvInp; - ConvOut[i]=ConvDialog->ConvOut; - ConvMsg[i]=ConvDialog->ConvMsg; - ConvOpt[i]=ConvDialog->ConvOpt; +void __fastcall TMainForm::BtnConvClick(TObject *Sender) { + TButton *btn[] = {BtnConv1, BtnConv2, BtnConv3, BtnConv4, BtnConv5, BtnConv6}; + AnsiString s; + int i; + + for (i = 0; i < MAXSTR - 1; i++) { + if ((TButton *)Sender == btn[i]) break; + } + if (i >= MAXSTR - 1) return; + + ConvDialog->ConvEna = ConvEna[i]; + ConvDialog->ConvInp = ConvInp[i]; + ConvDialog->ConvOut = ConvOut[i]; + ConvDialog->ConvMsg = ConvMsg[i]; + ConvDialog->ConvOpt = ConvOpt[i]; + ConvDialog->Caption = s.sprintf("Output%d Conversion Options", i + 1); + if (ConvDialog->ShowModal() != mrOk) return; + ConvEna[i] = ConvDialog->ConvEna; + ConvInp[i] = ConvDialog->ConvInp; + ConvOut[i] = ConvDialog->ConvOut; + ConvMsg[i] = ConvDialog->ConvMsg; + ConvOpt[i] = ConvDialog->ConvOpt; } // callback on about -------------------------------------------------------- -void __fastcall TMainForm::BtnAboutClick(TObject *Sender) -{ - AboutDialog->About=PRGNAME; - AboutDialog->IconIndex=6; - AboutDialog->ShowModal(); +void __fastcall TMainForm::BtnAboutClick(TObject *Sender) { + AboutDialog->About = PRGNAME; + AboutDialog->IconIndex = 6; + AboutDialog->ShowModal(); } // callback on task-icon ---------------------------------------------------- -void __fastcall TMainForm::BtnTaskIconClick(TObject *Sender) -{ - Visible=false; - TrayIcon->Visible=true; +void __fastcall TMainForm::BtnTaskIconClick(TObject *Sender) { + Visible = false; + TrayIcon->Visible = true; } // callback on task-icon double-click --------------------------------------- -void __fastcall TMainForm::TrayIconDblClick(TObject *Sender) -{ - Visible=true; - TrayIcon->Visible=false; +void __fastcall TMainForm::TrayIconDblClick(TObject *Sender) { + Visible = true; + TrayIcon->Visible = false; } // callback on task-tray-icon click ----------------------------------------- -void __fastcall TMainForm::TrayIconMouseDown(TObject *Sender, - TMouseButton Button, TShiftState Shift, int X, int Y) -{ - ; +void __fastcall TMainForm::TrayIconMouseDown(TObject *Sender, TMouseButton Button, + TShiftState Shift, int X, int Y) { + ; } // callback on menu-expand -------------------------------------------------- -void __fastcall TMainForm::MenuExpandClick(TObject *Sender) -{ - Visible=true; - TrayIcon->Visible=false; +void __fastcall TMainForm::MenuExpandClick(TObject *Sender) { + Visible = true; + TrayIcon->Visible = false; } // callback on menu-start --------------------------------------------------- -void __fastcall TMainForm::MenuStartClick(TObject *Sender) -{ - SvrStart(); -} +void __fastcall TMainForm::MenuStartClick(TObject *Sender) { SvrStart(); } // callback on menu-stop ---------------------------------------------------- -void __fastcall TMainForm::MenuStopClick(TObject *Sender) -{ - SvrStop(); -} +void __fastcall TMainForm::MenuStopClick(TObject *Sender) { SvrStop(); } // callback on menu-exit ---------------------------------------------------- -void __fastcall TMainForm::MenuExitClick(TObject *Sender) -{ - Close(); -} +void __fastcall TMainForm::MenuExitClick(TObject *Sender) { Close(); } // callback on stream-monitor ----------------------------------------------- -void __fastcall TMainForm::BtnStrMonClick(TObject *Sender) -{ - StrMonDialog->Show(); -} +void __fastcall TMainForm::BtnStrMonClick(TObject *Sender) { StrMonDialog->Show(); } // callback on output1 enable ----------------------------------------------- -void __fastcall TMainForm::EnaOut1Click(TObject *Sender) -{ - UpdateEnable(); -} -// callback on output2 enable -----------------------------------------------// callback on output3 enable -----------------------------------------------// callback on input type change -------------------------------------------- -void __fastcall TMainForm::InputChange(TObject *Sender) -{ - UpdateEnable(); -} +void __fastcall TMainForm::EnaOut1Click(TObject *Sender) { UpdateEnable(); } +// callback on output2 enable -----------------------------------------------// callback on output3 +// enable -----------------------------------------------// callback on input type change +// -------------------------------------------- +void __fastcall TMainForm::InputChange(TObject *Sender) { UpdateEnable(); } // callback on output1 type change ------------------------------------------ -void __fastcall TMainForm::OutputChange(TObject *Sender) -{ - UpdateEnable(); -} +void __fastcall TMainForm::OutputChange(TObject *Sender) { UpdateEnable(); } // callback on interval timer ----------------------------------------------- -void __fastcall TMainForm::Timer1Timer(TObject *Sender) -{ - TColor color[]={clRed,clWhite,CLORANGE,clGreen,clLime,clAqua}; - TPanel *e0[]={IndInput,IndOutput1,IndOutput2,IndOutput3,IndOutput4,IndOutput5,IndOutput6}; - TLabel *e1[]={InputByte,Output1Byte,Output2Byte,Output3Byte,Output4Byte,Output5Byte,Output6Byte}; - TLabel *e2[]={InputBps,Output1Bps,Output2Bps,Output3Bps,Output4Bps,Output5Bps,Output6Bps}; - TPanel *e3[]={IndLog,IndLog1,IndLog2,IndLog3,IndLog4,IndLog5,IndLog6}; - AnsiString s; - gtime_t time=utc2gpst(timeget()); - int stat[MAXSTR]={0},byte[MAXSTR]={0},bps[MAXSTR]={0},log_stat[MAXSTR]={0}; - char msg[MAXSTRMSG*MAXSTR]="",s1[256],s2[256]; - double ctime,t[4],pos,range; - - strsvrstat(&strsvr,stat,log_stat,byte,bps,msg); - for (int i=0;iColor=color[stat[i]+1]; - e1[i]->Caption=s1; - e2[i]->Caption=s2; - e3[i]->Color=color[log_stat[i]+1]; - } - pos=fmod(byte[0]/1e3/MAX(ProgBarRange,1),1.0)*110.0; - Progress->Position=!stat[0]?0:MIN((int)pos,100); - - char tstr[40]; - time2str(time,tstr,0); - Time->Caption=s.sprintf("%s GPST",tstr); - - if (Panel1->Enabled) { - ctime=timediff(EndTime,StartTime); - } - else { - ctime=timediff(time,StartTime); - } - ctime=floor(ctime); - t[0]=floor(ctime/86400.0); ctime-=t[0]*86400.0; - t[1]=floor(ctime/3600.0 ); ctime-=t[1]*3600.0; - t[2]=floor(ctime/60.0 ); ctime-=t[2]*60.0; - t[3]=ctime; - ConTime->Caption=s.sprintf("%.0fd %02.0f:%02.0f:%02.0f",t[0],t[1],t[2],t[3]); - - num2cnum(byte[0],s1); num2cnum(bps[0],s2); - TrayIcon->Hint=s.sprintf("%s bytes %s bps",s1,s2); - SetTrayIcon(stat[0]<=0?0:(stat[0]==3?2:1)); - - Message->Caption=msg; - Message->Hint=msg; +void __fastcall TMainForm::Timer1Timer(TObject *Sender) { + TColor color[] = {clRed, clWhite, CLORANGE, clGreen, clLime, clAqua}; + TPanel *e0[] = {IndInput, IndOutput1, IndOutput2, IndOutput3, IndOutput4, IndOutput5, IndOutput6}; + TLabel *e1[] = {InputByte, Output1Byte, Output2Byte, Output3Byte, + Output4Byte, Output5Byte, Output6Byte}; + TLabel *e2[] = {InputBps, Output1Bps, Output2Bps, Output3Bps, Output4Bps, Output5Bps, Output6Bps}; + TPanel *e3[] = {IndLog, IndLog1, IndLog2, IndLog3, IndLog4, IndLog5, IndLog6}; + AnsiString s; + gtime_t time = utc2gpst(timeget()); + int stat[MAXSTR] = {0}, byte[MAXSTR] = {0}, bps[MAXSTR] = {0}, log_stat[MAXSTR] = {0}; + char msg[MAXSTRMSG * MAXSTR] = "", s1[256], s2[256]; + double ctime, t[4], pos, range; + + strsvrstat(&strsvr, stat, log_stat, byte, bps, msg); + for (int i = 0; i < MAXSTR; i++) { + num2cnum(byte[i], s1); + num2cnum(bps[i], s2); + e0[i]->Color = color[stat[i] + 1]; + e1[i]->Caption = s1; + e2[i]->Caption = s2; + e3[i]->Color = color[log_stat[i] + 1]; + } + pos = fmod(byte[0] / 1e3 / MAX(ProgBarRange, 1), 1.0) * 110.0; + Progress->Position = !stat[0] ? 0 : MIN((int)pos, 100); + + char tstr[40]; + time2str(time, tstr, 0); + Time->Caption = s.sprintf("%s GPST", tstr); + + if (Panel1->Enabled) { + ctime = timediff(EndTime, StartTime); + } else { + ctime = timediff(time, StartTime); + } + ctime = floor(ctime); + t[0] = floor(ctime / 86400.0); + ctime -= t[0] * 86400.0; + t[1] = floor(ctime / 3600.0); + ctime -= t[1] * 3600.0; + t[2] = floor(ctime / 60.0); + ctime -= t[2] * 60.0; + t[3] = ctime; + ConTime->Caption = s.sprintf("%.0fd %02.0f:%02.0f:%02.0f", t[0], t[1], t[2], t[3]); + + num2cnum(byte[0], s1); + num2cnum(bps[0], s2); + TrayIcon->Hint = s.sprintf("%s bytes %s bps", s1, s2); + SetTrayIcon(stat[0] <= 0 ? 0 : (stat[0] == 3 ? 2 : 1)); + + Message->Caption = msg; + Message->Hint = msg; } // start stream server ------------------------------------------------------ -void __fastcall TMainForm::SvrStart(void) -{ - TComboBox *type[]={Input,Output1,Output2,Output3,Output4,Output5,Output6}; - strconv_t *conv[MAXSTR-1]={0}; - static char str1[MAXSTR][1024],str2[MAXSTR][1024]; - int itype[]={ - STR_SERIAL,STR_TCPCLI,STR_TCPSVR,STR_NTRIPCLI,STR_UDPSVR,STR_FILE, - STR_FTP,STR_HTTP - }; - int otype[]={ - STR_NONE,STR_SERIAL,STR_TCPCLI,STR_TCPSVR,STR_NTRIPSVR,STR_NTRIPCAS, - STR_UDPCLI,STR_FILE - }; - int strs[MAXSTR]={0},opt[8]={0},n; - char *paths[MAXSTR],*logs[MAXSTR],*cmds[MAXSTR]={0},*cmds_periodic[MAXSTR]={0}; - char filepath[1024],buff[1024],*p; - const char *ant[3]={"","",""},*rcv[3]={"","",""}; - FILE *fp; - - if (TraceLevel>0) { - traceopen(*LogFile.c_str()?LogFile.c_str():TRACEFILE); - tracelevel(TraceLevel); - } - for (int i=0;iItemIndex]; - strcpy(paths[0],Paths[0][type[0]->ItemIndex].c_str()); - strcpy(logs[0],type[0]->ItemIndex>5||!PathEna[0]?"":PathLog[0].c_str()); - - for (int i=1;iItemIndex]; - strcpy(paths[i],!type[i]->ItemIndex?"":Paths[i][type[i]->ItemIndex-1].c_str()); - strcpy(logs[i],!PathEna[i]?"":PathLog[i].c_str()); +void __fastcall TMainForm::SvrStart(void) { + TComboBox *type[] = {Input, Output1, Output2, Output3, Output4, Output5, Output6}; + strconv_t *conv[MAXSTR - 1] = {0}; + static char str1[MAXSTR][1024], str2[MAXSTR][1024]; + int itype[] = {STR_SERIAL, STR_TCPCLI, STR_TCPSVR, STR_NTRIPCLI, + STR_UDPSVR, STR_FILE, STR_FTP, STR_HTTP}; + int otype[] = {STR_NONE, STR_SERIAL, STR_TCPCLI, STR_TCPSVR, + STR_NTRIPSVR, STR_NTRIPCAS, STR_UDPCLI, STR_FILE}; + int strs[MAXSTR] = {0}, opt[8] = {0}, n; + char *paths[MAXSTR], *logs[MAXSTR], *cmds[MAXSTR] = {0}, *cmds_periodic[MAXSTR] = {0}; + char filepath[1024], buff[1024], *p; + const char *ant[3] = {"", "", ""}, *rcv[3] = {"", "", ""}; + FILE *fp; + + if (TraceLevel > 0) { + traceopen(*LogFile.c_str() ? LogFile.c_str() : TRACEFILE); + tracelevel(TraceLevel); + } + for (int i = 0; i < MAXSTR; i++) { + paths[i] = str1[i]; + logs[i] = str2[i]; + } + strs[0] = itype[type[0]->ItemIndex]; + strcpy(paths[0], Paths[0][type[0]->ItemIndex].c_str()); + strcpy(logs[0], type[0]->ItemIndex > 5 || !PathEna[0] ? "" : PathLog[0].c_str()); + + for (int i = 1; i < MAXSTR; i++) { + strs[i] = otype[type[i]->ItemIndex]; + strcpy(paths[i], !type[i]->ItemIndex ? "" : Paths[i][type[i]->ItemIndex - 1].c_str()); + strcpy(logs[i], !PathEna[i] ? "" : PathLog[i].c_str()); + } + for (int i = 0; i < MAXSTR; i++) { + if (strs[i] == STR_SERIAL) { + if (CmdEna[i][0]) cmds[i] = MainForm->Cmds[i][0].c_str(); + if (CmdEna[i][2]) cmds_periodic[i] = MainForm->Cmds[i][2].c_str(); + } else if (strs[i] == STR_TCPCLI || strs[i] == STR_NTRIPCLI) { + if (CmdEnaTcp[i][0]) cmds[i] = MainForm->CmdsTcp[i][0].c_str(); + if (CmdEnaTcp[i][2]) cmds_periodic[i] = MainForm->CmdsTcp[i][2].c_str(); } - for (int i=0;iCmds[i][0].c_str(); - if (CmdEna[i][2]) cmds_periodic[i]=MainForm->Cmds[i][2].c_str(); - } - else if (strs[i]==STR_TCPCLI||strs[i]==STR_NTRIPCLI) { - if (CmdEnaTcp[i][0]) cmds[i]=MainForm->CmdsTcp[i][0].c_str(); - if (CmdEnaTcp[i][2]) cmds_periodic[i]=MainForm->CmdsTcp[i][2].c_str(); - } - } - for (int i=0;i<5;i++) { - opt[i]=SvrOpt[i]; - } - opt[5]=NmeaReq?SvrOpt[5]:0; - opt[6]=FileSwapMargin; - opt[7]=RelayBack; - - for (int i=1;iLabel2->Caption=filepath; - if (ConfDialog->ShowModal()!=mrOk) return; - } - for (int i=0;iLabel2->Caption=filepath; - if (ConfDialog->ShowModal()!=mrOk) return; - } - strsetdir(LocalDirectory.c_str()); - strsetproxy(ProxyAddress.c_str()); - - for (int i=0;iItemIndex==2||Input->ItemIndex==4) continue; - if (!ConvEna[i]) continue; - if (!(conv[i]=strconvnew(ConvInp[i],ConvOut[i],ConvMsg[i].c_str(), - StaId,StaSel,ConvOpt[i].c_str()))) continue; - strcpy(buff,AntType.c_str()); - for (p=strtok(buff,","),n=0;p&&n<3;p=strtok(NULL,",")) ant[n++]=p; - strcpy(conv[i]->out.sta.antdes,ant[0]); - strcpy(conv[i]->out.sta.antsno,ant[1]); - conv[i]->out.sta.antsetup=atoi(ant[2]); - strcpy(buff,RcvType.c_str()); - for (p=strtok(buff,","),n=0;p&&n<3;p=strtok(NULL,",")) rcv[n++]=p; - strcpy(conv[i]->out.sta.rectype,rcv[0]); - strcpy(conv[i]->out.sta.recver ,rcv[1]); - strcpy(conv[i]->out.sta.recsno ,rcv[2]); - matcpy(conv[i]->out.sta.pos,AntPos,3,1); - matcpy(conv[i]->out.sta.del,AntOff,3,1); - } - // stream server start - if (!strsvrstart(&strsvr,opt,strs,(const char **)paths,(const char **)logs,conv,(const char **)cmds,(const char **)cmds_periodic,AntPos)) { - return; - } - StartTime=utc2gpst(timeget()); - Panel1 ->Enabled=false; - BtnStart ->Visible=false; - BtnStop ->Visible=true; - BtnOpt ->Enabled=false; - BtnExit ->Enabled=false; - MenuStart ->Enabled=false; - MenuStop ->Enabled=true; - MenuExit ->Enabled=false; - SetTrayIcon(1); + } + for (int i = 0; i < 5; i++) { + opt[i] = SvrOpt[i]; + } + opt[5] = NmeaReq ? SvrOpt[5] : 0; + opt[6] = FileSwapMargin; + opt[7] = RelayBack; + + for (int i = 1; i < MAXSTR; i++) { // for each out stream + if (strs[i] != STR_FILE) continue; + strcpy(filepath, paths[i]); + if (strstr(filepath, "::A")) continue; + if ((p = strstr(filepath, "::"))) *p = '\0'; + if (!(fp = fopen(filepath, "r"))) continue; + fclose(fp); + ConfDialog->Label2->Caption = filepath; + if (ConfDialog->ShowModal() != mrOk) return; + } + for (int i = 0; i < MAXSTR; i++) { // for each log stream + if (!*logs[i]) continue; + strcpy(filepath, logs[i]); + if (strstr(filepath, "::A")) continue; + if ((p = strstr(filepath, "::"))) *p = '\0'; + if (!(fp = fopen(filepath, "r"))) continue; + fclose(fp); + ConfDialog->Label2->Caption = filepath; + if (ConfDialog->ShowModal() != mrOk) return; + } + strsetdir(LocalDirectory.c_str()); + strsetproxy(ProxyAddress.c_str()); + + for (int i = 0; i < MAXSTR - 1; i++) { // for each out stream + if (Input->ItemIndex == 2 || Input->ItemIndex == 4) continue; + if (!ConvEna[i]) continue; + if (!(conv[i] = strconvnew(ConvInp[i], ConvOut[i], ConvMsg[i].c_str(), StaId, StaSel, + ConvOpt[i].c_str()))) + continue; + strcpy(buff, AntType.c_str()); + for (p = strtok(buff, ","), n = 0; p && n < 3; p = strtok(NULL, ",")) ant[n++] = p; + strcpy(conv[i]->out.sta.antdes, ant[0]); + strcpy(conv[i]->out.sta.antsno, ant[1]); + conv[i]->out.sta.antsetup = atoi(ant[2]); + strcpy(buff, RcvType.c_str()); + for (p = strtok(buff, ","), n = 0; p && n < 3; p = strtok(NULL, ",")) rcv[n++] = p; + strcpy(conv[i]->out.sta.rectype, rcv[0]); + strcpy(conv[i]->out.sta.recver, rcv[1]); + strcpy(conv[i]->out.sta.recsno, rcv[2]); + matcpy(conv[i]->out.sta.pos, AntPos, 3, 1); + matcpy(conv[i]->out.sta.del, AntOff, 3, 1); + } + // stream server start + if (!strsvrstart(&strsvr, opt, strs, (const char **)paths, (const char **)logs, conv, + (const char **)cmds, (const char **)cmds_periodic, AntPos)) { + return; + } + StartTime = utc2gpst(timeget()); + Panel1->Enabled = false; + BtnStart->Visible = false; + BtnStop->Visible = true; + BtnOpt->Enabled = false; + BtnExit->Enabled = false; + MenuStart->Enabled = false; + MenuStop->Enabled = true; + MenuExit->Enabled = false; + SetTrayIcon(1); } // stop stream server ------------------------------------------------------- -void __fastcall TMainForm::SvrStop(void) -{ - TComboBox *type[]={Input,Output1,Output2,Output3,Output4,Output5,Output6}; - int itype[]={ - STR_SERIAL,STR_TCPCLI,STR_TCPSVR,STR_NTRIPCLI,STR_UDPSVR,STR_FILE, - STR_FTP,STR_HTTP - }; - int otype[]={ - STR_NONE,STR_SERIAL,STR_TCPCLI,STR_TCPSVR,STR_NTRIPSVR,STR_NTRIPCAS, - STR_UDPCLI,STR_FILE - }; - char *cmds[MAXSTR]={0}; - int strs[MAXSTR]; - - strs[0]=itype[Input->ItemIndex]; - for (int i=1;iItemIndex]; +void __fastcall TMainForm::SvrStop(void) { + TComboBox *type[] = {Input, Output1, Output2, Output3, Output4, Output5, Output6}; + int itype[] = {STR_SERIAL, STR_TCPCLI, STR_TCPSVR, STR_NTRIPCLI, + STR_UDPSVR, STR_FILE, STR_FTP, STR_HTTP}; + int otype[] = {STR_NONE, STR_SERIAL, STR_TCPCLI, STR_TCPSVR, + STR_NTRIPSVR, STR_NTRIPCAS, STR_UDPCLI, STR_FILE}; + char *cmds[MAXSTR] = {0}; + int strs[MAXSTR]; + + strs[0] = itype[Input->ItemIndex]; + for (int i = 1; i < MAXSTR; i++) { + strs[i] = otype[type[i]->ItemIndex]; + } + for (int i = 0; i < MAXSTR; i++) { + if (strs[i] == STR_SERIAL) { + if (CmdEna[i][1]) cmds[i] = MainForm->Cmds[i][1].c_str(); + } else if (strs[i] == STR_TCPCLI || strs[i] == STR_NTRIPCLI) { + if (CmdEnaTcp[i][1]) cmds[i] = MainForm->CmdsTcp[i][1].c_str(); } - for (int i=0;iCmds[i][1].c_str(); - } - else if (strs[i]==STR_TCPCLI||strs[i]==STR_NTRIPCLI) { - if (CmdEnaTcp[i][1]) cmds[i]=MainForm->CmdsTcp[i][1].c_str(); - } - } - strsvrstop(&strsvr,(const char **)cmds); - - EndTime=utc2gpst(timeget()); - Panel1 ->Enabled=true; - BtnStart ->Visible=true; - BtnStop ->Visible=false; - BtnOpt ->Enabled=true; - BtnExit ->Enabled=true; - MenuStart ->Enabled=true; - MenuStop ->Enabled=false; - MenuExit ->Enabled=true; - SetTrayIcon(0); - - for (int i=0;i0) traceclose(); + } + strsvrstop(&strsvr, (const char **)cmds); + + EndTime = utc2gpst(timeget()); + Panel1->Enabled = true; + BtnStart->Visible = true; + BtnStop->Visible = false; + BtnOpt->Enabled = true; + BtnExit->Enabled = true; + MenuStart->Enabled = true; + MenuStop->Enabled = false; + MenuExit->Enabled = true; + SetTrayIcon(0); + + for (int i = 0; i < MAXSTR - 1; i++) { + if (ConvEna[i]) strconvfree(strsvr.conv[i]); + } + if (TraceLevel > 0) traceclose(); } // callback on interval timer for stream monitor ---------------------------- -void __fastcall TMainForm::Timer2Timer(TObject *Sender) -{ - const char *types[]={ - "None","Serial","File","TCP Server","TCP Client","Ntrip Server", - "Ntrip Client","FTP","HTTP","Ntrip Cast","UDP Server","UDP Client" - }; - const char *modes[]={"-","R","W","R/W"}; - const char *states[]={"ERR","-","WAIT","CONN"}; - stream_t *str; - char *msg, *p; - int i,len,inb,inr,outb,outr; - - if (StrMonDialog->StrFmt) { - rtklib_lock(&strsvr.lock); - len=strsvr.npb; - if (len>0&&(msg=(char *)malloc(len))) { - memcpy(msg,strsvr.pbuf,len); - strsvr.npb=0; - } - rtklib_unlock(&strsvr.lock); - if (len<=0||!msg) return; - StrMonDialog->AddMsg((uint8_t *)msg,len); - free(msg); - } - else { - if (!(msg=(char *)malloc(16000))) return; - - for (i=0,p=msg;i0) { - p+=sprintf(p," inb = %d\n",inb); - p+=sprintf(p," inr = %d\n",inr); - } - if (outb>0) { - p+=sprintf(p," outb = %d\n",outb); - p+=sprintf(p," outr = %d\n",outr); - } - } - StrMonDialog->AddMsg((uint8_t *)msg,strlen(msg)); - - free(msg); - } +void __fastcall TMainForm::Timer2Timer(TObject *Sender) { + const char *types[] = {"None", "Serial", "File", "TCP Server", + "TCP Client", "Ntrip Server", "Ntrip Client", "FTP", + "HTTP", "Ntrip Cast", "UDP Server", "UDP Client"}; + const char *modes[] = {"-", "R", "W", "R/W"}; + const char *states[] = {"ERR", "-", "WAIT", "CONN"}; + stream_t *str; + char *msg, *p; + int i, len, inb, inr, outb, outr; + + if (StrMonDialog->StrFmt) { + rtklib_lock(&strsvr.lock); + len = strsvr.npb; + if (len > 0 && (msg = (char *)malloc(len))) { + memcpy(msg, strsvr.pbuf, len); + strsvr.npb = 0; + } + rtklib_unlock(&strsvr.lock); + if (len <= 0 || !msg) return; + StrMonDialog->AddMsg((uint8_t *)msg, len); + free(msg); + } else { + if (!(msg = (char *)malloc(16000))) return; + + for (i = 0, p = msg; i < MAXSTR; i++) { + p += sprintf(p, "[STREAM %d]\n", i); + strsum(strsvr.stream + i, &inb, &inr, &outb, &outr); + strstatx(strsvr.stream + i, p); + p += strlen(p); + if (inb > 0) { + p += sprintf(p, " inb = %d\n", inb); + p += sprintf(p, " inr = %d\n", inr); + } + if (outb > 0) { + p += sprintf(p, " outb = %d\n", outb); + p += sprintf(p, " outr = %d\n", outr); + } + } + StrMonDialog->AddMsg((uint8_t *)msg, strlen(msg)); + + free(msg); + } } // set serial options ------------------------------------------------------- -void __fastcall TMainForm::SerialOpt(int index, int path) -{ - SerialOptDialog->Path=Paths[index][path]; - SerialOptDialog->Opt=(index==0)?0:1; - if (SerialOptDialog->ShowModal()!=mrOk) return; - Paths[index][path]=SerialOptDialog->Path; +void __fastcall TMainForm::SerialOpt(int index, int path) { + SerialOptDialog->Path = Paths[index][path]; + SerialOptDialog->Opt = (index == 0) ? 0 : 1; + if (SerialOptDialog->ShowModal() != mrOk) return; + Paths[index][path] = SerialOptDialog->Path; } // set tcp server options --------------------------------------------------- -void __fastcall TMainForm::TcpSvrOpt(int index, int path) -{ - TcpOptDialog->Path=Paths[index][path]; - TcpOptDialog->Opt=0; - if (TcpOptDialog->ShowModal()!=mrOk) return; - Paths[index][path]=TcpOptDialog->Path; +void __fastcall TMainForm::TcpSvrOpt(int index, int path) { + TcpOptDialog->Path = Paths[index][path]; + TcpOptDialog->Opt = 0; + if (TcpOptDialog->ShowModal() != mrOk) return; + Paths[index][path] = TcpOptDialog->Path; } // set tcp client options --------------------------------------------------- -void __fastcall TMainForm::TcpCliOpt(int index, int path) -{ - TcpOptDialog->Path=Paths[index][path]; - TcpOptDialog->Opt=1; - for (int i=0;iHistory[i]=TcpHistory[i]; - if (TcpOptDialog->ShowModal()!=mrOk) return; - Paths[index][path]=TcpOptDialog->Path; - for (int i=0;iHistory[i]; +void __fastcall TMainForm::TcpCliOpt(int index, int path) { + TcpOptDialog->Path = Paths[index][path]; + TcpOptDialog->Opt = 1; + for (int i = 0; i < MAXHIST; i++) TcpOptDialog->History[i] = TcpHistory[i]; + if (TcpOptDialog->ShowModal() != mrOk) return; + Paths[index][path] = TcpOptDialog->Path; + for (int i = 0; i < MAXHIST; i++) TcpHistory[i] = TcpOptDialog->History[i]; } // set ntrip server options ------------------------------------------------- -void __fastcall TMainForm::NtripSvrOpt(int index, int path) -{ - TcpOptDialog->Path=Paths[index][path]; - TcpOptDialog->Opt=2; - for (int i=0;iHistory[i]=TcpHistory[i]; - if (TcpOptDialog->ShowModal()!=mrOk) return; - Paths[index][path]=TcpOptDialog->Path; - for (int i=0;iHistory[i]; +void __fastcall TMainForm::NtripSvrOpt(int index, int path) { + TcpOptDialog->Path = Paths[index][path]; + TcpOptDialog->Opt = 2; + for (int i = 0; i < MAXHIST; i++) TcpOptDialog->History[i] = TcpHistory[i]; + if (TcpOptDialog->ShowModal() != mrOk) return; + Paths[index][path] = TcpOptDialog->Path; + for (int i = 0; i < MAXHIST; i++) TcpHistory[i] = TcpOptDialog->History[i]; } // set ntrip client options ------------------------------------------------- -void __fastcall TMainForm::NtripCliOpt(int index, int path) -{ - TcpOptDialog->Path=Paths[index][path]; - TcpOptDialog->Opt=3; - for (int i=0;iHistory[i]=TcpHistory[i]; - if (TcpOptDialog->ShowModal()!=mrOk) return; - Paths[index][path]=TcpOptDialog->Path; - for (int i=0;iHistory[i]; +void __fastcall TMainForm::NtripCliOpt(int index, int path) { + TcpOptDialog->Path = Paths[index][path]; + TcpOptDialog->Opt = 3; + for (int i = 0; i < MAXHIST; i++) TcpOptDialog->History[i] = TcpHistory[i]; + if (TcpOptDialog->ShowModal() != mrOk) return; + Paths[index][path] = TcpOptDialog->Path; + for (int i = 0; i < MAXHIST; i++) TcpHistory[i] = TcpOptDialog->History[i]; } // set ntrip caster options ------------------------------------------------- -void __fastcall TMainForm::NtripCasOpt(int index, int path) -{ - TcpOptDialog->Path=Paths[index][path]; - TcpOptDialog->Opt=4; - if (TcpOptDialog->ShowModal()!=mrOk) return; - Paths[index][path]=TcpOptDialog->Path; +void __fastcall TMainForm::NtripCasOpt(int index, int path) { + TcpOptDialog->Path = Paths[index][path]; + TcpOptDialog->Opt = 4; + if (TcpOptDialog->ShowModal() != mrOk) return; + Paths[index][path] = TcpOptDialog->Path; } // set udp server options --------------------------------------------------- -void __fastcall TMainForm::UdpSvrOpt(int index, int path) -{ - TcpOptDialog->Path=Paths[index][path]; - TcpOptDialog->Opt=6; - if (TcpOptDialog->ShowModal()!=mrOk) return; - Paths[index][path]=TcpOptDialog->Path; +void __fastcall TMainForm::UdpSvrOpt(int index, int path) { + TcpOptDialog->Path = Paths[index][path]; + TcpOptDialog->Opt = 6; + if (TcpOptDialog->ShowModal() != mrOk) return; + Paths[index][path] = TcpOptDialog->Path; } // set udp client options --------------------------------------------------- -void __fastcall TMainForm::UdpCliOpt(int index, int path) -{ - TcpOptDialog->Path=Paths[index][path]; - TcpOptDialog->Opt=7; - for (int i=0;iHistory[i]=TcpHistory[i]; - if (TcpOptDialog->ShowModal()!=mrOk) return; - Paths[index][path]=TcpOptDialog->Path; - for (int i=0;iHistory[i]; +void __fastcall TMainForm::UdpCliOpt(int index, int path) { + TcpOptDialog->Path = Paths[index][path]; + TcpOptDialog->Opt = 7; + for (int i = 0; i < MAXHIST; i++) TcpOptDialog->History[i] = TcpHistory[i]; + if (TcpOptDialog->ShowModal() != mrOk) return; + Paths[index][path] = TcpOptDialog->Path; + for (int i = 0; i < MAXHIST; i++) TcpHistory[i] = TcpOptDialog->History[i]; } // set file options --------------------------------------------------------- -void __fastcall TMainForm::FileOpt(int index, int path) -{ - FileOptDialog->Path=Paths[index][path]; - FileOptDialog->Caption="File Options"; - FileOptDialog->Opt=(index==0)?0:1; - if (FileOptDialog->ShowModal()!=mrOk) return; - Paths[index][path]=FileOptDialog->Path; +void __fastcall TMainForm::FileOpt(int index, int path) { + FileOptDialog->Path = Paths[index][path]; + FileOptDialog->Caption = "File Options"; + FileOptDialog->Opt = (index == 0) ? 0 : 1; + if (FileOptDialog->ShowModal() != mrOk) return; + Paths[index][path] = FileOptDialog->Path; } // undate enable of widgets ------------------------------------------------- -void __fastcall TMainForm::UpdateEnable(void) -{ - TComboBox *type[]={Output1,Output2,Output3,Output4,Output5,Output6}; - TLabel *label1[]={LabelOutput1,LabelOutput2,LabelOutput3,LabelOutput4,LabelOutput5,LabelOutput6}; - TLabel *label2[]={Output1Byte,Output2Byte,Output3Byte,Output4Byte,Output5Byte,Output6Byte}; - TLabel *label3[]={Output1Bps,Output2Bps,Output3Bps,Output4Bps,Output5Bps,Output6Bps}; - TButton *btn1[]={BtnOutput1,BtnOutput2,BtnOutput3,BtnOutput4,BtnOutput5,BtnOutput6}; - TButton *btn2[]={BtnCmd1,BtnCmd2,BtnCmd3,BtnCmd4,BtnCmd5,BtnCmd6}; - TButton *btn3[]={BtnConv1,BtnConv2,BtnConv3,BtnConv4,BtnConv5,BtnConv6}; - TButton *btn4[]={BtnLog1,BtnLog2,BtnLog3,BtnLog4,BtnLog5,BtnLog6}; - - BtnCmd->Enabled=Input->ItemIndex<2||Input->ItemIndex==3; - BtnLog->Enabled=Input->ItemIndex<6; - for (int i=0;iFont->Color=type[i]->ItemIndex>0?clBlack:clGray; - label2[i]->Font->Color=type[i]->ItemIndex>0?clBlack:clGray; - label3[i]->Font->Color=type[i]->ItemIndex>0?clBlack:clGray; - btn1[i]->Enabled=type[i]->ItemIndex>0; - btn2[i]->Enabled=btn1[i]->Enabled&&(type[i]->ItemIndex==1||type[i]->ItemIndex==2); - btn3[i]->Enabled=btn1[i]->Enabled&&Input->ItemIndex!=2&&Input->ItemIndex!=4; - btn4[i]->Enabled=btn1[i]->Enabled&&(type[i]->ItemIndex==1||type[i]->ItemIndex==2); - } +void __fastcall TMainForm::UpdateEnable(void) { + TComboBox *type[] = {Output1, Output2, Output3, Output4, Output5, Output6}; + TLabel *label1[] = {LabelOutput1, LabelOutput2, LabelOutput3, + LabelOutput4, LabelOutput5, LabelOutput6}; + TLabel *label2[] = {Output1Byte, Output2Byte, Output3Byte, Output4Byte, Output5Byte, Output6Byte}; + TLabel *label3[] = {Output1Bps, Output2Bps, Output3Bps, Output4Bps, Output5Bps, Output6Bps}; + TButton *btn1[] = {BtnOutput1, BtnOutput2, BtnOutput3, BtnOutput4, BtnOutput5, BtnOutput6}; + TButton *btn2[] = {BtnCmd1, BtnCmd2, BtnCmd3, BtnCmd4, BtnCmd5, BtnCmd6}; + TButton *btn3[] = {BtnConv1, BtnConv2, BtnConv3, BtnConv4, BtnConv5, BtnConv6}; + TButton *btn4[] = {BtnLog1, BtnLog2, BtnLog3, BtnLog4, BtnLog5, BtnLog6}; + + BtnCmd->Enabled = Input->ItemIndex < 2 || Input->ItemIndex == 3; + BtnLog->Enabled = Input->ItemIndex < 6; + for (int i = 0; i < MAXSTR - 1; i++) { + label1[i]->Font->Color = type[i]->ItemIndex > 0 ? clBlack : clGray; + label2[i]->Font->Color = type[i]->ItemIndex > 0 ? clBlack : clGray; + label3[i]->Font->Color = type[i]->ItemIndex > 0 ? clBlack : clGray; + btn1[i]->Enabled = type[i]->ItemIndex > 0; + btn2[i]->Enabled = btn1[i]->Enabled && (type[i]->ItemIndex == 1 || type[i]->ItemIndex == 2); + btn3[i]->Enabled = btn1[i]->Enabled && Input->ItemIndex != 2 && Input->ItemIndex != 4; + btn4[i]->Enabled = btn1[i]->Enabled && (type[i]->ItemIndex == 1 || type[i]->ItemIndex == 2); + } } // set task-tray icon ------------------------------------------------------- -void __fastcall TMainForm::SetTrayIcon(int index) -{ - TIcon *icon=new TIcon; - ImageList->GetIcon(index,icon); - TrayIcon->Icon=icon; - delete icon; +void __fastcall TMainForm::SetTrayIcon(int index) { + TIcon *icon = new TIcon; + ImageList->GetIcon(index, icon); + TrayIcon->Icon = icon; + delete icon; } // load options ------------------------------------------------------------- -void __fastcall TMainForm::LoadOpt(void) -{ - TIniFile *ini=new TIniFile(IniFile); - TComboBox *type[]={Output1,Output2,Output3,Output4,Output5,Output6}; - AnsiString s; - int optdef[]={10000,10000,1000,32768,10,0}; - - Input ->ItemIndex=ini->ReadInteger("set","input", 0); - for (int i=0;iItemIndex=ini->ReadInteger("set",s,0); - } - TraceLevel =ini->ReadInteger("set","tracelevel", 0); - NmeaReq =ini->ReadInteger("set","nmeareq", 0); - FileSwapMargin =ini->ReadInteger("set","fswapmargin",30); - RelayBack =ini->ReadInteger("set","relayback", 0); - ProgBarRange =ini->ReadInteger("set","progbarrange",2000); - StaId =ini->ReadInteger("set","staid" ,0); - StaSel =ini->ReadInteger("set","stasel" ,0); - AntType =ini->ReadString ("set","anttype", ""); - RcvType =ini->ReadString ("set","rcvtype", ""); - - for (int i=0;i<6;i++) { - SvrOpt[i]=ini->ReadInteger("set",s.sprintf("svropt_%d",i),optdef[i]); - } - for (int i=0;i<3;i++) { - AntPos[i]=ini->ReadFloat("set",s.sprintf("antpos_%d",i),0.0); - AntOff[i]=ini->ReadFloat("set",s.sprintf("antoff_%d",i),0.0); - } - for (int i=0;iReadInteger("conv",s.sprintf("ena_%d",i), 0); - ConvInp[i]=ini->ReadInteger("conv",s.sprintf("inp_%d",i), 0); - ConvOut[i]=ini->ReadInteger("conv",s.sprintf("out_%d",i), 0); - ConvMsg[i]=ini->ReadString ("conv",s.sprintf("msg_%d",i),""); - ConvOpt[i]=ini->ReadString ("conv",s.sprintf("opt_%d",i),""); - } - for (int i=0;iReadInteger("serial",s.sprintf("cmdena_%d_%d",i,j),1); - CmdEnaTcp[i][j]=ini->ReadInteger("tcpip" ,s.sprintf("cmdena_%d_%d",i,j),1); - } - for (int i=0;iReadString("path",s.sprintf("path_%d_%d",i,j),""); - } - for (int i=0;iReadString ("path",s.sprintf("path_log_%d",i),""); - PathEna[i]=ini->ReadInteger("path",s.sprintf("path_ena_%d",i),0); - } - for (int i=0;iReadString("serial",s.sprintf("cmd_%d_%d",i,j),""); - for (char *p=Cmds[i][j].c_str();*p;p++) { - if ((p=strstr(p,"@@"))) strncpy(p,"\r\n",2); else break; - } - } - for (int i=0;iReadString("tcpip",s.sprintf("cmd_%d_%d",i,j),""); - for (char *p=CmdsTcp[i][j].c_str();*p;p++) { - if ((p=strstr(p,"@@"))) strncpy(p,"\r\n",2); else break; - } - } - for (int i=0;iReadString("tcpopt",s.sprintf("history%d",i),""); - } - StaPosFile =ini->ReadString("stapos","staposfile", ""); - ExeDirectory =ini->ReadString("dirs", "exedirectory", ""); - LocalDirectory=ini->ReadString("dirs", "localdirectory",""); - ProxyAddress =ini->ReadString("dirs", "proxyaddress", ""); - LogFile =ini->ReadString("file", "logfile", ""); - Height =ini->ReadInteger("window","height", 271); - delete ini; - - UpdateEnable(); +void __fastcall TMainForm::LoadOpt(void) { + TIniFile *ini = new TIniFile(IniFile); + TComboBox *type[] = {Output1, Output2, Output3, Output4, Output5, Output6}; + AnsiString s; + int optdef[] = {10000, 10000, 1000, 32768, 10, 0}; + + Input->ItemIndex = ini->ReadInteger("set", "input", 0); + for (int i = 0; i < MAXSTR - 1; i++) { + s.sprintf("output_%d", i + 1); + type[i]->ItemIndex = ini->ReadInteger("set", s, 0); + } + TraceLevel = ini->ReadInteger("set", "tracelevel", 0); + NmeaReq = ini->ReadInteger("set", "nmeareq", 0); + FileSwapMargin = ini->ReadInteger("set", "fswapmargin", 30); + RelayBack = ini->ReadInteger("set", "relayback", 0); + ProgBarRange = ini->ReadInteger("set", "progbarrange", 2000); + StaId = ini->ReadInteger("set", "staid", 0); + StaSel = ini->ReadInteger("set", "stasel", 0); + AntType = ini->ReadString("set", "anttype", ""); + RcvType = ini->ReadString("set", "rcvtype", ""); + + for (int i = 0; i < 6; i++) { + SvrOpt[i] = ini->ReadInteger("set", s.sprintf("svropt_%d", i), optdef[i]); + } + for (int i = 0; i < 3; i++) { + AntPos[i] = ini->ReadFloat("set", s.sprintf("antpos_%d", i), 0.0); + AntOff[i] = ini->ReadFloat("set", s.sprintf("antoff_%d", i), 0.0); + } + for (int i = 0; i < MAXSTR - 1; i++) { + ConvEna[i] = ini->ReadInteger("conv", s.sprintf("ena_%d", i), 0); + ConvInp[i] = ini->ReadInteger("conv", s.sprintf("inp_%d", i), 0); + ConvOut[i] = ini->ReadInteger("conv", s.sprintf("out_%d", i), 0); + ConvMsg[i] = ini->ReadString("conv", s.sprintf("msg_%d", i), ""); + ConvOpt[i] = ini->ReadString("conv", s.sprintf("opt_%d", i), ""); + } + for (int i = 0; i < MAXSTR; i++) + for (int j = 0; j < 3; j++) { + CmdEna[i][j] = ini->ReadInteger("serial", s.sprintf("cmdena_%d_%d", i, j), 1); + CmdEnaTcp[i][j] = ini->ReadInteger("tcpip", s.sprintf("cmdena_%d_%d", i, j), 1); + } + for (int i = 0; i < MAXSTR; i++) + for (int j = 0; j < 7; j++) { + Paths[i][j] = ini->ReadString("path", s.sprintf("path_%d_%d", i, j), ""); + } + for (int i = 0; i < MAXSTR; i++) { + PathLog[i] = ini->ReadString("path", s.sprintf("path_log_%d", i), ""); + PathEna[i] = ini->ReadInteger("path", s.sprintf("path_ena_%d", i), 0); + } + for (int i = 0; i < MAXSTR; i++) + for (int j = 0; j < 3; j++) { + Cmds[i][j] = ini->ReadString("serial", s.sprintf("cmd_%d_%d", i, j), ""); + for (char *p = Cmds[i][j].c_str(); *p; p++) { + if ((p = strstr(p, "@@"))) + strncpy(p, "\r\n", 2); + else + break; + } + } + for (int i = 0; i < MAXSTR; i++) + for (int j = 0; j < 3; j++) { + CmdsTcp[i][j] = ini->ReadString("tcpip", s.sprintf("cmd_%d_%d", i, j), ""); + for (char *p = CmdsTcp[i][j].c_str(); *p; p++) { + if ((p = strstr(p, "@@"))) + strncpy(p, "\r\n", 2); + else + break; + } + } + for (int i = 0; i < MAXHIST; i++) { + TcpHistory[i] = ini->ReadString("tcpopt", s.sprintf("history%d", i), ""); + } + StaPosFile = ini->ReadString("stapos", "staposfile", ""); + ExeDirectory = ini->ReadString("dirs", "exedirectory", ""); + LocalDirectory = ini->ReadString("dirs", "localdirectory", ""); + ProxyAddress = ini->ReadString("dirs", "proxyaddress", ""); + LogFile = ini->ReadString("file", "logfile", ""); + Height = ini->ReadInteger("window", "height", 271); + delete ini; + + UpdateEnable(); } // save options-------------------------------------------------------------- -void __fastcall TMainForm::SaveOpt(void) -{ - TIniFile *ini=new TIniFile(IniFile); - TComboBox *type[]={Output1,Output2,Output3,Output4,Output5,Output6}; - AnsiString s; - - ini->WriteInteger("set","input", Input ->ItemIndex); - for (int i=0;iWriteInteger("set",s,type[i]->ItemIndex); - } - ini->WriteInteger("set","tracelevel", TraceLevel); - ini->WriteInteger("set","nmeareq", NmeaReq); - ini->WriteInteger("set","fswapmargin",FileSwapMargin); - ini->WriteInteger("set","relayback", RelayBack); - ini->WriteInteger("set","progbarrange",ProgBarRange); - ini->WriteInteger("set","staid", StaId); - ini->WriteInteger("set","stasel", StaSel); - ini->WriteString ("set","anttype", AntType); - ini->WriteString ("set","rcvtype", RcvType); - - for (int i=0;i<6;i++) { - ini->WriteInteger("set",s.sprintf("svropt_%d",i),SvrOpt[i]); - } - for (int i=0;i<3;i++) { - ini->WriteFloat("set",s.sprintf("antpos_%d",i),AntPos[i]); - ini->WriteFloat("set",s.sprintf("antoff_%d",i),AntOff[i]); - } - for (int i=0;iWriteInteger("conv",s.sprintf("ena_%d",i),ConvEna[i]); - ini->WriteInteger("conv",s.sprintf("inp_%d",i),ConvInp[i]); - ini->WriteInteger("conv",s.sprintf("out_%d",i),ConvOut[i]); - ini->WriteString ("conv",s.sprintf("msg_%d",i),ConvMsg[i]); - ini->WriteString ("conv",s.sprintf("opt_%d",i),ConvOpt[i]); - } - for (int i=0;iWriteInteger("serial",s.sprintf("cmdena_%d_%d",i,j),CmdEna [i][j]); - ini->WriteInteger("tcpip" ,s.sprintf("cmdena_%d_%d",i,j),CmdEnaTcp[i][j]); - } - for (int i=0;iWriteString("path",s.sprintf("path_%d_%d",i,j),Paths[i][j]); - } - for (int i=0;iWriteString ("path",s.sprintf("path_log_%d",i),PathLog[i]); - ini->WriteInteger("path",s.sprintf("path_ena_%d",i),PathEna[i]); - } - for (int i=0;iWriteString("serial",s.sprintf("cmd_%d_%d",i,j),Cmds[i][j]); - } - for (int i=0;iWriteString("tcpip",s.sprintf("cmd_%d_%d",i,j),CmdsTcp[i][j]); - } - for (int i=0;iWriteString("tcpopt",s.sprintf("history%d",i),TcpOptDialog->History[i]); - } - ini->WriteString("stapos","staposfile" ,StaPosFile ); - ini->WriteString("dirs" ,"exedirectory" ,ExeDirectory ); - ini->WriteString("dirs" ,"localdirectory",LocalDirectory); - ini->WriteString("dirs" ,"proxyaddress" ,ProxyAddress ); - ini->WriteString("file", "logfile" ,LogFile ); - ini->WriteInteger("window","height" ,Height ); - delete ini; +void __fastcall TMainForm::SaveOpt(void) { + TIniFile *ini = new TIniFile(IniFile); + TComboBox *type[] = {Output1, Output2, Output3, Output4, Output5, Output6}; + AnsiString s; + + ini->WriteInteger("set", "input", Input->ItemIndex); + for (int i = 0; i < MAXSTR - 1; i++) { + s.printf("output_%d", i + 1); + ini->WriteInteger("set", s, type[i]->ItemIndex); + } + ini->WriteInteger("set", "tracelevel", TraceLevel); + ini->WriteInteger("set", "nmeareq", NmeaReq); + ini->WriteInteger("set", "fswapmargin", FileSwapMargin); + ini->WriteInteger("set", "relayback", RelayBack); + ini->WriteInteger("set", "progbarrange", ProgBarRange); + ini->WriteInteger("set", "staid", StaId); + ini->WriteInteger("set", "stasel", StaSel); + ini->WriteString("set", "anttype", AntType); + ini->WriteString("set", "rcvtype", RcvType); + + for (int i = 0; i < 6; i++) { + ini->WriteInteger("set", s.sprintf("svropt_%d", i), SvrOpt[i]); + } + for (int i = 0; i < 3; i++) { + ini->WriteFloat("set", s.sprintf("antpos_%d", i), AntPos[i]); + ini->WriteFloat("set", s.sprintf("antoff_%d", i), AntOff[i]); + } + for (int i = 0; i < MAXSTR - 1; i++) { + ini->WriteInteger("conv", s.sprintf("ena_%d", i), ConvEna[i]); + ini->WriteInteger("conv", s.sprintf("inp_%d", i), ConvInp[i]); + ini->WriteInteger("conv", s.sprintf("out_%d", i), ConvOut[i]); + ini->WriteString("conv", s.sprintf("msg_%d", i), ConvMsg[i]); + ini->WriteString("conv", s.sprintf("opt_%d", i), ConvOpt[i]); + } + for (int i = 0; i < MAXSTR; i++) + for (int j = 0; j < 3; j++) { + ini->WriteInteger("serial", s.sprintf("cmdena_%d_%d", i, j), CmdEna[i][j]); + ini->WriteInteger("tcpip", s.sprintf("cmdena_%d_%d", i, j), CmdEnaTcp[i][j]); + } + for (int i = 0; i < MAXSTR; i++) + for (int j = 0; j < 7; j++) { + ini->WriteString("path", s.sprintf("path_%d_%d", i, j), Paths[i][j]); + } + for (int i = 0; i < MAXSTR; i++) { + ini->WriteString("path", s.sprintf("path_log_%d", i), PathLog[i]); + ini->WriteInteger("path", s.sprintf("path_ena_%d", i), PathEna[i]); + } + for (int i = 0; i < MAXSTR; i++) + for (int j = 0; j < 3; j++) { + for (char *p = Cmds[i][j].c_str(); *p; p++) { + if ((p = strstr(p, "\r\n"))) + strncpy(p, "@@", 2); + else + break; + } + ini->WriteString("serial", s.sprintf("cmd_%d_%d", i, j), Cmds[i][j]); + } + for (int i = 0; i < MAXSTR; i++) + for (int j = 0; j < 3; j++) { + for (char *p = CmdsTcp[i][j].c_str(); *p; p++) { + if ((p = strstr(p, "\r\n"))) + strncpy(p, "@@", 2); + else + break; + } + ini->WriteString("tcpip", s.sprintf("cmd_%d_%d", i, j), CmdsTcp[i][j]); + } + for (int i = 0; i < MAXHIST; i++) { + ini->WriteString("tcpopt", s.sprintf("history%d", i), TcpOptDialog->History[i]); + } + ini->WriteString("stapos", "staposfile", StaPosFile); + ini->WriteString("dirs", "exedirectory", ExeDirectory); + ini->WriteString("dirs", "localdirectory", LocalDirectory); + ini->WriteString("dirs", "proxyaddress", ProxyAddress); + ini->WriteString("file", "logfile", LogFile); + ini->WriteInteger("window", "height", Height); + delete ini; } //--------------------------------------------------------------------------- -void __fastcall TMainForm::BtnLogClick(TObject *Sender) -{ - TButton *btn[]={BtnLog,BtnLog1,BtnLog2,BtnLog3,BtnLog4,BtnLog5,BtnLog6}; - int i; - - for (i=0;i=MAXSTR) return; - - FileOptDialog->Path=PathLog[i]; - FileOptDialog->PathEna=PathEna[i]; - FileOptDialog->Caption=(i==0)?"Input Log Options":"Return Log Options"; - FileOptDialog->Opt=2; - if (FileOptDialog->ShowModal()!=mrOk) return; - PathLog[i]=FileOptDialog->Path; - PathEna[i]=FileOptDialog->PathEna; +void __fastcall TMainForm::BtnLogClick(TObject *Sender) { + TButton *btn[] = {BtnLog, BtnLog1, BtnLog2, BtnLog3, BtnLog4, BtnLog5, BtnLog6}; + int i; + + for (i = 0; i < MAXSTR; i++) { + if ((TButton *)Sender == btn[i]) break; + } + if (i >= MAXSTR) return; + + FileOptDialog->Path = PathLog[i]; + FileOptDialog->PathEna = PathEna[i]; + FileOptDialog->Caption = (i == 0) ? "Input Log Options" : "Return Log Options"; + FileOptDialog->Opt = 2; + if (FileOptDialog->ShowModal() != mrOk) return; + PathLog[i] = FileOptDialog->Path; + PathEna[i] = FileOptDialog->PathEna; } //--------------------------------------------------------------------------- - diff --git a/app/winapp/strsvr/svrmain.h b/app/winapp/strsvr/svrmain.h index 779ee45ac..68ea1875d 100644 --- a/app/winapp/strsvr/svrmain.h +++ b/app/winapp/strsvr/svrmain.h @@ -2,198 +2,198 @@ #ifndef svrmainH #define svrmainH //--------------------------------------------------------------------------- +#include #include +#include #include -#include -#include #include -#include +#include #include -#include -#include #include +#include +#include +#include #include "rtklib.h" #include "tcpoptdlg.h" -#include -#define MAXSTR 7 // number of streams +#define MAXSTR 7 // number of streams //--------------------------------------------------------------------------- -class TMainForm : public TForm -{ -__published: - TPanel *Panel1; - TLabel *LabelInput; - TLabel *LabelOutput1; - TComboBox *Input; - TLabel *Label3; - TComboBox *Output1; - TButton *BtnInput; - TLabel *Label4; - TButton *BtnOutput1; - TButton *BtnOutput2; - TLabel *InputByte; - TPanel *IndInput; - TLabel *Label6; - TLabel *Label7; - TLabel *LabelOutput2; - TComboBox *Output2; - TLabel *InputBps; - TLabel *Output1Byte; - TLabel *Output1Bps; - TLabel *Output2Byte; - TLabel *Output2Bps; - TPanel *IndOutput1; - TPanel *IndOutput2; - TLabel *Label5; - TTimer *Timer1; - TLabel *LabelOutput5; - TComboBox *Output5; - TButton *BtnOutput5; - TLabel *Output5Byte; - TLabel *Output5Bps; - TPanel *IndOutput5; - TButton *BtnCmd; - TLabel *Label1; - TPanel *Panel4; - TLabel *Message; - TProgressBar *Progress; - TSpeedButton *BtnAbout; - TSpeedButton *BtnStrMon; - TTimer *Timer2; - TSpeedButton *BtnTaskIcon; - TPopupMenu *PopupMenu; - TMenuItem *MenuStart; - TMenuItem *MenuStop; - TMenuItem *N1; - TMenuItem *N2; - TMenuItem *MenuExpand; - TMenuItem *MenuExit; - TTrayIcon *TrayIcon; - TImageList *ImageList; - TPanel *Panel2; - TLabel *Label8; - TLabel *ConTime; - TLabel *Time; - TButton *BtnConv1; - TButton *BtnConv2; - TButton *BtnConv5; - TLabel *Label2; - TBitBtn *BtnStart; - TBitBtn *BtnStop; - TBitBtn *BtnOpt; - TBitBtn *BtnExit; - TButton *BtnCmd1; - TButton *BtnCmd2; - TButton *BtnCmd5; - TPanel *Panel5; - TPanel *Panel12; - TPanel *Panel11; - TPanel *Panel13; - TPanel *Panel14; - TPanel *Panel17; - TPanel *Panel16; - TLabel *LabelOutput4; - TLabel *Output4Bps; - TLabel *Output4Byte; - TButton *BtnCmd4; - TButton *BtnConv4; - TButton *BtnOutput4; - TPanel *IndOutput4; - TComboBox *Output4; - TPanel *Panel15; - TLabel *LabelOutput3; - TLabel *Output3Bps; - TLabel *Output3Byte; - TButton *BtnCmd3; - TButton *BtnConv3; - TButton *BtnOutput3; - TPanel *IndOutput3; - TComboBox *Output3; - TLabel *Label9; - TButton *BtnLog1; - TButton *BtnLog2; - TButton *BtnLog3; - TButton *BtnLog4; - TButton *BtnLog5; - TPanel *Panel18; - TLabel *LabelOutput6; - TLabel *Output6Bps; - TLabel *Output6Byte; - TButton *BtnCmd6; - TButton *BtnConv6; - TButton *BtnOutput6; - TPanel *IndOutput6; - TComboBox *Output6; - TButton *BtnLog6; - TButton *BtnLog; - TPanel *IndLog; - TPanel *IndLog1; - TPanel *IndLog2; - TPanel *IndLog3; - TPanel *IndLog4; - TPanel *IndLog5; - TPanel *IndLog6; - void __fastcall BtnExitClick(TObject *Sender); - void __fastcall BtnInputClick(TObject *Sender); - void __fastcall BtnOutputClick(TObject *Sender); - void __fastcall BtnStartClick(TObject *Sender); - void __fastcall BtnStopClick(TObject *Sender); - void __fastcall FormClose(TObject *Sender, TCloseAction &Action); - void __fastcall Timer1Timer(TObject *Sender); - void __fastcall BtnOptClick(TObject *Sender); - void __fastcall OutputChange(TObject *Sender); - void __fastcall InputChange(TObject *Sender); - void __fastcall BtnCmdClick(TObject *Sender); - void __fastcall BtnAboutClick(TObject *Sender); - void __fastcall BtnStrMonClick(TObject *Sender); - void __fastcall Timer2Timer(TObject *Sender); - void __fastcall BtnTaskIconClick(TObject *Sender); - void __fastcall MenuExpandClick(TObject *Sender); - void __fastcall TrayIconDblClick(TObject *Sender); - void __fastcall MenuStartClick(TObject *Sender); - void __fastcall MenuStopClick(TObject *Sender); - void __fastcall MenuExitClick(TObject *Sender); - void __fastcall FormCreate(TObject *Sender); - void __fastcall BtnConvClick(TObject *Sender); - void __fastcall EnaOut1Click(TObject *Sender); - void __fastcall FormShow(TObject *Sender); - void __fastcall TrayIconMouseDown(TObject *Sender, TMouseButton Button, TShiftState Shift, - int X, int Y); - void __fastcall BtnLogClick(TObject *Sender); -private: - AnsiString IniFile; - AnsiString Paths[MAXSTR][7],Cmds[MAXSTR][3],CmdsTcp[MAXSTR][3]; - AnsiString TcpHistory[MAXHIST],TcpMntpHist[MAXHIST]; - AnsiString StaPosFile,ExeDirectory,LocalDirectory,SwapInterval; - AnsiString ProxyAddress,LogFile; - AnsiString ConvMsg[MAXSTR-1],ConvOpt[MAXSTR-1],AntType,RcvType; - AnsiString PathLog[MAXSTR]; - int ConvEna[MAXSTR-1],ConvInp[MAXSTR-1],ConvOut[MAXSTR-1],StaId,StaSel; - int TraceLevel,SvrOpt[6],CmdEna[MAXSTR][3],CmdEnaTcp[MAXSTR][3]; - int NmeaReq,FileSwapMargin,RelayBack,ProgBarRange,PathEna[MAXSTR]; - double AntPos[3],AntOff[3]; - gtime_t StartTime,EndTime; - - void __fastcall SerialOpt(int index, int path); - void __fastcall TcpCliOpt(int index, int path); - void __fastcall TcpSvrOpt(int index, int path); - void __fastcall NtripSvrOpt(int index, int path); - void __fastcall NtripCliOpt(int index, int path); - void __fastcall NtripCasOpt(int index, int path); - void __fastcall UdpCliOpt(int index, int path); - void __fastcall UdpSvrOpt(int index, int path); - void __fastcall FileOpt(int index, int path); - void __fastcall ShowMsg(AnsiString msg); - void __fastcall SvrStart(void); - void __fastcall SvrStop(void); - void __fastcall UpdateEnable(void); - void __fastcall SetTrayIcon(int index); - void __fastcall LoadOpt(void); - void __fastcall SaveOpt(void); -public: - __fastcall TMainForm(TComponent* Owner); +class TMainForm : public TForm { + __published : TPanel *Panel1; + TLabel *LabelInput; + TLabel *LabelOutput1; + TComboBox *Input; + TLabel *Label3; + TComboBox *Output1; + TButton *BtnInput; + TLabel *Label4; + TButton *BtnOutput1; + TButton *BtnOutput2; + TLabel *InputByte; + TPanel *IndInput; + TLabel *Label6; + TLabel *Label7; + TLabel *LabelOutput2; + TComboBox *Output2; + TLabel *InputBps; + TLabel *Output1Byte; + TLabel *Output1Bps; + TLabel *Output2Byte; + TLabel *Output2Bps; + TPanel *IndOutput1; + TPanel *IndOutput2; + TLabel *Label5; + TTimer *Timer1; + TLabel *LabelOutput5; + TComboBox *Output5; + TButton *BtnOutput5; + TLabel *Output5Byte; + TLabel *Output5Bps; + TPanel *IndOutput5; + TButton *BtnCmd; + TLabel *Label1; + TPanel *Panel4; + TLabel *Message; + TProgressBar *Progress; + TSpeedButton *BtnAbout; + TSpeedButton *BtnStrMon; + TTimer *Timer2; + TSpeedButton *BtnTaskIcon; + TPopupMenu *PopupMenu; + TMenuItem *MenuStart; + TMenuItem *MenuStop; + TMenuItem *N1; + TMenuItem *N2; + TMenuItem *MenuExpand; + TMenuItem *MenuExit; + TTrayIcon *TrayIcon; + TImageList *ImageList; + TPanel *Panel2; + TLabel *Label8; + TLabel *ConTime; + TLabel *Time; + TButton *BtnConv1; + TButton *BtnConv2; + TButton *BtnConv5; + TLabel *Label2; + TBitBtn *BtnStart; + TBitBtn *BtnStop; + TBitBtn *BtnOpt; + TBitBtn *BtnExit; + TButton *BtnCmd1; + TButton *BtnCmd2; + TButton *BtnCmd5; + TPanel *Panel5; + TPanel *Panel12; + TPanel *Panel11; + TPanel *Panel13; + TPanel *Panel14; + TPanel *Panel17; + TPanel *Panel16; + TLabel *LabelOutput4; + TLabel *Output4Bps; + TLabel *Output4Byte; + TButton *BtnCmd4; + TButton *BtnConv4; + TButton *BtnOutput4; + TPanel *IndOutput4; + TComboBox *Output4; + TPanel *Panel15; + TLabel *LabelOutput3; + TLabel *Output3Bps; + TLabel *Output3Byte; + TButton *BtnCmd3; + TButton *BtnConv3; + TButton *BtnOutput3; + TPanel *IndOutput3; + TComboBox *Output3; + TLabel *Label9; + TButton *BtnLog1; + TButton *BtnLog2; + TButton *BtnLog3; + TButton *BtnLog4; + TButton *BtnLog5; + TPanel *Panel18; + TLabel *LabelOutput6; + TLabel *Output6Bps; + TLabel *Output6Byte; + TButton *BtnCmd6; + TButton *BtnConv6; + TButton *BtnOutput6; + TPanel *IndOutput6; + TComboBox *Output6; + TButton *BtnLog6; + TButton *BtnLog; + TPanel *IndLog; + TPanel *IndLog1; + TPanel *IndLog2; + TPanel *IndLog3; + TPanel *IndLog4; + TPanel *IndLog5; + TPanel *IndLog6; + void __fastcall BtnExitClick(TObject *Sender); + void __fastcall BtnInputClick(TObject *Sender); + void __fastcall BtnOutputClick(TObject *Sender); + void __fastcall BtnStartClick(TObject *Sender); + void __fastcall BtnStopClick(TObject *Sender); + void __fastcall FormClose(TObject *Sender, TCloseAction &Action); + void __fastcall Timer1Timer(TObject *Sender); + void __fastcall BtnOptClick(TObject *Sender); + void __fastcall OutputChange(TObject *Sender); + void __fastcall InputChange(TObject *Sender); + void __fastcall BtnCmdClick(TObject *Sender); + void __fastcall BtnAboutClick(TObject *Sender); + void __fastcall BtnStrMonClick(TObject *Sender); + void __fastcall Timer2Timer(TObject *Sender); + void __fastcall BtnTaskIconClick(TObject *Sender); + void __fastcall MenuExpandClick(TObject *Sender); + void __fastcall TrayIconDblClick(TObject *Sender); + void __fastcall MenuStartClick(TObject *Sender); + void __fastcall MenuStopClick(TObject *Sender); + void __fastcall MenuExitClick(TObject *Sender); + void __fastcall FormCreate(TObject *Sender); + void __fastcall BtnConvClick(TObject *Sender); + void __fastcall EnaOut1Click(TObject *Sender); + void __fastcall FormShow(TObject *Sender); + void __fastcall TrayIconMouseDown(TObject *Sender, TMouseButton Button, TShiftState Shift, int X, + int Y); + void __fastcall BtnLogClick(TObject *Sender); + + private: + AnsiString IniFile; + AnsiString Paths[MAXSTR][7], Cmds[MAXSTR][3], CmdsTcp[MAXSTR][3]; + AnsiString TcpHistory[MAXHIST], TcpMntpHist[MAXHIST]; + AnsiString StaPosFile, ExeDirectory, LocalDirectory, SwapInterval; + AnsiString ProxyAddress, LogFile; + AnsiString ConvMsg[MAXSTR - 1], ConvOpt[MAXSTR - 1], AntType, RcvType; + AnsiString PathLog[MAXSTR]; + int ConvEna[MAXSTR - 1], ConvInp[MAXSTR - 1], ConvOut[MAXSTR - 1], StaId, StaSel; + int TraceLevel, SvrOpt[6], CmdEna[MAXSTR][3], CmdEnaTcp[MAXSTR][3]; + int NmeaReq, FileSwapMargin, RelayBack, ProgBarRange, PathEna[MAXSTR]; + double AntPos[3], AntOff[3]; + gtime_t StartTime, EndTime; + + void __fastcall SerialOpt(int index, int path); + void __fastcall TcpCliOpt(int index, int path); + void __fastcall TcpSvrOpt(int index, int path); + void __fastcall NtripSvrOpt(int index, int path); + void __fastcall NtripCliOpt(int index, int path); + void __fastcall NtripCasOpt(int index, int path); + void __fastcall UdpCliOpt(int index, int path); + void __fastcall UdpSvrOpt(int index, int path); + void __fastcall FileOpt(int index, int path); + void __fastcall ShowMsg(AnsiString msg); + void __fastcall SvrStart(void); + void __fastcall SvrStop(void); + void __fastcall UpdateEnable(void); + void __fastcall SetTrayIcon(int index); + void __fastcall LoadOpt(void); + void __fastcall SaveOpt(void); + + public: + __fastcall TMainForm(TComponent *Owner); }; //--------------------------------------------------------------------------- extern PACKAGE TMainForm *MainForm; diff --git a/app/winapp/strsvr/svroptdlg.cpp b/app/winapp/strsvr/svroptdlg.cpp index 6dccb0d70..b1d539923 100644 --- a/app/winapp/strsvr/svroptdlg.cpp +++ b/app/winapp/strsvr/svroptdlg.cpp @@ -1,163 +1,146 @@ //--------------------------------------------------------------------------- #include + #include #pragma hdrstop -#include "rtklib.h" -#include "refdlg.h" #include "svroptdlg.h" + +#include "refdlg.h" +#include "rtklib.h" //--------------------------------------------------------------------------- #pragma package(smart_init) #pragma resource "*.dfm" TSvrOptDialog *SvrOptDialog; //--------------------------------------------------------------------------- -static double str2dbl(AnsiString str) -{ - double val=0.0; - sscanf(str.c_str(),"%lf",&val); - return val; +static double str2dbl(AnsiString str) { + double val = 0.0; + sscanf(str.c_str(), "%lf", &val); + return val; } //--------------------------------------------------------------------------- -__fastcall TSvrOptDialog::TSvrOptDialog(TComponent* Owner) - : TForm(Owner) -{ -} +__fastcall TSvrOptDialog::TSvrOptDialog(TComponent *Owner) : TForm(Owner) {} //--------------------------------------------------------------------------- -void __fastcall TSvrOptDialog::FormShow(TObject *Sender) -{ - double pos[3]; - AnsiString s; - DataTimeout->Text=s.sprintf("%d",SvrOpt[0]); - ConnectInterval->Text=s.sprintf("%d",SvrOpt[1]); - AvePeriodRate->Text=s.sprintf("%d",SvrOpt[2]); - SvrBuffSize->Text=s.sprintf("%d",SvrOpt[3]); - SvrCycle->Text=s.sprintf("%d",SvrOpt[4]); - ProgBarR->Text=s.sprintf("%d",ProgBarRange); - RelayMsg->ItemIndex=RelayBack; - NmeaCycle->Text=s.sprintf("%d",SvrOpt[5]); - FileSwapMarginE->Text=s.sprintf("%d",FileSwapMargin); - if (norm(AntPos,3)>0.0) { - ecef2pos(AntPos,pos); - AntPos1->Text=s.sprintf("%.8f",pos[0]*R2D); - AntPos2->Text=s.sprintf("%.8f",pos[1]*R2D); - AntPos3->Text=s.sprintf("%.3f",pos[2]); - } - else { - AntPos1->Text="0.00000000"; - AntPos2->Text="0.00000000"; - AntPos3->Text="0.000"; - } - TraceLevelS->ItemIndex=TraceLevel; - NmeaReqT->Checked=NmeaReq; - LocalDir->Text=LocalDirectory; - ProxyAddr->Text=ProxyAddress; - StationId->Text=s.sprintf("%d",StaId); - StaInfoSel->Checked=StaSel; - AntInfo->Text=AntType; - RcvInfo->Text=RcvType; - AntOff1->Text=s.sprintf("%.4f",AntOff[0]); - AntOff2->Text=s.sprintf("%.4f",AntOff[1]); - AntOff3->Text=s.sprintf("%.4f",AntOff[2]); - LogFileF->Text=LogFile; - UpdateEnable(); +void __fastcall TSvrOptDialog::FormShow(TObject *Sender) { + double pos[3]; + AnsiString s; + DataTimeout->Text = s.sprintf("%d", SvrOpt[0]); + ConnectInterval->Text = s.sprintf("%d", SvrOpt[1]); + AvePeriodRate->Text = s.sprintf("%d", SvrOpt[2]); + SvrBuffSize->Text = s.sprintf("%d", SvrOpt[3]); + SvrCycle->Text = s.sprintf("%d", SvrOpt[4]); + ProgBarR->Text = s.sprintf("%d", ProgBarRange); + RelayMsg->ItemIndex = RelayBack; + NmeaCycle->Text = s.sprintf("%d", SvrOpt[5]); + FileSwapMarginE->Text = s.sprintf("%d", FileSwapMargin); + if (norm(AntPos, 3) > 0.0) { + ecef2pos(AntPos, pos); + AntPos1->Text = s.sprintf("%.8f", pos[0] * R2D); + AntPos2->Text = s.sprintf("%.8f", pos[1] * R2D); + AntPos3->Text = s.sprintf("%.3f", pos[2]); + } else { + AntPos1->Text = "0.00000000"; + AntPos2->Text = "0.00000000"; + AntPos3->Text = "0.000"; + } + TraceLevelS->ItemIndex = TraceLevel; + NmeaReqT->Checked = NmeaReq; + LocalDir->Text = LocalDirectory; + ProxyAddr->Text = ProxyAddress; + StationId->Text = s.sprintf("%d", StaId); + StaInfoSel->Checked = StaSel; + AntInfo->Text = AntType; + RcvInfo->Text = RcvType; + AntOff1->Text = s.sprintf("%.4f", AntOff[0]); + AntOff2->Text = s.sprintf("%.4f", AntOff[1]); + AntOff3->Text = s.sprintf("%.4f", AntOff[2]); + LogFileF->Text = LogFile; + UpdateEnable(); } //--------------------------------------------------------------------------- -void __fastcall TSvrOptDialog::BtnOkClick(TObject *Sender) -{ - double pos[3]; - SvrOpt[0]=DataTimeout->Text.ToInt(); - SvrOpt[1]=ConnectInterval->Text.ToInt(); - SvrOpt[2]=AvePeriodRate->Text.ToInt(); - SvrOpt[3]=SvrBuffSize->Text.ToInt(); - SvrOpt[4]=SvrCycle->Text.ToInt(); - SvrOpt[5]=NmeaCycle->Text.ToInt(); - ProgBarRange=ProgBarR->Text.ToInt(); - FileSwapMargin=FileSwapMarginE->Text.ToInt(); - RelayBack=RelayMsg->ItemIndex; - pos[0]=str2dbl(AntPos1->Text)*D2R; - pos[1]=str2dbl(AntPos2->Text)*D2R; - pos[2]=str2dbl(AntPos3->Text); - if (norm(pos,3)>0.0) { - pos2ecef(pos,AntPos); - } - else { - for (int i=0;i<3;i++) AntPos[i]=0.0; - } - TraceLevel=TraceLevelS->ItemIndex; - NmeaReq=NmeaReqT->Checked; - LocalDirectory=LocalDir->Text; - ProxyAddress=ProxyAddr->Text; - StaId=(int)str2dbl(StationId->Text); - StaSel=StaInfoSel->Checked; - AntType=AntInfo->Text; - RcvType=RcvInfo->Text; - AntOff[0]=str2dbl(AntOff1->Text); - AntOff[1]=str2dbl(AntOff2->Text); - AntOff[2]=str2dbl(AntOff3->Text); - LogFile=LogFileF->Text; +void __fastcall TSvrOptDialog::BtnOkClick(TObject *Sender) { + double pos[3]; + SvrOpt[0] = DataTimeout->Text.ToInt(); + SvrOpt[1] = ConnectInterval->Text.ToInt(); + SvrOpt[2] = AvePeriodRate->Text.ToInt(); + SvrOpt[3] = SvrBuffSize->Text.ToInt(); + SvrOpt[4] = SvrCycle->Text.ToInt(); + SvrOpt[5] = NmeaCycle->Text.ToInt(); + ProgBarRange = ProgBarR->Text.ToInt(); + FileSwapMargin = FileSwapMarginE->Text.ToInt(); + RelayBack = RelayMsg->ItemIndex; + pos[0] = str2dbl(AntPos1->Text) * D2R; + pos[1] = str2dbl(AntPos2->Text) * D2R; + pos[2] = str2dbl(AntPos3->Text); + if (norm(pos, 3) > 0.0) { + pos2ecef(pos, AntPos); + } else { + for (int i = 0; i < 3; i++) AntPos[i] = 0.0; + } + TraceLevel = TraceLevelS->ItemIndex; + NmeaReq = NmeaReqT->Checked; + LocalDirectory = LocalDir->Text; + ProxyAddress = ProxyAddr->Text; + StaId = (int)str2dbl(StationId->Text); + StaSel = StaInfoSel->Checked; + AntType = AntInfo->Text; + RcvType = RcvInfo->Text; + AntOff[0] = str2dbl(AntOff1->Text); + AntOff[1] = str2dbl(AntOff2->Text); + AntOff[2] = str2dbl(AntOff3->Text); + LogFile = LogFileF->Text; } //--------------------------------------------------------------------------- -void __fastcall TSvrOptDialog::BtnPosClick(TObject *Sender) -{ - AnsiString s; - RefDialog->RovPos[0]=str2dbl(AntPos1->Text); - RefDialog->RovPos[1]=str2dbl(AntPos2->Text); - RefDialog->RovPos[2]=str2dbl(AntPos3->Text); - RefDialog->BtnLoad->Enabled=true; - RefDialog->StaPosFile=StaPosFile; - RefDialog->Opt=1; - if (RefDialog->ShowModal()!=mrOk) return; - AntPos1->Text=s.sprintf("%.8f",RefDialog->Pos[0]); - AntPos2->Text=s.sprintf("%.8f",RefDialog->Pos[1]); - AntPos3->Text=s.sprintf("%.3f",RefDialog->Pos[2]); - StaPosFile=RefDialog->StaPosFile; +void __fastcall TSvrOptDialog::BtnPosClick(TObject *Sender) { + AnsiString s; + RefDialog->RovPos[0] = str2dbl(AntPos1->Text); + RefDialog->RovPos[1] = str2dbl(AntPos2->Text); + RefDialog->RovPos[2] = str2dbl(AntPos3->Text); + RefDialog->BtnLoad->Enabled = true; + RefDialog->StaPosFile = StaPosFile; + RefDialog->Opt = 1; + if (RefDialog->ShowModal() != mrOk) return; + AntPos1->Text = s.sprintf("%.8f", RefDialog->Pos[0]); + AntPos2->Text = s.sprintf("%.8f", RefDialog->Pos[1]); + AntPos3->Text = s.sprintf("%.3f", RefDialog->Pos[2]); + StaPosFile = RefDialog->StaPosFile; } //--------------------------------------------------------------------------- -void __fastcall TSvrOptDialog::BtnLocalDirClick(TObject *Sender) -{ +void __fastcall TSvrOptDialog::BtnLocalDirClick(TObject *Sender) { #ifdef TCPP - AnsiString dir=LocalDir->Text; - if (!SelectDirectory("Local Directory","",dir)) return; - LocalDir->Text=dir; + AnsiString dir = LocalDir->Text; + if (!SelectDirectory("Local Directory", "", dir)) return; + LocalDir->Text = dir; #else - UnicodeString dir=LocalDir->Text; - TSelectDirExtOpts opt=TSelectDirExtOpts()<Text=dir; + UnicodeString dir = LocalDir->Text; + TSelectDirExtOpts opt = TSelectDirExtOpts() << sdNewUI << sdNewFolder; + if (!SelectDirectory(L"Local Directory", L"", dir, opt)) return; + LocalDir->Text = dir; #endif } //--------------------------------------------------------------------------- -void __fastcall TSvrOptDialog::UpdateEnable(void) -{ - NmeaCycle->Enabled=NmeaReqT->Checked; - StationId->Enabled=StaInfoSel->Checked; - AntPos1->Enabled=StaInfoSel->Checked||NmeaReqT->Checked; - AntPos2->Enabled=StaInfoSel->Checked||NmeaReqT->Checked; - AntPos3->Enabled=StaInfoSel->Checked||NmeaReqT->Checked; - BtnPos ->Enabled=StaInfoSel->Checked||NmeaReqT->Checked; - AntOff1->Enabled=StaInfoSel->Checked; - AntOff2->Enabled=StaInfoSel->Checked; - AntOff3->Enabled=StaInfoSel->Checked; - AntInfo->Enabled=StaInfoSel->Checked; - RcvInfo->Enabled=StaInfoSel->Checked; +void __fastcall TSvrOptDialog::UpdateEnable(void) { + NmeaCycle->Enabled = NmeaReqT->Checked; + StationId->Enabled = StaInfoSel->Checked; + AntPos1->Enabled = StaInfoSel->Checked || NmeaReqT->Checked; + AntPos2->Enabled = StaInfoSel->Checked || NmeaReqT->Checked; + AntPos3->Enabled = StaInfoSel->Checked || NmeaReqT->Checked; + BtnPos->Enabled = StaInfoSel->Checked || NmeaReqT->Checked; + AntOff1->Enabled = StaInfoSel->Checked; + AntOff2->Enabled = StaInfoSel->Checked; + AntOff3->Enabled = StaInfoSel->Checked; + AntInfo->Enabled = StaInfoSel->Checked; + RcvInfo->Enabled = StaInfoSel->Checked; } //--------------------------------------------------------------------------- -void __fastcall TSvrOptDialog::NmeaReqTClick(TObject *Sender) -{ - UpdateEnable(); -} +void __fastcall TSvrOptDialog::NmeaReqTClick(TObject *Sender) { UpdateEnable(); } //--------------------------------------------------------------------------- -void __fastcall TSvrOptDialog::StaInfoSelClick(TObject *Sender) -{ - UpdateEnable(); -} +void __fastcall TSvrOptDialog::StaInfoSelClick(TObject *Sender) { UpdateEnable(); } //--------------------------------------------------------------------------- -void __fastcall TSvrOptDialog::BtnLogFileClick(TObject *Sender) -{ - OpenDialog->Title="Log File"; - OpenDialog->FileName=LogFileF->Text; - if (!OpenDialog->Execute()) return; - LogFileF->Text=OpenDialog->FileName; +void __fastcall TSvrOptDialog::BtnLogFileClick(TObject *Sender) { + OpenDialog->Title = "Log File"; + OpenDialog->FileName = LogFileF->Text; + if (!OpenDialog->Execute()) return; + LogFileF->Text = OpenDialog->FileName; } //--------------------------------------------------------------------------- - diff --git a/app/winapp/strsvr/svroptdlg.h b/app/winapp/strsvr/svroptdlg.h index be3f3e2d1..e41f50658 100644 --- a/app/winapp/strsvr/svroptdlg.h +++ b/app/winapp/strsvr/svroptdlg.h @@ -4,75 +4,75 @@ //--------------------------------------------------------------------------- #include #include -#include -#include #include +#include +#include //--------------------------------------------------------------------------- -class TSvrOptDialog : public TForm -{ -__published: - TButton *BtnOk; - TButton *BtnCancel; - TEdit *SvrBuffSize; - TLabel *Label1; - TLabel *Label2; - TEdit *SvrCycle; - TLabel *Label3; - TEdit *DataTimeout; - TLabel *Label6; - TEdit *ConnectInterval; - TEdit *AvePeriodRate; - TLabel *Label7; - TComboBox *TraceLevelS; - TEdit *AntPos2; - TEdit *AntPos1; - TEdit *NmeaCycle; - TLabel *Label8; - TEdit *AntPos3; - TButton *BtnPos; - TCheckBox *NmeaReqT; - TEdit *LocalDir; - TButton *BtnLocalDir; - TLabel *Label4; - TLabel *Label9; - TEdit *FileSwapMarginE; - TLabel *Label5; - TLabel *Label10; - TEdit *ProxyAddr; - TEdit *AntInfo; - TEdit *RcvInfo; - TLabel *Label11; - TEdit *AntOff1; - TEdit *AntOff2; - TEdit *AntOff3; - TLabel *Label12; - TLabel *Label13; - TEdit *StationId; - TCheckBox *StaInfoSel; - TLabel *Label15; - TEdit *LogFileF; - TButton *BtnLogFile; - TOpenDialog *OpenDialog; - TLabel *Label16; - TComboBox *RelayMsg; - TEdit *ProgBarR; - TLabel *Label17; - void __fastcall BtnOkClick(TObject *Sender); - void __fastcall FormShow(TObject *Sender); - void __fastcall BtnPosClick(TObject *Sender); - void __fastcall NmeaReqTClick(TObject *Sender); - void __fastcall BtnLocalDirClick(TObject *Sender); - void __fastcall StaInfoSelClick(TObject *Sender); - void __fastcall BtnLogFileClick(TObject *Sender); -private: - void __fastcall UpdateEnable(void); -public: - AnsiString StaPosFile,ExeDirectory,LocalDirectory,ProxyAddress; - AnsiString AntType,RcvType,LogFile; - int SvrOpt[6],TraceLevel,NmeaReq,FileSwapMargin,StaId,StaSel,RelayBack; - int ProgBarRange; - double AntPos[3],AntOff[3]; - __fastcall TSvrOptDialog(TComponent* Owner); +class TSvrOptDialog : public TForm { + __published : TButton *BtnOk; + TButton *BtnCancel; + TEdit *SvrBuffSize; + TLabel *Label1; + TLabel *Label2; + TEdit *SvrCycle; + TLabel *Label3; + TEdit *DataTimeout; + TLabel *Label6; + TEdit *ConnectInterval; + TEdit *AvePeriodRate; + TLabel *Label7; + TComboBox *TraceLevelS; + TEdit *AntPos2; + TEdit *AntPos1; + TEdit *NmeaCycle; + TLabel *Label8; + TEdit *AntPos3; + TButton *BtnPos; + TCheckBox *NmeaReqT; + TEdit *LocalDir; + TButton *BtnLocalDir; + TLabel *Label4; + TLabel *Label9; + TEdit *FileSwapMarginE; + TLabel *Label5; + TLabel *Label10; + TEdit *ProxyAddr; + TEdit *AntInfo; + TEdit *RcvInfo; + TLabel *Label11; + TEdit *AntOff1; + TEdit *AntOff2; + TEdit *AntOff3; + TLabel *Label12; + TLabel *Label13; + TEdit *StationId; + TCheckBox *StaInfoSel; + TLabel *Label15; + TEdit *LogFileF; + TButton *BtnLogFile; + TOpenDialog *OpenDialog; + TLabel *Label16; + TComboBox *RelayMsg; + TEdit *ProgBarR; + TLabel *Label17; + void __fastcall BtnOkClick(TObject *Sender); + void __fastcall FormShow(TObject *Sender); + void __fastcall BtnPosClick(TObject *Sender); + void __fastcall NmeaReqTClick(TObject *Sender); + void __fastcall BtnLocalDirClick(TObject *Sender); + void __fastcall StaInfoSelClick(TObject *Sender); + void __fastcall BtnLogFileClick(TObject *Sender); + + private: + void __fastcall UpdateEnable(void); + + public: + AnsiString StaPosFile, ExeDirectory, LocalDirectory, ProxyAddress; + AnsiString AntType, RcvType, LogFile; + int SvrOpt[6], TraceLevel, NmeaReq, FileSwapMargin, StaId, StaSel, RelayBack; + int ProgBarRange; + double AntPos[3], AntOff[3]; + __fastcall TSvrOptDialog(TComponent *Owner); }; //--------------------------------------------------------------------------- extern PACKAGE TSvrOptDialog *SvrOptDialog; diff --git a/src/convgpx.c b/src/convgpx.c index 2e8fd2164..e01ee5dde 100644 --- a/src/convgpx.c +++ b/src/convgpx.c @@ -1,15 +1,15 @@ /*------------------------------------------------------------------------------ -* convgpx.c : gpx converter -* -* Copyright (C) 2016 by T.TAKASU, All rights reserved. -* -* references : -* [1] GPX The GPS Exchange Format http://www.topografix.com/gpx.asp -* -* version : $Revision:$ $Date:$ -* history : 2016/06/11 1.0 new -* 2016/09/18 1.1 modify labels according GPX specs -*-----------------------------------------------------------------------------*/ + * convgpx.c : gpx converter + * + * Copyright (C) 2016 by T.TAKASU, All rights reserved. + * + * references : + * [1] GPX The GPS Exchange Format http://www.topografix.com/gpx.asp + * + * version : $Revision:$ $Date:$ + * history : 2016/06/11 1.0 new + * 2016/09/18 1.1 modify labels according GPX specs + *-----------------------------------------------------------------------------*/ #include "rtklib.h" /* constants -----------------------------------------------------------------*/ @@ -18,162 +18,159 @@ #define HEADGPX "\n" #define TAILGPX "" -static const char *XMLNS="http://www.topografix.com/GPX/1/1"; +static const char *XMLNS = "http://www.topografix.com/GPX/1/1"; /* output waypoint -----------------------------------------------------------*/ -static void outpoint(FILE *fp, gtime_t time, const double *pos, - const char *label, int stat, int outalt, int outtime) -{ - /* fix, float, sbas and ppp are rtklib extentions to GPX */ - const char *fix_label[]={"fix","float","sbas","dgps","3d","ppp"}; - double ep[6]; - - fprintf(fp,"\n",pos[0]*R2D,pos[1]*R2D); - if (outalt) { - fprintf(fp," %.4f\n",pos[2]-(outalt==2?geoidh(pos):0.0)); - } - if (outtime) { - if (outtime==2) time=gpst2utc(time); - else if (outtime==3) time=timeadd(gpst2utc(time),9*3600.0); - time2epoch(time,ep); - fprintf(fp," \n", - ep[0],ep[1],ep[2],ep[3],ep[4],ep[5]); - } - if (outalt==2) { - fprintf(fp," %.4f\n",geoidh(pos)); - } - if (stat>=1&&stat<=6) { - fprintf(fp," %s\n",fix_label[stat-1]); - } - if (label && *label) { - fprintf(fp," %s\n",label); - } - fprintf(fp,"\n"); +static void outpoint(FILE *fp, gtime_t time, const double *pos, const char *label, int stat, + int outalt, int outtime) { + /* fix, float, sbas and ppp are rtklib extentions to GPX */ + const char *fix_label[] = {"fix", "float", "sbas", "dgps", "3d", "ppp"}; + double ep[6]; + + fprintf(fp, "\n", pos[0] * R2D, pos[1] * R2D); + if (outalt) { + fprintf(fp, " %.4f\n", pos[2] - (outalt == 2 ? geoidh(pos) : 0.0)); + } + if (outtime) { + if (outtime == 2) + time = gpst2utc(time); + else if (outtime == 3) + time = timeadd(gpst2utc(time), 9 * 3600.0); + time2epoch(time, ep); + fprintf(fp, " \n", ep[0], ep[1], ep[2], + ep[3], ep[4], ep[5]); + } + if (outalt == 2) { + fprintf(fp, " %.4f\n", geoidh(pos)); + } + if (stat >= 1 && stat <= 6) { + fprintf(fp, " %s\n", fix_label[stat - 1]); + } + if (label && *label) { + fprintf(fp, " %s\n", label); + } + fprintf(fp, "\n"); } /* output track --------------------------------------------------------------*/ -static void outtrack(FILE *fp, const solbuf_t *solbuf, const char *name, - int outalt, int outtime) -{ - gtime_t time; - double pos[3],ep[6]; - int i; - - fprintf(fp,"\n"); - if (name && *name) fprintf(fp," %s\n",name); - fprintf(fp," \n"); - for (i=0;in;i++) { - ecef2pos(solbuf->data[i].rr,pos); - fprintf(fp," \n",pos[0]*R2D, - pos[1]*R2D); - if (outalt) - fprintf(fp," %.4f\n",pos[2]-(outalt==2?geoidh(pos):0.0)); - if (outtime) { - time=solbuf->data[i].time; - if (outtime==2) time=gpst2utc(time); - else if (outtime==3) time=timeadd(gpst2utc(time),9*3600.0); - time2epoch(time,ep); - fprintf(fp," \n", - ep[0],ep[1],ep[2],ep[3],ep[4],ep[5]); - } - if (outalt==2) { - fprintf(fp," %.4f\n",geoidh(pos)); - } - fprintf(fp," \n"); +static void outtrack(FILE *fp, const solbuf_t *solbuf, const char *name, int outalt, int outtime) { + gtime_t time; + double pos[3], ep[6]; + int i; + + fprintf(fp, "\n"); + if (name && *name) fprintf(fp, " %s\n", name); + fprintf(fp, " \n"); + for (i = 0; i < solbuf->n; i++) { + ecef2pos(solbuf->data[i].rr, pos); + fprintf(fp, " \n", pos[0] * R2D, pos[1] * R2D); + if (outalt) fprintf(fp, " %.4f\n", pos[2] - (outalt == 2 ? geoidh(pos) : 0.0)); + if (outtime) { + time = solbuf->data[i].time; + if (outtime == 2) + time = gpst2utc(time); + else if (outtime == 3) + time = timeadd(gpst2utc(time), 9 * 3600.0); + time2epoch(time, ep); + fprintf(fp, " \n", ep[0], ep[1], + ep[2], ep[3], ep[4], ep[5]); } - fprintf(fp," \n"); - fprintf(fp,"\n"); + if (outalt == 2) { + fprintf(fp, " %.4f\n", geoidh(pos)); + } + fprintf(fp, " \n"); + } + fprintf(fp, " \n"); + fprintf(fp, "\n"); } /* save gpx file -------------------------------------------------------------*/ -static int savegpx(const char *file, const solbuf_t *solbuf, const char *name, - int outtrk, int outpnt, int outalt, int outtime) -{ - FILE *fp; - double pos[3]; - int i; - - if (!(fp=fopen(file,"w"))) { - fprintf(stderr,"file open error : %s\n",file); - return 0; - } - fprintf(fp,HEADXML); - fprintf(fp,HEADGPX,"RTKLIB " VER_RTKLIB,XMLNS); - - /* output waypoint */ - if (outpnt) { - for (i=0;in;i++) { - ecef2pos(solbuf->data[i].rr,pos); - outpoint(fp,solbuf->data[i].time,pos, solbuf->n == 1 ? name : "", - solbuf->data[i].stat,outalt, outtime); - } - } - /* output waypoint of ref position */ - if (norm(solbuf->rb,3)>0.0) { - ecef2pos(solbuf->rb,pos); - outpoint(fp,solbuf->data[0].time,pos,"Reference Position",0,outalt,0); - } - /* output track */ - if (outtrk) { - outtrack(fp,solbuf,name,outalt,outtime); +static int savegpx(const char *file, const solbuf_t *solbuf, const char *name, int outtrk, + int outpnt, int outalt, int outtime) { + FILE *fp; + double pos[3]; + int i; + + if (!(fp = fopen(file, "w"))) { + fprintf(stderr, "file open error : %s\n", file); + return 0; + } + fprintf(fp, HEADXML); + fprintf(fp, HEADGPX, "RTKLIB " VER_RTKLIB, XMLNS); + + /* output waypoint */ + if (outpnt) { + for (i = 0; i < solbuf->n; i++) { + ecef2pos(solbuf->data[i].rr, pos); + outpoint(fp, solbuf->data[i].time, pos, solbuf->n == 1 ? name : "", solbuf->data[i].stat, + outalt, outtime); } - fprintf(fp,"%s\n",TAILGPX); - fclose(fp); - return 1; + } + /* output waypoint of ref position */ + if (norm(solbuf->rb, 3) > 0.0) { + ecef2pos(solbuf->rb, pos); + outpoint(fp, solbuf->data[0].time, pos, "Reference Position", 0, outalt, 0); + } + /* output track */ + if (outtrk) { + outtrack(fp, solbuf, name, outalt, outtime); + } + fprintf(fp, "%s\n", TAILGPX); + fclose(fp); + return 1; } /* convert to GPX file --------------------------------------------------------- -* convert solutions to GPX file [1] -* args : char *infile I input solutions file -* char *outfile I output google earth kml file ("":.kml) -* gtime_t ts,te I start/end time (gpst) -* int tint I time interval (s) (0.0:all) -* int qflg I quality flag (0:all) -* int mean I calculate the mean when true. -* char *name I point name. -* double *offset I add offset {east,north,up} (m) -* int outtrk I output track (0:off,1:on) -* int outpnt I output waypoint (0:off,1:on) -* int outalt I output altitude (0:off,1:elipsoidal,2:geodetic) -* int outtime I output time (0:off,1:gpst,2:utc,3:jst) -* return : status (0:ok,-1:file read,-2:file format,-3:no data,-4:file write) -*-----------------------------------------------------------------------------*/ -extern int convgpx(const char *infile, const char *outfile, gtime_t ts, - gtime_t te, double tint, int qflg, int mean, const char *name, - double *offset, int outtrk, int outpnt, int outalt, int outtime) -{ - solbuf_t solbuf={0}; - double rr[3]={0},pos[3],dr[3]; - int i,j; - char *p,file[1024]; - - trace(3,"convgpx : infile=%s outfile=%s\n",infile,outfile); - - if (!*outfile) { - if ((p=strrchr(infile,'.'))) { - strncpy(file,infile,p-infile); - strcpy(file+(p-infile),".gpx"); - } - else sprintf(file,"%s.gpx",infile); - } - else strcpy(file,outfile); - - /* read solution file */ - if (!readsolt(&infile,1,ts,te,tint,qflg,mean,&solbuf)) return -1; - - /* mean position */ - for (i=0;i<3;i++) { - for (j=0;j0.0) { - for (i=0;i<3;i++) solbuf.rb[i]+=dr[i]; - } - /* save gpx file */ - int r = savegpx(file,&solbuf,name,outtrk,outpnt,outalt,outtime)?0:-4; - freesolbuf(&solbuf); - return r; + * convert solutions to GPX file [1] + * args : char *infile I input solutions file + * char *outfile I output google earth kml file ("":.kml) + * gtime_t ts,te I start/end time (gpst) + * int tint I time interval (s) (0.0:all) + * int qflg I quality flag (0:all) + * int mean I calculate the mean when true. + * char *name I point name. + * double *offset I add offset {east,north,up} (m) + * int outtrk I output track (0:off,1:on) + * int outpnt I output waypoint (0:off,1:on) + * int outalt I output altitude (0:off,1:elipsoidal,2:geodetic) + * int outtime I output time (0:off,1:gpst,2:utc,3:jst) + * return : status (0:ok,-1:file read,-2:file format,-3:no data,-4:file write) + *-----------------------------------------------------------------------------*/ +extern int convgpx(const char *infile, const char *outfile, gtime_t ts, gtime_t te, double tint, + int qflg, int mean, const char *name, double *offset, int outtrk, int outpnt, + int outalt, int outtime) { + solbuf_t solbuf = {0}; + double rr[3] = {0}, pos[3], dr[3]; + int i, j; + char *p, file[1024]; + + trace(3, "convgpx : infile=%s outfile=%s\n", infile, outfile); + + if (!*outfile) { + if ((p = strrchr(infile, '.'))) { + strncpy(file, infile, p - infile); + strcpy(file + (p - infile), ".gpx"); + } else + sprintf(file, "%s.gpx", infile); + } else + strcpy(file, outfile); + + /* read solution file */ + if (!readsolt(&infile, 1, ts, te, tint, qflg, mean, &solbuf)) return -1; + + /* mean position */ + for (i = 0; i < 3; i++) { + for (j = 0; j < solbuf.n; j++) rr[i] += solbuf.data[j].rr[i]; + rr[i] /= solbuf.n; + } + /* add offset */ + ecef2pos(rr, pos); + enu2ecef(pos, offset, dr); + for (i = 0; i < solbuf.n; i++) { + for (j = 0; j < 3; j++) solbuf.data[i].rr[j] += dr[j]; + } + if (norm(solbuf.rb, 3) > 0.0) { + for (i = 0; i < 3; i++) solbuf.rb[i] += dr[i]; + } + /* save gpx file */ + int r = savegpx(file, &solbuf, name, outtrk, outpnt, outalt, outtime) ? 0 : -4; + freesolbuf(&solbuf); + return r; } diff --git a/src/convkml.c b/src/convkml.c index c9a770ee8..ec0ff2aee 100644 --- a/src/convkml.c +++ b/src/convkml.c @@ -1,230 +1,227 @@ /*------------------------------------------------------------------------------ -* convkml.c : google earth kml converter -* -* Copyright (C) 2007-2017 by T.TAKASU, All rights reserved. -* -* references : -* [1] Open Geospatial Consortium Inc., OGC 07-147r2, OGC(R) KML, 2008-04-14 -* -* version : $Revision: 1.1 $ $Date: 2008/07/17 21:48:06 $ -* history : 2007/01/20 1.0 new -* 2007/03/15 1.1 modify color sequence -* 2007/04/03 1.2 add geodetic height option -* support input of NMEA GGA sentence -* delete altitude info for track -* add time stamp option -* separate readsol.c file -* 2009/01/19 1.3 fix bug on display mark with by-q-flag option -* 2010/05/10 1.4 support api readsolt() change -* 2010/08/14 1.5 fix bug on readsolt() (2.4.0_p3) -* 2017/06/10 1.6 support wild-card in input file -*-----------------------------------------------------------------------------*/ + * convkml.c : google earth kml converter + * + * Copyright (C) 2007-2017 by T.TAKASU, All rights reserved. + * + * references : + * [1] Open Geospatial Consortium Inc., OGC 07-147r2, OGC(R) KML, 2008-04-14 + * + * version : $Revision: 1.1 $ $Date: 2008/07/17 21:48:06 $ + * history : 2007/01/20 1.0 new + * 2007/03/15 1.1 modify color sequence + * 2007/04/03 1.2 add geodetic height option + * support input of NMEA GGA sentence + * delete altitude info for track + * add time stamp option + * separate readsol.c file + * 2009/01/19 1.3 fix bug on display mark with by-q-flag option + * 2010/05/10 1.4 support api readsolt() change + * 2010/08/14 1.5 fix bug on readsolt() (2.4.0_p3) + * 2017/06/10 1.6 support wild-card in input file + *-----------------------------------------------------------------------------*/ #include "rtklib.h" /* constants -----------------------------------------------------------------*/ -#define SIZP 0.2 /* mark size of rover positions */ -#define SIZR 0.3 /* mark size of reference position */ -#define TINT 60.0 /* time label interval (sec) */ +#define SIZP 0.2 /* mark size of rover positions */ +#define SIZR 0.3 /* mark size of reference position */ +#define TINT 60.0 /* time label interval (sec) */ -static const char *head1=""; -static const char *head2=""; -static const char *mark="http://maps.google.com/mapfiles/kml/pal2/icon18.png"; +static const char *head1 = ""; +static const char *head2 = ""; +static const char *mark = "http://maps.google.com/mapfiles/kml/pal2/icon18.png"; /* output track --------------------------------------------------------------*/ -static void outtrack(FILE *f, const solbuf_t *solbuf, const char *name, - const char *color, int outalt, int outtime) -{ - (void)outtime; - double pos[3]; - int i; - - fprintf(f,"\n"); - if (name == NULL) name = "Rover Track"; - fprintf(f,"%s\n", name); - fprintf(f,"\n"); - fprintf(f,"\n"); - if (outalt) fprintf(f,"absolute\n"); - fprintf(f,"\n"); - for (i=0;in;i++) { - ecef2pos(solbuf->data[i].rr,pos); - if (outalt==0) pos[2]=0.0; - else if (outalt==2) pos[2]-=geoidh(pos); - fprintf(f,"%13.9f,%12.9f,%5.3f\n",pos[1]*R2D,pos[0]*R2D,pos[2]); - } - fprintf(f,"\n"); - fprintf(f,"\n"); - fprintf(f,"\n"); +static void outtrack(FILE *f, const solbuf_t *solbuf, const char *name, const char *color, + int outalt, int outtime) { + (void)outtime; + double pos[3]; + int i; + + fprintf(f, "\n"); + if (name == NULL) name = "Rover Track"; + fprintf(f, "%s\n", name); + fprintf(f, "\n"); + fprintf(f, "\n"); + if (outalt) fprintf(f, "absolute\n"); + fprintf(f, "\n"); + for (i = 0; i < solbuf->n; i++) { + ecef2pos(solbuf->data[i].rr, pos); + if (outalt == 0) + pos[2] = 0.0; + else if (outalt == 2) + pos[2] -= geoidh(pos); + fprintf(f, "%13.9f,%12.9f,%5.3f\n", pos[1] * R2D, pos[0] * R2D, pos[2]); + } + fprintf(f, "\n"); + fprintf(f, "\n"); + fprintf(f, "\n"); } /* output point --------------------------------------------------------------*/ -static void outpoint(FILE *fp, gtime_t time, const double *pos, - const char *label, const char *name, int style, int outalt, int outtime) -{ - double ep[6],alt=0.0; - char str[256]=""; - - fprintf(fp,"\n"); - if (label && *label) fprintf(fp,"%s\n",label); - fprintf(fp,"#P%d\n",style); - if (outtime) { - if (outtime==2) time=gpst2utc(time); - else if (outtime==3) time=timeadd(gpst2utc(time),9*3600.0); - time2epoch(time,ep); - if (!*label&&fmod(ep[5]+0.005,TINT)<0.01) { - sprintf(str,"%02.0f:%02.0f",ep[3],ep[4]); - if (name) - fprintf(fp,"%s %s\n", name, str); - else - fprintf(fp,"%s\n", str); - } - sprintf(str,"%04.0f-%02.0f-%02.0fT%02.0f:%02.0f:%05.2fZ", - ep[0],ep[1],ep[2],ep[3],ep[4],ep[5]); - fprintf(fp,"%s\n",str); - } - fprintf(fp,"\n"); - if (outalt) { - fprintf(fp,"1\n"); - fprintf(fp,"absolute\n"); - alt=pos[2]-(outalt==2?geoidh(pos):0.0); +static void outpoint(FILE *fp, gtime_t time, const double *pos, const char *label, const char *name, + int style, int outalt, int outtime) { + double ep[6], alt = 0.0; + char str[256] = ""; + + fprintf(fp, "\n"); + if (label && *label) fprintf(fp, "%s\n", label); + fprintf(fp, "#P%d\n", style); + if (outtime) { + if (outtime == 2) + time = gpst2utc(time); + else if (outtime == 3) + time = timeadd(gpst2utc(time), 9 * 3600.0); + time2epoch(time, ep); + if (!*label && fmod(ep[5] + 0.005, TINT) < 0.01) { + sprintf(str, "%02.0f:%02.0f", ep[3], ep[4]); + if (name) + fprintf(fp, "%s %s\n", name, str); + else + fprintf(fp, "%s\n", str); } - fprintf(fp,"%13.9f,%12.9f,%5.3f\n",pos[1]*R2D, - pos[0]*R2D,alt); - fprintf(fp,"\n"); - fprintf(fp,"\n"); + sprintf(str, "%04.0f-%02.0f-%02.0fT%02.0f:%02.0f:%05.2fZ", ep[0], ep[1], ep[2], ep[3], ep[4], + ep[5]); + fprintf(fp, "%s\n", str); + } + fprintf(fp, "\n"); + if (outalt) { + fprintf(fp, "1\n"); + fprintf(fp, "absolute\n"); + alt = pos[2] - (outalt == 2 ? geoidh(pos) : 0.0); + } + fprintf(fp, "%13.9f,%12.9f,%5.3f\n", pos[1] * R2D, pos[0] * R2D, alt); + fprintf(fp, "\n"); + fprintf(fp, "\n"); } /* save kml file -------------------------------------------------------------*/ -static int savekml(const char *file, const solbuf_t *solbuf, const char *name, - int tcolor, int pcolor, int outalt, int outtime) -{ - FILE *fp; - double pos[3]; - int i,qcolor[]={0,1,2,5,4,3,0}; - char *color[]={ - "ffffffff","ff008800","ff00aaff","ff0000ff","ff00ffff","ffff00ff" - }; - if (!(fp=fopen(file,"w"))) { - fprintf(stderr,"file open error : %s\n",file); - return 0; - } - fprintf(fp,"%s\n%s\n",head1,head2); - fprintf(fp,"\n"); - for (i=0;i<6;i++) { - fprintf(fp,"\n"); - } - if (tcolor>0) { - outtrack(fp,solbuf,name,color[tcolor-1],outalt,outtime); - } - if (pcolor>0) { - fprintf(fp,"\n"); - fprintf(fp," Rover Position\n"); - for (i=0;in;i++) { - ecef2pos(solbuf->data[i].rr,pos); - // If there is only one point then use the point name as the label. - outpoint(fp,solbuf->data[i].time,pos, solbuf->n == 1 ? name : "", name, - pcolor==5?qcolor[solbuf->data[i].stat]:pcolor-1,outalt,outtime); - } - fprintf(fp,"\n"); - } - if (norm(solbuf->rb,3)>0.0) { - ecef2pos(solbuf->rb,pos); - outpoint(fp,solbuf->data[0].time,pos,"Reference Position", NULL,0,outalt,0); +static int savekml(const char *file, const solbuf_t *solbuf, const char *name, int tcolor, + int pcolor, int outalt, int outtime) { + FILE *fp; + double pos[3]; + int i, qcolor[] = {0, 1, 2, 5, 4, 3, 0}; + char *color[] = {"ffffffff", "ff008800", "ff00aaff", "ff0000ff", "ff00ffff", "ffff00ff"}; + if (!(fp = fopen(file, "w"))) { + fprintf(stderr, "file open error : %s\n", file); + return 0; + } + fprintf(fp, "%s\n%s\n", head1, head2); + fprintf(fp, "\n"); + for (i = 0; i < 6; i++) { + fprintf(fp, "\n"); + } + if (tcolor > 0) { + outtrack(fp, solbuf, name, color[tcolor - 1], outalt, outtime); + } + if (pcolor > 0) { + fprintf(fp, "\n"); + fprintf(fp, " Rover Position\n"); + for (i = 0; i < solbuf->n; i++) { + ecef2pos(solbuf->data[i].rr, pos); + // If there is only one point then use the point name as the label. + outpoint(fp, solbuf->data[i].time, pos, solbuf->n == 1 ? name : "", name, + pcolor == 5 ? qcolor[solbuf->data[i].stat] : pcolor - 1, outalt, outtime); } - fprintf(fp,"\n"); - fprintf(fp,"\n"); - fclose(fp); - return 1; + fprintf(fp, "\n"); + } + if (norm(solbuf->rb, 3) > 0.0) { + ecef2pos(solbuf->rb, pos); + outpoint(fp, solbuf->data[0].time, pos, "Reference Position", NULL, 0, outalt, 0); + } + fprintf(fp, "\n"); + fprintf(fp, "\n"); + fclose(fp); + return 1; } /* convert to google earth kml file -------------------------------------------- -* convert solutions to google earth kml file -* args : char *infile I input solutions file (wild-card (*) is expanded) -* char *outfile I output google earth kml file ("":.kml) -* gtime_t ts,te I start/end time (gpst) -* int tint I time interval (s) (0.0:all) -* int qflg I quality flag (0:all) -* int mean I calculate the mean when true. -* char *name I point name. -* double *offset I add offset {east,north,up} (m) -* int tcolor I track color -* (0:none,1:white,2:green,3:orange,4:red,5:yellow) -* int pcolor I point color -* (0:none,1:white,2:green,3:orange,4:red,5:by qflag) -* int outalt I output altitude (0:off,1:elipsoidal,2:geodetic) -* int outtime I output time (0:off,1:gpst,2:utc,3:jst) -* return : status (0:ok,-1:file read,-2:file format,-3:no data,-4:file write) -* notes : see ref [1] for google earth kml file format -*-----------------------------------------------------------------------------*/ -extern int convkml(const char *infile, const char *outfile, gtime_t ts, - gtime_t te, double tint, int qflg, int mean, const char *name, - double *offset, int tcolor, int pcolor, int outalt, int outtime) -{ - solbuf_t solbuf={0}; - double rr[3]={0},pos[3],dr[3]; - int i,j,nfile,stat; - char *p,file[1024],*files[MAXEXFILE]={0}; - - trace(3,"convkml : infile=%s outfile=%s\n",infile,outfile); - - /* expand wild-card of infile */ - for (i=0;i=0;i--) free(files[i]); - return -4; - } - } - if ((nfile=expath(infile,files,MAXEXFILE))<=0) { - for (i=0;i0.0) { - for (i=0;i<3;i++) solbuf.rb[i]+=dr[i]; + * convert solutions to google earth kml file + * args : char *infile I input solutions file (wild-card (*) is expanded) + * char *outfile I output google earth kml file ("":.kml) + * gtime_t ts,te I start/end time (gpst) + * int tint I time interval (s) (0.0:all) + * int qflg I quality flag (0:all) + * int mean I calculate the mean when true. + * char *name I point name. + * double *offset I add offset {east,north,up} (m) + * int tcolor I track color + * (0:none,1:white,2:green,3:orange,4:red,5:yellow) + * int pcolor I point color + * (0:none,1:white,2:green,3:orange,4:red,5:by qflag) + * int outalt I output altitude (0:off,1:elipsoidal,2:geodetic) + * int outtime I output time (0:off,1:gpst,2:utc,3:jst) + * return : status (0:ok,-1:file read,-2:file format,-3:no data,-4:file write) + * notes : see ref [1] for google earth kml file format + *-----------------------------------------------------------------------------*/ +extern int convkml(const char *infile, const char *outfile, gtime_t ts, gtime_t te, double tint, + int qflg, int mean, const char *name, double *offset, int tcolor, int pcolor, + int outalt, int outtime) { + solbuf_t solbuf = {0}; + double rr[3] = {0}, pos[3], dr[3]; + int i, j, nfile, stat; + char *p, file[1024], *files[MAXEXFILE] = {0}; + + trace(3, "convkml : infile=%s outfile=%s\n", infile, outfile); + + /* expand wild-card of infile */ + for (i = 0; i < MAXEXFILE; i++) { + if (!(files[i] = (char *)malloc(1024))) { + for (i--; i >= 0; i--) free(files[i]); + return -4; } - /* save kml file */ - int r = savekml(file,&solbuf,name,tcolor,pcolor,outalt,outtime)?0:-4; - freesolbuf(&solbuf); - return r; + } + if ((nfile = expath(infile, files, MAXEXFILE)) <= 0) { + for (i = 0; i < MAXEXFILE; i++) free(files[i]); + return -3; + } + if (!*outfile) { + if ((p = strrchr(infile, '.'))) { + strncpy(file, infile, p - infile); + strcpy(file + (p - infile), ".kml"); + } else + sprintf(file, "%s.kml", infile); + } else + strcpy(file, outfile); + + /* read solution file */ + stat = readsolt((const char **)files, nfile, ts, te, tint, qflg, mean, &solbuf); + + for (i = 0; i < MAXEXFILE; i++) free(files[i]); + + if (!stat) { + return -1; + } + /* mean position */ + for (i = 0; i < 3; i++) { + for (j = 0; j < solbuf.n; j++) rr[i] += solbuf.data[j].rr[i]; + rr[i] /= solbuf.n; + } + /* add offset */ + ecef2pos(rr, pos); + enu2ecef(pos, offset, dr); + for (i = 0; i < solbuf.n; i++) { + for (j = 0; j < 3; j++) solbuf.data[i].rr[j] += dr[j]; + } + if (norm(solbuf.rb, 3) > 0.0) { + for (i = 0; i < 3; i++) solbuf.rb[i] += dr[i]; + } + /* save kml file */ + int r = savekml(file, &solbuf, name, tcolor, pcolor, outalt, outtime) ? 0 : -4; + freesolbuf(&solbuf); + return r; } // Save CSV file ---------------------------------------------------------------- -static int savecsv(const char *file, const solbuf_t *solbuf, const char *name, - int outalt, int outtime, int outorder) { +static int savecsv(const char *file, const solbuf_t *solbuf, const char *name, int outalt, + int outtime, int outorder) { FILE *fp = fopen(file, "w"); if (!fp) { fprintf(stderr, "file open error : %s\n", file); @@ -278,8 +275,8 @@ static int savecsv(const char *file, const solbuf_t *solbuf, const char *name, // Return : status (0:ok,-1:file read,-2:file format,-3:no data,-4:file write) //------------------------------------------------------------------------------ extern int convcsv(const char *infile, const char *outfile, gtime_t ts, gtime_t te, double tint, - int qflg, int mean, const char *name, double *offset, - int outalt, int outtime, int outorder) { + int qflg, int mean, const char *name, double *offset, int outalt, int outtime, + int outorder) { trace(3, "convcsv : infile=%s outfile=%s\n", infile, outfile); // Expand wild-card of infile. diff --git a/src/convrnx.c b/src/convrnx.c index 958821a7c..650dfeaac 100644 --- a/src/convrnx.c +++ b/src/convrnx.c @@ -1,100 +1,100 @@ /*------------------------------------------------------------------------------ -* convrnx.c : rinex translator for rtcm and receiver raw data log -* -* Copyright (C) 2009-2020 by T.TAKASU, All rights reserved. -* -* version : $Revision: 1.2 $ $Date: 2008/07/17 21:48:06 $ -* history : 2009/04/10 1.0 new -* 2009/06/02 1.1 support glonass -* 2009/12/18 1.2 add check return of init_rtcm()/init_raw() -* 2010/07/15 1.3 support wildcard expansion of input file -* support rinex 3.00 -* support rinex as input format -* support output of geo navigation message -* support rtcm antenna and receiver info -* changed api: -* convrnx() -* 2011/05/27 1.4 support GW10, Javad, LEX receiver -* support lex message conversion -* change api convrnx() -* 2012/10/18 1.5 support multiple codes in a frequency -* 2012/10/29 1.6 fix bug on scanning obs types -* support output of compass navigation data -* add supported obs types for rinex input -* 2013/03/11 1.7 support binex and rinex 3.02 -* add approx position in rinex obs header if blank -* 2014/05/24 1.8 support beidou B1 -* 2014/08/26 1.9 support input format rt17 -* 2015/05/24 1.10 fix bug on setting antenna delta in rtcm2opt() -* 2016/07/04 1.11 support IRNSS -* 2016/10/10 1.12 support event output by staid change in rtcm -* support separated navigation files for ver.3 -* 2017/06/06 1.13 fix bug on array overflow in set_obstype() and -* scan_obstype() -* 2018/10/10 1.14 add trace of half-cycle ambiguity status -* fix bug on missing navigation data -* 2020/11/30 1.15 force scanning receiver log for obs-types (2-pass) -* delete scanobs in RINEX options (rnxopt_t) -* add phase shift option (phshift) in rnxopt_t -* sort obs-types by freq-index and code priority -* add test obs-types supported by RINEX versions -* support receiver/antenna info in raw data -* fix bug on writing BDS/IRN nav header in closefile() -* fix bug on screening time in screent_ttol() -* fix bug on screening QZS L1S messages as SBAS -* use integer types in stdint.h -*-----------------------------------------------------------------------------*/ + * convrnx.c : rinex translator for rtcm and receiver raw data log + * + * Copyright (C) 2009-2020 by T.TAKASU, All rights reserved. + * + * version : $Revision: 1.2 $ $Date: 2008/07/17 21:48:06 $ + * history : 2009/04/10 1.0 new + * 2009/06/02 1.1 support glonass + * 2009/12/18 1.2 add check return of init_rtcm()/init_raw() + * 2010/07/15 1.3 support wildcard expansion of input file + * support rinex 3.00 + * support rinex as input format + * support output of geo navigation message + * support rtcm antenna and receiver info + * changed api: + * convrnx() + * 2011/05/27 1.4 support GW10, Javad, LEX receiver + * support lex message conversion + * change api convrnx() + * 2012/10/18 1.5 support multiple codes in a frequency + * 2012/10/29 1.6 fix bug on scanning obs types + * support output of compass navigation data + * add supported obs types for rinex input + * 2013/03/11 1.7 support binex and rinex 3.02 + * add approx position in rinex obs header if blank + * 2014/05/24 1.8 support beidou B1 + * 2014/08/26 1.9 support input format rt17 + * 2015/05/24 1.10 fix bug on setting antenna delta in rtcm2opt() + * 2016/07/04 1.11 support IRNSS + * 2016/10/10 1.12 support event output by staid change in rtcm + * support separated navigation files for ver.3 + * 2017/06/06 1.13 fix bug on array overflow in set_obstype() and + * scan_obstype() + * 2018/10/10 1.14 add trace of half-cycle ambiguity status + * fix bug on missing navigation data + * 2020/11/30 1.15 force scanning receiver log for obs-types (2-pass) + * delete scanobs in RINEX options (rnxopt_t) + * add phase shift option (phshift) in rnxopt_t + * sort obs-types by freq-index and code priority + * add test obs-types supported by RINEX versions + * support receiver/antenna info in raw data + * fix bug on writing BDS/IRN nav header in closefile() + * fix bug on screening time in screent_ttol() + * fix bug on screening QZS L1S messages as SBAS + * use integer types in stdint.h + *-----------------------------------------------------------------------------*/ #include "rtklib.h" -#define NOUTFILE 9 /* number of output files */ -#define TSTARTMARGIN 60.0 /* time margin for file name replacement */ +#define NOUTFILE 9 /* number of output files */ +#define TSTARTMARGIN 60.0 /* time margin for file name replacement */ -#define EVENT_STARTMOVE 2 /* rinex event start moving antenna */ -#define EVENT_NEWSITE 3 /* rinex event new site occupation */ -#define EVENT_HEADER 4 /* rinex event header info follows */ -#define EVENT_EXTERNAL 5 /* rinex event external event */ +#define EVENT_STARTMOVE 2 /* rinex event start moving antenna */ +#define EVENT_NEWSITE 3 /* rinex event new site occupation */ +#define EVENT_HEADER 4 /* rinex event header info follows */ +#define EVENT_EXTERNAL 5 /* rinex event external event */ /* type definitions ----------------------------------------------------------*/ -typedef struct stas_tag { /* station list type */ - int staid; /* station IS */ - gtime_t ts,te; /* first and last observation time */ - sta_t sta; /* station parameters */ - struct stas_tag *next; /* next list */ +typedef struct stas_tag { /* station list type */ + int staid; /* station IS */ + gtime_t ts, te; /* first and last observation time */ + sta_t sta; /* station parameters */ + struct stas_tag *next; /* next list */ } stas_t; -typedef struct halfc_tag { /* half-cycle ambiguity list type */ - gtime_t ts,te; /* first and last observation time */ - uint8_t stat; /* half-cycle ambiguity status */ - struct halfc_tag *next; /* next list */ +typedef struct halfc_tag { /* half-cycle ambiguity list type */ + gtime_t ts, te; /* first and last observation time */ + uint8_t stat; /* half-cycle ambiguity status */ + struct halfc_tag *next; /* next list */ } halfc_t; -typedef struct { /* stream file type */ - int format; /* stream format (STRFMT_???) */ - int staid; /* station ID */ - int ephsat,ephset; /* satellite and set of input ephemeris */ - gtime_t time; /* current time */ - gtime_t tstart; /* start time */ - obs_t *obs; /* pointer to input observation data */ - nav_t *nav; /* pointer to input navigation data */ - sta_t *sta; /* pointer to input station parameters */ - rtcm_t rtcm; /* input RTCM data */ - raw_t raw; /* input receiver raw data */ - rnxctr_t rnx; /* input RINEX control data */ - stas_t *stas; /* station list */ - uint8_t slips [MAXSAT][NFREQ+NEXOBS]; /* cycle slip flag cache */ - halfc_t *halfc[MAXSAT][NFREQ+NEXOBS]; /* half-cycle ambiguity list */ - FILE *fp; /* output file pointer */ +typedef struct { /* stream file type */ + int format; /* stream format (STRFMT_???) */ + int staid; /* station ID */ + int ephsat, ephset; /* satellite and set of input ephemeris */ + gtime_t time; /* current time */ + gtime_t tstart; /* start time */ + obs_t *obs; /* pointer to input observation data */ + nav_t *nav; /* pointer to input navigation data */ + sta_t *sta; /* pointer to input station parameters */ + rtcm_t rtcm; /* input RTCM data */ + raw_t raw; /* input receiver raw data */ + rnxctr_t rnx; /* input RINEX control data */ + stas_t *stas; /* station list */ + uint8_t slips[MAXSAT][NFREQ + NEXOBS]; /* cycle slip flag cache */ + halfc_t *halfc[MAXSAT][NFREQ + NEXOBS]; /* half-cycle ambiguity list */ + FILE *fp; /* output file pointer */ } strfile_t; /* global variables ----------------------------------------------------------*/ -static const int navsys[RNX_NUMSYS]={ /* system codes */ - SYS_GPS,SYS_GLO,SYS_GAL,SYS_QZS,SYS_SBS,SYS_CMP,SYS_IRN -}; +static const int navsys[RNX_NUMSYS] = {/* system codes */ + SYS_GPS, SYS_GLO, SYS_GAL, SYS_QZS, + SYS_SBS, SYS_CMP, SYS_IRN}; // Supported obs-type by RINEX version. static const char ver3code[][MAXCODE] = { - // clang-format off + // clang-format off // 0........1.........2.........3.........4.........5.........6.........7 // 1111111111111222222222255577766666668882266333115559999155567778844466 CODE // CPWYMNSLEABXZCDSLXPWYMNIQXIQXABCXZSLIQXIQIQIQXIQABCABCXDDPZEDPZDPABXDP @@ -105,10 +105,10 @@ static const char ver3code[][MAXCODE] = { "0......................000............................................", // SBS ".4...455.4.45....1.......41114..15....41111............444..44444...55", // BDS ".........................3......................3333333..............." // IRN - // clang-format on + // clang-format on }; static const char ver4code[][MAXCODE] = { - // clang-format off + // clang-format off // 0........1.........2.........3.........4.........5.........6.........7 // 1111111111111222222222255577766666668882266333115559999155567778844466 CODE // CPWYMNSLEABXZCDSLXPWYMNIQXIQXABCXZSLIQXIQIQIQXIQABCABCXDDPZEDPZDPABXDP @@ -119,1404 +119,1346 @@ static const char ver4code[][MAXCODE] = { "0......................000............................................", // SBS ".0....00...00....0.......0000...00....00000............000..00000...00", // BDS ".1.........1.............0......................00000001.............." // IRN - // clang-format on + // clang-format on }; /* convert RINEX obs-type ver.3 -> ver.2 -------------------------------------*/ -static void convcode(int rnxver, int sys, char *type) -{ - if (rnxver>=212&&(sys==SYS_GPS||sys==SYS_QZS||sys==SYS_SBS)&& - !strcmp(type+1,"1C")) { /* L1C/A */ - strcpy(type+1,"A"); - } - else if (rnxver>=212&&(sys==SYS_GPS||sys==SYS_QZS)&& - (!strcmp(type+1,"1S")||!strcmp(type+1,"1L")|| - !strcmp(type+1,"1X"))) { /* L1C */ - strcpy(type+1,"B"); - } - else if (rnxver>=212&&(sys==SYS_GPS||sys==SYS_QZS)&& - (!strcmp(type+1,"2S")||!strcmp(type+1,"2L")|| - !strcmp(type+1,"2X"))) { /* L2C */ - strcpy(type+1,"C"); - } - else if (rnxver>=212&&sys==SYS_GLO&&!strcmp(type+1,"1C")) { /* L1C/A */ - strcpy(type+1,"A"); - } - else if (rnxver>=212&&sys==SYS_GLO&&!strcmp(type+1,"2C")) { /* L2C/A */ - strcpy(type+1,"D"); - } - else if (sys==SYS_CMP&&(!strcmp(type+1,"2I")||!strcmp(type+1,"2Q")|| - !strcmp(type+1,"2X"))) { /* B1_2 */ - strcpy(type+1,"2"); - } - else if (!strcmp(type,"C1P")||!strcmp(type,"C1W")||!strcmp(type,"C1Y")|| - !strcmp(type,"C1N")) { /* L1P,P(Y) */ - strcpy(type,"P1"); - } - else if (!strcmp(type,"C2P")||!strcmp(type,"C2W")||!strcmp(type,"C2Y")|| - !strcmp(type,"C2N")||!strcmp(type,"C2D")) { /* L2P,P(Y) */ - strcpy(type,"P2"); - } - else { - type[2]='\0'; - } +static void convcode(int rnxver, int sys, char *type) { + if (rnxver >= 212 && (sys == SYS_GPS || sys == SYS_QZS || sys == SYS_SBS) && + !strcmp(type + 1, "1C")) { /* L1C/A */ + strcpy(type + 1, "A"); + } else if (rnxver >= 212 && (sys == SYS_GPS || sys == SYS_QZS) && + (!strcmp(type + 1, "1S") || !strcmp(type + 1, "1L") || + !strcmp(type + 1, "1X"))) { /* L1C */ + strcpy(type + 1, "B"); + } else if (rnxver >= 212 && (sys == SYS_GPS || sys == SYS_QZS) && + (!strcmp(type + 1, "2S") || !strcmp(type + 1, "2L") || + !strcmp(type + 1, "2X"))) { /* L2C */ + strcpy(type + 1, "C"); + } else if (rnxver >= 212 && sys == SYS_GLO && !strcmp(type + 1, "1C")) { /* L1C/A */ + strcpy(type + 1, "A"); + } else if (rnxver >= 212 && sys == SYS_GLO && !strcmp(type + 1, "2C")) { /* L2C/A */ + strcpy(type + 1, "D"); + } else if (sys == SYS_CMP && (!strcmp(type + 1, "2I") || !strcmp(type + 1, "2Q") || + !strcmp(type + 1, "2X"))) { /* B1_2 */ + strcpy(type + 1, "2"); + } else if (!strcmp(type, "C1P") || !strcmp(type, "C1W") || !strcmp(type, "C1Y") || + !strcmp(type, "C1N")) { /* L1P,P(Y) */ + strcpy(type, "P1"); + } else if (!strcmp(type, "C2P") || !strcmp(type, "C2W") || !strcmp(type, "C2Y") || + !strcmp(type, "C2N") || !strcmp(type, "C2D")) { /* L2P,P(Y) */ + strcpy(type, "P2"); + } else { + type[2] = '\0'; + } } /* generate stream file ------------------------------------------------------*/ -static strfile_t *gen_strfile(int format, const char *opt) -{ - strfile_t *str; - gtime_t time0={0}; - int i,j; - - trace(3,"init_strfile:\n"); - - if (!(str=(strfile_t *)calloc(1, sizeof(strfile_t)))) return NULL; - - str->format=format; - str->staid=-1; - str->ephsat=str->ephset=0; - str->time=str->tstart=time0; - - if (format==STRFMT_RTCM2||format==STRFMT_RTCM3) { - if (!init_rtcm(&str->rtcm)) { - free(str); - showmsg("init rtcm error"); - return NULL; - } - str->rtcm.time=time0; - str->obs=&str->rtcm.obs; - str->nav=&str->rtcm.nav; - str->sta=&str->rtcm.sta; - strcpy(str->rtcm.opt,opt); - } - else if (format<=MAXRCVFMT) { - if (!init_raw(&str->raw,format)) { - free(str); - showmsg("init raw error"); - return NULL; - } - str->raw.time=time0; - str->obs=&str->raw.obs; - str->nav=&str->raw.nav; - str->sta=&str->raw.sta; - strcpy(str->raw.opt,opt); - } - else if (format==STRFMT_RINEX) { - if (!init_rnxctr(&str->rnx)) { - free(str); - showmsg("init rnx error"); - return NULL; - } - str->rnx.time=time0; - str->obs=&str->rnx.obs; - str->nav=&str->rnx.nav; - str->sta=&str->rnx.sta; - strcpy(str->rnx.opt,opt); - } - else { - free(str); - return NULL; - } +static strfile_t *gen_strfile(int format, const char *opt) { + strfile_t *str; + gtime_t time0 = {0}; + int i, j; - str->stas=NULL; - for (i=0;islips[i][j]=0; - str->halfc[i][j]=NULL; - } - str->fp=NULL; - return str; + trace(3, "init_strfile:\n"); + + if (!(str = (strfile_t *)calloc(1, sizeof(strfile_t)))) return NULL; + + str->format = format; + str->staid = -1; + str->ephsat = str->ephset = 0; + str->time = str->tstart = time0; + + if (format == STRFMT_RTCM2 || format == STRFMT_RTCM3) { + if (!init_rtcm(&str->rtcm)) { + free(str); + showmsg("init rtcm error"); + return NULL; + } + str->rtcm.time = time0; + str->obs = &str->rtcm.obs; + str->nav = &str->rtcm.nav; + str->sta = &str->rtcm.sta; + strcpy(str->rtcm.opt, opt); + } else if (format <= MAXRCVFMT) { + if (!init_raw(&str->raw, format)) { + free(str); + showmsg("init raw error"); + return NULL; + } + str->raw.time = time0; + str->obs = &str->raw.obs; + str->nav = &str->raw.nav; + str->sta = &str->raw.sta; + strcpy(str->raw.opt, opt); + } else if (format == STRFMT_RINEX) { + if (!init_rnxctr(&str->rnx)) { + free(str); + showmsg("init rnx error"); + return NULL; + } + str->rnx.time = time0; + str->obs = &str->rnx.obs; + str->nav = &str->rnx.nav; + str->sta = &str->rnx.sta; + strcpy(str->rnx.opt, opt); + } else { + free(str); + return NULL; + } + + str->stas = NULL; + for (i = 0; i < MAXSAT; i++) + for (j = 0; j < NFREQ + NEXOBS; j++) { + str->slips[i][j] = 0; + str->halfc[i][j] = NULL; + } + str->fp = NULL; + return str; } /* free stream file ----------------------------------------------------------*/ -static void free_strfile(strfile_t *str) -{ - stas_t *sp,*sp_next; - halfc_t *hp,*hp_next; - int i,j; - - trace(3,"free_strfile:\n"); - - if (str->format==STRFMT_RTCM2||str->format==STRFMT_RTCM3) { - free_rtcm(&str->rtcm); - } - else if (str->format<=MAXRCVFMT) { - free_raw(&str->raw); - } - else if (str->format==STRFMT_RINEX) { - free_rnxctr(&str->rnx); - } - for (sp=str->stas;sp;sp=sp_next) { - sp_next=sp->next; - free(sp); - } - for (i=0;ihalfc[i][j];hp;hp=hp_next) { - hp_next=hp->next; - free(hp); - } - } - free(str); +static void free_strfile(strfile_t *str) { + stas_t *sp, *sp_next; + halfc_t *hp, *hp_next; + int i, j; + + trace(3, "free_strfile:\n"); + + if (str->format == STRFMT_RTCM2 || str->format == STRFMT_RTCM3) { + free_rtcm(&str->rtcm); + } else if (str->format <= MAXRCVFMT) { + free_raw(&str->raw); + } else if (str->format == STRFMT_RINEX) { + free_rnxctr(&str->rnx); + } + for (sp = str->stas; sp; sp = sp_next) { + sp_next = sp->next; + free(sp); + } + for (i = 0; i < MAXSAT; i++) + for (j = 0; j < NFREQ + NEXOBS; j++) { + for (hp = str->halfc[i][j]; hp; hp = hp_next) { + hp_next = hp->next; + free(hp); + } + } + free(str); } /* input stream file ---------------------------------------------------------*/ -static int input_strfile(strfile_t *str) -{ - int type=0; - - trace(4,"input_strfile:\n"); - - if (str->format==STRFMT_RTCM2) { - if ((type=input_rtcm2f(&str->rtcm,str->fp))>=1) { - str->time=str->rtcm.time; - str->ephsat=str->rtcm.ephsat; - str->ephset=str->rtcm.ephset; - str->staid=str->rtcm.staid; - } - } - else if (str->format==STRFMT_RTCM3) { - if ((type=input_rtcm3f(&str->rtcm,str->fp))>=1) { - str->time=str->rtcm.time; - str->ephsat=str->rtcm.ephsat; - str->ephset=str->rtcm.ephset; - str->staid=str->rtcm.staid; - } - } - else if (str->format<=MAXRCVFMT) { - if ((type=input_rawf(&str->raw,str->format,str->fp))>=1) { - str->time=str->raw.time; - str->ephsat=str->raw.ephsat; - str->ephset=str->raw.ephset; - str->staid=0; - } - } - else if (str->format==STRFMT_RINEX) { - if ((type=input_rnxctr(&str->rnx,str->fp))>=1) { - str->time=str->rnx.time; - str->ephsat=str->rnx.ephsat; - str->ephset=str->rnx.ephset; - str->staid=0; - } - } - if (!str->tstart.time&&str->time.time) { - str->tstart=str->time; - } - char tstr[40]; - trace(4,"input_strfile: time=%s type=%d\n",time2str(str->time,tstr,3),type); - return type; +static int input_strfile(strfile_t *str) { + int type = 0; + + trace(4, "input_strfile:\n"); + + if (str->format == STRFMT_RTCM2) { + if ((type = input_rtcm2f(&str->rtcm, str->fp)) >= 1) { + str->time = str->rtcm.time; + str->ephsat = str->rtcm.ephsat; + str->ephset = str->rtcm.ephset; + str->staid = str->rtcm.staid; + } + } else if (str->format == STRFMT_RTCM3) { + if ((type = input_rtcm3f(&str->rtcm, str->fp)) >= 1) { + str->time = str->rtcm.time; + str->ephsat = str->rtcm.ephsat; + str->ephset = str->rtcm.ephset; + str->staid = str->rtcm.staid; + } + } else if (str->format <= MAXRCVFMT) { + if ((type = input_rawf(&str->raw, str->format, str->fp)) >= 1) { + str->time = str->raw.time; + str->ephsat = str->raw.ephsat; + str->ephset = str->raw.ephset; + str->staid = 0; + } + } else if (str->format == STRFMT_RINEX) { + if ((type = input_rnxctr(&str->rnx, str->fp)) >= 1) { + str->time = str->rnx.time; + str->ephsat = str->rnx.ephsat; + str->ephset = str->rnx.ephset; + str->staid = 0; + } + } + if (!str->tstart.time && str->time.time) { + str->tstart = str->time; + } + char tstr[40]; + trace(4, "input_strfile: time=%s type=%d\n", time2str(str->time, tstr, 3), type); + return type; } /* open stream file ----------------------------------------------------------*/ -static int open_strfile(strfile_t *str, const char *file) -{ - trace(3,"open_strfile: file=%s\n",file); - - if (str->format==STRFMT_RTCM2||str->format==STRFMT_RTCM3) { - if (!(str->fp=fopen(file,"rb"))) { - showmsg("rtcm open error: %s",file); - return 0; - } - str->rtcm.time=str->time; - } - else if (str->format<=MAXRCVFMT) { - if (!(str->fp=fopen(file,"rb"))) { - showmsg("log open error: %s",file); - return 0; - } - str->raw.time=str->time; - } - else if (str->format==STRFMT_RINEX) { - if (!(str->fp=fopen(file,"r"))) { - showmsg("rinex open error: %s",file); - return 0; - } - /* open rinex control */ - if (!open_rnxctr(&str->rnx,str->fp)) { - showmsg("no rinex file: %s",file); - fclose(str->fp); - return 0; - } - str->rnx.time=str->time; - } - return 1; +static int open_strfile(strfile_t *str, const char *file) { + trace(3, "open_strfile: file=%s\n", file); + + if (str->format == STRFMT_RTCM2 || str->format == STRFMT_RTCM3) { + if (!(str->fp = fopen(file, "rb"))) { + showmsg("rtcm open error: %s", file); + return 0; + } + str->rtcm.time = str->time; + } else if (str->format <= MAXRCVFMT) { + if (!(str->fp = fopen(file, "rb"))) { + showmsg("log open error: %s", file); + return 0; + } + str->raw.time = str->time; + } else if (str->format == STRFMT_RINEX) { + if (!(str->fp = fopen(file, "r"))) { + showmsg("rinex open error: %s", file); + return 0; + } + /* open rinex control */ + if (!open_rnxctr(&str->rnx, str->fp)) { + showmsg("no rinex file: %s", file); + fclose(str->fp); + return 0; + } + str->rnx.time = str->time; + } + return 1; } /* close stream file ---------------------------------------------------------*/ -static void close_strfile(strfile_t *str) -{ - trace(3,"close_strfile:\n"); - - if (str->format==STRFMT_RTCM2||str->format==STRFMT_RTCM3) { - if (str->fp) fclose(str->fp); - } - else if (str->format<=MAXRCVFMT) { - if (str->fp) fclose(str->fp); - } - else if (str->format==STRFMT_RINEX) { - if (str->fp) fclose(str->fp); - } +static void close_strfile(strfile_t *str) { + trace(3, "close_strfile:\n"); + + if (str->format == STRFMT_RTCM2 || str->format == STRFMT_RTCM3) { + if (str->fp) fclose(str->fp); + } else if (str->format <= MAXRCVFMT) { + if (str->fp) fclose(str->fp); + } else if (str->format == STRFMT_RINEX) { + if (str->fp) fclose(str->fp); + } } /* set format and files in RINEX options comments ----------------------------*/ -static void setopt_file(int format, char **paths, int n, const int *mask, - rnxopt_t *opt) -{ - rnxcomment(opt,"format: %s",formatstrs[format]); - if (*opt->rcvopt) - rnxcomment(opt, "options: %s", opt->rcvopt); - for (int j=0; jrcvopt) rnxcomment(opt, "options: %s", opt->rcvopt); + for (int j = 0; j < n; j++) { + if (!mask[j]) continue; + rnxcomment(opt, "log: %s", paths[j]); + } } /* unset RINEX options comments ----------------------------------------------*/ -static void unsetopt_file(rnxopt_t *opt) -{ - int brk=0; - - for (int i=MAXCOMMENT-1;i>=0&&!brk;i--) { - if (!*opt->comment[i]) continue; - if (!strncmp(opt->comment[i],"format: ",8)) brk=1; - *opt->comment[i]='\0'; - } +static void unsetopt_file(rnxopt_t *opt) { + int brk = 0; + + for (int i = MAXCOMMENT - 1; i >= 0 && !brk; i--) { + if (!*opt->comment[i]) continue; + if (!strncmp(opt->comment[i], "format: ", 8)) brk = 1; + *opt->comment[i] = '\0'; + } } /* sort obs-types ------------------------------------------------------------*/ -static void sort_obstype(uint8_t *codes, uint8_t *types, int n, int sys) -{ - uint8_t tmp; - int i,j,idx1,idx2,pri1,pri2; - - for (i=0;i=pri2)) continue; - tmp=codes[i]; codes[i]=codes[j]; codes[j]=tmp; - tmp=types[i]; types[i]=types[j]; types[j]=tmp; +static void sort_obstype(uint8_t *codes, uint8_t *types, int n, int sys) { + uint8_t tmp; + int i, j, idx1, idx2, pri1, pri2; + + for (i = 0; i < n - 1; i++) + for (j = i + 1; j < n; j++) { + idx1 = code2idx(navsys[sys], codes[i]); + idx2 = code2idx(navsys[sys], codes[j]); + pri1 = getcodepri(navsys[sys], codes[i], ""); + pri2 = getcodepri(navsys[sys], codes[j], ""); + if (idx1 < idx2 || (idx1 == idx2 && pri1 >= pri2)) continue; + tmp = codes[i]; + codes[i] = codes[j]; + codes[j] = tmp; + tmp = types[i]; + types[i] = types[j]; + types[j] = tmp; } } /* set obs-types in RINEX options --------------------------------------------*/ -static void setopt_obstype(const uint8_t *codes, const uint8_t *types, int sys, - rnxopt_t *opt) -{ - const char type_str[]="CLDS"; - char type[16],*id,ver; - int i,j,k,idx; - - trace(3,"setopt_obstype: sys=%d\n",sys); - - opt->nobs[sys]=0; - - if (!(navsys[sys]&opt->navsys)) return; - - for (i=0;codes[i];i++) { - if (!(id=code2obs(codes[i]))||(idx=code2idx(navsys[sys],codes[i]))<0) { - continue; - } - if (!(opt->freqtype&(1<mask[sys][codes[i]-1]=='0') { - continue; - } - if (opt->rnxver>=400) { - ver=ver4code[sys][codes[i]-1]; - if (ver<'0'||ver>'0'+opt->rnxver-400) { - trace(2,"unsupported obs type: rnxver=%.2f sys=%d code=%s\n", - opt->rnxver/100.0,sys,code2obs(codes[i])); - continue; - } - } else if (opt->rnxver>=300) { - ver=ver3code[sys][codes[i]-1]; - if (ver<'0'||ver>'0'+opt->rnxver-300) { - trace(2,"unsupported obs type: rnxver=%.2f sys=%d code=%s\n", - opt->rnxver/100.0,sys,code2obs(codes[i])); - continue; - } +static void setopt_obstype(const uint8_t *codes, const uint8_t *types, int sys, rnxopt_t *opt) { + const char type_str[] = "CLDS"; + char type[16], *id, ver; + int i, j, k, idx; + + trace(3, "setopt_obstype: sys=%d\n", sys); + + opt->nobs[sys] = 0; + + if (!(navsys[sys] & opt->navsys)) return; + + for (i = 0; codes[i]; i++) { + if (!(id = code2obs(codes[i])) || (idx = code2idx(navsys[sys], codes[i])) < 0) { + continue; + } + if (!(opt->freqtype & (1 << idx)) || opt->mask[sys][codes[i] - 1] == '0') { + continue; + } + if (opt->rnxver >= 400) { + ver = ver4code[sys][codes[i] - 1]; + if (ver < '0' || ver > '0' + opt->rnxver - 400) { + trace(2, "unsupported obs type: rnxver=%.2f sys=%d code=%s\n", opt->rnxver / 100.0, sys, + code2obs(codes[i])); + continue; + } + } else if (opt->rnxver >= 300) { + ver = ver3code[sys][codes[i] - 1]; + if (ver < '0' || ver > '0' + opt->rnxver - 300) { + trace(2, "unsupported obs type: rnxver=%.2f sys=%d code=%s\n", opt->rnxver / 100.0, sys, + code2obs(codes[i])); + continue; + } + } + for (j = 0; j < 4; j++) { + if (!(opt->obstype & (1 << j))) continue; + if (types && !(types[i] & (1 << j))) continue; + + /* obs-types in ver.3 */ + sprintf(type, "%c%s", type_str[j], id); + if (type[0] == 'C' && type[2] == 'N') continue; /* codeless */ + + if (opt->rnxver <= 299) { /* ver.2 */ + + /* ver.3 -> ver.2 */ + convcode(opt->rnxver, navsys[sys], type); + + /* check duplicated obs-type */ + for (k = 0; k < opt->nobs[0]; k++) { + if (!strcmp(opt->tobs[0][k], type)) break; } - for (j=0;j<4;j++) { - if (!(opt->obstype&(1<rnxver<=299) { /* ver.2 */ - - /* ver.3 -> ver.2 */ - convcode(opt->rnxver,navsys[sys],type); - - /* check duplicated obs-type */ - for (k=0;knobs[0];k++) { - if (!strcmp(opt->tobs[0][k],type)) break; - } - if (k>=opt->nobs[0]&&opt->nobs[0]tobs[0][opt->nobs[0]++],type); - } - } - else if (opt->nobs[sys]tobs[sys][opt->nobs[sys]++],type); - } + if (k >= opt->nobs[0] && opt->nobs[0] < MAXOBSTYPE) { + strcpy(opt->tobs[0][opt->nobs[0]++], type); } + } else if (opt->nobs[sys] < MAXOBSTYPE) { /* ver.3 */ + strcpy(opt->tobs[sys][opt->nobs[sys]++], type); + } } + } } /* set phase shift in RINEX options (RINEX 3.04 A23) -------------------------*/ -static void setopt_phshift(rnxopt_t *opt) -{ - uint8_t code; - int i,j; - - for (i=0;inobs[i];j++) { - if (opt->tobs[i][j][0]!='L') continue; - code=obs2code(opt->tobs[i][j]+1); - - if (navsys[i]==SYS_GPS) { - if (code==CODE_L1S||code==CODE_L1L||code==CODE_L1X||code==CODE_L1P|| - code==CODE_L1W||code==CODE_L1N) { - opt->shift[i][j]=0.25; /* +1/4 cyc */ - } - else if (code==CODE_L2C||code==CODE_L2S||code==CODE_L2L|| - code==CODE_L2X||code==CODE_L5Q) { - opt->shift[i][j]=-0.25; /* -1/4 cyc */ - } +static void setopt_phshift(rnxopt_t *opt) { + uint8_t code; + int i, j; + + for (i = 0; i < RNX_NUMSYS; i++) + for (j = 0; j < opt->nobs[i]; j++) { + if (opt->tobs[i][j][0] != 'L') continue; + code = obs2code(opt->tobs[i][j] + 1); + + if (navsys[i] == SYS_GPS) { + if (code == CODE_L1S || code == CODE_L1L || code == CODE_L1X || code == CODE_L1P || + code == CODE_L1W || code == CODE_L1N) { + opt->shift[i][j] = 0.25; /* +1/4 cyc */ + } else if (code == CODE_L2C || code == CODE_L2S || code == CODE_L2L || code == CODE_L2X || + code == CODE_L5Q) { + opt->shift[i][j] = -0.25; /* -1/4 cyc */ } - else if (navsys[i]==SYS_GLO) { - if (code==CODE_L1P||code==CODE_L2P||code==CODE_L3Q) { - opt->shift[i][j]=0.25; /* +1/4 cyc */ - } + } else if (navsys[i] == SYS_GLO) { + if (code == CODE_L1P || code == CODE_L2P || code == CODE_L3Q) { + opt->shift[i][j] = 0.25; /* +1/4 cyc */ } - else if (navsys[i]==SYS_GAL) { - if (code==CODE_L1C) { - opt->shift[i][j]=0.5; /* +1/2 cyc */ - } - else if (code==CODE_L5Q||code==CODE_L7Q||code==CODE_L8Q) { - opt->shift[i][j]=-0.25; /* -1/4 cyc */ - } - else if (code==CODE_L6C) { - opt->shift[i][j]=-0.5; /* -1/2 cyc */ - } + } else if (navsys[i] == SYS_GAL) { + if (code == CODE_L1C) { + opt->shift[i][j] = 0.5; /* +1/2 cyc */ + } else if (code == CODE_L5Q || code == CODE_L7Q || code == CODE_L8Q) { + opt->shift[i][j] = -0.25; /* -1/4 cyc */ + } else if (code == CODE_L6C) { + opt->shift[i][j] = -0.5; /* -1/2 cyc */ } - else if (navsys[i]==SYS_QZS) { - if (code==CODE_L1S||code==CODE_L1L||code==CODE_L1X) { - opt->shift[i][j]=0.25; /* +1/4 cyc */ - } - else if (code==CODE_L5Q||code==CODE_L5P) { - opt->shift[i][j]=-0.25; /* -1/4 cyc */ - } + } else if (navsys[i] == SYS_QZS) { + if (code == CODE_L1S || code == CODE_L1L || code == CODE_L1X) { + opt->shift[i][j] = 0.25; /* +1/4 cyc */ + } else if (code == CODE_L5Q || code == CODE_L5P) { + opt->shift[i][j] = -0.25; /* -1/4 cyc */ } - else if (navsys[i]==SYS_CMP) { - if (code==CODE_L2P||code==CODE_L7Q||code==CODE_L6Q) { - opt->shift[i][j]=-0.25; /* -1/4 cyc */ - } - else if (code==CODE_L1P||code==CODE_L5P||code==CODE_L7P) { - opt->shift[i][j]=0.25; /* +1/4 cyc */ - } + } else if (navsys[i] == SYS_CMP) { + if (code == CODE_L2P || code == CODE_L7Q || code == CODE_L6Q) { + opt->shift[i][j] = -0.25; /* -1/4 cyc */ + } else if (code == CODE_L1P || code == CODE_L5P || code == CODE_L7P) { + opt->shift[i][j] = 0.25; /* +1/4 cyc */ } + } } } /* set station ID list to RINEX options comments -----------------------------*/ -static void setopt_sta_list(const strfile_t *str, rnxopt_t *opt) -{ - const stas_t *p; - char s1[40],s2[40]; - int n=0; - - for (p=str->stas;p;p=p->next) { - n++; - } - if (n<=1) return; - - rnxcomment(opt,"%5s %22s %22s", "STAID", "TIME OF FIRST OBS", "TIME OF LAST OBS"); - - for (p=str->stas,n--;p&&n>=0;p=p->next,n--) { - time2str(p->ts,s1,2); - time2str(p->te,s2,2); - rnxcomment(opt," %04d %s %s",p->staid,s1,s2); - } +static void setopt_sta_list(const strfile_t *str, rnxopt_t *opt) { + const stas_t *p; + char s1[40], s2[40]; + int n = 0; + + for (p = str->stas; p; p = p->next) { + n++; + } + if (n <= 1) return; + + rnxcomment(opt, "%5s %22s %22s", "STAID", "TIME OF FIRST OBS", "TIME OF LAST OBS"); + + for (p = str->stas, n--; p && n >= 0; p = p->next, n--) { + time2str(p->ts, s1, 2); + time2str(p->te, s2, 2); + rnxcomment(opt, " %04d %s %s", p->staid, s1, s2); + } } /* set station info in RINEX options -----------------------------------------*/ -static void setopt_sta(const strfile_t *str, rnxopt_t *opt) -{ - const stas_t *p; - const sta_t *sta; - double pos[3],enu[3]; - - trace(3,"setopt_sta:\n"); - - /* search first station in station list */ - for (p=str->stas;p;p=p->next) { - if (!p->next) break; - if (opt->ts.time&&timediff(p->next->te,opt->ts)<0.0) break; - } - if (p&&p->sta.name[0]!='\0') { - sta=&p->sta; - setopt_sta_list(str,opt); - } - else { - sta=str->sta; - } - /* Marker name, number and type */ - if (!*opt->marker && !*opt->markerno && !*opt->markertype) { - strcpy(opt->marker, sta->name); - strcpy(opt->markerno, sta->markerno); - strcpy(opt->markertype, sta->markertype); - } - /* Observer / agency */ - if (!*opt->name[0] && !*opt->name[1]) { - strcpy(opt->name[0], sta->observer); - strcpy(opt->name[1], sta->agency); - } - /* Receiver and antenna info */ - if (!*opt->rec[0]&&!*opt->rec[1]&&!*opt->rec[2]) { - strcpy(opt->rec[0],sta->recsno); - strcpy(opt->rec[1],sta->rectype); - strcpy(opt->rec[2],sta->recver); - } - if (!*opt->ant[0]&&!*opt->ant[1]&&!*opt->ant[2]) { - strcpy(opt->ant[0],sta->antsno); - strcpy(opt->ant[1],sta->antdes); - if (sta->antsetup) { - sprintf(opt->ant[2],"%d",sta->antsetup); - } - else *opt->ant[2]='\0'; - } - /* antenna approx position */ - if (!opt->autopos&&norm(sta->pos,3)>0.0) { - matcpy(opt->apppos,sta->pos,3,1); - } - /* antenna delta */ - if (norm(opt->antdel,3)>0.0) { - ; - } - else if (norm(sta->del,3)>0.0) { - if (!sta->deltype) { /* enu */ - opt->antdel[0]=sta->del[2]; /* h */ - opt->antdel[1]=sta->del[0]; /* e */ - opt->antdel[2]=sta->del[1]; /* n */ - } - else if (norm(sta->pos,3)>0.0) { /* xyz */ - ecef2pos(sta->pos,pos); - ecef2enu(pos,sta->del,enu); - opt->antdel[0]=enu[2]; /* h */ - opt->antdel[1]=enu[0]; /* e */ - opt->antdel[2]=enu[1]; /* n */ - } else { - trace(2,"failed to update RINEX option antenna delta from xyz due to no station position\n"); - } - } - else { - opt->antdel[0]=sta->hgt; - opt->antdel[1]=0.0; - opt->antdel[2]=0.0; - } +static void setopt_sta(const strfile_t *str, rnxopt_t *opt) { + const stas_t *p; + const sta_t *sta; + double pos[3], enu[3]; + + trace(3, "setopt_sta:\n"); + + /* search first station in station list */ + for (p = str->stas; p; p = p->next) { + if (!p->next) break; + if (opt->ts.time && timediff(p->next->te, opt->ts) < 0.0) break; + } + if (p && p->sta.name[0] != '\0') { + sta = &p->sta; + setopt_sta_list(str, opt); + } else { + sta = str->sta; + } + /* Marker name, number and type */ + if (!*opt->marker && !*opt->markerno && !*opt->markertype) { + strcpy(opt->marker, sta->name); + strcpy(opt->markerno, sta->markerno); + strcpy(opt->markertype, sta->markertype); + } + /* Observer / agency */ + if (!*opt->name[0] && !*opt->name[1]) { + strcpy(opt->name[0], sta->observer); + strcpy(opt->name[1], sta->agency); + } + /* Receiver and antenna info */ + if (!*opt->rec[0] && !*opt->rec[1] && !*opt->rec[2]) { + strcpy(opt->rec[0], sta->recsno); + strcpy(opt->rec[1], sta->rectype); + strcpy(opt->rec[2], sta->recver); + } + if (!*opt->ant[0] && !*opt->ant[1] && !*opt->ant[2]) { + strcpy(opt->ant[0], sta->antsno); + strcpy(opt->ant[1], sta->antdes); + if (sta->antsetup) { + sprintf(opt->ant[2], "%d", sta->antsetup); + } else + *opt->ant[2] = '\0'; + } + /* antenna approx position */ + if (!opt->autopos && norm(sta->pos, 3) > 0.0) { + matcpy(opt->apppos, sta->pos, 3, 1); + } + /* antenna delta */ + if (norm(opt->antdel, 3) > 0.0) { + ; + } else if (norm(sta->del, 3) > 0.0) { + if (!sta->deltype) { /* enu */ + opt->antdel[0] = sta->del[2]; /* h */ + opt->antdel[1] = sta->del[0]; /* e */ + opt->antdel[2] = sta->del[1]; /* n */ + } else if (norm(sta->pos, 3) > 0.0) { /* xyz */ + ecef2pos(sta->pos, pos); + ecef2enu(pos, sta->del, enu); + opt->antdel[0] = enu[2]; /* h */ + opt->antdel[1] = enu[0]; /* e */ + opt->antdel[2] = enu[1]; /* n */ + } else { + trace(2, "failed to update RINEX option antenna delta from xyz due to no station position\n"); + } + } else { + opt->antdel[0] = sta->hgt; + opt->antdel[1] = 0.0; + opt->antdel[2] = 0.0; + } } /* update station list -------------------------------------------------------*/ -static void update_stas(strfile_t *str) -{ - stas_t *p; - - if (!str->stas||str->stas->staid!=str->staid) { /* station ID changed */ - if (!(p=(stas_t *)calloc(1, sizeof(stas_t)))) return; - p->staid=str->staid; - p->ts=p->te=str->time; - p->next=str->stas; - str->stas=p; - } - else { - str->stas->te=str->time; - } +static void update_stas(strfile_t *str) { + stas_t *p; + + if (!str->stas || str->stas->staid != str->staid) { /* station ID changed */ + if (!(p = (stas_t *)calloc(1, sizeof(stas_t)))) return; + p->staid = str->staid; + p->ts = p->te = str->time; + p->next = str->stas; + str->stas = p; + } else { + str->stas->te = str->time; + } } /* update station info in station list ---------------------------------------*/ -static void update_stainf(strfile_t *str) -{ - if (str->stas&&str->stas->staid==str->staid) { - str->stas->sta=*str->sta; - } +static void update_stainf(strfile_t *str) { + if (str->stas && str->stas->staid == str->staid) { + str->stas->sta = *str->sta; + } } /* dump station list ---------------------------------------------------------*/ -static void dump_stas(const strfile_t *str) -{ - // #ifdef RTK_DISABLED // For debug - stas_t *p; - double pos[3]; - char s1[40],s2[40]; - - trace(2,"# STATION LIST\n"); - trace(2,"# %17s %19s %5s %6s %16s %16s %12s %13s %9s %2s %6s %6s %6s\n", - "START","END","STAID","MARKER","ANTENNA","RECEIVER","LATITUDE","LONGITUDE", - "HIGHT","DT","DEL1","DEL2","DEL3"); - - for (p=str->stas;p;p=p->next) { - time2str(p->ts,s1,0); - time2str(p->te,s2,0); - ecef2pos(p->sta.pos,pos); - trace(2,"%s %s %04d %-6.6s %-16.16s %-16.16s %12.8f %13.8f %9.3f %2d " - "%6.3f %6.3f %6.3f\n",s1,s2,p->staid,p->sta.name,p->sta.antdes, - p->sta.rectype,pos[0]*R2D,pos[1]*R2D,pos[2],p->sta.deltype, - p->sta.del[0],p->sta.del[1],p->sta.del[2]); - } +static void dump_stas(const strfile_t *str) { + // #ifdef RTK_DISABLED // For debug + stas_t *p; + double pos[3]; + char s1[40], s2[40]; + + trace(2, "# STATION LIST\n"); + trace(2, "# %17s %19s %5s %6s %16s %16s %12s %13s %9s %2s %6s %6s %6s\n", "START", "END", "STAID", + "MARKER", "ANTENNA", "RECEIVER", "LATITUDE", "LONGITUDE", "HIGHT", "DT", "DEL1", "DEL2", + "DEL3"); + + for (p = str->stas; p; p = p->next) { + time2str(p->ts, s1, 0); + time2str(p->te, s2, 0); + ecef2pos(p->sta.pos, pos); + trace(2, + "%s %s %04d %-6.6s %-16.16s %-16.16s %12.8f %13.8f %9.3f %2d " + "%6.3f %6.3f %6.3f\n", + s1, s2, p->staid, p->sta.name, p->sta.antdes, p->sta.rectype, pos[0] * R2D, pos[1] * R2D, + pos[2], p->sta.deltype, p->sta.del[0], p->sta.del[1], p->sta.del[2]); + } // #endif } /* add half-cycle ambiguity list ---------------------------------------------*/ -static int add_halfc(strfile_t *str, int sat, int idx, gtime_t time) -{ - halfc_t *p; - - if (!(p=(halfc_t *)calloc(1, sizeof(halfc_t)))) return 0; - p->ts=p->te=time; - p->stat=0; - p->next=str->halfc[sat-1][idx]; - str->halfc[sat-1][idx]=p; - return 1; +static int add_halfc(strfile_t *str, int sat, int idx, gtime_t time) { + halfc_t *p; + + if (!(p = (halfc_t *)calloc(1, sizeof(halfc_t)))) return 0; + p->ts = p->te = time; + p->stat = 0; + p->next = str->halfc[sat - 1][idx]; + str->halfc[sat - 1][idx] = p; + return 1; } /* update half-cycle ambiguity -----------------------------------------------*/ -static void update_halfc(strfile_t *str, obsd_t *obs) -{ - int i,sat=obs->sat; - - for (i=0;iL[i]==0.0) continue; - - /* if no list, start list */ - if (!str->halfc[sat-1][i]) { - if (!add_halfc(str,sat,i,obs->time)) continue; - } - /* reset list if true cycle slip */ - if ((obs->LLI[i]&LLI_SLIP)&&!(obs->LLI[i]&(LLI_HALFA|LLI_HALFS))) { - str->halfc[sat-1][i]->stat=0; - } - if (obs->LLI[i]&LLI_HALFC) { /* halfcyc unresolved */ - /* if new list, set unresolved start epoch */ - if (str->halfc[sat-1][i]->stat==0) { - str->halfc[sat-1][i]->ts=obs->time; - } - /* update unresolved end epoch and set status to active */ - str->halfc[sat-1][i]->te=obs->time; - str->halfc[sat-1][i]->stat=1; - } /* else if resolved, update status */ - else if (str->halfc[sat-1][i]->stat==1) { - if (obs->LLI[i]&LLI_HALFA) { - str->halfc[sat-1][i]->stat=2; /* resolved with add */ - } - else if (obs->LLI[i]&LLI_HALFS) { - str->halfc[sat-1][i]->stat=3; /* resolved with subtract */ - } - else { - str->halfc[sat-1][i]->stat=4; /* resolved with no adjust */ - } - /* create new list entry */ - if (!add_halfc(str,sat,i,obs->time)) continue; - } - } +static void update_halfc(strfile_t *str, obsd_t *obs) { + int i, sat = obs->sat; + + for (i = 0; i < NFREQ + NEXOBS; i++) { + if (obs->L[i] == 0.0) continue; + + /* if no list, start list */ + if (!str->halfc[sat - 1][i]) { + if (!add_halfc(str, sat, i, obs->time)) continue; + } + /* reset list if true cycle slip */ + if ((obs->LLI[i] & LLI_SLIP) && !(obs->LLI[i] & (LLI_HALFA | LLI_HALFS))) { + str->halfc[sat - 1][i]->stat = 0; + } + if (obs->LLI[i] & LLI_HALFC) { /* halfcyc unresolved */ + /* if new list, set unresolved start epoch */ + if (str->halfc[sat - 1][i]->stat == 0) { + str->halfc[sat - 1][i]->ts = obs->time; + } + /* update unresolved end epoch and set status to active */ + str->halfc[sat - 1][i]->te = obs->time; + str->halfc[sat - 1][i]->stat = 1; + } /* else if resolved, update status */ + else if (str->halfc[sat - 1][i]->stat == 1) { + if (obs->LLI[i] & LLI_HALFA) { + str->halfc[sat - 1][i]->stat = 2; /* resolved with add */ + } else if (obs->LLI[i] & LLI_HALFS) { + str->halfc[sat - 1][i]->stat = 3; /* resolved with subtract */ + } else { + str->halfc[sat - 1][i]->stat = 4; /* resolved with no adjust */ + } + /* create new list entry */ + if (!add_halfc(str, sat, i, obs->time)) continue; + } + } } /* dump half-cycle ambiguity list --------------------------------------------*/ -static void dump_halfc(const strfile_t *str) -{ - (void)str; +static void dump_halfc(const strfile_t *str) { + (void)str; #ifdef RTK_DISABLED - halfc_t *p; - char s0[8],s1[40],s2[40],*stats[]={"ADD","SUB","NON"}; - int i,j; - - trace(2,"# HALF-CYCLE AMBIGUITY CORRECTIONS\n"); - trace(2,"# %20s %22s %4s %3s %3s\n","START","END","SAT","FRQ","COR"); - - for (i=0;ihalfc[i][j];p;p=p->next) { - if (p->stat<=1) continue; - satno2id(i+1,s0); - time2str(p->ts,s1,2); - time2str(p->te,s2,2); - trace(2,"%s %s %4s %3d %3s\n",s1,s2,s0,j+1,stats[p->stat-2]); - } + halfc_t *p; + char s0[8], s1[40], s2[40], *stats[] = {"ADD", "SUB", "NON"}; + int i, j; + + trace(2, "# HALF-CYCLE AMBIGUITY CORRECTIONS\n"); + trace(2, "# %20s %22s %4s %3s %3s\n", "START", "END", "SAT", "FRQ", "COR"); + + for (i = 0; i < MAXSAT; i++) + for (j = 0; j < NFREQ + NEXOBS; j++) { + for (p = str->halfc[i][j]; p; p = p->next) { + if (p->stat <= 1) continue; + satno2id(i + 1, s0); + time2str(p->ts, s1, 2); + time2str(p->te, s2, 2); + trace(2, "%s %s %4s %3d %3s\n", s1, s2, s0, j + 1, stats[p->stat - 2]); + } } #endif } /* resolve half-cycle ambiguity ----------------------------------------------*/ -static void resolve_halfc(const strfile_t *str, obsd_t *data, int n) -{ - halfc_t *p; - int i,j,sat; - - for (i=0;ihalfc[sat-1][j];p;p=p->next) { - if (p->stat<=1) continue; /* unresolved half cycle */ - if (timediff(data[i].time,p->ts)<-DTTOL|| - timediff(data[i].time,p->te)> DTTOL) continue; - - if (p->stat==2) { /* add half cycle */ - data[i].L[j]+=0.5; - } - else if (p->stat==3) { /* subtract half cycle */ - data[i].L[j]-=0.5; - } - data[i].LLI[j]&=~LLI_HALFC; - } - data[i].LLI[j]&=~(LLI_HALFA|LLI_HALFS); +static void resolve_halfc(const strfile_t *str, obsd_t *data, int n) { + halfc_t *p; + int i, j, sat; + + for (i = 0; i < n; i++) { + sat = data[i].sat; + for (j = 0; j < NFREQ + NEXOBS; j++) { + for (p = str->halfc[sat - 1][j]; p; p = p->next) { + if (p->stat <= 1) continue; /* unresolved half cycle */ + if (timediff(data[i].time, p->ts) < -DTTOL || timediff(data[i].time, p->te) > DTTOL) + continue; + + if (p->stat == 2) { /* add half cycle */ + data[i].L[j] += 0.5; + } else if (p->stat == 3) { /* subtract half cycle */ + data[i].L[j] -= 0.5; } + data[i].LLI[j] &= ~LLI_HALFC; + } + data[i].LLI[j] &= ~(LLI_HALFA | LLI_HALFS); } + } } /* scan input files ----------------------------------------------------------*/ -static int scan_file(char **files, int nf, rnxopt_t *opt, strfile_t *str, - int *mask) -{ - eph_t eph0 ={0,-1,-1}; - geph_t geph0={0,-1}; - seph_t seph0={0}; - uint8_t codes[RNX_NUMSYS][33]={{0}}; - uint8_t types[RNX_NUMSYS][33]={{0}}; - char msg[128]; - int i,j,k,l,m,c=0,type,sys,prn,abort=0,n[RNX_NUMSYS]={0}; - - trace(3,"scan_file: nf=%d\n",nf); - - for (m=0;m=-1) { - if (opt->ts.time&&timediff(str->time,opt->ts)<-opt->ttol) continue; - if (opt->te.time&&timediff(str->time,opt->te)>-opt->ttol) break; - mask[m]=1; /* update file mask */ - - if (type==1) { /* observation data */ - for (i=0;iobs->n;i++) { - sys=satsys(str->obs->data[i].sat,NULL); - if (!(sys&opt->navsys)) continue; - /* Mapping from SYS_ to RNX_SYS_ */ - for (l=0;l=RNX_NUMSYS) continue; - - /* update obs-types */ - for (j=0;jobs->data[i].code[j]; - if (c==CODE_NONE) continue; - - for (k=0;k=n[l]&&n[l]<32) { - codes[l][n[l]++]=c; - } - if (kobs->data[i].P[j]!=0.0) types[l][k]|=1; - if (str->obs->data[i].L[j]!=0.0) types[l][k]|=2; - if (str->obs->data[i].D[j]!=0.0) types[l][k]|=4; - if (str->obs->data[i].SNR[j]!=0) types[l][k]|=8; - } - } - /* update half-cycle ambiguity list */ - if (opt->halfcyc) { - update_halfc(str,str->obs->data+i); - } - } - /* update station list */ - update_stas(str); +static int scan_file(char **files, int nf, rnxopt_t *opt, strfile_t *str, int *mask) { + eph_t eph0 = {0, -1, -1}; + geph_t geph0 = {0, -1}; + seph_t seph0 = {0}; + uint8_t codes[RNX_NUMSYS][33] = {{0}}; + uint8_t types[RNX_NUMSYS][33] = {{0}}; + char msg[128]; + int i, j, k, l, m, c = 0, type, sys, prn, abort = 0, n[RNX_NUMSYS] = {0}; + + trace(3, "scan_file: nf=%d\n", nf); + + for (m = 0; m < nf && !abort; m++) { + if (!open_strfile(str, files[m])) { + continue; + } + while ((type = input_strfile(str)) >= -1) { + if (opt->ts.time && timediff(str->time, opt->ts) < -opt->ttol) continue; + if (opt->te.time && timediff(str->time, opt->te) > -opt->ttol) break; + mask[m] = 1; /* update file mask */ + + if (type == 1) { /* observation data */ + for (i = 0; i < str->obs->n; i++) { + sys = satsys(str->obs->data[i].sat, NULL); + if (!(sys & opt->navsys)) continue; + /* Mapping from SYS_ to RNX_SYS_ */ + for (l = 0; l < RNX_NUMSYS; l++) + if (navsys[l] == sys) break; + if (l >= RNX_NUMSYS) continue; + + /* update obs-types */ + for (j = 0; j < NFREQ + NEXOBS; j++) { + int c = str->obs->data[i].code[j]; + if (c == CODE_NONE) continue; + + for (k = 0; k < n[l]; k++) { + if (codes[l][k] == c) break; } - else if (type==5) { /* station info */ - /* update station info */ - update_stainf(str); + if (k >= n[l] && n[l] < 32) { + codes[l][n[l]++] = c; } - if (++c%11) continue; - - char tstr[40]; - snprintf(msg,sizeof(msg),"scanning: %s %s%s%s%s%s%s%s", - time2str(str->time,tstr,0), - n[0]?"G":"",n[1]?"R":"",n[2]?"E":"",n[3]?"J":"", - n[4]?"S":"",n[5]?"C":"",n[6]?"I":""); - if ((abort=showmsg(msg))) break; - } - close_strfile(str); - } - showmsg(""); - - if (abort) { - trace(2,"aborted in scan\n"); - return 0; - } - for (i=0;iobs->data[i].P[j] != 0.0) types[l][k] |= 1; + if (str->obs->data[i].L[j] != 0.0) types[l][k] |= 2; + if (str->obs->data[i].D[j] != 0.0) types[l][k] |= 4; + if (str->obs->data[i].SNR[j] != 0) types[l][k] |= 8; + } + } + /* update half-cycle ambiguity list */ + if (opt->halfcyc) { + update_halfc(str, str->obs->data + i); + } } + /* update station list */ + update_stas(str); + } else if (type == 5) { /* station info */ + /* update station info */ + update_stainf(str); + } + if (++c % 11) continue; + + char tstr[40]; + snprintf(msg, sizeof(msg), "scanning: %s %s%s%s%s%s%s%s", time2str(str->time, tstr, 0), + n[0] ? "G" : "", n[1] ? "R" : "", n[2] ? "E" : "", n[3] ? "J" : "", n[4] ? "S" : "", + n[5] ? "C" : "", n[6] ? "I" : ""); + if ((abort = showmsg(msg))) break; + } + close_strfile(str); + } + showmsg(""); + + if (abort) { + trace(2, "aborted in scan\n"); + return 0; + } + for (i = 0; i < RNX_NUMSYS; i++) + for (j = 0; j < n[i]; j++) { + trace(2, "scan_file: sys=%d code=%s type=%d\n", i, code2obs(codes[i][j]), types[i][j]); + } + /* sort and set obs-types in RINEX options */ + for (i = 0; i < RNX_NUMSYS; i++) { + sort_obstype(codes[i], types[i], n[i], i); + setopt_obstype(codes[i], types[i], i, opt); + + for (j = 0; j < n[i]; j++) { + trace(3, "scan_file: sys=%d code=%s\n", i, code2obs(codes[i][j])); } - /* set station info in RINEX options */ - setopt_sta(str,opt); - - /* set phase shifts in RINEX options */ - if (opt->phshift) { - setopt_phshift(opt); - } - /* set GLONASS FCN and clear ephemeris */ - for (i=0;inav->n;i++) { - str->nav->eph[i]=eph0; - } - for (i=0;inav->ng;i++) { - if (satsys(str->nav->geph[i].sat,&prn)!=SYS_GLO) continue; - str->nav->glo_fcn[prn-1]=str->nav->geph[i].frq+8; - str->nav->geph[i]=geph0; - } - for (i=0;inav->ns;i++) { - str->nav->seph[i]=seph0; - } - dump_stas(str); - dump_halfc(str); - return 1; + } + /* set station info in RINEX options */ + setopt_sta(str, opt); + + /* set phase shifts in RINEX options */ + if (opt->phshift) { + setopt_phshift(opt); + } + /* set GLONASS FCN and clear ephemeris */ + for (i = 0; i < str->nav->n; i++) { + str->nav->eph[i] = eph0; + } + for (i = 0; i < str->nav->ng; i++) { + if (satsys(str->nav->geph[i].sat, &prn) != SYS_GLO) continue; + str->nav->glo_fcn[prn - 1] = str->nav->geph[i].frq + 8; + str->nav->geph[i] = geph0; + } + for (i = 0; i < str->nav->ns; i++) { + str->nav->seph[i] = seph0; + } + dump_stas(str); + dump_halfc(str); + return 1; } /* write RINEX header --------------------------------------------------------*/ -static void write_header(FILE **ofp, int idx, const rnxopt_t *opt, - const nav_t *nav) -{ - switch (idx) { - case 0: outrnxobsh (ofp[0],opt,nav); break; - case 1: outrnxnavh (ofp[1],opt,nav); break; - case 2: outrnxgnavh(ofp[2],opt,nav); break; - case 3: outrnxhnavh(ofp[3],opt,nav); break; - case 4: outrnxqnavh(ofp[4],opt,nav); break; - case 5: outrnxlnavh(ofp[5],opt,nav); break; - case 6: outrnxcnavh(ofp[6],opt,nav); break; - case 7: outrnxinavh(ofp[7],opt,nav); break; - } +static void write_header(FILE **ofp, int idx, const rnxopt_t *opt, const nav_t *nav) { + switch (idx) { + case 0: + outrnxobsh(ofp[0], opt, nav); + break; + case 1: + outrnxnavh(ofp[1], opt, nav); + break; + case 2: + outrnxgnavh(ofp[2], opt, nav); + break; + case 3: + outrnxhnavh(ofp[3], opt, nav); + break; + case 4: + outrnxqnavh(ofp[4], opt, nav); + break; + case 5: + outrnxlnavh(ofp[5], opt, nav); + break; + case 6: + outrnxcnavh(ofp[6], opt, nav); + break; + case 7: + outrnxinavh(ofp[7], opt, nav); + break; + } } /* open output files ---------------------------------------------------------*/ -static int openfile(FILE **ofp, char *files[], const char *file, - const rnxopt_t *opt, const nav_t *nav) -{ - char path[1024]; - int i; - - trace(3,"openfile:\n"); - - for (i=0;i=0;i--) if (ofp[i]) fclose(ofp[i]); - return 0; - } - /* write RINEX header */ - write_header(ofp,i,opt,nav); - } - return 1; +static int openfile(FILE **ofp, char *files[], const char *file, const rnxopt_t *opt, + const nav_t *nav) { + char path[1024]; + int i; + + trace(3, "openfile:\n"); + + for (i = 0; i < NOUTFILE; i++) { + if (!*files[i]) continue; + + strcpy(path, files[i]); + + /* check overwrite input file and modify output file */ + if (!strcmp(path, file)) strcat(path, "_"); + + /* create directory if not exist */ + createdir(path); + + if (!(ofp[i] = fopen(path, "w"))) { + showmsg("file open error: %s", path); + for (i--; i >= 0; i--) + if (ofp[i]) fclose(ofp[i]); + return 0; + } + /* write RINEX header */ + write_header(ofp, i, opt, nav); + } + return 1; } /* close output files --------------------------------------------------------*/ -static void closefile(FILE **ofp, const rnxopt_t *opt, nav_t *nav) -{ - int i; - - trace(3,"closefile:\n"); - - for (i=0;irnxver>=300)?31:28,"",event,2); - fprintf(fp,"%-60s%-20s\n","EVENT: START MOVING ANTENNA","COMMENT"); - fprintf(fp,"%-60s%-20s\n",opt->marker,"MARKER NAME"); - } - else if (event==EVENT_NEWSITE) { - for (q=stas;q;q=q->next) { - if (q->staid==staid&&timediff(time,q->te)<=0.0) p=q; - } - fprintf(fp,"%*s%d%3d\n",(opt->rnxver>=300)?31:28,"",event,6); - fprintf(fp,"%-60s%-20s\n","EVENT: NEW SITE OCCUPATION","COMMENT"); - if (!p) { - fprintf(fp,"%04d%56s%-20s\n",staid,"","MARKER NAME"); - return; - } - fprintf(fp,"%-60s%-20s\n",p->sta.name,"MARKER NAME"); - fprintf(fp,"%-20.20s%-20.20s%-20.20s%-20s\n",p->sta.recsno, - p->sta.rectype,p->sta.recver,"REC # / TYPE / VERS"); - fprintf(fp,"%-20.20s%-20.20s%-20.20s%-20s\n",p->sta.antsno, - p->sta.antdes,"","ANT # / TYPE"); - fprintf(fp,"%14.4f%14.4f%14.4f%-18s%-20s\n",p->sta.pos[0], - p->sta.pos[1],p->sta.pos[2],"","APPROX POSITION XYZ"); - - /* antenna delta */ - if (norm(p->sta.del,3)>0.0) { - if (!p->sta.deltype) { /* enu */ - del[0]=p->sta.del[2]; /* h */ - del[1]=p->sta.del[0]; /* e */ - del[2]=p->sta.del[1]; /* n */ - } - else if (norm(p->sta.pos,3)>0.0) { /* xyz */ - ecef2pos(p->sta.pos,pos); - ecef2enu(pos,p->sta.del,enu); - del[0]=enu[2]; /* h */ - del[1]=enu[0]; /* e */ - del[2]=enu[1]; /* n */ - } else { - trace(2,"failed to output RINEX option antenna delta from xyz due to no station position\n"); - del[0]=del[1]=del[2]=0.0; - } - } - else { - del[0]=p->sta.hgt; - del[1]=del[2]=0.0; - } - fprintf(fp,"%14.4f%14.4f%14.4f%-18s%-20s\n",del[0],del[1],del[2],"", - "ANTENNA: DELTA H/E/N"); - } - else if (event==EVENT_EXTERNAL) { - time2epoch(time,ep); - fprintf(fp,"%s %02d %02.0f %02.0f %02.0f %02.0f %010.7f %d%3d\n", - (opt->rnxver>=300)?">":"", - (opt->rnxver>=300)?(int)ep[0]:(int)ep[0]%100, - ep[1],ep[2],ep[3],ep[4],ep[5],event,1); - fprintf(fp,"%-60s%-20s\n","EXTERNAL EVENT","COMMENT"); - } +static void outrnxevent(FILE *fp, const rnxopt_t *opt, gtime_t time, int event, const stas_t *stas, + int staid) { + const stas_t *p = NULL, *q; + double ep[6], pos[3], enu[3], del[3]; + + trace(3, "outrnxevent: event=%d\n", event); + + if (event == EVENT_STARTMOVE) { + fprintf(fp, "%*s%d%3d\n", (opt->rnxver >= 300) ? 31 : 28, "", event, 2); + fprintf(fp, "%-60s%-20s\n", "EVENT: START MOVING ANTENNA", "COMMENT"); + fprintf(fp, "%-60s%-20s\n", opt->marker, "MARKER NAME"); + } else if (event == EVENT_NEWSITE) { + for (q = stas; q; q = q->next) { + if (q->staid == staid && timediff(time, q->te) <= 0.0) p = q; + } + fprintf(fp, "%*s%d%3d\n", (opt->rnxver >= 300) ? 31 : 28, "", event, 6); + fprintf(fp, "%-60s%-20s\n", "EVENT: NEW SITE OCCUPATION", "COMMENT"); + if (!p) { + fprintf(fp, "%04d%56s%-20s\n", staid, "", "MARKER NAME"); + return; + } + fprintf(fp, "%-60s%-20s\n", p->sta.name, "MARKER NAME"); + fprintf(fp, "%-20.20s%-20.20s%-20.20s%-20s\n", p->sta.recsno, p->sta.rectype, p->sta.recver, + "REC # / TYPE / VERS"); + fprintf(fp, "%-20.20s%-20.20s%-20.20s%-20s\n", p->sta.antsno, p->sta.antdes, "", + "ANT # / TYPE"); + fprintf(fp, "%14.4f%14.4f%14.4f%-18s%-20s\n", p->sta.pos[0], p->sta.pos[1], p->sta.pos[2], "", + "APPROX POSITION XYZ"); + + /* antenna delta */ + if (norm(p->sta.del, 3) > 0.0) { + if (!p->sta.deltype) { /* enu */ + del[0] = p->sta.del[2]; /* h */ + del[1] = p->sta.del[0]; /* e */ + del[2] = p->sta.del[1]; /* n */ + } else if (norm(p->sta.pos, 3) > 0.0) { /* xyz */ + ecef2pos(p->sta.pos, pos); + ecef2enu(pos, p->sta.del, enu); + del[0] = enu[2]; /* h */ + del[1] = enu[0]; /* e */ + del[2] = enu[1]; /* n */ + } else { + trace(2, + "failed to output RINEX option antenna delta from xyz due to no station position\n"); + del[0] = del[1] = del[2] = 0.0; + } + } else { + del[0] = p->sta.hgt; + del[1] = del[2] = 0.0; + } + fprintf(fp, "%14.4f%14.4f%14.4f%-18s%-20s\n", del[0], del[1], del[2], "", + "ANTENNA: DELTA H/E/N"); + } else if (event == EVENT_EXTERNAL) { + time2epoch(time, ep); + fprintf(fp, "%s %02d %02.0f %02.0f %02.0f %02.0f %010.7f %d%3d\n", + (opt->rnxver >= 300) ? ">" : "", (opt->rnxver >= 300) ? (int)ep[0] : (int)ep[0] % 100, + ep[1], ep[2], ep[3], ep[4], ep[5], event, 1); + fprintf(fp, "%-60s%-20s\n", "EXTERNAL EVENT", "COMMENT"); + } } /* save cycle slips ----------------------------------------------------------*/ -static void save_slips(strfile_t *str, obsd_t *data, int n) -{ - int i,j; - - for (i=0;islips[data[i].sat-1][j]=1; +static void save_slips(strfile_t *str, obsd_t *data, int n) { + int i, j; + + for (i = 0; i < n; i++) + for (j = 0; j < NFREQ + NEXOBS; j++) { + if (data[i].LLI[j] & LLI_SLIP) str->slips[data[i].sat - 1][j] = 1; } } /* restore cycle slips -------------------------------------------------------*/ -static void rest_slips(strfile_t *str, obsd_t *data, int n) -{ - int i,j; - - for (i=0;islips[data[i].sat-1][j]) { - data[i].LLI[j]|=LLI_SLIP; - str->slips[data[i].sat-1][j]=0; - } +static void rest_slips(strfile_t *str, obsd_t *data, int n) { + int i, j; + + for (i = 0; i < n; i++) + for (j = 0; j < NFREQ + NEXOBS; j++) { + if (data[i].L[j] != 0.0 && str->slips[data[i].sat - 1][j]) { + data[i].LLI[j] |= LLI_SLIP; + str->slips[data[i].sat - 1][j] = 0; + } } } /* screen time with time tolerance -------------------------------------------*/ -static int screent_ttol(gtime_t time, gtime_t ts, gtime_t te, double tint, - double ttol) -{ - if (ttol<=0.0) ttol=DTTOL; - - return (tint<=0.0||fmod(time2gpst(time,NULL)+ttol,tint)<=ttol*2.0)&& - (ts.time==0||timediff(time,ts)>=-ttol)&& - (te.time==0||timediff(time,te)< ttol); +static int screent_ttol(gtime_t time, gtime_t ts, gtime_t te, double tint, double ttol) { + if (ttol <= 0.0) ttol = DTTOL; + + return (tint <= 0.0 || fmod(time2gpst(time, NULL) + ttol, tint) <= ttol * 2.0) && + (ts.time == 0 || timediff(time, ts) >= -ttol) && + (te.time == 0 || timediff(time, te) < ttol); } /* Order observation data by the RTKLib satellite index */ -static int cmpobs(const void *p1, const void *p2) -{ - obsd_t *obs1 = (obsd_t *)p1, *obs2 = (obsd_t *)p2; - return obs1->sat - obs2->sat; +static int cmpobs(const void *p1, const void *p2) { + obsd_t *obs1 = (obsd_t *)p1, *obs2 = (obsd_t *)p2; + return obs1->sat - obs2->sat; } /* convert observation data --------------------------------------------------*/ -static void convobs(FILE **ofp, rnxopt_t *opt, strfile_t *str, int *n, - gtime_t *tend, int *staid) -{ - gtime_t time; - int i,j; - - trace(3,"convobs :\n"); - - if (!ofp[0]||str->obs->n<=0) return; - - time=str->obs->data[0].time; - - /* Avoid duplicated data by multiple files handover */ - if (tend->time&&timediff(time,*tend)<-opt->ttol) return; - *tend=time; - - /* save cycle slips */ - save_slips(str,str->obs->data,str->obs->n); - - if (!screent_ttol(time,opt->ts,opt->te,opt->tint,opt->ttol)) return; - - /* restore cycle slips */ - rest_slips(str,str->obs->data,str->obs->n); - - if (str->staid!=*staid) { /* station ID changed */ - - if (*staid>=0) { /* output RINEX event */ - outrnxevent(ofp[0],opt,str->time,EVENT_NEWSITE,str->stas,str->staid); - /* Set cycle slips */ - for (i=0;iobs->n;i++) { - for (j=0;jobs->data[i].L[j]!=0.0) { - str->obs->data[i].LLI[j]|=LLI_SLIP; - } - } - } +static void convobs(FILE **ofp, rnxopt_t *opt, strfile_t *str, int *n, gtime_t *tend, int *staid) { + gtime_t time; + int i, j; + + trace(3, "convobs :\n"); + + if (!ofp[0] || str->obs->n <= 0) return; + + time = str->obs->data[0].time; + + /* Avoid duplicated data by multiple files handover */ + if (tend->time && timediff(time, *tend) < -opt->ttol) return; + *tend = time; + + /* save cycle slips */ + save_slips(str, str->obs->data, str->obs->n); + + if (!screent_ttol(time, opt->ts, opt->te, opt->tint, opt->ttol)) return; + + /* restore cycle slips */ + rest_slips(str, str->obs->data, str->obs->n); + + if (str->staid != *staid) { /* station ID changed */ + + if (*staid >= 0) { /* output RINEX event */ + outrnxevent(ofp[0], opt, str->time, EVENT_NEWSITE, str->stas, str->staid); + /* Set cycle slips */ + for (i = 0; i < str->obs->n; i++) { + for (j = 0; j < NFREQ + NEXOBS; j++) { + if (str->obs->data[i].L[j] != 0.0) { + str->obs->data[i].LLI[j] |= LLI_SLIP; + } } - *staid=str->staid; + } + } + *staid = str->staid; + } + /* resolve half-cycle ambiguity */ + if (opt->halfcyc) { + resolve_halfc(str, str->obs->data, str->obs->n); + } + /* Sort observation data by the RTKLib satellite index */ + if (opt->sortsats) { + qsort(str->obs->data, str->obs->n, sizeof(obsd_t), cmpobs); + } + /* output RINEX observation data */ + outrnxobsb(ofp[0], opt, str->obs->data, str->obs->n, str->obs->flag); + /* n[NOUTFILE+1] - count of events converted to rinex */ + if (str->obs->flag == 5) n[NOUTFILE + 1]++; + /* set to zero flag for the next iteration (initialization) */ + str->obs->flag = 0; - } - /* resolve half-cycle ambiguity */ - if (opt->halfcyc) { - resolve_halfc(str,str->obs->data,str->obs->n); - } - /* Sort observation data by the RTKLib satellite index */ - if (opt->sortsats) { - qsort(str->obs->data, str->obs->n, sizeof(obsd_t), cmpobs); - } - /* output RINEX observation data */ - outrnxobsb(ofp[0],opt,str->obs->data,str->obs->n,str->obs->flag); - /* n[NOUTFILE+1] - count of events converted to rinex */ - if (str->obs->flag == 5) - n[NOUTFILE+1]++; - /* set to zero flag for the next iteration (initialization) */ - str->obs->flag = 0; - - if (opt->tstart.time==0) opt->tstart=time; - opt->tend=time; - - n[0]++; + if (opt->tstart.time == 0) opt->tstart = time; + opt->tend = time; + + n[0]++; } /* convert navigation data --------------------------------------------------*/ -static void convnav(FILE **ofp, rnxopt_t *opt, strfile_t *str, int *n) -{ - gtime_t ts; - double dtoe; - int sat,set,sys,prn,sep_nav=(opt->rnxver<=299||opt->sep_nav); - - trace(3,"convnav :\n"); - - sat=str->ephsat; - set=str->ephset; - sys=satsys(sat,&prn); - if (!(sys&opt->navsys)||opt->exsats[sat-1]) return; - - switch (sys) { - case SYS_GLO: dtoe=MAXDTOE_GLO; break; - case SYS_GAL: dtoe=MAXDTOE_GAL; break; - case SYS_QZS: dtoe=MAXDTOE_QZS; break; - case SYS_CMP: dtoe=MAXDTOE_CMP; break; - case SYS_IRN: dtoe=MAXDTOE_IRN; break; - case SYS_SBS: dtoe=MAXDTOE_SBS; break; - default : dtoe=MAXDTOE ; break; - } - ts=opt->ts; - if (ts.time!=0) ts=timeadd(ts,-dtoe); - if (!screent(str->time,ts,opt->te,0.0)) return; - - if (sys==SYS_GPS) { - if (ofp[1]) { - outrnxnavb(ofp[1],opt,str->nav->eph+sat-1+MAXSAT*set); - n[1]++; - } - } - else if (sys==SYS_GLO) { - if (ofp[1]&&!sep_nav) { - outrnxgnavb(ofp[1],opt,str->nav->geph+prn-1); - n[1]++; - } - else if (ofp[2]&&sep_nav) { - outrnxgnavb(ofp[2],opt,str->nav->geph+prn-1); - n[2]++; - } - } - else if (sys==SYS_SBS) { - if (ofp[1]&&!sep_nav) { - outrnxhnavb(ofp[1],opt,str->nav->seph+prn-MINPRNSBS); - n[1]++; - } - else if (ofp[3]&&sep_nav) { - outrnxhnavb(ofp[3],opt,str->nav->seph+prn-MINPRNSBS); - n[3]++; - } - } - else if (sys==SYS_QZS) { - if (ofp[1]&&!sep_nav) { - outrnxnavb(ofp[1],opt,str->nav->eph+sat-1+MAXSAT*set); - n[1]++; - } - else if (ofp[4]&&sep_nav) { - outrnxnavb(ofp[4],opt,str->nav->eph+sat-1+MAXSAT*set); - n[4]++; - } - } - else if (sys==SYS_GAL) { - if (ofp[1]&&!sep_nav) { - outrnxnavb(ofp[1],opt,str->nav->eph+sat-1+MAXSAT*set); - n[1]++; - } - else if (ofp[5]&&sep_nav) { - outrnxnavb(ofp[5],opt,str->nav->eph+sat-1+MAXSAT*set); - n[5]++; - } - } - else if (sys==SYS_CMP) { - if (ofp[1]&&!sep_nav) { - outrnxnavb(ofp[1],opt,str->nav->eph+sat-1+MAXSAT*set); - n[1]++; - } - else if (ofp[6]&&sep_nav) { - outrnxnavb(ofp[6],opt,str->nav->eph+sat-1+MAXSAT*set); - n[6]++; - } - } - else if (sys==SYS_IRN) { - if (ofp[1]&&!sep_nav) { - outrnxnavb(ofp[1],opt,str->nav->eph+sat-1+MAXSAT*set); - n[1]++; - } - else if (ofp[7]&&sep_nav) { - outrnxnavb(ofp[7],opt,str->nav->eph+sat-1+MAXSAT*set); - n[7]++; - } - } +static void convnav(FILE **ofp, rnxopt_t *opt, strfile_t *str, int *n) { + gtime_t ts; + double dtoe; + int sat, set, sys, prn, sep_nav = (opt->rnxver <= 299 || opt->sep_nav); + + trace(3, "convnav :\n"); + + sat = str->ephsat; + set = str->ephset; + sys = satsys(sat, &prn); + if (!(sys & opt->navsys) || opt->exsats[sat - 1]) return; + + switch (sys) { + case SYS_GLO: + dtoe = MAXDTOE_GLO; + break; + case SYS_GAL: + dtoe = MAXDTOE_GAL; + break; + case SYS_QZS: + dtoe = MAXDTOE_QZS; + break; + case SYS_CMP: + dtoe = MAXDTOE_CMP; + break; + case SYS_IRN: + dtoe = MAXDTOE_IRN; + break; + case SYS_SBS: + dtoe = MAXDTOE_SBS; + break; + default: + dtoe = MAXDTOE; + break; + } + ts = opt->ts; + if (ts.time != 0) ts = timeadd(ts, -dtoe); + if (!screent(str->time, ts, opt->te, 0.0)) return; + + if (sys == SYS_GPS) { + if (ofp[1]) { + outrnxnavb(ofp[1], opt, str->nav->eph + sat - 1 + MAXSAT * set); + n[1]++; + } + } else if (sys == SYS_GLO) { + if (ofp[1] && !sep_nav) { + outrnxgnavb(ofp[1], opt, str->nav->geph + prn - 1); + n[1]++; + } else if (ofp[2] && sep_nav) { + outrnxgnavb(ofp[2], opt, str->nav->geph + prn - 1); + n[2]++; + } + } else if (sys == SYS_SBS) { + if (ofp[1] && !sep_nav) { + outrnxhnavb(ofp[1], opt, str->nav->seph + prn - MINPRNSBS); + n[1]++; + } else if (ofp[3] && sep_nav) { + outrnxhnavb(ofp[3], opt, str->nav->seph + prn - MINPRNSBS); + n[3]++; + } + } else if (sys == SYS_QZS) { + if (ofp[1] && !sep_nav) { + outrnxnavb(ofp[1], opt, str->nav->eph + sat - 1 + MAXSAT * set); + n[1]++; + } else if (ofp[4] && sep_nav) { + outrnxnavb(ofp[4], opt, str->nav->eph + sat - 1 + MAXSAT * set); + n[4]++; + } + } else if (sys == SYS_GAL) { + if (ofp[1] && !sep_nav) { + outrnxnavb(ofp[1], opt, str->nav->eph + sat - 1 + MAXSAT * set); + n[1]++; + } else if (ofp[5] && sep_nav) { + outrnxnavb(ofp[5], opt, str->nav->eph + sat - 1 + MAXSAT * set); + n[5]++; + } + } else if (sys == SYS_CMP) { + if (ofp[1] && !sep_nav) { + outrnxnavb(ofp[1], opt, str->nav->eph + sat - 1 + MAXSAT * set); + n[1]++; + } else if (ofp[6] && sep_nav) { + outrnxnavb(ofp[6], opt, str->nav->eph + sat - 1 + MAXSAT * set); + n[6]++; + } + } else if (sys == SYS_IRN) { + if (ofp[1] && !sep_nav) { + outrnxnavb(ofp[1], opt, str->nav->eph + sat - 1 + MAXSAT * set); + n[1]++; + } else if (ofp[7] && sep_nav) { + outrnxnavb(ofp[7], opt, str->nav->eph + sat - 1 + MAXSAT * set); + n[7]++; + } + } } /* convert SBAS message ------------------------------------------------------*/ -static void convsbs(FILE **ofp, rnxopt_t *opt, strfile_t *str, int *n, - gtime_t *tend) -{ - gtime_t time; - int prn,sat,sys,sep_nav=opt->rnxver<=299||opt->sep_nav; - - trace(3,"convsbs :\n"); - - time=gpst2time(str->raw.sbsmsg.week,str->raw.sbsmsg.tow); - - if (!screent(time,opt->ts,opt->te,0.0)) return; - - /* Avoid duplicated data by multiple files handover */ - if (tend->time&&timediff(time,*tend)<-opt->ttol) return; - *tend=time; - - prn=str->raw.sbsmsg.prn; - if (MINPRNSBS<=prn&&prn<=MAXPRNSBS) { - sys=SYS_SBS; - } - else if (MINPRNQZS_S<=prn&&prn<=MAXPRNQZS_S) { - sys=SYS_QZS; - prn+=10; - } - else { - trace(2,"sbas message satellite error: prn=%d\n",prn); - return; - } - if (!(sat=satno(sys,prn))||opt->exsats[sat-1]==1) return; - - /* output SBAS message log */ - if (ofp[NOUTFILE-1]) { - sbsoutmsg(ofp[NOUTFILE-1],&str->raw.sbsmsg); - n[NOUTFILE-1]++; - } - /* output SBAS ephemeris */ - if ((opt->navsys&SYS_SBS)&&sbsupdatecorr(&str->raw.sbsmsg,str->nav)==9) { - - if (ofp[1]&&!sep_nav) { - outrnxhnavb(ofp[1],opt,str->nav->seph+prn-MINPRNSBS); - n[1]++; - } - else if (ofp[3]&&sep_nav) { - outrnxhnavb(ofp[3],opt,str->nav->seph+prn-MINPRNSBS); - n[3]++; - } - } +static void convsbs(FILE **ofp, rnxopt_t *opt, strfile_t *str, int *n, gtime_t *tend) { + gtime_t time; + int prn, sat, sys, sep_nav = opt->rnxver <= 299 || opt->sep_nav; + + trace(3, "convsbs :\n"); + + time = gpst2time(str->raw.sbsmsg.week, str->raw.sbsmsg.tow); + + if (!screent(time, opt->ts, opt->te, 0.0)) return; + + /* Avoid duplicated data by multiple files handover */ + if (tend->time && timediff(time, *tend) < -opt->ttol) return; + *tend = time; + + prn = str->raw.sbsmsg.prn; + if (MINPRNSBS <= prn && prn <= MAXPRNSBS) { + sys = SYS_SBS; + } else if (MINPRNQZS_S <= prn && prn <= MAXPRNQZS_S) { + sys = SYS_QZS; + prn += 10; + } else { + trace(2, "sbas message satellite error: prn=%d\n", prn); + return; + } + if (!(sat = satno(sys, prn)) || opt->exsats[sat - 1] == 1) return; + + /* output SBAS message log */ + if (ofp[NOUTFILE - 1]) { + sbsoutmsg(ofp[NOUTFILE - 1], &str->raw.sbsmsg); + n[NOUTFILE - 1]++; + } + /* output SBAS ephemeris */ + if ((opt->navsys & SYS_SBS) && sbsupdatecorr(&str->raw.sbsmsg, str->nav) == 9) { + if (ofp[1] && !sep_nav) { + outrnxhnavb(ofp[1], opt, str->nav->seph + prn - MINPRNSBS); + n[1]++; + } else if (ofp[3] && sep_nav) { + outrnxhnavb(ofp[3], opt, str->nav->seph + prn - MINPRNSBS); + n[3]++; + } + } } /* set approx position in RINEX options --------------------------------------*/ -static void setopt_apppos(strfile_t *str, rnxopt_t *opt) -{ - prcopt_t prcopt=prcopt_default; - sol_t sol={{0}}; - char msg[128]; - - prcopt.navsys=opt->navsys; - - /* point positioning with last obs data */ - if (!pntpos(str->obs->data,str->obs->n,str->nav,&prcopt,&sol,NULL,NULL, - msg)) { - trace(2,"point position error (%s)\n",msg); - return; - } - matcpy(opt->apppos,sol.rr,3,1); +static void setopt_apppos(strfile_t *str, rnxopt_t *opt) { + prcopt_t prcopt = prcopt_default; + sol_t sol = {{0}}; + char msg[128]; + + prcopt.navsys = opt->navsys; + + /* point positioning with last obs data */ + if (!pntpos(str->obs->data, str->obs->n, str->nav, &prcopt, &sol, NULL, NULL, msg)) { + trace(2, "point position error (%s)\n", msg); + return; + } + matcpy(opt->apppos, sol.rr, 3, 1); } /* show conversion status ----------------------------------------------------*/ -static int showstat(int sess, gtime_t ts, gtime_t te, int *n) -{ - const char type[]="ONGHQLCISET"; - char msg[1024]="",*p=msg,s[40]; - int i; - - if (sess>0) { - p+=sprintf(p,"(%d) ",sess); - } - if (ts.time!=0) { - time2str(ts,s,0); - p+=sprintf(p,"%s",s); - } - if (te.time!=0&&timediff(te,ts)>0.9) { - time2str(te,s,0); - p+=sprintf(p,"-%s",s+5); - } - p+=sprintf(p,": "); - - /* +2 to NOUTFILE for counters of errors and events */ - for (i=0;i 0) { + p += sprintf(p, "(%d) ", sess); + } + if (ts.time != 0) { + time2str(ts, s, 0); + p += sprintf(p, "%s", s); + } + if (te.time != 0 && timediff(te, ts) > 0.9) { + time2str(te, s, 0); + p += sprintf(p, "-%s", s + 5); + } + p += sprintf(p, ": "); + + /* +2 to NOUTFILE for counters of errors and events */ + for (i = 0; i < NOUTFILE + 2; i++) { + if (n[i] == 0) continue; + p += sprintf(p, "%c=%d%s", type[i], n[i], i < NOUTFILE + 1 ? " " : ""); + } + return showmsg(msg); } /* RINEX converter for single-session ----------------------------------------*/ -static int convrnx_s(int sess, int format, rnxopt_t *opt, const char *file, - char **ofile) -{ - FILE *ofp[NOUTFILE]={NULL}; - strfile_t *str; - gtime_t tend[3]={{0}}; - int i,j,nf,type,n[NOUTFILE+2]={0},mask[MAXEXFILE]={0},staid=-1,abort=0; - char path[1024],*paths[NOUTFILE],s[NOUTFILE][1024]; - char *epath[MAXEXFILE]={0},*staname=*opt->staid?opt->staid:"0000"; - - trace(3,"convrnx_s: sess=%d format=%d file=%s ofile=%s %s %s %s %s %s %s " - "%s %s\n",sess,format,file,ofile[0],ofile[1],ofile[2],ofile[3], - ofile[4],ofile[5],ofile[6],ofile[7],ofile[8]); - - /* replace keywords in input file */ - if (reppath(file,path,opt->ts,staname,"")<0) { - showmsg("no time for input file: %s",file); - return 0; - } - /* expand wild-cards in input file */ - for (i=0;ircvopt))) { - for (i=0;itime=opt->trtcm; - } - else if (opt->ts.time) { - str->time=timeadd(opt->ts,-1.0); - } - /* set GLONASS FCN in RINEX options */ - for (i=0;inav->glo_fcn[i]=opt->glofcn[i]; /* FCN+8 */ - } - /* scan input files */ - if (!scan_file(epath,nf,opt,str,mask)) { - for (i=0;its.time?opt->ts:str->tstart, - staname,"")<0) { - showmsg("no time for output path: %s",ofile[i]); - for (i=0;inav)) { - for (i=0;itime=str->tstart; - - // Reinitialize the input state. Don't want decoding state from the - // end of the scanning pass to affect the start of the next pass. - if (str->format == STRFMT_RTCM2 || str->format == STRFMT_RTCM3) { - free_rtcm(&str->rtcm); - if (!init_rtcm(&str->rtcm)) { - showmsg("init rtcm error"); - for (int i = 0; i < MAXEXFILE; i++) free(epath[i]); - free_strfile(str); - return 0; - } - strcpy(str->rtcm.opt, opt->rcvopt); - } else if (str->format <= MAXRCVFMT) { - free_raw(&str->raw); - if (!init_raw(&str->raw, str->format)) { - showmsg("reinit raw error"); - for (int i = 0; i < MAXEXFILE; i++) free(epath[i]); - free_strfile(str); - return 0; - } - strcpy(str->raw.opt, opt->rcvopt); - } else if (format == STRFMT_RINEX) { - free_rnxctr(&str->rnx); - if (!init_rnxctr(&str->rnx)) { - showmsg("reinit rnx error"); - for (int i = 0; i < MAXEXFILE; i++) free(epath[i]); - free_strfile(str); - return 0; - } - strcpy(str->rnx.opt, opt->rcvopt); - } +static int convrnx_s(int sess, int format, rnxopt_t *opt, const char *file, char **ofile) { + FILE *ofp[NOUTFILE] = {NULL}; + strfile_t *str; + gtime_t tend[3] = {{0}}; + int i, j, nf, type, n[NOUTFILE + 2] = {0}, mask[MAXEXFILE] = {0}, staid = -1, abort = 0; + char path[1024], *paths[NOUTFILE], s[NOUTFILE][1024]; + char *epath[MAXEXFILE] = {0}, *staname = *opt->staid ? opt->staid : "0000"; - // Don't want saved slips from the scanning pass to be flagged at - // the start of the next pass. But do want to retain the halfc data. - for (int i = 0; i < MAXSAT; i++) { - for (int j = 0; j < NFREQ + NEXOBS; j++) { - str->slips[i][j] = 0; - } - } + trace(3, + "convrnx_s: sess=%d format=%d file=%s ofile=%s %s %s %s %s %s %s " + "%s %s\n", + sess, format, file, ofile[0], ofile[1], ofile[2], ofile[3], ofile[4], ofile[5], ofile[6], + ofile[7], ofile[8]); - for (i=0;i=-1;j++) { - - if (!(j%11)&&(abort=showstat(sess,str->time,str->time,n))) break; - if (opt->te.time&&timediff(str->time,opt->te)>-opt->ttol) break; - - /* convert message */ - switch (type) { - case 1: convobs(ofp,opt,str,n,tend,&staid); break; - case 2: convnav(ofp,opt,str,n); break; - case 3: convsbs(ofp,opt,str,n,tend+1); break; - case -1: n[NOUTFILE]++; break; /* error */ - } - /* set approx position in rinex option */ - if (type==1&&!opt->autopos&&norm(opt->apppos,3)<=0.0) { - setopt_apppos(str,opt); - } - } - /* close stream file */ - close_strfile(str); - } - /* close output files */ - closefile(ofp,opt,str->nav); - - /* remove empty output files */ - for (i=0;itstart,opt->tend,n); - - /* unset RINEX options comments */ - unsetopt_file(opt); - + /* replace keywords in input file */ + if (reppath(file, path, opt->ts, staname, "") < 0) { + showmsg("no time for input file: %s", file); + return 0; + } + /* expand wild-cards in input file */ + for (i = 0; i < MAXEXFILE; i++) { + if (!(epath[i] = (char *)malloc(1024))) { + for (i = 0; i < MAXEXFILE; i++) free(epath[i]); + return 0; + } + } + if ((nf = expath(path, epath, MAXEXFILE)) <= 0) { + showmsg("no input file: %s", path); + return 0; + } + if (!(str = gen_strfile(format, opt->rcvopt))) { + for (i = 0; i < MAXEXFILE; i++) free(epath[i]); + return 0; + } + if (format == STRFMT_RTCM2 || format == STRFMT_RTCM3 || format == STRFMT_RT17) { + str->time = opt->trtcm; + } else if (opt->ts.time) { + str->time = timeadd(opt->ts, -1.0); + } + /* set GLONASS FCN in RINEX options */ + for (i = 0; i < MAXPRNGLO; i++) { + str->nav->glo_fcn[i] = opt->glofcn[i]; /* FCN+8 */ + } + /* scan input files */ + if (!scan_file(epath, nf, opt, str, mask)) { + for (i = 0; i < MAXEXFILE; i++) free(epath[i]); + free_strfile(str); + return 0; + } + /* set format and file in RINEX options comments */ + setopt_file(format, epath, nf, mask, opt); + + /* replace keywords in output file */ + for (i = 0; i < NOUTFILE; i++) { + paths[i] = s[i]; + if (reppath(ofile[i], paths[i], opt->ts.time ? opt->ts : str->tstart, staname, "") < 0) { + showmsg("no time for output path: %s", ofile[i]); + for (i = 0; i < MAXEXFILE; i++) free(epath[i]); + free_strfile(str); + return 0; + } + } + /* open output files */ + if (!openfile(ofp, paths, path, opt, str->nav)) { + for (i = 0; i < MAXEXFILE; i++) free(epath[i]); free_strfile(str); - for (i=0;itime = str->tstart; + + // Reinitialize the input state. Don't want decoding state from the + // end of the scanning pass to affect the start of the next pass. + if (str->format == STRFMT_RTCM2 || str->format == STRFMT_RTCM3) { + free_rtcm(&str->rtcm); + if (!init_rtcm(&str->rtcm)) { + showmsg("init rtcm error"); + for (int i = 0; i < MAXEXFILE; i++) free(epath[i]); + free_strfile(str); + return 0; + } + strcpy(str->rtcm.opt, opt->rcvopt); + } else if (str->format <= MAXRCVFMT) { + free_raw(&str->raw); + if (!init_raw(&str->raw, str->format)) { + showmsg("reinit raw error"); + for (int i = 0; i < MAXEXFILE; i++) free(epath[i]); + free_strfile(str); + return 0; + } + strcpy(str->raw.opt, opt->rcvopt); + } else if (format == STRFMT_RINEX) { + free_rnxctr(&str->rnx); + if (!init_rnxctr(&str->rnx)) { + showmsg("reinit rnx error"); + for (int i = 0; i < MAXEXFILE; i++) free(epath[i]); + free_strfile(str); + return 0; + } + strcpy(str->rnx.opt, opt->rcvopt); + } + + // Don't want saved slips from the scanning pass to be flagged at + // the start of the next pass. But do want to retain the halfc data. + for (int i = 0; i < MAXSAT; i++) { + for (int j = 0; j < NFREQ + NEXOBS; j++) { + str->slips[i][j] = 0; + } + } + + for (i = 0; i < nf && !abort; i++) { + if (!mask[i]) continue; + + /* open stream file */ + if (!open_strfile(str, epath[i])) continue; + + /* input message */ + for (j = 0; (type = input_strfile(str)) >= -1; j++) { + if (!(j % 11) && (abort = showstat(sess, str->time, str->time, n))) break; + if (opt->te.time && timediff(str->time, opt->te) > -opt->ttol) break; + + /* convert message */ + switch (type) { + case 1: + convobs(ofp, opt, str, n, tend, &staid); + break; + case 2: + convnav(ofp, opt, str, n); + break; + case 3: + convsbs(ofp, opt, str, n, tend + 1); + break; + case -1: + n[NOUTFILE]++; + break; /* error */ + } + /* set approx position in rinex option */ + if (type == 1 && !opt->autopos && norm(opt->apppos, 3) <= 0.0) { + setopt_apppos(str, opt); + } + } + /* close stream file */ + close_strfile(str); + } + /* close output files */ + closefile(ofp, opt, str->nav); + + /* remove empty output files */ + for (i = 0; i < NOUTFILE; i++) { + if (ofp[i] && n[i] <= 0) remove(ofile[i]); + } + showstat(sess, opt->tstart, opt->tend, n); + + /* unset RINEX options comments */ + unsetopt_file(opt); + + free_strfile(str); + for (i = 0; i < MAXEXFILE; i++) free(epath[i]); + + return abort ? -1 : 1; } /* RINEX converter ------------------------------------------------------------- -* convert receiver log file to RINEX obs/nav, SBAS log files -* args : int format I receiver raw format (STRFMT_???) -* rnxopt_t *opt IO RINEX options (see below) -* char *file I RTCM, receiver raw or RINEX file -* (wild-cards (*) are expanded) -* char **ofile IO output files -* ofile[0] RINEX OBS file ("": no output) -* ofile[1] RINEX NAV file ("": no output) -* ofile[2] RINEX GNAV file ("": no output) -* ofile[3] RINEX HNAV file ("": no output) -* ofile[4] RINEX QNAV file ("": no output) -* ofile[5] RINEX LNAV file ("": no output) -* ofile[6] RINEX CNAV file ("": no output) -* ofile[7] RINEX INAV file ("": no output) -* ofile[8] SBAS log file ("": no output) -* return : status (1:ok,0:error,-1:abort) -* notes : the following members of opt are replaced by information in last -* converted RINEX: opt->tstart, opt->tend, opt->obstype, opt->nobs -* keywords in ofile[] are replaced by first observation date/time and -* station ID (%r) -* the order of wild-card expanded files must be in-order by time -*-----------------------------------------------------------------------------*/ -extern int convrnx(int format, rnxopt_t *opt, const char *file, char **ofile) -{ - gtime_t t0={0}; - rnxopt_t opt_=*opt; - double tu,ts; - int i,week,stat=1,sys_GRS=SYS_GPS|SYS_GLO|SYS_SBS; - - trace(3,"convrnx: format=%d file=%s ofile=%s %s %s %s %s %s %s %s %s\n", - format,file,ofile[0],ofile[1],ofile[2],ofile[3],ofile[4],ofile[5], - ofile[6],ofile[7],ofile[8]); - - showmsg(""); - - /* disable systems according to RINEX version */ - if (opt->rnxver<=210) opt_.navsys&=sys_GRS; - else if (opt->rnxver<=211) opt_.navsys&=sys_GRS|SYS_GAL; - else if (opt->rnxver<=212) opt_.navsys&=sys_GRS|SYS_GAL|SYS_CMP; - else if (opt->rnxver<=300) opt_.navsys&=sys_GRS|SYS_GAL; - else if (opt->rnxver<=301) opt_.navsys&=sys_GRS|SYS_GAL|SYS_CMP; - else if (opt->rnxver<=302) opt_.navsys&=sys_GRS|SYS_GAL|SYS_CMP|SYS_QZS; - - /* disable frequency according to RINEX version */ - if (opt->rnxver<=210) opt_.freqtype&=0x3; - - if (opt->ts.time==0||opt->te.time==0||opt->tunit<=0.0) { - - /* single session */ - opt_.tstart=opt_.tend=t0; - stat=convrnx_s(0,format,&opt_,file,ofile); - } - else if (timediff(opt->ts,opt->te)<0.0) { - - /* multiple session */ - tu=opt->tunit<86400.0?opt->tunit:86400.0; - ts=tu*(int)floor(time2gpst(opt->ts,&week)/tu); - - for (i=0;;i++) { /* for each session */ - opt_.ts=gpst2time(week,ts+i*tu); - opt_.te=timeadd(opt_.ts,tu); - if (opt->trtcm.time) { - opt_.trtcm=timeadd(opt->trtcm,timediff(opt_.ts,opt->ts)); - } - if (timediff(opt_.ts,opt->te)>-opt->ttol) break; - - if (timediff(opt_.ts,opt->ts)<0.0) opt_.ts=opt->ts; - if (timediff(opt_.te,opt->te)>0.0) opt_.te=opt->te; - opt_.tstart=opt_.tend=t0; - if ((stat=convrnx_s(i+1,format,&opt_,file,ofile))<0) break; - } - } - else { - showmsg("no period"); - return 0; - } - /* output start and end time */ - opt->tstart=opt_.tstart; opt->tend=opt_.tend; - - return stat; + * convert receiver log file to RINEX obs/nav, SBAS log files + * args : int format I receiver raw format (STRFMT_???) + * rnxopt_t *opt IO RINEX options (see below) + * char *file I RTCM, receiver raw or RINEX file + * (wild-cards (*) are expanded) + * char **ofile IO output files + * ofile[0] RINEX OBS file ("": no output) + * ofile[1] RINEX NAV file ("": no output) + * ofile[2] RINEX GNAV file ("": no output) + * ofile[3] RINEX HNAV file ("": no output) + * ofile[4] RINEX QNAV file ("": no output) + * ofile[5] RINEX LNAV file ("": no output) + * ofile[6] RINEX CNAV file ("": no output) + * ofile[7] RINEX INAV file ("": no output) + * ofile[8] SBAS log file ("": no output) + * return : status (1:ok,0:error,-1:abort) + * notes : the following members of opt are replaced by information in last + * converted RINEX: opt->tstart, opt->tend, opt->obstype, opt->nobs + * keywords in ofile[] are replaced by first observation date/time and + * station ID (%r) + * the order of wild-card expanded files must be in-order by time + *-----------------------------------------------------------------------------*/ +extern int convrnx(int format, rnxopt_t *opt, const char *file, char **ofile) { + gtime_t t0 = {0}; + rnxopt_t opt_ = *opt; + double tu, ts; + int i, week, stat = 1, sys_GRS = SYS_GPS | SYS_GLO | SYS_SBS; + + trace(3, "convrnx: format=%d file=%s ofile=%s %s %s %s %s %s %s %s %s\n", format, file, ofile[0], + ofile[1], ofile[2], ofile[3], ofile[4], ofile[5], ofile[6], ofile[7], ofile[8]); + + showmsg(""); + + /* disable systems according to RINEX version */ + if (opt->rnxver <= 210) + opt_.navsys &= sys_GRS; + else if (opt->rnxver <= 211) + opt_.navsys &= sys_GRS | SYS_GAL; + else if (opt->rnxver <= 212) + opt_.navsys &= sys_GRS | SYS_GAL | SYS_CMP; + else if (opt->rnxver <= 300) + opt_.navsys &= sys_GRS | SYS_GAL; + else if (opt->rnxver <= 301) + opt_.navsys &= sys_GRS | SYS_GAL | SYS_CMP; + else if (opt->rnxver <= 302) + opt_.navsys &= sys_GRS | SYS_GAL | SYS_CMP | SYS_QZS; + + /* disable frequency according to RINEX version */ + if (opt->rnxver <= 210) opt_.freqtype &= 0x3; + + if (opt->ts.time == 0 || opt->te.time == 0 || opt->tunit <= 0.0) { + /* single session */ + opt_.tstart = opt_.tend = t0; + stat = convrnx_s(0, format, &opt_, file, ofile); + } else if (timediff(opt->ts, opt->te) < 0.0) { + /* multiple session */ + tu = opt->tunit < 86400.0 ? opt->tunit : 86400.0; + ts = tu * (int)floor(time2gpst(opt->ts, &week) / tu); + + for (i = 0;; i++) { /* for each session */ + opt_.ts = gpst2time(week, ts + i * tu); + opt_.te = timeadd(opt_.ts, tu); + if (opt->trtcm.time) { + opt_.trtcm = timeadd(opt->trtcm, timediff(opt_.ts, opt->ts)); + } + if (timediff(opt_.ts, opt->te) > -opt->ttol) break; + + if (timediff(opt_.ts, opt->ts) < 0.0) opt_.ts = opt->ts; + if (timediff(opt_.te, opt->te) > 0.0) opt_.te = opt->te; + opt_.tstart = opt_.tend = t0; + if ((stat = convrnx_s(i + 1, format, &opt_, file, ofile)) < 0) break; + } + } else { + showmsg("no period"); + return 0; + } + /* output start and end time */ + opt->tstart = opt_.tstart; + opt->tend = opt_.tend; + + return stat; } diff --git a/src/datum.c b/src/datum.c index 85bb108f3..c8a364bc1 100644 --- a/src/datum.c +++ b/src/datum.c @@ -1,131 +1,139 @@ /*------------------------------------------------------------------------------ -* datum.c : datum transformation -* -* Copyright (C) 2007 by T.TAKASU, All rights reserved. -* -* version : $Revision: 1.1 $ $Date: 2008/07/17 21:48:06 $ -* history : 2007/02/08 1.0 new -*-----------------------------------------------------------------------------*/ + * datum.c : datum transformation + * + * Copyright (C) 2007 by T.TAKASU, All rights reserved. + * + * version : $Revision: 1.1 $ $Date: 2008/07/17 21:48:06 $ + * history : 2007/02/08 1.0 new + *-----------------------------------------------------------------------------*/ #include "rtklib.h" -#define MAXPRM 400000 /* max number of parameter records */ +#define MAXPRM 400000 /* max number of parameter records */ -typedef struct { /* datum trans parameter type */ - int code; /* mesh code */ - float db,dl; /* difference of latitude/longitude (sec) */ +typedef struct { /* datum trans parameter type */ + int code; /* mesh code */ + float db, dl; /* difference of latitude/longitude (sec) */ } tprm_t; -static tprm_t *prm=NULL; /* datum trans parameter table */ -static int n=0; /* datum trans parameter table size */ +static tprm_t *prm = NULL; /* datum trans parameter table */ +static int n = 0; /* datum trans parameter table size */ /* compare datum trans parameters --------------------------------------------*/ -static int cmpprm(const void *p1, const void *p2) -{ - tprm_t *q1=(tprm_t *)p1,*q2=(tprm_t *)p2; - return q1->code-q2->code; +static int cmpprm(const void *p1, const void *p2) { + tprm_t *q1 = (tprm_t *)p1, *q2 = (tprm_t *)p2; + return q1->code - q2->code; } /* search datum trans parameter ----------------------------------------------*/ -static int searchprm(double lat, double lon) -{ - int i,j,k,n1,m1,n2,m2,code; - - lon-=6000.0; - n1=(int)(lat/40.0); lat-=n1*40.0; - m1=(int)(lon/60.0); lon-=m1*60.0; - n2=(int)(lat/5.0); lat-=n2*5.0; - m2=(int)(lon/7.5); lon-=m2*7.5; - code=n1*1000000+m1*10000+n2*1000+m2*100+(int)(lat/0.5)*10+(int)(lon/0.75); - - for (i=0,j=n-1;i:error) -* notes : parameters file shall comply with GSI TKY2JGD.par -*-----------------------------------------------------------------------------*/ -extern int loaddatump(const char *file) -{ - FILE *fp; - char buff[256]; - - if (n>0) return 0; /* already loaded */ - - if (!(fp=fopen(file,"r"))) { - fprintf(stderr,"%s : datum prm file open error : %s\n",__FILE__,file); - return -1; - } - if (!(prm=(tprm_t *)malloc(sizeof(tprm_t)*MAXPRM))) { - fclose(fp); - fprintf(stderr,"%s : memory allocation error\n",__FILE__); - return -1; - } - while (fgets(buff,sizeof(buff),fp)&&n=3) n++; - } + * load datum transformation parameter + * args : char *file I datum trans parameter file path + * return : status (0:ok,0>:error) + * notes : parameters file shall comply with GSI TKY2JGD.par + *-----------------------------------------------------------------------------*/ +extern int loaddatump(const char *file) { + FILE *fp; + char buff[256]; + + if (n > 0) return 0; /* already loaded */ + + if (!(fp = fopen(file, "r"))) { + fprintf(stderr, "%s : datum prm file open error : %s\n", __FILE__, file); + return -1; + } + if (!(prm = (tprm_t *)malloc(sizeof(tprm_t) * MAXPRM))) { fclose(fp); - qsort(prm,n,sizeof(tprm_t),cmpprm); /* sort parameter table */ - return 0; + fprintf(stderr, "%s : memory allocation error\n", __FILE__); + return -1; + } + while (fgets(buff, sizeof(buff), fp) && n < MAXPRM) { + if (sscanf(buff, "%d %f %f", &prm[n].code, &prm[n].db, &prm[n].dl) >= 3) n++; + } + fclose(fp); + qsort(prm, n, sizeof(tprm_t), cmpprm); /* sort parameter table */ + return 0; } /* tokyo datum to JGD2000 datum ------------------------------------------------ -* transform position in Tokyo datum to JGD2000 datum -* args : double *pos I position in Tokyo datum {lat,lon,h} (rad,m) -* O position in JGD2000 datum {lat,lon,h} (rad,m) -* return : status (0:ok,0>:error,out of range) -* notes : before calling, call loaddatump() to set parameter table -*-----------------------------------------------------------------------------*/ -extern int tokyo2jgd(double *pos) -{ - double post[2],dpos[2]; - - post[0]=pos[0]; - post[1]=pos[1]; - if (dlatdlon(post,dpos)) return -1; - pos[0]=post[0]+dpos[0]; - pos[1]=post[1]+dpos[1]; - return 0; + * transform position in Tokyo datum to JGD2000 datum + * args : double *pos I position in Tokyo datum {lat,lon,h} (rad,m) + * O position in JGD2000 datum {lat,lon,h} (rad,m) + * return : status (0:ok,0>:error,out of range) + * notes : before calling, call loaddatump() to set parameter table + *-----------------------------------------------------------------------------*/ +extern int tokyo2jgd(double *pos) { + double post[2], dpos[2]; + + post[0] = pos[0]; + post[1] = pos[1]; + if (dlatdlon(post, dpos)) return -1; + pos[0] = post[0] + dpos[0]; + pos[1] = post[1] + dpos[1]; + return 0; } /* JGD2000 datum to Tokyo datum ------------------------------------------------ -* transform position in JGD2000 datum to Tokyo datum -* args : double *pos I position in JGD2000 datum {lat,lon,h} (rad,m) -* O position in Tokyo datum {lat,lon,h} (rad,m) -* return : status (0:ok,0>:error,out of range) -* notes : before calling, call loaddatump() to set parameter table -*-----------------------------------------------------------------------------*/ -extern int jgd2tokyo(double *pos) -{ - double posj[2],dpos[2]; - int i; - - posj[0]=pos[0]; - posj[1]=pos[1]; - for (i=0;i<2;i++) { - if (dlatdlon(pos,dpos)) return -1; - pos[0]=posj[0]-dpos[0]; - pos[1]=posj[1]-dpos[1]; - } - return 0; + * transform position in JGD2000 datum to Tokyo datum + * args : double *pos I position in JGD2000 datum {lat,lon,h} (rad,m) + * O position in Tokyo datum {lat,lon,h} (rad,m) + * return : status (0:ok,0>:error,out of range) + * notes : before calling, call loaddatump() to set parameter table + *-----------------------------------------------------------------------------*/ +extern int jgd2tokyo(double *pos) { + double posj[2], dpos[2]; + int i; + + posj[0] = pos[0]; + posj[1] = pos[1]; + for (i = 0; i < 2; i++) { + if (dlatdlon(pos, dpos)) return -1; + pos[0] = posj[0] - dpos[0]; + pos[1] = posj[1] - dpos[1]; + } + return 0; } diff --git a/src/download.c b/src/download.c index 15c6bd336..41cb98970 100644 --- a/src/download.c +++ b/src/download.c @@ -1,19 +1,19 @@ /*------------------------------------------------------------------------------ -* download.c : gnss data downloader -* -* Copyright (C) 2012-2020 by T.TAKASU, All rights reserved. -* -* version : $Revision:$ $Date:$ -* history : 2012/12/28 1.0 new -* 2013/06/02 1.1 replace S_IREAD by S_IRUSR -* 2020/11/30 1.2 support protocol https:// and ftps:// -* support compressed RINEX (CRX) files -* support wild-card (*) in URL for FTP and FTPS -* use "=" to separate file name from URL -* fix bug on double-free of download paths -* limit max number of download paths -* use integer types in stdint.h -*-----------------------------------------------------------------------------*/ + * download.c : gnss data downloader + * + * Copyright (C) 2012-2020 by T.TAKASU, All rights reserved. + * + * version : $Revision:$ $Date:$ + * history : 2012/12/28 1.0 new + * 2013/06/02 1.1 replace S_IREAD by S_IRUSR + * 2020/11/30 1.2 support protocol https:// and ftps:// + * support compressed RINEX (CRX) files + * support wild-card (*) in URL for FTP and FTPS + * use "=" to separate file name from URL + * fix bug on double-free of download paths + * limit max number of download paths + * use integer types in stdint.h + *-----------------------------------------------------------------------------*/ #define _POSIX_C_SOURCE 199506 #include #include @@ -21,889 +21,881 @@ #include "rtklib.h" -#define FTP_CMD "wget" /* FTP/HTTP command */ -#define FTP_TIMEOUT 60 /* FTP/HTTP timeout (s) */ -#define FTP_LISTING ".listing" /* FTP listing file */ -#define FTP_NOFILE 2048 /* FTP error no file */ -#define HTTP_NOFILE 1 /* HTTP error no file */ -#define FTP_RETRY 3 /* FTP number of retry */ -#define MAX_PATHS 131072 /* max number of download paths */ +#define FTP_CMD "wget" /* FTP/HTTP command */ +#define FTP_TIMEOUT 60 /* FTP/HTTP timeout (s) */ +#define FTP_LISTING ".listing" /* FTP listing file */ +#define FTP_NOFILE 2048 /* FTP error no file */ +#define HTTP_NOFILE 1 /* HTTP error no file */ +#define FTP_RETRY 3 /* FTP number of retry */ +#define MAX_PATHS 131072 /* max number of download paths */ /* type definitions ----------------------------------------------------------*/ -typedef struct { /* download path type */ - char *remot; /* remote path */ - char *local; /* local path */ +typedef struct { /* download path type */ + char *remot; /* remote path */ + char *local; /* local path */ } path_t; -typedef struct { /* download paths type */ - path_t *path; /* download paths */ - int n,nmax; /* number and max number of paths */ +typedef struct { /* download paths type */ + path_t *path; /* download paths */ + int n, nmax; /* number and max number of paths */ } paths_t; /* execute command with test timeout -----------------------------------------*/ -extern int execcmd_to(const char *cmd) -{ +extern int execcmd_to(const char *cmd) { #ifdef WIN32 - PROCESS_INFORMATION info; - STARTUPINFO si={0}; - DWORD stat; - char cmds[4096]; - - si.cb=sizeof(si); - sprintf(cmds,"cmd /c %s",cmd); - if (!CreateProcess(NULL,(LPTSTR)cmds,NULL,NULL,FALSE,CREATE_NO_WINDOW,NULL, - NULL,&si,&info)) return -1; - - while (WaitForSingleObject(info.hProcess,10)==WAIT_TIMEOUT) { - showmsg(""); - } - if (!GetExitCodeProcess(info.hProcess,&stat)) stat=-1; - CloseHandle(info.hProcess); - CloseHandle(info.hThread); - return (int)stat; + PROCESS_INFORMATION info; + STARTUPINFO si = {0}; + DWORD stat; + char cmds[4096]; + + si.cb = sizeof(si); + sprintf(cmds, "cmd /c %s", cmd); + if (!CreateProcess(NULL, (LPTSTR)cmds, NULL, NULL, FALSE, CREATE_NO_WINDOW, NULL, NULL, &si, + &info)) + return -1; + + while (WaitForSingleObject(info.hProcess, 10) == WAIT_TIMEOUT) { + showmsg(""); + } + if (!GetExitCodeProcess(info.hProcess, &stat)) stat = -1; + CloseHandle(info.hProcess); + CloseHandle(info.hThread); + return (int)stat; #else - return system(cmd); + return system(cmd); #endif } /* generate path by replacing keywords ---------------------------------------*/ -static void genpath(const char *file, const char *name, gtime_t time, int seqno, - char *path) -{ - char buff[1024],*p,*q,*r,*env,var[1024]=""; - char l_name[1024]="",u_name[1024]=""; - - for (p=l_name,q=(char *)name;(*p=(char)tolower(*q));p++,q++) ; - for (p=u_name,q=(char *)name;(*p=(char)toupper(*q));p++,q++) ; - - for (p=buff,q=(char *)file;(*p=*q);p++,q++) { - if (*q=='%') q++; else continue; - if (*q=='s'||*q=='r') p+=sprintf(p,"%s",l_name)-1; - else if (*q=='S'||*q=='R') p+=sprintf(p,"%s",u_name)-1; - else if (*q=='N') p+=sprintf(p,"%d",seqno)-1; - else if (*q=='{'&&(r=strchr(q+1,'}'))) { - strncpy(var,q+1,r-q-1); - var[r-q-1]='\0'; - if ((env=getenv(var))) p+=sprintf(p,"%s",env)-1; - q=r; - } - else q--; - } - reppath(buff,path,time,"",""); +static void genpath(const char *file, const char *name, gtime_t time, int seqno, char *path) { + char buff[1024], *p, *q, *r, *env, var[1024] = ""; + char l_name[1024] = "", u_name[1024] = ""; + + for (p = l_name, q = (char *)name; (*p = (char)tolower(*q)); p++, q++); + for (p = u_name, q = (char *)name; (*p = (char)toupper(*q)); p++, q++); + + for (p = buff, q = (char *)file; (*p = *q); p++, q++) { + if (*q == '%') + q++; + else + continue; + if (*q == 's' || *q == 'r') + p += sprintf(p, "%s", l_name) - 1; + else if (*q == 'S' || *q == 'R') + p += sprintf(p, "%s", u_name) - 1; + else if (*q == 'N') + p += sprintf(p, "%d", seqno) - 1; + else if (*q == '{' && (r = strchr(q + 1, '}'))) { + strncpy(var, q + 1, r - q - 1); + var[r - q - 1] = '\0'; + if ((env = getenv(var))) p += sprintf(p, "%s", env) - 1; + q = r; + } else + q--; + } + reppath(buff, path, time, "", ""); } /* parse field strings separated by spaces -----------------------------------*/ -static char *parse_str(char *buff, char *str, int nmax) -{ - char *p,*q,sep[]=" \r\n"; - - for (p=buff;*p==' ';p++) ; - - if (*p=='"') sep[0]=*p++; /* enclosed within quotation marks */ - - for (q=str;*p&&!strchr(sep,*p);p++) { - if (qn;i++) { - free(paths->path[i].remot); - free(paths->path[i].local); - } - free(paths->path); +static void free_path(paths_t *paths) { + int i; + if (!paths) return; + for (i = 0; i < paths->n; i++) { + free(paths->path[i].remot); + free(paths->path[i].local); + } + free(paths->path); } /* add download paths --------------------------------------------------------*/ -static int add_path(paths_t *paths, const char *remot, const char *dir) -{ - path_t *paths_path; - char local[1024]; - - if (paths->n>=paths->nmax) { - if ((paths->nmax=paths->nmax<=0?1024:paths->nmax*2)>MAX_PATHS) { - return 0; - } - paths_path=(path_t *)realloc(paths->path,sizeof(path_t)*paths->nmax); - if (!paths_path) { - return 0; - } - paths->path=paths_path; +static int add_path(paths_t *paths, const char *remot, const char *dir) { + path_t *paths_path; + char local[1024]; + + if (paths->n >= paths->nmax) { + if ((paths->nmax = paths->nmax <= 0 ? 1024 : paths->nmax * 2) > MAX_PATHS) { + return 0; } - remot2local(remot,dir,local); - - paths->path[paths->n].remot=paths->path[paths->n].local=NULL; - - if (!(paths->path[paths->n].remot=(char *)malloc(strlen(remot)+1))|| - !(paths->path[paths->n].local=(char *)malloc(strlen(local)+1))) { - return 0; + paths_path = (path_t *)realloc(paths->path, sizeof(path_t) * paths->nmax); + if (!paths_path) { + return 0; } - strcpy(paths->path[paths->n].remot,remot); - strcpy(paths->path[paths->n].local,local); - paths->n++; - return 1; + paths->path = paths_path; + } + remot2local(remot, dir, local); + + paths->path[paths->n].remot = paths->path[paths->n].local = NULL; + + if (!(paths->path[paths->n].remot = (char *)malloc(strlen(remot) + 1)) || + !(paths->path[paths->n].local = (char *)malloc(strlen(local) + 1))) { + return 0; + } + strcpy(paths->path[paths->n].remot, remot); + strcpy(paths->path[paths->n].local, local); + paths->n++; + return 1; } /* generate download path ----------------------------------------------------*/ -static int gen_path(gtime_t time, gtime_t time_p, int seqnos, int seqnoe, - const url_t *url, const char *sta, const char *dir, - paths_t *paths) -{ - char remot[1024],remot_p[1024],dir_t[1024]; - int i; - - if (!*dir) dir=url->dir; - if (!*dir) dir="."; - - if (strstr(url->path,"%N")) { - for (i=seqnos;i<=seqnoe;i++) { - genpath(url->path,sta,time,i,remot); - genpath(dir ,sta,time,i,dir_t); - if (time_p.time) { - genpath(url->path,sta,time_p,i,remot_p); - if (!strcmp(remot_p,remot)) continue; - } - if (!add_path(paths,remot,dir_t)) return 0; - } - } - else { - genpath(url->path,sta,time,0,remot); - genpath(dir ,sta,time,0,dir_t); - if (time_p.time) { - genpath(url->path,sta,time_p,0,remot_p); - if (!strcmp(remot_p,remot)) return 1; - } - if (!add_path(paths,remot,dir_t)) return 0; - } - return 1; +static int gen_path(gtime_t time, gtime_t time_p, int seqnos, int seqnoe, const url_t *url, + const char *sta, const char *dir, paths_t *paths) { + char remot[1024], remot_p[1024], dir_t[1024]; + int i; + + if (!*dir) dir = url->dir; + if (!*dir) dir = "."; + + if (strstr(url->path, "%N")) { + for (i = seqnos; i <= seqnoe; i++) { + genpath(url->path, sta, time, i, remot); + genpath(dir, sta, time, i, dir_t); + if (time_p.time) { + genpath(url->path, sta, time_p, i, remot_p); + if (!strcmp(remot_p, remot)) continue; + } + if (!add_path(paths, remot, dir_t)) return 0; + } + } else { + genpath(url->path, sta, time, 0, remot); + genpath(dir, sta, time, 0, dir_t); + if (time_p.time) { + genpath(url->path, sta, time_p, 0, remot_p); + if (!strcmp(remot_p, remot)) return 1; + } + if (!add_path(paths, remot, dir_t)) return 0; + } + return 1; } /* generate download paths ---------------------------------------------------*/ -static int gen_paths(gtime_t time, gtime_t time_p, int seqnos, int seqnoe, - const url_t *url, const char **stas, int nsta, const char *dir, - paths_t *paths) -{ - int i; - - if (strstr(url->path,"%s")||strstr(url->path,"%S")) { - for (i=0;ipath, "%s") || strstr(url->path, "%S")) { + for (i = 0; i < nsta; i++) { + if (!gen_path(time, time_p, seqnos, seqnoe, url, stas[i], dir, paths)) { + return 0; + } } - else { - if (!gen_path(time,time_p,seqnos,seqnoe,url,"",dir,paths)) { - return 0; - } + } else { + if (!gen_path(time, time_p, seqnos, seqnoe, url, "", dir, paths)) { + return 0; } - return 1; + } + return 1; } /* compact download paths ----------------------------------------------------*/ -static void compact_paths(paths_t *paths) -{ - int i,j,k; - - for (i=0;in;i++) { - for (j=i+1;jn;j++) { - if (strcmp(paths->path[i].remot,paths->path[j].remot)) continue; - free(paths->path[j].remot); - free(paths->path[j].local); - for (k=j;kn-1;k++) paths->path[k]=paths->path[k+1]; - paths->n--; j--; - } - } +static void compact_paths(paths_t *paths) { + int i, j, k; + + for (i = 0; i < paths->n; i++) { + for (j = i + 1; j < paths->n; j++) { + if (strcmp(paths->path[i].remot, paths->path[j].remot)) continue; + free(paths->path[j].remot); + free(paths->path[j].local); + for (k = j; k < paths->n - 1; k++) paths->path[k] = paths->path[k + 1]; + paths->n--; + j--; + } + } } /* generate local directory recursively --------------------------------------*/ -static int mkdir_r(const char *dir) -{ - char pdir[1024],*p; - +static int mkdir_r(const char *dir) { + char pdir[1024], *p; + #ifdef WIN32 - HANDLE h; - WIN32_FIND_DATA data; - - if (!*dir||!strcmp(dir+1,":\\")) return 1; - - strcpy(pdir,dir); - if ((p=strrchr(pdir,RTKLIB_FILEPATHSEP))) { - *p='\0'; - h=FindFirstFile(pdir,&data); - if (h==INVALID_HANDLE_VALUE) { - if (!mkdir_r(pdir)) return 0; - } - else FindClose(h); - } - if (CreateDirectory(dir,NULL)|| - GetLastError()==ERROR_ALREADY_EXISTS) return 1; - - trace(2,"directory generation error: dir=%s\n",dir); - return 0; + HANDLE h; + WIN32_FIND_DATA data; + + if (!*dir || !strcmp(dir + 1, ":\\")) return 1; + + strcpy(pdir, dir); + if ((p = strrchr(pdir, RTKLIB_FILEPATHSEP))) { + *p = '\0'; + h = FindFirstFile(pdir, &data); + if (h == INVALID_HANDLE_VALUE) { + if (!mkdir_r(pdir)) return 0; + } else + FindClose(h); + } + if (CreateDirectory(dir, NULL) || GetLastError() == ERROR_ALREADY_EXISTS) return 1; + + trace(2, "directory generation error: dir=%s\n", dir); + return 0; #else - FILE *fp; - - if (!*dir) return 1; - - strcpy(pdir,dir); - if ((p=strrchr(pdir,RTKLIB_FILEPATHSEP))) { - *p='\0'; - if (!(fp=fopen(pdir,"r"))) { - if (!mkdir_r(pdir)) return 0; - } - else fclose(fp); - } - if (!mkdir(dir,0777)||errno==EEXIST) return 1; - - trace(2,"directory generation error: dir=%s\n",dir); - return 0; + FILE *fp; + + if (!*dir) return 1; + + strcpy(pdir, dir); + if ((p = strrchr(pdir, RTKLIB_FILEPATHSEP))) { + *p = '\0'; + if (!(fp = fopen(pdir, "r"))) { + if (!mkdir_r(pdir)) return 0; + } else + fclose(fp); + } + if (!mkdir(dir, 0777) || errno == EEXIST) return 1; + + trace(2, "directory generation error: dir=%s\n", dir); + return 0; #endif } /* get remote file list for FTP or FTPS --------------------------------------*/ -static int get_list(const path_t *path, const char *usr, const char *pwd, - const char *proxy) -{ - FILE *fp; - char cmd[4096],env[1024]="",remot[1024],*opt="",*opt2="",*p; - +static int get_list(const path_t *path, const char *usr, const char *pwd, const char *proxy) { + FILE *fp; + char cmd[4096], env[1024] = "", remot[1024], *opt = "", *opt2 = "", *p; + #ifndef WIN32 - opt2=" -o /dev/null"; + opt2 = " -o /dev/null"; #endif - remove(FTP_LISTING); - - strcpy(remot,path->remot); - - if ((p=strrchr(remot,'/'))) strcpy(p+1,"__REQUEST_LIST__"); else return 0; - - if (*proxy) { - sprintf(env,"set ftp_proxy=http://%s & ",proxy); - opt="--proxy=on "; - } - sprintf(cmd,"%s%s %s --ftp-user=%s --ftp-password=%s --glob=off " - "--passive-ftp --no-remove-listing -N %s-t 1 -T %d%s\n", - env,FTP_CMD,remot,usr,pwd,opt,FTP_TIMEOUT,opt2); - execcmd_to(cmd); - - if (!(fp=fopen(FTP_LISTING,"r"))) return 0; - fclose(fp); - return 1; + remove(FTP_LISTING); + + strcpy(remot, path->remot); + + if ((p = strrchr(remot, '/'))) + strcpy(p + 1, "__REQUEST_LIST__"); + else + return 0; + + if (*proxy) { + sprintf(env, "set ftp_proxy=http://%s & ", proxy); + opt = "--proxy=on "; + } + sprintf(cmd, + "%s%s %s --ftp-user=%s --ftp-password=%s --glob=off " + "--passive-ftp --no-remove-listing -N %s-t 1 -T %d%s\n", + env, FTP_CMD, remot, usr, pwd, opt, FTP_TIMEOUT, opt2); + execcmd_to(cmd); + + if (!(fp = fopen(FTP_LISTING, "r"))) return 0; + fclose(fp); + return 1; } /* replace wild-card (*) in the paths ----------------------------------------*/ -static int rep_paths(path_t *path, const char *file) -{ - char buff1[1024],buff2[1024],*p,*q,*remot,*local; - - strcpy(buff1,path->remot); - strcpy(buff2,path->local); - if ((p=strrchr(buff1,'/'))) p++; else p=buff1; - if ((q=strrchr(buff2,RTKLIB_FILEPATHSEP))) q++; else q=buff2; - strcpy(p,file); - strcpy(q,file); - - if (!(remot=(char *)malloc(strlen(buff1)+1)) || - !(local=(char *)malloc(strlen(buff2)+1))) { - free(remot); - return 0; - } - strcpy(remot,buff1); - strcpy(local,buff2); - free(path->remot); - free(path->local); - path->remot=remot; - path->local=local; - return 1; +static int rep_paths(path_t *path, const char *file) { + char buff1[1024], buff2[1024], *p, *q, *remot, *local; + + strcpy(buff1, path->remot); + strcpy(buff2, path->local); + if ((p = strrchr(buff1, '/'))) + p++; + else + p = buff1; + if ((q = strrchr(buff2, RTKLIB_FILEPATHSEP))) + q++; + else + q = buff2; + strcpy(p, file); + strcpy(q, file); + + if (!(remot = (char *)malloc(strlen(buff1) + 1)) || + !(local = (char *)malloc(strlen(buff2) + 1))) { + free(remot); + return 0; + } + strcpy(remot, buff1); + strcpy(local, buff2); + free(path->remot); + free(path->local); + path->remot = remot; + path->local = local; + return 1; } /* test file in remote file list ---------------------------------------------*/ -static int test_list(path_t *path) -{ - FILE *fp; - char buff[1024],*file,*list,*p; - int i; - - if (!(fp=fopen(FTP_LISTING,"r"))) return 1; - - if ((p=strrchr(path->remot,'/'))) - file=p+1; - else { +static int test_list(path_t *path) { + FILE *fp; + char buff[1024], *file, *list, *p; + int i; + + if (!(fp = fopen(FTP_LISTING, "r"))) return 1; + + if ((p = strrchr(path->remot, '/'))) + file = p + 1; + else { + fclose(fp); + return 1; + } + + /* search file in remote file list */ + while (fgets(buff, sizeof(buff), fp)) { + /* remove symbolic link */ + if ((p = strstr(buff, "->"))) *p = '\0'; + + for (i = strlen(buff) - 1; i >= 0; i--) { + if (strchr(" \r\n", buff[i])) + buff[i] = '\0'; + else + break; + } + /* file as last field */ + if ((p = strrchr(buff, ' '))) + list = p + 1; + else + list = buff; + + if (!strcmp(file, list)) { + fclose(fp); + return 1; + } + /* compare with wild-card (*) */ + if (cmp_str(list, file)) { + /* replace wild-card (*) in the paths */ + if (!rep_paths(path, list)) { fclose(fp); - return 1; - } - - /* search file in remote file list */ - while (fgets(buff,sizeof(buff),fp)) { - - /* remove symbolic link */ - if ((p=strstr(buff,"->"))) *p='\0'; - - for (i=strlen(buff)-1;i>=0;i--) { - if (strchr(" \r\n",buff[i])) buff[i]='\0'; else break; - } - /* file as last field */ - if ((p=strrchr(buff,' '))) list=p+1; else list=buff; - - if (!strcmp(file,list)) { - fclose(fp); - return 1; - } - /* compare with wild-card (*) */ - if (cmp_str(list,file)) { - - /* replace wild-card (*) in the paths */ - if (!rep_paths(path,list)) { - fclose(fp); - return 0; - } - fclose(fp); - return 1; - } + return 0; + } + fclose(fp); + return 1; } - fclose(fp); - return 0; + } + fclose(fp); + return 0; } /* execute download ----------------------------------------------------------*/ -static int exec_down(path_t *path, char *remot_p, const char *usr, - const char *pwd, const char *proxy, int opts, int *n, - FILE *fp) -{ - char dir[1024],errfile[1024],tmpfile[1024],cmd[4096],env[1024]=""; - char opt[1024]="",*opt2="",*p; - int ret,proto; - +static int exec_down(path_t *path, char *remot_p, const char *usr, const char *pwd, + const char *proxy, int opts, int *n, FILE *fp) { + char dir[1024], errfile[1024], tmpfile[1024], cmd[4096], env[1024] = ""; + char opt[1024] = "", *opt2 = "", *p; + int ret, proto; + #ifndef WIN32 - opt2=" 2> /dev/null"; + opt2 = " 2> /dev/null"; #endif - strcpy(dir,path->local); - if ((p=strrchr(dir,RTKLIB_FILEPATHSEP))) *p='\0'; - - if (!strncmp(path->remot,"ftp://" ,6)) proto=0; - else if (!strncmp(path->remot,"ftps://" ,7)) proto=2; - else if (!strncmp(path->remot,"http://" ,7)) proto=1; - else if (!strncmp(path->remot,"https://",8)) proto=1; - else { - trace(2,"exec_down: invalid path %s\n",path->remot); - showmsg("STAT=X"); - if (fp) fprintf(fp,"%s ERROR (INVALID PATH)\n",path->remot); - n[1]++; - return 0; - } - /* test local file existence */ - if (!(opts&DLOPT_FORCE)&&test_file(path->local)) { - showmsg("STAT=."); - if (fp) fprintf(fp,"%s in %s\n",path->remot,dir); - n[2]++; - return 0; - } - showmsg("STAT=_"); - - /* get remote file list for FTP or FTPS */ - if ((proto==0||proto==2)&&(p=strrchr(path->remot,'/'))&& - strncmp(path->remot,remot_p,p-path->remot)) { - - if (get_list(path,usr,pwd,proxy)) { - strcpy(remot_p,path->remot); - } - } - /* test file in listing for FTP or FTPS or extend wild-card in file path */ - if ((proto==0||proto==2)&&!test_list(path)) { - showmsg("STAT=x"); - if (fp) fprintf(fp,"%s NO_FILE\n",path->remot); - n[1]++; - return 0; - } - /* generate local directory recursively */ - if (!mkdir_r(dir)) { - showmsg("STAT=X"); - if (fp) fprintf(fp,"%s -> %s ERROR (LOCAL DIR)\n",path->remot,dir); - n[3]++; - return 0; - } - /* re-test local file existence for file with wild-card */ - if (!(opts&DLOPT_FORCE)&&test_file(path->local)) { - showmsg("STAT=."); - if (fp) fprintf(fp,"%s in %s\n",path->remot,dir); - n[2]++; - return 0; - } - /* proxy option */ - if (*proxy) { - sprintf(env,"set %s_proxy=http://%s & ",proto==0||proto==2?"ftp":"http", - proxy); - sprintf(opt," --proxy=on "); - } - /* download command */ - sprintf(errfile,"%s.err",path->local); - if (proto==0||proto==2) { - sprintf(cmd,"%s%s %s --ftp-user=%s --ftp-password=%s --glob=off " - "--passive-ftp %s-t %d -T %d -O \"%s\" -o \"%s\"%s\n", - env,FTP_CMD,path->remot,usr,pwd,opt,FTP_RETRY,FTP_TIMEOUT, - path->local,errfile,opt2); - } - else { - if (*pwd) { - sprintf(opt+strlen(opt)," --http-user=%s --http-password=%s ",usr, - pwd); - } - sprintf(cmd,"%s%s %s %s-t %d -T %d -O \"%s\" -o \"%s\"%s\n",env,FTP_CMD, - path->remot,opt,FTP_RETRY,FTP_TIMEOUT,path->local,errfile,opt2); - } - if (fp) fprintf(fp,"%s -> %s",path->remot,dir); - - /* execute download command */ - if ((ret=execcmd_to(cmd))) { - if ((proto==0&&ret==FTP_NOFILE)|| - (proto==1&&ret==HTTP_NOFILE)) { - showmsg("STAT=x"); - if (fp) fprintf(fp," NO_FILE\n"); - n[1]++; - } - else { - trace(2,"exec_down: error proto=%d %d\n",proto,ret); - showmsg("STAT=X"); - if (fp) fprintf(fp," ERROR (%d)\n",ret); - n[3]++; - } - remove(path->local); - if (!(opts&DLOPT_HOLDERR)) { - remove(errfile); - } - return ret==2; - } - remove(errfile); - - /* uncompress download file */ - if (!(opts&DLOPT_KEEPCMP)&&(p=strrchr(path->local,'.'))&& - (!strcmp(p,".z")||!strcmp(p,".gz")||!strcmp(p,".zip")|| - !strcmp(p,".Z")||!strcmp(p,".GZ")||!strcmp(p,".ZIP"))) { - - if (rtk_uncompress(path->local,tmpfile)) { - remove(path->local); - } - else { - trace(2,"exec_down: uncompress error\n"); - showmsg("STAT=C"); - if (fp) fprintf(fp," ERROR (UNCOMP)\n"); - n[3]++; - return 0; - } - } - showmsg("STAT=o"); - if (fp) fprintf(fp," OK\n"); - n[0]++; + strcpy(dir, path->local); + if ((p = strrchr(dir, RTKLIB_FILEPATHSEP))) *p = '\0'; + + if (!strncmp(path->remot, "ftp://", 6)) + proto = 0; + else if (!strncmp(path->remot, "ftps://", 7)) + proto = 2; + else if (!strncmp(path->remot, "http://", 7)) + proto = 1; + else if (!strncmp(path->remot, "https://", 8)) + proto = 1; + else { + trace(2, "exec_down: invalid path %s\n", path->remot); + showmsg("STAT=X"); + if (fp) fprintf(fp, "%s ERROR (INVALID PATH)\n", path->remot); + n[1]++; + return 0; + } + /* test local file existence */ + if (!(opts & DLOPT_FORCE) && test_file(path->local)) { + showmsg("STAT=."); + if (fp) fprintf(fp, "%s in %s\n", path->remot, dir); + n[2]++; return 0; + } + showmsg("STAT=_"); + + /* get remote file list for FTP or FTPS */ + if ((proto == 0 || proto == 2) && (p = strrchr(path->remot, '/')) && + strncmp(path->remot, remot_p, p - path->remot)) { + if (get_list(path, usr, pwd, proxy)) { + strcpy(remot_p, path->remot); + } + } + /* test file in listing for FTP or FTPS or extend wild-card in file path */ + if ((proto == 0 || proto == 2) && !test_list(path)) { + showmsg("STAT=x"); + if (fp) fprintf(fp, "%s NO_FILE\n", path->remot); + n[1]++; + return 0; + } + /* generate local directory recursively */ + if (!mkdir_r(dir)) { + showmsg("STAT=X"); + if (fp) fprintf(fp, "%s -> %s ERROR (LOCAL DIR)\n", path->remot, dir); + n[3]++; + return 0; + } + /* re-test local file existence for file with wild-card */ + if (!(opts & DLOPT_FORCE) && test_file(path->local)) { + showmsg("STAT=."); + if (fp) fprintf(fp, "%s in %s\n", path->remot, dir); + n[2]++; + return 0; + } + /* proxy option */ + if (*proxy) { + sprintf(env, "set %s_proxy=http://%s & ", proto == 0 || proto == 2 ? "ftp" : "http", proxy); + sprintf(opt, " --proxy=on "); + } + /* download command */ + sprintf(errfile, "%s.err", path->local); + if (proto == 0 || proto == 2) { + sprintf(cmd, + "%s%s %s --ftp-user=%s --ftp-password=%s --glob=off " + "--passive-ftp %s-t %d -T %d -O \"%s\" -o \"%s\"%s\n", + env, FTP_CMD, path->remot, usr, pwd, opt, FTP_RETRY, FTP_TIMEOUT, path->local, errfile, + opt2); + } else { + if (*pwd) { + sprintf(opt + strlen(opt), " --http-user=%s --http-password=%s ", usr, pwd); + } + sprintf(cmd, "%s%s %s %s-t %d -T %d -O \"%s\" -o \"%s\"%s\n", env, FTP_CMD, path->remot, opt, + FTP_RETRY, FTP_TIMEOUT, path->local, errfile, opt2); + } + if (fp) fprintf(fp, "%s -> %s", path->remot, dir); + + /* execute download command */ + if ((ret = execcmd_to(cmd))) { + if ((proto == 0 && ret == FTP_NOFILE) || (proto == 1 && ret == HTTP_NOFILE)) { + showmsg("STAT=x"); + if (fp) fprintf(fp, " NO_FILE\n"); + n[1]++; + } else { + trace(2, "exec_down: error proto=%d %d\n", proto, ret); + showmsg("STAT=X"); + if (fp) fprintf(fp, " ERROR (%d)\n", ret); + n[3]++; + } + remove(path->local); + if (!(opts & DLOPT_HOLDERR)) { + remove(errfile); + } + return ret == 2; + } + remove(errfile); + + /* uncompress download file */ + if (!(opts & DLOPT_KEEPCMP) && (p = strrchr(path->local, '.')) && + (!strcmp(p, ".z") || !strcmp(p, ".gz") || !strcmp(p, ".zip") || !strcmp(p, ".Z") || + !strcmp(p, ".GZ") || !strcmp(p, ".ZIP"))) { + if (rtk_uncompress(path->local, tmpfile)) { + remove(path->local); + } else { + trace(2, "exec_down: uncompress error\n"); + showmsg("STAT=C"); + if (fp) fprintf(fp, " ERROR (UNCOMP)\n"); + n[3]++; + return 0; + } + } + showmsg("STAT=o"); + if (fp) fprintf(fp, " OK\n"); + n[0]++; + return 0; } /* test local file -----------------------------------------------------------*/ -static int test_local(gtime_t ts, gtime_t te, double ti, const char *path, - const char *sta, const char *dir, int *nc, int *nt, - FILE *fp) -{ - gtime_t time; - char remot[1024],dir_t[1024],local[1024],str[1024]; - int stat,abort=0; - - for (time=ts;timediff(time,te)<=1E-3;time=timeadd(time,ti)) { - genpath(path,sta,time,0,remot); - genpath(dir ,sta,time,0,dir_t); - remot2local(remot,dir_t,local); - - sprintf(str,"%s->%s",path,local); - if (showmsg(str)) { - abort=1; - break; - } +static int test_local(gtime_t ts, gtime_t te, double ti, const char *path, const char *sta, + const char *dir, int *nc, int *nt, FILE *fp) { + gtime_t time; + char remot[1024], dir_t[1024], local[1024], str[1024]; + int stat, abort = 0; + + for (time = ts; timediff(time, te) <= 1E-3; time = timeadd(time, ti)) { + genpath(path, sta, time, 0, remot); + genpath(dir, sta, time, 0, dir_t); + remot2local(remot, dir_t, local); - stat=test_file(local); - - fprintf(fp," %s",stat==0?"-":(stat==1?"o":"z")); - - showmsg("STAT=%s",stat==0?"x":(stat==1?"o":"z")); - - (*nt)++; if (stat) (*nc)++; + sprintf(str, "%s->%s", path, local); + if (showmsg(str)) { + abort = 1; + break; } - fprintf(fp,"\n"); - return abort; + + stat = test_file(local); + + fprintf(fp, " %s", stat == 0 ? "-" : (stat == 1 ? "o" : "z")); + + showmsg("STAT=%s", stat == 0 ? "x" : (stat == 1 ? "o" : "z")); + + (*nt)++; + if (stat) (*nc)++; + } + fprintf(fp, "\n"); + return abort; } /* test local files ----------------------------------------------------------*/ -static int test_locals(gtime_t ts, gtime_t te, double ti, const url_t *url, - const char **stas, int nsta, const char *dir, int *nc, int *nt, - FILE *fp) -{ - int i; - - if (strstr(url->path,"%s")||strstr(url->path,"%S")) { - fprintf(fp,"%s\n",url->type); - for (i=0;ipath,stas[i],*dir?dir:url->dir,nc+i, - nt+i,fp)) { - return 1; - } - } +static int test_locals(gtime_t ts, gtime_t te, double ti, const url_t *url, const char **stas, + int nsta, const char *dir, int *nc, int *nt, FILE *fp) { + int i; + + if (strstr(url->path, "%s") || strstr(url->path, "%S")) { + fprintf(fp, "%s\n", url->type); + for (i = 0; i < nsta; i++) { + fprintf(fp, "%-12s:", stas[i]); + if (test_local(ts, te, ti, url->path, stas[i], *dir ? dir : url->dir, nc + i, nt + i, fp)) { + return 1; + } } - else { - fprintf(fp,"%-12s:",url->type); - if (test_local(ts,te,ti,url->path,"",*dir?dir:url->dir,nc,nt,fp)) { - return 1; - } + } else { + fprintf(fp, "%-12s:", url->type); + if (test_local(ts, te, ti, url->path, "", *dir ? dir : url->dir, nc, nt, fp)) { + return 1; } - return 0; + } + return 0; } /* print total count of local files ------------------------------------------*/ -static int print_total(const url_t *url, const char **stas, int nsta, int *nc, - int *nt, FILE *fp) -{ - int i; - - if (strstr(url->path,"%s")||strstr(url->path,"%S")) { - fprintf(fp,"%s\n",url->type); - for (i=0;itype,nc[0],nt[0]); - return 1; +static int print_total(const url_t *url, const char **stas, int nsta, int *nc, int *nt, FILE *fp) { + int i; + + if (strstr(url->path, "%s") || strstr(url->path, "%S")) { + fprintf(fp, "%s\n", url->type); + for (i = 0; i < nsta; i++) { + fprintf(fp, "%-12s: %5d/%5d\n", stas[i], nc[i], nt[i]); + } + return nsta; + } + fprintf(fp, "%-12s: %5d/%5d\n", url->type, nc[0], nt[0]); + return 1; } /* read URL list file ---------------------------------------------------------- -* read URL list file for GNSS data -* args : char *file I URL list file -* char **types I selected types ("*":wildcard) -* int ntype I number of selected types -* urls_t *urls O URL list -* int nmax I max number of URL list -* return : number of URL addresses (0:error) -* notes : -* (1) URL list file contains records containing the following fields -* separated by spaces. if a field contains spaces, enclose it within "". -* -* data_type url_address default_local_directory -* -* (2) strings after # in a line are treated as comments -* (3) url_address should be: -* -* ftp://host_address/file_path or -* ftps://host_address/file_path or -* http://host_address/file_path or -* https://host_address/file_path -* -* (4) the field url_address or default_local_directory can include the -* follwing keywords replaced by date, time, station names and environment -* variables. -* -* %Y -> yyyy : year (4 digits) (2000-2099) -* %y -> yy : year (2 digits) (00-99) -* %m -> mm : month (01-12) -* %d -> dd : day of month (01-31) -* %h -> hh : hours (00-23) -* %H -> a : hour code (a-x) -* %M -> mm : minutes (00-59) -* %n -> ddd : day of year (001-366) -* %W -> wwww : gps week (0001-9999) -* %D -> d : day of gps week (0-6) -* %N -> nnn : general number -* %s -> ssss : station name (lower-case) -* %S -> SSSS : station name (upper-case) -* %r -> rrrr : station name -* %{env} -> env : environment variable -*-----------------------------------------------------------------------------*/ -extern int dl_readurls(const char *file, const char **types, int ntype, url_t *urls, - int nmax) -{ - FILE *fp; - char buff[2048],type[32],path[1024],dir[1024],*p; - int i,n=0; - - if (!(fp=fopen(file,"r"))) { - fprintf(stderr,"options file read error %s\n",file); - return 0; - } - for (i=0;i yyyy : year (4 digits) (2000-2099) + * %y -> yy : year (2 digits) (00-99) + * %m -> mm : month (01-12) + * %d -> dd : day of month (01-31) + * %h -> hh : hours (00-23) + * %H -> a : hour code (a-x) + * %M -> mm : minutes (00-59) + * %n -> ddd : day of year (001-366) + * %W -> wwww : gps week (0001-9999) + * %D -> d : day of gps week (0-6) + * %N -> nnn : general number + * %s -> ssss : station name (lower-case) + * %S -> SSSS : station name (upper-case) + * %r -> rrrr : station name + * %{env} -> env : environment variable + *-----------------------------------------------------------------------------*/ +extern int dl_readurls(const char *file, const char **types, int ntype, url_t *urls, int nmax) { + FILE *fp; + char buff[2048], type[32], path[1024], dir[1024], *p; + int i, n = 0; + + if (!(fp = fopen(file, "r"))) { + fprintf(stderr, "options file read error %s\n", file); + return 0; + } + for (i = 0; i < ntype; i++) { + rewind(fp); + while (fgets(buff, sizeof(buff), fp) && n < nmax) { + if ((p = strchr(buff, '#'))) *p = '\0'; + p = buff; + p = parse_str(p, type, sizeof(type)); + p = parse_str(p, path, sizeof(path)); + p = parse_str(p, dir, sizeof(dir)); + if (!*type || !*path) continue; + if (!cmp_str(type, types[i])) continue; + strcpy(urls[n].type, type); + strcpy(urls[n].path, path); + strcpy(urls[n++].dir, dir); + } + } + fclose(fp); + + if (n <= 0) { + fprintf(stderr, "no url in options file %s\n", file); + return 0; + } + return n; } /* read station list file ------------------------------------------------------ -* read station list file -* args : char *file I station list file -* char **stas O stations -* int nmax I max number of stations -* return : number of stations (0:error) -* notes : -* (1) station list file contains station names separated by spaces. -* (2) strings after # in a line are treated as comments -*-----------------------------------------------------------------------------*/ -extern int dl_readstas(const char *file, char **stas, int nmax) -{ - FILE *fp; - char buff[4096],*p; - int n=0; - - if (!(fp=fopen(file,"r"))) { - fprintf(stderr,"station list file read error %s\n",file); - return 0; - } - while (fgets(buff,sizeof(buff),fp)&&n%s (%d/%d)",paths.path[i].remot,paths.path[i].local,i+1, - paths.n); - if (showmsg(str)) break; - - /* execute download */ - if (exec_down(paths.path+i,remot_p,usr,pwd,proxy,opts,n,fp)) { - break; - } - } - if (!(opts&DLOPT_HOLDLST)) { - remove(FTP_LISTING); + ts_p = ts; + ts = timeadd(ts, ti); + } + /* compact download paths */ + compact_paths(&paths); + + if (paths.n <= 0) { + sprintf(msg, "no download data"); + return 0; + } + for (i = 0; i < paths.n; i++) { + sprintf(str, "%s->%s (%d/%d)", paths.path[i].remot, paths.path[i].local, i + 1, paths.n); + if (showmsg(str)) break; + + /* execute download */ + if (exec_down(paths.path + i, remot_p, usr, pwd, proxy, opts, n, fp)) { + break; } - sprintf(msg,"OK=%d No_File=%d Skip=%d Error=%d (Time=%.1f s)",n[0],n[1],n[2], - n[3],(tickget()-tick)*0.001); - - free_path(&paths); - - return 1; + } + if (!(opts & DLOPT_HOLDLST)) { + remove(FTP_LISTING); + } + sprintf(msg, "OK=%d No_File=%d Skip=%d Error=%d (Time=%.1f s)", n[0], n[1], n[2], n[3], + (tickget() - tick) * 0.001); + + free_path(&paths); + + return 1; } /* execute local file test ----------------------------------------------------- -* execute local file test -* args : gtime_t ts,te I time start and end -* double tint I time interval (s) -* url_t *urls I remote URL addresses -* int nurl I number of remote URL addresses -* char **stas I stations -* int nsta I number of stations -* char *dir I local directory -* int ncol I number of column -* int datefmt I date format (0:year-dow,1:year-dd/mm,2:week) -* FILE *fp IO log test result file pointer -* return : status (1:ok,0:error,-1:aborted) -*-----------------------------------------------------------------------------*/ -extern void dl_test(gtime_t ts, gtime_t te, double ti, const url_t *urls, - int nurl, const char **stas, int nsta, const char *dir, - int ncol, int datefmt, FILE *fp) -{ - gtime_t time; - char year[32],date[32],date_p[32]; - int i,j,n,m,*nc,*nt,week,flag,abort=0; - - if (ncol<1) ncol=1; else if (ncol>200) ncol=200; - - char tstr[40]; - fprintf(fp,"** LOCAL DATA AVAILABILITY (%s, %s) **\n\n", - time2str(timeget(),tstr,0),*dir?dir:"*"); - - for (i=n=0;i=1E-3) break; - - if (datefmt<=1) { - genpath(datefmt==0?"%n":"%d","",time,0,date); - fprintf(fp,"%-4s",strcmp(date,date_p)?date:""); - } - else { - if (fabs(time2gpst(time,&week))<1.0) { - fprintf(fp,"%04d",week); flag=1; - } - else { - fprintf(fp,"%s",flag?"":" "); flag=0; - } - } - strcpy(date_p,date); - } - fprintf(fp,"\n"); - - for (i=j=0;i=0.0) time=te; - - /* test local files */ - abort=test_locals(ts,time,ti,urls+i,stas,nsta,dir,nc+j,nt+j,fp); - - j+=strstr(urls[i].path,"%s")||strstr(urls[i].path,"%S")?nsta:1; + * execute local file test + * args : gtime_t ts,te I time start and end + * double tint I time interval (s) + * url_t *urls I remote URL addresses + * int nurl I number of remote URL addresses + * char **stas I stations + * int nsta I number of stations + * char *dir I local directory + * int ncol I number of column + * int datefmt I date format (0:year-dow,1:year-dd/mm,2:week) + * FILE *fp IO log test result file pointer + * return : status (1:ok,0:error,-1:aborted) + *-----------------------------------------------------------------------------*/ +extern void dl_test(gtime_t ts, gtime_t te, double ti, const url_t *urls, int nurl, + const char **stas, int nsta, const char *dir, int ncol, int datefmt, FILE *fp) { + gtime_t time; + char year[32], date[32], date_p[32]; + int i, j, n, m, *nc, *nt, week, flag, abort = 0; + + if (ncol < 1) + ncol = 1; + else if (ncol > 200) + ncol = 200; + + char tstr[40]; + fprintf(fp, "** LOCAL DATA AVAILABILITY (%s, %s) **\n\n", time2str(timeget(), tstr, 0), + *dir ? dir : "*"); + + for (i = n = 0; i < nurl; i++) { + n += strstr(urls[i].path, "%s") || strstr(urls[i].path, "%S") ? nsta : 1; + } + nc = imat(n, 1); + nt = imat(n, 1); + for (i = 0; i < n; i++) nc[i] = nt[i] = 0; + + for (; timediff(ts, te) < 1E-3 && !abort; ts = timeadd(ts, ti * ncol)) { + genpath(datefmt == 0 ? " %Y-" : "%Y/%m/", "", ts, 0, year); + if (datefmt <= 1) + fprintf(fp, "%s %s", datefmt == 0 ? "DOY " : "DATE", year); + else + fprintf(fp, "WEEK "); + *date_p = '\0'; + flag = 0; + + m = datefmt == 2 ? 1 : 2; + + for (i = 0; i < (ncol + m - 1) / m; i++) { + time = timeadd(ts, ti * i * m); + if (timediff(time, te) >= 1E-3) break; + + if (datefmt <= 1) { + genpath(datefmt == 0 ? "%n" : "%d", "", time, 0, date); + fprintf(fp, "%-4s", strcmp(date, date_p) ? date : ""); + } else { + if (fabs(time2gpst(time, &week)) < 1.0) { + fprintf(fp, "%04d", week); + flag = 1; + } else { + fprintf(fp, "%s", flag ? "" : " "); + flag = 0; } - fprintf(fp,"\n"); + } + strcpy(date_p, date); } - fprintf(fp,"# COUNT : FILES/TOTAL\n"); - - for (i=j=0;i= 0.0) time = te; + + /* test local files */ + abort = test_locals(ts, time, ti, urls + i, stas, nsta, dir, nc + j, nt + j, fp); + + j += strstr(urls[i].path, "%s") || strstr(urls[i].path, "%S") ? nsta : 1; } - free(nc); free(nt); + fprintf(fp, "\n"); + } + fprintf(fp, "# COUNT : FILES/TOTAL\n"); + + for (i = j = 0; i < nurl; i++) { + j += print_total(urls + i, stas, nsta, nc + j, nt + j, fp); + } + free(nc); + free(nt); } diff --git a/src/ephemeris.c b/src/ephemeris.c index be4d0d9dd..06f646016 100644 --- a/src/ephemeris.c +++ b/src/ephemeris.c @@ -1,881 +1,925 @@ /*------------------------------------------------------------------------------ -* ephemeris.c : satellite ephemeris and clock functions -* -* Copyright (C) 2010-2020 by T.TAKASU, All rights reserved. -* -* references : -* [1] IS-GPS-200K, Navstar GPS Space Segment/Navigation User Interfaces, -* May 6, 2019 -* [2] Global Navigation Satellite System GLONASS, Interface Control Document -* Navigational radiosignal In bands L1, L2, (Version 5.1), 2008 -* [3] RTCA/DO-229C, Minimum operational performance standards for global -* positioning system/wide area augmentation system airborne equipment, -* RTCA inc, November 28, 2001 -* [4] RTCM Paper, April 12, 2010, Proposed SSR Messages for SV Orbit Clock, -* Code Biases, URA -* [5] RTCM Paper 012-2009-SC104-528, January 28, 2009 (previous ver of [4]) -* [6] RTCM Paper 012-2009-SC104-582, February 2, 2010 (previous ver of [4]) -* [7] European GNSS (Galileo) Open Service Signal In Space Interface Control -* Document, Issue 1.3, December, 2016 -* [8] Quasi-Zenith Satellite System Interface Specification Satellite -* Positioning, Navigation and Timing Service (IS-QZSS-PNT-003), Cabinet -* Office, November 5, 2018 -* [9] BeiDou navigation satellite system signal in space interface control -* document open service signal B1I (version 3.0), China Satellite -* Navigation office, February, 2019 -* [10] RTCM Standard 10403.3, Differential GNSS (Global Navigation -* Satellite Systems) Services - version 3, October 7, 2016 -* -* version : $Revision:$ $Date:$ -* history : 2010/07/28 1.1 moved from rtkcmn.c -* added api: -* eph2clk(),geph2clk(),seph2clk(),satantoff() -* satposs() -* changed api: -* eph2pos(),geph2pos(),satpos() -* deleted api: -* satposv(),satposiode() -* 2010/08/26 1.2 add ephemeris option EPHOPT_LEX -* 2010/09/09 1.3 fix problem when precise clock outage -* 2011/01/12 1.4 add api alm2pos() -* change api satpos(),satposs() -* enable valid unhealthy satellites and output status -* fix bug on exception by glonass ephem computation -* 2013/01/10 1.5 support beidou (compass) -* use newton's method to solve kepler eq. -* update ssr correction algorithm -* 2013/03/20 1.6 fix problem on ssr clock relativistic correction -* 2013/09/01 1.7 support negative pseudorange -* fix bug on variance in case of ura ssr = 63 -* 2013/11/11 1.8 change constant MAXAGESSR 70.0 -> 90.0 -* 2014/10/24 1.9 fix bug on return of var_uraeph() if ura<0||15 1E-13 -* set MAX_ITER_KEPLER for alm2pos() -* 2017/04/11 1.12 fix bug on max number of obs data in satposs() -* 2018/10/10 1.13 update reference [7] -* support ura value in var_uraeph() for galileo -* test eph->flag to recognize beidou geo -* add api satseleph() for ephemeris selection -* 2020/11/30 1.14 update references [1],[2],[8],[9] and [10] -* add API getseleph() -* rename API satseleph() as setseleph() -* support NavIC/IRNSS by API satpos() and satposs() -* support BDS C59-63 as GEO satellites in eph2pos() -* default selection of I/NAV for Galileo ephemeris -* no support EPHOPT_LEX by API satpos() and satposs() -* unselect Galileo ephemeris with AOD<=0 in seleph() -* fix bug on clock iteration in eph2clk(), geph2clk() -* fix bug on clock reference time in satpos_ssr() -* fix bug on wrong value with ura=15 in var_ura() -* use integer types in stdint.h -*-----------------------------------------------------------------------------*/ + * ephemeris.c : satellite ephemeris and clock functions + * + * Copyright (C) 2010-2020 by T.TAKASU, All rights reserved. + * + * references : + * [1] IS-GPS-200K, Navstar GPS Space Segment/Navigation User Interfaces, + * May 6, 2019 + * [2] Global Navigation Satellite System GLONASS, Interface Control Document + * Navigational radiosignal In bands L1, L2, (Version 5.1), 2008 + * [3] RTCA/DO-229C, Minimum operational performance standards for global + * positioning system/wide area augmentation system airborne equipment, + * RTCA inc, November 28, 2001 + * [4] RTCM Paper, April 12, 2010, Proposed SSR Messages for SV Orbit Clock, + * Code Biases, URA + * [5] RTCM Paper 012-2009-SC104-528, January 28, 2009 (previous ver of [4]) + * [6] RTCM Paper 012-2009-SC104-582, February 2, 2010 (previous ver of [4]) + * [7] European GNSS (Galileo) Open Service Signal In Space Interface Control + * Document, Issue 1.3, December, 2016 + * [8] Quasi-Zenith Satellite System Interface Specification Satellite + * Positioning, Navigation and Timing Service (IS-QZSS-PNT-003), Cabinet + * Office, November 5, 2018 + * [9] BeiDou navigation satellite system signal in space interface control + * document open service signal B1I (version 3.0), China Satellite + * Navigation office, February, 2019 + * [10] RTCM Standard 10403.3, Differential GNSS (Global Navigation + * Satellite Systems) Services - version 3, October 7, 2016 + * + * version : $Revision:$ $Date:$ + * history : 2010/07/28 1.1 moved from rtkcmn.c + * added api: + * eph2clk(),geph2clk(),seph2clk(),satantoff() + * satposs() + * changed api: + * eph2pos(),geph2pos(),satpos() + * deleted api: + * satposv(),satposiode() + * 2010/08/26 1.2 add ephemeris option EPHOPT_LEX + * 2010/09/09 1.3 fix problem when precise clock outage + * 2011/01/12 1.4 add api alm2pos() + * change api satpos(),satposs() + * enable valid unhealthy satellites and output status + * fix bug on exception by glonass ephem computation + * 2013/01/10 1.5 support beidou (compass) + * use newton's method to solve kepler eq. + * update ssr correction algorithm + * 2013/03/20 1.6 fix problem on ssr clock relativistic correction + * 2013/09/01 1.7 support negative pseudorange + * fix bug on variance in case of ura ssr = 63 + * 2013/11/11 1.8 change constant MAXAGESSR 70.0 -> 90.0 + * 2014/10/24 1.9 fix bug on return of var_uraeph() if ura<0||15 1E-13 + * set MAX_ITER_KEPLER for alm2pos() + * 2017/04/11 1.12 fix bug on max number of obs data in satposs() + * 2018/10/10 1.13 update reference [7] + * support ura value in var_uraeph() for galileo + * test eph->flag to recognize beidou geo + * add api satseleph() for ephemeris selection + * 2020/11/30 1.14 update references [1],[2],[8],[9] and [10] + * add API getseleph() + * rename API satseleph() as setseleph() + * support NavIC/IRNSS by API satpos() and satposs() + * support BDS C59-63 as GEO satellites in eph2pos() + * default selection of I/NAV for Galileo ephemeris + * no support EPHOPT_LEX by API satpos() and satposs() + * unselect Galileo ephemeris with AOD<=0 in seleph() + * fix bug on clock iteration in eph2clk(), geph2clk() + * fix bug on clock reference time in satpos_ssr() + * fix bug on wrong value with ura=15 in var_ura() + * use integer types in stdint.h + *-----------------------------------------------------------------------------*/ #include "rtklib.h" /* constants and macros ------------------------------------------------------*/ -#define SQR(x) ((x)*(x)) +#define SQR(x) ((x) * (x)) -#define RE_GLO 6378136.0 /* radius of earth (m) ref [2] */ -#define MU_GPS 3.9860050E14 /* gravitational constant ref [1] */ -#define MU_GLO 3.9860044E14 /* gravitational constant ref [2] */ -#define MU_GAL 3.986004418E14 /* earth gravitational constant ref [7] */ -#define MU_CMP 3.986004418E14 /* earth gravitational constant ref [9] */ -#define J2_GLO 1.0826257E-3 /* 2nd zonal harmonic of geopot ref [2] */ +#define RE_GLO 6378136.0 /* radius of earth (m) ref [2] */ +#define MU_GPS 3.9860050E14 /* gravitational constant ref [1] */ +#define MU_GLO 3.9860044E14 /* gravitational constant ref [2] */ +#define MU_GAL 3.986004418E14 /* earth gravitational constant ref [7] */ +#define MU_CMP 3.986004418E14 /* earth gravitational constant ref [9] */ +#define J2_GLO 1.0826257E-3 /* 2nd zonal harmonic of geopot ref [2] */ -#define OMGE_GLO 7.292115E-5 /* earth angular velocity (rad/s) ref [2] */ -#define OMGE_GAL 7.2921151467E-5 /* earth angular velocity (rad/s) ref [7] */ -#define OMGE_CMP 7.292115E-5 /* earth angular velocity (rad/s) ref [9] */ +#define OMGE_GLO 7.292115E-5 /* earth angular velocity (rad/s) ref [2] */ +#define OMGE_GAL 7.2921151467E-5 /* earth angular velocity (rad/s) ref [7] */ +#define OMGE_CMP 7.292115E-5 /* earth angular velocity (rad/s) ref [9] */ #define SIN_5 -0.0871557427476582 /* sin(-5.0 deg) */ -#define COS_5 0.9961946980917456 /* cos(-5.0 deg) */ +#define COS_5 0.9961946980917456 /* cos(-5.0 deg) */ -#define ERREPH_GLO 5.0 /* error of glonass ephemeris (m) */ -#define TSTEP 60.0 /* integration step glonass ephemeris (s) */ -#define RTOL_KEPLER 1E-13 /* relative tolerance for Kepler equation */ +#define ERREPH_GLO 5.0 /* error of glonass ephemeris (m) */ +#define TSTEP 60.0 /* integration step glonass ephemeris (s) */ +#define RTOL_KEPLER 1E-13 /* relative tolerance for Kepler equation */ -#define DEFURASSR 0.15 /* default accuracy of ssr corr (m) */ -#define MAXECORSSR 10.0 /* max orbit correction of ssr (m) */ -#define MAXCCORSSR (1E-6*CLIGHT) /* max clock correction of ssr (m) */ -#define MAXAGESSR 90.0 /* max age of ssr orbit and clock (s) */ -#define MAXAGESSR_HRCLK 10.0 /* max age of ssr high-rate clock (s) */ -#define STD_BRDCCLK 30.0 /* error of broadcast clock (m) */ -#define STD_GAL_NAPA 500.0 /* error of galileo ephemeris for NAPA (m) */ +#define DEFURASSR 0.15 /* default accuracy of ssr corr (m) */ +#define MAXECORSSR 10.0 /* max orbit correction of ssr (m) */ +#define MAXCCORSSR (1E-6 * CLIGHT) /* max clock correction of ssr (m) */ +#define MAXAGESSR 90.0 /* max age of ssr orbit and clock (s) */ +#define MAXAGESSR_HRCLK 10.0 /* max age of ssr high-rate clock (s) */ +#define STD_BRDCCLK 30.0 /* error of broadcast clock (m) */ +#define STD_GAL_NAPA 500.0 /* error of galileo ephemeris for NAPA (m) */ -#define MAX_ITER_KEPLER 30 /* max number of iteration of Kepler */ +#define MAX_ITER_KEPLER 30 /* max number of iteration of Kepler */ /* ephemeris selections ------------------------------------------------------*/ -static int eph_sel[]={ /* GPS,GLO,GAL,QZS,BDS,IRN,SBS */ - 0,0,0,0,0,0,0 -}; +static int eph_sel[] = {/* GPS,GLO,GAL,QZS,BDS,IRN,SBS */ + 0, 0, 0, 0, 0, 0, 0}; /* variance by ura ephemeris -------------------------------------------------*/ -static double var_uraeph(int sys, int ura) -{ - const double ura_value[]={ - 2.4,3.4,4.85,6.85,9.65,13.65,24.0,48.0,96.0,192.0,384.0,768.0,1536.0, - 3072.0,6144.0 - }; - if (sys==SYS_GAL) { /* galileo sisa (ref [7] 5.1.11) */ - if (ura<= 49) return SQR(ura*0.01); - if (ura<= 74) return SQR(0.5+(ura- 50)*0.02); - if (ura<= 99) return SQR(1.0+(ura- 75)*0.04); - if (ura<=125) return SQR(2.0+(ura-100)*0.16); - return SQR(STD_GAL_NAPA); - } - else { /* gps ura (ref [1] 20.3.3.3.1.1) */ - return ura<0||14=63) return SQR(5.4665); - std=(pow(3.0,(ura>>3)&7)*(1.0+(ura&7)/4.0)-1.0)*1E-3; - return SQR(std); +static double var_urassr(int ura) { + double std; + if (ura <= 0) return SQR(DEFURASSR); + if (ura >= 63) return SQR(5.4665); + std = (pow(3.0, (ura >> 3) & 7) * (1.0 + (ura & 7) / 4.0) - 1.0) * 1E-3; + return SQR(std); } /* almanac to satellite position and clock bias -------------------------------- -* compute satellite position and clock bias with almanac (gps, galileo, qzss) -* args : gtime_t time I time (gpst) -* alm_t *alm I almanac -* double *rs O satellite position (ecef) {x,y,z} (m) -* double *dts O satellite clock bias (s) -* return : none -* notes : see ref [1],[7],[8] -*-----------------------------------------------------------------------------*/ -extern void alm2pos(gtime_t time, const alm_t *alm, double *rs, double *dts) -{ - double tk,M,E,Ek,sinE,cosE,u,r,i,O,x,y,sinO,cosO,cosi,mu; - int n; - - char tstr[40]; - trace(4,"alm2pos : time=%s sat=%2d\n",time2str(time,tstr,3),alm->sat); - - tk=timediff(time,alm->toa); - - if (alm->A<=0.0) { - rs[0]=rs[1]=rs[2]=*dts=0.0; - return; - } - mu=satsys(alm->sat,NULL)==SYS_GAL?MU_GAL:MU_GPS; - - M=alm->M0+sqrt(mu/(alm->A*alm->A*alm->A))*tk; - for (n=0,E=M,Ek=0.0;fabs(E-Ek)>RTOL_KEPLER&&ne*sin(E)-M)/(1.0-alm->e*cos(E)); - } - if (n>=MAX_ITER_KEPLER) { - trace(2,"alm2pos: kepler iteration overflow sat=%2d\n",alm->sat); - } - sinE=sin(E); cosE=cos(E); - u=atan2(sqrt(1.0-alm->e*alm->e)*sinE,cosE-alm->e)+alm->omg; - r=alm->A*(1.0-alm->e*cosE); - i=alm->i0; - O=alm->OMG0+(alm->OMGd-OMGE)*tk-OMGE*alm->toas; - x=r*cos(u); y=r*sin(u); sinO=sin(O); cosO=cos(O); cosi=cos(i); - rs[0]=x*cosO-y*cosi*sinO; - rs[1]=x*sinO+y*cosi*cosO; - rs[2]=y*sin(i); - *dts=alm->f0+alm->f1*tk; + * compute satellite position and clock bias with almanac (gps, galileo, qzss) + * args : gtime_t time I time (gpst) + * alm_t *alm I almanac + * double *rs O satellite position (ecef) {x,y,z} (m) + * double *dts O satellite clock bias (s) + * return : none + * notes : see ref [1],[7],[8] + *-----------------------------------------------------------------------------*/ +extern void alm2pos(gtime_t time, const alm_t *alm, double *rs, double *dts) { + double tk, M, E, Ek, sinE, cosE, u, r, i, O, x, y, sinO, cosO, cosi, mu; + int n; + + char tstr[40]; + trace(4, "alm2pos : time=%s sat=%2d\n", time2str(time, tstr, 3), alm->sat); + + tk = timediff(time, alm->toa); + + if (alm->A <= 0.0) { + rs[0] = rs[1] = rs[2] = *dts = 0.0; + return; + } + mu = satsys(alm->sat, NULL) == SYS_GAL ? MU_GAL : MU_GPS; + + M = alm->M0 + sqrt(mu / (alm->A * alm->A * alm->A)) * tk; + for (n = 0, E = M, Ek = 0.0; fabs(E - Ek) > RTOL_KEPLER && n < MAX_ITER_KEPLER; n++) { + Ek = E; + E -= (E - alm->e * sin(E) - M) / (1.0 - alm->e * cos(E)); + } + if (n >= MAX_ITER_KEPLER) { + trace(2, "alm2pos: kepler iteration overflow sat=%2d\n", alm->sat); + } + sinE = sin(E); + cosE = cos(E); + u = atan2(sqrt(1.0 - alm->e * alm->e) * sinE, cosE - alm->e) + alm->omg; + r = alm->A * (1.0 - alm->e * cosE); + i = alm->i0; + O = alm->OMG0 + (alm->OMGd - OMGE) * tk - OMGE * alm->toas; + x = r * cos(u); + y = r * sin(u); + sinO = sin(O); + cosO = cos(O); + cosi = cos(i); + rs[0] = x * cosO - y * cosi * sinO; + rs[1] = x * sinO + y * cosi * cosO; + rs[2] = y * sin(i); + *dts = alm->f0 + alm->f1 * tk; } /* broadcast ephemeris to satellite clock bias --------------------------------- -* compute satellite clock bias with broadcast ephemeris (gps, galileo, qzss) -* args : gtime_t time I time by satellite clock (gpst) -* eph_t *eph I broadcast ephemeris -* return : satellite clock bias (s) without relativity correction -* notes : see ref [1],[7],[8] -* satellite clock does not include relativity correction and tdg -*-----------------------------------------------------------------------------*/ -extern double eph2clk(gtime_t time, const eph_t *eph) -{ - double t,ts; - int i; - - char tstr[40]; - trace(4,"eph2clk : time=%s sat=%2d\n",time2str(time,tstr,3),eph->sat); - - t=ts=timediff(time,eph->toc); - - for (i=0;i<2;i++) { - t=ts-(eph->f0+eph->f1*t+eph->f2*t*t); - } - trace(4,"ephclk: t=%.12f ts=%.12f dts=%.12f f0=%.12f f1=%.9f f2=%.9f\n",t,ts, - eph->f0+eph->f1*t+eph->f2*t*t,eph->f0,eph->f1,eph->f2); - - return eph->f0+eph->f1*t+eph->f2*t*t; + * compute satellite clock bias with broadcast ephemeris (gps, galileo, qzss) + * args : gtime_t time I time by satellite clock (gpst) + * eph_t *eph I broadcast ephemeris + * return : satellite clock bias (s) without relativity correction + * notes : see ref [1],[7],[8] + * satellite clock does not include relativity correction and tdg + *-----------------------------------------------------------------------------*/ +extern double eph2clk(gtime_t time, const eph_t *eph) { + double t, ts; + int i; + + char tstr[40]; + trace(4, "eph2clk : time=%s sat=%2d\n", time2str(time, tstr, 3), eph->sat); + + t = ts = timediff(time, eph->toc); + + for (i = 0; i < 2; i++) { + t = ts - (eph->f0 + eph->f1 * t + eph->f2 * t * t); + } + trace(4, "ephclk: t=%.12f ts=%.12f dts=%.12f f0=%.12f f1=%.9f f2=%.9f\n", t, ts, + eph->f0 + eph->f1 * t + eph->f2 * t * t, eph->f0, eph->f1, eph->f2); + + return eph->f0 + eph->f1 * t + eph->f2 * t * t; } /* broadcast ephemeris to satellite position and clock bias -------------------- -* compute satellite position and clock bias with broadcast ephemeris (gps, -* galileo, qzss) -* args : gtime_t time I time (gpst) -* eph_t *eph I broadcast ephemeris -* double *rs O satellite position (ecef) {x,y,z} (m) -* double *dts O satellite clock bias (s) -* double *var O satellite position and clock variance (m^2) -* return : none -* notes : see ref [1],[7],[8] -* satellite clock includes relativity correction without code bias -* (tgd or bgd) -*-----------------------------------------------------------------------------*/ -extern void eph2pos(gtime_t time, const eph_t *eph, double *rs, double *dts, - double *var) -{ - double tk,M,E,Ek,sinE,cosE,u,r,i,O,sin2u,cos2u,x,y,sinO,cosO,cosi,mu,omge; - double xg,yg,zg,sino,coso; - int n,sys,prn; - - char tstr[40]; - trace(4,"eph2pos : time=%s sat=%2d\n",time2str(time,tstr,3),eph->sat); - - if (eph->A<=0.0) { - rs[0]=rs[1]=rs[2]=*dts=*var=0.0; - return; - } - tk=timediff(time,eph->toe); - - switch ((sys=satsys(eph->sat,&prn))) { - case SYS_GAL: mu=MU_GAL; omge=OMGE_GAL; break; - case SYS_CMP: mu=MU_CMP; omge=OMGE_CMP; break; - default: mu=MU_GPS; omge=OMGE; break; - } - M=eph->M0+(sqrt(mu/(eph->A*eph->A*eph->A))+eph->deln)*tk; - - for (n=0,E=M,Ek=0.0;fabs(E-Ek)>RTOL_KEPLER&&ne*sin(E)-M)/(1.0-eph->e*cos(E)); - } - if (n>=MAX_ITER_KEPLER) { - trace(2,"eph2pos: kepler iteration overflow sat=%2d\n",eph->sat); - } - sinE=sin(E); cosE=cos(E); - - trace(4,"kepler: sat=%2d e=%8.5f n=%2d del=%10.3e\n",eph->sat,eph->e,n,E-Ek); - - u=atan2(sqrt(1.0-eph->e*eph->e)*sinE,cosE-eph->e)+eph->omg; - r=eph->A*(1.0-eph->e*cosE); - i=eph->i0+eph->idot*tk; - sin2u=sin(2.0*u); cos2u=cos(2.0*u); - u+=eph->cus*sin2u+eph->cuc*cos2u; - r+=eph->crs*sin2u+eph->crc*cos2u; - i+=eph->cis*sin2u+eph->cic*cos2u; - x=r*cos(u); y=r*sin(u); cosi=cos(i); - - /* beidou geo satellite */ - if (sys==SYS_CMP&&(prn<=5||prn>=59)) { /* ref [9] table 4-1 */ - O=eph->OMG0+eph->OMGd*tk-omge*eph->toes; - sinO=sin(O); cosO=cos(O); - xg=x*cosO-y*cosi*sinO; - yg=x*sinO+y*cosi*cosO; - zg=y*sin(i); - sino=sin(omge*tk); coso=cos(omge*tk); - rs[0]= xg*coso+yg*sino*COS_5+zg*sino*SIN_5; - rs[1]=-xg*sino+yg*coso*COS_5+zg*coso*SIN_5; - rs[2]=-yg*SIN_5+zg*COS_5; - } - else { - O=eph->OMG0+(eph->OMGd-omge)*tk-omge*eph->toes; - sinO=sin(O); cosO=cos(O); - rs[0]=x*cosO-y*cosi*sinO; - rs[1]=x*sinO+y*cosi*cosO; - rs[2]=y*sin(i); - } - tk=timediff(time,eph->toc); - *dts=eph->f0+eph->f1*tk+eph->f2*tk*tk; - - /* relativity correction */ - *dts-=2.0*sqrt(mu*eph->A)*eph->e*sinE/SQR(CLIGHT); - - /* position and clock error variance */ - *var=var_uraeph(sys,eph->sva); - trace(4,"eph2pos: sat=%d, dts=%.10f rs=%.4f %.4f %.4f var=%.3f\n",eph->sat, - *dts,rs[0],rs[1],rs[2],*var); + * compute satellite position and clock bias with broadcast ephemeris (gps, + * galileo, qzss) + * args : gtime_t time I time (gpst) + * eph_t *eph I broadcast ephemeris + * double *rs O satellite position (ecef) {x,y,z} (m) + * double *dts O satellite clock bias (s) + * double *var O satellite position and clock variance (m^2) + * return : none + * notes : see ref [1],[7],[8] + * satellite clock includes relativity correction without code bias + * (tgd or bgd) + *-----------------------------------------------------------------------------*/ +extern void eph2pos(gtime_t time, const eph_t *eph, double *rs, double *dts, double *var) { + double tk, M, E, Ek, sinE, cosE, u, r, i, O, sin2u, cos2u, x, y, sinO, cosO, cosi, mu, omge; + double xg, yg, zg, sino, coso; + int n, sys, prn; + + char tstr[40]; + trace(4, "eph2pos : time=%s sat=%2d\n", time2str(time, tstr, 3), eph->sat); + + if (eph->A <= 0.0) { + rs[0] = rs[1] = rs[2] = *dts = *var = 0.0; + return; + } + tk = timediff(time, eph->toe); + + switch ((sys = satsys(eph->sat, &prn))) { + case SYS_GAL: + mu = MU_GAL; + omge = OMGE_GAL; + break; + case SYS_CMP: + mu = MU_CMP; + omge = OMGE_CMP; + break; + default: + mu = MU_GPS; + omge = OMGE; + break; + } + M = eph->M0 + (sqrt(mu / (eph->A * eph->A * eph->A)) + eph->deln) * tk; + + for (n = 0, E = M, Ek = 0.0; fabs(E - Ek) > RTOL_KEPLER && n < MAX_ITER_KEPLER; n++) { + Ek = E; + E -= (E - eph->e * sin(E) - M) / (1.0 - eph->e * cos(E)); + } + if (n >= MAX_ITER_KEPLER) { + trace(2, "eph2pos: kepler iteration overflow sat=%2d\n", eph->sat); + } + sinE = sin(E); + cosE = cos(E); + + trace(4, "kepler: sat=%2d e=%8.5f n=%2d del=%10.3e\n", eph->sat, eph->e, n, E - Ek); + + u = atan2(sqrt(1.0 - eph->e * eph->e) * sinE, cosE - eph->e) + eph->omg; + r = eph->A * (1.0 - eph->e * cosE); + i = eph->i0 + eph->idot * tk; + sin2u = sin(2.0 * u); + cos2u = cos(2.0 * u); + u += eph->cus * sin2u + eph->cuc * cos2u; + r += eph->crs * sin2u + eph->crc * cos2u; + i += eph->cis * sin2u + eph->cic * cos2u; + x = r * cos(u); + y = r * sin(u); + cosi = cos(i); + + /* beidou geo satellite */ + if (sys == SYS_CMP && (prn <= 5 || prn >= 59)) { /* ref [9] table 4-1 */ + O = eph->OMG0 + eph->OMGd * tk - omge * eph->toes; + sinO = sin(O); + cosO = cos(O); + xg = x * cosO - y * cosi * sinO; + yg = x * sinO + y * cosi * cosO; + zg = y * sin(i); + sino = sin(omge * tk); + coso = cos(omge * tk); + rs[0] = xg * coso + yg * sino * COS_5 + zg * sino * SIN_5; + rs[1] = -xg * sino + yg * coso * COS_5 + zg * coso * SIN_5; + rs[2] = -yg * SIN_5 + zg * COS_5; + } else { + O = eph->OMG0 + (eph->OMGd - omge) * tk - omge * eph->toes; + sinO = sin(O); + cosO = cos(O); + rs[0] = x * cosO - y * cosi * sinO; + rs[1] = x * sinO + y * cosi * cosO; + rs[2] = y * sin(i); + } + tk = timediff(time, eph->toc); + *dts = eph->f0 + eph->f1 * tk + eph->f2 * tk * tk; + + /* relativity correction */ + *dts -= 2.0 * sqrt(mu * eph->A) * eph->e * sinE / SQR(CLIGHT); + + /* position and clock error variance */ + *var = var_uraeph(sys, eph->sva); + trace(4, "eph2pos: sat=%d, dts=%.10f rs=%.4f %.4f %.4f var=%.3f\n", eph->sat, *dts, rs[0], rs[1], + rs[2], *var); } /* glonass orbit differential equations --------------------------------------*/ -static void deq(const double *x, double *xdot, const double *acc) -{ - double a,b,c,r2=dot3(x,x),r3=r2*sqrt(r2),omg2=SQR(OMGE_GLO); - - if (r2<=0.0) { - xdot[0]=xdot[1]=xdot[2]=xdot[3]=xdot[4]=xdot[5]=0.0; - return; - } - /* ref [2] A.3.1.2 with bug fix for xdot[4],xdot[5] */ - a=1.5*J2_GLO*MU_GLO*SQR(RE_GLO)/r2/r3; /* 3/2*J2*mu*Ae^2/r^5 */ - b=5.0*x[2]*x[2]/r2; /* 5*z^2/r^2 */ - c=-MU_GLO/r3-a*(1.0-b); /* -mu/r^3-a(1-b) */ - xdot[0]=x[3]; xdot[1]=x[4]; xdot[2]=x[5]; - xdot[3]=(c+omg2)*x[0]+2.0*OMGE_GLO*x[4]+acc[0]; - xdot[4]=(c+omg2)*x[1]-2.0*OMGE_GLO*x[3]+acc[1]; - xdot[5]=(c-2.0*a)*x[2]+acc[2]; +static void deq(const double *x, double *xdot, const double *acc) { + double a, b, c, r2 = dot3(x, x), r3 = r2 * sqrt(r2), omg2 = SQR(OMGE_GLO); + + if (r2 <= 0.0) { + xdot[0] = xdot[1] = xdot[2] = xdot[3] = xdot[4] = xdot[5] = 0.0; + return; + } + /* ref [2] A.3.1.2 with bug fix for xdot[4],xdot[5] */ + a = 1.5 * J2_GLO * MU_GLO * SQR(RE_GLO) / r2 / r3; /* 3/2*J2*mu*Ae^2/r^5 */ + b = 5.0 * x[2] * x[2] / r2; /* 5*z^2/r^2 */ + c = -MU_GLO / r3 - a * (1.0 - b); /* -mu/r^3-a(1-b) */ + xdot[0] = x[3]; + xdot[1] = x[4]; + xdot[2] = x[5]; + xdot[3] = (c + omg2) * x[0] + 2.0 * OMGE_GLO * x[4] + acc[0]; + xdot[4] = (c + omg2) * x[1] - 2.0 * OMGE_GLO * x[3] + acc[1]; + xdot[5] = (c - 2.0 * a) * x[2] + acc[2]; } /* glonass position and velocity by numerical integration --------------------*/ -static void glorbit(double t, double *x, const double *acc) -{ - double k1[6],k2[6],k3[6],k4[6],w[6]; - int i; - - deq(x,k1,acc); for (i=0;i<6;i++) w[i]=x[i]+k1[i]*t/2.0; - deq(w,k2,acc); for (i=0;i<6;i++) w[i]=x[i]+k2[i]*t/2.0; - deq(w,k3,acc); for (i=0;i<6;i++) w[i]=x[i]+k3[i]*t; - deq(w,k4,acc); - for (i=0;i<6;i++) x[i]+=(k1[i]+2.0*k2[i]+2.0*k3[i]+k4[i])*t/6.0; +static void glorbit(double t, double *x, const double *acc) { + double k1[6], k2[6], k3[6], k4[6], w[6]; + int i; + + deq(x, k1, acc); + for (i = 0; i < 6; i++) w[i] = x[i] + k1[i] * t / 2.0; + deq(w, k2, acc); + for (i = 0; i < 6; i++) w[i] = x[i] + k2[i] * t / 2.0; + deq(w, k3, acc); + for (i = 0; i < 6; i++) w[i] = x[i] + k3[i] * t; + deq(w, k4, acc); + for (i = 0; i < 6; i++) x[i] += (k1[i] + 2.0 * k2[i] + 2.0 * k3[i] + k4[i]) * t / 6.0; } /* glonass ephemeris to satellite clock bias ----------------------------------- -* compute satellite clock bias with glonass ephemeris -* args : gtime_t time I time by satellite clock (gpst) -* geph_t *geph I glonass ephemeris -* return : satellite clock bias (s) -* notes : see ref [2] -*-----------------------------------------------------------------------------*/ -extern double geph2clk(gtime_t time, const geph_t *geph) -{ - double t,ts; - int i; - - char tstr[40]; - trace(4,"geph2clk: time=%s sat=%2d\n",time2str(time,tstr,3),geph->sat); - - t=ts=timediff(time,geph->toe); - - for (i=0;i<2;i++) { - t=ts-(-geph->taun+geph->gamn*t); - } - trace(4,"geph2clk: t=%.12f ts=%.12f taun=%.12f gamn=%.12f\n",t,ts,geph->taun, - geph->gamn); - return -geph->taun+geph->gamn*t; + * compute satellite clock bias with glonass ephemeris + * args : gtime_t time I time by satellite clock (gpst) + * geph_t *geph I glonass ephemeris + * return : satellite clock bias (s) + * notes : see ref [2] + *-----------------------------------------------------------------------------*/ +extern double geph2clk(gtime_t time, const geph_t *geph) { + double t, ts; + int i; + + char tstr[40]; + trace(4, "geph2clk: time=%s sat=%2d\n", time2str(time, tstr, 3), geph->sat); + + t = ts = timediff(time, geph->toe); + + for (i = 0; i < 2; i++) { + t = ts - (-geph->taun + geph->gamn * t); + } + trace(4, "geph2clk: t=%.12f ts=%.12f taun=%.12f gamn=%.12f\n", t, ts, geph->taun, geph->gamn); + return -geph->taun + geph->gamn * t; } /* glonass ephemeris to satellite position and clock bias ---------------------- -* compute satellite position and clock bias with glonass ephemeris -* args : gtime_t time I time (gpst) -* geph_t *geph I glonass ephemeris -* double *rs O satellite position {x,y,z} (ecef) (m) -* double *dts O satellite clock bias (s) -* double *var O satellite position and clock variance (m^2) -* return : none -* notes : see ref [2] -*-----------------------------------------------------------------------------*/ -extern void geph2pos(gtime_t time, const geph_t *geph, double *rs, double *dts, - double *var) -{ - double t,tt,x[6]; - int i; - - char tstr[40]; - trace(4,"geph2pos: time=%s sat=%2d\n",time2str(time,tstr,3),geph->sat); - - t=timediff(time,geph->toe); - - *dts=-geph->taun+geph->gamn*t; - trace(4,"geph2pos: sat=%d\n",geph->sat); - - for (i=0;i<3;i++) { - x[i ]=geph->pos[i]; - x[i+3]=geph->vel[i]; - } - for (tt=t<0.0?-TSTEP:TSTEP;fabs(t)>1E-9;t-=tt) { - if (fabs(t)acc); - } - for (i=0;i<3;i++) rs[i]=x[i]; - - *var=SQR(ERREPH_GLO); + * compute satellite position and clock bias with glonass ephemeris + * args : gtime_t time I time (gpst) + * geph_t *geph I glonass ephemeris + * double *rs O satellite position {x,y,z} (ecef) (m) + * double *dts O satellite clock bias (s) + * double *var O satellite position and clock variance (m^2) + * return : none + * notes : see ref [2] + *-----------------------------------------------------------------------------*/ +extern void geph2pos(gtime_t time, const geph_t *geph, double *rs, double *dts, double *var) { + double t, tt, x[6]; + int i; + + char tstr[40]; + trace(4, "geph2pos: time=%s sat=%2d\n", time2str(time, tstr, 3), geph->sat); + + t = timediff(time, geph->toe); + + *dts = -geph->taun + geph->gamn * t; + trace(4, "geph2pos: sat=%d\n", geph->sat); + + for (i = 0; i < 3; i++) { + x[i] = geph->pos[i]; + x[i + 3] = geph->vel[i]; + } + for (tt = t < 0.0 ? -TSTEP : TSTEP; fabs(t) > 1E-9; t -= tt) { + if (fabs(t) < TSTEP) tt = t; + glorbit(tt, x, geph->acc); + } + for (i = 0; i < 3; i++) rs[i] = x[i]; + + *var = SQR(ERREPH_GLO); } /* sbas ephemeris to satellite clock bias -------------------------------------- -* compute satellite clock bias with sbas ephemeris -* args : gtime_t time I time by satellite clock (gpst) -* seph_t *seph I sbas ephemeris -* return : satellite clock bias (s) -* notes : see ref [3] -*-----------------------------------------------------------------------------*/ -extern double seph2clk(gtime_t time, const seph_t *seph) -{ - char tstr[40]; - trace(4,"seph2clk: time=%s sat=%2d\n",time2str(time,tstr,3),seph->sat); - - double ts = timediff(time, seph->t0), t = ts; - - for (int i = 0; i < 2; i++) { - t = ts - (seph->af0 + seph->af1 * t); - } - return seph->af0 + seph->af1 * t; + * compute satellite clock bias with sbas ephemeris + * args : gtime_t time I time by satellite clock (gpst) + * seph_t *seph I sbas ephemeris + * return : satellite clock bias (s) + * notes : see ref [3] + *-----------------------------------------------------------------------------*/ +extern double seph2clk(gtime_t time, const seph_t *seph) { + char tstr[40]; + trace(4, "seph2clk: time=%s sat=%2d\n", time2str(time, tstr, 3), seph->sat); + + double ts = timediff(time, seph->t0), t = ts; + + for (int i = 0; i < 2; i++) { + t = ts - (seph->af0 + seph->af1 * t); + } + return seph->af0 + seph->af1 * t; } /* sbas ephemeris to satellite position and clock bias ------------------------- -* compute satellite position and clock bias with sbas ephemeris -* args : gtime_t time I time (gpst) -* seph_t *seph I sbas ephemeris -* double *rs O satellite position {x,y,z} (ecef) (m) -* double *dts O satellite clock bias (s) -* double *var O satellite position and clock variance (m^2) -* return : none -* notes : see ref [3] -*-----------------------------------------------------------------------------*/ -extern void seph2pos(gtime_t time, const seph_t *seph, double *rs, double *dts, - double *var) -{ - double t; - int i; - - char tstr[40]; - trace(4,"seph2pos: time=%s sat=%2d\n",time2str(time,tstr,3),seph->sat); - - t=timediff(time,seph->t0); - - for (i=0;i<3;i++) { - rs[i]=seph->pos[i]+seph->vel[i]*t+seph->acc[i]*t*t/2.0; - } - *dts=seph->af0+seph->af1*t; - - *var=var_uraeph(SYS_SBS,seph->sva); + * compute satellite position and clock bias with sbas ephemeris + * args : gtime_t time I time (gpst) + * seph_t *seph I sbas ephemeris + * double *rs O satellite position {x,y,z} (ecef) (m) + * double *dts O satellite clock bias (s) + * double *var O satellite position and clock variance (m^2) + * return : none + * notes : see ref [3] + *-----------------------------------------------------------------------------*/ +extern void seph2pos(gtime_t time, const seph_t *seph, double *rs, double *dts, double *var) { + double t; + int i; + + char tstr[40]; + trace(4, "seph2pos: time=%s sat=%2d\n", time2str(time, tstr, 3), seph->sat); + + t = timediff(time, seph->t0); + + for (i = 0; i < 3; i++) { + rs[i] = seph->pos[i] + seph->vel[i] * t + seph->acc[i] * t * t / 2.0; + } + *dts = seph->af0 + seph->af1 * t; + + *var = var_uraeph(SYS_SBS, seph->sva); } /* select ephemeris --------------------------------------------------------*/ -static eph_t *seleph(gtime_t time, int sat, int iode, const nav_t *nav) -{ - double t,tmax,tmin; - int i,j=-1,sys,sel=0; - - char tstr[40]; - trace(4,"seleph : time=%s sat=%2d iode=%d\n",time2str(time,tstr,3),sat,iode); - - sys=satsys(sat,NULL); - switch (sys) { - case SYS_GPS: tmax=MAXDTOE+1.0 ; sel=eph_sel[0]; break; - case SYS_GAL: tmax=MAXDTOE_GAL ; sel=eph_sel[2]; break; - case SYS_QZS: tmax=MAXDTOE_QZS+1.0; sel=eph_sel[3]; break; - case SYS_CMP: tmax=MAXDTOE_CMP+1.0; sel=eph_sel[4]; break; - case SYS_IRN: tmax=MAXDTOE_IRN+1.0; sel=eph_sel[5]; break; - default: tmax=MAXDTOE+1.0; break; - } - tmin=tmax+1.0; - - for (i=0;in;i++) { - if (nav->eph[i].sat!=sat) continue; - if (iode>=0&&nav->eph[i].iode!=iode) continue; - if (sys==SYS_GAL) { - sel=getseleph(SYS_GAL); - /* this code is from 2.4.3 b34 but does not seem to be fully supported, - so for now I have dropped back to the b33 code */ - /* if (sel==0&&!(nav->eph[i].code&(1<<9))) continue; */ /* I/NAV */ - /*if (sel==1&&!(nav->eph[i].code&(1<<8))) continue; */ /* F/NAV */ - if (sel==1&&!(nav->eph[i].code&(1<<9))) continue; /* I/NAV */ - if (sel==2&&!(nav->eph[i].code&(1<<8))) continue; /* F/NAV */ - if (timediff(nav->eph[i].toe,time)>=0.0) continue; /* AOD<=0 */ - } - if ((t=fabs(timediff(nav->eph[i].toe,time)))>tmax) continue; - if (iode>=0) return nav->eph+i; - if (t<=tmin) {j=i; tmin=t;} /* toe closest to time */ - } - if (iode>=0||j<0) { - trace(2,"no broadcast ephemeris: %s sat=%2d iode=%3d\n",time2str(time,tstr,0), - sat,iode); - return NULL; - } - trace(4,"seleph: sat=%d dt=%.0f\n",sat,tmin); - return nav->eph+j; +static eph_t *seleph(gtime_t time, int sat, int iode, const nav_t *nav) { + double t, tmax, tmin; + int i, j = -1, sys, sel = 0; + + char tstr[40]; + trace(4, "seleph : time=%s sat=%2d iode=%d\n", time2str(time, tstr, 3), sat, iode); + + sys = satsys(sat, NULL); + switch (sys) { + case SYS_GPS: + tmax = MAXDTOE + 1.0; + sel = eph_sel[0]; + break; + case SYS_GAL: + tmax = MAXDTOE_GAL; + sel = eph_sel[2]; + break; + case SYS_QZS: + tmax = MAXDTOE_QZS + 1.0; + sel = eph_sel[3]; + break; + case SYS_CMP: + tmax = MAXDTOE_CMP + 1.0; + sel = eph_sel[4]; + break; + case SYS_IRN: + tmax = MAXDTOE_IRN + 1.0; + sel = eph_sel[5]; + break; + default: + tmax = MAXDTOE + 1.0; + break; + } + tmin = tmax + 1.0; + + for (i = 0; i < nav->n; i++) { + if (nav->eph[i].sat != sat) continue; + if (iode >= 0 && nav->eph[i].iode != iode) continue; + if (sys == SYS_GAL) { + sel = getseleph(SYS_GAL); + /* this code is from 2.4.3 b34 but does not seem to be fully supported, + so for now I have dropped back to the b33 code */ + /* if (sel==0&&!(nav->eph[i].code&(1<<9))) continue; */ /* I/NAV */ + /*if (sel==1&&!(nav->eph[i].code&(1<<8))) continue; */ /* F/NAV */ + if (sel == 1 && !(nav->eph[i].code & (1 << 9))) continue; /* I/NAV */ + if (sel == 2 && !(nav->eph[i].code & (1 << 8))) continue; /* F/NAV */ + if (timediff(nav->eph[i].toe, time) >= 0.0) continue; /* AOD<=0 */ + } + if ((t = fabs(timediff(nav->eph[i].toe, time))) > tmax) continue; + if (iode >= 0) return nav->eph + i; + if (t <= tmin) { + j = i; + tmin = t; + } /* toe closest to time */ + } + if (iode >= 0 || j < 0) { + trace(2, "no broadcast ephemeris: %s sat=%2d iode=%3d\n", time2str(time, tstr, 0), sat, iode); + return NULL; + } + trace(4, "seleph: sat=%d dt=%.0f\n", sat, tmin); + return nav->eph + j; } /* select glonass ephemeris --------------------------------------------------*/ -static geph_t *selgeph(gtime_t time, int sat, int iode, const nav_t *nav) -{ - double t,tmax=MAXDTOE_GLO,tmin=tmax+1.0; - int i,j=-1; - - char tstr[40]; - trace(4,"selgeph : time=%s sat=%2d iode=%2d\n",time2str(time,tstr,3),sat,iode); - - for (i=0;ing;i++) { - if (nav->geph[i].sat!=sat) continue; - if (iode>=0&&nav->geph[i].iode!=iode) continue; - if ((t=fabs(timediff(nav->geph[i].toe,time)))>tmax) continue; - if (iode>=0) return nav->geph+i; - if (t<=tmin) {j=i; tmin=t;} /* toe closest to time */ - } - if (iode>=0||j<0) { - trace(3,"no glonass ephemeris : %s sat=%2d iode=%2d\n",time2str(time,tstr,0), - sat,iode); - return NULL; - } - trace(4,"selgeph: sat=%d dt=%.0f\n",sat,tmin); - return nav->geph+j; +static geph_t *selgeph(gtime_t time, int sat, int iode, const nav_t *nav) { + double t, tmax = MAXDTOE_GLO, tmin = tmax + 1.0; + int i, j = -1; + + char tstr[40]; + trace(4, "selgeph : time=%s sat=%2d iode=%2d\n", time2str(time, tstr, 3), sat, iode); + + for (i = 0; i < nav->ng; i++) { + if (nav->geph[i].sat != sat) continue; + if (iode >= 0 && nav->geph[i].iode != iode) continue; + if ((t = fabs(timediff(nav->geph[i].toe, time))) > tmax) continue; + if (iode >= 0) return nav->geph + i; + if (t <= tmin) { + j = i; + tmin = t; + } /* toe closest to time */ + } + if (iode >= 0 || j < 0) { + trace(3, "no glonass ephemeris : %s sat=%2d iode=%2d\n", time2str(time, tstr, 0), sat, iode); + return NULL; + } + trace(4, "selgeph: sat=%d dt=%.0f\n", sat, tmin); + return nav->geph + j; } /* select sbas ephemeris -----------------------------------------------------*/ -static seph_t *selseph(gtime_t time, int sat, const nav_t *nav) -{ - double t,tmax=MAXDTOE_SBS,tmin=tmax+1.0; - int i,j=-1; - - char tstr[40]; - trace(4,"selseph : time=%s sat=%2d\n",time2str(time,tstr,3),sat); - - for (i=0;ins;i++) { - if (nav->seph[i].sat!=sat) continue; - if ((t=fabs(timediff(nav->seph[i].t0,time)))>tmax) continue; - if (t<=tmin) {j=i; tmin=t;} /* toe closest to time */ - } - if (j<0) { - trace(3,"no sbas ephemeris : %s sat=%2d\n",time2str(time,tstr,0),sat); - return NULL; - } - return nav->seph+j; +static seph_t *selseph(gtime_t time, int sat, const nav_t *nav) { + double t, tmax = MAXDTOE_SBS, tmin = tmax + 1.0; + int i, j = -1; + + char tstr[40]; + trace(4, "selseph : time=%s sat=%2d\n", time2str(time, tstr, 3), sat); + + for (i = 0; i < nav->ns; i++) { + if (nav->seph[i].sat != sat) continue; + if ((t = fabs(timediff(nav->seph[i].t0, time))) > tmax) continue; + if (t <= tmin) { + j = i; + tmin = t; + } /* toe closest to time */ + } + if (j < 0) { + trace(3, "no sbas ephemeris : %s sat=%2d\n", time2str(time, tstr, 0), sat); + return NULL; + } + return nav->seph + j; } /* satellite clock with broadcast ephemeris ----------------------------------*/ -static int ephclk(gtime_t time, gtime_t teph, int sat, const nav_t *nav, - double *dts) -{ - eph_t *eph; - geph_t *geph; - seph_t *seph; - int sys; - - char tstr[40]; - trace(4,"ephclk : time=%s sat=%2d\n",time2str(time,tstr,3),sat); - - sys=satsys(sat,NULL); - - if (sys==SYS_GPS||sys==SYS_GAL||sys==SYS_QZS||sys==SYS_CMP||sys==SYS_IRN) { - if (!(eph=seleph(teph,sat,-1,nav))) return 0; - *dts=eph2clk(time,eph); - } - else if (sys==SYS_GLO) { - if (!(geph=selgeph(teph,sat,-1,nav))) return 0; - if (fabs(geph->taun) > 1) return 0; /* reject invalid data to prevent fp error */ - *dts=geph2clk(time,geph); - } - else if (sys==SYS_SBS) { - if (!(seph=selseph(teph,sat,nav))) return 0; - *dts=seph2clk(time,seph); - } - else return 0; +static int ephclk(gtime_t time, gtime_t teph, int sat, const nav_t *nav, double *dts) { + eph_t *eph; + geph_t *geph; + seph_t *seph; + int sys; + + char tstr[40]; + trace(4, "ephclk : time=%s sat=%2d\n", time2str(time, tstr, 3), sat); + + sys = satsys(sat, NULL); + + if (sys == SYS_GPS || sys == SYS_GAL || sys == SYS_QZS || sys == SYS_CMP || sys == SYS_IRN) { + if (!(eph = seleph(teph, sat, -1, nav))) return 0; + *dts = eph2clk(time, eph); + } else if (sys == SYS_GLO) { + if (!(geph = selgeph(teph, sat, -1, nav))) return 0; + if (fabs(geph->taun) > 1) return 0; /* reject invalid data to prevent fp error */ + *dts = geph2clk(time, geph); + } else if (sys == SYS_SBS) { + if (!(seph = selseph(teph, sat, nav))) return 0; + *dts = seph2clk(time, seph); + } else + return 0; - return 1; + return 1; } /* satellite position and clock by broadcast ephemeris -----------------------*/ -static int ephpos(gtime_t time, gtime_t teph, int sat, const nav_t *nav, - int iode, double *rs, double *dts, double *var, int *svh) -{ - eph_t *eph; - geph_t *geph; - seph_t *seph; - double rst[3],dtst[1],tt=1E-3; - int i,sys; - - char tstr[40]; - trace(4,"ephpos : time=%s sat=%2d iode=%d\n",time2str(time,tstr,3),sat,iode); - - sys=satsys(sat,NULL); - - *svh=-1; - - if (sys==SYS_GPS||sys==SYS_GAL||sys==SYS_QZS||sys==SYS_CMP||sys==SYS_IRN) { - if (!(eph=seleph(teph,sat,iode,nav))) return 0; - eph2pos(time,eph,rs,dts,var); - time=timeadd(time,tt); - eph2pos(time,eph,rst,dtst,var); - *svh=eph->svh; - } - else if (sys==SYS_GLO) { - if (!(geph=selgeph(teph,sat,iode,nav))) return 0; - geph2pos(time,geph,rs,dts,var); - time=timeadd(time,tt); - geph2pos(time,geph,rst,dtst,var); - *svh=geph->svh; - } - else if (sys==SYS_SBS) { - if (!(seph=selseph(teph,sat,nav))) return 0; - seph2pos(time,seph,rs,dts,var); - time=timeadd(time,tt); - seph2pos(time,seph,rst,dtst,var); - *svh=seph->svh; - } - else return 0; +static int ephpos(gtime_t time, gtime_t teph, int sat, const nav_t *nav, int iode, double *rs, + double *dts, double *var, int *svh) { + eph_t *eph; + geph_t *geph; + seph_t *seph; + double rst[3], dtst[1], tt = 1E-3; + int i, sys; + + char tstr[40]; + trace(4, "ephpos : time=%s sat=%2d iode=%d\n", time2str(time, tstr, 3), sat, iode); + + sys = satsys(sat, NULL); + + *svh = -1; + + if (sys == SYS_GPS || sys == SYS_GAL || sys == SYS_QZS || sys == SYS_CMP || sys == SYS_IRN) { + if (!(eph = seleph(teph, sat, iode, nav))) return 0; + eph2pos(time, eph, rs, dts, var); + time = timeadd(time, tt); + eph2pos(time, eph, rst, dtst, var); + *svh = eph->svh; + } else if (sys == SYS_GLO) { + if (!(geph = selgeph(teph, sat, iode, nav))) return 0; + geph2pos(time, geph, rs, dts, var); + time = timeadd(time, tt); + geph2pos(time, geph, rst, dtst, var); + *svh = geph->svh; + } else if (sys == SYS_SBS) { + if (!(seph = selseph(teph, sat, nav))) return 0; + seph2pos(time, seph, rs, dts, var); + time = timeadd(time, tt); + seph2pos(time, seph, rst, dtst, var); + *svh = seph->svh; + } else + return 0; - /* satellite velocity and clock drift by differential approx */ - for (i=0;i<3;i++) rs[i+3]=(rst[i]-rs[i])/tt; - dts[1]=(dtst[0]-dts[0])/tt; + /* satellite velocity and clock drift by differential approx */ + for (i = 0; i < 3; i++) rs[i + 3] = (rst[i] - rs[i]) / tt; + dts[1] = (dtst[0] - dts[0]) / tt; - return 1; + return 1; } /* satellite position and clock with sbas correction -------------------------*/ -static int satpos_sbas(gtime_t time, gtime_t teph, int sat, const nav_t *nav, - double *rs, double *dts, double *var, int *svh) -{ - const sbssatp_t *sbs=NULL; - int i; - - char tstr[40]; - trace(4,"satpos_sbas: time=%s sat=%2d\n",time2str(time,tstr,3),sat); - - /* search sbas satellite correction */ - for (i=0;isbssat.nsat;i++) { - sbs=nav->sbssat.sat+i; - if (sbs->sat==sat) break; - } - if (i>=nav->sbssat.nsat) { - trace(2,"no sbas, use brdcast: %s sat=%2d\n",time2str(time,tstr,0),sat); - if (!ephpos(time,teph,sat,nav,-1,rs,dts,var,svh)) return 0; - /* *svh=-1; */ /* use broadcast if no sbas */ - return 1; - } - /* satellite position and clock by broadcast ephemeris */ - if (!ephpos(time,teph,sat,nav,sbs->lcorr.iode,rs,dts,var,svh)) return 0; - - /* sbas satellite correction (long term and fast) */ - if (sbssatcorr(time,sat,nav,rs,dts,var)) return 1; - *svh=-1; - return 0; +static int satpos_sbas(gtime_t time, gtime_t teph, int sat, const nav_t *nav, double *rs, + double *dts, double *var, int *svh) { + const sbssatp_t *sbs = NULL; + int i; + + char tstr[40]; + trace(4, "satpos_sbas: time=%s sat=%2d\n", time2str(time, tstr, 3), sat); + + /* search sbas satellite correction */ + for (i = 0; i < nav->sbssat.nsat; i++) { + sbs = nav->sbssat.sat + i; + if (sbs->sat == sat) break; + } + if (i >= nav->sbssat.nsat) { + trace(2, "no sbas, use brdcast: %s sat=%2d\n", time2str(time, tstr, 0), sat); + if (!ephpos(time, teph, sat, nav, -1, rs, dts, var, svh)) return 0; + /* *svh=-1; */ /* use broadcast if no sbas */ + return 1; + } + /* satellite position and clock by broadcast ephemeris */ + if (!ephpos(time, teph, sat, nav, sbs->lcorr.iode, rs, dts, var, svh)) return 0; + + /* sbas satellite correction (long term and fast) */ + if (sbssatcorr(time, sat, nav, rs, dts, var)) return 1; + *svh = -1; + return 0; } /* satellite position and clock with ssr correction --------------------------*/ -static int satpos_ssr(gtime_t time, gtime_t teph, int sat, const nav_t *nav, - int opt, double *rs, double *dts, double *var, int *svh) -{ - const ssr_t *ssr; - eph_t *eph; - double t1,t2,t3,er[3],ea[3],ec[3],rc[3],deph[3],dclk,dant[3]={0},tk; - int i,sys; - - char tstr[40]; - trace(4,"satpos_ssr: time=%s sat=%2d\n",time2str(time,tstr,3),sat); - - ssr=nav->ssr+sat-1; - - if (!ssr->t0[0].time) { - trace(2,"no ssr orbit correction: %s sat=%2d\n",time2str(time,tstr,0),sat); - return 0; - } - if (!ssr->t0[1].time) { - trace(2,"no ssr clock correction: %s sat=%2d\n",time2str(time,tstr,0),sat); - return 0; - } - /* inconsistency between orbit and clock correction */ - if (ssr->iod[0]!=ssr->iod[1]) { - trace(2,"inconsist ssr correction: %s sat=%2d iod=%d %d\n", - time2str(time,tstr,0),sat,ssr->iod[0],ssr->iod[1]); - *svh=-1; - return 0; - } - t1=timediff(time,ssr->t0[0]); - t2=timediff(time,ssr->t0[1]); - t3=timediff(time,ssr->t0[2]); - - /* ssr orbit and clock correction (ref [4]) */ - if (fabs(t1)>MAXAGESSR||fabs(t2)>MAXAGESSR) { - trace(2,"age of ssr error: %s sat=%2d t=%.0f %.0f\n",time2str(time,tstr,0), - sat,t1,t2); - *svh=-1; - return 0; - } - if (ssr->udi[0]>=1.0) t1-=ssr->udi[0]/2.0; - if (ssr->udi[1]>=1.0) t2-=ssr->udi[1]/2.0; - - for (i=0;i<3;i++) deph[i]=ssr->deph[i]+ssr->ddeph[i]*t1; - dclk=ssr->dclk[0]+ssr->dclk[1]*t2+ssr->dclk[2]*t2*t2; +static int satpos_ssr(gtime_t time, gtime_t teph, int sat, const nav_t *nav, int opt, double *rs, + double *dts, double *var, int *svh) { + const ssr_t *ssr; + eph_t *eph; + double t1, t2, t3, er[3], ea[3], ec[3], rc[3], deph[3], dclk, dant[3] = {0}, tk; + int i, sys; - /* ssr highrate clock correction (ref [4]) */ - if (ssr->iod[0]==ssr->iod[2]&&ssr->t0[2].time&&fabs(t3)hrclk; - } - if (norm(deph,3)>MAXECORSSR||fabs(dclk)>MAXCCORSSR) { - trace(3,"invalid ssr correction: %s deph=%.1f dclk=%.1f\n", - time2str(time,tstr,0),norm(deph,3),dclk); - *svh=-1; - return 0; - } - /* satellite position and clock by broadcast ephemeris */ - if (!ephpos(time,teph,sat,nav,ssr->iode,rs,dts,var,svh)) return 0; - - /* satellite clock for gps, galileo and qzss */ - sys=satsys(sat,NULL); - if (sys==SYS_GPS||sys==SYS_GAL||sys==SYS_QZS||sys==SYS_CMP) { - if (!(eph=seleph(teph,sat,ssr->iode,nav))) return 0; + char tstr[40]; + trace(4, "satpos_ssr: time=%s sat=%2d\n", time2str(time, tstr, 3), sat); - /* satellite clock by clock parameters */ - tk=timediff(time,eph->toc); - dts[0]=eph->f0+eph->f1*tk+eph->f2*tk*tk; - dts[1]=eph->f1+2.0*eph->f2*tk; - - /* relativity correction */ - dts[0]-=2.0*dot3(rs,rs+3)/CLIGHT/CLIGHT; - } - /* radial-along-cross directions in ecef */ - if (!normv3(rs+3,ea)) return 0; - cross3(rs,rs+3,rc); - if (!normv3(rc,ec)) { - *svh=-1; - return 0; - } - cross3(ea,ec,er); + ssr = nav->ssr + sat - 1; - /* satellite antenna offset correction */ - if (opt) { - satantoff(time,rs,sat,nav,dant); - } - for (i=0;i<3;i++) { - rs[i]+=-(er[i]*deph[0]+ea[i]*deph[1]+ec[i]*deph[2])+dant[i]; - } - /* t_corr = t_sv - (dts(brdc) + dclk(ssr) / CLIGHT) (ref [10] eq.3.12-7) */ - dts[0]+=dclk/CLIGHT; + if (!ssr->t0[0].time) { + trace(2, "no ssr orbit correction: %s sat=%2d\n", time2str(time, tstr, 0), sat); + return 0; + } + if (!ssr->t0[1].time) { + trace(2, "no ssr clock correction: %s sat=%2d\n", time2str(time, tstr, 0), sat); + return 0; + } + /* inconsistency between orbit and clock correction */ + if (ssr->iod[0] != ssr->iod[1]) { + trace(2, "inconsist ssr correction: %s sat=%2d iod=%d %d\n", time2str(time, tstr, 0), sat, + ssr->iod[0], ssr->iod[1]); + *svh = -1; + return 0; + } + t1 = timediff(time, ssr->t0[0]); + t2 = timediff(time, ssr->t0[1]); + t3 = timediff(time, ssr->t0[2]); + + /* ssr orbit and clock correction (ref [4]) */ + if (fabs(t1) > MAXAGESSR || fabs(t2) > MAXAGESSR) { + trace(2, "age of ssr error: %s sat=%2d t=%.0f %.0f\n", time2str(time, tstr, 0), sat, t1, t2); + *svh = -1; + return 0; + } + if (ssr->udi[0] >= 1.0) t1 -= ssr->udi[0] / 2.0; + if (ssr->udi[1] >= 1.0) t2 -= ssr->udi[1] / 2.0; + + for (i = 0; i < 3; i++) deph[i] = ssr->deph[i] + ssr->ddeph[i] * t1; + dclk = ssr->dclk[0] + ssr->dclk[1] * t2 + ssr->dclk[2] * t2 * t2; + + /* ssr highrate clock correction (ref [4]) */ + if (ssr->iod[0] == ssr->iod[2] && ssr->t0[2].time && fabs(t3) < MAXAGESSR_HRCLK) { + dclk += ssr->hrclk; + } + if (norm(deph, 3) > MAXECORSSR || fabs(dclk) > MAXCCORSSR) { + trace(3, "invalid ssr correction: %s deph=%.1f dclk=%.1f\n", time2str(time, tstr, 0), + norm(deph, 3), dclk); + *svh = -1; + return 0; + } + /* satellite position and clock by broadcast ephemeris */ + if (!ephpos(time, teph, sat, nav, ssr->iode, rs, dts, var, svh)) return 0; - /* variance by ssr ura */ - *var=var_urassr(ssr->ura); + /* satellite clock for gps, galileo and qzss */ + sys = satsys(sat, NULL); + if (sys == SYS_GPS || sys == SYS_GAL || sys == SYS_QZS || sys == SYS_CMP) { + if (!(eph = seleph(teph, sat, ssr->iode, nav))) return 0; - trace(5,"satpos_ssr: %s sat=%2d deph=%6.3f %6.3f %6.3f er=%6.3f %6.3f %6.3f dclk=%6.3f var=%6.3f\n", - time2str(time,tstr,2),sat,deph[0],deph[1],deph[2],er[0],er[1],er[2],dclk,*var); + /* satellite clock by clock parameters */ + tk = timediff(time, eph->toc); + dts[0] = eph->f0 + eph->f1 * tk + eph->f2 * tk * tk; + dts[1] = eph->f1 + 2.0 * eph->f2 * tk; - return 1; + /* relativity correction */ + dts[0] -= 2.0 * dot3(rs, rs + 3) / CLIGHT / CLIGHT; + } + /* radial-along-cross directions in ecef */ + if (!normv3(rs + 3, ea)) return 0; + cross3(rs, rs + 3, rc); + if (!normv3(rc, ec)) { + *svh = -1; + return 0; + } + cross3(ea, ec, er); + + /* satellite antenna offset correction */ + if (opt) { + satantoff(time, rs, sat, nav, dant); + } + for (i = 0; i < 3; i++) { + rs[i] += -(er[i] * deph[0] + ea[i] * deph[1] + ec[i] * deph[2]) + dant[i]; + } + /* t_corr = t_sv - (dts(brdc) + dclk(ssr) / CLIGHT) (ref [10] eq.3.12-7) */ + dts[0] += dclk / CLIGHT; + + /* variance by ssr ura */ + *var = var_urassr(ssr->ura); + + trace(5, + "satpos_ssr: %s sat=%2d deph=%6.3f %6.3f %6.3f er=%6.3f %6.3f %6.3f dclk=%6.3f var=%6.3f\n", + time2str(time, tstr, 2), sat, deph[0], deph[1], deph[2], er[0], er[1], er[2], dclk, *var); + + return 1; } /* satellite position and clock ------------------------------------------------ -* compute satellite position, velocity and clock -* args : gtime_t time I time (gpst) -* gtime_t teph I time to select ephemeris (gpst) -* int sat I satellite number -* int ephopt I ephemeris option (EPHOPT_???) -* nav_t *nav I navigation data -* double *rs O sat position and velocity (ecef) -* {x,y,z,vx,vy,vz} (m|m/s) -* double *dts O sat clock {bias,drift} (s|s/s) -* double *var O sat position and clock error variance (m^2) -* int *svh O sat health flag (-1:correction not available) -* return : status (1:ok,0:error) -* notes : satellite position is referenced to antenna phase center -* satellite clock does not include code bias correction (tgd or bgd) -*-----------------------------------------------------------------------------*/ -extern int satpos(gtime_t time, gtime_t teph, int sat, int ephopt, - const nav_t *nav, double *rs, double *dts, double *var, - int *svh) -{ - char tstr[40]; - trace(4,"satpos : time=%s sat=%2d ephopt=%d\n",time2str(time,tstr,3),sat,ephopt); - - *svh=0; - - switch (ephopt) { - case EPHOPT_BRDC : return ephpos (time,teph,sat,nav,-1,rs,dts,var,svh); - case EPHOPT_SBAS : return satpos_sbas(time,teph,sat,nav, rs,dts,var,svh); - case EPHOPT_SSRAPC: return satpos_ssr (time,teph,sat,nav, 0,rs,dts,var,svh); - case EPHOPT_SSRCOM: return satpos_ssr (time,teph,sat,nav, 1,rs,dts,var,svh); - case EPHOPT_PREC : - if (!peph2pos(time,sat,nav,1,rs,dts,var)) break; else return 1; - } - *svh=-1; - return 0; + * compute satellite position, velocity and clock + * args : gtime_t time I time (gpst) + * gtime_t teph I time to select ephemeris (gpst) + * int sat I satellite number + * int ephopt I ephemeris option (EPHOPT_???) + * nav_t *nav I navigation data + * double *rs O sat position and velocity (ecef) + * {x,y,z,vx,vy,vz} (m|m/s) + * double *dts O sat clock {bias,drift} (s|s/s) + * double *var O sat position and clock error variance (m^2) + * int *svh O sat health flag (-1:correction not available) + * return : status (1:ok,0:error) + * notes : satellite position is referenced to antenna phase center + * satellite clock does not include code bias correction (tgd or bgd) + *-----------------------------------------------------------------------------*/ +extern int satpos(gtime_t time, gtime_t teph, int sat, int ephopt, const nav_t *nav, double *rs, + double *dts, double *var, int *svh) { + char tstr[40]; + trace(4, "satpos : time=%s sat=%2d ephopt=%d\n", time2str(time, tstr, 3), sat, ephopt); + + *svh = 0; + + switch (ephopt) { + case EPHOPT_BRDC: + return ephpos(time, teph, sat, nav, -1, rs, dts, var, svh); + case EPHOPT_SBAS: + return satpos_sbas(time, teph, sat, nav, rs, dts, var, svh); + case EPHOPT_SSRAPC: + return satpos_ssr(time, teph, sat, nav, 0, rs, dts, var, svh); + case EPHOPT_SSRCOM: + return satpos_ssr(time, teph, sat, nav, 1, rs, dts, var, svh); + case EPHOPT_PREC: + if (!peph2pos(time, sat, nav, 1, rs, dts, var)) + break; + else + return 1; + } + *svh = -1; + return 0; } /* satellite positions and clocks ---------------------------------------------- -* compute satellite positions, velocities and clocks -* args : gtime_t teph I time to select ephemeris (gpst) -* obsd_t *obs I observation data -* int n I number of observation data -* nav_t *nav I navigation data -* int ephopt I ephemeris option (EPHOPT_???) -* double *rs O satellite positions and velocities (ecef) -* double *dts O satellite clocks -* double *var O sat position and clock error variances (m^2) -* int *svh O sat health flag (-1:correction not available) -* return : none -* notes : rs [(0:2)+i*6]= obs[i] sat position {x,y,z} (m) -* rs [(3:5)+i*6]= obs[i] sat velocity {vx,vy,vz} (m/s) -* dts[(0:1)+i*2]= obs[i] sat clock {bias,drift} (s|s/s) -* var[i] = obs[i] sat position and clock error variance (m^2) -* svh[i] = obs[i] sat health flag -* if no navigation data, set 0 to rs[], dts[], var[] and svh[] -* satellite position and clock are values at signal transmission time -* satellite position is referenced to antenna phase center -* satellite clock does not include code bias correction (tgd or bgd) -* any pseudorange and broadcast ephemeris are always needed to get -* signal transmission time -*-----------------------------------------------------------------------------*/ -extern void satposs(gtime_t teph, const obsd_t *obs, int n, const nav_t *nav, - int ephopt, double *rs, double *dts, double *var, int *svh) -{ - gtime_t time[2*MAXOBS]={{0}}; - double dt,pr; - int i,j; - - char tstr[40]; - trace(3,"satposs : teph=%s n=%d ephopt=%d\n",time2str(teph,tstr,3),n,ephopt); - - for (i=0;i=NFREQ) { - trace(2,"no pseudorange %s sat=%2d\n",time2str(obs[i].time,tstr,3),obs[i].sat); - continue; - } - /* transmission time by satellite clock */ - time[i]=timeadd(obs[i].time,-pr/CLIGHT); - - /* satellite clock bias by broadcast ephemeris */ - if (!ephclk(time[i],teph,obs[i].sat,nav,&dt)) { - trace(3,"no broadcast clock %s sat=%2d\n",time2str(time[i],tstr,3),obs[i].sat); - continue; - } - time[i]=timeadd(time[i],-dt); - - /* satellite position and clock at transmission time */ - if (!satpos(time[i],teph,obs[i].sat,ephopt,nav,rs+i*6,dts+i*2,var+i, - svh+i)) { - trace(3,"no ephemeris %s sat=%2d\n",time2str(time[i],tstr,3),obs[i].sat); - continue; - } - /* if no precise clock available, use broadcast clock instead */ - if (dts[i*2]==0.0) { - if (!ephclk(time[i],teph,obs[i].sat,nav,dts+i*2)) continue; - dts[1+i*2]=0.0; - *var=SQR(STD_BRDCCLK); - } - trace(4,"satposs: %d,time=%.9f dt=%.9f pr=%.3f rs=%13.3f %13.3f %13.3f dts=%12.3f var=%7.3f\n", - obs[i].sat,time[i].sec,dt,pr,rs[i*6],rs[1+i*6],rs[2+i*6],dts[i*2]*1E9, - var[i]); - - } - for (i=0;i= NFREQ) { + trace(2, "no pseudorange %s sat=%2d\n", time2str(obs[i].time, tstr, 3), obs[i].sat); + continue; + } + /* transmission time by satellite clock */ + time[i] = timeadd(obs[i].time, -pr / CLIGHT); + + /* satellite clock bias by broadcast ephemeris */ + if (!ephclk(time[i], teph, obs[i].sat, nav, &dt)) { + trace(3, "no broadcast clock %s sat=%2d\n", time2str(time[i], tstr, 3), obs[i].sat); + continue; + } + time[i] = timeadd(time[i], -dt); + + /* satellite position and clock at transmission time */ + if (!satpos(time[i], teph, obs[i].sat, ephopt, nav, rs + i * 6, dts + i * 2, var + i, + svh + i)) { + trace(3, "no ephemeris %s sat=%2d\n", time2str(time[i], tstr, 3), obs[i].sat); + continue; + } + /* if no precise clock available, use broadcast clock instead */ + if (dts[i * 2] == 0.0) { + if (!ephclk(time[i], teph, obs[i].sat, nav, dts + i * 2)) continue; + dts[1 + i * 2] = 0.0; + *var = SQR(STD_BRDCCLK); + } + trace(4, "satposs: %d,time=%.9f dt=%.9f pr=%.3f rs=%13.3f %13.3f %13.3f dts=%12.3f var=%7.3f\n", + obs[i].sat, time[i].sec, dt, pr, rs[i * 6], rs[1 + i * 6], rs[2 + i * 6], + dts[i * 2] * 1E9, var[i]); + } + for (i = 0; i < n && i < 2 * MAXOBS; i++) { + trace(4, "%s sat=%2d rs=%13.3f %13.3f %13.3f dts=%12.3f var=%7.3f svh=%02X\n", + time2str(time[i], tstr, 9), obs[i].sat, rs[i * 6], rs[1 + i * 6], rs[2 + i * 6], + dts[i * 2] * 1E9, var[i], svh[i]); + } } /* set selected satellite ephemeris -------------------------------------------- -* Set selected satellite ephemeris for multiple ones like LNAV - CNAV, I/NAV - -* F/NAV. Call it before calling satpos(),satposs() to use unselected one. -* args : int sys I satellite system (SYS_???) -* int sel I selection of ephemeris -* GPS,QZS : 0:LNAV ,1:CNAV (default: LNAV) -* b33 and demo5 b34: GAL: 0:any,1:I/NAV,2:F/NAV -* 2.4.3 b34 but not functional? GAL : 0:I/NAV,1:F/NAV (default: I/NAV) -* others : undefined -* return : none -*-----------------------------------------------------------------------------*/ -extern void setseleph(int sys, int sel) -{ - switch (sys) { - case SYS_GPS: eph_sel[0]=sel; break; - case SYS_GLO: eph_sel[1]=sel; break; - case SYS_GAL: eph_sel[2]=sel; break; - case SYS_QZS: eph_sel[3]=sel; break; - case SYS_CMP: eph_sel[4]=sel; break; - case SYS_IRN: eph_sel[5]=sel; break; - case SYS_SBS: eph_sel[6]=sel; break; - } + * Set selected satellite ephemeris for multiple ones like LNAV - CNAV, I/NAV - + * F/NAV. Call it before calling satpos(),satposs() to use unselected one. + * args : int sys I satellite system (SYS_???) + * int sel I selection of ephemeris + * GPS,QZS : 0:LNAV ,1:CNAV (default: LNAV) + * b33 and demo5 b34: GAL: 0:any,1:I/NAV,2:F/NAV + * 2.4.3 b34 but not functional? GAL : 0:I/NAV,1:F/NAV (default: I/NAV) + * others : undefined + * return : none + *-----------------------------------------------------------------------------*/ +extern void setseleph(int sys, int sel) { + switch (sys) { + case SYS_GPS: + eph_sel[0] = sel; + break; + case SYS_GLO: + eph_sel[1] = sel; + break; + case SYS_GAL: + eph_sel[2] = sel; + break; + case SYS_QZS: + eph_sel[3] = sel; + break; + case SYS_CMP: + eph_sel[4] = sel; + break; + case SYS_IRN: + eph_sel[5] = sel; + break; + case SYS_SBS: + eph_sel[6] = sel; + break; + } } /* get selected satellite ephemeris ------------------------------------------- -* Get the selected satellite ephemeris. -* args : int sys I satellite system (SYS_???) -* return : selected ephemeris -* refer setseleph() -*-----------------------------------------------------------------------------*/ -extern int getseleph(int sys) -{ - switch (sys) { - case SYS_GPS: return eph_sel[0]; - case SYS_GLO: return eph_sel[1]; - case SYS_GAL: return eph_sel[2]; - case SYS_QZS: return eph_sel[3]; - case SYS_CMP: return eph_sel[4]; - case SYS_IRN: return eph_sel[5]; - case SYS_SBS: return eph_sel[6]; - } - return 0; + * Get the selected satellite ephemeris. + * args : int sys I satellite system (SYS_???) + * return : selected ephemeris + * refer setseleph() + *-----------------------------------------------------------------------------*/ +extern int getseleph(int sys) { + switch (sys) { + case SYS_GPS: + return eph_sel[0]; + case SYS_GLO: + return eph_sel[1]; + case SYS_GAL: + return eph_sel[2]; + case SYS_QZS: + return eph_sel[3]; + case SYS_CMP: + return eph_sel[4]; + case SYS_IRN: + return eph_sel[5]; + case SYS_SBS: + return eph_sel[6]; + } + return 0; } diff --git a/src/geoid.c b/src/geoid.c index cdd17e2e2..fc26e6580 100644 --- a/src/geoid.c +++ b/src/geoid.c @@ -1,7490 +1,7882 @@ /*------------------------------------------------------------------------------ -* geoid.c : geoid models -* -* Copyright (C) 2007-2020 by T.TAKASU, All rights reserved. -* -* reference : -* [1] EGM96 The NASA GSFC and NIMA Joint Geopotential Model -* [2] Earth Gravitational Model 2008 (EGM2008) -* -* version : $Revision: 1.1 $ $Date: 2008/07/17 21:48:06 $ -* history : 2007/01/07 1.0 new -* 2009/09/04 1.1 replace geoid data by global model -* 2009/12/05 1.2 added api: -* opengeoid(),closegeoid() -* 2020/11/30 1.3 use integer types in stdint.h -*-----------------------------------------------------------------------------*/ + * geoid.c : geoid models + * + * Copyright (C) 2007-2020 by T.TAKASU, All rights reserved. + * + * reference : + * [1] EGM96 The NASA GSFC and NIMA Joint Geopotential Model + * [2] Earth Gravitational Model 2008 (EGM2008) + * + * version : $Revision: 1.1 $ $Date: 2008/07/17 21:48:06 $ + * history : 2007/01/07 1.0 new + * 2009/09/04 1.1 replace geoid data by global model + * 2009/12/05 1.2 added api: + * opengeoid(),closegeoid() + * 2020/11/30 1.3 use integer types in stdint.h + *-----------------------------------------------------------------------------*/ #include "rtklib.h" -static const double range[4]; /* embedded geoid area range {W,E,S,N} (deg) */ -static const float geoid[361][181]; /* embedded geoid heights (m) (lon x lat) */ -static FILE *fp_geoid=NULL; /* geoid file pointer */ -static int model_geoid=GEOID_EMBEDDED; /* geoid model */ +static const double range[4]; /* embedded geoid area range {W,E,S,N} (deg) */ +static const float geoid[361][181]; /* embedded geoid heights (m) (lon x lat) */ +static FILE *fp_geoid = NULL; /* geoid file pointer */ +static int model_geoid = GEOID_EMBEDDED; /* geoid model */ /* bilinear interpolation ----------------------------------------------------*/ -static double interpb(const double *y, double a, double b) -{ - return y[0]*(1.0-a)*(1.0-b)+y[1]*a*(1.0-b)+y[2]*(1.0-a)*b+y[3]*a*b; +static double interpb(const double *y, double a, double b) { + return y[0] * (1.0 - a) * (1.0 - b) + y[1] * a * (1.0 - b) + y[2] * (1.0 - a) * b + y[3] * a * b; } /* embedded geoid model ------------------------------------------------------*/ -static double geoidh_emb(const double *pos) -{ - const double dlon=1.0,dlat=1.0; - double a,b,y[4]; - int i1,i2,j1,j2; - - if (pos[1]200.0) { - trace(2,"invalid geoid model: lat=%.3f lon=%.3f h=%.3f\n",posd[0],posd[1],h); - return 0.0; - } - return h; + * get geoid height from geoid model + * args : double *pos I geodetic position {lat,lon} (rad) + * return : geoid height (m) (0.0:error) + * notes : to use external geoid model, call function opengeoid() to open + * geoid model before calling the function. If the external geoid model + * is not open, the function uses embedded geoid model. + *-----------------------------------------------------------------------------*/ +extern double geoidh(const double *pos) { + double posd[2], h; + + posd[1] = pos[1] * R2D; + posd[0] = pos[0] * R2D; + if (posd[1] < 0.0) posd[1] += 360.0; + + if (posd[1] < 0.0 || 360.0 - 1E-12 < posd[1] || posd[0] < -90.0 || 90.0 < posd[0]) { + trace(2, "out of range for geoid model: lat=%.3f lon=%.3f\n", posd[0], posd[1]); + return 0.0; + } + switch (model_geoid) { + case GEOID_EMBEDDED: + h = geoidh_emb(posd); + break; + case GEOID_EGM96_M150: + h = geoidh_egm96(posd); + break; + case GEOID_EGM2008_M25: + h = geoidh_egm08(posd, model_geoid); + break; + case GEOID_EGM2008_M10: + h = geoidh_egm08(posd, model_geoid); + break; + case GEOID_GSI2000_M15: + h = geoidh_gsi(posd); + break; + default: + return 0.0; + } + if (fabs(h) > 200.0) { + trace(2, "invalid geoid model: lat=%.3f lon=%.3f h=%.3f\n", posd[0], posd[1], h); + return 0.0; + } + return h; } /*------------------------------------------------------------------------------ -* embedded geoid model -* notes : geoid heights are derived from EGM96 (1 x 1 deg grid) -*-----------------------------------------------------------------------------*/ -static const double range[]={0.00,360.00,-90.00,90.00}; + * embedded geoid model + * notes : geoid heights are derived from EGM96 (1 x 1 deg grid) + *-----------------------------------------------------------------------------*/ +static const double range[] = {0.00, 360.00, -90.00, 90.00}; -static const float geoid[361][181]={{ --29.534f,-27.880f,-24.897f,-21.973f,-18.154f,-15.493f,-14.636f,-12.657f,-10.648f, -9.301f, - -7.084f, -4.850f, -2.015f, 1.642f, 5.903f, 9.258f, 10.905f, 13.100f, 12.465f, 13.448f, - 14.464f, 10.528f, 10.660f, 10.931f, 12.894f, 13.775f, 13.406f, 13.503f, 13.701f, 14.329f, - 15.132f, 17.828f, 20.762f, 22.627f, 24.433f, 27.098f, 27.238f, 27.168f, 26.391f, 26.405f, - 25.022f, 23.761f, 23.319f, 22.775f, 22.479f, 21.243f, 20.774f, 18.793f, 23.573f, 17.031f, - 17.474f, 16.804f, 16.597f, 16.734f, 16.967f, 17.767f, 18.370f, 20.028f, 20.044f, 20.940f, - 21.409f, 21.247f, 20.852f, 20.564f, 20.098f, 19.847f, 18.959f, 18.146f, 17.336f, 16.808f, - 16.339f, 16.371f, 15.504f, 14.713f, 14.061f, 13.421f, 12.683f, 11.942f, 11.145f, 11.092f, - 11.477f, 11.602f, 13.059f, 15.223f, 16.411f, 16.838f, 17.664f, 18.217f, 18.196f, 17.846f, - 17.162f, 16.992f, 16.895f, 16.616f, 17.673f, 20.453f, 25.912f, 26.234f, 25.914f, 24.272f, - 23.262f, 23.412f, 24.155f, 25.095f, 23.751f, 22.245f, 24.140f, 27.104f, 28.980f, 30.837f, - 31.445f, 30.261f, 30.432f, 29.865f, 29.163f, 27.348f, 25.617f, 25.845f, 28.325f, 30.965f, - 35.389f, 39.102f, 41.083f, 45.020f, 48.293f, 49.580f, 47.460f, 46.235f, 49.156f, 49.913f, - 51.091f, 50.314f, 49.985f, 52.108f, 48.706f, 47.140f, 48.169f, 47.587f, 47.370f, 47.048f, - 45.038f, 45.301f, 46.300f, 46.367f, 45.821f, 46.184f, 46.676f, 47.262f, 47.762f, 46.927f, - 48.227f, 49.454f, 50.172f, 49.071f, 49.781f, 50.804f, 50.320f, 48.953f, 48.675f, 48.539f, - 48.836f, 50.053f, 50.553f, 48.925f, 46.724f, 43.723f, 43.370f, 41.560f, 38.495f, 36.215f, - 33.895f, 32.344f, 30.978f, 28.477f, 27.419f, 25.076f, 22.659f, 20.147f, 17.632f, 15.452f, - 13.606f -},{ --29.534f,-27.872f,-24.818f,-21.917f,-18.173f,-15.402f,-14.776f,-12.758f,-10.529f, -9.116f, - -6.976f, -4.953f, -2.543f, 1.310f, 5.640f, 8.533f, 10.927f, 13.842f, 12.831f, 12.856f, - 14.414f, 10.363f, 11.018f, 11.346f, 13.963f, 15.276f, 14.385f, 13.940f, 14.094f, 14.546f, - 15.512f, 17.859f, 20.624f, 22.106f, 24.013f, 25.824f, 27.236f, 27.060f, 26.242f, 25.680f, - 24.794f, 23.590f, 22.886f, 22.182f, 21.504f, 21.160f, 21.131f, 20.380f, 21.356f, 18.016f, - 17.639f, 17.348f, 16.947f, 17.054f, 17.591f, 18.255f, 19.837f, 19.761f, 20.307f, 21.184f, - 22.997f, 22.284f, 22.086f, 21.615f, 21.142f, 20.632f, 20.144f, 19.147f, 18.136f, 17.373f, - 16.785f, 16.271f, 15.632f, 14.847f, 14.130f, 13.408f, 12.631f, 11.798f, 11.082f, 10.733f, - 10.329f, 10.127f, 12.546f, 12.820f, 15.290f, 15.546f, 16.568f, 18.234f, 18.361f, 17.446f, - 16.997f, 16.742f, 16.948f, 16.553f, 17.426f, 19.542f, 24.700f, 26.558f, 25.574f, 23.570f, - 21.963f, 22.519f, 23.588f, 23.959f, 22.591f, 22.114f, 23.332f, 26.426f, 28.284f, 30.341f, - 31.433f, 31.283f, 31.117f, 31.596f, 30.563f, 28.159f, 25.538f, 25.691f, 27.841f, 28.600f, - 32.533f, 36.899f, 38.970f, 41.651f, 46.206f, 48.666f, 48.107f, 45.242f, 47.015f, 48.806f, - 49.616f, 49.832f, 50.005f, 51.846f, 49.203f, 48.970f, 48.786f, 47.510f, 46.237f, 45.552f, - 45.048f, 44.938f, 45.371f, 45.013f, 44.036f, 44.361f, 45.252f, 46.356f, 47.067f, 46.723f, - 47.361f, 47.685f, 48.633f, 48.060f, 48.638f, 49.669f, 49.180f, 48.457f, 48.343f, 47.985f, - 48.113f, 49.355f, 49.970f, 48.839f, 46.055f, 43.870f, 43.379f, 41.425f, 38.629f, 36.716f, - 34.188f, 32.741f, 31.166f, 28.361f, 27.379f, 25.135f, 22.684f, 20.156f, 17.609f, 15.446f, - 13.606f -},{ --29.534f,-27.865f,-24.741f,-21.844f,-18.189f,-15.386f,-14.844f,-12.759f,-10.339f, -8.906f, - -6.689f, -4.647f, -2.412f, 1.357f, 5.676f, 9.011f, 12.056f, 14.836f, 13.289f, 12.278f, - 14.264f, 10.369f, 11.217f, 11.990f, 14.534f, 16.613f, 15.894f, 14.464f, 14.419f, 14.737f, - 15.552f, 17.503f, 20.371f, 21.913f, 23.853f, 25.577f, 26.714f, 27.074f, 26.194f, 25.353f, - 24.914f, 23.342f, 22.596f, 21.805f, 21.324f, 21.433f, 21.171f, 21.243f, 21.521f, 18.293f, - 18.301f, 18.016f, 17.562f, 17.604f, 18.234f, 19.057f, 19.765f, 22.960f, 22.922f, 21.914f, - 22.944f, 24.099f, 23.245f, 22.425f, 22.109f, 21.822f, 21.210f, 20.463f, 19.201f, 18.137f, - 16.982f, 16.273f, 15.655f, 14.998f, 14.191f, 13.418f, 12.485f, 11.826f, 11.096f, 10.563f, - 10.033f, 9.905f, 10.429f, 10.989f, 11.786f, 13.499f, 15.282f, 17.237f, 17.811f, 17.591f, - 16.757f, 16.210f, 16.158f, 15.951f, 15.816f, 17.326f, 20.984f, 25.957f, 26.021f, 25.190f, - 23.883f, 21.991f, 22.407f, 22.965f, 23.025f, 22.790f, 24.188f, 25.330f, 26.929f, 30.179f, - 31.546f, 31.718f, 31.502f, 32.046f, 31.603f, 28.279f, 26.031f, 24.934f, 26.527f, 27.728f, - 30.134f, 34.456f, 38.013f, 40.139f, 44.998f, 46.912f, 47.887f, 44.456f, 46.072f, 48.802f, - 47.837f, 48.677f, 51.152f, 50.728f, 50.571f, 50.685f, 50.028f, 47.513f, 45.615f, 44.643f, - 44.892f, 44.441f, 44.538f, 44.131f, 42.692f, 43.024f, 44.565f, 45.533f, 45.788f, 46.040f, - 46.826f, 47.043f, 47.789f, 47.210f, 46.716f, 48.096f, 47.357f, 48.183f, 48.079f, 47.224f, - 47.473f, 48.408f, 49.272f, 48.533f, 45.403f, 44.082f, 42.920f, 41.345f, 38.921f, 36.961f, - 34.468f, 32.717f, 31.112f, 28.276f, 27.259f, 25.151f, 22.681f, 20.170f, 17.589f, 15.439f, - 13.606f -},{ --29.534f,-27.858f,-24.665f,-21.753f,-18.195f,-15.452f,-14.835f,-12.659f,-10.107f, -8.614f, - -6.205f, -3.991f, -1.675f, 1.769f, 5.916f, 10.055f, 13.417f, 15.862f, 14.224f, 12.716f, - 14.619f, 10.803f, 11.632f, 12.865f, 14.739f, 17.272f, 16.934f, 15.039f, 14.977f, 15.045f, - 15.547f, 17.438f, 19.743f, 22.194f, 24.179f, 25.803f, 27.246f, 26.646f, 26.346f, 25.153f, - 24.467f, 23.726f, 22.471f, 21.860f, 21.231f, 21.588f, 21.070f, 21.128f, 19.511f, 19.079f, - 18.796f, 18.945f, 18.551f, 17.949f, 18.620f, 19.614f, 20.048f, 20.934f, 21.138f, 24.234f, - 25.249f, 24.186f, 24.752f, 24.201f, 23.339f, 22.729f, 22.350f, 21.693f, 20.519f, 19.023f, - 17.573f, 16.519f, 15.752f, 15.071f, 14.152f, 13.391f, 12.539f, 11.840f, 11.210f, 10.474f, - 9.890f, 9.404f, 9.648f, 9.593f, 10.888f, 11.683f, 13.659f, 15.487f, 16.908f, 17.157f, - 16.942f, 16.466f, 15.867f, 15.076f, 14.806f, 16.182f, 18.527f, 24.702f, 25.834f, 24.851f, - 24.082f, 22.824f, 22.397f, 22.366f, 22.361f, 22.268f, 23.071f, 23.606f, 25.512f, 27.653f, - 30.007f, 31.606f, 32.335f, 33.284f, 32.620f, 30.289f, 27.742f, 25.887f, 27.412f, 28.285f, - 29.022f, 32.069f, 35.868f, 39.096f, 42.115f, 44.076f, 46.268f, 44.511f, 45.338f, 47.426f, - 48.638f, 47.538f, 49.946f, 49.958f, 51.977f, 52.593f, 50.290f, 47.902f, 46.000f, 44.714f, - 44.569f, 44.694f, 44.059f, 42.913f, 41.445f, 42.459f, 43.830f, 44.198f, 44.724f, 44.971f, - 45.367f, 46.038f, 47.165f, 46.513f, 44.688f, 46.149f, 45.965f, 46.815f, 47.523f, 46.682f, - 46.880f, 47.220f, 48.557f, 48.093f, 44.877f, 43.904f, 42.567f, 41.466f, 39.437f, 37.085f, - 34.733f, 32.390f, 30.947f, 28.200f, 27.066f, 25.126f, 22.654f, 20.185f, 17.570f, 15.431f, - 13.606f -},{ --29.534f,-27.853f,-24.591f,-21.645f,-18.181f,-15.590f,-14.763f,-12.487f, -9.869f, -8.231f, - -5.629f, -3.271f, -0.833f, 2.365f, 6.334f, 10.625f, 14.113f, 16.758f, 15.703f, 13.417f, - 14.793f, 11.489f, 12.038f, 13.143f, 14.829f, 17.094f, 17.228f, 16.001f, 15.661f, 15.448f, - 15.894f, 17.342f, 19.200f, 21.642f, 24.267f, 26.250f, 27.707f, 26.574f, 26.004f, 25.197f, - 24.562f, 24.092f, 22.633f, 22.110f, 21.742f, 22.345f, 21.296f, 21.180f, 20.181f, 19.475f, - 19.345f, 19.445f, 19.421f, 19.152f, 19.198f, 19.921f, 20.557f, 21.618f, 22.933f, 22.642f, - 22.478f, 23.033f, 24.020f, 26.116f, 24.905f, 23.921f, 23.911f, 22.839f, 21.555f, 20.361f, - 18.372f, 16.821f, 15.775f, 15.094f, 14.295f, 13.570f, 12.784f, 12.027f, 11.389f, 10.493f, - 9.780f, 9.152f, 9.006f, 9.111f, 9.411f, 10.193f, 11.846f, 14.082f, 16.287f, 16.712f, - 16.617f, 16.232f, 15.606f, 14.330f, 16.558f, 18.130f, 19.340f, 24.026f, 25.344f, 24.359f, - 23.284f, 21.650f, 20.171f, 20.802f, 21.103f, 20.681f, 21.466f, 22.402f, 23.756f, 25.827f, - 28.106f, 30.013f, 31.334f, 33.168f, 33.658f, 33.426f, 30.368f, 27.193f, 28.160f, 27.771f, - 27.461f, 29.163f, 32.442f, 35.690f, 38.945f, 42.108f, 44.068f, 44.542f, 44.446f, 45.654f, - 48.376f, 46.319f, 47.110f, 49.680f, 50.915f, 52.964f, 50.246f, 48.196f, 46.384f, 45.423f, - 45.712f, 45.111f, 43.604f, 42.290f, 41.365f, 41.790f, 43.021f, 43.171f, 43.635f, 44.465f, - 44.783f, 45.372f, 45.910f, 45.481f, 42.712f, 44.601f, 44.929f, 44.814f, 46.503f, 46.011f, - 46.213f, 46.320f, 47.778f, 47.537f, 44.576f, 43.583f, 42.642f, 41.609f, 39.981f, 37.323f, - 34.987f, 31.998f, 30.825f, 28.104f, 26.822f, 25.069f, 22.607f, 20.201f, 17.555f, 15.423f, - 13.606f -},{ --29.534f,-27.848f,-24.521f,-21.520f,-18.139f,-15.771f,-14.651f,-12.289f, -9.660f, -7.801f, - -5.090f, -2.710f, -0.272f, 2.978f, 6.889f, 10.628f, 14.298f, 17.657f, 17.063f, 13.906f, - 14.875f, 12.449f, 12.338f, 13.218f, 15.054f, 16.980f, 17.334f, 16.820f, 16.579f, 16.177f, - 16.516f, 17.416f, 19.038f, 20.935f, 23.615f, 26.014f, 27.547f, 26.127f, 25.595f, 24.695f, - 24.802f, 24.617f, 23.232f, 22.784f, 22.287f, 21.921f, 22.085f, 21.845f, 20.674f, 19.881f, - 19.615f, 19.811f, 20.174f, 20.307f, 20.120f, 20.208f, 20.724f, 21.813f, 22.621f, 22.759f, - 23.471f, 23.658f, 24.010f, 25.421f, 26.892f, 25.756f, 26.050f, 24.699f, 22.533f, 21.972f, - 19.429f, 17.607f, 16.271f, 15.167f, 14.390f, 13.610f, 12.930f, 12.399f, 11.697f, 10.703f, - 9.923f, 9.386f, 8.763f, 8.690f, 8.648f, 9.241f, 10.701f, 12.881f, 15.101f, 16.232f, - 16.254f, 16.002f, 15.280f, 15.548f, 19.235f, 20.892f, 19.610f, 23.241f, 25.027f, 23.769f, - 23.077f, 21.308f, 19.886f, 19.779f, 20.147f, 20.817f, 21.613f, 22.690f, 23.438f, 24.999f, - 26.666f, 29.152f, 31.820f, 34.425f, 35.793f, 35.128f, 32.418f, 29.146f, 27.687f, 26.968f, - 26.463f, 27.412f, 29.614f, 32.045f, 34.360f, 37.402f, 43.444f, 43.043f, 43.578f, 44.710f, - 45.486f, 45.808f, 46.589f, 48.893f, 50.381f, 50.720f, 49.311f, 48.285f, 47.377f, 46.672f, - 46.709f, 45.442f, 43.418f, 42.007f, 40.648f, 40.924f, 42.127f, 42.530f, 42.778f, 44.391f, - 44.966f, 45.949f, 45.463f, 45.186f, 42.236f, 43.936f, 43.966f, 43.324f, 45.195f, 45.051f, - 45.466f, 45.571f, 46.719f, 46.813f, 44.714f, 43.615f, 42.818f, 41.516f, 40.197f, 37.757f, - 35.205f, 31.739f, 30.846f, 27.965f, 26.564f, 24.992f, 22.551f, 20.214f, 17.541f, 15.414f, - 13.606f -},{ --29.534f,-27.844f,-24.454f,-21.380f,-18.059f,-15.950f,-14.517f,-12.098f, -9.510f, -7.400f, - -4.653f, -2.299f, 0.079f, 3.514f, 7.382f, 10.761f, 14.603f, 18.434f, 17.697f, 14.096f, - 14.871f, 13.127f, 12.795f, 13.861f, 15.200f, 17.027f, 17.405f, 17.421f, 17.593f, 17.118f, - 16.896f, 17.665f, 18.825f, 20.440f, 22.505f, 25.907f, 27.382f, 26.365f, 25.635f, 25.146f, - 24.473f, 24.494f, 23.834f, 23.578f, 23.041f, 22.849f, 22.969f, 22.872f, 21.633f, 20.593f, - 20.033f, 20.359f, 20.982f, 21.274f, 20.968f, 20.775f, 21.250f, 22.204f, 22.763f, 22.981f, - 23.564f, 24.142f, 24.538f, 24.686f, 28.629f, 28.327f, 27.073f, 25.850f, 24.353f, 22.283f, - 20.479f, 18.566f, 17.106f, 15.736f, 14.633f, 13.861f, 13.264f, 12.844f, 12.149f, 11.290f, - 10.216f, 9.382f, 8.487f, 7.872f, 7.869f, 8.443f, 9.403f, 11.327f, 13.967f, 15.677f, - 16.804f, 15.432f, 15.102f, 17.403f, 20.866f, 19.099f, 18.549f, 22.326f, 24.098f, 24.508f, - 24.169f, 22.182f, 20.792f, 19.493f, 19.081f, 20.190f, 20.819f, 22.097f, 22.998f, 24.003f, - 25.489f, 27.853f, 31.410f, 36.313f, 36.965f, 35.964f, 33.889f, 30.188f, 28.047f, 27.069f, - 26.381f, 26.753f, 28.247f, 29.939f, 30.694f, 36.085f, 43.335f, 43.467f, 42.678f, 44.277f, - 44.986f, 45.025f, 45.603f, 47.975f, 51.084f, 52.180f, 49.330f, 49.635f, 48.018f, 47.150f, - 48.087f, 45.700f, 43.694f, 41.611f, 39.777f, 40.626f, 41.818f, 41.680f, 42.158f, 44.184f, - 44.452f, 45.957f, 45.242f, 45.196f, 43.352f, 42.783f, 43.393f, 42.573f, 43.844f, 44.224f, - 44.808f, 44.702f, 45.589f, 46.096f, 45.145f, 43.790f, 42.637f, 41.178f, 39.905f, 38.250f, - 35.352f, 31.672f, 31.018f, 27.779f, 26.327f, 24.912f, 22.497f, 20.221f, 17.529f, 15.404f, - 13.606f -},{ --29.534f,-27.841f,-24.390f,-21.229f,-17.938f,-16.080f,-14.370f,-11.927f, -9.433f, -7.085f, - -4.283f, -1.891f, 0.525f, 3.940f, 7.644f, 11.373f, 15.108f, 18.532f, 17.439f, 13.633f, - 14.591f, 13.377f, 13.473f, 14.576f, 15.444f, 16.873f, 17.630f, 17.824f, 18.531f, 17.993f, - 17.492f, 17.772f, 18.992f, 19.870f, 21.651f, 25.845f, 26.556f, 26.396f, 25.794f, 25.476f, - 25.119f, 24.255f, 24.205f, 25.014f, 24.014f, 23.629f, 24.111f, 23.849f, 22.925f, 21.710f, - 20.827f, 21.040f, 21.635f, 22.412f, 21.917f, 21.464f, 21.842f, 22.901f, 23.404f, 23.830f, - 24.222f, 24.359f, 24.644f, 24.768f, 24.342f, 25.604f, 25.050f, 24.853f, 24.518f, 22.725f, - 20.790f, 19.248f, 17.555f, 15.881f, 14.741f, 14.402f, 14.005f, 13.472f, 12.914f, 11.945f, - 10.675f, 9.484f, 8.362f, 7.522f, 7.189f, 7.625f, 8.341f, 9.911f, 12.455f, 14.390f, - 16.331f, 15.955f, 15.972f, 17.036f, 19.374f, 18.789f, 20.377f, 21.712f, 23.681f, 25.011f, - 24.881f, 22.413f, 21.035f, 19.929f, 19.285f, 19.383f, 20.505f, 21.650f, 22.839f, 23.268f, - 24.178f, 26.177f, 29.701f, 33.566f, 36.582f, 36.022f, 33.149f, 29.679f, 27.527f, 27.080f, - 26.407f, 26.617f, 27.890f, 28.934f, 29.298f, 37.322f, 43.291f, 42.751f, 42.135f, 43.562f, - 44.224f, 44.773f, 45.549f, 45.828f, 51.578f, 52.963f, 51.283f, 49.310f, 49.141f, 48.396f, - 48.733f, 46.870f, 44.141f, 41.230f, 39.540f, 40.296f, 41.312f, 40.885f, 41.829f, 45.263f, - 45.307f, 45.594f, 45.572f, 44.547f, 43.190f, 41.290f, 42.911f, 42.322f, 42.287f, 43.497f, - 44.151f, 44.039f, 44.665f, 45.508f, 45.203f, 43.430f, 42.155f, 40.799f, 39.322f, 38.584f, - 35.413f, 31.721f, 31.268f, 27.559f, 26.134f, 24.841f, 22.454f, 20.222f, 17.519f, 15.393f, - 13.606f -},{ --29.534f,-27.838f,-24.330f,-21.070f,-17.776f,-16.117f,-14.200f,-11.756f, -9.418f, -6.869f, - -3.907f, -1.399f, 1.173f, 4.303f, 7.820f, 12.096f, 15.555f, 17.964f, 16.519f, 12.815f, - 14.465f, 13.556f, 13.988f, 14.877f, 15.863f, 16.730f, 17.919f, 18.421f, 19.514f, 18.884f, - 18.241f, 18.232f, 19.498f, 19.446f, 21.528f, 25.300f, 26.074f, 27.017f, 25.964f, 25.697f, - 23.581f, 25.107f, 25.961f, 26.093f, 24.159f, 24.672f, 24.250f, 24.518f, 24.000f, 23.171f, - 22.081f, 22.059f, 22.507f, 23.115f, 22.884f, 22.214f, 22.567f, 23.023f, 24.088f, 24.469f, - 24.913f, 24.668f, 24.779f, 25.331f, 24.728f, 23.617f, 22.854f, 23.789f, 23.733f, 23.227f, - 21.197f, 19.255f, 17.480f, 16.093f, 14.877f, 14.638f, 14.597f, 14.202f, 13.809f, 12.801f, - 11.271f, 9.841f, 8.417f, 7.415f, 7.209f, 7.341f, 7.621f, 7.748f, 11.371f, 14.324f, - 13.662f, 14.059f, 14.148f, 15.824f, 18.235f, 20.255f, 21.128f, 21.908f, 22.085f, 23.126f, - 23.888f, 22.158f, 21.603f, 20.888f, 20.143f, 19.409f, 20.876f, 22.493f, 24.230f, 24.776f, - 24.607f, 26.040f, 29.836f, 33.258f, 34.752f, 35.717f, 33.239f, 29.754f, 28.955f, 27.320f, - 26.524f, 27.292f, 28.717f, 29.407f, 29.607f, 38.465f, 43.029f, 42.697f, 41.625f, 45.074f, - 45.807f, 46.017f, 45.813f, 45.739f, 48.571f, 44.668f, 51.853f, 48.389f, 49.306f, 48.233f, - 48.497f, 48.385f, 44.503f, 41.177f, 39.194f, 40.626f, 40.872f, 40.445f, 40.740f, 43.606f, - 44.699f, 45.209f, 46.153f, 43.589f, 42.118f, 40.714f, 41.948f, 42.618f, 41.043f, 42.604f, - 43.381f, 43.593f, 43.736f, 44.866f, 44.488f, 42.496f, 41.729f, 40.488f, 38.887f, 38.637f, - 35.418f, 31.760f, 31.488f, 27.340f, 25.997f, 24.790f, 22.432f, 20.213f, 17.509f, 15.382f, - 13.606f -},{ --29.534f,-27.837f,-24.272f,-20.906f,-17.576f,-16.031f,-13.991f,-11.555f, -9.432f, -6.722f, - -3.481f, -0.881f, 1.823f, 4.715f, 8.213f, 12.545f, 15.960f, 17.613f, 15.652f, 12.250f, - 14.387f, 13.581f, 14.070f, 15.049f, 16.031f, 16.940f, 18.184f, 19.253f, 19.977f, 19.755f, - 19.078f, 18.582f, 19.134f, 19.592f, 21.792f, 24.516f, 25.942f, 26.723f, 26.439f, 25.567f, - 24.658f, 23.199f, 24.912f, 24.808f, 25.002f, 25.723f, 25.305f, 24.953f, 24.926f, 24.637f, - 23.628f, 22.890f, 22.708f, 23.378f, 23.609f, 23.157f, 23.476f, 23.664f, 24.301f, 25.152f, - 25.625f, 25.319f, 25.191f, 25.186f, 24.776f, 23.915f, 22.905f, 21.959f, 22.510f, 22.956f, - 22.698f, 19.039f, 17.490f, 16.650f, 15.258f, 14.987f, 14.960f, 15.060f, 14.745f, 13.517f, - 11.930f, 10.287f, 8.526f, 7.441f, 7.301f, 7.121f, 4.554f, 7.567f, 10.487f, 12.113f, - 12.343f, 13.445f, 13.439f, 15.328f, 20.480f, 21.327f, 21.736f, 21.333f, 20.872f, 22.753f, - 23.894f, 22.135f, 21.395f, 20.969f, 20.431f, 20.108f, 21.291f, 23.873f, 27.037f, 28.501f, - 26.649f, 27.712f, 29.742f, 31.482f, 34.439f, 34.874f, 31.979f, 29.649f, 28.740f, 27.964f, - 26.717f, 28.181f, 30.031f, 30.806f, 31.529f, 37.213f, 42.088f, 43.112f, 42.876f, 46.097f, - 48.223f, 48.052f, 50.617f, 47.476f, 45.549f, 41.503f, 47.574f, 47.703f, 48.101f, 48.414f, - 48.236f, 47.941f, 44.853f, 40.853f, 39.449f, 40.381f, 40.477f, 39.426f, 39.184f, 41.661f, - 41.977f, 43.124f, 44.902f, 42.426f, 41.314f, 40.404f, 40.709f, 42.485f, 40.898f, 41.457f, - 42.597f, 42.993f, 42.837f, 44.091f, 43.422f, 41.650f, 41.334f, 40.126f, 38.836f, 38.412f, - 35.411f, 31.706f, 31.596f, 27.162f, 25.906f, 24.764f, 22.435f, 20.195f, 17.500f, 15.371f, - 13.606f -},{ --29.534f,-27.836f,-24.217f,-20.744f,-17.349f,-15.811f,-13.726f,-11.301f, -9.422f, -6.597f, - -3.031f, -0.437f, 2.245f, 5.216f, 8.829f, 12.838f, 16.435f, 17.910f, 15.459f, 11.825f, - 14.062f, 14.179f, 14.615f, 15.578f, 16.567f, 17.494f, 18.453f, 19.944f, 20.579f, 20.770f, - 19.934f, 19.012f, 19.207f, 20.006f, 22.100f, 24.237f, 26.653f, 27.013f, 27.080f, 26.766f, - 25.100f, 25.440f, 26.439f, 25.798f, 25.368f, 26.060f, 26.398f, 26.397f, 25.761f, 25.697f, - 24.771f, 23.851f, 23.321f, 23.731f, 24.177f, 24.075f, 24.035f, 24.290f, 24.967f, 25.765f, - 25.904f, 25.760f, 25.543f, 25.288f, 24.599f, 23.915f, 22.918f, 22.423f, 22.387f, 22.403f, - 23.065f, 19.606f, 18.388f, 17.649f, 16.277f, 16.191f, 15.558f, 15.867f, 15.806f, 14.483f, - 12.982f, 10.964f, 9.002f, 8.046f, 7.983f, 5.531f, 5.286f, 7.046f, 6.526f, 9.303f, - 9.000f, 11.431f, 12.674f, 14.569f, 16.015f, 20.145f, 22.538f, 20.179f, 20.136f, 20.630f, - 21.569f, 21.015f, 20.507f, 19.677f, 20.178f, 19.774f, 20.885f, 22.985f, 25.402f, 26.481f, - 26.504f, 27.053f, 27.404f, 29.286f, 32.656f, 32.577f, 31.143f, 29.343f, 28.412f, 28.505f, - 27.749f, 29.019f, 32.060f, 32.830f, 33.460f, 36.839f, 40.039f, 42.474f, 43.499f, 43.900f, - 45.726f, 47.020f, 47.223f, 48.546f, 46.414f, 39.049f, 48.953f, 48.668f, 46.634f, 48.345f, - 48.029f, 47.138f, 44.395f, 41.003f, 39.506f, 40.019f, 39.343f, 38.490f, 38.129f, 40.336f, - 40.457f, 40.397f, 41.717f, 41.486f, 40.655f, 40.107f, 39.595f, 41.118f, 41.162f, 40.202f, - 41.764f, 42.337f, 42.334f, 43.339f, 42.586f, 41.173f, 40.599f, 39.589f, 38.901f, 37.953f, - 35.405f, 31.561f, 31.559f, 27.055f, 25.843f, 24.760f, 22.466f, 20.166f, 17.492f, 15.359f, - 13.606f -},{ --29.534f,-27.836f,-24.164f,-20.587f,-17.108f,-15.473f,-13.402f,-11.000f, -9.337f, -6.449f, - -2.621f, -0.081f, 2.463f, 5.670f, 9.330f, 13.263f, 16.866f, 18.298f, 15.582f, 11.374f, - 14.352f, 15.483f, 15.627f, 15.922f, 17.481f, 17.975f, 18.802f, 20.620f, 21.822f, 21.876f, - 20.926f, 19.731f, 19.492f, 20.188f, 22.091f, 24.209f, 27.029f, 28.154f, 28.613f, 26.876f, - 26.493f, 26.264f, 26.011f, 25.938f, 26.021f, 26.320f, 27.135f, 27.514f, 26.345f, 26.679f, - 25.629f, 24.868f, 24.113f, 24.425f, 24.887f, 24.950f, 24.639f, 24.863f, 25.372f, 25.643f, - 25.942f, 26.109f, 25.610f, 25.321f, 24.629f, 23.804f, 23.389f, 22.994f, 23.014f, 23.088f, - 23.512f, 22.296f, 20.461f, 21.282f, 19.670f, 17.937f, 17.237f, 16.669f, 16.623f, 15.230f, - 14.320f, 11.443f, 10.281f, 10.681f, 8.987f, 5.623f, 5.295f, 4.294f, 5.356f, 8.141f, - 9.154f, 10.954f, 11.653f, 13.161f, 15.020f, 18.332f, 20.108f, 20.026f, 19.385f, 19.103f, - 19.019f, 19.259f, 18.843f, 18.694f, 18.923f, 18.788f, 18.831f, 21.135f, 22.949f, 24.652f, - 25.056f, 25.013f, 27.014f, 28.892f, 30.358f, 30.499f, 29.130f, 28.704f, 28.291f, 28.480f, - 29.004f, 31.021f, 32.540f, 33.083f, 33.722f, 36.441f, 39.322f, 42.077f, 43.169f, 43.186f, - 44.352f, 46.020f, 47.718f, 48.848f, 44.595f, 40.733f, 49.278f, 49.611f, 45.956f, 46.995f, - 47.189f, 46.464f, 44.308f, 40.701f, 39.290f, 38.628f, 37.660f, 37.940f, 36.775f, 37.784f, - 38.595f, 38.163f, 38.809f, 39.656f, 38.901f, 39.329f, 38.713f, 39.795f, 41.126f, 39.381f, - 40.837f, 41.728f, 41.908f, 42.652f, 41.955f, 40.662f, 39.610f, 38.958f, 38.492f, 37.293f, - 35.353f, 31.390f, 31.388f, 27.031f, 25.781f, 24.769f, 22.520f, 20.128f, 17.484f, 15.346f, - 13.606f -},{ --29.534f,-27.837f,-24.112f,-20.440f,-16.868f,-15.055f,-13.039f,-10.694f, -9.143f, -6.249f, - -2.288f, 0.269f, 2.693f, 5.911f, 9.509f, 13.805f, 17.195f, 18.505f, 15.444f, 11.145f, - 15.693f, 15.637f, 15.369f, 15.624f, 18.247f, 18.334f, 19.261f, 21.250f, 22.895f, 22.852f, - 21.985f, 20.671f, 19.988f, 20.470f, 22.434f, 24.446f, 27.722f, 28.618f, 29.866f, 27.253f, - 26.336f, 26.855f, 26.229f, 26.005f, 26.679f, 26.778f, 27.348f, 27.784f, 27.409f, 26.967f, - 26.421f, 25.929f, 25.140f, 24.919f, 25.311f, 25.451f, 25.458f, 25.615f, 26.531f, 26.602f, - 26.532f, 26.835f, 26.651f, 26.420f, 25.843f, 25.429f, 25.204f, 24.397f, 24.348f, 24.512f, - 25.081f, 24.463f, 22.243f, 21.840f, 22.758f, 20.970f, 18.972f, 18.321f, 17.239f, 16.663f, - 15.327f, 12.786f, 11.138f, 12.795f, 10.655f, 4.414f, 2.715f, 3.764f, 7.300f, 8.246f, - 7.836f, 9.161f, 9.427f, 11.343f, 13.952f, 15.763f, 17.547f, 19.005f, 18.225f, 18.578f, - 18.132f, 18.077f, 17.383f, 17.326f, 16.934f, 16.708f, 17.222f, 19.977f, 21.997f, 22.852f, - 22.833f, 23.772f, 25.195f, 26.539f, 28.185f, 28.569f, 28.266f, 28.163f, 28.573f, 29.077f, - 30.290f, 31.888f, 32.318f, 33.102f, 33.438f, 36.376f, 39.411f, 41.920f, 43.318f, 43.082f, - 44.248f, 46.068f, 48.386f, 48.411f, 42.135f, 42.678f, 47.630f, 49.545f, 45.186f, 46.210f, - 47.303f, 45.847f, 43.060f, 40.459f, 38.592f, 37.468f, 36.597f, 37.256f, 35.538f, 35.119f, - 35.762f, 35.574f, 37.018f, 37.262f, 36.107f, 37.513f, 37.149f, 38.287f, 40.858f, 39.063f, - 40.008f, 40.944f, 41.245f, 42.070f, 41.202f, 39.991f, 39.113f, 38.369f, 37.226f, 36.511f, - 35.172f, 31.258f, 31.105f, 27.072f, 25.702f, 24.780f, 22.591f, 20.083f, 17.475f, 15.333f, - 13.606f -},{ --29.534f,-27.838f,-24.060f,-20.307f,-16.644f,-14.608f,-12.674f,-10.450f, -8.839f, -5.974f, - -2.015f, 0.676f, 3.083f, 6.003f, 9.612f, 14.250f, 17.561f, 18.917f, 15.476f, 11.353f, - 16.826f, 14.923f, 14.371f, 15.671f, 18.777f, 18.848f, 19.712f, 21.692f, 23.315f, 23.646f, - 22.824f, 21.535f, 20.554f, 21.343f, 23.019f, 25.351f, 27.599f, 29.875f, 30.967f, 29.473f, - 26.998f, 27.670f, 27.119f, 26.712f, 27.343f, 27.378f, 27.524f, 27.986f, 28.238f, 27.088f, - 26.635f, 26.356f, 25.526f, 25.477f, 25.543f, 25.774f, 25.870f, 26.575f, 27.104f, 27.692f, - 27.990f, 28.499f, 28.495f, 28.214f, 27.868f, 27.657f, 27.927f, 27.802f, 26.778f, 25.866f, - 24.724f, 24.367f, 24.619f, 23.382f, 23.857f, 22.393f, 21.322f, 21.982f, 19.394f, 18.226f, - 17.424f, 15.666f, 13.215f, 11.099f, 7.473f, 4.232f, 3.476f, 4.735f, 6.980f, 6.231f, - 6.074f, 6.566f, 7.388f, 8.256f, 12.298f, 14.098f, 14.671f, 16.806f, 16.363f, 16.488f, - 16.953f, 16.352f, 15.956f, 15.424f, 15.232f, 15.278f, 16.707f, 18.870f, 20.076f, 20.576f, - 21.220f, 22.225f, 23.673f, 25.094f, 26.433f, 26.872f, 26.785f, 26.897f, 28.994f, 30.354f, - 31.289f, 31.472f, 33.021f, 32.466f, 32.984f, 35.842f, 37.965f, 40.279f, 43.700f, 42.787f, - 44.180f, 47.154f, 49.299f, 47.124f, 40.782f, 43.195f, 44.762f, 48.629f, 44.741f, 46.606f, - 46.695f, 44.492f, 41.808f, 39.402f, 37.155f, 35.793f, 36.318f, 36.169f, 34.405f, 32.938f, - 32.610f, 33.576f, 35.295f, 34.957f, 33.958f, 35.803f, 34.847f, 35.543f, 39.433f, 38.724f, - 39.415f, 40.161f, 40.962f, 41.673f, 40.302f, 39.725f, 39.522f, 37.711f, 35.339f, 35.782f, - 34.795f, 31.184f, 30.720f, 27.135f, 25.595f, 24.780f, 22.671f, 20.031f, 17.465f, 15.319f, - 13.606f -},{ --29.534f,-27.841f,-24.007f,-20.191f,-16.452f,-14.189f,-12.359f,-10.329f, -8.454f, -5.599f, - -1.736f, 1.126f, 3.576f, 6.245f, 10.028f, 14.562f, 17.953f, 19.368f, 16.025f, 12.169f, - 16.837f, 15.423f, 14.549f, 16.062f, 18.410f, 19.497f, 20.165f, 21.927f, 23.536f, 23.848f, - 23.249f, 22.330f, 21.632f, 22.066f, 24.115f, 25.906f, 27.974f, 31.002f, 31.430f, 30.884f, - 28.346f, 28.432f, 28.075f, 27.025f, 27.479f, 28.200f, 28.047f, 27.649f, 28.346f, 28.887f, - 26.091f, 28.275f, 26.014f, 26.193f, 25.584f, 25.569f, 25.914f, 26.714f, 27.673f, 28.559f, - 29.431f, 29.943f, 30.080f, 31.186f, 30.606f, 30.384f, 29.205f, 29.349f, 27.831f, 25.377f, - 25.459f, 25.660f, 25.577f, 23.555f, 23.975f, 24.410f, 21.556f, 20.704f, 20.884f, 18.497f, - 17.230f, 15.554f, 13.150f, 9.760f, 5.594f, 3.099f, 2.861f, 4.359f, 4.401f, 3.820f, - 3.243f, 3.743f, 4.407f, 5.894f, 9.800f, 12.047f, 12.415f, 15.100f, 14.310f, 13.704f, - 14.584f, 14.839f, 14.408f, 13.911f, 13.536f, 14.532f, 15.413f, 17.109f, 18.005f, 18.568f, - 20.012f, 21.100f, 23.179f, 25.388f, 25.774f, 25.632f, 26.257f, 27.149f, 29.421f, 30.674f, - 31.063f, 30.891f, 31.772f, 31.357f, 32.230f, 34.107f, 36.779f, 38.398f, 42.250f, 43.028f, - 45.255f, 47.572f, 48.498f, 43.147f, 42.194f, 44.444f, 46.672f, 48.473f, 45.159f, 46.836f, - 45.781f, 43.576f, 40.854f, 37.483f, 35.772f, 34.340f, 34.841f, 33.912f, 32.508f, 30.912f, - 30.724f, 32.050f, 33.962f, 33.061f, 32.366f, 34.155f, 33.515f, 32.860f, 35.936f, 38.192f, - 38.900f, 39.591f, 41.002f, 41.056f, 39.422f, 40.130f, 40.056f, 36.661f, 33.539f, 35.295f, - 34.207f, 31.135f, 30.225f, 27.167f, 25.460f, 24.759f, 22.748f, 19.975f, 17.454f, 15.305f, - 13.606f -},{ --29.534f,-27.844f,-23.953f,-20.093f,-16.300f,-13.850f,-12.137f,-10.356f, -8.031f, -5.111f, - -1.385f, 1.561f, 4.046f, 6.853f, 10.786f, 14.904f, 18.190f, 19.313f, 16.249f, 13.385f, - 16.750f, 16.351f, 15.101f, 15.846f, 17.792f, 19.747f, 20.495f, 22.175f, 23.826f, 24.022f, - 23.640f, 22.987f, 22.811f, 23.395f, 24.992f, 26.929f, 28.757f, 31.543f, 32.671f, 31.200f, - 29.694f, 28.919f, 28.625f, 28.179f, 28.500f, 28.456f, 28.109f, 28.417f, 28.588f, 28.686f, - 27.889f, 26.652f, 27.357f, 26.233f, 25.897f, 25.500f, 25.875f, 27.174f, 28.637f, 29.020f, - 31.714f, 31.624f, 31.542f, 31.601f, 32.328f, 31.618f, 30.666f, 30.016f, 29.281f, 26.991f, - 25.870f, 24.663f, 23.765f, 22.282f, 21.637f, 22.453f, 22.419f, 22.303f, 21.653f, 19.860f, - 17.204f, 14.950f, 12.048f, 8.885f, 5.173f, 2.021f, 1.060f, 2.143f, 1.539f, 0.082f, - -1.156f, -0.314f, 0.287f, 3.495f, 7.870f, 9.020f, 10.118f, 11.949f, 11.841f, 12.036f, - 12.599f, 12.759f, 13.004f, 13.225f, 13.683f, 13.685f, 14.118f, 14.891f, 16.294f, 17.911f, - 20.147f, 22.067f, 24.184f, 26.087f, 25.918f, 25.256f, 26.239f, 28.042f, 29.953f, 31.016f, - 29.809f, 29.556f, 30.270f, 29.779f, 31.795f, 33.889f, 37.763f, 41.384f, 42.496f, 43.180f, - 46.366f, 48.151f, 46.227f, 43.084f, 43.049f, 45.537f, 46.977f, 47.768f, 46.447f, 46.411f, - 44.796f, 42.758f, 39.731f, 35.775f, 34.742f, 33.733f, 33.053f, 32.420f, 31.152f, 29.320f, - 29.331f, 30.658f, 32.361f, 31.863f, 31.097f, 32.129f, 32.982f, 31.089f, 31.938f, 37.221f, - 38.095f, 38.734f, 40.058f, 39.600f, 38.571f, 40.408f, 39.403f, 35.074f, 32.406f, 35.063f, - 33.444f, 31.056f, 29.615f, 27.120f, 25.308f, 24.710f, 22.812f, 19.917f, 17.443f, 15.290f, - 13.606f -},{ --29.534f,-27.848f,-23.897f,-20.014f,-16.194f,-13.622f,-12.031f,-10.502f, -7.612f, -4.520f, - -0.938f, 1.967f, 4.487f, 7.709f, 11.554f, 15.321f, 18.315f, 19.190f, 16.006f, 14.331f, - 17.584f, 16.305f, 14.808f, 15.479f, 17.562f, 19.140f, 20.857f, 22.181f, 23.701f, 24.182f, - 24.340f, 23.620f, 23.253f, 24.642f, 26.214f, 27.794f, 29.464f, 32.374f, 33.128f, 31.974f, - 30.727f, 29.606f, 29.510f, 29.019f, 29.112f, 29.412f, 29.369f, 29.004f, 28.734f, 28.779f, - 27.769f, 27.558f, 26.582f, 26.182f, 26.637f, 26.321f, 26.712f, 27.770f, 30.501f, 31.119f, - 30.758f, 31.246f, 32.488f, 33.354f, 33.627f, 33.277f, 32.511f, 31.783f, 29.821f, 28.852f, - 26.204f, 22.785f, 21.058f, 20.689f, 20.169f, 20.305f, 20.720f, 21.632f, 21.372f, 19.485f, - 16.402f, 12.684f, 10.016f, 7.395f, 3.669f, 0.299f, -2.046f, -2.433f, -3.124f, -4.257f, - -3.744f, -2.665f, -0.843f, 1.096f, 4.763f, 5.939f, 7.923f, 8.266f, 8.611f, 8.914f, - 10.228f, 11.350f, 12.026f, 12.213f, 12.541f, 12.896f, 13.041f, 13.607f, 15.226f, 17.702f, - 21.541f, 24.675f, 26.439f, 26.578f, 26.850f, 27.011f, 28.153f, 29.622f, 30.246f, 30.410f, - 29.526f, 28.521f, 28.693f, 28.794f, 30.528f, 33.128f, 31.055f, 30.834f, 37.560f, 44.374f, - 44.921f, 47.591f, 47.390f, 43.123f, 44.225f, 46.475f, 46.046f, 46.594f, 46.296f, 46.198f, - 44.127f, 42.374f, 38.764f, 34.287f, 33.721f, 32.698f, 31.814f, 30.485f, 29.280f, 27.720f, - 27.167f, 28.865f, 30.000f, 30.666f, 30.251f, 30.617f, 32.282f, 30.483f, 30.005f, 35.460f, - 36.785f, 37.200f, 37.936f, 37.440f, 37.622f, 39.508f, 37.215f, 33.223f, 31.917f, 34.829f, - 32.579f, 30.905f, 28.914f, 26.970f, 25.151f, 24.633f, 22.857f, 19.861f, 17.430f, 15.275f, - 13.606f -},{ --29.534f,-27.853f,-23.839f,-19.951f,-16.130f,-13.515f,-12.028f,-10.682f, -7.216f, -3.868f, - -0.429f, 2.372f, 4.998f, 8.513f, 12.087f, 15.651f, 18.541f, 19.667f, 16.516f, 14.980f, - 18.122f, 15.894f, 14.248f, 15.595f, 17.049f, 18.554f, 20.751f, 22.353f, 23.742f, 24.410f, - 24.901f, 24.066f, 24.065f, 25.418f, 27.152f, 28.563f, 30.759f, 33.035f, 33.759f, 32.430f, - 31.463f, 30.281f, 29.918f, 30.242f, 30.449f, 30.033f, 29.686f, 29.388f, 29.255f, 29.023f, - 28.775f, 27.226f, 27.046f, 26.921f, 27.222f, 28.041f, 28.629f, 31.070f, 30.447f, 30.889f, - 31.533f, 32.311f, 31.879f, 33.245f, 33.624f, 32.760f, 32.075f, 32.401f, 30.653f, 28.287f, - 26.372f, 22.204f, 19.766f, 19.091f, 18.425f, 18.037f, 17.959f, 18.473f, 19.251f, 15.996f, - 13.119f, 9.789f, 7.110f, 4.675f, 1.484f, -2.369f, -5.508f, -7.503f, -7.303f, -7.689f, - -8.208f, -6.206f, -3.087f, -0.471f, 2.909f, 4.301f, 5.029f, 5.880f, 5.693f, 5.505f, - 7.937f, 9.695f, 10.634f, 10.716f, 11.205f, 11.686f, 12.295f, 12.873f, 14.868f, 17.831f, - 22.845f, 28.835f, 28.132f, 27.267f, 27.281f, 28.047f, 29.539f, 30.860f, 30.212f, 29.249f, - 28.869f, 28.431f, 27.188f, 27.655f, 29.100f, 29.407f, 28.620f, 28.950f, 31.298f, 37.090f, - 37.884f, 45.798f, 43.624f, 43.273f, 46.350f, 46.312f, 45.433f, 45.356f, 44.001f, 43.452f, - 44.025f, 40.745f, 37.069f, 33.332f, 31.646f, 31.384f, 29.869f, 28.159f, 27.248f, 25.776f, - 25.200f, 25.821f, 26.646f, 28.517f, 29.642f, 29.746f, 31.455f, 30.975f, 30.383f, 33.375f, - 35.149f, 35.266f, 35.894f, 35.212f, 36.423f, 37.348f, 34.492f, 31.588f, 31.558f, 34.236f, - 31.701f, 30.669f, 28.187f, 26.717f, 25.000f, 24.533f, 22.876f, 19.808f, 17.415f, 15.260f, - 13.606f -},{ --29.534f,-27.858f,-23.777f,-19.902f,-16.102f,-13.510f,-12.081f,-10.776f, -6.838f, -3.218f, - 0.070f, 2.788f, 5.617f, 9.120f, 12.469f, 15.796f, 18.842f, 20.134f, 17.530f, 15.651f, - 17.031f, 15.404f, 14.150f, 15.814f, 16.946f, 18.897f, 19.954f, 22.355f, 23.888f, 24.697f, - 25.255f, 24.696f, 25.277f, 26.437f, 27.946f, 29.783f, 31.495f, 33.914f, 34.648f, 32.637f, - 32.004f, 31.073f, 30.646f, 30.844f, 31.388f, 31.142f, 30.473f, 29.846f, 29.394f, 29.425f, - 29.365f, 27.526f, 27.338f, 27.263f, 28.404f, 29.606f, 31.187f, 31.180f, 32.208f, 32.143f, - 33.847f, 32.489f, 32.068f, 30.946f, 29.678f, 29.299f, 29.226f, 29.793f, 28.795f, 28.643f, - 25.099f, 21.969f, 19.177f, 17.835f, 17.055f, 16.414f, 15.941f, 15.278f, 14.629f, 12.643f, - 10.560f, 7.984f, 5.528f, 3.110f, -0.850f, -5.602f, -8.504f,-10.739f,-11.015f,-13.061f, --11.410f,-10.020f, -6.514f, -3.274f, -2.799f, -1.130f, 1.203f, 2.623f, 3.976f, 3.572f, - 5.661f, 7.552f, 8.302f, 9.655f, 10.096f, 10.491f, 10.872f, 10.981f, 13.151f, 16.926f, - 24.088f, 29.591f, 28.108f, 26.639f, 26.077f, 26.481f, 28.154f, 29.715f, 28.533f, 28.517f, - 28.358f, 28.132f, 26.711f, 27.158f, 27.733f, 28.211f, 28.503f, 28.259f, 29.470f, 29.527f, - 39.073f, 39.786f, 39.050f, 42.868f, 46.822f, 46.065f, 44.912f, 45.104f, 43.596f, 43.159f, - 42.673f, 39.458f, 34.870f, 30.947f, 30.065f, 29.471f, 27.717f, 26.519f, 25.097f, 23.652f, - 22.891f, 23.220f, 23.422f, 25.233f, 28.403f, 28.766f, 30.359f, 31.118f, 31.451f, 31.776f, - 33.355f, 33.175f, 34.316f, 33.169f, 34.863f, 34.797f, 32.418f, 30.438f, 30.915f, 33.125f, - 30.905f, 30.357f, 27.525f, 26.390f, 24.860f, 24.421f, 22.868f, 19.761f, 17.399f, 15.244f, - 13.606f -},{ --29.534f,-27.865f,-23.712f,-19.863f,-16.097f,-13.569f,-12.118f,-10.668f, -6.446f, -2.626f, - 0.501f, 3.170f, 6.213f, 9.608f, 12.862f, 15.888f, 19.000f, 19.948f, 17.478f, 15.943f, - 15.701f, 14.913f, 14.702f, 15.883f, 17.413f, 19.059f, 19.790f, 21.941f, 24.240f, 24.911f, - 25.338f, 25.250f, 25.704f, 27.054f, 29.127f, 30.680f, 32.334f, 34.538f, 35.061f, 33.691f, - 32.538f, 32.258f, 31.927f, 31.372f, 32.005f, 32.032f, 31.441f, 30.297f, 29.658f, 29.365f, - 29.264f, 28.848f, 26.861f, 27.143f, 29.276f, 31.041f, 31.621f, 32.835f, 33.015f, 32.916f, - 34.822f, 32.115f, 31.913f, 31.906f, 28.358f, 27.643f, 27.118f, 26.503f, 26.912f, 27.515f, - 23.455f, 20.878f, 18.494f, 16.505f, 15.583f, 14.740f, 13.918f, 13.072f, 11.975f, 10.365f, - 8.374f, 6.413f, 4.035f, 0.550f, -3.867f, -8.310f,-10.484f,-13.130f,-14.556f,-14.998f, --15.079f,-12.667f,-10.069f, -6.918f, -6.313f, -5.191f, -2.758f, -0.369f, 1.935f, 0.709f, - 3.734f, 5.846f, 7.459f, 8.111f, 9.383f, 10.028f, 10.453f, 10.034f, 12.230f, 15.752f, - 20.298f, 24.499f, 25.715f, 24.964f, 25.083f, 24.702f, 26.094f, 26.641f, 26.261f, 26.146f, - 26.941f, 26.870f, 26.957f, 27.023f, 26.096f, 26.413f, 26.515f, 27.235f, 25.130f, 29.055f, - 34.161f, 35.293f, 36.853f, 44.137f, 46.377f, 45.082f, 44.650f, 43.717f, 43.887f, 43.032f, - 41.969f, 38.109f, 33.099f, 29.817f, 29.154f, 27.570f, 25.903f, 24.540f, 22.483f, 21.339f, - 20.260f, 21.474f, 22.235f, 22.149f, 26.188f, 27.286f, 29.188f, 30.557f, 31.729f, 31.040f, - 31.377f, 31.067f, 32.646f, 31.432f, 33.025f, 32.658f, 31.231f, 29.706f, 30.074f, 31.689f, - 30.265f, 29.980f, 27.005f, 26.028f, 24.728f, 24.308f, 22.834f, 19.720f, 17.382f, 15.227f, - 13.606f -},{ --29.534f,-27.871f,-23.644f,-19.827f,-16.099f,-13.641f,-12.061f,-10.280f, -5.999f, -2.112f, - 0.850f, 3.473f, 6.624f, 10.064f, 13.230f, 16.069f, 18.901f, 19.793f, 17.079f, 16.160f, - 15.908f, 15.082f, 15.187f, 15.909f, 17.533f, 18.759f, 19.981f, 21.813f, 24.062f, 25.170f, - 25.447f, 25.722f, 26.287f, 27.769f, 29.436f, 31.591f, 33.330f, 35.298f, 35.502f, 34.060f, - 33.226f, 32.657f, 32.301f, 31.924f, 32.384f, 32.462f, 31.888f, 30.988f, 30.094f, 29.555f, - 29.418f, 29.232f, 27.802f, 28.893f, 30.850f, 31.538f, 32.708f, 33.553f, 34.923f, 35.139f, - 33.695f, 31.271f, 30.187f, 29.771f, 29.044f, 27.603f, 26.235f, 24.964f, 24.947f, 24.054f, - 21.570f, 19.539f, 17.272f, 15.293f, 14.025f, 13.039f, 11.955f, 11.000f, 9.822f, 8.378f, - 6.333f, 3.927f, 1.269f, -2.368f, -6.429f, -9.731f,-12.792f,-15.168f,-17.660f,-18.760f, --17.336f,-15.490f,-14.135f,-10.131f, -8.206f, -7.529f, -5.639f, -1.890f, -0.587f, -0.867f, - 1.623f, 4.240f, 5.436f, 6.766f, 8.198f, 10.061f, 11.305f, 11.301f, 11.837f, 12.916f, - 14.434f, 16.606f, 19.863f, 21.806f, 22.411f, 22.090f, 23.884f, 25.218f, 24.534f, 24.702f, - 25.833f, 26.931f, 29.200f, 27.904f, 25.473f, 23.041f, 20.530f, 23.124f, 23.303f, 26.731f, - 34.187f, 37.167f, 40.781f, 45.690f, 45.268f, 44.007f, 43.669f, 42.814f, 42.729f, 42.772f, - 40.009f, 36.729f, 32.511f, 30.627f, 29.276f, 26.520f, 24.840f, 22.961f, 20.671f, 19.467f, - 18.615f, 20.337f, 21.007f, 19.592f, 23.769f, 25.206f, 27.593f, 29.653f, 30.598f, 30.833f, - 29.535f, 29.403f, 30.863f, 30.238f, 31.164f, 31.083f, 30.399f, 29.188f, 29.428f, 30.305f, - 29.804f, 29.555f, 26.652f, 25.672f, 24.597f, 24.207f, 22.776f, 19.687f, 17.363f, 15.210f, - 13.606f -},{ --29.534f,-27.879f,-23.572f,-19.791f,-16.091f,-13.672f,-11.843f, -9.598f, -5.456f, -1.653f, - 1.156f, 3.726f, 6.861f, 10.455f, 13.457f, 16.282f, 18.566f, 19.899f, 18.064f, 17.738f, - 17.223f, 15.681f, 15.046f, 15.764f, 17.542f, 18.890f, 20.284f, 22.179f, 23.652f, 25.288f, - 25.608f, 26.138f, 26.749f, 28.134f, 30.119f, 32.039f, 34.373f, 35.903f, 35.839f, 34.203f, - 33.751f, 33.061f, 32.456f, 32.271f, 32.748f, 32.759f, 32.140f, 31.589f, 30.590f, 29.908f, - 29.355f, 29.302f, 29.370f, 28.631f, 31.136f, 30.816f, 32.512f, 34.167f, 37.119f, 34.901f, - 33.039f, 30.714f, 30.876f, 29.373f, 28.406f, 27.020f, 25.663f, 23.086f, 21.256f, 20.509f, - 18.527f, 16.614f, 14.188f, 12.736f, 11.980f, 10.873f, 9.127f, 7.864f, 7.181f, 6.150f, - 4.160f, 1.580f, -1.450f, -4.765f, -7.626f,-11.797f,-14.364f,-14.966f,-19.525f,-20.620f, --19.364f,-17.872f,-15.890f,-12.894f, -9.424f, -7.728f, -6.113f, -2.680f, -0.794f, -1.452f, - 0.094f, 3.354f, 5.211f, 6.400f, 8.326f, 9.268f, 10.654f, 10.986f, 10.981f, 11.465f, - 12.137f, 14.245f, 16.810f, 18.545f, 19.548f, 20.291f, 21.972f, 23.260f, 22.952f, 23.202f, - 24.049f, 26.192f, 30.234f, 27.817f, 22.736f, 17.233f, 14.199f, 21.025f, 25.067f, 28.379f, - 36.194f, 42.536f, 44.511f, 44.537f, 43.787f, 42.885f, 42.745f, 42.160f, 41.302f, 40.773f, - 37.209f, 35.823f, 32.028f, 30.485f, 28.659f, 25.978f, 24.584f, 22.128f, 20.053f, 17.998f, - 18.779f, 19.478f, 19.376f, 18.308f, 21.194f, 22.680f, 25.398f, 28.263f, 29.132f, 30.210f, - 28.462f, 28.437f, 29.084f, 29.237f, 29.419f, 29.850f, 29.511f, 28.740f, 29.137f, 29.215f, - 29.462f, 29.105f, 26.424f, 25.349f, 24.459f, 24.124f, 22.700f, 19.661f, 17.343f, 15.193f, - 13.606f -},{ --29.534f,-27.887f,-23.497f,-19.746f,-16.059f,-13.619f,-11.433f, -8.672f, -4.791f, -1.201f, - 1.482f, 4.023f, 7.133f, 10.776f, 13.642f, 16.407f, 18.170f, 19.376f, 19.419f, 20.288f, - 18.798f, 16.026f, 15.033f, 15.451f, 17.588f, 19.025f, 20.643f, 22.436f, 24.066f, 24.973f, - 26.099f, 26.436f, 27.634f, 28.887f, 30.637f, 32.720f, 35.168f, 36.476f, 36.415f, 34.654f, - 34.147f, 33.315f, 32.419f, 32.575f, 33.032f, 33.238f, 32.651f, 32.583f, 31.397f, 30.222f, - 29.838f, 29.838f, 29.088f, 29.374f, 30.313f, 29.993f, 31.749f, 32.252f, 35.859f, 35.396f, - 32.954f, 32.178f, 31.122f, 28.433f, 26.670f, 25.547f, 24.040f, 21.820f, 19.297f, 17.666f, - 16.393f, 13.942f, 12.351f, 11.133f, 10.099f, 8.759f, 6.025f, 5.136f, 5.085f, 4.070f, - 1.916f, -0.484f, -3.429f, -6.780f, -9.741f,-13.555f,-15.184f,-18.309f,-20.584f,-21.231f, --19.952f,-19.080f,-17.552f,-13.627f, -9.624f, -7.288f, -5.858f, -3.475f, -2.324f, -1.289f, - -0.453f, 2.838f, 4.950f, 7.183f, 9.591f, 10.720f, 11.496f, 11.883f, 10.974f, 11.221f, - 11.896f, 13.392f, 14.688f, 16.084f, 17.340f, 18.853f, 21.164f, 21.819f, 21.544f, 22.143f, - 22.826f, 24.197f, 27.446f, 28.706f, 18.511f, 11.647f, 11.431f, 25.490f, 29.204f, 33.303f, - 39.531f, 43.995f, 44.481f, 43.828f, 43.254f, 43.254f, 42.269f, 41.583f, 39.929f, 38.812f, - 35.166f, 34.133f, 30.466f, 29.055f, 28.280f, 25.430f, 24.335f, 21.951f, 19.912f, 18.877f, - 19.383f, 18.744f, 18.814f, 17.958f, 19.017f, 20.332f, 23.352f, 26.427f, 28.319f, 28.939f, - 27.925f, 27.731f, 27.179f, 27.709f, 27.760f, 28.802f, 28.607f, 28.277f, 28.892f, 28.367f, - 29.120f, 28.674f, 26.224f, 25.069f, 24.310f, 24.061f, 22.610f, 19.644f, 17.322f, 15.176f, - 13.606f -},{ --29.534f,-27.896f,-23.420f,-19.690f,-15.991f,-13.458f,-10.839f, -7.599f, -3.996f, -0.705f, - 1.870f, 4.430f, 7.622f, 11.158f, 14.023f, 16.472f, 18.030f, 18.860f, 19.954f, 21.793f, - 20.328f, 16.184f, 15.322f, 15.335f, 17.419f, 19.270f, 20.779f, 22.449f, 24.428f, 25.177f, - 26.289f, 27.034f, 27.200f, 29.060f, 31.176f, 33.130f, 35.879f, 37.078f, 36.469f, 35.329f, - 34.591f, 33.523f, 32.871f, 32.534f, 33.073f, 33.449f, 32.928f, 33.265f, 32.494f, 31.204f, - 30.241f, 29.688f, 28.643f, 28.865f, 27.502f, 29.129f, 30.525f, 31.107f, 34.524f, 34.612f, - 32.924f, 32.113f, 32.884f, 28.662f, 26.678f, 24.401f, 22.929f, 20.929f, 19.257f, 17.636f, - 15.281f, 12.899f, 11.103f, 9.988f, 8.338f, 6.925f, 5.428f, 3.513f, 2.751f, 1.311f, - -1.592f, -3.139f, -5.479f, -9.444f,-12.677f,-15.005f,-16.878f,-19.555f,-20.833f,-21.359f, --20.823f,-18.733f,-15.890f,-12.937f,-10.578f, -8.736f, -7.062f, -4.985f, -3.136f, -0.711f, - -0.009f, 2.220f, 4.540f, 7.214f, 9.143f, 10.621f, 12.146f, 12.948f, 11.688f, 11.655f, - 12.433f, 12.730f, 13.343f, 14.242f, 15.334f, 17.256f, 19.169f, 20.116f, 21.178f, 22.784f, - 22.319f, 22.740f, 24.742f, 22.974f, 13.159f, 9.244f, 18.650f, 31.255f, 35.799f, 38.473f, - 40.470f, 42.733f, 44.752f, 43.810f, 40.494f, 41.763f, 42.273f, 41.317f, 38.639f, 36.707f, - 32.941f, 31.339f, 29.090f, 28.342f, 27.518f, 24.964f, 23.441f, 21.279f, 19.576f, 20.005f, - 19.513f, 18.869f, 18.589f, 17.872f, 17.835f, 18.747f, 21.557f, 24.381f, 27.109f, 27.757f, - 26.790f, 26.739f, 25.502f, 25.747f, 26.211f, 27.858f, 27.800f, 27.722f, 28.234f, 27.549f, - 28.662f, 28.307f, 25.942f, 24.823f, 24.147f, 24.014f, 22.512f, 19.633f, 17.299f, 15.158f, - 13.606f -},{ --29.534f,-27.906f,-23.341f,-19.616f,-15.881f,-13.186f,-10.107f, -6.489f, -3.093f, -0.140f, - 2.314f, 4.903f, 8.251f, 11.696f, 14.601f, 16.579f, 18.223f, 20.262f, 21.149f, 22.179f, - 21.156f, 16.557f, 15.614f, 15.593f, 17.354f, 19.420f, 21.126f, 22.571f, 24.233f, 26.056f, - 26.273f, 27.719f, 28.079f, 29.140f, 31.160f, 33.292f, 36.201f, 37.750f, 36.552f, 35.593f, - 35.068f, 34.374f, 33.208f, 32.565f, 32.848f, 33.327f, 33.375f, 33.432f, 34.127f, 32.608f, - 31.928f, 30.254f, 29.254f, 28.273f, 27.679f, 28.566f, 29.572f, 28.943f, 34.105f, 34.527f, - 32.527f, 30.796f, 31.022f, 28.443f, 25.617f, 24.309f, 22.194f, 19.435f, 17.732f, 16.229f, - 13.829f, 12.140f, 9.965f, 8.741f, 7.307f, 5.328f, 3.908f, 2.150f, 1.026f, -1.122f, - -4.390f, -5.625f, -6.965f,-10.433f,-14.581f,-15.899f,-17.661f,-18.931f,-20.582f,-21.303f, --20.906f,-18.880f,-15.666f,-12.359f,-10.656f, -8.876f, -7.504f, -6.115f, -4.669f, -1.813f, - -0.226f, 1.500f, 3.913f, 7.607f, 8.626f, 9.609f, 11.097f, 12.399f, 12.617f, 12.698f, - 13.283f, 13.216f, 13.357f, 13.686f, 14.486f, 15.552f, 16.913f, 18.028f, 19.708f, 21.249f, - 22.278f, 21.741f, 21.601f, 14.446f, 9.019f, 16.803f, 27.551f, 35.626f, 39.142f, 39.545f, - 40.758f, 42.225f, 43.346f, 42.330f, 39.958f, 38.406f, 41.328f, 39.103f, 38.413f, 33.114f, - 31.034f, 29.524f, 28.027f, 27.903f, 26.798f, 24.514f, 22.697f, 20.439f, 19.280f, 19.810f, - 19.017f, 19.044f, 18.311f, 18.137f, 17.417f, 17.957f, 20.311f, 22.889f, 25.180f, 26.797f, - 25.140f, 25.454f, 24.385f, 24.068f, 24.864f, 26.858f, 26.994f, 27.029f, 27.053f, 26.650f, - 28.038f, 28.028f, 25.508f, 24.594f, 23.975f, 23.969f, 22.407f, 19.628f, 17.275f, 15.140f, - 13.606f -},{ --29.534f,-27.916f,-23.261f,-19.522f,-15.728f,-12.823f, -9.311f, -5.442f, -2.135f, 0.489f, - 2.769f, 5.311f, 8.736f, 12.255f, 15.064f, 16.735f, 18.428f, 22.714f, 23.043f, 22.456f, - 21.201f, 17.175f, 16.108f, 16.043f, 17.720f, 19.423f, 21.232f, 22.521f, 24.222f, 26.095f, - 27.169f, 27.659f, 28.309f, 29.469f, 30.751f, 33.734f, 35.811f, 37.852f, 37.140f, 35.937f, - 35.116f, 34.166f, 33.218f, 33.014f, 32.906f, 33.301f, 33.634f, 33.717f, 35.063f, 34.837f, - 34.104f, 32.397f, 30.717f, 29.730f, 27.782f, 26.017f, 27.859f, 27.626f, 33.892f, 33.867f, - 32.289f, 31.145f, 29.856f, 28.733f, 26.239f, 23.783f, 20.625f, 18.333f, 16.316f, 14.651f, - 12.508f, 11.189f, 9.140f, 7.106f, 6.684f, 4.455f, 2.717f, 1.177f, -0.303f, -0.690f, - -5.234f, -7.556f, -7.818f,-11.187f,-14.893f,-16.502f,-18.094f,-19.400f,-20.283f,-19.783f, --19.028f,-17.853f,-14.730f,-11.730f,-10.546f, -9.884f, -9.317f, -8.577f, -5.203f, -3.052f, - -1.302f, 0.161f, 2.957f, 5.523f, 7.084f, 8.815f, 9.907f, 11.193f, 12.194f, 12.449f, - 13.656f, 14.913f, 14.794f, 14.487f, 14.763f, 14.870f, 15.404f, 15.743f, 17.209f, 19.677f, - 21.221f, 21.498f, 18.231f, 9.542f, 9.130f, 19.955f, 30.870f, 37.645f, 38.886f, 39.648f, - 40.268f, 40.967f, 41.084f, 41.153f, 38.556f, 36.509f, 39.493f, 39.401f, 35.937f, 32.465f, - 31.923f, 29.809f, 27.672f, 26.803f, 26.051f, 24.171f, 21.834f, 20.706f, 19.368f, 18.921f, - 17.680f, 18.266f, 18.450f, 18.282f, 17.783f, 17.704f, 19.611f, 21.791f, 23.652f, 25.774f, - 24.482f, 24.184f, 23.380f, 22.890f, 23.754f, 25.647f, 26.068f, 26.207f, 25.669f, 25.749f, - 27.288f, 27.814f, 24.916f, 24.357f, 23.797f, 23.911f, 22.298f, 19.628f, 17.250f, 15.121f, - 13.606f -},{ --29.534f,-27.926f,-23.182f,-19.407f,-15.535f,-12.400f, -8.532f, -4.521f, -1.195f, 1.147f, - 3.181f, 5.554f, 8.879f, 12.601f, 15.201f, 16.882f, 18.527f, 23.159f, 22.930f, 22.022f, - 21.169f, 17.725f, 16.344f, 16.580f, 18.034f, 19.782f, 21.399f, 22.840f, 24.507f, 26.201f, - 27.746f, 28.079f, 28.904f, 29.556f, 31.618f, 32.843f, 36.510f, 37.953f, 36.986f, 37.058f, - 35.666f, 34.917f, 33.871f, 33.244f, 33.018f, 33.258f, 33.626f, 34.059f, 35.263f, 35.528f, - 35.035f, 33.502f, 31.445f, 30.270f, 27.968f, 27.418f, 27.202f, 28.673f, 33.448f, 34.987f, - 34.296f, 31.267f, 30.281f, 28.819f, 26.242f, 22.380f, 18.644f, 17.472f, 15.550f, 14.109f, - 11.134f, 9.582f, 7.587f, 7.024f, 4.659f, 2.882f, 1.103f, 0.167f, -1.707f, -2.549f, - -4.977f, -9.657f,-12.094f,-13.183f,-15.095f,-16.427f,-17.525f,-18.054f,-18.837f,-18.437f, --17.391f,-16.123f,-13.774f,-11.500f,-10.624f,-11.120f,-11.345f, -8.675f, -6.108f, -3.976f, - -2.305f, -0.924f, 1.255f, 3.654f, 5.393f, 7.304f, 8.755f, 10.156f, 11.361f, 12.362f, - 13.576f, 15.147f, 15.399f, 14.914f, 14.414f, 13.629f, 13.805f, 14.514f, 15.352f, 17.707f, - 20.579f, 20.898f, 13.858f, 7.480f, 5.654f, 16.864f, 29.289f, 37.017f, 38.538f, 39.785f, - 39.887f, 40.649f, 39.782f, 39.567f, 36.894f, 34.317f, 37.340f, 36.162f, 33.961f, 33.543f, - 32.377f, 29.968f, 27.334f, 25.826f, 25.177f, 23.413f, 21.484f, 21.033f, 19.674f, 18.067f, - 16.416f, 16.530f, 18.547f, 18.202f, 17.929f, 17.735f, 18.865f, 20.431f, 22.584f, 24.876f, - 24.746f, 23.079f, 22.188f, 21.948f, 22.882f, 24.296f, 25.076f, 25.285f, 24.466f, 24.979f, - 26.508f, 27.589f, 24.233f, 24.092f, 23.615f, 23.822f, 22.183f, 19.629f, 17.224f, 15.103f, - 13.606f -},{ --29.534f,-27.938f,-23.103f,-19.272f,-15.312f,-11.958f, -7.839f, -3.755f, -0.360f, 1.775f, - 3.518f, 5.641f, 8.784f, 12.710f, 15.184f, 16.983f, 18.810f, 21.506f, 20.989f, 20.584f, - 20.999f, 18.122f, 16.417f, 17.239f, 18.210f, 19.866f, 21.644f, 23.278f, 24.795f, 27.067f, - 28.268f, 29.008f, 28.988f, 29.928f, 31.466f, 32.873f, 34.366f, 37.307f, 38.243f, 37.291f, - 36.728f, 35.451f, 34.242f, 33.561f, 33.457f, 33.211f, 33.229f, 33.478f, 34.801f, 35.385f, - 34.514f, 33.136f, 31.353f, 29.792f, 28.004f, 27.510f, 29.114f, 29.470f, 33.060f, 35.622f, - 33.209f, 31.242f, 30.441f, 28.941f, 25.873f, 21.264f, 16.690f, 15.893f, 14.360f, 13.348f, - 10.621f, 7.747f, 4.059f, 6.725f, 3.043f, 1.515f, -0.081f, -2.330f, -2.670f, -4.212f, - -7.489f, -8.873f,-13.589f,-15.855f,-15.602f,-16.321f,-16.492f,-16.417f,-17.178f,-16.259f, --15.482f,-14.365f,-13.083f,-11.617f,-11.045f,-11.623f,-10.600f, -8.248f, -6.620f, -5.493f, - -3.270f, -2.499f, -0.043f, 2.469f, 3.808f, 6.605f, 8.437f, 9.749f, 10.616f, 12.525f, - 13.519f, 13.799f, 13.787f, 13.969f, 13.690f, 12.950f, 12.938f, 14.474f, 15.000f, 15.835f, - 18.165f, 19.342f, 11.348f, 6.977f, 1.286f, 9.732f, 24.622f, 34.466f, 38.207f, 40.044f, - 39.971f, 39.347f, 39.535f, 37.944f, 36.039f, 32.271f, 32.466f, 33.107f, 33.795f, 33.731f, - 31.988f, 29.884f, 26.140f, 23.990f, 24.012f, 22.101f, 21.045f, 19.963f, 19.246f, 17.422f, - 15.598f, 15.477f, 18.502f, 18.171f, 17.715f, 17.541f, 18.272f, 19.308f, 21.524f, 23.858f, - 24.197f, 22.156f, 21.102f, 21.056f, 22.161f, 23.060f, 24.124f, 24.263f, 23.520f, 24.345f, - 25.790f, 27.267f, 23.562f, 23.787f, 23.429f, 23.687f, 22.063f, 19.632f, 17.196f, 15.084f, - 13.606f -},{ --29.534f,-27.949f,-23.028f,-19.121f,-15.070f,-11.533f, -7.275f, -3.142f, 0.294f, 2.298f, - 3.762f, 5.662f, 8.732f, 12.756f, 15.259f, 16.989f, 19.167f, 20.510f, 20.423f, 19.645f, - 20.472f, 18.480f, 16.964f, 17.791f, 18.666f, 20.276f, 21.991f, 23.522f, 25.386f, 27.601f, - 28.627f, 29.495f, 30.188f, 30.813f, 31.976f, 33.563f, 35.466f, 35.558f, 36.682f, 37.508f, - 37.135f, 36.809f, 35.280f, 34.144f, 33.321f, 33.257f, 33.319f, 33.704f, 34.478f, 34.636f, - 34.116f, 32.397f, 31.284f, 29.443f, 28.143f, 27.013f, 27.752f, 29.566f, 31.017f, 35.513f, - 36.054f, 34.344f, 32.366f, 29.259f, 25.634f, 21.118f, 18.589f, 15.084f, 12.553f, 12.236f, - 10.384f, 5.764f, 3.254f, -0.041f, 1.663f, -0.146f, -2.396f, -4.645f, -5.347f, -5.577f, - -6.384f, -8.392f,-11.365f,-15.325f,-15.123f,-15.092f,-14.994f,-13.950f,-13.702f,-11.885f, --11.529f,-12.869f,-12.702f,-11.562f,-11.173f,-10.885f, -9.767f, -8.451f, -7.307f, -5.958f, - -4.551f, -3.146f, -0.038f, 1.947f, 3.956f, 5.522f, 7.436f, 8.500f, 9.032f, 10.535f, - 11.873f, 12.526f, 13.033f, 13.221f, 13.379f, 13.166f, 12.697f, 14.148f, 14.514f, 15.292f, - 16.834f, 16.598f, 10.659f, 6.757f, 1.395f, 5.655f, 16.483f, 30.479f, 36.429f, 39.284f, - 38.778f, 38.116f, 38.473f, 35.717f, 34.973f, 32.970f, 31.186f, 32.543f, 32.628f, 32.703f, - 31.206f, 27.660f, 23.557f, 22.102f, 22.557f, 21.479f, 19.944f, 18.801f, 17.963f, 16.702f, - 15.289f, 15.465f, 18.459f, 18.188f, 17.720f, 17.417f, 18.128f, 18.370f, 20.550f, 22.339f, - 22.661f, 21.328f, 20.158f, 20.065f, 21.326f, 22.093f, 23.166f, 23.159f, 22.636f, 23.723f, - 25.182f, 26.800f, 22.999f, 23.439f, 23.237f, 23.496f, 21.935f, 19.634f, 17.168f, 15.065f, - 13.606f -},{ --29.534f,-27.961f,-22.956f,-18.956f,-14.821f,-11.152f, -6.854f, -2.664f, 0.725f, 2.638f, - 3.891f, 5.683f, 8.864f, 12.793f, 15.253f, 16.825f, 18.966f, 20.803f, 21.445f, 19.979f, - 20.365f, 19.236f, 17.333f, 18.271f, 19.375f, 20.764f, 22.492f, 23.920f, 25.774f, 27.776f, - 28.984f, 29.814f, 30.773f, 31.589f, 32.798f, 34.030f, 36.004f, 37.317f, 36.174f, 35.986f, - 38.018f, 38.196f, 37.196f, 35.409f, 34.328f, 33.372f, 33.204f, 33.549f, 33.603f, 33.264f, - 33.317f, 32.678f, 31.019f, 29.619f, 28.161f, 26.334f, 26.137f, 28.603f, 30.733f, 32.035f, - 34.574f, 35.394f, 31.757f, 29.125f, 26.711f, 19.442f, 18.437f, 14.780f, 10.968f, 10.291f, - 9.964f, 5.686f, 2.002f, -0.522f, -2.655f, -3.096f, -4.585f, -4.673f, -7.226f, -9.234f, - -9.328f,-12.226f,-11.672f,-10.940f,-12.566f,-13.284f,-12.341f, -9.406f, -6.610f, -7.340f, - -6.690f,-11.415f,-11.423f,-10.876f,-10.877f,-10.812f,-10.341f, -9.501f, -8.511f, -7.478f, - -5.989f, -2.586f, -0.172f, 1.989f, 3.322f, 4.712f, 6.216f, 7.703f, 8.344f, 9.142f, - 10.783f, 11.327f, 11.988f, 12.708f, 13.082f, 13.127f, 12.463f, 13.626f, 15.046f, 16.219f, - 16.653f, 14.804f, 12.453f, 8.888f, 5.161f, 5.671f, 12.443f, 27.555f, 35.551f, 40.028f, - 38.296f, 37.431f, 33.713f, 30.903f, 33.248f, 32.149f, 30.877f, 30.868f, 31.076f, 30.726f, - 29.283f, 25.338f, 21.069f, 20.400f, 20.691f, 20.446f, 19.291f, 18.589f, 16.656f, 15.875f, - 15.408f, 15.954f, 18.097f, 17.648f, 17.735f, 18.036f, 18.038f, 17.625f, 19.620f, 21.021f, - 21.217f, 20.225f, 19.223f, 18.931f, 20.259f, 21.322f, 22.082f, 22.047f, 21.664f, 23.020f, - 24.685f, 26.210f, 22.593f, 23.058f, 23.034f, 23.247f, 21.798f, 19.634f, 17.137f, 15.045f, - 13.606f -},{ --29.534f,-27.974f,-22.890f,-18.785f,-14.578f,-10.827f, -6.558f, -2.305f, 0.938f, 2.740f, - 3.869f, 5.694f, 9.044f, 12.622f, 14.723f, 16.467f, 18.208f, 20.753f, 21.808f, 20.839f, - 20.784f, 20.986f, 17.658f, 18.415f, 19.949f, 21.132f, 22.732f, 24.372f, 26.137f, 27.775f, - 28.907f, 30.247f, 31.697f, 32.448f, 33.640f, 34.610f, 35.569f, 37.032f, 39.020f, 38.414f, - 37.602f, 38.913f, 39.401f, 37.492f, 35.496f, 34.290f, 33.655f, 32.996f, 32.863f, 33.250f, - 32.979f, 31.983f, 31.399f, 29.282f, 27.799f, 26.327f, 25.710f, 25.333f, 27.185f, 30.251f, - 30.214f, 28.887f, 28.155f, 28.342f, 26.103f, 20.967f, 15.193f, 14.073f, 10.393f, 7.793f, - 7.253f, 5.958f, 3.090f, 1.048f, -5.203f, -7.980f, -7.079f, -6.085f, -8.684f,-10.049f, --12.651f,-13.808f,-11.391f,-11.023f,-13.173f,-14.782f,-11.881f, -8.983f, -8.357f, -8.251f, - -9.817f,-12.472f,-10.932f,-11.434f,-11.722f,-11.460f,-11.451f,-10.559f, -9.863f, -8.283f, - -5.324f, -2.019f, -0.617f, 0.954f, 2.179f, 3.651f, 5.088f, 6.592f, 7.460f, 7.925f, - 9.543f, 10.155f, 10.947f, 11.228f, 12.255f, 12.857f, 13.077f, 13.325f, 14.561f, 15.773f, - 16.214f, 15.258f, 16.110f, 11.527f, 7.537f, 6.814f, 15.178f, 29.386f, 36.680f, 39.885f, - 38.505f, 36.454f, 30.448f, 29.434f, 32.364f, 30.976f, 29.128f, 28.662f, 29.717f, 28.436f, - 27.298f, 24.603f, 21.752f, 19.331f, 19.581f, 19.388f, 18.506f, 17.644f, 15.546f, 15.179f, - 15.988f, 16.453f, 17.598f, 17.140f, 17.631f, 17.970f, 17.548f, 17.566f, 18.711f, 20.313f, - 19.931f, 18.703f, 18.483f, 17.921f, 19.281f, 20.608f, 20.910f, 21.007f, 20.679f, 22.283f, - 24.270f, 25.578f, 22.328f, 22.666f, 22.817f, 22.948f, 21.652f, 19.631f, 17.105f, 15.026f, - 13.606f -},{ --29.534f,-27.987f,-22.830f,-18.615f,-14.353f,-10.557f, -6.357f, -2.052f, 0.979f, 2.602f, - 3.667f, 5.633f, 9.040f, 12.119f, 13.627f, 15.963f, 17.762f, 20.302f, 21.564f, 21.542f, - 20.688f, 22.637f, 19.213f, 18.117f, 19.256f, 21.245f, 22.813f, 24.642f, 26.458f, 28.060f, - 29.009f, 30.428f, 32.286f, 33.468f, 34.548f, 35.412f, 36.125f, 37.019f, 38.750f, 39.577f, - 40.460f, 39.546f, 40.035f, 40.313f, 37.691f, 35.281f, 34.236f, 33.291f, 33.114f, 33.167f, - 32.943f, 31.795f, 31.038f, 29.889f, 28.067f, 27.055f, 25.914f, 24.551f, 24.263f, 25.052f, - 28.194f, 26.734f, 25.688f, 24.140f, 20.004f, 15.112f, 11.071f, 11.525f, 10.160f, 4.655f, - 4.730f, 5.589f, 4.034f, 0.528f, -9.399f, -9.057f,-11.342f,-10.171f,-10.246f,-11.045f, --11.682f,-13.169f,-14.031f,-12.946f,-13.498f,-14.663f,-14.623f,-12.763f,-12.163f,-12.372f, --11.860f,-13.023f,-12.620f,-12.937f,-12.507f,-12.287f,-11.882f,-11.292f,-10.109f, -7.715f, - -5.758f, -3.350f, -1.318f, -0.539f, 1.076f, 2.900f, 4.607f, 5.453f, 6.456f, 7.636f, - 8.622f, 9.392f, 9.938f, 10.070f, 11.684f, 12.576f, 12.683f, 12.814f, 13.856f, 15.124f, - 15.500f, 15.533f, 18.877f, 14.373f, 9.980f, 6.975f, 14.589f, 28.515f, 37.041f, 38.985f, - 38.510f, 35.772f, 28.393f, 28.491f, 29.301f, 29.374f, 26.920f, 27.505f, 28.115f, 25.988f, - 24.798f, 24.750f, 23.322f, 18.844f, 18.303f, 18.547f, 17.406f, 16.319f, 15.324f, 14.825f, - 15.931f, 16.462f, 17.312f, 16.460f, 16.743f, 16.842f, 17.264f, 17.381f, 18.130f, 19.436f, - 18.624f, 17.337f, 17.852f, 17.225f, 18.675f, 19.889f, 19.845f, 20.038f, 19.852f, 21.624f, - 23.889f, 24.998f, 22.138f, 22.289f, 22.586f, 22.614f, 21.497f, 19.623f, 17.071f, 15.006f, - 13.606f -},{ --29.534f,-28.001f,-22.779f,-18.453f,-14.153f,-10.330f, -6.216f, -1.902f, 0.910f, 2.289f, - 3.304f, 5.464f, 8.796f, 11.531f, 12.582f, 15.426f, 18.006f, 20.663f, 21.889f, 21.635f, - 20.390f, 22.862f, 21.672f, 19.553f, 19.298f, 20.047f, 22.604f, 24.483f, 26.472f, 28.386f, - 29.427f, 30.954f, 32.603f, 34.001f, 35.470f, 36.379f, 36.937f, 37.740f, 38.452f, 39.735f, - 40.121f, 42.287f, 41.385f, 40.972f, 39.963f, 37.990f, 35.138f, 33.900f, 33.436f, 33.210f, - 34.210f, 32.260f, 31.245f, 30.229f, 29.520f, 28.297f, 26.938f, 24.928f, 23.110f, 22.302f, - 23.908f, 24.618f, 23.923f, 22.382f, 19.006f, 15.017f, 12.455f, 9.544f, 7.559f, 4.251f, - 0.996f, 1.758f, 1.971f, -3.298f, -8.223f, -9.677f,-11.470f,-14.336f,-13.239f,-12.221f, --11.387f,-11.259f,-13.854f,-14.459f,-15.470f,-16.077f,-16.724f,-16.437f,-16.292f,-14.464f, --12.084f,-13.583f,-14.285f,-14.064f,-13.161f,-13.121f,-12.676f,-11.660f,-10.516f, -9.198f, - -6.735f, -4.579f, -2.907f, -1.533f, -0.176f, 1.800f, 3.059f, 4.283f, 5.635f, 7.188f, - 8.645f, 9.505f, 9.243f, 9.700f, 11.500f, 12.528f, 12.594f, 12.975f, 14.083f, 16.041f, - 16.305f, 16.326f, 17.496f, 15.483f, 12.808f, 17.308f, 20.881f, 33.139f, 36.927f, 37.378f, - 37.691f, 36.097f, 27.341f, 25.597f, 24.510f, 27.059f, 24.625f, 25.371f, 25.093f, 23.263f, - 23.131f, 22.831f, 21.188f, 17.991f, 17.088f, 17.466f, 17.359f, 16.038f, 15.533f, 15.194f, - 15.795f, 15.672f, 16.828f, 15.455f, 16.032f, 16.576f, 17.422f, 16.817f, 18.074f, 18.287f, - 17.561f, 16.605f, 16.974f, 16.696f, 18.151f, 19.144f, 19.013f, 19.095f, 19.220f, 21.063f, - 23.487f, 24.520f, 21.942f, 21.950f, 22.345f, 22.264f, 21.338f, 19.610f, 17.035f, 14.987f, - 13.606f -},{ --29.534f,-28.015f,-22.736f,-18.308f,-13.983f,-10.130f, -6.109f, -1.849f, 0.784f, 1.916f, - 2.870f, 5.218f, 8.471f, 11.252f, 12.264f, 15.101f, 18.355f, 21.524f, 22.462f, 21.064f, - 21.026f, 23.108f, 23.292f, 22.119f, 21.867f, 20.540f, 22.804f, 24.767f, 26.622f, 28.761f, - 30.237f, 31.700f, 33.080f, 34.192f, 36.120f, 37.358f, 38.088f, 38.722f, 39.014f, 39.442f, - 40.163f, 41.602f, 43.548f, 43.267f, 41.743f, 39.174f, 37.844f, 35.388f, 33.799f, 32.710f, - 33.728f, 32.260f, 31.410f, 30.604f, 30.034f, 29.659f, 29.109f, 25.612f, 23.124f, 22.265f, - 21.191f, 19.295f, 18.744f, 18.097f, 15.585f, 11.892f, 9.064f, 5.901f, 3.615f, 3.179f, - 1.165f, -1.619f, -3.881f, -8.901f,-10.352f,-10.872f,-11.560f,-12.395f,-13.288f,-14.001f, --11.897f,-12.184f,-15.458f,-15.702f,-18.367f,-19.163f,-19.256f,-18.277f,-17.536f,-16.564f, --14.069f,-13.704f,-14.430f,-13.163f,-11.621f,-12.521f,-13.194f,-12.908f,-11.676f,-10.065f, - -7.791f, -5.126f, -3.892f, -2.426f, -1.050f, 0.291f, 2.337f, 3.523f, 5.339f, 6.409f, - 8.002f, 9.187f, 9.205f, 9.495f, 10.353f, 11.712f, 13.301f, 14.219f, 13.473f, 13.579f, - 16.883f, 17.302f, 16.770f, 15.698f, 14.292f, 27.906f, 26.707f, 32.900f, 35.977f, 36.522f, - 36.716f, 35.371f, 27.678f, 22.512f, 21.533f, 25.829f, 23.296f, 23.718f, 23.794f, 22.832f, - 21.303f, 20.435f, 19.671f, 17.348f, 16.634f, 16.804f, 17.422f, 16.648f, 15.349f, 16.471f, - 15.834f, 15.072f, 15.970f, 15.009f, 16.029f, 17.028f, 17.535f, 16.827f, 18.217f, 17.488f, - 16.603f, 16.215f, 16.058f, 16.207f, 17.301f, 18.348f, 18.338f, 18.197f, 18.663f, 20.490f, - 23.014f, 24.121f, 21.677f, 21.659f, 22.099f, 21.918f, 21.176f, 19.590f, 16.997f, 14.967f, - 13.606f -},{ --29.534f,-28.029f,-22.703f,-18.185f,-13.847f, -9.944f, -6.029f, -1.889f, 0.622f, 1.602f, - 2.499f, 4.975f, 8.253f, 11.347f, 12.672f, 15.260f, 18.391f, 21.790f, 23.161f, 20.783f, - 21.722f, 24.116f, 23.286f, 22.228f, 22.993f, 22.804f, 23.695f, 25.782f, 27.260f, 29.226f, - 30.959f, 32.493f, 33.718f, 34.913f, 36.743f, 38.185f, 39.207f, 39.741f, 39.735f, 39.921f, - 40.615f, 42.232f, 43.643f, 44.702f, 44.549f, 42.333f, 39.551f, 37.417f, 35.463f, 33.316f, - 33.173f, 32.156f, 32.228f, 31.018f, 30.456f, 29.746f, 29.401f, 27.337f, 24.162f, 22.378f, - 21.063f, 18.321f, 17.558f, 15.416f, 13.053f, 10.874f, 8.282f, 5.563f, 3.230f, 0.277f, - -1.184f, -4.876f, -7.920f,-10.708f,-11.831f,-10.077f,-10.743f,-15.370f,-16.181f,-14.547f, --16.749f,-13.597f,-16.573f,-16.335f,-18.226f,-20.154f,-20.437f,-18.512f,-18.401f,-17.429f, --16.410f,-15.725f,-15.754f,-13.252f,-11.177f,-12.835f,-13.375f,-12.488f,-11.531f, -7.793f, - -4.444f, -3.891f, -4.673f, -3.533f, -1.604f, 0.055f, 1.846f, 2.844f, 4.312f, 5.411f, - 6.952f, 8.507f, 10.308f, 10.923f, 11.289f, 13.007f, 13.941f, 12.667f, 10.781f, 13.477f, - 16.521f, 17.056f, 16.446f, 15.961f, 15.355f, 24.295f, 24.730f, 32.362f, 35.371f, 36.234f, - 34.646f, 33.528f, 29.121f, 20.609f, 20.391f, 25.691f, 21.664f, 22.318f, 22.490f, 20.769f, - 19.478f, 17.879f, 18.218f, 16.766f, 16.112f, 16.249f, 16.830f, 16.091f, 15.472f, 17.211f, - 16.123f, 15.153f, 14.830f, 14.503f, 15.710f, 17.237f, 17.690f, 17.295f, 18.053f, 16.774f, - 15.675f, 15.790f, 15.456f, 15.730f, 16.271f, 17.501f, 17.656f, 17.413f, 18.068f, 19.790f, - 22.451f, 23.732f, 21.329f, 21.404f, 21.850f, 21.597f, 21.016f, 19.564f, 16.956f, 14.947f, - 13.606f -},{ --29.534f,-28.043f,-22.681f,-18.092f,-13.746f, -9.765f, -5.985f, -2.008f, 0.415f, 1.425f, - 2.302f, 4.813f, 8.194f, 11.489f, 13.177f, 15.800f, 18.297f, 21.572f, 24.514f, 21.450f, - 21.411f, 23.912f, 23.221f, 21.717f, 22.679f, 23.599f, 25.008f, 26.671f, 28.067f, 29.875f, - 31.634f, 32.898f, 34.231f, 35.658f, 37.457f, 39.003f, 40.169f, 40.902f, 41.184f, 40.892f, - 40.737f, 42.383f, 44.048f, 45.406f, 45.450f, 43.888f, 41.659f, 39.526f, 36.999f, 34.632f, - 33.085f, 32.178f, 31.103f, 29.807f, 29.439f, 28.915f, 28.909f, 28.835f, 25.332f, 22.349f, - 20.392f, 18.110f, 16.659f, 14.273f, 12.009f, 10.714f, 8.808f, 5.544f, 1.769f, -1.764f, - -4.036f, -6.365f, -9.594f,-10.772f,-10.537f,-12.240f,-15.556f,-18.885f,-18.815f,-16.822f, --15.318f,-13.424f,-14.931f,-18.736f,-20.346f,-18.771f,-19.232f,-17.751f,-16.910f,-15.285f, --16.299f,-12.138f,-15.343f,-15.407f,-13.815f,-13.371f,-12.716f,-11.802f, -9.737f, -4.041f, - -3.994f, -4.914f, -5.454f, -4.005f, -1.779f, 0.014f, 0.960f, 2.606f, 3.980f, 4.885f, - 6.321f, 8.654f, 10.523f, 10.530f, 11.416f, 11.606f, 11.576f, 12.159f, 13.322f, 14.796f, - 17.320f, 17.542f, 20.302f, 20.325f, 17.920f, 19.447f, 23.257f, 28.885f, 35.700f, 35.653f, - 33.882f, 30.682f, 26.731f, 20.152f, 16.699f, 21.651f, 19.705f, 21.078f, 21.264f, 18.545f, - 15.996f, 16.039f, 16.079f, 15.905f, 15.788f, 15.684f, 15.711f, 14.434f, 15.331f, 16.207f, - 15.537f, 14.036f, 13.858f, 13.708f, 15.205f, 17.406f, 17.259f, 17.671f, 17.548f, 15.743f, - 14.992f, 15.254f, 14.892f, 15.114f, 15.423f, 16.604f, 16.887f, 16.748f, 17.447f, 18.993f, - 21.816f, 23.282f, 20.924f, 21.159f, 21.602f, 21.310f, 20.863f, 19.529f, 16.913f, 14.927f, - 13.606f -},{ --29.534f,-28.058f,-22.670f,-18.031f,-13.679f, -9.596f, -5.997f, -2.195f, 0.148f, 1.398f, - 2.318f, 4.775f, 8.228f, 11.407f, 13.232f, 16.110f, 18.117f, 21.455f, 25.728f, 22.263f, - 20.929f, 22.397f, 24.382f, 22.630f, 23.363f, 24.145f, 26.054f, 27.431f, 28.868f, 30.625f, - 32.027f, 33.201f, 34.575f, 36.465f, 38.248f, 39.957f, 41.298f, 42.273f, 42.524f, 42.095f, - 41.815f, 42.613f, 43.471f, 44.921f, 45.874f, 46.218f, 43.924f, 40.580f, 38.213f, 35.997f, - 33.627f, 31.987f, 30.092f, 28.573f, 27.146f, 26.522f, 26.461f, 25.918f, 24.203f, 21.635f, - 19.567f, 17.595f, 15.215f, 12.853f, 10.037f, 8.347f, 5.921f, 2.882f, -0.504f, -4.500f, - -4.025f, -6.721f,-10.140f,-11.451f,-10.280f,-13.711f,-17.063f,-17.190f,-18.878f,-18.165f, --18.540f,-19.301f,-17.204f,-20.382f,-19.732f,-18.800f,-19.140f,-18.337f,-18.877f,-14.724f, --14.050f,-15.821f,-16.531f,-16.509f,-16.085f,-14.984f,-13.229f,-10.916f, -7.740f, -6.645f, - -5.010f, -4.549f, -4.028f, -3.396f, -2.742f, -0.934f, 0.268f, 2.089f, 3.506f, 5.429f, - 7.074f, 7.837f, 8.445f, 7.943f, 8.790f, 9.821f, 11.368f, 14.383f, 17.860f, 19.593f, - 19.290f, 20.190f, 20.915f, 23.566f, 27.636f, 24.190f, 25.229f, 29.579f, 35.006f, 35.648f, - 32.134f, 28.318f, 24.576f, 19.461f, 17.437f, 17.655f, 17.423f, 19.790f, 19.895f, 17.004f, - 13.989f, 14.288f, 14.175f, 13.928f, 14.684f, 15.231f, 15.383f, 13.293f, 14.440f, 15.253f, - 13.752f, 12.637f, 13.963f, 13.918f, 14.955f, 17.469f, 16.189f, 17.718f, 16.862f, 14.696f, - 14.334f, 14.508f, 14.083f, 14.322f, 14.709f, 15.621f, 16.049f, 16.098f, 16.874f, 18.255f, - 21.146f, 22.738f, 20.521f, 20.889f, 21.352f, 21.064f, 20.720f, 19.485f, 16.866f, 14.907f, - 13.606f -},{ --29.534f,-28.073f,-22.671f,-18.006f,-13.643f, -9.446f, -6.085f, -2.434f, -0.176f, 1.480f, - 2.512f, 4.863f, 8.291f, 11.179f, 12.853f, 15.685f, 17.796f, 21.503f, 25.818f, 22.345f, - 20.403f, 21.301f, 25.269f, 22.819f, 23.380f, 25.079f, 26.572f, 28.134f, 29.565f, 31.072f, - 32.438f, 33.595f, 35.346f, 37.262f, 38.978f, 41.127f, 42.585f, 43.518f, 43.977f, 43.349f, - 42.765f, 43.018f, 43.353f, 44.456f, 45.672f, 46.454f, 45.429f, 42.885f, 39.905f, 36.911f, - 34.441f, 32.245f, 30.254f, 28.399f, 26.584f, 24.883f, 23.321f, 21.658f, 19.956f, 17.330f, - 15.554f, 13.161f, 12.324f, 11.395f, 9.985f, 6.681f, 4.479f, 1.428f, -1.510f, -5.450f, - -9.344f, -7.249f, -9.252f,-11.743f,-13.682f,-16.147f,-18.903f,-21.205f,-22.632f,-22.424f, --21.520f,-21.351f,-21.973f,-21.859f,-18.554f,-17.816f,-17.978f,-16.080f,-15.433f,-15.681f, --12.102f,-14.132f,-16.114f,-17.511f,-16.660f,-14.392f,-12.686f,-10.726f, -8.381f, -7.091f, - -6.420f, -3.451f, -2.352f, -3.119f, -4.783f, -2.816f, 0.481f, 0.727f, 2.987f, 4.790f, - 5.667f, 6.432f, 6.226f, 6.517f, 7.500f, 9.396f, 12.641f, 15.406f, 16.536f, 16.975f, - 16.960f, 17.657f, 19.778f, 23.767f, 25.538f, 25.788f, 26.980f, 29.763f, 34.238f, 33.849f, - 30.346f, 26.351f, 21.725f, 20.051f, 15.254f, 16.098f, 14.532f, 17.790f, 17.974f, 15.402f, - 12.378f, 12.876f, 13.000f, 12.385f, 12.854f, 15.040f, 15.499f, 13.424f, 14.186f, 14.496f, - 11.790f, 11.657f, 13.703f, 13.837f, 14.804f, 16.686f, 15.355f, 16.833f, 15.930f, 13.761f, - 13.591f, 13.446f, 13.152f, 13.530f, 13.889f, 14.560f, 15.168f, 15.381f, 16.341f, 17.689f, - 20.464f, 22.115f, 20.179f, 20.569f, 21.097f, 20.852f, 20.588f, 19.430f, 16.816f, 14.887f, - 13.606f -},{ --29.534f,-28.088f,-22.684f,-18.017f,-13.636f, -9.331f, -6.259f, -2.720f, -0.517f, 1.619f, - 2.828f, 5.049f, 8.357f, 11.018f, 12.432f, 14.838f, 17.802f, 21.866f, 25.525f, 21.993f, - 19.439f, 20.912f, 25.116f, 22.876f, 23.309f, 25.577f, 27.265f, 28.645f, 30.213f, 31.626f, - 32.661f, 34.171f, 36.202f, 38.196f, 39.765f, 42.603f, 43.950f, 45.148f, 45.093f, 44.393f, - 43.229f, 42.213f, 42.709f, 46.260f, 45.670f, 46.635f, 45.719f, 43.277f, 41.099f, 38.340f, - 35.237f, 32.803f, 31.169f, 29.095f, 26.998f, 25.099f, 22.913f, 20.449f, 18.039f, 15.876f, - 13.917f, 11.721f, 9.849f, 7.341f, 6.199f, 5.670f, 3.695f, 0.423f, -2.502f, -4.836f, --11.044f,-11.054f,-10.677f,-12.871f,-15.499f,-17.881f,-20.051f,-21.816f,-24.062f,-24.569f, --23.453f,-23.807f,-24.773f,-24.531f,-23.038f,-22.755f,-20.729f,-19.503f,-20.029f,-19.718f, --19.258f,-19.298f,-19.739f,-19.611f,-16.406f,-14.688f,-13.129f,-11.399f, -8.533f, -7.035f, - -7.431f, -6.454f, -1.881f, -1.214f, -5.438f, -2.834f, 1.353f, 0.144f, 0.495f, 1.809f, - 2.647f, 4.088f, 4.951f, 5.555f, 7.658f, 10.236f, 12.170f, 13.797f, 14.024f, 14.142f, - 14.395f, 15.689f, 18.837f, 20.772f, 22.277f, 24.782f, 25.755f, 27.104f, 30.609f, 30.616f, - 29.007f, 24.856f, 20.114f, 17.979f, 12.709f, 14.151f, 13.224f, 15.420f, 16.107f, 12.603f, - 10.993f, 11.656f, 11.891f, 11.127f, 11.363f, 13.983f, 14.267f, 13.315f, 13.733f, 13.774f, - 11.391f, 12.143f, 13.187f, 12.845f, 14.364f, 15.003f, 14.820f, 15.517f, 14.902f, 13.001f, - 12.898f, 12.109f, 12.082f, 12.691f, 13.008f, 13.525f, 14.236f, 14.641f, 15.745f, 17.239f, - 19.762f, 21.456f, 19.944f, 20.193f, 20.835f, 20.667f, 20.467f, 19.363f, 16.763f, 14.867f, - 13.606f -},{ --29.534f,-28.104f,-22.708f,-18.062f,-13.656f, -9.267f, -6.510f, -3.048f, -0.811f, 1.780f, - 3.234f, 5.304f, 8.422f, 10.947f, 12.298f, 14.460f, 18.539f, 22.721f, 25.628f, 21.774f, - 19.509f, 21.367f, 25.187f, 23.923f, 23.829f, 25.971f, 27.829f, 29.277f, 31.001f, 32.284f, - 33.323f, 34.760f, 36.763f, 38.689f, 40.631f, 43.515f, 45.382f, 46.330f, 46.156f, 45.533f, - 44.323f, 43.339f, 43.135f, 43.349f, 45.147f, 46.411f, 45.694f, 43.685f, 41.734f, 39.479f, - 36.592f, 34.153f, 32.279f, 30.051f, 27.421f, 25.144f, 23.009f, 20.591f, 18.144f, 15.842f, - 13.427f, 11.255f, 8.466f, 6.099f, 5.413f, 4.325f, 2.964f, 0.689f, -2.316f, -6.218f, - -9.384f,-12.082f,-13.348f,-12.770f,-15.734f,-18.889f,-20.470f,-21.368f,-23.633f,-24.281f, --23.793f,-25.244f,-26.750f,-26.759f,-28.048f,-26.906f,-24.208f,-24.984f,-24.951f,-24.078f, --22.920f,-23.673f,-22.748f,-21.455f,-18.133f,-17.290f,-14.193f,-11.028f,-10.619f, -8.136f, - -8.274f, -6.547f, -3.246f, -1.819f, -1.557f, 1.058f, -0.581f, -1.139f, -1.238f, 0.964f, - 1.960f, 3.388f, 4.498f, 5.930f, 8.391f, 10.170f, 11.558f, 12.219f, 11.957f, 11.590f, - 11.824f, 14.214f, 17.641f, 19.007f, 19.504f, 22.167f, 23.978f, 25.272f, 27.850f, 30.397f, - 29.789f, 24.428f, 19.437f, 14.943f, 15.834f, 12.611f, 12.159f, 13.552f, 14.155f, 10.270f, - 10.943f, 11.073f, 10.693f, 9.959f, 10.236f, 12.013f, 12.731f, 12.865f, 12.780f, 13.586f, - 11.745f, 12.268f, 12.332f, 12.532f, 13.946f, 13.497f, 14.646f, 14.880f, 13.927f, 12.549f, - 11.909f, 10.737f, 10.847f, 11.612f, 12.180f, 12.584f, 13.243f, 13.961f, 15.017f, 16.737f, - 19.029f, 20.803f, 19.837f, 19.785f, 20.563f, 20.494f, 20.356f, 19.284f, 16.707f, 14.848f, - 13.606f -},{ --29.534f,-28.119f,-22.744f,-18.137f,-13.699f, -9.263f, -6.812f, -3.418f, -1.005f, 1.944f, - 3.724f, 5.616f, 8.499f, 10.879f, 12.487f, 14.989f, 19.457f, 23.500f, 25.618f, 21.625f, - 20.876f, 22.729f, 25.362f, 24.860f, 24.232f, 26.407f, 28.325f, 29.917f, 31.559f, 32.552f, - 33.728f, 35.362f, 37.133f, 38.907f, 41.196f, 44.486f, 46.516f, 47.267f, 47.044f, 46.068f, - 44.974f, 44.024f, 43.733f, 44.768f, 45.564f, 46.354f, 46.194f, 44.833f, 42.531f, 40.311f, - 38.227f, 36.083f, 33.756f, 30.947f, 28.037f, 25.600f, 23.215f, 21.016f, 18.549f, 16.077f, - 13.593f, 10.999f, 8.564f, 6.127f, 4.139f, 3.425f, 2.296f, -0.286f, -2.123f, -6.924f, --10.480f,-12.939f,-14.381f,-14.881f,-15.452f,-20.155f,-22.058f,-21.590f,-23.436f,-24.017f, --26.714f,-31.129f,-29.374f,-30.361f,-31.845f,-29.931f,-31.048f,-29.865f,-28.786f,-28.080f, --26.981f,-26.236f,-24.565f,-23.769f,-22.428f,-20.885f,-18.227f,-14.108f,-12.381f,-12.253f, - -9.728f, -8.925f, -7.977f, -4.688f, -3.661f, -3.579f, -3.289f, -1.881f, -1.096f, -0.255f, - 1.925f, 4.492f, 5.790f, 6.769f, 7.916f, 9.510f, 11.251f, 11.317f, 10.327f, 9.510f, - 9.797f, 12.351f, 14.922f, 16.578f, 17.642f, 19.715f, 22.302f, 22.996f, 25.829f, 29.310f, - 29.469f, 24.190f, 18.764f, 17.115f, 20.900f, 12.924f, 10.809f, 11.390f, 11.844f, 9.566f, - 10.526f, 9.907f, 9.587f, 9.005f, 9.265f, 11.094f, 11.565f, 12.105f, 11.935f, 13.042f, - 11.428f, 11.482f, 11.463f, 12.092f, 13.486f, 12.542f, 14.135f, 14.141f, 12.661f, 11.933f, - 10.668f, 9.716f, 9.785f, 10.462f, 11.285f, 11.666f, 12.222f, 13.316f, 14.226f, 16.084f, - 18.290f, 20.184f, 19.860f, 19.385f, 20.285f, 20.321f, 20.251f, 19.190f, 16.647f, 14.828f, - 13.606f -},{ --29.534f,-28.135f,-22.792f,-18.237f,-13.763f, -9.322f, -7.122f, -3.819f, -1.084f, 2.092f, - 4.266f, 5.989f, 8.640f, 10.861f, 12.794f, 15.873f, 19.765f, 23.512f, 25.265f, 21.556f, - 21.755f, 23.756f, 24.834f, 25.516f, 24.843f, 27.033f, 28.957f, 30.354f, 31.962f, 32.968f, - 34.191f, 35.807f, 37.461f, 39.066f, 41.412f, 44.614f, 47.414f, 48.297f, 49.219f, 46.372f, - 44.988f, 44.373f, 44.086f, 43.865f, 44.993f, 45.954f, 45.620f, 45.415f, 43.619f, 41.663f, - 39.577f, 37.498f, 34.821f, 31.342f, 28.335f, 26.066f, 24.231f, 22.104f, 19.953f, 16.364f, - 13.900f, 11.622f, 9.643f, 7.011f, 4.521f, 3.119f, 1.585f, -0.144f, -2.885f, -6.321f, - -9.610f,-12.141f,-14.986f,-18.452f,-21.550f,-23.311f,-24.009f,-25.446f,-26.124f,-27.032f, --31.052f,-33.349f,-33.689f,-34.031f,-34.491f,-34.426f,-32.783f,-31.462f,-30.646f,-31.366f, --30.343f,-29.016f,-27.679f,-26.704f,-26.079f,-24.052f,-22.869f,-19.336f,-15.611f,-12.328f, --12.455f,-10.783f, -9.002f, -8.007f, -6.290f, -5.935f, -4.078f, -2.966f, -2.272f, -0.529f, - 1.880f, 5.798f, 5.899f, 6.278f, 7.785f, 9.272f, 10.150f, 9.645f, 8.390f, 7.513f, - 7.119f, 8.806f, 11.351f, 12.856f, 14.439f, 16.922f, 19.864f, 21.553f, 23.366f, 28.121f, - 28.816f, 24.136f, 18.191f, 21.772f, 20.146f, 12.761f, 9.115f, 9.024f, 9.246f, 8.577f, - 9.525f, 8.804f, 8.175f, 8.298f, 9.343f, 10.176f, 10.350f, 10.570f, 11.486f, 12.895f, - 11.292f, 11.377f, 11.614f, 11.629f, 12.712f, 12.019f, 12.902f, 12.850f, 11.325f, 11.024f, - 9.925f, 9.131f, 9.056f, 9.558f, 10.249f, 10.708f, 11.274f, 12.609f, 13.523f, 15.364f, - 17.619f, 19.621f, 19.992f, 19.031f, 20.005f, 20.139f, 20.147f, 19.082f, 16.585f, 14.808f, - 13.606f -},{ --29.534f,-28.150f,-22.849f,-18.356f,-13.844f, -9.435f, -7.396f, -4.233f, -1.088f, 2.195f, - 4.768f, 6.415f, 8.879f, 11.015f, 12.939f, 16.235f, 19.591f, 22.912f, 24.804f, 22.013f, - 22.876f, 24.295f, 24.474f, 26.007f, 25.408f, 27.589f, 29.257f, 30.660f, 32.060f, 33.152f, - 34.478f, 35.892f, 37.398f, 38.993f, 41.519f, 44.612f, 47.087f, 47.881f, 48.713f, 46.593f, - 44.978f, 44.576f, 43.702f, 43.021f, 46.470f, 45.588f, 44.485f, 43.785f, 44.036f, 42.680f, - 40.867f, 38.586f, 35.782f, 32.244f, 29.686f, 27.101f, 25.055f, 23.266f, 21.124f, 17.652f, - 14.720f, 11.911f, 9.927f, 7.436f, 5.000f, 3.003f, 1.305f, -0.504f, -3.026f, -6.299f, - -9.408f,-11.340f,-14.012f,-16.639f,-19.694f,-21.241f,-23.057f,-27.099f,-26.724f,-26.803f, --29.794f,-33.389f,-35.345f,-36.494f,-37.493f,-37.531f,-37.061f,-37.760f,-37.644f,-33.533f, --32.985f,-31.161f,-29.548f,-29.229f,-29.885f,-29.165f,-26.443f,-23.311f,-18.715f,-14.179f, --13.437f,-11.547f, -9.757f, -9.041f, -8.390f, -7.279f, -5.370f, -3.543f, -2.002f, 0.775f, - 3.462f, 3.880f, 4.151f, 4.580f, 6.216f, 7.760f, 7.898f, 7.239f, 5.705f, 5.089f, - 4.860f, 5.287f, 6.831f, 8.310f, 10.380f, 13.497f, 16.489f, 18.907f, 23.479f, 26.890f, - 27.274f, 24.623f, 20.179f, 23.316f, 18.426f, 11.277f, 7.320f, 6.992f, 6.835f, 7.370f, - 7.756f, 7.130f, 7.148f, 7.582f, 8.039f, 8.568f, 9.100f, 9.204f, 10.942f, 12.697f, - 11.232f, 11.146f, 11.129f, 11.223f, 11.873f, 11.342f, 12.034f, 12.111f, 10.702f, 10.395f, - 9.573f, 8.710f, 8.446f, 8.827f, 9.279f, 9.819f, 10.518f, 11.833f, 12.990f, 14.761f, - 17.085f, 19.136f, 20.185f, 18.738f, 19.728f, 19.943f, 20.040f, 18.960f, 16.519f, 14.788f, - 13.606f -},{ --29.534f,-28.166f,-22.916f,-18.487f,-13.938f, -9.587f, -7.596f, -4.624f, -1.084f, 2.226f, - 5.101f, 6.838f, 9.141f, 11.223f, 12.796f, 15.917f, 19.555f, 22.187f, 23.668f, 22.714f, - 25.470f, 25.430f, 25.016f, 26.025f, 26.348f, 27.636f, 29.045f, 30.669f, 32.034f, 33.133f, - 34.522f, 35.937f, 37.361f, 39.153f, 41.301f, 44.481f, 46.543f, 48.490f, 47.499f, 46.455f, - 44.856f, 44.221f, 43.257f, 43.058f, 45.870f, 45.261f, 44.434f, 43.487f, 43.285f, 42.670f, - 42.023f, 39.765f, 37.201f, 34.085f, 31.871f, 30.291f, 28.000f, 26.113f, 23.752f, 20.198f, - 15.247f, 11.346f, 9.112f, 6.817f, 4.435f, 1.986f, -0.081f, -1.423f, -1.672f, -4.853f, - -7.836f,-10.239f,-13.656f,-15.893f,-21.432f,-23.297f,-25.008f,-27.757f,-25.931f,-28.662f, --31.801f,-34.383f,-36.273f,-37.302f,-38.636f,-39.603f,-39.769f,-39.880f,-40.519f,-39.688f, --35.341f,-33.241f,-30.366f,-30.012f,-30.496f,-29.856f,-29.050f,-25.359f,-20.502f,-16.541f, --14.519f,-13.356f,-11.710f,-10.961f, -9.862f, -8.962f, -5.987f, -3.819f, -0.441f, -0.172f, - -1.151f, -0.433f, 1.105f, 2.052f, 3.911f, 5.274f, 4.877f, 4.027f, 2.860f, 2.486f, - 2.491f, 2.179f, 2.373f, 3.323f, 5.698f, 9.633f, 13.996f, 18.438f, 24.181f, 26.122f, - 25.964f, 25.697f, 20.348f, 21.591f, 13.829f, 8.209f, 5.686f, 5.130f, 4.350f, 4.702f, - 5.482f, 6.041f, 6.509f, 6.594f, 7.033f, 7.234f, 8.308f, 8.771f, 10.080f, 11.206f, - 11.163f, 10.676f, 10.939f, 11.149f, 11.040f, 10.008f, 11.859f, 11.854f, 10.566f, 9.818f, - 8.889f, 8.347f, 7.877f, 8.039f, 8.501f, 9.132f, 9.975f, 11.113f, 12.556f, 14.384f, - 16.698f, 18.754f, 20.366f, 18.488f, 19.458f, 19.733f, 19.925f, 18.824f, 16.452f, 14.768f, - 13.606f -},{ --29.534f,-28.181f,-22.992f,-18.622f,-14.040f, -9.755f, -7.702f, -4.952f, -1.132f, 2.192f, - 5.200f, 7.161f, 9.249f, 11.142f, 12.510f, 15.584f, 19.692f, 21.509f, 21.763f, 22.793f, - 27.139f, 26.841f, 25.537f, 25.721f, 27.149f, 27.702f, 28.928f, 30.497f, 31.913f, 33.012f, - 34.443f, 35.954f, 37.487f, 39.140f, 41.270f, 44.141f, 45.625f, 50.892f, 46.969f, 46.556f, - 44.527f, 43.767f, 43.905f, 43.947f, 43.911f, 45.364f, 44.479f, 43.615f, 43.571f, 43.362f, - 42.612f, 40.413f, 38.416f, 36.366f, 33.774f, 32.517f, 31.378f, 30.967f, 26.327f, 22.452f, - 18.067f, 13.217f, 8.474f, 5.754f, 5.257f, 4.739f, 4.932f, 3.333f, 0.085f, -3.651f, - -6.700f, -9.556f,-11.028f,-14.223f,-19.413f,-24.457f,-26.387f,-27.145f,-23.729f,-29.225f, --32.410f,-34.702f,-36.543f,-38.236f,-39.337f,-40.713f,-41.262f,-40.740f,-41.072f,-41.620f, --41.311f,-36.186f,-32.683f,-31.031f,-30.568f,-31.328f,-30.155f,-26.215f,-21.917f,-18.244f, --18.174f,-17.102f,-15.072f,-11.331f, -7.649f, -5.347f, -4.542f, -4.340f, -3.549f, -4.652f, - -5.087f, -3.833f, -2.317f, 0.225f, 1.592f, 1.970f, 1.506f, 0.529f, -0.178f, -0.181f, - -0.320f, -1.309f, -2.168f, -1.306f, 1.331f, 6.326f, 13.335f, 19.033f, 23.647f, 23.986f, - 22.407f, 23.199f, 18.835f, 16.774f, 6.502f, 4.202f, 3.435f, 2.467f, 0.784f, 1.410f, - 3.434f, 4.705f, 5.506f, 5.210f, 6.794f, 6.460f, 7.874f, 8.354f, 9.332f, 10.071f, - 10.977f, 9.788f, 10.435f, 10.682f, 9.930f, 8.882f, 11.771f, 11.037f, 10.274f, 8.894f, - 8.001f, 8.013f, 7.372f, 7.231f, 7.768f, 8.587f, 9.503f, 10.530f, 12.083f, 14.160f, - 16.381f, 18.480f, 20.440f, 18.236f, 19.196f, 19.515f, 19.798f, 18.676f, 16.382f, 14.748f, - 13.606f -},{ --29.534f,-28.197f,-23.075f,-18.756f,-14.144f, -9.917f, -7.716f, -5.179f, -1.243f, 2.149f, - 5.127f, 7.308f, 9.098f, 10.659f, 12.330f, 15.720f, 19.565f, 21.039f, 20.844f, 22.654f, - 26.662f, 27.814f, 25.834f, 26.537f, 27.357f, 28.160f, 28.863f, 30.495f, 31.668f, 32.970f, - 34.436f, 36.075f, 37.586f, 39.266f, 41.370f, 43.920f, 45.258f, 50.084f, 47.001f, 46.493f, - 44.850f, 43.936f, 44.044f, 45.165f, 46.320f, 45.642f, 44.514f, 43.655f, 43.534f, 43.715f, - 42.759f, 40.832f, 38.833f, 36.922f, 34.526f, 33.176f, 32.986f, 30.260f, 25.874f, 22.480f, - 19.151f, 14.569f, 11.983f, 9.279f, 7.991f, 8.033f, 7.268f, 3.887f, 0.084f, -3.033f, - -6.410f, -8.221f, -9.514f,-12.145f,-17.883f,-26.089f,-26.579f,-22.107f,-26.892f,-30.300f, --32.638f,-35.044f,-37.679f,-39.119f,-39.993f,-41.755f,-42.903f,-43.223f,-43.700f,-42.830f, --43.372f,-41.997f,-36.292f,-34.601f,-34.095f,-33.942f,-32.393f,-28.403f,-24.624f,-22.029f, --20.486f,-19.775f,-16.827f,-14.769f, -9.855f, -8.346f, -8.618f, -8.488f, -9.151f,-10.146f, - -9.909f, -8.183f, -5.739f, -3.249f, -1.827f, -1.520f, -1.297f, -2.264f, -3.094f, -3.301f, - -4.183f, -5.786f, -6.555f, -4.387f, 0.251f, 5.885f, 13.440f, 19.625f, 20.481f, 20.675f, - 20.256f, 18.466f, 14.051f, 11.916f, 2.029f, 0.569f, 1.063f, -1.057f, -3.035f, -2.642f, - 0.420f, 2.822f, 3.504f, 4.575f, 6.093f, 6.429f, 6.795f, 8.618f, 9.047f, 9.106f, - 10.002f, 9.369f, 9.264f, 9.205f, 8.955f, 8.185f, 10.472f, 9.382f, 9.889f, 8.150f, - 7.254f, 7.508f, 6.884f, 6.545f, 7.057f, 8.009f, 8.934f, 9.998f, 11.507f, 13.899f, - 16.019f, 18.280f, 20.321f, 17.928f, 18.938f, 19.294f, 19.656f, 18.519f, 16.311f, 14.728f, - 13.606f -},{ --29.534f,-28.212f,-23.164f,-18.882f,-14.247f,-10.052f, -7.657f, -5.285f, -1.376f, 2.170f, - 5.052f, 7.281f, 8.795f, 10.134f, 12.303f, 15.899f, 19.028f, 21.004f, 21.935f, 23.366f, - 26.410f, 28.243f, 27.065f, 28.901f, 28.227f, 28.759f, 28.946f, 30.717f, 31.461f, 32.401f, - 34.398f, 36.043f, 37.601f, 39.257f, 41.414f, 44.018f, 45.061f, 46.548f, 47.243f, 46.147f, - 45.218f, 44.775f, 44.949f, 46.380f, 47.213f, 46.176f, 44.189f, 43.344f, 42.746f, 42.639f, - 43.013f, 41.192f, 39.142f, 36.725f, 34.687f, 32.871f, 31.428f, 28.235f, 24.966f, 21.988f, - 18.928f, 14.888f, 12.325f, 10.177f, 8.844f, 9.039f, 7.655f, 6.443f, 3.654f, 0.123f, - -2.206f, -2.871f, -7.154f,-13.120f,-17.663f,-23.013f,-25.482f,-27.321f,-28.059f,-31.223f, --33.384f,-37.016f,-39.639f,-40.348f,-40.966f,-42.039f,-43.625f,-44.925f,-45.387f,-44.924f, --45.018f,-44.108f,-40.355f,-37.364f,-36.852f,-36.250f,-34.423f,-31.084f,-28.057f,-24.644f, --22.862f,-21.244f,-18.965f,-17.970f,-13.512f,-12.188f,-11.807f,-12.281f,-14.086f,-14.789f, --15.181f,-13.296f, -9.883f, -7.509f, -5.438f, -4.993f, -4.729f, -5.785f, -6.578f, -6.915f, - -8.492f,-10.325f, -9.907f, -5.385f, 4.182f, 8.703f, 14.988f, 17.319f, 18.466f, 18.292f, - 19.194f, 11.180f, 11.506f, 4.940f, -2.073f, -2.133f, -1.481f, -3.511f, -5.029f, -5.434f, - -4.604f, -0.533f, 1.625f, 3.778f, 4.961f, 5.718f, 6.420f, 7.852f, 8.803f, 8.516f, - 8.474f, 9.142f, 8.839f, 8.968f, 8.897f, 7.565f, 7.839f, 7.806f, 9.418f, 7.649f, - 6.466f, 6.782f, 6.431f, 5.960f, 6.545f, 7.337f, 8.269f, 9.374f, 10.881f, 13.454f, - 15.546f, 18.083f, 19.964f, 17.534f, 18.678f, 19.079f, 19.499f, 18.356f, 16.239f, 14.708f, - 13.606f -},{ --29.534f,-28.227f,-23.259f,-18.997f,-14.341f,-10.146f, -7.553f, -5.273f, -1.465f, 2.296f, - 5.123f, 7.163f, 8.582f, 10.014f, 12.276f, 15.501f, 18.370f, 21.279f, 23.354f, 24.451f, - 26.877f, 27.529f, 28.687f, 30.834f, 29.440f, 29.547f, 29.445f, 30.724f, 31.430f, 32.247f, - 33.949f, 35.798f, 37.487f, 39.032f, 41.409f, 43.819f, 44.282f, 45.796f, 46.872f, 45.506f, - 45.257f, 45.077f, 45.361f, 46.152f, 46.733f, 45.757f, 44.154f, 43.399f, 42.843f, 42.593f, - 42.294f, 42.614f, 40.913f, 36.995f, 34.064f, 31.870f, 29.516f, 26.222f, 23.434f, 20.901f, - 17.670f, 14.852f, 11.982f, 9.299f, 6.850f, 6.852f, 5.851f, 2.854f, 3.336f, 2.588f, - 1.160f, -1.018f, -4.768f,-11.276f,-16.658f,-19.795f,-24.261f,-26.891f,-28.573f,-30.438f, --33.880f,-33.617f,-35.514f,-43.055f,-41.887f,-42.893f,-44.186f,-45.181f,-46.922f,-47.533f, --47.756f,-47.352f,-45.566f,-40.641f,-38.786f,-38.789f,-36.616f,-33.118f,-29.030f,-26.842f, --24.822f,-23.982f,-21.311f,-19.199f,-16.791f,-14.618f,-14.846f,-16.229f,-17.825f,-18.700f, --19.773f,-19.076f,-15.872f,-12.522f,-10.780f, -9.579f, -9.926f,-10.420f,-10.734f,-10.742f, --12.531f,-14.250f,-12.139f, -3.315f, 4.943f, 11.241f, 14.971f, 15.984f, 16.204f, 13.538f, - 10.657f, 5.424f, 9.426f, -1.051f, -5.499f, -4.279f, -3.783f, -5.539f, -8.507f, -6.938f, - -7.245f, -4.074f, -0.047f, 2.883f, 4.117f, 5.138f, 6.191f, 6.977f, 7.872f, 7.750f, - 7.338f, 8.112f, 8.392f, 9.374f, 8.911f, 7.061f, 6.174f, 7.332f, 8.659f, 6.777f, - 5.591f, 5.828f, 5.862f, 5.308f, 6.129f, 6.639f, 7.652f, 8.659f, 10.294f, 12.817f, - 14.986f, 17.815f, 19.400f, 17.066f, 18.412f, 18.871f, 19.329f, 18.191f, 16.166f, 14.687f, - 13.606f -},{ --29.534f,-28.241f,-23.357f,-19.098f,-14.425f,-10.196f, -7.434f, -5.172f, -1.454f, 2.493f, - 5.341f, 7.062f, 8.585f, 10.272f, 12.201f, 14.856f, 17.993f, 21.532f, 23.606f, 24.934f, - 26.607f, 26.456f, 29.791f, 31.995f, 30.181f, 30.371f, 29.206f, 30.111f, 31.343f, 32.194f, - 33.481f, 35.286f, 37.159f, 38.765f, 40.991f, 43.334f, 44.809f, 47.002f, 45.583f, 45.112f, - 45.185f, 44.956f, 44.727f, 44.632f, 44.653f, 44.824f, 44.107f, 43.582f, 42.776f, 42.123f, - 41.590f, 41.941f, 40.721f, 37.605f, 34.239f, 31.114f, 28.051f, 25.263f, 22.620f, 18.774f, - 16.392f, 14.549f, 12.074f, 8.040f, 4.757f, 2.898f, 2.331f, 1.018f, -0.252f, -0.880f, - -1.203f, -1.914f, -5.049f, -8.427f,-12.921f,-18.044f,-18.404f,-20.627f,-24.911f,-31.190f, --32.786f,-38.067f,-39.892f,-43.131f,-41.520f,-43.280f,-44.276f,-46.008f,-47.171f,-48.813f, --49.225f,-49.776f,-49.929f,-47.004f,-42.804f,-40.935f,-39.501f,-35.695f,-30.560f,-27.947f, --25.992f,-25.411f,-23.435f,-21.380f,-19.048f,-15.833f,-17.389f,-19.810f,-21.959f,-23.147f, --24.113f,-24.198f,-22.583f,-19.599f,-17.502f,-15.755f,-15.298f,-15.359f,-14.782f,-14.510f, --15.071f,-16.147f,-14.092f, -3.308f, 5.392f, 11.243f, 11.993f, 11.809f, 13.048f, 10.623f, - 3.137f, 4.660f, -1.376f, -6.393f, -7.392f, -6.251f, -5.663f, -8.324f,-11.823f, -8.645f, - -8.315f, -6.367f, -1.080f, 1.481f, 2.989f, 4.080f, 5.094f, 6.417f, 7.115f, 7.276f, - 6.953f, 7.458f, 7.757f, 9.298f, 8.036f, 6.593f, 6.313f, 7.508f, 7.539f, 5.557f, - 4.745f, 4.602f, 4.869f, 4.430f, 5.419f, 5.939f, 7.129f, 7.989f, 9.759f, 12.089f, - 14.422f, 17.435f, 18.736f, 16.576f, 18.136f, 18.673f, 19.147f, 18.028f, 16.093f, 14.667f, - 13.606f -},{ --29.534f,-28.256f,-23.458f,-19.184f,-14.493f,-10.204f, -7.318f, -5.021f, -1.333f, 2.678f, - 5.562f, 7.050f, 8.709f, 10.471f, 12.261f, 14.941f, 18.120f, 21.594f, 23.650f, 25.213f, - 26.208f, 27.265f, 31.976f, 33.005f, 30.178f, 30.513f, 28.779f, 29.413f, 30.957f, 31.859f, - 33.084f, 34.740f, 36.588f, 38.304f, 40.360f, 41.886f, 43.322f, 45.143f, 44.993f, 44.605f, - 44.876f, 44.999f, 44.554f, 44.600f, 47.419f, 44.489f, 43.915f, 43.661f, 42.751f, 41.608f, - 40.969f, 41.241f, 40.916f, 38.699f, 34.498f, 31.117f, 27.612f, 24.673f, 21.446f, 17.533f, - 14.934f, 13.375f, 10.620f, 6.332f, 3.352f, 1.268f, -0.748f, -2.888f, -5.310f, -6.095f, - -6.641f, -6.863f, -7.032f, -9.143f,-10.283f,-13.726f,-15.688f,-18.313f,-24.050f,-30.456f, --33.197f,-34.567f,-37.521f,-38.502f,-41.763f,-43.094f,-44.221f,-45.848f,-47.423f,-48.425f, --49.549f,-50.778f,-51.348f,-49.509f,-46.861f,-46.408f,-42.027f,-39.071f,-34.192f,-30.473f, --28.290f,-27.710f,-25.809f,-23.461f,-21.517f,-17.942f,-19.302f,-21.895f,-25.308f,-26.843f, --28.025f,-28.013f,-27.327f,-25.813f,-24.150f,-22.180f,-20.990f,-19.967f,-18.624f,-18.237f, --17.356f,-15.800f,-12.388f, -0.104f, 6.095f, 9.295f, 10.020f, 7.863f, 4.931f, -0.492f, - -7.695f, -6.319f, -7.977f, -7.770f, -8.958f, -8.902f, -7.998f,-11.148f,-12.915f,-11.655f, --10.037f, -8.435f, -2.524f, 0.172f, 1.561f, 2.505f, 3.908f, 5.132f, 5.898f, 6.738f, - 6.847f, 6.956f, 6.612f, 8.245f, 6.773f, 6.452f, 6.558f, 7.222f, 6.025f, 4.489f, - 3.860f, 3.481f, 3.696f, 3.396f, 4.432f, 5.202f, 6.563f, 7.452f, 9.216f, 11.375f, - 13.911f, 16.961f, 18.121f, 16.140f, 17.851f, 18.481f, 18.958f, 17.872f, 16.021f, 14.647f, - 13.606f -},{ --29.534f,-28.270f,-23.561f,-19.256f,-14.546f,-10.180f, -7.208f, -4.856f, -1.136f, 2.787f, - 5.635f, 7.163f, 8.794f, 10.360f, 12.602f, 15.907f, 18.552f, 21.364f, 24.289f, 25.706f, - 26.665f, 29.431f, 35.043f, 33.821f, 30.889f, 30.106f, 28.749f, 29.196f, 30.669f, 31.628f, - 32.927f, 34.177f, 36.278f, 37.762f, 39.694f, 40.810f, 42.965f, 44.213f, 44.436f, 44.354f, - 44.541f, 44.975f, 44.910f, 46.184f, 51.917f, 44.892f, 43.542f, 43.280f, 42.081f, 40.996f, - 40.493f, 40.262f, 40.554f, 38.520f, 34.527f, 30.898f, 27.533f, 24.079f, 20.799f, 17.158f, - 14.436f, 11.130f, 7.991f, 4.911f, 2.482f, 0.768f, -1.814f, -4.217f, -6.696f, -9.080f, --11.206f,-12.877f,-13.381f,-12.770f,-14.040f,-14.761f,-16.316f,-20.562f,-26.311f,-30.344f, --32.479f,-34.386f,-36.194f,-38.646f,-40.838f,-42.761f,-44.190f,-45.374f,-46.812f,-48.509f, --48.937f,-49.266f,-49.658f,-50.201f,-49.067f,-48.652f,-48.502f,-43.523f,-38.655f,-34.465f, --32.070f,-27.935f,-28.455f,-25.906f,-24.073f,-21.102f,-21.086f,-22.782f,-26.825f,-29.328f, --30.885f,-31.342f,-30.836f,-29.788f,-28.219f,-26.843f,-26.188f,-24.735f,-23.139f,-20.572f, --17.681f,-11.346f, -3.974f, 4.108f, 5.902f, 6.475f, 5.497f, 4.637f, -7.703f,-11.868f, --15.891f,-15.991f,-11.229f, -8.968f,-10.584f,-10.968f,-10.426f,-13.687f,-14.187f,-13.591f, --11.801f,-10.247f, -4.185f, -1.011f, 0.407f, 1.604f, 2.607f, 3.753f, 5.131f, 5.689f, - 6.032f, 6.178f, 5.519f, 6.126f, 5.733f, 6.356f, 5.744f, 5.885f, 4.626f, 3.798f, - 3.015f, 2.791f, 2.931f, 2.555f, 3.646f, 4.464f, 5.867f, 6.981f, 8.625f, 10.714f, - 13.438f, 16.458f, 17.683f, 15.825f, 17.561f, 18.291f, 18.767f, 17.729f, 15.950f, 14.626f, - 13.606f -},{ --29.534f,-28.284f,-23.663f,-19.317f,-14.583f,-10.137f, -7.096f, -4.696f, -0.915f, 2.846f, - 5.582f, 7.433f, 8.847f, 10.203f, 13.080f, 16.724f, 18.754f, 20.833f, 24.282f, 25.745f, - 27.406f, 31.048f, 36.330f, 35.690f, 33.133f, 30.102f, 28.943f, 29.207f, 30.555f, 31.477f, - 32.761f, 34.083f, 35.700f, 37.371f, 39.230f, 40.781f, 44.195f, 44.857f, 44.329f, 44.337f, - 44.466f, 44.856f, 44.876f, 47.874f, 50.171f, 44.569f, 43.164f, 42.604f, 41.604f, 40.885f, - 40.080f, 39.882f, 39.463f, 37.705f, 34.206f, 30.691f, 27.184f, 23.597f, 20.237f, 16.898f, - 13.585f, 10.184f, 7.185f, 4.202f, 2.021f, 0.608f, -1.815f, -4.644f, -6.665f, -9.197f, --11.251f,-13.315f,-15.304f,-17.019f,-17.586f,-19.425f,-21.902f,-25.500f,-28.525f,-30.681f, --30.190f,-33.971f,-36.926f,-38.188f,-40.360f,-42.082f,-43.787f,-44.867f,-46.313f,-48.051f, --49.168f,-49.990f,-50.323f,-51.695f,-52.660f,-52.663f,-52.086f,-51.120f,-47.127f,-41.718f, --36.516f,-33.254f,-30.413f,-28.087f,-26.305f,-23.966f,-22.699f,-23.773f,-27.731f,-31.364f, --32.930f,-33.140f,-32.774f,-31.814f,-30.803f,-29.863f,-28.480f,-27.083f,-25.661f,-21.075f, --13.200f, -5.293f, -1.135f, 3.136f, 3.915f, 1.294f, 4.962f, -2.919f,-11.902f,-17.313f, --20.601f,-16.263f,-11.810f,-10.022f,-11.722f,-12.476f,-12.435f,-15.269f,-15.811f,-15.283f, --13.562f,-11.463f, -5.724f, -2.094f, 0.022f, 0.655f, 0.966f, 2.106f, 3.775f, 4.616f, - 4.859f, 5.153f, 3.714f, 4.107f, 4.751f, 5.378f, 4.229f, 3.987f, 3.837f, 3.135f, - 2.412f, 2.177f, 2.576f, 2.128f, 3.180f, 3.832f, 5.199f, 6.469f, 8.024f, 10.092f, - 12.939f, 15.993f, 17.470f, 15.657f, 17.273f, 18.098f, 18.579f, 17.600f, 15.880f, 14.605f, - 13.606f -},{ --29.534f,-28.297f,-23.765f,-19.369f,-14.607f,-10.091f, -6.970f, -4.535f, -0.703f, 2.976f, - 5.634f, 7.890f, 9.051f, 10.391f, 13.426f, 16.594f, 18.440f, 20.243f, 22.892f, 24.990f, - 28.035f, 32.532f, 36.854f, 38.580f, 34.267f, 30.317f, 29.145f, 29.159f, 30.370f, 31.334f, - 32.739f, 34.176f, 35.270f, 36.919f, 38.706f, 40.883f, 44.714f, 43.020f, 43.284f, 44.033f, - 44.343f, 44.580f, 44.523f, 47.603f, 47.302f, 43.762f, 42.848f, 42.256f, 40.472f, 39.963f, - 38.797f, 37.546f, 37.344f, 36.245f, 33.963f, 30.432f, 26.754f, 22.973f, 19.607f, 16.596f, - 13.623f, 10.343f, 6.937f, 3.712f, 1.961f, 0.730f, -1.361f, -4.018f, -6.530f, -8.774f, --11.308f,-13.570f,-15.820f,-17.478f,-19.352f,-21.683f,-23.746f,-26.202f,-28.703f,-30.415f, --32.430f,-33.776f,-36.261f,-38.323f,-40.366f,-41.775f,-44.105f,-45.486f,-47.305f,-48.442f, --49.270f,-50.387f,-50.861f,-50.847f,-54.319f,-54.008f,-53.493f,-53.357f,-51.651f,-48.516f, --44.219f,-40.175f,-34.328f,-31.252f,-29.289f,-26.846f,-25.776f,-25.137f,-28.915f,-32.286f, --34.250f,-34.652f,-33.895f,-33.241f,-32.567f,-31.067f,-30.199f,-28.749f,-24.016f,-14.869f, - -6.978f, -3.041f, -1.414f, 1.378f, -0.558f, -1.998f, 0.894f, -7.336f,-12.491f,-16.910f, --18.034f,-11.441f,-10.923f,-11.745f,-12.605f,-14.077f,-14.755f,-16.382f,-16.913f,-16.019f, --14.870f,-12.846f, -7.175f, -2.767f, -1.154f, -0.263f, -0.575f, 0.476f, 2.344f, 3.552f, - 3.816f, 3.470f, 1.886f, 2.411f, 3.643f, 3.543f, 2.659f, 2.651f, 3.008f, 2.111f, - 1.894f, 1.499f, 2.338f, 1.958f, 2.635f, 3.284f, 4.776f, 5.914f, 7.485f, 9.504f, - 12.384f, 15.604f, 17.432f, 15.616f, 16.992f, 17.898f, 18.397f, 17.491f, 15.812f, 14.583f, - 13.606f -},{ --29.534f,-28.310f,-23.865f,-19.418f,-14.622f,-10.053f, -6.823f, -4.353f, -0.494f, 3.312f, - 6.080f, 8.521f, 9.524f, 10.901f, 13.512f, 15.913f, 17.875f, 19.721f, 21.464f, 24.032f, - 28.396f, 33.533f, 38.369f, 40.727f, 35.252f, 30.790f, 28.792f, 29.093f, 30.393f, 31.368f, - 32.864f, 34.127f, 35.174f, 36.212f, 38.517f, 40.609f, 42.582f, 43.049f, 43.441f, 43.913f, - 43.972f, 44.203f, 44.083f, 45.400f, 44.427f, 43.201f, 42.829f, 41.937f, 40.227f, 39.140f, - 37.746f, 36.578f, 35.864f, 35.616f, 33.380f, 30.843f, 27.020f, 23.499f, 19.911f, 16.754f, - 14.525f, 11.228f, 6.841f, 3.628f, 1.852f, 0.586f, -1.137f, -2.923f, -5.782f, -8.952f, --11.171f,-13.405f,-15.659f,-17.516f,-19.722f,-22.314f,-24.465f,-27.204f,-29.567f,-31.264f, --32.654f,-35.927f,-37.097f,-39.090f,-39.039f,-41.361f,-44.041f,-46.327f,-47.989f,-49.096f, --50.034f,-50.927f,-52.064f,-52.513f,-52.219f,-54.406f,-54.728f,-54.190f,-52.654f,-51.051f, --47.700f,-44.040f,-36.869f,-34.173f,-31.011f,-29.138f,-28.683f,-28.492f,-32.067f,-34.320f, --35.340f,-35.230f,-34.316f,-33.491f,-33.131f,-32.310f,-31.243f,-27.982f,-20.640f,-12.366f, - -8.173f, -3.668f, -1.699f, -0.601f, -2.591f, -4.580f, -1.862f, -9.472f,-13.231f,-17.996f, --15.373f,-11.910f,-11.991f,-13.780f,-14.779f,-16.175f,-16.119f,-17.617f,-18.108f,-16.107f, --15.055f,-14.239f, -8.235f, -4.022f, -2.938f, -1.967f, -2.366f, -1.420f, 0.799f, 2.227f, - 3.146f, 2.599f, 0.766f, 1.304f, 2.293f, 1.839f, 1.503f, 1.932f, 1.727f, 1.109f, - 1.067f, 1.105f, 2.201f, 1.883f, 1.938f, 2.651f, 4.559f, 5.406f, 7.036f, 8.993f, - 11.826f, 15.274f, 17.451f, 15.643f, 16.723f, 17.690f, 18.226f, 17.402f, 15.746f, 14.561f, - 13.606f -},{ --29.534f,-28.322f,-23.963f,-19.468f,-14.634f,-10.034f, -6.660f, -4.133f, -0.252f, 3.892f, - 7.005f, 9.223f, 10.125f, 11.318f, 13.357f, 15.412f, 17.427f, 19.181f, 21.082f, 23.500f, - 27.868f, 32.256f, 38.374f, 41.107f, 36.953f, 31.126f, 28.822f, 29.196f, 30.511f, 31.491f, - 32.768f, 34.150f, 35.086f, 36.263f, 38.174f, 39.741f, 41.400f, 41.964f, 43.024f, 43.123f, - 43.430f, 43.660f, 43.855f, 43.528f, 43.209f, 42.752f, 41.875f, 40.553f, 38.939f, 37.190f, - 36.109f, 35.056f, 33.721f, 33.029f, 32.872f, 30.329f, 27.781f, 23.718f, 20.412f, 17.604f, - 14.865f, 11.355f, 7.507f, 4.183f, 2.337f, 0.594f, -0.752f, -2.569f, -5.069f, -8.144f, --10.702f,-13.340f,-15.781f,-17.828f,-19.914f,-22.578f,-25.087f,-27.876f,-30.008f,-31.964f, --33.364f,-35.422f,-37.899f,-39.210f,-41.172f,-43.127f,-43.612f,-46.116f,-47.961f,-49.507f, --50.660f,-51.800f,-52.594f,-52.543f,-53.388f,-53.397f,-54.210f,-56.069f,-53.792f,-51.842f, --49.528f,-46.813f,-40.523f,-36.768f,-33.698f,-31.622f,-30.876f,-32.009f,-34.441f,-36.191f, --36.372f,-35.917f,-34.430f,-33.236f,-33.170f,-32.932f,-31.976f,-25.591f,-18.940f,-13.467f, - -7.788f, -4.698f, -2.778f, -3.641f, -5.479f, -7.340f, -3.983f,-10.146f,-15.984f,-20.606f, --15.610f,-12.953f,-13.893f,-16.748f,-16.424f,-18.239f,-17.794f,-19.173f,-19.294f,-16.429f, --15.518f,-15.323f, -9.317f, -5.915f, -5.363f, -3.888f, -4.614f, -3.353f, -0.626f, 1.190f, - 1.587f, 1.217f, -0.365f, 1.186f, 0.881f, 0.680f, 1.004f, 1.271f, 0.666f, 0.454f, - -0.084f, 0.795f, 1.873f, 1.899f, 1.572f, 1.934f, 4.279f, 4.993f, 6.645f, 8.612f, - 11.373f, 14.962f, 17.408f, 15.669f, 16.467f, 17.474f, 18.069f, 17.335f, 15.682f, 14.539f, - 13.606f -},{ --29.534f,-28.334f,-24.057f,-19.523f,-14.648f,-10.037f, -6.503f, -3.877f, 0.053f, 4.606f, - 8.163f, 9.820f, 10.517f, 11.314f, 12.976f, 15.085f, 17.144f, 18.852f, 21.065f, 23.475f, - 26.692f, 30.034f, 36.042f, 38.981f, 35.986f, 30.475f, 28.984f, 29.660f, 30.923f, 31.472f, - 32.583f, 34.013f, 35.046f, 36.318f, 37.753f, 39.232f, 40.537f, 41.454f, 42.389f, 42.829f, - 42.827f, 43.016f, 43.259f, 43.073f, 42.652f, 41.916f, 40.664f, 39.029f, 37.366f, 36.418f, - 34.697f, 33.107f, 32.330f, 31.368f, 30.658f, 30.357f, 28.538f, 24.919f, 21.053f, 18.108f, - 14.723f, 10.881f, 7.737f, 4.902f, 2.616f, 1.111f, -0.702f, -2.622f, -3.848f, -1.082f, --10.763f,-13.736f,-15.577f,-17.367f,-19.386f,-21.960f,-25.113f,-27.378f,-29.949f,-32.231f, --34.182f,-36.060f,-38.398f,-40.490f,-42.137f,-41.229f,-41.576f,-47.266f,-49.195f,-50.654f, --51.707f,-52.752f,-53.873f,-53.814f,-53.588f,-53.649f,-53.606f,-54.441f,-54.937f,-53.153f, --50.829f,-47.594f,-42.681f,-39.790f,-36.175f,-34.035f,-33.372f,-33.860f,-34.230f,-36.632f, --36.503f,-36.040f,-34.530f,-32.524f,-32.679f,-33.122f,-33.318f,-26.400f,-19.361f,-11.135f, - -6.458f, -5.040f, -5.111f, -5.431f, -7.474f, -9.115f, -7.606f,-10.183f,-17.355f,-19.542f, --15.284f,-13.630f,-16.555f,-18.592f,-17.881f,-20.177f,-19.909f,-20.398f,-20.389f,-18.706f, --16.929f,-16.707f,-11.680f, -8.583f, -7.543f, -6.179f, -6.014f, -4.664f, -1.685f, 0.123f, - 0.349f, -0.458f, -0.786f, 0.755f, -0.018f, -0.103f, 0.495f, 0.475f, -0.011f, -0.275f, - -1.118f, 0.164f, 0.781f, 1.742f, 1.694f, 1.527f, 3.769f, 4.618f, 6.269f, 8.354f, - 11.096f, 14.637f, 17.242f, 15.647f, 16.220f, 17.254f, 17.926f, 17.288f, 15.620f, 14.517f, - 13.606f -},{ --29.534f,-28.346f,-24.147f,-19.589f,-14.670f,-10.062f, -6.382f, -3.611f, 0.416f, 5.238f, - 9.080f, 10.140f, 10.450f, 10.922f, 12.405f, 14.589f, 16.934f, 18.977f, 20.675f, 23.406f, - 26.017f, 29.509f, 34.427f, 35.391f, 33.664f, 30.224f, 29.057f, 30.060f, 31.096f, 31.429f, - 32.339f, 33.620f, 34.951f, 36.182f, 37.454f, 38.904f, 40.320f, 41.065f, 41.574f, 41.434f, - 42.052f, 42.429f, 42.589f, 42.347f, 42.205f, 41.210f, 39.372f, 37.878f, 36.383f, 35.127f, - 33.408f, 31.428f, 30.619f, 29.582f, 28.854f, 28.630f, 27.080f, 25.384f, 21.871f, 18.062f, - 13.975f, 10.171f, 7.609f, 5.193f, 2.689f, 1.101f, -0.073f, -2.665f, -4.023f, -2.046f, --11.689f,-14.986f,-16.086f,-17.500f,-19.942f,-22.199f,-25.298f,-27.535f,-30.827f,-33.121f, --34.890f,-36.762f,-38.854f,-41.645f,-43.421f,-41.306f,-43.800f,-49.437f,-51.123f,-52.706f, --52.893f,-53.800f,-55.300f,-55.791f,-55.091f,-54.836f,-53.640f,-53.164f,-52.022f,-50.825f, --50.226f,-47.961f,-44.660f,-42.392f,-38.751f,-36.528f,-36.154f,-35.650f,-34.795f,-36.035f, --35.424f,-35.264f,-35.050f,-32.687f,-29.779f,-28.215f,-31.034f,-30.069f,-20.790f, -7.978f, - -5.862f, -6.561f, -6.482f, -7.875f, -9.706f,-10.778f,-10.088f,-10.482f,-15.688f,-19.237f, --17.660f,-17.307f,-19.980f,-20.314f,-20.210f,-22.106f,-22.027f,-21.392f,-21.503f,-21.280f, --19.619f,-18.095f,-14.282f,-11.223f,-10.227f, -8.432f, -6.626f, -5.014f, -2.511f, -1.198f, - -1.093f, -2.151f, -1.360f, -0.318f, -0.531f, -0.445f, -0.568f, -0.434f, -0.635f, -1.208f, - -1.694f, -0.520f, -0.846f, 0.936f, 1.734f, 1.815f, 3.122f, 4.187f, 5.876f, 8.126f, - 10.954f, 14.304f, 16.978f, 15.567f, 15.977f, 17.033f, 17.798f, 17.259f, 15.561f, 14.494f, - 13.606f -},{ --29.534f,-28.357f,-24.233f,-19.669f,-14.705f,-10.104f, -6.328f, -3.384f, 0.786f, 5.595f, - 9.363f, 10.102f, 9.965f, 10.356f, 11.788f, 14.058f, 16.827f, 19.045f, 20.267f, 22.859f, - 25.924f, 29.927f, 34.218f, 33.043f, 32.331f, 29.971f, 29.489f, 30.342f, 31.125f, 31.464f, - 32.392f, 33.614f, 34.549f, 35.661f, 37.236f, 38.283f, 39.357f, 40.715f, 40.726f, 40.863f, - 40.969f, 41.379f, 41.658f, 41.436f, 41.158f, 40.152f, 38.504f, 36.882f, 35.365f, 33.586f, - 31.993f, 29.976f, 28.608f, 27.648f, 26.848f, 26.222f, 24.923f, 23.574f, 20.673f, 17.748f, - 13.730f, 9.636f, 7.055f, 4.907f, 2.623f, 0.881f, -0.730f, -2.825f, -5.985f, -9.648f, --12.423f,-12.322f,-16.888f,-18.765f,-20.703f,-22.978f,-25.657f,-28.969f,-31.848f,-34.082f, --36.145f,-38.258f,-40.744f,-43.079f,-44.356f,-44.408f,-48.907f,-51.196f,-53.113f,-54.413f, --55.396f,-55.727f,-56.472f,-57.140f,-57.047f,-56.287f,-55.374f,-54.019f,-52.874f,-51.236f, --50.220f,-49.178f,-46.402f,-43.892f,-41.444f,-40.119f,-39.512f,-39.140f,-35.560f,-34.719f, --33.307f,-34.146f,-33.136f,-29.953f,-26.614f,-26.930f,-26.165f,-27.843f,-19.159f, -7.234f, - -7.028f, -8.552f,-10.044f,-10.346f,-11.080f,-11.933f,-12.170f,-11.459f,-14.951f,-21.494f, --21.009f,-21.345f,-23.163f,-22.711f,-22.967f,-23.817f,-24.293f,-22.137f,-21.441f,-21.508f, --20.910f,-18.376f,-14.039f,-11.642f,-10.766f, -9.680f, -6.728f, -5.060f, -3.363f, -2.428f, - -2.479f, -3.091f, -2.284f, -1.662f, -1.967f, -1.598f, -1.759f, -1.241f, -1.283f, -1.980f, - -1.776f, -1.109f, -2.057f, -0.431f, 1.168f, 2.528f, 2.520f, 3.673f, 5.438f, 7.812f, - 10.809f, 13.996f, 16.692f, 15.450f, 15.734f, 16.813f, 17.685f, 17.243f, 15.503f, 14.470f, - 13.606f -},{ --29.534f,-28.368f,-24.314f,-19.765f,-14.758f,-10.158f, -6.357f, -3.243f, 1.080f, 5.623f, - 8.962f, 9.739f, 9.350f, 9.786f, 11.284f, 13.779f, 16.879f, 18.698f, 20.175f, 22.439f, - 25.559f, 29.375f, 33.521f, 32.170f, 31.037f, 29.088f, 29.691f, 30.510f, 30.996f, 31.641f, - 32.534f, 33.548f, 34.562f, 35.581f, 36.855f, 37.945f, 38.272f, 39.433f, 39.821f, 40.117f, - 40.293f, 40.542f, 40.670f, 40.340f, 39.834f, 38.726f, 37.160f, 36.262f, 34.677f, 32.493f, - 30.624f, 28.909f, 27.070f, 25.731f, 25.180f, 24.739f, 23.749f, 22.123f, 20.956f, 18.831f, - 13.975f, 9.863f, 6.870f, 4.074f, 2.300f, 0.383f, -1.633f, -3.804f, -5.856f, -9.499f, - -6.875f, -9.636f,-16.768f,-19.287f,-21.890f,-24.336f,-26.898f,-30.166f,-33.455f,-35.653f, --38.286f,-40.137f,-42.407f,-43.757f,-45.144f,-48.705f,-50.864f,-53.103f,-55.086f,-56.289f, --57.721f,-58.203f,-58.428f,-59.212f,-58.618f,-57.261f,-56.624f,-55.736f,-54.007f,-52.578f, --50.753f,-51.612f,-50.635f,-47.171f,-45.364f,-44.670f,-43.759f,-42.497f,-39.878f,-36.685f, --35.484f,-32.945f,-31.639f,-27.549f,-29.918f,-28.699f,-22.012f,-19.779f,-17.860f,-11.159f, --13.407f,-14.314f,-12.075f,-11.640f,-12.358f,-14.442f,-13.229f,-13.530f,-19.156f,-23.967f, --24.103f,-24.671f,-25.279f,-25.224f,-25.445f,-25.982f,-25.865f,-22.907f,-20.388f,-19.875f, --18.282f,-16.428f,-12.503f,-11.325f, -9.983f, -9.461f, -6.984f, -5.842f, -4.196f, -2.954f, - -3.055f, -3.795f, -3.499f, -2.347f, -2.919f, -2.903f, -2.640f, -2.023f, -2.005f, -2.517f, - -1.638f, -1.973f, -2.487f, -1.663f, 0.121f, 2.805f, 2.081f, 3.133f, 4.925f, 7.368f, - 10.517f, 13.737f, 16.448f, 15.327f, 15.486f, 16.596f, 17.585f, 17.237f, 15.447f, 14.446f, - 13.606f -},{ --29.534f,-28.378f,-24.390f,-19.877f,-14.832f,-10.215f, -6.460f, -3.214f, 1.228f, 5.417f, - 8.199f, 9.160f, 8.904f, 9.380f, 10.936f, 13.516f, 17.014f, 18.875f, 20.090f, 22.676f, - 25.267f, 28.274f, 32.206f, 31.292f, 29.722f, 28.603f, 29.592f, 30.434f, 30.834f, 31.897f, - 32.681f, 33.604f, 34.403f, 35.464f, 36.301f, 37.259f, 37.901f, 37.831f, 38.742f, 39.240f, - 39.256f, 39.710f, 39.660f, 39.227f, 38.455f, 37.141f, 35.724f, 34.894f, 33.442f, 31.418f, - 29.638f, 27.773f, 26.381f, 25.080f, 23.765f, 23.152f, 22.005f, 21.415f, 20.761f, 18.049f, - 15.358f, 10.737f, 6.819f, 3.683f, 2.048f, 0.428f, -1.689f, -3.746f, -5.343f, -8.218f, --12.313f,-12.753f,-16.312f,-16.871f,-20.462f,-27.158f,-29.030f,-31.675f,-34.769f,-37.336f, --39.475f,-41.084f,-42.577f,-45.459f,-48.685f,-51.286f,-53.542f,-55.358f,-57.113f,-58.733f, --60.083f,-60.824f,-61.198f,-61.068f,-60.573f,-59.552f,-58.489f,-56.977f,-55.491f,-54.697f, --54.244f,-54.230f,-53.604f,-52.000f,-50.578f,-50.386f,-47.022f,-44.266f,-43.653f,-42.018f, --38.660f,-35.051f,-31.600f,-29.770f,-35.644f,-30.183f,-23.677f,-21.905f,-19.725f,-16.904f, --15.810f,-13.880f,-12.219f,-12.404f,-13.500f,-16.341f,-15.265f,-16.742f,-25.725f,-26.711f, --26.270f,-26.684f,-26.956f,-26.728f,-27.341f,-27.790f,-27.184f,-25.346f,-21.737f,-18.612f, --17.158f,-15.505f,-13.454f,-11.799f, -9.605f, -8.542f, -7.663f, -6.407f, -4.808f, -3.040f, - -2.634f, -2.942f, -2.669f, -1.889f, -1.580f, -2.044f, -3.545f, -2.800f, -2.544f, -3.129f, - -1.957f, -3.023f, -2.683f, -2.384f, -0.988f, 2.082f, 1.877f, 2.635f, 4.358f, 6.871f, - 10.033f, 13.505f, 16.245f, 15.217f, 15.231f, 16.380f, 17.495f, 17.233f, 15.393f, 14.422f, - 13.606f -},{ --29.534f,-28.388f,-24.461f,-20.006f,-14.927f,-10.268f, -6.604f, -3.281f, 1.204f, 5.141f, - 7.517f, 8.497f, 8.709f, 9.363f, 10.726f, 12.879f, 17.082f, 20.240f, 19.888f, 22.634f, - 25.739f, 27.667f, 31.135f, 30.397f, 28.360f, 27.665f, 29.073f, 30.184f, 30.727f, 31.864f, - 32.551f, 33.334f, 34.060f, 35.101f, 35.666f, 36.717f, 37.710f, 37.306f, 37.848f, 38.423f, - 38.223f, 38.624f, 38.457f, 37.664f, 36.792f, 35.605f, 34.170f, 33.350f, 32.111f, 30.185f, - 28.655f, 27.042f, 25.527f, 24.574f, 23.569f, 22.269f, 20.913f, 19.335f, 18.544f, 17.752f, - 14.922f, 11.454f, 7.222f, 3.862f, 1.885f, 0.493f, -1.626f, -3.977f, -5.459f, -7.445f, --10.458f,-13.063f,-16.494f,-17.437f,-19.341f,-23.788f,-29.118f,-34.081f,-36.541f,-38.192f, --38.094f,-40.308f,-44.458f,-48.641f,-51.340f,-53.947f,-55.843f,-57.878f,-60.110f,-61.738f, --62.749f,-63.573f,-63.488f,-63.183f,-62.669f,-61.658f,-60.221f,-59.064f,-58.346f,-58.230f, --58.224f,-58.008f,-56.849f,-56.743f,-54.346f,-53.580f,-52.462f,-49.706f,-47.753f,-43.200f, --42.720f,-40.368f,-36.154f,-37.645f,-37.495f,-31.810f,-25.641f,-23.630f,-20.464f,-17.279f, --15.055f,-14.771f,-13.916f,-14.135f,-17.196f,-16.827f,-18.251f,-23.099f,-28.906f,-29.351f, --28.329f,-28.207f,-27.746f,-27.690f,-28.908f,-28.946f,-28.767f,-26.605f,-24.239f,-21.778f, --19.360f,-18.272f,-16.251f,-14.538f,-11.909f, -9.512f, -7.724f, -7.041f, -4.864f, -4.763f, - -3.866f, -3.351f, -3.062f, -3.265f, -1.684f, -1.065f, -4.951f, -3.634f, -2.992f, -4.036f, - -2.966f, -3.868f, -3.199f, -2.859f, -1.915f, 0.688f, 1.921f, 2.198f, 3.830f, 6.441f, - 9.427f, 13.232f, 16.004f, 15.105f, 14.970f, 16.164f, 17.414f, 17.226f, 15.339f, 14.396f, - 13.606f -},{ --29.534f,-28.397f,-24.527f,-20.149f,-15.044f,-10.313f, -6.738f, -3.392f, 1.042f, 4.906f, - 7.164f, 7.858f, 8.595f, 9.763f, 10.702f, 12.084f, 17.048f, 21.488f, 19.829f, 21.654f, - 25.829f, 27.243f, 30.159f, 29.585f, 27.127f, 26.722f, 28.517f, 29.763f, 30.338f, 31.390f, - 32.176f, 33.106f, 33.955f, 34.638f, 35.498f, 36.202f, 37.090f, 37.289f, 37.071f, 37.993f, - 37.471f, 37.818f, 37.567f, 36.528f, 35.297f, 34.147f, 32.982f, 32.277f, 31.004f, 29.362f, - 27.846f, 26.263f, 25.082f, 24.224f, 23.561f, 22.093f, 20.347f, 18.554f, 16.419f, 15.158f, - 13.669f, 10.489f, 8.095f, 4.249f, 1.732f, 0.482f, -1.484f, -3.763f, -6.006f, -7.599f, --10.952f,-14.080f,-16.490f,-20.040f,-21.256f,-23.752f,-26.918f,-31.284f,-34.424f,-36.180f, --38.977f,-44.286f,-47.409f,-51.039f,-53.956f,-56.273f,-58.690f,-61.270f,-63.215f,-64.281f, --65.524f,-65.831f,-65.849f,-65.580f,-65.101f,-63.939f,-62.454f,-62.387f,-62.227f,-61.926f, --62.220f,-61.545f,-60.390f,-58.735f,-57.545f,-56.723f,-55.936f,-54.978f,-53.802f,-49.995f, --47.845f,-43.019f,-41.055f,-39.531f,-39.131f,-32.266f,-27.786f,-24.611f,-20.992f,-17.226f, --18.535f,-19.094f,-17.674f,-19.341f,-20.375f,-21.349f,-22.887f,-28.105f,-30.796f,-31.153f, --30.356f,-30.199f,-29.330f,-29.399f,-30.163f,-30.078f,-30.064f,-28.595f,-26.904f,-24.293f, --22.293f,-20.463f,-17.969f,-16.586f,-14.147f,-12.248f,-10.240f, -9.754f, -8.383f, -8.503f, - -8.109f, -6.376f, -6.149f, -5.758f, -4.098f, -1.867f, -6.142f, -5.067f, -3.904f, -4.794f, - -4.077f, -4.724f, -4.003f, -3.289f, -2.586f, -0.638f, 2.026f, 1.800f, 3.444f, 6.107f, - 8.821f, 12.836f, 15.611f, 14.950f, 14.710f, 15.945f, 17.338f, 17.209f, 15.286f, 14.371f, - 13.606f -},{ --29.534f,-28.406f,-24.589f,-20.304f,-15.180f,-10.348f, -6.806f, -3.474f, 0.823f, 4.711f, - 7.034f, 7.301f, 8.316f, 10.174f, 10.902f, 11.734f, 17.049f, 21.297f, 19.888f, 21.168f, - 25.164f, 27.067f, 29.707f, 28.838f, 26.255f, 26.579f, 28.334f, 29.442f, 30.160f, 31.015f, - 31.533f, 32.606f, 33.731f, 34.518f, 35.142f, 35.702f, 36.194f, 36.311f, 36.760f, 37.437f, - 37.019f, 38.157f, 36.910f, 35.507f, 34.452f, 33.032f, 32.414f, 31.511f, 29.947f, 28.514f, - 27.316f, 25.890f, 24.864f, 24.321f, 23.603f, 22.084f, 20.014f, 17.972f, 16.114f, 14.115f, - 12.907f, 10.843f, 8.866f, 5.264f, 1.781f, 0.282f, -1.384f, -3.805f, -6.084f, -8.413f, --11.214f,-14.763f,-17.296f,-20.750f,-24.594f,-27.559f,-30.573f,-34.035f,-36.409f,-37.864f, --41.541f,-46.356f,-49.918f,-53.394f,-56.312f,-58.929f,-61.316f,-63.870f,-65.759f,-67.162f, --67.895f,-68.247f,-68.303f,-68.202f,-67.168f,-66.439f,-66.255f,-66.445f,-66.282f,-66.464f, --65.982f,-64.518f,-63.030f,-61.532f,-59.694f,-58.007f,-56.370f,-54.604f,-52.691f,-50.044f, --49.320f,-46.449f,-41.935f,-43.417f,-41.852f,-33.813f,-29.902f,-27.200f,-24.686f,-22.419f, --21.522f,-21.080f,-20.511f,-20.548f,-21.111f,-22.110f,-26.659f,-30.517f,-32.656f,-33.055f, --32.541f,-31.865f,-31.466f,-31.513f,-32.212f,-31.597f,-31.004f,-30.329f,-28.782f,-26.508f, --24.280f,-22.740f,-20.747f,-18.637f,-16.775f,-14.148f,-13.267f,-12.385f,-11.377f,-10.372f, --10.246f, -8.773f, -8.677f, -8.116f, -6.056f, -3.810f, -6.034f, -6.610f, -4.993f, -4.995f, - -5.141f, -5.818f, -4.744f, -3.567f, -3.024f, -1.555f, 1.875f, 1.454f, 3.195f, 5.758f, - 8.295f, 12.274f, 14.989f, 14.705f, 14.455f, 15.724f, 17.266f, 17.177f, 15.233f, 14.344f, - 13.606f -},{ --29.534f,-28.415f,-24.646f,-20.467f,-15.332f,-10.374f, -6.767f, -3.458f, 0.637f, 4.483f, - 6.802f, 6.819f, 7.777f, 10.010f, 11.174f, 12.005f, 17.187f, 20.490f, 19.930f, 22.512f, - 25.997f, 27.915f, 29.914f, 28.369f, 25.489f, 26.868f, 28.060f, 29.221f, 29.721f, 30.522f, - 31.005f, 32.145f, 33.514f, 34.612f, 34.889f, 35.057f, 35.660f, 35.416f, 36.435f, 36.892f, - 36.254f, 37.578f, 36.299f, 35.228f, 33.691f, 32.229f, 31.701f, 30.699f, 29.611f, 28.269f, - 27.118f, 25.640f, 24.685f, 24.212f, 23.667f, 21.994f, 20.030f, 17.881f, 15.414f, 13.261f, - 11.565f, 10.856f, 8.164f, 5.879f, 2.581f, 0.025f, -1.872f, -3.851f, -6.363f, -8.647f, --10.837f,-15.527f,-18.318f,-22.023f,-25.701f,-29.020f,-32.281f,-35.799f,-39.375f,-42.434f, --45.841f,-49.164f,-52.693f,-55.965f,-58.881f,-61.446f,-64.132f,-66.411f,-68.505f,-69.944f, --70.659f,-70.696f,-70.859f,-70.592f,-69.779f,-69.969f,-70.300f,-70.376f,-70.401f,-70.220f, --69.546f,-67.935f,-66.622f,-65.067f,-62.965f,-60.875f,-58.671f,-56.469f,-53.931f,-51.555f, --49.920f,-47.575f,-45.088f,-46.487f,-44.948f,-35.657f,-30.625f,-29.462f,-29.928f,-25.073f, --22.579f,-22.276f,-22.447f,-20.944f,-19.763f,-22.689f,-28.253f,-32.541f,-34.579f,-33.985f, --33.778f,-33.389f,-33.087f,-32.424f,-33.639f,-33.351f,-33.041f,-32.063f,-31.160f,-29.059f, --26.105f,-24.452f,-22.988f,-20.403f,-18.135f,-16.641f,-15.605f,-14.352f,-13.345f,-12.226f, --10.953f,-10.205f,-10.157f, -9.843f, -7.841f, -5.945f, -4.781f, -6.994f, -5.900f, -5.227f, - -6.299f, -6.664f, -5.248f, -3.772f, -3.340f, -2.202f, 1.333f, 1.240f, 2.947f, 5.247f, - 7.842f, 11.578f, 14.149f, 14.342f, 14.212f, 15.502f, 17.195f, 17.125f, 15.180f, 14.317f, - 13.606f -},{ --29.534f,-28.424f,-24.699f,-20.634f,-15.498f,-10.396f, -6.610f, -3.311f, 0.552f, 4.176f, - 6.226f, 6.358f, 7.123f, 9.121f, 11.197f, 12.566f, 17.387f, 20.279f, 20.222f, 24.531f, - 28.245f, 28.975f, 29.130f, 27.201f, 25.122f, 27.345f, 27.448f, 28.618f, 29.187f, 30.259f, - 30.769f, 31.394f, 33.034f, 34.565f, 35.009f, 34.817f, 34.713f, 34.940f, 36.067f, 36.025f, - 39.017f, 36.902f, 35.509f, 34.061f, 32.519f, 31.766f, 31.117f, 30.275f, 29.225f, 27.792f, - 26.726f, 25.680f, 24.600f, 24.153f, 23.232f, 21.721f, 19.515f, 17.275f, 15.056f, 13.052f, - 10.706f, 9.717f, 8.150f, 5.713f, 2.206f, -0.229f, -2.259f, -4.206f, -6.762f, -9.062f, --11.834f,-15.071f,-19.282f,-23.061f,-26.561f,-30.032f,-33.770f,-37.361f,-41.058f,-44.884f, --48.761f,-51.964f,-55.208f,-58.472f,-61.426f,-64.283f,-66.604f,-68.682f,-70.516f,-72.331f, --73.069f,-73.337f,-73.749f,-73.012f,-73.030f,-73.888f,-74.292f,-74.362f,-74.445f,-73.666f, --72.476f,-71.236f,-69.774f,-68.254f,-66.332f,-64.095f,-61.704f,-59.246f,-55.997f,-54.073f, --51.848f,-49.835f,-44.330f,-45.061f,-46.617f,-38.392f,-31.420f,-31.147f,-31.677f,-26.919f, --23.818f,-23.435f,-23.572f,-20.618f,-19.935f,-22.433f,-28.733f,-34.865f,-36.438f,-35.524f, --35.224f,-34.145f,-34.343f,-34.437f,-35.516f,-35.144f,-34.793f,-33.883f,-32.600f,-30.523f, --28.266f,-26.237f,-24.566f,-22.538f,-20.014f,-18.037f,-17.565f,-16.486f,-14.860f,-14.043f, --12.961f,-11.016f,-10.621f,-10.584f, -9.891f, -7.771f, -4.423f, -5.956f, -6.602f, -5.890f, - -6.987f, -6.924f, -5.580f, -4.152f, -3.609f, -2.761f, 0.595f, 1.220f, 2.559f, 4.554f, - 7.401f, 10.840f, 13.202f, 13.870f, 13.986f, 15.284f, 17.122f, 17.049f, 15.126f, 14.289f, - 13.606f -},{ --29.534f,-28.432f,-24.750f,-20.802f,-15.672f,-10.421f, -6.361f, -3.045f, 0.590f, 3.835f, - 5.363f, 5.876f, 6.591f, 7.996f, 10.727f, 13.037f, 17.572f, 20.322f, 20.844f, 25.311f, - 28.418f, 28.762f, 27.787f, 25.926f, 25.098f, 26.894f, 27.034f, 27.933f, 28.472f, 30.071f, - 30.787f, 31.622f, 31.695f, 35.147f, 35.900f, 34.803f, 34.485f, 34.963f, 35.722f, 36.296f, - 40.417f, 37.221f, 35.875f, 34.420f, 32.599f, 31.719f, 30.575f, 29.680f, 28.472f, 27.265f, - 26.086f, 25.429f, 24.267f, 23.430f, 22.513f, 20.862f, 18.663f, 16.527f, 14.397f, 12.566f, - 10.397f, 8.795f, 7.018f, 5.676f, 1.571f, -0.369f, -2.692f, -5.103f, -7.340f, -9.798f, --12.470f,-15.599f,-19.575f,-23.803f,-27.052f,-30.944f,-34.713f,-38.454f,-42.413f,-46.935f, --50.510f,-54.322f,-57.743f,-60.974f,-63.940f,-66.487f,-68.608f,-71.032f,-72.385f,-74.307f, --75.251f,-76.030f,-76.114f,-75.838f,-76.534f,-77.502f,-77.914f,-78.331f,-78.395f,-77.371f, --75.927f,-74.607f,-72.989f,-71.152f,-69.349f,-67.039f,-64.629f,-61.718f,-58.480f,-56.451f, --54.730f,-54.943f,-48.811f,-47.295f,-48.091f,-41.995f,-34.822f,-31.304f,-32.248f,-29.554f, --26.990f,-24.546f,-24.324f,-22.565f,-20.648f,-22.129f,-29.555f,-36.736f,-37.720f,-37.030f, --36.392f,-35.673f,-35.459f,-36.990f,-37.186f,-36.529f,-36.224f,-34.726f,-32.839f,-30.976f, --29.175f,-26.983f,-24.927f,-23.666f,-22.007f,-19.885f,-18.647f,-17.811f,-16.484f,-15.438f, --14.554f,-13.161f,-11.395f,-11.199f,-11.341f, -9.810f, -6.297f, -4.716f, -6.502f, -6.551f, - -7.150f, -7.006f, -5.843f, -4.618f, -3.797f, -3.273f, -0.093f, 1.316f, 2.020f, 3.832f, - 6.917f, 10.160f, 12.306f, 13.334f, 13.778f, 15.076f, 17.044f, 16.947f, 15.071f, 14.261f, - 13.606f -},{ --29.534f,-28.441f,-24.798f,-20.966f,-15.851f,-10.455f, -6.076f, -2.713f, 0.734f, 3.573f, - 4.537f, 5.396f, 6.270f, 7.228f, 9.787f, 13.078f, 17.679f, 20.175f, 21.135f, 24.598f, - 26.014f, 27.239f, 27.410f, 25.550f, 24.751f, 25.858f, 26.748f, 27.459f, 28.068f, 29.988f, - 30.894f, 31.873f, 31.460f, 35.205f, 35.759f, 34.504f, 34.692f, 34.744f, 35.478f, 36.892f, - 38.728f, 37.607f, 38.627f, 36.351f, 33.113f, 31.433f, 30.188f, 29.515f, 28.296f, 27.057f, - 25.743f, 24.954f, 23.828f, 22.531f, 21.528f, 19.805f, 17.688f, 15.577f, 13.779f, 11.869f, - 10.019f, 7.918f, 6.725f, 4.699f, 1.150f, -1.022f, -3.406f, -6.013f, -8.099f,-10.716f, --13.281f,-16.593f,-20.533f,-24.431f,-28.243f,-31.671f,-35.715f,-39.403f,-43.757f,-47.531f, --52.376f,-55.945f,-59.558f,-62.831f,-65.977f,-68.638f,-70.540f,-72.950f,-74.757f,-76.592f, --77.714f,-78.475f,-78.510f,-78.772f,-80.003f,-80.808f,-81.514f,-81.949f,-81.463f,-80.411f, --79.219f,-77.756f,-76.135f,-74.228f,-71.915f,-69.878f,-67.349f,-64.314f,-62.168f,-58.375f, --55.696f,-55.463f,-52.291f,-47.217f,-45.091f,-43.167f,-40.145f,-35.150f,-31.644f,-29.549f, --27.914f,-25.586f,-24.547f,-23.979f,-22.493f,-22.262f,-30.333f,-38.386f,-37.727f,-37.701f, --36.927f,-37.067f,-38.570f,-39.174f,-38.430f,-37.686f,-37.407f,-35.306f,-32.781f,-31.142f, --29.287f,-27.052f,-24.892f,-23.915f,-23.379f,-21.625f,-20.439f,-19.234f,-17.962f,-16.568f, --15.924f,-15.035f,-13.040f,-11.661f,-11.872f,-10.880f, -8.476f, -5.011f, -5.810f, -7.092f, - -7.573f, -7.262f, -6.165f, -4.914f, -3.925f, -3.738f, -0.728f, 1.293f, 1.435f, 3.283f, - 6.383f, 9.593f, 11.601f, 12.798f, 13.583f, 14.886f, 16.958f, 16.819f, 15.014f, 14.232f, - 13.606f -},{ --29.534f,-28.449f,-24.844f,-21.123f,-16.032f,-10.507f, -5.831f, -2.394f, 0.942f, 3.487f, - 4.084f, 5.006f, 6.006f, 6.867f, 8.671f, 12.328f, 17.287f, 20.103f, 20.365f, 23.005f, - 23.767f, 25.155f, 26.605f, 24.384f, 23.879f, 25.468f, 26.443f, 26.874f, 27.951f, 29.668f, - 31.114f, 32.050f, 31.544f, 34.708f, 34.776f, 34.459f, 35.050f, 34.734f, 35.433f, 36.552f, - 36.915f, 39.246f, 39.492f, 37.503f, 33.973f, 31.094f, 29.887f, 29.118f, 28.072f, 26.829f, - 25.641f, 24.544f, 23.177f, 21.717f, 20.344f, 18.570f, 16.586f, 14.734f, 12.914f, 11.088f, - 9.234f, 7.283f, 5.839f, 2.612f, 1.254f, -1.856f, -4.278f, -6.806f, -9.102f,-11.652f, --14.697f,-18.243f,-21.950f,-25.875f,-29.485f,-33.110f,-37.382f,-41.621f,-45.736f,-49.732f, --53.601f,-57.902f,-61.203f,-64.643f,-67.615f,-70.731f,-73.041f,-74.888f,-76.814f,-78.248f, --79.801f,-80.621f,-81.418f,-82.346f,-83.452f,-84.405f,-85.232f,-85.344f,-84.643f,-83.778f, --82.622f,-80.844f,-79.290f,-77.341f,-74.804f,-72.649f,-70.499f,-68.789f,-65.639f,-60.000f, --57.496f,-56.639f,-53.072f,-47.641f,-45.599f,-43.307f,-42.045f,-40.412f,-37.913f,-34.236f, --28.073f,-24.571f,-25.167f,-22.814f,-22.108f,-22.593f,-31.195f,-41.053f,-39.003f,-35.789f, --37.644f,-39.786f,-40.653f,-40.963f,-38.778f,-38.404f,-38.345f,-36.333f,-33.878f,-32.077f, --30.437f,-28.305f,-26.004f,-24.672f,-24.347f,-22.553f,-21.656f,-20.969f,-19.876f,-18.011f, --17.298f,-16.775f,-15.481f,-13.026f,-12.322f,-11.423f, -9.751f, -6.683f, -6.006f, -7.696f, - -8.217f, -7.611f, -6.609f, -5.152f, -4.125f, -4.100f, -1.443f, 0.914f, 0.905f, 2.968f, - 5.827f, 9.124f, 11.148f, 12.321f, 13.394f, 14.719f, 16.861f, 16.666f, 14.956f, 14.203f, - 13.606f -},{ --29.534f,-28.457f,-24.890f,-21.271f,-16.214f,-10.584f, -5.697f, -2.163f, 1.177f, 3.589f, - 4.101f, 4.784f, 5.574f, 6.454f, 7.747f, 10.875f, 15.811f, 19.378f, 18.463f, 20.594f, - 21.996f, 23.377f, 25.172f, 23.327f, 23.598f, 25.441f, 26.392f, 26.470f, 27.743f, 29.222f, - 30.761f, 31.904f, 30.639f, 34.497f, 34.252f, 34.616f, 35.102f, 34.779f, 34.815f, 36.258f, - 38.766f, 41.023f, 39.952f, 37.447f, 33.991f, 31.032f, 29.842f, 28.729f, 27.702f, 26.444f, - 25.343f, 23.759f, 22.296f, 20.675f, 18.963f, 17.353f, 15.501f, 13.747f, 12.028f, 10.196f, - 8.305f, 6.418f, 4.155f, 2.626f, 0.280f, -2.981f, -5.259f, -7.693f,-10.322f,-13.052f, --16.483f,-20.005f,-23.704f,-27.691f,-31.793f,-35.661f,-39.920f,-43.991f,-48.372f,-52.124f, --56.221f,-60.128f,-62.785f,-66.058f,-69.343f,-72.066f,-74.815f,-77.136f,-79.058f,-81.066f, --82.858f,-84.430f,-85.488f,-86.080f,-86.821f,-87.594f,-88.455f,-88.703f,-87.775f,-86.666f, --85.465f,-84.018f,-82.157f,-80.134f,-77.860f,-75.999f,-74.046f,-70.885f,-66.248f,-63.010f, --61.190f,-58.235f,-53.737f,-49.893f,-46.474f,-44.504f,-43.799f,-44.913f,-43.812f,-42.389f, --33.607f,-26.396f,-26.242f,-25.638f,-23.493f,-25.435f,-31.830f,-43.533f,-43.407f,-34.652f, --39.394f,-42.159f,-42.861f,-42.406f,-37.526f,-39.489f,-38.825f,-37.444f,-34.799f,-32.516f, --31.133f,-28.706f,-27.101f,-26.043f,-25.932f,-23.650f,-22.806f,-22.212f,-21.363f,-19.533f, --18.225f,-18.349f,-16.786f,-14.412f,-13.143f,-12.695f,-11.018f, -8.499f, -7.484f, -8.387f, - -8.623f, -7.986f, -6.958f, -5.601f, -4.434f, -4.270f, -2.226f, 0.129f, 0.432f, 2.765f, - 5.276f, 8.696f, 10.917f, 11.934f, 13.203f, 14.577f, 16.751f, 16.491f, 14.895f, 14.172f, - 13.606f -},{ --29.534f,-28.465f,-24.936f,-21.409f,-16.395f,-10.692f, -5.726f, -2.070f, 1.415f, 3.802f, - 4.402f, 4.726f, 4.947f, 5.667f, 7.174f, 9.537f, 13.555f, 16.814f, 16.034f, 17.634f, - 19.505f, 22.010f, 24.343f, 24.053f, 23.653f, 25.001f, 25.890f, 26.063f, 27.460f, 28.546f, - 30.025f, 31.076f, 30.885f, 34.665f, 33.758f, 34.590f, 34.790f, 34.472f, 34.481f, 34.726f, - 40.635f, 40.841f, 39.764f, 36.487f, 33.090f, 31.044f, 29.672f, 28.211f, 27.095f, 25.819f, - 24.268f, 22.774f, 21.208f, 19.429f, 17.784f, 16.190f, 14.508f, 12.790f, 11.021f, 9.108f, - 7.224f, 5.285f, 3.327f, 1.202f, -1.186f, -3.664f, -6.092f, -8.833f,-11.673f,-14.796f, --18.361f,-22.083f,-26.224f,-30.315f,-33.873f,-38.139f,-42.391f,-46.242f,-50.715f,-54.883f, --58.556f,-62.578f,-66.486f,-69.138f,-71.826f,-74.809f,-77.452f,-80.037f,-82.503f,-84.633f, --86.464f,-87.922f,-88.925f,-89.755f,-90.374f,-90.636f,-91.200f,-91.251f,-90.622f,-89.697f, --88.392f,-86.679f,-84.945f,-82.865f,-80.715f,-79.147f,-75.460f,-72.083f,-68.966f,-67.359f, --62.673f,-57.019f,-54.026f,-50.987f,-47.965f,-46.268f,-45.315f,-43.454f,-42.497f,-38.997f, --33.051f,-30.810f,-31.090f,-28.802f,-27.769f,-28.757f,-35.111f,-44.904f,-44.447f,-35.885f, --41.347f,-44.226f,-42.807f,-42.090f,-38.966f,-40.640f,-41.152f,-38.778f,-36.149f,-33.993f, --32.380f,-29.865f,-28.287f,-27.317f,-26.649f,-24.799f,-24.007f,-23.497f,-22.432f,-20.797f, --19.766f,-19.357f,-17.749f,-15.634f,-14.125f,-13.421f,-12.368f,-10.276f, -9.148f, -9.235f, - -8.946f, -8.366f, -7.054f, -6.139f, -4.736f, -4.328f, -2.912f, -0.877f, -0.034f, 2.496f, - 4.746f, 8.264f, 10.823f, 11.635f, 13.003f, 14.456f, 16.625f, 16.299f, 14.833f, 14.142f, - 13.606f -},{ --29.534f,-28.473f,-24.983f,-21.536f,-16.576f,-10.834f, -5.935f, -2.138f, 1.647f, 4.039f, - 4.700f, 4.739f, 4.356f, 4.757f, 6.777f, 9.040f, 11.863f, 13.560f, 14.086f, 15.436f, - 17.281f, 20.298f, 22.967f, 24.598f, 22.641f, 23.894f, 25.203f, 25.628f, 27.109f, 28.306f, - 29.355f, 29.980f, 30.377f, 33.934f, 33.472f, 34.721f, 34.691f, 34.373f, 34.520f, 37.729f, - 39.925f, 40.075f, 38.559f, 35.680f, 32.677f, 30.883f, 28.999f, 27.450f, 26.301f, 24.875f, - 23.221f, 21.511f, 20.014f, 18.168f, 16.588f, 15.041f, 13.503f, 11.646f, 9.853f, 8.036f, - 6.075f, 4.102f, 1.972f, 0.004f, -2.068f, -4.669f, -7.565f,-10.581f,-13.717f,-16.964f, --20.596f,-24.515f,-28.970f,-33.042f,-36.947f,-40.756f,-44.822f,-48.869f,-52.695f,-56.778f, --60.861f,-64.217f,-68.849f,-72.612f,-75.750f,-78.454f,-81.139f,-83.794f,-85.890f,-87.840f, --89.475f,-91.154f,-92.300f,-92.512f,-93.199f,-93.885f,-93.826f,-93.588f,-93.254f,-92.292f, --91.153f,-89.554f,-87.879f,-85.671f,-83.279f,-80.708f,-77.830f,-74.583f,-71.990f,-65.318f, --60.900f,-56.819f,-53.999f,-51.755f,-48.264f,-45.884f,-45.309f,-45.257f,-44.794f,-44.844f, --38.805f,-37.340f,-39.525f,-36.855f,-34.988f,-32.439f,-28.764f,-38.518f,-40.601f,-36.376f, --41.082f,-41.211f,-40.121f,-39.620f,-41.208f,-42.372f,-41.463f,-39.414f,-38.290f,-35.462f, --33.374f,-31.199f,-29.108f,-27.833f,-27.310f,-26.277f,-25.238f,-24.844f,-23.780f,-22.254f, --21.313f,-20.278f,-19.060f,-16.973f,-14.992f,-14.057f,-13.434f,-11.727f,-10.591f,-10.126f, - -9.252f, -8.741f, -7.215f, -6.468f, -4.953f, -4.521f, -3.400f, -1.811f, -0.493f, 2.111f, - 4.259f, 7.837f, 10.773f, 11.398f, 12.790f, 14.351f, 16.483f, 16.094f, 14.768f, 14.110f, - 13.606f -},{ --29.534f,-28.482f,-25.032f,-21.653f,-16.757f,-11.014f, -6.307f, -2.357f, 1.860f, 4.271f, - 4.848f, 4.729f, 4.060f, 4.241f, 6.298f, 9.082f, 11.604f, 12.126f, 13.190f, 15.005f, - 16.600f, 18.604f, 20.945f, 24.511f, 21.669f, 22.601f, 24.386f, 25.082f, 26.401f, 27.791f, - 28.686f, 29.534f, 29.902f, 34.281f, 33.428f, 34.716f, 34.780f, 34.880f, 36.712f, 38.602f, - 37.367f, 37.643f, 37.248f, 34.536f, 32.011f, 30.334f, 28.548f, 26.683f, 25.165f, 23.513f, - 21.989f, 20.140f, 18.612f, 16.937f, 15.364f, 14.032f, 12.243f, 10.576f, 8.645f, 6.926f, - 4.869f, 2.970f, 0.890f, -1.160f, -3.549f, -6.458f, -9.446f,-12.647f,-15.912f,-19.309f, --23.174f,-27.167f,-31.127f,-35.284f,-39.509f,-43.409f,-47.458f,-51.339f,-54.955f,-58.338f, --62.613f,-65.920f,-69.460f,-72.743f,-77.224f,-81.347f,-84.177f,-86.605f,-89.003f,-90.757f, --92.225f,-94.021f,-95.032f,-95.469f,-95.854f,-96.013f,-96.194f,-95.538f,-95.302f,-94.383f, --93.025f,-90.716f,-89.004f,-86.694f,-84.267f,-82.164f,-79.894f,-77.417f,-70.406f,-66.701f, --63.904f,-59.089f,-55.971f,-53.305f,-49.365f,-46.248f,-44.602f,-45.221f,-47.560f,-50.233f, --49.334f,-48.384f,-44.747f,-45.377f,-41.624f,-35.427f,-28.397f,-32.662f,-33.433f,-35.348f, --41.576f,-45.270f,-35.959f,-41.338f,-42.449f,-43.149f,-41.864f,-41.348f,-39.856f,-36.505f, --33.878f,-32.063f,-30.187f,-28.770f,-28.492f,-27.369f,-26.546f,-26.358f,-24.957f,-23.659f, --22.815f,-21.285f,-19.989f,-18.181f,-15.897f,-15.061f,-14.389f,-12.898f,-12.200f,-10.768f, - -9.502f, -9.232f, -7.682f, -6.646f, -5.153f, -4.915f, -3.756f, -2.451f, -0.893f, 1.710f, - 3.864f, 7.469f, 10.704f, 11.186f, 12.566f, 14.253f, 16.326f, 15.882f, 14.702f, 14.079f, - 13.606f -},{ --29.534f,-28.491f,-25.084f,-21.762f,-16.943f,-11.234f, -6.795f, -2.701f, 2.026f, 4.534f, - 4.928f, 4.691f, 4.081f, 4.279f, 5.785f, 8.832f, 12.237f, 12.787f, 12.875f, 15.614f, - 16.860f, 17.546f, 19.615f, 24.084f, 21.261f, 21.552f, 23.367f, 24.683f, 25.786f, 26.882f, - 27.693f, 29.010f, 29.777f, 33.774f, 33.431f, 34.097f, 35.283f, 36.818f, 38.256f, 37.949f, - 36.646f, 35.523f, 34.764f, 33.235f, 31.159f, 29.593f, 27.749f, 25.601f, 24.169f, 22.365f, - 20.575f, 18.954f, 17.336f, 15.758f, 14.304f, 12.746f, 11.063f, 9.343f, 7.675f, 5.632f, - 3.785f, 1.655f, -0.307f, -2.365f, -5.120f, -8.062f,-11.358f,-14.431f,-17.892f,-21.577f, --25.322f,-29.302f,-33.414f,-37.874f,-42.311f,-46.454f,-50.472f,-54.356f,-58.173f,-61.689f, --64.980f,-68.528f,-71.883f,-74.282f,-75.888f,-81.293f,-86.235f,-88.816f,-91.174f,-93.646f, --94.834f,-95.748f,-96.847f,-97.549f,-97.639f,-97.416f,-97.153f,-96.805f,-96.303f,-95.497f, --93.524f,-91.519f,-89.614f,-87.515f,-86.018f,-83.718f,-80.491f,-75.545f,-71.170f,-68.752f, --65.377f,-60.783f,-57.688f,-54.922f,-50.827f,-47.997f,-45.578f,-44.019f,-46.960f,-49.338f, --49.078f,-46.857f,-43.488f,-47.382f,-47.769f,-37.133f,-30.462f,-29.737f,-30.305f,-33.004f, --40.162f,-49.216f,-37.686f,-41.383f,-44.147f,-43.542f,-42.586f,-42.375f,-40.696f,-37.682f, --34.528f,-33.383f,-31.389f,-30.328f,-29.727f,-28.826f,-28.256f,-27.857f,-25.765f,-25.117f, --23.718f,-22.641f,-21.209f,-19.272f,-16.896f,-16.102f,-15.571f,-14.186f,-13.357f,-11.174f, - -9.822f, -9.726f, -8.104f, -6.947f, -5.446f, -5.296f, -4.108f, -2.754f, -1.201f, 1.422f, - 3.624f, 7.220f, 10.595f, 10.974f, 12.336f, 14.150f, 16.155f, 15.668f, 14.633f, 14.046f, - 13.606f -},{ --29.534f,-28.500f,-25.139f,-21.866f,-17.134f,-11.492f, -7.338f, -3.137f, 2.098f, 4.860f, - 5.116f, 4.700f, 4.182f, 4.484f, 5.520f, 8.187f, 12.853f, 13.938f, 12.684f, 15.955f, - 17.172f, 16.551f, 18.751f, 22.345f, 20.478f, 20.765f, 22.674f, 24.381f, 25.176f, 26.512f, - 27.264f, 29.285f, 29.941f, 32.355f, 32.876f, 34.087f, 35.008f, 39.559f, 37.833f, 37.650f, - 36.342f, 34.085f, 32.812f, 31.643f, 30.141f, 28.582f, 26.893f, 24.777f, 23.046f, 21.343f, - 19.529f, 17.683f, 16.190f, 14.732f, 13.215f, 11.547f, 10.061f, 8.191f, 6.452f, 4.476f, - 2.556f, 0.374f, -1.564f, -3.956f, -6.934f, -9.925f,-13.000f,-16.837f,-19.852f,-23.260f, --27.280f,-31.321f,-35.746f,-40.114f,-44.742f,-49.252f,-52.754f,-56.756f,-60.956f,-65.094f, --68.439f,-72.126f,-75.880f,-78.078f,-80.454f,-83.587f,-86.799f,-90.089f,-91.856f,-93.275f, --94.642f,-95.694f,-96.608f,-95.940f,-95.742f,-96.493f,-96.603f,-96.854f,-96.914f,-96.137f, --94.693f,-93.106f,-91.923f,-89.494f,-86.512f,-82.569f,-79.735f,-77.433f,-74.969f,-69.341f, --66.217f,-61.645f,-59.575f,-56.367f,-51.727f,-48.591f,-47.551f,-46.081f,-46.767f,-48.075f, --47.274f,-44.757f,-43.307f,-47.395f,-44.306f,-34.622f,-29.691f,-28.750f,-28.089f,-30.255f, --38.559f,-43.840f,-37.469f,-42.109f,-44.219f,-44.265f,-43.603f,-42.797f,-40.858f,-38.577f, --35.251f,-34.543f,-33.224f,-32.085f,-31.372f,-30.415f,-29.900f,-28.871f,-27.091f,-26.625f, --24.769f,-23.595f,-22.263f,-20.015f,-17.919f,-17.129f,-16.582f,-14.973f,-13.598f,-11.525f, --10.018f, -9.888f, -8.173f, -7.309f, -5.874f, -5.537f, -4.523f, -2.844f, -1.436f, 1.273f, - 3.571f, 7.100f, 10.444f, 10.750f, 12.109f, 14.035f, 15.975f, 15.458f, 14.563f, 14.014f, - 13.606f -},{ --29.534f,-28.509f,-25.199f,-21.966f,-17.333f,-11.788f, -7.880f, -3.633f, 2.026f, 5.202f, - 5.474f, 4.820f, 4.142f, 4.383f, 5.523f, 7.790f, 13.180f, 14.918f, 13.058f, 15.918f, - 17.131f, 15.714f, 17.999f, 20.211f, 19.544f, 20.408f, 22.228f, 24.040f, 24.670f, 25.963f, - 27.439f, 30.037f, 29.986f, 31.428f, 32.264f, 34.068f, 34.994f, 39.101f, 38.156f, 36.648f, - 34.971f, 33.315f, 31.818f, 30.650f, 29.335f, 27.766f, 26.019f, 24.283f, 22.067f, 20.293f, - 18.450f, 16.626f, 15.019f, 13.723f, 12.017f, 10.513f, 8.727f, 7.052f, 5.307f, 3.378f, - 1.229f, -0.796f, -3.124f, -5.824f, -8.715f,-11.937f,-15.041f,-18.379f,-22.098f,-25.779f, --29.422f,-33.611f,-38.203f,-42.181f,-46.389f,-50.716f,-54.522f,-58.712f,-62.773f,-67.165f, --71.149f,-74.986f,-78.776f,-82.000f,-85.512f,-88.384f,-90.424f,-91.955f,-92.862f,-94.580f, --96.448f,-97.359f,-98.589f,-99.221f,-99.614f,-99.858f,-100.164f,-99.836f,-99.150f,-98.313f, --96.744f,-95.110f,-92.884f,-88.869f,-86.368f,-83.972f,-80.160f,-78.057f,-74.023f,-70.083f, --65.973f,-62.870f,-59.764f,-56.508f,-52.574f,-48.107f,-47.504f,-47.804f,-46.379f,-47.080f, --45.822f,-43.813f,-44.405f,-45.340f,-37.554f,-31.863f,-31.038f,-29.454f,-27.635f,-29.660f, --34.735f,-37.570f,-35.984f,-43.775f,-44.839f,-45.354f,-44.037f,-43.729f,-42.206f,-39.567f, --36.471f,-35.772f,-34.380f,-33.442f,-32.882f,-31.903f,-30.729f,-29.430f,-28.427f,-27.600f, --25.861f,-23.776f,-22.341f,-20.741f,-19.192f,-17.698f,-17.064f,-15.127f,-13.661f,-11.787f, --10.056f, -9.776f, -8.061f, -7.456f, -6.381f, -5.766f, -4.995f, -2.906f, -1.616f, 1.181f, - 3.661f, 7.061f, 10.246f, 10.519f, 11.890f, 13.905f, 15.790f, 15.258f, 14.491f, 13.980f, - 13.606f -},{ --29.534f,-28.520f,-25.264f,-22.068f,-17.542f,-12.119f, -8.384f, -4.159f, 1.778f, 5.415f, - 5.846f, 5.005f, 3.989f, 3.948f, 5.423f, 7.870f, 13.122f, 15.703f, 14.073f, 15.983f, - 16.555f, 15.575f, 17.143f, 18.766f, 18.768f, 20.261f, 21.979f, 23.597f, 24.293f, 25.627f, - 27.431f, 30.188f, 30.054f, 30.815f, 31.196f, 33.286f, 35.315f, 37.087f, 36.809f, 36.017f, - 32.970f, 32.152f, 30.860f, 29.752f, 28.695f, 26.795f, 25.194f, 23.571f, 21.657f, 19.260f, - 17.815f, 16.033f, 14.326f, 12.896f, 11.233f, 9.572f, 7.869f, 6.243f, 4.358f, 2.376f, - 0.150f, -2.217f, -5.122f, -7.874f,-10.833f,-13.714f,-17.177f,-20.654f,-24.156f,-27.634f, --31.600f,-35.561f,-39.610f,-44.051f,-47.815f,-52.013f,-56.258f,-60.499f,-64.475f,-68.567f, --72.711f,-76.301f,-80.231f,-83.983f,-87.499f,-90.014f,-92.178f,-94.888f,-97.331f,-99.292f, --100.316f,-100.195f,-100.405f,-101.016f,-101.100f,-100.931f,-100.881f,-100.411f,-100.127f,-99.265f, --97.286f,-93.965f,-91.086f,-91.263f,-87.689f,-83.478f,-80.389f,-76.942f,-74.598f,-70.413f, --66.722f,-63.495f,-59.951f,-56.489f,-54.114f,-51.821f,-48.953f,-46.888f,-46.520f,-46.812f, --46.482f,-46.259f,-46.328f,-40.425f,-32.337f,-28.435f,-29.518f,-30.646f,-30.406f,-35.826f, --35.460f,-34.197f,-35.323f,-42.764f,-45.057f,-47.276f,-46.005f,-44.721f,-42.898f,-39.997f, --37.843f,-37.636f,-35.686f,-35.140f,-34.188f,-33.423f,-31.346f,-30.046f,-29.240f,-28.424f, --26.357f,-24.646f,-22.791f,-21.271f,-20.223f,-18.438f,-17.195f,-15.191f,-13.799f,-11.920f, --10.306f, -9.609f, -7.965f, -7.468f, -6.848f, -6.055f, -5.483f, -3.056f, -1.721f, 1.069f, - 3.780f, 7.025f, 9.989f, 10.284f, 11.683f, 13.763f, 15.607f, 15.070f, 14.418f, 13.947f, - 13.606f -},{ --29.534f,-28.530f,-25.334f,-22.173f,-17.764f,-12.480f, -8.835f, -4.684f, 1.363f, 5.334f, - 5.966f, 5.106f, 3.925f, 3.579f, 5.006f, 7.905f, 12.438f, 15.562f, 14.791f, 15.942f, - 16.086f, 15.836f, 16.553f, 18.085f, 17.962f, 19.658f, 21.543f, 22.743f, 23.377f, 25.453f, - 27.545f, 29.919f, 30.303f, 30.445f, 30.547f, 32.694f, 34.395f, 35.364f, 36.174f, 33.405f, - 31.947f, 31.206f, 29.650f, 28.651f, 27.799f, 26.117f, 24.218f, 22.531f, 20.927f, 19.053f, - 17.010f, 15.721f, 14.022f, 12.232f, 10.609f, 8.644f, 6.917f, 5.167f, 3.248f, 1.162f, - -1.264f, -4.195f, -7.113f, -9.998f,-13.126f,-15.990f,-19.136f,-22.696f,-26.447f,-29.931f, --33.478f,-37.169f,-40.746f,-44.987f,-49.526f,-53.263f,-57.867f,-62.190f,-66.239f,-70.150f, --74.022f,-77.828f,-81.512f,-85.192f,-88.267f,-91.128f,-93.285f,-96.114f,-97.538f,-99.216f, --100.655f,-101.565f,-102.393f,-103.011f,-102.925f,-102.407f,-101.900f,-100.994f,-100.049f,-96.143f, --95.019f,-92.344f,-89.960f,-87.666f,-86.030f,-83.502f,-81.181f,-78.019f,-74.901f,-71.145f, --66.988f,-63.319f,-60.767f,-57.424f,-54.535f,-53.563f,-53.479f,-50.292f,-48.456f,-48.775f, --48.413f,-48.005f,-45.595f,-33.652f,-24.886f,-26.622f,-25.646f,-27.607f,-33.390f,-46.759f, --40.597f,-34.429f,-37.045f,-41.620f,-45.960f,-48.466f,-47.964f,-45.832f,-43.227f,-40.086f, --39.059f,-39.136f,-37.316f,-36.756f,-35.672f,-34.104f,-32.492f,-30.761f,-29.887f,-29.185f, --27.510f,-26.411f,-23.820f,-21.919f,-20.757f,-19.152f,-17.184f,-15.320f,-13.944f,-12.127f, --10.707f, -9.396f, -8.018f, -7.701f, -7.210f, -6.269f, -5.953f, -3.277f, -1.738f, 0.935f, - 3.793f, 6.936f, 9.662f, 10.046f, 11.486f, 13.616f, 15.431f, 14.897f, 14.344f, 13.913f, - 13.606f -},{ --29.534f,-28.541f,-25.409f,-22.284f,-17.997f,-12.863f, -9.239f, -5.182f, 0.827f, 4.882f, - 5.675f, 4.977f, 4.024f, 3.572f, 4.593f, 7.553f, 11.335f, 14.408f, 14.825f, 15.548f, - 16.157f, 16.357f, 17.274f, 18.171f, 16.601f, 18.853f, 20.987f, 21.970f, 22.498f, 24.762f, - 27.268f, 29.398f, 29.373f, 29.156f, 29.894f, 31.850f, 32.575f, 34.059f, 33.447f, 31.118f, - 30.801f, 29.932f, 28.567f, 27.599f, 26.563f, 25.237f, 23.217f, 21.652f, 20.110f, 18.482f, - 16.978f, 14.987f, 13.445f, 11.786f, 9.928f, 7.898f, 5.871f, 4.019f, 1.970f, -0.446f, - -3.066f, -5.981f, -9.161f,-12.129f,-15.024f,-18.174f,-21.572f,-24.942f,-28.326f,-31.806f, --35.432f,-39.013f,-42.361f,-46.062f,-50.089f,-54.290f,-58.988f,-63.670f,-67.669f,-71.483f, --75.289f,-79.072f,-82.451f,-85.685f,-88.575f,-91.327f,-93.943f,-97.003f,-99.249f,-100.363f, --102.115f,-102.842f,-103.651f,-104.203f,-104.153f,-103.421f,-102.330f,-100.675f,-97.444f,-96.422f, --94.895f,-93.514f,-88.890f,-86.029f,-85.011f,-84.855f,-83.222f,-79.440f,-74.634f,-71.781f, --67.450f,-63.312f,-60.087f,-57.544f,-54.774f,-54.341f,-54.903f,-53.750f,-52.653f,-51.328f, --50.196f,-43.521f,-35.361f,-26.721f,-24.580f,-22.993f,-21.173f,-28.377f,-45.687f,-50.931f, --44.895f,-33.377f,-38.447f,-41.200f,-46.852f,-49.605f,-50.145f,-47.223f,-42.905f,-39.911f, --40.304f,-40.157f,-38.662f,-37.776f,-36.608f,-34.761f,-33.516f,-32.084f,-30.423f,-29.733f, --28.435f,-27.339f,-24.810f,-22.578f,-20.799f,-19.320f,-17.229f,-15.350f,-14.119f,-12.448f, --11.029f, -9.408f, -8.488f, -8.173f, -7.528f, -6.367f, -6.381f, -3.466f, -1.753f, 0.817f, - 3.623f, 6.790f, 9.280f, 9.792f, 11.294f, 13.476f, 15.268f, 14.742f, 14.270f, 13.879f, - 13.606f -},{ --29.534f,-28.553f,-25.490f,-22.404f,-18.243f,-13.260f, -9.619f, -5.633f, 0.234f, 4.128f, - 5.039f, 4.596f, 4.066f, 3.738f, 4.552f, 7.147f, 10.425f, 13.471f, 14.800f, 15.302f, - 15.966f, 16.910f, 18.076f, 18.209f, 15.331f, 18.352f, 20.073f, 20.955f, 21.813f, 24.068f, - 26.443f, 28.506f, 28.211f, 28.538f, 28.632f, 29.646f, 30.598f, 32.463f, 30.418f, 30.182f, - 29.546f, 28.854f, 27.543f, 26.305f, 25.410f, 23.970f, 22.351f, 20.732f, 19.184f, 17.702f, - 16.356f, 15.332f, 13.903f, 11.393f, 9.156f, 6.909f, 4.727f, 2.519f, 0.199f, -2.196f, - -5.096f, -8.201f,-10.961f,-13.968f,-17.206f,-20.050f,-23.341f,-26.980f,-30.466f,-33.549f, --36.989f,-40.781f,-43.697f,-47.314f,-51.290f,-55.287f,-59.539f,-64.072f,-68.245f,-72.037f, --75.933f,-79.821f,-83.344f,-86.095f,-89.255f,-91.830f,-94.456f,-97.266f,-99.953f,-101.061f, --102.606f,-103.495f,-103.671f,-103.471f,-104.199f,-104.683f,-104.391f,-103.329f,-99.427f,-96.784f, --95.356f,-94.476f,-91.113f,-86.507f,-86.637f,-87.109f,-84.564f,-78.600f,-74.827f,-71.395f, --67.938f,-63.657f,-59.243f,-59.244f,-56.334f,-56.079f,-56.740f,-56.664f,-56.283f,-54.544f, --48.350f,-35.948f,-28.191f,-22.914f,-22.814f,-21.543f,-24.098f,-33.845f,-51.503f,-51.701f, --46.389f,-35.203f,-37.837f,-42.067f,-47.365f,-49.227f,-50.839f,-47.485f,-42.750f,-40.356f, --42.036f,-40.733f,-39.688f,-38.806f,-37.688f,-35.316f,-34.049f,-33.379f,-31.605f,-30.890f, --28.780f,-27.079f,-25.154f,-22.649f,-20.729f,-19.095f,-17.008f,-15.372f,-14.135f,-12.763f, --11.458f, -9.968f, -9.335f, -8.596f, -7.854f, -6.522f, -6.698f, -3.552f, -1.904f, 0.711f, - 3.280f, 6.620f, 8.891f, 9.508f, 11.099f, 13.355f, 15.121f, 14.603f, 14.196f, 13.844f, - 13.606f -},{ --29.534f,-28.566f,-25.578f,-22.534f,-18.500f,-13.661f, -9.998f, -6.032f, -0.360f, 3.246f, - 4.297f, 4.072f, 3.748f, 3.642f, 4.686f, 6.998f, 9.853f, 13.190f, 14.903f, 15.550f, - 15.476f, 17.005f, 17.390f, 17.258f, 15.066f, 17.561f, 18.829f, 19.718f, 21.539f, 23.817f, - 25.559f, 27.395f, 27.614f, 27.620f, 26.622f, 27.592f, 27.270f, 29.521f, 28.806f, 28.772f, - 28.746f, 27.886f, 26.542f, 25.296f, 23.975f, 22.882f, 21.402f, 19.760f, 18.130f, 16.426f, - 14.716f, 12.895f, 12.230f, 10.293f, 7.988f, 5.505f, 3.123f, 0.710f, -1.787f, -4.443f, - -7.187f,-10.026f,-13.213f,-15.734f,-19.018f,-22.264f,-25.114f,-28.400f,-31.840f,-35.463f, --38.774f,-42.040f,-45.475f,-49.028f,-52.292f,-56.278f,-60.039f,-64.044f,-68.371f,-72.151f, --76.194f,-79.890f,-84.088f,-86.586f,-89.869f,-93.125f,-95.162f,-97.585f,-100.841f,-101.820f, --102.894f,-103.375f,-103.521f,-103.920f,-106.377f,-106.594f,-105.007f,-102.733f,-100.373f,-96.695f, --94.909f,-92.610f,-91.033f,-89.350f,-88.954f,-88.429f,-84.568f,-79.833f,-75.037f,-71.625f, --68.392f,-64.448f,-59.538f,-59.526f,-57.613f,-58.643f,-59.354f,-60.367f,-59.848f,-57.470f, --39.381f,-24.372f,-24.592f,-24.100f,-23.665f,-22.266f,-25.302f,-41.784f,-53.443f,-50.660f, --49.639f,-44.374f,-38.134f,-44.404f,-48.622f,-45.465f,-50.705f,-48.448f,-43.253f,-42.327f, --43.609f,-41.551f,-40.504f,-39.259f,-38.169f,-36.062f,-34.594f,-33.879f,-32.696f,-31.343f, --30.026f,-27.823f,-25.472f,-23.072f,-21.002f,-18.871f,-17.202f,-15.908f,-14.382f,-13.125f, --12.046f,-10.734f,-10.094f, -8.912f, -8.118f, -6.800f, -6.779f, -3.581f, -2.244f, 0.560f, - 2.846f, 6.449f, 8.561f, 9.178f, 10.898f, 13.261f, 14.992f, 14.482f, 14.122f, 13.809f, - 13.606f -},{ --29.534f,-28.579f,-25.671f,-22.674f,-18.767f,-14.059f,-10.393f, -6.391f, -0.934f, 2.409f, - 3.665f, 3.554f, 3.035f, 3.168f, 4.563f, 6.862f, 9.313f, 12.669f, 14.703f, 15.783f, - 15.575f, 16.694f, 16.210f, 15.949f, 15.154f, 16.222f, 17.607f, 18.471f, 21.448f, 23.402f, - 24.978f, 26.064f, 26.029f, 26.045f, 24.397f, 24.737f, 24.432f, 28.346f, 28.041f, 27.789f, - 27.216f, 26.443f, 25.371f, 24.195f, 22.677f, 21.420f, 20.322f, 18.725f, 16.990f, 15.111f, - 13.083f, 11.149f, 9.000f, 8.000f, 6.040f, 3.632f, 1.476f, -1.146f, -3.683f, -6.402f, - -9.295f,-11.865f,-14.847f,-18.007f,-20.456f,-23.636f,-27.100f,-30.194f,-33.493f,-36.952f, --40.365f,-43.723f,-46.938f,-50.319f,-53.674f,-57.279f,-60.901f,-64.143f,-68.145f,-71.992f, --75.940f,-79.066f,-83.273f,-85.663f,-89.854f,-92.927f,-93.944f,-97.704f,-100.371f,-101.251f, --102.688f,-103.379f,-103.731f,-104.088f,-105.697f,-105.992f,-100.427f,-96.745f,-96.020f,-96.065f, --96.033f,-93.495f,-93.008f,-91.754f,-90.304f,-86.792f,-83.431f,-80.012f,-75.333f,-72.426f, --67.924f,-64.719f,-60.325f,-57.911f,-58.451f,-59.528f,-61.135f,-63.189f,-62.844f,-55.211f, --34.529f,-22.274f,-24.422f,-25.472f,-25.153f,-24.771f,-29.875f,-48.186f,-53.771f,-51.457f, --55.718f,-54.184f,-38.815f,-46.672f,-49.422f,-40.262f,-51.273f,-49.385f,-44.784f,-44.326f, --44.506f,-43.018f,-40.720f,-39.742f,-38.552f,-36.263f,-34.834f,-33.986f,-33.395f,-32.186f, --30.595f,-28.865f,-26.460f,-23.575f,-21.127f,-19.713f,-18.158f,-16.363f,-14.875f,-13.457f, --12.638f,-11.288f,-10.519f, -9.200f, -8.273f, -7.042f, -6.579f, -3.689f, -2.661f, 0.341f, - 2.407f, 6.254f, 8.341f, 8.806f, 10.692f, 13.196f, 14.879f, 14.375f, 14.049f, 13.774f, - 13.606f -},{ --29.534f,-28.593f,-25.769f,-22.826f,-19.043f,-14.448f,-10.808f, -6.738f, -1.493f, 1.697f, - 3.200f, 3.117f, 2.226f, 2.648f, 4.267f, 6.493f, 8.802f, 11.722f, 14.154f, 15.454f, - 15.693f, 16.034f, 15.340f, 15.769f, 15.559f, 15.099f, 16.275f, 17.818f, 21.185f, 22.913f, - 24.978f, 24.948f, 24.892f, 23.116f, 22.174f, 22.616f, 23.306f, 26.061f, 26.888f, 26.638f, - 25.744f, 25.083f, 24.121f, 22.838f, 21.599f, 20.177f, 18.988f, 17.719f, 15.980f, 13.718f, - 11.668f, 9.458f, 7.369f, 4.976f, 3.870f, 1.766f, -0.583f, -2.900f, -5.633f, -8.328f, --10.725f,-14.099f,-16.538f,-19.400f,-22.491f,-25.248f,-28.550f,-31.903f,-35.136f,-38.508f, --41.870f,-45.170f,-48.543f,-51.754f,-54.814f,-58.202f,-61.641f,-64.909f,-68.484f,-71.584f, --75.151f,-78.090f,-81.506f,-84.164f,-88.632f,-91.684f,-94.161f,-95.853f,-98.091f,-100.094f, --101.659f,-102.479f,-103.170f,-103.570f,-104.791f,-104.557f,-97.878f,-92.728f,-94.181f,-95.402f, --98.390f,-99.016f,-96.467f,-93.413f,-91.541f,-87.762f,-81.124f,-77.210f,-74.971f,-69.934f, --66.904f,-64.695f,-61.259f,-58.549f,-59.045f,-59.982f,-62.389f,-65.501f,-62.951f,-47.955f, --29.347f,-24.246f,-26.369f,-26.804f,-26.402f,-26.351f,-32.950f,-50.722f,-54.080f,-53.548f, --59.764f,-59.281f,-43.919f,-46.340f,-51.217f,-43.903f,-50.321f,-49.042f,-45.989f,-44.907f, --45.320f,-43.185f,-41.037f,-40.239f,-38.729f,-35.814f,-35.109f,-34.392f,-33.788f,-32.720f, --30.966f,-29.361f,-26.996f,-23.725f,-21.568f,-20.565f,-18.652f,-16.460f,-15.165f,-13.744f, --13.227f,-11.800f,-10.731f, -9.324f, -8.431f, -7.152f, -6.286f, -3.980f, -2.990f, 0.119f, - 2.005f, 5.984f, 8.236f, 8.406f, 10.486f, 13.157f, 14.779f, 14.281f, 13.978f, 13.739f, - 13.606f -},{ --29.534f,-28.609f,-25.873f,-22.988f,-19.326f,-14.825f,-11.237f, -7.110f, -2.057f, 1.090f, - 2.803f, 2.720f, 1.628f, 2.384f, 4.256f, 6.154f, 8.507f, 11.092f, 13.472f, 14.663f, - 14.979f, 15.169f, 14.600f, 15.847f, 15.744f, 14.286f, 15.388f, 17.670f, 20.148f, 22.383f, - 23.811f, 24.267f, 23.420f, 20.425f, 19.993f, 20.969f, 23.514f, 23.963f, 25.051f, 25.058f, - 24.308f, 23.703f, 22.919f, 21.685f, 20.287f, 19.041f, 17.558f, 16.476f, 14.704f, 12.564f, - 10.010f, 7.946f, 5.591f, 3.625f, 1.250f, -0.546f, -2.420f, -4.881f, -7.167f,-10.097f, --12.697f,-15.449f,-18.616f,-21.222f,-23.946f,-26.940f,-29.833f,-33.234f,-36.736f,-40.361f, --43.982f,-47.381f,-50.202f,-53.864f,-56.627f,-58.918f,-62.035f,-65.321f,-68.765f,-72.030f, --75.116f,-77.044f,-80.876f,-82.282f,-86.640f,-88.421f,-90.747f,-92.777f,-94.397f,-97.215f, --98.650f,-100.444f,-101.749f,-101.675f,-102.643f,-102.563f,-100.330f,-95.258f,-95.360f,-97.548f, --97.193f,-96.413f,-94.624f,-92.369f,-90.604f,-88.767f,-81.912f,-75.383f,-71.740f,-68.186f, --65.169f,-64.220f,-62.138f,-59.873f,-58.692f,-60.398f,-63.860f,-67.101f,-58.198f,-39.585f, --25.351f,-25.863f,-28.419f,-28.987f,-28.447f,-29.056f,-33.279f,-50.618f,-54.972f,-57.462f, --61.506f,-61.212f,-52.277f,-47.930f,-51.426f,-52.379f,-52.189f,-49.111f,-46.924f,-45.260f, --44.968f,-42.498f,-41.857f,-40.469f,-38.750f,-36.092f,-35.492f,-34.998f,-34.415f,-33.045f, --31.535f,-29.383f,-27.362f,-24.354f,-22.256f,-20.318f,-18.806f,-16.735f,-15.414f,-14.136f, --13.732f,-12.400f,-10.879f, -9.324f, -8.699f, -7.232f, -6.206f, -4.432f, -3.193f, 0.004f, - 1.630f, 5.602f, 8.203f, 8.011f, 10.289f, 13.131f, 14.686f, 14.197f, 13.908f, 13.703f, - 13.606f -},{ --29.534f,-28.625f,-25.981f,-23.159f,-19.614f,-15.194f,-11.669f, -7.537f, -2.636f, 0.526f, - 2.340f, 2.267f, 1.208f, 2.221f, 4.495f, 6.120f, 8.254f, 10.718f, 12.663f, 13.751f, - 14.142f, 14.431f, 14.044f, 14.912f, 15.052f, 13.857f, 14.690f, 16.950f, 18.693f, 21.089f, - 22.486f, 22.552f, 20.692f, 18.639f, 19.405f, 20.362f, 22.085f, 22.791f, 23.443f, 23.563f, - 22.857f, 22.258f, 21.500f, 20.459f, 19.219f, 17.807f, 16.325f, 14.821f, 13.343f, 11.134f, - 8.780f, 6.402f, 4.327f, 1.849f, -0.035f, -2.405f, -4.451f, -6.577f, -9.038f,-11.698f, --14.758f,-17.417f,-19.992f,-22.866f,-25.401f,-28.305f,-31.246f,-34.617f,-38.051f,-41.484f, --44.970f,-48.575f,-51.730f,-54.921f,-58.090f,-60.157f,-62.181f,-64.587f,-68.156f,-71.808f, --74.595f,-76.902f,-79.614f,-81.274f,-85.750f,-86.704f,-87.372f,-88.249f,-92.159f,-94.597f, --94.316f,-96.088f,-99.244f,-98.786f,-99.335f,-99.234f,-98.451f,-96.049f,-94.720f,-95.126f, --94.583f,-93.372f,-91.575f,-89.610f,-87.959f,-86.696f,-84.028f,-77.989f,-69.963f,-65.161f, --65.129f,-63.505f,-61.658f,-59.676f,-59.265f,-61.706f,-65.692f,-67.279f,-54.532f,-33.954f, --25.539f,-28.396f,-28.678f,-30.403f,-30.333f,-31.544f,-32.083f,-50.645f,-56.236f,-59.025f, --62.403f,-63.093f,-55.724f,-49.158f,-51.518f,-55.944f,-50.515f,-47.988f,-50.292f,-46.057f, --43.563f,-41.964f,-42.836f,-40.519f,-38.900f,-36.802f,-35.790f,-35.429f,-35.137f,-33.909f, --31.510f,-29.474f,-27.648f,-24.501f,-22.198f,-20.095f,-18.600f,-16.644f,-15.538f,-14.442f, --14.014f,-12.878f,-11.174f, -9.619f, -8.998f, -7.329f, -6.467f, -4.910f, -3.383f, 0.029f, - 1.267f, 5.132f, 8.165f, 7.652f, 10.112f, 13.102f, 14.594f, 14.120f, 13.841f, 13.668f, - 13.606f -},{ --29.534f,-28.642f,-26.093f,-23.337f,-19.907f,-15.563f,-12.093f, -8.034f, -3.221f, -0.023f, - 1.760f, 1.689f, 0.644f, 1.794f, 4.390f, 6.101f, 7.821f, 9.965f, 11.781f, 12.910f, - 13.633f, 13.767f, 13.483f, 14.283f, 14.204f, 13.782f, 13.780f, 15.632f, 16.917f, 19.031f, - 21.122f, 19.408f, 17.770f, 18.060f, 18.566f, 18.674f, 20.247f, 21.838f, 21.984f, 21.961f, - 21.615f, 20.809f, 20.000f, 19.034f, 17.933f, 16.422f, 15.103f, 12.963f, 11.800f, 9.542f, - 7.290f, 4.908f, 2.614f, 0.335f, -1.815f, -4.008f, -6.212f, -8.350f,-10.537f,-13.177f, --16.027f,-19.007f,-21.714f,-24.445f,-27.063f,-29.806f,-32.989f,-35.853f,-38.654f,-42.147f, --45.844f,-48.810f,-52.921f,-55.990f,-58.782f,-61.165f,-63.915f,-66.038f,-67.672f,-70.094f, --73.546f,-75.620f,-79.010f,-80.663f,-84.199f,-86.333f,-87.065f,-88.920f,-90.359f,-91.795f, --92.866f,-94.863f,-95.477f,-95.019f,-95.041f,-94.691f,-95.080f,-93.747f,-92.422f,-92.154f, --91.399f,-90.140f,-88.876f,-86.993f,-86.384f,-84.402f,-83.393f,-80.114f,-72.082f,-66.734f, --63.041f,-61.861f,-60.037f,-57.256f,-58.115f,-62.252f,-66.131f,-66.691f,-52.512f,-30.808f, --27.358f,-29.115f,-30.117f,-31.287f,-31.880f,-33.409f,-34.294f,-46.258f,-56.227f,-60.476f, --64.040f,-64.547f,-55.741f,-50.684f,-52.265f,-58.216f,-51.266f,-47.500f,-51.014f,-46.825f, --42.656f,-41.078f,-43.667f,-40.882f,-39.503f,-36.790f,-36.134f,-35.895f,-35.737f,-34.184f, --31.569f,-29.458f,-27.473f,-24.133f,-22.296f,-20.243f,-18.393f,-16.923f,-15.529f,-14.741f, --14.149f,-13.235f,-11.717f,-10.279f, -9.215f, -7.329f, -6.911f, -5.271f, -3.663f, 0.086f, - 0.949f, 4.663f, 8.060f, 7.356f, 9.961f, 13.051f, 14.498f, 14.047f, 13.777f, 13.632f, - 13.606f -},{ --29.534f,-28.660f,-26.209f,-23.522f,-20.202f,-15.940f,-12.508f, -8.591f, -3.794f, -0.535f, - 1.109f, 0.995f, -0.264f, 1.104f, 3.813f, 5.714f, 7.365f, 9.032f, 10.936f, 12.205f, - 12.972f, 13.352f, 12.751f, 13.679f, 12.956f, 13.108f, 12.889f, 14.044f, 14.710f, 16.793f, - 17.385f, 16.276f, 16.031f, 17.056f, 17.623f, 18.855f, 19.619f, 20.072f, 20.562f, 20.433f, - 20.167f, 19.554f, 18.625f, 17.735f, 16.738f, 15.029f, 13.448f, 11.994f, 9.918f, 7.955f, - 5.847f, 3.435f, 0.927f, -1.362f, -3.443f, -5.784f, -7.668f,-10.255f,-12.559f,-15.042f, --17.791f,-20.273f,-23.170f,-25.974f,-28.869f,-31.823f,-34.489f,-36.997f,-39.330f,-42.350f, --46.734f,-50.051f,-52.375f,-56.620f,-59.162f,-61.151f,-64.050f,-66.752f,-69.109f,-69.726f, --71.180f,-73.913f,-76.652f,-78.333f,-81.078f,-83.290f,-84.832f,-86.689f,-87.100f,-88.198f, --88.790f,-91.094f,-89.939f,-90.839f,-89.991f,-90.096f,-90.340f,-89.558f,-88.371f,-87.797f, --87.744f,-87.543f,-86.623f,-86.170f,-86.147f,-83.145f,-81.195f,-80.167f,-76.078f,-67.497f, --63.243f,-59.935f,-58.122f,-55.479f,-56.866f,-61.513f,-65.285f,-65.446f,-45.210f,-29.278f, --27.751f,-30.055f,-30.807f,-32.015f,-33.522f,-34.941f,-36.170f,-42.145f,-55.598f,-61.516f, --65.545f,-65.623f,-57.231f,-47.700f,-55.799f,-62.579f,-55.777f,-46.718f,-51.400f,-44.366f, --42.506f,-41.060f,-43.476f,-41.629f,-39.424f,-36.967f,-36.244f,-36.311f,-35.890f,-34.314f, --31.724f,-29.196f,-27.193f,-24.964f,-23.282f,-20.859f,-19.244f,-17.693f,-15.541f,-15.199f, --14.307f,-13.651f,-12.203f,-10.843f, -9.405f, -7.194f, -7.298f, -5.464f, -3.979f, 0.012f, - 0.751f, 4.292f, 7.871f, 7.135f, 9.839f, 12.965f, 14.392f, 13.977f, 13.715f, 13.596f, - 13.606f -},{ --29.534f,-28.679f,-26.327f,-23.710f,-20.500f,-16.335f,-12.922f, -9.179f, -4.351f, -0.987f, - 0.460f, 0.259f, -1.311f, 0.566f, 3.475f, 5.199f, 6.954f, 8.325f, 10.020f, 11.446f, - 12.170f, 12.977f, 11.622f, 11.753f, 11.886f, 12.074f, 11.921f, 12.717f, 13.020f, 14.461f, - 14.179f, 14.378f, 15.013f, 16.179f, 17.104f, 17.618f, 18.182f, 18.849f, 18.995f, 18.937f, - 18.680f, 18.084f, 17.368f, 16.385f, 15.154f, 13.707f, 12.121f, 10.593f, 8.931f, 6.507f, - 4.123f, 1.907f, -0.462f, -3.004f, -5.446f, -7.066f, -9.063f,-11.144f,-14.254f,-16.759f, --19.158f,-21.920f,-24.485f,-27.083f,-29.970f,-32.651f,-35.260f,-37.577f,-40.199f,-42.810f, --46.238f,-51.142f,-53.684f,-55.878f,-58.227f,-58.473f,-62.724f,-65.451f,-68.310f,-69.609f, --70.130f,-72.290f,-74.587f,-76.010f,-76.844f,-78.733f,-80.315f,-81.844f,-82.682f,-83.855f, --84.087f,-85.904f,-84.754f,-85.108f,-85.797f,-85.521f,-85.422f,-84.724f,-84.462f,-84.385f, --84.424f,-83.869f,-83.259f,-81.987f,-80.241f,-79.294f,-78.091f,-76.902f,-73.910f,-70.040f, --63.900f,-60.191f,-57.708f,-56.099f,-56.403f,-60.552f,-64.377f,-58.612f,-33.135f,-29.585f, --29.748f,-30.749f,-31.594f,-33.042f,-34.381f,-36.180f,-37.038f,-39.287f,-54.727f,-62.565f, --66.515f,-65.011f,-60.244f,-48.976f,-61.163f,-66.003f,-59.804f,-47.996f,-51.473f,-44.111f, --40.678f,-41.344f,-42.585f,-41.199f,-39.369f,-37.657f,-35.772f,-36.106f,-35.460f,-34.527f, --32.116f,-29.373f,-27.108f,-25.856f,-24.251f,-21.998f,-19.993f,-17.473f,-15.403f,-15.121f, --14.506f,-14.031f,-12.408f,-11.172f, -9.644f, -7.061f, -7.509f, -5.525f, -4.183f, -0.270f, - 0.739f, 4.068f, 7.646f, 6.985f, 9.745f, 12.838f, 14.274f, 13.906f, 13.657f, 13.560f, - 13.606f -},{ --29.534f,-28.699f,-26.448f,-23.900f,-20.797f,-16.754f,-13.351f, -9.764f, -4.920f, -1.419f, - -0.163f, -0.436f, -2.057f, 0.415f, 3.802f, 5.041f, 6.302f, 7.415f, 8.900f, 10.339f, - 11.433f, 12.028f, 10.438f, 10.259f, 11.541f, 11.037f, 10.900f, 11.503f, 11.717f, 12.448f, - 12.410f, 13.239f, 14.895f, 15.799f, 15.951f, 16.575f, 16.908f, 17.279f, 17.577f, 17.525f, - 17.216f, 16.737f, 15.897f, 14.955f, 13.633f, 11.994f, 10.618f, 9.099f, 7.486f, 5.433f, - 2.412f, 0.031f, -2.337f, -4.607f, -7.067f, -9.246f,-10.518f,-12.412f,-14.635f,-17.469f, --20.246f,-22.962f,-25.853f,-27.385f,-29.256f,-32.194f,-35.087f,-37.736f,-39.941f,-42.582f, --44.813f,-48.436f,-51.958f,-54.424f,-56.702f,-56.494f,-60.981f,-65.562f,-67.200f,-68.009f, --69.290f,-70.215f,-72.293f,-73.424f,-74.666f,-75.978f,-76.313f,-77.253f,-78.327f,-79.340f, --79.038f,-79.744f,-80.258f,-80.260f,-80.008f,-79.932f,-79.345f,-79.102f,-78.386f,-78.312f, --78.984f,-78.802f,-78.702f,-78.061f,-76.977f,-76.026f,-75.051f,-73.326f,-71.266f,-68.212f, --64.177f,-61.556f,-59.061f,-56.384f,-55.490f,-58.801f,-61.812f,-51.090f,-28.944f,-30.098f, --29.613f,-31.252f,-33.294f,-34.369f,-35.753f,-37.262f,-37.987f,-41.753f,-48.575f,-62.960f, --66.517f,-63.690f,-62.559f,-52.649f,-66.301f,-66.743f,-60.752f,-53.042f,-48.907f,-41.840f, --41.105f,-40.050f,-41.911f,-40.131f,-39.924f,-36.759f,-35.993f,-36.886f,-35.274f,-34.501f, --32.344f,-29.252f,-26.824f,-25.567f,-24.776f,-22.899f,-20.612f,-17.539f,-15.709f,-14.474f, --14.452f,-14.197f,-12.562f,-11.508f, -9.850f, -7.028f, -7.534f, -5.528f, -4.209f, -0.680f, - 0.907f, 3.965f, 7.470f, 6.891f, 9.674f, 12.672f, 14.146f, 13.833f, 13.603f, 13.524f, - 13.606f -},{ --29.534f,-28.720f,-26.570f,-24.092f,-21.093f,-17.199f,-13.808f,-10.321f, -5.552f, -1.949f, - -0.792f, -1.028f, -2.272f, 0.320f, 3.949f, 4.999f, 5.360f, 6.048f, 7.625f, 8.991f, - 10.539f, 11.248f, 10.449f, 10.332f, 10.358f, 9.740f, 9.729f, 9.901f, 10.378f, 10.707f, - 11.095f, 12.455f, 13.514f, 14.524f, 14.987f, 15.309f, 15.781f, 15.919f, 16.070f, 16.047f, - 15.782f, 15.206f, 14.507f, 13.468f, 12.009f, 10.585f, 9.045f, 7.587f, 5.828f, 3.722f, - 0.968f, -1.754f, -4.206f, -6.632f, -8.902f,-11.047f,-12.963f,-14.676f,-16.050f,-17.747f, --20.848f,-24.535f,-27.622f,-28.975f,-31.253f,-33.138f,-36.351f,-37.969f,-39.849f,-43.071f, --44.851f,-46.933f,-48.115f,-50.991f,-54.180f,-56.433f,-59.502f,-62.766f,-64.865f,-66.674f, --68.168f,-68.185f,-69.609f,-70.331f,-71.452f,-72.200f,-72.597f,-72.893f,-72.327f,-73.942f, --73.734f,-73.607f,-73.433f,-73.787f,-73.093f,-73.424f,-73.350f,-73.673f,-73.229f,-73.447f, --73.759f,-73.772f,-73.611f,-73.372f,-72.971f,-72.477f,-71.792f,-70.711f,-68.947f,-66.755f, --62.245f,-59.326f,-58.274f,-57.152f,-56.283f,-56.245f,-57.767f,-47.085f,-29.405f,-31.128f, --30.672f,-32.575f,-34.970f,-35.634f,-36.951f,-38.484f,-39.180f,-41.822f,-44.649f,-62.850f, --66.297f,-61.901f,-62.445f,-61.991f,-63.653f,-64.781f,-60.295f,-53.722f,-46.253f,-40.696f, --40.418f,-40.233f,-40.903f,-39.499f,-38.345f,-35.433f,-37.458f,-37.855f,-36.073f,-35.011f, --33.008f,-30.168f,-27.062f,-26.107f,-25.047f,-23.219f,-21.671f,-18.339f,-16.600f,-14.472f, --13.940f,-14.207f,-12.746f,-11.712f, -9.946f, -7.065f, -7.416f, -5.533f, -4.148f, -1.049f, - 1.160f, 3.917f, 7.422f, 6.832f, 9.623f, 12.480f, 14.009f, 13.756f, 13.552f, 13.489f, - 13.606f -},{ --29.534f,-28.742f,-26.693f,-24.284f,-21.387f,-17.665f,-14.303f,-10.844f, -6.296f, -2.714f, - -1.481f, -1.508f, -2.155f, -0.221f, 2.697f, 4.186f, 4.513f, 4.995f, 6.367f, 7.740f, - 9.363f, 10.889f, 10.540f, 10.050f, 8.581f, 8.414f, 8.246f, 8.273f, 8.882f, 9.378f, - 9.921f, 11.582f, 12.509f, 13.477f, 13.930f, 14.196f, 14.476f, 14.806f, 14.948f, 14.590f, - 14.145f, 13.726f, 13.025f, 11.878f, 10.535f, 9.019f, 7.618f, 5.988f, 4.178f, 1.857f, - -0.579f, -3.485f, -6.035f, -8.367f,-10.686f,-13.017f,-14.963f,-17.049f,-18.959f,-20.788f, --22.650f,-26.986f,-29.907f,-32.160f,-34.191f,-36.310f,-38.332f,-40.835f,-43.515f,-45.955f, --47.915f,-50.584f,-52.990f,-54.885f,-57.494f,-59.403f,-59.956f,-60.386f,-61.565f,-62.858f, --64.918f,-64.730f,-65.591f,-65.317f,-65.851f,-67.237f,-66.335f,-67.477f,-67.706f,-67.460f, --68.665f,-67.821f,-66.477f,-66.976f,-66.832f,-66.715f,-67.148f,-67.255f,-66.680f,-66.764f, --67.568f,-68.168f,-68.605f,-68.505f,-68.510f,-68.520f,-68.078f,-67.155f,-66.600f,-64.817f, --60.897f,-57.567f,-57.080f,-56.040f,-55.577f,-55.034f,-53.348f,-41.015f,-28.662f,-33.225f, --32.911f,-34.387f,-37.120f,-37.045f,-37.959f,-39.462f,-40.588f,-44.393f,-43.740f,-58.306f, --66.456f,-61.622f,-63.612f,-64.730f,-60.411f,-61.271f,-57.507f,-51.441f,-42.643f,-42.176f, --40.808f,-39.613f,-38.987f,-39.231f,-36.030f,-36.045f,-38.070f,-38.160f,-36.532f,-35.768f, --34.103f,-30.880f,-27.302f,-26.615f,-24.889f,-23.117f,-22.042f,-18.805f,-17.244f,-15.374f, --13.437f,-14.112f,-12.772f,-11.520f,-10.027f, -7.152f, -7.270f, -5.577f, -4.124f, -1.256f, - 1.378f, 3.884f, 7.525f, 6.791f, 9.588f, 12.283f, 13.868f, 13.676f, 13.504f, 13.453f, - 13.606f -},{ --29.534f,-28.765f,-26.817f,-24.475f,-21.676f,-18.142f,-14.834f,-11.351f, -7.168f, -3.777f, - -2.281f, -1.947f, -2.149f, -1.250f, 0.108f, 2.262f, 3.840f, 4.734f, 5.443f, 6.633f, - 8.244f, 10.021f, 9.412f, 8.843f, 7.539f, 7.069f, 6.643f, 6.971f, 7.440f, 7.972f, - 8.876f, 10.309f, 11.581f, 12.464f, 12.958f, 12.909f, 13.224f, 13.459f, 13.818f, 13.274f, - 12.701f, 12.225f, 11.368f, 10.333f, 8.965f, 7.587f, 6.068f, 4.389f, 2.454f, 0.057f, - -2.478f, -5.137f, -7.701f,-10.240f,-12.370f,-14.755f,-16.892f,-19.087f,-21.134f,-22.974f, --25.197f,-28.527f,-30.985f,-33.726f,-35.869f,-38.290f,-40.597f,-42.535f,-44.553f,-46.188f, --48.157f,-50.548f,-52.858f,-54.458f,-56.264f,-57.770f,-59.499f,-61.013f,-62.739f,-64.579f, --64.511f,-64.627f,-64.717f,-63.865f,-63.258f,-64.339f,-62.878f,-62.991f,-63.940f,-62.219f, --63.236f,-61.227f,-60.768f,-60.329f,-60.266f,-60.384f,-59.782f,-60.389f,-61.782f,-62.257f, --63.260f,-64.208f,-64.251f,-64.643f,-64.578f,-64.136f,-64.080f,-63.282f,-63.089f,-62.929f, --59.527f,-57.172f,-56.594f,-55.710f,-55.421f,-53.810f,-50.152f,-41.045f,-29.868f,-33.586f, --34.079f,-35.397f,-37.009f,-37.603f,-38.661f,-40.410f,-41.855f,-46.144f,-48.307f,-55.482f, --66.646f,-62.497f,-63.023f,-63.018f,-60.805f,-59.302f,-54.264f,-47.324f,-42.488f,-42.891f, --42.053f,-40.554f,-38.854f,-39.661f,-36.801f,-37.582f,-38.184f,-38.174f,-37.227f,-36.827f, --33.911f,-30.248f,-27.699f,-26.437f,-24.570f,-22.756f,-22.112f,-19.549f,-17.678f,-16.097f, --13.267f,-13.929f,-12.769f,-11.233f,-10.167f, -7.311f, -7.223f, -5.675f, -4.157f, -1.307f, - 1.501f, 3.895f, 7.724f, 6.758f, 9.569f, 12.105f, 13.731f, 13.590f, 13.461f, 13.417f, - 13.606f -},{ --29.534f,-28.789f,-26.940f,-24.667f,-21.961f,-18.616f,-15.387f,-11.875f, -8.141f, -5.072f, - -3.231f, -2.509f, -2.584f, -2.354f, -2.446f, -0.044f, 2.869f, 4.479f, 4.976f, 5.619f, - 7.532f, 9.288f, 9.371f, 8.429f, 6.561f, 6.002f, 5.370f, 5.717f, 5.877f, 6.314f, - 7.954f, 9.244f, 10.469f, 11.290f, 11.682f, 11.624f, 11.749f, 12.115f, 12.202f, 11.925f, - 11.403f, 10.773f, 9.754f, 8.633f, 7.410f, 6.042f, 4.412f, 2.726f, 0.570f, -1.691f, - -4.329f, -6.885f, -9.557f,-12.104f,-14.277f,-16.591f,-18.881f,-21.167f,-23.240f,-25.174f, --27.389f,-30.900f,-33.754f,-35.786f,-37.697f,-39.487f,-41.520f,-43.418f,-45.113f,-46.229f, --48.077f,-50.698f,-52.204f,-54.002f,-55.987f,-57.486f,-58.903f,-59.247f,-58.849f,-59.625f, --60.127f,-60.204f,-60.815f,-61.285f,-60.956f,-60.455f,-60.124f,-59.037f,-58.985f,-58.800f, --58.098f,-57.573f,-56.460f,-54.978f,-54.761f,-54.471f,-54.751f,-56.165f,-58.308f,-61.180f, --62.916f,-63.484f,-63.154f,-62.259f,-61.807f,-61.180f,-60.969f,-60.626f,-59.965f,-60.109f, --57.037f,-56.322f,-55.908f,-54.766f,-54.755f,-53.327f,-48.734f,-41.830f,-31.230f,-32.946f, --34.914f,-35.605f,-36.794f,-37.614f,-39.473f,-41.277f,-42.868f,-46.380f,-53.877f,-55.267f, --65.968f,-63.645f,-61.742f,-64.248f,-59.501f,-56.896f,-52.931f,-43.082f,-44.317f,-44.376f, --42.360f,-42.360f,-39.808f,-40.864f,-38.991f,-38.118f,-38.164f,-38.507f,-38.129f,-36.471f, --32.835f,-29.725f,-28.572f,-26.711f,-24.256f,-22.492f,-22.444f,-19.825f,-17.891f,-15.785f, --12.903f,-13.960f,-12.988f,-11.166f,-10.261f, -7.507f, -7.243f, -5.813f, -4.180f, -1.296f, - 1.563f, 4.025f, 7.898f, 6.731f, 9.566f, 11.967f, 13.602f, 13.499f, 13.420f, 13.381f, - 13.606f -},{ --29.534f,-28.814f,-27.063f,-24.859f,-22.241f,-19.072f,-15.939f,-12.451f, -9.156f, -6.432f, - -4.361f, -3.409f, -3.508f, -3.272f, -3.925f, -1.836f, 1.320f, 3.414f, 4.485f, 4.635f, - 6.818f, 9.056f, 10.036f, 7.997f, 4.893f, 5.134f, 4.411f, 4.379f, 3.944f, 4.709f, - 6.610f, 8.259f, 9.337f, 10.079f, 10.443f, 10.304f, 10.534f, 10.581f, 10.875f, 10.520f, - 10.033f, 9.372f, 8.208f, 7.046f, 5.768f, 4.365f, 2.681f, 0.854f, -1.252f, -3.632f, - -6.203f, -8.641f,-11.234f,-13.744f,-16.009f,-18.332f,-20.591f,-22.854f,-24.988f,-26.878f, --29.799f,-32.543f,-34.630f,-36.881f,-38.682f,-40.540f,-42.584f,-44.233f,-46.042f,-47.030f, --47.654f,-49.895f,-52.137f,-52.747f,-54.070f,-55.467f,-56.458f,-57.125f,-58.389f,-57.311f, --58.132f,-58.004f,-58.066f,-57.625f,-56.490f,-55.814f,-55.149f,-54.041f,-53.731f,-53.537f, --53.021f,-52.372f,-51.324f,-51.071f,-51.390f,-52.405f,-55.418f,-57.735f,-58.099f,-59.274f, --60.660f,-61.458f,-62.413f,-62.231f,-61.843f,-60.263f,-59.619f,-59.531f,-59.214f,-59.613f, --54.920f,-54.493f,-54.064f,-53.780f,-54.879f,-52.344f,-48.416f,-41.576f,-30.404f,-32.080f, --34.820f,-36.338f,-37.196f,-37.903f,-40.421f,-41.811f,-43.899f,-50.425f,-58.643f,-56.105f, --64.378f,-62.515f,-62.519f,-64.079f,-57.950f,-57.402f,-51.465f,-45.396f,-48.283f,-45.512f, --44.688f,-43.057f,-40.947f,-40.586f,-39.502f,-38.104f,-37.862f,-38.611f,-37.879f,-35.182f, --32.147f,-29.991f,-28.934f,-26.708f,-24.372f,-23.214f,-22.667f,-19.411f,-17.453f,-14.925f, --12.301f,-14.377f,-13.323f,-11.083f,-10.214f, -7.675f, -7.162f, -5.973f, -4.167f, -1.304f, - 1.648f, 4.318f, 7.903f, 6.714f, 9.573f, 11.885f, 13.487f, 13.403f, 13.383f, 13.345f, - 13.606f -},{ --29.534f,-28.841f,-27.185f,-25.052f,-22.515f,-19.500f,-16.469f,-13.102f,-10.152f, -7.681f, - -5.664f, -4.774f, -4.773f, -4.189f, -4.599f, -3.008f, -0.453f, 1.832f, 3.453f, 3.304f, - 5.562f, 8.402f, 8.673f, 5.818f, 3.073f, 4.332f, 3.426f, 3.156f, 2.045f, 3.084f, - 5.102f, 6.990f, 8.368f, 8.983f, 9.209f, 8.969f, 9.216f, 9.272f, 9.379f, 9.192f, - 8.589f, 7.779f, 6.654f, 5.538f, 4.062f, 2.679f, 0.900f, -0.996f, -3.081f, -5.457f, - -8.068f,-10.661f,-13.284f,-15.660f,-17.972f,-20.301f,-22.427f,-24.535f,-26.214f,-28.234f, --30.524f,-33.039f,-35.281f,-37.625f,-39.574f,-41.438f,-43.090f,-44.781f,-46.381f,-47.666f, --48.362f,-48.777f,-50.529f,-52.062f,-52.880f,-53.935f,-54.810f,-55.688f,-55.771f,-54.899f, --54.050f,-54.541f,-53.551f,-52.139f,-50.942f,-50.417f,-49.342f,-47.802f,-47.166f,-46.726f, --46.945f,-46.517f,-47.350f,-48.831f,-50.575f,-50.247f,-54.257f,-59.321f,-59.754f,-60.868f, --63.776f,-62.827f,-61.683f,-61.107f,-60.054f,-62.015f,-61.373f,-60.017f,-58.736f,-56.597f, --52.811f,-52.270f,-51.111f,-50.594f,-52.276f,-51.022f,-52.523f,-47.324f,-34.348f,-31.179f, --34.209f,-36.569f,-37.888f,-38.754f,-40.838f,-42.509f,-44.546f,-55.690f,-59.999f,-55.623f, --62.995f,-61.444f,-63.117f,-61.527f,-58.992f,-56.688f,-49.932f,-47.476f,-49.441f,-47.181f, --45.649f,-43.464f,-41.972f,-40.442f,-39.019f,-37.573f,-39.019f,-38.758f,-36.719f,-34.103f, --31.216f,-30.416f,-29.115f,-26.873f,-25.379f,-24.639f,-22.729f,-19.500f,-16.751f,-14.673f, --12.297f,-14.740f,-13.708f,-10.924f,-10.057f, -7.864f, -6.955f, -6.153f, -4.189f, -1.341f, - 1.800f, 4.732f, 7.637f, 6.711f, 9.585f, 11.864f, 13.388f, 13.300f, 13.347f, 13.310f, - 13.606f -},{ --29.534f,-28.868f,-27.306f,-25.247f,-22.787f,-19.894f,-16.965f,-13.832f,-11.100f, -8.739f, - -7.071f, -6.514f, -6.199f, -5.367f, -5.264f, -4.010f, -1.949f, 0.473f, 2.071f, 1.407f, - 4.112f, 7.689f, 7.123f, 4.065f, 1.329f, 3.927f, 2.726f, 2.093f, 0.628f, 2.003f, - 4.093f, 5.634f, 7.036f, 7.750f, 7.806f, 7.863f, 7.996f, 8.052f, 7.982f, 7.702f, - 7.157f, 6.262f, 5.030f, 3.695f, 2.436f, 0.873f, -0.875f, -2.804f, -5.025f, -7.445f, - -9.996f,-12.449f,-14.900f,-17.422f,-19.728f,-21.928f,-24.146f,-26.538f,-28.135f,-28.100f, --31.466f,-33.458f,-36.454f,-38.700f,-40.431f,-42.100f,-43.217f,-44.779f,-46.285f,-47.488f, --48.712f,-50.001f,-49.997f,-49.333f,-51.527f,-52.650f,-52.663f,-52.752f,-52.296f,-51.591f, --51.876f,-49.877f,-49.846f,-48.453f,-47.612f,-45.640f,-43.999f,-42.601f,-41.872f,-40.566f, --39.827f,-40.257f,-43.444f,-44.285f,-44.418f,-49.277f,-52.431f,-49.846f,-49.250f,-51.485f, --53.093f,-53.007f,-53.989f,-57.366f,-58.728f,-55.954f,-56.348f,-57.811f,-54.845f,-51.028f, --50.097f,-51.302f,-51.250f,-50.849f,-50.532f,-49.795f,-54.711f,-55.841f,-41.369f,-30.052f, --35.086f,-36.197f,-38.237f,-39.494f,-40.796f,-42.762f,-46.000f,-57.961f,-58.415f,-52.480f, --61.834f,-61.021f,-62.763f,-57.334f,-59.746f,-56.141f,-48.866f,-49.375f,-48.618f,-46.456f, --46.093f,-43.402f,-42.699f,-39.884f,-38.560f,-37.156f,-39.191f,-38.525f,-36.408f,-33.509f, --31.408f,-31.212f,-29.247f,-27.720f,-26.684f,-25.130f,-22.335f,-19.521f,-16.306f,-14.704f, --13.004f,-14.736f,-14.132f,-11.146f, -9.827f, -8.178f, -6.879f, -6.348f, -4.323f, -1.380f, - 1.985f, 5.142f, 7.089f, 6.724f, 9.588f, 11.897f, 13.305f, 13.191f, 13.314f, 13.275f, - 13.606f -},{ --29.534f,-28.896f,-27.425f,-25.447f,-23.056f,-20.256f,-17.429f,-14.621f,-12.009f, -9.648f, - -8.450f, -8.316f, -7.647f, -6.712f, -6.159f, -5.091f, -3.090f, -0.489f, 0.716f, -0.598f, - 2.662f, 6.687f, 6.126f, 3.295f, 0.141f, 3.432f, 2.396f, 0.354f, -0.308f, 1.363f, - 2.952f, 4.629f, 5.704f, 6.255f, 6.542f, 6.669f, 6.773f, 6.694f, 6.471f, 6.149f, - 5.650f, 4.859f, 3.582f, 2.223f, 0.705f, -0.734f, -2.774f, -4.668f, -6.806f, -9.367f, --11.975f,-14.436f,-16.999f,-19.420f,-21.852f,-23.934f,-26.084f,-27.989f,-29.728f,-29.559f, --32.114f,-34.179f,-37.191f,-39.483f,-41.212f,-42.621f,-43.849f,-44.864f,-45.881f,-47.053f, --48.332f,-49.157f,-50.793f,-51.338f,-49.641f,-48.583f,-49.519f,-47.551f,-47.934f,-47.787f, --46.860f,-45.718f,-44.802f,-44.450f,-43.559f,-41.506f,-39.064f,-36.975f,-35.570f,-34.657f, --34.089f,-35.312f,-38.876f,-36.796f,-42.686f,-41.775f,-40.405f,-41.808f,-42.784f,-44.019f, --46.101f,-48.188f,-48.914f,-49.978f,-50.516f,-50.176f,-50.713f,-51.304f,-49.931f,-49.314f, --51.185f,-51.803f,-51.373f,-51.015f,-50.659f,-50.540f,-52.108f,-55.732f,-48.239f,-39.941f, --38.469f,-37.136f,-38.640f,-40.004f,-40.849f,-42.296f,-47.623f,-57.078f,-52.694f,-50.947f, --58.938f,-59.665f,-60.955f,-57.243f,-61.526f,-52.932f,-51.803f,-49.307f,-47.558f,-45.589f, --45.950f,-43.456f,-40.960f,-39.702f,-37.850f,-37.867f,-39.455f,-40.243f,-37.775f,-33.687f, --33.081f,-31.723f,-29.256f,-28.663f,-27.504f,-24.801f,-21.957f,-19.538f,-16.238f,-14.242f, --13.799f,-14.575f,-14.131f,-11.848f, -9.614f, -8.580f, -7.164f, -6.527f, -4.558f, -1.413f, - 2.124f, 5.410f, 6.350f, 6.747f, 9.572f, 11.967f, 13.234f, 13.075f, 13.281f, 13.240f, - 13.606f -},{ --29.534f,-28.925f,-27.543f,-25.651f,-23.328f,-20.595f,-17.874f,-15.437f,-12.908f,-10.527f, - -9.681f, -9.820f, -9.039f, -7.929f, -7.062f, -6.141f, -4.199f, -1.478f, -0.783f, -2.268f, - 0.880f, 4.526f, 3.989f, 1.152f, -0.089f, 2.524f, 1.603f, -1.061f, -1.327f, 0.302f, - 1.547f, 3.382f, 4.391f, 4.946f, 5.301f, 5.447f, 5.602f, 5.332f, 4.979f, 4.552f, - 4.170f, 3.310f, 2.281f, 0.852f, -0.866f, -2.591f, -4.529f, -6.522f, -8.839f,-11.338f, --13.763f,-16.342f,-18.906f,-21.358f,-23.759f,-26.028f,-28.070f,-29.762f,-29.477f,-32.457f, --33.490f,-35.518f,-37.698f,-39.888f,-42.014f,-42.990f,-44.277f,-44.964f,-45.795f,-46.599f, --47.849f,-48.804f,-49.330f,-48.882f,-48.771f,-48.092f,-46.078f,-43.018f,-43.856f,-43.686f, --42.898f,-42.461f,-42.019f,-39.741f,-37.328f,-34.863f,-33.100f,-31.302f,-30.139f,-29.434f, --29.623f,-32.145f,-32.076f,-31.191f,-32.634f,-29.403f,-33.675f,-34.539f,-35.906f,-39.079f, --42.208f,-44.463f,-46.104f,-46.776f,-46.208f,-46.636f,-46.961f,-47.862f,-47.967f,-48.121f, --48.132f,-47.658f,-48.031f,-48.460f,-48.554f,-48.838f,-49.250f,-51.005f,-48.956f,-43.934f, --38.006f,-38.083f,-39.136f,-40.309f,-41.096f,-42.259f,-46.890f,-54.504f,-48.364f,-48.687f, --55.661f,-57.777f,-57.710f,-59.599f,-57.832f,-52.558f,-49.740f,-48.373f,-46.693f,-45.287f, --44.768f,-43.311f,-40.312f,-39.127f,-36.842f,-38.200f,-39.785f,-40.523f,-38.647f,-34.422f, --34.526f,-32.703f,-29.653f,-29.144f,-27.532f,-24.911f,-22.295f,-19.850f,-16.473f,-14.309f, --14.364f,-14.276f,-13.475f,-12.515f, -9.667f, -8.906f, -7.662f, -6.661f, -4.821f, -1.468f, - 2.180f, 5.475f, 5.587f, 6.766f, 9.531f, 12.050f, 13.169f, 12.954f, 13.247f, 13.206f, - 13.606f -},{ --29.534f,-28.955f,-27.659f,-25.861f,-23.604f,-20.921f,-18.326f,-16.246f,-13.819f,-11.477f, --10.733f,-10.868f,-10.354f, -8.992f, -7.946f, -7.067f, -5.532f, -2.992f, -2.647f, -3.641f, - -0.913f, 2.299f, 2.357f, -0.734f, -1.257f, 1.481f, 0.411f, -1.558f, -2.145f, -0.739f, - 0.333f, 1.812f, 2.876f, 3.625f, 4.221f, 4.223f, 4.404f, 3.993f, 3.620f, 3.043f, - 2.455f, 1.850f, 0.758f, -0.785f, -2.618f, -4.548f, -6.435f, -8.432f,-10.824f,-13.216f, --15.663f,-18.083f,-20.710f,-23.199f,-25.491f,-27.726f,-29.611f,-31.925f,-30.650f,-33.727f, --35.054f,-36.846f,-38.376f,-39.959f,-42.022f,-43.232f,-44.443f,-45.838f,-46.593f,-47.162f, --47.605f,-47.652f,-48.005f,-47.686f,-46.252f,-43.988f,-42.446f,-42.107f,-39.167f,-39.273f, --38.598f,-37.396f,-35.311f,-33.754f,-31.345f,-29.658f,-27.664f,-26.676f,-26.179f,-27.047f, --29.074f,-25.725f,-27.033f,-28.612f,-22.450f,-25.693f,-29.777f,-30.510f,-31.927f,-33.975f, --35.792f,-37.764f,-39.257f,-40.676f,-42.390f,-43.097f,-43.839f,-44.153f,-44.406f,-43.961f, --43.621f,-43.326f,-44.201f,-44.133f,-45.874f,-45.496f,-45.554f,-45.540f,-42.191f,-40.303f, --36.075f,-37.353f,-38.622f,-39.733f,-40.007f,-41.921f,-47.599f,-53.604f,-47.404f,-47.213f, --54.977f,-56.310f,-56.238f,-56.760f,-55.964f,-50.850f,-49.317f,-47.326f,-45.511f,-45.336f, --43.147f,-42.890f,-39.879f,-38.027f,-35.719f,-37.709f,-40.547f,-40.391f,-39.579f,-34.912f, --34.626f,-34.114f,-30.492f,-29.264f,-27.563f,-25.127f,-22.698f,-19.590f,-16.635f,-15.145f, --14.577f,-13.798f,-12.869f,-12.768f,-10.114f, -9.088f, -7.998f, -6.785f, -5.063f, -1.554f, - 2.188f, 5.386f, 4.974f, 6.768f, 9.465f, 12.121f, 13.102f, 12.827f, 13.213f, 13.172f, - 13.606f -},{ --29.534f,-28.985f,-27.773f,-26.078f,-23.888f,-21.250f,-18.805f,-17.021f,-14.735f,-12.512f, --11.679f,-11.605f,-11.617f,-10.237f, -9.017f, -7.987f, -6.957f, -5.008f, -4.554f, -4.786f, - -2.428f, 0.210f, 1.033f, -1.169f, -2.843f, 0.421f, 0.019f, -2.935f, -3.175f, -2.026f, - -0.956f, 0.370f, 1.028f, 2.228f, 2.780f, 2.458f, 2.835f, 2.778f, 2.100f, 1.568f, - 0.999f, 0.193f, -0.881f, -2.452f, -4.362f, -6.159f, -8.173f,-10.545f,-12.700f,-14.928f, --17.539f,-19.991f,-22.422f,-24.999f,-27.196f,-29.269f,-31.085f,-33.396f,-32.235f,-34.379f, --35.565f,-35.893f,-37.001f,-39.999f,-41.574f,-43.068f,-44.599f,-45.956f,-47.192f,-47.821f, --47.748f,-47.303f,-46.571f,-45.606f,-44.754f,-43.288f,-41.467f,-39.858f,-37.874f,-36.695f, --35.436f,-32.338f,-30.412f,-28.999f,-27.070f,-24.154f,-21.754f,-21.444f,-24.639f,-22.571f, --19.016f,-18.904f,-21.020f,-19.321f,-20.083f,-20.949f,-23.338f,-25.321f,-27.193f,-29.294f, --31.694f,-33.746f,-35.970f,-38.292f,-38.144f,-38.873f,-39.928f,-41.133f,-41.563f,-41.484f, --41.573f,-41.746f,-41.951f,-42.592f,-42.816f,-41.328f,-42.043f,-43.708f,-39.965f,-36.733f, --35.142f,-35.716f,-36.590f,-37.431f,-38.524f,-41.005f,-47.401f,-50.054f,-46.550f,-46.408f, --56.990f,-56.336f,-55.846f,-56.153f,-54.463f,-49.210f,-49.435f,-45.696f,-44.357f,-44.613f, --42.644f,-41.523f,-38.895f,-37.126f,-36.123f,-38.064f,-41.068f,-40.278f,-39.577f,-35.505f, --34.429f,-34.202f,-31.112f,-29.376f,-27.748f,-24.601f,-22.534f,-19.122f,-16.445f,-15.404f, --14.592f,-13.426f,-12.722f,-12.602f,-10.693f, -9.219f, -8.019f, -6.964f, -5.252f, -1.612f, - 2.226f, 5.257f, 4.626f, 6.740f, 9.387f, 12.155f, 13.024f, 12.697f, 13.175f, 13.139f, - 13.606f -},{ --29.534f,-29.017f,-27.885f,-26.303f,-24.182f,-21.591f,-19.323f,-17.750f,-15.625f,-13.566f, --12.639f,-12.357f,-12.846f,-11.960f,-10.294f, -9.127f, -8.211f, -6.878f, -6.152f, -5.860f, - -4.111f, -2.496f, -1.543f, -2.104f, -2.271f, -0.567f, -0.337f, -4.468f, -4.741f, -3.744f, - -2.225f, -0.864f, -0.174f, 0.684f, 1.278f, 1.590f, 1.273f, 1.438f, 0.812f, 0.096f, - -0.558f, -1.562f, -2.601f, -4.027f, -5.938f, -7.973f, -9.774f,-12.133f,-14.494f,-16.847f, --19.253f,-21.759f,-24.165f,-26.406f,-28.470f,-30.405f,-32.139f,-34.070f,-33.756f,-35.563f, --36.500f,-36.639f,-37.682f,-39.846f,-41.244f,-42.565f,-43.990f,-45.324f,-46.527f,-47.231f, --47.212f,-46.404f,-45.314f,-44.186f,-43.074f,-41.479f,-40.498f,-38.026f,-36.004f,-33.352f, --31.967f,-29.510f,-26.286f,-23.329f,-21.479f,-19.172f,-18.623f,-22.610f,-17.362f,-16.648f, --12.513f,-11.930f,-10.454f,-12.209f,-15.450f,-17.239f,-18.852f,-21.067f,-22.776f,-25.073f, --28.006f,-30.225f,-32.348f,-33.958f,-35.033f,-35.976f,-36.752f,-38.152f,-39.291f,-39.341f, --39.250f,-39.446f,-40.005f,-40.911f,-40.611f,-40.017f,-39.217f,-39.586f,-36.802f,-34.035f, --33.885f,-33.985f,-34.462f,-35.768f,-37.724f,-39.731f,-43.953f,-47.384f,-45.401f,-48.352f, --56.961f,-55.645f,-55.895f,-55.314f,-53.319f,-48.987f,-49.145f,-44.976f,-43.831f,-43.507f, --42.289f,-40.099f,-37.628f,-36.342f,-37.437f,-39.628f,-40.661f,-40.180f,-39.540f,-36.080f, --34.176f,-33.623f,-31.170f,-29.917f,-28.082f,-23.850f,-22.143f,-19.302f,-16.268f,-15.697f, --14.797f,-13.029f,-12.534f,-12.152f,-11.098f, -9.333f, -7.918f, -7.148f, -5.290f, -1.533f, - 2.329f, 5.181f, 4.556f, 6.679f, 9.320f, 12.139f, 12.927f, 12.565f, 13.134f, 13.107f, - 13.606f -},{ --29.534f,-29.049f,-27.996f,-26.534f,-24.489f,-21.952f,-19.877f,-18.439f,-16.455f,-14.550f, --13.682f,-13.369f,-14.048f,-14.056f,-11.624f,-10.604f, -9.383f, -8.206f, -7.598f, -7.256f, - -5.931f, -4.728f, -3.376f, -2.699f, -1.440f, -1.012f, -1.750f, -5.836f, -6.210f, -5.179f, - -3.480f, -1.910f, -1.264f, -0.741f, 0.001f, 0.291f, 0.065f, -0.043f, -0.571f, -1.337f, - -2.186f, -2.884f, -4.241f, -5.691f, -7.475f, -9.424f,-11.698f,-13.930f,-16.107f,-18.557f, --21.037f,-23.362f,-25.662f,-27.853f,-29.752f,-31.545f,-32.950f,-35.036f,-34.627f,-36.906f, --37.669f,-38.261f,-39.388f,-39.784f,-39.026f,-41.687f,-42.964f,-44.005f,-45.070f,-45.597f, --46.072f,-45.381f,-43.794f,-42.131f,-40.499f,-39.592f,-37.892f,-36.574f,-33.436f,-28.624f, --26.696f,-25.350f,-22.660f,-18.388f,-16.738f,-18.756f,-18.736f,-15.032f,-15.937f,-11.869f, - -7.164f, -6.713f, -6.779f, -8.616f,-10.514f,-12.602f,-14.787f,-16.730f,-18.779f,-21.905f, --25.356f,-27.666f,-29.490f,-31.763f,-33.153f,-34.152f,-35.141f,-36.560f,-37.238f,-37.499f, --37.448f,-37.267f,-37.901f,-38.670f,-38.851f,-38.927f,-37.869f,-36.248f,-33.506f,-31.976f, --31.653f,-32.061f,-33.683f,-34.535f,-36.364f,-39.783f,-45.708f,-45.848f,-44.247f,-51.897f, --55.322f,-55.625f,-55.417f,-53.369f,-52.005f,-49.338f,-47.841f,-44.478f,-43.509f,-43.362f, --41.668f,-39.569f,-36.815f,-36.236f,-39.183f,-40.230f,-40.260f,-39.020f,-38.734f,-36.181f, --34.245f,-32.926f,-31.189f,-30.141f,-28.782f,-23.926f,-22.068f,-19.930f,-16.496f,-16.892f, --15.010f,-12.318f,-12.421f,-11.763f,-11.309f, -9.290f, -7.880f, -7.115f, -5.014f, -1.243f, - 2.463f, 5.160f, 4.670f, 6.600f, 9.285f, 12.068f, 12.807f, 12.432f, 13.087f, 13.075f, - 13.606f -},{ --29.534f,-29.082f,-28.105f,-26.772f,-24.808f,-22.332f,-20.445f,-19.099f,-17.207f,-15.425f, --14.784f,-14.643f,-15.284f,-16.109f,-13.014f,-12.222f,-10.764f, -9.481f, -9.170f, -8.847f, - -7.434f, -6.247f, -4.917f, -3.180f, -2.006f, -1.737f, -4.371f, -7.229f, -7.134f, -6.017f, - -4.385f, -2.994f, -2.308f, -1.627f, -1.120f, -0.590f, -0.801f, -1.392f, -1.937f, -2.677f, - -3.619f, -4.513f, -5.608f, -7.348f, -9.182f,-10.881f,-13.140f,-15.922f,-18.059f,-20.181f, --22.609f,-24.922f,-27.182f,-29.318f,-31.152f,-32.754f,-34.873f,-36.540f,-35.821f,-37.067f, --38.185f,-38.627f,-38.993f,-39.074f,-39.847f,-40.875f,-41.804f,-42.723f,-43.562f,-44.312f, --43.960f,-43.534f,-42.569f,-41.829f,-39.761f,-36.924f,-34.574f,-31.366f,-28.257f,-25.930f, --23.151f,-20.644f,-18.726f,-16.848f,-16.668f,-14.938f,-10.372f, -9.765f, -3.401f, -0.385f, - -1.964f, -3.164f, -3.932f, -5.126f, -6.538f, -7.989f,-10.370f,-13.935f,-16.916f,-19.891f, --22.697f,-25.178f,-27.343f,-29.178f,-30.011f,-31.292f,-32.094f,-33.128f,-34.321f,-34.562f, --35.306f,-35.773f,-36.761f,-37.002f,-37.042f,-36.807f,-36.823f,-35.095f,-32.064f,-30.762f, --31.127f,-31.241f,-32.469f,-33.852f,-35.663f,-39.138f,-44.352f,-43.554f,-44.789f,-51.792f, --54.294f,-54.810f,-54.121f,-51.793f,-50.846f,-48.903f,-45.806f,-43.397f,-43.703f,-43.198f, --41.191f,-39.456f,-36.520f,-36.964f,-39.718f,-39.700f,-38.960f,-37.686f,-37.335f,-36.033f, --34.067f,-32.663f,-31.171f,-29.516f,-29.027f,-24.867f,-22.245f,-19.959f,-16.665f,-17.349f, --14.966f,-11.930f,-13.140f,-11.848f,-11.322f, -9.029f, -7.815f, -6.678f, -4.355f, -0.780f, - 2.552f, 5.103f, 4.816f, 6.530f, 9.299f, 11.947f, 12.660f, 12.304f, 13.033f, 13.045f, - 13.606f -},{ --29.534f,-29.116f,-28.213f,-27.015f,-25.141f,-22.726f,-20.998f,-19.740f,-17.897f,-16.225f, --15.878f,-15.984f,-16.704f,-17.730f,-14.564f,-13.595f,-12.300f,-11.231f,-10.837f,-10.100f, - -8.773f, -7.957f, -7.564f, -5.647f, -3.244f, -4.120f, -7.723f, -8.454f, -7.925f, -6.881f, - -5.479f, -4.286f, -3.547f, -2.843f, -2.244f, -2.214f, -2.271f, -2.592f, -3.269f, -3.929f, - -5.044f, -5.991f, -7.326f, -8.936f,-10.954f,-12.583f,-14.440f,-16.951f,-19.426f,-21.855f, --24.243f,-26.563f,-28.571f,-30.692f,-32.577f,-34.094f,-36.623f,-38.793f,-37.194f,-38.562f, --38.140f,-38.433f,-38.432f,-38.974f,-39.618f,-39.940f,-40.712f,-41.252f,-41.748f,-42.160f, --42.187f,-41.836f,-41.337f,-39.804f,-37.299f,-34.075f,-29.971f,-26.474f,-24.068f,-22.655f, --20.808f,-16.803f,-14.674f,-14.935f,-12.496f, -8.891f, -2.837f, 4.160f, 5.147f, 3.317f, - 1.980f, 1.433f, -0.163f, -1.066f, -2.178f, -3.173f, -7.428f,-11.618f,-14.271f,-16.869f, --19.424f,-21.993f,-23.817f,-25.302f,-26.585f,-29.043f,-30.512f,-31.592f,-32.481f,-33.413f, --33.711f,-34.090f,-34.274f,-34.785f,-35.525f,-34.720f,-35.594f,-34.668f,-32.953f,-32.393f, --32.222f,-30.976f,-32.114f,-34.049f,-35.706f,-37.924f,-42.555f,-43.201f,-46.203f,-51.532f, --52.731f,-52.883f,-52.691f,-49.998f,-49.440f,-47.337f,-44.577f,-43.756f,-43.926f,-42.482f, --40.899f,-38.447f,-37.888f,-37.889f,-38.905f,-38.653f,-38.136f,-36.570f,-36.243f,-35.511f, --33.495f,-32.365f,-30.621f,-29.387f,-28.645f,-25.148f,-21.991f,-18.991f,-16.376f,-16.463f, --14.906f,-12.350f,-14.193f,-12.381f,-11.006f, -8.803f, -7.546f, -5.939f, -3.474f, -0.270f, - 2.551f, 4.889f, 4.850f, 6.502f, 9.364f, 11.789f, 12.486f, 12.181f, 12.971f, 13.015f, - 13.606f -},{ --29.534f,-29.150f,-28.318f,-27.262f,-25.484f,-23.128f,-21.510f,-20.367f,-18.558f,-17.022f, --16.924f,-17.192f,-18.401f,-18.760f,-16.078f,-14.625f,-13.733f,-13.174f,-12.446f,-11.225f, --10.269f, -9.590f, -9.397f, -8.125f, -5.573f, -6.787f, -9.325f, -9.455f, -8.523f, -7.660f, - -6.735f, -5.574f, -4.834f, -4.206f, -3.803f, -3.449f, -3.536f, -4.140f, -4.542f, -5.364f, - -6.343f, -7.506f, -8.808f,-10.487f,-12.469f,-14.124f,-16.142f,-18.463f,-20.788f,-23.070f, --25.439f,-27.811f,-30.036f,-32.032f,-33.497f,-37.120f,-37.597f,-39.365f,-40.195f,-39.276f, --38.943f,-38.201f,-37.651f,-38.259f,-38.858f,-39.131f,-39.554f,-39.315f,-39.536f,-39.479f, --39.925f,-39.641f,-38.824f,-37.459f,-35.423f,-32.191f,-28.171f,-23.794f,-21.091f,-18.729f, --15.987f,-12.867f,-13.219f,-11.839f,-10.484f, -3.999f, 7.362f, 8.368f, 7.677f, 7.506f, - 6.350f, 4.482f, 3.779f, 2.027f, 0.725f, -1.237f, -5.238f, -8.569f,-10.771f,-13.149f, --15.734f,-17.992f,-19.907f,-22.218f,-24.179f,-26.994f,-29.583f,-29.650f,-31.907f,-30.570f, --31.367f,-32.454f,-32.666f,-32.788f,-33.170f,-32.686f,-32.704f,-34.453f,-34.666f,-37.849f, --41.015f,-32.766f,-31.435f,-32.769f,-35.664f,-38.362f,-43.336f,-43.047f,-48.993f,-50.900f, --49.922f,-50.310f,-50.144f,-48.813f,-47.001f,-46.974f,-44.723f,-43.530f,-43.188f,-41.501f, --40.380f,-38.307f,-38.010f,-37.865f,-37.834f,-36.836f,-36.582f,-35.920f,-34.815f,-33.967f, --32.914f,-31.381f,-30.238f,-29.846f,-27.999f,-23.958f,-21.239f,-18.312f,-16.028f,-15.690f, --14.633f,-12.793f,-14.274f,-12.942f,-10.527f, -8.908f, -7.096f, -5.239f, -2.676f, 0.163f, - 2.466f, 4.446f, 4.699f, 6.543f, 9.461f, 11.614f, 12.289f, 12.069f, 12.901f, 12.987f, - 13.606f -},{ --29.534f,-29.184f,-28.422f,-27.512f,-25.835f,-23.529f,-21.965f,-20.981f,-19.224f,-17.869f, --17.943f,-18.213f,-20.192f,-19.254f,-17.137f,-15.653f,-15.152f,-14.913f,-13.997f,-12.657f, --11.752f,-11.201f,-10.615f, -9.480f, -8.066f, -8.285f,-10.140f,-10.264f, -9.080f, -8.004f, - -7.371f, -6.813f, -5.882f, -5.482f, -5.015f, -4.963f, -4.834f, -5.170f, -5.908f, -6.809f, - -7.728f, -8.845f,-10.240f,-11.987f,-13.916f,-15.701f,-17.708f,-20.037f,-22.155f,-24.452f, --26.680f,-29.018f,-31.273f,-33.374f,-35.507f,-38.035f,-39.895f,-40.092f,-40.436f,-39.345f, --38.831f,-38.355f,-38.055f,-37.988f,-37.952f,-37.902f,-38.660f,-37.434f,-34.946f,-36.646f, --37.187f,-37.349f,-36.320f,-34.845f,-33.229f,-31.018f,-26.942f,-22.028f,-17.211f,-13.780f, --11.260f,-10.025f,-12.152f, -9.350f, -3.998f, 7.620f, 11.303f, 12.084f, 11.646f, 10.955f, - 10.414f, 8.552f, 7.551f, 5.488f, 2.903f, 0.499f, -3.097f, -5.412f, -7.083f, -9.402f, --12.188f,-14.798f,-17.232f,-19.700f,-21.367f,-24.488f,-26.825f,-27.129f,-29.982f,-29.038f, --29.683f,-31.107f,-30.396f,-31.217f,-31.687f,-30.965f,-30.882f,-32.166f,-37.263f,-42.559f, --43.693f,-40.560f,-34.876f,-34.149f,-36.421f,-38.886f,-42.258f,-43.552f,-46.919f,-48.222f, --47.233f,-48.031f,-48.087f,-45.887f,-45.812f,-45.765f,-44.101f,-43.199f,-42.590f,-41.037f, --39.978f,-37.811f,-39.147f,-37.146f,-35.609f,-35.260f,-35.646f,-35.327f,-33.530f,-32.351f, --32.061f,-30.524f,-29.799f,-29.637f,-27.156f,-22.647f,-20.701f,-18.449f,-16.088f,-15.428f, --13.722f,-12.558f,-13.369f,-13.151f,-10.363f, -9.190f, -6.644f, -4.806f, -2.158f, 0.479f, - 2.311f, 3.790f, 4.383f, 6.658f, 9.560f, 11.441f, 12.074f, 11.970f, 12.820f, 12.960f, - 13.606f -},{ --29.534f,-29.220f,-28.525f,-27.761f,-26.192f,-23.924f,-22.372f,-21.577f,-19.910f,-18.760f, --18.970f,-19.138f,-21.601f,-19.385f,-17.661f,-16.911f,-16.752f,-16.619f,-15.609f,-14.027f, --13.031f,-13.019f,-12.072f,-10.980f,-10.020f, -9.251f,-11.418f,-11.572f, -9.973f, -8.859f, - -7.926f, -7.597f, -6.943f, -6.593f, -6.179f, -6.062f, -6.089f, -6.443f, -7.032f, -8.019f, - -9.262f,-10.203f,-11.765f,-13.297f,-15.145f,-16.957f,-19.198f,-21.440f,-23.558f,-25.585f, --28.008f,-30.266f,-32.378f,-34.300f,-37.064f,-39.742f,-40.891f,-40.847f,-41.046f,-39.568f, --39.222f,-38.931f,-38.547f,-37.869f,-37.434f,-37.830f,-36.965f,-36.991f,-34.002f,-35.348f, --35.113f,-35.029f,-34.088f,-32.734f,-30.743f,-28.367f,-24.647f,-19.307f,-13.797f, -8.364f, - -6.048f, -9.393f,-11.687f, -6.018f, 7.611f, 13.225f, 14.182f, 14.803f, 15.268f, 15.029f, - 14.418f, 12.950f, 11.715f, 9.358f, 6.203f, 3.131f, 0.446f, -1.517f, -3.446f, -6.096f, - -9.052f,-11.924f,-14.073f,-16.084f,-18.078f,-21.198f,-23.453f,-24.596f,-24.756f,-26.914f, --28.058f,-29.378f,-30.018f,-30.102f,-31.709f,-31.800f,-31.042f,-31.076f,-37.037f,-41.823f, --42.342f,-42.709f,-40.917f,-38.067f,-37.978f,-39.465f,-40.034f,-42.068f,-44.619f,-45.095f, --44.625f,-45.663f,-45.806f,-43.775f,-44.058f,-43.640f,-42.469f,-42.238f,-41.351f,-40.403f, --39.806f,-38.313f,-39.964f,-35.881f,-33.971f,-34.486f,-34.278f,-34.821f,-33.651f,-31.778f, --31.123f,-29.963f,-29.484f,-29.113f,-26.474f,-22.040f,-20.446f,-18.576f,-16.493f,-15.221f, --12.615f,-11.841f,-12.377f,-12.810f,-10.604f, -9.138f, -6.264f, -4.538f, -1.866f, 0.710f, - 2.062f, 3.018f, 4.002f, 6.828f, 9.623f, 11.286f, 11.850f, 11.888f, 12.729f, 12.935f, - 13.606f -},{ --29.534f,-29.255f,-28.625f,-28.009f,-26.552f,-24.314f,-22.757f,-22.158f,-20.618f,-19.659f, --20.005f,-20.094f,-22.232f,-19.386f,-18.104f,-18.185f,-18.324f,-18.399f,-17.312f,-15.193f, --14.377f,-14.577f,-13.064f,-12.085f,-12.111f,-10.559f,-11.844f,-12.585f,-11.464f,-10.060f, - -8.876f, -8.383f, -8.068f, -7.622f, -7.407f, -7.134f, -7.252f, -7.791f, -8.458f, -9.414f, --10.398f,-11.728f,-13.091f,-14.667f,-16.406f,-18.534f,-20.629f,-22.709f,-25.027f,-26.968f, --29.177f,-31.313f,-33.225f,-34.836f,-38.144f,-40.493f,-40.943f,-40.395f,-40.389f,-40.296f, --39.556f,-39.001f,-38.905f,-38.008f,-36.997f,-37.076f,-37.099f,-36.280f,-35.739f,-34.874f, --33.837f,-33.098f,-31.923f,-30.561f,-28.185f,-24.649f,-20.610f,-16.572f,-12.734f, -7.986f, - -4.677f, -8.951f, -6.802f, 7.619f, 14.027f, 15.950f, 17.187f, 18.286f, 18.841f, 18.929f, - 18.051f, 16.916f, 15.413f, 13.346f, 10.218f, 7.622f, 5.730f, 3.146f, -0.020f, -2.904f, - -5.068f, -7.548f, -9.935f,-12.022f,-14.087f,-16.802f,-19.343f,-19.816f,-21.199f,-23.615f, --25.120f,-27.477f,-28.726f,-28.941f,-31.280f,-31.595f,-30.438f,-30.926f,-34.598f,-38.931f, --40.583f,-41.894f,-40.755f,-38.524f,-38.168f,-37.533f,-36.851f,-39.744f,-42.385f,-41.606f, --43.169f,-41.977f,-43.350f,-42.571f,-41.886f,-41.639f,-40.537f,-40.230f,-39.806f,-39.438f, --39.034f,-38.607f,-39.319f,-35.333f,-33.975f,-32.938f,-33.510f,-34.416f,-33.639f,-31.788f, --31.094f,-29.896f,-29.213f,-28.993f,-26.248f,-21.897f,-20.052f,-18.500f,-16.601f,-14.970f, --11.895f,-10.908f,-11.551f,-12.005f,-10.780f, -8.554f, -5.849f, -4.225f, -1.630f, 0.889f, - 1.668f, 2.251f, 3.682f, 7.003f, 9.620f, 11.159f, 11.624f, 11.824f, 12.627f, 12.912f, - 13.606f -},{ --29.534f,-29.291f,-28.724f,-28.254f,-26.913f,-24.704f,-23.161f,-22.734f,-21.345f,-20.544f, --21.011f,-21.150f,-22.198f,-19.511f,-18.932f,-19.337f,-19.699f,-20.014f,-18.920f,-16.627f, --15.807f,-15.862f,-14.267f,-13.303f,-13.583f,-11.930f,-13.174f,-13.336f,-13.211f,-11.440f, --10.063f, -9.388f, -9.185f, -8.875f, -8.757f, -8.509f, -8.581f, -9.041f, -9.779f,-10.719f, --11.744f,-12.874f,-14.484f,-15.969f,-17.670f,-19.878f,-22.020f,-24.079f,-26.051f,-28.242f, --30.185f,-32.143f,-33.847f,-35.520f,-38.806f,-40.499f,-40.490f,-40.043f,-40.629f,-40.326f, --39.447f,-39.087f,-38.852f,-37.792f,-37.149f,-37.115f,-34.962f,-33.784f,-32.976f,-32.964f, --32.297f,-31.151f,-29.724f,-27.835f,-25.246f,-21.674f,-17.385f,-12.792f, -9.300f, -7.320f, - -7.770f, -5.856f, 1.904f, 20.129f, 18.627f, 19.670f, 21.365f, 21.773f, 22.295f, 22.032f, - 22.043f, 21.201f, 19.845f, 17.857f, 14.981f, 11.861f, 9.515f, 6.924f, 4.218f, 1.524f, - -1.483f, -3.074f, -5.101f, -7.265f, -8.831f,-12.113f,-14.269f,-17.360f,-19.484f,-21.452f, --23.408f,-24.180f,-25.965f,-27.746f,-29.273f,-29.523f,-28.376f,-29.427f,-31.318f,-34.321f, --37.827f,-39.249f,-37.951f,-35.979f,-36.315f,-36.246f,-36.057f,-36.792f,-39.124f,-39.137f, --39.767f,-40.348f,-39.789f,-40.413f,-39.754f,-39.591f,-38.559f,-37.758f,-36.766f,-36.869f, --37.186f,-37.061f,-36.454f,-35.153f,-32.557f,-32.474f,-32.559f,-33.611f,-33.421f,-31.211f, --30.532f,-29.793f,-29.087f,-28.584f,-25.985f,-21.697f,-19.256f,-18.334f,-16.405f,-14.578f, --11.311f, -9.947f,-10.758f,-11.185f,-10.559f, -7.793f, -5.288f, -3.883f, -1.387f, 0.984f, - 1.119f, 1.594f, 3.520f, 7.126f, 9.541f, 11.062f, 11.406f, 11.779f, 12.515f, 12.890f, - 13.606f -},{ --29.534f,-29.327f,-28.822f,-28.492f,-27.273f,-25.102f,-23.625f,-23.325f,-22.097f,-21.447f, --21.970f,-22.282f,-22.130f,-19.996f,-20.123f,-20.714f,-21.321f,-21.683f,-20.372f,-18.069f, --16.805f,-16.858f,-15.532f,-15.147f,-14.361f,-13.140f,-15.562f,-14.525f,-13.964f,-12.622f, --11.158f,-10.659f,-10.166f, -9.901f, -9.735f, -9.804f, -9.842f,-10.264f,-11.018f,-11.973f, --13.052f,-14.127f,-15.598f,-17.395f,-19.030f,-21.034f,-23.318f,-25.216f,-27.403f,-29.238f, --31.083f,-32.863f,-34.121f,-36.627f,-39.371f,-40.097f,-39.729f,-40.628f,-40.673f,-40.187f, --39.922f,-39.404f,-39.452f,-37.887f,-37.687f,-35.356f,-32.379f,-31.820f,-31.114f,-31.257f, --30.054f,-29.096f,-27.308f,-25.046f,-21.993f,-18.374f,-14.426f, -9.525f, -6.512f, -5.275f, - -6.581f, -2.772f, 12.361f, 21.680f, 21.157f, 22.874f, 23.886f, 25.062f, 25.654f, 26.036f, - 26.013f, 25.156f, 23.070f, 21.383f, 18.955f, 16.684f, 14.236f, 10.941f, 7.779f, 6.156f, - 2.760f, 1.067f, 1.192f, -2.300f, -4.468f, -7.348f,-11.745f,-14.519f,-16.043f,-17.835f, --20.635f,-21.799f,-23.015f,-25.512f,-26.711f,-27.152f,-26.480f,-26.945f,-28.445f,-30.438f, --32.462f,-35.125f,-33.932f,-33.981f,-34.954f,-35.380f,-33.942f,-33.777f,-35.713f,-35.749f, --36.301f,-37.970f,-36.179f,-37.948f,-37.316f,-37.015f,-36.388f,-35.472f,-34.393f,-33.769f, --34.263f,-34.455f,-34.272f,-34.227f,-32.071f,-31.568f,-32.185f,-33.233f,-32.818f,-30.589f, --29.414f,-29.041f,-28.990f,-27.786f,-25.231f,-20.881f,-18.121f,-17.904f,-16.551f,-14.051f, --10.346f, -9.239f,-10.183f,-10.723f,-10.110f, -7.210f, -4.637f, -3.703f, -1.239f, 0.898f, - 0.494f, 1.103f, 3.541f, 7.150f, 9.403f, 10.989f, 11.204f, 11.751f, 12.392f, 12.871f, - 13.606f -},{ --29.534f,-29.364f,-28.917f,-28.723f,-27.631f,-25.521f,-24.176f,-23.950f,-22.890f,-22.435f, --22.934f,-23.418f,-22.650f,-20.997f,-21.394f,-22.571f,-23.556f,-23.969f,-22.079f,-19.020f, --17.521f,-17.624f,-16.621f,-16.550f,-14.910f,-15.107f,-17.655f,-16.047f,-14.834f,-13.555f, --12.338f,-11.911f,-11.487f,-11.165f,-10.795f,-10.928f,-11.138f,-11.503f,-12.128f,-12.946f, --14.149f,-15.400f,-16.944f,-18.614f,-20.502f,-22.456f,-24.456f,-26.369f,-28.423f,-30.390f, --31.967f,-33.418f,-34.367f,-37.390f,-39.850f,-39.987f,-39.512f,-39.898f,-40.106f,-40.095f, --39.921f,-39.646f,-39.121f,-38.136f,-36.609f,-33.988f,-32.370f,-31.487f,-30.994f,-29.602f, --27.664f,-26.757f,-25.100f,-22.494f,-19.437f,-15.270f, -9.412f, -5.591f, -2.915f, -2.442f, - -3.742f, 1.020f, 19.057f, 22.256f, 23.896f, 25.614f, 26.960f, 28.112f, 29.281f, 30.053f, - 30.414f, 28.755f, 26.490f, 24.221f, 21.912f, 19.636f, 17.300f, 14.986f, 12.506f, 10.354f, - 7.962f, 5.647f, 4.184f, 1.242f, -2.050f, -5.427f, -9.048f,-10.533f,-12.626f,-13.898f, --16.623f,-18.849f,-20.234f,-22.356f,-23.742f,-24.505f,-23.910f,-24.286f,-25.245f,-27.431f, --27.322f,-29.411f,-28.623f,-31.388f,-33.186f,-33.502f,-31.353f,-31.371f,-32.186f,-32.032f, --32.062f,-33.170f,-32.727f,-34.398f,-35.093f,-34.296f,-33.858f,-33.068f,-32.338f,-31.944f, --32.193f,-31.908f,-31.887f,-31.236f,-32.877f,-32.303f,-28.789f,-29.788f,-31.615f,-29.651f, --28.314f,-28.496f,-27.869f,-26.492f,-23.962f,-19.927f,-17.400f,-17.384f,-16.489f,-13.575f, - -9.317f, -8.902f,-10.024f,-10.533f, -9.694f, -6.738f, -4.075f, -3.688f, -1.296f, 0.530f, - -0.063f, 0.788f, 3.698f, 7.063f, 9.250f, 10.928f, 11.024f, 11.739f, 12.261f, 12.853f, - 13.606f -},{ --29.534f,-29.401f,-29.011f,-28.946f,-27.988f,-25.969f,-24.822f,-24.622f,-23.737f,-23.552f, --23.998f,-24.499f,-23.823f,-22.489f,-22.748f,-24.520f,-25.864f,-26.558f,-24.226f,-20.047f, --18.279f,-18.392f,-18.010f,-17.716f,-15.249f,-17.216f,-19.295f,-17.850f,-16.162f,-14.709f, --13.579f,-13.001f,-12.690f,-12.432f,-12.153f,-12.082f,-12.160f,-12.675f,-13.320f,-14.108f, --15.248f,-16.621f,-18.024f,-19.646f,-21.405f,-23.486f,-25.467f,-27.443f,-29.220f,-31.040f, --32.551f,-33.756f,-34.888f,-37.656f,-39.970f,-38.893f,-36.850f,-37.750f,-39.305f,-39.783f, --39.551f,-39.257f,-38.102f,-37.224f,-34.763f,-33.560f,-33.132f,-32.224f,-30.688f,-28.152f, --25.772f,-23.693f,-22.000f,-20.096f,-17.512f,-14.067f, -9.586f, -4.376f, 0.377f, -0.161f, - -2.172f, 7.220f, 23.520f, 24.376f, 26.294f, 27.840f, 29.368f, 31.392f, 32.590f, 33.751f, - 33.904f, 32.824f, 29.999f, 27.503f, 25.245f, 22.852f, 21.199f, 17.674f, 16.293f, 13.060f, - 10.843f, 8.636f, 5.960f, 3.443f, -0.473f, -2.657f, -6.312f, -7.635f, -8.483f,-10.467f, --12.674f,-14.684f,-17.398f,-18.751f,-20.179f,-21.409f,-20.716f,-21.607f,-22.510f,-23.731f, --23.688f,-24.386f,-26.251f,-28.410f,-28.295f,-31.517f,-28.832f,-29.851f,-29.788f,-28.467f, --28.800f,-27.841f,-29.346f,-31.277f,-32.127f,-31.935f,-31.536f,-31.007f,-30.491f,-29.776f, --29.537f,-29.477f,-29.605f,-29.142f,-31.154f,-29.784f,-28.000f,-26.610f,-29.016f,-28.546f, --27.674f,-27.265f,-26.561f,-25.129f,-22.617f,-19.136f,-17.047f,-17.036f,-15.764f,-13.300f, - -9.214f, -9.026f,-10.181f,-10.394f, -9.348f, -6.234f, -3.732f, -3.528f, -1.518f, -0.158f, - -0.449f, 0.629f, 3.901f, 6.895f, 9.135f, 10.861f, 10.870f, 11.738f, 12.122f, 12.838f, - 13.606f -},{ --29.534f,-29.437f,-29.104f,-29.158f,-28.342f,-26.454f,-25.544f,-25.342f,-24.631f,-24.768f, --25.214f,-25.518f,-25.191f,-24.220f,-24.442f,-26.072f,-27.422f,-28.286f,-26.022f,-21.678f, --18.641f,-18.630f,-18.370f,-18.332f,-16.236f,-18.461f,-19.984f,-19.538f,-17.549f,-16.003f, --14.696f,-14.139f,-13.813f,-13.647f,-13.487f,-13.398f,-13.554f,-13.758f,-14.438f,-15.300f, --16.386f,-17.658f,-19.100f,-20.618f,-22.397f,-24.292f,-26.239f,-28.217f,-30.074f,-31.754f, --33.168f,-34.385f,-35.452f,-38.600f,-39.864f,-38.224f,-36.341f,-37.951f,-39.092f,-39.259f, --38.619f,-37.819f,-36.806f,-34.428f,-31.469f,-30.080f,-30.402f,-30.748f,-28.850f,-26.905f, --23.887f,-22.174f,-19.384f,-17.263f,-14.808f,-12.069f, -7.682f, -2.584f, 3.293f, 2.693f, - 0.856f, 11.403f, 25.340f, 24.987f, 28.397f, 30.460f, 31.965f, 33.964f, 35.619f, 36.931f, - 37.184f, 36.720f, 34.325f, 31.103f, 28.843f, 26.792f, 24.124f, 21.764f, 20.310f, 17.714f, - 14.662f, 11.932f, 8.640f, 6.204f, 3.311f, 1.521f, -1.119f, -4.829f, -6.365f, -6.918f, - -9.310f,-10.715f,-13.591f,-14.882f,-16.648f,-17.422f,-18.524f,-19.476f,-20.340f,-21.369f, --22.146f,-22.513f,-23.843f,-25.906f,-25.074f,-27.118f,-26.324f,-24.801f,-25.047f,-25.220f, --25.060f,-23.983f,-26.288f,-28.047f,-28.427f,-28.734f,-28.342f,-28.338f,-28.056f,-27.586f, --27.261f,-27.485f,-27.446f,-26.737f,-27.403f,-26.304f,-26.965f,-24.432f,-26.560f,-27.871f, --27.536f,-26.231f,-25.328f,-24.313f,-21.517f,-18.281f,-16.263f,-16.455f,-15.205f,-12.968f, --10.057f, -9.596f,-10.306f,-10.247f, -9.017f, -5.845f, -3.546f, -2.975f, -1.740f, -1.088f, - -0.669f, 0.593f, 4.065f, 6.712f, 9.108f, 10.774f, 10.746f, 11.741f, 11.978f, 12.826f, - 13.606f -},{ --29.534f,-29.474f,-29.194f,-29.360f,-28.695f,-26.976f,-26.307f,-26.098f,-25.543f,-25.981f, --26.519f,-26.530f,-26.337f,-25.862f,-26.418f,-27.330f,-28.175f,-28.664f,-26.757f,-23.508f, --19.380f,-18.776f,-17.884f,-17.908f,-17.592f,-19.057f,-20.640f,-20.764f,-19.075f,-17.300f, --15.952f,-15.323f,-14.969f,-14.915f,-14.736f,-14.715f,-14.820f,-15.147f,-15.554f,-16.349f, --17.417f,-18.658f,-20.007f,-21.492f,-23.293f,-25.210f,-27.202f,-28.870f,-30.647f,-32.308f, --33.671f,-34.914f,-36.152f,-38.679f,-40.603f,-38.649f,-37.126f,-38.555f,-39.113f,-38.355f, --37.187f,-36.453f,-33.667f,-30.094f,-26.687f,-24.930f,-24.986f,-26.577f,-26.551f,-23.944f, --22.191f,-20.465f,-17.100f,-14.337f,-11.377f, -8.020f, -4.422f, 0.615f, 5.655f, 4.979f, - 4.806f, 15.538f, 26.548f, 27.910f, 31.102f, 32.988f, 35.317f, 37.544f, 39.378f, 41.254f, - 40.794f, 40.681f, 38.076f, 34.751f, 32.756f, 31.108f, 28.497f, 26.055f, 24.852f, 22.610f, - 19.156f, 16.218f, 13.435f, 10.641f, 8.397f, 5.876f, 3.717f, 0.587f, -3.548f, -3.850f, - -5.892f, -7.977f, -9.540f,-11.631f,-13.258f,-13.976f,-16.081f,-17.710f,-19.120f,-20.434f, --22.107f,-22.382f,-23.509f,-23.373f,-22.897f,-22.385f,-21.623f,-20.671f,-19.565f,-19.237f, --19.705f,-20.619f,-22.666f,-24.955f,-25.465f,-25.595f,-25.440f,-25.517f,-25.740f,-25.259f, --25.376f,-25.353f,-24.747f,-24.772f,-23.693f,-24.748f,-25.769f,-23.534f,-24.095f,-27.370f, --27.699f,-26.020f,-24.612f,-23.674f,-20.655f,-17.586f,-15.560f,-15.422f,-14.963f,-12.317f, --10.791f,-10.173f,-10.094f,-10.015f, -8.653f, -5.719f, -3.330f, -2.254f, -1.817f, -2.053f, - -0.810f, 0.654f, 4.146f, 6.597f, 9.197f, 10.652f, 10.651f, 11.742f, 11.833f, 12.815f, - 13.606f -},{ --29.534f,-29.511f,-29.283f,-29.551f,-29.046f,-27.533f,-27.071f,-26.872f,-26.435f,-27.081f, --27.768f,-27.605f,-27.325f,-27.287f,-28.169f,-28.633f,-28.687f,-28.493f,-27.041f,-25.066f, --21.698f,-20.145f,-18.059f,-17.493f,-18.949f,-19.314f,-21.763f,-21.854f,-20.665f,-18.702f, --17.094f,-16.486f,-16.171f,-16.057f,-15.923f,-15.827f,-16.007f,-16.265f,-16.843f,-17.420f, --18.324f,-19.450f,-20.916f,-22.358f,-24.112f,-25.968f,-27.698f,-29.362f,-31.014f,-32.695f, --33.926f,-35.212f,-36.256f,-39.004f,-40.615f,-40.078f,-38.134f,-38.227f,-38.281f,-37.481f, --36.208f,-33.612f,-28.901f,-25.989f,-23.834f,-21.998f,-20.904f,-21.314f,-22.105f,-21.917f, --18.734f,-16.581f,-14.122f,-10.313f, -8.927f, -5.196f, -0.509f, 2.950f, 7.134f, 4.606f, - 9.709f, 20.761f, 30.445f, 31.081f, 33.957f, 36.105f, 38.694f, 40.600f, 42.422f, 45.283f, - 45.363f, 44.526f, 41.257f, 39.681f, 36.528f, 34.387f, 31.255f, 31.034f, 28.884f, 26.341f, - 24.161f, 20.371f, 17.514f, 15.101f, 12.485f, 9.406f, 7.226f, 4.371f, 0.835f, 0.127f, - -1.877f, -4.205f, -5.743f, -7.715f, -9.984f,-10.748f,-12.855f,-14.906f,-16.404f,-17.689f, --19.020f,-19.524f,-20.720f,-20.737f,-20.682f,-20.737f,-17.143f,-16.406f,-16.696f,-16.443f, --16.085f,-16.777f,-19.127f,-21.659f,-22.330f,-22.088f,-22.150f,-22.708f,-23.324f,-23.205f, --23.151f,-23.478f,-23.237f,-22.815f,-22.350f,-22.629f,-23.623f,-22.794f,-21.607f,-25.430f, --27.821f,-25.798f,-24.417f,-22.946f,-19.971f,-17.084f,-15.357f,-14.514f,-14.619f,-12.024f, --11.124f,-10.366f, -9.742f, -9.612f, -8.216f, -5.668f, -3.013f, -1.874f, -1.726f, -2.785f, - -0.938f, 0.796f, 4.157f, 6.610f, 9.391f, 10.486f, 10.586f, 11.731f, 11.687f, 12.808f, - 13.606f -},{ --29.534f,-29.548f,-29.369f,-29.731f,-29.395f,-28.115f,-27.804f,-27.646f,-27.283f,-28.017f, --28.834f,-28.760f,-28.515f,-28.655f,-29.377f,-29.918f,-29.364f,-28.785f,-27.778f,-26.094f, --23.851f,-22.089f,-19.212f,-18.452f,-20.825f,-19.717f,-22.258f,-22.737f,-21.983f,-19.942f, --18.363f,-17.560f,-17.274f,-17.051f,-17.022f,-17.024f,-17.201f,-17.452f,-17.829f,-18.356f, --19.226f,-20.312f,-21.735f,-23.380f,-24.939f,-26.539f,-28.167f,-29.798f,-31.230f,-32.712f, --34.173f,-35.362f,-36.474f,-38.876f,-40.127f,-38.113f,-35.634f,-35.786f,-36.104f,-35.569f, --32.685f,-28.097f,-24.116f,-23.006f,-22.459f,-21.131f,-18.891f,-16.382f,-15.200f,-17.952f, --17.091f,-14.534f,-11.650f, -8.686f, -7.834f, -2.641f, 1.010f, 4.927f, 7.826f, 4.318f, - 10.214f, 24.158f, 33.203f, 33.550f, 37.091f, 39.504f, 41.982f, 43.132f, 45.144f, 48.242f, - 50.179f, 49.606f, 45.141f, 44.907f, 42.493f, 39.233f, 34.888f, 33.319f, 33.401f, 30.803f, - 28.674f, 25.159f, 22.342f, 19.191f, 16.587f, 13.667f, 13.080f, 7.915f, 4.901f, 3.546f, - 1.801f, -0.896f, -2.269f, -4.052f, -6.069f, -7.472f, -8.657f,-10.829f,-12.169f,-13.229f, --14.930f,-15.776f,-17.101f,-17.938f,-18.601f,-18.991f,-16.510f,-15.599f,-15.615f,-14.017f, --13.175f,-13.779f,-15.585f,-17.660f,-18.422f,-18.123f,-18.838f,-19.934f,-20.748f,-21.033f, --21.006f,-21.306f,-21.005f,-20.468f,-20.681f,-20.437f,-21.774f,-21.345f,-20.345f,-22.665f, --27.412f,-26.264f,-24.151f,-22.260f,-19.649f,-17.235f,-15.222f,-13.924f,-14.107f,-12.349f, --11.402f,-10.225f, -9.637f, -9.187f, -7.750f, -5.452f, -2.773f, -2.028f, -1.566f, -3.087f, - -1.036f, 1.002f, 4.149f, 6.768f, 9.644f, 10.277f, 10.547f, 11.702f, 11.547f, 12.803f, - 13.606f -},{ --29.534f,-29.584f,-29.454f,-29.901f,-29.740f,-28.711f,-28.491f,-28.411f,-28.094f,-28.830f, --29.703f,-29.928f,-30.034f,-30.159f,-30.385f,-30.967f,-30.228f,-29.652f,-28.800f,-26.612f, --24.262f,-23.327f,-21.711f,-21.647f,-22.080f,-20.094f,-22.243f,-23.374f,-23.020f,-21.173f, --19.630f,-18.745f,-18.348f,-18.175f,-18.079f,-17.947f,-18.156f,-18.443f,-18.817f,-19.415f, --20.084f,-21.170f,-22.377f,-23.859f,-25.507f,-27.126f,-28.679f,-30.063f,-31.513f,-32.969f, --34.106f,-35.328f,-36.653f,-38.504f,-39.493f,-34.807f,-32.519f,-33.094f,-34.522f,-31.425f, --29.165f,-26.281f,-21.458f,-20.305f,-19.473f,-18.287f,-16.170f,-13.090f,-11.878f,-11.547f, --12.406f,-13.835f,-10.015f, -5.705f, -5.653f, -1.318f, 3.137f, 7.415f, 10.343f, 7.216f, - 11.007f, 27.485f, 33.992f, 36.847f, 39.933f, 42.651f, 43.891f, 45.119f, 47.592f, 50.195f, - 54.232f, 54.504f, 53.321f, 49.957f, 47.186f, 44.130f, 41.553f, 36.182f, 35.967f, 34.719f, - 32.467f, 30.259f, 26.834f, 23.808f, 21.075f, 18.009f, 16.279f, 12.329f, 9.283f, 6.744f, - 5.360f, 3.444f, 1.199f, -0.191f, -1.912f, -3.614f, -5.637f, -7.149f, -8.730f, -9.258f, --10.758f,-12.119f,-13.170f,-14.870f,-15.363f,-15.558f,-15.473f,-15.600f,-15.363f,-13.474f, --10.692f,-10.665f,-11.383f,-13.028f,-13.863f,-14.792f,-16.181f,-17.040f,-18.256f,-18.634f, --18.803f,-18.721f,-18.941f,-18.704f,-18.992f,-18.471f,-19.603f,-19.053f,-19.112f,-20.308f, --25.678f,-25.675f,-23.446f,-22.406f,-20.202f,-18.006f,-15.363f,-13.584f,-13.326f,-12.318f, --11.437f, -9.968f, -9.592f, -8.978f, -7.361f, -5.168f, -2.821f, -2.324f, -1.506f, -2.966f, - -1.028f, 1.243f, 4.168f, 7.029f, 9.880f, 10.031f, 10.528f, 11.647f, 11.414f, 12.801f, - 13.606f -},{ --29.534f,-29.621f,-29.537f,-30.060f,-30.079f,-29.309f,-29.137f,-29.161f,-28.901f,-29.604f, --30.470f,-31.011f,-31.582f,-31.739f,-31.708f,-31.943f,-31.133f,-30.521f,-29.656f,-27.216f, --24.779f,-24.164f,-23.886f,-24.713f,-22.511f,-20.685f,-22.965f,-24.219f,-24.095f,-22.240f, --20.702f,-19.747f,-19.196f,-19.042f,-18.892f,-18.941f,-19.017f,-19.197f,-19.387f,-20.057f, --20.776f,-21.565f,-22.991f,-24.597f,-25.884f,-27.312f,-28.772f,-30.353f,-31.650f,-32.793f, --34.197f,-35.299f,-36.300f,-38.283f,-38.458f,-33.102f,-30.618f,-30.416f,-31.414f,-30.299f, --27.495f,-23.436f,-20.353f,-17.952f,-17.492f,-15.962f,-12.847f,-10.374f, -8.570f, -8.551f, - -7.216f, -7.309f, -7.376f, -6.035f, -3.300f, 1.308f, 5.574f, 10.537f, 13.216f, 10.806f, - 13.714f, 30.686f, 33.469f, 39.470f, 42.250f, 45.070f, 48.119f, 50.100f, 51.129f, 53.740f, - 54.842f, 58.143f, 56.205f, 53.673f, 52.227f, 49.404f, 46.609f, 43.540f, 38.254f, 38.453f, - 36.634f, 34.878f, 30.672f, 28.028f, 25.511f, 22.651f, 19.750f, 16.425f, 13.368f, 10.496f, - 9.273f, 8.107f, 5.472f, 3.744f, 2.145f, 0.524f, -1.489f, -3.774f, -5.210f, -6.137f, - -7.067f, -7.792f, -9.240f,-11.015f,-11.316f,-11.191f,-11.595f,-12.261f,-12.513f,-12.244f, --10.045f, -8.243f, -7.496f, -8.360f,-10.218f,-12.127f,-13.483f,-14.796f,-15.627f,-16.064f, --16.455f,-16.307f,-16.329f,-17.003f,-17.134f,-16.588f,-17.816f,-17.112f,-17.010f,-19.101f, --22.986f,-24.061f,-21.780f,-22.797f,-20.460f,-18.224f,-15.696f,-13.326f,-12.407f,-11.848f, --11.145f, -9.779f, -9.258f, -8.953f, -7.058f, -5.032f, -3.067f, -2.220f, -1.699f, -2.634f, - -0.885f, 1.464f, 4.227f, 7.306f, 10.018f, 9.763f, 10.522f, 11.559f, 11.294f, 12.802f, - 13.606f -},{ --29.534f,-29.657f,-29.619f,-30.210f,-30.410f,-29.896f,-29.766f,-29.892f,-29.732f,-30.401f, --31.246f,-31.974f,-32.809f,-33.154f,-33.272f,-33.120f,-31.982f,-31.114f,-30.544f,-28.229f, --26.114f,-25.074f,-24.689f,-25.656f,-23.616f,-22.364f,-24.647f,-25.397f,-25.173f,-23.223f, --21.793f,-20.780f,-20.266f,-20.008f,-19.680f,-19.606f,-19.652f,-19.931f,-20.011f,-20.547f, --21.285f,-22.309f,-23.533f,-24.704f,-26.010f,-27.409f,-28.875f,-30.204f,-31.406f,-32.741f, --34.210f,-35.370f,-36.881f,-38.944f,-37.894f,-32.179f,-28.125f,-27.113f,-27.085f,-26.181f, --24.396f,-22.593f,-19.857f,-17.628f,-16.613f,-16.284f,-11.402f, -8.737f, -7.477f, -7.742f, - -6.219f, -3.547f, -5.022f, -3.526f, -0.966f, 3.531f, 7.714f, 12.252f, 14.930f, 13.390f, - 16.273f, 34.751f, 35.471f, 40.810f, 44.126f, 46.913f, 49.921f, 52.559f, 53.354f, 53.783f, - 54.745f, 57.704f, 57.832f, 56.617f, 55.528f, 54.423f, 53.092f, 48.284f, 45.877f, 42.261f, - 39.686f, 39.297f, 35.967f, 32.109f, 29.938f, 26.964f, 24.317f, 21.133f, 17.980f, 14.571f, - 13.242f, 12.443f, 10.243f, 7.775f, 6.108f, 5.016f, 3.069f, 0.662f, -1.217f, -2.310f, - -3.048f, -4.381f, -5.602f, -6.483f, -6.873f, -6.782f, -6.754f, -8.034f, -8.768f, -9.364f, - -8.466f, -6.575f, -4.932f, -4.342f, -6.106f, -8.439f,-10.635f,-11.877f,-12.666f,-13.399f, --13.628f,-13.585f,-13.970f,-14.886f,-14.955f,-14.707f,-14.554f,-14.580f,-15.549f,-18.788f, --20.236f,-21.408f,-19.634f,-21.904f,-19.804f,-17.951f,-15.497f,-12.716f,-11.613f,-11.571f, --10.776f, -9.629f, -8.913f, -8.856f, -6.777f, -4.953f, -3.144f, -1.609f, -2.166f, -2.366f, - -0.680f, 1.598f, 4.293f, 7.497f, 9.989f, 9.493f, 10.520f, 11.437f, 11.191f, 12.805f, - 13.606f -},{ --29.534f,-29.693f,-29.698f,-30.352f,-30.730f,-30.463f,-30.404f,-30.600f,-30.588f,-31.212f, --32.076f,-32.881f,-33.744f,-34.307f,-34.551f,-34.359f,-32.871f,-31.748f,-31.545f,-29.317f, --26.860f,-25.742f,-25.829f,-26.722f,-24.605f,-24.653f,-26.651f,-26.670f,-26.152f,-24.243f, --22.709f,-21.737f,-21.129f,-20.851f,-20.580f,-20.399f,-20.280f,-20.570f,-20.665f,-20.940f, --21.735f,-22.782f,-24.017f,-25.094f,-26.171f,-27.345f,-28.679f,-30.048f,-31.318f,-32.782f, --34.099f,-35.307f,-36.338f,-38.541f,-38.079f,-31.899f,-27.927f,-26.918f,-26.512f,-25.103f, --23.813f,-21.428f,-19.521f,-17.979f,-16.634f,-15.268f,-10.279f, -7.247f, -7.081f, -6.175f, - -2.822f, -0.304f, 0.293f, -0.496f, 2.136f, 6.447f, 10.386f, 14.510f, 17.190f, 15.738f, - 19.300f, 33.271f, 36.796f, 42.863f, 46.371f, 47.114f, 48.083f, 53.708f, 51.171f, 53.808f, - 52.813f, 57.685f, 57.086f, 54.819f, 55.448f, 57.107f, 53.021f, 51.525f, 50.348f, 48.832f, - 44.822f, 41.551f, 38.218f, 35.814f, 33.586f, 31.448f, 28.715f, 25.224f, 22.140f, 19.393f, - 16.598f, 15.311f, 13.961f, 13.076f, 9.712f, 8.932f, 7.289f, 4.777f, 3.218f, 1.871f, - 1.158f, -0.654f, -1.791f, -2.429f, -2.527f, -2.354f, -1.937f, -3.478f, -4.587f, -5.026f, - -4.390f, -3.120f, -2.370f, -2.189f, -3.561f, -4.999f, -7.318f, -8.291f, -9.360f,-10.460f, --10.953f,-11.018f,-11.603f,-12.471f,-12.778f,-12.649f,-11.390f,-12.986f,-15.905f,-18.664f, --19.024f,-19.373f,-19.420f,-19.685f,-18.951f,-17.522f,-14.939f,-12.185f,-11.103f,-11.175f, --10.263f, -9.275f, -8.924f, -8.539f, -6.516f, -4.641f, -2.847f, -0.860f, -2.715f, -2.293f, - -0.535f, 1.603f, 4.311f, 7.523f, 9.763f, 9.243f, 10.511f, 11.279f, 11.109f, 12.812f, - 13.606f -},{ --29.534f,-29.728f,-29.775f,-30.485f,-31.035f,-31.004f,-31.073f,-31.273f,-31.428f,-31.976f, --32.924f,-33.836f,-34.718f,-35.344f,-35.349f,-35.298f,-33.907f,-32.581f,-32.137f,-30.267f, --27.628f,-26.278f,-26.484f,-27.824f,-24.923f,-26.778f,-28.332f,-27.846f,-27.256f,-25.292f, --23.695f,-22.634f,-22.017f,-21.646f,-21.235f,-21.070f,-21.061f,-21.322f,-21.184f,-21.497f, --22.006f,-23.158f,-24.318f,-25.379f,-26.279f,-27.482f,-28.786f,-30.000f,-31.212f,-32.597f, --33.805f,-34.863f,-36.246f,-38.397f,-38.487f,-33.668f,-29.882f,-27.675f,-25.909f,-24.736f, --22.482f,-20.721f,-19.021f,-17.254f,-13.844f,-12.179f, -7.521f, -5.225f, -5.963f, -3.294f, - 0.652f, 3.647f, 5.690f, 7.180f, 8.077f, 9.770f, 14.334f, 18.198f, 20.578f, 17.591f, - 27.170f, 35.991f, 37.276f, 44.209f, 47.217f, 50.277f, 51.002f, 56.046f, 56.867f, 55.312f, - 53.638f, 55.995f, 53.885f, 54.624f, 56.882f, 59.152f, 56.383f, 53.399f, 51.643f, 48.990f, - 49.922f, 47.600f, 43.140f, 38.280f, 33.769f, 31.930f, 30.801f, 28.128f, 24.882f, 22.061f, - 20.100f, 17.927f, 17.282f, 16.274f, 14.150f, 12.350f, 10.356f, 9.379f, 7.445f, 5.641f, - 4.206f, 2.799f, 1.690f, 1.124f, 1.133f, 1.554f, 1.553f, 0.390f, -0.687f, -1.374f, - -0.752f, 0.653f, 0.036f, -0.702f, -1.565f, -1.770f, -3.076f, -4.346f, -5.680f, -6.922f, - -7.840f, -8.267f, -8.716f,-10.098f,-10.904f,-10.920f, -9.690f,-11.964f,-14.099f,-17.819f, --18.230f,-18.905f,-21.728f,-18.300f,-18.219f,-17.091f,-14.678f,-12.066f,-10.941f,-10.455f, - -9.515f, -8.694f, -9.043f, -8.112f, -6.276f, -4.064f, -2.388f, -0.329f, -3.039f, -2.338f, - -0.509f, 1.498f, 4.236f, 7.357f, 9.354f, 9.033f, 10.483f, 11.088f, 11.051f, 12.821f, - 13.606f -},{ --29.534f,-29.763f,-29.851f,-30.611f,-31.323f,-31.515f,-31.778f,-31.902f,-32.194f,-32.652f, --33.756f,-34.890f,-35.914f,-36.396f,-35.991f,-35.873f,-34.898f,-33.280f,-32.178f,-30.891f, --28.964f,-27.199f,-26.615f,-27.657f,-26.059f,-28.877f,-29.756f,-28.953f,-28.353f,-26.241f, --24.625f,-23.594f,-22.781f,-22.382f,-21.991f,-21.631f,-21.727f,-21.429f,-21.553f,-21.976f, --22.668f,-23.382f,-24.462f,-25.450f,-26.389f,-27.350f,-28.569f,-29.994f,-31.151f,-32.482f, --33.574f,-34.502f,-35.499f,-37.678f,-38.507f,-34.648f,-30.380f,-28.227f,-25.458f,-24.343f, --22.596f,-20.454f,-18.069f,-15.262f,-11.635f, -8.796f, -5.008f, -5.120f, -2.321f, 1.090f, - 4.407f, 7.754f, 8.468f, 12.246f, 13.906f, 15.436f, 19.364f, 23.024f, 23.389f, 22.827f, - 36.360f, 39.719f, 37.895f, 44.402f, 49.795f, 53.974f, 56.689f, 60.713f, 63.793f, 61.864f, - 58.348f, 56.354f, 54.462f, 56.886f, 58.526f, 61.821f, 59.608f, 55.120f, 53.832f, 54.269f, - 52.010f, 52.056f, 48.928f, 37.842f, 36.434f, 40.614f, 41.033f, 34.306f, 30.586f, 23.796f, - 21.269f, 18.538f, 18.852f, 18.608f, 17.438f, 14.959f, 13.099f, 11.711f, 10.040f, 8.408f, - 7.023f, 5.760f, 5.071f, 4.587f, 4.690f, 4.387f, 4.307f, 4.283f, 3.011f, 1.948f, - 2.711f, 2.802f, 2.366f, 1.283f, 0.312f, 0.371f, 0.116f, -0.638f, -1.872f, -3.361f, - -4.504f, -5.281f, -6.660f, -8.027f, -8.983f, -9.359f, -8.871f,-10.156f,-12.612f,-15.910f, --16.614f,-17.266f,-21.518f,-18.298f,-17.948f,-17.007f,-14.534f,-11.932f,-10.928f,-10.066f, - -8.772f, -8.081f, -8.870f, -7.726f, -5.969f, -3.511f, -2.104f, -0.048f, -2.960f, -2.346f, - -0.539f, 1.371f, 4.067f, 7.029f, 8.818f, 8.879f, 10.426f, 10.872f, 11.022f, 12.832f, - 13.606f -},{ --29.534f,-29.798f,-29.925f,-30.731f,-31.591f,-31.997f,-32.508f,-32.490f,-32.854f,-33.274f, --34.595f,-36.001f,-37.151f,-37.399f,-36.721f,-36.295f,-35.620f,-33.839f,-32.353f,-31.090f, --29.551f,-28.120f,-27.986f,-28.019f,-27.363f,-30.655f,-31.189f,-30.060f,-29.216f,-27.319f, --25.546f,-24.347f,-23.716f,-23.096f,-22.731f,-22.355f,-22.109f,-22.162f,-22.131f,-22.592f, --22.993f,-23.887f,-24.722f,-25.596f,-26.385f,-27.425f,-28.613f,-29.841f,-30.962f,-32.290f, --33.247f,-34.122f,-35.268f,-36.958f,-38.303f,-34.549f,-29.791f,-28.336f,-25.887f,-23.638f, --22.392f,-19.992f,-16.213f,-13.558f,-10.974f, -7.332f, -4.323f, -2.025f, 0.026f, 3.713f, - 8.487f, 10.297f, 11.538f, 15.765f, 19.845f, 21.324f, 21.649f, 25.657f, 24.985f, 27.071f, - 33.589f, 37.484f, 37.933f, 48.961f, 49.011f, 53.601f, 57.393f, 61.225f, 64.492f, 61.140f, - 61.248f, 64.002f, 58.716f, 59.202f, 61.194f, 61.879f, 66.521f, 58.542f, 56.199f, 55.266f, - 55.887f, 54.411f, 51.156f, 46.697f, 43.503f, 42.516f, 42.621f, 43.318f, 39.063f, 30.166f, - 22.427f, 20.733f, 21.698f, 26.463f, 24.261f, 17.954f, 16.376f, 14.887f, 13.465f, 11.505f, - 10.356f, 9.442f, 8.968f, 8.004f, 7.928f, 7.297f, 7.676f, 7.249f, 6.695f, 5.995f, - 4.529f, 4.734f, 4.280f, 3.452f, 2.325f, 1.939f, 2.135f, 1.643f, 1.515f, 0.408f, - -0.629f, -1.552f, -3.762f, -6.398f, -7.605f, -8.208f, -7.984f, -9.757f,-10.943f,-13.936f, --14.617f,-14.656f,-17.633f,-17.356f,-17.576f,-16.981f,-14.356f,-11.993f,-11.111f,-10.484f, - -8.418f, -7.508f, -8.352f, -7.362f, -5.587f, -3.231f, -2.014f, 0.102f, -2.590f, -2.266f, - -0.497f, 1.340f, 3.849f, 6.614f, 8.239f, 8.786f, 10.329f, 10.640f, 11.024f, 12.846f, - 13.606f -},{ --29.534f,-29.832f,-29.997f,-30.845f,-31.839f,-32.451f,-33.232f,-33.058f,-33.436f,-33.948f, --35.518f,-37.095f,-38.171f,-38.292f,-37.418f,-36.726f,-36.307f,-34.756f,-33.123f,-31.502f, --29.867f,-28.747f,-28.761f,-28.908f,-28.009f,-31.556f,-32.265f,-31.238f,-30.001f,-28.125f, --26.216f,-25.194f,-24.364f,-23.764f,-23.368f,-22.915f,-22.678f,-22.586f,-22.616f,-23.045f, --23.311f,-23.984f,-24.894f,-25.727f,-26.478f,-27.407f,-28.399f,-29.550f,-30.872f,-31.954f, --32.900f,-33.775f,-34.585f,-36.328f,-37.082f,-33.886f,-29.958f,-28.248f,-26.268f,-23.100f, --21.565f,-18.046f,-15.422f,-12.570f,-10.595f, -6.328f, -3.569f, -0.489f, 3.265f, 6.408f, - 9.455f, 11.422f, 14.178f, 19.355f, 22.443f, 25.630f, 26.951f, 29.028f, 29.507f, 28.989f, - 27.231f, 34.638f, 41.267f, 48.114f, 51.427f, 57.115f, 60.801f, 61.360f, 61.228f, 64.379f, - 63.128f, 64.533f, 58.998f, 61.830f, 63.428f, 63.829f, 65.250f, 67.063f, 59.613f, 52.945f, - 54.297f, 55.089f, 52.480f, 49.791f, 47.889f, 41.154f, 37.840f, 40.548f, 37.027f, 32.601f, - 30.723f, 27.500f, 23.402f, 19.619f, 15.414f, 19.787f, 19.136f, 17.443f, 16.360f, 14.985f, - 14.063f, 13.253f, 11.940f, 11.201f, 11.002f, 10.593f, 10.452f, 9.991f, 9.802f, 9.966f, - 8.405f, 6.959f, 6.005f, 5.458f, 4.352f, 4.087f, 3.757f, 3.634f, 3.054f, 3.268f, - 2.681f, 2.052f, -0.202f, -4.190f, -6.069f, -6.074f, -6.706f, -7.771f, -8.843f,-11.199f, --11.683f,-12.701f,-14.181f,-15.497f,-16.966f,-16.995f,-14.403f,-12.476f,-11.911f,-11.522f, - -8.628f, -7.050f, -7.609f, -6.987f, -5.260f, -3.168f, -1.841f, 0.107f, -2.203f, -2.207f, - -0.317f, 1.477f, 3.648f, 6.199f, 7.706f, 8.749f, 10.186f, 10.406f, 11.060f, 12.862f, - 13.606f -},{ --29.534f,-29.865f,-30.067f,-30.955f,-32.067f,-32.879f,-33.917f,-33.645f,-34.037f,-34.779f, --36.561f,-38.123f,-38.994f,-39.207f,-38.050f,-37.280f,-37.314f,-35.962f,-34.044f,-32.459f, --30.926f,-29.592f,-28.654f,-29.181f,-29.001f,-31.932f,-33.079f,-32.014f,-30.917f,-28.883f, --26.882f,-25.905f,-25.005f,-24.351f,-23.964f,-23.560f,-23.241f,-23.123f,-23.031f,-23.402f, --23.620f,-24.154f,-24.846f,-25.605f,-26.340f,-27.356f,-28.177f,-29.414f,-30.455f,-31.522f, --32.436f,-32.997f,-34.087f,-35.448f,-36.426f,-33.035f,-29.069f,-26.591f,-23.809f,-24.026f, --20.620f,-17.058f,-14.125f,-12.422f,-10.106f, -6.998f, -3.829f, 1.227f, 4.890f, 6.992f, - 9.698f, 13.432f, 17.480f, 21.931f, 24.825f, 28.139f, 29.352f, 32.432f, 34.984f, 29.966f, - 26.926f, 32.270f, 43.313f, 47.518f, 52.077f, 57.074f, 59.324f, 57.860f, 61.451f, 60.564f, - 56.136f, 63.179f, 60.424f, 64.867f, 65.911f, 65.904f, 65.849f, 66.460f, 67.233f, 60.356f, - 61.728f, 59.888f, 55.139f, 51.367f, 50.390f, 41.604f, 33.232f, 32.912f, 31.476f, 30.213f, - 27.974f, 25.901f, 24.078f, 16.777f, 17.619f, 21.980f, 22.074f, 20.629f, 19.604f, 18.731f, - 17.497f, 16.112f, 15.173f, 14.828f, 14.462f, 13.685f, 12.944f, 13.164f, 12.697f, 13.156f, - 11.325f, 10.018f, 8.425f, 7.647f, 6.656f, 5.624f, 5.369f, 4.855f, 4.955f, 4.560f, - 4.627f, 4.145f, 2.388f, -1.788f, -4.010f, -4.229f, -4.470f, -4.980f, -6.673f, -8.112f, - -9.531f,-11.397f,-12.461f,-14.288f,-16.323f,-17.012f,-14.589f,-13.340f,-13.506f,-12.715f, - -9.063f, -6.802f, -6.871f, -6.747f, -5.021f, -3.069f, -1.438f, -0.110f, -1.977f, -2.296f, - -0.064f, 1.759f, 3.512f, 5.853f, 7.292f, 8.751f, 9.997f, 10.186f, 11.132f, 12.881f, - 13.606f -},{ --29.534f,-29.898f,-30.136f,-31.060f,-32.275f,-33.283f,-34.528f,-34.296f,-34.784f,-35.793f, --37.646f,-39.066f,-39.842f,-40.242f,-38.885f,-38.134f,-38.478f,-36.873f,-34.706f,-33.263f, --31.743f,-30.422f,-29.395f,-29.668f,-29.991f,-32.357f,-33.925f,-32.472f,-31.796f,-29.628f, --27.603f,-26.534f,-25.694f,-25.060f,-24.537f,-24.129f,-23.841f,-23.655f,-23.615f,-23.593f, --23.728f,-24.196f,-24.818f,-25.387f,-26.100f,-26.987f,-27.753f,-28.791f,-29.886f,-30.990f, --31.830f,-32.523f,-33.494f,-34.595f,-35.587f,-32.996f,-27.202f,-25.565f,-24.174f,-21.342f, --20.387f,-16.777f,-13.566f,-10.837f, -8.183f, -6.319f, -3.052f, 1.609f, 4.504f, 7.617f, - 11.171f, 15.869f, 19.787f, 24.294f, 27.032f, 30.233f, 32.355f, 35.340f, 36.514f, 31.208f, - 33.261f, 37.336f, 45.255f, 48.612f, 54.592f, 55.795f, 55.996f, 57.871f, 61.181f, 50.058f, - 54.811f, 66.814f, 64.072f, 67.831f, 68.268f, 67.058f, 67.253f, 69.252f, 70.642f, 63.685f, - 64.799f, 61.835f, 58.447f, 53.136f, 52.478f, 44.059f, 41.375f, 39.762f, 35.516f, 33.263f, - 31.119f, 29.019f, 26.768f, 18.564f, 21.432f, 25.200f, 25.744f, 24.076f, 22.912f, 21.599f, - 20.599f, 19.035f, 17.973f, 17.676f, 17.916f, 17.113f, 15.883f, 15.757f, 15.309f, 14.957f, - 14.146f, 14.160f, 12.627f, 10.619f, 9.415f, 8.129f, 7.215f, 6.650f, 6.565f, 6.752f, - 6.554f, 5.990f, 4.479f, 0.194f, -1.669f, -1.775f, -1.881f, -3.791f, -4.830f, -6.330f, - -7.718f,-10.008f,-11.581f,-13.594f,-15.668f,-17.111f,-14.867f,-14.176f,-15.190f,-13.783f, - -9.408f, -6.763f, -6.517f, -6.716f, -4.750f, -2.784f, -1.009f, -0.421f, -1.884f, -2.506f, - 0.111f, 2.068f, 3.445f, 5.607f, 7.034f, 8.767f, 9.765f, 9.995f, 11.240f, 12.901f, - 13.606f -},{ --29.534f,-29.930f,-30.203f,-31.162f,-32.464f,-33.662f,-35.045f,-35.037f,-35.766f,-36.903f, --38.605f,-39.885f,-40.764f,-41.147f,-39.955f,-39.324f,-39.460f,-37.765f,-35.565f,-33.697f, --32.267f,-31.154f,-30.085f,-30.644f,-30.611f,-32.864f,-34.844f,-33.105f,-32.299f,-30.188f, --28.328f,-27.306f,-26.316f,-25.604f,-25.100f,-24.682f,-24.270f,-24.014f,-23.815f,-23.689f, --23.635f,-24.040f,-24.557f,-25.269f,-25.880f,-26.654f,-27.480f,-28.327f,-29.331f,-30.297f, --31.071f,-31.819f,-32.720f,-33.766f,-34.879f,-33.176f,-26.322f,-23.308f,-21.822f,-20.487f, --17.679f,-16.012f,-13.666f,-10.238f, -7.244f, -3.864f, -0.616f, 2.899f, 5.427f, 9.212f, - 13.550f, 17.818f, 21.834f, 25.781f, 29.174f, 31.843f, 34.010f, 36.246f, 38.432f, 36.798f, - 33.094f, 41.986f, 45.824f, 50.191f, 55.078f, 56.293f, 58.451f, 59.767f, 62.223f, 43.752f, - 50.794f, 67.688f, 70.406f, 70.052f, 69.117f, 63.696f, 70.126f, 71.314f, 71.351f, 67.663f, - 64.685f, 65.336f, 60.343f, 46.375f, 43.900f, 42.282f, 44.490f, 42.920f, 38.355f, 35.324f, - 32.589f, 30.783f, 28.288f, 21.516f, 23.365f, 28.146f, 27.917f, 27.475f, 25.831f, 24.097f, - 23.207f, 21.600f, 20.825f, 20.984f, 20.994f, 19.827f, 18.838f, 18.500f, 17.900f, 17.468f, - 17.210f, 17.975f, 17.574f, 15.223f, 12.740f, 11.002f, 9.999f, 9.253f, 9.092f, 8.927f, - 8.714f, 7.777f, 5.975f, 2.305f, 0.996f, 0.330f, -0.224f, -1.565f, -1.660f, -4.767f, - -5.769f, -8.239f,-10.835f,-12.971f,-15.213f,-16.393f,-14.209f,-13.626f,-15.526f,-14.299f, - -9.715f, -6.975f, -6.686f, -6.665f, -4.474f, -2.413f, -0.818f, -0.520f, -1.848f, -2.653f, - 0.095f, 2.258f, 3.406f, 5.454f, 6.929f, 8.767f, 9.503f, 9.851f, 11.383f, 12.923f, - 13.606f -},{ --29.534f,-29.961f,-30.267f,-31.260f,-32.638f,-34.017f,-35.461f,-35.857f,-36.969f,-37.955f, --39.294f,-40.519f,-41.519f,-41.542f,-40.771f,-40.561f,-40.357f,-39.228f,-36.909f,-34.240f, --33.073f,-32.214f,-31.312f,-31.876f,-31.640f,-33.102f,-35.738f,-33.567f,-32.719f,-30.720f, --28.809f,-27.911f,-27.043f,-26.151f,-25.504f,-24.993f,-24.611f,-24.256f,-24.029f,-24.011f, --23.697f,-23.936f,-24.412f,-24.901f,-25.640f,-26.364f,-27.068f,-27.849f,-28.851f,-29.647f, --30.386f,-31.087f,-31.844f,-32.562f,-33.578f,-33.059f,-27.159f,-22.108f,-20.430f,-19.950f, --18.070f,-16.261f,-13.241f,-10.260f, -6.193f, -2.897f, 0.290f, 3.561f, 6.698f, 11.480f, - 15.531f, 19.703f, 24.076f, 28.757f, 33.042f, 34.763f, 35.743f, 37.247f, 40.938f, 41.559f, - 36.139f, 41.786f, 47.617f, 50.333f, 54.167f, 57.506f, 58.875f, 60.048f, 63.931f, 45.464f, - 46.844f, 58.459f, 62.148f, 67.323f, 70.163f, 65.074f, 64.085f, 61.921f, 64.718f, 68.014f, - 64.066f, 55.470f, 47.427f, 44.967f, 46.293f, 45.467f, 44.695f, 42.304f, 39.628f, 36.751f, - 34.461f, 32.560f, 30.392f, 26.308f, 27.221f, 26.365f, 29.129f, 30.014f, 29.283f, 27.057f, - 25.363f, 24.271f, 23.724f, 23.965f, 23.575f, 22.238f, 21.553f, 20.538f, 20.456f, 20.209f, - 20.383f, 20.708f, 21.037f, 18.812f, 16.011f, 13.553f, 12.162f, 11.586f, 11.444f, 11.179f, - 10.669f, 9.166f, 6.605f, 4.505f, 3.546f, 2.140f, 1.701f, 1.192f, 0.828f, -3.184f, - -4.113f, -6.690f,-10.100f,-12.563f,-14.259f,-13.592f,-11.527f,-11.231f,-13.753f,-13.408f, - -9.831f, -7.401f, -7.027f, -6.424f, -4.339f, -2.167f, -0.830f, -0.266f, -1.873f, -2.569f, - -0.106f, 2.237f, 3.342f, 5.362f, 6.940f, 8.722f, 9.230f, 9.769f, 11.561f, 12.947f, - 13.606f -},{ --29.534f,-29.992f,-30.331f,-31.356f,-32.799f,-34.342f,-35.786f,-36.703f,-38.255f,-38.809f, --39.705f,-40.945f,-41.903f,-41.512f,-41.016f,-41.509f,-41.253f,-40.294f,-37.750f,-34.810f, --33.576f,-33.194f,-33.580f,-33.944f,-33.404f,-33.687f,-36.595f,-34.195f,-33.574f,-31.306f, --29.504f,-28.581f,-27.443f,-26.488f,-25.728f,-24.896f,-24.388f,-23.826f,-23.427f,-23.486f, --23.466f,-23.723f,-24.094f,-24.688f,-25.265f,-25.997f,-26.662f,-27.328f,-28.294f,-29.025f, --29.691f,-30.295f,-30.927f,-31.809f,-32.704f,-32.553f,-27.695f,-21.315f,-19.332f,-18.813f, --17.339f,-16.439f,-12.382f, -8.247f, -1.866f, -2.565f, 1.973f, 6.187f, 10.091f, 13.878f, - 17.720f, 22.142f, 27.261f, 31.443f, 34.158f, 36.615f, 37.662f, 39.117f, 43.283f, 45.749f, - 42.028f, 37.418f, 45.588f, 50.058f, 54.362f, 57.946f, 58.806f, 58.785f, 61.523f, 54.522f, - 68.556f, 65.387f, 56.185f, 55.833f, 61.785f, 53.469f, 45.248f, 51.153f, 55.077f, 50.729f, - 49.711f, 51.713f, 52.089f, 51.194f, 49.570f, 47.087f, 44.895f, 42.435f, 39.925f, 38.000f, - 35.469f, 34.070f, 32.325f, 29.781f, 25.055f, 25.108f, 28.907f, 31.154f, 30.613f, 29.244f, - 28.390f, 27.216f, 26.314f, 26.118f, 25.895f, 25.322f, 24.296f, 23.290f, 22.890f, 23.026f, - 23.868f, 24.367f, 22.542f, 21.006f, 18.755f, 16.226f, 14.209f, 13.398f, 13.621f, 12.867f, - 11.805f, 10.050f, 7.989f, 5.862f, 5.183f, 3.816f, 3.799f, 3.866f, 2.355f, -1.271f, - -3.158f, -5.788f, -9.007f,-12.051f,-12.509f,-10.005f, -8.162f, -7.986f,-10.280f,-10.790f, - -9.507f, -7.759f, -7.123f, -6.153f, -4.260f, -2.118f, -0.777f, 0.136f, -1.947f, -2.276f, - -0.388f, 2.013f, 3.226f, 5.299f, 7.004f, 8.609f, 8.968f, 9.760f, 11.770f, 12.971f, - 13.606f -},{ --29.534f,-30.021f,-30.392f,-31.450f,-32.949f,-34.632f,-36.037f,-37.486f,-39.405f,-39.415f, --39.986f,-41.245f,-42.063f,-41.677f,-41.180f,-42.140f,-41.749f,-39.617f,-37.278f,-35.259f, --34.458f,-34.542f,-34.949f,-36.387f,-35.108f,-34.608f,-37.419f,-35.128f,-34.376f,-31.985f, --30.338f,-29.132f,-27.764f,-26.778f,-25.893f,-24.854f,-24.171f,-23.549f,-23.040f,-22.911f, --23.097f,-23.369f,-23.816f,-24.462f,-24.963f,-25.736f,-26.458f,-27.073f,-27.818f,-28.472f, --28.933f,-29.424f,-29.835f,-30.363f,-31.232f,-31.537f,-27.670f,-21.133f,-20.135f,-20.238f, --18.365f,-16.116f,-12.401f, -7.152f, 0.227f, 0.211f, 3.366f, 8.179f, 12.527f, 15.930f, - 20.568f, 23.501f, 28.264f, 32.873f, 34.618f, 37.472f, 38.925f, 41.965f, 44.724f, 47.967f, - 46.665f, 34.138f, 42.174f, 49.514f, 53.494f, 57.663f, 59.135f, 57.934f, 59.343f, 67.793f, - 72.155f, 71.211f, 68.269f, 61.556f, 65.198f, 55.527f, 60.250f, 61.977f, 61.455f, 60.184f, - 58.561f, 57.189f, 55.140f, 52.625f, 50.113f, 47.347f, 45.276f, 43.001f, 41.007f, 38.838f, - 36.471f, 35.344f, 33.921f, 32.117f, 28.926f, 24.479f, 28.159f, 31.978f, 31.217f, 30.280f, - 29.680f, 29.285f, 28.998f, 28.235f, 28.060f, 28.147f, 27.087f, 25.893f, 25.576f, 24.291f, - 24.167f, 26.288f, 24.573f, 22.224f, 20.379f, 17.957f, 16.762f, 15.861f, 16.049f, 14.285f, - 11.962f, 10.721f, 9.342f, 7.556f, 6.668f, 5.382f, 5.965f, 5.554f, 3.660f, 0.260f, - -2.470f, -4.792f, -7.586f,-11.288f,-10.556f, -6.848f, -5.585f, -5.498f, -6.653f, -7.492f, - -8.653f, -7.838f, -6.916f, -5.979f, -3.989f, -2.122f, -0.529f, 0.416f, -1.874f, -1.968f, - -0.643f, 1.678f, 3.077f, 5.242f, 7.054f, 8.421f, 8.746f, 9.835f, 12.006f, 12.997f, - 13.606f -},{ --29.534f,-30.050f,-30.452f,-31.542f,-33.092f,-34.881f,-36.237f,-38.116f,-40.207f,-39.819f, --40.337f,-41.574f,-42.362f,-42.485f,-41.973f,-42.704f,-41.771f,-38.371f,-36.714f,-36.065f, --36.139f,-36.383f,-35.717f,-37.323f,-35.904f,-35.056f,-38.154f,-36.117f,-34.718f,-32.623f, --30.975f,-29.544f,-28.221f,-26.937f,-25.881f,-24.896f,-24.114f,-23.362f,-22.691f,-22.511f, --22.821f,-22.857f,-23.280f,-23.763f,-24.379f,-25.127f,-25.909f,-26.474f,-27.133f,-27.841f, --28.315f,-28.644f,-28.920f,-29.425f,-30.176f,-30.612f,-26.915f,-20.666f,-19.435f,-18.100f, --16.637f,-14.720f,-11.983f, -5.220f, 3.121f, 2.449f, 3.692f, 9.129f, 14.226f, 17.485f, - 22.993f, 26.724f, 28.818f, 30.889f, 33.818f, 36.834f, 41.878f, 44.016f, 45.951f, 48.946f, - 49.787f, 40.950f, 41.725f, 49.521f, 52.540f, 55.787f, 59.148f, 59.713f, 63.761f, 70.802f, - 73.505f, 72.402f, 69.304f, 67.432f, 66.449f, 67.603f, 67.609f, 66.622f, 64.790f, 62.245f, - 59.894f, 57.813f, 55.374f, 52.563f, 49.956f, 47.630f, 45.472f, 43.296f, 41.478f, 39.314f, - 37.391f, 35.904f, 35.110f, 34.086f, 32.413f, 28.762f, 25.055f, 26.041f, 29.278f, 30.209f, - 30.562f, 30.499f, 30.116f, 30.708f, 29.661f, 29.167f, 29.600f, 28.724f, 25.586f, 22.982f, - 23.407f, 26.623f, 26.435f, 23.995f, 22.291f, 20.292f, 18.797f, 18.120f, 17.406f, 15.666f, - 13.106f, 11.978f, 10.833f, 9.399f, 8.004f, 7.207f, 8.200f, 7.472f, 5.732f, 1.361f, - -1.077f, -3.263f, -6.124f,-10.505f, -9.451f, -4.765f, -4.273f, -4.901f, -4.993f, -5.426f, - -7.267f, -7.618f, -6.562f, -5.753f, -3.581f, -2.001f, -0.249f, 0.584f, -1.361f, -1.818f, - -0.822f, 1.342f, 2.949f, 5.183f, 7.036f, 8.164f, 8.592f, 9.994f, 12.266f, 13.023f, - 13.606f -},{ --29.534f,-30.078f,-30.509f,-31.633f,-33.230f,-35.084f,-36.407f,-38.532f,-40.558f,-40.127f, --40.885f,-42.067f,-42.966f,-43.659f,-43.352f,-43.497f,-42.230f,-39.032f,-37.639f,-37.349f, --36.867f,-36.946f,-36.619f,-36.708f,-36.408f,-35.483f,-38.987f,-37.254f,-35.246f,-33.287f, --31.401f,-29.957f,-28.471f,-27.177f,-25.974f,-24.837f,-23.791f,-23.005f,-22.449f,-22.141f, --22.409f,-22.395f,-22.671f,-23.262f,-23.804f,-24.438f,-25.124f,-25.604f,-26.272f,-26.871f, --27.493f,-27.753f,-27.792f,-28.287f,-29.210f,-28.386f,-23.947f,-19.137f,-17.724f,-16.238f, --14.407f,-12.107f,-10.259f, -1.797f, 3.609f, 3.100f, 3.348f, 11.401f, 14.795f, 20.232f, - 24.383f, 28.525f, 31.876f, 33.408f, 35.033f, 39.084f, 42.481f, 45.728f, 49.110f, 51.997f, - 52.229f, 46.467f, 45.506f, 45.318f, 50.106f, 54.817f, 57.761f, 59.909f, 68.127f, 72.366f, - 76.604f, 73.326f, 72.358f, 72.731f, 71.136f, 69.890f, 68.196f, 66.701f, 64.336f, 61.499f, - 59.414f, 57.051f, 54.732f, 52.036f, 49.843f, 47.512f, 46.067f, 43.825f, 41.420f, 39.758f, - 37.807f, 36.193f, 35.165f, 35.124f, 35.144f, 33.203f, 28.254f, 24.248f, 24.898f, 26.293f, - 30.395f, 31.243f, 31.804f, 32.165f, 31.069f, 29.942f, 27.716f, 26.918f, 25.810f, 24.776f, - 22.967f, 23.528f, 24.571f, 25.405f, 25.271f, 22.695f, 20.460f, 18.573f, 18.116f, 16.102f, - 14.964f, 13.592f, 12.346f, 11.005f, 9.797f, 9.198f, 10.469f, 8.861f, 7.126f, 2.176f, - 0.589f, -1.486f, -4.620f, -9.764f, -9.524f, -4.145f, -4.341f, -5.111f, -5.184f, -5.331f, - -6.067f, -7.105f, -6.162f, -5.316f, -3.314f, -1.753f, -0.146f, 0.866f, -0.353f, -1.811f, - -0.931f, 1.072f, 2.894f, 5.117f, 6.916f, 7.864f, 8.529f, 10.237f, 12.542f, 13.049f, - 13.606f -},{ --29.534f,-30.105f,-30.565f,-31.722f,-33.366f,-35.238f,-36.563f,-38.732f,-40.524f,-40.442f, --41.610f,-42.745f,-43.707f,-44.616f,-44.689f,-44.723f,-43.877f,-41.469f,-39.277f,-38.351f, --36.881f,-36.828f,-37.093f,-36.413f,-36.905f,-35.515f,-39.646f,-38.085f,-35.791f,-33.807f, --31.932f,-30.271f,-28.599f,-27.250f,-25.847f,-24.703f,-23.654f,-22.988f,-22.132f,-21.891f, --22.114f,-21.822f,-22.113f,-22.559f,-23.153f,-23.618f,-24.163f,-24.660f,-25.198f,-25.994f, --26.331f,-26.923f,-26.748f,-27.172f,-28.052f,-25.044f,-21.750f,-16.552f,-14.821f,-13.019f, --10.285f, -9.198f, -8.592f, 0.011f, 1.203f, 3.495f, 4.508f, 12.905f, 15.585f, 22.265f, - 24.230f, 28.364f, 32.094f, 34.525f, 36.803f, 40.509f, 44.716f, 49.140f, 52.294f, 54.565f, - 55.261f, 51.742f, 46.677f, 41.798f, 34.941f, 43.155f, 56.643f, 58.588f, 68.866f, 73.940f, - 76.337f, 74.328f, 74.110f, 73.359f, 72.191f, 69.478f, 67.396f, 65.794f, 63.517f, 60.753f, - 58.579f, 56.355f, 54.318f, 51.891f, 49.940f, 48.014f, 46.015f, 43.939f, 41.812f, 39.879f, - 38.466f, 37.205f, 36.014f, 35.597f, 36.256f, 36.269f, 33.368f, 28.972f, 25.904f, 24.359f, - 25.716f, 29.264f, 31.243f, 32.673f, 32.313f, 31.020f, 28.457f, 27.524f, 27.198f, 24.783f, - 23.884f, 22.907f, 22.961f, 25.279f, 25.381f, 23.763f, 21.139f, 19.562f, 18.905f, 17.627f, - 16.818f, 15.810f, 13.997f, 12.712f, 11.658f, 11.801f, 11.295f, 9.589f, 8.401f, 3.781f, - 2.438f, 0.060f, -2.727f, -8.459f, -8.661f, -3.655f, -4.668f, -5.029f, -5.191f, -5.617f, - -5.829f, -6.426f, -5.732f, -4.664f, -3.189f, -1.529f, -0.198f, 1.338f, 0.799f, -1.769f, - -0.981f, 0.875f, 2.920f, 5.033f, 6.695f, 7.557f, 8.575f, 10.555f, 12.830f, 13.076f, - 13.606f -},{ --29.534f,-30.131f,-30.620f,-31.811f,-33.502f,-35.346f,-36.716f,-38.775f,-40.326f,-40.835f, --42.391f,-43.540f,-44.385f,-45.291f,-45.793f,-46.310f,-45.926f,-43.249f,-39.974f,-38.613f, --37.613f,-37.317f,-37.245f,-36.781f,-37.409f,-35.871f,-40.187f,-38.576f,-36.190f,-34.218f, --32.350f,-30.465f,-28.678f,-27.275f,-25.723f,-24.649f,-23.651f,-22.785f,-21.896f,-21.455f, --21.618f,-21.268f,-21.515f,-21.916f,-22.480f,-22.976f,-23.296f,-23.811f,-24.130f,-24.738f, --25.496f,-25.557f,-25.559f,-26.038f,-25.984f,-22.202f,-18.195f,-14.558f,-12.249f, -8.810f, - -6.130f, -4.116f, -5.796f, 0.312f, 1.837f, 4.739f, 7.081f, 15.490f, 18.529f, 23.856f, - 24.593f, 28.908f, 32.961f, 36.472f, 39.050f, 42.548f, 47.734f, 51.513f, 53.545f, 57.043f, - 57.786f, 56.275f, 51.040f, 46.077f, 43.563f, 48.859f, 54.477f, 63.454f, 70.554f, 76.510f, - 72.741f, 74.425f, 74.322f, 74.421f, 72.110f, 69.736f, 67.146f, 65.909f, 64.034f, 60.858f, - 58.246f, 56.054f, 53.869f, 51.616f, 49.611f, 48.452f, 46.409f, 44.127f, 42.281f, 40.493f, - 39.010f, 37.952f, 36.972f, 36.728f, 37.200f, 34.286f, 36.186f, 32.971f, 32.661f, 28.726f, - 26.786f, 26.630f, 25.814f, 30.691f, 31.903f, 32.720f, 30.003f, 29.132f, 27.961f, 25.842f, - 24.943f, 23.745f, 23.109f, 26.275f, 24.454f, 23.018f, 21.786f, 20.297f, 19.097f, 19.346f, - 18.555f, 17.128f, 15.884f, 14.542f, 13.104f, 13.459f, 12.351f, 11.086f, 9.827f, 5.640f, - 3.737f, 1.537f, -1.126f, -6.843f, -5.920f, -2.813f, -4.363f, -4.852f, -4.645f, -5.020f, - -5.810f, -5.757f, -5.240f, -3.919f, -2.966f, -1.456f, -0.252f, 1.753f, 1.612f, -1.556f, - -0.964f, 0.729f, 2.988f, 4.915f, 6.403f, 7.292f, 8.738f, 10.934f, 13.121f, 13.102f, - 13.606f -},{ --29.534f,-30.156f,-30.672f,-31.900f,-33.639f,-35.416f,-36.872f,-38.765f,-40.248f,-41.349f, --43.122f,-44.376f,-45.080f,-46.184f,-47.091f,-47.755f,-46.807f,-43.408f,-40.183f,-39.022f, --38.148f,-37.030f,-36.988f,-37.526f,-38.104f,-37.257f,-40.710f,-39.262f,-36.494f,-34.608f, --32.671f,-30.466f,-28.726f,-27.181f,-25.619f,-24.487f,-23.436f,-22.565f,-21.645f,-21.122f, --20.991f,-20.753f,-20.855f,-21.309f,-21.700f,-22.243f,-22.589f,-23.065f,-23.296f,-23.458f, --24.200f,-24.024f,-24.230f,-24.655f,-24.252f,-19.022f,-14.064f,-14.474f,-12.264f, -7.304f, - -3.517f, -0.993f, 0.042f, 0.512f, 4.390f, 6.667f, 9.880f, 19.153f, 21.349f, 25.896f, - 27.511f, 31.394f, 35.039f, 37.980f, 40.693f, 44.757f, 50.216f, 53.836f, 56.428f, 58.940f, - 60.347f, 59.849f, 58.995f, 53.909f, 52.503f, 58.730f, 65.159f, 68.542f, 70.688f, 79.491f, - 73.762f, 74.390f, 74.306f, 73.398f, 72.473f, 70.540f, 68.720f, 66.501f, 63.978f, 61.640f, - 58.137f, 55.787f, 53.810f, 52.016f, 50.048f, 48.737f, 46.421f, 44.399f, 42.555f, 41.049f, - 39.813f, 38.858f, 38.288f, 37.653f, 37.244f, 35.683f, 36.475f, 34.852f, 34.839f, 33.080f, - 31.990f, 29.804f, 31.368f, 34.322f, 34.017f, 35.077f, 32.916f, 31.457f, 28.904f, 27.670f, - 26.177f, 24.878f, 23.774f, 26.041f, 24.603f, 23.532f, 22.248f, 20.662f, 19.772f, 19.625f, - 19.985f, 18.499f, 17.584f, 16.534f, 14.058f, 14.126f, 13.029f, 11.492f, 10.009f, 7.119f, - 4.494f, 2.849f, -0.111f, -5.893f, -2.888f, -1.704f, -3.435f, -4.239f, -4.158f, -4.312f, - -5.047f, -5.119f, -4.676f, -3.348f, -2.611f, -1.498f, -0.291f, 1.795f, 1.928f, -1.241f, - -0.877f, 0.632f, 3.034f, 4.749f, 6.092f, 7.115f, 9.012f, 11.355f, 13.409f, 13.127f, - 13.606f -},{ --29.534f,-30.179f,-30.723f,-31.987f,-33.778f,-35.464f,-37.031f,-38.812f,-40.516f,-42.017f, --43.794f,-45.247f,-46.044f,-47.563f,-48.681f,-48.443f,-46.178f,-43.149f,-41.154f,-40.453f, --38.887f,-37.202f,-37.392f,-38.791f,-38.565f,-38.302f,-41.024f,-40.137f,-36.906f,-34.985f, --32.914f,-30.612f,-28.746f,-27.091f,-25.631f,-24.516f,-23.398f,-22.405f,-21.382f,-20.636f, --20.486f,-20.287f,-20.243f,-20.449f,-20.875f,-21.313f,-21.724f,-21.995f,-22.308f,-22.301f, --22.618f,-23.088f,-22.455f,-22.744f,-21.408f,-14.951f,-11.394f,-11.013f, -8.952f, -5.687f, - -1.150f, 1.725f, 3.533f, 4.313f, 7.982f, 9.524f, 12.902f, 21.742f, 25.114f, 27.975f, - 31.048f, 34.295f, 36.909f, 39.131f, 42.810f, 46.959f, 51.413f, 54.801f, 56.760f, 58.662f, - 61.227f, 61.965f, 63.176f, 62.905f, 57.547f, 57.415f, 66.820f, 68.675f, 69.716f, 77.891f, - 73.017f, 73.115f, 72.654f, 71.925f, 70.658f, 68.990f, 66.325f, 67.650f, 64.061f, 61.167f, - 58.783f, 56.083f, 53.846f, 52.283f, 50.621f, 49.402f, 47.162f, 45.280f, 43.485f, 41.825f, - 40.659f, 39.721f, 39.471f, 38.757f, 36.824f, 36.792f, 36.313f, 35.340f, 35.058f, 35.787f, - 34.399f, 33.208f, 32.508f, 34.908f, 36.959f, 36.063f, 33.064f, 31.643f, 31.162f, 29.770f, - 28.989f, 25.795f, 24.724f, 26.798f, 25.004f, 25.212f, 23.684f, 22.506f, 20.679f, 20.066f, - 20.791f, 20.219f, 18.817f, 17.785f, 15.531f, 14.257f, 13.484f, 11.575f, 10.373f, 8.049f, - 5.147f, 3.464f, 0.589f, -5.060f, -0.371f, -0.341f, -2.088f, -3.273f, -3.565f, -3.823f, - -4.001f, -4.540f, -4.136f, -3.125f, -2.269f, -1.491f, -0.425f, 1.405f, 2.019f, -1.050f, - -0.757f, 0.621f, 3.017f, 4.547f, 5.828f, 7.065f, 9.381f, 11.795f, 13.685f, 13.152f, - 13.606f -},{ --29.534f,-30.202f,-30.772f,-32.075f,-33.918f,-35.507f,-37.194f,-38.993f,-41.193f,-42.854f, --44.499f,-46.199f,-47.319f,-48.999f,-49.903f,-48.375f,-45.389f,-43.490f,-42.433f,-42.107f, --41.532f,-40.109f,-39.467f,-39.597f,-39.170f,-39.385f,-41.130f,-40.251f,-37.273f,-35.001f, --32.875f,-30.688f,-28.761f,-27.111f,-25.620f,-24.476f,-23.313f,-22.149f,-20.980f,-20.325f, --19.921f,-19.651f,-19.525f,-19.659f,-19.935f,-20.413f,-20.563f,-20.847f,-20.974f,-21.033f, --21.098f,-21.682f,-20.831f,-20.885f,-18.493f,-10.529f, -8.012f, -6.754f, -3.681f, -2.234f, - 0.429f, 3.821f, 5.143f, 6.749f, 9.634f, 13.389f, 17.001f, 23.980f, 27.253f, 30.792f, - 33.081f, 35.676f, 39.161f, 42.588f, 45.405f, 48.441f, 52.059f, 55.515f, 58.875f, 60.157f, - 62.761f, 64.513f, 66.447f, 67.124f, 66.134f, 67.526f, 70.023f, 68.664f, 72.121f, 75.191f, - 71.986f, 70.967f, 71.584f, 70.606f, 69.714f, 68.299f, 65.557f, 62.784f, 62.583f, 61.716f, - 59.575f, 58.032f, 55.340f, 53.643f, 51.830f, 50.329f, 48.649f, 46.718f, 44.692f, 42.622f, - 41.601f, 40.707f, 40.052f, 39.523f, 37.911f, 36.865f, 37.262f, 37.185f, 37.139f, 36.130f, - 36.017f, 35.644f, 33.159f, 33.537f, 36.515f, 36.355f, 34.320f, 32.656f, 30.558f, 30.632f, - 30.194f, 26.966f, 25.819f, 26.052f, 26.952f, 28.680f, 26.580f, 24.519f, 21.909f, 20.660f, - 20.553f, 20.227f, 18.974f, 18.480f, 16.616f, 14.537f, 14.082f, 12.421f, 10.822f, 8.506f, - 5.295f, 3.766f, 1.190f, -4.091f, 1.385f, 0.480f, -0.946f, -2.358f, -3.020f, -3.053f, - -3.196f, -4.083f, -3.695f, -3.033f, -1.972f, -1.301f, -0.585f, 0.817f, 2.241f, -1.125f, - -0.672f, 0.755f, 2.959f, 4.357f, 5.676f, 7.162f, 9.815f, 12.228f, 13.942f, 13.175f, - 13.606f -},{ --29.534f,-30.224f,-30.819f,-32.162f,-34.058f,-35.565f,-37.357f,-39.329f,-42.154f,-43.834f, --45.344f,-47.254f,-48.603f,-49.881f,-50.209f,-48.307f,-45.852f,-44.567f,-43.402f,-43.175f, --44.096f,-43.035f,-41.195f,-39.826f,-40.077f,-40.653f,-40.903f,-40.240f,-37.540f,-35.107f, --32.947f,-30.641f,-28.764f,-27.079f,-25.619f,-24.426f,-23.140f,-21.910f,-20.778f,-19.991f, --19.433f,-19.015f,-18.757f,-18.939f,-19.114f,-19.329f,-19.542f,-19.683f,-19.795f,-19.684f, --19.499f,-19.858f,-19.275f,-18.233f,-10.740f, -6.662f, -4.164f, -2.361f, 0.223f, 1.243f, - 3.202f, 5.387f, 7.510f, 8.805f, 12.246f, 16.394f, 21.843f, 26.481f, 29.720f, 31.859f, - 34.319f, 37.378f, 41.025f, 44.623f, 47.392f, 50.731f, 53.677f, 56.875f, 60.478f, 62.279f, - 64.934f, 66.660f, 67.204f, 68.115f, 68.022f, 67.518f, 75.594f, 69.122f, 72.104f, 74.609f, - 67.969f, 70.649f, 71.088f, 69.979f, 68.803f, 67.846f, 66.661f, 62.665f, 63.063f, 61.653f, - 59.510f, 57.946f, 55.709f, 53.988f, 52.155f, 50.667f, 49.134f, 47.615f, 46.058f, 44.870f, - 43.607f, 41.968f, 40.848f, 39.437f, 39.137f, 39.113f, 39.293f, 38.598f, 38.145f, 37.703f, - 37.491f, 37.208f, 35.537f, 34.273f, 39.600f, 36.730f, 35.649f, 34.538f, 32.362f, 31.354f, - 30.990f, 28.375f, 27.197f, 25.688f, 26.666f, 29.927f, 29.054f, 26.049f, 23.388f, 21.272f, - 20.394f, 19.692f, 18.183f, 17.283f, 16.292f, 14.666f, 14.574f, 13.529f, 11.317f, 9.676f, - 6.307f, 4.973f, 2.216f, -2.428f, 2.690f, 1.184f, -0.228f, -1.761f, -2.445f, -2.307f, - -2.466f, -3.691f, -3.318f, -2.792f, -1.724f, -0.952f, -0.466f, 0.332f, 2.635f, -1.319f, - -0.659f, 1.070f, 2.948f, 4.264f, 5.688f, 7.407f, 10.273f, 12.629f, 14.174f, 13.196f, - 13.606f -},{ --29.534f,-30.244f,-30.865f,-32.249f,-34.195f,-35.654f,-37.514f,-39.775f,-43.145f,-44.858f, --46.362f,-48.352f,-49.544f,-50.183f,-50.020f,-48.884f,-47.484f,-46.374f,-45.007f,-44.388f, --44.102f,-43.227f,-41.453f,-40.285f,-41.088f,-41.894f,-40.697f,-40.763f,-37.849f,-35.123f, --33.008f,-30.772f,-28.648f,-27.121f,-25.655f,-24.289f,-22.864f,-21.683f,-20.463f,-19.501f, --18.900f,-18.437f,-18.160f,-18.123f,-18.327f,-18.517f,-18.690f,-18.636f,-18.632f,-18.452f, --18.045f,-18.086f,-17.220f,-13.475f, -6.752f, -3.837f, -1.656f, 0.861f, 2.182f, 3.782f, - 5.848f, 7.571f, 9.025f, 11.654f, 14.470f, 19.446f, 24.286f, 28.010f, 31.402f, 33.828f, - 37.018f, 39.660f, 43.502f, 45.402f, 48.975f, 52.675f, 55.115f, 57.586f, 60.660f, 62.579f, - 64.210f, 66.472f, 68.354f, 69.843f, 70.102f, 69.888f, 80.779f, 76.710f, 73.647f, 72.421f, - 68.395f, 70.858f, 70.471f, 69.381f, 68.111f, 67.059f, 65.743f, 61.494f, 65.328f, 61.712f, - 59.703f, 57.794f, 55.974f, 54.642f, 52.821f, 51.316f, 49.750f, 48.650f, 47.290f, 46.353f, - 45.457f, 44.538f, 43.831f, 42.002f, 41.722f, 40.976f, 40.333f, 40.076f, 39.628f, 39.118f, - 38.564f, 37.920f, 37.244f, 35.670f, 36.136f, 37.492f, 39.826f, 36.770f, 35.931f, 32.791f, - 31.452f, 29.624f, 28.120f, 26.932f, 26.269f, 26.219f, 28.526f, 28.228f, 25.300f, 22.789f, - 20.588f, 19.417f, 18.396f, 17.538f, 16.480f, 15.210f, 15.050f, 14.891f, 12.413f, 10.883f, - 8.593f, 7.689f, 4.471f, 1.053f, 3.945f, 2.274f, 0.602f, -1.454f, -0.938f, -1.616f, - -1.874f, -3.299f, -3.017f, -2.501f, -1.604f, -0.587f, 0.071f, 0.146f, 2.935f, -1.247f, - -0.667f, 1.543f, 3.094f, 4.362f, 5.886f, 7.774f, 10.713f, 12.973f, 14.374f, 13.216f, - 13.606f -},{ --29.534f,-30.263f,-30.909f,-32.335f,-34.327f,-35.783f,-37.657f,-40.246f,-43.907f,-45.766f, --47.463f,-49.361f,-50.102f,-50.459f,-50.244f,-49.906f,-49.047f,-48.405f,-47.748f,-45.944f, --43.062f,-42.069f,-41.223f,-40.380f,-41.967f,-43.070f,-40.698f,-41.075f,-38.408f,-35.039f, --32.922f,-30.744f,-28.576f,-26.820f,-25.289f,-23.798f,-22.361f,-21.034f,-20.014f,-19.041f, --18.310f,-17.783f,-17.529f,-17.436f,-17.587f,-17.648f,-17.759f,-17.889f,-17.644f,-17.165f, --16.740f,-16.040f,-15.441f, -8.585f, -4.841f, -2.067f, 0.613f, 2.627f, 4.343f, 6.625f, - 7.975f, 9.716f, 10.744f, 13.569f, 16.969f, 21.232f, 26.206f, 30.388f, 33.575f, 36.273f, - 39.085f, 41.951f, 45.454f, 47.531f, 49.779f, 52.218f, 54.914f, 58.280f, 61.781f, 63.826f, - 65.607f, 67.491f, 68.685f, 69.639f, 70.066f, 69.257f, 82.330f, 78.075f, 74.879f, 69.956f, - 70.105f, 70.796f, 70.092f, 68.763f, 67.475f, 66.518f, 65.513f, 63.922f, 58.489f, 58.601f, - 60.112f, 58.869f, 56.081f, 54.956f, 53.069f, 51.907f, 50.658f, 49.566f, 48.268f, 47.473f, - 46.523f, 45.902f, 45.325f, 44.336f, 43.715f, 43.065f, 42.183f, 41.728f, 40.724f, 39.997f, - 39.470f, 39.227f, 38.618f, 36.997f, 37.136f, 40.882f, 42.320f, 39.586f, 36.248f, 34.509f, - 32.518f, 30.282f, 29.052f, 28.098f, 26.945f, 25.613f, 26.092f, 27.309f, 26.075f, 23.904f, - 21.807f, 20.341f, 19.489f, 17.958f, 16.957f, 15.661f, 14.953f, 15.060f, 13.798f, 11.811f, - 10.072f, 9.410f, 7.059f, 4.638f, 4.982f, 2.998f, 1.864f, 0.157f, 0.831f, -0.631f, - -1.458f, -2.896f, -2.820f, -2.267f, -1.524f, -0.304f, 0.693f, 0.317f, 2.897f, -0.592f, - -0.572f, 2.093f, 3.463f, 4.716f, 6.261f, 8.218f, 11.088f, 13.237f, 14.535f, 13.234f, - 13.606f -},{ --29.534f,-30.281f,-30.951f,-32.420f,-34.449f,-35.949f,-37.777f,-40.647f,-44.289f,-46.400f, --48.477f,-50.160f,-50.561f,-51.163f,-51.193f,-50.765f,-49.703f,-49.548f,-50.260f,-47.041f, --43.056f,-41.884f,-41.005f,-40.295f,-42.038f,-43.698f,-40.943f,-41.085f,-39.004f,-34.983f, --32.848f,-30.484f,-28.281f,-26.664f,-25.070f,-23.480f,-22.155f,-21.047f,-19.893f,-18.740f, --17.925f,-17.390f,-17.103f,-17.148f,-17.301f,-17.132f,-17.010f,-16.619f,-16.694f,-16.191f, --15.381f,-14.709f,-11.729f, -6.333f, -3.385f, -0.432f, 2.872f, 7.085f, 8.556f, 10.978f, - 11.752f, 11.534f, 13.214f, 15.988f, 19.472f, 23.911f, 28.380f, 33.129f, 37.267f, 40.227f, - 43.208f, 44.920f, 47.610f, 50.190f, 50.856f, 52.347f, 55.230f, 58.581f, 61.968f, 65.522f, - 67.514f, 68.885f, 69.818f, 70.126f, 70.331f, 71.609f, 81.022f, 76.423f, 73.707f, 69.321f, - 71.190f, 70.927f, 69.740f, 68.533f, 67.289f, 66.290f, 64.777f, 64.115f, 63.251f, 60.622f, - 55.067f, 50.489f, 54.030f, 53.788f, 53.111f, 52.134f, 51.111f, 49.966f, 49.314f, 48.606f, - 48.078f, 47.468f, 46.939f, 46.324f, 45.447f, 44.327f, 43.285f, 42.522f, 42.356f, 42.101f, - 42.094f, 42.374f, 41.856f, 40.636f, 39.672f, 39.367f, 41.430f, 42.368f, 38.126f, 36.699f, - 34.420f, 32.305f, 30.465f, 28.799f, 27.744f, 26.637f, 24.621f, 25.229f, 25.690f, 24.157f, - 22.715f, 21.420f, 19.742f, 18.478f, 17.436f, 15.605f, 14.627f, 14.550f, 14.877f, 12.973f, - 11.272f, 10.521f, 8.351f, 6.973f, 5.963f, 3.325f, 3.224f, 2.525f, 1.329f, 0.078f, - -0.989f, -2.427f, -2.576f, -1.870f, -1.273f, -0.088f, 0.922f, 0.756f, 2.534f, 0.600f, - -0.261f, 2.610f, 4.022f, 5.325f, 6.767f, 8.679f, 11.358f, 13.404f, 14.655f, 13.250f, - 13.606f -},{ --29.534f,-30.298f,-30.992f,-32.503f,-34.559f,-36.139f,-37.870f,-40.904f,-44.309f,-46.695f, --49.244f,-50.735f,-51.200f,-52.240f,-52.425f,-51.359f,-49.759f,-49.444f,-51.158f,-47.872f, --43.893f,-43.030f,-41.432f,-40.805f,-41.796f,-44.282f,-41.419f,-40.978f,-38.809f,-34.974f, --32.984f,-30.368f,-28.433f,-26.656f,-24.875f,-23.155f,-21.547f,-20.170f,-19.124f,-18.831f, --18.521f,-18.191f,-17.913f,-17.663f,-17.589f,-17.202f,-16.785f,-16.199f,-16.157f,-15.775f, --15.067f,-13.052f, -7.929f, -3.588f, -1.050f, 1.131f, 3.714f, 7.182f, 9.689f, 10.214f, - 12.594f, 13.599f, 15.034f, 17.691f, 20.906f, 25.805f, 31.368f, 35.923f, 40.445f, 43.896f, - 45.995f, 47.288f, 49.649f, 51.509f, 52.457f, 53.736f, 56.872f, 59.712f, 62.437f, 66.327f, - 69.201f, 70.472f, 70.995f, 72.213f, 72.856f, 75.784f, 77.301f, 77.238f, 71.214f, 72.106f, - 72.228f, 70.936f, 69.250f, 67.937f, 66.631f, 65.510f, 64.299f, 63.392f, 62.728f, 60.429f, - 61.322f, 50.860f, 52.845f, 52.936f, 53.022f, 52.366f, 51.165f, 50.845f, 50.042f, 49.307f, - 48.859f, 48.324f, 47.593f, 46.894f, 46.357f, 45.608f, 44.488f, 43.658f, 43.431f, 42.589f, - 42.338f, 42.313f, 41.582f, 43.158f, 39.302f, 33.735f, 38.186f, 42.581f, 41.619f, 39.119f, - 37.738f, 35.303f, 34.537f, 31.627f, 29.552f, 28.156f, 25.545f, 23.766f, 23.504f, 23.262f, - 22.490f, 21.417f, 20.022f, 18.815f, 17.853f, 15.715f, 14.179f, 14.292f, 14.255f, 13.422f, - 12.185f, 11.204f, 9.443f, 8.262f, 6.389f, 4.132f, 4.383f, 3.045f, 1.325f, 0.181f, - -0.683f, -1.937f, -2.198f, -1.300f, -0.945f, 0.107f, 0.715f, 1.216f, 2.065f, 1.900f, - 0.277f, 2.994f, 4.635f, 6.102f, 7.329f, 9.091f, 11.492f, 13.461f, 14.729f, 13.263f, - 13.606f -},{ --29.534f,-30.313f,-31.032f,-32.583f,-34.652f,-36.329f,-37.935f,-40.986f,-44.124f,-46.724f, --49.691f,-51.200f,-52.048f,-53.349f,-53.487f,-52.080f,-49.965f,-49.012f,-50.603f,-48.688f, --44.822f,-43.744f,-42.631f,-41.666f,-42.036f,-44.405f,-41.963f,-40.930f,-37.914f,-34.957f, --32.666f,-30.203f,-27.897f,-25.845f,-23.860f,-22.242f,-20.836f,-20.052f,-19.407f,-18.731f, --18.077f,-17.598f,-17.424f,-17.050f,-17.021f,-16.809f,-16.247f,-15.763f,-15.400f,-15.274f, --13.533f,-10.218f, -3.801f, -0.877f, 0.942f, 2.138f, 4.024f, 8.162f, 11.919f, 13.575f, - 15.313f, 16.289f, 17.512f, 20.089f, 22.792f, 26.588f, 32.388f, 37.448f, 40.986f, 43.649f, - 45.264f, 47.750f, 49.929f, 52.312f, 53.700f, 55.892f, 58.703f, 60.989f, 63.469f, 66.727f, - 70.022f, 71.361f, 72.174f, 73.311f, 74.572f, 81.112f, 78.736f, 77.573f, 71.138f, 72.791f, - 72.307f, 70.894f, 69.541f, 68.177f, 66.662f, 65.206f, 64.210f, 62.534f, 61.875f, 60.847f, - 56.076f, 43.494f, 48.140f, 52.422f, 52.610f, 52.181f, 51.634f, 50.670f, 50.132f, 49.347f, - 48.793f, 48.294f, 47.473f, 47.646f, 47.685f, 46.811f, 42.552f, 41.868f, 40.203f, 36.436f, - 34.539f, 35.484f, 33.148f, 33.620f, 24.859f, 22.738f, 30.788f, 39.027f, 41.355f, 41.209f, - 40.368f, 35.918f, 32.730f, 33.140f, 30.624f, 28.599f, 26.500f, 23.677f, 21.629f, 21.446f, - 20.872f, 19.814f, 19.283f, 18.698f, 16.926f, 15.225f, 14.408f, 14.215f, 13.284f, 13.223f, - 12.581f, 11.702f, 10.625f, 8.483f, 6.209f, 5.402f, 5.025f, 2.526f, 1.543f, 0.174f, - -0.800f, -1.592f, -1.888f, -0.927f, -0.831f, 0.278f, 0.498f, 1.420f, 1.717f, 2.806f, - 0.931f, 3.185f, 5.113f, 6.888f, 7.859f, 9.395f, 11.472f, 13.403f, 14.755f, 13.274f, - 13.606f -},{ --29.534f,-30.327f,-31.070f,-32.659f,-34.729f,-36.492f,-37.977f,-40.911f,-43.932f,-46.676f, --49.868f,-51.712f,-52.947f,-54.267f,-54.345f,-53.058f,-50.600f,-49.160f,-49.909f,-49.035f, --45.870f,-44.062f,-43.944f,-42.918f,-43.019f,-44.354f,-42.873f,-40.499f,-37.319f,-34.627f, --32.206f,-29.625f,-27.219f,-25.125f,-23.175f,-21.568f,-20.321f,-19.365f,-18.841f,-18.232f, --17.584f,-17.162f,-17.018f,-16.625f,-16.381f,-16.177f,-15.818f,-15.001f,-15.262f,-14.034f, --11.686f, -6.272f, -0.710f, 2.071f, 3.031f, 4.077f, 5.676f, 8.343f, 12.659f, 15.677f, - 17.624f, 18.854f, 19.897f, 21.928f, 23.985f, 27.870f, 31.903f, 37.240f, 40.757f, 43.407f, - 45.481f, 48.740f, 51.451f, 53.922f, 55.938f, 58.162f, 61.583f, 63.780f, 66.535f, 69.363f, - 72.079f, 73.286f, 74.238f, 74.952f, 78.517f, 83.627f, 78.267f, 77.106f, 73.477f, 73.389f, - 72.288f, 70.667f, 69.235f, 68.104f, 66.877f, 65.527f, 64.453f, 62.543f, 61.330f, 60.456f, - 53.968f, 37.894f, 46.371f, 53.394f, 52.784f, 52.196f, 51.536f, 50.641f, 49.941f, 49.287f, - 48.759f, 48.431f, 48.928f, 47.436f, 44.197f, 41.764f, 38.836f, 45.581f, 48.476f, 36.724f, - 25.043f, 19.519f, 16.345f, 14.570f, 10.793f, 12.689f, 18.972f, 28.451f, 35.366f, 38.049f, - 37.377f, 29.321f, 22.499f, 30.337f, 31.342f, 28.418f, 26.411f, 24.913f, 23.795f, 22.433f, - 20.734f, 19.210f, 18.678f, 18.052f, 16.014f, 15.764f, 14.803f, 13.802f, 13.125f, 13.007f, - 12.383f, 12.539f, 11.531f, 8.641f, 6.516f, 6.112f, 4.787f, 2.977f, 0.949f, 0.296f, - -0.953f, -1.403f, -1.708f, -0.795f, -0.801f, 0.392f, 0.589f, 1.307f, 1.612f, 3.114f, - 1.529f, 3.168f, 5.289f, 7.496f, 8.275f, 9.547f, 11.295f, 13.231f, 14.732f, 13.282f, - 13.606f -},{ --29.534f,-30.340f,-31.107f,-32.730f,-34.789f,-36.601f,-38.008f,-40.731f,-43.863f,-46.744f, --49.899f,-52.327f,-53.785f,-54.980f,-55.096f,-53.961f,-51.474f,-49.905f,-50.193f,-49.673f, --47.395f,-45.696f,-45.212f,-43.913f,-44.243f,-44.687f,-43.705f,-40.020f,-37.050f,-34.451f, --31.758f,-29.236f,-26.908f,-24.689f,-22.848f,-21.268f,-19.897f,-18.963f,-18.395f,-17.761f, --17.140f,-16.644f,-16.725f,-16.518f,-16.034f,-15.787f,-15.119f,-14.911f,-14.478f,-11.652f, - -7.415f, -2.647f, 1.500f, 3.788f, 4.607f, 6.031f, 7.848f, 9.067f, 12.231f, 16.132f, - 19.181f, 20.477f, 22.345f, 24.273f, 26.335f, 28.757f, 32.829f, 37.308f, 41.656f, 44.356f, - 48.264f, 52.441f, 53.834f, 56.827f, 58.842f, 61.251f, 63.732f, 66.734f, 69.328f, 72.354f, - 74.296f, 74.611f, 74.775f, 76.373f, 81.409f, 80.506f, 76.549f, 77.502f, 76.485f, 72.873f, - 72.123f, 70.214f, 68.123f, 66.630f, 65.757f, 64.866f, 63.767f, 62.616f, 61.590f, 57.357f, - 51.897f, 40.894f, 48.303f, 54.110f, 54.450f, 53.704f, 52.964f, 52.326f, 51.560f, 50.886f, - 50.196f, 48.993f, 47.185f, 40.385f, 34.846f, 32.709f, 35.251f, 33.341f, 32.239f, 23.492f, - 22.705f, 24.353f, 24.602f, 24.106f, 22.765f, 20.461f, 16.163f, 16.178f, 24.233f, 24.724f, - 23.564f, 17.019f, 20.894f, 30.896f, 31.694f, 28.042f, 25.718f, 24.531f, 22.783f, 22.142f, - 21.642f, 20.149f, 18.152f, 17.787f, 17.345f, 16.463f, 15.146f, 14.853f, 13.287f, 12.544f, - 12.561f, 12.656f, 12.119f, 8.851f, 7.767f, 6.376f, 4.609f, 4.586f, 0.232f, 0.575f, - -0.819f, -1.267f, -1.396f, -0.567f, -0.435f, 0.458f, 0.846f, 1.125f, 1.746f, 3.017f, - 1.941f, 2.971f, 5.103f, 7.773f, 8.516f, 9.527f, 10.976f, 12.954f, 14.661f, 13.288f, - 13.606f -},{ --29.534f,-30.351f,-31.142f,-32.795f,-34.836f,-36.639f,-38.039f,-40.517f,-43.928f,-47.002f, --49.902f,-52.931f,-54.576f,-55.575f,-55.717f,-54.608f,-52.416f,-50.890f,-51.097f,-51.155f, --49.271f,-47.397f,-46.396f,-44.743f,-44.962f,-44.907f,-43.834f,-39.812f,-36.830f,-34.235f, --31.370f,-28.920f,-26.633f,-24.616f,-22.773f,-21.034f,-19.783f,-18.868f,-18.243f,-17.778f, --17.149f,-16.506f,-16.072f,-15.894f,-15.508f,-15.291f,-14.965f,-14.091f,-11.623f, -5.904f, - -1.966f, -1.034f, 2.961f, 5.494f, 6.394f, 8.151f, 9.736f, 11.503f, 13.151f, 16.612f, - 20.860f, 22.821f, 24.746f, 26.489f, 28.282f, 31.639f, 34.710f, 39.102f, 43.323f, 46.689f, - 52.184f, 55.547f, 56.731f, 58.534f, 61.832f, 63.994f, 66.365f, 65.139f, 68.005f, 71.806f, - 73.661f, 74.385f, 74.530f, 77.424f, 82.389f, 76.693f, 74.999f, 78.182f, 77.568f, 73.336f, - 70.758f, 69.128f, 66.941f, 65.625f, 64.598f, 63.652f, 62.990f, 61.977f, 59.281f, 54.723f, - 53.264f, 46.358f, 38.267f, 52.992f, 54.722f, 54.827f, 53.655f, 52.603f, 51.219f, 50.117f, - 49.238f, 47.551f, 42.930f, 32.943f, 28.743f, 37.631f, 39.188f, 33.008f, 30.191f, 30.224f, - 29.865f, 28.874f, 28.507f, 27.625f, 26.909f, 23.573f, 21.916f, 18.006f, 16.680f, 15.470f, - 14.508f, 11.211f, 14.635f, 28.293f, 30.541f, 27.386f, 24.122f, 21.640f, 21.620f, 21.172f, - 20.994f, 18.447f, 17.606f, 17.307f, 16.508f, 15.917f, 16.248f, 14.998f, 13.491f, 12.839f, - 13.697f, 13.424f, 12.246f, 9.730f, 8.719f, 7.335f, 5.482f, 5.797f, 0.770f, 0.913f, - -0.553f, -1.103f, -0.901f, -0.285f, 0.192f, 0.545f, 0.983f, 1.191f, 1.989f, 2.885f, - 2.142f, 2.658f, 4.623f, 7.647f, 8.560f, 9.341f, 10.542f, 12.584f, 14.545f, 13.291f, - 13.606f -},{ --29.534f,-30.361f,-31.176f,-32.852f,-34.874f,-36.604f,-38.075f,-40.332f,-44.039f,-47.363f, --49.932f,-53.320f,-55.335f,-56.158f,-56.236f,-55.253f,-53.435f,-51.967f,-51.576f,-51.889f, --50.802f,-48.425f,-47.654f,-46.514f,-45.307f,-45.162f,-43.365f,-39.501f,-36.820f,-33.808f, --31.017f,-28.716f,-26.385f,-24.101f,-22.204f,-20.677f,-19.556f,-18.661f,-17.933f,-17.367f, --17.072f,-16.623f,-16.295f,-16.132f,-15.289f,-14.607f,-13.007f, -8.970f, -5.565f, -2.332f, - -1.725f, 0.795f, 3.864f, 6.684f, 7.909f, 9.682f, 11.768f, 14.017f, 16.500f, 18.355f, - 22.339f, 24.518f, 27.358f, 29.446f, 31.177f, 34.457f, 38.297f, 42.290f, 45.796f, 49.852f, - 55.249f, 58.179f, 59.535f, 61.114f, 62.777f, 65.219f, 64.652f, 64.335f, 66.948f, 70.070f, - 70.927f, 74.402f, 73.796f, 76.712f, 80.519f, 70.403f, 75.182f, 78.842f, 78.306f, 73.276f, - 69.202f, 68.039f, 66.229f, 64.783f, 63.980f, 63.016f, 62.586f, 60.859f, 60.107f, 55.520f, - 55.253f, 50.752f, 35.438f, 45.781f, 54.949f, 54.991f, 53.682f, 52.075f, 49.936f, 47.996f, - 46.608f, 43.811f, 32.953f, 26.550f, 36.126f, 38.298f, 38.387f, 35.144f, 32.397f, 31.585f, - 29.962f, 28.313f, 28.187f, 27.310f, 25.496f, 23.421f, 22.400f, 22.151f, 21.160f, 19.808f, - 16.913f, 10.494f, 10.981f, 28.077f, 30.534f, 25.606f, 23.080f, 21.134f, 21.833f, 21.010f, - 19.219f, 17.471f, 16.397f, 15.738f, 15.315f, 15.957f, 17.383f, 15.792f, 14.006f, 13.264f, - 13.741f, 13.581f, 12.285f, 10.999f, 8.699f, 8.831f, 6.992f, 4.531f, 1.810f, 1.168f, - -0.135f, -0.725f, -0.504f, -0.268f, 0.514f, 0.729f, 1.017f, 1.553f, 2.135f, 2.927f, - 2.215f, 2.314f, 4.017f, 7.153f, 8.425f, 9.017f, 10.030f, 12.142f, 14.385f, 13.291f, - 13.606f -},{ --29.534f,-30.370f,-31.208f,-32.902f,-34.910f,-36.511f,-38.112f,-40.220f,-44.085f,-47.644f, --49.969f,-53.375f,-55.980f,-56.779f,-56.816f,-56.079f,-54.528f,-53.127f,-51.844f,-51.516f, --51.345f,-50.206f,-48.871f,-47.976f,-45.358f,-45.309f,-42.676f,-39.439f,-36.663f,-33.808f, --30.913f,-28.366f,-25.951f,-24.076f,-22.261f,-20.507f,-19.318f,-19.190f,-18.810f,-18.222f, --17.887f,-17.221f,-15.733f,-14.937f,-13.966f,-13.726f, -9.746f, -5.227f, -1.927f, -1.377f, - -1.002f, 1.953f, 6.677f, 8.790f, 9.506f, 11.757f, 14.161f, 16.737f, 20.025f, 21.563f, - 24.109f, 26.228f, 29.005f, 31.683f, 34.558f, 37.836f, 41.954f, 46.097f, 49.123f, 52.548f, - 56.329f, 58.522f, 59.662f, 61.834f, 62.054f, 62.830f, 63.916f, 65.670f, 67.879f, 70.213f, - 69.206f, 70.884f, 75.442f, 78.264f, 72.099f, 68.271f, 77.267f, 79.405f, 77.637f, 72.968f, - 67.927f, 66.999f, 65.612f, 64.170f, 63.002f, 61.916f, 61.244f, 60.420f, 59.754f, 56.006f, - 53.500f, 50.458f, 41.714f, 31.760f, 42.874f, 49.670f, 52.657f, 48.828f, 44.180f, 42.227f, - 40.519f, 34.819f, 25.733f, 31.228f, 36.730f, 35.254f, 36.369f, 33.784f, 32.985f, 30.191f, - 28.272f, 26.356f, 26.036f, 25.410f, 24.005f, 21.937f, 22.024f, 21.822f, 22.238f, 22.030f, - 20.693f, 16.296f, 8.986f, 21.354f, 30.973f, 25.708f, 23.014f, 20.454f, 19.800f, 20.014f, - 18.812f, 17.495f, 16.462f, 15.938f, 15.827f, 16.945f, 17.620f, 17.037f, 14.855f, 13.892f, - 13.994f, 13.605f, 12.497f, 10.926f, 9.416f, 9.148f, 8.181f, 2.419f, 2.602f, 1.590f, - 0.607f, -0.074f, -0.259f, -0.370f, 0.345f, 1.008f, 1.176f, 1.947f, 2.073f, 3.067f, - 2.286f, 2.029f, 3.476f, 6.420f, 8.161f, 8.603f, 9.484f, 11.649f, 14.188f, 13.289f, - 13.606f -},{ --29.534f,-30.378f,-31.239f,-32.941f,-34.953f,-36.390f,-38.131f,-40.190f,-44.019f,-47.717f, --49.975f,-53.179f,-56.393f,-57.339f,-57.463f,-56.842f,-55.563f,-54.319f,-52.719f,-51.941f, --51.295f,-51.382f,-49.619f,-48.642f,-45.584f,-45.807f,-42.436f,-39.433f,-36.443f,-33.247f, --30.497f,-28.026f,-25.964f,-23.827f,-22.021f,-21.185f,-20.738f,-20.288f,-19.384f,-18.356f, --17.995f,-17.099f,-14.772f,-13.352f,-13.744f,-13.147f, -8.084f, -4.055f, -1.341f, -1.036f, - -0.032f, 1.627f, 6.520f, 12.393f, 11.819f, 13.558f, 16.575f, 18.869f, 21.657f, 24.488f, - 26.035f, 27.792f, 30.148f, 33.940f, 38.071f, 41.330f, 45.500f, 48.824f, 51.405f, 53.939f, - 56.609f, 58.355f, 59.050f, 59.333f, 61.043f, 63.347f, 64.844f, 64.939f, 67.210f, 69.299f, - 69.072f, 77.019f, 84.229f, 73.312f, 71.121f, 73.513f, 79.020f, 79.868f, 77.597f, 72.313f, - 66.041f, 66.345f, 65.300f, 63.749f, 62.464f, 61.276f, 60.137f, 59.348f, 58.682f, 54.071f, - 51.226f, 49.687f, 46.808f, 39.501f, 32.106f, 36.966f, 39.536f, 38.184f, 36.946f, 34.772f, - 31.172f, 29.460f, 32.055f, 35.019f, 35.440f, 34.104f, 33.829f, 32.244f, 30.172f, 27.900f, - 25.778f, 24.448f, 24.022f, 22.985f, 21.476f, 20.964f, 20.797f, 20.322f, 20.746f, 21.475f, - 20.805f, 18.685f, 9.999f, 10.537f, 29.627f, 26.460f, 22.913f, 21.082f, 19.957f, 19.841f, - 18.778f, 17.572f, 17.054f, 16.656f, 16.739f, 17.706f, 17.961f, 17.228f, 15.354f, 14.278f, - 14.142f, 14.024f, 12.585f, 10.866f, 10.537f, 8.850f, 8.183f, 2.301f, 3.204f, 2.229f, - 1.419f, 0.518f, 0.048f, -0.198f, 0.161f, 1.247f, 1.505f, 2.101f, 1.943f, 3.096f, - 2.449f, 1.867f, 3.130f, 5.626f, 7.838f, 8.156f, 8.949f, 11.131f, 13.957f, 13.284f, - 13.606f -},{ --29.534f,-30.384f,-31.268f,-32.971f,-35.010f,-36.282f,-38.105f,-40.213f,-43.888f,-47.631f, --49.953f,-52.945f,-56.567f,-57.646f,-57.899f,-57.268f,-56.379f,-55.452f,-54.004f,-53.401f, --52.058f,-51.236f,-50.563f,-49.336f,-45.865f,-46.246f,-42.382f,-39.188f,-36.054f,-33.000f, --30.493f,-27.966f,-25.598f,-23.751f,-22.907f,-22.068f,-21.246f,-19.732f,-19.060f,-18.169f, --17.479f,-16.248f,-13.842f,-12.275f,-13.746f,-13.252f, -9.376f, -5.051f, -1.741f, -0.259f, - 0.795f, 2.693f, 6.489f, 13.516f, 15.704f, 16.853f, 19.131f, 21.994f, 23.708f, 25.351f, - 27.663f, 30.086f, 32.165f, 35.211f, 39.151f, 44.317f, 47.382f, 49.758f, 52.111f, 55.042f, - 56.504f, 57.766f, 57.734f, 60.471f, 62.880f, 64.295f, 63.626f, 64.868f, 66.536f, 68.378f, - 75.329f, 82.188f, 74.844f, 59.791f, 69.821f, 78.240f, 80.567f, 79.443f, 76.228f, 71.140f, - 65.546f, 65.905f, 64.155f, 62.815f, 62.089f, 60.936f, 59.464f, 58.423f, 58.680f, 54.482f, - 51.174f, 47.426f, 47.108f, 46.510f, 42.883f, 39.610f, 36.164f, 31.384f, 30.938f, 32.978f, - 35.643f, 37.633f, 36.921f, 35.983f, 33.908f, 32.339f, 32.055f, 29.478f, 27.598f, 24.873f, - 23.454f, 21.845f, 21.732f, 20.817f, 19.496f, 18.957f, 18.808f, 18.371f, 18.620f, 19.890f, - 19.799f, 18.743f, 13.798f, 2.790f, 18.909f, 27.966f, 23.174f, 21.244f, 19.911f, 20.159f, - 19.313f, 18.127f, 17.826f, 17.759f, 17.725f, 18.109f, 18.466f, 17.515f, 15.661f, 15.015f, - 14.449f, 14.532f, 12.938f, 11.658f, 10.571f, 9.672f, 7.048f, 3.501f, 3.700f, 2.780f, - 1.893f, 0.861f, 0.387f, 0.180f, 0.358f, 1.271f, 1.829f, 2.007f, 2.041f, 2.921f, - 2.717f, 1.837f, 3.005f, 4.942f, 7.524f, 7.729f, 8.461f, 10.611f, 13.699f, 13.277f, - 13.606f -},{ --29.534f,-30.388f,-31.295f,-32.990f,-35.087f,-36.227f,-38.001f,-40.226f,-43.785f,-47.608f, --49.974f,-52.850f,-56.596f,-57.632f,-57.927f,-57.477f,-56.966f,-56.416f,-55.264f,-54.709f, --53.765f,-51.843f,-51.667f,-49.320f,-45.557f,-45.860f,-42.172f,-39.020f,-35.996f,-33.130f, --30.233f,-27.383f,-25.508f,-24.483f,-23.318f,-21.769f,-20.739f,-19.674f,-18.669f,-17.609f, --16.865f,-15.768f,-13.499f,-12.924f,-13.567f,-12.393f,-10.685f, -8.223f, -5.100f, -2.531f, - 0.169f, 0.793f, 7.076f, 14.101f, 18.586f, 19.524f, 22.141f, 24.827f, 25.988f, 27.243f, - 28.218f, 30.633f, 33.234f, 36.212f, 40.265f, 45.601f, 47.680f, 50.330f, 53.604f, 55.296f, - 57.346f, 58.048f, 58.738f, 61.140f, 63.270f, 64.072f, 62.308f, 64.648f, 65.337f, 69.000f, - 78.171f, 77.721f, 67.704f, 58.705f, 74.951f, 80.377f, 80.531f, 78.162f, 73.807f, 68.897f, - 62.062f, 62.435f, 61.957f, 60.985f, 59.461f, 59.093f, 57.703f, 58.455f, 57.721f, 50.707f, - 46.013f, 45.657f, 46.347f, 45.521f, 44.324f, 43.449f, 43.177f, 40.059f, 39.007f, 38.277f, - 41.115f, 36.670f, 37.272f, 35.485f, 31.894f, 30.936f, 28.186f, 27.698f, 24.483f, 22.705f, - 21.181f, 19.504f, 19.775f, 17.959f, 17.018f, 16.658f, 16.385f, 15.654f, 16.293f, 17.685f, - 18.389f, 18.468f, 16.468f, 5.614f, 2.230f, 24.029f, 23.699f, 21.219f, 19.886f, 20.278f, - 20.009f, 18.450f, 18.834f, 18.235f, 18.146f, 18.838f, 18.934f, 17.702f, 15.996f, 16.155f, - 15.302f, 14.921f, 13.570f, 11.960f, 10.385f, 9.259f, 5.336f, 4.613f, 4.289f, 3.231f, - 2.066f, 1.198f, 0.496f, 0.458f, 0.729f, 1.069f, 2.050f, 1.866f, 2.487f, 2.644f, - 3.012f, 1.891f, 3.025f, 4.477f, 7.267f, 7.366f, 8.052f, 10.114f, 13.421f, 13.268f, - 13.606f -},{ --29.534f,-30.392f,-31.321f,-32.999f,-35.187f,-36.257f,-37.793f,-40.149f,-43.769f,-47.890f, --50.124f,-52.912f,-56.544f,-57.431f,-57.740f,-57.731f,-57.454f,-57.054f,-56.359f,-55.803f, --54.940f,-52.839f,-51.859f,-48.891f,-45.244f,-45.580f,-42.018f,-38.840f,-35.983f,-32.693f, --29.654f,-27.227f,-25.791f,-24.298f,-23.024f,-21.523f,-20.637f,-19.599f,-19.055f,-18.075f, --17.065f,-14.012f,-14.281f,-14.314f,-13.509f,-11.796f, -9.014f, -8.741f, -6.905f, -4.609f, - -2.335f, -0.889f, 6.400f, 11.825f, 16.643f, 20.421f, 24.353f, 26.895f, 28.226f, 29.576f, - 31.691f, 32.827f, 35.217f, 38.001f, 42.150f, 46.178f, 49.255f, 51.466f, 53.438f, 55.637f, - 57.400f, 58.049f, 60.027f, 62.759f, 64.178f, 63.429f, 62.212f, 64.435f, 65.248f, 71.548f, - 78.443f, 78.413f, 71.729f, 64.837f, 81.327f, 81.823f, 79.809f, 77.093f, 72.988f, 64.406f, - 63.325f, 62.227f, 59.971f, 57.337f, 57.120f, 54.925f, 56.729f, 52.586f, 52.293f, 55.623f, - 44.975f, 44.268f, 44.558f, 44.053f, 43.485f, 43.862f, 42.363f, 44.069f, 40.858f, 38.105f, - 40.881f, 36.493f, 35.874f, 33.524f, 32.656f, 28.007f, 27.125f, 25.232f, 22.181f, 21.304f, - 19.332f, 17.630f, 16.977f, 16.208f, 15.809f, 14.782f, 13.999f, 13.672f, 13.400f, 15.650f, - 16.643f, 17.274f, 16.992f, 12.132f, -2.953f, 13.590f, 25.003f, 21.549f, 20.172f, 21.001f, - 20.277f, 19.053f, 19.310f, 18.430f, 18.782f, 19.310f, 19.081f, 17.595f, 16.517f, 17.164f, - 16.206f, 15.408f, 14.059f, 11.874f, 10.468f, 7.218f, 4.385f, 5.277f, 4.652f, 3.570f, - 2.234f, 1.498f, 0.369f, 0.655f, 0.904f, 0.864f, 2.243f, 1.849f, 3.023f, 2.452f, - 3.203f, 1.950f, 3.066f, 4.260f, 7.082f, 7.093f, 7.737f, 9.660f, 13.129f, 13.256f, - 13.606f -},{ --29.534f,-30.394f,-31.344f,-32.998f,-35.311f,-36.381f,-37.474f,-39.902f,-43.795f,-48.532f, --50.417f,-53.032f,-56.370f,-57.163f,-57.616f,-58.012f,-57.871f,-57.323f,-56.770f,-56.504f, --55.436f,-53.456f,-51.989f,-48.729f,-45.677f,-45.432f,-41.785f,-38.649f,-35.359f,-31.834f, --29.110f,-27.160f,-25.536f,-24.310f,-23.131f,-21.965f,-21.495f,-20.159f,-19.168f,-18.277f, --16.904f,-15.099f,-15.038f,-14.318f,-13.194f,-11.771f, -8.861f, -8.111f, -6.719f, -4.229f, - -2.061f, 0.103f, 2.491f, 5.584f, 9.663f, 17.015f, 22.309f, 26.023f, 29.709f, 32.306f, - 33.923f, 34.792f, 38.060f, 41.217f, 44.679f, 46.978f, 49.060f, 50.727f, 52.929f, 55.249f, - 57.341f, 58.214f, 60.055f, 62.576f, 63.902f, 61.965f, 62.609f, 64.334f, 65.556f, 74.733f, - 76.643f, 77.650f, 72.816f, 66.839f, 74.534f, 79.819f, 77.861f, 75.505f, 70.092f, 61.828f, - 61.307f, 59.178f, 57.008f, 55.745f, 54.986f, 53.599f, 53.349f, 52.298f, 49.915f, 46.676f, - 43.754f, 43.432f, 42.601f, 42.164f, 41.723f, 41.648f, 40.585f, 40.425f, 42.708f, 37.783f, - 37.463f, 33.707f, 34.043f, 30.912f, 29.701f, 27.108f, 26.002f, 23.168f, 20.988f, 19.571f, - 17.296f, 16.162f, 15.796f, 14.445f, 13.714f, 12.357f, 11.705f, 11.448f, 11.682f, 13.378f, - 14.530f, 15.728f, 16.401f, 14.661f, 2.040f, 1.264f, 23.752f, 22.533f, 20.839f, 20.756f, - 21.130f, 19.485f, 19.600f, 18.940f, 19.176f, 19.600f, 18.824f, 17.249f, 16.724f, 17.571f, - 16.689f, 15.637f, 14.215f, 11.917f, 10.113f, 6.852f, 5.388f, 5.549f, 4.667f, 3.567f, - 2.382f, 1.407f, 0.368f, 0.934f, 0.967f, 0.913f, 2.420f, 1.972f, 3.226f, 2.438f, - 3.179f, 1.952f, 3.025f, 4.242f, 6.956f, 6.914f, 7.520f, 9.266f, 12.831f, 13.243f, - 13.606f -},{ --29.534f,-30.395f,-31.365f,-32.990f,-35.455f,-36.586f,-37.055f,-39.441f,-43.718f,-49.293f, --50.747f,-53.104f,-56.042f,-56.766f,-57.479f,-58.163f,-58.088f,-57.464f,-56.676f,-56.626f, --56.166f,-54.280f,-52.729f,-48.704f,-47.382f,-44.984f,-41.520f,-38.397f,-34.537f,-31.317f, --29.148f,-27.293f,-26.181f,-25.052f,-23.811f,-22.421f,-21.053f,-19.879f,-18.837f,-17.904f, --16.827f,-16.147f,-14.954f,-14.126f,-12.627f,-11.113f, -9.269f, -7.501f, -5.929f, -3.211f, - -0.672f, 1.823f, 4.141f, 6.553f, 9.137f, 11.270f, 17.846f, 25.087f, 29.164f, 32.950f, - 35.543f, 37.332f, 40.406f, 43.171f, 45.007f, 46.761f, 48.667f, 50.934f, 53.755f, 56.034f, - 57.519f, 59.017f, 59.729f, 62.952f, 63.127f, 61.397f, 62.969f, 64.227f, 65.824f, 73.960f, - 74.346f, 77.115f, 68.732f, 69.737f, 60.484f, 74.007f, 74.172f, 71.220f, 66.444f, 60.487f, - 59.258f, 57.633f, 55.761f, 54.288f, 53.320f, 53.061f, 53.088f, 55.287f, 52.482f, 51.185f, - 43.767f, 41.915f, 41.395f, 40.626f, 39.626f, 40.090f, 41.066f, 41.043f, 37.612f, 36.628f, - 35.701f, 32.784f, 32.218f, 29.256f, 27.976f, 25.891f, 24.300f, 22.249f, 18.360f, 17.353f, - 15.546f, 14.256f, 13.163f, 12.752f, 11.120f, 9.939f, 10.088f, 9.817f, 10.165f, 11.420f, - 12.275f, 13.696f, 15.053f, 14.407f, 8.598f, -3.962f, 17.184f, 24.712f, 21.171f, 21.001f, - 21.200f, 20.374f, 20.151f, 19.769f, 19.685f, 19.823f, 18.395f, 16.526f, 16.309f, 17.339f, - 16.828f, 16.014f, 14.389f, 11.642f, 9.552f, 7.702f, 6.608f, 5.742f, 4.745f, 3.319f, - 2.318f, 1.119f, 0.739f, 1.206f, 1.298f, 1.207f, 2.447f, 2.172f, 2.952f, 2.565f, - 2.912f, 1.887f, 2.863f, 4.331f, 6.853f, 6.815f, 7.394f, 8.944f, 12.533f, 13.228f, - 13.606f -},{ --29.534f,-30.394f,-31.382f,-32.974f,-35.610f,-36.832f,-36.571f,-38.774f,-43.372f,-49.722f, --50.930f,-53.064f,-55.638f,-56.178f,-57.066f,-58.194f,-58.179f,-57.740f,-57.156f,-57.164f, --56.660f,-54.170f,-52.627f,-48.987f,-48.622f,-44.251f,-41.112f,-37.632f,-34.150f,-31.512f, --29.671f,-28.442f,-26.879f,-25.342f,-23.925f,-22.469f,-20.976f,-20.232f,-18.537f,-17.736f, --16.768f,-16.152f,-14.766f,-13.501f,-11.878f,-10.654f, -8.881f, -6.904f, -4.811f, -1.846f, - 0.584f, 2.886f, 5.426f, 8.001f, 10.500f, 13.288f, 15.355f, 20.192f, 27.127f, 30.590f, - 34.641f, 37.059f, 39.827f, 42.639f, 44.581f, 46.816f, 47.857f, 50.240f, 53.183f, 55.582f, - 56.362f, 57.365f, 59.320f, 61.311f, 60.686f, 61.770f, 63.384f, 64.090f, 66.448f, 73.717f, - 73.064f, 73.608f, 70.623f, 68.387f, 57.041f, 57.793f, 65.784f, 67.300f, 63.264f, 59.829f, - 58.042f, 56.552f, 56.291f, 54.342f, 52.939f, 52.453f, 51.590f, 51.954f, 48.978f, 45.814f, - 42.294f, 41.176f, 39.775f, 39.453f, 38.428f, 38.182f, 36.715f, 36.857f, 36.275f, 35.401f, - 32.993f, 32.574f, 29.583f, 31.460f, 24.881f, 24.480f, 21.805f, 18.146f, 17.478f, 15.607f, - 13.995f, 12.976f, 12.113f, 10.497f, 8.780f, 8.229f, 8.067f, 7.842f, 8.406f, 9.140f, - 10.125f, 11.617f, 12.977f, 13.504f, 11.454f, 2.664f, 6.863f, 23.648f, 23.905f, 21.689f, - 21.627f, 21.637f, 20.960f, 20.570f, 20.067f, 19.623f, 17.846f, 16.490f, 16.223f, 16.875f, - 16.739f, 16.317f, 14.033f, 11.388f, 9.600f, 8.092f, 6.938f, 5.805f, 4.815f, 3.250f, - 2.184f, 1.140f, 1.212f, 1.332f, 1.958f, 1.454f, 2.279f, 2.366f, 2.508f, 2.745f, - 2.483f, 1.798f, 2.616f, 4.430f, 6.730f, 6.769f, 7.339f, 8.700f, 12.242f, 13.211f, - 13.606f -},{ --29.534f,-30.392f,-31.397f,-32.954f,-35.767f,-37.060f,-36.065f,-37.978f,-42.687f,-49.419f, --50.859f,-52.867f,-55.250f,-55.573f,-56.490f,-58.190f,-58.498f,-58.103f,-57.807f,-57.766f, --56.254f,-53.356f,-51.760f,-48.913f,-47.772f,-43.792f,-40.613f,-37.207f,-34.779f,-32.216f, --30.815f,-28.904f,-26.912f,-25.423f,-24.065f,-22.391f,-21.455f,-19.819f,-19.119f,-17.623f, --17.073f,-15.955f,-14.968f,-13.030f,-11.506f, -9.699f, -8.198f, -6.422f, -3.933f, -1.480f, - 1.424f, 4.182f, 6.456f, 9.118f, 11.739f, 14.455f, 17.087f, 19.427f, 22.107f, 25.284f, - 29.681f, 34.338f, 37.915f, 38.816f, 41.829f, 42.892f, 44.564f, 50.385f, 51.909f, 52.765f, - 54.242f, 56.859f, 59.387f, 61.252f, 61.415f, 62.294f, 63.552f, 64.741f, 66.671f, 71.572f, - 72.596f, 73.430f, 69.428f, 60.354f, 56.169f, 59.515f, 63.466f, 61.892f, 61.641f, 58.955f, - 58.737f, 57.493f, 56.181f, 55.420f, 53.592f, 53.648f, 52.024f, 49.894f, 47.851f, 42.841f, - 41.319f, 40.185f, 38.818f, 37.737f, 36.860f, 36.300f, 34.886f, 37.228f, 33.466f, 33.054f, - 31.367f, 28.862f, 27.028f, 25.091f, 24.308f, 21.127f, 19.027f, 16.216f, 15.066f, 13.008f, - 12.329f, 11.083f, 10.854f, 8.889f, 7.339f, 6.403f, 5.801f, 5.991f, 6.299f, 7.086f, - 8.137f, 9.727f, 11.112f, 12.341f, 12.233f, 9.904f, 3.587f, 16.063f, 24.990f, 24.642f, - 22.214f, 22.687f, 22.057f, 21.282f, 20.494f, 19.502f, 18.303f, 17.045f, 16.835f, 16.330f, - 16.598f, 16.552f, 13.956f, 12.087f, 10.032f, 8.176f, 7.260f, 5.794f, 4.856f, 3.481f, - 2.219f, 1.381f, 1.358f, 1.475f, 2.585f, 1.425f, 2.101f, 2.463f, 2.342f, 2.943f, - 2.033f, 1.740f, 2.364f, 4.473f, 6.556f, 6.741f, 7.333f, 8.537f, 11.963f, 13.194f, - 13.606f -},{ --29.534f,-30.389f,-31.408f,-32.932f,-35.912f,-37.208f,-35.579f,-37.182f,-41.772f,-48.318f, --50.631f,-52.505f,-54.785f,-55.166f,-56.252f,-58.147f,-59.067f,-58.404f,-57.478f,-57.162f, --55.623f,-53.494f,-51.325f,-48.472f,-47.110f,-43.714f,-40.504f,-37.825f,-35.076f,-32.830f, --30.599f,-28.857f,-27.569f,-25.995f,-24.467f,-23.101f,-21.539f,-19.969f,-19.148f,-17.653f, --16.905f,-15.865f,-14.903f,-12.999f,-11.024f, -9.272f, -7.395f, -5.483f, -3.265f, -0.666f, - 2.019f, 4.634f, 7.433f, 10.294f, 13.044f, 15.201f, 17.792f, 20.522f, 23.418f, 26.153f, - 29.254f, 31.154f, 35.362f, 37.144f, 39.726f, 43.125f, 44.463f, 48.001f, 50.751f, 52.141f, - 54.883f, 57.380f, 60.218f, 61.200f, 61.294f, 62.658f, 64.575f, 66.960f, 64.557f, 70.132f, - 71.217f, 71.217f, 68.921f, 63.079f, 71.228f, 63.989f, 63.228f, 63.412f, 61.503f, 59.566f, - 59.055f, 57.469f, 56.271f, 54.868f, 54.051f, 51.676f, 50.077f, 50.381f, 48.956f, 43.238f, - 41.325f, 39.119f, 37.766f, 36.131f, 34.170f, 34.603f, 36.304f, 32.430f, 32.110f, 31.105f, - 28.303f, 29.737f, 25.505f, 24.408f, 21.467f, 19.111f, 16.988f, 15.327f, 12.883f, 11.180f, - 10.753f, 10.036f, 9.101f, 7.141f, 5.401f, 5.265f, 4.649f, 4.140f, 4.480f, 5.321f, - 6.318f, 7.467f, 9.149f, 10.850f, 11.414f, 11.631f, 10.242f, 4.343f, 15.253f, 24.598f, - 23.801f, 22.672f, 23.233f, 22.708f, 21.862f, 20.932f, 19.962f, 18.131f, 16.423f, 16.399f, - 16.030f, 16.190f, 14.672f, 12.720f, 10.565f, 8.414f, 7.138f, 5.877f, 5.002f, 3.706f, - 2.331f, 1.519f, 1.249f, 1.873f, 2.883f, 1.216f, 2.076f, 2.424f, 2.599f, 3.174f, - 1.680f, 1.736f, 2.187f, 4.437f, 6.318f, 6.700f, 7.349f, 8.451f, 11.702f, 13.175f, - 13.606f -},{ --29.534f,-30.385f,-31.415f,-32.910f,-36.034f,-37.223f,-35.143f,-36.538f,-40.896f,-46.791f, --50.555f,-52.118f,-54.010f,-54.806f,-56.516f,-58.164f,-59.280f,-58.590f,-57.002f,-56.657f, --55.562f,-53.495f,-50.855f,-48.758f,-47.182f,-43.596f,-40.966f,-37.889f,-34.775f,-32.778f, --30.728f,-29.161f,-27.590f,-26.179f,-24.533f,-23.115f,-22.365f,-20.197f,-18.778f,-17.631f, --16.710f,-15.788f,-14.516f,-12.718f,-10.742f, -8.941f, -7.245f, -4.754f, -2.496f, 0.079f, - 2.774f, 5.304f, 8.266f, 12.216f, 13.809f, 16.270f, 18.723f, 24.360f, 23.688f, 28.792f, - 29.404f, 32.841f, 35.947f, 36.807f, 39.574f, 41.463f, 45.821f, 48.459f, 51.076f, 53.862f, - 55.290f, 57.501f, 59.940f, 61.477f, 61.505f, 63.263f, 66.109f, 68.383f, 67.145f, 65.433f, - 69.797f, 70.327f, 67.709f, 69.853f, 64.831f, 65.911f, 64.504f, 62.746f, 61.083f, 59.227f, - 58.609f, 56.769f, 54.858f, 54.431f, 52.231f, 51.181f, 49.422f, 48.415f, 45.549f, 42.550f, - 40.061f, 37.306f, 36.089f, 33.783f, 36.494f, 30.606f, 30.915f, 31.134f, 30.479f, 28.554f, - 27.953f, 25.702f, 23.242f, 22.647f, 19.893f, 16.735f, 14.395f, 13.285f, 11.049f, 9.716f, - 8.923f, 8.763f, 7.561f, 5.713f, 4.199f, 4.093f, 3.303f, 2.369f, 2.623f, 3.684f, - 4.669f, 5.614f, 6.704f, 8.674f, 9.848f, 11.402f, 12.119f, 9.694f, 2.410f, 12.253f, - 23.850f, 24.505f, 23.835f, 23.454f, 22.146f, 21.212f, 20.817f, 19.119f, 17.085f, 16.167f, - 14.926f, 14.823f, 14.479f, 12.798f, 11.023f, 8.861f, 6.936f, 6.019f, 5.102f, 3.804f, - 2.421f, 1.647f, 1.259f, 2.296f, 2.829f, 1.092f, 2.129f, 2.365f, 3.036f, 3.433f, - 1.450f, 1.756f, 2.127f, 4.341f, 6.029f, 6.621f, 7.365f, 8.435f, 11.464f, 13.156f, - 13.606f -},{ --29.534f,-30.380f,-31.418f,-32.891f,-36.120f,-37.079f,-34.765f,-36.177f,-40.384f,-45.493f, --50.965f,-52.060f,-52.914f,-54.095f,-56.685f,-58.421f,-58.708f,-58.441f,-57.093f,-56.969f, --55.759f,-53.147f,-50.545f,-49.749f,-46.817f,-43.892f,-41.256f,-37.409f,-34.983f,-32.927f, --31.111f,-30.001f,-32.141f,-30.436f,-25.220f,-23.176f,-21.904f,-20.177f,-18.158f,-17.521f, --16.514f,-15.482f,-13.859f,-12.131f,-10.483f, -8.318f, -6.403f, -4.435f, -1.993f, 0.827f, - 3.262f, 6.108f, 8.715f, 11.343f, 14.024f, 16.834f, 19.161f, 21.978f, 24.825f, 27.699f, - 29.943f, 32.126f, 34.854f, 37.152f, 40.198f, 43.441f, 46.622f, 48.959f, 51.893f, 53.633f, - 54.965f, 57.306f, 58.911f, 60.275f, 62.753f, 63.161f, 64.713f, 67.655f, 68.195f, 69.023f, - 67.369f, 68.518f, 69.513f, 67.249f, 62.507f, 65.782f, 63.718f, 61.044f, 59.583f, 57.938f, - 56.400f, 54.978f, 54.078f, 52.971f, 52.570f, 50.659f, 50.214f, 45.774f, 44.293f, 41.693f, - 39.242f, 38.501f, 34.486f, 34.831f, 33.810f, 30.169f, 29.643f, 29.924f, 28.384f, 26.191f, - 26.807f, 25.238f, 21.873f, 20.575f, 19.196f, 15.106f, 12.612f, 11.141f, 9.342f, 8.517f, - 7.535f, 7.469f, 6.785f, 5.133f, 3.661f, 2.623f, 2.109f, 1.026f, 0.842f, 1.993f, - 2.876f, 3.884f, 4.802f, 6.917f, 8.227f, 9.843f, 12.158f, 11.979f, 6.704f, 1.457f, - 15.605f, 25.220f, 24.414f, 24.091f, 24.297f, 24.025f, 22.091f, 20.424f, 18.566f, 15.889f, - 14.373f, 13.774f, 13.624f, 13.186f, 11.486f, 9.082f, 7.419f, 6.375f, 5.232f, 3.914f, - 2.616f, 1.817f, 1.446f, 2.187f, 2.422f, 1.164f, 2.135f, 2.493f, 3.325f, 3.632f, - 1.282f, 1.741f, 2.178f, 4.222f, 5.718f, 6.496f, 7.363f, 8.479f, 11.250f, 13.136f, - 13.606f -},{ --29.534f,-30.373f,-31.415f,-32.875f,-36.164f,-36.784f,-34.436f,-36.167f,-40.465f,-45.019f, --51.967f,-52.719f,-51.969f,-53.038f,-56.070f,-58.598f,-57.741f,-57.610f,-56.191f,-55.838f, --55.464f,-54.101f,-51.482f,-50.460f,-46.856f,-44.238f,-41.019f,-37.770f,-35.434f,-33.448f, --31.242f,-33.940f,-31.571f,-29.604f,-26.184f,-21.567f,-21.848f,-20.032f,-18.185f,-16.673f, --15.790f,-14.842f,-13.539f,-11.542f,-10.114f, -8.189f, -5.674f, -3.962f, -1.267f, 1.049f, - 3.825f, 6.553f, 9.158f, 11.876f, 14.599f, 17.283f, 19.891f, 23.538f, 25.827f, 28.693f, - 32.341f, 33.831f, 36.455f, 38.366f, 40.903f, 44.192f, 46.047f, 48.139f, 51.271f, 54.063f, - 55.727f, 56.055f, 57.219f, 60.149f, 62.188f, 63.914f, 64.234f, 65.787f, 66.912f, 67.994f, - 65.925f, 66.950f, 65.470f, 62.123f, 60.192f, 62.878f, 61.193f, 58.578f, 56.886f, 55.530f, - 54.109f, 53.271f, 51.907f, 50.270f, 49.404f, 49.064f, 48.374f, 49.059f, 42.336f, 39.605f, - 37.929f, 35.571f, 33.493f, 32.375f, 31.406f, 29.456f, 29.188f, 28.197f, 26.316f, 25.330f, - 23.815f, 23.286f, 19.622f, 19.070f, 16.134f, 13.535f, 11.440f, 9.553f, 8.075f, 7.217f, - 5.975f, 5.594f, 6.042f, 4.858f, 2.870f, 1.015f, 1.698f, 0.996f, -0.436f, 0.182f, - 1.323f, 2.376f, 3.366f, 4.715f, 6.261f, 7.985f, 10.482f, 11.827f, 10.261f, 3.723f, - 5.351f, 20.060f, 23.858f, 24.217f, 25.086f, 24.668f, 23.983f, 20.896f, 18.698f, 15.969f, - 14.069f, 12.993f, 12.953f, 13.373f, 11.907f, 9.289f, 7.793f, 6.875f, 5.463f, 4.093f, - 2.928f, 1.890f, 1.701f, 1.559f, 1.696f, 1.338f, 2.191f, 2.846f, 3.380f, 3.631f, - 1.094f, 1.653f, 2.304f, 4.114f, 5.422f, 6.330f, 7.336f, 8.571f, 11.065f, 13.115f, - 13.606f -},{ --29.534f,-30.366f,-31.407f,-32.865f,-36.158f,-36.386f,-34.140f,-36.494f,-41.163f,-45.584f, --53.293f,-54.157f,-51.843f,-52.315f,-54.920f,-57.818f,-56.789f,-56.186f,-54.056f,-53.924f, --55.273f,-55.200f,-52.803f,-50.372f,-47.308f,-44.329f,-41.057f,-38.355f,-35.865f,-34.097f, --33.048f,-33.619f,-28.302f,-27.000f,-26.693f,-23.238f,-19.480f,-19.548f,-17.806f,-15.911f, --14.906f,-13.896f,-12.802f,-10.996f, -9.314f, -7.628f, -5.834f, -3.296f, -0.569f, 1.610f, - 4.112f, 6.774f, 9.144f, 11.959f, 14.742f, 17.192f, 20.128f, 23.780f, 28.395f, 30.628f, - 32.798f, 35.432f, 36.490f, 40.566f, 41.426f, 44.493f, 46.941f, 49.883f, 53.501f, 57.243f, - 57.629f, 58.414f, 59.120f, 59.546f, 61.939f, 63.210f, 64.470f, 65.636f, 63.435f, 64.705f, - 62.998f, 63.066f, 63.346f, 58.720f, 60.049f, 61.145f, 58.848f, 56.159f, 54.337f, 53.078f, - 51.697f, 50.421f, 50.306f, 49.486f, 48.206f, 46.597f, 44.950f, 43.456f, 41.055f, 37.808f, - 36.027f, 34.379f, 32.927f, 31.304f, 29.887f, 29.449f, 27.642f, 26.991f, 25.122f, 22.677f, - 20.932f, 19.436f, 19.187f, 15.306f, 15.933f, 12.511f, 10.190f, 8.235f, 6.214f, 4.582f, - 4.257f, 4.091f, 3.908f, 2.947f, 1.699f, -0.529f, 0.221f, -0.357f, -1.756f, -1.279f, - -0.403f, 0.502f, 1.610f, 3.090f, 4.397f, 6.394f, 8.696f, 10.480f, 10.403f, 7.995f, - 2.317f, 5.983f, 12.117f, 20.759f, 23.575f, 22.948f, 22.631f, 20.763f, 18.028f, 16.520f, - 13.743f, 13.193f, 12.618f, 13.050f, 11.940f, 9.572f, 8.089f, 7.083f, 5.681f, 4.327f, - 3.153f, 1.983f, 2.012f, 1.166f, 0.996f, 1.493f, 2.476f, 3.189f, 3.348f, 3.340f, - 0.862f, 1.506f, 2.460f, 4.035f, 5.176f, 6.141f, 7.284f, 8.698f, 10.910f, 13.095f, - 13.606f -},{ --29.534f,-30.357f,-31.393f,-32.861f,-36.103f,-35.963f,-33.875f,-37.066f,-42.293f,-46.917f, --54.414f,-55.885f,-52.740f,-52.611f,-54.367f,-55.835f,-55.334f,-54.700f,-53.223f,-54.730f, --56.242f,-55.009f,-53.372f,-50.622f,-47.588f,-44.371f,-41.459f,-38.904f,-36.601f,-35.019f, --34.958f,-33.336f,-30.922f,-29.576f,-27.558f,-26.434f,-22.697f,-17.440f,-15.322f,-15.293f, --14.001f,-12.450f,-11.412f,-10.695f, -8.279f, -6.651f, -5.067f, -2.884f, -0.101f, 2.543f, - 4.853f, 7.316f, 10.206f, 12.625f, 15.745f, 19.417f, 23.300f, 26.629f, 29.197f, 31.868f, - 33.445f, 35.484f, 37.620f, 40.506f, 43.287f, 47.970f, 47.780f, 50.503f, 52.215f, 53.925f, - 56.661f, 57.835f, 58.489f, 59.417f, 61.177f, 63.614f, 64.723f, 63.638f, 66.799f, 64.203f, - 63.230f, 62.308f, 61.454f, 56.387f, 59.944f, 59.360f, 56.229f, 53.778f, 51.263f, 50.288f, - 49.257f, 48.401f, 47.325f, 47.343f, 46.944f, 44.746f, 42.769f, 41.215f, 38.556f, 35.357f, - 34.926f, 33.622f, 31.551f, 29.980f, 28.835f, 28.586f, 28.153f, 25.818f, 24.110f, 22.119f, - 21.635f, 19.278f, 16.527f, 14.386f, 12.652f, 10.128f, 8.323f, 6.872f, 4.894f, 3.896f, - 3.289f, 2.775f, 1.337f, 0.332f, -0.140f, -1.611f, -2.074f, -2.303f, -3.215f, -2.848f, - -1.835f, -0.931f, -0.109f, 1.453f, 3.316f, 4.658f, 6.945f, 8.835f, 9.389f, 9.176f, - 6.275f, 0.739f, 1.903f, 16.923f, 21.529f, 22.356f, 20.965f, 20.258f, 18.272f, 16.797f, - 14.436f, 13.652f, 12.705f, 12.651f, 12.208f, 9.546f, 8.730f, 7.138f, 5.855f, 4.505f, - 3.246f, 2.242f, 2.148f, 1.388f, 0.735f, 1.549f, 2.886f, 3.279f, 3.367f, 2.810f, - 0.634f, 1.369f, 2.615f, 3.979f, 4.997f, 5.956f, 7.214f, 8.846f, 10.784f, 13.075f, - 13.606f -},{ --29.534f,-30.348f,-31.372f,-32.862f,-35.999f,-35.611f,-33.663f,-37.750f,-43.548f,-48.430f, --54.856f,-57.079f,-54.074f,-53.765f,-55.172f,-53.935f,-52.712f,-53.514f,-54.678f,-57.400f, --57.343f,-54.911f,-53.813f,-51.386f,-47.612f,-44.408f,-42.130f,-39.621f,-37.277f,-35.877f, --35.873f,-34.481f,-31.817f,-29.475f,-28.402f,-26.157f,-22.138f,-18.966f,-15.695f,-13.716f, --13.060f,-11.663f,-10.345f, -8.849f, -7.556f, -5.851f, -4.131f, -1.543f, 0.857f, 3.649f, - 5.872f, 8.242f, 11.018f, 14.008f, 17.856f, 20.969f, 24.326f, 27.644f, 30.318f, 32.741f, - 34.959f, 37.011f, 39.336f, 42.083f, 44.844f, 47.006f, 49.222f, 51.515f, 53.604f, 57.093f, - 57.682f, 56.989f, 57.862f, 58.446f, 60.561f, 61.765f, 64.493f, 65.238f, 64.262f, 58.105f, - 62.729f, 61.538f, 56.951f, 58.723f, 58.325f, 56.819f, 54.136f, 51.565f, 49.217f, 47.916f, - 47.442f, 46.375f, 45.855f, 45.727f, 44.656f, 42.734f, 41.428f, 38.735f, 37.454f, 34.858f, - 35.562f, 33.149f, 30.117f, 29.503f, 29.816f, 27.750f, 24.575f, 24.291f, 22.413f, 21.019f, - 20.914f, 18.007f, 16.032f, 13.382f, 12.250f, 8.931f, 6.743f, 4.913f, 3.906f, 3.450f, - 1.641f, 0.527f, -0.585f, -1.672f, -2.072f, -2.716f, -3.837f, -3.629f, -3.589f, -3.759f, - -3.189f, -2.615f, -1.415f, 0.047f, 1.516f, 3.106f, 4.887f, 6.896f, 8.226f, 8.798f, - 8.420f, 4.680f, -1.056f, 5.061f, 14.453f, 20.307f, 19.388f, 19.382f, 18.755f, 17.208f, - 15.493f, 13.891f, 13.234f, 12.295f, 12.205f, 9.655f, 9.330f, 7.429f, 5.947f, 4.749f, - 3.453f, 2.584f, 1.939f, 1.665f, 0.846f, 1.482f, 3.084f, 3.189f, 3.404f, 2.227f, - 0.483f, 1.313f, 2.758f, 3.931f, 4.891f, 5.803f, 7.142f, 9.004f, 10.688f, 13.055f, - 13.606f -},{ --29.534f,-30.338f,-31.345f,-32.868f,-35.851f,-35.419f,-33.558f,-38.416f,-44.642f,-49.552f, --54.486f,-57.144f,-54.922f,-54.909f,-56.810f,-53.752f,-49.664f,-52.490f,-56.444f,-58.865f, --57.389f,-55.865f,-54.629f,-51.030f,-47.503f,-44.965f,-42.667f,-40.342f,-37.988f,-36.849f, --36.922f,-35.678f,-33.907f,-31.133f,-29.485f,-26.995f,-22.753f,-18.953f,-17.192f,-11.941f, --12.770f,-10.715f, -8.857f, -7.163f, -6.503f, -4.355f, -2.927f, -0.396f, 2.047f, 4.655f, - 7.285f, 9.434f, 12.266f, 15.687f, 18.696f, 22.439f, 25.604f, 28.518f, 30.912f, 33.181f, - 35.997f, 38.445f, 40.636f, 43.424f, 46.106f, 48.275f, 50.605f, 52.028f, 53.958f, 56.855f, - 55.889f, 57.415f, 58.567f, 60.000f, 60.433f, 61.119f, 63.629f, 63.806f, 61.736f, 62.149f, - 58.420f, 54.496f, 58.690f, 58.330f, 55.823f, 54.396f, 51.743f, 49.651f, 47.911f, 45.590f, - 44.768f, 44.695f, 44.257f, 42.932f, 41.442f, 40.009f, 38.333f, 37.218f, 35.266f, 33.924f, - 33.095f, 31.965f, 30.952f, 28.548f, 26.921f, 25.136f, 23.705f, 22.765f, 21.452f, 20.185f, - 19.446f, 15.989f, 15.458f, 11.841f, 10.729f, 8.628f, 6.273f, 4.035f, 3.153f, 2.258f, - -0.194f, -1.359f, -2.533f, -4.125f, -4.252f, -4.747f, -4.997f, -4.707f, -4.006f, -4.622f, - -4.480f, -3.702f, -2.788f, -1.774f, -0.331f, 1.570f, 3.087f, 4.641f, 6.461f, 7.830f, - 8.490f, 7.407f, 2.916f, -2.507f, 4.631f, 14.103f, 14.594f, 17.662f, 16.830f, 16.276f, - 14.387f, 13.644f, 12.968f, 11.797f, 11.853f, 10.450f, 9.518f, 7.553f, 6.093f, 5.309f, - 3.848f, 3.048f, 1.893f, 1.521f, 0.941f, 1.410f, 2.932f, 3.213f, 3.355f, 1.796f, - 0.438f, 1.374f, 2.890f, 3.875f, 4.846f, 5.709f, 7.085f, 9.161f, 10.621f, 13.036f, - 13.606f -},{ --29.534f,-30.326f,-31.310f,-32.876f,-35.664f,-35.449f,-33.638f,-38.980f,-45.421f,-50.013f, --53.574f,-56.148f,-54.815f,-55.423f,-58.057f,-55.297f,-48.159f,-51.383f,-56.714f,-59.410f, --57.280f,-57.150f,-55.027f,-50.273f,-47.924f,-45.726f,-43.199f,-41.028f,-38.736f,-38.053f, --37.988f,-36.857f,-34.959f,-32.781f,-30.848f,-27.200f,-23.191f,-20.179f,-16.828f,-12.132f, --10.967f,-10.286f, -8.279f, -6.688f, -4.771f, -3.466f, -1.477f, 0.639f, 3.421f, 5.616f, - 8.382f, 11.007f, 13.432f, 17.165f, 20.380f, 24.124f, 27.171f, 29.706f, 31.506f, 33.864f, - 36.334f, 38.779f, 41.449f, 44.303f, 46.676f, 48.548f, 50.047f, 52.201f, 53.943f, 54.270f, - 55.718f, 59.003f, 61.259f, 58.712f, 60.077f, 62.237f, 62.676f, 62.654f, 60.932f, 55.653f, - 59.676f, 59.604f, 58.015f, 55.364f, 54.283f, 51.615f, 49.668f, 47.709f, 45.912f, 44.109f, - 43.543f, 43.089f, 42.095f, 41.017f, 40.576f, 40.224f, 36.455f, 35.001f, 32.791f, 32.379f, - 32.254f, 28.999f, 27.742f, 27.906f, 25.901f, 25.695f, 25.701f, 23.676f, 20.953f, 19.013f, - 18.376f, 16.409f, 12.500f, 10.593f, 8.880f, 7.050f, 4.824f, 2.531f, 1.442f, 0.561f, - -1.407f, -2.854f, -4.313f, -5.996f, -6.478f, -6.479f, -6.247f, -5.678f, -5.200f, -5.722f, - -5.637f, -5.093f, -4.291f, -3.243f, -1.452f, -0.288f, 1.149f, 2.584f, 4.508f, 6.818f, - 8.125f, 8.014f, 6.642f, 1.175f, -0.653f, 0.673f, 10.701f, 14.537f, 15.222f, 14.494f, - 13.070f, 12.168f, 11.723f, 11.470f, 11.674f, 11.004f, 9.522f, 7.534f, 6.518f, 5.846f, - 4.146f, 3.534f, 2.396f, 1.229f, 0.919f, 1.536f, 2.666f, 3.428f, 3.223f, 1.595f, - 0.459f, 1.529f, 3.013f, 3.810f, 4.846f, 5.691f, 7.059f, 9.309f, 10.580f, 13.018f, - 13.606f -},{ --29.534f,-30.314f,-31.268f,-32.882f,-35.447f,-35.719f,-33.982f,-39.424f,-45.896f,-49.921f, --52.575f,-54.725f,-54.074f,-55.441f,-58.299f,-56.984f,-49.490f,-50.733f,-55.586f,-59.595f, --57.465f,-58.005f,-54.666f,-50.425f,-48.538f,-46.289f,-44.073f,-41.701f,-39.373f,-39.072f, --38.790f,-37.882f,-35.976f,-33.981f,-31.979f,-27.624f,-23.737f,-20.792f,-17.826f,-13.829f, - -9.566f,-10.999f,-10.592f, -7.010f, -4.564f, -2.516f, -0.871f, 2.018f, 4.372f, 7.108f, - 10.101f, 13.024f, 16.701f, 19.252f, 22.157f, 24.951f, 27.255f, 29.359f, 31.049f, 33.534f, - 35.717f, 38.295f, 41.172f, 44.003f, 46.268f, 47.891f, 49.735f, 51.825f, 52.540f, 54.235f, - 60.094f, 59.103f, 59.724f, 59.826f, 58.613f, 63.012f, 61.564f, 61.938f, 59.761f, 55.246f, - 59.820f, 58.921f, 56.006f, 53.166f, 51.739f, 49.576f, 47.803f, 44.768f, 43.996f, 42.369f, - 42.194f, 41.613f, 40.413f, 39.540f, 37.983f, 36.058f, 34.913f, 33.076f, 31.279f, 30.330f, - 29.821f, 29.109f, 27.292f, 25.940f, 27.293f, 23.656f, 22.724f, 21.474f, 20.105f, 17.275f, - 15.180f, 13.812f, 11.391f, 8.980f, 6.903f, 4.854f, 2.745f, 1.471f, 0.086f, -1.058f, - -2.523f, -3.886f, -5.631f, -7.312f, -7.896f, -8.195f, -7.340f, -7.332f, -7.305f, -7.373f, - -6.774f, -6.154f, -5.474f, -4.561f, -2.951f, -1.891f, -0.617f, 1.141f, 3.239f, 5.244f, - 6.824f, 7.965f, 8.441f, 8.441f, 3.757f, -0.835f, 6.602f, 10.842f, 12.567f, 14.117f, - 13.201f, 11.329f, 11.001f, 11.512f, 11.224f, 10.875f, 9.785f, 7.870f, 7.067f, 6.110f, - 4.261f, 3.553f, 2.826f, 1.103f, 0.981f, 1.841f, 2.560f, 3.572f, 3.157f, 1.513f, - 0.496f, 1.723f, 3.123f, 3.751f, 4.873f, 5.753f, 7.078f, 9.442f, 10.564f, 13.000f, - 13.606f -},{ --29.534f,-30.302f,-31.219f,-32.884f,-35.206f,-36.190f,-34.645f,-39.790f,-46.182f,-49.609f, --51.834f,-53.557f,-53.389f,-55.379f,-57.897f,-57.622f,-52.935f,-51.899f,-54.655f,-58.693f, --57.451f,-58.172f,-54.550f,-51.029f,-48.875f,-46.864f,-44.643f,-42.441f,-40.158f,-39.703f, --40.129f,-38.905f,-36.693f,-34.898f,-31.598f,-26.885f,-22.069f,-20.391f,-17.854f,-14.101f, --12.317f, -7.869f, -9.587f, -7.730f, -5.307f, -2.834f, 0.164f, 2.571f, 5.651f, 8.193f, - 11.751f, 15.550f, 18.448f, 21.176f, 24.356f, 26.120f, 27.202f, 30.380f, 31.642f, 33.533f, - 35.984f, 38.093f, 40.242f, 42.886f, 45.836f, 47.574f, 50.072f, 52.102f, 52.615f, 62.224f, - 58.949f, 60.794f, 59.835f, 60.199f, 61.077f, 59.022f, 61.718f, 59.468f, 55.787f, 52.449f, - 58.238f, 56.327f, 53.530f, 51.794f, 49.155f, 47.433f, 45.390f, 43.547f, 42.132f, 41.082f, - 40.622f, 40.267f, 39.129f, 37.703f, 36.019f, 34.329f, 32.406f, 31.521f, 29.834f, 29.078f, - 27.518f, 27.198f, 29.651f, 25.760f, 23.665f, 22.636f, 21.505f, 20.342f, 18.618f, 18.989f, - 14.335f, 11.993f, 10.332f, 7.906f, 4.888f, 2.838f, 1.787f, 0.111f, -0.946f, -2.591f, - -3.688f, -5.058f, -6.646f, -8.173f, -8.498f, -8.950f, -8.417f, -8.423f, -8.745f, -8.512f, - -8.340f, -7.031f, -6.083f, -5.326f, -4.145f, -3.432f, -1.520f, 0.065f, 1.918f, 4.005f, - 5.469f, 7.621f, 8.843f, 9.603f, 5.686f, 0.615f, 8.388f, 10.482f, 10.274f, 11.994f, - 12.543f, 11.887f, 11.038f, 11.509f, 11.129f, 10.821f, 9.818f, 8.155f, 7.427f, 6.364f, - 4.262f, 3.118f, 2.646f, 1.089f, 1.186f, 2.032f, 2.608f, 3.446f, 3.291f, 1.339f, - 0.547f, 1.907f, 3.210f, 3.719f, 4.916f, 5.889f, 7.150f, 9.557f, 10.568f, 12.983f, - 13.606f -},{ --29.534f,-30.289f,-31.161f,-32.877f,-34.947f,-36.773f,-35.623f,-40.155f,-46.410f,-49.397f, --51.417f,-52.918f,-53.178f,-55.328f,-57.444f,-57.538f,-56.413f,-55.077f,-55.237f,-57.811f, --57.780f,-57.935f,-54.862f,-52.025f,-49.396f,-47.483f,-45.338f,-42.941f,-41.097f,-41.055f, --41.208f,-39.762f,-37.955f,-35.595f,-30.845f,-25.558f,-22.329f,-18.562f,-15.449f,-11.420f, - -9.740f, -8.838f, -6.133f, -3.660f, -2.462f, -5.782f, 1.381f, 4.347f, 7.329f, 9.398f, - 12.241f, 15.535f, 18.822f, 22.331f, 25.130f, 26.006f, 28.362f, 29.897f, 32.498f, 34.622f, - 37.463f, 39.715f, 41.708f, 45.006f, 46.915f, 49.208f, 51.495f, 53.469f, 59.328f, 60.190f, - 61.083f, 59.957f, 60.211f, 60.131f, 59.757f, 54.301f, 52.161f, 47.984f, 46.261f, 54.335f, - 58.336f, 55.675f, 51.459f, 50.040f, 47.316f, 45.297f, 43.624f, 42.011f, 40.630f, 39.454f, - 39.076f, 38.658f, 37.765f, 35.652f, 34.247f, 32.768f, 30.906f, 30.243f, 28.578f, 30.132f, - 28.204f, 26.926f, 25.948f, 24.336f, 24.053f, 22.468f, 20.312f, 19.053f, 17.584f, 15.160f, - 13.473f, 11.589f, 7.981f, 6.522f, 3.868f, 2.096f, 0.667f, -0.696f, -2.063f, -3.436f, - -5.182f, -6.681f, -7.857f, -8.795f, -9.104f, -9.506f, -9.391f, -8.739f, -9.421f, -9.205f, - -8.879f, -7.954f, -6.974f, -5.622f, -4.763f, -3.964f, -2.527f, -0.864f, 0.710f, 2.333f, - 3.900f, 6.234f, 8.846f, 8.523f, 2.494f, 8.276f, 9.380f, 10.218f, 9.621f, 9.568f, - 11.674f, 11.637f, 10.664f, 10.998f, 10.961f, 10.646f, 9.597f, 8.378f, 7.656f, 6.438f, - 4.018f, 2.940f, 2.348f, 1.217f, 1.398f, 1.980f, 2.648f, 3.260f, 3.568f, 0.949f, - 0.677f, 2.062f, 3.264f, 3.734f, 4.971f, 6.081f, 7.274f, 9.652f, 10.591f, 12.968f, - 13.606f -},{ --29.534f,-30.275f,-31.096f,-32.859f,-34.678f,-37.347f,-36.850f,-40.592f,-46.652f,-49.413f, --51.194f,-52.652f,-53.371f,-55.220f,-57.162f,-57.568f,-58.299f,-57.971f,-56.051f,-57.866f, --58.657f,-57.797f,-54.860f,-52.849f,-50.052f,-48.314f,-46.009f,-43.251f,-41.924f,-43.409f, --41.718f,-40.614f,-38.641f,-36.450f,-31.937f,-25.419f,-22.110f,-19.249f,-15.914f,-11.578f, - -8.693f, -6.222f, -3.223f, -1.501f, 3.601f, -0.690f, -0.350f, 5.140f, 8.729f, 12.540f, - 15.323f, 18.243f, 21.183f, 24.059f, 25.270f, 27.108f, 30.075f, 33.921f, 36.343f, 36.692f, - 39.271f, 41.470f, 43.547f, 46.382f, 49.156f, 50.686f, 53.586f, 56.917f, 60.329f, 60.235f, - 58.107f, 57.806f, 57.478f, 57.879f, 62.155f, 62.143f, 56.759f, 58.977f, 58.243f, 57.887f, - 57.415f, 53.817f, 50.330f, 48.220f, 45.332f, 43.470f, 42.600f, 40.416f, 39.597f, 38.870f, - 37.882f, 37.030f, 35.819f, 33.957f, 32.710f, 30.295f, 29.355f, 28.416f, 27.769f, 29.386f, - 25.860f, 27.983f, 25.515f, 21.597f, 23.954f, 18.989f, 19.596f, 18.202f, 17.535f, 16.589f, - 12.805f, 10.417f, 7.354f, 5.077f, 2.834f, 1.081f, -0.444f, -1.886f, -2.920f, -4.578f, - -6.222f, -7.481f, -8.323f, -8.972f, -9.560f, -9.650f, -9.910f, -9.455f, -9.749f, -9.836f, - -9.763f, -8.942f, -7.773f, -6.534f, -5.315f, -4.877f, -4.096f, -3.166f, -1.907f, -0.522f, - 3.185f, 6.347f, 8.034f, 5.468f, 0.168f, 13.546f, 8.330f, 9.223f, 8.766f, 7.460f, - 10.584f, 11.549f, 10.132f, 10.102f, 10.484f, 10.163f, 9.664f, 8.670f, 7.968f, 6.218f, - 3.790f, 3.174f, 2.381f, 1.530f, 1.520f, 1.966f, 2.636f, 3.379f, 3.762f, 0.441f, - 0.954f, 2.200f, 3.285f, 3.798f, 5.037f, 6.305f, 7.446f, 9.728f, 10.629f, 12.953f, - 13.606f -},{ --29.534f,-30.261f,-31.024f,-32.824f,-34.405f,-37.779f,-38.192f,-41.141f,-46.903f,-49.578f, --51.024f,-52.511f,-53.689f,-55.277f,-57.119f,-57.878f,-58.582f,-58.375f,-55.012f,-57.558f, --59.261f,-57.862f,-54.940f,-53.013f,-50.830f,-48.975f,-46.552f,-43.839f,-43.040f,-44.758f, --42.698f,-41.286f,-39.445f,-37.195f,-33.050f,-26.317f,-22.317f,-18.978f,-15.558f,-11.842f, - -9.616f, -7.446f, -3.853f, 1.088f, 3.523f, 4.173f, 1.986f, 7.276f, 10.722f, 14.383f, - 17.607f, 21.042f, 23.866f, 25.059f, 26.641f, 28.217f, 31.745f, 33.859f, 36.705f, 39.484f, - 42.462f, 46.101f, 45.710f, 47.989f, 50.313f, 52.721f, 55.335f, 58.061f, 58.150f, 57.145f, - 51.310f, 53.331f, 57.668f, 61.996f, 64.424f, 63.563f, 64.605f, 62.156f, 60.770f, 58.639f, - 55.647f, 52.320f, 48.623f, 45.988f, 44.057f, 42.116f, 40.839f, 39.489f, 38.205f, 37.101f, - 36.155f, 35.176f, 33.890f, 31.900f, 31.159f, 29.718f, 29.171f, 26.500f, 28.429f, 28.295f, - 24.619f, 25.515f, 22.997f, 21.254f, 21.793f, 17.615f, 18.140f, 16.592f, 15.923f, 14.011f, - 11.368f, 9.253f, 6.534f, 4.070f, 2.493f, 0.293f, -1.510f, -2.877f, -4.042f, -5.352f, - -6.449f, -7.658f, -8.646f, -8.990f, -9.481f, -9.626f, -9.760f, -9.897f,-10.644f,-10.897f, --11.119f,-10.505f, -9.257f, -8.017f, -7.532f, -7.250f, -7.389f, -6.641f, -3.910f, 0.596f, - 4.164f, 5.582f, 5.861f, 0.944f, 2.095f, 8.902f, 8.103f, 7.725f, 7.294f, 6.147f, - 8.665f, 11.278f, 10.334f, 9.753f, 9.954f, 9.517f, 9.486f, 8.573f, 8.083f, 5.990f, - 4.045f, 3.313f, 2.485f, 1.706f, 1.524f, 2.237f, 2.632f, 3.781f, 3.684f, 0.073f, - 1.355f, 2.334f, 3.282f, 3.897f, 5.113f, 6.536f, 7.653f, 9.788f, 10.678f, 12.940f, - 13.606f -},{ --29.534f,-30.246f,-30.944f,-32.773f,-34.135f,-37.958f,-39.483f,-41.788f,-47.117f,-49.729f, --50.887f,-52.428f,-53.962f,-55.820f,-57.463f,-58.199f,-58.377f,-57.246f,-53.341f,-56.842f, --59.321f,-57.820f,-55.334f,-53.383f,-51.653f,-49.295f,-47.156f,-44.423f,-45.112f,-45.016f, --43.621f,-42.339f,-40.557f,-37.807f,-34.061f,-28.052f,-22.970f,-18.315f,-15.201f,-12.135f, --10.209f, -7.990f, -4.642f, 0.876f, 5.219f, 5.204f, 5.106f, 8.345f, 11.751f, 15.439f, - 18.551f, 22.406f, 25.078f, 25.707f, 27.879f, 30.777f, 32.329f, 34.590f, 36.971f, 40.135f, - 42.679f, 44.558f, 46.842f, 49.221f, 51.418f, 53.586f, 55.170f, 56.550f, 54.393f, 49.570f, - 54.715f, 63.933f, 65.307f, 66.438f, 65.827f, 64.969f, 64.022f, 62.324f, 60.467f, 57.482f, - 53.949f, 49.307f, 46.766f, 44.101f, 42.292f, 40.909f, 39.682f, 38.492f, 36.821f, 35.205f, - 33.833f, 32.923f, 31.698f, 30.387f, 29.989f, 28.561f, 28.208f, 27.184f, 26.582f, 24.590f, - 26.444f, 22.543f, 23.307f, 20.289f, 18.921f, 19.183f, 16.590f, 15.511f, 14.187f, 12.076f, - 9.885f, 8.467f, 6.009f, 3.193f, 1.167f, -0.613f, -2.721f, -4.042f, -4.591f, -5.973f, - -6.948f, -7.693f, -8.427f, -9.365f, -9.785f,-10.310f,-10.215f,-11.210f,-12.366f,-12.920f, --12.787f,-12.122f,-11.726f,-10.813f,-10.514f,-10.188f, -4.472f, -2.995f, -0.303f, 1.164f, - 1.223f, 4.935f, 3.305f, -2.636f, 4.388f, 6.560f, 6.662f, 6.519f, 6.135f, 5.555f, - 7.661f, 10.255f, 10.908f, 9.733f, 9.136f, 9.107f, 8.864f, 8.321f, 7.517f, 5.612f, - 4.376f, 3.312f, 2.498f, 1.535f, 1.432f, 2.566f, 2.665f, 4.034f, 3.377f, 0.045f, - 1.747f, 2.458f, 3.277f, 4.003f, 5.198f, 6.748f, 7.879f, 9.836f, 10.735f, 12.928f, - 13.606f -},{ --29.534f,-30.232f,-30.858f,-32.702f,-33.878f,-37.820f,-40.560f,-42.481f,-47.260f,-49.762f, --50.844f,-52.465f,-54.163f,-56.628f,-58.092f,-58.527f,-58.503f,-56.970f,-53.822f,-57.135f, --58.875f,-57.621f,-55.577f,-53.923f,-52.080f,-50.055f,-47.522f,-44.838f,-46.847f,-45.516f, --44.474f,-43.063f,-41.230f,-38.270f,-35.171f,-29.912f,-23.738f,-18.442f,-16.005f,-12.766f, --10.074f, -7.962f, -5.090f, -0.904f, 5.770f, 7.694f, 7.793f, 9.474f, 12.668f, 15.831f, - 19.136f, 22.112f, 24.891f, 26.641f, 28.921f, 31.823f, 33.491f, 36.392f, 38.761f, 41.292f, - 43.845f, 45.797f, 47.499f, 49.706f, 51.436f, 53.278f, 54.420f, 51.606f, 51.364f, 61.519f, - 63.960f, 66.054f, 66.746f, 66.409f, 65.997f, 64.938f, 63.664f, 61.636f, 59.537f, 56.060f, - 50.628f, 47.984f, 44.179f, 42.023f, 40.402f, 39.458f, 37.951f, 36.707f, 34.663f, 33.372f, - 31.946f, 31.118f, 30.687f, 29.888f, 28.351f, 27.697f, 27.680f, 25.737f, 25.320f, 27.579f, - 24.966f, 25.223f, 21.942f, 19.520f, 17.540f, 16.437f, 15.694f, 14.384f, 12.422f, 11.254f, - 8.987f, 7.159f, 4.699f, 2.165f, 0.612f, -1.452f, -3.464f, -4.707f, -5.833f, -6.392f, - -6.843f, -7.740f, -8.419f,-10.128f,-11.753f,-11.863f,-11.933f,-13.192f, -9.567f,-14.709f, --10.680f, -7.250f, -9.678f, -8.361f, -7.658f, -3.284f, -4.702f, -4.377f, -5.569f, -1.751f, - 2.614f, 3.698f, 0.796f, -0.118f, 4.329f, 4.859f, 6.019f, 6.221f, 6.580f, 6.761f, - 8.921f, 10.007f, 11.187f, 9.455f, 8.703f, 8.587f, 8.377f, 8.001f, 6.534f, 5.117f, - 4.223f, 3.405f, 2.451f, 1.354f, 1.364f, 2.571f, 2.733f, 3.839f, 3.065f, 0.332f, - 1.962f, 2.555f, 3.291f, 4.087f, 5.284f, 6.926f, 8.106f, 9.874f, 10.796f, 12.917f, - 13.606f -},{ --29.534f,-30.217f,-30.766f,-32.613f,-33.640f,-37.369f,-41.311f,-43.141f,-47.336f,-49.692f, --50.931f,-52.602f,-54.274f,-56.953f,-58.456f,-58.967f,-58.863f,-57.775f,-56.061f,-58.197f, --58.222f,-57.624f,-56.060f,-54.359f,-52.460f,-50.706f,-47.852f,-45.610f,-47.780f,-46.388f, --45.138f,-43.854f,-41.657f,-39.054f,-36.036f,-32.064f,-24.437f,-19.495f,-16.194f,-13.057f, - -9.861f, -7.719f, -5.786f, -2.040f, 2.591f, 6.839f, 9.135f, 11.149f, 14.200f, 16.241f, - 19.367f, 21.942f, 24.137f, 27.442f, 29.424f, 31.679f, 35.723f, 37.392f, 39.842f, 42.039f, - 44.773f, 46.627f, 48.240f, 50.248f, 51.385f, 52.371f, 53.156f, 48.799f, 60.203f, 63.779f, - 64.892f, 65.852f, 66.135f, 65.875f, 65.148f, 64.113f, 62.580f, 60.441f, 57.903f, 52.234f, - 49.562f, 45.129f, 41.756f, 40.189f, 38.648f, 37.120f, 35.379f, 34.070f, 33.037f, 32.027f, - 31.137f, 30.897f, 29.885f, 28.619f, 27.728f, 26.634f, 24.616f, 25.780f, 25.878f, 26.386f, - 23.141f, 22.088f, 20.193f, 18.402f, 16.553f, 15.332f, 14.822f, 13.225f, 14.570f, 10.366f, - 6.965f, 6.247f, 3.732f, 1.732f, -0.185f, -2.189f, -4.025f, -5.613f, -6.633f, -6.727f, - -6.951f, -8.171f, -9.471f,-10.476f,-11.711f, -8.826f,-11.138f,-12.299f, -7.565f,-13.111f, --15.222f, -7.932f,-11.089f,-10.389f,-10.766f, -9.655f, -8.580f, -6.042f, -3.030f, 0.277f, - 2.218f, 2.537f, -2.592f, 2.953f, 3.422f, 2.475f, 4.252f, 5.379f, 5.987f, 5.114f, - 4.271f, 9.902f, 11.027f, 9.098f, 8.213f, 7.476f, 8.219f, 7.527f, 5.824f, 4.905f, - 3.909f, 3.334f, 2.170f, 1.414f, 1.387f, 2.277f, 2.865f, 3.390f, 2.902f, 0.705f, - 1.930f, 2.617f, 3.343f, 4.132f, 5.364f, 7.060f, 8.318f, 9.908f, 10.859f, 12.907f, - 13.606f -},{ --29.534f,-30.202f,-30.668f,-32.508f,-33.433f,-36.673f,-41.704f,-43.696f,-47.386f,-49.617f, --51.093f,-52.672f,-54.241f,-56.397f,-58.145f,-59.293f,-59.064f,-58.266f,-57.632f,-58.993f, --58.193f,-57.860f,-56.760f,-55.036f,-53.071f,-51.071f,-47.878f,-47.177f,-48.072f,-46.887f, --45.819f,-44.457f,-42.088f,-39.404f,-36.700f,-33.027f,-25.931f,-20.248f,-16.514f,-13.612f, - -9.872f, -7.255f, -5.366f, -2.443f, 0.793f, 5.508f, 9.499f, 12.836f, 15.150f, 17.782f, - 19.721f, 22.361f, 24.911f, 27.541f, 30.618f, 34.303f, 38.809f, 38.477f, 40.948f, 43.031f, - 45.429f, 46.824f, 48.277f, 50.156f, 51.955f, 53.101f, 53.183f, 49.988f, 60.852f, 63.756f, - 64.829f, 65.376f, 65.241f, 64.737f, 63.752f, 62.593f, 61.082f, 59.104f, 56.558f, 50.521f, - 46.958f, 42.803f, 40.526f, 38.659f, 37.200f, 35.050f, 34.067f, 32.765f, 32.314f, 30.597f, - 28.620f, 28.148f, 27.180f, 26.357f, 25.127f, 24.848f, 27.383f, 25.864f, 22.678f, 21.928f, - 21.913f, 21.329f, 19.180f, 17.248f, 15.532f, 14.350f, 13.220f, 11.725f, 12.334f, 9.369f, - 7.936f, 5.091f, 2.986f, 1.288f, -0.577f, -2.837f, -4.692f, -6.156f, -6.987f, -6.736f, - -7.074f, -8.566f, -8.429f, -6.580f, -9.027f, -4.060f,-11.053f,-12.932f,-14.378f,-13.974f, --13.483f,-13.489f,-12.529f,-11.110f,-10.076f, -8.699f, -6.906f, -4.957f, -2.168f, 0.102f, - 1.926f, 0.843f, -5.787f, 4.610f, 2.335f, 2.298f, 2.437f, 3.199f, 3.004f, 1.245f, - -0.910f, 8.233f, 9.539f, 8.573f, 7.851f, 7.113f, 7.547f, 7.113f, 5.656f, 4.878f, - 3.782f, 2.904f, 1.801f, 1.464f, 1.366f, 2.023f, 3.021f, 3.061f, 2.801f, 0.952f, - 1.749f, 2.662f, 3.439f, 4.142f, 5.431f, 7.152f, 8.502f, 9.941f, 10.921f, 12.899f, - 13.606f -},{ --29.534f,-30.187f,-30.566f,-32.389f,-33.264f,-35.861f,-41.796f,-44.106f,-47.447f,-49.619f, --51.245f,-52.550f,-54.068f,-55.489f,-57.508f,-59.200f,-59.075f,-58.195f,-58.005f,-59.325f, --58.626f,-58.202f,-57.077f,-55.541f,-53.711f,-51.850f,-48.311f,-48.631f,-48.047f,-47.460f, --46.282f,-44.617f,-42.301f,-39.684f,-36.811f,-33.508f,-27.648f,-21.144f,-17.465f,-13.794f, --10.148f, -7.022f, -5.310f, -2.475f, 0.573f, 4.975f, 10.669f, 11.676f, 14.960f, 16.287f, - 18.905f, 23.680f, 26.090f, 29.011f, 32.731f, 37.676f, 38.750f, 40.053f, 42.272f, 44.577f, - 45.952f, 47.232f, 48.637f, 50.252f, 51.727f, 52.941f, 53.607f, 49.514f, 60.072f, 62.715f, - 64.091f, 64.237f, 64.084f, 63.380f, 62.481f, 60.899f, 59.489f, 57.257f, 52.529f, 49.168f, - 44.349f, 41.545f, 39.404f, 37.413f, 35.830f, 33.873f, 32.251f, 31.793f, 29.532f, 27.757f, - 27.944f, 29.151f, 28.349f, 27.852f, 26.198f, 24.114f, 23.644f, 23.453f, 22.466f, 21.615f, - 21.015f, 20.134f, 18.226f, 15.998f, 14.234f, 13.099f, 12.348f, 10.853f, 10.674f, 8.576f, - 5.704f, 4.344f, 3.176f, 1.043f, -1.047f, -3.296f, -4.957f, -6.351f, -6.810f, -6.663f, - -7.168f, -8.464f, -5.157f, -9.489f,-11.313f,-12.719f,-12.298f,-12.582f,-12.913f,-12.544f, --11.853f,-11.323f,-10.707f, -9.167f, -8.576f, -7.643f, -6.066f, -4.049f, -2.934f, -0.402f, - 0.657f, -1.006f, -2.213f, 6.825f, 1.955f, 1.671f, 2.768f, 2.335f, 1.500f, 0.159f, - -0.924f, 5.243f, 7.722f, 8.095f, 7.501f, 6.927f, 6.324f, 6.602f, 6.006f, 4.941f, - 3.685f, 2.503f, 1.824f, 1.351f, 1.217f, 1.966f, 3.025f, 2.920f, 2.556f, 1.070f, - 1.635f, 2.733f, 3.570f, 4.138f, 5.484f, 7.213f, 8.650f, 9.976f, 10.980f, 12.892f, - 13.606f -},{ --29.534f,-30.172f,-30.459f,-32.262f,-33.140f,-35.090f,-41.719f,-44.367f,-47.531f,-49.704f, --51.355f,-52.337f,-53.867f,-55.107f,-57.252f,-58.803f,-59.102f,-58.424f,-58.286f,-59.308f, --58.886f,-58.852f,-57.365f,-55.713f,-54.424f,-51.921f,-49.121f,-48.928f,-48.426f,-47.917f, --46.462f,-44.737f,-42.196f,-39.791f,-37.119f,-33.645f,-29.145f,-22.938f,-18.802f,-14.635f, --10.703f, -7.152f, -5.198f, -2.422f, 0.523f, 5.271f, 10.396f, 10.406f, 10.729f, 12.837f, - 15.432f, 23.299f, 28.302f, 31.581f, 35.514f, 38.837f, 38.622f, 40.065f, 41.693f, 43.293f, - 44.947f, 46.741f, 48.839f, 50.099f, 51.279f, 52.423f, 53.783f, 51.521f, 58.288f, 61.742f, - 62.703f, 62.893f, 62.722f, 61.951f, 60.873f, 59.472f, 57.750f, 55.786f, 51.610f, 46.470f, - 42.602f, 40.775f, 38.647f, 36.674f, 34.075f, 32.702f, 30.394f, 29.551f, 27.277f, 28.364f, - 27.546f, 25.843f, 25.686f, 24.526f, 23.852f, 23.176f, 22.623f, 22.155f, 21.652f, 20.411f, - 20.202f, 18.692f, 17.025f, 15.445f, 14.105f, 12.641f, 11.844f, 10.539f, 9.778f, 7.473f, - 5.548f, 4.593f, 1.814f, 1.118f, -1.292f, -3.446f, -5.157f, -6.180f, -6.973f, -6.546f, - -6.389f, -8.224f, -9.329f, -9.368f, -9.032f,-10.101f,-10.991f,-11.648f,-11.690f,-11.668f, --11.237f,-11.188f,-10.708f, -9.809f, -9.472f, -8.566f, -6.341f, -4.505f, -2.200f, -0.236f, - 0.869f, -3.899f, 1.225f, 4.712f, 2.421f, -0.469f, 1.426f, 1.996f, 1.704f, 0.145f, - -1.270f, 3.403f, 6.123f, 7.473f, 6.811f, 6.365f, 6.085f, 6.298f, 6.452f, 5.133f, - 3.612f, 2.426f, 2.126f, 1.289f, 1.126f, 1.961f, 2.748f, 2.739f, 2.141f, 1.234f, - 1.779f, 2.872f, 3.718f, 4.153f, 5.528f, 7.256f, 8.760f, 10.015f, 11.034f, 12.885f, - 13.606f -},{ --29.534f,-30.157f,-30.350f,-32.131f,-33.067f,-34.520f,-41.639f,-44.514f,-47.616f,-49.804f, --51.474f,-52.309f,-53.805f,-55.501f,-57.573f,-58.545f,-59.275f,-59.195f,-59.090f,-59.436f, --59.386f,-59.567f,-57.849f,-56.077f,-54.759f,-51.691f,-49.520f,-49.503f,-48.723f,-47.832f, --46.830f,-45.010f,-42.375f,-39.855f,-36.836f,-33.437f,-29.746f,-25.713f,-20.802f,-15.783f, --11.765f, -7.086f, -5.153f, -2.608f, 0.872f, 5.701f, 11.055f, 12.340f, 8.993f, 13.304f, - 12.876f, 25.113f, 30.039f, 33.466f, 36.786f, 38.148f, 39.241f, 40.165f, 41.765f, 43.416f, - 44.955f, 46.474f, 48.328f, 49.599f, 50.636f, 51.960f, 53.376f, 53.343f, 56.648f, 60.111f, - 61.112f, 61.137f, 60.924f, 60.563f, 59.468f, 58.015f, 56.024f, 53.599f, 49.753f, 45.155f, - 41.495f, 39.432f, 37.248f, 35.192f, 32.690f, 31.141f, 28.908f, 27.266f, 27.506f, 27.506f, - 25.349f, 25.890f, 24.541f, 23.989f, 23.294f, 22.196f, 20.753f, 20.874f, 20.183f, 19.301f, - 18.987f, 17.118f, 15.571f, 14.456f, 13.622f, 12.018f, 11.062f, 9.650f, 8.968f, 7.256f, - 5.166f, 4.469f, 3.795f, -0.010f, -1.388f, -3.962f, -5.135f, -5.677f, -6.353f, -5.983f, - -6.857f, -8.337f, -8.964f, -8.608f, -8.218f, -9.917f,-10.891f,-11.013f,-11.402f,-11.935f, --11.909f,-12.062f,-11.281f,-11.304f,-10.240f, -7.491f, -6.279f, -4.624f, -2.062f, 0.026f, - 0.863f, -5.422f, 5.067f, 2.265f, 3.245f, -2.174f, 0.517f, 1.560f, 1.203f, 0.034f, - -1.884f, 1.122f, 3.903f, 6.902f, 6.142f, 6.031f, 6.180f, 6.334f, 6.408f, 5.259f, - 3.618f, 2.541f, 2.291f, 1.345f, 1.240f, 1.869f, 2.296f, 2.429f, 1.829f, 1.599f, - 2.219f, 3.089f, 3.856f, 4.214f, 5.575f, 7.299f, 8.835f, 10.059f, 11.081f, 12.880f, - 13.606f -},{ --29.534f,-30.143f,-30.238f,-32.002f,-33.044f,-34.276f,-41.710f,-44.605f,-47.668f,-49.851f, --51.667f,-52.643f,-53.994f,-56.173f,-58.072f,-58.721f,-59.575f,-60.021f,-60.203f,-60.184f, --60.124f,-59.733f,-58.182f,-56.622f,-54.618f,-52.211f,-49.839f,-50.186f,-48.886f,-47.880f, --46.997f,-45.261f,-42.436f,-39.746f,-36.684f,-33.264f,-30.029f,-26.507f,-23.096f,-18.168f, --12.624f, -8.343f, -5.615f, -2.750f, 0.624f, 5.419f, 11.603f, 13.510f, 9.704f, 16.848f, - 15.995f, 24.561f, 29.203f, 32.910f, 36.442f, 37.552f, 39.740f, 40.959f, 42.343f, 43.377f, - 45.120f, 46.706f, 47.805f, 48.931f, 50.079f, 51.166f, 52.441f, 53.588f, 54.195f, 58.987f, - 59.104f, 59.267f, 59.348f, 58.923f, 57.699f, 56.190f, 54.387f, 52.157f, 49.120f, 42.633f, - 39.323f, 37.872f, 35.722f, 32.457f, 32.334f, 29.161f, 28.798f, 26.094f, 27.087f, 26.363f, - 24.657f, 24.025f, 23.315f, 22.164f, 21.352f, 21.277f, 21.385f, 19.018f, 18.898f, 18.242f, - 17.613f, 15.917f, 14.427f, 13.930f, 13.704f, 12.278f, 11.268f, 9.293f, 8.013f, 6.682f, - 6.507f, 5.191f, 2.015f, 0.532f, -1.827f, -3.959f, -5.059f, -5.442f, -5.580f, -5.762f, - -7.040f, -6.452f, -9.214f, -9.157f, -8.806f,-10.209f,-10.584f,-10.638f,-11.142f,-11.997f, --12.440f,-12.306f,-11.941f,-10.537f, -8.786f, -7.760f, -6.167f, -4.115f, -2.033f, -0.152f, - 0.536f, -8.959f, 5.864f, 1.843f, 2.695f, 0.814f, -0.039f, 0.857f, 1.008f, -0.084f, - -1.841f, -0.575f, 2.486f, 6.254f, 4.721f, 5.147f, 5.640f, 6.376f, 6.212f, 5.333f, - 3.478f, 2.648f, 2.466f, 1.352f, 1.382f, 1.739f, 1.879f, 2.181f, 1.942f, 2.117f, - 2.834f, 3.357f, 3.965f, 4.332f, 5.637f, 7.356f, 8.883f, 10.108f, 11.120f, 12.876f, - 13.606f -},{ --29.534f,-30.129f,-30.125f,-31.883f,-33.070f,-34.420f,-42.024f,-44.694f,-47.674f,-49.837f, --51.942f,-53.239f,-54.436f,-56.643f,-58.464f,-59.338f,-59.883f,-60.555f,-61.093f,-60.977f, --60.464f,-59.639f,-58.531f,-57.080f,-54.900f,-52.336f,-50.203f,-49.939f,-49.353f,-47.977f, --46.933f,-45.211f,-42.610f,-39.780f,-36.621f,-33.492f,-30.609f,-27.083f,-23.725f,-19.647f, --13.219f, -9.009f, -5.193f, -3.138f, 0.081f, 4.911f, 11.051f, 14.460f, 11.324f, 15.938f, - 18.284f, 19.726f, 25.870f, 30.085f, 34.459f, 37.761f, 40.113f, 41.590f, 42.703f, 43.784f, - 45.252f, 46.579f, 47.491f, 48.100f, 49.172f, 50.314f, 51.246f, 52.011f, 53.228f, 53.961f, - 56.798f, 57.085f, 57.206f, 57.687f, 55.978f, 54.560f, 52.513f, 50.294f, 46.318f, 40.755f, - 37.734f, 35.923f, 34.258f, 31.477f, 30.510f, 28.448f, 26.606f, 25.863f, 24.518f, 23.842f, - 23.382f, 22.696f, 21.228f, 20.812f, 19.239f, 17.946f, 18.289f, 17.746f, 17.685f, 17.807f, - 16.343f, 15.283f, 14.037f, 13.298f, 12.422f, 11.334f, 10.245f, 8.897f, 7.275f, 6.376f, - 5.390f, 5.560f, 2.098f, 0.265f, -1.893f, -4.186f, -4.762f, -4.697f, -4.779f, -5.558f, - -6.917f, -8.144f, -9.093f, -9.276f, -8.928f, -9.776f,-10.599f,-10.727f,-11.499f,-12.321f, --12.543f,-12.449f,-11.673f, -9.679f, -8.735f, -7.094f, -5.755f, -3.849f, -1.736f, 0.337f, - -0.964f,-10.263f, 3.967f, 1.344f, 1.946f, 4.041f, -0.496f, 0.922f, 0.627f, 0.029f, - -1.018f, -1.525f, 3.025f, 5.247f, 4.071f, 4.661f, 5.319f, 6.493f, 6.293f, 5.217f, - 3.132f, 2.592f, 2.772f, 1.319f, 1.346f, 1.675f, 1.567f, 2.163f, 2.499f, 2.586f, - 3.440f, 3.624f, 4.039f, 4.502f, 5.725f, 7.439f, 8.913f, 10.163f, 11.152f, 12.873f, - 13.606f -},{ --29.534f,-30.115f,-30.011f,-31.777f,-33.138f,-34.946f,-42.591f,-44.819f,-47.652f,-49.823f, --52.235f,-53.819f,-55.028f,-56.957f,-58.866f,-60.231f,-60.156f,-60.778f,-61.497f,-61.186f, --60.780f,-60.107f,-58.952f,-57.482f,-55.345f,-51.869f,-50.534f,-49.799f,-49.325f,-48.243f, --46.691f,-45.019f,-42.670f,-39.944f,-37.004f,-33.579f,-30.602f,-27.520f,-24.215f,-20.489f, --13.987f, -9.182f, -5.070f, -3.322f, -0.351f, 4.574f, 10.564f, 14.833f, 14.074f, 15.402f, - 19.026f, 21.300f, 22.123f, 22.866f, 32.875f, 37.988f, 40.710f, 42.036f, 43.121f, 44.316f, - 45.470f, 46.451f, 47.112f, 47.529f, 48.524f, 49.394f, 50.232f, 50.847f, 51.217f, 53.361f, - 52.268f, 55.492f, 56.348f, 55.312f, 53.969f, 52.547f, 51.144f, 48.098f, 45.937f, 40.308f, - 36.219f, 34.504f, 33.087f, 29.697f, 28.292f, 27.188f, 26.369f, 25.149f, 24.097f, 23.634f, - 22.755f, 21.305f, 20.816f, 20.074f, 18.916f, 18.063f, 18.145f, 17.293f, 16.445f, 16.384f, - 14.845f, 14.348f, 13.253f, 11.916f, 11.159f, 10.176f, 9.291f, 8.063f, 7.178f, 5.592f, - 4.861f, 3.804f, 2.636f, -0.461f, -2.659f, -3.856f, -4.279f, -3.951f, -4.816f, -5.672f, - -6.973f, -8.411f, -9.083f, -9.158f, -8.510f, -9.482f,-10.263f,-11.158f,-12.151f,-12.630f, --12.738f,-12.117f,-10.924f,-10.091f, -8.579f, -6.801f, -5.170f, -3.702f, -1.827f, 0.228f, - -2.989f, -8.360f, 5.723f, 1.391f, 1.605f, 3.535f, -0.406f, 1.044f, 1.005f, 0.110f, - -0.331f, -0.093f, 5.297f, 5.137f, 4.181f, 4.859f, 5.186f, 6.276f, 6.185f, 4.673f, - 2.873f, 2.391f, 2.786f, 1.380f, 1.214f, 1.707f, 1.343f, 2.270f, 3.145f, 2.855f, - 3.911f, 3.841f, 4.088f, 4.698f, 5.845f, 7.550f, 8.938f, 10.220f, 11.175f, 12.870f, - 13.606f -},{ --29.534f,-30.102f,-29.897f,-31.689f,-33.239f,-35.775f,-43.335f,-44.989f,-47.643f,-49.891f, --52.467f,-54.201f,-55.614f,-57.379f,-59.357f,-61.076f,-60.592f,-60.828f,-61.680f,-61.030f, --61.405f,-60.902f,-58.811f,-57.671f,-55.306f,-51.562f,-50.608f,-49.884f,-48.933f,-48.032f, --46.458f,-44.723f,-42.709f,-40.207f,-37.037f,-34.005f,-30.816f,-27.742f,-24.229f,-20.879f, --15.207f, -8.844f, -4.270f, -3.528f, -1.105f, 3.828f, 10.224f, 14.324f, 15.900f, 17.285f, - 18.794f, 20.200f, 20.767f, 21.427f, 28.277f, 36.732f, 40.563f, 43.305f, 44.194f, 44.901f, - 45.637f, 46.410f, 47.290f, 47.361f, 48.600f, 49.214f, 49.628f, 50.213f, 50.128f, 50.619f, - 50.929f, 51.144f, 52.530f, 54.244f, 52.632f, 51.054f, 49.516f, 45.909f, 42.257f, 38.889f, - 35.070f, 33.325f, 31.301f, 29.342f, 26.801f, 25.594f, 25.387f, 24.311f, 22.785f, 22.056f, - 21.911f, 20.382f, 19.844f, 19.487f, 18.112f, 16.729f, 16.481f, 16.342f, 15.522f, 14.890f, - 14.324f, 12.943f, 12.380f, 11.963f, 9.019f, 8.892f, 8.276f, 7.038f, 6.490f, 5.504f, - 4.455f, 3.866f, 1.559f, -0.967f, -2.487f, -3.343f, -4.062f, -3.864f, -4.971f, -6.394f, - -4.933f, -8.501f, -8.935f, -9.056f, -8.158f, -9.872f,-10.693f,-11.856f,-12.621f,-13.030f, --12.366f,-11.597f,-10.885f, -9.629f, -8.270f, -6.931f, -5.335f, -3.295f, -1.567f, 0.176f, - -4.982f, -5.295f, 5.600f, 2.143f, 3.985f, 1.729f, 0.557f, 1.524f, 0.921f, 0.510f, - 0.052f, 3.537f, 5.337f, 4.989f, 3.684f, 4.845f, 5.191f, 5.571f, 5.665f, 4.086f, - 2.766f, 2.352f, 2.437f, 1.478f, 1.173f, 1.789f, 1.305f, 2.294f, 3.448f, 2.968f, - 4.222f, 3.986f, 4.131f, 4.888f, 5.992f, 7.687f, 8.969f, 10.278f, 11.190f, 12.868f, - 13.606f -},{ --29.534f,-30.089f,-29.785f,-31.622f,-33.361f,-36.775f,-44.126f,-45.188f,-47.687f,-50.075f, --52.608f,-54.426f,-56.082f,-57.905f,-59.737f,-61.530f,-61.355f,-60.938f,-61.764f,-60.824f, --61.886f,-61.002f,-58.358f,-57.674f,-54.955f,-51.524f,-50.615f,-49.787f,-48.909f,-47.660f, --46.305f,-44.608f,-42.718f,-40.197f,-37.167f,-34.086f,-31.151f,-27.997f,-24.654f,-20.999f, --16.589f, -9.612f, -4.896f, -4.735f, -1.921f, 3.240f, 10.247f, 13.704f, 15.302f, 18.896f, - 20.541f, 21.633f, 20.806f, 19.643f, 23.158f, 28.442f, 36.892f, 42.507f, 44.204f, 46.172f, - 47.528f, 47.515f, 47.799f, 48.063f, 49.055f, 49.760f, 50.457f, 50.481f, 50.471f, 50.179f, - 49.744f, 50.512f, 50.025f, 51.434f, 51.589f, 49.128f, 47.459f, 41.152f, 42.816f, 39.243f, - 35.210f, 31.891f, 28.605f, 26.724f, 26.036f, 24.356f, 23.801f, 23.029f, 21.880f, 20.980f, - 21.153f, 19.198f, 19.200f, 18.749f, 17.086f, 16.106f, 15.587f, 15.584f, 14.686f, 13.509f, - 12.684f, 12.248f, 10.808f, 9.945f, 9.262f, 8.807f, 7.321f, 6.885f, 6.085f, 5.387f, - 4.001f, 2.642f, 1.378f, -0.938f, -2.130f, -2.742f, -3.811f, -4.365f, -5.170f, -5.251f, - -7.504f, -8.125f, -9.128f, -9.421f, -9.612f,-10.142f,-11.171f,-12.042f,-12.516f,-12.747f, --12.520f,-11.692f,-11.195f, -9.689f, -7.974f, -6.432f, -4.947f, -2.748f, -1.045f, 0.356f, - -5.705f, -7.689f, 3.969f, 4.946f, 4.928f, -0.694f, 1.682f, 1.847f, 1.550f, 0.625f, - 0.445f, 4.645f, 4.519f, 4.329f, 3.863f, 4.744f, 4.960f, 4.990f, 4.952f, 3.662f, - 2.600f, 2.522f, 2.154f, 1.519f, 1.252f, 1.845f, 1.546f, 2.211f, 3.267f, 3.097f, - 4.410f, 4.058f, 4.186f, 5.041f, 6.156f, 7.842f, 9.013f, 10.335f, 11.198f, 12.867f, - 13.606f -},{ --29.534f,-30.078f,-29.674f,-31.578f,-33.495f,-37.793f,-44.815f,-45.389f,-47.800f,-50.331f, --52.674f,-54.640f,-56.428f,-58.302f,-59.902f,-61.638f,-62.204f,-61.320f,-61.638f,-60.988f, --62.411f,-60.607f,-58.880f,-58.164f,-54.190f,-51.468f,-50.530f,-49.572f,-48.843f,-47.367f, --46.116f,-44.457f,-42.736f,-40.114f,-37.378f,-34.563f,-31.530f,-28.321f,-24.912f,-21.240f, --16.843f,-11.736f, -7.830f, -6.526f, -2.800f, 3.010f, 9.792f, 13.205f, 14.670f, 18.282f, - 20.184f, 22.077f, 22.742f, 21.401f, 17.004f, 18.289f, 24.092f, 34.707f, 41.390f, 45.056f, - 46.256f, 47.331f, 48.852f, 49.893f, 50.516f, 51.343f, 51.871f, 52.193f, 52.094f, 51.775f, - 50.906f, 50.300f, 50.569f, 50.438f, 49.163f, 47.849f, 46.052f, 43.763f, 40.850f, 37.798f, - 33.142f, 29.368f, 27.062f, 25.180f, 23.810f, 22.789f, 21.709f, 21.359f, 20.611f, 20.329f, - 20.051f, 19.886f, 19.033f, 18.304f, 16.952f, 16.129f, 15.757f, 15.028f, 13.982f, 12.755f, - 12.035f, 11.075f, 10.446f, 10.402f, 9.678f, 8.730f, 7.428f, 6.750f, 6.046f, 5.198f, - 4.543f, 2.487f, 1.412f, -1.053f, -1.554f, -2.078f, -3.160f, -4.521f, -4.288f, -2.969f, - -8.148f, -8.576f, -9.521f, -9.678f,-10.343f,-10.287f,-11.297f,-11.909f,-12.426f,-12.229f, --12.795f,-11.905f,-11.496f, -9.525f, -7.787f, -6.278f, -4.427f, -2.580f, -0.492f, 0.885f, - -5.800f, -5.778f, 2.409f, 1.649f, -0.115f, 1.031f, 1.959f, 2.134f, 0.858f, 0.796f, - 2.698f, 4.167f, 4.562f, 4.534f, 4.197f, 4.414f, 4.354f, 4.613f, 4.211f, 3.147f, - 2.377f, 2.472f, 1.929f, 1.566f, 1.386f, 1.840f, 1.811f, 2.129f, 2.814f, 3.335f, - 4.493f, 4.072f, 4.256f, 5.137f, 6.326f, 8.004f, 9.076f, 10.388f, 11.198f, 12.867f, - 13.606f -},{ --29.534f,-30.066f,-29.565f,-31.554f,-33.631f,-38.682f,-45.285f,-45.565f,-47.973f,-50.566f, --52.694f,-54.873f,-56.717f,-58.464f,-60.033f,-61.882f,-62.829f,-62.030f,-61.695f,-62.038f, --63.207f,-61.041f,-60.115f,-58.732f,-53.500f,-51.445f,-50.339f,-49.232f,-48.644f,-47.156f, --45.771f,-44.474f,-42.520f,-39.970f,-37.520f,-34.669f,-31.569f,-28.526f,-25.335f,-21.125f, --16.900f,-14.017f,-11.253f, -8.230f, -3.683f, 2.668f, 9.260f, 12.435f, 13.731f, 16.598f, - 18.614f, 20.858f, 23.001f, 23.105f, 21.553f, 19.917f, 17.699f, 18.264f, 23.321f, 32.668f, - 39.853f, 45.525f, 47.804f, 49.082f, 49.972f, 51.229f, 51.573f, 51.809f, 52.155f, 51.999f, - 51.396f, 50.604f, 49.610f, 48.535f, 47.513f, 46.354f, 44.478f, 41.405f, 39.176f, 33.678f, - 31.217f, 28.531f, 26.149f, 23.868f, 22.456f, 21.480f, 20.587f, 20.163f, 19.700f, 20.124f, - 19.691f, 19.297f, 18.784f, 17.888f, 16.224f, 15.839f, 16.172f, 14.750f, 13.463f, 12.675f, - 11.962f, 10.904f, 10.955f, 10.973f, 9.761f, 8.461f, 7.604f, 5.948f, 6.030f, 5.316f, - 4.224f, 2.170f, 0.910f, -0.436f, -0.509f, -1.107f, -2.639f, -3.588f, -0.311f, -5.086f, - -8.315f, -8.414f, -9.031f,-10.187f, -9.387f,-10.168f,-11.366f,-12.397f,-12.620f,-12.636f, --12.274f,-12.097f,-11.440f, -9.264f, -7.725f, -5.691f, -3.814f, -1.977f, -0.003f, 1.249f, - -4.903f, -7.282f, 3.862f, 1.955f, 1.941f, 2.232f, 2.868f, 2.160f, 1.159f, 4.494f, - 4.522f, 3.681f, 4.289f, 4.586f, 4.351f, 4.325f, 4.248f, 4.205f, 3.594f, 2.601f, - 2.090f, 2.001f, 1.482f, 1.564f, 1.507f, 1.829f, 1.587f, 2.058f, 2.422f, 3.586f, - 4.451f, 4.035f, 4.328f, 5.168f, 6.487f, 8.163f, 9.159f, 10.435f, 11.194f, 12.866f, - 13.606f -},{ --29.534f,-30.056f,-29.459f,-31.549f,-33.762f,-39.336f,-45.478f,-45.708f,-48.180f,-50.700f, --52.681f,-55.005f,-56.970f,-58.483f,-60.205f,-62.525f,-63.402f,-62.894f,-62.362f,-63.491f, --63.684f,-62.190f,-60.880f,-58.374f,-53.432f,-51.504f,-50.151f,-48.972f,-48.280f,-47.018f, --45.385f,-44.231f,-42.298f,-39.627f,-37.263f,-34.661f,-31.423f,-28.477f,-25.532f,-21.404f, --15.304f,-15.018f,-11.921f, -8.375f, -3.767f, 2.574f, 9.780f, 11.796f, 12.713f, 14.966f, - 16.883f, 19.399f, 21.741f, 23.125f, 24.052f, 24.725f, 24.700f, 23.690f, 20.297f, 19.095f, - 26.232f, 34.582f, 40.900f, 44.898f, 47.367f, 49.680f, 51.065f, 52.145f, 52.918f, 52.593f, - 51.484f, 50.602f, 49.104f, 47.759f, 46.284f, 45.058f, 43.098f, 36.420f, 34.992f, 32.639f, - 29.722f, 27.150f, 24.807f, 22.371f, 21.178f, 20.499f, 19.698f, 19.895f, 19.261f, 18.597f, - 18.746f, 19.359f, 18.039f, 16.959f, 16.171f, 15.934f, 15.750f, 15.335f, 13.131f, 11.898f, - 11.327f, 11.086f, 11.313f, 10.988f, 9.523f, 8.665f, 7.557f, 7.028f, 6.506f, 5.317f, - 3.657f, 1.831f, 1.352f, 0.614f, -0.108f, -0.930f, -2.336f, -1.111f, -1.781f, -5.795f, - -7.771f, -8.213f, -9.055f,-10.405f,-10.498f, -9.755f,-11.772f,-12.699f,-12.988f,-12.915f, --12.583f,-11.875f,-10.853f, -9.212f, -7.494f, -5.638f, -3.278f, -1.408f, 0.539f, 1.822f, - -3.818f, -8.140f, 5.068f, 2.385f, 2.764f, 3.348f, 2.843f, 2.544f, 1.696f, 6.029f, - 4.553f, 3.821f, 4.718f, 4.166f, 4.644f, 4.597f, 4.123f, 3.627f, 2.983f, 2.076f, - 1.525f, 1.419f, 0.943f, 1.243f, 1.537f, 1.894f, 0.723f, 1.870f, 2.272f, 3.669f, - 4.258f, 3.945f, 4.374f, 5.142f, 6.632f, 8.309f, 9.260f, 10.475f, 11.184f, 12.867f, - 13.606f -},{ --29.534f,-30.046f,-29.357f,-31.558f,-33.886f,-39.704f,-45.410f,-45.824f,-48.399f,-50.724f, --52.647f,-54.936f,-57.101f,-58.436f,-60.165f,-63.160f,-64.200f,-63.637f,-63.281f,-64.413f, --63.784f,-62.678f,-61.475f,-57.661f,-53.565f,-51.454f,-49.832f,-48.840f,-47.931f,-46.511f, --44.893f,-43.514f,-42.018f,-39.447f,-37.139f,-34.552f,-31.397f,-28.566f,-25.658f,-22.090f, --17.320f,-15.919f,-12.525f, -9.064f, -4.019f, 1.443f, 9.231f, 10.307f, 11.304f, 13.030f, - 15.151f, 17.231f, 20.439f, 22.378f, 24.102f, 26.083f, 27.338f, 27.961f, 28.352f, 27.754f, - 24.655f, 23.098f, 24.847f, 29.076f, 33.646f, 39.276f, 44.552f, 51.026f, 52.418f, 52.880f, - 52.089f, 50.614f, 48.947f, 47.067f, 45.111f, 43.716f, 38.267f, 36.288f, 33.987f, 30.811f, - 28.515f, 25.662f, 23.589f, 21.204f, 20.174f, 19.577f, 19.038f, 18.959f, 18.717f, 18.842f, - 18.712f, 17.902f, 17.579f, 17.065f, 17.035f, 15.802f, 14.660f, 13.751f, 12.141f, 10.638f, - 10.360f, 10.749f, 10.891f, 10.075f, 9.224f, 8.196f, 7.739f, 7.026f, 8.257f, 6.186f, - 4.340f, 3.233f, 1.972f, 1.492f, 0.444f, -0.571f, -2.315f, -1.196f, 0.612f, -5.372f, - -7.250f, -8.131f, -9.641f,-10.413f, -9.993f,-10.410f,-11.631f,-12.464f,-12.582f,-12.877f, --12.484f,-11.689f,-10.648f, -9.002f, -7.067f, -5.195f, -2.934f, -0.867f, 0.780f, 1.840f, - -2.420f, -9.649f, 6.880f, 3.174f, 3.746f, 3.998f, 2.967f, 2.832f, 4.008f, 6.361f, - 5.089f, 4.906f, 5.023f, 4.717f, 4.598f, 4.797f, 3.782f, 2.901f, 2.322f, 1.507f, - 0.838f, 1.018f, 0.514f, 0.591f, 1.466f, 2.053f, -0.241f, 1.508f, 2.316f, 3.512f, - 3.933f, 3.800f, 4.370f, 5.075f, 6.758f, 8.439f, 9.375f, 10.507f, 11.172f, 12.867f, - 13.606f -},{ --29.534f,-30.037f,-29.258f,-31.576f,-34.002f,-39.797f,-45.157f,-45.935f,-48.617f,-50.703f, --52.619f,-54.755f,-57.009f,-58.294f,-59.765f,-63.288f,-64.893f,-64.221f,-64.124f,-64.838f, --63.942f,-62.563f,-61.901f,-56.999f,-53.675f,-51.383f,-49.700f,-48.655f,-47.600f,-46.128f, --44.577f,-43.128f,-41.746f,-39.442f,-36.997f,-34.353f,-31.372f,-28.703f,-25.836f,-22.595f, --19.481f,-16.443f,-12.901f, -9.456f, -4.527f, -0.111f, 6.369f, 8.742f, 10.213f, 11.601f, - 12.796f, 15.554f, 18.099f, 20.216f, 22.874f, 25.442f, 27.256f, 28.482f, 30.204f, 30.975f, - 30.738f, 30.494f, 30.033f, 30.521f, 31.799f, 28.172f, 24.212f, 29.268f, 43.869f, 52.254f, - 51.967f, 49.716f, 48.360f, 46.343f, 44.143f, 41.801f, 35.763f, 33.708f, 31.177f, 29.358f, - 27.422f, 24.521f, 22.190f, 20.685f, 19.179f, 18.823f, 18.714f, 18.782f, 19.481f, 16.950f, - 17.599f, 17.187f, 17.044f, 16.434f, 16.140f, 14.531f, 12.973f, 11.420f, 10.407f, 10.151f, - 10.259f, 11.260f, 10.683f, 9.706f, 8.894f, 7.924f, 7.633f, 7.644f, 9.300f, 6.776f, - 4.718f, 3.829f, 2.697f, 1.946f, 1.504f, -0.014f, -0.666f, -3.475f, -3.566f, -6.017f, - -7.500f, -8.304f, -9.635f, -9.984f,-11.248f,-12.160f,-12.229f,-12.887f,-12.696f,-12.790f, --12.276f,-11.288f,-10.454f, -9.011f, -6.467f, -4.718f, -2.722f, -0.587f, 1.296f, 2.694f, - -0.537f,-10.810f, 7.631f, 3.260f, 4.270f, 4.870f, 3.153f, 2.315f, 4.236f, 6.669f, - 6.177f, 6.104f, 5.595f, 5.136f, 4.779f, 4.712f, 3.610f, 2.318f, 1.757f, 1.057f, - 0.483f, 0.847f, 0.186f, 0.055f, 1.411f, 2.266f, -0.612f, 1.081f, 2.379f, 3.223f, - 3.546f, 3.611f, 4.306f, 4.988f, 6.868f, 8.553f, 9.496f, 10.531f, 11.159f, 12.868f, - 13.606f -},{ --29.534f,-30.029f,-29.163f,-31.596f,-34.114f,-39.683f,-44.829f,-46.058f,-48.824f,-50.721f, --52.629f,-54.671f,-56.731f,-58.073f,-59.315f,-63.068f,-64.970f,-64.843f,-65.098f,-65.021f, --63.929f,-62.671f,-61.307f,-56.349f,-53.688f,-51.285f,-49.583f,-48.406f,-47.114f,-45.755f, --44.411f,-42.949f,-41.471f,-39.271f,-36.774f,-33.918f,-31.124f,-28.313f,-25.720f,-22.692f, --19.764f,-16.427f,-13.083f, -9.748f, -5.326f, -1.450f, 3.251f, 6.650f, 8.543f, 10.171f, - 10.559f, 12.990f, 15.811f, 18.427f, 20.773f, 23.436f, 25.633f, 27.211f, 28.565f, 29.413f, - 30.521f, 31.478f, 35.302f, 33.612f, 33.889f, 33.784f, 31.900f, 27.751f, 25.581f, 35.159f, - 43.059f, 46.825f, 46.773f, 45.278f, 42.253f, 37.978f, 32.306f, 31.888f, 30.541f, 27.966f, - 27.291f, 24.337f, 21.117f, 20.129f, 19.396f, 18.257f, 18.157f, 18.001f, 17.454f, 17.191f, - 17.179f, 16.540f, 15.918f, 15.928f, 14.760f, 13.185f, 12.447f, 11.294f, 10.004f, 9.852f, - 10.373f, 10.810f, 10.461f, 9.573f, 8.786f, 8.316f, 7.574f, 7.922f, 8.930f, 8.277f, - 5.877f, 5.021f, 4.161f, 3.460f, 1.778f, 0.807f, 6.091f, -3.368f, -4.704f, -4.117f, - -6.412f, -8.228f, -9.160f,-10.681f,-11.920f,-12.462f,-13.027f,-12.960f,-12.744f,-12.532f, --11.958f,-11.204f,-10.039f, -8.375f, -5.967f, -4.308f, -2.417f, 0.073f, 1.950f, 3.560f, - 1.488f,-10.883f, 7.249f, 4.512f, 4.922f, 5.264f, 3.368f, 5.277f, 7.250f, 7.675f, - 7.217f, 6.442f, 6.047f, 5.087f, 4.886f, 4.594f, 3.360f, 2.044f, 1.305f, 0.801f, - 0.563f, 0.854f, 0.072f, -0.083f, 1.437f, 2.494f, -0.312f, 0.733f, 2.333f, 2.976f, - 3.182f, 3.408f, 4.194f, 4.903f, 6.967f, 8.653f, 9.617f, 10.547f, 11.145f, 12.869f, - 13.606f -},{ --29.534f,-30.021f,-29.072f,-31.613f,-34.224f,-39.464f,-44.533f,-46.197f,-49.009f,-50.822f, --52.679f,-54.792f,-56.453f,-57.896f,-59.193f,-63.019f,-64.707f,-65.444f,-65.999f,-64.752f, --63.578f,-62.530f,-60.054f,-56.213f,-53.607f,-51.215f,-49.378f,-47.971f,-46.571f,-45.399f, --44.276f,-42.662f,-41.198f,-39.021f,-36.163f,-33.524f,-30.781f,-28.177f,-25.308f,-22.189f, --19.180f,-16.484f,-13.491f, -9.827f, -6.301f, -3.012f, 1.282f, 4.316f, 7.167f, 7.309f, - 9.340f, 11.647f, 14.216f, 16.886f, 19.476f, 21.496f, 23.328f, 24.276f, 25.445f, 28.040f, - 30.297f, 31.220f, 31.753f, 32.529f, 33.530f, 33.650f, 32.711f, 31.212f, 29.865f, 26.933f, - 24.113f, 25.508f, 33.445f, 36.399f, 34.319f, 26.791f, 31.479f, 29.163f, 27.392f, 27.403f, - 26.385f, 23.511f, 21.440f, 18.840f, 17.900f, 17.942f, 18.228f, 17.997f, 17.491f, 17.012f, - 16.337f, 15.591f, 15.364f, 14.863f, 13.970f, 13.030f, 11.417f, 10.632f, 10.259f, 9.948f, - 9.939f, 10.448f, 11.337f, 10.189f, 8.875f, 8.430f, 7.657f, 8.268f, 8.311f, 8.792f, - 7.782f, 5.857f, 5.439f, 4.316f, 2.856f, 0.489f, 2.433f, -2.762f, -2.896f, -4.252f, - -6.323f, -8.015f, -9.610f,-10.991f,-12.137f,-12.770f,-13.209f,-13.088f,-12.945f,-12.380f, --11.668f,-10.795f, -9.383f, -7.637f, -5.967f, -3.904f, -1.781f, 0.468f, 2.555f, 4.062f, - 2.041f, -9.613f, 6.050f, 6.463f, 5.859f, 6.310f, 3.951f, 9.853f, 9.223f, 8.416f, - 7.289f, 6.905f, 6.161f, 5.404f, 4.602f, 4.446f, 3.446f, 2.103f, 1.081f, 0.681f, - 0.879f, 0.960f, 0.194f, -0.096f, 1.469f, 2.700f, 0.135f, 0.554f, 2.198f, 2.836f, - 2.899f, 3.232f, 4.064f, 4.840f, 7.057f, 8.747f, 9.728f, 10.556f, 11.133f, 12.871f, - 13.606f -},{ --29.534f,-30.015f,-28.986f,-31.622f,-34.338f,-39.252f,-44.342f,-46.338f,-49.151f,-50.977f, --52.721f,-54.990f,-56.366f,-57.859f,-59.337f,-63.188f,-64.873f,-65.725f,-66.291f,-64.472f, --63.259f,-61.839f,-58.970f,-56.108f,-53.521f,-51.051f,-49.114f,-47.372f,-46.086f,-45.181f, --43.639f,-42.394f,-40.867f,-38.504f,-35.642f,-33.152f,-30.630f,-27.938f,-24.689f,-21.603f, --18.938f,-16.573f,-13.552f,-10.329f, -7.432f, -4.076f, -0.231f, 2.619f, 5.305f, 6.300f, - 8.195f, 10.986f, 13.284f, 15.466f, 17.876f, 19.630f, 20.789f, 22.706f, 24.469f, 26.409f, - 26.626f, 28.495f, 29.799f, 30.593f, 31.393f, 31.183f, 30.775f, 30.335f, 30.265f, 29.614f, - 28.978f, 29.178f, 25.923f, 23.597f, 22.275f, 26.920f, 33.265f, 27.730f, 26.498f, 26.326f, - 24.513f, 22.927f, 20.418f, 19.524f, 18.749f, 18.350f, 17.949f, 18.014f, 16.513f, 16.124f, - 15.212f, 14.987f, 14.793f, 13.853f, 13.632f, 13.061f, 12.013f, 11.155f, 10.756f, 10.518f, - 10.509f, 10.598f, 10.651f, 9.593f, 9.391f, 8.387f, 8.344f, 9.095f, 8.895f, 8.262f, - 8.195f, 6.903f, 6.194f, 5.236f, 3.522f, 4.631f, 4.801f, -1.468f, -1.821f, -3.202f, - -5.673f, -7.825f, -9.610f,-11.046f,-12.254f,-12.947f,-13.218f,-12.942f,-12.589f,-11.986f, --11.523f,-10.544f, -8.952f, -6.968f, -5.681f, -3.920f, -1.714f, 0.516f, 3.273f, 4.999f, - 3.335f, -7.320f, 6.053f, 8.421f, 6.925f, 6.495f, 4.728f, 11.218f, 9.458f, 9.036f, - 8.164f, 7.193f, 6.257f, 5.695f, 4.994f, 3.963f, 3.877f, 2.375f, 0.955f, 0.684f, - 1.138f, 1.153f, 0.257f, -0.254f, 1.542f, 2.830f, 0.341f, 0.619f, 2.131f, 2.731f, - 2.719f, 3.116f, 3.950f, 4.813f, 7.142f, 8.841f, 9.826f, 10.561f, 11.123f, 12.873f, - 13.606f -},{ --29.534f,-30.009f,-28.905f,-31.618f,-34.458f,-39.141f,-44.283f,-46.455f,-49.231f,-51.111f, --52.698f,-55.045f,-56.500f,-57.925f,-59.440f,-63.206f,-65.518f,-65.729f,-66.119f,-64.949f, --63.127f,-61.342f,-58.277f,-55.775f,-53.298f,-50.867f,-48.759f,-46.899f,-45.540f,-44.776f, --43.148f,-41.904f,-40.459f,-37.896f,-35.136f,-32.770f,-30.308f,-27.553f,-24.216f,-21.203f, --18.718f,-16.423f,-13.715f,-10.806f, -8.170f, -5.132f, -2.080f, 1.941f, 4.240f, 5.450f, - 6.892f, 9.932f, 12.820f, 14.884f, 16.259f, 18.611f, 19.637f, 20.222f, 21.036f, 22.826f, - 24.615f, 26.307f, 27.352f, 27.955f, 27.727f, 27.596f, 27.728f, 27.858f, 28.108f, 28.229f, - 28.912f, 29.072f, 29.433f, 28.365f, 28.428f, 28.697f, 29.815f, 25.177f, 24.622f, 24.034f, - 22.434f, 21.643f, 20.273f, 19.120f, 17.557f, 17.163f, 17.773f, 17.359f, 15.771f, 15.832f, - 15.189f, 14.651f, 13.859f, 14.009f, 13.870f, 12.785f, 11.642f, 10.985f, 10.841f, 11.135f, - 11.793f, 10.475f, 10.356f, 9.598f, 9.004f, 9.270f, 8.676f, 9.331f, 8.588f, 9.840f, - 9.279f, 7.669f, 7.284f, 6.489f, 4.110f, 5.554f, 5.704f, -0.605f, -0.747f, -2.764f, - -5.348f, -7.858f, -9.777f,-11.160f,-12.478f,-13.062f,-13.560f,-12.939f,-12.294f,-11.667f, --11.078f,-10.227f, -8.793f, -7.184f, -5.663f, -3.601f, -1.309f, 1.003f, 3.596f, 5.592f, - 4.840f, -4.679f, 3.450f, 10.150f, 8.316f, 7.410f, 7.620f, 11.356f, 10.182f, 9.477f, - 8.747f, 7.391f, 6.412f, 6.084f, 5.477f, 4.115f, 3.868f, 2.438f, 0.690f, 0.849f, - 1.055f, 1.417f, 0.217f, -0.371f, 1.857f, 2.834f, 0.449f, 0.985f, 2.297f, 2.577f, - 2.649f, 3.064f, 3.876f, 4.828f, 7.219f, 8.939f, 9.904f, 10.563f, 11.118f, 12.875f, - 13.606f -},{ --29.534f,-30.005f,-28.829f,-31.598f,-34.587f,-39.192f,-44.336f,-46.519f,-49.242f,-51.150f, --52.602f,-54.892f,-56.715f,-58.013f,-59.405f,-63.038f,-65.854f,-65.749f,-65.872f,-65.538f, --63.204f,-60.985f,-57.902f,-55.634f,-52.996f,-50.710f,-48.429f,-46.582f,-45.121f,-44.014f, --42.861f,-41.461f,-39.773f,-37.264f,-34.807f,-32.329f,-29.699f,-26.950f,-23.846f,-20.977f, --18.710f,-16.326f,-13.875f,-11.463f, -8.669f, -6.067f, -3.511f, 0.441f, 2.600f, 4.134f, - 6.166f, 8.700f, 11.071f, 14.432f, 16.238f, 17.194f, 17.223f, 18.921f, 19.963f, 21.450f, - 22.536f, 23.337f, 24.443f, 24.625f, 24.667f, 24.702f, 24.721f, 25.010f, 25.567f, 25.861f, - 26.208f, 28.909f, 27.200f, 27.420f, 26.158f, 26.001f, 29.363f, 24.284f, 23.012f, 21.939f, - 21.455f, 20.264f, 18.884f, 17.746f, 17.325f, 16.757f, 16.168f, 16.059f, 16.149f, 15.743f, - 15.218f, 14.552f, 13.856f, 13.629f, 13.083f, 12.233f, 11.619f, 11.123f, 11.454f, 11.134f, - 11.679f, 12.389f, 10.765f, 9.649f, 10.241f, 8.084f, 9.648f, 9.772f, 8.994f, 9.376f, - 8.965f, 8.268f, 7.889f, 6.980f, 4.451f, 7.464f, 3.034f, 1.034f, -0.464f, -2.532f, - -5.337f, -8.078f, -9.898f,-11.280f,-12.671f,-13.334f,-13.566f,-12.824f,-12.256f,-11.590f, --10.896f,-10.157f, -8.684f, -7.109f, -5.258f, -3.296f, -0.917f, 1.480f, 3.849f, 5.682f, - 5.494f, -1.535f, 1.591f, 12.526f, 9.878f, 9.224f, 9.670f, 11.759f, 10.607f, 10.141f, - 9.151f, 7.938f, 6.530f, 6.318f, 5.306f, 4.407f, 3.528f, 2.173f, 0.576f, 1.079f, - 0.787f, 1.529f, 0.319f, -0.285f, 2.392f, 2.674f, 0.729f, 1.556f, 2.721f, 2.408f, - 2.677f, 3.052f, 3.841f, 4.883f, 7.287f, 9.043f, 9.962f, 10.565f, 11.118f, 12.877f, - 13.606f -},{ --29.534f,-30.001f,-28.760f,-31.563f,-34.724f,-39.420f,-44.447f,-46.517f,-49.199f,-51.072f, --52.492f,-54.708f,-56.820f,-58.104f,-59.287f,-63.046f,-65.498f,-65.753f,-65.498f,-65.093f, --63.471f,-60.300f,-57.698f,-55.381f,-52.867f,-50.423f,-48.029f,-46.129f,-44.709f,-43.412f, --42.550f,-41.085f,-39.040f,-36.683f,-34.449f,-31.844f,-29.421f,-26.669f,-23.625f,-21.212f, --18.942f,-16.452f,-14.028f,-11.703f, -9.364f, -6.824f, -4.233f, -0.709f, 1.620f, 4.322f, - 5.962f, 7.767f, 11.886f, 12.791f, 14.180f, 15.641f, 16.220f, 17.598f, 18.691f, 19.390f, - 20.527f, 21.362f, 21.812f, 21.516f, 21.544f, 21.770f, 22.188f, 22.643f, 22.887f, 22.938f, - 23.238f, 24.748f, 24.913f, 23.869f, 22.749f, 22.523f, 23.556f, 21.463f, 20.494f, 20.408f, - 19.877f, 18.856f, 17.923f, 16.583f, 16.775f, 16.807f, 16.640f, 16.367f, 16.419f, 14.855f, - 14.624f, 14.270f, 14.320f, 13.566f, 13.174f, 12.452f, 12.074f, 11.794f, 12.288f, 11.642f, - 11.979f, 11.787f, 11.546f, 10.420f, 10.513f, 9.681f, 9.901f, 9.702f, 9.811f, 9.934f, - 8.852f, 8.965f, 8.422f, 7.040f, 5.560f, 6.138f, 5.272f, 1.695f, 0.366f, -2.379f, - -5.507f, -8.036f,-10.020f,-11.366f,-12.507f,-13.247f,-13.619f,-13.021f,-12.222f,-11.311f, --10.612f, -9.893f, -8.568f, -6.945f, -4.673f, -2.906f, -0.752f, 1.341f, 3.903f, 5.965f, - 6.550f, 2.120f, -2.052f, 13.938f, 10.879f, 10.333f, 11.579f, 11.974f, 10.890f, 10.752f, - 9.732f, 8.451f, 6.910f, 6.529f, 5.281f, 4.308f, 3.665f, 1.995f, 0.599f, 1.046f, - 0.756f, 1.306f, 0.424f, -0.200f, 2.704f, 2.304f, 1.116f, 2.065f, 3.255f, 2.352f, - 2.756f, 3.042f, 3.830f, 4.967f, 7.346f, 9.151f, 9.998f, 10.569f, 11.124f, 12.879f, - 13.606f -},{ --29.534f,-29.999f,-28.696f,-31.514f,-34.867f,-39.795f,-44.557f,-46.458f,-49.132f,-50.916f, --52.450f,-54.724f,-56.712f,-58.238f,-59.030f,-63.281f,-65.051f,-65.579f,-65.140f,-64.146f, --63.427f,-59.741f,-57.625f,-55.194f,-52.756f,-50.305f,-47.732f,-45.784f,-44.377f,-42.973f, --42.086f,-40.584f,-38.419f,-36.388f,-34.031f,-31.389f,-29.104f,-26.353f,-23.836f,-21.275f, --18.805f,-16.403f,-14.033f,-11.918f, -9.621f, -7.619f, -4.631f, -2.159f, 0.577f, 3.190f, - 5.485f, 9.603f, 12.152f, 11.671f, 13.666f, 14.462f, 15.522f, 15.907f, 16.718f, 17.480f, - 18.629f, 19.169f, 19.191f, 19.103f, 19.580f, 19.419f, 19.649f, 19.899f, 20.548f, 20.290f, - 21.093f, 20.970f, 21.162f, 20.172f, 19.884f, 19.891f, 19.473f, 19.341f, 18.350f, 18.546f, - 18.306f, 17.422f, 17.195f, 16.814f, 16.870f, 16.902f, 16.701f, 16.297f, 15.494f, 14.319f, - 14.752f, 14.425f, 13.939f, 13.678f, 13.630f, 13.114f, 12.844f, 12.165f, 12.251f, 12.274f, - 12.247f, 11.941f, 11.831f, 11.591f, 11.036f, 10.393f, 10.315f, 10.141f, 8.766f, 8.979f, - 9.479f, 9.188f, 8.918f, 6.557f, 7.289f, 14.278f, 4.606f, 2.239f, 0.845f, -2.383f, - -5.767f, -8.121f,-10.111f,-11.273f,-12.235f,-13.244f,-13.850f,-13.003f,-12.203f,-11.409f, --10.830f,-10.027f, -8.577f, -6.906f, -4.545f, -2.735f, -0.394f, 2.038f, 4.099f, 6.167f, - 7.376f, 5.491f, -2.751f, 13.531f, 12.593f, 12.166f, 12.796f, 12.168f, 11.525f, 11.455f, - 10.493f, 9.223f, 7.745f, 6.664f, 5.250f, 4.882f, 4.071f, 2.074f, 0.577f, 0.867f, - 0.936f, 0.907f, 0.247f, -0.249f, 2.412f, 1.742f, 1.371f, 2.317f, 3.686f, 2.487f, - 2.791f, 3.005f, 3.816f, 5.064f, 7.400f, 9.260f, 10.014f, 10.577f, 11.137f, 12.882f, - 13.606f -},{ --29.534f,-29.997f,-28.640f,-31.456f,-35.014f,-40.257f,-44.617f,-46.369f,-49.072f,-50.748f, --52.505f,-54.955f,-56.436f,-58.442f,-58.685f,-63.369f,-65.128f,-65.410f,-65.138f,-63.899f, --62.770f,-59.617f,-57.513f,-55.164f,-52.481f,-50.166f,-47.581f,-45.368f,-43.936f,-42.785f, --41.450f,-39.778f,-37.869f,-36.017f,-33.201f,-31.032f,-28.856f,-26.153f,-23.840f,-21.147f, --18.581f,-16.099f,-14.109f,-12.078f,-10.253f, -8.038f, -5.249f, -2.479f, 0.391f, 2.453f, - 4.779f, 8.322f, 8.911f, 11.225f, 12.189f, 12.918f, 13.615f, 14.353f, 15.034f, 15.682f, - 16.451f, 17.089f, 17.196f, 17.470f, 17.278f, 16.956f, 17.218f, 17.618f, 17.890f, 17.501f, - 17.841f, 17.860f, 17.657f, 17.385f, 17.031f, 17.225f, 17.016f, 17.043f, 16.895f, 16.836f, - 17.248f, 16.759f, 16.860f, 16.671f, 17.500f, 17.006f, 16.237f, 15.845f, 15.298f, 15.740f, - 14.615f, 14.283f, 13.999f, 13.909f, 13.498f, 13.117f, 13.183f, 13.278f, 12.805f, 13.164f, - 12.675f, 12.554f, 12.348f, 11.619f, 10.965f, 11.008f, 9.456f, 9.434f, 9.083f, 8.656f, - 8.974f, 9.694f, 8.804f, 6.073f, 12.246f, 7.444f, 3.026f, 2.862f, 0.583f, -2.528f, - -5.534f, -8.190f,-10.013f,-11.182f,-11.845f,-13.177f,-13.821f,-13.117f,-12.355f,-11.676f, --10.894f, -9.816f, -8.199f, -6.886f, -4.742f, -2.641f, -0.434f, 1.764f, 4.314f, 6.573f, - 8.040f, 7.551f, -0.422f, 9.942f, 15.037f, 13.905f, 12.973f, 12.983f, 12.043f, 11.807f, - 11.396f, 9.913f, 8.485f, 6.815f, 5.358f, 5.672f, 4.429f, 2.175f, 0.816f, 0.914f, - 0.934f, 0.528f, -0.010f, -0.274f, 1.664f, 1.136f, 1.460f, 2.394f, 3.887f, 2.733f, - 2.672f, 2.937f, 3.782f, 5.159f, 7.458f, 9.362f, 10.013f, 10.590f, 11.157f, 12.885f, - 13.606f -},{ --29.534f,-29.997f,-28.590f,-31.393f,-35.162f,-40.728f,-44.605f,-46.286f,-49.030f,-50.619f, --52.612f,-55.151f,-56.149f,-58.689f,-58.708f,-63.232f,-65.443f,-65.406f,-65.165f,-64.068f, --62.015f,-59.576f,-57.319f,-54.806f,-52.426f,-49.934f,-47.499f,-44.868f,-43.321f,-42.407f, --40.845f,-39.322f,-37.409f,-35.312f,-32.635f,-30.871f,-28.381f,-25.957f,-23.492f,-21.120f, --18.552f,-16.218f,-14.180f,-12.264f,-10.306f, -8.317f, -5.548f, -2.583f, 0.061f, 2.349f, - 5.946f, 5.897f, 8.078f, 9.967f, 10.778f, 11.571f, 12.112f, 12.412f, 13.064f, 13.880f, - 14.902f, 15.090f, 15.165f, 15.176f, 15.192f, 15.218f, 15.470f, 15.699f, 15.442f, 15.548f, - 15.811f, 15.822f, 15.684f, 15.697f, 15.720f, 15.437f, 15.642f, 15.458f, 15.410f, 16.646f, - 15.843f, 15.944f, 16.576f, 16.845f, 16.701f, 16.819f, 16.847f, 15.783f, 15.229f, 14.891f, - 14.374f, 14.657f, 14.207f, 13.892f, 13.720f, 14.072f, 14.138f, 13.498f, 13.089f, 13.434f, - 13.280f, 13.343f, 12.370f, 11.692f, 11.208f, 9.788f, 9.576f, 9.011f, 8.297f, 8.232f, - 8.691f, 9.314f, 8.581f, 6.764f, 14.056f, 3.079f, 3.716f, 2.688f, 0.220f, -2.802f, - -5.694f, -8.060f, -9.946f,-11.025f,-11.999f,-13.084f,-13.286f,-13.190f,-12.264f,-11.671f, --11.017f, -9.510f, -8.228f, -6.802f, -4.645f, -2.510f, -0.525f, 1.851f, 4.357f, 6.663f, - 8.493f, 8.771f, 2.441f, 3.704f, 17.563f, 14.269f, 13.692f, 13.435f, 12.896f, 12.495f, - 11.787f, 10.516f, 9.000f, 7.167f, 5.890f, 6.309f, 4.894f, 2.235f, 1.145f, 0.899f, - 0.628f, 0.165f, -0.074f, -0.206f, 0.953f, 0.614f, 1.449f, 2.476f, 3.852f, 2.907f, - 2.346f, 2.853f, 3.725f, 5.242f, 7.531f, 9.453f, 9.998f, 10.610f, 11.184f, 12.889f, - 13.606f -},{ --29.534f,-29.997f,-28.548f,-31.332f,-35.311f,-41.138f,-44.525f,-46.238f,-48.995f,-50.543f, --52.697f,-55.017f,-56.011f,-58.892f,-59.536f,-63.317f,-65.353f,-65.333f,-64.767f,-63.800f, --61.656f,-59.360f,-57.113f,-54.418f,-52.427f,-49.729f,-47.223f,-44.559f,-42.838f,-42.001f, --40.405f,-38.815f,-36.816f,-34.662f,-32.251f,-30.497f,-28.039f,-25.550f,-23.185f,-21.094f, --18.356f,-16.107f,-14.155f,-11.956f,-10.482f, -8.553f, -5.608f, -2.705f, -0.937f, 3.910f, - 2.689f, 5.801f, 7.188f, 8.161f, 9.398f, 10.354f, 10.586f, 11.160f, 11.658f, 12.136f, - 13.523f, 13.599f, 13.397f, 13.375f, 13.557f, 13.805f, 14.182f, 14.142f, 13.642f, 14.107f, - 14.545f, 13.548f, 14.237f, 14.117f, 13.654f, 13.749f, 14.213f, 13.691f, 14.781f, 14.603f, - 14.939f, 15.204f, 16.291f, 16.234f, 16.103f, 16.966f, 17.106f, 15.492f, 15.030f, 14.487f, - 15.143f, 14.968f, 14.630f, 14.866f, 14.027f, 14.465f, 14.240f, 14.011f, 13.103f, 13.314f, - 14.819f, 13.063f, 11.845f, 11.122f, 10.022f, 9.560f, 9.252f, 8.348f, 7.707f, 7.984f, - 8.613f, 9.156f, 8.676f, 8.382f, 9.571f, 3.933f, 4.162f, 2.581f, -0.223f, -3.281f, - -5.973f, -8.320f, -9.728f,-10.927f,-12.115f,-13.120f,-13.099f,-12.961f,-12.175f,-11.606f, --11.350f, -9.948f, -8.613f, -7.189f, -4.850f, -2.798f, -0.541f, 1.805f, 4.186f, 6.646f, - 8.610f, 9.708f, 5.775f, 0.037f, 17.655f, 15.527f, 14.288f, 14.052f, 13.610f, 12.832f, - 11.887f, 10.994f, 9.666f, 7.774f, 6.395f, 6.706f, 5.090f, 2.521f, 1.372f, 0.831f, - 0.296f, -0.104f, -0.038f, -0.156f, 0.575f, 0.113f, 1.182f, 2.519f, 3.627f, 2.890f, - 1.873f, 2.765f, 3.661f, 5.310f, 7.629f, 9.527f, 9.972f, 10.637f, 11.219f, 12.892f, - 13.606f -},{ --29.534f,-29.999f,-28.514f,-31.281f,-35.459f,-41.436f,-44.406f,-46.234f,-48.942f,-50.500f, --52.714f,-54.493f,-56.053f,-58.902f,-60.873f,-63.862f,-64.865f,-65.068f,-64.309f,-63.343f, --61.659f,-59.038f,-56.649f,-54.276f,-52.141f,-49.484f,-46.981f,-44.145f,-42.416f,-41.442f, --39.789f,-38.258f,-36.057f,-33.900f,-32.049f,-29.966f,-27.679f,-25.186f,-23.088f,-20.930f, --18.355f,-15.838f,-14.004f,-12.017f,-10.648f, -8.439f, -5.565f, -3.226f, 0.115f, 1.915f, - 3.090f, 4.965f, 6.351f, 7.469f, 8.507f, 9.004f, 9.270f, 9.995f, 10.819f, 11.424f, - 11.776f, 11.729f, 12.185f, 12.000f, 11.849f, 12.010f, 12.353f, 12.618f, 12.550f, 13.518f, - 13.131f, 12.427f, 13.297f, 12.081f, 12.392f, 12.892f, 12.806f, 13.316f, 14.439f, 14.766f, - 15.501f, 14.988f, 14.935f, 15.017f, 15.914f, 16.460f, 16.573f, 15.242f, 15.090f, 15.010f, - 15.902f, 15.114f, 15.291f, 14.817f, 14.947f, 15.261f, 15.251f, 14.404f, 14.538f, 13.443f, - 13.388f, 12.909f, 10.910f, 10.512f, 9.540f, 8.752f, 8.295f, 7.944f, 7.741f, 7.864f, - 8.757f, 9.080f, 8.335f, 10.019f, 6.925f, 3.983f, 3.646f, 1.650f, -0.926f, -3.896f, - -6.464f, -8.256f, -9.470f,-10.891f,-12.482f,-13.176f,-13.332f,-13.222f,-12.245f,-11.906f, --11.453f,-10.466f, -8.845f, -7.512f, -5.238f, -3.107f, -0.469f, 1.729f, 4.096f, 6.511f, - 8.728f, 10.151f, 8.211f, 0.443f, 16.218f, 16.533f, 14.706f, 14.568f, 14.098f, 13.422f, - 12.096f, 11.329f, 10.394f, 8.633f, 6.845f, 6.806f, 5.257f, 3.079f, 1.986f, 1.372f, - 0.098f, -0.131f, 0.080f, -0.180f, 0.413f, -0.484f, 0.444f, 2.295f, 3.252f, 2.723f, - 1.398f, 2.667f, 3.617f, 5.365f, 7.757f, 9.582f, 9.940f, 10.671f, 11.262f, 12.897f, - 13.606f -},{ --29.534f,-30.001f,-28.489f,-31.246f,-35.609f,-41.603f,-44.284f,-46.263f,-48.853f,-50.461f, --52.677f,-53.809f,-56.132f,-58.597f,-61.891f,-64.425f,-64.530f,-64.853f,-64.167f,-63.174f, --61.799f,-58.915f,-56.111f,-54.146f,-51.927f,-49.352f,-46.884f,-43.816f,-42.178f,-40.745f, --39.186f,-37.487f,-35.212f,-33.257f,-31.310f,-29.515f,-27.170f,-24.903f,-22.888f,-20.535f, --18.449f,-16.124f,-13.790f,-12.196f,-10.457f, -8.303f, -5.456f, -3.323f, -0.136f, 0.374f, - 2.640f, 4.197f, 5.185f, 6.096f, 6.942f, 7.700f, 7.973f, 8.859f, 9.588f, 10.012f, - 10.160f, 10.191f, 10.386f, 10.224f, 10.104f, 10.416f, 11.134f, 11.797f, 12.162f, 12.284f, - 12.307f, 11.637f, 13.415f, 11.675f, 11.584f, 11.823f, 12.582f, 13.776f, 14.137f, 14.984f, - 15.160f, 14.781f, 14.564f, 14.406f, 14.876f, 16.287f, 15.604f, 15.178f, 14.959f, 14.825f, - 15.523f, 15.605f, 15.764f, 15.526f, 16.270f, 15.927f, 15.140f, 13.802f, 14.328f, 13.743f, - 12.890f, 11.766f, 10.254f, 9.543f, 8.505f, 8.041f, 7.627f, 6.987f, 7.246f, 7.590f, - 8.591f, 8.804f, 7.876f, 10.649f, 4.725f, 3.791f, 2.883f, 1.110f, -1.526f, -4.470f, - -6.811f, -8.498f, -8.932f,-11.209f,-12.867f,-13.612f,-13.846f,-13.661f,-12.714f,-12.524f, --11.978f,-11.076f, -9.501f, -8.008f, -5.702f, -3.171f, -0.315f, 1.855f, 3.897f, 6.234f, - 8.430f, 10.431f, 9.685f, 2.178f, 12.575f, 16.692f, 15.000f, 14.895f, 14.500f, 13.942f, - 12.883f, 11.781f, 10.852f, 9.546f, 7.453f, 7.198f, 5.577f, 3.599f, 2.890f, 2.435f, - -0.156f, -0.080f, 0.371f, -0.340f, 0.150f, -1.065f, -0.559f, 1.739f, 2.772f, 2.530f, - 1.051f, 2.535f, 3.614f, 5.410f, 7.908f, 9.621f, 9.904f, 10.710f, 11.310f, 12.902f, - 13.606f -},{ --29.534f,-30.005f,-28.473f,-31.233f,-35.765f,-41.651f,-44.193f,-46.300f,-48.732f,-50.412f, --52.614f,-53.286f,-56.028f,-58.033f,-62.222f,-64.479f,-64.565f,-64.759f,-64.000f,-62.969f, --61.818f,-59.012f,-55.793f,-53.885f,-51.821f,-49.234f,-46.553f,-43.656f,-41.628f,-40.104f, --38.632f,-36.740f,-34.500f,-32.598f,-30.446f,-28.901f,-26.635f,-24.520f,-22.451f,-20.296f, --18.047f,-16.145f,-13.918f,-12.233f,-10.367f, -8.209f, -5.589f, -2.865f, -1.700f, 0.326f, - 1.878f, 3.376f, 4.356f, 5.502f, 6.011f, 6.322f, 6.940f, 7.666f, 8.268f, 8.380f, - 8.551f, 8.644f, 8.736f, 8.802f, 8.993f, 9.914f, 10.914f, 11.302f, 11.260f, 11.710f, - 11.269f, 11.046f, 11.498f, 11.322f, 10.670f, 10.509f, 11.718f, 13.173f, 14.438f, 14.682f, - 13.987f, 13.077f, 14.165f, 13.788f, 14.756f, 14.869f, 15.133f, 14.939f, 14.418f, 14.791f, - 15.915f, 15.846f, 15.321f, 16.396f, 16.865f, 15.882f, 15.860f, 14.896f, 13.795f, 12.894f, - 12.491f, 10.783f, 9.732f, 8.488f, 7.538f, 7.126f, 6.974f, 6.368f, 6.597f, 7.277f, - 8.253f, 8.088f, 7.397f, 12.384f, 4.865f, 3.786f, 2.673f, 0.463f, -1.964f, -4.362f, - -6.938f, -8.556f, -9.935f,-11.871f,-13.244f,-13.923f,-14.287f,-14.204f,-13.358f,-13.027f, --12.278f,-11.100f, -9.981f, -8.090f, -5.871f, -3.367f, -0.529f, 1.703f, 3.672f, 5.730f, - 8.099f, 10.464f, 10.756f, 4.362f, 8.328f, 17.346f, 15.273f, 15.056f, 15.326f, 14.884f, - 13.431f, 12.261f, 11.345f, 10.506f, 8.305f, 7.640f, 5.933f, 4.142f, 3.599f, 3.438f, - -0.522f, -0.313f, 0.578f, -0.638f, -0.436f, -1.400f, -1.244f, 1.095f, 2.239f, 2.350f, - 0.866f, 2.346f, 3.661f, 5.445f, 8.069f, 9.645f, 9.869f, 10.755f, 11.365f, 12.907f, - 13.606f -},{ --29.534f,-30.009f,-28.466f,-31.247f,-35.928f,-41.621f,-44.152f,-46.319f,-48.607f,-50.360f, --52.531f,-53.087f,-55.636f,-57.439f,-62.307f,-64.127f,-64.655f,-64.559f,-63.612f,-62.521f, --61.649f,-58.990f,-55.670f,-53.713f,-51.740f,-48.987f,-46.242f,-43.322f,-41.344f,-39.621f, --37.890f,-35.961f,-33.880f,-31.969f,-29.983f,-28.068f,-26.072f,-24.074f,-21.947f,-19.874f, --18.124f,-16.092f,-14.360f,-12.337f,-10.143f, -8.006f, -4.111f, -3.856f, -2.175f, -0.595f, - 1.188f, 2.940f, 4.321f, 4.897f, 5.061f, 5.429f, 6.261f, 6.763f, 6.968f, 6.908f, - 7.000f, 7.183f, 7.436f, 7.465f, 8.307f, 9.048f, 9.712f, 9.943f, 10.848f, 10.909f, - 10.228f, 10.461f, 10.379f, 9.954f, 10.190f, 9.769f, 10.399f, 11.696f, 12.642f, 12.250f, - 12.574f, 12.305f, 12.390f, 13.133f, 14.275f, 14.340f, 14.254f, 14.566f, 14.688f, 15.267f, - 15.603f, 15.934f, 15.959f, 16.671f, 15.867f, 16.538f, 16.757f, 15.252f, 13.498f, 12.845f, - 11.141f, 9.932f, 9.100f, 7.712f, 6.545f, 6.223f, 5.860f, 6.277f, 6.800f, 7.514f, - 7.861f, 7.185f, 7.611f, 7.473f, 4.462f, 3.516f, 2.292f, 0.278f, -2.505f, -5.553f, - -7.932f, -9.469f,-10.672f,-12.526f,-13.693f,-14.339f,-14.615f,-14.687f,-13.994f,-13.399f, --12.610f,-11.095f,-10.175f, -8.318f, -6.055f, -3.878f, -1.179f, 1.128f, 3.291f, 5.446f, - 7.644f, 10.350f, 11.341f, 6.671f, 7.172f, 17.659f, 15.663f, 14.851f, 15.427f, 15.139f, - 14.513f, 12.799f, 11.740f, 11.028f, 9.233f, 8.024f, 6.423f, 4.754f, 4.065f, 4.099f, - -0.742f, -0.846f, 0.442f, -0.792f, -1.390f, -1.544f, -1.285f, 0.605f, 1.678f, 2.069f, - 0.769f, 2.111f, 3.744f, 5.467f, 8.219f, 9.662f, 9.836f, 10.804f, 11.426f, 12.913f, - 13.606f -},{ --29.534f,-30.015f,-28.468f,-31.290f,-36.102f,-41.567f,-44.169f,-46.310f,-48.511f,-50.323f, --52.415f,-53.119f,-55.045f,-57.021f,-62.618f,-63.864f,-64.545f,-64.245f,-63.299f,-62.189f, --61.418f,-58.785f,-55.927f,-53.806f,-51.559f,-48.689f,-45.868f,-42.987f,-40.967f,-39.033f, --37.334f,-35.186f,-33.315f,-31.425f,-29.590f,-27.315f,-25.582f,-23.596f,-21.478f,-19.732f, --18.453f,-16.375f,-14.369f,-12.196f, -9.906f, -8.089f, -5.520f, -4.498f, -2.465f, -0.947f, - 0.935f, 2.619f, 3.895f, 4.021f, 3.902f, 4.791f, 5.282f, 5.611f, 5.825f, 5.727f, - 5.591f, 5.805f, 6.268f, 6.763f, 7.306f, 7.906f, 8.248f, 8.969f, 9.952f, 11.038f, - 9.328f, 10.440f, 8.893f, 9.351f, 9.184f, 9.000f, 9.137f, 9.529f, 10.315f, 10.760f, - 10.868f, 11.198f, 12.197f, 12.493f, 13.020f, 14.005f, 13.950f, 14.373f, 15.265f, 15.314f, - 16.312f, 16.111f, 16.739f, 16.788f, 16.883f, 16.339f, 15.812f, 15.250f, 14.126f, 11.550f, - 10.242f, 9.234f, 7.946f, 6.870f, 5.920f, 5.333f, 5.146f, 5.562f, 6.844f, 7.480f, - 7.547f, 6.429f, 14.262f, 4.126f, 3.643f, 3.271f, 1.704f, -0.608f, -3.404f, -6.560f, - -8.706f,-10.315f,-11.323f,-12.959f,-14.235f,-14.704f,-15.019f,-14.975f,-14.440f,-13.849f, --13.099f,-11.593f,-10.356f, -8.706f, -6.620f, -4.233f, -1.960f, 0.355f, 2.900f, 5.104f, - 7.369f, 10.006f, 11.373f, 8.912f, 7.743f, 17.103f, 16.934f, 14.329f, 15.425f, 15.360f, - 15.195f, 13.678f, 11.882f, 10.899f, 9.817f, 8.565f, 6.702f, 5.193f, 4.153f, 4.186f, - -0.723f, -1.246f, 0.161f, -0.694f, -2.636f, -1.824f, -0.954f, 0.225f, 1.078f, 1.527f, - 0.658f, 1.883f, 3.837f, 5.470f, 8.334f, 9.678f, 9.809f, 10.855f, 11.490f, 12.920f, - 13.606f -},{ --29.534f,-30.021f,-28.480f,-31.360f,-36.285f,-41.544f,-44.235f,-46.277f,-48.459f,-50.319f, --52.277f,-53.167f,-54.444f,-56.778f,-63.010f,-63.878f,-64.316f,-64.020f,-63.095f,-62.036f, --61.054f,-58.531f,-56.223f,-53.673f,-51.103f,-48.573f,-45.439f,-42.807f,-40.330f,-38.518f, --36.717f,-34.569f,-32.616f,-30.706f,-29.005f,-26.928f,-25.156f,-23.095f,-21.026f,-20.449f, --18.113f,-16.451f,-14.466f,-11.998f, -9.843f, -7.650f, -6.674f, -4.328f, -2.630f, -1.143f, - 0.784f, 2.382f, 3.121f, 3.066f, 3.144f, 3.433f, 4.003f, 4.522f, 4.429f, 4.142f, - 4.236f, 4.461f, 4.829f, 5.417f, 6.045f, 6.588f, 6.677f, 7.535f, 8.564f, 8.745f, - 8.802f, 9.297f, 7.844f, 8.056f, 8.370f, 8.234f, 8.161f, 8.815f, 9.295f, 9.232f, - 9.670f, 9.483f, 10.443f, 11.596f, 12.215f, 13.409f, 14.281f, 14.470f, 15.386f, 15.473f, - 16.641f, 16.859f, 17.355f, 17.924f, 17.487f, 16.626f, 16.201f, 14.511f, 12.869f, 11.525f, - 9.761f, 8.298f, 7.531f, 6.038f, 5.022f, 4.500f, 4.495f, 5.499f, 6.946f, 7.276f, - 6.597f, 6.071f, 10.866f, 4.229f, 3.695f, 2.769f, 0.862f, -1.835f, -4.803f, -7.513f, - -9.586f,-11.165f,-12.390f,-13.502f,-14.755f,-15.197f,-15.369f,-15.201f,-14.914f,-13.748f, --13.097f,-11.974f,-10.721f, -9.476f, -7.390f, -5.001f, -2.779f, -0.294f, 2.141f, 4.606f, - 7.123f, 9.551f, 10.988f, 10.478f, 7.889f, 15.502f, 16.344f, 14.563f, 15.362f, 15.355f, - 14.803f, 13.750f, 12.085f, 10.576f, 9.681f, 8.828f, 7.110f, 5.484f, 3.940f, 3.801f, - -0.666f, -1.196f, -0.107f, -0.935f, -3.945f, -2.402f, -0.740f, -0.207f, 0.480f, 0.715f, - 0.492f, 1.725f, 3.906f, 5.452f, 8.395f, 9.699f, 9.791f, 10.907f, 11.557f, 12.928f, - 13.606f -},{ --29.534f,-30.028f,-28.502f,-31.455f,-36.474f,-41.594f,-44.333f,-46.241f,-48.436f,-50.353f, --52.182f,-53.087f,-53.945f,-56.576f,-63.122f,-63.908f,-64.060f,-63.849f,-62.809f,-61.763f, --60.581f,-58.428f,-56.099f,-53.269f,-50.726f,-48.398f,-45.148f,-42.266f,-39.903f,-38.035f, --35.998f,-34.047f,-32.103f,-30.005f,-28.179f,-26.411f,-24.799f,-22.862f,-21.005f,-20.810f, --18.188f,-16.526f,-14.282f,-11.878f, -9.753f, -6.929f, -6.989f, -4.807f, -3.599f, -1.474f, - 0.147f, 1.346f, 1.858f, 1.868f, 1.718f, 2.200f, 2.724f, 3.035f, 2.955f, 3.040f, - 3.083f, 3.118f, 3.607f, 4.102f, 4.495f, 5.103f, 5.609f, 6.027f, 7.560f, 6.819f, - 9.629f, 7.585f, 7.428f, 7.227f, 7.285f, 7.307f, 7.427f, 8.007f, 8.011f, 8.028f, - 8.267f, 12.384f, 9.589f, 10.873f, 11.638f, 12.867f, 13.715f, 14.750f, 15.380f, 15.820f, - 16.411f, 17.205f, 18.362f, 17.158f, 17.298f, 16.171f, 15.287f, 13.499f, 12.138f, 11.248f, - 8.587f, 7.538f, 6.146f, 4.954f, 3.971f, 3.440f, 4.165f, 5.254f, 6.843f, 7.269f, - 5.368f, 12.054f, 6.970f, 2.983f, 3.761f, 2.258f, -0.197f, -3.227f, -6.090f, -8.644f, --10.566f,-11.992f,-13.260f,-14.239f,-15.020f,-15.623f,-15.660f,-15.778f,-15.474f,-14.762f, --13.346f,-12.286f,-11.258f,-10.083f, -7.990f, -5.710f, -3.530f, -1.021f, 1.407f, 4.025f, - 6.753f, 8.750f, 10.519f, 11.042f, 8.082f, 14.369f, 14.376f, 15.534f, 15.120f, 15.000f, - 14.665f, 13.656f, 12.202f, 10.959f, 9.695f, 8.595f, 7.475f, 5.782f, 4.072f, 3.315f, - -0.680f, -0.984f, -0.586f, -2.002f, -4.924f, -3.129f, -0.877f, -0.646f, 0.028f, -0.168f, - 0.310f, 1.673f, 3.929f, 5.418f, 8.394f, 9.730f, 9.784f, 10.960f, 11.626f, 12.937f, - 13.606f -},{ --29.534f,-30.037f,-28.533f,-31.568f,-36.662f,-41.733f,-44.441f,-46.216f,-48.397f,-50.408f, --52.205f,-52.909f,-53.552f,-56.343f,-63.008f,-63.726f,-63.745f,-63.565f,-62.528f,-61.399f, --60.397f,-58.533f,-55.876f,-52.943f,-50.486f,-47.995f,-44.996f,-41.825f,-39.570f,-37.379f, --35.332f,-33.379f,-31.476f,-29.606f,-27.381f,-25.910f,-24.295f,-22.494f,-21.983f,-20.127f, --18.320f,-16.317f,-13.925f,-11.922f, -9.746f, -7.877f, -6.721f, -5.343f, -3.578f, -1.460f, - -0.271f, 0.660f, 0.692f, 0.767f, 1.033f, 1.457f, 1.772f, 1.990f, 2.140f, 1.795f, - 2.042f, 2.187f, 2.182f, 2.366f, 3.099f, 3.588f, 4.421f, 4.626f, 4.861f, 6.303f, - 6.824f, 6.163f, 6.795f, 6.681f, 6.688f, 7.080f, 6.923f, 7.197f, 7.311f, 7.880f, - 7.983f, 8.688f, 9.515f, 10.574f, 11.770f, 12.685f, 13.999f, 14.580f, 14.840f, 15.763f, - 16.385f, 17.445f, 17.966f, 16.764f, 16.124f, 15.408f, 14.209f, 12.929f, 11.345f, 9.630f, - 8.024f, 6.448f, 5.249f, 3.825f, 2.835f, 2.699f, 3.726f, 4.796f, 5.600f, 6.118f, - 6.130f, 15.271f, 1.632f, 2.624f, 3.157f, 1.286f, -1.774f, -4.598f, -7.283f, -9.577f, --11.371f,-12.749f,-13.953f,-14.911f,-15.533f,-16.083f,-16.044f,-16.184f,-15.751f,-15.181f, --14.244f,-13.131f,-11.909f,-10.563f, -8.599f, -6.518f, -4.122f, -1.593f, 0.527f, 3.380f, - 6.079f, 7.904f, 10.010f, 11.369f, 8.359f, 13.154f, 13.069f, 15.050f, 15.169f, 15.285f, - 14.991f, 13.863f, 11.863f, 11.575f, 10.209f, 8.599f, 7.417f, 6.370f, 5.005f, 2.864f, - -0.666f, -1.060f, -1.342f, -3.376f, -5.340f, -3.840f, -1.344f, -0.902f, -0.151f, -0.862f, - 0.173f, 1.699f, 3.905f, 5.381f, 8.335f, 9.771f, 9.792f, 11.013f, 11.696f, 12.946f, - 13.606f -},{ --29.534f,-30.046f,-28.574f,-31.691f,-36.837f,-41.952f,-44.535f,-46.205f,-48.289f,-50.453f, --52.359f,-52.785f,-53.276f,-56.119f,-62.892f,-63.419f,-63.424f,-63.220f,-62.305f,-61.181f, --60.498f,-58.356f,-55.654f,-52.571f,-50.192f,-47.612f,-44.833f,-41.529f,-39.082f,-36.854f, --34.814f,-32.863f,-30.902f,-29.000f,-26.874f,-25.380f,-23.772f,-22.085f,-22.123f,-19.645f, --18.145f,-15.964f,-13.666f,-11.543f, -9.188f, -8.394f, -7.107f, -5.901f, -4.149f, -2.317f, - -0.757f, 0.046f, -0.257f, -0.209f, -0.115f, 0.370f, 1.065f, 1.145f, 1.084f, 1.238f, - 1.283f, 1.115f, 1.069f, 1.560f, 1.917f, 2.672f, 3.387f, 3.480f, 4.040f, 4.910f, - 5.211f, 5.086f, 5.708f, 6.217f, 6.647f, 6.234f, 6.361f, 6.678f, 6.652f, 6.908f, - 7.305f, 7.953f, 9.202f, 10.660f, 11.874f, 12.521f, 13.587f, 14.443f, 15.044f, 15.757f, - 16.625f, 16.294f, 16.306f, 15.965f, 15.349f, 14.983f, 13.334f, 11.842f, 10.098f, 8.585f, - 7.066f, 5.644f, 4.634f, 2.915f, 1.931f, 1.871f, 2.988f, 3.560f, 3.458f, 13.203f, - 18.149f, 9.833f, -0.706f, 2.682f, 2.397f, -0.141f, -3.321f, -6.006f, -8.386f,-10.472f, --12.115f,-13.173f,-14.127f,-15.119f,-15.899f,-16.329f,-16.697f,-16.996f,-16.735f,-15.891f, --14.756f,-13.770f,-12.564f,-11.176f, -9.378f, -7.454f, -4.932f, -2.433f, -0.217f, 2.638f, - 5.144f, 7.186f, 9.689f, 11.638f, 9.173f, 11.724f, 12.440f, 12.031f, 15.585f, 15.486f, - 15.041f, 13.979f, 12.308f, 11.582f, 10.430f, 9.101f, 7.668f, 7.154f, 6.470f, 2.605f, - -0.541f, -1.386f, -2.061f, -4.363f, -5.461f, -4.442f, -2.031f, -0.999f, -0.156f, -1.261f, - 0.092f, 1.730f, 3.848f, 5.361f, 8.232f, 9.822f, 9.816f, 11.066f, 11.765f, 12.957f, - 13.606f -},{ --29.534f,-30.056f,-28.622f,-31.815f,-36.986f,-42.221f,-44.595f,-46.184f,-48.078f,-50.450f, --52.547f,-52.837f,-53.213f,-55.935f,-62.548f,-63.150f,-63.216f,-62.934f,-61.962f,-61.043f, --60.358f,-57.774f,-55.363f,-52.313f,-49.905f,-47.198f,-44.534f,-41.161f,-38.606f,-36.410f, --34.239f,-32.341f,-30.257f,-28.333f,-26.528f,-24.915f,-23.404f,-22.549f,-21.285f,-19.604f, --17.989f,-15.493f,-13.390f,-11.825f, -9.928f, -8.468f, -7.214f, -6.036f, -4.723f, -3.134f, - -1.692f, -0.952f, -1.286f, -1.255f, -1.071f, -0.310f, 0.435f, 0.527f, 0.645f, 0.554f, - 0.544f, 0.257f, 0.236f, 0.348f, 1.242f, 1.863f, 2.063f, 2.503f, 3.566f, 3.836f, - 4.313f, 4.297f, 4.459f, 5.748f, 6.290f, 6.008f, 5.708f, 5.510f, 5.737f, 5.881f, - 7.011f, 7.976f, 9.235f, 10.041f, 11.107f, 12.167f, 13.703f, 13.973f, 14.900f, 15.549f, - 15.697f, 15.622f, 15.392f, 14.795f, 14.557f, 14.208f, 12.535f, 10.932f, 9.440f, 7.579f, - 6.153f, 4.913f, 3.664f, 2.294f, 0.960f, 0.796f, 1.436f, 1.802f, 1.324f, 7.873f, - 12.436f, -0.362f, -0.073f, 1.913f, 0.876f, -1.914f, -4.927f, -7.324f, -9.206f,-11.233f, --12.456f,-13.359f,-14.095f,-15.138f,-16.114f,-16.909f,-17.242f,-17.634f,-17.379f,-16.591f, --15.573f,-14.549f,-13.155f,-11.877f,-10.404f, -8.292f, -5.813f, -3.401f, -0.968f, 2.007f, - 4.543f, 6.698f, 9.389f, 11.480f, 10.347f, 9.941f, 13.289f, 11.683f, 14.507f, 15.333f, - 14.796f, 14.575f, 13.820f, 11.550f, 10.838f, 9.545f, 8.143f, 7.801f, 7.600f, 2.666f, - -0.329f, -1.726f, -2.494f, -5.144f, -5.728f, -4.714f, -2.718f, -1.248f, -0.328f, -1.475f, - 0.026f, 1.685f, 3.784f, 5.376f, 8.110f, 9.877f, 9.861f, 11.121f, 11.833f, 12.969f, - 13.606f -},{ --29.534f,-30.067f,-28.679f,-31.929f,-37.096f,-42.489f,-44.604f,-46.112f,-47.765f,-50.375f, --52.615f,-53.040f,-53.441f,-55.740f,-61.468f,-62.904f,-63.036f,-62.643f,-61.538f,-60.739f, --59.842f,-57.359f,-55.110f,-52.119f,-49.721f,-46.883f,-44.067f,-40.853f,-38.206f,-35.922f, --33.736f,-31.799f,-29.728f,-27.710f,-26.270f,-24.288f,-22.998f,-22.930f,-20.350f,-19.285f, --17.324f,-15.143f,-13.502f,-11.749f, -9.774f, -9.180f, -8.197f, -6.742f, -5.337f, -3.595f, - -2.286f, -1.906f, -2.338f, -2.045f, -1.550f, -1.195f, -0.474f, -0.262f, 0.207f, -0.064f, - -0.256f, -0.436f, -0.390f, -0.125f, 0.497f, 0.957f, 1.481f, 1.679f, 2.056f, 2.302f, - 2.792f, 3.372f, 4.559f, 5.393f, 5.756f, 5.707f, 4.919f, 4.398f, 4.779f, 5.720f, - 6.575f, 7.665f, 8.863f, 9.827f, 10.939f, 11.850f, 12.854f, 13.774f, 14.778f, 15.148f, - 14.931f, 15.158f, 14.105f, 14.150f, 13.867f, 13.001f, 11.745f, 10.144f, 8.470f, 6.733f, - 5.491f, 3.951f, 2.604f, 1.061f, -0.493f, -0.794f, -0.018f, 0.037f, -0.524f, -1.555f, - -1.837f, -1.941f, -0.577f, -0.188f, -1.675f, -4.304f, -6.541f, -8.500f,-10.136f,-11.737f, --12.706f,-13.450f,-14.102f,-15.342f,-16.706f,-17.640f,-18.290f,-18.428f,-17.898f,-17.384f, --16.433f,-15.233f,-13.837f,-12.478f,-11.415f, -9.091f, -6.693f, -4.445f, -1.725f, 1.234f, - 3.566f, 6.047f, 8.819f, 10.861f, 10.908f, 9.138f, 13.996f, 13.325f, 12.883f, 13.863f, - 14.385f, 14.659f, 15.555f, 12.245f, 11.682f, 9.873f, 8.561f, 8.369f, 7.719f, 2.863f, - -0.127f, -2.091f, -2.721f, -6.127f, -6.133f, -4.454f, -3.097f, -1.822f, -0.944f, -1.684f, - -0.069f, 1.538f, 3.734f, 5.432f, 7.994f, 9.930f, 9.928f, 11.179f, 11.898f, 12.981f, - 13.606f -},{ --29.534f,-30.079f,-28.743f,-32.024f,-37.150f,-42.705f,-44.553f,-45.946f,-47.389f,-50.225f, --52.462f,-53.211f,-53.828f,-55.496f,-59.673f,-62.609f,-62.671f,-62.276f,-61.185f,-60.198f, --59.198f,-57.123f,-54.832f,-51.739f,-49.595f,-46.659f,-43.471f,-40.651f,-37.902f,-35.470f, --33.199f,-31.241f,-29.235f,-27.288f,-25.766f,-24.008f,-23.085f,-22.078f,-20.279f,-18.947f, --16.743f,-14.886f,-13.460f,-12.001f,-11.047f, -9.576f, -8.503f, -7.422f, -5.825f, -3.921f, - -3.098f, -3.042f, -3.094f, -2.969f, -2.582f, -2.046f, -1.550f, -0.636f, -0.497f, -0.713f, - -0.846f, -1.193f, -1.037f, -0.828f, -0.309f, 0.044f, 0.173f, 0.837f, 0.990f, 1.052f, - 1.867f, 2.195f, 3.446f, 4.397f, 4.833f, 4.517f, 4.049f, 3.887f, 4.191f, 4.860f, - 6.203f, 7.315f, 8.815f, 9.390f, 10.494f, 11.838f, 12.421f, 13.782f, 14.222f, 14.342f, - 14.364f, 14.675f, 13.807f, 13.718f, 12.694f, 11.908f, 10.734f, 8.972f, 7.367f, 5.896f, - 4.507f, 2.954f, 1.524f, -0.080f, -1.762f, -2.193f, -1.643f, -1.406f, -1.578f, -2.485f, - -2.781f, -2.525f, -2.581f, -3.185f, -4.510f, -6.529f, -8.093f, -9.521f,-10.833f,-12.226f, --13.306f,-13.918f,-14.591f,-16.213f,-17.758f,-18.672f,-19.486f,-19.643f,-19.165f,-18.331f, --17.439f,-16.173f,-14.910f,-13.418f,-12.216f,-10.026f, -7.800f, -5.330f, -2.657f, 0.459f, - 2.613f, 5.093f, 8.160f, 10.085f, 10.916f, 10.252f, 10.837f, 14.446f, 12.511f, 12.085f, - 12.576f, 14.803f, 14.936f, 13.687f, 11.957f, 9.983f, 9.029f, 8.572f, 7.272f, 2.936f, - -0.135f, -2.458f, -3.188f, -7.061f, -6.307f, -3.923f, -3.076f, -2.447f, -1.889f, -1.932f, - -0.175f, 1.326f, 3.700f, 5.522f, 7.908f, 9.973f, 10.019f, 11.240f, 11.959f, 12.995f, - 13.606f -},{ --29.534f,-30.092f,-28.814f,-32.089f,-37.136f,-42.824f,-44.437f,-45.662f,-47.006f,-50.018f, --52.119f,-53.127f,-54.029f,-55.234f,-57.885f,-62.354f,-62.168f,-61.890f,-60.778f,-59.565f, --58.467f,-56.719f,-54.597f,-51.491f,-49.197f,-46.473f,-43.169f,-40.316f,-37.701f,-35.234f, --32.771f,-30.687f,-28.789f,-27.000f,-25.230f,-23.800f,-23.317f,-21.225f,-20.171f,-18.600f, --16.463f,-14.576f,-13.721f,-12.266f,-11.482f,-10.279f, -9.270f, -8.230f, -6.503f, -5.101f, - -4.242f, -4.278f, -4.102f, -3.862f, -3.284f, -2.812f, -2.291f, -1.577f, -1.545f, -1.299f, - -1.548f, -1.641f, -1.395f, -1.101f, -0.922f, -1.096f, -1.002f, -1.156f, -0.401f, 0.425f, - 0.790f, 2.350f, 2.744f, 5.364f, 5.086f, 3.442f, 3.336f, 3.083f, 3.197f, 4.711f, - 6.057f, 7.297f, 8.276f, 9.241f, 10.314f, 10.764f, 12.712f, 13.677f, 13.767f, 13.642f, - 14.019f, 14.068f, 13.788f, 12.342f, 11.577f, 10.774f, 9.717f, 7.847f, 6.429f, 5.046f, - 3.425f, 1.821f, 0.394f, -1.306f, -2.705f, -3.222f, -3.162f, -3.132f, -3.089f, -3.405f, - -3.842f, -4.317f, -5.020f, -5.963f, -7.092f, -8.264f, -9.368f,-10.657f,-11.552f,-12.637f, --13.954f,-14.648f,-15.640f,-17.156f,-18.936f,-19.788f,-20.248f,-20.129f,-19.667f,-19.306f, --18.331f,-16.800f,-15.792f,-14.392f,-12.920f,-11.027f, -8.739f, -6.273f, -3.503f, -0.576f, - 1.671f, 4.346f, 7.059f, 9.171f, 10.758f, 11.519f, 6.852f, 15.325f, 11.716f, 10.903f, - 9.219f, 10.679f, 11.894f, 15.889f, 11.952f, 10.257f, 9.513f, 8.547f, 7.336f, 2.869f, - -0.489f, -2.736f, -4.410f, -7.610f, -6.186f, -3.681f, -2.931f, -2.686f, -2.701f, -2.100f, - -0.231f, 1.127f, 3.665f, 5.625f, 7.867f, 10.001f, 10.134f, 11.306f, 12.016f, 13.010f, - 13.606f -},{ --29.534f,-30.105f,-28.889f,-32.119f,-37.045f,-42.817f,-44.261f,-45.270f,-46.668f,-49.785f, --51.729f,-52.678f,-53.753f,-54.975f,-56.712f,-62.232f,-61.765f,-61.484f,-60.244f,-59.016f, --57.747f,-56.292f,-54.280f,-51.295f,-48.699f,-46.319f,-43.028f,-39.857f,-37.402f,-34.996f, --32.581f,-30.256f,-28.224f,-26.612f,-24.769f,-23.455f,-23.013f,-21.001f,-19.791f,-18.019f, --16.330f,-14.630f,-14.119f,-12.966f,-11.756f,-10.863f, -9.750f, -8.906f, -7.129f, -5.879f, - -5.603f, -5.700f, -5.185f, -4.883f, -3.735f, -3.259f, -2.799f, -2.183f, -2.252f, -1.635f, - -1.706f, -1.576f, -1.011f, -1.274f, -1.619f, -2.219f, -2.291f, -0.807f, -1.186f, -0.416f, - -0.106f, 1.695f, 2.971f, 5.470f, 3.544f, 2.418f, 1.977f, 1.688f, 2.607f, 4.256f, - 5.464f, 6.992f, 7.562f, 7.697f, 9.627f, 10.770f, 12.131f, 12.738f, 12.807f, 12.875f, - 13.457f, 13.413f, 12.880f, 11.430f, 10.717f, 9.593f, 8.188f, 7.027f, 5.646f, 4.072f, - 2.323f, 0.384f, -0.821f, -2.245f, -3.404f, -3.824f, -4.345f, -4.316f, -4.610f, -5.187f, - -5.443f, -6.089f, -7.195f, -7.960f, -8.762f, -9.705f,-10.726f,-11.667f,-12.557f,-13.418f, --14.846f,-15.446f,-16.761f,-18.174f,-19.927f,-20.714f,-21.079f,-20.963f,-20.980f,-20.691f, --19.683f,-17.589f,-16.615f,-15.556f,-13.987f,-12.150f, -9.788f, -7.206f, -4.311f, -1.604f, - 0.727f, 3.352f, 6.590f, 8.267f, 10.467f, 11.675f, 6.230f, 14.007f, 12.612f, 10.205f, - 10.719f, 5.871f, 9.594f, 16.664f, 12.723f, 10.748f, 9.698f, 8.876f, 8.217f, 2.975f, - -0.985f, -3.072f, -6.176f, -7.956f, -6.097f, -3.875f, -2.985f, -2.510f, -2.994f, -2.070f, - -0.191f, 1.007f, 3.600f, 5.714f, 7.878f, 10.011f, 10.273f, 11.380f, 12.069f, 13.026f, - 13.606f -},{ --29.534f,-30.119f,-28.969f,-32.107f,-36.871f,-42.679f,-44.034f,-44.819f,-46.401f,-49.545f, --51.422f,-51.963f,-53.045f,-54.637f,-56.013f,-62.040f,-61.388f,-60.992f,-59.797f,-58.592f, --57.332f,-55.945f,-53.687f,-50.952f,-48.362f,-45.918f,-42.718f,-39.766f,-37.091f,-34.633f, --32.403f,-29.979f,-27.897f,-26.280f,-24.305f,-23.175f,-22.509f,-20.886f,-19.407f,-17.671f, --16.145f,-15.386f,-13.882f,-13.348f,-12.259f,-11.539f,-10.349f, -9.161f, -7.991f, -7.417f, - -6.922f, -6.691f, -6.268f, -5.550f, -4.295f, -3.805f, -3.156f, -2.985f, -2.873f, -1.894f, - -1.441f, -1.708f, -1.803f, -2.240f, -2.230f, -2.586f, -3.704f, -3.059f, -2.615f, -2.156f, - -0.868f, 0.559f, 3.471f, 3.024f, 1.975f, 1.247f, 2.650f, 0.841f, 2.419f, 3.473f, - 4.912f, 5.306f, 6.065f, 7.078f, 8.660f, 10.118f, 11.648f, 12.012f, 12.172f, 12.275f, - 12.727f, 12.345f, 11.553f, 10.425f, 9.897f, 8.636f, 7.153f, 6.133f, 4.735f, 2.751f, - 1.080f, -0.523f, -1.534f, -2.755f, -3.801f, -4.295f, -4.833f, -5.406f, -5.902f, -6.779f, - -6.966f, -7.880f, -8.789f, -9.367f,-10.080f,-11.023f,-12.040f,-12.712f,-13.619f,-14.675f, --15.841f,-16.480f,-18.105f,-19.730f,-20.997f,-21.737f,-21.724f,-22.126f,-22.160f,-21.503f, --20.774f,-18.587f,-17.656f,-16.684f,-15.122f,-13.273f,-10.969f, -8.273f, -5.265f, -2.586f, - -0.035f, 2.606f, 5.694f, 7.270f, 10.638f, 11.046f, 7.422f, 10.916f, 13.893f, 11.483f, - 13.464f, 8.159f, 11.089f, 15.457f, 13.592f, 10.782f, 9.346f, 9.220f, 9.153f, 3.334f, - -1.373f, -3.575f, -7.528f, -8.292f, -6.173f, -4.100f, -3.232f, -2.362f, -2.828f, -1.896f, - -0.090f, 0.980f, 3.484f, 5.768f, 7.938f, 10.001f, 10.433f, 11.461f, 12.117f, 13.044f, - 13.606f -},{ --29.534f,-30.134f,-29.051f,-32.053f,-36.613f,-42.424f,-43.770f,-44.381f,-46.200f,-49.299f, --51.218f,-51.222f,-52.276f,-54.121f,-55.308f,-61.381f,-60.672f,-60.425f,-59.480f,-58.214f, --57.058f,-55.456f,-53.072f,-50.554f,-47.832f,-45.422f,-42.323f,-39.636f,-36.827f,-34.349f, --32.191f,-29.789f,-27.679f,-25.896f,-23.983f,-23.017f,-21.786f,-20.487f,-19.033f,-17.503f, --16.015f,-16.001f,-13.568f,-13.746f,-12.686f,-11.923f,-10.943f, -9.960f, -8.831f, -8.309f, - -8.234f, -7.607f, -7.132f, -6.045f, -5.250f, -4.587f, -3.882f, -3.537f, -3.319f, -2.717f, - -2.171f, -2.670f, -2.995f, -3.262f, -3.174f, -4.091f, -4.041f, -3.876f, -3.717f, -3.003f, - -1.952f, -0.443f, 3.440f, 1.394f, 0.579f, 1.048f, 1.047f, 0.106f, 1.083f, 2.623f, - 3.551f, 4.605f, 5.079f, 5.890f, 7.443f, 9.304f, 10.856f, 11.169f, 11.519f, 11.572f, - 11.715f, 11.399f, 10.539f, 9.572f, 8.806f, 7.623f, 6.459f, 5.202f, 3.616f, 1.708f, - 0.168f, -1.221f, -2.405f, -3.558f, -4.424f, -5.075f, -5.786f, -6.597f, -7.225f, -7.856f, - -8.442f, -9.268f,-10.259f,-10.724f,-11.397f,-12.382f,-13.123f,-13.936f,-14.414f,-15.661f, --16.674f,-18.089f,-19.801f,-21.129f,-22.148f,-22.517f,-22.553f,-22.610f,-22.458f,-21.906f, --21.795f,-19.816f,-18.903f,-17.836f,-16.249f,-14.323f,-11.904f, -9.361f, -6.516f, -3.800f, - -0.905f, 1.813f, 4.946f, 6.342f, 10.222f, 9.484f, 8.335f, 8.310f, 13.205f, 12.870f, - 13.349f, 11.759f, 15.668f, 15.483f, 14.322f, 10.945f, 9.250f, 9.229f, 9.481f, 3.816f, - -1.643f, -4.043f, -8.005f, -8.425f, -6.114f, -4.070f, -3.459f, -2.636f, -2.616f, -1.788f, - -0.025f, 1.010f, 3.315f, 5.779f, 8.038f, 9.979f, 10.612f, 11.551f, 12.159f, 13.062f, - 13.606f -},{ --29.534f,-30.150f,-29.135f,-31.958f,-36.274f,-42.084f,-43.482f,-44.024f,-46.036f,-49.030f, --51.008f,-50.680f,-51.800f,-53.454f,-54.484f,-60.082f,-59.635f,-59.787f,-59.103f,-57.841f, --56.476f,-54.779f,-52.519f,-49.939f,-47.318f,-44.893f,-41.988f,-39.427f,-36.665f,-34.187f, --31.958f,-29.646f,-27.409f,-25.545f,-23.881f,-22.967f,-21.341f,-20.138f,-18.752f,-17.442f, --16.409f,-15.958f,-14.052f,-13.967f,-12.845f,-12.078f,-11.434f,-10.614f, -9.963f, -9.551f, - -8.870f, -8.137f, -7.404f, -6.507f, -6.277f, -5.589f, -4.439f, -3.909f, -3.537f, -3.419f, - -3.657f, -4.032f, -3.729f, -3.610f, -4.098f, -3.874f, -3.800f, -5.403f, -5.149f, -4.114f, - -3.350f, -2.136f, -0.141f, -0.563f, -1.269f, 2.210f, -0.882f, -0.486f, 0.478f, 1.668f, - 2.371f, 3.481f, 3.994f, 5.192f, 6.852f, 8.235f, 9.939f, 10.180f, 10.521f, 11.127f, - 11.118f, 10.553f, 9.560f, 8.715f, 7.270f, 6.306f, 5.160f, 3.870f, 2.181f, 0.818f, - -0.706f, -1.995f, -3.210f, -4.267f, -5.276f, -6.422f, -7.233f, -7.831f, -8.425f, -9.093f, - -9.965f,-10.734f,-11.113f,-12.132f,-12.914f,-13.667f,-14.363f,-15.110f,-15.355f,-16.588f, --17.432f,-19.614f,-21.105f,-22.519f,-23.107f,-23.206f,-23.782f,-24.018f,-23.590f,-23.139f, --22.345f,-20.999f,-20.183f,-18.785f,-17.306f,-15.134f,-12.881f,-10.354f, -7.696f, -4.943f, - -2.018f, 0.904f, 3.743f, 5.745f, 8.538f, 8.115f, 8.626f, 7.274f, 10.149f, 12.468f, - 13.363f, 13.557f, 18.170f, 16.314f, 15.168f, 11.331f, 9.528f, 8.787f, 9.312f, 4.762f, - -1.717f, -4.222f, -8.083f, -8.206f, -5.629f, -3.934f, -3.604f, -3.231f, -2.720f, -1.923f, - -0.078f, 1.042f, 3.115f, 5.755f, 8.165f, 9.951f, 10.806f, 11.649f, 12.197f, 13.082f, - 13.606f -},{ --29.534f,-30.166f,-29.220f,-31.826f,-35.862f,-41.699f,-43.179f,-43.794f,-45.872f,-48.726f, --50.663f,-50.407f,-51.629f,-52.768f,-53.733f,-58.284f,-58.839f,-59.003f,-58.629f,-57.436f, --55.773f,-54.127f,-52.014f,-49.272f,-46.866f,-44.231f,-41.789f,-39.140f,-36.484f,-34.085f, --31.642f,-29.410f,-27.315f,-25.211f,-23.558f,-22.953f,-20.880f,-19.946f,-18.675f,-17.118f, --17.055f,-15.416f,-14.920f,-14.086f,-13.578f,-12.724f,-11.714f,-11.336f,-10.646f,-10.359f, - -9.581f, -8.615f, -7.679f, -7.208f, -6.740f, -6.060f, -5.133f, -4.523f, -4.989f, -4.804f, - -4.731f, -4.642f, -4.169f, -4.107f, -3.316f, -5.255f, -5.311f, -6.644f, -6.160f, -5.325f, - -4.236f, -3.484f, -2.627f, -2.875f, 0.800f, 0.175f, -1.863f, -1.405f, -0.070f, 0.726f, - 1.579f, 2.212f, 3.105f, 4.280f, 5.808f, 7.783f, 8.928f, 9.102f, 9.654f, 10.430f, - 10.061f, 9.706f, 8.614f, 7.747f, 5.942f, 5.211f, 3.661f, 2.535f, 0.910f, -0.240f, - -1.608f, -2.933f, -4.313f, -5.158f, -6.447f, -7.645f, -8.401f, -9.088f, -9.562f,-10.403f, --11.325f,-12.426f,-12.973f,-13.850f,-14.188f,-14.967f,-15.462f,-16.142f,-16.481f,-17.467f, --18.459f,-21.174f,-22.522f,-23.653f,-23.970f,-24.463f,-24.721f,-25.334f,-24.623f,-24.104f, --23.775f,-22.073f,-21.393f,-19.797f,-18.205f,-15.969f,-13.665f,-11.437f, -8.669f, -6.066f, - -2.900f, -0.183f, 2.331f, 4.679f, 6.667f, 7.364f, 8.567f, 7.862f, 6.307f, 10.957f, - 12.437f, 15.509f, 18.245f, 16.709f, 14.701f, 11.598f, 9.516f, 7.922f, 8.877f, 6.070f, - -1.556f, -3.876f, -8.190f, -7.801f, -4.856f, -3.864f, -3.812f, -3.754f, -3.154f, -2.276f, - -0.250f, 1.039f, 2.919f, 5.711f, 8.305f, 9.930f, 11.008f, 11.755f, 12.231f, 13.103f, - 13.606f -},{ --29.534f,-30.183f,-29.303f,-31.665f,-35.390f,-41.308f,-42.867f,-43.687f,-45.684f,-48.392f, --50.155f,-50.323f,-51.468f,-52.113f,-52.999f,-56.183f,-58.553f,-58.185f,-58.069f,-56.917f, --55.382f,-53.572f,-51.595f,-48.683f,-46.122f,-43.706f,-41.534f,-38.859f,-36.409f,-33.909f, --31.417f,-29.300f,-27.244f,-25.046f,-23.194f,-22.520f,-20.523f,-19.661f,-18.608f,-17.391f, --16.751f,-16.182f,-15.290f,-14.291f,-13.649f,-13.013f,-12.217f,-11.790f,-11.433f,-10.889f, - -9.967f, -8.950f, -8.409f, -7.857f, -7.229f, -6.695f, -6.079f, -5.805f, -6.124f, -5.961f, - -5.650f, -5.100f, -4.701f, -4.014f, -4.610f, -5.027f, -6.407f, -7.222f, -6.381f, -6.197f, - -5.851f, -4.609f, -3.765f, -2.426f, -0.107f, -1.772f, -2.506f, -2.526f, -1.638f, -0.495f, - 0.312f, 1.086f, 2.170f, 3.648f, 5.380f, 6.688f, 7.545f, 8.041f, 8.693f, 9.239f, - 8.958f, 8.227f, 7.390f, 6.546f, 5.049f, 3.893f, 2.587f, 1.393f, -0.148f, -1.427f, - -2.621f, -4.105f, -5.282f, -6.223f, -7.341f, -8.770f, -9.687f,-10.437f,-11.073f,-12.098f, --12.849f,-13.904f,-14.712f,-15.565f,-15.614f,-16.068f,-16.542f,-17.054f,-17.725f,-18.544f, --19.765f,-22.894f,-23.841f,-24.738f,-25.102f,-25.504f,-25.566f,-26.193f,-26.285f,-25.506f, --24.901f,-23.224f,-22.194f,-20.685f,-19.034f,-16.914f,-14.682f,-12.546f, -9.780f, -7.231f, - -4.178f, -1.180f, 1.392f, 3.477f, 5.246f, 6.637f, 8.218f, 8.120f, 5.995f, 8.420f, - 11.930f, 17.075f, 16.728f, 17.119f, 13.548f, 11.991f, 9.235f, 7.294f, 8.363f, 6.870f, - -1.498f, -2.971f, -8.290f, -7.447f, -4.306f, -3.837f, -4.178f, -4.048f, -3.692f, -2.662f, - -0.469f, 0.998f, 2.759f, 5.665f, 8.441f, 9.929f, 11.213f, 11.868f, 12.261f, 13.125f, - 13.606f -},{ --29.534f,-30.200f,-29.385f,-31.484f,-34.873f,-40.943f,-42.545f,-43.661f,-45.470f,-48.046f, --49.588f,-50.318f,-51.081f,-51.358f,-51.942f,-54.031f,-58.282f,-57.607f,-57.317f,-56.312f, --55.043f,-53.003f,-51.045f,-47.958f,-45.499f,-43.316f,-41.041f,-38.567f,-36.164f,-33.715f, --31.240f,-29.007f,-27.082f,-25.066f,-22.868f,-22.057f,-20.142f,-19.242f,-18.225f,-17.861f, --16.497f,-16.460f,-15.572f,-14.825f,-13.670f,-13.430f,-12.418f,-12.175f,-11.714f,-11.017f, --10.351f, -9.468f, -9.391f, -8.445f, -7.864f, -7.619f, -7.284f, -7.074f, -7.134f, -6.978f, - -6.275f, -5.373f, -5.296f, -3.951f, -5.687f, -6.785f, -7.570f, -7.628f, -7.068f, -6.987f, - -5.771f, -5.973f, -4.487f, -3.148f, -1.774f, -2.767f, -3.030f, -3.274f, -2.355f, -1.537f, - -0.552f, 0.412f, 1.722f, 3.154f, 4.834f, 5.750f, 6.742f, 7.097f, 7.663f, 7.946f, - 7.634f, 6.932f, 6.383f, 5.267f, 3.942f, 2.861f, 1.479f, -0.003f, -1.339f, -2.708f, - -3.865f, -5.340f, -6.391f, -7.184f, -8.454f,-10.230f,-11.347f,-12.252f,-13.019f,-13.933f, --14.811f,-15.660f,-16.452f,-17.069f,-16.947f,-17.375f,-17.901f,-18.261f,-19.082f,-20.015f, --21.460f,-23.930f,-24.929f,-25.769f,-26.216f,-26.827f,-27.055f,-27.305f,-26.988f,-26.547f, --26.290f,-24.361f,-23.141f,-21.532f,-19.804f,-17.801f,-15.910f,-13.839f,-10.988f, -8.105f, - -5.263f, -2.512f, 0.476f, 2.404f, 4.211f, 5.556f, 7.509f, 7.920f, 7.095f, 6.802f, - 11.622f, 17.775f, 16.607f, 17.233f, 13.111f, 12.111f, 8.982f, 7.069f, 8.089f, 7.104f, - -1.711f, -2.227f, -8.363f, -7.282f, -4.431f, -3.976f, -4.650f, -4.329f, -4.143f, -2.920f, - -0.658f, 0.940f, 2.650f, 5.624f, 8.558f, 9.960f, 11.417f, 11.984f, 12.288f, 13.148f, - 13.606f -},{ --29.534f,-30.217f,-29.464f,-31.295f,-34.331f,-40.617f,-42.216f,-43.645f,-45.245f,-47.708f, --49.118f,-50.359f,-50.602f,-50.331f,-50.481f,-52.288f,-57.542f,-57.201f,-56.450f,-55.681f, --54.372f,-52.456f,-50.354f,-47.342f,-45.049f,-42.785f,-40.517f,-38.180f,-35.981f,-33.606f, --31.157f,-28.777f,-26.755f,-24.857f,-23.064f,-21.436f,-19.824f,-18.905f,-18.221f,-17.693f, --17.060f,-16.508f,-15.768f,-15.110f,-14.570f,-13.994f,-13.188f,-12.524f,-11.639f,-11.040f, --10.321f,-10.196f, -9.726f, -9.112f, -8.631f, -8.157f, -7.997f, -8.081f, -8.220f, -7.721f, - -7.007f, -6.059f, -4.383f, -5.217f, -6.766f, -7.805f, -8.390f, -8.141f, -7.747f, -7.802f, - -7.460f, -6.293f, -5.577f, -3.275f, -4.208f, -3.703f, -3.947f, -4.029f, -3.545f, -2.425f, - -1.379f, 0.144f, 1.729f, 2.920f, 4.203f, 4.823f, 5.587f, 5.778f, 6.482f, 6.566f, - 6.334f, 5.786f, 5.020f, 3.992f, 2.965f, 1.168f, 0.043f, -1.424f, -2.696f, -3.980f, - -5.149f, -6.446f, -7.512f, -8.532f, -9.695f,-11.678f,-12.706f,-13.667f,-14.757f,-15.533f, --16.546f,-17.431f,-17.866f,-18.471f,-18.593f,-18.593f,-19.166f,-19.611f,-20.540f,-21.633f, --22.878f,-24.816f,-26.026f,-26.994f,-27.405f,-27.882f,-28.814f,-29.064f,-28.920f,-28.098f, --27.510f,-25.415f,-24.149f,-22.309f,-20.801f,-18.920f,-17.041f,-15.073f,-12.332f, -9.368f, - -6.512f, -3.298f, -0.858f, 1.197f, 3.032f, 4.528f, 6.381f, 7.169f, 7.053f, 6.382f, - 11.053f, 17.659f, 18.466f, 16.335f, 12.765f, 11.911f, 8.896f, 6.900f, 7.828f, 7.104f, - -1.849f, -2.574f, -8.382f, -7.364f, -5.187f, -4.561f, -5.148f, -4.799f, -4.490f, -3.046f, - -0.802f, 0.883f, 2.586f, 5.581f, 8.643f, 10.029f, 11.614f, 12.102f, 12.312f, 13.173f, - 13.606f -},{ --29.534f,-30.235f,-29.538f,-31.109f,-33.785f,-40.331f,-41.884f,-43.574f,-45.035f,-47.382f, --48.820f,-50.477f,-50.417f,-49.050f,-48.967f,-51.246f,-56.569f,-56.576f,-55.714f,-54.933f, --53.567f,-51.906f,-49.663f,-46.904f,-44.590f,-42.220f,-40.349f,-37.929f,-35.811f,-33.343f, --30.962f,-28.552f,-26.584f,-24.897f,-22.719f,-20.781f,-19.500f,-18.777f,-18.422f,-16.778f, --17.775f,-16.846f,-16.142f,-15.426f,-15.186f,-14.459f,-13.654f,-12.737f,-11.874f,-11.184f, --10.917f,-10.550f,-10.225f, -9.640f, -9.134f, -8.565f, -8.862f, -8.892f, -8.800f, -8.187f, - -7.416f, -6.595f, -5.093f, -6.296f, -7.687f, -8.630f, -8.859f, -8.753f, -8.585f, -8.004f, - -7.910f, -6.910f, -6.539f, -4.236f, -4.772f, -4.858f, -5.138f, -4.348f, -4.085f, -3.059f, - -1.693f, -0.266f, 1.197f, 2.639f, 3.458f, 3.770f, 4.330f, 4.561f, 5.399f, 5.117f, - 4.881f, 4.506f, 3.636f, 2.527f, 1.803f, -0.165f, -1.326f, -2.917f, -4.248f, -5.522f, - -6.672f, -7.626f, -8.632f, -9.944f,-11.009f,-13.124f,-14.334f,-15.455f,-16.401f,-17.134f, --18.046f,-18.721f,-19.600f,-20.019f,-19.908f,-19.786f,-20.376f,-21.116f,-22.158f,-23.091f, --24.134f,-25.625f,-27.157f,-27.855f,-28.643f,-29.137f,-30.076f,-30.447f,-30.124f,-29.722f, --28.476f,-26.359f,-25.111f,-23.139f,-21.612f,-20.080f,-18.314f,-16.228f,-13.717f,-10.730f, - -7.674f, -4.737f, -2.326f, -0.226f, 1.466f, 3.382f, 5.587f, 6.366f, 6.506f, 6.242f, - 10.267f, 16.057f, 18.224f, 14.517f, 12.648f, 11.502f, 8.756f, 6.986f, 7.267f, 6.527f, - -1.818f, -3.887f, -8.208f, -7.622f, -6.080f, -5.528f, -5.640f, -5.331f, -4.790f, -3.154f, - -0.945f, 0.841f, 2.552f, 5.524f, 8.685f, 10.140f, 11.800f, 12.219f, 12.335f, 13.198f, - 13.606f -},{ --29.534f,-30.253f,-29.607f,-30.936f,-33.260f,-40.071f,-41.560f,-43.410f,-44.858f,-47.057f, --48.628f,-50.648f,-50.731f,-47.758f,-47.683f,-50.491f,-55.710f,-55.763f,-55.112f,-54.098f, --52.904f,-51.195f,-49.024f,-46.400f,-44.107f,-41.946f,-40.359f,-37.801f,-35.747f,-33.166f, --30.575f,-28.384f,-26.393f,-24.843f,-21.975f,-20.391f,-19.195f,-18.307f,-18.485f,-17.408f, --17.803f,-17.319f,-16.426f,-16.011f,-15.414f,-14.836f,-14.042f,-13.321f,-12.349f,-11.738f, --11.362f,-10.881f,-10.726f, -9.984f, -9.432f, -8.994f, -9.326f, -9.348f, -9.282f, -8.542f, - -7.672f, -7.078f, -6.392f, -7.403f, -8.873f, -9.472f, -9.396f, -9.034f, -9.002f, -8.887f, - -8.333f, -8.008f, -6.420f, -5.913f, -5.139f, -5.213f, -5.601f, -4.874f, -4.746f, -3.421f, - -2.078f, -0.837f, 0.341f, 1.926f, 2.644f, 3.065f, 3.144f, 3.574f, 4.342f, 3.639f, - 3.439f, 2.984f, 1.949f, 0.959f, 0.161f, -1.472f, -2.738f, -4.603f, -5.924f, -7.130f, - -8.066f, -8.966f,-10.087f,-11.361f,-12.273f,-14.274f,-15.789f,-17.361f,-18.368f,-19.166f, --19.698f,-20.203f,-20.960f,-21.075f,-21.068f,-21.161f,-21.852f,-22.622f,-23.731f,-24.734f, --25.449f,-26.603f,-28.007f,-28.531f,-29.488f,-30.397f,-31.042f,-31.438f,-31.375f,-31.191f, --29.816f,-27.297f,-25.926f,-24.144f,-22.520f,-21.247f,-19.565f,-17.551f,-14.836f,-12.018f, - -8.939f, -6.336f, -3.992f, -1.680f, 0.168f, 2.194f, 4.601f, 5.158f, 5.268f, 7.294f, - 10.502f, 14.875f, 16.794f, 13.144f, 12.355f, 10.850f, 8.676f, 7.261f, 6.558f, 5.381f, - -2.020f, -5.207f, -7.948f, -7.889f, -6.745f, -6.410f, -6.096f, -5.665f, -5.048f, -3.328f, - -1.133f, 0.824f, 2.536f, 5.436f, 8.679f, 10.287f, 11.973f, 12.333f, 12.359f, 13.224f, - 13.606f -},{ --29.534f,-30.272f,-29.669f,-30.787f,-32.784f,-39.814f,-41.264f,-43.156f,-44.716f,-46.726f, --48.392f,-50.728f,-51.253f,-46.730f,-46.514f,-49.376f,-54.695f,-55.211f,-54.461f,-53.368f, --52.298f,-50.521f,-48.528f,-46.054f,-43.453f,-41.957f,-40.043f,-37.641f,-35.565f,-32.829f, --30.368f,-28.301f,-26.199f,-24.368f,-21.440f,-19.980f,-18.755f,-17.924f,-18.142f,-18.432f, --17.828f,-17.051f,-16.692f,-16.447f,-15.720f,-14.889f,-14.341f,-13.704f,-12.935f,-12.162f, --11.568f,-11.218f,-10.766f,-10.061f, -9.506f, -9.441f, -9.744f, -9.691f, -9.522f, -8.624f, - -8.216f, -7.541f, -8.051f, -8.965f, -9.910f,-10.169f, -9.973f, -9.689f, -9.352f, -9.377f, - -9.060f, -8.378f, -7.264f, -7.009f, -5.346f, -5.733f, -5.796f, -5.228f, -4.633f, -3.595f, - -2.899f, -0.471f, 2.843f, 0.488f, 1.429f, 1.979f, 2.207f, 2.519f, 2.755f, 2.103f, - 2.082f, 1.267f, 0.281f, -0.205f, -1.270f, -2.949f, -4.574f, -6.222f, -7.700f, -8.790f, - -9.554f,-10.710f,-11.941f,-12.804f,-13.772f,-15.184f,-17.367f,-18.938f,-19.997f,-20.858f, --21.536f,-21.995f,-22.596f,-22.431f,-22.500f,-22.902f,-23.125f,-24.363f,-25.223f,-26.023f, --26.833f,-27.721f,-28.868f,-29.469f,-30.614f,-31.504f,-32.213f,-32.539f,-32.600f,-32.002f, --30.446f,-28.473f,-26.730f,-25.249f,-23.794f,-22.398f,-20.781f,-18.659f,-16.039f,-13.154f, --10.138f, -7.549f, -5.319f, -3.152f, -1.196f, 1.405f, 2.911f, 3.777f, 3.902f, 8.135f, - 10.449f, 16.592f, 14.831f, 12.449f, 11.574f, 10.708f, 8.761f, 7.258f, 5.621f, 4.213f, - -2.501f, -5.998f, -7.852f, -8.071f, -7.310f, -6.949f, -6.499f, -5.796f, -5.225f, -3.541f, - -1.355f, 0.842f, 2.539f, 5.313f, 8.626f, 10.463f, 12.133f, 12.440f, 12.383f, 13.251f, - 13.606f -},{ --29.534f,-30.290f,-29.725f,-30.668f,-32.381f,-39.539f,-41.012f,-42.852f,-44.583f,-46.401f, --48.016f,-50.517f,-51.359f,-46.041f,-45.290f,-48.025f,-53.179f,-54.890f,-53.732f,-52.660f, --51.588f,-50.045f,-48.071f,-45.906f,-43.234f,-41.923f,-39.578f,-37.568f,-35.335f,-32.594f, --30.231f,-28.100f,-26.139f,-23.391f,-20.930f,-19.510f,-18.119f,-18.225f,-18.090f,-18.542f, --17.431f,-17.005f,-16.823f,-16.644f,-15.692f,-15.025f,-14.503f,-13.984f,-13.357f,-12.465f, --12.035f,-11.464f,-10.876f,-10.189f, -9.744f, -9.646f, -9.959f, -9.939f, -9.754f, -9.206f, - -8.780f, -8.198f, -9.125f, -9.969f,-10.726f,-10.849f,-10.537f,-10.382f,-10.142f, -9.973f, - -8.976f, -9.100f, -8.431f, -7.318f, -6.302f, -6.722f, -6.822f, -5.893f, -4.877f, -3.835f, - -2.540f, 2.357f, 0.833f, -0.305f, 0.625f, 0.864f, 0.920f, 1.181f, 1.383f, 1.014f, - 0.676f, -0.453f, -1.038f, -1.694f, -2.920f, -4.319f, -6.375f, -7.966f, -9.442f,-10.595f, --11.405f,-12.425f,-13.452f,-14.453f,-15.498f,-16.504f,-19.074f,-20.537f,-21.834f,-22.468f, --22.822f,-23.244f,-23.948f,-24.012f,-24.007f,-24.668f,-24.796f,-25.934f,-26.834f,-27.295f, --28.113f,-28.753f,-29.750f,-30.458f,-31.555f,-32.526f,-33.245f,-33.987f,-33.427f,-32.898f, --31.466f,-29.266f,-27.660f,-26.177f,-25.024f,-23.638f,-21.879f,-19.755f,-17.208f,-14.310f, --11.536f, -8.839f, -6.701f, -4.532f, -2.145f, 0.394f, 1.666f, 2.619f, 2.822f, 7.431f, - 10.503f, 16.253f, 12.676f, 11.608f, 10.950f, 11.002f, 8.532f, 6.985f, 4.635f, 2.968f, - -2.948f, -6.382f, -7.834f, -8.192f, -7.965f, -7.358f, -6.878f, -5.991f, -5.327f, -3.712f, - -1.548f, 0.907f, 2.569f, 5.165f, 8.538f, 10.652f, 12.280f, 12.539f, 12.409f, 13.279f, - 13.606f -},{ --29.534f,-30.309f,-29.773f,-30.583f,-32.078f,-39.232f,-40.819f,-42.555f,-44.422f,-46.111f, --47.538f,-49.921f,-50.617f,-45.518f,-44.184f,-47.113f,-51.477f,-54.251f,-52.998f,-51.846f, --50.831f,-49.455f,-47.599f,-45.647f,-43.397f,-41.561f,-39.243f,-37.473f,-35.103f,-32.345f, --30.151f,-27.766f,-26.112f,-22.671f,-20.393f,-19.058f,-18.082f,-18.330f,-18.853f,-17.830f, --17.042f,-17.186f,-17.074f,-16.636f,-15.723f,-15.096f,-14.803f,-14.310f,-13.326f,-12.795f, --12.301f,-11.701f,-11.069f,-10.521f, -9.974f, -9.958f,-10.431f,-10.267f,-10.015f, -9.493f, - -9.306f, -9.861f,-10.524f,-10.819f,-11.411f,-11.422f,-11.113f,-10.930f, -9.512f,-10.042f, - -9.855f, -9.248f, -8.711f, -7.720f, -7.910f, -7.958f, -7.143f, -6.040f, -4.845f, -3.707f, - 0.706f, -1.519f, -1.489f, -0.308f, 0.158f, -0.136f, -0.279f, -0.065f, -0.081f, -0.267f, - -0.897f, -1.980f, -2.515f, -3.475f, -4.488f, -5.963f, -8.162f, -9.779f,-11.058f,-12.328f, --13.394f,-14.524f,-15.364f,-16.379f,-17.174f,-18.247f,-20.831f,-21.981f,-23.319f,-23.845f, --24.202f,-24.737f,-25.481f,-25.798f,-25.804f,-26.093f,-26.676f,-27.548f,-28.314f,-28.739f, --29.432f,-29.957f,-30.738f,-31.595f,-32.477f,-33.276f,-34.151f,-34.701f,-34.595f,-33.777f, --32.286f,-29.967f,-28.590f,-27.066f,-26.037f,-24.572f,-22.969f,-20.694f,-18.367f,-15.580f, --12.546f,-10.323f, -7.951f, -5.832f, -3.209f, -0.756f, 0.532f, 1.251f, 3.437f, 5.090f, - 11.501f, 13.397f, 11.698f, 10.744f, 10.301f, 10.679f, 7.798f, 5.975f, 3.853f, 0.977f, - -3.450f, -6.476f, -7.696f, -8.293f, -8.559f, -7.868f, -7.270f, -6.411f, -5.428f, -3.808f, - -1.647f, 1.017f, 2.635f, 5.016f, 8.427f, 10.838f, 12.417f, 12.629f, 12.438f, 13.308f, - 13.606f -},{ --29.534f,-30.327f,-29.813f,-30.534f,-31.894f,-38.891f,-40.685f,-42.313f,-44.192f,-45.871f, --47.098f,-49.045f,-49.176f,-44.927f,-43.459f,-46.622f,-50.134f,-53.244f,-52.277f,-51.151f, --50.078f,-48.691f,-47.126f,-45.248f,-43.120f,-41.092f,-39.182f,-37.192f,-34.625f,-32.243f, --29.939f,-27.357f,-25.835f,-22.180f,-20.015f,-18.584f,-17.924f,-18.413f,-19.516f,-18.190f, --17.463f,-17.213f,-17.284f,-16.730f,-16.168f,-15.455f,-14.995f,-14.180f,-13.564f,-13.102f, --12.339f,-11.872f,-11.212f,-10.757f,-10.257f,-10.253f,-10.556f,-10.622f,-10.297f,-10.075f, --10.040f,-10.714f,-11.290f,-11.718f,-11.918f,-11.736f,-11.520f,-11.320f,-10.462f,-10.214f, --10.002f,-10.066f, -9.053f, -8.875f, -8.861f, -9.124f, -7.656f, -6.781f, -5.445f, -4.006f, - -2.067f, -2.657f, -1.672f, -0.954f, -1.207f, -1.239f, -1.536f, -1.343f, -1.569f, -1.702f, - -2.423f, -3.540f, -4.048f, -5.011f, -6.204f, -7.904f, -9.755f,-11.198f,-12.649f,-13.955f, --15.096f,-16.420f,-17.505f,-18.170f,-18.711f,-20.114f,-22.335f,-23.395f,-24.745f,-25.336f, --25.892f,-26.592f,-27.250f,-27.419f,-27.573f,-28.068f,-28.251f,-28.981f,-29.644f,-30.045f, --30.560f,-31.010f,-31.666f,-32.659f,-33.596f,-34.280f,-35.186f,-35.772f,-35.231f,-34.443f, --33.022f,-30.626f,-29.537f,-28.130f,-26.846f,-25.545f,-23.937f,-21.630f,-19.223f,-16.708f, --13.872f,-11.449f, -9.008f, -6.684f, -3.972f, -1.924f, -0.624f, 0.341f, 2.471f, 7.147f, - 11.007f, 11.571f, 10.715f, 9.690f, 9.695f, 9.920f, 6.855f, 4.545f, 2.882f, -1.670f, - -4.042f, -6.144f, -7.500f, -8.434f, -8.948f, -8.409f, -7.653f, -6.893f, -5.592f, -3.870f, - -1.649f, 1.146f, 2.731f, 4.899f, 8.314f, 11.006f, 12.547f, 12.710f, 12.470f, 13.337f, - 13.606f -},{ --29.534f,-30.346f,-29.844f,-30.518f,-31.842f,-38.531f,-40.595f,-42.147f,-43.873f,-45.652f, --46.803f,-48.132f,-47.644f,-44.199f,-42.984f,-45.777f,-49.316f,-52.389f,-51.629f,-50.588f, --49.169f,-47.927f,-46.462f,-44.717f,-42.720f,-40.757f,-39.279f,-36.871f,-34.336f,-32.100f, --29.535f,-27.137f,-25.485f,-21.945f,-19.866f,-18.468f,-17.706f,-19.217f,-19.204f,-18.382f, --17.584f,-17.274f,-17.190f,-16.458f,-16.220f,-15.816f,-14.677f,-14.313f,-13.609f,-13.371f, --12.482f,-12.113f,-11.318f,-10.773f,-10.772f,-10.633f,-10.800f,-10.846f,-10.648f,-10.766f, --10.875f,-11.598f,-11.982f,-12.319f,-12.292f,-12.124f,-11.999f,-11.104f,-10.904f,-10.447f, --10.479f,-10.145f, -9.655f, -9.924f, -9.795f, -9.592f, -8.518f, -7.583f, -6.281f, -4.672f, - -3.908f, -3.168f, -2.544f, -2.217f, -2.442f, -2.530f, -2.885f, -2.776f, -3.225f, -3.270f, - -4.116f, -5.095f, -5.688f, -6.831f, -7.961f, -9.777f,-11.418f,-12.825f,-14.274f,-15.497f, --16.890f,-18.371f,-19.298f,-20.122f,-20.712f,-22.239f,-23.800f,-25.395f,-26.438f,-27.035f, --27.948f,-28.421f,-28.843f,-28.927f,-29.244f,-29.757f,-29.910f,-30.540f,-30.810f,-31.161f, --31.793f,-32.264f,-33.070f,-33.661f,-34.802f,-35.154f,-36.067f,-36.683f,-35.677f,-34.802f, --33.940f,-31.340f,-30.108f,-28.975f,-27.525f,-26.336f,-24.676f,-22.443f,-19.966f,-17.627f, --14.935f,-12.725f,-10.230f, -7.784f, -4.940f, -3.251f, -2.282f, -0.879f, 2.973f, 9.252f, - 9.677f, 9.936f, 9.463f, 8.467f, 8.981f, 9.297f, 6.255f, 4.374f, 1.683f, -3.747f, - -4.247f, -5.404f, -7.373f, -8.708f, -9.317f, -8.834f, -7.961f, -7.166f, -5.802f, -3.943f, - -1.616f, 1.256f, 2.839f, 4.842f, 8.217f, 11.145f, 12.672f, 12.781f, 12.507f, 13.367f, - 13.606f -},{ --29.534f,-30.364f,-29.866f,-30.529f,-31.925f,-38.178f,-40.520f,-42.045f,-43.478f,-45.375f, --46.607f,-47.389f,-46.578f,-43.490f,-42.343f,-44.449f,-49.048f,-51.777f,-51.112f,-49.806f, --48.212f,-47.048f,-45.702f,-44.102f,-42.442f,-40.540f,-39.068f,-36.570f,-34.143f,-31.763f, --29.257f,-26.773f,-25.039f,-21.845f,-19.855f,-18.298f,-17.391f,-20.243f,-18.678f,-18.326f, --17.881f,-17.337f,-17.010f,-16.190f,-16.145f,-15.737f,-14.333f,-14.230f,-13.805f,-13.439f, --12.637f,-12.249f,-11.690f,-11.241f,-11.141f,-11.030f,-11.272f,-11.214f,-11.015f,-11.325f, --11.408f,-12.353f,-12.580f,-12.941f,-12.898f,-12.372f,-12.084f,-11.896f,-10.714f,-11.191f, --11.054f,-10.320f,-10.298f,-10.770f,-10.488f, -9.938f, -9.025f, -8.345f, -7.010f, -5.577f, - -4.819f, -4.397f, -3.941f, -3.550f, -3.725f, -3.881f, -4.075f, -4.005f, -4.417f, -4.831f, - -5.766f, -6.622f, -7.518f, -8.622f, -9.779f,-11.653f,-13.124f,-14.555f,-15.782f,-17.322f, --18.901f,-20.013f,-21.350f,-22.032f,-22.958f,-24.195f,-25.592f,-27.393f,-28.323f,-28.999f, --29.494f,-30.316f,-30.860f,-30.595f,-30.863f,-31.403f,-31.506f,-31.938f,-32.282f,-32.513f, --32.960f,-33.336f,-34.210f,-34.931f,-35.636f,-36.410f,-36.868f,-37.181f,-36.367f,-35.379f, --34.458f,-31.946f,-30.685f,-29.646f,-28.333f,-27.006f,-25.446f,-23.282f,-20.775f,-18.332f, --15.914f,-13.686f,-11.238f, -8.764f, -5.877f, -5.457f, -3.934f, 0.842f, 4.055f, 5.598f, - 8.271f, 8.339f, 8.072f, 7.398f, 8.054f, 8.587f, 5.715f, 4.097f, 0.111f, -4.829f, - -4.104f, -4.607f, -7.301f, -9.056f, -9.756f, -9.095f, -8.123f, -7.157f, -5.976f, -4.022f, - -1.642f, 1.316f, 2.937f, 4.857f, 8.153f, 11.248f, 12.796f, 12.846f, 12.549f, 13.398f, - 13.606f -},{ --29.534f,-30.382f,-29.879f,-30.558f,-32.134f,-37.867f,-40.425f,-41.971f,-43.051f,-44.947f, --46.318f,-46.851f,-46.072f,-42.995f,-41.414f,-43.561f,-49.213f,-51.058f,-50.577f,-48.855f, --47.482f,-46.138f,-45.039f,-43.513f,-42.042f,-40.546f,-38.646f,-36.429f,-33.883f,-31.522f, --29.020f,-26.503f,-24.534f,-21.761f,-19.865f,-18.375f,-17.085f,-20.393f,-18.563f,-18.194f, --17.833f,-17.311f,-16.758f,-16.180f,-15.648f,-15.191f,-14.589f,-14.217f,-13.821f,-13.367f, --12.810f,-12.278f,-11.898f,-11.684f,-11.556f,-11.121f,-11.592f,-11.571f,-11.516f,-11.893f, --12.063f,-12.950f,-13.096f,-13.285f,-13.087f,-12.734f,-12.792f,-10.647f,-10.935f,-11.439f, --11.430f,-10.638f,-10.855f,-11.086f,-10.627f,-10.117f, -9.338f, -8.789f, -7.658f, -6.599f, - -6.040f, -5.559f, -5.280f, -4.904f, -5.059f, -5.237f, -5.238f, -5.351f, -5.737f, -6.150f, - -6.863f, -7.850f, -9.169f,-10.058f,-11.513f,-13.210f,-14.777f,-16.444f,-17.835f,-19.297f, --20.859f,-22.032f,-23.064f,-23.972f,-25.046f,-26.103f,-27.485f,-29.274f,-29.960f,-30.908f, --31.374f,-32.148f,-32.395f,-32.504f,-32.571f,-33.071f,-33.079f,-33.289f,-33.599f,-33.772f, --34.312f,-34.528f,-35.536f,-36.057f,-36.888f,-37.707f,-37.497f,-37.457f,-36.825f,-35.858f, --34.975f,-32.570f,-31.181f,-30.162f,-28.948f,-27.436f,-25.660f,-23.885f,-21.343f,-19.045f, --16.576f,-14.368f,-11.873f, -9.240f, -7.892f, -6.645f, -0.681f, 2.076f, 2.858f, 5.409f, - 6.667f, 7.087f, 7.012f, 6.294f, 7.170f, 7.694f, 4.299f, 1.866f, -1.696f, -5.555f, - -4.321f, -3.947f, -7.214f, -9.207f, -9.977f, -9.129f, -8.029f, -6.988f, -6.034f, -4.066f, - -1.791f, 1.316f, 3.013f, 4.942f, 8.130f, 11.316f, 12.920f, 12.905f, 12.596f, 13.429f, - 13.606f -},{ --29.534f,-30.399f,-29.883f,-30.597f,-32.447f,-37.631f,-40.283f,-41.881f,-42.653f,-44.321f, --45.728f,-46.382f,-45.788f,-42.715f,-40.609f,-43.666f,-48.950f,-50.276f,-49.776f,-48.068f, --46.679f,-45.451f,-44.354f,-42.890f,-41.686f,-40.415f,-38.180f,-36.004f,-33.425f,-30.979f, --28.614f,-26.594f,-23.679f,-21.551f,-19.767f,-18.371f,-18.121f,-19.625f,-18.520f,-18.210f, --17.699f,-17.112f,-16.409f,-16.043f,-15.347f,-15.167f,-14.493f,-14.383f,-13.802f,-13.239f, --12.863f,-12.435f,-11.996f,-11.919f,-11.423f,-11.361f,-11.869f,-12.017f,-11.993f,-12.232f, --12.614f,-13.294f,-13.403f,-13.372f,-12.900f,-12.600f,-12.436f,-12.148f,-11.157f,-11.473f, --11.413f,-10.960f,-11.191f,-11.019f,-10.655f,-10.113f, -9.690f, -9.153f, -8.218f, -7.432f, - -6.756f, -6.618f, -6.437f, -6.138f, -6.316f, -6.231f, -6.037f, -6.800f, -6.785f, -7.393f, - -8.364f, -9.232f,-10.502f,-11.499f,-13.213f,-14.722f,-16.356f,-18.035f,-19.460f,-21.343f, --22.841f,-23.779f,-24.904f,-25.982f,-27.166f,-28.265f,-29.395f,-31.099f,-31.976f,-32.855f, --33.425f,-33.573f,-33.774f,-33.895f,-34.462f,-34.386f,-34.611f,-34.781f,-34.861f,-35.196f, --35.520f,-35.872f,-36.555f,-37.215f,-38.152f,-38.738f,-38.694f,-38.033f,-37.422f,-36.076f, --35.369f,-32.907f,-31.575f,-30.360f,-29.209f,-27.892f,-25.789f,-24.027f,-21.638f,-19.411f, --17.248f,-14.774f,-12.481f,-11.234f, -9.092f, -3.841f, -0.316f, 0.845f, 1.803f, 5.203f, - 5.327f, 5.988f, 6.019f, 5.211f, 5.922f, 7.032f, 2.057f, -0.162f, -2.305f, -5.808f, - -5.122f, -3.364f, -6.996f, -9.014f, -9.813f, -8.850f, -7.560f, -6.756f, -5.963f, -4.070f, - -2.069f, 1.268f, 3.071f, 5.074f, 8.151f, 11.355f, 13.046f, 12.963f, 12.648f, 13.461f, - 13.606f -},{ --29.534f,-30.416f,-29.878f,-30.633f,-32.828f,-37.496f,-40.081f,-41.748f,-42.336f,-43.538f, --44.772f,-45.789f,-45.336f,-42.443f,-40.401f,-44.097f,-47.269f,-49.626f,-48.735f,-47.364f, --45.660f,-44.797f,-43.587f,-42.283f,-41.388f,-39.864f,-37.812f,-35.579f,-32.924f,-30.345f, --28.095f,-26.582f,-23.070f,-21.318f,-19.657f,-18.276f,-18.817f,-18.683f,-18.256f,-18.039f, --17.473f,-16.815f,-15.955f,-15.541f,-14.942f,-14.951f,-14.262f,-14.283f,-13.844f,-13.452f, --12.875f,-12.669f,-11.928f,-11.947f,-11.272f,-10.930f,-11.828f,-12.078f,-12.302f,-12.570f, --13.134f,-13.478f,-13.587f,-13.293f,-12.889f,-12.769f,-12.323f,-11.780f,-11.456f,-11.771f, --11.638f,-11.383f,-11.223f,-10.924f,-10.551f, -9.968f, -9.652f, -9.103f, -8.504f, -7.883f, - -7.491f, -7.829f, -7.549f, -7.277f, -7.272f, -7.126f, -7.384f, -7.536f, -7.629f, -8.605f, - -9.435f,-10.589f,-11.745f,-13.006f,-14.564f,-16.053f,-17.602f,-19.620f,-21.585f,-23.143f, --24.285f,-25.695f,-26.697f,-28.148f,-29.279f,-30.569f,-31.572f,-33.075f,-33.926f,-34.678f, --34.997f,-35.059f,-35.201f,-35.136f,-35.894f,-35.956f,-36.336f,-36.390f,-36.265f,-36.295f, --36.717f,-36.994f,-37.570f,-38.169f,-39.055f,-39.107f,-38.979f,-38.814f,-38.025f,-36.708f, --36.107f,-32.956f,-31.676f,-30.395f,-29.291f,-27.734f,-25.841f,-23.888f,-21.613f,-19.615f, --17.475f,-15.175f,-13.423f,-11.693f, -6.429f, -3.643f, -1.286f, 0.884f, 2.626f, 3.267f, - 4.188f, 4.839f, 4.869f, 4.344f, 5.087f, 6.699f, -0.125f, -1.058f, -1.997f, -5.549f, - -6.100f, -3.136f, -6.419f, -8.616f, -9.441f, -8.239f, -6.761f, -6.463f, -5.812f, -4.078f, - -2.417f, 1.186f, 3.132f, 5.223f, 8.212f, 11.375f, 13.172f, 13.023f, 12.705f, 13.493f, - 13.606f -},{ --29.534f,-30.432f,-29.865f,-30.656f,-33.234f,-37.470f,-39.828f,-41.567f,-42.124f,-42.717f, --43.593f,-44.962f,-44.568f,-41.973f,-40.673f,-43.959f,-44.751f,-48.702f,-47.684f,-46.507f, --44.981f,-43.977f,-42.751f,-41.693f,-40.911f,-39.297f,-37.414f,-35.235f,-32.578f,-30.030f, --27.563f,-26.019f,-22.869f,-20.991f,-19.639f,-18.334f,-18.522f,-18.126f,-17.863f,-17.565f, --16.989f,-16.470f,-15.371f,-15.119f,-14.940f,-14.560f,-14.094f,-14.190f,-13.733f,-13.454f, --12.908f,-12.580f,-11.939f,-11.728f,-11.247f,-11.064f,-11.741f,-12.039f,-12.326f,-12.834f, --13.287f,-13.508f,-13.550f,-13.273f,-12.855f,-12.753f,-12.217f,-11.428f,-11.367f,-11.753f, --11.529f,-11.332f,-11.127f,-10.991f,-10.320f, -9.881f, -9.607f, -9.056f, -8.655f, -8.267f, - -8.162f, -8.497f, -8.286f, -8.404f, -7.996f, -8.084f, -8.614f, -8.559f, -9.032f, -9.797f, --10.579f,-11.800f,-12.979f,-14.418f,-16.034f,-17.341f,-18.852f,-21.145f,-23.256f,-24.928f, --26.149f,-27.604f,-28.658f,-30.018f,-31.512f,-32.534f,-33.578f,-34.534f,-35.638f,-36.159f, --36.397f,-36.472f,-36.489f,-36.485f,-36.854f,-37.520f,-37.796f,-37.784f,-37.587f,-37.806f, --37.897f,-38.423f,-38.507f,-38.840f,-39.797f,-39.869f,-39.194f,-38.870f,-38.358f,-37.015f, --36.207f,-32.928f,-31.632f,-30.505f,-29.118f,-27.759f,-25.522f,-23.690f,-21.713f,-20.035f, --17.865f,-15.709f,-14.436f, -9.179f, -7.879f, -4.773f, -2.278f, 1.149f, 2.433f, 2.009f, - 2.844f, 3.761f, 3.596f, 3.308f, 4.844f, 5.413f, -1.825f, -2.034f, -2.462f, -5.538f, - -6.815f, -3.801f, -5.357f, -8.078f, -8.767f, -7.227f, -5.909f, -6.119f, -5.632f, -4.117f, - -2.744f, 1.073f, 3.217f, 5.360f, 8.304f, 11.388f, 13.297f, 13.087f, 12.766f, 13.526f, - 13.606f -},{ --29.534f,-30.448f,-29.843f,-30.656f,-33.612f,-37.538f,-39.552f,-41.358f,-42.000f,-41.999f, --42.455f,-43.944f,-43.568f,-41.268f,-40.699f,-43.119f,-43.200f,-47.172f,-46.704f,-45.543f, --44.523f,-43.137f,-41.853f,-40.958f,-40.184f,-38.823f,-36.837f,-34.779f,-32.341f,-29.628f, --27.109f,-25.265f,-22.674f,-20.689f,-19.392f,-18.232f,-18.168f,-17.408f,-17.368f,-17.001f, --16.553f,-15.845f,-15.008f,-14.708f,-14.922f,-14.398f,-14.193f,-13.916f,-13.591f,-13.186f, --12.792f,-12.460f,-11.744f,-11.766f,-11.299f,-11.014f,-11.304f,-11.845f,-12.333f,-12.804f, --13.378f,-13.468f,-13.330f,-13.057f,-12.722f,-12.297f,-11.818f,-11.402f,-11.307f,-11.723f, --11.651f,-11.180f,-10.878f,-10.687f, -9.898f, -9.568f, -9.499f, -9.242f, -8.733f, -8.632f, - -8.837f, -9.129f, -9.116f, -9.147f, -8.933f, -9.093f, -9.368f, -9.643f,-10.253f,-10.864f, --11.755f,-13.054f,-14.350f,-15.846f,-17.397f,-18.636f,-20.123f,-22.580f,-24.897f,-26.386f, --27.688f,-29.188f,-30.694f,-32.061f,-33.319f,-34.502f,-35.320f,-36.312f,-37.395f,-37.771f, --37.809f,-37.646f,-37.927f,-38.305f,-38.584f,-38.912f,-39.365f,-39.223f,-39.179f,-39.216f, --39.275f,-39.314f,-39.606f,-39.434f,-40.460f,-40.272f,-39.865f,-39.191f,-38.633f,-37.248f, --36.467f,-32.556f,-31.243f,-30.315f,-28.927f,-26.749f,-24.980f,-23.276f,-21.752f,-20.044f, --18.203f,-16.562f,-13.264f,-10.747f, -8.848f, -6.000f, -2.171f, 0.969f, 1.087f, 1.604f, - 1.941f, 2.813f, 2.150f, 2.252f, 4.189f, 3.362f, -3.528f, -2.957f, -3.484f, -5.915f, - -7.273f, -5.373f, -4.422f, -7.361f, -7.382f, -5.724f, -5.296f, -5.738f, -5.421f, -4.147f, - -2.961f, 0.923f, 3.333f, 5.467f, 8.419f, 11.407f, 13.416f, 13.160f, 12.831f, 13.559f, - 13.606f -},{ --29.534f,-30.463f,-29.813f,-30.626f,-33.912f,-37.666f,-39.290f,-41.148f,-41.912f,-41.477f, --41.595f,-42.906f,-42.460f,-40.396f,-39.859f,-41.841f,-43.058f,-45.650f,-45.815f,-44.616f, --43.625f,-42.374f,-40.976f,-40.069f,-39.323f,-38.166f,-36.251f,-34.525f,-31.941f,-29.002f, --26.713f,-24.600f,-22.321f,-20.351f,-19.059f,-17.815f,-17.697f,-16.867f,-16.563f,-16.307f, --15.826f,-15.226f,-14.811f,-14.499f,-14.372f,-14.283f,-14.005f,-13.839f,-13.554f,-13.119f, --12.745f,-12.321f,-11.962f,-11.805f,-11.435f,-11.059f,-11.040f,-11.623f,-12.152f,-12.664f, --13.163f,-13.152f,-12.973f,-12.729f,-12.505f,-11.485f,-11.439f,-11.167f,-11.210f,-11.651f, --11.405f,-11.067f,-10.676f,-10.351f, -9.639f, -9.634f, -9.502f, -9.212f, -8.937f, -8.996f, - -9.244f, -9.688f, -9.888f, -9.728f, -9.540f, -9.926f,-10.434f,-10.838f,-11.490f,-12.208f, --13.154f,-14.529f,-15.669f,-17.217f,-18.716f,-19.939f,-21.683f,-23.839f,-26.046f,-27.673f, --29.262f,-30.613f,-32.274f,-33.673f,-34.974f,-36.113f,-37.013f,-37.978f,-38.700f,-39.169f, --39.386f,-39.528f,-39.466f,-39.893f,-39.994f,-40.569f,-40.842f,-40.637f,-40.498f,-40.518f, --40.465f,-40.136f,-40.045f,-40.194f,-40.629f,-40.316f,-40.105f,-39.639f,-38.624f,-37.237f, --36.635f,-32.102f,-31.023f,-29.987f,-28.542f,-26.248f,-24.595f,-23.469f,-21.818f,-20.551f, --18.042f,-17.337f,-14.113f,-11.580f, -9.114f, -7.051f, -3.247f, -1.551f, -0.004f, 0.354f, - 0.454f, 1.384f, 1.615f, 1.796f, 3.261f, 1.904f, -5.103f, -3.825f, -4.530f, -6.581f, - -7.954f, -7.267f, -4.962f, -6.853f, -5.596f, -4.111f, -4.983f, -5.223f, -5.114f, -4.096f, - -3.014f, 0.737f, 3.469f, 5.540f, 8.544f, 11.441f, 13.528f, 13.244f, 12.898f, 13.592f, - 13.606f -},{ --29.534f,-30.476f,-29.775f,-30.561f,-34.089f,-37.799f,-39.078f,-40.962f,-41.800f,-41.158f, --41.091f,-42.061f,-41.333f,-39.361f,-38.341f,-40.357f,-42.769f,-44.674f,-45.164f,-43.823f, --42.546f,-41.583f,-40.190f,-39.127f,-38.449f,-37.353f,-35.640f,-33.996f,-31.550f,-28.564f, --26.674f,-24.021f,-21.912f,-20.185f,-18.640f,-17.311f,-17.124f,-16.380f,-15.988f,-15.463f, --15.029f,-14.617f,-14.247f,-14.001f,-13.785f,-13.803f,-13.681f,-13.598f,-13.206f,-12.985f, --12.645f,-12.350f,-12.164f,-11.939f,-11.541f,-11.222f,-11.123f,-11.551f,-11.936f,-12.409f, --12.843f,-12.916f,-12.620f,-12.294f,-11.891f,-11.155f,-10.959f,-10.927f,-11.107f,-11.515f, --10.967f,-10.599f,-10.586f,-10.008f, -9.599f, -9.488f, -9.425f, -9.232f, -9.234f, -9.278f, - -9.534f,-10.216f,-10.441f,-10.481f,-10.285f,-10.732f,-11.473f,-11.667f,-12.599f,-13.494f, --14.495f,-15.736f,-16.911f,-18.416f,-19.915f,-21.290f,-22.937f,-25.209f,-27.291f,-29.070f, --30.748f,-32.318f,-33.914f,-35.158f,-36.333f,-37.581f,-38.615f,-39.366f,-39.834f,-40.429f, --40.883f,-41.018f,-41.064f,-41.036f,-41.341f,-41.586f,-41.987f,-41.842f,-41.904f,-41.789f, --41.341f,-40.885f,-40.459f,-40.767f,-40.975f,-40.704f,-40.146f,-39.781f,-38.902f,-36.944f, --36.583f,-31.923f,-30.626f,-29.670f,-28.177f,-26.550f,-24.951f,-23.473f,-21.932f,-20.839f, --20.232f,-16.453f,-14.187f,-12.180f,-10.313f, -7.716f, -5.544f, -2.640f, -0.998f, -1.008f, - -0.984f, -0.340f, 0.893f, 1.144f, 1.620f, -0.088f, -6.017f, -4.723f, -5.528f, -7.513f, - -8.850f, -8.884f, -7.393f, -7.203f, -4.684f, -3.375f, -4.866f, -4.429f, -4.666f, -3.956f, - -2.913f, 0.545f, 3.597f, 5.595f, 8.671f, 11.494f, 13.627f, 13.341f, 12.968f, 13.626f, - 13.606f -},{ --29.534f,-30.489f,-29.731f,-30.461f,-34.111f,-37.875f,-38.933f,-40.798f,-41.615f,-40.980f, --40.863f,-41.545f,-40.324f,-38.135f,-36.980f,-39.123f,-41.360f,-43.588f,-44.700f,-43.196f, --41.733f,-40.698f,-39.559f,-38.317f,-37.610f,-36.605f,-35.075f,-33.457f,-31.193f,-28.074f, --26.726f,-23.607f,-21.435f,-19.969f,-18.459f,-16.450f,-16.059f,-15.734f,-15.366f,-14.843f, --14.341f,-13.943f,-13.617f,-13.621f,-13.453f,-13.369f,-13.486f,-13.313f,-12.894f,-12.729f, --12.437f,-12.379f,-12.318f,-11.768f,-11.483f,-11.185f,-11.068f,-11.477f,-11.874f,-12.031f, --12.309f,-12.540f,-12.246f,-11.882f,-11.296f,-10.996f,-10.615f,-10.789f,-11.035f,-11.207f, --10.675f,-10.433f,-10.369f, -9.747f, -9.421f, -9.344f, -9.296f, -9.343f, -9.270f, -9.447f, - -9.996f,-10.404f,-10.990f,-11.058f,-11.082f,-11.623f,-12.158f,-12.735f,-13.792f,-14.521f, --15.677f,-16.847f,-18.241f,-19.671f,-21.067f,-22.559f,-24.293f,-26.529f,-28.518f,-30.596f, --32.206f,-33.974f,-35.479f,-36.527f,-37.614f,-39.111f,-39.929f,-40.364f,-41.115f,-41.657f, --42.040f,-42.150f,-42.064f,-42.003f,-42.477f,-42.662f,-43.022f,-43.118f,-42.833f,-42.590f, --42.081f,-41.307f,-40.728f,-41.097f,-41.160f,-40.952f,-40.375f,-39.816f,-38.812f,-36.780f, --36.480f,-31.664f,-30.512f,-29.290f,-27.715f,-26.442f,-25.114f,-23.718f,-22.026f,-21.535f, --19.588f,-15.445f,-14.202f,-13.038f, -9.654f, -8.423f, -6.743f, -3.919f, -2.220f, -2.558f, - -2.552f, -0.942f, 0.089f, 0.349f, -0.344f, -3.180f, -6.732f, -5.466f, -6.073f, -8.233f, - -9.484f,-10.091f,-10.015f, -8.378f, -5.436f, -4.212f, -4.965f, -3.449f, -4.119f, -3.827f, - -2.728f, 0.390f, 3.689f, 5.654f, 8.792f, 11.568f, 13.711f, 13.452f, 13.038f, 13.659f, - 13.606f -},{ --29.534f,-30.501f,-29.681f,-30.328f,-33.962f,-37.836f,-38.849f,-40.636f,-41.335f,-40.860f, --40.765f,-41.336f,-39.649f,-36.882f,-36.329f,-38.617f,-39.862f,-41.828f,-44.163f,-42.667f, --41.001f,-40.031f,-38.968f,-37.698f,-36.872f,-35.847f,-34.508f,-33.095f,-30.846f,-27.997f, --26.390f,-23.225f,-20.893f,-19.638f,-18.513f,-15.855f,-15.175f,-14.984f,-14.565f,-14.049f, --13.569f,-13.258f,-12.928f,-13.127f,-12.987f,-13.058f,-13.133f,-12.953f,-12.666f,-12.623f, --12.171f,-12.280f,-12.207f,-11.503f,-11.277f,-11.184f,-10.922f,-11.177f,-11.467f,-11.725f, --11.997f,-12.107f,-11.858f,-11.575f,-11.005f,-10.718f,-10.346f,-10.358f,-10.758f,-10.677f, --10.318f,-10.026f, -9.967f, -9.312f, -9.110f, -9.169f, -9.307f, -9.311f, -9.407f, -9.593f, --10.082f,-11.057f,-11.678f,-11.639f,-11.804f,-12.320f,-12.851f,-13.948f,-14.866f,-15.866f, --16.969f,-18.092f,-19.535f,-20.847f,-22.147f,-23.731f,-25.437f,-27.669f,-29.816f,-31.869f, --33.615f,-35.417f,-37.020f,-38.054f,-39.089f,-40.059f,-41.150f,-41.513f,-42.191f,-42.931f, --43.281f,-43.390f,-43.346f,-43.464f,-43.479f,-43.791f,-44.127f,-43.922f,-43.629f,-42.984f, --42.427f,-41.678f,-41.279f,-41.274f,-41.249f,-41.102f,-40.458f,-39.554f,-38.616f,-36.682f, --35.881f,-31.652f,-30.172f,-29.073f,-27.734f,-26.519f,-25.221f,-24.071f,-22.958f,-21.418f, --16.358f,-15.445f,-14.134f,-12.212f, -9.539f, -8.731f, -6.902f, -4.635f, -3.910f, -3.956f, - -3.825f, -1.849f, -0.838f, -0.897f, -2.581f, -6.719f, -7.441f, -6.371f, -6.645f, -8.705f, --10.034f,-11.124f,-10.948f, -9.591f, -7.138f, -6.173f, -5.454f, -2.723f, -3.583f, -3.827f, - -2.559f, 0.307f, 3.732f, 5.740f, 8.900f, 11.661f, 13.780f, 13.577f, 13.108f, 13.693f, - 13.606f -},{ --29.534f,-30.512f,-29.626f,-30.168f,-33.649f,-37.639f,-38.794f,-40.436f,-40.959f,-40.741f, --40.681f,-41.257f,-39.434f,-36.029f,-36.128f,-38.572f,-39.320f,-40.296f,-43.597f,-42.155f, --40.294f,-39.760f,-38.252f,-37.126f,-36.310f,-35.111f,-33.964f,-32.615f,-30.568f,-28.263f, --25.739f,-22.894f,-20.644f,-19.158f,-18.093f,-15.230f,-14.656f,-14.381f,-13.936f,-13.397f, --12.915f,-12.532f,-12.466f,-12.673f,-12.619f,-12.594f,-12.754f,-12.661f,-12.382f,-12.333f, --12.214f,-12.223f,-12.274f,-11.676f,-11.334f,-10.809f,-11.086f,-11.038f,-11.209f,-11.398f, --11.713f,-11.831f,-11.485f,-11.286f,-10.771f,-10.454f,-10.163f,-10.149f,-10.302f,-10.107f, - -9.861f, -9.350f, -9.508f, -8.895f, -8.826f, -8.875f, -9.085f, -9.365f, -9.465f, -9.739f, --10.290f,-11.345f,-11.929f,-12.113f,-12.682f,-13.192f,-13.802f,-15.082f,-16.002f,-17.083f, --18.265f,-19.324f,-20.791f,-22.177f,-23.445f,-25.053f,-26.601f,-28.908f,-31.050f,-33.193f, --34.915f,-36.501f,-38.220f,-39.336f,-40.472f,-41.320f,-42.195f,-42.779f,-43.121f,-43.727f, --44.405f,-44.540f,-44.539f,-44.722f,-44.462f,-44.819f,-45.090f,-44.635f,-44.039f,-43.876f, --42.895f,-42.179f,-41.628f,-41.427f,-41.432f,-41.078f,-40.449f,-39.289f,-37.943f,-36.142f, --35.004f,-31.811f,-30.044f,-29.285f,-28.710f,-27.498f,-26.064f,-24.525f,-22.549f,-19.565f, --14.891f,-15.066f,-12.842f,-11.324f,-10.897f, -9.300f, -7.693f, -5.818f, -5.256f, -5.410f, - -4.676f, -3.477f, -2.404f, -3.023f, -5.699f, -9.565f, -8.504f, -7.527f, -7.660f, -8.988f, --10.769f,-11.956f,-10.474f,-10.218f, -8.526f, -8.160f, -6.338f, -2.687f, -3.149f, -3.951f, - -2.477f, 0.299f, 3.735f, 5.866f, 8.993f, 11.771f, 13.834f, 13.714f, 13.176f, 13.728f, - 13.606f -},{ --29.534f,-30.522f,-29.567f,-29.989f,-33.198f,-37.264f,-38.723f,-40.161f,-40.502f,-40.604f, --40.567f,-41.089f,-39.537f,-35.948f,-35.888f,-38.263f,-39.151f,-39.934f,-43.100f,-41.589f, --39.775f,-39.333f,-37.596f,-36.613f,-35.822f,-34.615f,-33.403f,-32.124f,-30.163f,-28.686f, --24.888f,-22.566f,-20.706f,-18.630f,-17.298f,-14.911f,-14.191f,-13.732f,-13.454f,-12.691f, --12.448f,-11.928f,-12.080f,-12.035f,-12.284f,-12.204f,-12.327f,-12.355f,-12.180f,-12.162f, --12.090f,-12.206f,-12.042f,-11.803f,-10.994f,-11.090f,-11.005f,-11.157f,-10.966f,-11.240f, --11.448f,-11.351f,-11.135f,-10.877f,-10.252f, -9.981f, -9.786f, -9.726f, -9.746f, -9.540f, - -9.258f, -8.751f, -8.932f, -8.375f, -8.412f, -8.567f, -8.784f, -9.106f, -9.330f, -9.753f, --10.406f,-11.456f,-12.344f,-12.977f,-13.534f,-13.805f,-14.684f,-15.948f,-17.054f,-18.055f, --19.467f,-20.578f,-22.112f,-23.396f,-24.617f,-26.194f,-27.879f,-30.088f,-32.277f,-34.330f, --36.114f,-37.687f,-39.349f,-40.582f,-41.620f,-42.423f,-42.953f,-43.661f,-44.114f,-44.443f, --45.298f,-45.575f,-45.486f,-45.538f,-45.458f,-45.544f,-45.576f,-45.334f,-44.364f,-44.028f, --43.416f,-42.268f,-41.600f,-41.668f,-41.475f,-40.740f,-39.959f,-39.006f,-37.303f,-35.663f, --33.730f,-32.531f,-30.161f,-29.236f,-27.883f,-26.905f,-25.796f,-24.478f,-22.974f,-17.300f, --16.830f,-14.666f,-11.708f,-11.557f,-11.803f,-10.222f, -8.368f, -7.653f, -6.283f, -8.448f, - -6.776f, -4.837f, -4.186f, -5.275f, -8.097f,-10.599f,-10.366f, -8.985f, -8.482f, -8.640f, --11.468f,-12.315f, -9.943f,-10.195f, -9.136f, -9.569f, -7.240f, -3.321f, -2.833f, -4.031f, - -2.476f, 0.332f, 3.724f, 6.032f, 9.072f, 11.892f, 13.875f, 13.862f, 13.241f, 13.762f, - 13.606f -},{ --29.534f,-30.531f,-29.505f,-29.803f,-32.657f,-36.728f,-38.589f,-39.794f,-39.977f,-40.443f, --40.417f,-40.719f,-39.614f,-36.550f,-35.704f,-37.682f,-38.464f,-40.026f,-42.300f,-40.970f, --39.576f,-38.537f,-37.193f,-36.265f,-35.285f,-34.067f,-32.871f,-31.598f,-29.821f,-28.341f, --24.606f,-22.632f,-20.596f,-18.426f,-16.915f,-14.351f,-13.755f,-13.133f,-12.904f,-12.107f, --11.934f,-11.464f,-11.795f,-11.574f,-11.745f,-11.818f,-11.934f,-12.011f,-12.031f,-12.068f, --12.137f,-12.203f,-12.049f,-11.756f,-11.608f,-11.280f,-11.553f,-11.271f,-10.766f,-11.152f, --11.210f,-10.988f,-10.831f,-10.360f, -9.892f, -9.465f, -9.209f, -9.135f, -9.149f, -8.716f, - -8.451f, -8.197f, -8.133f, -7.782f, -7.980f, -8.262f, -8.635f, -8.837f, -9.236f, -9.808f, --10.702f,-11.459f,-12.720f,-13.313f,-14.076f,-14.416f,-15.314f,-16.760f,-17.834f,-18.988f, --20.459f,-21.781f,-23.202f,-24.533f,-25.824f,-27.348f,-28.847f,-31.150f,-33.284f,-35.225f, --37.190f,-38.806f,-40.334f,-41.661f,-42.653f,-43.516f,-43.928f,-44.525f,-45.033f,-45.654f, --46.167f,-46.317f,-46.223f,-46.201f,-46.390f,-46.322f,-46.014f,-45.489f,-44.827f,-44.140f, --43.462f,-42.352f,-41.708f,-41.443f,-41.263f,-40.140f,-38.686f,-37.982f,-37.135f,-33.591f, --30.970f,-29.710f,-26.661f,-24.110f,-23.402f,-22.561f,-22.724f,-23.070f,-20.301f,-17.378f, --17.479f,-13.969f,-12.942f,-12.149f,-12.079f,-10.625f, -9.611f, -8.368f, -8.867f,-10.750f, --10.322f, -8.360f, -7.232f, -7.912f, -9.404f,-11.337f,-11.967f,-10.438f, -8.945f, -8.163f, --12.205f,-12.521f, -9.683f, -9.703f, -9.277f,-10.496f, -7.700f, -4.168f, -2.634f, -3.867f, - -2.463f, 0.366f, 3.731f, 6.219f, 9.140f, 12.023f, 13.908f, 14.017f, 13.303f, 13.797f, - 13.606f -},{ --29.534f,-30.538f,-29.440f,-29.621f,-32.083f,-36.074f,-38.358f,-39.344f,-39.396f,-40.246f, --40.212f,-40.198f,-39.398f,-37.262f,-36.027f,-37.436f,-37.529f,-39.442f,-41.116f,-40.458f, --39.574f,-37.723f,-36.822f,-36.018f,-34.807f,-33.459f,-32.357f,-31.004f,-29.520f,-27.370f, --24.380f,-22.476f,-20.305f,-18.349f,-16.452f,-13.585f,-13.303f,-12.501f,-12.370f,-11.580f, --11.551f,-11.036f,-11.490f,-11.342f,-11.421f,-11.634f,-11.614f,-11.946f,-11.978f,-12.076f, --12.467f,-12.356f,-12.113f,-12.008f,-11.673f,-11.656f,-11.742f,-11.307f,-10.731f,-10.836f, --10.816f,-10.652f,-10.454f, -9.852f, -9.306f, -8.994f, -8.629f, -8.365f, -8.356f, -7.844f, - -7.785f, -7.486f, -7.436f, -7.334f, -7.517f, -7.893f, -8.285f, -8.552f, -9.306f, -9.647f, --10.610f,-11.521f,-12.868f,-13.635f,-14.413f,-14.830f,-15.852f,-17.214f,-18.543f,-20.016f, --21.303f,-22.708f,-24.259f,-25.481f,-26.973f,-28.231f,-29.926f,-31.934f,-34.182f,-36.123f, --37.916f,-39.561f,-41.130f,-42.580f,-43.517f,-44.311f,-44.753f,-45.261f,-45.819f,-46.324f, --46.954f,-47.087f,-46.940f,-46.898f,-46.946f,-46.743f,-46.461f,-45.880f,-45.024f,-44.228f, --43.240f,-42.211f,-41.856f,-40.955f,-40.632f,-39.455f,-37.859f,-36.625f,-33.025f,-29.662f, --28.372f,-25.342f,-24.125f,-23.214f,-22.472f,-21.835f,-20.457f,-20.539f,-20.262f,-20.566f, --16.838f,-13.577f,-13.603f,-13.256f,-12.684f,-11.742f,-10.875f,-10.262f,-11.763f,-12.353f, --11.941f,-11.292f,-10.679f,-10.569f,-10.811f,-12.860f,-13.278f,-11.536f, -9.557f, -8.491f, --12.967f,-13.165f, -9.480f, -9.067f, -9.349f,-11.098f, -7.665f, -4.796f, -2.605f, -3.391f, - -2.314f, 0.385f, 3.773f, 6.404f, 9.207f, 12.162f, 13.938f, 14.175f, 13.360f, 13.832f, - 13.606f -},{ --29.534f,-30.544f,-29.373f,-29.454f,-31.541f,-35.374f,-38.026f,-38.850f,-38.774f,-39.985f, --39.908f,-39.660f,-38.892f,-37.523f,-36.743f,-37.463f,-36.961f,-38.394f,-40.177f,-40.102f, --39.030f,-36.824f,-36.314f,-35.672f,-34.392f,-33.126f,-31.787f,-30.296f,-29.175f,-26.556f, --24.183f,-22.193f,-19.916f,-18.603f,-15.288f,-13.140f,-12.750f,-12.048f,-11.875f,-11.126f, --10.971f,-10.779f,-11.036f,-11.198f,-10.956f,-11.394f,-11.442f,-11.821f,-12.215f,-12.488f, --12.683f,-12.627f,-12.488f,-12.411f,-11.751f,-12.227f,-11.932f,-11.118f,-10.841f,-10.800f, --10.739f,-10.410f,-10.004f, -9.377f, -8.941f, -8.329f, -8.020f, -7.820f, -7.476f, -7.013f, - -6.964f, -6.783f, -6.723f, -6.819f, -6.945f, -7.490f, -7.910f, -8.326f, -9.050f, -9.622f, --10.760f,-11.894f,-13.233f,-14.029f,-14.601f,-15.164f,-16.428f,-17.814f,-19.354f,-20.679f, --22.125f,-23.554f,-25.060f,-26.316f,-27.826f,-29.148f,-30.844f,-32.483f,-34.716f,-36.829f, --38.497f,-40.208f,-41.638f,-43.042f,-43.882f,-44.720f,-45.141f,-45.857f,-46.442f,-46.823f, --47.434f,-47.541f,-47.402f,-47.171f,-47.205f,-47.112f,-46.221f,-45.907f,-44.997f,-44.206f, --43.296f,-42.244f,-41.551f,-40.710f,-39.712f,-39.227f,-36.380f,-33.354f,-31.936f,-29.786f, --27.657f,-24.879f,-22.807f,-21.243f,-20.567f,-20.387f,-19.855f,-20.166f,-21.612f,-18.875f, --16.618f,-14.798f,-14.172f,-13.478f,-13.513f,-12.492f,-12.667f,-12.124f,-13.257f,-13.373f, --12.413f,-12.301f,-13.053f,-12.405f,-12.589f,-14.575f,-15.060f,-12.946f,-10.451f, -9.410f, --13.447f,-14.024f, -9.643f, -8.735f, -9.668f,-11.378f, -7.540f, -5.125f, -2.805f, -2.720f, - -1.944f, 0.412f, 3.843f, 6.562f, 9.286f, 12.308f, 13.970f, 14.332f, 13.412f, 13.868f, - 13.606f -},{ --29.534f,-30.549f,-29.307f,-29.312f,-31.092f,-34.711f,-37.614f,-38.361f,-38.141f,-39.638f, --39.482f,-39.180f,-38.253f,-37.259f,-37.061f,-37.015f,-36.710f,-37.617f,-39.489f,-39.678f, --37.776f,-36.121f,-35.917f,-35.280f,-34.009f,-32.700f,-31.490f,-29.815f,-28.774f,-25.931f, --24.017f,-21.797f,-19.581f,-18.802f,-14.514f,-12.732f,-12.280f,-11.650f,-11.294f,-10.736f, --10.561f,-10.549f,-10.753f,-11.062f,-10.815f,-11.235f,-11.280f,-11.732f,-12.355f,-12.718f, --12.944f,-12.947f,-12.711f,-12.155f,-12.120f,-11.711f,-12.105f,-11.129f,-10.856f,-10.690f, --10.616f,-10.089f, -9.823f, -8.938f, -8.337f, -7.737f, -7.354f, -7.140f, -6.757f, -6.212f, - -6.235f, -6.090f, -6.166f, -6.216f, -6.516f, -6.997f, -7.558f, -8.069f, -8.853f, -9.722f, --10.804f,-12.277f,-13.518f,-14.350f,-14.887f,-15.728f,-17.159f,-18.307f,-20.026f,-21.353f, --22.783f,-24.259f,-25.616f,-27.077f,-28.462f,-29.677f,-31.331f,-33.003f,-35.155f,-37.238f, --39.102f,-40.725f,-42.004f,-43.219f,-44.045f,-44.955f,-45.662f,-45.758f,-46.805f,-47.351f, --47.569f,-47.702f,-47.538f,-47.511f,-47.140f,-46.826f,-46.329f,-45.639f,-44.823f,-44.011f, --42.906f,-41.795f,-40.965f,-40.366f,-39.053f,-36.262f,-33.256f,-32.691f,-30.994f,-27.231f, --23.423f,-22.688f,-21.369f,-20.071f,-19.494f,-20.094f,-19.683f,-18.239f,-17.851f,-16.704f, --15.990f,-15.192f,-14.303f,-13.797f,-13.850f,-13.682f,-13.901f,-13.472f,-14.649f,-14.670f, --13.882f,-13.780f,-13.991f,-13.612f,-14.384f,-15.633f,-16.489f,-14.709f,-11.310f,-10.522f, --14.126f,-14.539f,-10.408f, -8.987f,-10.394f,-11.496f, -7.702f, -5.296f, -3.157f, -2.035f, - -1.361f, 0.489f, 3.915f, 6.676f, 9.389f, 12.463f, 14.008f, 14.484f, 13.458f, 13.903f, - 13.606f -},{ --29.534f,-30.552f,-29.240f,-29.204f,-30.786f,-34.165f,-37.168f,-37.919f,-37.536f,-39.208f, --38.973f,-38.705f,-37.572f,-36.844f,-36.538f,-36.105f,-36.623f,-37.005f,-38.229f,-39.107f, --36.812f,-35.997f,-35.609f,-34.977f,-33.613f,-32.229f,-31.155f,-29.682f,-27.976f,-25.783f, --23.647f,-21.401f,-19.587f,-18.506f,-14.323f,-12.628f,-12.045f,-11.421f,-10.904f,-10.441f, --10.242f,-10.395f,-10.422f,-10.787f,-10.692f,-10.932f,-11.280f,-11.619f,-12.337f,-12.786f, --12.902f,-12.915f,-12.729f,-12.511f,-12.225f,-11.866f,-11.470f,-11.154f,-10.832f,-10.651f, --10.455f, -9.952f, -9.471f, -8.577f, -7.783f, -7.259f, -6.780f, -6.431f, -6.025f, -5.664f, - -5.528f, -5.390f, -5.523f, -5.628f, -5.998f, -6.567f, -7.166f, -7.887f, -8.780f, -9.887f, --11.028f,-12.572f,-13.436f,-14.538f,-15.233f,-16.281f,-17.514f,-18.840f,-20.408f,-21.923f, --23.146f,-24.831f,-26.079f,-27.583f,-28.951f,-30.236f,-31.803f,-33.267f,-35.370f,-37.444f, --39.423f,-40.836f,-42.201f,-43.242f,-44.172f,-44.844f,-45.674f,-46.056f,-46.757f,-47.189f, --47.576f,-47.487f,-47.406f,-47.312f,-47.124f,-46.555f,-46.189f,-45.214f,-44.334f,-43.151f, --42.404f,-41.472f,-40.781f,-38.420f,-37.231f,-33.954f,-34.083f,-32.350f,-25.939f,-23.671f, --23.328f,-21.539f,-19.960f,-19.272f,-17.952f,-19.165f,-20.384f,-19.521f,-17.923f,-16.168f, --16.043f,-15.836f,-14.758f,-14.277f,-13.685f,-15.389f,-14.847f,-14.363f,-15.115f,-16.836f, --15.902f,-15.826f,-14.970f,-15.791f,-16.173f,-16.214f,-17.296f,-15.903f,-12.456f,-11.914f, --15.490f,-14.878f,-11.449f, -9.807f,-11.245f,-11.694f, -8.097f, -5.397f, -3.423f, -1.430f, - -0.649f, 0.639f, 3.952f, 6.749f, 9.525f, 12.625f, 14.057f, 14.624f, 13.498f, 13.939f, - 13.606f -},{ --29.534f,-30.554f,-29.175f,-29.133f,-30.653f,-33.799f,-36.741f,-37.539f,-37.001f,-38.730f, --38.489f,-38.128f,-36.842f,-36.609f,-35.742f,-35.716f,-36.956f,-36.249f,-36.514f,-38.608f, --36.485f,-35.708f,-35.102f,-34.557f,-33.128f,-31.941f,-30.628f,-29.348f,-27.262f,-25.448f, --23.295f,-21.060f,-19.566f,-18.241f,-14.142f,-12.564f,-11.785f,-11.187f,-10.675f,-10.265f, - -9.951f,-10.302f,-10.108f,-10.469f,-10.502f,-10.853f,-11.190f,-11.559f,-12.177f,-12.656f, --12.685f,-12.894f,-12.765f,-12.383f,-11.975f,-11.519f,-11.577f,-11.109f,-10.776f,-10.596f, --10.153f, -9.797f, -9.281f, -8.247f, -7.443f, -6.714f, -6.231f, -5.825f, -5.357f, -5.069f, - -4.856f, -4.828f, -4.876f, -5.063f, -5.509f, -6.074f, -6.680f, -7.598f, -8.555f, -9.854f, --11.012f,-12.516f,-13.473f,-14.683f,-15.406f,-16.741f,-17.882f,-19.362f,-20.786f,-22.246f, --23.593f,-25.154f,-26.543f,-27.858f,-29.267f,-30.486f,-31.927f,-33.531f,-35.425f,-37.399f, --39.402f,-40.961f,-42.157f,-43.135f,-44.065f,-44.912f,-45.302f,-45.929f,-46.344f,-46.779f, --47.134f,-47.336f,-47.147f,-46.942f,-46.837f,-46.160f,-45.674f,-44.765f,-44.030f,-42.662f, --41.901f,-40.885f,-39.057f,-37.702f,-37.176f,-32.509f,-31.684f,-26.771f,-24.360f,-24.748f, --23.160f,-21.285f,-19.376f,-18.329f,-17.550f,-17.179f,-20.659f,-19.650f,-18.185f,-16.313f, --15.932f,-16.390f,-14.992f,-14.530f,-14.617f,-16.466f,-15.941f,-15.405f,-16.919f,-17.994f, --17.112f,-18.229f,-17.646f,-18.289f,-17.658f,-17.786f,-18.020f,-16.494f,-14.513f,-13.570f, --16.892f,-15.423f,-12.420f,-10.983f,-11.759f,-11.918f, -8.399f, -5.445f, -3.383f, -0.876f, - 0.092f, 0.854f, 3.933f, 6.793f, 9.695f, 12.790f, 14.118f, 14.751f, 13.533f, 13.976f, - 13.606f -},{ --29.534f,-30.554f,-29.111f,-29.100f,-30.698f,-33.642f,-36.376f,-37.203f,-36.554f,-38.245f, --38.153f,-37.426f,-36.119f,-36.523f,-35.519f,-36.202f,-37.701f,-35.637f,-35.286f,-38.201f, --36.193f,-35.048f,-34.561f,-34.056f,-32.802f,-31.465f,-30.113f,-28.746f,-26.990f,-25.156f, --23.052f,-21.162f,-19.465f,-17.823f,-14.121f,-12.716f,-11.655f,-11.004f,-10.536f,-10.239f, - -9.797f,-10.087f, -9.897f,-10.176f,-10.411f,-10.674f,-11.099f,-11.477f,-12.012f,-12.316f, --12.593f,-12.713f,-12.546f,-12.300f,-12.006f,-11.935f,-11.292f,-10.999f,-10.657f,-10.472f, - -9.976f, -9.532f, -9.109f, -7.968f, -7.057f, -6.232f, -5.682f, -5.205f, -4.794f, -4.479f, - -4.202f, -4.254f, -4.259f, -4.499f, -4.880f, -5.556f, -6.044f, -7.272f, -8.352f, -9.485f, --11.012f,-12.329f,-13.381f,-14.625f,-15.662f,-16.766f,-17.978f,-19.475f,-21.195f,-22.468f, --23.949f,-25.249f,-26.658f,-28.217f,-29.370f,-30.781f,-32.143f,-33.408f,-35.392f,-37.186f, --39.082f,-40.612f,-41.818f,-43.086f,-43.695f,-44.369f,-44.635f,-45.151f,-45.679f,-46.213f, --46.358f,-46.624f,-46.633f,-46.199f,-45.956f,-45.436f,-45.014f,-44.206f,-43.291f,-41.933f, --41.034f,-39.550f,-38.296f,-37.119f,-34.158f,-31.893f,-28.918f,-27.129f,-25.461f,-23.667f, --22.678f,-20.394f,-18.263f,-17.543f,-16.998f,-16.304f,-18.197f,-18.592f,-17.497f,-16.279f, --16.183f,-15.961f,-14.728f,-14.195f,-15.387f,-16.781f,-17.434f,-17.422f,-18.799f,-19.039f, --18.336f,-20.339f,-20.085f,-19.716f,-19.022f,-19.380f,-18.670f,-17.255f,-16.567f,-15.385f, --17.729f,-16.010f,-13.256f,-12.155f,-12.067f,-11.898f, -8.437f, -5.534f, -3.059f, -0.322f, - 0.817f, 1.103f, 3.864f, 6.831f, 9.894f, 12.954f, 14.191f, 14.861f, 13.563f, 14.013f, - 13.606f -},{ --29.534f,-30.553f,-29.050f,-29.103f,-30.902f,-33.686f,-36.096f,-36.866f,-36.183f,-37.789f, --38.035f,-36.717f,-35.598f,-36.366f,-35.838f,-36.592f,-38.173f,-35.405f,-34.441f,-37.658f, --35.740f,-34.701f,-34.044f,-33.661f,-32.453f,-30.997f,-29.644f,-28.212f,-26.676f,-24.960f, --22.945f,-21.099f,-19.515f,-17.069f,-14.148f,-12.937f,-11.802f,-11.204f,-10.635f,-10.238f, - -9.598f, -9.797f, -9.763f, -9.936f,-10.222f,-10.661f,-11.022f,-11.301f,-11.814f,-12.016f, --12.224f,-12.412f,-12.420f,-12.187f,-12.125f,-11.661f,-11.358f,-10.866f,-10.621f,-10.218f, - -9.746f, -9.247f, -8.712f, -7.630f, -6.425f, -5.692f, -5.204f, -4.754f, -4.255f, -3.954f, - -3.692f, -3.628f, -3.641f, -3.891f, -4.232f, -4.826f, -5.512f, -6.737f, -7.882f, -9.150f, --10.713f,-11.940f,-13.379f,-14.353f,-15.510f,-16.623f,-18.082f,-19.571f,-21.208f,-22.508f, --23.996f,-25.318f,-26.636f,-27.959f,-29.289f,-30.828f,-32.140f,-33.523f,-35.171f,-36.828f, --38.594f,-39.958f,-41.069f,-42.285f,-43.068f,-43.615f,-44.065f,-43.914f,-44.761f,-45.400f, --45.569f,-45.948f,-45.728f,-45.620f,-45.061f,-44.586f,-44.184f,-43.359f,-42.506f,-41.788f, --40.227f,-38.494f,-36.502f,-33.181f,-31.850f,-31.647f,-30.432f,-28.038f,-25.462f,-22.301f, --21.096f,-19.176f,-17.163f,-16.205f,-17.081f,-15.281f,-16.499f,-17.465f,-16.633f,-15.794f, --15.886f,-15.653f,-13.114f,-14.657f,-16.322f,-17.275f,-18.365f,-19.255f,-20.362f,-19.627f, --20.388f,-22.436f,-21.966f,-21.500f,-20.754f,-19.812f,-18.828f,-18.256f,-17.551f,-17.083f, --18.059f,-16.429f,-14.078f,-13.078f,-12.790f,-11.633f, -8.300f, -5.819f, -2.712f, 0.186f, - 1.552f, 1.368f, 3.782f, 6.885f, 10.109f, 13.111f, 14.274f, 14.951f, 13.589f, 14.050f, - 13.606f -},{ --29.534f,-30.551f,-28.992f,-29.134f,-31.225f,-33.885f,-35.891f,-36.473f,-35.846f,-37.377f, --38.110f,-36.178f,-35.415f,-36.078f,-35.801f,-35.959f,-37.751f,-35.229f,-33.398f,-37.001f, --35.226f,-34.341f,-33.455f,-33.164f,-31.953f,-30.616f,-29.404f,-27.825f,-26.260f,-24.841f, --23.016f,-21.029f,-19.995f,-16.855f,-14.219f,-13.059f,-11.993f,-11.157f,-10.681f,-10.339f, - -9.726f, -9.739f, -9.777f, -9.832f,-10.060f,-10.423f,-10.814f,-11.115f,-11.537f,-11.724f, --12.022f,-12.119f,-12.054f,-11.928f,-11.617f,-11.616f,-11.303f,-10.734f,-10.453f,-10.003f, - -9.535f, -8.978f, -8.262f, -7.254f, -5.980f, -5.428f, -4.812f, -4.383f, -3.872f, -3.586f, - -3.223f, -3.082f, -3.108f, -3.388f, -3.750f, -4.344f, -4.986f, -6.035f, -7.240f, -8.680f, --10.261f,-11.646f,-13.014f,-14.139f,-15.432f,-16.672f,-17.960f,-19.458f,-20.993f,-22.460f, --23.817f,-25.183f,-26.431f,-27.733f,-29.028f,-30.545f,-31.762f,-33.137f,-34.720f,-36.212f, --37.806f,-39.020f,-40.303f,-41.309f,-42.124f,-42.387f,-43.177f,-43.508f,-43.865f,-44.190f, --44.431f,-44.587f,-44.719f,-44.697f,-44.336f,-43.134f,-43.222f,-42.894f,-43.366f,-40.697f, --38.398f,-34.144f,-32.501f,-34.244f,-32.429f,-31.427f,-28.793f,-27.154f,-24.683f,-22.018f, --19.722f,-18.023f,-16.044f,-16.022f,-15.495f,-15.024f,-15.843f,-15.973f,-16.352f,-15.383f, --15.436f,-14.152f,-12.240f,-16.439f,-17.535f,-17.898f,-19.311f,-20.137f,-21.205f,-20.083f, --22.357f,-24.373f,-23.907f,-23.452f,-22.188f,-20.466f,-18.727f,-19.004f,-18.519f,-18.363f, --18.034f,-16.819f,-15.098f,-13.918f,-13.982f,-11.418f, -8.112f, -6.327f, -2.586f, 0.503f, - 2.344f, 1.665f, 3.741f, 6.969f, 10.327f, 13.253f, 14.364f, 15.020f, 13.612f, 14.088f, - 13.606f -},{ --29.534f,-30.547f,-28.937f,-29.186f,-31.607f,-34.161f,-35.723f,-35.981f,-35.490f,-37.010f, --38.278f,-35.902f,-35.430f,-35.789f,-34.753f,-34.580f,-36.492f,-34.812f,-32.647f,-36.353f, --34.745f,-33.754f,-32.944f,-32.487f,-31.602f,-30.273f,-29.091f,-27.531f,-25.923f,-24.632f, --23.018f,-21.568f,-19.737f,-17.255f,-14.269f,-13.034f,-12.061f,-11.240f,-10.786f,-10.450f, - -9.982f, -9.515f, -9.657f, -9.631f, -9.816f,-10.201f,-10.678f,-10.836f,-11.272f,-11.498f, --11.732f,-11.829f,-11.774f,-11.524f,-11.155f,-11.168f,-11.120f,-10.610f,-10.186f, -9.864f, - -9.250f, -8.714f, -7.932f, -6.878f, -5.848f, -5.213f, -4.604f, -4.007f, -3.571f, -3.246f, - -2.961f, -2.729f, -2.672f, -2.886f, -3.315f, -3.885f, -4.549f, -5.581f, -6.747f, -8.128f, - -9.583f,-11.156f,-12.758f,-13.948f,-15.241f,-16.473f,-17.760f,-19.303f,-20.716f,-22.122f, --23.417f,-24.721f,-25.906f,-27.076f,-28.518f,-30.084f,-31.372f,-32.780f,-34.094f,-35.446f, --36.774f,-37.963f,-39.181f,-40.043f,-40.543f,-41.067f,-41.574f,-42.207f,-42.420f,-42.795f, --43.011f,-43.110f,-43.302f,-43.139f,-42.729f,-42.576f,-41.754f,-42.586f,-37.387f,-37.795f, --34.618f,-34.869f,-35.331f,-34.136f,-32.594f,-30.368f,-28.741f,-26.574f,-24.007f,-20.946f, --19.352f,-17.096f,-15.040f,-14.916f,-13.119f,-14.016f,-14.887f,-15.090f,-15.403f,-15.312f, --14.147f,-13.466f,-15.499f,-17.815f,-18.646f,-19.003f,-20.045f,-21.713f,-22.898f,-21.228f, --24.236f,-26.227f,-25.922f,-25.296f,-23.361f,-21.530f,-19.660f,-19.988f,-20.734f,-19.416f, --18.038f,-17.170f,-16.243f,-14.947f,-14.932f,-11.427f, -7.954f, -6.891f, -2.695f, 0.504f, - 3.179f, 2.033f, 3.785f, 7.086f, 10.535f, 13.376f, 14.457f, 15.070f, 13.633f, 14.126f, - 13.606f -},{ --29.534f,-30.541f,-28.887f,-29.246f,-31.980f,-34.423f,-35.536f,-35.376f,-35.086f,-36.689f, --38.412f,-35.816f,-35.306f,-35.571f,-33.071f,-33.236f,-34.894f,-34.272f,-32.595f,-35.581f, --34.453f,-33.549f,-32.265f,-31.867f,-31.072f,-30.010f,-28.650f,-27.205f,-25.725f,-24.437f, --23.196f,-22.044f,-19.042f,-17.408f,-14.408f,-13.065f,-12.246f,-11.346f,-10.994f,-10.418f, - -9.996f, -9.409f, -9.432f, -9.463f, -9.725f,-10.023f,-10.351f,-10.628f,-10.894f,-11.132f, --11.347f,-11.490f,-11.362f,-11.205f,-10.796f,-11.031f,-10.896f,-10.325f,-10.007f, -9.476f, - -9.004f, -8.375f, -7.452f, -6.390f, -5.661f, -5.219f, -4.492f, -3.796f, -3.278f, -3.004f, - -2.703f, -2.427f, -2.354f, -2.570f, -2.982f, -3.542f, -4.215f, -5.232f, -6.361f, -7.559f, - -8.949f,-10.565f,-12.140f,-13.659f,-14.905f,-16.210f,-17.508f,-18.879f,-20.248f,-21.618f, --22.804f,-24.144f,-25.250f,-26.500f,-27.965f,-29.473f,-30.719f,-32.120f,-33.274f,-34.413f, --35.668f,-36.627f,-37.746f,-38.561f,-38.919f,-39.494f,-39.759f,-40.476f,-40.844f,-41.228f, --41.478f,-41.757f,-41.883f,-41.746f,-41.608f,-41.265f,-41.269f,-37.749f,-37.482f,-35.285f, --36.520f,-35.721f,-34.478f,-32.773f,-31.351f,-29.419f,-27.302f,-25.644f,-22.832f,-20.550f, --19.121f,-17.492f,-14.571f,-13.664f,-11.491f,-13.005f,-13.375f,-14.396f,-15.096f,-14.701f, --15.554f,-16.846f,-18.130f,-19.590f,-20.116f,-20.482f,-20.974f,-22.074f,-23.835f,-24.222f, --26.186f,-27.857f,-27.691f,-26.527f,-24.183f,-22.335f,-21.264f,-21.720f,-23.396f,-20.349f, --18.443f,-17.315f,-17.221f,-16.133f,-15.275f,-11.582f, -7.995f, -7.327f, -2.865f, 0.194f, - 3.949f, 2.504f, 3.931f, 7.234f, 10.729f, 13.479f, 14.548f, 15.100f, 13.655f, 14.165f, - 13.606f -},{ --29.534f,-30.534f,-28.841f,-29.303f,-32.279f,-34.578f,-35.272f,-34.679f,-34.635f,-36.402f, --38.407f,-35.737f,-34.864f,-35.332f,-31.775f,-32.161f,-33.414f,-33.826f,-32.509f,-34.845f, --34.148f,-33.452f,-31.596f,-31.327f,-30.441f,-29.508f,-28.192f,-26.804f,-25.560f,-24.315f, --23.007f,-22.294f,-19.132f,-16.876f,-14.512f,-13.342f,-12.296f,-11.469f,-11.139f,-10.403f, --10.150f, -9.485f, -9.391f, -9.395f, -9.527f, -9.803f,-10.144f,-10.350f,-10.576f,-10.849f, --10.988f,-11.132f,-10.862f,-10.702f,-10.813f,-10.823f,-10.370f,-10.033f, -9.669f, -9.187f, - -8.752f, -7.997f, -6.827f, -6.093f, -5.510f, -4.990f, -4.366f, -3.873f, -3.239f, -2.805f, - -2.404f, -2.132f, -2.066f, -2.315f, -2.808f, -3.358f, -4.062f, -5.036f, -6.103f, -7.242f, - -8.520f,-10.059f,-11.576f,-13.423f,-14.698f,-15.821f,-17.112f,-18.418f,-19.735f,-20.967f, --22.163f,-23.507f,-24.611f,-25.903f,-27.200f,-28.604f,-29.916f,-31.217f,-32.155f,-33.249f, --34.305f,-35.367f,-36.429f,-36.935f,-37.417f,-37.837f,-38.284f,-38.590f,-39.055f,-39.250f, --39.651f,-39.998f,-40.099f,-40.164f,-40.513f,-39.311f,-37.186f,-37.388f,-35.111f,-36.666f, --35.438f,-34.382f,-32.646f,-31.894f,-30.193f,-26.831f,-24.706f,-23.192f,-21.271f,-20.497f, --18.692f,-17.349f,-14.739f,-12.971f,-11.183f,-11.080f,-12.018f,-12.718f,-12.981f,-14.471f, --16.874f,-17.504f,-19.459f,-20.773f,-21.657f,-21.762f,-22.504f,-23.237f,-24.472f,-26.877f, --28.055f,-29.239f,-28.653f,-27.362f,-25.288f,-23.587f,-22.558f,-23.414f,-25.166f,-20.928f, --19.184f,-17.635f,-18.149f,-17.311f,-15.479f,-11.798f, -8.438f, -7.597f, -2.982f, -0.283f, - 4.489f, 3.067f, 4.157f, 7.406f, 10.912f, 13.564f, 14.633f, 15.114f, 13.677f, 14.205f, - 13.606f -},{ --29.534f,-30.526f,-28.799f,-29.345f,-32.447f,-34.555f,-34.890f,-33.929f,-34.169f,-36.113f, --38.204f,-35.503f,-34.276f,-35.022f,-31.506f,-31.186f,-32.231f,-33.473f,-31.999f,-34.492f, --33.642f,-32.957f,-31.459f,-30.621f,-29.832f,-28.904f,-27.645f,-26.315f,-25.410f,-24.204f, --22.768f,-22.129f,-19.340f,-16.694f,-14.464f,-13.448f,-12.191f,-11.687f,-11.345f,-10.716f, --10.408f, -9.624f, -9.555f, -9.474f, -9.564f, -9.763f, -9.947f,-10.120f,-10.337f,-10.570f, --10.727f,-10.702f,-10.469f,-10.373f,-10.512f,-10.442f,-10.156f, -9.661f, -9.238f, -8.877f, - -8.358f, -7.759f, -6.763f, -5.767f, -5.175f, -4.610f, -4.184f, -3.765f, -3.228f, -2.682f, - -2.238f, -2.009f, -2.049f, -2.264f, -2.701f, -3.288f, -3.923f, -4.884f, -5.880f, -7.047f, - -8.304f, -9.670f,-11.117f,-12.607f,-14.144f,-15.534f,-16.669f,-17.943f,-19.267f,-20.510f, --21.686f,-22.925f,-23.929f,-25.205f,-26.558f,-27.746f,-28.978f,-30.048f,-30.906f,-31.918f, --32.741f,-33.679f,-34.585f,-35.314f,-35.884f,-35.977f,-36.471f,-36.638f,-36.980f,-37.262f, --37.646f,-38.073f,-38.166f,-38.650f,-36.864f,-36.638f,-36.266f,-35.725f,-35.914f,-34.543f, --32.916f,-32.218f,-31.158f,-30.714f,-28.836f,-24.669f,-23.479f,-22.638f,-18.959f,-18.290f, --17.721f,-16.912f,-14.530f,-11.866f,-10.896f, -9.422f,-11.668f,-12.827f,-13.982f,-14.551f, --17.534f,-18.714f,-19.682f,-21.785f,-22.915f,-23.365f,-23.670f,-25.098f,-26.290f,-28.679f, --29.440f,-30.099f,-29.475f,-28.429f,-27.000f,-25.140f,-23.878f,-24.683f,-26.392f,-21.645f, --20.370f,-18.877f,-19.282f,-18.391f,-15.941f,-12.109f, -9.205f, -7.779f, -3.131f, -0.742f, - 4.679f, 3.674f, 4.419f, 7.597f, 11.095f, 13.637f, 14.710f, 15.113f, 13.704f, 14.245f, - 13.606f -},{ --29.534f,-30.516f,-28.761f,-29.363f,-32.444f,-34.313f,-34.375f,-33.175f,-33.730f,-35.758f, --37.790f,-35.090f,-33.883f,-34.773f,-31.987f,-30.342f,-31.305f,-33.010f,-31.529f,-34.013f, --33.163f,-32.408f,-31.162f,-29.801f,-29.049f,-28.292f,-27.164f,-25.992f,-25.168f,-24.026f, --22.655f,-21.402f,-19.256f,-16.402f,-14.379f,-13.393f,-12.376f,-11.683f,-11.535f,-10.930f, --10.563f, -9.795f, -9.604f, -9.533f, -9.637f, -9.751f, -9.889f, -9.971f,-10.127f,-10.275f, --10.484f,-10.370f,-10.035f,-10.003f,-10.135f,-10.147f,-10.082f, -9.593f, -8.963f, -8.633f, - -8.062f, -7.358f, -6.442f, -5.419f, -4.975f, -4.651f, -4.216f, -3.732f, -3.120f, -2.619f, - -2.245f, -2.034f, -2.051f, -2.282f, -2.773f, -3.296f, -3.969f, -4.749f, -5.701f, -6.893f, - -8.052f, -9.388f,-10.844f,-12.164f,-13.368f,-14.871f,-16.357f,-17.545f,-18.840f,-19.966f, --21.099f,-22.152f,-23.150f,-24.475f,-25.641f,-26.715f,-27.767f,-28.605f,-29.454f,-30.115f, --31.049f,-31.774f,-32.868f,-33.299f,-33.708f,-33.871f,-34.476f,-34.818f,-35.127f,-34.968f, --35.724f,-36.139f,-36.568f,-36.529f,-35.354f,-34.142f,-35.306f,-35.627f,-33.864f,-32.755f, --31.498f,-30.344f,-29.662f,-29.135f,-26.387f,-24.286f,-23.496f,-23.044f,-20.545f,-17.789f, --16.281f,-13.973f,-13.594f,-10.674f, -9.262f, -8.557f,-11.244f,-11.543f,-14.267f,-15.125f, --17.352f,-18.799f,-20.001f,-21.919f,-23.481f,-24.408f,-25.255f,-26.358f,-28.239f,-29.928f, --30.362f,-30.959f,-30.378f,-29.080f,-28.177f,-26.480f,-25.209f,-26.011f,-27.907f,-23.400f, --22.347f,-21.034f,-20.276f,-19.249f,-16.404f,-12.557f, -9.859f, -7.923f, -3.464f, -1.070f, - 4.522f, 4.266f, 4.672f, 7.802f, 11.289f, 13.706f, 14.779f, 15.103f, 13.735f, 14.286f, - 13.606f -},{ --29.534f,-30.504f,-28.728f,-29.348f,-32.255f,-33.850f,-33.747f,-32.452f,-33.336f,-35.265f, --37.180f,-34.633f,-33.840f,-34.715f,-32.377f,-29.751f,-30.622f,-32.376f,-31.137f,-32.950f, --32.843f,-31.985f,-30.474f,-29.117f,-28.399f,-27.648f,-26.667f,-25.707f,-24.872f,-23.637f, --22.560f,-20.448f,-18.716f,-16.130f,-14.479f,-13.480f,-12.395f,-11.766f,-11.701f,-10.858f, --10.620f, -9.936f, -9.753f, -9.583f, -9.561f, -9.692f, -9.768f, -9.939f,-10.056f,-10.287f, --10.317f,-10.280f, -9.995f, -9.866f, -9.884f, -9.809f, -9.511f, -9.336f, -8.894f, -8.438f, - -7.859f, -6.943f, -6.022f, -5.243f, -4.840f, -4.597f, -4.102f, -3.661f, -3.088f, -2.667f, - -2.311f, -2.184f, -2.201f, -2.409f, -2.848f, -3.339f, -4.035f, -4.737f, -5.705f, -6.768f, - -7.832f, -9.180f,-10.525f,-11.817f,-13.067f,-14.297f,-15.893f,-17.111f,-18.397f,-19.485f, --20.424f,-21.439f,-22.526f,-23.551f,-24.654f,-25.532f,-26.222f,-27.082f,-28.094f,-28.574f, --29.057f,-30.188f,-30.840f,-31.485f,-32.024f,-32.351f,-32.815f,-33.024f,-33.349f,-33.674f, --33.938f,-34.202f,-34.610f,-33.071f,-32.610f,-35.104f,-34.535f,-33.150f,-31.789f,-31.051f, --29.825f,-28.380f,-28.153f,-27.515f,-24.322f,-24.452f,-21.204f,-21.541f,-19.780f,-20.195f, --18.435f,-12.887f,-14.279f,-10.103f, -7.904f, -7.482f,-11.122f,-11.879f,-14.565f,-16.155f, --17.374f,-19.052f,-19.551f,-22.040f,-24.009f,-25.146f,-27.033f,-27.649f,-29.170f,-31.059f, --31.046f,-31.667f,-31.316f,-29.993f,-29.015f,-27.900f,-26.769f,-27.586f,-29.326f,-26.025f, --24.836f,-23.116f,-20.819f,-19.800f,-16.627f,-13.096f,-10.041f, -8.003f, -3.961f, -1.258f, - 4.132f, 4.800f, 4.894f, 8.015f, 11.503f, 13.781f, 14.839f, 15.087f, 13.773f, 14.327f, - 13.606f -},{ --29.534f,-30.491f,-28.700f,-29.297f,-31.889f,-33.203f,-33.053f,-31.776f,-32.975f,-34.606f, --36.403f,-34.300f,-34.017f,-34.701f,-32.078f,-29.261f,-30.211f,-31.817f,-30.615f,-32.152f, --32.666f,-31.496f,-30.111f,-28.665f,-27.698f,-27.020f,-26.168f,-25.290f,-24.429f,-22.984f, --22.274f,-19.578f,-18.463f,-16.044f,-14.515f,-13.447f,-12.425f,-11.920f,-11.613f,-10.803f, --10.688f,-10.049f, -9.948f, -9.549f, -9.523f, -9.671f, -9.712f, -9.802f, -9.945f,-10.127f, --10.267f,-10.112f, -9.855f, -9.839f, -9.735f, -9.588f, -9.131f, -9.068f, -8.724f, -8.220f, - -7.563f, -6.695f, -5.919f, -4.978f, -4.709f, -4.454f, -4.066f, -3.553f, -3.039f, -2.770f, - -2.525f, -2.405f, -2.359f, -2.580f, -3.060f, -3.389f, -4.183f, -4.882f, -5.890f, -6.894f, - -7.981f, -9.160f,-10.405f,-11.650f,-12.873f,-14.028f,-15.549f,-16.830f,-17.893f,-18.921f, --19.809f,-20.652f,-21.779f,-22.718f,-23.649f,-24.343f,-24.997f,-25.679f,-26.555f,-26.935f, --26.935f,-28.393f,-28.957f,-29.701f,-29.830f,-30.569f,-30.638f,-31.449f,-31.666f,-31.692f, --32.142f,-32.234f,-32.555f,-32.913f,-33.243f,-32.632f,-31.417f,-30.578f,-29.142f,-28.589f, --27.914f,-27.405f,-26.793f,-26.000f,-23.169f,-23.080f,-20.373f,-21.308f,-19.390f,-17.917f, --16.662f,-14.122f,-13.550f,-10.136f, -9.767f,-11.822f,-12.677f,-12.451f,-14.663f,-16.312f, --17.322f,-19.620f,-20.016f,-22.022f,-24.617f,-26.025f,-28.251f,-29.041f,-30.096f,-32.177f, --31.838f,-32.281f,-32.401f,-30.993f,-30.171f,-29.337f,-28.654f,-29.505f,-30.356f,-28.424f, --26.921f,-24.263f,-21.294f,-20.089f,-16.799f,-13.603f, -9.865f, -7.944f, -4.393f, -1.351f, - 3.657f, 5.261f, 5.097f, 8.226f, 11.737f, 13.870f, 14.893f, 15.069f, 13.819f, 14.369f, - 13.606f -},{ --29.534f,-30.476f,-28.675f,-29.211f,-31.375f,-32.437f,-32.357f,-31.152f,-32.607f,-33.832f, --35.491f,-34.138f,-34.179f,-34.412f,-31.190f,-28.628f,-29.841f,-31.361f,-30.249f,-31.771f, --32.476f,-31.018f,-29.813f,-28.505f,-27.113f,-26.429f,-25.711f,-24.856f,-23.833f,-22.303f, --21.497f,-19.382f,-17.994f,-15.814f,-14.448f,-13.425f,-12.559f,-12.102f,-11.544f,-10.876f, --10.741f,-10.100f, -9.866f, -9.662f, -9.474f, -9.399f, -9.405f, -9.499f, -9.809f, -9.855f, --10.040f,-10.033f, -9.852f, -9.864f, -9.595f, -9.437f, -8.913f, -8.780f, -8.454f, -7.961f, - -7.290f, -6.439f, -5.563f, -4.771f, -4.559f, -4.244f, -3.911f, -3.610f, -3.200f, -2.815f, - -2.742f, -2.583f, -2.662f, -2.694f, -3.204f, -3.578f, -4.326f, -5.117f, -6.087f, -7.130f, - -8.167f, -9.231f,-10.256f,-11.545f,-12.771f,-13.846f,-15.294f,-16.414f,-17.488f,-18.385f, --19.172f,-20.223f,-20.973f,-21.824f,-22.543f,-23.244f,-23.801f,-24.541f,-25.030f,-25.100f, --25.504f,-26.356f,-26.965f,-27.528f,-27.771f,-28.615f,-29.218f,-29.587f,-29.890f,-30.316f, --30.325f,-30.571f,-31.033f,-31.116f,-30.387f,-29.789f,-28.713f,-27.151f,-24.948f,-24.921f, --25.061f,-25.780f,-25.647f,-23.853f,-22.340f,-20.846f,-21.433f,-20.511f,-16.768f,-16.628f, --15.633f,-15.563f,-14.352f,-13.595f,-12.816f,-11.195f,-13.909f,-14.184f,-15.929f,-16.665f, --17.412f,-19.969f,-20.646f,-22.334f,-25.077f,-26.968f,-28.957f,-29.458f,-30.518f,-32.925f, --32.631f,-33.051f,-33.514f,-32.429f,-32.087f,-31.311f,-30.340f,-31.333f,-31.172f,-29.823f, --27.923f,-24.578f,-21.824f,-20.092f,-17.020f,-13.940f, -9.732f, -7.678f, -4.527f, -1.362f, - 3.184f, 5.642f, 5.313f, 8.421f, 11.981f, 13.977f, 14.944f, 15.053f, 13.875f, 14.412f, - 13.606f -},{ --29.534f,-30.460f,-28.654f,-29.091f,-30.763f,-31.629f,-31.720f,-30.581f,-32.190f,-33.063f, --34.490f,-33.991f,-34.173f,-33.728f,-30.236f,-27.883f,-29.189f,-30.563f,-29.985f,-30.367f, --31.952f,-30.635f,-29.385f,-28.233f,-26.762f,-25.976f,-25.269f,-24.223f,-23.307f,-21.738f, --20.663f,-19.552f,-17.368f,-15.593f,-14.356f,-13.343f,-12.570f,-12.081f,-11.413f,-11.010f, --10.615f,-10.260f, -9.780f, -9.441f, -9.284f, -9.081f, -9.119f, -9.295f, -9.412f, -9.605f, - -9.758f, -9.705f, -9.678f, -9.537f, -9.164f, -9.262f, -8.588f, -8.345f, -8.054f, -7.591f, - -7.063f, -6.141f, -5.312f, -4.528f, -4.106f, -3.871f, -3.855f, -3.575f, -3.266f, -3.052f, - -2.907f, -2.754f, -2.876f, -3.103f, -3.327f, -3.946f, -4.669f, -5.416f, -6.397f, -7.426f, - -8.447f, -9.360f,-10.405f,-11.477f,-12.522f,-13.693f,-14.985f,-16.136f,-17.065f,-17.904f, --18.719f,-19.390f,-20.051f,-20.796f,-21.425f,-22.067f,-22.613f,-23.134f,-23.392f,-23.466f, --23.916f,-24.194f,-24.832f,-25.251f,-25.459f,-26.013f,-26.494f,-26.949f,-27.634f,-27.994f, --29.049f,-30.165f,-29.030f,-28.493f,-27.386f,-26.463f,-24.374f,-23.668f,-23.528f,-23.793f, --25.147f,-25.529f,-24.928f,-23.945f,-22.867f,-22.109f,-20.048f,-18.577f,-15.116f,-14.447f, --13.011f,-11.549f,-13.445f,-12.496f,-10.207f,-13.699f,-14.745f,-14.644f,-16.236f,-16.977f, --18.851f,-20.971f,-21.550f,-23.324f,-25.902f,-27.670f,-29.095f,-29.808f,-31.628f,-33.303f, --33.966f,-33.982f,-34.307f,-33.828f,-33.627f,-33.250f,-31.737f,-32.212f,-31.693f,-30.393f, --28.025f,-24.637f,-21.916f,-19.892f,-17.107f,-14.051f, -9.817f, -7.213f, -4.349f, -1.227f, - 2.718f, 5.922f, 5.587f, 8.589f, 12.219f, 14.103f, 14.995f, 15.041f, 13.940f, 14.455f, - 13.606f -},{ --29.534f,-30.442f,-28.637f,-28.944f,-30.112f,-30.860f,-31.190f,-30.075f,-31.707f,-32.424f, --33.470f,-33.618f,-33.915f,-32.883f,-29.549f,-27.234f,-28.424f,-29.337f,-29.234f,-28.127f, --31.243f,-30.174f,-29.016f,-27.622f,-26.254f,-25.517f,-24.735f,-23.745f,-22.794f,-21.448f, --20.136f,-18.981f,-17.010f,-15.574f,-14.374f,-13.314f,-12.410f,-11.856f,-11.149f,-11.107f, --10.441f,-10.212f, -9.635f, -9.317f, -9.008f, -8.873f, -9.022f, -8.960f, -9.175f, -9.185f, - -9.368f, -9.502f, -9.453f, -9.109f, -8.942f, -8.787f, -8.280f, -7.989f, -7.820f, -7.215f, - -6.716f, -5.892f, -4.938f, -3.984f, -3.725f, -3.489f, -3.616f, -3.500f, -3.181f, -3.075f, - -3.047f, -2.972f, -3.213f, -3.441f, -3.573f, -4.504f, -5.080f, -6.031f, -6.858f, -7.861f, - -8.879f, -9.700f,-10.627f,-11.676f,-12.613f,-13.530f,-14.729f,-15.843f,-16.662f,-17.468f, --18.191f,-18.601f,-19.079f,-19.541f,-20.272f,-20.759f,-21.198f,-21.616f,-21.809f,-21.686f, --22.078f,-22.106f,-22.455f,-22.794f,-23.176f,-23.479f,-23.556f,-24.047f,-24.737f,-27.938f, --29.377f,-27.966f,-25.320f,-25.251f,-22.359f,-21.864f,-21.477f,-23.130f,-23.857f,-24.518f, --24.540f,-24.484f,-24.176f,-22.316f,-21.062f,-19.937f,-18.862f,-17.033f,-16.198f,-13.719f, --12.278f,-10.703f,-11.795f,-13.632f,-14.641f,-14.833f,-15.858f,-15.835f,-16.733f,-17.176f, --19.427f,-21.045f,-21.880f,-23.649f,-25.772f,-28.199f,-29.131f,-29.886f,-32.336f,-33.960f, --35.114f,-35.235f,-35.338f,-34.678f,-34.121f,-33.864f,-32.899f,-32.754f,-32.304f,-30.797f, --27.993f,-24.720f,-21.769f,-19.966f,-17.042f,-13.995f, -9.908f, -6.719f, -4.062f, -0.857f, - 2.241f, 6.066f, 5.950f, 8.728f, 12.434f, 14.245f, 15.050f, 15.036f, 14.018f, 14.499f, - 13.606f -},{ --29.534f,-30.422f,-28.622f,-28.781f,-29.480f,-30.191f,-30.783f,-29.660f,-31.184f,-31.963f, --32.518f,-32.912f,-33.349f,-32.172f,-29.041f,-26.764f,-27.995f,-28.181f,-28.042f,-27.042f, --30.667f,-29.486f,-28.491f,-27.153f,-25.900f,-25.091f,-24.221f,-23.288f,-22.249f,-21.331f, --19.893f,-18.127f,-16.893f,-15.262f,-14.154f,-13.051f,-11.961f,-11.768f,-11.332f,-10.873f, --10.362f,-10.106f, -9.476f, -9.155f, -8.847f, -8.530f, -8.820f, -8.701f, -8.934f, -8.758f, - -8.948f, -9.065f, -9.077f, -8.775f, -8.317f, -8.153f, -7.874f, -7.546f, -7.466f, -6.877f, - -6.340f, -5.689f, -4.583f, -3.609f, -3.353f, -3.140f, -3.226f, -3.284f, -3.087f, -3.118f, - -3.197f, -3.302f, -3.475f, -3.452f, -4.580f, -5.069f, -5.632f, -6.539f, -7.615f, -8.525f, - -9.369f,-10.184f,-10.935f,-11.965f,-12.884f,-13.636f,-14.563f,-15.559f,-16.326f,-16.988f, --17.555f,-17.942f,-18.231f,-18.670f,-19.155f,-19.428f,-19.673f,-19.856f,-20.043f,-19.926f, --20.050f,-20.093f,-20.282f,-20.487f,-20.820f,-21.005f,-21.217f,-21.824f,-22.910f,-24.708f, --20.856f,-21.793f,-22.394f,-20.852f,-19.306f,-20.632f,-21.049f,-22.164f,-23.314f,-23.777f, --24.008f,-23.908f,-23.456f,-22.441f,-22.942f,-21.938f,-18.673f,-17.291f,-17.370f,-15.962f, --17.207f,-15.133f,-13.697f,-15.003f,-14.572f,-14.621f,-15.852f,-16.314f,-17.242f,-17.811f, --19.333f,-20.893f,-22.298f,-24.486f,-26.265f,-28.848f,-29.732f,-31.051f,-32.721f,-34.799f, --35.865f,-36.937f,-36.738f,-36.202f,-35.067f,-34.444f,-34.183f,-33.766f,-33.052f,-31.272f, --28.302f,-24.948f,-22.231f,-20.472f,-16.942f,-13.827f, -9.739f, -6.464f, -3.868f, -0.250f, - 1.796f, 6.058f, 6.422f, 8.853f, 12.614f, 14.398f, 15.112f, 15.040f, 14.106f, 14.544f, - 13.606f -},{ --29.534f,-30.401f,-28.609f,-28.613f,-28.923f,-29.660f,-30.488f,-29.372f,-30.679f,-31.607f, --31.696f,-32.017f,-32.539f,-31.633f,-28.498f,-26.427f,-27.770f,-27.159f,-26.951f,-26.959f, --30.041f,-28.689f,-28.031f,-26.939f,-25.488f,-24.538f,-23.802f,-22.844f,-21.794f,-20.803f, --19.535f,-17.233f,-16.115f,-14.606f,-13.657f,-12.625f,-11.924f,-11.597f,-10.988f,-10.629f, --10.231f, -9.725f, -9.359f, -8.945f, -8.635f, -8.368f, -8.322f, -8.424f, -8.589f, -8.476f, - -8.357f, -8.492f, -8.695f, -8.436f, -7.962f, -7.428f, -7.457f, -7.320f, -7.112f, -6.585f, - -6.025f, -5.345f, -4.425f, -3.421f, -2.948f, -2.921f, -3.070f, -3.200f, -3.129f, -3.239f, - -3.424f, -3.589f, -3.712f, -4.170f, -4.978f, -5.631f, -6.404f, -7.396f, -8.507f, -9.453f, --10.196f,-10.702f,-11.428f,-12.298f,-13.060f,-13.773f,-14.512f,-15.329f,-16.047f,-16.560f, --16.983f,-17.352f,-17.591f,-17.706f,-17.968f,-17.941f,-18.004f,-18.170f,-18.182f,-18.075f, --18.026f,-18.016f,-18.114f,-18.172f,-18.384f,-18.663f,-19.345f,-19.572f,-23.410f,-19.195f, --15.905f,-18.418f,-18.080f,-17.688f,-18.293f,-19.664f,-20.582f,-21.350f,-21.887f,-22.595f, --22.479f,-23.034f,-26.447f,-23.523f,-23.945f,-23.942f,-20.602f,-19.775f,-21.326f,-19.635f, --19.194f,-18.207f,-17.907f,-15.136f,-12.935f,-15.451f,-15.706f,-15.929f,-17.670f,-18.618f, --19.600f,-21.153f,-22.939f,-25.128f,-27.277f,-29.489f,-30.657f,-32.277f,-33.749f,-35.279f, --37.152f,-38.416f,-38.447f,-37.955f,-37.035f,-35.819f,-35.511f,-34.699f,-33.462f,-31.525f, --28.727f,-25.443f,-23.070f,-20.643f,-16.694f,-13.517f, -9.303f, -6.565f, -3.808f, 0.425f, - 1.508f, 5.930f, 7.001f, 8.998f, 12.757f, 14.555f, 15.182f, 15.053f, 14.206f, 14.589f, - 13.606f -},{ --29.534f,-30.378f,-28.597f,-28.450f,-28.480f,-29.270f,-30.268f,-29.235f,-30.262f,-31.204f, --30.985f,-31.194f,-31.753f,-31.105f,-27.912f,-26.183f,-27.201f,-25.948f,-25.965f,-26.069f, --29.253f,-28.081f,-27.597f,-26.766f,-25.090f,-23.995f,-23.190f,-22.473f,-21.273f,-20.129f, --18.908f,-16.624f,-15.508f,-13.816f,-12.988f,-12.180f,-11.843f,-11.157f,-10.606f,-10.299f, - -9.811f, -9.453f, -9.165f, -8.557f, -8.289f, -7.959f, -7.995f, -7.954f, -8.490f, -8.000f, - -7.980f, -7.897f, -8.262f, -7.954f, -7.565f, -6.986f, -7.062f, -6.982f, -6.824f, -6.244f, - -5.612f, -5.054f, -4.005f, -3.243f, -2.677f, -2.626f, -2.867f, -3.107f, -3.174f, -3.359f, - -3.597f, -3.964f, -4.175f, -4.473f, -5.145f, -6.044f, -7.067f, -8.006f, -9.162f,-10.098f, --11.168f,-11.642f,-12.092f,-12.702f,-13.335f,-13.890f,-14.455f,-15.090f,-15.639f,-16.075f, --16.465f,-16.620f,-16.783f,-16.742f,-16.784f,-16.680f,-16.590f,-16.449f,-16.310f,-16.416f, --16.393f,-16.024f,-15.920f,-15.906f,-16.109f,-16.751f,-17.241f,-20.007f,-18.330f,-15.972f, --14.311f,-15.055f,-15.201f,-15.591f,-16.768f,-18.539f,-20.293f,-20.262f,-21.209f,-22.299f, --22.693f,-24.397f,-24.084f,-22.494f,-24.025f,-24.900f,-24.016f,-22.837f,-23.212f,-22.202f, --21.011f,-19.650f,-18.833f,-17.603f,-16.704f,-17.159f,-16.486f,-16.895f,-17.766f,-18.751f, --20.026f,-22.232f,-23.963f,-26.425f,-29.191f,-30.547f,-31.326f,-33.015f,-34.869f,-36.286f, --38.846f,-39.423f,-40.248f,-39.343f,-38.903f,-37.102f,-36.375f,-35.542f,-34.025f,-31.355f, --28.738f,-25.878f,-23.178f,-19.883f,-16.185f,-13.056f, -8.774f, -6.823f, -3.808f, 0.896f, - 1.516f, 5.773f, 7.672f, 9.200f, 12.872f, 14.712f, 15.261f, 15.076f, 14.316f, 14.634f, - 13.606f -},{ --29.534f,-30.354f,-28.586f,-28.306f,-28.174f,-28.999f,-30.073f,-29.247f,-29.981f,-30.620f, --30.270f,-30.553f,-31.266f,-30.504f,-27.402f,-25.966f,-26.269f,-24.939f,-24.844f,-24.605f, --28.238f,-27.613f,-26.939f,-26.346f,-24.794f,-23.601f,-22.871f,-21.926f,-20.886f,-19.559f, --18.373f,-16.226f,-14.846f,-13.376f,-12.343f,-11.815f,-11.658f,-10.838f,-10.036f,-10.109f, - -9.365f, -9.238f, -8.806f, -8.111f, -7.870f, -7.425f, -7.467f, -7.663f, -8.170f, -7.825f, - -7.723f, -7.669f, -7.775f, -7.178f, -7.211f, -6.454f, -6.736f, -6.605f, -6.472f, -5.927f, - -5.231f, -4.631f, -3.973f, -2.992f, -2.046f, -2.329f, -2.639f, -2.949f, -3.104f, -3.433f, - -3.901f, -4.135f, -4.564f, -4.881f, -5.406f, -6.494f, -7.509f, -8.522f, -9.370f,-10.484f, --11.440f,-12.158f,-12.911f,-13.086f,-13.727f,-14.083f,-14.443f,-14.868f,-15.216f,-15.503f, --15.729f,-15.842f,-15.850f,-15.701f,-15.515f,-15.261f,-15.041f,-14.800f,-14.672f,-14.847f, --14.675f,-14.133f,-13.886f,-13.873f,-14.463f,-14.763f,-15.399f,-19.008f,-14.294f,-12.968f, --11.836f,-12.608f,-13.383f,-14.352f,-15.427f,-16.343f,-17.936f,-20.255f,-21.017f,-21.789f, --23.968f,-24.501f,-25.723f,-24.935f,-26.177f,-26.757f,-27.098f,-25.634f,-24.613f,-23.959f, --22.958f,-20.907f,-19.005f,-18.734f,-19.772f,-19.522f,-19.065f,-18.729f,-18.327f,-20.026f, --21.447f,-23.045f,-24.340f,-27.388f,-29.966f,-31.153f,-32.145f,-33.662f,-35.755f,-37.993f, --40.292f,-40.796f,-41.514f,-40.867f,-40.242f,-38.283f,-36.989f,-36.342f,-34.869f,-31.052f, --28.210f,-25.716f,-22.388f,-18.717f,-15.571f,-12.482f, -8.261f, -6.907f, -3.832f, 0.974f, - 1.878f, 5.698f, 8.399f, 9.485f, 12.975f, 14.866f, 15.348f, 15.107f, 14.437f, 14.680f, - 13.606f -},{ --29.534f,-30.327f,-28.574f,-28.189f,-28.010f,-28.803f,-29.860f,-29.374f,-29.841f,-29.837f, --29.415f,-29.946f,-31.035f,-29.890f,-26.953f,-25.643f,-25.347f,-24.595f,-23.753f,-23.901f, --26.922f,-26.813f,-26.421f,-25.648f,-24.228f,-23.162f,-22.580f,-21.494f,-20.532f,-18.827f, --17.612f,-15.880f,-14.536f,-12.984f,-12.097f,-11.456f,-11.057f,-10.163f, -9.839f, -9.780f, - -9.144f, -8.814f, -8.236f, -7.492f, -7.319f, -6.958f, -6.835f, -7.506f, -7.628f, -7.668f, - -7.437f, -7.422f, -7.300f, -6.712f, -6.639f, -6.169f, -6.326f, -6.305f, -6.199f, -5.633f, - -4.925f, -4.214f, -3.400f, -2.618f, -1.855f, -2.075f, -2.375f, -2.823f, -3.089f, -3.277f, - -3.920f, -4.430f, -5.035f, -5.490f, -5.601f, -6.792f, -7.672f, -8.685f, -9.572f,-10.568f, --11.762f,-12.284f,-13.151f,-13.190f,-13.813f,-14.046f,-14.441f,-14.551f,-14.720f,-14.877f, --14.970f,-15.031f,-14.891f,-14.624f,-14.213f,-13.862f,-13.562f,-13.250f,-13.043f,-13.110f, --13.007f,-12.531f,-12.124f,-12.184f,-12.511f,-12.885f,-14.560f,-14.297f, -8.504f,-10.749f, - -9.508f,-11.052f,-12.173f,-13.203f,-14.209f,-14.750f,-18.739f,-21.072f,-22.965f,-23.639f, --23.947f,-24.482f,-26.156f,-27.310f,-28.169f,-27.821f,-28.356f,-27.567f,-25.876f,-25.242f, --24.249f,-22.431f,-20.851f,-21.115f,-23.184f,-21.604f,-20.769f,-20.899f,-20.637f,-21.493f, --22.991f,-24.544f,-26.815f,-28.034f,-30.458f,-31.970f,-33.354f,-34.680f,-36.573f,-39.504f, --41.093f,-41.730f,-42.415f,-42.331f,-41.730f,-39.447f,-37.612f,-36.560f,-35.316f,-31.161f, --27.658f,-25.017f,-21.327f,-17.715f,-14.870f,-11.739f, -7.734f, -6.699f, -3.886f, 0.735f, - 2.512f, 5.788f, 9.129f, 9.858f, 13.084f, 15.016f, 15.443f, 15.144f, 14.567f, 14.726f, - 13.606f -},{ --29.534f,-30.299f,-28.561f,-28.108f,-27.973f,-28.630f,-29.602f,-29.554f,-29.800f,-28.976f, --28.371f,-29.158f,-30.679f,-29.264f,-26.425f,-25.162f,-24.388f,-24.208f,-22.978f,-23.688f, --26.098f,-25.942f,-25.742f,-25.090f,-23.836f,-22.834f,-21.967f,-20.972f,-19.988f,-18.374f, --16.932f,-15.633f,-14.134f,-12.594f,-11.949f,-11.119f,-10.303f, -9.819f, -9.518f, -8.967f, - -8.583f, -8.125f, -7.718f, -7.243f, -6.454f, -6.642f, -6.348f, -7.111f, -7.388f, -7.439f, - -7.116f, -6.938f, -6.895f, -6.181f, -6.183f, -6.059f, -6.030f, -6.104f, -5.831f, -5.249f, - -4.449f, -3.885f, -3.160f, -2.324f, -1.979f, -1.589f, -1.896f, -2.429f, -2.924f, -3.381f, - -4.009f, -4.517f, -5.178f, -5.682f, -5.888f, -6.593f, -7.743f, -8.892f, -9.734f,-10.702f, --11.961f,-12.591f,-13.122f,-13.357f,-13.822f,-14.278f,-14.309f,-14.286f,-14.300f,-14.303f, --14.238f,-14.277f,-13.753f,-13.506f,-13.016f,-12.549f,-12.197f,-11.831f,-11.568f,-11.514f, --11.611f,-11.241f,-10.407f,-10.514f,-10.658f,-11.061f,-14.293f, -8.485f, -7.010f, -6.591f, - -7.020f,-10.317f,-12.421f,-13.217f,-13.160f,-16.250f,-19.984f,-21.983f,-24.404f,-23.903f, --23.141f,-24.099f,-26.960f,-30.097f,-29.451f,-28.250f,-29.397f,-28.210f,-26.605f,-26.227f, --25.052f,-23.289f,-22.296f,-23.714f,-24.917f,-22.541f,-22.183f,-22.090f,-21.999f,-21.522f, --23.789f,-26.567f,-30.026f,-29.758f,-30.927f,-32.798f,-34.448f,-36.138f,-38.130f,-40.677f, --42.152f,-42.800f,-43.070f,-43.434f,-42.936f,-40.302f,-38.258f,-36.629f,-35.446f,-31.611f, --27.524f,-24.172f,-20.141f,-16.653f,-13.895f,-10.768f, -7.165f, -6.348f, -3.885f, 0.492f, - 3.250f, 6.065f, 9.791f, 10.292f, 13.212f, 15.163f, 15.541f, 15.188f, 14.704f, 14.773f, - 13.606f -},{ --29.534f,-30.270f,-28.545f,-28.067f,-28.038f,-28.432f,-29.301f,-29.717f,-29.787f,-28.225f, --27.251f,-28.184f,-29.896f,-28.490f,-25.780f,-24.594f,-23.168f,-23.200f,-22.525f,-23.122f, --26.254f,-25.626f,-24.863f,-24.623f,-23.336f,-22.285f,-21.369f,-20.179f,-19.486f,-18.013f, --16.344f,-15.106f,-13.686f,-12.266f,-11.473f, -9.786f, -9.775f, -9.469f, -9.094f, -8.202f, - -8.049f, -7.357f, -7.322f, -6.826f, -5.720f, -6.159f, -5.784f, -6.298f, -7.402f, -6.632f, - -6.468f, -6.376f, -5.966f, -5.512f, -5.709f, -5.786f, -5.804f, -5.848f, -5.593f, -4.939f, - -4.129f, -3.470f, -2.874f, -2.128f, -1.704f, -1.215f, -1.518f, -2.147f, -2.695f, -3.281f, - -3.981f, -4.772f, -5.298f, -5.912f, -6.046f, -6.732f, -7.602f, -8.844f, -9.905f,-10.898f, --11.968f,-12.571f,-13.129f,-13.388f,-13.780f,-14.086f,-14.132f,-14.075f,-13.916f,-13.668f, --13.482f,-13.417f,-12.809f,-12.434f,-11.849f,-11.378f,-10.957f,-10.483f,-10.320f,-10.366f, --10.231f, -9.980f, -9.195f, -8.900f, -8.926f, -9.589f,-11.996f, -4.809f, -5.691f, -5.209f, - -5.961f,-10.042f,-14.440f,-15.582f,-17.905f,-19.374f,-23.432f,-25.285f,-26.300f,-25.430f, --23.544f,-24.625f,-28.051f,-30.402f,-29.624f,-27.015f,-28.748f,-29.011f,-27.084f,-26.643f, --26.179f,-24.484f,-23.694f,-25.776f,-25.330f,-23.958f,-23.617f,-23.716f,-23.735f,-23.290f, --24.956f,-28.447f,-30.901f,-31.546f,-32.017f,-34.070f,-35.159f,-37.836f,-39.821f,-41.855f, --42.899f,-43.942f,-43.972f,-44.341f,-43.711f,-40.841f,-38.844f,-36.819f,-35.343f,-31.801f, --27.621f,-23.354f,-18.930f,-15.538f,-12.891f, -9.762f, -6.625f, -5.945f, -3.598f, 0.548f, - 3.947f, 6.495f, 10.319f, 10.743f, 13.362f, 15.309f, 15.641f, 15.234f, 14.847f, 14.819f, - 13.606f -},{ --29.534f,-30.238f,-28.526f,-28.067f,-28.168f,-28.177f,-28.978f,-29.807f,-29.730f,-27.720f, --26.262f,-27.245f,-28.828f,-27.497f,-25.151f,-23.938f,-21.913f,-22.446f,-22.066f,-22.351f, --26.642f,-25.296f,-24.412f,-24.034f,-22.726f,-21.938f,-20.636f,-19.503f,-18.763f,-17.349f, --15.896f,-14.434f,-13.289f,-12.041f,-11.271f, -9.967f, -9.048f, -9.068f, -8.539f, -7.683f, - -7.527f, -6.880f, -6.851f, -6.060f, -5.662f, -5.503f, -5.438f, -5.492f, -6.222f, -4.958f, - -5.748f, -5.658f, -5.269f, -4.946f, -5.184f, -5.501f, -5.532f, -5.597f, -5.413f, -4.547f, - -3.767f, -3.180f, -2.460f, -1.740f, -1.267f, -0.938f, -1.373f, -2.079f, -2.555f, -3.174f, - -3.966f, -4.781f, -5.429f, -5.997f, -6.142f, -6.804f, -7.685f, -8.807f, -9.968f,-10.925f, --11.850f,-12.652f,-12.986f,-13.307f,-13.824f,-13.975f,-14.074f,-13.854f,-13.448f,-13.084f, --12.770f,-12.539f,-11.538f,-11.384f,-10.790f,-10.242f, -9.759f, -9.315f, -9.011f, -8.995f, - -9.018f, -8.780f, -8.458f, -7.629f, -7.555f, -9.416f, -7.707f, -3.399f, -4.101f, -4.246f, - -5.580f,-12.678f,-15.871f,-17.751f,-20.374f,-22.659f,-24.558f,-26.483f,-27.929f,-27.338f, --26.719f,-27.181f,-28.489f,-29.778f,-27.266f,-27.501f,-28.024f,-28.944f,-28.668f,-27.794f, --27.075f,-26.006f,-24.947f,-26.558f,-25.754f,-24.647f,-25.206f,-25.302f,-24.970f,-25.304f, --26.678f,-29.648f,-32.100f,-33.113f,-34.470f,-35.168f,-37.031f,-39.391f,-41.312f,-43.328f, --44.201f,-45.064f,-45.213f,-44.887f,-43.823f,-41.090f,-39.193f,-36.767f,-34.940f,-31.670f, --27.592f,-22.754f,-18.270f,-14.947f,-12.386f, -9.037f, -6.211f, -5.329f, -2.845f, 0.946f, - 4.587f, 7.030f, 10.679f, 11.167f, 13.531f, 15.454f, 15.739f, 15.284f, 14.994f, 14.866f, - 13.606f -},{ --29.534f,-30.205f,-28.503f,-28.105f,-28.327f,-27.853f,-28.672f,-29.797f,-29.585f,-27.452f, --25.552f,-26.493f,-27.841f,-26.444f,-24.632f,-23.102f,-20.884f,-22.468f,-21.369f,-21.806f, --27.045f,-24.813f,-23.809f,-23.112f,-22.021f,-21.305f,-20.021f,-18.899f,-17.817f,-16.608f, --15.367f,-13.961f,-12.796f,-11.625f,-10.557f, -9.708f, -8.842f, -8.372f, -8.150f, -7.557f, - -7.038f, -6.588f, -6.770f, -5.989f, -5.396f, -4.663f, -5.006f, -5.384f, -5.081f, -4.334f, - -4.638f, -4.661f, -4.492f, -4.387f, -4.836f, -4.861f, -5.245f, -5.072f, -4.942f, -4.267f, - -3.352f, -2.682f, -1.931f, -1.417f, -0.814f, -0.716f, -0.968f, -1.712f, -2.294f, -2.950f, - -3.860f, -4.597f, -5.404f, -5.901f, -6.283f, -6.781f, -7.763f, -8.780f, -9.896f,-10.916f, --11.760f,-12.571f,-13.003f,-13.430f,-13.861f,-14.021f,-13.834f,-13.507f,-13.019f,-12.539f, --12.028f,-11.693f,-10.440f,-10.454f, -9.683f, -9.195f, -8.642f, -8.149f, -7.602f, -7.519f, - -7.498f, -7.401f, -7.363f, -7.101f, -6.724f, -9.082f, -2.562f, -1.887f, -5.795f, -6.469f, - -9.682f,-15.379f,-19.342f,-21.552f,-23.399f,-22.297f,-22.696f,-25.323f,-28.144f,-28.885f, --27.726f,-27.298f,-27.723f,-27.674f,-26.717f,-26.993f,-28.966f,-29.679f,-29.796f,-29.588f, --27.863f,-27.177f,-25.399f,-26.161f,-26.159f,-25.391f,-26.288f,-26.380f,-27.178f,-27.070f, --28.456f,-30.547f,-32.731f,-34.039f,-35.882f,-37.053f,-38.359f,-40.655f,-42.590f,-44.810f, --45.593f,-46.482f,-46.299f,-45.287f,-43.206f,-41.155f,-38.983f,-36.638f,-34.598f,-31.522f, --27.306f,-22.232f,-18.119f,-14.731f,-12.213f, -8.569f, -5.923f, -4.348f, -1.777f, 1.454f, - 5.296f, 7.644f, 10.892f, 11.545f, 13.707f, 15.597f, 15.831f, 15.334f, 15.143f, 14.913f, - 13.606f -},{ --29.534f,-30.170f,-28.475f,-28.176f,-28.481f,-27.474f,-28.423f,-29.696f,-29.347f,-27.286f, --25.084f,-25.765f,-26.980f,-25.547f,-24.126f,-22.187f,-19.971f,-22.241f,-21.010f,-21.511f, --26.961f,-24.844f,-22.852f,-22.000f,-20.914f,-20.218f,-19.301f,-18.019f,-17.048f,-15.910f, --14.414f,-13.180f,-12.077f,-11.299f,-10.579f, -9.824f, -8.917f, -8.308f, -8.006f, -7.415f, - -6.802f, -6.615f, -6.432f, -5.646f, -4.803f, -4.036f, -4.325f, -4.902f, -4.918f, -3.832f, - -3.813f, -3.996f, -3.811f, -3.931f, -4.453f, -4.423f, -4.765f, -4.812f, -4.497f, -3.732f, - -2.914f, -2.180f, -1.403f, -0.842f, -0.484f, -0.382f, -0.696f, -1.346f, -2.004f, -2.777f, - -3.690f, -4.555f, -5.264f, -5.835f, -6.463f, -6.770f, -7.809f, -8.907f, -9.713f,-10.641f, --11.506f,-12.391f,-13.041f,-13.562f,-13.814f,-13.823f,-13.692f,-13.200f,-12.567f,-11.986f, --11.297f,-10.851f, -9.503f, -9.036f, -8.776f, -8.073f, -7.573f, -7.102f, -6.475f, -6.082f, - -5.877f, -6.002f, -6.128f, -5.929f, -6.172f, -9.198f, -3.420f, -6.489f,-12.111f,-12.995f, --15.108f,-19.087f,-23.682f,-25.783f,-28.108f,-27.310f,-27.050f,-27.982f,-27.242f,-28.275f, --28.729f,-27.709f,-26.727f,-26.530f,-28.649f,-30.050f,-29.635f,-30.117f,-31.547f,-31.601f, --30.247f,-28.132f,-28.201f,-27.205f,-26.595f,-26.696f,-26.759f,-26.984f,-27.290f,-28.057f, --29.196f,-31.114f,-32.691f,-34.349f,-36.750f,-38.757f,-39.719f,-41.925f,-44.007f,-46.379f, --46.765f,-47.628f,-47.166f,-45.396f,-42.814f,-40.852f,-38.174f,-36.242f,-34.265f,-31.381f, --26.710f,-21.124f,-17.656f,-14.005f,-11.700f, -8.050f, -5.644f, -3.239f, -0.859f, 1.841f, - 6.247f, 8.333f, 11.033f, 11.889f, 13.881f, 15.734f, 15.916f, 15.384f, 15.292f, 14.959f, - 13.606f -},{ --29.534f,-30.133f,-28.440f,-28.272f,-28.604f,-27.076f,-28.256f,-29.536f,-29.048f,-27.053f, --24.663f,-24.727f,-25.847f,-24.797f,-23.493f,-21.498f,-19.190f,-21.385f,-21.654f,-21.117f, --24.734f,-24.245f,-22.182f,-21.357f,-20.214f,-19.621f,-18.294f,-17.368f,-16.420f,-15.304f, --13.925f,-12.322f,-10.982f,-11.155f,-11.067f,-10.479f, -9.190f, -8.193f, -7.723f, -7.357f, - -6.676f, -6.263f, -5.693f, -5.008f, -3.964f, -3.681f, -3.999f, -4.199f, -4.246f, -3.269f, - -3.144f, -3.448f, -3.198f, -3.380f, -3.982f, -3.814f, -4.316f, -4.372f, -3.987f, -3.208f, - -2.478f, -1.704f, -0.873f, -0.240f, -0.061f, -0.098f, -0.253f, -0.877f, -1.566f, -2.312f, - -3.228f, -4.092f, -4.970f, -5.808f, -6.397f, -6.971f, -7.711f, -8.615f, -9.684f,-10.570f, --11.211f,-12.194f,-12.995f,-13.397f,-13.573f,-13.628f,-13.271f,-12.796f,-12.084f,-11.499f, --10.732f,-10.141f, -8.532f, -7.738f, -7.788f, -6.958f, -6.398f, -5.919f, -5.367f, -4.819f, - -4.633f, -4.620f, -4.646f, -4.899f, -6.304f,-10.170f, -7.602f, -8.646f,-11.410f,-13.345f, --19.200f,-22.105f,-25.630f,-28.832f,-31.337f,-32.330f,-32.572f,-31.050f,-28.021f,-27.429f, --28.543f,-28.275f,-27.529f,-27.744f,-29.585f,-32.353f,-29.862f,-30.645f,-32.308f,-32.851f, --32.077f,-30.262f,-29.094f,-29.010f,-27.722f,-27.304f,-26.861f,-27.658f,-28.285f,-29.399f, --29.994f,-31.575f,-32.776f,-35.284f,-37.706f,-39.796f,-41.022f,-43.092f,-45.173f,-47.777f, --47.859f,-48.272f,-47.833f,-45.358f,-42.183f,-40.193f,-37.292f,-35.204f,-33.767f,-31.092f, --25.898f,-19.674f,-16.816f,-12.748f,-10.850f, -7.441f, -5.223f, -2.519f, -0.503f, 2.160f, - 7.516f, 9.081f, 11.202f, 12.240f, 14.047f, 15.860f, 15.992f, 15.435f, 15.439f, 15.006f, - 13.606f -},{ --29.534f,-30.094f,-28.399f,-28.382f,-28.682f,-26.706f,-28.179f,-29.354f,-28.738f,-26.677f, --24.110f,-23.310f,-24.177f,-23.988f,-22.790f,-21.094f,-18.774f,-20.964f,-22.407f,-20.080f, --21.519f,-22.405f,-21.551f,-20.807f,-19.666f,-17.863f,-17.339f,-16.698f,-15.666f,-14.632f, --13.560f,-12.346f,-10.754f,-10.750f,-10.940f,-10.390f, -9.049f, -7.950f, -7.464f, -6.962f, - -6.262f, -5.759f, -5.028f, -4.524f, -3.600f, -3.451f, -3.579f, -3.514f, -3.560f, -2.691f, - -2.599f, -2.832f, -2.750f, -2.882f, -3.315f, -3.345f, -3.687f, -3.484f, -3.114f, -2.323f, - -1.630f, -0.942f, -0.439f, 0.041f, 0.134f, 0.318f, 0.132f, -0.623f, -1.140f, -1.880f, - -2.878f, -3.796f, -4.811f, -5.650f, -6.435f, -6.979f, -7.648f, -8.492f, -9.364f,-10.154f, --11.117f,-12.043f,-12.772f,-13.135f,-13.345f,-13.245f,-12.793f,-12.233f,-11.460f,-10.762f, - -9.966f, -8.863f, -7.355f, -6.617f, -6.606f, -5.947f, -5.257f, -4.627f, -4.128f, -3.486f, - -3.227f, -3.142f, -3.342f, -4.056f, -9.336f, -5.231f, -6.303f, -7.178f,-12.716f,-13.514f, --17.323f,-21.419f,-24.493f,-27.441f,-30.608f,-32.107f,-31.118f,-30.235f,-27.152f,-26.588f, --28.501f,-28.822f,-27.055f,-27.648f,-28.527f,-31.634f,-29.003f,-30.280f,-32.537f,-33.407f, --33.085f,-31.840f,-28.311f,-29.039f,-28.918f,-27.710f,-27.286f,-28.889f,-29.200f,-30.555f, --31.177f,-32.609f,-33.948f,-36.362f,-38.697f,-40.661f,-41.993f,-44.927f,-46.190f,-48.897f, --49.050f,-48.825f,-47.891f,-45.238f,-41.318f,-39.419f,-36.598f,-34.185f,-32.961f,-30.403f, --25.242f,-19.291f,-16.436f,-11.863f,-10.272f, -7.006f, -4.568f, -2.428f, -0.706f, 2.720f, - 8.982f, 9.824f, 11.476f, 12.644f, 14.203f, 15.971f, 16.056f, 15.487f, 15.582f, 15.052f, - 13.606f -},{ --29.534f,-30.053f,-28.351f,-28.494f,-28.712f,-26.419f,-28.176f,-29.184f,-28.460f,-26.225f, --23.424f,-21.880f,-22.350f,-23.040f,-22.238f,-20.676f,-18.535f,-20.962f,-21.664f,-18.476f, --20.637f,-20.901f,-20.807f,-20.001f,-19.372f,-16.793f,-16.818f,-15.768f,-15.043f,-14.106f, --12.849f,-11.761f,-10.756f,-10.006f, -9.928f, -9.660f, -8.320f, -7.788f, -7.211f, -6.479f, - -5.811f, -5.082f, -4.294f, -3.861f, -3.247f, -2.973f, -3.026f, -2.950f, -2.824f, -2.183f, - -2.032f, -2.385f, -2.397f, -2.856f, -3.044f, -2.964f, -3.243f, -2.897f, -2.334f, -1.564f, - -0.907f, -0.292f, 0.096f, 0.752f, 0.699f, 0.572f, 0.468f, -0.102f, -0.772f, -1.614f, - -2.580f, -3.493f, -4.479f, -5.496f, -6.350f, -6.853f, -7.477f, -8.178f, -9.186f,-10.088f, --10.932f,-11.906f,-12.403f,-12.784f,-12.858f,-12.735f,-12.279f,-11.520f,-10.582f, -9.851f, - -8.793f, -7.343f, -6.203f, -5.466f, -5.422f, -4.964f, -4.200f, -3.309f, -2.934f, -2.387f, - -2.098f, -1.859f, -1.812f, -4.037f, -7.440f, -5.357f, -2.494f, -5.046f,-11.244f,-11.877f, --15.978f,-20.846f,-24.203f,-26.470f,-28.209f,-30.364f,-29.432f,-28.880f,-25.850f,-25.863f, --28.025f,-27.520f,-26.897f,-27.349f,-27.786f,-29.878f,-29.279f,-29.843f,-32.371f,-33.411f, --32.621f,-32.421f,-32.139f,-30.253f,-29.376f,-28.414f,-27.812f,-29.641f,-30.797f,-32.144f, --32.515f,-33.834f,-35.237f,-37.637f,-39.484f,-41.639f,-43.007f,-46.110f,-47.116f,-49.186f, --49.501f,-49.048f,-47.934f,-45.141f,-40.800f,-38.484f,-36.365f,-33.581f,-31.549f,-29.300f, --25.046f,-20.263f,-16.773f,-11.712f,-10.063f, -6.718f, -3.697f, -2.638f, -1.096f, 3.753f, - 10.335f, 10.455f, 11.870f, 13.125f, 14.356f, 16.061f, 16.109f, 15.540f, 15.721f, 15.098f, - 13.606f -},{ --29.534f,-30.011f,-28.295f,-28.597f,-28.700f,-26.262f,-28.218f,-29.043f,-28.239f,-25.859f, --22.793f,-20.868f,-21.049f,-22.125f,-21.911f,-20.088f,-18.126f,-20.034f,-19.639f,-17.233f, --21.583f,-19.444f,-19.907f,-19.351f,-18.833f,-17.130f,-16.197f,-15.217f,-14.504f,-13.582f, --12.240f,-11.143f, -9.951f, -9.275f, -9.146f, -8.231f, -7.261f, -7.214f, -6.652f, -6.063f, - -5.227f, -4.178f, -3.359f, -2.993f, -2.634f, -2.354f, -2.447f, -2.323f, -2.032f, -1.779f, - -1.607f, -1.874f, -2.313f, -2.705f, -2.943f, -2.864f, -2.738f, -2.322f, -1.506f, -0.894f, - 0.140f, 0.419f, 0.685f, 0.790f, 1.042f, 1.256f, 0.738f, 0.212f, -0.571f, -1.435f, - -2.473f, -3.304f, -4.248f, -5.255f, -6.180f, -6.732f, -7.062f, -7.778f, -8.864f, -9.816f, --10.703f,-11.383f,-11.894f,-12.309f,-12.316f,-12.075f,-11.484f,-10.685f, -9.677f, -9.599f, - -8.208f, -6.204f, -4.958f, -4.320f, -4.117f, -3.991f, -3.169f, -2.240f, -1.536f, -1.046f, - -0.712f, -0.419f, -0.733f, -5.930f, -4.189f, 0.948f, -1.508f, -4.827f,-10.093f,-11.294f, --13.493f,-14.238f,-17.773f,-26.939f,-28.171f,-28.232f,-28.711f,-29.177f,-25.637f,-25.353f, --27.818f,-28.003f,-26.739f,-27.128f,-27.046f,-28.485f,-29.018f,-30.422f,-31.970f,-33.254f, --33.100f,-33.349f,-31.769f,-30.935f,-30.527f,-31.051f,-27.562f,-28.979f,-31.572f,-33.375f, --33.968f,-34.881f,-36.467f,-38.532f,-40.387f,-42.395f,-44.180f,-46.695f,-47.732f,-48.952f, --49.154f,-49.025f,-48.042f,-44.871f,-40.262f,-37.880f,-36.348f,-32.787f,-30.197f,-28.309f, --25.234f,-21.205f,-17.207f,-11.874f, -9.870f, -6.152f, -2.766f, -2.603f, -1.302f, 5.082f, - 11.211f, 10.874f, 12.326f, 13.671f, 14.511f, 16.131f, 16.152f, 15.596f, 15.852f, 15.143f, - 13.606f -},{ --29.534f,-29.967f,-28.231f,-28.679f,-28.662f,-26.269f,-28.274f,-28.941f,-28.086f,-25.724f, --22.436f,-20.218f,-20.330f,-21.393f,-21.564f,-19.554f,-17.774f,-18.420f,-18.008f,-16.613f, --21.642f,-17.354f,-18.675f,-18.447f,-16.879f,-15.567f,-14.887f,-14.421f,-13.809f,-12.847f, --11.530f,-10.756f, -9.085f, -9.195f, -8.793f, -7.210f, -6.411f, -6.490f, -6.010f, -5.182f, - -4.277f, -3.123f, -2.288f, -2.065f, -2.147f, -1.765f, -1.847f, -1.720f, -1.512f, -1.285f, - -1.218f, -1.691f, -2.068f, -2.487f, -2.847f, -2.547f, -2.264f, -1.878f, -1.061f, -0.296f, - 0.494f, 1.118f, 1.292f, 1.121f, 1.226f, 1.436f, 1.039f, 0.335f, -0.236f, -0.996f, - -2.036f, -2.839f, -3.749f, -4.752f, -5.642f, -6.217f, -6.557f, -7.353f, -8.471f, -9.346f, --10.240f,-10.793f,-11.273f,-11.569f,-11.603f,-11.268f,-10.587f, -9.538f, -9.244f, -5.803f, - -5.959f, -4.563f, -3.925f, -3.189f, -2.926f, -2.697f, -2.057f, -1.271f, -0.447f, 0.013f, - 0.429f, 0.753f, -0.069f, -4.832f, -2.915f, 3.820f, -2.647f, -6.087f, -8.023f,-10.023f, --11.654f,-13.279f,-16.267f,-25.388f,-28.536f,-27.377f,-28.561f,-28.540f,-25.329f,-25.099f, --27.507f,-28.031f,-27.337f,-27.414f,-27.668f,-28.099f,-29.044f,-30.873f,-30.795f,-32.665f, --33.235f,-33.469f,-32.904f,-32.370f,-32.905f,-31.370f,-30.159f,-31.297f,-30.647f,-34.415f, --34.886f,-35.909f,-37.433f,-39.667f,-41.558f,-43.388f,-45.100f,-47.127f,-48.057f,-48.637f, --48.150f,-48.183f,-47.693f,-44.411f,-40.000f,-37.650f,-35.993f,-31.899f,-29.732f,-27.907f, --25.515f,-21.251f,-17.110f,-11.988f, -9.731f, -5.127f, -2.019f, -2.095f, -1.231f, 6.161f, - 11.379f, 11.051f, 12.755f, 14.232f, 14.673f, 16.183f, 16.185f, 15.657f, 15.977f, 15.188f, - 13.606f -},{ --29.534f,-29.922f,-28.159f,-28.732f,-28.614f,-26.450f,-28.324f,-28.884f,-28.007f,-25.854f, --22.420f,-19.353f,-19.350f,-20.697f,-20.909f,-19.206f,-17.706f,-17.824f,-17.407f,-15.796f, --20.670f,-16.340f,-17.542f,-17.212f,-15.758f,-14.610f,-13.995f,-13.363f,-12.901f,-12.174f, --11.120f, -9.937f, -8.489f, -8.616f, -7.989f, -6.195f, -5.734f, -5.931f, -5.312f, -4.361f, - -3.378f, -2.509f, -1.521f, -1.213f, -1.318f, -1.019f, -1.217f, -1.040f, -0.931f, -0.940f, - -1.121f, -1.308f, -1.804f, -2.335f, -2.619f, -2.296f, -2.161f, -1.571f, -0.925f, -0.266f, - 0.855f, 1.365f, 1.615f, 1.718f, 1.490f, 1.821f, 1.469f, 0.740f, 0.186f, -0.684f, - -1.467f, -2.325f, -3.318f, -4.382f, -5.206f, -5.628f, -6.008f, -6.954f, -7.956f, -8.714f, - -9.363f, -9.979f,-10.300f,-10.699f,-10.555f,-10.206f, -9.495f, -8.373f, -7.978f, -3.595f, - -4.286f, -3.685f, -2.850f, -2.203f, -1.574f, -1.376f, -0.694f, 0.058f, 0.886f, 1.317f, - 1.283f, 1.603f, -2.309f, -2.850f, 0.467f, 2.127f, -1.857f, -4.754f, -6.843f, -8.827f, --10.723f,-13.624f,-15.260f,-19.682f,-27.855f,-27.006f,-27.437f,-27.054f,-25.779f,-24.535f, --27.256f,-28.492f,-27.164f,-27.904f,-27.286f,-28.349f,-29.111f,-29.507f,-30.262f,-31.925f, --33.271f,-33.341f,-33.394f,-34.306f,-35.521f,-33.788f,-31.013f,-31.699f,-33.131f,-35.250f, --35.009f,-36.989f,-38.989f,-40.700f,-42.640f,-44.601f,-46.384f,-47.597f,-48.196f,-48.295f, --47.040f,-47.059f,-46.916f,-44.116f,-39.909f,-37.315f,-35.612f,-31.426f,-29.761f,-27.929f, --25.671f,-20.799f,-16.244f,-11.846f, -9.787f, -3.988f, -1.623f, -1.251f, -0.955f, 6.491f, - 10.855f, 11.074f, 13.091f, 14.742f, 14.841f, 16.224f, 16.211f, 15.725f, 16.093f, 15.231f, - 13.606f -},{ --29.534f,-29.874f,-28.080f,-28.747f,-28.574f,-26.795f,-28.364f,-28.884f,-28.015f,-26.158f, --22.601f,-17.844f,-17.331f,-19.750f,-19.999f,-18.803f,-17.370f,-18.232f,-17.149f,-14.702f, --19.251f,-16.327f,-16.638f,-16.339f,-15.702f,-14.684f,-13.393f,-12.764f,-12.266f,-11.516f, --10.240f, -9.268f, -8.195f, -7.799f, -7.290f, -5.497f, -5.265f, -5.345f, -4.811f, -3.603f, - -2.654f, -1.736f, -1.140f, -0.446f, -0.488f, -0.274f, -0.254f, -0.212f, -0.357f, -0.445f, - -0.727f, -0.977f, -1.493f, -2.069f, -2.237f, -2.160f, -1.708f, -1.165f, -0.555f, 0.225f, - 0.972f, 1.667f, 2.198f, 2.085f, 1.981f, 2.047f, 1.923f, 1.242f, 0.692f, 0.000f, - -1.017f, -1.980f, -2.866f, -3.687f, -4.499f, -5.189f, -5.652f, -6.316f, -7.037f, -7.777f, - -8.469f, -9.038f, -9.356f, -9.516f, -9.441f, -9.088f, -8.385f, -7.312f, -6.571f, -3.608f, - -3.592f, -2.755f, -1.956f, -0.989f, -0.415f, 0.231f, 0.882f, 1.477f, 2.129f, 2.672f, - 2.826f, 2.687f, -3.456f, -1.186f, 2.576f, 1.753f, -1.492f, -3.591f, -6.263f, -7.394f, --10.087f,-12.400f,-14.823f,-15.823f,-24.407f,-28.003f,-26.206f,-26.010f,-27.360f,-25.215f, --27.842f,-29.256f,-27.842f,-29.043f,-28.320f,-28.619f,-29.190f,-29.006f,-30.201f,-32.271f, --32.778f,-33.030f,-33.530f,-34.796f,-36.827f,-35.926f,-32.245f,-32.536f,-34.551f,-36.255f, --36.326f,-37.746f,-40.649f,-42.038f,-43.831f,-45.577f,-47.537f,-48.074f,-48.677f,-48.006f, --46.226f,-46.288f,-45.726f,-43.497f,-39.699f,-37.028f,-34.990f,-31.390f,-30.077f,-27.857f, --25.648f,-20.245f,-14.867f,-11.318f, -9.662f, -3.021f, -1.521f, -0.175f, -0.432f, 6.028f, - 9.892f, 11.121f, 13.338f, 15.153f, 15.012f, 16.265f, 16.235f, 15.799f, 16.200f, 15.274f, - 13.606f -},{ --29.534f,-29.825f,-27.994f,-28.719f,-28.557f,-27.268f,-28.405f,-28.951f,-28.129f,-26.490f, --22.734f,-16.121f,-14.777f,-18.572f,-19.220f,-18.167f,-16.390f,-18.082f,-16.694f,-14.185f, --17.105f,-15.640f,-15.887f,-15.539f,-14.798f,-13.661f,-12.718f,-12.204f,-11.925f,-10.812f, - -9.455f, -8.824f, -7.554f, -7.059f, -6.705f, -5.090f, -4.842f, -4.545f, -3.981f, -2.914f, - -2.049f, -1.253f, -0.744f, 0.062f, 0.148f, 0.429f, 0.828f, 0.799f, 0.505f, -0.072f, - -0.365f, -0.514f, -1.118f, -1.651f, -1.689f, -1.724f, -1.271f, -0.729f, -0.200f, 0.599f, - 1.154f, 1.819f, 2.740f, 2.741f, 2.495f, 2.758f, 2.291f, 1.768f, 1.226f, 0.393f, - -0.401f, -1.443f, -2.267f, -3.078f, -3.999f, -4.734f, -5.120f, -5.611f, -6.284f, -6.899f, - -7.483f, -8.019f, -8.252f, -8.202f, -8.056f, -7.635f, -6.983f, -5.987f, -5.169f, -3.112f, - -2.634f, -1.796f, -0.990f, 0.291f, 1.365f, 1.717f, 2.536f, 3.131f, 3.666f, 4.400f, - 4.240f, 1.210f, -2.449f, -0.414f, 3.642f, 2.288f, -3.105f, -5.384f, -8.185f, -6.787f, - -8.738f,-11.715f,-13.890f,-16.673f,-20.883f,-27.685f,-25.700f,-26.092f,-30.195f,-28.908f, --27.934f,-29.481f,-28.696f,-30.020f,-28.266f,-28.418f,-29.388f,-30.028f,-31.235f,-32.310f, --32.724f,-33.088f,-34.058f,-35.226f,-36.129f,-36.664f,-33.865f,-35.366f,-34.803f,-37.110f, --37.890f,-39.315f,-41.772f,-43.172f,-44.843f,-46.053f,-47.382f,-48.518f,-48.878f,-47.870f, --46.540f,-45.840f,-44.863f,-42.770f,-39.476f,-36.871f,-34.212f,-31.841f,-30.803f,-27.745f, --25.430f,-19.578f,-13.685f,-10.816f, -9.059f, -2.024f, -1.467f, 1.255f, 0.521f, 5.222f, - 8.851f, 11.388f, 13.581f, 15.456f, 15.177f, 16.317f, 16.261f, 15.882f, 16.299f, 15.317f, - 13.606f -},{ --29.534f,-29.775f,-27.902f,-28.646f,-28.569f,-27.818f,-28.467f,-29.081f,-28.352f,-26.739f, --22.651f,-15.379f,-13.423f,-17.660f,-18.858f,-17.519f,-15.523f,-17.267f,-16.065f,-14.242f, --14.743f,-14.811f,-15.243f,-14.298f,-13.839f,-12.810f,-12.173f,-11.669f,-11.215f,-10.012f, - -8.759f, -8.100f, -6.797f, -6.585f, -6.082f, -4.878f, -4.343f, -3.921f, -2.987f, -1.993f, - -1.072f, -0.697f, -0.059f, 0.576f, 0.826f, 1.231f, 1.750f, 1.783f, 1.385f, 0.426f, - 0.080f, -0.134f, -0.598f, -0.716f, -1.163f, -0.931f, -0.590f, -0.222f, 0.197f, 0.894f, - 1.613f, 2.319f, 2.857f, 3.390f, 3.506f, 2.825f, 2.821f, 2.335f, 1.693f, 0.945f, - 0.081f, -1.026f, -1.795f, -2.548f, -3.405f, -4.303f, -4.658f, -4.869f, -5.480f, -6.028f, - -6.473f, -6.813f, -6.877f, -6.694f, -6.405f, -6.009f, -5.231f, -4.311f, -3.510f, -2.271f, - -1.592f, -0.733f, 0.092f, 1.072f, 2.908f, 3.873f, 4.252f, 4.907f, 5.283f, 5.889f, - 3.805f, -0.708f, -0.253f, 4.336f, 5.349f, 4.204f, -1.735f, -8.567f,-10.969f,-12.327f, --12.657f,-11.306f,-13.494f,-17.786f,-22.682f,-25.695f,-25.305f,-27.023f,-31.493f,-28.955f, --27.782f,-28.545f,-28.548f,-30.106f,-28.961f,-28.526f,-29.797f,-31.190f,-32.447f,-33.458f, --34.039f,-34.353f,-34.260f,-34.713f,-35.792f,-37.238f,-35.433f,-36.057f,-36.212f,-37.558f, --38.928f,-39.989f,-42.642f,-44.288f,-45.612f,-46.543f,-47.504f,-48.525f,-48.416f,-47.814f, --46.981f,-45.667f,-44.080f,-42.038f,-38.955f,-36.589f,-34.016f,-32.073f,-30.921f,-27.845f, --24.803f,-18.838f,-13.146f,-10.928f, -8.340f, -0.726f, -1.233f, 3.063f, 1.969f, 4.660f, - 8.052f, 11.996f, 13.936f, 15.687f, 15.334f, 16.390f, 16.293f, 15.974f, 16.391f, 15.358f, - 13.606f -},{ --29.534f,-29.723f,-27.803f,-28.528f,-28.611f,-28.382f,-28.568f,-29.249f,-28.653f,-26.873f, --22.377f,-16.588f,-14.703f,-17.603f,-18.835f,-17.138f,-15.564f,-16.911f,-15.455f,-14.249f, --12.981f,-14.487f,-14.428f,-13.302f,-13.136f,-11.880f,-11.516f,-11.163f,-10.409f, -9.199f, - -7.968f, -6.921f, -6.209f, -5.995f, -4.976f, -4.296f, -3.730f, -3.213f, -2.067f, -1.160f, - -0.401f, 0.241f, 0.831f, 1.189f, 1.660f, 2.196f, 2.627f, 2.441f, 2.190f, 1.047f, - 0.398f, 0.510f, 0.107f, 0.039f, -0.435f, -0.128f, 0.075f, 0.403f, 0.698f, 1.445f, - 2.137f, 2.750f, 3.422f, 3.758f, 3.856f, 3.449f, 3.274f, 2.837f, 2.248f, 1.385f, - 0.638f, -0.079f, -1.091f, -1.903f, -2.825f, -3.803f, -4.186f, -4.197f, -4.470f, -4.937f, - -5.308f, -5.461f, -5.373f, -5.080f, -4.599f, -4.098f, -3.439f, -2.503f, -1.781f, -1.098f, - -0.431f, 0.610f, 1.354f, 2.320f, 3.666f, 5.594f, 6.117f, 6.417f, 7.134f, 6.275f, - 6.285f, 6.036f, 5.671f, 6.801f, 5.550f, 4.284f, -0.477f, -8.584f,-10.937f,-12.358f, --15.646f,-17.810f,-17.772f,-19.072f,-24.328f,-24.481f,-25.631f,-29.268f,-29.546f,-27.368f, --28.102f,-28.284f,-27.953f,-30.125f,-30.067f,-29.890f,-30.442f,-31.731f,-34.039f,-34.578f, --34.658f,-34.626f,-33.927f,-33.963f,-34.454f,-36.119f,-35.502f,-36.753f,-37.171f,-38.081f, --39.358f,-39.920f,-42.687f,-45.085f,-45.973f,-47.037f,-47.628f,-48.198f,-48.150f,-47.611f, --46.755f,-45.258f,-43.525f,-41.417f,-38.259f,-35.866f,-33.967f,-31.487f,-29.513f,-27.209f, --23.593f,-18.148f,-12.913f,-11.211f, -7.763f, 0.753f, -0.739f, 4.846f, 3.664f, 4.685f, - 7.703f, 12.934f, 14.484f, 15.911f, 15.484f, 16.492f, 16.336f, 16.075f, 16.475f, 15.397f, - 13.606f -},{ --29.534f,-29.670f,-27.700f,-28.369f,-28.675f,-28.899f,-28.708f,-29.402f,-28.958f,-26.923f, --22.098f,-19.518f,-18.243f,-18.498f,-18.895f,-17.032f,-16.164f,-16.916f,-14.982f,-14.122f, --11.857f,-14.012f,-13.719f,-12.802f,-12.333f,-10.970f,-10.866f,-10.442f, -9.774f, -8.412f, - -7.206f, -6.004f, -5.642f, -5.045f, -3.808f, -3.313f, -3.158f, -2.257f, -1.139f, -0.324f, - 0.394f, 1.125f, 1.559f, 2.082f, 2.373f, 3.054f, 3.324f, 3.277f, 3.065f, 1.791f, - 1.034f, 0.807f, 0.991f, 0.974f, 0.670f, 0.929f, 1.079f, 1.495f, 1.679f, 2.102f, - 2.611f, 3.162f, 4.069f, 4.342f, 4.479f, 4.330f, 4.356f, 3.598f, 3.110f, 2.160f, - 1.306f, 0.510f, -0.290f, -1.086f, -2.078f, -2.891f, -3.488f, -3.523f, -3.476f, -3.734f, - -3.957f, -3.917f, -3.837f, -3.328f, -2.817f, -2.270f, -1.485f, -0.465f, 0.297f, 0.879f, - 0.898f, 1.944f, 2.887f, 3.873f, 4.664f, 6.066f, 7.593f, 8.474f, 9.192f, 6.811f, - 10.498f, 8.398f, 8.558f, 7.059f, 5.575f, 3.375f, -1.011f, -7.605f,-11.698f,-13.952f, --14.806f,-19.041f,-20.411f,-22.528f,-26.143f,-27.109f,-27.861f,-27.163f,-26.354f,-27.559f, --28.572f,-28.849f,-27.206f,-30.063f,-30.489f,-31.025f,-30.276f,-32.102f,-34.667f,-34.915f, --34.467f,-34.044f,-34.126f,-33.787f,-33.708f,-34.980f,-35.717f,-37.239f,-37.453f,-38.614f, --39.832f,-40.440f,-42.420f,-45.164f,-45.702f,-46.400f,-47.718f,-47.984f,-47.601f,-46.566f, --45.479f,-44.299f,-42.748f,-40.737f,-37.459f,-34.623f,-33.493f,-30.651f,-27.500f,-25.251f, --22.267f,-17.510f,-12.333f,-10.413f, -6.984f, 2.204f, -0.012f, 6.021f, 5.219f, 5.291f, - 7.905f, 14.058f, 15.214f, 16.190f, 15.635f, 16.626f, 16.396f, 16.183f, 16.553f, 15.436f, - 13.606f -},{ --29.534f,-29.616f,-27.594f,-28.172f,-28.747f,-29.315f,-28.870f,-29.476f,-29.170f,-26.935f, --22.045f,-22.759f,-22.002f,-19.737f,-18.878f,-17.019f,-16.573f,-16.416f,-14.547f,-13.762f, --11.024f,-13.159f,-13.049f,-11.916f,-11.519f,-10.324f, -9.904f, -9.569f, -8.837f, -7.656f, - -6.575f, -5.550f, -4.732f, -3.670f, -2.976f, -2.666f, -1.968f, -1.156f, -0.091f, 0.566f, - 1.144f, 1.771f, 2.294f, 3.040f, 3.606f, 3.886f, 4.202f, 4.301f, 3.924f, 2.740f, - 2.229f, 1.979f, 2.002f, 2.056f, 2.119f, 2.204f, 2.254f, 2.507f, 2.636f, 3.091f, - 3.526f, 3.886f, 4.498f, 5.311f, 5.270f, 4.600f, 4.476f, 4.448f, 4.030f, 3.019f, - 2.341f, 1.549f, 0.833f, -0.124f, -0.974f, -1.728f, -2.335f, -2.389f, -2.275f, -2.283f, - -2.426f, -2.189f, -1.950f, -1.676f, -1.132f, -0.436f, 0.539f, 1.537f, 2.643f, 3.536f, - 3.025f, 3.455f, 4.638f, 5.497f, 6.768f, 7.610f, 8.830f, 10.723f, 10.786f, 10.093f, - 13.705f, 8.875f, 7.289f, 5.509f, 3.445f, 1.040f, -1.643f, -5.668f,-12.240f,-13.241f, --17.054f,-19.712f,-18.958f,-22.877f,-25.362f,-23.348f,-25.442f,-25.039f,-24.584f,-27.915f, --28.637f,-28.609f,-27.744f,-28.620f,-30.955f,-29.739f,-31.896f,-31.330f,-33.923f,-34.537f, --33.753f,-35.896f,-35.168f,-33.969f,-35.515f,-36.402f,-37.496f,-37.232f,-37.385f,-38.693f, --39.938f,-41.382f,-42.867f,-44.658f,-45.100f,-45.329f,-47.442f,-47.819f,-47.117f,-45.798f, --44.088f,-43.133f,-41.520f,-40.030f,-36.709f,-33.332f,-32.725f,-29.632f,-26.357f,-23.597f, --21.466f,-16.747f,-11.181f, -8.295f, -5.894f, 3.763f, 0.886f, 6.436f, 6.455f, 6.303f, - 8.685f, 15.153f, 16.023f, 16.550f, 15.803f, 16.791f, 16.476f, 16.298f, 16.627f, 15.474f, - 13.606f -},{ --29.534f,-29.561f,-27.485f,-27.944f,-28.808f,-29.592f,-29.016f,-29.414f,-29.216f,-26.937f, --22.364f,-24.775f,-23.943f,-20.366f,-18.703f,-16.848f,-16.496f,-15.661f,-14.023f,-13.014f, --10.312f,-12.040f,-12.072f,-10.841f,-10.579f, -9.394f, -8.873f, -8.307f, -7.831f, -6.774f, - -5.752f, -4.827f, -3.553f, -2.732f, -2.448f, -1.516f, -0.769f, 0.036f, 0.867f, 1.565f, - 2.139f, 2.646f, 3.243f, 4.154f, 4.508f, 4.855f, 5.286f, 5.186f, 4.908f, 3.847f, - 3.276f, 3.156f, 3.042f, 3.265f, 3.389f, 3.549f, 3.290f, 3.612f, 3.646f, 4.073f, - 4.657f, 4.966f, 4.988f, 6.133f, 6.409f, 5.127f, 5.556f, 5.628f, 5.742f, 4.452f, - 3.457f, 2.880f, 2.202f, 1.353f, 0.384f, -0.074f, -0.687f, -1.027f, -0.816f, -0.572f, - -0.624f, -0.309f, -0.261f, -0.338f, -0.029f, 0.808f, 1.748f, 3.771f, 4.997f, 6.742f, - 6.166f, 5.724f, 6.504f, 7.444f, 8.504f, 9.357f, 10.021f, 10.894f, 11.912f, 14.872f, - 9.382f, 5.894f, 5.521f, 4.598f, 2.327f, -0.624f, -2.394f, -6.084f,-12.676f,-14.300f, --17.478f,-20.276f,-16.867f,-21.691f,-24.716f,-23.219f,-24.893f,-25.922f,-25.798f,-28.530f, --29.114f,-28.857f,-28.818f,-29.284f,-30.516f,-31.460f,-31.908f,-31.948f,-33.544f,-34.148f, --34.417f,-35.400f,-35.723f,-35.169f,-35.443f,-37.071f,-37.931f,-36.903f,-37.016f,-37.850f, --39.474f,-41.601f,-43.230f,-44.752f,-44.623f,-44.757f,-46.769f,-47.546f,-46.815f,-45.612f, --43.240f,-41.695f,-40.264f,-39.063f,-36.116f,-33.129f,-32.068f,-28.589f,-26.263f,-23.392f, --21.056f,-15.728f, -9.887f, -6.209f, -4.968f, 5.547f, 1.840f, 6.583f, 7.512f, 7.566f, - 9.984f, 16.008f, 16.771f, 16.968f, 16.005f, 16.982f, 16.579f, 16.418f, 16.697f, 15.510f, - 13.606f -},{ --29.534f,-29.505f,-27.374f,-27.691f,-28.836f,-29.713f,-29.104f,-29.197f,-29.084f,-26.938f, --23.038f,-25.028f,-23.573f,-19.773f,-18.323f,-16.293f,-15.777f,-15.252f,-13.439f,-12.202f, - -9.994f,-10.748f,-11.279f,-10.173f, -9.530f, -8.398f, -7.756f, -7.082f, -6.890f, -5.996f, - -5.001f, -4.019f, -2.513f, -2.061f, -1.683f, -0.938f, 0.389f, 1.241f, 1.784f, 2.410f, - 3.195f, 3.472f, 3.962f, 4.820f, 5.415f, 5.811f, 6.328f, 6.224f, 5.897f, 5.094f, - 4.465f, 4.379f, 4.187f, 4.525f, 4.856f, 4.712f, 4.877f, 4.633f, 4.863f, 4.938f, - 5.396f, 5.847f, 6.092f, 6.802f, 6.435f, 7.747f, 6.233f, 7.024f, 6.463f, 6.289f, - 5.230f, 4.431f, 3.706f, 3.019f, 2.387f, 1.656f, 1.271f, 1.259f, 1.282f, 1.328f, - 0.754f, 0.348f, -0.200f, -1.880f, -2.859f, -1.952f, 0.079f, 3.155f, 6.263f, 8.896f, - 9.560f, 8.454f, 9.042f, 10.141f, 10.469f, 10.401f, 12.807f, 11.570f, 14.169f, 13.263f, - 6.287f, 3.364f, 3.070f, 1.887f, 0.571f, -1.169f, -3.611f, -6.824f,-11.238f,-16.173f, --18.082f,-21.693f,-17.940f,-21.570f,-25.644f,-23.572f,-24.490f,-25.994f,-27.664f,-29.201f, --29.424f,-29.648f,-30.738f,-31.255f,-31.056f,-33.018f,-32.282f,-32.104f,-33.471f,-34.827f, --34.598f,-34.055f,-35.544f,-35.757f,-36.395f,-37.379f,-37.907f,-36.853f,-37.684f,-38.385f, --38.876f,-41.188f,-43.210f,-44.873f,-44.520f,-44.523f,-46.467f,-46.862f,-46.180f,-45.119f, --42.633f,-40.230f,-39.083f,-38.102f,-35.295f,-33.421f,-31.242f,-28.139f,-26.437f,-23.549f, --20.484f,-14.581f, -9.026f, -5.274f, -4.277f, 6.980f, 2.731f, 7.076f, 8.581f, 8.945f, - 11.619f, 16.492f, 17.361f, 17.384f, 16.257f, 17.190f, 16.704f, 16.540f, 16.767f, 15.544f, - 13.606f -},{ --29.534f,-29.448f,-27.264f,-27.423f,-28.812f,-29.681f,-29.092f,-28.854f,-28.837f,-26.954f, --23.880f,-24.177f,-21.973f,-18.190f,-17.899f,-15.511f,-14.435f,-14.760f,-12.831f,-11.435f, - -9.989f, -9.452f,-10.619f, -9.503f, -8.441f, -7.209f, -6.469f, -6.087f, -5.735f, -5.075f, - -4.256f, -3.065f, -1.990f, -1.049f, -0.591f, 0.697f, 1.686f, 2.315f, 2.805f, 3.410f, - 4.065f, 4.447f, 4.776f, 5.724f, 6.623f, 6.443f, 7.182f, 7.207f, 7.056f, 6.361f, - 5.549f, 5.651f, 5.400f, 5.713f, 6.000f, 5.968f, 6.599f, 5.529f, 6.087f, 6.379f, - 6.536f, 6.537f, 6.656f, 7.709f, 7.759f, 7.863f, 7.945f, 7.101f, 7.039f, 7.684f, - 6.876f, 6.146f, 5.443f, 5.010f, 4.526f, 4.105f, 3.500f, 3.552f, 3.410f, 2.276f, - 0.387f, -2.256f, -1.858f, 2.812f, 8.417f, 11.235f, 8.132f, 4.963f, 10.866f, 10.032f, - 8.863f, 9.541f, 11.276f, 11.834f, 13.071f, 12.147f, 12.897f, 11.754f, 15.276f, 10.722f, - 2.591f, 1.122f, 2.554f, 0.459f, -0.594f, -3.246f, -5.112f, -8.262f,-12.137f,-16.362f, --19.107f,-22.843f,-20.041f,-23.001f,-26.459f,-24.480f,-26.254f,-27.155f,-29.539f,-29.652f, --30.124f,-31.017f,-32.787f,-32.923f,-32.450f,-31.829f,-34.152f,-32.285f,-32.258f,-34.314f, --34.545f,-34.406f,-35.412f,-36.349f,-36.235f,-37.244f,-37.555f,-36.696f,-37.805f,-38.592f, --38.800f,-41.360f,-43.292f,-44.712f,-44.396f,-44.379f,-45.182f,-44.838f,-44.693f,-43.809f, --42.291f,-38.486f,-37.536f,-37.323f,-34.359f,-32.546f,-30.228f,-27.893f,-26.272f,-23.086f, --19.567f,-13.427f, -8.485f, -4.801f, -3.175f, 7.147f, 3.595f, 8.010f, 9.604f, 10.211f, - 13.270f, 16.601f, 17.799f, 17.728f, 16.566f, 17.408f, 16.850f, 16.663f, 16.837f, 15.577f, - 13.606f -},{ --29.534f,-29.391f,-27.155f,-27.144f,-28.715f,-29.516f,-28.960f,-28.460f,-28.587f,-27.004f, --24.603f,-23.302f,-20.591f,-16.630f,-17.808f,-15.102f,-13.195f,-13.730f,-12.318f,-10.706f, - -9.534f, -8.249f, -9.827f, -8.608f, -7.479f, -6.024f, -5.437f, -5.010f, -4.561f, -4.132f, - -3.512f, -2.162f, -1.246f, -0.345f, 0.736f, 1.526f, 2.567f, 3.391f, 4.108f, 4.528f, - 4.949f, 5.478f, 5.897f, 6.809f, 7.597f, 7.210f, 8.302f, 8.155f, 8.132f, 7.699f, - 6.855f, 6.701f, 6.469f, 6.772f, 7.252f, 7.344f, 7.443f, 6.383f, 7.095f, 7.296f, - 7.996f, 7.843f, 8.031f, 8.646f, 9.468f, 8.409f, 8.094f, 8.015f, 8.413f, 8.241f, - 8.162f, 7.802f, 7.817f, 7.324f, 6.701f, 6.950f, 6.319f, 5.702f, 3.823f, -0.052f, - -0.787f, 5.812f, 8.543f, 8.719f, 9.899f, 16.603f, 15.855f, 10.183f, 18.492f, 15.868f, - 14.391f, 12.117f, 10.550f, 12.655f, 13.635f, 13.356f, 13.718f, 11.960f, 14.540f, 12.352f, - 0.841f, -0.803f, 0.311f, -1.568f, -2.804f, -5.725f, -7.157f,-10.349f,-14.964f,-19.553f, --19.246f,-23.508f,-21.350f,-23.667f,-26.369f,-28.308f,-28.446f,-29.534f,-31.274f,-32.042f, --32.390f,-33.632f,-34.468f,-34.311f,-33.553f,-32.229f,-32.823f,-33.327f,-32.406f,-32.254f, --33.945f,-34.525f,-34.976f,-36.699f,-36.758f,-36.589f,-36.926f,-36.641f,-37.916f,-39.139f, --39.502f,-42.133f,-43.546f,-44.626f,-44.008f,-44.446f,-44.033f,-43.698f,-43.768f,-44.006f, --42.354f,-37.456f,-35.750f,-36.062f,-33.837f,-31.898f,-29.717f,-27.239f,-25.470f,-22.237f, --18.443f,-12.124f, -7.539f, -3.310f, -1.352f, 6.127f, 4.686f, 8.922f, 10.279f, 11.028f, - 14.574f, 16.463f, 18.191f, 17.953f, 16.931f, 17.628f, 17.015f, 16.785f, 16.909f, 15.608f, - 13.606f -},{ --29.534f,-29.334f,-27.049f,-26.863f,-28.533f,-29.249f,-28.705f,-28.111f,-28.437f,-27.084f, --24.948f,-22.982f,-20.134f,-16.209f,-18.184f,-15.328f,-12.777f,-12.681f,-12.004f,-10.303f, - -8.542f, -7.367f, -9.152f, -7.489f, -6.538f, -4.965f, -4.158f, -3.950f, -3.313f, -3.067f, - -2.470f, -1.537f, -0.170f, 0.613f, 1.765f, 3.079f, 3.678f, 4.469f, 5.098f, 5.351f, - 5.550f, 6.066f, 6.742f, 7.737f, 8.531f, 8.862f, 9.201f, 9.078f, 9.228f, 9.037f, - 8.081f, 7.928f, 7.540f, 8.029f, 8.435f, 8.352f, 10.050f, 7.614f, 8.597f, 8.475f, - 9.029f, 9.255f, 9.421f, 9.990f, 9.356f, 9.508f, 9.457f, 8.719f, 8.768f, 9.073f, - 9.374f, 9.884f, 10.305f, 10.080f, 9.750f, 9.851f, 8.505f, 6.255f, 1.934f, 2.243f, - 9.197f, 13.758f, 14.608f, 17.188f, 16.723f, 18.323f, 17.178f, 22.230f, 23.432f, 23.746f, - 22.030f, 17.646f, 12.585f, 10.941f, 13.089f, 14.384f, 14.105f, 11.813f, 15.043f, 14.482f, - 1.139f, -2.089f, -1.633f, -3.915f, -5.947f, -7.663f,-10.162f,-12.285f,-15.805f,-22.293f, --20.908f,-21.382f,-22.847f,-25.137f,-26.916f,-28.416f,-30.412f,-30.186f,-33.574f,-34.896f, --35.801f,-35.548f,-36.607f,-36.184f,-35.575f,-34.867f,-32.332f,-32.687f,-33.429f,-32.926f, --32.690f,-33.319f,-33.373f,-36.311f,-37.098f,-35.908f,-36.632f,-37.246f,-38.194f,-39.390f, --40.189f,-41.918f,-43.200f,-43.884f,-43.370f,-44.282f,-43.767f,-43.764f,-42.435f,-41.684f, --40.768f,-37.052f,-34.275f,-34.543f,-33.020f,-31.504f,-29.046f,-26.567f,-24.340f,-21.422f, --17.118f,-10.484f, -5.807f, -0.686f, 0.779f, 5.445f, 6.209f, 9.362f, 10.363f, 11.134f, - 15.267f, 16.292f, 18.678f, 18.060f, 17.337f, 17.845f, 17.191f, 16.906f, 16.985f, 15.638f, - 13.606f -},{ --29.534f,-29.276f,-26.946f,-26.583f,-28.258f,-28.911f,-28.349f,-27.883f,-28.425f,-27.141f, --24.823f,-23.061f,-20.435f,-17.315f,-18.575f,-15.512f,-12.740f,-12.036f,-11.488f, -9.694f, - -7.356f, -6.691f, -8.233f, -6.280f, -5.433f, -3.804f, -2.623f, -2.589f, -2.202f, -1.868f, - -1.251f, -0.636f, 0.534f, 1.595f, 2.935f, 3.893f, 4.741f, 4.998f, 5.364f, 5.042f, - 5.193f, 5.606f, 7.269f, 8.558f, 9.757f, 10.408f, 10.024f, 10.219f, 10.352f, 10.319f, - 9.377f, 9.263f, 9.036f, 9.205f, 9.797f, 9.703f, 9.599f, 8.770f, 10.035f, 9.933f, - 10.171f, 11.151f, 10.863f, 11.712f, 11.115f, 11.024f, 10.536f, 10.140f, 9.799f, 10.489f, - 10.897f, 11.762f, 12.053f, 13.024f, 12.950f, 11.654f, 8.769f, 6.645f, 10.235f, 14.975f, - 20.177f, 18.928f, 19.770f, 19.485f, 18.818f, 11.432f, 12.875f, 16.238f, 23.414f, 23.147f, - 24.530f, 27.656f, 19.544f, 15.393f, 10.132f, 11.971f, 12.096f, 13.955f, 14.609f, 9.980f, - -1.612f, -3.647f, -4.189f, -6.434f, -7.564f, -9.534f,-12.732f,-13.847f,-15.111f,-24.345f, --22.599f,-23.245f,-23.553f,-24.223f,-27.047f,-31.537f,-32.881f,-33.446f,-36.365f,-37.026f, --38.804f,-39.579f,-38.748f,-39.374f,-38.881f,-37.226f,-35.995f,-33.776f,-33.502f,-34.129f, --34.968f,-33.684f,-32.410f,-35.393f,-36.772f,-35.312f,-36.356f,-36.514f,-37.684f,-38.937f, --40.086f,-40.673f,-41.683f,-42.554f,-42.054f,-42.928f,-42.590f,-42.219f,-40.645f,-38.629f, --37.853f,-35.179f,-32.503f,-33.046f,-31.718f,-29.657f,-28.222f,-26.358f,-23.448f,-20.519f, --15.364f, -8.458f, -3.509f, 1.653f, 2.990f, 6.580f, 8.024f, 9.361f, 9.910f, 10.537f, - 15.291f, 16.311f, 19.339f, 18.097f, 17.762f, 18.059f, 17.374f, 17.025f, 17.066f, 15.665f, - 13.606f -},{ --29.534f,-29.219f,-26.848f,-26.311f,-27.887f,-28.527f,-27.924f,-27.803f,-28.503f,-27.082f, --24.357f,-23.108f,-20.987f,-19.280f,-18.416f,-14.792f,-12.147f,-11.381f,-10.319f, -8.320f, - -5.857f, -5.525f, -6.920f, -5.055f, -4.173f, -2.440f, -1.197f, -1.016f, -0.680f, -0.483f, - 0.031f, 0.608f, 1.465f, 2.652f, 3.733f, 4.819f, 4.807f, 4.642f, 4.505f, 4.609f, - 5.609f, 5.801f, 6.903f, 8.946f, 10.784f, 11.133f, 10.711f, 11.204f, 11.369f, 11.142f, - 10.719f, 10.306f, 10.284f, 10.672f, 11.023f, 11.303f, 10.565f, 10.754f, 11.878f, 11.315f, - 11.527f, 12.024f, 12.363f, 13.250f, 13.026f, 12.093f, 12.434f, 11.684f, 11.325f, 12.055f, - 12.501f, 13.378f, 14.353f, 15.236f, 14.757f, 11.037f, 11.663f, 16.848f, 24.029f, 26.677f, - 24.226f, 19.277f, 13.362f, 11.386f, 14.262f, 10.401f, 10.194f, 9.929f, 13.751f, 14.986f, - 17.319f, 24.490f, 26.364f, 23.863f, 17.340f, 16.469f, 19.252f, 17.022f, 12.334f, 1.487f, - -4.462f, -5.897f, -5.925f, -8.231f,-12.088f,-13.830f,-14.551f,-16.545f,-15.042f,-26.453f, --24.633f,-25.276f,-28.776f,-26.836f,-31.758f,-32.988f,-39.057f,-37.559f,-38.493f,-41.224f, --41.382f,-42.693f,-40.914f,-39.885f,-39.885f,-38.902f,-37.463f,-36.455f,-34.855f,-33.146f, --34.505f,-34.015f,-33.282f,-35.316f,-35.783f,-34.489f,-35.345f,-35.732f,-36.169f,-38.051f, --39.478f,-39.348f,-40.346f,-40.910f,-40.909f,-40.947f,-40.881f,-40.562f,-38.396f,-36.101f, --34.574f,-32.870f,-30.521f,-32.246f,-30.695f,-27.773f,-27.517f,-25.586f,-22.349f,-19.044f, --13.192f, -6.214f, -1.126f, 2.854f, 5.545f, 9.291f, 9.756f, 9.300f, 9.246f, 9.527f, - 14.774f, 16.667f, 20.127f, 18.139f, 18.181f, 18.273f, 17.556f, 17.143f, 17.153f, 15.691f, - 13.606f -},{ --29.534f,-29.161f,-26.755f,-26.049f,-27.426f,-28.110f,-27.461f,-27.836f,-28.567f,-26.830f, --23.824f,-22.938f,-21.388f,-20.871f,-17.818f,-13.247f,-10.937f,-10.391f, -8.785f, -7.121f, - -4.497f, -3.825f, -5.249f, -3.516f, -3.014f, -0.980f, 0.005f, 0.496f, 0.859f, 0.662f, - 1.308f, 1.764f, 2.665f, 3.578f, 4.620f, 4.502f, 4.200f, 4.696f, 7.113f, 9.192f, - 10.007f, 10.229f, 10.886f, 9.810f, 11.256f, 10.791f, 10.318f, 10.073f, 10.717f, 11.120f, - 10.968f, 10.602f, 10.940f, 11.164f, 11.942f, 12.556f, 12.425f, 11.665f, 13.241f, 12.703f, - 13.440f, 13.603f, 13.621f, 14.212f, 14.531f, 14.115f, 14.179f, 14.100f, 13.420f, 13.875f, - 14.635f, 15.338f, 15.880f, 15.779f, 12.678f, 15.450f, 24.460f, 31.969f, 31.575f, 31.677f, - 28.332f, 17.668f, 11.924f, 12.133f, 12.603f, 11.414f, 11.955f, 14.172f, 15.982f, 17.122f, - 18.048f, 19.095f, 24.361f, 26.881f, 26.670f, 27.074f, 26.218f, 21.663f, 8.879f, 2.233f, - -2.569f, -8.607f,-10.265f,-11.492f,-14.670f,-15.269f,-16.872f,-18.741f,-20.030f,-26.542f, --26.136f,-28.532f,-31.906f,-30.369f,-34.474f,-38.978f,-43.671f,-44.466f,-45.423f,-46.324f, --46.466f,-43.594f,-43.204f,-44.186f,-41.492f,-39.744f,-40.296f,-39.009f,-37.211f,-35.499f, --34.671f,-33.240f,-32.894f,-33.550f,-34.098f,-34.044f,-33.849f,-34.863f,-34.535f,-36.958f, --37.730f,-37.314f,-38.641f,-39.095f,-39.166f,-38.613f,-38.899f,-38.550f,-36.573f,-34.416f, --31.920f,-30.756f,-28.570f,-31.190f,-29.379f,-26.423f,-25.997f,-23.690f,-20.599f,-16.884f, --10.755f, -4.083f, 0.615f, 3.904f, 8.389f, 12.036f, 11.192f, 9.441f, 8.750f, 8.475f, - 13.902f, 17.351f, 20.875f, 18.253f, 18.568f, 18.490f, 17.733f, 17.262f, 17.247f, 15.715f, - 13.606f -},{ --29.534f,-29.104f,-26.669f,-25.799f,-26.888f,-27.659f,-26.983f,-27.901f,-28.516f,-26.389f, --23.467f,-22.673f,-21.408f,-21.229f,-17.453f,-11.667f, -9.612f, -9.340f, -7.260f, -6.240f, - -3.831f, -2.539f, -2.912f, -2.025f, -1.937f, 0.300f, 1.187f, 1.891f, 2.269f, 1.864f, - 2.254f, 2.981f, 3.712f, 4.559f, 5.112f, 3.359f, 3.676f, 9.078f, 12.788f, 13.698f, - 13.496f, 14.709f, 15.004f, 13.460f, 14.942f, 13.389f, 12.349f, 11.704f, 11.752f, 11.317f, - 9.575f, 9.342f, 8.839f, 9.475f, 11.155f, 12.814f, 14.020f, 13.543f, 14.572f, 14.432f, - 14.665f, 15.317f, 15.264f, 16.200f, 15.778f, 16.565f, 15.758f, 15.874f, 15.699f, 15.778f, - 16.493f, 17.218f, 16.978f, 14.125f, 15.241f, 30.370f, 37.657f, 35.765f, 32.546f, 30.958f, - 26.513f, 19.218f, 14.606f, 16.228f, 14.569f, 14.610f, 15.957f, 18.079f, 18.872f, 18.671f, - 19.591f, 19.666f, 19.699f, 18.380f, 17.578f, 23.061f, 20.064f, 14.158f, 4.214f, -2.232f, - -4.783f, -8.867f,-16.480f,-16.899f,-17.714f,-17.959f,-19.330f,-21.061f,-22.868f,-27.496f, --27.440f,-34.213f,-36.796f,-36.005f,-39.141f,-43.279f,-43.199f,-43.823f,-45.416f,-45.885f, --45.821f,-44.410f,-45.971f,-47.554f,-46.960f,-42.778f,-39.912f,-38.591f,-37.491f,-36.329f, --34.040f,-33.950f,-30.580f,-32.079f,-30.870f,-32.075f,-33.102f,-33.938f,-33.445f,-35.790f, --35.735f,-35.682f,-36.308f,-36.758f,-37.005f,-36.608f,-36.959f,-36.713f,-34.855f,-32.752f, --29.931f,-28.520f,-27.072f,-29.377f,-27.798f,-24.864f,-24.243f,-22.136f,-18.618f,-14.227f, - -7.833f, -2.148f, 1.351f, 6.148f, 10.873f, 13.871f, 12.398f, 9.741f, 8.705f, 7.626f, - 12.802f, 18.192f, 21.375f, 18.475f, 18.902f, 18.715f, 17.900f, 17.383f, 17.349f, 15.737f, - 13.606f -},{ --29.534f,-29.048f,-26.591f,-25.562f,-26.291f,-27.163f,-26.498f,-27.896f,-28.310f,-25.865f, --23.338f,-22.430f,-20.960f,-20.446f,-17.571f,-10.436f, -8.286f, -8.379f, -5.647f, -4.484f, - -3.088f, -1.633f, -0.641f, -0.587f, -0.438f, 1.304f, 2.389f, 2.874f, 3.450f, 3.349f, - 4.024f, 4.352f, 4.949f, 5.868f, 4.961f, 3.454f, 8.809f, 11.276f, 13.084f, 14.942f, - 15.815f, 16.335f, 15.561f, 17.947f, 17.583f, 16.116f, 13.930f, 14.558f, 15.742f, 15.713f, - 13.400f, 12.994f, 14.327f, 12.411f, 9.047f, 9.523f, 13.314f, 15.189f, 15.667f, 15.872f, - 15.745f, 16.733f, 16.743f, 17.726f, 17.436f, 18.184f, 18.248f, 17.622f, 17.240f, 17.950f, - 18.283f, 18.825f, 17.399f, 11.838f, 30.432f, 38.459f, 37.101f, 34.334f, 30.987f, 28.697f, - 23.260f, 20.675f, 20.568f, 20.244f, 17.763f, 18.557f, 19.968f, 20.343f, 19.527f, 19.657f, - 20.685f, 22.215f, 20.394f, 17.507f, 18.950f, 21.723f, 13.390f, 4.358f, 1.792f, -1.771f, - -4.390f, 0.010f,-20.105f,-21.884f,-20.811f,-21.000f,-22.735f,-25.496f,-24.847f,-27.188f, --35.951f,-41.624f,-37.785f,-39.063f,-43.020f,-44.446f,-45.257f,-45.183f,-45.907f,-46.761f, --46.822f,-48.331f,-49.992f,-49.582f,-47.775f,-45.232f,-42.979f,-41.888f,-38.857f,-37.024f, --33.760f,-32.312f,-32.012f,-31.517f,-29.181f,-29.968f,-32.514f,-32.685f,-32.739f,-34.675f, --34.540f,-34.293f,-34.345f,-34.288f,-34.676f,-34.506f,-35.086f,-34.850f,-33.317f,-31.106f, --28.113f,-26.520f,-25.359f,-27.720f,-25.809f,-23.133f,-22.590f,-21.016f,-16.532f,-11.411f, - -4.749f, -0.239f, 2.042f, 9.241f, 12.550f, 15.117f, 13.422f, 10.082f, 9.264f, 7.061f, - 11.528f, 18.910f, 21.481f, 18.792f, 19.177f, 18.950f, 18.059f, 17.511f, 17.457f, 15.757f, - 13.606f -},{ --29.534f,-28.993f,-26.520f,-25.338f,-25.660f,-26.605f,-26.007f,-27.747f,-27.983f,-25.407f, --23.293f,-22.105f,-20.171f,-19.338f,-17.526f, -9.298f, -6.989f, -7.133f, -3.932f, -2.523f, - -1.582f, 0.266f, 0.899f, 1.565f, 1.005f, 2.373f, 3.345f, 3.942f, 4.389f, 5.028f, - 5.644f, 5.838f, 6.756f, 6.453f, 4.506f, 6.869f, 11.568f, 10.147f, 12.689f, 14.837f, - 16.107f, 16.922f, 17.402f, 20.140f, 22.910f, 19.349f, 16.666f, 16.802f, 17.073f, 18.506f, - 17.317f, 16.970f, 19.892f, 20.647f, 18.537f, 11.735f, 8.441f, 10.331f, 12.447f, 13.300f, - 13.706f, 15.799f, 17.073f, 18.542f, 18.283f, 18.863f, 18.943f, 19.825f, 19.188f, 19.572f, - 20.196f, 20.589f, 13.443f, 18.983f, 38.486f, 43.637f, 40.306f, 36.390f, 31.445f, 27.833f, - 26.349f, 25.139f, 22.784f, 21.593f, 19.701f, 20.504f, 21.319f, 19.790f, 18.825f, 19.055f, - 18.982f, 20.860f, 20.087f, 16.084f, 10.216f, 13.210f, 20.135f, 11.383f, 4.407f, -2.013f, - -1.266f, -5.200f,-18.161f,-24.407f,-22.513f,-21.248f,-24.789f,-29.100f,-27.965f,-28.046f, --36.585f,-43.581f,-41.748f,-44.131f,-45.134f,-46.734f,-47.701f,-47.837f,-48.249f,-48.193f, --49.453f,-50.963f,-51.401f,-50.710f,-48.357f,-46.532f,-44.446f,-42.930f,-42.060f,-37.071f, --34.871f,-31.406f,-29.756f,-29.240f,-28.984f,-29.588f,-31.870f,-31.065f,-31.792f,-34.368f, --33.335f,-33.254f,-32.621f,-32.285f,-32.326f,-32.525f,-33.351f,-32.920f,-31.722f,-29.375f, --26.546f,-24.772f,-24.250f,-25.980f,-23.077f,-20.943f,-20.522f,-18.985f,-14.321f, -8.851f, - -2.459f, 1.414f, 3.946f, 11.652f, 13.631f, 16.256f, 14.128f, 10.542f, 10.444f, 6.829f, - 10.145f, 19.218f, 21.193f, 19.151f, 19.395f, 19.197f, 18.212f, 17.648f, 17.573f, 15.774f, - 13.606f -},{ --29.534f,-28.939f,-26.457f,-25.129f,-25.023f,-25.977f,-25.509f,-27.429f,-27.623f,-25.107f, --23.118f,-21.521f,-19.383f,-18.658f,-16.568f, -8.091f, -6.090f, -5.325f, -2.102f, -1.354f, - 0.296f, 2.747f, 2.138f, 3.679f, 2.439f, 3.673f, 4.459f, 5.023f, 5.711f, 6.615f, - 6.633f, 7.355f, 8.417f, 7.463f, 4.303f, 9.641f, 10.327f, 10.464f, 10.722f, 12.613f, - 13.684f, 16.049f, 17.753f, 19.988f, 23.445f, 18.874f, 18.079f, 19.864f, 20.066f, 21.453f, - 21.500f, 20.480f, 20.896f, 20.842f, 20.712f, 20.708f, 19.159f, 14.902f, 14.622f, 16.796f, - 15.168f, 14.101f, 12.947f, 13.359f, 15.638f, 16.471f, 17.135f, 18.414f, 19.501f, 20.040f, - 18.781f, 13.866f, 18.076f, 30.436f, 42.364f, 45.825f, 44.807f, 41.484f, 30.952f, 26.232f, - 26.310f, 24.918f, 23.560f, 23.261f, 22.206f, 21.102f, 20.848f, 19.189f, 17.022f, 16.792f, - 18.562f, 20.357f, 17.544f, 11.822f, 6.286f, 2.666f, 5.787f, 3.184f, 0.044f,-11.214f, --12.556f,-12.780f,-15.614f,-25.857f,-24.877f,-23.969f,-27.042f,-30.074f,-29.335f,-27.275f, --41.133f,-45.523f,-42.849f,-46.704f,-47.559f,-48.790f,-49.634f,-49.984f,-50.339f,-50.711f, --51.485f,-51.653f,-51.360f,-50.552f,-48.581f,-46.201f,-44.346f,-42.502f,-42.026f,-39.413f, --34.677f,-32.153f,-29.952f,-28.223f,-27.949f,-28.049f,-28.841f,-29.195f,-29.937f,-33.111f, --31.388f,-32.064f,-31.039f,-30.382f,-30.714f,-30.932f,-31.339f,-31.026f,-29.708f,-27.862f, --25.334f,-23.865f,-24.414f,-23.308f,-19.839f,-18.630f,-18.303f,-16.323f,-11.824f, -6.354f, - -0.692f, 2.300f, 6.708f, 12.766f, 14.513f, 17.160f, 14.470f, 11.340f, 12.102f, 7.041f, - 8.811f, 18.929f, 20.655f, 19.487f, 19.574f, 19.452f, 18.366f, 17.798f, 17.694f, 15.790f, - 13.606f -},{ --29.534f,-28.886f,-26.403f,-24.934f,-24.410f,-25.286f,-25.015f,-26.984f,-27.309f,-24.936f, --22.709f,-20.710f,-18.919f,-18.487f,-14.845f, -7.039f, -5.590f, -3.401f, -0.047f, 0.394f, - 2.152f, 3.977f, 3.386f, 4.792f, 4.838f, 4.817f, 5.673f, 6.227f, 7.113f, 8.103f, - 8.065f, 9.260f, 9.862f, 8.198f, 6.096f, 10.882f, 9.264f, 8.916f, 9.546f, 10.834f, - 12.879f, 14.583f, 15.690f, 17.482f, 18.753f, 17.759f, 18.037f, 20.016f, 21.224f, 22.141f, - 23.292f, 24.361f, 24.476f, 25.297f, 24.786f, 24.837f, 25.003f, 26.202f, 29.447f, 31.432f, - 32.594f, 30.768f, 25.786f, 22.669f, 20.212f, 18.319f, 16.955f, 15.033f, 14.598f, 15.553f, - 15.762f, 20.387f, 27.481f, 39.357f, 45.051f, 46.533f, 49.123f, 36.632f, 27.868f, 27.028f, - 27.267f, 26.175f, 25.617f, 23.608f, 23.119f, 21.533f, 20.274f, 17.787f, 15.527f, 15.475f, - 16.978f, 17.421f, 13.822f, 8.811f, 4.492f, -0.250f, -3.132f, -4.780f, -5.145f, -4.599f, --14.191f,-17.356f,-21.502f,-26.388f,-29.353f,-28.213f,-29.246f,-32.862f,-33.755f,-28.882f, --44.850f,-44.019f,-48.933f,-48.922f,-49.726f,-50.842f,-51.425f,-51.600f,-51.755f,-51.982f, --52.131f,-51.554f,-50.766f,-49.768f,-48.050f,-45.846f,-43.984f,-42.753f,-41.276f,-39.839f, --34.895f,-31.583f,-29.321f,-27.380f,-27.494f,-26.505f,-27.580f,-27.942f,-27.643f,-29.618f, --28.849f,-29.365f,-29.721f,-28.846f,-28.638f,-28.628f,-29.394f,-29.193f,-28.362f,-27.010f, --24.294f,-23.018f,-23.163f,-19.568f,-16.167f,-16.301f,-16.029f,-13.651f, -8.677f, -3.902f, - 1.281f, 2.579f, 8.986f, 13.221f, 15.267f, 17.691f, 14.726f, 12.576f, 13.949f, 7.816f, - 7.768f, 18.024f, 20.082f, 19.744f, 19.736f, 19.707f, 18.532f, 17.963f, 17.819f, 15.803f, - 13.606f -},{ --29.534f,-28.835f,-26.358f,-24.754f,-23.851f,-24.557f,-24.555f,-26.496f,-27.069f,-24.758f, --22.141f,-19.972f,-18.797f,-18.335f,-13.273f, -6.250f, -4.790f, -2.037f, 1.621f, 2.757f, - 3.688f, 4.571f, 4.937f, 6.190f, 7.394f, 6.204f, 6.875f, 7.623f, 8.496f, 9.364f, - 9.433f, 11.237f, 11.070f, 8.081f, 11.438f, 12.736f, 9.695f, 9.334f, 9.302f, 10.376f, - 11.452f, 12.911f, 15.223f, 15.780f, 16.085f, 16.927f, 18.771f, 20.285f, 21.697f, 22.547f, - 22.746f, 22.664f, 23.923f, 25.345f, 26.959f, 30.058f, 31.957f, 31.814f, 32.281f, 33.246f, - 36.671f, 37.574f, 35.090f, 34.594f, 34.258f, 35.752f, 32.146f, 33.283f, 33.308f, 31.616f, - 33.577f, 35.431f, 38.298f, 44.503f, 45.456f, 46.584f, 44.159f, 31.042f, 27.473f, 28.394f, - 27.401f, 26.406f, 24.246f, 22.700f, 22.652f, 19.600f, 18.205f, 16.642f, 14.994f, 14.154f, - 13.712f, 13.683f, 10.702f, 5.827f, 1.869f, -1.564f, -4.634f, -7.014f, -8.780f, -8.479f, --10.821f,-16.701f,-22.703f,-30.007f,-32.964f,-30.155f,-31.468f,-37.650f,-38.171f,-35.709f, --47.155f,-48.024f,-50.740f,-50.376f,-51.199f,-52.148f,-52.543f,-52.099f,-51.822f,-51.881f, --51.679f,-51.071f,-49.966f,-48.581f,-47.192f,-45.200f,-43.114f,-42.471f,-40.926f,-38.779f, --34.597f,-30.688f,-28.453f,-26.730f,-26.505f,-26.190f,-26.106f,-27.748f,-27.507f,-26.881f, --26.294f,-25.969f,-28.200f,-26.928f,-26.518f,-26.231f,-27.474f,-28.072f,-28.163f,-26.465f, --23.101f,-21.837f,-21.056f,-15.822f,-13.286f,-13.472f,-13.493f,-10.362f, -5.340f, -1.888f, - 2.847f, 3.268f, 10.356f, 13.506f, 15.740f, 18.173f, 15.212f, 14.105f, 15.684f, 9.134f, - 7.236f, 16.643f, 19.653f, 19.898f, 19.905f, 19.956f, 18.721f, 18.146f, 17.947f, 15.814f, - 13.606f -},{ --29.534f,-28.785f,-26.322f,-24.589f,-23.372f,-23.842f,-24.177f,-26.069f,-26.868f,-24.436f, --21.600f,-19.600f,-18.720f,-17.790f,-12.554f, -5.534f, -3.349f, -1.100f, 2.293f, 3.826f, - 5.080f, 5.922f, 6.409f, 8.352f, 9.203f, 8.375f, 8.277f, 8.831f, 9.900f, 10.608f, - 11.653f, 12.480f, 12.509f, 9.020f, 14.435f, 13.628f, 11.675f, 10.801f, 9.861f, 9.808f, - 10.392f, 11.900f, 13.865f, 14.474f, 15.133f, 15.847f, 17.541f, 20.329f, 23.061f, 23.980f, - 22.671f, 20.329f, 21.223f, 22.925f, 26.192f, 25.802f, 24.428f, 22.758f, 25.622f, 26.964f, - 31.787f, 35.160f, 38.266f, 41.244f, 40.663f, 38.421f, 34.178f, 36.310f, 36.830f, 37.887f, - 41.781f, 43.511f, 44.400f, 44.558f, 45.605f, 44.522f, 33.725f, 30.175f, 28.817f, 27.692f, - 26.278f, 24.359f, 22.424f, 22.146f, 21.279f, 18.738f, 16.266f, 14.310f, 13.608f, 12.057f, - 10.630f, 10.283f, 7.759f, 3.053f, -1.062f, -4.799f, -7.139f, -8.371f, -9.881f,-11.709f, --13.484f,-17.275f,-24.595f,-34.747f,-34.773f,-31.982f,-33.913f,-41.444f,-41.289f,-44.231f, --51.000f,-51.175f,-50.708f,-51.026f,-52.034f,-52.419f,-52.244f,-51.619f,-51.325f,-51.175f, --50.664f,-49.681f,-48.404f,-47.319f,-46.091f,-44.585f,-42.972f,-42.198f,-40.643f,-38.252f, --34.265f,-31.055f,-28.266f,-26.533f,-25.678f,-25.536f,-24.801f,-25.762f,-26.919f,-26.774f, --25.004f,-24.157f,-25.939f,-24.921f,-24.391f,-24.467f,-26.361f,-26.582f,-25.796f,-24.197f, --21.465f,-21.136f,-19.181f,-12.803f,-11.370f,-10.569f,-10.655f, -6.799f, -2.283f, -0.149f, - 3.569f, 5.104f, 11.222f, 13.664f, 15.944f, 18.804f, 15.881f, 15.705f, 17.146f, 10.777f, - 7.300f, 15.040f, 19.426f, 19.961f, 20.101f, 20.189f, 18.944f, 18.347f, 18.076f, 15.823f, - 13.606f -},{ --29.534f,-28.737f,-26.295f,-24.443f,-22.996f,-23.206f,-23.937f,-25.783f,-26.634f,-23.935f, --21.228f,-19.589f,-18.392f,-17.016f,-12.687f, -4.930f, -1.912f, 0.096f, 2.783f, 4.647f, - 7.317f, 7.494f, 7.005f, 9.283f, 10.436f, 10.970f, 9.663f, 10.310f, 11.516f, 12.080f, - 13.362f, 13.451f, 13.369f, 12.182f, 14.777f, 13.788f, 12.190f, 12.033f, 10.293f, 9.953f, - 10.430f, 11.547f, 11.604f, 13.036f, 14.371f, 14.694f, 16.010f, 18.932f, 22.721f, 23.298f, - 21.084f, 18.480f, 18.674f, 20.113f, 22.846f, 22.080f, 21.838f, 20.643f, 21.265f, 23.719f, - 27.033f, 31.142f, 34.975f, 41.047f, 42.812f, 41.184f, 39.763f, 40.278f, 43.256f, 42.778f, - 43.204f, 43.168f, 44.311f, 44.382f, 41.000f, 32.931f, 31.139f, 30.547f, 29.323f, 27.152f, - 24.797f, 22.609f, 20.125f, 18.840f, 17.754f, 15.149f, 12.639f, 10.374f, 10.136f, 8.408f, - 6.960f, 6.100f, 4.223f, 1.233f, -3.363f, -6.499f, -9.549f, -9.890f,-10.862f,-12.699f, --15.501f,-21.616f,-25.702f,-38.362f,-36.087f,-34.686f,-36.669f,-42.986f,-45.442f,-55.379f, --58.834f,-51.247f,-50.577f,-51.406f,-52.340f,-51.653f,-51.321f,-50.518f,-49.941f,-49.485f, --48.738f,-47.719f,-46.804f,-45.872f,-44.701f,-43.838f,-42.056f,-41.646f,-40.611f,-37.976f, --34.364f,-29.408f,-26.892f,-25.625f,-24.262f,-24.677f,-24.547f,-24.224f,-24.187f,-26.173f, --23.567f,-22.325f,-22.760f,-23.464f,-22.571f,-22.792f,-24.551f,-23.426f,-22.284f,-21.030f, --19.486f,-20.236f,-16.441f,-10.835f, -8.344f, -7.986f, -8.059f, -3.459f, 0.335f, 0.661f, - 3.997f, 7.560f, 11.890f, 14.060f, 16.211f, 19.240f, 16.433f, 17.255f, 18.355f, 12.454f, - 7.888f, 13.500f, 19.318f, 19.967f, 20.329f, 20.402f, 19.213f, 18.566f, 18.202f, 15.829f, - 13.606f -},{ --29.534f,-28.692f,-26.277f,-24.316f,-22.737f,-22.719f,-23.879f,-25.673f,-26.313f,-23.362f, --21.036f,-19.628f,-17.808f,-16.569f,-13.346f, -5.041f, -1.162f, 1.471f, 4.021f, 7.186f, - 10.079f, 9.216f, 7.379f, 9.059f, 11.255f, 12.824f, 11.386f, 11.878f, 12.857f, 13.504f, - 14.765f, 14.927f, 14.603f, 13.808f, 15.627f, 14.157f, 12.319f, 12.228f, 10.336f, 9.969f, - 10.509f, 11.393f, 11.460f, 12.114f, 13.019f, 13.546f, 14.507f, 16.121f, 19.322f, 19.799f, - 18.592f, 17.235f, 17.644f, 17.882f, 19.764f, 20.908f, 22.359f, 22.800f, 23.826f, 25.283f, - 24.801f, 28.095f, 28.518f, 36.927f, 41.330f, 43.064f, 43.174f, 43.769f, 43.572f, 42.392f, - 43.169f, 44.059f, 45.042f, 42.720f, 31.677f, 27.297f, 28.831f, 31.129f, 29.829f, 26.514f, - 23.441f, 20.333f, 17.947f, 16.129f, 14.371f, 12.535f, 9.807f, 8.350f, 6.889f, 5.051f, - 3.378f, 1.808f, -0.146f, -3.252f, -6.014f, -4.548f, -7.880f,-11.551f,-12.615f,-14.897f, --16.594f,-23.257f,-29.506f,-39.973f,-36.596f,-36.897f,-39.281f,-44.461f,-42.476f,-62.241f, --62.227f,-51.252f,-51.049f,-51.920f,-51.809f,-50.944f,-50.222f,-49.136f,-48.462f,-47.996f, --46.792f,-45.960f,-45.149f,-44.076f,-43.486f,-42.181f,-40.878f,-40.214f,-39.737f,-37.951f, --34.336f,-28.126f,-26.276f,-24.416f,-23.539f,-23.708f,-23.634f,-21.932f,-22.297f,-23.657f, --23.501f,-21.204f,-20.139f,-22.185f,-21.085f,-20.500f,-20.808f,-19.618f,-19.305f,-17.913f, --16.880f,-17.851f,-13.022f, -8.640f, -4.428f, -6.275f, -4.957f, 1.297f, 1.995f, 0.754f, - 4.750f, 9.700f, 12.729f, 14.973f, 16.943f, 19.164f, 16.757f, 18.736f, 19.433f, 13.990f, - 8.835f, 12.272f, 19.166f, 19.959f, 20.583f, 20.594f, 19.533f, 18.799f, 18.324f, 15.834f, - 13.606f -},{ --29.534f,-28.648f,-26.268f,-24.212f,-22.599f,-22.443f,-24.024f,-25.718f,-25.907f,-22.896f, --20.918f,-19.399f,-17.230f,-16.710f,-14.256f, -6.427f, -1.029f, 2.317f, 5.567f, 9.763f, - 11.917f, 11.297f, 7.964f, 9.411f, 12.152f, 13.833f, 13.871f, 13.421f, 14.171f, 15.426f, - 15.823f, 16.024f, 15.093f, 13.245f, 14.310f, 13.538f, 11.918f, 12.333f, 11.143f, 10.815f, - 10.537f, 10.904f, 11.499f, 11.607f, 11.730f, 12.308f, 13.593f, 14.253f, 15.734f, 16.255f, - 16.347f, 15.859f, 16.057f, 17.432f, 18.696f, 20.215f, 22.826f, 25.473f, 25.296f, 25.039f, - 23.801f, 25.633f, 29.066f, 35.922f, 36.121f, 38.966f, 43.192f, 43.434f, 42.001f, 42.917f, - 43.597f, 43.292f, 41.421f, 36.123f, 24.888f, 26.508f, 29.353f, 29.194f, 26.998f, 24.436f, - 21.391f, 17.301f, 14.548f, 13.031f, 11.659f, 9.912f, 7.669f, 6.005f, 4.862f, 2.122f, - 0.443f, 1.153f, -1.367f, -6.318f, -6.781f, -8.402f, -6.216f,-10.463f,-14.433f,-18.330f, --22.521f,-26.063f,-33.884f,-40.277f,-37.206f,-37.740f,-40.739f,-45.229f,-41.688f,-60.947f, --64.611f,-52.113f,-51.537f,-51.783f,-51.497f,-50.637f,-49.940f,-48.700f,-47.625f,-46.960f, --45.704f,-44.824f,-43.412f,-42.202f,-41.678f,-40.329f,-39.151f,-38.541f,-37.766f,-36.638f, --33.813f,-30.041f,-25.396f,-24.900f,-23.342f,-22.650f,-21.945f,-20.934f,-20.796f,-20.041f, --22.518f,-19.865f,-18.496f,-19.235f,-20.017f,-17.478f,-16.955f,-16.432f,-15.759f,-14.825f, --13.087f,-13.422f, -9.334f, -5.760f, -2.366f, -5.160f, -0.638f, 6.181f, 3.427f, 3.618f, - 6.817f, 11.589f, 14.067f, 15.989f, 18.230f, 18.752f, 17.045f, 20.112f, 20.492f, 15.408f, - 9.987f, 11.525f, 18.825f, 19.966f, 20.847f, 20.766f, 19.904f, 19.042f, 18.439f, 15.836f, - 13.606f -},{ --29.534f,-28.606f,-26.267f,-24.133f,-22.578f,-22.416f,-24.348f,-25.848f,-25.482f,-22.680f, --20.763f,-18.871f,-16.912f,-17.038f,-15.045f, -8.713f, -1.342f, 2.619f, 6.757f, 10.698f, - 12.976f, 12.173f, 8.485f, 9.875f, 12.880f, 14.783f, 16.133f, 14.442f, 15.335f, 16.941f, - 16.620f, 16.791f, 15.958f, 14.292f, 13.186f, 12.251f, 10.988f, 12.620f, 12.392f, 12.306f, - 11.345f, 10.911f, 11.437f, 11.548f, 11.653f, 11.925f, 12.121f, 13.037f, 14.114f, 14.143f, - 14.687f, 14.413f, 15.546f, 17.173f, 18.039f, 19.665f, 21.803f, 25.167f, 26.677f, 26.579f, - 23.945f, 25.821f, 26.559f, 26.365f, 29.347f, 29.307f, 30.769f, 37.253f, 38.888f, 39.661f, - 41.768f, 39.149f, 37.528f, 24.885f, 22.161f, 26.042f, 28.379f, 26.835f, 22.973f, 20.896f, - 18.491f, 13.779f, 10.933f, 9.434f, 7.671f, 6.069f, 3.609f, 2.003f, 0.894f, -0.655f, - -2.263f, -1.309f, -4.061f, -6.957f, -7.578f, -8.739f, -7.294f,-11.854f,-17.918f,-23.030f, --28.268f,-29.860f,-35.898f,-36.670f,-37.385f,-39.787f,-42.138f,-45.195f,-45.061f,-55.453f, --62.910f,-51.842f,-51.870f,-52.343f,-51.908f,-51.108f,-50.025f,-48.765f,-47.342f,-46.078f, --44.846f,-43.287f,-36.970f,-39.560f,-39.510f,-38.623f,-37.712f,-36.781f,-35.835f,-35.697f, --33.864f,-30.636f,-26.644f,-23.290f,-23.373f,-21.990f,-20.162f,-20.432f,-19.950f,-18.923f, --22.686f,-18.655f,-17.349f,-17.608f,-18.441f,-16.154f,-14.742f,-13.340f,-11.956f,-11.016f, - -8.422f, -7.775f, -5.407f, -3.618f, -1.804f, -2.351f, 3.416f, 7.642f, 5.990f, 9.371f, - 10.390f, 13.675f, 15.596f, 17.129f, 19.680f, 18.246f, 17.480f, 21.296f, 21.582f, 16.817f, - 11.250f, 11.330f, 18.244f, 19.997f, 21.100f, 20.926f, 20.318f, 19.291f, 18.545f, 15.835f, - 13.606f -},{ --29.534f,-28.567f,-26.275f,-24.084f,-22.659f,-22.639f,-24.788f,-25.974f,-25.137f,-22.735f, --20.542f,-18.309f,-16.888f,-16.889f,-15.160f,-10.606f, -2.430f, 2.596f, 7.070f, 10.820f, - 13.233f, 11.016f, 9.205f, 10.557f, 13.783f, 15.330f, 17.350f, 14.870f, 15.141f, 17.274f, - 17.402f, 17.151f, 16.203f, 15.257f, 13.789f, 11.280f, 9.979f, 12.786f, 13.174f, 13.331f, - 12.073f, 11.270f, 11.377f, 11.333f, 11.923f, 11.909f, 11.396f, 12.718f, 13.293f, 13.580f, - 14.091f, 13.883f, 15.218f, 16.849f, 17.715f, 18.851f, 21.204f, 23.351f, 24.522f, 25.669f, - 25.597f, 24.422f, 24.078f, 24.739f, 26.572f, 26.651f, 26.556f, 24.723f, 27.491f, 29.388f, - 29.757f, 30.252f, 30.405f, 21.083f, 22.306f, 25.316f, 24.806f, 23.899f, 20.833f, 19.397f, - 15.913f, 12.030f, 10.018f, 7.034f, 3.120f, 0.157f, -1.706f, -1.729f, -2.179f, -3.385f, - -4.676f, -5.896f, -6.485f, -6.293f, -8.586f, -9.954f,-13.159f,-15.579f,-21.433f,-29.188f, --31.586f,-29.996f,-32.125f,-35.319f,-37.459f,-39.122f,-41.603f,-43.350f,-45.685f,-55.498f, --59.238f,-51.376f,-52.095f,-52.585f,-52.190f,-51.316f,-50.060f,-48.863f,-47.165f,-45.280f, --43.489f,-41.733f,-39.526f,-38.323f,-38.046f,-37.488f,-36.823f,-35.117f,-34.389f,-33.157f, --32.802f,-29.664f,-26.292f,-22.192f,-22.941f,-21.141f,-19.373f,-19.402f,-19.348f,-19.973f, --20.580f,-17.678f,-16.125f,-16.314f,-17.599f,-14.798f,-12.521f,-10.518f, -9.121f, -7.179f, - -4.864f, -2.945f, -0.931f, -1.488f, -1.412f, 1.061f, 6.444f, 7.310f, 9.118f, 13.256f, - 13.794f, 15.661f, 16.976f, 19.336f, 20.570f, 17.600f, 18.046f, 22.229f, 22.695f, 18.250f, - 12.592f, 11.670f, 17.494f, 20.042f, 21.326f, 21.081f, 20.763f, 19.537f, 18.638f, 15.833f, - 13.606f -},{ --29.534f,-28.530f,-26.289f,-24.067f,-22.822f,-23.074f,-25.243f,-26.004f,-24.954f,-22.968f, --20.329f,-18.010f,-16.983f,-16.080f,-14.354f,-11.074f, -4.372f, 1.518f, 5.604f, 9.984f, - 11.130f, 9.221f, 9.324f, 11.783f, 15.313f, 16.393f, 17.994f, 15.460f, 14.392f, 17.931f, - 17.766f, 17.798f, 17.050f, 16.186f, 14.665f, 11.515f, 9.384f, 12.415f, 13.696f, 13.271f, - 12.962f, 11.571f, 11.293f, 11.556f, 11.560f, 11.252f, 11.387f, 11.924f, 12.642f, 12.695f, - 13.248f, 13.815f, 15.776f, 16.561f, 17.676f, 18.153f, 19.402f, 20.306f, 21.609f, 21.710f, - 22.552f, 23.592f, 23.874f, 24.158f, 25.487f, 25.650f, 23.895f, 23.543f, 23.224f, 22.405f, - 23.164f, 21.987f, 21.613f, 22.600f, 23.897f, 22.409f, 21.131f, 20.606f, 19.409f, 17.875f, - 14.459f, 10.986f, 8.117f, 4.341f, 0.799f, -3.252f, -5.498f, -4.423f, -4.920f, -5.905f, - -6.858f, -7.891f, -8.608f,-10.162f,-11.773f,-15.171f,-17.218f,-20.913f,-24.764f,-33.321f, --40.218f,-32.558f,-37.926f,-38.209f,-37.749f,-39.674f,-41.374f,-41.771f,-42.948f,-60.784f, --57.270f,-50.777f,-51.615f,-52.626f,-52.651f,-51.871f,-50.845f,-49.465f,-47.085f,-44.666f, --42.338f,-40.468f,-38.564f,-37.549f,-36.677f,-36.140f,-35.448f,-33.586f,-32.200f,-32.105f, --31.325f,-28.603f,-26.253f,-21.537f,-21.334f,-19.552f,-18.210f,-18.059f,-17.878f,-19.545f, --19.043f,-16.537f,-14.713f,-15.086f,-16.179f,-13.377f,-10.872f, -9.945f, -7.780f, -4.723f, - -1.720f, -0.118f, 2.316f, 2.019f, 0.900f, 2.885f, 7.608f, 8.245f, 11.916f, 14.700f, - 16.262f, 17.389f, 18.572f, 22.307f, 20.306f, 16.928f, 18.661f, 22.917f, 23.777f, 19.619f, - 14.001f, 12.457f, 16.732f, 20.081f, 21.518f, 21.237f, 21.216f, 19.774f, 18.716f, 15.829f, - 13.606f -},{ --29.534f,-28.496f,-26.311f,-24.085f,-23.039f,-23.649f,-25.603f,-25.875f,-24.956f,-23.254f, --20.240f,-18.050f,-16.978f,-15.101f,-13.134f,-10.398f, -6.265f, -1.004f, 2.747f, 7.641f, - 7.672f, 8.032f, 8.583f, 11.933f, 15.642f, 17.580f, 18.427f, 17.008f, 14.181f, 18.376f, - 18.400f, 18.596f, 18.423f, 16.737f, 15.861f, 13.041f, 10.268f, 12.092f, 13.865f, 11.770f, - 12.893f, 11.437f, 11.080f, 11.408f, 11.037f, 11.030f, 11.070f, 11.498f, 12.303f, 12.695f, - 13.045f, 14.071f, 15.137f, 16.258f, 17.535f, 17.756f, 18.144f, 18.842f, 19.536f, 19.591f, - 21.223f, 22.161f, 23.221f, 23.766f, 24.648f, 25.294f, 23.942f, 22.578f, 21.411f, 22.815f, - 23.578f, 23.056f, 21.602f, 22.273f, 22.418f, 19.983f, 18.807f, 18.690f, 18.370f, 14.753f, - 11.129f, 7.724f, 4.420f, 1.221f, -1.586f, -4.368f, -5.696f, -7.226f, -7.397f, -7.530f, - -8.360f, -9.232f,-10.063f,-12.689f,-14.322f,-13.388f,-16.488f,-23.619f,-26.905f,-35.211f, --45.096f,-38.578f,-38.030f,-41.799f,-41.252f,-42.056f,-41.163f,-40.995f,-49.142f,-62.033f, --52.976f,-50.517f,-51.085f,-52.189f,-52.322f,-51.793f,-50.874f,-49.377f,-46.861f,-44.355f, --41.707f,-39.558f,-37.366f,-36.328f,-35.238f,-34.277f,-33.477f,-32.017f,-30.488f,-30.515f, --29.890f,-28.269f,-26.344f,-20.962f,-19.435f,-18.198f,-16.869f,-17.173f,-16.749f,-17.795f, --17.905f,-15.208f,-12.814f,-13.859f,-14.652f,-12.245f, -9.960f, -8.975f, -6.982f, -1.421f, - 1.241f, 2.905f, 6.036f, 6.855f, 6.745f, 6.037f, 8.528f, 11.162f, 14.446f, 16.286f, - 18.736f, 19.477f, 20.672f, 23.697f, 19.068f, 16.791f, 19.307f, 23.394f, 24.757f, 20.810f, - 15.466f, 13.563f, 16.126f, 20.104f, 21.687f, 21.397f, 21.653f, 19.993f, 18.778f, 15.822f, - 13.606f -},{ --29.534f,-28.464f,-26.339f,-24.140f,-23.286f,-24.267f,-25.768f,-25.562f,-25.096f,-23.525f, --20.355f,-18.257f,-16.763f,-14.533f,-12.359f, -9.756f, -7.149f, -3.493f, 0.590f, 5.289f, - 5.797f, 7.286f, 8.478f, 11.428f, 15.094f, 17.672f, 19.405f, 19.377f, 15.067f, 17.894f, - 19.026f, 19.604f, 19.051f, 17.810f, 16.770f, 15.209f, 10.938f, 11.289f, 13.526f, 12.204f, - 12.710f, 11.302f, 11.000f, 11.373f, 10.266f, 10.798f, 11.095f, 11.734f, 12.425f, 13.462f, - 13.519f, 13.422f, 14.370f, 16.598f, 16.991f, 17.320f, 17.264f, 17.511f, 17.860f, 17.937f, - 19.125f, 20.146f, 21.333f, 22.292f, 22.900f, 23.255f, 22.887f, 21.079f, 20.519f, 20.963f, - 22.116f, 21.506f, 21.856f, 21.642f, 21.071f, 19.117f, 17.640f, 17.040f, 15.249f, 11.055f, - 7.234f, 4.106f, 1.316f, -1.643f, -4.513f, -5.922f, -6.824f, -9.328f, -9.462f, -9.076f, - -9.969f,-11.327f,-11.925f,-14.430f,-15.493f,-14.123f,-18.842f,-25.891f,-28.803f,-34.196f, --42.514f,-41.798f,-42.985f,-38.744f,-39.031f,-40.270f,-42.406f,-55.832f,-61.905f,-57.375f, --49.849f,-49.740f,-50.228f,-51.183f,-51.476f,-50.726f,-49.790f,-48.701f,-46.402f,-43.955f, --41.213f,-38.930f,-36.537f,-35.175f,-34.274f,-32.535f,-31.382f,-30.620f,-28.407f,-27.424f, --28.505f,-27.223f,-25.892f,-20.950f,-18.036f,-17.432f,-14.592f,-15.041f,-15.639f,-16.150f, --15.661f,-13.137f,-10.046f,-10.465f,-12.864f,-10.759f, -9.082f, -6.818f, -2.774f, 2.748f, - 3.512f, 6.180f, 9.512f, 10.087f, 11.569f, 11.805f, 12.763f, 15.159f, 16.569f, 18.127f, - 21.210f, 22.026f, 22.842f, 22.319f, 17.971f, 17.579f, 19.965f, 23.702f, 25.597f, 21.821f, - 16.966f, 14.853f, 15.789f, 20.111f, 21.852f, 21.556f, 22.045f, 20.186f, 18.822f, 15.814f, - 13.606f -},{ --29.534f,-28.434f,-26.371f,-24.232f,-23.537f,-24.828f,-25.680f,-25.076f,-25.285f,-23.785f, --20.663f,-18.416f,-16.409f,-14.427f,-12.341f, -9.797f, -7.250f, -4.436f, -0.111f, 3.891f, - 5.219f, 6.519f, 8.632f, 11.376f, 14.811f, 18.101f, 20.685f, 20.743f, 17.722f, 16.616f, - 20.199f, 19.239f, 19.550f, 18.850f, 17.776f, 16.815f, 10.228f, 10.560f, 11.863f, 12.848f, - 12.383f, 10.814f, 9.990f, 9.467f, 8.724f, 8.724f, 9.861f, 11.498f, 12.209f, 12.620f, - 13.555f, 12.307f, 14.617f, 16.878f, 16.837f, 17.324f, 17.106f, 16.968f, 16.834f, 17.082f, - 17.789f, 18.655f, 19.847f, 20.510f, 21.241f, 21.055f, 20.271f, 19.473f, 20.184f, 20.900f, - 19.708f, 18.897f, 20.660f, 19.098f, 17.031f, 16.401f, 14.906f, 13.394f, 10.845f, 6.779f, - 3.321f, 0.947f, -1.339f, -3.585f, -6.176f, -7.632f, -7.818f,-11.888f,-12.022f,-11.809f, --12.627f,-14.435f,-15.525f,-17.488f,-18.296f,-18.916f,-22.718f,-27.301f,-29.505f,-33.221f, --41.849f,-46.452f,-49.391f,-48.076f,-46.629f,-55.380f,-61.322f,-62.025f,-57.849f,-51.697f, --47.213f,-48.882f,-49.747f,-50.355f,-50.164f,-49.447f,-48.606f,-47.684f,-45.631f,-42.905f, --40.795f,-38.646f,-36.520f,-34.764f,-33.319f,-31.304f,-30.299f,-28.497f,-27.554f,-26.889f, --26.955f,-25.678f,-24.451f,-20.026f,-14.615f,-15.398f,-13.244f,-13.535f,-14.214f,-13.761f, --12.755f,-10.279f, -7.756f, -6.961f, -9.152f, -8.263f, -6.280f, -1.238f, 3.266f, 4.905f, - 4.817f, 7.709f, 9.260f, 10.859f, 13.594f, 16.237f, 17.391f, 17.733f, 19.044f, 20.710f, - 22.996f, 24.228f, 24.553f, 20.224f, 18.133f, 18.941f, 20.621f, 23.946f, 26.330f, 22.763f, - 18.462f, 16.202f, 15.746f, 20.117f, 22.038f, 21.704f, 22.365f, 20.348f, 18.847f, 15.803f, - 13.606f -},{ --29.534f,-28.407f,-26.408f,-24.360f,-23.776f,-25.245f,-25.335f,-24.458f,-25.430f,-24.072f, --21.072f,-18.451f,-16.111f,-14.376f,-12.619f,-10.074f, -7.426f, -4.378f, -0.526f, 2.773f, - 4.359f, 6.146f, 8.428f, 11.226f, 14.202f, 18.429f, 21.061f, 21.634f, 20.660f, 15.639f, - 21.014f, 19.090f, 19.860f, 19.687f, 18.332f, 16.897f, 10.109f, 10.507f, 11.660f, 12.555f, - 11.900f, 10.266f, 8.441f, 6.789f, 5.423f, 4.965f, 6.350f, 9.003f, 11.606f, 12.388f, - 13.253f, 12.655f, 14.948f, 16.351f, 17.226f, 16.706f, 16.908f, 17.536f, 17.037f, 16.814f, - 17.135f, 17.325f, 18.243f, 18.919f, 19.113f, 19.083f, 18.424f, 17.817f, 17.745f, 18.210f, - 17.703f, 17.332f, 15.891f, 14.393f, 13.262f, 12.632f, 12.283f, 11.519f, 9.143f, 2.284f, - -0.813f, -2.526f, -4.134f, -6.177f, -8.757f,-10.613f, -9.710f,-14.652f,-15.147f,-15.125f, --15.817f,-16.977f,-18.970f,-20.265f,-22.017f,-23.649f,-26.133f,-28.582f,-31.021f,-35.691f, --41.013f,-44.963f,-49.045f,-48.433f,-53.415f,-55.591f,-54.690f,-52.918f,-50.897f,-48.248f, --46.111f,-47.174f,-48.756f,-49.020f,-48.833f,-48.238f,-47.359f,-46.242f,-44.315f,-41.732f, --39.582f,-37.660f,-35.792f,-33.823f,-32.046f,-30.433f,-28.682f,-27.504f,-26.697f,-25.494f, --24.943f,-23.848f,-22.915f,-19.752f,-12.825f,-12.812f,-11.602f,-11.001f, -8.642f, -9.638f, - -9.796f, -7.582f, -4.917f, -3.084f, -5.067f, -4.465f, -0.241f, 4.007f, 4.717f, 5.275f, - 6.908f, 9.235f, 10.175f, 12.072f, 14.919f, 17.583f, 19.477f, 19.391f, 22.299f, 23.868f, - 24.360f, 25.599f, 25.519f, 19.847f, 19.522f, 20.206f, 21.378f, 24.295f, 27.027f, 23.739f, - 19.893f, 17.515f, 15.946f, 20.146f, 22.268f, 21.826f, 22.591f, 20.473f, 18.851f, 15.791f, - 13.606f -},{ --29.534f,-28.383f,-26.446f,-24.521f,-23.994f,-25.465f,-24.786f,-23.764f,-25.472f,-24.389f, --21.451f,-18.433f,-16.028f,-14.110f,-12.621f, -9.987f, -7.736f, -4.475f, -1.000f, 1.932f, - 3.803f, 6.534f, 9.053f, 11.522f, 14.407f, 18.100f, 21.328f, 22.850f, 21.906f, 15.404f, - 20.660f, 19.967f, 20.264f, 19.632f, 18.874f, 17.958f, 10.312f, 10.478f, 11.746f, 12.657f, - 11.193f, 9.565f, 6.619f, 5.553f, 4.378f, 2.918f, 5.584f, 5.595f, 9.730f, 11.145f, - 12.948f, 13.080f, 14.912f, 15.302f, 17.038f, 15.920f, 16.511f, 17.484f, 17.074f, 16.102f, - 15.326f, 15.691f, 16.482f, 16.949f, 16.812f, 16.935f, 16.138f, 15.907f, 15.544f, 15.883f, - 16.492f, 15.735f, 13.272f, 10.411f, 8.639f, 7.977f, 10.168f, 11.066f, 8.129f, -1.908f, - -4.002f, -5.353f, -7.487f, -9.437f,-11.423f,-13.434f,-11.938f,-14.737f,-16.386f,-17.868f, --18.872f,-20.275f,-21.702f,-22.937f,-24.387f,-25.442f,-27.373f,-29.634f,-32.742f,-39.915f, --41.915f,-44.798f,-45.443f,-46.111f,-48.688f,-49.108f,-49.441f,-49.118f,-48.410f,-48.085f, --45.447f,-45.092f,-46.986f,-47.494f,-47.389f,-47.079f,-45.815f,-44.660f,-42.654f,-40.208f, --38.043f,-36.183f,-34.993f,-31.904f,-30.090f,-29.435f,-27.275f,-25.353f,-24.452f,-23.653f, --22.890f,-21.494f,-20.011f,-18.050f,-12.301f,-10.243f, -9.475f, -7.803f, -4.234f, -3.343f, - -5.082f, -4.925f, -1.147f, -0.265f, -1.217f, -0.997f, 5.314f, 5.630f, 6.309f, 7.277f, - 9.256f, 10.948f, 12.388f, 14.050f, 16.309f, 18.725f, 20.608f, 21.406f, 24.482f, 25.395f, - 25.777f, 26.442f, 25.639f, 21.004f, 21.155f, 21.156f, 22.427f, 24.872f, 27.718f, 24.737f, - 21.184f, 18.724f, 16.301f, 20.214f, 22.547f, 21.903f, 22.707f, 20.558f, 18.836f, 15.777f, - 13.606f -},{ --29.534f,-28.360f,-26.486f,-24.712f,-24.191f,-25.477f,-24.130f,-23.048f,-25.408f,-24.685f, --21.699f,-18.444f,-16.113f,-13.801f,-12.309f, -9.675f, -7.589f, -4.570f, -1.001f, 1.475f, - 3.523f, 6.761f, 9.857f, 12.372f, 15.444f, 18.084f, 21.431f, 23.632f, 22.234f, 16.447f, - 20.426f, 20.668f, 20.353f, 19.843f, 18.436f, 18.344f, 9.014f, 9.750f, 12.079f, 11.999f, - 10.503f, 8.653f, 4.975f, 3.781f, 2.246f, 1.645f, 2.415f, 3.502f, 5.790f, 9.444f, - 12.206f, 12.606f, 13.223f, 14.382f, 15.286f, 15.192f, 16.309f, 16.976f, 16.372f, 14.960f, - 13.996f, 13.772f, 13.965f, 14.612f, 14.297f, 13.305f, 12.679f, 13.017f, 14.108f, 13.861f, - 13.895f, 12.488f, 9.925f, 7.125f, 4.912f, 3.173f, 4.095f, 4.692f, 2.022f, -4.416f, - -3.940f, -7.695f,-10.443f,-12.303f,-13.664f,-15.777f,-16.489f,-14.881f,-17.194f,-20.209f, --21.303f,-23.003f,-24.060f,-25.607f,-26.886f,-27.337f,-28.235f,-30.513f,-35.046f,-40.224f, --44.354f,-47.397f,-48.004f,-47.447f,-48.250f,-49.513f,-46.050f,-49.355f,-47.013f,-47.377f, --46.130f,-44.366f,-45.322f,-45.958f,-45.797f,-45.147f,-43.894f,-42.784f,-40.736f,-38.351f, --36.460f,-34.880f,-33.563f,-30.907f,-29.118f,-27.237f,-25.859f,-23.613f,-22.436f,-21.652f, --20.761f,-19.133f,-16.691f,-13.933f,-10.826f, -6.615f, -5.876f, -3.928f, -1.501f, 1.619f, - 0.644f, -1.769f, 1.828f, 3.632f, 2.021f, 3.325f, 6.336f, 7.864f, 8.589f, 9.926f, - 11.257f, 13.325f, 14.705f, 16.150f, 18.747f, 20.498f, 21.681f, 22.930f, 25.184f, 26.111f, - 27.078f, 27.288f, 25.416f, 22.193f, 22.420f, 22.084f, 23.818f, 25.651f, 28.363f, 25.642f, - 22.289f, 19.791f, 16.725f, 20.326f, 22.869f, 21.920f, 22.706f, 20.602f, 18.801f, 15.762f, - 13.606f -},{ --29.534f,-28.340f,-26.525f,-24.925f,-24.374f,-25.315f,-23.486f,-22.358f,-25.267f,-24.891f, --21.792f,-18.481f,-16.134f,-13.731f,-12.030f, -9.565f, -6.988f, -4.130f, -0.857f, 0.665f, - 2.282f, 5.983f, 9.333f, 12.602f, 16.203f, 18.830f, 21.515f, 23.954f, 22.331f, 20.504f, - 20.183f, 20.654f, 20.012f, 19.899f, 17.482f, 16.638f, 7.479f, 8.184f, 11.427f, 10.762f, - 9.197f, 7.200f, 3.749f, 1.598f, 0.404f, 0.303f, 0.909f, 1.372f, 2.333f, 5.162f, - 9.582f, 10.733f, 11.023f, 12.219f, 12.741f, 13.508f, 15.564f, 15.850f, 15.465f, 14.532f, - 12.757f, 11.251f, 11.005f, 11.311f, 10.572f, 9.649f, 8.775f, 9.090f, 9.253f, 9.141f, - 8.976f, 8.064f, 5.950f, 3.976f, 1.893f, -0.150f, -1.536f, -2.332f, -4.608f, -8.972f, - -7.075f,-10.445f,-13.513f,-15.656f,-16.756f,-18.469f,-19.917f,-18.278f,-18.681f,-21.158f, --23.068f,-24.939f,-25.949f,-28.060f,-30.992f,-32.582f,-31.621f,-31.721f,-36.836f,-42.286f, --45.819f,-47.163f,-46.971f,-46.342f,-47.714f,-49.379f,-46.043f,-48.015f,-45.491f,-45.293f, --45.018f,-43.774f,-43.859f,-44.025f,-43.866f,-43.113f,-41.843f,-40.821f,-38.730f,-36.561f, --34.719f,-33.046f,-31.231f,-29.284f,-27.727f,-25.545f,-23.449f,-21.748f,-20.152f,-19.353f, --18.212f,-16.126f,-12.998f, -9.824f, -8.525f, -3.908f, -1.681f, -0.165f, 1.911f, 4.614f, - 4.160f, 3.050f, 4.064f, 6.808f, 6.086f, 7.922f, 7.859f, 10.619f, 11.212f, 12.553f, - 13.844f, 15.825f, 17.506f, 18.157f, 20.795f, 22.436f, 24.306f, 24.644f, 25.488f, 27.180f, - 27.821f, 28.285f, 25.728f, 23.068f, 23.616f, 23.293f, 25.360f, 26.509f, 28.904f, 26.360f, - 23.221f, 20.705f, 17.158f, 20.472f, 23.211f, 21.868f, 22.593f, 20.607f, 18.748f, 15.745f, - 13.606f -},{ --29.534f,-28.323f,-26.562f,-25.153f,-24.559f,-25.049f,-22.961f,-21.728f,-25.079f,-24.980f, --21.779f,-18.484f,-15.923f,-13.872f,-11.988f, -9.555f, -6.503f, -3.460f, -0.955f, -0.434f, - 0.556f, 4.590f, 7.992f, 11.581f, 15.913f, 18.859f, 21.822f, 23.423f, 22.600f, 23.171f, - 20.408f, 20.447f, 19.787f, 18.797f, 18.335f, 14.916f, 6.894f, 6.397f, 10.129f, 9.795f, - 7.817f, 5.529f, 2.182f, 0.119f, -0.241f, 0.109f, 0.584f, 0.501f, 0.903f, 2.104f, - 5.104f, 7.669f, 8.589f, 9.823f, 11.306f, 12.530f, 14.625f, 14.879f, 14.450f, 13.633f, - 11.223f, 9.681f, 8.609f, 7.592f, 7.036f, 6.088f, 5.461f, 4.753f, 4.336f, 4.241f, - 3.829f, 3.621f, 2.030f, 0.824f, -0.181f, -1.958f, -4.199f, -4.985f, -7.527f,-10.094f, --10.236f,-13.189f,-16.340f,-18.297f,-19.283f,-20.161f,-20.145f,-17.871f,-22.341f,-23.581f, --24.915f,-26.435f,-27.652f,-29.410f,-32.593f,-34.083f,-32.110f,-32.764f,-38.300f,-43.846f, --44.928f,-45.839f,-45.952f,-45.561f,-47.401f,-48.842f,-47.286f,-46.678f,-43.993f,-42.795f, --42.581f,-42.499f,-41.975f,-41.681f,-41.460f,-40.880f,-39.419f,-38.216f,-36.282f,-34.362f, --32.558f,-30.700f,-28.955f,-27.211f,-25.209f,-23.057f,-20.984f,-19.480f,-17.852f,-16.257f, --15.080f,-12.938f,-10.316f, -8.298f, -6.622f, -1.695f, 1.467f, 3.299f, 5.254f, 6.972f, - 8.089f, 8.817f, 8.859f, 10.225f, 10.630f, 12.506f, 11.241f, 13.097f, 13.919f, 14.631f, - 16.514f, 18.568f, 19.687f, 20.247f, 22.495f, 25.775f, 27.264f, 25.947f, 25.211f, 26.358f, - 27.861f, 28.837f, 26.779f, 24.314f, 25.168f, 24.827f, 26.805f, 27.356f, 29.337f, 26.897f, - 24.063f, 21.479f, 17.570f, 20.634f, 23.544f, 21.747f, 22.382f, 20.576f, 18.677f, 15.727f, - 13.606f -},{ --29.534f,-28.307f,-26.595f,-25.386f,-24.759f,-24.766f,-22.630f,-21.187f,-24.852f,-24.978f, --21.721f,-18.424f,-15.599f,-13.958f,-12.060f, -9.273f, -6.221f, -2.951f, -0.922f, -1.137f, - -0.525f, 3.391f, 6.813f, 9.807f, 14.136f, 16.398f, 20.133f, 22.319f, 22.981f, 23.618f, - 20.622f, 20.384f, 19.802f, 18.224f, 18.118f, 13.595f, 8.774f, 5.026f, 9.085f, 9.604f, - 6.172f, 3.091f, 0.857f, -0.773f, -0.700f, -0.390f, -0.086f, 0.009f, 0.049f, 0.646f, - 1.783f, 3.483f, 4.260f, 8.055f, 9.174f, 10.329f, 12.785f, 13.191f, 12.770f, 12.726f, - 9.533f, 9.073f, 7.934f, 5.925f, 4.877f, 4.174f, 2.453f, -0.060f, -0.562f, -0.721f, - -1.083f, -1.502f, -1.105f, -1.288f, -2.209f, -4.359f, -6.269f, -8.014f, -9.556f,-10.425f, --11.526f,-14.884f,-18.042f,-19.747f,-20.649f,-20.933f,-20.016f,-18.540f,-21.642f,-24.084f, --25.554f,-27.553f,-29.007f,-30.444f,-32.627f,-33.322f,-31.783f,-33.222f,-37.410f,-42.178f, --44.943f,-45.380f,-44.930f,-44.724f,-45.952f,-47.015f,-46.129f,-44.039f,-41.785f,-41.476f, --40.988f,-40.770f,-40.204f,-39.314f,-38.631f,-37.986f,-36.508f,-35.289f,-33.678f,-32.003f, --30.126f,-28.267f,-26.452f,-24.709f,-22.361f,-20.281f,-18.176f,-16.437f,-14.768f,-13.310f, --11.757f, -9.847f, -8.144f, -6.617f, -3.094f, 3.321f, 4.400f, 6.475f, 7.926f, 9.488f, - 10.944f, 11.332f, 12.135f, 12.578f, 13.927f, 15.054f, 14.218f, 15.729f, 16.775f, 17.526f, - 19.083f, 20.742f, 21.892f, 22.070f, 25.512f, 27.877f, 28.289f, 26.441f, 25.298f, 23.893f, - 27.319f, 28.336f, 28.198f, 26.265f, 26.961f, 26.565f, 28.030f, 28.185f, 29.701f, 27.333f, - 24.904f, 22.148f, 17.951f, 20.797f, 23.842f, 21.570f, 22.095f, 20.515f, 18.592f, 15.708f, - 13.606f -},{ --29.534f,-28.293f,-26.622f,-25.614f,-24.987f,-24.554f,-22.515f,-20.761f,-24.562f,-24.936f, --21.620f,-18.324f,-15.461f,-13.896f,-12.037f, -8.827f, -5.786f, -2.471f, -0.790f, -1.503f, - -0.961f, 2.922f, 6.239f, 8.821f, 12.979f, 14.635f, 17.858f, 21.563f, 21.930f, 23.508f, - 21.269f, 20.477f, 19.696f, 19.168f, 17.126f, 14.163f, 11.788f, 5.062f, 7.674f, 8.541f, - 4.380f, 0.653f, -0.027f, -1.486f, -1.647f, -1.471f, -1.008f, -0.884f, -0.609f, -0.264f, - 0.385f, 1.329f, 2.062f, 4.181f, 7.140f, 8.827f, 9.601f, 11.002f, 10.766f, 11.135f, - 8.577f, 8.330f, 7.841f, 5.310f, 4.174f, 2.808f, 0.820f, -1.792f, -2.844f, -3.977f, - -5.400f, -4.946f, -3.386f, -3.311f, -4.284f, -5.000f, -7.599f, -8.469f, -9.436f,-10.789f, --12.420f,-15.590f,-19.064f,-20.542f,-21.296f,-21.588f,-21.195f,-20.119f,-21.686f,-23.285f, --24.762f,-27.578f,-29.336f,-30.396f,-32.167f,-33.711f,-32.627f,-34.324f,-38.835f,-43.913f, --44.976f,-45.302f,-44.709f,-44.240f,-44.368f,-44.495f,-44.210f,-42.101f,-40.665f,-40.495f, --40.001f,-38.726f,-38.237f,-36.855f,-36.330f,-35.496f,-33.596f,-32.572f,-31.137f,-29.093f, --27.592f,-25.804f,-23.791f,-21.602f,-19.551f,-17.518f,-15.655f,-13.083f,-11.122f,-10.176f, - -8.891f, -7.311f, -5.723f, -2.479f, 2.603f, 6.164f, 7.456f, 8.498f, 9.465f, 12.220f, - 12.907f, 13.646f, 14.559f, 15.401f, 15.644f, 15.977f, 16.970f, 18.433f, 19.177f, 20.583f, - 21.683f, 23.070f, 23.352f, 24.755f, 27.946f, 27.195f, 29.648f, 28.063f, 26.408f, 22.776f, - 26.390f, 27.509f, 29.934f, 28.550f, 28.658f, 28.303f, 29.025f, 28.993f, 30.020f, 27.742f, - 25.774f, 22.761f, 18.301f, 20.959f, 24.094f, 21.358f, 21.763f, 20.431f, 18.494f, 15.688f, - 13.606f -},{ --29.534f,-28.282f,-26.642f,-25.827f,-25.249f,-24.475f,-22.587f,-20.475f,-24.190f,-24.867f, --21.385f,-18.181f,-15.624f,-13.872f,-11.846f, -8.631f, -5.248f, -1.991f, -0.949f, -1.640f, - -0.827f, 3.132f, 6.236f, 8.701f, 12.512f, 14.533f, 16.655f, 20.855f, 20.788f, 22.296f, - 21.305f, 20.201f, 19.292f, 18.956f, 17.226f, 14.594f, 13.436f, 5.751f, 6.644f, 7.083f, - 3.436f, -0.311f, -0.955f, -2.237f, -2.610f, -2.407f, -2.051f, -1.758f, -1.342f, -0.987f, - -0.399f, -0.179f, 0.834f, 2.316f, 4.134f, 7.689f, 8.433f, 7.828f, 8.190f, 8.244f, - 6.125f, 6.973f, 6.946f, 6.505f, 4.848f, 2.453f, -0.996f, -2.656f, -4.397f, -5.797f, - -6.555f, -6.569f, -6.106f, -4.485f, -4.937f, -5.937f, -8.796f, -8.344f,-10.683f,-12.027f, --12.752f,-16.214f,-19.439f,-20.913f,-21.514f,-21.859f,-22.091f,-22.276f,-22.717f,-23.579f, --24.158f,-26.516f,-28.659f,-30.447f,-32.521f,-34.264f,-33.098f,-39.220f,-43.167f,-43.856f, --44.800f,-44.983f,-44.197f,-43.731f,-43.209f,-42.845f,-42.021f,-40.721f,-39.372f,-38.779f, --37.900f,-36.333f,-35.683f,-34.246f,-33.720f,-32.627f,-30.706f,-29.525f,-28.021f,-26.299f, --24.581f,-22.825f,-20.876f,-18.355f,-16.199f,-14.718f,-11.314f,-10.211f, -7.959f, -6.733f, - -5.796f, -4.227f, -1.032f, 3.678f, 8.258f, 9.743f, 10.261f, 11.194f, 12.947f, 15.496f, - 16.458f, 16.362f, 17.394f, 18.783f, 17.655f, 18.422f, 19.536f, 20.824f, 22.085f, 23.143f, - 24.357f, 25.318f, 25.262f, 28.261f, 28.382f, 27.312f, 31.441f, 29.960f, 27.378f, 23.593f, - 25.997f, 27.890f, 31.962f, 30.633f, 30.181f, 29.798f, 29.830f, 29.718f, 30.279f, 28.148f, - 26.623f, 23.367f, 18.629f, 21.135f, 24.300f, 21.139f, 21.417f, 20.331f, 18.386f, 15.667f, - 13.606f -},{ --29.534f,-28.272f,-26.653f,-26.012f,-25.540f,-24.553f,-22.770f,-20.350f,-23.759f,-24.724f, --20.888f,-17.915f,-15.820f,-14.027f,-11.561f, -8.656f, -4.943f, -1.722f, -1.094f, -1.446f, - -0.229f, 3.584f, 6.511f, 8.641f, 11.696f, 13.643f, 15.404f, 20.003f, 20.184f, 21.343f, - 20.022f, 20.294f, 19.071f, 18.077f, 17.314f, 14.671f, 11.769f, 6.811f, 6.198f, 6.000f, - 3.157f, -0.714f, -1.642f, -2.932f, -3.326f, -2.775f, -2.261f, -2.167f, -2.026f, -1.722f, - -1.641f, -1.560f, -1.095f, -0.365f, 1.495f, 3.169f, 5.927f, 7.296f, 5.830f, 5.750f, - 4.245f, 6.211f, 6.396f, 5.892f, 4.913f, 3.017f, -0.006f, -4.412f, -5.691f, -6.880f, - -8.022f, -8.415f, -7.943f, -6.513f, -6.078f, -7.231f, -9.534f,-11.124f,-13.996f,-15.596f, --14.751f,-17.445f,-20.083f,-21.290f,-21.931f,-22.295f,-22.536f,-22.173f,-23.051f,-23.019f, --23.655f,-25.561f,-28.391f,-30.855f,-33.639f,-33.698f,-35.616f,-39.996f,-42.968f,-43.138f, --44.051f,-43.903f,-43.356f,-42.788f,-41.867f,-40.846f,-39.910f,-38.802f,-37.599f,-36.998f, --35.505f,-34.013f,-33.506f,-31.353f,-30.697f,-29.254f,-27.658f,-26.335f,-24.638f,-22.920f, --21.042f,-19.450f,-17.722f,-15.509f,-13.274f,-11.287f, -8.784f, -6.815f, -4.985f, -3.320f, - -2.073f, -0.858f, 3.589f, 9.570f, 11.945f, 14.045f, 13.752f, 14.709f, 16.672f, 21.733f, - 22.083f, 20.108f, 20.634f, 20.752f, 21.098f, 21.899f, 22.735f, 23.510f, 24.604f, 25.271f, - 26.784f, 27.169f, 28.940f, 30.034f, 29.388f, 29.372f, 32.417f, 31.408f, 29.002f, 25.739f, - 27.302f, 29.794f, 33.744f, 32.387f, 31.585f, 30.900f, 30.526f, 30.260f, 30.470f, 28.566f, - 27.367f, 24.002f, 18.959f, 21.349f, 24.475f, 20.943f, 21.087f, 20.224f, 18.272f, 15.646f, - 13.606f -},{ --29.534f,-28.263f,-26.653f,-26.159f,-25.843f,-24.765f,-22.968f,-20.391f,-23.348f,-24.438f, --20.073f,-17.417f,-15.658f,-14.194f,-11.280f, -8.517f, -4.805f, -1.575f, -0.905f, -1.260f, - 0.278f, 4.057f, 6.916f, 8.822f, 11.336f, 12.973f, 15.430f, 19.545f, 20.167f, 20.790f, - 19.614f, 19.895f, 19.200f, 18.040f, 17.916f, 14.834f, 11.451f, 5.535f, 5.743f, 5.537f, - 2.474f, -0.640f, -1.959f, -3.603f, -3.663f, -3.122f, -2.337f, -2.318f, -2.734f, -2.671f, - -2.633f, -2.698f, -2.480f, -2.203f, -1.459f, -0.245f, 2.140f, 4.474f, 4.527f, 4.393f, - 2.771f, 4.303f, 5.898f, 4.045f, 3.854f, 4.111f, -0.131f, -5.005f, -6.197f, -7.124f, - -8.115f, -8.328f, -9.057f, -9.112f, -8.244f, -9.230f, -9.562f,-12.152f,-16.348f,-18.501f, --18.860f,-20.533f,-21.769f,-22.124f,-22.878f,-23.737f,-24.189f,-23.806f,-23.941f,-24.958f, --25.693f,-26.828f,-28.634f,-30.567f,-32.293f,-36.260f,-38.493f,-40.314f,-42.047f,-42.403f, --42.806f,-42.547f,-42.499f,-41.398f,-40.544f,-38.256f,-37.762f,-36.087f,-35.396f,-34.331f, --32.982f,-31.264f,-30.634f,-28.820f,-27.700f,-26.168f,-24.327f,-22.898f,-21.004f,-19.342f, --17.633f,-15.731f,-14.074f,-12.089f, -9.715f, -7.512f, -5.421f, -3.706f, -2.034f, -0.374f, - 1.179f, 3.419f, 5.205f, 13.012f, 15.565f, 17.046f, 17.574f, 17.416f, 20.574f, 23.794f, - 24.159f, 23.632f, 22.247f, 22.806f, 23.644f, 25.065f, 25.718f, 26.526f, 26.942f, 27.951f, - 28.522f, 29.294f, 31.305f, 32.328f, 32.519f, 32.779f, 33.877f, 33.422f, 31.841f, 28.667f, - 29.860f, 32.108f, 34.932f, 34.082f, 32.760f, 31.651f, 31.171f, 30.564f, 30.640f, 29.038f, - 27.971f, 24.682f, 19.333f, 21.627f, 24.639f, 20.796f, 20.801f, 20.118f, 18.153f, 15.624f, - 13.606f -},{ --29.534f,-28.256f,-26.642f,-26.259f,-26.133f,-25.045f,-23.088f,-20.574f,-23.078f,-23.987f, --19.045f,-16.662f,-15.058f,-14.084f,-11.018f, -8.156f, -4.579f, -1.359f, -0.807f, -1.197f, - 0.590f, 4.418f, 7.168f, 8.956f, 11.037f, 13.241f, 16.300f, 19.093f, 20.293f, 20.826f, - 19.266f, 20.206f, 19.210f, 18.121f, 17.901f, 15.591f, 10.900f, 3.606f, 5.572f, 5.797f, - 2.227f, -0.702f, -2.308f, -3.900f, -4.122f, -3.331f, -2.559f, -2.622f, -2.987f, -3.313f, - -3.549f, -3.538f, -3.384f, -3.283f, -3.391f, -3.058f, -1.129f, -0.291f, -0.997f, 0.928f, - 3.222f, 1.999f, 1.615f, 0.776f, 2.013f, 1.577f, -1.021f, -4.808f, -6.506f, -7.122f, - -8.053f,-10.772f,-13.258f,-11.781f,-10.629f,-11.526f,-10.635f,-11.741f,-14.045f,-17.111f, --19.403f,-22.076f,-23.277f,-22.811f,-23.608f,-24.569f,-25.425f,-24.954f,-24.536f,-25.035f, --26.783f,-28.145f,-29.402f,-29.285f,-29.491f,-35.000f,-38.238f,-40.251f,-41.526f,-41.158f, --41.154f,-41.139f,-41.012f,-39.660f,-38.226f,-35.567f,-34.479f,-33.613f,-32.651f,-31.682f, --30.161f,-28.592f,-27.278f,-25.763f,-24.512f,-22.480f,-20.921f,-19.331f,-17.529f,-15.720f, --13.944f,-12.196f,-10.294f, -8.541f, -6.086f, -4.212f, -2.944f, -0.882f, 0.906f, 2.495f, - 4.479f, 6.530f, 9.463f, 16.154f, 16.939f, 19.469f, 20.133f, 20.523f, 25.154f, 22.200f, - 22.967f, 24.226f, 23.558f, 25.362f, 26.754f, 27.942f, 28.379f, 29.298f, 29.659f, 30.561f, - 30.422f, 30.952f, 33.432f, 36.870f, 36.246f, 36.792f, 36.234f, 35.818f, 34.233f, 31.371f, - 32.384f, 33.988f, 35.832f, 35.695f, 33.562f, 32.213f, 31.708f, 30.678f, 30.872f, 29.608f, - 28.485f, 25.403f, 19.809f, 21.980f, 24.807f, 20.713f, 20.577f, 20.020f, 18.034f, 15.602f, - 13.606f -},{ --29.534f,-28.250f,-26.617f,-26.304f,-26.375f,-25.296f,-23.058f,-20.838f,-23.040f,-23.435f, --18.047f,-15.786f,-14.363f,-13.658f,-10.686f, -7.833f, -4.338f, -1.255f, -1.064f, -0.951f, - 0.919f, 4.547f, 7.230f, 8.905f, 11.185f, 14.140f, 16.395f, 18.806f, 19.547f, 20.854f, - 18.024f, 20.431f, 19.629f, 18.685f, 17.670f, 15.851f, 12.050f, 5.564f, 5.138f, 5.938f, - 2.379f, -0.884f, -2.762f, -3.962f, -4.062f, -3.709f, -2.761f, -2.792f, -3.224f, -3.872f, - -4.418f, -4.363f, -3.891f, -4.131f, -4.522f, -5.039f, -3.419f, -2.653f, -2.668f, -3.127f, - 0.819f, 1.266f, 1.238f, 0.399f, -0.106f, -1.420f, -3.140f, -5.195f, -6.299f, -7.063f, - -9.089f,-11.087f,-13.172f,-12.496f,-12.625f,-13.543f,-14.600f,-15.855f,-15.390f,-15.738f, --18.862f,-21.278f,-22.955f,-23.608f,-24.334f,-24.843f,-24.685f,-26.061f,-25.205f,-25.323f, --26.444f,-27.257f,-28.446f,-28.979f,-30.149f,-34.620f,-37.568f,-39.070f,-39.960f,-39.300f, --39.489f,-39.383f,-38.420f,-36.962f,-35.304f,-32.953f,-32.026f,-31.008f,-29.837f,-28.639f, --26.902f,-25.580f,-24.024f,-22.280f,-20.846f,-18.932f,-17.083f,-15.407f,-13.845f,-12.010f, --10.187f, -8.432f, -6.732f, -4.720f, -2.708f, -0.658f, 0.245f, 2.016f, 3.754f, 5.100f, - 6.963f, 9.329f, 11.785f, 17.415f, 17.827f, 20.909f, 23.713f, 25.060f, 27.226f, 23.321f, - 23.476f, 24.693f, 26.311f, 28.283f, 29.673f, 30.635f, 31.088f, 31.974f, 32.483f, 33.577f, - 32.792f, 33.424f, 37.363f, 41.199f, 39.911f, 40.070f, 39.109f, 38.617f, 36.012f, 33.721f, - 34.567f, 35.510f, 36.671f, 36.683f, 34.117f, 32.760f, 32.038f, 30.772f, 31.209f, 30.266f, - 29.014f, 26.150f, 20.446f, 22.401f, 24.979f, 20.701f, 20.428f, 19.935f, 17.917f, 15.581f, - 13.606f -},{ --29.534f,-28.246f,-26.580f,-26.289f,-26.532f,-25.409f,-22.845f,-21.094f,-23.235f,-22.893f, --17.339f,-15.041f,-13.997f,-13.152f,-10.213f, -7.564f, -4.204f, -1.453f, -1.358f, -0.674f, - 1.174f, 4.501f, 7.208f, 8.955f, 11.809f, 14.731f, 16.520f, 18.815f, 20.854f, 23.434f, - 18.817f, 20.713f, 20.074f, 18.905f, 17.502f, 15.646f, 13.723f, 7.760f, 4.432f, 5.397f, - 2.244f, -0.927f, -2.886f, -3.938f, -3.716f, -3.776f, -3.144f, -3.111f, -3.646f, -4.572f, - -5.101f, -4.878f, -4.563f, -4.772f, -5.261f, -5.835f, -4.858f, -4.091f, -3.797f, -5.182f, - -3.905f, -3.009f, -1.594f, -2.679f, -2.465f, -1.567f, -2.466f, -3.986f, -5.118f, -5.575f, - -7.870f, -9.134f,-11.478f,-12.859f,-13.222f,-15.030f,-16.752f,-17.952f,-16.929f,-16.499f, --18.510f,-20.688f,-23.055f,-24.423f,-25.519f,-26.300f,-26.418f,-26.432f,-24.877f,-25.388f, --26.060f,-26.085f,-29.960f,-30.764f,-31.201f,-33.904f,-36.179f,-37.537f,-37.385f,-37.010f, --37.320f,-37.399f,-35.243f,-33.702f,-32.043f,-30.662f,-28.905f,-27.907f,-26.815f,-25.131f, --23.982f,-22.411f,-20.631f,-18.862f,-17.198f,-15.014f,-13.466f,-11.646f,-10.086f, -8.078f, - -6.433f, -4.579f, -3.179f, -1.095f, 0.755f, 2.147f, 3.928f, 5.288f, 6.702f, 7.742f, - 10.150f, 11.862f, 15.248f, 18.555f, 20.494f, 23.481f, 26.235f, 27.799f, 28.971f, 26.266f, - 26.092f, 27.164f, 29.082f, 31.343f, 32.320f, 33.849f, 33.897f, 34.025f, 35.043f, 36.324f, - 35.964f, 35.925f, 41.538f, 44.442f, 43.236f, 42.997f, 41.712f, 41.185f, 37.930f, 35.956f, - 36.487f, 36.862f, 37.299f, 36.850f, 34.705f, 33.417f, 32.231f, 31.071f, 31.627f, 30.935f, - 29.639f, 26.916f, 21.285f, 22.867f, 25.144f, 20.757f, 20.356f, 19.868f, 17.805f, 15.560f, - 13.606f -},{ --29.534f,-28.242f,-26.529f,-26.211f,-26.567f,-25.287f,-22.453f,-21.242f,-23.531f,-22.443f, --17.057f,-14.659f,-14.079f,-12.782f, -9.683f, -7.125f, -4.051f, -1.746f, -1.504f, -0.601f, - 1.415f, 4.354f, 7.010f, 9.087f, 12.062f, 14.344f, 16.733f, 18.622f, 22.414f, 25.395f, - 17.324f, 20.967f, 20.212f, 18.446f, 17.052f, 15.592f, 14.008f, 6.490f, 4.091f, 5.898f, - 2.274f, -0.595f, -2.809f, -3.783f, -3.561f, -3.634f, -3.351f, -3.574f, -4.462f, -5.411f, - -5.787f, -5.376f, -5.141f, -5.317f, -5.660f, -6.065f, -5.607f, -5.039f, -4.923f, -6.136f, - -6.361f, -6.316f, -6.291f, -7.050f, -5.754f, -3.362f, -3.375f, -2.179f, -2.832f, -5.439f, - -8.122f, -9.211f,-11.608f,-14.624f,-13.887f,-13.644f,-14.055f,-14.031f,-15.588f,-16.208f, --17.214f,-19.887f,-23.170f,-24.563f,-25.385f,-26.404f,-27.480f,-26.624f,-25.708f,-23.806f, --24.872f,-26.482f,-31.513f,-30.656f,-31.795f,-32.880f,-34.485f,-35.051f,-34.629f,-34.909f, --34.948f,-34.770f,-32.030f,-30.653f,-28.993f,-28.057f,-26.637f,-25.342f,-24.029f,-22.536f, --20.668f,-18.864f,-17.224f,-15.650f,-13.490f,-11.367f, -9.574f, -8.187f, -6.173f, -4.177f, - -2.524f, -0.843f, 0.591f, 2.565f, 4.336f, 5.926f, 7.351f, 8.545f, 9.396f, 11.124f, - 13.491f, 15.579f, 18.091f, 20.451f, 23.436f, 26.258f, 29.085f, 31.982f, 31.575f, 29.104f, - 29.242f, 30.649f, 31.850f, 33.923f, 35.358f, 36.569f, 36.589f, 36.682f, 37.666f, 37.750f, - 39.190f, 37.863f, 45.059f, 47.180f, 46.319f, 45.749f, 43.608f, 42.885f, 39.923f, 37.855f, - 38.034f, 37.981f, 37.814f, 36.818f, 35.394f, 34.200f, 32.550f, 31.700f, 32.072f, 31.538f, - 30.365f, 27.705f, 22.335f, 23.347f, 25.278f, 20.867f, 20.355f, 19.821f, 17.700f, 15.539f, - 13.606f -},{ --29.534f,-28.239f,-26.464f,-26.071f,-26.452f,-24.869f,-21.918f,-21.204f,-23.710f,-22.079f, --17.151f,-14.730f,-14.411f,-12.540f, -9.247f, -6.561f, -3.853f, -1.975f, -1.575f, -0.467f, - 1.717f, 4.218f, 6.859f, 9.469f, 12.251f, 13.972f, 16.793f, 18.772f, 22.803f, 25.916f, - 16.085f, 20.824f, 19.862f, 18.565f, 17.132f, 15.725f, 13.657f, 4.309f, 4.715f, 6.285f, - 3.189f, 0.018f, -2.113f, -3.143f, -3.307f, -3.480f, -3.805f, -4.364f, -5.423f, -6.179f, - -6.434f, -6.055f, -5.731f, -5.728f, -5.983f, -6.282f, -5.989f, -6.105f, -6.230f, -7.895f, - -7.315f, -8.015f, -7.855f, -8.138f, -9.589f, -5.665f, -4.489f, -3.181f, -2.733f, -4.289f, - -6.951f,-10.452f,-12.102f,-14.588f,-14.055f,-12.755f,-12.681f,-12.817f,-15.773f,-17.097f, --16.003f,-18.909f,-22.621f,-23.825f,-23.819f,-25.313f,-26.465f,-26.553f,-26.351f,-22.262f, --23.154f,-28.256f,-29.277f,-28.685f,-29.672f,-31.179f,-32.439f,-32.478f,-32.148f,-32.537f, --32.354f,-30.790f,-29.042f,-27.148f,-25.734f,-25.770f,-25.234f,-24.217f,-22.639f,-20.673f, --18.396f,-16.451f,-14.359f,-12.354f,-11.376f, -8.325f, -6.148f, -3.844f, -2.087f, -0.493f, - 1.281f, 2.957f, 4.435f, 6.479f, 7.850f, 9.343f, 10.692f, 11.747f, 12.607f, 13.863f, - 16.119f, 18.567f, 20.741f, 22.972f, 25.370f, 27.854f, 29.490f, 35.015f, 34.888f, 32.864f, - 32.376f, 33.501f, 34.146f, 36.334f, 37.761f, 38.770f, 39.091f, 39.341f, 40.221f, 39.729f, - 41.214f, 42.487f, 47.700f, 49.366f, 48.852f, 47.873f, 45.463f, 44.498f, 41.852f, 39.427f, - 39.311f, 38.881f, 38.556f, 37.228f, 36.046f, 34.965f, 33.166f, 32.558f, 32.517f, 32.070f, - 31.126f, 28.539f, 23.559f, 23.820f, 25.361f, 21.016f, 20.412f, 19.795f, 17.606f, 15.518f, - 13.606f -},{ --29.534f,-28.237f,-26.386f,-25.871f,-26.174f,-24.139f,-21.295f,-20.946f,-23.558f,-21.715f, --17.443f,-15.161f,-14.750f,-12.341f, -8.932f, -6.121f, -3.784f, -2.347f, -1.585f, -0.189f, - 1.912f, 4.171f, 6.815f, 9.826f, 12.148f, 13.995f, 16.796f, 18.458f, 22.500f, 25.721f, - 15.910f, 19.986f, 19.763f, 18.436f, 17.292f, 15.631f, 13.487f, 4.101f, 5.010f, 7.583f, - 4.527f, 0.678f, -1.333f, -2.557f, -3.547f, -3.644f, -4.667f, -5.425f, -6.457f, -7.085f, - -6.970f, -6.696f, -6.402f, -6.215f, -6.482f, -6.959f, -6.724f, -6.993f, -7.559f, -8.027f, - -7.765f, -8.684f,-10.449f,-10.558f,-10.922f,-10.188f, -6.162f, -4.054f, -3.886f, -3.804f, - -6.280f, -9.680f,-10.965f,-12.365f,-12.864f,-13.234f,-13.124f,-14.264f,-16.022f,-17.016f, --14.816f,-17.716f,-21.737f,-23.111f,-22.620f,-23.000f,-23.425f,-23.525f,-22.296f,-22.190f, --24.792f,-26.740f,-26.675f,-26.888f,-28.177f,-28.554f,-29.603f,-29.952f,-29.795f,-29.550f, --28.963f,-27.480f,-25.942f,-25.165f,-24.621f,-24.503f,-23.624f,-22.492f,-20.738f,-19.030f, --17.043f,-14.920f,-12.920f,-10.803f, -8.570f, -6.513f, -3.643f, -0.821f, 1.698f, 3.637f, - 5.132f, 6.747f, 8.366f, 10.168f, 11.341f, 12.749f, 14.022f, 15.538f, 16.039f, 16.843f, - 19.352f, 21.309f, 23.528f, 25.774f, 27.553f, 29.688f, 30.962f, 35.528f, 35.863f, 35.086f, - 35.272f, 36.326f, 36.484f, 38.845f, 39.977f, 40.858f, 41.317f, 41.512f, 41.647f, 43.277f, - 43.654f, 46.079f, 49.067f, 50.233f, 50.119f, 49.201f, 47.251f, 46.048f, 43.444f, 40.699f, - 40.460f, 39.743f, 39.417f, 38.081f, 36.613f, 35.530f, 33.985f, 33.395f, 32.957f, 32.596f, - 31.843f, 29.441f, 24.887f, 24.279f, 25.379f, 21.191f, 20.513f, 19.790f, 17.524f, 15.499f, - 13.606f -},{ --29.534f,-28.235f,-26.296f,-25.619f,-25.730f,-23.135f,-20.640f,-20.497f,-22.980f,-21.267f, --17.747f,-15.715f,-14.983f,-12.203f, -8.650f, -5.786f, -3.811f, -2.943f, -1.617f, 0.016f, - 2.130f, 4.151f, 6.749f, 9.797f, 12.000f, 14.297f, 16.533f, 18.242f, 21.795f, 24.433f, - 17.711f, 19.643f, 19.555f, 18.030f, 17.252f, 15.514f, 14.061f, 5.735f, 5.291f, 8.766f, - 6.024f, 1.373f, -1.126f, -2.784f, -4.238f, -4.375f, -5.360f, -6.311f, -7.216f, -7.620f, - -7.428f, -7.097f, -6.828f, -6.732f, -6.830f, -7.309f, -7.198f, -7.614f, -7.588f, -7.943f, - -8.247f, -9.085f,-10.331f,-10.229f,-10.520f,-11.619f, -7.944f, -5.636f, -4.632f, -5.215f, - -9.677f,-11.310f,-10.541f,-12.227f,-11.957f,-12.789f,-13.133f,-15.671f,-15.690f,-16.479f, --16.776f,-15.643f,-19.194f,-21.327f,-21.506f,-21.562f,-21.058f,-22.151f,-20.269f,-22.839f, --24.768f,-24.501f,-24.361f,-24.860f,-25.613f,-26.463f,-27.052f,-27.576f,-27.986f,-26.185f, --25.612f,-24.752f,-23.678f,-23.741f,-23.085f,-23.140f,-21.856f,-21.033f,-19.288f,-17.432f, --15.206f,-13.427f,-11.398f, -9.356f, -6.667f, -4.127f, -1.591f, 0.875f, 3.990f, 6.859f, - 8.848f, 10.561f, 12.048f, 13.671f, 14.842f, 16.231f, 17.691f, 19.182f, 19.725f, 20.456f, - 22.523f, 24.360f, 26.287f, 28.560f, 30.173f, 31.925f, 33.487f, 35.147f, 36.419f, 37.177f, - 37.886f, 38.631f, 39.185f, 41.320f, 42.349f, 43.068f, 43.357f, 43.781f, 43.428f, 45.357f, - 45.497f, 45.544f, 46.690f, 47.998f, 50.219f, 49.146f, 48.111f, 47.075f, 44.766f, 41.927f, - 41.720f, 40.710f, 40.066f, 39.103f, 37.143f, 35.908f, 34.824f, 34.053f, 33.376f, 33.162f, - 32.469f, 30.416f, 26.224f, 24.737f, 25.337f, 21.382f, 20.641f, 19.802f, 17.454f, 15.480f, - 13.606f -},{ --29.534f,-28.234f,-26.195f,-25.322f,-25.139f,-21.944f,-20.002f,-19.934f,-22.060f,-20.732f, --17.947f,-16.127f,-15.058f,-12.180f, -8.393f, -5.335f, -3.764f, -3.487f, -1.772f, 0.166f, - 2.448f, 4.235f, 6.915f, 9.606f, 11.924f, 14.330f, 16.355f, 18.364f, 20.763f, 21.074f, - 20.167f, 19.319f, 19.329f, 18.021f, 17.373f, 15.882f, 15.932f, 6.040f, 5.183f, 7.850f, - 6.377f, 1.787f, -1.132f, -3.317f, -4.572f, -4.857f, -5.972f, -6.936f, -7.706f, -7.840f, - -7.506f, -7.262f, -7.085f, -7.171f, -7.222f, -7.619f, -7.601f, -7.633f, -7.381f, -8.092f, - -9.116f, -9.217f,-10.772f,-10.143f,-10.243f,-11.278f, -8.752f, -5.855f, -5.222f, -5.796f, - -6.315f,-10.842f,-10.134f,-11.396f,-10.803f,-10.640f,-13.562f,-12.706f,-13.136f,-15.813f, --16.529f,-14.491f,-16.170f,-18.431f,-18.954f,-19.274f,-19.115f,-20.369f,-19.035f,-21.751f, --23.138f,-22.110f,-21.956f,-22.856f,-22.990f,-23.733f,-24.148f,-24.720f,-24.853f,-22.907f, --22.298f,-22.422f,-22.247f,-22.164f,-21.433f,-21.365f,-20.237f,-19.051f,-17.666f,-15.631f, --13.767f,-11.951f, -9.744f, -7.756f, -4.935f, -2.132f, 0.724f, 3.367f, 5.901f, 9.017f, - 12.025f, 14.476f, 15.778f, 17.139f, 18.430f, 19.850f, 21.511f, 22.761f, 23.311f, 23.789f, - 25.564f, 27.323f, 29.160f, 31.422f, 32.986f, 34.126f, 35.322f, 36.091f, 37.454f, 39.425f, - 40.031f, 40.794f, 41.686f, 43.523f, 44.330f, 45.167f, 45.417f, 45.545f, 45.326f, 46.365f, - 47.544f, 48.108f, 46.762f, 45.931f, 48.001f, 47.725f, 47.701f, 47.573f, 46.036f, 43.598f, - 43.177f, 41.863f, 40.741f, 40.118f, 37.567f, 36.314f, 35.664f, 34.597f, 33.746f, 33.737f, - 33.002f, 31.436f, 27.475f, 25.216f, 25.261f, 21.586f, 20.780f, 19.828f, 17.400f, 15.463f, - 13.606f -},{ --29.534f,-28.232f,-26.085f,-24.991f,-24.431f,-20.686f,-19.413f,-19.356f,-21.031f,-20.206f, --18.002f,-16.239f,-14.918f,-12.210f, -8.239f, -4.777f, -3.735f, -3.833f, -1.895f, 0.323f, - 2.542f, 4.470f, 7.181f, 9.426f, 11.585f, 14.193f, 16.313f, 17.855f, 18.997f, 18.180f, - 21.260f, 19.572f, 19.164f, 18.514f, 17.783f, 16.536f, 15.852f, 3.919f, 4.965f, 6.514f, - 5.719f, 1.502f, -0.714f, -3.382f, -4.773f, -5.025f, -6.369f, -7.197f, -7.615f, -7.646f, - -7.389f, -7.184f, -6.901f, -7.081f, -7.324f, -7.336f, -7.378f, -7.773f, -8.016f, -8.956f, - -9.586f, -9.460f,-11.036f,-11.012f,-11.067f,-11.777f,-10.339f, -6.358f, -6.042f, -5.981f, - -5.628f, -8.638f,-10.133f,-10.227f, -9.453f, -9.954f,-11.951f,-11.997f,-11.979f,-12.667f, --14.236f,-13.751f,-12.539f,-14.054f,-14.741f,-15.417f,-14.934f,-15.815f,-16.894f,-19.791f, --20.176f,-19.889f,-19.803f,-20.553f,-20.610f,-21.127f,-21.553f,-21.847f,-21.276f,-19.591f, --18.702f,-20.224f,-20.464f,-20.216f,-19.952f,-19.168f,-18.158f,-16.967f,-15.613f,-13.800f, --12.023f,-10.243f, -8.180f, -5.781f, -3.360f, -0.470f, 2.325f, 5.314f, 8.007f, 11.125f, - 14.226f, 17.551f, 19.869f, 20.921f, 22.014f, 23.419f, 24.754f, 26.302f, 26.951f, 27.013f, - 28.817f, 30.362f, 32.166f, 34.003f, 35.070f, 37.195f, 37.736f, 38.285f, 39.735f, 41.483f, - 42.206f, 42.989f, 44.583f, 45.434f, 46.533f, 47.361f, 47.494f, 47.220f, 47.107f, 47.392f, - 48.009f, 48.978f, 49.703f, 47.648f, 45.436f, 45.461f, 47.545f, 47.887f, 47.008f, 45.263f, - 44.430f, 43.282f, 41.832f, 40.972f, 37.820f, 36.883f, 36.587f, 35.198f, 34.074f, 34.233f, - 33.461f, 32.430f, 28.568f, 25.738f, 25.188f, 21.806f, 20.918f, 19.865f, 17.359f, 15.446f, - 13.606f -},{ --29.534f,-28.231f,-25.968f,-24.638f,-23.650f,-19.492f,-18.894f,-18.847f,-20.172f,-19.825f, --17.899f,-16.061f,-14.598f,-12.184f, -8.151f, -4.303f, -3.845f, -4.147f, -1.838f, 0.396f, - 2.515f, 4.598f, 7.223f, 9.251f, 11.502f, 14.226f, 15.987f, 18.142f, 18.648f, 19.510f, - 21.863f, 20.077f, 19.511f, 19.041f, 18.321f, 16.306f, 15.305f, 2.789f, 5.806f, 6.041f, - 3.419f, 1.319f, -0.322f, -2.764f, -4.185f, -4.836f, -6.251f, -6.906f, -7.162f, -7.103f, - -6.836f, -6.638f, -6.668f, -6.872f, -6.883f, -7.169f, -7.429f, -7.553f, -7.481f, -8.041f, - -8.687f, -8.639f,-10.767f,-11.527f,-10.884f,-11.301f,-11.585f,-10.598f, -7.652f, -7.925f, - -6.679f, -7.658f, -9.021f, -9.264f, -9.472f,-10.895f,-10.269f,-10.850f,-11.571f,-11.758f, --11.872f,-12.139f,-11.072f,-11.337f,-11.843f,-12.337f,-13.172f,-13.081f,-15.757f,-17.866f, --18.568f,-17.689f,-17.400f,-17.940f,-18.087f,-18.399f,-18.855f,-18.837f,-18.378f,-16.404f, --16.334f,-18.448f,-18.871f,-18.334f,-17.680f,-16.927f,-15.901f,-14.950f,-13.661f,-11.992f, --10.238f, -8.247f, -6.250f, -4.167f, -1.506f, 1.126f, 3.841f, 6.802f, 9.742f, 12.997f, - 16.299f, 19.552f, 22.836f, 25.129f, 25.762f, 26.727f, 27.918f, 29.197f, 30.501f, 30.367f, - 32.340f, 33.583f, 35.028f, 36.619f, 37.692f, 39.194f, 40.294f, 41.208f, 42.073f, 43.430f, - 44.505f, 45.410f, 47.059f, 47.417f, 48.843f, 49.575f, 49.456f, 48.909f, 48.768f, 48.694f, - 48.765f, 48.657f, 49.850f, 49.628f, 46.650f, 44.363f, 48.339f, 48.558f, 47.891f, 46.528f, - 45.572f, 44.846f, 43.093f, 41.642f, 38.090f, 37.476f, 37.543f, 35.921f, 34.423f, 34.597f, - 33.872f, 33.305f, 29.464f, 26.308f, 25.160f, 22.048f, 21.045f, 19.908f, 17.334f, 15.431f, - 13.606f -},{ --29.534f,-28.230f,-25.845f,-24.275f,-22.844f,-18.485f,-18.454f,-18.448f,-19.664f,-19.669f, --17.645f,-15.731f,-14.269f,-12.122f, -7.987f, -3.930f, -3.873f, -4.466f, -1.717f, 0.453f, - 2.681f, 4.545f, 7.195f, 9.058f, 11.637f, 14.175f, 15.702f, 18.410f, 19.246f, 19.971f, - 21.183f, 20.511f, 19.907f, 19.617f, 18.527f, 16.529f, 17.216f, 2.903f, 6.682f, 6.271f, - 2.807f, 1.338f, -0.212f, -2.471f, -3.726f, -4.423f, -5.700f, -6.309f, -6.400f, -6.181f, - -6.027f, -6.324f, -6.548f, -6.578f, -6.749f, -7.026f, -7.092f, -7.100f, -7.131f, -7.055f, - -7.201f, -7.660f, -9.863f, -9.465f,-10.984f,-10.525f,-10.548f,-10.804f,-10.395f,-11.423f, --10.129f, -6.615f, -7.560f, -8.280f, -8.477f, -8.423f, -9.221f,-11.125f,-11.783f,-13.412f, --12.348f,-10.895f, -9.917f,-10.472f,-10.619f, -9.647f, -9.543f,-10.781f,-15.850f,-16.009f, --16.488f,-15.287f,-15.162f,-15.244f,-15.295f,-15.694f,-16.320f,-15.951f,-14.832f,-14.455f, --14.683f,-16.719f,-16.774f,-16.577f,-15.787f,-14.748f,-13.598f,-12.730f,-11.566f,-10.011f, - -8.318f, -6.403f, -4.261f, -2.268f, 0.147f, 3.027f, 5.792f, 8.409f, 11.434f, 14.855f, - 18.289f, 21.613f, 24.601f, 28.048f, 29.324f, 30.407f, 31.211f, 32.518f, 33.541f, 33.324f, - 35.134f, 36.708f, 38.450f, 39.837f, 40.445f, 41.680f, 42.328f, 43.604f, 44.086f, 45.235f, - 47.054f, 47.770f, 48.685f, 49.661f, 51.146f, 51.821f, 51.504f, 50.971f, 50.542f, 50.078f, - 49.599f, 49.709f, 50.119f, 50.213f, 49.921f, 45.926f, 48.629f, 50.070f, 49.302f, 48.016f, - 47.015f, 46.268f, 44.266f, 42.400f, 38.684f, 37.907f, 38.378f, 36.709f, 34.868f, 34.869f, - 34.268f, 33.973f, 30.162f, 26.910f, 25.207f, 22.317f, 21.159f, 19.952f, 17.323f, 15.418f, - 13.606f -},{ --29.534f,-28.229f,-25.719f,-23.915f,-22.063f,-17.754f,-18.104f,-18.148f,-19.507f,-19.699f, --17.302f,-15.377f,-14.040f,-12.133f, -7.748f, -3.549f, -3.643f, -4.612f, -1.621f, 0.616f, - 2.756f, 4.566f, 7.163f, 8.888f, 11.545f, 14.144f, 15.622f, 17.722f, 19.987f, 21.164f, - 20.366f, 20.392f, 19.879f, 19.620f, 18.887f, 18.919f, 18.483f, 5.384f, 7.988f, 6.523f, - 3.260f, 1.822f, 0.164f, -2.262f, -3.252f, -3.967f, -5.272f, -5.506f, -5.289f, -5.212f, - -5.186f, -5.862f, -6.049f, -6.119f, -6.336f, -6.335f, -5.957f, -6.444f, -6.376f, -5.405f, - -6.046f, -7.942f, -8.956f, -9.158f, -9.815f, -9.235f, -9.655f, -9.718f,-10.023f, -8.858f, - -7.230f, -7.677f, -5.901f,-12.013f, -9.334f,-13.252f,-11.657f,-11.104f,-10.659f,-11.568f, --10.583f, -9.383f, -7.931f, -8.630f, -7.548f, -8.010f, -8.477f,-11.023f,-12.906f,-14.071f, --14.357f,-12.824f,-12.692f,-12.391f,-12.563f,-12.835f,-13.094f,-12.758f,-12.050f,-12.329f, --12.718f,-14.868f,-14.779f,-14.778f,-13.805f,-12.660f,-11.252f,-10.073f, -9.299f, -7.795f, - -6.237f, -4.239f, -2.252f, -0.524f, 1.672f, 4.687f, 7.447f, 10.166f, 13.253f, 16.392f, - 20.196f, 23.534f, 26.713f, 29.889f, 32.453f, 33.752f, 34.466f, 35.521f, 36.535f, 36.381f, - 38.105f, 39.716f, 41.618f, 42.698f, 43.511f, 44.206f, 44.815f, 45.575f, 46.325f, 47.304f, - 49.277f, 50.036f, 50.473f, 51.399f, 53.401f, 53.988f, 53.801f, 53.029f, 52.439f, 51.534f, - 50.807f, 50.758f, 50.909f, 50.849f, 52.085f, 48.357f, 49.125f, 52.646f, 51.305f, 49.707f, - 48.372f, 47.498f, 45.642f, 43.491f, 39.708f, 38.291f, 39.062f, 37.528f, 35.422f, 35.139f, - 34.700f, 34.385f, 30.688f, 27.512f, 25.341f, 22.611f, 21.257f, 19.994f, 17.327f, 15.406f, - 13.606f -},{ --29.534f,-28.227f,-25.594f,-23.569f,-21.349f,-17.342f,-17.852f,-17.906f,-19.530f,-19.779f, --17.026f,-15.045f,-13.694f,-12.171f, -7.617f, -3.166f, -3.335f, -4.541f, -1.496f, 0.763f, - 2.590f, 4.650f, 7.128f, 8.721f, 11.168f, 13.961f, 15.437f, 17.259f, 20.194f, 21.556f, - 20.622f, 20.806f, 20.235f, 20.210f, 19.219f, 21.351f, 18.282f, 9.784f, 10.296f, 7.437f, - 3.954f, 2.662f, 0.756f, -1.823f, -2.740f, -3.346f, -4.413f, -4.503f, -4.334f, -4.339f, - -4.393f, -4.858f, -5.096f, -5.311f, -5.462f, -5.167f, -5.232f, -5.144f, -4.558f, -3.737f, - -4.056f, -6.179f, -6.953f, -7.912f, -8.647f, -8.593f, -9.200f, -9.479f, -9.643f, -9.817f, - -8.906f,-10.926f,-10.773f,-10.103f,-13.978f,-13.717f,-12.888f,-12.317f,-12.320f,-10.316f, - -9.060f, -7.585f, -6.313f, -6.081f, -6.511f, -7.169f, -9.459f,-10.790f,-12.360f,-12.135f, --12.448f,-10.507f, -9.909f, -9.544f, -9.676f, -9.846f, -9.894f, -9.525f, -9.796f,-10.221f, --11.022f,-12.556f,-12.841f,-12.883f,-11.493f,-10.239f, -8.370f, -7.024f, -6.354f, -5.172f, - -3.668f, -1.822f, 0.030f, 1.643f, 3.341f, 6.194f, 9.295f, 12.007f, 14.928f, 18.269f, - 21.882f, 25.062f, 28.350f, 31.653f, 35.103f, 36.892f, 37.694f, 38.422f, 39.135f, 39.186f, - 40.819f, 42.171f, 43.978f, 45.005f, 45.905f, 46.337f, 46.909f, 47.662f, 48.865f, 49.555f, - 51.136f, 51.791f, 52.309f, 53.627f, 55.395f, 56.048f, 55.906f, 55.312f, 54.377f, 53.246f, - 52.332f, 52.192f, 51.711f, 51.522f, 53.348f, 51.239f, 51.005f, 55.134f, 53.646f, 51.354f, - 49.691f, 48.625f, 47.098f, 44.851f, 41.043f, 38.966f, 39.748f, 38.406f, 36.017f, 35.469f, - 35.219f, 34.548f, 31.083f, 28.075f, 25.553f, 22.925f, 21.342f, 20.031f, 17.342f, 15.395f, - 13.606f -},{ --29.534f,-28.225f,-25.471f,-23.246f,-20.737f,-17.241f,-17.711f,-17.679f,-19.484f,-19.748f, --17.024f,-14.737f,-12.824f,-12.017f, -7.661f, -2.837f, -2.993f, -4.327f, -1.360f, 0.762f, - 2.472f, 4.515f, 7.138f, 8.590f, 10.988f, 13.595f, 15.121f, 17.305f, 20.430f, 20.650f, - 21.848f, 21.428f, 21.005f, 20.509f, 19.407f, 22.755f, 16.624f, 11.034f, 10.728f, 7.589f, - 5.227f, 3.099f, 1.515f, -1.077f, -2.112f, -2.787f, -3.165f, -3.334f, -3.234f, -3.358f, - -3.173f, -3.794f, -4.114f, -4.195f, -4.140f, -4.046f, -3.885f, -3.159f, -1.846f, -0.704f, - -1.330f, -4.440f, -5.533f, -6.635f, -7.286f, -7.718f, -8.565f, -8.506f, -9.523f, -8.103f, - -7.185f, -9.321f, -6.678f, -9.905f,-11.315f,-11.942f,-12.471f,-12.528f,-12.517f,-10.401f, - -9.376f, -7.078f, -5.317f, -3.997f, -5.013f, -6.318f, -7.717f,-10.049f,-11.360f, -9.598f, --10.476f, -8.149f, -7.738f, -6.815f, -6.819f, -6.820f, -6.789f, -6.945f, -7.390f, -8.066f, - -9.051f,-10.509f,-10.870f,-10.790f, -9.170f, -7.842f, -5.400f, -4.091f, -3.391f, -2.279f, - -1.007f, 1.078f, 2.719f, 3.894f, 5.320f, 7.802f, 10.776f, 13.716f, 16.766f, 20.100f, - 23.403f, 26.747f, 29.897f, 33.020f, 36.400f, 39.180f, 40.912f, 41.722f, 41.791f, 42.519f, - 43.432f, 44.616f, 46.041f, 47.290f, 48.403f, 48.990f, 49.280f, 50.016f, 50.724f, 51.613f, - 52.775f, 53.298f, 53.935f, 56.086f, 57.894f, 58.232f, 58.254f, 57.264f, 56.270f, 55.244f, - 54.099f, 53.335f, 52.781f, 52.240f, 53.724f, 54.430f, 53.028f, 56.307f, 55.771f, 53.358f, - 51.632f, 49.681f, 48.021f, 46.257f, 42.414f, 40.012f, 40.532f, 39.338f, 36.587f, 35.841f, - 35.841f, 34.530f, 31.383f, 28.566f, 25.813f, 23.243f, 21.416f, 20.060f, 17.370f, 15.386f, - 13.606f -},{ --29.534f,-28.222f,-25.352f,-22.955f,-20.245f,-17.398f,-17.688f,-17.454f,-19.186f,-19.497f, --17.408f,-14.515f,-11.325f,-11.587f, -7.703f, -2.517f, -2.347f, -3.948f, -1.246f, 0.750f, - 2.309f, 4.158f, 6.992f, 8.636f, 10.991f, 12.933f, 14.804f, 17.328f, 19.828f, 21.797f, - 22.674f, 21.953f, 21.392f, 20.887f, 20.179f, 21.478f, 11.834f, 12.219f, 10.475f, 8.091f, - 5.664f, 4.138f, 2.371f, 0.075f, -1.307f, -1.616f, -1.819f, -2.047f, -1.932f, -2.333f, - -2.210f, -2.715f, -3.010f, -2.449f, -2.840f, -2.707f, -2.673f, -1.945f, -0.761f, 1.224f, - -0.144f, -3.198f, -4.081f, -5.287f, -6.019f, -7.178f, -7.912f, -7.885f, -8.704f, -5.676f, - -8.310f, -8.307f, -8.885f, -8.986f, -9.136f,-10.630f,-11.238f,-11.602f,-12.089f,-11.610f, --11.554f, -7.574f, -5.270f, -4.421f, -5.390f, -6.529f, -8.171f, -8.818f, -9.532f, -7.607f, - -8.434f, -5.794f, -5.174f, -4.166f, -3.948f, -3.873f, -3.881f, -4.060f, -5.430f, -6.085f, - -7.147f, -8.370f, -8.597f, -8.687f, -6.992f, -5.431f, -3.228f, -1.301f, -0.146f, 0.958f, - 2.015f, 3.887f, 5.581f, 6.525f, 7.291f, 9.325f, 11.971f, 15.309f, 18.620f, 21.771f, - 24.831f, 28.041f, 31.437f, 34.447f, 37.790f, 40.821f, 43.396f, 44.543f, 44.611f, 45.448f, - 45.934f, 47.068f, 48.402f, 49.688f, 50.838f, 50.640f, 51.753f, 52.229f, 52.354f, 53.092f, - 54.096f, 54.908f, 55.547f, 57.641f, 59.369f, 59.741f, 60.099f, 59.512f, 58.174f, 57.125f, - 55.812f, 54.796f, 54.032f, 53.456f, 53.505f, 55.972f, 54.952f, 56.595f, 56.435f, 54.637f, - 53.506f, 50.912f, 48.576f, 47.432f, 43.481f, 41.079f, 41.334f, 40.226f, 37.148f, 36.195f, - 36.501f, 34.436f, 31.610f, 28.970f, 26.081f, 23.547f, 21.483f, 20.079f, 17.407f, 15.378f, - 13.606f -},{ --29.534f,-28.219f,-25.242f,-22.701f,-19.879f,-17.724f,-17.781f,-17.263f,-18.610f,-19.007f, --18.064f,-14.499f, -9.691f,-11.071f, -7.605f, -2.183f, -1.428f, -3.441f, -1.110f, 0.846f, - 1.962f, 3.758f, 6.662f, 8.664f, 10.616f, 12.480f, 14.657f, 17.055f, 19.353f, 22.179f, - 22.587f, 22.000f, 21.628f, 21.385f, 20.555f, 16.571f, 11.996f, 13.492f, 12.648f, 9.924f, - 6.762f, 4.464f, 3.318f, 1.557f, 0.198f, -0.149f, -0.475f, -0.783f, -0.647f, -1.119f, - -1.106f, -1.257f, -0.903f, -0.850f, -1.289f, -1.198f, -0.836f, -0.571f, 0.459f, 2.714f, - 0.482f, -1.438f, -2.910f, -4.004f, -5.346f, -6.774f, -7.355f, -7.532f, -7.985f, -5.323f, - -7.302f, -7.249f, -7.851f, -8.361f, -8.428f, -9.414f,-10.020f,-10.185f,-10.590f,-11.186f, --11.432f,-11.143f, -9.543f, -9.233f, -8.466f, -8.434f, -7.082f, -8.069f, -8.198f, -5.808f, - -6.544f, -3.792f, -2.403f, -1.543f, -1.404f, -1.184f, -0.627f, -1.242f, -3.435f, -4.362f, - -5.200f, -6.313f, -6.394f, -6.046f, -4.584f, -2.954f, -0.501f, 1.614f, 3.123f, 4.413f, - 5.805f, 7.334f, 8.625f, 8.870f, 9.438f, 11.115f, 13.331f, 16.584f, 20.204f, 23.354f, - 26.240f, 29.210f, 32.594f, 35.963f, 39.046f, 42.184f, 45.627f, 47.267f, 47.801f, 48.604f, - 49.030f, 49.739f, 50.653f, 51.736f, 52.806f, 53.197f, 53.469f, 53.868f, 54.097f, 54.709f, - 55.553f, 56.573f, 56.952f, 59.057f, 59.630f, 60.226f, 60.982f, 60.970f, 60.270f, 58.919f, - 57.795f, 56.319f, 55.348f, 54.622f, 54.034f, 56.018f, 56.866f, 56.764f, 55.750f, 54.443f, - 54.539f, 52.165f, 49.259f, 48.082f, 44.179f, 41.816f, 42.060f, 40.989f, 37.761f, 36.475f, - 37.061f, 34.379f, 31.766f, 29.291f, 26.320f, 23.817f, 21.545f, 20.088f, 17.452f, 15.373f, - 13.606f -},{ --29.534f,-28.216f,-25.141f,-22.486f,-19.629f,-18.116f,-17.971f,-17.166f,-17.899f,-18.334f, --18.640f,-14.723f, -8.658f,-10.601f, -7.458f, -1.913f, -0.682f, -2.989f, -0.998f, 0.864f, - 1.711f, 3.324f, 6.325f, 8.434f, 10.190f, 12.507f, 14.513f, 16.807f, 19.627f, 22.280f, - 23.194f, 22.759f, 22.356f, 21.961f, 21.105f, 10.845f, 13.206f, 15.315f, 15.023f, 9.944f, - 7.518f, 5.593f, 4.445f, 2.935f, 1.838f, 1.399f, 0.984f, 0.888f, 0.661f, 0.267f, - 0.094f, 0.558f, 0.619f, 0.515f, 0.652f, 0.485f, 0.712f, 0.974f, 1.279f, 2.862f, - 0.502f, 0.141f, -1.610f, -3.320f, -4.689f, -6.069f, -6.780f, -7.332f, -7.165f, -6.386f, - -5.884f, -6.043f, -6.980f, -7.628f, -8.129f, -8.272f, -8.534f, -8.771f, -9.395f,-10.640f, --11.217f,-11.050f,-10.685f, -9.523f, -7.986f, -8.002f, -5.955f, -6.592f, -7.083f, -4.245f, - -3.870f, -1.163f, 0.184f, 1.112f, 1.550f, 2.199f, 1.996f, 0.927f, -1.747f, -2.607f, - -3.242f, -4.212f, -4.035f, -3.415f, -2.034f, -0.259f, 2.550f, 4.713f, 6.383f, 7.950f, - 9.345f, 10.593f, 11.419f, 11.280f, 11.472f, 12.833f, 15.357f, 18.269f, 21.489f, 24.799f, - 27.620f, 30.320f, 33.531f, 37.091f, 40.243f, 43.071f, 46.545f, 49.432f, 50.549f, 51.568f, - 52.340f, 52.676f, 53.313f, 53.975f, 54.584f, 55.129f, 55.461f, 55.682f, 56.047f, 56.190f, - 57.255f, 58.064f, 58.304f, 59.484f, 59.928f, 60.193f, 61.036f, 61.767f, 61.842f, 60.832f, - 59.594f, 58.308f, 56.727f, 55.710f, 55.143f, 55.682f, 57.679f, 57.100f, 55.820f, 55.191f, - 55.437f, 52.676f, 49.823f, 48.329f, 44.896f, 42.300f, 42.804f, 41.659f, 38.408f, 36.650f, - 37.369f, 34.437f, 31.842f, 29.545f, 26.503f, 24.041f, 21.603f, 20.088f, 17.504f, 15.368f, - 13.606f -},{ --29.534f,-28.212f,-25.051f,-22.310f,-19.476f,-18.474f,-18.220f,-17.221f,-17.284f,-17.577f, --18.736f,-14.999f, -8.512f, -9.921f, -7.359f, -1.746f, -0.338f, -2.686f, -1.012f, 0.678f, - 1.618f, 2.908f, 5.960f, 8.130f, 9.904f, 12.065f, 14.504f, 16.888f, 19.365f, 22.479f, - 23.736f, 23.226f, 22.828f, 22.608f, 21.341f, 11.667f, 13.232f, 15.231f, 14.553f, 10.862f, - 8.708f, 6.310f, 5.834f, 4.405f, 3.274f, 2.922f, 2.890f, 3.208f, 2.648f, 2.131f, - 2.123f, 2.473f, 2.369f, 2.450f, 1.975f, 1.726f, 2.822f, 1.792f, 2.282f, 2.376f, - 1.473f, 0.748f, -0.988f, -2.849f, -4.191f, -5.744f, -6.399f, -6.520f, -6.425f, -4.877f, - -5.366f, -5.488f, -6.378f, -7.022f, -7.578f, -7.665f, -7.866f, -8.154f, -8.662f,-10.159f, --10.796f,-10.927f,-10.633f, -9.481f, -8.100f, -7.247f, -5.839f, -5.631f, -5.986f, -2.454f, - -1.791f, 1.228f, 2.652f, 3.596f, 3.737f, 3.774f, 3.651f, 2.818f, -0.182f, -0.522f, - -1.173f, -2.063f, -1.671f, -0.776f, 0.371f, 2.564f, 5.191f, 7.614f, 9.477f, 11.030f, - 12.630f, 13.652f, 13.783f, 13.455f, 13.608f, 14.587f, 16.625f, 20.028f, 23.213f, 26.258f, - 28.932f, 31.537f, 34.520f, 37.978f, 40.677f, 43.970f, 47.043f, 50.505f, 52.835f, 53.832f, - 54.938f, 55.452f, 55.873f, 56.482f, 57.150f, 57.479f, 57.377f, 57.475f, 57.962f, 58.070f, - 59.141f, 59.386f, 59.504f, 59.819f, 60.137f, 60.420f, 61.188f, 61.937f, 62.732f, 62.465f, - 61.204f, 59.914f, 58.614f, 57.190f, 56.232f, 56.101f, 58.018f, 57.396f, 56.915f, 57.468f, - 56.384f, 52.908f, 50.248f, 48.683f, 45.908f, 42.878f, 43.732f, 42.271f, 38.917f, 36.684f, - 37.338f, 34.620f, 31.828f, 29.752f, 26.621f, 24.211f, 21.656f, 20.079f, 17.561f, 15.365f, - 13.606f -},{ --29.534f,-28.207f,-24.975f,-22.173f,-19.394f,-18.722f,-18.477f,-17.442f,-16.951f,-16.842f, --18.165f,-14.975f, -8.841f, -8.672f, -7.206f, -1.680f, -0.296f, -2.464f, -1.097f, 0.509f, - 1.509f, 2.647f, 5.589f, 7.973f, 9.607f, 11.634f, 14.454f, 16.772f, 19.682f, 22.257f, - 23.707f, 23.766f, 23.638f, 23.095f, 21.464f, 10.284f, 13.444f, 15.943f, 15.166f, 11.720f, - 10.012f, 6.795f, 7.171f, 5.809f, 5.050f, 4.820f, 4.960f, 5.118f, 4.717f, 4.170f, - 4.172f, 4.174f, 4.161f, 4.107f, 3.782f, 4.927f, 2.911f, 3.435f, 3.121f, 2.804f, - 2.635f, 2.463f, -0.182f, -2.357f, -4.093f, -5.574f, -6.235f, -6.383f, -6.064f, -6.007f, - -5.710f, -5.402f, -5.933f, -6.677f, -7.199f, -7.059f, -7.349f, -8.220f, -9.210f, -9.815f, --10.184f,-10.369f,-10.515f, -9.213f, -7.653f, -6.326f, -5.535f, -4.757f, -4.480f, -0.562f, - 0.420f, 3.559f, 5.127f, 5.364f, 5.157f, 5.508f, 5.163f, 4.448f, 2.087f, 1.175f, - 0.903f, 0.078f, 0.763f, 1.761f, 3.053f, 5.371f, 7.711f, 10.333f, 12.186f, 13.622f, - 15.290f, 15.998f, 15.486f, 15.080f, 15.774f, 16.805f, 18.522f, 21.354f, 24.779f, 27.382f, - 29.877f, 32.474f, 35.583f, 38.520f, 41.410f, 44.507f, 47.837f, 50.550f, 54.083f, 55.925f, - 56.869f, 57.634f, 58.067f, 58.598f, 59.206f, 59.525f, 59.505f, 59.797f, 59.940f, 60.228f, - 60.574f, 61.040f, 61.078f, 59.990f, 60.021f, 60.357f, 60.872f, 61.903f, 63.030f, 63.331f, - 62.788f, 61.512f, 60.290f, 58.946f, 57.613f, 57.526f, 58.964f, 57.683f, 57.766f, 58.676f, - 56.922f, 53.985f, 50.900f, 49.073f, 46.851f, 43.743f, 44.857f, 42.734f, 39.058f, 36.512f, - 36.987f, 34.856f, 31.717f, 29.920f, 26.679f, 24.332f, 21.705f, 20.063f, 17.621f, 15.364f, - 13.606f -},{ --29.534f,-28.202f,-24.914f,-22.069f,-19.352f,-18.816f,-18.689f,-17.780f,-16.946f,-16.230f, --17.094f,-14.394f, -9.003f, -6.976f, -6.888f, -1.771f, -0.537f, -2.279f, -1.113f, 0.499f, - 1.447f, 2.511f, 5.375f, 7.829f, 9.320f, 11.534f, 14.010f, 16.679f, 19.385f, 22.198f, - 23.544f, 24.102f, 23.655f, 23.105f, 21.300f, 8.469f, 14.057f, 16.015f, 15.542f, 12.170f, - 11.097f, 7.527f, 8.452f, 7.392f, 7.034f, 6.801f, 6.881f, 6.844f, 6.358f, 6.184f, - 6.314f, 6.414f, 6.415f, 5.950f, 5.557f, 6.571f, 4.745f, 4.277f, 4.181f, 3.992f, - 3.488f, 2.176f, -0.161f, -1.850f, -3.689f, -4.932f, -5.970f, -6.340f, -6.255f, -6.217f, - -6.023f, -5.422f, -5.680f, -6.479f, -6.855f, -7.056f, -7.412f, -8.365f, -9.062f, -9.189f, - -9.548f, -9.618f, -9.222f, -8.404f, -6.944f, -5.169f, -3.943f, -3.733f, -3.527f, 1.257f, - 2.156f, 5.047f, 6.512f, 6.433f, 6.424f, 6.623f, 6.530f, 5.755f, 4.324f, 2.886f, - 2.785f, 2.274f, 3.140f, 4.265f, 5.678f, 7.846f, 10.109f, 12.699f, 14.432f, 15.426f, - 16.998f, 17.444f, 16.715f, 16.259f, 17.135f, 18.479f, 20.440f, 22.784f, 25.803f, 28.215f, - 30.194f, 32.419f, 35.863f, 39.354f, 42.110f, 44.351f, 48.132f, 50.636f, 55.008f, 57.268f, - 58.756f, 59.482f, 60.233f, 60.869f, 60.922f, 61.268f, 61.434f, 61.625f, 61.732f, 61.735f, - 62.429f, 62.212f, 61.442f, 60.108f, 60.319f, 60.221f, 60.668f, 61.754f, 62.778f, 63.859f, - 63.799f, 62.916f, 61.684f, 60.554f, 59.219f, 58.595f, 59.796f, 58.397f, 58.560f, 59.130f, - 57.182f, 54.734f, 51.123f, 48.809f, 47.217f, 44.749f, 45.970f, 42.917f, 38.732f, 36.057f, - 36.412f, 35.010f, 31.511f, 30.042f, 26.696f, 24.420f, 21.747f, 20.043f, 17.681f, 15.364f, - 13.606f -},{ --29.534f,-28.196f,-24.868f,-21.995f,-19.324f,-18.751f,-18.807f,-18.122f,-17.146f,-15.815f, --15.957f,-13.318f, -8.767f, -5.449f, -6.473f, -1.991f, -1.016f, -2.090f, -1.018f, 0.565f, - 1.501f, 2.463f, 5.294f, 7.551f, 9.015f, 11.281f, 13.728f, 16.682f, 19.037f, 21.658f, - 23.094f, 23.790f, 24.028f, 22.981f, 20.646f, 6.682f, 13.599f, 15.558f, 14.870f, 12.874f, - 11.171f, 9.400f, 9.978f, 9.086f, 8.890f, 8.617f, 8.433f, 8.370f, 7.999f, 7.964f, - 8.072f, 8.174f, 7.993f, 7.349f, 7.353f, 6.292f, 6.233f, 5.839f, 5.552f, 5.386f, - 4.053f, 2.173f, 0.626f, -1.361f, -3.114f, -4.598f, -5.681f, -6.211f, -6.356f, -5.586f, - -5.751f, -5.694f, -6.158f, -6.800f, -6.935f, -7.148f, -7.243f, -8.395f, -8.669f, -8.747f, - -8.932f, -8.627f, -8.059f, -7.481f, -6.490f, -4.784f, -3.461f, -2.782f, -2.458f, 3.586f, - 4.282f, 6.159f, 7.473f, 7.578f, 7.820f, 7.942f, 7.872f, 7.059f, 5.860f, 4.772f, - 4.600f, 4.462f, 5.549f, 6.595f, 7.966f, 10.289f, 12.627f, 14.667f, 16.186f, 16.951f, - 17.920f, 17.734f, 17.120f, 16.867f, 17.992f, 19.339f, 21.550f, 23.367f, 25.558f, 28.123f, - 32.966f, 33.784f, 35.551f, 39.539f, 41.940f, 45.341f, 48.277f, 51.495f, 56.041f, 57.658f, - 59.329f, 60.741f, 61.541f, 62.257f, 62.784f, 63.099f, 63.087f, 62.896f, 63.386f, 63.782f, - 63.052f, 63.343f, 61.960f, 60.303f, 60.739f, 60.473f, 60.719f, 61.349f, 62.698f, 63.684f, - 64.373f, 63.958f, 62.918f, 61.867f, 60.636f, 59.422f, 60.199f, 59.220f, 59.039f, 60.417f, - 56.887f, 53.925f, 50.587f, 48.115f, 47.093f, 45.510f, 46.743f, 42.857f, 38.043f, 35.289f, - 35.719f, 34.936f, 31.220f, 30.098f, 26.691f, 24.495f, 21.784f, 20.020f, 17.742f, 15.365f, - 13.606f -},{ --29.534f,-28.189f,-24.837f,-21.944f,-19.286f,-18.553f,-18.806f,-18.329f,-17.316f,-15.617f, --15.178f,-12.106f, -8.425f, -4.527f, -6.003f, -2.077f, -1.413f, -1.885f, -0.903f, 0.747f, - 1.619f, 2.548f, 5.196f, 7.261f, 8.829f, 11.003f, 13.350f, 16.209f, 18.791f, 20.614f, - 21.765f, 23.171f, 22.820f, 22.331f, 21.148f, 4.085f, 13.107f, 15.533f, 14.533f, 13.327f, - 12.433f, 11.691f, 11.173f, 10.529f, 10.365f, 10.250f, 9.989f, 9.767f, 9.738f, 9.524f, - 9.582f, 9.661f, 9.468f, 8.929f, 9.117f, 7.948f, 7.138f, 6.600f, 5.713f, 4.973f, - 4.141f, 2.254f, 1.147f, -0.766f, -2.269f, -3.913f, -5.182f, -5.978f, -6.418f, -6.616f, - -6.681f, -6.387f, -6.755f, -7.160f, -7.187f, -7.254f, -7.173f, -7.923f, -8.066f, -8.063f, - -8.213f, -7.946f, -7.652f, -7.042f, -5.653f, -4.184f, -3.149f, -2.009f, -0.894f, 4.640f, - 6.024f, 7.128f, 8.428f, 8.424f, 8.742f, 8.773f, 9.299f, 8.658f, 7.199f, 6.768f, - 6.499f, 6.556f, 7.771f, 8.846f, 10.456f, 12.830f, 14.989f, 16.368f, 17.992f, 18.283f, - 18.637f, 17.820f, 17.375f, 17.269f, 18.703f, 20.544f, 22.625f, 24.594f, 25.797f, 27.494f, - 32.657f, 32.237f, 37.948f, 38.406f, 42.015f, 45.944f, 48.502f, 52.014f, 55.495f, 58.478f, - 59.197f, 60.604f, 61.472f, 62.382f, 63.833f, 64.766f, 65.018f, 64.984f, 65.054f, 64.714f, - 64.125f, 63.023f, 61.893f, 60.750f, 60.683f, 60.931f, 60.951f, 61.354f, 62.547f, 63.435f, - 64.306f, 64.668f, 64.002f, 63.030f, 61.847f, 60.867f, 60.641f, 59.864f, 58.873f, 61.196f, - 56.232f, 53.539f, 50.955f, 48.266f, 46.909f, 45.668f, 46.818f, 42.698f, 37.174f, 34.265f, - 34.970f, 34.552f, 30.850f, 30.063f, 26.682f, 24.582f, 21.817f, 19.999f, 17.801f, 15.367f, - 13.606f -},{ --29.534f,-28.182f,-24.822f,-21.912f,-19.223f,-18.274f,-18.682f,-18.281f,-17.221f,-15.578f, --14.911f,-11.151f, -8.329f, -4.014f, -5.319f, -1.837f, -1.543f, -1.815f, -0.901f, 1.008f, - 1.794f, 2.691f, 5.145f, 7.081f, 8.701f, 10.723f, 12.574f, 15.858f, 18.518f, 18.765f, - 17.788f, 22.404f, 22.382f, 20.494f, 16.545f, 3.092f, 13.533f, 15.841f, 15.326f, 15.281f, - 13.878f, 12.575f, 12.568f, 11.986f, 11.868f, 11.806f, 11.655f, 11.190f, 11.407f, 11.135f, - 11.211f, 11.209f, 10.938f, 10.675f, 10.394f, 9.259f, 8.555f, 7.409f, 6.681f, 5.527f, - 4.646f, 2.646f, 1.711f, 0.297f, -1.447f, -3.119f, -4.651f, -5.764f, -6.269f, -6.331f, - -6.790f, -6.928f, -7.267f, -7.584f, -7.384f, -7.275f, -6.990f, -7.415f, -7.731f, -7.772f, - -7.453f, -7.163f, -6.940f, -5.715f, -4.672f, -3.219f, -1.930f, -0.806f, 0.783f, 5.741f, - 7.598f, 8.308f, 9.163f, 9.122f, 9.599f, 9.615f, 9.989f, 10.111f, 8.734f, 8.395f, - 8.442f, 8.551f, 9.885f, 11.206f, 12.940f, 15.454f, 17.414f, 18.313f, 19.697f, 20.001f, - 19.913f, 18.741f, 18.034f, 18.295f, 19.505f, 21.126f, 23.578f, 25.686f, 26.638f, 27.954f, - 30.350f, 32.216f, 33.730f, 37.853f, 41.513f, 44.363f, 48.453f, 52.492f, 55.354f, 58.244f, - 59.515f, 60.487f, 61.460f, 62.265f, 63.715f, 64.687f, 65.709f, 66.012f, 65.604f, 65.092f, - 63.924f, 62.959f, 61.638f, 61.259f, 60.937f, 60.671f, 61.043f, 61.161f, 62.083f, 63.181f, - 64.085f, 64.842f, 64.829f, 63.803f, 63.320f, 62.647f, 61.270f, 60.220f, 59.273f, 60.677f, - 56.652f, 54.403f, 52.854f, 49.461f, 46.877f, 45.318f, 45.919f, 42.341f, 36.197f, 33.114f, - 34.184f, 33.889f, 30.405f, 29.919f, 26.679f, 24.703f, 21.848f, 19.980f, 17.857f, 15.370f, - 13.606f -},{ --29.534f,-28.174f,-24.823f,-21.891f,-19.129f,-17.972f,-18.459f,-17.921f,-16.730f,-15.570f, --14.989f,-10.645f, -8.457f, -3.479f, -4.343f, -1.495f, -1.568f, -1.961f, -0.970f, 1.088f, - 1.946f, 2.803f, 5.217f, 6.982f, 8.551f, 10.499f, 12.121f, 15.350f, 18.289f, 16.653f, - 12.902f, 19.996f, 19.528f, 16.142f, 4.718f, 8.224f, 14.756f, 16.028f, 17.691f, 16.386f, - 14.971f, 13.524f, 13.999f, 13.650f, 13.270f, 13.358f, 13.166f, 12.552f, 12.821f, 12.668f, - 12.915f, 12.662f, 12.532f, 12.177f, 11.806f, 11.077f, 9.495f, 8.400f, 7.770f, 6.348f, - 4.914f, 3.402f, 2.379f, 1.333f, -0.495f, -2.194f, -3.904f, -5.200f, -5.955f, -6.219f, - -6.690f, -7.171f, -7.372f, -7.592f, -7.405f, -7.005f, -6.602f, -7.071f, -7.206f, -7.076f, - -6.841f, -6.126f, -5.914f, -4.727f, -3.468f, -1.805f, -0.873f, 0.456f, 2.359f, 5.933f, - 8.608f, 8.974f, 9.665f, 9.929f, 10.461f, 10.809f, 10.880f, 11.537f, 10.201f, 10.211f, - 10.173f, 10.407f, 11.849f, 13.012f, 15.114f, 17.537f, 19.244f, 21.204f, 21.805f, 22.053f, - 21.416f, 20.051f, 19.068f, 19.796f, 20.471f, 21.372f, 24.263f, 26.009f, 26.818f, 28.609f, - 30.592f, 31.672f, 34.069f, 38.103f, 39.503f, 43.168f, 47.737f, 52.101f, 55.458f, 57.150f, - 58.541f, 59.806f, 60.878f, 62.320f, 63.855f, 64.758f, 65.730f, 65.986f, 65.093f, 64.486f, - 63.659f, 62.861f, 61.999f, 61.497f, 61.030f, 61.041f, 60.871f, 61.132f, 61.698f, 62.648f, - 63.681f, 64.648f, 65.107f, 64.711f, 64.505f, 63.786f, 62.245f, 60.108f, 59.755f, 59.801f, - 57.775f, 54.037f, 54.057f, 50.252f, 47.066f, 45.163f, 44.090f, 41.278f, 35.040f, 31.981f, - 33.393f, 33.092f, 29.881f, 29.669f, 26.680f, 24.868f, 21.882f, 19.967f, 17.909f, 15.375f, - 13.606f -},{ --29.534f,-28.165f,-24.838f,-21.879f,-19.003f,-17.700f,-18.173f,-17.282f,-15.870f,-15.450f, --15.082f,-10.533f, -8.476f, -2.864f, -3.373f, -1.376f, -1.449f, -2.031f, -0.916f, 1.033f, - 1.990f, 2.905f, 5.249f, 6.886f, 8.431f, 10.321f, 12.259f, 14.768f, 17.934f, 16.640f, - 10.302f, 14.587f, 15.214f, 8.242f, 5.398f, 14.917f, 17.025f, 17.431f, 17.402f, 17.108f, - 15.827f, 14.725f, 15.370f, 14.807f, 14.567f, 14.984f, 14.723f, 14.156f, 14.409f, 14.195f, - 14.421f, 14.198f, 14.025f, 13.473f, 13.283f, 12.255f, 10.678f, 9.273f, 8.775f, 7.437f, - 5.761f, 4.473f, 3.305f, 2.297f, 0.706f, -1.029f, -2.947f, -4.260f, -5.244f, -5.868f, - -6.362f, -7.021f, -6.968f, -7.121f, -6.668f, -6.225f, -6.021f, -6.371f, -6.161f, -5.991f, - -5.939f, -5.121f, -4.740f, -3.576f, -2.084f, -0.972f, 0.189f, 1.408f, 4.183f, 6.732f, - 10.096f, 9.890f, 10.445f, 10.795f, 11.611f, 12.105f, 12.412f, 12.792f, 11.667f, 11.839f, - 11.388f, 12.265f, 13.575f, 14.448f, 16.543f, 20.440f, 21.213f, 29.185f, 23.628f, 23.349f, - 22.638f, 21.077f, 20.477f, 21.085f, 21.727f, 21.990f, 24.074f, 26.011f, 26.812f, 28.522f, - 30.096f, 30.860f, 33.357f, 37.217f, 38.287f, 42.503f, 48.161f, 52.320f, 54.788f, 56.443f, - 57.636f, 59.109f, 60.387f, 62.174f, 63.635f, 64.969f, 65.928f, 65.606f, 64.617f, 64.182f, - 63.445f, 62.916f, 61.916f, 61.413f, 61.117f, 61.301f, 61.162f, 61.053f, 61.335f, 62.123f, - 63.264f, 64.173f, 65.045f, 65.390f, 64.819f, 64.343f, 63.207f, 60.535f, 59.200f, 58.973f, - 57.764f, 52.664f, 53.458f, 49.865f, 47.533f, 45.834f, 41.835f, 39.028f, 33.630f, 30.955f, - 32.679f, 32.352f, 29.275f, 29.337f, 26.679f, 25.079f, 21.923f, 19.962f, 17.956f, 15.380f, - 13.606f -},{ --29.534f,-28.156f,-24.865f,-21.870f,-18.853f,-17.496f,-17.862f,-16.471f,-14.805f,-15.136f, --14.944f,-10.647f, -8.134f, -2.414f, -2.757f, -1.414f, -0.889f, -1.678f, -0.751f, 1.107f, - 1.997f, 3.000f, 5.211f, 6.711f, 8.366f, 10.189f, 12.295f, 14.297f, 17.673f, 16.811f, - 13.338f, 9.420f, 9.604f, 8.660f, 14.807f, 18.347f, 19.165f, 19.223f, 18.332f, 17.280f, - 16.851f, 15.996f, 16.223f, 15.981f, 15.888f, 16.548f, 16.305f, 15.969f, 16.040f, 15.990f, - 15.708f, 15.673f, 15.234f, 14.868f, 14.315f, 13.675f, 11.532f, 10.756f, 9.865f, 8.402f, - 6.873f, 5.428f, 4.356f, 3.185f, 1.701f, 0.200f, -1.777f, -3.334f, -4.578f, -4.990f, - -5.648f, -6.242f, -6.097f, -6.002f, -5.513f, -5.317f, -5.131f, -5.237f, -4.943f, -4.738f, - -4.404f, -3.656f, -3.727f, -2.327f, -0.658f, 0.108f, 1.350f, 2.332f, 5.317f, 7.485f, - 10.195f, 10.279f, 10.837f, 11.398f, 12.115f, 13.276f, 13.310f, 13.928f, 13.021f, 13.221f, - 12.934f, 13.929f, 14.568f, 15.743f, 17.619f, 24.834f, 22.615f, 25.150f, 24.693f, 24.396f, - 23.430f, 22.376f, 21.842f, 22.365f, 22.980f, 23.348f, 24.585f, 25.444f, 26.781f, 28.649f, - 29.816f, 30.377f, 32.666f, 35.349f, 38.269f, 42.000f, 46.854f, 49.196f, 53.150f, 54.659f, - 56.617f, 58.047f, 59.750f, 61.605f, 63.118f, 64.413f, 65.414f, 65.160f, 63.650f, 64.026f, - 62.968f, 62.965f, 62.264f, 60.816f, 60.801f, 60.759f, 61.907f, 61.060f, 61.012f, 61.525f, - 62.736f, 63.895f, 64.795f, 65.492f, 65.224f, 65.146f, 63.817f, 61.916f, 58.915f, 58.607f, - 56.806f, 53.191f, 52.770f, 49.360f, 48.041f, 46.974f, 39.898f, 35.842f, 32.065f, 30.052f, - 32.153f, 31.818f, 28.601f, 28.971f, 26.667f, 25.327f, 21.976f, 19.965f, 17.997f, 15.386f, - 13.606f -},{ --29.534f,-28.146f,-24.904f,-21.863f,-18.690f,-17.370f,-17.555f,-15.635f,-13.757f,-14.653f, --14.548f,-10.828f, -7.510f, -2.147f, -2.364f, -1.306f, -0.056f, -0.923f, -0.615f, 1.208f, - 2.022f, 3.108f, 5.228f, 6.461f, 8.317f, 9.983f, 11.632f, 13.914f, 16.977f, 16.491f, - 18.484f, 14.749f, 14.545f, 16.166f, 18.577f, 20.445f, 20.940f, 19.398f, 18.774f, 18.041f, - 17.869f, 17.491f, 17.519f, 17.421f, 17.332f, 17.744f, 17.803f, 17.581f, 17.673f, 17.501f, - 17.107f, 16.996f, 16.425f, 15.990f, 15.540f, 14.676f, 12.772f, 11.972f, 11.057f, 9.323f, - 7.838f, 6.477f, 5.284f, 4.089f, 2.631f, 1.187f, -0.709f, -2.201f, -3.488f, -4.124f, - -4.755f, -4.913f, -4.673f, -4.193f, -4.224f, -4.227f, -4.069f, -4.048f, -3.575f, -3.271f, - -2.633f, -2.078f, -1.954f, -0.538f, 0.709f, 1.687f, 2.823f, 3.546f, 5.985f, 8.494f, - 10.181f, 10.879f, 11.235f, 11.978f, 12.993f, 14.436f, 15.237f, 15.451f, 14.984f, 14.518f, - 14.489f, 15.106f, 15.326f, 16.481f, 18.238f, 25.235f, 31.100f, 27.099f, 25.430f, 25.692f, - 24.552f, 23.320f, 23.137f, 23.389f, 23.952f, 24.736f, 25.683f, 25.873f, 27.156f, 29.227f, - 30.501f, 31.642f, 33.036f, 34.742f, 37.623f, 41.249f, 45.233f, 48.569f, 51.548f, 53.552f, - 55.695f, 57.279f, 59.365f, 61.697f, 62.567f, 63.814f, 64.066f, 64.049f, 62.780f, 63.378f, - 62.881f, 63.056f, 61.772f, 60.296f, 60.067f, 60.030f, 62.766f, 61.051f, 60.970f, 60.947f, - 62.116f, 63.291f, 64.377f, 65.152f, 65.897f, 65.723f, 64.557f, 62.938f, 59.650f, 58.779f, - 56.253f, 54.973f, 52.981f, 49.779f, 48.211f, 47.452f, 38.762f, 32.837f, 30.627f, 29.264f, - 31.888f, 31.525f, 27.901f, 28.626f, 26.634f, 25.590f, 22.044f, 19.978f, 18.032f, 15.392f, - 13.606f -},{ --29.534f,-28.136f,-24.952f,-21.855f,-18.526f,-17.312f,-17.261f,-14.908f,-12.917f,-14.120f, --14.038f,-10.952f, -6.879f, -1.799f, -1.759f, -1.022f, 0.518f, 0.013f, -0.397f, 1.206f, - 2.054f, 3.300f, 5.269f, 6.352f, 8.060f, 9.820f, 11.238f, 13.609f, 16.469f, 17.213f, - 19.620f, 18.391f, 18.277f, 18.846f, 19.759f, 21.203f, 20.578f, 19.775f, 19.397f, 18.662f, - 18.943f, 18.783f, 18.749f, 18.916f, 18.866f, 19.226f, 19.102f, 19.203f, 19.070f, 18.928f, - 18.685f, 18.152f, 17.824f, 16.749f, 16.624f, 15.844f, 13.678f, 12.948f, 11.733f, 10.246f, - 8.656f, 7.412f, 6.233f, 4.964f, 3.643f, 2.235f, 0.410f, -1.120f, -2.190f, -3.037f, - -3.488f, -3.403f, -2.612f, -2.340f, -2.855f, -2.932f, -2.740f, -2.730f, -2.186f, -1.446f, - -0.783f, -0.214f, 0.139f, 1.238f, 2.484f, 3.120f, 4.564f, 4.758f, 7.557f, 8.309f, - 10.654f, 11.935f, 11.541f, 12.955f, 14.124f, 15.391f, 15.960f, 17.424f, 16.681f, 16.124f, - 15.738f, 15.673f, 16.485f, 17.499f, 19.028f, 21.321f, 25.145f, 25.238f, 25.968f, 26.800f, - 25.555f, 23.905f, 23.775f, 24.219f, 25.095f, 26.172f, 27.288f, 27.652f, 28.337f, 30.444f, - 31.952f, 33.351f, 34.150f, 35.162f, 37.528f, 40.816f, 43.523f, 48.556f, 50.543f, 51.920f, - 54.169f, 56.437f, 58.362f, 60.799f, 62.591f, 62.830f, 63.051f, 62.228f, 62.624f, 63.140f, - 62.686f, 63.097f, 61.579f, 60.137f, 60.248f, 60.196f, 62.989f, 61.564f, 60.994f, 60.777f, - 61.004f, 62.714f, 64.034f, 64.895f, 66.313f, 66.007f, 65.173f, 63.265f, 60.598f, 59.004f, - 56.840f, 55.864f, 53.440f, 50.686f, 48.117f, 46.664f, 38.350f, 31.251f, 29.653f, 28.635f, - 31.851f, 31.394f, 27.253f, 28.353f, 26.579f, 25.843f, 22.128f, 20.001f, 18.062f, 15.399f, - 13.606f -},{ --29.534f,-28.125f,-25.006f,-21.847f,-18.373f,-17.292f,-16.975f,-14.373f,-12.370f,-13.679f, --13.579f,-10.909f, -6.425f, -1.346f, -0.948f, -0.804f, 0.875f, 0.926f, -0.011f, 1.230f, - 2.152f, 3.579f, 5.361f, 6.425f, 7.753f, 9.709f, 11.262f, 13.122f, 16.363f, 17.788f, - 20.225f, 19.713f, 19.530f, 19.641f, 20.061f, 20.263f, 20.972f, 20.117f, 19.982f, 19.590f, - 19.888f, 19.556f, 19.946f, 20.275f, 20.283f, 20.834f, 20.572f, 20.410f, 20.387f, 20.335f, - 19.602f, 19.094f, 18.834f, 17.863f, 17.600f, 16.456f, 14.662f, 13.656f, 12.546f, 11.001f, - 9.441f, 8.249f, 7.128f, 5.880f, 4.610f, 3.267f, 1.526f, 0.068f, -0.855f, -1.699f, - -2.108f, -1.870f, -1.428f, -1.156f, -1.565f, -1.557f, -1.191f, -1.118f, -0.371f, 0.540f, - 1.566f, 2.313f, 2.057f, 3.297f, 4.038f, 4.860f, 5.753f, 6.266f, 8.368f, 8.751f, - 11.591f, 12.780f, 11.669f, 13.433f, 14.951f, 17.049f, 17.254f, 17.034f, 18.666f, 18.600f, - 15.747f, 16.258f, 17.976f, 18.931f, 20.242f, 21.612f, 23.584f, 25.323f, 26.681f, 26.683f, - 25.350f, 23.981f, 23.943f, 24.912f, 26.525f, 28.063f, 29.296f, 29.630f, 29.625f, 31.596f, - 33.359f, 34.636f, 35.682f, 36.270f, 38.384f, 40.238f, 42.705f, 48.016f, 50.028f, 50.667f, - 53.536f, 56.102f, 57.464f, 59.654f, 60.887f, 61.769f, 61.468f, 62.106f, 62.563f, 62.688f, - 62.770f, 62.174f, 60.856f, 60.287f, 60.423f, 59.763f, 61.099f, 61.752f, 60.906f, 60.664f, - 60.629f, 62.002f, 63.594f, 64.563f, 66.295f, 66.509f, 65.289f, 63.553f, 61.375f, 59.378f, - 58.478f, 56.486f, 54.112f, 51.183f, 48.186f, 45.233f, 38.217f, 31.438f, 29.351f, 28.283f, - 31.910f, 31.301f, 26.764f, 28.175f, 26.504f, 26.058f, 22.226f, 20.032f, 18.084f, 15.406f, - 13.606f -},{ --29.534f,-28.114f,-25.066f,-21.839f,-18.241f,-17.272f,-16.678f,-14.034f,-12.082f,-13.402f, --13.233f,-10.646f, -6.110f, -1.166f, -0.501f, -0.728f, 1.514f, 1.694f, 0.396f, 1.217f, - 2.420f, 3.898f, 5.579f, 6.433f, 7.607f, 9.363f, 10.786f, 12.993f, 15.820f, 18.026f, - 20.839f, 20.577f, 19.806f, 19.821f, 20.526f, 20.486f, 21.032f, 20.866f, 20.419f, 20.203f, - 20.422f, 20.504f, 21.041f, 21.499f, 21.532f, 22.031f, 21.922f, 21.620f, 21.773f, 21.438f, - 20.882f, 19.990f, 19.729f, 18.836f, 18.275f, 17.087f, 15.684f, 14.493f, 13.298f, 11.733f, - 10.248f, 8.999f, 7.892f, 6.858f, 5.574f, 4.276f, 2.677f, 1.465f, 0.515f, -0.281f, - -0.627f, -0.167f, -0.182f, 0.115f, -0.064f, -0.076f, 0.370f, 0.658f, 1.521f, 2.490f, - 3.870f, 4.330f, 4.300f, 5.285f, 5.647f, 6.666f, 7.475f, 8.000f, 9.837f, 10.496f, - 12.605f, 12.554f, 12.141f, 14.657f, 15.681f, 16.841f, 18.446f, 18.485f, 18.677f, 19.779f, - 17.071f, 17.475f, 18.811f, 20.121f, 21.483f, 23.172f, 24.978f, 26.238f, 26.140f, 26.176f, - 25.261f, 23.872f, 24.037f, 25.877f, 28.108f, 30.526f, 32.061f, 31.485f, 31.414f, 32.408f, - 34.150f, 35.678f, 37.935f, 39.592f, 40.163f, 41.028f, 41.409f, 46.624f, 48.626f, 51.082f, - 51.872f, 54.055f, 56.727f, 57.687f, 59.893f, 60.760f, 60.855f, 61.910f, 62.136f, 62.344f, - 61.655f, 61.522f, 60.935f, 60.326f, 61.042f, 60.830f, 61.092f, 61.331f, 61.393f, 60.282f, - 60.658f, 61.386f, 63.098f, 63.360f, 66.727f, 66.912f, 65.564f, 63.774f, 61.869f, 59.761f, - 59.554f, 57.054f, 55.069f, 51.295f, 48.541f, 44.217f, 37.992f, 32.594f, 29.676f, 28.326f, - 31.914f, 31.170f, 26.544f, 28.088f, 26.421f, 26.214f, 22.333f, 20.071f, 18.100f, 15.413f, - 13.606f -},{ --29.534f,-28.102f,-25.127f,-21.831f,-18.138f,-17.215f,-16.355f,-13.832f,-11.937f,-13.255f, --12.951f,-10.229f, -5.792f, -1.436f, -0.709f, -0.521f, 2.332f, 2.565f, 1.018f, 1.118f, - 2.867f, 4.234f, 5.825f, 6.499f, 7.331f, 9.083f, 10.516f, 12.734f, 14.840f, 17.930f, - 21.094f, 20.934f, 19.790f, 20.026f, 20.186f, 20.818f, 21.081f, 21.392f, 21.020f, 20.990f, - 21.092f, 21.346f, 22.046f, 22.511f, 22.745f, 23.112f, 22.980f, 22.737f, 22.710f, 22.171f, - 21.838f, 20.814f, 20.454f, 19.741f, 18.966f, 17.813f, 16.416f, 15.274f, 13.994f, 12.458f, - 11.045f, 9.918f, 8.888f, 7.779f, 6.702f, 5.383f, 4.046f, 2.868f, 1.837f, 1.222f, - 0.972f, 1.361f, 1.611f, 1.952f, 1.513f, 1.448f, 2.013f, 2.352f, 3.156f, 4.323f, - 5.306f, 6.251f, 6.422f, 7.577f, 8.192f, 8.790f, 9.719f, 9.616f, 11.878f, 13.079f, - 12.859f, 12.229f, 12.792f, 14.543f, 15.713f, 17.085f, 17.774f, 18.981f, 19.216f, 18.796f, - 18.852f, 19.080f, 20.003f, 21.409f, 23.553f, 24.752f, 25.823f, 26.619f, 26.296f, 26.228f, - 25.671f, 24.735f, 24.860f, 26.875f, 30.075f, 32.979f, 34.198f, 33.704f, 33.567f, 33.706f, - 34.798f, 37.072f, 39.478f, 43.128f, 41.987f, 42.091f, 41.516f, 45.844f, 47.906f, 49.476f, - 50.885f, 52.127f, 55.149f, 58.340f, 58.045f, 59.381f, 60.815f, 61.141f, 61.507f, 61.441f, - 61.107f, 59.969f, 58.997f, 60.085f, 60.719f, 61.696f, 61.241f, 60.303f, 61.142f, 60.681f, - 60.375f, 60.804f, 62.499f, 62.976f, 67.146f, 67.182f, 65.816f, 63.806f, 62.236f, 60.002f, - 59.039f, 56.532f, 55.313f, 51.704f, 49.043f, 43.999f, 37.676f, 33.470f, 30.301f, 28.752f, - 31.791f, 31.012f, 26.667f, 28.057f, 26.344f, 26.294f, 22.441f, 20.115f, 18.109f, 15.420f, - 13.606f -},{ --29.534f,-28.090f,-25.189f,-21.825f,-18.065f,-17.095f,-16.002f,-13.675f,-11.802f,-13.131f, --12.651f, -9.831f, -5.411f, -1.644f, -0.980f, 0.184f, 2.704f, 3.989f, 2.259f, 1.327f, - 3.313f, 4.543f, 6.022f, 6.707f, 7.109f, 8.812f, 10.459f, 11.946f, 14.316f, 17.459f, - 21.035f, 20.876f, 19.482f, 19.884f, 20.199f, 21.078f, 21.514f, 21.808f, 21.650f, 21.849f, - 21.811f, 22.535f, 22.832f, 23.479f, 23.880f, 23.930f, 23.804f, 23.812f, 23.586f, 23.085f, - 22.552f, 21.734f, 21.438f, 20.631f, 19.614f, 18.151f, 17.174f, 15.901f, 14.604f, 13.255f, - 11.852f, 10.784f, 9.738f, 8.713f, 7.808f, 6.572f, 5.409f, 4.179f, 3.115f, 2.774f, - 2.578f, 3.183f, 3.415f, 3.707f, 3.315f, 3.045f, 3.530f, 4.032f, 4.679f, 5.739f, - 6.860f, 7.854f, 8.312f, 9.479f, 10.125f, 10.677f, 11.290f, 11.319f, 13.057f, 15.272f, - 14.834f, 12.260f, 13.140f, 15.442f, 16.555f, 17.383f, 18.156f, 19.444f, 19.956f, 20.941f, - 20.878f, 19.944f, 21.272f, 22.742f, 25.710f, 27.826f, 27.106f, 27.458f, 26.472f, 26.035f, - 27.676f, 28.140f, 27.131f, 28.549f, 31.167f, 32.962f, 33.727f, 34.192f, 38.058f, 39.078f, - 35.500f, 37.246f, 39.865f, 45.191f, 43.092f, 43.823f, 42.751f, 45.647f, 48.571f, 49.286f, - 51.690f, 51.802f, 54.150f, 57.715f, 58.353f, 58.540f, 60.480f, 60.298f, 60.661f, 60.294f, - 59.654f, 58.738f, 57.938f, 59.632f, 60.778f, 61.499f, 61.347f, 59.795f, 60.699f, 60.666f, - 59.862f, 60.486f, 61.703f, 63.022f, 66.196f, 67.258f, 65.467f, 63.680f, 62.347f, 60.517f, - 58.503f, 55.992f, 54.463f, 52.524f, 49.708f, 44.258f, 37.615f, 33.415f, 30.765f, 29.373f, - 31.581f, 30.904f, 27.148f, 28.034f, 26.289f, 26.293f, 22.542f, 20.162f, 18.112f, 15.427f, - 13.606f -},{ --29.534f,-28.078f,-25.248f,-21.822f,-18.022f,-16.906f,-15.631f,-13.480f,-11.592f,-12.931f, --12.299f, -9.598f, -5.035f, -1.103f, -0.451f, 1.505f, 2.660f, 5.692f, 3.910f, 2.098f, - 3.574f, 4.840f, 6.185f, 6.808f, 7.236f, 8.651f, 10.200f, 11.545f, 13.971f, 16.797f, - 20.619f, 21.264f, 19.338f, 20.348f, 20.377f, 21.492f, 21.848f, 22.488f, 22.411f, 22.630f, - 22.595f, 23.430f, 24.067f, 24.590f, 24.890f, 24.893f, 24.831f, 24.823f, 24.594f, 24.246f, - 23.287f, 22.537f, 21.977f, 20.890f, 19.710f, 18.264f, 17.522f, 16.354f, 15.126f, 13.845f, - 12.632f, 11.692f, 10.627f, 9.681f, 8.942f, 7.814f, 6.688f, 5.402f, 4.474f, 4.177f, - 4.206f, 4.839f, 4.839f, 5.018f, 4.907f, 4.624f, 4.908f, 5.457f, 6.111f, 7.100f, - 8.020f, 9.436f, 9.709f, 10.494f, 11.721f, 12.404f, 12.822f, 13.057f, 14.204f, 16.564f, - 16.515f, 14.631f, 13.664f, 16.253f, 17.113f, 17.956f, 18.815f, 20.199f, 21.273f, 23.052f, - 25.424f, 26.159f, 27.278f, 28.622f, 29.012f, 30.472f, 29.723f, 29.778f, 28.367f, 28.729f, - 31.206f, 31.615f, 32.665f, 33.299f, 33.373f, 31.238f, 30.811f, 33.272f, 45.418f, 37.064f, - 36.659f, 37.905f, 40.612f, 48.065f, 44.249f, 47.459f, 45.105f, 46.954f, 47.128f, 48.918f, - 50.562f, 51.382f, 53.639f, 56.511f, 58.497f, 58.957f, 58.985f, 59.111f, 59.799f, 58.977f, - 58.217f, 57.676f, 57.492f, 59.165f, 59.713f, 60.204f, 61.978f, 60.402f, 59.591f, 59.858f, - 59.714f, 60.074f, 61.009f, 62.232f, 65.209f, 66.703f, 65.239f, 63.422f, 61.881f, 60.835f, - 58.974f, 56.659f, 53.664f, 52.958f, 50.441f, 44.692f, 38.165f, 32.824f, 30.784f, 29.917f, - 31.395f, 30.907f, 27.922f, 27.970f, 26.271f, 26.214f, 22.626f, 20.209f, 18.109f, 15.434f, - 13.606f -},{ --29.534f,-28.065f,-25.302f,-21.823f,-18.007f,-16.657f,-15.270f,-13.202f,-11.299f,-12.633f, --11.930f, -9.529f, -4.749f, 0.145f, 0.968f, 3.110f, 2.967f, 6.715f, 5.521f, 3.278f, - 3.752f, 5.136f, 6.291f, 6.968f, 7.373f, 8.654f, 10.084f, 11.600f, 13.854f, 16.179f, - 19.687f, 20.861f, 19.435f, 20.922f, 21.080f, 21.975f, 22.359f, 22.793f, 22.910f, 23.453f, - 23.498f, 24.084f, 24.865f, 25.714f, 25.705f, 25.890f, 25.688f, 25.358f, 25.136f, 24.502f, - 23.883f, 23.257f, 21.896f, 20.657f, 19.518f, 18.617f, 17.687f, 16.577f, 15.733f, 14.439f, - 13.376f, 12.420f, 11.579f, 10.837f, 9.986f, 9.059f, 7.994f, 6.730f, 6.070f, 5.590f, - 5.627f, 6.030f, 6.132f, 6.251f, 6.187f, 5.987f, 6.263f, 6.836f, 7.388f, 8.410f, - 9.223f, 10.492f, 10.850f, 12.112f, 12.870f, 13.915f, 14.456f, 14.709f, 15.349f, 18.233f, - 18.261f, 16.228f, 14.394f, 16.753f, 17.970f, 18.892f, 19.799f, 21.024f, 22.698f, 25.141f, - 28.759f, 28.193f, 28.217f, 29.796f, 30.199f, 29.379f, 30.052f, 31.613f, 32.799f, 33.071f, - 32.595f, 34.733f, 35.952f, 35.634f, 34.747f, 33.608f, 31.244f, 31.773f, 44.216f, 36.692f, - 38.927f, 38.674f, 40.152f, 45.124f, 45.854f, 48.104f, 47.277f, 47.169f, 48.163f, 48.385f, - 49.433f, 51.086f, 52.735f, 55.561f, 55.745f, 58.817f, 58.577f, 58.102f, 58.432f, 58.023f, - 57.512f, 57.073f, 58.028f, 58.641f, 58.983f, 58.459f, 61.588f, 59.584f, 59.527f, 58.898f, - 59.741f, 59.725f, 60.534f, 61.279f, 64.681f, 66.280f, 65.252f, 63.186f, 61.392f, 60.478f, - 59.433f, 57.349f, 53.767f, 52.380f, 50.719f, 45.317f, 39.329f, 32.679f, 30.528f, 30.227f, - 31.317f, 31.006f, 28.864f, 27.839f, 26.299f, 26.068f, 22.685f, 20.252f, 18.100f, 15.441f, - 13.606f -},{ --29.534f,-28.053f,-25.350f,-21.829f,-18.014f,-16.377f,-14.954f,-12.854f,-10.978f,-12.305f, --11.605f, -9.488f, -4.538f, 1.304f, 2.552f, 4.426f, 3.970f, 6.838f, 6.983f, 4.809f, - 4.100f, 5.307f, 6.333f, 7.157f, 7.517f, 8.647f, 10.051f, 11.241f, 13.521f, 15.896f, - 19.164f, 21.320f, 19.371f, 21.067f, 21.330f, 22.332f, 22.652f, 23.290f, 23.554f, 24.257f, - 24.636f, 24.871f, 25.578f, 26.420f, 26.628f, 26.328f, 25.456f, 25.179f, 24.892f, 24.389f, - 23.865f, 23.093f, 21.902f, 20.738f, 19.550f, 18.684f, 18.129f, 17.284f, 16.215f, 15.028f, - 14.181f, 13.186f, 12.431f, 11.817f, 11.085f, 10.257f, 9.268f, 8.105f, 7.569f, 7.088f, - 6.886f, 7.128f, 7.192f, 7.417f, 7.314f, 7.265f, 7.767f, 8.667f, 8.680f, 9.759f, - 10.473f, 11.764f, 12.114f, 12.854f, 13.981f, 15.013f, 15.841f, 16.153f, 17.002f, 17.821f, - 18.763f, 16.660f, 14.846f, 17.530f, 19.002f, 19.893f, 20.810f, 21.848f, 23.988f, 28.611f, - 30.376f, 28.830f, 29.243f, 30.966f, 30.491f, 30.921f, 31.536f, 32.165f, 32.356f, 33.895f, - 33.633f, 35.801f, 35.765f, 37.562f, 37.243f, 33.970f, 33.609f, 31.707f, 40.889f, 36.019f, - 39.500f, 41.097f, 40.479f, 42.653f, 45.228f, 46.412f, 48.779f, 50.747f, 48.519f, 49.050f, - 48.392f, 49.629f, 51.132f, 53.139f, 54.662f, 57.225f, 56.714f, 57.026f, 57.263f, 56.926f, - 56.608f, 58.999f, 60.508f, 60.171f, 58.015f, 57.566f, 60.127f, 60.360f, 59.984f, 58.811f, - 59.927f, 59.590f, 60.126f, 60.621f, 64.009f, 65.880f, 64.406f, 62.836f, 60.854f, 60.054f, - 59.323f, 57.319f, 54.251f, 51.273f, 50.195f, 46.125f, 40.665f, 33.675f, 30.568f, 30.356f, - 31.348f, 31.124f, 29.823f, 27.652f, 26.378f, 25.873f, 22.713f, 20.291f, 18.086f, 15.447f, - 13.606f -},{ --29.534f,-28.040f,-25.389f,-21.840f,-18.036f,-16.102f,-14.713f,-12.492f,-10.708f,-12.043f, --11.356f, -9.344f, -4.316f, 1.754f, 3.710f, 5.269f, 5.178f, 6.900f, 7.892f, 6.582f, - 4.724f, 5.445f, 6.336f, 7.137f, 7.672f, 8.713f, 9.962f, 10.966f, 13.052f, 15.920f, - 18.417f, 20.643f, 18.639f, 21.151f, 21.741f, 22.453f, 23.144f, 23.881f, 24.294f, 24.828f, - 25.468f, 25.819f, 26.217f, 27.401f, 27.008f, 26.211f, 25.579f, 25.272f, 24.939f, 24.415f, - 23.667f, 22.865f, 21.864f, 20.546f, 19.280f, 18.398f, 17.873f, 17.383f, 16.427f, 15.801f, - 15.021f, 13.818f, 13.331f, 13.033f, 12.291f, 11.541f, 10.964f, 9.528f, 9.108f, 8.394f, - 8.246f, 8.159f, 8.233f, 8.706f, 8.385f, 8.701f, 8.830f, 9.311f, 9.632f, 10.661f, - 11.995f, 13.258f, 14.334f, 14.096f, 15.158f, 16.146f, 17.024f, 17.603f, 18.239f, 18.509f, - 19.316f, 17.207f, 15.959f, 18.058f, 19.347f, 20.253f, 21.666f, 23.057f, 30.599f, 32.346f, - 31.335f, 31.051f, 30.187f, 30.740f, 31.241f, 31.997f, 33.221f, 33.849f, 34.679f, 35.095f, - 33.649f, 35.292f, 35.589f, 37.154f, 39.815f, 37.128f, 35.979f, 36.074f, 41.228f, 42.236f, - 40.616f, 44.012f, 41.659f, 41.054f, 43.224f, 45.747f, 45.761f, 52.187f, 50.144f, 50.421f, - 47.031f, 48.571f, 50.530f, 50.804f, 55.243f, 55.462f, 55.001f, 56.074f, 56.382f, 55.786f, - 56.070f, 60.145f, 60.964f, 61.495f, 58.021f, 57.153f, 57.624f, 59.600f, 59.558f, 58.248f, - 59.581f, 59.457f, 60.326f, 60.914f, 63.172f, 64.338f, 63.308f, 61.989f, 59.959f, 59.606f, - 58.949f, 57.373f, 54.290f, 50.566f, 49.281f, 46.823f, 41.645f, 35.670f, 31.400f, 30.499f, - 31.426f, 31.193f, 30.661f, 27.448f, 26.502f, 25.646f, 22.708f, 20.321f, 18.068f, 15.453f, - 13.606f -},{ --29.534f,-28.027f,-25.419f,-21.856f,-18.067f,-15.869f,-14.558f,-12.187f,-10.538f,-11.898f, --11.156f, -9.077f, -4.064f, 1.685f, 4.525f, 6.143f, 6.078f, 7.348f, 7.943f, 8.267f, - 5.565f, 5.810f, 6.294f, 7.182f, 7.709f, 8.595f, 9.770f, 11.079f, 12.982f, 15.861f, - 18.100f, 20.396f, 19.002f, 21.326f, 21.830f, 22.841f, 23.421f, 24.394f, 24.759f, 25.337f, - 26.015f, 26.551f, 27.122f, 27.620f, 26.870f, 26.068f, 25.747f, 25.161f, 24.778f, 24.258f, - 23.223f, 22.691f, 21.642f, 20.583f, 18.925f, 17.886f, 17.331f, 16.718f, 16.226f, 15.904f, - 15.257f, 14.543f, 14.135f, 13.594f, 12.957f, 12.334f, 11.756f, 11.039f, 10.458f, 9.857f, - 9.820f, 9.747f, 9.529f, 9.240f, 9.159f, 9.539f, 9.333f, 9.458f, 9.865f, 11.874f, - 13.254f, 14.218f, 15.076f, 15.097f, 16.454f, 17.465f, 18.290f, 18.768f, 19.561f, 19.479f, - 19.476f, 17.236f, 17.973f, 19.331f, 20.318f, 21.272f, 22.756f, 26.736f, 32.665f, 32.068f, - 32.780f, 32.285f, 30.297f, 31.018f, 32.188f, 33.193f, 31.784f, 30.446f, 30.850f, 32.112f, - 33.617f, 35.455f, 36.827f, 38.961f, 39.193f, 39.455f, 38.815f, 38.258f, 39.493f, 42.125f, - 44.465f, 44.226f, 42.922f, 42.261f, 41.925f, 47.748f, 46.101f, 48.142f, 48.123f, 50.916f, - 45.930f, 48.003f, 50.154f, 51.824f, 53.070f, 56.170f, 54.190f, 55.219f, 54.695f, 56.474f, - 57.154f, 58.363f, 60.239f, 60.425f, 58.500f, 56.336f, 56.572f, 56.516f, 57.092f, 56.389f, - 58.468f, 59.579f, 60.434f, 61.582f, 62.669f, 63.069f, 62.915f, 60.339f, 59.364f, 58.906f, - 58.517f, 57.582f, 53.843f, 50.459f, 48.634f, 47.057f, 42.162f, 37.859f, 32.949f, 30.811f, - 31.501f, 31.229f, 31.283f, 27.292f, 26.656f, 25.407f, 22.672f, 20.342f, 18.045f, 15.458f, - 13.606f -},{ --29.534f,-28.014f,-25.438f,-21.876f,-18.100f,-15.706f,-14.480f,-11.996f,-10.469f,-11.839f, --10.935f, -8.753f, -3.873f, 1.658f, 5.288f, 7.563f, 6.695f, 7.659f, 8.172f, 9.786f, - 6.569f, 6.289f, 6.294f, 7.190f, 7.825f, 8.562f, 9.763f, 10.820f, 12.894f, 15.459f, - 17.609f, 19.951f, 19.083f, 21.599f, 22.018f, 23.191f, 23.914f, 24.848f, 25.153f, 25.880f, - 26.281f, 26.937f, 27.724f, 27.264f, 26.475f, 25.974f, 25.504f, 24.776f, 24.454f, 24.026f, - 23.233f, 22.609f, 21.358f, 20.312f, 18.499f, 17.537f, 16.761f, 16.180f, 15.962f, 15.357f, - 15.088f, 14.485f, 14.243f, 13.676f, 13.179f, 12.572f, 12.085f, 12.067f, 11.414f, 11.681f, - 11.568f, 11.159f, 10.247f, 10.134f, 9.578f, 9.726f, 9.592f, 9.758f, 10.264f, 11.444f, - 12.834f, 13.954f, 15.100f, 15.771f, 17.464f, 18.239f, 19.065f, 19.707f, 19.983f, 19.721f, - 19.001f, 17.587f, 20.126f, 20.293f, 21.045f, 22.563f, 24.505f, 31.245f, 30.264f, 29.829f, - 32.141f, 35.299f, 33.011f, 30.707f, 30.377f, 29.307f, 27.665f, 27.350f, 29.518f, 31.305f, - 32.959f, 35.160f, 36.896f, 38.115f, 38.410f, 39.508f, 39.081f, 39.099f, 39.458f, 40.986f, - 42.043f, 44.135f, 43.123f, 42.467f, 41.245f, 47.396f, 46.962f, 45.799f, 45.075f, 48.614f, - 45.837f, 48.103f, 50.978f, 55.259f, 49.869f, 53.879f, 52.202f, 52.579f, 54.366f, 57.675f, - 57.471f, 58.554f, 59.760f, 60.584f, 58.751f, 56.252f, 55.242f, 55.440f, 55.790f, 55.703f, - 57.691f, 59.157f, 60.176f, 61.560f, 62.383f, 62.496f, 61.853f, 58.504f, 58.763f, 58.320f, - 57.925f, 57.299f, 53.460f, 50.533f, 48.413f, 46.784f, 42.595f, 39.434f, 34.568f, 31.315f, - 31.607f, 31.341f, 31.638f, 27.243f, 26.819f, 25.172f, 22.612f, 20.353f, 18.018f, 15.462f, - 13.606f -},{ --29.534f,-28.001f,-25.445f,-21.900f,-18.131f,-15.631f,-14.451f,-11.935f,-10.455f,-11.777f, --10.637f, -8.410f, -3.818f, 1.828f, 5.935f, 9.198f, 7.253f, 7.581f, 9.403f, 10.939f, - 7.717f, 6.738f, 6.457f, 7.042f, 7.913f, 8.677f, 9.747f, 10.614f, 13.201f, 15.189f, - 17.173f, 19.922f, 19.325f, 21.888f, 22.549f, 23.915f, 24.567f, 25.463f, 25.672f, 26.282f, - 26.743f, 27.389f, 28.076f, 27.146f, 26.622f, 25.856f, 24.904f, 24.416f, 24.258f, 23.686f, - 23.214f, 22.236f, 21.176f, 19.527f, 18.012f, 17.235f, 16.420f, 15.802f, 15.660f, 15.326f, - 14.982f, 14.613f, 14.235f, 14.065f, 13.522f, 12.980f, 12.578f, 12.462f, 12.174f, 12.382f, - 12.038f, 11.456f, 10.884f, 10.590f, 10.450f, 10.401f, 10.189f, 10.022f, 10.342f, 11.324f, - 12.758f, 13.758f, 15.221f, 16.049f, 17.934f, 18.416f, 18.986f, 19.240f, 19.876f, 20.004f, - 19.126f, 18.726f, 19.963f, 20.662f, 21.547f, 23.264f, 28.050f, 30.881f, 32.219f, 32.683f, - 33.081f, 33.569f, 33.382f, 31.330f, 30.695f, 29.658f, 27.857f, 26.637f, 28.628f, 30.734f, - 31.860f, 32.981f, 35.458f, 36.254f, 38.007f, 38.726f, 40.152f, 39.396f, 39.137f, 41.404f, - 39.657f, 42.935f, 43.550f, 40.777f, 40.098f, 44.058f, 43.760f, 50.640f, 44.342f, 49.395f, - 45.815f, 47.912f, 52.036f, 52.968f, 47.417f, 52.998f, 49.996f, 50.165f, 53.143f, 58.253f, - 59.089f, 59.554f, 59.412f, 59.949f, 59.358f, 56.139f, 55.780f, 55.871f, 55.638f, 55.446f, - 56.596f, 58.759f, 59.913f, 61.037f, 61.443f, 61.378f, 59.850f, 57.679f, 57.650f, 57.719f, - 56.832f, 56.598f, 53.406f, 50.555f, 48.366f, 46.289f, 43.304f, 40.170f, 35.616f, 31.977f, - 31.853f, 31.647f, 31.707f, 27.341f, 26.967f, 24.955f, 22.535f, 20.353f, 17.989f, 15.466f, - 13.606f -},{ --29.534f,-27.988f,-25.441f,-21.927f,-18.156f,-15.641f,-14.432f,-11.976f,-10.436f,-11.631f, --10.258f, -8.023f, -3.812f, 1.899f, 6.244f, 10.204f, 7.829f, 7.797f, 10.339f, 11.149f, - 8.781f, 7.228f, 6.741f, 7.181f, 8.023f, 8.843f, 9.678f, 11.071f, 13.269f, 14.926f, - 16.702f, 19.664f, 19.318f, 22.584f, 23.014f, 24.449f, 25.286f, 26.068f, 26.323f, 26.466f, - 26.901f, 27.588f, 28.095f, 27.252f, 26.094f, 25.658f, 24.697f, 23.948f, 23.826f, 23.441f, - 23.167f, 22.198f, 21.011f, 19.466f, 18.061f, 16.865f, 16.104f, 15.660f, 15.551f, 15.233f, - 14.860f, 14.794f, 14.367f, 14.313f, 13.727f, 13.302f, 12.826f, 12.558f, 12.290f, 12.477f, - 12.176f, 12.143f, 11.598f, 10.996f, 10.890f, 10.975f, 10.596f, 10.397f, 10.510f, 11.163f, - 12.658f, 13.795f, 15.017f, 16.405f, 17.395f, 18.339f, 18.737f, 19.159f, 19.729f, 19.993f, - 19.457f, 19.474f, 19.558f, 20.438f, 22.389f, 26.902f, 30.043f, 31.342f, 33.879f, 34.067f, - 32.657f, 32.030f, 33.016f, 32.345f, 31.291f, 30.109f, 28.525f, 27.671f, 28.298f, 29.617f, - 30.315f, 31.549f, 33.103f, 34.657f, 36.367f, 37.939f, 39.918f, 39.872f, 38.996f, 42.223f, - 43.405f, 46.000f, 45.571f, 39.407f, 37.413f, 43.020f, 43.175f, 48.848f, 49.007f, 53.380f, - 48.540f, 49.108f, 52.578f, 53.558f, 47.332f, 51.037f, 49.060f, 49.863f, 52.129f, 57.635f, - 58.389f, 59.033f, 58.362f, 58.548f, 58.750f, 57.907f, 56.814f, 55.808f, 55.691f, 56.206f, - 55.457f, 58.202f, 59.395f, 60.167f, 59.940f, 59.593f, 58.435f, 57.274f, 56.638f, 56.787f, - 55.741f, 56.082f, 53.410f, 50.579f, 48.271f, 45.894f, 44.143f, 40.466f, 36.056f, 32.826f, - 32.334f, 32.155f, 31.496f, 27.587f, 27.081f, 24.770f, 22.455f, 20.342f, 17.957f, 15.469f, - 13.606f -},{ --29.534f,-27.976f,-25.426f,-21.955f,-18.172f,-15.719f,-14.392f,-12.066f,-10.377f,-11.386f, - -9.851f, -7.577f, -3.676f, 1.715f, 6.306f, 10.395f, 8.504f, 9.016f, 10.067f, 10.742f, - 9.504f, 7.641f, 7.196f, 7.620f, 8.286f, 9.093f, 9.782f, 11.519f, 12.844f, 14.696f, - 16.458f, 19.287f, 20.265f, 23.093f, 23.518f, 25.086f, 25.487f, 26.372f, 26.989f, 26.809f, - 27.225f, 27.415f, 27.213f, 27.013f, 25.338f, 25.344f, 24.525f, 23.509f, 23.720f, 22.992f, - 22.270f, 21.772f, 20.854f, 19.314f, 17.940f, 16.856f, 16.064f, 15.567f, 15.416f, 15.087f, - 15.009f, 14.877f, 14.624f, 14.587f, 13.970f, 13.535f, 12.963f, 12.622f, 12.527f, 12.642f, - 12.374f, 12.420f, 12.261f, 11.616f, 11.309f, 11.505f, 11.324f, 10.796f, 11.055f, 11.450f, - 12.984f, 13.968f, 14.882f, 16.388f, 17.018f, 18.187f, 18.560f, 18.969f, 19.487f, 19.891f, - 19.540f, 19.937f, 18.622f, 21.106f, 24.295f, 30.284f, 30.753f, 32.063f, 34.905f, 34.937f, - 32.379f, 31.576f, 32.078f, 32.508f, 31.220f, 29.775f, 28.598f, 27.603f, 28.037f, 28.494f, - 28.811f, 30.011f, 31.854f, 32.602f, 33.976f, 35.906f, 37.278f, 38.499f, 38.945f, 42.086f, - 47.290f, 51.050f, 48.298f, 45.962f, 37.994f, 41.038f, 44.757f, 51.849f, 52.736f, 54.109f, - 54.009f, 54.540f, 55.626f, 55.319f, 51.317f, 47.793f, 48.116f, 50.142f, 52.391f, 55.954f, - 57.563f, 57.783f, 57.754f, 57.535f, 58.241f, 58.392f, 57.779f, 57.689f, 58.153f, 55.312f, - 55.575f, 58.142f, 59.318f, 59.534f, 58.487f, 57.650f, 57.548f, 56.376f, 55.690f, 55.596f, - 55.297f, 55.880f, 53.222f, 50.635f, 48.051f, 45.720f, 44.614f, 40.877f, 36.433f, 33.936f, - 33.031f, 32.700f, 31.036f, 27.941f, 27.150f, 24.624f, 22.383f, 20.324f, 17.923f, 15.471f, - 13.606f -},{ --29.534f,-27.963f,-25.399f,-21.982f,-18.178f,-15.836f,-14.315f,-12.143f,-10.284f,-11.097f, - -9.484f, -7.128f, -3.363f, 1.523f, 6.426f, 10.458f, 9.521f, 11.107f, 10.313f, 10.790f, - 10.004f, 8.132f, 7.738f, 8.102f, 8.660f, 9.287f, 10.144f, 11.621f, 13.005f, 14.648f, - 16.228f, 18.780f, 21.086f, 24.108f, 24.314f, 25.263f, 25.628f, 26.532f, 27.312f, 27.286f, - 27.270f, 26.559f, 26.642f, 26.623f, 24.732f, 25.260f, 24.117f, 23.382f, 23.353f, 22.887f, - 22.154f, 21.828f, 20.241f, 19.254f, 17.726f, 16.610f, 16.126f, 15.713f, 15.336f, 15.157f, - 15.256f, 15.067f, 15.027f, 14.938f, 14.430f, 13.736f, 13.242f, 12.716f, 12.631f, 12.819f, - 12.620f, 12.379f, 12.728f, 12.280f, 11.842f, 12.003f, 12.003f, 11.639f, 11.727f, 12.095f, - 13.062f, 14.254f, 14.687f, 15.940f, 16.263f, 17.780f, 18.277f, 18.813f, 19.166f, 19.564f, - 19.331f, 19.677f, 18.360f, 20.500f, 25.177f, 29.610f, 30.580f, 31.274f, 33.646f, 33.553f, - 31.810f, 30.824f, 30.570f, 30.759f, 30.115f, 29.084f, 27.929f, 27.588f, 27.610f, 27.559f, - 27.271f, 28.666f, 30.468f, 30.988f, 32.595f, 33.805f, 34.847f, 38.009f, 37.753f, 39.907f, - 49.234f, 53.102f, 49.358f, 48.280f, 43.148f, 40.652f, 45.405f, 51.801f, 54.779f, 54.919f, - 55.882f, 55.951f, 56.313f, 56.552f, 50.813f, 46.464f, 47.452f, 48.695f, 53.423f, 54.983f, - 56.090f, 56.137f, 56.475f, 56.868f, 57.519f, 57.588f, 58.138f, 58.110f, 57.328f, 55.394f, - 55.616f, 56.954f, 58.283f, 58.715f, 57.285f, 56.716f, 56.051f, 55.497f, 54.711f, 54.056f, - 54.392f, 55.402f, 52.937f, 50.680f, 47.785f, 45.699f, 44.469f, 41.566f, 37.259f, 35.256f, - 33.777f, 33.010f, 30.396f, 28.337f, 27.174f, 24.525f, 22.330f, 20.298f, 17.888f, 15.472f, - 13.606f -},{ --29.534f,-27.951f,-25.361f,-22.007f,-18.175f,-15.957f,-14.208f,-12.173f,-10.196f,-10.834f, - -9.176f, -6.753f, -3.025f, 1.611f, 6.662f, 10.861f, 10.996f, 13.260f, 12.214f, 11.062f, - 10.351f, 8.975f, 8.008f, 8.449f, 9.137f, 9.729f, 10.588f, 11.575f, 13.139f, 14.464f, - 15.714f, 18.258f, 21.129f, 24.192f, 24.902f, 25.685f, 26.229f, 26.944f, 27.390f, 27.584f, - 27.181f, 26.419f, 26.157f, 25.335f, 24.572f, 24.938f, 23.818f, 22.840f, 23.119f, 22.374f, - 21.878f, 20.407f, 20.047f, 18.621f, 17.216f, 16.656f, 16.162f, 15.908f, 15.400f, 15.470f, - 15.542f, 15.399f, 15.425f, 15.414f, 15.027f, 14.219f, 13.643f, 13.074f, 12.848f, 13.085f, - 12.950f, 12.445f, 12.692f, 12.683f, 12.716f, 12.393f, 12.596f, 12.309f, 12.185f, 12.525f, - 13.084f, 14.177f, 14.816f, 15.426f, 15.868f, 17.529f, 18.201f, 18.568f, 18.815f, 19.238f, - 19.426f, 19.142f, 18.284f, 20.063f, 23.947f, 28.746f, 29.246f, 30.458f, 30.900f, 30.506f, - 29.736f, 28.872f, 29.113f, 29.065f, 29.236f, 28.343f, 27.911f, 27.795f, 27.307f, 26.839f, - 26.799f, 27.801f, 28.915f, 29.442f, 30.554f, 31.560f, 33.029f, 35.005f, 36.454f, 40.048f, - 47.999f, 53.869f, 50.408f, 50.596f, 45.137f, 40.030f, 41.645f, 50.500f, 55.377f, 55.081f, - 55.093f, 55.873f, 57.102f, 56.227f, 48.652f, 45.555f, 47.336f, 48.037f, 53.577f, 53.880f, - 54.917f, 54.802f, 55.733f, 55.878f, 56.889f, 57.227f, 57.118f, 57.029f, 57.129f, 56.501f, - 55.417f, 56.582f, 57.260f, 57.102f, 55.464f, 55.868f, 54.348f, 54.278f, 53.771f, 52.483f, - 52.474f, 54.457f, 52.727f, 50.632f, 47.673f, 45.686f, 43.961f, 42.189f, 38.452f, 36.485f, - 34.336f, 32.862f, 29.699f, 28.698f, 27.168f, 24.476f, 22.303f, 20.269f, 17.852f, 15.473f, - 13.606f -},{ --29.534f,-27.940f,-25.313f,-22.028f,-18.166f,-16.047f,-14.101f,-12.154f,-10.163f,-10.632f, - -8.878f, -6.432f, -2.803f, 1.938f, 6.824f, 11.194f, 12.547f, 14.573f, 13.951f, 10.757f, - 10.454f, 9.537f, 8.267f, 8.700f, 9.497f, 10.219f, 10.781f, 11.549f, 12.816f, 13.989f, - 15.532f, 18.040f, 21.301f, 24.363f, 25.535f, 26.142f, 26.901f, 27.393f, 27.968f, 27.873f, - 26.891f, 25.727f, 25.262f, 24.845f, 24.074f, 24.831f, 23.330f, 22.504f, 22.336f, 22.295f, - 21.853f, 19.819f, 19.437f, 18.447f, 17.165f, 16.669f, 16.457f, 16.418f, 15.901f, 15.990f, - 15.950f, 15.971f, 16.049f, 15.872f, 15.677f, 14.815f, 13.993f, 13.602f, 13.301f, 13.223f, - 13.141f, 12.682f, 12.698f, 12.762f, 13.895f, 12.758f, 13.111f, 14.263f, 11.866f, 12.626f, - 13.359f, 13.954f, 14.626f, 15.141f, 15.922f, 17.064f, 17.996f, 18.214f, 18.227f, 18.769f, - 19.466f, 18.663f, 18.188f, 19.537f, 23.079f, 27.015f, 29.004f, 29.951f, 30.078f, 29.079f, - 28.368f, 28.745f, 28.829f, 28.481f, 28.554f, 28.009f, 27.766f, 27.831f, 26.863f, 26.276f, - 26.719f, 27.281f, 27.294f, 27.886f, 30.195f, 30.530f, 31.677f, 33.336f, 35.968f, 40.253f, - 47.269f, 52.336f, 55.495f, 52.161f, 45.669f, 40.116f, 41.669f, 47.313f, 54.971f, 54.292f, - 54.816f, 56.167f, 56.810f, 56.099f, 47.762f, 44.927f, 46.670f, 48.238f, 52.400f, 52.801f, - 53.820f, 54.465f, 54.518f, 55.760f, 56.262f, 55.766f, 55.809f, 55.603f, 55.866f, 55.893f, - 55.372f, 55.350f, 56.109f, 55.515f, 53.497f, 54.303f, 53.632f, 52.719f, 52.324f, 51.546f, - 51.265f, 53.747f, 52.593f, 50.398f, 47.744f, 45.581f, 43.461f, 42.295f, 39.420f, 37.183f, - 34.533f, 32.247f, 29.111f, 28.961f, 27.153f, 24.480f, 22.307f, 20.238f, 17.817f, 15.472f, - 13.606f -},{ --29.534f,-27.928f,-25.257f,-22.044f,-18.154f,-16.080f,-14.031f,-12.119f,-10.211f,-10.467f, - -8.520f, -6.036f, -2.595f, 2.265f, 6.854f, 11.013f, 13.524f, 14.594f, 14.044f, 10.477f, - 10.546f, 9.311f, 8.946f, 9.174f, 9.873f, 10.515f, 11.001f, 11.605f, 12.781f, 13.863f, - 15.467f, 18.000f, 21.236f, 24.577f, 25.184f, 26.506f, 27.051f, 27.802f, 27.889f, 27.379f, - 26.587f, 25.449f, 24.635f, 24.287f, 23.468f, 24.268f, 23.231f, 22.220f, 21.973f, 20.431f, - 19.967f, 19.016f, 18.700f, 18.007f, 17.496f, 17.829f, 16.779f, 17.246f, 16.870f, 16.630f, - 16.651f, 16.566f, 16.708f, 16.551f, 16.338f, 15.639f, 14.694f, 14.203f, 13.775f, 13.594f, - 13.478f, 12.835f, 12.769f, 13.048f, 13.050f, 13.045f, 13.288f, 13.373f, 12.962f, 12.712f, - 13.381f, 14.086f, 15.010f, 15.376f, 15.591f, 16.836f, 17.802f, 17.811f, 17.727f, 18.252f, - 18.851f, 18.444f, 19.283f, 19.079f, 22.399f, 25.615f, 27.363f, 28.189f, 28.789f, 28.367f, - 27.905f, 29.157f, 28.605f, 27.885f, 28.207f, 28.333f, 28.090f, 27.467f, 26.833f, 25.929f, - 26.909f, 27.385f, 26.130f, 25.918f, 28.534f, 30.376f, 31.556f, 33.261f, 36.021f, 40.426f, - 46.259f, 49.718f, 53.836f, 54.610f, 47.548f, 43.626f, 42.412f, 47.245f, 52.206f, 54.330f, - 54.471f, 54.537f, 54.489f, 55.206f, 49.560f, 44.856f, 46.214f, 50.297f, 51.463f, 51.730f, - 52.943f, 53.962f, 54.035f, 54.585f, 55.260f, 55.094f, 55.036f, 54.925f, 55.201f, 54.540f, - 54.208f, 53.215f, 54.483f, 53.572f, 52.335f, 53.278f, 52.998f, 52.028f, 51.032f, 51.089f, - 51.329f, 53.474f, 52.424f, 50.058f, 47.734f, 45.418f, 43.036f, 41.825f, 39.673f, 37.096f, - 34.365f, 31.408f, 28.793f, 29.090f, 27.152f, 24.531f, 22.340f, 20.208f, 17.782f, 15.471f, - 13.606f -},{ --29.534f,-27.917f,-25.194f,-22.052f,-18.141f,-16.045f,-14.028f,-12.115f,-10.332f,-10.284f, - -8.083f, -5.487f, -2.173f, 2.467f, 6.901f, 10.695f, 13.676f, 13.673f, 13.489f, 10.738f, - 10.508f, 8.912f, 9.663f, 9.826f, 10.348f, 10.839f, 11.120f, 11.655f, 12.731f, 14.062f, - 15.206f, 17.998f, 20.741f, 24.186f, 25.490f, 26.650f, 27.370f, 28.226f, 27.597f, 27.037f, - 26.408f, 25.093f, 24.333f, 24.141f, 23.238f, 23.646f, 22.309f, 21.198f, 21.411f, 20.129f, - 18.942f, 18.585f, 17.316f, 17.713f, 17.530f, 17.386f, 17.840f, 17.350f, 18.276f, 17.562f, - 17.498f, 17.530f, 17.295f, 17.432f, 17.095f, 16.458f, 15.611f, 15.015f, 14.446f, 14.171f, - 13.981f, 13.354f, 13.052f, 13.017f, 13.144f, 13.434f, 13.030f, 13.289f, 12.728f, 12.691f, - 13.365f, 14.059f, 14.996f, 15.891f, 15.900f, 16.583f, 17.722f, 17.607f, 17.593f, 17.821f, - 18.106f, 18.063f, 19.028f, 18.142f, 20.507f, 24.238f, 27.220f, 27.701f, 27.328f, 27.005f, - 27.018f, 27.628f, 27.856f, 28.115f, 29.075f, 29.100f, 28.526f, 28.130f, 27.013f, 26.444f, - 27.031f, 27.390f, 25.485f, 25.230f, 27.249f, 29.373f, 31.322f, 32.977f, 35.790f, 40.126f, - 43.658f, 47.860f, 51.136f, 52.410f, 51.533f, 48.364f, 45.523f, 48.400f, 50.838f, 54.138f, - 52.391f, 53.721f, 53.621f, 53.615f, 46.230f, 44.392f, 48.421f, 49.724f, 50.653f, 50.816f, - 52.053f, 52.937f, 53.850f, 54.571f, 53.858f, 54.424f, 54.047f, 53.723f, 52.786f, 53.645f, - 53.724f, 51.715f, 52.420f, 52.165f, 51.892f, 52.695f, 52.000f, 51.623f, 50.830f, 50.572f, - 51.300f, 53.068f, 52.194f, 49.783f, 47.489f, 45.286f, 42.578f, 41.210f, 39.279f, 36.408f, - 34.000f, 30.733f, 28.845f, 29.087f, 27.181f, 24.621f, 22.397f, 20.183f, 17.748f, 15.469f, - 13.606f -},{ --29.534f,-27.907f,-25.125f,-22.051f,-18.133f,-15.945f,-14.108f,-12.177f,-10.485f,-10.048f, - -7.640f, -4.909f, -1.564f, 2.546f, 6.975f, 10.804f, 13.300f, 12.704f, 13.200f, 10.919f, - 10.144f, 8.827f, 9.978f, 10.408f, 10.780f, 11.269f, 11.415f, 11.963f, 12.873f, 14.138f, - 15.454f, 18.007f, 21.113f, 23.484f, 24.835f, 27.057f, 27.690f, 27.793f, 27.381f, 26.845f, - 26.021f, 24.778f, 23.990f, 23.632f, 23.308f, 22.505f, 21.833f, 21.980f, 20.203f, 19.686f, - 18.432f, 17.540f, 16.350f, 16.902f, 17.168f, 16.994f, 17.204f, 18.688f, 18.521f, 18.324f, - 18.400f, 18.391f, 17.986f, 18.107f, 17.922f, 17.342f, 16.117f, 16.005f, 15.288f, 14.773f, - 14.688f, 14.167f, 13.610f, 13.336f, 13.328f, 13.297f, 12.899f, 13.328f, 12.289f, 12.107f, - 12.745f, 14.081f, 15.169f, 16.130f, 16.750f, 16.570f, 17.661f, 17.673f, 17.512f, 17.663f, - 17.740f, 17.714f, 17.827f, 18.087f, 19.901f, 25.172f, 27.542f, 27.753f, 27.642f, 27.091f, - 26.407f, 26.048f, 26.792f, 26.814f, 26.595f, 28.228f, 28.712f, 28.668f, 27.316f, 27.022f, - 26.556f, 26.989f, 25.237f, 25.428f, 26.297f, 28.160f, 30.349f, 31.933f, 34.081f, 37.812f, - 41.367f, 45.506f, 48.180f, 51.696f, 51.448f, 49.912f, 47.540f, 50.842f, 51.202f, 53.306f, - 52.386f, 53.679f, 54.027f, 51.426f, 46.928f, 46.617f, 49.390f, 49.315f, 49.590f, 50.445f, - 50.182f, 50.644f, 51.868f, 52.806f, 52.610f, 53.029f, 52.204f, 52.302f, 50.256f, 52.465f, - 52.911f, 50.656f, 50.047f, 51.446f, 51.761f, 52.046f, 51.661f, 50.914f, 50.823f, 49.899f, - 50.816f, 52.457f, 51.944f, 49.542f, 47.246f, 45.108f, 42.212f, 40.953f, 38.726f, 35.655f, - 33.672f, 30.541f, 29.252f, 28.978f, 27.242f, 24.737f, 22.468f, 20.163f, 17.716f, 15.466f, - 13.606f -},{ --29.534f,-27.897f,-25.051f,-22.039f,-18.132f,-15.799f,-14.259f,-12.311f,-10.615f, -9.776f, - -7.307f, -4.563f, -1.162f, 2.456f, 6.845f, 11.005f, 12.659f, 12.348f, 12.822f, 11.334f, - 10.719f, 9.190f, 9.986f, 10.640f, 11.222f, 11.730f, 12.053f, 12.288f, 13.087f, 14.067f, - 15.566f, 17.915f, 21.003f, 23.067f, 24.515f, 27.469f, 27.705f, 27.557f, 26.961f, 26.592f, - 25.752f, 24.448f, 23.671f, 23.177f, 22.689f, 21.777f, 22.689f, 20.852f, 19.774f, 18.740f, - 17.917f, 17.035f, 15.888f, 16.407f, 16.676f, 17.153f, 18.053f, 18.819f, 19.237f, 18.961f, - 19.111f, 19.130f, 19.094f, 18.884f, 18.540f, 18.205f, 16.712f, 16.768f, 15.902f, 15.620f, - 15.415f, 15.247f, 14.673f, 14.044f, 13.668f, 13.510f, 13.031f, 12.467f, 11.796f, 11.577f, - 12.627f, 13.817f, 15.207f, 16.133f, 17.126f, 17.037f, 18.047f, 17.951f, 17.838f, 17.630f, - 17.469f, 17.585f, 17.001f, 17.601f, 20.252f, 24.441f, 27.162f, 28.002f, 27.156f, 25.697f, - 25.278f, 25.413f, 26.059f, 26.062f, 25.264f, 25.640f, 28.147f, 28.075f, 28.631f, 28.157f, - 28.540f, 28.908f, 27.284f, 26.694f, 26.311f, 27.385f, 28.410f, 29.836f, 31.431f, 36.354f, - 38.972f, 43.343f, 47.114f, 49.614f, 51.025f, 49.938f, 47.663f, 49.950f, 51.740f, 52.668f, - 52.723f, 52.940f, 51.708f, 50.233f, 48.663f, 47.560f, 48.342f, 48.517f, 48.888f, 49.067f, - 48.049f, 48.106f, 49.163f, 50.801f, 51.154f, 50.926f, 49.989f, 50.065f, 49.024f, 50.518f, - 50.981f, 51.020f, 49.287f, 50.315f, 51.386f, 51.542f, 51.267f, 50.641f, 50.215f, 49.210f, - 50.298f, 51.798f, 51.599f, 49.227f, 47.207f, 44.677f, 42.277f, 41.153f, 38.423f, 35.351f, - 33.545f, 30.908f, 29.877f, 28.811f, 27.321f, 24.863f, 22.543f, 20.150f, 17.686f, 15.462f, - 13.606f -},{ --29.534f,-27.888f,-24.975f,-22.013f,-18.140f,-15.637f,-14.450f,-12.489f,-10.677f, -9.516f, - -7.143f, -4.597f, -1.353f, 2.121f, 6.408f, 10.464f, 11.750f, 12.582f, 12.407f, 12.616f, - 12.857f, 10.021f, 10.154f, 10.646f, 11.833f, 12.456f, 12.724f, 12.886f, 13.213f, 14.150f, - 15.272f, 17.879f, 20.764f, 22.963f, 24.603f, 27.003f, 27.587f, 27.312f, 26.803f, 26.526f, - 25.291f, 24.096f, 23.523f, 22.860f, 22.752f, 21.480f, 22.172f, 18.988f, 19.650f, 17.750f, - 17.522f, 16.845f, 16.386f, 16.183f, 17.003f, 17.802f, 18.774f, 19.157f, 19.414f, 20.208f, - 20.392f, 20.320f, 19.995f, 19.687f, 19.195f, 19.094f, 17.727f, 17.493f, 16.872f, 16.112f, - 16.132f, 15.979f, 15.094f, 14.507f, 13.875f, 13.380f, 12.826f, 12.117f, 11.241f, 11.934f, - 12.519f, 12.857f, 14.591f, 16.103f, 17.129f, 17.396f, 18.050f, 18.272f, 18.391f, 17.622f, - 17.305f, 17.384f, 16.676f, 17.044f, 18.966f, 22.479f, 26.936f, 26.761f, 26.042f, 24.794f, - 24.105f, 24.333f, 25.136f, 26.068f, 24.616f, 24.020f, 26.847f, 27.605f, 28.812f, 29.965f, - 30.065f, 29.214f, 28.555f, 27.388f, 27.796f, 27.299f, 26.763f, 27.335f, 29.782f, 33.521f, - 37.537f, 41.763f, 44.136f, 48.303f, 50.145f, 50.431f, 46.838f, 46.726f, 50.401f, 51.817f, - 52.456f, 51.249f, 50.245f, 51.390f, 48.555f, 47.214f, 47.805f, 48.125f, 48.277f, 48.255f, - 46.171f, 46.144f, 47.757f, 48.543f, 48.096f, 48.258f, 48.075f, 48.496f, 48.596f, 48.469f, - 49.185f, 50.555f, 49.938f, 49.639f, 50.646f, 51.296f, 50.668f, 50.105f, 49.348f, 48.775f, - 49.634f, 50.929f, 51.099f, 48.981f, 47.136f, 44.066f, 42.825f, 41.472f, 38.405f, 35.629f, - 33.647f, 31.629f, 30.516f, 28.632f, 27.390f, 24.982f, 22.610f, 20.145f, 17.658f, 15.457f, - 13.606f -},{ --29.534f,-27.880f,-24.897f,-21.973f,-18.154f,-15.493f,-14.636f,-12.657f,-10.648f, -9.301f, - -7.084f, -4.850f, -2.015f, 1.642f, 5.903f, 9.258f, 10.905f, 13.100f, 12.465f, 13.448f, - 14.464f, 10.528f, 10.660f, 10.931f, 12.894f, 13.775f, 13.406f, 13.503f, 13.701f, 14.329f, - 15.132f, 17.828f, 20.762f, 22.627f, 24.433f, 27.098f, 27.238f, 27.168f, 26.391f, 26.405f, - 25.022f, 23.761f, 23.319f, 22.775f, 22.479f, 21.243f, 20.774f, 18.793f, 23.573f, 17.031f, - 17.474f, 16.804f, 16.597f, 16.734f, 16.967f, 17.767f, 18.370f, 20.028f, 20.044f, 20.940f, - 21.409f, 21.247f, 20.852f, 20.564f, 20.098f, 19.847f, 18.959f, 18.146f, 17.336f, 16.808f, - 16.339f, 16.371f, 15.504f, 14.713f, 14.061f, 13.421f, 12.683f, 11.942f, 11.145f, 11.092f, - 11.477f, 11.602f, 13.059f, 15.223f, 16.411f, 16.838f, 17.664f, 18.217f, 18.196f, 17.846f, - 17.162f, 16.992f, 16.895f, 16.616f, 17.673f, 20.453f, 25.912f, 26.234f, 25.914f, 24.272f, - 23.262f, 23.412f, 24.155f, 25.095f, 23.751f, 22.245f, 24.140f, 27.104f, 28.980f, 30.837f, - 31.445f, 30.261f, 30.432f, 29.865f, 29.163f, 27.348f, 25.617f, 25.845f, 28.325f, 30.965f, - 35.389f, 39.102f, 41.083f, 45.020f, 48.293f, 49.580f, 47.460f, 46.235f, 49.156f, 49.913f, - 51.091f, 50.314f, 49.985f, 52.108f, 48.706f, 47.140f, 48.169f, 47.587f, 47.370f, 47.048f, - 45.038f, 45.301f, 46.300f, 46.367f, 45.821f, 46.184f, 46.676f, 47.262f, 47.762f, 46.927f, - 48.227f, 49.454f, 50.172f, 49.071f, 49.781f, 50.804f, 50.320f, 48.953f, 48.675f, 48.539f, - 48.836f, 50.053f, 50.553f, 48.925f, 46.724f, 43.723f, 43.370f, 41.560f, 38.495f, 36.215f, - 33.895f, 32.344f, 30.978f, 28.477f, 27.419f, 25.076f, 22.659f, 20.147f, 17.632f, 15.452f, - 13.606f -}}; +static const float geoid[361][181] = { + {-29.534f, -27.880f, -24.897f, -21.973f, -18.154f, -15.493f, -14.636f, -12.657f, -10.648f, + -9.301f, -7.084f, -4.850f, -2.015f, 1.642f, 5.903f, 9.258f, 10.905f, 13.100f, + 12.465f, 13.448f, 14.464f, 10.528f, 10.660f, 10.931f, 12.894f, 13.775f, 13.406f, + 13.503f, 13.701f, 14.329f, 15.132f, 17.828f, 20.762f, 22.627f, 24.433f, 27.098f, + 27.238f, 27.168f, 26.391f, 26.405f, 25.022f, 23.761f, 23.319f, 22.775f, 22.479f, + 21.243f, 20.774f, 18.793f, 23.573f, 17.031f, 17.474f, 16.804f, 16.597f, 16.734f, + 16.967f, 17.767f, 18.370f, 20.028f, 20.044f, 20.940f, 21.409f, 21.247f, 20.852f, + 20.564f, 20.098f, 19.847f, 18.959f, 18.146f, 17.336f, 16.808f, 16.339f, 16.371f, + 15.504f, 14.713f, 14.061f, 13.421f, 12.683f, 11.942f, 11.145f, 11.092f, 11.477f, + 11.602f, 13.059f, 15.223f, 16.411f, 16.838f, 17.664f, 18.217f, 18.196f, 17.846f, + 17.162f, 16.992f, 16.895f, 16.616f, 17.673f, 20.453f, 25.912f, 26.234f, 25.914f, + 24.272f, 23.262f, 23.412f, 24.155f, 25.095f, 23.751f, 22.245f, 24.140f, 27.104f, + 28.980f, 30.837f, 31.445f, 30.261f, 30.432f, 29.865f, 29.163f, 27.348f, 25.617f, + 25.845f, 28.325f, 30.965f, 35.389f, 39.102f, 41.083f, 45.020f, 48.293f, 49.580f, + 47.460f, 46.235f, 49.156f, 49.913f, 51.091f, 50.314f, 49.985f, 52.108f, 48.706f, + 47.140f, 48.169f, 47.587f, 47.370f, 47.048f, 45.038f, 45.301f, 46.300f, 46.367f, + 45.821f, 46.184f, 46.676f, 47.262f, 47.762f, 46.927f, 48.227f, 49.454f, 50.172f, + 49.071f, 49.781f, 50.804f, 50.320f, 48.953f, 48.675f, 48.539f, 48.836f, 50.053f, + 50.553f, 48.925f, 46.724f, 43.723f, 43.370f, 41.560f, 38.495f, 36.215f, 33.895f, + 32.344f, 30.978f, 28.477f, 27.419f, 25.076f, 22.659f, 20.147f, 17.632f, 15.452f, + 13.606f}, + {-29.534f, -27.872f, -24.818f, -21.917f, -18.173f, -15.402f, -14.776f, -12.758f, -10.529f, + -9.116f, -6.976f, -4.953f, -2.543f, 1.310f, 5.640f, 8.533f, 10.927f, 13.842f, + 12.831f, 12.856f, 14.414f, 10.363f, 11.018f, 11.346f, 13.963f, 15.276f, 14.385f, + 13.940f, 14.094f, 14.546f, 15.512f, 17.859f, 20.624f, 22.106f, 24.013f, 25.824f, + 27.236f, 27.060f, 26.242f, 25.680f, 24.794f, 23.590f, 22.886f, 22.182f, 21.504f, + 21.160f, 21.131f, 20.380f, 21.356f, 18.016f, 17.639f, 17.348f, 16.947f, 17.054f, + 17.591f, 18.255f, 19.837f, 19.761f, 20.307f, 21.184f, 22.997f, 22.284f, 22.086f, + 21.615f, 21.142f, 20.632f, 20.144f, 19.147f, 18.136f, 17.373f, 16.785f, 16.271f, + 15.632f, 14.847f, 14.130f, 13.408f, 12.631f, 11.798f, 11.082f, 10.733f, 10.329f, + 10.127f, 12.546f, 12.820f, 15.290f, 15.546f, 16.568f, 18.234f, 18.361f, 17.446f, + 16.997f, 16.742f, 16.948f, 16.553f, 17.426f, 19.542f, 24.700f, 26.558f, 25.574f, + 23.570f, 21.963f, 22.519f, 23.588f, 23.959f, 22.591f, 22.114f, 23.332f, 26.426f, + 28.284f, 30.341f, 31.433f, 31.283f, 31.117f, 31.596f, 30.563f, 28.159f, 25.538f, + 25.691f, 27.841f, 28.600f, 32.533f, 36.899f, 38.970f, 41.651f, 46.206f, 48.666f, + 48.107f, 45.242f, 47.015f, 48.806f, 49.616f, 49.832f, 50.005f, 51.846f, 49.203f, + 48.970f, 48.786f, 47.510f, 46.237f, 45.552f, 45.048f, 44.938f, 45.371f, 45.013f, + 44.036f, 44.361f, 45.252f, 46.356f, 47.067f, 46.723f, 47.361f, 47.685f, 48.633f, + 48.060f, 48.638f, 49.669f, 49.180f, 48.457f, 48.343f, 47.985f, 48.113f, 49.355f, + 49.970f, 48.839f, 46.055f, 43.870f, 43.379f, 41.425f, 38.629f, 36.716f, 34.188f, + 32.741f, 31.166f, 28.361f, 27.379f, 25.135f, 22.684f, 20.156f, 17.609f, 15.446f, + 13.606f}, + {-29.534f, -27.865f, -24.741f, -21.844f, -18.189f, -15.386f, -14.844f, -12.759f, -10.339f, + -8.906f, -6.689f, -4.647f, -2.412f, 1.357f, 5.676f, 9.011f, 12.056f, 14.836f, + 13.289f, 12.278f, 14.264f, 10.369f, 11.217f, 11.990f, 14.534f, 16.613f, 15.894f, + 14.464f, 14.419f, 14.737f, 15.552f, 17.503f, 20.371f, 21.913f, 23.853f, 25.577f, + 26.714f, 27.074f, 26.194f, 25.353f, 24.914f, 23.342f, 22.596f, 21.805f, 21.324f, + 21.433f, 21.171f, 21.243f, 21.521f, 18.293f, 18.301f, 18.016f, 17.562f, 17.604f, + 18.234f, 19.057f, 19.765f, 22.960f, 22.922f, 21.914f, 22.944f, 24.099f, 23.245f, + 22.425f, 22.109f, 21.822f, 21.210f, 20.463f, 19.201f, 18.137f, 16.982f, 16.273f, + 15.655f, 14.998f, 14.191f, 13.418f, 12.485f, 11.826f, 11.096f, 10.563f, 10.033f, + 9.905f, 10.429f, 10.989f, 11.786f, 13.499f, 15.282f, 17.237f, 17.811f, 17.591f, + 16.757f, 16.210f, 16.158f, 15.951f, 15.816f, 17.326f, 20.984f, 25.957f, 26.021f, + 25.190f, 23.883f, 21.991f, 22.407f, 22.965f, 23.025f, 22.790f, 24.188f, 25.330f, + 26.929f, 30.179f, 31.546f, 31.718f, 31.502f, 32.046f, 31.603f, 28.279f, 26.031f, + 24.934f, 26.527f, 27.728f, 30.134f, 34.456f, 38.013f, 40.139f, 44.998f, 46.912f, + 47.887f, 44.456f, 46.072f, 48.802f, 47.837f, 48.677f, 51.152f, 50.728f, 50.571f, + 50.685f, 50.028f, 47.513f, 45.615f, 44.643f, 44.892f, 44.441f, 44.538f, 44.131f, + 42.692f, 43.024f, 44.565f, 45.533f, 45.788f, 46.040f, 46.826f, 47.043f, 47.789f, + 47.210f, 46.716f, 48.096f, 47.357f, 48.183f, 48.079f, 47.224f, 47.473f, 48.408f, + 49.272f, 48.533f, 45.403f, 44.082f, 42.920f, 41.345f, 38.921f, 36.961f, 34.468f, + 32.717f, 31.112f, 28.276f, 27.259f, 25.151f, 22.681f, 20.170f, 17.589f, 15.439f, + 13.606f}, + {-29.534f, -27.858f, -24.665f, -21.753f, -18.195f, -15.452f, -14.835f, -12.659f, -10.107f, + -8.614f, -6.205f, -3.991f, -1.675f, 1.769f, 5.916f, 10.055f, 13.417f, 15.862f, + 14.224f, 12.716f, 14.619f, 10.803f, 11.632f, 12.865f, 14.739f, 17.272f, 16.934f, + 15.039f, 14.977f, 15.045f, 15.547f, 17.438f, 19.743f, 22.194f, 24.179f, 25.803f, + 27.246f, 26.646f, 26.346f, 25.153f, 24.467f, 23.726f, 22.471f, 21.860f, 21.231f, + 21.588f, 21.070f, 21.128f, 19.511f, 19.079f, 18.796f, 18.945f, 18.551f, 17.949f, + 18.620f, 19.614f, 20.048f, 20.934f, 21.138f, 24.234f, 25.249f, 24.186f, 24.752f, + 24.201f, 23.339f, 22.729f, 22.350f, 21.693f, 20.519f, 19.023f, 17.573f, 16.519f, + 15.752f, 15.071f, 14.152f, 13.391f, 12.539f, 11.840f, 11.210f, 10.474f, 9.890f, + 9.404f, 9.648f, 9.593f, 10.888f, 11.683f, 13.659f, 15.487f, 16.908f, 17.157f, + 16.942f, 16.466f, 15.867f, 15.076f, 14.806f, 16.182f, 18.527f, 24.702f, 25.834f, + 24.851f, 24.082f, 22.824f, 22.397f, 22.366f, 22.361f, 22.268f, 23.071f, 23.606f, + 25.512f, 27.653f, 30.007f, 31.606f, 32.335f, 33.284f, 32.620f, 30.289f, 27.742f, + 25.887f, 27.412f, 28.285f, 29.022f, 32.069f, 35.868f, 39.096f, 42.115f, 44.076f, + 46.268f, 44.511f, 45.338f, 47.426f, 48.638f, 47.538f, 49.946f, 49.958f, 51.977f, + 52.593f, 50.290f, 47.902f, 46.000f, 44.714f, 44.569f, 44.694f, 44.059f, 42.913f, + 41.445f, 42.459f, 43.830f, 44.198f, 44.724f, 44.971f, 45.367f, 46.038f, 47.165f, + 46.513f, 44.688f, 46.149f, 45.965f, 46.815f, 47.523f, 46.682f, 46.880f, 47.220f, + 48.557f, 48.093f, 44.877f, 43.904f, 42.567f, 41.466f, 39.437f, 37.085f, 34.733f, + 32.390f, 30.947f, 28.200f, 27.066f, 25.126f, 22.654f, 20.185f, 17.570f, 15.431f, + 13.606f}, + {-29.534f, -27.853f, -24.591f, -21.645f, -18.181f, -15.590f, -14.763f, -12.487f, -9.869f, + -8.231f, -5.629f, -3.271f, -0.833f, 2.365f, 6.334f, 10.625f, 14.113f, 16.758f, + 15.703f, 13.417f, 14.793f, 11.489f, 12.038f, 13.143f, 14.829f, 17.094f, 17.228f, + 16.001f, 15.661f, 15.448f, 15.894f, 17.342f, 19.200f, 21.642f, 24.267f, 26.250f, + 27.707f, 26.574f, 26.004f, 25.197f, 24.562f, 24.092f, 22.633f, 22.110f, 21.742f, + 22.345f, 21.296f, 21.180f, 20.181f, 19.475f, 19.345f, 19.445f, 19.421f, 19.152f, + 19.198f, 19.921f, 20.557f, 21.618f, 22.933f, 22.642f, 22.478f, 23.033f, 24.020f, + 26.116f, 24.905f, 23.921f, 23.911f, 22.839f, 21.555f, 20.361f, 18.372f, 16.821f, + 15.775f, 15.094f, 14.295f, 13.570f, 12.784f, 12.027f, 11.389f, 10.493f, 9.780f, + 9.152f, 9.006f, 9.111f, 9.411f, 10.193f, 11.846f, 14.082f, 16.287f, 16.712f, + 16.617f, 16.232f, 15.606f, 14.330f, 16.558f, 18.130f, 19.340f, 24.026f, 25.344f, + 24.359f, 23.284f, 21.650f, 20.171f, 20.802f, 21.103f, 20.681f, 21.466f, 22.402f, + 23.756f, 25.827f, 28.106f, 30.013f, 31.334f, 33.168f, 33.658f, 33.426f, 30.368f, + 27.193f, 28.160f, 27.771f, 27.461f, 29.163f, 32.442f, 35.690f, 38.945f, 42.108f, + 44.068f, 44.542f, 44.446f, 45.654f, 48.376f, 46.319f, 47.110f, 49.680f, 50.915f, + 52.964f, 50.246f, 48.196f, 46.384f, 45.423f, 45.712f, 45.111f, 43.604f, 42.290f, + 41.365f, 41.790f, 43.021f, 43.171f, 43.635f, 44.465f, 44.783f, 45.372f, 45.910f, + 45.481f, 42.712f, 44.601f, 44.929f, 44.814f, 46.503f, 46.011f, 46.213f, 46.320f, + 47.778f, 47.537f, 44.576f, 43.583f, 42.642f, 41.609f, 39.981f, 37.323f, 34.987f, + 31.998f, 30.825f, 28.104f, 26.822f, 25.069f, 22.607f, 20.201f, 17.555f, 15.423f, + 13.606f}, + {-29.534f, -27.848f, -24.521f, -21.520f, -18.139f, -15.771f, -14.651f, -12.289f, -9.660f, + -7.801f, -5.090f, -2.710f, -0.272f, 2.978f, 6.889f, 10.628f, 14.298f, 17.657f, + 17.063f, 13.906f, 14.875f, 12.449f, 12.338f, 13.218f, 15.054f, 16.980f, 17.334f, + 16.820f, 16.579f, 16.177f, 16.516f, 17.416f, 19.038f, 20.935f, 23.615f, 26.014f, + 27.547f, 26.127f, 25.595f, 24.695f, 24.802f, 24.617f, 23.232f, 22.784f, 22.287f, + 21.921f, 22.085f, 21.845f, 20.674f, 19.881f, 19.615f, 19.811f, 20.174f, 20.307f, + 20.120f, 20.208f, 20.724f, 21.813f, 22.621f, 22.759f, 23.471f, 23.658f, 24.010f, + 25.421f, 26.892f, 25.756f, 26.050f, 24.699f, 22.533f, 21.972f, 19.429f, 17.607f, + 16.271f, 15.167f, 14.390f, 13.610f, 12.930f, 12.399f, 11.697f, 10.703f, 9.923f, + 9.386f, 8.763f, 8.690f, 8.648f, 9.241f, 10.701f, 12.881f, 15.101f, 16.232f, + 16.254f, 16.002f, 15.280f, 15.548f, 19.235f, 20.892f, 19.610f, 23.241f, 25.027f, + 23.769f, 23.077f, 21.308f, 19.886f, 19.779f, 20.147f, 20.817f, 21.613f, 22.690f, + 23.438f, 24.999f, 26.666f, 29.152f, 31.820f, 34.425f, 35.793f, 35.128f, 32.418f, + 29.146f, 27.687f, 26.968f, 26.463f, 27.412f, 29.614f, 32.045f, 34.360f, 37.402f, + 43.444f, 43.043f, 43.578f, 44.710f, 45.486f, 45.808f, 46.589f, 48.893f, 50.381f, + 50.720f, 49.311f, 48.285f, 47.377f, 46.672f, 46.709f, 45.442f, 43.418f, 42.007f, + 40.648f, 40.924f, 42.127f, 42.530f, 42.778f, 44.391f, 44.966f, 45.949f, 45.463f, + 45.186f, 42.236f, 43.936f, 43.966f, 43.324f, 45.195f, 45.051f, 45.466f, 45.571f, + 46.719f, 46.813f, 44.714f, 43.615f, 42.818f, 41.516f, 40.197f, 37.757f, 35.205f, + 31.739f, 30.846f, 27.965f, 26.564f, 24.992f, 22.551f, 20.214f, 17.541f, 15.414f, + 13.606f}, + {-29.534f, -27.844f, -24.454f, -21.380f, -18.059f, -15.950f, -14.517f, -12.098f, -9.510f, + -7.400f, -4.653f, -2.299f, 0.079f, 3.514f, 7.382f, 10.761f, 14.603f, 18.434f, + 17.697f, 14.096f, 14.871f, 13.127f, 12.795f, 13.861f, 15.200f, 17.027f, 17.405f, + 17.421f, 17.593f, 17.118f, 16.896f, 17.665f, 18.825f, 20.440f, 22.505f, 25.907f, + 27.382f, 26.365f, 25.635f, 25.146f, 24.473f, 24.494f, 23.834f, 23.578f, 23.041f, + 22.849f, 22.969f, 22.872f, 21.633f, 20.593f, 20.033f, 20.359f, 20.982f, 21.274f, + 20.968f, 20.775f, 21.250f, 22.204f, 22.763f, 22.981f, 23.564f, 24.142f, 24.538f, + 24.686f, 28.629f, 28.327f, 27.073f, 25.850f, 24.353f, 22.283f, 20.479f, 18.566f, + 17.106f, 15.736f, 14.633f, 13.861f, 13.264f, 12.844f, 12.149f, 11.290f, 10.216f, + 9.382f, 8.487f, 7.872f, 7.869f, 8.443f, 9.403f, 11.327f, 13.967f, 15.677f, + 16.804f, 15.432f, 15.102f, 17.403f, 20.866f, 19.099f, 18.549f, 22.326f, 24.098f, + 24.508f, 24.169f, 22.182f, 20.792f, 19.493f, 19.081f, 20.190f, 20.819f, 22.097f, + 22.998f, 24.003f, 25.489f, 27.853f, 31.410f, 36.313f, 36.965f, 35.964f, 33.889f, + 30.188f, 28.047f, 27.069f, 26.381f, 26.753f, 28.247f, 29.939f, 30.694f, 36.085f, + 43.335f, 43.467f, 42.678f, 44.277f, 44.986f, 45.025f, 45.603f, 47.975f, 51.084f, + 52.180f, 49.330f, 49.635f, 48.018f, 47.150f, 48.087f, 45.700f, 43.694f, 41.611f, + 39.777f, 40.626f, 41.818f, 41.680f, 42.158f, 44.184f, 44.452f, 45.957f, 45.242f, + 45.196f, 43.352f, 42.783f, 43.393f, 42.573f, 43.844f, 44.224f, 44.808f, 44.702f, + 45.589f, 46.096f, 45.145f, 43.790f, 42.637f, 41.178f, 39.905f, 38.250f, 35.352f, + 31.672f, 31.018f, 27.779f, 26.327f, 24.912f, 22.497f, 20.221f, 17.529f, 15.404f, + 13.606f}, + {-29.534f, -27.841f, -24.390f, -21.229f, -17.938f, -16.080f, -14.370f, -11.927f, -9.433f, + -7.085f, -4.283f, -1.891f, 0.525f, 3.940f, 7.644f, 11.373f, 15.108f, 18.532f, + 17.439f, 13.633f, 14.591f, 13.377f, 13.473f, 14.576f, 15.444f, 16.873f, 17.630f, + 17.824f, 18.531f, 17.993f, 17.492f, 17.772f, 18.992f, 19.870f, 21.651f, 25.845f, + 26.556f, 26.396f, 25.794f, 25.476f, 25.119f, 24.255f, 24.205f, 25.014f, 24.014f, + 23.629f, 24.111f, 23.849f, 22.925f, 21.710f, 20.827f, 21.040f, 21.635f, 22.412f, + 21.917f, 21.464f, 21.842f, 22.901f, 23.404f, 23.830f, 24.222f, 24.359f, 24.644f, + 24.768f, 24.342f, 25.604f, 25.050f, 24.853f, 24.518f, 22.725f, 20.790f, 19.248f, + 17.555f, 15.881f, 14.741f, 14.402f, 14.005f, 13.472f, 12.914f, 11.945f, 10.675f, + 9.484f, 8.362f, 7.522f, 7.189f, 7.625f, 8.341f, 9.911f, 12.455f, 14.390f, + 16.331f, 15.955f, 15.972f, 17.036f, 19.374f, 18.789f, 20.377f, 21.712f, 23.681f, + 25.011f, 24.881f, 22.413f, 21.035f, 19.929f, 19.285f, 19.383f, 20.505f, 21.650f, + 22.839f, 23.268f, 24.178f, 26.177f, 29.701f, 33.566f, 36.582f, 36.022f, 33.149f, + 29.679f, 27.527f, 27.080f, 26.407f, 26.617f, 27.890f, 28.934f, 29.298f, 37.322f, + 43.291f, 42.751f, 42.135f, 43.562f, 44.224f, 44.773f, 45.549f, 45.828f, 51.578f, + 52.963f, 51.283f, 49.310f, 49.141f, 48.396f, 48.733f, 46.870f, 44.141f, 41.230f, + 39.540f, 40.296f, 41.312f, 40.885f, 41.829f, 45.263f, 45.307f, 45.594f, 45.572f, + 44.547f, 43.190f, 41.290f, 42.911f, 42.322f, 42.287f, 43.497f, 44.151f, 44.039f, + 44.665f, 45.508f, 45.203f, 43.430f, 42.155f, 40.799f, 39.322f, 38.584f, 35.413f, + 31.721f, 31.268f, 27.559f, 26.134f, 24.841f, 22.454f, 20.222f, 17.519f, 15.393f, + 13.606f}, + {-29.534f, -27.838f, -24.330f, -21.070f, -17.776f, -16.117f, -14.200f, -11.756f, -9.418f, + -6.869f, -3.907f, -1.399f, 1.173f, 4.303f, 7.820f, 12.096f, 15.555f, 17.964f, + 16.519f, 12.815f, 14.465f, 13.556f, 13.988f, 14.877f, 15.863f, 16.730f, 17.919f, + 18.421f, 19.514f, 18.884f, 18.241f, 18.232f, 19.498f, 19.446f, 21.528f, 25.300f, + 26.074f, 27.017f, 25.964f, 25.697f, 23.581f, 25.107f, 25.961f, 26.093f, 24.159f, + 24.672f, 24.250f, 24.518f, 24.000f, 23.171f, 22.081f, 22.059f, 22.507f, 23.115f, + 22.884f, 22.214f, 22.567f, 23.023f, 24.088f, 24.469f, 24.913f, 24.668f, 24.779f, + 25.331f, 24.728f, 23.617f, 22.854f, 23.789f, 23.733f, 23.227f, 21.197f, 19.255f, + 17.480f, 16.093f, 14.877f, 14.638f, 14.597f, 14.202f, 13.809f, 12.801f, 11.271f, + 9.841f, 8.417f, 7.415f, 7.209f, 7.341f, 7.621f, 7.748f, 11.371f, 14.324f, + 13.662f, 14.059f, 14.148f, 15.824f, 18.235f, 20.255f, 21.128f, 21.908f, 22.085f, + 23.126f, 23.888f, 22.158f, 21.603f, 20.888f, 20.143f, 19.409f, 20.876f, 22.493f, + 24.230f, 24.776f, 24.607f, 26.040f, 29.836f, 33.258f, 34.752f, 35.717f, 33.239f, + 29.754f, 28.955f, 27.320f, 26.524f, 27.292f, 28.717f, 29.407f, 29.607f, 38.465f, + 43.029f, 42.697f, 41.625f, 45.074f, 45.807f, 46.017f, 45.813f, 45.739f, 48.571f, + 44.668f, 51.853f, 48.389f, 49.306f, 48.233f, 48.497f, 48.385f, 44.503f, 41.177f, + 39.194f, 40.626f, 40.872f, 40.445f, 40.740f, 43.606f, 44.699f, 45.209f, 46.153f, + 43.589f, 42.118f, 40.714f, 41.948f, 42.618f, 41.043f, 42.604f, 43.381f, 43.593f, + 43.736f, 44.866f, 44.488f, 42.496f, 41.729f, 40.488f, 38.887f, 38.637f, 35.418f, + 31.760f, 31.488f, 27.340f, 25.997f, 24.790f, 22.432f, 20.213f, 17.509f, 15.382f, + 13.606f}, + {-29.534f, -27.837f, -24.272f, -20.906f, -17.576f, -16.031f, -13.991f, -11.555f, -9.432f, + -6.722f, -3.481f, -0.881f, 1.823f, 4.715f, 8.213f, 12.545f, 15.960f, 17.613f, + 15.652f, 12.250f, 14.387f, 13.581f, 14.070f, 15.049f, 16.031f, 16.940f, 18.184f, + 19.253f, 19.977f, 19.755f, 19.078f, 18.582f, 19.134f, 19.592f, 21.792f, 24.516f, + 25.942f, 26.723f, 26.439f, 25.567f, 24.658f, 23.199f, 24.912f, 24.808f, 25.002f, + 25.723f, 25.305f, 24.953f, 24.926f, 24.637f, 23.628f, 22.890f, 22.708f, 23.378f, + 23.609f, 23.157f, 23.476f, 23.664f, 24.301f, 25.152f, 25.625f, 25.319f, 25.191f, + 25.186f, 24.776f, 23.915f, 22.905f, 21.959f, 22.510f, 22.956f, 22.698f, 19.039f, + 17.490f, 16.650f, 15.258f, 14.987f, 14.960f, 15.060f, 14.745f, 13.517f, 11.930f, + 10.287f, 8.526f, 7.441f, 7.301f, 7.121f, 4.554f, 7.567f, 10.487f, 12.113f, + 12.343f, 13.445f, 13.439f, 15.328f, 20.480f, 21.327f, 21.736f, 21.333f, 20.872f, + 22.753f, 23.894f, 22.135f, 21.395f, 20.969f, 20.431f, 20.108f, 21.291f, 23.873f, + 27.037f, 28.501f, 26.649f, 27.712f, 29.742f, 31.482f, 34.439f, 34.874f, 31.979f, + 29.649f, 28.740f, 27.964f, 26.717f, 28.181f, 30.031f, 30.806f, 31.529f, 37.213f, + 42.088f, 43.112f, 42.876f, 46.097f, 48.223f, 48.052f, 50.617f, 47.476f, 45.549f, + 41.503f, 47.574f, 47.703f, 48.101f, 48.414f, 48.236f, 47.941f, 44.853f, 40.853f, + 39.449f, 40.381f, 40.477f, 39.426f, 39.184f, 41.661f, 41.977f, 43.124f, 44.902f, + 42.426f, 41.314f, 40.404f, 40.709f, 42.485f, 40.898f, 41.457f, 42.597f, 42.993f, + 42.837f, 44.091f, 43.422f, 41.650f, 41.334f, 40.126f, 38.836f, 38.412f, 35.411f, + 31.706f, 31.596f, 27.162f, 25.906f, 24.764f, 22.435f, 20.195f, 17.500f, 15.371f, + 13.606f}, + {-29.534f, -27.836f, -24.217f, -20.744f, -17.349f, -15.811f, -13.726f, -11.301f, -9.422f, + -6.597f, -3.031f, -0.437f, 2.245f, 5.216f, 8.829f, 12.838f, 16.435f, 17.910f, + 15.459f, 11.825f, 14.062f, 14.179f, 14.615f, 15.578f, 16.567f, 17.494f, 18.453f, + 19.944f, 20.579f, 20.770f, 19.934f, 19.012f, 19.207f, 20.006f, 22.100f, 24.237f, + 26.653f, 27.013f, 27.080f, 26.766f, 25.100f, 25.440f, 26.439f, 25.798f, 25.368f, + 26.060f, 26.398f, 26.397f, 25.761f, 25.697f, 24.771f, 23.851f, 23.321f, 23.731f, + 24.177f, 24.075f, 24.035f, 24.290f, 24.967f, 25.765f, 25.904f, 25.760f, 25.543f, + 25.288f, 24.599f, 23.915f, 22.918f, 22.423f, 22.387f, 22.403f, 23.065f, 19.606f, + 18.388f, 17.649f, 16.277f, 16.191f, 15.558f, 15.867f, 15.806f, 14.483f, 12.982f, + 10.964f, 9.002f, 8.046f, 7.983f, 5.531f, 5.286f, 7.046f, 6.526f, 9.303f, + 9.000f, 11.431f, 12.674f, 14.569f, 16.015f, 20.145f, 22.538f, 20.179f, 20.136f, + 20.630f, 21.569f, 21.015f, 20.507f, 19.677f, 20.178f, 19.774f, 20.885f, 22.985f, + 25.402f, 26.481f, 26.504f, 27.053f, 27.404f, 29.286f, 32.656f, 32.577f, 31.143f, + 29.343f, 28.412f, 28.505f, 27.749f, 29.019f, 32.060f, 32.830f, 33.460f, 36.839f, + 40.039f, 42.474f, 43.499f, 43.900f, 45.726f, 47.020f, 47.223f, 48.546f, 46.414f, + 39.049f, 48.953f, 48.668f, 46.634f, 48.345f, 48.029f, 47.138f, 44.395f, 41.003f, + 39.506f, 40.019f, 39.343f, 38.490f, 38.129f, 40.336f, 40.457f, 40.397f, 41.717f, + 41.486f, 40.655f, 40.107f, 39.595f, 41.118f, 41.162f, 40.202f, 41.764f, 42.337f, + 42.334f, 43.339f, 42.586f, 41.173f, 40.599f, 39.589f, 38.901f, 37.953f, 35.405f, + 31.561f, 31.559f, 27.055f, 25.843f, 24.760f, 22.466f, 20.166f, 17.492f, 15.359f, + 13.606f}, + {-29.534f, -27.836f, -24.164f, -20.587f, -17.108f, -15.473f, -13.402f, -11.000f, -9.337f, + -6.449f, -2.621f, -0.081f, 2.463f, 5.670f, 9.330f, 13.263f, 16.866f, 18.298f, + 15.582f, 11.374f, 14.352f, 15.483f, 15.627f, 15.922f, 17.481f, 17.975f, 18.802f, + 20.620f, 21.822f, 21.876f, 20.926f, 19.731f, 19.492f, 20.188f, 22.091f, 24.209f, + 27.029f, 28.154f, 28.613f, 26.876f, 26.493f, 26.264f, 26.011f, 25.938f, 26.021f, + 26.320f, 27.135f, 27.514f, 26.345f, 26.679f, 25.629f, 24.868f, 24.113f, 24.425f, + 24.887f, 24.950f, 24.639f, 24.863f, 25.372f, 25.643f, 25.942f, 26.109f, 25.610f, + 25.321f, 24.629f, 23.804f, 23.389f, 22.994f, 23.014f, 23.088f, 23.512f, 22.296f, + 20.461f, 21.282f, 19.670f, 17.937f, 17.237f, 16.669f, 16.623f, 15.230f, 14.320f, + 11.443f, 10.281f, 10.681f, 8.987f, 5.623f, 5.295f, 4.294f, 5.356f, 8.141f, + 9.154f, 10.954f, 11.653f, 13.161f, 15.020f, 18.332f, 20.108f, 20.026f, 19.385f, + 19.103f, 19.019f, 19.259f, 18.843f, 18.694f, 18.923f, 18.788f, 18.831f, 21.135f, + 22.949f, 24.652f, 25.056f, 25.013f, 27.014f, 28.892f, 30.358f, 30.499f, 29.130f, + 28.704f, 28.291f, 28.480f, 29.004f, 31.021f, 32.540f, 33.083f, 33.722f, 36.441f, + 39.322f, 42.077f, 43.169f, 43.186f, 44.352f, 46.020f, 47.718f, 48.848f, 44.595f, + 40.733f, 49.278f, 49.611f, 45.956f, 46.995f, 47.189f, 46.464f, 44.308f, 40.701f, + 39.290f, 38.628f, 37.660f, 37.940f, 36.775f, 37.784f, 38.595f, 38.163f, 38.809f, + 39.656f, 38.901f, 39.329f, 38.713f, 39.795f, 41.126f, 39.381f, 40.837f, 41.728f, + 41.908f, 42.652f, 41.955f, 40.662f, 39.610f, 38.958f, 38.492f, 37.293f, 35.353f, + 31.390f, 31.388f, 27.031f, 25.781f, 24.769f, 22.520f, 20.128f, 17.484f, 15.346f, + 13.606f}, + {-29.534f, -27.837f, -24.112f, -20.440f, -16.868f, -15.055f, -13.039f, -10.694f, -9.143f, + -6.249f, -2.288f, 0.269f, 2.693f, 5.911f, 9.509f, 13.805f, 17.195f, 18.505f, + 15.444f, 11.145f, 15.693f, 15.637f, 15.369f, 15.624f, 18.247f, 18.334f, 19.261f, + 21.250f, 22.895f, 22.852f, 21.985f, 20.671f, 19.988f, 20.470f, 22.434f, 24.446f, + 27.722f, 28.618f, 29.866f, 27.253f, 26.336f, 26.855f, 26.229f, 26.005f, 26.679f, + 26.778f, 27.348f, 27.784f, 27.409f, 26.967f, 26.421f, 25.929f, 25.140f, 24.919f, + 25.311f, 25.451f, 25.458f, 25.615f, 26.531f, 26.602f, 26.532f, 26.835f, 26.651f, + 26.420f, 25.843f, 25.429f, 25.204f, 24.397f, 24.348f, 24.512f, 25.081f, 24.463f, + 22.243f, 21.840f, 22.758f, 20.970f, 18.972f, 18.321f, 17.239f, 16.663f, 15.327f, + 12.786f, 11.138f, 12.795f, 10.655f, 4.414f, 2.715f, 3.764f, 7.300f, 8.246f, + 7.836f, 9.161f, 9.427f, 11.343f, 13.952f, 15.763f, 17.547f, 19.005f, 18.225f, + 18.578f, 18.132f, 18.077f, 17.383f, 17.326f, 16.934f, 16.708f, 17.222f, 19.977f, + 21.997f, 22.852f, 22.833f, 23.772f, 25.195f, 26.539f, 28.185f, 28.569f, 28.266f, + 28.163f, 28.573f, 29.077f, 30.290f, 31.888f, 32.318f, 33.102f, 33.438f, 36.376f, + 39.411f, 41.920f, 43.318f, 43.082f, 44.248f, 46.068f, 48.386f, 48.411f, 42.135f, + 42.678f, 47.630f, 49.545f, 45.186f, 46.210f, 47.303f, 45.847f, 43.060f, 40.459f, + 38.592f, 37.468f, 36.597f, 37.256f, 35.538f, 35.119f, 35.762f, 35.574f, 37.018f, + 37.262f, 36.107f, 37.513f, 37.149f, 38.287f, 40.858f, 39.063f, 40.008f, 40.944f, + 41.245f, 42.070f, 41.202f, 39.991f, 39.113f, 38.369f, 37.226f, 36.511f, 35.172f, + 31.258f, 31.105f, 27.072f, 25.702f, 24.780f, 22.591f, 20.083f, 17.475f, 15.333f, + 13.606f}, + {-29.534f, -27.838f, -24.060f, -20.307f, -16.644f, -14.608f, -12.674f, -10.450f, -8.839f, + -5.974f, -2.015f, 0.676f, 3.083f, 6.003f, 9.612f, 14.250f, 17.561f, 18.917f, + 15.476f, 11.353f, 16.826f, 14.923f, 14.371f, 15.671f, 18.777f, 18.848f, 19.712f, + 21.692f, 23.315f, 23.646f, 22.824f, 21.535f, 20.554f, 21.343f, 23.019f, 25.351f, + 27.599f, 29.875f, 30.967f, 29.473f, 26.998f, 27.670f, 27.119f, 26.712f, 27.343f, + 27.378f, 27.524f, 27.986f, 28.238f, 27.088f, 26.635f, 26.356f, 25.526f, 25.477f, + 25.543f, 25.774f, 25.870f, 26.575f, 27.104f, 27.692f, 27.990f, 28.499f, 28.495f, + 28.214f, 27.868f, 27.657f, 27.927f, 27.802f, 26.778f, 25.866f, 24.724f, 24.367f, + 24.619f, 23.382f, 23.857f, 22.393f, 21.322f, 21.982f, 19.394f, 18.226f, 17.424f, + 15.666f, 13.215f, 11.099f, 7.473f, 4.232f, 3.476f, 4.735f, 6.980f, 6.231f, + 6.074f, 6.566f, 7.388f, 8.256f, 12.298f, 14.098f, 14.671f, 16.806f, 16.363f, + 16.488f, 16.953f, 16.352f, 15.956f, 15.424f, 15.232f, 15.278f, 16.707f, 18.870f, + 20.076f, 20.576f, 21.220f, 22.225f, 23.673f, 25.094f, 26.433f, 26.872f, 26.785f, + 26.897f, 28.994f, 30.354f, 31.289f, 31.472f, 33.021f, 32.466f, 32.984f, 35.842f, + 37.965f, 40.279f, 43.700f, 42.787f, 44.180f, 47.154f, 49.299f, 47.124f, 40.782f, + 43.195f, 44.762f, 48.629f, 44.741f, 46.606f, 46.695f, 44.492f, 41.808f, 39.402f, + 37.155f, 35.793f, 36.318f, 36.169f, 34.405f, 32.938f, 32.610f, 33.576f, 35.295f, + 34.957f, 33.958f, 35.803f, 34.847f, 35.543f, 39.433f, 38.724f, 39.415f, 40.161f, + 40.962f, 41.673f, 40.302f, 39.725f, 39.522f, 37.711f, 35.339f, 35.782f, 34.795f, + 31.184f, 30.720f, 27.135f, 25.595f, 24.780f, 22.671f, 20.031f, 17.465f, 15.319f, + 13.606f}, + {-29.534f, -27.841f, -24.007f, -20.191f, -16.452f, -14.189f, -12.359f, -10.329f, -8.454f, + -5.599f, -1.736f, 1.126f, 3.576f, 6.245f, 10.028f, 14.562f, 17.953f, 19.368f, + 16.025f, 12.169f, 16.837f, 15.423f, 14.549f, 16.062f, 18.410f, 19.497f, 20.165f, + 21.927f, 23.536f, 23.848f, 23.249f, 22.330f, 21.632f, 22.066f, 24.115f, 25.906f, + 27.974f, 31.002f, 31.430f, 30.884f, 28.346f, 28.432f, 28.075f, 27.025f, 27.479f, + 28.200f, 28.047f, 27.649f, 28.346f, 28.887f, 26.091f, 28.275f, 26.014f, 26.193f, + 25.584f, 25.569f, 25.914f, 26.714f, 27.673f, 28.559f, 29.431f, 29.943f, 30.080f, + 31.186f, 30.606f, 30.384f, 29.205f, 29.349f, 27.831f, 25.377f, 25.459f, 25.660f, + 25.577f, 23.555f, 23.975f, 24.410f, 21.556f, 20.704f, 20.884f, 18.497f, 17.230f, + 15.554f, 13.150f, 9.760f, 5.594f, 3.099f, 2.861f, 4.359f, 4.401f, 3.820f, + 3.243f, 3.743f, 4.407f, 5.894f, 9.800f, 12.047f, 12.415f, 15.100f, 14.310f, + 13.704f, 14.584f, 14.839f, 14.408f, 13.911f, 13.536f, 14.532f, 15.413f, 17.109f, + 18.005f, 18.568f, 20.012f, 21.100f, 23.179f, 25.388f, 25.774f, 25.632f, 26.257f, + 27.149f, 29.421f, 30.674f, 31.063f, 30.891f, 31.772f, 31.357f, 32.230f, 34.107f, + 36.779f, 38.398f, 42.250f, 43.028f, 45.255f, 47.572f, 48.498f, 43.147f, 42.194f, + 44.444f, 46.672f, 48.473f, 45.159f, 46.836f, 45.781f, 43.576f, 40.854f, 37.483f, + 35.772f, 34.340f, 34.841f, 33.912f, 32.508f, 30.912f, 30.724f, 32.050f, 33.962f, + 33.061f, 32.366f, 34.155f, 33.515f, 32.860f, 35.936f, 38.192f, 38.900f, 39.591f, + 41.002f, 41.056f, 39.422f, 40.130f, 40.056f, 36.661f, 33.539f, 35.295f, 34.207f, + 31.135f, 30.225f, 27.167f, 25.460f, 24.759f, 22.748f, 19.975f, 17.454f, 15.305f, + 13.606f}, + {-29.534f, -27.844f, -23.953f, -20.093f, -16.300f, -13.850f, -12.137f, -10.356f, -8.031f, + -5.111f, -1.385f, 1.561f, 4.046f, 6.853f, 10.786f, 14.904f, 18.190f, 19.313f, + 16.249f, 13.385f, 16.750f, 16.351f, 15.101f, 15.846f, 17.792f, 19.747f, 20.495f, + 22.175f, 23.826f, 24.022f, 23.640f, 22.987f, 22.811f, 23.395f, 24.992f, 26.929f, + 28.757f, 31.543f, 32.671f, 31.200f, 29.694f, 28.919f, 28.625f, 28.179f, 28.500f, + 28.456f, 28.109f, 28.417f, 28.588f, 28.686f, 27.889f, 26.652f, 27.357f, 26.233f, + 25.897f, 25.500f, 25.875f, 27.174f, 28.637f, 29.020f, 31.714f, 31.624f, 31.542f, + 31.601f, 32.328f, 31.618f, 30.666f, 30.016f, 29.281f, 26.991f, 25.870f, 24.663f, + 23.765f, 22.282f, 21.637f, 22.453f, 22.419f, 22.303f, 21.653f, 19.860f, 17.204f, + 14.950f, 12.048f, 8.885f, 5.173f, 2.021f, 1.060f, 2.143f, 1.539f, 0.082f, + -1.156f, -0.314f, 0.287f, 3.495f, 7.870f, 9.020f, 10.118f, 11.949f, 11.841f, + 12.036f, 12.599f, 12.759f, 13.004f, 13.225f, 13.683f, 13.685f, 14.118f, 14.891f, + 16.294f, 17.911f, 20.147f, 22.067f, 24.184f, 26.087f, 25.918f, 25.256f, 26.239f, + 28.042f, 29.953f, 31.016f, 29.809f, 29.556f, 30.270f, 29.779f, 31.795f, 33.889f, + 37.763f, 41.384f, 42.496f, 43.180f, 46.366f, 48.151f, 46.227f, 43.084f, 43.049f, + 45.537f, 46.977f, 47.768f, 46.447f, 46.411f, 44.796f, 42.758f, 39.731f, 35.775f, + 34.742f, 33.733f, 33.053f, 32.420f, 31.152f, 29.320f, 29.331f, 30.658f, 32.361f, + 31.863f, 31.097f, 32.129f, 32.982f, 31.089f, 31.938f, 37.221f, 38.095f, 38.734f, + 40.058f, 39.600f, 38.571f, 40.408f, 39.403f, 35.074f, 32.406f, 35.063f, 33.444f, + 31.056f, 29.615f, 27.120f, 25.308f, 24.710f, 22.812f, 19.917f, 17.443f, 15.290f, + 13.606f}, + {-29.534f, -27.848f, -23.897f, -20.014f, -16.194f, -13.622f, -12.031f, -10.502f, -7.612f, + -4.520f, -0.938f, 1.967f, 4.487f, 7.709f, 11.554f, 15.321f, 18.315f, 19.190f, + 16.006f, 14.331f, 17.584f, 16.305f, 14.808f, 15.479f, 17.562f, 19.140f, 20.857f, + 22.181f, 23.701f, 24.182f, 24.340f, 23.620f, 23.253f, 24.642f, 26.214f, 27.794f, + 29.464f, 32.374f, 33.128f, 31.974f, 30.727f, 29.606f, 29.510f, 29.019f, 29.112f, + 29.412f, 29.369f, 29.004f, 28.734f, 28.779f, 27.769f, 27.558f, 26.582f, 26.182f, + 26.637f, 26.321f, 26.712f, 27.770f, 30.501f, 31.119f, 30.758f, 31.246f, 32.488f, + 33.354f, 33.627f, 33.277f, 32.511f, 31.783f, 29.821f, 28.852f, 26.204f, 22.785f, + 21.058f, 20.689f, 20.169f, 20.305f, 20.720f, 21.632f, 21.372f, 19.485f, 16.402f, + 12.684f, 10.016f, 7.395f, 3.669f, 0.299f, -2.046f, -2.433f, -3.124f, -4.257f, + -3.744f, -2.665f, -0.843f, 1.096f, 4.763f, 5.939f, 7.923f, 8.266f, 8.611f, + 8.914f, 10.228f, 11.350f, 12.026f, 12.213f, 12.541f, 12.896f, 13.041f, 13.607f, + 15.226f, 17.702f, 21.541f, 24.675f, 26.439f, 26.578f, 26.850f, 27.011f, 28.153f, + 29.622f, 30.246f, 30.410f, 29.526f, 28.521f, 28.693f, 28.794f, 30.528f, 33.128f, + 31.055f, 30.834f, 37.560f, 44.374f, 44.921f, 47.591f, 47.390f, 43.123f, 44.225f, + 46.475f, 46.046f, 46.594f, 46.296f, 46.198f, 44.127f, 42.374f, 38.764f, 34.287f, + 33.721f, 32.698f, 31.814f, 30.485f, 29.280f, 27.720f, 27.167f, 28.865f, 30.000f, + 30.666f, 30.251f, 30.617f, 32.282f, 30.483f, 30.005f, 35.460f, 36.785f, 37.200f, + 37.936f, 37.440f, 37.622f, 39.508f, 37.215f, 33.223f, 31.917f, 34.829f, 32.579f, + 30.905f, 28.914f, 26.970f, 25.151f, 24.633f, 22.857f, 19.861f, 17.430f, 15.275f, + 13.606f}, + {-29.534f, -27.853f, -23.839f, -19.951f, -16.130f, -13.515f, -12.028f, -10.682f, -7.216f, + -3.868f, -0.429f, 2.372f, 4.998f, 8.513f, 12.087f, 15.651f, 18.541f, 19.667f, + 16.516f, 14.980f, 18.122f, 15.894f, 14.248f, 15.595f, 17.049f, 18.554f, 20.751f, + 22.353f, 23.742f, 24.410f, 24.901f, 24.066f, 24.065f, 25.418f, 27.152f, 28.563f, + 30.759f, 33.035f, 33.759f, 32.430f, 31.463f, 30.281f, 29.918f, 30.242f, 30.449f, + 30.033f, 29.686f, 29.388f, 29.255f, 29.023f, 28.775f, 27.226f, 27.046f, 26.921f, + 27.222f, 28.041f, 28.629f, 31.070f, 30.447f, 30.889f, 31.533f, 32.311f, 31.879f, + 33.245f, 33.624f, 32.760f, 32.075f, 32.401f, 30.653f, 28.287f, 26.372f, 22.204f, + 19.766f, 19.091f, 18.425f, 18.037f, 17.959f, 18.473f, 19.251f, 15.996f, 13.119f, + 9.789f, 7.110f, 4.675f, 1.484f, -2.369f, -5.508f, -7.503f, -7.303f, -7.689f, + -8.208f, -6.206f, -3.087f, -0.471f, 2.909f, 4.301f, 5.029f, 5.880f, 5.693f, + 5.505f, 7.937f, 9.695f, 10.634f, 10.716f, 11.205f, 11.686f, 12.295f, 12.873f, + 14.868f, 17.831f, 22.845f, 28.835f, 28.132f, 27.267f, 27.281f, 28.047f, 29.539f, + 30.860f, 30.212f, 29.249f, 28.869f, 28.431f, 27.188f, 27.655f, 29.100f, 29.407f, + 28.620f, 28.950f, 31.298f, 37.090f, 37.884f, 45.798f, 43.624f, 43.273f, 46.350f, + 46.312f, 45.433f, 45.356f, 44.001f, 43.452f, 44.025f, 40.745f, 37.069f, 33.332f, + 31.646f, 31.384f, 29.869f, 28.159f, 27.248f, 25.776f, 25.200f, 25.821f, 26.646f, + 28.517f, 29.642f, 29.746f, 31.455f, 30.975f, 30.383f, 33.375f, 35.149f, 35.266f, + 35.894f, 35.212f, 36.423f, 37.348f, 34.492f, 31.588f, 31.558f, 34.236f, 31.701f, + 30.669f, 28.187f, 26.717f, 25.000f, 24.533f, 22.876f, 19.808f, 17.415f, 15.260f, + 13.606f}, + {-29.534f, -27.858f, -23.777f, -19.902f, -16.102f, -13.510f, -12.081f, -10.776f, -6.838f, + -3.218f, 0.070f, 2.788f, 5.617f, 9.120f, 12.469f, 15.796f, 18.842f, 20.134f, + 17.530f, 15.651f, 17.031f, 15.404f, 14.150f, 15.814f, 16.946f, 18.897f, 19.954f, + 22.355f, 23.888f, 24.697f, 25.255f, 24.696f, 25.277f, 26.437f, 27.946f, 29.783f, + 31.495f, 33.914f, 34.648f, 32.637f, 32.004f, 31.073f, 30.646f, 30.844f, 31.388f, + 31.142f, 30.473f, 29.846f, 29.394f, 29.425f, 29.365f, 27.526f, 27.338f, 27.263f, + 28.404f, 29.606f, 31.187f, 31.180f, 32.208f, 32.143f, 33.847f, 32.489f, 32.068f, + 30.946f, 29.678f, 29.299f, 29.226f, 29.793f, 28.795f, 28.643f, 25.099f, 21.969f, + 19.177f, 17.835f, 17.055f, 16.414f, 15.941f, 15.278f, 14.629f, 12.643f, 10.560f, + 7.984f, 5.528f, 3.110f, -0.850f, -5.602f, -8.504f, -10.739f, -11.015f, -13.061f, + -11.410f, -10.020f, -6.514f, -3.274f, -2.799f, -1.130f, 1.203f, 2.623f, 3.976f, + 3.572f, 5.661f, 7.552f, 8.302f, 9.655f, 10.096f, 10.491f, 10.872f, 10.981f, + 13.151f, 16.926f, 24.088f, 29.591f, 28.108f, 26.639f, 26.077f, 26.481f, 28.154f, + 29.715f, 28.533f, 28.517f, 28.358f, 28.132f, 26.711f, 27.158f, 27.733f, 28.211f, + 28.503f, 28.259f, 29.470f, 29.527f, 39.073f, 39.786f, 39.050f, 42.868f, 46.822f, + 46.065f, 44.912f, 45.104f, 43.596f, 43.159f, 42.673f, 39.458f, 34.870f, 30.947f, + 30.065f, 29.471f, 27.717f, 26.519f, 25.097f, 23.652f, 22.891f, 23.220f, 23.422f, + 25.233f, 28.403f, 28.766f, 30.359f, 31.118f, 31.451f, 31.776f, 33.355f, 33.175f, + 34.316f, 33.169f, 34.863f, 34.797f, 32.418f, 30.438f, 30.915f, 33.125f, 30.905f, + 30.357f, 27.525f, 26.390f, 24.860f, 24.421f, 22.868f, 19.761f, 17.399f, 15.244f, + 13.606f}, + {-29.534f, -27.865f, -23.712f, -19.863f, -16.097f, -13.569f, -12.118f, -10.668f, -6.446f, + -2.626f, 0.501f, 3.170f, 6.213f, 9.608f, 12.862f, 15.888f, 19.000f, 19.948f, + 17.478f, 15.943f, 15.701f, 14.913f, 14.702f, 15.883f, 17.413f, 19.059f, 19.790f, + 21.941f, 24.240f, 24.911f, 25.338f, 25.250f, 25.704f, 27.054f, 29.127f, 30.680f, + 32.334f, 34.538f, 35.061f, 33.691f, 32.538f, 32.258f, 31.927f, 31.372f, 32.005f, + 32.032f, 31.441f, 30.297f, 29.658f, 29.365f, 29.264f, 28.848f, 26.861f, 27.143f, + 29.276f, 31.041f, 31.621f, 32.835f, 33.015f, 32.916f, 34.822f, 32.115f, 31.913f, + 31.906f, 28.358f, 27.643f, 27.118f, 26.503f, 26.912f, 27.515f, 23.455f, 20.878f, + 18.494f, 16.505f, 15.583f, 14.740f, 13.918f, 13.072f, 11.975f, 10.365f, 8.374f, + 6.413f, 4.035f, 0.550f, -3.867f, -8.310f, -10.484f, -13.130f, -14.556f, -14.998f, + -15.079f, -12.667f, -10.069f, -6.918f, -6.313f, -5.191f, -2.758f, -0.369f, 1.935f, + 0.709f, 3.734f, 5.846f, 7.459f, 8.111f, 9.383f, 10.028f, 10.453f, 10.034f, + 12.230f, 15.752f, 20.298f, 24.499f, 25.715f, 24.964f, 25.083f, 24.702f, 26.094f, + 26.641f, 26.261f, 26.146f, 26.941f, 26.870f, 26.957f, 27.023f, 26.096f, 26.413f, + 26.515f, 27.235f, 25.130f, 29.055f, 34.161f, 35.293f, 36.853f, 44.137f, 46.377f, + 45.082f, 44.650f, 43.717f, 43.887f, 43.032f, 41.969f, 38.109f, 33.099f, 29.817f, + 29.154f, 27.570f, 25.903f, 24.540f, 22.483f, 21.339f, 20.260f, 21.474f, 22.235f, + 22.149f, 26.188f, 27.286f, 29.188f, 30.557f, 31.729f, 31.040f, 31.377f, 31.067f, + 32.646f, 31.432f, 33.025f, 32.658f, 31.231f, 29.706f, 30.074f, 31.689f, 30.265f, + 29.980f, 27.005f, 26.028f, 24.728f, 24.308f, 22.834f, 19.720f, 17.382f, 15.227f, + 13.606f}, + {-29.534f, -27.871f, -23.644f, -19.827f, -16.099f, -13.641f, -12.061f, -10.280f, -5.999f, + -2.112f, 0.850f, 3.473f, 6.624f, 10.064f, 13.230f, 16.069f, 18.901f, 19.793f, + 17.079f, 16.160f, 15.908f, 15.082f, 15.187f, 15.909f, 17.533f, 18.759f, 19.981f, + 21.813f, 24.062f, 25.170f, 25.447f, 25.722f, 26.287f, 27.769f, 29.436f, 31.591f, + 33.330f, 35.298f, 35.502f, 34.060f, 33.226f, 32.657f, 32.301f, 31.924f, 32.384f, + 32.462f, 31.888f, 30.988f, 30.094f, 29.555f, 29.418f, 29.232f, 27.802f, 28.893f, + 30.850f, 31.538f, 32.708f, 33.553f, 34.923f, 35.139f, 33.695f, 31.271f, 30.187f, + 29.771f, 29.044f, 27.603f, 26.235f, 24.964f, 24.947f, 24.054f, 21.570f, 19.539f, + 17.272f, 15.293f, 14.025f, 13.039f, 11.955f, 11.000f, 9.822f, 8.378f, 6.333f, + 3.927f, 1.269f, -2.368f, -6.429f, -9.731f, -12.792f, -15.168f, -17.660f, -18.760f, + -17.336f, -15.490f, -14.135f, -10.131f, -8.206f, -7.529f, -5.639f, -1.890f, -0.587f, + -0.867f, 1.623f, 4.240f, 5.436f, 6.766f, 8.198f, 10.061f, 11.305f, 11.301f, + 11.837f, 12.916f, 14.434f, 16.606f, 19.863f, 21.806f, 22.411f, 22.090f, 23.884f, + 25.218f, 24.534f, 24.702f, 25.833f, 26.931f, 29.200f, 27.904f, 25.473f, 23.041f, + 20.530f, 23.124f, 23.303f, 26.731f, 34.187f, 37.167f, 40.781f, 45.690f, 45.268f, + 44.007f, 43.669f, 42.814f, 42.729f, 42.772f, 40.009f, 36.729f, 32.511f, 30.627f, + 29.276f, 26.520f, 24.840f, 22.961f, 20.671f, 19.467f, 18.615f, 20.337f, 21.007f, + 19.592f, 23.769f, 25.206f, 27.593f, 29.653f, 30.598f, 30.833f, 29.535f, 29.403f, + 30.863f, 30.238f, 31.164f, 31.083f, 30.399f, 29.188f, 29.428f, 30.305f, 29.804f, + 29.555f, 26.652f, 25.672f, 24.597f, 24.207f, 22.776f, 19.687f, 17.363f, 15.210f, + 13.606f}, + {-29.534f, -27.879f, -23.572f, -19.791f, -16.091f, -13.672f, -11.843f, -9.598f, -5.456f, + -1.653f, 1.156f, 3.726f, 6.861f, 10.455f, 13.457f, 16.282f, 18.566f, 19.899f, + 18.064f, 17.738f, 17.223f, 15.681f, 15.046f, 15.764f, 17.542f, 18.890f, 20.284f, + 22.179f, 23.652f, 25.288f, 25.608f, 26.138f, 26.749f, 28.134f, 30.119f, 32.039f, + 34.373f, 35.903f, 35.839f, 34.203f, 33.751f, 33.061f, 32.456f, 32.271f, 32.748f, + 32.759f, 32.140f, 31.589f, 30.590f, 29.908f, 29.355f, 29.302f, 29.370f, 28.631f, + 31.136f, 30.816f, 32.512f, 34.167f, 37.119f, 34.901f, 33.039f, 30.714f, 30.876f, + 29.373f, 28.406f, 27.020f, 25.663f, 23.086f, 21.256f, 20.509f, 18.527f, 16.614f, + 14.188f, 12.736f, 11.980f, 10.873f, 9.127f, 7.864f, 7.181f, 6.150f, 4.160f, + 1.580f, -1.450f, -4.765f, -7.626f, -11.797f, -14.364f, -14.966f, -19.525f, -20.620f, + -19.364f, -17.872f, -15.890f, -12.894f, -9.424f, -7.728f, -6.113f, -2.680f, -0.794f, + -1.452f, 0.094f, 3.354f, 5.211f, 6.400f, 8.326f, 9.268f, 10.654f, 10.986f, + 10.981f, 11.465f, 12.137f, 14.245f, 16.810f, 18.545f, 19.548f, 20.291f, 21.972f, + 23.260f, 22.952f, 23.202f, 24.049f, 26.192f, 30.234f, 27.817f, 22.736f, 17.233f, + 14.199f, 21.025f, 25.067f, 28.379f, 36.194f, 42.536f, 44.511f, 44.537f, 43.787f, + 42.885f, 42.745f, 42.160f, 41.302f, 40.773f, 37.209f, 35.823f, 32.028f, 30.485f, + 28.659f, 25.978f, 24.584f, 22.128f, 20.053f, 17.998f, 18.779f, 19.478f, 19.376f, + 18.308f, 21.194f, 22.680f, 25.398f, 28.263f, 29.132f, 30.210f, 28.462f, 28.437f, + 29.084f, 29.237f, 29.419f, 29.850f, 29.511f, 28.740f, 29.137f, 29.215f, 29.462f, + 29.105f, 26.424f, 25.349f, 24.459f, 24.124f, 22.700f, 19.661f, 17.343f, 15.193f, + 13.606f}, + {-29.534f, -27.887f, -23.497f, -19.746f, -16.059f, -13.619f, -11.433f, -8.672f, -4.791f, + -1.201f, 1.482f, 4.023f, 7.133f, 10.776f, 13.642f, 16.407f, 18.170f, 19.376f, + 19.419f, 20.288f, 18.798f, 16.026f, 15.033f, 15.451f, 17.588f, 19.025f, 20.643f, + 22.436f, 24.066f, 24.973f, 26.099f, 26.436f, 27.634f, 28.887f, 30.637f, 32.720f, + 35.168f, 36.476f, 36.415f, 34.654f, 34.147f, 33.315f, 32.419f, 32.575f, 33.032f, + 33.238f, 32.651f, 32.583f, 31.397f, 30.222f, 29.838f, 29.838f, 29.088f, 29.374f, + 30.313f, 29.993f, 31.749f, 32.252f, 35.859f, 35.396f, 32.954f, 32.178f, 31.122f, + 28.433f, 26.670f, 25.547f, 24.040f, 21.820f, 19.297f, 17.666f, 16.393f, 13.942f, + 12.351f, 11.133f, 10.099f, 8.759f, 6.025f, 5.136f, 5.085f, 4.070f, 1.916f, + -0.484f, -3.429f, -6.780f, -9.741f, -13.555f, -15.184f, -18.309f, -20.584f, -21.231f, + -19.952f, -19.080f, -17.552f, -13.627f, -9.624f, -7.288f, -5.858f, -3.475f, -2.324f, + -1.289f, -0.453f, 2.838f, 4.950f, 7.183f, 9.591f, 10.720f, 11.496f, 11.883f, + 10.974f, 11.221f, 11.896f, 13.392f, 14.688f, 16.084f, 17.340f, 18.853f, 21.164f, + 21.819f, 21.544f, 22.143f, 22.826f, 24.197f, 27.446f, 28.706f, 18.511f, 11.647f, + 11.431f, 25.490f, 29.204f, 33.303f, 39.531f, 43.995f, 44.481f, 43.828f, 43.254f, + 43.254f, 42.269f, 41.583f, 39.929f, 38.812f, 35.166f, 34.133f, 30.466f, 29.055f, + 28.280f, 25.430f, 24.335f, 21.951f, 19.912f, 18.877f, 19.383f, 18.744f, 18.814f, + 17.958f, 19.017f, 20.332f, 23.352f, 26.427f, 28.319f, 28.939f, 27.925f, 27.731f, + 27.179f, 27.709f, 27.760f, 28.802f, 28.607f, 28.277f, 28.892f, 28.367f, 29.120f, + 28.674f, 26.224f, 25.069f, 24.310f, 24.061f, 22.610f, 19.644f, 17.322f, 15.176f, + 13.606f}, + {-29.534f, -27.896f, -23.420f, -19.690f, -15.991f, -13.458f, -10.839f, -7.599f, -3.996f, + -0.705f, 1.870f, 4.430f, 7.622f, 11.158f, 14.023f, 16.472f, 18.030f, 18.860f, + 19.954f, 21.793f, 20.328f, 16.184f, 15.322f, 15.335f, 17.419f, 19.270f, 20.779f, + 22.449f, 24.428f, 25.177f, 26.289f, 27.034f, 27.200f, 29.060f, 31.176f, 33.130f, + 35.879f, 37.078f, 36.469f, 35.329f, 34.591f, 33.523f, 32.871f, 32.534f, 33.073f, + 33.449f, 32.928f, 33.265f, 32.494f, 31.204f, 30.241f, 29.688f, 28.643f, 28.865f, + 27.502f, 29.129f, 30.525f, 31.107f, 34.524f, 34.612f, 32.924f, 32.113f, 32.884f, + 28.662f, 26.678f, 24.401f, 22.929f, 20.929f, 19.257f, 17.636f, 15.281f, 12.899f, + 11.103f, 9.988f, 8.338f, 6.925f, 5.428f, 3.513f, 2.751f, 1.311f, -1.592f, + -3.139f, -5.479f, -9.444f, -12.677f, -15.005f, -16.878f, -19.555f, -20.833f, -21.359f, + -20.823f, -18.733f, -15.890f, -12.937f, -10.578f, -8.736f, -7.062f, -4.985f, -3.136f, + -0.711f, -0.009f, 2.220f, 4.540f, 7.214f, 9.143f, 10.621f, 12.146f, 12.948f, + 11.688f, 11.655f, 12.433f, 12.730f, 13.343f, 14.242f, 15.334f, 17.256f, 19.169f, + 20.116f, 21.178f, 22.784f, 22.319f, 22.740f, 24.742f, 22.974f, 13.159f, 9.244f, + 18.650f, 31.255f, 35.799f, 38.473f, 40.470f, 42.733f, 44.752f, 43.810f, 40.494f, + 41.763f, 42.273f, 41.317f, 38.639f, 36.707f, 32.941f, 31.339f, 29.090f, 28.342f, + 27.518f, 24.964f, 23.441f, 21.279f, 19.576f, 20.005f, 19.513f, 18.869f, 18.589f, + 17.872f, 17.835f, 18.747f, 21.557f, 24.381f, 27.109f, 27.757f, 26.790f, 26.739f, + 25.502f, 25.747f, 26.211f, 27.858f, 27.800f, 27.722f, 28.234f, 27.549f, 28.662f, + 28.307f, 25.942f, 24.823f, 24.147f, 24.014f, 22.512f, 19.633f, 17.299f, 15.158f, + 13.606f}, + {-29.534f, -27.906f, -23.341f, -19.616f, -15.881f, -13.186f, -10.107f, -6.489f, -3.093f, + -0.140f, 2.314f, 4.903f, 8.251f, 11.696f, 14.601f, 16.579f, 18.223f, 20.262f, + 21.149f, 22.179f, 21.156f, 16.557f, 15.614f, 15.593f, 17.354f, 19.420f, 21.126f, + 22.571f, 24.233f, 26.056f, 26.273f, 27.719f, 28.079f, 29.140f, 31.160f, 33.292f, + 36.201f, 37.750f, 36.552f, 35.593f, 35.068f, 34.374f, 33.208f, 32.565f, 32.848f, + 33.327f, 33.375f, 33.432f, 34.127f, 32.608f, 31.928f, 30.254f, 29.254f, 28.273f, + 27.679f, 28.566f, 29.572f, 28.943f, 34.105f, 34.527f, 32.527f, 30.796f, 31.022f, + 28.443f, 25.617f, 24.309f, 22.194f, 19.435f, 17.732f, 16.229f, 13.829f, 12.140f, + 9.965f, 8.741f, 7.307f, 5.328f, 3.908f, 2.150f, 1.026f, -1.122f, -4.390f, + -5.625f, -6.965f, -10.433f, -14.581f, -15.899f, -17.661f, -18.931f, -20.582f, -21.303f, + -20.906f, -18.880f, -15.666f, -12.359f, -10.656f, -8.876f, -7.504f, -6.115f, -4.669f, + -1.813f, -0.226f, 1.500f, 3.913f, 7.607f, 8.626f, 9.609f, 11.097f, 12.399f, + 12.617f, 12.698f, 13.283f, 13.216f, 13.357f, 13.686f, 14.486f, 15.552f, 16.913f, + 18.028f, 19.708f, 21.249f, 22.278f, 21.741f, 21.601f, 14.446f, 9.019f, 16.803f, + 27.551f, 35.626f, 39.142f, 39.545f, 40.758f, 42.225f, 43.346f, 42.330f, 39.958f, + 38.406f, 41.328f, 39.103f, 38.413f, 33.114f, 31.034f, 29.524f, 28.027f, 27.903f, + 26.798f, 24.514f, 22.697f, 20.439f, 19.280f, 19.810f, 19.017f, 19.044f, 18.311f, + 18.137f, 17.417f, 17.957f, 20.311f, 22.889f, 25.180f, 26.797f, 25.140f, 25.454f, + 24.385f, 24.068f, 24.864f, 26.858f, 26.994f, 27.029f, 27.053f, 26.650f, 28.038f, + 28.028f, 25.508f, 24.594f, 23.975f, 23.969f, 22.407f, 19.628f, 17.275f, 15.140f, + 13.606f}, + {-29.534f, -27.916f, -23.261f, -19.522f, -15.728f, -12.823f, -9.311f, -5.442f, -2.135f, + 0.489f, 2.769f, 5.311f, 8.736f, 12.255f, 15.064f, 16.735f, 18.428f, 22.714f, + 23.043f, 22.456f, 21.201f, 17.175f, 16.108f, 16.043f, 17.720f, 19.423f, 21.232f, + 22.521f, 24.222f, 26.095f, 27.169f, 27.659f, 28.309f, 29.469f, 30.751f, 33.734f, + 35.811f, 37.852f, 37.140f, 35.937f, 35.116f, 34.166f, 33.218f, 33.014f, 32.906f, + 33.301f, 33.634f, 33.717f, 35.063f, 34.837f, 34.104f, 32.397f, 30.717f, 29.730f, + 27.782f, 26.017f, 27.859f, 27.626f, 33.892f, 33.867f, 32.289f, 31.145f, 29.856f, + 28.733f, 26.239f, 23.783f, 20.625f, 18.333f, 16.316f, 14.651f, 12.508f, 11.189f, + 9.140f, 7.106f, 6.684f, 4.455f, 2.717f, 1.177f, -0.303f, -0.690f, -5.234f, + -7.556f, -7.818f, -11.187f, -14.893f, -16.502f, -18.094f, -19.400f, -20.283f, -19.783f, + -19.028f, -17.853f, -14.730f, -11.730f, -10.546f, -9.884f, -9.317f, -8.577f, -5.203f, + -3.052f, -1.302f, 0.161f, 2.957f, 5.523f, 7.084f, 8.815f, 9.907f, 11.193f, + 12.194f, 12.449f, 13.656f, 14.913f, 14.794f, 14.487f, 14.763f, 14.870f, 15.404f, + 15.743f, 17.209f, 19.677f, 21.221f, 21.498f, 18.231f, 9.542f, 9.130f, 19.955f, + 30.870f, 37.645f, 38.886f, 39.648f, 40.268f, 40.967f, 41.084f, 41.153f, 38.556f, + 36.509f, 39.493f, 39.401f, 35.937f, 32.465f, 31.923f, 29.809f, 27.672f, 26.803f, + 26.051f, 24.171f, 21.834f, 20.706f, 19.368f, 18.921f, 17.680f, 18.266f, 18.450f, + 18.282f, 17.783f, 17.704f, 19.611f, 21.791f, 23.652f, 25.774f, 24.482f, 24.184f, + 23.380f, 22.890f, 23.754f, 25.647f, 26.068f, 26.207f, 25.669f, 25.749f, 27.288f, + 27.814f, 24.916f, 24.357f, 23.797f, 23.911f, 22.298f, 19.628f, 17.250f, 15.121f, + 13.606f}, + {-29.534f, -27.926f, -23.182f, -19.407f, -15.535f, -12.400f, -8.532f, -4.521f, -1.195f, + 1.147f, 3.181f, 5.554f, 8.879f, 12.601f, 15.201f, 16.882f, 18.527f, 23.159f, + 22.930f, 22.022f, 21.169f, 17.725f, 16.344f, 16.580f, 18.034f, 19.782f, 21.399f, + 22.840f, 24.507f, 26.201f, 27.746f, 28.079f, 28.904f, 29.556f, 31.618f, 32.843f, + 36.510f, 37.953f, 36.986f, 37.058f, 35.666f, 34.917f, 33.871f, 33.244f, 33.018f, + 33.258f, 33.626f, 34.059f, 35.263f, 35.528f, 35.035f, 33.502f, 31.445f, 30.270f, + 27.968f, 27.418f, 27.202f, 28.673f, 33.448f, 34.987f, 34.296f, 31.267f, 30.281f, + 28.819f, 26.242f, 22.380f, 18.644f, 17.472f, 15.550f, 14.109f, 11.134f, 9.582f, + 7.587f, 7.024f, 4.659f, 2.882f, 1.103f, 0.167f, -1.707f, -2.549f, -4.977f, + -9.657f, -12.094f, -13.183f, -15.095f, -16.427f, -17.525f, -18.054f, -18.837f, -18.437f, + -17.391f, -16.123f, -13.774f, -11.500f, -10.624f, -11.120f, -11.345f, -8.675f, -6.108f, + -3.976f, -2.305f, -0.924f, 1.255f, 3.654f, 5.393f, 7.304f, 8.755f, 10.156f, + 11.361f, 12.362f, 13.576f, 15.147f, 15.399f, 14.914f, 14.414f, 13.629f, 13.805f, + 14.514f, 15.352f, 17.707f, 20.579f, 20.898f, 13.858f, 7.480f, 5.654f, 16.864f, + 29.289f, 37.017f, 38.538f, 39.785f, 39.887f, 40.649f, 39.782f, 39.567f, 36.894f, + 34.317f, 37.340f, 36.162f, 33.961f, 33.543f, 32.377f, 29.968f, 27.334f, 25.826f, + 25.177f, 23.413f, 21.484f, 21.033f, 19.674f, 18.067f, 16.416f, 16.530f, 18.547f, + 18.202f, 17.929f, 17.735f, 18.865f, 20.431f, 22.584f, 24.876f, 24.746f, 23.079f, + 22.188f, 21.948f, 22.882f, 24.296f, 25.076f, 25.285f, 24.466f, 24.979f, 26.508f, + 27.589f, 24.233f, 24.092f, 23.615f, 23.822f, 22.183f, 19.629f, 17.224f, 15.103f, + 13.606f}, + {-29.534f, -27.938f, -23.103f, -19.272f, -15.312f, -11.958f, -7.839f, -3.755f, -0.360f, + 1.775f, 3.518f, 5.641f, 8.784f, 12.710f, 15.184f, 16.983f, 18.810f, 21.506f, + 20.989f, 20.584f, 20.999f, 18.122f, 16.417f, 17.239f, 18.210f, 19.866f, 21.644f, + 23.278f, 24.795f, 27.067f, 28.268f, 29.008f, 28.988f, 29.928f, 31.466f, 32.873f, + 34.366f, 37.307f, 38.243f, 37.291f, 36.728f, 35.451f, 34.242f, 33.561f, 33.457f, + 33.211f, 33.229f, 33.478f, 34.801f, 35.385f, 34.514f, 33.136f, 31.353f, 29.792f, + 28.004f, 27.510f, 29.114f, 29.470f, 33.060f, 35.622f, 33.209f, 31.242f, 30.441f, + 28.941f, 25.873f, 21.264f, 16.690f, 15.893f, 14.360f, 13.348f, 10.621f, 7.747f, + 4.059f, 6.725f, 3.043f, 1.515f, -0.081f, -2.330f, -2.670f, -4.212f, -7.489f, + -8.873f, -13.589f, -15.855f, -15.602f, -16.321f, -16.492f, -16.417f, -17.178f, -16.259f, + -15.482f, -14.365f, -13.083f, -11.617f, -11.045f, -11.623f, -10.600f, -8.248f, -6.620f, + -5.493f, -3.270f, -2.499f, -0.043f, 2.469f, 3.808f, 6.605f, 8.437f, 9.749f, + 10.616f, 12.525f, 13.519f, 13.799f, 13.787f, 13.969f, 13.690f, 12.950f, 12.938f, + 14.474f, 15.000f, 15.835f, 18.165f, 19.342f, 11.348f, 6.977f, 1.286f, 9.732f, + 24.622f, 34.466f, 38.207f, 40.044f, 39.971f, 39.347f, 39.535f, 37.944f, 36.039f, + 32.271f, 32.466f, 33.107f, 33.795f, 33.731f, 31.988f, 29.884f, 26.140f, 23.990f, + 24.012f, 22.101f, 21.045f, 19.963f, 19.246f, 17.422f, 15.598f, 15.477f, 18.502f, + 18.171f, 17.715f, 17.541f, 18.272f, 19.308f, 21.524f, 23.858f, 24.197f, 22.156f, + 21.102f, 21.056f, 22.161f, 23.060f, 24.124f, 24.263f, 23.520f, 24.345f, 25.790f, + 27.267f, 23.562f, 23.787f, 23.429f, 23.687f, 22.063f, 19.632f, 17.196f, 15.084f, + 13.606f}, + {-29.534f, -27.949f, -23.028f, -19.121f, -15.070f, -11.533f, -7.275f, -3.142f, 0.294f, + 2.298f, 3.762f, 5.662f, 8.732f, 12.756f, 15.259f, 16.989f, 19.167f, 20.510f, + 20.423f, 19.645f, 20.472f, 18.480f, 16.964f, 17.791f, 18.666f, 20.276f, 21.991f, + 23.522f, 25.386f, 27.601f, 28.627f, 29.495f, 30.188f, 30.813f, 31.976f, 33.563f, + 35.466f, 35.558f, 36.682f, 37.508f, 37.135f, 36.809f, 35.280f, 34.144f, 33.321f, + 33.257f, 33.319f, 33.704f, 34.478f, 34.636f, 34.116f, 32.397f, 31.284f, 29.443f, + 28.143f, 27.013f, 27.752f, 29.566f, 31.017f, 35.513f, 36.054f, 34.344f, 32.366f, + 29.259f, 25.634f, 21.118f, 18.589f, 15.084f, 12.553f, 12.236f, 10.384f, 5.764f, + 3.254f, -0.041f, 1.663f, -0.146f, -2.396f, -4.645f, -5.347f, -5.577f, -6.384f, + -8.392f, -11.365f, -15.325f, -15.123f, -15.092f, -14.994f, -13.950f, -13.702f, -11.885f, + -11.529f, -12.869f, -12.702f, -11.562f, -11.173f, -10.885f, -9.767f, -8.451f, -7.307f, + -5.958f, -4.551f, -3.146f, -0.038f, 1.947f, 3.956f, 5.522f, 7.436f, 8.500f, + 9.032f, 10.535f, 11.873f, 12.526f, 13.033f, 13.221f, 13.379f, 13.166f, 12.697f, + 14.148f, 14.514f, 15.292f, 16.834f, 16.598f, 10.659f, 6.757f, 1.395f, 5.655f, + 16.483f, 30.479f, 36.429f, 39.284f, 38.778f, 38.116f, 38.473f, 35.717f, 34.973f, + 32.970f, 31.186f, 32.543f, 32.628f, 32.703f, 31.206f, 27.660f, 23.557f, 22.102f, + 22.557f, 21.479f, 19.944f, 18.801f, 17.963f, 16.702f, 15.289f, 15.465f, 18.459f, + 18.188f, 17.720f, 17.417f, 18.128f, 18.370f, 20.550f, 22.339f, 22.661f, 21.328f, + 20.158f, 20.065f, 21.326f, 22.093f, 23.166f, 23.159f, 22.636f, 23.723f, 25.182f, + 26.800f, 22.999f, 23.439f, 23.237f, 23.496f, 21.935f, 19.634f, 17.168f, 15.065f, + 13.606f}, + {-29.534f, -27.961f, -22.956f, -18.956f, -14.821f, -11.152f, -6.854f, -2.664f, 0.725f, + 2.638f, 3.891f, 5.683f, 8.864f, 12.793f, 15.253f, 16.825f, 18.966f, 20.803f, + 21.445f, 19.979f, 20.365f, 19.236f, 17.333f, 18.271f, 19.375f, 20.764f, 22.492f, + 23.920f, 25.774f, 27.776f, 28.984f, 29.814f, 30.773f, 31.589f, 32.798f, 34.030f, + 36.004f, 37.317f, 36.174f, 35.986f, 38.018f, 38.196f, 37.196f, 35.409f, 34.328f, + 33.372f, 33.204f, 33.549f, 33.603f, 33.264f, 33.317f, 32.678f, 31.019f, 29.619f, + 28.161f, 26.334f, 26.137f, 28.603f, 30.733f, 32.035f, 34.574f, 35.394f, 31.757f, + 29.125f, 26.711f, 19.442f, 18.437f, 14.780f, 10.968f, 10.291f, 9.964f, 5.686f, + 2.002f, -0.522f, -2.655f, -3.096f, -4.585f, -4.673f, -7.226f, -9.234f, -9.328f, + -12.226f, -11.672f, -10.940f, -12.566f, -13.284f, -12.341f, -9.406f, -6.610f, -7.340f, + -6.690f, -11.415f, -11.423f, -10.876f, -10.877f, -10.812f, -10.341f, -9.501f, -8.511f, + -7.478f, -5.989f, -2.586f, -0.172f, 1.989f, 3.322f, 4.712f, 6.216f, 7.703f, + 8.344f, 9.142f, 10.783f, 11.327f, 11.988f, 12.708f, 13.082f, 13.127f, 12.463f, + 13.626f, 15.046f, 16.219f, 16.653f, 14.804f, 12.453f, 8.888f, 5.161f, 5.671f, + 12.443f, 27.555f, 35.551f, 40.028f, 38.296f, 37.431f, 33.713f, 30.903f, 33.248f, + 32.149f, 30.877f, 30.868f, 31.076f, 30.726f, 29.283f, 25.338f, 21.069f, 20.400f, + 20.691f, 20.446f, 19.291f, 18.589f, 16.656f, 15.875f, 15.408f, 15.954f, 18.097f, + 17.648f, 17.735f, 18.036f, 18.038f, 17.625f, 19.620f, 21.021f, 21.217f, 20.225f, + 19.223f, 18.931f, 20.259f, 21.322f, 22.082f, 22.047f, 21.664f, 23.020f, 24.685f, + 26.210f, 22.593f, 23.058f, 23.034f, 23.247f, 21.798f, 19.634f, 17.137f, 15.045f, + 13.606f}, + {-29.534f, -27.974f, -22.890f, -18.785f, -14.578f, -10.827f, -6.558f, -2.305f, 0.938f, + 2.740f, 3.869f, 5.694f, 9.044f, 12.622f, 14.723f, 16.467f, 18.208f, 20.753f, + 21.808f, 20.839f, 20.784f, 20.986f, 17.658f, 18.415f, 19.949f, 21.132f, 22.732f, + 24.372f, 26.137f, 27.775f, 28.907f, 30.247f, 31.697f, 32.448f, 33.640f, 34.610f, + 35.569f, 37.032f, 39.020f, 38.414f, 37.602f, 38.913f, 39.401f, 37.492f, 35.496f, + 34.290f, 33.655f, 32.996f, 32.863f, 33.250f, 32.979f, 31.983f, 31.399f, 29.282f, + 27.799f, 26.327f, 25.710f, 25.333f, 27.185f, 30.251f, 30.214f, 28.887f, 28.155f, + 28.342f, 26.103f, 20.967f, 15.193f, 14.073f, 10.393f, 7.793f, 7.253f, 5.958f, + 3.090f, 1.048f, -5.203f, -7.980f, -7.079f, -6.085f, -8.684f, -10.049f, -12.651f, + -13.808f, -11.391f, -11.023f, -13.173f, -14.782f, -11.881f, -8.983f, -8.357f, -8.251f, + -9.817f, -12.472f, -10.932f, -11.434f, -11.722f, -11.460f, -11.451f, -10.559f, -9.863f, + -8.283f, -5.324f, -2.019f, -0.617f, 0.954f, 2.179f, 3.651f, 5.088f, 6.592f, + 7.460f, 7.925f, 9.543f, 10.155f, 10.947f, 11.228f, 12.255f, 12.857f, 13.077f, + 13.325f, 14.561f, 15.773f, 16.214f, 15.258f, 16.110f, 11.527f, 7.537f, 6.814f, + 15.178f, 29.386f, 36.680f, 39.885f, 38.505f, 36.454f, 30.448f, 29.434f, 32.364f, + 30.976f, 29.128f, 28.662f, 29.717f, 28.436f, 27.298f, 24.603f, 21.752f, 19.331f, + 19.581f, 19.388f, 18.506f, 17.644f, 15.546f, 15.179f, 15.988f, 16.453f, 17.598f, + 17.140f, 17.631f, 17.970f, 17.548f, 17.566f, 18.711f, 20.313f, 19.931f, 18.703f, + 18.483f, 17.921f, 19.281f, 20.608f, 20.910f, 21.007f, 20.679f, 22.283f, 24.270f, + 25.578f, 22.328f, 22.666f, 22.817f, 22.948f, 21.652f, 19.631f, 17.105f, 15.026f, + 13.606f}, + {-29.534f, -27.987f, -22.830f, -18.615f, -14.353f, -10.557f, -6.357f, -2.052f, 0.979f, + 2.602f, 3.667f, 5.633f, 9.040f, 12.119f, 13.627f, 15.963f, 17.762f, 20.302f, + 21.564f, 21.542f, 20.688f, 22.637f, 19.213f, 18.117f, 19.256f, 21.245f, 22.813f, + 24.642f, 26.458f, 28.060f, 29.009f, 30.428f, 32.286f, 33.468f, 34.548f, 35.412f, + 36.125f, 37.019f, 38.750f, 39.577f, 40.460f, 39.546f, 40.035f, 40.313f, 37.691f, + 35.281f, 34.236f, 33.291f, 33.114f, 33.167f, 32.943f, 31.795f, 31.038f, 29.889f, + 28.067f, 27.055f, 25.914f, 24.551f, 24.263f, 25.052f, 28.194f, 26.734f, 25.688f, + 24.140f, 20.004f, 15.112f, 11.071f, 11.525f, 10.160f, 4.655f, 4.730f, 5.589f, + 4.034f, 0.528f, -9.399f, -9.057f, -11.342f, -10.171f, -10.246f, -11.045f, -11.682f, + -13.169f, -14.031f, -12.946f, -13.498f, -14.663f, -14.623f, -12.763f, -12.163f, -12.372f, + -11.860f, -13.023f, -12.620f, -12.937f, -12.507f, -12.287f, -11.882f, -11.292f, -10.109f, + -7.715f, -5.758f, -3.350f, -1.318f, -0.539f, 1.076f, 2.900f, 4.607f, 5.453f, + 6.456f, 7.636f, 8.622f, 9.392f, 9.938f, 10.070f, 11.684f, 12.576f, 12.683f, + 12.814f, 13.856f, 15.124f, 15.500f, 15.533f, 18.877f, 14.373f, 9.980f, 6.975f, + 14.589f, 28.515f, 37.041f, 38.985f, 38.510f, 35.772f, 28.393f, 28.491f, 29.301f, + 29.374f, 26.920f, 27.505f, 28.115f, 25.988f, 24.798f, 24.750f, 23.322f, 18.844f, + 18.303f, 18.547f, 17.406f, 16.319f, 15.324f, 14.825f, 15.931f, 16.462f, 17.312f, + 16.460f, 16.743f, 16.842f, 17.264f, 17.381f, 18.130f, 19.436f, 18.624f, 17.337f, + 17.852f, 17.225f, 18.675f, 19.889f, 19.845f, 20.038f, 19.852f, 21.624f, 23.889f, + 24.998f, 22.138f, 22.289f, 22.586f, 22.614f, 21.497f, 19.623f, 17.071f, 15.006f, + 13.606f}, + {-29.534f, -28.001f, -22.779f, -18.453f, -14.153f, -10.330f, -6.216f, -1.902f, 0.910f, + 2.289f, 3.304f, 5.464f, 8.796f, 11.531f, 12.582f, 15.426f, 18.006f, 20.663f, + 21.889f, 21.635f, 20.390f, 22.862f, 21.672f, 19.553f, 19.298f, 20.047f, 22.604f, + 24.483f, 26.472f, 28.386f, 29.427f, 30.954f, 32.603f, 34.001f, 35.470f, 36.379f, + 36.937f, 37.740f, 38.452f, 39.735f, 40.121f, 42.287f, 41.385f, 40.972f, 39.963f, + 37.990f, 35.138f, 33.900f, 33.436f, 33.210f, 34.210f, 32.260f, 31.245f, 30.229f, + 29.520f, 28.297f, 26.938f, 24.928f, 23.110f, 22.302f, 23.908f, 24.618f, 23.923f, + 22.382f, 19.006f, 15.017f, 12.455f, 9.544f, 7.559f, 4.251f, 0.996f, 1.758f, + 1.971f, -3.298f, -8.223f, -9.677f, -11.470f, -14.336f, -13.239f, -12.221f, -11.387f, + -11.259f, -13.854f, -14.459f, -15.470f, -16.077f, -16.724f, -16.437f, -16.292f, -14.464f, + -12.084f, -13.583f, -14.285f, -14.064f, -13.161f, -13.121f, -12.676f, -11.660f, -10.516f, + -9.198f, -6.735f, -4.579f, -2.907f, -1.533f, -0.176f, 1.800f, 3.059f, 4.283f, + 5.635f, 7.188f, 8.645f, 9.505f, 9.243f, 9.700f, 11.500f, 12.528f, 12.594f, + 12.975f, 14.083f, 16.041f, 16.305f, 16.326f, 17.496f, 15.483f, 12.808f, 17.308f, + 20.881f, 33.139f, 36.927f, 37.378f, 37.691f, 36.097f, 27.341f, 25.597f, 24.510f, + 27.059f, 24.625f, 25.371f, 25.093f, 23.263f, 23.131f, 22.831f, 21.188f, 17.991f, + 17.088f, 17.466f, 17.359f, 16.038f, 15.533f, 15.194f, 15.795f, 15.672f, 16.828f, + 15.455f, 16.032f, 16.576f, 17.422f, 16.817f, 18.074f, 18.287f, 17.561f, 16.605f, + 16.974f, 16.696f, 18.151f, 19.144f, 19.013f, 19.095f, 19.220f, 21.063f, 23.487f, + 24.520f, 21.942f, 21.950f, 22.345f, 22.264f, 21.338f, 19.610f, 17.035f, 14.987f, + 13.606f}, + {-29.534f, -28.015f, -22.736f, -18.308f, -13.983f, -10.130f, -6.109f, -1.849f, 0.784f, + 1.916f, 2.870f, 5.218f, 8.471f, 11.252f, 12.264f, 15.101f, 18.355f, 21.524f, + 22.462f, 21.064f, 21.026f, 23.108f, 23.292f, 22.119f, 21.867f, 20.540f, 22.804f, + 24.767f, 26.622f, 28.761f, 30.237f, 31.700f, 33.080f, 34.192f, 36.120f, 37.358f, + 38.088f, 38.722f, 39.014f, 39.442f, 40.163f, 41.602f, 43.548f, 43.267f, 41.743f, + 39.174f, 37.844f, 35.388f, 33.799f, 32.710f, 33.728f, 32.260f, 31.410f, 30.604f, + 30.034f, 29.659f, 29.109f, 25.612f, 23.124f, 22.265f, 21.191f, 19.295f, 18.744f, + 18.097f, 15.585f, 11.892f, 9.064f, 5.901f, 3.615f, 3.179f, 1.165f, -1.619f, + -3.881f, -8.901f, -10.352f, -10.872f, -11.560f, -12.395f, -13.288f, -14.001f, -11.897f, + -12.184f, -15.458f, -15.702f, -18.367f, -19.163f, -19.256f, -18.277f, -17.536f, -16.564f, + -14.069f, -13.704f, -14.430f, -13.163f, -11.621f, -12.521f, -13.194f, -12.908f, -11.676f, + -10.065f, -7.791f, -5.126f, -3.892f, -2.426f, -1.050f, 0.291f, 2.337f, 3.523f, + 5.339f, 6.409f, 8.002f, 9.187f, 9.205f, 9.495f, 10.353f, 11.712f, 13.301f, + 14.219f, 13.473f, 13.579f, 16.883f, 17.302f, 16.770f, 15.698f, 14.292f, 27.906f, + 26.707f, 32.900f, 35.977f, 36.522f, 36.716f, 35.371f, 27.678f, 22.512f, 21.533f, + 25.829f, 23.296f, 23.718f, 23.794f, 22.832f, 21.303f, 20.435f, 19.671f, 17.348f, + 16.634f, 16.804f, 17.422f, 16.648f, 15.349f, 16.471f, 15.834f, 15.072f, 15.970f, + 15.009f, 16.029f, 17.028f, 17.535f, 16.827f, 18.217f, 17.488f, 16.603f, 16.215f, + 16.058f, 16.207f, 17.301f, 18.348f, 18.338f, 18.197f, 18.663f, 20.490f, 23.014f, + 24.121f, 21.677f, 21.659f, 22.099f, 21.918f, 21.176f, 19.590f, 16.997f, 14.967f, + 13.606f}, + {-29.534f, -28.029f, -22.703f, -18.185f, -13.847f, -9.944f, -6.029f, -1.889f, 0.622f, + 1.602f, 2.499f, 4.975f, 8.253f, 11.347f, 12.672f, 15.260f, 18.391f, 21.790f, + 23.161f, 20.783f, 21.722f, 24.116f, 23.286f, 22.228f, 22.993f, 22.804f, 23.695f, + 25.782f, 27.260f, 29.226f, 30.959f, 32.493f, 33.718f, 34.913f, 36.743f, 38.185f, + 39.207f, 39.741f, 39.735f, 39.921f, 40.615f, 42.232f, 43.643f, 44.702f, 44.549f, + 42.333f, 39.551f, 37.417f, 35.463f, 33.316f, 33.173f, 32.156f, 32.228f, 31.018f, + 30.456f, 29.746f, 29.401f, 27.337f, 24.162f, 22.378f, 21.063f, 18.321f, 17.558f, + 15.416f, 13.053f, 10.874f, 8.282f, 5.563f, 3.230f, 0.277f, -1.184f, -4.876f, + -7.920f, -10.708f, -11.831f, -10.077f, -10.743f, -15.370f, -16.181f, -14.547f, -16.749f, + -13.597f, -16.573f, -16.335f, -18.226f, -20.154f, -20.437f, -18.512f, -18.401f, -17.429f, + -16.410f, -15.725f, -15.754f, -13.252f, -11.177f, -12.835f, -13.375f, -12.488f, -11.531f, + -7.793f, -4.444f, -3.891f, -4.673f, -3.533f, -1.604f, 0.055f, 1.846f, 2.844f, + 4.312f, 5.411f, 6.952f, 8.507f, 10.308f, 10.923f, 11.289f, 13.007f, 13.941f, + 12.667f, 10.781f, 13.477f, 16.521f, 17.056f, 16.446f, 15.961f, 15.355f, 24.295f, + 24.730f, 32.362f, 35.371f, 36.234f, 34.646f, 33.528f, 29.121f, 20.609f, 20.391f, + 25.691f, 21.664f, 22.318f, 22.490f, 20.769f, 19.478f, 17.879f, 18.218f, 16.766f, + 16.112f, 16.249f, 16.830f, 16.091f, 15.472f, 17.211f, 16.123f, 15.153f, 14.830f, + 14.503f, 15.710f, 17.237f, 17.690f, 17.295f, 18.053f, 16.774f, 15.675f, 15.790f, + 15.456f, 15.730f, 16.271f, 17.501f, 17.656f, 17.413f, 18.068f, 19.790f, 22.451f, + 23.732f, 21.329f, 21.404f, 21.850f, 21.597f, 21.016f, 19.564f, 16.956f, 14.947f, + 13.606f}, + {-29.534f, -28.043f, -22.681f, -18.092f, -13.746f, -9.765f, -5.985f, -2.008f, 0.415f, + 1.425f, 2.302f, 4.813f, 8.194f, 11.489f, 13.177f, 15.800f, 18.297f, 21.572f, + 24.514f, 21.450f, 21.411f, 23.912f, 23.221f, 21.717f, 22.679f, 23.599f, 25.008f, + 26.671f, 28.067f, 29.875f, 31.634f, 32.898f, 34.231f, 35.658f, 37.457f, 39.003f, + 40.169f, 40.902f, 41.184f, 40.892f, 40.737f, 42.383f, 44.048f, 45.406f, 45.450f, + 43.888f, 41.659f, 39.526f, 36.999f, 34.632f, 33.085f, 32.178f, 31.103f, 29.807f, + 29.439f, 28.915f, 28.909f, 28.835f, 25.332f, 22.349f, 20.392f, 18.110f, 16.659f, + 14.273f, 12.009f, 10.714f, 8.808f, 5.544f, 1.769f, -1.764f, -4.036f, -6.365f, + -9.594f, -10.772f, -10.537f, -12.240f, -15.556f, -18.885f, -18.815f, -16.822f, -15.318f, + -13.424f, -14.931f, -18.736f, -20.346f, -18.771f, -19.232f, -17.751f, -16.910f, -15.285f, + -16.299f, -12.138f, -15.343f, -15.407f, -13.815f, -13.371f, -12.716f, -11.802f, -9.737f, + -4.041f, -3.994f, -4.914f, -5.454f, -4.005f, -1.779f, 0.014f, 0.960f, 2.606f, + 3.980f, 4.885f, 6.321f, 8.654f, 10.523f, 10.530f, 11.416f, 11.606f, 11.576f, + 12.159f, 13.322f, 14.796f, 17.320f, 17.542f, 20.302f, 20.325f, 17.920f, 19.447f, + 23.257f, 28.885f, 35.700f, 35.653f, 33.882f, 30.682f, 26.731f, 20.152f, 16.699f, + 21.651f, 19.705f, 21.078f, 21.264f, 18.545f, 15.996f, 16.039f, 16.079f, 15.905f, + 15.788f, 15.684f, 15.711f, 14.434f, 15.331f, 16.207f, 15.537f, 14.036f, 13.858f, + 13.708f, 15.205f, 17.406f, 17.259f, 17.671f, 17.548f, 15.743f, 14.992f, 15.254f, + 14.892f, 15.114f, 15.423f, 16.604f, 16.887f, 16.748f, 17.447f, 18.993f, 21.816f, + 23.282f, 20.924f, 21.159f, 21.602f, 21.310f, 20.863f, 19.529f, 16.913f, 14.927f, + 13.606f}, + {-29.534f, -28.058f, -22.670f, -18.031f, -13.679f, -9.596f, -5.997f, -2.195f, 0.148f, + 1.398f, 2.318f, 4.775f, 8.228f, 11.407f, 13.232f, 16.110f, 18.117f, 21.455f, + 25.728f, 22.263f, 20.929f, 22.397f, 24.382f, 22.630f, 23.363f, 24.145f, 26.054f, + 27.431f, 28.868f, 30.625f, 32.027f, 33.201f, 34.575f, 36.465f, 38.248f, 39.957f, + 41.298f, 42.273f, 42.524f, 42.095f, 41.815f, 42.613f, 43.471f, 44.921f, 45.874f, + 46.218f, 43.924f, 40.580f, 38.213f, 35.997f, 33.627f, 31.987f, 30.092f, 28.573f, + 27.146f, 26.522f, 26.461f, 25.918f, 24.203f, 21.635f, 19.567f, 17.595f, 15.215f, + 12.853f, 10.037f, 8.347f, 5.921f, 2.882f, -0.504f, -4.500f, -4.025f, -6.721f, + -10.140f, -11.451f, -10.280f, -13.711f, -17.063f, -17.190f, -18.878f, -18.165f, -18.540f, + -19.301f, -17.204f, -20.382f, -19.732f, -18.800f, -19.140f, -18.337f, -18.877f, -14.724f, + -14.050f, -15.821f, -16.531f, -16.509f, -16.085f, -14.984f, -13.229f, -10.916f, -7.740f, + -6.645f, -5.010f, -4.549f, -4.028f, -3.396f, -2.742f, -0.934f, 0.268f, 2.089f, + 3.506f, 5.429f, 7.074f, 7.837f, 8.445f, 7.943f, 8.790f, 9.821f, 11.368f, + 14.383f, 17.860f, 19.593f, 19.290f, 20.190f, 20.915f, 23.566f, 27.636f, 24.190f, + 25.229f, 29.579f, 35.006f, 35.648f, 32.134f, 28.318f, 24.576f, 19.461f, 17.437f, + 17.655f, 17.423f, 19.790f, 19.895f, 17.004f, 13.989f, 14.288f, 14.175f, 13.928f, + 14.684f, 15.231f, 15.383f, 13.293f, 14.440f, 15.253f, 13.752f, 12.637f, 13.963f, + 13.918f, 14.955f, 17.469f, 16.189f, 17.718f, 16.862f, 14.696f, 14.334f, 14.508f, + 14.083f, 14.322f, 14.709f, 15.621f, 16.049f, 16.098f, 16.874f, 18.255f, 21.146f, + 22.738f, 20.521f, 20.889f, 21.352f, 21.064f, 20.720f, 19.485f, 16.866f, 14.907f, + 13.606f}, + {-29.534f, -28.073f, -22.671f, -18.006f, -13.643f, -9.446f, -6.085f, -2.434f, -0.176f, + 1.480f, 2.512f, 4.863f, 8.291f, 11.179f, 12.853f, 15.685f, 17.796f, 21.503f, + 25.818f, 22.345f, 20.403f, 21.301f, 25.269f, 22.819f, 23.380f, 25.079f, 26.572f, + 28.134f, 29.565f, 31.072f, 32.438f, 33.595f, 35.346f, 37.262f, 38.978f, 41.127f, + 42.585f, 43.518f, 43.977f, 43.349f, 42.765f, 43.018f, 43.353f, 44.456f, 45.672f, + 46.454f, 45.429f, 42.885f, 39.905f, 36.911f, 34.441f, 32.245f, 30.254f, 28.399f, + 26.584f, 24.883f, 23.321f, 21.658f, 19.956f, 17.330f, 15.554f, 13.161f, 12.324f, + 11.395f, 9.985f, 6.681f, 4.479f, 1.428f, -1.510f, -5.450f, -9.344f, -7.249f, + -9.252f, -11.743f, -13.682f, -16.147f, -18.903f, -21.205f, -22.632f, -22.424f, -21.520f, + -21.351f, -21.973f, -21.859f, -18.554f, -17.816f, -17.978f, -16.080f, -15.433f, -15.681f, + -12.102f, -14.132f, -16.114f, -17.511f, -16.660f, -14.392f, -12.686f, -10.726f, -8.381f, + -7.091f, -6.420f, -3.451f, -2.352f, -3.119f, -4.783f, -2.816f, 0.481f, 0.727f, + 2.987f, 4.790f, 5.667f, 6.432f, 6.226f, 6.517f, 7.500f, 9.396f, 12.641f, + 15.406f, 16.536f, 16.975f, 16.960f, 17.657f, 19.778f, 23.767f, 25.538f, 25.788f, + 26.980f, 29.763f, 34.238f, 33.849f, 30.346f, 26.351f, 21.725f, 20.051f, 15.254f, + 16.098f, 14.532f, 17.790f, 17.974f, 15.402f, 12.378f, 12.876f, 13.000f, 12.385f, + 12.854f, 15.040f, 15.499f, 13.424f, 14.186f, 14.496f, 11.790f, 11.657f, 13.703f, + 13.837f, 14.804f, 16.686f, 15.355f, 16.833f, 15.930f, 13.761f, 13.591f, 13.446f, + 13.152f, 13.530f, 13.889f, 14.560f, 15.168f, 15.381f, 16.341f, 17.689f, 20.464f, + 22.115f, 20.179f, 20.569f, 21.097f, 20.852f, 20.588f, 19.430f, 16.816f, 14.887f, + 13.606f}, + {-29.534f, -28.088f, -22.684f, -18.017f, -13.636f, -9.331f, -6.259f, -2.720f, -0.517f, + 1.619f, 2.828f, 5.049f, 8.357f, 11.018f, 12.432f, 14.838f, 17.802f, 21.866f, + 25.525f, 21.993f, 19.439f, 20.912f, 25.116f, 22.876f, 23.309f, 25.577f, 27.265f, + 28.645f, 30.213f, 31.626f, 32.661f, 34.171f, 36.202f, 38.196f, 39.765f, 42.603f, + 43.950f, 45.148f, 45.093f, 44.393f, 43.229f, 42.213f, 42.709f, 46.260f, 45.670f, + 46.635f, 45.719f, 43.277f, 41.099f, 38.340f, 35.237f, 32.803f, 31.169f, 29.095f, + 26.998f, 25.099f, 22.913f, 20.449f, 18.039f, 15.876f, 13.917f, 11.721f, 9.849f, + 7.341f, 6.199f, 5.670f, 3.695f, 0.423f, -2.502f, -4.836f, -11.044f, -11.054f, + -10.677f, -12.871f, -15.499f, -17.881f, -20.051f, -21.816f, -24.062f, -24.569f, -23.453f, + -23.807f, -24.773f, -24.531f, -23.038f, -22.755f, -20.729f, -19.503f, -20.029f, -19.718f, + -19.258f, -19.298f, -19.739f, -19.611f, -16.406f, -14.688f, -13.129f, -11.399f, -8.533f, + -7.035f, -7.431f, -6.454f, -1.881f, -1.214f, -5.438f, -2.834f, 1.353f, 0.144f, + 0.495f, 1.809f, 2.647f, 4.088f, 4.951f, 5.555f, 7.658f, 10.236f, 12.170f, + 13.797f, 14.024f, 14.142f, 14.395f, 15.689f, 18.837f, 20.772f, 22.277f, 24.782f, + 25.755f, 27.104f, 30.609f, 30.616f, 29.007f, 24.856f, 20.114f, 17.979f, 12.709f, + 14.151f, 13.224f, 15.420f, 16.107f, 12.603f, 10.993f, 11.656f, 11.891f, 11.127f, + 11.363f, 13.983f, 14.267f, 13.315f, 13.733f, 13.774f, 11.391f, 12.143f, 13.187f, + 12.845f, 14.364f, 15.003f, 14.820f, 15.517f, 14.902f, 13.001f, 12.898f, 12.109f, + 12.082f, 12.691f, 13.008f, 13.525f, 14.236f, 14.641f, 15.745f, 17.239f, 19.762f, + 21.456f, 19.944f, 20.193f, 20.835f, 20.667f, 20.467f, 19.363f, 16.763f, 14.867f, + 13.606f}, + {-29.534f, -28.104f, -22.708f, -18.062f, -13.656f, -9.267f, -6.510f, -3.048f, -0.811f, + 1.780f, 3.234f, 5.304f, 8.422f, 10.947f, 12.298f, 14.460f, 18.539f, 22.721f, + 25.628f, 21.774f, 19.509f, 21.367f, 25.187f, 23.923f, 23.829f, 25.971f, 27.829f, + 29.277f, 31.001f, 32.284f, 33.323f, 34.760f, 36.763f, 38.689f, 40.631f, 43.515f, + 45.382f, 46.330f, 46.156f, 45.533f, 44.323f, 43.339f, 43.135f, 43.349f, 45.147f, + 46.411f, 45.694f, 43.685f, 41.734f, 39.479f, 36.592f, 34.153f, 32.279f, 30.051f, + 27.421f, 25.144f, 23.009f, 20.591f, 18.144f, 15.842f, 13.427f, 11.255f, 8.466f, + 6.099f, 5.413f, 4.325f, 2.964f, 0.689f, -2.316f, -6.218f, -9.384f, -12.082f, + -13.348f, -12.770f, -15.734f, -18.889f, -20.470f, -21.368f, -23.633f, -24.281f, -23.793f, + -25.244f, -26.750f, -26.759f, -28.048f, -26.906f, -24.208f, -24.984f, -24.951f, -24.078f, + -22.920f, -23.673f, -22.748f, -21.455f, -18.133f, -17.290f, -14.193f, -11.028f, -10.619f, + -8.136f, -8.274f, -6.547f, -3.246f, -1.819f, -1.557f, 1.058f, -0.581f, -1.139f, + -1.238f, 0.964f, 1.960f, 3.388f, 4.498f, 5.930f, 8.391f, 10.170f, 11.558f, + 12.219f, 11.957f, 11.590f, 11.824f, 14.214f, 17.641f, 19.007f, 19.504f, 22.167f, + 23.978f, 25.272f, 27.850f, 30.397f, 29.789f, 24.428f, 19.437f, 14.943f, 15.834f, + 12.611f, 12.159f, 13.552f, 14.155f, 10.270f, 10.943f, 11.073f, 10.693f, 9.959f, + 10.236f, 12.013f, 12.731f, 12.865f, 12.780f, 13.586f, 11.745f, 12.268f, 12.332f, + 12.532f, 13.946f, 13.497f, 14.646f, 14.880f, 13.927f, 12.549f, 11.909f, 10.737f, + 10.847f, 11.612f, 12.180f, 12.584f, 13.243f, 13.961f, 15.017f, 16.737f, 19.029f, + 20.803f, 19.837f, 19.785f, 20.563f, 20.494f, 20.356f, 19.284f, 16.707f, 14.848f, + 13.606f}, + {-29.534f, -28.119f, -22.744f, -18.137f, -13.699f, -9.263f, -6.812f, -3.418f, -1.005f, + 1.944f, 3.724f, 5.616f, 8.499f, 10.879f, 12.487f, 14.989f, 19.457f, 23.500f, + 25.618f, 21.625f, 20.876f, 22.729f, 25.362f, 24.860f, 24.232f, 26.407f, 28.325f, + 29.917f, 31.559f, 32.552f, 33.728f, 35.362f, 37.133f, 38.907f, 41.196f, 44.486f, + 46.516f, 47.267f, 47.044f, 46.068f, 44.974f, 44.024f, 43.733f, 44.768f, 45.564f, + 46.354f, 46.194f, 44.833f, 42.531f, 40.311f, 38.227f, 36.083f, 33.756f, 30.947f, + 28.037f, 25.600f, 23.215f, 21.016f, 18.549f, 16.077f, 13.593f, 10.999f, 8.564f, + 6.127f, 4.139f, 3.425f, 2.296f, -0.286f, -2.123f, -6.924f, -10.480f, -12.939f, + -14.381f, -14.881f, -15.452f, -20.155f, -22.058f, -21.590f, -23.436f, -24.017f, -26.714f, + -31.129f, -29.374f, -30.361f, -31.845f, -29.931f, -31.048f, -29.865f, -28.786f, -28.080f, + -26.981f, -26.236f, -24.565f, -23.769f, -22.428f, -20.885f, -18.227f, -14.108f, -12.381f, + -12.253f, -9.728f, -8.925f, -7.977f, -4.688f, -3.661f, -3.579f, -3.289f, -1.881f, + -1.096f, -0.255f, 1.925f, 4.492f, 5.790f, 6.769f, 7.916f, 9.510f, 11.251f, + 11.317f, 10.327f, 9.510f, 9.797f, 12.351f, 14.922f, 16.578f, 17.642f, 19.715f, + 22.302f, 22.996f, 25.829f, 29.310f, 29.469f, 24.190f, 18.764f, 17.115f, 20.900f, + 12.924f, 10.809f, 11.390f, 11.844f, 9.566f, 10.526f, 9.907f, 9.587f, 9.005f, + 9.265f, 11.094f, 11.565f, 12.105f, 11.935f, 13.042f, 11.428f, 11.482f, 11.463f, + 12.092f, 13.486f, 12.542f, 14.135f, 14.141f, 12.661f, 11.933f, 10.668f, 9.716f, + 9.785f, 10.462f, 11.285f, 11.666f, 12.222f, 13.316f, 14.226f, 16.084f, 18.290f, + 20.184f, 19.860f, 19.385f, 20.285f, 20.321f, 20.251f, 19.190f, 16.647f, 14.828f, + 13.606f}, + {-29.534f, -28.135f, -22.792f, -18.237f, -13.763f, -9.322f, -7.122f, -3.819f, -1.084f, + 2.092f, 4.266f, 5.989f, 8.640f, 10.861f, 12.794f, 15.873f, 19.765f, 23.512f, + 25.265f, 21.556f, 21.755f, 23.756f, 24.834f, 25.516f, 24.843f, 27.033f, 28.957f, + 30.354f, 31.962f, 32.968f, 34.191f, 35.807f, 37.461f, 39.066f, 41.412f, 44.614f, + 47.414f, 48.297f, 49.219f, 46.372f, 44.988f, 44.373f, 44.086f, 43.865f, 44.993f, + 45.954f, 45.620f, 45.415f, 43.619f, 41.663f, 39.577f, 37.498f, 34.821f, 31.342f, + 28.335f, 26.066f, 24.231f, 22.104f, 19.953f, 16.364f, 13.900f, 11.622f, 9.643f, + 7.011f, 4.521f, 3.119f, 1.585f, -0.144f, -2.885f, -6.321f, -9.610f, -12.141f, + -14.986f, -18.452f, -21.550f, -23.311f, -24.009f, -25.446f, -26.124f, -27.032f, -31.052f, + -33.349f, -33.689f, -34.031f, -34.491f, -34.426f, -32.783f, -31.462f, -30.646f, -31.366f, + -30.343f, -29.016f, -27.679f, -26.704f, -26.079f, -24.052f, -22.869f, -19.336f, -15.611f, + -12.328f, -12.455f, -10.783f, -9.002f, -8.007f, -6.290f, -5.935f, -4.078f, -2.966f, + -2.272f, -0.529f, 1.880f, 5.798f, 5.899f, 6.278f, 7.785f, 9.272f, 10.150f, + 9.645f, 8.390f, 7.513f, 7.119f, 8.806f, 11.351f, 12.856f, 14.439f, 16.922f, + 19.864f, 21.553f, 23.366f, 28.121f, 28.816f, 24.136f, 18.191f, 21.772f, 20.146f, + 12.761f, 9.115f, 9.024f, 9.246f, 8.577f, 9.525f, 8.804f, 8.175f, 8.298f, + 9.343f, 10.176f, 10.350f, 10.570f, 11.486f, 12.895f, 11.292f, 11.377f, 11.614f, + 11.629f, 12.712f, 12.019f, 12.902f, 12.850f, 11.325f, 11.024f, 9.925f, 9.131f, + 9.056f, 9.558f, 10.249f, 10.708f, 11.274f, 12.609f, 13.523f, 15.364f, 17.619f, + 19.621f, 19.992f, 19.031f, 20.005f, 20.139f, 20.147f, 19.082f, 16.585f, 14.808f, + 13.606f}, + {-29.534f, -28.150f, -22.849f, -18.356f, -13.844f, -9.435f, -7.396f, -4.233f, -1.088f, + 2.195f, 4.768f, 6.415f, 8.879f, 11.015f, 12.939f, 16.235f, 19.591f, 22.912f, + 24.804f, 22.013f, 22.876f, 24.295f, 24.474f, 26.007f, 25.408f, 27.589f, 29.257f, + 30.660f, 32.060f, 33.152f, 34.478f, 35.892f, 37.398f, 38.993f, 41.519f, 44.612f, + 47.087f, 47.881f, 48.713f, 46.593f, 44.978f, 44.576f, 43.702f, 43.021f, 46.470f, + 45.588f, 44.485f, 43.785f, 44.036f, 42.680f, 40.867f, 38.586f, 35.782f, 32.244f, + 29.686f, 27.101f, 25.055f, 23.266f, 21.124f, 17.652f, 14.720f, 11.911f, 9.927f, + 7.436f, 5.000f, 3.003f, 1.305f, -0.504f, -3.026f, -6.299f, -9.408f, -11.340f, + -14.012f, -16.639f, -19.694f, -21.241f, -23.057f, -27.099f, -26.724f, -26.803f, -29.794f, + -33.389f, -35.345f, -36.494f, -37.493f, -37.531f, -37.061f, -37.760f, -37.644f, -33.533f, + -32.985f, -31.161f, -29.548f, -29.229f, -29.885f, -29.165f, -26.443f, -23.311f, -18.715f, + -14.179f, -13.437f, -11.547f, -9.757f, -9.041f, -8.390f, -7.279f, -5.370f, -3.543f, + -2.002f, 0.775f, 3.462f, 3.880f, 4.151f, 4.580f, 6.216f, 7.760f, 7.898f, + 7.239f, 5.705f, 5.089f, 4.860f, 5.287f, 6.831f, 8.310f, 10.380f, 13.497f, + 16.489f, 18.907f, 23.479f, 26.890f, 27.274f, 24.623f, 20.179f, 23.316f, 18.426f, + 11.277f, 7.320f, 6.992f, 6.835f, 7.370f, 7.756f, 7.130f, 7.148f, 7.582f, + 8.039f, 8.568f, 9.100f, 9.204f, 10.942f, 12.697f, 11.232f, 11.146f, 11.129f, + 11.223f, 11.873f, 11.342f, 12.034f, 12.111f, 10.702f, 10.395f, 9.573f, 8.710f, + 8.446f, 8.827f, 9.279f, 9.819f, 10.518f, 11.833f, 12.990f, 14.761f, 17.085f, + 19.136f, 20.185f, 18.738f, 19.728f, 19.943f, 20.040f, 18.960f, 16.519f, 14.788f, + 13.606f}, + {-29.534f, -28.166f, -22.916f, -18.487f, -13.938f, -9.587f, -7.596f, -4.624f, -1.084f, + 2.226f, 5.101f, 6.838f, 9.141f, 11.223f, 12.796f, 15.917f, 19.555f, 22.187f, + 23.668f, 22.714f, 25.470f, 25.430f, 25.016f, 26.025f, 26.348f, 27.636f, 29.045f, + 30.669f, 32.034f, 33.133f, 34.522f, 35.937f, 37.361f, 39.153f, 41.301f, 44.481f, + 46.543f, 48.490f, 47.499f, 46.455f, 44.856f, 44.221f, 43.257f, 43.058f, 45.870f, + 45.261f, 44.434f, 43.487f, 43.285f, 42.670f, 42.023f, 39.765f, 37.201f, 34.085f, + 31.871f, 30.291f, 28.000f, 26.113f, 23.752f, 20.198f, 15.247f, 11.346f, 9.112f, + 6.817f, 4.435f, 1.986f, -0.081f, -1.423f, -1.672f, -4.853f, -7.836f, -10.239f, + -13.656f, -15.893f, -21.432f, -23.297f, -25.008f, -27.757f, -25.931f, -28.662f, -31.801f, + -34.383f, -36.273f, -37.302f, -38.636f, -39.603f, -39.769f, -39.880f, -40.519f, -39.688f, + -35.341f, -33.241f, -30.366f, -30.012f, -30.496f, -29.856f, -29.050f, -25.359f, -20.502f, + -16.541f, -14.519f, -13.356f, -11.710f, -10.961f, -9.862f, -8.962f, -5.987f, -3.819f, + -0.441f, -0.172f, -1.151f, -0.433f, 1.105f, 2.052f, 3.911f, 5.274f, 4.877f, + 4.027f, 2.860f, 2.486f, 2.491f, 2.179f, 2.373f, 3.323f, 5.698f, 9.633f, + 13.996f, 18.438f, 24.181f, 26.122f, 25.964f, 25.697f, 20.348f, 21.591f, 13.829f, + 8.209f, 5.686f, 5.130f, 4.350f, 4.702f, 5.482f, 6.041f, 6.509f, 6.594f, + 7.033f, 7.234f, 8.308f, 8.771f, 10.080f, 11.206f, 11.163f, 10.676f, 10.939f, + 11.149f, 11.040f, 10.008f, 11.859f, 11.854f, 10.566f, 9.818f, 8.889f, 8.347f, + 7.877f, 8.039f, 8.501f, 9.132f, 9.975f, 11.113f, 12.556f, 14.384f, 16.698f, + 18.754f, 20.366f, 18.488f, 19.458f, 19.733f, 19.925f, 18.824f, 16.452f, 14.768f, + 13.606f}, + {-29.534f, -28.181f, -22.992f, -18.622f, -14.040f, -9.755f, -7.702f, -4.952f, -1.132f, + 2.192f, 5.200f, 7.161f, 9.249f, 11.142f, 12.510f, 15.584f, 19.692f, 21.509f, + 21.763f, 22.793f, 27.139f, 26.841f, 25.537f, 25.721f, 27.149f, 27.702f, 28.928f, + 30.497f, 31.913f, 33.012f, 34.443f, 35.954f, 37.487f, 39.140f, 41.270f, 44.141f, + 45.625f, 50.892f, 46.969f, 46.556f, 44.527f, 43.767f, 43.905f, 43.947f, 43.911f, + 45.364f, 44.479f, 43.615f, 43.571f, 43.362f, 42.612f, 40.413f, 38.416f, 36.366f, + 33.774f, 32.517f, 31.378f, 30.967f, 26.327f, 22.452f, 18.067f, 13.217f, 8.474f, + 5.754f, 5.257f, 4.739f, 4.932f, 3.333f, 0.085f, -3.651f, -6.700f, -9.556f, + -11.028f, -14.223f, -19.413f, -24.457f, -26.387f, -27.145f, -23.729f, -29.225f, -32.410f, + -34.702f, -36.543f, -38.236f, -39.337f, -40.713f, -41.262f, -40.740f, -41.072f, -41.620f, + -41.311f, -36.186f, -32.683f, -31.031f, -30.568f, -31.328f, -30.155f, -26.215f, -21.917f, + -18.244f, -18.174f, -17.102f, -15.072f, -11.331f, -7.649f, -5.347f, -4.542f, -4.340f, + -3.549f, -4.652f, -5.087f, -3.833f, -2.317f, 0.225f, 1.592f, 1.970f, 1.506f, + 0.529f, -0.178f, -0.181f, -0.320f, -1.309f, -2.168f, -1.306f, 1.331f, 6.326f, + 13.335f, 19.033f, 23.647f, 23.986f, 22.407f, 23.199f, 18.835f, 16.774f, 6.502f, + 4.202f, 3.435f, 2.467f, 0.784f, 1.410f, 3.434f, 4.705f, 5.506f, 5.210f, + 6.794f, 6.460f, 7.874f, 8.354f, 9.332f, 10.071f, 10.977f, 9.788f, 10.435f, + 10.682f, 9.930f, 8.882f, 11.771f, 11.037f, 10.274f, 8.894f, 8.001f, 8.013f, + 7.372f, 7.231f, 7.768f, 8.587f, 9.503f, 10.530f, 12.083f, 14.160f, 16.381f, + 18.480f, 20.440f, 18.236f, 19.196f, 19.515f, 19.798f, 18.676f, 16.382f, 14.748f, + 13.606f}, + {-29.534f, -28.197f, -23.075f, -18.756f, -14.144f, -9.917f, -7.716f, -5.179f, -1.243f, + 2.149f, 5.127f, 7.308f, 9.098f, 10.659f, 12.330f, 15.720f, 19.565f, 21.039f, + 20.844f, 22.654f, 26.662f, 27.814f, 25.834f, 26.537f, 27.357f, 28.160f, 28.863f, + 30.495f, 31.668f, 32.970f, 34.436f, 36.075f, 37.586f, 39.266f, 41.370f, 43.920f, + 45.258f, 50.084f, 47.001f, 46.493f, 44.850f, 43.936f, 44.044f, 45.165f, 46.320f, + 45.642f, 44.514f, 43.655f, 43.534f, 43.715f, 42.759f, 40.832f, 38.833f, 36.922f, + 34.526f, 33.176f, 32.986f, 30.260f, 25.874f, 22.480f, 19.151f, 14.569f, 11.983f, + 9.279f, 7.991f, 8.033f, 7.268f, 3.887f, 0.084f, -3.033f, -6.410f, -8.221f, + -9.514f, -12.145f, -17.883f, -26.089f, -26.579f, -22.107f, -26.892f, -30.300f, -32.638f, + -35.044f, -37.679f, -39.119f, -39.993f, -41.755f, -42.903f, -43.223f, -43.700f, -42.830f, + -43.372f, -41.997f, -36.292f, -34.601f, -34.095f, -33.942f, -32.393f, -28.403f, -24.624f, + -22.029f, -20.486f, -19.775f, -16.827f, -14.769f, -9.855f, -8.346f, -8.618f, -8.488f, + -9.151f, -10.146f, -9.909f, -8.183f, -5.739f, -3.249f, -1.827f, -1.520f, -1.297f, + -2.264f, -3.094f, -3.301f, -4.183f, -5.786f, -6.555f, -4.387f, 0.251f, 5.885f, + 13.440f, 19.625f, 20.481f, 20.675f, 20.256f, 18.466f, 14.051f, 11.916f, 2.029f, + 0.569f, 1.063f, -1.057f, -3.035f, -2.642f, 0.420f, 2.822f, 3.504f, 4.575f, + 6.093f, 6.429f, 6.795f, 8.618f, 9.047f, 9.106f, 10.002f, 9.369f, 9.264f, + 9.205f, 8.955f, 8.185f, 10.472f, 9.382f, 9.889f, 8.150f, 7.254f, 7.508f, + 6.884f, 6.545f, 7.057f, 8.009f, 8.934f, 9.998f, 11.507f, 13.899f, 16.019f, + 18.280f, 20.321f, 17.928f, 18.938f, 19.294f, 19.656f, 18.519f, 16.311f, 14.728f, + 13.606f}, + {-29.534f, -28.212f, -23.164f, -18.882f, -14.247f, -10.052f, -7.657f, -5.285f, -1.376f, + 2.170f, 5.052f, 7.281f, 8.795f, 10.134f, 12.303f, 15.899f, 19.028f, 21.004f, + 21.935f, 23.366f, 26.410f, 28.243f, 27.065f, 28.901f, 28.227f, 28.759f, 28.946f, + 30.717f, 31.461f, 32.401f, 34.398f, 36.043f, 37.601f, 39.257f, 41.414f, 44.018f, + 45.061f, 46.548f, 47.243f, 46.147f, 45.218f, 44.775f, 44.949f, 46.380f, 47.213f, + 46.176f, 44.189f, 43.344f, 42.746f, 42.639f, 43.013f, 41.192f, 39.142f, 36.725f, + 34.687f, 32.871f, 31.428f, 28.235f, 24.966f, 21.988f, 18.928f, 14.888f, 12.325f, + 10.177f, 8.844f, 9.039f, 7.655f, 6.443f, 3.654f, 0.123f, -2.206f, -2.871f, + -7.154f, -13.120f, -17.663f, -23.013f, -25.482f, -27.321f, -28.059f, -31.223f, -33.384f, + -37.016f, -39.639f, -40.348f, -40.966f, -42.039f, -43.625f, -44.925f, -45.387f, -44.924f, + -45.018f, -44.108f, -40.355f, -37.364f, -36.852f, -36.250f, -34.423f, -31.084f, -28.057f, + -24.644f, -22.862f, -21.244f, -18.965f, -17.970f, -13.512f, -12.188f, -11.807f, -12.281f, + -14.086f, -14.789f, -15.181f, -13.296f, -9.883f, -7.509f, -5.438f, -4.993f, -4.729f, + -5.785f, -6.578f, -6.915f, -8.492f, -10.325f, -9.907f, -5.385f, 4.182f, 8.703f, + 14.988f, 17.319f, 18.466f, 18.292f, 19.194f, 11.180f, 11.506f, 4.940f, -2.073f, + -2.133f, -1.481f, -3.511f, -5.029f, -5.434f, -4.604f, -0.533f, 1.625f, 3.778f, + 4.961f, 5.718f, 6.420f, 7.852f, 8.803f, 8.516f, 8.474f, 9.142f, 8.839f, + 8.968f, 8.897f, 7.565f, 7.839f, 7.806f, 9.418f, 7.649f, 6.466f, 6.782f, + 6.431f, 5.960f, 6.545f, 7.337f, 8.269f, 9.374f, 10.881f, 13.454f, 15.546f, + 18.083f, 19.964f, 17.534f, 18.678f, 19.079f, 19.499f, 18.356f, 16.239f, 14.708f, + 13.606f}, + {-29.534f, -28.227f, -23.259f, -18.997f, -14.341f, -10.146f, -7.553f, -5.273f, -1.465f, + 2.296f, 5.123f, 7.163f, 8.582f, 10.014f, 12.276f, 15.501f, 18.370f, 21.279f, + 23.354f, 24.451f, 26.877f, 27.529f, 28.687f, 30.834f, 29.440f, 29.547f, 29.445f, + 30.724f, 31.430f, 32.247f, 33.949f, 35.798f, 37.487f, 39.032f, 41.409f, 43.819f, + 44.282f, 45.796f, 46.872f, 45.506f, 45.257f, 45.077f, 45.361f, 46.152f, 46.733f, + 45.757f, 44.154f, 43.399f, 42.843f, 42.593f, 42.294f, 42.614f, 40.913f, 36.995f, + 34.064f, 31.870f, 29.516f, 26.222f, 23.434f, 20.901f, 17.670f, 14.852f, 11.982f, + 9.299f, 6.850f, 6.852f, 5.851f, 2.854f, 3.336f, 2.588f, 1.160f, -1.018f, + -4.768f, -11.276f, -16.658f, -19.795f, -24.261f, -26.891f, -28.573f, -30.438f, -33.880f, + -33.617f, -35.514f, -43.055f, -41.887f, -42.893f, -44.186f, -45.181f, -46.922f, -47.533f, + -47.756f, -47.352f, -45.566f, -40.641f, -38.786f, -38.789f, -36.616f, -33.118f, -29.030f, + -26.842f, -24.822f, -23.982f, -21.311f, -19.199f, -16.791f, -14.618f, -14.846f, -16.229f, + -17.825f, -18.700f, -19.773f, -19.076f, -15.872f, -12.522f, -10.780f, -9.579f, -9.926f, + -10.420f, -10.734f, -10.742f, -12.531f, -14.250f, -12.139f, -3.315f, 4.943f, 11.241f, + 14.971f, 15.984f, 16.204f, 13.538f, 10.657f, 5.424f, 9.426f, -1.051f, -5.499f, + -4.279f, -3.783f, -5.539f, -8.507f, -6.938f, -7.245f, -4.074f, -0.047f, 2.883f, + 4.117f, 5.138f, 6.191f, 6.977f, 7.872f, 7.750f, 7.338f, 8.112f, 8.392f, + 9.374f, 8.911f, 7.061f, 6.174f, 7.332f, 8.659f, 6.777f, 5.591f, 5.828f, + 5.862f, 5.308f, 6.129f, 6.639f, 7.652f, 8.659f, 10.294f, 12.817f, 14.986f, + 17.815f, 19.400f, 17.066f, 18.412f, 18.871f, 19.329f, 18.191f, 16.166f, 14.687f, + 13.606f}, + {-29.534f, -28.241f, -23.357f, -19.098f, -14.425f, -10.196f, -7.434f, -5.172f, -1.454f, + 2.493f, 5.341f, 7.062f, 8.585f, 10.272f, 12.201f, 14.856f, 17.993f, 21.532f, + 23.606f, 24.934f, 26.607f, 26.456f, 29.791f, 31.995f, 30.181f, 30.371f, 29.206f, + 30.111f, 31.343f, 32.194f, 33.481f, 35.286f, 37.159f, 38.765f, 40.991f, 43.334f, + 44.809f, 47.002f, 45.583f, 45.112f, 45.185f, 44.956f, 44.727f, 44.632f, 44.653f, + 44.824f, 44.107f, 43.582f, 42.776f, 42.123f, 41.590f, 41.941f, 40.721f, 37.605f, + 34.239f, 31.114f, 28.051f, 25.263f, 22.620f, 18.774f, 16.392f, 14.549f, 12.074f, + 8.040f, 4.757f, 2.898f, 2.331f, 1.018f, -0.252f, -0.880f, -1.203f, -1.914f, + -5.049f, -8.427f, -12.921f, -18.044f, -18.404f, -20.627f, -24.911f, -31.190f, -32.786f, + -38.067f, -39.892f, -43.131f, -41.520f, -43.280f, -44.276f, -46.008f, -47.171f, -48.813f, + -49.225f, -49.776f, -49.929f, -47.004f, -42.804f, -40.935f, -39.501f, -35.695f, -30.560f, + -27.947f, -25.992f, -25.411f, -23.435f, -21.380f, -19.048f, -15.833f, -17.389f, -19.810f, + -21.959f, -23.147f, -24.113f, -24.198f, -22.583f, -19.599f, -17.502f, -15.755f, -15.298f, + -15.359f, -14.782f, -14.510f, -15.071f, -16.147f, -14.092f, -3.308f, 5.392f, 11.243f, + 11.993f, 11.809f, 13.048f, 10.623f, 3.137f, 4.660f, -1.376f, -6.393f, -7.392f, + -6.251f, -5.663f, -8.324f, -11.823f, -8.645f, -8.315f, -6.367f, -1.080f, 1.481f, + 2.989f, 4.080f, 5.094f, 6.417f, 7.115f, 7.276f, 6.953f, 7.458f, 7.757f, + 9.298f, 8.036f, 6.593f, 6.313f, 7.508f, 7.539f, 5.557f, 4.745f, 4.602f, + 4.869f, 4.430f, 5.419f, 5.939f, 7.129f, 7.989f, 9.759f, 12.089f, 14.422f, + 17.435f, 18.736f, 16.576f, 18.136f, 18.673f, 19.147f, 18.028f, 16.093f, 14.667f, + 13.606f}, + {-29.534f, -28.256f, -23.458f, -19.184f, -14.493f, -10.204f, -7.318f, -5.021f, -1.333f, + 2.678f, 5.562f, 7.050f, 8.709f, 10.471f, 12.261f, 14.941f, 18.120f, 21.594f, + 23.650f, 25.213f, 26.208f, 27.265f, 31.976f, 33.005f, 30.178f, 30.513f, 28.779f, + 29.413f, 30.957f, 31.859f, 33.084f, 34.740f, 36.588f, 38.304f, 40.360f, 41.886f, + 43.322f, 45.143f, 44.993f, 44.605f, 44.876f, 44.999f, 44.554f, 44.600f, 47.419f, + 44.489f, 43.915f, 43.661f, 42.751f, 41.608f, 40.969f, 41.241f, 40.916f, 38.699f, + 34.498f, 31.117f, 27.612f, 24.673f, 21.446f, 17.533f, 14.934f, 13.375f, 10.620f, + 6.332f, 3.352f, 1.268f, -0.748f, -2.888f, -5.310f, -6.095f, -6.641f, -6.863f, + -7.032f, -9.143f, -10.283f, -13.726f, -15.688f, -18.313f, -24.050f, -30.456f, -33.197f, + -34.567f, -37.521f, -38.502f, -41.763f, -43.094f, -44.221f, -45.848f, -47.423f, -48.425f, + -49.549f, -50.778f, -51.348f, -49.509f, -46.861f, -46.408f, -42.027f, -39.071f, -34.192f, + -30.473f, -28.290f, -27.710f, -25.809f, -23.461f, -21.517f, -17.942f, -19.302f, -21.895f, + -25.308f, -26.843f, -28.025f, -28.013f, -27.327f, -25.813f, -24.150f, -22.180f, -20.990f, + -19.967f, -18.624f, -18.237f, -17.356f, -15.800f, -12.388f, -0.104f, 6.095f, 9.295f, + 10.020f, 7.863f, 4.931f, -0.492f, -7.695f, -6.319f, -7.977f, -7.770f, -8.958f, + -8.902f, -7.998f, -11.148f, -12.915f, -11.655f, -10.037f, -8.435f, -2.524f, 0.172f, + 1.561f, 2.505f, 3.908f, 5.132f, 5.898f, 6.738f, 6.847f, 6.956f, 6.612f, + 8.245f, 6.773f, 6.452f, 6.558f, 7.222f, 6.025f, 4.489f, 3.860f, 3.481f, + 3.696f, 3.396f, 4.432f, 5.202f, 6.563f, 7.452f, 9.216f, 11.375f, 13.911f, + 16.961f, 18.121f, 16.140f, 17.851f, 18.481f, 18.958f, 17.872f, 16.021f, 14.647f, + 13.606f}, + {-29.534f, -28.270f, -23.561f, -19.256f, -14.546f, -10.180f, -7.208f, -4.856f, -1.136f, + 2.787f, 5.635f, 7.163f, 8.794f, 10.360f, 12.602f, 15.907f, 18.552f, 21.364f, + 24.289f, 25.706f, 26.665f, 29.431f, 35.043f, 33.821f, 30.889f, 30.106f, 28.749f, + 29.196f, 30.669f, 31.628f, 32.927f, 34.177f, 36.278f, 37.762f, 39.694f, 40.810f, + 42.965f, 44.213f, 44.436f, 44.354f, 44.541f, 44.975f, 44.910f, 46.184f, 51.917f, + 44.892f, 43.542f, 43.280f, 42.081f, 40.996f, 40.493f, 40.262f, 40.554f, 38.520f, + 34.527f, 30.898f, 27.533f, 24.079f, 20.799f, 17.158f, 14.436f, 11.130f, 7.991f, + 4.911f, 2.482f, 0.768f, -1.814f, -4.217f, -6.696f, -9.080f, -11.206f, -12.877f, + -13.381f, -12.770f, -14.040f, -14.761f, -16.316f, -20.562f, -26.311f, -30.344f, -32.479f, + -34.386f, -36.194f, -38.646f, -40.838f, -42.761f, -44.190f, -45.374f, -46.812f, -48.509f, + -48.937f, -49.266f, -49.658f, -50.201f, -49.067f, -48.652f, -48.502f, -43.523f, -38.655f, + -34.465f, -32.070f, -27.935f, -28.455f, -25.906f, -24.073f, -21.102f, -21.086f, -22.782f, + -26.825f, -29.328f, -30.885f, -31.342f, -30.836f, -29.788f, -28.219f, -26.843f, -26.188f, + -24.735f, -23.139f, -20.572f, -17.681f, -11.346f, -3.974f, 4.108f, 5.902f, 6.475f, + 5.497f, 4.637f, -7.703f, -11.868f, -15.891f, -15.991f, -11.229f, -8.968f, -10.584f, + -10.968f, -10.426f, -13.687f, -14.187f, -13.591f, -11.801f, -10.247f, -4.185f, -1.011f, + 0.407f, 1.604f, 2.607f, 3.753f, 5.131f, 5.689f, 6.032f, 6.178f, 5.519f, + 6.126f, 5.733f, 6.356f, 5.744f, 5.885f, 4.626f, 3.798f, 3.015f, 2.791f, + 2.931f, 2.555f, 3.646f, 4.464f, 5.867f, 6.981f, 8.625f, 10.714f, 13.438f, + 16.458f, 17.683f, 15.825f, 17.561f, 18.291f, 18.767f, 17.729f, 15.950f, 14.626f, + 13.606f}, + {-29.534f, -28.284f, -23.663f, -19.317f, -14.583f, -10.137f, -7.096f, -4.696f, -0.915f, + 2.846f, 5.582f, 7.433f, 8.847f, 10.203f, 13.080f, 16.724f, 18.754f, 20.833f, + 24.282f, 25.745f, 27.406f, 31.048f, 36.330f, 35.690f, 33.133f, 30.102f, 28.943f, + 29.207f, 30.555f, 31.477f, 32.761f, 34.083f, 35.700f, 37.371f, 39.230f, 40.781f, + 44.195f, 44.857f, 44.329f, 44.337f, 44.466f, 44.856f, 44.876f, 47.874f, 50.171f, + 44.569f, 43.164f, 42.604f, 41.604f, 40.885f, 40.080f, 39.882f, 39.463f, 37.705f, + 34.206f, 30.691f, 27.184f, 23.597f, 20.237f, 16.898f, 13.585f, 10.184f, 7.185f, + 4.202f, 2.021f, 0.608f, -1.815f, -4.644f, -6.665f, -9.197f, -11.251f, -13.315f, + -15.304f, -17.019f, -17.586f, -19.425f, -21.902f, -25.500f, -28.525f, -30.681f, -30.190f, + -33.971f, -36.926f, -38.188f, -40.360f, -42.082f, -43.787f, -44.867f, -46.313f, -48.051f, + -49.168f, -49.990f, -50.323f, -51.695f, -52.660f, -52.663f, -52.086f, -51.120f, -47.127f, + -41.718f, -36.516f, -33.254f, -30.413f, -28.087f, -26.305f, -23.966f, -22.699f, -23.773f, + -27.731f, -31.364f, -32.930f, -33.140f, -32.774f, -31.814f, -30.803f, -29.863f, -28.480f, + -27.083f, -25.661f, -21.075f, -13.200f, -5.293f, -1.135f, 3.136f, 3.915f, 1.294f, + 4.962f, -2.919f, -11.902f, -17.313f, -20.601f, -16.263f, -11.810f, -10.022f, -11.722f, + -12.476f, -12.435f, -15.269f, -15.811f, -15.283f, -13.562f, -11.463f, -5.724f, -2.094f, + 0.022f, 0.655f, 0.966f, 2.106f, 3.775f, 4.616f, 4.859f, 5.153f, 3.714f, + 4.107f, 4.751f, 5.378f, 4.229f, 3.987f, 3.837f, 3.135f, 2.412f, 2.177f, + 2.576f, 2.128f, 3.180f, 3.832f, 5.199f, 6.469f, 8.024f, 10.092f, 12.939f, + 15.993f, 17.470f, 15.657f, 17.273f, 18.098f, 18.579f, 17.600f, 15.880f, 14.605f, + 13.606f}, + {-29.534f, -28.297f, -23.765f, -19.369f, -14.607f, -10.091f, -6.970f, -4.535f, -0.703f, + 2.976f, 5.634f, 7.890f, 9.051f, 10.391f, 13.426f, 16.594f, 18.440f, 20.243f, + 22.892f, 24.990f, 28.035f, 32.532f, 36.854f, 38.580f, 34.267f, 30.317f, 29.145f, + 29.159f, 30.370f, 31.334f, 32.739f, 34.176f, 35.270f, 36.919f, 38.706f, 40.883f, + 44.714f, 43.020f, 43.284f, 44.033f, 44.343f, 44.580f, 44.523f, 47.603f, 47.302f, + 43.762f, 42.848f, 42.256f, 40.472f, 39.963f, 38.797f, 37.546f, 37.344f, 36.245f, + 33.963f, 30.432f, 26.754f, 22.973f, 19.607f, 16.596f, 13.623f, 10.343f, 6.937f, + 3.712f, 1.961f, 0.730f, -1.361f, -4.018f, -6.530f, -8.774f, -11.308f, -13.570f, + -15.820f, -17.478f, -19.352f, -21.683f, -23.746f, -26.202f, -28.703f, -30.415f, -32.430f, + -33.776f, -36.261f, -38.323f, -40.366f, -41.775f, -44.105f, -45.486f, -47.305f, -48.442f, + -49.270f, -50.387f, -50.861f, -50.847f, -54.319f, -54.008f, -53.493f, -53.357f, -51.651f, + -48.516f, -44.219f, -40.175f, -34.328f, -31.252f, -29.289f, -26.846f, -25.776f, -25.137f, + -28.915f, -32.286f, -34.250f, -34.652f, -33.895f, -33.241f, -32.567f, -31.067f, -30.199f, + -28.749f, -24.016f, -14.869f, -6.978f, -3.041f, -1.414f, 1.378f, -0.558f, -1.998f, + 0.894f, -7.336f, -12.491f, -16.910f, -18.034f, -11.441f, -10.923f, -11.745f, -12.605f, + -14.077f, -14.755f, -16.382f, -16.913f, -16.019f, -14.870f, -12.846f, -7.175f, -2.767f, + -1.154f, -0.263f, -0.575f, 0.476f, 2.344f, 3.552f, 3.816f, 3.470f, 1.886f, + 2.411f, 3.643f, 3.543f, 2.659f, 2.651f, 3.008f, 2.111f, 1.894f, 1.499f, + 2.338f, 1.958f, 2.635f, 3.284f, 4.776f, 5.914f, 7.485f, 9.504f, 12.384f, + 15.604f, 17.432f, 15.616f, 16.992f, 17.898f, 18.397f, 17.491f, 15.812f, 14.583f, + 13.606f}, + {-29.534f, -28.310f, -23.865f, -19.418f, -14.622f, -10.053f, -6.823f, -4.353f, -0.494f, + 3.312f, 6.080f, 8.521f, 9.524f, 10.901f, 13.512f, 15.913f, 17.875f, 19.721f, + 21.464f, 24.032f, 28.396f, 33.533f, 38.369f, 40.727f, 35.252f, 30.790f, 28.792f, + 29.093f, 30.393f, 31.368f, 32.864f, 34.127f, 35.174f, 36.212f, 38.517f, 40.609f, + 42.582f, 43.049f, 43.441f, 43.913f, 43.972f, 44.203f, 44.083f, 45.400f, 44.427f, + 43.201f, 42.829f, 41.937f, 40.227f, 39.140f, 37.746f, 36.578f, 35.864f, 35.616f, + 33.380f, 30.843f, 27.020f, 23.499f, 19.911f, 16.754f, 14.525f, 11.228f, 6.841f, + 3.628f, 1.852f, 0.586f, -1.137f, -2.923f, -5.782f, -8.952f, -11.171f, -13.405f, + -15.659f, -17.516f, -19.722f, -22.314f, -24.465f, -27.204f, -29.567f, -31.264f, -32.654f, + -35.927f, -37.097f, -39.090f, -39.039f, -41.361f, -44.041f, -46.327f, -47.989f, -49.096f, + -50.034f, -50.927f, -52.064f, -52.513f, -52.219f, -54.406f, -54.728f, -54.190f, -52.654f, + -51.051f, -47.700f, -44.040f, -36.869f, -34.173f, -31.011f, -29.138f, -28.683f, -28.492f, + -32.067f, -34.320f, -35.340f, -35.230f, -34.316f, -33.491f, -33.131f, -32.310f, -31.243f, + -27.982f, -20.640f, -12.366f, -8.173f, -3.668f, -1.699f, -0.601f, -2.591f, -4.580f, + -1.862f, -9.472f, -13.231f, -17.996f, -15.373f, -11.910f, -11.991f, -13.780f, -14.779f, + -16.175f, -16.119f, -17.617f, -18.108f, -16.107f, -15.055f, -14.239f, -8.235f, -4.022f, + -2.938f, -1.967f, -2.366f, -1.420f, 0.799f, 2.227f, 3.146f, 2.599f, 0.766f, + 1.304f, 2.293f, 1.839f, 1.503f, 1.932f, 1.727f, 1.109f, 1.067f, 1.105f, + 2.201f, 1.883f, 1.938f, 2.651f, 4.559f, 5.406f, 7.036f, 8.993f, 11.826f, + 15.274f, 17.451f, 15.643f, 16.723f, 17.690f, 18.226f, 17.402f, 15.746f, 14.561f, + 13.606f}, + {-29.534f, -28.322f, -23.963f, -19.468f, -14.634f, -10.034f, -6.660f, -4.133f, -0.252f, + 3.892f, 7.005f, 9.223f, 10.125f, 11.318f, 13.357f, 15.412f, 17.427f, 19.181f, + 21.082f, 23.500f, 27.868f, 32.256f, 38.374f, 41.107f, 36.953f, 31.126f, 28.822f, + 29.196f, 30.511f, 31.491f, 32.768f, 34.150f, 35.086f, 36.263f, 38.174f, 39.741f, + 41.400f, 41.964f, 43.024f, 43.123f, 43.430f, 43.660f, 43.855f, 43.528f, 43.209f, + 42.752f, 41.875f, 40.553f, 38.939f, 37.190f, 36.109f, 35.056f, 33.721f, 33.029f, + 32.872f, 30.329f, 27.781f, 23.718f, 20.412f, 17.604f, 14.865f, 11.355f, 7.507f, + 4.183f, 2.337f, 0.594f, -0.752f, -2.569f, -5.069f, -8.144f, -10.702f, -13.340f, + -15.781f, -17.828f, -19.914f, -22.578f, -25.087f, -27.876f, -30.008f, -31.964f, -33.364f, + -35.422f, -37.899f, -39.210f, -41.172f, -43.127f, -43.612f, -46.116f, -47.961f, -49.507f, + -50.660f, -51.800f, -52.594f, -52.543f, -53.388f, -53.397f, -54.210f, -56.069f, -53.792f, + -51.842f, -49.528f, -46.813f, -40.523f, -36.768f, -33.698f, -31.622f, -30.876f, -32.009f, + -34.441f, -36.191f, -36.372f, -35.917f, -34.430f, -33.236f, -33.170f, -32.932f, -31.976f, + -25.591f, -18.940f, -13.467f, -7.788f, -4.698f, -2.778f, -3.641f, -5.479f, -7.340f, + -3.983f, -10.146f, -15.984f, -20.606f, -15.610f, -12.953f, -13.893f, -16.748f, -16.424f, + -18.239f, -17.794f, -19.173f, -19.294f, -16.429f, -15.518f, -15.323f, -9.317f, -5.915f, + -5.363f, -3.888f, -4.614f, -3.353f, -0.626f, 1.190f, 1.587f, 1.217f, -0.365f, + 1.186f, 0.881f, 0.680f, 1.004f, 1.271f, 0.666f, 0.454f, -0.084f, 0.795f, + 1.873f, 1.899f, 1.572f, 1.934f, 4.279f, 4.993f, 6.645f, 8.612f, 11.373f, + 14.962f, 17.408f, 15.669f, 16.467f, 17.474f, 18.069f, 17.335f, 15.682f, 14.539f, + 13.606f}, + {-29.534f, -28.334f, -24.057f, -19.523f, -14.648f, -10.037f, -6.503f, -3.877f, 0.053f, + 4.606f, 8.163f, 9.820f, 10.517f, 11.314f, 12.976f, 15.085f, 17.144f, 18.852f, + 21.065f, 23.475f, 26.692f, 30.034f, 36.042f, 38.981f, 35.986f, 30.475f, 28.984f, + 29.660f, 30.923f, 31.472f, 32.583f, 34.013f, 35.046f, 36.318f, 37.753f, 39.232f, + 40.537f, 41.454f, 42.389f, 42.829f, 42.827f, 43.016f, 43.259f, 43.073f, 42.652f, + 41.916f, 40.664f, 39.029f, 37.366f, 36.418f, 34.697f, 33.107f, 32.330f, 31.368f, + 30.658f, 30.357f, 28.538f, 24.919f, 21.053f, 18.108f, 14.723f, 10.881f, 7.737f, + 4.902f, 2.616f, 1.111f, -0.702f, -2.622f, -3.848f, -1.082f, -10.763f, -13.736f, + -15.577f, -17.367f, -19.386f, -21.960f, -25.113f, -27.378f, -29.949f, -32.231f, -34.182f, + -36.060f, -38.398f, -40.490f, -42.137f, -41.229f, -41.576f, -47.266f, -49.195f, -50.654f, + -51.707f, -52.752f, -53.873f, -53.814f, -53.588f, -53.649f, -53.606f, -54.441f, -54.937f, + -53.153f, -50.829f, -47.594f, -42.681f, -39.790f, -36.175f, -34.035f, -33.372f, -33.860f, + -34.230f, -36.632f, -36.503f, -36.040f, -34.530f, -32.524f, -32.679f, -33.122f, -33.318f, + -26.400f, -19.361f, -11.135f, -6.458f, -5.040f, -5.111f, -5.431f, -7.474f, -9.115f, + -7.606f, -10.183f, -17.355f, -19.542f, -15.284f, -13.630f, -16.555f, -18.592f, -17.881f, + -20.177f, -19.909f, -20.398f, -20.389f, -18.706f, -16.929f, -16.707f, -11.680f, -8.583f, + -7.543f, -6.179f, -6.014f, -4.664f, -1.685f, 0.123f, 0.349f, -0.458f, -0.786f, + 0.755f, -0.018f, -0.103f, 0.495f, 0.475f, -0.011f, -0.275f, -1.118f, 0.164f, + 0.781f, 1.742f, 1.694f, 1.527f, 3.769f, 4.618f, 6.269f, 8.354f, 11.096f, + 14.637f, 17.242f, 15.647f, 16.220f, 17.254f, 17.926f, 17.288f, 15.620f, 14.517f, + 13.606f}, + {-29.534f, -28.346f, -24.147f, -19.589f, -14.670f, -10.062f, -6.382f, -3.611f, 0.416f, + 5.238f, 9.080f, 10.140f, 10.450f, 10.922f, 12.405f, 14.589f, 16.934f, 18.977f, + 20.675f, 23.406f, 26.017f, 29.509f, 34.427f, 35.391f, 33.664f, 30.224f, 29.057f, + 30.060f, 31.096f, 31.429f, 32.339f, 33.620f, 34.951f, 36.182f, 37.454f, 38.904f, + 40.320f, 41.065f, 41.574f, 41.434f, 42.052f, 42.429f, 42.589f, 42.347f, 42.205f, + 41.210f, 39.372f, 37.878f, 36.383f, 35.127f, 33.408f, 31.428f, 30.619f, 29.582f, + 28.854f, 28.630f, 27.080f, 25.384f, 21.871f, 18.062f, 13.975f, 10.171f, 7.609f, + 5.193f, 2.689f, 1.101f, -0.073f, -2.665f, -4.023f, -2.046f, -11.689f, -14.986f, + -16.086f, -17.500f, -19.942f, -22.199f, -25.298f, -27.535f, -30.827f, -33.121f, -34.890f, + -36.762f, -38.854f, -41.645f, -43.421f, -41.306f, -43.800f, -49.437f, -51.123f, -52.706f, + -52.893f, -53.800f, -55.300f, -55.791f, -55.091f, -54.836f, -53.640f, -53.164f, -52.022f, + -50.825f, -50.226f, -47.961f, -44.660f, -42.392f, -38.751f, -36.528f, -36.154f, -35.650f, + -34.795f, -36.035f, -35.424f, -35.264f, -35.050f, -32.687f, -29.779f, -28.215f, -31.034f, + -30.069f, -20.790f, -7.978f, -5.862f, -6.561f, -6.482f, -7.875f, -9.706f, -10.778f, + -10.088f, -10.482f, -15.688f, -19.237f, -17.660f, -17.307f, -19.980f, -20.314f, -20.210f, + -22.106f, -22.027f, -21.392f, -21.503f, -21.280f, -19.619f, -18.095f, -14.282f, -11.223f, + -10.227f, -8.432f, -6.626f, -5.014f, -2.511f, -1.198f, -1.093f, -2.151f, -1.360f, + -0.318f, -0.531f, -0.445f, -0.568f, -0.434f, -0.635f, -1.208f, -1.694f, -0.520f, + -0.846f, 0.936f, 1.734f, 1.815f, 3.122f, 4.187f, 5.876f, 8.126f, 10.954f, + 14.304f, 16.978f, 15.567f, 15.977f, 17.033f, 17.798f, 17.259f, 15.561f, 14.494f, + 13.606f}, + {-29.534f, -28.357f, -24.233f, -19.669f, -14.705f, -10.104f, -6.328f, -3.384f, 0.786f, + 5.595f, 9.363f, 10.102f, 9.965f, 10.356f, 11.788f, 14.058f, 16.827f, 19.045f, + 20.267f, 22.859f, 25.924f, 29.927f, 34.218f, 33.043f, 32.331f, 29.971f, 29.489f, + 30.342f, 31.125f, 31.464f, 32.392f, 33.614f, 34.549f, 35.661f, 37.236f, 38.283f, + 39.357f, 40.715f, 40.726f, 40.863f, 40.969f, 41.379f, 41.658f, 41.436f, 41.158f, + 40.152f, 38.504f, 36.882f, 35.365f, 33.586f, 31.993f, 29.976f, 28.608f, 27.648f, + 26.848f, 26.222f, 24.923f, 23.574f, 20.673f, 17.748f, 13.730f, 9.636f, 7.055f, + 4.907f, 2.623f, 0.881f, -0.730f, -2.825f, -5.985f, -9.648f, -12.423f, -12.322f, + -16.888f, -18.765f, -20.703f, -22.978f, -25.657f, -28.969f, -31.848f, -34.082f, -36.145f, + -38.258f, -40.744f, -43.079f, -44.356f, -44.408f, -48.907f, -51.196f, -53.113f, -54.413f, + -55.396f, -55.727f, -56.472f, -57.140f, -57.047f, -56.287f, -55.374f, -54.019f, -52.874f, + -51.236f, -50.220f, -49.178f, -46.402f, -43.892f, -41.444f, -40.119f, -39.512f, -39.140f, + -35.560f, -34.719f, -33.307f, -34.146f, -33.136f, -29.953f, -26.614f, -26.930f, -26.165f, + -27.843f, -19.159f, -7.234f, -7.028f, -8.552f, -10.044f, -10.346f, -11.080f, -11.933f, + -12.170f, -11.459f, -14.951f, -21.494f, -21.009f, -21.345f, -23.163f, -22.711f, -22.967f, + -23.817f, -24.293f, -22.137f, -21.441f, -21.508f, -20.910f, -18.376f, -14.039f, -11.642f, + -10.766f, -9.680f, -6.728f, -5.060f, -3.363f, -2.428f, -2.479f, -3.091f, -2.284f, + -1.662f, -1.967f, -1.598f, -1.759f, -1.241f, -1.283f, -1.980f, -1.776f, -1.109f, + -2.057f, -0.431f, 1.168f, 2.528f, 2.520f, 3.673f, 5.438f, 7.812f, 10.809f, + 13.996f, 16.692f, 15.450f, 15.734f, 16.813f, 17.685f, 17.243f, 15.503f, 14.470f, + 13.606f}, + {-29.534f, -28.368f, -24.314f, -19.765f, -14.758f, -10.158f, -6.357f, -3.243f, 1.080f, + 5.623f, 8.962f, 9.739f, 9.350f, 9.786f, 11.284f, 13.779f, 16.879f, 18.698f, + 20.175f, 22.439f, 25.559f, 29.375f, 33.521f, 32.170f, 31.037f, 29.088f, 29.691f, + 30.510f, 30.996f, 31.641f, 32.534f, 33.548f, 34.562f, 35.581f, 36.855f, 37.945f, + 38.272f, 39.433f, 39.821f, 40.117f, 40.293f, 40.542f, 40.670f, 40.340f, 39.834f, + 38.726f, 37.160f, 36.262f, 34.677f, 32.493f, 30.624f, 28.909f, 27.070f, 25.731f, + 25.180f, 24.739f, 23.749f, 22.123f, 20.956f, 18.831f, 13.975f, 9.863f, 6.870f, + 4.074f, 2.300f, 0.383f, -1.633f, -3.804f, -5.856f, -9.499f, -6.875f, -9.636f, + -16.768f, -19.287f, -21.890f, -24.336f, -26.898f, -30.166f, -33.455f, -35.653f, -38.286f, + -40.137f, -42.407f, -43.757f, -45.144f, -48.705f, -50.864f, -53.103f, -55.086f, -56.289f, + -57.721f, -58.203f, -58.428f, -59.212f, -58.618f, -57.261f, -56.624f, -55.736f, -54.007f, + -52.578f, -50.753f, -51.612f, -50.635f, -47.171f, -45.364f, -44.670f, -43.759f, -42.497f, + -39.878f, -36.685f, -35.484f, -32.945f, -31.639f, -27.549f, -29.918f, -28.699f, -22.012f, + -19.779f, -17.860f, -11.159f, -13.407f, -14.314f, -12.075f, -11.640f, -12.358f, -14.442f, + -13.229f, -13.530f, -19.156f, -23.967f, -24.103f, -24.671f, -25.279f, -25.224f, -25.445f, + -25.982f, -25.865f, -22.907f, -20.388f, -19.875f, -18.282f, -16.428f, -12.503f, -11.325f, + -9.983f, -9.461f, -6.984f, -5.842f, -4.196f, -2.954f, -3.055f, -3.795f, -3.499f, + -2.347f, -2.919f, -2.903f, -2.640f, -2.023f, -2.005f, -2.517f, -1.638f, -1.973f, + -2.487f, -1.663f, 0.121f, 2.805f, 2.081f, 3.133f, 4.925f, 7.368f, 10.517f, + 13.737f, 16.448f, 15.327f, 15.486f, 16.596f, 17.585f, 17.237f, 15.447f, 14.446f, + 13.606f}, + {-29.534f, -28.378f, -24.390f, -19.877f, -14.832f, -10.215f, -6.460f, -3.214f, 1.228f, + 5.417f, 8.199f, 9.160f, 8.904f, 9.380f, 10.936f, 13.516f, 17.014f, 18.875f, + 20.090f, 22.676f, 25.267f, 28.274f, 32.206f, 31.292f, 29.722f, 28.603f, 29.592f, + 30.434f, 30.834f, 31.897f, 32.681f, 33.604f, 34.403f, 35.464f, 36.301f, 37.259f, + 37.901f, 37.831f, 38.742f, 39.240f, 39.256f, 39.710f, 39.660f, 39.227f, 38.455f, + 37.141f, 35.724f, 34.894f, 33.442f, 31.418f, 29.638f, 27.773f, 26.381f, 25.080f, + 23.765f, 23.152f, 22.005f, 21.415f, 20.761f, 18.049f, 15.358f, 10.737f, 6.819f, + 3.683f, 2.048f, 0.428f, -1.689f, -3.746f, -5.343f, -8.218f, -12.313f, -12.753f, + -16.312f, -16.871f, -20.462f, -27.158f, -29.030f, -31.675f, -34.769f, -37.336f, -39.475f, + -41.084f, -42.577f, -45.459f, -48.685f, -51.286f, -53.542f, -55.358f, -57.113f, -58.733f, + -60.083f, -60.824f, -61.198f, -61.068f, -60.573f, -59.552f, -58.489f, -56.977f, -55.491f, + -54.697f, -54.244f, -54.230f, -53.604f, -52.000f, -50.578f, -50.386f, -47.022f, -44.266f, + -43.653f, -42.018f, -38.660f, -35.051f, -31.600f, -29.770f, -35.644f, -30.183f, -23.677f, + -21.905f, -19.725f, -16.904f, -15.810f, -13.880f, -12.219f, -12.404f, -13.500f, -16.341f, + -15.265f, -16.742f, -25.725f, -26.711f, -26.270f, -26.684f, -26.956f, -26.728f, -27.341f, + -27.790f, -27.184f, -25.346f, -21.737f, -18.612f, -17.158f, -15.505f, -13.454f, -11.799f, + -9.605f, -8.542f, -7.663f, -6.407f, -4.808f, -3.040f, -2.634f, -2.942f, -2.669f, + -1.889f, -1.580f, -2.044f, -3.545f, -2.800f, -2.544f, -3.129f, -1.957f, -3.023f, + -2.683f, -2.384f, -0.988f, 2.082f, 1.877f, 2.635f, 4.358f, 6.871f, 10.033f, + 13.505f, 16.245f, 15.217f, 15.231f, 16.380f, 17.495f, 17.233f, 15.393f, 14.422f, + 13.606f}, + {-29.534f, -28.388f, -24.461f, -20.006f, -14.927f, -10.268f, -6.604f, -3.281f, 1.204f, + 5.141f, 7.517f, 8.497f, 8.709f, 9.363f, 10.726f, 12.879f, 17.082f, 20.240f, + 19.888f, 22.634f, 25.739f, 27.667f, 31.135f, 30.397f, 28.360f, 27.665f, 29.073f, + 30.184f, 30.727f, 31.864f, 32.551f, 33.334f, 34.060f, 35.101f, 35.666f, 36.717f, + 37.710f, 37.306f, 37.848f, 38.423f, 38.223f, 38.624f, 38.457f, 37.664f, 36.792f, + 35.605f, 34.170f, 33.350f, 32.111f, 30.185f, 28.655f, 27.042f, 25.527f, 24.574f, + 23.569f, 22.269f, 20.913f, 19.335f, 18.544f, 17.752f, 14.922f, 11.454f, 7.222f, + 3.862f, 1.885f, 0.493f, -1.626f, -3.977f, -5.459f, -7.445f, -10.458f, -13.063f, + -16.494f, -17.437f, -19.341f, -23.788f, -29.118f, -34.081f, -36.541f, -38.192f, -38.094f, + -40.308f, -44.458f, -48.641f, -51.340f, -53.947f, -55.843f, -57.878f, -60.110f, -61.738f, + -62.749f, -63.573f, -63.488f, -63.183f, -62.669f, -61.658f, -60.221f, -59.064f, -58.346f, + -58.230f, -58.224f, -58.008f, -56.849f, -56.743f, -54.346f, -53.580f, -52.462f, -49.706f, + -47.753f, -43.200f, -42.720f, -40.368f, -36.154f, -37.645f, -37.495f, -31.810f, -25.641f, + -23.630f, -20.464f, -17.279f, -15.055f, -14.771f, -13.916f, -14.135f, -17.196f, -16.827f, + -18.251f, -23.099f, -28.906f, -29.351f, -28.329f, -28.207f, -27.746f, -27.690f, -28.908f, + -28.946f, -28.767f, -26.605f, -24.239f, -21.778f, -19.360f, -18.272f, -16.251f, -14.538f, + -11.909f, -9.512f, -7.724f, -7.041f, -4.864f, -4.763f, -3.866f, -3.351f, -3.062f, + -3.265f, -1.684f, -1.065f, -4.951f, -3.634f, -2.992f, -4.036f, -2.966f, -3.868f, + -3.199f, -2.859f, -1.915f, 0.688f, 1.921f, 2.198f, 3.830f, 6.441f, 9.427f, + 13.232f, 16.004f, 15.105f, 14.970f, 16.164f, 17.414f, 17.226f, 15.339f, 14.396f, + 13.606f}, + {-29.534f, -28.397f, -24.527f, -20.149f, -15.044f, -10.313f, -6.738f, -3.392f, 1.042f, + 4.906f, 7.164f, 7.858f, 8.595f, 9.763f, 10.702f, 12.084f, 17.048f, 21.488f, + 19.829f, 21.654f, 25.829f, 27.243f, 30.159f, 29.585f, 27.127f, 26.722f, 28.517f, + 29.763f, 30.338f, 31.390f, 32.176f, 33.106f, 33.955f, 34.638f, 35.498f, 36.202f, + 37.090f, 37.289f, 37.071f, 37.993f, 37.471f, 37.818f, 37.567f, 36.528f, 35.297f, + 34.147f, 32.982f, 32.277f, 31.004f, 29.362f, 27.846f, 26.263f, 25.082f, 24.224f, + 23.561f, 22.093f, 20.347f, 18.554f, 16.419f, 15.158f, 13.669f, 10.489f, 8.095f, + 4.249f, 1.732f, 0.482f, -1.484f, -3.763f, -6.006f, -7.599f, -10.952f, -14.080f, + -16.490f, -20.040f, -21.256f, -23.752f, -26.918f, -31.284f, -34.424f, -36.180f, -38.977f, + -44.286f, -47.409f, -51.039f, -53.956f, -56.273f, -58.690f, -61.270f, -63.215f, -64.281f, + -65.524f, -65.831f, -65.849f, -65.580f, -65.101f, -63.939f, -62.454f, -62.387f, -62.227f, + -61.926f, -62.220f, -61.545f, -60.390f, -58.735f, -57.545f, -56.723f, -55.936f, -54.978f, + -53.802f, -49.995f, -47.845f, -43.019f, -41.055f, -39.531f, -39.131f, -32.266f, -27.786f, + -24.611f, -20.992f, -17.226f, -18.535f, -19.094f, -17.674f, -19.341f, -20.375f, -21.349f, + -22.887f, -28.105f, -30.796f, -31.153f, -30.356f, -30.199f, -29.330f, -29.399f, -30.163f, + -30.078f, -30.064f, -28.595f, -26.904f, -24.293f, -22.293f, -20.463f, -17.969f, -16.586f, + -14.147f, -12.248f, -10.240f, -9.754f, -8.383f, -8.503f, -8.109f, -6.376f, -6.149f, + -5.758f, -4.098f, -1.867f, -6.142f, -5.067f, -3.904f, -4.794f, -4.077f, -4.724f, + -4.003f, -3.289f, -2.586f, -0.638f, 2.026f, 1.800f, 3.444f, 6.107f, 8.821f, + 12.836f, 15.611f, 14.950f, 14.710f, 15.945f, 17.338f, 17.209f, 15.286f, 14.371f, + 13.606f}, + {-29.534f, -28.406f, -24.589f, -20.304f, -15.180f, -10.348f, -6.806f, -3.474f, 0.823f, + 4.711f, 7.034f, 7.301f, 8.316f, 10.174f, 10.902f, 11.734f, 17.049f, 21.297f, + 19.888f, 21.168f, 25.164f, 27.067f, 29.707f, 28.838f, 26.255f, 26.579f, 28.334f, + 29.442f, 30.160f, 31.015f, 31.533f, 32.606f, 33.731f, 34.518f, 35.142f, 35.702f, + 36.194f, 36.311f, 36.760f, 37.437f, 37.019f, 38.157f, 36.910f, 35.507f, 34.452f, + 33.032f, 32.414f, 31.511f, 29.947f, 28.514f, 27.316f, 25.890f, 24.864f, 24.321f, + 23.603f, 22.084f, 20.014f, 17.972f, 16.114f, 14.115f, 12.907f, 10.843f, 8.866f, + 5.264f, 1.781f, 0.282f, -1.384f, -3.805f, -6.084f, -8.413f, -11.214f, -14.763f, + -17.296f, -20.750f, -24.594f, -27.559f, -30.573f, -34.035f, -36.409f, -37.864f, -41.541f, + -46.356f, -49.918f, -53.394f, -56.312f, -58.929f, -61.316f, -63.870f, -65.759f, -67.162f, + -67.895f, -68.247f, -68.303f, -68.202f, -67.168f, -66.439f, -66.255f, -66.445f, -66.282f, + -66.464f, -65.982f, -64.518f, -63.030f, -61.532f, -59.694f, -58.007f, -56.370f, -54.604f, + -52.691f, -50.044f, -49.320f, -46.449f, -41.935f, -43.417f, -41.852f, -33.813f, -29.902f, + -27.200f, -24.686f, -22.419f, -21.522f, -21.080f, -20.511f, -20.548f, -21.111f, -22.110f, + -26.659f, -30.517f, -32.656f, -33.055f, -32.541f, -31.865f, -31.466f, -31.513f, -32.212f, + -31.597f, -31.004f, -30.329f, -28.782f, -26.508f, -24.280f, -22.740f, -20.747f, -18.637f, + -16.775f, -14.148f, -13.267f, -12.385f, -11.377f, -10.372f, -10.246f, -8.773f, -8.677f, + -8.116f, -6.056f, -3.810f, -6.034f, -6.610f, -4.993f, -4.995f, -5.141f, -5.818f, + -4.744f, -3.567f, -3.024f, -1.555f, 1.875f, 1.454f, 3.195f, 5.758f, 8.295f, + 12.274f, 14.989f, 14.705f, 14.455f, 15.724f, 17.266f, 17.177f, 15.233f, 14.344f, + 13.606f}, + {-29.534f, -28.415f, -24.646f, -20.467f, -15.332f, -10.374f, -6.767f, -3.458f, 0.637f, + 4.483f, 6.802f, 6.819f, 7.777f, 10.010f, 11.174f, 12.005f, 17.187f, 20.490f, + 19.930f, 22.512f, 25.997f, 27.915f, 29.914f, 28.369f, 25.489f, 26.868f, 28.060f, + 29.221f, 29.721f, 30.522f, 31.005f, 32.145f, 33.514f, 34.612f, 34.889f, 35.057f, + 35.660f, 35.416f, 36.435f, 36.892f, 36.254f, 37.578f, 36.299f, 35.228f, 33.691f, + 32.229f, 31.701f, 30.699f, 29.611f, 28.269f, 27.118f, 25.640f, 24.685f, 24.212f, + 23.667f, 21.994f, 20.030f, 17.881f, 15.414f, 13.261f, 11.565f, 10.856f, 8.164f, + 5.879f, 2.581f, 0.025f, -1.872f, -3.851f, -6.363f, -8.647f, -10.837f, -15.527f, + -18.318f, -22.023f, -25.701f, -29.020f, -32.281f, -35.799f, -39.375f, -42.434f, -45.841f, + -49.164f, -52.693f, -55.965f, -58.881f, -61.446f, -64.132f, -66.411f, -68.505f, -69.944f, + -70.659f, -70.696f, -70.859f, -70.592f, -69.779f, -69.969f, -70.300f, -70.376f, -70.401f, + -70.220f, -69.546f, -67.935f, -66.622f, -65.067f, -62.965f, -60.875f, -58.671f, -56.469f, + -53.931f, -51.555f, -49.920f, -47.575f, -45.088f, -46.487f, -44.948f, -35.657f, -30.625f, + -29.462f, -29.928f, -25.073f, -22.579f, -22.276f, -22.447f, -20.944f, -19.763f, -22.689f, + -28.253f, -32.541f, -34.579f, -33.985f, -33.778f, -33.389f, -33.087f, -32.424f, -33.639f, + -33.351f, -33.041f, -32.063f, -31.160f, -29.059f, -26.105f, -24.452f, -22.988f, -20.403f, + -18.135f, -16.641f, -15.605f, -14.352f, -13.345f, -12.226f, -10.953f, -10.205f, -10.157f, + -9.843f, -7.841f, -5.945f, -4.781f, -6.994f, -5.900f, -5.227f, -6.299f, -6.664f, + -5.248f, -3.772f, -3.340f, -2.202f, 1.333f, 1.240f, 2.947f, 5.247f, 7.842f, + 11.578f, 14.149f, 14.342f, 14.212f, 15.502f, 17.195f, 17.125f, 15.180f, 14.317f, + 13.606f}, + {-29.534f, -28.424f, -24.699f, -20.634f, -15.498f, -10.396f, -6.610f, -3.311f, 0.552f, + 4.176f, 6.226f, 6.358f, 7.123f, 9.121f, 11.197f, 12.566f, 17.387f, 20.279f, + 20.222f, 24.531f, 28.245f, 28.975f, 29.130f, 27.201f, 25.122f, 27.345f, 27.448f, + 28.618f, 29.187f, 30.259f, 30.769f, 31.394f, 33.034f, 34.565f, 35.009f, 34.817f, + 34.713f, 34.940f, 36.067f, 36.025f, 39.017f, 36.902f, 35.509f, 34.061f, 32.519f, + 31.766f, 31.117f, 30.275f, 29.225f, 27.792f, 26.726f, 25.680f, 24.600f, 24.153f, + 23.232f, 21.721f, 19.515f, 17.275f, 15.056f, 13.052f, 10.706f, 9.717f, 8.150f, + 5.713f, 2.206f, -0.229f, -2.259f, -4.206f, -6.762f, -9.062f, -11.834f, -15.071f, + -19.282f, -23.061f, -26.561f, -30.032f, -33.770f, -37.361f, -41.058f, -44.884f, -48.761f, + -51.964f, -55.208f, -58.472f, -61.426f, -64.283f, -66.604f, -68.682f, -70.516f, -72.331f, + -73.069f, -73.337f, -73.749f, -73.012f, -73.030f, -73.888f, -74.292f, -74.362f, -74.445f, + -73.666f, -72.476f, -71.236f, -69.774f, -68.254f, -66.332f, -64.095f, -61.704f, -59.246f, + -55.997f, -54.073f, -51.848f, -49.835f, -44.330f, -45.061f, -46.617f, -38.392f, -31.420f, + -31.147f, -31.677f, -26.919f, -23.818f, -23.435f, -23.572f, -20.618f, -19.935f, -22.433f, + -28.733f, -34.865f, -36.438f, -35.524f, -35.224f, -34.145f, -34.343f, -34.437f, -35.516f, + -35.144f, -34.793f, -33.883f, -32.600f, -30.523f, -28.266f, -26.237f, -24.566f, -22.538f, + -20.014f, -18.037f, -17.565f, -16.486f, -14.860f, -14.043f, -12.961f, -11.016f, -10.621f, + -10.584f, -9.891f, -7.771f, -4.423f, -5.956f, -6.602f, -5.890f, -6.987f, -6.924f, + -5.580f, -4.152f, -3.609f, -2.761f, 0.595f, 1.220f, 2.559f, 4.554f, 7.401f, + 10.840f, 13.202f, 13.870f, 13.986f, 15.284f, 17.122f, 17.049f, 15.126f, 14.289f, + 13.606f}, + {-29.534f, -28.432f, -24.750f, -20.802f, -15.672f, -10.421f, -6.361f, -3.045f, 0.590f, + 3.835f, 5.363f, 5.876f, 6.591f, 7.996f, 10.727f, 13.037f, 17.572f, 20.322f, + 20.844f, 25.311f, 28.418f, 28.762f, 27.787f, 25.926f, 25.098f, 26.894f, 27.034f, + 27.933f, 28.472f, 30.071f, 30.787f, 31.622f, 31.695f, 35.147f, 35.900f, 34.803f, + 34.485f, 34.963f, 35.722f, 36.296f, 40.417f, 37.221f, 35.875f, 34.420f, 32.599f, + 31.719f, 30.575f, 29.680f, 28.472f, 27.265f, 26.086f, 25.429f, 24.267f, 23.430f, + 22.513f, 20.862f, 18.663f, 16.527f, 14.397f, 12.566f, 10.397f, 8.795f, 7.018f, + 5.676f, 1.571f, -0.369f, -2.692f, -5.103f, -7.340f, -9.798f, -12.470f, -15.599f, + -19.575f, -23.803f, -27.052f, -30.944f, -34.713f, -38.454f, -42.413f, -46.935f, -50.510f, + -54.322f, -57.743f, -60.974f, -63.940f, -66.487f, -68.608f, -71.032f, -72.385f, -74.307f, + -75.251f, -76.030f, -76.114f, -75.838f, -76.534f, -77.502f, -77.914f, -78.331f, -78.395f, + -77.371f, -75.927f, -74.607f, -72.989f, -71.152f, -69.349f, -67.039f, -64.629f, -61.718f, + -58.480f, -56.451f, -54.730f, -54.943f, -48.811f, -47.295f, -48.091f, -41.995f, -34.822f, + -31.304f, -32.248f, -29.554f, -26.990f, -24.546f, -24.324f, -22.565f, -20.648f, -22.129f, + -29.555f, -36.736f, -37.720f, -37.030f, -36.392f, -35.673f, -35.459f, -36.990f, -37.186f, + -36.529f, -36.224f, -34.726f, -32.839f, -30.976f, -29.175f, -26.983f, -24.927f, -23.666f, + -22.007f, -19.885f, -18.647f, -17.811f, -16.484f, -15.438f, -14.554f, -13.161f, -11.395f, + -11.199f, -11.341f, -9.810f, -6.297f, -4.716f, -6.502f, -6.551f, -7.150f, -7.006f, + -5.843f, -4.618f, -3.797f, -3.273f, -0.093f, 1.316f, 2.020f, 3.832f, 6.917f, + 10.160f, 12.306f, 13.334f, 13.778f, 15.076f, 17.044f, 16.947f, 15.071f, 14.261f, + 13.606f}, + {-29.534f, -28.441f, -24.798f, -20.966f, -15.851f, -10.455f, -6.076f, -2.713f, 0.734f, + 3.573f, 4.537f, 5.396f, 6.270f, 7.228f, 9.787f, 13.078f, 17.679f, 20.175f, + 21.135f, 24.598f, 26.014f, 27.239f, 27.410f, 25.550f, 24.751f, 25.858f, 26.748f, + 27.459f, 28.068f, 29.988f, 30.894f, 31.873f, 31.460f, 35.205f, 35.759f, 34.504f, + 34.692f, 34.744f, 35.478f, 36.892f, 38.728f, 37.607f, 38.627f, 36.351f, 33.113f, + 31.433f, 30.188f, 29.515f, 28.296f, 27.057f, 25.743f, 24.954f, 23.828f, 22.531f, + 21.528f, 19.805f, 17.688f, 15.577f, 13.779f, 11.869f, 10.019f, 7.918f, 6.725f, + 4.699f, 1.150f, -1.022f, -3.406f, -6.013f, -8.099f, -10.716f, -13.281f, -16.593f, + -20.533f, -24.431f, -28.243f, -31.671f, -35.715f, -39.403f, -43.757f, -47.531f, -52.376f, + -55.945f, -59.558f, -62.831f, -65.977f, -68.638f, -70.540f, -72.950f, -74.757f, -76.592f, + -77.714f, -78.475f, -78.510f, -78.772f, -80.003f, -80.808f, -81.514f, -81.949f, -81.463f, + -80.411f, -79.219f, -77.756f, -76.135f, -74.228f, -71.915f, -69.878f, -67.349f, -64.314f, + -62.168f, -58.375f, -55.696f, -55.463f, -52.291f, -47.217f, -45.091f, -43.167f, -40.145f, + -35.150f, -31.644f, -29.549f, -27.914f, -25.586f, -24.547f, -23.979f, -22.493f, -22.262f, + -30.333f, -38.386f, -37.727f, -37.701f, -36.927f, -37.067f, -38.570f, -39.174f, -38.430f, + -37.686f, -37.407f, -35.306f, -32.781f, -31.142f, -29.287f, -27.052f, -24.892f, -23.915f, + -23.379f, -21.625f, -20.439f, -19.234f, -17.962f, -16.568f, -15.924f, -15.035f, -13.040f, + -11.661f, -11.872f, -10.880f, -8.476f, -5.011f, -5.810f, -7.092f, -7.573f, -7.262f, + -6.165f, -4.914f, -3.925f, -3.738f, -0.728f, 1.293f, 1.435f, 3.283f, 6.383f, + 9.593f, 11.601f, 12.798f, 13.583f, 14.886f, 16.958f, 16.819f, 15.014f, 14.232f, + 13.606f}, + {-29.534f, -28.449f, -24.844f, -21.123f, -16.032f, -10.507f, -5.831f, -2.394f, 0.942f, + 3.487f, 4.084f, 5.006f, 6.006f, 6.867f, 8.671f, 12.328f, 17.287f, 20.103f, + 20.365f, 23.005f, 23.767f, 25.155f, 26.605f, 24.384f, 23.879f, 25.468f, 26.443f, + 26.874f, 27.951f, 29.668f, 31.114f, 32.050f, 31.544f, 34.708f, 34.776f, 34.459f, + 35.050f, 34.734f, 35.433f, 36.552f, 36.915f, 39.246f, 39.492f, 37.503f, 33.973f, + 31.094f, 29.887f, 29.118f, 28.072f, 26.829f, 25.641f, 24.544f, 23.177f, 21.717f, + 20.344f, 18.570f, 16.586f, 14.734f, 12.914f, 11.088f, 9.234f, 7.283f, 5.839f, + 2.612f, 1.254f, -1.856f, -4.278f, -6.806f, -9.102f, -11.652f, -14.697f, -18.243f, + -21.950f, -25.875f, -29.485f, -33.110f, -37.382f, -41.621f, -45.736f, -49.732f, -53.601f, + -57.902f, -61.203f, -64.643f, -67.615f, -70.731f, -73.041f, -74.888f, -76.814f, -78.248f, + -79.801f, -80.621f, -81.418f, -82.346f, -83.452f, -84.405f, -85.232f, -85.344f, -84.643f, + -83.778f, -82.622f, -80.844f, -79.290f, -77.341f, -74.804f, -72.649f, -70.499f, -68.789f, + -65.639f, -60.000f, -57.496f, -56.639f, -53.072f, -47.641f, -45.599f, -43.307f, -42.045f, + -40.412f, -37.913f, -34.236f, -28.073f, -24.571f, -25.167f, -22.814f, -22.108f, -22.593f, + -31.195f, -41.053f, -39.003f, -35.789f, -37.644f, -39.786f, -40.653f, -40.963f, -38.778f, + -38.404f, -38.345f, -36.333f, -33.878f, -32.077f, -30.437f, -28.305f, -26.004f, -24.672f, + -24.347f, -22.553f, -21.656f, -20.969f, -19.876f, -18.011f, -17.298f, -16.775f, -15.481f, + -13.026f, -12.322f, -11.423f, -9.751f, -6.683f, -6.006f, -7.696f, -8.217f, -7.611f, + -6.609f, -5.152f, -4.125f, -4.100f, -1.443f, 0.914f, 0.905f, 2.968f, 5.827f, + 9.124f, 11.148f, 12.321f, 13.394f, 14.719f, 16.861f, 16.666f, 14.956f, 14.203f, + 13.606f}, + {-29.534f, -28.457f, -24.890f, -21.271f, -16.214f, -10.584f, -5.697f, -2.163f, 1.177f, + 3.589f, 4.101f, 4.784f, 5.574f, 6.454f, 7.747f, 10.875f, 15.811f, 19.378f, + 18.463f, 20.594f, 21.996f, 23.377f, 25.172f, 23.327f, 23.598f, 25.441f, 26.392f, + 26.470f, 27.743f, 29.222f, 30.761f, 31.904f, 30.639f, 34.497f, 34.252f, 34.616f, + 35.102f, 34.779f, 34.815f, 36.258f, 38.766f, 41.023f, 39.952f, 37.447f, 33.991f, + 31.032f, 29.842f, 28.729f, 27.702f, 26.444f, 25.343f, 23.759f, 22.296f, 20.675f, + 18.963f, 17.353f, 15.501f, 13.747f, 12.028f, 10.196f, 8.305f, 6.418f, 4.155f, + 2.626f, 0.280f, -2.981f, -5.259f, -7.693f, -10.322f, -13.052f, -16.483f, -20.005f, + -23.704f, -27.691f, -31.793f, -35.661f, -39.920f, -43.991f, -48.372f, -52.124f, -56.221f, + -60.128f, -62.785f, -66.058f, -69.343f, -72.066f, -74.815f, -77.136f, -79.058f, -81.066f, + -82.858f, -84.430f, -85.488f, -86.080f, -86.821f, -87.594f, -88.455f, -88.703f, -87.775f, + -86.666f, -85.465f, -84.018f, -82.157f, -80.134f, -77.860f, -75.999f, -74.046f, -70.885f, + -66.248f, -63.010f, -61.190f, -58.235f, -53.737f, -49.893f, -46.474f, -44.504f, -43.799f, + -44.913f, -43.812f, -42.389f, -33.607f, -26.396f, -26.242f, -25.638f, -23.493f, -25.435f, + -31.830f, -43.533f, -43.407f, -34.652f, -39.394f, -42.159f, -42.861f, -42.406f, -37.526f, + -39.489f, -38.825f, -37.444f, -34.799f, -32.516f, -31.133f, -28.706f, -27.101f, -26.043f, + -25.932f, -23.650f, -22.806f, -22.212f, -21.363f, -19.533f, -18.225f, -18.349f, -16.786f, + -14.412f, -13.143f, -12.695f, -11.018f, -8.499f, -7.484f, -8.387f, -8.623f, -7.986f, + -6.958f, -5.601f, -4.434f, -4.270f, -2.226f, 0.129f, 0.432f, 2.765f, 5.276f, + 8.696f, 10.917f, 11.934f, 13.203f, 14.577f, 16.751f, 16.491f, 14.895f, 14.172f, + 13.606f}, + {-29.534f, -28.465f, -24.936f, -21.409f, -16.395f, -10.692f, -5.726f, -2.070f, 1.415f, + 3.802f, 4.402f, 4.726f, 4.947f, 5.667f, 7.174f, 9.537f, 13.555f, 16.814f, + 16.034f, 17.634f, 19.505f, 22.010f, 24.343f, 24.053f, 23.653f, 25.001f, 25.890f, + 26.063f, 27.460f, 28.546f, 30.025f, 31.076f, 30.885f, 34.665f, 33.758f, 34.590f, + 34.790f, 34.472f, 34.481f, 34.726f, 40.635f, 40.841f, 39.764f, 36.487f, 33.090f, + 31.044f, 29.672f, 28.211f, 27.095f, 25.819f, 24.268f, 22.774f, 21.208f, 19.429f, + 17.784f, 16.190f, 14.508f, 12.790f, 11.021f, 9.108f, 7.224f, 5.285f, 3.327f, + 1.202f, -1.186f, -3.664f, -6.092f, -8.833f, -11.673f, -14.796f, -18.361f, -22.083f, + -26.224f, -30.315f, -33.873f, -38.139f, -42.391f, -46.242f, -50.715f, -54.883f, -58.556f, + -62.578f, -66.486f, -69.138f, -71.826f, -74.809f, -77.452f, -80.037f, -82.503f, -84.633f, + -86.464f, -87.922f, -88.925f, -89.755f, -90.374f, -90.636f, -91.200f, -91.251f, -90.622f, + -89.697f, -88.392f, -86.679f, -84.945f, -82.865f, -80.715f, -79.147f, -75.460f, -72.083f, + -68.966f, -67.359f, -62.673f, -57.019f, -54.026f, -50.987f, -47.965f, -46.268f, -45.315f, + -43.454f, -42.497f, -38.997f, -33.051f, -30.810f, -31.090f, -28.802f, -27.769f, -28.757f, + -35.111f, -44.904f, -44.447f, -35.885f, -41.347f, -44.226f, -42.807f, -42.090f, -38.966f, + -40.640f, -41.152f, -38.778f, -36.149f, -33.993f, -32.380f, -29.865f, -28.287f, -27.317f, + -26.649f, -24.799f, -24.007f, -23.497f, -22.432f, -20.797f, -19.766f, -19.357f, -17.749f, + -15.634f, -14.125f, -13.421f, -12.368f, -10.276f, -9.148f, -9.235f, -8.946f, -8.366f, + -7.054f, -6.139f, -4.736f, -4.328f, -2.912f, -0.877f, -0.034f, 2.496f, 4.746f, + 8.264f, 10.823f, 11.635f, 13.003f, 14.456f, 16.625f, 16.299f, 14.833f, 14.142f, + 13.606f}, + {-29.534f, -28.473f, -24.983f, -21.536f, -16.576f, -10.834f, -5.935f, -2.138f, 1.647f, + 4.039f, 4.700f, 4.739f, 4.356f, 4.757f, 6.777f, 9.040f, 11.863f, 13.560f, + 14.086f, 15.436f, 17.281f, 20.298f, 22.967f, 24.598f, 22.641f, 23.894f, 25.203f, + 25.628f, 27.109f, 28.306f, 29.355f, 29.980f, 30.377f, 33.934f, 33.472f, 34.721f, + 34.691f, 34.373f, 34.520f, 37.729f, 39.925f, 40.075f, 38.559f, 35.680f, 32.677f, + 30.883f, 28.999f, 27.450f, 26.301f, 24.875f, 23.221f, 21.511f, 20.014f, 18.168f, + 16.588f, 15.041f, 13.503f, 11.646f, 9.853f, 8.036f, 6.075f, 4.102f, 1.972f, + 0.004f, -2.068f, -4.669f, -7.565f, -10.581f, -13.717f, -16.964f, -20.596f, -24.515f, + -28.970f, -33.042f, -36.947f, -40.756f, -44.822f, -48.869f, -52.695f, -56.778f, -60.861f, + -64.217f, -68.849f, -72.612f, -75.750f, -78.454f, -81.139f, -83.794f, -85.890f, -87.840f, + -89.475f, -91.154f, -92.300f, -92.512f, -93.199f, -93.885f, -93.826f, -93.588f, -93.254f, + -92.292f, -91.153f, -89.554f, -87.879f, -85.671f, -83.279f, -80.708f, -77.830f, -74.583f, + -71.990f, -65.318f, -60.900f, -56.819f, -53.999f, -51.755f, -48.264f, -45.884f, -45.309f, + -45.257f, -44.794f, -44.844f, -38.805f, -37.340f, -39.525f, -36.855f, -34.988f, -32.439f, + -28.764f, -38.518f, -40.601f, -36.376f, -41.082f, -41.211f, -40.121f, -39.620f, -41.208f, + -42.372f, -41.463f, -39.414f, -38.290f, -35.462f, -33.374f, -31.199f, -29.108f, -27.833f, + -27.310f, -26.277f, -25.238f, -24.844f, -23.780f, -22.254f, -21.313f, -20.278f, -19.060f, + -16.973f, -14.992f, -14.057f, -13.434f, -11.727f, -10.591f, -10.126f, -9.252f, -8.741f, + -7.215f, -6.468f, -4.953f, -4.521f, -3.400f, -1.811f, -0.493f, 2.111f, 4.259f, + 7.837f, 10.773f, 11.398f, 12.790f, 14.351f, 16.483f, 16.094f, 14.768f, 14.110f, + 13.606f}, + {-29.534f, -28.482f, -25.032f, -21.653f, -16.757f, -11.014f, -6.307f, -2.357f, 1.860f, + 4.271f, 4.848f, 4.729f, 4.060f, 4.241f, 6.298f, 9.082f, 11.604f, 12.126f, + 13.190f, 15.005f, 16.600f, 18.604f, 20.945f, 24.511f, 21.669f, 22.601f, 24.386f, + 25.082f, 26.401f, 27.791f, 28.686f, 29.534f, 29.902f, 34.281f, 33.428f, 34.716f, + 34.780f, 34.880f, 36.712f, 38.602f, 37.367f, 37.643f, 37.248f, 34.536f, 32.011f, + 30.334f, 28.548f, 26.683f, 25.165f, 23.513f, 21.989f, 20.140f, 18.612f, 16.937f, + 15.364f, 14.032f, 12.243f, 10.576f, 8.645f, 6.926f, 4.869f, 2.970f, 0.890f, + -1.160f, -3.549f, -6.458f, -9.446f, -12.647f, -15.912f, -19.309f, -23.174f, -27.167f, + -31.127f, -35.284f, -39.509f, -43.409f, -47.458f, -51.339f, -54.955f, -58.338f, -62.613f, + -65.920f, -69.460f, -72.743f, -77.224f, -81.347f, -84.177f, -86.605f, -89.003f, -90.757f, + -92.225f, -94.021f, -95.032f, -95.469f, -95.854f, -96.013f, -96.194f, -95.538f, -95.302f, + -94.383f, -93.025f, -90.716f, -89.004f, -86.694f, -84.267f, -82.164f, -79.894f, -77.417f, + -70.406f, -66.701f, -63.904f, -59.089f, -55.971f, -53.305f, -49.365f, -46.248f, -44.602f, + -45.221f, -47.560f, -50.233f, -49.334f, -48.384f, -44.747f, -45.377f, -41.624f, -35.427f, + -28.397f, -32.662f, -33.433f, -35.348f, -41.576f, -45.270f, -35.959f, -41.338f, -42.449f, + -43.149f, -41.864f, -41.348f, -39.856f, -36.505f, -33.878f, -32.063f, -30.187f, -28.770f, + -28.492f, -27.369f, -26.546f, -26.358f, -24.957f, -23.659f, -22.815f, -21.285f, -19.989f, + -18.181f, -15.897f, -15.061f, -14.389f, -12.898f, -12.200f, -10.768f, -9.502f, -9.232f, + -7.682f, -6.646f, -5.153f, -4.915f, -3.756f, -2.451f, -0.893f, 1.710f, 3.864f, + 7.469f, 10.704f, 11.186f, 12.566f, 14.253f, 16.326f, 15.882f, 14.702f, 14.079f, + 13.606f}, + {-29.534f, -28.491f, -25.084f, -21.762f, -16.943f, -11.234f, -6.795f, -2.701f, 2.026f, + 4.534f, 4.928f, 4.691f, 4.081f, 4.279f, 5.785f, 8.832f, 12.237f, 12.787f, + 12.875f, 15.614f, 16.860f, 17.546f, 19.615f, 24.084f, 21.261f, 21.552f, 23.367f, + 24.683f, 25.786f, 26.882f, 27.693f, 29.010f, 29.777f, 33.774f, 33.431f, 34.097f, + 35.283f, 36.818f, 38.256f, 37.949f, 36.646f, 35.523f, 34.764f, 33.235f, 31.159f, + 29.593f, 27.749f, 25.601f, 24.169f, 22.365f, 20.575f, 18.954f, 17.336f, 15.758f, + 14.304f, 12.746f, 11.063f, 9.343f, 7.675f, 5.632f, 3.785f, 1.655f, -0.307f, + -2.365f, -5.120f, -8.062f, -11.358f, -14.431f, -17.892f, -21.577f, -25.322f, -29.302f, + -33.414f, -37.874f, -42.311f, -46.454f, -50.472f, -54.356f, -58.173f, -61.689f, -64.980f, + -68.528f, -71.883f, -74.282f, -75.888f, -81.293f, -86.235f, -88.816f, -91.174f, -93.646f, + -94.834f, -95.748f, -96.847f, -97.549f, -97.639f, -97.416f, -97.153f, -96.805f, -96.303f, + -95.497f, -93.524f, -91.519f, -89.614f, -87.515f, -86.018f, -83.718f, -80.491f, -75.545f, + -71.170f, -68.752f, -65.377f, -60.783f, -57.688f, -54.922f, -50.827f, -47.997f, -45.578f, + -44.019f, -46.960f, -49.338f, -49.078f, -46.857f, -43.488f, -47.382f, -47.769f, -37.133f, + -30.462f, -29.737f, -30.305f, -33.004f, -40.162f, -49.216f, -37.686f, -41.383f, -44.147f, + -43.542f, -42.586f, -42.375f, -40.696f, -37.682f, -34.528f, -33.383f, -31.389f, -30.328f, + -29.727f, -28.826f, -28.256f, -27.857f, -25.765f, -25.117f, -23.718f, -22.641f, -21.209f, + -19.272f, -16.896f, -16.102f, -15.571f, -14.186f, -13.357f, -11.174f, -9.822f, -9.726f, + -8.104f, -6.947f, -5.446f, -5.296f, -4.108f, -2.754f, -1.201f, 1.422f, 3.624f, + 7.220f, 10.595f, 10.974f, 12.336f, 14.150f, 16.155f, 15.668f, 14.633f, 14.046f, + 13.606f}, + {-29.534f, -28.500f, -25.139f, -21.866f, -17.134f, -11.492f, -7.338f, -3.137f, 2.098f, + 4.860f, 5.116f, 4.700f, 4.182f, 4.484f, 5.520f, 8.187f, 12.853f, 13.938f, + 12.684f, 15.955f, 17.172f, 16.551f, 18.751f, 22.345f, 20.478f, 20.765f, 22.674f, + 24.381f, 25.176f, 26.512f, 27.264f, 29.285f, 29.941f, 32.355f, 32.876f, 34.087f, + 35.008f, 39.559f, 37.833f, 37.650f, 36.342f, 34.085f, 32.812f, 31.643f, 30.141f, + 28.582f, 26.893f, 24.777f, 23.046f, 21.343f, 19.529f, 17.683f, 16.190f, 14.732f, + 13.215f, 11.547f, 10.061f, 8.191f, 6.452f, 4.476f, 2.556f, 0.374f, -1.564f, + -3.956f, -6.934f, -9.925f, -13.000f, -16.837f, -19.852f, -23.260f, -27.280f, -31.321f, + -35.746f, -40.114f, -44.742f, -49.252f, -52.754f, -56.756f, -60.956f, -65.094f, -68.439f, + -72.126f, -75.880f, -78.078f, -80.454f, -83.587f, -86.799f, -90.089f, -91.856f, -93.275f, + -94.642f, -95.694f, -96.608f, -95.940f, -95.742f, -96.493f, -96.603f, -96.854f, -96.914f, + -96.137f, -94.693f, -93.106f, -91.923f, -89.494f, -86.512f, -82.569f, -79.735f, -77.433f, + -74.969f, -69.341f, -66.217f, -61.645f, -59.575f, -56.367f, -51.727f, -48.591f, -47.551f, + -46.081f, -46.767f, -48.075f, -47.274f, -44.757f, -43.307f, -47.395f, -44.306f, -34.622f, + -29.691f, -28.750f, -28.089f, -30.255f, -38.559f, -43.840f, -37.469f, -42.109f, -44.219f, + -44.265f, -43.603f, -42.797f, -40.858f, -38.577f, -35.251f, -34.543f, -33.224f, -32.085f, + -31.372f, -30.415f, -29.900f, -28.871f, -27.091f, -26.625f, -24.769f, -23.595f, -22.263f, + -20.015f, -17.919f, -17.129f, -16.582f, -14.973f, -13.598f, -11.525f, -10.018f, -9.888f, + -8.173f, -7.309f, -5.874f, -5.537f, -4.523f, -2.844f, -1.436f, 1.273f, 3.571f, + 7.100f, 10.444f, 10.750f, 12.109f, 14.035f, 15.975f, 15.458f, 14.563f, 14.014f, + 13.606f}, + {-29.534f, -28.509f, -25.199f, -21.966f, -17.333f, -11.788f, -7.880f, -3.633f, 2.026f, + 5.202f, 5.474f, 4.820f, 4.142f, 4.383f, 5.523f, 7.790f, 13.180f, 14.918f, + 13.058f, 15.918f, 17.131f, 15.714f, 17.999f, 20.211f, 19.544f, 20.408f, 22.228f, + 24.040f, 24.670f, 25.963f, 27.439f, 30.037f, 29.986f, 31.428f, 32.264f, 34.068f, + 34.994f, 39.101f, 38.156f, 36.648f, 34.971f, 33.315f, 31.818f, 30.650f, 29.335f, + 27.766f, 26.019f, 24.283f, 22.067f, 20.293f, 18.450f, 16.626f, 15.019f, 13.723f, + 12.017f, 10.513f, 8.727f, 7.052f, 5.307f, 3.378f, 1.229f, -0.796f, -3.124f, + -5.824f, -8.715f, -11.937f, -15.041f, -18.379f, -22.098f, -25.779f, -29.422f, -33.611f, + -38.203f, -42.181f, -46.389f, -50.716f, -54.522f, -58.712f, -62.773f, -67.165f, -71.149f, + -74.986f, -78.776f, -82.000f, -85.512f, -88.384f, -90.424f, -91.955f, -92.862f, -94.580f, + -96.448f, -97.359f, -98.589f, -99.221f, -99.614f, -99.858f, -100.164f, -99.836f, -99.150f, + -98.313f, -96.744f, -95.110f, -92.884f, -88.869f, -86.368f, -83.972f, -80.160f, -78.057f, + -74.023f, -70.083f, -65.973f, -62.870f, -59.764f, -56.508f, -52.574f, -48.107f, -47.504f, + -47.804f, -46.379f, -47.080f, -45.822f, -43.813f, -44.405f, -45.340f, -37.554f, -31.863f, + -31.038f, -29.454f, -27.635f, -29.660f, -34.735f, -37.570f, -35.984f, -43.775f, -44.839f, + -45.354f, -44.037f, -43.729f, -42.206f, -39.567f, -36.471f, -35.772f, -34.380f, -33.442f, + -32.882f, -31.903f, -30.729f, -29.430f, -28.427f, -27.600f, -25.861f, -23.776f, -22.341f, + -20.741f, -19.192f, -17.698f, -17.064f, -15.127f, -13.661f, -11.787f, -10.056f, -9.776f, + -8.061f, -7.456f, -6.381f, -5.766f, -4.995f, -2.906f, -1.616f, 1.181f, 3.661f, + 7.061f, 10.246f, 10.519f, 11.890f, 13.905f, 15.790f, 15.258f, 14.491f, 13.980f, + 13.606f}, + {-29.534f, -28.520f, -25.264f, -22.068f, -17.542f, -12.119f, -8.384f, -4.159f, + 1.778f, 5.415f, 5.846f, 5.005f, 3.989f, 3.948f, 5.423f, 7.870f, + 13.122f, 15.703f, 14.073f, 15.983f, 16.555f, 15.575f, 17.143f, 18.766f, + 18.768f, 20.261f, 21.979f, 23.597f, 24.293f, 25.627f, 27.431f, 30.188f, + 30.054f, 30.815f, 31.196f, 33.286f, 35.315f, 37.087f, 36.809f, 36.017f, + 32.970f, 32.152f, 30.860f, 29.752f, 28.695f, 26.795f, 25.194f, 23.571f, + 21.657f, 19.260f, 17.815f, 16.033f, 14.326f, 12.896f, 11.233f, 9.572f, + 7.869f, 6.243f, 4.358f, 2.376f, 0.150f, -2.217f, -5.122f, -7.874f, + -10.833f, -13.714f, -17.177f, -20.654f, -24.156f, -27.634f, -31.600f, -35.561f, + -39.610f, -44.051f, -47.815f, -52.013f, -56.258f, -60.499f, -64.475f, -68.567f, + -72.711f, -76.301f, -80.231f, -83.983f, -87.499f, -90.014f, -92.178f, -94.888f, + -97.331f, -99.292f, -100.316f, -100.195f, -100.405f, -101.016f, -101.100f, -100.931f, + -100.881f, -100.411f, -100.127f, -99.265f, -97.286f, -93.965f, -91.086f, -91.263f, + -87.689f, -83.478f, -80.389f, -76.942f, -74.598f, -70.413f, -66.722f, -63.495f, + -59.951f, -56.489f, -54.114f, -51.821f, -48.953f, -46.888f, -46.520f, -46.812f, + -46.482f, -46.259f, -46.328f, -40.425f, -32.337f, -28.435f, -29.518f, -30.646f, + -30.406f, -35.826f, -35.460f, -34.197f, -35.323f, -42.764f, -45.057f, -47.276f, + -46.005f, -44.721f, -42.898f, -39.997f, -37.843f, -37.636f, -35.686f, -35.140f, + -34.188f, -33.423f, -31.346f, -30.046f, -29.240f, -28.424f, -26.357f, -24.646f, + -22.791f, -21.271f, -20.223f, -18.438f, -17.195f, -15.191f, -13.799f, -11.920f, + -10.306f, -9.609f, -7.965f, -7.468f, -6.848f, -6.055f, -5.483f, -3.056f, + -1.721f, 1.069f, 3.780f, 7.025f, 9.989f, 10.284f, 11.683f, 13.763f, + 15.607f, 15.070f, 14.418f, 13.947f, 13.606f}, + {-29.534f, -28.530f, -25.334f, -22.173f, -17.764f, -12.480f, -8.835f, -4.684f, + 1.363f, 5.334f, 5.966f, 5.106f, 3.925f, 3.579f, 5.006f, 7.905f, + 12.438f, 15.562f, 14.791f, 15.942f, 16.086f, 15.836f, 16.553f, 18.085f, + 17.962f, 19.658f, 21.543f, 22.743f, 23.377f, 25.453f, 27.545f, 29.919f, + 30.303f, 30.445f, 30.547f, 32.694f, 34.395f, 35.364f, 36.174f, 33.405f, + 31.947f, 31.206f, 29.650f, 28.651f, 27.799f, 26.117f, 24.218f, 22.531f, + 20.927f, 19.053f, 17.010f, 15.721f, 14.022f, 12.232f, 10.609f, 8.644f, + 6.917f, 5.167f, 3.248f, 1.162f, -1.264f, -4.195f, -7.113f, -9.998f, + -13.126f, -15.990f, -19.136f, -22.696f, -26.447f, -29.931f, -33.478f, -37.169f, + -40.746f, -44.987f, -49.526f, -53.263f, -57.867f, -62.190f, -66.239f, -70.150f, + -74.022f, -77.828f, -81.512f, -85.192f, -88.267f, -91.128f, -93.285f, -96.114f, + -97.538f, -99.216f, -100.655f, -101.565f, -102.393f, -103.011f, -102.925f, -102.407f, + -101.900f, -100.994f, -100.049f, -96.143f, -95.019f, -92.344f, -89.960f, -87.666f, + -86.030f, -83.502f, -81.181f, -78.019f, -74.901f, -71.145f, -66.988f, -63.319f, + -60.767f, -57.424f, -54.535f, -53.563f, -53.479f, -50.292f, -48.456f, -48.775f, + -48.413f, -48.005f, -45.595f, -33.652f, -24.886f, -26.622f, -25.646f, -27.607f, + -33.390f, -46.759f, -40.597f, -34.429f, -37.045f, -41.620f, -45.960f, -48.466f, + -47.964f, -45.832f, -43.227f, -40.086f, -39.059f, -39.136f, -37.316f, -36.756f, + -35.672f, -34.104f, -32.492f, -30.761f, -29.887f, -29.185f, -27.510f, -26.411f, + -23.820f, -21.919f, -20.757f, -19.152f, -17.184f, -15.320f, -13.944f, -12.127f, + -10.707f, -9.396f, -8.018f, -7.701f, -7.210f, -6.269f, -5.953f, -3.277f, + -1.738f, 0.935f, 3.793f, 6.936f, 9.662f, 10.046f, 11.486f, 13.616f, + 15.431f, 14.897f, 14.344f, 13.913f, 13.606f}, + {-29.534f, -28.541f, -25.409f, -22.284f, -17.997f, -12.863f, -9.239f, -5.182f, + 0.827f, 4.882f, 5.675f, 4.977f, 4.024f, 3.572f, 4.593f, 7.553f, + 11.335f, 14.408f, 14.825f, 15.548f, 16.157f, 16.357f, 17.274f, 18.171f, + 16.601f, 18.853f, 20.987f, 21.970f, 22.498f, 24.762f, 27.268f, 29.398f, + 29.373f, 29.156f, 29.894f, 31.850f, 32.575f, 34.059f, 33.447f, 31.118f, + 30.801f, 29.932f, 28.567f, 27.599f, 26.563f, 25.237f, 23.217f, 21.652f, + 20.110f, 18.482f, 16.978f, 14.987f, 13.445f, 11.786f, 9.928f, 7.898f, + 5.871f, 4.019f, 1.970f, -0.446f, -3.066f, -5.981f, -9.161f, -12.129f, + -15.024f, -18.174f, -21.572f, -24.942f, -28.326f, -31.806f, -35.432f, -39.013f, + -42.361f, -46.062f, -50.089f, -54.290f, -58.988f, -63.670f, -67.669f, -71.483f, + -75.289f, -79.072f, -82.451f, -85.685f, -88.575f, -91.327f, -93.943f, -97.003f, + -99.249f, -100.363f, -102.115f, -102.842f, -103.651f, -104.203f, -104.153f, -103.421f, + -102.330f, -100.675f, -97.444f, -96.422f, -94.895f, -93.514f, -88.890f, -86.029f, + -85.011f, -84.855f, -83.222f, -79.440f, -74.634f, -71.781f, -67.450f, -63.312f, + -60.087f, -57.544f, -54.774f, -54.341f, -54.903f, -53.750f, -52.653f, -51.328f, + -50.196f, -43.521f, -35.361f, -26.721f, -24.580f, -22.993f, -21.173f, -28.377f, + -45.687f, -50.931f, -44.895f, -33.377f, -38.447f, -41.200f, -46.852f, -49.605f, + -50.145f, -47.223f, -42.905f, -39.911f, -40.304f, -40.157f, -38.662f, -37.776f, + -36.608f, -34.761f, -33.516f, -32.084f, -30.423f, -29.733f, -28.435f, -27.339f, + -24.810f, -22.578f, -20.799f, -19.320f, -17.229f, -15.350f, -14.119f, -12.448f, + -11.029f, -9.408f, -8.488f, -8.173f, -7.528f, -6.367f, -6.381f, -3.466f, + -1.753f, 0.817f, 3.623f, 6.790f, 9.280f, 9.792f, 11.294f, 13.476f, + 15.268f, 14.742f, 14.270f, 13.879f, 13.606f}, + {-29.534f, -28.553f, -25.490f, -22.404f, -18.243f, -13.260f, -9.619f, -5.633f, + 0.234f, 4.128f, 5.039f, 4.596f, 4.066f, 3.738f, 4.552f, 7.147f, + 10.425f, 13.471f, 14.800f, 15.302f, 15.966f, 16.910f, 18.076f, 18.209f, + 15.331f, 18.352f, 20.073f, 20.955f, 21.813f, 24.068f, 26.443f, 28.506f, + 28.211f, 28.538f, 28.632f, 29.646f, 30.598f, 32.463f, 30.418f, 30.182f, + 29.546f, 28.854f, 27.543f, 26.305f, 25.410f, 23.970f, 22.351f, 20.732f, + 19.184f, 17.702f, 16.356f, 15.332f, 13.903f, 11.393f, 9.156f, 6.909f, + 4.727f, 2.519f, 0.199f, -2.196f, -5.096f, -8.201f, -10.961f, -13.968f, + -17.206f, -20.050f, -23.341f, -26.980f, -30.466f, -33.549f, -36.989f, -40.781f, + -43.697f, -47.314f, -51.290f, -55.287f, -59.539f, -64.072f, -68.245f, -72.037f, + -75.933f, -79.821f, -83.344f, -86.095f, -89.255f, -91.830f, -94.456f, -97.266f, + -99.953f, -101.061f, -102.606f, -103.495f, -103.671f, -103.471f, -104.199f, -104.683f, + -104.391f, -103.329f, -99.427f, -96.784f, -95.356f, -94.476f, -91.113f, -86.507f, + -86.637f, -87.109f, -84.564f, -78.600f, -74.827f, -71.395f, -67.938f, -63.657f, + -59.243f, -59.244f, -56.334f, -56.079f, -56.740f, -56.664f, -56.283f, -54.544f, + -48.350f, -35.948f, -28.191f, -22.914f, -22.814f, -21.543f, -24.098f, -33.845f, + -51.503f, -51.701f, -46.389f, -35.203f, -37.837f, -42.067f, -47.365f, -49.227f, + -50.839f, -47.485f, -42.750f, -40.356f, -42.036f, -40.733f, -39.688f, -38.806f, + -37.688f, -35.316f, -34.049f, -33.379f, -31.605f, -30.890f, -28.780f, -27.079f, + -25.154f, -22.649f, -20.729f, -19.095f, -17.008f, -15.372f, -14.135f, -12.763f, + -11.458f, -9.968f, -9.335f, -8.596f, -7.854f, -6.522f, -6.698f, -3.552f, + -1.904f, 0.711f, 3.280f, 6.620f, 8.891f, 9.508f, 11.099f, 13.355f, + 15.121f, 14.603f, 14.196f, 13.844f, 13.606f}, + {-29.534f, -28.566f, -25.578f, -22.534f, -18.500f, -13.661f, -9.998f, -6.032f, + -0.360f, 3.246f, 4.297f, 4.072f, 3.748f, 3.642f, 4.686f, 6.998f, + 9.853f, 13.190f, 14.903f, 15.550f, 15.476f, 17.005f, 17.390f, 17.258f, + 15.066f, 17.561f, 18.829f, 19.718f, 21.539f, 23.817f, 25.559f, 27.395f, + 27.614f, 27.620f, 26.622f, 27.592f, 27.270f, 29.521f, 28.806f, 28.772f, + 28.746f, 27.886f, 26.542f, 25.296f, 23.975f, 22.882f, 21.402f, 19.760f, + 18.130f, 16.426f, 14.716f, 12.895f, 12.230f, 10.293f, 7.988f, 5.505f, + 3.123f, 0.710f, -1.787f, -4.443f, -7.187f, -10.026f, -13.213f, -15.734f, + -19.018f, -22.264f, -25.114f, -28.400f, -31.840f, -35.463f, -38.774f, -42.040f, + -45.475f, -49.028f, -52.292f, -56.278f, -60.039f, -64.044f, -68.371f, -72.151f, + -76.194f, -79.890f, -84.088f, -86.586f, -89.869f, -93.125f, -95.162f, -97.585f, + -100.841f, -101.820f, -102.894f, -103.375f, -103.521f, -103.920f, -106.377f, -106.594f, + -105.007f, -102.733f, -100.373f, -96.695f, -94.909f, -92.610f, -91.033f, -89.350f, + -88.954f, -88.429f, -84.568f, -79.833f, -75.037f, -71.625f, -68.392f, -64.448f, + -59.538f, -59.526f, -57.613f, -58.643f, -59.354f, -60.367f, -59.848f, -57.470f, + -39.381f, -24.372f, -24.592f, -24.100f, -23.665f, -22.266f, -25.302f, -41.784f, + -53.443f, -50.660f, -49.639f, -44.374f, -38.134f, -44.404f, -48.622f, -45.465f, + -50.705f, -48.448f, -43.253f, -42.327f, -43.609f, -41.551f, -40.504f, -39.259f, + -38.169f, -36.062f, -34.594f, -33.879f, -32.696f, -31.343f, -30.026f, -27.823f, + -25.472f, -23.072f, -21.002f, -18.871f, -17.202f, -15.908f, -14.382f, -13.125f, + -12.046f, -10.734f, -10.094f, -8.912f, -8.118f, -6.800f, -6.779f, -3.581f, + -2.244f, 0.560f, 2.846f, 6.449f, 8.561f, 9.178f, 10.898f, 13.261f, + 14.992f, 14.482f, 14.122f, 13.809f, 13.606f}, + {-29.534f, -28.579f, -25.671f, -22.674f, -18.767f, -14.059f, -10.393f, -6.391f, + -0.934f, 2.409f, 3.665f, 3.554f, 3.035f, 3.168f, 4.563f, 6.862f, + 9.313f, 12.669f, 14.703f, 15.783f, 15.575f, 16.694f, 16.210f, 15.949f, + 15.154f, 16.222f, 17.607f, 18.471f, 21.448f, 23.402f, 24.978f, 26.064f, + 26.029f, 26.045f, 24.397f, 24.737f, 24.432f, 28.346f, 28.041f, 27.789f, + 27.216f, 26.443f, 25.371f, 24.195f, 22.677f, 21.420f, 20.322f, 18.725f, + 16.990f, 15.111f, 13.083f, 11.149f, 9.000f, 8.000f, 6.040f, 3.632f, + 1.476f, -1.146f, -3.683f, -6.402f, -9.295f, -11.865f, -14.847f, -18.007f, + -20.456f, -23.636f, -27.100f, -30.194f, -33.493f, -36.952f, -40.365f, -43.723f, + -46.938f, -50.319f, -53.674f, -57.279f, -60.901f, -64.143f, -68.145f, -71.992f, + -75.940f, -79.066f, -83.273f, -85.663f, -89.854f, -92.927f, -93.944f, -97.704f, + -100.371f, -101.251f, -102.688f, -103.379f, -103.731f, -104.088f, -105.697f, -105.992f, + -100.427f, -96.745f, -96.020f, -96.065f, -96.033f, -93.495f, -93.008f, -91.754f, + -90.304f, -86.792f, -83.431f, -80.012f, -75.333f, -72.426f, -67.924f, -64.719f, + -60.325f, -57.911f, -58.451f, -59.528f, -61.135f, -63.189f, -62.844f, -55.211f, + -34.529f, -22.274f, -24.422f, -25.472f, -25.153f, -24.771f, -29.875f, -48.186f, + -53.771f, -51.457f, -55.718f, -54.184f, -38.815f, -46.672f, -49.422f, -40.262f, + -51.273f, -49.385f, -44.784f, -44.326f, -44.506f, -43.018f, -40.720f, -39.742f, + -38.552f, -36.263f, -34.834f, -33.986f, -33.395f, -32.186f, -30.595f, -28.865f, + -26.460f, -23.575f, -21.127f, -19.713f, -18.158f, -16.363f, -14.875f, -13.457f, + -12.638f, -11.288f, -10.519f, -9.200f, -8.273f, -7.042f, -6.579f, -3.689f, + -2.661f, 0.341f, 2.407f, 6.254f, 8.341f, 8.806f, 10.692f, 13.196f, + 14.879f, 14.375f, 14.049f, 13.774f, 13.606f}, + {-29.534f, -28.593f, -25.769f, -22.826f, -19.043f, -14.448f, -10.808f, -6.738f, + -1.493f, 1.697f, 3.200f, 3.117f, 2.226f, 2.648f, 4.267f, 6.493f, + 8.802f, 11.722f, 14.154f, 15.454f, 15.693f, 16.034f, 15.340f, 15.769f, + 15.559f, 15.099f, 16.275f, 17.818f, 21.185f, 22.913f, 24.978f, 24.948f, + 24.892f, 23.116f, 22.174f, 22.616f, 23.306f, 26.061f, 26.888f, 26.638f, + 25.744f, 25.083f, 24.121f, 22.838f, 21.599f, 20.177f, 18.988f, 17.719f, + 15.980f, 13.718f, 11.668f, 9.458f, 7.369f, 4.976f, 3.870f, 1.766f, + -0.583f, -2.900f, -5.633f, -8.328f, -10.725f, -14.099f, -16.538f, -19.400f, + -22.491f, -25.248f, -28.550f, -31.903f, -35.136f, -38.508f, -41.870f, -45.170f, + -48.543f, -51.754f, -54.814f, -58.202f, -61.641f, -64.909f, -68.484f, -71.584f, + -75.151f, -78.090f, -81.506f, -84.164f, -88.632f, -91.684f, -94.161f, -95.853f, + -98.091f, -100.094f, -101.659f, -102.479f, -103.170f, -103.570f, -104.791f, -104.557f, + -97.878f, -92.728f, -94.181f, -95.402f, -98.390f, -99.016f, -96.467f, -93.413f, + -91.541f, -87.762f, -81.124f, -77.210f, -74.971f, -69.934f, -66.904f, -64.695f, + -61.259f, -58.549f, -59.045f, -59.982f, -62.389f, -65.501f, -62.951f, -47.955f, + -29.347f, -24.246f, -26.369f, -26.804f, -26.402f, -26.351f, -32.950f, -50.722f, + -54.080f, -53.548f, -59.764f, -59.281f, -43.919f, -46.340f, -51.217f, -43.903f, + -50.321f, -49.042f, -45.989f, -44.907f, -45.320f, -43.185f, -41.037f, -40.239f, + -38.729f, -35.814f, -35.109f, -34.392f, -33.788f, -32.720f, -30.966f, -29.361f, + -26.996f, -23.725f, -21.568f, -20.565f, -18.652f, -16.460f, -15.165f, -13.744f, + -13.227f, -11.800f, -10.731f, -9.324f, -8.431f, -7.152f, -6.286f, -3.980f, + -2.990f, 0.119f, 2.005f, 5.984f, 8.236f, 8.406f, 10.486f, 13.157f, + 14.779f, 14.281f, 13.978f, 13.739f, 13.606f}, + {-29.534f, -28.609f, -25.873f, -22.988f, -19.326f, -14.825f, -11.237f, -7.110f, -2.057f, + 1.090f, 2.803f, 2.720f, 1.628f, 2.384f, 4.256f, 6.154f, 8.507f, 11.092f, + 13.472f, 14.663f, 14.979f, 15.169f, 14.600f, 15.847f, 15.744f, 14.286f, 15.388f, + 17.670f, 20.148f, 22.383f, 23.811f, 24.267f, 23.420f, 20.425f, 19.993f, 20.969f, + 23.514f, 23.963f, 25.051f, 25.058f, 24.308f, 23.703f, 22.919f, 21.685f, 20.287f, + 19.041f, 17.558f, 16.476f, 14.704f, 12.564f, 10.010f, 7.946f, 5.591f, 3.625f, + 1.250f, -0.546f, -2.420f, -4.881f, -7.167f, -10.097f, -12.697f, -15.449f, -18.616f, + -21.222f, -23.946f, -26.940f, -29.833f, -33.234f, -36.736f, -40.361f, -43.982f, -47.381f, + -50.202f, -53.864f, -56.627f, -58.918f, -62.035f, -65.321f, -68.765f, -72.030f, -75.116f, + -77.044f, -80.876f, -82.282f, -86.640f, -88.421f, -90.747f, -92.777f, -94.397f, -97.215f, + -98.650f, -100.444f, -101.749f, -101.675f, -102.643f, -102.563f, -100.330f, -95.258f, -95.360f, + -97.548f, -97.193f, -96.413f, -94.624f, -92.369f, -90.604f, -88.767f, -81.912f, -75.383f, + -71.740f, -68.186f, -65.169f, -64.220f, -62.138f, -59.873f, -58.692f, -60.398f, -63.860f, + -67.101f, -58.198f, -39.585f, -25.351f, -25.863f, -28.419f, -28.987f, -28.447f, -29.056f, + -33.279f, -50.618f, -54.972f, -57.462f, -61.506f, -61.212f, -52.277f, -47.930f, -51.426f, + -52.379f, -52.189f, -49.111f, -46.924f, -45.260f, -44.968f, -42.498f, -41.857f, -40.469f, + -38.750f, -36.092f, -35.492f, -34.998f, -34.415f, -33.045f, -31.535f, -29.383f, -27.362f, + -24.354f, -22.256f, -20.318f, -18.806f, -16.735f, -15.414f, -14.136f, -13.732f, -12.400f, + -10.879f, -9.324f, -8.699f, -7.232f, -6.206f, -4.432f, -3.193f, 0.004f, 1.630f, + 5.602f, 8.203f, 8.011f, 10.289f, 13.131f, 14.686f, 14.197f, 13.908f, 13.703f, + 13.606f}, + {-29.534f, -28.625f, -25.981f, -23.159f, -19.614f, -15.194f, -11.669f, -7.537f, -2.636f, + 0.526f, 2.340f, 2.267f, 1.208f, 2.221f, 4.495f, 6.120f, 8.254f, 10.718f, + 12.663f, 13.751f, 14.142f, 14.431f, 14.044f, 14.912f, 15.052f, 13.857f, 14.690f, + 16.950f, 18.693f, 21.089f, 22.486f, 22.552f, 20.692f, 18.639f, 19.405f, 20.362f, + 22.085f, 22.791f, 23.443f, 23.563f, 22.857f, 22.258f, 21.500f, 20.459f, 19.219f, + 17.807f, 16.325f, 14.821f, 13.343f, 11.134f, 8.780f, 6.402f, 4.327f, 1.849f, + -0.035f, -2.405f, -4.451f, -6.577f, -9.038f, -11.698f, -14.758f, -17.417f, -19.992f, + -22.866f, -25.401f, -28.305f, -31.246f, -34.617f, -38.051f, -41.484f, -44.970f, -48.575f, + -51.730f, -54.921f, -58.090f, -60.157f, -62.181f, -64.587f, -68.156f, -71.808f, -74.595f, + -76.902f, -79.614f, -81.274f, -85.750f, -86.704f, -87.372f, -88.249f, -92.159f, -94.597f, + -94.316f, -96.088f, -99.244f, -98.786f, -99.335f, -99.234f, -98.451f, -96.049f, -94.720f, + -95.126f, -94.583f, -93.372f, -91.575f, -89.610f, -87.959f, -86.696f, -84.028f, -77.989f, + -69.963f, -65.161f, -65.129f, -63.505f, -61.658f, -59.676f, -59.265f, -61.706f, -65.692f, + -67.279f, -54.532f, -33.954f, -25.539f, -28.396f, -28.678f, -30.403f, -30.333f, -31.544f, + -32.083f, -50.645f, -56.236f, -59.025f, -62.403f, -63.093f, -55.724f, -49.158f, -51.518f, + -55.944f, -50.515f, -47.988f, -50.292f, -46.057f, -43.563f, -41.964f, -42.836f, -40.519f, + -38.900f, -36.802f, -35.790f, -35.429f, -35.137f, -33.909f, -31.510f, -29.474f, -27.648f, + -24.501f, -22.198f, -20.095f, -18.600f, -16.644f, -15.538f, -14.442f, -14.014f, -12.878f, + -11.174f, -9.619f, -8.998f, -7.329f, -6.467f, -4.910f, -3.383f, 0.029f, 1.267f, + 5.132f, 8.165f, 7.652f, 10.112f, 13.102f, 14.594f, 14.120f, 13.841f, 13.668f, + 13.606f}, + {-29.534f, -28.642f, -26.093f, -23.337f, -19.907f, -15.563f, -12.093f, -8.034f, -3.221f, + -0.023f, 1.760f, 1.689f, 0.644f, 1.794f, 4.390f, 6.101f, 7.821f, 9.965f, + 11.781f, 12.910f, 13.633f, 13.767f, 13.483f, 14.283f, 14.204f, 13.782f, 13.780f, + 15.632f, 16.917f, 19.031f, 21.122f, 19.408f, 17.770f, 18.060f, 18.566f, 18.674f, + 20.247f, 21.838f, 21.984f, 21.961f, 21.615f, 20.809f, 20.000f, 19.034f, 17.933f, + 16.422f, 15.103f, 12.963f, 11.800f, 9.542f, 7.290f, 4.908f, 2.614f, 0.335f, + -1.815f, -4.008f, -6.212f, -8.350f, -10.537f, -13.177f, -16.027f, -19.007f, -21.714f, + -24.445f, -27.063f, -29.806f, -32.989f, -35.853f, -38.654f, -42.147f, -45.844f, -48.810f, + -52.921f, -55.990f, -58.782f, -61.165f, -63.915f, -66.038f, -67.672f, -70.094f, -73.546f, + -75.620f, -79.010f, -80.663f, -84.199f, -86.333f, -87.065f, -88.920f, -90.359f, -91.795f, + -92.866f, -94.863f, -95.477f, -95.019f, -95.041f, -94.691f, -95.080f, -93.747f, -92.422f, + -92.154f, -91.399f, -90.140f, -88.876f, -86.993f, -86.384f, -84.402f, -83.393f, -80.114f, + -72.082f, -66.734f, -63.041f, -61.861f, -60.037f, -57.256f, -58.115f, -62.252f, -66.131f, + -66.691f, -52.512f, -30.808f, -27.358f, -29.115f, -30.117f, -31.287f, -31.880f, -33.409f, + -34.294f, -46.258f, -56.227f, -60.476f, -64.040f, -64.547f, -55.741f, -50.684f, -52.265f, + -58.216f, -51.266f, -47.500f, -51.014f, -46.825f, -42.656f, -41.078f, -43.667f, -40.882f, + -39.503f, -36.790f, -36.134f, -35.895f, -35.737f, -34.184f, -31.569f, -29.458f, -27.473f, + -24.133f, -22.296f, -20.243f, -18.393f, -16.923f, -15.529f, -14.741f, -14.149f, -13.235f, + -11.717f, -10.279f, -9.215f, -7.329f, -6.911f, -5.271f, -3.663f, 0.086f, 0.949f, + 4.663f, 8.060f, 7.356f, 9.961f, 13.051f, 14.498f, 14.047f, 13.777f, 13.632f, + 13.606f}, + {-29.534f, -28.660f, -26.209f, -23.522f, -20.202f, -15.940f, -12.508f, -8.591f, -3.794f, + -0.535f, 1.109f, 0.995f, -0.264f, 1.104f, 3.813f, 5.714f, 7.365f, 9.032f, + 10.936f, 12.205f, 12.972f, 13.352f, 12.751f, 13.679f, 12.956f, 13.108f, 12.889f, + 14.044f, 14.710f, 16.793f, 17.385f, 16.276f, 16.031f, 17.056f, 17.623f, 18.855f, + 19.619f, 20.072f, 20.562f, 20.433f, 20.167f, 19.554f, 18.625f, 17.735f, 16.738f, + 15.029f, 13.448f, 11.994f, 9.918f, 7.955f, 5.847f, 3.435f, 0.927f, -1.362f, + -3.443f, -5.784f, -7.668f, -10.255f, -12.559f, -15.042f, -17.791f, -20.273f, -23.170f, + -25.974f, -28.869f, -31.823f, -34.489f, -36.997f, -39.330f, -42.350f, -46.734f, -50.051f, + -52.375f, -56.620f, -59.162f, -61.151f, -64.050f, -66.752f, -69.109f, -69.726f, -71.180f, + -73.913f, -76.652f, -78.333f, -81.078f, -83.290f, -84.832f, -86.689f, -87.100f, -88.198f, + -88.790f, -91.094f, -89.939f, -90.839f, -89.991f, -90.096f, -90.340f, -89.558f, -88.371f, + -87.797f, -87.744f, -87.543f, -86.623f, -86.170f, -86.147f, -83.145f, -81.195f, -80.167f, + -76.078f, -67.497f, -63.243f, -59.935f, -58.122f, -55.479f, -56.866f, -61.513f, -65.285f, + -65.446f, -45.210f, -29.278f, -27.751f, -30.055f, -30.807f, -32.015f, -33.522f, -34.941f, + -36.170f, -42.145f, -55.598f, -61.516f, -65.545f, -65.623f, -57.231f, -47.700f, -55.799f, + -62.579f, -55.777f, -46.718f, -51.400f, -44.366f, -42.506f, -41.060f, -43.476f, -41.629f, + -39.424f, -36.967f, -36.244f, -36.311f, -35.890f, -34.314f, -31.724f, -29.196f, -27.193f, + -24.964f, -23.282f, -20.859f, -19.244f, -17.693f, -15.541f, -15.199f, -14.307f, -13.651f, + -12.203f, -10.843f, -9.405f, -7.194f, -7.298f, -5.464f, -3.979f, 0.012f, 0.751f, + 4.292f, 7.871f, 7.135f, 9.839f, 12.965f, 14.392f, 13.977f, 13.715f, 13.596f, + 13.606f}, + {-29.534f, -28.679f, -26.327f, -23.710f, -20.500f, -16.335f, -12.922f, -9.179f, -4.351f, + -0.987f, 0.460f, 0.259f, -1.311f, 0.566f, 3.475f, 5.199f, 6.954f, 8.325f, + 10.020f, 11.446f, 12.170f, 12.977f, 11.622f, 11.753f, 11.886f, 12.074f, 11.921f, + 12.717f, 13.020f, 14.461f, 14.179f, 14.378f, 15.013f, 16.179f, 17.104f, 17.618f, + 18.182f, 18.849f, 18.995f, 18.937f, 18.680f, 18.084f, 17.368f, 16.385f, 15.154f, + 13.707f, 12.121f, 10.593f, 8.931f, 6.507f, 4.123f, 1.907f, -0.462f, -3.004f, + -5.446f, -7.066f, -9.063f, -11.144f, -14.254f, -16.759f, -19.158f, -21.920f, -24.485f, + -27.083f, -29.970f, -32.651f, -35.260f, -37.577f, -40.199f, -42.810f, -46.238f, -51.142f, + -53.684f, -55.878f, -58.227f, -58.473f, -62.724f, -65.451f, -68.310f, -69.609f, -70.130f, + -72.290f, -74.587f, -76.010f, -76.844f, -78.733f, -80.315f, -81.844f, -82.682f, -83.855f, + -84.087f, -85.904f, -84.754f, -85.108f, -85.797f, -85.521f, -85.422f, -84.724f, -84.462f, + -84.385f, -84.424f, -83.869f, -83.259f, -81.987f, -80.241f, -79.294f, -78.091f, -76.902f, + -73.910f, -70.040f, -63.900f, -60.191f, -57.708f, -56.099f, -56.403f, -60.552f, -64.377f, + -58.612f, -33.135f, -29.585f, -29.748f, -30.749f, -31.594f, -33.042f, -34.381f, -36.180f, + -37.038f, -39.287f, -54.727f, -62.565f, -66.515f, -65.011f, -60.244f, -48.976f, -61.163f, + -66.003f, -59.804f, -47.996f, -51.473f, -44.111f, -40.678f, -41.344f, -42.585f, -41.199f, + -39.369f, -37.657f, -35.772f, -36.106f, -35.460f, -34.527f, -32.116f, -29.373f, -27.108f, + -25.856f, -24.251f, -21.998f, -19.993f, -17.473f, -15.403f, -15.121f, -14.506f, -14.031f, + -12.408f, -11.172f, -9.644f, -7.061f, -7.509f, -5.525f, -4.183f, -0.270f, 0.739f, + 4.068f, 7.646f, 6.985f, 9.745f, 12.838f, 14.274f, 13.906f, 13.657f, 13.560f, + 13.606f}, + {-29.534f, -28.699f, -26.448f, -23.900f, -20.797f, -16.754f, -13.351f, -9.764f, -4.920f, + -1.419f, -0.163f, -0.436f, -2.057f, 0.415f, 3.802f, 5.041f, 6.302f, 7.415f, + 8.900f, 10.339f, 11.433f, 12.028f, 10.438f, 10.259f, 11.541f, 11.037f, 10.900f, + 11.503f, 11.717f, 12.448f, 12.410f, 13.239f, 14.895f, 15.799f, 15.951f, 16.575f, + 16.908f, 17.279f, 17.577f, 17.525f, 17.216f, 16.737f, 15.897f, 14.955f, 13.633f, + 11.994f, 10.618f, 9.099f, 7.486f, 5.433f, 2.412f, 0.031f, -2.337f, -4.607f, + -7.067f, -9.246f, -10.518f, -12.412f, -14.635f, -17.469f, -20.246f, -22.962f, -25.853f, + -27.385f, -29.256f, -32.194f, -35.087f, -37.736f, -39.941f, -42.582f, -44.813f, -48.436f, + -51.958f, -54.424f, -56.702f, -56.494f, -60.981f, -65.562f, -67.200f, -68.009f, -69.290f, + -70.215f, -72.293f, -73.424f, -74.666f, -75.978f, -76.313f, -77.253f, -78.327f, -79.340f, + -79.038f, -79.744f, -80.258f, -80.260f, -80.008f, -79.932f, -79.345f, -79.102f, -78.386f, + -78.312f, -78.984f, -78.802f, -78.702f, -78.061f, -76.977f, -76.026f, -75.051f, -73.326f, + -71.266f, -68.212f, -64.177f, -61.556f, -59.061f, -56.384f, -55.490f, -58.801f, -61.812f, + -51.090f, -28.944f, -30.098f, -29.613f, -31.252f, -33.294f, -34.369f, -35.753f, -37.262f, + -37.987f, -41.753f, -48.575f, -62.960f, -66.517f, -63.690f, -62.559f, -52.649f, -66.301f, + -66.743f, -60.752f, -53.042f, -48.907f, -41.840f, -41.105f, -40.050f, -41.911f, -40.131f, + -39.924f, -36.759f, -35.993f, -36.886f, -35.274f, -34.501f, -32.344f, -29.252f, -26.824f, + -25.567f, -24.776f, -22.899f, -20.612f, -17.539f, -15.709f, -14.474f, -14.452f, -14.197f, + -12.562f, -11.508f, -9.850f, -7.028f, -7.534f, -5.528f, -4.209f, -0.680f, 0.907f, + 3.965f, 7.470f, 6.891f, 9.674f, 12.672f, 14.146f, 13.833f, 13.603f, 13.524f, + 13.606f}, + {-29.534f, -28.720f, -26.570f, -24.092f, -21.093f, -17.199f, -13.808f, -10.321f, -5.552f, + -1.949f, -0.792f, -1.028f, -2.272f, 0.320f, 3.949f, 4.999f, 5.360f, 6.048f, + 7.625f, 8.991f, 10.539f, 11.248f, 10.449f, 10.332f, 10.358f, 9.740f, 9.729f, + 9.901f, 10.378f, 10.707f, 11.095f, 12.455f, 13.514f, 14.524f, 14.987f, 15.309f, + 15.781f, 15.919f, 16.070f, 16.047f, 15.782f, 15.206f, 14.507f, 13.468f, 12.009f, + 10.585f, 9.045f, 7.587f, 5.828f, 3.722f, 0.968f, -1.754f, -4.206f, -6.632f, + -8.902f, -11.047f, -12.963f, -14.676f, -16.050f, -17.747f, -20.848f, -24.535f, -27.622f, + -28.975f, -31.253f, -33.138f, -36.351f, -37.969f, -39.849f, -43.071f, -44.851f, -46.933f, + -48.115f, -50.991f, -54.180f, -56.433f, -59.502f, -62.766f, -64.865f, -66.674f, -68.168f, + -68.185f, -69.609f, -70.331f, -71.452f, -72.200f, -72.597f, -72.893f, -72.327f, -73.942f, + -73.734f, -73.607f, -73.433f, -73.787f, -73.093f, -73.424f, -73.350f, -73.673f, -73.229f, + -73.447f, -73.759f, -73.772f, -73.611f, -73.372f, -72.971f, -72.477f, -71.792f, -70.711f, + -68.947f, -66.755f, -62.245f, -59.326f, -58.274f, -57.152f, -56.283f, -56.245f, -57.767f, + -47.085f, -29.405f, -31.128f, -30.672f, -32.575f, -34.970f, -35.634f, -36.951f, -38.484f, + -39.180f, -41.822f, -44.649f, -62.850f, -66.297f, -61.901f, -62.445f, -61.991f, -63.653f, + -64.781f, -60.295f, -53.722f, -46.253f, -40.696f, -40.418f, -40.233f, -40.903f, -39.499f, + -38.345f, -35.433f, -37.458f, -37.855f, -36.073f, -35.011f, -33.008f, -30.168f, -27.062f, + -26.107f, -25.047f, -23.219f, -21.671f, -18.339f, -16.600f, -14.472f, -13.940f, -14.207f, + -12.746f, -11.712f, -9.946f, -7.065f, -7.416f, -5.533f, -4.148f, -1.049f, 1.160f, + 3.917f, 7.422f, 6.832f, 9.623f, 12.480f, 14.009f, 13.756f, 13.552f, 13.489f, + 13.606f}, + {-29.534f, -28.742f, -26.693f, -24.284f, -21.387f, -17.665f, -14.303f, -10.844f, -6.296f, + -2.714f, -1.481f, -1.508f, -2.155f, -0.221f, 2.697f, 4.186f, 4.513f, 4.995f, + 6.367f, 7.740f, 9.363f, 10.889f, 10.540f, 10.050f, 8.581f, 8.414f, 8.246f, + 8.273f, 8.882f, 9.378f, 9.921f, 11.582f, 12.509f, 13.477f, 13.930f, 14.196f, + 14.476f, 14.806f, 14.948f, 14.590f, 14.145f, 13.726f, 13.025f, 11.878f, 10.535f, + 9.019f, 7.618f, 5.988f, 4.178f, 1.857f, -0.579f, -3.485f, -6.035f, -8.367f, + -10.686f, -13.017f, -14.963f, -17.049f, -18.959f, -20.788f, -22.650f, -26.986f, -29.907f, + -32.160f, -34.191f, -36.310f, -38.332f, -40.835f, -43.515f, -45.955f, -47.915f, -50.584f, + -52.990f, -54.885f, -57.494f, -59.403f, -59.956f, -60.386f, -61.565f, -62.858f, -64.918f, + -64.730f, -65.591f, -65.317f, -65.851f, -67.237f, -66.335f, -67.477f, -67.706f, -67.460f, + -68.665f, -67.821f, -66.477f, -66.976f, -66.832f, -66.715f, -67.148f, -67.255f, -66.680f, + -66.764f, -67.568f, -68.168f, -68.605f, -68.505f, -68.510f, -68.520f, -68.078f, -67.155f, + -66.600f, -64.817f, -60.897f, -57.567f, -57.080f, -56.040f, -55.577f, -55.034f, -53.348f, + -41.015f, -28.662f, -33.225f, -32.911f, -34.387f, -37.120f, -37.045f, -37.959f, -39.462f, + -40.588f, -44.393f, -43.740f, -58.306f, -66.456f, -61.622f, -63.612f, -64.730f, -60.411f, + -61.271f, -57.507f, -51.441f, -42.643f, -42.176f, -40.808f, -39.613f, -38.987f, -39.231f, + -36.030f, -36.045f, -38.070f, -38.160f, -36.532f, -35.768f, -34.103f, -30.880f, -27.302f, + -26.615f, -24.889f, -23.117f, -22.042f, -18.805f, -17.244f, -15.374f, -13.437f, -14.112f, + -12.772f, -11.520f, -10.027f, -7.152f, -7.270f, -5.577f, -4.124f, -1.256f, 1.378f, + 3.884f, 7.525f, 6.791f, 9.588f, 12.283f, 13.868f, 13.676f, 13.504f, 13.453f, + 13.606f}, + {-29.534f, -28.765f, -26.817f, -24.475f, -21.676f, -18.142f, -14.834f, -11.351f, -7.168f, + -3.777f, -2.281f, -1.947f, -2.149f, -1.250f, 0.108f, 2.262f, 3.840f, 4.734f, + 5.443f, 6.633f, 8.244f, 10.021f, 9.412f, 8.843f, 7.539f, 7.069f, 6.643f, + 6.971f, 7.440f, 7.972f, 8.876f, 10.309f, 11.581f, 12.464f, 12.958f, 12.909f, + 13.224f, 13.459f, 13.818f, 13.274f, 12.701f, 12.225f, 11.368f, 10.333f, 8.965f, + 7.587f, 6.068f, 4.389f, 2.454f, 0.057f, -2.478f, -5.137f, -7.701f, -10.240f, + -12.370f, -14.755f, -16.892f, -19.087f, -21.134f, -22.974f, -25.197f, -28.527f, -30.985f, + -33.726f, -35.869f, -38.290f, -40.597f, -42.535f, -44.553f, -46.188f, -48.157f, -50.548f, + -52.858f, -54.458f, -56.264f, -57.770f, -59.499f, -61.013f, -62.739f, -64.579f, -64.511f, + -64.627f, -64.717f, -63.865f, -63.258f, -64.339f, -62.878f, -62.991f, -63.940f, -62.219f, + -63.236f, -61.227f, -60.768f, -60.329f, -60.266f, -60.384f, -59.782f, -60.389f, -61.782f, + -62.257f, -63.260f, -64.208f, -64.251f, -64.643f, -64.578f, -64.136f, -64.080f, -63.282f, + -63.089f, -62.929f, -59.527f, -57.172f, -56.594f, -55.710f, -55.421f, -53.810f, -50.152f, + -41.045f, -29.868f, -33.586f, -34.079f, -35.397f, -37.009f, -37.603f, -38.661f, -40.410f, + -41.855f, -46.144f, -48.307f, -55.482f, -66.646f, -62.497f, -63.023f, -63.018f, -60.805f, + -59.302f, -54.264f, -47.324f, -42.488f, -42.891f, -42.053f, -40.554f, -38.854f, -39.661f, + -36.801f, -37.582f, -38.184f, -38.174f, -37.227f, -36.827f, -33.911f, -30.248f, -27.699f, + -26.437f, -24.570f, -22.756f, -22.112f, -19.549f, -17.678f, -16.097f, -13.267f, -13.929f, + -12.769f, -11.233f, -10.167f, -7.311f, -7.223f, -5.675f, -4.157f, -1.307f, 1.501f, + 3.895f, 7.724f, 6.758f, 9.569f, 12.105f, 13.731f, 13.590f, 13.461f, 13.417f, + 13.606f}, + {-29.534f, -28.789f, -26.940f, -24.667f, -21.961f, -18.616f, -15.387f, -11.875f, -8.141f, + -5.072f, -3.231f, -2.509f, -2.584f, -2.354f, -2.446f, -0.044f, 2.869f, 4.479f, + 4.976f, 5.619f, 7.532f, 9.288f, 9.371f, 8.429f, 6.561f, 6.002f, 5.370f, + 5.717f, 5.877f, 6.314f, 7.954f, 9.244f, 10.469f, 11.290f, 11.682f, 11.624f, + 11.749f, 12.115f, 12.202f, 11.925f, 11.403f, 10.773f, 9.754f, 8.633f, 7.410f, + 6.042f, 4.412f, 2.726f, 0.570f, -1.691f, -4.329f, -6.885f, -9.557f, -12.104f, + -14.277f, -16.591f, -18.881f, -21.167f, -23.240f, -25.174f, -27.389f, -30.900f, -33.754f, + -35.786f, -37.697f, -39.487f, -41.520f, -43.418f, -45.113f, -46.229f, -48.077f, -50.698f, + -52.204f, -54.002f, -55.987f, -57.486f, -58.903f, -59.247f, -58.849f, -59.625f, -60.127f, + -60.204f, -60.815f, -61.285f, -60.956f, -60.455f, -60.124f, -59.037f, -58.985f, -58.800f, + -58.098f, -57.573f, -56.460f, -54.978f, -54.761f, -54.471f, -54.751f, -56.165f, -58.308f, + -61.180f, -62.916f, -63.484f, -63.154f, -62.259f, -61.807f, -61.180f, -60.969f, -60.626f, + -59.965f, -60.109f, -57.037f, -56.322f, -55.908f, -54.766f, -54.755f, -53.327f, -48.734f, + -41.830f, -31.230f, -32.946f, -34.914f, -35.605f, -36.794f, -37.614f, -39.473f, -41.277f, + -42.868f, -46.380f, -53.877f, -55.267f, -65.968f, -63.645f, -61.742f, -64.248f, -59.501f, + -56.896f, -52.931f, -43.082f, -44.317f, -44.376f, -42.360f, -42.360f, -39.808f, -40.864f, + -38.991f, -38.118f, -38.164f, -38.507f, -38.129f, -36.471f, -32.835f, -29.725f, -28.572f, + -26.711f, -24.256f, -22.492f, -22.444f, -19.825f, -17.891f, -15.785f, -12.903f, -13.960f, + -12.988f, -11.166f, -10.261f, -7.507f, -7.243f, -5.813f, -4.180f, -1.296f, 1.563f, + 4.025f, 7.898f, 6.731f, 9.566f, 11.967f, 13.602f, 13.499f, 13.420f, 13.381f, + 13.606f}, + {-29.534f, -28.814f, -27.063f, -24.859f, -22.241f, -19.072f, -15.939f, -12.451f, -9.156f, + -6.432f, -4.361f, -3.409f, -3.508f, -3.272f, -3.925f, -1.836f, 1.320f, 3.414f, + 4.485f, 4.635f, 6.818f, 9.056f, 10.036f, 7.997f, 4.893f, 5.134f, 4.411f, + 4.379f, 3.944f, 4.709f, 6.610f, 8.259f, 9.337f, 10.079f, 10.443f, 10.304f, + 10.534f, 10.581f, 10.875f, 10.520f, 10.033f, 9.372f, 8.208f, 7.046f, 5.768f, + 4.365f, 2.681f, 0.854f, -1.252f, -3.632f, -6.203f, -8.641f, -11.234f, -13.744f, + -16.009f, -18.332f, -20.591f, -22.854f, -24.988f, -26.878f, -29.799f, -32.543f, -34.630f, + -36.881f, -38.682f, -40.540f, -42.584f, -44.233f, -46.042f, -47.030f, -47.654f, -49.895f, + -52.137f, -52.747f, -54.070f, -55.467f, -56.458f, -57.125f, -58.389f, -57.311f, -58.132f, + -58.004f, -58.066f, -57.625f, -56.490f, -55.814f, -55.149f, -54.041f, -53.731f, -53.537f, + -53.021f, -52.372f, -51.324f, -51.071f, -51.390f, -52.405f, -55.418f, -57.735f, -58.099f, + -59.274f, -60.660f, -61.458f, -62.413f, -62.231f, -61.843f, -60.263f, -59.619f, -59.531f, + -59.214f, -59.613f, -54.920f, -54.493f, -54.064f, -53.780f, -54.879f, -52.344f, -48.416f, + -41.576f, -30.404f, -32.080f, -34.820f, -36.338f, -37.196f, -37.903f, -40.421f, -41.811f, + -43.899f, -50.425f, -58.643f, -56.105f, -64.378f, -62.515f, -62.519f, -64.079f, -57.950f, + -57.402f, -51.465f, -45.396f, -48.283f, -45.512f, -44.688f, -43.057f, -40.947f, -40.586f, + -39.502f, -38.104f, -37.862f, -38.611f, -37.879f, -35.182f, -32.147f, -29.991f, -28.934f, + -26.708f, -24.372f, -23.214f, -22.667f, -19.411f, -17.453f, -14.925f, -12.301f, -14.377f, + -13.323f, -11.083f, -10.214f, -7.675f, -7.162f, -5.973f, -4.167f, -1.304f, 1.648f, + 4.318f, 7.903f, 6.714f, 9.573f, 11.885f, 13.487f, 13.403f, 13.383f, 13.345f, + 13.606f}, + {-29.534f, -28.841f, -27.185f, -25.052f, -22.515f, -19.500f, -16.469f, -13.102f, -10.152f, + -7.681f, -5.664f, -4.774f, -4.773f, -4.189f, -4.599f, -3.008f, -0.453f, 1.832f, + 3.453f, 3.304f, 5.562f, 8.402f, 8.673f, 5.818f, 3.073f, 4.332f, 3.426f, + 3.156f, 2.045f, 3.084f, 5.102f, 6.990f, 8.368f, 8.983f, 9.209f, 8.969f, + 9.216f, 9.272f, 9.379f, 9.192f, 8.589f, 7.779f, 6.654f, 5.538f, 4.062f, + 2.679f, 0.900f, -0.996f, -3.081f, -5.457f, -8.068f, -10.661f, -13.284f, -15.660f, + -17.972f, -20.301f, -22.427f, -24.535f, -26.214f, -28.234f, -30.524f, -33.039f, -35.281f, + -37.625f, -39.574f, -41.438f, -43.090f, -44.781f, -46.381f, -47.666f, -48.362f, -48.777f, + -50.529f, -52.062f, -52.880f, -53.935f, -54.810f, -55.688f, -55.771f, -54.899f, -54.050f, + -54.541f, -53.551f, -52.139f, -50.942f, -50.417f, -49.342f, -47.802f, -47.166f, -46.726f, + -46.945f, -46.517f, -47.350f, -48.831f, -50.575f, -50.247f, -54.257f, -59.321f, -59.754f, + -60.868f, -63.776f, -62.827f, -61.683f, -61.107f, -60.054f, -62.015f, -61.373f, -60.017f, + -58.736f, -56.597f, -52.811f, -52.270f, -51.111f, -50.594f, -52.276f, -51.022f, -52.523f, + -47.324f, -34.348f, -31.179f, -34.209f, -36.569f, -37.888f, -38.754f, -40.838f, -42.509f, + -44.546f, -55.690f, -59.999f, -55.623f, -62.995f, -61.444f, -63.117f, -61.527f, -58.992f, + -56.688f, -49.932f, -47.476f, -49.441f, -47.181f, -45.649f, -43.464f, -41.972f, -40.442f, + -39.019f, -37.573f, -39.019f, -38.758f, -36.719f, -34.103f, -31.216f, -30.416f, -29.115f, + -26.873f, -25.379f, -24.639f, -22.729f, -19.500f, -16.751f, -14.673f, -12.297f, -14.740f, + -13.708f, -10.924f, -10.057f, -7.864f, -6.955f, -6.153f, -4.189f, -1.341f, 1.800f, + 4.732f, 7.637f, 6.711f, 9.585f, 11.864f, 13.388f, 13.300f, 13.347f, 13.310f, + 13.606f}, + {-29.534f, -28.868f, -27.306f, -25.247f, -22.787f, -19.894f, -16.965f, -13.832f, -11.100f, + -8.739f, -7.071f, -6.514f, -6.199f, -5.367f, -5.264f, -4.010f, -1.949f, 0.473f, + 2.071f, 1.407f, 4.112f, 7.689f, 7.123f, 4.065f, 1.329f, 3.927f, 2.726f, + 2.093f, 0.628f, 2.003f, 4.093f, 5.634f, 7.036f, 7.750f, 7.806f, 7.863f, + 7.996f, 8.052f, 7.982f, 7.702f, 7.157f, 6.262f, 5.030f, 3.695f, 2.436f, + 0.873f, -0.875f, -2.804f, -5.025f, -7.445f, -9.996f, -12.449f, -14.900f, -17.422f, + -19.728f, -21.928f, -24.146f, -26.538f, -28.135f, -28.100f, -31.466f, -33.458f, -36.454f, + -38.700f, -40.431f, -42.100f, -43.217f, -44.779f, -46.285f, -47.488f, -48.712f, -50.001f, + -49.997f, -49.333f, -51.527f, -52.650f, -52.663f, -52.752f, -52.296f, -51.591f, -51.876f, + -49.877f, -49.846f, -48.453f, -47.612f, -45.640f, -43.999f, -42.601f, -41.872f, -40.566f, + -39.827f, -40.257f, -43.444f, -44.285f, -44.418f, -49.277f, -52.431f, -49.846f, -49.250f, + -51.485f, -53.093f, -53.007f, -53.989f, -57.366f, -58.728f, -55.954f, -56.348f, -57.811f, + -54.845f, -51.028f, -50.097f, -51.302f, -51.250f, -50.849f, -50.532f, -49.795f, -54.711f, + -55.841f, -41.369f, -30.052f, -35.086f, -36.197f, -38.237f, -39.494f, -40.796f, -42.762f, + -46.000f, -57.961f, -58.415f, -52.480f, -61.834f, -61.021f, -62.763f, -57.334f, -59.746f, + -56.141f, -48.866f, -49.375f, -48.618f, -46.456f, -46.093f, -43.402f, -42.699f, -39.884f, + -38.560f, -37.156f, -39.191f, -38.525f, -36.408f, -33.509f, -31.408f, -31.212f, -29.247f, + -27.720f, -26.684f, -25.130f, -22.335f, -19.521f, -16.306f, -14.704f, -13.004f, -14.736f, + -14.132f, -11.146f, -9.827f, -8.178f, -6.879f, -6.348f, -4.323f, -1.380f, 1.985f, + 5.142f, 7.089f, 6.724f, 9.588f, 11.897f, 13.305f, 13.191f, 13.314f, 13.275f, + 13.606f}, + {-29.534f, -28.896f, -27.425f, -25.447f, -23.056f, -20.256f, -17.429f, -14.621f, -12.009f, + -9.648f, -8.450f, -8.316f, -7.647f, -6.712f, -6.159f, -5.091f, -3.090f, -0.489f, + 0.716f, -0.598f, 2.662f, 6.687f, 6.126f, 3.295f, 0.141f, 3.432f, 2.396f, + 0.354f, -0.308f, 1.363f, 2.952f, 4.629f, 5.704f, 6.255f, 6.542f, 6.669f, + 6.773f, 6.694f, 6.471f, 6.149f, 5.650f, 4.859f, 3.582f, 2.223f, 0.705f, + -0.734f, -2.774f, -4.668f, -6.806f, -9.367f, -11.975f, -14.436f, -16.999f, -19.420f, + -21.852f, -23.934f, -26.084f, -27.989f, -29.728f, -29.559f, -32.114f, -34.179f, -37.191f, + -39.483f, -41.212f, -42.621f, -43.849f, -44.864f, -45.881f, -47.053f, -48.332f, -49.157f, + -50.793f, -51.338f, -49.641f, -48.583f, -49.519f, -47.551f, -47.934f, -47.787f, -46.860f, + -45.718f, -44.802f, -44.450f, -43.559f, -41.506f, -39.064f, -36.975f, -35.570f, -34.657f, + -34.089f, -35.312f, -38.876f, -36.796f, -42.686f, -41.775f, -40.405f, -41.808f, -42.784f, + -44.019f, -46.101f, -48.188f, -48.914f, -49.978f, -50.516f, -50.176f, -50.713f, -51.304f, + -49.931f, -49.314f, -51.185f, -51.803f, -51.373f, -51.015f, -50.659f, -50.540f, -52.108f, + -55.732f, -48.239f, -39.941f, -38.469f, -37.136f, -38.640f, -40.004f, -40.849f, -42.296f, + -47.623f, -57.078f, -52.694f, -50.947f, -58.938f, -59.665f, -60.955f, -57.243f, -61.526f, + -52.932f, -51.803f, -49.307f, -47.558f, -45.589f, -45.950f, -43.456f, -40.960f, -39.702f, + -37.850f, -37.867f, -39.455f, -40.243f, -37.775f, -33.687f, -33.081f, -31.723f, -29.256f, + -28.663f, -27.504f, -24.801f, -21.957f, -19.538f, -16.238f, -14.242f, -13.799f, -14.575f, + -14.131f, -11.848f, -9.614f, -8.580f, -7.164f, -6.527f, -4.558f, -1.413f, 2.124f, + 5.410f, 6.350f, 6.747f, 9.572f, 11.967f, 13.234f, 13.075f, 13.281f, 13.240f, + 13.606f}, + {-29.534f, -28.925f, -27.543f, -25.651f, -23.328f, -20.595f, -17.874f, -15.437f, -12.908f, + -10.527f, -9.681f, -9.820f, -9.039f, -7.929f, -7.062f, -6.141f, -4.199f, -1.478f, + -0.783f, -2.268f, 0.880f, 4.526f, 3.989f, 1.152f, -0.089f, 2.524f, 1.603f, + -1.061f, -1.327f, 0.302f, 1.547f, 3.382f, 4.391f, 4.946f, 5.301f, 5.447f, + 5.602f, 5.332f, 4.979f, 4.552f, 4.170f, 3.310f, 2.281f, 0.852f, -0.866f, + -2.591f, -4.529f, -6.522f, -8.839f, -11.338f, -13.763f, -16.342f, -18.906f, -21.358f, + -23.759f, -26.028f, -28.070f, -29.762f, -29.477f, -32.457f, -33.490f, -35.518f, -37.698f, + -39.888f, -42.014f, -42.990f, -44.277f, -44.964f, -45.795f, -46.599f, -47.849f, -48.804f, + -49.330f, -48.882f, -48.771f, -48.092f, -46.078f, -43.018f, -43.856f, -43.686f, -42.898f, + -42.461f, -42.019f, -39.741f, -37.328f, -34.863f, -33.100f, -31.302f, -30.139f, -29.434f, + -29.623f, -32.145f, -32.076f, -31.191f, -32.634f, -29.403f, -33.675f, -34.539f, -35.906f, + -39.079f, -42.208f, -44.463f, -46.104f, -46.776f, -46.208f, -46.636f, -46.961f, -47.862f, + -47.967f, -48.121f, -48.132f, -47.658f, -48.031f, -48.460f, -48.554f, -48.838f, -49.250f, + -51.005f, -48.956f, -43.934f, -38.006f, -38.083f, -39.136f, -40.309f, -41.096f, -42.259f, + -46.890f, -54.504f, -48.364f, -48.687f, -55.661f, -57.777f, -57.710f, -59.599f, -57.832f, + -52.558f, -49.740f, -48.373f, -46.693f, -45.287f, -44.768f, -43.311f, -40.312f, -39.127f, + -36.842f, -38.200f, -39.785f, -40.523f, -38.647f, -34.422f, -34.526f, -32.703f, -29.653f, + -29.144f, -27.532f, -24.911f, -22.295f, -19.850f, -16.473f, -14.309f, -14.364f, -14.276f, + -13.475f, -12.515f, -9.667f, -8.906f, -7.662f, -6.661f, -4.821f, -1.468f, 2.180f, + 5.475f, 5.587f, 6.766f, 9.531f, 12.050f, 13.169f, 12.954f, 13.247f, 13.206f, + 13.606f}, + {-29.534f, -28.955f, -27.659f, -25.861f, -23.604f, -20.921f, -18.326f, -16.246f, -13.819f, + -11.477f, -10.733f, -10.868f, -10.354f, -8.992f, -7.946f, -7.067f, -5.532f, -2.992f, + -2.647f, -3.641f, -0.913f, 2.299f, 2.357f, -0.734f, -1.257f, 1.481f, 0.411f, + -1.558f, -2.145f, -0.739f, 0.333f, 1.812f, 2.876f, 3.625f, 4.221f, 4.223f, + 4.404f, 3.993f, 3.620f, 3.043f, 2.455f, 1.850f, 0.758f, -0.785f, -2.618f, + -4.548f, -6.435f, -8.432f, -10.824f, -13.216f, -15.663f, -18.083f, -20.710f, -23.199f, + -25.491f, -27.726f, -29.611f, -31.925f, -30.650f, -33.727f, -35.054f, -36.846f, -38.376f, + -39.959f, -42.022f, -43.232f, -44.443f, -45.838f, -46.593f, -47.162f, -47.605f, -47.652f, + -48.005f, -47.686f, -46.252f, -43.988f, -42.446f, -42.107f, -39.167f, -39.273f, -38.598f, + -37.396f, -35.311f, -33.754f, -31.345f, -29.658f, -27.664f, -26.676f, -26.179f, -27.047f, + -29.074f, -25.725f, -27.033f, -28.612f, -22.450f, -25.693f, -29.777f, -30.510f, -31.927f, + -33.975f, -35.792f, -37.764f, -39.257f, -40.676f, -42.390f, -43.097f, -43.839f, -44.153f, + -44.406f, -43.961f, -43.621f, -43.326f, -44.201f, -44.133f, -45.874f, -45.496f, -45.554f, + -45.540f, -42.191f, -40.303f, -36.075f, -37.353f, -38.622f, -39.733f, -40.007f, -41.921f, + -47.599f, -53.604f, -47.404f, -47.213f, -54.977f, -56.310f, -56.238f, -56.760f, -55.964f, + -50.850f, -49.317f, -47.326f, -45.511f, -45.336f, -43.147f, -42.890f, -39.879f, -38.027f, + -35.719f, -37.709f, -40.547f, -40.391f, -39.579f, -34.912f, -34.626f, -34.114f, -30.492f, + -29.264f, -27.563f, -25.127f, -22.698f, -19.590f, -16.635f, -15.145f, -14.577f, -13.798f, + -12.869f, -12.768f, -10.114f, -9.088f, -7.998f, -6.785f, -5.063f, -1.554f, 2.188f, + 5.386f, 4.974f, 6.768f, 9.465f, 12.121f, 13.102f, 12.827f, 13.213f, 13.172f, + 13.606f}, + {-29.534f, -28.985f, -27.773f, -26.078f, -23.888f, -21.250f, -18.805f, -17.021f, -14.735f, + -12.512f, -11.679f, -11.605f, -11.617f, -10.237f, -9.017f, -7.987f, -6.957f, -5.008f, + -4.554f, -4.786f, -2.428f, 0.210f, 1.033f, -1.169f, -2.843f, 0.421f, 0.019f, + -2.935f, -3.175f, -2.026f, -0.956f, 0.370f, 1.028f, 2.228f, 2.780f, 2.458f, + 2.835f, 2.778f, 2.100f, 1.568f, 0.999f, 0.193f, -0.881f, -2.452f, -4.362f, + -6.159f, -8.173f, -10.545f, -12.700f, -14.928f, -17.539f, -19.991f, -22.422f, -24.999f, + -27.196f, -29.269f, -31.085f, -33.396f, -32.235f, -34.379f, -35.565f, -35.893f, -37.001f, + -39.999f, -41.574f, -43.068f, -44.599f, -45.956f, -47.192f, -47.821f, -47.748f, -47.303f, + -46.571f, -45.606f, -44.754f, -43.288f, -41.467f, -39.858f, -37.874f, -36.695f, -35.436f, + -32.338f, -30.412f, -28.999f, -27.070f, -24.154f, -21.754f, -21.444f, -24.639f, -22.571f, + -19.016f, -18.904f, -21.020f, -19.321f, -20.083f, -20.949f, -23.338f, -25.321f, -27.193f, + -29.294f, -31.694f, -33.746f, -35.970f, -38.292f, -38.144f, -38.873f, -39.928f, -41.133f, + -41.563f, -41.484f, -41.573f, -41.746f, -41.951f, -42.592f, -42.816f, -41.328f, -42.043f, + -43.708f, -39.965f, -36.733f, -35.142f, -35.716f, -36.590f, -37.431f, -38.524f, -41.005f, + -47.401f, -50.054f, -46.550f, -46.408f, -56.990f, -56.336f, -55.846f, -56.153f, -54.463f, + -49.210f, -49.435f, -45.696f, -44.357f, -44.613f, -42.644f, -41.523f, -38.895f, -37.126f, + -36.123f, -38.064f, -41.068f, -40.278f, -39.577f, -35.505f, -34.429f, -34.202f, -31.112f, + -29.376f, -27.748f, -24.601f, -22.534f, -19.122f, -16.445f, -15.404f, -14.592f, -13.426f, + -12.722f, -12.602f, -10.693f, -9.219f, -8.019f, -6.964f, -5.252f, -1.612f, 2.226f, + 5.257f, 4.626f, 6.740f, 9.387f, 12.155f, 13.024f, 12.697f, 13.175f, 13.139f, + 13.606f}, + {-29.534f, -29.017f, -27.885f, -26.303f, -24.182f, -21.591f, -19.323f, -17.750f, -15.625f, + -13.566f, -12.639f, -12.357f, -12.846f, -11.960f, -10.294f, -9.127f, -8.211f, -6.878f, + -6.152f, -5.860f, -4.111f, -2.496f, -1.543f, -2.104f, -2.271f, -0.567f, -0.337f, + -4.468f, -4.741f, -3.744f, -2.225f, -0.864f, -0.174f, 0.684f, 1.278f, 1.590f, + 1.273f, 1.438f, 0.812f, 0.096f, -0.558f, -1.562f, -2.601f, -4.027f, -5.938f, + -7.973f, -9.774f, -12.133f, -14.494f, -16.847f, -19.253f, -21.759f, -24.165f, -26.406f, + -28.470f, -30.405f, -32.139f, -34.070f, -33.756f, -35.563f, -36.500f, -36.639f, -37.682f, + -39.846f, -41.244f, -42.565f, -43.990f, -45.324f, -46.527f, -47.231f, -47.212f, -46.404f, + -45.314f, -44.186f, -43.074f, -41.479f, -40.498f, -38.026f, -36.004f, -33.352f, -31.967f, + -29.510f, -26.286f, -23.329f, -21.479f, -19.172f, -18.623f, -22.610f, -17.362f, -16.648f, + -12.513f, -11.930f, -10.454f, -12.209f, -15.450f, -17.239f, -18.852f, -21.067f, -22.776f, + -25.073f, -28.006f, -30.225f, -32.348f, -33.958f, -35.033f, -35.976f, -36.752f, -38.152f, + -39.291f, -39.341f, -39.250f, -39.446f, -40.005f, -40.911f, -40.611f, -40.017f, -39.217f, + -39.586f, -36.802f, -34.035f, -33.885f, -33.985f, -34.462f, -35.768f, -37.724f, -39.731f, + -43.953f, -47.384f, -45.401f, -48.352f, -56.961f, -55.645f, -55.895f, -55.314f, -53.319f, + -48.987f, -49.145f, -44.976f, -43.831f, -43.507f, -42.289f, -40.099f, -37.628f, -36.342f, + -37.437f, -39.628f, -40.661f, -40.180f, -39.540f, -36.080f, -34.176f, -33.623f, -31.170f, + -29.917f, -28.082f, -23.850f, -22.143f, -19.302f, -16.268f, -15.697f, -14.797f, -13.029f, + -12.534f, -12.152f, -11.098f, -9.333f, -7.918f, -7.148f, -5.290f, -1.533f, 2.329f, + 5.181f, 4.556f, 6.679f, 9.320f, 12.139f, 12.927f, 12.565f, 13.134f, 13.107f, + 13.606f}, + {-29.534f, -29.049f, -27.996f, -26.534f, -24.489f, -21.952f, -19.877f, -18.439f, -16.455f, + -14.550f, -13.682f, -13.369f, -14.048f, -14.056f, -11.624f, -10.604f, -9.383f, -8.206f, + -7.598f, -7.256f, -5.931f, -4.728f, -3.376f, -2.699f, -1.440f, -1.012f, -1.750f, + -5.836f, -6.210f, -5.179f, -3.480f, -1.910f, -1.264f, -0.741f, 0.001f, 0.291f, + 0.065f, -0.043f, -0.571f, -1.337f, -2.186f, -2.884f, -4.241f, -5.691f, -7.475f, + -9.424f, -11.698f, -13.930f, -16.107f, -18.557f, -21.037f, -23.362f, -25.662f, -27.853f, + -29.752f, -31.545f, -32.950f, -35.036f, -34.627f, -36.906f, -37.669f, -38.261f, -39.388f, + -39.784f, -39.026f, -41.687f, -42.964f, -44.005f, -45.070f, -45.597f, -46.072f, -45.381f, + -43.794f, -42.131f, -40.499f, -39.592f, -37.892f, -36.574f, -33.436f, -28.624f, -26.696f, + -25.350f, -22.660f, -18.388f, -16.738f, -18.756f, -18.736f, -15.032f, -15.937f, -11.869f, + -7.164f, -6.713f, -6.779f, -8.616f, -10.514f, -12.602f, -14.787f, -16.730f, -18.779f, + -21.905f, -25.356f, -27.666f, -29.490f, -31.763f, -33.153f, -34.152f, -35.141f, -36.560f, + -37.238f, -37.499f, -37.448f, -37.267f, -37.901f, -38.670f, -38.851f, -38.927f, -37.869f, + -36.248f, -33.506f, -31.976f, -31.653f, -32.061f, -33.683f, -34.535f, -36.364f, -39.783f, + -45.708f, -45.848f, -44.247f, -51.897f, -55.322f, -55.625f, -55.417f, -53.369f, -52.005f, + -49.338f, -47.841f, -44.478f, -43.509f, -43.362f, -41.668f, -39.569f, -36.815f, -36.236f, + -39.183f, -40.230f, -40.260f, -39.020f, -38.734f, -36.181f, -34.245f, -32.926f, -31.189f, + -30.141f, -28.782f, -23.926f, -22.068f, -19.930f, -16.496f, -16.892f, -15.010f, -12.318f, + -12.421f, -11.763f, -11.309f, -9.290f, -7.880f, -7.115f, -5.014f, -1.243f, 2.463f, + 5.160f, 4.670f, 6.600f, 9.285f, 12.068f, 12.807f, 12.432f, 13.087f, 13.075f, + 13.606f}, + {-29.534f, -29.082f, -28.105f, -26.772f, -24.808f, -22.332f, -20.445f, -19.099f, -17.207f, + -15.425f, -14.784f, -14.643f, -15.284f, -16.109f, -13.014f, -12.222f, -10.764f, -9.481f, + -9.170f, -8.847f, -7.434f, -6.247f, -4.917f, -3.180f, -2.006f, -1.737f, -4.371f, + -7.229f, -7.134f, -6.017f, -4.385f, -2.994f, -2.308f, -1.627f, -1.120f, -0.590f, + -0.801f, -1.392f, -1.937f, -2.677f, -3.619f, -4.513f, -5.608f, -7.348f, -9.182f, + -10.881f, -13.140f, -15.922f, -18.059f, -20.181f, -22.609f, -24.922f, -27.182f, -29.318f, + -31.152f, -32.754f, -34.873f, -36.540f, -35.821f, -37.067f, -38.185f, -38.627f, -38.993f, + -39.074f, -39.847f, -40.875f, -41.804f, -42.723f, -43.562f, -44.312f, -43.960f, -43.534f, + -42.569f, -41.829f, -39.761f, -36.924f, -34.574f, -31.366f, -28.257f, -25.930f, -23.151f, + -20.644f, -18.726f, -16.848f, -16.668f, -14.938f, -10.372f, -9.765f, -3.401f, -0.385f, + -1.964f, -3.164f, -3.932f, -5.126f, -6.538f, -7.989f, -10.370f, -13.935f, -16.916f, + -19.891f, -22.697f, -25.178f, -27.343f, -29.178f, -30.011f, -31.292f, -32.094f, -33.128f, + -34.321f, -34.562f, -35.306f, -35.773f, -36.761f, -37.002f, -37.042f, -36.807f, -36.823f, + -35.095f, -32.064f, -30.762f, -31.127f, -31.241f, -32.469f, -33.852f, -35.663f, -39.138f, + -44.352f, -43.554f, -44.789f, -51.792f, -54.294f, -54.810f, -54.121f, -51.793f, -50.846f, + -48.903f, -45.806f, -43.397f, -43.703f, -43.198f, -41.191f, -39.456f, -36.520f, -36.964f, + -39.718f, -39.700f, -38.960f, -37.686f, -37.335f, -36.033f, -34.067f, -32.663f, -31.171f, + -29.516f, -29.027f, -24.867f, -22.245f, -19.959f, -16.665f, -17.349f, -14.966f, -11.930f, + -13.140f, -11.848f, -11.322f, -9.029f, -7.815f, -6.678f, -4.355f, -0.780f, 2.552f, + 5.103f, 4.816f, 6.530f, 9.299f, 11.947f, 12.660f, 12.304f, 13.033f, 13.045f, + 13.606f}, + {-29.534f, -29.116f, -28.213f, -27.015f, -25.141f, -22.726f, -20.998f, -19.740f, -17.897f, + -16.225f, -15.878f, -15.984f, -16.704f, -17.730f, -14.564f, -13.595f, -12.300f, -11.231f, + -10.837f, -10.100f, -8.773f, -7.957f, -7.564f, -5.647f, -3.244f, -4.120f, -7.723f, + -8.454f, -7.925f, -6.881f, -5.479f, -4.286f, -3.547f, -2.843f, -2.244f, -2.214f, + -2.271f, -2.592f, -3.269f, -3.929f, -5.044f, -5.991f, -7.326f, -8.936f, -10.954f, + -12.583f, -14.440f, -16.951f, -19.426f, -21.855f, -24.243f, -26.563f, -28.571f, -30.692f, + -32.577f, -34.094f, -36.623f, -38.793f, -37.194f, -38.562f, -38.140f, -38.433f, -38.432f, + -38.974f, -39.618f, -39.940f, -40.712f, -41.252f, -41.748f, -42.160f, -42.187f, -41.836f, + -41.337f, -39.804f, -37.299f, -34.075f, -29.971f, -26.474f, -24.068f, -22.655f, -20.808f, + -16.803f, -14.674f, -14.935f, -12.496f, -8.891f, -2.837f, 4.160f, 5.147f, 3.317f, + 1.980f, 1.433f, -0.163f, -1.066f, -2.178f, -3.173f, -7.428f, -11.618f, -14.271f, + -16.869f, -19.424f, -21.993f, -23.817f, -25.302f, -26.585f, -29.043f, -30.512f, -31.592f, + -32.481f, -33.413f, -33.711f, -34.090f, -34.274f, -34.785f, -35.525f, -34.720f, -35.594f, + -34.668f, -32.953f, -32.393f, -32.222f, -30.976f, -32.114f, -34.049f, -35.706f, -37.924f, + -42.555f, -43.201f, -46.203f, -51.532f, -52.731f, -52.883f, -52.691f, -49.998f, -49.440f, + -47.337f, -44.577f, -43.756f, -43.926f, -42.482f, -40.899f, -38.447f, -37.888f, -37.889f, + -38.905f, -38.653f, -38.136f, -36.570f, -36.243f, -35.511f, -33.495f, -32.365f, -30.621f, + -29.387f, -28.645f, -25.148f, -21.991f, -18.991f, -16.376f, -16.463f, -14.906f, -12.350f, + -14.193f, -12.381f, -11.006f, -8.803f, -7.546f, -5.939f, -3.474f, -0.270f, 2.551f, + 4.889f, 4.850f, 6.502f, 9.364f, 11.789f, 12.486f, 12.181f, 12.971f, 13.015f, + 13.606f}, + {-29.534f, -29.150f, -28.318f, -27.262f, -25.484f, -23.128f, -21.510f, -20.367f, -18.558f, + -17.022f, -16.924f, -17.192f, -18.401f, -18.760f, -16.078f, -14.625f, -13.733f, -13.174f, + -12.446f, -11.225f, -10.269f, -9.590f, -9.397f, -8.125f, -5.573f, -6.787f, -9.325f, + -9.455f, -8.523f, -7.660f, -6.735f, -5.574f, -4.834f, -4.206f, -3.803f, -3.449f, + -3.536f, -4.140f, -4.542f, -5.364f, -6.343f, -7.506f, -8.808f, -10.487f, -12.469f, + -14.124f, -16.142f, -18.463f, -20.788f, -23.070f, -25.439f, -27.811f, -30.036f, -32.032f, + -33.497f, -37.120f, -37.597f, -39.365f, -40.195f, -39.276f, -38.943f, -38.201f, -37.651f, + -38.259f, -38.858f, -39.131f, -39.554f, -39.315f, -39.536f, -39.479f, -39.925f, -39.641f, + -38.824f, -37.459f, -35.423f, -32.191f, -28.171f, -23.794f, -21.091f, -18.729f, -15.987f, + -12.867f, -13.219f, -11.839f, -10.484f, -3.999f, 7.362f, 8.368f, 7.677f, 7.506f, + 6.350f, 4.482f, 3.779f, 2.027f, 0.725f, -1.237f, -5.238f, -8.569f, -10.771f, + -13.149f, -15.734f, -17.992f, -19.907f, -22.218f, -24.179f, -26.994f, -29.583f, -29.650f, + -31.907f, -30.570f, -31.367f, -32.454f, -32.666f, -32.788f, -33.170f, -32.686f, -32.704f, + -34.453f, -34.666f, -37.849f, -41.015f, -32.766f, -31.435f, -32.769f, -35.664f, -38.362f, + -43.336f, -43.047f, -48.993f, -50.900f, -49.922f, -50.310f, -50.144f, -48.813f, -47.001f, + -46.974f, -44.723f, -43.530f, -43.188f, -41.501f, -40.380f, -38.307f, -38.010f, -37.865f, + -37.834f, -36.836f, -36.582f, -35.920f, -34.815f, -33.967f, -32.914f, -31.381f, -30.238f, + -29.846f, -27.999f, -23.958f, -21.239f, -18.312f, -16.028f, -15.690f, -14.633f, -12.793f, + -14.274f, -12.942f, -10.527f, -8.908f, -7.096f, -5.239f, -2.676f, 0.163f, 2.466f, + 4.446f, 4.699f, 6.543f, 9.461f, 11.614f, 12.289f, 12.069f, 12.901f, 12.987f, + 13.606f}, + {-29.534f, -29.184f, -28.422f, -27.512f, -25.835f, -23.529f, -21.965f, -20.981f, -19.224f, + -17.869f, -17.943f, -18.213f, -20.192f, -19.254f, -17.137f, -15.653f, -15.152f, -14.913f, + -13.997f, -12.657f, -11.752f, -11.201f, -10.615f, -9.480f, -8.066f, -8.285f, -10.140f, + -10.264f, -9.080f, -8.004f, -7.371f, -6.813f, -5.882f, -5.482f, -5.015f, -4.963f, + -4.834f, -5.170f, -5.908f, -6.809f, -7.728f, -8.845f, -10.240f, -11.987f, -13.916f, + -15.701f, -17.708f, -20.037f, -22.155f, -24.452f, -26.680f, -29.018f, -31.273f, -33.374f, + -35.507f, -38.035f, -39.895f, -40.092f, -40.436f, -39.345f, -38.831f, -38.355f, -38.055f, + -37.988f, -37.952f, -37.902f, -38.660f, -37.434f, -34.946f, -36.646f, -37.187f, -37.349f, + -36.320f, -34.845f, -33.229f, -31.018f, -26.942f, -22.028f, -17.211f, -13.780f, -11.260f, + -10.025f, -12.152f, -9.350f, -3.998f, 7.620f, 11.303f, 12.084f, 11.646f, 10.955f, + 10.414f, 8.552f, 7.551f, 5.488f, 2.903f, 0.499f, -3.097f, -5.412f, -7.083f, + -9.402f, -12.188f, -14.798f, -17.232f, -19.700f, -21.367f, -24.488f, -26.825f, -27.129f, + -29.982f, -29.038f, -29.683f, -31.107f, -30.396f, -31.217f, -31.687f, -30.965f, -30.882f, + -32.166f, -37.263f, -42.559f, -43.693f, -40.560f, -34.876f, -34.149f, -36.421f, -38.886f, + -42.258f, -43.552f, -46.919f, -48.222f, -47.233f, -48.031f, -48.087f, -45.887f, -45.812f, + -45.765f, -44.101f, -43.199f, -42.590f, -41.037f, -39.978f, -37.811f, -39.147f, -37.146f, + -35.609f, -35.260f, -35.646f, -35.327f, -33.530f, -32.351f, -32.061f, -30.524f, -29.799f, + -29.637f, -27.156f, -22.647f, -20.701f, -18.449f, -16.088f, -15.428f, -13.722f, -12.558f, + -13.369f, -13.151f, -10.363f, -9.190f, -6.644f, -4.806f, -2.158f, 0.479f, 2.311f, + 3.790f, 4.383f, 6.658f, 9.560f, 11.441f, 12.074f, 11.970f, 12.820f, 12.960f, + 13.606f}, + {-29.534f, -29.220f, -28.525f, -27.761f, -26.192f, -23.924f, -22.372f, -21.577f, -19.910f, + -18.760f, -18.970f, -19.138f, -21.601f, -19.385f, -17.661f, -16.911f, -16.752f, -16.619f, + -15.609f, -14.027f, -13.031f, -13.019f, -12.072f, -10.980f, -10.020f, -9.251f, -11.418f, + -11.572f, -9.973f, -8.859f, -7.926f, -7.597f, -6.943f, -6.593f, -6.179f, -6.062f, + -6.089f, -6.443f, -7.032f, -8.019f, -9.262f, -10.203f, -11.765f, -13.297f, -15.145f, + -16.957f, -19.198f, -21.440f, -23.558f, -25.585f, -28.008f, -30.266f, -32.378f, -34.300f, + -37.064f, -39.742f, -40.891f, -40.847f, -41.046f, -39.568f, -39.222f, -38.931f, -38.547f, + -37.869f, -37.434f, -37.830f, -36.965f, -36.991f, -34.002f, -35.348f, -35.113f, -35.029f, + -34.088f, -32.734f, -30.743f, -28.367f, -24.647f, -19.307f, -13.797f, -8.364f, -6.048f, + -9.393f, -11.687f, -6.018f, 7.611f, 13.225f, 14.182f, 14.803f, 15.268f, 15.029f, + 14.418f, 12.950f, 11.715f, 9.358f, 6.203f, 3.131f, 0.446f, -1.517f, -3.446f, + -6.096f, -9.052f, -11.924f, -14.073f, -16.084f, -18.078f, -21.198f, -23.453f, -24.596f, + -24.756f, -26.914f, -28.058f, -29.378f, -30.018f, -30.102f, -31.709f, -31.800f, -31.042f, + -31.076f, -37.037f, -41.823f, -42.342f, -42.709f, -40.917f, -38.067f, -37.978f, -39.465f, + -40.034f, -42.068f, -44.619f, -45.095f, -44.625f, -45.663f, -45.806f, -43.775f, -44.058f, + -43.640f, -42.469f, -42.238f, -41.351f, -40.403f, -39.806f, -38.313f, -39.964f, -35.881f, + -33.971f, -34.486f, -34.278f, -34.821f, -33.651f, -31.778f, -31.123f, -29.963f, -29.484f, + -29.113f, -26.474f, -22.040f, -20.446f, -18.576f, -16.493f, -15.221f, -12.615f, -11.841f, + -12.377f, -12.810f, -10.604f, -9.138f, -6.264f, -4.538f, -1.866f, 0.710f, 2.062f, + 3.018f, 4.002f, 6.828f, 9.623f, 11.286f, 11.850f, 11.888f, 12.729f, 12.935f, + 13.606f}, + {-29.534f, -29.255f, -28.625f, -28.009f, -26.552f, -24.314f, -22.757f, -22.158f, -20.618f, + -19.659f, -20.005f, -20.094f, -22.232f, -19.386f, -18.104f, -18.185f, -18.324f, -18.399f, + -17.312f, -15.193f, -14.377f, -14.577f, -13.064f, -12.085f, -12.111f, -10.559f, -11.844f, + -12.585f, -11.464f, -10.060f, -8.876f, -8.383f, -8.068f, -7.622f, -7.407f, -7.134f, + -7.252f, -7.791f, -8.458f, -9.414f, -10.398f, -11.728f, -13.091f, -14.667f, -16.406f, + -18.534f, -20.629f, -22.709f, -25.027f, -26.968f, -29.177f, -31.313f, -33.225f, -34.836f, + -38.144f, -40.493f, -40.943f, -40.395f, -40.389f, -40.296f, -39.556f, -39.001f, -38.905f, + -38.008f, -36.997f, -37.076f, -37.099f, -36.280f, -35.739f, -34.874f, -33.837f, -33.098f, + -31.923f, -30.561f, -28.185f, -24.649f, -20.610f, -16.572f, -12.734f, -7.986f, -4.677f, + -8.951f, -6.802f, 7.619f, 14.027f, 15.950f, 17.187f, 18.286f, 18.841f, 18.929f, + 18.051f, 16.916f, 15.413f, 13.346f, 10.218f, 7.622f, 5.730f, 3.146f, -0.020f, + -2.904f, -5.068f, -7.548f, -9.935f, -12.022f, -14.087f, -16.802f, -19.343f, -19.816f, + -21.199f, -23.615f, -25.120f, -27.477f, -28.726f, -28.941f, -31.280f, -31.595f, -30.438f, + -30.926f, -34.598f, -38.931f, -40.583f, -41.894f, -40.755f, -38.524f, -38.168f, -37.533f, + -36.851f, -39.744f, -42.385f, -41.606f, -43.169f, -41.977f, -43.350f, -42.571f, -41.886f, + -41.639f, -40.537f, -40.230f, -39.806f, -39.438f, -39.034f, -38.607f, -39.319f, -35.333f, + -33.975f, -32.938f, -33.510f, -34.416f, -33.639f, -31.788f, -31.094f, -29.896f, -29.213f, + -28.993f, -26.248f, -21.897f, -20.052f, -18.500f, -16.601f, -14.970f, -11.895f, -10.908f, + -11.551f, -12.005f, -10.780f, -8.554f, -5.849f, -4.225f, -1.630f, 0.889f, 1.668f, + 2.251f, 3.682f, 7.003f, 9.620f, 11.159f, 11.624f, 11.824f, 12.627f, 12.912f, + 13.606f}, + {-29.534f, -29.291f, -28.724f, -28.254f, -26.913f, -24.704f, -23.161f, -22.734f, -21.345f, + -20.544f, -21.011f, -21.150f, -22.198f, -19.511f, -18.932f, -19.337f, -19.699f, -20.014f, + -18.920f, -16.627f, -15.807f, -15.862f, -14.267f, -13.303f, -13.583f, -11.930f, -13.174f, + -13.336f, -13.211f, -11.440f, -10.063f, -9.388f, -9.185f, -8.875f, -8.757f, -8.509f, + -8.581f, -9.041f, -9.779f, -10.719f, -11.744f, -12.874f, -14.484f, -15.969f, -17.670f, + -19.878f, -22.020f, -24.079f, -26.051f, -28.242f, -30.185f, -32.143f, -33.847f, -35.520f, + -38.806f, -40.499f, -40.490f, -40.043f, -40.629f, -40.326f, -39.447f, -39.087f, -38.852f, + -37.792f, -37.149f, -37.115f, -34.962f, -33.784f, -32.976f, -32.964f, -32.297f, -31.151f, + -29.724f, -27.835f, -25.246f, -21.674f, -17.385f, -12.792f, -9.300f, -7.320f, -7.770f, + -5.856f, 1.904f, 20.129f, 18.627f, 19.670f, 21.365f, 21.773f, 22.295f, 22.032f, + 22.043f, 21.201f, 19.845f, 17.857f, 14.981f, 11.861f, 9.515f, 6.924f, 4.218f, + 1.524f, -1.483f, -3.074f, -5.101f, -7.265f, -8.831f, -12.113f, -14.269f, -17.360f, + -19.484f, -21.452f, -23.408f, -24.180f, -25.965f, -27.746f, -29.273f, -29.523f, -28.376f, + -29.427f, -31.318f, -34.321f, -37.827f, -39.249f, -37.951f, -35.979f, -36.315f, -36.246f, + -36.057f, -36.792f, -39.124f, -39.137f, -39.767f, -40.348f, -39.789f, -40.413f, -39.754f, + -39.591f, -38.559f, -37.758f, -36.766f, -36.869f, -37.186f, -37.061f, -36.454f, -35.153f, + -32.557f, -32.474f, -32.559f, -33.611f, -33.421f, -31.211f, -30.532f, -29.793f, -29.087f, + -28.584f, -25.985f, -21.697f, -19.256f, -18.334f, -16.405f, -14.578f, -11.311f, -9.947f, + -10.758f, -11.185f, -10.559f, -7.793f, -5.288f, -3.883f, -1.387f, 0.984f, 1.119f, + 1.594f, 3.520f, 7.126f, 9.541f, 11.062f, 11.406f, 11.779f, 12.515f, 12.890f, + 13.606f}, + {-29.534f, -29.327f, -28.822f, -28.492f, -27.273f, -25.102f, -23.625f, -23.325f, -22.097f, + -21.447f, -21.970f, -22.282f, -22.130f, -19.996f, -20.123f, -20.714f, -21.321f, -21.683f, + -20.372f, -18.069f, -16.805f, -16.858f, -15.532f, -15.147f, -14.361f, -13.140f, -15.562f, + -14.525f, -13.964f, -12.622f, -11.158f, -10.659f, -10.166f, -9.901f, -9.735f, -9.804f, + -9.842f, -10.264f, -11.018f, -11.973f, -13.052f, -14.127f, -15.598f, -17.395f, -19.030f, + -21.034f, -23.318f, -25.216f, -27.403f, -29.238f, -31.083f, -32.863f, -34.121f, -36.627f, + -39.371f, -40.097f, -39.729f, -40.628f, -40.673f, -40.187f, -39.922f, -39.404f, -39.452f, + -37.887f, -37.687f, -35.356f, -32.379f, -31.820f, -31.114f, -31.257f, -30.054f, -29.096f, + -27.308f, -25.046f, -21.993f, -18.374f, -14.426f, -9.525f, -6.512f, -5.275f, -6.581f, + -2.772f, 12.361f, 21.680f, 21.157f, 22.874f, 23.886f, 25.062f, 25.654f, 26.036f, + 26.013f, 25.156f, 23.070f, 21.383f, 18.955f, 16.684f, 14.236f, 10.941f, 7.779f, + 6.156f, 2.760f, 1.067f, 1.192f, -2.300f, -4.468f, -7.348f, -11.745f, -14.519f, + -16.043f, -17.835f, -20.635f, -21.799f, -23.015f, -25.512f, -26.711f, -27.152f, -26.480f, + -26.945f, -28.445f, -30.438f, -32.462f, -35.125f, -33.932f, -33.981f, -34.954f, -35.380f, + -33.942f, -33.777f, -35.713f, -35.749f, -36.301f, -37.970f, -36.179f, -37.948f, -37.316f, + -37.015f, -36.388f, -35.472f, -34.393f, -33.769f, -34.263f, -34.455f, -34.272f, -34.227f, + -32.071f, -31.568f, -32.185f, -33.233f, -32.818f, -30.589f, -29.414f, -29.041f, -28.990f, + -27.786f, -25.231f, -20.881f, -18.121f, -17.904f, -16.551f, -14.051f, -10.346f, -9.239f, + -10.183f, -10.723f, -10.110f, -7.210f, -4.637f, -3.703f, -1.239f, 0.898f, 0.494f, + 1.103f, 3.541f, 7.150f, 9.403f, 10.989f, 11.204f, 11.751f, 12.392f, 12.871f, + 13.606f}, + {-29.534f, -29.364f, -28.917f, -28.723f, -27.631f, -25.521f, -24.176f, -23.950f, -22.890f, + -22.435f, -22.934f, -23.418f, -22.650f, -20.997f, -21.394f, -22.571f, -23.556f, -23.969f, + -22.079f, -19.020f, -17.521f, -17.624f, -16.621f, -16.550f, -14.910f, -15.107f, -17.655f, + -16.047f, -14.834f, -13.555f, -12.338f, -11.911f, -11.487f, -11.165f, -10.795f, -10.928f, + -11.138f, -11.503f, -12.128f, -12.946f, -14.149f, -15.400f, -16.944f, -18.614f, -20.502f, + -22.456f, -24.456f, -26.369f, -28.423f, -30.390f, -31.967f, -33.418f, -34.367f, -37.390f, + -39.850f, -39.987f, -39.512f, -39.898f, -40.106f, -40.095f, -39.921f, -39.646f, -39.121f, + -38.136f, -36.609f, -33.988f, -32.370f, -31.487f, -30.994f, -29.602f, -27.664f, -26.757f, + -25.100f, -22.494f, -19.437f, -15.270f, -9.412f, -5.591f, -2.915f, -2.442f, -3.742f, + 1.020f, 19.057f, 22.256f, 23.896f, 25.614f, 26.960f, 28.112f, 29.281f, 30.053f, + 30.414f, 28.755f, 26.490f, 24.221f, 21.912f, 19.636f, 17.300f, 14.986f, 12.506f, + 10.354f, 7.962f, 5.647f, 4.184f, 1.242f, -2.050f, -5.427f, -9.048f, -10.533f, + -12.626f, -13.898f, -16.623f, -18.849f, -20.234f, -22.356f, -23.742f, -24.505f, -23.910f, + -24.286f, -25.245f, -27.431f, -27.322f, -29.411f, -28.623f, -31.388f, -33.186f, -33.502f, + -31.353f, -31.371f, -32.186f, -32.032f, -32.062f, -33.170f, -32.727f, -34.398f, -35.093f, + -34.296f, -33.858f, -33.068f, -32.338f, -31.944f, -32.193f, -31.908f, -31.887f, -31.236f, + -32.877f, -32.303f, -28.789f, -29.788f, -31.615f, -29.651f, -28.314f, -28.496f, -27.869f, + -26.492f, -23.962f, -19.927f, -17.400f, -17.384f, -16.489f, -13.575f, -9.317f, -8.902f, + -10.024f, -10.533f, -9.694f, -6.738f, -4.075f, -3.688f, -1.296f, 0.530f, -0.063f, + 0.788f, 3.698f, 7.063f, 9.250f, 10.928f, 11.024f, 11.739f, 12.261f, 12.853f, + 13.606f}, + {-29.534f, -29.401f, -29.011f, -28.946f, -27.988f, -25.969f, -24.822f, -24.622f, -23.737f, + -23.552f, -23.998f, -24.499f, -23.823f, -22.489f, -22.748f, -24.520f, -25.864f, -26.558f, + -24.226f, -20.047f, -18.279f, -18.392f, -18.010f, -17.716f, -15.249f, -17.216f, -19.295f, + -17.850f, -16.162f, -14.709f, -13.579f, -13.001f, -12.690f, -12.432f, -12.153f, -12.082f, + -12.160f, -12.675f, -13.320f, -14.108f, -15.248f, -16.621f, -18.024f, -19.646f, -21.405f, + -23.486f, -25.467f, -27.443f, -29.220f, -31.040f, -32.551f, -33.756f, -34.888f, -37.656f, + -39.970f, -38.893f, -36.850f, -37.750f, -39.305f, -39.783f, -39.551f, -39.257f, -38.102f, + -37.224f, -34.763f, -33.560f, -33.132f, -32.224f, -30.688f, -28.152f, -25.772f, -23.693f, + -22.000f, -20.096f, -17.512f, -14.067f, -9.586f, -4.376f, 0.377f, -0.161f, -2.172f, + 7.220f, 23.520f, 24.376f, 26.294f, 27.840f, 29.368f, 31.392f, 32.590f, 33.751f, + 33.904f, 32.824f, 29.999f, 27.503f, 25.245f, 22.852f, 21.199f, 17.674f, 16.293f, + 13.060f, 10.843f, 8.636f, 5.960f, 3.443f, -0.473f, -2.657f, -6.312f, -7.635f, + -8.483f, -10.467f, -12.674f, -14.684f, -17.398f, -18.751f, -20.179f, -21.409f, -20.716f, + -21.607f, -22.510f, -23.731f, -23.688f, -24.386f, -26.251f, -28.410f, -28.295f, -31.517f, + -28.832f, -29.851f, -29.788f, -28.467f, -28.800f, -27.841f, -29.346f, -31.277f, -32.127f, + -31.935f, -31.536f, -31.007f, -30.491f, -29.776f, -29.537f, -29.477f, -29.605f, -29.142f, + -31.154f, -29.784f, -28.000f, -26.610f, -29.016f, -28.546f, -27.674f, -27.265f, -26.561f, + -25.129f, -22.617f, -19.136f, -17.047f, -17.036f, -15.764f, -13.300f, -9.214f, -9.026f, + -10.181f, -10.394f, -9.348f, -6.234f, -3.732f, -3.528f, -1.518f, -0.158f, -0.449f, + 0.629f, 3.901f, 6.895f, 9.135f, 10.861f, 10.870f, 11.738f, 12.122f, 12.838f, + 13.606f}, + {-29.534f, -29.437f, -29.104f, -29.158f, -28.342f, -26.454f, -25.544f, -25.342f, -24.631f, + -24.768f, -25.214f, -25.518f, -25.191f, -24.220f, -24.442f, -26.072f, -27.422f, -28.286f, + -26.022f, -21.678f, -18.641f, -18.630f, -18.370f, -18.332f, -16.236f, -18.461f, -19.984f, + -19.538f, -17.549f, -16.003f, -14.696f, -14.139f, -13.813f, -13.647f, -13.487f, -13.398f, + -13.554f, -13.758f, -14.438f, -15.300f, -16.386f, -17.658f, -19.100f, -20.618f, -22.397f, + -24.292f, -26.239f, -28.217f, -30.074f, -31.754f, -33.168f, -34.385f, -35.452f, -38.600f, + -39.864f, -38.224f, -36.341f, -37.951f, -39.092f, -39.259f, -38.619f, -37.819f, -36.806f, + -34.428f, -31.469f, -30.080f, -30.402f, -30.748f, -28.850f, -26.905f, -23.887f, -22.174f, + -19.384f, -17.263f, -14.808f, -12.069f, -7.682f, -2.584f, 3.293f, 2.693f, 0.856f, + 11.403f, 25.340f, 24.987f, 28.397f, 30.460f, 31.965f, 33.964f, 35.619f, 36.931f, + 37.184f, 36.720f, 34.325f, 31.103f, 28.843f, 26.792f, 24.124f, 21.764f, 20.310f, + 17.714f, 14.662f, 11.932f, 8.640f, 6.204f, 3.311f, 1.521f, -1.119f, -4.829f, + -6.365f, -6.918f, -9.310f, -10.715f, -13.591f, -14.882f, -16.648f, -17.422f, -18.524f, + -19.476f, -20.340f, -21.369f, -22.146f, -22.513f, -23.843f, -25.906f, -25.074f, -27.118f, + -26.324f, -24.801f, -25.047f, -25.220f, -25.060f, -23.983f, -26.288f, -28.047f, -28.427f, + -28.734f, -28.342f, -28.338f, -28.056f, -27.586f, -27.261f, -27.485f, -27.446f, -26.737f, + -27.403f, -26.304f, -26.965f, -24.432f, -26.560f, -27.871f, -27.536f, -26.231f, -25.328f, + -24.313f, -21.517f, -18.281f, -16.263f, -16.455f, -15.205f, -12.968f, -10.057f, -9.596f, + -10.306f, -10.247f, -9.017f, -5.845f, -3.546f, -2.975f, -1.740f, -1.088f, -0.669f, + 0.593f, 4.065f, 6.712f, 9.108f, 10.774f, 10.746f, 11.741f, 11.978f, 12.826f, + 13.606f}, + {-29.534f, -29.474f, -29.194f, -29.360f, -28.695f, -26.976f, -26.307f, -26.098f, -25.543f, + -25.981f, -26.519f, -26.530f, -26.337f, -25.862f, -26.418f, -27.330f, -28.175f, -28.664f, + -26.757f, -23.508f, -19.380f, -18.776f, -17.884f, -17.908f, -17.592f, -19.057f, -20.640f, + -20.764f, -19.075f, -17.300f, -15.952f, -15.323f, -14.969f, -14.915f, -14.736f, -14.715f, + -14.820f, -15.147f, -15.554f, -16.349f, -17.417f, -18.658f, -20.007f, -21.492f, -23.293f, + -25.210f, -27.202f, -28.870f, -30.647f, -32.308f, -33.671f, -34.914f, -36.152f, -38.679f, + -40.603f, -38.649f, -37.126f, -38.555f, -39.113f, -38.355f, -37.187f, -36.453f, -33.667f, + -30.094f, -26.687f, -24.930f, -24.986f, -26.577f, -26.551f, -23.944f, -22.191f, -20.465f, + -17.100f, -14.337f, -11.377f, -8.020f, -4.422f, 0.615f, 5.655f, 4.979f, 4.806f, + 15.538f, 26.548f, 27.910f, 31.102f, 32.988f, 35.317f, 37.544f, 39.378f, 41.254f, + 40.794f, 40.681f, 38.076f, 34.751f, 32.756f, 31.108f, 28.497f, 26.055f, 24.852f, + 22.610f, 19.156f, 16.218f, 13.435f, 10.641f, 8.397f, 5.876f, 3.717f, 0.587f, + -3.548f, -3.850f, -5.892f, -7.977f, -9.540f, -11.631f, -13.258f, -13.976f, -16.081f, + -17.710f, -19.120f, -20.434f, -22.107f, -22.382f, -23.509f, -23.373f, -22.897f, -22.385f, + -21.623f, -20.671f, -19.565f, -19.237f, -19.705f, -20.619f, -22.666f, -24.955f, -25.465f, + -25.595f, -25.440f, -25.517f, -25.740f, -25.259f, -25.376f, -25.353f, -24.747f, -24.772f, + -23.693f, -24.748f, -25.769f, -23.534f, -24.095f, -27.370f, -27.699f, -26.020f, -24.612f, + -23.674f, -20.655f, -17.586f, -15.560f, -15.422f, -14.963f, -12.317f, -10.791f, -10.173f, + -10.094f, -10.015f, -8.653f, -5.719f, -3.330f, -2.254f, -1.817f, -2.053f, -0.810f, + 0.654f, 4.146f, 6.597f, 9.197f, 10.652f, 10.651f, 11.742f, 11.833f, 12.815f, + 13.606f}, + {-29.534f, -29.511f, -29.283f, -29.551f, -29.046f, -27.533f, -27.071f, -26.872f, -26.435f, + -27.081f, -27.768f, -27.605f, -27.325f, -27.287f, -28.169f, -28.633f, -28.687f, -28.493f, + -27.041f, -25.066f, -21.698f, -20.145f, -18.059f, -17.493f, -18.949f, -19.314f, -21.763f, + -21.854f, -20.665f, -18.702f, -17.094f, -16.486f, -16.171f, -16.057f, -15.923f, -15.827f, + -16.007f, -16.265f, -16.843f, -17.420f, -18.324f, -19.450f, -20.916f, -22.358f, -24.112f, + -25.968f, -27.698f, -29.362f, -31.014f, -32.695f, -33.926f, -35.212f, -36.256f, -39.004f, + -40.615f, -40.078f, -38.134f, -38.227f, -38.281f, -37.481f, -36.208f, -33.612f, -28.901f, + -25.989f, -23.834f, -21.998f, -20.904f, -21.314f, -22.105f, -21.917f, -18.734f, -16.581f, + -14.122f, -10.313f, -8.927f, -5.196f, -0.509f, 2.950f, 7.134f, 4.606f, 9.709f, + 20.761f, 30.445f, 31.081f, 33.957f, 36.105f, 38.694f, 40.600f, 42.422f, 45.283f, + 45.363f, 44.526f, 41.257f, 39.681f, 36.528f, 34.387f, 31.255f, 31.034f, 28.884f, + 26.341f, 24.161f, 20.371f, 17.514f, 15.101f, 12.485f, 9.406f, 7.226f, 4.371f, + 0.835f, 0.127f, -1.877f, -4.205f, -5.743f, -7.715f, -9.984f, -10.748f, -12.855f, + -14.906f, -16.404f, -17.689f, -19.020f, -19.524f, -20.720f, -20.737f, -20.682f, -20.737f, + -17.143f, -16.406f, -16.696f, -16.443f, -16.085f, -16.777f, -19.127f, -21.659f, -22.330f, + -22.088f, -22.150f, -22.708f, -23.324f, -23.205f, -23.151f, -23.478f, -23.237f, -22.815f, + -22.350f, -22.629f, -23.623f, -22.794f, -21.607f, -25.430f, -27.821f, -25.798f, -24.417f, + -22.946f, -19.971f, -17.084f, -15.357f, -14.514f, -14.619f, -12.024f, -11.124f, -10.366f, + -9.742f, -9.612f, -8.216f, -5.668f, -3.013f, -1.874f, -1.726f, -2.785f, -0.938f, + 0.796f, 4.157f, 6.610f, 9.391f, 10.486f, 10.586f, 11.731f, 11.687f, 12.808f, + 13.606f}, + {-29.534f, -29.548f, -29.369f, -29.731f, -29.395f, -28.115f, -27.804f, -27.646f, -27.283f, + -28.017f, -28.834f, -28.760f, -28.515f, -28.655f, -29.377f, -29.918f, -29.364f, -28.785f, + -27.778f, -26.094f, -23.851f, -22.089f, -19.212f, -18.452f, -20.825f, -19.717f, -22.258f, + -22.737f, -21.983f, -19.942f, -18.363f, -17.560f, -17.274f, -17.051f, -17.022f, -17.024f, + -17.201f, -17.452f, -17.829f, -18.356f, -19.226f, -20.312f, -21.735f, -23.380f, -24.939f, + -26.539f, -28.167f, -29.798f, -31.230f, -32.712f, -34.173f, -35.362f, -36.474f, -38.876f, + -40.127f, -38.113f, -35.634f, -35.786f, -36.104f, -35.569f, -32.685f, -28.097f, -24.116f, + -23.006f, -22.459f, -21.131f, -18.891f, -16.382f, -15.200f, -17.952f, -17.091f, -14.534f, + -11.650f, -8.686f, -7.834f, -2.641f, 1.010f, 4.927f, 7.826f, 4.318f, 10.214f, + 24.158f, 33.203f, 33.550f, 37.091f, 39.504f, 41.982f, 43.132f, 45.144f, 48.242f, + 50.179f, 49.606f, 45.141f, 44.907f, 42.493f, 39.233f, 34.888f, 33.319f, 33.401f, + 30.803f, 28.674f, 25.159f, 22.342f, 19.191f, 16.587f, 13.667f, 13.080f, 7.915f, + 4.901f, 3.546f, 1.801f, -0.896f, -2.269f, -4.052f, -6.069f, -7.472f, -8.657f, + -10.829f, -12.169f, -13.229f, -14.930f, -15.776f, -17.101f, -17.938f, -18.601f, -18.991f, + -16.510f, -15.599f, -15.615f, -14.017f, -13.175f, -13.779f, -15.585f, -17.660f, -18.422f, + -18.123f, -18.838f, -19.934f, -20.748f, -21.033f, -21.006f, -21.306f, -21.005f, -20.468f, + -20.681f, -20.437f, -21.774f, -21.345f, -20.345f, -22.665f, -27.412f, -26.264f, -24.151f, + -22.260f, -19.649f, -17.235f, -15.222f, -13.924f, -14.107f, -12.349f, -11.402f, -10.225f, + -9.637f, -9.187f, -7.750f, -5.452f, -2.773f, -2.028f, -1.566f, -3.087f, -1.036f, + 1.002f, 4.149f, 6.768f, 9.644f, 10.277f, 10.547f, 11.702f, 11.547f, 12.803f, + 13.606f}, + {-29.534f, -29.584f, -29.454f, -29.901f, -29.740f, -28.711f, -28.491f, -28.411f, -28.094f, + -28.830f, -29.703f, -29.928f, -30.034f, -30.159f, -30.385f, -30.967f, -30.228f, -29.652f, + -28.800f, -26.612f, -24.262f, -23.327f, -21.711f, -21.647f, -22.080f, -20.094f, -22.243f, + -23.374f, -23.020f, -21.173f, -19.630f, -18.745f, -18.348f, -18.175f, -18.079f, -17.947f, + -18.156f, -18.443f, -18.817f, -19.415f, -20.084f, -21.170f, -22.377f, -23.859f, -25.507f, + -27.126f, -28.679f, -30.063f, -31.513f, -32.969f, -34.106f, -35.328f, -36.653f, -38.504f, + -39.493f, -34.807f, -32.519f, -33.094f, -34.522f, -31.425f, -29.165f, -26.281f, -21.458f, + -20.305f, -19.473f, -18.287f, -16.170f, -13.090f, -11.878f, -11.547f, -12.406f, -13.835f, + -10.015f, -5.705f, -5.653f, -1.318f, 3.137f, 7.415f, 10.343f, 7.216f, 11.007f, + 27.485f, 33.992f, 36.847f, 39.933f, 42.651f, 43.891f, 45.119f, 47.592f, 50.195f, + 54.232f, 54.504f, 53.321f, 49.957f, 47.186f, 44.130f, 41.553f, 36.182f, 35.967f, + 34.719f, 32.467f, 30.259f, 26.834f, 23.808f, 21.075f, 18.009f, 16.279f, 12.329f, + 9.283f, 6.744f, 5.360f, 3.444f, 1.199f, -0.191f, -1.912f, -3.614f, -5.637f, + -7.149f, -8.730f, -9.258f, -10.758f, -12.119f, -13.170f, -14.870f, -15.363f, -15.558f, + -15.473f, -15.600f, -15.363f, -13.474f, -10.692f, -10.665f, -11.383f, -13.028f, -13.863f, + -14.792f, -16.181f, -17.040f, -18.256f, -18.634f, -18.803f, -18.721f, -18.941f, -18.704f, + -18.992f, -18.471f, -19.603f, -19.053f, -19.112f, -20.308f, -25.678f, -25.675f, -23.446f, + -22.406f, -20.202f, -18.006f, -15.363f, -13.584f, -13.326f, -12.318f, -11.437f, -9.968f, + -9.592f, -8.978f, -7.361f, -5.168f, -2.821f, -2.324f, -1.506f, -2.966f, -1.028f, + 1.243f, 4.168f, 7.029f, 9.880f, 10.031f, 10.528f, 11.647f, 11.414f, 12.801f, + 13.606f}, + {-29.534f, -29.621f, -29.537f, -30.060f, -30.079f, -29.309f, -29.137f, -29.161f, -28.901f, + -29.604f, -30.470f, -31.011f, -31.582f, -31.739f, -31.708f, -31.943f, -31.133f, -30.521f, + -29.656f, -27.216f, -24.779f, -24.164f, -23.886f, -24.713f, -22.511f, -20.685f, -22.965f, + -24.219f, -24.095f, -22.240f, -20.702f, -19.747f, -19.196f, -19.042f, -18.892f, -18.941f, + -19.017f, -19.197f, -19.387f, -20.057f, -20.776f, -21.565f, -22.991f, -24.597f, -25.884f, + -27.312f, -28.772f, -30.353f, -31.650f, -32.793f, -34.197f, -35.299f, -36.300f, -38.283f, + -38.458f, -33.102f, -30.618f, -30.416f, -31.414f, -30.299f, -27.495f, -23.436f, -20.353f, + -17.952f, -17.492f, -15.962f, -12.847f, -10.374f, -8.570f, -8.551f, -7.216f, -7.309f, + -7.376f, -6.035f, -3.300f, 1.308f, 5.574f, 10.537f, 13.216f, 10.806f, 13.714f, + 30.686f, 33.469f, 39.470f, 42.250f, 45.070f, 48.119f, 50.100f, 51.129f, 53.740f, + 54.842f, 58.143f, 56.205f, 53.673f, 52.227f, 49.404f, 46.609f, 43.540f, 38.254f, + 38.453f, 36.634f, 34.878f, 30.672f, 28.028f, 25.511f, 22.651f, 19.750f, 16.425f, + 13.368f, 10.496f, 9.273f, 8.107f, 5.472f, 3.744f, 2.145f, 0.524f, -1.489f, + -3.774f, -5.210f, -6.137f, -7.067f, -7.792f, -9.240f, -11.015f, -11.316f, -11.191f, + -11.595f, -12.261f, -12.513f, -12.244f, -10.045f, -8.243f, -7.496f, -8.360f, -10.218f, + -12.127f, -13.483f, -14.796f, -15.627f, -16.064f, -16.455f, -16.307f, -16.329f, -17.003f, + -17.134f, -16.588f, -17.816f, -17.112f, -17.010f, -19.101f, -22.986f, -24.061f, -21.780f, + -22.797f, -20.460f, -18.224f, -15.696f, -13.326f, -12.407f, -11.848f, -11.145f, -9.779f, + -9.258f, -8.953f, -7.058f, -5.032f, -3.067f, -2.220f, -1.699f, -2.634f, -0.885f, + 1.464f, 4.227f, 7.306f, 10.018f, 9.763f, 10.522f, 11.559f, 11.294f, 12.802f, + 13.606f}, + {-29.534f, -29.657f, -29.619f, -30.210f, -30.410f, -29.896f, -29.766f, -29.892f, -29.732f, + -30.401f, -31.246f, -31.974f, -32.809f, -33.154f, -33.272f, -33.120f, -31.982f, -31.114f, + -30.544f, -28.229f, -26.114f, -25.074f, -24.689f, -25.656f, -23.616f, -22.364f, -24.647f, + -25.397f, -25.173f, -23.223f, -21.793f, -20.780f, -20.266f, -20.008f, -19.680f, -19.606f, + -19.652f, -19.931f, -20.011f, -20.547f, -21.285f, -22.309f, -23.533f, -24.704f, -26.010f, + -27.409f, -28.875f, -30.204f, -31.406f, -32.741f, -34.210f, -35.370f, -36.881f, -38.944f, + -37.894f, -32.179f, -28.125f, -27.113f, -27.085f, -26.181f, -24.396f, -22.593f, -19.857f, + -17.628f, -16.613f, -16.284f, -11.402f, -8.737f, -7.477f, -7.742f, -6.219f, -3.547f, + -5.022f, -3.526f, -0.966f, 3.531f, 7.714f, 12.252f, 14.930f, 13.390f, 16.273f, + 34.751f, 35.471f, 40.810f, 44.126f, 46.913f, 49.921f, 52.559f, 53.354f, 53.783f, + 54.745f, 57.704f, 57.832f, 56.617f, 55.528f, 54.423f, 53.092f, 48.284f, 45.877f, + 42.261f, 39.686f, 39.297f, 35.967f, 32.109f, 29.938f, 26.964f, 24.317f, 21.133f, + 17.980f, 14.571f, 13.242f, 12.443f, 10.243f, 7.775f, 6.108f, 5.016f, 3.069f, + 0.662f, -1.217f, -2.310f, -3.048f, -4.381f, -5.602f, -6.483f, -6.873f, -6.782f, + -6.754f, -8.034f, -8.768f, -9.364f, -8.466f, -6.575f, -4.932f, -4.342f, -6.106f, + -8.439f, -10.635f, -11.877f, -12.666f, -13.399f, -13.628f, -13.585f, -13.970f, -14.886f, + -14.955f, -14.707f, -14.554f, -14.580f, -15.549f, -18.788f, -20.236f, -21.408f, -19.634f, + -21.904f, -19.804f, -17.951f, -15.497f, -12.716f, -11.613f, -11.571f, -10.776f, -9.629f, + -8.913f, -8.856f, -6.777f, -4.953f, -3.144f, -1.609f, -2.166f, -2.366f, -0.680f, + 1.598f, 4.293f, 7.497f, 9.989f, 9.493f, 10.520f, 11.437f, 11.191f, 12.805f, + 13.606f}, + {-29.534f, -29.693f, -29.698f, -30.352f, -30.730f, -30.463f, -30.404f, -30.600f, -30.588f, + -31.212f, -32.076f, -32.881f, -33.744f, -34.307f, -34.551f, -34.359f, -32.871f, -31.748f, + -31.545f, -29.317f, -26.860f, -25.742f, -25.829f, -26.722f, -24.605f, -24.653f, -26.651f, + -26.670f, -26.152f, -24.243f, -22.709f, -21.737f, -21.129f, -20.851f, -20.580f, -20.399f, + -20.280f, -20.570f, -20.665f, -20.940f, -21.735f, -22.782f, -24.017f, -25.094f, -26.171f, + -27.345f, -28.679f, -30.048f, -31.318f, -32.782f, -34.099f, -35.307f, -36.338f, -38.541f, + -38.079f, -31.899f, -27.927f, -26.918f, -26.512f, -25.103f, -23.813f, -21.428f, -19.521f, + -17.979f, -16.634f, -15.268f, -10.279f, -7.247f, -7.081f, -6.175f, -2.822f, -0.304f, + 0.293f, -0.496f, 2.136f, 6.447f, 10.386f, 14.510f, 17.190f, 15.738f, 19.300f, + 33.271f, 36.796f, 42.863f, 46.371f, 47.114f, 48.083f, 53.708f, 51.171f, 53.808f, + 52.813f, 57.685f, 57.086f, 54.819f, 55.448f, 57.107f, 53.021f, 51.525f, 50.348f, + 48.832f, 44.822f, 41.551f, 38.218f, 35.814f, 33.586f, 31.448f, 28.715f, 25.224f, + 22.140f, 19.393f, 16.598f, 15.311f, 13.961f, 13.076f, 9.712f, 8.932f, 7.289f, + 4.777f, 3.218f, 1.871f, 1.158f, -0.654f, -1.791f, -2.429f, -2.527f, -2.354f, + -1.937f, -3.478f, -4.587f, -5.026f, -4.390f, -3.120f, -2.370f, -2.189f, -3.561f, + -4.999f, -7.318f, -8.291f, -9.360f, -10.460f, -10.953f, -11.018f, -11.603f, -12.471f, + -12.778f, -12.649f, -11.390f, -12.986f, -15.905f, -18.664f, -19.024f, -19.373f, -19.420f, + -19.685f, -18.951f, -17.522f, -14.939f, -12.185f, -11.103f, -11.175f, -10.263f, -9.275f, + -8.924f, -8.539f, -6.516f, -4.641f, -2.847f, -0.860f, -2.715f, -2.293f, -0.535f, + 1.603f, 4.311f, 7.523f, 9.763f, 9.243f, 10.511f, 11.279f, 11.109f, 12.812f, + 13.606f}, + {-29.534f, -29.728f, -29.775f, -30.485f, -31.035f, -31.004f, -31.073f, -31.273f, -31.428f, + -31.976f, -32.924f, -33.836f, -34.718f, -35.344f, -35.349f, -35.298f, -33.907f, -32.581f, + -32.137f, -30.267f, -27.628f, -26.278f, -26.484f, -27.824f, -24.923f, -26.778f, -28.332f, + -27.846f, -27.256f, -25.292f, -23.695f, -22.634f, -22.017f, -21.646f, -21.235f, -21.070f, + -21.061f, -21.322f, -21.184f, -21.497f, -22.006f, -23.158f, -24.318f, -25.379f, -26.279f, + -27.482f, -28.786f, -30.000f, -31.212f, -32.597f, -33.805f, -34.863f, -36.246f, -38.397f, + -38.487f, -33.668f, -29.882f, -27.675f, -25.909f, -24.736f, -22.482f, -20.721f, -19.021f, + -17.254f, -13.844f, -12.179f, -7.521f, -5.225f, -5.963f, -3.294f, 0.652f, 3.647f, + 5.690f, 7.180f, 8.077f, 9.770f, 14.334f, 18.198f, 20.578f, 17.591f, 27.170f, + 35.991f, 37.276f, 44.209f, 47.217f, 50.277f, 51.002f, 56.046f, 56.867f, 55.312f, + 53.638f, 55.995f, 53.885f, 54.624f, 56.882f, 59.152f, 56.383f, 53.399f, 51.643f, + 48.990f, 49.922f, 47.600f, 43.140f, 38.280f, 33.769f, 31.930f, 30.801f, 28.128f, + 24.882f, 22.061f, 20.100f, 17.927f, 17.282f, 16.274f, 14.150f, 12.350f, 10.356f, + 9.379f, 7.445f, 5.641f, 4.206f, 2.799f, 1.690f, 1.124f, 1.133f, 1.554f, + 1.553f, 0.390f, -0.687f, -1.374f, -0.752f, 0.653f, 0.036f, -0.702f, -1.565f, + -1.770f, -3.076f, -4.346f, -5.680f, -6.922f, -7.840f, -8.267f, -8.716f, -10.098f, + -10.904f, -10.920f, -9.690f, -11.964f, -14.099f, -17.819f, -18.230f, -18.905f, -21.728f, + -18.300f, -18.219f, -17.091f, -14.678f, -12.066f, -10.941f, -10.455f, -9.515f, -8.694f, + -9.043f, -8.112f, -6.276f, -4.064f, -2.388f, -0.329f, -3.039f, -2.338f, -0.509f, + 1.498f, 4.236f, 7.357f, 9.354f, 9.033f, 10.483f, 11.088f, 11.051f, 12.821f, + 13.606f}, + {-29.534f, -29.763f, -29.851f, -30.611f, -31.323f, -31.515f, -31.778f, -31.902f, -32.194f, + -32.652f, -33.756f, -34.890f, -35.914f, -36.396f, -35.991f, -35.873f, -34.898f, -33.280f, + -32.178f, -30.891f, -28.964f, -27.199f, -26.615f, -27.657f, -26.059f, -28.877f, -29.756f, + -28.953f, -28.353f, -26.241f, -24.625f, -23.594f, -22.781f, -22.382f, -21.991f, -21.631f, + -21.727f, -21.429f, -21.553f, -21.976f, -22.668f, -23.382f, -24.462f, -25.450f, -26.389f, + -27.350f, -28.569f, -29.994f, -31.151f, -32.482f, -33.574f, -34.502f, -35.499f, -37.678f, + -38.507f, -34.648f, -30.380f, -28.227f, -25.458f, -24.343f, -22.596f, -20.454f, -18.069f, + -15.262f, -11.635f, -8.796f, -5.008f, -5.120f, -2.321f, 1.090f, 4.407f, 7.754f, + 8.468f, 12.246f, 13.906f, 15.436f, 19.364f, 23.024f, 23.389f, 22.827f, 36.360f, + 39.719f, 37.895f, 44.402f, 49.795f, 53.974f, 56.689f, 60.713f, 63.793f, 61.864f, + 58.348f, 56.354f, 54.462f, 56.886f, 58.526f, 61.821f, 59.608f, 55.120f, 53.832f, + 54.269f, 52.010f, 52.056f, 48.928f, 37.842f, 36.434f, 40.614f, 41.033f, 34.306f, + 30.586f, 23.796f, 21.269f, 18.538f, 18.852f, 18.608f, 17.438f, 14.959f, 13.099f, + 11.711f, 10.040f, 8.408f, 7.023f, 5.760f, 5.071f, 4.587f, 4.690f, 4.387f, + 4.307f, 4.283f, 3.011f, 1.948f, 2.711f, 2.802f, 2.366f, 1.283f, 0.312f, + 0.371f, 0.116f, -0.638f, -1.872f, -3.361f, -4.504f, -5.281f, -6.660f, -8.027f, + -8.983f, -9.359f, -8.871f, -10.156f, -12.612f, -15.910f, -16.614f, -17.266f, -21.518f, + -18.298f, -17.948f, -17.007f, -14.534f, -11.932f, -10.928f, -10.066f, -8.772f, -8.081f, + -8.870f, -7.726f, -5.969f, -3.511f, -2.104f, -0.048f, -2.960f, -2.346f, -0.539f, + 1.371f, 4.067f, 7.029f, 8.818f, 8.879f, 10.426f, 10.872f, 11.022f, 12.832f, + 13.606f}, + {-29.534f, -29.798f, -29.925f, -30.731f, -31.591f, -31.997f, -32.508f, -32.490f, -32.854f, + -33.274f, -34.595f, -36.001f, -37.151f, -37.399f, -36.721f, -36.295f, -35.620f, -33.839f, + -32.353f, -31.090f, -29.551f, -28.120f, -27.986f, -28.019f, -27.363f, -30.655f, -31.189f, + -30.060f, -29.216f, -27.319f, -25.546f, -24.347f, -23.716f, -23.096f, -22.731f, -22.355f, + -22.109f, -22.162f, -22.131f, -22.592f, -22.993f, -23.887f, -24.722f, -25.596f, -26.385f, + -27.425f, -28.613f, -29.841f, -30.962f, -32.290f, -33.247f, -34.122f, -35.268f, -36.958f, + -38.303f, -34.549f, -29.791f, -28.336f, -25.887f, -23.638f, -22.392f, -19.992f, -16.213f, + -13.558f, -10.974f, -7.332f, -4.323f, -2.025f, 0.026f, 3.713f, 8.487f, 10.297f, + 11.538f, 15.765f, 19.845f, 21.324f, 21.649f, 25.657f, 24.985f, 27.071f, 33.589f, + 37.484f, 37.933f, 48.961f, 49.011f, 53.601f, 57.393f, 61.225f, 64.492f, 61.140f, + 61.248f, 64.002f, 58.716f, 59.202f, 61.194f, 61.879f, 66.521f, 58.542f, 56.199f, + 55.266f, 55.887f, 54.411f, 51.156f, 46.697f, 43.503f, 42.516f, 42.621f, 43.318f, + 39.063f, 30.166f, 22.427f, 20.733f, 21.698f, 26.463f, 24.261f, 17.954f, 16.376f, + 14.887f, 13.465f, 11.505f, 10.356f, 9.442f, 8.968f, 8.004f, 7.928f, 7.297f, + 7.676f, 7.249f, 6.695f, 5.995f, 4.529f, 4.734f, 4.280f, 3.452f, 2.325f, + 1.939f, 2.135f, 1.643f, 1.515f, 0.408f, -0.629f, -1.552f, -3.762f, -6.398f, + -7.605f, -8.208f, -7.984f, -9.757f, -10.943f, -13.936f, -14.617f, -14.656f, -17.633f, + -17.356f, -17.576f, -16.981f, -14.356f, -11.993f, -11.111f, -10.484f, -8.418f, -7.508f, + -8.352f, -7.362f, -5.587f, -3.231f, -2.014f, 0.102f, -2.590f, -2.266f, -0.497f, + 1.340f, 3.849f, 6.614f, 8.239f, 8.786f, 10.329f, 10.640f, 11.024f, 12.846f, + 13.606f}, + {-29.534f, -29.832f, -29.997f, -30.845f, -31.839f, -32.451f, -33.232f, -33.058f, -33.436f, + -33.948f, -35.518f, -37.095f, -38.171f, -38.292f, -37.418f, -36.726f, -36.307f, -34.756f, + -33.123f, -31.502f, -29.867f, -28.747f, -28.761f, -28.908f, -28.009f, -31.556f, -32.265f, + -31.238f, -30.001f, -28.125f, -26.216f, -25.194f, -24.364f, -23.764f, -23.368f, -22.915f, + -22.678f, -22.586f, -22.616f, -23.045f, -23.311f, -23.984f, -24.894f, -25.727f, -26.478f, + -27.407f, -28.399f, -29.550f, -30.872f, -31.954f, -32.900f, -33.775f, -34.585f, -36.328f, + -37.082f, -33.886f, -29.958f, -28.248f, -26.268f, -23.100f, -21.565f, -18.046f, -15.422f, + -12.570f, -10.595f, -6.328f, -3.569f, -0.489f, 3.265f, 6.408f, 9.455f, 11.422f, + 14.178f, 19.355f, 22.443f, 25.630f, 26.951f, 29.028f, 29.507f, 28.989f, 27.231f, + 34.638f, 41.267f, 48.114f, 51.427f, 57.115f, 60.801f, 61.360f, 61.228f, 64.379f, + 63.128f, 64.533f, 58.998f, 61.830f, 63.428f, 63.829f, 65.250f, 67.063f, 59.613f, + 52.945f, 54.297f, 55.089f, 52.480f, 49.791f, 47.889f, 41.154f, 37.840f, 40.548f, + 37.027f, 32.601f, 30.723f, 27.500f, 23.402f, 19.619f, 15.414f, 19.787f, 19.136f, + 17.443f, 16.360f, 14.985f, 14.063f, 13.253f, 11.940f, 11.201f, 11.002f, 10.593f, + 10.452f, 9.991f, 9.802f, 9.966f, 8.405f, 6.959f, 6.005f, 5.458f, 4.352f, + 4.087f, 3.757f, 3.634f, 3.054f, 3.268f, 2.681f, 2.052f, -0.202f, -4.190f, + -6.069f, -6.074f, -6.706f, -7.771f, -8.843f, -11.199f, -11.683f, -12.701f, -14.181f, + -15.497f, -16.966f, -16.995f, -14.403f, -12.476f, -11.911f, -11.522f, -8.628f, -7.050f, + -7.609f, -6.987f, -5.260f, -3.168f, -1.841f, 0.107f, -2.203f, -2.207f, -0.317f, + 1.477f, 3.648f, 6.199f, 7.706f, 8.749f, 10.186f, 10.406f, 11.060f, 12.862f, + 13.606f}, + {-29.534f, -29.865f, -30.067f, -30.955f, -32.067f, -32.879f, -33.917f, -33.645f, -34.037f, + -34.779f, -36.561f, -38.123f, -38.994f, -39.207f, -38.050f, -37.280f, -37.314f, -35.962f, + -34.044f, -32.459f, -30.926f, -29.592f, -28.654f, -29.181f, -29.001f, -31.932f, -33.079f, + -32.014f, -30.917f, -28.883f, -26.882f, -25.905f, -25.005f, -24.351f, -23.964f, -23.560f, + -23.241f, -23.123f, -23.031f, -23.402f, -23.620f, -24.154f, -24.846f, -25.605f, -26.340f, + -27.356f, -28.177f, -29.414f, -30.455f, -31.522f, -32.436f, -32.997f, -34.087f, -35.448f, + -36.426f, -33.035f, -29.069f, -26.591f, -23.809f, -24.026f, -20.620f, -17.058f, -14.125f, + -12.422f, -10.106f, -6.998f, -3.829f, 1.227f, 4.890f, 6.992f, 9.698f, 13.432f, + 17.480f, 21.931f, 24.825f, 28.139f, 29.352f, 32.432f, 34.984f, 29.966f, 26.926f, + 32.270f, 43.313f, 47.518f, 52.077f, 57.074f, 59.324f, 57.860f, 61.451f, 60.564f, + 56.136f, 63.179f, 60.424f, 64.867f, 65.911f, 65.904f, 65.849f, 66.460f, 67.233f, + 60.356f, 61.728f, 59.888f, 55.139f, 51.367f, 50.390f, 41.604f, 33.232f, 32.912f, + 31.476f, 30.213f, 27.974f, 25.901f, 24.078f, 16.777f, 17.619f, 21.980f, 22.074f, + 20.629f, 19.604f, 18.731f, 17.497f, 16.112f, 15.173f, 14.828f, 14.462f, 13.685f, + 12.944f, 13.164f, 12.697f, 13.156f, 11.325f, 10.018f, 8.425f, 7.647f, 6.656f, + 5.624f, 5.369f, 4.855f, 4.955f, 4.560f, 4.627f, 4.145f, 2.388f, -1.788f, + -4.010f, -4.229f, -4.470f, -4.980f, -6.673f, -8.112f, -9.531f, -11.397f, -12.461f, + -14.288f, -16.323f, -17.012f, -14.589f, -13.340f, -13.506f, -12.715f, -9.063f, -6.802f, + -6.871f, -6.747f, -5.021f, -3.069f, -1.438f, -0.110f, -1.977f, -2.296f, -0.064f, + 1.759f, 3.512f, 5.853f, 7.292f, 8.751f, 9.997f, 10.186f, 11.132f, 12.881f, + 13.606f}, + {-29.534f, -29.898f, -30.136f, -31.060f, -32.275f, -33.283f, -34.528f, -34.296f, -34.784f, + -35.793f, -37.646f, -39.066f, -39.842f, -40.242f, -38.885f, -38.134f, -38.478f, -36.873f, + -34.706f, -33.263f, -31.743f, -30.422f, -29.395f, -29.668f, -29.991f, -32.357f, -33.925f, + -32.472f, -31.796f, -29.628f, -27.603f, -26.534f, -25.694f, -25.060f, -24.537f, -24.129f, + -23.841f, -23.655f, -23.615f, -23.593f, -23.728f, -24.196f, -24.818f, -25.387f, -26.100f, + -26.987f, -27.753f, -28.791f, -29.886f, -30.990f, -31.830f, -32.523f, -33.494f, -34.595f, + -35.587f, -32.996f, -27.202f, -25.565f, -24.174f, -21.342f, -20.387f, -16.777f, -13.566f, + -10.837f, -8.183f, -6.319f, -3.052f, 1.609f, 4.504f, 7.617f, 11.171f, 15.869f, + 19.787f, 24.294f, 27.032f, 30.233f, 32.355f, 35.340f, 36.514f, 31.208f, 33.261f, + 37.336f, 45.255f, 48.612f, 54.592f, 55.795f, 55.996f, 57.871f, 61.181f, 50.058f, + 54.811f, 66.814f, 64.072f, 67.831f, 68.268f, 67.058f, 67.253f, 69.252f, 70.642f, + 63.685f, 64.799f, 61.835f, 58.447f, 53.136f, 52.478f, 44.059f, 41.375f, 39.762f, + 35.516f, 33.263f, 31.119f, 29.019f, 26.768f, 18.564f, 21.432f, 25.200f, 25.744f, + 24.076f, 22.912f, 21.599f, 20.599f, 19.035f, 17.973f, 17.676f, 17.916f, 17.113f, + 15.883f, 15.757f, 15.309f, 14.957f, 14.146f, 14.160f, 12.627f, 10.619f, 9.415f, + 8.129f, 7.215f, 6.650f, 6.565f, 6.752f, 6.554f, 5.990f, 4.479f, 0.194f, + -1.669f, -1.775f, -1.881f, -3.791f, -4.830f, -6.330f, -7.718f, -10.008f, -11.581f, + -13.594f, -15.668f, -17.111f, -14.867f, -14.176f, -15.190f, -13.783f, -9.408f, -6.763f, + -6.517f, -6.716f, -4.750f, -2.784f, -1.009f, -0.421f, -1.884f, -2.506f, 0.111f, + 2.068f, 3.445f, 5.607f, 7.034f, 8.767f, 9.765f, 9.995f, 11.240f, 12.901f, + 13.606f}, + {-29.534f, -29.930f, -30.203f, -31.162f, -32.464f, -33.662f, -35.045f, -35.037f, -35.766f, + -36.903f, -38.605f, -39.885f, -40.764f, -41.147f, -39.955f, -39.324f, -39.460f, -37.765f, + -35.565f, -33.697f, -32.267f, -31.154f, -30.085f, -30.644f, -30.611f, -32.864f, -34.844f, + -33.105f, -32.299f, -30.188f, -28.328f, -27.306f, -26.316f, -25.604f, -25.100f, -24.682f, + -24.270f, -24.014f, -23.815f, -23.689f, -23.635f, -24.040f, -24.557f, -25.269f, -25.880f, + -26.654f, -27.480f, -28.327f, -29.331f, -30.297f, -31.071f, -31.819f, -32.720f, -33.766f, + -34.879f, -33.176f, -26.322f, -23.308f, -21.822f, -20.487f, -17.679f, -16.012f, -13.666f, + -10.238f, -7.244f, -3.864f, -0.616f, 2.899f, 5.427f, 9.212f, 13.550f, 17.818f, + 21.834f, 25.781f, 29.174f, 31.843f, 34.010f, 36.246f, 38.432f, 36.798f, 33.094f, + 41.986f, 45.824f, 50.191f, 55.078f, 56.293f, 58.451f, 59.767f, 62.223f, 43.752f, + 50.794f, 67.688f, 70.406f, 70.052f, 69.117f, 63.696f, 70.126f, 71.314f, 71.351f, + 67.663f, 64.685f, 65.336f, 60.343f, 46.375f, 43.900f, 42.282f, 44.490f, 42.920f, + 38.355f, 35.324f, 32.589f, 30.783f, 28.288f, 21.516f, 23.365f, 28.146f, 27.917f, + 27.475f, 25.831f, 24.097f, 23.207f, 21.600f, 20.825f, 20.984f, 20.994f, 19.827f, + 18.838f, 18.500f, 17.900f, 17.468f, 17.210f, 17.975f, 17.574f, 15.223f, 12.740f, + 11.002f, 9.999f, 9.253f, 9.092f, 8.927f, 8.714f, 7.777f, 5.975f, 2.305f, + 0.996f, 0.330f, -0.224f, -1.565f, -1.660f, -4.767f, -5.769f, -8.239f, -10.835f, + -12.971f, -15.213f, -16.393f, -14.209f, -13.626f, -15.526f, -14.299f, -9.715f, -6.975f, + -6.686f, -6.665f, -4.474f, -2.413f, -0.818f, -0.520f, -1.848f, -2.653f, 0.095f, + 2.258f, 3.406f, 5.454f, 6.929f, 8.767f, 9.503f, 9.851f, 11.383f, 12.923f, + 13.606f}, + {-29.534f, -29.961f, -30.267f, -31.260f, -32.638f, -34.017f, -35.461f, -35.857f, -36.969f, + -37.955f, -39.294f, -40.519f, -41.519f, -41.542f, -40.771f, -40.561f, -40.357f, -39.228f, + -36.909f, -34.240f, -33.073f, -32.214f, -31.312f, -31.876f, -31.640f, -33.102f, -35.738f, + -33.567f, -32.719f, -30.720f, -28.809f, -27.911f, -27.043f, -26.151f, -25.504f, -24.993f, + -24.611f, -24.256f, -24.029f, -24.011f, -23.697f, -23.936f, -24.412f, -24.901f, -25.640f, + -26.364f, -27.068f, -27.849f, -28.851f, -29.647f, -30.386f, -31.087f, -31.844f, -32.562f, + -33.578f, -33.059f, -27.159f, -22.108f, -20.430f, -19.950f, -18.070f, -16.261f, -13.241f, + -10.260f, -6.193f, -2.897f, 0.290f, 3.561f, 6.698f, 11.480f, 15.531f, 19.703f, + 24.076f, 28.757f, 33.042f, 34.763f, 35.743f, 37.247f, 40.938f, 41.559f, 36.139f, + 41.786f, 47.617f, 50.333f, 54.167f, 57.506f, 58.875f, 60.048f, 63.931f, 45.464f, + 46.844f, 58.459f, 62.148f, 67.323f, 70.163f, 65.074f, 64.085f, 61.921f, 64.718f, + 68.014f, 64.066f, 55.470f, 47.427f, 44.967f, 46.293f, 45.467f, 44.695f, 42.304f, + 39.628f, 36.751f, 34.461f, 32.560f, 30.392f, 26.308f, 27.221f, 26.365f, 29.129f, + 30.014f, 29.283f, 27.057f, 25.363f, 24.271f, 23.724f, 23.965f, 23.575f, 22.238f, + 21.553f, 20.538f, 20.456f, 20.209f, 20.383f, 20.708f, 21.037f, 18.812f, 16.011f, + 13.553f, 12.162f, 11.586f, 11.444f, 11.179f, 10.669f, 9.166f, 6.605f, 4.505f, + 3.546f, 2.140f, 1.701f, 1.192f, 0.828f, -3.184f, -4.113f, -6.690f, -10.100f, + -12.563f, -14.259f, -13.592f, -11.527f, -11.231f, -13.753f, -13.408f, -9.831f, -7.401f, + -7.027f, -6.424f, -4.339f, -2.167f, -0.830f, -0.266f, -1.873f, -2.569f, -0.106f, + 2.237f, 3.342f, 5.362f, 6.940f, 8.722f, 9.230f, 9.769f, 11.561f, 12.947f, + 13.606f}, + {-29.534f, -29.992f, -30.331f, -31.356f, -32.799f, -34.342f, -35.786f, -36.703f, -38.255f, + -38.809f, -39.705f, -40.945f, -41.903f, -41.512f, -41.016f, -41.509f, -41.253f, -40.294f, + -37.750f, -34.810f, -33.576f, -33.194f, -33.580f, -33.944f, -33.404f, -33.687f, -36.595f, + -34.195f, -33.574f, -31.306f, -29.504f, -28.581f, -27.443f, -26.488f, -25.728f, -24.896f, + -24.388f, -23.826f, -23.427f, -23.486f, -23.466f, -23.723f, -24.094f, -24.688f, -25.265f, + -25.997f, -26.662f, -27.328f, -28.294f, -29.025f, -29.691f, -30.295f, -30.927f, -31.809f, + -32.704f, -32.553f, -27.695f, -21.315f, -19.332f, -18.813f, -17.339f, -16.439f, -12.382f, + -8.247f, -1.866f, -2.565f, 1.973f, 6.187f, 10.091f, 13.878f, 17.720f, 22.142f, + 27.261f, 31.443f, 34.158f, 36.615f, 37.662f, 39.117f, 43.283f, 45.749f, 42.028f, + 37.418f, 45.588f, 50.058f, 54.362f, 57.946f, 58.806f, 58.785f, 61.523f, 54.522f, + 68.556f, 65.387f, 56.185f, 55.833f, 61.785f, 53.469f, 45.248f, 51.153f, 55.077f, + 50.729f, 49.711f, 51.713f, 52.089f, 51.194f, 49.570f, 47.087f, 44.895f, 42.435f, + 39.925f, 38.000f, 35.469f, 34.070f, 32.325f, 29.781f, 25.055f, 25.108f, 28.907f, + 31.154f, 30.613f, 29.244f, 28.390f, 27.216f, 26.314f, 26.118f, 25.895f, 25.322f, + 24.296f, 23.290f, 22.890f, 23.026f, 23.868f, 24.367f, 22.542f, 21.006f, 18.755f, + 16.226f, 14.209f, 13.398f, 13.621f, 12.867f, 11.805f, 10.050f, 7.989f, 5.862f, + 5.183f, 3.816f, 3.799f, 3.866f, 2.355f, -1.271f, -3.158f, -5.788f, -9.007f, + -12.051f, -12.509f, -10.005f, -8.162f, -7.986f, -10.280f, -10.790f, -9.507f, -7.759f, + -7.123f, -6.153f, -4.260f, -2.118f, -0.777f, 0.136f, -1.947f, -2.276f, -0.388f, + 2.013f, 3.226f, 5.299f, 7.004f, 8.609f, 8.968f, 9.760f, 11.770f, 12.971f, + 13.606f}, + {-29.534f, -30.021f, -30.392f, -31.450f, -32.949f, -34.632f, -36.037f, -37.486f, -39.405f, + -39.415f, -39.986f, -41.245f, -42.063f, -41.677f, -41.180f, -42.140f, -41.749f, -39.617f, + -37.278f, -35.259f, -34.458f, -34.542f, -34.949f, -36.387f, -35.108f, -34.608f, -37.419f, + -35.128f, -34.376f, -31.985f, -30.338f, -29.132f, -27.764f, -26.778f, -25.893f, -24.854f, + -24.171f, -23.549f, -23.040f, -22.911f, -23.097f, -23.369f, -23.816f, -24.462f, -24.963f, + -25.736f, -26.458f, -27.073f, -27.818f, -28.472f, -28.933f, -29.424f, -29.835f, -30.363f, + -31.232f, -31.537f, -27.670f, -21.133f, -20.135f, -20.238f, -18.365f, -16.116f, -12.401f, + -7.152f, 0.227f, 0.211f, 3.366f, 8.179f, 12.527f, 15.930f, 20.568f, 23.501f, + 28.264f, 32.873f, 34.618f, 37.472f, 38.925f, 41.965f, 44.724f, 47.967f, 46.665f, + 34.138f, 42.174f, 49.514f, 53.494f, 57.663f, 59.135f, 57.934f, 59.343f, 67.793f, + 72.155f, 71.211f, 68.269f, 61.556f, 65.198f, 55.527f, 60.250f, 61.977f, 61.455f, + 60.184f, 58.561f, 57.189f, 55.140f, 52.625f, 50.113f, 47.347f, 45.276f, 43.001f, + 41.007f, 38.838f, 36.471f, 35.344f, 33.921f, 32.117f, 28.926f, 24.479f, 28.159f, + 31.978f, 31.217f, 30.280f, 29.680f, 29.285f, 28.998f, 28.235f, 28.060f, 28.147f, + 27.087f, 25.893f, 25.576f, 24.291f, 24.167f, 26.288f, 24.573f, 22.224f, 20.379f, + 17.957f, 16.762f, 15.861f, 16.049f, 14.285f, 11.962f, 10.721f, 9.342f, 7.556f, + 6.668f, 5.382f, 5.965f, 5.554f, 3.660f, 0.260f, -2.470f, -4.792f, -7.586f, + -11.288f, -10.556f, -6.848f, -5.585f, -5.498f, -6.653f, -7.492f, -8.653f, -7.838f, + -6.916f, -5.979f, -3.989f, -2.122f, -0.529f, 0.416f, -1.874f, -1.968f, -0.643f, + 1.678f, 3.077f, 5.242f, 7.054f, 8.421f, 8.746f, 9.835f, 12.006f, 12.997f, + 13.606f}, + {-29.534f, -30.050f, -30.452f, -31.542f, -33.092f, -34.881f, -36.237f, -38.116f, -40.207f, + -39.819f, -40.337f, -41.574f, -42.362f, -42.485f, -41.973f, -42.704f, -41.771f, -38.371f, + -36.714f, -36.065f, -36.139f, -36.383f, -35.717f, -37.323f, -35.904f, -35.056f, -38.154f, + -36.117f, -34.718f, -32.623f, -30.975f, -29.544f, -28.221f, -26.937f, -25.881f, -24.896f, + -24.114f, -23.362f, -22.691f, -22.511f, -22.821f, -22.857f, -23.280f, -23.763f, -24.379f, + -25.127f, -25.909f, -26.474f, -27.133f, -27.841f, -28.315f, -28.644f, -28.920f, -29.425f, + -30.176f, -30.612f, -26.915f, -20.666f, -19.435f, -18.100f, -16.637f, -14.720f, -11.983f, + -5.220f, 3.121f, 2.449f, 3.692f, 9.129f, 14.226f, 17.485f, 22.993f, 26.724f, + 28.818f, 30.889f, 33.818f, 36.834f, 41.878f, 44.016f, 45.951f, 48.946f, 49.787f, + 40.950f, 41.725f, 49.521f, 52.540f, 55.787f, 59.148f, 59.713f, 63.761f, 70.802f, + 73.505f, 72.402f, 69.304f, 67.432f, 66.449f, 67.603f, 67.609f, 66.622f, 64.790f, + 62.245f, 59.894f, 57.813f, 55.374f, 52.563f, 49.956f, 47.630f, 45.472f, 43.296f, + 41.478f, 39.314f, 37.391f, 35.904f, 35.110f, 34.086f, 32.413f, 28.762f, 25.055f, + 26.041f, 29.278f, 30.209f, 30.562f, 30.499f, 30.116f, 30.708f, 29.661f, 29.167f, + 29.600f, 28.724f, 25.586f, 22.982f, 23.407f, 26.623f, 26.435f, 23.995f, 22.291f, + 20.292f, 18.797f, 18.120f, 17.406f, 15.666f, 13.106f, 11.978f, 10.833f, 9.399f, + 8.004f, 7.207f, 8.200f, 7.472f, 5.732f, 1.361f, -1.077f, -3.263f, -6.124f, + -10.505f, -9.451f, -4.765f, -4.273f, -4.901f, -4.993f, -5.426f, -7.267f, -7.618f, + -6.562f, -5.753f, -3.581f, -2.001f, -0.249f, 0.584f, -1.361f, -1.818f, -0.822f, + 1.342f, 2.949f, 5.183f, 7.036f, 8.164f, 8.592f, 9.994f, 12.266f, 13.023f, + 13.606f}, + {-29.534f, -30.078f, -30.509f, -31.633f, -33.230f, -35.084f, -36.407f, -38.532f, -40.558f, + -40.127f, -40.885f, -42.067f, -42.966f, -43.659f, -43.352f, -43.497f, -42.230f, -39.032f, + -37.639f, -37.349f, -36.867f, -36.946f, -36.619f, -36.708f, -36.408f, -35.483f, -38.987f, + -37.254f, -35.246f, -33.287f, -31.401f, -29.957f, -28.471f, -27.177f, -25.974f, -24.837f, + -23.791f, -23.005f, -22.449f, -22.141f, -22.409f, -22.395f, -22.671f, -23.262f, -23.804f, + -24.438f, -25.124f, -25.604f, -26.272f, -26.871f, -27.493f, -27.753f, -27.792f, -28.287f, + -29.210f, -28.386f, -23.947f, -19.137f, -17.724f, -16.238f, -14.407f, -12.107f, -10.259f, + -1.797f, 3.609f, 3.100f, 3.348f, 11.401f, 14.795f, 20.232f, 24.383f, 28.525f, + 31.876f, 33.408f, 35.033f, 39.084f, 42.481f, 45.728f, 49.110f, 51.997f, 52.229f, + 46.467f, 45.506f, 45.318f, 50.106f, 54.817f, 57.761f, 59.909f, 68.127f, 72.366f, + 76.604f, 73.326f, 72.358f, 72.731f, 71.136f, 69.890f, 68.196f, 66.701f, 64.336f, + 61.499f, 59.414f, 57.051f, 54.732f, 52.036f, 49.843f, 47.512f, 46.067f, 43.825f, + 41.420f, 39.758f, 37.807f, 36.193f, 35.165f, 35.124f, 35.144f, 33.203f, 28.254f, + 24.248f, 24.898f, 26.293f, 30.395f, 31.243f, 31.804f, 32.165f, 31.069f, 29.942f, + 27.716f, 26.918f, 25.810f, 24.776f, 22.967f, 23.528f, 24.571f, 25.405f, 25.271f, + 22.695f, 20.460f, 18.573f, 18.116f, 16.102f, 14.964f, 13.592f, 12.346f, 11.005f, + 9.797f, 9.198f, 10.469f, 8.861f, 7.126f, 2.176f, 0.589f, -1.486f, -4.620f, + -9.764f, -9.524f, -4.145f, -4.341f, -5.111f, -5.184f, -5.331f, -6.067f, -7.105f, + -6.162f, -5.316f, -3.314f, -1.753f, -0.146f, 0.866f, -0.353f, -1.811f, -0.931f, + 1.072f, 2.894f, 5.117f, 6.916f, 7.864f, 8.529f, 10.237f, 12.542f, 13.049f, + 13.606f}, + {-29.534f, -30.105f, -30.565f, -31.722f, -33.366f, -35.238f, -36.563f, -38.732f, -40.524f, + -40.442f, -41.610f, -42.745f, -43.707f, -44.616f, -44.689f, -44.723f, -43.877f, -41.469f, + -39.277f, -38.351f, -36.881f, -36.828f, -37.093f, -36.413f, -36.905f, -35.515f, -39.646f, + -38.085f, -35.791f, -33.807f, -31.932f, -30.271f, -28.599f, -27.250f, -25.847f, -24.703f, + -23.654f, -22.988f, -22.132f, -21.891f, -22.114f, -21.822f, -22.113f, -22.559f, -23.153f, + -23.618f, -24.163f, -24.660f, -25.198f, -25.994f, -26.331f, -26.923f, -26.748f, -27.172f, + -28.052f, -25.044f, -21.750f, -16.552f, -14.821f, -13.019f, -10.285f, -9.198f, -8.592f, + 0.011f, 1.203f, 3.495f, 4.508f, 12.905f, 15.585f, 22.265f, 24.230f, 28.364f, + 32.094f, 34.525f, 36.803f, 40.509f, 44.716f, 49.140f, 52.294f, 54.565f, 55.261f, + 51.742f, 46.677f, 41.798f, 34.941f, 43.155f, 56.643f, 58.588f, 68.866f, 73.940f, + 76.337f, 74.328f, 74.110f, 73.359f, 72.191f, 69.478f, 67.396f, 65.794f, 63.517f, + 60.753f, 58.579f, 56.355f, 54.318f, 51.891f, 49.940f, 48.014f, 46.015f, 43.939f, + 41.812f, 39.879f, 38.466f, 37.205f, 36.014f, 35.597f, 36.256f, 36.269f, 33.368f, + 28.972f, 25.904f, 24.359f, 25.716f, 29.264f, 31.243f, 32.673f, 32.313f, 31.020f, + 28.457f, 27.524f, 27.198f, 24.783f, 23.884f, 22.907f, 22.961f, 25.279f, 25.381f, + 23.763f, 21.139f, 19.562f, 18.905f, 17.627f, 16.818f, 15.810f, 13.997f, 12.712f, + 11.658f, 11.801f, 11.295f, 9.589f, 8.401f, 3.781f, 2.438f, 0.060f, -2.727f, + -8.459f, -8.661f, -3.655f, -4.668f, -5.029f, -5.191f, -5.617f, -5.829f, -6.426f, + -5.732f, -4.664f, -3.189f, -1.529f, -0.198f, 1.338f, 0.799f, -1.769f, -0.981f, + 0.875f, 2.920f, 5.033f, 6.695f, 7.557f, 8.575f, 10.555f, 12.830f, 13.076f, + 13.606f}, + {-29.534f, -30.131f, -30.620f, -31.811f, -33.502f, -35.346f, -36.716f, -38.775f, -40.326f, + -40.835f, -42.391f, -43.540f, -44.385f, -45.291f, -45.793f, -46.310f, -45.926f, -43.249f, + -39.974f, -38.613f, -37.613f, -37.317f, -37.245f, -36.781f, -37.409f, -35.871f, -40.187f, + -38.576f, -36.190f, -34.218f, -32.350f, -30.465f, -28.678f, -27.275f, -25.723f, -24.649f, + -23.651f, -22.785f, -21.896f, -21.455f, -21.618f, -21.268f, -21.515f, -21.916f, -22.480f, + -22.976f, -23.296f, -23.811f, -24.130f, -24.738f, -25.496f, -25.557f, -25.559f, -26.038f, + -25.984f, -22.202f, -18.195f, -14.558f, -12.249f, -8.810f, -6.130f, -4.116f, -5.796f, + 0.312f, 1.837f, 4.739f, 7.081f, 15.490f, 18.529f, 23.856f, 24.593f, 28.908f, + 32.961f, 36.472f, 39.050f, 42.548f, 47.734f, 51.513f, 53.545f, 57.043f, 57.786f, + 56.275f, 51.040f, 46.077f, 43.563f, 48.859f, 54.477f, 63.454f, 70.554f, 76.510f, + 72.741f, 74.425f, 74.322f, 74.421f, 72.110f, 69.736f, 67.146f, 65.909f, 64.034f, + 60.858f, 58.246f, 56.054f, 53.869f, 51.616f, 49.611f, 48.452f, 46.409f, 44.127f, + 42.281f, 40.493f, 39.010f, 37.952f, 36.972f, 36.728f, 37.200f, 34.286f, 36.186f, + 32.971f, 32.661f, 28.726f, 26.786f, 26.630f, 25.814f, 30.691f, 31.903f, 32.720f, + 30.003f, 29.132f, 27.961f, 25.842f, 24.943f, 23.745f, 23.109f, 26.275f, 24.454f, + 23.018f, 21.786f, 20.297f, 19.097f, 19.346f, 18.555f, 17.128f, 15.884f, 14.542f, + 13.104f, 13.459f, 12.351f, 11.086f, 9.827f, 5.640f, 3.737f, 1.537f, -1.126f, + -6.843f, -5.920f, -2.813f, -4.363f, -4.852f, -4.645f, -5.020f, -5.810f, -5.757f, + -5.240f, -3.919f, -2.966f, -1.456f, -0.252f, 1.753f, 1.612f, -1.556f, -0.964f, + 0.729f, 2.988f, 4.915f, 6.403f, 7.292f, 8.738f, 10.934f, 13.121f, 13.102f, + 13.606f}, + {-29.534f, -30.156f, -30.672f, -31.900f, -33.639f, -35.416f, -36.872f, -38.765f, -40.248f, + -41.349f, -43.122f, -44.376f, -45.080f, -46.184f, -47.091f, -47.755f, -46.807f, -43.408f, + -40.183f, -39.022f, -38.148f, -37.030f, -36.988f, -37.526f, -38.104f, -37.257f, -40.710f, + -39.262f, -36.494f, -34.608f, -32.671f, -30.466f, -28.726f, -27.181f, -25.619f, -24.487f, + -23.436f, -22.565f, -21.645f, -21.122f, -20.991f, -20.753f, -20.855f, -21.309f, -21.700f, + -22.243f, -22.589f, -23.065f, -23.296f, -23.458f, -24.200f, -24.024f, -24.230f, -24.655f, + -24.252f, -19.022f, -14.064f, -14.474f, -12.264f, -7.304f, -3.517f, -0.993f, 0.042f, + 0.512f, 4.390f, 6.667f, 9.880f, 19.153f, 21.349f, 25.896f, 27.511f, 31.394f, + 35.039f, 37.980f, 40.693f, 44.757f, 50.216f, 53.836f, 56.428f, 58.940f, 60.347f, + 59.849f, 58.995f, 53.909f, 52.503f, 58.730f, 65.159f, 68.542f, 70.688f, 79.491f, + 73.762f, 74.390f, 74.306f, 73.398f, 72.473f, 70.540f, 68.720f, 66.501f, 63.978f, + 61.640f, 58.137f, 55.787f, 53.810f, 52.016f, 50.048f, 48.737f, 46.421f, 44.399f, + 42.555f, 41.049f, 39.813f, 38.858f, 38.288f, 37.653f, 37.244f, 35.683f, 36.475f, + 34.852f, 34.839f, 33.080f, 31.990f, 29.804f, 31.368f, 34.322f, 34.017f, 35.077f, + 32.916f, 31.457f, 28.904f, 27.670f, 26.177f, 24.878f, 23.774f, 26.041f, 24.603f, + 23.532f, 22.248f, 20.662f, 19.772f, 19.625f, 19.985f, 18.499f, 17.584f, 16.534f, + 14.058f, 14.126f, 13.029f, 11.492f, 10.009f, 7.119f, 4.494f, 2.849f, -0.111f, + -5.893f, -2.888f, -1.704f, -3.435f, -4.239f, -4.158f, -4.312f, -5.047f, -5.119f, + -4.676f, -3.348f, -2.611f, -1.498f, -0.291f, 1.795f, 1.928f, -1.241f, -0.877f, + 0.632f, 3.034f, 4.749f, 6.092f, 7.115f, 9.012f, 11.355f, 13.409f, 13.127f, + 13.606f}, + {-29.534f, -30.179f, -30.723f, -31.987f, -33.778f, -35.464f, -37.031f, -38.812f, -40.516f, + -42.017f, -43.794f, -45.247f, -46.044f, -47.563f, -48.681f, -48.443f, -46.178f, -43.149f, + -41.154f, -40.453f, -38.887f, -37.202f, -37.392f, -38.791f, -38.565f, -38.302f, -41.024f, + -40.137f, -36.906f, -34.985f, -32.914f, -30.612f, -28.746f, -27.091f, -25.631f, -24.516f, + -23.398f, -22.405f, -21.382f, -20.636f, -20.486f, -20.287f, -20.243f, -20.449f, -20.875f, + -21.313f, -21.724f, -21.995f, -22.308f, -22.301f, -22.618f, -23.088f, -22.455f, -22.744f, + -21.408f, -14.951f, -11.394f, -11.013f, -8.952f, -5.687f, -1.150f, 1.725f, 3.533f, + 4.313f, 7.982f, 9.524f, 12.902f, 21.742f, 25.114f, 27.975f, 31.048f, 34.295f, + 36.909f, 39.131f, 42.810f, 46.959f, 51.413f, 54.801f, 56.760f, 58.662f, 61.227f, + 61.965f, 63.176f, 62.905f, 57.547f, 57.415f, 66.820f, 68.675f, 69.716f, 77.891f, + 73.017f, 73.115f, 72.654f, 71.925f, 70.658f, 68.990f, 66.325f, 67.650f, 64.061f, + 61.167f, 58.783f, 56.083f, 53.846f, 52.283f, 50.621f, 49.402f, 47.162f, 45.280f, + 43.485f, 41.825f, 40.659f, 39.721f, 39.471f, 38.757f, 36.824f, 36.792f, 36.313f, + 35.340f, 35.058f, 35.787f, 34.399f, 33.208f, 32.508f, 34.908f, 36.959f, 36.063f, + 33.064f, 31.643f, 31.162f, 29.770f, 28.989f, 25.795f, 24.724f, 26.798f, 25.004f, + 25.212f, 23.684f, 22.506f, 20.679f, 20.066f, 20.791f, 20.219f, 18.817f, 17.785f, + 15.531f, 14.257f, 13.484f, 11.575f, 10.373f, 8.049f, 5.147f, 3.464f, 0.589f, + -5.060f, -0.371f, -0.341f, -2.088f, -3.273f, -3.565f, -3.823f, -4.001f, -4.540f, + -4.136f, -3.125f, -2.269f, -1.491f, -0.425f, 1.405f, 2.019f, -1.050f, -0.757f, + 0.621f, 3.017f, 4.547f, 5.828f, 7.065f, 9.381f, 11.795f, 13.685f, 13.152f, + 13.606f}, + {-29.534f, -30.202f, -30.772f, -32.075f, -33.918f, -35.507f, -37.194f, -38.993f, -41.193f, + -42.854f, -44.499f, -46.199f, -47.319f, -48.999f, -49.903f, -48.375f, -45.389f, -43.490f, + -42.433f, -42.107f, -41.532f, -40.109f, -39.467f, -39.597f, -39.170f, -39.385f, -41.130f, + -40.251f, -37.273f, -35.001f, -32.875f, -30.688f, -28.761f, -27.111f, -25.620f, -24.476f, + -23.313f, -22.149f, -20.980f, -20.325f, -19.921f, -19.651f, -19.525f, -19.659f, -19.935f, + -20.413f, -20.563f, -20.847f, -20.974f, -21.033f, -21.098f, -21.682f, -20.831f, -20.885f, + -18.493f, -10.529f, -8.012f, -6.754f, -3.681f, -2.234f, 0.429f, 3.821f, 5.143f, + 6.749f, 9.634f, 13.389f, 17.001f, 23.980f, 27.253f, 30.792f, 33.081f, 35.676f, + 39.161f, 42.588f, 45.405f, 48.441f, 52.059f, 55.515f, 58.875f, 60.157f, 62.761f, + 64.513f, 66.447f, 67.124f, 66.134f, 67.526f, 70.023f, 68.664f, 72.121f, 75.191f, + 71.986f, 70.967f, 71.584f, 70.606f, 69.714f, 68.299f, 65.557f, 62.784f, 62.583f, + 61.716f, 59.575f, 58.032f, 55.340f, 53.643f, 51.830f, 50.329f, 48.649f, 46.718f, + 44.692f, 42.622f, 41.601f, 40.707f, 40.052f, 39.523f, 37.911f, 36.865f, 37.262f, + 37.185f, 37.139f, 36.130f, 36.017f, 35.644f, 33.159f, 33.537f, 36.515f, 36.355f, + 34.320f, 32.656f, 30.558f, 30.632f, 30.194f, 26.966f, 25.819f, 26.052f, 26.952f, + 28.680f, 26.580f, 24.519f, 21.909f, 20.660f, 20.553f, 20.227f, 18.974f, 18.480f, + 16.616f, 14.537f, 14.082f, 12.421f, 10.822f, 8.506f, 5.295f, 3.766f, 1.190f, + -4.091f, 1.385f, 0.480f, -0.946f, -2.358f, -3.020f, -3.053f, -3.196f, -4.083f, + -3.695f, -3.033f, -1.972f, -1.301f, -0.585f, 0.817f, 2.241f, -1.125f, -0.672f, + 0.755f, 2.959f, 4.357f, 5.676f, 7.162f, 9.815f, 12.228f, 13.942f, 13.175f, + 13.606f}, + {-29.534f, -30.224f, -30.819f, -32.162f, -34.058f, -35.565f, -37.357f, -39.329f, -42.154f, + -43.834f, -45.344f, -47.254f, -48.603f, -49.881f, -50.209f, -48.307f, -45.852f, -44.567f, + -43.402f, -43.175f, -44.096f, -43.035f, -41.195f, -39.826f, -40.077f, -40.653f, -40.903f, + -40.240f, -37.540f, -35.107f, -32.947f, -30.641f, -28.764f, -27.079f, -25.619f, -24.426f, + -23.140f, -21.910f, -20.778f, -19.991f, -19.433f, -19.015f, -18.757f, -18.939f, -19.114f, + -19.329f, -19.542f, -19.683f, -19.795f, -19.684f, -19.499f, -19.858f, -19.275f, -18.233f, + -10.740f, -6.662f, -4.164f, -2.361f, 0.223f, 1.243f, 3.202f, 5.387f, 7.510f, + 8.805f, 12.246f, 16.394f, 21.843f, 26.481f, 29.720f, 31.859f, 34.319f, 37.378f, + 41.025f, 44.623f, 47.392f, 50.731f, 53.677f, 56.875f, 60.478f, 62.279f, 64.934f, + 66.660f, 67.204f, 68.115f, 68.022f, 67.518f, 75.594f, 69.122f, 72.104f, 74.609f, + 67.969f, 70.649f, 71.088f, 69.979f, 68.803f, 67.846f, 66.661f, 62.665f, 63.063f, + 61.653f, 59.510f, 57.946f, 55.709f, 53.988f, 52.155f, 50.667f, 49.134f, 47.615f, + 46.058f, 44.870f, 43.607f, 41.968f, 40.848f, 39.437f, 39.137f, 39.113f, 39.293f, + 38.598f, 38.145f, 37.703f, 37.491f, 37.208f, 35.537f, 34.273f, 39.600f, 36.730f, + 35.649f, 34.538f, 32.362f, 31.354f, 30.990f, 28.375f, 27.197f, 25.688f, 26.666f, + 29.927f, 29.054f, 26.049f, 23.388f, 21.272f, 20.394f, 19.692f, 18.183f, 17.283f, + 16.292f, 14.666f, 14.574f, 13.529f, 11.317f, 9.676f, 6.307f, 4.973f, 2.216f, + -2.428f, 2.690f, 1.184f, -0.228f, -1.761f, -2.445f, -2.307f, -2.466f, -3.691f, + -3.318f, -2.792f, -1.724f, -0.952f, -0.466f, 0.332f, 2.635f, -1.319f, -0.659f, + 1.070f, 2.948f, 4.264f, 5.688f, 7.407f, 10.273f, 12.629f, 14.174f, 13.196f, + 13.606f}, + {-29.534f, -30.244f, -30.865f, -32.249f, -34.195f, -35.654f, -37.514f, -39.775f, -43.145f, + -44.858f, -46.362f, -48.352f, -49.544f, -50.183f, -50.020f, -48.884f, -47.484f, -46.374f, + -45.007f, -44.388f, -44.102f, -43.227f, -41.453f, -40.285f, -41.088f, -41.894f, -40.697f, + -40.763f, -37.849f, -35.123f, -33.008f, -30.772f, -28.648f, -27.121f, -25.655f, -24.289f, + -22.864f, -21.683f, -20.463f, -19.501f, -18.900f, -18.437f, -18.160f, -18.123f, -18.327f, + -18.517f, -18.690f, -18.636f, -18.632f, -18.452f, -18.045f, -18.086f, -17.220f, -13.475f, + -6.752f, -3.837f, -1.656f, 0.861f, 2.182f, 3.782f, 5.848f, 7.571f, 9.025f, + 11.654f, 14.470f, 19.446f, 24.286f, 28.010f, 31.402f, 33.828f, 37.018f, 39.660f, + 43.502f, 45.402f, 48.975f, 52.675f, 55.115f, 57.586f, 60.660f, 62.579f, 64.210f, + 66.472f, 68.354f, 69.843f, 70.102f, 69.888f, 80.779f, 76.710f, 73.647f, 72.421f, + 68.395f, 70.858f, 70.471f, 69.381f, 68.111f, 67.059f, 65.743f, 61.494f, 65.328f, + 61.712f, 59.703f, 57.794f, 55.974f, 54.642f, 52.821f, 51.316f, 49.750f, 48.650f, + 47.290f, 46.353f, 45.457f, 44.538f, 43.831f, 42.002f, 41.722f, 40.976f, 40.333f, + 40.076f, 39.628f, 39.118f, 38.564f, 37.920f, 37.244f, 35.670f, 36.136f, 37.492f, + 39.826f, 36.770f, 35.931f, 32.791f, 31.452f, 29.624f, 28.120f, 26.932f, 26.269f, + 26.219f, 28.526f, 28.228f, 25.300f, 22.789f, 20.588f, 19.417f, 18.396f, 17.538f, + 16.480f, 15.210f, 15.050f, 14.891f, 12.413f, 10.883f, 8.593f, 7.689f, 4.471f, + 1.053f, 3.945f, 2.274f, 0.602f, -1.454f, -0.938f, -1.616f, -1.874f, -3.299f, + -3.017f, -2.501f, -1.604f, -0.587f, 0.071f, 0.146f, 2.935f, -1.247f, -0.667f, + 1.543f, 3.094f, 4.362f, 5.886f, 7.774f, 10.713f, 12.973f, 14.374f, 13.216f, + 13.606f}, + {-29.534f, -30.263f, -30.909f, -32.335f, -34.327f, -35.783f, -37.657f, -40.246f, -43.907f, + -45.766f, -47.463f, -49.361f, -50.102f, -50.459f, -50.244f, -49.906f, -49.047f, -48.405f, + -47.748f, -45.944f, -43.062f, -42.069f, -41.223f, -40.380f, -41.967f, -43.070f, -40.698f, + -41.075f, -38.408f, -35.039f, -32.922f, -30.744f, -28.576f, -26.820f, -25.289f, -23.798f, + -22.361f, -21.034f, -20.014f, -19.041f, -18.310f, -17.783f, -17.529f, -17.436f, -17.587f, + -17.648f, -17.759f, -17.889f, -17.644f, -17.165f, -16.740f, -16.040f, -15.441f, -8.585f, + -4.841f, -2.067f, 0.613f, 2.627f, 4.343f, 6.625f, 7.975f, 9.716f, 10.744f, + 13.569f, 16.969f, 21.232f, 26.206f, 30.388f, 33.575f, 36.273f, 39.085f, 41.951f, + 45.454f, 47.531f, 49.779f, 52.218f, 54.914f, 58.280f, 61.781f, 63.826f, 65.607f, + 67.491f, 68.685f, 69.639f, 70.066f, 69.257f, 82.330f, 78.075f, 74.879f, 69.956f, + 70.105f, 70.796f, 70.092f, 68.763f, 67.475f, 66.518f, 65.513f, 63.922f, 58.489f, + 58.601f, 60.112f, 58.869f, 56.081f, 54.956f, 53.069f, 51.907f, 50.658f, 49.566f, + 48.268f, 47.473f, 46.523f, 45.902f, 45.325f, 44.336f, 43.715f, 43.065f, 42.183f, + 41.728f, 40.724f, 39.997f, 39.470f, 39.227f, 38.618f, 36.997f, 37.136f, 40.882f, + 42.320f, 39.586f, 36.248f, 34.509f, 32.518f, 30.282f, 29.052f, 28.098f, 26.945f, + 25.613f, 26.092f, 27.309f, 26.075f, 23.904f, 21.807f, 20.341f, 19.489f, 17.958f, + 16.957f, 15.661f, 14.953f, 15.060f, 13.798f, 11.811f, 10.072f, 9.410f, 7.059f, + 4.638f, 4.982f, 2.998f, 1.864f, 0.157f, 0.831f, -0.631f, -1.458f, -2.896f, + -2.820f, -2.267f, -1.524f, -0.304f, 0.693f, 0.317f, 2.897f, -0.592f, -0.572f, + 2.093f, 3.463f, 4.716f, 6.261f, 8.218f, 11.088f, 13.237f, 14.535f, 13.234f, + 13.606f}, + {-29.534f, -30.281f, -30.951f, -32.420f, -34.449f, -35.949f, -37.777f, -40.647f, -44.289f, + -46.400f, -48.477f, -50.160f, -50.561f, -51.163f, -51.193f, -50.765f, -49.703f, -49.548f, + -50.260f, -47.041f, -43.056f, -41.884f, -41.005f, -40.295f, -42.038f, -43.698f, -40.943f, + -41.085f, -39.004f, -34.983f, -32.848f, -30.484f, -28.281f, -26.664f, -25.070f, -23.480f, + -22.155f, -21.047f, -19.893f, -18.740f, -17.925f, -17.390f, -17.103f, -17.148f, -17.301f, + -17.132f, -17.010f, -16.619f, -16.694f, -16.191f, -15.381f, -14.709f, -11.729f, -6.333f, + -3.385f, -0.432f, 2.872f, 7.085f, 8.556f, 10.978f, 11.752f, 11.534f, 13.214f, + 15.988f, 19.472f, 23.911f, 28.380f, 33.129f, 37.267f, 40.227f, 43.208f, 44.920f, + 47.610f, 50.190f, 50.856f, 52.347f, 55.230f, 58.581f, 61.968f, 65.522f, 67.514f, + 68.885f, 69.818f, 70.126f, 70.331f, 71.609f, 81.022f, 76.423f, 73.707f, 69.321f, + 71.190f, 70.927f, 69.740f, 68.533f, 67.289f, 66.290f, 64.777f, 64.115f, 63.251f, + 60.622f, 55.067f, 50.489f, 54.030f, 53.788f, 53.111f, 52.134f, 51.111f, 49.966f, + 49.314f, 48.606f, 48.078f, 47.468f, 46.939f, 46.324f, 45.447f, 44.327f, 43.285f, + 42.522f, 42.356f, 42.101f, 42.094f, 42.374f, 41.856f, 40.636f, 39.672f, 39.367f, + 41.430f, 42.368f, 38.126f, 36.699f, 34.420f, 32.305f, 30.465f, 28.799f, 27.744f, + 26.637f, 24.621f, 25.229f, 25.690f, 24.157f, 22.715f, 21.420f, 19.742f, 18.478f, + 17.436f, 15.605f, 14.627f, 14.550f, 14.877f, 12.973f, 11.272f, 10.521f, 8.351f, + 6.973f, 5.963f, 3.325f, 3.224f, 2.525f, 1.329f, 0.078f, -0.989f, -2.427f, + -2.576f, -1.870f, -1.273f, -0.088f, 0.922f, 0.756f, 2.534f, 0.600f, -0.261f, + 2.610f, 4.022f, 5.325f, 6.767f, 8.679f, 11.358f, 13.404f, 14.655f, 13.250f, + 13.606f}, + {-29.534f, -30.298f, -30.992f, -32.503f, -34.559f, -36.139f, -37.870f, -40.904f, -44.309f, + -46.695f, -49.244f, -50.735f, -51.200f, -52.240f, -52.425f, -51.359f, -49.759f, -49.444f, + -51.158f, -47.872f, -43.893f, -43.030f, -41.432f, -40.805f, -41.796f, -44.282f, -41.419f, + -40.978f, -38.809f, -34.974f, -32.984f, -30.368f, -28.433f, -26.656f, -24.875f, -23.155f, + -21.547f, -20.170f, -19.124f, -18.831f, -18.521f, -18.191f, -17.913f, -17.663f, -17.589f, + -17.202f, -16.785f, -16.199f, -16.157f, -15.775f, -15.067f, -13.052f, -7.929f, -3.588f, + -1.050f, 1.131f, 3.714f, 7.182f, 9.689f, 10.214f, 12.594f, 13.599f, 15.034f, + 17.691f, 20.906f, 25.805f, 31.368f, 35.923f, 40.445f, 43.896f, 45.995f, 47.288f, + 49.649f, 51.509f, 52.457f, 53.736f, 56.872f, 59.712f, 62.437f, 66.327f, 69.201f, + 70.472f, 70.995f, 72.213f, 72.856f, 75.784f, 77.301f, 77.238f, 71.214f, 72.106f, + 72.228f, 70.936f, 69.250f, 67.937f, 66.631f, 65.510f, 64.299f, 63.392f, 62.728f, + 60.429f, 61.322f, 50.860f, 52.845f, 52.936f, 53.022f, 52.366f, 51.165f, 50.845f, + 50.042f, 49.307f, 48.859f, 48.324f, 47.593f, 46.894f, 46.357f, 45.608f, 44.488f, + 43.658f, 43.431f, 42.589f, 42.338f, 42.313f, 41.582f, 43.158f, 39.302f, 33.735f, + 38.186f, 42.581f, 41.619f, 39.119f, 37.738f, 35.303f, 34.537f, 31.627f, 29.552f, + 28.156f, 25.545f, 23.766f, 23.504f, 23.262f, 22.490f, 21.417f, 20.022f, 18.815f, + 17.853f, 15.715f, 14.179f, 14.292f, 14.255f, 13.422f, 12.185f, 11.204f, 9.443f, + 8.262f, 6.389f, 4.132f, 4.383f, 3.045f, 1.325f, 0.181f, -0.683f, -1.937f, + -2.198f, -1.300f, -0.945f, 0.107f, 0.715f, 1.216f, 2.065f, 1.900f, 0.277f, + 2.994f, 4.635f, 6.102f, 7.329f, 9.091f, 11.492f, 13.461f, 14.729f, 13.263f, + 13.606f}, + {-29.534f, -30.313f, -31.032f, -32.583f, -34.652f, -36.329f, -37.935f, -40.986f, -44.124f, + -46.724f, -49.691f, -51.200f, -52.048f, -53.349f, -53.487f, -52.080f, -49.965f, -49.012f, + -50.603f, -48.688f, -44.822f, -43.744f, -42.631f, -41.666f, -42.036f, -44.405f, -41.963f, + -40.930f, -37.914f, -34.957f, -32.666f, -30.203f, -27.897f, -25.845f, -23.860f, -22.242f, + -20.836f, -20.052f, -19.407f, -18.731f, -18.077f, -17.598f, -17.424f, -17.050f, -17.021f, + -16.809f, -16.247f, -15.763f, -15.400f, -15.274f, -13.533f, -10.218f, -3.801f, -0.877f, + 0.942f, 2.138f, 4.024f, 8.162f, 11.919f, 13.575f, 15.313f, 16.289f, 17.512f, + 20.089f, 22.792f, 26.588f, 32.388f, 37.448f, 40.986f, 43.649f, 45.264f, 47.750f, + 49.929f, 52.312f, 53.700f, 55.892f, 58.703f, 60.989f, 63.469f, 66.727f, 70.022f, + 71.361f, 72.174f, 73.311f, 74.572f, 81.112f, 78.736f, 77.573f, 71.138f, 72.791f, + 72.307f, 70.894f, 69.541f, 68.177f, 66.662f, 65.206f, 64.210f, 62.534f, 61.875f, + 60.847f, 56.076f, 43.494f, 48.140f, 52.422f, 52.610f, 52.181f, 51.634f, 50.670f, + 50.132f, 49.347f, 48.793f, 48.294f, 47.473f, 47.646f, 47.685f, 46.811f, 42.552f, + 41.868f, 40.203f, 36.436f, 34.539f, 35.484f, 33.148f, 33.620f, 24.859f, 22.738f, + 30.788f, 39.027f, 41.355f, 41.209f, 40.368f, 35.918f, 32.730f, 33.140f, 30.624f, + 28.599f, 26.500f, 23.677f, 21.629f, 21.446f, 20.872f, 19.814f, 19.283f, 18.698f, + 16.926f, 15.225f, 14.408f, 14.215f, 13.284f, 13.223f, 12.581f, 11.702f, 10.625f, + 8.483f, 6.209f, 5.402f, 5.025f, 2.526f, 1.543f, 0.174f, -0.800f, -1.592f, + -1.888f, -0.927f, -0.831f, 0.278f, 0.498f, 1.420f, 1.717f, 2.806f, 0.931f, + 3.185f, 5.113f, 6.888f, 7.859f, 9.395f, 11.472f, 13.403f, 14.755f, 13.274f, + 13.606f}, + {-29.534f, -30.327f, -31.070f, -32.659f, -34.729f, -36.492f, -37.977f, -40.911f, -43.932f, + -46.676f, -49.868f, -51.712f, -52.947f, -54.267f, -54.345f, -53.058f, -50.600f, -49.160f, + -49.909f, -49.035f, -45.870f, -44.062f, -43.944f, -42.918f, -43.019f, -44.354f, -42.873f, + -40.499f, -37.319f, -34.627f, -32.206f, -29.625f, -27.219f, -25.125f, -23.175f, -21.568f, + -20.321f, -19.365f, -18.841f, -18.232f, -17.584f, -17.162f, -17.018f, -16.625f, -16.381f, + -16.177f, -15.818f, -15.001f, -15.262f, -14.034f, -11.686f, -6.272f, -0.710f, 2.071f, + 3.031f, 4.077f, 5.676f, 8.343f, 12.659f, 15.677f, 17.624f, 18.854f, 19.897f, + 21.928f, 23.985f, 27.870f, 31.903f, 37.240f, 40.757f, 43.407f, 45.481f, 48.740f, + 51.451f, 53.922f, 55.938f, 58.162f, 61.583f, 63.780f, 66.535f, 69.363f, 72.079f, + 73.286f, 74.238f, 74.952f, 78.517f, 83.627f, 78.267f, 77.106f, 73.477f, 73.389f, + 72.288f, 70.667f, 69.235f, 68.104f, 66.877f, 65.527f, 64.453f, 62.543f, 61.330f, + 60.456f, 53.968f, 37.894f, 46.371f, 53.394f, 52.784f, 52.196f, 51.536f, 50.641f, + 49.941f, 49.287f, 48.759f, 48.431f, 48.928f, 47.436f, 44.197f, 41.764f, 38.836f, + 45.581f, 48.476f, 36.724f, 25.043f, 19.519f, 16.345f, 14.570f, 10.793f, 12.689f, + 18.972f, 28.451f, 35.366f, 38.049f, 37.377f, 29.321f, 22.499f, 30.337f, 31.342f, + 28.418f, 26.411f, 24.913f, 23.795f, 22.433f, 20.734f, 19.210f, 18.678f, 18.052f, + 16.014f, 15.764f, 14.803f, 13.802f, 13.125f, 13.007f, 12.383f, 12.539f, 11.531f, + 8.641f, 6.516f, 6.112f, 4.787f, 2.977f, 0.949f, 0.296f, -0.953f, -1.403f, + -1.708f, -0.795f, -0.801f, 0.392f, 0.589f, 1.307f, 1.612f, 3.114f, 1.529f, + 3.168f, 5.289f, 7.496f, 8.275f, 9.547f, 11.295f, 13.231f, 14.732f, 13.282f, + 13.606f}, + {-29.534f, -30.340f, -31.107f, -32.730f, -34.789f, -36.601f, -38.008f, -40.731f, -43.863f, + -46.744f, -49.899f, -52.327f, -53.785f, -54.980f, -55.096f, -53.961f, -51.474f, -49.905f, + -50.193f, -49.673f, -47.395f, -45.696f, -45.212f, -43.913f, -44.243f, -44.687f, -43.705f, + -40.020f, -37.050f, -34.451f, -31.758f, -29.236f, -26.908f, -24.689f, -22.848f, -21.268f, + -19.897f, -18.963f, -18.395f, -17.761f, -17.140f, -16.644f, -16.725f, -16.518f, -16.034f, + -15.787f, -15.119f, -14.911f, -14.478f, -11.652f, -7.415f, -2.647f, 1.500f, 3.788f, + 4.607f, 6.031f, 7.848f, 9.067f, 12.231f, 16.132f, 19.181f, 20.477f, 22.345f, + 24.273f, 26.335f, 28.757f, 32.829f, 37.308f, 41.656f, 44.356f, 48.264f, 52.441f, + 53.834f, 56.827f, 58.842f, 61.251f, 63.732f, 66.734f, 69.328f, 72.354f, 74.296f, + 74.611f, 74.775f, 76.373f, 81.409f, 80.506f, 76.549f, 77.502f, 76.485f, 72.873f, + 72.123f, 70.214f, 68.123f, 66.630f, 65.757f, 64.866f, 63.767f, 62.616f, 61.590f, + 57.357f, 51.897f, 40.894f, 48.303f, 54.110f, 54.450f, 53.704f, 52.964f, 52.326f, + 51.560f, 50.886f, 50.196f, 48.993f, 47.185f, 40.385f, 34.846f, 32.709f, 35.251f, + 33.341f, 32.239f, 23.492f, 22.705f, 24.353f, 24.602f, 24.106f, 22.765f, 20.461f, + 16.163f, 16.178f, 24.233f, 24.724f, 23.564f, 17.019f, 20.894f, 30.896f, 31.694f, + 28.042f, 25.718f, 24.531f, 22.783f, 22.142f, 21.642f, 20.149f, 18.152f, 17.787f, + 17.345f, 16.463f, 15.146f, 14.853f, 13.287f, 12.544f, 12.561f, 12.656f, 12.119f, + 8.851f, 7.767f, 6.376f, 4.609f, 4.586f, 0.232f, 0.575f, -0.819f, -1.267f, + -1.396f, -0.567f, -0.435f, 0.458f, 0.846f, 1.125f, 1.746f, 3.017f, 1.941f, + 2.971f, 5.103f, 7.773f, 8.516f, 9.527f, 10.976f, 12.954f, 14.661f, 13.288f, + 13.606f}, + {-29.534f, -30.351f, -31.142f, -32.795f, -34.836f, -36.639f, -38.039f, -40.517f, -43.928f, + -47.002f, -49.902f, -52.931f, -54.576f, -55.575f, -55.717f, -54.608f, -52.416f, -50.890f, + -51.097f, -51.155f, -49.271f, -47.397f, -46.396f, -44.743f, -44.962f, -44.907f, -43.834f, + -39.812f, -36.830f, -34.235f, -31.370f, -28.920f, -26.633f, -24.616f, -22.773f, -21.034f, + -19.783f, -18.868f, -18.243f, -17.778f, -17.149f, -16.506f, -16.072f, -15.894f, -15.508f, + -15.291f, -14.965f, -14.091f, -11.623f, -5.904f, -1.966f, -1.034f, 2.961f, 5.494f, + 6.394f, 8.151f, 9.736f, 11.503f, 13.151f, 16.612f, 20.860f, 22.821f, 24.746f, + 26.489f, 28.282f, 31.639f, 34.710f, 39.102f, 43.323f, 46.689f, 52.184f, 55.547f, + 56.731f, 58.534f, 61.832f, 63.994f, 66.365f, 65.139f, 68.005f, 71.806f, 73.661f, + 74.385f, 74.530f, 77.424f, 82.389f, 76.693f, 74.999f, 78.182f, 77.568f, 73.336f, + 70.758f, 69.128f, 66.941f, 65.625f, 64.598f, 63.652f, 62.990f, 61.977f, 59.281f, + 54.723f, 53.264f, 46.358f, 38.267f, 52.992f, 54.722f, 54.827f, 53.655f, 52.603f, + 51.219f, 50.117f, 49.238f, 47.551f, 42.930f, 32.943f, 28.743f, 37.631f, 39.188f, + 33.008f, 30.191f, 30.224f, 29.865f, 28.874f, 28.507f, 27.625f, 26.909f, 23.573f, + 21.916f, 18.006f, 16.680f, 15.470f, 14.508f, 11.211f, 14.635f, 28.293f, 30.541f, + 27.386f, 24.122f, 21.640f, 21.620f, 21.172f, 20.994f, 18.447f, 17.606f, 17.307f, + 16.508f, 15.917f, 16.248f, 14.998f, 13.491f, 12.839f, 13.697f, 13.424f, 12.246f, + 9.730f, 8.719f, 7.335f, 5.482f, 5.797f, 0.770f, 0.913f, -0.553f, -1.103f, + -0.901f, -0.285f, 0.192f, 0.545f, 0.983f, 1.191f, 1.989f, 2.885f, 2.142f, + 2.658f, 4.623f, 7.647f, 8.560f, 9.341f, 10.542f, 12.584f, 14.545f, 13.291f, + 13.606f}, + {-29.534f, -30.361f, -31.176f, -32.852f, -34.874f, -36.604f, -38.075f, -40.332f, -44.039f, + -47.363f, -49.932f, -53.320f, -55.335f, -56.158f, -56.236f, -55.253f, -53.435f, -51.967f, + -51.576f, -51.889f, -50.802f, -48.425f, -47.654f, -46.514f, -45.307f, -45.162f, -43.365f, + -39.501f, -36.820f, -33.808f, -31.017f, -28.716f, -26.385f, -24.101f, -22.204f, -20.677f, + -19.556f, -18.661f, -17.933f, -17.367f, -17.072f, -16.623f, -16.295f, -16.132f, -15.289f, + -14.607f, -13.007f, -8.970f, -5.565f, -2.332f, -1.725f, 0.795f, 3.864f, 6.684f, + 7.909f, 9.682f, 11.768f, 14.017f, 16.500f, 18.355f, 22.339f, 24.518f, 27.358f, + 29.446f, 31.177f, 34.457f, 38.297f, 42.290f, 45.796f, 49.852f, 55.249f, 58.179f, + 59.535f, 61.114f, 62.777f, 65.219f, 64.652f, 64.335f, 66.948f, 70.070f, 70.927f, + 74.402f, 73.796f, 76.712f, 80.519f, 70.403f, 75.182f, 78.842f, 78.306f, 73.276f, + 69.202f, 68.039f, 66.229f, 64.783f, 63.980f, 63.016f, 62.586f, 60.859f, 60.107f, + 55.520f, 55.253f, 50.752f, 35.438f, 45.781f, 54.949f, 54.991f, 53.682f, 52.075f, + 49.936f, 47.996f, 46.608f, 43.811f, 32.953f, 26.550f, 36.126f, 38.298f, 38.387f, + 35.144f, 32.397f, 31.585f, 29.962f, 28.313f, 28.187f, 27.310f, 25.496f, 23.421f, + 22.400f, 22.151f, 21.160f, 19.808f, 16.913f, 10.494f, 10.981f, 28.077f, 30.534f, + 25.606f, 23.080f, 21.134f, 21.833f, 21.010f, 19.219f, 17.471f, 16.397f, 15.738f, + 15.315f, 15.957f, 17.383f, 15.792f, 14.006f, 13.264f, 13.741f, 13.581f, 12.285f, + 10.999f, 8.699f, 8.831f, 6.992f, 4.531f, 1.810f, 1.168f, -0.135f, -0.725f, + -0.504f, -0.268f, 0.514f, 0.729f, 1.017f, 1.553f, 2.135f, 2.927f, 2.215f, + 2.314f, 4.017f, 7.153f, 8.425f, 9.017f, 10.030f, 12.142f, 14.385f, 13.291f, + 13.606f}, + {-29.534f, -30.370f, -31.208f, -32.902f, -34.910f, -36.511f, -38.112f, -40.220f, -44.085f, + -47.644f, -49.969f, -53.375f, -55.980f, -56.779f, -56.816f, -56.079f, -54.528f, -53.127f, + -51.844f, -51.516f, -51.345f, -50.206f, -48.871f, -47.976f, -45.358f, -45.309f, -42.676f, + -39.439f, -36.663f, -33.808f, -30.913f, -28.366f, -25.951f, -24.076f, -22.261f, -20.507f, + -19.318f, -19.190f, -18.810f, -18.222f, -17.887f, -17.221f, -15.733f, -14.937f, -13.966f, + -13.726f, -9.746f, -5.227f, -1.927f, -1.377f, -1.002f, 1.953f, 6.677f, 8.790f, + 9.506f, 11.757f, 14.161f, 16.737f, 20.025f, 21.563f, 24.109f, 26.228f, 29.005f, + 31.683f, 34.558f, 37.836f, 41.954f, 46.097f, 49.123f, 52.548f, 56.329f, 58.522f, + 59.662f, 61.834f, 62.054f, 62.830f, 63.916f, 65.670f, 67.879f, 70.213f, 69.206f, + 70.884f, 75.442f, 78.264f, 72.099f, 68.271f, 77.267f, 79.405f, 77.637f, 72.968f, + 67.927f, 66.999f, 65.612f, 64.170f, 63.002f, 61.916f, 61.244f, 60.420f, 59.754f, + 56.006f, 53.500f, 50.458f, 41.714f, 31.760f, 42.874f, 49.670f, 52.657f, 48.828f, + 44.180f, 42.227f, 40.519f, 34.819f, 25.733f, 31.228f, 36.730f, 35.254f, 36.369f, + 33.784f, 32.985f, 30.191f, 28.272f, 26.356f, 26.036f, 25.410f, 24.005f, 21.937f, + 22.024f, 21.822f, 22.238f, 22.030f, 20.693f, 16.296f, 8.986f, 21.354f, 30.973f, + 25.708f, 23.014f, 20.454f, 19.800f, 20.014f, 18.812f, 17.495f, 16.462f, 15.938f, + 15.827f, 16.945f, 17.620f, 17.037f, 14.855f, 13.892f, 13.994f, 13.605f, 12.497f, + 10.926f, 9.416f, 9.148f, 8.181f, 2.419f, 2.602f, 1.590f, 0.607f, -0.074f, + -0.259f, -0.370f, 0.345f, 1.008f, 1.176f, 1.947f, 2.073f, 3.067f, 2.286f, + 2.029f, 3.476f, 6.420f, 8.161f, 8.603f, 9.484f, 11.649f, 14.188f, 13.289f, + 13.606f}, + {-29.534f, -30.378f, -31.239f, -32.941f, -34.953f, -36.390f, -38.131f, -40.190f, -44.019f, + -47.717f, -49.975f, -53.179f, -56.393f, -57.339f, -57.463f, -56.842f, -55.563f, -54.319f, + -52.719f, -51.941f, -51.295f, -51.382f, -49.619f, -48.642f, -45.584f, -45.807f, -42.436f, + -39.433f, -36.443f, -33.247f, -30.497f, -28.026f, -25.964f, -23.827f, -22.021f, -21.185f, + -20.738f, -20.288f, -19.384f, -18.356f, -17.995f, -17.099f, -14.772f, -13.352f, -13.744f, + -13.147f, -8.084f, -4.055f, -1.341f, -1.036f, -0.032f, 1.627f, 6.520f, 12.393f, + 11.819f, 13.558f, 16.575f, 18.869f, 21.657f, 24.488f, 26.035f, 27.792f, 30.148f, + 33.940f, 38.071f, 41.330f, 45.500f, 48.824f, 51.405f, 53.939f, 56.609f, 58.355f, + 59.050f, 59.333f, 61.043f, 63.347f, 64.844f, 64.939f, 67.210f, 69.299f, 69.072f, + 77.019f, 84.229f, 73.312f, 71.121f, 73.513f, 79.020f, 79.868f, 77.597f, 72.313f, + 66.041f, 66.345f, 65.300f, 63.749f, 62.464f, 61.276f, 60.137f, 59.348f, 58.682f, + 54.071f, 51.226f, 49.687f, 46.808f, 39.501f, 32.106f, 36.966f, 39.536f, 38.184f, + 36.946f, 34.772f, 31.172f, 29.460f, 32.055f, 35.019f, 35.440f, 34.104f, 33.829f, + 32.244f, 30.172f, 27.900f, 25.778f, 24.448f, 24.022f, 22.985f, 21.476f, 20.964f, + 20.797f, 20.322f, 20.746f, 21.475f, 20.805f, 18.685f, 9.999f, 10.537f, 29.627f, + 26.460f, 22.913f, 21.082f, 19.957f, 19.841f, 18.778f, 17.572f, 17.054f, 16.656f, + 16.739f, 17.706f, 17.961f, 17.228f, 15.354f, 14.278f, 14.142f, 14.024f, 12.585f, + 10.866f, 10.537f, 8.850f, 8.183f, 2.301f, 3.204f, 2.229f, 1.419f, 0.518f, + 0.048f, -0.198f, 0.161f, 1.247f, 1.505f, 2.101f, 1.943f, 3.096f, 2.449f, + 1.867f, 3.130f, 5.626f, 7.838f, 8.156f, 8.949f, 11.131f, 13.957f, 13.284f, + 13.606f}, + {-29.534f, -30.384f, -31.268f, -32.971f, -35.010f, -36.282f, -38.105f, -40.213f, -43.888f, + -47.631f, -49.953f, -52.945f, -56.567f, -57.646f, -57.899f, -57.268f, -56.379f, -55.452f, + -54.004f, -53.401f, -52.058f, -51.236f, -50.563f, -49.336f, -45.865f, -46.246f, -42.382f, + -39.188f, -36.054f, -33.000f, -30.493f, -27.966f, -25.598f, -23.751f, -22.907f, -22.068f, + -21.246f, -19.732f, -19.060f, -18.169f, -17.479f, -16.248f, -13.842f, -12.275f, -13.746f, + -13.252f, -9.376f, -5.051f, -1.741f, -0.259f, 0.795f, 2.693f, 6.489f, 13.516f, + 15.704f, 16.853f, 19.131f, 21.994f, 23.708f, 25.351f, 27.663f, 30.086f, 32.165f, + 35.211f, 39.151f, 44.317f, 47.382f, 49.758f, 52.111f, 55.042f, 56.504f, 57.766f, + 57.734f, 60.471f, 62.880f, 64.295f, 63.626f, 64.868f, 66.536f, 68.378f, 75.329f, + 82.188f, 74.844f, 59.791f, 69.821f, 78.240f, 80.567f, 79.443f, 76.228f, 71.140f, + 65.546f, 65.905f, 64.155f, 62.815f, 62.089f, 60.936f, 59.464f, 58.423f, 58.680f, + 54.482f, 51.174f, 47.426f, 47.108f, 46.510f, 42.883f, 39.610f, 36.164f, 31.384f, + 30.938f, 32.978f, 35.643f, 37.633f, 36.921f, 35.983f, 33.908f, 32.339f, 32.055f, + 29.478f, 27.598f, 24.873f, 23.454f, 21.845f, 21.732f, 20.817f, 19.496f, 18.957f, + 18.808f, 18.371f, 18.620f, 19.890f, 19.799f, 18.743f, 13.798f, 2.790f, 18.909f, + 27.966f, 23.174f, 21.244f, 19.911f, 20.159f, 19.313f, 18.127f, 17.826f, 17.759f, + 17.725f, 18.109f, 18.466f, 17.515f, 15.661f, 15.015f, 14.449f, 14.532f, 12.938f, + 11.658f, 10.571f, 9.672f, 7.048f, 3.501f, 3.700f, 2.780f, 1.893f, 0.861f, + 0.387f, 0.180f, 0.358f, 1.271f, 1.829f, 2.007f, 2.041f, 2.921f, 2.717f, + 1.837f, 3.005f, 4.942f, 7.524f, 7.729f, 8.461f, 10.611f, 13.699f, 13.277f, + 13.606f}, + {-29.534f, -30.388f, -31.295f, -32.990f, -35.087f, -36.227f, -38.001f, -40.226f, -43.785f, + -47.608f, -49.974f, -52.850f, -56.596f, -57.632f, -57.927f, -57.477f, -56.966f, -56.416f, + -55.264f, -54.709f, -53.765f, -51.843f, -51.667f, -49.320f, -45.557f, -45.860f, -42.172f, + -39.020f, -35.996f, -33.130f, -30.233f, -27.383f, -25.508f, -24.483f, -23.318f, -21.769f, + -20.739f, -19.674f, -18.669f, -17.609f, -16.865f, -15.768f, -13.499f, -12.924f, -13.567f, + -12.393f, -10.685f, -8.223f, -5.100f, -2.531f, 0.169f, 0.793f, 7.076f, 14.101f, + 18.586f, 19.524f, 22.141f, 24.827f, 25.988f, 27.243f, 28.218f, 30.633f, 33.234f, + 36.212f, 40.265f, 45.601f, 47.680f, 50.330f, 53.604f, 55.296f, 57.346f, 58.048f, + 58.738f, 61.140f, 63.270f, 64.072f, 62.308f, 64.648f, 65.337f, 69.000f, 78.171f, + 77.721f, 67.704f, 58.705f, 74.951f, 80.377f, 80.531f, 78.162f, 73.807f, 68.897f, + 62.062f, 62.435f, 61.957f, 60.985f, 59.461f, 59.093f, 57.703f, 58.455f, 57.721f, + 50.707f, 46.013f, 45.657f, 46.347f, 45.521f, 44.324f, 43.449f, 43.177f, 40.059f, + 39.007f, 38.277f, 41.115f, 36.670f, 37.272f, 35.485f, 31.894f, 30.936f, 28.186f, + 27.698f, 24.483f, 22.705f, 21.181f, 19.504f, 19.775f, 17.959f, 17.018f, 16.658f, + 16.385f, 15.654f, 16.293f, 17.685f, 18.389f, 18.468f, 16.468f, 5.614f, 2.230f, + 24.029f, 23.699f, 21.219f, 19.886f, 20.278f, 20.009f, 18.450f, 18.834f, 18.235f, + 18.146f, 18.838f, 18.934f, 17.702f, 15.996f, 16.155f, 15.302f, 14.921f, 13.570f, + 11.960f, 10.385f, 9.259f, 5.336f, 4.613f, 4.289f, 3.231f, 2.066f, 1.198f, + 0.496f, 0.458f, 0.729f, 1.069f, 2.050f, 1.866f, 2.487f, 2.644f, 3.012f, + 1.891f, 3.025f, 4.477f, 7.267f, 7.366f, 8.052f, 10.114f, 13.421f, 13.268f, + 13.606f}, + {-29.534f, -30.392f, -31.321f, -32.999f, -35.187f, -36.257f, -37.793f, -40.149f, -43.769f, + -47.890f, -50.124f, -52.912f, -56.544f, -57.431f, -57.740f, -57.731f, -57.454f, -57.054f, + -56.359f, -55.803f, -54.940f, -52.839f, -51.859f, -48.891f, -45.244f, -45.580f, -42.018f, + -38.840f, -35.983f, -32.693f, -29.654f, -27.227f, -25.791f, -24.298f, -23.024f, -21.523f, + -20.637f, -19.599f, -19.055f, -18.075f, -17.065f, -14.012f, -14.281f, -14.314f, -13.509f, + -11.796f, -9.014f, -8.741f, -6.905f, -4.609f, -2.335f, -0.889f, 6.400f, 11.825f, + 16.643f, 20.421f, 24.353f, 26.895f, 28.226f, 29.576f, 31.691f, 32.827f, 35.217f, + 38.001f, 42.150f, 46.178f, 49.255f, 51.466f, 53.438f, 55.637f, 57.400f, 58.049f, + 60.027f, 62.759f, 64.178f, 63.429f, 62.212f, 64.435f, 65.248f, 71.548f, 78.443f, + 78.413f, 71.729f, 64.837f, 81.327f, 81.823f, 79.809f, 77.093f, 72.988f, 64.406f, + 63.325f, 62.227f, 59.971f, 57.337f, 57.120f, 54.925f, 56.729f, 52.586f, 52.293f, + 55.623f, 44.975f, 44.268f, 44.558f, 44.053f, 43.485f, 43.862f, 42.363f, 44.069f, + 40.858f, 38.105f, 40.881f, 36.493f, 35.874f, 33.524f, 32.656f, 28.007f, 27.125f, + 25.232f, 22.181f, 21.304f, 19.332f, 17.630f, 16.977f, 16.208f, 15.809f, 14.782f, + 13.999f, 13.672f, 13.400f, 15.650f, 16.643f, 17.274f, 16.992f, 12.132f, -2.953f, + 13.590f, 25.003f, 21.549f, 20.172f, 21.001f, 20.277f, 19.053f, 19.310f, 18.430f, + 18.782f, 19.310f, 19.081f, 17.595f, 16.517f, 17.164f, 16.206f, 15.408f, 14.059f, + 11.874f, 10.468f, 7.218f, 4.385f, 5.277f, 4.652f, 3.570f, 2.234f, 1.498f, + 0.369f, 0.655f, 0.904f, 0.864f, 2.243f, 1.849f, 3.023f, 2.452f, 3.203f, + 1.950f, 3.066f, 4.260f, 7.082f, 7.093f, 7.737f, 9.660f, 13.129f, 13.256f, + 13.606f}, + {-29.534f, -30.394f, -31.344f, -32.998f, -35.311f, -36.381f, -37.474f, -39.902f, -43.795f, + -48.532f, -50.417f, -53.032f, -56.370f, -57.163f, -57.616f, -58.012f, -57.871f, -57.323f, + -56.770f, -56.504f, -55.436f, -53.456f, -51.989f, -48.729f, -45.677f, -45.432f, -41.785f, + -38.649f, -35.359f, -31.834f, -29.110f, -27.160f, -25.536f, -24.310f, -23.131f, -21.965f, + -21.495f, -20.159f, -19.168f, -18.277f, -16.904f, -15.099f, -15.038f, -14.318f, -13.194f, + -11.771f, -8.861f, -8.111f, -6.719f, -4.229f, -2.061f, 0.103f, 2.491f, 5.584f, + 9.663f, 17.015f, 22.309f, 26.023f, 29.709f, 32.306f, 33.923f, 34.792f, 38.060f, + 41.217f, 44.679f, 46.978f, 49.060f, 50.727f, 52.929f, 55.249f, 57.341f, 58.214f, + 60.055f, 62.576f, 63.902f, 61.965f, 62.609f, 64.334f, 65.556f, 74.733f, 76.643f, + 77.650f, 72.816f, 66.839f, 74.534f, 79.819f, 77.861f, 75.505f, 70.092f, 61.828f, + 61.307f, 59.178f, 57.008f, 55.745f, 54.986f, 53.599f, 53.349f, 52.298f, 49.915f, + 46.676f, 43.754f, 43.432f, 42.601f, 42.164f, 41.723f, 41.648f, 40.585f, 40.425f, + 42.708f, 37.783f, 37.463f, 33.707f, 34.043f, 30.912f, 29.701f, 27.108f, 26.002f, + 23.168f, 20.988f, 19.571f, 17.296f, 16.162f, 15.796f, 14.445f, 13.714f, 12.357f, + 11.705f, 11.448f, 11.682f, 13.378f, 14.530f, 15.728f, 16.401f, 14.661f, 2.040f, + 1.264f, 23.752f, 22.533f, 20.839f, 20.756f, 21.130f, 19.485f, 19.600f, 18.940f, + 19.176f, 19.600f, 18.824f, 17.249f, 16.724f, 17.571f, 16.689f, 15.637f, 14.215f, + 11.917f, 10.113f, 6.852f, 5.388f, 5.549f, 4.667f, 3.567f, 2.382f, 1.407f, + 0.368f, 0.934f, 0.967f, 0.913f, 2.420f, 1.972f, 3.226f, 2.438f, 3.179f, + 1.952f, 3.025f, 4.242f, 6.956f, 6.914f, 7.520f, 9.266f, 12.831f, 13.243f, + 13.606f}, + {-29.534f, -30.395f, -31.365f, -32.990f, -35.455f, -36.586f, -37.055f, -39.441f, -43.718f, + -49.293f, -50.747f, -53.104f, -56.042f, -56.766f, -57.479f, -58.163f, -58.088f, -57.464f, + -56.676f, -56.626f, -56.166f, -54.280f, -52.729f, -48.704f, -47.382f, -44.984f, -41.520f, + -38.397f, -34.537f, -31.317f, -29.148f, -27.293f, -26.181f, -25.052f, -23.811f, -22.421f, + -21.053f, -19.879f, -18.837f, -17.904f, -16.827f, -16.147f, -14.954f, -14.126f, -12.627f, + -11.113f, -9.269f, -7.501f, -5.929f, -3.211f, -0.672f, 1.823f, 4.141f, 6.553f, + 9.137f, 11.270f, 17.846f, 25.087f, 29.164f, 32.950f, 35.543f, 37.332f, 40.406f, + 43.171f, 45.007f, 46.761f, 48.667f, 50.934f, 53.755f, 56.034f, 57.519f, 59.017f, + 59.729f, 62.952f, 63.127f, 61.397f, 62.969f, 64.227f, 65.824f, 73.960f, 74.346f, + 77.115f, 68.732f, 69.737f, 60.484f, 74.007f, 74.172f, 71.220f, 66.444f, 60.487f, + 59.258f, 57.633f, 55.761f, 54.288f, 53.320f, 53.061f, 53.088f, 55.287f, 52.482f, + 51.185f, 43.767f, 41.915f, 41.395f, 40.626f, 39.626f, 40.090f, 41.066f, 41.043f, + 37.612f, 36.628f, 35.701f, 32.784f, 32.218f, 29.256f, 27.976f, 25.891f, 24.300f, + 22.249f, 18.360f, 17.353f, 15.546f, 14.256f, 13.163f, 12.752f, 11.120f, 9.939f, + 10.088f, 9.817f, 10.165f, 11.420f, 12.275f, 13.696f, 15.053f, 14.407f, 8.598f, + -3.962f, 17.184f, 24.712f, 21.171f, 21.001f, 21.200f, 20.374f, 20.151f, 19.769f, + 19.685f, 19.823f, 18.395f, 16.526f, 16.309f, 17.339f, 16.828f, 16.014f, 14.389f, + 11.642f, 9.552f, 7.702f, 6.608f, 5.742f, 4.745f, 3.319f, 2.318f, 1.119f, + 0.739f, 1.206f, 1.298f, 1.207f, 2.447f, 2.172f, 2.952f, 2.565f, 2.912f, + 1.887f, 2.863f, 4.331f, 6.853f, 6.815f, 7.394f, 8.944f, 12.533f, 13.228f, + 13.606f}, + {-29.534f, -30.394f, -31.382f, -32.974f, -35.610f, -36.832f, -36.571f, -38.774f, -43.372f, + -49.722f, -50.930f, -53.064f, -55.638f, -56.178f, -57.066f, -58.194f, -58.179f, -57.740f, + -57.156f, -57.164f, -56.660f, -54.170f, -52.627f, -48.987f, -48.622f, -44.251f, -41.112f, + -37.632f, -34.150f, -31.512f, -29.671f, -28.442f, -26.879f, -25.342f, -23.925f, -22.469f, + -20.976f, -20.232f, -18.537f, -17.736f, -16.768f, -16.152f, -14.766f, -13.501f, -11.878f, + -10.654f, -8.881f, -6.904f, -4.811f, -1.846f, 0.584f, 2.886f, 5.426f, 8.001f, + 10.500f, 13.288f, 15.355f, 20.192f, 27.127f, 30.590f, 34.641f, 37.059f, 39.827f, + 42.639f, 44.581f, 46.816f, 47.857f, 50.240f, 53.183f, 55.582f, 56.362f, 57.365f, + 59.320f, 61.311f, 60.686f, 61.770f, 63.384f, 64.090f, 66.448f, 73.717f, 73.064f, + 73.608f, 70.623f, 68.387f, 57.041f, 57.793f, 65.784f, 67.300f, 63.264f, 59.829f, + 58.042f, 56.552f, 56.291f, 54.342f, 52.939f, 52.453f, 51.590f, 51.954f, 48.978f, + 45.814f, 42.294f, 41.176f, 39.775f, 39.453f, 38.428f, 38.182f, 36.715f, 36.857f, + 36.275f, 35.401f, 32.993f, 32.574f, 29.583f, 31.460f, 24.881f, 24.480f, 21.805f, + 18.146f, 17.478f, 15.607f, 13.995f, 12.976f, 12.113f, 10.497f, 8.780f, 8.229f, + 8.067f, 7.842f, 8.406f, 9.140f, 10.125f, 11.617f, 12.977f, 13.504f, 11.454f, + 2.664f, 6.863f, 23.648f, 23.905f, 21.689f, 21.627f, 21.637f, 20.960f, 20.570f, + 20.067f, 19.623f, 17.846f, 16.490f, 16.223f, 16.875f, 16.739f, 16.317f, 14.033f, + 11.388f, 9.600f, 8.092f, 6.938f, 5.805f, 4.815f, 3.250f, 2.184f, 1.140f, + 1.212f, 1.332f, 1.958f, 1.454f, 2.279f, 2.366f, 2.508f, 2.745f, 2.483f, + 1.798f, 2.616f, 4.430f, 6.730f, 6.769f, 7.339f, 8.700f, 12.242f, 13.211f, + 13.606f}, + {-29.534f, -30.392f, -31.397f, -32.954f, -35.767f, -37.060f, -36.065f, -37.978f, -42.687f, + -49.419f, -50.859f, -52.867f, -55.250f, -55.573f, -56.490f, -58.190f, -58.498f, -58.103f, + -57.807f, -57.766f, -56.254f, -53.356f, -51.760f, -48.913f, -47.772f, -43.792f, -40.613f, + -37.207f, -34.779f, -32.216f, -30.815f, -28.904f, -26.912f, -25.423f, -24.065f, -22.391f, + -21.455f, -19.819f, -19.119f, -17.623f, -17.073f, -15.955f, -14.968f, -13.030f, -11.506f, + -9.699f, -8.198f, -6.422f, -3.933f, -1.480f, 1.424f, 4.182f, 6.456f, 9.118f, + 11.739f, 14.455f, 17.087f, 19.427f, 22.107f, 25.284f, 29.681f, 34.338f, 37.915f, + 38.816f, 41.829f, 42.892f, 44.564f, 50.385f, 51.909f, 52.765f, 54.242f, 56.859f, + 59.387f, 61.252f, 61.415f, 62.294f, 63.552f, 64.741f, 66.671f, 71.572f, 72.596f, + 73.430f, 69.428f, 60.354f, 56.169f, 59.515f, 63.466f, 61.892f, 61.641f, 58.955f, + 58.737f, 57.493f, 56.181f, 55.420f, 53.592f, 53.648f, 52.024f, 49.894f, 47.851f, + 42.841f, 41.319f, 40.185f, 38.818f, 37.737f, 36.860f, 36.300f, 34.886f, 37.228f, + 33.466f, 33.054f, 31.367f, 28.862f, 27.028f, 25.091f, 24.308f, 21.127f, 19.027f, + 16.216f, 15.066f, 13.008f, 12.329f, 11.083f, 10.854f, 8.889f, 7.339f, 6.403f, + 5.801f, 5.991f, 6.299f, 7.086f, 8.137f, 9.727f, 11.112f, 12.341f, 12.233f, + 9.904f, 3.587f, 16.063f, 24.990f, 24.642f, 22.214f, 22.687f, 22.057f, 21.282f, + 20.494f, 19.502f, 18.303f, 17.045f, 16.835f, 16.330f, 16.598f, 16.552f, 13.956f, + 12.087f, 10.032f, 8.176f, 7.260f, 5.794f, 4.856f, 3.481f, 2.219f, 1.381f, + 1.358f, 1.475f, 2.585f, 1.425f, 2.101f, 2.463f, 2.342f, 2.943f, 2.033f, + 1.740f, 2.364f, 4.473f, 6.556f, 6.741f, 7.333f, 8.537f, 11.963f, 13.194f, + 13.606f}, + {-29.534f, -30.389f, -31.408f, -32.932f, -35.912f, -37.208f, -35.579f, -37.182f, -41.772f, + -48.318f, -50.631f, -52.505f, -54.785f, -55.166f, -56.252f, -58.147f, -59.067f, -58.404f, + -57.478f, -57.162f, -55.623f, -53.494f, -51.325f, -48.472f, -47.110f, -43.714f, -40.504f, + -37.825f, -35.076f, -32.830f, -30.599f, -28.857f, -27.569f, -25.995f, -24.467f, -23.101f, + -21.539f, -19.969f, -19.148f, -17.653f, -16.905f, -15.865f, -14.903f, -12.999f, -11.024f, + -9.272f, -7.395f, -5.483f, -3.265f, -0.666f, 2.019f, 4.634f, 7.433f, 10.294f, + 13.044f, 15.201f, 17.792f, 20.522f, 23.418f, 26.153f, 29.254f, 31.154f, 35.362f, + 37.144f, 39.726f, 43.125f, 44.463f, 48.001f, 50.751f, 52.141f, 54.883f, 57.380f, + 60.218f, 61.200f, 61.294f, 62.658f, 64.575f, 66.960f, 64.557f, 70.132f, 71.217f, + 71.217f, 68.921f, 63.079f, 71.228f, 63.989f, 63.228f, 63.412f, 61.503f, 59.566f, + 59.055f, 57.469f, 56.271f, 54.868f, 54.051f, 51.676f, 50.077f, 50.381f, 48.956f, + 43.238f, 41.325f, 39.119f, 37.766f, 36.131f, 34.170f, 34.603f, 36.304f, 32.430f, + 32.110f, 31.105f, 28.303f, 29.737f, 25.505f, 24.408f, 21.467f, 19.111f, 16.988f, + 15.327f, 12.883f, 11.180f, 10.753f, 10.036f, 9.101f, 7.141f, 5.401f, 5.265f, + 4.649f, 4.140f, 4.480f, 5.321f, 6.318f, 7.467f, 9.149f, 10.850f, 11.414f, + 11.631f, 10.242f, 4.343f, 15.253f, 24.598f, 23.801f, 22.672f, 23.233f, 22.708f, + 21.862f, 20.932f, 19.962f, 18.131f, 16.423f, 16.399f, 16.030f, 16.190f, 14.672f, + 12.720f, 10.565f, 8.414f, 7.138f, 5.877f, 5.002f, 3.706f, 2.331f, 1.519f, + 1.249f, 1.873f, 2.883f, 1.216f, 2.076f, 2.424f, 2.599f, 3.174f, 1.680f, + 1.736f, 2.187f, 4.437f, 6.318f, 6.700f, 7.349f, 8.451f, 11.702f, 13.175f, + 13.606f}, + {-29.534f, -30.385f, -31.415f, -32.910f, -36.034f, -37.223f, -35.143f, -36.538f, -40.896f, + -46.791f, -50.555f, -52.118f, -54.010f, -54.806f, -56.516f, -58.164f, -59.280f, -58.590f, + -57.002f, -56.657f, -55.562f, -53.495f, -50.855f, -48.758f, -47.182f, -43.596f, -40.966f, + -37.889f, -34.775f, -32.778f, -30.728f, -29.161f, -27.590f, -26.179f, -24.533f, -23.115f, + -22.365f, -20.197f, -18.778f, -17.631f, -16.710f, -15.788f, -14.516f, -12.718f, -10.742f, + -8.941f, -7.245f, -4.754f, -2.496f, 0.079f, 2.774f, 5.304f, 8.266f, 12.216f, + 13.809f, 16.270f, 18.723f, 24.360f, 23.688f, 28.792f, 29.404f, 32.841f, 35.947f, + 36.807f, 39.574f, 41.463f, 45.821f, 48.459f, 51.076f, 53.862f, 55.290f, 57.501f, + 59.940f, 61.477f, 61.505f, 63.263f, 66.109f, 68.383f, 67.145f, 65.433f, 69.797f, + 70.327f, 67.709f, 69.853f, 64.831f, 65.911f, 64.504f, 62.746f, 61.083f, 59.227f, + 58.609f, 56.769f, 54.858f, 54.431f, 52.231f, 51.181f, 49.422f, 48.415f, 45.549f, + 42.550f, 40.061f, 37.306f, 36.089f, 33.783f, 36.494f, 30.606f, 30.915f, 31.134f, + 30.479f, 28.554f, 27.953f, 25.702f, 23.242f, 22.647f, 19.893f, 16.735f, 14.395f, + 13.285f, 11.049f, 9.716f, 8.923f, 8.763f, 7.561f, 5.713f, 4.199f, 4.093f, + 3.303f, 2.369f, 2.623f, 3.684f, 4.669f, 5.614f, 6.704f, 8.674f, 9.848f, + 11.402f, 12.119f, 9.694f, 2.410f, 12.253f, 23.850f, 24.505f, 23.835f, 23.454f, + 22.146f, 21.212f, 20.817f, 19.119f, 17.085f, 16.167f, 14.926f, 14.823f, 14.479f, + 12.798f, 11.023f, 8.861f, 6.936f, 6.019f, 5.102f, 3.804f, 2.421f, 1.647f, + 1.259f, 2.296f, 2.829f, 1.092f, 2.129f, 2.365f, 3.036f, 3.433f, 1.450f, + 1.756f, 2.127f, 4.341f, 6.029f, 6.621f, 7.365f, 8.435f, 11.464f, 13.156f, + 13.606f}, + {-29.534f, -30.380f, -31.418f, -32.891f, -36.120f, -37.079f, -34.765f, -36.177f, -40.384f, + -45.493f, -50.965f, -52.060f, -52.914f, -54.095f, -56.685f, -58.421f, -58.708f, -58.441f, + -57.093f, -56.969f, -55.759f, -53.147f, -50.545f, -49.749f, -46.817f, -43.892f, -41.256f, + -37.409f, -34.983f, -32.927f, -31.111f, -30.001f, -32.141f, -30.436f, -25.220f, -23.176f, + -21.904f, -20.177f, -18.158f, -17.521f, -16.514f, -15.482f, -13.859f, -12.131f, -10.483f, + -8.318f, -6.403f, -4.435f, -1.993f, 0.827f, 3.262f, 6.108f, 8.715f, 11.343f, + 14.024f, 16.834f, 19.161f, 21.978f, 24.825f, 27.699f, 29.943f, 32.126f, 34.854f, + 37.152f, 40.198f, 43.441f, 46.622f, 48.959f, 51.893f, 53.633f, 54.965f, 57.306f, + 58.911f, 60.275f, 62.753f, 63.161f, 64.713f, 67.655f, 68.195f, 69.023f, 67.369f, + 68.518f, 69.513f, 67.249f, 62.507f, 65.782f, 63.718f, 61.044f, 59.583f, 57.938f, + 56.400f, 54.978f, 54.078f, 52.971f, 52.570f, 50.659f, 50.214f, 45.774f, 44.293f, + 41.693f, 39.242f, 38.501f, 34.486f, 34.831f, 33.810f, 30.169f, 29.643f, 29.924f, + 28.384f, 26.191f, 26.807f, 25.238f, 21.873f, 20.575f, 19.196f, 15.106f, 12.612f, + 11.141f, 9.342f, 8.517f, 7.535f, 7.469f, 6.785f, 5.133f, 3.661f, 2.623f, + 2.109f, 1.026f, 0.842f, 1.993f, 2.876f, 3.884f, 4.802f, 6.917f, 8.227f, + 9.843f, 12.158f, 11.979f, 6.704f, 1.457f, 15.605f, 25.220f, 24.414f, 24.091f, + 24.297f, 24.025f, 22.091f, 20.424f, 18.566f, 15.889f, 14.373f, 13.774f, 13.624f, + 13.186f, 11.486f, 9.082f, 7.419f, 6.375f, 5.232f, 3.914f, 2.616f, 1.817f, + 1.446f, 2.187f, 2.422f, 1.164f, 2.135f, 2.493f, 3.325f, 3.632f, 1.282f, + 1.741f, 2.178f, 4.222f, 5.718f, 6.496f, 7.363f, 8.479f, 11.250f, 13.136f, + 13.606f}, + {-29.534f, -30.373f, -31.415f, -32.875f, -36.164f, -36.784f, -34.436f, -36.167f, -40.465f, + -45.019f, -51.967f, -52.719f, -51.969f, -53.038f, -56.070f, -58.598f, -57.741f, -57.610f, + -56.191f, -55.838f, -55.464f, -54.101f, -51.482f, -50.460f, -46.856f, -44.238f, -41.019f, + -37.770f, -35.434f, -33.448f, -31.242f, -33.940f, -31.571f, -29.604f, -26.184f, -21.567f, + -21.848f, -20.032f, -18.185f, -16.673f, -15.790f, -14.842f, -13.539f, -11.542f, -10.114f, + -8.189f, -5.674f, -3.962f, -1.267f, 1.049f, 3.825f, 6.553f, 9.158f, 11.876f, + 14.599f, 17.283f, 19.891f, 23.538f, 25.827f, 28.693f, 32.341f, 33.831f, 36.455f, + 38.366f, 40.903f, 44.192f, 46.047f, 48.139f, 51.271f, 54.063f, 55.727f, 56.055f, + 57.219f, 60.149f, 62.188f, 63.914f, 64.234f, 65.787f, 66.912f, 67.994f, 65.925f, + 66.950f, 65.470f, 62.123f, 60.192f, 62.878f, 61.193f, 58.578f, 56.886f, 55.530f, + 54.109f, 53.271f, 51.907f, 50.270f, 49.404f, 49.064f, 48.374f, 49.059f, 42.336f, + 39.605f, 37.929f, 35.571f, 33.493f, 32.375f, 31.406f, 29.456f, 29.188f, 28.197f, + 26.316f, 25.330f, 23.815f, 23.286f, 19.622f, 19.070f, 16.134f, 13.535f, 11.440f, + 9.553f, 8.075f, 7.217f, 5.975f, 5.594f, 6.042f, 4.858f, 2.870f, 1.015f, + 1.698f, 0.996f, -0.436f, 0.182f, 1.323f, 2.376f, 3.366f, 4.715f, 6.261f, + 7.985f, 10.482f, 11.827f, 10.261f, 3.723f, 5.351f, 20.060f, 23.858f, 24.217f, + 25.086f, 24.668f, 23.983f, 20.896f, 18.698f, 15.969f, 14.069f, 12.993f, 12.953f, + 13.373f, 11.907f, 9.289f, 7.793f, 6.875f, 5.463f, 4.093f, 2.928f, 1.890f, + 1.701f, 1.559f, 1.696f, 1.338f, 2.191f, 2.846f, 3.380f, 3.631f, 1.094f, + 1.653f, 2.304f, 4.114f, 5.422f, 6.330f, 7.336f, 8.571f, 11.065f, 13.115f, + 13.606f}, + {-29.534f, -30.366f, -31.407f, -32.865f, -36.158f, -36.386f, -34.140f, -36.494f, -41.163f, + -45.584f, -53.293f, -54.157f, -51.843f, -52.315f, -54.920f, -57.818f, -56.789f, -56.186f, + -54.056f, -53.924f, -55.273f, -55.200f, -52.803f, -50.372f, -47.308f, -44.329f, -41.057f, + -38.355f, -35.865f, -34.097f, -33.048f, -33.619f, -28.302f, -27.000f, -26.693f, -23.238f, + -19.480f, -19.548f, -17.806f, -15.911f, -14.906f, -13.896f, -12.802f, -10.996f, -9.314f, + -7.628f, -5.834f, -3.296f, -0.569f, 1.610f, 4.112f, 6.774f, 9.144f, 11.959f, + 14.742f, 17.192f, 20.128f, 23.780f, 28.395f, 30.628f, 32.798f, 35.432f, 36.490f, + 40.566f, 41.426f, 44.493f, 46.941f, 49.883f, 53.501f, 57.243f, 57.629f, 58.414f, + 59.120f, 59.546f, 61.939f, 63.210f, 64.470f, 65.636f, 63.435f, 64.705f, 62.998f, + 63.066f, 63.346f, 58.720f, 60.049f, 61.145f, 58.848f, 56.159f, 54.337f, 53.078f, + 51.697f, 50.421f, 50.306f, 49.486f, 48.206f, 46.597f, 44.950f, 43.456f, 41.055f, + 37.808f, 36.027f, 34.379f, 32.927f, 31.304f, 29.887f, 29.449f, 27.642f, 26.991f, + 25.122f, 22.677f, 20.932f, 19.436f, 19.187f, 15.306f, 15.933f, 12.511f, 10.190f, + 8.235f, 6.214f, 4.582f, 4.257f, 4.091f, 3.908f, 2.947f, 1.699f, -0.529f, + 0.221f, -0.357f, -1.756f, -1.279f, -0.403f, 0.502f, 1.610f, 3.090f, 4.397f, + 6.394f, 8.696f, 10.480f, 10.403f, 7.995f, 2.317f, 5.983f, 12.117f, 20.759f, + 23.575f, 22.948f, 22.631f, 20.763f, 18.028f, 16.520f, 13.743f, 13.193f, 12.618f, + 13.050f, 11.940f, 9.572f, 8.089f, 7.083f, 5.681f, 4.327f, 3.153f, 1.983f, + 2.012f, 1.166f, 0.996f, 1.493f, 2.476f, 3.189f, 3.348f, 3.340f, 0.862f, + 1.506f, 2.460f, 4.035f, 5.176f, 6.141f, 7.284f, 8.698f, 10.910f, 13.095f, + 13.606f}, + {-29.534f, -30.357f, -31.393f, -32.861f, -36.103f, -35.963f, -33.875f, -37.066f, -42.293f, + -46.917f, -54.414f, -55.885f, -52.740f, -52.611f, -54.367f, -55.835f, -55.334f, -54.700f, + -53.223f, -54.730f, -56.242f, -55.009f, -53.372f, -50.622f, -47.588f, -44.371f, -41.459f, + -38.904f, -36.601f, -35.019f, -34.958f, -33.336f, -30.922f, -29.576f, -27.558f, -26.434f, + -22.697f, -17.440f, -15.322f, -15.293f, -14.001f, -12.450f, -11.412f, -10.695f, -8.279f, + -6.651f, -5.067f, -2.884f, -0.101f, 2.543f, 4.853f, 7.316f, 10.206f, 12.625f, + 15.745f, 19.417f, 23.300f, 26.629f, 29.197f, 31.868f, 33.445f, 35.484f, 37.620f, + 40.506f, 43.287f, 47.970f, 47.780f, 50.503f, 52.215f, 53.925f, 56.661f, 57.835f, + 58.489f, 59.417f, 61.177f, 63.614f, 64.723f, 63.638f, 66.799f, 64.203f, 63.230f, + 62.308f, 61.454f, 56.387f, 59.944f, 59.360f, 56.229f, 53.778f, 51.263f, 50.288f, + 49.257f, 48.401f, 47.325f, 47.343f, 46.944f, 44.746f, 42.769f, 41.215f, 38.556f, + 35.357f, 34.926f, 33.622f, 31.551f, 29.980f, 28.835f, 28.586f, 28.153f, 25.818f, + 24.110f, 22.119f, 21.635f, 19.278f, 16.527f, 14.386f, 12.652f, 10.128f, 8.323f, + 6.872f, 4.894f, 3.896f, 3.289f, 2.775f, 1.337f, 0.332f, -0.140f, -1.611f, + -2.074f, -2.303f, -3.215f, -2.848f, -1.835f, -0.931f, -0.109f, 1.453f, 3.316f, + 4.658f, 6.945f, 8.835f, 9.389f, 9.176f, 6.275f, 0.739f, 1.903f, 16.923f, + 21.529f, 22.356f, 20.965f, 20.258f, 18.272f, 16.797f, 14.436f, 13.652f, 12.705f, + 12.651f, 12.208f, 9.546f, 8.730f, 7.138f, 5.855f, 4.505f, 3.246f, 2.242f, + 2.148f, 1.388f, 0.735f, 1.549f, 2.886f, 3.279f, 3.367f, 2.810f, 0.634f, + 1.369f, 2.615f, 3.979f, 4.997f, 5.956f, 7.214f, 8.846f, 10.784f, 13.075f, + 13.606f}, + {-29.534f, -30.348f, -31.372f, -32.862f, -35.999f, -35.611f, -33.663f, -37.750f, -43.548f, + -48.430f, -54.856f, -57.079f, -54.074f, -53.765f, -55.172f, -53.935f, -52.712f, -53.514f, + -54.678f, -57.400f, -57.343f, -54.911f, -53.813f, -51.386f, -47.612f, -44.408f, -42.130f, + -39.621f, -37.277f, -35.877f, -35.873f, -34.481f, -31.817f, -29.475f, -28.402f, -26.157f, + -22.138f, -18.966f, -15.695f, -13.716f, -13.060f, -11.663f, -10.345f, -8.849f, -7.556f, + -5.851f, -4.131f, -1.543f, 0.857f, 3.649f, 5.872f, 8.242f, 11.018f, 14.008f, + 17.856f, 20.969f, 24.326f, 27.644f, 30.318f, 32.741f, 34.959f, 37.011f, 39.336f, + 42.083f, 44.844f, 47.006f, 49.222f, 51.515f, 53.604f, 57.093f, 57.682f, 56.989f, + 57.862f, 58.446f, 60.561f, 61.765f, 64.493f, 65.238f, 64.262f, 58.105f, 62.729f, + 61.538f, 56.951f, 58.723f, 58.325f, 56.819f, 54.136f, 51.565f, 49.217f, 47.916f, + 47.442f, 46.375f, 45.855f, 45.727f, 44.656f, 42.734f, 41.428f, 38.735f, 37.454f, + 34.858f, 35.562f, 33.149f, 30.117f, 29.503f, 29.816f, 27.750f, 24.575f, 24.291f, + 22.413f, 21.019f, 20.914f, 18.007f, 16.032f, 13.382f, 12.250f, 8.931f, 6.743f, + 4.913f, 3.906f, 3.450f, 1.641f, 0.527f, -0.585f, -1.672f, -2.072f, -2.716f, + -3.837f, -3.629f, -3.589f, -3.759f, -3.189f, -2.615f, -1.415f, 0.047f, 1.516f, + 3.106f, 4.887f, 6.896f, 8.226f, 8.798f, 8.420f, 4.680f, -1.056f, 5.061f, + 14.453f, 20.307f, 19.388f, 19.382f, 18.755f, 17.208f, 15.493f, 13.891f, 13.234f, + 12.295f, 12.205f, 9.655f, 9.330f, 7.429f, 5.947f, 4.749f, 3.453f, 2.584f, + 1.939f, 1.665f, 0.846f, 1.482f, 3.084f, 3.189f, 3.404f, 2.227f, 0.483f, + 1.313f, 2.758f, 3.931f, 4.891f, 5.803f, 7.142f, 9.004f, 10.688f, 13.055f, + 13.606f}, + {-29.534f, -30.338f, -31.345f, -32.868f, -35.851f, -35.419f, -33.558f, -38.416f, -44.642f, + -49.552f, -54.486f, -57.144f, -54.922f, -54.909f, -56.810f, -53.752f, -49.664f, -52.490f, + -56.444f, -58.865f, -57.389f, -55.865f, -54.629f, -51.030f, -47.503f, -44.965f, -42.667f, + -40.342f, -37.988f, -36.849f, -36.922f, -35.678f, -33.907f, -31.133f, -29.485f, -26.995f, + -22.753f, -18.953f, -17.192f, -11.941f, -12.770f, -10.715f, -8.857f, -7.163f, -6.503f, + -4.355f, -2.927f, -0.396f, 2.047f, 4.655f, 7.285f, 9.434f, 12.266f, 15.687f, + 18.696f, 22.439f, 25.604f, 28.518f, 30.912f, 33.181f, 35.997f, 38.445f, 40.636f, + 43.424f, 46.106f, 48.275f, 50.605f, 52.028f, 53.958f, 56.855f, 55.889f, 57.415f, + 58.567f, 60.000f, 60.433f, 61.119f, 63.629f, 63.806f, 61.736f, 62.149f, 58.420f, + 54.496f, 58.690f, 58.330f, 55.823f, 54.396f, 51.743f, 49.651f, 47.911f, 45.590f, + 44.768f, 44.695f, 44.257f, 42.932f, 41.442f, 40.009f, 38.333f, 37.218f, 35.266f, + 33.924f, 33.095f, 31.965f, 30.952f, 28.548f, 26.921f, 25.136f, 23.705f, 22.765f, + 21.452f, 20.185f, 19.446f, 15.989f, 15.458f, 11.841f, 10.729f, 8.628f, 6.273f, + 4.035f, 3.153f, 2.258f, -0.194f, -1.359f, -2.533f, -4.125f, -4.252f, -4.747f, + -4.997f, -4.707f, -4.006f, -4.622f, -4.480f, -3.702f, -2.788f, -1.774f, -0.331f, + 1.570f, 3.087f, 4.641f, 6.461f, 7.830f, 8.490f, 7.407f, 2.916f, -2.507f, + 4.631f, 14.103f, 14.594f, 17.662f, 16.830f, 16.276f, 14.387f, 13.644f, 12.968f, + 11.797f, 11.853f, 10.450f, 9.518f, 7.553f, 6.093f, 5.309f, 3.848f, 3.048f, + 1.893f, 1.521f, 0.941f, 1.410f, 2.932f, 3.213f, 3.355f, 1.796f, 0.438f, + 1.374f, 2.890f, 3.875f, 4.846f, 5.709f, 7.085f, 9.161f, 10.621f, 13.036f, + 13.606f}, + {-29.534f, -30.326f, -31.310f, -32.876f, -35.664f, -35.449f, -33.638f, -38.980f, -45.421f, + -50.013f, -53.574f, -56.148f, -54.815f, -55.423f, -58.057f, -55.297f, -48.159f, -51.383f, + -56.714f, -59.410f, -57.280f, -57.150f, -55.027f, -50.273f, -47.924f, -45.726f, -43.199f, + -41.028f, -38.736f, -38.053f, -37.988f, -36.857f, -34.959f, -32.781f, -30.848f, -27.200f, + -23.191f, -20.179f, -16.828f, -12.132f, -10.967f, -10.286f, -8.279f, -6.688f, -4.771f, + -3.466f, -1.477f, 0.639f, 3.421f, 5.616f, 8.382f, 11.007f, 13.432f, 17.165f, + 20.380f, 24.124f, 27.171f, 29.706f, 31.506f, 33.864f, 36.334f, 38.779f, 41.449f, + 44.303f, 46.676f, 48.548f, 50.047f, 52.201f, 53.943f, 54.270f, 55.718f, 59.003f, + 61.259f, 58.712f, 60.077f, 62.237f, 62.676f, 62.654f, 60.932f, 55.653f, 59.676f, + 59.604f, 58.015f, 55.364f, 54.283f, 51.615f, 49.668f, 47.709f, 45.912f, 44.109f, + 43.543f, 43.089f, 42.095f, 41.017f, 40.576f, 40.224f, 36.455f, 35.001f, 32.791f, + 32.379f, 32.254f, 28.999f, 27.742f, 27.906f, 25.901f, 25.695f, 25.701f, 23.676f, + 20.953f, 19.013f, 18.376f, 16.409f, 12.500f, 10.593f, 8.880f, 7.050f, 4.824f, + 2.531f, 1.442f, 0.561f, -1.407f, -2.854f, -4.313f, -5.996f, -6.478f, -6.479f, + -6.247f, -5.678f, -5.200f, -5.722f, -5.637f, -5.093f, -4.291f, -3.243f, -1.452f, + -0.288f, 1.149f, 2.584f, 4.508f, 6.818f, 8.125f, 8.014f, 6.642f, 1.175f, + -0.653f, 0.673f, 10.701f, 14.537f, 15.222f, 14.494f, 13.070f, 12.168f, 11.723f, + 11.470f, 11.674f, 11.004f, 9.522f, 7.534f, 6.518f, 5.846f, 4.146f, 3.534f, + 2.396f, 1.229f, 0.919f, 1.536f, 2.666f, 3.428f, 3.223f, 1.595f, 0.459f, + 1.529f, 3.013f, 3.810f, 4.846f, 5.691f, 7.059f, 9.309f, 10.580f, 13.018f, + 13.606f}, + {-29.534f, -30.314f, -31.268f, -32.882f, -35.447f, -35.719f, -33.982f, -39.424f, -45.896f, + -49.921f, -52.575f, -54.725f, -54.074f, -55.441f, -58.299f, -56.984f, -49.490f, -50.733f, + -55.586f, -59.595f, -57.465f, -58.005f, -54.666f, -50.425f, -48.538f, -46.289f, -44.073f, + -41.701f, -39.373f, -39.072f, -38.790f, -37.882f, -35.976f, -33.981f, -31.979f, -27.624f, + -23.737f, -20.792f, -17.826f, -13.829f, -9.566f, -10.999f, -10.592f, -7.010f, -4.564f, + -2.516f, -0.871f, 2.018f, 4.372f, 7.108f, 10.101f, 13.024f, 16.701f, 19.252f, + 22.157f, 24.951f, 27.255f, 29.359f, 31.049f, 33.534f, 35.717f, 38.295f, 41.172f, + 44.003f, 46.268f, 47.891f, 49.735f, 51.825f, 52.540f, 54.235f, 60.094f, 59.103f, + 59.724f, 59.826f, 58.613f, 63.012f, 61.564f, 61.938f, 59.761f, 55.246f, 59.820f, + 58.921f, 56.006f, 53.166f, 51.739f, 49.576f, 47.803f, 44.768f, 43.996f, 42.369f, + 42.194f, 41.613f, 40.413f, 39.540f, 37.983f, 36.058f, 34.913f, 33.076f, 31.279f, + 30.330f, 29.821f, 29.109f, 27.292f, 25.940f, 27.293f, 23.656f, 22.724f, 21.474f, + 20.105f, 17.275f, 15.180f, 13.812f, 11.391f, 8.980f, 6.903f, 4.854f, 2.745f, + 1.471f, 0.086f, -1.058f, -2.523f, -3.886f, -5.631f, -7.312f, -7.896f, -8.195f, + -7.340f, -7.332f, -7.305f, -7.373f, -6.774f, -6.154f, -5.474f, -4.561f, -2.951f, + -1.891f, -0.617f, 1.141f, 3.239f, 5.244f, 6.824f, 7.965f, 8.441f, 8.441f, + 3.757f, -0.835f, 6.602f, 10.842f, 12.567f, 14.117f, 13.201f, 11.329f, 11.001f, + 11.512f, 11.224f, 10.875f, 9.785f, 7.870f, 7.067f, 6.110f, 4.261f, 3.553f, + 2.826f, 1.103f, 0.981f, 1.841f, 2.560f, 3.572f, 3.157f, 1.513f, 0.496f, + 1.723f, 3.123f, 3.751f, 4.873f, 5.753f, 7.078f, 9.442f, 10.564f, 13.000f, + 13.606f}, + {-29.534f, -30.302f, -31.219f, -32.884f, -35.206f, -36.190f, -34.645f, -39.790f, -46.182f, + -49.609f, -51.834f, -53.557f, -53.389f, -55.379f, -57.897f, -57.622f, -52.935f, -51.899f, + -54.655f, -58.693f, -57.451f, -58.172f, -54.550f, -51.029f, -48.875f, -46.864f, -44.643f, + -42.441f, -40.158f, -39.703f, -40.129f, -38.905f, -36.693f, -34.898f, -31.598f, -26.885f, + -22.069f, -20.391f, -17.854f, -14.101f, -12.317f, -7.869f, -9.587f, -7.730f, -5.307f, + -2.834f, 0.164f, 2.571f, 5.651f, 8.193f, 11.751f, 15.550f, 18.448f, 21.176f, + 24.356f, 26.120f, 27.202f, 30.380f, 31.642f, 33.533f, 35.984f, 38.093f, 40.242f, + 42.886f, 45.836f, 47.574f, 50.072f, 52.102f, 52.615f, 62.224f, 58.949f, 60.794f, + 59.835f, 60.199f, 61.077f, 59.022f, 61.718f, 59.468f, 55.787f, 52.449f, 58.238f, + 56.327f, 53.530f, 51.794f, 49.155f, 47.433f, 45.390f, 43.547f, 42.132f, 41.082f, + 40.622f, 40.267f, 39.129f, 37.703f, 36.019f, 34.329f, 32.406f, 31.521f, 29.834f, + 29.078f, 27.518f, 27.198f, 29.651f, 25.760f, 23.665f, 22.636f, 21.505f, 20.342f, + 18.618f, 18.989f, 14.335f, 11.993f, 10.332f, 7.906f, 4.888f, 2.838f, 1.787f, + 0.111f, -0.946f, -2.591f, -3.688f, -5.058f, -6.646f, -8.173f, -8.498f, -8.950f, + -8.417f, -8.423f, -8.745f, -8.512f, -8.340f, -7.031f, -6.083f, -5.326f, -4.145f, + -3.432f, -1.520f, 0.065f, 1.918f, 4.005f, 5.469f, 7.621f, 8.843f, 9.603f, + 5.686f, 0.615f, 8.388f, 10.482f, 10.274f, 11.994f, 12.543f, 11.887f, 11.038f, + 11.509f, 11.129f, 10.821f, 9.818f, 8.155f, 7.427f, 6.364f, 4.262f, 3.118f, + 2.646f, 1.089f, 1.186f, 2.032f, 2.608f, 3.446f, 3.291f, 1.339f, 0.547f, + 1.907f, 3.210f, 3.719f, 4.916f, 5.889f, 7.150f, 9.557f, 10.568f, 12.983f, + 13.606f}, + {-29.534f, -30.289f, -31.161f, -32.877f, -34.947f, -36.773f, -35.623f, -40.155f, -46.410f, + -49.397f, -51.417f, -52.918f, -53.178f, -55.328f, -57.444f, -57.538f, -56.413f, -55.077f, + -55.237f, -57.811f, -57.780f, -57.935f, -54.862f, -52.025f, -49.396f, -47.483f, -45.338f, + -42.941f, -41.097f, -41.055f, -41.208f, -39.762f, -37.955f, -35.595f, -30.845f, -25.558f, + -22.329f, -18.562f, -15.449f, -11.420f, -9.740f, -8.838f, -6.133f, -3.660f, -2.462f, + -5.782f, 1.381f, 4.347f, 7.329f, 9.398f, 12.241f, 15.535f, 18.822f, 22.331f, + 25.130f, 26.006f, 28.362f, 29.897f, 32.498f, 34.622f, 37.463f, 39.715f, 41.708f, + 45.006f, 46.915f, 49.208f, 51.495f, 53.469f, 59.328f, 60.190f, 61.083f, 59.957f, + 60.211f, 60.131f, 59.757f, 54.301f, 52.161f, 47.984f, 46.261f, 54.335f, 58.336f, + 55.675f, 51.459f, 50.040f, 47.316f, 45.297f, 43.624f, 42.011f, 40.630f, 39.454f, + 39.076f, 38.658f, 37.765f, 35.652f, 34.247f, 32.768f, 30.906f, 30.243f, 28.578f, + 30.132f, 28.204f, 26.926f, 25.948f, 24.336f, 24.053f, 22.468f, 20.312f, 19.053f, + 17.584f, 15.160f, 13.473f, 11.589f, 7.981f, 6.522f, 3.868f, 2.096f, 0.667f, + -0.696f, -2.063f, -3.436f, -5.182f, -6.681f, -7.857f, -8.795f, -9.104f, -9.506f, + -9.391f, -8.739f, -9.421f, -9.205f, -8.879f, -7.954f, -6.974f, -5.622f, -4.763f, + -3.964f, -2.527f, -0.864f, 0.710f, 2.333f, 3.900f, 6.234f, 8.846f, 8.523f, + 2.494f, 8.276f, 9.380f, 10.218f, 9.621f, 9.568f, 11.674f, 11.637f, 10.664f, + 10.998f, 10.961f, 10.646f, 9.597f, 8.378f, 7.656f, 6.438f, 4.018f, 2.940f, + 2.348f, 1.217f, 1.398f, 1.980f, 2.648f, 3.260f, 3.568f, 0.949f, 0.677f, + 2.062f, 3.264f, 3.734f, 4.971f, 6.081f, 7.274f, 9.652f, 10.591f, 12.968f, + 13.606f}, + {-29.534f, -30.275f, -31.096f, -32.859f, -34.678f, -37.347f, -36.850f, -40.592f, -46.652f, + -49.413f, -51.194f, -52.652f, -53.371f, -55.220f, -57.162f, -57.568f, -58.299f, -57.971f, + -56.051f, -57.866f, -58.657f, -57.797f, -54.860f, -52.849f, -50.052f, -48.314f, -46.009f, + -43.251f, -41.924f, -43.409f, -41.718f, -40.614f, -38.641f, -36.450f, -31.937f, -25.419f, + -22.110f, -19.249f, -15.914f, -11.578f, -8.693f, -6.222f, -3.223f, -1.501f, 3.601f, + -0.690f, -0.350f, 5.140f, 8.729f, 12.540f, 15.323f, 18.243f, 21.183f, 24.059f, + 25.270f, 27.108f, 30.075f, 33.921f, 36.343f, 36.692f, 39.271f, 41.470f, 43.547f, + 46.382f, 49.156f, 50.686f, 53.586f, 56.917f, 60.329f, 60.235f, 58.107f, 57.806f, + 57.478f, 57.879f, 62.155f, 62.143f, 56.759f, 58.977f, 58.243f, 57.887f, 57.415f, + 53.817f, 50.330f, 48.220f, 45.332f, 43.470f, 42.600f, 40.416f, 39.597f, 38.870f, + 37.882f, 37.030f, 35.819f, 33.957f, 32.710f, 30.295f, 29.355f, 28.416f, 27.769f, + 29.386f, 25.860f, 27.983f, 25.515f, 21.597f, 23.954f, 18.989f, 19.596f, 18.202f, + 17.535f, 16.589f, 12.805f, 10.417f, 7.354f, 5.077f, 2.834f, 1.081f, -0.444f, + -1.886f, -2.920f, -4.578f, -6.222f, -7.481f, -8.323f, -8.972f, -9.560f, -9.650f, + -9.910f, -9.455f, -9.749f, -9.836f, -9.763f, -8.942f, -7.773f, -6.534f, -5.315f, + -4.877f, -4.096f, -3.166f, -1.907f, -0.522f, 3.185f, 6.347f, 8.034f, 5.468f, + 0.168f, 13.546f, 8.330f, 9.223f, 8.766f, 7.460f, 10.584f, 11.549f, 10.132f, + 10.102f, 10.484f, 10.163f, 9.664f, 8.670f, 7.968f, 6.218f, 3.790f, 3.174f, + 2.381f, 1.530f, 1.520f, 1.966f, 2.636f, 3.379f, 3.762f, 0.441f, 0.954f, + 2.200f, 3.285f, 3.798f, 5.037f, 6.305f, 7.446f, 9.728f, 10.629f, 12.953f, + 13.606f}, + {-29.534f, -30.261f, -31.024f, -32.824f, -34.405f, -37.779f, -38.192f, -41.141f, -46.903f, + -49.578f, -51.024f, -52.511f, -53.689f, -55.277f, -57.119f, -57.878f, -58.582f, -58.375f, + -55.012f, -57.558f, -59.261f, -57.862f, -54.940f, -53.013f, -50.830f, -48.975f, -46.552f, + -43.839f, -43.040f, -44.758f, -42.698f, -41.286f, -39.445f, -37.195f, -33.050f, -26.317f, + -22.317f, -18.978f, -15.558f, -11.842f, -9.616f, -7.446f, -3.853f, 1.088f, 3.523f, + 4.173f, 1.986f, 7.276f, 10.722f, 14.383f, 17.607f, 21.042f, 23.866f, 25.059f, + 26.641f, 28.217f, 31.745f, 33.859f, 36.705f, 39.484f, 42.462f, 46.101f, 45.710f, + 47.989f, 50.313f, 52.721f, 55.335f, 58.061f, 58.150f, 57.145f, 51.310f, 53.331f, + 57.668f, 61.996f, 64.424f, 63.563f, 64.605f, 62.156f, 60.770f, 58.639f, 55.647f, + 52.320f, 48.623f, 45.988f, 44.057f, 42.116f, 40.839f, 39.489f, 38.205f, 37.101f, + 36.155f, 35.176f, 33.890f, 31.900f, 31.159f, 29.718f, 29.171f, 26.500f, 28.429f, + 28.295f, 24.619f, 25.515f, 22.997f, 21.254f, 21.793f, 17.615f, 18.140f, 16.592f, + 15.923f, 14.011f, 11.368f, 9.253f, 6.534f, 4.070f, 2.493f, 0.293f, -1.510f, + -2.877f, -4.042f, -5.352f, -6.449f, -7.658f, -8.646f, -8.990f, -9.481f, -9.626f, + -9.760f, -9.897f, -10.644f, -10.897f, -11.119f, -10.505f, -9.257f, -8.017f, -7.532f, + -7.250f, -7.389f, -6.641f, -3.910f, 0.596f, 4.164f, 5.582f, 5.861f, 0.944f, + 2.095f, 8.902f, 8.103f, 7.725f, 7.294f, 6.147f, 8.665f, 11.278f, 10.334f, + 9.753f, 9.954f, 9.517f, 9.486f, 8.573f, 8.083f, 5.990f, 4.045f, 3.313f, + 2.485f, 1.706f, 1.524f, 2.237f, 2.632f, 3.781f, 3.684f, 0.073f, 1.355f, + 2.334f, 3.282f, 3.897f, 5.113f, 6.536f, 7.653f, 9.788f, 10.678f, 12.940f, + 13.606f}, + {-29.534f, -30.246f, -30.944f, -32.773f, -34.135f, -37.958f, -39.483f, -41.788f, -47.117f, + -49.729f, -50.887f, -52.428f, -53.962f, -55.820f, -57.463f, -58.199f, -58.377f, -57.246f, + -53.341f, -56.842f, -59.321f, -57.820f, -55.334f, -53.383f, -51.653f, -49.295f, -47.156f, + -44.423f, -45.112f, -45.016f, -43.621f, -42.339f, -40.557f, -37.807f, -34.061f, -28.052f, + -22.970f, -18.315f, -15.201f, -12.135f, -10.209f, -7.990f, -4.642f, 0.876f, 5.219f, + 5.204f, 5.106f, 8.345f, 11.751f, 15.439f, 18.551f, 22.406f, 25.078f, 25.707f, + 27.879f, 30.777f, 32.329f, 34.590f, 36.971f, 40.135f, 42.679f, 44.558f, 46.842f, + 49.221f, 51.418f, 53.586f, 55.170f, 56.550f, 54.393f, 49.570f, 54.715f, 63.933f, + 65.307f, 66.438f, 65.827f, 64.969f, 64.022f, 62.324f, 60.467f, 57.482f, 53.949f, + 49.307f, 46.766f, 44.101f, 42.292f, 40.909f, 39.682f, 38.492f, 36.821f, 35.205f, + 33.833f, 32.923f, 31.698f, 30.387f, 29.989f, 28.561f, 28.208f, 27.184f, 26.582f, + 24.590f, 26.444f, 22.543f, 23.307f, 20.289f, 18.921f, 19.183f, 16.590f, 15.511f, + 14.187f, 12.076f, 9.885f, 8.467f, 6.009f, 3.193f, 1.167f, -0.613f, -2.721f, + -4.042f, -4.591f, -5.973f, -6.948f, -7.693f, -8.427f, -9.365f, -9.785f, -10.310f, + -10.215f, -11.210f, -12.366f, -12.920f, -12.787f, -12.122f, -11.726f, -10.813f, -10.514f, + -10.188f, -4.472f, -2.995f, -0.303f, 1.164f, 1.223f, 4.935f, 3.305f, -2.636f, + 4.388f, 6.560f, 6.662f, 6.519f, 6.135f, 5.555f, 7.661f, 10.255f, 10.908f, + 9.733f, 9.136f, 9.107f, 8.864f, 8.321f, 7.517f, 5.612f, 4.376f, 3.312f, + 2.498f, 1.535f, 1.432f, 2.566f, 2.665f, 4.034f, 3.377f, 0.045f, 1.747f, + 2.458f, 3.277f, 4.003f, 5.198f, 6.748f, 7.879f, 9.836f, 10.735f, 12.928f, + 13.606f}, + {-29.534f, -30.232f, -30.858f, -32.702f, -33.878f, -37.820f, -40.560f, -42.481f, -47.260f, + -49.762f, -50.844f, -52.465f, -54.163f, -56.628f, -58.092f, -58.527f, -58.503f, -56.970f, + -53.822f, -57.135f, -58.875f, -57.621f, -55.577f, -53.923f, -52.080f, -50.055f, -47.522f, + -44.838f, -46.847f, -45.516f, -44.474f, -43.063f, -41.230f, -38.270f, -35.171f, -29.912f, + -23.738f, -18.442f, -16.005f, -12.766f, -10.074f, -7.962f, -5.090f, -0.904f, 5.770f, + 7.694f, 7.793f, 9.474f, 12.668f, 15.831f, 19.136f, 22.112f, 24.891f, 26.641f, + 28.921f, 31.823f, 33.491f, 36.392f, 38.761f, 41.292f, 43.845f, 45.797f, 47.499f, + 49.706f, 51.436f, 53.278f, 54.420f, 51.606f, 51.364f, 61.519f, 63.960f, 66.054f, + 66.746f, 66.409f, 65.997f, 64.938f, 63.664f, 61.636f, 59.537f, 56.060f, 50.628f, + 47.984f, 44.179f, 42.023f, 40.402f, 39.458f, 37.951f, 36.707f, 34.663f, 33.372f, + 31.946f, 31.118f, 30.687f, 29.888f, 28.351f, 27.697f, 27.680f, 25.737f, 25.320f, + 27.579f, 24.966f, 25.223f, 21.942f, 19.520f, 17.540f, 16.437f, 15.694f, 14.384f, + 12.422f, 11.254f, 8.987f, 7.159f, 4.699f, 2.165f, 0.612f, -1.452f, -3.464f, + -4.707f, -5.833f, -6.392f, -6.843f, -7.740f, -8.419f, -10.128f, -11.753f, -11.863f, + -11.933f, -13.192f, -9.567f, -14.709f, -10.680f, -7.250f, -9.678f, -8.361f, -7.658f, + -3.284f, -4.702f, -4.377f, -5.569f, -1.751f, 2.614f, 3.698f, 0.796f, -0.118f, + 4.329f, 4.859f, 6.019f, 6.221f, 6.580f, 6.761f, 8.921f, 10.007f, 11.187f, + 9.455f, 8.703f, 8.587f, 8.377f, 8.001f, 6.534f, 5.117f, 4.223f, 3.405f, + 2.451f, 1.354f, 1.364f, 2.571f, 2.733f, 3.839f, 3.065f, 0.332f, 1.962f, + 2.555f, 3.291f, 4.087f, 5.284f, 6.926f, 8.106f, 9.874f, 10.796f, 12.917f, + 13.606f}, + {-29.534f, -30.217f, -30.766f, -32.613f, -33.640f, -37.369f, -41.311f, -43.141f, -47.336f, + -49.692f, -50.931f, -52.602f, -54.274f, -56.953f, -58.456f, -58.967f, -58.863f, -57.775f, + -56.061f, -58.197f, -58.222f, -57.624f, -56.060f, -54.359f, -52.460f, -50.706f, -47.852f, + -45.610f, -47.780f, -46.388f, -45.138f, -43.854f, -41.657f, -39.054f, -36.036f, -32.064f, + -24.437f, -19.495f, -16.194f, -13.057f, -9.861f, -7.719f, -5.786f, -2.040f, 2.591f, + 6.839f, 9.135f, 11.149f, 14.200f, 16.241f, 19.367f, 21.942f, 24.137f, 27.442f, + 29.424f, 31.679f, 35.723f, 37.392f, 39.842f, 42.039f, 44.773f, 46.627f, 48.240f, + 50.248f, 51.385f, 52.371f, 53.156f, 48.799f, 60.203f, 63.779f, 64.892f, 65.852f, + 66.135f, 65.875f, 65.148f, 64.113f, 62.580f, 60.441f, 57.903f, 52.234f, 49.562f, + 45.129f, 41.756f, 40.189f, 38.648f, 37.120f, 35.379f, 34.070f, 33.037f, 32.027f, + 31.137f, 30.897f, 29.885f, 28.619f, 27.728f, 26.634f, 24.616f, 25.780f, 25.878f, + 26.386f, 23.141f, 22.088f, 20.193f, 18.402f, 16.553f, 15.332f, 14.822f, 13.225f, + 14.570f, 10.366f, 6.965f, 6.247f, 3.732f, 1.732f, -0.185f, -2.189f, -4.025f, + -5.613f, -6.633f, -6.727f, -6.951f, -8.171f, -9.471f, -10.476f, -11.711f, -8.826f, + -11.138f, -12.299f, -7.565f, -13.111f, -15.222f, -7.932f, -11.089f, -10.389f, -10.766f, + -9.655f, -8.580f, -6.042f, -3.030f, 0.277f, 2.218f, 2.537f, -2.592f, 2.953f, + 3.422f, 2.475f, 4.252f, 5.379f, 5.987f, 5.114f, 4.271f, 9.902f, 11.027f, + 9.098f, 8.213f, 7.476f, 8.219f, 7.527f, 5.824f, 4.905f, 3.909f, 3.334f, + 2.170f, 1.414f, 1.387f, 2.277f, 2.865f, 3.390f, 2.902f, 0.705f, 1.930f, + 2.617f, 3.343f, 4.132f, 5.364f, 7.060f, 8.318f, 9.908f, 10.859f, 12.907f, + 13.606f}, + {-29.534f, -30.202f, -30.668f, -32.508f, -33.433f, -36.673f, -41.704f, -43.696f, -47.386f, + -49.617f, -51.093f, -52.672f, -54.241f, -56.397f, -58.145f, -59.293f, -59.064f, -58.266f, + -57.632f, -58.993f, -58.193f, -57.860f, -56.760f, -55.036f, -53.071f, -51.071f, -47.878f, + -47.177f, -48.072f, -46.887f, -45.819f, -44.457f, -42.088f, -39.404f, -36.700f, -33.027f, + -25.931f, -20.248f, -16.514f, -13.612f, -9.872f, -7.255f, -5.366f, -2.443f, 0.793f, + 5.508f, 9.499f, 12.836f, 15.150f, 17.782f, 19.721f, 22.361f, 24.911f, 27.541f, + 30.618f, 34.303f, 38.809f, 38.477f, 40.948f, 43.031f, 45.429f, 46.824f, 48.277f, + 50.156f, 51.955f, 53.101f, 53.183f, 49.988f, 60.852f, 63.756f, 64.829f, 65.376f, + 65.241f, 64.737f, 63.752f, 62.593f, 61.082f, 59.104f, 56.558f, 50.521f, 46.958f, + 42.803f, 40.526f, 38.659f, 37.200f, 35.050f, 34.067f, 32.765f, 32.314f, 30.597f, + 28.620f, 28.148f, 27.180f, 26.357f, 25.127f, 24.848f, 27.383f, 25.864f, 22.678f, + 21.928f, 21.913f, 21.329f, 19.180f, 17.248f, 15.532f, 14.350f, 13.220f, 11.725f, + 12.334f, 9.369f, 7.936f, 5.091f, 2.986f, 1.288f, -0.577f, -2.837f, -4.692f, + -6.156f, -6.987f, -6.736f, -7.074f, -8.566f, -8.429f, -6.580f, -9.027f, -4.060f, + -11.053f, -12.932f, -14.378f, -13.974f, -13.483f, -13.489f, -12.529f, -11.110f, -10.076f, + -8.699f, -6.906f, -4.957f, -2.168f, 0.102f, 1.926f, 0.843f, -5.787f, 4.610f, + 2.335f, 2.298f, 2.437f, 3.199f, 3.004f, 1.245f, -0.910f, 8.233f, 9.539f, + 8.573f, 7.851f, 7.113f, 7.547f, 7.113f, 5.656f, 4.878f, 3.782f, 2.904f, + 1.801f, 1.464f, 1.366f, 2.023f, 3.021f, 3.061f, 2.801f, 0.952f, 1.749f, + 2.662f, 3.439f, 4.142f, 5.431f, 7.152f, 8.502f, 9.941f, 10.921f, 12.899f, + 13.606f}, + {-29.534f, -30.187f, -30.566f, -32.389f, -33.264f, -35.861f, -41.796f, -44.106f, -47.447f, + -49.619f, -51.245f, -52.550f, -54.068f, -55.489f, -57.508f, -59.200f, -59.075f, -58.195f, + -58.005f, -59.325f, -58.626f, -58.202f, -57.077f, -55.541f, -53.711f, -51.850f, -48.311f, + -48.631f, -48.047f, -47.460f, -46.282f, -44.617f, -42.301f, -39.684f, -36.811f, -33.508f, + -27.648f, -21.144f, -17.465f, -13.794f, -10.148f, -7.022f, -5.310f, -2.475f, 0.573f, + 4.975f, 10.669f, 11.676f, 14.960f, 16.287f, 18.905f, 23.680f, 26.090f, 29.011f, + 32.731f, 37.676f, 38.750f, 40.053f, 42.272f, 44.577f, 45.952f, 47.232f, 48.637f, + 50.252f, 51.727f, 52.941f, 53.607f, 49.514f, 60.072f, 62.715f, 64.091f, 64.237f, + 64.084f, 63.380f, 62.481f, 60.899f, 59.489f, 57.257f, 52.529f, 49.168f, 44.349f, + 41.545f, 39.404f, 37.413f, 35.830f, 33.873f, 32.251f, 31.793f, 29.532f, 27.757f, + 27.944f, 29.151f, 28.349f, 27.852f, 26.198f, 24.114f, 23.644f, 23.453f, 22.466f, + 21.615f, 21.015f, 20.134f, 18.226f, 15.998f, 14.234f, 13.099f, 12.348f, 10.853f, + 10.674f, 8.576f, 5.704f, 4.344f, 3.176f, 1.043f, -1.047f, -3.296f, -4.957f, + -6.351f, -6.810f, -6.663f, -7.168f, -8.464f, -5.157f, -9.489f, -11.313f, -12.719f, + -12.298f, -12.582f, -12.913f, -12.544f, -11.853f, -11.323f, -10.707f, -9.167f, -8.576f, + -7.643f, -6.066f, -4.049f, -2.934f, -0.402f, 0.657f, -1.006f, -2.213f, 6.825f, + 1.955f, 1.671f, 2.768f, 2.335f, 1.500f, 0.159f, -0.924f, 5.243f, 7.722f, + 8.095f, 7.501f, 6.927f, 6.324f, 6.602f, 6.006f, 4.941f, 3.685f, 2.503f, + 1.824f, 1.351f, 1.217f, 1.966f, 3.025f, 2.920f, 2.556f, 1.070f, 1.635f, + 2.733f, 3.570f, 4.138f, 5.484f, 7.213f, 8.650f, 9.976f, 10.980f, 12.892f, + 13.606f}, + {-29.534f, -30.172f, -30.459f, -32.262f, -33.140f, -35.090f, -41.719f, -44.367f, -47.531f, + -49.704f, -51.355f, -52.337f, -53.867f, -55.107f, -57.252f, -58.803f, -59.102f, -58.424f, + -58.286f, -59.308f, -58.886f, -58.852f, -57.365f, -55.713f, -54.424f, -51.921f, -49.121f, + -48.928f, -48.426f, -47.917f, -46.462f, -44.737f, -42.196f, -39.791f, -37.119f, -33.645f, + -29.145f, -22.938f, -18.802f, -14.635f, -10.703f, -7.152f, -5.198f, -2.422f, 0.523f, + 5.271f, 10.396f, 10.406f, 10.729f, 12.837f, 15.432f, 23.299f, 28.302f, 31.581f, + 35.514f, 38.837f, 38.622f, 40.065f, 41.693f, 43.293f, 44.947f, 46.741f, 48.839f, + 50.099f, 51.279f, 52.423f, 53.783f, 51.521f, 58.288f, 61.742f, 62.703f, 62.893f, + 62.722f, 61.951f, 60.873f, 59.472f, 57.750f, 55.786f, 51.610f, 46.470f, 42.602f, + 40.775f, 38.647f, 36.674f, 34.075f, 32.702f, 30.394f, 29.551f, 27.277f, 28.364f, + 27.546f, 25.843f, 25.686f, 24.526f, 23.852f, 23.176f, 22.623f, 22.155f, 21.652f, + 20.411f, 20.202f, 18.692f, 17.025f, 15.445f, 14.105f, 12.641f, 11.844f, 10.539f, + 9.778f, 7.473f, 5.548f, 4.593f, 1.814f, 1.118f, -1.292f, -3.446f, -5.157f, + -6.180f, -6.973f, -6.546f, -6.389f, -8.224f, -9.329f, -9.368f, -9.032f, -10.101f, + -10.991f, -11.648f, -11.690f, -11.668f, -11.237f, -11.188f, -10.708f, -9.809f, -9.472f, + -8.566f, -6.341f, -4.505f, -2.200f, -0.236f, 0.869f, -3.899f, 1.225f, 4.712f, + 2.421f, -0.469f, 1.426f, 1.996f, 1.704f, 0.145f, -1.270f, 3.403f, 6.123f, + 7.473f, 6.811f, 6.365f, 6.085f, 6.298f, 6.452f, 5.133f, 3.612f, 2.426f, + 2.126f, 1.289f, 1.126f, 1.961f, 2.748f, 2.739f, 2.141f, 1.234f, 1.779f, + 2.872f, 3.718f, 4.153f, 5.528f, 7.256f, 8.760f, 10.015f, 11.034f, 12.885f, + 13.606f}, + {-29.534f, -30.157f, -30.350f, -32.131f, -33.067f, -34.520f, -41.639f, -44.514f, -47.616f, + -49.804f, -51.474f, -52.309f, -53.805f, -55.501f, -57.573f, -58.545f, -59.275f, -59.195f, + -59.090f, -59.436f, -59.386f, -59.567f, -57.849f, -56.077f, -54.759f, -51.691f, -49.520f, + -49.503f, -48.723f, -47.832f, -46.830f, -45.010f, -42.375f, -39.855f, -36.836f, -33.437f, + -29.746f, -25.713f, -20.802f, -15.783f, -11.765f, -7.086f, -5.153f, -2.608f, 0.872f, + 5.701f, 11.055f, 12.340f, 8.993f, 13.304f, 12.876f, 25.113f, 30.039f, 33.466f, + 36.786f, 38.148f, 39.241f, 40.165f, 41.765f, 43.416f, 44.955f, 46.474f, 48.328f, + 49.599f, 50.636f, 51.960f, 53.376f, 53.343f, 56.648f, 60.111f, 61.112f, 61.137f, + 60.924f, 60.563f, 59.468f, 58.015f, 56.024f, 53.599f, 49.753f, 45.155f, 41.495f, + 39.432f, 37.248f, 35.192f, 32.690f, 31.141f, 28.908f, 27.266f, 27.506f, 27.506f, + 25.349f, 25.890f, 24.541f, 23.989f, 23.294f, 22.196f, 20.753f, 20.874f, 20.183f, + 19.301f, 18.987f, 17.118f, 15.571f, 14.456f, 13.622f, 12.018f, 11.062f, 9.650f, + 8.968f, 7.256f, 5.166f, 4.469f, 3.795f, -0.010f, -1.388f, -3.962f, -5.135f, + -5.677f, -6.353f, -5.983f, -6.857f, -8.337f, -8.964f, -8.608f, -8.218f, -9.917f, + -10.891f, -11.013f, -11.402f, -11.935f, -11.909f, -12.062f, -11.281f, -11.304f, -10.240f, + -7.491f, -6.279f, -4.624f, -2.062f, 0.026f, 0.863f, -5.422f, 5.067f, 2.265f, + 3.245f, -2.174f, 0.517f, 1.560f, 1.203f, 0.034f, -1.884f, 1.122f, 3.903f, + 6.902f, 6.142f, 6.031f, 6.180f, 6.334f, 6.408f, 5.259f, 3.618f, 2.541f, + 2.291f, 1.345f, 1.240f, 1.869f, 2.296f, 2.429f, 1.829f, 1.599f, 2.219f, + 3.089f, 3.856f, 4.214f, 5.575f, 7.299f, 8.835f, 10.059f, 11.081f, 12.880f, + 13.606f}, + {-29.534f, -30.143f, -30.238f, -32.002f, -33.044f, -34.276f, -41.710f, -44.605f, -47.668f, + -49.851f, -51.667f, -52.643f, -53.994f, -56.173f, -58.072f, -58.721f, -59.575f, -60.021f, + -60.203f, -60.184f, -60.124f, -59.733f, -58.182f, -56.622f, -54.618f, -52.211f, -49.839f, + -50.186f, -48.886f, -47.880f, -46.997f, -45.261f, -42.436f, -39.746f, -36.684f, -33.264f, + -30.029f, -26.507f, -23.096f, -18.168f, -12.624f, -8.343f, -5.615f, -2.750f, 0.624f, + 5.419f, 11.603f, 13.510f, 9.704f, 16.848f, 15.995f, 24.561f, 29.203f, 32.910f, + 36.442f, 37.552f, 39.740f, 40.959f, 42.343f, 43.377f, 45.120f, 46.706f, 47.805f, + 48.931f, 50.079f, 51.166f, 52.441f, 53.588f, 54.195f, 58.987f, 59.104f, 59.267f, + 59.348f, 58.923f, 57.699f, 56.190f, 54.387f, 52.157f, 49.120f, 42.633f, 39.323f, + 37.872f, 35.722f, 32.457f, 32.334f, 29.161f, 28.798f, 26.094f, 27.087f, 26.363f, + 24.657f, 24.025f, 23.315f, 22.164f, 21.352f, 21.277f, 21.385f, 19.018f, 18.898f, + 18.242f, 17.613f, 15.917f, 14.427f, 13.930f, 13.704f, 12.278f, 11.268f, 9.293f, + 8.013f, 6.682f, 6.507f, 5.191f, 2.015f, 0.532f, -1.827f, -3.959f, -5.059f, + -5.442f, -5.580f, -5.762f, -7.040f, -6.452f, -9.214f, -9.157f, -8.806f, -10.209f, + -10.584f, -10.638f, -11.142f, -11.997f, -12.440f, -12.306f, -11.941f, -10.537f, -8.786f, + -7.760f, -6.167f, -4.115f, -2.033f, -0.152f, 0.536f, -8.959f, 5.864f, 1.843f, + 2.695f, 0.814f, -0.039f, 0.857f, 1.008f, -0.084f, -1.841f, -0.575f, 2.486f, + 6.254f, 4.721f, 5.147f, 5.640f, 6.376f, 6.212f, 5.333f, 3.478f, 2.648f, + 2.466f, 1.352f, 1.382f, 1.739f, 1.879f, 2.181f, 1.942f, 2.117f, 2.834f, + 3.357f, 3.965f, 4.332f, 5.637f, 7.356f, 8.883f, 10.108f, 11.120f, 12.876f, + 13.606f}, + {-29.534f, -30.129f, -30.125f, -31.883f, -33.070f, -34.420f, -42.024f, -44.694f, -47.674f, + -49.837f, -51.942f, -53.239f, -54.436f, -56.643f, -58.464f, -59.338f, -59.883f, -60.555f, + -61.093f, -60.977f, -60.464f, -59.639f, -58.531f, -57.080f, -54.900f, -52.336f, -50.203f, + -49.939f, -49.353f, -47.977f, -46.933f, -45.211f, -42.610f, -39.780f, -36.621f, -33.492f, + -30.609f, -27.083f, -23.725f, -19.647f, -13.219f, -9.009f, -5.193f, -3.138f, 0.081f, + 4.911f, 11.051f, 14.460f, 11.324f, 15.938f, 18.284f, 19.726f, 25.870f, 30.085f, + 34.459f, 37.761f, 40.113f, 41.590f, 42.703f, 43.784f, 45.252f, 46.579f, 47.491f, + 48.100f, 49.172f, 50.314f, 51.246f, 52.011f, 53.228f, 53.961f, 56.798f, 57.085f, + 57.206f, 57.687f, 55.978f, 54.560f, 52.513f, 50.294f, 46.318f, 40.755f, 37.734f, + 35.923f, 34.258f, 31.477f, 30.510f, 28.448f, 26.606f, 25.863f, 24.518f, 23.842f, + 23.382f, 22.696f, 21.228f, 20.812f, 19.239f, 17.946f, 18.289f, 17.746f, 17.685f, + 17.807f, 16.343f, 15.283f, 14.037f, 13.298f, 12.422f, 11.334f, 10.245f, 8.897f, + 7.275f, 6.376f, 5.390f, 5.560f, 2.098f, 0.265f, -1.893f, -4.186f, -4.762f, + -4.697f, -4.779f, -5.558f, -6.917f, -8.144f, -9.093f, -9.276f, -8.928f, -9.776f, + -10.599f, -10.727f, -11.499f, -12.321f, -12.543f, -12.449f, -11.673f, -9.679f, -8.735f, + -7.094f, -5.755f, -3.849f, -1.736f, 0.337f, -0.964f, -10.263f, 3.967f, 1.344f, + 1.946f, 4.041f, -0.496f, 0.922f, 0.627f, 0.029f, -1.018f, -1.525f, 3.025f, + 5.247f, 4.071f, 4.661f, 5.319f, 6.493f, 6.293f, 5.217f, 3.132f, 2.592f, + 2.772f, 1.319f, 1.346f, 1.675f, 1.567f, 2.163f, 2.499f, 2.586f, 3.440f, + 3.624f, 4.039f, 4.502f, 5.725f, 7.439f, 8.913f, 10.163f, 11.152f, 12.873f, + 13.606f}, + {-29.534f, -30.115f, -30.011f, -31.777f, -33.138f, -34.946f, -42.591f, -44.819f, -47.652f, + -49.823f, -52.235f, -53.819f, -55.028f, -56.957f, -58.866f, -60.231f, -60.156f, -60.778f, + -61.497f, -61.186f, -60.780f, -60.107f, -58.952f, -57.482f, -55.345f, -51.869f, -50.534f, + -49.799f, -49.325f, -48.243f, -46.691f, -45.019f, -42.670f, -39.944f, -37.004f, -33.579f, + -30.602f, -27.520f, -24.215f, -20.489f, -13.987f, -9.182f, -5.070f, -3.322f, -0.351f, + 4.574f, 10.564f, 14.833f, 14.074f, 15.402f, 19.026f, 21.300f, 22.123f, 22.866f, + 32.875f, 37.988f, 40.710f, 42.036f, 43.121f, 44.316f, 45.470f, 46.451f, 47.112f, + 47.529f, 48.524f, 49.394f, 50.232f, 50.847f, 51.217f, 53.361f, 52.268f, 55.492f, + 56.348f, 55.312f, 53.969f, 52.547f, 51.144f, 48.098f, 45.937f, 40.308f, 36.219f, + 34.504f, 33.087f, 29.697f, 28.292f, 27.188f, 26.369f, 25.149f, 24.097f, 23.634f, + 22.755f, 21.305f, 20.816f, 20.074f, 18.916f, 18.063f, 18.145f, 17.293f, 16.445f, + 16.384f, 14.845f, 14.348f, 13.253f, 11.916f, 11.159f, 10.176f, 9.291f, 8.063f, + 7.178f, 5.592f, 4.861f, 3.804f, 2.636f, -0.461f, -2.659f, -3.856f, -4.279f, + -3.951f, -4.816f, -5.672f, -6.973f, -8.411f, -9.083f, -9.158f, -8.510f, -9.482f, + -10.263f, -11.158f, -12.151f, -12.630f, -12.738f, -12.117f, -10.924f, -10.091f, -8.579f, + -6.801f, -5.170f, -3.702f, -1.827f, 0.228f, -2.989f, -8.360f, 5.723f, 1.391f, + 1.605f, 3.535f, -0.406f, 1.044f, 1.005f, 0.110f, -0.331f, -0.093f, 5.297f, + 5.137f, 4.181f, 4.859f, 5.186f, 6.276f, 6.185f, 4.673f, 2.873f, 2.391f, + 2.786f, 1.380f, 1.214f, 1.707f, 1.343f, 2.270f, 3.145f, 2.855f, 3.911f, + 3.841f, 4.088f, 4.698f, 5.845f, 7.550f, 8.938f, 10.220f, 11.175f, 12.870f, + 13.606f}, + {-29.534f, -30.102f, -29.897f, -31.689f, -33.239f, -35.775f, -43.335f, -44.989f, -47.643f, + -49.891f, -52.467f, -54.201f, -55.614f, -57.379f, -59.357f, -61.076f, -60.592f, -60.828f, + -61.680f, -61.030f, -61.405f, -60.902f, -58.811f, -57.671f, -55.306f, -51.562f, -50.608f, + -49.884f, -48.933f, -48.032f, -46.458f, -44.723f, -42.709f, -40.207f, -37.037f, -34.005f, + -30.816f, -27.742f, -24.229f, -20.879f, -15.207f, -8.844f, -4.270f, -3.528f, -1.105f, + 3.828f, 10.224f, 14.324f, 15.900f, 17.285f, 18.794f, 20.200f, 20.767f, 21.427f, + 28.277f, 36.732f, 40.563f, 43.305f, 44.194f, 44.901f, 45.637f, 46.410f, 47.290f, + 47.361f, 48.600f, 49.214f, 49.628f, 50.213f, 50.128f, 50.619f, 50.929f, 51.144f, + 52.530f, 54.244f, 52.632f, 51.054f, 49.516f, 45.909f, 42.257f, 38.889f, 35.070f, + 33.325f, 31.301f, 29.342f, 26.801f, 25.594f, 25.387f, 24.311f, 22.785f, 22.056f, + 21.911f, 20.382f, 19.844f, 19.487f, 18.112f, 16.729f, 16.481f, 16.342f, 15.522f, + 14.890f, 14.324f, 12.943f, 12.380f, 11.963f, 9.019f, 8.892f, 8.276f, 7.038f, + 6.490f, 5.504f, 4.455f, 3.866f, 1.559f, -0.967f, -2.487f, -3.343f, -4.062f, + -3.864f, -4.971f, -6.394f, -4.933f, -8.501f, -8.935f, -9.056f, -8.158f, -9.872f, + -10.693f, -11.856f, -12.621f, -13.030f, -12.366f, -11.597f, -10.885f, -9.629f, -8.270f, + -6.931f, -5.335f, -3.295f, -1.567f, 0.176f, -4.982f, -5.295f, 5.600f, 2.143f, + 3.985f, 1.729f, 0.557f, 1.524f, 0.921f, 0.510f, 0.052f, 3.537f, 5.337f, + 4.989f, 3.684f, 4.845f, 5.191f, 5.571f, 5.665f, 4.086f, 2.766f, 2.352f, + 2.437f, 1.478f, 1.173f, 1.789f, 1.305f, 2.294f, 3.448f, 2.968f, 4.222f, + 3.986f, 4.131f, 4.888f, 5.992f, 7.687f, 8.969f, 10.278f, 11.190f, 12.868f, + 13.606f}, + {-29.534f, -30.089f, -29.785f, -31.622f, -33.361f, -36.775f, -44.126f, -45.188f, -47.687f, + -50.075f, -52.608f, -54.426f, -56.082f, -57.905f, -59.737f, -61.530f, -61.355f, -60.938f, + -61.764f, -60.824f, -61.886f, -61.002f, -58.358f, -57.674f, -54.955f, -51.524f, -50.615f, + -49.787f, -48.909f, -47.660f, -46.305f, -44.608f, -42.718f, -40.197f, -37.167f, -34.086f, + -31.151f, -27.997f, -24.654f, -20.999f, -16.589f, -9.612f, -4.896f, -4.735f, -1.921f, + 3.240f, 10.247f, 13.704f, 15.302f, 18.896f, 20.541f, 21.633f, 20.806f, 19.643f, + 23.158f, 28.442f, 36.892f, 42.507f, 44.204f, 46.172f, 47.528f, 47.515f, 47.799f, + 48.063f, 49.055f, 49.760f, 50.457f, 50.481f, 50.471f, 50.179f, 49.744f, 50.512f, + 50.025f, 51.434f, 51.589f, 49.128f, 47.459f, 41.152f, 42.816f, 39.243f, 35.210f, + 31.891f, 28.605f, 26.724f, 26.036f, 24.356f, 23.801f, 23.029f, 21.880f, 20.980f, + 21.153f, 19.198f, 19.200f, 18.749f, 17.086f, 16.106f, 15.587f, 15.584f, 14.686f, + 13.509f, 12.684f, 12.248f, 10.808f, 9.945f, 9.262f, 8.807f, 7.321f, 6.885f, + 6.085f, 5.387f, 4.001f, 2.642f, 1.378f, -0.938f, -2.130f, -2.742f, -3.811f, + -4.365f, -5.170f, -5.251f, -7.504f, -8.125f, -9.128f, -9.421f, -9.612f, -10.142f, + -11.171f, -12.042f, -12.516f, -12.747f, -12.520f, -11.692f, -11.195f, -9.689f, -7.974f, + -6.432f, -4.947f, -2.748f, -1.045f, 0.356f, -5.705f, -7.689f, 3.969f, 4.946f, + 4.928f, -0.694f, 1.682f, 1.847f, 1.550f, 0.625f, 0.445f, 4.645f, 4.519f, + 4.329f, 3.863f, 4.744f, 4.960f, 4.990f, 4.952f, 3.662f, 2.600f, 2.522f, + 2.154f, 1.519f, 1.252f, 1.845f, 1.546f, 2.211f, 3.267f, 3.097f, 4.410f, + 4.058f, 4.186f, 5.041f, 6.156f, 7.842f, 9.013f, 10.335f, 11.198f, 12.867f, + 13.606f}, + {-29.534f, -30.078f, -29.674f, -31.578f, -33.495f, -37.793f, -44.815f, -45.389f, -47.800f, + -50.331f, -52.674f, -54.640f, -56.428f, -58.302f, -59.902f, -61.638f, -62.204f, -61.320f, + -61.638f, -60.988f, -62.411f, -60.607f, -58.880f, -58.164f, -54.190f, -51.468f, -50.530f, + -49.572f, -48.843f, -47.367f, -46.116f, -44.457f, -42.736f, -40.114f, -37.378f, -34.563f, + -31.530f, -28.321f, -24.912f, -21.240f, -16.843f, -11.736f, -7.830f, -6.526f, -2.800f, + 3.010f, 9.792f, 13.205f, 14.670f, 18.282f, 20.184f, 22.077f, 22.742f, 21.401f, + 17.004f, 18.289f, 24.092f, 34.707f, 41.390f, 45.056f, 46.256f, 47.331f, 48.852f, + 49.893f, 50.516f, 51.343f, 51.871f, 52.193f, 52.094f, 51.775f, 50.906f, 50.300f, + 50.569f, 50.438f, 49.163f, 47.849f, 46.052f, 43.763f, 40.850f, 37.798f, 33.142f, + 29.368f, 27.062f, 25.180f, 23.810f, 22.789f, 21.709f, 21.359f, 20.611f, 20.329f, + 20.051f, 19.886f, 19.033f, 18.304f, 16.952f, 16.129f, 15.757f, 15.028f, 13.982f, + 12.755f, 12.035f, 11.075f, 10.446f, 10.402f, 9.678f, 8.730f, 7.428f, 6.750f, + 6.046f, 5.198f, 4.543f, 2.487f, 1.412f, -1.053f, -1.554f, -2.078f, -3.160f, + -4.521f, -4.288f, -2.969f, -8.148f, -8.576f, -9.521f, -9.678f, -10.343f, -10.287f, + -11.297f, -11.909f, -12.426f, -12.229f, -12.795f, -11.905f, -11.496f, -9.525f, -7.787f, + -6.278f, -4.427f, -2.580f, -0.492f, 0.885f, -5.800f, -5.778f, 2.409f, 1.649f, + -0.115f, 1.031f, 1.959f, 2.134f, 0.858f, 0.796f, 2.698f, 4.167f, 4.562f, + 4.534f, 4.197f, 4.414f, 4.354f, 4.613f, 4.211f, 3.147f, 2.377f, 2.472f, + 1.929f, 1.566f, 1.386f, 1.840f, 1.811f, 2.129f, 2.814f, 3.335f, 4.493f, + 4.072f, 4.256f, 5.137f, 6.326f, 8.004f, 9.076f, 10.388f, 11.198f, 12.867f, + 13.606f}, + {-29.534f, -30.066f, -29.565f, -31.554f, -33.631f, -38.682f, -45.285f, -45.565f, -47.973f, + -50.566f, -52.694f, -54.873f, -56.717f, -58.464f, -60.033f, -61.882f, -62.829f, -62.030f, + -61.695f, -62.038f, -63.207f, -61.041f, -60.115f, -58.732f, -53.500f, -51.445f, -50.339f, + -49.232f, -48.644f, -47.156f, -45.771f, -44.474f, -42.520f, -39.970f, -37.520f, -34.669f, + -31.569f, -28.526f, -25.335f, -21.125f, -16.900f, -14.017f, -11.253f, -8.230f, -3.683f, + 2.668f, 9.260f, 12.435f, 13.731f, 16.598f, 18.614f, 20.858f, 23.001f, 23.105f, + 21.553f, 19.917f, 17.699f, 18.264f, 23.321f, 32.668f, 39.853f, 45.525f, 47.804f, + 49.082f, 49.972f, 51.229f, 51.573f, 51.809f, 52.155f, 51.999f, 51.396f, 50.604f, + 49.610f, 48.535f, 47.513f, 46.354f, 44.478f, 41.405f, 39.176f, 33.678f, 31.217f, + 28.531f, 26.149f, 23.868f, 22.456f, 21.480f, 20.587f, 20.163f, 19.700f, 20.124f, + 19.691f, 19.297f, 18.784f, 17.888f, 16.224f, 15.839f, 16.172f, 14.750f, 13.463f, + 12.675f, 11.962f, 10.904f, 10.955f, 10.973f, 9.761f, 8.461f, 7.604f, 5.948f, + 6.030f, 5.316f, 4.224f, 2.170f, 0.910f, -0.436f, -0.509f, -1.107f, -2.639f, + -3.588f, -0.311f, -5.086f, -8.315f, -8.414f, -9.031f, -10.187f, -9.387f, -10.168f, + -11.366f, -12.397f, -12.620f, -12.636f, -12.274f, -12.097f, -11.440f, -9.264f, -7.725f, + -5.691f, -3.814f, -1.977f, -0.003f, 1.249f, -4.903f, -7.282f, 3.862f, 1.955f, + 1.941f, 2.232f, 2.868f, 2.160f, 1.159f, 4.494f, 4.522f, 3.681f, 4.289f, + 4.586f, 4.351f, 4.325f, 4.248f, 4.205f, 3.594f, 2.601f, 2.090f, 2.001f, + 1.482f, 1.564f, 1.507f, 1.829f, 1.587f, 2.058f, 2.422f, 3.586f, 4.451f, + 4.035f, 4.328f, 5.168f, 6.487f, 8.163f, 9.159f, 10.435f, 11.194f, 12.866f, + 13.606f}, + {-29.534f, -30.056f, -29.459f, -31.549f, -33.762f, -39.336f, -45.478f, -45.708f, -48.180f, + -50.700f, -52.681f, -55.005f, -56.970f, -58.483f, -60.205f, -62.525f, -63.402f, -62.894f, + -62.362f, -63.491f, -63.684f, -62.190f, -60.880f, -58.374f, -53.432f, -51.504f, -50.151f, + -48.972f, -48.280f, -47.018f, -45.385f, -44.231f, -42.298f, -39.627f, -37.263f, -34.661f, + -31.423f, -28.477f, -25.532f, -21.404f, -15.304f, -15.018f, -11.921f, -8.375f, -3.767f, + 2.574f, 9.780f, 11.796f, 12.713f, 14.966f, 16.883f, 19.399f, 21.741f, 23.125f, + 24.052f, 24.725f, 24.700f, 23.690f, 20.297f, 19.095f, 26.232f, 34.582f, 40.900f, + 44.898f, 47.367f, 49.680f, 51.065f, 52.145f, 52.918f, 52.593f, 51.484f, 50.602f, + 49.104f, 47.759f, 46.284f, 45.058f, 43.098f, 36.420f, 34.992f, 32.639f, 29.722f, + 27.150f, 24.807f, 22.371f, 21.178f, 20.499f, 19.698f, 19.895f, 19.261f, 18.597f, + 18.746f, 19.359f, 18.039f, 16.959f, 16.171f, 15.934f, 15.750f, 15.335f, 13.131f, + 11.898f, 11.327f, 11.086f, 11.313f, 10.988f, 9.523f, 8.665f, 7.557f, 7.028f, + 6.506f, 5.317f, 3.657f, 1.831f, 1.352f, 0.614f, -0.108f, -0.930f, -2.336f, + -1.111f, -1.781f, -5.795f, -7.771f, -8.213f, -9.055f, -10.405f, -10.498f, -9.755f, + -11.772f, -12.699f, -12.988f, -12.915f, -12.583f, -11.875f, -10.853f, -9.212f, -7.494f, + -5.638f, -3.278f, -1.408f, 0.539f, 1.822f, -3.818f, -8.140f, 5.068f, 2.385f, + 2.764f, 3.348f, 2.843f, 2.544f, 1.696f, 6.029f, 4.553f, 3.821f, 4.718f, + 4.166f, 4.644f, 4.597f, 4.123f, 3.627f, 2.983f, 2.076f, 1.525f, 1.419f, + 0.943f, 1.243f, 1.537f, 1.894f, 0.723f, 1.870f, 2.272f, 3.669f, 4.258f, + 3.945f, 4.374f, 5.142f, 6.632f, 8.309f, 9.260f, 10.475f, 11.184f, 12.867f, + 13.606f}, + {-29.534f, -30.046f, -29.357f, -31.558f, -33.886f, -39.704f, -45.410f, -45.824f, -48.399f, + -50.724f, -52.647f, -54.936f, -57.101f, -58.436f, -60.165f, -63.160f, -64.200f, -63.637f, + -63.281f, -64.413f, -63.784f, -62.678f, -61.475f, -57.661f, -53.565f, -51.454f, -49.832f, + -48.840f, -47.931f, -46.511f, -44.893f, -43.514f, -42.018f, -39.447f, -37.139f, -34.552f, + -31.397f, -28.566f, -25.658f, -22.090f, -17.320f, -15.919f, -12.525f, -9.064f, -4.019f, + 1.443f, 9.231f, 10.307f, 11.304f, 13.030f, 15.151f, 17.231f, 20.439f, 22.378f, + 24.102f, 26.083f, 27.338f, 27.961f, 28.352f, 27.754f, 24.655f, 23.098f, 24.847f, + 29.076f, 33.646f, 39.276f, 44.552f, 51.026f, 52.418f, 52.880f, 52.089f, 50.614f, + 48.947f, 47.067f, 45.111f, 43.716f, 38.267f, 36.288f, 33.987f, 30.811f, 28.515f, + 25.662f, 23.589f, 21.204f, 20.174f, 19.577f, 19.038f, 18.959f, 18.717f, 18.842f, + 18.712f, 17.902f, 17.579f, 17.065f, 17.035f, 15.802f, 14.660f, 13.751f, 12.141f, + 10.638f, 10.360f, 10.749f, 10.891f, 10.075f, 9.224f, 8.196f, 7.739f, 7.026f, + 8.257f, 6.186f, 4.340f, 3.233f, 1.972f, 1.492f, 0.444f, -0.571f, -2.315f, + -1.196f, 0.612f, -5.372f, -7.250f, -8.131f, -9.641f, -10.413f, -9.993f, -10.410f, + -11.631f, -12.464f, -12.582f, -12.877f, -12.484f, -11.689f, -10.648f, -9.002f, -7.067f, + -5.195f, -2.934f, -0.867f, 0.780f, 1.840f, -2.420f, -9.649f, 6.880f, 3.174f, + 3.746f, 3.998f, 2.967f, 2.832f, 4.008f, 6.361f, 5.089f, 4.906f, 5.023f, + 4.717f, 4.598f, 4.797f, 3.782f, 2.901f, 2.322f, 1.507f, 0.838f, 1.018f, + 0.514f, 0.591f, 1.466f, 2.053f, -0.241f, 1.508f, 2.316f, 3.512f, 3.933f, + 3.800f, 4.370f, 5.075f, 6.758f, 8.439f, 9.375f, 10.507f, 11.172f, 12.867f, + 13.606f}, + {-29.534f, -30.037f, -29.258f, -31.576f, -34.002f, -39.797f, -45.157f, -45.935f, -48.617f, + -50.703f, -52.619f, -54.755f, -57.009f, -58.294f, -59.765f, -63.288f, -64.893f, -64.221f, + -64.124f, -64.838f, -63.942f, -62.563f, -61.901f, -56.999f, -53.675f, -51.383f, -49.700f, + -48.655f, -47.600f, -46.128f, -44.577f, -43.128f, -41.746f, -39.442f, -36.997f, -34.353f, + -31.372f, -28.703f, -25.836f, -22.595f, -19.481f, -16.443f, -12.901f, -9.456f, -4.527f, + -0.111f, 6.369f, 8.742f, 10.213f, 11.601f, 12.796f, 15.554f, 18.099f, 20.216f, + 22.874f, 25.442f, 27.256f, 28.482f, 30.204f, 30.975f, 30.738f, 30.494f, 30.033f, + 30.521f, 31.799f, 28.172f, 24.212f, 29.268f, 43.869f, 52.254f, 51.967f, 49.716f, + 48.360f, 46.343f, 44.143f, 41.801f, 35.763f, 33.708f, 31.177f, 29.358f, 27.422f, + 24.521f, 22.190f, 20.685f, 19.179f, 18.823f, 18.714f, 18.782f, 19.481f, 16.950f, + 17.599f, 17.187f, 17.044f, 16.434f, 16.140f, 14.531f, 12.973f, 11.420f, 10.407f, + 10.151f, 10.259f, 11.260f, 10.683f, 9.706f, 8.894f, 7.924f, 7.633f, 7.644f, + 9.300f, 6.776f, 4.718f, 3.829f, 2.697f, 1.946f, 1.504f, -0.014f, -0.666f, + -3.475f, -3.566f, -6.017f, -7.500f, -8.304f, -9.635f, -9.984f, -11.248f, -12.160f, + -12.229f, -12.887f, -12.696f, -12.790f, -12.276f, -11.288f, -10.454f, -9.011f, -6.467f, + -4.718f, -2.722f, -0.587f, 1.296f, 2.694f, -0.537f, -10.810f, 7.631f, 3.260f, + 4.270f, 4.870f, 3.153f, 2.315f, 4.236f, 6.669f, 6.177f, 6.104f, 5.595f, + 5.136f, 4.779f, 4.712f, 3.610f, 2.318f, 1.757f, 1.057f, 0.483f, 0.847f, + 0.186f, 0.055f, 1.411f, 2.266f, -0.612f, 1.081f, 2.379f, 3.223f, 3.546f, + 3.611f, 4.306f, 4.988f, 6.868f, 8.553f, 9.496f, 10.531f, 11.159f, 12.868f, + 13.606f}, + {-29.534f, -30.029f, -29.163f, -31.596f, -34.114f, -39.683f, -44.829f, -46.058f, -48.824f, + -50.721f, -52.629f, -54.671f, -56.731f, -58.073f, -59.315f, -63.068f, -64.970f, -64.843f, + -65.098f, -65.021f, -63.929f, -62.671f, -61.307f, -56.349f, -53.688f, -51.285f, -49.583f, + -48.406f, -47.114f, -45.755f, -44.411f, -42.949f, -41.471f, -39.271f, -36.774f, -33.918f, + -31.124f, -28.313f, -25.720f, -22.692f, -19.764f, -16.427f, -13.083f, -9.748f, -5.326f, + -1.450f, 3.251f, 6.650f, 8.543f, 10.171f, 10.559f, 12.990f, 15.811f, 18.427f, + 20.773f, 23.436f, 25.633f, 27.211f, 28.565f, 29.413f, 30.521f, 31.478f, 35.302f, + 33.612f, 33.889f, 33.784f, 31.900f, 27.751f, 25.581f, 35.159f, 43.059f, 46.825f, + 46.773f, 45.278f, 42.253f, 37.978f, 32.306f, 31.888f, 30.541f, 27.966f, 27.291f, + 24.337f, 21.117f, 20.129f, 19.396f, 18.257f, 18.157f, 18.001f, 17.454f, 17.191f, + 17.179f, 16.540f, 15.918f, 15.928f, 14.760f, 13.185f, 12.447f, 11.294f, 10.004f, + 9.852f, 10.373f, 10.810f, 10.461f, 9.573f, 8.786f, 8.316f, 7.574f, 7.922f, + 8.930f, 8.277f, 5.877f, 5.021f, 4.161f, 3.460f, 1.778f, 0.807f, 6.091f, + -3.368f, -4.704f, -4.117f, -6.412f, -8.228f, -9.160f, -10.681f, -11.920f, -12.462f, + -13.027f, -12.960f, -12.744f, -12.532f, -11.958f, -11.204f, -10.039f, -8.375f, -5.967f, + -4.308f, -2.417f, 0.073f, 1.950f, 3.560f, 1.488f, -10.883f, 7.249f, 4.512f, + 4.922f, 5.264f, 3.368f, 5.277f, 7.250f, 7.675f, 7.217f, 6.442f, 6.047f, + 5.087f, 4.886f, 4.594f, 3.360f, 2.044f, 1.305f, 0.801f, 0.563f, 0.854f, + 0.072f, -0.083f, 1.437f, 2.494f, -0.312f, 0.733f, 2.333f, 2.976f, 3.182f, + 3.408f, 4.194f, 4.903f, 6.967f, 8.653f, 9.617f, 10.547f, 11.145f, 12.869f, + 13.606f}, + {-29.534f, -30.021f, -29.072f, -31.613f, -34.224f, -39.464f, -44.533f, -46.197f, -49.009f, + -50.822f, -52.679f, -54.792f, -56.453f, -57.896f, -59.193f, -63.019f, -64.707f, -65.444f, + -65.999f, -64.752f, -63.578f, -62.530f, -60.054f, -56.213f, -53.607f, -51.215f, -49.378f, + -47.971f, -46.571f, -45.399f, -44.276f, -42.662f, -41.198f, -39.021f, -36.163f, -33.524f, + -30.781f, -28.177f, -25.308f, -22.189f, -19.180f, -16.484f, -13.491f, -9.827f, -6.301f, + -3.012f, 1.282f, 4.316f, 7.167f, 7.309f, 9.340f, 11.647f, 14.216f, 16.886f, + 19.476f, 21.496f, 23.328f, 24.276f, 25.445f, 28.040f, 30.297f, 31.220f, 31.753f, + 32.529f, 33.530f, 33.650f, 32.711f, 31.212f, 29.865f, 26.933f, 24.113f, 25.508f, + 33.445f, 36.399f, 34.319f, 26.791f, 31.479f, 29.163f, 27.392f, 27.403f, 26.385f, + 23.511f, 21.440f, 18.840f, 17.900f, 17.942f, 18.228f, 17.997f, 17.491f, 17.012f, + 16.337f, 15.591f, 15.364f, 14.863f, 13.970f, 13.030f, 11.417f, 10.632f, 10.259f, + 9.948f, 9.939f, 10.448f, 11.337f, 10.189f, 8.875f, 8.430f, 7.657f, 8.268f, + 8.311f, 8.792f, 7.782f, 5.857f, 5.439f, 4.316f, 2.856f, 0.489f, 2.433f, + -2.762f, -2.896f, -4.252f, -6.323f, -8.015f, -9.610f, -10.991f, -12.137f, -12.770f, + -13.209f, -13.088f, -12.945f, -12.380f, -11.668f, -10.795f, -9.383f, -7.637f, -5.967f, + -3.904f, -1.781f, 0.468f, 2.555f, 4.062f, 2.041f, -9.613f, 6.050f, 6.463f, + 5.859f, 6.310f, 3.951f, 9.853f, 9.223f, 8.416f, 7.289f, 6.905f, 6.161f, + 5.404f, 4.602f, 4.446f, 3.446f, 2.103f, 1.081f, 0.681f, 0.879f, 0.960f, + 0.194f, -0.096f, 1.469f, 2.700f, 0.135f, 0.554f, 2.198f, 2.836f, 2.899f, + 3.232f, 4.064f, 4.840f, 7.057f, 8.747f, 9.728f, 10.556f, 11.133f, 12.871f, + 13.606f}, + {-29.534f, -30.015f, -28.986f, -31.622f, -34.338f, -39.252f, -44.342f, -46.338f, -49.151f, + -50.977f, -52.721f, -54.990f, -56.366f, -57.859f, -59.337f, -63.188f, -64.873f, -65.725f, + -66.291f, -64.472f, -63.259f, -61.839f, -58.970f, -56.108f, -53.521f, -51.051f, -49.114f, + -47.372f, -46.086f, -45.181f, -43.639f, -42.394f, -40.867f, -38.504f, -35.642f, -33.152f, + -30.630f, -27.938f, -24.689f, -21.603f, -18.938f, -16.573f, -13.552f, -10.329f, -7.432f, + -4.076f, -0.231f, 2.619f, 5.305f, 6.300f, 8.195f, 10.986f, 13.284f, 15.466f, + 17.876f, 19.630f, 20.789f, 22.706f, 24.469f, 26.409f, 26.626f, 28.495f, 29.799f, + 30.593f, 31.393f, 31.183f, 30.775f, 30.335f, 30.265f, 29.614f, 28.978f, 29.178f, + 25.923f, 23.597f, 22.275f, 26.920f, 33.265f, 27.730f, 26.498f, 26.326f, 24.513f, + 22.927f, 20.418f, 19.524f, 18.749f, 18.350f, 17.949f, 18.014f, 16.513f, 16.124f, + 15.212f, 14.987f, 14.793f, 13.853f, 13.632f, 13.061f, 12.013f, 11.155f, 10.756f, + 10.518f, 10.509f, 10.598f, 10.651f, 9.593f, 9.391f, 8.387f, 8.344f, 9.095f, + 8.895f, 8.262f, 8.195f, 6.903f, 6.194f, 5.236f, 3.522f, 4.631f, 4.801f, + -1.468f, -1.821f, -3.202f, -5.673f, -7.825f, -9.610f, -11.046f, -12.254f, -12.947f, + -13.218f, -12.942f, -12.589f, -11.986f, -11.523f, -10.544f, -8.952f, -6.968f, -5.681f, + -3.920f, -1.714f, 0.516f, 3.273f, 4.999f, 3.335f, -7.320f, 6.053f, 8.421f, + 6.925f, 6.495f, 4.728f, 11.218f, 9.458f, 9.036f, 8.164f, 7.193f, 6.257f, + 5.695f, 4.994f, 3.963f, 3.877f, 2.375f, 0.955f, 0.684f, 1.138f, 1.153f, + 0.257f, -0.254f, 1.542f, 2.830f, 0.341f, 0.619f, 2.131f, 2.731f, 2.719f, + 3.116f, 3.950f, 4.813f, 7.142f, 8.841f, 9.826f, 10.561f, 11.123f, 12.873f, + 13.606f}, + {-29.534f, -30.009f, -28.905f, -31.618f, -34.458f, -39.141f, -44.283f, -46.455f, -49.231f, + -51.111f, -52.698f, -55.045f, -56.500f, -57.925f, -59.440f, -63.206f, -65.518f, -65.729f, + -66.119f, -64.949f, -63.127f, -61.342f, -58.277f, -55.775f, -53.298f, -50.867f, -48.759f, + -46.899f, -45.540f, -44.776f, -43.148f, -41.904f, -40.459f, -37.896f, -35.136f, -32.770f, + -30.308f, -27.553f, -24.216f, -21.203f, -18.718f, -16.423f, -13.715f, -10.806f, -8.170f, + -5.132f, -2.080f, 1.941f, 4.240f, 5.450f, 6.892f, 9.932f, 12.820f, 14.884f, + 16.259f, 18.611f, 19.637f, 20.222f, 21.036f, 22.826f, 24.615f, 26.307f, 27.352f, + 27.955f, 27.727f, 27.596f, 27.728f, 27.858f, 28.108f, 28.229f, 28.912f, 29.072f, + 29.433f, 28.365f, 28.428f, 28.697f, 29.815f, 25.177f, 24.622f, 24.034f, 22.434f, + 21.643f, 20.273f, 19.120f, 17.557f, 17.163f, 17.773f, 17.359f, 15.771f, 15.832f, + 15.189f, 14.651f, 13.859f, 14.009f, 13.870f, 12.785f, 11.642f, 10.985f, 10.841f, + 11.135f, 11.793f, 10.475f, 10.356f, 9.598f, 9.004f, 9.270f, 8.676f, 9.331f, + 8.588f, 9.840f, 9.279f, 7.669f, 7.284f, 6.489f, 4.110f, 5.554f, 5.704f, + -0.605f, -0.747f, -2.764f, -5.348f, -7.858f, -9.777f, -11.160f, -12.478f, -13.062f, + -13.560f, -12.939f, -12.294f, -11.667f, -11.078f, -10.227f, -8.793f, -7.184f, -5.663f, + -3.601f, -1.309f, 1.003f, 3.596f, 5.592f, 4.840f, -4.679f, 3.450f, 10.150f, + 8.316f, 7.410f, 7.620f, 11.356f, 10.182f, 9.477f, 8.747f, 7.391f, 6.412f, + 6.084f, 5.477f, 4.115f, 3.868f, 2.438f, 0.690f, 0.849f, 1.055f, 1.417f, + 0.217f, -0.371f, 1.857f, 2.834f, 0.449f, 0.985f, 2.297f, 2.577f, 2.649f, + 3.064f, 3.876f, 4.828f, 7.219f, 8.939f, 9.904f, 10.563f, 11.118f, 12.875f, + 13.606f}, + {-29.534f, -30.005f, -28.829f, -31.598f, -34.587f, -39.192f, -44.336f, -46.519f, -49.242f, + -51.150f, -52.602f, -54.892f, -56.715f, -58.013f, -59.405f, -63.038f, -65.854f, -65.749f, + -65.872f, -65.538f, -63.204f, -60.985f, -57.902f, -55.634f, -52.996f, -50.710f, -48.429f, + -46.582f, -45.121f, -44.014f, -42.861f, -41.461f, -39.773f, -37.264f, -34.807f, -32.329f, + -29.699f, -26.950f, -23.846f, -20.977f, -18.710f, -16.326f, -13.875f, -11.463f, -8.669f, + -6.067f, -3.511f, 0.441f, 2.600f, 4.134f, 6.166f, 8.700f, 11.071f, 14.432f, + 16.238f, 17.194f, 17.223f, 18.921f, 19.963f, 21.450f, 22.536f, 23.337f, 24.443f, + 24.625f, 24.667f, 24.702f, 24.721f, 25.010f, 25.567f, 25.861f, 26.208f, 28.909f, + 27.200f, 27.420f, 26.158f, 26.001f, 29.363f, 24.284f, 23.012f, 21.939f, 21.455f, + 20.264f, 18.884f, 17.746f, 17.325f, 16.757f, 16.168f, 16.059f, 16.149f, 15.743f, + 15.218f, 14.552f, 13.856f, 13.629f, 13.083f, 12.233f, 11.619f, 11.123f, 11.454f, + 11.134f, 11.679f, 12.389f, 10.765f, 9.649f, 10.241f, 8.084f, 9.648f, 9.772f, + 8.994f, 9.376f, 8.965f, 8.268f, 7.889f, 6.980f, 4.451f, 7.464f, 3.034f, + 1.034f, -0.464f, -2.532f, -5.337f, -8.078f, -9.898f, -11.280f, -12.671f, -13.334f, + -13.566f, -12.824f, -12.256f, -11.590f, -10.896f, -10.157f, -8.684f, -7.109f, -5.258f, + -3.296f, -0.917f, 1.480f, 3.849f, 5.682f, 5.494f, -1.535f, 1.591f, 12.526f, + 9.878f, 9.224f, 9.670f, 11.759f, 10.607f, 10.141f, 9.151f, 7.938f, 6.530f, + 6.318f, 5.306f, 4.407f, 3.528f, 2.173f, 0.576f, 1.079f, 0.787f, 1.529f, + 0.319f, -0.285f, 2.392f, 2.674f, 0.729f, 1.556f, 2.721f, 2.408f, 2.677f, + 3.052f, 3.841f, 4.883f, 7.287f, 9.043f, 9.962f, 10.565f, 11.118f, 12.877f, + 13.606f}, + {-29.534f, -30.001f, -28.760f, -31.563f, -34.724f, -39.420f, -44.447f, -46.517f, -49.199f, + -51.072f, -52.492f, -54.708f, -56.820f, -58.104f, -59.287f, -63.046f, -65.498f, -65.753f, + -65.498f, -65.093f, -63.471f, -60.300f, -57.698f, -55.381f, -52.867f, -50.423f, -48.029f, + -46.129f, -44.709f, -43.412f, -42.550f, -41.085f, -39.040f, -36.683f, -34.449f, -31.844f, + -29.421f, -26.669f, -23.625f, -21.212f, -18.942f, -16.452f, -14.028f, -11.703f, -9.364f, + -6.824f, -4.233f, -0.709f, 1.620f, 4.322f, 5.962f, 7.767f, 11.886f, 12.791f, + 14.180f, 15.641f, 16.220f, 17.598f, 18.691f, 19.390f, 20.527f, 21.362f, 21.812f, + 21.516f, 21.544f, 21.770f, 22.188f, 22.643f, 22.887f, 22.938f, 23.238f, 24.748f, + 24.913f, 23.869f, 22.749f, 22.523f, 23.556f, 21.463f, 20.494f, 20.408f, 19.877f, + 18.856f, 17.923f, 16.583f, 16.775f, 16.807f, 16.640f, 16.367f, 16.419f, 14.855f, + 14.624f, 14.270f, 14.320f, 13.566f, 13.174f, 12.452f, 12.074f, 11.794f, 12.288f, + 11.642f, 11.979f, 11.787f, 11.546f, 10.420f, 10.513f, 9.681f, 9.901f, 9.702f, + 9.811f, 9.934f, 8.852f, 8.965f, 8.422f, 7.040f, 5.560f, 6.138f, 5.272f, + 1.695f, 0.366f, -2.379f, -5.507f, -8.036f, -10.020f, -11.366f, -12.507f, -13.247f, + -13.619f, -13.021f, -12.222f, -11.311f, -10.612f, -9.893f, -8.568f, -6.945f, -4.673f, + -2.906f, -0.752f, 1.341f, 3.903f, 5.965f, 6.550f, 2.120f, -2.052f, 13.938f, + 10.879f, 10.333f, 11.579f, 11.974f, 10.890f, 10.752f, 9.732f, 8.451f, 6.910f, + 6.529f, 5.281f, 4.308f, 3.665f, 1.995f, 0.599f, 1.046f, 0.756f, 1.306f, + 0.424f, -0.200f, 2.704f, 2.304f, 1.116f, 2.065f, 3.255f, 2.352f, 2.756f, + 3.042f, 3.830f, 4.967f, 7.346f, 9.151f, 9.998f, 10.569f, 11.124f, 12.879f, + 13.606f}, + {-29.534f, -29.999f, -28.696f, -31.514f, -34.867f, -39.795f, -44.557f, -46.458f, -49.132f, + -50.916f, -52.450f, -54.724f, -56.712f, -58.238f, -59.030f, -63.281f, -65.051f, -65.579f, + -65.140f, -64.146f, -63.427f, -59.741f, -57.625f, -55.194f, -52.756f, -50.305f, -47.732f, + -45.784f, -44.377f, -42.973f, -42.086f, -40.584f, -38.419f, -36.388f, -34.031f, -31.389f, + -29.104f, -26.353f, -23.836f, -21.275f, -18.805f, -16.403f, -14.033f, -11.918f, -9.621f, + -7.619f, -4.631f, -2.159f, 0.577f, 3.190f, 5.485f, 9.603f, 12.152f, 11.671f, + 13.666f, 14.462f, 15.522f, 15.907f, 16.718f, 17.480f, 18.629f, 19.169f, 19.191f, + 19.103f, 19.580f, 19.419f, 19.649f, 19.899f, 20.548f, 20.290f, 21.093f, 20.970f, + 21.162f, 20.172f, 19.884f, 19.891f, 19.473f, 19.341f, 18.350f, 18.546f, 18.306f, + 17.422f, 17.195f, 16.814f, 16.870f, 16.902f, 16.701f, 16.297f, 15.494f, 14.319f, + 14.752f, 14.425f, 13.939f, 13.678f, 13.630f, 13.114f, 12.844f, 12.165f, 12.251f, + 12.274f, 12.247f, 11.941f, 11.831f, 11.591f, 11.036f, 10.393f, 10.315f, 10.141f, + 8.766f, 8.979f, 9.479f, 9.188f, 8.918f, 6.557f, 7.289f, 14.278f, 4.606f, + 2.239f, 0.845f, -2.383f, -5.767f, -8.121f, -10.111f, -11.273f, -12.235f, -13.244f, + -13.850f, -13.003f, -12.203f, -11.409f, -10.830f, -10.027f, -8.577f, -6.906f, -4.545f, + -2.735f, -0.394f, 2.038f, 4.099f, 6.167f, 7.376f, 5.491f, -2.751f, 13.531f, + 12.593f, 12.166f, 12.796f, 12.168f, 11.525f, 11.455f, 10.493f, 9.223f, 7.745f, + 6.664f, 5.250f, 4.882f, 4.071f, 2.074f, 0.577f, 0.867f, 0.936f, 0.907f, + 0.247f, -0.249f, 2.412f, 1.742f, 1.371f, 2.317f, 3.686f, 2.487f, 2.791f, + 3.005f, 3.816f, 5.064f, 7.400f, 9.260f, 10.014f, 10.577f, 11.137f, 12.882f, + 13.606f}, + {-29.534f, -29.997f, -28.640f, -31.456f, -35.014f, -40.257f, -44.617f, -46.369f, -49.072f, + -50.748f, -52.505f, -54.955f, -56.436f, -58.442f, -58.685f, -63.369f, -65.128f, -65.410f, + -65.138f, -63.899f, -62.770f, -59.617f, -57.513f, -55.164f, -52.481f, -50.166f, -47.581f, + -45.368f, -43.936f, -42.785f, -41.450f, -39.778f, -37.869f, -36.017f, -33.201f, -31.032f, + -28.856f, -26.153f, -23.840f, -21.147f, -18.581f, -16.099f, -14.109f, -12.078f, -10.253f, + -8.038f, -5.249f, -2.479f, 0.391f, 2.453f, 4.779f, 8.322f, 8.911f, 11.225f, + 12.189f, 12.918f, 13.615f, 14.353f, 15.034f, 15.682f, 16.451f, 17.089f, 17.196f, + 17.470f, 17.278f, 16.956f, 17.218f, 17.618f, 17.890f, 17.501f, 17.841f, 17.860f, + 17.657f, 17.385f, 17.031f, 17.225f, 17.016f, 17.043f, 16.895f, 16.836f, 17.248f, + 16.759f, 16.860f, 16.671f, 17.500f, 17.006f, 16.237f, 15.845f, 15.298f, 15.740f, + 14.615f, 14.283f, 13.999f, 13.909f, 13.498f, 13.117f, 13.183f, 13.278f, 12.805f, + 13.164f, 12.675f, 12.554f, 12.348f, 11.619f, 10.965f, 11.008f, 9.456f, 9.434f, + 9.083f, 8.656f, 8.974f, 9.694f, 8.804f, 6.073f, 12.246f, 7.444f, 3.026f, + 2.862f, 0.583f, -2.528f, -5.534f, -8.190f, -10.013f, -11.182f, -11.845f, -13.177f, + -13.821f, -13.117f, -12.355f, -11.676f, -10.894f, -9.816f, -8.199f, -6.886f, -4.742f, + -2.641f, -0.434f, 1.764f, 4.314f, 6.573f, 8.040f, 7.551f, -0.422f, 9.942f, + 15.037f, 13.905f, 12.973f, 12.983f, 12.043f, 11.807f, 11.396f, 9.913f, 8.485f, + 6.815f, 5.358f, 5.672f, 4.429f, 2.175f, 0.816f, 0.914f, 0.934f, 0.528f, + -0.010f, -0.274f, 1.664f, 1.136f, 1.460f, 2.394f, 3.887f, 2.733f, 2.672f, + 2.937f, 3.782f, 5.159f, 7.458f, 9.362f, 10.013f, 10.590f, 11.157f, 12.885f, + 13.606f}, + {-29.534f, -29.997f, -28.590f, -31.393f, -35.162f, -40.728f, -44.605f, -46.286f, -49.030f, + -50.619f, -52.612f, -55.151f, -56.149f, -58.689f, -58.708f, -63.232f, -65.443f, -65.406f, + -65.165f, -64.068f, -62.015f, -59.576f, -57.319f, -54.806f, -52.426f, -49.934f, -47.499f, + -44.868f, -43.321f, -42.407f, -40.845f, -39.322f, -37.409f, -35.312f, -32.635f, -30.871f, + -28.381f, -25.957f, -23.492f, -21.120f, -18.552f, -16.218f, -14.180f, -12.264f, -10.306f, + -8.317f, -5.548f, -2.583f, 0.061f, 2.349f, 5.946f, 5.897f, 8.078f, 9.967f, + 10.778f, 11.571f, 12.112f, 12.412f, 13.064f, 13.880f, 14.902f, 15.090f, 15.165f, + 15.176f, 15.192f, 15.218f, 15.470f, 15.699f, 15.442f, 15.548f, 15.811f, 15.822f, + 15.684f, 15.697f, 15.720f, 15.437f, 15.642f, 15.458f, 15.410f, 16.646f, 15.843f, + 15.944f, 16.576f, 16.845f, 16.701f, 16.819f, 16.847f, 15.783f, 15.229f, 14.891f, + 14.374f, 14.657f, 14.207f, 13.892f, 13.720f, 14.072f, 14.138f, 13.498f, 13.089f, + 13.434f, 13.280f, 13.343f, 12.370f, 11.692f, 11.208f, 9.788f, 9.576f, 9.011f, + 8.297f, 8.232f, 8.691f, 9.314f, 8.581f, 6.764f, 14.056f, 3.079f, 3.716f, + 2.688f, 0.220f, -2.802f, -5.694f, -8.060f, -9.946f, -11.025f, -11.999f, -13.084f, + -13.286f, -13.190f, -12.264f, -11.671f, -11.017f, -9.510f, -8.228f, -6.802f, -4.645f, + -2.510f, -0.525f, 1.851f, 4.357f, 6.663f, 8.493f, 8.771f, 2.441f, 3.704f, + 17.563f, 14.269f, 13.692f, 13.435f, 12.896f, 12.495f, 11.787f, 10.516f, 9.000f, + 7.167f, 5.890f, 6.309f, 4.894f, 2.235f, 1.145f, 0.899f, 0.628f, 0.165f, + -0.074f, -0.206f, 0.953f, 0.614f, 1.449f, 2.476f, 3.852f, 2.907f, 2.346f, + 2.853f, 3.725f, 5.242f, 7.531f, 9.453f, 9.998f, 10.610f, 11.184f, 12.889f, + 13.606f}, + {-29.534f, -29.997f, -28.548f, -31.332f, -35.311f, -41.138f, -44.525f, -46.238f, -48.995f, + -50.543f, -52.697f, -55.017f, -56.011f, -58.892f, -59.536f, -63.317f, -65.353f, -65.333f, + -64.767f, -63.800f, -61.656f, -59.360f, -57.113f, -54.418f, -52.427f, -49.729f, -47.223f, + -44.559f, -42.838f, -42.001f, -40.405f, -38.815f, -36.816f, -34.662f, -32.251f, -30.497f, + -28.039f, -25.550f, -23.185f, -21.094f, -18.356f, -16.107f, -14.155f, -11.956f, -10.482f, + -8.553f, -5.608f, -2.705f, -0.937f, 3.910f, 2.689f, 5.801f, 7.188f, 8.161f, + 9.398f, 10.354f, 10.586f, 11.160f, 11.658f, 12.136f, 13.523f, 13.599f, 13.397f, + 13.375f, 13.557f, 13.805f, 14.182f, 14.142f, 13.642f, 14.107f, 14.545f, 13.548f, + 14.237f, 14.117f, 13.654f, 13.749f, 14.213f, 13.691f, 14.781f, 14.603f, 14.939f, + 15.204f, 16.291f, 16.234f, 16.103f, 16.966f, 17.106f, 15.492f, 15.030f, 14.487f, + 15.143f, 14.968f, 14.630f, 14.866f, 14.027f, 14.465f, 14.240f, 14.011f, 13.103f, + 13.314f, 14.819f, 13.063f, 11.845f, 11.122f, 10.022f, 9.560f, 9.252f, 8.348f, + 7.707f, 7.984f, 8.613f, 9.156f, 8.676f, 8.382f, 9.571f, 3.933f, 4.162f, + 2.581f, -0.223f, -3.281f, -5.973f, -8.320f, -9.728f, -10.927f, -12.115f, -13.120f, + -13.099f, -12.961f, -12.175f, -11.606f, -11.350f, -9.948f, -8.613f, -7.189f, -4.850f, + -2.798f, -0.541f, 1.805f, 4.186f, 6.646f, 8.610f, 9.708f, 5.775f, 0.037f, + 17.655f, 15.527f, 14.288f, 14.052f, 13.610f, 12.832f, 11.887f, 10.994f, 9.666f, + 7.774f, 6.395f, 6.706f, 5.090f, 2.521f, 1.372f, 0.831f, 0.296f, -0.104f, + -0.038f, -0.156f, 0.575f, 0.113f, 1.182f, 2.519f, 3.627f, 2.890f, 1.873f, + 2.765f, 3.661f, 5.310f, 7.629f, 9.527f, 9.972f, 10.637f, 11.219f, 12.892f, + 13.606f}, + {-29.534f, -29.999f, -28.514f, -31.281f, -35.459f, -41.436f, -44.406f, -46.234f, -48.942f, + -50.500f, -52.714f, -54.493f, -56.053f, -58.902f, -60.873f, -63.862f, -64.865f, -65.068f, + -64.309f, -63.343f, -61.659f, -59.038f, -56.649f, -54.276f, -52.141f, -49.484f, -46.981f, + -44.145f, -42.416f, -41.442f, -39.789f, -38.258f, -36.057f, -33.900f, -32.049f, -29.966f, + -27.679f, -25.186f, -23.088f, -20.930f, -18.355f, -15.838f, -14.004f, -12.017f, -10.648f, + -8.439f, -5.565f, -3.226f, 0.115f, 1.915f, 3.090f, 4.965f, 6.351f, 7.469f, + 8.507f, 9.004f, 9.270f, 9.995f, 10.819f, 11.424f, 11.776f, 11.729f, 12.185f, + 12.000f, 11.849f, 12.010f, 12.353f, 12.618f, 12.550f, 13.518f, 13.131f, 12.427f, + 13.297f, 12.081f, 12.392f, 12.892f, 12.806f, 13.316f, 14.439f, 14.766f, 15.501f, + 14.988f, 14.935f, 15.017f, 15.914f, 16.460f, 16.573f, 15.242f, 15.090f, 15.010f, + 15.902f, 15.114f, 15.291f, 14.817f, 14.947f, 15.261f, 15.251f, 14.404f, 14.538f, + 13.443f, 13.388f, 12.909f, 10.910f, 10.512f, 9.540f, 8.752f, 8.295f, 7.944f, + 7.741f, 7.864f, 8.757f, 9.080f, 8.335f, 10.019f, 6.925f, 3.983f, 3.646f, + 1.650f, -0.926f, -3.896f, -6.464f, -8.256f, -9.470f, -10.891f, -12.482f, -13.176f, + -13.332f, -13.222f, -12.245f, -11.906f, -11.453f, -10.466f, -8.845f, -7.512f, -5.238f, + -3.107f, -0.469f, 1.729f, 4.096f, 6.511f, 8.728f, 10.151f, 8.211f, 0.443f, + 16.218f, 16.533f, 14.706f, 14.568f, 14.098f, 13.422f, 12.096f, 11.329f, 10.394f, + 8.633f, 6.845f, 6.806f, 5.257f, 3.079f, 1.986f, 1.372f, 0.098f, -0.131f, + 0.080f, -0.180f, 0.413f, -0.484f, 0.444f, 2.295f, 3.252f, 2.723f, 1.398f, + 2.667f, 3.617f, 5.365f, 7.757f, 9.582f, 9.940f, 10.671f, 11.262f, 12.897f, + 13.606f}, + {-29.534f, -30.001f, -28.489f, -31.246f, -35.609f, -41.603f, -44.284f, -46.263f, -48.853f, + -50.461f, -52.677f, -53.809f, -56.132f, -58.597f, -61.891f, -64.425f, -64.530f, -64.853f, + -64.167f, -63.174f, -61.799f, -58.915f, -56.111f, -54.146f, -51.927f, -49.352f, -46.884f, + -43.816f, -42.178f, -40.745f, -39.186f, -37.487f, -35.212f, -33.257f, -31.310f, -29.515f, + -27.170f, -24.903f, -22.888f, -20.535f, -18.449f, -16.124f, -13.790f, -12.196f, -10.457f, + -8.303f, -5.456f, -3.323f, -0.136f, 0.374f, 2.640f, 4.197f, 5.185f, 6.096f, + 6.942f, 7.700f, 7.973f, 8.859f, 9.588f, 10.012f, 10.160f, 10.191f, 10.386f, + 10.224f, 10.104f, 10.416f, 11.134f, 11.797f, 12.162f, 12.284f, 12.307f, 11.637f, + 13.415f, 11.675f, 11.584f, 11.823f, 12.582f, 13.776f, 14.137f, 14.984f, 15.160f, + 14.781f, 14.564f, 14.406f, 14.876f, 16.287f, 15.604f, 15.178f, 14.959f, 14.825f, + 15.523f, 15.605f, 15.764f, 15.526f, 16.270f, 15.927f, 15.140f, 13.802f, 14.328f, + 13.743f, 12.890f, 11.766f, 10.254f, 9.543f, 8.505f, 8.041f, 7.627f, 6.987f, + 7.246f, 7.590f, 8.591f, 8.804f, 7.876f, 10.649f, 4.725f, 3.791f, 2.883f, + 1.110f, -1.526f, -4.470f, -6.811f, -8.498f, -8.932f, -11.209f, -12.867f, -13.612f, + -13.846f, -13.661f, -12.714f, -12.524f, -11.978f, -11.076f, -9.501f, -8.008f, -5.702f, + -3.171f, -0.315f, 1.855f, 3.897f, 6.234f, 8.430f, 10.431f, 9.685f, 2.178f, + 12.575f, 16.692f, 15.000f, 14.895f, 14.500f, 13.942f, 12.883f, 11.781f, 10.852f, + 9.546f, 7.453f, 7.198f, 5.577f, 3.599f, 2.890f, 2.435f, -0.156f, -0.080f, + 0.371f, -0.340f, 0.150f, -1.065f, -0.559f, 1.739f, 2.772f, 2.530f, 1.051f, + 2.535f, 3.614f, 5.410f, 7.908f, 9.621f, 9.904f, 10.710f, 11.310f, 12.902f, + 13.606f}, + {-29.534f, -30.005f, -28.473f, -31.233f, -35.765f, -41.651f, -44.193f, -46.300f, -48.732f, + -50.412f, -52.614f, -53.286f, -56.028f, -58.033f, -62.222f, -64.479f, -64.565f, -64.759f, + -64.000f, -62.969f, -61.818f, -59.012f, -55.793f, -53.885f, -51.821f, -49.234f, -46.553f, + -43.656f, -41.628f, -40.104f, -38.632f, -36.740f, -34.500f, -32.598f, -30.446f, -28.901f, + -26.635f, -24.520f, -22.451f, -20.296f, -18.047f, -16.145f, -13.918f, -12.233f, -10.367f, + -8.209f, -5.589f, -2.865f, -1.700f, 0.326f, 1.878f, 3.376f, 4.356f, 5.502f, + 6.011f, 6.322f, 6.940f, 7.666f, 8.268f, 8.380f, 8.551f, 8.644f, 8.736f, + 8.802f, 8.993f, 9.914f, 10.914f, 11.302f, 11.260f, 11.710f, 11.269f, 11.046f, + 11.498f, 11.322f, 10.670f, 10.509f, 11.718f, 13.173f, 14.438f, 14.682f, 13.987f, + 13.077f, 14.165f, 13.788f, 14.756f, 14.869f, 15.133f, 14.939f, 14.418f, 14.791f, + 15.915f, 15.846f, 15.321f, 16.396f, 16.865f, 15.882f, 15.860f, 14.896f, 13.795f, + 12.894f, 12.491f, 10.783f, 9.732f, 8.488f, 7.538f, 7.126f, 6.974f, 6.368f, + 6.597f, 7.277f, 8.253f, 8.088f, 7.397f, 12.384f, 4.865f, 3.786f, 2.673f, + 0.463f, -1.964f, -4.362f, -6.938f, -8.556f, -9.935f, -11.871f, -13.244f, -13.923f, + -14.287f, -14.204f, -13.358f, -13.027f, -12.278f, -11.100f, -9.981f, -8.090f, -5.871f, + -3.367f, -0.529f, 1.703f, 3.672f, 5.730f, 8.099f, 10.464f, 10.756f, 4.362f, + 8.328f, 17.346f, 15.273f, 15.056f, 15.326f, 14.884f, 13.431f, 12.261f, 11.345f, + 10.506f, 8.305f, 7.640f, 5.933f, 4.142f, 3.599f, 3.438f, -0.522f, -0.313f, + 0.578f, -0.638f, -0.436f, -1.400f, -1.244f, 1.095f, 2.239f, 2.350f, 0.866f, + 2.346f, 3.661f, 5.445f, 8.069f, 9.645f, 9.869f, 10.755f, 11.365f, 12.907f, + 13.606f}, + {-29.534f, -30.009f, -28.466f, -31.247f, -35.928f, -41.621f, -44.152f, -46.319f, -48.607f, + -50.360f, -52.531f, -53.087f, -55.636f, -57.439f, -62.307f, -64.127f, -64.655f, -64.559f, + -63.612f, -62.521f, -61.649f, -58.990f, -55.670f, -53.713f, -51.740f, -48.987f, -46.242f, + -43.322f, -41.344f, -39.621f, -37.890f, -35.961f, -33.880f, -31.969f, -29.983f, -28.068f, + -26.072f, -24.074f, -21.947f, -19.874f, -18.124f, -16.092f, -14.360f, -12.337f, -10.143f, + -8.006f, -4.111f, -3.856f, -2.175f, -0.595f, 1.188f, 2.940f, 4.321f, 4.897f, + 5.061f, 5.429f, 6.261f, 6.763f, 6.968f, 6.908f, 7.000f, 7.183f, 7.436f, + 7.465f, 8.307f, 9.048f, 9.712f, 9.943f, 10.848f, 10.909f, 10.228f, 10.461f, + 10.379f, 9.954f, 10.190f, 9.769f, 10.399f, 11.696f, 12.642f, 12.250f, 12.574f, + 12.305f, 12.390f, 13.133f, 14.275f, 14.340f, 14.254f, 14.566f, 14.688f, 15.267f, + 15.603f, 15.934f, 15.959f, 16.671f, 15.867f, 16.538f, 16.757f, 15.252f, 13.498f, + 12.845f, 11.141f, 9.932f, 9.100f, 7.712f, 6.545f, 6.223f, 5.860f, 6.277f, + 6.800f, 7.514f, 7.861f, 7.185f, 7.611f, 7.473f, 4.462f, 3.516f, 2.292f, + 0.278f, -2.505f, -5.553f, -7.932f, -9.469f, -10.672f, -12.526f, -13.693f, -14.339f, + -14.615f, -14.687f, -13.994f, -13.399f, -12.610f, -11.095f, -10.175f, -8.318f, -6.055f, + -3.878f, -1.179f, 1.128f, 3.291f, 5.446f, 7.644f, 10.350f, 11.341f, 6.671f, + 7.172f, 17.659f, 15.663f, 14.851f, 15.427f, 15.139f, 14.513f, 12.799f, 11.740f, + 11.028f, 9.233f, 8.024f, 6.423f, 4.754f, 4.065f, 4.099f, -0.742f, -0.846f, + 0.442f, -0.792f, -1.390f, -1.544f, -1.285f, 0.605f, 1.678f, 2.069f, 0.769f, + 2.111f, 3.744f, 5.467f, 8.219f, 9.662f, 9.836f, 10.804f, 11.426f, 12.913f, + 13.606f}, + {-29.534f, -30.015f, -28.468f, -31.290f, -36.102f, -41.567f, -44.169f, -46.310f, -48.511f, + -50.323f, -52.415f, -53.119f, -55.045f, -57.021f, -62.618f, -63.864f, -64.545f, -64.245f, + -63.299f, -62.189f, -61.418f, -58.785f, -55.927f, -53.806f, -51.559f, -48.689f, -45.868f, + -42.987f, -40.967f, -39.033f, -37.334f, -35.186f, -33.315f, -31.425f, -29.590f, -27.315f, + -25.582f, -23.596f, -21.478f, -19.732f, -18.453f, -16.375f, -14.369f, -12.196f, -9.906f, + -8.089f, -5.520f, -4.498f, -2.465f, -0.947f, 0.935f, 2.619f, 3.895f, 4.021f, + 3.902f, 4.791f, 5.282f, 5.611f, 5.825f, 5.727f, 5.591f, 5.805f, 6.268f, + 6.763f, 7.306f, 7.906f, 8.248f, 8.969f, 9.952f, 11.038f, 9.328f, 10.440f, + 8.893f, 9.351f, 9.184f, 9.000f, 9.137f, 9.529f, 10.315f, 10.760f, 10.868f, + 11.198f, 12.197f, 12.493f, 13.020f, 14.005f, 13.950f, 14.373f, 15.265f, 15.314f, + 16.312f, 16.111f, 16.739f, 16.788f, 16.883f, 16.339f, 15.812f, 15.250f, 14.126f, + 11.550f, 10.242f, 9.234f, 7.946f, 6.870f, 5.920f, 5.333f, 5.146f, 5.562f, + 6.844f, 7.480f, 7.547f, 6.429f, 14.262f, 4.126f, 3.643f, 3.271f, 1.704f, + -0.608f, -3.404f, -6.560f, -8.706f, -10.315f, -11.323f, -12.959f, -14.235f, -14.704f, + -15.019f, -14.975f, -14.440f, -13.849f, -13.099f, -11.593f, -10.356f, -8.706f, -6.620f, + -4.233f, -1.960f, 0.355f, 2.900f, 5.104f, 7.369f, 10.006f, 11.373f, 8.912f, + 7.743f, 17.103f, 16.934f, 14.329f, 15.425f, 15.360f, 15.195f, 13.678f, 11.882f, + 10.899f, 9.817f, 8.565f, 6.702f, 5.193f, 4.153f, 4.186f, -0.723f, -1.246f, + 0.161f, -0.694f, -2.636f, -1.824f, -0.954f, 0.225f, 1.078f, 1.527f, 0.658f, + 1.883f, 3.837f, 5.470f, 8.334f, 9.678f, 9.809f, 10.855f, 11.490f, 12.920f, + 13.606f}, + {-29.534f, -30.021f, -28.480f, -31.360f, -36.285f, -41.544f, -44.235f, -46.277f, -48.459f, + -50.319f, -52.277f, -53.167f, -54.444f, -56.778f, -63.010f, -63.878f, -64.316f, -64.020f, + -63.095f, -62.036f, -61.054f, -58.531f, -56.223f, -53.673f, -51.103f, -48.573f, -45.439f, + -42.807f, -40.330f, -38.518f, -36.717f, -34.569f, -32.616f, -30.706f, -29.005f, -26.928f, + -25.156f, -23.095f, -21.026f, -20.449f, -18.113f, -16.451f, -14.466f, -11.998f, -9.843f, + -7.650f, -6.674f, -4.328f, -2.630f, -1.143f, 0.784f, 2.382f, 3.121f, 3.066f, + 3.144f, 3.433f, 4.003f, 4.522f, 4.429f, 4.142f, 4.236f, 4.461f, 4.829f, + 5.417f, 6.045f, 6.588f, 6.677f, 7.535f, 8.564f, 8.745f, 8.802f, 9.297f, + 7.844f, 8.056f, 8.370f, 8.234f, 8.161f, 8.815f, 9.295f, 9.232f, 9.670f, + 9.483f, 10.443f, 11.596f, 12.215f, 13.409f, 14.281f, 14.470f, 15.386f, 15.473f, + 16.641f, 16.859f, 17.355f, 17.924f, 17.487f, 16.626f, 16.201f, 14.511f, 12.869f, + 11.525f, 9.761f, 8.298f, 7.531f, 6.038f, 5.022f, 4.500f, 4.495f, 5.499f, + 6.946f, 7.276f, 6.597f, 6.071f, 10.866f, 4.229f, 3.695f, 2.769f, 0.862f, + -1.835f, -4.803f, -7.513f, -9.586f, -11.165f, -12.390f, -13.502f, -14.755f, -15.197f, + -15.369f, -15.201f, -14.914f, -13.748f, -13.097f, -11.974f, -10.721f, -9.476f, -7.390f, + -5.001f, -2.779f, -0.294f, 2.141f, 4.606f, 7.123f, 9.551f, 10.988f, 10.478f, + 7.889f, 15.502f, 16.344f, 14.563f, 15.362f, 15.355f, 14.803f, 13.750f, 12.085f, + 10.576f, 9.681f, 8.828f, 7.110f, 5.484f, 3.940f, 3.801f, -0.666f, -1.196f, + -0.107f, -0.935f, -3.945f, -2.402f, -0.740f, -0.207f, 0.480f, 0.715f, 0.492f, + 1.725f, 3.906f, 5.452f, 8.395f, 9.699f, 9.791f, 10.907f, 11.557f, 12.928f, + 13.606f}, + {-29.534f, -30.028f, -28.502f, -31.455f, -36.474f, -41.594f, -44.333f, -46.241f, -48.436f, + -50.353f, -52.182f, -53.087f, -53.945f, -56.576f, -63.122f, -63.908f, -64.060f, -63.849f, + -62.809f, -61.763f, -60.581f, -58.428f, -56.099f, -53.269f, -50.726f, -48.398f, -45.148f, + -42.266f, -39.903f, -38.035f, -35.998f, -34.047f, -32.103f, -30.005f, -28.179f, -26.411f, + -24.799f, -22.862f, -21.005f, -20.810f, -18.188f, -16.526f, -14.282f, -11.878f, -9.753f, + -6.929f, -6.989f, -4.807f, -3.599f, -1.474f, 0.147f, 1.346f, 1.858f, 1.868f, + 1.718f, 2.200f, 2.724f, 3.035f, 2.955f, 3.040f, 3.083f, 3.118f, 3.607f, + 4.102f, 4.495f, 5.103f, 5.609f, 6.027f, 7.560f, 6.819f, 9.629f, 7.585f, + 7.428f, 7.227f, 7.285f, 7.307f, 7.427f, 8.007f, 8.011f, 8.028f, 8.267f, + 12.384f, 9.589f, 10.873f, 11.638f, 12.867f, 13.715f, 14.750f, 15.380f, 15.820f, + 16.411f, 17.205f, 18.362f, 17.158f, 17.298f, 16.171f, 15.287f, 13.499f, 12.138f, + 11.248f, 8.587f, 7.538f, 6.146f, 4.954f, 3.971f, 3.440f, 4.165f, 5.254f, + 6.843f, 7.269f, 5.368f, 12.054f, 6.970f, 2.983f, 3.761f, 2.258f, -0.197f, + -3.227f, -6.090f, -8.644f, -10.566f, -11.992f, -13.260f, -14.239f, -15.020f, -15.623f, + -15.660f, -15.778f, -15.474f, -14.762f, -13.346f, -12.286f, -11.258f, -10.083f, -7.990f, + -5.710f, -3.530f, -1.021f, 1.407f, 4.025f, 6.753f, 8.750f, 10.519f, 11.042f, + 8.082f, 14.369f, 14.376f, 15.534f, 15.120f, 15.000f, 14.665f, 13.656f, 12.202f, + 10.959f, 9.695f, 8.595f, 7.475f, 5.782f, 4.072f, 3.315f, -0.680f, -0.984f, + -0.586f, -2.002f, -4.924f, -3.129f, -0.877f, -0.646f, 0.028f, -0.168f, 0.310f, + 1.673f, 3.929f, 5.418f, 8.394f, 9.730f, 9.784f, 10.960f, 11.626f, 12.937f, + 13.606f}, + {-29.534f, -30.037f, -28.533f, -31.568f, -36.662f, -41.733f, -44.441f, -46.216f, -48.397f, + -50.408f, -52.205f, -52.909f, -53.552f, -56.343f, -63.008f, -63.726f, -63.745f, -63.565f, + -62.528f, -61.399f, -60.397f, -58.533f, -55.876f, -52.943f, -50.486f, -47.995f, -44.996f, + -41.825f, -39.570f, -37.379f, -35.332f, -33.379f, -31.476f, -29.606f, -27.381f, -25.910f, + -24.295f, -22.494f, -21.983f, -20.127f, -18.320f, -16.317f, -13.925f, -11.922f, -9.746f, + -7.877f, -6.721f, -5.343f, -3.578f, -1.460f, -0.271f, 0.660f, 0.692f, 0.767f, + 1.033f, 1.457f, 1.772f, 1.990f, 2.140f, 1.795f, 2.042f, 2.187f, 2.182f, + 2.366f, 3.099f, 3.588f, 4.421f, 4.626f, 4.861f, 6.303f, 6.824f, 6.163f, + 6.795f, 6.681f, 6.688f, 7.080f, 6.923f, 7.197f, 7.311f, 7.880f, 7.983f, + 8.688f, 9.515f, 10.574f, 11.770f, 12.685f, 13.999f, 14.580f, 14.840f, 15.763f, + 16.385f, 17.445f, 17.966f, 16.764f, 16.124f, 15.408f, 14.209f, 12.929f, 11.345f, + 9.630f, 8.024f, 6.448f, 5.249f, 3.825f, 2.835f, 2.699f, 3.726f, 4.796f, + 5.600f, 6.118f, 6.130f, 15.271f, 1.632f, 2.624f, 3.157f, 1.286f, -1.774f, + -4.598f, -7.283f, -9.577f, -11.371f, -12.749f, -13.953f, -14.911f, -15.533f, -16.083f, + -16.044f, -16.184f, -15.751f, -15.181f, -14.244f, -13.131f, -11.909f, -10.563f, -8.599f, + -6.518f, -4.122f, -1.593f, 0.527f, 3.380f, 6.079f, 7.904f, 10.010f, 11.369f, + 8.359f, 13.154f, 13.069f, 15.050f, 15.169f, 15.285f, 14.991f, 13.863f, 11.863f, + 11.575f, 10.209f, 8.599f, 7.417f, 6.370f, 5.005f, 2.864f, -0.666f, -1.060f, + -1.342f, -3.376f, -5.340f, -3.840f, -1.344f, -0.902f, -0.151f, -0.862f, 0.173f, + 1.699f, 3.905f, 5.381f, 8.335f, 9.771f, 9.792f, 11.013f, 11.696f, 12.946f, + 13.606f}, + {-29.534f, -30.046f, -28.574f, -31.691f, -36.837f, -41.952f, -44.535f, -46.205f, -48.289f, + -50.453f, -52.359f, -52.785f, -53.276f, -56.119f, -62.892f, -63.419f, -63.424f, -63.220f, + -62.305f, -61.181f, -60.498f, -58.356f, -55.654f, -52.571f, -50.192f, -47.612f, -44.833f, + -41.529f, -39.082f, -36.854f, -34.814f, -32.863f, -30.902f, -29.000f, -26.874f, -25.380f, + -23.772f, -22.085f, -22.123f, -19.645f, -18.145f, -15.964f, -13.666f, -11.543f, -9.188f, + -8.394f, -7.107f, -5.901f, -4.149f, -2.317f, -0.757f, 0.046f, -0.257f, -0.209f, + -0.115f, 0.370f, 1.065f, 1.145f, 1.084f, 1.238f, 1.283f, 1.115f, 1.069f, + 1.560f, 1.917f, 2.672f, 3.387f, 3.480f, 4.040f, 4.910f, 5.211f, 5.086f, + 5.708f, 6.217f, 6.647f, 6.234f, 6.361f, 6.678f, 6.652f, 6.908f, 7.305f, + 7.953f, 9.202f, 10.660f, 11.874f, 12.521f, 13.587f, 14.443f, 15.044f, 15.757f, + 16.625f, 16.294f, 16.306f, 15.965f, 15.349f, 14.983f, 13.334f, 11.842f, 10.098f, + 8.585f, 7.066f, 5.644f, 4.634f, 2.915f, 1.931f, 1.871f, 2.988f, 3.560f, + 3.458f, 13.203f, 18.149f, 9.833f, -0.706f, 2.682f, 2.397f, -0.141f, -3.321f, + -6.006f, -8.386f, -10.472f, -12.115f, -13.173f, -14.127f, -15.119f, -15.899f, -16.329f, + -16.697f, -16.996f, -16.735f, -15.891f, -14.756f, -13.770f, -12.564f, -11.176f, -9.378f, + -7.454f, -4.932f, -2.433f, -0.217f, 2.638f, 5.144f, 7.186f, 9.689f, 11.638f, + 9.173f, 11.724f, 12.440f, 12.031f, 15.585f, 15.486f, 15.041f, 13.979f, 12.308f, + 11.582f, 10.430f, 9.101f, 7.668f, 7.154f, 6.470f, 2.605f, -0.541f, -1.386f, + -2.061f, -4.363f, -5.461f, -4.442f, -2.031f, -0.999f, -0.156f, -1.261f, 0.092f, + 1.730f, 3.848f, 5.361f, 8.232f, 9.822f, 9.816f, 11.066f, 11.765f, 12.957f, + 13.606f}, + {-29.534f, -30.056f, -28.622f, -31.815f, -36.986f, -42.221f, -44.595f, -46.184f, -48.078f, + -50.450f, -52.547f, -52.837f, -53.213f, -55.935f, -62.548f, -63.150f, -63.216f, -62.934f, + -61.962f, -61.043f, -60.358f, -57.774f, -55.363f, -52.313f, -49.905f, -47.198f, -44.534f, + -41.161f, -38.606f, -36.410f, -34.239f, -32.341f, -30.257f, -28.333f, -26.528f, -24.915f, + -23.404f, -22.549f, -21.285f, -19.604f, -17.989f, -15.493f, -13.390f, -11.825f, -9.928f, + -8.468f, -7.214f, -6.036f, -4.723f, -3.134f, -1.692f, -0.952f, -1.286f, -1.255f, + -1.071f, -0.310f, 0.435f, 0.527f, 0.645f, 0.554f, 0.544f, 0.257f, 0.236f, + 0.348f, 1.242f, 1.863f, 2.063f, 2.503f, 3.566f, 3.836f, 4.313f, 4.297f, + 4.459f, 5.748f, 6.290f, 6.008f, 5.708f, 5.510f, 5.737f, 5.881f, 7.011f, + 7.976f, 9.235f, 10.041f, 11.107f, 12.167f, 13.703f, 13.973f, 14.900f, 15.549f, + 15.697f, 15.622f, 15.392f, 14.795f, 14.557f, 14.208f, 12.535f, 10.932f, 9.440f, + 7.579f, 6.153f, 4.913f, 3.664f, 2.294f, 0.960f, 0.796f, 1.436f, 1.802f, + 1.324f, 7.873f, 12.436f, -0.362f, -0.073f, 1.913f, 0.876f, -1.914f, -4.927f, + -7.324f, -9.206f, -11.233f, -12.456f, -13.359f, -14.095f, -15.138f, -16.114f, -16.909f, + -17.242f, -17.634f, -17.379f, -16.591f, -15.573f, -14.549f, -13.155f, -11.877f, -10.404f, + -8.292f, -5.813f, -3.401f, -0.968f, 2.007f, 4.543f, 6.698f, 9.389f, 11.480f, + 10.347f, 9.941f, 13.289f, 11.683f, 14.507f, 15.333f, 14.796f, 14.575f, 13.820f, + 11.550f, 10.838f, 9.545f, 8.143f, 7.801f, 7.600f, 2.666f, -0.329f, -1.726f, + -2.494f, -5.144f, -5.728f, -4.714f, -2.718f, -1.248f, -0.328f, -1.475f, 0.026f, + 1.685f, 3.784f, 5.376f, 8.110f, 9.877f, 9.861f, 11.121f, 11.833f, 12.969f, + 13.606f}, + {-29.534f, -30.067f, -28.679f, -31.929f, -37.096f, -42.489f, -44.604f, -46.112f, -47.765f, + -50.375f, -52.615f, -53.040f, -53.441f, -55.740f, -61.468f, -62.904f, -63.036f, -62.643f, + -61.538f, -60.739f, -59.842f, -57.359f, -55.110f, -52.119f, -49.721f, -46.883f, -44.067f, + -40.853f, -38.206f, -35.922f, -33.736f, -31.799f, -29.728f, -27.710f, -26.270f, -24.288f, + -22.998f, -22.930f, -20.350f, -19.285f, -17.324f, -15.143f, -13.502f, -11.749f, -9.774f, + -9.180f, -8.197f, -6.742f, -5.337f, -3.595f, -2.286f, -1.906f, -2.338f, -2.045f, + -1.550f, -1.195f, -0.474f, -0.262f, 0.207f, -0.064f, -0.256f, -0.436f, -0.390f, + -0.125f, 0.497f, 0.957f, 1.481f, 1.679f, 2.056f, 2.302f, 2.792f, 3.372f, + 4.559f, 5.393f, 5.756f, 5.707f, 4.919f, 4.398f, 4.779f, 5.720f, 6.575f, + 7.665f, 8.863f, 9.827f, 10.939f, 11.850f, 12.854f, 13.774f, 14.778f, 15.148f, + 14.931f, 15.158f, 14.105f, 14.150f, 13.867f, 13.001f, 11.745f, 10.144f, 8.470f, + 6.733f, 5.491f, 3.951f, 2.604f, 1.061f, -0.493f, -0.794f, -0.018f, 0.037f, + -0.524f, -1.555f, -1.837f, -1.941f, -0.577f, -0.188f, -1.675f, -4.304f, -6.541f, + -8.500f, -10.136f, -11.737f, -12.706f, -13.450f, -14.102f, -15.342f, -16.706f, -17.640f, + -18.290f, -18.428f, -17.898f, -17.384f, -16.433f, -15.233f, -13.837f, -12.478f, -11.415f, + -9.091f, -6.693f, -4.445f, -1.725f, 1.234f, 3.566f, 6.047f, 8.819f, 10.861f, + 10.908f, 9.138f, 13.996f, 13.325f, 12.883f, 13.863f, 14.385f, 14.659f, 15.555f, + 12.245f, 11.682f, 9.873f, 8.561f, 8.369f, 7.719f, 2.863f, -0.127f, -2.091f, + -2.721f, -6.127f, -6.133f, -4.454f, -3.097f, -1.822f, -0.944f, -1.684f, -0.069f, + 1.538f, 3.734f, 5.432f, 7.994f, 9.930f, 9.928f, 11.179f, 11.898f, 12.981f, + 13.606f}, + {-29.534f, -30.079f, -28.743f, -32.024f, -37.150f, -42.705f, -44.553f, -45.946f, -47.389f, + -50.225f, -52.462f, -53.211f, -53.828f, -55.496f, -59.673f, -62.609f, -62.671f, -62.276f, + -61.185f, -60.198f, -59.198f, -57.123f, -54.832f, -51.739f, -49.595f, -46.659f, -43.471f, + -40.651f, -37.902f, -35.470f, -33.199f, -31.241f, -29.235f, -27.288f, -25.766f, -24.008f, + -23.085f, -22.078f, -20.279f, -18.947f, -16.743f, -14.886f, -13.460f, -12.001f, -11.047f, + -9.576f, -8.503f, -7.422f, -5.825f, -3.921f, -3.098f, -3.042f, -3.094f, -2.969f, + -2.582f, -2.046f, -1.550f, -0.636f, -0.497f, -0.713f, -0.846f, -1.193f, -1.037f, + -0.828f, -0.309f, 0.044f, 0.173f, 0.837f, 0.990f, 1.052f, 1.867f, 2.195f, + 3.446f, 4.397f, 4.833f, 4.517f, 4.049f, 3.887f, 4.191f, 4.860f, 6.203f, + 7.315f, 8.815f, 9.390f, 10.494f, 11.838f, 12.421f, 13.782f, 14.222f, 14.342f, + 14.364f, 14.675f, 13.807f, 13.718f, 12.694f, 11.908f, 10.734f, 8.972f, 7.367f, + 5.896f, 4.507f, 2.954f, 1.524f, -0.080f, -1.762f, -2.193f, -1.643f, -1.406f, + -1.578f, -2.485f, -2.781f, -2.525f, -2.581f, -3.185f, -4.510f, -6.529f, -8.093f, + -9.521f, -10.833f, -12.226f, -13.306f, -13.918f, -14.591f, -16.213f, -17.758f, -18.672f, + -19.486f, -19.643f, -19.165f, -18.331f, -17.439f, -16.173f, -14.910f, -13.418f, -12.216f, + -10.026f, -7.800f, -5.330f, -2.657f, 0.459f, 2.613f, 5.093f, 8.160f, 10.085f, + 10.916f, 10.252f, 10.837f, 14.446f, 12.511f, 12.085f, 12.576f, 14.803f, 14.936f, + 13.687f, 11.957f, 9.983f, 9.029f, 8.572f, 7.272f, 2.936f, -0.135f, -2.458f, + -3.188f, -7.061f, -6.307f, -3.923f, -3.076f, -2.447f, -1.889f, -1.932f, -0.175f, + 1.326f, 3.700f, 5.522f, 7.908f, 9.973f, 10.019f, 11.240f, 11.959f, 12.995f, + 13.606f}, + {-29.534f, -30.092f, -28.814f, -32.089f, -37.136f, -42.824f, -44.437f, -45.662f, -47.006f, + -50.018f, -52.119f, -53.127f, -54.029f, -55.234f, -57.885f, -62.354f, -62.168f, -61.890f, + -60.778f, -59.565f, -58.467f, -56.719f, -54.597f, -51.491f, -49.197f, -46.473f, -43.169f, + -40.316f, -37.701f, -35.234f, -32.771f, -30.687f, -28.789f, -27.000f, -25.230f, -23.800f, + -23.317f, -21.225f, -20.171f, -18.600f, -16.463f, -14.576f, -13.721f, -12.266f, -11.482f, + -10.279f, -9.270f, -8.230f, -6.503f, -5.101f, -4.242f, -4.278f, -4.102f, -3.862f, + -3.284f, -2.812f, -2.291f, -1.577f, -1.545f, -1.299f, -1.548f, -1.641f, -1.395f, + -1.101f, -0.922f, -1.096f, -1.002f, -1.156f, -0.401f, 0.425f, 0.790f, 2.350f, + 2.744f, 5.364f, 5.086f, 3.442f, 3.336f, 3.083f, 3.197f, 4.711f, 6.057f, + 7.297f, 8.276f, 9.241f, 10.314f, 10.764f, 12.712f, 13.677f, 13.767f, 13.642f, + 14.019f, 14.068f, 13.788f, 12.342f, 11.577f, 10.774f, 9.717f, 7.847f, 6.429f, + 5.046f, 3.425f, 1.821f, 0.394f, -1.306f, -2.705f, -3.222f, -3.162f, -3.132f, + -3.089f, -3.405f, -3.842f, -4.317f, -5.020f, -5.963f, -7.092f, -8.264f, -9.368f, + -10.657f, -11.552f, -12.637f, -13.954f, -14.648f, -15.640f, -17.156f, -18.936f, -19.788f, + -20.248f, -20.129f, -19.667f, -19.306f, -18.331f, -16.800f, -15.792f, -14.392f, -12.920f, + -11.027f, -8.739f, -6.273f, -3.503f, -0.576f, 1.671f, 4.346f, 7.059f, 9.171f, + 10.758f, 11.519f, 6.852f, 15.325f, 11.716f, 10.903f, 9.219f, 10.679f, 11.894f, + 15.889f, 11.952f, 10.257f, 9.513f, 8.547f, 7.336f, 2.869f, -0.489f, -2.736f, + -4.410f, -7.610f, -6.186f, -3.681f, -2.931f, -2.686f, -2.701f, -2.100f, -0.231f, + 1.127f, 3.665f, 5.625f, 7.867f, 10.001f, 10.134f, 11.306f, 12.016f, 13.010f, + 13.606f}, + {-29.534f, -30.105f, -28.889f, -32.119f, -37.045f, -42.817f, -44.261f, -45.270f, -46.668f, + -49.785f, -51.729f, -52.678f, -53.753f, -54.975f, -56.712f, -62.232f, -61.765f, -61.484f, + -60.244f, -59.016f, -57.747f, -56.292f, -54.280f, -51.295f, -48.699f, -46.319f, -43.028f, + -39.857f, -37.402f, -34.996f, -32.581f, -30.256f, -28.224f, -26.612f, -24.769f, -23.455f, + -23.013f, -21.001f, -19.791f, -18.019f, -16.330f, -14.630f, -14.119f, -12.966f, -11.756f, + -10.863f, -9.750f, -8.906f, -7.129f, -5.879f, -5.603f, -5.700f, -5.185f, -4.883f, + -3.735f, -3.259f, -2.799f, -2.183f, -2.252f, -1.635f, -1.706f, -1.576f, -1.011f, + -1.274f, -1.619f, -2.219f, -2.291f, -0.807f, -1.186f, -0.416f, -0.106f, 1.695f, + 2.971f, 5.470f, 3.544f, 2.418f, 1.977f, 1.688f, 2.607f, 4.256f, 5.464f, + 6.992f, 7.562f, 7.697f, 9.627f, 10.770f, 12.131f, 12.738f, 12.807f, 12.875f, + 13.457f, 13.413f, 12.880f, 11.430f, 10.717f, 9.593f, 8.188f, 7.027f, 5.646f, + 4.072f, 2.323f, 0.384f, -0.821f, -2.245f, -3.404f, -3.824f, -4.345f, -4.316f, + -4.610f, -5.187f, -5.443f, -6.089f, -7.195f, -7.960f, -8.762f, -9.705f, -10.726f, + -11.667f, -12.557f, -13.418f, -14.846f, -15.446f, -16.761f, -18.174f, -19.927f, -20.714f, + -21.079f, -20.963f, -20.980f, -20.691f, -19.683f, -17.589f, -16.615f, -15.556f, -13.987f, + -12.150f, -9.788f, -7.206f, -4.311f, -1.604f, 0.727f, 3.352f, 6.590f, 8.267f, + 10.467f, 11.675f, 6.230f, 14.007f, 12.612f, 10.205f, 10.719f, 5.871f, 9.594f, + 16.664f, 12.723f, 10.748f, 9.698f, 8.876f, 8.217f, 2.975f, -0.985f, -3.072f, + -6.176f, -7.956f, -6.097f, -3.875f, -2.985f, -2.510f, -2.994f, -2.070f, -0.191f, + 1.007f, 3.600f, 5.714f, 7.878f, 10.011f, 10.273f, 11.380f, 12.069f, 13.026f, + 13.606f}, + {-29.534f, -30.119f, -28.969f, -32.107f, -36.871f, -42.679f, -44.034f, -44.819f, -46.401f, + -49.545f, -51.422f, -51.963f, -53.045f, -54.637f, -56.013f, -62.040f, -61.388f, -60.992f, + -59.797f, -58.592f, -57.332f, -55.945f, -53.687f, -50.952f, -48.362f, -45.918f, -42.718f, + -39.766f, -37.091f, -34.633f, -32.403f, -29.979f, -27.897f, -26.280f, -24.305f, -23.175f, + -22.509f, -20.886f, -19.407f, -17.671f, -16.145f, -15.386f, -13.882f, -13.348f, -12.259f, + -11.539f, -10.349f, -9.161f, -7.991f, -7.417f, -6.922f, -6.691f, -6.268f, -5.550f, + -4.295f, -3.805f, -3.156f, -2.985f, -2.873f, -1.894f, -1.441f, -1.708f, -1.803f, + -2.240f, -2.230f, -2.586f, -3.704f, -3.059f, -2.615f, -2.156f, -0.868f, 0.559f, + 3.471f, 3.024f, 1.975f, 1.247f, 2.650f, 0.841f, 2.419f, 3.473f, 4.912f, + 5.306f, 6.065f, 7.078f, 8.660f, 10.118f, 11.648f, 12.012f, 12.172f, 12.275f, + 12.727f, 12.345f, 11.553f, 10.425f, 9.897f, 8.636f, 7.153f, 6.133f, 4.735f, + 2.751f, 1.080f, -0.523f, -1.534f, -2.755f, -3.801f, -4.295f, -4.833f, -5.406f, + -5.902f, -6.779f, -6.966f, -7.880f, -8.789f, -9.367f, -10.080f, -11.023f, -12.040f, + -12.712f, -13.619f, -14.675f, -15.841f, -16.480f, -18.105f, -19.730f, -20.997f, -21.737f, + -21.724f, -22.126f, -22.160f, -21.503f, -20.774f, -18.587f, -17.656f, -16.684f, -15.122f, + -13.273f, -10.969f, -8.273f, -5.265f, -2.586f, -0.035f, 2.606f, 5.694f, 7.270f, + 10.638f, 11.046f, 7.422f, 10.916f, 13.893f, 11.483f, 13.464f, 8.159f, 11.089f, + 15.457f, 13.592f, 10.782f, 9.346f, 9.220f, 9.153f, 3.334f, -1.373f, -3.575f, + -7.528f, -8.292f, -6.173f, -4.100f, -3.232f, -2.362f, -2.828f, -1.896f, -0.090f, + 0.980f, 3.484f, 5.768f, 7.938f, 10.001f, 10.433f, 11.461f, 12.117f, 13.044f, + 13.606f}, + {-29.534f, -30.134f, -29.051f, -32.053f, -36.613f, -42.424f, -43.770f, -44.381f, -46.200f, + -49.299f, -51.218f, -51.222f, -52.276f, -54.121f, -55.308f, -61.381f, -60.672f, -60.425f, + -59.480f, -58.214f, -57.058f, -55.456f, -53.072f, -50.554f, -47.832f, -45.422f, -42.323f, + -39.636f, -36.827f, -34.349f, -32.191f, -29.789f, -27.679f, -25.896f, -23.983f, -23.017f, + -21.786f, -20.487f, -19.033f, -17.503f, -16.015f, -16.001f, -13.568f, -13.746f, -12.686f, + -11.923f, -10.943f, -9.960f, -8.831f, -8.309f, -8.234f, -7.607f, -7.132f, -6.045f, + -5.250f, -4.587f, -3.882f, -3.537f, -3.319f, -2.717f, -2.171f, -2.670f, -2.995f, + -3.262f, -3.174f, -4.091f, -4.041f, -3.876f, -3.717f, -3.003f, -1.952f, -0.443f, + 3.440f, 1.394f, 0.579f, 1.048f, 1.047f, 0.106f, 1.083f, 2.623f, 3.551f, + 4.605f, 5.079f, 5.890f, 7.443f, 9.304f, 10.856f, 11.169f, 11.519f, 11.572f, + 11.715f, 11.399f, 10.539f, 9.572f, 8.806f, 7.623f, 6.459f, 5.202f, 3.616f, + 1.708f, 0.168f, -1.221f, -2.405f, -3.558f, -4.424f, -5.075f, -5.786f, -6.597f, + -7.225f, -7.856f, -8.442f, -9.268f, -10.259f, -10.724f, -11.397f, -12.382f, -13.123f, + -13.936f, -14.414f, -15.661f, -16.674f, -18.089f, -19.801f, -21.129f, -22.148f, -22.517f, + -22.553f, -22.610f, -22.458f, -21.906f, -21.795f, -19.816f, -18.903f, -17.836f, -16.249f, + -14.323f, -11.904f, -9.361f, -6.516f, -3.800f, -0.905f, 1.813f, 4.946f, 6.342f, + 10.222f, 9.484f, 8.335f, 8.310f, 13.205f, 12.870f, 13.349f, 11.759f, 15.668f, + 15.483f, 14.322f, 10.945f, 9.250f, 9.229f, 9.481f, 3.816f, -1.643f, -4.043f, + -8.005f, -8.425f, -6.114f, -4.070f, -3.459f, -2.636f, -2.616f, -1.788f, -0.025f, + 1.010f, 3.315f, 5.779f, 8.038f, 9.979f, 10.612f, 11.551f, 12.159f, 13.062f, + 13.606f}, + {-29.534f, -30.150f, -29.135f, -31.958f, -36.274f, -42.084f, -43.482f, -44.024f, -46.036f, + -49.030f, -51.008f, -50.680f, -51.800f, -53.454f, -54.484f, -60.082f, -59.635f, -59.787f, + -59.103f, -57.841f, -56.476f, -54.779f, -52.519f, -49.939f, -47.318f, -44.893f, -41.988f, + -39.427f, -36.665f, -34.187f, -31.958f, -29.646f, -27.409f, -25.545f, -23.881f, -22.967f, + -21.341f, -20.138f, -18.752f, -17.442f, -16.409f, -15.958f, -14.052f, -13.967f, -12.845f, + -12.078f, -11.434f, -10.614f, -9.963f, -9.551f, -8.870f, -8.137f, -7.404f, -6.507f, + -6.277f, -5.589f, -4.439f, -3.909f, -3.537f, -3.419f, -3.657f, -4.032f, -3.729f, + -3.610f, -4.098f, -3.874f, -3.800f, -5.403f, -5.149f, -4.114f, -3.350f, -2.136f, + -0.141f, -0.563f, -1.269f, 2.210f, -0.882f, -0.486f, 0.478f, 1.668f, 2.371f, + 3.481f, 3.994f, 5.192f, 6.852f, 8.235f, 9.939f, 10.180f, 10.521f, 11.127f, + 11.118f, 10.553f, 9.560f, 8.715f, 7.270f, 6.306f, 5.160f, 3.870f, 2.181f, + 0.818f, -0.706f, -1.995f, -3.210f, -4.267f, -5.276f, -6.422f, -7.233f, -7.831f, + -8.425f, -9.093f, -9.965f, -10.734f, -11.113f, -12.132f, -12.914f, -13.667f, -14.363f, + -15.110f, -15.355f, -16.588f, -17.432f, -19.614f, -21.105f, -22.519f, -23.107f, -23.206f, + -23.782f, -24.018f, -23.590f, -23.139f, -22.345f, -20.999f, -20.183f, -18.785f, -17.306f, + -15.134f, -12.881f, -10.354f, -7.696f, -4.943f, -2.018f, 0.904f, 3.743f, 5.745f, + 8.538f, 8.115f, 8.626f, 7.274f, 10.149f, 12.468f, 13.363f, 13.557f, 18.170f, + 16.314f, 15.168f, 11.331f, 9.528f, 8.787f, 9.312f, 4.762f, -1.717f, -4.222f, + -8.083f, -8.206f, -5.629f, -3.934f, -3.604f, -3.231f, -2.720f, -1.923f, -0.078f, + 1.042f, 3.115f, 5.755f, 8.165f, 9.951f, 10.806f, 11.649f, 12.197f, 13.082f, + 13.606f}, + {-29.534f, -30.166f, -29.220f, -31.826f, -35.862f, -41.699f, -43.179f, -43.794f, -45.872f, + -48.726f, -50.663f, -50.407f, -51.629f, -52.768f, -53.733f, -58.284f, -58.839f, -59.003f, + -58.629f, -57.436f, -55.773f, -54.127f, -52.014f, -49.272f, -46.866f, -44.231f, -41.789f, + -39.140f, -36.484f, -34.085f, -31.642f, -29.410f, -27.315f, -25.211f, -23.558f, -22.953f, + -20.880f, -19.946f, -18.675f, -17.118f, -17.055f, -15.416f, -14.920f, -14.086f, -13.578f, + -12.724f, -11.714f, -11.336f, -10.646f, -10.359f, -9.581f, -8.615f, -7.679f, -7.208f, + -6.740f, -6.060f, -5.133f, -4.523f, -4.989f, -4.804f, -4.731f, -4.642f, -4.169f, + -4.107f, -3.316f, -5.255f, -5.311f, -6.644f, -6.160f, -5.325f, -4.236f, -3.484f, + -2.627f, -2.875f, 0.800f, 0.175f, -1.863f, -1.405f, -0.070f, 0.726f, 1.579f, + 2.212f, 3.105f, 4.280f, 5.808f, 7.783f, 8.928f, 9.102f, 9.654f, 10.430f, + 10.061f, 9.706f, 8.614f, 7.747f, 5.942f, 5.211f, 3.661f, 2.535f, 0.910f, + -0.240f, -1.608f, -2.933f, -4.313f, -5.158f, -6.447f, -7.645f, -8.401f, -9.088f, + -9.562f, -10.403f, -11.325f, -12.426f, -12.973f, -13.850f, -14.188f, -14.967f, -15.462f, + -16.142f, -16.481f, -17.467f, -18.459f, -21.174f, -22.522f, -23.653f, -23.970f, -24.463f, + -24.721f, -25.334f, -24.623f, -24.104f, -23.775f, -22.073f, -21.393f, -19.797f, -18.205f, + -15.969f, -13.665f, -11.437f, -8.669f, -6.066f, -2.900f, -0.183f, 2.331f, 4.679f, + 6.667f, 7.364f, 8.567f, 7.862f, 6.307f, 10.957f, 12.437f, 15.509f, 18.245f, + 16.709f, 14.701f, 11.598f, 9.516f, 7.922f, 8.877f, 6.070f, -1.556f, -3.876f, + -8.190f, -7.801f, -4.856f, -3.864f, -3.812f, -3.754f, -3.154f, -2.276f, -0.250f, + 1.039f, 2.919f, 5.711f, 8.305f, 9.930f, 11.008f, 11.755f, 12.231f, 13.103f, + 13.606f}, + {-29.534f, -30.183f, -29.303f, -31.665f, -35.390f, -41.308f, -42.867f, -43.687f, -45.684f, + -48.392f, -50.155f, -50.323f, -51.468f, -52.113f, -52.999f, -56.183f, -58.553f, -58.185f, + -58.069f, -56.917f, -55.382f, -53.572f, -51.595f, -48.683f, -46.122f, -43.706f, -41.534f, + -38.859f, -36.409f, -33.909f, -31.417f, -29.300f, -27.244f, -25.046f, -23.194f, -22.520f, + -20.523f, -19.661f, -18.608f, -17.391f, -16.751f, -16.182f, -15.290f, -14.291f, -13.649f, + -13.013f, -12.217f, -11.790f, -11.433f, -10.889f, -9.967f, -8.950f, -8.409f, -7.857f, + -7.229f, -6.695f, -6.079f, -5.805f, -6.124f, -5.961f, -5.650f, -5.100f, -4.701f, + -4.014f, -4.610f, -5.027f, -6.407f, -7.222f, -6.381f, -6.197f, -5.851f, -4.609f, + -3.765f, -2.426f, -0.107f, -1.772f, -2.506f, -2.526f, -1.638f, -0.495f, 0.312f, + 1.086f, 2.170f, 3.648f, 5.380f, 6.688f, 7.545f, 8.041f, 8.693f, 9.239f, + 8.958f, 8.227f, 7.390f, 6.546f, 5.049f, 3.893f, 2.587f, 1.393f, -0.148f, + -1.427f, -2.621f, -4.105f, -5.282f, -6.223f, -7.341f, -8.770f, -9.687f, -10.437f, + -11.073f, -12.098f, -12.849f, -13.904f, -14.712f, -15.565f, -15.614f, -16.068f, -16.542f, + -17.054f, -17.725f, -18.544f, -19.765f, -22.894f, -23.841f, -24.738f, -25.102f, -25.504f, + -25.566f, -26.193f, -26.285f, -25.506f, -24.901f, -23.224f, -22.194f, -20.685f, -19.034f, + -16.914f, -14.682f, -12.546f, -9.780f, -7.231f, -4.178f, -1.180f, 1.392f, 3.477f, + 5.246f, 6.637f, 8.218f, 8.120f, 5.995f, 8.420f, 11.930f, 17.075f, 16.728f, + 17.119f, 13.548f, 11.991f, 9.235f, 7.294f, 8.363f, 6.870f, -1.498f, -2.971f, + -8.290f, -7.447f, -4.306f, -3.837f, -4.178f, -4.048f, -3.692f, -2.662f, -0.469f, + 0.998f, 2.759f, 5.665f, 8.441f, 9.929f, 11.213f, 11.868f, 12.261f, 13.125f, + 13.606f}, + {-29.534f, -30.200f, -29.385f, -31.484f, -34.873f, -40.943f, -42.545f, -43.661f, -45.470f, + -48.046f, -49.588f, -50.318f, -51.081f, -51.358f, -51.942f, -54.031f, -58.282f, -57.607f, + -57.317f, -56.312f, -55.043f, -53.003f, -51.045f, -47.958f, -45.499f, -43.316f, -41.041f, + -38.567f, -36.164f, -33.715f, -31.240f, -29.007f, -27.082f, -25.066f, -22.868f, -22.057f, + -20.142f, -19.242f, -18.225f, -17.861f, -16.497f, -16.460f, -15.572f, -14.825f, -13.670f, + -13.430f, -12.418f, -12.175f, -11.714f, -11.017f, -10.351f, -9.468f, -9.391f, -8.445f, + -7.864f, -7.619f, -7.284f, -7.074f, -7.134f, -6.978f, -6.275f, -5.373f, -5.296f, + -3.951f, -5.687f, -6.785f, -7.570f, -7.628f, -7.068f, -6.987f, -5.771f, -5.973f, + -4.487f, -3.148f, -1.774f, -2.767f, -3.030f, -3.274f, -2.355f, -1.537f, -0.552f, + 0.412f, 1.722f, 3.154f, 4.834f, 5.750f, 6.742f, 7.097f, 7.663f, 7.946f, + 7.634f, 6.932f, 6.383f, 5.267f, 3.942f, 2.861f, 1.479f, -0.003f, -1.339f, + -2.708f, -3.865f, -5.340f, -6.391f, -7.184f, -8.454f, -10.230f, -11.347f, -12.252f, + -13.019f, -13.933f, -14.811f, -15.660f, -16.452f, -17.069f, -16.947f, -17.375f, -17.901f, + -18.261f, -19.082f, -20.015f, -21.460f, -23.930f, -24.929f, -25.769f, -26.216f, -26.827f, + -27.055f, -27.305f, -26.988f, -26.547f, -26.290f, -24.361f, -23.141f, -21.532f, -19.804f, + -17.801f, -15.910f, -13.839f, -10.988f, -8.105f, -5.263f, -2.512f, 0.476f, 2.404f, + 4.211f, 5.556f, 7.509f, 7.920f, 7.095f, 6.802f, 11.622f, 17.775f, 16.607f, + 17.233f, 13.111f, 12.111f, 8.982f, 7.069f, 8.089f, 7.104f, -1.711f, -2.227f, + -8.363f, -7.282f, -4.431f, -3.976f, -4.650f, -4.329f, -4.143f, -2.920f, -0.658f, + 0.940f, 2.650f, 5.624f, 8.558f, 9.960f, 11.417f, 11.984f, 12.288f, 13.148f, + 13.606f}, + {-29.534f, -30.217f, -29.464f, -31.295f, -34.331f, -40.617f, -42.216f, -43.645f, -45.245f, + -47.708f, -49.118f, -50.359f, -50.602f, -50.331f, -50.481f, -52.288f, -57.542f, -57.201f, + -56.450f, -55.681f, -54.372f, -52.456f, -50.354f, -47.342f, -45.049f, -42.785f, -40.517f, + -38.180f, -35.981f, -33.606f, -31.157f, -28.777f, -26.755f, -24.857f, -23.064f, -21.436f, + -19.824f, -18.905f, -18.221f, -17.693f, -17.060f, -16.508f, -15.768f, -15.110f, -14.570f, + -13.994f, -13.188f, -12.524f, -11.639f, -11.040f, -10.321f, -10.196f, -9.726f, -9.112f, + -8.631f, -8.157f, -7.997f, -8.081f, -8.220f, -7.721f, -7.007f, -6.059f, -4.383f, + -5.217f, -6.766f, -7.805f, -8.390f, -8.141f, -7.747f, -7.802f, -7.460f, -6.293f, + -5.577f, -3.275f, -4.208f, -3.703f, -3.947f, -4.029f, -3.545f, -2.425f, -1.379f, + 0.144f, 1.729f, 2.920f, 4.203f, 4.823f, 5.587f, 5.778f, 6.482f, 6.566f, + 6.334f, 5.786f, 5.020f, 3.992f, 2.965f, 1.168f, 0.043f, -1.424f, -2.696f, + -3.980f, -5.149f, -6.446f, -7.512f, -8.532f, -9.695f, -11.678f, -12.706f, -13.667f, + -14.757f, -15.533f, -16.546f, -17.431f, -17.866f, -18.471f, -18.593f, -18.593f, -19.166f, + -19.611f, -20.540f, -21.633f, -22.878f, -24.816f, -26.026f, -26.994f, -27.405f, -27.882f, + -28.814f, -29.064f, -28.920f, -28.098f, -27.510f, -25.415f, -24.149f, -22.309f, -20.801f, + -18.920f, -17.041f, -15.073f, -12.332f, -9.368f, -6.512f, -3.298f, -0.858f, 1.197f, + 3.032f, 4.528f, 6.381f, 7.169f, 7.053f, 6.382f, 11.053f, 17.659f, 18.466f, + 16.335f, 12.765f, 11.911f, 8.896f, 6.900f, 7.828f, 7.104f, -1.849f, -2.574f, + -8.382f, -7.364f, -5.187f, -4.561f, -5.148f, -4.799f, -4.490f, -3.046f, -0.802f, + 0.883f, 2.586f, 5.581f, 8.643f, 10.029f, 11.614f, 12.102f, 12.312f, 13.173f, + 13.606f}, + {-29.534f, -30.235f, -29.538f, -31.109f, -33.785f, -40.331f, -41.884f, -43.574f, -45.035f, + -47.382f, -48.820f, -50.477f, -50.417f, -49.050f, -48.967f, -51.246f, -56.569f, -56.576f, + -55.714f, -54.933f, -53.567f, -51.906f, -49.663f, -46.904f, -44.590f, -42.220f, -40.349f, + -37.929f, -35.811f, -33.343f, -30.962f, -28.552f, -26.584f, -24.897f, -22.719f, -20.781f, + -19.500f, -18.777f, -18.422f, -16.778f, -17.775f, -16.846f, -16.142f, -15.426f, -15.186f, + -14.459f, -13.654f, -12.737f, -11.874f, -11.184f, -10.917f, -10.550f, -10.225f, -9.640f, + -9.134f, -8.565f, -8.862f, -8.892f, -8.800f, -8.187f, -7.416f, -6.595f, -5.093f, + -6.296f, -7.687f, -8.630f, -8.859f, -8.753f, -8.585f, -8.004f, -7.910f, -6.910f, + -6.539f, -4.236f, -4.772f, -4.858f, -5.138f, -4.348f, -4.085f, -3.059f, -1.693f, + -0.266f, 1.197f, 2.639f, 3.458f, 3.770f, 4.330f, 4.561f, 5.399f, 5.117f, + 4.881f, 4.506f, 3.636f, 2.527f, 1.803f, -0.165f, -1.326f, -2.917f, -4.248f, + -5.522f, -6.672f, -7.626f, -8.632f, -9.944f, -11.009f, -13.124f, -14.334f, -15.455f, + -16.401f, -17.134f, -18.046f, -18.721f, -19.600f, -20.019f, -19.908f, -19.786f, -20.376f, + -21.116f, -22.158f, -23.091f, -24.134f, -25.625f, -27.157f, -27.855f, -28.643f, -29.137f, + -30.076f, -30.447f, -30.124f, -29.722f, -28.476f, -26.359f, -25.111f, -23.139f, -21.612f, + -20.080f, -18.314f, -16.228f, -13.717f, -10.730f, -7.674f, -4.737f, -2.326f, -0.226f, + 1.466f, 3.382f, 5.587f, 6.366f, 6.506f, 6.242f, 10.267f, 16.057f, 18.224f, + 14.517f, 12.648f, 11.502f, 8.756f, 6.986f, 7.267f, 6.527f, -1.818f, -3.887f, + -8.208f, -7.622f, -6.080f, -5.528f, -5.640f, -5.331f, -4.790f, -3.154f, -0.945f, + 0.841f, 2.552f, 5.524f, 8.685f, 10.140f, 11.800f, 12.219f, 12.335f, 13.198f, + 13.606f}, + {-29.534f, -30.253f, -29.607f, -30.936f, -33.260f, -40.071f, -41.560f, -43.410f, -44.858f, + -47.057f, -48.628f, -50.648f, -50.731f, -47.758f, -47.683f, -50.491f, -55.710f, -55.763f, + -55.112f, -54.098f, -52.904f, -51.195f, -49.024f, -46.400f, -44.107f, -41.946f, -40.359f, + -37.801f, -35.747f, -33.166f, -30.575f, -28.384f, -26.393f, -24.843f, -21.975f, -20.391f, + -19.195f, -18.307f, -18.485f, -17.408f, -17.803f, -17.319f, -16.426f, -16.011f, -15.414f, + -14.836f, -14.042f, -13.321f, -12.349f, -11.738f, -11.362f, -10.881f, -10.726f, -9.984f, + -9.432f, -8.994f, -9.326f, -9.348f, -9.282f, -8.542f, -7.672f, -7.078f, -6.392f, + -7.403f, -8.873f, -9.472f, -9.396f, -9.034f, -9.002f, -8.887f, -8.333f, -8.008f, + -6.420f, -5.913f, -5.139f, -5.213f, -5.601f, -4.874f, -4.746f, -3.421f, -2.078f, + -0.837f, 0.341f, 1.926f, 2.644f, 3.065f, 3.144f, 3.574f, 4.342f, 3.639f, + 3.439f, 2.984f, 1.949f, 0.959f, 0.161f, -1.472f, -2.738f, -4.603f, -5.924f, + -7.130f, -8.066f, -8.966f, -10.087f, -11.361f, -12.273f, -14.274f, -15.789f, -17.361f, + -18.368f, -19.166f, -19.698f, -20.203f, -20.960f, -21.075f, -21.068f, -21.161f, -21.852f, + -22.622f, -23.731f, -24.734f, -25.449f, -26.603f, -28.007f, -28.531f, -29.488f, -30.397f, + -31.042f, -31.438f, -31.375f, -31.191f, -29.816f, -27.297f, -25.926f, -24.144f, -22.520f, + -21.247f, -19.565f, -17.551f, -14.836f, -12.018f, -8.939f, -6.336f, -3.992f, -1.680f, + 0.168f, 2.194f, 4.601f, 5.158f, 5.268f, 7.294f, 10.502f, 14.875f, 16.794f, + 13.144f, 12.355f, 10.850f, 8.676f, 7.261f, 6.558f, 5.381f, -2.020f, -5.207f, + -7.948f, -7.889f, -6.745f, -6.410f, -6.096f, -5.665f, -5.048f, -3.328f, -1.133f, + 0.824f, 2.536f, 5.436f, 8.679f, 10.287f, 11.973f, 12.333f, 12.359f, 13.224f, + 13.606f}, + {-29.534f, -30.272f, -29.669f, -30.787f, -32.784f, -39.814f, -41.264f, -43.156f, -44.716f, + -46.726f, -48.392f, -50.728f, -51.253f, -46.730f, -46.514f, -49.376f, -54.695f, -55.211f, + -54.461f, -53.368f, -52.298f, -50.521f, -48.528f, -46.054f, -43.453f, -41.957f, -40.043f, + -37.641f, -35.565f, -32.829f, -30.368f, -28.301f, -26.199f, -24.368f, -21.440f, -19.980f, + -18.755f, -17.924f, -18.142f, -18.432f, -17.828f, -17.051f, -16.692f, -16.447f, -15.720f, + -14.889f, -14.341f, -13.704f, -12.935f, -12.162f, -11.568f, -11.218f, -10.766f, -10.061f, + -9.506f, -9.441f, -9.744f, -9.691f, -9.522f, -8.624f, -8.216f, -7.541f, -8.051f, + -8.965f, -9.910f, -10.169f, -9.973f, -9.689f, -9.352f, -9.377f, -9.060f, -8.378f, + -7.264f, -7.009f, -5.346f, -5.733f, -5.796f, -5.228f, -4.633f, -3.595f, -2.899f, + -0.471f, 2.843f, 0.488f, 1.429f, 1.979f, 2.207f, 2.519f, 2.755f, 2.103f, + 2.082f, 1.267f, 0.281f, -0.205f, -1.270f, -2.949f, -4.574f, -6.222f, -7.700f, + -8.790f, -9.554f, -10.710f, -11.941f, -12.804f, -13.772f, -15.184f, -17.367f, -18.938f, + -19.997f, -20.858f, -21.536f, -21.995f, -22.596f, -22.431f, -22.500f, -22.902f, -23.125f, + -24.363f, -25.223f, -26.023f, -26.833f, -27.721f, -28.868f, -29.469f, -30.614f, -31.504f, + -32.213f, -32.539f, -32.600f, -32.002f, -30.446f, -28.473f, -26.730f, -25.249f, -23.794f, + -22.398f, -20.781f, -18.659f, -16.039f, -13.154f, -10.138f, -7.549f, -5.319f, -3.152f, + -1.196f, 1.405f, 2.911f, 3.777f, 3.902f, 8.135f, 10.449f, 16.592f, 14.831f, + 12.449f, 11.574f, 10.708f, 8.761f, 7.258f, 5.621f, 4.213f, -2.501f, -5.998f, + -7.852f, -8.071f, -7.310f, -6.949f, -6.499f, -5.796f, -5.225f, -3.541f, -1.355f, + 0.842f, 2.539f, 5.313f, 8.626f, 10.463f, 12.133f, 12.440f, 12.383f, 13.251f, + 13.606f}, + {-29.534f, -30.290f, -29.725f, -30.668f, -32.381f, -39.539f, -41.012f, -42.852f, -44.583f, + -46.401f, -48.016f, -50.517f, -51.359f, -46.041f, -45.290f, -48.025f, -53.179f, -54.890f, + -53.732f, -52.660f, -51.588f, -50.045f, -48.071f, -45.906f, -43.234f, -41.923f, -39.578f, + -37.568f, -35.335f, -32.594f, -30.231f, -28.100f, -26.139f, -23.391f, -20.930f, -19.510f, + -18.119f, -18.225f, -18.090f, -18.542f, -17.431f, -17.005f, -16.823f, -16.644f, -15.692f, + -15.025f, -14.503f, -13.984f, -13.357f, -12.465f, -12.035f, -11.464f, -10.876f, -10.189f, + -9.744f, -9.646f, -9.959f, -9.939f, -9.754f, -9.206f, -8.780f, -8.198f, -9.125f, + -9.969f, -10.726f, -10.849f, -10.537f, -10.382f, -10.142f, -9.973f, -8.976f, -9.100f, + -8.431f, -7.318f, -6.302f, -6.722f, -6.822f, -5.893f, -4.877f, -3.835f, -2.540f, + 2.357f, 0.833f, -0.305f, 0.625f, 0.864f, 0.920f, 1.181f, 1.383f, 1.014f, + 0.676f, -0.453f, -1.038f, -1.694f, -2.920f, -4.319f, -6.375f, -7.966f, -9.442f, + -10.595f, -11.405f, -12.425f, -13.452f, -14.453f, -15.498f, -16.504f, -19.074f, -20.537f, + -21.834f, -22.468f, -22.822f, -23.244f, -23.948f, -24.012f, -24.007f, -24.668f, -24.796f, + -25.934f, -26.834f, -27.295f, -28.113f, -28.753f, -29.750f, -30.458f, -31.555f, -32.526f, + -33.245f, -33.987f, -33.427f, -32.898f, -31.466f, -29.266f, -27.660f, -26.177f, -25.024f, + -23.638f, -21.879f, -19.755f, -17.208f, -14.310f, -11.536f, -8.839f, -6.701f, -4.532f, + -2.145f, 0.394f, 1.666f, 2.619f, 2.822f, 7.431f, 10.503f, 16.253f, 12.676f, + 11.608f, 10.950f, 11.002f, 8.532f, 6.985f, 4.635f, 2.968f, -2.948f, -6.382f, + -7.834f, -8.192f, -7.965f, -7.358f, -6.878f, -5.991f, -5.327f, -3.712f, -1.548f, + 0.907f, 2.569f, 5.165f, 8.538f, 10.652f, 12.280f, 12.539f, 12.409f, 13.279f, + 13.606f}, + {-29.534f, -30.309f, -29.773f, -30.583f, -32.078f, -39.232f, -40.819f, -42.555f, -44.422f, + -46.111f, -47.538f, -49.921f, -50.617f, -45.518f, -44.184f, -47.113f, -51.477f, -54.251f, + -52.998f, -51.846f, -50.831f, -49.455f, -47.599f, -45.647f, -43.397f, -41.561f, -39.243f, + -37.473f, -35.103f, -32.345f, -30.151f, -27.766f, -26.112f, -22.671f, -20.393f, -19.058f, + -18.082f, -18.330f, -18.853f, -17.830f, -17.042f, -17.186f, -17.074f, -16.636f, -15.723f, + -15.096f, -14.803f, -14.310f, -13.326f, -12.795f, -12.301f, -11.701f, -11.069f, -10.521f, + -9.974f, -9.958f, -10.431f, -10.267f, -10.015f, -9.493f, -9.306f, -9.861f, -10.524f, + -10.819f, -11.411f, -11.422f, -11.113f, -10.930f, -9.512f, -10.042f, -9.855f, -9.248f, + -8.711f, -7.720f, -7.910f, -7.958f, -7.143f, -6.040f, -4.845f, -3.707f, 0.706f, + -1.519f, -1.489f, -0.308f, 0.158f, -0.136f, -0.279f, -0.065f, -0.081f, -0.267f, + -0.897f, -1.980f, -2.515f, -3.475f, -4.488f, -5.963f, -8.162f, -9.779f, -11.058f, + -12.328f, -13.394f, -14.524f, -15.364f, -16.379f, -17.174f, -18.247f, -20.831f, -21.981f, + -23.319f, -23.845f, -24.202f, -24.737f, -25.481f, -25.798f, -25.804f, -26.093f, -26.676f, + -27.548f, -28.314f, -28.739f, -29.432f, -29.957f, -30.738f, -31.595f, -32.477f, -33.276f, + -34.151f, -34.701f, -34.595f, -33.777f, -32.286f, -29.967f, -28.590f, -27.066f, -26.037f, + -24.572f, -22.969f, -20.694f, -18.367f, -15.580f, -12.546f, -10.323f, -7.951f, -5.832f, + -3.209f, -0.756f, 0.532f, 1.251f, 3.437f, 5.090f, 11.501f, 13.397f, 11.698f, + 10.744f, 10.301f, 10.679f, 7.798f, 5.975f, 3.853f, 0.977f, -3.450f, -6.476f, + -7.696f, -8.293f, -8.559f, -7.868f, -7.270f, -6.411f, -5.428f, -3.808f, -1.647f, + 1.017f, 2.635f, 5.016f, 8.427f, 10.838f, 12.417f, 12.629f, 12.438f, 13.308f, + 13.606f}, + {-29.534f, -30.327f, -29.813f, -30.534f, -31.894f, -38.891f, -40.685f, -42.313f, -44.192f, + -45.871f, -47.098f, -49.045f, -49.176f, -44.927f, -43.459f, -46.622f, -50.134f, -53.244f, + -52.277f, -51.151f, -50.078f, -48.691f, -47.126f, -45.248f, -43.120f, -41.092f, -39.182f, + -37.192f, -34.625f, -32.243f, -29.939f, -27.357f, -25.835f, -22.180f, -20.015f, -18.584f, + -17.924f, -18.413f, -19.516f, -18.190f, -17.463f, -17.213f, -17.284f, -16.730f, -16.168f, + -15.455f, -14.995f, -14.180f, -13.564f, -13.102f, -12.339f, -11.872f, -11.212f, -10.757f, + -10.257f, -10.253f, -10.556f, -10.622f, -10.297f, -10.075f, -10.040f, -10.714f, -11.290f, + -11.718f, -11.918f, -11.736f, -11.520f, -11.320f, -10.462f, -10.214f, -10.002f, -10.066f, + -9.053f, -8.875f, -8.861f, -9.124f, -7.656f, -6.781f, -5.445f, -4.006f, -2.067f, + -2.657f, -1.672f, -0.954f, -1.207f, -1.239f, -1.536f, -1.343f, -1.569f, -1.702f, + -2.423f, -3.540f, -4.048f, -5.011f, -6.204f, -7.904f, -9.755f, -11.198f, -12.649f, + -13.955f, -15.096f, -16.420f, -17.505f, -18.170f, -18.711f, -20.114f, -22.335f, -23.395f, + -24.745f, -25.336f, -25.892f, -26.592f, -27.250f, -27.419f, -27.573f, -28.068f, -28.251f, + -28.981f, -29.644f, -30.045f, -30.560f, -31.010f, -31.666f, -32.659f, -33.596f, -34.280f, + -35.186f, -35.772f, -35.231f, -34.443f, -33.022f, -30.626f, -29.537f, -28.130f, -26.846f, + -25.545f, -23.937f, -21.630f, -19.223f, -16.708f, -13.872f, -11.449f, -9.008f, -6.684f, + -3.972f, -1.924f, -0.624f, 0.341f, 2.471f, 7.147f, 11.007f, 11.571f, 10.715f, + 9.690f, 9.695f, 9.920f, 6.855f, 4.545f, 2.882f, -1.670f, -4.042f, -6.144f, + -7.500f, -8.434f, -8.948f, -8.409f, -7.653f, -6.893f, -5.592f, -3.870f, -1.649f, + 1.146f, 2.731f, 4.899f, 8.314f, 11.006f, 12.547f, 12.710f, 12.470f, 13.337f, + 13.606f}, + {-29.534f, -30.346f, -29.844f, -30.518f, -31.842f, -38.531f, -40.595f, -42.147f, -43.873f, + -45.652f, -46.803f, -48.132f, -47.644f, -44.199f, -42.984f, -45.777f, -49.316f, -52.389f, + -51.629f, -50.588f, -49.169f, -47.927f, -46.462f, -44.717f, -42.720f, -40.757f, -39.279f, + -36.871f, -34.336f, -32.100f, -29.535f, -27.137f, -25.485f, -21.945f, -19.866f, -18.468f, + -17.706f, -19.217f, -19.204f, -18.382f, -17.584f, -17.274f, -17.190f, -16.458f, -16.220f, + -15.816f, -14.677f, -14.313f, -13.609f, -13.371f, -12.482f, -12.113f, -11.318f, -10.773f, + -10.772f, -10.633f, -10.800f, -10.846f, -10.648f, -10.766f, -10.875f, -11.598f, -11.982f, + -12.319f, -12.292f, -12.124f, -11.999f, -11.104f, -10.904f, -10.447f, -10.479f, -10.145f, + -9.655f, -9.924f, -9.795f, -9.592f, -8.518f, -7.583f, -6.281f, -4.672f, -3.908f, + -3.168f, -2.544f, -2.217f, -2.442f, -2.530f, -2.885f, -2.776f, -3.225f, -3.270f, + -4.116f, -5.095f, -5.688f, -6.831f, -7.961f, -9.777f, -11.418f, -12.825f, -14.274f, + -15.497f, -16.890f, -18.371f, -19.298f, -20.122f, -20.712f, -22.239f, -23.800f, -25.395f, + -26.438f, -27.035f, -27.948f, -28.421f, -28.843f, -28.927f, -29.244f, -29.757f, -29.910f, + -30.540f, -30.810f, -31.161f, -31.793f, -32.264f, -33.070f, -33.661f, -34.802f, -35.154f, + -36.067f, -36.683f, -35.677f, -34.802f, -33.940f, -31.340f, -30.108f, -28.975f, -27.525f, + -26.336f, -24.676f, -22.443f, -19.966f, -17.627f, -14.935f, -12.725f, -10.230f, -7.784f, + -4.940f, -3.251f, -2.282f, -0.879f, 2.973f, 9.252f, 9.677f, 9.936f, 9.463f, + 8.467f, 8.981f, 9.297f, 6.255f, 4.374f, 1.683f, -3.747f, -4.247f, -5.404f, + -7.373f, -8.708f, -9.317f, -8.834f, -7.961f, -7.166f, -5.802f, -3.943f, -1.616f, + 1.256f, 2.839f, 4.842f, 8.217f, 11.145f, 12.672f, 12.781f, 12.507f, 13.367f, + 13.606f}, + {-29.534f, -30.364f, -29.866f, -30.529f, -31.925f, -38.178f, -40.520f, -42.045f, -43.478f, + -45.375f, -46.607f, -47.389f, -46.578f, -43.490f, -42.343f, -44.449f, -49.048f, -51.777f, + -51.112f, -49.806f, -48.212f, -47.048f, -45.702f, -44.102f, -42.442f, -40.540f, -39.068f, + -36.570f, -34.143f, -31.763f, -29.257f, -26.773f, -25.039f, -21.845f, -19.855f, -18.298f, + -17.391f, -20.243f, -18.678f, -18.326f, -17.881f, -17.337f, -17.010f, -16.190f, -16.145f, + -15.737f, -14.333f, -14.230f, -13.805f, -13.439f, -12.637f, -12.249f, -11.690f, -11.241f, + -11.141f, -11.030f, -11.272f, -11.214f, -11.015f, -11.325f, -11.408f, -12.353f, -12.580f, + -12.941f, -12.898f, -12.372f, -12.084f, -11.896f, -10.714f, -11.191f, -11.054f, -10.320f, + -10.298f, -10.770f, -10.488f, -9.938f, -9.025f, -8.345f, -7.010f, -5.577f, -4.819f, + -4.397f, -3.941f, -3.550f, -3.725f, -3.881f, -4.075f, -4.005f, -4.417f, -4.831f, + -5.766f, -6.622f, -7.518f, -8.622f, -9.779f, -11.653f, -13.124f, -14.555f, -15.782f, + -17.322f, -18.901f, -20.013f, -21.350f, -22.032f, -22.958f, -24.195f, -25.592f, -27.393f, + -28.323f, -28.999f, -29.494f, -30.316f, -30.860f, -30.595f, -30.863f, -31.403f, -31.506f, + -31.938f, -32.282f, -32.513f, -32.960f, -33.336f, -34.210f, -34.931f, -35.636f, -36.410f, + -36.868f, -37.181f, -36.367f, -35.379f, -34.458f, -31.946f, -30.685f, -29.646f, -28.333f, + -27.006f, -25.446f, -23.282f, -20.775f, -18.332f, -15.914f, -13.686f, -11.238f, -8.764f, + -5.877f, -5.457f, -3.934f, 0.842f, 4.055f, 5.598f, 8.271f, 8.339f, 8.072f, + 7.398f, 8.054f, 8.587f, 5.715f, 4.097f, 0.111f, -4.829f, -4.104f, -4.607f, + -7.301f, -9.056f, -9.756f, -9.095f, -8.123f, -7.157f, -5.976f, -4.022f, -1.642f, + 1.316f, 2.937f, 4.857f, 8.153f, 11.248f, 12.796f, 12.846f, 12.549f, 13.398f, + 13.606f}, + {-29.534f, -30.382f, -29.879f, -30.558f, -32.134f, -37.867f, -40.425f, -41.971f, -43.051f, + -44.947f, -46.318f, -46.851f, -46.072f, -42.995f, -41.414f, -43.561f, -49.213f, -51.058f, + -50.577f, -48.855f, -47.482f, -46.138f, -45.039f, -43.513f, -42.042f, -40.546f, -38.646f, + -36.429f, -33.883f, -31.522f, -29.020f, -26.503f, -24.534f, -21.761f, -19.865f, -18.375f, + -17.085f, -20.393f, -18.563f, -18.194f, -17.833f, -17.311f, -16.758f, -16.180f, -15.648f, + -15.191f, -14.589f, -14.217f, -13.821f, -13.367f, -12.810f, -12.278f, -11.898f, -11.684f, + -11.556f, -11.121f, -11.592f, -11.571f, -11.516f, -11.893f, -12.063f, -12.950f, -13.096f, + -13.285f, -13.087f, -12.734f, -12.792f, -10.647f, -10.935f, -11.439f, -11.430f, -10.638f, + -10.855f, -11.086f, -10.627f, -10.117f, -9.338f, -8.789f, -7.658f, -6.599f, -6.040f, + -5.559f, -5.280f, -4.904f, -5.059f, -5.237f, -5.238f, -5.351f, -5.737f, -6.150f, + -6.863f, -7.850f, -9.169f, -10.058f, -11.513f, -13.210f, -14.777f, -16.444f, -17.835f, + -19.297f, -20.859f, -22.032f, -23.064f, -23.972f, -25.046f, -26.103f, -27.485f, -29.274f, + -29.960f, -30.908f, -31.374f, -32.148f, -32.395f, -32.504f, -32.571f, -33.071f, -33.079f, + -33.289f, -33.599f, -33.772f, -34.312f, -34.528f, -35.536f, -36.057f, -36.888f, -37.707f, + -37.497f, -37.457f, -36.825f, -35.858f, -34.975f, -32.570f, -31.181f, -30.162f, -28.948f, + -27.436f, -25.660f, -23.885f, -21.343f, -19.045f, -16.576f, -14.368f, -11.873f, -9.240f, + -7.892f, -6.645f, -0.681f, 2.076f, 2.858f, 5.409f, 6.667f, 7.087f, 7.012f, + 6.294f, 7.170f, 7.694f, 4.299f, 1.866f, -1.696f, -5.555f, -4.321f, -3.947f, + -7.214f, -9.207f, -9.977f, -9.129f, -8.029f, -6.988f, -6.034f, -4.066f, -1.791f, + 1.316f, 3.013f, 4.942f, 8.130f, 11.316f, 12.920f, 12.905f, 12.596f, 13.429f, + 13.606f}, + {-29.534f, -30.399f, -29.883f, -30.597f, -32.447f, -37.631f, -40.283f, -41.881f, -42.653f, + -44.321f, -45.728f, -46.382f, -45.788f, -42.715f, -40.609f, -43.666f, -48.950f, -50.276f, + -49.776f, -48.068f, -46.679f, -45.451f, -44.354f, -42.890f, -41.686f, -40.415f, -38.180f, + -36.004f, -33.425f, -30.979f, -28.614f, -26.594f, -23.679f, -21.551f, -19.767f, -18.371f, + -18.121f, -19.625f, -18.520f, -18.210f, -17.699f, -17.112f, -16.409f, -16.043f, -15.347f, + -15.167f, -14.493f, -14.383f, -13.802f, -13.239f, -12.863f, -12.435f, -11.996f, -11.919f, + -11.423f, -11.361f, -11.869f, -12.017f, -11.993f, -12.232f, -12.614f, -13.294f, -13.403f, + -13.372f, -12.900f, -12.600f, -12.436f, -12.148f, -11.157f, -11.473f, -11.413f, -10.960f, + -11.191f, -11.019f, -10.655f, -10.113f, -9.690f, -9.153f, -8.218f, -7.432f, -6.756f, + -6.618f, -6.437f, -6.138f, -6.316f, -6.231f, -6.037f, -6.800f, -6.785f, -7.393f, + -8.364f, -9.232f, -10.502f, -11.499f, -13.213f, -14.722f, -16.356f, -18.035f, -19.460f, + -21.343f, -22.841f, -23.779f, -24.904f, -25.982f, -27.166f, -28.265f, -29.395f, -31.099f, + -31.976f, -32.855f, -33.425f, -33.573f, -33.774f, -33.895f, -34.462f, -34.386f, -34.611f, + -34.781f, -34.861f, -35.196f, -35.520f, -35.872f, -36.555f, -37.215f, -38.152f, -38.738f, + -38.694f, -38.033f, -37.422f, -36.076f, -35.369f, -32.907f, -31.575f, -30.360f, -29.209f, + -27.892f, -25.789f, -24.027f, -21.638f, -19.411f, -17.248f, -14.774f, -12.481f, -11.234f, + -9.092f, -3.841f, -0.316f, 0.845f, 1.803f, 5.203f, 5.327f, 5.988f, 6.019f, + 5.211f, 5.922f, 7.032f, 2.057f, -0.162f, -2.305f, -5.808f, -5.122f, -3.364f, + -6.996f, -9.014f, -9.813f, -8.850f, -7.560f, -6.756f, -5.963f, -4.070f, -2.069f, + 1.268f, 3.071f, 5.074f, 8.151f, 11.355f, 13.046f, 12.963f, 12.648f, 13.461f, + 13.606f}, + {-29.534f, -30.416f, -29.878f, -30.633f, -32.828f, -37.496f, -40.081f, -41.748f, -42.336f, + -43.538f, -44.772f, -45.789f, -45.336f, -42.443f, -40.401f, -44.097f, -47.269f, -49.626f, + -48.735f, -47.364f, -45.660f, -44.797f, -43.587f, -42.283f, -41.388f, -39.864f, -37.812f, + -35.579f, -32.924f, -30.345f, -28.095f, -26.582f, -23.070f, -21.318f, -19.657f, -18.276f, + -18.817f, -18.683f, -18.256f, -18.039f, -17.473f, -16.815f, -15.955f, -15.541f, -14.942f, + -14.951f, -14.262f, -14.283f, -13.844f, -13.452f, -12.875f, -12.669f, -11.928f, -11.947f, + -11.272f, -10.930f, -11.828f, -12.078f, -12.302f, -12.570f, -13.134f, -13.478f, -13.587f, + -13.293f, -12.889f, -12.769f, -12.323f, -11.780f, -11.456f, -11.771f, -11.638f, -11.383f, + -11.223f, -10.924f, -10.551f, -9.968f, -9.652f, -9.103f, -8.504f, -7.883f, -7.491f, + -7.829f, -7.549f, -7.277f, -7.272f, -7.126f, -7.384f, -7.536f, -7.629f, -8.605f, + -9.435f, -10.589f, -11.745f, -13.006f, -14.564f, -16.053f, -17.602f, -19.620f, -21.585f, + -23.143f, -24.285f, -25.695f, -26.697f, -28.148f, -29.279f, -30.569f, -31.572f, -33.075f, + -33.926f, -34.678f, -34.997f, -35.059f, -35.201f, -35.136f, -35.894f, -35.956f, -36.336f, + -36.390f, -36.265f, -36.295f, -36.717f, -36.994f, -37.570f, -38.169f, -39.055f, -39.107f, + -38.979f, -38.814f, -38.025f, -36.708f, -36.107f, -32.956f, -31.676f, -30.395f, -29.291f, + -27.734f, -25.841f, -23.888f, -21.613f, -19.615f, -17.475f, -15.175f, -13.423f, -11.693f, + -6.429f, -3.643f, -1.286f, 0.884f, 2.626f, 3.267f, 4.188f, 4.839f, 4.869f, + 4.344f, 5.087f, 6.699f, -0.125f, -1.058f, -1.997f, -5.549f, -6.100f, -3.136f, + -6.419f, -8.616f, -9.441f, -8.239f, -6.761f, -6.463f, -5.812f, -4.078f, -2.417f, + 1.186f, 3.132f, 5.223f, 8.212f, 11.375f, 13.172f, 13.023f, 12.705f, 13.493f, + 13.606f}, + {-29.534f, -30.432f, -29.865f, -30.656f, -33.234f, -37.470f, -39.828f, -41.567f, -42.124f, + -42.717f, -43.593f, -44.962f, -44.568f, -41.973f, -40.673f, -43.959f, -44.751f, -48.702f, + -47.684f, -46.507f, -44.981f, -43.977f, -42.751f, -41.693f, -40.911f, -39.297f, -37.414f, + -35.235f, -32.578f, -30.030f, -27.563f, -26.019f, -22.869f, -20.991f, -19.639f, -18.334f, + -18.522f, -18.126f, -17.863f, -17.565f, -16.989f, -16.470f, -15.371f, -15.119f, -14.940f, + -14.560f, -14.094f, -14.190f, -13.733f, -13.454f, -12.908f, -12.580f, -11.939f, -11.728f, + -11.247f, -11.064f, -11.741f, -12.039f, -12.326f, -12.834f, -13.287f, -13.508f, -13.550f, + -13.273f, -12.855f, -12.753f, -12.217f, -11.428f, -11.367f, -11.753f, -11.529f, -11.332f, + -11.127f, -10.991f, -10.320f, -9.881f, -9.607f, -9.056f, -8.655f, -8.267f, -8.162f, + -8.497f, -8.286f, -8.404f, -7.996f, -8.084f, -8.614f, -8.559f, -9.032f, -9.797f, + -10.579f, -11.800f, -12.979f, -14.418f, -16.034f, -17.341f, -18.852f, -21.145f, -23.256f, + -24.928f, -26.149f, -27.604f, -28.658f, -30.018f, -31.512f, -32.534f, -33.578f, -34.534f, + -35.638f, -36.159f, -36.397f, -36.472f, -36.489f, -36.485f, -36.854f, -37.520f, -37.796f, + -37.784f, -37.587f, -37.806f, -37.897f, -38.423f, -38.507f, -38.840f, -39.797f, -39.869f, + -39.194f, -38.870f, -38.358f, -37.015f, -36.207f, -32.928f, -31.632f, -30.505f, -29.118f, + -27.759f, -25.522f, -23.690f, -21.713f, -20.035f, -17.865f, -15.709f, -14.436f, -9.179f, + -7.879f, -4.773f, -2.278f, 1.149f, 2.433f, 2.009f, 2.844f, 3.761f, 3.596f, + 3.308f, 4.844f, 5.413f, -1.825f, -2.034f, -2.462f, -5.538f, -6.815f, -3.801f, + -5.357f, -8.078f, -8.767f, -7.227f, -5.909f, -6.119f, -5.632f, -4.117f, -2.744f, + 1.073f, 3.217f, 5.360f, 8.304f, 11.388f, 13.297f, 13.087f, 12.766f, 13.526f, + 13.606f}, + {-29.534f, -30.448f, -29.843f, -30.656f, -33.612f, -37.538f, -39.552f, -41.358f, -42.000f, + -41.999f, -42.455f, -43.944f, -43.568f, -41.268f, -40.699f, -43.119f, -43.200f, -47.172f, + -46.704f, -45.543f, -44.523f, -43.137f, -41.853f, -40.958f, -40.184f, -38.823f, -36.837f, + -34.779f, -32.341f, -29.628f, -27.109f, -25.265f, -22.674f, -20.689f, -19.392f, -18.232f, + -18.168f, -17.408f, -17.368f, -17.001f, -16.553f, -15.845f, -15.008f, -14.708f, -14.922f, + -14.398f, -14.193f, -13.916f, -13.591f, -13.186f, -12.792f, -12.460f, -11.744f, -11.766f, + -11.299f, -11.014f, -11.304f, -11.845f, -12.333f, -12.804f, -13.378f, -13.468f, -13.330f, + -13.057f, -12.722f, -12.297f, -11.818f, -11.402f, -11.307f, -11.723f, -11.651f, -11.180f, + -10.878f, -10.687f, -9.898f, -9.568f, -9.499f, -9.242f, -8.733f, -8.632f, -8.837f, + -9.129f, -9.116f, -9.147f, -8.933f, -9.093f, -9.368f, -9.643f, -10.253f, -10.864f, + -11.755f, -13.054f, -14.350f, -15.846f, -17.397f, -18.636f, -20.123f, -22.580f, -24.897f, + -26.386f, -27.688f, -29.188f, -30.694f, -32.061f, -33.319f, -34.502f, -35.320f, -36.312f, + -37.395f, -37.771f, -37.809f, -37.646f, -37.927f, -38.305f, -38.584f, -38.912f, -39.365f, + -39.223f, -39.179f, -39.216f, -39.275f, -39.314f, -39.606f, -39.434f, -40.460f, -40.272f, + -39.865f, -39.191f, -38.633f, -37.248f, -36.467f, -32.556f, -31.243f, -30.315f, -28.927f, + -26.749f, -24.980f, -23.276f, -21.752f, -20.044f, -18.203f, -16.562f, -13.264f, -10.747f, + -8.848f, -6.000f, -2.171f, 0.969f, 1.087f, 1.604f, 1.941f, 2.813f, 2.150f, + 2.252f, 4.189f, 3.362f, -3.528f, -2.957f, -3.484f, -5.915f, -7.273f, -5.373f, + -4.422f, -7.361f, -7.382f, -5.724f, -5.296f, -5.738f, -5.421f, -4.147f, -2.961f, + 0.923f, 3.333f, 5.467f, 8.419f, 11.407f, 13.416f, 13.160f, 12.831f, 13.559f, + 13.606f}, + {-29.534f, -30.463f, -29.813f, -30.626f, -33.912f, -37.666f, -39.290f, -41.148f, -41.912f, + -41.477f, -41.595f, -42.906f, -42.460f, -40.396f, -39.859f, -41.841f, -43.058f, -45.650f, + -45.815f, -44.616f, -43.625f, -42.374f, -40.976f, -40.069f, -39.323f, -38.166f, -36.251f, + -34.525f, -31.941f, -29.002f, -26.713f, -24.600f, -22.321f, -20.351f, -19.059f, -17.815f, + -17.697f, -16.867f, -16.563f, -16.307f, -15.826f, -15.226f, -14.811f, -14.499f, -14.372f, + -14.283f, -14.005f, -13.839f, -13.554f, -13.119f, -12.745f, -12.321f, -11.962f, -11.805f, + -11.435f, -11.059f, -11.040f, -11.623f, -12.152f, -12.664f, -13.163f, -13.152f, -12.973f, + -12.729f, -12.505f, -11.485f, -11.439f, -11.167f, -11.210f, -11.651f, -11.405f, -11.067f, + -10.676f, -10.351f, -9.639f, -9.634f, -9.502f, -9.212f, -8.937f, -8.996f, -9.244f, + -9.688f, -9.888f, -9.728f, -9.540f, -9.926f, -10.434f, -10.838f, -11.490f, -12.208f, + -13.154f, -14.529f, -15.669f, -17.217f, -18.716f, -19.939f, -21.683f, -23.839f, -26.046f, + -27.673f, -29.262f, -30.613f, -32.274f, -33.673f, -34.974f, -36.113f, -37.013f, -37.978f, + -38.700f, -39.169f, -39.386f, -39.528f, -39.466f, -39.893f, -39.994f, -40.569f, -40.842f, + -40.637f, -40.498f, -40.518f, -40.465f, -40.136f, -40.045f, -40.194f, -40.629f, -40.316f, + -40.105f, -39.639f, -38.624f, -37.237f, -36.635f, -32.102f, -31.023f, -29.987f, -28.542f, + -26.248f, -24.595f, -23.469f, -21.818f, -20.551f, -18.042f, -17.337f, -14.113f, -11.580f, + -9.114f, -7.051f, -3.247f, -1.551f, -0.004f, 0.354f, 0.454f, 1.384f, 1.615f, + 1.796f, 3.261f, 1.904f, -5.103f, -3.825f, -4.530f, -6.581f, -7.954f, -7.267f, + -4.962f, -6.853f, -5.596f, -4.111f, -4.983f, -5.223f, -5.114f, -4.096f, -3.014f, + 0.737f, 3.469f, 5.540f, 8.544f, 11.441f, 13.528f, 13.244f, 12.898f, 13.592f, + 13.606f}, + {-29.534f, -30.476f, -29.775f, -30.561f, -34.089f, -37.799f, -39.078f, -40.962f, -41.800f, + -41.158f, -41.091f, -42.061f, -41.333f, -39.361f, -38.341f, -40.357f, -42.769f, -44.674f, + -45.164f, -43.823f, -42.546f, -41.583f, -40.190f, -39.127f, -38.449f, -37.353f, -35.640f, + -33.996f, -31.550f, -28.564f, -26.674f, -24.021f, -21.912f, -20.185f, -18.640f, -17.311f, + -17.124f, -16.380f, -15.988f, -15.463f, -15.029f, -14.617f, -14.247f, -14.001f, -13.785f, + -13.803f, -13.681f, -13.598f, -13.206f, -12.985f, -12.645f, -12.350f, -12.164f, -11.939f, + -11.541f, -11.222f, -11.123f, -11.551f, -11.936f, -12.409f, -12.843f, -12.916f, -12.620f, + -12.294f, -11.891f, -11.155f, -10.959f, -10.927f, -11.107f, -11.515f, -10.967f, -10.599f, + -10.586f, -10.008f, -9.599f, -9.488f, -9.425f, -9.232f, -9.234f, -9.278f, -9.534f, + -10.216f, -10.441f, -10.481f, -10.285f, -10.732f, -11.473f, -11.667f, -12.599f, -13.494f, + -14.495f, -15.736f, -16.911f, -18.416f, -19.915f, -21.290f, -22.937f, -25.209f, -27.291f, + -29.070f, -30.748f, -32.318f, -33.914f, -35.158f, -36.333f, -37.581f, -38.615f, -39.366f, + -39.834f, -40.429f, -40.883f, -41.018f, -41.064f, -41.036f, -41.341f, -41.586f, -41.987f, + -41.842f, -41.904f, -41.789f, -41.341f, -40.885f, -40.459f, -40.767f, -40.975f, -40.704f, + -40.146f, -39.781f, -38.902f, -36.944f, -36.583f, -31.923f, -30.626f, -29.670f, -28.177f, + -26.550f, -24.951f, -23.473f, -21.932f, -20.839f, -20.232f, -16.453f, -14.187f, -12.180f, + -10.313f, -7.716f, -5.544f, -2.640f, -0.998f, -1.008f, -0.984f, -0.340f, 0.893f, + 1.144f, 1.620f, -0.088f, -6.017f, -4.723f, -5.528f, -7.513f, -8.850f, -8.884f, + -7.393f, -7.203f, -4.684f, -3.375f, -4.866f, -4.429f, -4.666f, -3.956f, -2.913f, + 0.545f, 3.597f, 5.595f, 8.671f, 11.494f, 13.627f, 13.341f, 12.968f, 13.626f, + 13.606f}, + {-29.534f, -30.489f, -29.731f, -30.461f, -34.111f, -37.875f, -38.933f, -40.798f, -41.615f, + -40.980f, -40.863f, -41.545f, -40.324f, -38.135f, -36.980f, -39.123f, -41.360f, -43.588f, + -44.700f, -43.196f, -41.733f, -40.698f, -39.559f, -38.317f, -37.610f, -36.605f, -35.075f, + -33.457f, -31.193f, -28.074f, -26.726f, -23.607f, -21.435f, -19.969f, -18.459f, -16.450f, + -16.059f, -15.734f, -15.366f, -14.843f, -14.341f, -13.943f, -13.617f, -13.621f, -13.453f, + -13.369f, -13.486f, -13.313f, -12.894f, -12.729f, -12.437f, -12.379f, -12.318f, -11.768f, + -11.483f, -11.185f, -11.068f, -11.477f, -11.874f, -12.031f, -12.309f, -12.540f, -12.246f, + -11.882f, -11.296f, -10.996f, -10.615f, -10.789f, -11.035f, -11.207f, -10.675f, -10.433f, + -10.369f, -9.747f, -9.421f, -9.344f, -9.296f, -9.343f, -9.270f, -9.447f, -9.996f, + -10.404f, -10.990f, -11.058f, -11.082f, -11.623f, -12.158f, -12.735f, -13.792f, -14.521f, + -15.677f, -16.847f, -18.241f, -19.671f, -21.067f, -22.559f, -24.293f, -26.529f, -28.518f, + -30.596f, -32.206f, -33.974f, -35.479f, -36.527f, -37.614f, -39.111f, -39.929f, -40.364f, + -41.115f, -41.657f, -42.040f, -42.150f, -42.064f, -42.003f, -42.477f, -42.662f, -43.022f, + -43.118f, -42.833f, -42.590f, -42.081f, -41.307f, -40.728f, -41.097f, -41.160f, -40.952f, + -40.375f, -39.816f, -38.812f, -36.780f, -36.480f, -31.664f, -30.512f, -29.290f, -27.715f, + -26.442f, -25.114f, -23.718f, -22.026f, -21.535f, -19.588f, -15.445f, -14.202f, -13.038f, + -9.654f, -8.423f, -6.743f, -3.919f, -2.220f, -2.558f, -2.552f, -0.942f, 0.089f, + 0.349f, -0.344f, -3.180f, -6.732f, -5.466f, -6.073f, -8.233f, -9.484f, -10.091f, + -10.015f, -8.378f, -5.436f, -4.212f, -4.965f, -3.449f, -4.119f, -3.827f, -2.728f, + 0.390f, 3.689f, 5.654f, 8.792f, 11.568f, 13.711f, 13.452f, 13.038f, 13.659f, + 13.606f}, + {-29.534f, -30.501f, -29.681f, -30.328f, -33.962f, -37.836f, -38.849f, -40.636f, -41.335f, + -40.860f, -40.765f, -41.336f, -39.649f, -36.882f, -36.329f, -38.617f, -39.862f, -41.828f, + -44.163f, -42.667f, -41.001f, -40.031f, -38.968f, -37.698f, -36.872f, -35.847f, -34.508f, + -33.095f, -30.846f, -27.997f, -26.390f, -23.225f, -20.893f, -19.638f, -18.513f, -15.855f, + -15.175f, -14.984f, -14.565f, -14.049f, -13.569f, -13.258f, -12.928f, -13.127f, -12.987f, + -13.058f, -13.133f, -12.953f, -12.666f, -12.623f, -12.171f, -12.280f, -12.207f, -11.503f, + -11.277f, -11.184f, -10.922f, -11.177f, -11.467f, -11.725f, -11.997f, -12.107f, -11.858f, + -11.575f, -11.005f, -10.718f, -10.346f, -10.358f, -10.758f, -10.677f, -10.318f, -10.026f, + -9.967f, -9.312f, -9.110f, -9.169f, -9.307f, -9.311f, -9.407f, -9.593f, -10.082f, + -11.057f, -11.678f, -11.639f, -11.804f, -12.320f, -12.851f, -13.948f, -14.866f, -15.866f, + -16.969f, -18.092f, -19.535f, -20.847f, -22.147f, -23.731f, -25.437f, -27.669f, -29.816f, + -31.869f, -33.615f, -35.417f, -37.020f, -38.054f, -39.089f, -40.059f, -41.150f, -41.513f, + -42.191f, -42.931f, -43.281f, -43.390f, -43.346f, -43.464f, -43.479f, -43.791f, -44.127f, + -43.922f, -43.629f, -42.984f, -42.427f, -41.678f, -41.279f, -41.274f, -41.249f, -41.102f, + -40.458f, -39.554f, -38.616f, -36.682f, -35.881f, -31.652f, -30.172f, -29.073f, -27.734f, + -26.519f, -25.221f, -24.071f, -22.958f, -21.418f, -16.358f, -15.445f, -14.134f, -12.212f, + -9.539f, -8.731f, -6.902f, -4.635f, -3.910f, -3.956f, -3.825f, -1.849f, -0.838f, + -0.897f, -2.581f, -6.719f, -7.441f, -6.371f, -6.645f, -8.705f, -10.034f, -11.124f, + -10.948f, -9.591f, -7.138f, -6.173f, -5.454f, -2.723f, -3.583f, -3.827f, -2.559f, + 0.307f, 3.732f, 5.740f, 8.900f, 11.661f, 13.780f, 13.577f, 13.108f, 13.693f, + 13.606f}, + {-29.534f, -30.512f, -29.626f, -30.168f, -33.649f, -37.639f, -38.794f, -40.436f, -40.959f, + -40.741f, -40.681f, -41.257f, -39.434f, -36.029f, -36.128f, -38.572f, -39.320f, -40.296f, + -43.597f, -42.155f, -40.294f, -39.760f, -38.252f, -37.126f, -36.310f, -35.111f, -33.964f, + -32.615f, -30.568f, -28.263f, -25.739f, -22.894f, -20.644f, -19.158f, -18.093f, -15.230f, + -14.656f, -14.381f, -13.936f, -13.397f, -12.915f, -12.532f, -12.466f, -12.673f, -12.619f, + -12.594f, -12.754f, -12.661f, -12.382f, -12.333f, -12.214f, -12.223f, -12.274f, -11.676f, + -11.334f, -10.809f, -11.086f, -11.038f, -11.209f, -11.398f, -11.713f, -11.831f, -11.485f, + -11.286f, -10.771f, -10.454f, -10.163f, -10.149f, -10.302f, -10.107f, -9.861f, -9.350f, + -9.508f, -8.895f, -8.826f, -8.875f, -9.085f, -9.365f, -9.465f, -9.739f, -10.290f, + -11.345f, -11.929f, -12.113f, -12.682f, -13.192f, -13.802f, -15.082f, -16.002f, -17.083f, + -18.265f, -19.324f, -20.791f, -22.177f, -23.445f, -25.053f, -26.601f, -28.908f, -31.050f, + -33.193f, -34.915f, -36.501f, -38.220f, -39.336f, -40.472f, -41.320f, -42.195f, -42.779f, + -43.121f, -43.727f, -44.405f, -44.540f, -44.539f, -44.722f, -44.462f, -44.819f, -45.090f, + -44.635f, -44.039f, -43.876f, -42.895f, -42.179f, -41.628f, -41.427f, -41.432f, -41.078f, + -40.449f, -39.289f, -37.943f, -36.142f, -35.004f, -31.811f, -30.044f, -29.285f, -28.710f, + -27.498f, -26.064f, -24.525f, -22.549f, -19.565f, -14.891f, -15.066f, -12.842f, -11.324f, + -10.897f, -9.300f, -7.693f, -5.818f, -5.256f, -5.410f, -4.676f, -3.477f, -2.404f, + -3.023f, -5.699f, -9.565f, -8.504f, -7.527f, -7.660f, -8.988f, -10.769f, -11.956f, + -10.474f, -10.218f, -8.526f, -8.160f, -6.338f, -2.687f, -3.149f, -3.951f, -2.477f, + 0.299f, 3.735f, 5.866f, 8.993f, 11.771f, 13.834f, 13.714f, 13.176f, 13.728f, + 13.606f}, + {-29.534f, -30.522f, -29.567f, -29.989f, -33.198f, -37.264f, -38.723f, -40.161f, -40.502f, + -40.604f, -40.567f, -41.089f, -39.537f, -35.948f, -35.888f, -38.263f, -39.151f, -39.934f, + -43.100f, -41.589f, -39.775f, -39.333f, -37.596f, -36.613f, -35.822f, -34.615f, -33.403f, + -32.124f, -30.163f, -28.686f, -24.888f, -22.566f, -20.706f, -18.630f, -17.298f, -14.911f, + -14.191f, -13.732f, -13.454f, -12.691f, -12.448f, -11.928f, -12.080f, -12.035f, -12.284f, + -12.204f, -12.327f, -12.355f, -12.180f, -12.162f, -12.090f, -12.206f, -12.042f, -11.803f, + -10.994f, -11.090f, -11.005f, -11.157f, -10.966f, -11.240f, -11.448f, -11.351f, -11.135f, + -10.877f, -10.252f, -9.981f, -9.786f, -9.726f, -9.746f, -9.540f, -9.258f, -8.751f, + -8.932f, -8.375f, -8.412f, -8.567f, -8.784f, -9.106f, -9.330f, -9.753f, -10.406f, + -11.456f, -12.344f, -12.977f, -13.534f, -13.805f, -14.684f, -15.948f, -17.054f, -18.055f, + -19.467f, -20.578f, -22.112f, -23.396f, -24.617f, -26.194f, -27.879f, -30.088f, -32.277f, + -34.330f, -36.114f, -37.687f, -39.349f, -40.582f, -41.620f, -42.423f, -42.953f, -43.661f, + -44.114f, -44.443f, -45.298f, -45.575f, -45.486f, -45.538f, -45.458f, -45.544f, -45.576f, + -45.334f, -44.364f, -44.028f, -43.416f, -42.268f, -41.600f, -41.668f, -41.475f, -40.740f, + -39.959f, -39.006f, -37.303f, -35.663f, -33.730f, -32.531f, -30.161f, -29.236f, -27.883f, + -26.905f, -25.796f, -24.478f, -22.974f, -17.300f, -16.830f, -14.666f, -11.708f, -11.557f, + -11.803f, -10.222f, -8.368f, -7.653f, -6.283f, -8.448f, -6.776f, -4.837f, -4.186f, + -5.275f, -8.097f, -10.599f, -10.366f, -8.985f, -8.482f, -8.640f, -11.468f, -12.315f, + -9.943f, -10.195f, -9.136f, -9.569f, -7.240f, -3.321f, -2.833f, -4.031f, -2.476f, + 0.332f, 3.724f, 6.032f, 9.072f, 11.892f, 13.875f, 13.862f, 13.241f, 13.762f, + 13.606f}, + {-29.534f, -30.531f, -29.505f, -29.803f, -32.657f, -36.728f, -38.589f, -39.794f, -39.977f, + -40.443f, -40.417f, -40.719f, -39.614f, -36.550f, -35.704f, -37.682f, -38.464f, -40.026f, + -42.300f, -40.970f, -39.576f, -38.537f, -37.193f, -36.265f, -35.285f, -34.067f, -32.871f, + -31.598f, -29.821f, -28.341f, -24.606f, -22.632f, -20.596f, -18.426f, -16.915f, -14.351f, + -13.755f, -13.133f, -12.904f, -12.107f, -11.934f, -11.464f, -11.795f, -11.574f, -11.745f, + -11.818f, -11.934f, -12.011f, -12.031f, -12.068f, -12.137f, -12.203f, -12.049f, -11.756f, + -11.608f, -11.280f, -11.553f, -11.271f, -10.766f, -11.152f, -11.210f, -10.988f, -10.831f, + -10.360f, -9.892f, -9.465f, -9.209f, -9.135f, -9.149f, -8.716f, -8.451f, -8.197f, + -8.133f, -7.782f, -7.980f, -8.262f, -8.635f, -8.837f, -9.236f, -9.808f, -10.702f, + -11.459f, -12.720f, -13.313f, -14.076f, -14.416f, -15.314f, -16.760f, -17.834f, -18.988f, + -20.459f, -21.781f, -23.202f, -24.533f, -25.824f, -27.348f, -28.847f, -31.150f, -33.284f, + -35.225f, -37.190f, -38.806f, -40.334f, -41.661f, -42.653f, -43.516f, -43.928f, -44.525f, + -45.033f, -45.654f, -46.167f, -46.317f, -46.223f, -46.201f, -46.390f, -46.322f, -46.014f, + -45.489f, -44.827f, -44.140f, -43.462f, -42.352f, -41.708f, -41.443f, -41.263f, -40.140f, + -38.686f, -37.982f, -37.135f, -33.591f, -30.970f, -29.710f, -26.661f, -24.110f, -23.402f, + -22.561f, -22.724f, -23.070f, -20.301f, -17.378f, -17.479f, -13.969f, -12.942f, -12.149f, + -12.079f, -10.625f, -9.611f, -8.368f, -8.867f, -10.750f, -10.322f, -8.360f, -7.232f, + -7.912f, -9.404f, -11.337f, -11.967f, -10.438f, -8.945f, -8.163f, -12.205f, -12.521f, + -9.683f, -9.703f, -9.277f, -10.496f, -7.700f, -4.168f, -2.634f, -3.867f, -2.463f, + 0.366f, 3.731f, 6.219f, 9.140f, 12.023f, 13.908f, 14.017f, 13.303f, 13.797f, + 13.606f}, + {-29.534f, -30.538f, -29.440f, -29.621f, -32.083f, -36.074f, -38.358f, -39.344f, -39.396f, + -40.246f, -40.212f, -40.198f, -39.398f, -37.262f, -36.027f, -37.436f, -37.529f, -39.442f, + -41.116f, -40.458f, -39.574f, -37.723f, -36.822f, -36.018f, -34.807f, -33.459f, -32.357f, + -31.004f, -29.520f, -27.370f, -24.380f, -22.476f, -20.305f, -18.349f, -16.452f, -13.585f, + -13.303f, -12.501f, -12.370f, -11.580f, -11.551f, -11.036f, -11.490f, -11.342f, -11.421f, + -11.634f, -11.614f, -11.946f, -11.978f, -12.076f, -12.467f, -12.356f, -12.113f, -12.008f, + -11.673f, -11.656f, -11.742f, -11.307f, -10.731f, -10.836f, -10.816f, -10.652f, -10.454f, + -9.852f, -9.306f, -8.994f, -8.629f, -8.365f, -8.356f, -7.844f, -7.785f, -7.486f, + -7.436f, -7.334f, -7.517f, -7.893f, -8.285f, -8.552f, -9.306f, -9.647f, -10.610f, + -11.521f, -12.868f, -13.635f, -14.413f, -14.830f, -15.852f, -17.214f, -18.543f, -20.016f, + -21.303f, -22.708f, -24.259f, -25.481f, -26.973f, -28.231f, -29.926f, -31.934f, -34.182f, + -36.123f, -37.916f, -39.561f, -41.130f, -42.580f, -43.517f, -44.311f, -44.753f, -45.261f, + -45.819f, -46.324f, -46.954f, -47.087f, -46.940f, -46.898f, -46.946f, -46.743f, -46.461f, + -45.880f, -45.024f, -44.228f, -43.240f, -42.211f, -41.856f, -40.955f, -40.632f, -39.455f, + -37.859f, -36.625f, -33.025f, -29.662f, -28.372f, -25.342f, -24.125f, -23.214f, -22.472f, + -21.835f, -20.457f, -20.539f, -20.262f, -20.566f, -16.838f, -13.577f, -13.603f, -13.256f, + -12.684f, -11.742f, -10.875f, -10.262f, -11.763f, -12.353f, -11.941f, -11.292f, -10.679f, + -10.569f, -10.811f, -12.860f, -13.278f, -11.536f, -9.557f, -8.491f, -12.967f, -13.165f, + -9.480f, -9.067f, -9.349f, -11.098f, -7.665f, -4.796f, -2.605f, -3.391f, -2.314f, + 0.385f, 3.773f, 6.404f, 9.207f, 12.162f, 13.938f, 14.175f, 13.360f, 13.832f, + 13.606f}, + {-29.534f, -30.544f, -29.373f, -29.454f, -31.541f, -35.374f, -38.026f, -38.850f, -38.774f, + -39.985f, -39.908f, -39.660f, -38.892f, -37.523f, -36.743f, -37.463f, -36.961f, -38.394f, + -40.177f, -40.102f, -39.030f, -36.824f, -36.314f, -35.672f, -34.392f, -33.126f, -31.787f, + -30.296f, -29.175f, -26.556f, -24.183f, -22.193f, -19.916f, -18.603f, -15.288f, -13.140f, + -12.750f, -12.048f, -11.875f, -11.126f, -10.971f, -10.779f, -11.036f, -11.198f, -10.956f, + -11.394f, -11.442f, -11.821f, -12.215f, -12.488f, -12.683f, -12.627f, -12.488f, -12.411f, + -11.751f, -12.227f, -11.932f, -11.118f, -10.841f, -10.800f, -10.739f, -10.410f, -10.004f, + -9.377f, -8.941f, -8.329f, -8.020f, -7.820f, -7.476f, -7.013f, -6.964f, -6.783f, + -6.723f, -6.819f, -6.945f, -7.490f, -7.910f, -8.326f, -9.050f, -9.622f, -10.760f, + -11.894f, -13.233f, -14.029f, -14.601f, -15.164f, -16.428f, -17.814f, -19.354f, -20.679f, + -22.125f, -23.554f, -25.060f, -26.316f, -27.826f, -29.148f, -30.844f, -32.483f, -34.716f, + -36.829f, -38.497f, -40.208f, -41.638f, -43.042f, -43.882f, -44.720f, -45.141f, -45.857f, + -46.442f, -46.823f, -47.434f, -47.541f, -47.402f, -47.171f, -47.205f, -47.112f, -46.221f, + -45.907f, -44.997f, -44.206f, -43.296f, -42.244f, -41.551f, -40.710f, -39.712f, -39.227f, + -36.380f, -33.354f, -31.936f, -29.786f, -27.657f, -24.879f, -22.807f, -21.243f, -20.567f, + -20.387f, -19.855f, -20.166f, -21.612f, -18.875f, -16.618f, -14.798f, -14.172f, -13.478f, + -13.513f, -12.492f, -12.667f, -12.124f, -13.257f, -13.373f, -12.413f, -12.301f, -13.053f, + -12.405f, -12.589f, -14.575f, -15.060f, -12.946f, -10.451f, -9.410f, -13.447f, -14.024f, + -9.643f, -8.735f, -9.668f, -11.378f, -7.540f, -5.125f, -2.805f, -2.720f, -1.944f, + 0.412f, 3.843f, 6.562f, 9.286f, 12.308f, 13.970f, 14.332f, 13.412f, 13.868f, + 13.606f}, + {-29.534f, -30.549f, -29.307f, -29.312f, -31.092f, -34.711f, -37.614f, -38.361f, -38.141f, + -39.638f, -39.482f, -39.180f, -38.253f, -37.259f, -37.061f, -37.015f, -36.710f, -37.617f, + -39.489f, -39.678f, -37.776f, -36.121f, -35.917f, -35.280f, -34.009f, -32.700f, -31.490f, + -29.815f, -28.774f, -25.931f, -24.017f, -21.797f, -19.581f, -18.802f, -14.514f, -12.732f, + -12.280f, -11.650f, -11.294f, -10.736f, -10.561f, -10.549f, -10.753f, -11.062f, -10.815f, + -11.235f, -11.280f, -11.732f, -12.355f, -12.718f, -12.944f, -12.947f, -12.711f, -12.155f, + -12.120f, -11.711f, -12.105f, -11.129f, -10.856f, -10.690f, -10.616f, -10.089f, -9.823f, + -8.938f, -8.337f, -7.737f, -7.354f, -7.140f, -6.757f, -6.212f, -6.235f, -6.090f, + -6.166f, -6.216f, -6.516f, -6.997f, -7.558f, -8.069f, -8.853f, -9.722f, -10.804f, + -12.277f, -13.518f, -14.350f, -14.887f, -15.728f, -17.159f, -18.307f, -20.026f, -21.353f, + -22.783f, -24.259f, -25.616f, -27.077f, -28.462f, -29.677f, -31.331f, -33.003f, -35.155f, + -37.238f, -39.102f, -40.725f, -42.004f, -43.219f, -44.045f, -44.955f, -45.662f, -45.758f, + -46.805f, -47.351f, -47.569f, -47.702f, -47.538f, -47.511f, -47.140f, -46.826f, -46.329f, + -45.639f, -44.823f, -44.011f, -42.906f, -41.795f, -40.965f, -40.366f, -39.053f, -36.262f, + -33.256f, -32.691f, -30.994f, -27.231f, -23.423f, -22.688f, -21.369f, -20.071f, -19.494f, + -20.094f, -19.683f, -18.239f, -17.851f, -16.704f, -15.990f, -15.192f, -14.303f, -13.797f, + -13.850f, -13.682f, -13.901f, -13.472f, -14.649f, -14.670f, -13.882f, -13.780f, -13.991f, + -13.612f, -14.384f, -15.633f, -16.489f, -14.709f, -11.310f, -10.522f, -14.126f, -14.539f, + -10.408f, -8.987f, -10.394f, -11.496f, -7.702f, -5.296f, -3.157f, -2.035f, -1.361f, + 0.489f, 3.915f, 6.676f, 9.389f, 12.463f, 14.008f, 14.484f, 13.458f, 13.903f, + 13.606f}, + {-29.534f, -30.552f, -29.240f, -29.204f, -30.786f, -34.165f, -37.168f, -37.919f, -37.536f, + -39.208f, -38.973f, -38.705f, -37.572f, -36.844f, -36.538f, -36.105f, -36.623f, -37.005f, + -38.229f, -39.107f, -36.812f, -35.997f, -35.609f, -34.977f, -33.613f, -32.229f, -31.155f, + -29.682f, -27.976f, -25.783f, -23.647f, -21.401f, -19.587f, -18.506f, -14.323f, -12.628f, + -12.045f, -11.421f, -10.904f, -10.441f, -10.242f, -10.395f, -10.422f, -10.787f, -10.692f, + -10.932f, -11.280f, -11.619f, -12.337f, -12.786f, -12.902f, -12.915f, -12.729f, -12.511f, + -12.225f, -11.866f, -11.470f, -11.154f, -10.832f, -10.651f, -10.455f, -9.952f, -9.471f, + -8.577f, -7.783f, -7.259f, -6.780f, -6.431f, -6.025f, -5.664f, -5.528f, -5.390f, + -5.523f, -5.628f, -5.998f, -6.567f, -7.166f, -7.887f, -8.780f, -9.887f, -11.028f, + -12.572f, -13.436f, -14.538f, -15.233f, -16.281f, -17.514f, -18.840f, -20.408f, -21.923f, + -23.146f, -24.831f, -26.079f, -27.583f, -28.951f, -30.236f, -31.803f, -33.267f, -35.370f, + -37.444f, -39.423f, -40.836f, -42.201f, -43.242f, -44.172f, -44.844f, -45.674f, -46.056f, + -46.757f, -47.189f, -47.576f, -47.487f, -47.406f, -47.312f, -47.124f, -46.555f, -46.189f, + -45.214f, -44.334f, -43.151f, -42.404f, -41.472f, -40.781f, -38.420f, -37.231f, -33.954f, + -34.083f, -32.350f, -25.939f, -23.671f, -23.328f, -21.539f, -19.960f, -19.272f, -17.952f, + -19.165f, -20.384f, -19.521f, -17.923f, -16.168f, -16.043f, -15.836f, -14.758f, -14.277f, + -13.685f, -15.389f, -14.847f, -14.363f, -15.115f, -16.836f, -15.902f, -15.826f, -14.970f, + -15.791f, -16.173f, -16.214f, -17.296f, -15.903f, -12.456f, -11.914f, -15.490f, -14.878f, + -11.449f, -9.807f, -11.245f, -11.694f, -8.097f, -5.397f, -3.423f, -1.430f, -0.649f, + 0.639f, 3.952f, 6.749f, 9.525f, 12.625f, 14.057f, 14.624f, 13.498f, 13.939f, + 13.606f}, + {-29.534f, -30.554f, -29.175f, -29.133f, -30.653f, -33.799f, -36.741f, -37.539f, -37.001f, + -38.730f, -38.489f, -38.128f, -36.842f, -36.609f, -35.742f, -35.716f, -36.956f, -36.249f, + -36.514f, -38.608f, -36.485f, -35.708f, -35.102f, -34.557f, -33.128f, -31.941f, -30.628f, + -29.348f, -27.262f, -25.448f, -23.295f, -21.060f, -19.566f, -18.241f, -14.142f, -12.564f, + -11.785f, -11.187f, -10.675f, -10.265f, -9.951f, -10.302f, -10.108f, -10.469f, -10.502f, + -10.853f, -11.190f, -11.559f, -12.177f, -12.656f, -12.685f, -12.894f, -12.765f, -12.383f, + -11.975f, -11.519f, -11.577f, -11.109f, -10.776f, -10.596f, -10.153f, -9.797f, -9.281f, + -8.247f, -7.443f, -6.714f, -6.231f, -5.825f, -5.357f, -5.069f, -4.856f, -4.828f, + -4.876f, -5.063f, -5.509f, -6.074f, -6.680f, -7.598f, -8.555f, -9.854f, -11.012f, + -12.516f, -13.473f, -14.683f, -15.406f, -16.741f, -17.882f, -19.362f, -20.786f, -22.246f, + -23.593f, -25.154f, -26.543f, -27.858f, -29.267f, -30.486f, -31.927f, -33.531f, -35.425f, + -37.399f, -39.402f, -40.961f, -42.157f, -43.135f, -44.065f, -44.912f, -45.302f, -45.929f, + -46.344f, -46.779f, -47.134f, -47.336f, -47.147f, -46.942f, -46.837f, -46.160f, -45.674f, + -44.765f, -44.030f, -42.662f, -41.901f, -40.885f, -39.057f, -37.702f, -37.176f, -32.509f, + -31.684f, -26.771f, -24.360f, -24.748f, -23.160f, -21.285f, -19.376f, -18.329f, -17.550f, + -17.179f, -20.659f, -19.650f, -18.185f, -16.313f, -15.932f, -16.390f, -14.992f, -14.530f, + -14.617f, -16.466f, -15.941f, -15.405f, -16.919f, -17.994f, -17.112f, -18.229f, -17.646f, + -18.289f, -17.658f, -17.786f, -18.020f, -16.494f, -14.513f, -13.570f, -16.892f, -15.423f, + -12.420f, -10.983f, -11.759f, -11.918f, -8.399f, -5.445f, -3.383f, -0.876f, 0.092f, + 0.854f, 3.933f, 6.793f, 9.695f, 12.790f, 14.118f, 14.751f, 13.533f, 13.976f, + 13.606f}, + {-29.534f, -30.554f, -29.111f, -29.100f, -30.698f, -33.642f, -36.376f, -37.203f, -36.554f, + -38.245f, -38.153f, -37.426f, -36.119f, -36.523f, -35.519f, -36.202f, -37.701f, -35.637f, + -35.286f, -38.201f, -36.193f, -35.048f, -34.561f, -34.056f, -32.802f, -31.465f, -30.113f, + -28.746f, -26.990f, -25.156f, -23.052f, -21.162f, -19.465f, -17.823f, -14.121f, -12.716f, + -11.655f, -11.004f, -10.536f, -10.239f, -9.797f, -10.087f, -9.897f, -10.176f, -10.411f, + -10.674f, -11.099f, -11.477f, -12.012f, -12.316f, -12.593f, -12.713f, -12.546f, -12.300f, + -12.006f, -11.935f, -11.292f, -10.999f, -10.657f, -10.472f, -9.976f, -9.532f, -9.109f, + -7.968f, -7.057f, -6.232f, -5.682f, -5.205f, -4.794f, -4.479f, -4.202f, -4.254f, + -4.259f, -4.499f, -4.880f, -5.556f, -6.044f, -7.272f, -8.352f, -9.485f, -11.012f, + -12.329f, -13.381f, -14.625f, -15.662f, -16.766f, -17.978f, -19.475f, -21.195f, -22.468f, + -23.949f, -25.249f, -26.658f, -28.217f, -29.370f, -30.781f, -32.143f, -33.408f, -35.392f, + -37.186f, -39.082f, -40.612f, -41.818f, -43.086f, -43.695f, -44.369f, -44.635f, -45.151f, + -45.679f, -46.213f, -46.358f, -46.624f, -46.633f, -46.199f, -45.956f, -45.436f, -45.014f, + -44.206f, -43.291f, -41.933f, -41.034f, -39.550f, -38.296f, -37.119f, -34.158f, -31.893f, + -28.918f, -27.129f, -25.461f, -23.667f, -22.678f, -20.394f, -18.263f, -17.543f, -16.998f, + -16.304f, -18.197f, -18.592f, -17.497f, -16.279f, -16.183f, -15.961f, -14.728f, -14.195f, + -15.387f, -16.781f, -17.434f, -17.422f, -18.799f, -19.039f, -18.336f, -20.339f, -20.085f, + -19.716f, -19.022f, -19.380f, -18.670f, -17.255f, -16.567f, -15.385f, -17.729f, -16.010f, + -13.256f, -12.155f, -12.067f, -11.898f, -8.437f, -5.534f, -3.059f, -0.322f, 0.817f, + 1.103f, 3.864f, 6.831f, 9.894f, 12.954f, 14.191f, 14.861f, 13.563f, 14.013f, + 13.606f}, + {-29.534f, -30.553f, -29.050f, -29.103f, -30.902f, -33.686f, -36.096f, -36.866f, -36.183f, + -37.789f, -38.035f, -36.717f, -35.598f, -36.366f, -35.838f, -36.592f, -38.173f, -35.405f, + -34.441f, -37.658f, -35.740f, -34.701f, -34.044f, -33.661f, -32.453f, -30.997f, -29.644f, + -28.212f, -26.676f, -24.960f, -22.945f, -21.099f, -19.515f, -17.069f, -14.148f, -12.937f, + -11.802f, -11.204f, -10.635f, -10.238f, -9.598f, -9.797f, -9.763f, -9.936f, -10.222f, + -10.661f, -11.022f, -11.301f, -11.814f, -12.016f, -12.224f, -12.412f, -12.420f, -12.187f, + -12.125f, -11.661f, -11.358f, -10.866f, -10.621f, -10.218f, -9.746f, -9.247f, -8.712f, + -7.630f, -6.425f, -5.692f, -5.204f, -4.754f, -4.255f, -3.954f, -3.692f, -3.628f, + -3.641f, -3.891f, -4.232f, -4.826f, -5.512f, -6.737f, -7.882f, -9.150f, -10.713f, + -11.940f, -13.379f, -14.353f, -15.510f, -16.623f, -18.082f, -19.571f, -21.208f, -22.508f, + -23.996f, -25.318f, -26.636f, -27.959f, -29.289f, -30.828f, -32.140f, -33.523f, -35.171f, + -36.828f, -38.594f, -39.958f, -41.069f, -42.285f, -43.068f, -43.615f, -44.065f, -43.914f, + -44.761f, -45.400f, -45.569f, -45.948f, -45.728f, -45.620f, -45.061f, -44.586f, -44.184f, + -43.359f, -42.506f, -41.788f, -40.227f, -38.494f, -36.502f, -33.181f, -31.850f, -31.647f, + -30.432f, -28.038f, -25.462f, -22.301f, -21.096f, -19.176f, -17.163f, -16.205f, -17.081f, + -15.281f, -16.499f, -17.465f, -16.633f, -15.794f, -15.886f, -15.653f, -13.114f, -14.657f, + -16.322f, -17.275f, -18.365f, -19.255f, -20.362f, -19.627f, -20.388f, -22.436f, -21.966f, + -21.500f, -20.754f, -19.812f, -18.828f, -18.256f, -17.551f, -17.083f, -18.059f, -16.429f, + -14.078f, -13.078f, -12.790f, -11.633f, -8.300f, -5.819f, -2.712f, 0.186f, 1.552f, + 1.368f, 3.782f, 6.885f, 10.109f, 13.111f, 14.274f, 14.951f, 13.589f, 14.050f, + 13.606f}, + {-29.534f, -30.551f, -28.992f, -29.134f, -31.225f, -33.885f, -35.891f, -36.473f, -35.846f, + -37.377f, -38.110f, -36.178f, -35.415f, -36.078f, -35.801f, -35.959f, -37.751f, -35.229f, + -33.398f, -37.001f, -35.226f, -34.341f, -33.455f, -33.164f, -31.953f, -30.616f, -29.404f, + -27.825f, -26.260f, -24.841f, -23.016f, -21.029f, -19.995f, -16.855f, -14.219f, -13.059f, + -11.993f, -11.157f, -10.681f, -10.339f, -9.726f, -9.739f, -9.777f, -9.832f, -10.060f, + -10.423f, -10.814f, -11.115f, -11.537f, -11.724f, -12.022f, -12.119f, -12.054f, -11.928f, + -11.617f, -11.616f, -11.303f, -10.734f, -10.453f, -10.003f, -9.535f, -8.978f, -8.262f, + -7.254f, -5.980f, -5.428f, -4.812f, -4.383f, -3.872f, -3.586f, -3.223f, -3.082f, + -3.108f, -3.388f, -3.750f, -4.344f, -4.986f, -6.035f, -7.240f, -8.680f, -10.261f, + -11.646f, -13.014f, -14.139f, -15.432f, -16.672f, -17.960f, -19.458f, -20.993f, -22.460f, + -23.817f, -25.183f, -26.431f, -27.733f, -29.028f, -30.545f, -31.762f, -33.137f, -34.720f, + -36.212f, -37.806f, -39.020f, -40.303f, -41.309f, -42.124f, -42.387f, -43.177f, -43.508f, + -43.865f, -44.190f, -44.431f, -44.587f, -44.719f, -44.697f, -44.336f, -43.134f, -43.222f, + -42.894f, -43.366f, -40.697f, -38.398f, -34.144f, -32.501f, -34.244f, -32.429f, -31.427f, + -28.793f, -27.154f, -24.683f, -22.018f, -19.722f, -18.023f, -16.044f, -16.022f, -15.495f, + -15.024f, -15.843f, -15.973f, -16.352f, -15.383f, -15.436f, -14.152f, -12.240f, -16.439f, + -17.535f, -17.898f, -19.311f, -20.137f, -21.205f, -20.083f, -22.357f, -24.373f, -23.907f, + -23.452f, -22.188f, -20.466f, -18.727f, -19.004f, -18.519f, -18.363f, -18.034f, -16.819f, + -15.098f, -13.918f, -13.982f, -11.418f, -8.112f, -6.327f, -2.586f, 0.503f, 2.344f, + 1.665f, 3.741f, 6.969f, 10.327f, 13.253f, 14.364f, 15.020f, 13.612f, 14.088f, + 13.606f}, + {-29.534f, -30.547f, -28.937f, -29.186f, -31.607f, -34.161f, -35.723f, -35.981f, -35.490f, + -37.010f, -38.278f, -35.902f, -35.430f, -35.789f, -34.753f, -34.580f, -36.492f, -34.812f, + -32.647f, -36.353f, -34.745f, -33.754f, -32.944f, -32.487f, -31.602f, -30.273f, -29.091f, + -27.531f, -25.923f, -24.632f, -23.018f, -21.568f, -19.737f, -17.255f, -14.269f, -13.034f, + -12.061f, -11.240f, -10.786f, -10.450f, -9.982f, -9.515f, -9.657f, -9.631f, -9.816f, + -10.201f, -10.678f, -10.836f, -11.272f, -11.498f, -11.732f, -11.829f, -11.774f, -11.524f, + -11.155f, -11.168f, -11.120f, -10.610f, -10.186f, -9.864f, -9.250f, -8.714f, -7.932f, + -6.878f, -5.848f, -5.213f, -4.604f, -4.007f, -3.571f, -3.246f, -2.961f, -2.729f, + -2.672f, -2.886f, -3.315f, -3.885f, -4.549f, -5.581f, -6.747f, -8.128f, -9.583f, + -11.156f, -12.758f, -13.948f, -15.241f, -16.473f, -17.760f, -19.303f, -20.716f, -22.122f, + -23.417f, -24.721f, -25.906f, -27.076f, -28.518f, -30.084f, -31.372f, -32.780f, -34.094f, + -35.446f, -36.774f, -37.963f, -39.181f, -40.043f, -40.543f, -41.067f, -41.574f, -42.207f, + -42.420f, -42.795f, -43.011f, -43.110f, -43.302f, -43.139f, -42.729f, -42.576f, -41.754f, + -42.586f, -37.387f, -37.795f, -34.618f, -34.869f, -35.331f, -34.136f, -32.594f, -30.368f, + -28.741f, -26.574f, -24.007f, -20.946f, -19.352f, -17.096f, -15.040f, -14.916f, -13.119f, + -14.016f, -14.887f, -15.090f, -15.403f, -15.312f, -14.147f, -13.466f, -15.499f, -17.815f, + -18.646f, -19.003f, -20.045f, -21.713f, -22.898f, -21.228f, -24.236f, -26.227f, -25.922f, + -25.296f, -23.361f, -21.530f, -19.660f, -19.988f, -20.734f, -19.416f, -18.038f, -17.170f, + -16.243f, -14.947f, -14.932f, -11.427f, -7.954f, -6.891f, -2.695f, 0.504f, 3.179f, + 2.033f, 3.785f, 7.086f, 10.535f, 13.376f, 14.457f, 15.070f, 13.633f, 14.126f, + 13.606f}, + {-29.534f, -30.541f, -28.887f, -29.246f, -31.980f, -34.423f, -35.536f, -35.376f, -35.086f, + -36.689f, -38.412f, -35.816f, -35.306f, -35.571f, -33.071f, -33.236f, -34.894f, -34.272f, + -32.595f, -35.581f, -34.453f, -33.549f, -32.265f, -31.867f, -31.072f, -30.010f, -28.650f, + -27.205f, -25.725f, -24.437f, -23.196f, -22.044f, -19.042f, -17.408f, -14.408f, -13.065f, + -12.246f, -11.346f, -10.994f, -10.418f, -9.996f, -9.409f, -9.432f, -9.463f, -9.725f, + -10.023f, -10.351f, -10.628f, -10.894f, -11.132f, -11.347f, -11.490f, -11.362f, -11.205f, + -10.796f, -11.031f, -10.896f, -10.325f, -10.007f, -9.476f, -9.004f, -8.375f, -7.452f, + -6.390f, -5.661f, -5.219f, -4.492f, -3.796f, -3.278f, -3.004f, -2.703f, -2.427f, + -2.354f, -2.570f, -2.982f, -3.542f, -4.215f, -5.232f, -6.361f, -7.559f, -8.949f, + -10.565f, -12.140f, -13.659f, -14.905f, -16.210f, -17.508f, -18.879f, -20.248f, -21.618f, + -22.804f, -24.144f, -25.250f, -26.500f, -27.965f, -29.473f, -30.719f, -32.120f, -33.274f, + -34.413f, -35.668f, -36.627f, -37.746f, -38.561f, -38.919f, -39.494f, -39.759f, -40.476f, + -40.844f, -41.228f, -41.478f, -41.757f, -41.883f, -41.746f, -41.608f, -41.265f, -41.269f, + -37.749f, -37.482f, -35.285f, -36.520f, -35.721f, -34.478f, -32.773f, -31.351f, -29.419f, + -27.302f, -25.644f, -22.832f, -20.550f, -19.121f, -17.492f, -14.571f, -13.664f, -11.491f, + -13.005f, -13.375f, -14.396f, -15.096f, -14.701f, -15.554f, -16.846f, -18.130f, -19.590f, + -20.116f, -20.482f, -20.974f, -22.074f, -23.835f, -24.222f, -26.186f, -27.857f, -27.691f, + -26.527f, -24.183f, -22.335f, -21.264f, -21.720f, -23.396f, -20.349f, -18.443f, -17.315f, + -17.221f, -16.133f, -15.275f, -11.582f, -7.995f, -7.327f, -2.865f, 0.194f, 3.949f, + 2.504f, 3.931f, 7.234f, 10.729f, 13.479f, 14.548f, 15.100f, 13.655f, 14.165f, + 13.606f}, + {-29.534f, -30.534f, -28.841f, -29.303f, -32.279f, -34.578f, -35.272f, -34.679f, -34.635f, + -36.402f, -38.407f, -35.737f, -34.864f, -35.332f, -31.775f, -32.161f, -33.414f, -33.826f, + -32.509f, -34.845f, -34.148f, -33.452f, -31.596f, -31.327f, -30.441f, -29.508f, -28.192f, + -26.804f, -25.560f, -24.315f, -23.007f, -22.294f, -19.132f, -16.876f, -14.512f, -13.342f, + -12.296f, -11.469f, -11.139f, -10.403f, -10.150f, -9.485f, -9.391f, -9.395f, -9.527f, + -9.803f, -10.144f, -10.350f, -10.576f, -10.849f, -10.988f, -11.132f, -10.862f, -10.702f, + -10.813f, -10.823f, -10.370f, -10.033f, -9.669f, -9.187f, -8.752f, -7.997f, -6.827f, + -6.093f, -5.510f, -4.990f, -4.366f, -3.873f, -3.239f, -2.805f, -2.404f, -2.132f, + -2.066f, -2.315f, -2.808f, -3.358f, -4.062f, -5.036f, -6.103f, -7.242f, -8.520f, + -10.059f, -11.576f, -13.423f, -14.698f, -15.821f, -17.112f, -18.418f, -19.735f, -20.967f, + -22.163f, -23.507f, -24.611f, -25.903f, -27.200f, -28.604f, -29.916f, -31.217f, -32.155f, + -33.249f, -34.305f, -35.367f, -36.429f, -36.935f, -37.417f, -37.837f, -38.284f, -38.590f, + -39.055f, -39.250f, -39.651f, -39.998f, -40.099f, -40.164f, -40.513f, -39.311f, -37.186f, + -37.388f, -35.111f, -36.666f, -35.438f, -34.382f, -32.646f, -31.894f, -30.193f, -26.831f, + -24.706f, -23.192f, -21.271f, -20.497f, -18.692f, -17.349f, -14.739f, -12.971f, -11.183f, + -11.080f, -12.018f, -12.718f, -12.981f, -14.471f, -16.874f, -17.504f, -19.459f, -20.773f, + -21.657f, -21.762f, -22.504f, -23.237f, -24.472f, -26.877f, -28.055f, -29.239f, -28.653f, + -27.362f, -25.288f, -23.587f, -22.558f, -23.414f, -25.166f, -20.928f, -19.184f, -17.635f, + -18.149f, -17.311f, -15.479f, -11.798f, -8.438f, -7.597f, -2.982f, -0.283f, 4.489f, + 3.067f, 4.157f, 7.406f, 10.912f, 13.564f, 14.633f, 15.114f, 13.677f, 14.205f, + 13.606f}, + {-29.534f, -30.526f, -28.799f, -29.345f, -32.447f, -34.555f, -34.890f, -33.929f, -34.169f, + -36.113f, -38.204f, -35.503f, -34.276f, -35.022f, -31.506f, -31.186f, -32.231f, -33.473f, + -31.999f, -34.492f, -33.642f, -32.957f, -31.459f, -30.621f, -29.832f, -28.904f, -27.645f, + -26.315f, -25.410f, -24.204f, -22.768f, -22.129f, -19.340f, -16.694f, -14.464f, -13.448f, + -12.191f, -11.687f, -11.345f, -10.716f, -10.408f, -9.624f, -9.555f, -9.474f, -9.564f, + -9.763f, -9.947f, -10.120f, -10.337f, -10.570f, -10.727f, -10.702f, -10.469f, -10.373f, + -10.512f, -10.442f, -10.156f, -9.661f, -9.238f, -8.877f, -8.358f, -7.759f, -6.763f, + -5.767f, -5.175f, -4.610f, -4.184f, -3.765f, -3.228f, -2.682f, -2.238f, -2.009f, + -2.049f, -2.264f, -2.701f, -3.288f, -3.923f, -4.884f, -5.880f, -7.047f, -8.304f, + -9.670f, -11.117f, -12.607f, -14.144f, -15.534f, -16.669f, -17.943f, -19.267f, -20.510f, + -21.686f, -22.925f, -23.929f, -25.205f, -26.558f, -27.746f, -28.978f, -30.048f, -30.906f, + -31.918f, -32.741f, -33.679f, -34.585f, -35.314f, -35.884f, -35.977f, -36.471f, -36.638f, + -36.980f, -37.262f, -37.646f, -38.073f, -38.166f, -38.650f, -36.864f, -36.638f, -36.266f, + -35.725f, -35.914f, -34.543f, -32.916f, -32.218f, -31.158f, -30.714f, -28.836f, -24.669f, + -23.479f, -22.638f, -18.959f, -18.290f, -17.721f, -16.912f, -14.530f, -11.866f, -10.896f, + -9.422f, -11.668f, -12.827f, -13.982f, -14.551f, -17.534f, -18.714f, -19.682f, -21.785f, + -22.915f, -23.365f, -23.670f, -25.098f, -26.290f, -28.679f, -29.440f, -30.099f, -29.475f, + -28.429f, -27.000f, -25.140f, -23.878f, -24.683f, -26.392f, -21.645f, -20.370f, -18.877f, + -19.282f, -18.391f, -15.941f, -12.109f, -9.205f, -7.779f, -3.131f, -0.742f, 4.679f, + 3.674f, 4.419f, 7.597f, 11.095f, 13.637f, 14.710f, 15.113f, 13.704f, 14.245f, + 13.606f}, + {-29.534f, -30.516f, -28.761f, -29.363f, -32.444f, -34.313f, -34.375f, -33.175f, -33.730f, + -35.758f, -37.790f, -35.090f, -33.883f, -34.773f, -31.987f, -30.342f, -31.305f, -33.010f, + -31.529f, -34.013f, -33.163f, -32.408f, -31.162f, -29.801f, -29.049f, -28.292f, -27.164f, + -25.992f, -25.168f, -24.026f, -22.655f, -21.402f, -19.256f, -16.402f, -14.379f, -13.393f, + -12.376f, -11.683f, -11.535f, -10.930f, -10.563f, -9.795f, -9.604f, -9.533f, -9.637f, + -9.751f, -9.889f, -9.971f, -10.127f, -10.275f, -10.484f, -10.370f, -10.035f, -10.003f, + -10.135f, -10.147f, -10.082f, -9.593f, -8.963f, -8.633f, -8.062f, -7.358f, -6.442f, + -5.419f, -4.975f, -4.651f, -4.216f, -3.732f, -3.120f, -2.619f, -2.245f, -2.034f, + -2.051f, -2.282f, -2.773f, -3.296f, -3.969f, -4.749f, -5.701f, -6.893f, -8.052f, + -9.388f, -10.844f, -12.164f, -13.368f, -14.871f, -16.357f, -17.545f, -18.840f, -19.966f, + -21.099f, -22.152f, -23.150f, -24.475f, -25.641f, -26.715f, -27.767f, -28.605f, -29.454f, + -30.115f, -31.049f, -31.774f, -32.868f, -33.299f, -33.708f, -33.871f, -34.476f, -34.818f, + -35.127f, -34.968f, -35.724f, -36.139f, -36.568f, -36.529f, -35.354f, -34.142f, -35.306f, + -35.627f, -33.864f, -32.755f, -31.498f, -30.344f, -29.662f, -29.135f, -26.387f, -24.286f, + -23.496f, -23.044f, -20.545f, -17.789f, -16.281f, -13.973f, -13.594f, -10.674f, -9.262f, + -8.557f, -11.244f, -11.543f, -14.267f, -15.125f, -17.352f, -18.799f, -20.001f, -21.919f, + -23.481f, -24.408f, -25.255f, -26.358f, -28.239f, -29.928f, -30.362f, -30.959f, -30.378f, + -29.080f, -28.177f, -26.480f, -25.209f, -26.011f, -27.907f, -23.400f, -22.347f, -21.034f, + -20.276f, -19.249f, -16.404f, -12.557f, -9.859f, -7.923f, -3.464f, -1.070f, 4.522f, + 4.266f, 4.672f, 7.802f, 11.289f, 13.706f, 14.779f, 15.103f, 13.735f, 14.286f, + 13.606f}, + {-29.534f, -30.504f, -28.728f, -29.348f, -32.255f, -33.850f, -33.747f, -32.452f, -33.336f, + -35.265f, -37.180f, -34.633f, -33.840f, -34.715f, -32.377f, -29.751f, -30.622f, -32.376f, + -31.137f, -32.950f, -32.843f, -31.985f, -30.474f, -29.117f, -28.399f, -27.648f, -26.667f, + -25.707f, -24.872f, -23.637f, -22.560f, -20.448f, -18.716f, -16.130f, -14.479f, -13.480f, + -12.395f, -11.766f, -11.701f, -10.858f, -10.620f, -9.936f, -9.753f, -9.583f, -9.561f, + -9.692f, -9.768f, -9.939f, -10.056f, -10.287f, -10.317f, -10.280f, -9.995f, -9.866f, + -9.884f, -9.809f, -9.511f, -9.336f, -8.894f, -8.438f, -7.859f, -6.943f, -6.022f, + -5.243f, -4.840f, -4.597f, -4.102f, -3.661f, -3.088f, -2.667f, -2.311f, -2.184f, + -2.201f, -2.409f, -2.848f, -3.339f, -4.035f, -4.737f, -5.705f, -6.768f, -7.832f, + -9.180f, -10.525f, -11.817f, -13.067f, -14.297f, -15.893f, -17.111f, -18.397f, -19.485f, + -20.424f, -21.439f, -22.526f, -23.551f, -24.654f, -25.532f, -26.222f, -27.082f, -28.094f, + -28.574f, -29.057f, -30.188f, -30.840f, -31.485f, -32.024f, -32.351f, -32.815f, -33.024f, + -33.349f, -33.674f, -33.938f, -34.202f, -34.610f, -33.071f, -32.610f, -35.104f, -34.535f, + -33.150f, -31.789f, -31.051f, -29.825f, -28.380f, -28.153f, -27.515f, -24.322f, -24.452f, + -21.204f, -21.541f, -19.780f, -20.195f, -18.435f, -12.887f, -14.279f, -10.103f, -7.904f, + -7.482f, -11.122f, -11.879f, -14.565f, -16.155f, -17.374f, -19.052f, -19.551f, -22.040f, + -24.009f, -25.146f, -27.033f, -27.649f, -29.170f, -31.059f, -31.046f, -31.667f, -31.316f, + -29.993f, -29.015f, -27.900f, -26.769f, -27.586f, -29.326f, -26.025f, -24.836f, -23.116f, + -20.819f, -19.800f, -16.627f, -13.096f, -10.041f, -8.003f, -3.961f, -1.258f, 4.132f, + 4.800f, 4.894f, 8.015f, 11.503f, 13.781f, 14.839f, 15.087f, 13.773f, 14.327f, + 13.606f}, + {-29.534f, -30.491f, -28.700f, -29.297f, -31.889f, -33.203f, -33.053f, -31.776f, -32.975f, + -34.606f, -36.403f, -34.300f, -34.017f, -34.701f, -32.078f, -29.261f, -30.211f, -31.817f, + -30.615f, -32.152f, -32.666f, -31.496f, -30.111f, -28.665f, -27.698f, -27.020f, -26.168f, + -25.290f, -24.429f, -22.984f, -22.274f, -19.578f, -18.463f, -16.044f, -14.515f, -13.447f, + -12.425f, -11.920f, -11.613f, -10.803f, -10.688f, -10.049f, -9.948f, -9.549f, -9.523f, + -9.671f, -9.712f, -9.802f, -9.945f, -10.127f, -10.267f, -10.112f, -9.855f, -9.839f, + -9.735f, -9.588f, -9.131f, -9.068f, -8.724f, -8.220f, -7.563f, -6.695f, -5.919f, + -4.978f, -4.709f, -4.454f, -4.066f, -3.553f, -3.039f, -2.770f, -2.525f, -2.405f, + -2.359f, -2.580f, -3.060f, -3.389f, -4.183f, -4.882f, -5.890f, -6.894f, -7.981f, + -9.160f, -10.405f, -11.650f, -12.873f, -14.028f, -15.549f, -16.830f, -17.893f, -18.921f, + -19.809f, -20.652f, -21.779f, -22.718f, -23.649f, -24.343f, -24.997f, -25.679f, -26.555f, + -26.935f, -26.935f, -28.393f, -28.957f, -29.701f, -29.830f, -30.569f, -30.638f, -31.449f, + -31.666f, -31.692f, -32.142f, -32.234f, -32.555f, -32.913f, -33.243f, -32.632f, -31.417f, + -30.578f, -29.142f, -28.589f, -27.914f, -27.405f, -26.793f, -26.000f, -23.169f, -23.080f, + -20.373f, -21.308f, -19.390f, -17.917f, -16.662f, -14.122f, -13.550f, -10.136f, -9.767f, + -11.822f, -12.677f, -12.451f, -14.663f, -16.312f, -17.322f, -19.620f, -20.016f, -22.022f, + -24.617f, -26.025f, -28.251f, -29.041f, -30.096f, -32.177f, -31.838f, -32.281f, -32.401f, + -30.993f, -30.171f, -29.337f, -28.654f, -29.505f, -30.356f, -28.424f, -26.921f, -24.263f, + -21.294f, -20.089f, -16.799f, -13.603f, -9.865f, -7.944f, -4.393f, -1.351f, 3.657f, + 5.261f, 5.097f, 8.226f, 11.737f, 13.870f, 14.893f, 15.069f, 13.819f, 14.369f, + 13.606f}, + {-29.534f, -30.476f, -28.675f, -29.211f, -31.375f, -32.437f, -32.357f, -31.152f, -32.607f, + -33.832f, -35.491f, -34.138f, -34.179f, -34.412f, -31.190f, -28.628f, -29.841f, -31.361f, + -30.249f, -31.771f, -32.476f, -31.018f, -29.813f, -28.505f, -27.113f, -26.429f, -25.711f, + -24.856f, -23.833f, -22.303f, -21.497f, -19.382f, -17.994f, -15.814f, -14.448f, -13.425f, + -12.559f, -12.102f, -11.544f, -10.876f, -10.741f, -10.100f, -9.866f, -9.662f, -9.474f, + -9.399f, -9.405f, -9.499f, -9.809f, -9.855f, -10.040f, -10.033f, -9.852f, -9.864f, + -9.595f, -9.437f, -8.913f, -8.780f, -8.454f, -7.961f, -7.290f, -6.439f, -5.563f, + -4.771f, -4.559f, -4.244f, -3.911f, -3.610f, -3.200f, -2.815f, -2.742f, -2.583f, + -2.662f, -2.694f, -3.204f, -3.578f, -4.326f, -5.117f, -6.087f, -7.130f, -8.167f, + -9.231f, -10.256f, -11.545f, -12.771f, -13.846f, -15.294f, -16.414f, -17.488f, -18.385f, + -19.172f, -20.223f, -20.973f, -21.824f, -22.543f, -23.244f, -23.801f, -24.541f, -25.030f, + -25.100f, -25.504f, -26.356f, -26.965f, -27.528f, -27.771f, -28.615f, -29.218f, -29.587f, + -29.890f, -30.316f, -30.325f, -30.571f, -31.033f, -31.116f, -30.387f, -29.789f, -28.713f, + -27.151f, -24.948f, -24.921f, -25.061f, -25.780f, -25.647f, -23.853f, -22.340f, -20.846f, + -21.433f, -20.511f, -16.768f, -16.628f, -15.633f, -15.563f, -14.352f, -13.595f, -12.816f, + -11.195f, -13.909f, -14.184f, -15.929f, -16.665f, -17.412f, -19.969f, -20.646f, -22.334f, + -25.077f, -26.968f, -28.957f, -29.458f, -30.518f, -32.925f, -32.631f, -33.051f, -33.514f, + -32.429f, -32.087f, -31.311f, -30.340f, -31.333f, -31.172f, -29.823f, -27.923f, -24.578f, + -21.824f, -20.092f, -17.020f, -13.940f, -9.732f, -7.678f, -4.527f, -1.362f, 3.184f, + 5.642f, 5.313f, 8.421f, 11.981f, 13.977f, 14.944f, 15.053f, 13.875f, 14.412f, + 13.606f}, + {-29.534f, -30.460f, -28.654f, -29.091f, -30.763f, -31.629f, -31.720f, -30.581f, -32.190f, + -33.063f, -34.490f, -33.991f, -34.173f, -33.728f, -30.236f, -27.883f, -29.189f, -30.563f, + -29.985f, -30.367f, -31.952f, -30.635f, -29.385f, -28.233f, -26.762f, -25.976f, -25.269f, + -24.223f, -23.307f, -21.738f, -20.663f, -19.552f, -17.368f, -15.593f, -14.356f, -13.343f, + -12.570f, -12.081f, -11.413f, -11.010f, -10.615f, -10.260f, -9.780f, -9.441f, -9.284f, + -9.081f, -9.119f, -9.295f, -9.412f, -9.605f, -9.758f, -9.705f, -9.678f, -9.537f, + -9.164f, -9.262f, -8.588f, -8.345f, -8.054f, -7.591f, -7.063f, -6.141f, -5.312f, + -4.528f, -4.106f, -3.871f, -3.855f, -3.575f, -3.266f, -3.052f, -2.907f, -2.754f, + -2.876f, -3.103f, -3.327f, -3.946f, -4.669f, -5.416f, -6.397f, -7.426f, -8.447f, + -9.360f, -10.405f, -11.477f, -12.522f, -13.693f, -14.985f, -16.136f, -17.065f, -17.904f, + -18.719f, -19.390f, -20.051f, -20.796f, -21.425f, -22.067f, -22.613f, -23.134f, -23.392f, + -23.466f, -23.916f, -24.194f, -24.832f, -25.251f, -25.459f, -26.013f, -26.494f, -26.949f, + -27.634f, -27.994f, -29.049f, -30.165f, -29.030f, -28.493f, -27.386f, -26.463f, -24.374f, + -23.668f, -23.528f, -23.793f, -25.147f, -25.529f, -24.928f, -23.945f, -22.867f, -22.109f, + -20.048f, -18.577f, -15.116f, -14.447f, -13.011f, -11.549f, -13.445f, -12.496f, -10.207f, + -13.699f, -14.745f, -14.644f, -16.236f, -16.977f, -18.851f, -20.971f, -21.550f, -23.324f, + -25.902f, -27.670f, -29.095f, -29.808f, -31.628f, -33.303f, -33.966f, -33.982f, -34.307f, + -33.828f, -33.627f, -33.250f, -31.737f, -32.212f, -31.693f, -30.393f, -28.025f, -24.637f, + -21.916f, -19.892f, -17.107f, -14.051f, -9.817f, -7.213f, -4.349f, -1.227f, 2.718f, + 5.922f, 5.587f, 8.589f, 12.219f, 14.103f, 14.995f, 15.041f, 13.940f, 14.455f, + 13.606f}, + {-29.534f, -30.442f, -28.637f, -28.944f, -30.112f, -30.860f, -31.190f, -30.075f, -31.707f, + -32.424f, -33.470f, -33.618f, -33.915f, -32.883f, -29.549f, -27.234f, -28.424f, -29.337f, + -29.234f, -28.127f, -31.243f, -30.174f, -29.016f, -27.622f, -26.254f, -25.517f, -24.735f, + -23.745f, -22.794f, -21.448f, -20.136f, -18.981f, -17.010f, -15.574f, -14.374f, -13.314f, + -12.410f, -11.856f, -11.149f, -11.107f, -10.441f, -10.212f, -9.635f, -9.317f, -9.008f, + -8.873f, -9.022f, -8.960f, -9.175f, -9.185f, -9.368f, -9.502f, -9.453f, -9.109f, + -8.942f, -8.787f, -8.280f, -7.989f, -7.820f, -7.215f, -6.716f, -5.892f, -4.938f, + -3.984f, -3.725f, -3.489f, -3.616f, -3.500f, -3.181f, -3.075f, -3.047f, -2.972f, + -3.213f, -3.441f, -3.573f, -4.504f, -5.080f, -6.031f, -6.858f, -7.861f, -8.879f, + -9.700f, -10.627f, -11.676f, -12.613f, -13.530f, -14.729f, -15.843f, -16.662f, -17.468f, + -18.191f, -18.601f, -19.079f, -19.541f, -20.272f, -20.759f, -21.198f, -21.616f, -21.809f, + -21.686f, -22.078f, -22.106f, -22.455f, -22.794f, -23.176f, -23.479f, -23.556f, -24.047f, + -24.737f, -27.938f, -29.377f, -27.966f, -25.320f, -25.251f, -22.359f, -21.864f, -21.477f, + -23.130f, -23.857f, -24.518f, -24.540f, -24.484f, -24.176f, -22.316f, -21.062f, -19.937f, + -18.862f, -17.033f, -16.198f, -13.719f, -12.278f, -10.703f, -11.795f, -13.632f, -14.641f, + -14.833f, -15.858f, -15.835f, -16.733f, -17.176f, -19.427f, -21.045f, -21.880f, -23.649f, + -25.772f, -28.199f, -29.131f, -29.886f, -32.336f, -33.960f, -35.114f, -35.235f, -35.338f, + -34.678f, -34.121f, -33.864f, -32.899f, -32.754f, -32.304f, -30.797f, -27.993f, -24.720f, + -21.769f, -19.966f, -17.042f, -13.995f, -9.908f, -6.719f, -4.062f, -0.857f, 2.241f, + 6.066f, 5.950f, 8.728f, 12.434f, 14.245f, 15.050f, 15.036f, 14.018f, 14.499f, + 13.606f}, + {-29.534f, -30.422f, -28.622f, -28.781f, -29.480f, -30.191f, -30.783f, -29.660f, -31.184f, + -31.963f, -32.518f, -32.912f, -33.349f, -32.172f, -29.041f, -26.764f, -27.995f, -28.181f, + -28.042f, -27.042f, -30.667f, -29.486f, -28.491f, -27.153f, -25.900f, -25.091f, -24.221f, + -23.288f, -22.249f, -21.331f, -19.893f, -18.127f, -16.893f, -15.262f, -14.154f, -13.051f, + -11.961f, -11.768f, -11.332f, -10.873f, -10.362f, -10.106f, -9.476f, -9.155f, -8.847f, + -8.530f, -8.820f, -8.701f, -8.934f, -8.758f, -8.948f, -9.065f, -9.077f, -8.775f, + -8.317f, -8.153f, -7.874f, -7.546f, -7.466f, -6.877f, -6.340f, -5.689f, -4.583f, + -3.609f, -3.353f, -3.140f, -3.226f, -3.284f, -3.087f, -3.118f, -3.197f, -3.302f, + -3.475f, -3.452f, -4.580f, -5.069f, -5.632f, -6.539f, -7.615f, -8.525f, -9.369f, + -10.184f, -10.935f, -11.965f, -12.884f, -13.636f, -14.563f, -15.559f, -16.326f, -16.988f, + -17.555f, -17.942f, -18.231f, -18.670f, -19.155f, -19.428f, -19.673f, -19.856f, -20.043f, + -19.926f, -20.050f, -20.093f, -20.282f, -20.487f, -20.820f, -21.005f, -21.217f, -21.824f, + -22.910f, -24.708f, -20.856f, -21.793f, -22.394f, -20.852f, -19.306f, -20.632f, -21.049f, + -22.164f, -23.314f, -23.777f, -24.008f, -23.908f, -23.456f, -22.441f, -22.942f, -21.938f, + -18.673f, -17.291f, -17.370f, -15.962f, -17.207f, -15.133f, -13.697f, -15.003f, -14.572f, + -14.621f, -15.852f, -16.314f, -17.242f, -17.811f, -19.333f, -20.893f, -22.298f, -24.486f, + -26.265f, -28.848f, -29.732f, -31.051f, -32.721f, -34.799f, -35.865f, -36.937f, -36.738f, + -36.202f, -35.067f, -34.444f, -34.183f, -33.766f, -33.052f, -31.272f, -28.302f, -24.948f, + -22.231f, -20.472f, -16.942f, -13.827f, -9.739f, -6.464f, -3.868f, -0.250f, 1.796f, + 6.058f, 6.422f, 8.853f, 12.614f, 14.398f, 15.112f, 15.040f, 14.106f, 14.544f, + 13.606f}, + {-29.534f, -30.401f, -28.609f, -28.613f, -28.923f, -29.660f, -30.488f, -29.372f, -30.679f, + -31.607f, -31.696f, -32.017f, -32.539f, -31.633f, -28.498f, -26.427f, -27.770f, -27.159f, + -26.951f, -26.959f, -30.041f, -28.689f, -28.031f, -26.939f, -25.488f, -24.538f, -23.802f, + -22.844f, -21.794f, -20.803f, -19.535f, -17.233f, -16.115f, -14.606f, -13.657f, -12.625f, + -11.924f, -11.597f, -10.988f, -10.629f, -10.231f, -9.725f, -9.359f, -8.945f, -8.635f, + -8.368f, -8.322f, -8.424f, -8.589f, -8.476f, -8.357f, -8.492f, -8.695f, -8.436f, + -7.962f, -7.428f, -7.457f, -7.320f, -7.112f, -6.585f, -6.025f, -5.345f, -4.425f, + -3.421f, -2.948f, -2.921f, -3.070f, -3.200f, -3.129f, -3.239f, -3.424f, -3.589f, + -3.712f, -4.170f, -4.978f, -5.631f, -6.404f, -7.396f, -8.507f, -9.453f, -10.196f, + -10.702f, -11.428f, -12.298f, -13.060f, -13.773f, -14.512f, -15.329f, -16.047f, -16.560f, + -16.983f, -17.352f, -17.591f, -17.706f, -17.968f, -17.941f, -18.004f, -18.170f, -18.182f, + -18.075f, -18.026f, -18.016f, -18.114f, -18.172f, -18.384f, -18.663f, -19.345f, -19.572f, + -23.410f, -19.195f, -15.905f, -18.418f, -18.080f, -17.688f, -18.293f, -19.664f, -20.582f, + -21.350f, -21.887f, -22.595f, -22.479f, -23.034f, -26.447f, -23.523f, -23.945f, -23.942f, + -20.602f, -19.775f, -21.326f, -19.635f, -19.194f, -18.207f, -17.907f, -15.136f, -12.935f, + -15.451f, -15.706f, -15.929f, -17.670f, -18.618f, -19.600f, -21.153f, -22.939f, -25.128f, + -27.277f, -29.489f, -30.657f, -32.277f, -33.749f, -35.279f, -37.152f, -38.416f, -38.447f, + -37.955f, -37.035f, -35.819f, -35.511f, -34.699f, -33.462f, -31.525f, -28.727f, -25.443f, + -23.070f, -20.643f, -16.694f, -13.517f, -9.303f, -6.565f, -3.808f, 0.425f, 1.508f, + 5.930f, 7.001f, 8.998f, 12.757f, 14.555f, 15.182f, 15.053f, 14.206f, 14.589f, + 13.606f}, + {-29.534f, -30.378f, -28.597f, -28.450f, -28.480f, -29.270f, -30.268f, -29.235f, -30.262f, + -31.204f, -30.985f, -31.194f, -31.753f, -31.105f, -27.912f, -26.183f, -27.201f, -25.948f, + -25.965f, -26.069f, -29.253f, -28.081f, -27.597f, -26.766f, -25.090f, -23.995f, -23.190f, + -22.473f, -21.273f, -20.129f, -18.908f, -16.624f, -15.508f, -13.816f, -12.988f, -12.180f, + -11.843f, -11.157f, -10.606f, -10.299f, -9.811f, -9.453f, -9.165f, -8.557f, -8.289f, + -7.959f, -7.995f, -7.954f, -8.490f, -8.000f, -7.980f, -7.897f, -8.262f, -7.954f, + -7.565f, -6.986f, -7.062f, -6.982f, -6.824f, -6.244f, -5.612f, -5.054f, -4.005f, + -3.243f, -2.677f, -2.626f, -2.867f, -3.107f, -3.174f, -3.359f, -3.597f, -3.964f, + -4.175f, -4.473f, -5.145f, -6.044f, -7.067f, -8.006f, -9.162f, -10.098f, -11.168f, + -11.642f, -12.092f, -12.702f, -13.335f, -13.890f, -14.455f, -15.090f, -15.639f, -16.075f, + -16.465f, -16.620f, -16.783f, -16.742f, -16.784f, -16.680f, -16.590f, -16.449f, -16.310f, + -16.416f, -16.393f, -16.024f, -15.920f, -15.906f, -16.109f, -16.751f, -17.241f, -20.007f, + -18.330f, -15.972f, -14.311f, -15.055f, -15.201f, -15.591f, -16.768f, -18.539f, -20.293f, + -20.262f, -21.209f, -22.299f, -22.693f, -24.397f, -24.084f, -22.494f, -24.025f, -24.900f, + -24.016f, -22.837f, -23.212f, -22.202f, -21.011f, -19.650f, -18.833f, -17.603f, -16.704f, + -17.159f, -16.486f, -16.895f, -17.766f, -18.751f, -20.026f, -22.232f, -23.963f, -26.425f, + -29.191f, -30.547f, -31.326f, -33.015f, -34.869f, -36.286f, -38.846f, -39.423f, -40.248f, + -39.343f, -38.903f, -37.102f, -36.375f, -35.542f, -34.025f, -31.355f, -28.738f, -25.878f, + -23.178f, -19.883f, -16.185f, -13.056f, -8.774f, -6.823f, -3.808f, 0.896f, 1.516f, + 5.773f, 7.672f, 9.200f, 12.872f, 14.712f, 15.261f, 15.076f, 14.316f, 14.634f, + 13.606f}, + {-29.534f, -30.354f, -28.586f, -28.306f, -28.174f, -28.999f, -30.073f, -29.247f, -29.981f, + -30.620f, -30.270f, -30.553f, -31.266f, -30.504f, -27.402f, -25.966f, -26.269f, -24.939f, + -24.844f, -24.605f, -28.238f, -27.613f, -26.939f, -26.346f, -24.794f, -23.601f, -22.871f, + -21.926f, -20.886f, -19.559f, -18.373f, -16.226f, -14.846f, -13.376f, -12.343f, -11.815f, + -11.658f, -10.838f, -10.036f, -10.109f, -9.365f, -9.238f, -8.806f, -8.111f, -7.870f, + -7.425f, -7.467f, -7.663f, -8.170f, -7.825f, -7.723f, -7.669f, -7.775f, -7.178f, + -7.211f, -6.454f, -6.736f, -6.605f, -6.472f, -5.927f, -5.231f, -4.631f, -3.973f, + -2.992f, -2.046f, -2.329f, -2.639f, -2.949f, -3.104f, -3.433f, -3.901f, -4.135f, + -4.564f, -4.881f, -5.406f, -6.494f, -7.509f, -8.522f, -9.370f, -10.484f, -11.440f, + -12.158f, -12.911f, -13.086f, -13.727f, -14.083f, -14.443f, -14.868f, -15.216f, -15.503f, + -15.729f, -15.842f, -15.850f, -15.701f, -15.515f, -15.261f, -15.041f, -14.800f, -14.672f, + -14.847f, -14.675f, -14.133f, -13.886f, -13.873f, -14.463f, -14.763f, -15.399f, -19.008f, + -14.294f, -12.968f, -11.836f, -12.608f, -13.383f, -14.352f, -15.427f, -16.343f, -17.936f, + -20.255f, -21.017f, -21.789f, -23.968f, -24.501f, -25.723f, -24.935f, -26.177f, -26.757f, + -27.098f, -25.634f, -24.613f, -23.959f, -22.958f, -20.907f, -19.005f, -18.734f, -19.772f, + -19.522f, -19.065f, -18.729f, -18.327f, -20.026f, -21.447f, -23.045f, -24.340f, -27.388f, + -29.966f, -31.153f, -32.145f, -33.662f, -35.755f, -37.993f, -40.292f, -40.796f, -41.514f, + -40.867f, -40.242f, -38.283f, -36.989f, -36.342f, -34.869f, -31.052f, -28.210f, -25.716f, + -22.388f, -18.717f, -15.571f, -12.482f, -8.261f, -6.907f, -3.832f, 0.974f, 1.878f, + 5.698f, 8.399f, 9.485f, 12.975f, 14.866f, 15.348f, 15.107f, 14.437f, 14.680f, + 13.606f}, + {-29.534f, -30.327f, -28.574f, -28.189f, -28.010f, -28.803f, -29.860f, -29.374f, -29.841f, + -29.837f, -29.415f, -29.946f, -31.035f, -29.890f, -26.953f, -25.643f, -25.347f, -24.595f, + -23.753f, -23.901f, -26.922f, -26.813f, -26.421f, -25.648f, -24.228f, -23.162f, -22.580f, + -21.494f, -20.532f, -18.827f, -17.612f, -15.880f, -14.536f, -12.984f, -12.097f, -11.456f, + -11.057f, -10.163f, -9.839f, -9.780f, -9.144f, -8.814f, -8.236f, -7.492f, -7.319f, + -6.958f, -6.835f, -7.506f, -7.628f, -7.668f, -7.437f, -7.422f, -7.300f, -6.712f, + -6.639f, -6.169f, -6.326f, -6.305f, -6.199f, -5.633f, -4.925f, -4.214f, -3.400f, + -2.618f, -1.855f, -2.075f, -2.375f, -2.823f, -3.089f, -3.277f, -3.920f, -4.430f, + -5.035f, -5.490f, -5.601f, -6.792f, -7.672f, -8.685f, -9.572f, -10.568f, -11.762f, + -12.284f, -13.151f, -13.190f, -13.813f, -14.046f, -14.441f, -14.551f, -14.720f, -14.877f, + -14.970f, -15.031f, -14.891f, -14.624f, -14.213f, -13.862f, -13.562f, -13.250f, -13.043f, + -13.110f, -13.007f, -12.531f, -12.124f, -12.184f, -12.511f, -12.885f, -14.560f, -14.297f, + -8.504f, -10.749f, -9.508f, -11.052f, -12.173f, -13.203f, -14.209f, -14.750f, -18.739f, + -21.072f, -22.965f, -23.639f, -23.947f, -24.482f, -26.156f, -27.310f, -28.169f, -27.821f, + -28.356f, -27.567f, -25.876f, -25.242f, -24.249f, -22.431f, -20.851f, -21.115f, -23.184f, + -21.604f, -20.769f, -20.899f, -20.637f, -21.493f, -22.991f, -24.544f, -26.815f, -28.034f, + -30.458f, -31.970f, -33.354f, -34.680f, -36.573f, -39.504f, -41.093f, -41.730f, -42.415f, + -42.331f, -41.730f, -39.447f, -37.612f, -36.560f, -35.316f, -31.161f, -27.658f, -25.017f, + -21.327f, -17.715f, -14.870f, -11.739f, -7.734f, -6.699f, -3.886f, 0.735f, 2.512f, + 5.788f, 9.129f, 9.858f, 13.084f, 15.016f, 15.443f, 15.144f, 14.567f, 14.726f, + 13.606f}, + {-29.534f, -30.299f, -28.561f, -28.108f, -27.973f, -28.630f, -29.602f, -29.554f, -29.800f, + -28.976f, -28.371f, -29.158f, -30.679f, -29.264f, -26.425f, -25.162f, -24.388f, -24.208f, + -22.978f, -23.688f, -26.098f, -25.942f, -25.742f, -25.090f, -23.836f, -22.834f, -21.967f, + -20.972f, -19.988f, -18.374f, -16.932f, -15.633f, -14.134f, -12.594f, -11.949f, -11.119f, + -10.303f, -9.819f, -9.518f, -8.967f, -8.583f, -8.125f, -7.718f, -7.243f, -6.454f, + -6.642f, -6.348f, -7.111f, -7.388f, -7.439f, -7.116f, -6.938f, -6.895f, -6.181f, + -6.183f, -6.059f, -6.030f, -6.104f, -5.831f, -5.249f, -4.449f, -3.885f, -3.160f, + -2.324f, -1.979f, -1.589f, -1.896f, -2.429f, -2.924f, -3.381f, -4.009f, -4.517f, + -5.178f, -5.682f, -5.888f, -6.593f, -7.743f, -8.892f, -9.734f, -10.702f, -11.961f, + -12.591f, -13.122f, -13.357f, -13.822f, -14.278f, -14.309f, -14.286f, -14.300f, -14.303f, + -14.238f, -14.277f, -13.753f, -13.506f, -13.016f, -12.549f, -12.197f, -11.831f, -11.568f, + -11.514f, -11.611f, -11.241f, -10.407f, -10.514f, -10.658f, -11.061f, -14.293f, -8.485f, + -7.010f, -6.591f, -7.020f, -10.317f, -12.421f, -13.217f, -13.160f, -16.250f, -19.984f, + -21.983f, -24.404f, -23.903f, -23.141f, -24.099f, -26.960f, -30.097f, -29.451f, -28.250f, + -29.397f, -28.210f, -26.605f, -26.227f, -25.052f, -23.289f, -22.296f, -23.714f, -24.917f, + -22.541f, -22.183f, -22.090f, -21.999f, -21.522f, -23.789f, -26.567f, -30.026f, -29.758f, + -30.927f, -32.798f, -34.448f, -36.138f, -38.130f, -40.677f, -42.152f, -42.800f, -43.070f, + -43.434f, -42.936f, -40.302f, -38.258f, -36.629f, -35.446f, -31.611f, -27.524f, -24.172f, + -20.141f, -16.653f, -13.895f, -10.768f, -7.165f, -6.348f, -3.885f, 0.492f, 3.250f, + 6.065f, 9.791f, 10.292f, 13.212f, 15.163f, 15.541f, 15.188f, 14.704f, 14.773f, + 13.606f}, + {-29.534f, -30.270f, -28.545f, -28.067f, -28.038f, -28.432f, -29.301f, -29.717f, -29.787f, + -28.225f, -27.251f, -28.184f, -29.896f, -28.490f, -25.780f, -24.594f, -23.168f, -23.200f, + -22.525f, -23.122f, -26.254f, -25.626f, -24.863f, -24.623f, -23.336f, -22.285f, -21.369f, + -20.179f, -19.486f, -18.013f, -16.344f, -15.106f, -13.686f, -12.266f, -11.473f, -9.786f, + -9.775f, -9.469f, -9.094f, -8.202f, -8.049f, -7.357f, -7.322f, -6.826f, -5.720f, + -6.159f, -5.784f, -6.298f, -7.402f, -6.632f, -6.468f, -6.376f, -5.966f, -5.512f, + -5.709f, -5.786f, -5.804f, -5.848f, -5.593f, -4.939f, -4.129f, -3.470f, -2.874f, + -2.128f, -1.704f, -1.215f, -1.518f, -2.147f, -2.695f, -3.281f, -3.981f, -4.772f, + -5.298f, -5.912f, -6.046f, -6.732f, -7.602f, -8.844f, -9.905f, -10.898f, -11.968f, + -12.571f, -13.129f, -13.388f, -13.780f, -14.086f, -14.132f, -14.075f, -13.916f, -13.668f, + -13.482f, -13.417f, -12.809f, -12.434f, -11.849f, -11.378f, -10.957f, -10.483f, -10.320f, + -10.366f, -10.231f, -9.980f, -9.195f, -8.900f, -8.926f, -9.589f, -11.996f, -4.809f, + -5.691f, -5.209f, -5.961f, -10.042f, -14.440f, -15.582f, -17.905f, -19.374f, -23.432f, + -25.285f, -26.300f, -25.430f, -23.544f, -24.625f, -28.051f, -30.402f, -29.624f, -27.015f, + -28.748f, -29.011f, -27.084f, -26.643f, -26.179f, -24.484f, -23.694f, -25.776f, -25.330f, + -23.958f, -23.617f, -23.716f, -23.735f, -23.290f, -24.956f, -28.447f, -30.901f, -31.546f, + -32.017f, -34.070f, -35.159f, -37.836f, -39.821f, -41.855f, -42.899f, -43.942f, -43.972f, + -44.341f, -43.711f, -40.841f, -38.844f, -36.819f, -35.343f, -31.801f, -27.621f, -23.354f, + -18.930f, -15.538f, -12.891f, -9.762f, -6.625f, -5.945f, -3.598f, 0.548f, 3.947f, + 6.495f, 10.319f, 10.743f, 13.362f, 15.309f, 15.641f, 15.234f, 14.847f, 14.819f, + 13.606f}, + {-29.534f, -30.238f, -28.526f, -28.067f, -28.168f, -28.177f, -28.978f, -29.807f, -29.730f, + -27.720f, -26.262f, -27.245f, -28.828f, -27.497f, -25.151f, -23.938f, -21.913f, -22.446f, + -22.066f, -22.351f, -26.642f, -25.296f, -24.412f, -24.034f, -22.726f, -21.938f, -20.636f, + -19.503f, -18.763f, -17.349f, -15.896f, -14.434f, -13.289f, -12.041f, -11.271f, -9.967f, + -9.048f, -9.068f, -8.539f, -7.683f, -7.527f, -6.880f, -6.851f, -6.060f, -5.662f, + -5.503f, -5.438f, -5.492f, -6.222f, -4.958f, -5.748f, -5.658f, -5.269f, -4.946f, + -5.184f, -5.501f, -5.532f, -5.597f, -5.413f, -4.547f, -3.767f, -3.180f, -2.460f, + -1.740f, -1.267f, -0.938f, -1.373f, -2.079f, -2.555f, -3.174f, -3.966f, -4.781f, + -5.429f, -5.997f, -6.142f, -6.804f, -7.685f, -8.807f, -9.968f, -10.925f, -11.850f, + -12.652f, -12.986f, -13.307f, -13.824f, -13.975f, -14.074f, -13.854f, -13.448f, -13.084f, + -12.770f, -12.539f, -11.538f, -11.384f, -10.790f, -10.242f, -9.759f, -9.315f, -9.011f, + -8.995f, -9.018f, -8.780f, -8.458f, -7.629f, -7.555f, -9.416f, -7.707f, -3.399f, + -4.101f, -4.246f, -5.580f, -12.678f, -15.871f, -17.751f, -20.374f, -22.659f, -24.558f, + -26.483f, -27.929f, -27.338f, -26.719f, -27.181f, -28.489f, -29.778f, -27.266f, -27.501f, + -28.024f, -28.944f, -28.668f, -27.794f, -27.075f, -26.006f, -24.947f, -26.558f, -25.754f, + -24.647f, -25.206f, -25.302f, -24.970f, -25.304f, -26.678f, -29.648f, -32.100f, -33.113f, + -34.470f, -35.168f, -37.031f, -39.391f, -41.312f, -43.328f, -44.201f, -45.064f, -45.213f, + -44.887f, -43.823f, -41.090f, -39.193f, -36.767f, -34.940f, -31.670f, -27.592f, -22.754f, + -18.270f, -14.947f, -12.386f, -9.037f, -6.211f, -5.329f, -2.845f, 0.946f, 4.587f, + 7.030f, 10.679f, 11.167f, 13.531f, 15.454f, 15.739f, 15.284f, 14.994f, 14.866f, + 13.606f}, + {-29.534f, -30.205f, -28.503f, -28.105f, -28.327f, -27.853f, -28.672f, -29.797f, -29.585f, + -27.452f, -25.552f, -26.493f, -27.841f, -26.444f, -24.632f, -23.102f, -20.884f, -22.468f, + -21.369f, -21.806f, -27.045f, -24.813f, -23.809f, -23.112f, -22.021f, -21.305f, -20.021f, + -18.899f, -17.817f, -16.608f, -15.367f, -13.961f, -12.796f, -11.625f, -10.557f, -9.708f, + -8.842f, -8.372f, -8.150f, -7.557f, -7.038f, -6.588f, -6.770f, -5.989f, -5.396f, + -4.663f, -5.006f, -5.384f, -5.081f, -4.334f, -4.638f, -4.661f, -4.492f, -4.387f, + -4.836f, -4.861f, -5.245f, -5.072f, -4.942f, -4.267f, -3.352f, -2.682f, -1.931f, + -1.417f, -0.814f, -0.716f, -0.968f, -1.712f, -2.294f, -2.950f, -3.860f, -4.597f, + -5.404f, -5.901f, -6.283f, -6.781f, -7.763f, -8.780f, -9.896f, -10.916f, -11.760f, + -12.571f, -13.003f, -13.430f, -13.861f, -14.021f, -13.834f, -13.507f, -13.019f, -12.539f, + -12.028f, -11.693f, -10.440f, -10.454f, -9.683f, -9.195f, -8.642f, -8.149f, -7.602f, + -7.519f, -7.498f, -7.401f, -7.363f, -7.101f, -6.724f, -9.082f, -2.562f, -1.887f, + -5.795f, -6.469f, -9.682f, -15.379f, -19.342f, -21.552f, -23.399f, -22.297f, -22.696f, + -25.323f, -28.144f, -28.885f, -27.726f, -27.298f, -27.723f, -27.674f, -26.717f, -26.993f, + -28.966f, -29.679f, -29.796f, -29.588f, -27.863f, -27.177f, -25.399f, -26.161f, -26.159f, + -25.391f, -26.288f, -26.380f, -27.178f, -27.070f, -28.456f, -30.547f, -32.731f, -34.039f, + -35.882f, -37.053f, -38.359f, -40.655f, -42.590f, -44.810f, -45.593f, -46.482f, -46.299f, + -45.287f, -43.206f, -41.155f, -38.983f, -36.638f, -34.598f, -31.522f, -27.306f, -22.232f, + -18.119f, -14.731f, -12.213f, -8.569f, -5.923f, -4.348f, -1.777f, 1.454f, 5.296f, + 7.644f, 10.892f, 11.545f, 13.707f, 15.597f, 15.831f, 15.334f, 15.143f, 14.913f, + 13.606f}, + {-29.534f, -30.170f, -28.475f, -28.176f, -28.481f, -27.474f, -28.423f, -29.696f, -29.347f, + -27.286f, -25.084f, -25.765f, -26.980f, -25.547f, -24.126f, -22.187f, -19.971f, -22.241f, + -21.010f, -21.511f, -26.961f, -24.844f, -22.852f, -22.000f, -20.914f, -20.218f, -19.301f, + -18.019f, -17.048f, -15.910f, -14.414f, -13.180f, -12.077f, -11.299f, -10.579f, -9.824f, + -8.917f, -8.308f, -8.006f, -7.415f, -6.802f, -6.615f, -6.432f, -5.646f, -4.803f, + -4.036f, -4.325f, -4.902f, -4.918f, -3.832f, -3.813f, -3.996f, -3.811f, -3.931f, + -4.453f, -4.423f, -4.765f, -4.812f, -4.497f, -3.732f, -2.914f, -2.180f, -1.403f, + -0.842f, -0.484f, -0.382f, -0.696f, -1.346f, -2.004f, -2.777f, -3.690f, -4.555f, + -5.264f, -5.835f, -6.463f, -6.770f, -7.809f, -8.907f, -9.713f, -10.641f, -11.506f, + -12.391f, -13.041f, -13.562f, -13.814f, -13.823f, -13.692f, -13.200f, -12.567f, -11.986f, + -11.297f, -10.851f, -9.503f, -9.036f, -8.776f, -8.073f, -7.573f, -7.102f, -6.475f, + -6.082f, -5.877f, -6.002f, -6.128f, -5.929f, -6.172f, -9.198f, -3.420f, -6.489f, + -12.111f, -12.995f, -15.108f, -19.087f, -23.682f, -25.783f, -28.108f, -27.310f, -27.050f, + -27.982f, -27.242f, -28.275f, -28.729f, -27.709f, -26.727f, -26.530f, -28.649f, -30.050f, + -29.635f, -30.117f, -31.547f, -31.601f, -30.247f, -28.132f, -28.201f, -27.205f, -26.595f, + -26.696f, -26.759f, -26.984f, -27.290f, -28.057f, -29.196f, -31.114f, -32.691f, -34.349f, + -36.750f, -38.757f, -39.719f, -41.925f, -44.007f, -46.379f, -46.765f, -47.628f, -47.166f, + -45.396f, -42.814f, -40.852f, -38.174f, -36.242f, -34.265f, -31.381f, -26.710f, -21.124f, + -17.656f, -14.005f, -11.700f, -8.050f, -5.644f, -3.239f, -0.859f, 1.841f, 6.247f, + 8.333f, 11.033f, 11.889f, 13.881f, 15.734f, 15.916f, 15.384f, 15.292f, 14.959f, + 13.606f}, + {-29.534f, -30.133f, -28.440f, -28.272f, -28.604f, -27.076f, -28.256f, -29.536f, -29.048f, + -27.053f, -24.663f, -24.727f, -25.847f, -24.797f, -23.493f, -21.498f, -19.190f, -21.385f, + -21.654f, -21.117f, -24.734f, -24.245f, -22.182f, -21.357f, -20.214f, -19.621f, -18.294f, + -17.368f, -16.420f, -15.304f, -13.925f, -12.322f, -10.982f, -11.155f, -11.067f, -10.479f, + -9.190f, -8.193f, -7.723f, -7.357f, -6.676f, -6.263f, -5.693f, -5.008f, -3.964f, + -3.681f, -3.999f, -4.199f, -4.246f, -3.269f, -3.144f, -3.448f, -3.198f, -3.380f, + -3.982f, -3.814f, -4.316f, -4.372f, -3.987f, -3.208f, -2.478f, -1.704f, -0.873f, + -0.240f, -0.061f, -0.098f, -0.253f, -0.877f, -1.566f, -2.312f, -3.228f, -4.092f, + -4.970f, -5.808f, -6.397f, -6.971f, -7.711f, -8.615f, -9.684f, -10.570f, -11.211f, + -12.194f, -12.995f, -13.397f, -13.573f, -13.628f, -13.271f, -12.796f, -12.084f, -11.499f, + -10.732f, -10.141f, -8.532f, -7.738f, -7.788f, -6.958f, -6.398f, -5.919f, -5.367f, + -4.819f, -4.633f, -4.620f, -4.646f, -4.899f, -6.304f, -10.170f, -7.602f, -8.646f, + -11.410f, -13.345f, -19.200f, -22.105f, -25.630f, -28.832f, -31.337f, -32.330f, -32.572f, + -31.050f, -28.021f, -27.429f, -28.543f, -28.275f, -27.529f, -27.744f, -29.585f, -32.353f, + -29.862f, -30.645f, -32.308f, -32.851f, -32.077f, -30.262f, -29.094f, -29.010f, -27.722f, + -27.304f, -26.861f, -27.658f, -28.285f, -29.399f, -29.994f, -31.575f, -32.776f, -35.284f, + -37.706f, -39.796f, -41.022f, -43.092f, -45.173f, -47.777f, -47.859f, -48.272f, -47.833f, + -45.358f, -42.183f, -40.193f, -37.292f, -35.204f, -33.767f, -31.092f, -25.898f, -19.674f, + -16.816f, -12.748f, -10.850f, -7.441f, -5.223f, -2.519f, -0.503f, 2.160f, 7.516f, + 9.081f, 11.202f, 12.240f, 14.047f, 15.860f, 15.992f, 15.435f, 15.439f, 15.006f, + 13.606f}, + {-29.534f, -30.094f, -28.399f, -28.382f, -28.682f, -26.706f, -28.179f, -29.354f, -28.738f, + -26.677f, -24.110f, -23.310f, -24.177f, -23.988f, -22.790f, -21.094f, -18.774f, -20.964f, + -22.407f, -20.080f, -21.519f, -22.405f, -21.551f, -20.807f, -19.666f, -17.863f, -17.339f, + -16.698f, -15.666f, -14.632f, -13.560f, -12.346f, -10.754f, -10.750f, -10.940f, -10.390f, + -9.049f, -7.950f, -7.464f, -6.962f, -6.262f, -5.759f, -5.028f, -4.524f, -3.600f, + -3.451f, -3.579f, -3.514f, -3.560f, -2.691f, -2.599f, -2.832f, -2.750f, -2.882f, + -3.315f, -3.345f, -3.687f, -3.484f, -3.114f, -2.323f, -1.630f, -0.942f, -0.439f, + 0.041f, 0.134f, 0.318f, 0.132f, -0.623f, -1.140f, -1.880f, -2.878f, -3.796f, + -4.811f, -5.650f, -6.435f, -6.979f, -7.648f, -8.492f, -9.364f, -10.154f, -11.117f, + -12.043f, -12.772f, -13.135f, -13.345f, -13.245f, -12.793f, -12.233f, -11.460f, -10.762f, + -9.966f, -8.863f, -7.355f, -6.617f, -6.606f, -5.947f, -5.257f, -4.627f, -4.128f, + -3.486f, -3.227f, -3.142f, -3.342f, -4.056f, -9.336f, -5.231f, -6.303f, -7.178f, + -12.716f, -13.514f, -17.323f, -21.419f, -24.493f, -27.441f, -30.608f, -32.107f, -31.118f, + -30.235f, -27.152f, -26.588f, -28.501f, -28.822f, -27.055f, -27.648f, -28.527f, -31.634f, + -29.003f, -30.280f, -32.537f, -33.407f, -33.085f, -31.840f, -28.311f, -29.039f, -28.918f, + -27.710f, -27.286f, -28.889f, -29.200f, -30.555f, -31.177f, -32.609f, -33.948f, -36.362f, + -38.697f, -40.661f, -41.993f, -44.927f, -46.190f, -48.897f, -49.050f, -48.825f, -47.891f, + -45.238f, -41.318f, -39.419f, -36.598f, -34.185f, -32.961f, -30.403f, -25.242f, -19.291f, + -16.436f, -11.863f, -10.272f, -7.006f, -4.568f, -2.428f, -0.706f, 2.720f, 8.982f, + 9.824f, 11.476f, 12.644f, 14.203f, 15.971f, 16.056f, 15.487f, 15.582f, 15.052f, + 13.606f}, + {-29.534f, -30.053f, -28.351f, -28.494f, -28.712f, -26.419f, -28.176f, -29.184f, -28.460f, + -26.225f, -23.424f, -21.880f, -22.350f, -23.040f, -22.238f, -20.676f, -18.535f, -20.962f, + -21.664f, -18.476f, -20.637f, -20.901f, -20.807f, -20.001f, -19.372f, -16.793f, -16.818f, + -15.768f, -15.043f, -14.106f, -12.849f, -11.761f, -10.756f, -10.006f, -9.928f, -9.660f, + -8.320f, -7.788f, -7.211f, -6.479f, -5.811f, -5.082f, -4.294f, -3.861f, -3.247f, + -2.973f, -3.026f, -2.950f, -2.824f, -2.183f, -2.032f, -2.385f, -2.397f, -2.856f, + -3.044f, -2.964f, -3.243f, -2.897f, -2.334f, -1.564f, -0.907f, -0.292f, 0.096f, + 0.752f, 0.699f, 0.572f, 0.468f, -0.102f, -0.772f, -1.614f, -2.580f, -3.493f, + -4.479f, -5.496f, -6.350f, -6.853f, -7.477f, -8.178f, -9.186f, -10.088f, -10.932f, + -11.906f, -12.403f, -12.784f, -12.858f, -12.735f, -12.279f, -11.520f, -10.582f, -9.851f, + -8.793f, -7.343f, -6.203f, -5.466f, -5.422f, -4.964f, -4.200f, -3.309f, -2.934f, + -2.387f, -2.098f, -1.859f, -1.812f, -4.037f, -7.440f, -5.357f, -2.494f, -5.046f, + -11.244f, -11.877f, -15.978f, -20.846f, -24.203f, -26.470f, -28.209f, -30.364f, -29.432f, + -28.880f, -25.850f, -25.863f, -28.025f, -27.520f, -26.897f, -27.349f, -27.786f, -29.878f, + -29.279f, -29.843f, -32.371f, -33.411f, -32.621f, -32.421f, -32.139f, -30.253f, -29.376f, + -28.414f, -27.812f, -29.641f, -30.797f, -32.144f, -32.515f, -33.834f, -35.237f, -37.637f, + -39.484f, -41.639f, -43.007f, -46.110f, -47.116f, -49.186f, -49.501f, -49.048f, -47.934f, + -45.141f, -40.800f, -38.484f, -36.365f, -33.581f, -31.549f, -29.300f, -25.046f, -20.263f, + -16.773f, -11.712f, -10.063f, -6.718f, -3.697f, -2.638f, -1.096f, 3.753f, 10.335f, + 10.455f, 11.870f, 13.125f, 14.356f, 16.061f, 16.109f, 15.540f, 15.721f, 15.098f, + 13.606f}, + {-29.534f, -30.011f, -28.295f, -28.597f, -28.700f, -26.262f, -28.218f, -29.043f, -28.239f, + -25.859f, -22.793f, -20.868f, -21.049f, -22.125f, -21.911f, -20.088f, -18.126f, -20.034f, + -19.639f, -17.233f, -21.583f, -19.444f, -19.907f, -19.351f, -18.833f, -17.130f, -16.197f, + -15.217f, -14.504f, -13.582f, -12.240f, -11.143f, -9.951f, -9.275f, -9.146f, -8.231f, + -7.261f, -7.214f, -6.652f, -6.063f, -5.227f, -4.178f, -3.359f, -2.993f, -2.634f, + -2.354f, -2.447f, -2.323f, -2.032f, -1.779f, -1.607f, -1.874f, -2.313f, -2.705f, + -2.943f, -2.864f, -2.738f, -2.322f, -1.506f, -0.894f, 0.140f, 0.419f, 0.685f, + 0.790f, 1.042f, 1.256f, 0.738f, 0.212f, -0.571f, -1.435f, -2.473f, -3.304f, + -4.248f, -5.255f, -6.180f, -6.732f, -7.062f, -7.778f, -8.864f, -9.816f, -10.703f, + -11.383f, -11.894f, -12.309f, -12.316f, -12.075f, -11.484f, -10.685f, -9.677f, -9.599f, + -8.208f, -6.204f, -4.958f, -4.320f, -4.117f, -3.991f, -3.169f, -2.240f, -1.536f, + -1.046f, -0.712f, -0.419f, -0.733f, -5.930f, -4.189f, 0.948f, -1.508f, -4.827f, + -10.093f, -11.294f, -13.493f, -14.238f, -17.773f, -26.939f, -28.171f, -28.232f, -28.711f, + -29.177f, -25.637f, -25.353f, -27.818f, -28.003f, -26.739f, -27.128f, -27.046f, -28.485f, + -29.018f, -30.422f, -31.970f, -33.254f, -33.100f, -33.349f, -31.769f, -30.935f, -30.527f, + -31.051f, -27.562f, -28.979f, -31.572f, -33.375f, -33.968f, -34.881f, -36.467f, -38.532f, + -40.387f, -42.395f, -44.180f, -46.695f, -47.732f, -48.952f, -49.154f, -49.025f, -48.042f, + -44.871f, -40.262f, -37.880f, -36.348f, -32.787f, -30.197f, -28.309f, -25.234f, -21.205f, + -17.207f, -11.874f, -9.870f, -6.152f, -2.766f, -2.603f, -1.302f, 5.082f, 11.211f, + 10.874f, 12.326f, 13.671f, 14.511f, 16.131f, 16.152f, 15.596f, 15.852f, 15.143f, + 13.606f}, + {-29.534f, -29.967f, -28.231f, -28.679f, -28.662f, -26.269f, -28.274f, -28.941f, -28.086f, + -25.724f, -22.436f, -20.218f, -20.330f, -21.393f, -21.564f, -19.554f, -17.774f, -18.420f, + -18.008f, -16.613f, -21.642f, -17.354f, -18.675f, -18.447f, -16.879f, -15.567f, -14.887f, + -14.421f, -13.809f, -12.847f, -11.530f, -10.756f, -9.085f, -9.195f, -8.793f, -7.210f, + -6.411f, -6.490f, -6.010f, -5.182f, -4.277f, -3.123f, -2.288f, -2.065f, -2.147f, + -1.765f, -1.847f, -1.720f, -1.512f, -1.285f, -1.218f, -1.691f, -2.068f, -2.487f, + -2.847f, -2.547f, -2.264f, -1.878f, -1.061f, -0.296f, 0.494f, 1.118f, 1.292f, + 1.121f, 1.226f, 1.436f, 1.039f, 0.335f, -0.236f, -0.996f, -2.036f, -2.839f, + -3.749f, -4.752f, -5.642f, -6.217f, -6.557f, -7.353f, -8.471f, -9.346f, -10.240f, + -10.793f, -11.273f, -11.569f, -11.603f, -11.268f, -10.587f, -9.538f, -9.244f, -5.803f, + -5.959f, -4.563f, -3.925f, -3.189f, -2.926f, -2.697f, -2.057f, -1.271f, -0.447f, + 0.013f, 0.429f, 0.753f, -0.069f, -4.832f, -2.915f, 3.820f, -2.647f, -6.087f, + -8.023f, -10.023f, -11.654f, -13.279f, -16.267f, -25.388f, -28.536f, -27.377f, -28.561f, + -28.540f, -25.329f, -25.099f, -27.507f, -28.031f, -27.337f, -27.414f, -27.668f, -28.099f, + -29.044f, -30.873f, -30.795f, -32.665f, -33.235f, -33.469f, -32.904f, -32.370f, -32.905f, + -31.370f, -30.159f, -31.297f, -30.647f, -34.415f, -34.886f, -35.909f, -37.433f, -39.667f, + -41.558f, -43.388f, -45.100f, -47.127f, -48.057f, -48.637f, -48.150f, -48.183f, -47.693f, + -44.411f, -40.000f, -37.650f, -35.993f, -31.899f, -29.732f, -27.907f, -25.515f, -21.251f, + -17.110f, -11.988f, -9.731f, -5.127f, -2.019f, -2.095f, -1.231f, 6.161f, 11.379f, + 11.051f, 12.755f, 14.232f, 14.673f, 16.183f, 16.185f, 15.657f, 15.977f, 15.188f, + 13.606f}, + {-29.534f, -29.922f, -28.159f, -28.732f, -28.614f, -26.450f, -28.324f, -28.884f, -28.007f, + -25.854f, -22.420f, -19.353f, -19.350f, -20.697f, -20.909f, -19.206f, -17.706f, -17.824f, + -17.407f, -15.796f, -20.670f, -16.340f, -17.542f, -17.212f, -15.758f, -14.610f, -13.995f, + -13.363f, -12.901f, -12.174f, -11.120f, -9.937f, -8.489f, -8.616f, -7.989f, -6.195f, + -5.734f, -5.931f, -5.312f, -4.361f, -3.378f, -2.509f, -1.521f, -1.213f, -1.318f, + -1.019f, -1.217f, -1.040f, -0.931f, -0.940f, -1.121f, -1.308f, -1.804f, -2.335f, + -2.619f, -2.296f, -2.161f, -1.571f, -0.925f, -0.266f, 0.855f, 1.365f, 1.615f, + 1.718f, 1.490f, 1.821f, 1.469f, 0.740f, 0.186f, -0.684f, -1.467f, -2.325f, + -3.318f, -4.382f, -5.206f, -5.628f, -6.008f, -6.954f, -7.956f, -8.714f, -9.363f, + -9.979f, -10.300f, -10.699f, -10.555f, -10.206f, -9.495f, -8.373f, -7.978f, -3.595f, + -4.286f, -3.685f, -2.850f, -2.203f, -1.574f, -1.376f, -0.694f, 0.058f, 0.886f, + 1.317f, 1.283f, 1.603f, -2.309f, -2.850f, 0.467f, 2.127f, -1.857f, -4.754f, + -6.843f, -8.827f, -10.723f, -13.624f, -15.260f, -19.682f, -27.855f, -27.006f, -27.437f, + -27.054f, -25.779f, -24.535f, -27.256f, -28.492f, -27.164f, -27.904f, -27.286f, -28.349f, + -29.111f, -29.507f, -30.262f, -31.925f, -33.271f, -33.341f, -33.394f, -34.306f, -35.521f, + -33.788f, -31.013f, -31.699f, -33.131f, -35.250f, -35.009f, -36.989f, -38.989f, -40.700f, + -42.640f, -44.601f, -46.384f, -47.597f, -48.196f, -48.295f, -47.040f, -47.059f, -46.916f, + -44.116f, -39.909f, -37.315f, -35.612f, -31.426f, -29.761f, -27.929f, -25.671f, -20.799f, + -16.244f, -11.846f, -9.787f, -3.988f, -1.623f, -1.251f, -0.955f, 6.491f, 10.855f, + 11.074f, 13.091f, 14.742f, 14.841f, 16.224f, 16.211f, 15.725f, 16.093f, 15.231f, + 13.606f}, + {-29.534f, -29.874f, -28.080f, -28.747f, -28.574f, -26.795f, -28.364f, -28.884f, -28.015f, + -26.158f, -22.601f, -17.844f, -17.331f, -19.750f, -19.999f, -18.803f, -17.370f, -18.232f, + -17.149f, -14.702f, -19.251f, -16.327f, -16.638f, -16.339f, -15.702f, -14.684f, -13.393f, + -12.764f, -12.266f, -11.516f, -10.240f, -9.268f, -8.195f, -7.799f, -7.290f, -5.497f, + -5.265f, -5.345f, -4.811f, -3.603f, -2.654f, -1.736f, -1.140f, -0.446f, -0.488f, + -0.274f, -0.254f, -0.212f, -0.357f, -0.445f, -0.727f, -0.977f, -1.493f, -2.069f, + -2.237f, -2.160f, -1.708f, -1.165f, -0.555f, 0.225f, 0.972f, 1.667f, 2.198f, + 2.085f, 1.981f, 2.047f, 1.923f, 1.242f, 0.692f, 0.000f, -1.017f, -1.980f, + -2.866f, -3.687f, -4.499f, -5.189f, -5.652f, -6.316f, -7.037f, -7.777f, -8.469f, + -9.038f, -9.356f, -9.516f, -9.441f, -9.088f, -8.385f, -7.312f, -6.571f, -3.608f, + -3.592f, -2.755f, -1.956f, -0.989f, -0.415f, 0.231f, 0.882f, 1.477f, 2.129f, + 2.672f, 2.826f, 2.687f, -3.456f, -1.186f, 2.576f, 1.753f, -1.492f, -3.591f, + -6.263f, -7.394f, -10.087f, -12.400f, -14.823f, -15.823f, -24.407f, -28.003f, -26.206f, + -26.010f, -27.360f, -25.215f, -27.842f, -29.256f, -27.842f, -29.043f, -28.320f, -28.619f, + -29.190f, -29.006f, -30.201f, -32.271f, -32.778f, -33.030f, -33.530f, -34.796f, -36.827f, + -35.926f, -32.245f, -32.536f, -34.551f, -36.255f, -36.326f, -37.746f, -40.649f, -42.038f, + -43.831f, -45.577f, -47.537f, -48.074f, -48.677f, -48.006f, -46.226f, -46.288f, -45.726f, + -43.497f, -39.699f, -37.028f, -34.990f, -31.390f, -30.077f, -27.857f, -25.648f, -20.245f, + -14.867f, -11.318f, -9.662f, -3.021f, -1.521f, -0.175f, -0.432f, 6.028f, 9.892f, + 11.121f, 13.338f, 15.153f, 15.012f, 16.265f, 16.235f, 15.799f, 16.200f, 15.274f, + 13.606f}, + {-29.534f, -29.825f, -27.994f, -28.719f, -28.557f, -27.268f, -28.405f, -28.951f, -28.129f, + -26.490f, -22.734f, -16.121f, -14.777f, -18.572f, -19.220f, -18.167f, -16.390f, -18.082f, + -16.694f, -14.185f, -17.105f, -15.640f, -15.887f, -15.539f, -14.798f, -13.661f, -12.718f, + -12.204f, -11.925f, -10.812f, -9.455f, -8.824f, -7.554f, -7.059f, -6.705f, -5.090f, + -4.842f, -4.545f, -3.981f, -2.914f, -2.049f, -1.253f, -0.744f, 0.062f, 0.148f, + 0.429f, 0.828f, 0.799f, 0.505f, -0.072f, -0.365f, -0.514f, -1.118f, -1.651f, + -1.689f, -1.724f, -1.271f, -0.729f, -0.200f, 0.599f, 1.154f, 1.819f, 2.740f, + 2.741f, 2.495f, 2.758f, 2.291f, 1.768f, 1.226f, 0.393f, -0.401f, -1.443f, + -2.267f, -3.078f, -3.999f, -4.734f, -5.120f, -5.611f, -6.284f, -6.899f, -7.483f, + -8.019f, -8.252f, -8.202f, -8.056f, -7.635f, -6.983f, -5.987f, -5.169f, -3.112f, + -2.634f, -1.796f, -0.990f, 0.291f, 1.365f, 1.717f, 2.536f, 3.131f, 3.666f, + 4.400f, 4.240f, 1.210f, -2.449f, -0.414f, 3.642f, 2.288f, -3.105f, -5.384f, + -8.185f, -6.787f, -8.738f, -11.715f, -13.890f, -16.673f, -20.883f, -27.685f, -25.700f, + -26.092f, -30.195f, -28.908f, -27.934f, -29.481f, -28.696f, -30.020f, -28.266f, -28.418f, + -29.388f, -30.028f, -31.235f, -32.310f, -32.724f, -33.088f, -34.058f, -35.226f, -36.129f, + -36.664f, -33.865f, -35.366f, -34.803f, -37.110f, -37.890f, -39.315f, -41.772f, -43.172f, + -44.843f, -46.053f, -47.382f, -48.518f, -48.878f, -47.870f, -46.540f, -45.840f, -44.863f, + -42.770f, -39.476f, -36.871f, -34.212f, -31.841f, -30.803f, -27.745f, -25.430f, -19.578f, + -13.685f, -10.816f, -9.059f, -2.024f, -1.467f, 1.255f, 0.521f, 5.222f, 8.851f, + 11.388f, 13.581f, 15.456f, 15.177f, 16.317f, 16.261f, 15.882f, 16.299f, 15.317f, + 13.606f}, + {-29.534f, -29.775f, -27.902f, -28.646f, -28.569f, -27.818f, -28.467f, -29.081f, -28.352f, + -26.739f, -22.651f, -15.379f, -13.423f, -17.660f, -18.858f, -17.519f, -15.523f, -17.267f, + -16.065f, -14.242f, -14.743f, -14.811f, -15.243f, -14.298f, -13.839f, -12.810f, -12.173f, + -11.669f, -11.215f, -10.012f, -8.759f, -8.100f, -6.797f, -6.585f, -6.082f, -4.878f, + -4.343f, -3.921f, -2.987f, -1.993f, -1.072f, -0.697f, -0.059f, 0.576f, 0.826f, + 1.231f, 1.750f, 1.783f, 1.385f, 0.426f, 0.080f, -0.134f, -0.598f, -0.716f, + -1.163f, -0.931f, -0.590f, -0.222f, 0.197f, 0.894f, 1.613f, 2.319f, 2.857f, + 3.390f, 3.506f, 2.825f, 2.821f, 2.335f, 1.693f, 0.945f, 0.081f, -1.026f, + -1.795f, -2.548f, -3.405f, -4.303f, -4.658f, -4.869f, -5.480f, -6.028f, -6.473f, + -6.813f, -6.877f, -6.694f, -6.405f, -6.009f, -5.231f, -4.311f, -3.510f, -2.271f, + -1.592f, -0.733f, 0.092f, 1.072f, 2.908f, 3.873f, 4.252f, 4.907f, 5.283f, + 5.889f, 3.805f, -0.708f, -0.253f, 4.336f, 5.349f, 4.204f, -1.735f, -8.567f, + -10.969f, -12.327f, -12.657f, -11.306f, -13.494f, -17.786f, -22.682f, -25.695f, -25.305f, + -27.023f, -31.493f, -28.955f, -27.782f, -28.545f, -28.548f, -30.106f, -28.961f, -28.526f, + -29.797f, -31.190f, -32.447f, -33.458f, -34.039f, -34.353f, -34.260f, -34.713f, -35.792f, + -37.238f, -35.433f, -36.057f, -36.212f, -37.558f, -38.928f, -39.989f, -42.642f, -44.288f, + -45.612f, -46.543f, -47.504f, -48.525f, -48.416f, -47.814f, -46.981f, -45.667f, -44.080f, + -42.038f, -38.955f, -36.589f, -34.016f, -32.073f, -30.921f, -27.845f, -24.803f, -18.838f, + -13.146f, -10.928f, -8.340f, -0.726f, -1.233f, 3.063f, 1.969f, 4.660f, 8.052f, + 11.996f, 13.936f, 15.687f, 15.334f, 16.390f, 16.293f, 15.974f, 16.391f, 15.358f, + 13.606f}, + {-29.534f, -29.723f, -27.803f, -28.528f, -28.611f, -28.382f, -28.568f, -29.249f, -28.653f, + -26.873f, -22.377f, -16.588f, -14.703f, -17.603f, -18.835f, -17.138f, -15.564f, -16.911f, + -15.455f, -14.249f, -12.981f, -14.487f, -14.428f, -13.302f, -13.136f, -11.880f, -11.516f, + -11.163f, -10.409f, -9.199f, -7.968f, -6.921f, -6.209f, -5.995f, -4.976f, -4.296f, + -3.730f, -3.213f, -2.067f, -1.160f, -0.401f, 0.241f, 0.831f, 1.189f, 1.660f, + 2.196f, 2.627f, 2.441f, 2.190f, 1.047f, 0.398f, 0.510f, 0.107f, 0.039f, + -0.435f, -0.128f, 0.075f, 0.403f, 0.698f, 1.445f, 2.137f, 2.750f, 3.422f, + 3.758f, 3.856f, 3.449f, 3.274f, 2.837f, 2.248f, 1.385f, 0.638f, -0.079f, + -1.091f, -1.903f, -2.825f, -3.803f, -4.186f, -4.197f, -4.470f, -4.937f, -5.308f, + -5.461f, -5.373f, -5.080f, -4.599f, -4.098f, -3.439f, -2.503f, -1.781f, -1.098f, + -0.431f, 0.610f, 1.354f, 2.320f, 3.666f, 5.594f, 6.117f, 6.417f, 7.134f, + 6.275f, 6.285f, 6.036f, 5.671f, 6.801f, 5.550f, 4.284f, -0.477f, -8.584f, + -10.937f, -12.358f, -15.646f, -17.810f, -17.772f, -19.072f, -24.328f, -24.481f, -25.631f, + -29.268f, -29.546f, -27.368f, -28.102f, -28.284f, -27.953f, -30.125f, -30.067f, -29.890f, + -30.442f, -31.731f, -34.039f, -34.578f, -34.658f, -34.626f, -33.927f, -33.963f, -34.454f, + -36.119f, -35.502f, -36.753f, -37.171f, -38.081f, -39.358f, -39.920f, -42.687f, -45.085f, + -45.973f, -47.037f, -47.628f, -48.198f, -48.150f, -47.611f, -46.755f, -45.258f, -43.525f, + -41.417f, -38.259f, -35.866f, -33.967f, -31.487f, -29.513f, -27.209f, -23.593f, -18.148f, + -12.913f, -11.211f, -7.763f, 0.753f, -0.739f, 4.846f, 3.664f, 4.685f, 7.703f, + 12.934f, 14.484f, 15.911f, 15.484f, 16.492f, 16.336f, 16.075f, 16.475f, 15.397f, + 13.606f}, + {-29.534f, -29.670f, -27.700f, -28.369f, -28.675f, -28.899f, -28.708f, -29.402f, -28.958f, + -26.923f, -22.098f, -19.518f, -18.243f, -18.498f, -18.895f, -17.032f, -16.164f, -16.916f, + -14.982f, -14.122f, -11.857f, -14.012f, -13.719f, -12.802f, -12.333f, -10.970f, -10.866f, + -10.442f, -9.774f, -8.412f, -7.206f, -6.004f, -5.642f, -5.045f, -3.808f, -3.313f, + -3.158f, -2.257f, -1.139f, -0.324f, 0.394f, 1.125f, 1.559f, 2.082f, 2.373f, + 3.054f, 3.324f, 3.277f, 3.065f, 1.791f, 1.034f, 0.807f, 0.991f, 0.974f, + 0.670f, 0.929f, 1.079f, 1.495f, 1.679f, 2.102f, 2.611f, 3.162f, 4.069f, + 4.342f, 4.479f, 4.330f, 4.356f, 3.598f, 3.110f, 2.160f, 1.306f, 0.510f, + -0.290f, -1.086f, -2.078f, -2.891f, -3.488f, -3.523f, -3.476f, -3.734f, -3.957f, + -3.917f, -3.837f, -3.328f, -2.817f, -2.270f, -1.485f, -0.465f, 0.297f, 0.879f, + 0.898f, 1.944f, 2.887f, 3.873f, 4.664f, 6.066f, 7.593f, 8.474f, 9.192f, + 6.811f, 10.498f, 8.398f, 8.558f, 7.059f, 5.575f, 3.375f, -1.011f, -7.605f, + -11.698f, -13.952f, -14.806f, -19.041f, -20.411f, -22.528f, -26.143f, -27.109f, -27.861f, + -27.163f, -26.354f, -27.559f, -28.572f, -28.849f, -27.206f, -30.063f, -30.489f, -31.025f, + -30.276f, -32.102f, -34.667f, -34.915f, -34.467f, -34.044f, -34.126f, -33.787f, -33.708f, + -34.980f, -35.717f, -37.239f, -37.453f, -38.614f, -39.832f, -40.440f, -42.420f, -45.164f, + -45.702f, -46.400f, -47.718f, -47.984f, -47.601f, -46.566f, -45.479f, -44.299f, -42.748f, + -40.737f, -37.459f, -34.623f, -33.493f, -30.651f, -27.500f, -25.251f, -22.267f, -17.510f, + -12.333f, -10.413f, -6.984f, 2.204f, -0.012f, 6.021f, 5.219f, 5.291f, 7.905f, + 14.058f, 15.214f, 16.190f, 15.635f, 16.626f, 16.396f, 16.183f, 16.553f, 15.436f, + 13.606f}, + {-29.534f, -29.616f, -27.594f, -28.172f, -28.747f, -29.315f, -28.870f, -29.476f, -29.170f, + -26.935f, -22.045f, -22.759f, -22.002f, -19.737f, -18.878f, -17.019f, -16.573f, -16.416f, + -14.547f, -13.762f, -11.024f, -13.159f, -13.049f, -11.916f, -11.519f, -10.324f, -9.904f, + -9.569f, -8.837f, -7.656f, -6.575f, -5.550f, -4.732f, -3.670f, -2.976f, -2.666f, + -1.968f, -1.156f, -0.091f, 0.566f, 1.144f, 1.771f, 2.294f, 3.040f, 3.606f, + 3.886f, 4.202f, 4.301f, 3.924f, 2.740f, 2.229f, 1.979f, 2.002f, 2.056f, + 2.119f, 2.204f, 2.254f, 2.507f, 2.636f, 3.091f, 3.526f, 3.886f, 4.498f, + 5.311f, 5.270f, 4.600f, 4.476f, 4.448f, 4.030f, 3.019f, 2.341f, 1.549f, + 0.833f, -0.124f, -0.974f, -1.728f, -2.335f, -2.389f, -2.275f, -2.283f, -2.426f, + -2.189f, -1.950f, -1.676f, -1.132f, -0.436f, 0.539f, 1.537f, 2.643f, 3.536f, + 3.025f, 3.455f, 4.638f, 5.497f, 6.768f, 7.610f, 8.830f, 10.723f, 10.786f, + 10.093f, 13.705f, 8.875f, 7.289f, 5.509f, 3.445f, 1.040f, -1.643f, -5.668f, + -12.240f, -13.241f, -17.054f, -19.712f, -18.958f, -22.877f, -25.362f, -23.348f, -25.442f, + -25.039f, -24.584f, -27.915f, -28.637f, -28.609f, -27.744f, -28.620f, -30.955f, -29.739f, + -31.896f, -31.330f, -33.923f, -34.537f, -33.753f, -35.896f, -35.168f, -33.969f, -35.515f, + -36.402f, -37.496f, -37.232f, -37.385f, -38.693f, -39.938f, -41.382f, -42.867f, -44.658f, + -45.100f, -45.329f, -47.442f, -47.819f, -47.117f, -45.798f, -44.088f, -43.133f, -41.520f, + -40.030f, -36.709f, -33.332f, -32.725f, -29.632f, -26.357f, -23.597f, -21.466f, -16.747f, + -11.181f, -8.295f, -5.894f, 3.763f, 0.886f, 6.436f, 6.455f, 6.303f, 8.685f, + 15.153f, 16.023f, 16.550f, 15.803f, 16.791f, 16.476f, 16.298f, 16.627f, 15.474f, + 13.606f}, + {-29.534f, -29.561f, -27.485f, -27.944f, -28.808f, -29.592f, -29.016f, -29.414f, -29.216f, + -26.937f, -22.364f, -24.775f, -23.943f, -20.366f, -18.703f, -16.848f, -16.496f, -15.661f, + -14.023f, -13.014f, -10.312f, -12.040f, -12.072f, -10.841f, -10.579f, -9.394f, -8.873f, + -8.307f, -7.831f, -6.774f, -5.752f, -4.827f, -3.553f, -2.732f, -2.448f, -1.516f, + -0.769f, 0.036f, 0.867f, 1.565f, 2.139f, 2.646f, 3.243f, 4.154f, 4.508f, + 4.855f, 5.286f, 5.186f, 4.908f, 3.847f, 3.276f, 3.156f, 3.042f, 3.265f, + 3.389f, 3.549f, 3.290f, 3.612f, 3.646f, 4.073f, 4.657f, 4.966f, 4.988f, + 6.133f, 6.409f, 5.127f, 5.556f, 5.628f, 5.742f, 4.452f, 3.457f, 2.880f, + 2.202f, 1.353f, 0.384f, -0.074f, -0.687f, -1.027f, -0.816f, -0.572f, -0.624f, + -0.309f, -0.261f, -0.338f, -0.029f, 0.808f, 1.748f, 3.771f, 4.997f, 6.742f, + 6.166f, 5.724f, 6.504f, 7.444f, 8.504f, 9.357f, 10.021f, 10.894f, 11.912f, + 14.872f, 9.382f, 5.894f, 5.521f, 4.598f, 2.327f, -0.624f, -2.394f, -6.084f, + -12.676f, -14.300f, -17.478f, -20.276f, -16.867f, -21.691f, -24.716f, -23.219f, -24.893f, + -25.922f, -25.798f, -28.530f, -29.114f, -28.857f, -28.818f, -29.284f, -30.516f, -31.460f, + -31.908f, -31.948f, -33.544f, -34.148f, -34.417f, -35.400f, -35.723f, -35.169f, -35.443f, + -37.071f, -37.931f, -36.903f, -37.016f, -37.850f, -39.474f, -41.601f, -43.230f, -44.752f, + -44.623f, -44.757f, -46.769f, -47.546f, -46.815f, -45.612f, -43.240f, -41.695f, -40.264f, + -39.063f, -36.116f, -33.129f, -32.068f, -28.589f, -26.263f, -23.392f, -21.056f, -15.728f, + -9.887f, -6.209f, -4.968f, 5.547f, 1.840f, 6.583f, 7.512f, 7.566f, 9.984f, + 16.008f, 16.771f, 16.968f, 16.005f, 16.982f, 16.579f, 16.418f, 16.697f, 15.510f, + 13.606f}, + {-29.534f, -29.505f, -27.374f, -27.691f, -28.836f, -29.713f, -29.104f, -29.197f, -29.084f, + -26.938f, -23.038f, -25.028f, -23.573f, -19.773f, -18.323f, -16.293f, -15.777f, -15.252f, + -13.439f, -12.202f, -9.994f, -10.748f, -11.279f, -10.173f, -9.530f, -8.398f, -7.756f, + -7.082f, -6.890f, -5.996f, -5.001f, -4.019f, -2.513f, -2.061f, -1.683f, -0.938f, + 0.389f, 1.241f, 1.784f, 2.410f, 3.195f, 3.472f, 3.962f, 4.820f, 5.415f, + 5.811f, 6.328f, 6.224f, 5.897f, 5.094f, 4.465f, 4.379f, 4.187f, 4.525f, + 4.856f, 4.712f, 4.877f, 4.633f, 4.863f, 4.938f, 5.396f, 5.847f, 6.092f, + 6.802f, 6.435f, 7.747f, 6.233f, 7.024f, 6.463f, 6.289f, 5.230f, 4.431f, + 3.706f, 3.019f, 2.387f, 1.656f, 1.271f, 1.259f, 1.282f, 1.328f, 0.754f, + 0.348f, -0.200f, -1.880f, -2.859f, -1.952f, 0.079f, 3.155f, 6.263f, 8.896f, + 9.560f, 8.454f, 9.042f, 10.141f, 10.469f, 10.401f, 12.807f, 11.570f, 14.169f, + 13.263f, 6.287f, 3.364f, 3.070f, 1.887f, 0.571f, -1.169f, -3.611f, -6.824f, + -11.238f, -16.173f, -18.082f, -21.693f, -17.940f, -21.570f, -25.644f, -23.572f, -24.490f, + -25.994f, -27.664f, -29.201f, -29.424f, -29.648f, -30.738f, -31.255f, -31.056f, -33.018f, + -32.282f, -32.104f, -33.471f, -34.827f, -34.598f, -34.055f, -35.544f, -35.757f, -36.395f, + -37.379f, -37.907f, -36.853f, -37.684f, -38.385f, -38.876f, -41.188f, -43.210f, -44.873f, + -44.520f, -44.523f, -46.467f, -46.862f, -46.180f, -45.119f, -42.633f, -40.230f, -39.083f, + -38.102f, -35.295f, -33.421f, -31.242f, -28.139f, -26.437f, -23.549f, -20.484f, -14.581f, + -9.026f, -5.274f, -4.277f, 6.980f, 2.731f, 7.076f, 8.581f, 8.945f, 11.619f, + 16.492f, 17.361f, 17.384f, 16.257f, 17.190f, 16.704f, 16.540f, 16.767f, 15.544f, + 13.606f}, + {-29.534f, -29.448f, -27.264f, -27.423f, -28.812f, -29.681f, -29.092f, -28.854f, -28.837f, + -26.954f, -23.880f, -24.177f, -21.973f, -18.190f, -17.899f, -15.511f, -14.435f, -14.760f, + -12.831f, -11.435f, -9.989f, -9.452f, -10.619f, -9.503f, -8.441f, -7.209f, -6.469f, + -6.087f, -5.735f, -5.075f, -4.256f, -3.065f, -1.990f, -1.049f, -0.591f, 0.697f, + 1.686f, 2.315f, 2.805f, 3.410f, 4.065f, 4.447f, 4.776f, 5.724f, 6.623f, + 6.443f, 7.182f, 7.207f, 7.056f, 6.361f, 5.549f, 5.651f, 5.400f, 5.713f, + 6.000f, 5.968f, 6.599f, 5.529f, 6.087f, 6.379f, 6.536f, 6.537f, 6.656f, + 7.709f, 7.759f, 7.863f, 7.945f, 7.101f, 7.039f, 7.684f, 6.876f, 6.146f, + 5.443f, 5.010f, 4.526f, 4.105f, 3.500f, 3.552f, 3.410f, 2.276f, 0.387f, + -2.256f, -1.858f, 2.812f, 8.417f, 11.235f, 8.132f, 4.963f, 10.866f, 10.032f, + 8.863f, 9.541f, 11.276f, 11.834f, 13.071f, 12.147f, 12.897f, 11.754f, 15.276f, + 10.722f, 2.591f, 1.122f, 2.554f, 0.459f, -0.594f, -3.246f, -5.112f, -8.262f, + -12.137f, -16.362f, -19.107f, -22.843f, -20.041f, -23.001f, -26.459f, -24.480f, -26.254f, + -27.155f, -29.539f, -29.652f, -30.124f, -31.017f, -32.787f, -32.923f, -32.450f, -31.829f, + -34.152f, -32.285f, -32.258f, -34.314f, -34.545f, -34.406f, -35.412f, -36.349f, -36.235f, + -37.244f, -37.555f, -36.696f, -37.805f, -38.592f, -38.800f, -41.360f, -43.292f, -44.712f, + -44.396f, -44.379f, -45.182f, -44.838f, -44.693f, -43.809f, -42.291f, -38.486f, -37.536f, + -37.323f, -34.359f, -32.546f, -30.228f, -27.893f, -26.272f, -23.086f, -19.567f, -13.427f, + -8.485f, -4.801f, -3.175f, 7.147f, 3.595f, 8.010f, 9.604f, 10.211f, 13.270f, + 16.601f, 17.799f, 17.728f, 16.566f, 17.408f, 16.850f, 16.663f, 16.837f, 15.577f, + 13.606f}, + {-29.534f, -29.391f, -27.155f, -27.144f, -28.715f, -29.516f, -28.960f, -28.460f, -28.587f, + -27.004f, -24.603f, -23.302f, -20.591f, -16.630f, -17.808f, -15.102f, -13.195f, -13.730f, + -12.318f, -10.706f, -9.534f, -8.249f, -9.827f, -8.608f, -7.479f, -6.024f, -5.437f, + -5.010f, -4.561f, -4.132f, -3.512f, -2.162f, -1.246f, -0.345f, 0.736f, 1.526f, + 2.567f, 3.391f, 4.108f, 4.528f, 4.949f, 5.478f, 5.897f, 6.809f, 7.597f, + 7.210f, 8.302f, 8.155f, 8.132f, 7.699f, 6.855f, 6.701f, 6.469f, 6.772f, + 7.252f, 7.344f, 7.443f, 6.383f, 7.095f, 7.296f, 7.996f, 7.843f, 8.031f, + 8.646f, 9.468f, 8.409f, 8.094f, 8.015f, 8.413f, 8.241f, 8.162f, 7.802f, + 7.817f, 7.324f, 6.701f, 6.950f, 6.319f, 5.702f, 3.823f, -0.052f, -0.787f, + 5.812f, 8.543f, 8.719f, 9.899f, 16.603f, 15.855f, 10.183f, 18.492f, 15.868f, + 14.391f, 12.117f, 10.550f, 12.655f, 13.635f, 13.356f, 13.718f, 11.960f, 14.540f, + 12.352f, 0.841f, -0.803f, 0.311f, -1.568f, -2.804f, -5.725f, -7.157f, -10.349f, + -14.964f, -19.553f, -19.246f, -23.508f, -21.350f, -23.667f, -26.369f, -28.308f, -28.446f, + -29.534f, -31.274f, -32.042f, -32.390f, -33.632f, -34.468f, -34.311f, -33.553f, -32.229f, + -32.823f, -33.327f, -32.406f, -32.254f, -33.945f, -34.525f, -34.976f, -36.699f, -36.758f, + -36.589f, -36.926f, -36.641f, -37.916f, -39.139f, -39.502f, -42.133f, -43.546f, -44.626f, + -44.008f, -44.446f, -44.033f, -43.698f, -43.768f, -44.006f, -42.354f, -37.456f, -35.750f, + -36.062f, -33.837f, -31.898f, -29.717f, -27.239f, -25.470f, -22.237f, -18.443f, -12.124f, + -7.539f, -3.310f, -1.352f, 6.127f, 4.686f, 8.922f, 10.279f, 11.028f, 14.574f, + 16.463f, 18.191f, 17.953f, 16.931f, 17.628f, 17.015f, 16.785f, 16.909f, 15.608f, + 13.606f}, + {-29.534f, -29.334f, -27.049f, -26.863f, -28.533f, -29.249f, -28.705f, -28.111f, -28.437f, + -27.084f, -24.948f, -22.982f, -20.134f, -16.209f, -18.184f, -15.328f, -12.777f, -12.681f, + -12.004f, -10.303f, -8.542f, -7.367f, -9.152f, -7.489f, -6.538f, -4.965f, -4.158f, + -3.950f, -3.313f, -3.067f, -2.470f, -1.537f, -0.170f, 0.613f, 1.765f, 3.079f, + 3.678f, 4.469f, 5.098f, 5.351f, 5.550f, 6.066f, 6.742f, 7.737f, 8.531f, + 8.862f, 9.201f, 9.078f, 9.228f, 9.037f, 8.081f, 7.928f, 7.540f, 8.029f, + 8.435f, 8.352f, 10.050f, 7.614f, 8.597f, 8.475f, 9.029f, 9.255f, 9.421f, + 9.990f, 9.356f, 9.508f, 9.457f, 8.719f, 8.768f, 9.073f, 9.374f, 9.884f, + 10.305f, 10.080f, 9.750f, 9.851f, 8.505f, 6.255f, 1.934f, 2.243f, 9.197f, + 13.758f, 14.608f, 17.188f, 16.723f, 18.323f, 17.178f, 22.230f, 23.432f, 23.746f, + 22.030f, 17.646f, 12.585f, 10.941f, 13.089f, 14.384f, 14.105f, 11.813f, 15.043f, + 14.482f, 1.139f, -2.089f, -1.633f, -3.915f, -5.947f, -7.663f, -10.162f, -12.285f, + -15.805f, -22.293f, -20.908f, -21.382f, -22.847f, -25.137f, -26.916f, -28.416f, -30.412f, + -30.186f, -33.574f, -34.896f, -35.801f, -35.548f, -36.607f, -36.184f, -35.575f, -34.867f, + -32.332f, -32.687f, -33.429f, -32.926f, -32.690f, -33.319f, -33.373f, -36.311f, -37.098f, + -35.908f, -36.632f, -37.246f, -38.194f, -39.390f, -40.189f, -41.918f, -43.200f, -43.884f, + -43.370f, -44.282f, -43.767f, -43.764f, -42.435f, -41.684f, -40.768f, -37.052f, -34.275f, + -34.543f, -33.020f, -31.504f, -29.046f, -26.567f, -24.340f, -21.422f, -17.118f, -10.484f, + -5.807f, -0.686f, 0.779f, 5.445f, 6.209f, 9.362f, 10.363f, 11.134f, 15.267f, + 16.292f, 18.678f, 18.060f, 17.337f, 17.845f, 17.191f, 16.906f, 16.985f, 15.638f, + 13.606f}, + {-29.534f, -29.276f, -26.946f, -26.583f, -28.258f, -28.911f, -28.349f, -27.883f, -28.425f, + -27.141f, -24.823f, -23.061f, -20.435f, -17.315f, -18.575f, -15.512f, -12.740f, -12.036f, + -11.488f, -9.694f, -7.356f, -6.691f, -8.233f, -6.280f, -5.433f, -3.804f, -2.623f, + -2.589f, -2.202f, -1.868f, -1.251f, -0.636f, 0.534f, 1.595f, 2.935f, 3.893f, + 4.741f, 4.998f, 5.364f, 5.042f, 5.193f, 5.606f, 7.269f, 8.558f, 9.757f, + 10.408f, 10.024f, 10.219f, 10.352f, 10.319f, 9.377f, 9.263f, 9.036f, 9.205f, + 9.797f, 9.703f, 9.599f, 8.770f, 10.035f, 9.933f, 10.171f, 11.151f, 10.863f, + 11.712f, 11.115f, 11.024f, 10.536f, 10.140f, 9.799f, 10.489f, 10.897f, 11.762f, + 12.053f, 13.024f, 12.950f, 11.654f, 8.769f, 6.645f, 10.235f, 14.975f, 20.177f, + 18.928f, 19.770f, 19.485f, 18.818f, 11.432f, 12.875f, 16.238f, 23.414f, 23.147f, + 24.530f, 27.656f, 19.544f, 15.393f, 10.132f, 11.971f, 12.096f, 13.955f, 14.609f, + 9.980f, -1.612f, -3.647f, -4.189f, -6.434f, -7.564f, -9.534f, -12.732f, -13.847f, + -15.111f, -24.345f, -22.599f, -23.245f, -23.553f, -24.223f, -27.047f, -31.537f, -32.881f, + -33.446f, -36.365f, -37.026f, -38.804f, -39.579f, -38.748f, -39.374f, -38.881f, -37.226f, + -35.995f, -33.776f, -33.502f, -34.129f, -34.968f, -33.684f, -32.410f, -35.393f, -36.772f, + -35.312f, -36.356f, -36.514f, -37.684f, -38.937f, -40.086f, -40.673f, -41.683f, -42.554f, + -42.054f, -42.928f, -42.590f, -42.219f, -40.645f, -38.629f, -37.853f, -35.179f, -32.503f, + -33.046f, -31.718f, -29.657f, -28.222f, -26.358f, -23.448f, -20.519f, -15.364f, -8.458f, + -3.509f, 1.653f, 2.990f, 6.580f, 8.024f, 9.361f, 9.910f, 10.537f, 15.291f, + 16.311f, 19.339f, 18.097f, 17.762f, 18.059f, 17.374f, 17.025f, 17.066f, 15.665f, + 13.606f}, + {-29.534f, -29.219f, -26.848f, -26.311f, -27.887f, -28.527f, -27.924f, -27.803f, -28.503f, + -27.082f, -24.357f, -23.108f, -20.987f, -19.280f, -18.416f, -14.792f, -12.147f, -11.381f, + -10.319f, -8.320f, -5.857f, -5.525f, -6.920f, -5.055f, -4.173f, -2.440f, -1.197f, + -1.016f, -0.680f, -0.483f, 0.031f, 0.608f, 1.465f, 2.652f, 3.733f, 4.819f, + 4.807f, 4.642f, 4.505f, 4.609f, 5.609f, 5.801f, 6.903f, 8.946f, 10.784f, + 11.133f, 10.711f, 11.204f, 11.369f, 11.142f, 10.719f, 10.306f, 10.284f, 10.672f, + 11.023f, 11.303f, 10.565f, 10.754f, 11.878f, 11.315f, 11.527f, 12.024f, 12.363f, + 13.250f, 13.026f, 12.093f, 12.434f, 11.684f, 11.325f, 12.055f, 12.501f, 13.378f, + 14.353f, 15.236f, 14.757f, 11.037f, 11.663f, 16.848f, 24.029f, 26.677f, 24.226f, + 19.277f, 13.362f, 11.386f, 14.262f, 10.401f, 10.194f, 9.929f, 13.751f, 14.986f, + 17.319f, 24.490f, 26.364f, 23.863f, 17.340f, 16.469f, 19.252f, 17.022f, 12.334f, + 1.487f, -4.462f, -5.897f, -5.925f, -8.231f, -12.088f, -13.830f, -14.551f, -16.545f, + -15.042f, -26.453f, -24.633f, -25.276f, -28.776f, -26.836f, -31.758f, -32.988f, -39.057f, + -37.559f, -38.493f, -41.224f, -41.382f, -42.693f, -40.914f, -39.885f, -39.885f, -38.902f, + -37.463f, -36.455f, -34.855f, -33.146f, -34.505f, -34.015f, -33.282f, -35.316f, -35.783f, + -34.489f, -35.345f, -35.732f, -36.169f, -38.051f, -39.478f, -39.348f, -40.346f, -40.910f, + -40.909f, -40.947f, -40.881f, -40.562f, -38.396f, -36.101f, -34.574f, -32.870f, -30.521f, + -32.246f, -30.695f, -27.773f, -27.517f, -25.586f, -22.349f, -19.044f, -13.192f, -6.214f, + -1.126f, 2.854f, 5.545f, 9.291f, 9.756f, 9.300f, 9.246f, 9.527f, 14.774f, + 16.667f, 20.127f, 18.139f, 18.181f, 18.273f, 17.556f, 17.143f, 17.153f, 15.691f, + 13.606f}, + {-29.534f, -29.161f, -26.755f, -26.049f, -27.426f, -28.110f, -27.461f, -27.836f, -28.567f, + -26.830f, -23.824f, -22.938f, -21.388f, -20.871f, -17.818f, -13.247f, -10.937f, -10.391f, + -8.785f, -7.121f, -4.497f, -3.825f, -5.249f, -3.516f, -3.014f, -0.980f, 0.005f, + 0.496f, 0.859f, 0.662f, 1.308f, 1.764f, 2.665f, 3.578f, 4.620f, 4.502f, + 4.200f, 4.696f, 7.113f, 9.192f, 10.007f, 10.229f, 10.886f, 9.810f, 11.256f, + 10.791f, 10.318f, 10.073f, 10.717f, 11.120f, 10.968f, 10.602f, 10.940f, 11.164f, + 11.942f, 12.556f, 12.425f, 11.665f, 13.241f, 12.703f, 13.440f, 13.603f, 13.621f, + 14.212f, 14.531f, 14.115f, 14.179f, 14.100f, 13.420f, 13.875f, 14.635f, 15.338f, + 15.880f, 15.779f, 12.678f, 15.450f, 24.460f, 31.969f, 31.575f, 31.677f, 28.332f, + 17.668f, 11.924f, 12.133f, 12.603f, 11.414f, 11.955f, 14.172f, 15.982f, 17.122f, + 18.048f, 19.095f, 24.361f, 26.881f, 26.670f, 27.074f, 26.218f, 21.663f, 8.879f, + 2.233f, -2.569f, -8.607f, -10.265f, -11.492f, -14.670f, -15.269f, -16.872f, -18.741f, + -20.030f, -26.542f, -26.136f, -28.532f, -31.906f, -30.369f, -34.474f, -38.978f, -43.671f, + -44.466f, -45.423f, -46.324f, -46.466f, -43.594f, -43.204f, -44.186f, -41.492f, -39.744f, + -40.296f, -39.009f, -37.211f, -35.499f, -34.671f, -33.240f, -32.894f, -33.550f, -34.098f, + -34.044f, -33.849f, -34.863f, -34.535f, -36.958f, -37.730f, -37.314f, -38.641f, -39.095f, + -39.166f, -38.613f, -38.899f, -38.550f, -36.573f, -34.416f, -31.920f, -30.756f, -28.570f, + -31.190f, -29.379f, -26.423f, -25.997f, -23.690f, -20.599f, -16.884f, -10.755f, -4.083f, + 0.615f, 3.904f, 8.389f, 12.036f, 11.192f, 9.441f, 8.750f, 8.475f, 13.902f, + 17.351f, 20.875f, 18.253f, 18.568f, 18.490f, 17.733f, 17.262f, 17.247f, 15.715f, + 13.606f}, + {-29.534f, -29.104f, -26.669f, -25.799f, -26.888f, -27.659f, -26.983f, -27.901f, -28.516f, + -26.389f, -23.467f, -22.673f, -21.408f, -21.229f, -17.453f, -11.667f, -9.612f, -9.340f, + -7.260f, -6.240f, -3.831f, -2.539f, -2.912f, -2.025f, -1.937f, 0.300f, 1.187f, + 1.891f, 2.269f, 1.864f, 2.254f, 2.981f, 3.712f, 4.559f, 5.112f, 3.359f, + 3.676f, 9.078f, 12.788f, 13.698f, 13.496f, 14.709f, 15.004f, 13.460f, 14.942f, + 13.389f, 12.349f, 11.704f, 11.752f, 11.317f, 9.575f, 9.342f, 8.839f, 9.475f, + 11.155f, 12.814f, 14.020f, 13.543f, 14.572f, 14.432f, 14.665f, 15.317f, 15.264f, + 16.200f, 15.778f, 16.565f, 15.758f, 15.874f, 15.699f, 15.778f, 16.493f, 17.218f, + 16.978f, 14.125f, 15.241f, 30.370f, 37.657f, 35.765f, 32.546f, 30.958f, 26.513f, + 19.218f, 14.606f, 16.228f, 14.569f, 14.610f, 15.957f, 18.079f, 18.872f, 18.671f, + 19.591f, 19.666f, 19.699f, 18.380f, 17.578f, 23.061f, 20.064f, 14.158f, 4.214f, + -2.232f, -4.783f, -8.867f, -16.480f, -16.899f, -17.714f, -17.959f, -19.330f, -21.061f, + -22.868f, -27.496f, -27.440f, -34.213f, -36.796f, -36.005f, -39.141f, -43.279f, -43.199f, + -43.823f, -45.416f, -45.885f, -45.821f, -44.410f, -45.971f, -47.554f, -46.960f, -42.778f, + -39.912f, -38.591f, -37.491f, -36.329f, -34.040f, -33.950f, -30.580f, -32.079f, -30.870f, + -32.075f, -33.102f, -33.938f, -33.445f, -35.790f, -35.735f, -35.682f, -36.308f, -36.758f, + -37.005f, -36.608f, -36.959f, -36.713f, -34.855f, -32.752f, -29.931f, -28.520f, -27.072f, + -29.377f, -27.798f, -24.864f, -24.243f, -22.136f, -18.618f, -14.227f, -7.833f, -2.148f, + 1.351f, 6.148f, 10.873f, 13.871f, 12.398f, 9.741f, 8.705f, 7.626f, 12.802f, + 18.192f, 21.375f, 18.475f, 18.902f, 18.715f, 17.900f, 17.383f, 17.349f, 15.737f, + 13.606f}, + {-29.534f, -29.048f, -26.591f, -25.562f, -26.291f, -27.163f, -26.498f, -27.896f, -28.310f, + -25.865f, -23.338f, -22.430f, -20.960f, -20.446f, -17.571f, -10.436f, -8.286f, -8.379f, + -5.647f, -4.484f, -3.088f, -1.633f, -0.641f, -0.587f, -0.438f, 1.304f, 2.389f, + 2.874f, 3.450f, 3.349f, 4.024f, 4.352f, 4.949f, 5.868f, 4.961f, 3.454f, + 8.809f, 11.276f, 13.084f, 14.942f, 15.815f, 16.335f, 15.561f, 17.947f, 17.583f, + 16.116f, 13.930f, 14.558f, 15.742f, 15.713f, 13.400f, 12.994f, 14.327f, 12.411f, + 9.047f, 9.523f, 13.314f, 15.189f, 15.667f, 15.872f, 15.745f, 16.733f, 16.743f, + 17.726f, 17.436f, 18.184f, 18.248f, 17.622f, 17.240f, 17.950f, 18.283f, 18.825f, + 17.399f, 11.838f, 30.432f, 38.459f, 37.101f, 34.334f, 30.987f, 28.697f, 23.260f, + 20.675f, 20.568f, 20.244f, 17.763f, 18.557f, 19.968f, 20.343f, 19.527f, 19.657f, + 20.685f, 22.215f, 20.394f, 17.507f, 18.950f, 21.723f, 13.390f, 4.358f, 1.792f, + -1.771f, -4.390f, 0.010f, -20.105f, -21.884f, -20.811f, -21.000f, -22.735f, -25.496f, + -24.847f, -27.188f, -35.951f, -41.624f, -37.785f, -39.063f, -43.020f, -44.446f, -45.257f, + -45.183f, -45.907f, -46.761f, -46.822f, -48.331f, -49.992f, -49.582f, -47.775f, -45.232f, + -42.979f, -41.888f, -38.857f, -37.024f, -33.760f, -32.312f, -32.012f, -31.517f, -29.181f, + -29.968f, -32.514f, -32.685f, -32.739f, -34.675f, -34.540f, -34.293f, -34.345f, -34.288f, + -34.676f, -34.506f, -35.086f, -34.850f, -33.317f, -31.106f, -28.113f, -26.520f, -25.359f, + -27.720f, -25.809f, -23.133f, -22.590f, -21.016f, -16.532f, -11.411f, -4.749f, -0.239f, + 2.042f, 9.241f, 12.550f, 15.117f, 13.422f, 10.082f, 9.264f, 7.061f, 11.528f, + 18.910f, 21.481f, 18.792f, 19.177f, 18.950f, 18.059f, 17.511f, 17.457f, 15.757f, + 13.606f}, + {-29.534f, -28.993f, -26.520f, -25.338f, -25.660f, -26.605f, -26.007f, -27.747f, -27.983f, + -25.407f, -23.293f, -22.105f, -20.171f, -19.338f, -17.526f, -9.298f, -6.989f, -7.133f, + -3.932f, -2.523f, -1.582f, 0.266f, 0.899f, 1.565f, 1.005f, 2.373f, 3.345f, + 3.942f, 4.389f, 5.028f, 5.644f, 5.838f, 6.756f, 6.453f, 4.506f, 6.869f, + 11.568f, 10.147f, 12.689f, 14.837f, 16.107f, 16.922f, 17.402f, 20.140f, 22.910f, + 19.349f, 16.666f, 16.802f, 17.073f, 18.506f, 17.317f, 16.970f, 19.892f, 20.647f, + 18.537f, 11.735f, 8.441f, 10.331f, 12.447f, 13.300f, 13.706f, 15.799f, 17.073f, + 18.542f, 18.283f, 18.863f, 18.943f, 19.825f, 19.188f, 19.572f, 20.196f, 20.589f, + 13.443f, 18.983f, 38.486f, 43.637f, 40.306f, 36.390f, 31.445f, 27.833f, 26.349f, + 25.139f, 22.784f, 21.593f, 19.701f, 20.504f, 21.319f, 19.790f, 18.825f, 19.055f, + 18.982f, 20.860f, 20.087f, 16.084f, 10.216f, 13.210f, 20.135f, 11.383f, 4.407f, + -2.013f, -1.266f, -5.200f, -18.161f, -24.407f, -22.513f, -21.248f, -24.789f, -29.100f, + -27.965f, -28.046f, -36.585f, -43.581f, -41.748f, -44.131f, -45.134f, -46.734f, -47.701f, + -47.837f, -48.249f, -48.193f, -49.453f, -50.963f, -51.401f, -50.710f, -48.357f, -46.532f, + -44.446f, -42.930f, -42.060f, -37.071f, -34.871f, -31.406f, -29.756f, -29.240f, -28.984f, + -29.588f, -31.870f, -31.065f, -31.792f, -34.368f, -33.335f, -33.254f, -32.621f, -32.285f, + -32.326f, -32.525f, -33.351f, -32.920f, -31.722f, -29.375f, -26.546f, -24.772f, -24.250f, + -25.980f, -23.077f, -20.943f, -20.522f, -18.985f, -14.321f, -8.851f, -2.459f, 1.414f, + 3.946f, 11.652f, 13.631f, 16.256f, 14.128f, 10.542f, 10.444f, 6.829f, 10.145f, + 19.218f, 21.193f, 19.151f, 19.395f, 19.197f, 18.212f, 17.648f, 17.573f, 15.774f, + 13.606f}, + {-29.534f, -28.939f, -26.457f, -25.129f, -25.023f, -25.977f, -25.509f, -27.429f, -27.623f, + -25.107f, -23.118f, -21.521f, -19.383f, -18.658f, -16.568f, -8.091f, -6.090f, -5.325f, + -2.102f, -1.354f, 0.296f, 2.747f, 2.138f, 3.679f, 2.439f, 3.673f, 4.459f, + 5.023f, 5.711f, 6.615f, 6.633f, 7.355f, 8.417f, 7.463f, 4.303f, 9.641f, + 10.327f, 10.464f, 10.722f, 12.613f, 13.684f, 16.049f, 17.753f, 19.988f, 23.445f, + 18.874f, 18.079f, 19.864f, 20.066f, 21.453f, 21.500f, 20.480f, 20.896f, 20.842f, + 20.712f, 20.708f, 19.159f, 14.902f, 14.622f, 16.796f, 15.168f, 14.101f, 12.947f, + 13.359f, 15.638f, 16.471f, 17.135f, 18.414f, 19.501f, 20.040f, 18.781f, 13.866f, + 18.076f, 30.436f, 42.364f, 45.825f, 44.807f, 41.484f, 30.952f, 26.232f, 26.310f, + 24.918f, 23.560f, 23.261f, 22.206f, 21.102f, 20.848f, 19.189f, 17.022f, 16.792f, + 18.562f, 20.357f, 17.544f, 11.822f, 6.286f, 2.666f, 5.787f, 3.184f, 0.044f, + -11.214f, -12.556f, -12.780f, -15.614f, -25.857f, -24.877f, -23.969f, -27.042f, -30.074f, + -29.335f, -27.275f, -41.133f, -45.523f, -42.849f, -46.704f, -47.559f, -48.790f, -49.634f, + -49.984f, -50.339f, -50.711f, -51.485f, -51.653f, -51.360f, -50.552f, -48.581f, -46.201f, + -44.346f, -42.502f, -42.026f, -39.413f, -34.677f, -32.153f, -29.952f, -28.223f, -27.949f, + -28.049f, -28.841f, -29.195f, -29.937f, -33.111f, -31.388f, -32.064f, -31.039f, -30.382f, + -30.714f, -30.932f, -31.339f, -31.026f, -29.708f, -27.862f, -25.334f, -23.865f, -24.414f, + -23.308f, -19.839f, -18.630f, -18.303f, -16.323f, -11.824f, -6.354f, -0.692f, 2.300f, + 6.708f, 12.766f, 14.513f, 17.160f, 14.470f, 11.340f, 12.102f, 7.041f, 8.811f, + 18.929f, 20.655f, 19.487f, 19.574f, 19.452f, 18.366f, 17.798f, 17.694f, 15.790f, + 13.606f}, + {-29.534f, -28.886f, -26.403f, -24.934f, -24.410f, -25.286f, -25.015f, -26.984f, -27.309f, + -24.936f, -22.709f, -20.710f, -18.919f, -18.487f, -14.845f, -7.039f, -5.590f, -3.401f, + -0.047f, 0.394f, 2.152f, 3.977f, 3.386f, 4.792f, 4.838f, 4.817f, 5.673f, + 6.227f, 7.113f, 8.103f, 8.065f, 9.260f, 9.862f, 8.198f, 6.096f, 10.882f, + 9.264f, 8.916f, 9.546f, 10.834f, 12.879f, 14.583f, 15.690f, 17.482f, 18.753f, + 17.759f, 18.037f, 20.016f, 21.224f, 22.141f, 23.292f, 24.361f, 24.476f, 25.297f, + 24.786f, 24.837f, 25.003f, 26.202f, 29.447f, 31.432f, 32.594f, 30.768f, 25.786f, + 22.669f, 20.212f, 18.319f, 16.955f, 15.033f, 14.598f, 15.553f, 15.762f, 20.387f, + 27.481f, 39.357f, 45.051f, 46.533f, 49.123f, 36.632f, 27.868f, 27.028f, 27.267f, + 26.175f, 25.617f, 23.608f, 23.119f, 21.533f, 20.274f, 17.787f, 15.527f, 15.475f, + 16.978f, 17.421f, 13.822f, 8.811f, 4.492f, -0.250f, -3.132f, -4.780f, -5.145f, + -4.599f, -14.191f, -17.356f, -21.502f, -26.388f, -29.353f, -28.213f, -29.246f, -32.862f, + -33.755f, -28.882f, -44.850f, -44.019f, -48.933f, -48.922f, -49.726f, -50.842f, -51.425f, + -51.600f, -51.755f, -51.982f, -52.131f, -51.554f, -50.766f, -49.768f, -48.050f, -45.846f, + -43.984f, -42.753f, -41.276f, -39.839f, -34.895f, -31.583f, -29.321f, -27.380f, -27.494f, + -26.505f, -27.580f, -27.942f, -27.643f, -29.618f, -28.849f, -29.365f, -29.721f, -28.846f, + -28.638f, -28.628f, -29.394f, -29.193f, -28.362f, -27.010f, -24.294f, -23.018f, -23.163f, + -19.568f, -16.167f, -16.301f, -16.029f, -13.651f, -8.677f, -3.902f, 1.281f, 2.579f, + 8.986f, 13.221f, 15.267f, 17.691f, 14.726f, 12.576f, 13.949f, 7.816f, 7.768f, + 18.024f, 20.082f, 19.744f, 19.736f, 19.707f, 18.532f, 17.963f, 17.819f, 15.803f, + 13.606f}, + {-29.534f, -28.835f, -26.358f, -24.754f, -23.851f, -24.557f, -24.555f, -26.496f, -27.069f, + -24.758f, -22.141f, -19.972f, -18.797f, -18.335f, -13.273f, -6.250f, -4.790f, -2.037f, + 1.621f, 2.757f, 3.688f, 4.571f, 4.937f, 6.190f, 7.394f, 6.204f, 6.875f, + 7.623f, 8.496f, 9.364f, 9.433f, 11.237f, 11.070f, 8.081f, 11.438f, 12.736f, + 9.695f, 9.334f, 9.302f, 10.376f, 11.452f, 12.911f, 15.223f, 15.780f, 16.085f, + 16.927f, 18.771f, 20.285f, 21.697f, 22.547f, 22.746f, 22.664f, 23.923f, 25.345f, + 26.959f, 30.058f, 31.957f, 31.814f, 32.281f, 33.246f, 36.671f, 37.574f, 35.090f, + 34.594f, 34.258f, 35.752f, 32.146f, 33.283f, 33.308f, 31.616f, 33.577f, 35.431f, + 38.298f, 44.503f, 45.456f, 46.584f, 44.159f, 31.042f, 27.473f, 28.394f, 27.401f, + 26.406f, 24.246f, 22.700f, 22.652f, 19.600f, 18.205f, 16.642f, 14.994f, 14.154f, + 13.712f, 13.683f, 10.702f, 5.827f, 1.869f, -1.564f, -4.634f, -7.014f, -8.780f, + -8.479f, -10.821f, -16.701f, -22.703f, -30.007f, -32.964f, -30.155f, -31.468f, -37.650f, + -38.171f, -35.709f, -47.155f, -48.024f, -50.740f, -50.376f, -51.199f, -52.148f, -52.543f, + -52.099f, -51.822f, -51.881f, -51.679f, -51.071f, -49.966f, -48.581f, -47.192f, -45.200f, + -43.114f, -42.471f, -40.926f, -38.779f, -34.597f, -30.688f, -28.453f, -26.730f, -26.505f, + -26.190f, -26.106f, -27.748f, -27.507f, -26.881f, -26.294f, -25.969f, -28.200f, -26.928f, + -26.518f, -26.231f, -27.474f, -28.072f, -28.163f, -26.465f, -23.101f, -21.837f, -21.056f, + -15.822f, -13.286f, -13.472f, -13.493f, -10.362f, -5.340f, -1.888f, 2.847f, 3.268f, + 10.356f, 13.506f, 15.740f, 18.173f, 15.212f, 14.105f, 15.684f, 9.134f, 7.236f, + 16.643f, 19.653f, 19.898f, 19.905f, 19.956f, 18.721f, 18.146f, 17.947f, 15.814f, + 13.606f}, + {-29.534f, -28.785f, -26.322f, -24.589f, -23.372f, -23.842f, -24.177f, -26.069f, -26.868f, + -24.436f, -21.600f, -19.600f, -18.720f, -17.790f, -12.554f, -5.534f, -3.349f, -1.100f, + 2.293f, 3.826f, 5.080f, 5.922f, 6.409f, 8.352f, 9.203f, 8.375f, 8.277f, + 8.831f, 9.900f, 10.608f, 11.653f, 12.480f, 12.509f, 9.020f, 14.435f, 13.628f, + 11.675f, 10.801f, 9.861f, 9.808f, 10.392f, 11.900f, 13.865f, 14.474f, 15.133f, + 15.847f, 17.541f, 20.329f, 23.061f, 23.980f, 22.671f, 20.329f, 21.223f, 22.925f, + 26.192f, 25.802f, 24.428f, 22.758f, 25.622f, 26.964f, 31.787f, 35.160f, 38.266f, + 41.244f, 40.663f, 38.421f, 34.178f, 36.310f, 36.830f, 37.887f, 41.781f, 43.511f, + 44.400f, 44.558f, 45.605f, 44.522f, 33.725f, 30.175f, 28.817f, 27.692f, 26.278f, + 24.359f, 22.424f, 22.146f, 21.279f, 18.738f, 16.266f, 14.310f, 13.608f, 12.057f, + 10.630f, 10.283f, 7.759f, 3.053f, -1.062f, -4.799f, -7.139f, -8.371f, -9.881f, + -11.709f, -13.484f, -17.275f, -24.595f, -34.747f, -34.773f, -31.982f, -33.913f, -41.444f, + -41.289f, -44.231f, -51.000f, -51.175f, -50.708f, -51.026f, -52.034f, -52.419f, -52.244f, + -51.619f, -51.325f, -51.175f, -50.664f, -49.681f, -48.404f, -47.319f, -46.091f, -44.585f, + -42.972f, -42.198f, -40.643f, -38.252f, -34.265f, -31.055f, -28.266f, -26.533f, -25.678f, + -25.536f, -24.801f, -25.762f, -26.919f, -26.774f, -25.004f, -24.157f, -25.939f, -24.921f, + -24.391f, -24.467f, -26.361f, -26.582f, -25.796f, -24.197f, -21.465f, -21.136f, -19.181f, + -12.803f, -11.370f, -10.569f, -10.655f, -6.799f, -2.283f, -0.149f, 3.569f, 5.104f, + 11.222f, 13.664f, 15.944f, 18.804f, 15.881f, 15.705f, 17.146f, 10.777f, 7.300f, + 15.040f, 19.426f, 19.961f, 20.101f, 20.189f, 18.944f, 18.347f, 18.076f, 15.823f, + 13.606f}, + {-29.534f, -28.737f, -26.295f, -24.443f, -22.996f, -23.206f, -23.937f, -25.783f, -26.634f, + -23.935f, -21.228f, -19.589f, -18.392f, -17.016f, -12.687f, -4.930f, -1.912f, 0.096f, + 2.783f, 4.647f, 7.317f, 7.494f, 7.005f, 9.283f, 10.436f, 10.970f, 9.663f, + 10.310f, 11.516f, 12.080f, 13.362f, 13.451f, 13.369f, 12.182f, 14.777f, 13.788f, + 12.190f, 12.033f, 10.293f, 9.953f, 10.430f, 11.547f, 11.604f, 13.036f, 14.371f, + 14.694f, 16.010f, 18.932f, 22.721f, 23.298f, 21.084f, 18.480f, 18.674f, 20.113f, + 22.846f, 22.080f, 21.838f, 20.643f, 21.265f, 23.719f, 27.033f, 31.142f, 34.975f, + 41.047f, 42.812f, 41.184f, 39.763f, 40.278f, 43.256f, 42.778f, 43.204f, 43.168f, + 44.311f, 44.382f, 41.000f, 32.931f, 31.139f, 30.547f, 29.323f, 27.152f, 24.797f, + 22.609f, 20.125f, 18.840f, 17.754f, 15.149f, 12.639f, 10.374f, 10.136f, 8.408f, + 6.960f, 6.100f, 4.223f, 1.233f, -3.363f, -6.499f, -9.549f, -9.890f, -10.862f, + -12.699f, -15.501f, -21.616f, -25.702f, -38.362f, -36.087f, -34.686f, -36.669f, -42.986f, + -45.442f, -55.379f, -58.834f, -51.247f, -50.577f, -51.406f, -52.340f, -51.653f, -51.321f, + -50.518f, -49.941f, -49.485f, -48.738f, -47.719f, -46.804f, -45.872f, -44.701f, -43.838f, + -42.056f, -41.646f, -40.611f, -37.976f, -34.364f, -29.408f, -26.892f, -25.625f, -24.262f, + -24.677f, -24.547f, -24.224f, -24.187f, -26.173f, -23.567f, -22.325f, -22.760f, -23.464f, + -22.571f, -22.792f, -24.551f, -23.426f, -22.284f, -21.030f, -19.486f, -20.236f, -16.441f, + -10.835f, -8.344f, -7.986f, -8.059f, -3.459f, 0.335f, 0.661f, 3.997f, 7.560f, + 11.890f, 14.060f, 16.211f, 19.240f, 16.433f, 17.255f, 18.355f, 12.454f, 7.888f, + 13.500f, 19.318f, 19.967f, 20.329f, 20.402f, 19.213f, 18.566f, 18.202f, 15.829f, + 13.606f}, + {-29.534f, -28.692f, -26.277f, -24.316f, -22.737f, -22.719f, -23.879f, -25.673f, -26.313f, + -23.362f, -21.036f, -19.628f, -17.808f, -16.569f, -13.346f, -5.041f, -1.162f, 1.471f, + 4.021f, 7.186f, 10.079f, 9.216f, 7.379f, 9.059f, 11.255f, 12.824f, 11.386f, + 11.878f, 12.857f, 13.504f, 14.765f, 14.927f, 14.603f, 13.808f, 15.627f, 14.157f, + 12.319f, 12.228f, 10.336f, 9.969f, 10.509f, 11.393f, 11.460f, 12.114f, 13.019f, + 13.546f, 14.507f, 16.121f, 19.322f, 19.799f, 18.592f, 17.235f, 17.644f, 17.882f, + 19.764f, 20.908f, 22.359f, 22.800f, 23.826f, 25.283f, 24.801f, 28.095f, 28.518f, + 36.927f, 41.330f, 43.064f, 43.174f, 43.769f, 43.572f, 42.392f, 43.169f, 44.059f, + 45.042f, 42.720f, 31.677f, 27.297f, 28.831f, 31.129f, 29.829f, 26.514f, 23.441f, + 20.333f, 17.947f, 16.129f, 14.371f, 12.535f, 9.807f, 8.350f, 6.889f, 5.051f, + 3.378f, 1.808f, -0.146f, -3.252f, -6.014f, -4.548f, -7.880f, -11.551f, -12.615f, + -14.897f, -16.594f, -23.257f, -29.506f, -39.973f, -36.596f, -36.897f, -39.281f, -44.461f, + -42.476f, -62.241f, -62.227f, -51.252f, -51.049f, -51.920f, -51.809f, -50.944f, -50.222f, + -49.136f, -48.462f, -47.996f, -46.792f, -45.960f, -45.149f, -44.076f, -43.486f, -42.181f, + -40.878f, -40.214f, -39.737f, -37.951f, -34.336f, -28.126f, -26.276f, -24.416f, -23.539f, + -23.708f, -23.634f, -21.932f, -22.297f, -23.657f, -23.501f, -21.204f, -20.139f, -22.185f, + -21.085f, -20.500f, -20.808f, -19.618f, -19.305f, -17.913f, -16.880f, -17.851f, -13.022f, + -8.640f, -4.428f, -6.275f, -4.957f, 1.297f, 1.995f, 0.754f, 4.750f, 9.700f, + 12.729f, 14.973f, 16.943f, 19.164f, 16.757f, 18.736f, 19.433f, 13.990f, 8.835f, + 12.272f, 19.166f, 19.959f, 20.583f, 20.594f, 19.533f, 18.799f, 18.324f, 15.834f, + 13.606f}, + {-29.534f, -28.648f, -26.268f, -24.212f, -22.599f, -22.443f, -24.024f, -25.718f, -25.907f, + -22.896f, -20.918f, -19.399f, -17.230f, -16.710f, -14.256f, -6.427f, -1.029f, 2.317f, + 5.567f, 9.763f, 11.917f, 11.297f, 7.964f, 9.411f, 12.152f, 13.833f, 13.871f, + 13.421f, 14.171f, 15.426f, 15.823f, 16.024f, 15.093f, 13.245f, 14.310f, 13.538f, + 11.918f, 12.333f, 11.143f, 10.815f, 10.537f, 10.904f, 11.499f, 11.607f, 11.730f, + 12.308f, 13.593f, 14.253f, 15.734f, 16.255f, 16.347f, 15.859f, 16.057f, 17.432f, + 18.696f, 20.215f, 22.826f, 25.473f, 25.296f, 25.039f, 23.801f, 25.633f, 29.066f, + 35.922f, 36.121f, 38.966f, 43.192f, 43.434f, 42.001f, 42.917f, 43.597f, 43.292f, + 41.421f, 36.123f, 24.888f, 26.508f, 29.353f, 29.194f, 26.998f, 24.436f, 21.391f, + 17.301f, 14.548f, 13.031f, 11.659f, 9.912f, 7.669f, 6.005f, 4.862f, 2.122f, + 0.443f, 1.153f, -1.367f, -6.318f, -6.781f, -8.402f, -6.216f, -10.463f, -14.433f, + -18.330f, -22.521f, -26.063f, -33.884f, -40.277f, -37.206f, -37.740f, -40.739f, -45.229f, + -41.688f, -60.947f, -64.611f, -52.113f, -51.537f, -51.783f, -51.497f, -50.637f, -49.940f, + -48.700f, -47.625f, -46.960f, -45.704f, -44.824f, -43.412f, -42.202f, -41.678f, -40.329f, + -39.151f, -38.541f, -37.766f, -36.638f, -33.813f, -30.041f, -25.396f, -24.900f, -23.342f, + -22.650f, -21.945f, -20.934f, -20.796f, -20.041f, -22.518f, -19.865f, -18.496f, -19.235f, + -20.017f, -17.478f, -16.955f, -16.432f, -15.759f, -14.825f, -13.087f, -13.422f, -9.334f, + -5.760f, -2.366f, -5.160f, -0.638f, 6.181f, 3.427f, 3.618f, 6.817f, 11.589f, + 14.067f, 15.989f, 18.230f, 18.752f, 17.045f, 20.112f, 20.492f, 15.408f, 9.987f, + 11.525f, 18.825f, 19.966f, 20.847f, 20.766f, 19.904f, 19.042f, 18.439f, 15.836f, + 13.606f}, + {-29.534f, -28.606f, -26.267f, -24.133f, -22.578f, -22.416f, -24.348f, -25.848f, -25.482f, + -22.680f, -20.763f, -18.871f, -16.912f, -17.038f, -15.045f, -8.713f, -1.342f, 2.619f, + 6.757f, 10.698f, 12.976f, 12.173f, 8.485f, 9.875f, 12.880f, 14.783f, 16.133f, + 14.442f, 15.335f, 16.941f, 16.620f, 16.791f, 15.958f, 14.292f, 13.186f, 12.251f, + 10.988f, 12.620f, 12.392f, 12.306f, 11.345f, 10.911f, 11.437f, 11.548f, 11.653f, + 11.925f, 12.121f, 13.037f, 14.114f, 14.143f, 14.687f, 14.413f, 15.546f, 17.173f, + 18.039f, 19.665f, 21.803f, 25.167f, 26.677f, 26.579f, 23.945f, 25.821f, 26.559f, + 26.365f, 29.347f, 29.307f, 30.769f, 37.253f, 38.888f, 39.661f, 41.768f, 39.149f, + 37.528f, 24.885f, 22.161f, 26.042f, 28.379f, 26.835f, 22.973f, 20.896f, 18.491f, + 13.779f, 10.933f, 9.434f, 7.671f, 6.069f, 3.609f, 2.003f, 0.894f, -0.655f, + -2.263f, -1.309f, -4.061f, -6.957f, -7.578f, -8.739f, -7.294f, -11.854f, -17.918f, + -23.030f, -28.268f, -29.860f, -35.898f, -36.670f, -37.385f, -39.787f, -42.138f, -45.195f, + -45.061f, -55.453f, -62.910f, -51.842f, -51.870f, -52.343f, -51.908f, -51.108f, -50.025f, + -48.765f, -47.342f, -46.078f, -44.846f, -43.287f, -36.970f, -39.560f, -39.510f, -38.623f, + -37.712f, -36.781f, -35.835f, -35.697f, -33.864f, -30.636f, -26.644f, -23.290f, -23.373f, + -21.990f, -20.162f, -20.432f, -19.950f, -18.923f, -22.686f, -18.655f, -17.349f, -17.608f, + -18.441f, -16.154f, -14.742f, -13.340f, -11.956f, -11.016f, -8.422f, -7.775f, -5.407f, + -3.618f, -1.804f, -2.351f, 3.416f, 7.642f, 5.990f, 9.371f, 10.390f, 13.675f, + 15.596f, 17.129f, 19.680f, 18.246f, 17.480f, 21.296f, 21.582f, 16.817f, 11.250f, + 11.330f, 18.244f, 19.997f, 21.100f, 20.926f, 20.318f, 19.291f, 18.545f, 15.835f, + 13.606f}, + {-29.534f, -28.567f, -26.275f, -24.084f, -22.659f, -22.639f, -24.788f, -25.974f, -25.137f, + -22.735f, -20.542f, -18.309f, -16.888f, -16.889f, -15.160f, -10.606f, -2.430f, 2.596f, + 7.070f, 10.820f, 13.233f, 11.016f, 9.205f, 10.557f, 13.783f, 15.330f, 17.350f, + 14.870f, 15.141f, 17.274f, 17.402f, 17.151f, 16.203f, 15.257f, 13.789f, 11.280f, + 9.979f, 12.786f, 13.174f, 13.331f, 12.073f, 11.270f, 11.377f, 11.333f, 11.923f, + 11.909f, 11.396f, 12.718f, 13.293f, 13.580f, 14.091f, 13.883f, 15.218f, 16.849f, + 17.715f, 18.851f, 21.204f, 23.351f, 24.522f, 25.669f, 25.597f, 24.422f, 24.078f, + 24.739f, 26.572f, 26.651f, 26.556f, 24.723f, 27.491f, 29.388f, 29.757f, 30.252f, + 30.405f, 21.083f, 22.306f, 25.316f, 24.806f, 23.899f, 20.833f, 19.397f, 15.913f, + 12.030f, 10.018f, 7.034f, 3.120f, 0.157f, -1.706f, -1.729f, -2.179f, -3.385f, + -4.676f, -5.896f, -6.485f, -6.293f, -8.586f, -9.954f, -13.159f, -15.579f, -21.433f, + -29.188f, -31.586f, -29.996f, -32.125f, -35.319f, -37.459f, -39.122f, -41.603f, -43.350f, + -45.685f, -55.498f, -59.238f, -51.376f, -52.095f, -52.585f, -52.190f, -51.316f, -50.060f, + -48.863f, -47.165f, -45.280f, -43.489f, -41.733f, -39.526f, -38.323f, -38.046f, -37.488f, + -36.823f, -35.117f, -34.389f, -33.157f, -32.802f, -29.664f, -26.292f, -22.192f, -22.941f, + -21.141f, -19.373f, -19.402f, -19.348f, -19.973f, -20.580f, -17.678f, -16.125f, -16.314f, + -17.599f, -14.798f, -12.521f, -10.518f, -9.121f, -7.179f, -4.864f, -2.945f, -0.931f, + -1.488f, -1.412f, 1.061f, 6.444f, 7.310f, 9.118f, 13.256f, 13.794f, 15.661f, + 16.976f, 19.336f, 20.570f, 17.600f, 18.046f, 22.229f, 22.695f, 18.250f, 12.592f, + 11.670f, 17.494f, 20.042f, 21.326f, 21.081f, 20.763f, 19.537f, 18.638f, 15.833f, + 13.606f}, + {-29.534f, -28.530f, -26.289f, -24.067f, -22.822f, -23.074f, -25.243f, -26.004f, -24.954f, + -22.968f, -20.329f, -18.010f, -16.983f, -16.080f, -14.354f, -11.074f, -4.372f, 1.518f, + 5.604f, 9.984f, 11.130f, 9.221f, 9.324f, 11.783f, 15.313f, 16.393f, 17.994f, + 15.460f, 14.392f, 17.931f, 17.766f, 17.798f, 17.050f, 16.186f, 14.665f, 11.515f, + 9.384f, 12.415f, 13.696f, 13.271f, 12.962f, 11.571f, 11.293f, 11.556f, 11.560f, + 11.252f, 11.387f, 11.924f, 12.642f, 12.695f, 13.248f, 13.815f, 15.776f, 16.561f, + 17.676f, 18.153f, 19.402f, 20.306f, 21.609f, 21.710f, 22.552f, 23.592f, 23.874f, + 24.158f, 25.487f, 25.650f, 23.895f, 23.543f, 23.224f, 22.405f, 23.164f, 21.987f, + 21.613f, 22.600f, 23.897f, 22.409f, 21.131f, 20.606f, 19.409f, 17.875f, 14.459f, + 10.986f, 8.117f, 4.341f, 0.799f, -3.252f, -5.498f, -4.423f, -4.920f, -5.905f, + -6.858f, -7.891f, -8.608f, -10.162f, -11.773f, -15.171f, -17.218f, -20.913f, -24.764f, + -33.321f, -40.218f, -32.558f, -37.926f, -38.209f, -37.749f, -39.674f, -41.374f, -41.771f, + -42.948f, -60.784f, -57.270f, -50.777f, -51.615f, -52.626f, -52.651f, -51.871f, -50.845f, + -49.465f, -47.085f, -44.666f, -42.338f, -40.468f, -38.564f, -37.549f, -36.677f, -36.140f, + -35.448f, -33.586f, -32.200f, -32.105f, -31.325f, -28.603f, -26.253f, -21.537f, -21.334f, + -19.552f, -18.210f, -18.059f, -17.878f, -19.545f, -19.043f, -16.537f, -14.713f, -15.086f, + -16.179f, -13.377f, -10.872f, -9.945f, -7.780f, -4.723f, -1.720f, -0.118f, 2.316f, + 2.019f, 0.900f, 2.885f, 7.608f, 8.245f, 11.916f, 14.700f, 16.262f, 17.389f, + 18.572f, 22.307f, 20.306f, 16.928f, 18.661f, 22.917f, 23.777f, 19.619f, 14.001f, + 12.457f, 16.732f, 20.081f, 21.518f, 21.237f, 21.216f, 19.774f, 18.716f, 15.829f, + 13.606f}, + {-29.534f, -28.496f, -26.311f, -24.085f, -23.039f, -23.649f, -25.603f, -25.875f, -24.956f, + -23.254f, -20.240f, -18.050f, -16.978f, -15.101f, -13.134f, -10.398f, -6.265f, -1.004f, + 2.747f, 7.641f, 7.672f, 8.032f, 8.583f, 11.933f, 15.642f, 17.580f, 18.427f, + 17.008f, 14.181f, 18.376f, 18.400f, 18.596f, 18.423f, 16.737f, 15.861f, 13.041f, + 10.268f, 12.092f, 13.865f, 11.770f, 12.893f, 11.437f, 11.080f, 11.408f, 11.037f, + 11.030f, 11.070f, 11.498f, 12.303f, 12.695f, 13.045f, 14.071f, 15.137f, 16.258f, + 17.535f, 17.756f, 18.144f, 18.842f, 19.536f, 19.591f, 21.223f, 22.161f, 23.221f, + 23.766f, 24.648f, 25.294f, 23.942f, 22.578f, 21.411f, 22.815f, 23.578f, 23.056f, + 21.602f, 22.273f, 22.418f, 19.983f, 18.807f, 18.690f, 18.370f, 14.753f, 11.129f, + 7.724f, 4.420f, 1.221f, -1.586f, -4.368f, -5.696f, -7.226f, -7.397f, -7.530f, + -8.360f, -9.232f, -10.063f, -12.689f, -14.322f, -13.388f, -16.488f, -23.619f, -26.905f, + -35.211f, -45.096f, -38.578f, -38.030f, -41.799f, -41.252f, -42.056f, -41.163f, -40.995f, + -49.142f, -62.033f, -52.976f, -50.517f, -51.085f, -52.189f, -52.322f, -51.793f, -50.874f, + -49.377f, -46.861f, -44.355f, -41.707f, -39.558f, -37.366f, -36.328f, -35.238f, -34.277f, + -33.477f, -32.017f, -30.488f, -30.515f, -29.890f, -28.269f, -26.344f, -20.962f, -19.435f, + -18.198f, -16.869f, -17.173f, -16.749f, -17.795f, -17.905f, -15.208f, -12.814f, -13.859f, + -14.652f, -12.245f, -9.960f, -8.975f, -6.982f, -1.421f, 1.241f, 2.905f, 6.036f, + 6.855f, 6.745f, 6.037f, 8.528f, 11.162f, 14.446f, 16.286f, 18.736f, 19.477f, + 20.672f, 23.697f, 19.068f, 16.791f, 19.307f, 23.394f, 24.757f, 20.810f, 15.466f, + 13.563f, 16.126f, 20.104f, 21.687f, 21.397f, 21.653f, 19.993f, 18.778f, 15.822f, + 13.606f}, + {-29.534f, -28.464f, -26.339f, -24.140f, -23.286f, -24.267f, -25.768f, -25.562f, -25.096f, + -23.525f, -20.355f, -18.257f, -16.763f, -14.533f, -12.359f, -9.756f, -7.149f, -3.493f, + 0.590f, 5.289f, 5.797f, 7.286f, 8.478f, 11.428f, 15.094f, 17.672f, 19.405f, + 19.377f, 15.067f, 17.894f, 19.026f, 19.604f, 19.051f, 17.810f, 16.770f, 15.209f, + 10.938f, 11.289f, 13.526f, 12.204f, 12.710f, 11.302f, 11.000f, 11.373f, 10.266f, + 10.798f, 11.095f, 11.734f, 12.425f, 13.462f, 13.519f, 13.422f, 14.370f, 16.598f, + 16.991f, 17.320f, 17.264f, 17.511f, 17.860f, 17.937f, 19.125f, 20.146f, 21.333f, + 22.292f, 22.900f, 23.255f, 22.887f, 21.079f, 20.519f, 20.963f, 22.116f, 21.506f, + 21.856f, 21.642f, 21.071f, 19.117f, 17.640f, 17.040f, 15.249f, 11.055f, 7.234f, + 4.106f, 1.316f, -1.643f, -4.513f, -5.922f, -6.824f, -9.328f, -9.462f, -9.076f, + -9.969f, -11.327f, -11.925f, -14.430f, -15.493f, -14.123f, -18.842f, -25.891f, -28.803f, + -34.196f, -42.514f, -41.798f, -42.985f, -38.744f, -39.031f, -40.270f, -42.406f, -55.832f, + -61.905f, -57.375f, -49.849f, -49.740f, -50.228f, -51.183f, -51.476f, -50.726f, -49.790f, + -48.701f, -46.402f, -43.955f, -41.213f, -38.930f, -36.537f, -35.175f, -34.274f, -32.535f, + -31.382f, -30.620f, -28.407f, -27.424f, -28.505f, -27.223f, -25.892f, -20.950f, -18.036f, + -17.432f, -14.592f, -15.041f, -15.639f, -16.150f, -15.661f, -13.137f, -10.046f, -10.465f, + -12.864f, -10.759f, -9.082f, -6.818f, -2.774f, 2.748f, 3.512f, 6.180f, 9.512f, + 10.087f, 11.569f, 11.805f, 12.763f, 15.159f, 16.569f, 18.127f, 21.210f, 22.026f, + 22.842f, 22.319f, 17.971f, 17.579f, 19.965f, 23.702f, 25.597f, 21.821f, 16.966f, + 14.853f, 15.789f, 20.111f, 21.852f, 21.556f, 22.045f, 20.186f, 18.822f, 15.814f, + 13.606f}, + {-29.534f, -28.434f, -26.371f, -24.232f, -23.537f, -24.828f, -25.680f, -25.076f, -25.285f, + -23.785f, -20.663f, -18.416f, -16.409f, -14.427f, -12.341f, -9.797f, -7.250f, -4.436f, + -0.111f, 3.891f, 5.219f, 6.519f, 8.632f, 11.376f, 14.811f, 18.101f, 20.685f, + 20.743f, 17.722f, 16.616f, 20.199f, 19.239f, 19.550f, 18.850f, 17.776f, 16.815f, + 10.228f, 10.560f, 11.863f, 12.848f, 12.383f, 10.814f, 9.990f, 9.467f, 8.724f, + 8.724f, 9.861f, 11.498f, 12.209f, 12.620f, 13.555f, 12.307f, 14.617f, 16.878f, + 16.837f, 17.324f, 17.106f, 16.968f, 16.834f, 17.082f, 17.789f, 18.655f, 19.847f, + 20.510f, 21.241f, 21.055f, 20.271f, 19.473f, 20.184f, 20.900f, 19.708f, 18.897f, + 20.660f, 19.098f, 17.031f, 16.401f, 14.906f, 13.394f, 10.845f, 6.779f, 3.321f, + 0.947f, -1.339f, -3.585f, -6.176f, -7.632f, -7.818f, -11.888f, -12.022f, -11.809f, + -12.627f, -14.435f, -15.525f, -17.488f, -18.296f, -18.916f, -22.718f, -27.301f, -29.505f, + -33.221f, -41.849f, -46.452f, -49.391f, -48.076f, -46.629f, -55.380f, -61.322f, -62.025f, + -57.849f, -51.697f, -47.213f, -48.882f, -49.747f, -50.355f, -50.164f, -49.447f, -48.606f, + -47.684f, -45.631f, -42.905f, -40.795f, -38.646f, -36.520f, -34.764f, -33.319f, -31.304f, + -30.299f, -28.497f, -27.554f, -26.889f, -26.955f, -25.678f, -24.451f, -20.026f, -14.615f, + -15.398f, -13.244f, -13.535f, -14.214f, -13.761f, -12.755f, -10.279f, -7.756f, -6.961f, + -9.152f, -8.263f, -6.280f, -1.238f, 3.266f, 4.905f, 4.817f, 7.709f, 9.260f, + 10.859f, 13.594f, 16.237f, 17.391f, 17.733f, 19.044f, 20.710f, 22.996f, 24.228f, + 24.553f, 20.224f, 18.133f, 18.941f, 20.621f, 23.946f, 26.330f, 22.763f, 18.462f, + 16.202f, 15.746f, 20.117f, 22.038f, 21.704f, 22.365f, 20.348f, 18.847f, 15.803f, + 13.606f}, + {-29.534f, -28.407f, -26.408f, -24.360f, -23.776f, -25.245f, -25.335f, -24.458f, -25.430f, + -24.072f, -21.072f, -18.451f, -16.111f, -14.376f, -12.619f, -10.074f, -7.426f, -4.378f, + -0.526f, 2.773f, 4.359f, 6.146f, 8.428f, 11.226f, 14.202f, 18.429f, 21.061f, + 21.634f, 20.660f, 15.639f, 21.014f, 19.090f, 19.860f, 19.687f, 18.332f, 16.897f, + 10.109f, 10.507f, 11.660f, 12.555f, 11.900f, 10.266f, 8.441f, 6.789f, 5.423f, + 4.965f, 6.350f, 9.003f, 11.606f, 12.388f, 13.253f, 12.655f, 14.948f, 16.351f, + 17.226f, 16.706f, 16.908f, 17.536f, 17.037f, 16.814f, 17.135f, 17.325f, 18.243f, + 18.919f, 19.113f, 19.083f, 18.424f, 17.817f, 17.745f, 18.210f, 17.703f, 17.332f, + 15.891f, 14.393f, 13.262f, 12.632f, 12.283f, 11.519f, 9.143f, 2.284f, -0.813f, + -2.526f, -4.134f, -6.177f, -8.757f, -10.613f, -9.710f, -14.652f, -15.147f, -15.125f, + -15.817f, -16.977f, -18.970f, -20.265f, -22.017f, -23.649f, -26.133f, -28.582f, -31.021f, + -35.691f, -41.013f, -44.963f, -49.045f, -48.433f, -53.415f, -55.591f, -54.690f, -52.918f, + -50.897f, -48.248f, -46.111f, -47.174f, -48.756f, -49.020f, -48.833f, -48.238f, -47.359f, + -46.242f, -44.315f, -41.732f, -39.582f, -37.660f, -35.792f, -33.823f, -32.046f, -30.433f, + -28.682f, -27.504f, -26.697f, -25.494f, -24.943f, -23.848f, -22.915f, -19.752f, -12.825f, + -12.812f, -11.602f, -11.001f, -8.642f, -9.638f, -9.796f, -7.582f, -4.917f, -3.084f, + -5.067f, -4.465f, -0.241f, 4.007f, 4.717f, 5.275f, 6.908f, 9.235f, 10.175f, + 12.072f, 14.919f, 17.583f, 19.477f, 19.391f, 22.299f, 23.868f, 24.360f, 25.599f, + 25.519f, 19.847f, 19.522f, 20.206f, 21.378f, 24.295f, 27.027f, 23.739f, 19.893f, + 17.515f, 15.946f, 20.146f, 22.268f, 21.826f, 22.591f, 20.473f, 18.851f, 15.791f, + 13.606f}, + {-29.534f, -28.383f, -26.446f, -24.521f, -23.994f, -25.465f, -24.786f, -23.764f, -25.472f, + -24.389f, -21.451f, -18.433f, -16.028f, -14.110f, -12.621f, -9.987f, -7.736f, -4.475f, + -1.000f, 1.932f, 3.803f, 6.534f, 9.053f, 11.522f, 14.407f, 18.100f, 21.328f, + 22.850f, 21.906f, 15.404f, 20.660f, 19.967f, 20.264f, 19.632f, 18.874f, 17.958f, + 10.312f, 10.478f, 11.746f, 12.657f, 11.193f, 9.565f, 6.619f, 5.553f, 4.378f, + 2.918f, 5.584f, 5.595f, 9.730f, 11.145f, 12.948f, 13.080f, 14.912f, 15.302f, + 17.038f, 15.920f, 16.511f, 17.484f, 17.074f, 16.102f, 15.326f, 15.691f, 16.482f, + 16.949f, 16.812f, 16.935f, 16.138f, 15.907f, 15.544f, 15.883f, 16.492f, 15.735f, + 13.272f, 10.411f, 8.639f, 7.977f, 10.168f, 11.066f, 8.129f, -1.908f, -4.002f, + -5.353f, -7.487f, -9.437f, -11.423f, -13.434f, -11.938f, -14.737f, -16.386f, -17.868f, + -18.872f, -20.275f, -21.702f, -22.937f, -24.387f, -25.442f, -27.373f, -29.634f, -32.742f, + -39.915f, -41.915f, -44.798f, -45.443f, -46.111f, -48.688f, -49.108f, -49.441f, -49.118f, + -48.410f, -48.085f, -45.447f, -45.092f, -46.986f, -47.494f, -47.389f, -47.079f, -45.815f, + -44.660f, -42.654f, -40.208f, -38.043f, -36.183f, -34.993f, -31.904f, -30.090f, -29.435f, + -27.275f, -25.353f, -24.452f, -23.653f, -22.890f, -21.494f, -20.011f, -18.050f, -12.301f, + -10.243f, -9.475f, -7.803f, -4.234f, -3.343f, -5.082f, -4.925f, -1.147f, -0.265f, + -1.217f, -0.997f, 5.314f, 5.630f, 6.309f, 7.277f, 9.256f, 10.948f, 12.388f, + 14.050f, 16.309f, 18.725f, 20.608f, 21.406f, 24.482f, 25.395f, 25.777f, 26.442f, + 25.639f, 21.004f, 21.155f, 21.156f, 22.427f, 24.872f, 27.718f, 24.737f, 21.184f, + 18.724f, 16.301f, 20.214f, 22.547f, 21.903f, 22.707f, 20.558f, 18.836f, 15.777f, + 13.606f}, + {-29.534f, -28.360f, -26.486f, -24.712f, -24.191f, -25.477f, -24.130f, -23.048f, -25.408f, + -24.685f, -21.699f, -18.444f, -16.113f, -13.801f, -12.309f, -9.675f, -7.589f, -4.570f, + -1.001f, 1.475f, 3.523f, 6.761f, 9.857f, 12.372f, 15.444f, 18.084f, 21.431f, + 23.632f, 22.234f, 16.447f, 20.426f, 20.668f, 20.353f, 19.843f, 18.436f, 18.344f, + 9.014f, 9.750f, 12.079f, 11.999f, 10.503f, 8.653f, 4.975f, 3.781f, 2.246f, + 1.645f, 2.415f, 3.502f, 5.790f, 9.444f, 12.206f, 12.606f, 13.223f, 14.382f, + 15.286f, 15.192f, 16.309f, 16.976f, 16.372f, 14.960f, 13.996f, 13.772f, 13.965f, + 14.612f, 14.297f, 13.305f, 12.679f, 13.017f, 14.108f, 13.861f, 13.895f, 12.488f, + 9.925f, 7.125f, 4.912f, 3.173f, 4.095f, 4.692f, 2.022f, -4.416f, -3.940f, + -7.695f, -10.443f, -12.303f, -13.664f, -15.777f, -16.489f, -14.881f, -17.194f, -20.209f, + -21.303f, -23.003f, -24.060f, -25.607f, -26.886f, -27.337f, -28.235f, -30.513f, -35.046f, + -40.224f, -44.354f, -47.397f, -48.004f, -47.447f, -48.250f, -49.513f, -46.050f, -49.355f, + -47.013f, -47.377f, -46.130f, -44.366f, -45.322f, -45.958f, -45.797f, -45.147f, -43.894f, + -42.784f, -40.736f, -38.351f, -36.460f, -34.880f, -33.563f, -30.907f, -29.118f, -27.237f, + -25.859f, -23.613f, -22.436f, -21.652f, -20.761f, -19.133f, -16.691f, -13.933f, -10.826f, + -6.615f, -5.876f, -3.928f, -1.501f, 1.619f, 0.644f, -1.769f, 1.828f, 3.632f, + 2.021f, 3.325f, 6.336f, 7.864f, 8.589f, 9.926f, 11.257f, 13.325f, 14.705f, + 16.150f, 18.747f, 20.498f, 21.681f, 22.930f, 25.184f, 26.111f, 27.078f, 27.288f, + 25.416f, 22.193f, 22.420f, 22.084f, 23.818f, 25.651f, 28.363f, 25.642f, 22.289f, + 19.791f, 16.725f, 20.326f, 22.869f, 21.920f, 22.706f, 20.602f, 18.801f, 15.762f, + 13.606f}, + {-29.534f, -28.340f, -26.525f, -24.925f, -24.374f, -25.315f, -23.486f, -22.358f, -25.267f, + -24.891f, -21.792f, -18.481f, -16.134f, -13.731f, -12.030f, -9.565f, -6.988f, -4.130f, + -0.857f, 0.665f, 2.282f, 5.983f, 9.333f, 12.602f, 16.203f, 18.830f, 21.515f, + 23.954f, 22.331f, 20.504f, 20.183f, 20.654f, 20.012f, 19.899f, 17.482f, 16.638f, + 7.479f, 8.184f, 11.427f, 10.762f, 9.197f, 7.200f, 3.749f, 1.598f, 0.404f, + 0.303f, 0.909f, 1.372f, 2.333f, 5.162f, 9.582f, 10.733f, 11.023f, 12.219f, + 12.741f, 13.508f, 15.564f, 15.850f, 15.465f, 14.532f, 12.757f, 11.251f, 11.005f, + 11.311f, 10.572f, 9.649f, 8.775f, 9.090f, 9.253f, 9.141f, 8.976f, 8.064f, + 5.950f, 3.976f, 1.893f, -0.150f, -1.536f, -2.332f, -4.608f, -8.972f, -7.075f, + -10.445f, -13.513f, -15.656f, -16.756f, -18.469f, -19.917f, -18.278f, -18.681f, -21.158f, + -23.068f, -24.939f, -25.949f, -28.060f, -30.992f, -32.582f, -31.621f, -31.721f, -36.836f, + -42.286f, -45.819f, -47.163f, -46.971f, -46.342f, -47.714f, -49.379f, -46.043f, -48.015f, + -45.491f, -45.293f, -45.018f, -43.774f, -43.859f, -44.025f, -43.866f, -43.113f, -41.843f, + -40.821f, -38.730f, -36.561f, -34.719f, -33.046f, -31.231f, -29.284f, -27.727f, -25.545f, + -23.449f, -21.748f, -20.152f, -19.353f, -18.212f, -16.126f, -12.998f, -9.824f, -8.525f, + -3.908f, -1.681f, -0.165f, 1.911f, 4.614f, 4.160f, 3.050f, 4.064f, 6.808f, + 6.086f, 7.922f, 7.859f, 10.619f, 11.212f, 12.553f, 13.844f, 15.825f, 17.506f, + 18.157f, 20.795f, 22.436f, 24.306f, 24.644f, 25.488f, 27.180f, 27.821f, 28.285f, + 25.728f, 23.068f, 23.616f, 23.293f, 25.360f, 26.509f, 28.904f, 26.360f, 23.221f, + 20.705f, 17.158f, 20.472f, 23.211f, 21.868f, 22.593f, 20.607f, 18.748f, 15.745f, + 13.606f}, + {-29.534f, -28.323f, -26.562f, -25.153f, -24.559f, -25.049f, -22.961f, -21.728f, -25.079f, + -24.980f, -21.779f, -18.484f, -15.923f, -13.872f, -11.988f, -9.555f, -6.503f, -3.460f, + -0.955f, -0.434f, 0.556f, 4.590f, 7.992f, 11.581f, 15.913f, 18.859f, 21.822f, + 23.423f, 22.600f, 23.171f, 20.408f, 20.447f, 19.787f, 18.797f, 18.335f, 14.916f, + 6.894f, 6.397f, 10.129f, 9.795f, 7.817f, 5.529f, 2.182f, 0.119f, -0.241f, + 0.109f, 0.584f, 0.501f, 0.903f, 2.104f, 5.104f, 7.669f, 8.589f, 9.823f, + 11.306f, 12.530f, 14.625f, 14.879f, 14.450f, 13.633f, 11.223f, 9.681f, 8.609f, + 7.592f, 7.036f, 6.088f, 5.461f, 4.753f, 4.336f, 4.241f, 3.829f, 3.621f, + 2.030f, 0.824f, -0.181f, -1.958f, -4.199f, -4.985f, -7.527f, -10.094f, -10.236f, + -13.189f, -16.340f, -18.297f, -19.283f, -20.161f, -20.145f, -17.871f, -22.341f, -23.581f, + -24.915f, -26.435f, -27.652f, -29.410f, -32.593f, -34.083f, -32.110f, -32.764f, -38.300f, + -43.846f, -44.928f, -45.839f, -45.952f, -45.561f, -47.401f, -48.842f, -47.286f, -46.678f, + -43.993f, -42.795f, -42.581f, -42.499f, -41.975f, -41.681f, -41.460f, -40.880f, -39.419f, + -38.216f, -36.282f, -34.362f, -32.558f, -30.700f, -28.955f, -27.211f, -25.209f, -23.057f, + -20.984f, -19.480f, -17.852f, -16.257f, -15.080f, -12.938f, -10.316f, -8.298f, -6.622f, + -1.695f, 1.467f, 3.299f, 5.254f, 6.972f, 8.089f, 8.817f, 8.859f, 10.225f, + 10.630f, 12.506f, 11.241f, 13.097f, 13.919f, 14.631f, 16.514f, 18.568f, 19.687f, + 20.247f, 22.495f, 25.775f, 27.264f, 25.947f, 25.211f, 26.358f, 27.861f, 28.837f, + 26.779f, 24.314f, 25.168f, 24.827f, 26.805f, 27.356f, 29.337f, 26.897f, 24.063f, + 21.479f, 17.570f, 20.634f, 23.544f, 21.747f, 22.382f, 20.576f, 18.677f, 15.727f, + 13.606f}, + {-29.534f, -28.307f, -26.595f, -25.386f, -24.759f, -24.766f, -22.630f, -21.187f, -24.852f, + -24.978f, -21.721f, -18.424f, -15.599f, -13.958f, -12.060f, -9.273f, -6.221f, -2.951f, + -0.922f, -1.137f, -0.525f, 3.391f, 6.813f, 9.807f, 14.136f, 16.398f, 20.133f, + 22.319f, 22.981f, 23.618f, 20.622f, 20.384f, 19.802f, 18.224f, 18.118f, 13.595f, + 8.774f, 5.026f, 9.085f, 9.604f, 6.172f, 3.091f, 0.857f, -0.773f, -0.700f, + -0.390f, -0.086f, 0.009f, 0.049f, 0.646f, 1.783f, 3.483f, 4.260f, 8.055f, + 9.174f, 10.329f, 12.785f, 13.191f, 12.770f, 12.726f, 9.533f, 9.073f, 7.934f, + 5.925f, 4.877f, 4.174f, 2.453f, -0.060f, -0.562f, -0.721f, -1.083f, -1.502f, + -1.105f, -1.288f, -2.209f, -4.359f, -6.269f, -8.014f, -9.556f, -10.425f, -11.526f, + -14.884f, -18.042f, -19.747f, -20.649f, -20.933f, -20.016f, -18.540f, -21.642f, -24.084f, + -25.554f, -27.553f, -29.007f, -30.444f, -32.627f, -33.322f, -31.783f, -33.222f, -37.410f, + -42.178f, -44.943f, -45.380f, -44.930f, -44.724f, -45.952f, -47.015f, -46.129f, -44.039f, + -41.785f, -41.476f, -40.988f, -40.770f, -40.204f, -39.314f, -38.631f, -37.986f, -36.508f, + -35.289f, -33.678f, -32.003f, -30.126f, -28.267f, -26.452f, -24.709f, -22.361f, -20.281f, + -18.176f, -16.437f, -14.768f, -13.310f, -11.757f, -9.847f, -8.144f, -6.617f, -3.094f, + 3.321f, 4.400f, 6.475f, 7.926f, 9.488f, 10.944f, 11.332f, 12.135f, 12.578f, + 13.927f, 15.054f, 14.218f, 15.729f, 16.775f, 17.526f, 19.083f, 20.742f, 21.892f, + 22.070f, 25.512f, 27.877f, 28.289f, 26.441f, 25.298f, 23.893f, 27.319f, 28.336f, + 28.198f, 26.265f, 26.961f, 26.565f, 28.030f, 28.185f, 29.701f, 27.333f, 24.904f, + 22.148f, 17.951f, 20.797f, 23.842f, 21.570f, 22.095f, 20.515f, 18.592f, 15.708f, + 13.606f}, + {-29.534f, -28.293f, -26.622f, -25.614f, -24.987f, -24.554f, -22.515f, -20.761f, -24.562f, + -24.936f, -21.620f, -18.324f, -15.461f, -13.896f, -12.037f, -8.827f, -5.786f, -2.471f, + -0.790f, -1.503f, -0.961f, 2.922f, 6.239f, 8.821f, 12.979f, 14.635f, 17.858f, + 21.563f, 21.930f, 23.508f, 21.269f, 20.477f, 19.696f, 19.168f, 17.126f, 14.163f, + 11.788f, 5.062f, 7.674f, 8.541f, 4.380f, 0.653f, -0.027f, -1.486f, -1.647f, + -1.471f, -1.008f, -0.884f, -0.609f, -0.264f, 0.385f, 1.329f, 2.062f, 4.181f, + 7.140f, 8.827f, 9.601f, 11.002f, 10.766f, 11.135f, 8.577f, 8.330f, 7.841f, + 5.310f, 4.174f, 2.808f, 0.820f, -1.792f, -2.844f, -3.977f, -5.400f, -4.946f, + -3.386f, -3.311f, -4.284f, -5.000f, -7.599f, -8.469f, -9.436f, -10.789f, -12.420f, + -15.590f, -19.064f, -20.542f, -21.296f, -21.588f, -21.195f, -20.119f, -21.686f, -23.285f, + -24.762f, -27.578f, -29.336f, -30.396f, -32.167f, -33.711f, -32.627f, -34.324f, -38.835f, + -43.913f, -44.976f, -45.302f, -44.709f, -44.240f, -44.368f, -44.495f, -44.210f, -42.101f, + -40.665f, -40.495f, -40.001f, -38.726f, -38.237f, -36.855f, -36.330f, -35.496f, -33.596f, + -32.572f, -31.137f, -29.093f, -27.592f, -25.804f, -23.791f, -21.602f, -19.551f, -17.518f, + -15.655f, -13.083f, -11.122f, -10.176f, -8.891f, -7.311f, -5.723f, -2.479f, 2.603f, + 6.164f, 7.456f, 8.498f, 9.465f, 12.220f, 12.907f, 13.646f, 14.559f, 15.401f, + 15.644f, 15.977f, 16.970f, 18.433f, 19.177f, 20.583f, 21.683f, 23.070f, 23.352f, + 24.755f, 27.946f, 27.195f, 29.648f, 28.063f, 26.408f, 22.776f, 26.390f, 27.509f, + 29.934f, 28.550f, 28.658f, 28.303f, 29.025f, 28.993f, 30.020f, 27.742f, 25.774f, + 22.761f, 18.301f, 20.959f, 24.094f, 21.358f, 21.763f, 20.431f, 18.494f, 15.688f, + 13.606f}, + {-29.534f, -28.282f, -26.642f, -25.827f, -25.249f, -24.475f, -22.587f, -20.475f, -24.190f, + -24.867f, -21.385f, -18.181f, -15.624f, -13.872f, -11.846f, -8.631f, -5.248f, -1.991f, + -0.949f, -1.640f, -0.827f, 3.132f, 6.236f, 8.701f, 12.512f, 14.533f, 16.655f, + 20.855f, 20.788f, 22.296f, 21.305f, 20.201f, 19.292f, 18.956f, 17.226f, 14.594f, + 13.436f, 5.751f, 6.644f, 7.083f, 3.436f, -0.311f, -0.955f, -2.237f, -2.610f, + -2.407f, -2.051f, -1.758f, -1.342f, -0.987f, -0.399f, -0.179f, 0.834f, 2.316f, + 4.134f, 7.689f, 8.433f, 7.828f, 8.190f, 8.244f, 6.125f, 6.973f, 6.946f, + 6.505f, 4.848f, 2.453f, -0.996f, -2.656f, -4.397f, -5.797f, -6.555f, -6.569f, + -6.106f, -4.485f, -4.937f, -5.937f, -8.796f, -8.344f, -10.683f, -12.027f, -12.752f, + -16.214f, -19.439f, -20.913f, -21.514f, -21.859f, -22.091f, -22.276f, -22.717f, -23.579f, + -24.158f, -26.516f, -28.659f, -30.447f, -32.521f, -34.264f, -33.098f, -39.220f, -43.167f, + -43.856f, -44.800f, -44.983f, -44.197f, -43.731f, -43.209f, -42.845f, -42.021f, -40.721f, + -39.372f, -38.779f, -37.900f, -36.333f, -35.683f, -34.246f, -33.720f, -32.627f, -30.706f, + -29.525f, -28.021f, -26.299f, -24.581f, -22.825f, -20.876f, -18.355f, -16.199f, -14.718f, + -11.314f, -10.211f, -7.959f, -6.733f, -5.796f, -4.227f, -1.032f, 3.678f, 8.258f, + 9.743f, 10.261f, 11.194f, 12.947f, 15.496f, 16.458f, 16.362f, 17.394f, 18.783f, + 17.655f, 18.422f, 19.536f, 20.824f, 22.085f, 23.143f, 24.357f, 25.318f, 25.262f, + 28.261f, 28.382f, 27.312f, 31.441f, 29.960f, 27.378f, 23.593f, 25.997f, 27.890f, + 31.962f, 30.633f, 30.181f, 29.798f, 29.830f, 29.718f, 30.279f, 28.148f, 26.623f, + 23.367f, 18.629f, 21.135f, 24.300f, 21.139f, 21.417f, 20.331f, 18.386f, 15.667f, + 13.606f}, + {-29.534f, -28.272f, -26.653f, -26.012f, -25.540f, -24.553f, -22.770f, -20.350f, -23.759f, + -24.724f, -20.888f, -17.915f, -15.820f, -14.027f, -11.561f, -8.656f, -4.943f, -1.722f, + -1.094f, -1.446f, -0.229f, 3.584f, 6.511f, 8.641f, 11.696f, 13.643f, 15.404f, + 20.003f, 20.184f, 21.343f, 20.022f, 20.294f, 19.071f, 18.077f, 17.314f, 14.671f, + 11.769f, 6.811f, 6.198f, 6.000f, 3.157f, -0.714f, -1.642f, -2.932f, -3.326f, + -2.775f, -2.261f, -2.167f, -2.026f, -1.722f, -1.641f, -1.560f, -1.095f, -0.365f, + 1.495f, 3.169f, 5.927f, 7.296f, 5.830f, 5.750f, 4.245f, 6.211f, 6.396f, + 5.892f, 4.913f, 3.017f, -0.006f, -4.412f, -5.691f, -6.880f, -8.022f, -8.415f, + -7.943f, -6.513f, -6.078f, -7.231f, -9.534f, -11.124f, -13.996f, -15.596f, -14.751f, + -17.445f, -20.083f, -21.290f, -21.931f, -22.295f, -22.536f, -22.173f, -23.051f, -23.019f, + -23.655f, -25.561f, -28.391f, -30.855f, -33.639f, -33.698f, -35.616f, -39.996f, -42.968f, + -43.138f, -44.051f, -43.903f, -43.356f, -42.788f, -41.867f, -40.846f, -39.910f, -38.802f, + -37.599f, -36.998f, -35.505f, -34.013f, -33.506f, -31.353f, -30.697f, -29.254f, -27.658f, + -26.335f, -24.638f, -22.920f, -21.042f, -19.450f, -17.722f, -15.509f, -13.274f, -11.287f, + -8.784f, -6.815f, -4.985f, -3.320f, -2.073f, -0.858f, 3.589f, 9.570f, 11.945f, + 14.045f, 13.752f, 14.709f, 16.672f, 21.733f, 22.083f, 20.108f, 20.634f, 20.752f, + 21.098f, 21.899f, 22.735f, 23.510f, 24.604f, 25.271f, 26.784f, 27.169f, 28.940f, + 30.034f, 29.388f, 29.372f, 32.417f, 31.408f, 29.002f, 25.739f, 27.302f, 29.794f, + 33.744f, 32.387f, 31.585f, 30.900f, 30.526f, 30.260f, 30.470f, 28.566f, 27.367f, + 24.002f, 18.959f, 21.349f, 24.475f, 20.943f, 21.087f, 20.224f, 18.272f, 15.646f, + 13.606f}, + {-29.534f, -28.263f, -26.653f, -26.159f, -25.843f, -24.765f, -22.968f, -20.391f, -23.348f, + -24.438f, -20.073f, -17.417f, -15.658f, -14.194f, -11.280f, -8.517f, -4.805f, -1.575f, + -0.905f, -1.260f, 0.278f, 4.057f, 6.916f, 8.822f, 11.336f, 12.973f, 15.430f, + 19.545f, 20.167f, 20.790f, 19.614f, 19.895f, 19.200f, 18.040f, 17.916f, 14.834f, + 11.451f, 5.535f, 5.743f, 5.537f, 2.474f, -0.640f, -1.959f, -3.603f, -3.663f, + -3.122f, -2.337f, -2.318f, -2.734f, -2.671f, -2.633f, -2.698f, -2.480f, -2.203f, + -1.459f, -0.245f, 2.140f, 4.474f, 4.527f, 4.393f, 2.771f, 4.303f, 5.898f, + 4.045f, 3.854f, 4.111f, -0.131f, -5.005f, -6.197f, -7.124f, -8.115f, -8.328f, + -9.057f, -9.112f, -8.244f, -9.230f, -9.562f, -12.152f, -16.348f, -18.501f, -18.860f, + -20.533f, -21.769f, -22.124f, -22.878f, -23.737f, -24.189f, -23.806f, -23.941f, -24.958f, + -25.693f, -26.828f, -28.634f, -30.567f, -32.293f, -36.260f, -38.493f, -40.314f, -42.047f, + -42.403f, -42.806f, -42.547f, -42.499f, -41.398f, -40.544f, -38.256f, -37.762f, -36.087f, + -35.396f, -34.331f, -32.982f, -31.264f, -30.634f, -28.820f, -27.700f, -26.168f, -24.327f, + -22.898f, -21.004f, -19.342f, -17.633f, -15.731f, -14.074f, -12.089f, -9.715f, -7.512f, + -5.421f, -3.706f, -2.034f, -0.374f, 1.179f, 3.419f, 5.205f, 13.012f, 15.565f, + 17.046f, 17.574f, 17.416f, 20.574f, 23.794f, 24.159f, 23.632f, 22.247f, 22.806f, + 23.644f, 25.065f, 25.718f, 26.526f, 26.942f, 27.951f, 28.522f, 29.294f, 31.305f, + 32.328f, 32.519f, 32.779f, 33.877f, 33.422f, 31.841f, 28.667f, 29.860f, 32.108f, + 34.932f, 34.082f, 32.760f, 31.651f, 31.171f, 30.564f, 30.640f, 29.038f, 27.971f, + 24.682f, 19.333f, 21.627f, 24.639f, 20.796f, 20.801f, 20.118f, 18.153f, 15.624f, + 13.606f}, + {-29.534f, -28.256f, -26.642f, -26.259f, -26.133f, -25.045f, -23.088f, -20.574f, -23.078f, + -23.987f, -19.045f, -16.662f, -15.058f, -14.084f, -11.018f, -8.156f, -4.579f, -1.359f, + -0.807f, -1.197f, 0.590f, 4.418f, 7.168f, 8.956f, 11.037f, 13.241f, 16.300f, + 19.093f, 20.293f, 20.826f, 19.266f, 20.206f, 19.210f, 18.121f, 17.901f, 15.591f, + 10.900f, 3.606f, 5.572f, 5.797f, 2.227f, -0.702f, -2.308f, -3.900f, -4.122f, + -3.331f, -2.559f, -2.622f, -2.987f, -3.313f, -3.549f, -3.538f, -3.384f, -3.283f, + -3.391f, -3.058f, -1.129f, -0.291f, -0.997f, 0.928f, 3.222f, 1.999f, 1.615f, + 0.776f, 2.013f, 1.577f, -1.021f, -4.808f, -6.506f, -7.122f, -8.053f, -10.772f, + -13.258f, -11.781f, -10.629f, -11.526f, -10.635f, -11.741f, -14.045f, -17.111f, -19.403f, + -22.076f, -23.277f, -22.811f, -23.608f, -24.569f, -25.425f, -24.954f, -24.536f, -25.035f, + -26.783f, -28.145f, -29.402f, -29.285f, -29.491f, -35.000f, -38.238f, -40.251f, -41.526f, + -41.158f, -41.154f, -41.139f, -41.012f, -39.660f, -38.226f, -35.567f, -34.479f, -33.613f, + -32.651f, -31.682f, -30.161f, -28.592f, -27.278f, -25.763f, -24.512f, -22.480f, -20.921f, + -19.331f, -17.529f, -15.720f, -13.944f, -12.196f, -10.294f, -8.541f, -6.086f, -4.212f, + -2.944f, -0.882f, 0.906f, 2.495f, 4.479f, 6.530f, 9.463f, 16.154f, 16.939f, + 19.469f, 20.133f, 20.523f, 25.154f, 22.200f, 22.967f, 24.226f, 23.558f, 25.362f, + 26.754f, 27.942f, 28.379f, 29.298f, 29.659f, 30.561f, 30.422f, 30.952f, 33.432f, + 36.870f, 36.246f, 36.792f, 36.234f, 35.818f, 34.233f, 31.371f, 32.384f, 33.988f, + 35.832f, 35.695f, 33.562f, 32.213f, 31.708f, 30.678f, 30.872f, 29.608f, 28.485f, + 25.403f, 19.809f, 21.980f, 24.807f, 20.713f, 20.577f, 20.020f, 18.034f, 15.602f, + 13.606f}, + {-29.534f, -28.250f, -26.617f, -26.304f, -26.375f, -25.296f, -23.058f, -20.838f, -23.040f, + -23.435f, -18.047f, -15.786f, -14.363f, -13.658f, -10.686f, -7.833f, -4.338f, -1.255f, + -1.064f, -0.951f, 0.919f, 4.547f, 7.230f, 8.905f, 11.185f, 14.140f, 16.395f, + 18.806f, 19.547f, 20.854f, 18.024f, 20.431f, 19.629f, 18.685f, 17.670f, 15.851f, + 12.050f, 5.564f, 5.138f, 5.938f, 2.379f, -0.884f, -2.762f, -3.962f, -4.062f, + -3.709f, -2.761f, -2.792f, -3.224f, -3.872f, -4.418f, -4.363f, -3.891f, -4.131f, + -4.522f, -5.039f, -3.419f, -2.653f, -2.668f, -3.127f, 0.819f, 1.266f, 1.238f, + 0.399f, -0.106f, -1.420f, -3.140f, -5.195f, -6.299f, -7.063f, -9.089f, -11.087f, + -13.172f, -12.496f, -12.625f, -13.543f, -14.600f, -15.855f, -15.390f, -15.738f, -18.862f, + -21.278f, -22.955f, -23.608f, -24.334f, -24.843f, -24.685f, -26.061f, -25.205f, -25.323f, + -26.444f, -27.257f, -28.446f, -28.979f, -30.149f, -34.620f, -37.568f, -39.070f, -39.960f, + -39.300f, -39.489f, -39.383f, -38.420f, -36.962f, -35.304f, -32.953f, -32.026f, -31.008f, + -29.837f, -28.639f, -26.902f, -25.580f, -24.024f, -22.280f, -20.846f, -18.932f, -17.083f, + -15.407f, -13.845f, -12.010f, -10.187f, -8.432f, -6.732f, -4.720f, -2.708f, -0.658f, + 0.245f, 2.016f, 3.754f, 5.100f, 6.963f, 9.329f, 11.785f, 17.415f, 17.827f, + 20.909f, 23.713f, 25.060f, 27.226f, 23.321f, 23.476f, 24.693f, 26.311f, 28.283f, + 29.673f, 30.635f, 31.088f, 31.974f, 32.483f, 33.577f, 32.792f, 33.424f, 37.363f, + 41.199f, 39.911f, 40.070f, 39.109f, 38.617f, 36.012f, 33.721f, 34.567f, 35.510f, + 36.671f, 36.683f, 34.117f, 32.760f, 32.038f, 30.772f, 31.209f, 30.266f, 29.014f, + 26.150f, 20.446f, 22.401f, 24.979f, 20.701f, 20.428f, 19.935f, 17.917f, 15.581f, + 13.606f}, + {-29.534f, -28.246f, -26.580f, -26.289f, -26.532f, -25.409f, -22.845f, -21.094f, -23.235f, + -22.893f, -17.339f, -15.041f, -13.997f, -13.152f, -10.213f, -7.564f, -4.204f, -1.453f, + -1.358f, -0.674f, 1.174f, 4.501f, 7.208f, 8.955f, 11.809f, 14.731f, 16.520f, + 18.815f, 20.854f, 23.434f, 18.817f, 20.713f, 20.074f, 18.905f, 17.502f, 15.646f, + 13.723f, 7.760f, 4.432f, 5.397f, 2.244f, -0.927f, -2.886f, -3.938f, -3.716f, + -3.776f, -3.144f, -3.111f, -3.646f, -4.572f, -5.101f, -4.878f, -4.563f, -4.772f, + -5.261f, -5.835f, -4.858f, -4.091f, -3.797f, -5.182f, -3.905f, -3.009f, -1.594f, + -2.679f, -2.465f, -1.567f, -2.466f, -3.986f, -5.118f, -5.575f, -7.870f, -9.134f, + -11.478f, -12.859f, -13.222f, -15.030f, -16.752f, -17.952f, -16.929f, -16.499f, -18.510f, + -20.688f, -23.055f, -24.423f, -25.519f, -26.300f, -26.418f, -26.432f, -24.877f, -25.388f, + -26.060f, -26.085f, -29.960f, -30.764f, -31.201f, -33.904f, -36.179f, -37.537f, -37.385f, + -37.010f, -37.320f, -37.399f, -35.243f, -33.702f, -32.043f, -30.662f, -28.905f, -27.907f, + -26.815f, -25.131f, -23.982f, -22.411f, -20.631f, -18.862f, -17.198f, -15.014f, -13.466f, + -11.646f, -10.086f, -8.078f, -6.433f, -4.579f, -3.179f, -1.095f, 0.755f, 2.147f, + 3.928f, 5.288f, 6.702f, 7.742f, 10.150f, 11.862f, 15.248f, 18.555f, 20.494f, + 23.481f, 26.235f, 27.799f, 28.971f, 26.266f, 26.092f, 27.164f, 29.082f, 31.343f, + 32.320f, 33.849f, 33.897f, 34.025f, 35.043f, 36.324f, 35.964f, 35.925f, 41.538f, + 44.442f, 43.236f, 42.997f, 41.712f, 41.185f, 37.930f, 35.956f, 36.487f, 36.862f, + 37.299f, 36.850f, 34.705f, 33.417f, 32.231f, 31.071f, 31.627f, 30.935f, 29.639f, + 26.916f, 21.285f, 22.867f, 25.144f, 20.757f, 20.356f, 19.868f, 17.805f, 15.560f, + 13.606f}, + {-29.534f, -28.242f, -26.529f, -26.211f, -26.567f, -25.287f, -22.453f, -21.242f, -23.531f, + -22.443f, -17.057f, -14.659f, -14.079f, -12.782f, -9.683f, -7.125f, -4.051f, -1.746f, + -1.504f, -0.601f, 1.415f, 4.354f, 7.010f, 9.087f, 12.062f, 14.344f, 16.733f, + 18.622f, 22.414f, 25.395f, 17.324f, 20.967f, 20.212f, 18.446f, 17.052f, 15.592f, + 14.008f, 6.490f, 4.091f, 5.898f, 2.274f, -0.595f, -2.809f, -3.783f, -3.561f, + -3.634f, -3.351f, -3.574f, -4.462f, -5.411f, -5.787f, -5.376f, -5.141f, -5.317f, + -5.660f, -6.065f, -5.607f, -5.039f, -4.923f, -6.136f, -6.361f, -6.316f, -6.291f, + -7.050f, -5.754f, -3.362f, -3.375f, -2.179f, -2.832f, -5.439f, -8.122f, -9.211f, + -11.608f, -14.624f, -13.887f, -13.644f, -14.055f, -14.031f, -15.588f, -16.208f, -17.214f, + -19.887f, -23.170f, -24.563f, -25.385f, -26.404f, -27.480f, -26.624f, -25.708f, -23.806f, + -24.872f, -26.482f, -31.513f, -30.656f, -31.795f, -32.880f, -34.485f, -35.051f, -34.629f, + -34.909f, -34.948f, -34.770f, -32.030f, -30.653f, -28.993f, -28.057f, -26.637f, -25.342f, + -24.029f, -22.536f, -20.668f, -18.864f, -17.224f, -15.650f, -13.490f, -11.367f, -9.574f, + -8.187f, -6.173f, -4.177f, -2.524f, -0.843f, 0.591f, 2.565f, 4.336f, 5.926f, + 7.351f, 8.545f, 9.396f, 11.124f, 13.491f, 15.579f, 18.091f, 20.451f, 23.436f, + 26.258f, 29.085f, 31.982f, 31.575f, 29.104f, 29.242f, 30.649f, 31.850f, 33.923f, + 35.358f, 36.569f, 36.589f, 36.682f, 37.666f, 37.750f, 39.190f, 37.863f, 45.059f, + 47.180f, 46.319f, 45.749f, 43.608f, 42.885f, 39.923f, 37.855f, 38.034f, 37.981f, + 37.814f, 36.818f, 35.394f, 34.200f, 32.550f, 31.700f, 32.072f, 31.538f, 30.365f, + 27.705f, 22.335f, 23.347f, 25.278f, 20.867f, 20.355f, 19.821f, 17.700f, 15.539f, + 13.606f}, + {-29.534f, -28.239f, -26.464f, -26.071f, -26.452f, -24.869f, -21.918f, -21.204f, -23.710f, + -22.079f, -17.151f, -14.730f, -14.411f, -12.540f, -9.247f, -6.561f, -3.853f, -1.975f, + -1.575f, -0.467f, 1.717f, 4.218f, 6.859f, 9.469f, 12.251f, 13.972f, 16.793f, + 18.772f, 22.803f, 25.916f, 16.085f, 20.824f, 19.862f, 18.565f, 17.132f, 15.725f, + 13.657f, 4.309f, 4.715f, 6.285f, 3.189f, 0.018f, -2.113f, -3.143f, -3.307f, + -3.480f, -3.805f, -4.364f, -5.423f, -6.179f, -6.434f, -6.055f, -5.731f, -5.728f, + -5.983f, -6.282f, -5.989f, -6.105f, -6.230f, -7.895f, -7.315f, -8.015f, -7.855f, + -8.138f, -9.589f, -5.665f, -4.489f, -3.181f, -2.733f, -4.289f, -6.951f, -10.452f, + -12.102f, -14.588f, -14.055f, -12.755f, -12.681f, -12.817f, -15.773f, -17.097f, -16.003f, + -18.909f, -22.621f, -23.825f, -23.819f, -25.313f, -26.465f, -26.553f, -26.351f, -22.262f, + -23.154f, -28.256f, -29.277f, -28.685f, -29.672f, -31.179f, -32.439f, -32.478f, -32.148f, + -32.537f, -32.354f, -30.790f, -29.042f, -27.148f, -25.734f, -25.770f, -25.234f, -24.217f, + -22.639f, -20.673f, -18.396f, -16.451f, -14.359f, -12.354f, -11.376f, -8.325f, -6.148f, + -3.844f, -2.087f, -0.493f, 1.281f, 2.957f, 4.435f, 6.479f, 7.850f, 9.343f, + 10.692f, 11.747f, 12.607f, 13.863f, 16.119f, 18.567f, 20.741f, 22.972f, 25.370f, + 27.854f, 29.490f, 35.015f, 34.888f, 32.864f, 32.376f, 33.501f, 34.146f, 36.334f, + 37.761f, 38.770f, 39.091f, 39.341f, 40.221f, 39.729f, 41.214f, 42.487f, 47.700f, + 49.366f, 48.852f, 47.873f, 45.463f, 44.498f, 41.852f, 39.427f, 39.311f, 38.881f, + 38.556f, 37.228f, 36.046f, 34.965f, 33.166f, 32.558f, 32.517f, 32.070f, 31.126f, + 28.539f, 23.559f, 23.820f, 25.361f, 21.016f, 20.412f, 19.795f, 17.606f, 15.518f, + 13.606f}, + {-29.534f, -28.237f, -26.386f, -25.871f, -26.174f, -24.139f, -21.295f, -20.946f, -23.558f, + -21.715f, -17.443f, -15.161f, -14.750f, -12.341f, -8.932f, -6.121f, -3.784f, -2.347f, + -1.585f, -0.189f, 1.912f, 4.171f, 6.815f, 9.826f, 12.148f, 13.995f, 16.796f, + 18.458f, 22.500f, 25.721f, 15.910f, 19.986f, 19.763f, 18.436f, 17.292f, 15.631f, + 13.487f, 4.101f, 5.010f, 7.583f, 4.527f, 0.678f, -1.333f, -2.557f, -3.547f, + -3.644f, -4.667f, -5.425f, -6.457f, -7.085f, -6.970f, -6.696f, -6.402f, -6.215f, + -6.482f, -6.959f, -6.724f, -6.993f, -7.559f, -8.027f, -7.765f, -8.684f, -10.449f, + -10.558f, -10.922f, -10.188f, -6.162f, -4.054f, -3.886f, -3.804f, -6.280f, -9.680f, + -10.965f, -12.365f, -12.864f, -13.234f, -13.124f, -14.264f, -16.022f, -17.016f, -14.816f, + -17.716f, -21.737f, -23.111f, -22.620f, -23.000f, -23.425f, -23.525f, -22.296f, -22.190f, + -24.792f, -26.740f, -26.675f, -26.888f, -28.177f, -28.554f, -29.603f, -29.952f, -29.795f, + -29.550f, -28.963f, -27.480f, -25.942f, -25.165f, -24.621f, -24.503f, -23.624f, -22.492f, + -20.738f, -19.030f, -17.043f, -14.920f, -12.920f, -10.803f, -8.570f, -6.513f, -3.643f, + -0.821f, 1.698f, 3.637f, 5.132f, 6.747f, 8.366f, 10.168f, 11.341f, 12.749f, + 14.022f, 15.538f, 16.039f, 16.843f, 19.352f, 21.309f, 23.528f, 25.774f, 27.553f, + 29.688f, 30.962f, 35.528f, 35.863f, 35.086f, 35.272f, 36.326f, 36.484f, 38.845f, + 39.977f, 40.858f, 41.317f, 41.512f, 41.647f, 43.277f, 43.654f, 46.079f, 49.067f, + 50.233f, 50.119f, 49.201f, 47.251f, 46.048f, 43.444f, 40.699f, 40.460f, 39.743f, + 39.417f, 38.081f, 36.613f, 35.530f, 33.985f, 33.395f, 32.957f, 32.596f, 31.843f, + 29.441f, 24.887f, 24.279f, 25.379f, 21.191f, 20.513f, 19.790f, 17.524f, 15.499f, + 13.606f}, + {-29.534f, -28.235f, -26.296f, -25.619f, -25.730f, -23.135f, -20.640f, -20.497f, -22.980f, + -21.267f, -17.747f, -15.715f, -14.983f, -12.203f, -8.650f, -5.786f, -3.811f, -2.943f, + -1.617f, 0.016f, 2.130f, 4.151f, 6.749f, 9.797f, 12.000f, 14.297f, 16.533f, + 18.242f, 21.795f, 24.433f, 17.711f, 19.643f, 19.555f, 18.030f, 17.252f, 15.514f, + 14.061f, 5.735f, 5.291f, 8.766f, 6.024f, 1.373f, -1.126f, -2.784f, -4.238f, + -4.375f, -5.360f, -6.311f, -7.216f, -7.620f, -7.428f, -7.097f, -6.828f, -6.732f, + -6.830f, -7.309f, -7.198f, -7.614f, -7.588f, -7.943f, -8.247f, -9.085f, -10.331f, + -10.229f, -10.520f, -11.619f, -7.944f, -5.636f, -4.632f, -5.215f, -9.677f, -11.310f, + -10.541f, -12.227f, -11.957f, -12.789f, -13.133f, -15.671f, -15.690f, -16.479f, -16.776f, + -15.643f, -19.194f, -21.327f, -21.506f, -21.562f, -21.058f, -22.151f, -20.269f, -22.839f, + -24.768f, -24.501f, -24.361f, -24.860f, -25.613f, -26.463f, -27.052f, -27.576f, -27.986f, + -26.185f, -25.612f, -24.752f, -23.678f, -23.741f, -23.085f, -23.140f, -21.856f, -21.033f, + -19.288f, -17.432f, -15.206f, -13.427f, -11.398f, -9.356f, -6.667f, -4.127f, -1.591f, + 0.875f, 3.990f, 6.859f, 8.848f, 10.561f, 12.048f, 13.671f, 14.842f, 16.231f, + 17.691f, 19.182f, 19.725f, 20.456f, 22.523f, 24.360f, 26.287f, 28.560f, 30.173f, + 31.925f, 33.487f, 35.147f, 36.419f, 37.177f, 37.886f, 38.631f, 39.185f, 41.320f, + 42.349f, 43.068f, 43.357f, 43.781f, 43.428f, 45.357f, 45.497f, 45.544f, 46.690f, + 47.998f, 50.219f, 49.146f, 48.111f, 47.075f, 44.766f, 41.927f, 41.720f, 40.710f, + 40.066f, 39.103f, 37.143f, 35.908f, 34.824f, 34.053f, 33.376f, 33.162f, 32.469f, + 30.416f, 26.224f, 24.737f, 25.337f, 21.382f, 20.641f, 19.802f, 17.454f, 15.480f, + 13.606f}, + {-29.534f, -28.234f, -26.195f, -25.322f, -25.139f, -21.944f, -20.002f, -19.934f, -22.060f, + -20.732f, -17.947f, -16.127f, -15.058f, -12.180f, -8.393f, -5.335f, -3.764f, -3.487f, + -1.772f, 0.166f, 2.448f, 4.235f, 6.915f, 9.606f, 11.924f, 14.330f, 16.355f, + 18.364f, 20.763f, 21.074f, 20.167f, 19.319f, 19.329f, 18.021f, 17.373f, 15.882f, + 15.932f, 6.040f, 5.183f, 7.850f, 6.377f, 1.787f, -1.132f, -3.317f, -4.572f, + -4.857f, -5.972f, -6.936f, -7.706f, -7.840f, -7.506f, -7.262f, -7.085f, -7.171f, + -7.222f, -7.619f, -7.601f, -7.633f, -7.381f, -8.092f, -9.116f, -9.217f, -10.772f, + -10.143f, -10.243f, -11.278f, -8.752f, -5.855f, -5.222f, -5.796f, -6.315f, -10.842f, + -10.134f, -11.396f, -10.803f, -10.640f, -13.562f, -12.706f, -13.136f, -15.813f, -16.529f, + -14.491f, -16.170f, -18.431f, -18.954f, -19.274f, -19.115f, -20.369f, -19.035f, -21.751f, + -23.138f, -22.110f, -21.956f, -22.856f, -22.990f, -23.733f, -24.148f, -24.720f, -24.853f, + -22.907f, -22.298f, -22.422f, -22.247f, -22.164f, -21.433f, -21.365f, -20.237f, -19.051f, + -17.666f, -15.631f, -13.767f, -11.951f, -9.744f, -7.756f, -4.935f, -2.132f, 0.724f, + 3.367f, 5.901f, 9.017f, 12.025f, 14.476f, 15.778f, 17.139f, 18.430f, 19.850f, + 21.511f, 22.761f, 23.311f, 23.789f, 25.564f, 27.323f, 29.160f, 31.422f, 32.986f, + 34.126f, 35.322f, 36.091f, 37.454f, 39.425f, 40.031f, 40.794f, 41.686f, 43.523f, + 44.330f, 45.167f, 45.417f, 45.545f, 45.326f, 46.365f, 47.544f, 48.108f, 46.762f, + 45.931f, 48.001f, 47.725f, 47.701f, 47.573f, 46.036f, 43.598f, 43.177f, 41.863f, + 40.741f, 40.118f, 37.567f, 36.314f, 35.664f, 34.597f, 33.746f, 33.737f, 33.002f, + 31.436f, 27.475f, 25.216f, 25.261f, 21.586f, 20.780f, 19.828f, 17.400f, 15.463f, + 13.606f}, + {-29.534f, -28.232f, -26.085f, -24.991f, -24.431f, -20.686f, -19.413f, -19.356f, -21.031f, + -20.206f, -18.002f, -16.239f, -14.918f, -12.210f, -8.239f, -4.777f, -3.735f, -3.833f, + -1.895f, 0.323f, 2.542f, 4.470f, 7.181f, 9.426f, 11.585f, 14.193f, 16.313f, + 17.855f, 18.997f, 18.180f, 21.260f, 19.572f, 19.164f, 18.514f, 17.783f, 16.536f, + 15.852f, 3.919f, 4.965f, 6.514f, 5.719f, 1.502f, -0.714f, -3.382f, -4.773f, + -5.025f, -6.369f, -7.197f, -7.615f, -7.646f, -7.389f, -7.184f, -6.901f, -7.081f, + -7.324f, -7.336f, -7.378f, -7.773f, -8.016f, -8.956f, -9.586f, -9.460f, -11.036f, + -11.012f, -11.067f, -11.777f, -10.339f, -6.358f, -6.042f, -5.981f, -5.628f, -8.638f, + -10.133f, -10.227f, -9.453f, -9.954f, -11.951f, -11.997f, -11.979f, -12.667f, -14.236f, + -13.751f, -12.539f, -14.054f, -14.741f, -15.417f, -14.934f, -15.815f, -16.894f, -19.791f, + -20.176f, -19.889f, -19.803f, -20.553f, -20.610f, -21.127f, -21.553f, -21.847f, -21.276f, + -19.591f, -18.702f, -20.224f, -20.464f, -20.216f, -19.952f, -19.168f, -18.158f, -16.967f, + -15.613f, -13.800f, -12.023f, -10.243f, -8.180f, -5.781f, -3.360f, -0.470f, 2.325f, + 5.314f, 8.007f, 11.125f, 14.226f, 17.551f, 19.869f, 20.921f, 22.014f, 23.419f, + 24.754f, 26.302f, 26.951f, 27.013f, 28.817f, 30.362f, 32.166f, 34.003f, 35.070f, + 37.195f, 37.736f, 38.285f, 39.735f, 41.483f, 42.206f, 42.989f, 44.583f, 45.434f, + 46.533f, 47.361f, 47.494f, 47.220f, 47.107f, 47.392f, 48.009f, 48.978f, 49.703f, + 47.648f, 45.436f, 45.461f, 47.545f, 47.887f, 47.008f, 45.263f, 44.430f, 43.282f, + 41.832f, 40.972f, 37.820f, 36.883f, 36.587f, 35.198f, 34.074f, 34.233f, 33.461f, + 32.430f, 28.568f, 25.738f, 25.188f, 21.806f, 20.918f, 19.865f, 17.359f, 15.446f, + 13.606f}, + {-29.534f, -28.231f, -25.968f, -24.638f, -23.650f, -19.492f, -18.894f, -18.847f, -20.172f, + -19.825f, -17.899f, -16.061f, -14.598f, -12.184f, -8.151f, -4.303f, -3.845f, -4.147f, + -1.838f, 0.396f, 2.515f, 4.598f, 7.223f, 9.251f, 11.502f, 14.226f, 15.987f, + 18.142f, 18.648f, 19.510f, 21.863f, 20.077f, 19.511f, 19.041f, 18.321f, 16.306f, + 15.305f, 2.789f, 5.806f, 6.041f, 3.419f, 1.319f, -0.322f, -2.764f, -4.185f, + -4.836f, -6.251f, -6.906f, -7.162f, -7.103f, -6.836f, -6.638f, -6.668f, -6.872f, + -6.883f, -7.169f, -7.429f, -7.553f, -7.481f, -8.041f, -8.687f, -8.639f, -10.767f, + -11.527f, -10.884f, -11.301f, -11.585f, -10.598f, -7.652f, -7.925f, -6.679f, -7.658f, + -9.021f, -9.264f, -9.472f, -10.895f, -10.269f, -10.850f, -11.571f, -11.758f, -11.872f, + -12.139f, -11.072f, -11.337f, -11.843f, -12.337f, -13.172f, -13.081f, -15.757f, -17.866f, + -18.568f, -17.689f, -17.400f, -17.940f, -18.087f, -18.399f, -18.855f, -18.837f, -18.378f, + -16.404f, -16.334f, -18.448f, -18.871f, -18.334f, -17.680f, -16.927f, -15.901f, -14.950f, + -13.661f, -11.992f, -10.238f, -8.247f, -6.250f, -4.167f, -1.506f, 1.126f, 3.841f, + 6.802f, 9.742f, 12.997f, 16.299f, 19.552f, 22.836f, 25.129f, 25.762f, 26.727f, + 27.918f, 29.197f, 30.501f, 30.367f, 32.340f, 33.583f, 35.028f, 36.619f, 37.692f, + 39.194f, 40.294f, 41.208f, 42.073f, 43.430f, 44.505f, 45.410f, 47.059f, 47.417f, + 48.843f, 49.575f, 49.456f, 48.909f, 48.768f, 48.694f, 48.765f, 48.657f, 49.850f, + 49.628f, 46.650f, 44.363f, 48.339f, 48.558f, 47.891f, 46.528f, 45.572f, 44.846f, + 43.093f, 41.642f, 38.090f, 37.476f, 37.543f, 35.921f, 34.423f, 34.597f, 33.872f, + 33.305f, 29.464f, 26.308f, 25.160f, 22.048f, 21.045f, 19.908f, 17.334f, 15.431f, + 13.606f}, + {-29.534f, -28.230f, -25.845f, -24.275f, -22.844f, -18.485f, -18.454f, -18.448f, -19.664f, + -19.669f, -17.645f, -15.731f, -14.269f, -12.122f, -7.987f, -3.930f, -3.873f, -4.466f, + -1.717f, 0.453f, 2.681f, 4.545f, 7.195f, 9.058f, 11.637f, 14.175f, 15.702f, + 18.410f, 19.246f, 19.971f, 21.183f, 20.511f, 19.907f, 19.617f, 18.527f, 16.529f, + 17.216f, 2.903f, 6.682f, 6.271f, 2.807f, 1.338f, -0.212f, -2.471f, -3.726f, + -4.423f, -5.700f, -6.309f, -6.400f, -6.181f, -6.027f, -6.324f, -6.548f, -6.578f, + -6.749f, -7.026f, -7.092f, -7.100f, -7.131f, -7.055f, -7.201f, -7.660f, -9.863f, + -9.465f, -10.984f, -10.525f, -10.548f, -10.804f, -10.395f, -11.423f, -10.129f, -6.615f, + -7.560f, -8.280f, -8.477f, -8.423f, -9.221f, -11.125f, -11.783f, -13.412f, -12.348f, + -10.895f, -9.917f, -10.472f, -10.619f, -9.647f, -9.543f, -10.781f, -15.850f, -16.009f, + -16.488f, -15.287f, -15.162f, -15.244f, -15.295f, -15.694f, -16.320f, -15.951f, -14.832f, + -14.455f, -14.683f, -16.719f, -16.774f, -16.577f, -15.787f, -14.748f, -13.598f, -12.730f, + -11.566f, -10.011f, -8.318f, -6.403f, -4.261f, -2.268f, 0.147f, 3.027f, 5.792f, + 8.409f, 11.434f, 14.855f, 18.289f, 21.613f, 24.601f, 28.048f, 29.324f, 30.407f, + 31.211f, 32.518f, 33.541f, 33.324f, 35.134f, 36.708f, 38.450f, 39.837f, 40.445f, + 41.680f, 42.328f, 43.604f, 44.086f, 45.235f, 47.054f, 47.770f, 48.685f, 49.661f, + 51.146f, 51.821f, 51.504f, 50.971f, 50.542f, 50.078f, 49.599f, 49.709f, 50.119f, + 50.213f, 49.921f, 45.926f, 48.629f, 50.070f, 49.302f, 48.016f, 47.015f, 46.268f, + 44.266f, 42.400f, 38.684f, 37.907f, 38.378f, 36.709f, 34.868f, 34.869f, 34.268f, + 33.973f, 30.162f, 26.910f, 25.207f, 22.317f, 21.159f, 19.952f, 17.323f, 15.418f, + 13.606f}, + {-29.534f, -28.229f, -25.719f, -23.915f, -22.063f, -17.754f, -18.104f, -18.148f, -19.507f, + -19.699f, -17.302f, -15.377f, -14.040f, -12.133f, -7.748f, -3.549f, -3.643f, -4.612f, + -1.621f, 0.616f, 2.756f, 4.566f, 7.163f, 8.888f, 11.545f, 14.144f, 15.622f, + 17.722f, 19.987f, 21.164f, 20.366f, 20.392f, 19.879f, 19.620f, 18.887f, 18.919f, + 18.483f, 5.384f, 7.988f, 6.523f, 3.260f, 1.822f, 0.164f, -2.262f, -3.252f, + -3.967f, -5.272f, -5.506f, -5.289f, -5.212f, -5.186f, -5.862f, -6.049f, -6.119f, + -6.336f, -6.335f, -5.957f, -6.444f, -6.376f, -5.405f, -6.046f, -7.942f, -8.956f, + -9.158f, -9.815f, -9.235f, -9.655f, -9.718f, -10.023f, -8.858f, -7.230f, -7.677f, + -5.901f, -12.013f, -9.334f, -13.252f, -11.657f, -11.104f, -10.659f, -11.568f, -10.583f, + -9.383f, -7.931f, -8.630f, -7.548f, -8.010f, -8.477f, -11.023f, -12.906f, -14.071f, + -14.357f, -12.824f, -12.692f, -12.391f, -12.563f, -12.835f, -13.094f, -12.758f, -12.050f, + -12.329f, -12.718f, -14.868f, -14.779f, -14.778f, -13.805f, -12.660f, -11.252f, -10.073f, + -9.299f, -7.795f, -6.237f, -4.239f, -2.252f, -0.524f, 1.672f, 4.687f, 7.447f, + 10.166f, 13.253f, 16.392f, 20.196f, 23.534f, 26.713f, 29.889f, 32.453f, 33.752f, + 34.466f, 35.521f, 36.535f, 36.381f, 38.105f, 39.716f, 41.618f, 42.698f, 43.511f, + 44.206f, 44.815f, 45.575f, 46.325f, 47.304f, 49.277f, 50.036f, 50.473f, 51.399f, + 53.401f, 53.988f, 53.801f, 53.029f, 52.439f, 51.534f, 50.807f, 50.758f, 50.909f, + 50.849f, 52.085f, 48.357f, 49.125f, 52.646f, 51.305f, 49.707f, 48.372f, 47.498f, + 45.642f, 43.491f, 39.708f, 38.291f, 39.062f, 37.528f, 35.422f, 35.139f, 34.700f, + 34.385f, 30.688f, 27.512f, 25.341f, 22.611f, 21.257f, 19.994f, 17.327f, 15.406f, + 13.606f}, + {-29.534f, -28.227f, -25.594f, -23.569f, -21.349f, -17.342f, -17.852f, -17.906f, -19.530f, + -19.779f, -17.026f, -15.045f, -13.694f, -12.171f, -7.617f, -3.166f, -3.335f, -4.541f, + -1.496f, 0.763f, 2.590f, 4.650f, 7.128f, 8.721f, 11.168f, 13.961f, 15.437f, + 17.259f, 20.194f, 21.556f, 20.622f, 20.806f, 20.235f, 20.210f, 19.219f, 21.351f, + 18.282f, 9.784f, 10.296f, 7.437f, 3.954f, 2.662f, 0.756f, -1.823f, -2.740f, + -3.346f, -4.413f, -4.503f, -4.334f, -4.339f, -4.393f, -4.858f, -5.096f, -5.311f, + -5.462f, -5.167f, -5.232f, -5.144f, -4.558f, -3.737f, -4.056f, -6.179f, -6.953f, + -7.912f, -8.647f, -8.593f, -9.200f, -9.479f, -9.643f, -9.817f, -8.906f, -10.926f, + -10.773f, -10.103f, -13.978f, -13.717f, -12.888f, -12.317f, -12.320f, -10.316f, -9.060f, + -7.585f, -6.313f, -6.081f, -6.511f, -7.169f, -9.459f, -10.790f, -12.360f, -12.135f, + -12.448f, -10.507f, -9.909f, -9.544f, -9.676f, -9.846f, -9.894f, -9.525f, -9.796f, + -10.221f, -11.022f, -12.556f, -12.841f, -12.883f, -11.493f, -10.239f, -8.370f, -7.024f, + -6.354f, -5.172f, -3.668f, -1.822f, 0.030f, 1.643f, 3.341f, 6.194f, 9.295f, + 12.007f, 14.928f, 18.269f, 21.882f, 25.062f, 28.350f, 31.653f, 35.103f, 36.892f, + 37.694f, 38.422f, 39.135f, 39.186f, 40.819f, 42.171f, 43.978f, 45.005f, 45.905f, + 46.337f, 46.909f, 47.662f, 48.865f, 49.555f, 51.136f, 51.791f, 52.309f, 53.627f, + 55.395f, 56.048f, 55.906f, 55.312f, 54.377f, 53.246f, 52.332f, 52.192f, 51.711f, + 51.522f, 53.348f, 51.239f, 51.005f, 55.134f, 53.646f, 51.354f, 49.691f, 48.625f, + 47.098f, 44.851f, 41.043f, 38.966f, 39.748f, 38.406f, 36.017f, 35.469f, 35.219f, + 34.548f, 31.083f, 28.075f, 25.553f, 22.925f, 21.342f, 20.031f, 17.342f, 15.395f, + 13.606f}, + {-29.534f, -28.225f, -25.471f, -23.246f, -20.737f, -17.241f, -17.711f, -17.679f, -19.484f, + -19.748f, -17.024f, -14.737f, -12.824f, -12.017f, -7.661f, -2.837f, -2.993f, -4.327f, + -1.360f, 0.762f, 2.472f, 4.515f, 7.138f, 8.590f, 10.988f, 13.595f, 15.121f, + 17.305f, 20.430f, 20.650f, 21.848f, 21.428f, 21.005f, 20.509f, 19.407f, 22.755f, + 16.624f, 11.034f, 10.728f, 7.589f, 5.227f, 3.099f, 1.515f, -1.077f, -2.112f, + -2.787f, -3.165f, -3.334f, -3.234f, -3.358f, -3.173f, -3.794f, -4.114f, -4.195f, + -4.140f, -4.046f, -3.885f, -3.159f, -1.846f, -0.704f, -1.330f, -4.440f, -5.533f, + -6.635f, -7.286f, -7.718f, -8.565f, -8.506f, -9.523f, -8.103f, -7.185f, -9.321f, + -6.678f, -9.905f, -11.315f, -11.942f, -12.471f, -12.528f, -12.517f, -10.401f, -9.376f, + -7.078f, -5.317f, -3.997f, -5.013f, -6.318f, -7.717f, -10.049f, -11.360f, -9.598f, + -10.476f, -8.149f, -7.738f, -6.815f, -6.819f, -6.820f, -6.789f, -6.945f, -7.390f, + -8.066f, -9.051f, -10.509f, -10.870f, -10.790f, -9.170f, -7.842f, -5.400f, -4.091f, + -3.391f, -2.279f, -1.007f, 1.078f, 2.719f, 3.894f, 5.320f, 7.802f, 10.776f, + 13.716f, 16.766f, 20.100f, 23.403f, 26.747f, 29.897f, 33.020f, 36.400f, 39.180f, + 40.912f, 41.722f, 41.791f, 42.519f, 43.432f, 44.616f, 46.041f, 47.290f, 48.403f, + 48.990f, 49.280f, 50.016f, 50.724f, 51.613f, 52.775f, 53.298f, 53.935f, 56.086f, + 57.894f, 58.232f, 58.254f, 57.264f, 56.270f, 55.244f, 54.099f, 53.335f, 52.781f, + 52.240f, 53.724f, 54.430f, 53.028f, 56.307f, 55.771f, 53.358f, 51.632f, 49.681f, + 48.021f, 46.257f, 42.414f, 40.012f, 40.532f, 39.338f, 36.587f, 35.841f, 35.841f, + 34.530f, 31.383f, 28.566f, 25.813f, 23.243f, 21.416f, 20.060f, 17.370f, 15.386f, + 13.606f}, + {-29.534f, -28.222f, -25.352f, -22.955f, -20.245f, -17.398f, -17.688f, -17.454f, -19.186f, + -19.497f, -17.408f, -14.515f, -11.325f, -11.587f, -7.703f, -2.517f, -2.347f, -3.948f, + -1.246f, 0.750f, 2.309f, 4.158f, 6.992f, 8.636f, 10.991f, 12.933f, 14.804f, + 17.328f, 19.828f, 21.797f, 22.674f, 21.953f, 21.392f, 20.887f, 20.179f, 21.478f, + 11.834f, 12.219f, 10.475f, 8.091f, 5.664f, 4.138f, 2.371f, 0.075f, -1.307f, + -1.616f, -1.819f, -2.047f, -1.932f, -2.333f, -2.210f, -2.715f, -3.010f, -2.449f, + -2.840f, -2.707f, -2.673f, -1.945f, -0.761f, 1.224f, -0.144f, -3.198f, -4.081f, + -5.287f, -6.019f, -7.178f, -7.912f, -7.885f, -8.704f, -5.676f, -8.310f, -8.307f, + -8.885f, -8.986f, -9.136f, -10.630f, -11.238f, -11.602f, -12.089f, -11.610f, -11.554f, + -7.574f, -5.270f, -4.421f, -5.390f, -6.529f, -8.171f, -8.818f, -9.532f, -7.607f, + -8.434f, -5.794f, -5.174f, -4.166f, -3.948f, -3.873f, -3.881f, -4.060f, -5.430f, + -6.085f, -7.147f, -8.370f, -8.597f, -8.687f, -6.992f, -5.431f, -3.228f, -1.301f, + -0.146f, 0.958f, 2.015f, 3.887f, 5.581f, 6.525f, 7.291f, 9.325f, 11.971f, + 15.309f, 18.620f, 21.771f, 24.831f, 28.041f, 31.437f, 34.447f, 37.790f, 40.821f, + 43.396f, 44.543f, 44.611f, 45.448f, 45.934f, 47.068f, 48.402f, 49.688f, 50.838f, + 50.640f, 51.753f, 52.229f, 52.354f, 53.092f, 54.096f, 54.908f, 55.547f, 57.641f, + 59.369f, 59.741f, 60.099f, 59.512f, 58.174f, 57.125f, 55.812f, 54.796f, 54.032f, + 53.456f, 53.505f, 55.972f, 54.952f, 56.595f, 56.435f, 54.637f, 53.506f, 50.912f, + 48.576f, 47.432f, 43.481f, 41.079f, 41.334f, 40.226f, 37.148f, 36.195f, 36.501f, + 34.436f, 31.610f, 28.970f, 26.081f, 23.547f, 21.483f, 20.079f, 17.407f, 15.378f, + 13.606f}, + {-29.534f, -28.219f, -25.242f, -22.701f, -19.879f, -17.724f, -17.781f, -17.263f, -18.610f, + -19.007f, -18.064f, -14.499f, -9.691f, -11.071f, -7.605f, -2.183f, -1.428f, -3.441f, + -1.110f, 0.846f, 1.962f, 3.758f, 6.662f, 8.664f, 10.616f, 12.480f, 14.657f, + 17.055f, 19.353f, 22.179f, 22.587f, 22.000f, 21.628f, 21.385f, 20.555f, 16.571f, + 11.996f, 13.492f, 12.648f, 9.924f, 6.762f, 4.464f, 3.318f, 1.557f, 0.198f, + -0.149f, -0.475f, -0.783f, -0.647f, -1.119f, -1.106f, -1.257f, -0.903f, -0.850f, + -1.289f, -1.198f, -0.836f, -0.571f, 0.459f, 2.714f, 0.482f, -1.438f, -2.910f, + -4.004f, -5.346f, -6.774f, -7.355f, -7.532f, -7.985f, -5.323f, -7.302f, -7.249f, + -7.851f, -8.361f, -8.428f, -9.414f, -10.020f, -10.185f, -10.590f, -11.186f, -11.432f, + -11.143f, -9.543f, -9.233f, -8.466f, -8.434f, -7.082f, -8.069f, -8.198f, -5.808f, + -6.544f, -3.792f, -2.403f, -1.543f, -1.404f, -1.184f, -0.627f, -1.242f, -3.435f, + -4.362f, -5.200f, -6.313f, -6.394f, -6.046f, -4.584f, -2.954f, -0.501f, 1.614f, + 3.123f, 4.413f, 5.805f, 7.334f, 8.625f, 8.870f, 9.438f, 11.115f, 13.331f, + 16.584f, 20.204f, 23.354f, 26.240f, 29.210f, 32.594f, 35.963f, 39.046f, 42.184f, + 45.627f, 47.267f, 47.801f, 48.604f, 49.030f, 49.739f, 50.653f, 51.736f, 52.806f, + 53.197f, 53.469f, 53.868f, 54.097f, 54.709f, 55.553f, 56.573f, 56.952f, 59.057f, + 59.630f, 60.226f, 60.982f, 60.970f, 60.270f, 58.919f, 57.795f, 56.319f, 55.348f, + 54.622f, 54.034f, 56.018f, 56.866f, 56.764f, 55.750f, 54.443f, 54.539f, 52.165f, + 49.259f, 48.082f, 44.179f, 41.816f, 42.060f, 40.989f, 37.761f, 36.475f, 37.061f, + 34.379f, 31.766f, 29.291f, 26.320f, 23.817f, 21.545f, 20.088f, 17.452f, 15.373f, + 13.606f}, + {-29.534f, -28.216f, -25.141f, -22.486f, -19.629f, -18.116f, -17.971f, -17.166f, -17.899f, + -18.334f, -18.640f, -14.723f, -8.658f, -10.601f, -7.458f, -1.913f, -0.682f, -2.989f, + -0.998f, 0.864f, 1.711f, 3.324f, 6.325f, 8.434f, 10.190f, 12.507f, 14.513f, + 16.807f, 19.627f, 22.280f, 23.194f, 22.759f, 22.356f, 21.961f, 21.105f, 10.845f, + 13.206f, 15.315f, 15.023f, 9.944f, 7.518f, 5.593f, 4.445f, 2.935f, 1.838f, + 1.399f, 0.984f, 0.888f, 0.661f, 0.267f, 0.094f, 0.558f, 0.619f, 0.515f, + 0.652f, 0.485f, 0.712f, 0.974f, 1.279f, 2.862f, 0.502f, 0.141f, -1.610f, + -3.320f, -4.689f, -6.069f, -6.780f, -7.332f, -7.165f, -6.386f, -5.884f, -6.043f, + -6.980f, -7.628f, -8.129f, -8.272f, -8.534f, -8.771f, -9.395f, -10.640f, -11.217f, + -11.050f, -10.685f, -9.523f, -7.986f, -8.002f, -5.955f, -6.592f, -7.083f, -4.245f, + -3.870f, -1.163f, 0.184f, 1.112f, 1.550f, 2.199f, 1.996f, 0.927f, -1.747f, + -2.607f, -3.242f, -4.212f, -4.035f, -3.415f, -2.034f, -0.259f, 2.550f, 4.713f, + 6.383f, 7.950f, 9.345f, 10.593f, 11.419f, 11.280f, 11.472f, 12.833f, 15.357f, + 18.269f, 21.489f, 24.799f, 27.620f, 30.320f, 33.531f, 37.091f, 40.243f, 43.071f, + 46.545f, 49.432f, 50.549f, 51.568f, 52.340f, 52.676f, 53.313f, 53.975f, 54.584f, + 55.129f, 55.461f, 55.682f, 56.047f, 56.190f, 57.255f, 58.064f, 58.304f, 59.484f, + 59.928f, 60.193f, 61.036f, 61.767f, 61.842f, 60.832f, 59.594f, 58.308f, 56.727f, + 55.710f, 55.143f, 55.682f, 57.679f, 57.100f, 55.820f, 55.191f, 55.437f, 52.676f, + 49.823f, 48.329f, 44.896f, 42.300f, 42.804f, 41.659f, 38.408f, 36.650f, 37.369f, + 34.437f, 31.842f, 29.545f, 26.503f, 24.041f, 21.603f, 20.088f, 17.504f, 15.368f, + 13.606f}, + {-29.534f, -28.212f, -25.051f, -22.310f, -19.476f, -18.474f, -18.220f, -17.221f, -17.284f, + -17.577f, -18.736f, -14.999f, -8.512f, -9.921f, -7.359f, -1.746f, -0.338f, -2.686f, + -1.012f, 0.678f, 1.618f, 2.908f, 5.960f, 8.130f, 9.904f, 12.065f, 14.504f, + 16.888f, 19.365f, 22.479f, 23.736f, 23.226f, 22.828f, 22.608f, 21.341f, 11.667f, + 13.232f, 15.231f, 14.553f, 10.862f, 8.708f, 6.310f, 5.834f, 4.405f, 3.274f, + 2.922f, 2.890f, 3.208f, 2.648f, 2.131f, 2.123f, 2.473f, 2.369f, 2.450f, + 1.975f, 1.726f, 2.822f, 1.792f, 2.282f, 2.376f, 1.473f, 0.748f, -0.988f, + -2.849f, -4.191f, -5.744f, -6.399f, -6.520f, -6.425f, -4.877f, -5.366f, -5.488f, + -6.378f, -7.022f, -7.578f, -7.665f, -7.866f, -8.154f, -8.662f, -10.159f, -10.796f, + -10.927f, -10.633f, -9.481f, -8.100f, -7.247f, -5.839f, -5.631f, -5.986f, -2.454f, + -1.791f, 1.228f, 2.652f, 3.596f, 3.737f, 3.774f, 3.651f, 2.818f, -0.182f, + -0.522f, -1.173f, -2.063f, -1.671f, -0.776f, 0.371f, 2.564f, 5.191f, 7.614f, + 9.477f, 11.030f, 12.630f, 13.652f, 13.783f, 13.455f, 13.608f, 14.587f, 16.625f, + 20.028f, 23.213f, 26.258f, 28.932f, 31.537f, 34.520f, 37.978f, 40.677f, 43.970f, + 47.043f, 50.505f, 52.835f, 53.832f, 54.938f, 55.452f, 55.873f, 56.482f, 57.150f, + 57.479f, 57.377f, 57.475f, 57.962f, 58.070f, 59.141f, 59.386f, 59.504f, 59.819f, + 60.137f, 60.420f, 61.188f, 61.937f, 62.732f, 62.465f, 61.204f, 59.914f, 58.614f, + 57.190f, 56.232f, 56.101f, 58.018f, 57.396f, 56.915f, 57.468f, 56.384f, 52.908f, + 50.248f, 48.683f, 45.908f, 42.878f, 43.732f, 42.271f, 38.917f, 36.684f, 37.338f, + 34.620f, 31.828f, 29.752f, 26.621f, 24.211f, 21.656f, 20.079f, 17.561f, 15.365f, + 13.606f}, + {-29.534f, -28.207f, -24.975f, -22.173f, -19.394f, -18.722f, -18.477f, -17.442f, -16.951f, + -16.842f, -18.165f, -14.975f, -8.841f, -8.672f, -7.206f, -1.680f, -0.296f, -2.464f, + -1.097f, 0.509f, 1.509f, 2.647f, 5.589f, 7.973f, 9.607f, 11.634f, 14.454f, + 16.772f, 19.682f, 22.257f, 23.707f, 23.766f, 23.638f, 23.095f, 21.464f, 10.284f, + 13.444f, 15.943f, 15.166f, 11.720f, 10.012f, 6.795f, 7.171f, 5.809f, 5.050f, + 4.820f, 4.960f, 5.118f, 4.717f, 4.170f, 4.172f, 4.174f, 4.161f, 4.107f, + 3.782f, 4.927f, 2.911f, 3.435f, 3.121f, 2.804f, 2.635f, 2.463f, -0.182f, + -2.357f, -4.093f, -5.574f, -6.235f, -6.383f, -6.064f, -6.007f, -5.710f, -5.402f, + -5.933f, -6.677f, -7.199f, -7.059f, -7.349f, -8.220f, -9.210f, -9.815f, -10.184f, + -10.369f, -10.515f, -9.213f, -7.653f, -6.326f, -5.535f, -4.757f, -4.480f, -0.562f, + 0.420f, 3.559f, 5.127f, 5.364f, 5.157f, 5.508f, 5.163f, 4.448f, 2.087f, + 1.175f, 0.903f, 0.078f, 0.763f, 1.761f, 3.053f, 5.371f, 7.711f, 10.333f, + 12.186f, 13.622f, 15.290f, 15.998f, 15.486f, 15.080f, 15.774f, 16.805f, 18.522f, + 21.354f, 24.779f, 27.382f, 29.877f, 32.474f, 35.583f, 38.520f, 41.410f, 44.507f, + 47.837f, 50.550f, 54.083f, 55.925f, 56.869f, 57.634f, 58.067f, 58.598f, 59.206f, + 59.525f, 59.505f, 59.797f, 59.940f, 60.228f, 60.574f, 61.040f, 61.078f, 59.990f, + 60.021f, 60.357f, 60.872f, 61.903f, 63.030f, 63.331f, 62.788f, 61.512f, 60.290f, + 58.946f, 57.613f, 57.526f, 58.964f, 57.683f, 57.766f, 58.676f, 56.922f, 53.985f, + 50.900f, 49.073f, 46.851f, 43.743f, 44.857f, 42.734f, 39.058f, 36.512f, 36.987f, + 34.856f, 31.717f, 29.920f, 26.679f, 24.332f, 21.705f, 20.063f, 17.621f, 15.364f, + 13.606f}, + {-29.534f, -28.202f, -24.914f, -22.069f, -19.352f, -18.816f, -18.689f, -17.780f, -16.946f, + -16.230f, -17.094f, -14.394f, -9.003f, -6.976f, -6.888f, -1.771f, -0.537f, -2.279f, + -1.113f, 0.499f, 1.447f, 2.511f, 5.375f, 7.829f, 9.320f, 11.534f, 14.010f, + 16.679f, 19.385f, 22.198f, 23.544f, 24.102f, 23.655f, 23.105f, 21.300f, 8.469f, + 14.057f, 16.015f, 15.542f, 12.170f, 11.097f, 7.527f, 8.452f, 7.392f, 7.034f, + 6.801f, 6.881f, 6.844f, 6.358f, 6.184f, 6.314f, 6.414f, 6.415f, 5.950f, + 5.557f, 6.571f, 4.745f, 4.277f, 4.181f, 3.992f, 3.488f, 2.176f, -0.161f, + -1.850f, -3.689f, -4.932f, -5.970f, -6.340f, -6.255f, -6.217f, -6.023f, -5.422f, + -5.680f, -6.479f, -6.855f, -7.056f, -7.412f, -8.365f, -9.062f, -9.189f, -9.548f, + -9.618f, -9.222f, -8.404f, -6.944f, -5.169f, -3.943f, -3.733f, -3.527f, 1.257f, + 2.156f, 5.047f, 6.512f, 6.433f, 6.424f, 6.623f, 6.530f, 5.755f, 4.324f, + 2.886f, 2.785f, 2.274f, 3.140f, 4.265f, 5.678f, 7.846f, 10.109f, 12.699f, + 14.432f, 15.426f, 16.998f, 17.444f, 16.715f, 16.259f, 17.135f, 18.479f, 20.440f, + 22.784f, 25.803f, 28.215f, 30.194f, 32.419f, 35.863f, 39.354f, 42.110f, 44.351f, + 48.132f, 50.636f, 55.008f, 57.268f, 58.756f, 59.482f, 60.233f, 60.869f, 60.922f, + 61.268f, 61.434f, 61.625f, 61.732f, 61.735f, 62.429f, 62.212f, 61.442f, 60.108f, + 60.319f, 60.221f, 60.668f, 61.754f, 62.778f, 63.859f, 63.799f, 62.916f, 61.684f, + 60.554f, 59.219f, 58.595f, 59.796f, 58.397f, 58.560f, 59.130f, 57.182f, 54.734f, + 51.123f, 48.809f, 47.217f, 44.749f, 45.970f, 42.917f, 38.732f, 36.057f, 36.412f, + 35.010f, 31.511f, 30.042f, 26.696f, 24.420f, 21.747f, 20.043f, 17.681f, 15.364f, + 13.606f}, + {-29.534f, -28.196f, -24.868f, -21.995f, -19.324f, -18.751f, -18.807f, -18.122f, -17.146f, + -15.815f, -15.957f, -13.318f, -8.767f, -5.449f, -6.473f, -1.991f, -1.016f, -2.090f, + -1.018f, 0.565f, 1.501f, 2.463f, 5.294f, 7.551f, 9.015f, 11.281f, 13.728f, + 16.682f, 19.037f, 21.658f, 23.094f, 23.790f, 24.028f, 22.981f, 20.646f, 6.682f, + 13.599f, 15.558f, 14.870f, 12.874f, 11.171f, 9.400f, 9.978f, 9.086f, 8.890f, + 8.617f, 8.433f, 8.370f, 7.999f, 7.964f, 8.072f, 8.174f, 7.993f, 7.349f, + 7.353f, 6.292f, 6.233f, 5.839f, 5.552f, 5.386f, 4.053f, 2.173f, 0.626f, + -1.361f, -3.114f, -4.598f, -5.681f, -6.211f, -6.356f, -5.586f, -5.751f, -5.694f, + -6.158f, -6.800f, -6.935f, -7.148f, -7.243f, -8.395f, -8.669f, -8.747f, -8.932f, + -8.627f, -8.059f, -7.481f, -6.490f, -4.784f, -3.461f, -2.782f, -2.458f, 3.586f, + 4.282f, 6.159f, 7.473f, 7.578f, 7.820f, 7.942f, 7.872f, 7.059f, 5.860f, + 4.772f, 4.600f, 4.462f, 5.549f, 6.595f, 7.966f, 10.289f, 12.627f, 14.667f, + 16.186f, 16.951f, 17.920f, 17.734f, 17.120f, 16.867f, 17.992f, 19.339f, 21.550f, + 23.367f, 25.558f, 28.123f, 32.966f, 33.784f, 35.551f, 39.539f, 41.940f, 45.341f, + 48.277f, 51.495f, 56.041f, 57.658f, 59.329f, 60.741f, 61.541f, 62.257f, 62.784f, + 63.099f, 63.087f, 62.896f, 63.386f, 63.782f, 63.052f, 63.343f, 61.960f, 60.303f, + 60.739f, 60.473f, 60.719f, 61.349f, 62.698f, 63.684f, 64.373f, 63.958f, 62.918f, + 61.867f, 60.636f, 59.422f, 60.199f, 59.220f, 59.039f, 60.417f, 56.887f, 53.925f, + 50.587f, 48.115f, 47.093f, 45.510f, 46.743f, 42.857f, 38.043f, 35.289f, 35.719f, + 34.936f, 31.220f, 30.098f, 26.691f, 24.495f, 21.784f, 20.020f, 17.742f, 15.365f, + 13.606f}, + {-29.534f, -28.189f, -24.837f, -21.944f, -19.286f, -18.553f, -18.806f, -18.329f, -17.316f, + -15.617f, -15.178f, -12.106f, -8.425f, -4.527f, -6.003f, -2.077f, -1.413f, -1.885f, + -0.903f, 0.747f, 1.619f, 2.548f, 5.196f, 7.261f, 8.829f, 11.003f, 13.350f, + 16.209f, 18.791f, 20.614f, 21.765f, 23.171f, 22.820f, 22.331f, 21.148f, 4.085f, + 13.107f, 15.533f, 14.533f, 13.327f, 12.433f, 11.691f, 11.173f, 10.529f, 10.365f, + 10.250f, 9.989f, 9.767f, 9.738f, 9.524f, 9.582f, 9.661f, 9.468f, 8.929f, + 9.117f, 7.948f, 7.138f, 6.600f, 5.713f, 4.973f, 4.141f, 2.254f, 1.147f, + -0.766f, -2.269f, -3.913f, -5.182f, -5.978f, -6.418f, -6.616f, -6.681f, -6.387f, + -6.755f, -7.160f, -7.187f, -7.254f, -7.173f, -7.923f, -8.066f, -8.063f, -8.213f, + -7.946f, -7.652f, -7.042f, -5.653f, -4.184f, -3.149f, -2.009f, -0.894f, 4.640f, + 6.024f, 7.128f, 8.428f, 8.424f, 8.742f, 8.773f, 9.299f, 8.658f, 7.199f, + 6.768f, 6.499f, 6.556f, 7.771f, 8.846f, 10.456f, 12.830f, 14.989f, 16.368f, + 17.992f, 18.283f, 18.637f, 17.820f, 17.375f, 17.269f, 18.703f, 20.544f, 22.625f, + 24.594f, 25.797f, 27.494f, 32.657f, 32.237f, 37.948f, 38.406f, 42.015f, 45.944f, + 48.502f, 52.014f, 55.495f, 58.478f, 59.197f, 60.604f, 61.472f, 62.382f, 63.833f, + 64.766f, 65.018f, 64.984f, 65.054f, 64.714f, 64.125f, 63.023f, 61.893f, 60.750f, + 60.683f, 60.931f, 60.951f, 61.354f, 62.547f, 63.435f, 64.306f, 64.668f, 64.002f, + 63.030f, 61.847f, 60.867f, 60.641f, 59.864f, 58.873f, 61.196f, 56.232f, 53.539f, + 50.955f, 48.266f, 46.909f, 45.668f, 46.818f, 42.698f, 37.174f, 34.265f, 34.970f, + 34.552f, 30.850f, 30.063f, 26.682f, 24.582f, 21.817f, 19.999f, 17.801f, 15.367f, + 13.606f}, + {-29.534f, -28.182f, -24.822f, -21.912f, -19.223f, -18.274f, -18.682f, -18.281f, -17.221f, + -15.578f, -14.911f, -11.151f, -8.329f, -4.014f, -5.319f, -1.837f, -1.543f, -1.815f, + -0.901f, 1.008f, 1.794f, 2.691f, 5.145f, 7.081f, 8.701f, 10.723f, 12.574f, + 15.858f, 18.518f, 18.765f, 17.788f, 22.404f, 22.382f, 20.494f, 16.545f, 3.092f, + 13.533f, 15.841f, 15.326f, 15.281f, 13.878f, 12.575f, 12.568f, 11.986f, 11.868f, + 11.806f, 11.655f, 11.190f, 11.407f, 11.135f, 11.211f, 11.209f, 10.938f, 10.675f, + 10.394f, 9.259f, 8.555f, 7.409f, 6.681f, 5.527f, 4.646f, 2.646f, 1.711f, + 0.297f, -1.447f, -3.119f, -4.651f, -5.764f, -6.269f, -6.331f, -6.790f, -6.928f, + -7.267f, -7.584f, -7.384f, -7.275f, -6.990f, -7.415f, -7.731f, -7.772f, -7.453f, + -7.163f, -6.940f, -5.715f, -4.672f, -3.219f, -1.930f, -0.806f, 0.783f, 5.741f, + 7.598f, 8.308f, 9.163f, 9.122f, 9.599f, 9.615f, 9.989f, 10.111f, 8.734f, + 8.395f, 8.442f, 8.551f, 9.885f, 11.206f, 12.940f, 15.454f, 17.414f, 18.313f, + 19.697f, 20.001f, 19.913f, 18.741f, 18.034f, 18.295f, 19.505f, 21.126f, 23.578f, + 25.686f, 26.638f, 27.954f, 30.350f, 32.216f, 33.730f, 37.853f, 41.513f, 44.363f, + 48.453f, 52.492f, 55.354f, 58.244f, 59.515f, 60.487f, 61.460f, 62.265f, 63.715f, + 64.687f, 65.709f, 66.012f, 65.604f, 65.092f, 63.924f, 62.959f, 61.638f, 61.259f, + 60.937f, 60.671f, 61.043f, 61.161f, 62.083f, 63.181f, 64.085f, 64.842f, 64.829f, + 63.803f, 63.320f, 62.647f, 61.270f, 60.220f, 59.273f, 60.677f, 56.652f, 54.403f, + 52.854f, 49.461f, 46.877f, 45.318f, 45.919f, 42.341f, 36.197f, 33.114f, 34.184f, + 33.889f, 30.405f, 29.919f, 26.679f, 24.703f, 21.848f, 19.980f, 17.857f, 15.370f, + 13.606f}, + {-29.534f, -28.174f, -24.823f, -21.891f, -19.129f, -17.972f, -18.459f, -17.921f, -16.730f, + -15.570f, -14.989f, -10.645f, -8.457f, -3.479f, -4.343f, -1.495f, -1.568f, -1.961f, + -0.970f, 1.088f, 1.946f, 2.803f, 5.217f, 6.982f, 8.551f, 10.499f, 12.121f, + 15.350f, 18.289f, 16.653f, 12.902f, 19.996f, 19.528f, 16.142f, 4.718f, 8.224f, + 14.756f, 16.028f, 17.691f, 16.386f, 14.971f, 13.524f, 13.999f, 13.650f, 13.270f, + 13.358f, 13.166f, 12.552f, 12.821f, 12.668f, 12.915f, 12.662f, 12.532f, 12.177f, + 11.806f, 11.077f, 9.495f, 8.400f, 7.770f, 6.348f, 4.914f, 3.402f, 2.379f, + 1.333f, -0.495f, -2.194f, -3.904f, -5.200f, -5.955f, -6.219f, -6.690f, -7.171f, + -7.372f, -7.592f, -7.405f, -7.005f, -6.602f, -7.071f, -7.206f, -7.076f, -6.841f, + -6.126f, -5.914f, -4.727f, -3.468f, -1.805f, -0.873f, 0.456f, 2.359f, 5.933f, + 8.608f, 8.974f, 9.665f, 9.929f, 10.461f, 10.809f, 10.880f, 11.537f, 10.201f, + 10.211f, 10.173f, 10.407f, 11.849f, 13.012f, 15.114f, 17.537f, 19.244f, 21.204f, + 21.805f, 22.053f, 21.416f, 20.051f, 19.068f, 19.796f, 20.471f, 21.372f, 24.263f, + 26.009f, 26.818f, 28.609f, 30.592f, 31.672f, 34.069f, 38.103f, 39.503f, 43.168f, + 47.737f, 52.101f, 55.458f, 57.150f, 58.541f, 59.806f, 60.878f, 62.320f, 63.855f, + 64.758f, 65.730f, 65.986f, 65.093f, 64.486f, 63.659f, 62.861f, 61.999f, 61.497f, + 61.030f, 61.041f, 60.871f, 61.132f, 61.698f, 62.648f, 63.681f, 64.648f, 65.107f, + 64.711f, 64.505f, 63.786f, 62.245f, 60.108f, 59.755f, 59.801f, 57.775f, 54.037f, + 54.057f, 50.252f, 47.066f, 45.163f, 44.090f, 41.278f, 35.040f, 31.981f, 33.393f, + 33.092f, 29.881f, 29.669f, 26.680f, 24.868f, 21.882f, 19.967f, 17.909f, 15.375f, + 13.606f}, + {-29.534f, -28.165f, -24.838f, -21.879f, -19.003f, -17.700f, -18.173f, -17.282f, -15.870f, + -15.450f, -15.082f, -10.533f, -8.476f, -2.864f, -3.373f, -1.376f, -1.449f, -2.031f, + -0.916f, 1.033f, 1.990f, 2.905f, 5.249f, 6.886f, 8.431f, 10.321f, 12.259f, + 14.768f, 17.934f, 16.640f, 10.302f, 14.587f, 15.214f, 8.242f, 5.398f, 14.917f, + 17.025f, 17.431f, 17.402f, 17.108f, 15.827f, 14.725f, 15.370f, 14.807f, 14.567f, + 14.984f, 14.723f, 14.156f, 14.409f, 14.195f, 14.421f, 14.198f, 14.025f, 13.473f, + 13.283f, 12.255f, 10.678f, 9.273f, 8.775f, 7.437f, 5.761f, 4.473f, 3.305f, + 2.297f, 0.706f, -1.029f, -2.947f, -4.260f, -5.244f, -5.868f, -6.362f, -7.021f, + -6.968f, -7.121f, -6.668f, -6.225f, -6.021f, -6.371f, -6.161f, -5.991f, -5.939f, + -5.121f, -4.740f, -3.576f, -2.084f, -0.972f, 0.189f, 1.408f, 4.183f, 6.732f, + 10.096f, 9.890f, 10.445f, 10.795f, 11.611f, 12.105f, 12.412f, 12.792f, 11.667f, + 11.839f, 11.388f, 12.265f, 13.575f, 14.448f, 16.543f, 20.440f, 21.213f, 29.185f, + 23.628f, 23.349f, 22.638f, 21.077f, 20.477f, 21.085f, 21.727f, 21.990f, 24.074f, + 26.011f, 26.812f, 28.522f, 30.096f, 30.860f, 33.357f, 37.217f, 38.287f, 42.503f, + 48.161f, 52.320f, 54.788f, 56.443f, 57.636f, 59.109f, 60.387f, 62.174f, 63.635f, + 64.969f, 65.928f, 65.606f, 64.617f, 64.182f, 63.445f, 62.916f, 61.916f, 61.413f, + 61.117f, 61.301f, 61.162f, 61.053f, 61.335f, 62.123f, 63.264f, 64.173f, 65.045f, + 65.390f, 64.819f, 64.343f, 63.207f, 60.535f, 59.200f, 58.973f, 57.764f, 52.664f, + 53.458f, 49.865f, 47.533f, 45.834f, 41.835f, 39.028f, 33.630f, 30.955f, 32.679f, + 32.352f, 29.275f, 29.337f, 26.679f, 25.079f, 21.923f, 19.962f, 17.956f, 15.380f, + 13.606f}, + {-29.534f, -28.156f, -24.865f, -21.870f, -18.853f, -17.496f, -17.862f, -16.471f, -14.805f, + -15.136f, -14.944f, -10.647f, -8.134f, -2.414f, -2.757f, -1.414f, -0.889f, -1.678f, + -0.751f, 1.107f, 1.997f, 3.000f, 5.211f, 6.711f, 8.366f, 10.189f, 12.295f, + 14.297f, 17.673f, 16.811f, 13.338f, 9.420f, 9.604f, 8.660f, 14.807f, 18.347f, + 19.165f, 19.223f, 18.332f, 17.280f, 16.851f, 15.996f, 16.223f, 15.981f, 15.888f, + 16.548f, 16.305f, 15.969f, 16.040f, 15.990f, 15.708f, 15.673f, 15.234f, 14.868f, + 14.315f, 13.675f, 11.532f, 10.756f, 9.865f, 8.402f, 6.873f, 5.428f, 4.356f, + 3.185f, 1.701f, 0.200f, -1.777f, -3.334f, -4.578f, -4.990f, -5.648f, -6.242f, + -6.097f, -6.002f, -5.513f, -5.317f, -5.131f, -5.237f, -4.943f, -4.738f, -4.404f, + -3.656f, -3.727f, -2.327f, -0.658f, 0.108f, 1.350f, 2.332f, 5.317f, 7.485f, + 10.195f, 10.279f, 10.837f, 11.398f, 12.115f, 13.276f, 13.310f, 13.928f, 13.021f, + 13.221f, 12.934f, 13.929f, 14.568f, 15.743f, 17.619f, 24.834f, 22.615f, 25.150f, + 24.693f, 24.396f, 23.430f, 22.376f, 21.842f, 22.365f, 22.980f, 23.348f, 24.585f, + 25.444f, 26.781f, 28.649f, 29.816f, 30.377f, 32.666f, 35.349f, 38.269f, 42.000f, + 46.854f, 49.196f, 53.150f, 54.659f, 56.617f, 58.047f, 59.750f, 61.605f, 63.118f, + 64.413f, 65.414f, 65.160f, 63.650f, 64.026f, 62.968f, 62.965f, 62.264f, 60.816f, + 60.801f, 60.759f, 61.907f, 61.060f, 61.012f, 61.525f, 62.736f, 63.895f, 64.795f, + 65.492f, 65.224f, 65.146f, 63.817f, 61.916f, 58.915f, 58.607f, 56.806f, 53.191f, + 52.770f, 49.360f, 48.041f, 46.974f, 39.898f, 35.842f, 32.065f, 30.052f, 32.153f, + 31.818f, 28.601f, 28.971f, 26.667f, 25.327f, 21.976f, 19.965f, 17.997f, 15.386f, + 13.606f}, + {-29.534f, -28.146f, -24.904f, -21.863f, -18.690f, -17.370f, -17.555f, -15.635f, -13.757f, + -14.653f, -14.548f, -10.828f, -7.510f, -2.147f, -2.364f, -1.306f, -0.056f, -0.923f, + -0.615f, 1.208f, 2.022f, 3.108f, 5.228f, 6.461f, 8.317f, 9.983f, 11.632f, + 13.914f, 16.977f, 16.491f, 18.484f, 14.749f, 14.545f, 16.166f, 18.577f, 20.445f, + 20.940f, 19.398f, 18.774f, 18.041f, 17.869f, 17.491f, 17.519f, 17.421f, 17.332f, + 17.744f, 17.803f, 17.581f, 17.673f, 17.501f, 17.107f, 16.996f, 16.425f, 15.990f, + 15.540f, 14.676f, 12.772f, 11.972f, 11.057f, 9.323f, 7.838f, 6.477f, 5.284f, + 4.089f, 2.631f, 1.187f, -0.709f, -2.201f, -3.488f, -4.124f, -4.755f, -4.913f, + -4.673f, -4.193f, -4.224f, -4.227f, -4.069f, -4.048f, -3.575f, -3.271f, -2.633f, + -2.078f, -1.954f, -0.538f, 0.709f, 1.687f, 2.823f, 3.546f, 5.985f, 8.494f, + 10.181f, 10.879f, 11.235f, 11.978f, 12.993f, 14.436f, 15.237f, 15.451f, 14.984f, + 14.518f, 14.489f, 15.106f, 15.326f, 16.481f, 18.238f, 25.235f, 31.100f, 27.099f, + 25.430f, 25.692f, 24.552f, 23.320f, 23.137f, 23.389f, 23.952f, 24.736f, 25.683f, + 25.873f, 27.156f, 29.227f, 30.501f, 31.642f, 33.036f, 34.742f, 37.623f, 41.249f, + 45.233f, 48.569f, 51.548f, 53.552f, 55.695f, 57.279f, 59.365f, 61.697f, 62.567f, + 63.814f, 64.066f, 64.049f, 62.780f, 63.378f, 62.881f, 63.056f, 61.772f, 60.296f, + 60.067f, 60.030f, 62.766f, 61.051f, 60.970f, 60.947f, 62.116f, 63.291f, 64.377f, + 65.152f, 65.897f, 65.723f, 64.557f, 62.938f, 59.650f, 58.779f, 56.253f, 54.973f, + 52.981f, 49.779f, 48.211f, 47.452f, 38.762f, 32.837f, 30.627f, 29.264f, 31.888f, + 31.525f, 27.901f, 28.626f, 26.634f, 25.590f, 22.044f, 19.978f, 18.032f, 15.392f, + 13.606f}, + {-29.534f, -28.136f, -24.952f, -21.855f, -18.526f, -17.312f, -17.261f, -14.908f, -12.917f, + -14.120f, -14.038f, -10.952f, -6.879f, -1.799f, -1.759f, -1.022f, 0.518f, 0.013f, + -0.397f, 1.206f, 2.054f, 3.300f, 5.269f, 6.352f, 8.060f, 9.820f, 11.238f, + 13.609f, 16.469f, 17.213f, 19.620f, 18.391f, 18.277f, 18.846f, 19.759f, 21.203f, + 20.578f, 19.775f, 19.397f, 18.662f, 18.943f, 18.783f, 18.749f, 18.916f, 18.866f, + 19.226f, 19.102f, 19.203f, 19.070f, 18.928f, 18.685f, 18.152f, 17.824f, 16.749f, + 16.624f, 15.844f, 13.678f, 12.948f, 11.733f, 10.246f, 8.656f, 7.412f, 6.233f, + 4.964f, 3.643f, 2.235f, 0.410f, -1.120f, -2.190f, -3.037f, -3.488f, -3.403f, + -2.612f, -2.340f, -2.855f, -2.932f, -2.740f, -2.730f, -2.186f, -1.446f, -0.783f, + -0.214f, 0.139f, 1.238f, 2.484f, 3.120f, 4.564f, 4.758f, 7.557f, 8.309f, + 10.654f, 11.935f, 11.541f, 12.955f, 14.124f, 15.391f, 15.960f, 17.424f, 16.681f, + 16.124f, 15.738f, 15.673f, 16.485f, 17.499f, 19.028f, 21.321f, 25.145f, 25.238f, + 25.968f, 26.800f, 25.555f, 23.905f, 23.775f, 24.219f, 25.095f, 26.172f, 27.288f, + 27.652f, 28.337f, 30.444f, 31.952f, 33.351f, 34.150f, 35.162f, 37.528f, 40.816f, + 43.523f, 48.556f, 50.543f, 51.920f, 54.169f, 56.437f, 58.362f, 60.799f, 62.591f, + 62.830f, 63.051f, 62.228f, 62.624f, 63.140f, 62.686f, 63.097f, 61.579f, 60.137f, + 60.248f, 60.196f, 62.989f, 61.564f, 60.994f, 60.777f, 61.004f, 62.714f, 64.034f, + 64.895f, 66.313f, 66.007f, 65.173f, 63.265f, 60.598f, 59.004f, 56.840f, 55.864f, + 53.440f, 50.686f, 48.117f, 46.664f, 38.350f, 31.251f, 29.653f, 28.635f, 31.851f, + 31.394f, 27.253f, 28.353f, 26.579f, 25.843f, 22.128f, 20.001f, 18.062f, 15.399f, + 13.606f}, + {-29.534f, -28.125f, -25.006f, -21.847f, -18.373f, -17.292f, -16.975f, -14.373f, -12.370f, + -13.679f, -13.579f, -10.909f, -6.425f, -1.346f, -0.948f, -0.804f, 0.875f, 0.926f, + -0.011f, 1.230f, 2.152f, 3.579f, 5.361f, 6.425f, 7.753f, 9.709f, 11.262f, + 13.122f, 16.363f, 17.788f, 20.225f, 19.713f, 19.530f, 19.641f, 20.061f, 20.263f, + 20.972f, 20.117f, 19.982f, 19.590f, 19.888f, 19.556f, 19.946f, 20.275f, 20.283f, + 20.834f, 20.572f, 20.410f, 20.387f, 20.335f, 19.602f, 19.094f, 18.834f, 17.863f, + 17.600f, 16.456f, 14.662f, 13.656f, 12.546f, 11.001f, 9.441f, 8.249f, 7.128f, + 5.880f, 4.610f, 3.267f, 1.526f, 0.068f, -0.855f, -1.699f, -2.108f, -1.870f, + -1.428f, -1.156f, -1.565f, -1.557f, -1.191f, -1.118f, -0.371f, 0.540f, 1.566f, + 2.313f, 2.057f, 3.297f, 4.038f, 4.860f, 5.753f, 6.266f, 8.368f, 8.751f, + 11.591f, 12.780f, 11.669f, 13.433f, 14.951f, 17.049f, 17.254f, 17.034f, 18.666f, + 18.600f, 15.747f, 16.258f, 17.976f, 18.931f, 20.242f, 21.612f, 23.584f, 25.323f, + 26.681f, 26.683f, 25.350f, 23.981f, 23.943f, 24.912f, 26.525f, 28.063f, 29.296f, + 29.630f, 29.625f, 31.596f, 33.359f, 34.636f, 35.682f, 36.270f, 38.384f, 40.238f, + 42.705f, 48.016f, 50.028f, 50.667f, 53.536f, 56.102f, 57.464f, 59.654f, 60.887f, + 61.769f, 61.468f, 62.106f, 62.563f, 62.688f, 62.770f, 62.174f, 60.856f, 60.287f, + 60.423f, 59.763f, 61.099f, 61.752f, 60.906f, 60.664f, 60.629f, 62.002f, 63.594f, + 64.563f, 66.295f, 66.509f, 65.289f, 63.553f, 61.375f, 59.378f, 58.478f, 56.486f, + 54.112f, 51.183f, 48.186f, 45.233f, 38.217f, 31.438f, 29.351f, 28.283f, 31.910f, + 31.301f, 26.764f, 28.175f, 26.504f, 26.058f, 22.226f, 20.032f, 18.084f, 15.406f, + 13.606f}, + {-29.534f, -28.114f, -25.066f, -21.839f, -18.241f, -17.272f, -16.678f, -14.034f, -12.082f, + -13.402f, -13.233f, -10.646f, -6.110f, -1.166f, -0.501f, -0.728f, 1.514f, 1.694f, + 0.396f, 1.217f, 2.420f, 3.898f, 5.579f, 6.433f, 7.607f, 9.363f, 10.786f, + 12.993f, 15.820f, 18.026f, 20.839f, 20.577f, 19.806f, 19.821f, 20.526f, 20.486f, + 21.032f, 20.866f, 20.419f, 20.203f, 20.422f, 20.504f, 21.041f, 21.499f, 21.532f, + 22.031f, 21.922f, 21.620f, 21.773f, 21.438f, 20.882f, 19.990f, 19.729f, 18.836f, + 18.275f, 17.087f, 15.684f, 14.493f, 13.298f, 11.733f, 10.248f, 8.999f, 7.892f, + 6.858f, 5.574f, 4.276f, 2.677f, 1.465f, 0.515f, -0.281f, -0.627f, -0.167f, + -0.182f, 0.115f, -0.064f, -0.076f, 0.370f, 0.658f, 1.521f, 2.490f, 3.870f, + 4.330f, 4.300f, 5.285f, 5.647f, 6.666f, 7.475f, 8.000f, 9.837f, 10.496f, + 12.605f, 12.554f, 12.141f, 14.657f, 15.681f, 16.841f, 18.446f, 18.485f, 18.677f, + 19.779f, 17.071f, 17.475f, 18.811f, 20.121f, 21.483f, 23.172f, 24.978f, 26.238f, + 26.140f, 26.176f, 25.261f, 23.872f, 24.037f, 25.877f, 28.108f, 30.526f, 32.061f, + 31.485f, 31.414f, 32.408f, 34.150f, 35.678f, 37.935f, 39.592f, 40.163f, 41.028f, + 41.409f, 46.624f, 48.626f, 51.082f, 51.872f, 54.055f, 56.727f, 57.687f, 59.893f, + 60.760f, 60.855f, 61.910f, 62.136f, 62.344f, 61.655f, 61.522f, 60.935f, 60.326f, + 61.042f, 60.830f, 61.092f, 61.331f, 61.393f, 60.282f, 60.658f, 61.386f, 63.098f, + 63.360f, 66.727f, 66.912f, 65.564f, 63.774f, 61.869f, 59.761f, 59.554f, 57.054f, + 55.069f, 51.295f, 48.541f, 44.217f, 37.992f, 32.594f, 29.676f, 28.326f, 31.914f, + 31.170f, 26.544f, 28.088f, 26.421f, 26.214f, 22.333f, 20.071f, 18.100f, 15.413f, + 13.606f}, + {-29.534f, -28.102f, -25.127f, -21.831f, -18.138f, -17.215f, -16.355f, -13.832f, -11.937f, + -13.255f, -12.951f, -10.229f, -5.792f, -1.436f, -0.709f, -0.521f, 2.332f, 2.565f, + 1.018f, 1.118f, 2.867f, 4.234f, 5.825f, 6.499f, 7.331f, 9.083f, 10.516f, + 12.734f, 14.840f, 17.930f, 21.094f, 20.934f, 19.790f, 20.026f, 20.186f, 20.818f, + 21.081f, 21.392f, 21.020f, 20.990f, 21.092f, 21.346f, 22.046f, 22.511f, 22.745f, + 23.112f, 22.980f, 22.737f, 22.710f, 22.171f, 21.838f, 20.814f, 20.454f, 19.741f, + 18.966f, 17.813f, 16.416f, 15.274f, 13.994f, 12.458f, 11.045f, 9.918f, 8.888f, + 7.779f, 6.702f, 5.383f, 4.046f, 2.868f, 1.837f, 1.222f, 0.972f, 1.361f, + 1.611f, 1.952f, 1.513f, 1.448f, 2.013f, 2.352f, 3.156f, 4.323f, 5.306f, + 6.251f, 6.422f, 7.577f, 8.192f, 8.790f, 9.719f, 9.616f, 11.878f, 13.079f, + 12.859f, 12.229f, 12.792f, 14.543f, 15.713f, 17.085f, 17.774f, 18.981f, 19.216f, + 18.796f, 18.852f, 19.080f, 20.003f, 21.409f, 23.553f, 24.752f, 25.823f, 26.619f, + 26.296f, 26.228f, 25.671f, 24.735f, 24.860f, 26.875f, 30.075f, 32.979f, 34.198f, + 33.704f, 33.567f, 33.706f, 34.798f, 37.072f, 39.478f, 43.128f, 41.987f, 42.091f, + 41.516f, 45.844f, 47.906f, 49.476f, 50.885f, 52.127f, 55.149f, 58.340f, 58.045f, + 59.381f, 60.815f, 61.141f, 61.507f, 61.441f, 61.107f, 59.969f, 58.997f, 60.085f, + 60.719f, 61.696f, 61.241f, 60.303f, 61.142f, 60.681f, 60.375f, 60.804f, 62.499f, + 62.976f, 67.146f, 67.182f, 65.816f, 63.806f, 62.236f, 60.002f, 59.039f, 56.532f, + 55.313f, 51.704f, 49.043f, 43.999f, 37.676f, 33.470f, 30.301f, 28.752f, 31.791f, + 31.012f, 26.667f, 28.057f, 26.344f, 26.294f, 22.441f, 20.115f, 18.109f, 15.420f, + 13.606f}, + {-29.534f, -28.090f, -25.189f, -21.825f, -18.065f, -17.095f, -16.002f, -13.675f, -11.802f, + -13.131f, -12.651f, -9.831f, -5.411f, -1.644f, -0.980f, 0.184f, 2.704f, 3.989f, + 2.259f, 1.327f, 3.313f, 4.543f, 6.022f, 6.707f, 7.109f, 8.812f, 10.459f, + 11.946f, 14.316f, 17.459f, 21.035f, 20.876f, 19.482f, 19.884f, 20.199f, 21.078f, + 21.514f, 21.808f, 21.650f, 21.849f, 21.811f, 22.535f, 22.832f, 23.479f, 23.880f, + 23.930f, 23.804f, 23.812f, 23.586f, 23.085f, 22.552f, 21.734f, 21.438f, 20.631f, + 19.614f, 18.151f, 17.174f, 15.901f, 14.604f, 13.255f, 11.852f, 10.784f, 9.738f, + 8.713f, 7.808f, 6.572f, 5.409f, 4.179f, 3.115f, 2.774f, 2.578f, 3.183f, + 3.415f, 3.707f, 3.315f, 3.045f, 3.530f, 4.032f, 4.679f, 5.739f, 6.860f, + 7.854f, 8.312f, 9.479f, 10.125f, 10.677f, 11.290f, 11.319f, 13.057f, 15.272f, + 14.834f, 12.260f, 13.140f, 15.442f, 16.555f, 17.383f, 18.156f, 19.444f, 19.956f, + 20.941f, 20.878f, 19.944f, 21.272f, 22.742f, 25.710f, 27.826f, 27.106f, 27.458f, + 26.472f, 26.035f, 27.676f, 28.140f, 27.131f, 28.549f, 31.167f, 32.962f, 33.727f, + 34.192f, 38.058f, 39.078f, 35.500f, 37.246f, 39.865f, 45.191f, 43.092f, 43.823f, + 42.751f, 45.647f, 48.571f, 49.286f, 51.690f, 51.802f, 54.150f, 57.715f, 58.353f, + 58.540f, 60.480f, 60.298f, 60.661f, 60.294f, 59.654f, 58.738f, 57.938f, 59.632f, + 60.778f, 61.499f, 61.347f, 59.795f, 60.699f, 60.666f, 59.862f, 60.486f, 61.703f, + 63.022f, 66.196f, 67.258f, 65.467f, 63.680f, 62.347f, 60.517f, 58.503f, 55.992f, + 54.463f, 52.524f, 49.708f, 44.258f, 37.615f, 33.415f, 30.765f, 29.373f, 31.581f, + 30.904f, 27.148f, 28.034f, 26.289f, 26.293f, 22.542f, 20.162f, 18.112f, 15.427f, + 13.606f}, + {-29.534f, -28.078f, -25.248f, -21.822f, -18.022f, -16.906f, -15.631f, -13.480f, -11.592f, + -12.931f, -12.299f, -9.598f, -5.035f, -1.103f, -0.451f, 1.505f, 2.660f, 5.692f, + 3.910f, 2.098f, 3.574f, 4.840f, 6.185f, 6.808f, 7.236f, 8.651f, 10.200f, + 11.545f, 13.971f, 16.797f, 20.619f, 21.264f, 19.338f, 20.348f, 20.377f, 21.492f, + 21.848f, 22.488f, 22.411f, 22.630f, 22.595f, 23.430f, 24.067f, 24.590f, 24.890f, + 24.893f, 24.831f, 24.823f, 24.594f, 24.246f, 23.287f, 22.537f, 21.977f, 20.890f, + 19.710f, 18.264f, 17.522f, 16.354f, 15.126f, 13.845f, 12.632f, 11.692f, 10.627f, + 9.681f, 8.942f, 7.814f, 6.688f, 5.402f, 4.474f, 4.177f, 4.206f, 4.839f, + 4.839f, 5.018f, 4.907f, 4.624f, 4.908f, 5.457f, 6.111f, 7.100f, 8.020f, + 9.436f, 9.709f, 10.494f, 11.721f, 12.404f, 12.822f, 13.057f, 14.204f, 16.564f, + 16.515f, 14.631f, 13.664f, 16.253f, 17.113f, 17.956f, 18.815f, 20.199f, 21.273f, + 23.052f, 25.424f, 26.159f, 27.278f, 28.622f, 29.012f, 30.472f, 29.723f, 29.778f, + 28.367f, 28.729f, 31.206f, 31.615f, 32.665f, 33.299f, 33.373f, 31.238f, 30.811f, + 33.272f, 45.418f, 37.064f, 36.659f, 37.905f, 40.612f, 48.065f, 44.249f, 47.459f, + 45.105f, 46.954f, 47.128f, 48.918f, 50.562f, 51.382f, 53.639f, 56.511f, 58.497f, + 58.957f, 58.985f, 59.111f, 59.799f, 58.977f, 58.217f, 57.676f, 57.492f, 59.165f, + 59.713f, 60.204f, 61.978f, 60.402f, 59.591f, 59.858f, 59.714f, 60.074f, 61.009f, + 62.232f, 65.209f, 66.703f, 65.239f, 63.422f, 61.881f, 60.835f, 58.974f, 56.659f, + 53.664f, 52.958f, 50.441f, 44.692f, 38.165f, 32.824f, 30.784f, 29.917f, 31.395f, + 30.907f, 27.922f, 27.970f, 26.271f, 26.214f, 22.626f, 20.209f, 18.109f, 15.434f, + 13.606f}, + {-29.534f, -28.065f, -25.302f, -21.823f, -18.007f, -16.657f, -15.270f, -13.202f, -11.299f, + -12.633f, -11.930f, -9.529f, -4.749f, 0.145f, 0.968f, 3.110f, 2.967f, 6.715f, + 5.521f, 3.278f, 3.752f, 5.136f, 6.291f, 6.968f, 7.373f, 8.654f, 10.084f, + 11.600f, 13.854f, 16.179f, 19.687f, 20.861f, 19.435f, 20.922f, 21.080f, 21.975f, + 22.359f, 22.793f, 22.910f, 23.453f, 23.498f, 24.084f, 24.865f, 25.714f, 25.705f, + 25.890f, 25.688f, 25.358f, 25.136f, 24.502f, 23.883f, 23.257f, 21.896f, 20.657f, + 19.518f, 18.617f, 17.687f, 16.577f, 15.733f, 14.439f, 13.376f, 12.420f, 11.579f, + 10.837f, 9.986f, 9.059f, 7.994f, 6.730f, 6.070f, 5.590f, 5.627f, 6.030f, + 6.132f, 6.251f, 6.187f, 5.987f, 6.263f, 6.836f, 7.388f, 8.410f, 9.223f, + 10.492f, 10.850f, 12.112f, 12.870f, 13.915f, 14.456f, 14.709f, 15.349f, 18.233f, + 18.261f, 16.228f, 14.394f, 16.753f, 17.970f, 18.892f, 19.799f, 21.024f, 22.698f, + 25.141f, 28.759f, 28.193f, 28.217f, 29.796f, 30.199f, 29.379f, 30.052f, 31.613f, + 32.799f, 33.071f, 32.595f, 34.733f, 35.952f, 35.634f, 34.747f, 33.608f, 31.244f, + 31.773f, 44.216f, 36.692f, 38.927f, 38.674f, 40.152f, 45.124f, 45.854f, 48.104f, + 47.277f, 47.169f, 48.163f, 48.385f, 49.433f, 51.086f, 52.735f, 55.561f, 55.745f, + 58.817f, 58.577f, 58.102f, 58.432f, 58.023f, 57.512f, 57.073f, 58.028f, 58.641f, + 58.983f, 58.459f, 61.588f, 59.584f, 59.527f, 58.898f, 59.741f, 59.725f, 60.534f, + 61.279f, 64.681f, 66.280f, 65.252f, 63.186f, 61.392f, 60.478f, 59.433f, 57.349f, + 53.767f, 52.380f, 50.719f, 45.317f, 39.329f, 32.679f, 30.528f, 30.227f, 31.317f, + 31.006f, 28.864f, 27.839f, 26.299f, 26.068f, 22.685f, 20.252f, 18.100f, 15.441f, + 13.606f}, + {-29.534f, -28.053f, -25.350f, -21.829f, -18.014f, -16.377f, -14.954f, -12.854f, -10.978f, + -12.305f, -11.605f, -9.488f, -4.538f, 1.304f, 2.552f, 4.426f, 3.970f, 6.838f, + 6.983f, 4.809f, 4.100f, 5.307f, 6.333f, 7.157f, 7.517f, 8.647f, 10.051f, + 11.241f, 13.521f, 15.896f, 19.164f, 21.320f, 19.371f, 21.067f, 21.330f, 22.332f, + 22.652f, 23.290f, 23.554f, 24.257f, 24.636f, 24.871f, 25.578f, 26.420f, 26.628f, + 26.328f, 25.456f, 25.179f, 24.892f, 24.389f, 23.865f, 23.093f, 21.902f, 20.738f, + 19.550f, 18.684f, 18.129f, 17.284f, 16.215f, 15.028f, 14.181f, 13.186f, 12.431f, + 11.817f, 11.085f, 10.257f, 9.268f, 8.105f, 7.569f, 7.088f, 6.886f, 7.128f, + 7.192f, 7.417f, 7.314f, 7.265f, 7.767f, 8.667f, 8.680f, 9.759f, 10.473f, + 11.764f, 12.114f, 12.854f, 13.981f, 15.013f, 15.841f, 16.153f, 17.002f, 17.821f, + 18.763f, 16.660f, 14.846f, 17.530f, 19.002f, 19.893f, 20.810f, 21.848f, 23.988f, + 28.611f, 30.376f, 28.830f, 29.243f, 30.966f, 30.491f, 30.921f, 31.536f, 32.165f, + 32.356f, 33.895f, 33.633f, 35.801f, 35.765f, 37.562f, 37.243f, 33.970f, 33.609f, + 31.707f, 40.889f, 36.019f, 39.500f, 41.097f, 40.479f, 42.653f, 45.228f, 46.412f, + 48.779f, 50.747f, 48.519f, 49.050f, 48.392f, 49.629f, 51.132f, 53.139f, 54.662f, + 57.225f, 56.714f, 57.026f, 57.263f, 56.926f, 56.608f, 58.999f, 60.508f, 60.171f, + 58.015f, 57.566f, 60.127f, 60.360f, 59.984f, 58.811f, 59.927f, 59.590f, 60.126f, + 60.621f, 64.009f, 65.880f, 64.406f, 62.836f, 60.854f, 60.054f, 59.323f, 57.319f, + 54.251f, 51.273f, 50.195f, 46.125f, 40.665f, 33.675f, 30.568f, 30.356f, 31.348f, + 31.124f, 29.823f, 27.652f, 26.378f, 25.873f, 22.713f, 20.291f, 18.086f, 15.447f, + 13.606f}, + {-29.534f, -28.040f, -25.389f, -21.840f, -18.036f, -16.102f, -14.713f, -12.492f, -10.708f, + -12.043f, -11.356f, -9.344f, -4.316f, 1.754f, 3.710f, 5.269f, 5.178f, 6.900f, + 7.892f, 6.582f, 4.724f, 5.445f, 6.336f, 7.137f, 7.672f, 8.713f, 9.962f, + 10.966f, 13.052f, 15.920f, 18.417f, 20.643f, 18.639f, 21.151f, 21.741f, 22.453f, + 23.144f, 23.881f, 24.294f, 24.828f, 25.468f, 25.819f, 26.217f, 27.401f, 27.008f, + 26.211f, 25.579f, 25.272f, 24.939f, 24.415f, 23.667f, 22.865f, 21.864f, 20.546f, + 19.280f, 18.398f, 17.873f, 17.383f, 16.427f, 15.801f, 15.021f, 13.818f, 13.331f, + 13.033f, 12.291f, 11.541f, 10.964f, 9.528f, 9.108f, 8.394f, 8.246f, 8.159f, + 8.233f, 8.706f, 8.385f, 8.701f, 8.830f, 9.311f, 9.632f, 10.661f, 11.995f, + 13.258f, 14.334f, 14.096f, 15.158f, 16.146f, 17.024f, 17.603f, 18.239f, 18.509f, + 19.316f, 17.207f, 15.959f, 18.058f, 19.347f, 20.253f, 21.666f, 23.057f, 30.599f, + 32.346f, 31.335f, 31.051f, 30.187f, 30.740f, 31.241f, 31.997f, 33.221f, 33.849f, + 34.679f, 35.095f, 33.649f, 35.292f, 35.589f, 37.154f, 39.815f, 37.128f, 35.979f, + 36.074f, 41.228f, 42.236f, 40.616f, 44.012f, 41.659f, 41.054f, 43.224f, 45.747f, + 45.761f, 52.187f, 50.144f, 50.421f, 47.031f, 48.571f, 50.530f, 50.804f, 55.243f, + 55.462f, 55.001f, 56.074f, 56.382f, 55.786f, 56.070f, 60.145f, 60.964f, 61.495f, + 58.021f, 57.153f, 57.624f, 59.600f, 59.558f, 58.248f, 59.581f, 59.457f, 60.326f, + 60.914f, 63.172f, 64.338f, 63.308f, 61.989f, 59.959f, 59.606f, 58.949f, 57.373f, + 54.290f, 50.566f, 49.281f, 46.823f, 41.645f, 35.670f, 31.400f, 30.499f, 31.426f, + 31.193f, 30.661f, 27.448f, 26.502f, 25.646f, 22.708f, 20.321f, 18.068f, 15.453f, + 13.606f}, + {-29.534f, -28.027f, -25.419f, -21.856f, -18.067f, -15.869f, -14.558f, -12.187f, -10.538f, + -11.898f, -11.156f, -9.077f, -4.064f, 1.685f, 4.525f, 6.143f, 6.078f, 7.348f, + 7.943f, 8.267f, 5.565f, 5.810f, 6.294f, 7.182f, 7.709f, 8.595f, 9.770f, + 11.079f, 12.982f, 15.861f, 18.100f, 20.396f, 19.002f, 21.326f, 21.830f, 22.841f, + 23.421f, 24.394f, 24.759f, 25.337f, 26.015f, 26.551f, 27.122f, 27.620f, 26.870f, + 26.068f, 25.747f, 25.161f, 24.778f, 24.258f, 23.223f, 22.691f, 21.642f, 20.583f, + 18.925f, 17.886f, 17.331f, 16.718f, 16.226f, 15.904f, 15.257f, 14.543f, 14.135f, + 13.594f, 12.957f, 12.334f, 11.756f, 11.039f, 10.458f, 9.857f, 9.820f, 9.747f, + 9.529f, 9.240f, 9.159f, 9.539f, 9.333f, 9.458f, 9.865f, 11.874f, 13.254f, + 14.218f, 15.076f, 15.097f, 16.454f, 17.465f, 18.290f, 18.768f, 19.561f, 19.479f, + 19.476f, 17.236f, 17.973f, 19.331f, 20.318f, 21.272f, 22.756f, 26.736f, 32.665f, + 32.068f, 32.780f, 32.285f, 30.297f, 31.018f, 32.188f, 33.193f, 31.784f, 30.446f, + 30.850f, 32.112f, 33.617f, 35.455f, 36.827f, 38.961f, 39.193f, 39.455f, 38.815f, + 38.258f, 39.493f, 42.125f, 44.465f, 44.226f, 42.922f, 42.261f, 41.925f, 47.748f, + 46.101f, 48.142f, 48.123f, 50.916f, 45.930f, 48.003f, 50.154f, 51.824f, 53.070f, + 56.170f, 54.190f, 55.219f, 54.695f, 56.474f, 57.154f, 58.363f, 60.239f, 60.425f, + 58.500f, 56.336f, 56.572f, 56.516f, 57.092f, 56.389f, 58.468f, 59.579f, 60.434f, + 61.582f, 62.669f, 63.069f, 62.915f, 60.339f, 59.364f, 58.906f, 58.517f, 57.582f, + 53.843f, 50.459f, 48.634f, 47.057f, 42.162f, 37.859f, 32.949f, 30.811f, 31.501f, + 31.229f, 31.283f, 27.292f, 26.656f, 25.407f, 22.672f, 20.342f, 18.045f, 15.458f, + 13.606f}, + {-29.534f, -28.014f, -25.438f, -21.876f, -18.100f, -15.706f, -14.480f, -11.996f, -10.469f, + -11.839f, -10.935f, -8.753f, -3.873f, 1.658f, 5.288f, 7.563f, 6.695f, 7.659f, + 8.172f, 9.786f, 6.569f, 6.289f, 6.294f, 7.190f, 7.825f, 8.562f, 9.763f, + 10.820f, 12.894f, 15.459f, 17.609f, 19.951f, 19.083f, 21.599f, 22.018f, 23.191f, + 23.914f, 24.848f, 25.153f, 25.880f, 26.281f, 26.937f, 27.724f, 27.264f, 26.475f, + 25.974f, 25.504f, 24.776f, 24.454f, 24.026f, 23.233f, 22.609f, 21.358f, 20.312f, + 18.499f, 17.537f, 16.761f, 16.180f, 15.962f, 15.357f, 15.088f, 14.485f, 14.243f, + 13.676f, 13.179f, 12.572f, 12.085f, 12.067f, 11.414f, 11.681f, 11.568f, 11.159f, + 10.247f, 10.134f, 9.578f, 9.726f, 9.592f, 9.758f, 10.264f, 11.444f, 12.834f, + 13.954f, 15.100f, 15.771f, 17.464f, 18.239f, 19.065f, 19.707f, 19.983f, 19.721f, + 19.001f, 17.587f, 20.126f, 20.293f, 21.045f, 22.563f, 24.505f, 31.245f, 30.264f, + 29.829f, 32.141f, 35.299f, 33.011f, 30.707f, 30.377f, 29.307f, 27.665f, 27.350f, + 29.518f, 31.305f, 32.959f, 35.160f, 36.896f, 38.115f, 38.410f, 39.508f, 39.081f, + 39.099f, 39.458f, 40.986f, 42.043f, 44.135f, 43.123f, 42.467f, 41.245f, 47.396f, + 46.962f, 45.799f, 45.075f, 48.614f, 45.837f, 48.103f, 50.978f, 55.259f, 49.869f, + 53.879f, 52.202f, 52.579f, 54.366f, 57.675f, 57.471f, 58.554f, 59.760f, 60.584f, + 58.751f, 56.252f, 55.242f, 55.440f, 55.790f, 55.703f, 57.691f, 59.157f, 60.176f, + 61.560f, 62.383f, 62.496f, 61.853f, 58.504f, 58.763f, 58.320f, 57.925f, 57.299f, + 53.460f, 50.533f, 48.413f, 46.784f, 42.595f, 39.434f, 34.568f, 31.315f, 31.607f, + 31.341f, 31.638f, 27.243f, 26.819f, 25.172f, 22.612f, 20.353f, 18.018f, 15.462f, + 13.606f}, + {-29.534f, -28.001f, -25.445f, -21.900f, -18.131f, -15.631f, -14.451f, -11.935f, -10.455f, + -11.777f, -10.637f, -8.410f, -3.818f, 1.828f, 5.935f, 9.198f, 7.253f, 7.581f, + 9.403f, 10.939f, 7.717f, 6.738f, 6.457f, 7.042f, 7.913f, 8.677f, 9.747f, + 10.614f, 13.201f, 15.189f, 17.173f, 19.922f, 19.325f, 21.888f, 22.549f, 23.915f, + 24.567f, 25.463f, 25.672f, 26.282f, 26.743f, 27.389f, 28.076f, 27.146f, 26.622f, + 25.856f, 24.904f, 24.416f, 24.258f, 23.686f, 23.214f, 22.236f, 21.176f, 19.527f, + 18.012f, 17.235f, 16.420f, 15.802f, 15.660f, 15.326f, 14.982f, 14.613f, 14.235f, + 14.065f, 13.522f, 12.980f, 12.578f, 12.462f, 12.174f, 12.382f, 12.038f, 11.456f, + 10.884f, 10.590f, 10.450f, 10.401f, 10.189f, 10.022f, 10.342f, 11.324f, 12.758f, + 13.758f, 15.221f, 16.049f, 17.934f, 18.416f, 18.986f, 19.240f, 19.876f, 20.004f, + 19.126f, 18.726f, 19.963f, 20.662f, 21.547f, 23.264f, 28.050f, 30.881f, 32.219f, + 32.683f, 33.081f, 33.569f, 33.382f, 31.330f, 30.695f, 29.658f, 27.857f, 26.637f, + 28.628f, 30.734f, 31.860f, 32.981f, 35.458f, 36.254f, 38.007f, 38.726f, 40.152f, + 39.396f, 39.137f, 41.404f, 39.657f, 42.935f, 43.550f, 40.777f, 40.098f, 44.058f, + 43.760f, 50.640f, 44.342f, 49.395f, 45.815f, 47.912f, 52.036f, 52.968f, 47.417f, + 52.998f, 49.996f, 50.165f, 53.143f, 58.253f, 59.089f, 59.554f, 59.412f, 59.949f, + 59.358f, 56.139f, 55.780f, 55.871f, 55.638f, 55.446f, 56.596f, 58.759f, 59.913f, + 61.037f, 61.443f, 61.378f, 59.850f, 57.679f, 57.650f, 57.719f, 56.832f, 56.598f, + 53.406f, 50.555f, 48.366f, 46.289f, 43.304f, 40.170f, 35.616f, 31.977f, 31.853f, + 31.647f, 31.707f, 27.341f, 26.967f, 24.955f, 22.535f, 20.353f, 17.989f, 15.466f, + 13.606f}, + {-29.534f, -27.988f, -25.441f, -21.927f, -18.156f, -15.641f, -14.432f, -11.976f, -10.436f, + -11.631f, -10.258f, -8.023f, -3.812f, 1.899f, 6.244f, 10.204f, 7.829f, 7.797f, + 10.339f, 11.149f, 8.781f, 7.228f, 6.741f, 7.181f, 8.023f, 8.843f, 9.678f, + 11.071f, 13.269f, 14.926f, 16.702f, 19.664f, 19.318f, 22.584f, 23.014f, 24.449f, + 25.286f, 26.068f, 26.323f, 26.466f, 26.901f, 27.588f, 28.095f, 27.252f, 26.094f, + 25.658f, 24.697f, 23.948f, 23.826f, 23.441f, 23.167f, 22.198f, 21.011f, 19.466f, + 18.061f, 16.865f, 16.104f, 15.660f, 15.551f, 15.233f, 14.860f, 14.794f, 14.367f, + 14.313f, 13.727f, 13.302f, 12.826f, 12.558f, 12.290f, 12.477f, 12.176f, 12.143f, + 11.598f, 10.996f, 10.890f, 10.975f, 10.596f, 10.397f, 10.510f, 11.163f, 12.658f, + 13.795f, 15.017f, 16.405f, 17.395f, 18.339f, 18.737f, 19.159f, 19.729f, 19.993f, + 19.457f, 19.474f, 19.558f, 20.438f, 22.389f, 26.902f, 30.043f, 31.342f, 33.879f, + 34.067f, 32.657f, 32.030f, 33.016f, 32.345f, 31.291f, 30.109f, 28.525f, 27.671f, + 28.298f, 29.617f, 30.315f, 31.549f, 33.103f, 34.657f, 36.367f, 37.939f, 39.918f, + 39.872f, 38.996f, 42.223f, 43.405f, 46.000f, 45.571f, 39.407f, 37.413f, 43.020f, + 43.175f, 48.848f, 49.007f, 53.380f, 48.540f, 49.108f, 52.578f, 53.558f, 47.332f, + 51.037f, 49.060f, 49.863f, 52.129f, 57.635f, 58.389f, 59.033f, 58.362f, 58.548f, + 58.750f, 57.907f, 56.814f, 55.808f, 55.691f, 56.206f, 55.457f, 58.202f, 59.395f, + 60.167f, 59.940f, 59.593f, 58.435f, 57.274f, 56.638f, 56.787f, 55.741f, 56.082f, + 53.410f, 50.579f, 48.271f, 45.894f, 44.143f, 40.466f, 36.056f, 32.826f, 32.334f, + 32.155f, 31.496f, 27.587f, 27.081f, 24.770f, 22.455f, 20.342f, 17.957f, 15.469f, + 13.606f}, + {-29.534f, -27.976f, -25.426f, -21.955f, -18.172f, -15.719f, -14.392f, -12.066f, -10.377f, + -11.386f, -9.851f, -7.577f, -3.676f, 1.715f, 6.306f, 10.395f, 8.504f, 9.016f, + 10.067f, 10.742f, 9.504f, 7.641f, 7.196f, 7.620f, 8.286f, 9.093f, 9.782f, + 11.519f, 12.844f, 14.696f, 16.458f, 19.287f, 20.265f, 23.093f, 23.518f, 25.086f, + 25.487f, 26.372f, 26.989f, 26.809f, 27.225f, 27.415f, 27.213f, 27.013f, 25.338f, + 25.344f, 24.525f, 23.509f, 23.720f, 22.992f, 22.270f, 21.772f, 20.854f, 19.314f, + 17.940f, 16.856f, 16.064f, 15.567f, 15.416f, 15.087f, 15.009f, 14.877f, 14.624f, + 14.587f, 13.970f, 13.535f, 12.963f, 12.622f, 12.527f, 12.642f, 12.374f, 12.420f, + 12.261f, 11.616f, 11.309f, 11.505f, 11.324f, 10.796f, 11.055f, 11.450f, 12.984f, + 13.968f, 14.882f, 16.388f, 17.018f, 18.187f, 18.560f, 18.969f, 19.487f, 19.891f, + 19.540f, 19.937f, 18.622f, 21.106f, 24.295f, 30.284f, 30.753f, 32.063f, 34.905f, + 34.937f, 32.379f, 31.576f, 32.078f, 32.508f, 31.220f, 29.775f, 28.598f, 27.603f, + 28.037f, 28.494f, 28.811f, 30.011f, 31.854f, 32.602f, 33.976f, 35.906f, 37.278f, + 38.499f, 38.945f, 42.086f, 47.290f, 51.050f, 48.298f, 45.962f, 37.994f, 41.038f, + 44.757f, 51.849f, 52.736f, 54.109f, 54.009f, 54.540f, 55.626f, 55.319f, 51.317f, + 47.793f, 48.116f, 50.142f, 52.391f, 55.954f, 57.563f, 57.783f, 57.754f, 57.535f, + 58.241f, 58.392f, 57.779f, 57.689f, 58.153f, 55.312f, 55.575f, 58.142f, 59.318f, + 59.534f, 58.487f, 57.650f, 57.548f, 56.376f, 55.690f, 55.596f, 55.297f, 55.880f, + 53.222f, 50.635f, 48.051f, 45.720f, 44.614f, 40.877f, 36.433f, 33.936f, 33.031f, + 32.700f, 31.036f, 27.941f, 27.150f, 24.624f, 22.383f, 20.324f, 17.923f, 15.471f, + 13.606f}, + {-29.534f, -27.963f, -25.399f, -21.982f, -18.178f, -15.836f, -14.315f, -12.143f, -10.284f, + -11.097f, -9.484f, -7.128f, -3.363f, 1.523f, 6.426f, 10.458f, 9.521f, 11.107f, + 10.313f, 10.790f, 10.004f, 8.132f, 7.738f, 8.102f, 8.660f, 9.287f, 10.144f, + 11.621f, 13.005f, 14.648f, 16.228f, 18.780f, 21.086f, 24.108f, 24.314f, 25.263f, + 25.628f, 26.532f, 27.312f, 27.286f, 27.270f, 26.559f, 26.642f, 26.623f, 24.732f, + 25.260f, 24.117f, 23.382f, 23.353f, 22.887f, 22.154f, 21.828f, 20.241f, 19.254f, + 17.726f, 16.610f, 16.126f, 15.713f, 15.336f, 15.157f, 15.256f, 15.067f, 15.027f, + 14.938f, 14.430f, 13.736f, 13.242f, 12.716f, 12.631f, 12.819f, 12.620f, 12.379f, + 12.728f, 12.280f, 11.842f, 12.003f, 12.003f, 11.639f, 11.727f, 12.095f, 13.062f, + 14.254f, 14.687f, 15.940f, 16.263f, 17.780f, 18.277f, 18.813f, 19.166f, 19.564f, + 19.331f, 19.677f, 18.360f, 20.500f, 25.177f, 29.610f, 30.580f, 31.274f, 33.646f, + 33.553f, 31.810f, 30.824f, 30.570f, 30.759f, 30.115f, 29.084f, 27.929f, 27.588f, + 27.610f, 27.559f, 27.271f, 28.666f, 30.468f, 30.988f, 32.595f, 33.805f, 34.847f, + 38.009f, 37.753f, 39.907f, 49.234f, 53.102f, 49.358f, 48.280f, 43.148f, 40.652f, + 45.405f, 51.801f, 54.779f, 54.919f, 55.882f, 55.951f, 56.313f, 56.552f, 50.813f, + 46.464f, 47.452f, 48.695f, 53.423f, 54.983f, 56.090f, 56.137f, 56.475f, 56.868f, + 57.519f, 57.588f, 58.138f, 58.110f, 57.328f, 55.394f, 55.616f, 56.954f, 58.283f, + 58.715f, 57.285f, 56.716f, 56.051f, 55.497f, 54.711f, 54.056f, 54.392f, 55.402f, + 52.937f, 50.680f, 47.785f, 45.699f, 44.469f, 41.566f, 37.259f, 35.256f, 33.777f, + 33.010f, 30.396f, 28.337f, 27.174f, 24.525f, 22.330f, 20.298f, 17.888f, 15.472f, + 13.606f}, + {-29.534f, -27.951f, -25.361f, -22.007f, -18.175f, -15.957f, -14.208f, -12.173f, -10.196f, + -10.834f, -9.176f, -6.753f, -3.025f, 1.611f, 6.662f, 10.861f, 10.996f, 13.260f, + 12.214f, 11.062f, 10.351f, 8.975f, 8.008f, 8.449f, 9.137f, 9.729f, 10.588f, + 11.575f, 13.139f, 14.464f, 15.714f, 18.258f, 21.129f, 24.192f, 24.902f, 25.685f, + 26.229f, 26.944f, 27.390f, 27.584f, 27.181f, 26.419f, 26.157f, 25.335f, 24.572f, + 24.938f, 23.818f, 22.840f, 23.119f, 22.374f, 21.878f, 20.407f, 20.047f, 18.621f, + 17.216f, 16.656f, 16.162f, 15.908f, 15.400f, 15.470f, 15.542f, 15.399f, 15.425f, + 15.414f, 15.027f, 14.219f, 13.643f, 13.074f, 12.848f, 13.085f, 12.950f, 12.445f, + 12.692f, 12.683f, 12.716f, 12.393f, 12.596f, 12.309f, 12.185f, 12.525f, 13.084f, + 14.177f, 14.816f, 15.426f, 15.868f, 17.529f, 18.201f, 18.568f, 18.815f, 19.238f, + 19.426f, 19.142f, 18.284f, 20.063f, 23.947f, 28.746f, 29.246f, 30.458f, 30.900f, + 30.506f, 29.736f, 28.872f, 29.113f, 29.065f, 29.236f, 28.343f, 27.911f, 27.795f, + 27.307f, 26.839f, 26.799f, 27.801f, 28.915f, 29.442f, 30.554f, 31.560f, 33.029f, + 35.005f, 36.454f, 40.048f, 47.999f, 53.869f, 50.408f, 50.596f, 45.137f, 40.030f, + 41.645f, 50.500f, 55.377f, 55.081f, 55.093f, 55.873f, 57.102f, 56.227f, 48.652f, + 45.555f, 47.336f, 48.037f, 53.577f, 53.880f, 54.917f, 54.802f, 55.733f, 55.878f, + 56.889f, 57.227f, 57.118f, 57.029f, 57.129f, 56.501f, 55.417f, 56.582f, 57.260f, + 57.102f, 55.464f, 55.868f, 54.348f, 54.278f, 53.771f, 52.483f, 52.474f, 54.457f, + 52.727f, 50.632f, 47.673f, 45.686f, 43.961f, 42.189f, 38.452f, 36.485f, 34.336f, + 32.862f, 29.699f, 28.698f, 27.168f, 24.476f, 22.303f, 20.269f, 17.852f, 15.473f, + 13.606f}, + {-29.534f, -27.940f, -25.313f, -22.028f, -18.166f, -16.047f, -14.101f, -12.154f, -10.163f, + -10.632f, -8.878f, -6.432f, -2.803f, 1.938f, 6.824f, 11.194f, 12.547f, 14.573f, + 13.951f, 10.757f, 10.454f, 9.537f, 8.267f, 8.700f, 9.497f, 10.219f, 10.781f, + 11.549f, 12.816f, 13.989f, 15.532f, 18.040f, 21.301f, 24.363f, 25.535f, 26.142f, + 26.901f, 27.393f, 27.968f, 27.873f, 26.891f, 25.727f, 25.262f, 24.845f, 24.074f, + 24.831f, 23.330f, 22.504f, 22.336f, 22.295f, 21.853f, 19.819f, 19.437f, 18.447f, + 17.165f, 16.669f, 16.457f, 16.418f, 15.901f, 15.990f, 15.950f, 15.971f, 16.049f, + 15.872f, 15.677f, 14.815f, 13.993f, 13.602f, 13.301f, 13.223f, 13.141f, 12.682f, + 12.698f, 12.762f, 13.895f, 12.758f, 13.111f, 14.263f, 11.866f, 12.626f, 13.359f, + 13.954f, 14.626f, 15.141f, 15.922f, 17.064f, 17.996f, 18.214f, 18.227f, 18.769f, + 19.466f, 18.663f, 18.188f, 19.537f, 23.079f, 27.015f, 29.004f, 29.951f, 30.078f, + 29.079f, 28.368f, 28.745f, 28.829f, 28.481f, 28.554f, 28.009f, 27.766f, 27.831f, + 26.863f, 26.276f, 26.719f, 27.281f, 27.294f, 27.886f, 30.195f, 30.530f, 31.677f, + 33.336f, 35.968f, 40.253f, 47.269f, 52.336f, 55.495f, 52.161f, 45.669f, 40.116f, + 41.669f, 47.313f, 54.971f, 54.292f, 54.816f, 56.167f, 56.810f, 56.099f, 47.762f, + 44.927f, 46.670f, 48.238f, 52.400f, 52.801f, 53.820f, 54.465f, 54.518f, 55.760f, + 56.262f, 55.766f, 55.809f, 55.603f, 55.866f, 55.893f, 55.372f, 55.350f, 56.109f, + 55.515f, 53.497f, 54.303f, 53.632f, 52.719f, 52.324f, 51.546f, 51.265f, 53.747f, + 52.593f, 50.398f, 47.744f, 45.581f, 43.461f, 42.295f, 39.420f, 37.183f, 34.533f, + 32.247f, 29.111f, 28.961f, 27.153f, 24.480f, 22.307f, 20.238f, 17.817f, 15.472f, + 13.606f}, + {-29.534f, -27.928f, -25.257f, -22.044f, -18.154f, -16.080f, -14.031f, -12.119f, -10.211f, + -10.467f, -8.520f, -6.036f, -2.595f, 2.265f, 6.854f, 11.013f, 13.524f, 14.594f, + 14.044f, 10.477f, 10.546f, 9.311f, 8.946f, 9.174f, 9.873f, 10.515f, 11.001f, + 11.605f, 12.781f, 13.863f, 15.467f, 18.000f, 21.236f, 24.577f, 25.184f, 26.506f, + 27.051f, 27.802f, 27.889f, 27.379f, 26.587f, 25.449f, 24.635f, 24.287f, 23.468f, + 24.268f, 23.231f, 22.220f, 21.973f, 20.431f, 19.967f, 19.016f, 18.700f, 18.007f, + 17.496f, 17.829f, 16.779f, 17.246f, 16.870f, 16.630f, 16.651f, 16.566f, 16.708f, + 16.551f, 16.338f, 15.639f, 14.694f, 14.203f, 13.775f, 13.594f, 13.478f, 12.835f, + 12.769f, 13.048f, 13.050f, 13.045f, 13.288f, 13.373f, 12.962f, 12.712f, 13.381f, + 14.086f, 15.010f, 15.376f, 15.591f, 16.836f, 17.802f, 17.811f, 17.727f, 18.252f, + 18.851f, 18.444f, 19.283f, 19.079f, 22.399f, 25.615f, 27.363f, 28.189f, 28.789f, + 28.367f, 27.905f, 29.157f, 28.605f, 27.885f, 28.207f, 28.333f, 28.090f, 27.467f, + 26.833f, 25.929f, 26.909f, 27.385f, 26.130f, 25.918f, 28.534f, 30.376f, 31.556f, + 33.261f, 36.021f, 40.426f, 46.259f, 49.718f, 53.836f, 54.610f, 47.548f, 43.626f, + 42.412f, 47.245f, 52.206f, 54.330f, 54.471f, 54.537f, 54.489f, 55.206f, 49.560f, + 44.856f, 46.214f, 50.297f, 51.463f, 51.730f, 52.943f, 53.962f, 54.035f, 54.585f, + 55.260f, 55.094f, 55.036f, 54.925f, 55.201f, 54.540f, 54.208f, 53.215f, 54.483f, + 53.572f, 52.335f, 53.278f, 52.998f, 52.028f, 51.032f, 51.089f, 51.329f, 53.474f, + 52.424f, 50.058f, 47.734f, 45.418f, 43.036f, 41.825f, 39.673f, 37.096f, 34.365f, + 31.408f, 28.793f, 29.090f, 27.152f, 24.531f, 22.340f, 20.208f, 17.782f, 15.471f, + 13.606f}, + {-29.534f, -27.917f, -25.194f, -22.052f, -18.141f, -16.045f, -14.028f, -12.115f, -10.332f, + -10.284f, -8.083f, -5.487f, -2.173f, 2.467f, 6.901f, 10.695f, 13.676f, 13.673f, + 13.489f, 10.738f, 10.508f, 8.912f, 9.663f, 9.826f, 10.348f, 10.839f, 11.120f, + 11.655f, 12.731f, 14.062f, 15.206f, 17.998f, 20.741f, 24.186f, 25.490f, 26.650f, + 27.370f, 28.226f, 27.597f, 27.037f, 26.408f, 25.093f, 24.333f, 24.141f, 23.238f, + 23.646f, 22.309f, 21.198f, 21.411f, 20.129f, 18.942f, 18.585f, 17.316f, 17.713f, + 17.530f, 17.386f, 17.840f, 17.350f, 18.276f, 17.562f, 17.498f, 17.530f, 17.295f, + 17.432f, 17.095f, 16.458f, 15.611f, 15.015f, 14.446f, 14.171f, 13.981f, 13.354f, + 13.052f, 13.017f, 13.144f, 13.434f, 13.030f, 13.289f, 12.728f, 12.691f, 13.365f, + 14.059f, 14.996f, 15.891f, 15.900f, 16.583f, 17.722f, 17.607f, 17.593f, 17.821f, + 18.106f, 18.063f, 19.028f, 18.142f, 20.507f, 24.238f, 27.220f, 27.701f, 27.328f, + 27.005f, 27.018f, 27.628f, 27.856f, 28.115f, 29.075f, 29.100f, 28.526f, 28.130f, + 27.013f, 26.444f, 27.031f, 27.390f, 25.485f, 25.230f, 27.249f, 29.373f, 31.322f, + 32.977f, 35.790f, 40.126f, 43.658f, 47.860f, 51.136f, 52.410f, 51.533f, 48.364f, + 45.523f, 48.400f, 50.838f, 54.138f, 52.391f, 53.721f, 53.621f, 53.615f, 46.230f, + 44.392f, 48.421f, 49.724f, 50.653f, 50.816f, 52.053f, 52.937f, 53.850f, 54.571f, + 53.858f, 54.424f, 54.047f, 53.723f, 52.786f, 53.645f, 53.724f, 51.715f, 52.420f, + 52.165f, 51.892f, 52.695f, 52.000f, 51.623f, 50.830f, 50.572f, 51.300f, 53.068f, + 52.194f, 49.783f, 47.489f, 45.286f, 42.578f, 41.210f, 39.279f, 36.408f, 34.000f, + 30.733f, 28.845f, 29.087f, 27.181f, 24.621f, 22.397f, 20.183f, 17.748f, 15.469f, + 13.606f}, + {-29.534f, -27.907f, -25.125f, -22.051f, -18.133f, -15.945f, -14.108f, -12.177f, -10.485f, + -10.048f, -7.640f, -4.909f, -1.564f, 2.546f, 6.975f, 10.804f, 13.300f, 12.704f, + 13.200f, 10.919f, 10.144f, 8.827f, 9.978f, 10.408f, 10.780f, 11.269f, 11.415f, + 11.963f, 12.873f, 14.138f, 15.454f, 18.007f, 21.113f, 23.484f, 24.835f, 27.057f, + 27.690f, 27.793f, 27.381f, 26.845f, 26.021f, 24.778f, 23.990f, 23.632f, 23.308f, + 22.505f, 21.833f, 21.980f, 20.203f, 19.686f, 18.432f, 17.540f, 16.350f, 16.902f, + 17.168f, 16.994f, 17.204f, 18.688f, 18.521f, 18.324f, 18.400f, 18.391f, 17.986f, + 18.107f, 17.922f, 17.342f, 16.117f, 16.005f, 15.288f, 14.773f, 14.688f, 14.167f, + 13.610f, 13.336f, 13.328f, 13.297f, 12.899f, 13.328f, 12.289f, 12.107f, 12.745f, + 14.081f, 15.169f, 16.130f, 16.750f, 16.570f, 17.661f, 17.673f, 17.512f, 17.663f, + 17.740f, 17.714f, 17.827f, 18.087f, 19.901f, 25.172f, 27.542f, 27.753f, 27.642f, + 27.091f, 26.407f, 26.048f, 26.792f, 26.814f, 26.595f, 28.228f, 28.712f, 28.668f, + 27.316f, 27.022f, 26.556f, 26.989f, 25.237f, 25.428f, 26.297f, 28.160f, 30.349f, + 31.933f, 34.081f, 37.812f, 41.367f, 45.506f, 48.180f, 51.696f, 51.448f, 49.912f, + 47.540f, 50.842f, 51.202f, 53.306f, 52.386f, 53.679f, 54.027f, 51.426f, 46.928f, + 46.617f, 49.390f, 49.315f, 49.590f, 50.445f, 50.182f, 50.644f, 51.868f, 52.806f, + 52.610f, 53.029f, 52.204f, 52.302f, 50.256f, 52.465f, 52.911f, 50.656f, 50.047f, + 51.446f, 51.761f, 52.046f, 51.661f, 50.914f, 50.823f, 49.899f, 50.816f, 52.457f, + 51.944f, 49.542f, 47.246f, 45.108f, 42.212f, 40.953f, 38.726f, 35.655f, 33.672f, + 30.541f, 29.252f, 28.978f, 27.242f, 24.737f, 22.468f, 20.163f, 17.716f, 15.466f, + 13.606f}, + {-29.534f, -27.897f, -25.051f, -22.039f, -18.132f, -15.799f, -14.259f, -12.311f, -10.615f, + -9.776f, -7.307f, -4.563f, -1.162f, 2.456f, 6.845f, 11.005f, 12.659f, 12.348f, + 12.822f, 11.334f, 10.719f, 9.190f, 9.986f, 10.640f, 11.222f, 11.730f, 12.053f, + 12.288f, 13.087f, 14.067f, 15.566f, 17.915f, 21.003f, 23.067f, 24.515f, 27.469f, + 27.705f, 27.557f, 26.961f, 26.592f, 25.752f, 24.448f, 23.671f, 23.177f, 22.689f, + 21.777f, 22.689f, 20.852f, 19.774f, 18.740f, 17.917f, 17.035f, 15.888f, 16.407f, + 16.676f, 17.153f, 18.053f, 18.819f, 19.237f, 18.961f, 19.111f, 19.130f, 19.094f, + 18.884f, 18.540f, 18.205f, 16.712f, 16.768f, 15.902f, 15.620f, 15.415f, 15.247f, + 14.673f, 14.044f, 13.668f, 13.510f, 13.031f, 12.467f, 11.796f, 11.577f, 12.627f, + 13.817f, 15.207f, 16.133f, 17.126f, 17.037f, 18.047f, 17.951f, 17.838f, 17.630f, + 17.469f, 17.585f, 17.001f, 17.601f, 20.252f, 24.441f, 27.162f, 28.002f, 27.156f, + 25.697f, 25.278f, 25.413f, 26.059f, 26.062f, 25.264f, 25.640f, 28.147f, 28.075f, + 28.631f, 28.157f, 28.540f, 28.908f, 27.284f, 26.694f, 26.311f, 27.385f, 28.410f, + 29.836f, 31.431f, 36.354f, 38.972f, 43.343f, 47.114f, 49.614f, 51.025f, 49.938f, + 47.663f, 49.950f, 51.740f, 52.668f, 52.723f, 52.940f, 51.708f, 50.233f, 48.663f, + 47.560f, 48.342f, 48.517f, 48.888f, 49.067f, 48.049f, 48.106f, 49.163f, 50.801f, + 51.154f, 50.926f, 49.989f, 50.065f, 49.024f, 50.518f, 50.981f, 51.020f, 49.287f, + 50.315f, 51.386f, 51.542f, 51.267f, 50.641f, 50.215f, 49.210f, 50.298f, 51.798f, + 51.599f, 49.227f, 47.207f, 44.677f, 42.277f, 41.153f, 38.423f, 35.351f, 33.545f, + 30.908f, 29.877f, 28.811f, 27.321f, 24.863f, 22.543f, 20.150f, 17.686f, 15.462f, + 13.606f}, + {-29.534f, -27.888f, -24.975f, -22.013f, -18.140f, -15.637f, -14.450f, -12.489f, -10.677f, + -9.516f, -7.143f, -4.597f, -1.353f, 2.121f, 6.408f, 10.464f, 11.750f, 12.582f, + 12.407f, 12.616f, 12.857f, 10.021f, 10.154f, 10.646f, 11.833f, 12.456f, 12.724f, + 12.886f, 13.213f, 14.150f, 15.272f, 17.879f, 20.764f, 22.963f, 24.603f, 27.003f, + 27.587f, 27.312f, 26.803f, 26.526f, 25.291f, 24.096f, 23.523f, 22.860f, 22.752f, + 21.480f, 22.172f, 18.988f, 19.650f, 17.750f, 17.522f, 16.845f, 16.386f, 16.183f, + 17.003f, 17.802f, 18.774f, 19.157f, 19.414f, 20.208f, 20.392f, 20.320f, 19.995f, + 19.687f, 19.195f, 19.094f, 17.727f, 17.493f, 16.872f, 16.112f, 16.132f, 15.979f, + 15.094f, 14.507f, 13.875f, 13.380f, 12.826f, 12.117f, 11.241f, 11.934f, 12.519f, + 12.857f, 14.591f, 16.103f, 17.129f, 17.396f, 18.050f, 18.272f, 18.391f, 17.622f, + 17.305f, 17.384f, 16.676f, 17.044f, 18.966f, 22.479f, 26.936f, 26.761f, 26.042f, + 24.794f, 24.105f, 24.333f, 25.136f, 26.068f, 24.616f, 24.020f, 26.847f, 27.605f, + 28.812f, 29.965f, 30.065f, 29.214f, 28.555f, 27.388f, 27.796f, 27.299f, 26.763f, + 27.335f, 29.782f, 33.521f, 37.537f, 41.763f, 44.136f, 48.303f, 50.145f, 50.431f, + 46.838f, 46.726f, 50.401f, 51.817f, 52.456f, 51.249f, 50.245f, 51.390f, 48.555f, + 47.214f, 47.805f, 48.125f, 48.277f, 48.255f, 46.171f, 46.144f, 47.757f, 48.543f, + 48.096f, 48.258f, 48.075f, 48.496f, 48.596f, 48.469f, 49.185f, 50.555f, 49.938f, + 49.639f, 50.646f, 51.296f, 50.668f, 50.105f, 49.348f, 48.775f, 49.634f, 50.929f, + 51.099f, 48.981f, 47.136f, 44.066f, 42.825f, 41.472f, 38.405f, 35.629f, 33.647f, + 31.629f, 30.516f, 28.632f, 27.390f, 24.982f, 22.610f, 20.145f, 17.658f, 15.457f, + 13.606f}, + {-29.534f, -27.880f, -24.897f, -21.973f, -18.154f, -15.493f, -14.636f, -12.657f, -10.648f, + -9.301f, -7.084f, -4.850f, -2.015f, 1.642f, 5.903f, 9.258f, 10.905f, 13.100f, + 12.465f, 13.448f, 14.464f, 10.528f, 10.660f, 10.931f, 12.894f, 13.775f, 13.406f, + 13.503f, 13.701f, 14.329f, 15.132f, 17.828f, 20.762f, 22.627f, 24.433f, 27.098f, + 27.238f, 27.168f, 26.391f, 26.405f, 25.022f, 23.761f, 23.319f, 22.775f, 22.479f, + 21.243f, 20.774f, 18.793f, 23.573f, 17.031f, 17.474f, 16.804f, 16.597f, 16.734f, + 16.967f, 17.767f, 18.370f, 20.028f, 20.044f, 20.940f, 21.409f, 21.247f, 20.852f, + 20.564f, 20.098f, 19.847f, 18.959f, 18.146f, 17.336f, 16.808f, 16.339f, 16.371f, + 15.504f, 14.713f, 14.061f, 13.421f, 12.683f, 11.942f, 11.145f, 11.092f, 11.477f, + 11.602f, 13.059f, 15.223f, 16.411f, 16.838f, 17.664f, 18.217f, 18.196f, 17.846f, + 17.162f, 16.992f, 16.895f, 16.616f, 17.673f, 20.453f, 25.912f, 26.234f, 25.914f, + 24.272f, 23.262f, 23.412f, 24.155f, 25.095f, 23.751f, 22.245f, 24.140f, 27.104f, + 28.980f, 30.837f, 31.445f, 30.261f, 30.432f, 29.865f, 29.163f, 27.348f, 25.617f, + 25.845f, 28.325f, 30.965f, 35.389f, 39.102f, 41.083f, 45.020f, 48.293f, 49.580f, + 47.460f, 46.235f, 49.156f, 49.913f, 51.091f, 50.314f, 49.985f, 52.108f, 48.706f, + 47.140f, 48.169f, 47.587f, 47.370f, 47.048f, 45.038f, 45.301f, 46.300f, 46.367f, + 45.821f, 46.184f, 46.676f, 47.262f, 47.762f, 46.927f, 48.227f, 49.454f, 50.172f, + 49.071f, 49.781f, 50.804f, 50.320f, 48.953f, 48.675f, 48.539f, 48.836f, 50.053f, + 50.553f, 48.925f, 46.724f, 43.723f, 43.370f, 41.560f, 38.495f, 36.215f, 33.895f, + 32.344f, 30.978f, 28.477f, 27.419f, 25.076f, 22.659f, 20.147f, 17.632f, 15.452f, + 13.606f}}; diff --git a/src/gis.c b/src/gis.c index 8ce1d87eb..077a3cff8 100644 --- a/src/gis.c +++ b/src/gis.c @@ -1,381 +1,360 @@ /*------------------------------------------------------------------------------ -* gis.c: GIS data functions -* -* Copyright (C) 2016 by T.TAKASU, All rights reserved. -* -* references: -* [1] ESRI Shapefile Technical Description, An ESRI White Paper, July, 1998 -* -* version : $Revision:$ $Date:$ -* history : 2016/06/10 1.0 new -* 2016/07/31 1.1 add boundary of polyline and polygon -*-----------------------------------------------------------------------------*/ + * gis.c: GIS data functions + * + * Copyright (C) 2016 by T.TAKASU, All rights reserved. + * + * references: + * [1] ESRI Shapefile Technical Description, An ESRI White Paper, July, 1998 + * + * version : $Revision:$ $Date:$ + * history : 2016/06/10 1.0 new + * 2016/07/31 1.1 add boundary of polyline and polygon + *-----------------------------------------------------------------------------*/ #include "rtklib.h" -#define SHAPE_CODE 9994 /* shapefile code */ +#define SHAPE_CODE 9994 /* shapefile code */ /* get integer big-endian ----------------------------------------------------*/ -static int I4_B(uint8_t *buff) -{ - int i,val=0; - uint8_t *p=buff,*q=(uint8_t *)&val+3; - - for (i=0;i<4;i++) { - *q--=*p++; - } - return val; +static int I4_B(uint8_t *buff) { + int i, val = 0; + uint8_t *p = buff, *q = (uint8_t *)&val + 3; + + for (i = 0; i < 4; i++) { + *q-- = *p++; + } + return val; } /* get integer little-endian -------------------------------------------------*/ -static int I4_L(uint8_t *buff) -{ - int val; - - memcpy(&val,buff,4); - return val; +static int I4_L(uint8_t *buff) { + int val; + + memcpy(&val, buff, 4); + return val; } /* get double little-endian --------------------------------------------------*/ -static double D8_L(uint8_t *buff) -{ - double val; - - memcpy(&val,buff,8); - return val; +static double D8_L(uint8_t *buff) { + double val; + + memcpy(&val, buff, 8); + return val; } /* read shapefile header -----------------------------------------------------*/ -static int read_shape_head(FILE *fp) -{ - uint8_t buff[128]; - - if (fread(buff,100,1,fp)!=1) { - return -1; - } - if (I4_B(buff)!=SHAPE_CODE) { - return -1; - } - return I4_L(buff+32); +static int read_shape_head(FILE *fp) { + uint8_t buff[128]; + + if (fread(buff, 100, 1, fp) != 1) { + return -1; + } + if (I4_B(buff) != SHAPE_CODE) { + return -1; + } + return I4_L(buff + 32); } /* initialize boundary -------------------------------------------------------*/ -static void init_bound(double *bound) -{ - bound[0]= PI/2.0; - bound[1]=-PI/2.0; - bound[2]= PI; - bound[3]=-PI; +static void init_bound(double *bound) { + bound[0] = PI / 2.0; + bound[1] = -PI / 2.0; + bound[2] = PI; + bound[3] = -PI; } /* update boundary -----------------------------------------------------------*/ -static void update_bound(const double *pos, double *bound) -{ - if (pos[0]bound[1]) bound[1]=pos[0]; - if (pos[1]bound[3]) bound[3]=pos[1]; +static void update_bound(const double *pos, double *bound) { + if (pos[0] < bound[0]) bound[0] = pos[0]; + if (pos[0] > bound[1]) bound[1] = pos[0]; + if (pos[1] < bound[2]) bound[2] = pos[1]; + if (pos[1] > bound[3]) bound[3] = pos[1]; } /* add gis data --------------------------------------------------------------*/ -static int gis_add(gisd_t **p, int type, void *data) -{ - gisd_t *new_data; - - if (!(new_data=(gisd_t *)malloc(sizeof(gisd_t)))) { - return 0; - } - new_data->next=*p; - new_data->type=type; - new_data->data=data; - *p=new_data; - return 1; +static int gis_add(gisd_t **p, int type, void *data) { + gisd_t *new_data; + + if (!(new_data = (gisd_t *)malloc(sizeof(gisd_t)))) { + return 0; + } + new_data->next = *p; + new_data->type = type; + new_data->data = data; + *p = new_data; + return 1; } /* read point data -----------------------------------------------------------*/ -static int read_pnt(FILE *fp, double *bound, gisd_t **p) -{ - gis_pnt_t *pnt; - double pos[3]={0}; - uint8_t buff[16]; - - if (fread(buff,16,1,fp)!=1) { - return 0; - } - if (!(pnt=(gis_pnt_t *)malloc(sizeof(gis_pnt_t)))) { - return 0; - } - pos[0]=D8_L(buff+8)*D2R; - pos[1]=D8_L(buff )*D2R; - update_bound(pos,bound); - pos2ecef(pos,pnt->pos); - - return gis_add(p,1,pnt); +static int read_pnt(FILE *fp, double *bound, gisd_t **p) { + gis_pnt_t *pnt; + double pos[3] = {0}; + uint8_t buff[16]; + + if (fread(buff, 16, 1, fp) != 1) { + return 0; + } + if (!(pnt = (gis_pnt_t *)malloc(sizeof(gis_pnt_t)))) { + return 0; + } + pos[0] = D8_L(buff + 8) * D2R; + pos[1] = D8_L(buff) * D2R; + update_bound(pos, bound); + pos2ecef(pos, pnt->pos); + + return gis_add(p, 1, pnt); } /* read multi-point data ------------------------------------------------------*/ -static int read_mpnt(FILE *fp, double *bound, gisd_t **p) -{ - uint8_t buff[36]; - int i,np; - - if (fread(buff,36,1,fp)!=1) { - return 0; - } - np=I4_L(buff+32); - - for (i=0;ipos = (double *)malloc(sizeof(double) * nr * 3))) { + free(poly); + free(part); + return 0; } - for (i=0;ibound); + + for (j = n = 0; j < nr; j++) { + if (fread(buff, 16, 1, fp) != 1) { + free(poly->pos); + free(poly); + free(part); + return 0; + } + pos[0] = D8_L(buff + 8) * D2R; + pos[1] = D8_L(buff) * D2R; + if (pos[0] < -1E16 || pos[1] < -1E16) { + continue; + } + update_bound(pos, poly->bound); + update_bound(pos, bound); + pos2ecef(pos, poly->pos + n * 3); + n++; } - for (i=0;ipos=(double *)malloc(sizeof(double)*nr*3))) { - free(poly); - free(part); - return 0; - } - init_bound(poly->bound); - - for (j=n=0;jpos); - free(poly); - free(part); - return 0; - } - pos[0]=D8_L(buff+8)*D2R; - pos[1]=D8_L(buff )*D2R; - if (pos[0]<-1E16||pos[1]<-1E16) { - continue; - } - update_bound(pos,poly->bound); - update_bound(pos,bound); - pos2ecef(pos,poly->pos+n*3); - n++; - } - poly->npnt=n; - if (!gis_add(p,2,(void *)poly)) { - free(poly->pos); - free(poly); - free(part); - return 0; - } + poly->npnt = n; + if (!gis_add(p, 2, (void *)poly)) { + free(poly->pos); + free(poly); + free(part); + return 0; } - free(part); - return 1; + } + free(part); + return 1; } /* read polygon data ---------------------------------------------------------*/ -static int read_polygon(FILE *fp, double *bound, gisd_t **p) -{ - gis_polygon_t *polygon; - double pos[3]={0}; - uint8_t buff[40]; - int i,j,nt,np,nr,n,*part; - - if (fread(buff,40,1,fp)!=1) { - return 0; +static int read_polygon(FILE *fp, double *bound, gisd_t **p) { + gis_polygon_t *polygon; + double pos[3] = {0}; + uint8_t buff[40]; + int i, j, nt, np, nr, n, *part; + + if (fread(buff, 40, 1, fp) != 1) { + return 0; + } + nt = I4_L(buff + 32); + np = I4_L(buff + 36); + + if (!(part = (int *)malloc(sizeof(int) * nt))) { + return 0; + } + for (i = 0; i < nt; i++) { + fread(buff, 4, 1, fp); + part[i] = I4_L(buff); + } + for (i = 0; i < nt; i++) { + nr = (i < nt - 1 ? part[i + 1] : np) - part[i]; + + if (!(polygon = (gis_polygon_t *)malloc(sizeof(gis_polygon_t)))) { + free(part); + return 0; } - nt=I4_L(buff+32); - np=I4_L(buff+36); - - if (!(part=(int *)malloc(sizeof(int)*nt))) { - return 0; + if (!(polygon->pos = (double *)malloc(sizeof(double) * nr * 3))) { + free(polygon); + free(part); + return 0; } - for (i=0;ibound); + + for (j = n = 0; j < nr; j++) { + if (fread(buff, 16, 1, fp) != 1) { + free(polygon->pos); + free(polygon); + free(part); + return 0; + } + pos[0] = D8_L(buff + 8) * D2R; + pos[1] = D8_L(buff) * D2R; + if (pos[0] < -1E16 || pos[1] < -1E16) { + continue; + } + update_bound(pos, polygon->bound); + update_bound(pos, bound); + pos2ecef(pos, polygon->pos + n * 3); + n++; } - for (i=0;ipos=(double *)malloc(sizeof(double)*nr*3))) { - free(polygon); - free(part); - return 0; - } - init_bound(polygon->bound); - - for (j=n=0;jpos); - free(polygon); - free(part); - return 0; - } - pos[0]=D8_L(buff+8)*D2R; - pos[1]=D8_L(buff )*D2R; - if (pos[0]<-1E16||pos[1]<-1E16) { - continue; - } - update_bound(pos,polygon->bound); - update_bound(pos,bound); - pos2ecef(pos,polygon->pos+n*3); - n++; - } - polygon->npnt=n; - if (!gis_add(p,3,(void *)polygon)) { - free(polygon->pos); - free(polygon); - free(part); - return 0; - } + polygon->npnt = n; + if (!gis_add(p, 3, (void *)polygon)) { + free(polygon->pos); + free(polygon); + free(part); + return 0; } - free(part); - return 1; + } + free(part); + return 1; } /* read shapefile records ----------------------------------------------------*/ -static int gis_read_record(FILE *fp, FILE *fp_idx, int type, double *bound, - gisd_t **data) -{ - gisd_t *p,*next; - uint8_t buff[16]; - int i,off,num,len1,len2,typ2; - - for (i=0;fread(buff,1,8,fp_idx)==8;i++) { - off =I4_B(buff )*2; - len1=I4_B(buff+4)*2; - - if (fseek(fp,(long)off,SEEK_SET)<0||fread(buff,12,1,fp)!=1) { - return 0; - } - num =I4_B(buff ); - len2=I4_B(buff+4)*2; - typ2=I4_L(buff+8); - - if (num!=i+1||len1!=len2||type!=typ2) { - trace(2,"shapefile record error n=%d %d len=%d %d type=%d %d\n", - i+1,num,len1,len2,type,typ2); - continue; - } - if (type==1) { /* point */ - read_pnt(fp,bound,data); - } - else if (type==8) { /* multi-point */ - read_mpnt(fp,bound,data); - } - else if (type==3) { /* polyline */ - read_poly(fp,bound,data); - } - else if (type==5) { /* polygon */ - read_polygon(fp,bound,data); - } - else { /* skip record */ - for (int j=0;jnext; - p->next=*data; - *data=p; + if (type == 1) { /* point */ + read_pnt(fp, bound, data); + } else if (type == 8) { /* multi-point */ + read_mpnt(fp, bound, data); + } else if (type == 3) { /* polyline */ + read_poly(fp, bound, data); + } else if (type == 5) { /* polygon */ + read_polygon(fp, bound, data); + } else { /* skip record */ + for (int j = 0; j < len1 - 4; j++) { + fread(buff, 1, 1, fp); + } } - return 1; + } + /* reverse list order */ + for (p = *data, *data = NULL; p; p = next) { + next = p->next; + p->next = *data; + *data = p; + } + return 1; } /* read gis data from shapefile ------------------------------------------------ -* read gis data from shapefile (ref [1]) -* args : char *file I shapefile -* gis_t *gis IO GIS data -* return : status (0:error) -* notes : only support point, multipoint, polyline and polygon. -* only support lat-lon for map projection. -*-----------------------------------------------------------------------------*/ -extern int gis_read(const char *file, gis_t *gis, int layer) -{ - FILE *fp,*fp_idx; - char path[1024],*p; - int type1=0,type2=0; - - trace(3,"gis_read file=%s layer=%d\n",file,layer); - - strcpy(path,file); - - if ((p=strrchr(path,'.'))) { - sprintf(p,".shx"); - } - else { - sprintf(path+strlen(path),".shx"); - } - if (!(fp=fopen(file,"rb"))) { /* shapefile */ - trace(2,"shapefile open error: %s\n",file); - return 0; - } - if (!(fp_idx=fopen(path,"rb"))) { /* index file */ - fclose(fp); - trace(2,"shapefile index open error: %s\n",path); - return 0; - } - /* read header */ - if ((type1=read_shape_head(fp))<0||(type2=read_shape_head(fp_idx))<0|| - type1!=type2) { - trace(2,"shapefile header error: %s type=%d %d\n",file,type1,type2); - fclose(fp); - fclose(fp_idx); - return 0; - } - init_bound(gis->bound); - - /* read records */ - if (!gis_read_record(fp,fp_idx,type1,gis->bound,gis->data+layer)) { - fclose(fp); - fclose(fp_idx); - return 0; - } + * read gis data from shapefile (ref [1]) + * args : char *file I shapefile + * gis_t *gis IO GIS data + * return : status (0:error) + * notes : only support point, multipoint, polyline and polygon. + * only support lat-lon for map projection. + *-----------------------------------------------------------------------------*/ +extern int gis_read(const char *file, gis_t *gis, int layer) { + FILE *fp, *fp_idx; + char path[1024], *p; + int type1 = 0, type2 = 0; + + trace(3, "gis_read file=%s layer=%d\n", file, layer); + + strcpy(path, file); + + if ((p = strrchr(path, '.'))) { + sprintf(p, ".shx"); + } else { + sprintf(path + strlen(path), ".shx"); + } + if (!(fp = fopen(file, "rb"))) { /* shapefile */ + trace(2, "shapefile open error: %s\n", file); + return 0; + } + if (!(fp_idx = fopen(path, "rb"))) { /* index file */ + fclose(fp); + trace(2, "shapefile index open error: %s\n", path); + return 0; + } + /* read header */ + if ((type1 = read_shape_head(fp)) < 0 || (type2 = read_shape_head(fp_idx)) < 0 || + type1 != type2) { + trace(2, "shapefile header error: %s type=%d %d\n", file, type1, type2); fclose(fp); fclose(fp_idx); - gis->name[layer][0]='\0'; - gis->flag[layer]=1; - return 1; + return 0; + } + init_bound(gis->bound); + + /* read records */ + if (!gis_read_record(fp, fp_idx, type1, gis->bound, gis->data + layer)) { + fclose(fp); + fclose(fp_idx); + return 0; + } + fclose(fp); + fclose(fp_idx); + gis->name[layer][0] = '\0'; + gis->flag[layer] = 1; + return 1; } /* free gis-data --------------------------------------------------------------- -* free and initialize gis data -* args : gis_t *gis IO gis data -* return : none -*-----------------------------------------------------------------------------*/ -extern void gis_free(gis_t *gis) -{ - gisd_t *data,*next; - int i; - - for (i=0;idata[i];data;data=next) { - next=data->next; - if (data->type==2) { - free(((gis_poly_t *)data->data)->pos); - } - else if (data->type==3) { - free(((gis_polygon_t *)data->data)->pos); - } - free(data); - } - gis->data[i]=NULL; - gis->name[i][0]='\0'; - gis->flag[i]=0; + * free and initialize gis data + * args : gis_t *gis IO gis data + * return : none + *-----------------------------------------------------------------------------*/ +extern void gis_free(gis_t *gis) { + gisd_t *data, *next; + int i; + + for (i = 0; i < MAXGISLAYER; i++) { + for (data = gis->data[i]; data; data = next) { + next = data->next; + if (data->type == 2) { + free(((gis_poly_t *)data->data)->pos); + } else if (data->type == 3) { + free(((gis_polygon_t *)data->data)->pos); + } + free(data); } + gis->data[i] = NULL; + gis->name[i][0] = '\0'; + gis->flag[i] = 0; + } } diff --git a/src/ionex.c b/src/ionex.c index d4cd62385..f4759d80f 100644 --- a/src/ionex.c +++ b/src/ionex.c @@ -1,484 +1,477 @@ /*------------------------------------------------------------------------------ -* ionex.c : ionex functions -* -* Copyright (C) 2011-2013 by T.TAKASU, All rights reserved. -* -* references: -* [1] S.Schear, W.Gurtner and J.Feltens, IONEX: The IONosphere Map EXchange -* Format Version 1, February 25, 1998 -* [2] S.Schaer, R.Markus, B.Gerhard and A.S.Timon, Daily Global Ionosphere -* Maps based on GPS Carrier Phase Data Routinely produced by CODE -* Analysis Center, Proceeding of the IGS Analysis Center Workshop, 1996 -* -* version : $Revision:$ $Date:$ -* history : 2011/03/29 1.0 new -* 2013/03/05 1.1 change api readtec() -* fix problem in case of lat>85deg or lat<-85deg -* 2014/02/22 1.2 fix problem on compiled as C++ -*-----------------------------------------------------------------------------*/ + * ionex.c : ionex functions + * + * Copyright (C) 2011-2013 by T.TAKASU, All rights reserved. + * + * references: + * [1] S.Schear, W.Gurtner and J.Feltens, IONEX: The IONosphere Map EXchange + * Format Version 1, February 25, 1998 + * [2] S.Schaer, R.Markus, B.Gerhard and A.S.Timon, Daily Global Ionosphere + * Maps based on GPS Carrier Phase Data Routinely produced by CODE + * Analysis Center, Proceeding of the IGS Analysis Center Workshop, 1996 + * + * version : $Revision:$ $Date:$ + * history : 2011/03/29 1.0 new + * 2013/03/05 1.1 change api readtec() + * fix problem in case of lat>85deg or lat<-85deg + * 2014/02/22 1.2 fix problem on compiled as C++ + *-----------------------------------------------------------------------------*/ #include "rtklib.h" -#define SQR(x) ((x)*(x)) -#define VAR_NOTEC SQR(30.0) /* variance of no tec */ -#define MIN_EL 0.0 /* min elevation angle (rad) */ -#define MIN_HGT -1000.0 /* min user height (m) */ +#define SQR(x) ((x) * (x)) +#define VAR_NOTEC SQR(30.0) /* variance of no tec */ +#define MIN_EL 0.0 /* min elevation angle (rad) */ +#define MIN_HGT -1000.0 /* min user height (m) */ /* get index -----------------------------------------------------------------*/ -static int getindex(double value, const double *range) -{ - if (range[2]==0.0) return 0; - if (range[1]>0.0&&(value 0.0 && (value < range[0] || range[1] < value)) return -1; + if (range[1] < 0.0 && (value < range[1] || range[0] < value)) return -1; + return (int)floor((value - range[0]) / range[2] + 0.5); } /* get number of items -------------------------------------------------------*/ -static int nitem(const double *range) -{ - return getindex(range[1],range)+1; -} +static int nitem(const double *range) { return getindex(range[1], range) + 1; } /* data index (i:lat,j:lon,k:hgt) --------------------------------------------*/ -static int dataindex(int i, int j, int k, const int *ndata) -{ - if (i<0||ndata[0]<=i||j<0||ndata[1]<=j||k<0||ndata[2]<=k) return -1; - return i+ndata[0]*(j+ndata[1]*k); +static int dataindex(int i, int j, int k, const int *ndata) { + if (i < 0 || ndata[0] <= i || j < 0 || ndata[1] <= j || k < 0 || ndata[2] <= k) return -1; + return i + ndata[0] * (j + ndata[1] * k); } /* add tec data to navigation data -------------------------------------------*/ -static tec_t *addtec(const double *lats, const double *lons, const double *hgts, - double rb, nav_t *nav) -{ - tec_t *p,*nav_tec; - gtime_t time0={0}; - int i,n,ndata[3],indx; - - trace(3,"addtec :\n"); - - ndata[0]=nitem(lats); - ndata[1]=nitem(lons); - ndata[2]=nitem(hgts); - if (ndata[0] > 1 && ndata[1] > 1 && ndata[2] > 0) - { - if (nav->nt >= nav->ntmax) { - nav->ntmax += 256; - if (!(nav_tec = (tec_t*)realloc(nav->tec, sizeof(tec_t) * nav->ntmax))) { - trace(1, "readionex malloc error ntmax=%d\n", nav->ntmax); - free(nav->tec); nav->tec = NULL; nav->nt = nav->ntmax = 0; - return NULL; - } - for (indx = nav->ntmax - 1; indx >= nav->ntmax - 256; indx--) - memset(&nav_tec[indx], 0, sizeof(tec_t)); - nav->tec = nav_tec; - } - p = nav->tec + nav->nt; - p->time = time0; - p->rb = rb; - for (i = 0; i < 3; i++) { - p->ndata[i] = ndata[i]; - p->lats[i] = lats[i]; - p->lons[i] = lons[i]; - p->hgts[i] = hgts[i]; - } - n = ndata[0] * ndata[1] * ndata[2]; +static tec_t *addtec(const double *lats, const double *lons, const double *hgts, double rb, + nav_t *nav) { + tec_t *p, *nav_tec; + gtime_t time0 = {0}; + int i, n, ndata[3], indx; - if (!(p->data = (double*)malloc(sizeof(double) * n)) || - !(p->rms = (float*)malloc(sizeof(float) * n))) { - return NULL; - } - for (i = 0; i < n; i++) { - /* Thanks to 'if (ndata[0]>1 && ndata[1]>1 && ndata[2]>0)' we know analysis is wrong - disable 6386 */ - p->data[i] = 0.0; - p->rms[i] = 0.0f; - } - nav->nt++; - return p; - } - else + trace(3, "addtec :\n"); + + ndata[0] = nitem(lats); + ndata[1] = nitem(lons); + ndata[2] = nitem(hgts); + if (ndata[0] > 1 && ndata[1] > 1 && ndata[2] > 0) { + if (nav->nt >= nav->ntmax) { + nav->ntmax += 256; + if (!(nav_tec = (tec_t *)realloc(nav->tec, sizeof(tec_t) * nav->ntmax))) { + trace(1, "readionex malloc error ntmax=%d\n", nav->ntmax); + free(nav->tec); + nav->tec = NULL; + nav->nt = nav->ntmax = 0; return NULL; + } + for (indx = nav->ntmax - 1; indx >= nav->ntmax - 256; indx--) + memset(&nav_tec[indx], 0, sizeof(tec_t)); + nav->tec = nav_tec; + } + p = nav->tec + nav->nt; + p->time = time0; + p->rb = rb; + for (i = 0; i < 3; i++) { + p->ndata[i] = ndata[i]; + p->lats[i] = lats[i]; + p->lons[i] = lons[i]; + p->hgts[i] = hgts[i]; + } + n = ndata[0] * ndata[1] * ndata[2]; + + if (!(p->data = (double *)malloc(sizeof(double) * n)) || + !(p->rms = (float *)malloc(sizeof(float) * n))) { + return NULL; + } + for (i = 0; i < n; i++) { + /* Thanks to 'if (ndata[0]>1 && ndata[1]>1 && ndata[2]>0)' we know analysis is wrong - disable + * 6386 */ + p->data[i] = 0.0; + p->rms[i] = 0.0f; + } + nav->nt++; + return p; + } else + return NULL; } /* read ionex dcb aux data ----------------------------------------------------*/ -static void readionexdcb(FILE *fp, double *dcb, double *rms) -{ - int i,sat; - char buff[1024],id[8],*label; - - trace(3,"readionexdcb:\n"); - - for (i=0;int-1;i>=0;i--) { - if (fabs(timediff(time,nav->tec[i].time))>=1.0) continue; - p=nav->tec+i; - break; - } - } - else if (p) p->time=time; - } - else if (strstr(label,"LAT/LON1/LON2/DLON/H")==label&&p) { - lat =str2num(buff, 2,6); - lon[0]=str2num(buff, 8,6); - lon[1]=str2num(buff,14,6); - lon[2]=str2num(buff,20,6); - hgt =str2num(buff,26,6); - - i=getindex(lat,p->lats); - k=getindex(hgt,p->hgts); - n=nitem(lon); - - for (m=0;mlons); - if ((index=dataindex(i,j,k,p->ndata))<0) continue; - - if ((x=str2num(buff,m%16*5,5))==9999.0) continue; - - if (type==1) p->data[index]=x*pow(10.0,nexp); - else p->rms[index]=(float)(x*pow(10.0,nexp)); - } +static int readionexb(FILE *fp, const double *lats, const double *lons, const double *hgts, + double rb, double nexp, nav_t *nav) { + tec_t *p = NULL; + gtime_t time = {0}; + double lat, lon[3], hgt, x; + int i, j, k, n, m, index, type = 0; + char buff[1024], *label = buff + 60; + + trace(3, "readionexb:\n"); + + while (fgets(buff, sizeof(buff), fp)) { + if (strlen(buff) < 60) continue; + + if (strstr(label, "START OF TEC MAP") == label) { + if ((p = addtec(lats, lons, hgts, rb, nav))) type = 1; + } else if (strstr(label, "END OF TEC MAP") == label) { + type = 0; + p = NULL; + } else if (strstr(label, "START OF RMS MAP") == label) { + type = 2; + p = NULL; + } else if (strstr(label, "END OF RMS MAP") == label) { + type = 0; + p = NULL; + } else if (strstr(label, "EPOCH OF CURRENT MAP") == label) { + if (str2time(buff, 0, 36, &time)) { + trace(2, "ionex epoch invalid: %-36.36s\n", buff); + continue; + } + if (type == 2) { + for (i = nav->nt - 1; i >= 0; i--) { + if (fabs(timediff(time, nav->tec[i].time)) >= 1.0) continue; + p = nav->tec + i; + break; } + } else if (p) + p->time = time; + } else if (strstr(label, "LAT/LON1/LON2/DLON/H") == label && p) { + lat = str2num(buff, 2, 6); + lon[0] = str2num(buff, 8, 6); + lon[1] = str2num(buff, 14, 6); + lon[2] = str2num(buff, 20, 6); + hgt = str2num(buff, 26, 6); + + i = getindex(lat, p->lats); + k = getindex(hgt, p->hgts); + n = nitem(lon); + + for (m = 0; m < n; m++) { + if (m % 16 == 0 && !fgets(buff, sizeof(buff), fp)) break; + + j = getindex(lon[0] + lon[2] * m, p->lons); + if ((index = dataindex(i, j, k, p->ndata)) < 0) continue; + + if ((x = str2num(buff, m % 16 * 5, 5)) == 9999.0) continue; + + if (type == 1) + p->data[index] = x * pow(10.0, nexp); + else + p->rms[index] = (float)(x * pow(10.0, nexp)); + } } - return 1; + } + return 1; } /* combine tec grid data -----------------------------------------------------*/ -static void combtec(nav_t *nav) -{ - tec_t tmp; - int i,j,n=0; - - trace(3,"combtec : nav->nt=%d\n",nav->nt); - - for (i=0;int-1;i++) { - for (j=i+1;jnt;j++) { - if (timediff(nav->tec[j].time,nav->tec[i].time)<0.0) { - tmp=nav->tec[i]; - nav->tec[i]=nav->tec[j]; - nav->tec[j]=tmp; - } - } +static void combtec(nav_t *nav) { + tec_t tmp; + int i, j, n = 0; + + trace(3, "combtec : nav->nt=%d\n", nav->nt); + + for (i = 0; i < nav->nt - 1; i++) { + for (j = i + 1; j < nav->nt; j++) { + if (timediff(nav->tec[j].time, nav->tec[i].time) < 0.0) { + tmp = nav->tec[i]; + nav->tec[i] = nav->tec[j]; + nav->tec[j] = tmp; + } } - for (i=0;int;i++) { - if (i>0&&timediff(nav->tec[i].time,nav->tec[n-1].time)==0.0) { - free(nav->tec[n-1].data); - free(nav->tec[n-1].rms ); - nav->tec[n-1]=nav->tec[i]; - continue; - } - nav->tec[n++]=nav->tec[i]; + } + for (i = 0; i < nav->nt; i++) { + if (i > 0 && timediff(nav->tec[i].time, nav->tec[n - 1].time) == 0.0) { + free(nav->tec[n - 1].data); + free(nav->tec[n - 1].rms); + nav->tec[n - 1] = nav->tec[i]; + continue; } - nav->nt=n; - - trace(4,"combtec : nav->nt=%d\n",nav->nt); + nav->tec[n++] = nav->tec[i]; + } + nav->nt = n; + + trace(4, "combtec : nav->nt=%d\n", nav->nt); } /* read ionex tec grid file ---------------------------------------------------- -* read ionex ionospheric tec grid file -* args : char *file I ionex tec grid file -* (wild-card * is expanded) -* nav_t *nav IO navigation data -* nav->nt, nav->ntmax and nav->tec are modified -* int opt I read option (1: no clear of tec data,0:clear) -* return : none -* notes : see ref [1] -*-----------------------------------------------------------------------------*/ -extern void readtec(const char *file, nav_t *nav, int opt) -{ - FILE *fp; - double dcb[MAXSAT]={0},rms[MAXSAT]={0}; - int i,n; - char *efiles[MAXEXFILE]; - - trace(3,"readtec : file=%s\n",file); - - /* clear of tec grid data option */ - if (!opt) { - free(nav->tec); nav->tec=NULL; nav->nt=nav->ntmax=0; + * read ionex ionospheric tec grid file + * args : char *file I ionex tec grid file + * (wild-card * is expanded) + * nav_t *nav IO navigation data + * nav->nt, nav->ntmax and nav->tec are modified + * int opt I read option (1: no clear of tec data,0:clear) + * return : none + * notes : see ref [1] + *-----------------------------------------------------------------------------*/ +extern void readtec(const char *file, nav_t *nav, int opt) { + FILE *fp; + double dcb[MAXSAT] = {0}, rms[MAXSAT] = {0}; + int i, n; + char *efiles[MAXEXFILE]; + + trace(3, "readtec : file=%s\n", file); + + /* clear of tec grid data option */ + if (!opt) { + free(nav->tec); + nav->tec = NULL; + nav->nt = nav->ntmax = 0; + } + for (i = 0; i < MAXEXFILE; i++) { + if (!(efiles[i] = (char *)malloc(1024))) { + for (i--; i >= 0; i--) free(efiles[i]); + return; } - for (i=0;i=0;i--) free(efiles[i]); - return; - } + } + /* expand wild card in file path */ + n = expath(file, efiles, MAXEXFILE); + + for (i = 0; i < n; i++) { + if (!(fp = fopen(efiles[i], "r"))) { + trace(2, "ionex file open error %s\n", efiles[i]); + continue; } - /* expand wild card in file path */ - n=expath(file,efiles,MAXEXFILE); - - for (i=0;int>0) combtec(nav); - - /* P1-P2 dcb (not used)*/ - /* for (i=0;icbias[i][0]=CLIGHT*dcb[i]*1E-9; */ /* ns->m */ - /* } */ + /* read ionex body */ + readionexb(fp, lats, lons, hgts, rb, nexp, nav); + + fclose(fp); + } + for (i = 0; i < MAXEXFILE; i++) free(efiles[i]); + + /* combine tec grid data */ + if (nav->nt > 0) combtec(nav); + + /* P1-P2 dcb (not used)*/ + /* for (i=0;icbias[i][0]=CLIGHT*dcb[i]*1E-9; */ /* ns->m */ + /* } */ } /* interpolate tec grid data -------------------------------------------------*/ -static int interptec(const tec_t *tec, int k, const double *posp, double *value, - double *rms) -{ - double dlat,dlon,a,b,d[4]={0},r[4]={0}; - int i,j,n,index; - - trace(3,"interptec: k=%d posp=%.2f %.2f\n",k,posp[0]*R2D,posp[1]*R2D); - *value=*rms=0.0; - - if (tec->lats[2]==0.0||tec->lons[2]==0.0) return 0; - - dlat=posp[0]*R2D-tec->lats[0]; - dlon=posp[1]*R2D-tec->lons[0]; - if (tec->lons[2]>0.0) dlon-=floor( dlon/360)*360.0; /* 0<=dlon<360 */ - else dlon+=floor(-dlon/360)*360.0; /* -360lats[2]; - b=dlon/tec->lons[2]; - i=(int)floor(a); a-=i; - j=(int)floor(b); b-=j; - - /* get gridded tec data */ - for (n=0;n<4;n++) { - if ((index=dataindex(i+(n%2),j+(n<2?0:1),k,tec->ndata))<0) continue; - d[n]=tec->data[index]; - r[n]=tec->rms [index]; - } - if (d[0]>0.0&&d[1]>0.0&&d[2]>0.0&&d[3]>0.0) { - - /* bilinear interpolation (inside of grid) */ - *value=(1.0-a)*(1.0-b)*d[0]+a*(1.0-b)*d[1]+(1.0-a)*b*d[2]+a*b*d[3]; - *rms =(1.0-a)*(1.0-b)*r[0]+a*(1.0-b)*r[1]+(1.0-a)*b*r[2]+a*b*r[3]; - } - /* nearest-neighbour extrapolation (outside of grid) */ - else if (a<=0.5&&b<=0.5&&d[0]>0.0) {*value=d[0]; *rms=r[0];} - else if (a> 0.5&&b<=0.5&&d[1]>0.0) {*value=d[1]; *rms=r[1];} - else if (a<=0.5&&b> 0.5&&d[2]>0.0) {*value=d[2]; *rms=r[2];} - else if (a> 0.5&&b> 0.5&&d[3]>0.0) {*value=d[3]; *rms=r[3];} - else { - i=0; - for (n=0;n<4;n++) if (d[n]>0.0) {i++; *value+=d[n]; *rms+=r[n];} - if(i==0) return 0; - *value/=i; *rms/=i; - } - return 1; +static int interptec(const tec_t *tec, int k, const double *posp, double *value, double *rms) { + double dlat, dlon, a, b, d[4] = {0}, r[4] = {0}; + int i, j, n, index; + + trace(3, "interptec: k=%d posp=%.2f %.2f\n", k, posp[0] * R2D, posp[1] * R2D); + *value = *rms = 0.0; + + if (tec->lats[2] == 0.0 || tec->lons[2] == 0.0) return 0; + + dlat = posp[0] * R2D - tec->lats[0]; + dlon = posp[1] * R2D - tec->lons[0]; + if (tec->lons[2] > 0.0) + dlon -= floor(dlon / 360) * 360.0; /* 0<=dlon<360 */ + else + dlon += floor(-dlon / 360) * 360.0; /* -360lats[2]; + b = dlon / tec->lons[2]; + i = (int)floor(a); + a -= i; + j = (int)floor(b); + b -= j; + + /* get gridded tec data */ + for (n = 0; n < 4; n++) { + if ((index = dataindex(i + (n % 2), j + (n < 2 ? 0 : 1), k, tec->ndata)) < 0) continue; + d[n] = tec->data[index]; + r[n] = tec->rms[index]; + } + if (d[0] > 0.0 && d[1] > 0.0 && d[2] > 0.0 && d[3] > 0.0) { + /* bilinear interpolation (inside of grid) */ + *value = + (1.0 - a) * (1.0 - b) * d[0] + a * (1.0 - b) * d[1] + (1.0 - a) * b * d[2] + a * b * d[3]; + *rms = + (1.0 - a) * (1.0 - b) * r[0] + a * (1.0 - b) * r[1] + (1.0 - a) * b * r[2] + a * b * r[3]; + } + /* nearest-neighbour extrapolation (outside of grid) */ + else if (a <= 0.5 && b <= 0.5 && d[0] > 0.0) { + *value = d[0]; + *rms = r[0]; + } else if (a > 0.5 && b <= 0.5 && d[1] > 0.0) { + *value = d[1]; + *rms = r[1]; + } else if (a <= 0.5 && b > 0.5 && d[2] > 0.0) { + *value = d[2]; + *rms = r[2]; + } else if (a > 0.5 && b > 0.5 && d[3] > 0.0) { + *value = d[3]; + *rms = r[3]; + } else { + i = 0; + for (n = 0; n < 4; n++) + if (d[n] > 0.0) { + i++; + *value += d[n]; + *rms += r[n]; + } + if (i == 0) return 0; + *value /= i; + *rms /= i; + } + return 1; } /* ionosphere delay by tec grid data -----------------------------------------*/ -static int iondelay(gtime_t time, const tec_t *tec, const double *pos, - const double *azel, int opt, double *delay, double *var) -{ - const double fact=40.30E16/FREQL1/FREQL1; /* tecu->L1 iono (m) */ - double fs,posp[3]={0},vtec,rms,hion,rp; - int i; - - char tstr[40]; - trace(3,"iondelay: time=%s pos=%.1f %.1f azel=%.1f %.1f\n",time2str(time,tstr,0), - pos[0]*R2D,pos[1]*R2D,azel[0]*R2D,azel[1]*R2D); - - *delay=*var=0.0; - - for (i=0;indata[2];i++) { /* for a layer */ - - hion=tec->hgts[0]+tec->hgts[2]*i; - - /* ionospheric pierce point position */ - fs=ionppp(pos,azel,tec->rb,hion,posp); - - if (opt&2) { - /* modified single layer mapping function (M-SLM) ref [2] */ - rp=tec->rb/(tec->rb+hion)*sin(0.9782*(PI/2.0-azel[1])); - fs=1.0/sqrt(1.0-rp*rp); - } - if (opt&1) { - /* earth rotation correction (sun-fixed coordinate) */ - posp[1]+=2.0*PI*timediff(time,tec->time)/86400.0; - } - /* interpolate tec grid data */ - if (!interptec(tec,i,posp,&vtec,&rms)) return 0; - - *delay+=fact*fs*vtec; - *var+=fact*fact*fs*fs*rms*rms; +static int iondelay(gtime_t time, const tec_t *tec, const double *pos, const double *azel, int opt, + double *delay, double *var) { + const double fact = 40.30E16 / FREQL1 / FREQL1; /* tecu->L1 iono (m) */ + double fs, posp[3] = {0}, vtec, rms, hion, rp; + int i; + + char tstr[40]; + trace(3, "iondelay: time=%s pos=%.1f %.1f azel=%.1f %.1f\n", time2str(time, tstr, 0), + pos[0] * R2D, pos[1] * R2D, azel[0] * R2D, azel[1] * R2D); + + *delay = *var = 0.0; + + for (i = 0; i < tec->ndata[2]; i++) { /* for a layer */ + + hion = tec->hgts[0] + tec->hgts[2] * i; + + /* ionospheric pierce point position */ + fs = ionppp(pos, azel, tec->rb, hion, posp); + + if (opt & 2) { + /* modified single layer mapping function (M-SLM) ref [2] */ + rp = tec->rb / (tec->rb + hion) * sin(0.9782 * (PI / 2.0 - azel[1])); + fs = 1.0 / sqrt(1.0 - rp * rp); } - trace(4,"iondelay: delay=%7.2f std=%6.2f\n",*delay,sqrt(*var)); - - return 1; + if (opt & 1) { + /* earth rotation correction (sun-fixed coordinate) */ + posp[1] += 2.0 * PI * timediff(time, tec->time) / 86400.0; + } + /* interpolate tec grid data */ + if (!interptec(tec, i, posp, &vtec, &rms)) return 0; + + *delay += fact * fs * vtec; + *var += fact * fact * fs * fs * rms * rms; + } + trace(4, "iondelay: delay=%7.2f std=%6.2f\n", *delay, sqrt(*var)); + + return 1; } /* ionosphere model by tec grid data ------------------------------------------- -* compute ionospheric delay by tec grid data -* args : gtime_t time I time (gpst) -* nav_t *nav I navigation data -* double *pos I receiver position {lat,lon,h} (rad,m) -* double *azel I azimuth/elevation angle {az,el} (rad) -* int opt I model option -* bit0: 0:earth-fixed,1:sun-fixed -* bit1: 0:single-layer,1:modified single-layer -* double *delay O ionospheric delay (L1) (m) -* double *var O ionospheric dealy (L1) variance (m^2) -* return : status (1:ok,0:error) -* notes : before calling the function, read tec grid data by calling readtec() -* return ok with delay=0 and var=VAR_NOTEC if elnt;i++) { - if (timediff(nav->tec[i].time,time)>0.0) break; - } - if (i==0||i>=nav->nt) { - trace(2,"%s: tec grid out of period\n",time2str(time,tstr,0)); - return 0; - } - if ((tt=timediff(nav->tec[i].time,nav->tec[i-1].time))==0.0) { - trace(2,"tec grid time interval error\n"); - return 0; - } - /* ionospheric delay by tec grid data */ - stat[0]=iondelay(time,nav->tec+i-1,pos,azel,opt,dels ,vars ); - stat[1]=iondelay(time,nav->tec+i ,pos,azel,opt,dels+1,vars+1); - - if (!stat[0]&&!stat[1]) { - trace(2,"%s: tec grid out of area pos=%6.2f %7.2f azel=%6.1f %5.1f\n", - time2str(time,tstr,0),pos[0]*R2D,pos[1]*R2D,azel[0]*R2D,azel[1]*R2D); - return 0; - } - if (stat[0]&&stat[1]) { /* linear interpolation by time */ - a=timediff(time,nav->tec[i-1].time)/tt; - *delay=dels[0]*(1.0-a)+dels[1]*a; - *var =vars[0]*(1.0-a)+vars[1]*a; - } - else if (stat[0]) { /* nearest-neighbour extrapolation by time */ - *delay=dels[0]; - *var =vars[0]; - } - else { - *delay=dels[1]; - *var =vars[1]; - } - trace(3,"iontec : delay=%5.2f std=%5.2f\n",*delay,sqrt(*var)); + * compute ionospheric delay by tec grid data + * args : gtime_t time I time (gpst) + * nav_t *nav I navigation data + * double *pos I receiver position {lat,lon,h} (rad,m) + * double *azel I azimuth/elevation angle {az,el} (rad) + * int opt I model option + * bit0: 0:earth-fixed,1:sun-fixed + * bit1: 0:single-layer,1:modified single-layer + * double *delay O ionospheric delay (L1) (m) + * double *var O ionospheric dealy (L1) variance (m^2) + * return : status (1:ok,0:error) + * notes : before calling the function, read tec grid data by calling readtec() + * return ok with delay=0 and var=VAR_NOTEC if elnt; i++) { + if (timediff(nav->tec[i].time, time) > 0.0) break; + } + if (i == 0 || i >= nav->nt) { + trace(2, "%s: tec grid out of period\n", time2str(time, tstr, 0)); + return 0; + } + if ((tt = timediff(nav->tec[i].time, nav->tec[i - 1].time)) == 0.0) { + trace(2, "tec grid time interval error\n"); + return 0; + } + /* ionospheric delay by tec grid data */ + stat[0] = iondelay(time, nav->tec + i - 1, pos, azel, opt, dels, vars); + stat[1] = iondelay(time, nav->tec + i, pos, azel, opt, dels + 1, vars + 1); + + if (!stat[0] && !stat[1]) { + trace(2, "%s: tec grid out of area pos=%6.2f %7.2f azel=%6.1f %5.1f\n", time2str(time, tstr, 0), + pos[0] * R2D, pos[1] * R2D, azel[0] * R2D, azel[1] * R2D); + return 0; + } + if (stat[0] && stat[1]) { /* linear interpolation by time */ + a = timediff(time, nav->tec[i - 1].time) / tt; + *delay = dels[0] * (1.0 - a) + dels[1] * a; + *var = vars[0] * (1.0 - a) + vars[1] * a; + } else if (stat[0]) { /* nearest-neighbour extrapolation by time */ + *delay = dels[0]; + *var = vars[0]; + } else { + *delay = dels[1]; + *var = vars[1]; + } + trace(3, "iontec : delay=%5.2f std=%5.2f\n", *delay, sqrt(*var)); + return 1; } diff --git a/src/lambda.c b/src/lambda.c index ccd7e42c3..0d659253b 100644 --- a/src/lambda.c +++ b/src/lambda.c @@ -1,91 +1,102 @@ /*------------------------------------------------------------------------------ -* lambda.c : integer ambiguity resolution -* -* Copyright (C) 2007-2008 by T.TAKASU, All rights reserved. -* -* reference : -* [1] P.J.G.Teunissen, The least-square ambiguity decorrelation adjustment: -* a method for fast GPS ambiguity estimation, J.Geodesy, Vol.70, 65-82, -* 1995 -* [2] X.-W.Chang, X.Yang, T.Zhou, MLAMBDA: A modified LAMBDA method for -* integer least-squares estimation, J.Geodesy, Vol.79, 552-565, 2005 -* -* version : $Revision: 1.1 $ $Date: 2008/07/17 21:48:06 $ -* history : 2007/01/13 1.0 new -* 2015/05/31 1.1 add api lambda_reduction(), lambda_search() -*-----------------------------------------------------------------------------*/ + * lambda.c : integer ambiguity resolution + * + * Copyright (C) 2007-2008 by T.TAKASU, All rights reserved. + * + * reference : + * [1] P.J.G.Teunissen, The least-square ambiguity decorrelation adjustment: + * a method for fast GPS ambiguity estimation, J.Geodesy, Vol.70, 65-82, + * 1995 + * [2] X.-W.Chang, X.Yang, T.Zhou, MLAMBDA: A modified LAMBDA method for + * integer least-squares estimation, J.Geodesy, Vol.79, 552-565, 2005 + * + * version : $Revision: 1.1 $ $Date: 2008/07/17 21:48:06 $ + * history : 2007/01/13 1.0 new + * 2015/05/31 1.1 add api lambda_reduction(), lambda_search() + *-----------------------------------------------------------------------------*/ #include "rtklib.h" /* constants/macros ----------------------------------------------------------*/ -#define LOOPMAX 10000 /* maximum count of search loop */ +#define LOOPMAX 10000 /* maximum count of search loop */ -#define SGN(x) ((x)<=0.0?-1.0:1.0) -#define ROUND(x) (floor((x)+0.5)) -#define SWAP(x,y) do {double tmp_; tmp_=x; x=y; y=tmp_;} while (0) +#define SGN(x) ((x) <= 0.0 ? -1.0 : 1.0) +#define ROUND(x) (floor((x) + 0.5)) +#define SWAP(x, y) \ + do { \ + double tmp_; \ + tmp_ = x; \ + x = y; \ + y = tmp_; \ + } while (0) /* LD factorization (Q=L'*diag(D)*L) -----------------------------------------*/ -static int LD(int n, const double *Q, double *L, double *D) -{ - int i,j,k,info=0; - double a,*A=mat(n,n); - - memcpy(A,Q,sizeof(double)*n*n); - for (i=n-1;i>=0;i--) { - if ((D[i]=A[i+i*n])<=0.0) {info=-1; break;} - a=sqrt(D[i]); - for (j=0;j<=i;j++) L[i+j*n]=A[i+j*n]/a; - for (j=0;j<=i-1;j++) for (k=0;k<=j;k++) A[j+k*n]-=L[i+k*n]*L[i+j*n]; - for (j=0;j<=i;j++) L[i+j*n]/=L[i+i*n]; +static int LD(int n, const double *Q, double *L, double *D) { + int i, j, k, info = 0; + double a, *A = mat(n, n); + + memcpy(A, Q, sizeof(double) * n * n); + for (i = n - 1; i >= 0; i--) { + if ((D[i] = A[i + i * n]) <= 0.0) { + info = -1; + break; } - free(A); - if (info) fprintf(stderr,"%s : LD factorization error\n",__FILE__); - return info; + a = sqrt(D[i]); + for (j = 0; j <= i; j++) L[i + j * n] = A[i + j * n] / a; + for (j = 0; j <= i - 1; j++) + for (k = 0; k <= j; k++) A[j + k * n] -= L[i + k * n] * L[i + j * n]; + for (j = 0; j <= i; j++) L[i + j * n] /= L[i + i * n]; + } + free(A); + if (info) fprintf(stderr, "%s : LD factorization error\n", __FILE__); + return info; } /* integer gauss transformation ----------------------------------------------*/ -static void gauss(int n, double *L, double *Z, int i, int j) -{ - int k,mu; - - if ((mu=(int)ROUND(L[i+j*n]))!=0) { - for (k=i;k=0) { - if (j<=k) for (i=j+1;i= 0) { + if (j <= k) + for (i = j + 1; i < n; i++) gauss(n, L, Z, i, j); + del = D[j] + L[j + 1 + j * n] * L[j + 1 + j * n] * D[j + 1]; + if (del + 1E-6 < D[j + 1]) { /* compared considering numerical error */ + perm(n, L, D, j, del, Z); + k = j; + j = n - 2; + } else + j--; + } } /* modified lambda (mlambda) search (ref. [2]) ------------------------------- * args : n I number of float parameters @@ -94,174 +105,188 @@ static void reduction(int n, double *L, double *D, double *Z) zs I transformed double-diff phase biases zn O fixed solutions s O sum of residuals for fixed solutions */ -static int search(int n, int m, const double *L, const double *D, - const double *zs, double *zn, double *s) -{ - int i,j,k,c,nn=0,imax=0; - double newdist,maxdist=1E99,y; - double *S=zeros(n,n),*dist=mat(n,1),*zb=mat(n,1),*z=mat(n,1),*step=mat(n,1); - - k=n-1; dist[k]=0.0; - zb[k]=zs[k]; - z[k]=ROUND(zb[k]); - y=zb[k]-z[k]; - step[k]=SGN(y); /* step towards closest integer */ - for (c=0;cs[imax]) imax=nn; - for (i=0;i s[imax]) imax = nn; + for (i = 0; i < n; i++) zn[i + nn * n] = z[i]; + s[nn++] = newdist; + } else { + if (newdist < s[imax]) { + for (i = 0; i < n; i++) zn[i + imax * n] = z[i]; + s[imax] = newdist; + for (i = imax = 0; i < m; i++) + if (s[imax] < s[i]) imax = i; + } + maxdist = s[imax]; } + z[0] += step[0]; /* next valid integer */ + y = zb[0] - z[0]; + step[0] = -step[0] - SGN(step[0]); + } } - for (i=0;i=LOOPMAX) { - fprintf(stderr,"%s : search loop count overflow\n",__FILE__); - return -2; + } + for (i = 0; i < m - 1; i++) { /* sort by s */ + for (j = i + 1; j < m; j++) { + if (s[i] < s[j]) continue; + SWAP(s[i], s[j]); + for (k = 0; k < n; k++) SWAP(zn[k + i * n], zn[k + j * n]); } - return 0; + } + free(S); + free(dist); + free(zb); + free(z); + free(step); + + if (c >= LOOPMAX) { + fprintf(stderr, "%s : search loop count overflow\n", __FILE__); + return -2; + } + return 0; } /* lambda/mlambda integer least-square estimation ------------------------------ -* integer least-square estimation. reduction is performed by lambda (ref.[1]), -* and search by mlambda (ref.[2]). -* args : int n I number of float parameters -* int m I number of fixed solutions -* double *a I float parameters (n x 1) (double-diff phase biases) -* double *Q I covariance matrix of float parameters (n x n) -* double *F O fixed solutions (n x m) -* double *s O sum of squared residulas of fixed solutions (1 x m) -* return : status (0:ok,other:error) -* notes : matrix stored by column-major order (fortran convension) -*-----------------------------------------------------------------------------*/ -extern int lambda(int n, int m, const double *a, const double *Q, double *F, - double *s) -{ - int info; - double *L,*D,*Z,*z,*E; - - if (n<=0||m<=0) return -1; - L=zeros(n,n); D=mat(n,1); Z=eye(n); z=mat(n,1); E=mat(n,m); - - /* LD (lower diagonal) factorization (Q=L'*diag(D)*L) */ - if (!(info=LD(n,Q,L,D))) { - - /* lambda reduction (z=Z'*a, Qz=Z'*Q*Z=L'*diag(D)*L) */ - reduction(n,L,D,Z); - matmul("TN",n,1,n,Z,a,z); /* z=Z'*a */ - - /* mlambda search - z = transformed double-diff phase biases - L,D = transformed covariance matrix */ - if (!(info=search(n,m,L,D,z,E,s))) { /* returns 0 if no error */ - - info=solve("T",Z,E,n,m,F); /* F=Z'\E */ - } + * integer least-square estimation. reduction is performed by lambda (ref.[1]), + * and search by mlambda (ref.[2]). + * args : int n I number of float parameters + * int m I number of fixed solutions + * double *a I float parameters (n x 1) (double-diff phase biases) + * double *Q I covariance matrix of float parameters (n x n) + * double *F O fixed solutions (n x m) + * double *s O sum of squared residulas of fixed solutions (1 x m) + * return : status (0:ok,other:error) + * notes : matrix stored by column-major order (fortran convension) + *-----------------------------------------------------------------------------*/ +extern int lambda(int n, int m, const double *a, const double *Q, double *F, double *s) { + int info; + double *L, *D, *Z, *z, *E; + + if (n <= 0 || m <= 0) return -1; + L = zeros(n, n); + D = mat(n, 1); + Z = eye(n); + z = mat(n, 1); + E = mat(n, m); + + /* LD (lower diagonal) factorization (Q=L'*diag(D)*L) */ + if (!(info = LD(n, Q, L, D))) { + /* lambda reduction (z=Z'*a, Qz=Z'*Q*Z=L'*diag(D)*L) */ + reduction(n, L, D, Z); + matmul("TN", n, 1, n, Z, a, z); /* z=Z'*a */ + + /* mlambda search + z = transformed double-diff phase biases + L,D = transformed covariance matrix */ + if (!(info = search(n, m, L, D, z, E, s))) { /* returns 0 if no error */ + + info = solve("T", Z, E, n, m, F); /* F=Z'\E */ } - free(L); free(D); free(Z); free(z); free(E); - return info; + } + free(L); + free(D); + free(Z); + free(z); + free(E); + return info; } /* lambda reduction ------------------------------------------------------------ -* reduction by lambda (ref [1]) for integer least square -* args : int n I number of float parameters -* double *Q I covariance matrix of float parameters (n x n) -* double *Z O lambda reduction matrix (n x n) -* return : status (0:ok,other:error) -*-----------------------------------------------------------------------------*/ -extern int lambda_reduction(int n, const double *Q, double *Z) -{ - double *L,*D; - int i,j,info; - - if (n<=0) return -1; - - L=zeros(n,n); D=mat(n,1); - - for (i=0;isnrmaskena -* pos1-snrmask1,2,3 -* 2013/03/11 1.3 add pos1-posopt1,2,3,4,5,pos2-syncsol -* misc-rnxopt1,2,pos1-snrmask_r,_b,_L1,_L2,_L5 -* 2014/10/21 1.4 add pos2-bdsarmode -* 2015/02/20 1.4 add ppp-fixed as pos1-posmode option -* 2015/05/10 1.5 add pos2-arthres1,2,3,4 -* 2015/05/31 1.6 add pos2-armaxiter, pos1-posopt6 -* add selection precise for pos1-pospot3 -* 2015/11/26 1.7 modify pos1-frequency 4:l1+l2+l5+l6 -> l1+l5 -* 2015/12/05 1.8 add misc-pppopt -* 2016/06/10 1.9 add ant2-maxaveep,ant2-initrst -* 2016/07/31 1.10 add out-outsingle,out-maxsolstd -* 2017/06/14 1.11 add out-outvel -* 2020/11/30 1.12 change options pos1-frequency, pos1-ionoopt, -* pos1-tropopt, pos1-sateph, pos1-navsys, -* pos2-gloarmode, -*-----------------------------------------------------------------------------*/ + * options.c : options functions + * + * Copyright (C) 2010-2020 by T.TAKASU, All rights reserved. + * + * version : $Revision:$ $Date:$ + * history : 2010/07/20 1.1 moved from postpos.c + * added api: + * searchopt(),str2opt(),opt2str(),opt2buf(), + * loadopts(),saveopts(),resetsysopts(), + * getsysopts(),setsysopts() + * 2010/09/11 1.2 add options + * pos2-elmaskhold,pos1->snrmaskena + * pos1-snrmask1,2,3 + * 2013/03/11 1.3 add pos1-posopt1,2,3,4,5,pos2-syncsol + * misc-rnxopt1,2,pos1-snrmask_r,_b,_L1,_L2,_L5 + * 2014/10/21 1.4 add pos2-bdsarmode + * 2015/02/20 1.4 add ppp-fixed as pos1-posmode option + * 2015/05/10 1.5 add pos2-arthres1,2,3,4 + * 2015/05/31 1.6 add pos2-armaxiter, pos1-posopt6 + * add selection precise for pos1-pospot3 + * 2015/11/26 1.7 modify pos1-frequency 4:l1+l2+l5+l6 -> l1+l5 + * 2015/12/05 1.8 add misc-pppopt + * 2016/06/10 1.9 add ant2-maxaveep,ant2-initrst + * 2016/07/31 1.10 add out-outsingle,out-maxsolstd + * 2017/06/14 1.11 add out-outvel + * 2020/11/30 1.12 change options pos1-frequency, pos1-ionoopt, + * pos1-tropopt, pos1-sateph, pos1-navsys, + * pos2-gloarmode, + *-----------------------------------------------------------------------------*/ #define _POSIX_C_SOURCE 199506 #include "rtklib.h" @@ -35,543 +35,551 @@ static prcopt_t prcopt_; static solopt_t solopt_; static filopt_t filopt_; -static double elmask_,elmaskar_,elmaskhold_; +static double elmask_, elmaskar_, elmaskhold_; static double antpos_[2][3]; static char exsats_[1024]; static char snrmask_[NFREQ][1024]; /* system options table ------------------------------------------------------*/ -#define SWTOPT "0:off,1:on" -#define MODOPT "0:single,1:dgps,2:kinematic,3:static,4:static-start,5:movingbase,6:fixed,7:ppp-kine,8:ppp-static,9:ppp-fixed" -#define FRQOPT "1:l1,2:l1+l2,3:l1+l2+l5,4:l1+l2+l5+l6" -#define TYPOPT "0:forward,1:backward,2:combined,3:combined-nophasereset" -#define IONOPT "0:off,1:brdc,2:sbas,3:dual-freq,4:est-stec,5:ionex-tec,6:qzs-brdc" -#define TRPOPT "0:off,1:saas,2:sbas,3:est-ztd,4:est-ztdgrad" -#define EPHOPT "0:brdc,1:precise,2:brdc+sbas,3:brdc+ssrapc,4:brdc+ssrcom" -#define NAVOPT "1:gps+2:sbas+4:glo+8:gal+16:qzs+32:bds+64:navic" -#define GAROPT "0:off,1:on,2:autocal,3:fix-and-hold" +#define SWTOPT "0:off,1:on" +#define MODOPT \ + "0:single,1:dgps,2:kinematic,3:static,4:static-start,5:movingbase,6:fixed,7:ppp-kine,8:ppp-" \ + "static,9:ppp-fixed" +#define FRQOPT "1:l1,2:l1+l2,3:l1+l2+l5,4:l1+l2+l5+l6" +#define TYPOPT "0:forward,1:backward,2:combined,3:combined-nophasereset" +#define IONOPT "0:off,1:brdc,2:sbas,3:dual-freq,4:est-stec,5:ionex-tec,6:qzs-brdc" +#define TRPOPT "0:off,1:saas,2:sbas,3:est-ztd,4:est-ztdgrad" +#define EPHOPT "0:brdc,1:precise,2:brdc+sbas,3:brdc+ssrapc,4:brdc+ssrcom" +#define NAVOPT "1:gps+2:sbas+4:glo+8:gal+16:qzs+32:bds+64:navic" +#define GAROPT "0:off,1:on,2:autocal,3:fix-and-hold" #define WEIGHTOPT "0:elevation,1:snr" -#define SOLOPT "0:llh,1:xyz,2:enu,3:nmea" -#define TSYOPT "0:gpst,1:utc,2:jst" -#define TFTOPT "0:tow,1:hms" -#define DFTOPT "0:deg,1:dms" -#define HGTOPT "0:ellipsoidal,1:geodetic" -#define GEOOPT "0:internal,1:egm96,2:egm08_2.5,3:egm08_1,4:gsi2000" -#define STAOPT "0:all,1:single" -#define STSOPT "0:off,1:state,2:residual" -#define ARMOPT "0:off,1:continuous,2:instantaneous,3:fix-and-hold" -#define POSOPT "0:llh,1:xyz,2:single,3:posfile,4:rinexhead,5:rtcm" +#define SOLOPT "0:llh,1:xyz,2:enu,3:nmea" +#define TSYOPT "0:gpst,1:utc,2:jst" +#define TFTOPT "0:tow,1:hms" +#define DFTOPT "0:deg,1:dms" +#define HGTOPT "0:ellipsoidal,1:geodetic" +#define GEOOPT "0:internal,1:egm96,2:egm08_2.5,3:egm08_1,4:gsi2000" +#define STAOPT "0:all,1:single" +#define STSOPT "0:off,1:state,2:residual" +#define ARMOPT "0:off,1:continuous,2:instantaneous,3:fix-and-hold" +#define POSOPT "0:llh,1:xyz,2:single,3:posfile,4:rinexhead,5:rtcm" #define TIDEOPT "1:solid+2:otl+4:spole" -#define PHWOPT "0:off,1:on,2:precise" - -EXPORT opt_t sysopts[]={ - {"pos1-posmode", 3, (void *)&prcopt_.mode, MODOPT }, - {"pos1-frequency", 3, (void *)&prcopt_.nf, FRQOPT }, - {"pos1-soltype", 3, (void *)&prcopt_.soltype, TYPOPT }, - {"pos1-elmask", 1, (void *)&elmask_, "deg" }, - {"pos1-snrmask_r", 3, (void *)&prcopt_.snrmask.ena[0],SWTOPT}, - {"pos1-snrmask_b", 3, (void *)&prcopt_.snrmask.ena[1],SWTOPT}, - {"pos1-snrmask_L1", 2, (void *)snrmask_[0], "" }, - {"pos1-snrmask_L2", 2, (void *)snrmask_[1], "" }, - {"pos1-snrmask_L5", 2, (void *)snrmask_[2], "" }, - {"pos1-snrmask_L6", 2, (void *)snrmask_[3], "" }, - {"pos1-dynamics", 3, (void *)&prcopt_.dynamics, SWTOPT }, - {"pos1-tidecorr", 0, (void *)&prcopt_.tidecorr, TIDEOPT}, - {"pos1-ionoopt", 3, (void *)&prcopt_.ionoopt, IONOPT }, - {"pos1-tropopt", 3, (void *)&prcopt_.tropopt, TRPOPT }, - {"pos1-sateph", 3, (void *)&prcopt_.sateph, EPHOPT }, - {"pos1-posopt1", 3, (void *)&prcopt_.posopt[0], SWTOPT }, - {"pos1-posopt2", 3, (void *)&prcopt_.posopt[1], SWTOPT }, - {"pos1-posopt3", 3, (void *)&prcopt_.posopt[2], PHWOPT }, - {"pos1-posopt4", 3, (void *)&prcopt_.posopt[3], SWTOPT }, - {"pos1-posopt5", 3, (void *)&prcopt_.posopt[4], SWTOPT }, - {"pos1-posopt6", 3, (void *)&prcopt_.posopt[5], SWTOPT }, - {"pos1-exclsats", 2, (void *)exsats_, "prn ..."}, - {"pos1-navsys", 0, (void *)&prcopt_.navsys, NAVOPT }, - - {"pos2-armode", 3, (void *)&prcopt_.modear, ARMOPT }, - {"pos2-gloarmode", 3, (void *)&prcopt_.glomodear, GAROPT }, - {"pos2-bdsarmode", 3, (void *)&prcopt_.bdsmodear, SWTOPT }, - {"pos2-arfilter", 3, (void *)&prcopt_.arfilter, SWTOPT }, - {"pos2-arthres", 1, (void *)&prcopt_.thresar[0], "" }, - {"pos2-arthresmin", 1, (void *)&prcopt_.thresar[5], "" }, - {"pos2-arthresmax", 1, (void *)&prcopt_.thresar[6], "" }, - {"pos2-arthres1", 1, (void *)&prcopt_.thresar[1], "" }, - {"pos2-arthres2", 1, (void *)&prcopt_.thresar[2], "" }, - {"pos2-arthres3", 1, (void *)&prcopt_.thresar[3], "" }, - {"pos2-arthres4", 1, (void *)&prcopt_.thresar[4], "" }, - {"pos2-varholdamb", 1, (void *)&prcopt_.varholdamb, "cyc^2"}, - {"pos2-gainholdamb",1, (void *)&prcopt_.gainholdamb,"" }, - {"pos2-arlockcnt", 0, (void *)&prcopt_.minlock, "" }, - {"pos2-minfixsats", 0, (void *)&prcopt_.minfixsats, "" }, - {"pos2-minholdsats",0, (void *)&prcopt_.minholdsats,"" }, - {"pos2-mindropsats",0, (void *)&prcopt_.mindropsats,"" }, - {"pos2-arelmask", 1, (void *)&elmaskar_, "deg" }, - {"pos2-arminfix", 0, (void *)&prcopt_.minfix, "" }, - {"pos2-armaxiter", 0, (void *)&prcopt_.armaxiter, "" }, - {"pos2-elmaskhold", 1, (void *)&elmaskhold_, "deg" }, - {"pos2-aroutcnt", 0, (void *)&prcopt_.maxout, "" }, - {"pos2-maxage", 1, (void *)&prcopt_.maxtdiff, "s" }, - {"pos2-syncsol", 3, (void *)&prcopt_.syncsol, SWTOPT }, - {"pos2-slipthres", 1, (void *)&prcopt_.thresslip, "m" }, - {"pos2-dopthres", 1, (void *)&prcopt_.thresdop, "m" }, - {"pos2-rejionno", 1, (void *)&prcopt_.maxinno[0], "m" }, - {"pos2-rejcode", 1, (void *)&prcopt_.maxinno[1], "m" }, - {"pos2-niter", 0, (void *)&prcopt_.niter, "" }, - {"pos2-baselen", 1, (void *)&prcopt_.baseline[0],"m" }, - {"pos2-basesig", 1, (void *)&prcopt_.baseline[1],"m" }, - - {"out-solformat", 3, (void *)&solopt_.posf, SOLOPT }, - {"out-outhead", 3, (void *)&solopt_.outhead, SWTOPT }, - {"out-outopt", 3, (void *)&solopt_.outopt, SWTOPT }, - {"out-outvel", 3, (void *)&solopt_.outvel, SWTOPT }, - {"out-timesys", 3, (void *)&solopt_.times, TSYOPT }, - {"out-timeform", 3, (void *)&solopt_.timef, TFTOPT }, - {"out-timendec", 0, (void *)&solopt_.timeu, "" }, - {"out-degform", 3, (void *)&solopt_.degf, DFTOPT }, - {"out-fieldsep", 2, (void *)&solopt_.sep, "" }, - {"out-outsingle", 3, (void *)&prcopt_.outsingle, SWTOPT }, - {"out-maxsolstd", 1, (void *)&solopt_.maxsolstd, "m" }, - {"out-height", 3, (void *)&solopt_.height, HGTOPT }, - {"out-geoid", 3, (void *)&solopt_.geoid, GEOOPT }, - {"out-solstatic", 3, (void *)&solopt_.solstatic, STAOPT }, - {"out-nmeaintv1", 1, (void *)&solopt_.nmeaintv[0],"s" }, - {"out-nmeaintv2", 1, (void *)&solopt_.nmeaintv[1],"s" }, - {"out-outstat", 3, (void *)&solopt_.sstat, STSOPT }, - {"stats-eratio1", 1, (void *)&prcopt_.eratio[0], "" }, - {"stats-eratio2", 1, (void *)&prcopt_.eratio[1], "" }, - {"stats-eratio5", 1, (void *)&prcopt_.eratio[2], "" }, - {"stats-eratio6", 1, (void *)&prcopt_.eratio[3], "" }, - {"stats-errphase", 1, (void *)&prcopt_.err[1], "m" }, - {"stats-errphaseel",1, (void *)&prcopt_.err[2], "m" }, - {"stats-errphasebl",1, (void *)&prcopt_.err[3], "m/10km"}, - {"stats-errdoppler",1, (void *)&prcopt_.err[4], "Hz" }, - {"stats-snrmax", 1, (void *)&prcopt_.err[5], "dB.Hz"}, - {"stats-errsnr", 1, (void *)&prcopt_.err[6], "m" }, - {"stats-errrcv", 1, (void *)&prcopt_.err[7], " " }, - {"stats-stdbias", 1, (void *)&prcopt_.std[0], "m" }, - {"stats-stdiono", 1, (void *)&prcopt_.std[1], "m" }, - {"stats-stdtrop", 1, (void *)&prcopt_.std[2], "m" }, - {"stats-prnaccelh", 1, (void *)&prcopt_.prn[3], "m/s^2"}, - {"stats-prnaccelv", 1, (void *)&prcopt_.prn[4], "m/s^2"}, - {"stats-prnbias", 1, (void *)&prcopt_.prn[0], "m" }, - {"stats-prniono", 1, (void *)&prcopt_.prn[1], "m" }, - {"stats-prntrop", 1, (void *)&prcopt_.prn[2], "m" }, - {"stats-prnpos", 1, (void *)&prcopt_.prn[5], "m" }, - {"stats-clkstab", 1, (void *)&prcopt_.sclkstab, "s/s" }, - - {"ant1-postype", 3, (void *)&prcopt_.rovpos, POSOPT }, - {"ant1-pos1", 1, (void *)&antpos_[0][0], "deg|m"}, - {"ant1-pos2", 1, (void *)&antpos_[0][1], "deg|m"}, - {"ant1-pos3", 1, (void *)&antpos_[0][2], "m|m" }, - {"ant1-anttype", 2, (void *)prcopt_.anttype[0], "" }, - {"ant1-antdele", 1, (void *)&prcopt_.antdel[0][0],"m" }, - {"ant1-antdeln", 1, (void *)&prcopt_.antdel[0][1],"m" }, - {"ant1-antdelu", 1, (void *)&prcopt_.antdel[0][2],"m" }, - - {"ant2-postype", 3, (void *)&prcopt_.refpos, POSOPT }, - {"ant2-pos1", 1, (void *)&antpos_[1][0], "deg|m"}, - {"ant2-pos2", 1, (void *)&antpos_[1][1], "deg|m"}, - {"ant2-pos3", 1, (void *)&antpos_[1][2], "m|m" }, - {"ant2-anttype", 2, (void *)prcopt_.anttype[1], "" }, - {"ant2-antdele", 1, (void *)&prcopt_.antdel[1][0],"m" }, - {"ant2-antdeln", 1, (void *)&prcopt_.antdel[1][1],"m" }, - {"ant2-antdelu", 1, (void *)&prcopt_.antdel[1][2],"m" }, - {"ant2-maxaveep", 0, (void *)&prcopt_.maxaveep ,"" }, - {"ant2-initrst", 3, (void *)&prcopt_.initrst, SWTOPT }, - - {"misc-timeinterp", 3, (void *)&prcopt_.intpref, SWTOPT }, - {"misc-sbasatsel", 0, (void *)&prcopt_.sbassatsel, "0:all"}, - {"misc-rnxopt1", 2, (void *)prcopt_.rnxopt[0], "" }, - {"misc-rnxopt2", 2, (void *)prcopt_.rnxopt[1], "" }, - {"misc-pppopt", 2, (void *)prcopt_.pppopt, "" }, - - {"file-satantfile", 2, (void *)&filopt_.satantp, "" }, - {"file-rcvantfile", 2, (void *)&filopt_.rcvantp, "" }, - {"file-staposfile", 2, (void *)&filopt_.stapos, "" }, - {"file-geoidfile", 2, (void *)&filopt_.geoid, "" }, - {"file-ionofile", 2, (void *)&filopt_.iono, "" }, - {"file-dcbfile", 2, (void *)&filopt_.dcb, "" }, - {"file-eopfile", 2, (void *)&filopt_.eop, "" }, - {"file-blqfile", 2, (void *)&filopt_.blq, "" }, - {"file-tempdir", 2, (void *)&filopt_.tempdir, "" }, - {"file-geexefile", 2, (void *)&filopt_.geexe, "" }, - {"file-solstatfile",2, (void *)&filopt_.solstat, "" }, - {"file-tracefile", 2, (void *)&filopt_.trace, "" }, - - {"",0,NULL,""} /* terminator */ +#define PHWOPT "0:off,1:on,2:precise" + +EXPORT opt_t sysopts[] = { + {"pos1-posmode", 3, (void *)&prcopt_.mode, MODOPT}, + {"pos1-frequency", 3, (void *)&prcopt_.nf, FRQOPT}, + {"pos1-soltype", 3, (void *)&prcopt_.soltype, TYPOPT}, + {"pos1-elmask", 1, (void *)&elmask_, "deg"}, + {"pos1-snrmask_r", 3, (void *)&prcopt_.snrmask.ena[0], SWTOPT}, + {"pos1-snrmask_b", 3, (void *)&prcopt_.snrmask.ena[1], SWTOPT}, + {"pos1-snrmask_L1", 2, (void *)snrmask_[0], ""}, + {"pos1-snrmask_L2", 2, (void *)snrmask_[1], ""}, + {"pos1-snrmask_L5", 2, (void *)snrmask_[2], ""}, + {"pos1-snrmask_L6", 2, (void *)snrmask_[3], ""}, + {"pos1-dynamics", 3, (void *)&prcopt_.dynamics, SWTOPT}, + {"pos1-tidecorr", 0, (void *)&prcopt_.tidecorr, TIDEOPT}, + {"pos1-ionoopt", 3, (void *)&prcopt_.ionoopt, IONOPT}, + {"pos1-tropopt", 3, (void *)&prcopt_.tropopt, TRPOPT}, + {"pos1-sateph", 3, (void *)&prcopt_.sateph, EPHOPT}, + {"pos1-posopt1", 3, (void *)&prcopt_.posopt[0], SWTOPT}, + {"pos1-posopt2", 3, (void *)&prcopt_.posopt[1], SWTOPT}, + {"pos1-posopt3", 3, (void *)&prcopt_.posopt[2], PHWOPT}, + {"pos1-posopt4", 3, (void *)&prcopt_.posopt[3], SWTOPT}, + {"pos1-posopt5", 3, (void *)&prcopt_.posopt[4], SWTOPT}, + {"pos1-posopt6", 3, (void *)&prcopt_.posopt[5], SWTOPT}, + {"pos1-exclsats", 2, (void *)exsats_, "prn ..."}, + {"pos1-navsys", 0, (void *)&prcopt_.navsys, NAVOPT}, + + {"pos2-armode", 3, (void *)&prcopt_.modear, ARMOPT}, + {"pos2-gloarmode", 3, (void *)&prcopt_.glomodear, GAROPT}, + {"pos2-bdsarmode", 3, (void *)&prcopt_.bdsmodear, SWTOPT}, + {"pos2-arfilter", 3, (void *)&prcopt_.arfilter, SWTOPT}, + {"pos2-arthres", 1, (void *)&prcopt_.thresar[0], ""}, + {"pos2-arthresmin", 1, (void *)&prcopt_.thresar[5], ""}, + {"pos2-arthresmax", 1, (void *)&prcopt_.thresar[6], ""}, + {"pos2-arthres1", 1, (void *)&prcopt_.thresar[1], ""}, + {"pos2-arthres2", 1, (void *)&prcopt_.thresar[2], ""}, + {"pos2-arthres3", 1, (void *)&prcopt_.thresar[3], ""}, + {"pos2-arthres4", 1, (void *)&prcopt_.thresar[4], ""}, + {"pos2-varholdamb", 1, (void *)&prcopt_.varholdamb, "cyc^2"}, + {"pos2-gainholdamb", 1, (void *)&prcopt_.gainholdamb, ""}, + {"pos2-arlockcnt", 0, (void *)&prcopt_.minlock, ""}, + {"pos2-minfixsats", 0, (void *)&prcopt_.minfixsats, ""}, + {"pos2-minholdsats", 0, (void *)&prcopt_.minholdsats, ""}, + {"pos2-mindropsats", 0, (void *)&prcopt_.mindropsats, ""}, + {"pos2-arelmask", 1, (void *)&elmaskar_, "deg"}, + {"pos2-arminfix", 0, (void *)&prcopt_.minfix, ""}, + {"pos2-armaxiter", 0, (void *)&prcopt_.armaxiter, ""}, + {"pos2-elmaskhold", 1, (void *)&elmaskhold_, "deg"}, + {"pos2-aroutcnt", 0, (void *)&prcopt_.maxout, ""}, + {"pos2-maxage", 1, (void *)&prcopt_.maxtdiff, "s"}, + {"pos2-syncsol", 3, (void *)&prcopt_.syncsol, SWTOPT}, + {"pos2-slipthres", 1, (void *)&prcopt_.thresslip, "m"}, + {"pos2-dopthres", 1, (void *)&prcopt_.thresdop, "m"}, + {"pos2-rejionno", 1, (void *)&prcopt_.maxinno[0], "m"}, + {"pos2-rejcode", 1, (void *)&prcopt_.maxinno[1], "m"}, + {"pos2-niter", 0, (void *)&prcopt_.niter, ""}, + {"pos2-baselen", 1, (void *)&prcopt_.baseline[0], "m"}, + {"pos2-basesig", 1, (void *)&prcopt_.baseline[1], "m"}, + + {"out-solformat", 3, (void *)&solopt_.posf, SOLOPT}, + {"out-outhead", 3, (void *)&solopt_.outhead, SWTOPT}, + {"out-outopt", 3, (void *)&solopt_.outopt, SWTOPT}, + {"out-outvel", 3, (void *)&solopt_.outvel, SWTOPT}, + {"out-timesys", 3, (void *)&solopt_.times, TSYOPT}, + {"out-timeform", 3, (void *)&solopt_.timef, TFTOPT}, + {"out-timendec", 0, (void *)&solopt_.timeu, ""}, + {"out-degform", 3, (void *)&solopt_.degf, DFTOPT}, + {"out-fieldsep", 2, (void *)&solopt_.sep, ""}, + {"out-outsingle", 3, (void *)&prcopt_.outsingle, SWTOPT}, + {"out-maxsolstd", 1, (void *)&solopt_.maxsolstd, "m"}, + {"out-height", 3, (void *)&solopt_.height, HGTOPT}, + {"out-geoid", 3, (void *)&solopt_.geoid, GEOOPT}, + {"out-solstatic", 3, (void *)&solopt_.solstatic, STAOPT}, + {"out-nmeaintv1", 1, (void *)&solopt_.nmeaintv[0], "s"}, + {"out-nmeaintv2", 1, (void *)&solopt_.nmeaintv[1], "s"}, + {"out-outstat", 3, (void *)&solopt_.sstat, STSOPT}, + {"stats-eratio1", 1, (void *)&prcopt_.eratio[0], ""}, + {"stats-eratio2", 1, (void *)&prcopt_.eratio[1], ""}, + {"stats-eratio5", 1, (void *)&prcopt_.eratio[2], ""}, + {"stats-eratio6", 1, (void *)&prcopt_.eratio[3], ""}, + {"stats-errphase", 1, (void *)&prcopt_.err[1], "m"}, + {"stats-errphaseel", 1, (void *)&prcopt_.err[2], "m"}, + {"stats-errphasebl", 1, (void *)&prcopt_.err[3], "m/10km"}, + {"stats-errdoppler", 1, (void *)&prcopt_.err[4], "Hz"}, + {"stats-snrmax", 1, (void *)&prcopt_.err[5], "dB.Hz"}, + {"stats-errsnr", 1, (void *)&prcopt_.err[6], "m"}, + {"stats-errrcv", 1, (void *)&prcopt_.err[7], " "}, + {"stats-stdbias", 1, (void *)&prcopt_.std[0], "m"}, + {"stats-stdiono", 1, (void *)&prcopt_.std[1], "m"}, + {"stats-stdtrop", 1, (void *)&prcopt_.std[2], "m"}, + {"stats-prnaccelh", 1, (void *)&prcopt_.prn[3], "m/s^2"}, + {"stats-prnaccelv", 1, (void *)&prcopt_.prn[4], "m/s^2"}, + {"stats-prnbias", 1, (void *)&prcopt_.prn[0], "m"}, + {"stats-prniono", 1, (void *)&prcopt_.prn[1], "m"}, + {"stats-prntrop", 1, (void *)&prcopt_.prn[2], "m"}, + {"stats-prnpos", 1, (void *)&prcopt_.prn[5], "m"}, + {"stats-clkstab", 1, (void *)&prcopt_.sclkstab, "s/s"}, + + {"ant1-postype", 3, (void *)&prcopt_.rovpos, POSOPT}, + {"ant1-pos1", 1, (void *)&antpos_[0][0], "deg|m"}, + {"ant1-pos2", 1, (void *)&antpos_[0][1], "deg|m"}, + {"ant1-pos3", 1, (void *)&antpos_[0][2], "m|m"}, + {"ant1-anttype", 2, (void *)prcopt_.anttype[0], ""}, + {"ant1-antdele", 1, (void *)&prcopt_.antdel[0][0], "m"}, + {"ant1-antdeln", 1, (void *)&prcopt_.antdel[0][1], "m"}, + {"ant1-antdelu", 1, (void *)&prcopt_.antdel[0][2], "m"}, + + {"ant2-postype", 3, (void *)&prcopt_.refpos, POSOPT}, + {"ant2-pos1", 1, (void *)&antpos_[1][0], "deg|m"}, + {"ant2-pos2", 1, (void *)&antpos_[1][1], "deg|m"}, + {"ant2-pos3", 1, (void *)&antpos_[1][2], "m|m"}, + {"ant2-anttype", 2, (void *)prcopt_.anttype[1], ""}, + {"ant2-antdele", 1, (void *)&prcopt_.antdel[1][0], "m"}, + {"ant2-antdeln", 1, (void *)&prcopt_.antdel[1][1], "m"}, + {"ant2-antdelu", 1, (void *)&prcopt_.antdel[1][2], "m"}, + {"ant2-maxaveep", 0, (void *)&prcopt_.maxaveep, ""}, + {"ant2-initrst", 3, (void *)&prcopt_.initrst, SWTOPT}, + + {"misc-timeinterp", 3, (void *)&prcopt_.intpref, SWTOPT}, + {"misc-sbasatsel", 0, (void *)&prcopt_.sbassatsel, "0:all"}, + {"misc-rnxopt1", 2, (void *)prcopt_.rnxopt[0], ""}, + {"misc-rnxopt2", 2, (void *)prcopt_.rnxopt[1], ""}, + {"misc-pppopt", 2, (void *)prcopt_.pppopt, ""}, + + {"file-satantfile", 2, (void *)&filopt_.satantp, ""}, + {"file-rcvantfile", 2, (void *)&filopt_.rcvantp, ""}, + {"file-staposfile", 2, (void *)&filopt_.stapos, ""}, + {"file-geoidfile", 2, (void *)&filopt_.geoid, ""}, + {"file-ionofile", 2, (void *)&filopt_.iono, ""}, + {"file-dcbfile", 2, (void *)&filopt_.dcb, ""}, + {"file-eopfile", 2, (void *)&filopt_.eop, ""}, + {"file-blqfile", 2, (void *)&filopt_.blq, ""}, + {"file-tempdir", 2, (void *)&filopt_.tempdir, ""}, + {"file-geexefile", 2, (void *)&filopt_.geexe, ""}, + {"file-solstatfile", 2, (void *)&filopt_.solstat, ""}, + {"file-tracefile", 2, (void *)&filopt_.trace, ""}, + + {"", 0, NULL, ""} /* terminator */ }; /* discard space characters at tail ------------------------------------------*/ -static void chop(char *str) -{ - char *p; - if ((p=strchr(str,'#'))) *p='\0'; /* comment */ - for (p=str+strlen(str)-1;p>=str&&!isgraph((int)*p);p--) *p='\0'; +static void chop(char *str) { + char *p; + if ((p = strchr(str, '#'))) *p = '\0'; /* comment */ + for (p = str + strlen(str) - 1; p >= str && !isgraph((int)*p); p--) *p = '\0'; } /* enum to string ------------------------------------------------------------*/ -static int enum2str(char *s, const char *comment, int val) -{ - char str[32],*p,*q; - int n; - - n=sprintf(str,"%d:",val); - if (!(p=strstr(comment,str))) { - return sprintf(s,"%d",val); - } - if (!(q=strchr(p+n,','))&&!(q=strchr(p+n,')'))) { - strcpy(s,p+n); - return (int)strlen(p+n); - } - strncpy(s,p+n,q-p-n); s[q-p-n]='\0'; - return (int)(q-p-n); +static int enum2str(char *s, const char *comment, int val) { + char str[32], *p, *q; + int n; + + n = sprintf(str, "%d:", val); + if (!(p = strstr(comment, str))) { + return sprintf(s, "%d", val); + } + if (!(q = strchr(p + n, ',')) && !(q = strchr(p + n, ')'))) { + strcpy(s, p + n); + return (int)strlen(p + n); + } + strncpy(s, p + n, q - p - n); + s[q - p - n] = '\0'; + return (int)(q - p - n); } /* String to enum ------------------------------------------------------------ * Note if str is empty then the first comment digit is returned. */ static int str2enum(const char *str, const char *comment, int *val) { - for (const char *p = comment;; p++) { - p=strstr(p, str); - if (!p) break; - size_t i=p-comment; - if (i<1) continue; - if (comment[--i]!=':') continue; - /* Search for preceding digits */ - size_t j=i; - while (j>0) { - char c=comment[j-1]; - if (c<'0' || c>'9') break; - j--; - } - if (j==i) continue; /* No digits found */ - return sscanf(comment+j,"%d",val)==1; - } - char s[32]; - snprintf(s,sizeof(s),"%.30s:",str); - const char *p=strstr(comment,s); - if (p) { /* Number */ - return sscanf(p,"%d",val)==1; + for (const char *p = comment;; p++) { + p = strstr(p, str); + if (!p) break; + size_t i = p - comment; + if (i < 1) continue; + if (comment[--i] != ':') continue; + /* Search for preceding digits */ + size_t j = i; + while (j > 0) { + char c = comment[j - 1]; + if (c < '0' || c > '9') break; + j--; } - return 0; + if (j == i) continue; /* No digits found */ + return sscanf(comment + j, "%d", val) == 1; + } + char s[32]; + snprintf(s, sizeof(s), "%.30s:", str); + const char *p = strstr(comment, s); + if (p) { /* Number */ + return sscanf(p, "%d", val) == 1; + } + return 0; } /* search option --------------------------------------------------------------- -* search option record -* args : char *name I option name -* opt_t *opts I options table -* (terminated with table[i].name="") -* return : option record (NULL: not found) -*-----------------------------------------------------------------------------*/ -extern opt_t *searchopt(const char *name, const opt_t *opts) -{ - int i; - - trace(3,"searchopt: name=%s\n",name); - - for (i=0;*opts[i].name;i++) { - if (strstr(opts[i].name,name)) return (opt_t *)(opts+i); - } - return NULL; + * search option record + * args : char *name I option name + * opt_t *opts I options table + * (terminated with table[i].name="") + * return : option record (NULL: not found) + *-----------------------------------------------------------------------------*/ +extern opt_t *searchopt(const char *name, const opt_t *opts) { + int i; + + trace(3, "searchopt: name=%s\n", name); + + for (i = 0; *opts[i].name; i++) { + if (strstr(opts[i].name, name)) return (opt_t *)(opts + i); + } + return NULL; } /* string to option value ------------------------------------------------------ -* convert string to option value -* args : opt_t *opt O option -* char *str I option value string -* return : status (1:ok,0:error) -*-----------------------------------------------------------------------------*/ -extern int str2opt(opt_t *opt, const char *str) -{ - switch (opt->format) { - case 0: *(int *)opt->var=atoi(str); break; - case 1: *(double *)opt->var=atof(str); break; - case 2: strcpy((char *)opt->var,str); break; - case 3: return str2enum(str,opt->comment,(int *)opt->var); - default: return 0; - } - return 1; + * convert string to option value + * args : opt_t *opt O option + * char *str I option value string + * return : status (1:ok,0:error) + *-----------------------------------------------------------------------------*/ +extern int str2opt(opt_t *opt, const char *str) { + switch (opt->format) { + case 0: + *(int *)opt->var = atoi(str); + break; + case 1: + *(double *)opt->var = atof(str); + break; + case 2: + strcpy((char *)opt->var, str); + break; + case 3: + return str2enum(str, opt->comment, (int *)opt->var); + default: + return 0; + } + return 1; } /* option value to string ------------------------------------------------------ -* convert option value to string -* args : opt_t *opt I option -* char *str O option value string -* return : length of output string -*-----------------------------------------------------------------------------*/ -extern int opt2str(const opt_t *opt, char *str) -{ - char *p=str; - - trace(3,"opt2str : name=%s\n",opt->name); - - switch (opt->format) { - case 0: p+=sprintf(p,"%d" ,*(int *)opt->var); break; - case 1: p+=sprintf(p,"%.15g",*(double*)opt->var); break; - case 2: p+=sprintf(p,"%s" , (char *)opt->var); break; - case 3: p+=enum2str(p,opt->comment,*(int *)opt->var); break; - } - return (int)(p-str); + * convert option value to string + * args : opt_t *opt I option + * char *str O option value string + * return : length of output string + *-----------------------------------------------------------------------------*/ +extern int opt2str(const opt_t *opt, char *str) { + char *p = str; + + trace(3, "opt2str : name=%s\n", opt->name); + + switch (opt->format) { + case 0: + p += sprintf(p, "%d", *(int *)opt->var); + break; + case 1: + p += sprintf(p, "%.15g", *(double *)opt->var); + break; + case 2: + p += sprintf(p, "%s", (char *)opt->var); + break; + case 3: + p += enum2str(p, opt->comment, *(int *)opt->var); + break; + } + return (int)(p - str); } /* option to string ------------------------------------------------------------- -* convert option to string (keyword=value # comment) -* args : opt_t *opt I option -* char *buff O option string -* return : length of output string -*-----------------------------------------------------------------------------*/ -extern int opt2buf(const opt_t *opt, char *buff) -{ - char *p=buff; - int n; - - trace(3,"opt2buf : name=%s\n",opt->name); - - p+=sprintf(p,"%-18s =",opt->name); - p+=opt2str(opt,p); - if (*opt->comment) { - if ((n=(int)(buff+30-p))>0) p+=sprintf(p,"%*s",n,""); - p+=sprintf(p," # (%s)",opt->comment); - } - return (int)(p-buff); + * convert option to string (keyword=value # comment) + * args : opt_t *opt I option + * char *buff O option string + * return : length of output string + *-----------------------------------------------------------------------------*/ +extern int opt2buf(const opt_t *opt, char *buff) { + char *p = buff; + int n; + + trace(3, "opt2buf : name=%s\n", opt->name); + + p += sprintf(p, "%-18s =", opt->name); + p += opt2str(opt, p); + if (*opt->comment) { + if ((n = (int)(buff + 30 - p)) > 0) p += sprintf(p, "%*s", n, ""); + p += sprintf(p, " # (%s)", opt->comment); + } + return (int)(p - buff); } /* load options ---------------------------------------------------------------- -* load options from file -* args : char *file I options file -* opt_t *opts IO options table -* (terminated with table[i].name="") -* return : status (1:ok,0:error) -*-----------------------------------------------------------------------------*/ -extern int loadopts(const char *file, opt_t *opts) -{ - FILE *fp; - opt_t *opt; - char buff[2048],*p; - int n=0; - - trace(3,"loadopts: file=%s\n",file); - - if (!(fp=fopen(file,"r"))) { - trace(1,"loadopts: options file open error (%s)\n",file); - return 0; + * load options from file + * args : char *file I options file + * opt_t *opts IO options table + * (terminated with table[i].name="") + * return : status (1:ok,0:error) + *-----------------------------------------------------------------------------*/ +extern int loadopts(const char *file, opt_t *opts) { + FILE *fp; + opt_t *opt; + char buff[2048], *p; + int n = 0; + + trace(3, "loadopts: file=%s\n", file); + + if (!(fp = fopen(file, "r"))) { + trace(1, "loadopts: options file open error (%s)\n", file); + return 0; + } + while (fgets(buff, sizeof(buff), fp)) { + n++; + chop(buff); + + if (buff[0] == '\0') continue; + + if (!(p = strstr(buff, "="))) { + fprintf(stderr, "invalid option %s (%s:%d)\n", buff, file, n); + continue; } - while (fgets(buff,sizeof(buff),fp)) { - n++; - chop(buff); - - if (buff[0]=='\0') continue; - - if (!(p=strstr(buff,"="))) { - fprintf(stderr,"invalid option %s (%s:%d)\n",buff,file,n); - continue; - } - *p++='\0'; - chop(buff); - if (!(opt=searchopt(buff,opts))) continue; - - if (!str2opt(opt,p)) { - fprintf(stderr,"invalid option value %s (%s:%d)\n",buff,file,n); - continue; - } + *p++ = '\0'; + chop(buff); + if (!(opt = searchopt(buff, opts))) continue; + + if (!str2opt(opt, p)) { + fprintf(stderr, "invalid option value %s (%s:%d)\n", buff, file, n); + continue; } - fclose(fp); - - return 1; + } + fclose(fp); + + return 1; } /* save options to file -------------------------------------------------------- -* save options to file -* args : char *file I options file -* char *mode I write mode ("w":overwrite,"a":append); -* char *comment I header comment (NULL: no comment) -* opt_t *opts I options table -* (terminated with table[i].name="") -* return : status (1:ok,0:error) -*-----------------------------------------------------------------------------*/ -extern int saveopts(const char *file, const char *mode, const char *comment, - const opt_t *opts) -{ - FILE *fp; - char buff[2048]; - int i; - - trace(3,"saveopts: file=%s mode=%s\n",file,mode); - - if (!(fp=fopen(file,mode))) { - trace(1,"saveopts: options file open error (%s)\n",file); - return 0; - } - if (comment) fprintf(fp,"# %s\n\n",comment); - - for (i=0;*opts[i].name;i++) { - opt2buf(opts+i,buff); - fprintf(fp,"%s\n",buff); - } - fclose(fp); - return 1; + * save options to file + * args : char *file I options file + * char *mode I write mode ("w":overwrite,"a":append); + * char *comment I header comment (NULL: no comment) + * opt_t *opts I options table + * (terminated with table[i].name="") + * return : status (1:ok,0:error) + *-----------------------------------------------------------------------------*/ +extern int saveopts(const char *file, const char *mode, const char *comment, const opt_t *opts) { + FILE *fp; + char buff[2048]; + int i; + + trace(3, "saveopts: file=%s mode=%s\n", file, mode); + + if (!(fp = fopen(file, mode))) { + trace(1, "saveopts: options file open error (%s)\n", file); + return 0; + } + if (comment) fprintf(fp, "# %s\n\n", comment); + + for (i = 0; *opts[i].name; i++) { + opt2buf(opts + i, buff); + fprintf(fp, "%s\n", buff); + } + fclose(fp); + return 1; } /* system options buffer to options ------------------------------------------*/ -static void buff2sysopts(void) -{ - double pos[3],*rr; - char buff[1024],*p,*id; - int i,j,sat,ps; - - prcopt_.elmin =elmask_ *D2R; - prcopt_.elmaskar =elmaskar_ *D2R; - prcopt_.elmaskhold=elmaskhold_*D2R; - - for (i=0;i<2;i++) { - ps=i==0?prcopt_.rovpos:prcopt_.refpos; - rr=i==0?prcopt_.ru:prcopt_.rb; - - if (ps==POSOPT_POS_LLH) { /* lat/lon/hgt */ - pos[0]=antpos_[i][0]*D2R; - pos[1]=antpos_[i][1]*D2R; - pos[2]=antpos_[i][2]; - pos2ecef(pos,rr); - } - else if (ps==POSOPT_POS_XYZ) { /* xyz-ecef */ - rr[0]=antpos_[i][0]; - rr[1]=antpos_[i][1]; - rr[2]=antpos_[i][2]; - } - } - /* excluded satellites */ - for (i=0;iNFREQ) { - fprintf(stderr,"Number of frequencies %d limited to %d, rebuild with NFREQ=%d\n",prcopt_.nf, NFREQ, prcopt_.nf); - prcopt_.nf=NFREQ; + } + /* snrmask */ + for (i = 0; i < NFREQ; i++) { + for (j = 0; j < 9; j++) prcopt_.snrmask.mask[i][j] = 0.0; + strcpy(buff, snrmask_[i]); + char *q; + for (p = strtok_r(buff, ",", &q), j = 0; p && j < 9; p = strtok_r(NULL, ",", &q)) { + prcopt_.snrmask.mask[i][j++] = atof(p); } - /* number of frequency (4:L1+L5) TODO ????*/ - /*if (prcopt_.nf==4) { - prcopt_.nf=3; - prcopt_.freqopt=1; - }*/ + } + /* Guard number of frequencies */ + if (prcopt_.nf > NFREQ) { + fprintf(stderr, "Number of frequencies %d limited to %d, rebuild with NFREQ=%d\n", prcopt_.nf, + NFREQ, prcopt_.nf); + prcopt_.nf = NFREQ; + } + /* number of frequency (4:L1+L5) TODO ????*/ + /*if (prcopt_.nf==4) { + prcopt_.nf=3; + prcopt_.freqopt=1; + }*/ } /* options to system options buffer ------------------------------------------*/ -static void sysopts2buff(void) -{ - double pos[3],*rr; - char id[8],*p; - int i,j,sat,ps; - - elmask_ =prcopt_.elmin *R2D; - elmaskar_ =prcopt_.elmaskar *R2D; - elmaskhold_=prcopt_.elmaskhold*R2D; - - for (i=0;i<2;i++) { - ps=i==0?prcopt_.rovpos:prcopt_.refpos; - rr=i==0?prcopt_.ru:prcopt_.rb; - - if (ps==POSOPT_POS_LLH) { - ecef2pos(rr,pos); - antpos_[i][0]=pos[0]*R2D; - antpos_[i][1]=pos[1]*R2D; - antpos_[i][2]=pos[2]; - } else if (ps==POSOPT_POS_XYZ) { - antpos_[i][0] = rr[0]; - antpos_[i][1] = rr[1]; - antpos_[i][2] = rr[2]; - } +static void sysopts2buff(void) { + double pos[3], *rr; + char id[8], *p; + int i, j, sat, ps; + + elmask_ = prcopt_.elmin * R2D; + elmaskar_ = prcopt_.elmaskar * R2D; + elmaskhold_ = prcopt_.elmaskhold * R2D; + + for (i = 0; i < 2; i++) { + ps = i == 0 ? prcopt_.rovpos : prcopt_.refpos; + rr = i == 0 ? prcopt_.ru : prcopt_.rb; + + if (ps == POSOPT_POS_LLH) { + ecef2pos(rr, pos); + antpos_[i][0] = pos[0] * R2D; + antpos_[i][1] = pos[1] * R2D; + antpos_[i][2] = pos[2]; + } else if (ps == POSOPT_POS_XYZ) { + antpos_[i][0] = rr[0]; + antpos_[i][1] = rr[1]; + antpos_[i][2] = rr[2]; } - /* excluded satellites */ - exsats_[0]='\0'; - for (sat=1,p=exsats_;sat<=MAXSAT&&p-exsats_<(int)sizeof(exsats_)-32;sat++) { - if (prcopt_.exsats[sat-1]) { - satno2id(sat,id); - p+=sprintf(p,"%s%s%s",p==exsats_?"":" ", - prcopt_.exsats[sat-1]==2?"+":"",id); - } + } + /* excluded satellites */ + exsats_[0] = '\0'; + for (sat = 1, p = exsats_; sat <= MAXSAT && p - exsats_ < (int)sizeof(exsats_) - 32; sat++) { + if (prcopt_.exsats[sat - 1]) { + satno2id(sat, id); + p += sprintf(p, "%s%s%s", p == exsats_ ? "" : " ", prcopt_.exsats[sat - 1] == 2 ? "+" : "", + id); } - /* snrmask */ - for (i=0;i0?",":"",prcopt_.snrmask.mask[i][j]); - } + } + /* snrmask */ + for (i = 0; i < NFREQ; i++) { + snrmask_[i][0] = '\0'; + p = snrmask_[i]; + for (j = 0; j < 9; j++) { + p += sprintf(p, "%s%.0f", j > 0 ? "," : "", prcopt_.snrmask.mask[i][j]); } - /* number of frequency (4:L1+L5) TODO ???? */ - /*if (prcopt_.nf==3&&prcopt_.freqopt==1) { - prcopt_.nf=4; - prcopt_.freqopt=0; - }*/ + } + /* number of frequency (4:L1+L5) TODO ???? */ + /*if (prcopt_.nf==3&&prcopt_.freqopt==1) { + prcopt_.nf=4; + prcopt_.freqopt=0; + }*/ } /* reset system options to default --------------------------------------------- -* reset system options to default -* args : none -* return : none -*-----------------------------------------------------------------------------*/ -extern void resetsysopts(void) -{ - int i,j; - - trace(3,"resetsysopts:\n"); - - prcopt_=prcopt_default; - solopt_=solopt_default; - filopt_.satantp[0]='\0'; - filopt_.rcvantp[0]='\0'; - filopt_.stapos [0]='\0'; - filopt_.geoid [0]='\0'; - filopt_.dcb [0]='\0'; - filopt_.blq [0]='\0'; - filopt_.solstat[0]='\0'; - filopt_.trace [0]='\0'; - elmask_=15.0; - elmaskar_=0.0; - elmaskhold_=0.0; - for (i=0;i<2;i++) for (j=0;j<3;j++) { - antpos_[i][j]=0.0; + * reset system options to default + * args : none + * return : none + *-----------------------------------------------------------------------------*/ +extern void resetsysopts(void) { + int i, j; + + trace(3, "resetsysopts:\n"); + + prcopt_ = prcopt_default; + solopt_ = solopt_default; + filopt_.satantp[0] = '\0'; + filopt_.rcvantp[0] = '\0'; + filopt_.stapos[0] = '\0'; + filopt_.geoid[0] = '\0'; + filopt_.dcb[0] = '\0'; + filopt_.blq[0] = '\0'; + filopt_.solstat[0] = '\0'; + filopt_.trace[0] = '\0'; + elmask_ = 15.0; + elmaskar_ = 0.0; + elmaskhold_ = 0.0; + for (i = 0; i < 2; i++) + for (j = 0; j < 3; j++) { + antpos_[i][j] = 0.0; } - exsats_[0] ='\0'; + exsats_[0] = '\0'; } /* get system options ---------------------------------------------------------- -* get system options -* args : prcopt_t *popt IO processing options (NULL: no output) -* solopt_t *sopt IO solution options (NULL: no output) -* folopt_t *fopt IO file options (NULL: no output) -* return : none -* notes : to load system options, use loadopts() before calling the function -*-----------------------------------------------------------------------------*/ -extern void getsysopts(prcopt_t *popt, solopt_t *sopt, filopt_t *fopt) -{ - trace(3,"getsysopts:\n"); - - buff2sysopts(); - if (popt) *popt=prcopt_; - if (sopt) *sopt=solopt_; - if (fopt) *fopt=filopt_; + * get system options + * args : prcopt_t *popt IO processing options (NULL: no output) + * solopt_t *sopt IO solution options (NULL: no output) + * folopt_t *fopt IO file options (NULL: no output) + * return : none + * notes : to load system options, use loadopts() before calling the function + *-----------------------------------------------------------------------------*/ +extern void getsysopts(prcopt_t *popt, solopt_t *sopt, filopt_t *fopt) { + trace(3, "getsysopts:\n"); + + buff2sysopts(); + if (popt) *popt = prcopt_; + if (sopt) *sopt = solopt_; + if (fopt) *fopt = filopt_; } /* set system options ---------------------------------------------------------- -* set system options -* args : prcopt_t *prcopt I processing options (NULL: default) -* solopt_t *solopt I solution options (NULL: default) -* filopt_t *filopt I file options (NULL: default) -* return : none -* notes : to save system options, use saveopts() after calling the function -*-----------------------------------------------------------------------------*/ -extern void setsysopts(const prcopt_t *prcopt, const solopt_t *solopt, - const filopt_t *filopt) -{ - trace(3,"setsysopts:\n"); - - resetsysopts(); - if (prcopt) prcopt_=*prcopt; - if (solopt) solopt_=*solopt; - if (filopt) filopt_=*filopt; - sysopts2buff(); + * set system options + * args : prcopt_t *prcopt I processing options (NULL: default) + * solopt_t *solopt I solution options (NULL: default) + * filopt_t *filopt I file options (NULL: default) + * return : none + * notes : to save system options, use saveopts() after calling the function + *-----------------------------------------------------------------------------*/ +extern void setsysopts(const prcopt_t *prcopt, const solopt_t *solopt, const filopt_t *filopt) { + trace(3, "setsysopts:\n"); + + resetsysopts(); + if (prcopt) prcopt_ = *prcopt; + if (solopt) solopt_ = *solopt; + if (filopt) filopt_ = *filopt; + sysopts2buff(); } diff --git a/src/pntpos.c b/src/pntpos.c index 70f6c2457..032e0e1ff 100644 --- a/src/pntpos.c +++ b/src/pntpos.c @@ -1,722 +1,758 @@ /*------------------------------------------------------------------------------ -* pntpos.c : standard positioning -* -* Copyright (C) 2007-2020 by T.TAKASU, All rights reserved. -* -* version : $Revision:$ $Date:$ -* history : 2010/07/28 1.0 moved from rtkcmn.c -* changed api: -* pntpos() -* deleted api: -* pntvel() -* 2011/01/12 1.1 add option to include unhealthy satellite -* reject duplicated observation data -* changed api: ionocorr() -* 2011/11/08 1.2 enable snr mask for single-mode (rtklib_2.4.1_p3) -* 2012/12/25 1.3 add variable snr mask -* 2014/05/26 1.4 support galileo and beidou -* 2015/03/19 1.5 fix bug on ionosphere correction for GLO and BDS -* 2018/10/10 1.6 support api change of satexclude() -* 2020/11/30 1.7 support NavIC/IRNSS in pntpos() -* no support IONOOPT_LEX option in ioncorr() -* improve handling of TGD correction for each system -* use E1-E5b for Galileo dual-freq iono-correction -* use API sat2freq() to get carrier frequency -* add output of velocity estimation error in estvel() -*-----------------------------------------------------------------------------*/ + * pntpos.c : standard positioning + * + * Copyright (C) 2007-2020 by T.TAKASU, All rights reserved. + * + * version : $Revision:$ $Date:$ + * history : 2010/07/28 1.0 moved from rtkcmn.c + * changed api: + * pntpos() + * deleted api: + * pntvel() + * 2011/01/12 1.1 add option to include unhealthy satellite + * reject duplicated observation data + * changed api: ionocorr() + * 2011/11/08 1.2 enable snr mask for single-mode (rtklib_2.4.1_p3) + * 2012/12/25 1.3 add variable snr mask + * 2014/05/26 1.4 support galileo and beidou + * 2015/03/19 1.5 fix bug on ionosphere correction for GLO and BDS + * 2018/10/10 1.6 support api change of satexclude() + * 2020/11/30 1.7 support NavIC/IRNSS in pntpos() + * no support IONOOPT_LEX option in ioncorr() + * improve handling of TGD correction for each system + * use E1-E5b for Galileo dual-freq iono-correction + * use API sat2freq() to get carrier frequency + * add output of velocity estimation error in estvel() + *-----------------------------------------------------------------------------*/ #include "rtklib.h" /* constants/macros ----------------------------------------------------------*/ -#define SQR(x) ((x)*(x)) -#define MAX(x,y) ((x)>=(y)?(x):(y)) +#define SQR(x) ((x) * (x)) +#define MAX(x, y) ((x) >= (y) ? (x) : (y)) #define QZSDT /* enable GPS-QZS time offset estimation */ #ifdef QZSDT -#define NX (4+5) /* # of estimated parameters */ +#define NX (4 + 5) /* # of estimated parameters */ #else -#define NX (4+4) /* # of estimated parameters */ +#define NX (4 + 4) /* # of estimated parameters */ #endif -#define MAXITR 10 /* max number of iteration for point pos */ -#define ERR_ION 5.0 /* ionospheric delay Std (m) */ -#define ERR_TROP 3.0 /* tropspheric delay Std (m) */ -#define ERR_SAAS 0.3 /* Saastamoinen model error Std (m) */ -#define ERR_BRDCI 0.5 /* broadcast ionosphere model error factor */ -#define ERR_CBIAS 0.3 /* code bias error Std (m) */ -#define REL_HUMI 0.7 /* relative humidity for Saastamoinen model */ -#define MIN_EL (5.0*D2R) /* min elevation for measurement error (rad) */ -# define MAX_GDOP 30 /* max gdop for valid solution */ +#define MAXITR 10 /* max number of iteration for point pos */ +#define ERR_ION 5.0 /* ionospheric delay Std (m) */ +#define ERR_TROP 3.0 /* tropspheric delay Std (m) */ +#define ERR_SAAS 0.3 /* Saastamoinen model error Std (m) */ +#define ERR_BRDCI 0.5 /* broadcast ionosphere model error factor */ +#define ERR_CBIAS 0.3 /* code bias error Std (m) */ +#define REL_HUMI 0.7 /* relative humidity for Saastamoinen model */ +#define MIN_EL (5.0 * D2R) /* min elevation for measurement error (rad) */ +#define MAX_GDOP 30 /* max gdop for valid solution */ /* pseudorange measurement error variance ------------------------------------*/ -static double varerr(const prcopt_t *opt, const obsd_t *obs, double el, int sys) -{ - double fact=1.0,varr; - - switch (sys) { - case SYS_GPS: fact *= EFACT_GPS; break; - case SYS_GLO: fact *= EFACT_GLO; break; - case SYS_SBS: fact *= EFACT_SBS; break; - case SYS_CMP: fact *= EFACT_CMP; break; - case SYS_QZS: fact *= EFACT_QZS; break; - case SYS_IRN: fact *= EFACT_IRN; break; - default: fact *= EFACT_GPS; break; - } - if (elerr[1])+SQR(opt->err[2])/sin(el); - if (opt->err[6]>0.0) { /* if snr term not zero */ - varr+=SQR(opt->err[6])*pow(10,0.1*MAX(opt->err[5]-obs->SNR[0],0)); - } - varr*=SQR(opt->eratio[0]); - if (opt->err[7]>0.0) { - varr+=SQR(opt->err[7]*obs->Pstd[0]); - } - if (opt->ionoopt==IONOOPT_IFLC) varr*=SQR(3.0); /* iono-free */ - return SQR(fact)*varr; +static double varerr(const prcopt_t *opt, const obsd_t *obs, double el, int sys) { + double fact = 1.0, varr; + + switch (sys) { + case SYS_GPS: + fact *= EFACT_GPS; + break; + case SYS_GLO: + fact *= EFACT_GLO; + break; + case SYS_SBS: + fact *= EFACT_SBS; + break; + case SYS_CMP: + fact *= EFACT_CMP; + break; + case SYS_QZS: + fact *= EFACT_QZS; + break; + case SYS_IRN: + fact *= EFACT_IRN; + break; + default: + fact *= EFACT_GPS; + break; + } + if (el < MIN_EL) el = MIN_EL; + /* var = R^2*(a^2 + (b^2/sin(el) + c^2*(10^(0.1*(snr_max-snr)))) + (d*rcv_std)^2) */ + varr = SQR(opt->err[1]) + SQR(opt->err[2]) / sin(el); + if (opt->err[6] > 0.0) { /* if snr term not zero */ + varr += SQR(opt->err[6]) * pow(10, 0.1 * MAX(opt->err[5] - obs->SNR[0], 0)); + } + varr *= SQR(opt->eratio[0]); + if (opt->err[7] > 0.0) { + varr += SQR(opt->err[7] * obs->Pstd[0]); + } + if (opt->ionoopt == IONOOPT_IFLC) varr *= SQR(3.0); /* iono-free */ + return SQR(fact) * varr; } /* get group delay parameter (m) ---------------------------------------------*/ -static double gettgd(int sat, const nav_t *nav, int type) -{ - int i,sys=satsys(sat,NULL); - - if (sys==SYS_GLO) { - for (i=0;ing;i++) { - if (nav->geph[i].sat==sat) break; - } - return (i>=nav->ng)?0.0:-nav->geph[i].dtaun*CLIGHT; +static double gettgd(int sat, const nav_t *nav, int type) { + int i, sys = satsys(sat, NULL); + + if (sys == SYS_GLO) { + for (i = 0; i < nav->ng; i++) { + if (nav->geph[i].sat == sat) break; } - else { - for (i=0;in;i++) { - if (nav->eph[i].sat==sat) break; - } - return (i>=nav->n)?0.0:nav->eph[i].tgd[type]*CLIGHT; + return (i >= nav->ng) ? 0.0 : -nav->geph[i].dtaun * CLIGHT; + } else { + for (i = 0; i < nav->n; i++) { + if (nav->eph[i].sat == sat) break; } + return (i >= nav->n) ? 0.0 : nav->eph[i].tgd[type] * CLIGHT; + } } /* test SNR mask -------------------------------------------------------------*/ -static int snrmask(const obsd_t *obs, const double *azel, const prcopt_t *opt) -{ - int f2; +static int snrmask(const obsd_t *obs, const double *azel, const prcopt_t *opt) { + int f2; - if (testsnr(0,0,azel[1],obs->SNR[0],&opt->snrmask)) { - return 0; - } - if (opt->ionoopt==IONOOPT_IFLC) { - f2=seliflc(opt->nf,satsys(obs->sat,NULL)); - if (testsnr(0,f2,azel[1],obs->SNR[f2],&opt->snrmask)) return 0; - } - return 1; + if (testsnr(0, 0, azel[1], obs->SNR[0], &opt->snrmask)) { + return 0; + } + if (opt->ionoopt == IONOOPT_IFLC) { + f2 = seliflc(opt->nf, satsys(obs->sat, NULL)); + if (testsnr(0, f2, azel[1], obs->SNR[f2], &opt->snrmask)) return 0; + } + return 1; } /* iono-free or "pseudo iono-free" pseudorange with code bias correction -----*/ -static double prange(const obsd_t *obs, const nav_t *nav, const prcopt_t *opt, - double *var) -{ - double P1,P2,gamma,b1,b2; - int sat,sys,f2,bias_ix; - - sat=obs->sat; - sys=satsys(sat,NULL); - P1=obs->P[0]; - f2=seliflc(opt->nf,satsys(obs->sat,NULL)); - P2=obs->P[f2]; - *var=0.0; - - if (P1==0.0||(opt->ionoopt==IONOOPT_IFLC&&P2==0.0)) return 0.0; - bias_ix=code2bias_ix(sys,obs->code[0]); /* L1 code bias */ - if (bias_ix>0) { /* 0=ref code */ - P1+=nav->cbias[sat-1][0][bias_ix-1]; - } - /* GPS code biases are L1/L2, Galileo are L1/L5 */ - if (sys==SYS_GAL&&f2==1) { - /* skip code bias, no GAL L2 bias available */ - } - else { /* apply L2 or L5 code bias */ - bias_ix=code2bias_ix(sys,obs->code[f2]); - if (bias_ix>0) { /* 0=ref code */ - P2+=nav->cbias[sat-1][1][bias_ix-1]; /* L2 or L5 code bias */ - } - } - if (opt->ionoopt==IONOOPT_IFLC) { /* dual-frequency */ - - if (sys==SYS_GPS||sys==SYS_QZS) { /* L1-L2 or L1-L5 */ - gamma=f2==1?SQR(FREQL1/FREQL2):SQR(FREQL1/FREQL5); - return (P2-gamma*P1)/(1.0-gamma); - } - else if (sys==SYS_GLO) { /* G1-G2 or G1-G3 */ - gamma=f2==1?SQR(FREQ1_GLO/FREQ2_GLO):SQR(FREQ1_GLO/FREQ3_GLO); - return (P2-gamma*P1)/(1.0-gamma); - } - else if (sys==SYS_GAL) { /* E1-E5b, E1-E5a */ - gamma=f2==1?SQR(FREQL1/FREQE5b):SQR(FREQL1/FREQL5); - if (f2==1&&getseleph(SYS_GAL)) { /* F/NAV */ - P2-=gettgd(sat,nav,0)-gettgd(sat,nav,1); /* BGD_E5aE5b */ - } - return (P2-gamma*P1)/(1.0-gamma); - } - else if (sys==SYS_CMP) { /* B1-B2 */ - gamma=SQR(((obs->code[0]==CODE_L2I)?FREQ1_CMP:FREQL1)/FREQ2_CMP); - if (obs->code[0]==CODE_L2I) b1=gettgd(sat,nav,0); /* TGD_B1I */ - else if (obs->code[0]==CODE_L1P) b1=gettgd(sat,nav,2); /* TGD_B1Cp */ - else b1=gettgd(sat,nav,2)+gettgd(sat,nav,4); /* TGD_B1Cp+ISC_B1Cd */ - b2=gettgd(sat,nav,1); /* TGD_B2I/B2bI (m) */ - return ((P2-gamma*P1)-(b2-gamma*b1))/(1.0-gamma); - } - else if (sys==SYS_IRN) { /* L5-S */ - gamma=SQR(FREQL5/FREQs); - return (P2-gamma*P1)/(1.0-gamma); - } - } - else { /* single-freq (L1/E1/B1) */ - *var=SQR(ERR_CBIAS); - - if (sys==SYS_GPS||sys==SYS_QZS) { /* L1 */ - b1=gettgd(sat,nav,0); /* TGD (m) */ - return P1-b1; - } - else if (sys==SYS_GLO) { /* G1 */ - gamma=SQR(FREQ1_GLO/FREQ2_GLO); - b1=gettgd(sat,nav,0); /* -dtaun (m) */ - return P1-b1/(gamma-1.0); - } - else if (sys==SYS_GAL) { /* E1 */ - if (getseleph(SYS_GAL)) b1=gettgd(sat,nav,0); /* BGD_E1E5a */ - else b1=gettgd(sat,nav,1); /* BGD_E1E5b */ - return P1-b1; - } - else if (sys==SYS_CMP) { /* B1I/B1Cp/B1Cd */ - if (obs->code[0]==CODE_L2I) b1=gettgd(sat,nav,0); /* TGD_B1I */ - else if (obs->code[0]==CODE_L1P) b1=gettgd(sat,nav,2); /* TGD_B1Cp */ - else b1=gettgd(sat,nav,2)+gettgd(sat,nav,4); /* TGD_B1Cp+ISC_B1Cd */ - return P1-b1; - } - else if (sys==SYS_IRN) { /* L5 */ - gamma=SQR(FREQs/FREQL5); - b1=gettgd(sat,nav,0); /* TGD (m) */ - return P1-gamma*b1; - } - } - return P1; +static double prange(const obsd_t *obs, const nav_t *nav, const prcopt_t *opt, double *var) { + double P1, P2, gamma, b1, b2; + int sat, sys, f2, bias_ix; + + sat = obs->sat; + sys = satsys(sat, NULL); + P1 = obs->P[0]; + f2 = seliflc(opt->nf, satsys(obs->sat, NULL)); + P2 = obs->P[f2]; + *var = 0.0; + + if (P1 == 0.0 || (opt->ionoopt == IONOOPT_IFLC && P2 == 0.0)) return 0.0; + bias_ix = code2bias_ix(sys, obs->code[0]); /* L1 code bias */ + if (bias_ix > 0) { /* 0=ref code */ + P1 += nav->cbias[sat - 1][0][bias_ix - 1]; + } + /* GPS code biases are L1/L2, Galileo are L1/L5 */ + if (sys == SYS_GAL && f2 == 1) { + /* skip code bias, no GAL L2 bias available */ + } else { /* apply L2 or L5 code bias */ + bias_ix = code2bias_ix(sys, obs->code[f2]); + if (bias_ix > 0) { /* 0=ref code */ + P2 += nav->cbias[sat - 1][1][bias_ix - 1]; /* L2 or L5 code bias */ + } + } + if (opt->ionoopt == IONOOPT_IFLC) { /* dual-frequency */ + + if (sys == SYS_GPS || sys == SYS_QZS) { /* L1-L2 or L1-L5 */ + gamma = f2 == 1 ? SQR(FREQL1 / FREQL2) : SQR(FREQL1 / FREQL5); + return (P2 - gamma * P1) / (1.0 - gamma); + } else if (sys == SYS_GLO) { /* G1-G2 or G1-G3 */ + gamma = f2 == 1 ? SQR(FREQ1_GLO / FREQ2_GLO) : SQR(FREQ1_GLO / FREQ3_GLO); + return (P2 - gamma * P1) / (1.0 - gamma); + } else if (sys == SYS_GAL) { /* E1-E5b, E1-E5a */ + gamma = f2 == 1 ? SQR(FREQL1 / FREQE5b) : SQR(FREQL1 / FREQL5); + if (f2 == 1 && getseleph(SYS_GAL)) { /* F/NAV */ + P2 -= gettgd(sat, nav, 0) - gettgd(sat, nav, 1); /* BGD_E5aE5b */ + } + return (P2 - gamma * P1) / (1.0 - gamma); + } else if (sys == SYS_CMP) { /* B1-B2 */ + gamma = SQR(((obs->code[0] == CODE_L2I) ? FREQ1_CMP : FREQL1) / FREQ2_CMP); + if (obs->code[0] == CODE_L2I) + b1 = gettgd(sat, nav, 0); /* TGD_B1I */ + else if (obs->code[0] == CODE_L1P) + b1 = gettgd(sat, nav, 2); /* TGD_B1Cp */ + else + b1 = gettgd(sat, nav, 2) + gettgd(sat, nav, 4); /* TGD_B1Cp+ISC_B1Cd */ + b2 = gettgd(sat, nav, 1); /* TGD_B2I/B2bI (m) */ + return ((P2 - gamma * P1) - (b2 - gamma * b1)) / (1.0 - gamma); + } else if (sys == SYS_IRN) { /* L5-S */ + gamma = SQR(FREQL5 / FREQs); + return (P2 - gamma * P1) / (1.0 - gamma); + } + } else { /* single-freq (L1/E1/B1) */ + *var = SQR(ERR_CBIAS); + + if (sys == SYS_GPS || sys == SYS_QZS) { /* L1 */ + b1 = gettgd(sat, nav, 0); /* TGD (m) */ + return P1 - b1; + } else if (sys == SYS_GLO) { /* G1 */ + gamma = SQR(FREQ1_GLO / FREQ2_GLO); + b1 = gettgd(sat, nav, 0); /* -dtaun (m) */ + return P1 - b1 / (gamma - 1.0); + } else if (sys == SYS_GAL) { /* E1 */ + if (getseleph(SYS_GAL)) + b1 = gettgd(sat, nav, 0); /* BGD_E1E5a */ + else + b1 = gettgd(sat, nav, 1); /* BGD_E1E5b */ + return P1 - b1; + } else if (sys == SYS_CMP) { /* B1I/B1Cp/B1Cd */ + if (obs->code[0] == CODE_L2I) + b1 = gettgd(sat, nav, 0); /* TGD_B1I */ + else if (obs->code[0] == CODE_L1P) + b1 = gettgd(sat, nav, 2); /* TGD_B1Cp */ + else + b1 = gettgd(sat, nav, 2) + gettgd(sat, nav, 4); /* TGD_B1Cp+ISC_B1Cd */ + return P1 - b1; + } else if (sys == SYS_IRN) { /* L5 */ + gamma = SQR(FREQs / FREQL5); + b1 = gettgd(sat, nav, 0); /* TGD (m) */ + return P1 - gamma * b1; + } + } + return P1; } /* ionospheric correction ------------------------------------------------------ -* compute ionospheric correction -* args : gtime_t time I time -* nav_t *nav I navigation data -* int sat I satellite number -* double *pos I receiver position {lat,lon,h} (rad|m) -* double *azel I azimuth/elevation angle {az,el} (rad) -* int ionoopt I ionospheric correction option (IONOOPT_???) -* double *ion O ionospheric delay (L1) (m) -* double *var O ionospheric delay (L1) variance (m^2) -* return : status(1:ok,0:error) -*-----------------------------------------------------------------------------*/ -extern int ionocorr(gtime_t time, const nav_t *nav, int sat, const double *pos, - const double *azel, int ionoopt, double *ion, double *var) -{ - int err=0; - - char tstr[40]; - trace(4,"ionocorr: time=%s opt=%d sat=%2d pos=%.3f %.3f azel=%.3f %.3f\n", - time2str(time,tstr,3),ionoopt,sat,pos[0]*R2D,pos[1]*R2D,azel[0]*R2D, - azel[1]*R2D); - - /* SBAS ionosphere model */ - if (ionoopt==IONOOPT_SBAS) { - if (sbsioncorr(time,nav,pos,azel,ion,var)) return 1; - err=1; - } - /* IONEX TEC model */ - if (ionoopt==IONOOPT_TEC) { - if (iontec(time,nav,pos,azel,1,ion,var)) return 1; - err=1; - } - /* QZSS broadcast ionosphere model */ - if (ionoopt==IONOOPT_QZS&&norm(nav->ion_qzs,8)>0.0) { - *ion=ionmodel(time,nav->ion_qzs,pos,azel); - *var=SQR(*ion*ERR_BRDCI); - return 1; - } - /* GPS broadcast ionosphere model */ - if (ionoopt==IONOOPT_BRDC||err==1) { - *ion=ionmodel(time,nav->ion_gps,pos,azel); - *var=SQR(*ion*ERR_BRDCI); - return 1; - } - *ion=0.0; - *var=ionoopt==IONOOPT_OFF?SQR(ERR_ION):0.0; + * compute ionospheric correction + * args : gtime_t time I time + * nav_t *nav I navigation data + * int sat I satellite number + * double *pos I receiver position {lat,lon,h} (rad|m) + * double *azel I azimuth/elevation angle {az,el} (rad) + * int ionoopt I ionospheric correction option (IONOOPT_???) + * double *ion O ionospheric delay (L1) (m) + * double *var O ionospheric delay (L1) variance (m^2) + * return : status(1:ok,0:error) + *-----------------------------------------------------------------------------*/ +extern int ionocorr(gtime_t time, const nav_t *nav, int sat, const double *pos, const double *azel, + int ionoopt, double *ion, double *var) { + int err = 0; + + char tstr[40]; + trace(4, "ionocorr: time=%s opt=%d sat=%2d pos=%.3f %.3f azel=%.3f %.3f\n", + time2str(time, tstr, 3), ionoopt, sat, pos[0] * R2D, pos[1] * R2D, azel[0] * R2D, + azel[1] * R2D); + + /* SBAS ionosphere model */ + if (ionoopt == IONOOPT_SBAS) { + if (sbsioncorr(time, nav, pos, azel, ion, var)) return 1; + err = 1; + } + /* IONEX TEC model */ + if (ionoopt == IONOOPT_TEC) { + if (iontec(time, nav, pos, azel, 1, ion, var)) return 1; + err = 1; + } + /* QZSS broadcast ionosphere model */ + if (ionoopt == IONOOPT_QZS && norm(nav->ion_qzs, 8) > 0.0) { + *ion = ionmodel(time, nav->ion_qzs, pos, azel); + *var = SQR(*ion * ERR_BRDCI); + return 1; + } + /* GPS broadcast ionosphere model */ + if (ionoopt == IONOOPT_BRDC || err == 1) { + *ion = ionmodel(time, nav->ion_gps, pos, azel); + *var = SQR(*ion * ERR_BRDCI); return 1; + } + *ion = 0.0; + *var = ionoopt == IONOOPT_OFF ? SQR(ERR_ION) : 0.0; + return 1; } /* tropospheric correction ----------------------------------------------------- -* compute tropospheric correction -* args : gtime_t time I time -* nav_t *nav I navigation data -* double *pos I receiver position {lat,lon,h} (rad|m) -* double *azel I azimuth/elevation angle {az,el} (rad) -* int tropopt I tropospheric correction option (TROPOPT_???) -* double *trp O tropospheric delay (m) -* double *var O tropospheric delay variance (m^2) -* return : status(1:ok,0:error) -*-----------------------------------------------------------------------------*/ -extern int tropcorr(gtime_t time, const nav_t *nav, const double *pos, - const double *azel, int tropopt, double *trp, double *var) -{ - (void)nav; - char tstr[40]; - trace(4,"tropcorr: time=%s opt=%d pos=%.3f %.3f azel=%.3f %.3f\n", - time2str(time,tstr,3),tropopt,pos[0]*R2D,pos[1]*R2D,azel[0]*R2D, - azel[1]*R2D); - - /* Saastamoinen model */ - if (tropopt==TROPOPT_SAAS||tropopt==TROPOPT_EST||tropopt==TROPOPT_ESTG) { - *trp=tropmodel(time,pos,azel,REL_HUMI); - *var=SQR(ERR_SAAS/(sin(azel[1])+0.1)); - return 1; - } - /* SBAS (MOPS) troposphere model */ - if (tropopt==TROPOPT_SBAS) { - *trp=sbstropcorr(time,pos,azel,var); - return 1; - } - /* no correction */ - *trp=0.0; - *var=tropopt==TROPOPT_OFF?SQR(ERR_TROP):0.0; + * compute tropospheric correction + * args : gtime_t time I time + * nav_t *nav I navigation data + * double *pos I receiver position {lat,lon,h} (rad|m) + * double *azel I azimuth/elevation angle {az,el} (rad) + * int tropopt I tropospheric correction option (TROPOPT_???) + * double *trp O tropospheric delay (m) + * double *var O tropospheric delay variance (m^2) + * return : status(1:ok,0:error) + *-----------------------------------------------------------------------------*/ +extern int tropcorr(gtime_t time, const nav_t *nav, const double *pos, const double *azel, + int tropopt, double *trp, double *var) { + (void)nav; + char tstr[40]; + trace(4, "tropcorr: time=%s opt=%d pos=%.3f %.3f azel=%.3f %.3f\n", time2str(time, tstr, 3), + tropopt, pos[0] * R2D, pos[1] * R2D, azel[0] * R2D, azel[1] * R2D); + + /* Saastamoinen model */ + if (tropopt == TROPOPT_SAAS || tropopt == TROPOPT_EST || tropopt == TROPOPT_ESTG) { + *trp = tropmodel(time, pos, azel, REL_HUMI); + *var = SQR(ERR_SAAS / (sin(azel[1]) + 0.1)); return 1; + } + /* SBAS (MOPS) troposphere model */ + if (tropopt == TROPOPT_SBAS) { + *trp = sbstropcorr(time, pos, azel, var); + return 1; + } + /* no correction */ + *trp = 0.0; + *var = tropopt == TROPOPT_OFF ? SQR(ERR_TROP) : 0.0; + return 1; } /* pseudorange residuals -----------------------------------------------------*/ -static int rescode(int iter, const obsd_t *obs, int n, const double *rs, - const double *dts, const double *vare, const int *svh, - const nav_t *nav, const double *x, const prcopt_t *opt, - const ssat_t *ssat, double *v, double *H, double *var, - double *azel, int *vsat, double *resp, int *ns) -{ - gtime_t time; - double r,freq,dion=0.0,dtrp=0.0,vmeas,vion=0.0,vtrp=0.0,rr[3],pos[3],dtr,e[3],P; - int i,j,nv=0,sat,sys,mask[NX-3]={0}; - - for (i=0;i<3;i++) rr[i]=x[i]; - dtr=x[3]; - - ecef2pos(rr,pos); - trace(3,"rescode: rr=%.3f %.3f %.3f\n",rr[0], rr[1], rr[2]); - - for (i=*ns=0;ielmin) continue; - - if (iter>0) { - /* test SNR mask */ - if (!snrmask(obs+i,azel+i*2,opt)) continue; - - /* ionospheric correction */ - if (!ionocorr(time,nav,sat,pos,azel+i*2,opt->ionoopt,&dion,&vion)) { - continue; - } - if ((freq=sat2freq(sat,obs[i].code[0],nav))==0.0) continue; - /* Convert from FREQL1 to freq */ - dion*=SQR(FREQL1/freq); - vion*=SQR(SQR(FREQL1/freq)); - - /* tropospheric correction */ - if (!tropcorr(time,nav,pos,azel+i*2,opt->tropopt,&dtrp,&vtrp)) { - continue; - } - } - /* pseudorange with code bias correction */ - if ((P=prange(obs+i,nav,opt,&vmeas))==0.0) continue; - - /* pseudorange residual */ - v[nv]=P-(r+dtr-CLIGHT*dts[i*2]+dion+dtrp); - trace(4,"sat=%d: v=%.3f P=%.3f r=%.3f dtr=%.6f dts=%.6f dion=%.3f dtrp=%.3f\n", - sat,v[nv],P,r,dtr,dts[i*2],dion,dtrp); - - /* design matrix */ - for (j=0;jelmin) continue; + + if (iter > 0) { + /* test SNR mask */ + if (!snrmask(obs + i, azel + i * 2, opt)) continue; + + /* ionospheric correction */ + if (!ionocorr(time, nav, sat, pos, azel + i * 2, opt->ionoopt, &dion, &vion)) { + continue; + } + if ((freq = sat2freq(sat, obs[i].code[0], nav)) == 0.0) continue; + /* Convert from FREQL1 to freq */ + dion *= SQR(FREQL1 / freq); + vion *= SQR(SQR(FREQL1 / freq)); + + /* tropospheric correction */ + if (!tropcorr(time, nav, pos, azel + i * 2, opt->tropopt, &dtrp, &vtrp)) { + continue; + } + } + /* pseudorange with code bias correction */ + if ((P = prange(obs + i, nav, opt, &vmeas)) == 0.0) continue; + + /* pseudorange residual */ + v[nv] = P - (r + dtr - CLIGHT * dts[i * 2] + dion + dtrp); + trace(4, "sat=%d: v=%.3f P=%.3f r=%.3f dtr=%.6f dts=%.6f dion=%.3f dtrp=%.3f\n", sat, v[nv], P, + r, dtr, dts[i * 2], dion, dtrp); + + /* design matrix */ + for (j = 0; j < NX; j++) { + H[j + nv * NX] = j < 3 ? -e[j] : (j == 3 ? 1.0 : 0.0); + } + /* time system offset and receiver bias correction */ + if (sys == SYS_GLO) { + v[nv] -= x[4]; + H[4 + nv * NX] = 1.0; + mask[1] = 1; + } else if (sys == SYS_GAL) { + v[nv] -= x[5]; + H[5 + nv * NX] = 1.0; + mask[2] = 1; + } else if (sys == SYS_CMP) { + v[nv] -= x[6]; + H[6 + nv * NX] = 1.0; + mask[3] = 1; + } else if (sys == SYS_IRN) { + v[nv] -= x[7]; + H[7 + nv * NX] = 1.0; + mask[4] = 1; } - /* constraint to avoid rank-deficient */ - for (i=0;inx&&vv>chisqr[nv-nx-1]) { - sprintf(msg,"Warning: large chi-square error nv=%d vv=%.1f cs=%.1f",nv,vv,chisqr[nv-nx-1]); - /* return 0; */ /* threshold too strict for all use cases, report error but continue on */ - } - /* large GDOP check */ - for (i=ns=0;ielmin,dop); - if (dop[0]<=0.0||dop[0]>MAX_GDOP) { - sprintf(msg,"gdop error nv=%d gdop=%.1f",nv,dop[0]); - return 0; - } - return 1; +static int valsol(const double *azel, const int *vsat, int n, const prcopt_t *opt, const double *v, + int nv, int nx, char *msg) { + double azels[MAXOBS * 2], dop[4], vv; + int i, ns; + + trace(3, "valsol : n=%d nv=%d\n", n, nv); + + /* Chi-square validation of residuals */ + vv = dot(v, v, nv); + if (nv > nx && vv > chisqr[nv - nx - 1]) { + sprintf(msg, "Warning: large chi-square error nv=%d vv=%.1f cs=%.1f", nv, vv, + chisqr[nv - nx - 1]); + /* return 0; */ /* threshold too strict for all use cases, report error but continue on */ + } + /* large GDOP check */ + for (i = ns = 0; i < n; i++) { + if (!vsat[i]) continue; + azels[ns * 2] = azel[i * 2]; + azels[1 + ns * 2] = azel[1 + i * 2]; + ns++; + } + dops(ns, azels, opt->elmin, dop); + if (dop[0] <= 0.0 || dop[0] > MAX_GDOP) { + sprintf(msg, "gdop error nv=%d gdop=%.1f", nv, dop[0]); + return 0; + } + return 1; } /* estimate receiver position ------------------------------------------------*/ -static int estpos(const obsd_t *obs, int n, const double *rs, const double *dts, - const double *vare, const int *svh, const nav_t *nav, - const prcopt_t *opt, const ssat_t *ssat, sol_t *sol, double *azel, - int *vsat, double *resp, char *msg) -{ - double x[NX]={0},dx[NX],Q[NX*NX],*v,*H,*var,sig; - int i,j,k,info,stat,nv,ns; - - trace(3,"estpos : n=%d\n",n); - - v=mat(n+NX-3,1); H=mat(NX,n+NX-3); var=mat(n+NX-3,1); - - for (i=0;i<3;i++) x[i]=sol->rr[i]; - - for (i=0;itype=0; - sol->time=timeadd(obs[0].time,-x[3]/CLIGHT); - sol->dtr[0]=x[3]/CLIGHT; /* receiver clock bias (s) */ - sol->dtr[1]=x[4]/CLIGHT; /* GLO-GPS time offset (s) */ - sol->dtr[2]=x[5]/CLIGHT; /* GAL-GPS time offset (s) */ - sol->dtr[3]=x[6]/CLIGHT; /* BDS-GPS time offset (s) */ - sol->dtr[4]=x[7]/CLIGHT; /* IRN-GPS time offset (s) */ +static int estpos(const obsd_t *obs, int n, const double *rs, const double *dts, const double *vare, + const int *svh, const nav_t *nav, const prcopt_t *opt, const ssat_t *ssat, + sol_t *sol, double *azel, int *vsat, double *resp, char *msg) { + double x[NX] = {0}, dx[NX], Q[NX * NX], *v, *H, *var, sig; + int i, j, k, info, stat, nv, ns; + + trace(3, "estpos : n=%d\n", n); + + v = mat(n + NX - 3, 1); + H = mat(NX, n + NX - 3); + var = mat(n + NX - 3, 1); + + for (i = 0; i < 3; i++) x[i] = sol->rr[i]; + + for (i = 0; i < MAXITR; i++) { + /* pseudorange residuals (m) */ + nv = + rescode(i, obs, n, rs, dts, vare, svh, nav, x, opt, ssat, v, H, var, azel, vsat, resp, &ns); + + if (nv < NX) { + sprintf(msg, "lack of valid sats ns=%d", nv); + break; + } + /* weight by variance (lsq uses sqrt of weight */ + for (j = 0; j < nv; j++) { + sig = sqrt(var[j]); + v[j] /= sig; + for (k = 0; k < NX; k++) H[k + j * NX] /= sig; + } + /* least square estimation */ + if ((info = lsq(H, v, NX, nv, dx, Q))) { + sprintf(msg, "lsq error info=%d", info); + break; + } + for (j = 0; j < NX; j++) { + x[j] += dx[j]; + } + if (norm(dx, NX) < 1E-4) { + sol->type = 0; + sol->time = timeadd(obs[0].time, -x[3] / CLIGHT); + sol->dtr[0] = x[3] / CLIGHT; /* receiver clock bias (s) */ + sol->dtr[1] = x[4] / CLIGHT; /* GLO-GPS time offset (s) */ + sol->dtr[2] = x[5] / CLIGHT; /* GAL-GPS time offset (s) */ + sol->dtr[3] = x[6] / CLIGHT; /* BDS-GPS time offset (s) */ + sol->dtr[4] = x[7] / CLIGHT; /* IRN-GPS time offset (s) */ #ifdef QZSDT - sol->dtr[5]=x[8]/CLIGHT; /* QZS-GPS time offset (s) */ + sol->dtr[5] = x[8] / CLIGHT; /* QZS-GPS time offset (s) */ #endif - for (j=0;j<6;j++) sol->rr[j]=j<3?x[j]:0.0; - for (j=0;j<3;j++) sol->qr[j]=(float)Q[j+j*NX]; - sol->qr[3]=(float)Q[1]; /* cov xy */ - sol->qr[4]=(float)Q[2+NX]; /* cov yz */ - sol->qr[5]=(float)Q[2]; /* cov zx */ - sol->ns=(uint8_t)ns; - sol->age=sol->ratio=0.0; - - /* validate solution */ - if ((stat=valsol(azel,vsat,n,opt,v,nv,NX,msg))) { - sol->stat=opt->sateph==EPHOPT_SBAS?SOLQ_SBAS:SOLQ_SINGLE; - } - free(v); free(H); free(var); - return stat; - } - } - if (i>=MAXITR) sprintf(msg,"iteration divergent i=%d",i); - - free(v); free(H); free(var); - return 0; + for (j = 0; j < 6; j++) sol->rr[j] = j < 3 ? x[j] : 0.0; + for (j = 0; j < 3; j++) sol->qr[j] = (float)Q[j + j * NX]; + sol->qr[3] = (float)Q[1]; /* cov xy */ + sol->qr[4] = (float)Q[2 + NX]; /* cov yz */ + sol->qr[5] = (float)Q[2]; /* cov zx */ + sol->ns = (uint8_t)ns; + sol->age = sol->ratio = 0.0; + + /* validate solution */ + if ((stat = valsol(azel, vsat, n, opt, v, nv, NX, msg))) { + sol->stat = opt->sateph == EPHOPT_SBAS ? SOLQ_SBAS : SOLQ_SINGLE; + } + free(v); + free(H); + free(var); + return stat; + } + } + if (i >= MAXITR) sprintf(msg, "iteration divergent i=%d", i); + + free(v); + free(H); + free(var); + return 0; } /* RAIM FDE (failure detection and exclusion) -------------------------------*/ -static int raim_fde(const obsd_t *obs, int n, const double *rs, - const double *dts, const double *vare, const int *svh, - const nav_t *nav, const prcopt_t *opt, const ssat_t *ssat, - sol_t *sol, double *azel, int *vsat, double *resp, char *msg) -{ - obsd_t *obs_e; - sol_t sol_e={{0}}; - char tstr[40],name[8],msg_e[128]; - double *rs_e,*dts_e,*vare_e,*azel_e,*resp_e,rms_e,rms=100.0; - int i,j,k,nvsat,stat=0,*svh_e,*vsat_e,sat=0; - - trace(3,"raim_fde: %s n=%2d\n",time2str(obs[0].time,tstr,0),n); - - if (!(obs_e=(obsd_t *)malloc(sizeof(obsd_t)*n))) return 0; - rs_e = mat(6,n); dts_e = mat(2,n); vare_e=mat(1,n); azel_e=zeros(2,n); - svh_e=imat(1,n); vsat_e=imat(1,n); resp_e=mat(1,n); - - for (i=0;irms) continue; - - /* save result */ - for (j=k=0;jeventime; - *sol=sol_e; - sat=obs[i].sat; - rms=rms_e; - vsat[i]=0; - strcpy(msg,msg_e); - } +static int raim_fde(const obsd_t *obs, int n, const double *rs, const double *dts, + const double *vare, const int *svh, const nav_t *nav, const prcopt_t *opt, + const ssat_t *ssat, sol_t *sol, double *azel, int *vsat, double *resp, + char *msg) { + obsd_t *obs_e; + sol_t sol_e = {{0}}; + char tstr[40], name[8], msg_e[128]; + double *rs_e, *dts_e, *vare_e, *azel_e, *resp_e, rms_e, rms = 100.0; + int i, j, k, nvsat, stat = 0, *svh_e, *vsat_e, sat = 0; + + trace(3, "raim_fde: %s n=%2d\n", time2str(obs[0].time, tstr, 0), n); + + if (!(obs_e = (obsd_t *)malloc(sizeof(obsd_t) * n))) return 0; + rs_e = mat(6, n); + dts_e = mat(2, n); + vare_e = mat(1, n); + azel_e = zeros(2, n); + svh_e = imat(1, n); + vsat_e = imat(1, n); + resp_e = mat(1, n); + + for (i = 0; i < n; i++) { + /* satellite exclusion */ + for (j = k = 0; j < n; j++) { + if (j == i) continue; + obs_e[k] = obs[j]; + matcpy(rs_e + 6 * k, rs + 6 * j, 6, 1); + matcpy(dts_e + 2 * k, dts + 2 * j, 2, 1); + vare_e[k] = vare[j]; + svh_e[k++] = svh[j]; + } + /* estimate receiver position without a satellite */ + if (!estpos(obs_e, n - 1, rs_e, dts_e, vare_e, svh_e, nav, opt, ssat, &sol_e, azel_e, vsat_e, + resp_e, msg_e)) { + trace(3, "raim_fde: exsat=%2d (%s)\n", obs[i].sat, msg); + continue; + } + for (j = nvsat = 0, rms_e = 0.0; j < n - 1; j++) { + if (!vsat_e[j]) continue; + rms_e += SQR(resp_e[j]); + nvsat++; + } + if (nvsat < 5) { + trace(3, "raim_fde: exsat=%2d lack of satellites nvsat=%2d\n", obs[i].sat, nvsat); + continue; + } + rms_e = sqrt(rms_e / nvsat); + + trace(3, "raim_fde: exsat=%2d rms=%8.3f\n", obs[i].sat, rms_e); + + if (rms_e > rms) continue; + + /* save result */ + for (j = k = 0; j < n; j++) { + if (j == i) continue; + matcpy(azel + 2 * j, azel_e + 2 * k, 2, 1); + vsat[j] = vsat_e[k]; + resp[j] = resp_e[k++]; + } + stat = 1; + sol_e.eventime = sol->eventime; + *sol = sol_e; + sat = obs[i].sat; + rms = rms_e; + vsat[i] = 0; + strcpy(msg, msg_e); + } #ifdef TRACE - if (stat) { - time2str(obs[0].time,tstr,2); satno2id(sat,name); - trace(2,"%s: %s excluded by raim\n",tstr+11,name); - } + if (stat) { + time2str(obs[0].time, tstr, 2); + satno2id(sat, name); + trace(2, "%s: %s excluded by raim\n", tstr + 11, name); + } #endif - free(obs_e); - free(rs_e ); free(dts_e ); free(vare_e); free(azel_e); - free(svh_e); free(vsat_e); free(resp_e); - return stat; + free(obs_e); + free(rs_e); + free(dts_e); + free(vare_e); + free(azel_e); + free(svh_e); + free(vsat_e); + free(resp_e); + return stat; } /* range rate residuals ------------------------------------------------------*/ -static int resdop(const obsd_t *obs, int n, const double *rs, const double *dts, - const nav_t *nav, const double *rr, const double *x, - const double *azel, const int *vsat, double err, double *v, - double *H) -{ - double freq,rate,pos[3],E[9],a[3],e[3],vs[3],cosel,sig; - int i,j,nv=0; - - trace(3,"resdop : n=%d\n",n); - - ecef2pos(rr,pos); xyz2enu(pos,E); - - for (i=0;ierr[4]; /* Doppler error (Hz) */ - int i,j,nv; - - v=mat(n,1); H=mat(4,n); - - for (i=0;irr,x,azel,vsat,err,v,H))<4) { - break; - } - /* least square estimation */ - if (lsq(H,v,4,nv,dx,Q)) break; - - for (j=0;j<4;j++) x[j]+=dx[j]; - - if (norm(dx,4)<1E-6) { - trace(3,"estvel : vx=%.3f vy=%.3f vz=%.3f, n=%d\n",x[0],x[1],x[2],n); - matcpy(sol->rr+3,x,3,1); - sol->qv[0]=(float)Q[0]; /* xx */ - sol->qv[1]=(float)Q[5]; /* yy */ - sol->qv[2]=(float)Q[10]; /* zz */ - sol->qv[3]=(float)Q[1]; /* xy */ - sol->qv[4]=(float)Q[6]; /* yz */ - sol->qv[5]=(float)Q[2]; /* zx */ - break; - } +static void estvel(const obsd_t *obs, int n, const double *rs, const double *dts, const nav_t *nav, + const prcopt_t *opt, sol_t *sol, const double *azel, const int *vsat) { + double x[4] = {0}, dx[4], Q[16], *v, *H; + double err = opt->err[4]; /* Doppler error (Hz) */ + int i, j, nv; + + v = mat(n, 1); + H = mat(4, n); + + for (i = 0; i < MAXITR; i++) { + /* range rate residuals (m/s) */ + if ((nv = resdop(obs, n, rs, dts, nav, sol->rr, x, azel, vsat, err, v, H)) < 4) { + break; } - free(v); free(H); + /* least square estimation */ + if (lsq(H, v, 4, nv, dx, Q)) break; + + for (j = 0; j < 4; j++) x[j] += dx[j]; + + if (norm(dx, 4) < 1E-6) { + trace(3, "estvel : vx=%.3f vy=%.3f vz=%.3f, n=%d\n", x[0], x[1], x[2], n); + matcpy(sol->rr + 3, x, 3, 1); + sol->qv[0] = (float)Q[0]; /* xx */ + sol->qv[1] = (float)Q[5]; /* yy */ + sol->qv[2] = (float)Q[10]; /* zz */ + sol->qv[3] = (float)Q[1]; /* xy */ + sol->qv[4] = (float)Q[6]; /* yz */ + sol->qv[5] = (float)Q[2]; /* zx */ + break; + } + } + free(v); + free(H); } /* single-point positioning ---------------------------------------------------- -* compute receiver position, velocity, clock bias by single-point positioning -* with pseudorange and doppler observables -* args : obsd_t *obs I observation data -* int n I number of observation data -* nav_t *nav I navigation data -* prcopt_t *opt I processing options -* sol_t *sol IO solution -* double *azel IO azimuth/elevation angle (rad) (NULL: no output) -* ssat_t *ssat IO satellite status (NULL: no output) -* char *msg O error message for error exit -* return : status(1:ok,0:error) -*-----------------------------------------------------------------------------*/ -extern int pntpos(const obsd_t *obs, int n, const nav_t *nav, - const prcopt_t *opt, sol_t *sol, double *azel, ssat_t *ssat, - char *msg) -{ - prcopt_t opt_=*opt; - double *rs,*dts,*var,*azel_,*resp; - int i,stat,vsat[MAXOBS]={0},svh[MAXOBS]; - - char tstr[40]; - trace(3,"pntpos : tobs=%s n=%d\n",time2str(obs[0].time,tstr,3),n); - - sol->stat=SOLQ_NONE; - - if (n<=0) { - strcpy(msg,"no observation data"); - return 0; - } - sol->time=obs[0].time; - msg[0]='\0'; - sol->eventime = obs[0].eventime; - - rs=mat(6,n); dts=mat(2,n); var=mat(1,n); azel_=zeros(2,n); resp=mat(1,n); - - if (ssat) { - for (i=0;itime,obs,n,nav,opt_.sateph,rs,dts,var,svh); - - /* estimate receiver position and time with pseudorange */ - stat=estpos(obs,n,rs,dts,var,svh,nav,&opt_,ssat,sol,azel_,vsat,resp,msg); - - /* RAIM FDE */ - if (!stat&&n>=6&&opt->posopt[4]) { - stat=raim_fde(obs,n,rs,dts,var,svh,nav,&opt_,ssat,sol,azel_,vsat,resp,msg); - } - /* estimate receiver velocity with Doppler */ - if (stat) { - estvel(obs,n,rs,dts,nav,&opt_,sol,azel_,vsat); - } - if (azel) { - for (i=0;istat = SOLQ_NONE; + + if (n <= 0) { + strcpy(msg, "no observation data"); + return 0; + } + sol->time = obs[0].time; + msg[0] = '\0'; + sol->eventime = obs[0].eventime; + + rs = mat(6, n); + dts = mat(2, n); + var = mat(1, n); + azel_ = zeros(2, n); + resp = mat(1, n); + + if (ssat) { + for (i = 0; i < MAXSAT; i++) { + ssat[i].snr_rover[0] = 0; + ssat[i].snr_base[0] = 0; } - free(rs); free(dts); free(var); free(azel_); free(resp); - return stat; + for (i = 0; i < n; i++) ssat[obs[i].sat - 1].snr_rover[0] = obs[i].SNR[0]; + } + + if (opt_.mode != PMODE_SINGLE) { /* for precise positioning */ + opt_.ionoopt = IONOOPT_BRDC; + opt_.tropopt = TROPOPT_SAAS; + } + /* satellite positions, velocities and clocks */ + satposs(sol->time, obs, n, nav, opt_.sateph, rs, dts, var, svh); + + /* estimate receiver position and time with pseudorange */ + stat = estpos(obs, n, rs, dts, var, svh, nav, &opt_, ssat, sol, azel_, vsat, resp, msg); + + /* RAIM FDE */ + if (!stat && n >= 6 && opt->posopt[4]) { + stat = raim_fde(obs, n, rs, dts, var, svh, nav, &opt_, ssat, sol, azel_, vsat, resp, msg); + } + /* estimate receiver velocity with Doppler */ + if (stat) { + estvel(obs, n, rs, dts, nav, &opt_, sol, azel_, vsat); + } + if (azel) { + for (i = 0; i < n * 2; i++) azel[i] = azel_[i]; + } + if (ssat) { + for (i = 0; i < MAXSAT; i++) { + ssat[i].vs = 0; + ssat[i].azel[0] = ssat[i].azel[1] = 0.0; + ssat[i].resp[0] = ssat[i].resc[0] = 0.0; + } + for (i = 0; i < n; i++) { + ssat[obs[i].sat - 1].azel[0] = azel_[i * 2]; + ssat[obs[i].sat - 1].azel[1] = azel_[1 + i * 2]; + if (!vsat[i]) continue; + ssat[obs[i].sat - 1].vs = 1; + ssat[obs[i].sat - 1].resp[0] = resp[i]; + } + } + free(rs); + free(dts); + free(var); + free(azel_); + free(resp); + return stat; } diff --git a/src/postpos.c b/src/postpos.c index e71780228..0de528806 100644 --- a/src/postpos.c +++ b/src/postpos.c @@ -1,1495 +1,1478 @@ /*------------------------------------------------------------------------------ -* postpos.c : post-processing positioning -* -* Copyright (C) 2007-2020 by T.TAKASU, All rights reserved. -* -* version : $Revision: 1.1 $ $Date: 2008/07/17 21:48:06 $ -* history : 2007/05/08 1.0 new -* 2008/06/16 1.1 support binary inputs -* 2009/01/02 1.2 support new rtk positioning api -* 2009/09/03 1.3 fix bug on combined mode of moving-baseline -* 2009/12/04 1.4 fix bug on obs data buffer overflow -* 2010/07/26 1.5 support ppp-kinematic and ppp-static -* support multiple sessions -* support sbas positioning -* changed api: -* postpos() -* deleted api: -* postposopt() -* 2010/08/16 1.6 fix bug sbas message synchronization (2.4.0_p4) -* 2010/12/09 1.7 support qzss lex and ssr corrections -* 2011/02/07 1.8 fix bug on sbas navigation data conflict -* 2011/03/22 1.9 add function reading g_tec file -* 2011/08/20 1.10 fix bug on freez if solstatic=single and combined -* 2011/09/15 1.11 add function reading stec file -* 2012/02/01 1.12 support keyword expansion of rtcm ssr corrections -* 2013/03/11 1.13 add function reading otl and erp data -* 2014/06/29 1.14 fix problem on overflow of # of satellites -* 2015/03/23 1.15 fix bug on ant type replacement by rinex header -* fix bug on combined filter for moving-base mode -* 2015/04/29 1.16 fix bug on reading rtcm ssr corrections -* add function to read satellite fcb -* add function to read stec and troposphere file -* add keyword replacement in dcb, erp and ionos file -* 2015/11/13 1.17 add support of L5 antenna phase center parameters -* add *.stec and *.trp file for ppp correction -* 2015/11/26 1.18 support opt->freqopt(disable L2) -* 2016/01/12 1.19 add carrier-phase bias correction by ssr -* 2016/07/31 1.20 fix error message problem in rnx2rtkp -* 2016/08/29 1.21 suppress warnings -* 2016/10/10 1.22 fix bug on identification of file fopt->blq -* 2017/06/13 1.23 add smoother of velocity solution -* 2020/11/30 1.24 use API sat2freq() to get carrier frequency -* fix bug on select best solution in static mode -* delete function to use L2 instead of L5 PCV -* writing solution file in binary mode -*-----------------------------------------------------------------------------*/ + * postpos.c : post-processing positioning + * + * Copyright (C) 2007-2020 by T.TAKASU, All rights reserved. + * + * version : $Revision: 1.1 $ $Date: 2008/07/17 21:48:06 $ + * history : 2007/05/08 1.0 new + * 2008/06/16 1.1 support binary inputs + * 2009/01/02 1.2 support new rtk positioning api + * 2009/09/03 1.3 fix bug on combined mode of moving-baseline + * 2009/12/04 1.4 fix bug on obs data buffer overflow + * 2010/07/26 1.5 support ppp-kinematic and ppp-static + * support multiple sessions + * support sbas positioning + * changed api: + * postpos() + * deleted api: + * postposopt() + * 2010/08/16 1.6 fix bug sbas message synchronization (2.4.0_p4) + * 2010/12/09 1.7 support qzss lex and ssr corrections + * 2011/02/07 1.8 fix bug on sbas navigation data conflict + * 2011/03/22 1.9 add function reading g_tec file + * 2011/08/20 1.10 fix bug on freez if solstatic=single and combined + * 2011/09/15 1.11 add function reading stec file + * 2012/02/01 1.12 support keyword expansion of rtcm ssr corrections + * 2013/03/11 1.13 add function reading otl and erp data + * 2014/06/29 1.14 fix problem on overflow of # of satellites + * 2015/03/23 1.15 fix bug on ant type replacement by rinex header + * fix bug on combined filter for moving-base mode + * 2015/04/29 1.16 fix bug on reading rtcm ssr corrections + * add function to read satellite fcb + * add function to read stec and troposphere file + * add keyword replacement in dcb, erp and ionos file + * 2015/11/13 1.17 add support of L5 antenna phase center parameters + * add *.stec and *.trp file for ppp correction + * 2015/11/26 1.18 support opt->freqopt(disable L2) + * 2016/01/12 1.19 add carrier-phase bias correction by ssr + * 2016/07/31 1.20 fix error message problem in rnx2rtkp + * 2016/08/29 1.21 suppress warnings + * 2016/10/10 1.22 fix bug on identification of file fopt->blq + * 2017/06/13 1.23 add smoother of velocity solution + * 2020/11/30 1.24 use API sat2freq() to get carrier frequency + * fix bug on select best solution in static mode + * delete function to use L2 instead of L5 PCV + * writing solution file in binary mode + *-----------------------------------------------------------------------------*/ #include "rtklib.h" -#define MIN(x,y) ((x)<(y)?(x):(y)) -#define SQRT(x) ((x)<=0.0||(x)!=(x)?0.0:sqrt(x)) +#define MIN(x, y) ((x) < (y) ? (x) : (y)) +#define SQRT(x) ((x) <= 0.0 || (x) != (x) ? 0.0 : sqrt(x)) -#define MAXPRCDAYS 100 /* max days of continuous processing */ -#define MAXINFILE 1000 /* max number of input files */ -#define MAXINVALIDTM 100 /* max number of invalid time marks */ +#define MAXPRCDAYS 100 /* max days of continuous processing */ +#define MAXINFILE 1000 /* max number of input files */ +#define MAXINVALIDTM 100 /* max number of invalid time marks */ /* constants/global variables ------------------------------------------------*/ -static pcvs_t pcvss={0}; /* satellite antenna parameters */ -static pcvs_t pcvsr={0}; /* receiver antenna parameters */ -static obs_t obss={0}; /* observation data */ -static nav_t navs={0}; /* navigation data */ -static sbs_t sbss={0}; /* sbas messages */ -static sta_t stas[MAXRCV]; /* station information */ -static int nepoch=0; /* number of observation epochs */ -static int nitm =0; /* number of invalid time marks */ -static int iobsu =0; /* current rover observation data index */ -static int iobsr =0; /* current reference observation data index */ -static int isbs =0; /* current sbas message index */ -static int iitm =0; /* current invalid time mark index */ -static int reverse=0; /* analysis direction (0:forward,1:backward) */ -static int aborts=0; /* abort status */ -static sol_t *solf; /* forward solutions */ -static sol_t *solb; /* backward solutions */ -static double *rbf; /* forward base positions */ -static double *rbb; /* backward base positions */ -static int isolf=0; /* current forward solutions index */ -static int isolb=0; /* current backward solutions index */ -static char proc_rov [64]=""; /* rover for current processing */ -static char proc_base[64]=""; /* base station for current processing */ -static char rtcm_file[1024]=""; /* rtcm data file */ -static char rtcm_path[1024]=""; /* rtcm data path */ -static gtime_t invalidtm[MAXINVALIDTM]={{0}};/* invalid time marks */ -static rtcm_t rtcm; /* rtcm control struct */ -static FILE *fp_rtcm=NULL; /* rtcm data file pointer */ +static pcvs_t pcvss = {0}; /* satellite antenna parameters */ +static pcvs_t pcvsr = {0}; /* receiver antenna parameters */ +static obs_t obss = {0}; /* observation data */ +static nav_t navs = {0}; /* navigation data */ +static sbs_t sbss = {0}; /* sbas messages */ +static sta_t stas[MAXRCV]; /* station information */ +static int nepoch = 0; /* number of observation epochs */ +static int nitm = 0; /* number of invalid time marks */ +static int iobsu = 0; /* current rover observation data index */ +static int iobsr = 0; /* current reference observation data index */ +static int isbs = 0; /* current sbas message index */ +static int iitm = 0; /* current invalid time mark index */ +static int reverse = 0; /* analysis direction (0:forward,1:backward) */ +static int aborts = 0; /* abort status */ +static sol_t *solf; /* forward solutions */ +static sol_t *solb; /* backward solutions */ +static double *rbf; /* forward base positions */ +static double *rbb; /* backward base positions */ +static int isolf = 0; /* current forward solutions index */ +static int isolb = 0; /* current backward solutions index */ +static char proc_rov[64] = ""; /* rover for current processing */ +static char proc_base[64] = ""; /* base station for current processing */ +static char rtcm_file[1024] = ""; /* rtcm data file */ +static char rtcm_path[1024] = ""; /* rtcm data path */ +static gtime_t invalidtm[MAXINVALIDTM] = {{0}}; /* invalid time marks */ +static rtcm_t rtcm; /* rtcm control struct */ +static FILE *fp_rtcm = NULL; /* rtcm data file pointer */ /* show message and check break ----------------------------------------------*/ -static int checkbrk(const char *format, ...) -{ - va_list arg; - char buff[1024],*p=buff; - if (!*format) return showmsg(""); - va_start(arg,format); - p+=vsprintf(p,format,arg); - va_end(arg); - if (*proc_rov&&*proc_base) sprintf(p," (%s-%s)",proc_rov,proc_base); - else if (*proc_rov ) sprintf(p," (%s)",proc_rov ); - else if (*proc_base) sprintf(p," (%s)",proc_base); - return showmsg(buff); +static int checkbrk(const char *format, ...) { + va_list arg; + char buff[1024], *p = buff; + if (!*format) return showmsg(""); + va_start(arg, format); + p += vsprintf(p, format, arg); + va_end(arg); + if (*proc_rov && *proc_base) + sprintf(p, " (%s-%s)", proc_rov, proc_base); + else if (*proc_rov) + sprintf(p, " (%s)", proc_rov); + else if (*proc_base) + sprintf(p, " (%s)", proc_base); + return showmsg(buff); } /* Solution option to field separator ----------------------------------------*/ /* Repeated from solution.c */ -static const char *opt2sep(const solopt_t *opt) -{ - if (!*opt->sep) return " "; - else if (!strcmp(opt->sep,"\\t")) return "\t"; - return opt->sep; +static const char *opt2sep(const solopt_t *opt) { + if (!*opt->sep) + return " "; + else if (!strcmp(opt->sep, "\\t")) + return "\t"; + return opt->sep; } /* output reference position -------------------------------------------------*/ -static void outrpos(FILE *fp, const double *r, const solopt_t *opt) -{ - double pos[3],dms1[3],dms2[3]; - - trace(3,"outrpos :\n"); - - const char *sep = opt2sep(opt); - if (opt->posf==SOLF_LLH||opt->posf==SOLF_ENU) { - ecef2pos(r,pos); - if (opt->degf) { - deg2dms(pos[0]*R2D,dms1,5); - deg2dms(pos[1]*R2D,dms2,5); - fprintf(fp,"%3.0f%s%02.0f%s%08.5f%s%4.0f%s%02.0f%s%08.5f%s%10.4f", - dms1[0],sep,dms1[1],sep,dms1[2],sep,dms2[0],sep,dms2[1], - sep,dms2[2],sep,pos[2]); - } - else { - fprintf(fp,"%13.9f%s%14.9f%s%10.4f",pos[0]*R2D,sep,pos[1]*R2D, - sep,pos[2]); - } - } - else if (opt->posf==SOLF_XYZ) { - fprintf(fp,"%14.4f%s%14.4f%s%14.4f",r[0],sep,r[1],sep,r[2]); +static void outrpos(FILE *fp, const double *r, const solopt_t *opt) { + double pos[3], dms1[3], dms2[3]; + + trace(3, "outrpos :\n"); + + const char *sep = opt2sep(opt); + if (opt->posf == SOLF_LLH || opt->posf == SOLF_ENU) { + ecef2pos(r, pos); + if (opt->degf) { + deg2dms(pos[0] * R2D, dms1, 5); + deg2dms(pos[1] * R2D, dms2, 5); + fprintf(fp, "%3.0f%s%02.0f%s%08.5f%s%4.0f%s%02.0f%s%08.5f%s%10.4f", dms1[0], sep, dms1[1], + sep, dms1[2], sep, dms2[0], sep, dms2[1], sep, dms2[2], sep, pos[2]); + } else { + fprintf(fp, "%13.9f%s%14.9f%s%10.4f", pos[0] * R2D, sep, pos[1] * R2D, sep, pos[2]); } + } else if (opt->posf == SOLF_XYZ) { + fprintf(fp, "%14.4f%s%14.4f%s%14.4f", r[0], sep, r[1], sep, r[2]); + } } /* output header -------------------------------------------------------------*/ static void outheader(FILE *fp, const char **file, int n, const prcopt_t *popt, - const solopt_t *sopt) -{ - const char *s1[]={"GPST","UTC","JST"}; - gtime_t ts,te; - double t1,t2; - int i,j,w1,w2; - char s2[40],s3[40]; - - trace(3,"outheader: n=%d\n",n); - - if (sopt->posf==SOLF_NMEA||sopt->posf==SOLF_STAT) { - return; - } - if (sopt->outhead) { - if (!*sopt->prog) { - fprintf(fp,"%s program : RTKLIB ver.%s %s\n",COMMENTH,VER_RTKLIB,PATCH_LEVEL); - } - else { - fprintf(fp,"%s program : %s\n",COMMENTH,sopt->prog); - } - for (i=0;i=0;j--) if (obss.data[j].rcv==1) break; - if (jtimes>=1) { - ts=gpst2utc(ts); - te=gpst2utc(te); - } - if (sopt->times==2) { - ts=timeadd(ts,9*3600.0); - te=timeadd(te,9*3600.0); - } - time2str(ts,s2,1); - time2str(te,s3,1); - fprintf(fp,"%s obs start : %s %s (week%04d %8.1fs)\n",COMMENTH,s2,s1[sopt->times],w1,t1); - fprintf(fp,"%s obs end : %s %s (week%04d %8.1fs)\n",COMMENTH,s3,s1[sopt->times],w2,t2); + const solopt_t *sopt) { + const char *s1[] = {"GPST", "UTC", "JST"}; + gtime_t ts, te; + double t1, t2; + int i, j, w1, w2; + char s2[40], s3[40]; + + trace(3, "outheader: n=%d\n", n); + + if (sopt->posf == SOLF_NMEA || sopt->posf == SOLF_STAT) { + return; + } + if (sopt->outhead) { + if (!*sopt->prog) { + fprintf(fp, "%s program : RTKLIB ver.%s %s\n", COMMENTH, VER_RTKLIB, PATCH_LEVEL); + } else { + fprintf(fp, "%s program : %s\n", COMMENTH, sopt->prog); } - if (sopt->outopt) { - outprcopt(fp,popt); + for (i = 0; i < n; i++) { + fprintf(fp, "%s inp file : %s\n", COMMENTH, file[i]); } - if (PMODE_DGPS<=popt->mode&&popt->mode<=PMODE_FIXED&&popt->mode!=PMODE_MOVEB) { - fprintf(fp,"%s ref pos : ",COMMENTH); - outrpos(fp,popt->rb,sopt); - fprintf(fp,"\n"); + for (i = 0; i < obss.n; i++) + if (obss.data[i].rcv == 1) break; + for (j = obss.n - 1; j >= 0; j--) + if (obss.data[j].rcv == 1) break; + if (j < i) { + fprintf(fp, "\n%s no rover obs data\n", COMMENTH); + return; } - if (sopt->outhead||sopt->outopt) fprintf(fp,"%s\n",COMMENTH); - - outsolhead(fp,sopt); + ts = obss.data[i].time; + te = obss.data[j].time; + t1 = time2gpst(ts, &w1); + t2 = time2gpst(te, &w2); + if (sopt->times >= 1) { + ts = gpst2utc(ts); + te = gpst2utc(te); + } + if (sopt->times == 2) { + ts = timeadd(ts, 9 * 3600.0); + te = timeadd(te, 9 * 3600.0); + } + time2str(ts, s2, 1); + time2str(te, s3, 1); + fprintf(fp, "%s obs start : %s %s (week%04d %8.1fs)\n", COMMENTH, s2, s1[sopt->times], w1, t1); + fprintf(fp, "%s obs end : %s %s (week%04d %8.1fs)\n", COMMENTH, s3, s1[sopt->times], w2, t2); + } + if (sopt->outopt) { + outprcopt(fp, popt); + } + if (PMODE_DGPS <= popt->mode && popt->mode <= PMODE_FIXED && popt->mode != PMODE_MOVEB) { + fprintf(fp, "%s ref pos : ", COMMENTH); + outrpos(fp, popt->rb, sopt); + fprintf(fp, "\n"); + } + if (sopt->outhead || sopt->outopt) fprintf(fp, "%s\n", COMMENTH); + + outsolhead(fp, sopt); } /* search next observation data index ---------------------------------------- Note *i will be advanced outside the index range of the obs data if none are found. */ -static int nextobsf(const obs_t *obs, int *i, int rcv) -{ - for (;*in;(*i)++) - if (obs->data[*i].rcv==rcv) break; - int n; - for (n=0;*i+nn;n++) { - if (obs->data[*i+n].rcv!=rcv) break; - double tt=timediff(obs->data[*i+n].time,obs->data[*i].time); - if (tt>DTTOL) break; - } - return n; +static int nextobsf(const obs_t *obs, int *i, int rcv) { + for (; *i < obs->n; (*i)++) + if (obs->data[*i].rcv == rcv) break; + int n; + for (n = 0; *i + n < obs->n; n++) { + if (obs->data[*i + n].rcv != rcv) break; + double tt = timediff(obs->data[*i + n].time, obs->data[*i].time); + if (tt > DTTOL) break; + } + return n; } -static int nextobsb(const obs_t *obs, int *i, int rcv) -{ - for (;*i>=0;(*i)--) - if (obs->data[*i].rcv==rcv) break; - int n; - for (n=0;*i-n>=0;n++) { - if (obs->data[*i-n].rcv!=rcv) break; - double tt=timediff(obs->data[*i-n].time,obs->data[*i].time); - if (tt<-DTTOL) break; - } - return n; +static int nextobsb(const obs_t *obs, int *i, int rcv) { + for (; *i >= 0; (*i)--) + if (obs->data[*i].rcv == rcv) break; + int n; + for (n = 0; *i - n >= 0; n++) { + if (obs->data[*i - n].rcv != rcv) break; + double tt = timediff(obs->data[*i - n].time, obs->data[*i].time); + if (tt < -DTTOL) break; + } + return n; } /* update rtcm ssr correction ------------------------------------------------*/ -static void update_rtcm_ssr(gtime_t time) -{ - char path[1024]; - int i; - - /* open or swap rtcm file */ - reppath(rtcm_file,path,time,"",""); - - if (strcmp(path,rtcm_path)) { - strcpy(rtcm_path,path); - - if (fp_rtcm) fclose(fp_rtcm); - fp_rtcm=fopen(path,"rb"); - if (fp_rtcm) { - rtcm.time=time; - input_rtcm3f(&rtcm,fp_rtcm); - trace(2,"rtcm file open: %s\n",path); - } - } - if (!fp_rtcm) return; - - /* read rtcm file until current time */ - while (timediff(rtcm.time,time)<1E-3) { - if (input_rtcm3f(&rtcm,fp_rtcm)<-1) break; - - /* update ssr corrections */ - for (i=0;iintpref) { - /* For interpolation, find first base timestamp after rover timestamp */ - int nr=nextobsf(&obss,&iobsr,2); - while (nr>0) { - if (timediff(obss.data[iobsr].time,obss.data[iobsu].time)>-DTTOL) break; - iobsr+=nr; - nr=nextobsf(&obss,&iobsr,2); - } - } else { - /* If not interpolating, find the closest iobsr timestamp before or after iobsu. */ - double dt=fabs(timediff(obss.data[iobsr].time,obss.data[iobsu].time)); - int i=iobsr,nr=nextobsf(&obss,&i,2); - while (nr>0) { - double dt_next=fabs(timediff(obss.data[i].time,obss.data[iobsu].time)); - if (dt_next>dt) break; - dt=dt_next; - iobsr=i; - i+=nr; - nr=nextobsf(&obss,&i,2); - } - } - /* Recalculate nr for the determined iobsr. This does not change iobsr. */ - int nr=nextobsf(&obss,&iobsr,2); - for (int i=0;i-1.0-DTTOL) break; - isbs++; - } - /* Update rtcm ssr corrections */ - if (*rtcm_file) { - update_rtcm_ssr(obs[0].time); - } - } else { - /* Input backward data */ - int nu=nextobsb(&obss,&iobsu,1); - if (nu<=0) return -1; - for (int i=0;i=0) { - if (popt->intpref) { - /* For interpolation, find first base timestamp before rover timestamp */ - int nr=nextobsb(&obss,&iobsr,2); - while (nr>0) { - if (timediff(obss.data[iobsr].time,obss.data[iobsu].time)0) { - double dt_next=fabs(timediff(obss.data[i].time,obss.data[iobsu].time)); - if (dt_next>dt) break; - dt=dt_next; - iobsr=i; - i-=nr; - nr=nextobsb(&obss,&i,2); - } - } - int nr=nextobsb(&obss,&iobsr,2); - for (int i=0;i=0) { - gtime_t time=gpst2time(sbss.msgs[isbs].week,sbss.msgs[isbs].tow); + if (fp_rtcm) fclose(fp_rtcm); + fp_rtcm = fopen(path, "rb"); + if (fp_rtcm) { + rtcm.time = time; + input_rtcm3f(&rtcm, fp_rtcm); + trace(2, "rtcm file open: %s\n", path); + } + } + if (!fp_rtcm) return; + + /* read rtcm file until current time */ + while (timediff(rtcm.time, time) < 1E-3) { + if (input_rtcm3f(&rtcm, fp_rtcm) < -1) break; + + /* update ssr corrections */ + for (i = 0; i < MAXSAT; i++) { + if (!rtcm.ssr[i].update || rtcm.ssr[i].iod[0] != rtcm.ssr[i].iod[1] || + timediff(time, rtcm.ssr[i].t0[0]) < -1E-3) + continue; + navs.ssr[i] = rtcm.ssr[i]; + rtcm.ssr[i].update = 0; + } + } +} +/* Input obs data, navigation messages and sbas correction -------------------*/ +static int inputobs(obsd_t *obs, int solq, const prcopt_t *popt) { + trace(3, "\ninfunc : dir=%d iobsu=%d iobsr=%d isbs=%d\n", reverse, iobsu, iobsr, isbs); - if (getbitu(sbss.msgs[isbs].msg,8,6)!=9) { /* Except for geo nav */ - sbsupdatecorr(sbss.msgs+isbs,&navs); - } - if (timediff(time,obs[0].time)<1.0+DTTOL) break; - isbs--; - } - } - return n; + if (0 <= iobsu && iobsu < obss.n) { + gtime_t time = obss.data[iobsu].time; + settime(time); + char tstr[40]; + if (checkbrk("processing : %s Q=%d", time2str(time, tstr, 0), solq)) { + aborts = 1; + showmsg("aborted"); + return -1; + } + } + int n = 0; + if (!reverse) { + /* Input forward data */ + int nu = nextobsf(&obss, &iobsu, 1); + if (nu <= 0) return -1; + for (int i = 0; i < nu && n < MAXOBS * 2; i++) obs[n++] = obss.data[iobsu + i]; + if (iobsr < obss.n) { + if (popt->intpref) { + /* For interpolation, find first base timestamp after rover timestamp */ + int nr = nextobsf(&obss, &iobsr, 2); + while (nr > 0) { + if (timediff(obss.data[iobsr].time, obss.data[iobsu].time) > -DTTOL) break; + iobsr += nr; + nr = nextobsf(&obss, &iobsr, 2); + } + } else { + /* If not interpolating, find the closest iobsr timestamp before or after iobsu. */ + double dt = fabs(timediff(obss.data[iobsr].time, obss.data[iobsu].time)); + int i = iobsr, nr = nextobsf(&obss, &i, 2); + while (nr > 0) { + double dt_next = fabs(timediff(obss.data[i].time, obss.data[iobsu].time)); + if (dt_next > dt) break; + dt = dt_next; + iobsr = i; + i += nr; + nr = nextobsf(&obss, &i, 2); + } + } + /* Recalculate nr for the determined iobsr. This does not change iobsr. */ + int nr = nextobsf(&obss, &iobsr, 2); + for (int i = 0; i < nr && n < MAXOBS * 2; i++) obs[n++] = obss.data[iobsr + i]; + } + iobsu += nu; + + /* Update sbas corrections */ + while (isbs < sbss.n) { + gtime_t time = gpst2time(sbss.msgs[isbs].week, sbss.msgs[isbs].tow); + + if (getbitu(sbss.msgs[isbs].msg, 8, 6) != 9) { /* Except for geo nav */ + sbsupdatecorr(sbss.msgs + isbs, &navs); + } + if (timediff(time, obs[0].time) > -1.0 - DTTOL) break; + isbs++; + } + /* Update rtcm ssr corrections */ + if (*rtcm_file) { + update_rtcm_ssr(obs[0].time); + } + } else { + /* Input backward data */ + int nu = nextobsb(&obss, &iobsu, 1); + if (nu <= 0) return -1; + for (int i = 0; i < nu && n < MAXOBS * 2; i++) obs[n++] = obss.data[iobsu - nu + 1 + i]; + if (iobsr >= 0) { + if (popt->intpref) { + /* For interpolation, find first base timestamp before rover timestamp */ + int nr = nextobsb(&obss, &iobsr, 2); + while (nr > 0) { + if (timediff(obss.data[iobsr].time, obss.data[iobsu].time) < DTTOL) break; + iobsr -= nr; + nr = nextobsb(&obss, &iobsr, 2); + } + } else { + /* If not interpolating, find the closest iobsr timestamp before or after iobsu. */ + double dt = fabs(timediff(obss.data[iobsr].time, obss.data[iobsu].time)); + int i = iobsr, nr = nextobsb(&obss, &i, 2); + while (nr > 0) { + double dt_next = fabs(timediff(obss.data[i].time, obss.data[iobsu].time)); + if (dt_next > dt) break; + dt = dt_next; + iobsr = i; + i -= nr; + nr = nextobsb(&obss, &i, 2); + } + } + int nr = nextobsb(&obss, &iobsr, 2); + for (int i = 0; i < nr && n < MAXOBS * 2; i++) obs[n++] = obss.data[iobsr - nr + 1 + i]; + } + iobsu -= nu; + + /* Update sbas corrections */ + while (isbs >= 0) { + gtime_t time = gpst2time(sbss.msgs[isbs].week, sbss.msgs[isbs].tow); + + if (getbitu(sbss.msgs[isbs].msg, 8, 6) != 9) { /* Except for geo nav */ + sbsupdatecorr(sbss.msgs + isbs, &navs); + } + if (timediff(time, obs[0].time) < 1.0 + DTTOL) break; + isbs--; + } + } + return n; } /* output to file message of invalid time mark -------------------------------*/ -static void outinvalidtm(FILE *fptm, const solopt_t *opt, const gtime_t tm) -{ - gtime_t time = tm; - double gpst; - const double secondsInAWeek = 604800; - int week,timeu; - char s[100]; - - timeu=opt->timeu<0?0:(opt->timeu>20?20:opt->timeu); - - if (opt->times>=TIMES_UTC) time=gpst2utc(time); - if (opt->times==TIMES_JST) time=timeadd(time,9*3600.0); - - if (opt->timef) time2str(time,s,timeu); - else { - gpst=time2gpst(time,&week); - if (secondsInAWeek-gpst < 0.5/pow(10.0,timeu)) { - week++; - gpst=0.0; - } - sprintf(s,"%4d %*.*f",week,6+(timeu<=0?0:timeu+1),timeu,gpst); - } - strcat(s, " Q=0, Time mark is not valid\n"); - - fwrite(s,strlen(s),1,fptm); +static void outinvalidtm(FILE *fptm, const solopt_t *opt, const gtime_t tm) { + gtime_t time = tm; + double gpst; + const double secondsInAWeek = 604800; + int week, timeu; + char s[100]; + + timeu = opt->timeu < 0 ? 0 : (opt->timeu > 20 ? 20 : opt->timeu); + + if (opt->times >= TIMES_UTC) time = gpst2utc(time); + if (opt->times == TIMES_JST) time = timeadd(time, 9 * 3600.0); + + if (opt->timef) + time2str(time, s, timeu); + else { + gpst = time2gpst(time, &week); + if (secondsInAWeek - gpst < 0.5 / pow(10.0, timeu)) { + week++; + gpst = 0.0; + } + sprintf(s, "%4d %*.*f", week, 6 + (timeu <= 0 ? 0 : timeu + 1), timeu, gpst); + } + strcat(s, " Q=0, Time mark is not valid\n"); + + fwrite(s, strlen(s), 1, fptm); } /* fill structure sol_t for time mark ----------------------------------------*/ -static sol_t fillsoltm(const sol_t solold, const sol_t solnew, const gtime_t tm) -{ - gtime_t t1={0},t2={0}; - sol_t sol=solold; - int i=0; - - if (solold.stat == 0 || solnew.stat == 0) { - sol.stat = 0; - } else { - sol.stat = (solold.stat > solnew.stat) ? solold.stat : solnew.stat; - } - sol.ns = (solold.ns < solnew.ns) ? solold.ns : solnew.ns; - sol.ratio = (solold.ratio < solnew.ratio) ? solold.ratio : solnew.ratio; - - /* interpolation position and speed of time mark */ - t1 = solold.time; - t2 = solnew.time; - sol.time = tm; - - for (i=0;i<6;i++) - { - sol.rr[i] = solold.rr[i] + timediff(tm,t1) / timediff(t2,t1) * (solnew.rr[i] - solold.rr[i]); - } - - return sol; +static sol_t fillsoltm(const sol_t solold, const sol_t solnew, const gtime_t tm) { + gtime_t t1 = {0}, t2 = {0}; + sol_t sol = solold; + int i = 0; + + if (solold.stat == 0 || solnew.stat == 0) { + sol.stat = 0; + } else { + sol.stat = (solold.stat > solnew.stat) ? solold.stat : solnew.stat; + } + sol.ns = (solold.ns < solnew.ns) ? solold.ns : solnew.ns; + sol.ratio = (solold.ratio < solnew.ratio) ? solold.ratio : solnew.ratio; + + /* interpolation position and speed of time mark */ + t1 = solold.time; + t2 = solnew.time; + sol.time = tm; + + for (i = 0; i < 6; i++) { + sol.rr[i] = solold.rr[i] + timediff(tm, t1) / timediff(t2, t1) * (solnew.rr[i] - solold.rr[i]); + } + + return sol; } /* carrier-phase bias correction by ssr --------------------------------------*/ -static void corr_phase_bias_ssr(obsd_t *obs, int n, const nav_t *nav) -{ - double freq; - uint8_t code; - int i,j; +static void corr_phase_bias_ssr(obsd_t *obs, int n, const nav_t *nav) { + double freq; + uint8_t code; + int i, j; - for (i=0;issr[obs[i].sat-1].pbias[code-1]*freq/CLIGHT; + /* correct phase bias (cyc) */ + obs[i].L[j] -= nav->ssr[obs[i].sat - 1].pbias[code - 1] * freq / CLIGHT; } } /* process positioning -------------------------------------------------------*/ -static void procpos(FILE *fp, FILE *fptm, const prcopt_t *popt, const solopt_t *sopt, - rtk_t *rtk, int mode) -{ - gtime_t time={0}; - sol_t sol={{0}},oldsol={{0}},newsol={{0}}; - obsd_t *obs_ptr = (obsd_t *)malloc(sizeof(obsd_t)*MAXOBS*2); /* for rover and base */ - if (obs_ptr == NULL) { - trace(2, "procpos: memory allocation failure\n"); - return; - } - double rb[3]={0}; - int i,nobs,n,solstatic,num=0,pri[]={6,1,2,3,4,5,1,6}; - - trace(3,"procpos : mode=%d\n",mode); /* 0=single dir, 1=combined */ - - solstatic=sopt->solstatic&& - (popt->mode==PMODE_STATIC||popt->mode==PMODE_STATIC_START||popt->mode==PMODE_PPP_STATIC); - - rtcm_path[0]='\0'; - - while ((nobs=inputobs(obs_ptr,rtk->sol.stat,popt))>=0) { - - /* exclude satellites */ - for (i=n=0;inavsys)&& - popt->exsats[obs_ptr[i].sat-1]!=1) obs_ptr[n++]= obs_ptr[i]; - } - if (n<=0) continue; - - /* carrier-phase bias correction */ - if (!strstr(popt->pppopt,"-ENA_FCB")) { - corr_phase_bias_ssr(obs_ptr,n,&navs); - } - if (!rtkpos(rtk, obs_ptr,n,&navs)) { - if (rtk->sol.eventime.time != 0) { - if (mode == SOLMODE_SINGLE_DIR) { - if (fptm) outinvalidtm(fptm, sopt, rtk->sol.eventime); - } else if (!reverse&&nitmsol.eventime; - } - } - continue; - } - - if (mode==SOLMODE_SINGLE_DIR) { /* forward or backward */ - if (!solstatic) { - outsol(fp,&rtk->sol,rtk->rb,sopt); - } - else if (time.time==0||pri[rtk->sol.stat]<=pri[sol.stat]) { - sol=rtk->sol; - for (i=0;i<3;i++) rb[i]=rtk->rb[i]; - if (time.time==0||timediff(rtk->sol.time,time)<0.0) { - time=rtk->sol.time; - } - } - /* check time mark */ - if (rtk->sol.eventime.time != 0) - { - newsol = fillsoltm(oldsol,rtk->sol,rtk->sol.eventime); - num++; - if (!solstatic&&mode==SOLMODE_SINGLE_DIR) { - if (fptm) outsol(fptm,&newsol,rb,sopt); - } - } - oldsol = rtk->sol; - } - else if (!reverse) { /* combined-forward */ - if (isolf >= nepoch) { - free(obs_ptr); - return; - } - solf[isolf]=rtk->sol; - for (i=0;i<3;i++) rbf[i+isolf*3]=rtk->rb[i]; - isolf++; - } - else { /* combined-backward */ - if (isolb>=nepoch) { - free(obs_ptr); - return; - } - solb[isolb]=rtk->sol; - for (i=0;i<3;i++) rbb[i+isolb*3]=rtk->rb[i]; - isolb++; - } - } - if (mode==SOLMODE_SINGLE_DIR && solstatic&&time.time!=0.0) { - sol.time=time; - outsol(fp,&sol,rb,sopt); - } - - free(obs_ptr); /* moved from stack to heap to kill a stack overflow warning */ +static void procpos(FILE *fp, FILE *fptm, const prcopt_t *popt, const solopt_t *sopt, rtk_t *rtk, + int mode) { + gtime_t time = {0}; + sol_t sol = {{0}}, oldsol = {{0}}, newsol = {{0}}; + obsd_t *obs_ptr = (obsd_t *)malloc(sizeof(obsd_t) * MAXOBS * 2); /* for rover and base */ + if (obs_ptr == NULL) { + trace(2, "procpos: memory allocation failure\n"); + return; + } + double rb[3] = {0}; + int i, nobs, n, solstatic, num = 0, pri[] = {6, 1, 2, 3, 4, 5, 1, 6}; + + trace(3, "procpos : mode=%d\n", mode); /* 0=single dir, 1=combined */ + + solstatic = sopt->solstatic && (popt->mode == PMODE_STATIC || popt->mode == PMODE_STATIC_START || + popt->mode == PMODE_PPP_STATIC); + + rtcm_path[0] = '\0'; + + while ((nobs = inputobs(obs_ptr, rtk->sol.stat, popt)) >= 0) { + /* exclude satellites */ + for (i = n = 0; i < nobs; i++) { + if ((satsys(obs_ptr[i].sat, NULL) & popt->navsys) && popt->exsats[obs_ptr[i].sat - 1] != 1) + obs_ptr[n++] = obs_ptr[i]; + } + if (n <= 0) continue; + + /* carrier-phase bias correction */ + if (!strstr(popt->pppopt, "-ENA_FCB")) { + corr_phase_bias_ssr(obs_ptr, n, &navs); + } + if (!rtkpos(rtk, obs_ptr, n, &navs)) { + if (rtk->sol.eventime.time != 0) { + if (mode == SOLMODE_SINGLE_DIR) { + if (fptm) outinvalidtm(fptm, sopt, rtk->sol.eventime); + } else if (!reverse && nitm < MAXINVALIDTM) { + invalidtm[nitm++] = rtk->sol.eventime; + } + } + continue; + } + + if (mode == SOLMODE_SINGLE_DIR) { /* forward or backward */ + if (!solstatic) { + outsol(fp, &rtk->sol, rtk->rb, sopt); + } else if (time.time == 0 || pri[rtk->sol.stat] <= pri[sol.stat]) { + sol = rtk->sol; + for (i = 0; i < 3; i++) rb[i] = rtk->rb[i]; + if (time.time == 0 || timediff(rtk->sol.time, time) < 0.0) { + time = rtk->sol.time; + } + } + /* check time mark */ + if (rtk->sol.eventime.time != 0) { + newsol = fillsoltm(oldsol, rtk->sol, rtk->sol.eventime); + num++; + if (!solstatic && mode == SOLMODE_SINGLE_DIR) { + if (fptm) outsol(fptm, &newsol, rb, sopt); + } + } + oldsol = rtk->sol; + } else if (!reverse) { /* combined-forward */ + if (isolf >= nepoch) { + free(obs_ptr); + return; + } + solf[isolf] = rtk->sol; + for (i = 0; i < 3; i++) rbf[i + isolf * 3] = rtk->rb[i]; + isolf++; + } else { /* combined-backward */ + if (isolb >= nepoch) { + free(obs_ptr); + return; + } + solb[isolb] = rtk->sol; + for (i = 0; i < 3; i++) rbb[i + isolb * 3] = rtk->rb[i]; + isolb++; + } + } + if (mode == SOLMODE_SINGLE_DIR && solstatic && time.time != 0.0) { + sol.time = time; + outsol(fp, &sol, rb, sopt); + } + + free(obs_ptr); /* moved from stack to heap to kill a stack overflow warning */ } /* validation of combined solutions ------------------------------------------*/ -static int valcomb(const sol_t *solf, const sol_t *solb, double *rbf, - double *rbb, const prcopt_t *popt) -{ - double dr[3],var[3]; - int i; - char tstr[40]; - - trace(4,"valcomb :\n"); - - /* compare forward and backward solution */ - for (i=0;i<3;i++) { - dr[i]=solf->rr[i]-solb->rr[i]; - if (popt->mode==PMODE_MOVEB) dr[i]-=(rbf[i]-rbb[i]); - var[i]=(double)solf->qr[i] + (double)solb->qr[i]; - } - for (i=0;i<3;i++) { - if (dr[i]*dr[i]<=16.0*var[i]) continue; /* ok if in 4-sigma */ - - time2str(solf->time,tstr,2); - trace(2,"degrade fix to float: %s dr=%.3f %.3f %.3f std=%.3f %.3f %.3f\n", - tstr+11,dr[0],dr[1],dr[2],SQRT(var[0]),SQRT(var[1]),SQRT(var[2])); - return 0; - } - return 1; +static int valcomb(const sol_t *solf, const sol_t *solb, double *rbf, double *rbb, + const prcopt_t *popt) { + double dr[3], var[3]; + int i; + char tstr[40]; + + trace(4, "valcomb :\n"); + + /* compare forward and backward solution */ + for (i = 0; i < 3; i++) { + dr[i] = solf->rr[i] - solb->rr[i]; + if (popt->mode == PMODE_MOVEB) dr[i] -= (rbf[i] - rbb[i]); + var[i] = (double)solf->qr[i] + (double)solb->qr[i]; + } + for (i = 0; i < 3; i++) { + if (dr[i] * dr[i] <= 16.0 * var[i]) continue; /* ok if in 4-sigma */ + + time2str(solf->time, tstr, 2); + trace(2, "degrade fix to float: %s dr=%.3f %.3f %.3f std=%.3f %.3f %.3f\n", tstr + 11, dr[0], + dr[1], dr[2], SQRT(var[0]), SQRT(var[1]), SQRT(var[2])); + return 0; + } + return 1; } /* combine forward/backward solutions and save results ---------------------*/ -static void combres(FILE *fp, FILE *fptm, const prcopt_t *popt, const solopt_t *sopt) -{ - gtime_t time={0}; - sol_t sols={{0}},sol={{0}},oldsol={{0}},newsol={{0}}; - double tt,Qf[9],Qb[9],Qs[9],rbs[3]={0},rb[3]={0},rr_f[3],rr_b[3],rr_s[3]; - int i,j,k,solstatic,num=0,pri[]={7,1,2,3,4,5,1,6}; - - trace(3,"combres : isolf=%d isolb=%d\n",isolf,isolb); - - solstatic=sopt->solstatic&& - (popt->mode==PMODE_STATIC||popt->mode==PMODE_STATIC_START||popt->mode==PMODE_PPP_STATIC); - - for (i=0,j=isolb-1;i=0;i++,j--) { - if ((tt=timediff(solf[i].time,solb[j].time))<-DTTOL) { - sols=solf[i]; - for (k=0;k<3;k++) rbs[k]=rbf[k+i*3]; - j++; - } - else if (tt>DTTOL) { - sols=solb[j]; - for (k=0;k<3;k++) rbs[k]=rbb[k+j*3]; - i--; - } - else if (pri[solf[i].stat]pri[solb[j].stat]) { - sols=solb[j]; - for (k=0;k<3;k++) rbs[k]=rbb[k+j*3]; - } - else { - sols=solf[i]; - sols.time=timeadd(sols.time,-tt/2.0); - - if ((popt->mode==PMODE_KINEMA||popt->mode==PMODE_MOVEB)&& - sols.stat==SOLQ_FIX) { - - /* degrade fix to float if validation failed */ - if (!valcomb(solf+i,solb+j,rbf+i*3,rbb+j*3,popt)) sols.stat=SOLQ_FLOAT; - } - for (k=0;k<3;k++) { - Qf[k+k*3]=solf[i].qr[k]; - Qb[k+k*3]=solb[j].qr[k]; - } - Qf[1]=Qf[3]=solf[i].qr[3]; - Qf[5]=Qf[7]=solf[i].qr[4]; - Qf[2]=Qf[6]=solf[i].qr[5]; - Qb[1]=Qb[3]=solb[j].qr[3]; - Qb[5]=Qb[7]=solb[j].qr[4]; - Qb[2]=Qb[6]=solb[j].qr[5]; - - if (popt->mode==PMODE_MOVEB) { - for (k=0;k<3;k++) rr_f[k]=solf[i].rr[k]-rbf[k+i*3]; - for (k=0;k<3;k++) rr_b[k]=solb[j].rr[k]-rbb[k+j*3]; - if (smoother(rr_f,Qf,rr_b,Qb,3,rr_s,Qs)) continue; - for (k=0;k<3;k++) sols.rr[k]=rbs[k]+rr_s[k]; - } - else { - if (smoother(solf[i].rr,Qf,solb[j].rr,Qb,3,sols.rr,Qs)) continue; - } - sols.qr[0]=(float)Qs[0]; - sols.qr[1]=(float)Qs[4]; - sols.qr[2]=(float)Qs[8]; - sols.qr[3]=(float)Qs[1]; - sols.qr[4]=(float)Qs[5]; - sols.qr[5]=(float)Qs[2]; - - /* smoother for velocity solution */ - if (popt->dynamics) { - for (k=0;k<3;k++) { - Qf[k+k*3]=solf[i].qv[k]; - Qb[k+k*3]=solb[j].qv[k]; - } - Qf[1]=Qf[3]=solf[i].qv[3]; - Qf[5]=Qf[7]=solf[i].qv[4]; - Qf[2]=Qf[6]=solf[i].qv[5]; - Qb[1]=Qb[3]=solb[j].qv[3]; - Qb[5]=Qb[7]=solb[j].qv[4]; - Qb[2]=Qb[6]=solb[j].qv[5]; - if (smoother(solf[i].rr+3,Qf,solb[j].rr+3,Qb,3,sols.rr+3,Qs)) continue; - sols.qv[0]=(float)Qs[0]; - sols.qv[1]=(float)Qs[4]; - sols.qv[2]=(float)Qs[8]; - sols.qv[3]=(float)Qs[1]; - sols.qv[4]=(float)Qs[5]; - sols.qv[5]=(float)Qs[2]; - } - } - if (!solstatic) { - outsol(fp,&sols,rbs,sopt); - } - else if (time.time==0||pri[sols.stat]<=pri[sol.stat]) { - sol=sols; - for (k=0;k<3;k++) rb[k]=rbs[k]; - if (time.time==0||timediff(sols.time,time)<0.0) { - time=sols.time; - } - } - if (iitm < nitm && timediff(invalidtm[iitm],sols.time)<0.0) - { - outinvalidtm(fptm,sopt,invalidtm[iitm]); - iitm++; - } - if (sols.eventime.time != 0) - { - newsol = fillsoltm(oldsol,sols,sols.eventime); - num++; - if (!solstatic) { - outsol(fptm,&newsol,rb,sopt); - } - } - oldsol = sols; - } - if (solstatic&&time.time!=0.0) { - sol.time=time; - outsol(fp,&sol,rb,sopt); - } +static void combres(FILE *fp, FILE *fptm, const prcopt_t *popt, const solopt_t *sopt) { + gtime_t time = {0}; + sol_t sols = {{0}}, sol = {{0}}, oldsol = {{0}}, newsol = {{0}}; + double tt, Qf[9], Qb[9], Qs[9], rbs[3] = {0}, rb[3] = {0}, rr_f[3], rr_b[3], rr_s[3]; + int i, j, k, solstatic, num = 0, pri[] = {7, 1, 2, 3, 4, 5, 1, 6}; + + trace(3, "combres : isolf=%d isolb=%d\n", isolf, isolb); + + solstatic = sopt->solstatic && (popt->mode == PMODE_STATIC || popt->mode == PMODE_STATIC_START || + popt->mode == PMODE_PPP_STATIC); + + for (i = 0, j = isolb - 1; i < isolf && j >= 0; i++, j--) { + if ((tt = timediff(solf[i].time, solb[j].time)) < -DTTOL) { + sols = solf[i]; + for (k = 0; k < 3; k++) rbs[k] = rbf[k + i * 3]; + j++; + } else if (tt > DTTOL) { + sols = solb[j]; + for (k = 0; k < 3; k++) rbs[k] = rbb[k + j * 3]; + i--; + } else if (pri[solf[i].stat] < pri[solb[j].stat]) { + sols = solf[i]; + for (k = 0; k < 3; k++) rbs[k] = rbf[k + i * 3]; + } else if (pri[solf[i].stat] > pri[solb[j].stat]) { + sols = solb[j]; + for (k = 0; k < 3; k++) rbs[k] = rbb[k + j * 3]; + } else { + sols = solf[i]; + sols.time = timeadd(sols.time, -tt / 2.0); + + if ((popt->mode == PMODE_KINEMA || popt->mode == PMODE_MOVEB) && sols.stat == SOLQ_FIX) { + /* degrade fix to float if validation failed */ + if (!valcomb(solf + i, solb + j, rbf + i * 3, rbb + j * 3, popt)) sols.stat = SOLQ_FLOAT; + } + for (k = 0; k < 3; k++) { + Qf[k + k * 3] = solf[i].qr[k]; + Qb[k + k * 3] = solb[j].qr[k]; + } + Qf[1] = Qf[3] = solf[i].qr[3]; + Qf[5] = Qf[7] = solf[i].qr[4]; + Qf[2] = Qf[6] = solf[i].qr[5]; + Qb[1] = Qb[3] = solb[j].qr[3]; + Qb[5] = Qb[7] = solb[j].qr[4]; + Qb[2] = Qb[6] = solb[j].qr[5]; + + if (popt->mode == PMODE_MOVEB) { + for (k = 0; k < 3; k++) rr_f[k] = solf[i].rr[k] - rbf[k + i * 3]; + for (k = 0; k < 3; k++) rr_b[k] = solb[j].rr[k] - rbb[k + j * 3]; + if (smoother(rr_f, Qf, rr_b, Qb, 3, rr_s, Qs)) continue; + for (k = 0; k < 3; k++) sols.rr[k] = rbs[k] + rr_s[k]; + } else { + if (smoother(solf[i].rr, Qf, solb[j].rr, Qb, 3, sols.rr, Qs)) continue; + } + sols.qr[0] = (float)Qs[0]; + sols.qr[1] = (float)Qs[4]; + sols.qr[2] = (float)Qs[8]; + sols.qr[3] = (float)Qs[1]; + sols.qr[4] = (float)Qs[5]; + sols.qr[5] = (float)Qs[2]; + + /* smoother for velocity solution */ + if (popt->dynamics) { + for (k = 0; k < 3; k++) { + Qf[k + k * 3] = solf[i].qv[k]; + Qb[k + k * 3] = solb[j].qv[k]; + } + Qf[1] = Qf[3] = solf[i].qv[3]; + Qf[5] = Qf[7] = solf[i].qv[4]; + Qf[2] = Qf[6] = solf[i].qv[5]; + Qb[1] = Qb[3] = solb[j].qv[3]; + Qb[5] = Qb[7] = solb[j].qv[4]; + Qb[2] = Qb[6] = solb[j].qv[5]; + if (smoother(solf[i].rr + 3, Qf, solb[j].rr + 3, Qb, 3, sols.rr + 3, Qs)) continue; + sols.qv[0] = (float)Qs[0]; + sols.qv[1] = (float)Qs[4]; + sols.qv[2] = (float)Qs[8]; + sols.qv[3] = (float)Qs[1]; + sols.qv[4] = (float)Qs[5]; + sols.qv[5] = (float)Qs[2]; + } + } + if (!solstatic) { + outsol(fp, &sols, rbs, sopt); + } else if (time.time == 0 || pri[sols.stat] <= pri[sol.stat]) { + sol = sols; + for (k = 0; k < 3; k++) rb[k] = rbs[k]; + if (time.time == 0 || timediff(sols.time, time) < 0.0) { + time = sols.time; + } + } + if (iitm < nitm && timediff(invalidtm[iitm], sols.time) < 0.0) { + outinvalidtm(fptm, sopt, invalidtm[iitm]); + iitm++; + } + if (sols.eventime.time != 0) { + newsol = fillsoltm(oldsol, sols, sols.eventime); + num++; + if (!solstatic) { + outsol(fptm, &newsol, rb, sopt); + } + } + oldsol = sols; + } + if (solstatic && time.time != 0.0) { + sol.time = time; + outsol(fp, &sol, rb, sopt); + } } /* read prec ephemeris, sbas data, tec grid and open rtcm --------------------*/ -static void readpreceph(const char **infile, int n, const prcopt_t *prcopt, - nav_t *nav, sbs_t *sbs) -{ - int i; - const char *ext; - - trace(2,"readpreceph: n=%d\n",n); - - nav->ne=nav->nemax=0; - nav->nc=nav->ncmax=0; - sbs->n =sbs->nmax =0; - - /* read precise ephemeris files */ - for (i=0;isbassatsel,sbs); - } - - /* set rtcm file and initialize rtcm struct */ - rtcm_file[0]=rtcm_path[0]='\0'; fp_rtcm=NULL; - - for (i=0;ine = nav->nemax = 0; + nav->nc = nav->ncmax = 0; + sbs->n = sbs->nmax = 0; + + /* read precise ephemeris files */ + for (i = 0; i < n; i++) { + if (strstr(infile[i], "%r") || strstr(infile[i], "%b")) continue; + readsp3(infile[i], nav, 0); + } + /* read precise clock files */ + for (i = 0; i < n; i++) { + if (strstr(infile[i], "%r") || strstr(infile[i], "%b")) continue; + readrnxc(infile[i], nav); + } + /* read sbas message files */ + for (i = 0; i < n; i++) { + if (strstr(infile[i], "%r") || strstr(infile[i], "%b")) continue; + sbsreadmsg(infile[i], prcopt->sbassatsel, sbs); + } + + /* set rtcm file and initialize rtcm struct */ + rtcm_file[0] = rtcm_path[0] = '\0'; + fp_rtcm = NULL; + + for (i = 0; i < n; i++) { + if ((ext = strrchr(infile[i], '.')) && (!strcmp(ext, ".rtcm3") || !strcmp(ext, ".RTCM3"))) { + strcpy(rtcm_file, infile[i]); + init_rtcm(&rtcm); + break; + } + } } /* free prec ephemeris and sbas data -----------------------------------------*/ -static void freepreceph(nav_t *nav, sbs_t *sbs) -{ - int i; - - trace(3,"freepreceph:\n"); - - free(nav->peph); nav->peph=NULL; nav->ne=nav->nemax=0; - free(nav->pclk); nav->pclk=NULL; nav->nc=nav->ncmax=0; - free(sbs->msgs); sbs->msgs=NULL; sbs->n =sbs->nmax =0; - for (i=0;int;i++) { - free(nav->tec[i].data); - free(nav->tec[i].rms ); - } - free(nav->tec ); nav->tec =NULL; nav->nt=nav->ntmax=0; - - if (fp_rtcm) fclose(fp_rtcm); - free_rtcm(&rtcm); +static void freepreceph(nav_t *nav, sbs_t *sbs) { + int i; + + trace(3, "freepreceph:\n"); + + free(nav->peph); + nav->peph = NULL; + nav->ne = nav->nemax = 0; + free(nav->pclk); + nav->pclk = NULL; + nav->nc = nav->ncmax = 0; + free(sbs->msgs); + sbs->msgs = NULL; + sbs->n = sbs->nmax = 0; + for (i = 0; i < nav->nt; i++) { + free(nav->tec[i].data); + free(nav->tec[i].rms); + } + free(nav->tec); + nav->tec = NULL; + nav->nt = nav->ntmax = 0; + + if (fp_rtcm) fclose(fp_rtcm); + free_rtcm(&rtcm); } /* read obs and nav data -----------------------------------------------------*/ -static int readobsnav(gtime_t ts, gtime_t te, double ti, const char **infile, - const int *index, int n, const prcopt_t *prcopt, - obs_t *obs, nav_t *nav, sta_t *sta) -{ - int i,j,ind=0,nobs=0,rcv=1; - - char tstr[40]; - trace(3,"readobsnav: ts=%s n=%d\n",time2str(ts,tstr,0),n); - - obs->data=NULL; obs->n =obs->nmax =0; - nav->eph =NULL; nav->n =nav->nmax =0; - nav->geph=NULL; nav->ng=nav->ngmax=0; - /* free(nav->seph); */ /* is this needed to avoid memory leak??? */ - nav->seph=NULL; nav->ns=nav->nsmax=0; - nepoch=0; - - for (i=0;in>nobs) rcv++; - ind=index[i]; nobs=obs->n; - } - gtime_t tsw = ts, tew = te; - if (rcv > 1) { - // Expand the time span a little for base observations to support - // interpolation at the extents of the rover observations. - if (tsw.time >= 60) tsw = timeadd(tsw, -60); - if (tew.time > 0) tew = timeadd(tew, 60); - } - /* read rinex obs and nav file */ - if (readrnxt(infile[i],rcv,tsw,tew,ti,prcopt->rnxopt[rcv<=1?0:1],obs,nav, - rcv<=2?sta+rcv-1:NULL)<0) { - checkbrk("error : insufficient memory"); - trace(1,"insufficient memory\n"); - return 0; - } - } - if (obs->n<=0) { - checkbrk("error : no obs data"); - trace(1,"\n"); - return 0; - } - if (nav->n<=0&&nav->ng<=0&&nav->ns<=0) { - checkbrk("error : no nav data"); - trace(1,"\n"); - return 0; - } - /* sort observation data */ - nepoch=sortobs(obs); - - /* delete duplicated ephemeris */ - uniqnav(nav); - - /* set time span for progress display */ - if (ts.time==0||te.time==0) { - for (i=0; in;i++) if (obs->data[i].rcv==1) break; - for (j=obs->n-1;j>=0;j--) if (obs->data[j].rcv==1) break; - if (idata[i].time; - if (te.time==0) te=obs->data[j].time; - settspan(ts,te); - } +static int readobsnav(gtime_t ts, gtime_t te, double ti, const char **infile, const int *index, + int n, const prcopt_t *prcopt, obs_t *obs, nav_t *nav, sta_t *sta) { + int i, j, ind = 0, nobs = 0, rcv = 1; + + char tstr[40]; + trace(3, "readobsnav: ts=%s n=%d\n", time2str(ts, tstr, 0), n); + + obs->data = NULL; + obs->n = obs->nmax = 0; + nav->eph = NULL; + nav->n = nav->nmax = 0; + nav->geph = NULL; + nav->ng = nav->ngmax = 0; + /* free(nav->seph); */ /* is this needed to avoid memory leak??? */ + nav->seph = NULL; + nav->ns = nav->nsmax = 0; + nepoch = 0; + + for (i = 0; i < n; i++) { + if (checkbrk("")) return 0; + + if (index[i] != ind) { + if (obs->n > nobs) rcv++; + ind = index[i]; + nobs = obs->n; + } + gtime_t tsw = ts, tew = te; + if (rcv > 1) { + // Expand the time span a little for base observations to support + // interpolation at the extents of the rover observations. + if (tsw.time >= 60) tsw = timeadd(tsw, -60); + if (tew.time > 0) tew = timeadd(tew, 60); + } + /* read rinex obs and nav file */ + if (readrnxt(infile[i], rcv, tsw, tew, ti, prcopt->rnxopt[rcv <= 1 ? 0 : 1], obs, nav, + rcv <= 2 ? sta + rcv - 1 : NULL) < 0) { + checkbrk("error : insufficient memory"); + trace(1, "insufficient memory\n"); + return 0; } - return 1; + } + if (obs->n <= 0) { + checkbrk("error : no obs data"); + trace(1, "\n"); + return 0; + } + if (nav->n <= 0 && nav->ng <= 0 && nav->ns <= 0) { + checkbrk("error : no nav data"); + trace(1, "\n"); + return 0; + } + /* sort observation data */ + nepoch = sortobs(obs); + + /* delete duplicated ephemeris */ + uniqnav(nav); + + /* set time span for progress display */ + if (ts.time == 0 || te.time == 0) { + for (i = 0; i < obs->n; i++) + if (obs->data[i].rcv == 1) break; + for (j = obs->n - 1; j >= 0; j--) + if (obs->data[j].rcv == 1) break; + if (i < j) { + if (ts.time == 0) ts = obs->data[i].time; + if (te.time == 0) te = obs->data[j].time; + settspan(ts, te); + } + } + return 1; } /* free obs and nav data -----------------------------------------------------*/ -static void freeobsnav(obs_t *obs, nav_t *nav) -{ - trace(3,"freeobsnav:\n"); - - free(obs->data); obs->data=NULL; obs->n =obs->nmax =0; - free(nav->eph ); nav->eph =NULL; nav->n =nav->nmax =0; - free(nav->geph); nav->geph=NULL; nav->ng=nav->ngmax=0; - free(nav->seph); nav->seph=NULL; nav->ns=nav->nsmax=0; +static void freeobsnav(obs_t *obs, nav_t *nav) { + trace(3, "freeobsnav:\n"); + + free(obs->data); + obs->data = NULL; + obs->n = obs->nmax = 0; + free(nav->eph); + nav->eph = NULL; + nav->n = nav->nmax = 0; + free(nav->geph); + nav->geph = NULL; + nav->ng = nav->ngmax = 0; + free(nav->seph); + nav->seph = NULL; + nav->ns = nav->nsmax = 0; } /* average of single position ------------------------------------------------*/ -static int avepos(double *ra, int rcv, const obs_t *obs, const nav_t *nav, - const prcopt_t *opt) -{ - gtime_t ts={0}; - sol_t sol={{0}}; - int i,j,n=0,m,iobs; - char msg[128]; - - trace(3,"avepos: rcv=%d obs.n=%d\n",rcv,obs->n); - - obsd_t *data = (obsd_t *)calloc(MAXOBS, sizeof(obsd_t)); - if (data == NULL) { - trace(1, "avepos: obsd_t alloc failed\n"); - return 0; - } - - for (i=0;i<3;i++) ra[i]=0.0; - - for (iobs=0;(m=nextobsf(obs,&iobs,rcv))>0;iobs+=m) { - - for (i=j=0;idata[iobs+i]; - if ((satsys(data[j].sat,NULL)&opt->navsys)&& - opt->exsats[data[j].sat-1]!=1) j++; - } - if (j<=0||!screent(data[0].time,ts,ts,1.0)) continue; /* only 1 hz */ - - if (!pntpos(data,j,nav,opt,&sol,NULL,NULL,msg)) continue; - - for (i=0;i<3;i++) ra[i]+=sol.rr[i]; - n++; - } - free(data); - if (n<=0) { - trace(1,"no average of base station position\n"); - return 0; - } - for (i=0;i<3;i++) ra[i]/=n; - return 1; +static int avepos(double *ra, int rcv, const obs_t *obs, const nav_t *nav, const prcopt_t *opt) { + gtime_t ts = {0}; + sol_t sol = {{0}}; + int i, j, n = 0, m, iobs; + char msg[128]; + + trace(3, "avepos: rcv=%d obs.n=%d\n", rcv, obs->n); + + obsd_t *data = (obsd_t *)calloc(MAXOBS, sizeof(obsd_t)); + if (data == NULL) { + trace(1, "avepos: obsd_t alloc failed\n"); + return 0; + } + + for (i = 0; i < 3; i++) ra[i] = 0.0; + + for (iobs = 0; (m = nextobsf(obs, &iobs, rcv)) > 0; iobs += m) { + for (i = j = 0; i < m && i < MAXOBS; i++) { + data[j] = obs->data[iobs + i]; + if ((satsys(data[j].sat, NULL) & opt->navsys) && opt->exsats[data[j].sat - 1] != 1) j++; + } + if (j <= 0 || !screent(data[0].time, ts, ts, 1.0)) continue; /* only 1 hz */ + + if (!pntpos(data, j, nav, opt, &sol, NULL, NULL, msg)) continue; + + for (i = 0; i < 3; i++) ra[i] += sol.rr[i]; + n++; + } + free(data); + if (n <= 0) { + trace(1, "no average of base station position\n"); + return 0; + } + for (i = 0; i < 3; i++) ra[i] /= n; + return 1; } /* antenna phase center position ---------------------------------------------*/ -static int antpos(prcopt_t *opt, int rcvno, const obs_t *obs, const nav_t *nav, - const sta_t *stas, const char *posfile) -{ - double *rr=rcvno==1?opt->ru:opt->rb,del[3],pos[3],dr[3]={0}; - int i,postype=rcvno==1?opt->rovpos:opt->refpos; - const char *name; - - trace(3,"antpos : rcvno=%d\n",rcvno); - - if (postype==POSOPT_SINGLE) { /* average of single position */ - if (!avepos(rr,rcvno,obs,nav,opt)) { - showmsg("error : station pos computation"); - return 0; - } +static int antpos(prcopt_t *opt, int rcvno, const obs_t *obs, const nav_t *nav, const sta_t *stas, + const char *posfile) { + double *rr = rcvno == 1 ? opt->ru : opt->rb, del[3], pos[3], dr[3] = {0}; + int i, postype = rcvno == 1 ? opt->rovpos : opt->refpos; + const char *name; + + trace(3, "antpos : rcvno=%d\n", rcvno); + + if (postype == POSOPT_SINGLE) { /* average of single position */ + if (!avepos(rr, rcvno, obs, nav, opt)) { + showmsg("error : station pos computation"); + return 0; } - else if (postype==POSOPT_FILE) { /* read from position file */ - name=stas[rcvno==1?0:1].name; - if (!getstapos(posfile,name,rr)) { - showmsg("error : no position of %s in %s",name,posfile); - return 0; - } + } else if (postype == POSOPT_FILE) { /* read from position file */ + name = stas[rcvno == 1 ? 0 : 1].name; + if (!getstapos(posfile, name, rr)) { + showmsg("error : no position of %s in %s", name, posfile); + return 0; } - else if (postype==POSOPT_RINEX) { /* get from rinex header */ - if (norm(stas[rcvno==1?0:1].pos,3)<=0.0) { - showmsg("error : no position in rinex header"); - trace(1,"no position in rinex header\n"); - return 0; - } - /* add antenna delta unless already done in antpcv() */ - if (!strcmp(opt->anttype[rcvno],"*")) { - if (stas[rcvno==1?0:1].deltype==0) { /* enu */ - for (i=0;i<3;i++) del[i]=stas[rcvno==1?0:1].del[i]; - del[2]+=stas[rcvno==1?0:1].hgt; - ecef2pos(stas[rcvno==1?0:1].pos,pos); - enu2ecef(pos,del,dr); - } else { /* xyz */ - for (i=0;i<3;i++) dr[i]=stas[rcvno==1?0:1].del[i]; - } - } - for (i=0;i<3;i++) rr[i]=stas[rcvno==1?0:1].pos[i]+dr[i]; + } else if (postype == POSOPT_RINEX) { /* get from rinex header */ + if (norm(stas[rcvno == 1 ? 0 : 1].pos, 3) <= 0.0) { + showmsg("error : no position in rinex header"); + trace(1, "no position in rinex header\n"); + return 0; } - return 1; + /* add antenna delta unless already done in antpcv() */ + if (!strcmp(opt->anttype[rcvno], "*")) { + if (stas[rcvno == 1 ? 0 : 1].deltype == 0) { /* enu */ + for (i = 0; i < 3; i++) del[i] = stas[rcvno == 1 ? 0 : 1].del[i]; + del[2] += stas[rcvno == 1 ? 0 : 1].hgt; + ecef2pos(stas[rcvno == 1 ? 0 : 1].pos, pos); + enu2ecef(pos, del, dr); + } else { /* xyz */ + for (i = 0; i < 3; i++) dr[i] = stas[rcvno == 1 ? 0 : 1].del[i]; + } + } + for (i = 0; i < 3; i++) rr[i] = stas[rcvno == 1 ? 0 : 1].pos[i] + dr[i]; + } + return 1; } /* open processing session ----------------------------------------------------*/ -static int openses(const prcopt_t *popt, const solopt_t *sopt, - const filopt_t *fopt, nav_t *nav, pcvs_t *pcvs, pcvs_t *pcvr) -{ - (void)popt; (void)nav; - trace(3,"openses :\n"); - - /* read satellite antenna parameters */ - if (*fopt->satantp&&!(readpcv(fopt->satantp,pcvs))) { - showmsg("error : no sat ant pcv in %s",fopt->satantp); - trace(1,"sat antenna pcv read error: %s\n",fopt->satantp); - return 0; - } - /* read receiver antenna parameters */ - if (*fopt->rcvantp&&!(readpcv(fopt->rcvantp,pcvr))) { - showmsg("error : no rec ant pcv in %s",fopt->rcvantp); - trace(1,"rec antenna pcv read error: %s\n",fopt->rcvantp); - return 0; - } - /* open geoid data */ - if (sopt->geoid>0&&*fopt->geoid) { - if (!opengeoid(sopt->geoid,fopt->geoid)) { - showmsg("error : no geoid data %s",fopt->geoid); - trace(2,"no geoid data %s\n",fopt->geoid); - } - } - return 1; +static int openses(const prcopt_t *popt, const solopt_t *sopt, const filopt_t *fopt, nav_t *nav, + pcvs_t *pcvs, pcvs_t *pcvr) { + (void)popt; + (void)nav; + trace(3, "openses :\n"); + + /* read satellite antenna parameters */ + if (*fopt->satantp && !(readpcv(fopt->satantp, pcvs))) { + showmsg("error : no sat ant pcv in %s", fopt->satantp); + trace(1, "sat antenna pcv read error: %s\n", fopt->satantp); + return 0; + } + /* read receiver antenna parameters */ + if (*fopt->rcvantp && !(readpcv(fopt->rcvantp, pcvr))) { + showmsg("error : no rec ant pcv in %s", fopt->rcvantp); + trace(1, "rec antenna pcv read error: %s\n", fopt->rcvantp); + return 0; + } + /* open geoid data */ + if (sopt->geoid > 0 && *fopt->geoid) { + if (!opengeoid(sopt->geoid, fopt->geoid)) { + showmsg("error : no geoid data %s", fopt->geoid); + trace(2, "no geoid data %s\n", fopt->geoid); + } + } + return 1; } /* close processing session ---------------------------------------------------*/ -static void closeses(nav_t *nav, pcvs_t *pcvs, pcvs_t *pcvr) -{ - trace(3,"closeses:\n"); +static void closeses(nav_t *nav, pcvs_t *pcvs, pcvs_t *pcvr) { + trace(3, "closeses:\n"); - /* free antenna parameters */ - free_pcvs(pcvs); - free_pcvs(pcvr); + /* free antenna parameters */ + free_pcvs(pcvs); + free_pcvs(pcvr); - /* close geoid data */ - closegeoid(); + /* close geoid data */ + closegeoid(); - /* free erp data */ - free(nav->erp.data); nav->erp.data=NULL; nav->erp.n=nav->erp.nmax=0; + /* free erp data */ + free(nav->erp.data); + nav->erp.data = NULL; + nav->erp.n = nav->erp.nmax = 0; - /* close solution statistics and debug trace */ - rtkclosestat(); - traceclose(); + /* close solution statistics and debug trace */ + rtkclosestat(); + traceclose(); } /* set antenna parameters ----------------------------------------------------*/ -static void setpcv(gtime_t time, prcopt_t *popt, nav_t *nav, const pcvs_t *pcvs, - const pcvs_t *pcvr, const sta_t *sta) -{ - pcv_t *pcv,pcv0={0}; - double pos[3],del[3]; - int i,j,mode=PMODE_DGPS<=popt->mode&&popt->mode<=PMODE_FIXED; - char id[8]; - - /* set satellite antenna parameters */ - for (i=0;ipcvs[i]=pcv0; - if (!(satsys(i+1,NULL)&popt->navsys)) continue; - if (!(pcv=searchpcv(i+1,"",time,pcvs))) { - satno2id(i+1,id); - trace(4,"no satellite antenna pcv: %s\n",id); - continue; - } - nav->pcvs[i]=*pcv; - } - for (i=0;i<(mode?2:1);i++) { - popt->pcvr[i]=pcv0; - if (!strcmp(popt->anttype[i],"*")) { /* set by station parameters */ - strcpy(popt->anttype[i],sta[i].antdes); - if (sta[i].deltype==1) { /* xyz */ - if (norm(sta[i].pos,3)>0.0) { - ecef2pos(sta[i].pos,pos); - ecef2enu(pos,sta[i].del,del); - for (j=0;j<3;j++) popt->antdel[i][j]=del[j]; - } - } - else { /* enu */ - for (j=0;j<3;j++) popt->antdel[i][j]=stas[i].del[j]; - } - } - if (!(pcv=searchpcv(0,popt->anttype[i],time,pcvr))) { - trace(2,"no receiver antenna pcv: %s\n",popt->anttype[i]); - *popt->anttype[i]='\0'; - continue; - } - strcpy(popt->anttype[i],pcv->type); - popt->pcvr[i]=*pcv; - } +static void setpcv(gtime_t time, prcopt_t *popt, nav_t *nav, const pcvs_t *pcvs, const pcvs_t *pcvr, + const sta_t *sta) { + pcv_t *pcv, pcv0 = {0}; + double pos[3], del[3]; + int i, j, mode = PMODE_DGPS <= popt->mode && popt->mode <= PMODE_FIXED; + char id[8]; + + /* set satellite antenna parameters */ + for (i = 0; i < MAXSAT; i++) { + nav->pcvs[i] = pcv0; + if (!(satsys(i + 1, NULL) & popt->navsys)) continue; + if (!(pcv = searchpcv(i + 1, "", time, pcvs))) { + satno2id(i + 1, id); + trace(4, "no satellite antenna pcv: %s\n", id); + continue; + } + nav->pcvs[i] = *pcv; + } + for (i = 0; i < (mode ? 2 : 1); i++) { + popt->pcvr[i] = pcv0; + if (!strcmp(popt->anttype[i], "*")) { /* set by station parameters */ + strcpy(popt->anttype[i], sta[i].antdes); + if (sta[i].deltype == 1) { /* xyz */ + if (norm(sta[i].pos, 3) > 0.0) { + ecef2pos(sta[i].pos, pos); + ecef2enu(pos, sta[i].del, del); + for (j = 0; j < 3; j++) popt->antdel[i][j] = del[j]; + } + } else { /* enu */ + for (j = 0; j < 3; j++) popt->antdel[i][j] = stas[i].del[j]; + } + } + if (!(pcv = searchpcv(0, popt->anttype[i], time, pcvr))) { + trace(2, "no receiver antenna pcv: %s\n", popt->anttype[i]); + *popt->anttype[i] = '\0'; + continue; + } + strcpy(popt->anttype[i], pcv->type); + popt->pcvr[i] = *pcv; + } } /* read ocean tide loading parameters ----------------------------------------*/ -static void readotl(prcopt_t *popt, const char *file, const sta_t *sta) -{ - int i,mode=PMODE_DGPS<=popt->mode&&popt->mode<=PMODE_FIXED; +static void readotl(prcopt_t *popt, const char *file, const sta_t *sta) { + int i, mode = PMODE_DGPS <= popt->mode && popt->mode <= PMODE_FIXED; - for (i=0;i<(mode?2:1);i++) { - readblq(file,sta[i].name,popt->odisp[i]); - } + for (i = 0; i < (mode ? 2 : 1); i++) { + readblq(file, sta[i].name, popt->odisp[i]); + } } /* write header to output file -----------------------------------------------*/ -static int outhead(const char *outfile, const char **infile, int n, - const prcopt_t *popt, const solopt_t *sopt) -{ - FILE *fp=stdout; +static int outhead(const char *outfile, const char **infile, int n, const prcopt_t *popt, + const solopt_t *sopt) { + FILE *fp = stdout; - trace(3,"outhead: outfile=%s n=%d\n",outfile,n); + trace(3, "outhead: outfile=%s n=%d\n", outfile, n); - if (*outfile) { - createdir(outfile); + if (*outfile) { + createdir(outfile); - if (!(fp=fopen(outfile,"wb"))) { - showmsg("error : open output file %s",outfile); - return 0; - } + if (!(fp = fopen(outfile, "wb"))) { + showmsg("error : open output file %s", outfile); + return 0; } - /* output header */ - outheader(fp,infile,n,popt,sopt); + } + /* output header */ + outheader(fp, infile, n, popt, sopt); - if (*outfile) fclose(fp); + if (*outfile) fclose(fp); - return 1; + return 1; } /* open output file for append -----------------------------------------------*/ -static FILE *openfile(const char *outfile) -{ - trace(3,"openfile: outfile=%s\n",outfile); +static FILE *openfile(const char *outfile) { + trace(3, "openfile: outfile=%s\n", outfile); - return !*outfile?stdout:fopen(outfile,"ab"); + return !*outfile ? stdout : fopen(outfile, "ab"); } /* Name time marks file ------------------------------------------------------*/ -static void namefiletm(char *outfiletm, const char *outfile) -{ - int i; - - for (i=(int)strlen(outfile);i>0;i--) { - if (outfile[i] == '.') { - break; - } - } - /* if no file extension, then name time marks file as name of outfile + _events.pos */ - if (i == 0) { - i = (int)strlen(outfile); - } - strncpy(outfiletm, outfile, i); - strcat(outfiletm, "_events.pos"); +static void namefiletm(char *outfiletm, const char *outfile) { + int i; + + for (i = (int)strlen(outfile); i > 0; i--) { + if (outfile[i] == '.') { + break; + } + } + /* if no file extension, then name time marks file as name of outfile + _events.pos */ + if (i == 0) { + i = (int)strlen(outfile); + } + strncpy(outfiletm, outfile, i); + strcat(outfiletm, "_events.pos"); } /* execute processing session ------------------------------------------------*/ -static int execses(gtime_t ts, gtime_t te, double ti, const prcopt_t *popt, - const solopt_t *sopt, const filopt_t *fopt, int flag, - const char **infile, const int *index, int n, const char *outfile) -{ - rtk_t *rtk_ptr = (rtk_t *)malloc(sizeof(rtk_t)); /* moved from stack to heap to avoid stack overflow warning */ - prcopt_t popt_=*popt; - char tracefile[1024],statfile[1024],path[1024],outfiletm[1024]={0}; - const char *ext; - int i,j,k,dcb_ok; - - trace(3,"execses : n=%d outfile=%s\n",n,outfile); - - /* open debug trace */ - if (flag&&sopt->trace>0) { - if (*outfile) { - strcpy(tracefile,outfile); - strcat(tracefile,".trace"); - } - else { - strcpy(tracefile,fopt->trace); - } - traceclose(); - traceopen(tracefile); - tracelevel(sopt->trace); - } - /* read ionosphere data file */ - if (*fopt->iono&&(ext=strrchr(fopt->iono,'.'))) { - if (strlen(ext)==4&&(ext[3]=='i'||ext[3]=='I'|| - strcmp(ext,".INX")==0||strcmp(ext,".inx")==0)) { - reppath(fopt->iono,path,ts,"",""); - readtec(path,&navs,1); - } - } - /* read erp data */ - if (*fopt->eop) { - free(navs.erp.data); navs.erp.data=NULL; navs.erp.n=navs.erp.nmax=0; - reppath(fopt->eop,path,ts,"",""); - if (!readerp(path,&navs.erp)) { - showmsg("error : no erp data %s",path); - trace(2,"no erp data %s\n",path); - } - } - /* read obs and nav data */ - if (!readobsnav(ts,te,ti,infile,index,n,&popt_,&obss,&navs,stas)) { - /* free obs and nav data */ - freeobsnav(&obss, &navs); - free(rtk_ptr); - return 0; - } - - /* read dcb parameters from DCB, BIA, BSX files */ - dcb_ok = 0; - for (i=0;idcb) { /* then check if DCB file specified */ - reppath(fopt->dcb,path,ts,"",""); - dcb_ok=readdcb(path,&navs,stas); - } - if (!dcb_ok) { - - } - /* set antenna parameters */ - if (popt_.mode!=PMODE_SINGLE) { - setpcv(obss.n>0?obss.data[0].time:timeget(),&popt_,&navs,&pcvss,&pcvsr, - stas); - } - /* read ocean tide loading parameters */ - if (popt_.mode>PMODE_SINGLE&&*fopt->blq) { - readotl(&popt_,fopt->blq,stas); +static int execses(gtime_t ts, gtime_t te, double ti, const prcopt_t *popt, const solopt_t *sopt, + const filopt_t *fopt, int flag, const char **infile, const int *index, int n, + const char *outfile) { + rtk_t *rtk_ptr = + (rtk_t *)malloc(sizeof(rtk_t)); /* moved from stack to heap to avoid stack overflow warning */ + prcopt_t popt_ = *popt; + char tracefile[1024], statfile[1024], path[1024], outfiletm[1024] = {0}; + const char *ext; + int i, j, k, dcb_ok; + + trace(3, "execses : n=%d outfile=%s\n", n, outfile); + + /* open debug trace */ + if (flag && sopt->trace > 0) { + if (*outfile) { + strcpy(tracefile, outfile); + strcat(tracefile, ".trace"); + } else { + strcpy(tracefile, fopt->trace); } - /* rover/reference fixed position */ - if (popt_.mode==PMODE_FIXED) { - if (!antpos(&popt_,1,&obss,&navs,stas,fopt->stapos)) { - freeobsnav(&obss,&navs); - free(rtk_ptr); - return 0; - } - if (!antpos(&popt_,2,&obss,&navs,stas,fopt->stapos)) { - freeobsnav(&obss,&navs); - free(rtk_ptr); - return 0; - } + traceclose(); + traceopen(tracefile); + tracelevel(sopt->trace); + } + /* read ionosphere data file */ + if (*fopt->iono && (ext = strrchr(fopt->iono, '.'))) { + if (strlen(ext) == 4 && + (ext[3] == 'i' || ext[3] == 'I' || strcmp(ext, ".INX") == 0 || strcmp(ext, ".inx") == 0)) { + reppath(fopt->iono, path, ts, "", ""); + readtec(path, &navs, 1); + } + } + /* read erp data */ + if (*fopt->eop) { + free(navs.erp.data); + navs.erp.data = NULL; + navs.erp.n = navs.erp.nmax = 0; + reppath(fopt->eop, path, ts, "", ""); + if (!readerp(path, &navs.erp)) { + showmsg("error : no erp data %s", path); + trace(2, "no erp data %s\n", path); + } + } + /* read obs and nav data */ + if (!readobsnav(ts, te, ti, infile, index, n, &popt_, &obss, &navs, stas)) { + /* free obs and nav data */ + freeobsnav(&obss, &navs); + free(rtk_ptr); + return 0; + } + + /* read dcb parameters from DCB, BIA, BSX files */ + dcb_ok = 0; + for (i = 0; i < MAX_CODE_BIASES; i++) + for (k = 0; k < MAX_CODE_BIAS_FREQS; k++) { + /* FIXME: cbias later initialized with 0 in readdcb()! */ + for (j = 0; j < MAXSAT; j++) navs.cbias[j][k][i] = -1; + for (j = 0; j < MAXRCV; j++) navs.rbias[j][k][i] = 0; + } + for (i = 0; i < n; i++) { /* first check infiles for .BIA or .BSX files */ + if ((dcb_ok = readdcb(infile[i], &navs, stas))) break; + } + if (!dcb_ok && *fopt->dcb) { /* then check if DCB file specified */ + reppath(fopt->dcb, path, ts, "", ""); + dcb_ok = readdcb(path, &navs, stas); + } + if (!dcb_ok) { + } + /* set antenna parameters */ + if (popt_.mode != PMODE_SINGLE) { + setpcv(obss.n > 0 ? obss.data[0].time : timeget(), &popt_, &navs, &pcvss, &pcvsr, stas); + } + /* read ocean tide loading parameters */ + if (popt_.mode > PMODE_SINGLE && *fopt->blq) { + readotl(&popt_, fopt->blq, stas); + } + /* rover/reference fixed position */ + if (popt_.mode == PMODE_FIXED) { + if (!antpos(&popt_, 1, &obss, &navs, stas, fopt->stapos)) { + freeobsnav(&obss, &navs); + free(rtk_ptr); + return 0; } - else if (PMODE_DGPS<=popt_.mode&&popt_.mode<=PMODE_STATIC_START) { - if (!antpos(&popt_,2,&obss,&navs,stas,fopt->stapos)) { - freeobsnav(&obss,&navs); - free(rtk_ptr); - return 0; - } + if (!antpos(&popt_, 2, &obss, &navs, stas, fopt->stapos)) { + freeobsnav(&obss, &navs); + free(rtk_ptr); + return 0; } - /* open solution statistics */ - if (flag&&sopt->sstat>0) { - strcpy(statfile,outfile); - strcat(statfile,".stat"); - rtkclosestat(); - rtkopenstat(statfile,sopt->sstat); + } else if (PMODE_DGPS <= popt_.mode && popt_.mode <= PMODE_STATIC_START) { + if (!antpos(&popt_, 2, &obss, &navs, stas, fopt->stapos)) { + freeobsnav(&obss, &navs); + free(rtk_ptr); + return 0; } - /* write header to output file */ - if (flag&&!outhead(outfile,infile,n,&popt_,sopt)) { - freeobsnav(&obss,&navs); - free(rtk_ptr); + } + /* open solution statistics */ + if (flag && sopt->sstat > 0) { + strcpy(statfile, outfile); + strcat(statfile, ".stat"); + rtkclosestat(); + rtkopenstat(statfile, sopt->sstat); + } + /* write header to output file */ + if (flag && !outhead(outfile, infile, n, &popt_, sopt)) { + freeobsnav(&obss, &navs); + free(rtk_ptr); + return 0; + } + /* name time events file */ + namefiletm(outfiletm, outfile); + /* write header to file with time marks */ + outhead(outfiletm, infile, n, &popt_, sopt); + + iobsu = iobsr = isbs = reverse = aborts = 0; + + if (popt_.mode == PMODE_SINGLE || popt_.soltype == SOLTYPE_FORWARD) { + FILE *fp = openfile(outfile); + if (fp) { + FILE *fptm = openfile(outfiletm); + if (fptm) { + rtkinit(rtk_ptr, &popt_); + procpos(fp, fptm, &popt_, sopt, rtk_ptr, SOLMODE_SINGLE_DIR); + rtkfree(rtk_ptr); + fclose(fptm); + } + fclose(fp); + } + } else if (popt_.soltype == SOLTYPE_BACKWARD) { + FILE *fp = openfile(outfile); + if (fp) { + FILE *fptm = openfile(outfiletm); + if (fptm) { + reverse = 1; + iobsu = iobsr = obss.n - 1; + isbs = sbss.n - 1; + rtkinit(rtk_ptr, &popt_); + procpos(fp, fptm, &popt_, sopt, rtk_ptr, SOLMODE_SINGLE_DIR); + rtkfree(rtk_ptr); + fclose(fptm); + } + fclose(fp); + } + } else { /* combined or combined with no phase reset */ + solf = (sol_t *)malloc(sizeof(sol_t) * nepoch); + solb = (sol_t *)malloc(sizeof(sol_t) * nepoch); + rbf = (double *)malloc(sizeof(double) * nepoch * 3); + rbb = (double *)malloc(sizeof(double) * nepoch * 3); + + if (solf && solb) { + isolf = isolb = 0; + rtkinit(rtk_ptr, &popt_); + procpos(NULL, NULL, &popt_, sopt, rtk_ptr, SOLMODE_COMBINED); /* forward */ + reverse = 1; + iobsu = iobsr = obss.n - 1; + isbs = sbss.n - 1; + if (popt_.soltype != SOLTYPE_COMBINED_NORESET) { + /* Reset */ + rtkfree(rtk_ptr); + rtkinit(rtk_ptr, &popt_); + } + procpos(NULL, NULL, &popt_, sopt, rtk_ptr, SOLMODE_COMBINED); /* backward */ + rtkfree(rtk_ptr); + + /* combine forward/backward solutions */ + if (!aborts) { + FILE *fp = openfile(outfile); + if (fp) { + FILE *fptm = openfile(outfiletm); + if (fptm) { + combres(fp, fptm, &popt_, sopt); + fclose(fptm); + } + fclose(fp); + } + } + } else + showmsg("error : memory allocation"); + free(solf); + free(solb); + free(rbf); + free(rbb); + } + /* free rtk, obs and nav data */ + free(rtk_ptr); + freeobsnav(&obss, &navs); + + return aborts ? 1 : 0; +} +/* execute processing session for each rover ---------------------------------*/ +static int execses_r(gtime_t ts, gtime_t te, double ti, const prcopt_t *popt, const solopt_t *sopt, + const filopt_t *fopt, int flag, const char **infile, const int *index, int n, + const char *outfile, const char *rov) { + gtime_t t0 = {0}; + int i, stat = 0; + char *ifile[MAXINFILE], ofile[1024], *rov_, *q, s[40] = ""; + const char *p; + + trace(3, "execses_r: n=%d outfile=%s\n", n, outfile); + + for (i = 0; i < n; i++) + if (strstr(infile[i], "%r")) break; + + if (i < n) { /* include rover keywords */ + if (!(rov_ = (char *)malloc(strlen(rov) + 1))) return 0; + strcpy(rov_, rov); + + for (i = 0; i < n; i++) { + if (!(ifile[i] = (char *)malloc(1024))) { + free(rov_); + for (; i >= 0; i--) free(ifile[i]); return 0; + } } - /* name time events file */ - namefiletm(outfiletm,outfile); - /* write header to file with time marks */ - outhead(outfiletm,infile,n,&popt_,sopt); + for (p = rov_;; p = q + 1) { /* for each rover */ + if ((q = strchr(p, ' '))) *q = '\0'; - iobsu=iobsr=isbs=reverse=aborts=0; - - if (popt_.mode==PMODE_SINGLE||popt_.soltype==SOLTYPE_FORWARD) { - FILE *fp=openfile(outfile); - if (fp) { - FILE *fptm=openfile(outfiletm); - if (fptm) { - rtkinit(rtk_ptr,&popt_); - procpos(fp,fptm,&popt_,sopt,rtk_ptr,SOLMODE_SINGLE_DIR); - rtkfree(rtk_ptr); - fclose(fptm); - } - fclose(fp); + if (*p) { + strcpy(proc_rov, p); + if (ts.time) + time2str(ts, s, 0); + else + *s = '\0'; + if (checkbrk("reading : %s", s)) { + stat = 1; + break; } - } - else if (popt_.soltype==SOLTYPE_BACKWARD) { - FILE *fp=openfile(outfile); - if (fp) { - FILE *fptm=openfile(outfiletm); - if (fptm) { - reverse=1; iobsu=iobsr=obss.n-1; isbs=sbss.n-1; - rtkinit(rtk_ptr,&popt_); - procpos(fp,fptm,&popt_,sopt,rtk_ptr,SOLMODE_SINGLE_DIR); - rtkfree(rtk_ptr); - fclose(fptm); - } - fclose(fp); - } - } - else { /* combined or combined with no phase reset */ - solf=(sol_t *)malloc(sizeof(sol_t)*nepoch); - solb=(sol_t *)malloc(sizeof(sol_t)*nepoch); - rbf=(double *)malloc(sizeof(double)*nepoch*3); - rbb=(double *)malloc(sizeof(double)*nepoch*3); - - if (solf&&solb) { - isolf=isolb=0; - rtkinit(rtk_ptr,&popt_); - procpos(NULL,NULL,&popt_,sopt,rtk_ptr,SOLMODE_COMBINED); /* forward */ - reverse=1; iobsu=iobsr=obss.n-1; isbs=sbss.n-1; - if (popt_.soltype!=SOLTYPE_COMBINED_NORESET) { - /* Reset */ - rtkfree(rtk_ptr); - rtkinit(rtk_ptr,&popt_); - } - procpos(NULL,NULL,&popt_,sopt,rtk_ptr,SOLMODE_COMBINED); /* backward */ - rtkfree(rtk_ptr); - - /* combine forward/backward solutions */ - if (!aborts) { - FILE *fp=openfile(outfile); - if (fp) { - FILE *fptm=openfile(outfiletm); - if (fptm) { - combres(fp,fptm,&popt_,sopt); - fclose(fptm); - } - fclose(fp); - } - } - } - else showmsg("error : memory allocation"); - free(solf); - free(solb); - free(rbf); - free(rbb); - } - /* free rtk, obs and nav data */ - free(rtk_ptr); - freeobsnav(&obss,&navs); + for (i = 0; i < n; i++) reppath(infile[i], ifile[i], t0, p, ""); + reppath(outfile, ofile, t0, p, ""); - return aborts?1:0; -} -/* execute processing session for each rover ---------------------------------*/ -static int execses_r(gtime_t ts, gtime_t te, double ti, const prcopt_t *popt, - const solopt_t *sopt, const filopt_t *fopt, int flag, - const char **infile, const int *index, int n, const char *outfile, - const char *rov) -{ - gtime_t t0={0}; - int i,stat=0; - char *ifile[MAXINFILE],ofile[1024],*rov_,*q,s[40]=""; - const char *p; - - trace(3,"execses_r: n=%d outfile=%s\n",n,outfile); - - for (i=0;i=0;i--) free(ifile[i]); - return 0; - } - } - for (p=rov_;;p=q+1) { /* for each rover */ - if ((q=strchr(p,' '))) *q='\0'; - - if (*p) { - strcpy(proc_rov,p); - if (ts.time) time2str(ts,s,0); else *s='\0'; - if (checkbrk("reading : %s",s)) { - stat=1; - break; - } - for (i=0;i=0;i--) free(ifile[i]); - freepreceph(&navs,&sbss); - return 0; - } - } - for (p=base_;;p=q+1) { /* for each base station */ - if ((q=strchr(p,' '))) *q='\0'; - - if (*p) { - strcpy(proc_base,p); - if (ts.time) time2str(ts,s,0); else *s='\0'; - if (checkbrk("reading : %s",s)) { - stat=1; - break; - } - for (i=0;i:error,1:aborted) -* notes : input files should contain observation data, navigation data, precise -* ephemeris/clock (optional), sbas log file (optional), ssr message -* log file (optional) and tec grid file (optional). only the first -* observation data file in the input files is recognized as the rover -* data. -* -* the type of an input file is recognized by the file extension as ] -* follows: -* .sp3,.SP3,.eph*,.EPH*: precise ephemeris (sp3c) -* .sbs,.SBS,.ems,.EMS : sbas message log files (rtklib or ems) -* .rtcm3,.RTCM3 : ssr message log files (rtcm3) -* .*i,.*I : tec grid files (ionex) -* others : rinex obs, nav, gnav, hnav, qnav or clock -* -* inputs files can include wild-cards (*). if an file includes -* wild-cards, the wild-card expanded multiple files are used. -* -* inputs files can include keywords. if an file includes keywords, -* the keywords are replaced by date, time, rover id and base station -* id and multiple session analyses run. refer reppath() for the -* keywords. -* -* the output file can also include keywords. if the output file does -* not include keywords. the results of all multiple session analyses -* are output to a single output file. -* -* ssr corrections are valid only for forward estimation. -*-----------------------------------------------------------------------------*/ -extern int postpos(gtime_t ts, gtime_t te, double ti, double tu, - const prcopt_t *popt, const solopt_t *sopt, - const filopt_t *fopt, const char **infile, int n, const char *outfile, - const char *rov, const char *base) -{ - gtime_t tts,tte,ttte; - double tunit,tss; - int i,j,k,nf,stat=0,week,flag=1,index[MAXINFILE]={0}; - char *ifile[MAXINFILE],ofile[1024]; - const char *ext; - - trace(3,"postpos : ti=%.0f tu=%.0f n=%d outfile=%s\n",ti,tu,n,outfile); - - /* open processing session */ - if (!openses(popt,sopt,fopt,&navs,&pcvss,&pcvsr)) return -1; - - if (ts.time!=0&&te.time!=0&&tu>=0.0) { - if (timediff(te,ts)<0.0) { - showmsg("error : no period"); - closeses(&navs,&pcvss,&pcvsr); - return 0; - } - for (i=0;i=0;i--) free(ifile[i]); - closeses(&navs,&pcvss,&pcvsr); - return -1; - } - } - if (tu==0.0||tu>86400.0*MAXPRCDAYS) tu=86400.0*MAXPRCDAYS; - settspan(ts,te); - tunit=tu<86400.0?tu:86400.0; - tss=tunit*(int)floor(time2gpst(ts,&week)/tunit); - - for (i=0;;i++) { /* for each periods */ - tts=gpst2time(week,tss+i*tu); - tte=timeadd(tts,tu-DTTOL); - if (timediff(tts,te)>0.0) break; - if (timediff(tts,ts)<0.0) tts=ts; - if (timediff(tte,te)>0.0) tte=te; - - strcpy(proc_rov ,""); - strcpy(proc_base,""); - char tstr[40]; - if (checkbrk("reading : %s",time2str(tts,tstr,0))) { - stat=1; - break; - } - for (j=k=nf=0;j=MAXINFILE) { - trace(2,"too many input files. trancated\n"); - break; - } - } - if (!reppath(outfile,ofile,tts,"","")&&i>0) flag=0; - - /* execute processing session */ - stat=execses_b(tts,tte,ti,popt,sopt,fopt,flag,(const char **)ifile,index,nf,(const char *)ofile, - rov,base); - - if (stat==1) break; - } - for (i=0;i=0;i--) free(ifile[i]); - return -1; - } - reppath(infile[i],ifile[i],ts,"",""); - index[i]=i; - } - reppath(outfile,ofile,ts,"",""); + trace(3, "execses_b: n=%d outfile=%s\n", n, outfile); - /* execute processing session */ - stat=execses_b(ts,te,ti,popt,sopt,fopt,1,(const char **)ifile,index,n,ofile,rov, - base); + /* read prec ephemeris and sbas data */ + readpreceph(infile, n, popt, &navs, &sbss); - for (i=0;i= 0; i--) free(ifile[i]); + freepreceph(&navs, &sbss); + return 0; + } + } + for (p = base_;; p = q + 1) { /* for each base station */ + if ((q = strchr(p, ' '))) *q = '\0'; + + if (*p) { + strcpy(proc_base, p); + if (ts.time) + time2str(ts, s, 0); + else + *s = '\0'; + if (checkbrk("reading : %s", s)) { + stat = 1; + break; + } + for (i = 0; i < n; i++) reppath(infile[i], ifile[i], t0, "", p); + reppath(outfile, ofile, t0, "", p); + + stat = execses_r(ts, te, ti, popt, sopt, fopt, flag, (const char **)ifile, index, n, + (const char *)ofile, rov); + } + if (stat == 1 || !q) break; + } + free(base_); + for (i = 0; i < n; i++) free(ifile[i]); + } else { + stat = execses_r(ts, te, ti, popt, sopt, fopt, flag, infile, index, n, outfile, rov); + } + /* free prec ephemeris and sbas data */ + freepreceph(&navs, &sbss); + + return stat; +} +/* post-processing positioning ------------------------------------------------- + * post-processing positioning + * args : gtime_t ts I processing start time (ts.time==0: no limit) + * : gtime_t te I processing end time (te.time==0: no limit) + * double ti I processing interval (s) (0:all) + * double tu I processing unit time (s) (0:all) + * prcopt_t *popt I processing options + * solopt_t *sopt I solution options + * filopt_t *fopt I file options + * char **infile I input files (see below) + * int n I number of input files + * char *outfile I output file ("":stdout, see below) + * char *rov I rover id list (separated by " ") + * char *base I base station id list (separated by " ") + * return : status (0:ok,0>:error,1:aborted) + * notes : input files should contain observation data, navigation data, precise + * ephemeris/clock (optional), sbas log file (optional), ssr message + * log file (optional) and tec grid file (optional). only the first + * observation data file in the input files is recognized as the rover + * data. + * + * the type of an input file is recognized by the file extension as ] + * follows: + * .sp3,.SP3,.eph*,.EPH*: precise ephemeris (sp3c) + * .sbs,.SBS,.ems,.EMS : sbas message log files (rtklib or ems) + * .rtcm3,.RTCM3 : ssr message log files (rtcm3) + * .*i,.*I : tec grid files (ionex) + * others : rinex obs, nav, gnav, hnav, qnav or clock + * + * inputs files can include wild-cards (*). if an file includes + * wild-cards, the wild-card expanded multiple files are used. + * + * inputs files can include keywords. if an file includes keywords, + * the keywords are replaced by date, time, rover id and base station + * id and multiple session analyses run. refer reppath() for the + * keywords. + * + * the output file can also include keywords. if the output file does + * not include keywords. the results of all multiple session analyses + * are output to a single output file. + * + * ssr corrections are valid only for forward estimation. + *-----------------------------------------------------------------------------*/ +extern int postpos(gtime_t ts, gtime_t te, double ti, double tu, const prcopt_t *popt, + const solopt_t *sopt, const filopt_t *fopt, const char **infile, int n, + const char *outfile, const char *rov, const char *base) { + gtime_t tts, tte, ttte; + double tunit, tss; + int i, j, k, nf, stat = 0, week, flag = 1, index[MAXINFILE] = {0}; + char *ifile[MAXINFILE], ofile[1024]; + const char *ext; + + trace(3, "postpos : ti=%.0f tu=%.0f n=%d outfile=%s\n", ti, tu, n, outfile); + + /* open processing session */ + if (!openses(popt, sopt, fopt, &navs, &pcvss, &pcvsr)) return -1; + + if (ts.time != 0 && te.time != 0 && tu >= 0.0) { + if (timediff(te, ts) < 0.0) { + showmsg("error : no period"); + closeses(&navs, &pcvss, &pcvsr); + return 0; + } + for (i = 0; i < MAXINFILE; i++) { + if (!(ifile[i] = (char *)malloc(1024))) { + for (; i >= 0; i--) free(ifile[i]); + closeses(&navs, &pcvss, &pcvsr); + return -1; + } + } + if (tu == 0.0 || tu > 86400.0 * MAXPRCDAYS) tu = 86400.0 * MAXPRCDAYS; + settspan(ts, te); + tunit = tu < 86400.0 ? tu : 86400.0; + tss = tunit * (int)floor(time2gpst(ts, &week) / tunit); + + for (i = 0;; i++) { /* for each periods */ + tts = gpst2time(week, tss + i * tu); + tte = timeadd(tts, tu - DTTOL); + if (timediff(tts, te) > 0.0) break; + if (timediff(tts, ts) < 0.0) tts = ts; + if (timediff(tte, te) > 0.0) tte = te; + + strcpy(proc_rov, ""); + strcpy(proc_base, ""); + char tstr[40]; + if (checkbrk("reading : %s", time2str(tts, tstr, 0))) { + stat = 1; + break; + } + for (j = k = nf = 0; j < n; j++) { + ext = strrchr(infile[j], '.'); + + if (ext && (!strcmp(ext, ".rtcm3") || !strcmp(ext, ".RTCM3"))) { + strcpy(ifile[nf++], infile[j]); + } else { + /* include next day precise ephemeris or rinex brdc nav */ + ttte = tte; + if (ext && (!strcmp(ext, ".sp3") || !strcmp(ext, ".SP3") || !strcmp(ext, ".eph") || + !strcmp(ext, ".EPH"))) { + ttte = timeadd(ttte, 3600.0); + } else if (strstr(infile[j], "brdc")) { + ttte = timeadd(ttte, 7200.0); + } + nf += reppaths(infile[j], ifile + nf, MAXINFILE - nf, tts, ttte, "", ""); + } + while (k < nf) index[k++] = j; + + if (nf >= MAXINFILE) { + trace(2, "too many input files. trancated\n"); + break; + } + } + if (!reppath(outfile, ofile, tts, "", "") && i > 0) flag = 0; + + /* execute processing session */ + stat = execses_b(tts, tte, ti, popt, sopt, fopt, flag, (const char **)ifile, index, nf, + (const char *)ofile, rov, base); + + if (stat == 1) break; + } + for (i = 0; i < MAXINFILE; i++) free(ifile[i]); + } else if (ts.time != 0) { + for (i = 0; i < n && i < MAXINFILE; i++) { + if (!(ifile[i] = (char *)malloc(1024))) { + for (; i >= 0; i--) free(ifile[i]); + return -1; + } + reppath(infile[i], ifile[i], ts, "", ""); + index[i] = i; + } + reppath(outfile, ofile, ts, "", ""); + + /* execute processing session */ + stat = execses_b(ts, te, ti, popt, sopt, fopt, 1, (const char **)ifile, index, n, ofile, rov, + base); + + for (i = 0; i < n && i < MAXINFILE; i++) free(ifile[i]); + } else { + for (i = 0; i < n; i++) index[i] = i; + + /* execute processing session */ + stat = execses_b(ts, te, ti, popt, sopt, fopt, 1, infile, index, n, outfile, rov, base); + } + /* close processing session */ + closeses(&navs, &pcvss, &pcvsr); + + return stat; } diff --git a/src/ppp.c b/src/ppp.c index 385dc9990..adb685cdf 100644 --- a/src/ppp.c +++ b/src/ppp.c @@ -1,1275 +1,1303 @@ /*------------------------------------------------------------------------------ -* ppp.c : precise point positioning -* -* Copyright (C) 2010-2020 by T.TAKASU, All rights reserved. -* -* options : -DIERS_MODEL use IERS tide model -* -DOUTSTAT_AMB output ambiguity parameters to solution status -* -* references : -* [1] D.D.McCarthy, IERS Technical Note 21, IERS Conventions 1996, July 1996 -* [2] D.D.McCarthy and G.Petit, IERS Technical Note 32, IERS Conventions -* 2003, November 2003 -* [3] D.A.Vallado, Fundamentals of Astrodynamics and Applications 2nd ed, -* Space Technology Library, 2004 -* [4] J.Kouba, A Guide to using International GNSS Service (IGS) products, -* May 2009 -* [5] RTCM Paper, April 12, 2010, Proposed SSR Messages for SV Orbit Clock, -* Code Biases, URA -* [6] MacMillan et al., Atmospheric gradients and the VLBI terrestrial and -* celestial reference frames, Geophys. Res. Let., 1997 -* [7] G.Petit and B.Luzum (eds), IERS Technical Note No. 36, IERS -* Conventions (2010), 2010 -* [8] J.Kouba, A simplified yaw-attitude model for eclipsing GPS satellites, -* GPS Solutions, 13:1-12, 2009 -* [9] F.Dilssner, GPS IIF-1 satellite antenna phase center and attitude -* modeling, InsideGNSS, September, 2010 -* [10] F.Dilssner, The GLONASS-M satellite yaw-attitude model, Advances in -* Space Research, 2010 -* [11] IGS MGEX (http://igs.org/mgex) -* -* version : $Revision:$ $Date:$ -* history : 2010/07/20 1.0 new -* added api: -* tidedisp() -* 2010/12/11 1.1 enable exclusion of eclipsing satellite -* 2012/02/01 1.2 add gps-glonass h/w bias correction -* move windupcorr() to rtkcmn.c -* 2013/03/11 1.3 add otl and pole tides corrections -* involve iers model with -DIERS_MODEL -* change initial variances -* suppress acos domain error -* 2013/09/01 1.4 pole tide model by iers 2010 -* add mode of ionosphere model off -* 2014/05/23 1.5 add output of trop gradient in solution status -* 2014/10/13 1.6 fix bug on P0(a[3]) computation in tide_oload() -* fix bug on m2 computation in tide_pole() -* 2015/03/19 1.7 fix bug on ionosphere correction for GLO and BDS -* 2015/05/10 1.8 add function to detect slip by MW-LC jump -* fix ppp solution problem with large clock variance -* 2015/06/08 1.9 add precise satellite yaw-models -* cope with day-boundary problem of satellite clock -* 2015/07/31 1.10 fix bug on nan-solution without glonass nav-data -* pppoutsolsat() -> pppoutstat() -* 2015/11/13 1.11 add L5-receiver-dcb estimation -* merge post-residual validation by rnx2rtkp_test -* support support option opt->pppopt=-GAP_RESION=nnnn -* 2016/01/22 1.12 delete support for yaw-model bug -* add support for ura of ephemeris -* 2018/10/10 1.13 support api change of satexclude() -* 2020/11/30 1.14 use sat2freq() to get carrier frequency -* use E1-E5b for Galileo iono-free LC -*-----------------------------------------------------------------------------*/ + * ppp.c : precise point positioning + * + * Copyright (C) 2010-2020 by T.TAKASU, All rights reserved. + * + * options : -DIERS_MODEL use IERS tide model + * -DOUTSTAT_AMB output ambiguity parameters to solution status + * + * references : + * [1] D.D.McCarthy, IERS Technical Note 21, IERS Conventions 1996, July 1996 + * [2] D.D.McCarthy and G.Petit, IERS Technical Note 32, IERS Conventions + * 2003, November 2003 + * [3] D.A.Vallado, Fundamentals of Astrodynamics and Applications 2nd ed, + * Space Technology Library, 2004 + * [4] J.Kouba, A Guide to using International GNSS Service (IGS) products, + * May 2009 + * [5] RTCM Paper, April 12, 2010, Proposed SSR Messages for SV Orbit Clock, + * Code Biases, URA + * [6] MacMillan et al., Atmospheric gradients and the VLBI terrestrial and + * celestial reference frames, Geophys. Res. Let., 1997 + * [7] G.Petit and B.Luzum (eds), IERS Technical Note No. 36, IERS + * Conventions (2010), 2010 + * [8] J.Kouba, A simplified yaw-attitude model for eclipsing GPS satellites, + * GPS Solutions, 13:1-12, 2009 + * [9] F.Dilssner, GPS IIF-1 satellite antenna phase center and attitude + * modeling, InsideGNSS, September, 2010 + * [10] F.Dilssner, The GLONASS-M satellite yaw-attitude model, Advances in + * Space Research, 2010 + * [11] IGS MGEX (http://igs.org/mgex) + * + * version : $Revision:$ $Date:$ + * history : 2010/07/20 1.0 new + * added api: + * tidedisp() + * 2010/12/11 1.1 enable exclusion of eclipsing satellite + * 2012/02/01 1.2 add gps-glonass h/w bias correction + * move windupcorr() to rtkcmn.c + * 2013/03/11 1.3 add otl and pole tides corrections + * involve iers model with -DIERS_MODEL + * change initial variances + * suppress acos domain error + * 2013/09/01 1.4 pole tide model by iers 2010 + * add mode of ionosphere model off + * 2014/05/23 1.5 add output of trop gradient in solution status + * 2014/10/13 1.6 fix bug on P0(a[3]) computation in tide_oload() + * fix bug on m2 computation in tide_pole() + * 2015/03/19 1.7 fix bug on ionosphere correction for GLO and BDS + * 2015/05/10 1.8 add function to detect slip by MW-LC jump + * fix ppp solution problem with large clock variance + * 2015/06/08 1.9 add precise satellite yaw-models + * cope with day-boundary problem of satellite clock + * 2015/07/31 1.10 fix bug on nan-solution without glonass nav-data + * pppoutsolsat() -> pppoutstat() + * 2015/11/13 1.11 add L5-receiver-dcb estimation + * merge post-residual validation by rnx2rtkp_test + * support support option opt->pppopt=-GAP_RESION=nnnn + * 2016/01/22 1.12 delete support for yaw-model bug + * add support for ura of ephemeris + * 2018/10/10 1.13 support api change of satexclude() + * 2020/11/30 1.14 use sat2freq() to get carrier frequency + * use E1-E5b for Galileo iono-free LC + *-----------------------------------------------------------------------------*/ #include "rtklib.h" -#define SQR(x) ((x)*(x)) -#define SQRT(x) ((x)<=0.0||(x)!=(x)?0.0:sqrt(x)) -#define MAX(x,y) ((x)>(y)?(x):(y)) -#define MIN(x,y) ((x)<(y)?(x):(y)) -#define ROUND(x) (int)floor((x)+0.5) +#define SQR(x) ((x) * (x)) +#define SQRT(x) ((x) <= 0.0 || (x) != (x) ? 0.0 : sqrt(x)) +#define MAX(x, y) ((x) > (y) ? (x) : (y)) +#define MIN(x, y) ((x) < (y) ? (x) : (y)) +#define ROUND(x) (int)floor((x) + 0.5) -#define MAX_ITER 8 /* max number of iterations */ -#define MAX_STD_FIX 0.15 /* max std-dev (3d) to fix solution */ -#define MIN_NSAT_SOL 4 /* min satellite number for solution */ -#define THRES_REJECT 4.0 /* reject threshold of posfit-res (sigma) */ +#define MAX_ITER 8 /* max number of iterations */ +#define MAX_STD_FIX 0.15 /* max std-dev (3d) to fix solution */ +#define MIN_NSAT_SOL 4 /* min satellite number for solution */ +#define THRES_REJECT 4.0 /* reject threshold of posfit-res (sigma) */ #define THRES_MW_JUMP 10.0 -#define VAR_POS SQR(60.0) /* init variance receiver position (m^2) */ -#define VAR_VEL SQR(10.0) /* init variance of receiver vel ((m/s)^2) */ -#define VAR_ACC SQR(10.0) /* init variance of receiver acc ((m/ss)^2) */ -#define VAR_CLK SQR(60.0) /* init variance receiver clock (m^2) */ -#define VAR_ZTD SQR( 0.6) /* init variance ztd (m^2) */ -#define VAR_GRA SQR(0.01) /* init variance gradient (m^2) */ -#define VAR_DCB SQR(30.0) /* init variance dcb (m^2) */ -#define VAR_BIAS SQR(60.0) /* init variance phase-bias (m^2) */ -#define VAR_IONO SQR(60.0) /* init variance iono-delay */ -#define VAR_GLO_IFB SQR( 0.6) /* variance of glonass ifb */ - -#define ERR_SAAS 0.3 /* saastamoinen model error std (m) */ -#define ERR_BRDCI 0.5 /* broadcast iono model error factor */ -#define ERR_CBIAS 0.3 /* code bias error std (m) */ -#define REL_HUMI 0.7 /* relative humidity for saastamoinen model */ -#define GAP_RESION 120 /* default gap to reset ionos parameters (ep) */ - -#define EFACT_GPS_L5 10.0 /* error factor of GPS/QZS L5 */ - -#define MUDOT_GPS (0.00836*D2R) /* average angular velocity GPS (rad/s) */ -#define MUDOT_GLO (0.00888*D2R) /* average angular velocity GLO (rad/s) */ -#define EPS0_GPS (13.5*D2R) /* max shadow crossing angle GPS (rad) */ -#define EPS0_GLO (14.2*D2R) /* max shadow crossing angle GLO (rad) */ -#define T_POSTSHADOW 1800.0 /* post-shadow recovery time (s) */ -#define QZS_EC_BETA 20.0 /* max beta angle for qzss Ec (deg) */ +#define VAR_POS SQR(60.0) /* init variance receiver position (m^2) */ +#define VAR_VEL SQR(10.0) /* init variance of receiver vel ((m/s)^2) */ +#define VAR_ACC SQR(10.0) /* init variance of receiver acc ((m/ss)^2) */ +#define VAR_CLK SQR(60.0) /* init variance receiver clock (m^2) */ +#define VAR_ZTD SQR(0.6) /* init variance ztd (m^2) */ +#define VAR_GRA SQR(0.01) /* init variance gradient (m^2) */ +#define VAR_DCB SQR(30.0) /* init variance dcb (m^2) */ +#define VAR_BIAS SQR(60.0) /* init variance phase-bias (m^2) */ +#define VAR_IONO SQR(60.0) /* init variance iono-delay */ +#define VAR_GLO_IFB SQR(0.6) /* variance of glonass ifb */ + +#define ERR_SAAS 0.3 /* saastamoinen model error std (m) */ +#define ERR_BRDCI 0.5 /* broadcast iono model error factor */ +#define ERR_CBIAS 0.3 /* code bias error std (m) */ +#define REL_HUMI 0.7 /* relative humidity for saastamoinen model */ +#define GAP_RESION 120 /* default gap to reset ionos parameters (ep) */ + +#define EFACT_GPS_L5 10.0 /* error factor of GPS/QZS L5 */ + +#define MUDOT_GPS (0.00836 * D2R) /* average angular velocity GPS (rad/s) */ +#define MUDOT_GLO (0.00888 * D2R) /* average angular velocity GLO (rad/s) */ +#define EPS0_GPS (13.5 * D2R) /* max shadow crossing angle GPS (rad) */ +#define EPS0_GLO (14.2 * D2R) /* max shadow crossing angle GLO (rad) */ +#define T_POSTSHADOW 1800.0 /* post-shadow recovery time (s) */ +#define QZS_EC_BETA 20.0 /* max beta angle for qzss Ec (deg) */ /* number and index of states */ -#define NF(opt) ((opt)->ionoopt==IONOOPT_IFLC?1:(opt)->nf) -#define NP(opt) ((opt)->dynamics?9:3) -#define NC(opt) (NSYS) -#define NT(opt) ((opt)->tropopttropopt==TROPOPT_EST?1:3)) -#define NI(opt) ((opt)->ionoopt==IONOOPT_EST?MAXSAT:0) -#define ND(opt) ((opt)->nf>=3?1:0) -#define NR(opt) (NP(opt)+NC(opt)+NT(opt)+NI(opt)+ND(opt)) -#define NB(opt) (NF(opt)*MAXSAT) -#define NX(opt) (NR(opt)+NB(opt)) -#define IC(s,opt) (NP(opt)+(s)) -#define IT(opt) (NP(opt)+NC(opt)) -#define II(s,opt) (NP(opt)+NC(opt)+NT(opt)+(s)-1) -#define ID(opt) (NP(opt)+NC(opt)+NT(opt)+NI(opt)) -#define IB(s,f,opt) (NR(opt)+MAXSAT*(f)+(s)-1) +#define NF(opt) ((opt)->ionoopt == IONOOPT_IFLC ? 1 : (opt)->nf) +#define NP(opt) ((opt)->dynamics ? 9 : 3) +#define NC(opt) (NSYS) +#define NT(opt) ((opt)->tropopt < TROPOPT_EST ? 0 : ((opt)->tropopt == TROPOPT_EST ? 1 : 3)) +#define NI(opt) ((opt)->ionoopt == IONOOPT_EST ? MAXSAT : 0) +#define ND(opt) ((opt)->nf >= 3 ? 1 : 0) +#define NR(opt) (NP(opt) + NC(opt) + NT(opt) + NI(opt) + ND(opt)) +#define NB(opt) (NF(opt) * MAXSAT) +#define NX(opt) (NR(opt) + NB(opt)) +#define IC(s, opt) (NP(opt) + (s)) +#define IT(opt) (NP(opt) + NC(opt)) +#define II(s, opt) (NP(opt) + NC(opt) + NT(opt) + (s) - 1) +#define ID(opt) (NP(opt) + NC(opt) + NT(opt) + NI(opt)) +#define IB(s, f, opt) (NR(opt) + MAXSAT * (f) + (s) - 1) /* standard deviation of state -----------------------------------------------*/ -static double STD(rtk_t *rtk, int i) -{ - if (rtk->sol.stat==SOLQ_FIX) return SQRT(rtk->Pa[i+i*rtk->nx]); - return SQRT(rtk->P[i+i*rtk->nx]); +static double STD(rtk_t *rtk, int i) { + if (rtk->sol.stat == SOLQ_FIX) return SQRT(rtk->Pa[i + i * rtk->nx]); + return SQRT(rtk->P[i + i * rtk->nx]); } /* write solution status for PPP ---------------------------------------------*/ -extern int pppoutstat(rtk_t *rtk, char *buff) -{ - ssat_t *ssat; - double tow,pos[3],vel[3],acc[3],*x; - int i,j,week; - char id[8],*p=buff; - - if (!rtk->sol.stat) return 0; - - trace(3,"pppoutstat:\n"); - - tow=time2gpst(rtk->sol.time,&week); - - x=rtk->sol.stat==SOLQ_FIX?rtk->xa:rtk->x; - - /* receiver position */ - p+=sprintf(p,"$POS,%d,%.3f,%d,%.4f,%.4f,%.4f,%.4f,%.4f,%.4f\n",week,tow, - rtk->sol.stat,x[0],x[1],x[2],STD(rtk,0),STD(rtk,1),STD(rtk,2)); - - /* receiver velocity and acceleration */ - if (rtk->opt.dynamics) { - ecef2pos(rtk->sol.rr,pos); - ecef2enu(pos,rtk->x+3,vel); - ecef2enu(pos,rtk->x+6,acc); - p+=sprintf(p,"$VELACC,%d,%.3f,%d,%.4f,%.4f,%.4f,%.5f,%.5f,%.5f,%.4f,%.4f," - "%.4f,%.5f,%.5f,%.5f\n",week,tow,rtk->sol.stat,vel[0],vel[1], - vel[2],acc[0],acc[1],acc[2],0.0,0.0,0.0,0.0,0.0,0.0); - } - /* receiver clocks */ - i=IC(0,&rtk->opt); - p+=sprintf(p,"$CLK,%d,%.3f,%d,%d,%.3f,%.3f,%.3f,%.3f,%.3f,%.3f,%.3f,%.3f\n", - week,tow,rtk->sol.stat,1,x[i]*1E9/CLIGHT,x[i+1]*1E9/CLIGHT, - x[i+2]*1E9/CLIGHT,x[i+3]*1E9/CLIGHT,STD(rtk,i)*1E9/CLIGHT, - STD(rtk,i+1)*1E9/CLIGHT,STD(rtk,i+2)*1E9/CLIGHT, - STD(rtk,i+2)*1E9/CLIGHT); - - /* tropospheric parameters */ - if (rtk->opt.tropopt==TROPOPT_EST||rtk->opt.tropopt==TROPOPT_ESTG) { - i=IT(&rtk->opt); - p+=sprintf(p,"$TROP,%d,%.3f,%d,%d,%.4f,%.4f\n",week,tow,rtk->sol.stat, - 1,x[i],STD(rtk,i)); - } - if (rtk->opt.tropopt==TROPOPT_ESTG) { - i=IT(&rtk->opt); - p+=sprintf(p,"$TRPG,%d,%.3f,%d,%d,%.5f,%.5f,%.5f,%.5f\n",week,tow, - rtk->sol.stat,1,x[i+1],x[i+2],STD(rtk,i+1),STD(rtk,i+2)); - } - /* ionosphere parameters */ - if (rtk->opt.ionoopt==IONOOPT_EST) { - for (i=0;issat+i; - if (!ssat->vs) continue; - j=II(i+1,&rtk->opt); - if (rtk->x[j]==0.0) continue; - satno2id(i+1,id); - p+=sprintf(p,"$ION,%d,%.3f,%d,%s,%.1f,%.1f,%.4f,%.4f\n",week,tow, - rtk->sol.stat,id,rtk->ssat[i].azel[0]*R2D, - rtk->ssat[i].azel[1]*R2D,x[j],STD(rtk,j)); - } - } +extern int pppoutstat(rtk_t *rtk, char *buff) { + ssat_t *ssat; + double tow, pos[3], vel[3], acc[3], *x; + int i, j, week; + char id[8], *p = buff; + + if (!rtk->sol.stat) return 0; + + trace(3, "pppoutstat:\n"); + + tow = time2gpst(rtk->sol.time, &week); + + x = rtk->sol.stat == SOLQ_FIX ? rtk->xa : rtk->x; + + /* receiver position */ + p += sprintf(p, "$POS,%d,%.3f,%d,%.4f,%.4f,%.4f,%.4f,%.4f,%.4f\n", week, tow, rtk->sol.stat, x[0], + x[1], x[2], STD(rtk, 0), STD(rtk, 1), STD(rtk, 2)); + + /* receiver velocity and acceleration */ + if (rtk->opt.dynamics) { + ecef2pos(rtk->sol.rr, pos); + ecef2enu(pos, rtk->x + 3, vel); + ecef2enu(pos, rtk->x + 6, acc); + p += sprintf(p, + "$VELACC,%d,%.3f,%d,%.4f,%.4f,%.4f,%.5f,%.5f,%.5f,%.4f,%.4f," + "%.4f,%.5f,%.5f,%.5f\n", + week, tow, rtk->sol.stat, vel[0], vel[1], vel[2], acc[0], acc[1], acc[2], 0.0, 0.0, + 0.0, 0.0, 0.0, 0.0); + } + /* receiver clocks */ + i = IC(0, &rtk->opt); + p += sprintf(p, "$CLK,%d,%.3f,%d,%d,%.3f,%.3f,%.3f,%.3f,%.3f,%.3f,%.3f,%.3f\n", week, tow, + rtk->sol.stat, 1, x[i] * 1E9 / CLIGHT, x[i + 1] * 1E9 / CLIGHT, + x[i + 2] * 1E9 / CLIGHT, x[i + 3] * 1E9 / CLIGHT, STD(rtk, i) * 1E9 / CLIGHT, + STD(rtk, i + 1) * 1E9 / CLIGHT, STD(rtk, i + 2) * 1E9 / CLIGHT, + STD(rtk, i + 2) * 1E9 / CLIGHT); + + /* tropospheric parameters */ + if (rtk->opt.tropopt == TROPOPT_EST || rtk->opt.tropopt == TROPOPT_ESTG) { + i = IT(&rtk->opt); + p += sprintf(p, "$TROP,%d,%.3f,%d,%d,%.4f,%.4f\n", week, tow, rtk->sol.stat, 1, x[i], + STD(rtk, i)); + } + if (rtk->opt.tropopt == TROPOPT_ESTG) { + i = IT(&rtk->opt); + p += sprintf(p, "$TRPG,%d,%.3f,%d,%d,%.5f,%.5f,%.5f,%.5f\n", week, tow, rtk->sol.stat, 1, + x[i + 1], x[i + 2], STD(rtk, i + 1), STD(rtk, i + 2)); + } + /* ionosphere parameters */ + if (rtk->opt.ionoopt == IONOOPT_EST) { + for (i = 0; i < MAXSAT; i++) { + ssat = rtk->ssat + i; + if (!ssat->vs) continue; + j = II(i + 1, &rtk->opt); + if (rtk->x[j] == 0.0) continue; + satno2id(i + 1, id); + p += sprintf(p, "$ION,%d,%.3f,%d,%s,%.1f,%.1f,%.4f,%.4f\n", week, tow, rtk->sol.stat, id, + rtk->ssat[i].azel[0] * R2D, rtk->ssat[i].azel[1] * R2D, x[j], STD(rtk, j)); + } + } #ifdef OUTSTAT_AMB - /* ambiguity parameters */ - int k; - for (i=0;iopt);j++) { - k=IB(i+1,j,&rtk->opt); - if (rtk->x[k]==0.0) continue; - satno2id(i+1,id); - p+=sprintf(p,"$AMB,%d,%.3f,%d,%s,%d,%.4f,%.4f\n",week,tow, - rtk->sol.stat,id,j+1,x[k],STD(rtk,k)); + /* ambiguity parameters */ + int k; + for (i = 0; i < MAXSAT; i++) + for (j = 0; j < NF(&rtk->opt); j++) { + k = IB(i + 1, j, &rtk->opt); + if (rtk->x[k] == 0.0) continue; + satno2id(i + 1, id); + p += sprintf(p, "$AMB,%d,%.3f,%d,%s,%d,%.4f,%.4f\n", week, tow, rtk->sol.stat, id, j + 1, + x[k], STD(rtk, k)); } #endif - return (int)(p-buff); + return (int)(p - buff); } /* exclude meas of eclipsing satellite (block IIA) ---------------------------*/ -static void testeclipse(const obsd_t *obs, int n, const nav_t *nav, double *rs) -{ - double rsun[3],esun[3],r,ang,erpv[5]={0},cosa; - int i,j; - const char *type; +static void testeclipse(const obsd_t *obs, int n, const nav_t *nav, double *rs) { + double rsun[3], esun[3], r, ang, erpv[5] = {0}, cosa; + int i, j; + const char *type; - trace(3,"testeclipse:\n"); + trace(3, "testeclipse:\n"); - /* unit vector of sun direction (ecef) */ - sunmoonpos(gpst2utc(obs[0].time),erpv,rsun,NULL,NULL); - normv3(rsun,esun); + /* unit vector of sun direction (ecef) */ + sunmoonpos(gpst2utc(obs[0].time), erpv, rsun, NULL, NULL); + normv3(rsun, esun); - for (i=0;ipcvs[obs[i].sat-1].type; + for (i = 0; i < n; i++) { + type = nav->pcvs[obs[i].sat - 1].type; - if ((r=norm(rs+i*6,3))<=0.0) continue; + if ((r = norm(rs + i * 6, 3)) <= 0.0) continue; - /* only block IIA */ - if (*type&&!strstr(type,"BLOCK IIA")) continue; + /* only block IIA */ + if (*type && !strstr(type, "BLOCK IIA")) continue; - /* sun-earth-satellite angle */ - cosa=dot3(rs+i*6,esun)/r; - cosa=cosa<-1.0?-1.0:(cosa>1.0?1.0:cosa); - ang=acos(cosa); + /* sun-earth-satellite angle */ + cosa = dot3(rs + i * 6, esun) / r; + cosa = cosa < -1.0 ? -1.0 : (cosa > 1.0 ? 1.0 : cosa); + ang = acos(cosa); - /* test eclipse */ - if (angRE_WGS84) continue; + /* test eclipse */ + if (ang < PI / 2.0 || r * sin(ang) > RE_WGS84) continue; - char tstr[40]; - trace(3,"eclipsing sat excluded %s sat=%2d\n",time2str(obs[0].time,tstr,0), - obs[i].sat); + char tstr[40]; + trace(3, "eclipsing sat excluded %s sat=%2d\n", time2str(obs[0].time, tstr, 0), obs[i].sat); - for (j=0;j<3;j++) rs[j+i*6]=0.0; - } + for (j = 0; j < 3; j++) rs[j + i * 6] = 0.0; + } } /* nominal yaw-angle ---------------------------------------------------------*/ -static double yaw_nominal(double beta, double mu) -{ - if (fabs(beta)<1E-12&&fabs(mu)<1E-12) return PI; - return atan2(-tan(beta),sin(mu))+PI; +static double yaw_nominal(double beta, double mu) { + if (fabs(beta) < 1E-12 && fabs(mu) < 1E-12) return PI; + return atan2(-tan(beta), sin(mu)) + PI; } /* yaw-angle of satellite ----------------------------------------------------*/ -extern int yaw_angle(int sat, const char *type, int opt, double beta, double mu, - double *yaw) -{ - (void)sat; - (void)type; - (void)opt; - *yaw=yaw_nominal(beta,mu); - return 1; +extern int yaw_angle(int sat, const char *type, int opt, double beta, double mu, double *yaw) { + (void)sat; + (void)type; + (void)opt; + *yaw = yaw_nominal(beta, mu); + return 1; } /* satellite attitude model --------------------------------------------------*/ -static int sat_yaw(gtime_t time, int sat, const char *type, int opt, - const double *rs, double *exs, double *eys) -{ - double rsun[3],ri[6],es[3],esun[3],n[3],p[3],en[3],ep[3],ex[3],E,beta,mu; - double yaw,cosy,siny,erpv[5]={0}; - int i; - - sunmoonpos(gpst2utc(time),erpv,rsun,NULL,NULL); - - /* beta and orbit angle */ - matcpy(ri,rs,6,1); - ri[3]-=OMGE*ri[1]; - ri[4]+=OMGE*ri[0]; - cross3(ri,ri+3,n); - cross3(rsun,n,p); - if (!normv3(rs,es)||!normv3(rsun,esun)||!normv3(n,en)|| - !normv3(p,ep)) return 0; - beta=PI/2.0-acos(dot3(esun,en)); - E=acos(dot3(es,ep)); - mu=PI/2.0+(dot3(es,esun)<=0?-E:E); - if (mu<-PI/2.0) mu+=2.0*PI; - else if (mu>=PI/2.0) mu-=2.0*PI; - - /* yaw-angle of satellite */ - if (!yaw_angle(sat,type,opt,beta,mu,&yaw)) return 0; - - /* satellite fixed x,y-vector */ - cross3(en,es,ex); - cosy=cos(yaw); - siny=sin(yaw); - for (i=0;i<3;i++) { - exs[i]=-siny*en[i]+cosy*ex[i]; - eys[i]=-cosy*en[i]-siny*ex[i]; - } - return 1; +static int sat_yaw(gtime_t time, int sat, const char *type, int opt, const double *rs, double *exs, + double *eys) { + double rsun[3], ri[6], es[3], esun[3], n[3], p[3], en[3], ep[3], ex[3], E, beta, mu; + double yaw, cosy, siny, erpv[5] = {0}; + int i; + + sunmoonpos(gpst2utc(time), erpv, rsun, NULL, NULL); + + /* beta and orbit angle */ + matcpy(ri, rs, 6, 1); + ri[3] -= OMGE * ri[1]; + ri[4] += OMGE * ri[0]; + cross3(ri, ri + 3, n); + cross3(rsun, n, p); + if (!normv3(rs, es) || !normv3(rsun, esun) || !normv3(n, en) || !normv3(p, ep)) return 0; + beta = PI / 2.0 - acos(dot3(esun, en)); + E = acos(dot3(es, ep)); + mu = PI / 2.0 + (dot3(es, esun) <= 0 ? -E : E); + if (mu < -PI / 2.0) + mu += 2.0 * PI; + else if (mu >= PI / 2.0) + mu -= 2.0 * PI; + + /* yaw-angle of satellite */ + if (!yaw_angle(sat, type, opt, beta, mu, &yaw)) return 0; + + /* satellite fixed x,y-vector */ + cross3(en, es, ex); + cosy = cos(yaw); + siny = sin(yaw); + for (i = 0; i < 3; i++) { + exs[i] = -siny * en[i] + cosy * ex[i]; + eys[i] = -cosy * en[i] - siny * ex[i]; + } + return 1; } /* phase windup model --------------------------------------------------------*/ -static int model_phw(gtime_t time, int sat, const char *type, int opt, - const double *rs, const double *rr, double *phw) -{ - double exs[3],eys[3],ek[3],exr[3],eyr[3],eks[3],ekr[3],E[9]; - double dr[3],ds[3],drs[3],r[3],pos[3],cosp,ph; - int i; - - if (opt<=0) return 1; /* no phase windup */ - - /* satellite yaw attitude model */ - if (!sat_yaw(time,sat,type,opt,rs,exs,eys)) return 0; - - /* unit vector satellite to receiver */ - for (i=0;i<3;i++) r[i]=rr[i]-rs[i]; - if (!normv3(r,ek)) return 0; - - /* unit vectors of receiver antenna */ - ecef2pos(rr,pos); - xyz2enu(pos,E); - exr[0]= E[1]; exr[1]= E[4]; exr[2]= E[7]; /* x = north */ - eyr[0]=-E[0]; eyr[1]=-E[3]; eyr[2]=-E[6]; /* y = west */ - - /* phase windup effect */ - cross3(ek,eys,eks); - cross3(ek,eyr,ekr); - for (i=0;i<3;i++) { - ds[i]=exs[i]-ek[i]*dot3(ek,exs)-eks[i]; - dr[i]=exr[i]-ek[i]*dot3(ek,exr)+ekr[i]; - } - cosp=dot3(ds,dr)/norm(ds,3)/norm(dr,3); - if (cosp<-1.0) cosp=-1.0; - else if (cosp> 1.0) cosp= 1.0; - ph=acos(cosp)/2.0/PI; - cross3(ds,dr,drs); - if (dot3(ek,drs)<0.0) ph=-ph; - - *phw=ph+floor(*phw-ph+0.5); /* in cycle */ - return 1; +static int model_phw(gtime_t time, int sat, const char *type, int opt, const double *rs, + const double *rr, double *phw) { + double exs[3], eys[3], ek[3], exr[3], eyr[3], eks[3], ekr[3], E[9]; + double dr[3], ds[3], drs[3], r[3], pos[3], cosp, ph; + int i; + + if (opt <= 0) return 1; /* no phase windup */ + + /* satellite yaw attitude model */ + if (!sat_yaw(time, sat, type, opt, rs, exs, eys)) return 0; + + /* unit vector satellite to receiver */ + for (i = 0; i < 3; i++) r[i] = rr[i] - rs[i]; + if (!normv3(r, ek)) return 0; + + /* unit vectors of receiver antenna */ + ecef2pos(rr, pos); + xyz2enu(pos, E); + exr[0] = E[1]; + exr[1] = E[4]; + exr[2] = E[7]; /* x = north */ + eyr[0] = -E[0]; + eyr[1] = -E[3]; + eyr[2] = -E[6]; /* y = west */ + + /* phase windup effect */ + cross3(ek, eys, eks); + cross3(ek, eyr, ekr); + for (i = 0; i < 3; i++) { + ds[i] = exs[i] - ek[i] * dot3(ek, exs) - eks[i]; + dr[i] = exr[i] - ek[i] * dot3(ek, exr) + ekr[i]; + } + cosp = dot3(ds, dr) / norm(ds, 3) / norm(dr, 3); + if (cosp < -1.0) + cosp = -1.0; + else if (cosp > 1.0) + cosp = 1.0; + ph = acos(cosp) / 2.0 / PI; + cross3(ds, dr, drs); + if (dot3(ek, drs) < 0.0) ph = -ph; + + *phw = ph + floor(*phw - ph + 0.5); /* in cycle */ + return 1; } /* measurement error variance ------------------------------------------------*/ -static double varerr(int sat, int sys, double el, double snr_rover, - int f, const prcopt_t *opt, const obsd_t *obs) -{ - (void)sat; - double a,b,e; - double snr_max=opt->err[5]; - double fact=1.0; - double sinel=sin(el),var; - int frq,code; - - frq=f/2;code=f%2; /* 0=phase, 1=code */ - /* increase variance for pseudoranges */ - if (code) fact=opt->eratio[frq]; - if (fact<=0.0) fact=opt->eratio[0]; - /* adjust variances for constellation */ - switch (sys) { - case SYS_GPS: fact*=EFACT_GPS;break; - case SYS_GLO: fact*=EFACT_GLO;break; - case SYS_GAL: fact*=EFACT_GAL;break; - case SYS_SBS: fact*=EFACT_SBS;break; - case SYS_QZS: fact*=EFACT_QZS;break; - case SYS_CMP: fact*=EFACT_CMP;break; - case SYS_IRN: fact*=EFACT_IRN;break; - default: fact*=EFACT_GPS;break; - } - if (sys==SYS_GPS||sys==SYS_QZS) { - if (frq==2) fact*=EFACT_GPS_L5; /* GPS/QZS L5 error factor */ - } - /* adjust variance for config parameters */ - a=fact*opt->err[1]; /* base term */ - b=fact*opt->err[2]; /* el term */ - /* calculate variance */ - var=(a*a+b*b/sinel/sinel); - if (opt->err[6]>0) { /* add SNR term */ - e=fact*opt->err[6]; - var+=e*e*(pow(10,0.1*MAX(snr_max-snr_rover,0))); - } - if (opt->err[7]>0.0) { /* add rcvr stdevs term */ - if (code) var+=SQR(opt->err[7]*obs->Pstd[frq]); - else var+=SQR(opt->err[7]*obs->Lstd[frq]*0.2); - } - /* FIXME: the scaling factor is not 3 for other signals/constellations than GPS L1/L2 */ - var*=(opt->ionoopt==IONOOPT_IFLC)?SQR(3.0):1.0; - return var; +static double varerr(int sat, int sys, double el, double snr_rover, int f, const prcopt_t *opt, + const obsd_t *obs) { + (void)sat; + double a, b, e; + double snr_max = opt->err[5]; + double fact = 1.0; + double sinel = sin(el), var; + int frq, code; + + frq = f / 2; + code = f % 2; /* 0=phase, 1=code */ + /* increase variance for pseudoranges */ + if (code) fact = opt->eratio[frq]; + if (fact <= 0.0) fact = opt->eratio[0]; + /* adjust variances for constellation */ + switch (sys) { + case SYS_GPS: + fact *= EFACT_GPS; + break; + case SYS_GLO: + fact *= EFACT_GLO; + break; + case SYS_GAL: + fact *= EFACT_GAL; + break; + case SYS_SBS: + fact *= EFACT_SBS; + break; + case SYS_QZS: + fact *= EFACT_QZS; + break; + case SYS_CMP: + fact *= EFACT_CMP; + break; + case SYS_IRN: + fact *= EFACT_IRN; + break; + default: + fact *= EFACT_GPS; + break; + } + if (sys == SYS_GPS || sys == SYS_QZS) { + if (frq == 2) fact *= EFACT_GPS_L5; /* GPS/QZS L5 error factor */ + } + /* adjust variance for config parameters */ + a = fact * opt->err[1]; /* base term */ + b = fact * opt->err[2]; /* el term */ + /* calculate variance */ + var = (a * a + b * b / sinel / sinel); + if (opt->err[6] > 0) { /* add SNR term */ + e = fact * opt->err[6]; + var += e * e * (pow(10, 0.1 * MAX(snr_max - snr_rover, 0))); + } + if (opt->err[7] > 0.0) { /* add rcvr stdevs term */ + if (code) + var += SQR(opt->err[7] * obs->Pstd[frq]); + else + var += SQR(opt->err[7] * obs->Lstd[frq] * 0.2); + } + /* FIXME: the scaling factor is not 3 for other signals/constellations than GPS L1/L2 */ + var *= (opt->ionoopt == IONOOPT_IFLC) ? SQR(3.0) : 1.0; + return var; } /* initialize state and covariance -------------------------------------------*/ -static inline void initx(rtk_t *rtk, double xi, double var, int i) -{ - int j; - rtk->x[i]=xi; - for (j=0;jnx;j++) rtk->P[i+j*rtk->nx]=0.0; - for (j=0;jnx;j++) rtk->P[j+i*rtk->nx]=0.0; - rtk->P[i+i*rtk->nx]=var; +static inline void initx(rtk_t *rtk, double xi, double var, int i) { + int j; + rtk->x[i] = xi; + for (j = 0; j < rtk->nx; j++) rtk->P[i + j * rtk->nx] = 0.0; + for (j = 0; j < rtk->nx; j++) rtk->P[j + i * rtk->nx] = 0.0; + rtk->P[i + i * rtk->nx] = var; } /* geometry-free phase measurement -------------------------------------------*/ -static double gfmeas(const obsd_t *obs, const nav_t *nav) -{ - double freq1,freq2; - - freq1=sat2freq(obs->sat,obs->code[0],nav); - freq2=sat2freq(obs->sat,obs->code[1],nav); - if (freq1==0.0||freq2==0.0||obs->L[0]==0.0||obs->L[1]==0.0) return 0.0; - return (obs->L[0]/freq1-obs->L[1]/freq2)*CLIGHT; +static double gfmeas(const obsd_t *obs, const nav_t *nav) { + double freq1, freq2; + + freq1 = sat2freq(obs->sat, obs->code[0], nav); + freq2 = sat2freq(obs->sat, obs->code[1], nav); + if (freq1 == 0.0 || freq2 == 0.0 || obs->L[0] == 0.0 || obs->L[1] == 0.0) return 0.0; + return (obs->L[0] / freq1 - obs->L[1] / freq2) * CLIGHT; } /* Melbourne-Wubbena linear combination --------------------------------------*/ -static double mwmeas(const obsd_t *obs, const nav_t *nav) -{ - double freq1,freq2; - - freq1=sat2freq(obs->sat,obs->code[0],nav); - freq2=sat2freq(obs->sat,obs->code[1],nav); - - if (freq1==0.0||freq2==0.0||obs->L[0]==0.0||obs->L[1]==0.0|| - obs->P[0]==0.0||obs->P[1]==0.0) return 0.0; - trace(3,"mwmeas: %12.1f %12.1f %15.3f %15.3f %15.3f %15.3f %d %d\n",freq1,freq2,obs->L[0],obs->L[1],obs->P[0],obs->P[1],obs->code[0],obs->code[1]); - return (obs->L[0]-obs->L[1])*CLIGHT/(freq1-freq2)- - (freq1*obs->P[0]+freq2*obs->P[1])/(freq1+freq2); +static double mwmeas(const obsd_t *obs, const nav_t *nav) { + double freq1, freq2; + + freq1 = sat2freq(obs->sat, obs->code[0], nav); + freq2 = sat2freq(obs->sat, obs->code[1], nav); + + if (freq1 == 0.0 || freq2 == 0.0 || obs->L[0] == 0.0 || obs->L[1] == 0.0 || obs->P[0] == 0.0 || + obs->P[1] == 0.0) + return 0.0; + trace(3, "mwmeas: %12.1f %12.1f %15.3f %15.3f %15.3f %15.3f %d %d\n", freq1, freq2, obs->L[0], + obs->L[1], obs->P[0], obs->P[1], obs->code[0], obs->code[1]); + return (obs->L[0] - obs->L[1]) * CLIGHT / (freq1 - freq2) - + (freq1 * obs->P[0] + freq2 * obs->P[1]) / (freq1 + freq2); } /* antenna corrected measurements --------------------------------------------*/ -static void corr_meas(const obsd_t *obs, const nav_t *nav, const double *azel, - const prcopt_t *opt, const double *dantr, - const double *dants, double phw, double *L, double *P, - double *Lc, double *Pc) -{ - double freq[NFREQ]={0},C1,C2; - int i,ix=0,frq,frq2,bias_ix,sys=satsys(obs->sat,NULL); - - for (i=0;inf;i++) { - L[i]=P[i]=0.0; - /* skip if low SNR or missing observations */ - freq[i]=sat2freq(obs->sat,obs->code[i],nav); - if (freq[i]==0.0||obs->L[i]==0.0||obs->P[i]==0.0) continue; - if (testsnr(0,0,azel[1],obs->SNR[i],&opt->snrmask)) continue; - - /* antenna phase center and phase windup correction */ - L[i]=obs->L[i]*CLIGHT/freq[i]-dants[i]-dantr[i]-phw*CLIGHT/freq[i]; - P[i]=obs->P[i] -dants[i]-dantr[i]; - - if (opt->sateph==EPHOPT_SSRAPC||opt->sateph==EPHOPT_SSRCOM) { - /* select SSR code correction based on code */ - if (sys==SYS_GPS) - ix=(i==0?CODE_L1W-1:CODE_L2W-1); - else if (sys==SYS_GLO) - ix=(i==0?CODE_L1P-1:CODE_L2P-1); - else if (sys==SYS_GAL) - ix=(i==0?CODE_L1X-1:CODE_L7X-1); - /* apply SSR correction */ - P[i]+=(nav->ssr[obs->sat-1].cbias[obs->code[i]-1]-nav->ssr[obs->sat-1].cbias[ix]); - } - else { /* apply code bias corrections from file */ - if (sys==SYS_GAL&&(i==1||i==2)) frq=3-i; /* GAL biases are L1/L5 */ - else frq=i; /* other biases are L1/L2 */ - if (frq>=MAX_CODE_BIAS_FREQS) continue; /* only 2 freqs per system supported in code bias table */ - bias_ix=code2bias_ix(sys,obs->code[i]); /* look up bias index in table */ - if (bias_ix>0) { /* 0=ref code */ - P[i]+=nav->cbias[obs->sat-1][frq][bias_ix-1]; /* code bias */ - } - } - } - /* choose freqs for iono-free LC */ - *Lc=*Pc=0.0; - frq2=L[1]==0?2:1; /* if L[1]==0, try L[2] */ - if (freq[0]==0.0||freq[frq2]==0.0) return; - C1= SQR(freq[0])/(SQR(freq[0])-SQR(freq[frq2])); - C2=-SQR(freq[frq2])/(SQR(freq[0])-SQR(freq[frq2])); - - if (L[0]!=0.0&&L[frq2]!=0.0) *Lc=C1*L[0]+C2*L[frq2]; - if (P[0]!=0.0&&P[frq2]!=0.0) *Pc=C1*P[0]+C2*P[frq2]; +static void corr_meas(const obsd_t *obs, const nav_t *nav, const double *azel, const prcopt_t *opt, + const double *dantr, const double *dants, double phw, double *L, double *P, + double *Lc, double *Pc) { + double freq[NFREQ] = {0}, C1, C2; + int i, ix = 0, frq, frq2, bias_ix, sys = satsys(obs->sat, NULL); + + for (i = 0; i < opt->nf; i++) { + L[i] = P[i] = 0.0; + /* skip if low SNR or missing observations */ + freq[i] = sat2freq(obs->sat, obs->code[i], nav); + if (freq[i] == 0.0 || obs->L[i] == 0.0 || obs->P[i] == 0.0) continue; + if (testsnr(0, 0, azel[1], obs->SNR[i], &opt->snrmask)) continue; + + /* antenna phase center and phase windup correction */ + L[i] = obs->L[i] * CLIGHT / freq[i] - dants[i] - dantr[i] - phw * CLIGHT / freq[i]; + P[i] = obs->P[i] - dants[i] - dantr[i]; + + if (opt->sateph == EPHOPT_SSRAPC || opt->sateph == EPHOPT_SSRCOM) { + /* select SSR code correction based on code */ + if (sys == SYS_GPS) + ix = (i == 0 ? CODE_L1W - 1 : CODE_L2W - 1); + else if (sys == SYS_GLO) + ix = (i == 0 ? CODE_L1P - 1 : CODE_L2P - 1); + else if (sys == SYS_GAL) + ix = (i == 0 ? CODE_L1X - 1 : CODE_L7X - 1); + /* apply SSR correction */ + P[i] += (nav->ssr[obs->sat - 1].cbias[obs->code[i] - 1] - nav->ssr[obs->sat - 1].cbias[ix]); + } else { /* apply code bias corrections from file */ + if (sys == SYS_GAL && (i == 1 || i == 2)) + frq = 3 - i; /* GAL biases are L1/L5 */ + else + frq = i; /* other biases are L1/L2 */ + if (frq >= MAX_CODE_BIAS_FREQS) + continue; /* only 2 freqs per system supported in code bias table */ + bias_ix = code2bias_ix(sys, obs->code[i]); /* look up bias index in table */ + if (bias_ix > 0) { /* 0=ref code */ + P[i] += nav->cbias[obs->sat - 1][frq][bias_ix - 1]; /* code bias */ + } + } + } + /* choose freqs for iono-free LC */ + *Lc = *Pc = 0.0; + frq2 = L[1] == 0 ? 2 : 1; /* if L[1]==0, try L[2] */ + if (freq[0] == 0.0 || freq[frq2] == 0.0) return; + C1 = SQR(freq[0]) / (SQR(freq[0]) - SQR(freq[frq2])); + C2 = -SQR(freq[frq2]) / (SQR(freq[0]) - SQR(freq[frq2])); + + if (L[0] != 0.0 && L[frq2] != 0.0) *Lc = C1 * L[0] + C2 * L[frq2]; + if (P[0] != 0.0 && P[frq2] != 0.0) *Pc = C1 * P[0] + C2 * P[frq2]; } /* detect cycle slip by LLI --------------------------------------------------*/ -static void detslp_ll(rtk_t *rtk, const obsd_t *obs, int n) -{ - int i,j,nf=rtk->opt.nf; +static void detslp_ll(rtk_t *rtk, const obsd_t *obs, int n) { + int i, j, nf = rtk->opt.nf; - trace(3,"detslp_ll: n=%d\n",n); + trace(3, "detslp_ll: n=%d\n", n); - if (nf > NFREQ) nf = NFREQ; // Quieten compiler warnings on slip[] write. - for (i=0;i NFREQ) nf = NFREQ; // Quieten compiler warnings on slip[] write. + for (i = 0; i < n && i < MAXOBS; i++) + for (j = 0; j < nf; j++) { + if (obs[i].L[j] == 0.0 || !(obs[i].LLI[j] & (LLI_SLIP | LLI_HALFC))) continue; - trace(3,"detslp_ll: slip detected sat=%2d f=%d\n",obs[i].sat,j+1); + trace(3, "detslp_ll: slip detected sat=%2d f=%d\n", obs[i].sat, j + 1); - rtk->ssat[obs[i].sat-1].slip[j]=LLI_SLIP; + rtk->ssat[obs[i].sat - 1].slip[j] = LLI_SLIP; } } /* detect cycle slip by geometry free phase jump -----------------------------*/ -static void detslp_gf(rtk_t *rtk, const obsd_t *obs, int n, const nav_t *nav) -{ - double g0,g1; - int i,j; - - trace(4,"detslp_gf: n=%d\n",n); +static void detslp_gf(rtk_t *rtk, const obsd_t *obs, int n, const nav_t *nav) { + double g0, g1; + int i, j; - for (i=0;issat[obs[i].sat-1].gf[0]; - rtk->ssat[obs[i].sat-1].gf[0]=g1; + g0 = rtk->ssat[obs[i].sat - 1].gf[0]; + rtk->ssat[obs[i].sat - 1].gf[0] = g1; - trace(4,"detslip_gf: sat=%2d gf0=%8.3f gf1=%8.3f\n",obs[i].sat,g0,g1); + trace(4, "detslip_gf: sat=%2d gf0=%8.3f gf1=%8.3f\n", obs[i].sat, g0, g1); - if (g0!=0.0&&fabs(g1-g0)>rtk->opt.thresslip) { - trace(3,"detslip_gf: slip detected sat=%2d gf=%8.3f->%8.3f\n", - obs[i].sat,g0,g1); + if (g0 != 0.0 && fabs(g1 - g0) > rtk->opt.thresslip) { + trace(3, "detslip_gf: slip detected sat=%2d gf=%8.3f->%8.3f\n", obs[i].sat, g0, g1); - for (j=0;jopt.nf;j++) rtk->ssat[obs[i].sat-1].slip[j]|=LLI_SLIP; - } + for (j = 0; j < rtk->opt.nf; j++) rtk->ssat[obs[i].sat - 1].slip[j] |= LLI_SLIP; } + } } /* detect slip by Melbourne-Wubbena linear combination jump ------------------*/ -static void detslp_mw(rtk_t *rtk, const obsd_t *obs, int n, const nav_t *nav) -{ - double w0,w1; - int i,j; +static void detslp_mw(rtk_t *rtk, const obsd_t *obs, int n, const nav_t *nav) { + double w0, w1; + int i, j; - trace(4,"detslp_mw: n=%d\n",n); + trace(4, "detslp_mw: n=%d\n", n); - for (i=0;issat[obs[i].sat-1].mw[0]; - rtk->ssat[obs[i].sat-1].mw[0]=w1; + w0 = rtk->ssat[obs[i].sat - 1].mw[0]; + rtk->ssat[obs[i].sat - 1].mw[0] = w1; - trace(4,"detslip_mw: sat=%2d mw0=%8.3f mw1=%8.3f\n",obs[i].sat,w0,w1); + trace(4, "detslip_mw: sat=%2d mw0=%8.3f mw1=%8.3f\n", obs[i].sat, w0, w1); - if (w0!=0.0&&fabs(w1-w0)>THRES_MW_JUMP) { - trace(3,"detslip_mw: slip detected sat=%2d mw=%8.3f->%8.3f\n", - obs[i].sat,w0,w1); + if (w0 != 0.0 && fabs(w1 - w0) > THRES_MW_JUMP) { + trace(3, "detslip_mw: slip detected sat=%2d mw=%8.3f->%8.3f\n", obs[i].sat, w0, w1); - for (j=0;jopt.nf;j++) rtk->ssat[obs[i].sat-1].slip[j]|=LLI_SLIP; - } + for (j = 0; j < rtk->opt.nf; j++) rtk->ssat[obs[i].sat - 1].slip[j] |= LLI_SLIP; } + } } /* temporal update of position -----------------------------------------------*/ -static void udpos_ppp(rtk_t *rtk) -{ - double *F,*P,*FP,*x,*xp,pos[3],Q[9]={0},Qv[9],var=0.0; - int i,j,*ix,nx; - - trace(3,"udpos_ppp:\n"); - - /* fixed mode */ - if (rtk->opt.mode==PMODE_PPP_FIXED) { - for (i=0;i<3;i++) initx(rtk,rtk->opt.ru[i],1E-8,i); - return; - } - /* initialize position for first epoch */ - if (norm(rtk->x,3)<=0.0) { - for (i=0;i<3;i++) initx(rtk,rtk->sol.rr[i],VAR_POS,i); - if (rtk->opt.dynamics) { - for (i=3;i<6;i++) initx(rtk,rtk->sol.rr[i],VAR_VEL,i); - for (i=6;i<9;i++) initx(rtk,1E-6,VAR_ACC,i); - } - } - /* static ppp mode */ - if (rtk->opt.mode==PMODE_PPP_STATIC) { - for (i=0;i<3;i++) { - rtk->P[i*(1+rtk->nx)]+=SQR(rtk->opt.prn[5])*fabs(rtk->tt); - } - return; - } - /* kinematic mode without dynamics */ - if (!rtk->opt.dynamics) { - for (i=0;i<3;i++) { - initx(rtk,rtk->sol.rr[i],VAR_POS,i); - } - return; - } - /* check variance of estimated position */ - for (i=0;i<3;i++) var+=rtk->P[i+i*rtk->nx]; - var/=3.0; - - if (var>VAR_POS) { - /* reset position with large variance */ - for (i=0;i<3;i++) initx(rtk,rtk->sol.rr[i],VAR_POS,i); - for (i=3;i<6;i++) initx(rtk,rtk->sol.rr[i],VAR_VEL,i); - for (i=6;i<9;i++) initx(rtk,1E-6,VAR_ACC,i); - trace(2,"reset rtk position due to large variance: var=%.3f\n",var); - return; - } - /* generate valid state index */ - ix=imat(rtk->nx,1); - for (i=nx=0;inx;i++) { - if (i<9||(rtk->x[i]!=0.0&&rtk->P[i+i*rtk->nx]>0.0)) ix[nx++]=i; - } - /* state transition of position/velocity/acceleration */ - F=eye(nx); P=mat(nx,nx); FP=mat(nx,nx); x=mat(nx,1); xp=mat(nx,1); - - for (i=0;i<6;i++) { - F[i+(i+3)*nx]=rtk->tt; - } - /* include accel terms if filter is converged */ - if (varopt.thresar[1]) { - for (i=0;i<3;i++) { - F[i+(i+6)*nx]=SQR(rtk->tt)/2.0; - } - } - else trace(3,"pos var too high for accel term: %.4f,%.4f\n", var,rtk->opt.thresar[1]); - for (i=0;ix[ix[i]]; - for (j=0;jP[ix[i]+ix[j]*rtk->nx]; - } - } - /* x=F*x, P=F*P*F+Q */ - matmul("NN",nx,1,nx,F,x,xp); - matmul("NN",nx,nx,nx,F,P,FP); - matmul("NT",nx,nx,nx,FP,F,P); - - for (i=0;ix[ix[i]]=xp[i]; - for (j=0;jP[ix[i]+ix[j]*rtk->nx]=P[i+j*nx]; - } - } - /* process noise added to only acceleration */ - Q[0]=Q[4]=SQR(rtk->opt.prn[3])*fabs(rtk->tt); - Q[8]=SQR(rtk->opt.prn[4])*fabs(rtk->tt); - ecef2pos(rtk->x,pos); - covecef(pos,Q,Qv); - for (i=0;i<3;i++) for (j=0;j<3;j++) { - rtk->P[i+6+(j+6)*rtk->nx]+=Qv[i+j*3]; - } - free(ix); free(F); free(P); free(FP); free(x); free(xp); +static void udpos_ppp(rtk_t *rtk) { + double *F, *P, *FP, *x, *xp, pos[3], Q[9] = {0}, Qv[9], var = 0.0; + int i, j, *ix, nx; + + trace(3, "udpos_ppp:\n"); + + /* fixed mode */ + if (rtk->opt.mode == PMODE_PPP_FIXED) { + for (i = 0; i < 3; i++) initx(rtk, rtk->opt.ru[i], 1E-8, i); + return; + } + /* initialize position for first epoch */ + if (norm(rtk->x, 3) <= 0.0) { + for (i = 0; i < 3; i++) initx(rtk, rtk->sol.rr[i], VAR_POS, i); + if (rtk->opt.dynamics) { + for (i = 3; i < 6; i++) initx(rtk, rtk->sol.rr[i], VAR_VEL, i); + for (i = 6; i < 9; i++) initx(rtk, 1E-6, VAR_ACC, i); + } + } + /* static ppp mode */ + if (rtk->opt.mode == PMODE_PPP_STATIC) { + for (i = 0; i < 3; i++) { + rtk->P[i * (1 + rtk->nx)] += SQR(rtk->opt.prn[5]) * fabs(rtk->tt); + } + return; + } + /* kinematic mode without dynamics */ + if (!rtk->opt.dynamics) { + for (i = 0; i < 3; i++) { + initx(rtk, rtk->sol.rr[i], VAR_POS, i); + } + return; + } + /* check variance of estimated position */ + for (i = 0; i < 3; i++) var += rtk->P[i + i * rtk->nx]; + var /= 3.0; + + if (var > VAR_POS) { + /* reset position with large variance */ + for (i = 0; i < 3; i++) initx(rtk, rtk->sol.rr[i], VAR_POS, i); + for (i = 3; i < 6; i++) initx(rtk, rtk->sol.rr[i], VAR_VEL, i); + for (i = 6; i < 9; i++) initx(rtk, 1E-6, VAR_ACC, i); + trace(2, "reset rtk position due to large variance: var=%.3f\n", var); + return; + } + /* generate valid state index */ + ix = imat(rtk->nx, 1); + for (i = nx = 0; i < rtk->nx; i++) { + if (i < 9 || (rtk->x[i] != 0.0 && rtk->P[i + i * rtk->nx] > 0.0)) ix[nx++] = i; + } + /* state transition of position/velocity/acceleration */ + F = eye(nx); + P = mat(nx, nx); + FP = mat(nx, nx); + x = mat(nx, 1); + xp = mat(nx, 1); + + for (i = 0; i < 6; i++) { + F[i + (i + 3) * nx] = rtk->tt; + } + /* include accel terms if filter is converged */ + if (var < rtk->opt.thresar[1]) { + for (i = 0; i < 3; i++) { + F[i + (i + 6) * nx] = SQR(rtk->tt) / 2.0; + } + } else + trace(3, "pos var too high for accel term: %.4f,%.4f\n", var, rtk->opt.thresar[1]); + for (i = 0; i < nx; i++) { + x[i] = rtk->x[ix[i]]; + for (j = 0; j < nx; j++) { + P[i + j * nx] = rtk->P[ix[i] + ix[j] * rtk->nx]; + } + } + /* x=F*x, P=F*P*F+Q */ + matmul("NN", nx, 1, nx, F, x, xp); + matmul("NN", nx, nx, nx, F, P, FP); + matmul("NT", nx, nx, nx, FP, F, P); + + for (i = 0; i < nx; i++) { + rtk->x[ix[i]] = xp[i]; + for (j = 0; j < nx; j++) { + rtk->P[ix[i] + ix[j] * rtk->nx] = P[i + j * nx]; + } + } + /* process noise added to only acceleration */ + Q[0] = Q[4] = SQR(rtk->opt.prn[3]) * fabs(rtk->tt); + Q[8] = SQR(rtk->opt.prn[4]) * fabs(rtk->tt); + ecef2pos(rtk->x, pos); + covecef(pos, Q, Qv); + for (i = 0; i < 3; i++) + for (j = 0; j < 3; j++) { + rtk->P[i + 6 + (j + 6) * rtk->nx] += Qv[i + j * 3]; + } + free(ix); + free(F); + free(P); + free(FP); + free(x); + free(xp); } /* temporal update of clock --------------------------------------------------*/ -static void udclk_ppp(rtk_t *rtk) -{ - double dtr; - int i; - - trace(3,"udclk_ppp:\n"); - - /* initialize every epoch for clock (white noise) */ - for (i=0;iopt.sateph==EPHOPT_PREC) { - /* time of prec ephemeris is based gpst */ - /* neglect receiver inter-system bias */ - dtr=rtk->sol.dtr[0]; - } - else { - dtr=i==0?rtk->sol.dtr[0]:rtk->sol.dtr[0]+rtk->sol.dtr[i]; - } - initx(rtk,CLIGHT*dtr,VAR_CLK,IC(i,&rtk->opt)); - } +static void udclk_ppp(rtk_t *rtk) { + double dtr; + int i; + + trace(3, "udclk_ppp:\n"); + + /* initialize every epoch for clock (white noise) */ + for (i = 0; i < NSYS; i++) { + if (rtk->opt.sateph == EPHOPT_PREC) { + /* time of prec ephemeris is based gpst */ + /* neglect receiver inter-system bias */ + dtr = rtk->sol.dtr[0]; + } else { + dtr = i == 0 ? rtk->sol.dtr[0] : rtk->sol.dtr[0] + rtk->sol.dtr[i]; + } + initx(rtk, CLIGHT * dtr, VAR_CLK, IC(i, &rtk->opt)); + } } /* temporal update of tropospheric parameters --------------------------------*/ -static void udtrop_ppp(rtk_t *rtk) -{ - double pos[3],azel[]={0.0,PI/2.0},ztd,var; - int i=IT(&rtk->opt),j; +static void udtrop_ppp(rtk_t *rtk) { + double pos[3], azel[] = {0.0, PI / 2.0}, ztd, var; + int i = IT(&rtk->opt), j; - trace(3,"udtrop_ppp:\n"); + trace(3, "udtrop_ppp:\n"); - if (rtk->x[i]==0.0) { - ecef2pos(rtk->sol.rr,pos); - ztd=sbstropcorr(rtk->sol.time,pos,azel,&var); - initx(rtk,ztd,var,i); + if (rtk->x[i] == 0.0) { + ecef2pos(rtk->sol.rr, pos); + ztd = sbstropcorr(rtk->sol.time, pos, azel, &var); + initx(rtk, ztd, var, i); - if (rtk->opt.tropopt>=TROPOPT_ESTG) { - for (j=i+1;jopt.tropopt >= TROPOPT_ESTG) { + for (j = i + 1; j < i + 3; j++) initx(rtk, 1E-6, VAR_GRA, j); } - else { - rtk->P[i+i*rtk->nx]+=SQR(rtk->opt.prn[2])*fabs(rtk->tt); + } else { + rtk->P[i + i * rtk->nx] += SQR(rtk->opt.prn[2]) * fabs(rtk->tt); - if (rtk->opt.tropopt>=TROPOPT_ESTG) { - for (j=i+1;jP[j+j*rtk->nx]+=SQR(rtk->opt.prn[2]*0.1)*fabs(rtk->tt); - } - } + if (rtk->opt.tropopt >= TROPOPT_ESTG) { + for (j = i + 1; j < i + 3; j++) { + rtk->P[j + j * rtk->nx] += SQR(rtk->opt.prn[2] * 0.1) * fabs(rtk->tt); + } } + } } /* temporal update of ionospheric parameters ---------------------------------*/ -static void udiono_ppp(rtk_t *rtk, const obsd_t *obs, int n, const nav_t *nav) -{ - double freq1,freq2,ion,sinel,pos[3],*azel; - char *p; - int i,j,f2,gap_resion=GAP_RESION,sat; - - trace(3,"udiono_ppp:\n"); - - if ((p=strstr(rtk->opt.pppopt,"-GAP_RESION="))) { - sscanf(p,"-GAP_RESION=%d",&gap_resion); - } - /* reset ionosphere delay estimate if outage too long */ - for (i=0;iopt); - if (rtk->x[j]!=0.0&&(int)rtk->ssat[i].outc[0]>gap_resion) { - rtk->x[j]=0.0; - } - } - for (i=0;iopt); - if (rtk->x[j]==0.0) { - /* initialize ionosphere delay estimates if zero */ - f2=seliflc(rtk->opt.nf,satsys(sat,NULL)); - freq1=sat2freq(sat,obs[i].code[0],nav); - freq2=sat2freq(sat,obs[i].code[f2],nav); - if (obs[i].P[0]==0.0||obs[i].P[f2]==0.0||freq1==0.0||freq2==0.0) { - continue; - } - /* use pseudorange difference adjusted by freq for initial estimate */ - ion=(obs[i].P[0]-obs[i].P[f2])/(SQR(FREQL1/freq1)-SQR(FREQL1/freq2)); - ecef2pos(rtk->sol.rr,pos); - azel=rtk->ssat[sat-1].azel; - /* adjust delay estimate by path length */ - ion/=ionmapf(pos,azel); - initx(rtk,ion,VAR_IONO,j); - trace(4,"ion init: sat=%d ion=%.4f\n",sat,ion); - } - else { - sinel=sin(MAX(rtk->ssat[sat-1].azel[1],5.0*D2R)); - /* update variance of delay state */ - rtk->P[j+j*rtk->nx]+=SQR(rtk->opt.prn[1]/sinel)*fabs(rtk->tt); - } - } +static void udiono_ppp(rtk_t *rtk, const obsd_t *obs, int n, const nav_t *nav) { + double freq1, freq2, ion, sinel, pos[3], *azel; + char *p; + int i, j, f2, gap_resion = GAP_RESION, sat; + + trace(3, "udiono_ppp:\n"); + + if ((p = strstr(rtk->opt.pppopt, "-GAP_RESION="))) { + sscanf(p, "-GAP_RESION=%d", &gap_resion); + } + /* reset ionosphere delay estimate if outage too long */ + for (i = 0; i < MAXSAT; i++) { + j = II(i + 1, &rtk->opt); + if (rtk->x[j] != 0.0 && (int)rtk->ssat[i].outc[0] > gap_resion) { + rtk->x[j] = 0.0; + } + } + for (i = 0; i < n; i++) { + sat = obs[i].sat; + j = II(sat, &rtk->opt); + if (rtk->x[j] == 0.0) { + /* initialize ionosphere delay estimates if zero */ + f2 = seliflc(rtk->opt.nf, satsys(sat, NULL)); + freq1 = sat2freq(sat, obs[i].code[0], nav); + freq2 = sat2freq(sat, obs[i].code[f2], nav); + if (obs[i].P[0] == 0.0 || obs[i].P[f2] == 0.0 || freq1 == 0.0 || freq2 == 0.0) { + continue; + } + /* use pseudorange difference adjusted by freq for initial estimate */ + ion = (obs[i].P[0] - obs[i].P[f2]) / (SQR(FREQL1 / freq1) - SQR(FREQL1 / freq2)); + ecef2pos(rtk->sol.rr, pos); + azel = rtk->ssat[sat - 1].azel; + /* adjust delay estimate by path length */ + ion /= ionmapf(pos, azel); + initx(rtk, ion, VAR_IONO, j); + trace(4, "ion init: sat=%d ion=%.4f\n", sat, ion); + } else { + sinel = sin(MAX(rtk->ssat[sat - 1].azel[1], 5.0 * D2R)); + /* update variance of delay state */ + rtk->P[j + j * rtk->nx] += SQR(rtk->opt.prn[1] / sinel) * fabs(rtk->tt); + } + } } /* temporal update of L5-receiver-dcb parameters -----------------------------*/ -static void uddcb_ppp(rtk_t *rtk) -{ - int i=ID(&rtk->opt); +static void uddcb_ppp(rtk_t *rtk) { + int i = ID(&rtk->opt); - trace(3,"uddcb_ppp:\n"); + trace(3, "uddcb_ppp:\n"); - if (rtk->x[i]==0.0) { - initx(rtk,1E-6,VAR_DCB,i); - } + if (rtk->x[i] == 0.0) { + initx(rtk, 1E-6, VAR_DCB, i); + } } /* temporal update of phase biases -------------------------------------------*/ -static void udbias_ppp(rtk_t *rtk, const obsd_t *obs, int n, const nav_t *nav) -{ - double L[NFREQ],P[NFREQ],Lc,Pc,bias[MAXOBS],offset=0.0; - double freq1,freq2,ion,dantr[NFREQ]={0},dants[NFREQ]={0}; - int i,j,k,f,sat,slip[MAXOBS]={0},clk_jump=0; - - trace(3,"udbias : n=%d\n",n); - - /* handle day-boundary clock jump */ - if (rtk->opt.posopt[5]) { - clk_jump=ROUND(time2gpst(obs[0].time,NULL)*10)%864000==0; - } - for (i=0;iopt.nf;j++) { - rtk->ssat[i].slip[j]=0; - } - /* detect cycle slip by LLI */ - detslp_ll(rtk,obs,n); - - /* detect cycle slip by geometry-free phase jump */ - detslp_gf(rtk,obs,n,nav); - - /* detect slip by Melbourne-Wubbena linear combination jump */ - detslp_mw(rtk,obs,n,nav); - - for (f=0;fopt);f++) { - - /* reset phase-bias if expire obs outage counter */ - for (i=0;issat[i].outc[f]>(uint32_t)rtk->opt.maxout|| - rtk->opt.modear==ARMODE_INST||clk_jump) { - initx(rtk,0.0,0.0,IB(i+1,f,&rtk->opt)); - } - } - for (i=k=0;iopt); - corr_meas(obs+i,nav,rtk->ssat[sat-1].azel,&rtk->opt,dantr,dants, - 0.0,L,P,&Lc,&Pc); - - bias[i]=0.0; - - if (rtk->opt.ionoopt==IONOOPT_IFLC) { - bias[i]=Lc-Pc; - slip[i]=rtk->ssat[sat-1].slip[0]||rtk->ssat[sat-1].slip[1]; - } - else if (L[f]!=0.0&&P[f]!=0.0) { - freq1=sat2freq(sat,obs[i].code[0],nav); - freq2=sat2freq(sat,obs[i].code[f],nav); - slip[i]=rtk->ssat[sat-1].slip[f]; - if (f==0||obs[i].P[0]==0.0||obs[i].P[f]==0.0||freq1==0.0||freq2==0.0) - ion=0; - else - ion=(obs[i].P[0]-obs[i].P[f])/(1.0-SQR(freq1/freq2)); - bias[i]=L[f]-P[f]+2.0*ion*SQR(freq1/freq2); - } - if (rtk->x[j]==0.0||slip[i]||bias[i]==0.0) continue; - - offset+=bias[i]-rtk->x[j]; - k++; - } - /* correct phase-code jump to ensure phase-code coherence */ - if (k>=2&&fabs(offset/k)>0.0005*CLIGHT) { - for (i=0;iopt); - if (rtk->x[j]!=0.0) rtk->x[j]+=offset/k; - } - char tstr[40]; - trace(2,"phase-code jump corrected: %s n=%2d dt=%12.9fs\n", - time2str(rtk->sol.time,tstr,0),k,offset/k/CLIGHT); - } - for (i=0;iopt); - - rtk->P[j+j*rtk->nx]+=SQR(rtk->opt.prn[0])*fabs(rtk->tt); - - if (bias[i]==0.0||(rtk->x[j]!=0.0&&!slip[i])) continue; - - /* reinitialize phase-bias if detecting cycle slip */ - initx(rtk,bias[i],VAR_BIAS,IB(sat,f,&rtk->opt)); - - /* reset fix flags */ - for (k=0;kambc[sat-1].flags[k]=0; - - trace(3,"udbias_ppp: sat=%2d bias=%.3f\n",sat,bias[i]); - } - } +static void udbias_ppp(rtk_t *rtk, const obsd_t *obs, int n, const nav_t *nav) { + double L[NFREQ], P[NFREQ], Lc, Pc, bias[MAXOBS], offset = 0.0; + double freq1, freq2, ion, dantr[NFREQ] = {0}, dants[NFREQ] = {0}; + int i, j, k, f, sat, slip[MAXOBS] = {0}, clk_jump = 0; + + trace(3, "udbias : n=%d\n", n); + + /* handle day-boundary clock jump */ + if (rtk->opt.posopt[5]) { + clk_jump = ROUND(time2gpst(obs[0].time, NULL) * 10) % 864000 == 0; + } + for (i = 0; i < MAXSAT; i++) + for (j = 0; j < rtk->opt.nf; j++) { + rtk->ssat[i].slip[j] = 0; + } + /* detect cycle slip by LLI */ + detslp_ll(rtk, obs, n); + + /* detect cycle slip by geometry-free phase jump */ + detslp_gf(rtk, obs, n, nav); + + /* detect slip by Melbourne-Wubbena linear combination jump */ + detslp_mw(rtk, obs, n, nav); + + for (f = 0; f < NF(&rtk->opt); f++) { + /* reset phase-bias if expire obs outage counter */ + for (i = 0; i < MAXSAT; i++) { + if (++rtk->ssat[i].outc[f] > (uint32_t)rtk->opt.maxout || rtk->opt.modear == ARMODE_INST || + clk_jump) { + initx(rtk, 0.0, 0.0, IB(i + 1, f, &rtk->opt)); + } + } + for (i = k = 0; i < n && i < MAXOBS; i++) { + sat = obs[i].sat; + j = IB(sat, f, &rtk->opt); + corr_meas(obs + i, nav, rtk->ssat[sat - 1].azel, &rtk->opt, dantr, dants, 0.0, L, P, &Lc, + &Pc); + + bias[i] = 0.0; + + if (rtk->opt.ionoopt == IONOOPT_IFLC) { + bias[i] = Lc - Pc; + slip[i] = rtk->ssat[sat - 1].slip[0] || rtk->ssat[sat - 1].slip[1]; + } else if (L[f] != 0.0 && P[f] != 0.0) { + freq1 = sat2freq(sat, obs[i].code[0], nav); + freq2 = sat2freq(sat, obs[i].code[f], nav); + slip[i] = rtk->ssat[sat - 1].slip[f]; + if (f == 0 || obs[i].P[0] == 0.0 || obs[i].P[f] == 0.0 || freq1 == 0.0 || freq2 == 0.0) + ion = 0; + else + ion = (obs[i].P[0] - obs[i].P[f]) / (1.0 - SQR(freq1 / freq2)); + bias[i] = L[f] - P[f] + 2.0 * ion * SQR(freq1 / freq2); + } + if (rtk->x[j] == 0.0 || slip[i] || bias[i] == 0.0) continue; + + offset += bias[i] - rtk->x[j]; + k++; + } + /* correct phase-code jump to ensure phase-code coherence */ + if (k >= 2 && fabs(offset / k) > 0.0005 * CLIGHT) { + for (i = 0; i < MAXSAT; i++) { + j = IB(i + 1, f, &rtk->opt); + if (rtk->x[j] != 0.0) rtk->x[j] += offset / k; + } + char tstr[40]; + trace(2, "phase-code jump corrected: %s n=%2d dt=%12.9fs\n", time2str(rtk->sol.time, tstr, 0), + k, offset / k / CLIGHT); + } + for (i = 0; i < n && i < MAXOBS; i++) { + sat = obs[i].sat; + j = IB(sat, f, &rtk->opt); + + rtk->P[j + j * rtk->nx] += SQR(rtk->opt.prn[0]) * fabs(rtk->tt); + + if (bias[i] == 0.0 || (rtk->x[j] != 0.0 && !slip[i])) continue; + + /* reinitialize phase-bias if detecting cycle slip */ + initx(rtk, bias[i], VAR_BIAS, IB(sat, f, &rtk->opt)); + + /* reset fix flags */ + for (k = 0; k < MAXSAT; k++) rtk->ambc[sat - 1].flags[k] = 0; + + trace(3, "udbias_ppp: sat=%2d bias=%.3f\n", sat, bias[i]); + } + } } /* temporal update of states --------------------------------------------------*/ -static void udstate_ppp(rtk_t *rtk, const obsd_t *obs, int n, const nav_t *nav) -{ - trace(3,"udstate_ppp: n=%d\n",n); - - /* temporal update of position */ - udpos_ppp(rtk); - - /* temporal update of clock */ - udclk_ppp(rtk); - - /* temporal update of tropospheric parameters */ - if (rtk->opt.tropopt==TROPOPT_EST||rtk->opt.tropopt==TROPOPT_ESTG) { - udtrop_ppp(rtk); - } - /* temporal update of ionospheric parameters */ - if (rtk->opt.ionoopt==IONOOPT_EST) { - udiono_ppp(rtk,obs,n,nav); - } - /* temporal update of L5-receiver-dcb parameters */ - if (rtk->opt.nf>=3) { - uddcb_ppp(rtk); - } - /* temporal update of phase-bias */ - udbias_ppp(rtk,obs,n,nav); +static void udstate_ppp(rtk_t *rtk, const obsd_t *obs, int n, const nav_t *nav) { + trace(3, "udstate_ppp: n=%d\n", n); + + /* temporal update of position */ + udpos_ppp(rtk); + + /* temporal update of clock */ + udclk_ppp(rtk); + + /* temporal update of tropospheric parameters */ + if (rtk->opt.tropopt == TROPOPT_EST || rtk->opt.tropopt == TROPOPT_ESTG) { + udtrop_ppp(rtk); + } + /* temporal update of ionospheric parameters */ + if (rtk->opt.ionoopt == IONOOPT_EST) { + udiono_ppp(rtk, obs, n, nav); + } + /* temporal update of L5-receiver-dcb parameters */ + if (rtk->opt.nf >= 3) { + uddcb_ppp(rtk); + } + /* temporal update of phase-bias */ + udbias_ppp(rtk, obs, n, nav); } /* satellite antenna phase center variation ----------------------------------*/ -static void satantpcv(const double *rs, const double *rr, const pcv_t *pcv, - double *dant) -{ - double ru[3],rz[3],eu[3],ez[3],nadir,cosa; - int i; - - for (i=0;i<3;i++) { - ru[i]=rr[i]-rs[i]; - rz[i]=-rs[i]; - } - if (!normv3(ru,eu)||!normv3(rz,ez)) return; +static void satantpcv(const double *rs, const double *rr, const pcv_t *pcv, double *dant) { + double ru[3], rz[3], eu[3], ez[3], nadir, cosa; + int i; + + for (i = 0; i < 3; i++) { + ru[i] = rr[i] - rs[i]; + rz[i] = -rs[i]; + } + if (!normv3(ru, eu) || !normv3(rz, ez)) return; - cosa=dot3(eu,ez); - cosa=cosa<-1.0?-1.0:(cosa>1.0?1.0:cosa); - nadir=acos(cosa); + cosa = dot3(eu, ez); + cosa = cosa < -1.0 ? -1.0 : (cosa > 1.0 ? 1.0 : cosa); + nadir = acos(cosa); - antmodel_s(pcv,nadir,dant); + antmodel_s(pcv, nadir, dant); } /* precise tropospheric model ------------------------------------------------*/ -static double trop_model_prec(gtime_t time, const double *pos, - const double *azel, const double *x, double *dtdx, - double *var) -{ - const double zazel[]={0.0,PI/2.0}; - double zhd,m_h,m_w,cotz,grad_n,grad_e; - - /* zenith hydrostatic delay */ - zhd=tropmodel(time,pos,zazel,0.0); - - /* mapping function */ - m_h=tropmapf(time,pos,azel,&m_w); - - if (azel[1]>0.0) { - - /* m_w=m_0+m_0*cot(el)*(Gn*cos(az)+Ge*sin(az)): ref [6] */ - cotz=1.0/tan(azel[1]); - grad_n=m_w*cotz*cos(azel[0]); - grad_e=m_w*cotz*sin(azel[0]); - m_w+=grad_n*x[1]+grad_e*x[2]; - dtdx[1]=grad_n*(x[0]-zhd); - dtdx[2]=grad_e*(x[0]-zhd); - } - dtdx[0]=m_w; - *var=SQR(0.01); - return m_h*zhd+m_w*(x[0]-zhd); +static double trop_model_prec(gtime_t time, const double *pos, const double *azel, const double *x, + double *dtdx, double *var) { + const double zazel[] = {0.0, PI / 2.0}; + double zhd, m_h, m_w, cotz, grad_n, grad_e; + + /* zenith hydrostatic delay */ + zhd = tropmodel(time, pos, zazel, 0.0); + + /* mapping function */ + m_h = tropmapf(time, pos, azel, &m_w); + + if (azel[1] > 0.0) { + /* m_w=m_0+m_0*cot(el)*(Gn*cos(az)+Ge*sin(az)): ref [6] */ + cotz = 1.0 / tan(azel[1]); + grad_n = m_w * cotz * cos(azel[0]); + grad_e = m_w * cotz * sin(azel[0]); + m_w += grad_n * x[1] + grad_e * x[2]; + dtdx[1] = grad_n * (x[0] - zhd); + dtdx[2] = grad_e * (x[0] - zhd); + } + dtdx[0] = m_w; + *var = SQR(0.01); + return m_h * zhd + m_w * (x[0] - zhd); } /* tropospheric model ---------------------------------------------------------*/ -static int model_trop(gtime_t time, const double *pos, const double *azel, - const prcopt_t *opt, const double *x, double *dtdx, - const nav_t *nav, double *dtrp, double *var) -{ - (void)nav; - double trp[3]={0}; - - if (opt->tropopt==TROPOPT_SAAS) { - *dtrp=tropmodel(time,pos,azel,REL_HUMI); - *var=SQR(ERR_SAAS); - return 1; - } - if (opt->tropopt==TROPOPT_SBAS) { - *dtrp=sbstropcorr(time,pos,azel,var); - return 1; - } - if (opt->tropopt==TROPOPT_EST||opt->tropopt==TROPOPT_ESTG) { - matcpy(trp,x+IT(opt),opt->tropopt==TROPOPT_EST?1:3,1); - *dtrp=trop_model_prec(time,pos,azel,trp,dtdx,var); - return 1; - } - return 0; +static int model_trop(gtime_t time, const double *pos, const double *azel, const prcopt_t *opt, + const double *x, double *dtdx, const nav_t *nav, double *dtrp, double *var) { + (void)nav; + double trp[3] = {0}; + + if (opt->tropopt == TROPOPT_SAAS) { + *dtrp = tropmodel(time, pos, azel, REL_HUMI); + *var = SQR(ERR_SAAS); + return 1; + } + if (opt->tropopt == TROPOPT_SBAS) { + *dtrp = sbstropcorr(time, pos, azel, var); + return 1; + } + if (opt->tropopt == TROPOPT_EST || opt->tropopt == TROPOPT_ESTG) { + matcpy(trp, x + IT(opt), opt->tropopt == TROPOPT_EST ? 1 : 3, 1); + *dtrp = trop_model_prec(time, pos, azel, trp, dtdx, var); + return 1; + } + return 0; } /* ionospheric model ---------------------------------------------------------*/ -static int model_iono(gtime_t time, const double *pos, const double *azel, - const prcopt_t *opt, int sat, const double *x, - const nav_t *nav, double *dion, double *var) -{ - if (opt->ionoopt==IONOOPT_SBAS) { - return sbsioncorr(time,nav,pos,azel,dion,var); - } - if (opt->ionoopt==IONOOPT_TEC) { - return iontec(time,nav,pos,azel,1,dion,var); - } - if (opt->ionoopt==IONOOPT_BRDC) { - *dion=ionmodel(time,nav->ion_gps,pos,azel); - *var=SQR(*dion*ERR_BRDCI); - return 1; - } - if (opt->ionoopt==IONOOPT_EST) { - /* Estimated delay is a vertical delay, apply the mapping function. */ - *dion=x[II(sat,opt)]*ionmapf(pos,azel); - *var=0.0; - return 1; - } - if (opt->ionoopt==IONOOPT_IFLC) { - *dion=*var=0.0; - return 1; - } - return 0; +static int model_iono(gtime_t time, const double *pos, const double *azel, const prcopt_t *opt, + int sat, const double *x, const nav_t *nav, double *dion, double *var) { + if (opt->ionoopt == IONOOPT_SBAS) { + return sbsioncorr(time, nav, pos, azel, dion, var); + } + if (opt->ionoopt == IONOOPT_TEC) { + return iontec(time, nav, pos, azel, 1, dion, var); + } + if (opt->ionoopt == IONOOPT_BRDC) { + *dion = ionmodel(time, nav->ion_gps, pos, azel); + *var = SQR(*dion * ERR_BRDCI); + return 1; + } + if (opt->ionoopt == IONOOPT_EST) { + /* Estimated delay is a vertical delay, apply the mapping function. */ + *dion = x[II(sat, opt)] * ionmapf(pos, azel); + *var = 0.0; + return 1; + } + if (opt->ionoopt == IONOOPT_IFLC) { + *dion = *var = 0.0; + return 1; + } + return 0; } /* phase and code residuals --------------------------------------------------*/ -static int ppp_res(int post, const obsd_t *obs, int n, const double *rs, - const double *dts, const double *var_rs, const int *svh, - const double *dr, int *exc, const nav_t *nav, - const double *x, rtk_t *rtk, double *v, double *H, double *R, - double *azel) -{ - prcopt_t *opt=&rtk->opt; - double y,r,cdtr,bias,rr[3],pos[3],e[3],dtdx[3],L[NFREQ],P[NFREQ],Lc,Pc; - double var[MAXOBS*2*NFREQ],dtrp=0.0,dion=0.0,vart=0.0,vari=0.0,dcb,freq; - double dantr[NFREQ]={0},dants[NFREQ]={0}; - double ve[MAXOBS*2*NFREQ]={0},vmax=0; - char str[40]; - int ne=0,obsi[MAXOBS*2*NFREQ]={0},frqi[MAXOBS*2*NFREQ],maxobs,maxfrq,rej; - int i,j,k,sat,sys,nv=0,nx=rtk->nx,stat=1,frq,code; - - time2str(obs[0].time,str,2); - - for (i=0;inf;j++) rtk->ssat[i].vsat[j]=0; - - for (i=0;i<3;i++) rr[i]=x[i]+dr[i]; - ecef2pos(rr,pos); - - for (i=0;ielmin) { - exc[i]=1; - continue; - } - if (!(sys=satsys(sat,NULL))||!rtk->ssat[sat-1].vs|| - satexclude(sat,var_rs[i],svh[i],opt)||exc[i]) { - exc[i]=1; - continue; - } - /* tropospheric and ionospheric model */ - if (!model_trop(obs[i].time,pos,azel+i*2,opt,x,dtdx,nav,&dtrp,&vart)|| - !model_iono(obs[i].time,pos,azel+i*2,opt,sat,x,nav,&dion,&vari)) { - continue; - } - /* satellite and receiver antenna model */ - if (opt->posopt[0]) satantpcv(rs+i*6,rr,nav->pcvs+sat-1,dants); - antmodel(opt->pcvr,opt->antdel[0],azel+i*2,opt->posopt[1],dantr); - - /* phase windup model */ - if (!model_phw(rtk->sol.time,sat,nav->pcvs[sat-1].type, - opt->posopt[2]?2:0,rs+i*6,rr,&rtk->ssat[sat-1].phw)) { - continue; - } - /* corrected phase and code measurements */ - corr_meas(obs+i,nav,azel+i*2,&rtk->opt,dantr,dants, - rtk->ssat[sat-1].phw,L,P,&Lc,&Pc); - - /* stack phase and code residuals {L1,P1,L2,P2,...} */ - for (j=0;j<2*NF(opt);j++) { - double C=0.0; - - dcb=bias=0.0; - code=j%2; /* 0=phase, 1=code */ - frq=j/2; - - if (opt->ionoopt==IONOOPT_IFLC) { - if ((y=code==0?Lc:Pc)==0.0) continue; - } - else { - if ((y=code==0?L[frq]:P[frq])==0.0) continue; - - if ((freq=sat2freq(sat,obs[i].code[frq],nav))==0.0) continue; - /* The iono paths have already applied a slant factor. */ - C=SQR(FREQL1/freq)*(code==0?-1.0:1.0); - } - if (H) { - for (k=0;ktropopt==TROPOPT_EST||opt->tropopt==TROPOPT_ESTG) { - for (k=0;k<(opt->tropopt>=TROPOPT_ESTG?3:1);k++) { - H[IT(opt)+k+nx*nv]=dtdx[k]; - } - } - } - if (opt->ionoopt==IONOOPT_EST) { - if (rtk->x[II(sat,opt)]==0.0) continue; - /* The vertical iono delay is estimated, but the residual is - * in the direction of the slant, so apply the slat factor - * mapping function. */ - if (H) H[II(sat,opt)+nx*nv]=C*ionmapf(pos,azel+i*2); - } - if (frq==2&&code==1) { /* L5-receiver-dcb */ - dcb+=rtk->x[ID(opt)]; - if (H) H[ID(opt)+nx*nv]=1.0; - } - if (code==0) { /* phase bias */ - if ((bias=x[IB(sat,frq,opt)])==0.0) continue; - if (H) H[IB(sat,frq,opt)+nx*nv]=1.0; - } - /* residual */ - double res=y-(r+cdtr-CLIGHT*dts[i*2]+dtrp+C*dion+dcb+bias); - if (v) v[nv]=res; - - if (code==0) rtk->ssat[sat-1].resc[frq]=res; /* carrier phase */ - else rtk->ssat[sat-1].resp[frq]=res; /* pseudorange */ - - /* variance */ - var[nv]=varerr(sat,sys,azel[1+i*2], - rtk->ssat[sat-1].snr_rover[frq], - j,opt,obs+i); - var[nv] +=vart+SQR(C)*vari+var_rs[i]; - if (sys==SYS_GLO&&code==1) var[nv]+=VAR_GLO_IFB; - - trace(3,"%s sat=%2d %s%d res=%9.4f sig=%9.4f el=%4.1f\n",str,sat, - code?"P":"L",frq+1,res,sqrt(var[nv]),azel[1+i*2]*R2D); - - /* reject satellite by pre-fit residuals */ - if (!post&&opt->maxinno[code]>0.0&&fabs(res)>opt->maxinno[code]) { - trace(2,"outlier (%d) rejected %s sat=%2d %s%d res=%9.4f el=%4.1f\n", - post,str,sat,code?"P":"L",frq+1,res,azel[1+i*2]*R2D); - exc[i]=1; rtk->ssat[sat-1].rejc[frq]++; - continue; - } - /* record large post-fit residuals */ - if (post&&fabs(res)>sqrt(var[nv])*THRES_REJECT) { - obsi[ne]=i; frqi[ne]=j; ve[ne]=res; ne++; - } - if (code==0) rtk->ssat[sat-1].vsat[frq]=1; - nv++; - } - } - /* reject satellite with large and max post-fit residual */ - if (post&&ne>0) { - vmax=ve[0]; maxobs=obsi[0]; maxfrq=frqi[0]; rej=0; - for (j=1;j=fabs(ve[j])) continue; - vmax=ve[j]; maxobs=obsi[j]; maxfrq=frqi[j]; rej=j; +static int ppp_res(int post, const obsd_t *obs, int n, const double *rs, const double *dts, + const double *var_rs, const int *svh, const double *dr, int *exc, + const nav_t *nav, const double *x, rtk_t *rtk, double *v, double *H, double *R, + double *azel) { + prcopt_t *opt = &rtk->opt; + double y, r, cdtr, bias, rr[3], pos[3], e[3], dtdx[3], L[NFREQ], P[NFREQ], Lc, Pc; + double var[MAXOBS * 2 * NFREQ], dtrp = 0.0, dion = 0.0, vart = 0.0, vari = 0.0, dcb, freq; + double dantr[NFREQ] = {0}, dants[NFREQ] = {0}; + double ve[MAXOBS * 2 * NFREQ] = {0}, vmax = 0; + char str[40]; + int ne = 0, obsi[MAXOBS * 2 * NFREQ] = {0}, frqi[MAXOBS * 2 * NFREQ], maxobs, maxfrq, rej; + int i, j, k, sat, sys, nv = 0, nx = rtk->nx, stat = 1, frq, code; + + time2str(obs[0].time, str, 2); + + for (i = 0; i < MAXSAT; i++) + for (j = 0; j < opt->nf; j++) rtk->ssat[i].vsat[j] = 0; + + for (i = 0; i < 3; i++) rr[i] = x[i] + dr[i]; + ecef2pos(rr, pos); + + for (i = 0; i < n && i < MAXOBS; i++) { + sat = obs[i].sat; + + if ((r = geodist(rs + i * 6, rr, e)) <= 0.0 || satazel(pos, e, azel + i * 2) < opt->elmin) { + exc[i] = 1; + continue; + } + if (!(sys = satsys(sat, NULL)) || !rtk->ssat[sat - 1].vs || + satexclude(sat, var_rs[i], svh[i], opt) || exc[i]) { + exc[i] = 1; + continue; + } + /* tropospheric and ionospheric model */ + if (!model_trop(obs[i].time, pos, azel + i * 2, opt, x, dtdx, nav, &dtrp, &vart) || + !model_iono(obs[i].time, pos, azel + i * 2, opt, sat, x, nav, &dion, &vari)) { + continue; + } + /* satellite and receiver antenna model */ + if (opt->posopt[0]) satantpcv(rs + i * 6, rr, nav->pcvs + sat - 1, dants); + antmodel(opt->pcvr, opt->antdel[0], azel + i * 2, opt->posopt[1], dantr); + + /* phase windup model */ + if (!model_phw(rtk->sol.time, sat, nav->pcvs[sat - 1].type, opt->posopt[2] ? 2 : 0, rs + i * 6, + rr, &rtk->ssat[sat - 1].phw)) { + continue; + } + /* corrected phase and code measurements */ + corr_meas(obs + i, nav, azel + i * 2, &rtk->opt, dantr, dants, rtk->ssat[sat - 1].phw, L, P, + &Lc, &Pc); + + /* stack phase and code residuals {L1,P1,L2,P2,...} */ + for (j = 0; j < 2 * NF(opt); j++) { + double C = 0.0; + + dcb = bias = 0.0; + code = j % 2; /* 0=phase, 1=code */ + frq = j / 2; + + if (opt->ionoopt == IONOOPT_IFLC) { + if ((y = code == 0 ? Lc : Pc) == 0.0) continue; + } else { + if ((y = code == 0 ? L[frq] : P[frq]) == 0.0) continue; + + if ((freq = sat2freq(sat, obs[i].code[frq], nav)) == 0.0) continue; + /* The iono paths have already applied a slant factor. */ + C = SQR(FREQL1 / freq) * (code == 0 ? -1.0 : 1.0); + } + if (H) { + for (k = 0; k < nx; k++) H[k + nx * nv] = 0.0; + for (k = 0; k < 3; k++) H[k + nx * nv] = -e[k]; + } + + /* receiver clock */ + switch (sys) { + case SYS_GLO: + k = 1; + break; + case SYS_GAL: + k = 2; + break; + case SYS_CMP: + k = 3; + break; + case SYS_IRN: + k = 4; + break; + default: + k = 0; + break; + } + cdtr = x[IC(k, opt)]; + if (H) { + H[IC(k, opt) + nx * nv] = 1.0; + + if (opt->tropopt == TROPOPT_EST || opt->tropopt == TROPOPT_ESTG) { + for (k = 0; k < (opt->tropopt >= TROPOPT_ESTG ? 3 : 1); k++) { + H[IT(opt) + k + nx * nv] = dtdx[k]; + } } - sat=obs[maxobs].sat; - trace(2,"outlier (%d) rejected %s sat=%2d %s%d res=%9.4f el=%4.1f\n", - post,str,sat,maxfrq%2?"P":"L",maxfrq/2+1,vmax,azel[1+maxobs*2]*R2D); - exc[maxobs]=1; rtk->ssat[sat-1].rejc[maxfrq%2]++; stat=0; - ve[rej]=0; - } - if (R) { - for (j=0;jionoopt == IONOOPT_EST) { + if (rtk->x[II(sat, opt)] == 0.0) continue; + /* The vertical iono delay is estimated, but the residual is + * in the direction of the slant, so apply the slat factor + * mapping function. */ + if (H) H[II(sat, opt) + nx * nv] = C * ionmapf(pos, azel + i * 2); + } + if (frq == 2 && code == 1) { /* L5-receiver-dcb */ + dcb += rtk->x[ID(opt)]; + if (H) H[ID(opt) + nx * nv] = 1.0; + } + if (code == 0) { /* phase bias */ + if ((bias = x[IB(sat, frq, opt)]) == 0.0) continue; + if (H) H[IB(sat, frq, opt) + nx * nv] = 1.0; + } + /* residual */ + double res = y - (r + cdtr - CLIGHT * dts[i * 2] + dtrp + C * dion + dcb + bias); + if (v) v[nv] = res; + + if (code == 0) + rtk->ssat[sat - 1].resc[frq] = res; /* carrier phase */ + else + rtk->ssat[sat - 1].resp[frq] = res; /* pseudorange */ + + /* variance */ + var[nv] = + varerr(sat, sys, azel[1 + i * 2], rtk->ssat[sat - 1].snr_rover[frq], j, opt, obs + i); + var[nv] += vart + SQR(C) * vari + var_rs[i]; + if (sys == SYS_GLO && code == 1) var[nv] += VAR_GLO_IFB; + + trace(3, "%s sat=%2d %s%d res=%9.4f sig=%9.4f el=%4.1f\n", str, sat, code ? "P" : "L", + frq + 1, res, sqrt(var[nv]), azel[1 + i * 2] * R2D); + + /* reject satellite by pre-fit residuals */ + if (!post && opt->maxinno[code] > 0.0 && fabs(res) > opt->maxinno[code]) { + trace(2, "outlier (%d) rejected %s sat=%2d %s%d res=%9.4f el=%4.1f\n", post, str, sat, + code ? "P" : "L", frq + 1, res, azel[1 + i * 2] * R2D); + exc[i] = 1; + rtk->ssat[sat - 1].rejc[frq]++; + continue; + } + /* record large post-fit residuals */ + if (post && fabs(res) > sqrt(var[nv]) * THRES_REJECT) { + obsi[ne] = i; + frqi[ne] = j; + ve[ne] = res; + ne++; + } + if (code == 0) rtk->ssat[sat - 1].vsat[frq] = 1; + nv++; + } + } + /* reject satellite with large and max post-fit residual */ + if (post && ne > 0) { + vmax = ve[0]; + maxobs = obsi[0]; + maxfrq = frqi[0]; + rej = 0; + for (j = 1; j < ne; j++) { + if (fabs(vmax) >= fabs(ve[j])) continue; + vmax = ve[j]; + maxobs = obsi[j]; + maxfrq = frqi[j]; + rej = j; + } + sat = obs[maxobs].sat; + trace(2, "outlier (%d) rejected %s sat=%2d %s%d res=%9.4f el=%4.1f\n", post, str, sat, + maxfrq % 2 ? "P" : "L", maxfrq / 2 + 1, vmax, azel[1 + maxobs * 2] * R2D); + exc[maxobs] = 1; + rtk->ssat[sat - 1].rejc[maxfrq % 2]++; + stat = 0; + ve[rej] = 0; + } + if (R) { + for (j = 0; j < nv; j++) + for (i = 0; i < nv; i++) R[i + j * nv] = 0.0; + for (i = 0; i < nv; i++) R[i + i * nv] = var[i]; + } + return post ? stat : nv; } /* number of estimated states ------------------------------------------------*/ -extern int pppnx(const prcopt_t *opt) -{ - return NX(opt); -} +extern int pppnx(const prcopt_t *opt) { return NX(opt); } /* update solution status ----------------------------------------------------*/ -static void update_stat(rtk_t *rtk, const obsd_t *obs, int n, int stat) -{ - const prcopt_t *opt=&rtk->opt; - int i,j; - - /* test # of valid satellites */ - rtk->sol.ns=0; - for (i=0;inf;j++) { - if (!rtk->ssat[obs[i].sat-1].vsat[j]) continue; - rtk->ssat[obs[i].sat-1].lock[j]++; - rtk->ssat[obs[i].sat-1].outc[j]=0; - if (j==0) rtk->sol.ns++; - } - } - rtk->sol.stat=rtk->sol.nssol.stat==SOLQ_FIX) { - for (i=0;i<3;i++) { - rtk->sol.rr[i]=rtk->xa[i]; - rtk->sol.qr[i]=(float)rtk->Pa[i+i*rtk->na]; - } - rtk->sol.qr[3]=(float)rtk->Pa[1]; - rtk->sol.qr[4]=(float)rtk->Pa[1+2*rtk->na]; - rtk->sol.qr[5]=(float)rtk->Pa[2]; - } - else { - for (i=0;i<3;i++) { - rtk->sol.rr[i]=rtk->x[i]; - rtk->sol.qr[i]=(float)rtk->P[i+i*rtk->nx]; - } - rtk->sol.qr[3]=(float)rtk->P[1]; - rtk->sol.qr[4]=(float)rtk->P[2+rtk->nx]; - rtk->sol.qr[5]=(float)rtk->P[2]; - - if (rtk->opt.dynamics) { /* velocity and covariance */ - for (i=3;i<6;i++) { - rtk->sol.rr[i]=rtk->x[i]; - rtk->sol.qv[i-3]=(float)rtk->P[i+i*rtk->nx]; - } - rtk->sol.qv[3]=(float)rtk->P[4+3*rtk->nx]; - rtk->sol.qv[4]=(float)rtk->P[5+4*rtk->nx]; - rtk->sol.qv[5]=(float)rtk->P[5+3*rtk->nx]; - } - } - rtk->sol.dtr[0]=rtk->x[IC(0,opt)]/CLIGHT; /* GPS */ - rtk->sol.dtr[1]=(rtk->x[IC(1,opt)]-rtk->x[IC(0,opt)])/CLIGHT; /* GLO-GPS */ - rtk->sol.dtr[2]=(rtk->x[IC(2,opt)]-rtk->x[IC(0,opt)])/CLIGHT; /* GAL-GPS */ - rtk->sol.dtr[3]=(rtk->x[IC(3,opt)]-rtk->x[IC(0,opt)])/CLIGHT; /* BDS-GPS */ - - for (i=0;inf;j++) { - rtk->ssat[obs[i].sat-1].snr_rover[j]=obs[i].SNR[j]; - rtk->ssat[obs[i].sat-1].snr_base[j] =0; - } - for (i=0;inf;j++) { - if (rtk->ssat[i].slip[j]&(LLI_SLIP|LLI_HALFC)) rtk->ssat[i].slipc[j]++; - if (rtk->ssat[i].fix[j]==2&&stat!=SOLQ_FIX) rtk->ssat[i].fix[j]=1; +static void update_stat(rtk_t *rtk, const obsd_t *obs, int n, int stat) { + const prcopt_t *opt = &rtk->opt; + int i, j; + + /* test # of valid satellites */ + rtk->sol.ns = 0; + for (i = 0; i < n && i < MAXOBS; i++) { + for (j = 0; j < opt->nf; j++) { + if (!rtk->ssat[obs[i].sat - 1].vsat[j]) continue; + rtk->ssat[obs[i].sat - 1].lock[j]++; + rtk->ssat[obs[i].sat - 1].outc[j] = 0; + if (j == 0) rtk->sol.ns++; + } + } + rtk->sol.stat = rtk->sol.ns < MIN_NSAT_SOL ? SOLQ_NONE : stat; + + if (rtk->sol.stat == SOLQ_FIX) { + for (i = 0; i < 3; i++) { + rtk->sol.rr[i] = rtk->xa[i]; + rtk->sol.qr[i] = (float)rtk->Pa[i + i * rtk->na]; + } + rtk->sol.qr[3] = (float)rtk->Pa[1]; + rtk->sol.qr[4] = (float)rtk->Pa[1 + 2 * rtk->na]; + rtk->sol.qr[5] = (float)rtk->Pa[2]; + } else { + for (i = 0; i < 3; i++) { + rtk->sol.rr[i] = rtk->x[i]; + rtk->sol.qr[i] = (float)rtk->P[i + i * rtk->nx]; + } + rtk->sol.qr[3] = (float)rtk->P[1]; + rtk->sol.qr[4] = (float)rtk->P[2 + rtk->nx]; + rtk->sol.qr[5] = (float)rtk->P[2]; + + if (rtk->opt.dynamics) { /* velocity and covariance */ + for (i = 3; i < 6; i++) { + rtk->sol.rr[i] = rtk->x[i]; + rtk->sol.qv[i - 3] = (float)rtk->P[i + i * rtk->nx]; + } + rtk->sol.qv[3] = (float)rtk->P[4 + 3 * rtk->nx]; + rtk->sol.qv[4] = (float)rtk->P[5 + 4 * rtk->nx]; + rtk->sol.qv[5] = (float)rtk->P[5 + 3 * rtk->nx]; + } + } + rtk->sol.dtr[0] = rtk->x[IC(0, opt)] / CLIGHT; /* GPS */ + rtk->sol.dtr[1] = (rtk->x[IC(1, opt)] - rtk->x[IC(0, opt)]) / CLIGHT; /* GLO-GPS */ + rtk->sol.dtr[2] = (rtk->x[IC(2, opt)] - rtk->x[IC(0, opt)]) / CLIGHT; /* GAL-GPS */ + rtk->sol.dtr[3] = (rtk->x[IC(3, opt)] - rtk->x[IC(0, opt)]) / CLIGHT; /* BDS-GPS */ + + for (i = 0; i < n && i < MAXOBS; i++) + for (j = 0; j < opt->nf; j++) { + rtk->ssat[obs[i].sat - 1].snr_rover[j] = obs[i].SNR[j]; + rtk->ssat[obs[i].sat - 1].snr_base[j] = 0; + } + for (i = 0; i < MAXSAT; i++) + for (j = 0; j < opt->nf; j++) { + if (rtk->ssat[i].slip[j] & (LLI_SLIP | LLI_HALFC)) rtk->ssat[i].slipc[j]++; + if (rtk->ssat[i].fix[j] == 2 && stat != SOLQ_FIX) rtk->ssat[i].fix[j] = 1; } } /* test hold ambiguity -------------------------------------------------------*/ -static int test_hold_amb(rtk_t *rtk) -{ - int i,j,stat=0; - - /* no fix-and-hold mode */ - if (rtk->opt.modear!=ARMODE_FIXHOLD) return 0; - - /* reset # of continuous fixed if new ambiguity introduced */ - for (i=0;issat[i].fix[0]!=2&&rtk->ssat[i].fix[1]!=2) continue; - for (j=0;jssat[j].fix[0]!=2&&rtk->ssat[j].fix[1]!=2) continue; - if (!rtk->ambc[j].flags[i]||!rtk->ambc[i].flags[j]) stat=1; - rtk->ambc[j].flags[i]=rtk->ambc[i].flags[j]=1; - } - } - if (stat) { - rtk->nfix=0; - return 0; - } - /* test # of continuous fixed */ - return ++rtk->nfix>=rtk->opt.minfix; +static int test_hold_amb(rtk_t *rtk) { + int i, j, stat = 0; + + /* no fix-and-hold mode */ + if (rtk->opt.modear != ARMODE_FIXHOLD) return 0; + + /* reset # of continuous fixed if new ambiguity introduced */ + for (i = 0; i < MAXSAT; i++) { + if (rtk->ssat[i].fix[0] != 2 && rtk->ssat[i].fix[1] != 2) continue; + for (j = 0; j < MAXSAT; j++) { + if (rtk->ssat[j].fix[0] != 2 && rtk->ssat[j].fix[1] != 2) continue; + if (!rtk->ambc[j].flags[i] || !rtk->ambc[i].flags[j]) stat = 1; + rtk->ambc[j].flags[i] = rtk->ambc[i].flags[j] = 1; + } + } + if (stat) { + rtk->nfix = 0; + return 0; + } + /* test # of continuous fixed */ + return ++rtk->nfix >= rtk->opt.minfix; } /* precise point positioning -------------------------------------------------*/ -extern void pppos(rtk_t *rtk, const obsd_t *obs, int n, const nav_t *nav) -{ - const prcopt_t *opt=&rtk->opt; - double *rs,*dts,*var,*v,*H,*R,*azel,*xp,*Pp,dr[3]={0},std[3]; - char str[40]; - int i,j,nv,info,svh[MAXOBS],exc[MAXOBS]={0},stat=SOLQ_SINGLE; - - time2str(obs[0].time,str,2); - trace(3,"pppos : time=%s nx=%d n=%d\n",str,rtk->nx,n); - - rs=mat(6,n); dts=mat(2,n); var=mat(1,n); azel=zeros(2,n); - - for (i=0;inf;j++) rtk->ssat[i].fix[j]=0; - for (i=0;inf;j++) { - rtk->ssat[obs[i].sat-1].snr_rover[j]=obs[i].SNR[j]; - rtk->ssat[obs[i].sat-1].snr_base[j] =0; - } - - /* temporal update of ekf states */ - udstate_ppp(rtk,obs,n,nav); - - /* satellite positions and clocks */ - satposs(obs[0].time,obs,n,nav,rtk->opt.sateph,rs,dts,var,svh); - - /* exclude measurements of eclipsing satellite (block IIA) */ - if (rtk->opt.posopt[3]) { - testeclipse(obs,n,nav,rs); - } - /* earth tides correction */ - if (opt->tidecorr) { - tidedisp(gpst2utc(obs[0].time),rtk->x,opt->tidecorr,&nav->erp, - opt->odisp[0],dr); - } - nv=n*rtk->opt.nf*2+MAXSAT+3; - xp=mat(rtk->nx,1); Pp=zeros(rtk->nx,rtk->nx); - v=mat(nv,1); H=mat(rtk->nx,nv); R=mat(nv,nv); - - for (i=0;ix,rtk->nx,1); - matcpy(Pp,rtk->P,rtk->nx,rtk->nx); - - /* prefit residuals */ - if (!(nv=ppp_res(0,obs,n,rs,dts,var,svh,dr,exc,nav,xp,rtk,v,H,R,azel))) { - trace(2,"%s ppp (%d) no valid obs data\n",str,i+1); - break; - } - /* measurement update of ekf states */ - if ((info=filter(xp,Pp,H,v,R,rtk->nx,nv))) { - trace(2,"%s ppp (%d) filter error info=%d\n",str,i+1,info); - break; - } - /* postfit residuals */ - if (ppp_res(i+1,obs,n,rs,dts,var,svh,dr,exc,nav,xp,rtk,NULL,NULL,NULL,azel)) { - matcpy(rtk->x,xp,rtk->nx,1); - matcpy(rtk->P,Pp,rtk->nx,rtk->nx); - stat=SOLQ_PPP; - break; - } - } - if (i>=MAX_ITER) { - trace(2,"%s ppp (%d) iteration overflows\n",str,i); - } - if (stat==SOLQ_PPP) { - - if (ppp_ar(rtk,obs,n,exc,nav,azel,xp,Pp)&& - ppp_res(9,obs,n,rs,dts,var,svh,dr,exc,nav,xp,rtk,NULL,NULL,NULL,azel)) { - - matcpy(rtk->xa,xp,rtk->nx,1); - matcpy(rtk->Pa,Pp,rtk->nx,rtk->nx); - - for (i=0;i<3;i++) std[i]=sqrt(Pp[i+i*rtk->nx]); - if (norm(std,3)nfix=0; - } - /* update solution status */ - update_stat(rtk,obs,n,stat); - - if (stat==SOLQ_FIX&&test_hold_amb(rtk)) { - matcpy(rtk->x,xp,rtk->nx,1); - matcpy(rtk->P,Pp,rtk->nx,rtk->nx); - trace(2,"%s hold ambiguity\n",str); - rtk->nfix=0; - } - } - free(rs); free(dts); free(var); free(azel); - free(xp); free(Pp); free(v); free(H); free(R); +extern void pppos(rtk_t *rtk, const obsd_t *obs, int n, const nav_t *nav) { + const prcopt_t *opt = &rtk->opt; + double *rs, *dts, *var, *v, *H, *R, *azel, *xp, *Pp, dr[3] = {0}, std[3]; + char str[40]; + int i, j, nv, info, svh[MAXOBS], exc[MAXOBS] = {0}, stat = SOLQ_SINGLE; + + time2str(obs[0].time, str, 2); + trace(3, "pppos : time=%s nx=%d n=%d\n", str, rtk->nx, n); + + rs = mat(6, n); + dts = mat(2, n); + var = mat(1, n); + azel = zeros(2, n); + + for (i = 0; i < MAXSAT; i++) + for (j = 0; j < opt->nf; j++) rtk->ssat[i].fix[j] = 0; + for (i = 0; i < n && i < MAXOBS; i++) + for (j = 0; j < opt->nf; j++) { + rtk->ssat[obs[i].sat - 1].snr_rover[j] = obs[i].SNR[j]; + rtk->ssat[obs[i].sat - 1].snr_base[j] = 0; + } + + /* temporal update of ekf states */ + udstate_ppp(rtk, obs, n, nav); + + /* satellite positions and clocks */ + satposs(obs[0].time, obs, n, nav, rtk->opt.sateph, rs, dts, var, svh); + + /* exclude measurements of eclipsing satellite (block IIA) */ + if (rtk->opt.posopt[3]) { + testeclipse(obs, n, nav, rs); + } + /* earth tides correction */ + if (opt->tidecorr) { + tidedisp(gpst2utc(obs[0].time), rtk->x, opt->tidecorr, &nav->erp, opt->odisp[0], dr); + } + nv = n * rtk->opt.nf * 2 + MAXSAT + 3; + xp = mat(rtk->nx, 1); + Pp = zeros(rtk->nx, rtk->nx); + v = mat(nv, 1); + H = mat(rtk->nx, nv); + R = mat(nv, nv); + + for (i = 0; i < MAX_ITER; i++) { + matcpy(xp, rtk->x, rtk->nx, 1); + matcpy(Pp, rtk->P, rtk->nx, rtk->nx); + + /* prefit residuals */ + if (!(nv = ppp_res(0, obs, n, rs, dts, var, svh, dr, exc, nav, xp, rtk, v, H, R, azel))) { + trace(2, "%s ppp (%d) no valid obs data\n", str, i + 1); + break; + } + /* measurement update of ekf states */ + if ((info = filter(xp, Pp, H, v, R, rtk->nx, nv))) { + trace(2, "%s ppp (%d) filter error info=%d\n", str, i + 1, info); + break; + } + /* postfit residuals */ + if (ppp_res(i + 1, obs, n, rs, dts, var, svh, dr, exc, nav, xp, rtk, NULL, NULL, NULL, azel)) { + matcpy(rtk->x, xp, rtk->nx, 1); + matcpy(rtk->P, Pp, rtk->nx, rtk->nx); + stat = SOLQ_PPP; + break; + } + } + if (i >= MAX_ITER) { + trace(2, "%s ppp (%d) iteration overflows\n", str, i); + } + if (stat == SOLQ_PPP) { + if (ppp_ar(rtk, obs, n, exc, nav, azel, xp, Pp) && + ppp_res(9, obs, n, rs, dts, var, svh, dr, exc, nav, xp, rtk, NULL, NULL, NULL, azel)) { + matcpy(rtk->xa, xp, rtk->nx, 1); + matcpy(rtk->Pa, Pp, rtk->nx, rtk->nx); + + for (i = 0; i < 3; i++) std[i] = sqrt(Pp[i + i * rtk->nx]); + if (norm(std, 3) < MAX_STD_FIX) stat = SOLQ_FIX; + } else { + rtk->nfix = 0; + } + /* update solution status */ + update_stat(rtk, obs, n, stat); + + if (stat == SOLQ_FIX && test_hold_amb(rtk)) { + matcpy(rtk->x, xp, rtk->nx, 1); + matcpy(rtk->P, Pp, rtk->nx, rtk->nx); + trace(2, "%s hold ambiguity\n", str); + rtk->nfix = 0; + } + } + free(rs); + free(dts); + free(var); + free(azel); + free(xp); + free(Pp); + free(v); + free(H); + free(R); } diff --git a/src/ppp_ar.c b/src/ppp_ar.c index d3fc46326..42d0aabfd 100644 --- a/src/ppp_ar.c +++ b/src/ppp_ar.c @@ -1,22 +1,28 @@ /*------------------------------------------------------------------------------ -* ppp_ar.c : ppp ambiguity resolution -* -* reference : -* [1] H.Okumura, C-gengo niyoru saishin algorithm jiten (in Japanese), -* Software Technology, 1991 -* -* Copyright (C) 2012-2015 by T.TAKASU, All rights reserved. -* -* version : $Revision:$ $Date:$ -* history : 2013/03/11 1.0 new -* 2016/05/10 1.1 delete codes -*-----------------------------------------------------------------------------*/ + * ppp_ar.c : ppp ambiguity resolution + * + * reference : + * [1] H.Okumura, C-gengo niyoru saishin algorithm jiten (in Japanese), + * Software Technology, 1991 + * + * Copyright (C) 2012-2015 by T.TAKASU, All rights reserved. + * + * version : $Revision:$ $Date:$ + * history : 2013/03/11 1.0 new + * 2016/05/10 1.1 delete codes + *-----------------------------------------------------------------------------*/ #include "rtklib.h" /* ambiguity resolution in ppp -----------------------------------------------*/ -extern int ppp_ar(rtk_t *rtk, const obsd_t *obs, int n, int *exc, - const nav_t *nav, const double *azel, double *x, double *P) -{ - (void)rtk; (void)obs; (void)n; (void)exc; (void)nav; (void)azel; (void)x; (void)P; - return 0; +extern int ppp_ar(rtk_t *rtk, const obsd_t *obs, int n, int *exc, const nav_t *nav, + const double *azel, double *x, double *P) { + (void)rtk; + (void)obs; + (void)n; + (void)exc; + (void)nav; + (void)azel; + (void)x; + (void)P; + return 0; } diff --git a/src/preceph.c b/src/preceph.c index 207983c91..2c5c34634 100644 --- a/src/preceph.c +++ b/src/preceph.c @@ -1,359 +1,346 @@ /*------------------------------------------------------------------------------ -* preceph.c : precise ephemeris and clock functions -* -* Copyright (C) 2007-2020 by T.TAKASU, All rights reserved. -* -* references : -* [1] S.Hilla, The Extended Standard Product 3 Orbit Format (SP3-c), -* 12 February, 2007 -* [2] J.Ray, W.Gurtner, RINEX Extensions to Handle Clock Information, -* 27 August, 1998 -* [3] D.D.McCarthy, IERS Technical Note 21, IERS Conventions 1996, July 1996 -* [4] D.A.Vallado, Fundamentals of Astrodynamics and Applications 2nd ed, -* Space Technology Library, 2004 -* [5] S.Hilla, The Extended Standard Product 3 Orbit Format (SP3-d), -* February 21, 2016 -* -* version : $Revision: 1.1 $ $Date: 2008/07/17 21:48:06 $ -* history : 2009/01/18 1.0 new -* 2009/01/31 1.1 fix bug on numerical error to read sp3a ephemeris -* 2009/05/15 1.2 support glonass,galileo,qzs -* 2009/12/11 1.3 support wild-card expansion of file path -* 2010/07/21 1.4 added api: -* eci2ecef(),sunmoonpos(),peph2pos(),satantoff(), -* readdcb() -* changed api: -* readsp3() -* deleted api: -* eph2posp() -* 2010/09/09 1.5 fix problem when precise clock outage -* 2011/01/23 1.6 support qzss satellite code -* 2011/09/12 1.7 fix problem on precise clock outage -* move sunmmonpos() to rtkcmn.c -* 2011/12/01 1.8 modify api readsp3() -* precede later ephemeris if ephemeris is NULL -* move eci2ecef() to rtkcmn.c -* 2013/05/08 1.9 fix bug on computing std-dev of precise clocks -* 2013/11/20 1.10 modify option for api readsp3() -* 2014/04/03 1.11 accept extension including sp3,eph,SP3,EPH -* 2014/05/23 1.12 add function to read sp3 velocity records -* change api: satantoff() -* 2014/08/31 1.13 add member cov and vco in peph_t sturct -* 2014/10/13 1.14 fix bug on clock error variance in peph2pos() -* 2015/05/10 1.15 add api readfcb() -* modify api readdcb() -* 2017/04/11 1.16 fix bug on antenna offset correction in peph2pos() -* 2020/11/30 1.17 support SP3-d [5] to accept more than 85 satellites -* support NavIC/IRNSS in API peph2pos() -* LC defined GPS/QZS L1-L2, GLO G1-G2, GAL E1-E5b, -* BDS B1I-B2I and IRN L5-S for API satantoff() -* fix bug on reading SP3 file extension -*-----------------------------------------------------------------------------*/ + * preceph.c : precise ephemeris and clock functions + * + * Copyright (C) 2007-2020 by T.TAKASU, All rights reserved. + * + * references : + * [1] S.Hilla, The Extended Standard Product 3 Orbit Format (SP3-c), + * 12 February, 2007 + * [2] J.Ray, W.Gurtner, RINEX Extensions to Handle Clock Information, + * 27 August, 1998 + * [3] D.D.McCarthy, IERS Technical Note 21, IERS Conventions 1996, July 1996 + * [4] D.A.Vallado, Fundamentals of Astrodynamics and Applications 2nd ed, + * Space Technology Library, 2004 + * [5] S.Hilla, The Extended Standard Product 3 Orbit Format (SP3-d), + * February 21, 2016 + * + * version : $Revision: 1.1 $ $Date: 2008/07/17 21:48:06 $ + * history : 2009/01/18 1.0 new + * 2009/01/31 1.1 fix bug on numerical error to read sp3a ephemeris + * 2009/05/15 1.2 support glonass,galileo,qzs + * 2009/12/11 1.3 support wild-card expansion of file path + * 2010/07/21 1.4 added api: + * eci2ecef(),sunmoonpos(),peph2pos(),satantoff(), + * readdcb() + * changed api: + * readsp3() + * deleted api: + * eph2posp() + * 2010/09/09 1.5 fix problem when precise clock outage + * 2011/01/23 1.6 support qzss satellite code + * 2011/09/12 1.7 fix problem on precise clock outage + * move sunmmonpos() to rtkcmn.c + * 2011/12/01 1.8 modify api readsp3() + * precede later ephemeris if ephemeris is NULL + * move eci2ecef() to rtkcmn.c + * 2013/05/08 1.9 fix bug on computing std-dev of precise clocks + * 2013/11/20 1.10 modify option for api readsp3() + * 2014/04/03 1.11 accept extension including sp3,eph,SP3,EPH + * 2014/05/23 1.12 add function to read sp3 velocity records + * change api: satantoff() + * 2014/08/31 1.13 add member cov and vco in peph_t sturct + * 2014/10/13 1.14 fix bug on clock error variance in peph2pos() + * 2015/05/10 1.15 add api readfcb() + * modify api readdcb() + * 2017/04/11 1.16 fix bug on antenna offset correction in peph2pos() + * 2020/11/30 1.17 support SP3-d [5] to accept more than 85 satellites + * support NavIC/IRNSS in API peph2pos() + * LC defined GPS/QZS L1-L2, GLO G1-G2, GAL E1-E5b, + * BDS B1I-B2I and IRN L5-S for API satantoff() + * fix bug on reading SP3 file extension + *-----------------------------------------------------------------------------*/ #include "rtklib.h" -#define SQR(x) ((x)*(x)) +#define SQR(x) ((x) * (x)) -#define NMAX 10 /* order of polynomial interpolation */ -#define MAXDTE 900.0 /* max time difference to ephem time (s) */ -#define EXTERR_CLK 1E-3 /* extrapolation error for clock (m/s) */ -#define EXTERR_EPH 5E-7 /* extrapolation error for ephem (m/s^2) */ -#define MAX_BIAS_SYS 4 /* # of constellations supported */ +#define NMAX 10 /* order of polynomial interpolation */ +#define MAXDTE 900.0 /* max time difference to ephem time (s) */ +#define EXTERR_CLK 1E-3 /* extrapolation error for clock (m/s) */ +#define EXTERR_EPH 5E-7 /* extrapolation error for ephem (m/s^2) */ +#define MAX_BIAS_SYS 4 /* # of constellations supported */ /* table to translate code to code bias table index */ static int8_t code_bias_ix[MAX_BIAS_SYS][MAXCODE]; /* initialize code bias lookup table ------------------------------------------- -* -1 = code not supported -* 0 = reference code (0 bias) -* 1-3 = table index for code -* ----------------------------------------------------------------------------*/ + * -1 = code not supported + * 0 = reference code (0 bias) + * 1-3 = table index for code + * ----------------------------------------------------------------------------*/ static void init_bias_ix(void) { - int i,j; - - for (i=0;i85) nl=ns/17+(ns%17!=0); - } - for (j=0;j<17&&k 85) nl = ns / 17 + (ns % 17 != 0); + } + for (j = 0; j < 17 && k < ns; j++) { + sys = code2sys(buff[9 + 3 * j]); + prn = (int)str2num(buff, 10 + 3 * j, 2); + if (k < MAXSAT) sats[k++] = satno(sys, prn); + } + } else if (i == 2 * nl + 2) { /* %c */ + memcpy(tsys, buff + 9, 3); + tsys[3] = '\0'; + } else if (i == 2 * nl + 4) { /* %f */ + bfact[0] = str2num(buff, 3, 10); + bfact[1] = str2num(buff, 14, 12); + } else if (i == 2 * nl + 11) { + break; /* at end of header */ + } + i = i + 1; /* line counter */ + } + return ns; } /* add precise ephemeris -----------------------------------------------------*/ -static int addpeph(nav_t *nav, peph_t *peph) -{ - peph_t *nav_peph; - - if (nav->ne>=nav->nemax) { - nav->nemax+=256; - if (!(nav_peph=(peph_t *)realloc(nav->peph,sizeof(peph_t)*nav->nemax))) { - trace(1,"readsp3b malloc error n=%d\n",nav->nemax); - free(nav->peph); nav->peph=NULL; nav->ne=nav->nemax=0; - return 0; - } - nav->peph=nav_peph; - } - nav->peph[nav->ne++]=*peph; - return 1; +static int addpeph(nav_t *nav, peph_t *peph) { + peph_t *nav_peph; + + if (nav->ne >= nav->nemax) { + nav->nemax += 256; + if (!(nav_peph = (peph_t *)realloc(nav->peph, sizeof(peph_t) * nav->nemax))) { + trace(1, "readsp3b malloc error n=%d\n", nav->nemax); + free(nav->peph); + nav->peph = NULL; + nav->ne = nav->nemax = 0; + return 0; + } + nav->peph = nav_peph; + } + nav->peph[nav->ne++] = *peph; + return 1; } /* read SP3 body -------------------------------------------------------------*/ -static void readsp3b(FILE *fp, char type, int *sats, int ns, double *bfact, - char *tsys, int index, int opt, nav_t *nav) -{ - (void)sats; - peph_t peph; - gtime_t time; - double val,std,base; - int i,j,sat,sys,prn,n=ns*(type=='P'?1:2),pred_o,pred_c,v; - char buff[1024]; - - trace(3,"readsp3b: type=%c ns=%d index=%d opt=%d\n",type,ns,index,opt); - - while (fgets(buff,sizeof(buff),fp)) { - - if (!strncmp(buff,"EOF",3)) break; - - if (buff[0]!='*'||str2time(buff,3,28,&time)) { - trace(2,"sp3 invalid epoch %31.31s\n",buff); - continue; - } - if (!strcmp(tsys,"UTC")) time=utc2gpst(time); /* utc->gpst */ - peph.time =time; - peph.index=index; - - for (i=0;i=76&&buff[75]=='P'; - pred_o=strlen(buff)>=80&&buff[79]=='P'; - } - for (j=0;j<4;j++) { - - /* read option for predicted value */ - if (j< 3&&(opt&1)&& pred_o) continue; - if (j< 3&&(opt&2)&&!pred_o) continue; - if (j==3&&(opt&1)&& pred_c) continue; - if (j==3&&(opt&2)&&!pred_c) continue; - - val=str2num(buff, 4+j*14,14); - std=str2num(buff,61+j* 3,j<3?2:3); - - if (buff[0]=='P') { /* position */ - if (val!=0.0&&fabs(val-999999.999999)>=1E-6) { - peph.pos[sat-1][j]=val*(j<3?1000.0:1E-6); - v=1; /* valid epoch */ - } - if ((base=bfact[j<3?0:1])>0.0&&std>0.0) { - peph.std[sat-1][j]=(float)(pow(base,std)*(j<3?1E-3:1E-12)); - } - } - else if (v) { /* velocity */ - if (val!=0.0&&fabs(val-999999.999999)>=1E-6) { - peph.vel[sat-1][j]=val*(j<3?0.1:1E-10); - } - if ((base=bfact[j<3?0:1])>0.0&&std>0.0) { - peph.vst[sat-1][j]=(float)(pow(base,std)*(j<3?1E-7:1E-16)); - } - } - } - } - if (v) { - if (!addpeph(nav,&peph)) return; +static void readsp3b(FILE *fp, char type, int *sats, int ns, double *bfact, char *tsys, int index, + int opt, nav_t *nav) { + (void)sats; + peph_t peph; + gtime_t time; + double val, std, base; + int i, j, sat, sys, prn, n = ns * (type == 'P' ? 1 : 2), pred_o, pred_c, v; + char buff[1024]; + + trace(3, "readsp3b: type=%c ns=%d index=%d opt=%d\n", type, ns, index, opt); + + while (fgets(buff, sizeof(buff), fp)) { + if (!strncmp(buff, "EOF", 3)) break; + + if (buff[0] != '*' || str2time(buff, 3, 28, &time)) { + trace(2, "sp3 invalid epoch %31.31s\n", buff); + continue; + } + if (!strcmp(tsys, "UTC")) time = utc2gpst(time); /* utc->gpst */ + peph.time = time; + peph.index = index; + + for (i = 0; i < MAXSAT; i++) { + for (j = 0; j < 4; j++) { + peph.pos[i][j] = 0.0; + peph.std[i][j] = 0.0f; + peph.vel[i][j] = 0.0; + peph.vst[i][j] = 0.0f; + } + for (j = 0; j < 3; j++) { + peph.cov[i][j] = 0.0f; + peph.vco[i][j] = 0.0f; + } + } + for (i = pred_o = pred_c = v = 0; i < n && fgets(buff, sizeof(buff), fp); i++) { + if (strlen(buff) < 4 || (buff[0] != 'P' && buff[0] != 'V')) continue; + + sys = buff[1] == ' ' ? SYS_GPS : code2sys(buff[1]); + prn = (int)str2num(buff, 2, 2); + if (sys == SYS_SBS) + prn += 100; + else if (sys == SYS_QZS) + prn += 192; /* extension to sp3-c */ + + if (!(sat = satno(sys, prn))) continue; + + if (buff[0] == 'P') { + pred_c = strlen(buff) >= 76 && buff[75] == 'P'; + pred_o = strlen(buff) >= 80 && buff[79] == 'P'; + } + for (j = 0; j < 4; j++) { + /* read option for predicted value */ + if (j < 3 && (opt & 1) && pred_o) continue; + if (j < 3 && (opt & 2) && !pred_o) continue; + if (j == 3 && (opt & 1) && pred_c) continue; + if (j == 3 && (opt & 2) && !pred_c) continue; + + val = str2num(buff, 4 + j * 14, 14); + std = str2num(buff, 61 + j * 3, j < 3 ? 2 : 3); + + if (buff[0] == 'P') { /* position */ + if (val != 0.0 && fabs(val - 999999.999999) >= 1E-6) { + peph.pos[sat - 1][j] = val * (j < 3 ? 1000.0 : 1E-6); + v = 1; /* valid epoch */ + } + if ((base = bfact[j < 3 ? 0 : 1]) > 0.0 && std > 0.0) { + peph.std[sat - 1][j] = (float)(pow(base, std) * (j < 3 ? 1E-3 : 1E-12)); + } + } else if (v) { /* velocity */ + if (val != 0.0 && fabs(val - 999999.999999) >= 1E-6) { + peph.vel[sat - 1][j] = val * (j < 3 ? 0.1 : 1E-10); + } + if ((base = bfact[j < 3 ? 0 : 1]) > 0.0 && std > 0.0) { + peph.vst[sat - 1][j] = (float)(pow(base, std) * (j < 3 ? 1E-7 : 1E-16)); + } } + } + } + if (v) { + if (!addpeph(nav, &peph)) return; } + } } /* compare precise ephemeris -------------------------------------------------*/ -static int cmppeph(const void *p1, const void *p2) -{ - peph_t *q1=(peph_t *)p1,*q2=(peph_t *)p2; - double tt=timediff(q1->time,q2->time); - return tt<-1E-9?-1:(tt>1E-9?1:q1->index-q2->index); +static int cmppeph(const void *p1, const void *p2) { + peph_t *q1 = (peph_t *)p1, *q2 = (peph_t *)p2; + double tt = timediff(q1->time, q2->time); + return tt < -1E-9 ? -1 : (tt > 1E-9 ? 1 : q1->index - q2->index); } /* combine precise ephemeris -------------------------------------------------*/ -static void combpeph(nav_t *nav, int opt) -{ - int i,j,k,m; - - trace(3,"combpeph: ne=%d\n",nav->ne); - - qsort(nav->peph,nav->ne,sizeof(peph_t),cmppeph); - - if (opt&4) return; - - for (i=0,j=1;jne;j++) { - - if (fabs(timediff(nav->peph[i].time,nav->peph[j].time))<1E-9) { - - for (k=0;kpeph[j].pos[k],4)<=0.0) continue; - for (m=0;m<4;m++) nav->peph[i].pos[k][m]=nav->peph[j].pos[k][m]; - for (m=0;m<4;m++) nav->peph[i].std[k][m]=nav->peph[j].std[k][m]; - for (m=0;m<4;m++) nav->peph[i].vel[k][m]=nav->peph[j].vel[k][m]; - for (m=0;m<4;m++) nav->peph[i].vst[k][m]=nav->peph[j].vst[k][m]; - } - } - else if (++ipeph[i]=nav->peph[j]; - } - nav->ne=i+1; +static void combpeph(nav_t *nav, int opt) { + int i, j, k, m; + + trace(3, "combpeph: ne=%d\n", nav->ne); + + qsort(nav->peph, nav->ne, sizeof(peph_t), cmppeph); + + if (opt & 4) return; + + for (i = 0, j = 1; j < nav->ne; j++) { + if (fabs(timediff(nav->peph[i].time, nav->peph[j].time)) < 1E-9) { + for (k = 0; k < MAXSAT; k++) { + if (norm(nav->peph[j].pos[k], 4) <= 0.0) continue; + for (m = 0; m < 4; m++) nav->peph[i].pos[k][m] = nav->peph[j].pos[k][m]; + for (m = 0; m < 4; m++) nav->peph[i].std[k][m] = nav->peph[j].std[k][m]; + for (m = 0; m < 4; m++) nav->peph[i].vel[k][m] = nav->peph[j].vel[k][m]; + for (m = 0; m < 4; m++) nav->peph[i].vst[k][m] = nav->peph[j].vst[k][m]; + } + } else if (++i < j) + nav->peph[i] = nav->peph[j]; + } + nav->ne = i + 1; - trace(4,"combpeph: ne=%d\n",nav->ne); + trace(4, "combpeph: ne=%d\n", nav->ne); } /* read sp3 precise ephemeris file --------------------------------------------- -* read sp3 precise ephemeris/clock files and set them to navigation data -* args : char *file I sp3-c precise ephemeris file -* (wild-card * is expanded) -* nav_t *nav IO navigation data -* int opt I options (1: only observed + 2: only predicted + -* 4: not combined) -* return : none -* notes : see ref [1] -* precise ephemeris is appended and combined -* nav->peph and nav->ne must by properly initialized before calling the -* function -* only files with extensions of .sp3, .SP3, .eph* and .EPH* are read -*-----------------------------------------------------------------------------*/ -extern void readsp3(const char *file, nav_t *nav, int opt) -{ - FILE *fp; - gtime_t time={0}; - double bfact[2]={0}; - int i,j,n,ns,sats[MAXSAT]={0}; - char *efiles[MAXEXFILE],*ext,type=' ',tsys[4]=""; - - trace(3,"readpephs: file=%s\n",file); - - for (i=0;i=0;i--) free(efiles[i]); - return; - } + * read sp3 precise ephemeris/clock files and set them to navigation data + * args : char *file I sp3-c precise ephemeris file + * (wild-card * is expanded) + * nav_t *nav IO navigation data + * int opt I options (1: only observed + 2: only predicted + + * 4: not combined) + * return : none + * notes : see ref [1] + * precise ephemeris is appended and combined + * nav->peph and nav->ne must by properly initialized before calling the + * function + * only files with extensions of .sp3, .SP3, .eph* and .EPH* are read + *-----------------------------------------------------------------------------*/ +extern void readsp3(const char *file, nav_t *nav, int opt) { + FILE *fp; + gtime_t time = {0}; + double bfact[2] = {0}; + int i, j, n, ns, sats[MAXSAT] = {0}; + char *efiles[MAXEXFILE], *ext, type = ' ', tsys[4] = ""; + + trace(3, "readpephs: file=%s\n", file); + + for (i = 0; i < MAXEXFILE; i++) { + if (!(efiles[i] = (char *)malloc(1024))) { + for (i--; i >= 0; i--) free(efiles[i]); + return; } - /* expand wild card in file path */ - n=expath(file,efiles,MAXEXFILE); + } + /* expand wild card in file path */ + n = expath(file, efiles, MAXEXFILE); - for (i=j=0;ine>0) combpeph(nav,opt); + /* combine precise ephemeris */ + if (nav->ne > 0) combpeph(nav, opt); } /* read satellite antenna parameters ------------------------------------------- -* read satellite antenna parameters -* args : char *file I antenna parameter file -* gtime_t time I time -* nav_t *nav IO navigation data -* return : status (1:ok,0:error) -* notes : only support antex format for the antenna parameter file -*-----------------------------------------------------------------------------*/ + * read satellite antenna parameters + * args : char *file I antenna parameter file + * gtime_t time I time + * nav_t *nav IO navigation data + * return : status (1:ok,0:error) + * notes : only support antex format for the antenna parameter file + *-----------------------------------------------------------------------------*/ extern int readsap(const char *file, const gtime_t time, nav_t *nav) { char tstr[40]; trace(3, "readsap : file=%s time=%s\n", file, time2str(time, tstr, 0)); @@ -374,132 +361,134 @@ extern int readsap(const char *file, const gtime_t time, nav_t *nav) { return 1; } /* read DCB parameters from DCB file ------------------------------------------- -* - supports satellite and receiver biases -*-----------------------------------------------------------------------------*/ -static int readdcbf(const char *file, nav_t *nav, const sta_t *sta) -{ - FILE *fp; - double cbias; - char buff[256],str1[32],str2[32]=""; - int i,j,sat,type=0; - - trace(3,"readdcbf: file=%s\n",file); - - if (!(fp=fopen(file,"r"))) { - trace(2,"dcb parameters file open error: %s\n",file); - return 0; - } - while (fgets(buff,sizeof(buff),fp)) { - - if (strstr(buff,"DIFFERENTIAL (P1-C1) CODE BIASES")) type=1; - else if (strstr(buff,"DIFFERENTIAL (P2-C2) CODE BIASES")) type=2; - - str2[0]='\0'; - if (!type||sscanf(buff,"%31s %31s",str1,str2)<1) continue; - - if ((cbias=str2num(buff,26,9))==0.0) continue; - - if (sta&&(!strcmp(str1,"G")||!strcmp(str1,"R"))) { /* receiver DCB */ - for (i=0;irbias[i][j][type-1]=cbias*1E-9*CLIGHT; /* ns -> m */ - } - } - else if ((sat=satid2no(str1))) { /* satellite dcb */ - nav->cbias[sat-1][type-1][0]=cbias*1E-9*CLIGHT; /* ns -> m */ - } + * - supports satellite and receiver biases + *-----------------------------------------------------------------------------*/ +static int readdcbf(const char *file, nav_t *nav, const sta_t *sta) { + FILE *fp; + double cbias; + char buff[256], str1[32], str2[32] = ""; + int i, j, sat, type = 0; + + trace(3, "readdcbf: file=%s\n", file); + + if (!(fp = fopen(file, "r"))) { + trace(2, "dcb parameters file open error: %s\n", file); + return 0; + } + while (fgets(buff, sizeof(buff), fp)) { + if (strstr(buff, "DIFFERENTIAL (P1-C1) CODE BIASES")) + type = 1; + else if (strstr(buff, "DIFFERENTIAL (P2-C2) CODE BIASES")) + type = 2; + + str2[0] = '\0'; + if (!type || sscanf(buff, "%31s %31s", str1, str2) < 1) continue; + + if ((cbias = str2num(buff, 26, 9)) == 0.0) continue; + + if (sta && (!strcmp(str1, "G") || !strcmp(str1, "R"))) { /* receiver DCB */ + for (i = 0; i < MAXRCV; i++) { + if (!strcmp(sta[i].name, str2)) break; + } + if (i < MAXRCV) { + j = !strcmp(str1, "G") ? 0 : 1; + nav->rbias[i][j][type - 1] = cbias * 1E-9 * CLIGHT; /* ns -> m */ + } + } else if ((sat = satid2no(str1))) { /* satellite dcb */ + nav->cbias[sat - 1][type - 1][0] = cbias * 1E-9 * CLIGHT; /* ns -> m */ } - fclose(fp); + } + fclose(fp); - return 1; + return 1; } /* satellite system to index */ -static int sys2ix(int sys) -{ - switch (sys) { - case SYS_GPS: return 0; - case SYS_SBS: return 0; - case SYS_GLO: return 1; - case SYS_GAL: return 2; - case SYS_CMP: return 3; - case SYS_QZS: return 4; - case SYS_IRN: return 5; - } - return 0; +static int sys2ix(int sys) { + switch (sys) { + case SYS_GPS: + return 0; + case SYS_SBS: + return 0; + case SYS_GLO: + return 1; + case SYS_GAL: + return 2; + case SYS_CMP: + return 3; + case SYS_QZS: + return 4; + case SYS_IRN: + return 5; + } + return 0; } /* translate satellite system and code to code bias table index ---------------- -* -1 = code not supported -* 0 = reference code (0 bias) -* 1-3 = table index for code -* ----------------------------------------------------------------------------*/ + * -1 = code not supported + * 0 = reference code (0 bias) + * 1-3 = table index for code + * ----------------------------------------------------------------------------*/ extern int code2bias_ix(int sys, int code) { - int sys_ix; + int sys_ix; - sys_ix=sys2ix(sys); - if (sys_ixcbias[sat-1][freq][i]+=cbias*1E-9*CLIGHT; /* ns -> m */ - } else { - nav->cbias[sat-1][freq][bias_ix1-1]-=cbias*1E-9*CLIGHT; /* ns -> m */ - } - } - else if (strcmp(bias,"DSB")==0) { - /* differential signal bias */ - if (obs1[1]!=obs2[1]) continue; /* skip biases between freqs for now */ - if (!(code2=obs2code(&obs2[1]))) continue; /* skip if code not valid */ - bias_ix2=code2bias_ix(sys,code2); - if (bias_ix1==0) /* this is ref code */ - nav->cbias[sat-1][freq][bias_ix2-1]=cbias*1E-9*CLIGHT; /* ns -> m */ - else if (bias_ix2==0) /* this is ref code */ - nav->cbias[sat-1][freq][bias_ix1-1]=-cbias*1E-9*CLIGHT; /* ns -> m */ - } - + * - supports satellite code biases only + *-----------------------------------------------------------------------------*/ +static int readbiaf(const char *file, nav_t *nav) { + FILE *fp; + double cbias; + char buff[256], bias[6] = "", svn[6] = "", prn[6] = "", obs1[6] = "", obs2[6]; + int i, sat, freq, code1, code2, bias_ix1, bias_ix2, sys; + + trace(3, "readbiaf: file=%s\n", file); + + if (!(fp = fopen(file, "r"))) { + trace(2, "dcb parameters file open error: %s\n", file); + return 0; + } + while (fgets(buff, sizeof(buff), fp)) { + if (sscanf(buff, "%4s %5s %4s %4s %4s", bias, svn, prn, obs1, obs2) < 5) continue; + if (obs1[0] != 'C') continue; /* skip phase biases for now */ + if ((cbias = str2num(buff, 70, 21)) == 0.0) continue; + sat = satid2no(prn); + sys = satsys(sat, NULL); + /* other code biases are L1/L2, Galileo is L1/L5 */ + if (obs1[1] == '1') + freq = 0; + else if ((sys != SYS_GAL && obs1[1] == '2') || (sys == SYS_GAL && obs1[1] == '5')) + freq = 1; + else + continue; + + if (!(code1 = obs2code(&obs1[1]))) continue; /* skip if code not valid */ + bias_ix1 = code2bias_ix(sys, code1); + if (strcmp(bias, "OSB") == 0) { + /* observed signal bias */ + if (bias_ix1 == 0) { /* this is ref code */ + for (i = 0; i < MAX_CODE_BIASES; i++) /* adjust all other codes by ref code bias */ + nav->cbias[sat - 1][freq][i] += cbias * 1E-9 * CLIGHT; /* ns -> m */ + } else { + nav->cbias[sat - 1][freq][bias_ix1 - 1] -= cbias * 1E-9 * CLIGHT; /* ns -> m */ + } + } else if (strcmp(bias, "DSB") == 0) { + /* differential signal bias */ + if (obs1[1] != obs2[1]) continue; /* skip biases between freqs for now */ + if (!(code2 = obs2code(&obs2[1]))) continue; /* skip if code not valid */ + bias_ix2 = code2bias_ix(sys, code2); + if (bias_ix1 == 0) /* this is ref code */ + nav->cbias[sat - 1][freq][bias_ix2 - 1] = cbias * 1E-9 * CLIGHT; /* ns -> m */ + else if (bias_ix2 == 0) /* this is ref code */ + nav->cbias[sat - 1][freq][bias_ix1 - 1] = -cbias * 1E-9 * CLIGHT; /* ns -> m */ } - fclose(fp); + } + fclose(fp); - return 1; + return 1; } /* read DCB parameters --------------------------------------------------------- * read differential code bias (DCB) parameters @@ -512,313 +501,305 @@ static int readbiaf(const char *file, nav_t *nav) : currently only support P1-P2, P1-C1 bias in DCB file : currently only supports satellite biases in BIA/BSX files *-----------------------------------------------------------------------------*/ -extern int readdcb(const char *file, nav_t *nav, const sta_t *sta) -{ - int i,j,k,n,dcb_ok=0; - char *efiles[MAXEXFILE]={0}; +extern int readdcb(const char *file, nav_t *nav, const sta_t *sta) { + int i, j, k, n, dcb_ok = 0; + char *efiles[MAXEXFILE] = {0}; - trace(3,"readdcb : file=%s\n",file); + trace(3, "readdcb : file=%s\n", file); - init_bias_ix(); /* init translation table from code to table column */ + init_bias_ix(); /* init translation table from code to table column */ - for (i=0;icbias[i][j][k]=0.0; - } - for (i=0;i=0;i--) free(efiles[i]); - return 0; - } - } - n=expath(file,efiles,MAXEXFILE); - - for (i=0;icbias[i][j][k] = 0.0; + } + for (i = 0; i < MAXEXFILE; i++) { + if (!(efiles[i] = (char *)malloc(1024))) { + for (i--; i >= 0; i--) free(efiles[i]); + return 0; } - for (i=0;inepeph[0].time)<-MAXDTE|| - timediff(time,nav->peph[nav->ne-1].time)>MAXDTE) { - trace(3,"no prec ephem %s sat=%2d\n",time2str(time,tstr,0),sat); - return 0; - } - /* binary search */ - for (i=0,j=nav->ne-1;ipeph[k].time,time)<0.0) i=k+1; else j=k; - } - index=i<=0?0:i-1; +static int pephpos(gtime_t time, int sat, const nav_t *nav, double *rs, double *dts, double *vare, + double *varc) { + double t[NMAX + 1], p[3][NMAX + 1], c[2], *pos, std = 0.0, s[3], sinl, cosl; + int i, j, k, index; - /* polynomial interpolation for orbit */ - i=index-(NMAX+1)/2; - if (i<0) i=0; else if (i+NMAX>=nav->ne) i=nav->ne-NMAX-1; + char tstr[40]; + trace(4, "pephpos : time=%s sat=%2d\n", time2str(time, tstr, 3), sat); - for (j=0;j<=NMAX;j++) { - t[j]=timediff(nav->peph[i+j].time,time); - if (norm(nav->peph[i+j].pos[sat-1],3)<=0.0) { - trace(3,"prec ephem outage %s sat=%2d\n",time2str(time,tstr,0),sat); - return 0; - } - } - for (j=0;j<=NMAX;j++) { - pos=nav->peph[i+j].pos[sat-1]; - /* correction for earth rotation ver.2.4.0 */ - sinl=sin(OMGE*t[j]); - cosl=cos(OMGE*t[j]); - p[0][j]=cosl*pos[0]-sinl*pos[1]; - p[1][j]=sinl*pos[0]+cosl*pos[1]; - p[2][j]=pos[2]; - } - for (i=0;i<3;i++) { - rs[i]=interppol(t,p[i],NMAX+1); - } - if (vare) { - for (i=0;i<3;i++) s[i]=nav->peph[index].std[sat-1][i]; - std=norm(s,3); - - /* extrapolation error for orbit */ - if (t[0 ]>0.0) std+=EXTERR_EPH*SQR(t[0 ])/2.0; - else if (t[NMAX]<0.0) std+=EXTERR_EPH*SQR(t[NMAX])/2.0; - *vare=SQR(std); - } - /* linear interpolation for clock */ - t[0]=timediff(time,nav->peph[index ].time); - t[1]=timediff(time,nav->peph[index+1].time); - c[0]=nav->peph[index ].pos[sat-1][3]; - c[1]=nav->peph[index+1].pos[sat-1][3]; - - if (t[0]<=0.0) { - if ((dts[0]=c[0])!=0.0) { - std=nav->peph[index].std[sat-1][3]*CLIGHT-EXTERR_CLK*t[0]; - } - } - else if (t[1]>=0.0) { - if ((dts[0]=c[1])!=0.0) { - std=nav->peph[index+1].std[sat-1][3]*CLIGHT+EXTERR_CLK*t[1]; - } - } - else if (c[0]!=0.0&&c[1]!=0.0) { - dts[0]=(c[1]*t[0]-c[0]*t[1])/(t[0]-t[1]); - i=t[0]<-t[1]?0:1; - std=nav->peph[index+i].std[sat-1][3]+EXTERR_CLK*fabs(t[i]); - } - else { - dts[0]=0.0; + rs[0] = rs[1] = rs[2] = dts[0] = 0.0; + + if (nav->ne < NMAX + 1 || timediff(time, nav->peph[0].time) < -MAXDTE || + timediff(time, nav->peph[nav->ne - 1].time) > MAXDTE) { + trace(3, "no prec ephem %s sat=%2d\n", time2str(time, tstr, 0), sat); + return 0; + } + /* binary search */ + for (i = 0, j = nav->ne - 1; i < j;) { + k = (i + j) / 2; + if (timediff(nav->peph[k].time, time) < 0.0) + i = k + 1; + else + j = k; + } + index = i <= 0 ? 0 : i - 1; + + /* polynomial interpolation for orbit */ + i = index - (NMAX + 1) / 2; + if (i < 0) + i = 0; + else if (i + NMAX >= nav->ne) + i = nav->ne - NMAX - 1; + + for (j = 0; j <= NMAX; j++) { + t[j] = timediff(nav->peph[i + j].time, time); + if (norm(nav->peph[i + j].pos[sat - 1], 3) <= 0.0) { + trace(3, "prec ephem outage %s sat=%2d\n", time2str(time, tstr, 0), sat); + return 0; } - if (varc) *varc=SQR(std); - return 1; + } + for (j = 0; j <= NMAX; j++) { + pos = nav->peph[i + j].pos[sat - 1]; + /* correction for earth rotation ver.2.4.0 */ + sinl = sin(OMGE * t[j]); + cosl = cos(OMGE * t[j]); + p[0][j] = cosl * pos[0] - sinl * pos[1]; + p[1][j] = sinl * pos[0] + cosl * pos[1]; + p[2][j] = pos[2]; + } + for (i = 0; i < 3; i++) { + rs[i] = interppol(t, p[i], NMAX + 1); + } + if (vare) { + for (i = 0; i < 3; i++) s[i] = nav->peph[index].std[sat - 1][i]; + std = norm(s, 3); + + /* extrapolation error for orbit */ + if (t[0] > 0.0) + std += EXTERR_EPH * SQR(t[0]) / 2.0; + else if (t[NMAX] < 0.0) + std += EXTERR_EPH * SQR(t[NMAX]) / 2.0; + *vare = SQR(std); + } + /* linear interpolation for clock */ + t[0] = timediff(time, nav->peph[index].time); + t[1] = timediff(time, nav->peph[index + 1].time); + c[0] = nav->peph[index].pos[sat - 1][3]; + c[1] = nav->peph[index + 1].pos[sat - 1][3]; + + if (t[0] <= 0.0) { + if ((dts[0] = c[0]) != 0.0) { + std = nav->peph[index].std[sat - 1][3] * CLIGHT - EXTERR_CLK * t[0]; + } + } else if (t[1] >= 0.0) { + if ((dts[0] = c[1]) != 0.0) { + std = nav->peph[index + 1].std[sat - 1][3] * CLIGHT + EXTERR_CLK * t[1]; + } + } else if (c[0] != 0.0 && c[1] != 0.0) { + dts[0] = (c[1] * t[0] - c[0] * t[1]) / (t[0] - t[1]); + i = t[0] < -t[1] ? 0 : 1; + std = nav->peph[index + i].std[sat - 1][3] + EXTERR_CLK * fabs(t[i]); + } else { + dts[0] = 0.0; + } + if (varc) *varc = SQR(std); + return 1; } /* satellite clock by precise clock ------------------------------------------*/ -static int pephclk(gtime_t time, int sat, const nav_t *nav, double *dts, - double *varc) -{ - double t[2],c[2],std; - int i,j,k,index; - - char tstr[40]; - trace(4,"pephclk : time=%s sat=%2d\n",time2str(time,tstr,3),sat); - - if (nav->nc<2|| - timediff(time,nav->pclk[0].time)<-MAXDTE|| - timediff(time,nav->pclk[nav->nc-1].time)>MAXDTE) { - trace(3,"no prec clock %s sat=%2d\n",time2str(time,tstr,0),sat); - return 1; - } - /* binary search */ - for (i=0,j=nav->nc-1;ipclk[k].time,time)<0.0) i=k+1; else j=k; - } - index=i<=0?0:i-1; +static int pephclk(gtime_t time, int sat, const nav_t *nav, double *dts, double *varc) { + double t[2], c[2], std; + int i, j, k, index; - /* linear interpolation for clock */ - t[0]=timediff(time,nav->pclk[index ].time); - t[1]=timediff(time,nav->pclk[index+1].time); - c[0]=nav->pclk[index ].clk[sat-1][0]; - c[1]=nav->pclk[index+1].clk[sat-1][0]; + char tstr[40]; + trace(4, "pephclk : time=%s sat=%2d\n", time2str(time, tstr, 3), sat); - if (t[0]<=0.0) { - if ((dts[0]=c[0])==0.0) return 0; - std=nav->pclk[index].std[sat-1][0]*CLIGHT-EXTERR_CLK*t[0]; - } - else if (t[1]>=0.0) { - if ((dts[0]=c[1])==0.0) return 0; - std=nav->pclk[index+1].std[sat-1][0]*CLIGHT+EXTERR_CLK*t[1]; - } - else if (c[0]!=0.0&&c[1]!=0.0) { - dts[0]=(c[1]*t[0]-c[0]*t[1])/(t[0]-t[1]); - i=t[0]<-t[1]?0:1; - std=nav->pclk[index+i].std[sat-1][0]*CLIGHT+EXTERR_CLK*fabs(t[i]); - } - else { - trace(3,"prec clock outage %s sat=%2d\n",time2str(time,tstr,0),sat); - return 0; - } - if (varc) *varc=SQR(std); + if (nav->nc < 2 || timediff(time, nav->pclk[0].time) < -MAXDTE || + timediff(time, nav->pclk[nav->nc - 1].time) > MAXDTE) { + trace(3, "no prec clock %s sat=%2d\n", time2str(time, tstr, 0), sat); return 1; + } + /* binary search */ + for (i = 0, j = nav->nc - 1; i < j;) { + k = (i + j) / 2; + if (timediff(nav->pclk[k].time, time) < 0.0) + i = k + 1; + else + j = k; + } + index = i <= 0 ? 0 : i - 1; + + /* linear interpolation for clock */ + t[0] = timediff(time, nav->pclk[index].time); + t[1] = timediff(time, nav->pclk[index + 1].time); + c[0] = nav->pclk[index].clk[sat - 1][0]; + c[1] = nav->pclk[index + 1].clk[sat - 1][0]; + + if (t[0] <= 0.0) { + if ((dts[0] = c[0]) == 0.0) return 0; + std = nav->pclk[index].std[sat - 1][0] * CLIGHT - EXTERR_CLK * t[0]; + } else if (t[1] >= 0.0) { + if ((dts[0] = c[1]) == 0.0) return 0; + std = nav->pclk[index + 1].std[sat - 1][0] * CLIGHT + EXTERR_CLK * t[1]; + } else if (c[0] != 0.0 && c[1] != 0.0) { + dts[0] = (c[1] * t[0] - c[0] * t[1]) / (t[0] - t[1]); + i = t[0] < -t[1] ? 0 : 1; + std = nav->pclk[index + i].std[sat - 1][0] * CLIGHT + EXTERR_CLK * fabs(t[i]); + } else { + trace(3, "prec clock outage %s sat=%2d\n", time2str(time, tstr, 0), sat); + return 0; + } + if (varc) *varc = SQR(std); + return 1; } /* satellite antenna phase center offset --------------------------------------- -* compute satellite antenna phase center offset in ecef -* args : gtime_t time I time (gpst) -* double *rs I satellite position and velocity (ecef) -* {x,y,z,vx,vy,vz} (m|m/s) -* int sat I satellite number -* nav_t *nav I navigation data -* double *dant O satellite antenna phase center offset (ecef) -* {dx,dy,dz} (m) (iono-free LC value) -* return : none -* notes : iono-free LC frequencies defined as follows: -* GPS/QZSS : L1-L2 -* GLONASS : G1-G2 -* Galileo : E1-E5b -* BDS : B1I-B2I -* NavIC : L5-S -*-----------------------------------------------------------------------------*/ -extern void satantoff(gtime_t time, const double *rs, int sat, const nav_t *nav, - double *dant) -{ - const pcv_t *pcv=nav->pcvs+sat-1; - double ex[3],ey[3],ez[3],es[3],r[3],rsun[3],gmst,erpv[5]={0},freq[2]; - double C1,C2,dant1,dant2; - int i,sys; - - char tstr[40]; - trace(4,"satantoff: time=%s sat=%2d\n",time2str(time,tstr,3),sat); - - dant[0]=dant[1]=dant[2]=0.0; - - /* sun position in ecef */ - sunmoonpos(gpst2utc(time),erpv,rsun,NULL,&gmst); - - /* unit vectors of satellite fixed coordinates */ - for (i=0;i<3;i++) r[i]=-rs[i]; - if (!normv3(r,ez)) return; - for (i=0;i<3;i++) r[i]=rsun[i]-rs[i]; - if (!normv3(r,es)) return; - cross3(ez,es,r); - if (!normv3(r,ey)) return; - cross3(ey,ez,ex); - - /* iono-free LC coefficients */ - sys=satsys(sat,NULL); - if (sys==SYS_GPS||sys==SYS_QZS) { /* L1-L2 */ - freq[0]=FREQL1; - freq[1]=FREQL2; - } - else if (sys==SYS_GLO) { /* G1-G2 */ - freq[0]=sat2freq(sat,CODE_L1C,nav); - freq[1]=sat2freq(sat,CODE_L2C,nav); - } - else if (sys==SYS_GAL) { /* E1-E5b */ - freq[0]=FREQL1; - freq[1]=FREQE5b; - } - else if (sys==SYS_CMP) { /* B1I-B2I */ - freq[0]=FREQ1_CMP; - freq[1]=FREQ2_CMP; - } - else if (sys==SYS_IRN) { /* L5-S */ - freq[0]=FREQL5; - freq[1]=FREQs; - } - else return; - - C1= SQR(freq[0])/(SQR(freq[0])-SQR(freq[1])); - C2=-SQR(freq[1])/(SQR(freq[0])-SQR(freq[1])); + * compute satellite antenna phase center offset in ecef + * args : gtime_t time I time (gpst) + * double *rs I satellite position and velocity (ecef) + * {x,y,z,vx,vy,vz} (m|m/s) + * int sat I satellite number + * nav_t *nav I navigation data + * double *dant O satellite antenna phase center offset (ecef) + * {dx,dy,dz} (m) (iono-free LC value) + * return : none + * notes : iono-free LC frequencies defined as follows: + * GPS/QZSS : L1-L2 + * GLONASS : G1-G2 + * Galileo : E1-E5b + * BDS : B1I-B2I + * NavIC : L5-S + *-----------------------------------------------------------------------------*/ +extern void satantoff(gtime_t time, const double *rs, int sat, const nav_t *nav, double *dant) { + const pcv_t *pcv = nav->pcvs + sat - 1; + double ex[3], ey[3], ez[3], es[3], r[3], rsun[3], gmst, erpv[5] = {0}, freq[2]; + double C1, C2, dant1, dant2; + int i, sys; - /* iono-free LC */ - for (i=0;i<3;i++) { - dant1=pcv->off[0][0]*ex[i]+pcv->off[0][1]*ey[i]+pcv->off[0][2]*ez[i]; - dant2=pcv->off[1][0]*ex[i]+pcv->off[1][1]*ey[i]+pcv->off[1][2]*ez[i]; - dant[i]=C1*dant1+C2*dant2; - } + char tstr[40]; + trace(4, "satantoff: time=%s sat=%2d\n", time2str(time, tstr, 3), sat); + + dant[0] = dant[1] = dant[2] = 0.0; + + /* sun position in ecef */ + sunmoonpos(gpst2utc(time), erpv, rsun, NULL, &gmst); + + /* unit vectors of satellite fixed coordinates */ + for (i = 0; i < 3; i++) r[i] = -rs[i]; + if (!normv3(r, ez)) return; + for (i = 0; i < 3; i++) r[i] = rsun[i] - rs[i]; + if (!normv3(r, es)) return; + cross3(ez, es, r); + if (!normv3(r, ey)) return; + cross3(ey, ez, ex); + + /* iono-free LC coefficients */ + sys = satsys(sat, NULL); + if (sys == SYS_GPS || sys == SYS_QZS) { /* L1-L2 */ + freq[0] = FREQL1; + freq[1] = FREQL2; + } else if (sys == SYS_GLO) { /* G1-G2 */ + freq[0] = sat2freq(sat, CODE_L1C, nav); + freq[1] = sat2freq(sat, CODE_L2C, nav); + } else if (sys == SYS_GAL) { /* E1-E5b */ + freq[0] = FREQL1; + freq[1] = FREQE5b; + } else if (sys == SYS_CMP) { /* B1I-B2I */ + freq[0] = FREQ1_CMP; + freq[1] = FREQ2_CMP; + } else if (sys == SYS_IRN) { /* L5-S */ + freq[0] = FREQL5; + freq[1] = FREQs; + } else + return; + + C1 = SQR(freq[0]) / (SQR(freq[0]) - SQR(freq[1])); + C2 = -SQR(freq[1]) / (SQR(freq[0]) - SQR(freq[1])); + + /* iono-free LC */ + for (i = 0; i < 3; i++) { + dant1 = pcv->off[0][0] * ex[i] + pcv->off[0][1] * ey[i] + pcv->off[0][2] * ez[i]; + dant2 = pcv->off[1][0] * ex[i] + pcv->off[1][1] * ey[i] + pcv->off[1][2] * ez[i]; + dant[i] = C1 * dant1 + C2 * dant2; + } } /* satellite position/clock by precise ephemeris/clock ------------------------- -* compute satellite position/clock with precise ephemeris/clock -* args : gtime_t time I time (gpst) -* int sat I satellite number -* nav_t *nav I navigation data -* int opt I sat position option -* (0: center of mass, 1: antenna phase center) -* double *rs O sat position and velocity (ecef) -* {x,y,z,vx,vy,vz} (m|m/s) -* double *dts O sat clock {bias,drift} (s|s/s) -* double *var IO sat position and clock error variance (m) -* (NULL: no output) -* return : status (1:ok,0:error or data outage) -* notes : clock includes relativistic correction but does not contain code bias -* before calling the function, nav->peph, nav->ne, nav->pclk and -* nav->nc must be set by calling readsp3(), readrnx() or readrnxt() -* if precise clocks are not set, clocks in sp3 are used instead -*-----------------------------------------------------------------------------*/ -extern int peph2pos(gtime_t time, int sat, const nav_t *nav, int opt, - double *rs, double *dts, double *var) -{ - gtime_t time_tt; - double rss[3],rst[3],dtss[1],dtst[1],dant[3]={0},vare=0.0,varc=0.0,tt=1E-3; - int i; + * compute satellite position/clock with precise ephemeris/clock + * args : gtime_t time I time (gpst) + * int sat I satellite number + * nav_t *nav I navigation data + * int opt I sat position option + * (0: center of mass, 1: antenna phase center) + * double *rs O sat position and velocity (ecef) + * {x,y,z,vx,vy,vz} (m|m/s) + * double *dts O sat clock {bias,drift} (s|s/s) + * double *var IO sat position and clock error variance (m) + * (NULL: no output) + * return : status (1:ok,0:error or data outage) + * notes : clock includes relativistic correction but does not contain code bias + * before calling the function, nav->peph, nav->ne, nav->pclk and + * nav->nc must be set by calling readsp3(), readrnx() or readrnxt() + * if precise clocks are not set, clocks in sp3 are used instead + *-----------------------------------------------------------------------------*/ +extern int peph2pos(gtime_t time, int sat, const nav_t *nav, int opt, double *rs, double *dts, + double *var) { + gtime_t time_tt; + double rss[3], rst[3], dtss[1], dtst[1], dant[3] = {0}, vare = 0.0, varc = 0.0, tt = 1E-3; + int i; - char tstr[40]; - trace(4,"peph2pos: time=%s sat=%2d opt=%d\n",time2str(time,tstr,3),sat,opt); + char tstr[40]; + trace(4, "peph2pos: time=%s sat=%2d opt=%d\n", time2str(time, tstr, 3), sat, opt); - if (sat<=0||MAXSAT rtk_crc16() -* 2017/04/11 1.6 (char *) -> (signed char *) -* fix bug on unchange-test of beidou ephemeris -* 2018/10/10 1.7 fix problem of sisa handling in galileo ephemeris -* add receiver option -GALINAV, -GALFNAV -* 2018/12/06 1.8 fix bug on decoding galileo ephemeirs iode (0x01-04) -* 2019/05/10 1.9 save galileo E5b data to obs index 2 -* 2019/07/25 1.10 support upgraded galileo ephemeris (0x01-14) -* 2020/11/30 1.11 support NavIC/IRNSS raw obs data (0x7f-05) -* support BDS B2b in raw obs data (0x7f-05) -* support IRNSS decoded ephemeris (0x01-07) -* support station info in site metadata (0x00) -* handle I/NAV and F/NAV seperately for Galileo -* CODE_L1I/L1Q/L1X -> CODE_L2I/L2Q/L2X for BDS B1I -* use API code2idx() to get frequency index -* use API code2idx() to get carrier frequency -* use integer types in stdint.h -*-----------------------------------------------------------------------------*/ + * BINEX.c : BINEX dependent functions + * + * Copyright (C) 2013-2020 by T.TAKASU, All rights reserved. + * + * reference : + * [1] UNAVCO, BINEX: Binary exchange format (updated on July 13, 2018) + * (http://BINEX.unavco.org/BINEX.html) + * + * version : $Revision:$ $Date:$ + * history : 2013/02/20 1.0 new + * 2013/04/15 1.1 support 0x01-05 beidou-2/compass ephemeris + * 2013/05/18 1.2 fix bug on decoding obsflags in message 0x7f-05 + * 2014/04/27 1.3 fix bug on decoding iode for message 0x01-02 + * 2015/12/05 1.4 fix bug on decoding tgd for message 0x01-05 + * 2016/07/29 1.5 crc16() -> rtk_crc16() + * 2017/04/11 1.6 (char *) -> (signed char *) + * fix bug on unchange-test of beidou ephemeris + * 2018/10/10 1.7 fix problem of sisa handling in galileo ephemeris + * add receiver option -GALINAV, -GALFNAV + * 2018/12/06 1.8 fix bug on decoding galileo ephemeirs iode (0x01-04) + * 2019/05/10 1.9 save galileo E5b data to obs index 2 + * 2019/07/25 1.10 support upgraded galileo ephemeris (0x01-14) + * 2020/11/30 1.11 support NavIC/IRNSS raw obs data (0x7f-05) + * support BDS B2b in raw obs data (0x7f-05) + * support IRNSS decoded ephemeris (0x01-07) + * support station info in site metadata (0x00) + * handle I/NAV and F/NAV seperately for Galileo + * CODE_L1I/L1Q/L1X -> CODE_L2I/L2Q/L2X for BDS B1I + * use API code2idx() to get frequency index + * use API code2idx() to get carrier frequency + * use integer types in stdint.h + *-----------------------------------------------------------------------------*/ #include "rtklib.h" -#define BNXSYNC1 0xC2 /* BINEX sync (little-endian,regular-crc) */ -#define BNXSYNC2 0xE2 /* BINEX sync (big-endian ,regular-crc) */ -#define BNXSYNC3 0xC8 /* BINEX sync (little-endian,enhanced-crc) */ -#define BNXSYNC4 0xE8 /* BINEX sync (big-endian ,enhanced-crc) */ +#define BNXSYNC1 0xC2 /* BINEX sync (little-endian,regular-crc) */ +#define BNXSYNC2 0xE2 /* BINEX sync (big-endian ,regular-crc) */ +#define BNXSYNC3 0xC8 /* BINEX sync (little-endian,enhanced-crc) */ +#define BNXSYNC4 0xE8 /* BINEX sync (big-endian ,enhanced-crc) */ -#define BNXSYNC1R 0xD2 /* BINEX sync (little-endian,regular-crc,rev) */ -#define BNXSYNC2R 0xF2 /* BINEX sync (big-endian ,regular-crc,rev) */ -#define BNXSYNC3R 0xD8 /* BINEX sync (little-endian,enhanced-crc,rev) */ -#define BNXSYNC4R 0xF8 /* BINEX sync (big-endian ,enhanced-crc,rev) */ +#define BNXSYNC1R 0xD2 /* BINEX sync (little-endian,regular-crc,rev) */ +#define BNXSYNC2R 0xF2 /* BINEX sync (big-endian ,regular-crc,rev) */ +#define BNXSYNC3R 0xD8 /* BINEX sync (little-endian,enhanced-crc,rev) */ +#define BNXSYNC4R 0xF8 /* BINEX sync (big-endian ,enhanced-crc,rev) */ -#define MIN(x,y) ((x)<(y)?(x):(y)) -#define SQR(x) ((x)*(x)) +#define MIN(x, y) ((x) < (y) ? (x) : (y)) +#define SQR(x) ((x) * (x)) /* URA table (URA index -> URA value) ----------------------------------------*/ -static const double ura_eph[]={ - 2.4,3.4,4.85,6.85,9.65,13.65,24.0,48.0,96.0,192.0,384.0,768.0,1536.0, - 3072.0,6144.0,0.0 -}; +static const double ura_eph[] = {2.4, 3.4, 4.85, 6.85, 9.65, 13.65, 24.0, 48.0, + 96.0, 192.0, 384.0, 768.0, 1536.0, 3072.0, 6144.0, 0.0}; /* get fields (big-endian) ---------------------------------------------------*/ #define U1(p) (*((uint8_t *)(p))) -#define I1(p) (*((int8_t *)(p))) - -static uint16_t U2(uint8_t *p) -{ - uint16_t value; - uint8_t *q=(uint8_t *)&value+1; - int i; - for (i=0;i<2;i++) *q--=*p++; - return value; -} -static uint32_t U4(uint8_t *p) -{ - uint32_t value; - uint8_t *q=(uint8_t *)&value+3; - int i; - for (i=0;i<4;i++) *q--=*p++; - return value; +#define I1(p) (*((int8_t *)(p))) + +static uint16_t U2(uint8_t *p) { + uint16_t value; + uint8_t *q = (uint8_t *)&value + 1; + int i; + for (i = 0; i < 2; i++) *q-- = *p++; + return value; } -static int32_t I4(uint8_t *p) -{ - return (int32_t)U4(p); +static uint32_t U4(uint8_t *p) { + uint32_t value; + uint8_t *q = (uint8_t *)&value + 3; + int i; + for (i = 0; i < 4; i++) *q-- = *p++; + return value; } -static float R4(uint8_t *p) -{ - float value; - uint8_t *q=(uint8_t *)&value+3; - int i; - for (i=0;i<4;i++) *q--=*p++; - return value; +static int32_t I4(uint8_t *p) { return (int32_t)U4(p); } +static float R4(uint8_t *p) { + float value; + uint8_t *q = (uint8_t *)&value + 3; + int i; + for (i = 0; i < 4; i++) *q-- = *p++; + return value; } -static double R8(uint8_t *p) -{ - double value; - uint8_t *q=(uint8_t *)&value+7; - int i; - for (i=0;i<8;i++) *q--=*p++; - return value; +static double R8(uint8_t *p) { + double value; + uint8_t *q = (uint8_t *)&value + 7; + int i; + for (i = 0; i < 8; i++) *q-- = *p++; + return value; } /* get BINEX 1-4 byte unsigned integer (big endian) --------------------------*/ -static int getbnxi(uint8_t *p, uint32_t *val) -{ - int i; - - for (*val=0,i=0;i<3;i++) { - *val=(*val<<7)+(p[i]&0x7F); - if (!(p[i]&0x80)) return i+1; - } - *val=(*val<<8)+p[i]; - return 4; +static int getbnxi(uint8_t *p, uint32_t *val) { + int i; + + for (*val = 0, i = 0; i < 3; i++) { + *val = (*val << 7) + (p[i] & 0x7F); + if (!(p[i] & 0x80)) return i + 1; + } + *val = (*val << 8) + p[i]; + return 4; } /* checksum 8 parity ---------------------------------------------------------*/ -static uint8_t csum8(const uint8_t *buff, int len) -{ - uint8_t cs=0; - int i; - - for (i=0;itow_p+302400.0) tow-=604800.0; - return gpst2time(week,tow); +static gtime_t adjweek(gtime_t time, double tow) { + double tow_p; + int week; + tow_p = time2gpst(time, &week); + if (tow < tow_p - 302400.0) + tow += 604800.0; + else if (tow > tow_p + 302400.0) + tow -= 604800.0; + return gpst2time(week, tow); } /* adjust daily rollover of time ---------------------------------------------*/ -static gtime_t adjday(gtime_t time, double tod) -{ - double ep[6],tod_p; - time2epoch(time,ep); - tod_p=ep[3]*3600.0+ep[4]*60.0+ep[5]; - if (todtod_p+43200.0) tod-=86400.0; - ep[3]=ep[4]=ep[5]=0.0; - return timeadd(epoch2time(ep),tod); +static gtime_t adjday(gtime_t time, double tod) { + double ep[6], tod_p; + time2epoch(time, ep); + tod_p = ep[3] * 3600.0 + ep[4] * 60.0 + ep[5]; + if (tod < tod_p - 43200.0) + tod += 86400.0; + else if (tod > tod_p + 43200.0) + tod -= 86400.0; + ep[3] = ep[4] = ep[5] = 0.0; + return timeadd(epoch2time(ep), tod); } /* URA value (m) to URA index ------------------------------------------------*/ -static int uraindex(double value) -{ - int i; - for (i=0;i<15;i++) if (ura_eph[i]>=value) break; - return i; +static int uraindex(double value) { + int i; + for (i = 0; i < 15; i++) + if (ura_eph[i] >= value) break; + return i; } /* Galileo SISA value (m) to SISA index --------------------------------------*/ -static int sisaindex(double value) -{ - if (value< 0.5) return (int)((value )/0.01); - if (value< 1.0) return (int)((value-0.5)/0.02)+ 50; - if (value< 2.0) return (int)((value-1.0)/0.04)+ 75; - if (value<=6.0) return (int)((value-2.0)/0.16)+100; - return 255; /* NAPA */ +static int sisaindex(double value) { + if (value < 0.5) return (int)((value) / 0.01); + if (value < 1.0) return (int)((value - 0.5) / 0.02) + 50; + if (value < 2.0) return (int)((value - 1.0) / 0.04) + 75; + if (value <= 6.0) return (int)((value - 2.0) / 0.16) + 100; + return 255; /* NAPA */ } /* decode BINEX mesaage 0x00: site metadata ----------------------------------*/ -static int decode_bnx_00(raw_t *raw, uint8_t *buff, int len) -{ - static const double gpst0[]={1980,1,6,0,0,0}; - double x[3]; - char *msg,str[MAXANT]; - uint8_t *p=buff; - uint32_t min,qsec,src,fid=0,flen=0; - int i,ret=0; - - min =U4(p); p+=4; - qsec=U1(p); p+=1; - src =U1(p); p+=1; - raw->time=timeadd(epoch2time(gpst0),min*60.0+qsec*0.25); - - msg=raw->msgtype+strlen(raw->msgtype); - if (raw->outtype) { - char tstr[40]; - msg+=sprintf(msg," time=%s src=%u",time2str(raw->time,tstr,0),src); - } - while (p-buff=len) break; - - if (fid<=0x0c||(fid>=0x0f&&fid<=0x1c)||(fid>=0x20&&fid<=0x22)|| - fid==0x7f) { - p+=getbnxi(p,&flen); /* field length*/ - sprintf(str,"%.*s",MIN(flen,MAXANT-1),(char *)p); - p+=flen; - if (raw->outtype) { - msg+=sprintf(msg," [%02x]%s",fid,str); - } - if (fid==0x08) strcpy(raw->sta.name ,str); - else if (fid==0x09) strcpy(raw->sta.markerno, str); - else if (fid==0x17) strcpy(raw->sta.antdes ,str); - else if (fid==0x18) strcpy(raw->sta.antsno ,str); - else if (fid==0x19) strcpy(raw->sta.rectype,str); - else if (fid==0x1a) strcpy(raw->sta.recsno ,str); - else if (fid==0x1b) strcpy(raw->sta.recver ,str); - ret=5; - } - else if (fid==0x1d||fid==0x1e||fid==0x1f) { - if (fid==0x1d||fid==0x1e) { - p+=getbnxi(p,&flen); /* subfield length */ - p+=flen; - } - for (i=0;i<3;i++) { - x[i]=R8(p); p+=8; - } - if (raw->outtype) { - msg+=sprintf(msg," [%02x]%.3f/%.3f/%.3f",fid,x[0],x[1],x[2]); - } - if (fid==0x1d) { /* antenna ECEF X/Y/Z position */ - matcpy(raw->sta.pos,x,3,1); - } - else if (fid==0x1e) { /* antenna geographic position */ - x[0]*=D2R; - x[1]*=D2R; - pos2ecef(x,raw->sta.pos); - } - else if (fid==0x1f) { /* antenna offset (H/E/N) */ - raw->sta.deltype=0; /* (E/N/U) */ - raw->sta.del[0]=x[1]; - raw->sta.del[1]=x[2]; - raw->sta.del[2]=x[0]; - } - ret=5; - } - else { - trace(2,"BINEX 0x00: unsupported field fid=0x%02x\n",fid); - break; - } +static int decode_bnx_00(raw_t *raw, uint8_t *buff, int len) { + static const double gpst0[] = {1980, 1, 6, 0, 0, 0}; + double x[3]; + char *msg, str[MAXANT]; + uint8_t *p = buff; + uint32_t min, qsec, src, fid = 0, flen = 0; + int i, ret = 0; + + min = U4(p); + p += 4; + qsec = U1(p); + p += 1; + src = U1(p); + p += 1; + raw->time = timeadd(epoch2time(gpst0), min * 60.0 + qsec * 0.25); + + msg = raw->msgtype + strlen(raw->msgtype); + if (raw->outtype) { + char tstr[40]; + msg += sprintf(msg, " time=%s src=%u", time2str(raw->time, tstr, 0), src); + } + while (p - buff < len) { + p += getbnxi(p, &fid); + if (p - buff >= len) break; + + if (fid <= 0x0c || (fid >= 0x0f && fid <= 0x1c) || (fid >= 0x20 && fid <= 0x22) || + fid == 0x7f) { + p += getbnxi(p, &flen); /* field length*/ + sprintf(str, "%.*s", MIN(flen, MAXANT - 1), (char *)p); + p += flen; + if (raw->outtype) { + msg += sprintf(msg, " [%02x]%s", fid, str); + } + if (fid == 0x08) + strcpy(raw->sta.name, str); + else if (fid == 0x09) + strcpy(raw->sta.markerno, str); + else if (fid == 0x17) + strcpy(raw->sta.antdes, str); + else if (fid == 0x18) + strcpy(raw->sta.antsno, str); + else if (fid == 0x19) + strcpy(raw->sta.rectype, str); + else if (fid == 0x1a) + strcpy(raw->sta.recsno, str); + else if (fid == 0x1b) + strcpy(raw->sta.recver, str); + ret = 5; + } else if (fid == 0x1d || fid == 0x1e || fid == 0x1f) { + if (fid == 0x1d || fid == 0x1e) { + p += getbnxi(p, &flen); /* subfield length */ + p += flen; + } + for (i = 0; i < 3; i++) { + x[i] = R8(p); + p += 8; + } + if (raw->outtype) { + msg += sprintf(msg, " [%02x]%.3f/%.3f/%.3f", fid, x[0], x[1], x[2]); + } + if (fid == 0x1d) { /* antenna ECEF X/Y/Z position */ + matcpy(raw->sta.pos, x, 3, 1); + } else if (fid == 0x1e) { /* antenna geographic position */ + x[0] *= D2R; + x[1] *= D2R; + pos2ecef(x, raw->sta.pos); + } else if (fid == 0x1f) { /* antenna offset (H/E/N) */ + raw->sta.deltype = 0; /* (E/N/U) */ + raw->sta.del[0] = x[1]; + raw->sta.del[1] = x[2]; + raw->sta.del[2] = x[0]; + } + ret = 5; + } else { + trace(2, "BINEX 0x00: unsupported field fid=0x%02x\n", fid); + break; } - return ret; + } + return ret; } /* decode BINEX mesaage 0x01-00: coded (raw bytes) GNSS ephemeris ------------*/ -static int decode_bnx_01_00(raw_t *raw, uint8_t *buff, int len) -{ - (void)raw; (void)buff; (void)len; - trace(2,"BINEX 0x01-00: unsupported message\n"); - return 0; +static int decode_bnx_01_00(raw_t *raw, uint8_t *buff, int len) { + (void)raw; + (void)buff; + (void)len; + trace(2, "BINEX 0x01-00: unsupported message\n"); + return 0; } /* decode BINEX mesaage 0x01-01: decoded GPS ephmemeris ----------------------*/ -static int decode_bnx_01_01(raw_t *raw, uint8_t *buff, int len) -{ - eph_t eph={0}; - uint8_t *p=buff; - double tow,ura,sqrtA; - int prn,sat,flag; - - trace(4,"BINEX 0x01-01: len=%d\n",len); - - if (len>=127) { - prn =U1(p)+1; p+=1; - eph.week =U2(p); p+=2; - tow =I4(p); p+=4; - eph.toes =I4(p); p+=4; - eph.tgd[0]=R4(p); p+=4; - eph.iodc =I4(p); p+=4; - eph.f2 =R4(p); p+=4; - eph.f1 =R4(p); p+=4; - eph.f0 =R4(p); p+=4; - eph.iode =I4(p); p+=4; - eph.deln =R4(p)*SC2RAD; p+=4; - eph.M0 =R8(p); p+=8; - eph.e =R8(p); p+=8; - sqrtA =R8(p); p+=8; - eph.cic =R4(p); p+=4; - eph.crc =R4(p); p+=4; - eph.cis =R4(p); p+=4; - eph.crs =R4(p); p+=4; - eph.cuc =R4(p); p+=4; - eph.cus =R4(p); p+=4; - eph.OMG0 =R8(p); p+=8; - eph.omg =R8(p); p+=8; - eph.i0 =R8(p); p+=8; - eph.OMGd =R4(p)*SC2RAD; p+=4; - eph.idot =R4(p)*SC2RAD; p+=4; - ura =R4(p)*0.1; p+=4; - eph.svh =U2(p); p+=2; - flag =U2(p); - } - else { - trace(2,"BINEX 0x01-01: length error len=%d\n",len); - return -1; - } - if (!(sat=satno(SYS_GPS,prn))) { - trace(2,"BINEX 0x01-01: satellite error prn=%d\n",prn); - return -1; - } - eph.sat=sat; - eph.A=SQR(sqrtA); - eph.toe=gpst2time(eph.week,eph.toes); - eph.toc=gpst2time(eph.week,eph.toes); - eph.ttr=adjweek(eph.toe,tow); - eph.fit=flag&0xFF; - eph.flag=(flag>>8)&0x01; - eph.code=(flag>>9)&0x03; - eph.sva=uraindex(ura); - - if (!strstr(raw->opt,"-EPHALL")) { - if (raw->nav.eph[eph.sat-1].iode==eph.iode&& - raw->nav.eph[eph.sat-1].iodc==eph.iodc) return 0; /* unchanged */ - } - raw->nav.eph[sat-1]=eph; - raw->ephsat=sat; - raw->ephset=0; - return 2; +static int decode_bnx_01_01(raw_t *raw, uint8_t *buff, int len) { + eph_t eph = {0}; + uint8_t *p = buff; + double tow, ura, sqrtA; + int prn, sat, flag; + + trace(4, "BINEX 0x01-01: len=%d\n", len); + + if (len >= 127) { + prn = U1(p) + 1; + p += 1; + eph.week = U2(p); + p += 2; + tow = I4(p); + p += 4; + eph.toes = I4(p); + p += 4; + eph.tgd[0] = R4(p); + p += 4; + eph.iodc = I4(p); + p += 4; + eph.f2 = R4(p); + p += 4; + eph.f1 = R4(p); + p += 4; + eph.f0 = R4(p); + p += 4; + eph.iode = I4(p); + p += 4; + eph.deln = R4(p) * SC2RAD; + p += 4; + eph.M0 = R8(p); + p += 8; + eph.e = R8(p); + p += 8; + sqrtA = R8(p); + p += 8; + eph.cic = R4(p); + p += 4; + eph.crc = R4(p); + p += 4; + eph.cis = R4(p); + p += 4; + eph.crs = R4(p); + p += 4; + eph.cuc = R4(p); + p += 4; + eph.cus = R4(p); + p += 4; + eph.OMG0 = R8(p); + p += 8; + eph.omg = R8(p); + p += 8; + eph.i0 = R8(p); + p += 8; + eph.OMGd = R4(p) * SC2RAD; + p += 4; + eph.idot = R4(p) * SC2RAD; + p += 4; + ura = R4(p) * 0.1; + p += 4; + eph.svh = U2(p); + p += 2; + flag = U2(p); + } else { + trace(2, "BINEX 0x01-01: length error len=%d\n", len); + return -1; + } + if (!(sat = satno(SYS_GPS, prn))) { + trace(2, "BINEX 0x01-01: satellite error prn=%d\n", prn); + return -1; + } + eph.sat = sat; + eph.A = SQR(sqrtA); + eph.toe = gpst2time(eph.week, eph.toes); + eph.toc = gpst2time(eph.week, eph.toes); + eph.ttr = adjweek(eph.toe, tow); + eph.fit = flag & 0xFF; + eph.flag = (flag >> 8) & 0x01; + eph.code = (flag >> 9) & 0x03; + eph.sva = uraindex(ura); + + if (!strstr(raw->opt, "-EPHALL")) { + if (raw->nav.eph[eph.sat - 1].iode == eph.iode && raw->nav.eph[eph.sat - 1].iodc == eph.iodc) + return 0; /* unchanged */ + } + raw->nav.eph[sat - 1] = eph; + raw->ephsat = sat; + raw->ephset = 0; + return 2; } /* decode BINEX mesaage 0x01-02: decoded GLONASS ephmemeris ------------------*/ -static int decode_bnx_01_02(raw_t *raw, uint8_t *buff, int len) -{ - geph_t geph={0}; - uint8_t *p=buff; - double tod,tof,tau_gps; - int prn,sat,day,leap; - - trace(4,"BINEX 0x01-02: len=%d\n",len); - - if (len>=119) { - prn =U1(p)+1; p+=1; - day =U2(p); p+=2; - tod =U4(p); p+=4; - geph.taun =-R8(p); p+=8; - geph.gamn =R8(p); p+=8; - tof =U4(p); p+=4; - geph.pos[0]=R8(p)*1E3; p+=8; - geph.vel[0]=R8(p)*1E3; p+=8; - geph.acc[0]=R8(p)*1E3; p+=8; - geph.pos[1]=R8(p)*1E3; p+=8; - geph.vel[1]=R8(p)*1E3; p+=8; - geph.acc[1]=R8(p)*1E3; p+=8; - geph.pos[2]=R8(p)*1E3; p+=8; - geph.vel[2]=R8(p)*1E3; p+=8; - geph.acc[2]=R8(p)*1E3; p+=8; - geph.svh =U1(p)&0x7; p+=1; // Extended SVH (Cn_a, CN, Bn) - geph.frq =I1(p); p+=1; - geph.age =U1(p); p+=1; - leap =U1(p); p+=1; - tau_gps =R8(p); p+=8; - geph.dtaun =R8(p); - } - else { - trace(2,"BINEX 0x01-02: length error len=%d\n",len); - return -1; - } - if (!(sat=satno(SYS_GLO,prn))) { - trace(2,"BINEX 0x01-02: satellite error prn=%d\n",prn); - return -1; - } - if (raw->time.time==0) return 0; - geph.sat=sat; - geph.toe=utc2gpst(adjday(raw->time,tod-10800.0)); - geph.tof=utc2gpst(adjday(raw->time,tof-10800.0)); - geph.iode=(int)(fmod(tod,86400.0)/900.0+0.5); - - if (!strstr(raw->opt,"-EPHALL")) { - if (fabs(timediff(geph.toe,raw->nav.geph[prn-MINPRNGLO].toe))<1.0&& - geph.svh==raw->nav.geph[prn-MINPRNGLO].svh) return 0; - } - raw->nav.geph[prn-1]=geph; - raw->ephsat=sat; - raw->ephset=0; - return 2; +static int decode_bnx_01_02(raw_t *raw, uint8_t *buff, int len) { + geph_t geph = {0}; + uint8_t *p = buff; + double tod, tof, tau_gps; + int prn, sat, day, leap; + + trace(4, "BINEX 0x01-02: len=%d\n", len); + + if (len >= 119) { + prn = U1(p) + 1; + p += 1; + day = U2(p); + p += 2; + tod = U4(p); + p += 4; + geph.taun = -R8(p); + p += 8; + geph.gamn = R8(p); + p += 8; + tof = U4(p); + p += 4; + geph.pos[0] = R8(p) * 1E3; + p += 8; + geph.vel[0] = R8(p) * 1E3; + p += 8; + geph.acc[0] = R8(p) * 1E3; + p += 8; + geph.pos[1] = R8(p) * 1E3; + p += 8; + geph.vel[1] = R8(p) * 1E3; + p += 8; + geph.acc[1] = R8(p) * 1E3; + p += 8; + geph.pos[2] = R8(p) * 1E3; + p += 8; + geph.vel[2] = R8(p) * 1E3; + p += 8; + geph.acc[2] = R8(p) * 1E3; + p += 8; + geph.svh = U1(p) & 0x7; + p += 1; // Extended SVH (Cn_a, CN, Bn) + geph.frq = I1(p); + p += 1; + geph.age = U1(p); + p += 1; + leap = U1(p); + p += 1; + tau_gps = R8(p); + p += 8; + geph.dtaun = R8(p); + } else { + trace(2, "BINEX 0x01-02: length error len=%d\n", len); + return -1; + } + if (!(sat = satno(SYS_GLO, prn))) { + trace(2, "BINEX 0x01-02: satellite error prn=%d\n", prn); + return -1; + } + if (raw->time.time == 0) return 0; + geph.sat = sat; + geph.toe = utc2gpst(adjday(raw->time, tod - 10800.0)); + geph.tof = utc2gpst(adjday(raw->time, tof - 10800.0)); + geph.iode = (int)(fmod(tod, 86400.0) / 900.0 + 0.5); + + if (!strstr(raw->opt, "-EPHALL")) { + if (fabs(timediff(geph.toe, raw->nav.geph[prn - MINPRNGLO].toe)) < 1.0 && + geph.svh == raw->nav.geph[prn - MINPRNGLO].svh) + return 0; + } + raw->nav.geph[prn - 1] = geph; + raw->ephsat = sat; + raw->ephset = 0; + return 2; } /* decode BINEX mesaage 0x01-03: decoded SBAS ephmemeris ---------------------*/ -static int decode_bnx_01_03(raw_t *raw, uint8_t *buff, int len) -{ - seph_t seph={0}; - uint8_t *p=buff; - double tow,tod,tof; - int prn,sat,week,iodn; - - trace(4,"BINEX 0x01-03: len=%d\n",len); - - if (len>=98) { - prn =U1(p); p+=1; - week =U2(p); p+=2; - tow =U4(p); p+=4; - seph.af0 =R8(p); p+=8; - tod =R4(p); p+=4; - tof =U4(p); p+=4; - seph.pos[0]=R8(p)*1E3; p+=8; - seph.vel[0]=R8(p)*1E3; p+=8; - seph.acc[0]=R8(p)*1E3; p+=8; - seph.pos[1]=R8(p)*1E3; p+=8; - seph.vel[1]=R8(p)*1E3; p+=8; - seph.acc[1]=R8(p)*1E3; p+=8; - seph.pos[2]=R8(p)*1E3; p+=8; - seph.vel[2]=R8(p)*1E3; p+=8; - seph.acc[2]=R8(p)*1E3; p+=8; - seph.svh =U1(p); p+=1; - seph.sva =U1(p); p+=1; - iodn =U1(p); - } - else { - trace(2,"BINEX 0x01-03 length error: len=%d\n",len); - return -1; - } - if (!(sat=satno(SYS_SBS,prn))) { - trace(2,"BINEX 0x01-03 satellite error: prn=%d\n",prn); - return -1; - } - seph.sat=sat; - seph.t0=gpst2time(week,tow); - seph.tof=adjweek(seph.t0,tof); - - if (!strstr(raw->opt,"-EPHALL")) { - if (fabs(timediff(seph.t0,raw->nav.seph[prn-MINPRNSBS].t0))<1.0&& - seph.sva==raw->nav.seph[prn-MINPRNSBS].sva) return 0; - } - raw->nav.seph[prn-MINPRNSBS]=seph; - raw->ephsat=sat; - raw->ephset=0; - return 2; +static int decode_bnx_01_03(raw_t *raw, uint8_t *buff, int len) { + seph_t seph = {0}; + uint8_t *p = buff; + double tow, tod, tof; + int prn, sat, week, iodn; + + trace(4, "BINEX 0x01-03: len=%d\n", len); + + if (len >= 98) { + prn = U1(p); + p += 1; + week = U2(p); + p += 2; + tow = U4(p); + p += 4; + seph.af0 = R8(p); + p += 8; + tod = R4(p); + p += 4; + tof = U4(p); + p += 4; + seph.pos[0] = R8(p) * 1E3; + p += 8; + seph.vel[0] = R8(p) * 1E3; + p += 8; + seph.acc[0] = R8(p) * 1E3; + p += 8; + seph.pos[1] = R8(p) * 1E3; + p += 8; + seph.vel[1] = R8(p) * 1E3; + p += 8; + seph.acc[1] = R8(p) * 1E3; + p += 8; + seph.pos[2] = R8(p) * 1E3; + p += 8; + seph.vel[2] = R8(p) * 1E3; + p += 8; + seph.acc[2] = R8(p) * 1E3; + p += 8; + seph.svh = U1(p); + p += 1; + seph.sva = U1(p); + p += 1; + iodn = U1(p); + } else { + trace(2, "BINEX 0x01-03 length error: len=%d\n", len); + return -1; + } + if (!(sat = satno(SYS_SBS, prn))) { + trace(2, "BINEX 0x01-03 satellite error: prn=%d\n", prn); + return -1; + } + seph.sat = sat; + seph.t0 = gpst2time(week, tow); + seph.tof = adjweek(seph.t0, tof); + + if (!strstr(raw->opt, "-EPHALL")) { + if (fabs(timediff(seph.t0, raw->nav.seph[prn - MINPRNSBS].t0)) < 1.0 && + seph.sva == raw->nav.seph[prn - MINPRNSBS].sva) + return 0; + } + raw->nav.seph[prn - MINPRNSBS] = seph; + raw->ephsat = sat; + raw->ephset = 0; + return 2; } /* decode BINEX mesaage 0x01-04: decoded Galileo ephmemeris ------------------*/ -static int decode_bnx_01_04(raw_t *raw, uint8_t *buff, int len) -{ - eph_t eph={0}; - uint8_t *p=buff; - double tow,ura,sqrtA; - int prn,sat,set,eph_sel=3; /* ephemeris selection (1:I/NAV+2:F/NAV) */ - - trace(4,"BINEX 0x01-04: len=%d\n",len); - - if (strstr(raw->opt,"-GALFNAV")) eph_sel=1; - if (strstr(raw->opt,"-GALINAV")) eph_sel=2; - - if (len>=127) { - prn =U1(p)+1; p+=1; - eph.week =U2(p); p+=2; /* gal-week = gps-week */ - tow =I4(p); p+=4; - eph.toes =I4(p); p+=4; - eph.tgd[0]=R4(p); p+=4; /* BGD E5a/E1 */ - eph.tgd[1]=R4(p); p+=4; /* BGD E5b/E1 */ - eph.iode =I4(p); p+=4; /* IODnav */ - eph.f2 =R4(p); p+=4; - eph.f1 =R4(p); p+=4; - eph.f0 =R4(p); p+=4; - eph.deln =R4(p)*SC2RAD; p+=4; - eph.M0 =R8(p); p+=8; - eph.e =R8(p); p+=8; - sqrtA =R8(p); p+=8; - eph.cic =R4(p); p+=4; - eph.crc =R4(p); p+=4; - eph.cis =R4(p); p+=4; - eph.crs =R4(p); p+=4; - eph.cuc =R4(p); p+=4; - eph.cus =R4(p); p+=4; - eph.OMG0 =R8(p); p+=8; - eph.omg =R8(p); p+=8; - eph.i0 =R8(p); p+=8; - eph.OMGd =R4(p)*SC2RAD; p+=4; - eph.idot =R4(p)*SC2RAD; p+=4; - ura =R4(p); p+=4; - eph.svh =U2(p); p+=2; - eph.code =U2(p); /* data source defined as RINEX 3.03 */ - } - else { - trace(2,"BINEX 0x01-04: length error len=%d\n",len); - return -1; - } - if (!(sat=satno(SYS_GAL,prn))) { - trace(2,"BINEX 0x01-04: satellite error prn=%d\n",prn); - return -1; - } - set=(eph.code&(1<<8))?1:0; /* 0:I/NAV,1:F/NAV */ - if (!(eph_sel&1)&&set==0) return 0; - if (!(eph_sel&2)&&set==1) return 0; - - eph.sat=sat; - eph.A=SQR(sqrtA); - eph.iodc=eph.iode; - eph.toe=gpst2time(eph.week,eph.toes); - eph.toc=gpst2time(eph.week,eph.toes); - eph.ttr=adjweek(eph.toe,tow); - eph.sva=ura<0.0?(int)(-ura)-1:sisaindex(ura); /* SISA index */ - if (!strstr(raw->opt,"-EPHALL")) { - if (raw->nav.eph[sat-1+MAXSAT*set].iode==eph.iode&& - fabs(timediff(raw->nav.eph[sat-1+MAXSAT*set].toe,eph.toe))<1.0&& - fabs(timediff(raw->nav.eph[sat-1+MAXSAT*set].toc,eph.toc))<1.0) { - return 0; - } +static int decode_bnx_01_04(raw_t *raw, uint8_t *buff, int len) { + eph_t eph = {0}; + uint8_t *p = buff; + double tow, ura, sqrtA; + int prn, sat, set, eph_sel = 3; /* ephemeris selection (1:I/NAV+2:F/NAV) */ + + trace(4, "BINEX 0x01-04: len=%d\n", len); + + if (strstr(raw->opt, "-GALFNAV")) eph_sel = 1; + if (strstr(raw->opt, "-GALINAV")) eph_sel = 2; + + if (len >= 127) { + prn = U1(p) + 1; + p += 1; + eph.week = U2(p); + p += 2; /* gal-week = gps-week */ + tow = I4(p); + p += 4; + eph.toes = I4(p); + p += 4; + eph.tgd[0] = R4(p); + p += 4; /* BGD E5a/E1 */ + eph.tgd[1] = R4(p); + p += 4; /* BGD E5b/E1 */ + eph.iode = I4(p); + p += 4; /* IODnav */ + eph.f2 = R4(p); + p += 4; + eph.f1 = R4(p); + p += 4; + eph.f0 = R4(p); + p += 4; + eph.deln = R4(p) * SC2RAD; + p += 4; + eph.M0 = R8(p); + p += 8; + eph.e = R8(p); + p += 8; + sqrtA = R8(p); + p += 8; + eph.cic = R4(p); + p += 4; + eph.crc = R4(p); + p += 4; + eph.cis = R4(p); + p += 4; + eph.crs = R4(p); + p += 4; + eph.cuc = R4(p); + p += 4; + eph.cus = R4(p); + p += 4; + eph.OMG0 = R8(p); + p += 8; + eph.omg = R8(p); + p += 8; + eph.i0 = R8(p); + p += 8; + eph.OMGd = R4(p) * SC2RAD; + p += 4; + eph.idot = R4(p) * SC2RAD; + p += 4; + ura = R4(p); + p += 4; + eph.svh = U2(p); + p += 2; + eph.code = U2(p); /* data source defined as RINEX 3.03 */ + } else { + trace(2, "BINEX 0x01-04: length error len=%d\n", len); + return -1; + } + if (!(sat = satno(SYS_GAL, prn))) { + trace(2, "BINEX 0x01-04: satellite error prn=%d\n", prn); + return -1; + } + set = (eph.code & (1 << 8)) ? 1 : 0; /* 0:I/NAV,1:F/NAV */ + if (!(eph_sel & 1) && set == 0) return 0; + if (!(eph_sel & 2) && set == 1) return 0; + + eph.sat = sat; + eph.A = SQR(sqrtA); + eph.iodc = eph.iode; + eph.toe = gpst2time(eph.week, eph.toes); + eph.toc = gpst2time(eph.week, eph.toes); + eph.ttr = adjweek(eph.toe, tow); + eph.sva = ura < 0.0 ? (int)(-ura) - 1 : sisaindex(ura); /* SISA index */ + if (!strstr(raw->opt, "-EPHALL")) { + if (raw->nav.eph[sat - 1 + MAXSAT * set].iode == eph.iode && + fabs(timediff(raw->nav.eph[sat - 1 + MAXSAT * set].toe, eph.toe)) < 1.0 && + fabs(timediff(raw->nav.eph[sat - 1 + MAXSAT * set].toc, eph.toc)) < 1.0) { + return 0; } - raw->nav.eph[sat-1+MAXSAT*set]=eph; - raw->ephsat=sat; - raw->ephset=set; - return 2; + } + raw->nav.eph[sat - 1 + MAXSAT * set] = eph; + raw->ephsat = sat; + raw->ephset = set; + return 2; } /* BDS signed 10 bit Tgd -> sec ----------------------------------------------*/ -static double bds_tgd(int tgd) -{ - tgd&=0x3FF; - return (tgd&0x200)?-1E-10*((~tgd)&0x1FF):1E-10*(tgd&0x1FF); +static double bds_tgd(int tgd) { + tgd &= 0x3FF; + return (tgd & 0x200) ? -1E-10 * ((~tgd) & 0x1FF) : 1E-10 * (tgd & 0x1FF); } /* decode BINEX mesaage 0x01-05: decoded Beidou-2/Compass ephmemeris ---------*/ -static int decode_bnx_01_05(raw_t *raw, uint8_t *buff, int len) -{ - eph_t eph={0}; - uint8_t *p=buff; - double tow,toc,sqrtA; - int prn,sat,flag1,flag2; - - trace(4,"BINEX 0x01-05: len=%d\n",len); - - if (len>=117) { - prn =U1(p); p+=1; - eph.week =U2(p); p+=2; - tow =I4(p); p+=4; - toc =I4(p); p+=4; - eph.toes =I4(p); p+=4; - eph.f2 =R4(p); p+=4; - eph.f1 =R4(p); p+=4; - eph.f0 =R4(p); p+=4; - eph.deln =R4(p)*SC2RAD; p+=4; - eph.M0 =R8(p); p+=8; - eph.e =R8(p); p+=8; - sqrtA =R8(p); p+=8; - eph.cic =R4(p); p+=4; - eph.crc =R4(p); p+=4; - eph.cis =R4(p); p+=4; - eph.crs =R4(p); p+=4; - eph.cuc =R4(p); p+=4; - eph.cus =R4(p); p+=4; - eph.OMG0 =R8(p); p+=8; - eph.omg =R8(p); p+=8; - eph.i0 =R8(p); p+=8; - eph.OMGd =R4(p)*SC2RAD; p+=4; - eph.idot =R4(p)*SC2RAD; p+=4; - flag1 =U2(p); p+=2; - flag2 =U4(p); - } - else { - trace(2,"BINEX 0x01-05: length error len=%d\n",len); - return -1; - } - if (!(sat=satno(SYS_CMP,prn))) { - trace(2,"BINEX 0x01-05: satellite error prn=%d\n",prn); - return -1; - } - eph.sat=sat; - eph.A=SQR(sqrtA); - eph.toe=gpst2time(eph.week+1356,eph.toes+14.0); /* bdt -> gpst */ - eph.toc=gpst2time(eph.week+1356,eph.toes+14.0); /* bdt -> gpst */ - eph.ttr=adjweek(eph.toe,tow+14.0); /* bdt -> gpst */ - eph.iodc=(flag1>>1)&0x1F; - eph.iode=(flag1>>6)&0x1F; - eph.svh=flag1&0x01; - eph.sva=flag2&0x0F; /* URA index */ - eph.tgd[0]=bds_tgd(flag2>> 4); /* TGD1 (s) */ - eph.tgd[1]=bds_tgd(flag2>>14); /* TGD2 (s) */ - eph.flag=(flag1>>11)&0x07; /* nav type (0:unknown,1:IGSO/MEO,2:GEO) */ - eph.code=(flag2>>25)&0x7F; - /* message source (0:unknown,1:B1I,2:B1Q,3:B2I,4:B2Q,5:B3I,6:B3Q)*/ - - if (!strstr(raw->opt,"-EPHALL")) { - if (fabs(timediff(raw->nav.eph[sat-1].toe,eph.toe))<1.0) return 0; - } - raw->nav.eph[sat-1]=eph; - raw->ephsat=sat; - raw->ephset=0; - return 2; +static int decode_bnx_01_05(raw_t *raw, uint8_t *buff, int len) { + eph_t eph = {0}; + uint8_t *p = buff; + double tow, toc, sqrtA; + int prn, sat, flag1, flag2; + + trace(4, "BINEX 0x01-05: len=%d\n", len); + + if (len >= 117) { + prn = U1(p); + p += 1; + eph.week = U2(p); + p += 2; + tow = I4(p); + p += 4; + toc = I4(p); + p += 4; + eph.toes = I4(p); + p += 4; + eph.f2 = R4(p); + p += 4; + eph.f1 = R4(p); + p += 4; + eph.f0 = R4(p); + p += 4; + eph.deln = R4(p) * SC2RAD; + p += 4; + eph.M0 = R8(p); + p += 8; + eph.e = R8(p); + p += 8; + sqrtA = R8(p); + p += 8; + eph.cic = R4(p); + p += 4; + eph.crc = R4(p); + p += 4; + eph.cis = R4(p); + p += 4; + eph.crs = R4(p); + p += 4; + eph.cuc = R4(p); + p += 4; + eph.cus = R4(p); + p += 4; + eph.OMG0 = R8(p); + p += 8; + eph.omg = R8(p); + p += 8; + eph.i0 = R8(p); + p += 8; + eph.OMGd = R4(p) * SC2RAD; + p += 4; + eph.idot = R4(p) * SC2RAD; + p += 4; + flag1 = U2(p); + p += 2; + flag2 = U4(p); + } else { + trace(2, "BINEX 0x01-05: length error len=%d\n", len); + return -1; + } + if (!(sat = satno(SYS_CMP, prn))) { + trace(2, "BINEX 0x01-05: satellite error prn=%d\n", prn); + return -1; + } + eph.sat = sat; + eph.A = SQR(sqrtA); + eph.toe = gpst2time(eph.week + 1356, eph.toes + 14.0); /* bdt -> gpst */ + eph.toc = gpst2time(eph.week + 1356, eph.toes + 14.0); /* bdt -> gpst */ + eph.ttr = adjweek(eph.toe, tow + 14.0); /* bdt -> gpst */ + eph.iodc = (flag1 >> 1) & 0x1F; + eph.iode = (flag1 >> 6) & 0x1F; + eph.svh = flag1 & 0x01; + eph.sva = flag2 & 0x0F; /* URA index */ + eph.tgd[0] = bds_tgd(flag2 >> 4); /* TGD1 (s) */ + eph.tgd[1] = bds_tgd(flag2 >> 14); /* TGD2 (s) */ + eph.flag = (flag1 >> 11) & 0x07; /* nav type (0:unknown,1:IGSO/MEO,2:GEO) */ + eph.code = (flag2 >> 25) & 0x7F; + /* message source (0:unknown,1:B1I,2:B1Q,3:B2I,4:B2Q,5:B3I,6:B3Q)*/ + + if (!strstr(raw->opt, "-EPHALL")) { + if (fabs(timediff(raw->nav.eph[sat - 1].toe, eph.toe)) < 1.0) return 0; + } + raw->nav.eph[sat - 1] = eph; + raw->ephsat = sat; + raw->ephset = 0; + return 2; } /* decode BINEX mesaage 0x01-06: decoded QZSS ephmemeris ---------------------*/ -static int decode_bnx_01_06(raw_t *raw, uint8_t *buff, int len) -{ - eph_t eph={0}; - uint8_t *p=buff; - double tow,ura,sqrtA; - int prn,sat,flag; - - trace(4,"BINEX 0x01-06: len=%d\n",len); - - if (len>=127) { - prn =U1(p); p+=1; - eph.week =U2(p); p+=2; - tow =I4(p); p+=4; - eph.toes =I4(p); p+=4; - eph.tgd[0]=R4(p); p+=4; - eph.iodc =I4(p); p+=4; - eph.f2 =R4(p); p+=4; - eph.f1 =R4(p); p+=4; - eph.f0 =R4(p); p+=4; - eph.iode =I4(p); p+=4; - eph.deln =R4(p)*SC2RAD; p+=4; - eph.M0 =R8(p); p+=8; - eph.e =R8(p); p+=8; - sqrtA =R8(p); p+=8; - eph.cic =R4(p); p+=4; - eph.crc =R4(p); p+=4; - eph.cis =R4(p); p+=4; - eph.crs =R4(p); p+=4; - eph.cuc =R4(p); p+=4; - eph.cus =R4(p); p+=4; - eph.OMG0 =R8(p); p+=8; - eph.omg =R8(p); p+=8; - eph.i0 =R8(p); p+=8; - eph.OMGd =R4(p)*SC2RAD; p+=4; - eph.idot =R4(p)*SC2RAD; p+=4; - ura =R4(p)*0.1; p+=4; - eph.svh =U2(p); p+=2; - flag =U2(p); - } - else { - trace(2,"BINEX 0x01-06: length error len=%d\n",len); - return -1; - } - if (!(sat=satno(SYS_QZS,prn))) { - trace(2,"BINEX 0x01-06: satellite error prn=%d\n",prn); - return -1; - } - eph.sat=sat; - eph.A=SQR(sqrtA); - eph.toe=gpst2time(eph.week,eph.toes); - eph.toc=gpst2time(eph.week,eph.toes); - eph.ttr=adjweek(eph.toe,tow); - eph.fit=(flag&0x01)?0.0:2.0; /* 0:2hr,1:>2hr */ - eph.sva=uraindex(ura); - eph.code=2; /* codes on L2 channel */ - - if (!strstr(raw->opt,"-EPHALL")) { - if (raw->nav.eph[sat-1].iode==eph.iode&& - raw->nav.eph[sat-1].iodc==eph.iodc) return 0; - } - raw->nav.eph[sat-1]=eph; - raw->ephsat=sat; - raw->ephset=0; - return 2; +static int decode_bnx_01_06(raw_t *raw, uint8_t *buff, int len) { + eph_t eph = {0}; + uint8_t *p = buff; + double tow, ura, sqrtA; + int prn, sat, flag; + + trace(4, "BINEX 0x01-06: len=%d\n", len); + + if (len >= 127) { + prn = U1(p); + p += 1; + eph.week = U2(p); + p += 2; + tow = I4(p); + p += 4; + eph.toes = I4(p); + p += 4; + eph.tgd[0] = R4(p); + p += 4; + eph.iodc = I4(p); + p += 4; + eph.f2 = R4(p); + p += 4; + eph.f1 = R4(p); + p += 4; + eph.f0 = R4(p); + p += 4; + eph.iode = I4(p); + p += 4; + eph.deln = R4(p) * SC2RAD; + p += 4; + eph.M0 = R8(p); + p += 8; + eph.e = R8(p); + p += 8; + sqrtA = R8(p); + p += 8; + eph.cic = R4(p); + p += 4; + eph.crc = R4(p); + p += 4; + eph.cis = R4(p); + p += 4; + eph.crs = R4(p); + p += 4; + eph.cuc = R4(p); + p += 4; + eph.cus = R4(p); + p += 4; + eph.OMG0 = R8(p); + p += 8; + eph.omg = R8(p); + p += 8; + eph.i0 = R8(p); + p += 8; + eph.OMGd = R4(p) * SC2RAD; + p += 4; + eph.idot = R4(p) * SC2RAD; + p += 4; + ura = R4(p) * 0.1; + p += 4; + eph.svh = U2(p); + p += 2; + flag = U2(p); + } else { + trace(2, "BINEX 0x01-06: length error len=%d\n", len); + return -1; + } + if (!(sat = satno(SYS_QZS, prn))) { + trace(2, "BINEX 0x01-06: satellite error prn=%d\n", prn); + return -1; + } + eph.sat = sat; + eph.A = SQR(sqrtA); + eph.toe = gpst2time(eph.week, eph.toes); + eph.toc = gpst2time(eph.week, eph.toes); + eph.ttr = adjweek(eph.toe, tow); + eph.fit = (flag & 0x01) ? 0.0 : 2.0; /* 0:2hr,1:>2hr */ + eph.sva = uraindex(ura); + eph.code = 2; /* codes on L2 channel */ + + if (!strstr(raw->opt, "-EPHALL")) { + if (raw->nav.eph[sat - 1].iode == eph.iode && raw->nav.eph[sat - 1].iodc == eph.iodc) return 0; + } + raw->nav.eph[sat - 1] = eph; + raw->ephsat = sat; + raw->ephset = 0; + return 2; } /* decode BINEX mesaage 0x01-07: decoded IRNSS ephmemeris --------------------*/ -static int decode_bnx_01_07(raw_t *raw, uint8_t *buff, int len) -{ - eph_t eph={0}; - uint8_t *p=buff; - double tow,toc,sqrtA; - int prn,sat,flag,iodec; - - trace(4,"BINEX 0x01-07: len=%d\n",len); - - if (len>=114) { - prn =U1(p); p+=1; - eph.week =U2(p)+1024; p+=2; /* IRNSS week -> GPS week */ - tow =I4(p); p+=4; - toc =I4(p); p+=4; - eph.toes =I4(p); p+=4; - eph.f2 =R4(p); p+=4; - eph.f1 =R4(p); p+=4; - eph.f0 =R4(p); p+=4; - eph.deln =R4(p)*SC2RAD; p+=4; - eph.M0 =R8(p); p+=8; - eph.e =R8(p); p+=8; - sqrtA =R8(p); p+=8; - eph.cic =R4(p); p+=4; - eph.crc =R4(p); p+=4; - eph.cis =R4(p); p+=4; - eph.crs =R4(p); p+=4; - eph.cuc =R4(p); p+=4; - eph.cus =R4(p); p+=4; - eph.OMG0 =R8(p); p+=8; - eph.omg =R8(p); p+=8; - eph.i0 =R8(p); p+=8; - eph.OMGd =R4(p)*SC2RAD; p+=4; - eph.idot =R4(p)*SC2RAD; p+=4; - flag =U1(p); p+=1; - iodec =U2(p); - } - else { - trace(2,"BINEX 0x01-07: length error len=%d\n",len); - return -1; - } - if (!(sat=satno(SYS_IRN,prn))) { - trace(2,"BINEX 0x01-07: satellite error prn=%d\n",prn); - return -1; - } - eph.sat=sat; - eph.A=SQR(sqrtA); - eph.toe=gpst2time(eph.week,eph.toes); - eph.toc=adjweek(eph.toe,toc); - eph.ttr=adjweek(eph.toe,tow); - eph.sva=flag&0x0F; /* URA index (0-15) */ - eph.svh=((flag&0x10)?2:0)+((flag&0x20)?1:0); - eph.iode=eph.iodc=iodec&0xFF; - eph.tgd[0]=(int8_t)(iodec>>8)*P2_31; - - if (!strstr(raw->opt,"-EPHALL")) { - if (raw->nav.eph[sat-1].iode==eph.iode&& - fabs(timediff(raw->nav.eph[sat-1].toe,eph.toe))<1.0&& - fabs(timediff(raw->nav.eph[sat-1].toc,eph.toc))<1.0) return 0; - } - raw->nav.eph[sat-1]=eph; - raw->ephsat=sat; - raw->ephset=0; - return 2; +static int decode_bnx_01_07(raw_t *raw, uint8_t *buff, int len) { + eph_t eph = {0}; + uint8_t *p = buff; + double tow, toc, sqrtA; + int prn, sat, flag, iodec; + + trace(4, "BINEX 0x01-07: len=%d\n", len); + + if (len >= 114) { + prn = U1(p); + p += 1; + eph.week = U2(p) + 1024; + p += 2; /* IRNSS week -> GPS week */ + tow = I4(p); + p += 4; + toc = I4(p); + p += 4; + eph.toes = I4(p); + p += 4; + eph.f2 = R4(p); + p += 4; + eph.f1 = R4(p); + p += 4; + eph.f0 = R4(p); + p += 4; + eph.deln = R4(p) * SC2RAD; + p += 4; + eph.M0 = R8(p); + p += 8; + eph.e = R8(p); + p += 8; + sqrtA = R8(p); + p += 8; + eph.cic = R4(p); + p += 4; + eph.crc = R4(p); + p += 4; + eph.cis = R4(p); + p += 4; + eph.crs = R4(p); + p += 4; + eph.cuc = R4(p); + p += 4; + eph.cus = R4(p); + p += 4; + eph.OMG0 = R8(p); + p += 8; + eph.omg = R8(p); + p += 8; + eph.i0 = R8(p); + p += 8; + eph.OMGd = R4(p) * SC2RAD; + p += 4; + eph.idot = R4(p) * SC2RAD; + p += 4; + flag = U1(p); + p += 1; + iodec = U2(p); + } else { + trace(2, "BINEX 0x01-07: length error len=%d\n", len); + return -1; + } + if (!(sat = satno(SYS_IRN, prn))) { + trace(2, "BINEX 0x01-07: satellite error prn=%d\n", prn); + return -1; + } + eph.sat = sat; + eph.A = SQR(sqrtA); + eph.toe = gpst2time(eph.week, eph.toes); + eph.toc = adjweek(eph.toe, toc); + eph.ttr = adjweek(eph.toe, tow); + eph.sva = flag & 0x0F; /* URA index (0-15) */ + eph.svh = ((flag & 0x10) ? 2 : 0) + ((flag & 0x20) ? 1 : 0); + eph.iode = eph.iodc = iodec & 0xFF; + eph.tgd[0] = (int8_t)(iodec >> 8) * P2_31; + + if (!strstr(raw->opt, "-EPHALL")) { + if (raw->nav.eph[sat - 1].iode == eph.iode && + fabs(timediff(raw->nav.eph[sat - 1].toe, eph.toe)) < 1.0 && + fabs(timediff(raw->nav.eph[sat - 1].toc, eph.toc)) < 1.0) + return 0; + } + raw->nav.eph[sat - 1] = eph; + raw->ephsat = sat; + raw->ephset = 0; + return 2; } /* decode BINEX mesaage 0x01-14: upgraded decoded Galileo ephmemeris ---------*/ -static int decode_bnx_01_14(raw_t *raw, uint8_t *buff, int len) -{ - eph_t eph={0}; - uint8_t *p=buff; - double tow,ura,sqrtA; - int prn,sat,tocs,set,eph_sel=3; - - trace(4,"BINEX 0x01-14: len=%d\n",len); - - if (strstr(raw->opt,"-GALFNAV")) eph_sel=1; - if (strstr(raw->opt,"-GALINAV")) eph_sel=2; - - if (len>=135) { - prn =U1(p)+1; p+=1; - eph.week =U2(p); p+=2; /* gal-week = gps-week */ - tow =I4(p); p+=4; - tocs =I4(p); p+=4; - eph.toes =I4(p); p+=4; - eph.tgd[0]=R4(p); p+=4; /* BGD E5a/E1 */ - eph.tgd[1]=R4(p); p+=4; /* BGD E5b/E1 */ - eph.iode =I4(p); p+=4; /* IODnav */ - eph.f2 =R4(p); p+=4; - eph.f1 =R4(p); p+=4; - eph.f0 =R8(p); p+=8; - eph.deln =R4(p)*SC2RAD; p+=4; - eph.M0 =R8(p); p+=8; - eph.e =R8(p); p+=8; - sqrtA =R8(p); p+=8; - eph.cic =R4(p); p+=4; - eph.crc =R4(p); p+=4; - eph.cis =R4(p); p+=4; - eph.crs =R4(p); p+=4; - eph.cuc =R4(p); p+=4; - eph.cus =R4(p); p+=4; - eph.OMG0 =R8(p); p+=8; - eph.omg =R8(p); p+=8; - eph.i0 =R8(p); p+=8; - eph.OMGd =R4(p)*SC2RAD; p+=4; - eph.idot =R4(p)*SC2RAD; p+=4; - ura =R4(p); p+=4; - eph.svh =U2(p); p+=2; - eph.code =U2(p); /* data source defined as RINEX 3.03 */ - } - else { - trace(2,"BINEX 0x01-14: length error len=%d\n",len); - return -1; - } - if (!(sat=satno(SYS_GAL,prn))) { - trace(2,"BINEX 0x01-14: satellite error prn=%d\n",prn); - return -1; - } - set=(eph.code&(1<<8))?1:0; /* 0:I/NAV,1:F/NAV */ - if (!(eph_sel&1)&&set==0) return 0; - if (!(eph_sel&2)&&set==1) return 0; - - eph.sat=sat; - eph.A=SQR(sqrtA); - eph.iodc=eph.iode; - eph.toe=gpst2time(eph.week,eph.toes); - eph.toc=gpst2time(eph.week,tocs); - eph.ttr=adjweek(eph.toe,tow); - eph.sva=ura<0.0?(int)(-ura)-1:sisaindex(ura); /* SISA index */ - if (!strstr(raw->opt,"-EPHALL")) { - if (raw->nav.eph[sat-1+MAXSAT*set].iode==eph.iode&& - fabs(timediff(raw->nav.eph[sat-1+MAXSAT*set].toe,eph.toe))<1.0&& - fabs(timediff(raw->nav.eph[sat-1+MAXSAT*set].toc,eph.toc))<1.0) { - return 0; - } +static int decode_bnx_01_14(raw_t *raw, uint8_t *buff, int len) { + eph_t eph = {0}; + uint8_t *p = buff; + double tow, ura, sqrtA; + int prn, sat, tocs, set, eph_sel = 3; + + trace(4, "BINEX 0x01-14: len=%d\n", len); + + if (strstr(raw->opt, "-GALFNAV")) eph_sel = 1; + if (strstr(raw->opt, "-GALINAV")) eph_sel = 2; + + if (len >= 135) { + prn = U1(p) + 1; + p += 1; + eph.week = U2(p); + p += 2; /* gal-week = gps-week */ + tow = I4(p); + p += 4; + tocs = I4(p); + p += 4; + eph.toes = I4(p); + p += 4; + eph.tgd[0] = R4(p); + p += 4; /* BGD E5a/E1 */ + eph.tgd[1] = R4(p); + p += 4; /* BGD E5b/E1 */ + eph.iode = I4(p); + p += 4; /* IODnav */ + eph.f2 = R4(p); + p += 4; + eph.f1 = R4(p); + p += 4; + eph.f0 = R8(p); + p += 8; + eph.deln = R4(p) * SC2RAD; + p += 4; + eph.M0 = R8(p); + p += 8; + eph.e = R8(p); + p += 8; + sqrtA = R8(p); + p += 8; + eph.cic = R4(p); + p += 4; + eph.crc = R4(p); + p += 4; + eph.cis = R4(p); + p += 4; + eph.crs = R4(p); + p += 4; + eph.cuc = R4(p); + p += 4; + eph.cus = R4(p); + p += 4; + eph.OMG0 = R8(p); + p += 8; + eph.omg = R8(p); + p += 8; + eph.i0 = R8(p); + p += 8; + eph.OMGd = R4(p) * SC2RAD; + p += 4; + eph.idot = R4(p) * SC2RAD; + p += 4; + ura = R4(p); + p += 4; + eph.svh = U2(p); + p += 2; + eph.code = U2(p); /* data source defined as RINEX 3.03 */ + } else { + trace(2, "BINEX 0x01-14: length error len=%d\n", len); + return -1; + } + if (!(sat = satno(SYS_GAL, prn))) { + trace(2, "BINEX 0x01-14: satellite error prn=%d\n", prn); + return -1; + } + set = (eph.code & (1 << 8)) ? 1 : 0; /* 0:I/NAV,1:F/NAV */ + if (!(eph_sel & 1) && set == 0) return 0; + if (!(eph_sel & 2) && set == 1) return 0; + + eph.sat = sat; + eph.A = SQR(sqrtA); + eph.iodc = eph.iode; + eph.toe = gpst2time(eph.week, eph.toes); + eph.toc = gpst2time(eph.week, tocs); + eph.ttr = adjweek(eph.toe, tow); + eph.sva = ura < 0.0 ? (int)(-ura) - 1 : sisaindex(ura); /* SISA index */ + if (!strstr(raw->opt, "-EPHALL")) { + if (raw->nav.eph[sat - 1 + MAXSAT * set].iode == eph.iode && + fabs(timediff(raw->nav.eph[sat - 1 + MAXSAT * set].toe, eph.toe)) < 1.0 && + fabs(timediff(raw->nav.eph[sat - 1 + MAXSAT * set].toc, eph.toc)) < 1.0) { + return 0; } - raw->nav.eph[sat-1+MAXSAT*set]=eph; - raw->ephsat=sat; - raw->ephset=set; - return 2; + } + raw->nav.eph[sat - 1 + MAXSAT * set] = eph; + raw->ephsat = sat; + raw->ephset = set; + return 2; } /* decode BINEX mesaage 0x01: GNSS navigation information --------------------*/ -static int decode_bnx_01(raw_t *raw, uint8_t *buff, int len) -{ - int srec=U1(buff),prn=U1(buff+1); - - if (raw->outtype) { - prn=srec==0x01||srec==0x02||srec==0x04?prn+1:(srec==0x00?0:prn); - sprintf(raw->msgtype+strlen(raw->msgtype)," subrec=%02X prn=%d",srec, - prn); - } - switch (srec) { - case 0x00: return decode_bnx_01_00(raw,buff+1,len-1); - case 0x01: return decode_bnx_01_01(raw,buff+1,len-1); - case 0x02: return decode_bnx_01_02(raw,buff+1,len-1); - case 0x03: return decode_bnx_01_03(raw,buff+1,len-1); - case 0x04: return decode_bnx_01_04(raw,buff+1,len-1); - case 0x05: return decode_bnx_01_05(raw,buff+1,len-1); - case 0x06: return decode_bnx_01_06(raw,buff+1,len-1); - case 0x07: return decode_bnx_01_07(raw,buff+1,len-1); - case 0x14: return decode_bnx_01_14(raw,buff+1,len-1); - } - return 0; +static int decode_bnx_01(raw_t *raw, uint8_t *buff, int len) { + int srec = U1(buff), prn = U1(buff + 1); + + if (raw->outtype) { + prn = srec == 0x01 || srec == 0x02 || srec == 0x04 ? prn + 1 : (srec == 0x00 ? 0 : prn); + sprintf(raw->msgtype + strlen(raw->msgtype), " subrec=%02X prn=%d", srec, prn); + } + switch (srec) { + case 0x00: + return decode_bnx_01_00(raw, buff + 1, len - 1); + case 0x01: + return decode_bnx_01_01(raw, buff + 1, len - 1); + case 0x02: + return decode_bnx_01_02(raw, buff + 1, len - 1); + case 0x03: + return decode_bnx_01_03(raw, buff + 1, len - 1); + case 0x04: + return decode_bnx_01_04(raw, buff + 1, len - 1); + case 0x05: + return decode_bnx_01_05(raw, buff + 1, len - 1); + case 0x06: + return decode_bnx_01_06(raw, buff + 1, len - 1); + case 0x07: + return decode_bnx_01_07(raw, buff + 1, len - 1); + case 0x14: + return decode_bnx_01_14(raw, buff + 1, len - 1); + } + return 0; } /* decode BINEX mesaage 0x02: generalized GNSS data --------------------------*/ -static int decode_bnx_02(raw_t *raw, uint8_t *buff, int len) -{ - (void)raw; (void)buff; (void)len; - trace(2,"BINEX 0x02: unsupported message\n"); - return 0; +static int decode_bnx_02(raw_t *raw, uint8_t *buff, int len) { + (void)raw; + (void)buff; + (void)len; + trace(2, "BINEX 0x02: unsupported message\n"); + return 0; } /* decode BINEX mesaage 0x03: generalized ancillary site data ----------------*/ -static int decode_bnx_03(raw_t *raw, uint8_t *buff, int len) -{ - (void)raw; (void)buff; (void)len; - trace(2,"BINEX 0x03: unsupported message\n"); - return 0; +static int decode_bnx_03(raw_t *raw, uint8_t *buff, int len) { + (void)raw; + (void)buff; + (void)len; + trace(2, "BINEX 0x03: unsupported message\n"); + return 0; } /* decode BINEX mesaage 0x7d: receiver internal state prototyping ------------*/ -static int decode_bnx_7d(raw_t *raw, uint8_t *buff, int len) -{ - (void)raw; (void)buff; (void)len; - trace(2,"BINEX 0x7d: unsupported message\n"); - return 0; +static int decode_bnx_7d(raw_t *raw, uint8_t *buff, int len) { + (void)raw; + (void)buff; + (void)len; + trace(2, "BINEX 0x7d: unsupported message\n"); + return 0; } /* decode BINEX mesaage 0x7e: ancillary site data prototyping ----------------*/ -static int decode_bnx_7e(raw_t *raw, uint8_t *buff, int len) -{ - (void)raw; (void)buff; (void)len; - trace(2,"BINEX 0x7e: unsupported message\n"); - return 0; +static int decode_bnx_7e(raw_t *raw, uint8_t *buff, int len) { + (void)raw; + (void)buff; + (void)len; + trace(2, "BINEX 0x7e: unsupported message\n"); + return 0; } /* decode BINEX mesaage 0x7f-00: JPL fiducial site ---------------------------*/ -static int decode_bnx_7f_00(raw_t *raw, uint8_t *buff, int len) -{ - (void)raw; (void)buff; (void)len; - trace(2,"BINEX 0x7f-00: unsupported message\n"); - return 0; +static int decode_bnx_7f_00(raw_t *raw, uint8_t *buff, int len) { + (void)raw; + (void)buff; + (void)len; + trace(2, "BINEX 0x7f-00: unsupported message\n"); + return 0; } /* decode BINEX mesaage 0x7f-01: UCAR COSMIC ---------------------------------*/ -static int decode_bnx_7f_01(raw_t *raw, uint8_t *buff, int len) -{ - (void)raw; (void)buff; (void)len; - trace(2,"BINEX 0x7f-01: unsupported message\n"); - return 0; +static int decode_bnx_7f_01(raw_t *raw, uint8_t *buff, int len) { + (void)raw; + (void)buff; + (void)len; + trace(2, "BINEX 0x7f-01: unsupported message\n"); + return 0; } /* decode BINEX mesaage 0x7f-02: Trimble 4700 --------------------------------*/ -static int decode_bnx_7f_02(raw_t *raw, uint8_t *buff, int len) -{ - (void)raw; (void)buff; (void)len; - trace(2,"BINEX 0x7f-02: unsupported message\n"); - return 0; +static int decode_bnx_7f_02(raw_t *raw, uint8_t *buff, int len) { + (void)raw; + (void)buff; + (void)len; + trace(2, "BINEX 0x7f-02: unsupported message\n"); + return 0; } /* decode BINEX mesaage 0x7f-03: Trimble NetRS -------------------------------*/ -static int decode_bnx_7f_03(raw_t *raw, uint8_t *buff, int len) -{ - (void)raw; (void)buff; (void)len; - trace(2,"BINEX 0x7f-03: unsupported message\n"); - return 0; +static int decode_bnx_7f_03(raw_t *raw, uint8_t *buff, int len) { + (void)raw; + (void)buff; + (void)len; + trace(2, "BINEX 0x7f-03: unsupported message\n"); + return 0; } /* decode BINEX mesaage 0x7f-04: Trimble NetRS -------------------------------*/ -static int decode_bnx_7f_04(raw_t *raw, uint8_t *buff, int len) -{ - (void)raw; (void)buff; (void)len; - trace(2,"BINEX 0x7f-04: unsupported message\n"); - return 0; +static int decode_bnx_7f_04(raw_t *raw, uint8_t *buff, int len) { + (void)raw; + (void)buff; + (void)len; + trace(2, "BINEX 0x7f-04: unsupported message\n"); + return 0; } /* decode BINEX mesaage 0x7f-05: Trimble NetR8 obs data ----------------------*/ -static uint8_t *decode_bnx_7f_05_obs(raw_t *raw, uint8_t *buff, int sat, - int nobs, obsd_t *data) -{ - const uint8_t codes_gps[32]={ - CODE_L1C ,CODE_L1C ,CODE_L1P ,CODE_L1W ,CODE_L1Y ,CODE_L1M , /* 0- 5 */ - CODE_L1X ,CODE_L1N ,CODE_NONE,CODE_NONE,CODE_L2W ,CODE_L2C , /* 6-11 */ - CODE_L2D ,CODE_L2S ,CODE_L2L ,CODE_L2X ,CODE_L2P ,CODE_L2W , /* 12-17 */ - CODE_L2Y ,CODE_L2M ,CODE_L2N ,CODE_NONE,CODE_NONE,CODE_L5X , /* 18-23 */ - CODE_L5I ,CODE_L5Q ,CODE_L5X /* 24-26 */ - }; - const uint8_t codes_glo[32]={ - CODE_L1C ,CODE_L1C ,CODE_L1P ,CODE_NONE,CODE_NONE,CODE_NONE, /* 0- 5 */ - CODE_NONE,CODE_NONE,CODE_NONE,CODE_NONE,CODE_L2C ,CODE_L2C , /* 6-11 */ - CODE_L2P ,CODE_L3X ,CODE_L3I ,CODE_L3Q ,CODE_L3X /* 12-16 */ - }; - const uint8_t codes_gal[32]={ - CODE_L1C ,CODE_L1A ,CODE_L1B ,CODE_L1C ,CODE_L1X ,CODE_L1Z , /* 0- 5 */ - CODE_L5X ,CODE_L5I ,CODE_L5Q ,CODE_L5X ,CODE_L7X ,CODE_L7I , /* 6-11 */ - CODE_L7Q ,CODE_L7X ,CODE_L8X ,CODE_L8I ,CODE_L8Q ,CODE_L8X , /* 12-17 */ - CODE_L6X ,CODE_L6A ,CODE_L6B ,CODE_L6C ,CODE_L6X ,CODE_L6Z , /* 18-23 */ - }; - const uint8_t codes_sbs[32]={ - CODE_L1C ,CODE_L1C ,CODE_NONE,CODE_NONE,CODE_NONE,CODE_NONE, /* 0- 5 */ - CODE_L5X ,CODE_L5I ,CODE_L5Q ,CODE_L5X /* 6- 9 */ - }; - const uint8_t codes_cmp[32]={ - CODE_L2X ,CODE_L2I ,CODE_L2Q ,CODE_L2X ,CODE_L7X ,CODE_L7I , /* 0- 5 */ - CODE_L7Q ,CODE_L7X ,CODE_L6X ,CODE_L6I ,CODE_L6Q ,CODE_L6X , /* 6-11 */ - CODE_L1X ,CODE_L1D ,CODE_L1P ,CODE_L1X ,CODE_L5X ,CODE_L5D , /* 12-17 */ - CODE_L5P ,CODE_L5X ,CODE_L7Z ,CODE_L7D ,CODE_L7P ,CODE_L7Z /* 18-23 */ - /* 20-23: extension for BD990 F/W 5.48 */ - }; - const uint8_t codes_qzs[32]={ - CODE_L1C ,CODE_L1C ,CODE_L1S ,CODE_L1L ,CODE_L1X ,CODE_NONE, /* 0- 5 */ - CODE_NONE,CODE_L2X ,CODE_L2S ,CODE_L2L ,CODE_L2X ,CODE_NONE, /* 6-11 */ - CODE_NONE,CODE_L5X ,CODE_L5I ,CODE_L5Q ,CODE_L5X ,CODE_NONE, /* 12-17 */ - CODE_NONE,CODE_L6X ,CODE_L6S ,CODE_L6L ,CODE_L6X ,CODE_NONE, /* 18-23 */ - CODE_NONE,CODE_NONE,CODE_NONE,CODE_NONE,CODE_NONE,CODE_NONE, /* 24-29 */ - CODE_L1Z /* 30-30 */ - }; - const uint8_t codes_irn[32]={ - CODE_L5X ,CODE_L5A ,CODE_L5B ,CODE_L5C ,CODE_L5X ,CODE_L9X , /* 0- 5 */ - CODE_L9A ,CODE_L9B ,CODE_L9C ,CODE_L9X /* 6- 9 */ - }; - const uint8_t *codes=NULL; - double range[8],phase[8],cnr[8],dopp[8]={0},acc,freq; - uint8_t *p=buff; - uint8_t flag,flags[4]; - int i,j,k,sys,prn,fcn=-10,code[8],slip[8],pri[8],idx[8]; - int slipcnt[8]={0},mask[8]={0}; - - trace(5,"decode_bnx_7f_05_obs: sat=%2d nobs=%2d\n",sat,nobs); - - sys=satsys(sat,&prn); - - switch (sys) { - case SYS_GPS: codes=codes_gps; break; - case SYS_GLO: codes=codes_glo; break; - case SYS_GAL: codes=codes_gal; break; - case SYS_QZS: codes=codes_qzs; break; - case SYS_SBS: codes=codes_sbs; break; - case SYS_CMP: codes=codes_cmp; break; - case SYS_IRN: codes=codes_irn; break; - default: return 0; +static uint8_t *decode_bnx_7f_05_obs(raw_t *raw, uint8_t *buff, int sat, int nobs, obsd_t *data) { + const uint8_t codes_gps[32] = { + CODE_L1C, CODE_L1C, CODE_L1P, CODE_L1W, CODE_L1Y, CODE_L1M, /* 0- 5 */ + CODE_L1X, CODE_L1N, CODE_NONE, CODE_NONE, CODE_L2W, CODE_L2C, /* 6-11 */ + CODE_L2D, CODE_L2S, CODE_L2L, CODE_L2X, CODE_L2P, CODE_L2W, /* 12-17 */ + CODE_L2Y, CODE_L2M, CODE_L2N, CODE_NONE, CODE_NONE, CODE_L5X, /* 18-23 */ + CODE_L5I, CODE_L5Q, CODE_L5X /* 24-26 */ + }; + const uint8_t codes_glo[32] = { + CODE_L1C, CODE_L1C, CODE_L1P, CODE_NONE, CODE_NONE, CODE_NONE, /* 0- 5 */ + CODE_NONE, CODE_NONE, CODE_NONE, CODE_NONE, CODE_L2C, CODE_L2C, /* 6-11 */ + CODE_L2P, CODE_L3X, CODE_L3I, CODE_L3Q, CODE_L3X /* 12-16 */ + }; + const uint8_t codes_gal[32] = { + CODE_L1C, CODE_L1A, CODE_L1B, CODE_L1C, CODE_L1X, CODE_L1Z, /* 0- 5 */ + CODE_L5X, CODE_L5I, CODE_L5Q, CODE_L5X, CODE_L7X, CODE_L7I, /* 6-11 */ + CODE_L7Q, CODE_L7X, CODE_L8X, CODE_L8I, CODE_L8Q, CODE_L8X, /* 12-17 */ + CODE_L6X, CODE_L6A, CODE_L6B, CODE_L6C, CODE_L6X, CODE_L6Z, /* 18-23 */ + }; + const uint8_t codes_sbs[32] = { + CODE_L1C, CODE_L1C, CODE_NONE, CODE_NONE, CODE_NONE, CODE_NONE, /* 0- 5 */ + CODE_L5X, CODE_L5I, CODE_L5Q, CODE_L5X /* 6- 9 */ + }; + const uint8_t codes_cmp[32] = { + CODE_L2X, CODE_L2I, CODE_L2Q, CODE_L2X, + CODE_L7X, CODE_L7I, /* 0- 5 */ + CODE_L7Q, CODE_L7X, CODE_L6X, CODE_L6I, + CODE_L6Q, CODE_L6X, /* 6-11 */ + CODE_L1X, CODE_L1D, CODE_L1P, CODE_L1X, + CODE_L5X, CODE_L5D, /* 12-17 */ + CODE_L5P, CODE_L5X, CODE_L7Z, CODE_L7D, + CODE_L7P, CODE_L7Z /* 18-23 */ + /* 20-23: extension for BD990 F/W 5.48 */ + }; + const uint8_t codes_qzs[32] = { + CODE_L1C, CODE_L1C, CODE_L1S, CODE_L1L, CODE_L1X, CODE_NONE, /* 0- 5 */ + CODE_NONE, CODE_L2X, CODE_L2S, CODE_L2L, CODE_L2X, CODE_NONE, /* 6-11 */ + CODE_NONE, CODE_L5X, CODE_L5I, CODE_L5Q, CODE_L5X, CODE_NONE, /* 12-17 */ + CODE_NONE, CODE_L6X, CODE_L6S, CODE_L6L, CODE_L6X, CODE_NONE, /* 18-23 */ + CODE_NONE, CODE_NONE, CODE_NONE, CODE_NONE, CODE_NONE, CODE_NONE, /* 24-29 */ + CODE_L1Z /* 30-30 */ + }; + const uint8_t codes_irn[32] = { + CODE_L5X, CODE_L5A, CODE_L5B, CODE_L5C, CODE_L5X, CODE_L9X, /* 0- 5 */ + CODE_L9A, CODE_L9B, CODE_L9C, CODE_L9X /* 6- 9 */ + }; + const uint8_t *codes = NULL; + double range[8], phase[8], cnr[8], dopp[8] = {0}, acc, freq; + uint8_t *p = buff; + uint8_t flag, flags[4]; + int i, j, k, sys, prn, fcn = -10, code[8], slip[8], pri[8], idx[8]; + int slipcnt[8] = {0}, mask[8] = {0}; + + trace(5, "decode_bnx_7f_05_obs: sat=%2d nobs=%2d\n", sat, nobs); + + sys = satsys(sat, &prn); + + switch (sys) { + case SYS_GPS: + codes = codes_gps; + break; + case SYS_GLO: + codes = codes_glo; + break; + case SYS_GAL: + codes = codes_gal; + break; + case SYS_QZS: + codes = codes_qzs; + break; + case SYS_SBS: + codes = codes_sbs; + break; + case SYS_CMP: + codes = codes_cmp; + break; + case SYS_IRN: + codes = codes_irn; + break; + default: + return 0; + } + for (i = 0; i < nobs; i++) { + flag = getbitu(p, 0, 1); + slip[i] = getbitu(p, 2, 1); + code[i] = getbitu(p, 3, 5); + p++; + + for (j = 0; j < 4; j++) flags[j] = 0; + + for (j = 0; flag && j < 4; j++) { + flag = U1(p++); + flags[flag & 0x03] = flag & 0x7F; + flag &= 0x80; } - for (i=0;inav.glo_fcn[prn-1]) { - raw->nav.glo_fcn[prn-1]=fcn+8; /* fcn+8 */ - } - } - acc=(flags[0]&0x20)?0.0001:0.00002; /* phase accuracy */ - - cnr[i]=U1(p++)*0.4; - - if (i==0) { - cnr[i]+=getbits(p,0,2)*0.1; - range[i]=getbitu(p,2,32)*0.064+getbitu(p,34,6)*0.001; p+=5; - } - else if (flags[0]&0x40) { - cnr[i]+=getbits(p,0,2)*0.1; - range[i]=range[0]+getbits(p,4,20)*0.001; p+=3; - } - else { - range[i]=range[0]+getbits(p,0,16)*0.001; p+=2; - } - if (flags[0]&0x40) { - phase[i]=range[i]+getbits(p,0,24)*acc; p+=3; - } - else { - cnr[i]+=getbits(p,0,2)*0.1; - phase[i]=range[i]+getbits(p,2,22)*acc; p+=3; - } - if (flags[0]&0x04) { - dopp[i]=getbits(p,0,24)/256.0; p+=3; - } - if (flags[0]&0x08) { - if (flags[0]&0x10) { - slipcnt[i]=U2(p); p+=2; - } - else { - slipcnt[i]=U1(p); p+=1; - } - } - trace(5,"(%d) CODE=%2d S=%d F=%02X %02X %02X %02X\n",i+1, - code[i],slip[i],flags[0],flags[1],flags[2],flags[3]); - trace(5,"(%d) P=%13.3f L=%13.3f D=%7.1f SNR=%4.1f SCNT=%2d\n", - i+1,range[i],phase[i],dopp[i],cnr[i],slipcnt[i]); + if (flags[2]) { + fcn = getbits(flags + 2, 2, 4); + if (sys == SYS_GLO && !raw->nav.glo_fcn[prn - 1]) { + raw->nav.glo_fcn[prn - 1] = fcn + 8; /* fcn+8 */ + } } - if (!codes) { - data->sat=0; - return p; + acc = (flags[0] & 0x20) ? 0.0001 : 0.00002; /* phase accuracy */ + + cnr[i] = U1(p++) * 0.4; + + if (i == 0) { + cnr[i] += getbits(p, 0, 2) * 0.1; + range[i] = getbitu(p, 2, 32) * 0.064 + getbitu(p, 34, 6) * 0.001; + p += 5; + } else if (flags[0] & 0x40) { + cnr[i] += getbits(p, 0, 2) * 0.1; + range[i] = range[0] + getbits(p, 4, 20) * 0.001; + p += 3; + } else { + range[i] = range[0] + getbits(p, 0, 16) * 0.001; + p += 2; } - data->time=raw->time; - data->sat=sat; - - /* get code priority */ - for (i=0;iopt); + if (flags[0] & 0x40) { + phase[i] = range[i] + getbits(p, 0, 24) * acc; + p += 3; + } else { + cnr[i] += getbits(p, 0, 2) * 0.1; + phase[i] = range[i] + getbits(p, 2, 22) * acc; + p += 3; } - for (i=0;ipri[k])) k=j; - } - if (k<0) { - data->P[i]=data->L[i]=0.0; - data->D[i]=data->SNR[i]=0.0; - data->LLI[i]=0; - data->code[i]=CODE_NONE; - } - else { - freq=code2freq(sys,codes[code[k]],fcn); - data->P[i]=range[k]; - data->L[i]=phase[k]*freq/CLIGHT; - data->D[i]=dopp[k]; - data->SNR[i]=cnr[k]; - data->code[i]=codes[code[k]]; - data->LLI[i]=slip[k]?1:0; - mask[k]=1; - } + if (flags[0] & 0x04) { + dopp[i] = getbits(p, 0, 24) / 256.0; + p += 3; } - for (;i=nobs) { - data->P[i]=data->L[i]=0.0; - data->D[i]=data->SNR[i]=0.0; - data->LLI[i]=0; - data->code[i]=CODE_NONE; - } - else { - freq=code2freq(sys,codes[code[k]],fcn); - data->P[i]=range[k]; - data->L[i]=phase[k]*freq/CLIGHT; - data->D[i]=dopp[k]; - data->SNR[i]=cnr[k]; - data->code[i]=codes[code[k]]; - data->LLI[i]=slip[k]?1:0; - mask[k]=1; - } + if (flags[0] & 0x08) { + if (flags[0] & 0x10) { + slipcnt[i] = U2(p); + p += 2; + } else { + slipcnt[i] = U1(p); + p += 1; + } } + trace(5, "(%d) CODE=%2d S=%d F=%02X %02X %02X %02X\n", i + 1, code[i], slip[i], flags[0], + flags[1], flags[2], flags[3]); + trace(5, "(%d) P=%13.3f L=%13.3f D=%7.1f SNR=%4.1f SCNT=%2d\n", i + 1, range[i], phase[i], + dopp[i], cnr[i], slipcnt[i]); + } + if (!codes) { + data->sat = 0; return p; + } + data->time = raw->time; + data->sat = sat; + + /* get code priority */ + for (i = 0; i < nobs; i++) { + idx[i] = code2idx(sys, codes[code[i]]); + pri[i] = getcodepri(sys, codes[code[i]], raw->opt); + } + for (i = 0; i < NFREQ; i++) { + for (j = 0, k = -1; j < nobs; j++) { + if (idx[j] == i && (k < 0 || pri[j] > pri[k])) k = j; + } + if (k < 0) { + data->P[i] = data->L[i] = 0.0; + data->D[i] = data->SNR[i] = 0.0; + data->LLI[i] = 0; + data->code[i] = CODE_NONE; + } else { + freq = code2freq(sys, codes[code[k]], fcn); + data->P[i] = range[k]; + data->L[i] = phase[k] * freq / CLIGHT; + data->D[i] = dopp[k]; + data->SNR[i] = cnr[k]; + data->code[i] = codes[code[k]]; + data->LLI[i] = slip[k] ? 1 : 0; + mask[k] = 1; + } + } + for (; i < NFREQ + NEXOBS; i++) { + for (k = 0; k < nobs; k++) { + if (!mask[k]) break; + } + if (k >= nobs) { + data->P[i] = data->L[i] = 0.0; + data->D[i] = data->SNR[i] = 0.0; + data->LLI[i] = 0; + data->code[i] = CODE_NONE; + } else { + freq = code2freq(sys, codes[code[k]], fcn); + data->P[i] = range[k]; + data->L[i] = phase[k] * freq / CLIGHT; + data->D[i] = dopp[k]; + data->SNR[i] = cnr[k]; + data->code[i] = codes[code[k]]; + data->LLI[i] = slip[k] ? 1 : 0; + mask[k] = 1; + } + } + return p; } /* decode BINEX mesaage 0x7f-05: Trimble NetR8 -------------------------------*/ -static int decode_bnx_7f_05(raw_t *raw, uint8_t *buff, int len) -{ - obsd_t data={{0}}; - double clkoff=0.0,toff[16]={0}; - char *msg; - uint8_t *p=buff; - uint32_t flag; - int i,nsat,nobs,prn,sys,sat,clkrst=0,rsys=0,nsys=0,tsys[16]={0}; - - trace(4,"decode_bnx_7f_05\n"); - - raw->obs.n=0; - flag=U1(p++); - nsat=(int)(flag&0x3F)+1; - - if (flag&0x80) { /* rxclkoff */ - clkrst=getbitu(p,0, 2); - clkoff=getbits(p,2,22)*1E-9; p+=3; +static int decode_bnx_7f_05(raw_t *raw, uint8_t *buff, int len) { + obsd_t data = {{0}}; + double clkoff = 0.0, toff[16] = {0}; + char *msg; + uint8_t *p = buff; + uint32_t flag; + int i, nsat, nobs, prn, sys, sat, clkrst = 0, rsys = 0, nsys = 0, tsys[16] = {0}; + + trace(4, "decode_bnx_7f_05\n"); + + raw->obs.n = 0; + flag = U1(p++); + nsat = (int)(flag & 0x3F) + 1; + + if (flag & 0x80) { /* rxclkoff */ + clkrst = getbitu(p, 0, 2); + clkoff = getbits(p, 2, 22) * 1E-9; + p += 3; + } + if (flag & 0x40) { /* systime */ + nsys = getbitu(p, 0, 4); + rsys = getbitu(p, 4, 4); + p++; + for (i = 0; i < nsys; i++) { + toff[i] = getbits(p, 0, 24) * 1E-9; + tsys[i] = getbitu(p, 28, 4); + p += 4; } - if (flag&0x40) { /* systime */ - nsys=getbitu(p,0,4); - rsys=getbitu(p,4,4); p++; - for (i=0;ilen) { - trace(2,"BINEX 0x7F-05 length error: nsat=%2d len=%d\n",nsat,len); - return -1; - } - /* save obs data to obs buffer */ - if (data.sat&&raw->obs.nobs.data[raw->obs.n++]=data; - } + /* decode BINEX mesaage 0x7F-05 obs data */ + if (!(p = decode_bnx_7f_05_obs(raw, p, sat, nobs, &data))) return -1; + + if ((int)(p - buff) > len) { + trace(2, "BINEX 0x7F-05 length error: nsat=%2d len=%d\n", nsat, len); + return -1; } - if (raw->outtype) { - msg=raw->msgtype+strlen(raw->msgtype); - sprintf(msg," nsat=%2d",nsat); + /* save obs data to obs buffer */ + if (data.sat && raw->obs.n < MAXOBS) { + raw->obs.data[raw->obs.n++] = data; } - return raw->obs.n>0?1:0; + } + if (raw->outtype) { + msg = raw->msgtype + strlen(raw->msgtype); + sprintf(msg, " nsat=%2d", nsat); + } + return raw->obs.n > 0 ? 1 : 0; } /* decode BINEX mesaage 0x7f: GNSS data prototyping --------------------------*/ -static int decode_bnx_7f(raw_t *raw, uint8_t *buff, int len) -{ - static const double gpst0[]={1980,1,6,0,0,0}; - char *msg; - uint8_t *p=buff; - uint32_t srec,min,msec; - - srec=U1(p); p+=1; /* subrecord ID */ - min =U4(p); p+=4; - msec=U2(p); p+=2; - raw->time=timeadd(epoch2time(gpst0),min*60.0+msec*0.001); - - if (raw->outtype) { - msg=raw->msgtype+strlen(raw->msgtype); - char tstr[40]; - sprintf(msg," subrec=%02X time%s",srec,time2str(raw->time,tstr,3)); - } - switch (srec) { - case 0x00: return decode_bnx_7f_00(raw,buff+7,len-7); - case 0x01: return decode_bnx_7f_01(raw,buff+7,len-7); - case 0x02: return decode_bnx_7f_02(raw,buff+7,len-7); - case 0x03: return decode_bnx_7f_03(raw,buff+7,len-7); - case 0x04: return decode_bnx_7f_04(raw,buff+7,len-7); - case 0x05: return decode_bnx_7f_05(raw,buff+7,len-7); - } - return 0; +static int decode_bnx_7f(raw_t *raw, uint8_t *buff, int len) { + static const double gpst0[] = {1980, 1, 6, 0, 0, 0}; + char *msg; + uint8_t *p = buff; + uint32_t srec, min, msec; + + srec = U1(p); + p += 1; /* subrecord ID */ + min = U4(p); + p += 4; + msec = U2(p); + p += 2; + raw->time = timeadd(epoch2time(gpst0), min * 60.0 + msec * 0.001); + + if (raw->outtype) { + msg = raw->msgtype + strlen(raw->msgtype); + char tstr[40]; + sprintf(msg, " subrec=%02X time%s", srec, time2str(raw->time, tstr, 3)); + } + switch (srec) { + case 0x00: + return decode_bnx_7f_00(raw, buff + 7, len - 7); + case 0x01: + return decode_bnx_7f_01(raw, buff + 7, len - 7); + case 0x02: + return decode_bnx_7f_02(raw, buff + 7, len - 7); + case 0x03: + return decode_bnx_7f_03(raw, buff + 7, len - 7); + case 0x04: + return decode_bnx_7f_04(raw, buff + 7, len - 7); + case 0x05: + return decode_bnx_7f_05(raw, buff + 7, len - 7); + } + return 0; } /* decode BINEX mesaage ------------------------------------------------------*/ -static int decode_bnx(raw_t *raw) -{ - uint32_t len,cs1,cs2; - int rec,len_h; - - rec=raw->buff[1]; /* record ID */ - - /* record and header length */ - len_h=getbnxi(raw->buff+2,&len); - - trace(5,"decode_bnx: rec=%02x len=%d\n",rec,len); - - /* check parity */ - if (raw->len-1<128) { - cs1=U1(raw->buff+raw->len); - cs2=csum8(raw->buff+1,raw->len-1); - } - else { - cs1=U2(raw->buff+raw->len); - cs2=rtk_crc16(raw->buff+1,raw->len-1); - } - if (cs1!=cs2) { - trace(2,"BINEX 0x%02X parity error CS=%X %X\n",rec,cs1,cs2); - return -1; - } - if (raw->outtype) { - sprintf(raw->msgtype,"BINEX 0x%02X (%4d)",rec,raw->len); - } - /* decode BINEX message record */ - switch (rec) { - case 0x00: return decode_bnx_00(raw,raw->buff+2+len_h,len); - case 0x01: return decode_bnx_01(raw,raw->buff+2+len_h,len); - case 0x02: return decode_bnx_02(raw,raw->buff+2+len_h,len); - case 0x03: return decode_bnx_03(raw,raw->buff+2+len_h,len); - case 0x7d: return decode_bnx_7d(raw,raw->buff+2+len_h,len); - case 0x7e: return decode_bnx_7e(raw,raw->buff+2+len_h,len); - case 0x7f: return decode_bnx_7f(raw,raw->buff+2+len_h,len); - } - return 0; +static int decode_bnx(raw_t *raw) { + uint32_t len, cs1, cs2; + int rec, len_h; + + rec = raw->buff[1]; /* record ID */ + + /* record and header length */ + len_h = getbnxi(raw->buff + 2, &len); + + trace(5, "decode_bnx: rec=%02x len=%d\n", rec, len); + + /* check parity */ + if (raw->len - 1 < 128) { + cs1 = U1(raw->buff + raw->len); + cs2 = csum8(raw->buff + 1, raw->len - 1); + } else { + cs1 = U2(raw->buff + raw->len); + cs2 = rtk_crc16(raw->buff + 1, raw->len - 1); + } + if (cs1 != cs2) { + trace(2, "BINEX 0x%02X parity error CS=%X %X\n", rec, cs1, cs2); + return -1; + } + if (raw->outtype) { + sprintf(raw->msgtype, "BINEX 0x%02X (%4d)", rec, raw->len); + } + /* decode BINEX message record */ + switch (rec) { + case 0x00: + return decode_bnx_00(raw, raw->buff + 2 + len_h, len); + case 0x01: + return decode_bnx_01(raw, raw->buff + 2 + len_h, len); + case 0x02: + return decode_bnx_02(raw, raw->buff + 2 + len_h, len); + case 0x03: + return decode_bnx_03(raw, raw->buff + 2 + len_h, len); + case 0x7d: + return decode_bnx_7d(raw, raw->buff + 2 + len_h, len); + case 0x7e: + return decode_bnx_7e(raw, raw->buff + 2 + len_h, len); + case 0x7f: + return decode_bnx_7f(raw, raw->buff + 2 + len_h, len); + } + return 0; } /* synchronize BINEX message -------------------------------------------------*/ -static int sync_bnx(uint8_t *buff, uint8_t data) -{ - buff[0]=buff[1]; buff[1]=data; - - return buff[0]==BNXSYNC2&& - (buff[1]==0x00||buff[1]==0x01||buff[1]==0x02||buff[1]==0x03|| - buff[1]==0x7D||buff[1]==0x7E||buff[1]==0x7F); +static int sync_bnx(uint8_t *buff, uint8_t data) { + buff[0] = buff[1]; + buff[1] = data; + + return buff[0] == BNXSYNC2 && + (buff[1] == 0x00 || buff[1] == 0x01 || buff[1] == 0x02 || buff[1] == 0x03 || + buff[1] == 0x7D || buff[1] == 0x7E || buff[1] == 0x7F); } /* input BINEX message from stream --------------------------------------------- -* fetch next BINEX data and input a message from stream -* args : raw_t *raw IO receiver raw data control struct -* uint8_t data I stream data (1 byte) -* return : status (-1: error message, 0: no message, 1: input observation data, -* 2: input ephemeris, 5: input station pos/ant parameters) -* notes : support only the following message (ref [1]) -* -* - big-endian, regular CRC, forward record (sync=0xE2) -* - record-subrecord: -* 0x00 : site metadata (monument,marker,ref point,setup) -* 0x01-01: decoded GPS ephemeris -* 0x01-02: decoded GLONASS ephemeris -* 0x01-03: decoded SBAS ephemeris -* 0x01-04: decoded Galileo ephemeris -* 0x01-05: decoded BDS-2/compass ephemeris -* 0x01-06: decoded QZSS ephemeris -* 0x01-07: decoded IRNSS ephemeris -* 0x01-14: decoded upgraded Galileo ephemeris -* 0x7f-05: GNSS data prototyping - Trimble NetR8 -* -* to specify input options, set rtcm->opt to the following option -* strings separated by spaces. -* -* -EPHALL : input all ephemerides -* -GLss : select signal ss for GPS (ss=1C,1P,...) -* -RLss : select signal ss for GLO (ss=1C,1P,...) -* -ELss : select signal ss for GAL (ss=1C,1B,...) -* -JLss : select signal ss for QZS (ss=1C,2C,...) -* -CLss : select signal ss for BDS (ss=2I,2X,...) -* -GALINAV : select I/NAV for Galileo ephemeris (default: all) -* -GALFNAV : select F/NAV for Galileo ephemeris (default: all) -*-----------------------------------------------------------------------------*/ -extern int input_bnx(raw_t *raw, uint8_t data) -{ - uint32_t len; - int len_h,len_c; - - trace(5,"input_bnx: data=%02x\n",data); - - /* synchronize BINEX message */ - if (raw->nbyte==0) { - if (!sync_bnx(raw->buff,data)) return 0; - raw->nbyte=2; - return 0; - } - raw->buff[raw->nbyte++]=data; - if (raw->nbyte<4) return 0; - - len_h=getbnxi(raw->buff+2,&len); - - raw->len=len+len_h+2; /* length without CRC */ - - if (raw->len-1>4096) { - trace(2,"BINEX length error: len=%d\n",raw->len-1); - raw->nbyte=0; - return -1; - } - len_c=(raw->len-1<128)?1:2; - - if (raw->nbyte<(int)(raw->len+len_c)) return 0; - raw->nbyte=0; - - /* decode BINEX message */ - return decode_bnx(raw); + * fetch next BINEX data and input a message from stream + * args : raw_t *raw IO receiver raw data control struct + * uint8_t data I stream data (1 byte) + * return : status (-1: error message, 0: no message, 1: input observation data, + * 2: input ephemeris, 5: input station pos/ant parameters) + * notes : support only the following message (ref [1]) + * + * - big-endian, regular CRC, forward record (sync=0xE2) + * - record-subrecord: + * 0x00 : site metadata (monument,marker,ref point,setup) + * 0x01-01: decoded GPS ephemeris + * 0x01-02: decoded GLONASS ephemeris + * 0x01-03: decoded SBAS ephemeris + * 0x01-04: decoded Galileo ephemeris + * 0x01-05: decoded BDS-2/compass ephemeris + * 0x01-06: decoded QZSS ephemeris + * 0x01-07: decoded IRNSS ephemeris + * 0x01-14: decoded upgraded Galileo ephemeris + * 0x7f-05: GNSS data prototyping - Trimble NetR8 + * + * to specify input options, set rtcm->opt to the following option + * strings separated by spaces. + * + * -EPHALL : input all ephemerides + * -GLss : select signal ss for GPS (ss=1C,1P,...) + * -RLss : select signal ss for GLO (ss=1C,1P,...) + * -ELss : select signal ss for GAL (ss=1C,1B,...) + * -JLss : select signal ss for QZS (ss=1C,2C,...) + * -CLss : select signal ss for BDS (ss=2I,2X,...) + * -GALINAV : select I/NAV for Galileo ephemeris (default: all) + * -GALFNAV : select F/NAV for Galileo ephemeris (default: all) + *-----------------------------------------------------------------------------*/ +extern int input_bnx(raw_t *raw, uint8_t data) { + uint32_t len; + int len_h, len_c; + + trace(5, "input_bnx: data=%02x\n", data); + + /* synchronize BINEX message */ + if (raw->nbyte == 0) { + if (!sync_bnx(raw->buff, data)) return 0; + raw->nbyte = 2; + return 0; + } + raw->buff[raw->nbyte++] = data; + if (raw->nbyte < 4) return 0; + + len_h = getbnxi(raw->buff + 2, &len); + + raw->len = len + len_h + 2; /* length without CRC */ + + if (raw->len - 1 > 4096) { + trace(2, "BINEX length error: len=%d\n", raw->len - 1); + raw->nbyte = 0; + return -1; + } + len_c = (raw->len - 1 < 128) ? 1 : 2; + + if (raw->nbyte < (int)(raw->len + len_c)) return 0; + raw->nbyte = 0; + + /* decode BINEX message */ + return decode_bnx(raw); } /* input BINEX message from file ----------------------------------------------- -* fetch next BINEX data and input a message from file -* args : raw_t *raw IO receiver raw data control struct -* FILE *fp I file pointer -* return : status(-2: end of file, -1...9: same as above) -*-----------------------------------------------------------------------------*/ -extern int input_bnxf(raw_t *raw, FILE *fp) -{ - uint32_t len; - int i,data,len_h,len_c; - - trace(4,"input_bnxf\n"); - - if (raw->nbyte==0) { - for (i=0;;i++) { - if ((data=fgetc(fp))==EOF) return -2; - if (sync_bnx(raw->buff,(uint8_t)data)) break; - if (i>=4096) return 0; - } - } - if (fread(raw->buff+2,1,4,fp)<4) return -2; - - len_h=getbnxi(raw->buff+2,&len); - - raw->len=len+len_h+2; - - if (raw->len-1>4096) { - trace(2,"BINEX length error: len=%d\n",raw->len-1); - raw->nbyte=0; - return -1; - } - len_c=(raw->len-1<128)?1:2; - - if (fread(raw->buff+6,1,raw->len+len_c-6,fp)<(size_t)(raw->len+len_c-6)) { - return -2; + * fetch next BINEX data and input a message from file + * args : raw_t *raw IO receiver raw data control struct + * FILE *fp I file pointer + * return : status(-2: end of file, -1...9: same as above) + *-----------------------------------------------------------------------------*/ +extern int input_bnxf(raw_t *raw, FILE *fp) { + uint32_t len; + int i, data, len_h, len_c; + + trace(4, "input_bnxf\n"); + + if (raw->nbyte == 0) { + for (i = 0;; i++) { + if ((data = fgetc(fp)) == EOF) return -2; + if (sync_bnx(raw->buff, (uint8_t)data)) break; + if (i >= 4096) return 0; } - raw->nbyte=0; - - /* decode BINEX message */ - return decode_bnx(raw); + } + if (fread(raw->buff + 2, 1, 4, fp) < 4) return -2; + + len_h = getbnxi(raw->buff + 2, &len); + + raw->len = len + len_h + 2; + + if (raw->len - 1 > 4096) { + trace(2, "BINEX length error: len=%d\n", raw->len - 1); + raw->nbyte = 0; + return -1; + } + len_c = (raw->len - 1 < 128) ? 1 : 2; + + if (fread(raw->buff + 6, 1, raw->len + len_c - 6, fp) < (size_t)(raw->len + len_c - 6)) { + return -2; + } + raw->nbyte = 0; + + /* decode BINEX message */ + return decode_bnx(raw); } diff --git a/src/rcv/comnav.c b/src/rcv/comnav.c index e88b5203c..85176415c 100644 --- a/src/rcv/comnav.c +++ b/src/rcv/comnav.c @@ -12,21 +12,21 @@ *-----------------------------------------------------------------------------*/ #include "rtklib.h" -#define CNAVSYNC1 0xAA /* cnav message start sync code 1 */ -#define CNAVSYNC2 0x44 /* cnav message start sync code 2 */ -#define CNAVSYNC3 0x12 /* cnav message start sync code 3 */ - -#define CNAVHLEN 28 /* cnav message header length (bytes) */ - -#define ID_ALMANAC 73 /* message id: cnav decoded almanac */ -#define ID_GLOALMANAC 718 /* message id: cnav glonass decoded almanac */ -#define ID_GLOEPHEMERIS 723 /* message id: cnav glonass ephemeris */ -#define ID_IONUTC 8 /* message id: cnav iono and utc data */ -#define ID_RANGE 43 /* message id: cnav range measurement */ -#define ID_RANGECMP 140 /* message id: cnav range compressed */ -#define ID_RAWALM 74 /* message id: cnav raw almanac */ -#define ID_RAWEPHEM 41 /* message id: cnav raw ephemeris */ -#define ID_RAWWAASFRAME 287 /* message id: cnav raw waas frame */ +#define CNAVSYNC1 0xAA /* cnav message start sync code 1 */ +#define CNAVSYNC2 0x44 /* cnav message start sync code 2 */ +#define CNAVSYNC3 0x12 /* cnav message start sync code 3 */ + +#define CNAVHLEN 28 /* cnav message header length (bytes) */ + +#define ID_ALMANAC 73 /* message id: cnav decoded almanac */ +#define ID_GLOALMANAC 718 /* message id: cnav glonass decoded almanac */ +#define ID_GLOEPHEMERIS 723 /* message id: cnav glonass ephemeris */ +#define ID_IONUTC 8 /* message id: cnav iono and utc data */ +#define ID_RANGE 43 /* message id: cnav range measurement */ +#define ID_RANGECMP 140 /* message id: cnav range compressed */ +#define ID_RAWALM 74 /* message id: cnav raw almanac */ +#define ID_RAWEPHEM 41 /* message id: cnav raw ephemeris */ +#define ID_RAWWAASFRAME 287 /* message id: cnav raw waas frame */ #define ID_QZSSIONUTC 1347 /* message id: oem6 qzss ion/utc parameters */ #define ID_QZSSRAWEPHEM 1330 /* message id: oem6 qzss raw ephemeris */ @@ -35,1108 +35,1322 @@ #define ID_GALEPHEMERIS 1122 /* message id: oem6 decoded galileo ephemeris */ #define ID_GALALMANAC 1120 /* message id: oem6 decoded galileo almanac */ #define ID_GALCLOCK 1121 /* message id: oem6 galileo clockinformation */ -#define ID_GALIONO 1127 /* message id: oem6 decoded galileo iono corrections */ +#define ID_GALIONO 1127 /* message id: oem6 decoded galileo iono corrections */ #define ID_GALFNAVRAWPAGE 1413 /* message id: oem6 raw galileo f/nav paga data */ #define ID_GALINAVRAWWORD 1414 /* message id: oem6 raw galileo i/nav word data */ #define ID_RAWCNAVFRAME 1066 /* message id: oem6 raw cnav frame data */ #define ID_BDSEPHEMERIS 1696 /* message id: oem6 decoded bds ephemeris */ -#define WL1 0.1902936727984 -#define WL2 0.2442102134246 -#define MAXVAL 8388608.0 +#define WL1 0.1902936727984 +#define WL2 0.2442102134246 +#define MAXVAL 8388608.0 -#define OFF_FRQNO -7 /* F/W ver.3.620 */ +#define OFF_FRQNO -7 /* F/W ver.3.620 */ /* get fields (little-endian) ------------------------------------------------*/ #define U1(p) (*((unsigned char *)(p))) #define I1(p) (*((signed char *)(p))) -static unsigned short U2(unsigned char *p) {unsigned short u; memcpy(&u,p,2); return u;} -static unsigned int U4(unsigned char *p) {unsigned int u; memcpy(&u,p,4); return u;} -static int I4(unsigned char *p) {int i; memcpy(&i,p,4); return i;} -static float R4(unsigned char *p) {float r; memcpy(&r,p,4); return r;} -static double R8(unsigned char *p) {double r; memcpy(&r,p,8); return r;} +static unsigned short U2(unsigned char *p) { + unsigned short u; + memcpy(&u, p, 2); + return u; +} +static unsigned int U4(unsigned char *p) { + unsigned int u; + memcpy(&u, p, 4); + return u; +} +static int I4(unsigned char *p) { + int i; + memcpy(&i, p, 4); + return i; +} +static float R4(unsigned char *p) { + float r; + memcpy(&r, p, 4); + return r; +} +static double R8(unsigned char *p) { + double r; + memcpy(&r, p, 8); + return r; +} /* extend sign ---------------------------------------------------------------*/ -static int exsign(unsigned int v, int bits) -{ - return (int)(v&(1<<(bits-1))?v|(~0u<tow_p+302400.0) tow-=604800.0; - return gpst2time(week,tow); +static gtime_t adjweek(gtime_t time, double tow) { + double tow_p; + int week; + tow_p = time2gpst(time, &week); + if (tow < tow_p - 302400.0) + tow += 604800.0; + else if (tow > tow_p + 302400.0) + tow -= 604800.0; + return gpst2time(week, tow); } /* get observation data index ------------------------------------------------*/ -static int obsindex(obs_t *obs, gtime_t time, int sat) -{ - int i,j; - - if (obs->n>=MAXOBS) return -1; - for (i=0;in;i++) { - if (obs->data[i].sat==sat) return i; - } - obs->data[i].time=time; - obs->data[i].sat=sat; - for (j=0;jdata[i].L[j]=obs->data[i].P[j]=0.0; - obs->data[i].D[j]=obs->data[i].SNR[j]=0.0; - obs->data[i].LLI[j]=0; - obs->data[i].code[j]=CODE_NONE; - } - obs->n++; - return i; +static int obsindex(obs_t *obs, gtime_t time, int sat) { + int i, j; + + if (obs->n >= MAXOBS) return -1; + for (i = 0; i < obs->n; i++) { + if (obs->data[i].sat == sat) return i; + } + obs->data[i].time = time; + obs->data[i].sat = sat; + for (j = 0; j < NFREQ + NEXOBS; j++) { + obs->data[i].L[j] = obs->data[i].P[j] = 0.0; + obs->data[i].D[j] = obs->data[i].SNR[j] = 0.0; + obs->data[i].LLI[j] = 0; + obs->data[i].code[j] = CODE_NONE; + } + obs->n++; + return i; } /* decode cnav tracking status ------------------------------------------------- -* deocode cnav tracking status -* args : unsigned int stat I tracking status field -* int *sys O system (SYS_???) -* int *code O signal code (CODE_L??) -* int *track O tracking state -* (cnav/5) -* 0=L1 idle 8=L2 idle -* 1=L1 sky search 9=L2 p-code align -* 2=L1 wide freq pull-in 10=L2 search -* 3=L1 narrow freq pull-in 11=L2 pll -* 4=L1 pll 12=L2 steering -* 5=L1 reacq -* 6=L1 steering -* 7=L1 fll -* (oem6) -* 0=idle 7=freq-lock loop -* 2=wide freq band pull-in 9=channel alignment -* 3=narrow freq band pull-in 10=code search -* 4=phase lock loop 11=aided phase lock loop -* int *plock O phase-lock flag (0=not locked, 1=locked) -* int *clock O code-lock flag (0=not locked, 1=locked) -* int *parity O parity known flag (0=not known, 1=known) -* int *halfc O phase measurement (0=half-cycle not added, -* 1=added) -* return : signal frequency (0:L1,1:L2,2:L5,3:L6,4:L7,5:L8,-1:error) -* notes : refer [1][3] -*-----------------------------------------------------------------------------*/ -static int decode_trackstat(unsigned int stat, int *sys, int *code, int *track, - int *plock, int *clock, int *parity, int *halfc) -{ - int satsys,sigtype,freq=0; - - *track =stat&0x1F; - *plock =(stat>>10)&1; - *parity=(stat>>11)&1; - *clock =(stat>>12)&1; - satsys =(stat>>16)&7; - *halfc =(stat>>28)&1; - sigtype=(stat>>21)&0x1F; - - switch (satsys) { - case 0: *sys=SYS_GPS; break; - case 1: *sys=SYS_GLO; break; - case 2: *sys=SYS_SBS; break; - case 3: *sys=SYS_GAL; break; /* OEM6 */ - case 4: *sys=SYS_CMP; break; /* OEM6 F/W 6.400 */ - case 5: *sys=SYS_QZS; break; /* OEM6 */ - default: - trace(2,"cnav unknown system: sys=%d\n",satsys); - return -1; - } - if (*sys==SYS_GPS||*sys==SYS_QZS) { - switch (sigtype) { - case 0: freq=0; *code=CODE_L1C; break; /* L1C/A */ - case 2: freq=2; *code=CODE_L5I; break; /* L5 */ - case 5: freq=0; *code=CODE_L1P; break; /* L1P */ - case 9: freq=1; *code=CODE_L2D; break; /* L2P codeless */ - case 14: freq=2; *code=CODE_L5I; break; /* L5I */ - case 17: freq=1; *code=CODE_L2X; break; /* L2C(M+L) */ - default: freq=-1; break; - } - } - else if (*sys==SYS_GLO) { - switch (sigtype) { - case 0: freq=0; *code=CODE_L1C; break; /* L1C/A */ - case 1: freq=1; *code=CODE_L2C; break; /* L2C/A (OEM6) */ - case 5: freq=1; *code=CODE_L2C; break; /* L2C */ - default: freq=-1; break; - } - } - else if (*sys==SYS_GAL) { - switch (sigtype) { - case 1: freq=0; *code=CODE_L1B; break; /* E1B (OEM6) */ - case 2: freq=0; *code=CODE_L1X; break; /* E1C (OEM6) */ - case 12: freq=2; *code=CODE_L5X; break; /* E5aQ (OEM6) */ - case 17: freq=4; *code=CODE_L7X; break; /* E5bQ (OEM6) */ - case 20: freq=5; *code=CODE_L8X; break; /* AltBOCQ (OEM6) */ - default: freq=-1; break; - } - } - else if (*sys==SYS_CMP) { - switch (sigtype) { - case 0: freq=0; *code=CODE_L1I; break; /* B1 with D1 (OEM6) */ - case 1: freq=1; *code=CODE_L7I; break; /* B2 with D1 (OEM6) */ - case 4: freq=0; *code=CODE_L1I; break; /* B1 with D2 (OEM6) */ - case 5: freq=1; *code=CODE_L7I; break; /* B2 with D2 (OEM6) */ - default: freq=-1; break; - } - } - else if (*sys==SYS_SBS) { - switch (sigtype) { - case 0: freq=0; *code=CODE_L1C; break; /* L1C/A */ - case 6: freq=2; *code=CODE_L5I; break; /* L5I (OEM6) */ - default: freq=-1; break; - } - } - if (freq<0) { - trace(2,"cnav signal type error: sys=%d sigtype=%d\n",*sys,sigtype); - return -1; - } - return freq; + * deocode cnav tracking status + * args : unsigned int stat I tracking status field + * int *sys O system (SYS_???) + * int *code O signal code (CODE_L??) + * int *track O tracking state + * (cnav/5) + * 0=L1 idle 8=L2 idle + * 1=L1 sky search 9=L2 p-code align + * 2=L1 wide freq pull-in 10=L2 search + * 3=L1 narrow freq pull-in 11=L2 pll + * 4=L1 pll 12=L2 steering + * 5=L1 reacq + * 6=L1 steering + * 7=L1 fll + * (oem6) + * 0=idle 7=freq-lock loop + * 2=wide freq band pull-in 9=channel alignment + * 3=narrow freq band pull-in 10=code search + * 4=phase lock loop 11=aided phase lock loop + * int *plock O phase-lock flag (0=not locked, 1=locked) + * int *clock O code-lock flag (0=not locked, 1=locked) + * int *parity O parity known flag (0=not known, 1=known) + * int *halfc O phase measurement (0=half-cycle not added, + * 1=added) + * return : signal frequency (0:L1,1:L2,2:L5,3:L6,4:L7,5:L8,-1:error) + * notes : refer [1][3] + *-----------------------------------------------------------------------------*/ +static int decode_trackstat(unsigned int stat, int *sys, int *code, int *track, int *plock, + int *clock, int *parity, int *halfc) { + int satsys, sigtype, freq = 0; + + *track = stat & 0x1F; + *plock = (stat >> 10) & 1; + *parity = (stat >> 11) & 1; + *clock = (stat >> 12) & 1; + satsys = (stat >> 16) & 7; + *halfc = (stat >> 28) & 1; + sigtype = (stat >> 21) & 0x1F; + + switch (satsys) { + case 0: + *sys = SYS_GPS; + break; + case 1: + *sys = SYS_GLO; + break; + case 2: + *sys = SYS_SBS; + break; + case 3: + *sys = SYS_GAL; + break; /* OEM6 */ + case 4: + *sys = SYS_CMP; + break; /* OEM6 F/W 6.400 */ + case 5: + *sys = SYS_QZS; + break; /* OEM6 */ + default: + trace(2, "cnav unknown system: sys=%d\n", satsys); + return -1; + } + if (*sys == SYS_GPS || *sys == SYS_QZS) { + switch (sigtype) { + case 0: + freq = 0; + *code = CODE_L1C; + break; /* L1C/A */ + case 2: + freq = 2; + *code = CODE_L5I; + break; /* L5 */ + case 5: + freq = 0; + *code = CODE_L1P; + break; /* L1P */ + case 9: + freq = 1; + *code = CODE_L2D; + break; /* L2P codeless */ + case 14: + freq = 2; + *code = CODE_L5I; + break; /* L5I */ + case 17: + freq = 1; + *code = CODE_L2X; + break; /* L2C(M+L) */ + default: + freq = -1; + break; + } + } else if (*sys == SYS_GLO) { + switch (sigtype) { + case 0: + freq = 0; + *code = CODE_L1C; + break; /* L1C/A */ + case 1: + freq = 1; + *code = CODE_L2C; + break; /* L2C/A (OEM6) */ + case 5: + freq = 1; + *code = CODE_L2C; + break; /* L2C */ + default: + freq = -1; + break; + } + } else if (*sys == SYS_GAL) { + switch (sigtype) { + case 1: + freq = 0; + *code = CODE_L1B; + break; /* E1B (OEM6) */ + case 2: + freq = 0; + *code = CODE_L1X; + break; /* E1C (OEM6) */ + case 12: + freq = 2; + *code = CODE_L5X; + break; /* E5aQ (OEM6) */ + case 17: + freq = 4; + *code = CODE_L7X; + break; /* E5bQ (OEM6) */ + case 20: + freq = 5; + *code = CODE_L8X; + break; /* AltBOCQ (OEM6) */ + default: + freq = -1; + break; + } + } else if (*sys == SYS_CMP) { + switch (sigtype) { + case 0: + freq = 0; + *code = CODE_L1I; + break; /* B1 with D1 (OEM6) */ + case 1: + freq = 1; + *code = CODE_L7I; + break; /* B2 with D1 (OEM6) */ + case 4: + freq = 0; + *code = CODE_L1I; + break; /* B1 with D2 (OEM6) */ + case 5: + freq = 1; + *code = CODE_L7I; + break; /* B2 with D2 (OEM6) */ + default: + freq = -1; + break; + } + } else if (*sys == SYS_SBS) { + switch (sigtype) { + case 0: + freq = 0; + *code = CODE_L1C; + break; /* L1C/A */ + case 6: + freq = 2; + *code = CODE_L5I; + break; /* L5I (OEM6) */ + default: + freq = -1; + break; + } + } + if (freq < 0) { + trace(2, "cnav signal type error: sys=%d sigtype=%d\n", *sys, sigtype); + return -1; + } + return freq; } /* check code priority and return obs position -------------------------------*/ -static int checkpri(const char *opt, int sys, int code, int freq) -{ - int nex=NEXOBS; /* number of extended obs data */ - - if (sys==SYS_GPS) { - if (strstr(opt,"-GL1P")&&freq==0) return code==CODE_L1P?0:-1; - if (strstr(opt,"-GL2X")&&freq==1) return code==CODE_L2X?1:-1; - if (code==CODE_L1P) return nex<1?-1:NFREQ; - if (code==CODE_L2X) return nex<2?-1:NFREQ+1; - } - else if (sys==SYS_GLO) { - if (strstr(opt,"-RL2C")&&freq==1) return code==CODE_L2C?1:-1; - if (code==CODE_L2C) return nex<1?-1:NFREQ; - } - else if (sys==SYS_GAL) { - if (strstr(opt,"-EL1B")&&freq==0) return code==CODE_L1B?0:-1; - if (code==CODE_L1B) return nex<1?-1:NFREQ; - if (code==CODE_L7Q) return nex<2?-1:NFREQ+1; - if (code==CODE_L8Q) return nex<3?-1:NFREQ+2; - } - return freqbuff+CNAVHLEN; - - trace(3,"decode_rangecmpb: len=%d\n",raw->len); - - nobs=U4(p); - - if (raw->outtype) { - msg=raw->msgtype+strlen(raw->msgtype); - sprintf(msg," nobs=%2d",nobs); +static int decode_rangecmpb(raw_t *raw) { + double psr, adr, adr_rolls, lockt, tt, dop, snr, wavelen; + int i, index, nobs, prn, sat, sys, code, freq, pos; + int track, plock, clock, parity, halfc, lli; + char *msg; + unsigned char *p = raw->buff + CNAVHLEN; + + trace(3, "decode_rangecmpb: len=%d\n", raw->len); + + nobs = U4(p); + + if (raw->outtype) { + msg = raw->msgtype + strlen(raw->msgtype); + sprintf(msg, " nobs=%2d", nobs); + } + if (raw->len < CNAVHLEN + 4 + nobs * 24) { + trace(2, "cnav rangecmpb length error: len=%d nobs=%d\n", raw->len, nobs); + return -1; + } + for (i = 0, p += 4; i < nobs; i++, p += 24) { + /* decode tracking status */ + if ((freq = decode_trackstat(U4(p), &sys, &code, &track, &plock, &clock, &parity, &halfc)) < 0) + continue; + + /* obs position */ + if ((pos = checkpri(raw->opt, sys, code, freq)) < 0) continue; + + prn = U1(p + 17); + if (sys == SYS_GLO) prn -= 37; + + if (!(sat = satno(sys, prn))) { + trace(3, "cnav rangecmpb satellite number error: sys=%d,prn=%d\n", sys, prn); + continue; } - if (raw->lenlen,nobs); - return -1; + if (sys == SYS_GLO && !parity) continue; /* invalid if GLO parity unknown */ + + dop = exsign(U4(p + 4) & 0xFFFFFFF, 28) / 256.0; + psr = (U4(p + 7) >> 4) / 128.0 + U1(p + 11) * 2097152.0; + + if ((wavelen = satwavelen(sat, freq, &raw->nav)) <= 0.0) { + if (sys == SYS_GLO) + wavelen = CLIGHT / (freq == 0 ? FREQ1_GLO : FREQ2_GLO); + else + wavelen = lam_carr[freq]; + } + adr = I4(p + 12) / 256.0; + adr_rolls = (psr / wavelen + adr) / MAXVAL; + adr = -adr + MAXVAL * floor(adr_rolls + (adr_rolls <= 0 ? -0.5 : 0.5)); + + lockt = (U4(p + 18) & 0x1FFFFF) / 32.0; /* lock time */ + if (lockt < 2) parity = 0; /* pseudo-parity */ + + if (raw->tobs[sat - 1][pos].time != 0) { + tt = timediff(raw->time, raw->tobs[sat - 1][pos]); + lli = (lockt < 65535.968 && lockt - raw->lockt[sat - 1][pos] + 0.05 <= tt) ? LLI_SLIP : 0; + } else { + lli = 0; } - for (i=0,p+=4;iopt,sys,code,freq))<0) continue; - - prn=U1(p+17); - if (sys==SYS_GLO) prn-=37; - - if (!(sat=satno(sys,prn))) { - trace(3,"cnav rangecmpb satellite number error: sys=%d,prn=%d\n",sys,prn); - continue; - } - if (sys==SYS_GLO&&!parity) continue; /* invalid if GLO parity unknown */ - - dop=exsign(U4(p+4)&0xFFFFFFF,28)/256.0; - psr=(U4(p+7)>>4)/128.0+U1(p+11)*2097152.0; - - if ((wavelen=satwavelen(sat,freq,&raw->nav))<=0.0) { - if (sys==SYS_GLO) wavelen=CLIGHT/(freq==0?FREQ1_GLO:FREQ2_GLO); - else wavelen=lam_carr[freq]; - } - adr=I4(p+12)/256.0; - adr_rolls=(psr/wavelen+adr)/MAXVAL; - adr=-adr+MAXVAL*floor(adr_rolls+(adr_rolls<=0?-0.5:0.5)); - - lockt=(U4(p+18)&0x1FFFFF)/32.0; /* lock time */ - if (lockt<2) parity=0; /* pseudo-parity */ - - if (raw->tobs[sat-1][pos].time!=0) { - tt=timediff(raw->time,raw->tobs[sat-1][pos]); - lli=(lockt<65535.968&&lockt-raw->lockt[sat-1][pos]+0.05<=tt)?LLI_SLIP:0; - } - else { - lli=0; - } - - if (!parity) lli|=LLI_HALFC; + + if (!parity) lli |= LLI_HALFC; #ifdef RTK_DISABLED - if (halfc ) lli|=LLI_HALFA; + if (halfc) lli |= LLI_HALFA; #else - if (halfc!=raw->halfc[sat-1][pos]) lli|=LLI_SLIP; + if (halfc != raw->halfc[sat - 1][pos]) lli |= LLI_SLIP; #endif - raw->tobs [sat-1][pos]=raw->time; - raw->lockt[sat-1][pos]=lockt; - raw->halfc[sat-1][pos]=halfc; - - snr=((U2(p+20)&0x3FF)>>5)+20.0; - if ((sys!=SYS_GAL&&!clock)||(sys==SYS_GAL&&!plock)) psr=0.0; /* code unlock */ - if (!plock) adr=dop=0.0; /* phase unlock */ - - if (fabs(timediff(raw->obs.data[0].time,raw->time))>1E-9) { - raw->obs.n=0; - } - if ((index=obsindex(&raw->obs,raw->time,sat))>=0) { - raw->obs.data[index].L [pos]=adr; - raw->obs.data[index].P [pos]=psr; - raw->obs.data[index].D [pos]=(float)dop; - raw->obs.data[index].SNR[pos]=0.0<=snr&&snr<255.0?snr:0; - raw->obs.data[index].LLI[pos]=(unsigned char)lli; - raw->obs.data[index].code[pos]=code; + raw->tobs[sat - 1][pos] = raw->time; + raw->lockt[sat - 1][pos] = lockt; + raw->halfc[sat - 1][pos] = halfc; + + snr = ((U2(p + 20) & 0x3FF) >> 5) + 20.0; + if ((sys != SYS_GAL && !clock) || (sys == SYS_GAL && !plock)) psr = 0.0; /* code unlock */ + if (!plock) adr = dop = 0.0; /* phase unlock */ + + if (fabs(timediff(raw->obs.data[0].time, raw->time)) > 1E-9) { + raw->obs.n = 0; + } + if ((index = obsindex(&raw->obs, raw->time, sat)) >= 0) { + raw->obs.data[index].L[pos] = adr; + raw->obs.data[index].P[pos] = psr; + raw->obs.data[index].D[pos] = (float)dop; + raw->obs.data[index].SNR[pos] = 0.0 <= snr && snr < 255.0 ? snr : 0; + raw->obs.data[index].LLI[pos] = (unsigned char)lli; + raw->obs.data[index].code[pos] = code; #ifdef RTK_DISABLED - /* L2C phase shift correction (L2C->L2P) */ - if (code==CODE_L2X) { - raw->obs.data[index].L[pos]+=0.25; - trace(3,"cnav L2C phase shift corrected: prn=%2d\n",prn); - } + /* L2C phase shift correction (L2C->L2P) */ + if (code == CODE_L2X) { + raw->obs.data[index].L[pos] += 0.25; + trace(3, "cnav L2C phase shift corrected: prn=%2d\n", prn); + } #endif - } } - return 1; + } + return 1; } /* decode rangeb -------------------------------------------------------------*/ -static int decode_rangeb(raw_t *raw) -{ - double psr,adr,dop,snr,lockt,tt; - char *msg; - int i,index,nobs,prn,sat,sys,code,freq,pos; - int track,plock,clock,parity,halfc,lli,gfrq; - unsigned char *p=raw->buff+CNAVHLEN; - - trace(3,"decode_rangeb: len=%d\n",raw->len); - - nobs=U4(p); - - if (raw->outtype) { - msg=raw->msgtype+strlen(raw->msgtype); - sprintf(msg," nobs=%2d",nobs); - } - if (raw->lenlen,nobs); - return -1; +static int decode_rangeb(raw_t *raw) { + double psr, adr, dop, snr, lockt, tt; + char *msg; + int i, index, nobs, prn, sat, sys, code, freq, pos; + int track, plock, clock, parity, halfc, lli, gfrq; + unsigned char *p = raw->buff + CNAVHLEN; + + trace(3, "decode_rangeb: len=%d\n", raw->len); + + nobs = U4(p); + + if (raw->outtype) { + msg = raw->msgtype + strlen(raw->msgtype); + sprintf(msg, " nobs=%2d", nobs); + } + if (raw->len < CNAVHLEN + 4 + nobs * 44) { + trace(2, "cnav rangeb length error: len=%d nobs=%d\n", raw->len, nobs); + return -1; + } + for (i = 0, p += 4; i < nobs; i++, p += 44) { + /* decode tracking status */ + if ((freq = decode_trackstat(U4(p + 40), &sys, &code, &track, &plock, &clock, &parity, + &halfc)) < 0) + continue; + + /* obs position */ + if ((pos = checkpri(raw->opt, sys, code, freq)) < 0) continue; + + prn = U2(p); + if (sys == SYS_GLO) prn -= 37; + + if (!(sat = satno(sys, prn))) { + trace(3, "cnav rangeb satellite number error: sys=%d,prn=%d\n", sys, prn); + continue; } - for (i=0,p+=4;iopt,sys,code,freq))<0) continue; - - prn=U2(p); - if (sys==SYS_GLO) prn-=37; - - if (!(sat=satno(sys,prn))) { - trace(3,"cnav rangeb satellite number error: sys=%d,prn=%d\n",sys,prn); - continue; - } - if (sys==SYS_GLO&&!parity) continue; /* invalid if GLO parity unknown */ - - gfrq =U2(p+ 2); - psr =R8(p+ 4); - adr =R8(p+16); - dop =R4(p+28); - snr =R4(p+32); - lockt=R4(p+36); - if (lockt<2) parity=0; /* pseudo-parity */ - - /* set glonass frequency channel number */ - if (sys==SYS_GLO&&raw->nav.geph[prn-1].sat!=sat) { - raw->nav.geph[prn-1].frq=gfrq-7; - } - if (raw->tobs[sat-1][pos].time!=0) { - tt=timediff(raw->time,raw->tobs[sat-1][pos]); - lli=lockt-raw->lockt[sat-1][pos]+0.05<=tt?LLI_SLIP:0; - } - else { - lli=0; - } - if (!parity) lli|=LLI_HALFC; - if (halfc ) lli|=LLI_HALFA; - raw->tobs [sat-1][pos]=raw->time; - raw->lockt[sat-1][pos]=lockt; - raw->halfc[sat-1][pos]=halfc; - - if (!clock) psr=0.0; /* code unlock */ - if (!plock) adr=dop=0.0; /* phase unlock */ - - if (fabs(timediff(raw->obs.data[0].time,raw->time))>1E-9) { - raw->obs.n=0; - } - if ((index=obsindex(&raw->obs,raw->time,sat))>=0) { - raw->obs.data[index].L [pos]=-adr; - raw->obs.data[index].P [pos]=psr; - raw->obs.data[index].D [pos]=(float)dop; - raw->obs.data[index].SNR[pos]=0.0<=snr&&snr<255.0?snr:0; - raw->obs.data[index].LLI[pos]=(unsigned char)lli; - raw->obs.data[index].code[pos]=code; + if (sys == SYS_GLO && !parity) continue; /* invalid if GLO parity unknown */ + + gfrq = U2(p + 2); + psr = R8(p + 4); + adr = R8(p + 16); + dop = R4(p + 28); + snr = R4(p + 32); + lockt = R4(p + 36); + if (lockt < 2) parity = 0; /* pseudo-parity */ + + /* set glonass frequency channel number */ + if (sys == SYS_GLO && raw->nav.geph[prn - 1].sat != sat) { + raw->nav.geph[prn - 1].frq = gfrq - 7; + } + if (raw->tobs[sat - 1][pos].time != 0) { + tt = timediff(raw->time, raw->tobs[sat - 1][pos]); + lli = lockt - raw->lockt[sat - 1][pos] + 0.05 <= tt ? LLI_SLIP : 0; + } else { + lli = 0; + } + if (!parity) lli |= LLI_HALFC; + if (halfc) lli |= LLI_HALFA; + raw->tobs[sat - 1][pos] = raw->time; + raw->lockt[sat - 1][pos] = lockt; + raw->halfc[sat - 1][pos] = halfc; + + if (!clock) psr = 0.0; /* code unlock */ + if (!plock) adr = dop = 0.0; /* phase unlock */ + + if (fabs(timediff(raw->obs.data[0].time, raw->time)) > 1E-9) { + raw->obs.n = 0; + } + if ((index = obsindex(&raw->obs, raw->time, sat)) >= 0) { + raw->obs.data[index].L[pos] = -adr; + raw->obs.data[index].P[pos] = psr; + raw->obs.data[index].D[pos] = (float)dop; + raw->obs.data[index].SNR[pos] = 0.0 <= snr && snr < 255.0 ? snr : 0; + raw->obs.data[index].LLI[pos] = (unsigned char)lli; + raw->obs.data[index].code[pos] = code; #ifdef RTK_DISABLED - /* L2C phase shift correction */ - if (code==CODE_L2X) { - raw->obs.data[index].L[pos]+=0.25; - trace(3,"cnav L2C phase shift corrected: prn=%2d\n",prn); - } + /* L2C phase shift correction */ + if (code == CODE_L2X) { + raw->obs.data[index].L[pos] += 0.25; + trace(3, "cnav L2C phase shift corrected: prn=%2d\n", prn); + } #endif - } } - return 1; + } + return 1; } /* decode rawephemb ----------------------------------------------------------*/ -static int decode_rawephemb(raw_t *raw) -{ - unsigned char *p=raw->buff+CNAVHLEN; - eph_t eph={0}; - int prn,sat; - - trace(3,"decode_rawephemb: len=%d\n",raw->len); - - if (raw->lenlen); - return -1; - } - prn=U4(p); - if (!(sat=satno(SYS_GPS,prn))) { - trace(2,"cnav rawephemb satellite number error: prn=%d\n",prn); - return -1; - } - if (decode_frame(p+ 12,&eph,NULL,NULL,NULL,NULL)!=1|| - decode_frame(p+ 42,&eph,NULL,NULL,NULL,NULL)!=2|| - decode_frame(p+ 72,&eph,NULL,NULL,NULL,NULL)!=3) { - trace(2,"cnav rawephemb subframe error: prn=%d\n",prn); - return -1; - } - if (!strstr(raw->opt,"-EPHALL")) { - if (eph.iode==raw->nav.eph[sat-1].iode) return 0; /* unchanged */ - } - eph.sat=sat; - raw->nav.eph[sat-1]=eph; - raw->ephsat=sat; - trace(4,"decode_rawephemb: sat=%2d\n",sat); - return 2; +static int decode_rawephemb(raw_t *raw) { + unsigned char *p = raw->buff + CNAVHLEN; + eph_t eph = {0}; + int prn, sat; + + trace(3, "decode_rawephemb: len=%d\n", raw->len); + + if (raw->len < CNAVHLEN + 102) { + trace(2, "cnav rawephemb length error: len=%d\n", raw->len); + return -1; + } + prn = U4(p); + if (!(sat = satno(SYS_GPS, prn))) { + trace(2, "cnav rawephemb satellite number error: prn=%d\n", prn); + return -1; + } + if (decode_frame(p + 12, &eph, NULL, NULL, NULL, NULL) != 1 || + decode_frame(p + 42, &eph, NULL, NULL, NULL, NULL) != 2 || + decode_frame(p + 72, &eph, NULL, NULL, NULL, NULL) != 3) { + trace(2, "cnav rawephemb subframe error: prn=%d\n", prn); + return -1; + } + if (!strstr(raw->opt, "-EPHALL")) { + if (eph.iode == raw->nav.eph[sat - 1].iode) return 0; /* unchanged */ + } + eph.sat = sat; + raw->nav.eph[sat - 1] = eph; + raw->ephsat = sat; + trace(4, "decode_rawephemb: sat=%2d\n", sat); + return 2; } /* decode ionutcb ------------------------------------------------------------*/ -static int decode_ionutcb(raw_t *raw) -{ - unsigned char *p=raw->buff+CNAVHLEN; - int i; - - trace(3,"decode_ionutcb: len=%d\n",raw->len); - - if (raw->lenlen); - return -1; - } - for (i=0;i<8;i++) raw->nav.ion_gps[i]=R8(p+i*8); - raw->nav.utc_gps[0]=R8(p+72); - raw->nav.utc_gps[1]=R8(p+80); - raw->nav.utc_gps[2]=U4(p+68); - raw->nav.utc_gps[3]=U4(p+64); - raw->nav.leaps =I4(p+96); - return 9; +static int decode_ionutcb(raw_t *raw) { + unsigned char *p = raw->buff + CNAVHLEN; + int i; + + trace(3, "decode_ionutcb: len=%d\n", raw->len); + + if (raw->len < CNAVHLEN + 108) { + trace(2, "cnav ionutcb length error: len=%d\n", raw->len); + return -1; + } + for (i = 0; i < 8; i++) raw->nav.ion_gps[i] = R8(p + i * 8); + raw->nav.utc_gps[0] = R8(p + 72); + raw->nav.utc_gps[1] = R8(p + 80); + raw->nav.utc_gps[2] = U4(p + 68); + raw->nav.utc_gps[3] = U4(p + 64); + raw->nav.leaps = I4(p + 96); + return 9; } /* decode rawwaasframeb ------------------------------------------------------*/ -static int decode_rawwaasframeb(raw_t *raw) -{ - unsigned char *p=raw->buff+CNAVHLEN; - int i,prn; - - trace(3,"decode_rawwaasframeb: len=%d\n",raw->len); - - if (raw->lenlen); - return -1; - } - prn=U4(p+4); - - if (MINPRNQZS_S<=prn&&prn<=MAXPRNQZS_S) { - prn+=10; /* QZSS SAIF PRN -> QZSS PRN */ - } - else if (prnsbsmsg.tow=(int)time2gpst(raw->time,&raw->sbsmsg.week); - raw->sbsmsg.prn=prn; - for (i=0,p+=12;i<29;i++,p++) raw->sbsmsg.msg[i]=*p; - return 3; +static int decode_rawwaasframeb(raw_t *raw) { + unsigned char *p = raw->buff + CNAVHLEN; + int i, prn; + + trace(3, "decode_rawwaasframeb: len=%d\n", raw->len); + + if (raw->len < CNAVHLEN + 48) { + trace(2, "cnav rawwaasframeb length error: len=%d\n", raw->len); + return -1; + } + prn = U4(p + 4); + + if (MINPRNQZS_S <= prn && prn <= MAXPRNQZS_S) { + prn += 10; /* QZSS SAIF PRN -> QZSS PRN */ + } else if (prn < MINPRNSBS || MAXPRNSBS < prn) + return 0; + + raw->sbsmsg.tow = (int)time2gpst(raw->time, &raw->sbsmsg.week); + raw->sbsmsg.prn = prn; + for (i = 0, p += 12; i < 29; i++, p++) raw->sbsmsg.msg[i] = *p; + return 3; } /* decode rawsbasframeb ------------------------------------------------------*/ -static int decode_rawsbasframeb(raw_t *raw) -{ - trace(3,"decode_rawsbasframeb: len=%d\n",raw->len); - - /* format same as rawwaasframeb */ - return decode_rawwaasframeb(raw); +static int decode_rawsbasframeb(raw_t *raw) { + trace(3, "decode_rawsbasframeb: len=%d\n", raw->len); + + /* format same as rawwaasframeb */ + return decode_rawwaasframeb(raw); } /* decode gloephemerisb ------------------------------------------------------*/ -static int decode_gloephemerisb(raw_t *raw) -{ - unsigned char *p=raw->buff+CNAVHLEN; - geph_t geph={0}; - char *msg; - double tow,tof,toff; - int prn,sat,week; - - trace(3,"decode_gloephemerisb: len=%d\n",raw->len); - - if (raw->lenlen); - return -1; - } - prn =U2(p)-37; - - if (raw->outtype) { - msg=raw->msgtype+strlen(raw->msgtype); - sprintf(msg," prn=%3d",prn); - } - if (!(sat=satno(SYS_GLO,prn))) { - trace(2,"cnav gloephemerisb prn error: prn=%d\n",prn); - return -1; - } - geph.frq =U2(p+ 2)+OFF_FRQNO; - week =U2(p+ 6); - tow =floor(U4(p+8)/1000.0+0.5); /* rounded to integer sec */ - toff =U4(p+ 12); - geph.iode =U4(p+ 20)&0x7F; - geph.svh =U4(p+ 24); - geph.pos[0]=R8(p+ 28); - geph.pos[1]=R8(p+ 36); - geph.pos[2]=R8(p+ 44); - geph.vel[0]=R8(p+ 52); - geph.vel[1]=R8(p+ 60); - geph.vel[2]=R8(p+ 68); - geph.acc[0]=R8(p+ 76); - geph.acc[1]=R8(p+ 84); - geph.acc[2]=R8(p+ 92); - geph.taun =R8(p+100); - geph.gamn =R8(p+116); - tof =U4(p+124)-toff; /* glonasst->gpst */ - geph.age =U4(p+136); - geph.toe=gpst2time(week,tow); - tof+=floor(tow/86400.0)*86400; - if (toftow+43200.0) tof-=86400.0; - geph.tof=gpst2time(week,tof); - - if (!strstr(raw->opt,"-EPHALL")) { - if (fabs(timediff(geph.toe,raw->nav.geph[prn-1].toe))<1.0&& - geph.svh==raw->nav.geph[prn-1].svh) return 0; /* unchanged */ - } - geph.sat=sat; - raw->nav.geph[prn-1]=geph; - raw->ephsat=sat; - return 2; +static int decode_gloephemerisb(raw_t *raw) { + unsigned char *p = raw->buff + CNAVHLEN; + geph_t geph = {0}; + char *msg; + double tow, tof, toff; + int prn, sat, week; + + trace(3, "decode_gloephemerisb: len=%d\n", raw->len); + + if (raw->len < CNAVHLEN + 144) { + trace(2, "cnav gloephemerisb length error: len=%d\n", raw->len); + return -1; + } + prn = U2(p) - 37; + + if (raw->outtype) { + msg = raw->msgtype + strlen(raw->msgtype); + sprintf(msg, " prn=%3d", prn); + } + if (!(sat = satno(SYS_GLO, prn))) { + trace(2, "cnav gloephemerisb prn error: prn=%d\n", prn); + return -1; + } + geph.frq = U2(p + 2) + OFF_FRQNO; + week = U2(p + 6); + tow = floor(U4(p + 8) / 1000.0 + 0.5); /* rounded to integer sec */ + toff = U4(p + 12); + geph.iode = U4(p + 20) & 0x7F; + geph.svh = U4(p + 24); + geph.pos[0] = R8(p + 28); + geph.pos[1] = R8(p + 36); + geph.pos[2] = R8(p + 44); + geph.vel[0] = R8(p + 52); + geph.vel[1] = R8(p + 60); + geph.vel[2] = R8(p + 68); + geph.acc[0] = R8(p + 76); + geph.acc[1] = R8(p + 84); + geph.acc[2] = R8(p + 92); + geph.taun = R8(p + 100); + geph.gamn = R8(p + 116); + tof = U4(p + 124) - toff; /* glonasst->gpst */ + geph.age = U4(p + 136); + geph.toe = gpst2time(week, tow); + tof += floor(tow / 86400.0) * 86400; + if (tof < tow - 43200.0) + tof += 86400.0; + else if (tof > tow + 43200.0) + tof -= 86400.0; + geph.tof = gpst2time(week, tof); + + if (!strstr(raw->opt, "-EPHALL")) { + if (fabs(timediff(geph.toe, raw->nav.geph[prn - 1].toe)) < 1.0 && + geph.svh == raw->nav.geph[prn - 1].svh) + return 0; /* unchanged */ + } + geph.sat = sat; + raw->nav.geph[prn - 1] = geph; + raw->ephsat = sat; + return 2; } /* decode qzss rawephemb -----------------------------------------------------*/ -static int decode_qzssrawephemb(raw_t *raw) -{ - unsigned char *p=raw->buff+CNAVHLEN,*q; - eph_t eph={0}; - char *msg; - int i,prn,id,sat; - - trace(3,"decode_qzssrawephemb: len=%d\n",raw->len); - - if (raw->lenlen); - return -1; - } - prn=U4(p); - id =U4(p+4); - - if (raw->outtype) { - msg=raw->msgtype+strlen(raw->msgtype); - sprintf(msg," prn=%3d id=%d",prn,id); - } - if (!(sat=satno(SYS_QZS,prn))) { - trace(2,"cnav qzssrawephemb satellite number error: prn=%d\n",prn); - return -1; - } - if (id<1||3subfrm[sat-1]+(id-1)*30; - for (i=0;i<30;i++) *q++=p[8+i]; - - if (id<3) return 0; - if (decode_frame(raw->subfrm[sat-1] ,&eph,NULL,NULL,NULL,NULL)!=1|| - decode_frame(raw->subfrm[sat-1]+30,&eph,NULL,NULL,NULL,NULL)!=2|| - decode_frame(raw->subfrm[sat-1]+60,&eph,NULL,NULL,NULL,NULL)!=3) { - return 0; - } - if (!strstr(raw->opt,"-EPHALL")) { - if (eph.iodc==raw->nav.eph[sat-1].iodc&& - eph.iode==raw->nav.eph[sat-1].iode) return 0; /* unchanged */ - } - eph.sat=sat; - raw->nav.eph[sat-1]=eph; - raw->ephsat=sat; - trace(4,"decode_qzssrawephemb: sat=%2d\n",sat); - return 2; +static int decode_qzssrawephemb(raw_t *raw) { + unsigned char *p = raw->buff + CNAVHLEN, *q; + eph_t eph = {0}; + char *msg; + int i, prn, id, sat; + + trace(3, "decode_qzssrawephemb: len=%d\n", raw->len); + + if (raw->len < CNAVHLEN + 44) { + trace(2, "cnav qzssrawephemb length error: len=%d\n", raw->len); + return -1; + } + prn = U4(p); + id = U4(p + 4); + + if (raw->outtype) { + msg = raw->msgtype + strlen(raw->msgtype); + sprintf(msg, " prn=%3d id=%d", prn, id); + } + if (!(sat = satno(SYS_QZS, prn))) { + trace(2, "cnav qzssrawephemb satellite number error: prn=%d\n", prn); + return -1; + } + if (id < 1 || 3 < id) return 0; + + q = raw->subfrm[sat - 1] + (id - 1) * 30; + for (i = 0; i < 30; i++) *q++ = p[8 + i]; + + if (id < 3) return 0; + if (decode_frame(raw->subfrm[sat - 1], &eph, NULL, NULL, NULL, NULL) != 1 || + decode_frame(raw->subfrm[sat - 1] + 30, &eph, NULL, NULL, NULL, NULL) != 2 || + decode_frame(raw->subfrm[sat - 1] + 60, &eph, NULL, NULL, NULL, NULL) != 3) { + return 0; + } + if (!strstr(raw->opt, "-EPHALL")) { + if (eph.iodc == raw->nav.eph[sat - 1].iodc && eph.iode == raw->nav.eph[sat - 1].iode) + return 0; /* unchanged */ + } + eph.sat = sat; + raw->nav.eph[sat - 1] = eph; + raw->ephsat = sat; + trace(4, "decode_qzssrawephemb: sat=%2d\n", sat); + return 2; } /* decode qzss rawsubframeb --------------------------------------------------*/ -static int decode_qzssrawsubframeb(raw_t *raw) -{ - unsigned char *p=raw->buff+CNAVHLEN; - eph_t eph={0}; - char *msg; - int prn,sat; - - trace(3,"decode_qzssrawsubframeb: len=%d\n",raw->len); - - if (raw->lenlen); - return -1; - } - prn=U4(p); - - if (raw->outtype) { - msg=raw->msgtype+strlen(raw->msgtype); - sprintf(msg," prn=%3d",prn); - } - if (!(sat=satno(SYS_QZS,prn))) { - trace(2,"cnav qzssrawephemb satellite number error: prn=%d\n",prn); - return -1; - } - if (decode_frame(p+12,&eph,NULL,NULL,NULL,NULL)!=1|| - decode_frame(p+42,&eph,NULL,NULL,NULL,NULL)!=2|| - decode_frame(p+72,&eph,NULL,NULL,NULL,NULL)!=3) { - return 0; - } - if (!strstr(raw->opt,"-EPHALL")) { - if (eph.iodc==raw->nav.eph[sat-1].iodc&& - eph.iode==raw->nav.eph[sat-1].iode) return 0; /* unchanged */ - } - eph.sat=sat; - raw->nav.eph[sat-1]=eph; - raw->ephsat=sat; - trace(4,"decode_qzssrawsubframeb: sat=%2d\n",sat); - return 2; +static int decode_qzssrawsubframeb(raw_t *raw) { + unsigned char *p = raw->buff + CNAVHLEN; + eph_t eph = {0}; + char *msg; + int prn, sat; + + trace(3, "decode_qzssrawsubframeb: len=%d\n", raw->len); + + if (raw->len < CNAVHLEN + 44) { + trace(2, "cnav qzssrawsubframeb length error: len=%d\n", raw->len); + return -1; + } + prn = U4(p); + + if (raw->outtype) { + msg = raw->msgtype + strlen(raw->msgtype); + sprintf(msg, " prn=%3d", prn); + } + if (!(sat = satno(SYS_QZS, prn))) { + trace(2, "cnav qzssrawephemb satellite number error: prn=%d\n", prn); + return -1; + } + if (decode_frame(p + 12, &eph, NULL, NULL, NULL, NULL) != 1 || + decode_frame(p + 42, &eph, NULL, NULL, NULL, NULL) != 2 || + decode_frame(p + 72, &eph, NULL, NULL, NULL, NULL) != 3) { + return 0; + } + if (!strstr(raw->opt, "-EPHALL")) { + if (eph.iodc == raw->nav.eph[sat - 1].iodc && eph.iode == raw->nav.eph[sat - 1].iode) + return 0; /* unchanged */ + } + eph.sat = sat; + raw->nav.eph[sat - 1] = eph; + raw->ephsat = sat; + trace(4, "decode_qzssrawsubframeb: sat=%2d\n", sat); + return 2; } /* decode qzssionutcb --------------------------------------------------------*/ -static int decode_qzssionutcb(raw_t *raw) -{ - unsigned char *p=raw->buff+CNAVHLEN; - int i; - - trace(3,"decode_qzssionutcb: len=%d\n",raw->len); - - if (raw->lenlen); - return -1; - } - for (i=0;i<8;i++) raw->nav.ion_qzs[i]=R8(p+i*8); - raw->nav.utc_qzs[0]=R8(p+72); - raw->nav.utc_qzs[1]=R8(p+80); - raw->nav.utc_qzs[2]=U4(p+68); - raw->nav.utc_qzs[3]=U4(p+64); - raw->nav.leaps =I4(p+96); - return 9; +static int decode_qzssionutcb(raw_t *raw) { + unsigned char *p = raw->buff + CNAVHLEN; + int i; + + trace(3, "decode_qzssionutcb: len=%d\n", raw->len); + + if (raw->len < CNAVHLEN + 108) { + trace(2, "cnav qzssionutcb length error: len=%d\n", raw->len); + return -1; + } + for (i = 0; i < 8; i++) raw->nav.ion_qzs[i] = R8(p + i * 8); + raw->nav.utc_qzs[0] = R8(p + 72); + raw->nav.utc_qzs[1] = R8(p + 80); + raw->nav.utc_qzs[2] = U4(p + 68); + raw->nav.utc_qzs[3] = U4(p + 64); + raw->nav.leaps = I4(p + 96); + return 9; } /* decode galephemerisb ------------------------------------------------------*/ -static int decode_galephemerisb(raw_t *raw) -{ - eph_t eph={0}; - unsigned char *p=raw->buff+CNAVHLEN; - double tow,sqrtA,af0_fnav,af1_fnav,af2_fnav,af0_inav,af1_inav,af2_inav,tt; - char *msg; - int prn,rcv_fnav,rcv_inav,svh_e1b,svh_e5a,svh_e5b,dvs_e1b,dvs_e5a,dvs_e5b; - int toc_fnav,toc_inav,week,sel_nav=0; - - trace(3,"decode_galephemerisb: len=%d\n",raw->len); - - if (raw->lenlen); - return -1; - } - prn =U4(p); p+=4; - rcv_fnav =U4(p)&1; p+=4; - rcv_inav =U4(p)&1; p+=4; - svh_e1b =U1(p)&3; p+=1; - svh_e5a =U1(p)&3; p+=1; - svh_e5b =U1(p)&3; p+=1; - dvs_e1b =U1(p)&1; p+=1; - dvs_e5a =U1(p)&1; p+=1; - dvs_e5b =U1(p)&1; p+=1; - eph.sva =U1(p); p+=1+1; /* SISA */ - eph.iode =U4(p); p+=4; /* IODNav */ - eph.toes =U4(p); p+=4; - sqrtA =R8(p); p+=8; - eph.deln =R8(p); p+=8; - eph.M0 =R8(p); p+=8; - eph.e =R8(p); p+=8; - eph.omg =R8(p); p+=8; - eph.cuc =R8(p); p+=8; - eph.cus =R8(p); p+=8; - eph.crc =R8(p); p+=8; - eph.crs =R8(p); p+=8; - eph.cic =R8(p); p+=8; - eph.cis =R8(p); p+=8; - eph.i0 =R8(p); p+=8; - eph.idot =R8(p); p+=8; - eph.OMG0 =R8(p); p+=8; - eph.OMGd =R8(p); p+=8; - toc_fnav =U4(p); p+=4; - af0_fnav =R8(p); p+=8; - af1_fnav =R8(p); p+=8; - af2_fnav =R8(p); p+=8; - toc_inav =U4(p); p+=4; - af0_inav =R8(p); p+=8; - af1_inav =R8(p); p+=8; - af2_inav =R8(p); p+=8; - eph.tgd[0]=R8(p); p+=8; /* BGD: E5A-E1 (s) */ - eph.tgd[1]=R8(p); /* BGD: E5B-E1 (s) */ - eph.iodc =eph.iode; - eph.svh =(svh_e5b<<7)|(dvs_e5b<<6)|(svh_e5a<<4)|(dvs_e5a<<3)| - (svh_e1b<<1)|dvs_e1b; - - /* ephemeris selection (0:INAV,1:FNAV) */ - if (strstr(raw->opt,"-GALINAV")) sel_nav=0; - else if (strstr(raw->opt,"-GALFNAV")) sel_nav=1; - else if (!rcv_inav&&rcv_fnav) sel_nav=1; - - eph.A =sqrtA*sqrtA; - eph.f0 =sel_nav?af0_fnav:af0_inav; - eph.f1 =sel_nav?af1_fnav:af1_inav; - eph.f2 =sel_nav?af2_fnav:af2_inav; - eph.code =sel_nav?2:1; /* data source 1:I/NAV E1B,2:F/NAV E5a-I */ - - if (raw->outtype) { - msg=raw->msgtype+strlen(raw->msgtype); - sprintf(msg," prn=%3d iod=%3d toes=%6.0f",prn,eph.iode,eph.toes); - } - if (!(eph.sat=satno(SYS_GAL,prn))) { - trace(2,"oemv galephemeris satellite error: prn=%d\n",prn); - return -1; - } - tow=time2gpst(raw->time,&week); - eph.week=week; /* gps-week = gal-week */ - eph.toe=gpst2time(eph.week,eph.toes); - - /* for week-handover problem */ - tt=timediff(eph.toe,raw->time); - if (tt<-302400.0) eph.week++; - else if (tt> 302400.0) eph.week--; - eph.toe=gpst2time(eph.week,eph.toes); - eph.toc=adjweek(eph.toe,sel_nav?toc_fnav:toc_inav); - eph.ttr=adjweek(eph.toe,tow); - - if (!strstr(raw->opt,"-EPHALL")) { - if (raw->nav.eph[eph.sat-1].iode==eph.iode&& - raw->nav.eph[eph.sat-1].code==eph.code) return 0; /* unchanged */ - } - raw->nav.eph[eph.sat-1]=eph; - raw->ephsat=eph.sat; - return 2; +static int decode_galephemerisb(raw_t *raw) { + eph_t eph = {0}; + unsigned char *p = raw->buff + CNAVHLEN; + double tow, sqrtA, af0_fnav, af1_fnav, af2_fnav, af0_inav, af1_inav, af2_inav, tt; + char *msg; + int prn, rcv_fnav, rcv_inav, svh_e1b, svh_e5a, svh_e5b, dvs_e1b, dvs_e5a, dvs_e5b; + int toc_fnav, toc_inav, week, sel_nav = 0; + + trace(3, "decode_galephemerisb: len=%d\n", raw->len); + + if (raw->len < CNAVHLEN + 220) { + trace(2, "cnav galephemrisb length error: len=%d\n", raw->len); + return -1; + } + prn = U4(p); + p += 4; + rcv_fnav = U4(p) & 1; + p += 4; + rcv_inav = U4(p) & 1; + p += 4; + svh_e1b = U1(p) & 3; + p += 1; + svh_e5a = U1(p) & 3; + p += 1; + svh_e5b = U1(p) & 3; + p += 1; + dvs_e1b = U1(p) & 1; + p += 1; + dvs_e5a = U1(p) & 1; + p += 1; + dvs_e5b = U1(p) & 1; + p += 1; + eph.sva = U1(p); + p += 1 + 1; /* SISA */ + eph.iode = U4(p); + p += 4; /* IODNav */ + eph.toes = U4(p); + p += 4; + sqrtA = R8(p); + p += 8; + eph.deln = R8(p); + p += 8; + eph.M0 = R8(p); + p += 8; + eph.e = R8(p); + p += 8; + eph.omg = R8(p); + p += 8; + eph.cuc = R8(p); + p += 8; + eph.cus = R8(p); + p += 8; + eph.crc = R8(p); + p += 8; + eph.crs = R8(p); + p += 8; + eph.cic = R8(p); + p += 8; + eph.cis = R8(p); + p += 8; + eph.i0 = R8(p); + p += 8; + eph.idot = R8(p); + p += 8; + eph.OMG0 = R8(p); + p += 8; + eph.OMGd = R8(p); + p += 8; + toc_fnav = U4(p); + p += 4; + af0_fnav = R8(p); + p += 8; + af1_fnav = R8(p); + p += 8; + af2_fnav = R8(p); + p += 8; + toc_inav = U4(p); + p += 4; + af0_inav = R8(p); + p += 8; + af1_inav = R8(p); + p += 8; + af2_inav = R8(p); + p += 8; + eph.tgd[0] = R8(p); + p += 8; /* BGD: E5A-E1 (s) */ + eph.tgd[1] = R8(p); /* BGD: E5B-E1 (s) */ + eph.iodc = eph.iode; + eph.svh = + (svh_e5b << 7) | (dvs_e5b << 6) | (svh_e5a << 4) | (dvs_e5a << 3) | (svh_e1b << 1) | dvs_e1b; + + /* ephemeris selection (0:INAV,1:FNAV) */ + if (strstr(raw->opt, "-GALINAV")) + sel_nav = 0; + else if (strstr(raw->opt, "-GALFNAV")) + sel_nav = 1; + else if (!rcv_inav && rcv_fnav) + sel_nav = 1; + + eph.A = sqrtA * sqrtA; + eph.f0 = sel_nav ? af0_fnav : af0_inav; + eph.f1 = sel_nav ? af1_fnav : af1_inav; + eph.f2 = sel_nav ? af2_fnav : af2_inav; + eph.code = sel_nav ? 2 : 1; /* data source 1:I/NAV E1B,2:F/NAV E5a-I */ + + if (raw->outtype) { + msg = raw->msgtype + strlen(raw->msgtype); + sprintf(msg, " prn=%3d iod=%3d toes=%6.0f", prn, eph.iode, eph.toes); + } + if (!(eph.sat = satno(SYS_GAL, prn))) { + trace(2, "oemv galephemeris satellite error: prn=%d\n", prn); + return -1; + } + tow = time2gpst(raw->time, &week); + eph.week = week; /* gps-week = gal-week */ + eph.toe = gpst2time(eph.week, eph.toes); + + /* for week-handover problem */ + tt = timediff(eph.toe, raw->time); + if (tt < -302400.0) + eph.week++; + else if (tt > 302400.0) + eph.week--; + eph.toe = gpst2time(eph.week, eph.toes); + eph.toc = adjweek(eph.toe, sel_nav ? toc_fnav : toc_inav); + eph.ttr = adjweek(eph.toe, tow); + + if (!strstr(raw->opt, "-EPHALL")) { + if (raw->nav.eph[eph.sat - 1].iode == eph.iode && raw->nav.eph[eph.sat - 1].code == eph.code) + return 0; /* unchanged */ + } + raw->nav.eph[eph.sat - 1] = eph; + raw->ephsat = eph.sat; + return 2; } /* decode galalmanacb --------------------------------------------------------*/ -static int decode_galalmanacb(raw_t *raw) -{ - alm_t alm={0}; - unsigned char *p=raw->buff+CNAVHLEN; - double dsqrtA,sqrtA=sqrt(29601297.0); - int prn,rcv_fnav,rcv_inav,svh_e1b,svh_e5a,svh_e5b,ioda; - - trace(3,"decode_galalmanacb: len=%d\n",raw->len); - - if (raw->lenlen); - return -1; - } - prn =U4(p); p+=4; - rcv_fnav=U4(p)&1; p+=4; - rcv_inav=U4(p)&1; p+=4; - svh_e1b =U1(p)&3; p+=1; - svh_e5a =U1(p)&3; p+=1; - svh_e5b =U1(p)&3; p+=1+1; - ioda =U4(p); p+=4; - alm.week=U4(p); p+=4; /* gst week */ - alm.toas=U4(p); p+=4; - alm.e =R8(p); p+=8; - alm.OMGd=R8(p); p+=8; - alm.OMG0=R8(p); p+=8; - alm.omg =R8(p); p+=8; - alm.M0 =R8(p); p+=8; - alm.f0 =R8(p); p+=8; - alm.f1 =R8(p); p+=8; - dsqrtA =R8(p); p+=8; - alm.i0 =(R8(p)+56.0)*D2R; - alm.svh =(svh_e5b<<7)|(svh_e5a<<4)|(svh_e1b<<1); - alm.A =(sqrtA+dsqrtA)*(sqrtA+dsqrtA); - - if (!(alm.sat=satno(SYS_GAL,prn))) { - trace(2,"oemv galalmanac satellite error: prn=%d\n",prn); - return -1; - } - alm.toa=gst2time(alm.week,alm.toas); - raw->nav.alm[alm.sat-1]=alm; - return 0; +static int decode_galalmanacb(raw_t *raw) { + alm_t alm = {0}; + unsigned char *p = raw->buff + CNAVHLEN; + double dsqrtA, sqrtA = sqrt(29601297.0); + int prn, rcv_fnav, rcv_inav, svh_e1b, svh_e5a, svh_e5b, ioda; + + trace(3, "decode_galalmanacb: len=%d\n", raw->len); + + if (raw->len < CNAVHLEN + 100) { + trace(2, "cnav galephemrisb length error: len=%d\n", raw->len); + return -1; + } + prn = U4(p); + p += 4; + rcv_fnav = U4(p) & 1; + p += 4; + rcv_inav = U4(p) & 1; + p += 4; + svh_e1b = U1(p) & 3; + p += 1; + svh_e5a = U1(p) & 3; + p += 1; + svh_e5b = U1(p) & 3; + p += 1 + 1; + ioda = U4(p); + p += 4; + alm.week = U4(p); + p += 4; /* gst week */ + alm.toas = U4(p); + p += 4; + alm.e = R8(p); + p += 8; + alm.OMGd = R8(p); + p += 8; + alm.OMG0 = R8(p); + p += 8; + alm.omg = R8(p); + p += 8; + alm.M0 = R8(p); + p += 8; + alm.f0 = R8(p); + p += 8; + alm.f1 = R8(p); + p += 8; + dsqrtA = R8(p); + p += 8; + alm.i0 = (R8(p) + 56.0) * D2R; + alm.svh = (svh_e5b << 7) | (svh_e5a << 4) | (svh_e1b << 1); + alm.A = (sqrtA + dsqrtA) * (sqrtA + dsqrtA); + + if (!(alm.sat = satno(SYS_GAL, prn))) { + trace(2, "oemv galalmanac satellite error: prn=%d\n", prn); + return -1; + } + alm.toa = gst2time(alm.week, alm.toas); + raw->nav.alm[alm.sat - 1] = alm; + return 0; } /* decode galclockb ----------------------------------------------------------*/ -static int decode_galclockb(raw_t *raw) -{ - unsigned char *p=raw->buff+CNAVHLEN; - double a0,a1,a0g,a1g; - int leaps,tot,wnt,wnlsf,dn,dtlsf,t0g,wn0g; - - trace(3,"decode_galclockb: len=%d\n",raw->len); - - if (raw->lenlen); - return -1; - } - a0 =R8(p); p+=8; - a1 =R8(p); p+=8; - leaps=I4(p); p+=4; - tot =U4(p); p+=4; - wnt =U4(p); p+=4; - wnlsf=U4(p); p+=4; - dn =U4(p); p+=4; - dtlsf=U4(p); p+=4; - a0g =R8(p); p+=8; - a1g =R8(p); p+=8; - t0g =U4(p); p+=4; - wn0g =U4(p); - - raw->nav.utc_gal[0]=a0; - raw->nav.utc_gal[1]=a1; - raw->nav.utc_gal[2]=tot; /* utc reference tow (s) */ - raw->nav.utc_gal[3]=wnt; /* utc reference week */ - return 9; +static int decode_galclockb(raw_t *raw) { + unsigned char *p = raw->buff + CNAVHLEN; + double a0, a1, a0g, a1g; + int leaps, tot, wnt, wnlsf, dn, dtlsf, t0g, wn0g; + + trace(3, "decode_galclockb: len=%d\n", raw->len); + + if (raw->len < CNAVHLEN + 64) { + trace(2, "cnav galclockb length error: len=%d\n", raw->len); + return -1; + } + a0 = R8(p); + p += 8; + a1 = R8(p); + p += 8; + leaps = I4(p); + p += 4; + tot = U4(p); + p += 4; + wnt = U4(p); + p += 4; + wnlsf = U4(p); + p += 4; + dn = U4(p); + p += 4; + dtlsf = U4(p); + p += 4; + a0g = R8(p); + p += 8; + a1g = R8(p); + p += 8; + t0g = U4(p); + p += 4; + wn0g = U4(p); + + raw->nav.utc_gal[0] = a0; + raw->nav.utc_gal[1] = a1; + raw->nav.utc_gal[2] = tot; /* utc reference tow (s) */ + raw->nav.utc_gal[3] = wnt; /* utc reference week */ + return 9; } /* decode galionob -----------------------------------------------------------*/ -static int decode_galionob(raw_t *raw) -{ - unsigned char *p=raw->buff+CNAVHLEN; - double ai[3]; - int i,sf[5]; - - trace(3,"decode_galionob: len=%d\n",raw->len); - - if (raw->lenlen); - return -1; - } - ai[0]=R8(p); p+=8; - ai[1]=R8(p); p+=8; - ai[2]=R8(p); p+=8; - sf[0]=U1(p); p+=1; - sf[1]=U1(p); p+=1; - sf[2]=U1(p); p+=1; - sf[3]=U1(p); p+=1; - sf[4]=U1(p); - - for (i=0;i<3;i++) raw->nav.ion_gal[i]=ai[i]; - return 9; +static int decode_galionob(raw_t *raw) { + unsigned char *p = raw->buff + CNAVHLEN; + double ai[3]; + int i, sf[5]; + + trace(3, "decode_galionob: len=%d\n", raw->len); + + if (raw->len < CNAVHLEN + 29) { + trace(2, "cnav galionob length error: len=%d\n", raw->len); + return -1; + } + ai[0] = R8(p); + p += 8; + ai[1] = R8(p); + p += 8; + ai[2] = R8(p); + p += 8; + sf[0] = U1(p); + p += 1; + sf[1] = U1(p); + p += 1; + sf[2] = U1(p); + p += 1; + sf[3] = U1(p); + p += 1; + sf[4] = U1(p); + + for (i = 0; i < 3; i++) raw->nav.ion_gal[i] = ai[i]; + return 9; } /* decode galfnavrawpageb ----------------------------------------------------*/ -static int decode_galfnavrawpageb(raw_t *raw) -{ - unsigned char *p=raw->buff+CNAVHLEN; - unsigned char buff[27]; - int i,sigch,satid,page; - - trace(3,"decode_galfnavrawpageb: len=%d\n",raw->len); - - if (raw->lenlen); - return -1; - } - sigch=U4(p); p+=4; - satid=U4(p); p+=4; - for (i=0;i<27;i++) { - buff[i]=U1(p); p+=1; - } - page=getbitu(buff,0,6); +static int decode_galfnavrawpageb(raw_t *raw) { + unsigned char *p = raw->buff + CNAVHLEN; + unsigned char buff[27]; + int i, sigch, satid, page; - char tstr[40]; - trace(3,"%s E%2d FNAV (%2d) ",time2str(raw->time,tstr,0),satid,page); - traceb(3,buff,27); - - return 0; + trace(3, "decode_galfnavrawpageb: len=%d\n", raw->len); + + if (raw->len < CNAVHLEN + 35) { + trace(2, "cnav galfnavrawpageb length error: len=%d\n", raw->len); + return -1; + } + sigch = U4(p); + p += 4; + satid = U4(p); + p += 4; + for (i = 0; i < 27; i++) { + buff[i] = U1(p); + p += 1; + } + page = getbitu(buff, 0, 6); + + char tstr[40]; + trace(3, "%s E%2d FNAV (%2d) ", time2str(raw->time, tstr, 0), satid, page); + traceb(3, buff, 27); + + return 0; } /* decode galinavrawwordb ----------------------------------------------------*/ -static int decode_galinavrawwordb(raw_t *raw) -{ - unsigned char *p=raw->buff+CNAVHLEN; - unsigned char buff[16]; - gtime_t time=raw->time; - char *sig; - int i,sigch,satid,sigtype,type,week=0,tow=0; - - trace(3,"decode_galinavrawwordb: len=%d\n",raw->len); - - if (raw->lenlen); - return -1; - } - sigch =U4(p); p+=4; - satid =U4(p); p+=4; - sigtype=U4(p); p+=4; - - switch (sigtype) { - case 10433: sig="E1 "; break; - case 10466: sig="E5A"; break; - case 10499: sig="E5B"; break; - default: sig="???" ; break; - } - for (i=0;i<16;i++) { - buff[i]=U1(p); p+=1; - } - type=getbitu(buff,0,6); - if (type==0&&getbitu(buff,6,2)==2) { - week=getbitu(buff, 96,12); /* gst week */ - tow =getbitu(buff,108,20); - time=gst2time(week,tow); - } - char tstr[40]; - trace(3,"%s E%2d INAV-%s (%2d) ",time2str(time,tstr,0),satid,sig,type); - traceb(3,buff,16); - - return 0; +static int decode_galinavrawwordb(raw_t *raw) { + unsigned char *p = raw->buff + CNAVHLEN; + unsigned char buff[16]; + gtime_t time = raw->time; + char *sig; + int i, sigch, satid, sigtype, type, week = 0, tow = 0; + + trace(3, "decode_galinavrawwordb: len=%d\n", raw->len); + + if (raw->len < CNAVHLEN + 28) { + trace(2, "cnav galinavrawwordb length error: len=%d\n", raw->len); + return -1; + } + sigch = U4(p); + p += 4; + satid = U4(p); + p += 4; + sigtype = U4(p); + p += 4; + + switch (sigtype) { + case 10433: + sig = "E1 "; + break; + case 10466: + sig = "E5A"; + break; + case 10499: + sig = "E5B"; + break; + default: + sig = "???"; + break; + } + for (i = 0; i < 16; i++) { + buff[i] = U1(p); + p += 1; + } + type = getbitu(buff, 0, 6); + if (type == 0 && getbitu(buff, 6, 2) == 2) { + week = getbitu(buff, 96, 12); /* gst week */ + tow = getbitu(buff, 108, 20); + time = gst2time(week, tow); + } + char tstr[40]; + trace(3, "%s E%2d INAV-%s (%2d) ", time2str(time, tstr, 0), satid, sig, type); + traceb(3, buff, 16); + + return 0; } /* decode rawcnavframeb ------------------------------------------------------*/ -static int decode_rawcnavframeb(raw_t *raw) -{ - unsigned char *p=raw->buff+CNAVHLEN; - unsigned char buff[38]; - int i,sigch,prn,frmid; - - trace(3,"decode_rawcnavframeb: len=%d\n",raw->len); - - if (raw->lenlen); - return -1; - } - sigch=U4(p); p+=4; - prn =U4(p); p+=4; - frmid=U4(p); p+=4; - - for (i=0;i<38;i++) { - buff[i]=U1(p); p+=1; - } - char tstr[40]; - trace(3,"%s PRN=%3d FRMID=%2d ",time2str(raw->time,tstr,0),prn,frmid); - traceb(3,buff,38); - - return 0; +static int decode_rawcnavframeb(raw_t *raw) { + unsigned char *p = raw->buff + CNAVHLEN; + unsigned char buff[38]; + int i, sigch, prn, frmid; + + trace(3, "decode_rawcnavframeb: len=%d\n", raw->len); + + if (raw->len < CNAVHLEN + 50) { + trace(2, "cnav rawcnavframeb length error: len=%d\n", raw->len); + return -1; + } + sigch = U4(p); + p += 4; + prn = U4(p); + p += 4; + frmid = U4(p); + p += 4; + + for (i = 0; i < 38; i++) { + buff[i] = U1(p); + p += 1; + } + char tstr[40]; + trace(3, "%s PRN=%3d FRMID=%2d ", time2str(raw->time, tstr, 0), prn, frmid); + traceb(3, buff, 38); + + return 0; } /* decode bdsephemerisb ------------------------------------------------------*/ -static int decode_bdsephemerisb(raw_t *raw) -{ - eph_t eph={0}; - unsigned char *p=raw->buff+CNAVHLEN; - double ura,sqrtA; - char *msg; - int prn,toc; - - trace(3,"decode_bdsephemerisb: len=%d\n",raw->len); - - if (raw->lenlen); - return -1; - } - prn =U4(p); p+=4; - eph.week =U4(p); p+=4; - ura =R8(p); p+=8; - eph.svh =U4(p)&1; p+=4; - eph.tgd[0]=R8(p); p+=8; /* TGD1 for B1 (s) */ - eph.tgd[1]=R8(p); p+=8; /* TGD2 for B2 (s) */ - eph.iodc =U4(p); p+=4; /* AODC */ - toc =U4(p); p+=4; - eph.f0 =R8(p); p+=8; - eph.f1 =R8(p); p+=8; - eph.f2 =R8(p); p+=8; - eph.iode =U4(p); p+=4; /* AODE */ - eph.toes =U4(p); p+=4; - sqrtA =R8(p); p+=8; - eph.e =R8(p); p+=8; - eph.omg =R8(p); p+=8; - eph.deln =R8(p); p+=8; - eph.M0 =R8(p); p+=8; - eph.OMG0 =R8(p); p+=8; - eph.OMGd =R8(p); p+=8; - eph.i0 =R8(p); p+=8; - eph.idot =R8(p); p+=8; - eph.cuc =R8(p); p+=8; - eph.cus =R8(p); p+=8; - eph.crc =R8(p); p+=8; - eph.crs =R8(p); p+=8; - eph.cic =R8(p); p+=8; - eph.cis =R8(p); - eph.A =sqrtA*sqrtA; - eph.sva =uraindex(ura); - - if (raw->outtype) { - msg=raw->msgtype+strlen(raw->msgtype); - sprintf(msg," prn=%3d iod=%3d toes=%6.0f",prn,eph.iode,eph.toes); - } - if (!(eph.sat=satno(SYS_CMP,prn))) { - trace(2,"oemv bdsephemeris satellite error: prn=%d\n",prn); - return -1; - } - eph.toe=bdt2gpst(bdt2time(eph.week,eph.toes)); /* bdt -> gpst */ - eph.toc=bdt2gpst(bdt2time(eph.week,toc)); /* bdt -> gpst */ - eph.ttr=raw->time; - - if (!strstr(raw->opt,"-EPHALL")) { - if (timediff(raw->nav.eph[eph.sat-1].toe,eph.toe)==0.0&& - raw->nav.eph[eph.sat-1].iode==eph.iode&& - raw->nav.eph[eph.sat-1].iodc==eph.iodc) return 0; /* unchanged */ - } - raw->nav.eph[eph.sat-1]=eph; - raw->ephsat=eph.sat; - return 2; +static int decode_bdsephemerisb(raw_t *raw) { + eph_t eph = {0}; + unsigned char *p = raw->buff + CNAVHLEN; + double ura, sqrtA; + char *msg; + int prn, toc; + + trace(3, "decode_bdsephemerisb: len=%d\n", raw->len); + + if (raw->len < CNAVHLEN + 196) { + trace(2, "cnav bdsephemrisb length error: len=%d\n", raw->len); + return -1; + } + prn = U4(p); + p += 4; + eph.week = U4(p); + p += 4; + ura = R8(p); + p += 8; + eph.svh = U4(p) & 1; + p += 4; + eph.tgd[0] = R8(p); + p += 8; /* TGD1 for B1 (s) */ + eph.tgd[1] = R8(p); + p += 8; /* TGD2 for B2 (s) */ + eph.iodc = U4(p); + p += 4; /* AODC */ + toc = U4(p); + p += 4; + eph.f0 = R8(p); + p += 8; + eph.f1 = R8(p); + p += 8; + eph.f2 = R8(p); + p += 8; + eph.iode = U4(p); + p += 4; /* AODE */ + eph.toes = U4(p); + p += 4; + sqrtA = R8(p); + p += 8; + eph.e = R8(p); + p += 8; + eph.omg = R8(p); + p += 8; + eph.deln = R8(p); + p += 8; + eph.M0 = R8(p); + p += 8; + eph.OMG0 = R8(p); + p += 8; + eph.OMGd = R8(p); + p += 8; + eph.i0 = R8(p); + p += 8; + eph.idot = R8(p); + p += 8; + eph.cuc = R8(p); + p += 8; + eph.cus = R8(p); + p += 8; + eph.crc = R8(p); + p += 8; + eph.crs = R8(p); + p += 8; + eph.cic = R8(p); + p += 8; + eph.cis = R8(p); + eph.A = sqrtA * sqrtA; + eph.sva = uraindex(ura); + + if (raw->outtype) { + msg = raw->msgtype + strlen(raw->msgtype); + sprintf(msg, " prn=%3d iod=%3d toes=%6.0f", prn, eph.iode, eph.toes); + } + if (!(eph.sat = satno(SYS_CMP, prn))) { + trace(2, "oemv bdsephemeris satellite error: prn=%d\n", prn); + return -1; + } + eph.toe = bdt2gpst(bdt2time(eph.week, eph.toes)); /* bdt -> gpst */ + eph.toc = bdt2gpst(bdt2time(eph.week, toc)); /* bdt -> gpst */ + eph.ttr = raw->time; + + if (!strstr(raw->opt, "-EPHALL")) { + if (timediff(raw->nav.eph[eph.sat - 1].toe, eph.toe) == 0.0 && + raw->nav.eph[eph.sat - 1].iode == eph.iode && raw->nav.eph[eph.sat - 1].iodc == eph.iodc) + return 0; /* unchanged */ + } + raw->nav.eph[eph.sat - 1] = eph; + raw->ephsat = eph.sat; + return 2; } - + /* decode cnav message -------------------------------------------------------*/ -static int decode_cnav(raw_t *raw) -{ - double tow; - int msg,week,type=U2(raw->buff+4); - - trace(3,"decode_cnav: type=%3d len=%d\n",type,raw->len); - - /* check crc32 */ - if (rtk_crc32(raw->buff,raw->len)!=U4(raw->buff+raw->len)) { - trace(2,"cnav crc error: type=%3d len=%d\n",type,raw->len); - return -1; - } - msg =(U1(raw->buff+6)>>4)&0x3; - if (!(week=U2(raw->buff+14))) { - return -1; - } - week=adjgpsweek(week); - tow =U4(raw->buff+16)*0.001; - raw->time=gpst2time(week,tow); - - if (raw->outtype) { - char tstr[40]; - sprintf(raw->msgtype,"CNAV %4d (%4d): msg=%d %s",type,raw->len,msg, - time2str(gpst2time(week,tow),tstr,2)); - } - if (msg!=0) return 0; /* message type: 0=binary,1=ascii */ - - switch (type) { - case ID_RANGECMP : return decode_rangecmpb (raw); - case ID_RANGE : return decode_rangeb (raw); - case ID_RAWEPHEM : return decode_rawephemb (raw); - case ID_RAWWAASFRAME : return decode_rawwaasframeb (raw); - case ID_RAWSBASFRAME : return decode_rawsbasframeb (raw); - case ID_IONUTC : return decode_ionutcb (raw); - case ID_GLOEPHEMERIS : return decode_gloephemerisb (raw); - case ID_QZSSRAWEPHEM : return decode_qzssrawephemb (raw); - case ID_QZSSRAWSUBFRAME: return decode_qzssrawsubframeb(raw); - case ID_QZSSIONUTC : return decode_qzssionutcb (raw); - case ID_GALEPHEMERIS : return decode_galephemerisb (raw); - case ID_GALALMANAC : return decode_galalmanacb (raw); - case ID_GALCLOCK : return decode_galclockb (raw); - case ID_GALIONO : return decode_galionob (raw); - case ID_GALFNAVRAWPAGE: return decode_galfnavrawpageb(raw); - case ID_GALINAVRAWWORD: return decode_galinavrawwordb(raw); - case ID_RAWCNAVFRAME : return decode_rawcnavframeb (raw); - case ID_BDSEPHEMERIS : return decode_bdsephemerisb (raw); - } - return 0; +static int decode_cnav(raw_t *raw) { + double tow; + int msg, week, type = U2(raw->buff + 4); + + trace(3, "decode_cnav: type=%3d len=%d\n", type, raw->len); + + /* check crc32 */ + if (rtk_crc32(raw->buff, raw->len) != U4(raw->buff + raw->len)) { + trace(2, "cnav crc error: type=%3d len=%d\n", type, raw->len); + return -1; + } + msg = (U1(raw->buff + 6) >> 4) & 0x3; + if (!(week = U2(raw->buff + 14))) { + return -1; + } + week = adjgpsweek(week); + tow = U4(raw->buff + 16) * 0.001; + raw->time = gpst2time(week, tow); + + if (raw->outtype) { + char tstr[40]; + sprintf(raw->msgtype, "CNAV %4d (%4d): msg=%d %s", type, raw->len, msg, + time2str(gpst2time(week, tow), tstr, 2)); + } + if (msg != 0) return 0; /* message type: 0=binary,1=ascii */ + + switch (type) { + case ID_RANGECMP: + return decode_rangecmpb(raw); + case ID_RANGE: + return decode_rangeb(raw); + case ID_RAWEPHEM: + return decode_rawephemb(raw); + case ID_RAWWAASFRAME: + return decode_rawwaasframeb(raw); + case ID_RAWSBASFRAME: + return decode_rawsbasframeb(raw); + case ID_IONUTC: + return decode_ionutcb(raw); + case ID_GLOEPHEMERIS: + return decode_gloephemerisb(raw); + case ID_QZSSRAWEPHEM: + return decode_qzssrawephemb(raw); + case ID_QZSSRAWSUBFRAME: + return decode_qzssrawsubframeb(raw); + case ID_QZSSIONUTC: + return decode_qzssionutcb(raw); + case ID_GALEPHEMERIS: + return decode_galephemerisb(raw); + case ID_GALALMANAC: + return decode_galalmanacb(raw); + case ID_GALCLOCK: + return decode_galclockb(raw); + case ID_GALIONO: + return decode_galionob(raw); + case ID_GALFNAVRAWPAGE: + return decode_galfnavrawpageb(raw); + case ID_GALINAVRAWWORD: + return decode_galinavrawwordb(raw); + case ID_RAWCNAVFRAME: + return decode_rawcnavframeb(raw); + case ID_BDSEPHEMERIS: + return decode_bdsephemerisb(raw); + } + return 0; } /* sync header ---------------------------------------------------------------*/ -static int sync_cnav(unsigned char *buff, unsigned char data) -{ - buff[0]=buff[1]; buff[1]=buff[2]; buff[2]=data; - return buff[0]==CNAVSYNC1&&buff[1]==CNAVSYNC2&&buff[2]==CNAVSYNC3; +static int sync_cnav(unsigned char *buff, unsigned char data) { + buff[0] = buff[1]; + buff[1] = buff[2]; + buff[2] = data; + return buff[0] == CNAVSYNC1 && buff[1] == CNAVSYNC2 && buff[2] == CNAVSYNC3; } /* input comnav raw data from stream ---------------------------------------- -* fetch next comnav raw data and input a mesasge from stream -* args : raw_t *raw IO receiver raw data control struct -* unsigned char data I stream data (1 byte) -* return : status (-1: error message, 0: no message, 1: input observation data, -* 2: input ephemeris, 3: input sbas message, -* 9: input ion/utc parameter) -* -* notes : to specify input options for cnav, set raw->opt to the following -* option strings separated by spaces. -* -* -EPHALL : input all ephemerides -* -GL1P : select 1P for GPS L1 (default 1C) -* -GL2X : select 2X for GPS L2 (default 2W) -* -RL2C : select 2C for GLO L2 (default 2P) -* -EL2C : select 2C for GAL L2 (default 2C) -* -GALINAV: use I/NAV for GAL ephemeris -* -GALFNAV: use F/NAV for GAL ephemeris -* -*-----------------------------------------------------------------------------*/ -extern int input_cnav(raw_t *raw, unsigned char data) -{ - trace(5,"input_cnav: data=%02x\n",data); - - /* synchronize frame */ - if (raw->nbyte==0) { - if (sync_cnav(raw->buff,data)) raw->nbyte=3; - return 0; - } - raw->buff[raw->nbyte++]=data; - - if (raw->nbyte==10&&(raw->len=U2(raw->buff+8)+CNAVHLEN)>MAXRAWLEN-4) { - trace(2,"cnav length error: len=%d\n",raw->len); - raw->nbyte=0; - return -1; - } - if (raw->nbyte<10||raw->nbytelen+4) return 0; - raw->nbyte=0; - - /* decode cnav message */ - return decode_cnav(raw); + * fetch next comnav raw data and input a mesasge from stream + * args : raw_t *raw IO receiver raw data control struct + * unsigned char data I stream data (1 byte) + * return : status (-1: error message, 0: no message, 1: input observation data, + * 2: input ephemeris, 3: input sbas message, + * 9: input ion/utc parameter) + * + * notes : to specify input options for cnav, set raw->opt to the following + * option strings separated by spaces. + * + * -EPHALL : input all ephemerides + * -GL1P : select 1P for GPS L1 (default 1C) + * -GL2X : select 2X for GPS L2 (default 2W) + * -RL2C : select 2C for GLO L2 (default 2P) + * -EL2C : select 2C for GAL L2 (default 2C) + * -GALINAV: use I/NAV for GAL ephemeris + * -GALFNAV: use F/NAV for GAL ephemeris + * + *-----------------------------------------------------------------------------*/ +extern int input_cnav(raw_t *raw, unsigned char data) { + trace(5, "input_cnav: data=%02x\n", data); + + /* synchronize frame */ + if (raw->nbyte == 0) { + if (sync_cnav(raw->buff, data)) raw->nbyte = 3; + return 0; + } + raw->buff[raw->nbyte++] = data; + + if (raw->nbyte == 10 && (raw->len = U2(raw->buff + 8) + CNAVHLEN) > MAXRAWLEN - 4) { + trace(2, "cnav length error: len=%d\n", raw->len); + raw->nbyte = 0; + return -1; + } + if (raw->nbyte < 10 || raw->nbyte < raw->len + 4) return 0; + raw->nbyte = 0; + + /* decode cnav message */ + return decode_cnav(raw); } /* input comnav raw data from file ------------------------------------------ -* fetch next comnav raw data and input a message from file -* args : raw_t *raw IO receiver raw data control struct -* int format I receiver raw data format (STRFMT_???) -* FILE *fp I file pointer -* return : status(-2: end of file, -1...9: same as above) -*-----------------------------------------------------------------------------*/ -extern int input_cnavf(raw_t *raw, FILE *fp) -{ - int i,data; - - trace(4,"input_cnavf:\n"); - - /* synchronize frame */ - if (raw->nbyte==0) { - for (i=0;;i++) { - if ((data=fgetc(fp))==EOF) return -2; - if (sync_cnav(raw->buff,(unsigned char)data)) break; - if (i>=4096) return 0; - } - } - if (fread(raw->buff+3,7,1,fp)<1) return -2; - raw->nbyte=10; - - if ((raw->len=U2(raw->buff+8)+CNAVHLEN)>MAXRAWLEN-4) { - trace(2,"cnav length error: len=%d\n",raw->len); - raw->nbyte=0; - return -1; - } - if (fread(raw->buff+10,raw->len-6,1,fp)<1) return -2; - raw->nbyte=0; - - /* decode cnav message */ - return decode_cnav(raw); + * fetch next comnav raw data and input a message from file + * args : raw_t *raw IO receiver raw data control struct + * int format I receiver raw data format (STRFMT_???) + * FILE *fp I file pointer + * return : status(-2: end of file, -1...9: same as above) + *-----------------------------------------------------------------------------*/ +extern int input_cnavf(raw_t *raw, FILE *fp) { + int i, data; + + trace(4, "input_cnavf:\n"); + + /* synchronize frame */ + if (raw->nbyte == 0) { + for (i = 0;; i++) { + if ((data = fgetc(fp)) == EOF) return -2; + if (sync_cnav(raw->buff, (unsigned char)data)) break; + if (i >= 4096) return 0; + } + } + if (fread(raw->buff + 3, 7, 1, fp) < 1) return -2; + raw->nbyte = 10; + + if ((raw->len = U2(raw->buff + 8) + CNAVHLEN) > MAXRAWLEN - 4) { + trace(2, "cnav length error: len=%d\n", raw->len); + raw->nbyte = 0; + return -1; + } + if (fread(raw->buff + 10, raw->len - 6, 1, fp) < 1) return -2; + raw->nbyte = 0; + + /* decode cnav message */ + return decode_cnav(raw); } - diff --git a/src/rcv/crescent.c b/src/rcv/crescent.c index 1293ce454..648328236 100644 --- a/src/rcv/crescent.c +++ b/src/rcv/crescent.c @@ -1,631 +1,665 @@ /*------------------------------------------------------------------------------ -* crescent.c : hemisphere crescent/eclipse receiver dependent functions -* -* Copyright (C) 2007-2020 by T.TAKASU, All rights reserved. -* -* reference : -* [1] Hemisphere GPS, Grescent Integrator's Manual, December, 2005 -* [2] Hemisphere GPS, GPS Technical Reference, Part No. 875-0175-000, -* Rev.D1, 2008 -* [3] Hemisphere GPS, Hemisphere GPS Technical Reference Manual, v4.0, -* June 30, 2020 -* -* version : $Revision: 1.2 $ $Date: 2008/07/14 00:05:05 $ -* history : 2008/05/21 1.0 new -* 2009/04/01 1.1 support sbas, set 0 to L2 observables -* fix bug on getting doppler observables -* 2009/10/19 1.2 support eclipse (message bin 76) -* 2009/10/24 1.3 ignore vaild phase flag -* 2011/05/27 1.4 add -EPHALL option -* fix problem with ARM compiler -* 2011/07/01 1.5 suppress warning -* 2013/02/23 1.6 fix memory access violation problem on arm -* 2014/05/13 1.7 support bin65 and bin66 -* add receiver option -TTCORR -* 2014/06/21 1.8 move decode_glostr() to rcvraw.c -* 2017/04/11 1.9 (char *) -> (signed char *) -* 2020/11/30 1.10 use integer type in stdint.h -* use sat2freq() instead of lam_carr() -* udpate reference [3] -*-----------------------------------------------------------------------------*/ + * crescent.c : hemisphere crescent/eclipse receiver dependent functions + * + * Copyright (C) 2007-2020 by T.TAKASU, All rights reserved. + * + * reference : + * [1] Hemisphere GPS, Grescent Integrator's Manual, December, 2005 + * [2] Hemisphere GPS, GPS Technical Reference, Part No. 875-0175-000, + * Rev.D1, 2008 + * [3] Hemisphere GPS, Hemisphere GPS Technical Reference Manual, v4.0, + * June 30, 2020 + * + * version : $Revision: 1.2 $ $Date: 2008/07/14 00:05:05 $ + * history : 2008/05/21 1.0 new + * 2009/04/01 1.1 support sbas, set 0 to L2 observables + * fix bug on getting doppler observables + * 2009/10/19 1.2 support eclipse (message bin 76) + * 2009/10/24 1.3 ignore vaild phase flag + * 2011/05/27 1.4 add -EPHALL option + * fix problem with ARM compiler + * 2011/07/01 1.5 suppress warning + * 2013/02/23 1.6 fix memory access violation problem on arm + * 2014/05/13 1.7 support bin65 and bin66 + * add receiver option -TTCORR + * 2014/06/21 1.8 move decode_glostr() to rcvraw.c + * 2017/04/11 1.9 (char *) -> (signed char *) + * 2020/11/30 1.10 use integer type in stdint.h + * use sat2freq() instead of lam_carr() + * udpate reference [3] + *-----------------------------------------------------------------------------*/ #include "rtklib.h" -#define CRESSYNC "$BIN" /* hemis bin sync code */ +#define CRESSYNC "$BIN" /* hemis bin sync code */ -#define ID_CRESPOS 1 /* hemis msg id: bin 1 position/velocity */ -#define ID_CRESGLOEPH 65 /* hemis msg id: bin 65 glonass ephemeris */ -#define ID_CRESGLORAW 66 /* hemis msg id: bin 66 glonass L1/L2 phase and code */ -#define ID_CRESRAW2 76 /* hemis msg id: bin 76 dual-freq raw */ -#define ID_CRESWAAS 80 /* hemis msg id: bin 80 waas messages */ -#define ID_CRESIONUTC 94 /* hemis msg id: bin 94 ion/utc parameters */ -#define ID_CRESEPH 95 /* hemis msg id: bin 95 raw ephemeris */ -#define ID_CRESRAW 96 /* hemis msg id: bin 96 raw phase and code */ +#define ID_CRESPOS 1 /* hemis msg id: bin 1 position/velocity */ +#define ID_CRESGLOEPH 65 /* hemis msg id: bin 65 glonass ephemeris */ +#define ID_CRESGLORAW 66 /* hemis msg id: bin 66 glonass L1/L2 phase and code */ +#define ID_CRESRAW2 76 /* hemis msg id: bin 76 dual-freq raw */ +#define ID_CRESWAAS 80 /* hemis msg id: bin 80 waas messages */ +#define ID_CRESIONUTC 94 /* hemis msg id: bin 94 ion/utc parameters */ +#define ID_CRESEPH 95 /* hemis msg id: bin 95 raw ephemeris */ +#define ID_CRESRAW 96 /* hemis msg id: bin 96 raw phase and code */ -#define SNR2CN0_L1 30.0 /* hemis snr to c/n0 offset (db) L1 */ -#define SNR2CN0_L2 30.0 /* hemis snr to c/n0 offset (db) L2 */ +#define SNR2CN0_L1 30.0 /* hemis snr to c/n0 offset (db) L1 */ +#define SNR2CN0_L2 30.0 /* hemis snr to c/n0 offset (db) L2 */ /* get fields (little-endian) ------------------------------------------------*/ #define U1(p) (*((uint8_t *)(p))) -#define I1(p) (*((int8_t *)(p))) -static uint16_t U2(uint8_t *p) {uint16_t u; memcpy(&u,p,2); return u;} -static uint32_t U4(uint8_t *p) {uint32_t u; memcpy(&u,p,4); return u;} -static int16_t I2(uint8_t *p) {int16_t i; memcpy(&i,p,2); return i;} -static int32_t I4(uint8_t *p) {int32_t i; memcpy(&i,p,4); return i;} -static float R4(uint8_t *p) {float r; memcpy(&r,p,4); return r;} -static double R8(uint8_t *p) {double r; memcpy(&r,p,8); return r;} +#define I1(p) (*((int8_t *)(p))) +static uint16_t U2(uint8_t *p) { + uint16_t u; + memcpy(&u, p, 2); + return u; +} +static uint32_t U4(uint8_t *p) { + uint32_t u; + memcpy(&u, p, 4); + return u; +} +static int16_t I2(uint8_t *p) { + int16_t i; + memcpy(&i, p, 2); + return i; +} +static int32_t I4(uint8_t *p) { + int32_t i; + memcpy(&i, p, 4); + return i; +} +static float R4(uint8_t *p) { + float r; + memcpy(&r, p, 4); + return r; +} +static double R8(uint8_t *p) { + double r; + memcpy(&r, p, 8); + return r; +} /* checksum ------------------------------------------------------------------*/ -static int chksum(const uint8_t *buff, int len) -{ - uint16_t sum=0; - int i; - - for (i=8;i>8,sum&0xFF,buff[len-3],buff[len-4],buff[len-2],buff[len-1]); - return (sum>>8)==buff[len-3]&&(sum&0xFF)==buff[len-4]&& - buff[len-2]==0x0D&&buff[len-1]==0x0A; +static int chksum(const uint8_t *buff, int len) { + uint16_t sum = 0; + int i; + + for (i = 8; i < len - 4; i++) sum += buff[i]; + trace(4, "checksum=%02X%02X %02X%02X:%02X%02X\n", sum >> 8, sum & 0xFF, buff[len - 3], + buff[len - 4], buff[len - 2], buff[len - 1]); + return (sum >> 8) == buff[len - 3] && (sum & 0xFF) == buff[len - 4] && buff[len - 2] == 0x0D && + buff[len - 1] == 0x0A; } /* decode bin 1 position/velocity ---------------------------------------------*/ -static int decode_crespos(raw_t *raw) -{ - int ns,week,mode; - double tow,pos[3],vel[3],std; - char tstr[40]; - uint8_t *p=raw->buff+8; - - trace(4,"decode_crespos: len=%d\n",raw->len); - - if (raw->len!=64) { - trace(2,"crescent bin 1 message length error: len=%d\n",raw->len); - return -1; - } - ns =U1(p+1); - week=U2(p+2); - tow =R8(p+4); - pos[0]=R8(p+12); - pos[1]=R8(p+20); - pos[2]=R4(p+28); - vel[0]=R4(p+32); - vel[1]=R4(p+36); - vel[2]=R4(p+40); - std =R4(p+44); - mode=U2(p+48); - time2str(gpst2time(week,tow),tstr,3); - trace(3,"$BIN1 %s %13.9f %14.9f %10.4f %4d %3d %.3f\n",tstr,pos[0],pos[1], - pos[2],mode==6?1:(mode>4?2:(mode>1?5:0)),ns,std); - return 0; +static int decode_crespos(raw_t *raw) { + int ns, week, mode; + double tow, pos[3], vel[3], std; + char tstr[40]; + uint8_t *p = raw->buff + 8; + + trace(4, "decode_crespos: len=%d\n", raw->len); + + if (raw->len != 64) { + trace(2, "crescent bin 1 message length error: len=%d\n", raw->len); + return -1; + } + ns = U1(p + 1); + week = U2(p + 2); + tow = R8(p + 4); + pos[0] = R8(p + 12); + pos[1] = R8(p + 20); + pos[2] = R4(p + 28); + vel[0] = R4(p + 32); + vel[1] = R4(p + 36); + vel[2] = R4(p + 40); + std = R4(p + 44); + mode = U2(p + 48); + time2str(gpst2time(week, tow), tstr, 3); + trace(3, "$BIN1 %s %13.9f %14.9f %10.4f %4d %3d %.3f\n", tstr, pos[0], pos[1], pos[2], + mode == 6 ? 1 : (mode > 4 ? 2 : (mode > 1 ? 5 : 0)), ns, std); + return 0; } /* decode bin 96 raw phase and code ------------------------------------------*/ -static int decode_cresraw(raw_t *raw) -{ - gtime_t time; - double tow,tows,toff=0.0,cp,pr,dop,snr,freq=FREQL1; - int i,j,n,prn,sat,week,word2,lli=0; - uint32_t word1,sn,sc; - uint8_t *p=raw->buff+8; - - trace(4,"decode_cresraw: len=%d\n",raw->len); - - if (raw->len!=312) { - trace(2,"crescent bin 96 message length error: len=%d\n",raw->len); - return -1; +static int decode_cresraw(raw_t *raw) { + gtime_t time; + double tow, tows, toff = 0.0, cp, pr, dop, snr, freq = FREQL1; + int i, j, n, prn, sat, week, word2, lli = 0; + uint32_t word1, sn, sc; + uint8_t *p = raw->buff + 8; + + trace(4, "decode_cresraw: len=%d\n", raw->len); + + if (raw->len != 312) { + trace(2, "crescent bin 96 message length error: len=%d\n", raw->len); + return -1; + } + week = U2(p + 2); + tow = R8(p + 4); + tows = floor(tow * 1000.0 + 0.5) / 1000.0; /* round by 1ms */ + time = gpst2time(week, tows); + + /* time tag offset correction */ + if (strstr(raw->opt, "-TTCORR")) { + toff = CLIGHT * (tows - tow); + } + for (i = n = 0, p += 12; i < 12 && n < MAXOBS; i++, p += 24) { + word1 = U4(p); + word2 = I4(p + 4); + if ((prn = word1 & 0xFF) == 0) continue; /* if 0, no data */ + if (!(sat = satno(prn <= MAXPRNGPS ? SYS_GPS : SYS_SBS, prn))) { + trace(2, "creasent bin 96 satellite number error: prn=%d\n", prn); + continue; } - week=U2(p+2); - tow =R8(p+4); - tows=floor(tow*1000.0+0.5)/1000.0; /* round by 1ms */ - time=gpst2time(week,tows); - - /* time tag offset correction */ - if (strstr(raw->opt,"-TTCORR")) { - toff=CLIGHT*(tows-tow); + pr = R8(p + 8) - toff; + cp = R8(p + 16) - toff; + if (!(word2 & 1)) cp = 0.0; /* invalid phase */ + sn = (word1 >> 8) & 0xFF; + snr = sn == 0 ? 0.0 : 10.0 * log10(0.8192 * sn) + SNR2CN0_L1; + sc = (uint32_t)(word1 >> 24); + if (raw->time.time != 0) { + lli = (int)((uint8_t)sc - (uint8_t)raw->lockt[sat - 1][0]) > 0; } - for (i=n=0,p+=12;i<12&&n>8)&0xFF; - snr=sn==0?0.0:10.0*log10(0.8192*sn)+SNR2CN0_L1; - sc =(uint32_t)(word1>>24); - if (raw->time.time!=0) { - lli=(int)((uint8_t)sc-(uint8_t)raw->lockt[sat-1][0])>0; - } - raw->lockt[sat-1][0]=(uint8_t)sc; - dop=word2/16/4096.0; - - raw->obs.data[n].time=time; - raw->obs.data[n].sat =sat; - raw->obs.data[n].P[0]=pr; - raw->obs.data[n].L[0]=cp*freq/CLIGHT; - raw->obs.data[n].D[0]=-(float)(dop*freq/CLIGHT); - raw->obs.data[n].SNR[0]=snr; - raw->obs.data[n].LLI[0]=(uint8_t)lli; - raw->obs.data[n].code[0]=CODE_L1C; - - for (j=1;jobs.data[n].L[j]=raw->obs.data[n].P[j]=0.0; - raw->obs.data[n].D[j]=raw->obs.data[n].SNR[j]=0.0; - raw->obs.data[n].LLI[j]=0; - raw->obs.data[n].code[j]=CODE_NONE; - } - n++; + raw->lockt[sat - 1][0] = (uint8_t)sc; + dop = word2 / 16 / 4096.0; + + raw->obs.data[n].time = time; + raw->obs.data[n].sat = sat; + raw->obs.data[n].P[0] = pr; + raw->obs.data[n].L[0] = cp * freq / CLIGHT; + raw->obs.data[n].D[0] = -(float)(dop * freq / CLIGHT); + raw->obs.data[n].SNR[0] = snr; + raw->obs.data[n].LLI[0] = (uint8_t)lli; + raw->obs.data[n].code[0] = CODE_L1C; + + for (j = 1; j < NFREQ; j++) { + raw->obs.data[n].L[j] = raw->obs.data[n].P[j] = 0.0; + raw->obs.data[n].D[j] = raw->obs.data[n].SNR[j] = 0.0; + raw->obs.data[n].LLI[j] = 0; + raw->obs.data[n].code[j] = CODE_NONE; } - raw->time=time; - raw->obs.n=n; - return 1; + n++; + } + raw->time = time; + raw->obs.n = n; + return 1; } /* decode bin 76 dual-freq raw phase and code --------------------------------*/ -static int decode_cresraw2(raw_t *raw) -{ - gtime_t time; - double tow,tows,toff=0.0,cp[2]={0},pr1,pr[2]={0},dop[2]={0},snr[2]={0}; - double freq[2]={FREQL1,FREQL2}; - int i,j,n=0,prn,sat,week,lli[2]={0}; - uint32_t word1,word2,word3,sc,sn; - uint8_t *p=raw->buff+8; - - trace(4,"decode_cresraw2: len=%d\n",raw->len); - - if (raw->len!=460) { - trace(2,"crescent bin 76 message length error: len=%d\n",raw->len); - return -1; +static int decode_cresraw2(raw_t *raw) { + gtime_t time; + double tow, tows, toff = 0.0, cp[2] = {0}, pr1, pr[2] = {0}, dop[2] = {0}, snr[2] = {0}; + double freq[2] = {FREQL1, FREQL2}; + int i, j, n = 0, prn, sat, week, lli[2] = {0}; + uint32_t word1, word2, word3, sc, sn; + uint8_t *p = raw->buff + 8; + + trace(4, "decode_cresraw2: len=%d\n", raw->len); + + if (raw->len != 460) { + trace(2, "crescent bin 76 message length error: len=%d\n", raw->len); + return -1; + } + tow = R8(p); + week = U2(p + 8); + tows = floor(tow * 1000.0 + 0.5) / 1000.0; /* round by 1ms */ + time = gpst2time(week, tows); + + /* time tag offset correction */ + if (strstr(raw->opt, "-TTCORR")) { + toff = CLIGHT * (tows - tow); + } + if (fabs(timediff(time, raw->time)) < 1e-9) { + n = raw->obs.n; + } + for (i = 0, p += 16; i < 15 && n < MAXOBS; i++) { + word1 = U4(p + 324 + 4 * i); /* L1CACodeMSBsPRN */ + if ((prn = word1 & 0xFF) == 0) continue; /* if 0, no data */ + if (!(sat = satno(prn <= MAXPRNGPS ? SYS_GPS : SYS_SBS, prn))) { + trace(2, "creasent bin 76 satellite number error: prn=%d\n", prn); + continue; } - tow =R8(p); - week=U2(p+8); - tows=floor(tow*1000.0+0.5)/1000.0; /* round by 1ms */ - time=gpst2time(week,tows); - - /* time tag offset correction */ - if (strstr(raw->opt,"-TTCORR")) { - toff=CLIGHT*(tows-tow); + pr1 = (word1 >> 13) * 256.0; /* upper 19bit of L1CA pseudorange */ + + word1 = U4(p + 144 + 12 * i); /* L1CASatObs */ + word2 = U4(p + 148 + 12 * i); + word3 = U4(p + 152 + 12 * i); + sn = word1 & 0xFFF; + snr[0] = sn == 0 ? 0.0 : 10.0 * log10(0.1024 * sn) + SNR2CN0_L1; + sc = (uint32_t)(word1 >> 24); + if (raw->time.time != 0) { + lli[0] = (int)((uint8_t)sc - (uint8_t)raw->lockt[sat - 1][0]) > 0; + } else { + lli[0] = 0; } - if (fabs(timediff(time,raw->time))<1e-9) { - n=raw->obs.n; + lli[0] |= ((word1 >> 12) & 7) ? 2 : 0; + raw->lockt[sat - 1][0] = (uint8_t)sc; + dop[0] = ((word2 >> 1) & 0x7FFFFF) / 512.0; + if ((word2 >> 24) & 1) dop[0] = -dop[0]; + pr[0] = pr1 + (word3 & 0xFFFF) / 256.0; + cp[0] = floor(pr[0] * freq[0] / CLIGHT / 8192.0) * 8192.0; + cp[0] += ((word2 & 0xFE000000) + ((word3 & 0xFFFF0000) >> 7)) / 524288.0; + if (cp[0] - pr[0] * freq[0] / CLIGHT < -4096.0) + cp[0] += 8192.0; + else if (cp[0] - pr[0] * freq[0] / CLIGHT > 4096.0) + cp[0] -= 8192.0; + + if (i < 12) { + word1 = U4(p + 12 * i); /* L2PSatObs */ + word2 = U4(p + 4 + 12 * i); + word3 = U4(p + 8 + 12 * i); + sn = word1 & 0xFFF; + snr[1] = sn == 0 ? 0.0 : 10.0 * log10(0.1164 * sn) + SNR2CN0_L2; + sc = (uint32_t)(word1 >> 24); + if (raw->time.time == 0) { + lli[1] = (int)((uint8_t)sc - (uint8_t)raw->lockt[sat - 1][1]) > 0; + } else { + lli[1] = 0; + } + lli[1] |= ((word1 >> 12) & 7) ? 2 : 0; + raw->lockt[sat - 1][1] = (uint8_t)sc; + dop[1] = ((word2 >> 1) & 0x7FFFFF) / 512.0; + if ((word2 >> 24) & 1) dop[1] = -dop[1]; + pr[1] = (word3 & 0xFFFF) / 256.0; + if (pr[1] != 0.0) { + pr[1] += pr1; + if (pr[1] - pr[0] < -128.0) + pr[1] += 256.0; + else if (pr[1] - pr[0] > 128.0) + pr[1] -= 256.0; + cp[1] = floor(pr[1] * freq[1] / CLIGHT / 8192.0) * 8192.0; + cp[1] += ((word2 & 0xFE000000) + ((word3 & 0xFFFF0000) >> 7)) / 524288.0; + if (cp[1] - pr[1] * freq[1] / CLIGHT < -4096.0) + cp[1] += 8192.0; + else if (cp[1] - pr[1] * freq[1] / CLIGHT > 4096.0) + cp[1] -= 8192.0; + } else + cp[1] = 0.0; } - for (i=0,p+=16;i<15&&n>13)*256.0; /* upper 19bit of L1CA pseudorange */ - - word1=U4(p+144+12*i); /* L1CASatObs */ - word2=U4(p+148+12*i); - word3=U4(p+152+12*i); - sn=word1&0xFFF; - snr[0]=sn==0?0.0:10.0*log10(0.1024*sn)+SNR2CN0_L1; - sc=(uint32_t)(word1>>24); - if (raw->time.time!=0) { - lli[0]=(int)((uint8_t)sc-(uint8_t)raw->lockt[sat-1][0])>0; - } - else { - lli[0]=0; - } - lli[0]|=((word1>>12)&7)?2:0; - raw->lockt[sat-1][0]=(uint8_t)sc; - dop[0]=((word2>>1)&0x7FFFFF)/512.0; - if ((word2>>24)&1) dop[0]=-dop[0]; - pr[0]=pr1+(word3&0xFFFF)/256.0; - cp[0]=floor(pr[0]*freq[0]/CLIGHT/8192.0)*8192.0; - cp[0]+=((word2&0xFE000000)+((word3&0xFFFF0000)>>7))/524288.0; - if (cp[0]-pr[0]*freq[0]/CLIGHT<-4096.0) cp[0]+=8192.0; - else if (cp[0]-pr[0]*freq[0]/CLIGHT> 4096.0) cp[0]-=8192.0; - - if (i<12) { - word1=U4(p +12*i); /* L2PSatObs */ - word2=U4(p+4+12*i); - word3=U4(p+8+12*i); - sn=word1&0xFFF; - snr[1]=sn==0?0.0:10.0*log10(0.1164*sn)+SNR2CN0_L2; - sc=(uint32_t)(word1>>24); - if (raw->time.time==0) { - lli[1]=(int)((uint8_t)sc-(uint8_t)raw->lockt[sat-1][1])>0; - } - else { - lli[1]=0; - } - lli[1]|=((word1>>12)&7)?2:0; - raw->lockt[sat-1][1]=(uint8_t)sc; - dop[1]=((word2>>1)&0x7FFFFF)/512.0; - if ((word2>>24)&1) dop[1]=-dop[1]; - pr[1]=(word3&0xFFFF)/256.0; - if (pr[1]!=0.0) { - pr[1]+=pr1; - if (pr[1]-pr[0]<-128.0) pr[1]+=256.0; - else if (pr[1]-pr[0]> 128.0) pr[1]-=256.0; - cp[1]=floor(pr[1]*freq[1]/CLIGHT/8192.0)*8192.0; - cp[1]+=((word2&0xFE000000)+((word3&0xFFFF0000)>>7))/524288.0; - if (cp[1]-pr[1]*freq[1]/CLIGHT<-4096.0) cp[1]+=8192.0; - else if (cp[1]-pr[1]*freq[1]/CLIGHT> 4096.0) cp[1]-=8192.0; - } - else cp[1]=0.0; - } - raw->obs.data[n].time=time; - raw->obs.data[n].sat =sat; - for (j=0;jobs.data[n].P[j]=pr[j]==0.0?0.0:pr[j]-toff; - raw->obs.data[n].L[j]=cp[j]==0.0?0.0:cp[j]-toff*freq[j]/CLIGHT; - raw->obs.data[n].D[j]=-(float)dop[j]; - raw->obs.data[n].SNR[j]=snr[j]; - raw->obs.data[n].LLI[j]=(uint8_t)lli[j]; - raw->obs.data[n].code[j]=j==0?CODE_L1C:CODE_L2P; - } - else { - raw->obs.data[n].L[j]=raw->obs.data[n].P[j]=0.0; - raw->obs.data[n].D[j]=raw->obs.data[n].SNR[j]=0.0; - raw->obs.data[n].LLI[j]=0; - raw->obs.data[n].code[j]=CODE_NONE; - } - } - n++; + raw->obs.data[n].time = time; + raw->obs.data[n].sat = sat; + for (j = 0; j < NFREQ; j++) { + if (j == 0 || (j == 1 && i < 12)) { + raw->obs.data[n].P[j] = pr[j] == 0.0 ? 0.0 : pr[j] - toff; + raw->obs.data[n].L[j] = cp[j] == 0.0 ? 0.0 : cp[j] - toff * freq[j] / CLIGHT; + raw->obs.data[n].D[j] = -(float)dop[j]; + raw->obs.data[n].SNR[j] = snr[j]; + raw->obs.data[n].LLI[j] = (uint8_t)lli[j]; + raw->obs.data[n].code[j] = j == 0 ? CODE_L1C : CODE_L2P; + } else { + raw->obs.data[n].L[j] = raw->obs.data[n].P[j] = 0.0; + raw->obs.data[n].D[j] = raw->obs.data[n].SNR[j] = 0.0; + raw->obs.data[n].LLI[j] = 0; + raw->obs.data[n].code[j] = CODE_NONE; + } } - raw->time=time; - raw->obs.n=n; - if (strstr(raw->opt,"-ENAGLO")) return 0; /* glonass follows */ - return 1; + n++; + } + raw->time = time; + raw->obs.n = n; + if (strstr(raw->opt, "-ENAGLO")) return 0; /* glonass follows */ + return 1; } /* decode bin 95 ephemeris ---------------------------------------------------*/ -static int decode_creseph(raw_t *raw) -{ - eph_t eph={0}; - uint32_t word; - int i,j,k,prn,sat; - uint8_t *p=raw->buff+8,buff[90]; - - trace(4,"decode_creseph: len=%d\n",raw->len); - - if (raw->len!=140) { - trace(2,"crescent bin 95 message length error: len=%d\n",raw->len); - return -1; - } - prn=U2(p); - if (!(sat=satno(SYS_GPS,prn))) { - trace(2,"crescent bin 95 satellite number error: prn=%d\n",prn); - return -1; - } - for (i=0;i<3;i++) for (j=0;j<10;j++) { - word=U4(p+8+i*40+j*4)>>6; - for (k=0;k<3;k++) buff[i*30+j*3+k]=(uint8_t)((word>>(8*(2-k)))&0xFF); - } - if (!decode_frame(buff,SYS_GPS,&eph,NULL,NULL,NULL)) { - trace(2,"crescent bin 95 navigation frame error: prn=%d\n",prn); - return -1; - } - if (!strstr(raw->opt,"-EPHALL")) { - if (eph.iode==raw->nav.eph[sat-1].iode) return 0; /* unchanged */ +static int decode_creseph(raw_t *raw) { + eph_t eph = {0}; + uint32_t word; + int i, j, k, prn, sat; + uint8_t *p = raw->buff + 8, buff[90]; + + trace(4, "decode_creseph: len=%d\n", raw->len); + + if (raw->len != 140) { + trace(2, "crescent bin 95 message length error: len=%d\n", raw->len); + return -1; + } + prn = U2(p); + if (!(sat = satno(SYS_GPS, prn))) { + trace(2, "crescent bin 95 satellite number error: prn=%d\n", prn); + return -1; + } + for (i = 0; i < 3; i++) + for (j = 0; j < 10; j++) { + word = U4(p + 8 + i * 40 + j * 4) >> 6; + for (k = 0; k < 3; k++) buff[i * 30 + j * 3 + k] = (uint8_t)((word >> (8 * (2 - k))) & 0xFF); } - eph.sat=sat; - raw->nav.eph[sat-1]=eph; - raw->ephsat=sat; - raw->ephset=0; - return 2; + if (!decode_frame(buff, SYS_GPS, &eph, NULL, NULL, NULL)) { + trace(2, "crescent bin 95 navigation frame error: prn=%d\n", prn); + return -1; + } + if (!strstr(raw->opt, "-EPHALL")) { + if (eph.iode == raw->nav.eph[sat - 1].iode) return 0; /* unchanged */ + } + eph.sat = sat; + raw->nav.eph[sat - 1] = eph; + raw->ephsat = sat; + raw->ephset = 0; + return 2; } /* decode bin 94 ion/utc parameters ------------------------------------------*/ -static int decode_cresionutc(raw_t *raw) -{ - int i; - uint8_t *p=raw->buff+8; - - trace(4,"decode_cresionutc: len=%d\n",raw->len); - - if (raw->len!=108) { - trace(2,"crescent bin 94 message length error: len=%d\n",raw->len); - return -1; - } - for (i=0;i<8;i++) raw->nav.ion_gps[i]=R8(p+i*8); - raw->nav.utc_gps[0]=R8(p+64); - raw->nav.utc_gps[1]=R8(p+72); - raw->nav.utc_gps[2]=(double)U4(p+80); - raw->nav.utc_gps[3]=(double)U2(p+84); - raw->nav.utc_gps[4]=I2(p+90); - return 9; +static int decode_cresionutc(raw_t *raw) { + int i; + uint8_t *p = raw->buff + 8; + + trace(4, "decode_cresionutc: len=%d\n", raw->len); + + if (raw->len != 108) { + trace(2, "crescent bin 94 message length error: len=%d\n", raw->len); + return -1; + } + for (i = 0; i < 8; i++) raw->nav.ion_gps[i] = R8(p + i * 8); + raw->nav.utc_gps[0] = R8(p + 64); + raw->nav.utc_gps[1] = R8(p + 72); + raw->nav.utc_gps[2] = (double)U4(p + 80); + raw->nav.utc_gps[3] = (double)U2(p + 84); + raw->nav.utc_gps[4] = I2(p + 90); + return 9; } /* decode bin 80 waas messages -----------------------------------------------*/ -static int decode_creswaas(raw_t *raw) -{ - double tow; - uint32_t word; - int i,j,k,prn; - uint8_t *p=raw->buff+8; - - trace(4,"decode_creswaas: len=%d\n",raw->len); - - if (raw->len!=52) { - trace(2,"creasent bin 80 message length error: len=%d\n",raw->len); - return -1; - } - prn=U2(p); - if (prnsbsmsg.prn=prn; - raw->sbsmsg.tow=U4(p+4); - tow=time2gpst(raw->time,&raw->sbsmsg.week); - if (raw->sbsmsg.towsbsmsg.week++; - else if (raw->sbsmsg.tow>tow+302400.0) raw->sbsmsg.week--; - - for (i=k=0;i<8&&k<29;i++) { - word=U4(p+8+i*4); - for (j=0;j<4&&k<29;j++) raw->sbsmsg.msg[k++]=(uint8_t)(word>>(3-j)*8); - } - raw->sbsmsg.msg[28]&=0xC0; - return 3; +static int decode_creswaas(raw_t *raw) { + double tow; + uint32_t word; + int i, j, k, prn; + uint8_t *p = raw->buff + 8; + + trace(4, "decode_creswaas: len=%d\n", raw->len); + + if (raw->len != 52) { + trace(2, "creasent bin 80 message length error: len=%d\n", raw->len); + return -1; + } + prn = U2(p); + if (prn < MINPRNSBS || MAXPRNSBS < prn) { + trace(2, "creasent bin 80 satellite number error: prn=%d\n", prn); + return -1; + } + raw->sbsmsg.prn = prn; + raw->sbsmsg.tow = U4(p + 4); + tow = time2gpst(raw->time, &raw->sbsmsg.week); + if (raw->sbsmsg.tow < tow - 302400.0) + raw->sbsmsg.week++; + else if (raw->sbsmsg.tow > tow + 302400.0) + raw->sbsmsg.week--; + + for (i = k = 0; i < 8 && k < 29; i++) { + word = U4(p + 8 + i * 4); + for (j = 0; j < 4 && k < 29; j++) raw->sbsmsg.msg[k++] = (uint8_t)(word >> (3 - j) * 8); + } + raw->sbsmsg.msg[28] &= 0xC0; + return 3; } /* decode bin 66 glonass L1/L2 code and carrier phase ------------------------*/ -static int decode_cresgloraw(raw_t *raw) -{ - gtime_t time; - double tow,tows,toff=0.0,cp[2]={0},pr1,pr[2]={0},dop[2]={0},snr[2]={0}; - double freq[2]; - int i,j,n=0,prn,sat,week,lli[2]={0}; - uint32_t word1,word2,word3,sc,sn; - uint8_t *p=raw->buff+8; - - trace(4,"decode_cregloraw: len=%d\n",raw->len); - - if (!strstr(raw->opt,"-ENAGLO")) return 0; - - if (raw->len!=364) { - trace(2,"crescent bin 66 message length error: len=%d\n",raw->len); - return -1; +static int decode_cresgloraw(raw_t *raw) { + gtime_t time; + double tow, tows, toff = 0.0, cp[2] = {0}, pr1, pr[2] = {0}, dop[2] = {0}, snr[2] = {0}; + double freq[2]; + int i, j, n = 0, prn, sat, week, lli[2] = {0}; + uint32_t word1, word2, word3, sc, sn; + uint8_t *p = raw->buff + 8; + + trace(4, "decode_cregloraw: len=%d\n", raw->len); + + if (!strstr(raw->opt, "-ENAGLO")) return 0; + + if (raw->len != 364) { + trace(2, "crescent bin 66 message length error: len=%d\n", raw->len); + return -1; + } + tow = R8(p); + week = U2(p + 8); + tows = floor(tow * 1000.0 + 0.5) / 1000.0; /* round by 1ms */ + time = gpst2time(week, tows); + + /* time tag offset correction */ + if (strstr(raw->opt, "-TTCORR")) { + toff = CLIGHT * (tows - tow); + } + if (fabs(timediff(time, raw->time)) < 1e-9) { + n = raw->obs.n; + } + for (i = 0, p += 16; i < 12 && n < MAXOBS; i++) { + word1 = U4(p + 288 + 4 * i); /* L1CACodeMSBsSlot */ + if ((prn = word1 & 0xFF) == 0) continue; /* if 0, no data */ + if (!(sat = satno(SYS_GLO, prn))) { + trace(2, "creasent bin 66 satellite number error: prn=%d\n", prn); + continue; } - tow =R8(p); - week=U2(p+8); - tows=floor(tow*1000.0+0.5)/1000.0; /* round by 1ms */ - time=gpst2time(week,tows); - - /* time tag offset correction */ - if (strstr(raw->opt,"-TTCORR")) { - toff=CLIGHT*(tows-tow); + pr1 = (word1 >> 13) * 256.0; /* upper 19bit of L1CA pseudorange */ + + freq[0] = sat2freq(sat, CODE_L1C, &raw->nav); + freq[1] = sat2freq(sat, CODE_L2C, &raw->nav); + + /* L1Obs */ + word1 = U4(p + 12 * i); + word2 = U4(p + 4 + 12 * i); + word3 = U4(p + 8 + 12 * i); + sn = word1 & 0xFFF; + snr[0] = sn == 0 ? 0.0 : 10.0 * log10(0.1024 * sn) + SNR2CN0_L1; + sc = (uint32_t)(word1 >> 24); + if (raw->time.time != 0) { + lli[0] = (int)((uint8_t)sc - (uint8_t)raw->lockt[sat - 1][0]) > 0; + } else { + lli[0] = 0; } - if (fabs(timediff(time,raw->time))<1e-9) { - n=raw->obs.n; + lli[0] |= ((word1 >> 12) & 7) ? 2 : 0; + raw->lockt[sat - 1][0] = (uint8_t)sc; + dop[0] = ((word2 >> 1) & 0x7FFFFF) / 512.0; + if ((word2 >> 24) & 1) dop[0] = -dop[0]; + pr[0] = pr1 + (word3 & 0xFFFF) / 256.0; + cp[0] = floor(pr[0] * freq[0] / CLIGHT / 8192.0) * 8192.0; + cp[0] += ((word2 & 0xFE000000) + ((word3 & 0xFFFF0000) >> 7)) / 524288.0; + if (cp[0] - pr[0] * freq[0] / CLIGHT < -4096.0) + cp[0] += 8192.0; + else if (cp[0] - pr[0] * freq[0] / CLIGHT > 4096.0) + cp[0] -= 8192.0; + + /* L2Obs */ + word1 = U4(p + 144 + 12 * i); + word2 = U4(p + 148 + 12 * i); + word3 = U4(p + 152 + 12 * i); + sn = word1 & 0xFFF; + snr[1] = sn == 0 ? 0.0 : 10.0 * log10(0.1164 * sn) + SNR2CN0_L2; + sc = (uint32_t)(word1 >> 24); + if (raw->time.time == 0) { + lli[1] = (int)((uint8_t)sc - (uint8_t)raw->lockt[sat - 1][1]) > 0; + } else { + lli[1] = 0; } - for (i=0,p+=16;i<12&&n>13)*256.0; /* upper 19bit of L1CA pseudorange */ - - freq[0]=sat2freq(sat,CODE_L1C,&raw->nav); - freq[1]=sat2freq(sat,CODE_L2C,&raw->nav); - - /* L1Obs */ - word1=U4(p +12*i); - word2=U4(p+4+12*i); - word3=U4(p+8+12*i); - sn=word1&0xFFF; - snr[0]=sn==0?0.0:10.0*log10(0.1024*sn)+SNR2CN0_L1; - sc=(uint32_t)(word1>>24); - if (raw->time.time!=0) { - lli[0]=(int)((uint8_t)sc-(uint8_t)raw->lockt[sat-1][0])>0; - } - else { - lli[0]=0; - } - lli[0]|=((word1>>12)&7)?2:0; - raw->lockt[sat-1][0]=(uint8_t)sc; - dop[0]=((word2>>1)&0x7FFFFF)/512.0; - if ((word2>>24)&1) dop[0]=-dop[0]; - pr[0]=pr1+(word3&0xFFFF)/256.0; - cp[0]=floor(pr[0]*freq[0]/CLIGHT/8192.0)*8192.0; - cp[0]+=((word2&0xFE000000)+((word3&0xFFFF0000)>>7))/524288.0; - if (cp[0]-pr[0]*freq[0]/CLIGHT<-4096.0) cp[0]+=8192.0; - else if (cp[0]-pr[0]*freq[0]/CLIGHT> 4096.0) cp[0]-=8192.0; - - /* L2Obs */ - word1=U4(p+144+12*i); - word2=U4(p+148+12*i); - word3=U4(p+152+12*i); - sn=word1&0xFFF; - snr[1]=sn==0?0.0:10.0*log10(0.1164*sn)+SNR2CN0_L2; - sc=(uint32_t)(word1>>24); - if (raw->time.time==0) { - lli[1]=(int)((uint8_t)sc-(uint8_t)raw->lockt[sat-1][1])>0; - } - else { - lli[1]=0; - } - lli[1]|=((word1>>12)&7)?2:0; - raw->lockt[sat-1][1]=(uint8_t)sc; - dop[1]=((word2>>1)&0x7FFFFF)/512.0; - if ((word2>>24)&1) dop[1]=-dop[1]; - pr[1]=(word3&0xFFFF)/256.0; - if (pr[1]!=0.0) { - pr[1]+=pr1; - if (pr[1]-pr[0]<-128.0) pr[1]+=256.0; - else if (pr[1]-pr[0]> 128.0) pr[1]-=256.0; - cp[1]=floor(pr[1]*freq[1]/CLIGHT/8192.0)*8192.0; - cp[1]+=((word2&0xFE000000)+((word3&0xFFFF0000)>>7))/524288.0; - if (cp[1]-pr[1]*freq[1]/CLIGHT<-4096.0) cp[1]+=8192.0; - else if (cp[1]-pr[1]*freq[1]/CLIGHT> 4096.0) cp[1]-=8192.0; - } - raw->obs.data[n].time=time; - raw->obs.data[n].sat =sat; - for (j=0;jobs.data[n].P[j]=pr[j]==0.0?0.0:pr[j]-toff; - raw->obs.data[n].L[j]=cp[j]==0.0?0.0:cp[j]-toff*freq[j]/CLIGHT; - raw->obs.data[n].D[j]=-(float)dop[j]; - raw->obs.data[n].SNR[j]=snr[j]; - raw->obs.data[n].LLI[j]=(uint8_t)lli[j]; - raw->obs.data[n].code[j]=j==0?CODE_L1C:CODE_L2P; - } - else { - raw->obs.data[n].L[j]=raw->obs.data[n].P[j]=0.0; - raw->obs.data[n].D[j]=raw->obs.data[n].SNR[j]=0.0; - raw->obs.data[n].LLI[j]=0; - raw->obs.data[n].code[j]=CODE_NONE; - } - } - n++; + lli[1] |= ((word1 >> 12) & 7) ? 2 : 0; + raw->lockt[sat - 1][1] = (uint8_t)sc; + dop[1] = ((word2 >> 1) & 0x7FFFFF) / 512.0; + if ((word2 >> 24) & 1) dop[1] = -dop[1]; + pr[1] = (word3 & 0xFFFF) / 256.0; + if (pr[1] != 0.0) { + pr[1] += pr1; + if (pr[1] - pr[0] < -128.0) + pr[1] += 256.0; + else if (pr[1] - pr[0] > 128.0) + pr[1] -= 256.0; + cp[1] = floor(pr[1] * freq[1] / CLIGHT / 8192.0) * 8192.0; + cp[1] += ((word2 & 0xFE000000) + ((word3 & 0xFFFF0000) >> 7)) / 524288.0; + if (cp[1] - pr[1] * freq[1] / CLIGHT < -4096.0) + cp[1] += 8192.0; + else if (cp[1] - pr[1] * freq[1] / CLIGHT > 4096.0) + cp[1] -= 8192.0; } - raw->time=time; - raw->obs.n=n; - return 1; + raw->obs.data[n].time = time; + raw->obs.data[n].sat = sat; + for (j = 0; j < NFREQ; j++) { + if (j == 0 || (j == 1 && i < 12)) { + raw->obs.data[n].P[j] = pr[j] == 0.0 ? 0.0 : pr[j] - toff; + raw->obs.data[n].L[j] = cp[j] == 0.0 ? 0.0 : cp[j] - toff * freq[j] / CLIGHT; + raw->obs.data[n].D[j] = -(float)dop[j]; + raw->obs.data[n].SNR[j] = snr[j]; + raw->obs.data[n].LLI[j] = (uint8_t)lli[j]; + raw->obs.data[n].code[j] = j == 0 ? CODE_L1C : CODE_L2P; + } else { + raw->obs.data[n].L[j] = raw->obs.data[n].P[j] = 0.0; + raw->obs.data[n].D[j] = raw->obs.data[n].SNR[j] = 0.0; + raw->obs.data[n].LLI[j] = 0; + raw->obs.data[n].code[j] = CODE_NONE; + } + } + n++; + } + raw->time = time; + raw->obs.n = n; + return 1; } /* decode bin 65 glonass ephemeris -------------------------------------------*/ -static int decode_cresgloeph(raw_t *raw) -{ - geph_t geph={0}; - uint8_t *p=raw->buff+8,str[12]; - int i,j,k,sat,prn,frq,time,no; - - trace(4,"decode_cregloeph: len=%d\n",raw->len); - - if (!strstr(raw->opt,"-ENAGLO")) return 0; - - prn =U1(p); p+=1; - frq =U1(p)-8; p+=1+2; - time=U4(p); p+=4; - - if (!(sat=satno(SYS_GLO,prn))) { - trace(2,"creasent bin 65 satellite number error: prn=%d\n",prn); - return -1; - } - for (i=0;i<5;i++) { - for (j=0;j<3;j++) for (k=3;k>=0;k--) { - str[k+j*4]=U1(p++); - } - if ((no=getbitu(str,1,4))!=i+1) { - trace(2,"creasent bin 65 string no error: sat=%2d no=%d %d\n",sat, - i+1,no); - return -1; - } - memcpy(raw->subfrm[sat-1]+10*i,str,10); - } - /* decode glonass ephemeris strings */ - geph.tof=raw->time; - if (!decode_glostr(raw->subfrm[sat-1],&geph,NULL)||geph.sat!=sat) return -1; - geph.frq=frq; - - if (!strstr(raw->opt,"-EPHALL")) { - if (geph.iode==raw->nav.geph[prn-1].iode) return 0; /* unchanged */ +static int decode_cresgloeph(raw_t *raw) { + geph_t geph = {0}; + uint8_t *p = raw->buff + 8, str[12]; + int i, j, k, sat, prn, frq, time, no; + + trace(4, "decode_cregloeph: len=%d\n", raw->len); + + if (!strstr(raw->opt, "-ENAGLO")) return 0; + + prn = U1(p); + p += 1; + frq = U1(p) - 8; + p += 1 + 2; + time = U4(p); + p += 4; + + if (!(sat = satno(SYS_GLO, prn))) { + trace(2, "creasent bin 65 satellite number error: prn=%d\n", prn); + return -1; + } + for (i = 0; i < 5; i++) { + for (j = 0; j < 3; j++) + for (k = 3; k >= 0; k--) { + str[k + j * 4] = U1(p++); + } + if ((no = getbitu(str, 1, 4)) != i + 1) { + trace(2, "creasent bin 65 string no error: sat=%2d no=%d %d\n", sat, i + 1, no); + return -1; } - raw->nav.geph[prn-1]=geph; - raw->ephsat=sat; - raw->ephset=0; - return 2; + memcpy(raw->subfrm[sat - 1] + 10 * i, str, 10); + } + /* decode glonass ephemeris strings */ + geph.tof = raw->time; + if (!decode_glostr(raw->subfrm[sat - 1], &geph, NULL) || geph.sat != sat) return -1; + geph.frq = frq; + + if (!strstr(raw->opt, "-EPHALL")) { + if (geph.iode == raw->nav.geph[prn - 1].iode) return 0; /* unchanged */ + } + raw->nav.geph[prn - 1] = geph; + raw->ephsat = sat; + raw->ephset = 0; + return 2; } /* decode crescent raw message -----------------------------------------------*/ -static int decode_cres(raw_t *raw) -{ - int type=U2(raw->buff+4); - - trace(3,"decode_cres: type=%2d len=%d\n",type,raw->len); - - if (!chksum(raw->buff,raw->len)) { - trace(2,"crescent checksum error: type=%2d len=%d\n",type,raw->len); - return -1; - } - if (raw->outtype) { - sprintf(raw->msgtype,"HEMIS %2d (%4d):",type,raw->len); - } - switch (type) { - case ID_CRESPOS : return decode_crespos(raw); - case ID_CRESRAW : return decode_cresraw(raw); - case ID_CRESRAW2 : return decode_cresraw2(raw); - case ID_CRESEPH : return decode_creseph(raw); - case ID_CRESWAAS : return decode_creswaas(raw); - case ID_CRESIONUTC: return decode_cresionutc(raw); - case ID_CRESGLORAW: return decode_cresgloraw(raw); - case ID_CRESGLOEPH: return decode_cresgloeph(raw); - } - return 0; +static int decode_cres(raw_t *raw) { + int type = U2(raw->buff + 4); + + trace(3, "decode_cres: type=%2d len=%d\n", type, raw->len); + + if (!chksum(raw->buff, raw->len)) { + trace(2, "crescent checksum error: type=%2d len=%d\n", type, raw->len); + return -1; + } + if (raw->outtype) { + sprintf(raw->msgtype, "HEMIS %2d (%4d):", type, raw->len); + } + switch (type) { + case ID_CRESPOS: + return decode_crespos(raw); + case ID_CRESRAW: + return decode_cresraw(raw); + case ID_CRESRAW2: + return decode_cresraw2(raw); + case ID_CRESEPH: + return decode_creseph(raw); + case ID_CRESWAAS: + return decode_creswaas(raw); + case ID_CRESIONUTC: + return decode_cresionutc(raw); + case ID_CRESGLORAW: + return decode_cresgloraw(raw); + case ID_CRESGLOEPH: + return decode_cresgloeph(raw); + } + return 0; } /* sync code -----------------------------------------------------------------*/ -static int sync_cres(uint8_t *buff, uint8_t data) -{ - buff[0]=buff[1]; buff[1]=buff[2]; buff[2]=buff[3]; buff[3]=data; - return buff[0]==CRESSYNC[0]&&buff[1]==CRESSYNC[1]&& - buff[2]==CRESSYNC[2]&&buff[3]==CRESSYNC[3]; +static int sync_cres(uint8_t *buff, uint8_t data) { + buff[0] = buff[1]; + buff[1] = buff[2]; + buff[2] = buff[3]; + buff[3] = data; + return buff[0] == CRESSYNC[0] && buff[1] == CRESSYNC[1] && buff[2] == CRESSYNC[2] && + buff[3] == CRESSYNC[3]; } /* input cresent raw message --------------------------------------------------- -* input next crescent raw message from stream -* args : raw_t *raw IO receiver raw data control struct -* uint8_t data I stream data (1 byte) -* return : status (-1: error message, 0: no message, 1: input observation data, -* 2: input ephemeris, 3: input sbas message, -* 9: input ion/utc parameter) -* -* notes : to specify input options, set raw->opt to the following option -* strings separated by spaces. -* -* -EPHALL : input all ephemerides -* -TTCORR : time-tag offset correction -* -ENAGLO : enable glonass messages -* -*-----------------------------------------------------------------------------*/ -extern int input_cres(raw_t *raw, uint8_t data) -{ - trace(5,"input_cres: data=%02x\n",data); - - /* synchronize frame */ - if (raw->nbyte==0) { - if (!sync_cres(raw->buff,data)) return 0; - raw->nbyte=4; - return 0; - } - raw->buff[raw->nbyte++]=data; - - if (raw->nbyte==8) { - if ((raw->len=U2(raw->buff+6)+12)>MAXRAWLEN) { - trace(2,"cresent length error: len=%d\n",raw->len); - raw->nbyte=0; - return -1; - } + * input next crescent raw message from stream + * args : raw_t *raw IO receiver raw data control struct + * uint8_t data I stream data (1 byte) + * return : status (-1: error message, 0: no message, 1: input observation data, + * 2: input ephemeris, 3: input sbas message, + * 9: input ion/utc parameter) + * + * notes : to specify input options, set raw->opt to the following option + * strings separated by spaces. + * + * -EPHALL : input all ephemerides + * -TTCORR : time-tag offset correction + * -ENAGLO : enable glonass messages + * + *-----------------------------------------------------------------------------*/ +extern int input_cres(raw_t *raw, uint8_t data) { + trace(5, "input_cres: data=%02x\n", data); + + /* synchronize frame */ + if (raw->nbyte == 0) { + if (!sync_cres(raw->buff, data)) return 0; + raw->nbyte = 4; + return 0; + } + raw->buff[raw->nbyte++] = data; + + if (raw->nbyte == 8) { + if ((raw->len = U2(raw->buff + 6) + 12) > MAXRAWLEN) { + trace(2, "cresent length error: len=%d\n", raw->len); + raw->nbyte = 0; + return -1; } - if (raw->nbyte<8||raw->nbytelen) return 0; - raw->nbyte=0; - - /* decode crescent raw message */ - return decode_cres(raw); + } + if (raw->nbyte < 8 || raw->nbyte < raw->len) return 0; + raw->nbyte = 0; + + /* decode crescent raw message */ + return decode_cres(raw); } /* input crescent raw message from file ---------------------------------------- -* input next crescent raw message from file -* args : raw_t *raw IO receiver raw data control struct -* FILE *fp I file pointer -* return : status(-2: end of file, -1...9: same as above) -*-----------------------------------------------------------------------------*/ -extern int input_cresf(raw_t *raw, FILE *fp) -{ - int i,data; - - trace(4,"input_cresf:\n"); - - /* synchronize frame */ - if (raw->nbyte==0) { - for (i=0;;i++) { - if ((data=fgetc(fp))==EOF) return -2; - if (sync_cres(raw->buff,(uint8_t)data)) break; - if (i>=4096) return 0; - } - } - if (fread(raw->buff+4,1,4,fp)<4) return -2; - raw->nbyte=8; - - if ((raw->len=U2(raw->buff+6)+12)>MAXRAWLEN) { - trace(2,"crescent length error: len=%d\n",raw->len); - raw->nbyte=0; - return -1; + * input next crescent raw message from file + * args : raw_t *raw IO receiver raw data control struct + * FILE *fp I file pointer + * return : status(-2: end of file, -1...9: same as above) + *-----------------------------------------------------------------------------*/ +extern int input_cresf(raw_t *raw, FILE *fp) { + int i, data; + + trace(4, "input_cresf:\n"); + + /* synchronize frame */ + if (raw->nbyte == 0) { + for (i = 0;; i++) { + if ((data = fgetc(fp)) == EOF) return -2; + if (sync_cres(raw->buff, (uint8_t)data)) break; + if (i >= 4096) return 0; } - if (fread(raw->buff+8,1,raw->len-8,fp)<(size_t)(raw->len-8)) return -2; - raw->nbyte=0; - - /* decode crescent raw message */ - return decode_cres(raw); + } + if (fread(raw->buff + 4, 1, 4, fp) < 4) return -2; + raw->nbyte = 8; + + if ((raw->len = U2(raw->buff + 6) + 12) > MAXRAWLEN) { + trace(2, "crescent length error: len=%d\n", raw->len); + raw->nbyte = 0; + return -1; + } + if (fread(raw->buff + 8, 1, raw->len - 8, fp) < (size_t)(raw->len - 8)) return -2; + raw->nbyte = 0; + + /* decode crescent raw message */ + return decode_cres(raw); } diff --git a/src/rcv/javad.c b/src/rcv/javad.c index 77f64ee6d..b9097de1f 100644 --- a/src/rcv/javad.c +++ b/src/rcv/javad.c @@ -1,1893 +1,2022 @@ /*------------------------------------------------------------------------------ -* javad.c : javad receiver dependent functions -* -* Copyright (C) 2011-2020 by T.TAKASU, All rights reserved. -* -* reference : -* [1] Javad GNSS, GREIS GNSS Receiver External Interface Specification, -* Reflects Firmware Version 3.2.0, July 22, 2010 -* [2] Javad navigation systemms, GPS Receiver Interface Language (GRIL) -* Reference Guide Rev 2.2, Reflects Firmware Version 2.6.0 -* [3] Javad GNSS, User visible changes in the firmware vesion 3.4.0 since -* version 3.3.x (NEWS_3_4_0.txt) -* [4] Javad GNSS, GREIS GNSS Receiver External Interface Specification, -* Reflects Firmware Version 3.4.6, October 9, 2012 -* [5] Javad GNSS, GREIS GNSS Receiver External Interface Specification, -* Reflects Firmware Version 3.5.4, January 30, 2014 -* [6] Javad GNSS, GREIS GNSS Receiver External Interface Specification, -* Reflects Firmware Version 3.6.7, August 25, 2016 -* [7] Javad GNSS, GREIS GNSS Receiver External Interface Specification, -* Reflects Firmware Version 3.7.2, October 11, 2017 -* -* version : $Revision:$ $Date:$ -* history : 2011/05/27 1.0 new -* 2011/07/07 1.1 fix QZSS IODC-only-update problem -* 2012/07/17 1.2 change GALILEO scale factor for short pseudorange -* 2012/10/18 1.3 change receiver options and rinex obs code -* 2013/01/24 1.4 change compass factor for short pseudorange -* add raw option -NOET -* 2013/02/23 1.6 fix memory access violation problem on arm -* 2013/05/08 1.7 fix bug on week number of galileo ephemeris -* 2014/05/23 1.8 support beidou -* 2014/06/23 1.9 support [lD] for glonass raw navigation data -* 2014/08/26 1.10 fix bug on decoding iode in glonass ephemeris [NE] -* 2014/10/20 1.11 fix bug on receiver option -GL*,-RL*,-JL* -* 2016/01/26 1.12 fix problem on bus-error on ARM CPU (#129) -* 2017/04/11 1.13 support IRNSS -* fix bug on carrier frequency for beidou -* fix bug on unchange-test for beidou ephemeris -* update Asys coef for [r*] short pseudorange by [6] -* (char *) -> (signed char *) -* 2018/10/10 1.14 update signal allocation by ref [7] -* update Ksys value for galileo by ref [7] -* fix problem to set eph->code for beidou and galileo -* fix bug on saving galileo bgd to ephemeris -* add receiver option -GALINAV, -GALFNAV -* 2019/05/10 1.15 save galileo E5b data to obs index 2 -* 2020/11/30 1.16 output L1C for GLONASS G1 as default -* change receiver option -RL1C -> -RL1P -* CODE_L1I -> CODE_L2I for BDS B1I (RINEX 3.04) -* output GAL I/NAV and F/NAV to separated ephem sets -* fix bug on decoding SVH in message [NE] for GLONASS -* use API code2idx() to get freq-index -* use integer types in stdint.h -*-----------------------------------------------------------------------------*/ + * javad.c : javad receiver dependent functions + * + * Copyright (C) 2011-2020 by T.TAKASU, All rights reserved. + * + * reference : + * [1] Javad GNSS, GREIS GNSS Receiver External Interface Specification, + * Reflects Firmware Version 3.2.0, July 22, 2010 + * [2] Javad navigation systemms, GPS Receiver Interface Language (GRIL) + * Reference Guide Rev 2.2, Reflects Firmware Version 2.6.0 + * [3] Javad GNSS, User visible changes in the firmware vesion 3.4.0 since + * version 3.3.x (NEWS_3_4_0.txt) + * [4] Javad GNSS, GREIS GNSS Receiver External Interface Specification, + * Reflects Firmware Version 3.4.6, October 9, 2012 + * [5] Javad GNSS, GREIS GNSS Receiver External Interface Specification, + * Reflects Firmware Version 3.5.4, January 30, 2014 + * [6] Javad GNSS, GREIS GNSS Receiver External Interface Specification, + * Reflects Firmware Version 3.6.7, August 25, 2016 + * [7] Javad GNSS, GREIS GNSS Receiver External Interface Specification, + * Reflects Firmware Version 3.7.2, October 11, 2017 + * + * version : $Revision:$ $Date:$ + * history : 2011/05/27 1.0 new + * 2011/07/07 1.1 fix QZSS IODC-only-update problem + * 2012/07/17 1.2 change GALILEO scale factor for short pseudorange + * 2012/10/18 1.3 change receiver options and rinex obs code + * 2013/01/24 1.4 change compass factor for short pseudorange + * add raw option -NOET + * 2013/02/23 1.6 fix memory access violation problem on arm + * 2013/05/08 1.7 fix bug on week number of galileo ephemeris + * 2014/05/23 1.8 support beidou + * 2014/06/23 1.9 support [lD] for glonass raw navigation data + * 2014/08/26 1.10 fix bug on decoding iode in glonass ephemeris [NE] + * 2014/10/20 1.11 fix bug on receiver option -GL*,-RL*,-JL* + * 2016/01/26 1.12 fix problem on bus-error on ARM CPU (#129) + * 2017/04/11 1.13 support IRNSS + * fix bug on carrier frequency for beidou + * fix bug on unchange-test for beidou ephemeris + * update Asys coef for [r*] short pseudorange by [6] + * (char *) -> (signed char *) + * 2018/10/10 1.14 update signal allocation by ref [7] + * update Ksys value for galileo by ref [7] + * fix problem to set eph->code for beidou and galileo + * fix bug on saving galileo bgd to ephemeris + * add receiver option -GALINAV, -GALFNAV + * 2019/05/10 1.15 save galileo E5b data to obs index 2 + * 2020/11/30 1.16 output L1C for GLONASS G1 as default + * change receiver option -RL1C -> -RL1P + * CODE_L1I -> CODE_L2I for BDS B1I (RINEX 3.04) + * output GAL I/NAV and F/NAV to separated ephem sets + * fix bug on decoding SVH in message [NE] for GLONASS + * use API code2idx() to get freq-index + * use integer types in stdint.h + *-----------------------------------------------------------------------------*/ #include "rtklib.h" #define PREAMB_CNAV 0x8B -#define ISTXT(c) ('0'<=(c)&&(c)<='~') -#define ISHEX(c) (('0'<=(c)&&(c)<='9')||('A'<=(c)&&(c)<='F')) -#define ROT_LEFT(val) (((val)<<2)|((val)>>6)) +#define ISTXT(c) ('0' <= (c) && (c) <= '~') +#define ISHEX(c) (('0' <= (c) && (c) <= '9') || ('A' <= (c) && (c) <= 'F')) +#define ROT_LEFT(val) (((val) << 2) | ((val) >> 6)) /* extract field (little-endian) ---------------------------------------------*/ #define U1(p) (*((uint8_t *)(p))) -#define I1(p) (*((int8_t *)(p))) -static uint16_t U2(uint8_t *p) {uint16_t u; memcpy(&u,p,2); return u;} -static uint32_t U4(uint8_t *p) {uint32_t u; memcpy(&u,p,4); return u;} -static int16_t I2(uint8_t *p) {int16_t i; memcpy(&i,p,2); return i;} -static int32_t I4(uint8_t *p) {int32_t i; memcpy(&i,p,4); return i;} - -static float R4(uint8_t *p) -{ - float value; - uint8_t *q=(uint8_t *)&value; - int i; - if (U4(p)==0x7FC00000) return 0.0f; /* quiet nan */ - for (i=0;i<4;i++) *q++=*p++; - return value; -} -static double R8(uint8_t *p) -{ - double value; - uint8_t *q=(uint8_t *)&value; - int i; - if (U4(p+4)==0x7FF80000&&U4(p)==0) return 0.0; /* quiet nan */ - for (i=0;i<8;i++) *q++=*p++; - return value; +#define I1(p) (*((int8_t *)(p))) +static uint16_t U2(uint8_t *p) { + uint16_t u; + memcpy(&u, p, 2); + return u; +} +static uint32_t U4(uint8_t *p) { + uint32_t u; + memcpy(&u, p, 4); + return u; +} +static int16_t I2(uint8_t *p) { + int16_t i; + memcpy(&i, p, 2); + return i; +} +static int32_t I4(uint8_t *p) { + int32_t i; + memcpy(&i, p, 4); + return i; +} + +static float R4(uint8_t *p) { + float value; + uint8_t *q = (uint8_t *)&value; + int i; + if (U4(p) == 0x7FC00000) return 0.0f; /* quiet nan */ + for (i = 0; i < 4; i++) *q++ = *p++; + return value; +} +static double R8(uint8_t *p) { + double value; + uint8_t *q = (uint8_t *)&value; + int i; + if (U4(p + 4) == 0x7FF80000 && U4(p) == 0) return 0.0; /* quiet nan */ + for (i = 0; i < 8; i++) *q++ = *p++; + return value; } /* decode message length -----------------------------------------------------*/ -static int decodelen(const uint8_t *buff) -{ - uint32_t len; - if (!ISHEX(buff[0])||!ISHEX(buff[1])||!ISHEX(buff[2])) return 0; - if (sscanf((char *)buff,"%3X",&len)==1) return (int)len; - return 0; +static int decodelen(const uint8_t *buff) { + uint32_t len; + if (!ISHEX(buff[0]) || !ISHEX(buff[1]) || !ISHEX(buff[2])) return 0; + if (sscanf((char *)buff, "%3X", &len) == 1) return (int)len; + return 0; } /* test measurement data -----------------------------------------------------*/ -static int is_meas(char sig) -{ - return sig=='c'||sig=='C'||sig=='1'||sig=='2'||sig=='3'||sig=='5'||sig=='l'; +static int is_meas(char sig) { + return sig == 'c' || sig == 'C' || sig == '1' || sig == '2' || sig == '3' || sig == '5' || + sig == 'l'; } /* convert signal to freq-index ----------------------------------------------*/ -static int sig2idx(int sys, char sig, int *code) -{ - const uint8_t codes[7][6]={ /* ref [7] table 3-8 */ - /* c/C 1 2 3 5 l */ - /* (CA/L1 P/L1 P/L2 CA/L2 L5 L1C) */ - {CODE_L1C,CODE_L1W,CODE_L2W,CODE_L2X,CODE_L5X,CODE_L1X}, /* GPS */ - {CODE_L1C,CODE_L1Z,CODE_L6X,CODE_L2X,CODE_L5X,CODE_L1X}, /* QZS */ - {CODE_L1C,0 ,0 ,0 ,CODE_L5X,0 }, /* SBS */ - {CODE_L1X,CODE_L8X,CODE_L7X,CODE_L6X,CODE_L5X,0 }, /* GAL */ - {CODE_L1C,CODE_L1P,CODE_L2P,CODE_L2C,CODE_L3X,0 }, /* GLO */ - {CODE_L2I,0 ,CODE_L7I,CODE_L6I,CODE_L5X,CODE_L1X}, /* BDS */ - {0 ,0 ,0 ,0 ,CODE_L5X,0 } /* IRN */ - }; - int i,j,idx; - - switch (sig) { - case 'c': - case 'C': i=0; break; - case '1': i=1; break; - case '2': i=2; break; - case '3': i=3; break; - case '5': i=4; break; - case 'l': i=5; break; - default: return -1; - } - switch (sys) { - case SYS_GPS: j=0; break; - case SYS_QZS: j=1; break; - case SYS_SBS: j=2; break; - case SYS_GAL: j=3; break; - case SYS_GLO: j=4; break; - case SYS_CMP: j=5; break; - case SYS_IRN: j=6; break; - default: return -1; - } - if (!(*code=codes[j][i])) return -1; - idx=code2idx(sys,(uint8_t)*code); - return idxtow_p+302400.0) tow-=604800.0; - return gpst2time(week,tow); +static gtime_t adjweek(gtime_t time, double tow) { + double tow_p; + int week; + tow_p = time2gpst(time, &week); + if (tow < tow_p - 302400.0) + tow += 604800.0; + else if (tow > tow_p + 302400.0) + tow -= 604800.0; + return gpst2time(week, tow); } /* adjust daily rollover of time ---------------------------------------------*/ -static gtime_t adjday(gtime_t time, double tod) -{ - double ep[6],tod_p; - time2epoch(time,ep); - tod_p=ep[3]*3600.0+ep[4]*60.0+ep[5]; - if (todtod_p+43200.0) tod-=86400.0; - ep[3]=ep[4]=ep[5]=0.0; - return timeadd(epoch2time(ep),tod); +static gtime_t adjday(gtime_t time, double tod) { + double ep[6], tod_p; + time2epoch(time, ep); + tod_p = ep[3] * 3600.0 + ep[4] * 60.0 + ep[5]; + if (tod < tod_p - 43200.0) + tod += 86400.0; + else if (tod > tod_p + 43200.0) + tod -= 86400.0; + ep[3] = ep[4] = ep[5] = 0.0; + return timeadd(epoch2time(ep), tod); } /* set time tag --------------------------------------------------------------*/ -static int settag(obsd_t *data, gtime_t time) -{ - char s1[40],s2[40]; - - if (data->time.time!=0&&fabs(timediff(data->time,time))>5E-4) { - time2str(data->time,s1,4); time2str(time,s2,4); - trace(2,"time inconsistent: time=%s %s sat=%2d\n",s1,s2,data->sat); - return 0; - } - data->time=time; - return 1; +static int settag(obsd_t *data, gtime_t time) { + char s1[40], s2[40]; + + if (data->time.time != 0 && fabs(timediff(data->time, time)) > 5E-4) { + time2str(data->time, s1, 4); + time2str(time, s2, 4); + trace(2, "time inconsistent: time=%s %s sat=%2d\n", s1, s2, data->sat); + return 0; + } + data->time = time; + return 1; } /* flush observation data buffer ---------------------------------------------*/ -static int flushobuf(raw_t *raw) -{ - gtime_t time0={0}; - int i,j,n=0; - - trace(3,"flushobuf: n=%d\n",raw->obuf.n); - - /* copy observation data buffer */ - for (i=0;iobuf.n&&iobuf.data[i].sat,NULL)) continue; - if (raw->obuf.data[i].time.time==0) continue; - raw->obs.data[n++]=raw->obuf.data[i]; - } - raw->obs.n=n; - - /* clear observation data buffer */ - for (i=0;iobuf.data[i].time=time0; - for (j=0;jobuf.data[i].L[j]=raw->obuf.data[i].P[j]=0.0; - raw->obuf.data[i].D[j]=raw->obuf.data[i].SNR[j]=0.0; - raw->obuf.data[i].LLI[j]=0; - raw->obuf.data[i].code[j]=CODE_NONE; - } - } - for (i=0;iprCA[i]=raw->dpCA[i]=0.0; - return n>0?1:0; +static int flushobuf(raw_t *raw) { + gtime_t time0 = {0}; + int i, j, n = 0; + + trace(3, "flushobuf: n=%d\n", raw->obuf.n); + + /* copy observation data buffer */ + for (i = 0; i < raw->obuf.n && i < MAXOBS; i++) { + if (!satsys(raw->obuf.data[i].sat, NULL)) continue; + if (raw->obuf.data[i].time.time == 0) continue; + raw->obs.data[n++] = raw->obuf.data[i]; + } + raw->obs.n = n; + + /* clear observation data buffer */ + for (i = 0; i < MAXOBS; i++) { + raw->obuf.data[i].time = time0; + for (j = 0; j < NFREQ + NEXOBS; j++) { + raw->obuf.data[i].L[j] = raw->obuf.data[i].P[j] = 0.0; + raw->obuf.data[i].D[j] = raw->obuf.data[i].SNR[j] = 0.0; + raw->obuf.data[i].LLI[j] = 0; + raw->obuf.data[i].code[j] = CODE_NONE; + } + } + for (i = 0; i < MAXSAT; i++) raw->prCA[i] = raw->dpCA[i] = 0.0; + return n > 0 ? 1 : 0; } /* decode [~~] receiver time -------------------------------------------------*/ -static int decode_RT(raw_t *raw) -{ - gtime_t time; - char *msg; - uint8_t *p=raw->buff+5; - - if (!checksum(raw->buff,raw->len)) { - trace(2,"javad RT error: len=%d\n",raw->len); - return -1; - } - if (raw->len<10) { - trace(2,"javad RT length error: len=%d\n",raw->len); - return -1; - } - raw->tod=U4(p); - - if (raw->time.time==0) return 0; - - /* update receiver time */ - time=raw->time; - if (raw->tbase>=1) time=gpst2utc(time); /* GPST->UTC */ - time=adjday(time,raw->tod*0.001); - if (raw->tbase>=1) time=utc2gpst(time); /* UTC->GPST */ - raw->time=time; - - char tstr[40]; - trace(3,"decode_RT: time=%s\n",time2str(time,tstr,3)); - - if (raw->outtype) { - msg=raw->msgtype+strlen(raw->msgtype); - sprintf(msg," %s",time2str(time,tstr,3)); - } - /* flush observation data buffer */ - return flushobuf(raw); +static int decode_RT(raw_t *raw) { + gtime_t time; + char *msg; + uint8_t *p = raw->buff + 5; + + if (!checksum(raw->buff, raw->len)) { + trace(2, "javad RT error: len=%d\n", raw->len); + return -1; + } + if (raw->len < 10) { + trace(2, "javad RT length error: len=%d\n", raw->len); + return -1; + } + raw->tod = U4(p); + + if (raw->time.time == 0) return 0; + + /* update receiver time */ + time = raw->time; + if (raw->tbase >= 1) time = gpst2utc(time); /* GPST->UTC */ + time = adjday(time, raw->tod * 0.001); + if (raw->tbase >= 1) time = utc2gpst(time); /* UTC->GPST */ + raw->time = time; + + char tstr[40]; + trace(3, "decode_RT: time=%s\n", time2str(time, tstr, 3)); + + if (raw->outtype) { + msg = raw->msgtype + strlen(raw->msgtype); + sprintf(msg, " %s", time2str(time, tstr, 3)); + } + /* flush observation data buffer */ + return flushobuf(raw); } /* decode [::] epoch time ----------------------------------------------------*/ -static int decode_ET(raw_t *raw) -{ - uint8_t *p=raw->buff+5; - - if (!checksum(raw->buff,raw->len)) { - trace(2,"javad ET checksum error: len=%d\n",raw->len); - return -1; - } - if (raw->len<10) { - trace(2,"javad ET length error: len=%d\n",raw->len); - return -1; - } - if (raw->tod!=(int)U4(p)) { - trace(2,"javad ET inconsistent tod: tod=%d %d\n",raw->tod,U4(p)); - return -1; - } - raw->tod=-1; /* end of epoch */ - - /* flush observation data buffer */ - return flushobuf(raw); +static int decode_ET(raw_t *raw) { + uint8_t *p = raw->buff + 5; + + if (!checksum(raw->buff, raw->len)) { + trace(2, "javad ET checksum error: len=%d\n", raw->len); + return -1; + } + if (raw->len < 10) { + trace(2, "javad ET length error: len=%d\n", raw->len); + return -1; + } + if (raw->tod != (int)U4(p)) { + trace(2, "javad ET inconsistent tod: tod=%d %d\n", raw->tod, U4(p)); + return -1; + } + raw->tod = -1; /* end of epoch */ + + /* flush observation data buffer */ + return flushobuf(raw); } /* decode [RD] receiver date -------------------------------------------------*/ -static int decode_RD(raw_t *raw) -{ - double ep[6]={0}; - char *msg; - uint8_t *p=raw->buff+5; - - if (!checksum(raw->buff,raw->len)) { - trace(2,"javad RD checksum error: len=%d\n",raw->len); - return -1; - } - if (raw->len<11) { - trace(2,"javad RD length error: len=%d\n",raw->len); - return -1; - } - ep[0]=U2(p); p+=2; - ep[1]=U1(p); p+=1; - ep[2]=U1(p); p+=1; - raw->tbase=U1(p); - - if (raw->outtype) { - msg=raw->msgtype+strlen(raw->msgtype); - sprintf(msg," %04.0f/%02.0f/%02.0f base=%d",ep[0],ep[1],ep[2],raw->tbase); - } - if (raw->tod<0) { - trace(2,"javad RD lack of preceding RT\n"); - return 0; - } - raw->time=timeadd(epoch2time(ep),raw->tod*0.001); - if (raw->tbase>=1) raw->time=utc2gpst(raw->time); /* UTC->GPST */ - - char tstr[40]; - trace(3,"decode_RD: time=%s\n",time2str(raw->time,tstr,3)); - +static int decode_RD(raw_t *raw) { + double ep[6] = {0}; + char *msg; + uint8_t *p = raw->buff + 5; + + if (!checksum(raw->buff, raw->len)) { + trace(2, "javad RD checksum error: len=%d\n", raw->len); + return -1; + } + if (raw->len < 11) { + trace(2, "javad RD length error: len=%d\n", raw->len); + return -1; + } + ep[0] = U2(p); + p += 2; + ep[1] = U1(p); + p += 1; + ep[2] = U1(p); + p += 1; + raw->tbase = U1(p); + + if (raw->outtype) { + msg = raw->msgtype + strlen(raw->msgtype); + sprintf(msg, " %04.0f/%02.0f/%02.0f base=%d", ep[0], ep[1], ep[2], raw->tbase); + } + if (raw->tod < 0) { + trace(2, "javad RD lack of preceding RT\n"); return 0; + } + raw->time = timeadd(epoch2time(ep), raw->tod * 0.001); + if (raw->tbase >= 1) raw->time = utc2gpst(raw->time); /* UTC->GPST */ + + char tstr[40]; + trace(3, "decode_RD: time=%s\n", time2str(raw->time, tstr, 3)); + + return 0; } /* decode [SI] satellite indices ---------------------------------------------*/ -static int decode_SI(raw_t *raw) -{ - int i,usi,sat; - char *msg; - uint8_t *p=raw->buff+5; - - if (!checksum(raw->buff,raw->len)) { - trace(2,"javad SI checksum error: len=%d\n",raw->len); - return -1; - } - raw->obuf.n=raw->len-6; - - for (i=0;iobuf.n&&iobuf.data[i].time=raw->time; - raw->obuf.data[i].sat=sat; - - /* glonass fcn (frequency channel number) */ - if (sat==255) raw->freqn[i]=usi-45; - } - trace(4,"decode_SI: nsat=raw->obuf.n\n"); - - if (raw->outtype) { - msg=raw->msgtype+strlen(raw->msgtype); - sprintf(msg," nsat=%2d",raw->obuf.n); - } - return 0; +static int decode_SI(raw_t *raw) { + int i, usi, sat; + char *msg; + uint8_t *p = raw->buff + 5; + + if (!checksum(raw->buff, raw->len)) { + trace(2, "javad SI checksum error: len=%d\n", raw->len); + return -1; + } + raw->obuf.n = raw->len - 6; + + for (i = 0; i < raw->obuf.n && i < MAXOBS; i++) { + usi = U1(p); + p += 1; + + if (usi <= 0) + sat = 0; /* ref [5] table 3-6 */ + else if (usi <= 37) + sat = satno(SYS_GPS, usi); /* 1- 37: GPS */ + else if (usi <= 70) + sat = 255; /* 38- 70: GLONASS */ + else if (usi <= 119) + sat = satno(SYS_GAL, usi - 70); /* 71-119: GALILEO */ + else if (usi <= 142) + sat = satno(SYS_SBS, usi); /* 120-142: SBAS */ + else if (usi <= 192) + sat = 0; + else if (usi <= 197) + sat = satno(SYS_QZS, usi); /* 193-197: QZSS */ + else if (usi <= 210) + sat = 0; + else if (usi <= 240) + sat = satno(SYS_CMP, usi - 210); /* 211-240: BeiDou */ + else if (usi <= 247) + sat = satno(SYS_IRN, usi - 240); /* 241-247: IRNSS */ + else + sat = 0; + + raw->obuf.data[i].time = raw->time; + raw->obuf.data[i].sat = sat; + + /* glonass fcn (frequency channel number) */ + if (sat == 255) raw->freqn[i] = usi - 45; + } + trace(4, "decode_SI: nsat=raw->obuf.n\n"); + + if (raw->outtype) { + msg = raw->msgtype + strlen(raw->msgtype); + sprintf(msg, " nsat=%2d", raw->obuf.n); + } + return 0; } /* decode [NN] GLONASS satellite system numbers ------------------------------*/ -static int decode_NN(raw_t *raw) -{ - uint8_t *p=raw->buff+5; - char *msg; - int i,n,ns,slot,sat,index[MAXOBS]; - - if (!checksum(raw->buff,raw->len)) { - trace(2,"javad NN checksum error: len=%d\n",raw->len); - return -1; - } - for (i=n=0;iobuf.n&&iobuf.data[i].sat==255) index[n++]=i; - } - ns=raw->len-6; - - for (i=0;iobuf.data[index[i]].sat=sat; - } - if (raw->outtype) { - msg=raw->msgtype+strlen(raw->msgtype); - sprintf(msg," nsat=%2d",ns); - } - return 0; +static int decode_NN(raw_t *raw) { + uint8_t *p = raw->buff + 5; + char *msg; + int i, n, ns, slot, sat, index[MAXOBS]; + + if (!checksum(raw->buff, raw->len)) { + trace(2, "javad NN checksum error: len=%d\n", raw->len); + return -1; + } + for (i = n = 0; i < raw->obuf.n && i < MAXOBS; i++) { + if (raw->obuf.data[i].sat == 255) index[n++] = i; + } + ns = raw->len - 6; + + for (i = 0; i < ns && i < n; i++) { + slot = U1(p); + p += 1; + sat = satno(SYS_GLO, slot); + raw->obuf.data[index[i]].sat = sat; + } + if (raw->outtype) { + msg = raw->msgtype + strlen(raw->msgtype); + sprintf(msg, " nsat=%2d", ns); + } + return 0; } /* decode [GA] GPS almanac ---------------------------------------------------*/ -static int decode_GA(raw_t *raw) -{ - (void)raw; - trace(3,"javad GA unsupported\n"); - - return 0; +static int decode_GA(raw_t *raw) { + (void)raw; + trace(3, "javad GA unsupported\n"); + + return 0; } /* decode [NA] GLONASS almanac -----------------------------------------------*/ -static int decode_NA(raw_t *raw) -{ - (void)raw; - trace(3,"javad NA unsupported\n"); - - return 0; +static int decode_NA(raw_t *raw) { + (void)raw; + trace(3, "javad NA unsupported\n"); + + return 0; } /* decode [EA] Galileo almanac -----------------------------------------------*/ -static int decode_EA(raw_t *raw) -{ - (void)raw; - trace(3,"javad EA unsupported\n"); - - return 0; +static int decode_EA(raw_t *raw) { + (void)raw; + trace(3, "javad EA unsupported\n"); + + return 0; } /* decode [WA] WAAS almanac --------------------------------------------------*/ -static int decode_WA(raw_t *raw) -{ - (void)raw; - trace(3,"javad WA unsupported\n"); - - return 0; +static int decode_WA(raw_t *raw) { + (void)raw; + trace(3, "javad WA unsupported\n"); + + return 0; } /* decode [QA] QZSS almanac --------------------------------------------------*/ -static int decode_QA(raw_t *raw) -{ - (void)raw; - trace(3,"javad QA unsupported\n"); - - return 0; +static int decode_QA(raw_t *raw) { + (void)raw; + trace(3, "javad QA unsupported\n"); + + return 0; } /* decode [CA] Beidou almanac ------------------------------------------------*/ -static int decode_CA(raw_t *raw) -{ - (void)raw; - trace(3,"javad CA unsupported\n"); - - return 0; +static int decode_CA(raw_t *raw) { + (void)raw; + trace(3, "javad CA unsupported\n"); + + return 0; } /* decode [IA] IRNSS almanac -------------------------------------------------*/ -static int decode_IA(raw_t *raw) -{ - (void)raw; - trace(3,"javad IA unsupported\n"); - - return 0; +static int decode_IA(raw_t *raw) { + (void)raw; + trace(3, "javad IA unsupported\n"); + + return 0; } /* decode GPS/Galileo/QZSS/Beidou ephemeris ----------------------------------*/ -static int decode_eph(raw_t *raw, int sys) -{ - eph_t eph={0}; - double toc,sqrtA,tt; - char *msg; - int sat,prn,tow,flag,week,navtype,sigtype,set=0; - int eph_sel=3; /* Galileo ephemeris selection */ - uint8_t *p=raw->buff+5; - - trace(3,"decode_eph: sys=%2d prn=%3d\n",sys,U1(p)); - - if (strstr(raw->opt,"-GALINAV")) eph_sel=1; - if (strstr(raw->opt,"-GALFNAV")) eph_sel=2; - - prn =U1(p); p+=1; - tow =U4(p); p+=4; - flag =U1(p); p+=1; - eph.iodc =I2(p); p+=2; - toc =I4(p); p+=4; - eph.sva =I1(p); p+=1; - eph.svh =U1(p); p+=1; - week =I2(p); p+=2; - eph.tgd[0]=R4(p); p+=4; - eph.f2 =R4(p); p+=4; - eph.f1 =R4(p); p+=4; - eph.f0 =R4(p); p+=4; - eph.toes =I4(p); p+=4; - eph.iode =I2(p); p+=2; - sqrtA =R8(p); p+=8; - eph.e =R8(p); p+=8; - eph.M0 =R8(p)*SC2RAD; p+=8; - eph.OMG0 =R8(p)*SC2RAD; p+=8; - eph.i0 =R8(p)*SC2RAD; p+=8; - eph.omg =R8(p)*SC2RAD; p+=8; - eph.deln =R4(p)*SC2RAD; p+=4; - eph.OMGd =R4(p)*SC2RAD; p+=4; - eph.idot =R4(p)*SC2RAD; p+=4; - eph.crc =R4(p); p+=4; - eph.crs =R4(p); p+=4; - eph.cuc =R4(p); p+=4; - eph.cus =R4(p); p+=4; - eph.cic =R4(p); p+=4; - eph.cis =R4(p); p+=4; - eph.A =sqrtA*sqrtA; - - if (raw->outtype) { - msg=raw->msgtype+strlen(raw->msgtype); - sprintf(msg," prn=%3d iode=%3d iodc=%3d toes=%6.0f",prn,eph.iode, - eph.iodc,eph.toes); - } - if (sys==SYS_GPS||sys==SYS_QZS||sys==SYS_IRN) { - if (!(sat=satno(sys,prn))) { - trace(2,"javad ephemeris satellite error: sys=%d prn=%d\n",sys,prn); - return -1; - } - eph.flag=(flag>>1)&1; - eph.code=(flag>>2)&3; - eph.fit =flag&1; - eph.week=adjgpsweek(week); - eph.toe=gpst2time(eph.week,eph.toes); - - /* for week-handover problem */ - tt=timediff(eph.toe,raw->time); - if (tt<-302400.0) eph.week++; - else if (tt> 302400.0) eph.week--; - eph.toe=gpst2time(eph.week,eph.toes); - - eph.toc=gpst2time(eph.week,toc); - eph.ttr=adjweek(eph.toe,tow); - } - else if (sys==SYS_GAL) { - if (!(sat=satno(sys,prn))) { - trace(2,"javad ephemeris satellite error: sys=%d prn=%d\n",sys,prn); - return -1; - } - eph.tgd[0]=R4(p); p+=4; /* BGD: E1-E5A (s) */ - eph.tgd[1]=R4(p); p+=4+13; /* BGD: E1-E5B (s) */ - navtype =U1(p); /* navtype: 0:E1B(INAV),1:E5A(FNAV) */ - /* 3:GIOVE E1B,4:GIOVE E5A */ - - set=(navtype==1)?1:0; /* 0:I/NAV,1:F/NAV */ - if (!(eph_sel&1)&&set==0) return 0; - if (!(eph_sel&2)&&set==1) return 0; - eph.code=set?(1<<1)+(1<<8):(1<<0)+(1<<2)+(1<<9); - - /* gal-week = gst-week + 1024 */ - eph.week=week+1024; - eph.toe=gpst2time(eph.week,eph.toes); - - /* for week-handover problem */ - tt=timediff(eph.toe,raw->time); - if (tt<-302400.0) eph.week++; - else if (tt> 302400.0) eph.week--; - eph.toe=gpst2time(eph.week,eph.toes); - - eph.toc=gpst2time(eph.week,toc); - eph.ttr=adjweek(eph.toe,tow); - } - else if (sys==SYS_CMP) { - if (!(sat=satno(sys,prn))) { - trace(2,"javad ephemeris satellite error: sys=%d prn=%d\n",sys,prn); - return -1; - } - eph.tgd[1]=R4(p); p+=4; /* TGD2 (s) */ - sigtype =U1(p); /* signal type: 0:B1,1:B2,2:B3 */ - eph.code=(sigtype==0)?1:((sigtype==1)?3:((sigtype==2)?5:0)); - eph.week=week; - eph.toe=bdt2time(week,eph.toes); /* BDT -> GPST */ - eph.toc=bdt2time(week,toc); /* BDT -> GPST */ - eph.ttr=adjweek(eph.toe,tow); - } - else return 0; - - if (!strstr(raw->opt,"-EPHALL")) { - if (timediff(raw->nav.eph[sat-1+MAXSAT*set].toe,eph.toe)==0.0&& - raw->nav.eph[sat-1+MAXSAT*set].iode==eph.iode&& - raw->nav.eph[sat-1+MAXSAT*set].iodc==eph.iodc) return 0; /* unchanged */ - } - eph.sat=sat; - raw->nav.eph[sat-1]=eph; - raw->ephsat=sat; - raw->ephset=set; - return 2; +static int decode_eph(raw_t *raw, int sys) { + eph_t eph = {0}; + double toc, sqrtA, tt; + char *msg; + int sat, prn, tow, flag, week, navtype, sigtype, set = 0; + int eph_sel = 3; /* Galileo ephemeris selection */ + uint8_t *p = raw->buff + 5; + + trace(3, "decode_eph: sys=%2d prn=%3d\n", sys, U1(p)); + + if (strstr(raw->opt, "-GALINAV")) eph_sel = 1; + if (strstr(raw->opt, "-GALFNAV")) eph_sel = 2; + + prn = U1(p); + p += 1; + tow = U4(p); + p += 4; + flag = U1(p); + p += 1; + eph.iodc = I2(p); + p += 2; + toc = I4(p); + p += 4; + eph.sva = I1(p); + p += 1; + eph.svh = U1(p); + p += 1; + week = I2(p); + p += 2; + eph.tgd[0] = R4(p); + p += 4; + eph.f2 = R4(p); + p += 4; + eph.f1 = R4(p); + p += 4; + eph.f0 = R4(p); + p += 4; + eph.toes = I4(p); + p += 4; + eph.iode = I2(p); + p += 2; + sqrtA = R8(p); + p += 8; + eph.e = R8(p); + p += 8; + eph.M0 = R8(p) * SC2RAD; + p += 8; + eph.OMG0 = R8(p) * SC2RAD; + p += 8; + eph.i0 = R8(p) * SC2RAD; + p += 8; + eph.omg = R8(p) * SC2RAD; + p += 8; + eph.deln = R4(p) * SC2RAD; + p += 4; + eph.OMGd = R4(p) * SC2RAD; + p += 4; + eph.idot = R4(p) * SC2RAD; + p += 4; + eph.crc = R4(p); + p += 4; + eph.crs = R4(p); + p += 4; + eph.cuc = R4(p); + p += 4; + eph.cus = R4(p); + p += 4; + eph.cic = R4(p); + p += 4; + eph.cis = R4(p); + p += 4; + eph.A = sqrtA * sqrtA; + + if (raw->outtype) { + msg = raw->msgtype + strlen(raw->msgtype); + sprintf(msg, " prn=%3d iode=%3d iodc=%3d toes=%6.0f", prn, eph.iode, eph.iodc, eph.toes); + } + if (sys == SYS_GPS || sys == SYS_QZS || sys == SYS_IRN) { + if (!(sat = satno(sys, prn))) { + trace(2, "javad ephemeris satellite error: sys=%d prn=%d\n", sys, prn); + return -1; + } + eph.flag = (flag >> 1) & 1; + eph.code = (flag >> 2) & 3; + eph.fit = flag & 1; + eph.week = adjgpsweek(week); + eph.toe = gpst2time(eph.week, eph.toes); + + /* for week-handover problem */ + tt = timediff(eph.toe, raw->time); + if (tt < -302400.0) + eph.week++; + else if (tt > 302400.0) + eph.week--; + eph.toe = gpst2time(eph.week, eph.toes); + + eph.toc = gpst2time(eph.week, toc); + eph.ttr = adjweek(eph.toe, tow); + } else if (sys == SYS_GAL) { + if (!(sat = satno(sys, prn))) { + trace(2, "javad ephemeris satellite error: sys=%d prn=%d\n", sys, prn); + return -1; + } + eph.tgd[0] = R4(p); + p += 4; /* BGD: E1-E5A (s) */ + eph.tgd[1] = R4(p); + p += 4 + 13; /* BGD: E1-E5B (s) */ + navtype = U1(p); /* navtype: 0:E1B(INAV),1:E5A(FNAV) */ + /* 3:GIOVE E1B,4:GIOVE E5A */ + + set = (navtype == 1) ? 1 : 0; /* 0:I/NAV,1:F/NAV */ + if (!(eph_sel & 1) && set == 0) return 0; + if (!(eph_sel & 2) && set == 1) return 0; + eph.code = set ? (1 << 1) + (1 << 8) : (1 << 0) + (1 << 2) + (1 << 9); + + /* gal-week = gst-week + 1024 */ + eph.week = week + 1024; + eph.toe = gpst2time(eph.week, eph.toes); + + /* for week-handover problem */ + tt = timediff(eph.toe, raw->time); + if (tt < -302400.0) + eph.week++; + else if (tt > 302400.0) + eph.week--; + eph.toe = gpst2time(eph.week, eph.toes); + + eph.toc = gpst2time(eph.week, toc); + eph.ttr = adjweek(eph.toe, tow); + } else if (sys == SYS_CMP) { + if (!(sat = satno(sys, prn))) { + trace(2, "javad ephemeris satellite error: sys=%d prn=%d\n", sys, prn); + return -1; + } + eph.tgd[1] = R4(p); + p += 4; /* TGD2 (s) */ + sigtype = U1(p); /* signal type: 0:B1,1:B2,2:B3 */ + eph.code = (sigtype == 0) ? 1 : ((sigtype == 1) ? 3 : ((sigtype == 2) ? 5 : 0)); + eph.week = week; + eph.toe = bdt2time(week, eph.toes); /* BDT -> GPST */ + eph.toc = bdt2time(week, toc); /* BDT -> GPST */ + eph.ttr = adjweek(eph.toe, tow); + } else + return 0; + + if (!strstr(raw->opt, "-EPHALL")) { + if (timediff(raw->nav.eph[sat - 1 + MAXSAT * set].toe, eph.toe) == 0.0 && + raw->nav.eph[sat - 1 + MAXSAT * set].iode == eph.iode && + raw->nav.eph[sat - 1 + MAXSAT * set].iodc == eph.iodc) + return 0; /* unchanged */ + } + eph.sat = sat; + raw->nav.eph[sat - 1] = eph; + raw->ephsat = sat; + raw->ephset = set; + return 2; } /* decode [GE] GPS ephemeris -------------------------------------------------*/ -static int decode_GE(raw_t *raw) -{ - if (!checksum(raw->buff,raw->len)) { - trace(2,"javad GE checksum error: len=%d\n",raw->len); - return -1; - } - if (raw->len<128) { - trace(2,"javad GE length error: len=%d\n",raw->len); - return -1; - } - return decode_eph(raw,SYS_GPS); +static int decode_GE(raw_t *raw) { + if (!checksum(raw->buff, raw->len)) { + trace(2, "javad GE checksum error: len=%d\n", raw->len); + return -1; + } + if (raw->len < 128) { + trace(2, "javad GE length error: len=%d\n", raw->len); + return -1; + } + return decode_eph(raw, SYS_GPS); } /* decode [NE] GLONASS ephemeris ---------------------------------------------*/ -static int decode_NE(raw_t *raw) -{ - geph_t geph={0}; - double tt; - char *msg; - int prn,tk,tb; - uint8_t *p=raw->buff+5; - - if (!checksum(raw->buff,raw->len)) { - trace(2,"javad NE checksum error: len=%d\n",raw->len); - return -1; - } - if (raw->len>=85) { /* firmware v 2.6.0 [2] */ - prn =U1(p); p+=1; - geph.frq =I1(p); p+=1+2; - tk =I4(p); p+=4; - tb =I4(p); p+=4; - geph.svh =U1(p)&0x1; p+=1; /* MSB of Bn */ - geph.age =U1(p); p+=1+1; - geph.pos[0]=R8(p)*1E3; p+=8; - geph.pos[1]=R8(p)*1E3; p+=8; - geph.pos[2]=R8(p)*1E3; p+=8; - geph.vel[0]=R4(p)*1E3; p+=4; - geph.vel[1]=R4(p)*1E3; p+=4; - geph.vel[2]=R4(p)*1E3; p+=4; - geph.acc[0]=R4(p)*1E3; p+=4; - geph.acc[1]=R4(p)*1E3; p+=4; - geph.acc[2]=R4(p)*1E3; p+=4+8; - geph.taun =R4(p); p+=4; - geph.gamn =R4(p); p+=4; - } - else { - trace(2,"javad NE length error: len=%d\n",raw->len); - return -1; - } - if (raw->len>=93) { /* firmware v 3.2.0 [1] */ - geph.dtaun =R4(p); p+=4; - geph.sva =U1(p); - } - if (raw->outtype) { - msg=raw->msgtype+strlen(raw->msgtype); - sprintf(msg," prn=%2d frq=%2d tk=%6d tb=%4d",prn,geph.frq,tk,tb); - } - if (!(geph.sat=satno(SYS_GLO,prn))) { - trace(2,"javad NE satellite error: prn=%d\n",prn); - return 0; - } - if (raw->time.time==0) return 0; - geph.iode=(tb/900)&0x7F; - geph.toe=utc2gpst(adjday(raw->time,tb-10800.0)); - geph.tof=utc2gpst(adjday(raw->time,tk-10800.0)); - - /* check illegal ephemeris by toe */ - tt=timediff(raw->time,geph.toe); - if (fabs(tt)>3600.0) { - trace(3,"javad NE illegal toe: prn=%2d tt=%6.0f\n",prn,tt); - return 0; - } - /* check illegal ephemeris by frequency number consistency */ - if (raw->nav.geph[prn-1].toe.time&&geph.frq!=raw->nav.geph[prn-1].frq) { - trace(2,"javad NE glonass fcn changed: prn=%2d fcn=%2d->%2d\n",prn, - raw->nav.geph[prn-1].frq,geph.frq); - return -1; - } - if (!strstr(raw->opt,"-EPHALL")) { - if (fabs(timediff(geph.toe,raw->nav.geph[prn-1].toe))<1.0&& - geph.svh==raw->nav.geph[prn-1].svh) return 0; /* unchanged */ - } - raw->nav.geph[prn-1]=geph; - raw->ephsat=geph.sat; - return 2; +static int decode_NE(raw_t *raw) { + geph_t geph = {0}; + double tt; + char *msg; + int prn, tk, tb; + uint8_t *p = raw->buff + 5; + + if (!checksum(raw->buff, raw->len)) { + trace(2, "javad NE checksum error: len=%d\n", raw->len); + return -1; + } + if (raw->len >= 85) { /* firmware v 2.6.0 [2] */ + prn = U1(p); + p += 1; + geph.frq = I1(p); + p += 1 + 2; + tk = I4(p); + p += 4; + tb = I4(p); + p += 4; + geph.svh = U1(p) & 0x1; + p += 1; /* MSB of Bn */ + geph.age = U1(p); + p += 1 + 1; + geph.pos[0] = R8(p) * 1E3; + p += 8; + geph.pos[1] = R8(p) * 1E3; + p += 8; + geph.pos[2] = R8(p) * 1E3; + p += 8; + geph.vel[0] = R4(p) * 1E3; + p += 4; + geph.vel[1] = R4(p) * 1E3; + p += 4; + geph.vel[2] = R4(p) * 1E3; + p += 4; + geph.acc[0] = R4(p) * 1E3; + p += 4; + geph.acc[1] = R4(p) * 1E3; + p += 4; + geph.acc[2] = R4(p) * 1E3; + p += 4 + 8; + geph.taun = R4(p); + p += 4; + geph.gamn = R4(p); + p += 4; + } else { + trace(2, "javad NE length error: len=%d\n", raw->len); + return -1; + } + if (raw->len >= 93) { /* firmware v 3.2.0 [1] */ + geph.dtaun = R4(p); + p += 4; + geph.sva = U1(p); + } + if (raw->outtype) { + msg = raw->msgtype + strlen(raw->msgtype); + sprintf(msg, " prn=%2d frq=%2d tk=%6d tb=%4d", prn, geph.frq, tk, tb); + } + if (!(geph.sat = satno(SYS_GLO, prn))) { + trace(2, "javad NE satellite error: prn=%d\n", prn); + return 0; + } + if (raw->time.time == 0) return 0; + geph.iode = (tb / 900) & 0x7F; + geph.toe = utc2gpst(adjday(raw->time, tb - 10800.0)); + geph.tof = utc2gpst(adjday(raw->time, tk - 10800.0)); + + /* check illegal ephemeris by toe */ + tt = timediff(raw->time, geph.toe); + if (fabs(tt) > 3600.0) { + trace(3, "javad NE illegal toe: prn=%2d tt=%6.0f\n", prn, tt); + return 0; + } + /* check illegal ephemeris by frequency number consistency */ + if (raw->nav.geph[prn - 1].toe.time && geph.frq != raw->nav.geph[prn - 1].frq) { + trace(2, "javad NE glonass fcn changed: prn=%2d fcn=%2d->%2d\n", prn, + raw->nav.geph[prn - 1].frq, geph.frq); + return -1; + } + if (!strstr(raw->opt, "-EPHALL")) { + if (fabs(timediff(geph.toe, raw->nav.geph[prn - 1].toe)) < 1.0 && + geph.svh == raw->nav.geph[prn - 1].svh) + return 0; /* unchanged */ + } + raw->nav.geph[prn - 1] = geph; + raw->ephsat = geph.sat; + return 2; } /* decode [EN] Galileo ephemeris ---------------------------------------------*/ -static int decode_EN(raw_t *raw) -{ - if (!checksum(raw->buff,raw->len)) { - trace(2,"javad EN checksum error: len=%d\n",raw->len); - return -1; - } - if (raw->len<150) { - trace(2,"javad EN length error: len=%d\n",raw->len); - return -1; - } - return decode_eph(raw,SYS_GAL); +static int decode_EN(raw_t *raw) { + if (!checksum(raw->buff, raw->len)) { + trace(2, "javad EN checksum error: len=%d\n", raw->len); + return -1; + } + if (raw->len < 150) { + trace(2, "javad EN length error: len=%d\n", raw->len); + return -1; + } + return decode_eph(raw, SYS_GAL); } /* decode [WE] SBAS ephemeris ------------------------------------------------*/ -static int decode_WE(raw_t *raw) -{ - seph_t seph={0}; - uint32_t tod,tow; - char *msg; - int i,prn,week; - uint8_t *p=raw->buff+5; - - if (!checksum(raw->buff,raw->len)) { - trace(2,"javad WE checksum error: len=%d\n",raw->len); - return -1; - } - if (raw->len<44) { - trace(2,"javad WE length error: len=%d\n",raw->len); - return -1; - } - prn =U1(p); p+=1+1+1; - seph.sva=U1(p); p+=1; - tod =U4(p); p+=4; - for (i=0;i<3;i++) {seph.pos[i]=R8(p); p+=8;} - for (i=0;i<3;i++) {seph.vel[i]=R4(p); p+=4;} - for (i=0;i<3;i++) {seph.acc[i]=R4(p); p+=4;} - seph.af0 =R4(p); p+=4; - seph.af1 =R4(p); p+=4; - tow =U4(p); p+=4; - week =U2(p); - - if (raw->outtype) { - msg=raw->msgtype+strlen(raw->msgtype); - sprintf(msg," prn=%3d tod=%6u",prn,tod); - } - if (!(seph.sat=satno(SYS_SBS,prn))) { - trace(2,"javad WE satellite error: prn=%d\n",prn); - return -1; - } - seph.tof=gpst2time(adjgpsweek(week),tow); - seph.t0=adjday(seph.tof,tod); - - if (!strstr(raw->opt,"-EPHALL")) { - if (fabs(timediff(seph.t0,raw->nav.seph[prn-MINPRNSBS].t0))<1.0&& - seph.sva==raw->nav.seph[prn-MINPRNSBS].sva) return 0; /* unchanged */ - } - raw->nav.seph[prn-MINPRNSBS]=seph; - raw->ephsat=seph.sat; - return 2; +static int decode_WE(raw_t *raw) { + seph_t seph = {0}; + uint32_t tod, tow; + char *msg; + int i, prn, week; + uint8_t *p = raw->buff + 5; + + if (!checksum(raw->buff, raw->len)) { + trace(2, "javad WE checksum error: len=%d\n", raw->len); + return -1; + } + if (raw->len < 44) { + trace(2, "javad WE length error: len=%d\n", raw->len); + return -1; + } + prn = U1(p); + p += 1 + 1 + 1; + seph.sva = U1(p); + p += 1; + tod = U4(p); + p += 4; + for (i = 0; i < 3; i++) { + seph.pos[i] = R8(p); + p += 8; + } + for (i = 0; i < 3; i++) { + seph.vel[i] = R4(p); + p += 4; + } + for (i = 0; i < 3; i++) { + seph.acc[i] = R4(p); + p += 4; + } + seph.af0 = R4(p); + p += 4; + seph.af1 = R4(p); + p += 4; + tow = U4(p); + p += 4; + week = U2(p); + + if (raw->outtype) { + msg = raw->msgtype + strlen(raw->msgtype); + sprintf(msg, " prn=%3d tod=%6u", prn, tod); + } + if (!(seph.sat = satno(SYS_SBS, prn))) { + trace(2, "javad WE satellite error: prn=%d\n", prn); + return -1; + } + seph.tof = gpst2time(adjgpsweek(week), tow); + seph.t0 = adjday(seph.tof, tod); + + if (!strstr(raw->opt, "-EPHALL")) { + if (fabs(timediff(seph.t0, raw->nav.seph[prn - MINPRNSBS].t0)) < 1.0 && + seph.sva == raw->nav.seph[prn - MINPRNSBS].sva) + return 0; /* unchanged */ + } + raw->nav.seph[prn - MINPRNSBS] = seph; + raw->ephsat = seph.sat; + return 2; } /* decode [QE] QZSS ephemeris ------------------------------------------------*/ -static int decode_QE(raw_t *raw) -{ - if (!checksum(raw->buff,raw->len)) { - trace(2,"javad QE checksum error: len=%d\n",raw->len); - return -1; - } - if (raw->len<128) { - trace(2,"javad QE length error: len=%d\n",raw->len); - return -1; - } - return decode_eph(raw,SYS_QZS); +static int decode_QE(raw_t *raw) { + if (!checksum(raw->buff, raw->len)) { + trace(2, "javad QE checksum error: len=%d\n", raw->len); + return -1; + } + if (raw->len < 128) { + trace(2, "javad QE length error: len=%d\n", raw->len); + return -1; + } + return decode_eph(raw, SYS_QZS); } /* decode [CN] Beidou ephemeris ----------------------------------------------*/ -static int decode_CN(raw_t *raw) -{ - if (!checksum(raw->buff,raw->len)) { - trace(2,"javad CN checksum error: len=%d\n",raw->len); - return -1; - } - if (raw->len<133) { - trace(2,"javad QE length error: len=%d\n",raw->len); - return -1; - } - return decode_eph(raw,SYS_CMP); +static int decode_CN(raw_t *raw) { + if (!checksum(raw->buff, raw->len)) { + trace(2, "javad CN checksum error: len=%d\n", raw->len); + return -1; + } + if (raw->len < 133) { + trace(2, "javad QE length error: len=%d\n", raw->len); + return -1; + } + return decode_eph(raw, SYS_CMP); } /* decode [IE] IRNSS ephemeris -----------------------------------------------*/ -static int decode_IE(raw_t *raw) -{ - if (!checksum(raw->buff,raw->len)) { - trace(2,"javad IE checksum error: len=%d\n",raw->len); - return -1; - } - if (raw->len<129) { - trace(2,"javad IE length error: len=%d\n",raw->len); - return -1; - } - return decode_eph(raw,SYS_IRN); +static int decode_IE(raw_t *raw) { + if (!checksum(raw->buff, raw->len)) { + trace(2, "javad IE checksum error: len=%d\n", raw->len); + return -1; + } + if (raw->len < 129) { + trace(2, "javad IE length error: len=%d\n", raw->len); + return -1; + } + return decode_eph(raw, SYS_IRN); } /* decode [UO] GPS UTC time parameters ---------------------------------------*/ -static int decode_UO(raw_t *raw) -{ - uint8_t *p=raw->buff+5; - - if (!checksum(raw->buff,raw->len)) { - trace(2,"javad UO checksum error: len=%d\n",raw->len); - return -1; - } - if (raw->len<29) { - trace(2,"javad UO length error: len=%d\n",raw->len); - return -1; - } - raw->nav.utc_gps[0]=R8(p); p+=8; - raw->nav.utc_gps[1]=R4(p); p+=4; - raw->nav.utc_gps[2]=U4(p); p+=4; - raw->nav.utc_gps[3]=adjgpsweek((int)U2(p)); p+=2; - raw->nav.utc_gps[4]=I1(p); - return 9; +static int decode_UO(raw_t *raw) { + uint8_t *p = raw->buff + 5; + + if (!checksum(raw->buff, raw->len)) { + trace(2, "javad UO checksum error: len=%d\n", raw->len); + return -1; + } + if (raw->len < 29) { + trace(2, "javad UO length error: len=%d\n", raw->len); + return -1; + } + raw->nav.utc_gps[0] = R8(p); + p += 8; + raw->nav.utc_gps[1] = R4(p); + p += 4; + raw->nav.utc_gps[2] = U4(p); + p += 4; + raw->nav.utc_gps[3] = adjgpsweek((int)U2(p)); + p += 2; + raw->nav.utc_gps[4] = I1(p); + return 9; } /* decode [NU] GLONASS UTC and GPS time parameters ---------------------------*/ -static int decode_NU(raw_t *raw) -{ - (void)raw; - trace(3,"javad NU unsupported\n"); - - return 0; +static int decode_NU(raw_t *raw) { + (void)raw; + trace(3, "javad NU unsupported\n"); + + return 0; } /* decode [EU] Galileo UTC and GPS time parameters ---------------------------*/ -static int decode_EU(raw_t *raw) -{ - (void)raw; - trace(3,"javad EU unsupported\n"); - - return 0; +static int decode_EU(raw_t *raw) { + (void)raw; + trace(3, "javad EU unsupported\n"); + + return 0; } /* decode [WU] WAAS UTC time parameters --------------------------------------*/ -static int decode_WU(raw_t *raw) -{ - (void)raw; - trace(3,"javad WU unsupported\n"); - - return 0; +static int decode_WU(raw_t *raw) { + (void)raw; + trace(3, "javad WU unsupported\n"); + + return 0; } /* decode [QU] QZSS UTC and GPS time parameters ------------------------------*/ -static int decode_QU(raw_t *raw) -{ - (void)raw; - trace(3,"javad QU unsupported\n"); - - return 0; +static int decode_QU(raw_t *raw) { + (void)raw; + trace(3, "javad QU unsupported\n"); + + return 0; } /* decode [IO] ionospheric parameters ----------------------------------------*/ -static int decode_IO(raw_t *raw) -{ - int i; - uint8_t *p=raw->buff+5; - - if (!checksum(raw->buff,raw->len)) { - trace(2,"javad IO checksum error: len=%d\n",raw->len); - return -1; - } - if (raw->len<44) { - trace(2,"javad IO length error: len=%d\n",raw->len); - return -1; - } - p+=4+2; - for (i=0;i<8;i++) { - raw->nav.ion_gps[i]=R4(p); p+=4; - } - return 9; +static int decode_IO(raw_t *raw) { + int i; + uint8_t *p = raw->buff + 5; + + if (!checksum(raw->buff, raw->len)) { + trace(2, "javad IO checksum error: len=%d\n", raw->len); + return -1; + } + if (raw->len < 44) { + trace(2, "javad IO length error: len=%d\n", raw->len); + return -1; + } + p += 4 + 2; + for (i = 0; i < 8; i++) { + raw->nav.ion_gps[i] = R4(p); + p += 4; + } + return 9; } /* decode L1 ephemeris -------------------------------------------------------*/ -static int decode_L1eph(int sat, raw_t *raw) -{ - eph_t eph={0}; - - int sys = satsys(sat, NULL); - if (!decode_frame(raw->subfrm[sat-1],sys,&eph,NULL,NULL,NULL)) return 0; - - if (!strstr(raw->opt,"-EPHALL")) { - if (eph.iode==raw->nav.eph[sat-1].iode&& - eph.iodc==raw->nav.eph[sat-1].iodc) return 0; - } - eph.sat=sat; - raw->nav.eph[sat-1]=eph; - raw->ephsat=sat; - raw->ephset=0; - return 2; +static int decode_L1eph(int sat, raw_t *raw) { + eph_t eph = {0}; + + int sys = satsys(sat, NULL); + if (!decode_frame(raw->subfrm[sat - 1], sys, &eph, NULL, NULL, NULL)) return 0; + + if (!strstr(raw->opt, "-EPHALL")) { + if (eph.iode == raw->nav.eph[sat - 1].iode && eph.iodc == raw->nav.eph[sat - 1].iodc) return 0; + } + eph.sat = sat; + raw->nav.eph[sat - 1] = eph; + raw->ephsat = sat; + raw->ephset = 0; + return 2; } /* UTC 8-bit week -> full week -----------------------------------------------*/ -static void adj_utcweek(gtime_t time, double *utc) -{ - int week; - - time2gpst(time,&week); - utc[3]+=week/256*256; - if (utc[3]week+127) utc[3]-=256.0; - utc[5]+=utc[3]/256*256; - if (utc[5]utc[3]+127) utc[5]-=256.0; +static void adj_utcweek(gtime_t time, double *utc) { + int week; + + time2gpst(time, &week); + utc[3] += week / 256 * 256; + if (utc[3] < week - 127) + utc[3] += 256.0; + else if (utc[3] > week + 127) + utc[3] -= 256.0; + utc[5] += utc[3] / 256 * 256; + if (utc[5] < utc[3] - 127) + utc[5] += 256.0; + else if (utc[5] > utc[3] + 127) + utc[5] -= 256.0; } /* decode L1 ION/UTC parameters ----------------------------------------------*/ -static int decode_L1ionutc(int sat, raw_t *raw) -{ - double ion[8],utc[8]; - int sys=satsys(sat,NULL); - - if (!decode_frame(raw->subfrm[sat-1],sys,NULL,NULL,ion,utc)) return 0; - - adj_utcweek(raw->time,utc); - if (sys==SYS_QZS) { - matcpy(raw->nav.ion_qzs,ion,8,1); - matcpy(raw->nav.utc_qzs,utc,8,1); - } - else { - matcpy(raw->nav.ion_gps,ion,8,1); - matcpy(raw->nav.utc_gps,utc,8,1); - } - return 9; +static int decode_L1ionutc(int sat, raw_t *raw) { + double ion[8], utc[8]; + int sys = satsys(sat, NULL); + + if (!decode_frame(raw->subfrm[sat - 1], sys, NULL, NULL, ion, utc)) return 0; + + adj_utcweek(raw->time, utc); + if (sys == SYS_QZS) { + matcpy(raw->nav.ion_qzs, ion, 8, 1); + matcpy(raw->nav.utc_qzs, utc, 8, 1); + } else { + matcpy(raw->nav.ion_gps, ion, 8, 1); + matcpy(raw->nav.utc_gps, utc, 8, 1); + } + return 9; } /* decode L1 NAV data --------------------------------------------------------*/ -static int decode_L1nav(uint8_t *buff, int len, int sat, raw_t *raw) -{ - uint8_t subfrm[30],*p; - int i,id,sys=satsys(sat,NULL); - - if (sys!=SYS_GPS&&sys!=SYS_QZS) { - trace(2,"navigation subframe system error: sat=%d\n",sat); - return -1; - } - if (len<10) { - trace(2,"navigation subframe length error: len=%d\n",len); - return -1; - } - for (i=0,p=buff;i<10;i++,p+=4) { - setbitu(subfrm,24*i,24,U4(p)>>6); - } - id=getbitu(subfrm,43,3); - if (id<1||id>5) { - trace(2,"navigation subframe format error: sat=%d id=%d\n",sat,id); - return -1; - } - memcpy(raw->subfrm[sat-1]+(id-1)*30,subfrm,30); - - if (id==3) { - return decode_L1eph(sat,raw); - } - else if (id==4||id==5) { - return decode_L1ionutc(sat,raw); - } - return 0; +static int decode_L1nav(uint8_t *buff, int len, int sat, raw_t *raw) { + uint8_t subfrm[30], *p; + int i, id, sys = satsys(sat, NULL); + + if (sys != SYS_GPS && sys != SYS_QZS) { + trace(2, "navigation subframe system error: sat=%d\n", sat); + return -1; + } + if (len < 10) { + trace(2, "navigation subframe length error: len=%d\n", len); + return -1; + } + for (i = 0, p = buff; i < 10; i++, p += 4) { + setbitu(subfrm, 24 * i, 24, U4(p) >> 6); + } + id = getbitu(subfrm, 43, 3); + if (id < 1 || id > 5) { + trace(2, "navigation subframe format error: sat=%d id=%d\n", sat, id); + return -1; + } + memcpy(raw->subfrm[sat - 1] + (id - 1) * 30, subfrm, 30); + + if (id == 3) { + return decode_L1eph(sat, raw); + } else if (id == 4 || id == 5) { + return decode_L1ionutc(sat, raw); + } + return 0; } /* decode raw L2C CNAV data --------------------------------------------------*/ -static int decode_L2nav(uint8_t *buff, int len, int sat, raw_t *raw) -{ - (void)raw; - uint8_t msg[1024]={0}; - int i,j,preamb,prn,msgid,tow,alert; - - trace(3,"decode_L2nav len=%2d sat=%2d L5 CNAV\n",len,sat); - - for (i=0;ibuff+5; - - if (!checksum(raw->buff,raw->len)) { - trace(2,"javad nD checksum error: sys=%d len=%d\n",sys,raw->len); - return -1; - } - siz=U1(p); p+=1; - n=(raw->len-7)/siz; - - if (n<=0) { - trace(2,"javad nD length error: sys=%d len=%d\n",sys,raw->len); - return -1; - } - for (i=0;ibuff + 5; + + if (!checksum(raw->buff, raw->len)) { + trace(2, "javad nD checksum error: sys=%d len=%d\n", sys, raw->len); + return -1; + } + siz = U1(p); + p += 1; + n = (raw->len - 7) / siz; + + if (n <= 0) { + trace(2, "javad nD length error: sys=%d len=%d\n", sys, raw->len); + return -1; + } + for (i = 0; i < n; i++, p += siz) { + trace(3, "decode_*D: sys=%2d prn=%3d\n", sys, U1(p)); + + prn = U1(p); + if (!(sat = satno(sys, prn))) { + trace(2, "javad nD satellite error: sys=%d prn=%d\n", sys, prn); + continue; } - return stat; + stat = decode_L1nav(p + 2, 0, sat, raw); + } + return stat; } /* decode [*d] raw navigation data -------------------------------------------*/ -static int decode_nd(raw_t *raw, int sys) -{ - uint8_t *p=raw->buff+5; - char *msg; - int sat,prn,time,type,len; - - if (!checksum(raw->buff,raw->len)) { - trace(2,"javad nd checksum error: sys=%d len=%d\n",sys,raw->len); - return -1; - } - trace(3,"decode_*d: sys=%2d prn=%3d\n",sys,U1(p)); - - prn =U1(p); p+=1; - time=U4(p); p+=4; - type=U1(p); p+=1; - len =U1(p); p+=1; - if (raw->len!=13+len*4) { - trace(2,"javad nd length error: sys=%d len=%d\n",sys,raw->len); - return -1; - } - if (raw->outtype) { - msg=raw->msgtype+strlen(raw->msgtype); - sprintf(msg," prn=%3d time=%7d type=%d",prn,time,type); - } - if (!(sat=satno(sys,prn))) { - trace(2,"javad nd satellite error: sys=%d prn=%d\n",sys,prn); - return 0; - } - trace(4,"sat=%2d time=%7d type=%d len=%3d\n",sat,time,type,len); - - switch (type) { - case 0: return decode_L1nav (p,len,sat,raw); /* L1 NAV */ - case 1: return decode_L2nav (p,len,sat,raw); /* L2C CNAV */ - case 2: return decode_L5nav (p,len,sat,raw); /* L5 CNAV */ - case 3: return decode_L1Cnav(p,len,sat,raw); /* L1C CNAV2 */ - } +static int decode_nd(raw_t *raw, int sys) { + uint8_t *p = raw->buff + 5; + char *msg; + int sat, prn, time, type, len; + + if (!checksum(raw->buff, raw->len)) { + trace(2, "javad nd checksum error: sys=%d len=%d\n", sys, raw->len); + return -1; + } + trace(3, "decode_*d: sys=%2d prn=%3d\n", sys, U1(p)); + + prn = U1(p); + p += 1; + time = U4(p); + p += 4; + type = U1(p); + p += 1; + len = U1(p); + p += 1; + if (raw->len != 13 + len * 4) { + trace(2, "javad nd length error: sys=%d len=%d\n", sys, raw->len); + return -1; + } + if (raw->outtype) { + msg = raw->msgtype + strlen(raw->msgtype); + sprintf(msg, " prn=%3d time=%7d type=%d", prn, time, type); + } + if (!(sat = satno(sys, prn))) { + trace(2, "javad nd satellite error: sys=%d prn=%d\n", sys, prn); return 0; + } + trace(4, "sat=%2d time=%7d type=%d len=%3d\n", sat, time, type, len); + + switch (type) { + case 0: + return decode_L1nav(p, len, sat, raw); /* L1 NAV */ + case 1: + return decode_L2nav(p, len, sat, raw); /* L2C CNAV */ + case 2: + return decode_L5nav(p, len, sat, raw); /* L5 CNAV */ + case 3: + return decode_L1Cnav(p, len, sat, raw); /* L1C CNAV2 */ + } + return 0; } /* decode [LD] GLONASS raw navigation data -----------------------------------*/ -static int decode_LD(raw_t *raw) -{ - (void)raw; - trace(3,"javad LD unsupported\n"); - - return 0; +static int decode_LD(raw_t *raw) { + (void)raw; + trace(3, "javad LD unsupported\n"); + + return 0; } /* decode [lD] GLONASS raw navigation data -----------------------------------*/ -static int decode_lD(raw_t *raw) -{ - geph_t geph={0}; - uint8_t *p=raw->buff+5; - char *msg; - int i,sat,prn,frq,time,type,len,id; - - if (!checksum(raw->buff,raw->len)) { - trace(2,"javad lD checksum error: len=%d\n",raw->len); - return -1; - } - trace(3,"decode_lD: prn=%3d\n",U1(p)); - - prn =U1(p); p+=1; - frq =I1(p); p+=1; - time=U4(p); p+=4; - type=U1(p); p+=1; - len =U1(p); p+=1; - - if (raw->len!=14+len*4) { - trace(2,"javad lD length error: len=%d\n",raw->len); - return -1; - } - if (raw->outtype) { - msg=raw->msgtype+strlen(raw->msgtype); - sprintf(msg," prn=%2d frq=%2d time=%7d type=%d",prn,frq,time,type); - } - if (!(sat=satno(SYS_GLO,prn))) { - trace(2,"javad lD satellite error: prn=%d\n",prn); - return 0; - } - if (type!=0) { - trace(3,"javad lD type unsupported: type=%d\n",type); - return 0; - } - if ((id=(U4(p)>>20)&0xF)<1) return 0; - - /* get 77 bit (25x3+2) in frame without hamming and time mark */ - for (i=0;i<4;i++) { - setbitu(raw->subfrm[sat-1]+(id-1)*10,i*25,i<3?25:2, - U4(p+4*i)>>(i<3?0:23)); - } - if (id!=4) return 0; - - /* decode glonass ephemeris strings */ - geph.tof=raw->time; - if (!decode_glostr(raw->subfrm[sat-1],&geph,NULL)||geph.sat!=sat) return -1; - geph.frq=frq; - - if (!strstr(raw->opt,"-EPHALL")) { - if (geph.iode==raw->nav.geph[prn-1].iode) return 0; /* unchanged */ - } - raw->nav.geph[prn-1]=geph; - raw->ephsat=sat; - return 2; +static int decode_lD(raw_t *raw) { + geph_t geph = {0}; + uint8_t *p = raw->buff + 5; + char *msg; + int i, sat, prn, frq, time, type, len, id; + + if (!checksum(raw->buff, raw->len)) { + trace(2, "javad lD checksum error: len=%d\n", raw->len); + return -1; + } + trace(3, "decode_lD: prn=%3d\n", U1(p)); + + prn = U1(p); + p += 1; + frq = I1(p); + p += 1; + time = U4(p); + p += 4; + type = U1(p); + p += 1; + len = U1(p); + p += 1; + + if (raw->len != 14 + len * 4) { + trace(2, "javad lD length error: len=%d\n", raw->len); + return -1; + } + if (raw->outtype) { + msg = raw->msgtype + strlen(raw->msgtype); + sprintf(msg, " prn=%2d frq=%2d time=%7d type=%d", prn, frq, time, type); + } + if (!(sat = satno(SYS_GLO, prn))) { + trace(2, "javad lD satellite error: prn=%d\n", prn); + return 0; + } + if (type != 0) { + trace(3, "javad lD type unsupported: type=%d\n", type); + return 0; + } + if ((id = (U4(p) >> 20) & 0xF) < 1) return 0; + + /* get 77 bit (25x3+2) in frame without hamming and time mark */ + for (i = 0; i < 4; i++) { + setbitu(raw->subfrm[sat - 1] + (id - 1) * 10, i * 25, i < 3 ? 25 : 2, + U4(p + 4 * i) >> (i < 3 ? 0 : 23)); + } + if (id != 4) return 0; + + /* decode glonass ephemeris strings */ + geph.tof = raw->time; + if (!decode_glostr(raw->subfrm[sat - 1], &geph, NULL) || geph.sat != sat) return -1; + geph.frq = frq; + + if (!strstr(raw->opt, "-EPHALL")) { + if (geph.iode == raw->nav.geph[prn - 1].iode) return 0; /* unchanged */ + } + raw->nav.geph[prn - 1] = geph; + raw->ephsat = sat; + return 2; } /* decode [ED] Galileo raw navigation data -----------------------------------*/ -static int decode_ED(raw_t *raw) -{ - (void)raw; - trace(3,"javad ED unsupported\n"); - - return 0; +static int decode_ED(raw_t *raw) { + (void)raw; + trace(3, "javad ED unsupported\n"); + + return 0; } /* decode [cd] Beidou raw navigation data ------------------------------------*/ -static int decode_cd(raw_t *raw) -{ - (void)raw; - trace(3,"javad cd unsupported\n"); - - return 0; +static int decode_cd(raw_t *raw) { + (void)raw; + trace(3, "javad cd unsupported\n"); + + return 0; } /* decode [id] IRNSS raw navigation data -------------------------------------*/ -static int decode_id(raw_t *raw) -{ - (void)raw; - trace(3,"javad id unsupported\n"); - - return 0; +static int decode_id(raw_t *raw) { + (void)raw; + trace(3, "javad id unsupported\n"); + + return 0; } /* decode [WD] SBAS raw navigation data --------------------------------------*/ -static int decode_WD(raw_t *raw) -{ - int i,prn,tow,tow_p,week; - char *msg; - uint8_t *p=raw->buff+5; - - if (!checksum(raw->buff,raw->len)) { - trace(2,"javad WD checksum error: len=%d\n",raw->len); - return -1; - } - if (raw->len<45) { - trace(2,"javad WD length error: len=%d\n",raw->len); - return -1; - } - trace(3,"decode_WD: prn=%3d\n",U1(p)); - - prn=U1(p); p+=1; - tow=U4(p); p+=4+2; - - if (raw->outtype) { - msg=raw->msgtype+strlen(raw->msgtype); - sprintf(msg," prn=%3d tow=%6d",prn,tow); - } - if ((prn=MINPRNQZS&&prn<=MAXPRNQZS) { - prn-=10; /* QZSS L1S */ - } - raw->sbsmsg.prn=prn; - raw->sbsmsg.tow=tow; - - if (raw->time.time==0) { - raw->sbsmsg.week=0; - } - else { - tow_p=(int)time2gpst(raw->time,&week); - if (towtow_p+302400.0) week--; - raw->sbsmsg.week=week; - } - for (i=0;i<29;i++) raw->sbsmsg.msg[i]=*p++; - raw->sbsmsg.msg[28]&=0xC0; - return 3; +static int decode_WD(raw_t *raw) { + int i, prn, tow, tow_p, week; + char *msg; + uint8_t *p = raw->buff + 5; + + if (!checksum(raw->buff, raw->len)) { + trace(2, "javad WD checksum error: len=%d\n", raw->len); + return -1; + } + if (raw->len < 45) { + trace(2, "javad WD length error: len=%d\n", raw->len); + return -1; + } + trace(3, "decode_WD: prn=%3d\n", U1(p)); + + prn = U1(p); + p += 1; + tow = U4(p); + p += 4 + 2; + + if (raw->outtype) { + msg = raw->msgtype + strlen(raw->msgtype); + sprintf(msg, " prn=%3d tow=%6d", prn, tow); + } + if ((prn < MINPRNSBS || MAXPRNSBS < prn) && (prn < MINPRNQZS || MAXPRNQZS < prn)) { + trace(2, "javad WD satellite error: prn=%d\n", prn); + return 0; + } + if (prn >= MINPRNQZS && prn <= MAXPRNQZS) { + prn -= 10; /* QZSS L1S */ + } + raw->sbsmsg.prn = prn; + raw->sbsmsg.tow = tow; + + if (raw->time.time == 0) { + raw->sbsmsg.week = 0; + } else { + tow_p = (int)time2gpst(raw->time, &week); + if (tow < tow_p - 302400.0) + week++; + else if (tow > tow_p + 302400.0) + week--; + raw->sbsmsg.week = week; + } + for (i = 0; i < 29; i++) raw->sbsmsg.msg[i] = *p++; + raw->sbsmsg.msg[28] &= 0xC0; + return 3; } /* decode [R*] pseudoranges --------------------------------------------------*/ -static int decode_Rx(raw_t *raw, char sig) -{ - uint8_t *p=raw->buff+5; - double pr,prm; - int i,idx,code,sat,sys; - - if (!is_meas(sig)||raw->tod<0||raw->obuf.n==0) return 0; - - if (!checksum(raw->buff,raw->len)) { - trace(2,"javad R%c checksum error: len=%d\n",sig,raw->len); - return -1; - } - if (raw->len!=raw->obuf.n*8+6) { - trace(2,"javad R%c length error: n=%d len=%d\n",sig,raw->obuf.n,raw->len); - return -1; - } - for (i=0;iobuf.n&&iobuf.data[i].sat; - if (!(sys=satsys(sat,NULL))) continue; - - prm=pr*CLIGHT; - - if (sig=='C') raw->prCA[sat-1]=prm; - - if ((idx=sig2idx(sys,sig,&code))<0) continue; - - if ((idx=checkpri(sys,code,raw->opt,idx))>=0) { - if (!settag(raw->obuf.data+i,raw->time)) continue; - raw->obuf.data[i].P[idx]=prm; - raw->obuf.data[i].code[idx]=code; - } +static int decode_Rx(raw_t *raw, char sig) { + uint8_t *p = raw->buff + 5; + double pr, prm; + int i, idx, code, sat, sys; + + if (!is_meas(sig) || raw->tod < 0 || raw->obuf.n == 0) return 0; + + if (!checksum(raw->buff, raw->len)) { + trace(2, "javad R%c checksum error: len=%d\n", sig, raw->len); + return -1; + } + if (raw->len != raw->obuf.n * 8 + 6) { + trace(2, "javad R%c length error: n=%d len=%d\n", sig, raw->obuf.n, raw->len); + return -1; + } + for (i = 0; i < raw->obuf.n && i < MAXOBS; i++) { + pr = R8(p); + p += 8; + if (pr == 0.0) continue; + + sat = raw->obuf.data[i].sat; + if (!(sys = satsys(sat, NULL))) continue; + + prm = pr * CLIGHT; + + if (sig == 'C') raw->prCA[sat - 1] = prm; + + if ((idx = sig2idx(sys, sig, &code)) < 0) continue; + + if ((idx = checkpri(sys, code, raw->opt, idx)) >= 0) { + if (!settag(raw->obuf.data + i, raw->time)) continue; + raw->obuf.data[i].P[idx] = prm; + raw->obuf.data[i].code[idx] = code; } - return 0; + } + return 0; } /* decode [r*] short pseudoranges --------------------------------------------*/ -static int decode_rx(raw_t *raw, char sig) -{ - uint8_t *p=raw->buff+5; - double prm; - int i,idx,code,pr,sat,sys; - - if (!is_meas(sig)||raw->tod<0||raw->obuf.n==0) return 0; - - if (!checksum(raw->buff,raw->len)) { - trace(2,"javad r%c checksum error: len=%d\n",sig,raw->len); - return -1; - } - if (raw->len!=raw->obuf.n*4+6) { - trace(2,"javad r%c length error: n=%d len=%d\n",sig,raw->obuf.n,raw->len); - return -1; - } - for (i=0;iobuf.n&&iobuf.data[i].sat; - if (!(sys=satsys(sat,NULL))) continue; - - if (pr==0x7FFFFFFF) { - trace(3,"javad r%c value missing: sat=%2d\n",sig,sat); - continue; - } - /* Ksys Asys */ - if (sys==SYS_SBS) prm=(pr*1E-11+0.125)*CLIGHT; /* [6] */ - else if (sys==SYS_QZS) prm=(pr*2E-11+0.125)*CLIGHT; /* [3] */ - else if (sys==SYS_CMP) prm=(pr*2E-11+0.105)*CLIGHT; /* [4] */ - else if (sys==SYS_GAL) prm=(pr*2E-11+0.085)*CLIGHT; /* [7] */ - else if (sys==SYS_IRN) prm=(pr*2E-11+0.105)*CLIGHT; /* [6] */ - else prm=(pr*1E-11+0.075)*CLIGHT; - - if (sig=='c') raw->prCA[sat-1]=prm; - - if ((idx=sig2idx(sys,sig,&code))<0) continue; - - if ((idx=checkpri(sys,code,raw->opt,idx))>=0) { - if (!settag(raw->obuf.data+i,raw->time)) continue; - raw->obuf.data[i].P[idx]=prm; - raw->obuf.data[i].code[idx]=(uint8_t)code; - } +static int decode_rx(raw_t *raw, char sig) { + uint8_t *p = raw->buff + 5; + double prm; + int i, idx, code, pr, sat, sys; + + if (!is_meas(sig) || raw->tod < 0 || raw->obuf.n == 0) return 0; + + if (!checksum(raw->buff, raw->len)) { + trace(2, "javad r%c checksum error: len=%d\n", sig, raw->len); + return -1; + } + if (raw->len != raw->obuf.n * 4 + 6) { + trace(2, "javad r%c length error: n=%d len=%d\n", sig, raw->obuf.n, raw->len); + return -1; + } + for (i = 0; i < raw->obuf.n && i < MAXOBS; i++) { + pr = I4(p); + p += 4; + sat = raw->obuf.data[i].sat; + if (!(sys = satsys(sat, NULL))) continue; + + if (pr == 0x7FFFFFFF) { + trace(3, "javad r%c value missing: sat=%2d\n", sig, sat); + continue; + } + /* Ksys Asys */ + if (sys == SYS_SBS) + prm = (pr * 1E-11 + 0.125) * CLIGHT; /* [6] */ + else if (sys == SYS_QZS) + prm = (pr * 2E-11 + 0.125) * CLIGHT; /* [3] */ + else if (sys == SYS_CMP) + prm = (pr * 2E-11 + 0.105) * CLIGHT; /* [4] */ + else if (sys == SYS_GAL) + prm = (pr * 2E-11 + 0.085) * CLIGHT; /* [7] */ + else if (sys == SYS_IRN) + prm = (pr * 2E-11 + 0.105) * CLIGHT; /* [6] */ + else + prm = (pr * 1E-11 + 0.075) * CLIGHT; + + if (sig == 'c') raw->prCA[sat - 1] = prm; + + if ((idx = sig2idx(sys, sig, &code)) < 0) continue; + + if ((idx = checkpri(sys, code, raw->opt, idx)) >= 0) { + if (!settag(raw->obuf.data + i, raw->time)) continue; + raw->obuf.data[i].P[idx] = prm; + raw->obuf.data[i].code[idx] = (uint8_t)code; } - return 0; + } + return 0; } /* decode [*R] relative pseudoranges -----------------------------------------*/ -static int decode_xR(raw_t *raw, char sig) -{ - uint8_t *p=raw->buff+5; - float pr; - int i,idx,code,sat,sys; - - if (!is_meas(sig)||raw->tod<0||raw->obuf.n==0) return 0; - - if (!checksum(raw->buff,raw->len)) { - trace(2,"javad %cR checksum error: len=%d\n",sig,raw->len); - return -1; - } - if (raw->len!=raw->obuf.n*4+6) { - trace(2,"javad %cR length error: n=%d len=%d\n",sig,raw->obuf.n,raw->len); - return -1; - } - for (i=0;iobuf.n&&iobuf.data[i].sat; - if (!(sys=satsys(sat,NULL))||raw->prCA[sat-1]==0.0) continue; - - if ((idx=sig2idx(sys,sig,&code))<0) continue; - - if ((idx=checkpri(sys,code,raw->opt,idx))>=0) { - if (!settag(raw->obuf.data+i,raw->time)) continue; - raw->obuf.data[i].P[idx]=pr*CLIGHT+raw->prCA[sat-1]; - raw->obuf.data[i].code[idx]=(uint8_t)code; - } +static int decode_xR(raw_t *raw, char sig) { + uint8_t *p = raw->buff + 5; + float pr; + int i, idx, code, sat, sys; + + if (!is_meas(sig) || raw->tod < 0 || raw->obuf.n == 0) return 0; + + if (!checksum(raw->buff, raw->len)) { + trace(2, "javad %cR checksum error: len=%d\n", sig, raw->len); + return -1; + } + if (raw->len != raw->obuf.n * 4 + 6) { + trace(2, "javad %cR length error: n=%d len=%d\n", sig, raw->obuf.n, raw->len); + return -1; + } + for (i = 0; i < raw->obuf.n && i < MAXOBS; i++) { + pr = R4(p); + p += 4; + if (pr == 0.0) continue; + + sat = raw->obuf.data[i].sat; + if (!(sys = satsys(sat, NULL)) || raw->prCA[sat - 1] == 0.0) continue; + + if ((idx = sig2idx(sys, sig, &code)) < 0) continue; + + if ((idx = checkpri(sys, code, raw->opt, idx)) >= 0) { + if (!settag(raw->obuf.data + i, raw->time)) continue; + raw->obuf.data[i].P[idx] = pr * CLIGHT + raw->prCA[sat - 1]; + raw->obuf.data[i].code[idx] = (uint8_t)code; } - return 0; + } + return 0; } /* decode [*r] short relative pseudoranges -----------------------------------*/ -static int decode_xr(raw_t *raw, char sig) -{ - uint8_t *p=raw->buff+5; - double prm; - int16_t pr; - int i,idx,code,sat,sys; - - if (!is_meas(sig)||raw->tod<0||raw->obuf.n==0) return 0; - - if (!checksum(raw->buff,raw->len)) { - trace(2,"javad %cr checksum error: len=%d\n",sig,raw->len); - return -1; - } - if (raw->len!=raw->obuf.n*2+6) { - trace(2,"javad %cR length error: n=%d len=%d\n",sig,raw->obuf.n,raw->len); - return -1; - } - for (i=0;iobuf.n&&iobuf.data[i].sat; - if (!(sys=satsys(sat,NULL))||raw->prCA[sat-1]==0.0) continue; - - prm=(pr*1E-11+2E-7)*CLIGHT+raw->prCA[sat-1]; - - if ((idx=sig2idx(sys,sig,&code))<0) continue; - - if ((idx=checkpri(sys,code,raw->opt,idx))>=0) { - if (!settag(raw->obuf.data+i,raw->time)) continue; - raw->obuf.data[i].P[idx]=prm; - raw->obuf.data[i].code[idx]=(uint8_t)code; - } +static int decode_xr(raw_t *raw, char sig) { + uint8_t *p = raw->buff + 5; + double prm; + int16_t pr; + int i, idx, code, sat, sys; + + if (!is_meas(sig) || raw->tod < 0 || raw->obuf.n == 0) return 0; + + if (!checksum(raw->buff, raw->len)) { + trace(2, "javad %cr checksum error: len=%d\n", sig, raw->len); + return -1; + } + if (raw->len != raw->obuf.n * 2 + 6) { + trace(2, "javad %cR length error: n=%d len=%d\n", sig, raw->obuf.n, raw->len); + return -1; + } + for (i = 0; i < raw->obuf.n && i < MAXOBS; i++) { + pr = I2(p); + p += 2; + if (pr == (int16_t)0x7FFF) continue; + + sat = raw->obuf.data[i].sat; + if (!(sys = satsys(sat, NULL)) || raw->prCA[sat - 1] == 0.0) continue; + + prm = (pr * 1E-11 + 2E-7) * CLIGHT + raw->prCA[sat - 1]; + + if ((idx = sig2idx(sys, sig, &code)) < 0) continue; + + if ((idx = checkpri(sys, code, raw->opt, idx)) >= 0) { + if (!settag(raw->obuf.data + i, raw->time)) continue; + raw->obuf.data[i].P[idx] = prm; + raw->obuf.data[i].code[idx] = (uint8_t)code; } - return 0; + } + return 0; } /* decode [P*] carrier phases ------------------------------------------------*/ -static int decode_Px(raw_t *raw, char sig) -{ - uint8_t *p=raw->buff+5; - double cp; - int i,idx,code,sys; - - if (!is_meas(sig)||raw->tod<0||raw->obuf.n==0) return 0; - - if (!checksum(raw->buff,raw->len)) { - trace(2,"javad P%c checksum error: len=%d\n",sig,raw->len); - return -1; - } - if (raw->len!=raw->obuf.n*8+6) { - trace(2,"javad P%c length error: n=%d len=%d\n",sig,raw->obuf.n,raw->len); - return -1; - } - for (i=0;iobuf.n&&iobuf.data[i].sat,NULL))) continue; - - if ((idx=sig2idx(sys,sig,&code))<0) continue; - - if ((idx=checkpri(sys,code,raw->opt,idx))>=0) { - if (!settag(raw->obuf.data+i,raw->time)) continue; - raw->obuf.data[i].L[idx]=cp; - raw->obuf.data[i].code[idx]=(uint8_t)code; - } +static int decode_Px(raw_t *raw, char sig) { + uint8_t *p = raw->buff + 5; + double cp; + int i, idx, code, sys; + + if (!is_meas(sig) || raw->tod < 0 || raw->obuf.n == 0) return 0; + + if (!checksum(raw->buff, raw->len)) { + trace(2, "javad P%c checksum error: len=%d\n", sig, raw->len); + return -1; + } + if (raw->len != raw->obuf.n * 8 + 6) { + trace(2, "javad P%c length error: n=%d len=%d\n", sig, raw->obuf.n, raw->len); + return -1; + } + for (i = 0; i < raw->obuf.n && i < MAXOBS; i++) { + cp = R8(p); + p += 8; + if (cp == 0.0) continue; + + if (!(sys = satsys(raw->obuf.data[i].sat, NULL))) continue; + + if ((idx = sig2idx(sys, sig, &code)) < 0) continue; + + if ((idx = checkpri(sys, code, raw->opt, idx)) >= 0) { + if (!settag(raw->obuf.data + i, raw->time)) continue; + raw->obuf.data[i].L[idx] = cp; + raw->obuf.data[i].code[idx] = (uint8_t)code; } - return 0; + } + return 0; } /* decode [p*] short carrier phases ------------------------------------------*/ -static int decode_px(raw_t *raw, char sig) -{ - uint8_t *p=raw->buff+5; - uint32_t cp; - int i,idx,code,sys; - - if (!is_meas(sig)||raw->tod<0||raw->obuf.n==0) return 0; - - if (!checksum(raw->buff,raw->len)) { - trace(2,"javad p%c checksum error: len=%d\n",sig,raw->len); - return -1; - } - if (raw->len!=raw->obuf.n*4+6) { - trace(2,"javad p%c length error: n=%d len=%d\n",sig,raw->obuf.n,raw->len); - return -1; - } - for (i=0;iobuf.n&&iobuf.data[i].sat,NULL))) continue; - - if ((idx=sig2idx(sys,sig,&code))<0) continue; - - if ((idx=checkpri(sys,code,raw->opt,idx))>=0) { - if (!settag(raw->obuf.data+i,raw->time)) continue; - raw->obuf.data[i].L[idx]=cp/1024.0; - raw->obuf.data[i].code[idx]=(uint8_t)code; - } +static int decode_px(raw_t *raw, char sig) { + uint8_t *p = raw->buff + 5; + uint32_t cp; + int i, idx, code, sys; + + if (!is_meas(sig) || raw->tod < 0 || raw->obuf.n == 0) return 0; + + if (!checksum(raw->buff, raw->len)) { + trace(2, "javad p%c checksum error: len=%d\n", sig, raw->len); + return -1; + } + if (raw->len != raw->obuf.n * 4 + 6) { + trace(2, "javad p%c length error: n=%d len=%d\n", sig, raw->obuf.n, raw->len); + return -1; + } + for (i = 0; i < raw->obuf.n && i < MAXOBS; i++) { + cp = U4(p); + p += 4; + if (cp == 0xFFFFFFFF) continue; + + if (!(sys = satsys(raw->obuf.data[i].sat, NULL))) continue; + + if ((idx = sig2idx(sys, sig, &code)) < 0) continue; + + if ((idx = checkpri(sys, code, raw->opt, idx)) >= 0) { + if (!settag(raw->obuf.data + i, raw->time)) continue; + raw->obuf.data[i].L[idx] = cp / 1024.0; + raw->obuf.data[i].code[idx] = (uint8_t)code; } - return 0; + } + return 0; } /* decode [*P] short relative carrier phases ---------------------------------*/ -static int decode_xP(raw_t *raw, char sig) -{ - uint8_t *p=raw->buff+5; - double cp,rcp,freq; - int i,idx,code,sat,sys; - - if (!is_meas(sig)||raw->tod<0||raw->obuf.n==0) return 0; - - if (!checksum(raw->buff,raw->len)) { - trace(2,"javad %cP checksum error: len=%d\n",sig,raw->len); - return -1; - } - if (raw->len!=raw->obuf.n*4+6) { - trace(2,"javad %cP length error: n=%d len=%d\n",sig,raw->obuf.n,raw->len); - return -1; - } - for (i=0;iobuf.n&&iobuf.data[i].sat; - if (!(sys=satsys(sat,NULL))||raw->prCA[sat-1]==0.0) continue; - - if ((idx=sig2idx(sys,sig,&code))<0) continue; - - if ((idx=checkpri(sys,code,raw->opt,idx))>=0) { - if (!settag(raw->obuf.data+i,raw->time)) continue; - - freq=code2freq(sys,code,raw->freqn[i]); - cp=(rcp+raw->prCA[sat-1]/CLIGHT)*freq; - - raw->obuf.data[i].L[idx]=cp; - raw->obuf.data[i].code[idx]=(uint8_t)code; - } +static int decode_xP(raw_t *raw, char sig) { + uint8_t *p = raw->buff + 5; + double cp, rcp, freq; + int i, idx, code, sat, sys; + + if (!is_meas(sig) || raw->tod < 0 || raw->obuf.n == 0) return 0; + + if (!checksum(raw->buff, raw->len)) { + trace(2, "javad %cP checksum error: len=%d\n", sig, raw->len); + return -1; + } + if (raw->len != raw->obuf.n * 4 + 6) { + trace(2, "javad %cP length error: n=%d len=%d\n", sig, raw->obuf.n, raw->len); + return -1; + } + for (i = 0; i < raw->obuf.n && i < MAXOBS; i++) { + rcp = R4(p); + p += 4; + if (rcp == 0.0) continue; + + sat = raw->obuf.data[i].sat; + if (!(sys = satsys(sat, NULL)) || raw->prCA[sat - 1] == 0.0) continue; + + if ((idx = sig2idx(sys, sig, &code)) < 0) continue; + + if ((idx = checkpri(sys, code, raw->opt, idx)) >= 0) { + if (!settag(raw->obuf.data + i, raw->time)) continue; + + freq = code2freq(sys, code, raw->freqn[i]); + cp = (rcp + raw->prCA[sat - 1] / CLIGHT) * freq; + + raw->obuf.data[i].L[idx] = cp; + raw->obuf.data[i].code[idx] = (uint8_t)code; } - return 0; + } + return 0; } /* decode [*p] short relative carrier phases ---------------------------------*/ -static int decode_xp(raw_t *raw, char sig) -{ - uint8_t *p=raw->buff+5; - double cp,freq; - int i,idx,code,rcp,sat,sys; - - if (!is_meas(sig)||raw->tod<0||raw->obuf.n==0) return 0; - - if (!checksum(raw->buff,raw->len)) { - trace(2,"javad %cp checksum error: len=%d\n",sig,raw->len); - return -1; - } - if (raw->len!=raw->obuf.n*4+6) { - trace(2,"javad %cp length error: n=%d len=%d\n",sig,raw->obuf.n,raw->len); - return -1; - } - for (i=0;iobuf.n&&iobuf.data[i].sat; - if (!(sys=satsys(sat,NULL))||raw->prCA[sat-1]==0.0) continue; - - if ((idx=sig2idx(sys,sig,&code))<0) continue; - - if ((idx=checkpri(sys,code,raw->opt,idx))>=0) { - if (!settag(raw->obuf.data+i,raw->time)) continue; - - freq=code2freq(sys,(uint8_t)code,raw->freqn[i]); - cp=(rcp*P2_40+raw->prCA[sat-1]/CLIGHT)*freq; - - raw->obuf.data[i].L[idx]=cp; - raw->obuf.data[i].code[idx]=(uint8_t)code; - } +static int decode_xp(raw_t *raw, char sig) { + uint8_t *p = raw->buff + 5; + double cp, freq; + int i, idx, code, rcp, sat, sys; + + if (!is_meas(sig) || raw->tod < 0 || raw->obuf.n == 0) return 0; + + if (!checksum(raw->buff, raw->len)) { + trace(2, "javad %cp checksum error: len=%d\n", sig, raw->len); + return -1; + } + if (raw->len != raw->obuf.n * 4 + 6) { + trace(2, "javad %cp length error: n=%d len=%d\n", sig, raw->obuf.n, raw->len); + return -1; + } + for (i = 0; i < raw->obuf.n && i < MAXOBS; i++) { + rcp = I4(p); + p += 4; + if (rcp == 0x7FFFFFFF) continue; + + sat = raw->obuf.data[i].sat; + if (!(sys = satsys(sat, NULL)) || raw->prCA[sat - 1] == 0.0) continue; + + if ((idx = sig2idx(sys, sig, &code)) < 0) continue; + + if ((idx = checkpri(sys, code, raw->opt, idx)) >= 0) { + if (!settag(raw->obuf.data + i, raw->time)) continue; + + freq = code2freq(sys, (uint8_t)code, raw->freqn[i]); + cp = (rcp * P2_40 + raw->prCA[sat - 1] / CLIGHT) * freq; + + raw->obuf.data[i].L[idx] = cp; + raw->obuf.data[i].code[idx] = (uint8_t)code; } - return 0; + } + return 0; } /* decode [D*] doppler -------------------------------------------------------*/ -static int decode_Dx(raw_t *raw, char sig) -{ - uint8_t *p=raw->buff+5; - double dop; - int i,idx,code,dp,sat,sys; - - if (!is_meas(sig)||raw->tod<0||raw->obuf.n==0) return 0; - - if (!checksum(raw->buff,raw->len)) { - trace(2,"javad D%c checksum error: len=%d\n",sig,raw->len); - return -1; - } - if (raw->len!=raw->obuf.n*4+6) { - trace(2,"javad D%c length error: n=%d len=%d\n",sig,raw->obuf.n,raw->len); - return -1; - } - for (i=0;iobuf.n&&iobuf.data[i].sat; - if (!(sys=satsys(sat,NULL))) continue; - - dop=-dp*1E-4; - - if (sig=='C') raw->dpCA[sat-1]=dop; - - if ((idx=sig2idx(sys,sig,&code))<0) continue; - - if ((idx=checkpri(sys,code,raw->opt,idx))>=0) { - if (!settag(raw->obuf.data+i,raw->time)) continue; - raw->obuf.data[i].D[idx]=(float)dop; - } +static int decode_Dx(raw_t *raw, char sig) { + uint8_t *p = raw->buff + 5; + double dop; + int i, idx, code, dp, sat, sys; + + if (!is_meas(sig) || raw->tod < 0 || raw->obuf.n == 0) return 0; + + if (!checksum(raw->buff, raw->len)) { + trace(2, "javad D%c checksum error: len=%d\n", sig, raw->len); + return -1; + } + if (raw->len != raw->obuf.n * 4 + 6) { + trace(2, "javad D%c length error: n=%d len=%d\n", sig, raw->obuf.n, raw->len); + return -1; + } + for (i = 0; i < raw->obuf.n && i < MAXOBS; i++) { + dp = I4(p); + p += 4; + if (dp == 0x7FFFFFFF) continue; + + sat = raw->obuf.data[i].sat; + if (!(sys = satsys(sat, NULL))) continue; + + dop = -dp * 1E-4; + + if (sig == 'C') raw->dpCA[sat - 1] = dop; + + if ((idx = sig2idx(sys, sig, &code)) < 0) continue; + + if ((idx = checkpri(sys, code, raw->opt, idx)) >= 0) { + if (!settag(raw->obuf.data + i, raw->time)) continue; + raw->obuf.data[i].D[idx] = (float)dop; } - return 0; + } + return 0; } /* decode [*d] short relative doppler ----------------------------------------*/ -static int decode_xd(raw_t *raw, char sig) -{ - uint8_t *p=raw->buff+5; - double dop,f1,fn; - int16_t rdp; - int i,idx,code,sat,sys; - - if (!is_meas(sig)||raw->tod<0||raw->obuf.n==0) return 0; - - if (!checksum(raw->buff,raw->len)) { - trace(2,"javad %cd checksum error: len=%d\n",sig,raw->len); - return -1; - } - if (raw->len!=raw->obuf.n*2+6) { - trace(2,"javad %cd length error: n=%d len=%d\n",sig,raw->obuf.n,raw->len); - return -1; - } - for (i=0;iobuf.n&&iobuf.data[i].sat; - if (!(sys=satsys(sat,NULL))||raw->dpCA[sat-1]==0.0) continue; - - if ((idx=sig2idx(sys,sig,&code))<0) continue; - - if ((idx=checkpri(sys,code,raw->opt,idx))>=0) { - if (!settag(raw->obuf.data+i,raw->time)) continue; - f1=code2freq(sys,CODE_L1X,raw->freqn[i]); - fn=code2freq(sys,code ,raw->freqn[i]); - dop=(-rdp+raw->dpCA[sat-1]*1E4)*fn/f1*1E-4; - - raw->obuf.data[i].D[idx]=(float)dop; - } +static int decode_xd(raw_t *raw, char sig) { + uint8_t *p = raw->buff + 5; + double dop, f1, fn; + int16_t rdp; + int i, idx, code, sat, sys; + + if (!is_meas(sig) || raw->tod < 0 || raw->obuf.n == 0) return 0; + + if (!checksum(raw->buff, raw->len)) { + trace(2, "javad %cd checksum error: len=%d\n", sig, raw->len); + return -1; + } + if (raw->len != raw->obuf.n * 2 + 6) { + trace(2, "javad %cd length error: n=%d len=%d\n", sig, raw->obuf.n, raw->len); + return -1; + } + for (i = 0; i < raw->obuf.n && i < MAXOBS; i++) { + rdp = I2(p); + p += 2; + if (rdp == (int16_t)0x7FFF) continue; + + sat = raw->obuf.data[i].sat; + if (!(sys = satsys(sat, NULL)) || raw->dpCA[sat - 1] == 0.0) continue; + + if ((idx = sig2idx(sys, sig, &code)) < 0) continue; + + if ((idx = checkpri(sys, code, raw->opt, idx)) >= 0) { + if (!settag(raw->obuf.data + i, raw->time)) continue; + f1 = code2freq(sys, CODE_L1X, raw->freqn[i]); + fn = code2freq(sys, code, raw->freqn[i]); + dop = (-rdp + raw->dpCA[sat - 1] * 1E4) * fn / f1 * 1E-4; + + raw->obuf.data[i].D[idx] = (float)dop; } - return 0; + } + return 0; } /* decode [E*] carrier to noise ratio ----------------------------------------*/ -static int decode_Ex(raw_t *raw, char sig) -{ - uint8_t *p=raw->buff+5; - uint8_t cnr; - int i,idx,code,sys; - - if (!is_meas(sig)||raw->tod<0||raw->obuf.n==0) return 0; - - if (!checksum(raw->buff,raw->len)) { - trace(2,"javad E%c checksum error: len=%d\n",sig,raw->len); - return -1; - } - if (raw->len!=raw->obuf.n+6) { - trace(2,"javad E%c length error: n=%d len=%d\n",sig,raw->obuf.n,raw->len); - return -1; - } - for (i=0;iobuf.n&&iobuf.data[i].sat,NULL))) continue; - - if ((idx=sig2idx(sys,sig,&code))<0) continue; - - if ((idx=checkpri(sys,code,raw->opt,idx))>=0) { - if (!settag(raw->obuf.data+i,raw->time)) continue; - raw->obuf.data[i].SNR[idx]=cnr; - } +static int decode_Ex(raw_t *raw, char sig) { + uint8_t *p = raw->buff + 5; + uint8_t cnr; + int i, idx, code, sys; + + if (!is_meas(sig) || raw->tod < 0 || raw->obuf.n == 0) return 0; + + if (!checksum(raw->buff, raw->len)) { + trace(2, "javad E%c checksum error: len=%d\n", sig, raw->len); + return -1; + } + if (raw->len != raw->obuf.n + 6) { + trace(2, "javad E%c length error: n=%d len=%d\n", sig, raw->obuf.n, raw->len); + return -1; + } + for (i = 0; i < raw->obuf.n && i < MAXOBS; i++) { + cnr = U1(p); + p += 1; + if (cnr == 255) continue; + + if (!(sys = satsys(raw->obuf.data[i].sat, NULL))) continue; + + if ((idx = sig2idx(sys, sig, &code)) < 0) continue; + + if ((idx = checkpri(sys, code, raw->opt, idx)) >= 0) { + if (!settag(raw->obuf.data + i, raw->time)) continue; + raw->obuf.data[i].SNR[idx] = cnr; } - return 0; + } + return 0; } /* decode [*E] carrier to noise ratio x 4 ------------------------------------*/ -static int decode_xE(raw_t *raw, char sig) -{ - uint8_t *p=raw->buff+5; - uint8_t cnr; - int i,idx,code,sys; - - if (!is_meas(sig)||raw->tod<0||raw->obuf.n==0) return 0; - - if (!checksum(raw->buff,raw->len)) { - trace(2,"javad %cE checksum error: len=%d\n",sig,raw->len); - return -1; - } - if (raw->len!=raw->obuf.n+6) { - trace(2,"javad %cE length error: n=%d len=%d\n",sig,raw->obuf.n,raw->len); - return -1; - } - for (i=0;iobuf.n&&iobuf.data[i].sat,NULL))) continue; - - if ((idx=sig2idx(sys,sig,&code))<0) continue; - - if ((idx=checkpri(sys,code,raw->opt,idx))>=0) { - if (!settag(raw->obuf.data+i,raw->time)) continue; - raw->obuf.data[i].SNR[idx]=cnr*0.25; - } +static int decode_xE(raw_t *raw, char sig) { + uint8_t *p = raw->buff + 5; + uint8_t cnr; + int i, idx, code, sys; + + if (!is_meas(sig) || raw->tod < 0 || raw->obuf.n == 0) return 0; + + if (!checksum(raw->buff, raw->len)) { + trace(2, "javad %cE checksum error: len=%d\n", sig, raw->len); + return -1; + } + if (raw->len != raw->obuf.n + 6) { + trace(2, "javad %cE length error: n=%d len=%d\n", sig, raw->obuf.n, raw->len); + return -1; + } + for (i = 0; i < raw->obuf.n && i < MAXOBS; i++) { + cnr = U1(p); + p += 1; + if (cnr == 255) continue; + + if (!(sys = satsys(raw->obuf.data[i].sat, NULL))) continue; + + if ((idx = sig2idx(sys, sig, &code)) < 0) continue; + + if ((idx = checkpri(sys, code, raw->opt, idx)) >= 0) { + if (!settag(raw->obuf.data + i, raw->time)) continue; + raw->obuf.data[i].SNR[idx] = cnr * 0.25; } - return 0; + } + return 0; } /* decode [F*] signal lock loop flags ----------------------------------------*/ -static int decode_Fx(raw_t *raw, char sig) -{ - uint8_t *p=raw->buff+5; - uint16_t flags; - int i,idx,code,sat,sys; - - if (!is_meas(sig)||raw->tod<0||raw->obuf.n==0) return 0; - - if (!checksum(raw->buff,raw->len)) { - trace(2,"javad F%c checksum error: len=%d\n",sig,raw->len); - return -1; - } - if (raw->len!=raw->obuf.n*2+6) { - trace(2,"javad F%c length error: n=%d len=%d\n",sig,raw->obuf.n,raw->len); - return -1; - } - for (i=0;iobuf.n&&iobuf.data[i].sat; - if (!(sys=satsys(sat,NULL))) continue; - - if ((idx=sig2idx(sys,sig,&code))<0) continue; - - if ((idx=checkpri(sys,code,raw->opt,idx))>=0) { - if (!settag(raw->obuf.data+i,raw->time)) continue; -#ifdef RTK_DISABLED /* disable to suppress overdetection of cycle-slips */ - if (flags&0x20) { /* loss-of-lock potential */ - raw->obuf.data[i].LLI[idx]|=1; - } - if (!(flags&0x40)||!(flags&0x100)) { /* integral indicator */ - raw->obuf.data[i].LLI[idx]|=2; - } +static int decode_Fx(raw_t *raw, char sig) { + uint8_t *p = raw->buff + 5; + uint16_t flags; + int i, idx, code, sat, sys; + + if (!is_meas(sig) || raw->tod < 0 || raw->obuf.n == 0) return 0; + + if (!checksum(raw->buff, raw->len)) { + trace(2, "javad F%c checksum error: len=%d\n", sig, raw->len); + return -1; + } + if (raw->len != raw->obuf.n * 2 + 6) { + trace(2, "javad F%c length error: n=%d len=%d\n", sig, raw->obuf.n, raw->len); + return -1; + } + for (i = 0; i < raw->obuf.n && i < MAXOBS; i++) { + flags = U2(p); + p += 1; + if (flags == 0xFFFF) continue; + + sat = raw->obuf.data[i].sat; + if (!(sys = satsys(sat, NULL))) continue; + + if ((idx = sig2idx(sys, sig, &code)) < 0) continue; + + if ((idx = checkpri(sys, code, raw->opt, idx)) >= 0) { + if (!settag(raw->obuf.data + i, raw->time)) continue; +#ifdef RTK_DISABLED /* disable to suppress overdetection of cycle-slips */ + if (flags & 0x20) { /* loss-of-lock potential */ + raw->obuf.data[i].LLI[idx] |= 1; + } + if (!(flags & 0x40) || !(flags & 0x100)) { /* integral indicator */ + raw->obuf.data[i].LLI[idx] |= 2; + } #endif - } } - return 0; + } + return 0; } /* decode [TC] CA/L1 continuous tracking time --------------------------------*/ -static int decode_TC(raw_t *raw) -{ - uint16_t tt,tt_p; - int i,sat; - uint8_t *p=raw->buff+5; - - if (raw->obuf.n==0) return 0; - - if (!checksum(raw->buff,raw->len)) { - trace(2,"javad TC checksum error: len=%d\n",raw->len); - return -1; - } - if (raw->len!=raw->obuf.n*2+6) { - trace(2,"javad TC length error: n=%d len=%d\n",raw->obuf.n,raw->len); - return -1; - } - for (i=0;iobuf.n&&iobuf.data+i,raw->time)) continue; - - sat=raw->obuf.data[i].sat; - tt_p=(uint16_t)raw->lockt[sat-1][0]; - - char tstr[40]; - trace(4,"%s: sat=%2d tt=%6d->%6d\n",time2str(raw->time,tstr,3),sat,tt_p,tt); - - /* loss-of-lock detected by lock-time counter */ - if (tt==0||tt%6d\n", - time2str(raw->time,tstr,3),sat,tt_p,tt); - raw->obuf.data[i].LLI[0]|=1; - } - raw->lockt[sat-1][0]=tt; +static int decode_TC(raw_t *raw) { + uint16_t tt, tt_p; + int i, sat; + uint8_t *p = raw->buff + 5; + + if (raw->obuf.n == 0) return 0; + + if (!checksum(raw->buff, raw->len)) { + trace(2, "javad TC checksum error: len=%d\n", raw->len); + return -1; + } + if (raw->len != raw->obuf.n * 2 + 6) { + trace(2, "javad TC length error: n=%d len=%d\n", raw->obuf.n, raw->len); + return -1; + } + for (i = 0; i < raw->obuf.n && i < MAXOBS; i++) { + tt = U2(p); + p += 2; + if (tt == 0xFFFF) continue; + + if (!settag(raw->obuf.data + i, raw->time)) continue; + + sat = raw->obuf.data[i].sat; + tt_p = (uint16_t)raw->lockt[sat - 1][0]; + + char tstr[40]; + trace(4, "%s: sat=%2d tt=%6d->%6d\n", time2str(raw->time, tstr, 3), sat, tt_p, tt); + + /* loss-of-lock detected by lock-time counter */ + if (tt == 0 || tt < tt_p) { + trace(3, "decode_TC: loss-of-lock detected: t=%s sat=%2d tt=%6d->%6d\n", + time2str(raw->time, tstr, 3), sat, tt_p, tt); + raw->obuf.data[i].LLI[0] |= 1; } - return 0; + raw->lockt[sat - 1][0] = tt; + } + return 0; } /* decode JAVAD raw message --------------------------------------------------*/ -static int decode_javad(raw_t *raw) -{ - char *p=(char *)raw->buff; - - trace(3,"decode_javad: type=%2.2s len=%3d\n",p,raw->len); - - if (raw->outtype) { - sprintf(raw->msgtype,"JAVAD %2.2s (%4d)",p,raw->len); - } - if (!strncmp(p,"~~",2)) return decode_RT(raw); /* receiver time */ - - if (strstr(raw->opt,"-NOET")) { - if (!strncmp(p,"::",2)) return decode_ET(raw); /* epoch time */ - } - if (!strncmp(p,"RD",2)) return decode_RD(raw); /* receiver date */ - if (!strncmp(p,"SI",2)) return decode_SI(raw); /* satellite indices */ - if (!strncmp(p,"NN",2)) return decode_NN(raw); /* GLONASS slot numbers */ - if (!strncmp(p,"GA",2)) return decode_GA(raw); /* GPS almanac */ - if (!strncmp(p,"NA",2)) return decode_NA(raw); /* GLONASS almanac */ - if (!strncmp(p,"EA",2)) return decode_EA(raw); /* Galileo almanac */ - if (!strncmp(p,"WA",2)) return decode_WA(raw); /* SBAS almanac */ - if (!strncmp(p,"QA",2)) return decode_QA(raw); /* QZSS almanac */ - if (!strncmp(p,"CA",2)) return decode_CA(raw); /* Beidou almanac */ - if (!strncmp(p,"IA",2)) return decode_IA(raw); /* IRNSS almanac */ - - if (!strncmp(p,"GE",2)) return decode_GE(raw); /* GPS ephemeris */ - if (!strncmp(p,"NE",2)) return decode_NE(raw); /* GLONASS ephemeris */ - if (!strncmp(p,"EN",2)) return decode_EN(raw); /* Galileo ephemeris */ - if (!strncmp(p,"WE",2)) return decode_WE(raw); /* SBAS ephemeris */ - if (!strncmp(p,"QE",2)) return decode_QE(raw); /* QZSS ephemeris */ - if (!strncmp(p,"CN",2)) return decode_CN(raw); /* Beidou ephemeris */ - if (!strncmp(p,"IE",2)) return decode_IE(raw); /* IRNSS ephemeris */ - - if (!strncmp(p,"UO",2)) return decode_UO(raw); /* GPS UTC time parameters */ - if (!strncmp(p,"NU",2)) return decode_NU(raw); /* GLONASS UTC and GPS time par */ - if (!strncmp(p,"EU",2)) return decode_EU(raw); /* Galileo UTC and GPS time par */ - if (!strncmp(p,"WU",2)) return decode_WU(raw); /* WAAS UTC time parameters */ - if (!strncmp(p,"QU",2)) return decode_QU(raw); /* QZSS UTC and GPS time par */ - if (!strncmp(p,"IO",2)) return decode_IO(raw); /* ionospheric parameters */ - - if (!strncmp(p,"GD",2)) return decode_nD(raw,SYS_GPS); /* raw navigation data */ - if (!strncmp(p,"QD",2)) return decode_nD(raw,SYS_QZS); /* raw navigation data */ - if (!strncmp(p,"gd",2)) return decode_nd(raw,SYS_GPS); /* raw navigation data */ - if (!strncmp(p,"qd",2)) return decode_nd(raw,SYS_QZS); /* raw navigation data */ - if (!strncmp(p,"ED",2)) return decode_ED(raw); /* Galileo raw navigation data */ - - if (!strncmp(p,"cd",2)) return decode_cd(raw); /* Beidou raw navigation data */ - if (!strncmp(p,"id",2)) return decode_id(raw); /* IRNSS raw navigation data */ - if (!strncmp(p,"LD",2)) return decode_LD(raw); /* GLONASS raw navigation data */ - if (!strncmp(p,"lD",2)) return decode_lD(raw); /* GLONASS raw navigation data */ - if (!strncmp(p,"WD",2)) return decode_WD(raw); /* SBAS raw navigation data */ - if (!strncmp(p,"TC",2)) return decode_TC(raw); /* CA/L1 continuous track time */ - - if (p[0]=='R') return decode_Rx(raw,p[1]); /* pseudoranges */ - if (p[0]=='r') return decode_rx(raw,p[1]); /* short pseudoranges */ - if (p[1]=='R') return decode_xR(raw,p[0]); /* relative pseudoranges */ - if (p[1]=='r') return decode_xr(raw,p[0]); /* short relative pseudoranges */ - if (p[0]=='P') return decode_Px(raw,p[1]); /* carrier phases */ - if (p[0]=='p') return decode_px(raw,p[1]); /* short carrier phases */ - if (p[1]=='P') return decode_xP(raw,p[0]); /* relative carrier phases */ - if (p[1]=='p') return decode_xp(raw,p[0]); /* relative carrier phases */ - if (p[0]=='D') return decode_Dx(raw,p[1]); /* doppler */ - if (p[1]=='d') return decode_xd(raw,p[0]); /* short relative doppler */ - if (p[0]=='E') return decode_Ex(raw,p[1]); /* carrier to noise ratio */ - if (p[1]=='E') return decode_xE(raw,p[0]); /* carrier to noise ratio x 4 */ - if (p[0]=='F') return decode_Fx(raw,p[1]); /* signal lock loop flags */ - - return 0; +static int decode_javad(raw_t *raw) { + char *p = (char *)raw->buff; + + trace(3, "decode_javad: type=%2.2s len=%3d\n", p, raw->len); + + if (raw->outtype) { + sprintf(raw->msgtype, "JAVAD %2.2s (%4d)", p, raw->len); + } + if (!strncmp(p, "~~", 2)) return decode_RT(raw); /* receiver time */ + + if (strstr(raw->opt, "-NOET")) { + if (!strncmp(p, "::", 2)) return decode_ET(raw); /* epoch time */ + } + if (!strncmp(p, "RD", 2)) return decode_RD(raw); /* receiver date */ + if (!strncmp(p, "SI", 2)) return decode_SI(raw); /* satellite indices */ + if (!strncmp(p, "NN", 2)) return decode_NN(raw); /* GLONASS slot numbers */ + if (!strncmp(p, "GA", 2)) return decode_GA(raw); /* GPS almanac */ + if (!strncmp(p, "NA", 2)) return decode_NA(raw); /* GLONASS almanac */ + if (!strncmp(p, "EA", 2)) return decode_EA(raw); /* Galileo almanac */ + if (!strncmp(p, "WA", 2)) return decode_WA(raw); /* SBAS almanac */ + if (!strncmp(p, "QA", 2)) return decode_QA(raw); /* QZSS almanac */ + if (!strncmp(p, "CA", 2)) return decode_CA(raw); /* Beidou almanac */ + if (!strncmp(p, "IA", 2)) return decode_IA(raw); /* IRNSS almanac */ + + if (!strncmp(p, "GE", 2)) return decode_GE(raw); /* GPS ephemeris */ + if (!strncmp(p, "NE", 2)) return decode_NE(raw); /* GLONASS ephemeris */ + if (!strncmp(p, "EN", 2)) return decode_EN(raw); /* Galileo ephemeris */ + if (!strncmp(p, "WE", 2)) return decode_WE(raw); /* SBAS ephemeris */ + if (!strncmp(p, "QE", 2)) return decode_QE(raw); /* QZSS ephemeris */ + if (!strncmp(p, "CN", 2)) return decode_CN(raw); /* Beidou ephemeris */ + if (!strncmp(p, "IE", 2)) return decode_IE(raw); /* IRNSS ephemeris */ + + if (!strncmp(p, "UO", 2)) return decode_UO(raw); /* GPS UTC time parameters */ + if (!strncmp(p, "NU", 2)) return decode_NU(raw); /* GLONASS UTC and GPS time par */ + if (!strncmp(p, "EU", 2)) return decode_EU(raw); /* Galileo UTC and GPS time par */ + if (!strncmp(p, "WU", 2)) return decode_WU(raw); /* WAAS UTC time parameters */ + if (!strncmp(p, "QU", 2)) return decode_QU(raw); /* QZSS UTC and GPS time par */ + if (!strncmp(p, "IO", 2)) return decode_IO(raw); /* ionospheric parameters */ + + if (!strncmp(p, "GD", 2)) return decode_nD(raw, SYS_GPS); /* raw navigation data */ + if (!strncmp(p, "QD", 2)) return decode_nD(raw, SYS_QZS); /* raw navigation data */ + if (!strncmp(p, "gd", 2)) return decode_nd(raw, SYS_GPS); /* raw navigation data */ + if (!strncmp(p, "qd", 2)) return decode_nd(raw, SYS_QZS); /* raw navigation data */ + if (!strncmp(p, "ED", 2)) return decode_ED(raw); /* Galileo raw navigation data */ + + if (!strncmp(p, "cd", 2)) return decode_cd(raw); /* Beidou raw navigation data */ + if (!strncmp(p, "id", 2)) return decode_id(raw); /* IRNSS raw navigation data */ + if (!strncmp(p, "LD", 2)) return decode_LD(raw); /* GLONASS raw navigation data */ + if (!strncmp(p, "lD", 2)) return decode_lD(raw); /* GLONASS raw navigation data */ + if (!strncmp(p, "WD", 2)) return decode_WD(raw); /* SBAS raw navigation data */ + if (!strncmp(p, "TC", 2)) return decode_TC(raw); /* CA/L1 continuous track time */ + + if (p[0] == 'R') return decode_Rx(raw, p[1]); /* pseudoranges */ + if (p[0] == 'r') return decode_rx(raw, p[1]); /* short pseudoranges */ + if (p[1] == 'R') return decode_xR(raw, p[0]); /* relative pseudoranges */ + if (p[1] == 'r') return decode_xr(raw, p[0]); /* short relative pseudoranges */ + if (p[0] == 'P') return decode_Px(raw, p[1]); /* carrier phases */ + if (p[0] == 'p') return decode_px(raw, p[1]); /* short carrier phases */ + if (p[1] == 'P') return decode_xP(raw, p[0]); /* relative carrier phases */ + if (p[1] == 'p') return decode_xp(raw, p[0]); /* relative carrier phases */ + if (p[0] == 'D') return decode_Dx(raw, p[1]); /* doppler */ + if (p[1] == 'd') return decode_xd(raw, p[0]); /* short relative doppler */ + if (p[0] == 'E') return decode_Ex(raw, p[1]); /* carrier to noise ratio */ + if (p[1] == 'E') return decode_xE(raw, p[0]); /* carrier to noise ratio x 4 */ + if (p[0] == 'F') return decode_Fx(raw, p[1]); /* signal lock loop flags */ + + return 0; } /* sync JAVAD message --------------------------------------------------------*/ -static int sync_javad(uint8_t *buff, uint8_t data) -{ - uint8_t p=buff[0]; - - buff[0]=buff[1]; buff[1]=buff[2]; buff[2]=buff[3]; buff[3]=buff[4]; - buff[4]=data; - - /* sync message header {\r|\n}IIHHH (II:id,HHH: hex length) */ - return (p=='\r'||p=='\n')&&ISTXT(buff[0])&&ISTXT(buff[1])&& - ISHEX(buff[2])&&ISHEX(buff[3])&&ISHEX(buff[4]); +static int sync_javad(uint8_t *buff, uint8_t data) { + uint8_t p = buff[0]; + + buff[0] = buff[1]; + buff[1] = buff[2]; + buff[2] = buff[3]; + buff[3] = buff[4]; + buff[4] = data; + + /* sync message header {\r|\n}IIHHH (II:id,HHH: hex length) */ + return (p == '\r' || p == '\n') && ISTXT(buff[0]) && ISTXT(buff[1]) && ISHEX(buff[2]) && + ISHEX(buff[3]) && ISHEX(buff[4]); } /* clear buffer --------------------------------------------------------------*/ -static void clearbuff(raw_t *raw) -{ - int i; - for (i=0;i<5;i++) raw->buff[i]=0; - raw->len=raw->nbyte=0; +static void clearbuff(raw_t *raw) { + int i; + for (i = 0; i < 5; i++) raw->buff[i] = 0; + raw->len = raw->nbyte = 0; } /* input JAVAD raw message from stream ----------------------------------------- -* fetch next JAVAD raw data and input a mesasge from stream -* args : raw_t *raw IO receiver raw data control struct -* uint8_t data I stream data (1 byte) -* return : status (-1: error message, 0: no message, 1: input observation data, -* 2: input ephemeris, 3: input sbas message, -* 9: input ion/utc parameter) -* -* notes : to specify input options, set raw->opt to the following option -* strings separated by spaces. -* -* -EPHALL : input all ephemerides -* -GL1W : select 1W for GPS L1 (default 1C) -* -GL1X : select 1X for GPS L1 (default 1C) -* -GL2X : select 2X for GPS L2 (default 2W) -* -RL1P : select 1C for GLO G1 (default 1C) -* -RL2C : select 2C for GLO G2 (default 2P) -* -JL1Z : select 1Z for QZS L1 (default 1C) -* -JL1X : select 1X for QZS L1 (default 1C) -* -NOET : discard epoch time message ET (::) -* -GALINAV: select F/NAV for Galileo ephemeris (default: all) -* -GALFNAV: select F/NAV for Galileo ephemeris (default: all) -*-----------------------------------------------------------------------------*/ -extern int input_javad(raw_t *raw, uint8_t data) -{ - int len,stat; - - trace(5,"input_javad: data=%02x\n",data); - - /* synchronize message */ - if (raw->nbyte==0) { - if (!sync_javad(raw->buff,data)) return 0; - if (!(len=decodelen(raw->buff+2))||len>MAXRAWLEN-5) { - trace(2,"javad message length error: len=%d\n",len); - clearbuff(raw); - return -1; - } - raw->len=len+5; - raw->nbyte=5; - return 0; - } - raw->buff[raw->nbyte++]=data; - - if (raw->nbytelen) return 0; - - /* decode javad raw message */ - stat=decode_javad(raw); - - clearbuff(raw); - return stat; + * fetch next JAVAD raw data and input a mesasge from stream + * args : raw_t *raw IO receiver raw data control struct + * uint8_t data I stream data (1 byte) + * return : status (-1: error message, 0: no message, 1: input observation data, + * 2: input ephemeris, 3: input sbas message, + * 9: input ion/utc parameter) + * + * notes : to specify input options, set raw->opt to the following option + * strings separated by spaces. + * + * -EPHALL : input all ephemerides + * -GL1W : select 1W for GPS L1 (default 1C) + * -GL1X : select 1X for GPS L1 (default 1C) + * -GL2X : select 2X for GPS L2 (default 2W) + * -RL1P : select 1C for GLO G1 (default 1C) + * -RL2C : select 2C for GLO G2 (default 2P) + * -JL1Z : select 1Z for QZS L1 (default 1C) + * -JL1X : select 1X for QZS L1 (default 1C) + * -NOET : discard epoch time message ET (::) + * -GALINAV: select F/NAV for Galileo ephemeris (default: all) + * -GALFNAV: select F/NAV for Galileo ephemeris (default: all) + *-----------------------------------------------------------------------------*/ +extern int input_javad(raw_t *raw, uint8_t data) { + int len, stat; + + trace(5, "input_javad: data=%02x\n", data); + + /* synchronize message */ + if (raw->nbyte == 0) { + if (!sync_javad(raw->buff, data)) return 0; + if (!(len = decodelen(raw->buff + 2)) || len > MAXRAWLEN - 5) { + trace(2, "javad message length error: len=%d\n", len); + clearbuff(raw); + return -1; + } + raw->len = len + 5; + raw->nbyte = 5; + return 0; + } + raw->buff[raw->nbyte++] = data; + + if (raw->nbyte < raw->len) return 0; + + /* decode javad raw message */ + stat = decode_javad(raw); + + clearbuff(raw); + return stat; } /* start input file ----------------------------------------------------------*/ -static void startfile(raw_t *raw) -{ - raw->tod=-1; - raw->obuf.n=0; - raw->buff[4]='\n'; +static void startfile(raw_t *raw) { + raw->tod = -1; + raw->obuf.n = 0; + raw->buff[4] = '\n'; } /* end input file ------------------------------------------------------------*/ -static int endfile(raw_t *raw) -{ - /* flush observation data buffer */ - if (!flushobuf(raw)) return -2; - raw->obuf.n=0; - return 1; +static int endfile(raw_t *raw) { + /* flush observation data buffer */ + if (!flushobuf(raw)) return -2; + raw->obuf.n = 0; + return 1; } /* input JAVAD raw message from file ------------------------------------------- -* fetch next JAVAD raw data and input a message from file -* args : raw_t *raw IO receiver raw data control struct -* FILE *fp I file pointer -* return : status(-2: end of file, -1...9: same as above) -*-----------------------------------------------------------------------------*/ -extern int input_javadf(raw_t *raw, FILE *fp) -{ - int i,data,len,stat; - - trace(4,"input_javadf:\n"); - - /* start input file */ - if (raw->flag) { - startfile(raw); - raw->flag=0; - } - /* synchronize message */ - if (raw->nbyte==0) { - for (i=0;;i++) { - if ((data=fgetc(fp))==EOF) return endfile(raw); - if (sync_javad(raw->buff,(uint8_t)data)) break; - if (i>=4096) return 0; - } - } - if (!(len=decodelen(raw->buff+2))||len>MAXRAWLEN-5) { - trace(2,"javad message length error: len=%3.3s\n",raw->buff+2); - clearbuff(raw); - return -1; - } - raw->len=len+5; - raw->nbyte=5; - - if (fread(raw->buff+5,1,raw->len-5,fp)<(size_t)(raw->len-5)) { - return endfile(raw); - } - /* decode javad raw message */ - stat=decode_javad(raw); - + * fetch next JAVAD raw data and input a message from file + * args : raw_t *raw IO receiver raw data control struct + * FILE *fp I file pointer + * return : status(-2: end of file, -1...9: same as above) + *-----------------------------------------------------------------------------*/ +extern int input_javadf(raw_t *raw, FILE *fp) { + int i, data, len, stat; + + trace(4, "input_javadf:\n"); + + /* start input file */ + if (raw->flag) { + startfile(raw); + raw->flag = 0; + } + /* synchronize message */ + if (raw->nbyte == 0) { + for (i = 0;; i++) { + if ((data = fgetc(fp)) == EOF) return endfile(raw); + if (sync_javad(raw->buff, (uint8_t)data)) break; + if (i >= 4096) return 0; + } + } + if (!(len = decodelen(raw->buff + 2)) || len > MAXRAWLEN - 5) { + trace(2, "javad message length error: len=%3.3s\n", raw->buff + 2); clearbuff(raw); - return stat; + return -1; + } + raw->len = len + 5; + raw->nbyte = 5; + + if (fread(raw->buff + 5, 1, raw->len - 5, fp) < (size_t)(raw->len - 5)) { + return endfile(raw); + } + /* decode javad raw message */ + stat = decode_javad(raw); + + clearbuff(raw); + return stat; } diff --git a/src/rcv/novatel.c b/src/rcv/novatel.c index 89a0b1796..41c985927 100644 --- a/src/rcv/novatel.c +++ b/src/rcv/novatel.c @@ -1,1500 +1,1657 @@ /*------------------------------------------------------------------------------ -* novatel.c : NovAtel OEM7/OEM6/OEM5/OEM4/OEM3 receiver functions -* -* Copyright (C) 2007-2020 by T.TAKASU, All rights reserved. -* -* reference : -* [1] NovAtel, OM-20000094 Rev6 OEMV Family Firmware Reference Manual, 2008 -* [2] NovAtel, OM-20000053 Rev2 MiLLennium GPSCard Software Versions 4.503 -* and 4.52 Command Descriptions Manual, 2001 -* [3] NovAtel, OM-20000129 Rev2 OEM6 Family Firmware Reference Manual, 2011 -* [4] NovAtel, OM-20000127 Rev1 OEMStar Firmware Reference Manual, 2009 -* [5] NovAtel, OM-20000129 Rev6 OEM6 Family Firmware Reference Manual, 2014 -* [6] NovAtel, OM-20000169 v15C OEM7 Commands and Logs Reference Manual, -* June 2020 -* [7] Bynav, UG017 Inteface Protocol, Nov 2022 -* -* version : $Revision: 1.2 $ $Date: 2008/07/14 00:05:05 $ -* history : 2007/10/08 1.0 new -* 2008/05/09 1.1 fix bug lli flag outage -* 2008/06/16 1.2 separate common functions to rcvcmn.c -* 2009/04/01 1.3 add prn number check for raw obs data -* 2009/04/10 1.4 refactored -* add oem3, oem4 rangeb support -* 2009/06/06 1.5 fix bug on numerical exception with illegal snr -* support oem3 regd message -* 2009/12/09 1.6 support oem4 gloephemerisb message -* invalid if parity unknown in GLONASS range -* fix bug of dopper polarity inversion for oem3 regd -* 2010/04/29 1.7 add tod field in geph_t -* 2011/05/27 1.8 support RAWALM for oem4/v -* add almanac decoding -* add -EPHALL option -* fix problem on ARM compiler -* 2012/05/02 1.9 support OEM6,L5,QZSS -* 2012/10/18 1.10 change obs codes -* support Galileo -* support rawsbasframeb,galephemerisb,galalmanacb, -* galclockb,galionob -* 2012/11/08 1.11 support galfnavrawpageb, galinavrawword -* 2012/11/19 1.12 fix bug on decodeing rangeb -* 2013/02/23 1.13 fix memory access violation problem on arm -* 2013/03/28 1.14 fix invalid phase if glonass wavelen unavailable -* 2013/06/02 1.15 fix bug on reading galephemrisb,galalmanacb, -* galclockb,galionob -* fix bug on decoding rawwaasframeb for qzss-saif -* 2014/05/24 1.16 support beidou -* 2014/07/01 1.17 fix problem on decoding of bdsephemerisb -* fix bug on beidou tracking codes -* 2014/10/20 1.11 fix bug on receiver option -GL*,-RL*,-EL* -* 2016/01/28 1.12 precede I/NAV for galileo ephemeris -* add option -GALINAV and -GALFNAV -* 2016/07/31 1.13 add week number check to decode oem4 messages -* 2017/04/11 1.14 (char *) -> (signed char *) -* improve unchange-test of beidou ephemeris -* 2017/06/15 1.15 add output half-cycle-ambiguity status to LLI -* improve slip-detection by lock-time rollback -* 2018/10/10 1.16 fix problem on data source for galileo ephemeris -* output L2W instead of L2D for L2Pcodeless -* test toc difference to output beidou ephemeris -* 2019/05/10 1.17 save galileo E5b data to obs index 2 -* 2020/11/30 1.18 support OEM7 receiver (ref [6]) -* support NavIC/IRNSS -* support GPS/QZS L1C, GLO L3, GAL E6, QZS L6, BDS B3, -* B1C, B2a, B2b -* support message NAVICEPHEMERISB -* support QZS L1S in RANGEB and RANGECMPB -* no support message GALALMANACB -* add receiver option -GL1L,-GL2S,-GL2P,-EL6B,-JL1L, -* -JL1Z,-CL1P,-CL7D,-GLOBIAS=bias -* delete receiver option -GL1P,-GL2X,EL2C -* fix bug on reading SVH in GLOEPHEMERISB -* add reading of dtaun field in GLOEPHEMERISB -* output GAL I/NAV or F/NAV to seperated ephem sets -* use API sat2freq() to get carrier-frequency -* use API code2idx() to get freq-index -* use integer types in stdint.h -* 2024/12/06 1.19 support Bynav M2X receiver (ref[7]) -* add receiver option -CL6I -*-----------------------------------------------------------------------------*/ + * novatel.c : NovAtel OEM7/OEM6/OEM5/OEM4/OEM3 receiver functions + * + * Copyright (C) 2007-2020 by T.TAKASU, All rights reserved. + * + * reference : + * [1] NovAtel, OM-20000094 Rev6 OEMV Family Firmware Reference Manual, 2008 + * [2] NovAtel, OM-20000053 Rev2 MiLLennium GPSCard Software Versions 4.503 + * and 4.52 Command Descriptions Manual, 2001 + * [3] NovAtel, OM-20000129 Rev2 OEM6 Family Firmware Reference Manual, 2011 + * [4] NovAtel, OM-20000127 Rev1 OEMStar Firmware Reference Manual, 2009 + * [5] NovAtel, OM-20000129 Rev6 OEM6 Family Firmware Reference Manual, 2014 + * [6] NovAtel, OM-20000169 v15C OEM7 Commands and Logs Reference Manual, + * June 2020 + * [7] Bynav, UG017 Inteface Protocol, Nov 2022 + * + * version : $Revision: 1.2 $ $Date: 2008/07/14 00:05:05 $ + * history : 2007/10/08 1.0 new + * 2008/05/09 1.1 fix bug lli flag outage + * 2008/06/16 1.2 separate common functions to rcvcmn.c + * 2009/04/01 1.3 add prn number check for raw obs data + * 2009/04/10 1.4 refactored + * add oem3, oem4 rangeb support + * 2009/06/06 1.5 fix bug on numerical exception with illegal snr + * support oem3 regd message + * 2009/12/09 1.6 support oem4 gloephemerisb message + * invalid if parity unknown in GLONASS range + * fix bug of dopper polarity inversion for oem3 regd + * 2010/04/29 1.7 add tod field in geph_t + * 2011/05/27 1.8 support RAWALM for oem4/v + * add almanac decoding + * add -EPHALL option + * fix problem on ARM compiler + * 2012/05/02 1.9 support OEM6,L5,QZSS + * 2012/10/18 1.10 change obs codes + * support Galileo + * support rawsbasframeb,galephemerisb,galalmanacb, + * galclockb,galionob + * 2012/11/08 1.11 support galfnavrawpageb, galinavrawword + * 2012/11/19 1.12 fix bug on decodeing rangeb + * 2013/02/23 1.13 fix memory access violation problem on arm + * 2013/03/28 1.14 fix invalid phase if glonass wavelen unavailable + * 2013/06/02 1.15 fix bug on reading galephemrisb,galalmanacb, + * galclockb,galionob + * fix bug on decoding rawwaasframeb for qzss-saif + * 2014/05/24 1.16 support beidou + * 2014/07/01 1.17 fix problem on decoding of bdsephemerisb + * fix bug on beidou tracking codes + * 2014/10/20 1.11 fix bug on receiver option -GL*,-RL*,-EL* + * 2016/01/28 1.12 precede I/NAV for galileo ephemeris + * add option -GALINAV and -GALFNAV + * 2016/07/31 1.13 add week number check to decode oem4 messages + * 2017/04/11 1.14 (char *) -> (signed char *) + * improve unchange-test of beidou ephemeris + * 2017/06/15 1.15 add output half-cycle-ambiguity status to LLI + * improve slip-detection by lock-time rollback + * 2018/10/10 1.16 fix problem on data source for galileo ephemeris + * output L2W instead of L2D for L2Pcodeless + * test toc difference to output beidou ephemeris + * 2019/05/10 1.17 save galileo E5b data to obs index 2 + * 2020/11/30 1.18 support OEM7 receiver (ref [6]) + * support NavIC/IRNSS + * support GPS/QZS L1C, GLO L3, GAL E6, QZS L6, BDS B3, + * B1C, B2a, B2b + * support message NAVICEPHEMERISB + * support QZS L1S in RANGEB and RANGECMPB + * no support message GALALMANACB + * add receiver option -GL1L,-GL2S,-GL2P,-EL6B,-JL1L, + * -JL1Z,-CL1P,-CL7D,-GLOBIAS=bias + * delete receiver option -GL1P,-GL2X,EL2C + * fix bug on reading SVH in GLOEPHEMERISB + * add reading of dtaun field in GLOEPHEMERISB + * output GAL I/NAV or F/NAV to seperated ephem sets + * use API sat2freq() to get carrier-frequency + * use API code2idx() to get freq-index + * use integer types in stdint.h + * 2024/12/06 1.19 support Bynav M2X receiver (ref[7]) + * add receiver option -CL6I + *-----------------------------------------------------------------------------*/ #include "rtklib.h" -#define OEM4SYNC1 0xAA /* oem7/6/4 message start sync code 1 */ -#define OEM4SYNC2 0x44 /* oem7/6/4 message start sync code 2 */ -#define OEM4SYNC3 0x12 /* oem7/6/4 message start sync code 3 */ -#define OEM3SYNC1 0xAA /* oem3 message start sync code 1 */ -#define OEM3SYNC2 0x44 /* oem3 message start sync code 2 */ -#define OEM3SYNC3 0x11 /* oem3 message start sync code 3 */ -#define OEM4HLEN 28 /* oem7/6/4 message header length (bytes) */ -#define OEM3HLEN 12 /* oem3 message header length (bytes) */ +#define OEM4SYNC1 0xAA /* oem7/6/4 message start sync code 1 */ +#define OEM4SYNC2 0x44 /* oem7/6/4 message start sync code 2 */ +#define OEM4SYNC3 0x12 /* oem7/6/4 message start sync code 3 */ +#define OEM3SYNC1 0xAA /* oem3 message start sync code 1 */ +#define OEM3SYNC2 0x44 /* oem3 message start sync code 2 */ +#define OEM3SYNC3 0x11 /* oem3 message start sync code 3 */ +#define OEM4HLEN 28 /* oem7/6/4 message header length (bytes) */ +#define OEM3HLEN 12 /* oem3 message header length (bytes) */ /* message IDs */ -#define ID_RANGECMP 140 /* oem7/6/4 range compressed */ -#define ID_RANGE 43 /* oem7/6/4 range measurement */ -#define ID_RAWEPHEM 41 /* oem7/6/4 raw ephemeris */ -#define ID_IONUTC 8 /* oem7/6/4 iono and utc data */ +#define ID_RANGECMP 140 /* oem7/6/4 range compressed */ +#define ID_RANGE 43 /* oem7/6/4 range measurement */ +#define ID_RAWEPHEM 41 /* oem7/6/4 raw ephemeris */ +#define ID_IONUTC 8 /* oem7/6/4 iono and utc data */ #define ID_RAWWAASFRAME 287 /* oem7/6/4 raw waas frame */ #define ID_RAWSBASFRAME 973 /* oem7/6 raw sbas frame */ #define ID_GLOEPHEMERIS 723 /* oem7/6/4 glonass ephemeris */ #define ID_GALEPHEMERIS 1122 /* oem7/6 decoded galileo ephemeris */ -#define ID_GALIONO 1127 /* oem7/6 decoded galileo iono corrections */ -#define ID_GALCLOCK 1121 /* oem7/6 galileo clock information */ +#define ID_GALIONO 1127 /* oem7/6 decoded galileo iono corrections */ +#define ID_GALCLOCK 1121 /* oem7/6 galileo clock information */ #define ID_QZSSRAWEPHEM 1331 /* oem7/6 qzss raw ephemeris */ #define ID_QZSSRAWSUBFRAME 1330 /* oem7/6 qzss raw subframe */ -#define ID_QZSSIONUTC 1347 /* oem7/6 qzss ion/utc parameters */ +#define ID_QZSSIONUTC 1347 /* oem7/6 qzss ion/utc parameters */ #define ID_BDSEPHEMERIS 1696 /* oem7/6 decoded bds ephemeris */ #define ID_NAVICEPHEMERIS 2123 /* oem7 decoded navic ephemeris */ -#define ID_ALMB 18 /* oem3 decoded almanac */ -#define ID_IONB 16 /* oem3 iono parameters */ -#define ID_UTCB 17 /* oem3 utc parameters */ -#define ID_FRMB 54 /* oem3 framed raw navigation data */ -#define ID_RALB 15 /* oem3 raw almanac */ -#define ID_RASB 66 /* oem3 raw almanac set */ -#define ID_REPB 14 /* oem3 raw ephemeris */ -#define ID_RGEB 32 /* oem3 range measurement */ -#define ID_RGED 65 /* oem3 range compressed */ +#define ID_ALMB 18 /* oem3 decoded almanac */ +#define ID_IONB 16 /* oem3 iono parameters */ +#define ID_UTCB 17 /* oem3 utc parameters */ +#define ID_FRMB 54 /* oem3 framed raw navigation data */ +#define ID_RALB 15 /* oem3 raw almanac */ +#define ID_RASB 66 /* oem3 raw almanac set */ +#define ID_REPB 14 /* oem3 raw ephemeris */ +#define ID_RGEB 32 /* oem3 range measurement */ +#define ID_RGED 65 /* oem3 range compressed */ -#define WL1 0.1902936727984 -#define WL2 0.2442102134246 -#define MAXVAL 8388608.0 -#define OFF_FRQNO -7 /* F/W ver.3.620 */ +#define WL1 0.1902936727984 +#define WL2 0.2442102134246 +#define MAXVAL 8388608.0 +#define OFF_FRQNO -7 /* F/W ver.3.620 */ -#define SQR(x) ((x)*(x)) +#define SQR(x) ((x) * (x)) /* get fields (little-endian) ------------------------------------------------*/ #define U1(p) (*((uint8_t *)(p))) -#define I1(p) (*((int8_t *)(p))) -static uint16_t U2(uint8_t *p) {uint16_t u; memcpy(&u,p,2); return u;} -static uint32_t U4(uint8_t *p) {uint32_t u; memcpy(&u,p,4); return u;} -static int32_t I4(uint8_t *p) {int32_t i; memcpy(&i,p,4); return i;} -static float R4(uint8_t *p) {float r; memcpy(&r,p,4); return r;} -static double R8(uint8_t *p) {double r; memcpy(&r,p,8); return r;} +#define I1(p) (*((int8_t *)(p))) +static uint16_t U2(uint8_t *p) { + uint16_t u; + memcpy(&u, p, 2); + return u; +} +static uint32_t U4(uint8_t *p) { + uint32_t u; + memcpy(&u, p, 4); + return u; +} +static int32_t I4(uint8_t *p) { + int32_t i; + memcpy(&i, p, 4); + return i; +} +static float R4(uint8_t *p) { + float r; + memcpy(&r, p, 4); + return r; +} +static double R8(uint8_t *p) { + double r; + memcpy(&r, p, 8); + return r; +} /* extend sign ---------------------------------------------------------------*/ -static int32_t exsign(uint32_t v, int bits) -{ - return (int32_t)(v&(1<<(bits-1))?v|(~0u<tow_p+302400.0) tow-=604800.0; - return gpst2time(week,tow); +static gtime_t adjweek(gtime_t time, double tow) { + double tow_p; + int week; + tow_p = time2gpst(time, &week); + if (tow < tow_p - 302400.0) + tow += 604800.0; + else if (tow > tow_p + 302400.0) + tow -= 604800.0; + return gpst2time(week, tow); } /* UTC 8-bit week -> full week -----------------------------------------------*/ -static void adj_utcweek(gtime_t time, double *utc) -{ - int week; - - time2gpst(time,&week); - utc[3]+=week/256*256; - if (utc[3]week+127) utc[3]-=256.0; - utc[5]+=utc[3]/256*256; - if (utc[5]utc[3]+127) utc[5]-=256.0; +static void adj_utcweek(gtime_t time, double *utc) { + int week; + + time2gpst(time, &week); + utc[3] += week / 256 * 256; + if (utc[3] < week - 127) + utc[3] += 256.0; + else if (utc[3] > week + 127) + utc[3] -= 256.0; + utc[5] += utc[3] / 256 * 256; + if (utc[5] < utc[3] - 127) + utc[5] += 256.0; + else if (utc[5] > utc[3] + 127) + utc[5] -= 256.0; } /* get observation data index ------------------------------------------------*/ -static int obsindex(obs_t *obs, gtime_t time, int sat) -{ - int i,j; - - if (obs->n>=MAXOBS) return -1; - for (i=0;in;i++) { - if (obs->data[i].sat==sat) return i; - } - obs->data[i].time=time; - obs->data[i].sat=sat; - for (j=0;jdata[i].L[j]=obs->data[i].P[j]=0.0; - obs->data[i].D[j]=obs->data[i].SNR[j]=0.0; - obs->data[i].LLI[j]=0; - obs->data[i].code[j]=CODE_NONE; - } - obs->n++; - return i; +static int obsindex(obs_t *obs, gtime_t time, int sat) { + int i, j; + + if (obs->n >= MAXOBS) return -1; + for (i = 0; i < obs->n; i++) { + if (obs->data[i].sat == sat) return i; + } + obs->data[i].time = time; + obs->data[i].sat = sat; + for (j = 0; j < NFREQ + NEXOBS; j++) { + obs->data[i].L[j] = obs->data[i].P[j] = 0.0; + obs->data[i].D[j] = obs->data[i].SNR[j] = 0.0; + obs->data[i].LLI[j] = 0; + obs->data[i].code[j] = CODE_NONE; + } + obs->n++; + return i; } /* URA value (m) to URA index ------------------------------------------------*/ -static int uraindex(double value) -{ - static const double ura_eph[]={ - 2.4,3.4,4.85,6.85,9.65,13.65,24.0,48.0,96.0,192.0,384.0,768.0,1536.0, - 3072.0,6144.0,0.0 - }; - int i; - for (i=0;i<15;i++) if (ura_eph[i]>=value) break; - return i; +static int uraindex(double value) { + static const double ura_eph[] = {2.4, 3.4, 4.85, 6.85, 9.65, 13.65, 24.0, 48.0, + 96.0, 192.0, 384.0, 768.0, 1536.0, 3072.0, 6144.0, 0.0}; + int i; + for (i = 0; i < 15; i++) + if (ura_eph[i] >= value) break; + return i; } /* signal type to obs code ---------------------------------------------------*/ -static int sig2code(int sys, int sigtype) -{ - if (sys==SYS_GPS) { - switch (sigtype) { - case 0: return CODE_L1C; /* L1C/A */ - case 5: return CODE_L2P; /* L2P (OEM7) */ - case 9: return CODE_L2W; /* L2P(Y),semi-codeless */ - case 14: return CODE_L5Q; /* L5Q (OEM6) */ - case 16: return CODE_L1L; /* L1C(P) (OEM7) */ - case 17: return CODE_L2S; /* L2C(M) (OEM7) */ - } - } - else if (sys==SYS_GLO) { - switch (sigtype) { - case 0: return CODE_L1C; /* L1C/A */ - case 1: return CODE_L2C; /* L2C/A (OEM6) */ - case 5: return CODE_L2P; /* L2P */ - case 6: return CODE_L3Q; /* L3Q (OEM7) */ - } - } - else if (sys==SYS_GAL) { - switch (sigtype) { - case 1: return CODE_L1C; /* E1BC (Bynav M2) */ - case 2: return CODE_L1C; /* E1C (OEM6) */ - case 6: return CODE_L6B; /* E6B (OEM7) */ - case 7: return CODE_L6C; /* E6C (OEM7) */ - case 12: return CODE_L5Q; /* E5aQ (OEM6) */ - case 17: return CODE_L7Q; /* E5bQ (OEM6) */ - case 20: return CODE_L8Q; /* AltBOCQ (OEM6) */ - } - } - else if (sys==SYS_QZS) { - switch (sigtype) { - case 0: return CODE_L1C; /* L1C/A */ - case 14: return CODE_L5Q; /* L5Q (OEM6) */ - case 16: return CODE_L1L; /* L1C(P) (OEM7) */ - case 17: return CODE_L2S; /* L2C(M) (OEM7) */ - case 27: return CODE_L6L; /* L6P (OEM7) */ - } - } - else if (sys==SYS_CMP) { - switch (sigtype) { - case 0: return CODE_L2I; /* B1I with D1 (OEM6) */ - case 1: return CODE_L7I; /* B2I with D1 (OEM6) */ - case 2: return CODE_L6I; /* B3I with D1 (OEM7) */ - case 4: return CODE_L2I; /* B1I with D2 (OEM6) */ - case 5: return CODE_L7I; /* B2I with D2 (OEM6) */ - case 6: return CODE_L6I; /* B3I with D2 (OEM7) */ - case 7: return CODE_L1P; /* B1C(P) (OEM7) */ - case 9: return CODE_L5P; /* B2a(P) (OEM7) */ - case 11: return CODE_L7D; /* B2b(I) (OEM7,F/W 7.08) */ - } - } - else if (sys==SYS_IRN) { - switch (sigtype) { - case 0: return CODE_L5A; /* L5 (OEM7) */ - } - } - else if (sys==SYS_SBS) { - switch (sigtype) { - case 0: return CODE_L1C; /* L1C/A */ - case 6: return CODE_L5I; /* L5I (OEM6) */ - } - } - return 0; +static int sig2code(int sys, int sigtype) { + if (sys == SYS_GPS) { + switch (sigtype) { + case 0: + return CODE_L1C; /* L1C/A */ + case 5: + return CODE_L2P; /* L2P (OEM7) */ + case 9: + return CODE_L2W; /* L2P(Y),semi-codeless */ + case 14: + return CODE_L5Q; /* L5Q (OEM6) */ + case 16: + return CODE_L1L; /* L1C(P) (OEM7) */ + case 17: + return CODE_L2S; /* L2C(M) (OEM7) */ + } + } else if (sys == SYS_GLO) { + switch (sigtype) { + case 0: + return CODE_L1C; /* L1C/A */ + case 1: + return CODE_L2C; /* L2C/A (OEM6) */ + case 5: + return CODE_L2P; /* L2P */ + case 6: + return CODE_L3Q; /* L3Q (OEM7) */ + } + } else if (sys == SYS_GAL) { + switch (sigtype) { + case 1: + return CODE_L1C; /* E1BC (Bynav M2) */ + case 2: + return CODE_L1C; /* E1C (OEM6) */ + case 6: + return CODE_L6B; /* E6B (OEM7) */ + case 7: + return CODE_L6C; /* E6C (OEM7) */ + case 12: + return CODE_L5Q; /* E5aQ (OEM6) */ + case 17: + return CODE_L7Q; /* E5bQ (OEM6) */ + case 20: + return CODE_L8Q; /* AltBOCQ (OEM6) */ + } + } else if (sys == SYS_QZS) { + switch (sigtype) { + case 0: + return CODE_L1C; /* L1C/A */ + case 14: + return CODE_L5Q; /* L5Q (OEM6) */ + case 16: + return CODE_L1L; /* L1C(P) (OEM7) */ + case 17: + return CODE_L2S; /* L2C(M) (OEM7) */ + case 27: + return CODE_L6L; /* L6P (OEM7) */ + } + } else if (sys == SYS_CMP) { + switch (sigtype) { + case 0: + return CODE_L2I; /* B1I with D1 (OEM6) */ + case 1: + return CODE_L7I; /* B2I with D1 (OEM6) */ + case 2: + return CODE_L6I; /* B3I with D1 (OEM7) */ + case 4: + return CODE_L2I; /* B1I with D2 (OEM6) */ + case 5: + return CODE_L7I; /* B2I with D2 (OEM6) */ + case 6: + return CODE_L6I; /* B3I with D2 (OEM7) */ + case 7: + return CODE_L1P; /* B1C(P) (OEM7) */ + case 9: + return CODE_L5P; /* B2a(P) (OEM7) */ + case 11: + return CODE_L7D; /* B2b(I) (OEM7,F/W 7.08) */ + } + } else if (sys == SYS_IRN) { + switch (sigtype) { + case 0: + return CODE_L5A; /* L5 (OEM7) */ + } + } else if (sys == SYS_SBS) { + switch (sigtype) { + case 0: + return CODE_L1C; /* L1C/A */ + case 6: + return CODE_L5I; /* L5I (OEM6) */ + } + } + return 0; } /* decode receiver tracking status --------------------------------------------- -* decode receiver tracking status -* args : uint32_t stat I tracking status field -* int *sys O system (SYS_???) -* int *code O signal code (CODE_L??) -* int *track O tracking state -* (OEM4/5) -* 0=L1 idle 8=L2 idle -* 1=L1 sky search 9=L2 p-code align -* 2=L1 wide freq pull-in 10=L2 search -* 3=L1 narrow freq pull-in 11=L2 pll -* 4=L1 pll 12=L2 steering -* 5=L1 reacq -* 6=L1 steering -* 7=L1 fll -* (OEM6/7) -* 0=idle 7=freq-lock loop -* 2=wide freq band pull-in 9=channel alignment -* 3=narrow freq band pull-in 10=code search -* 4=phase lock loop 11=aided phase lock loop -* int *plock O phase-lock flag (0=not locked, 1=locked) -* int *clock O code-lock flag (0=not locked, 1=locked) -* int *parity O parity known flag (0=not known, 1=known) -* int *halfc O phase measurement (0=half-cycle not added, -* 1=added) -* return : freq-index (-1:error) -* notes : refer [1][3] -*-----------------------------------------------------------------------------*/ -static int decode_track_stat(uint32_t stat, int *sys, int *code, int *track, - int *plock, int *clock, int *parity, int *halfc) -{ - int satsys,sigtype,idx=-1; - - *code=CODE_NONE; - *track =stat&0x1F; - *plock =(stat>>10)&1; - *parity=(stat>>11)&1; - *clock =(stat>>12)&1; - satsys =(stat>>16)&7; - *halfc =(stat>>28)&1; - sigtype=(stat>>21)&0x1F; - - switch (satsys) { - case 0: *sys=SYS_GPS; break; - case 1: *sys=SYS_GLO; break; - case 2: *sys=SYS_SBS; break; - case 3: *sys=SYS_GAL; break; /* OEM6 */ - case 4: *sys=SYS_CMP; break; /* OEM6 F/W 6.400 */ - case 5: *sys=SYS_QZS; break; /* OEM6 */ - case 6: *sys=SYS_IRN; break; /* OEM7 */ - default: - trace(2,"oem4 unknown system: sys=%d\n",satsys); - return -1; - } - if (!(*code=sig2code(*sys,sigtype))||(idx=code2idx(*sys,*code))<0) { - trace(2,"oem4 signal type error: sys=%d sigtype=%d\n",*sys,sigtype); - return -1; - } - return idx; + * decode receiver tracking status + * args : uint32_t stat I tracking status field + * int *sys O system (SYS_???) + * int *code O signal code (CODE_L??) + * int *track O tracking state + * (OEM4/5) + * 0=L1 idle 8=L2 idle + * 1=L1 sky search 9=L2 p-code align + * 2=L1 wide freq pull-in 10=L2 search + * 3=L1 narrow freq pull-in 11=L2 pll + * 4=L1 pll 12=L2 steering + * 5=L1 reacq + * 6=L1 steering + * 7=L1 fll + * (OEM6/7) + * 0=idle 7=freq-lock loop + * 2=wide freq band pull-in 9=channel alignment + * 3=narrow freq band pull-in 10=code search + * 4=phase lock loop 11=aided phase lock loop + * int *plock O phase-lock flag (0=not locked, 1=locked) + * int *clock O code-lock flag (0=not locked, 1=locked) + * int *parity O parity known flag (0=not known, 1=known) + * int *halfc O phase measurement (0=half-cycle not added, + * 1=added) + * return : freq-index (-1:error) + * notes : refer [1][3] + *-----------------------------------------------------------------------------*/ +static int decode_track_stat(uint32_t stat, int *sys, int *code, int *track, int *plock, int *clock, + int *parity, int *halfc) { + int satsys, sigtype, idx = -1; + + *code = CODE_NONE; + *track = stat & 0x1F; + *plock = (stat >> 10) & 1; + *parity = (stat >> 11) & 1; + *clock = (stat >> 12) & 1; + satsys = (stat >> 16) & 7; + *halfc = (stat >> 28) & 1; + sigtype = (stat >> 21) & 0x1F; + + switch (satsys) { + case 0: + *sys = SYS_GPS; + break; + case 1: + *sys = SYS_GLO; + break; + case 2: + *sys = SYS_SBS; + break; + case 3: + *sys = SYS_GAL; + break; /* OEM6 */ + case 4: + *sys = SYS_CMP; + break; /* OEM6 F/W 6.400 */ + case 5: + *sys = SYS_QZS; + break; /* OEM6 */ + case 6: + *sys = SYS_IRN; + break; /* OEM7 */ + default: + trace(2, "oem4 unknown system: sys=%d\n", satsys); + return -1; + } + if (!(*code = sig2code(*sys, sigtype)) || (idx = code2idx(*sys, *code)) < 0) { + trace(2, "oem4 signal type error: sys=%d sigtype=%d\n", *sys, sigtype); + return -1; + } + return idx; } /* check code priority and return freq-index ---------------------------------*/ -static int checkpri(const char *opt, int sys, int code, int idx) -{ - int nex=NEXOBS; - - if (sys==SYS_GPS) { - if (strstr(opt,"-GL1L")&&idx==0) return (code==CODE_L1L)?0:-1; - if (strstr(opt,"-GL2S")&&idx==1) return (code==CODE_L2X)?1:-1; - if (strstr(opt,"-GL2P")&&idx==1) return (code==CODE_L2P)?1:-1; - if (code==CODE_L1L) return (nex<1)?-1:NFREQ; - if (code==CODE_L2S) return (nex<2)?-1:NFREQ+1; - if (code==CODE_L2P) return (nex<3)?-1:NFREQ+2; - } - else if (sys==SYS_GLO) { - if (strstr(opt,"-RL2C")&&idx==1) return (code==CODE_L2C)?1:-1; - if (code==CODE_L2C) return (nex<1)?-1:NFREQ; - } - else if (sys==SYS_GAL) { - if (strstr(opt,"-EL6B")&&idx==3) return (code==CODE_L6B)?3:-1; - if (code==CODE_L6B) return (nex<2)?-1:NFREQ; - } - else if (sys==SYS_QZS) { - if (strstr(opt,"-JL1L")&&idx==0) return (code==CODE_L1L)?0:-1; - if (strstr(opt,"-JL1Z")&&idx==0) return (code==CODE_L1Z)?0:-1; - if (code==CODE_L1L) return (nex<1)?-1:NFREQ; - if (code==CODE_L1Z) return (nex<2)?-1:NFREQ+1; - } - else if (sys==SYS_CMP) { - if (strstr(opt,"-CL1P")&&idx==0) return (code==CODE_L1P)?0:-1; - if (strstr(opt,"-CL7D")&&idx==0) return (code==CODE_L7D)?0:-1; - if (strstr(opt,"-CL6I")&&idx==1) return (code==CODE_L6I)?1:-1; - if (code==CODE_L1P) return (nex<1)?-1:NFREQ; - if (code==CODE_L7D) return (nex<2)?-1:NFREQ+1; - if (code==CODE_L6I) return (nex<3)?-1:NFREQ+2; - } - return idxbuff+OEM4HLEN; - char *q; - double psr,adr,adr_rolls,lockt,tt,dop,snr,freq,glo_bias=0.0; - int i,index,nobs,prn,sat,sys,code,idx,track,plock,clock,parity,halfc,lli; - - if ((q=strstr(raw->opt,"-GLOBIAS="))) sscanf(q,"-GLOBIAS=%lf",&glo_bias); - - nobs=U4(p); - if (raw->lenlen,nobs); - return -1; - } - if (raw->outtype) { - sprintf(raw->msgtype+strlen(raw->msgtype)," nobs=%d",nobs); - } - for (i=0,p+=4;i=MINPRNQZS_S&&prn<=MAXPRNQZS_S&&code==CODE_L1C) { - sys=SYS_QZS; - prn+=10; - code=CODE_L1Z; /* QZS L1S */ - } - if (!(sat=satno(sys,prn))) { - trace(3,"oem4 rangecmpb satellite number error: sys=%d,prn=%d\n",sys,prn); - continue; - } - if (sys==SYS_GLO&&!parity) continue; /* invalid if GLO parity unknown */ - - if ((idx=checkpri(raw->opt,sys,code,idx))<0) continue; - - dop=exsign(U4(p+4)&0xFFFFFFF,28)/256.0; - psr=(U4(p+7)>>4)/128.0+U1(p+11)*2097152.0; - - if ((freq=sat2freq(sat,(uint8_t)code,&raw->nav))!=0.0) { - adr=I4(p+12)/256.0; - adr_rolls=(psr*freq/CLIGHT+adr)/MAXVAL; - adr=-adr+MAXVAL*floor(adr_rolls+(adr_rolls<=0?-0.5:0.5)); - if (sys==SYS_GLO) adr+=glo_bias*freq/CLIGHT; - } - else { - adr=1e-9; - } - lockt=(U4(p+18)&0x1FFFFF)/32.0; /* lock time */ - - if (raw->tobs[sat-1][idx].time!=0) { - tt=timediff(raw->time,raw->tobs[sat-1][idx]); - lli=(lockt<65535.968&&lockt-raw->lockt[sat-1][idx]+0.05<=tt)?LLI_SLIP:0; - } - else { - lli=0; - } - if (!parity) lli|=LLI_HALFC; - if (halfc ) lli|=LLI_HALFA; - raw->tobs [sat-1][idx]=raw->time; - raw->lockt[sat-1][idx]=lockt; - raw->halfc[sat-1][idx]=halfc; - - snr=((U2(p+20)&0x3FF)>>5)+20.0; - if (!clock) psr=0.0; /* code unlock */ - if (!plock) adr=dop=0.0; /* phase unlock */ - - if (fabs(timediff(raw->obs.data[0].time,raw->time))>1E-9) { - raw->obs.n=0; - } - if ((index=obsindex(&raw->obs,raw->time,sat))>=0) { - raw->obs.data[index].L [idx]=adr; - raw->obs.data[index].P [idx]=psr; - raw->obs.data[index].D [idx]=(float)dop; - raw->obs.data[index].SNR[idx]=snr; - raw->obs.data[index].LLI[idx]=(uint8_t)lli; - raw->obs.data[index].code[idx]=(uint8_t)code; - } - } - return 1; +static int decode_rangecmpb(raw_t *raw) { + uint8_t *p = raw->buff + OEM4HLEN; + char *q; + double psr, adr, adr_rolls, lockt, tt, dop, snr, freq, glo_bias = 0.0; + int i, index, nobs, prn, sat, sys, code, idx, track, plock, clock, parity, halfc, lli; + + if ((q = strstr(raw->opt, "-GLOBIAS="))) sscanf(q, "-GLOBIAS=%lf", &glo_bias); + + nobs = U4(p); + if (raw->len < OEM4HLEN + 4 + nobs * 24) { + trace(2, "oem4 rangecmpb length error: len=%d nobs=%d\n", raw->len, nobs); + return -1; + } + if (raw->outtype) { + sprintf(raw->msgtype + strlen(raw->msgtype), " nobs=%d", nobs); + } + for (i = 0, p += 4; i < nobs; i++, p += 24) { + if ((idx = decode_track_stat(U4(p), &sys, &code, &track, &plock, &clock, &parity, &halfc)) < + 0) { + continue; + } + prn = U1(p + 17); + if (sys == SYS_GLO) prn -= 37; + if (sys == SYS_SBS && prn >= MINPRNQZS_S && prn <= MAXPRNQZS_S && code == CODE_L1C) { + sys = SYS_QZS; + prn += 10; + code = CODE_L1Z; /* QZS L1S */ + } + if (!(sat = satno(sys, prn))) { + trace(3, "oem4 rangecmpb satellite number error: sys=%d,prn=%d\n", sys, prn); + continue; + } + if (sys == SYS_GLO && !parity) continue; /* invalid if GLO parity unknown */ + + if ((idx = checkpri(raw->opt, sys, code, idx)) < 0) continue; + + dop = exsign(U4(p + 4) & 0xFFFFFFF, 28) / 256.0; + psr = (U4(p + 7) >> 4) / 128.0 + U1(p + 11) * 2097152.0; + + if ((freq = sat2freq(sat, (uint8_t)code, &raw->nav)) != 0.0) { + adr = I4(p + 12) / 256.0; + adr_rolls = (psr * freq / CLIGHT + adr) / MAXVAL; + adr = -adr + MAXVAL * floor(adr_rolls + (adr_rolls <= 0 ? -0.5 : 0.5)); + if (sys == SYS_GLO) adr += glo_bias * freq / CLIGHT; + } else { + adr = 1e-9; + } + lockt = (U4(p + 18) & 0x1FFFFF) / 32.0; /* lock time */ + + if (raw->tobs[sat - 1][idx].time != 0) { + tt = timediff(raw->time, raw->tobs[sat - 1][idx]); + lli = (lockt < 65535.968 && lockt - raw->lockt[sat - 1][idx] + 0.05 <= tt) ? LLI_SLIP : 0; + } else { + lli = 0; + } + if (!parity) lli |= LLI_HALFC; + if (halfc) lli |= LLI_HALFA; + raw->tobs[sat - 1][idx] = raw->time; + raw->lockt[sat - 1][idx] = lockt; + raw->halfc[sat - 1][idx] = halfc; + + snr = ((U2(p + 20) & 0x3FF) >> 5) + 20.0; + if (!clock) psr = 0.0; /* code unlock */ + if (!plock) adr = dop = 0.0; /* phase unlock */ + + if (fabs(timediff(raw->obs.data[0].time, raw->time)) > 1E-9) { + raw->obs.n = 0; + } + if ((index = obsindex(&raw->obs, raw->time, sat)) >= 0) { + raw->obs.data[index].L[idx] = adr; + raw->obs.data[index].P[idx] = psr; + raw->obs.data[index].D[idx] = (float)dop; + raw->obs.data[index].SNR[idx] = snr; + raw->obs.data[index].LLI[idx] = (uint8_t)lli; + raw->obs.data[index].code[idx] = (uint8_t)code; + } + } + return 1; } /* decode RANGEB -------------------------------------------------------------*/ -static int decode_rangeb(raw_t *raw) -{ - uint8_t *p=raw->buff+OEM4HLEN; - char *q; - double psr,adr,dop,snr,lockt,tt,freq,glo_bias=0.0; - int i,index,nobs,prn,sat,sys,code,idx,track,plock,clock,parity,halfc,lli; - int gfrq; - - if ((q=strstr(raw->opt,"-GLOBIAS="))) sscanf(q,"-GLOBIAS=%lf",&glo_bias); - - nobs=U4(p); - if (raw->lenlen,nobs); - return -1; - } - if (raw->outtype) { - sprintf(raw->msgtype+strlen(raw->msgtype)," nobs=%d",nobs); - } - for (i=0,p+=4;i=MINPRNQZS_S&&prn<=MAXPRNQZS_S&&code==CODE_L1C) { - sys=SYS_QZS; - prn+=10; - code=CODE_L1Z; /* QZS L1S */ - } - if (!(sat=satno(sys,prn))) { - trace(3,"oem4 rangeb satellite number error: sys=%d,prn=%d\n",sys,prn); - continue; - } - if (sys==SYS_GLO&&!parity) continue; - - if ((idx=checkpri(raw->opt,sys,code,idx))<0) continue; - - gfrq =U2(p+ 2); /* GLONASS FCN+8 */ - psr =R8(p+ 4); - adr =R8(p+16); - dop =R4(p+28); - snr =R4(p+32); - lockt=R4(p+36); - - if (sys==SYS_GLO) { - freq=sat2freq(sat,(uint8_t)code,&raw->nav); - adr-=glo_bias*freq/CLIGHT; - if (!raw->nav.glo_fcn[prn-1]) { - raw->nav.glo_fcn[prn-1]=gfrq; /* fcn+8 */ - } - } - if (raw->tobs[sat-1][idx].time!=0) { - tt=timediff(raw->time,raw->tobs[sat-1][idx]); - lli=lockt-raw->lockt[sat-1][idx]+0.05<=tt?LLI_SLIP:0; - } - else { - lli=0; - } - if (!parity) lli|=LLI_HALFC; - if (halfc ) lli|=LLI_HALFA; - raw->tobs [sat-1][idx]=raw->time; - raw->lockt[sat-1][idx]=lockt; - raw->halfc[sat-1][idx]=halfc; - - if (!clock) psr=0.0; /* code unlock */ - if (!plock) adr=dop=0.0; /* phase unlock */ - - if (fabs(timediff(raw->obs.data[0].time,raw->time))>1E-9) { - raw->obs.n=0; - } - if ((index=obsindex(&raw->obs,raw->time,sat))>=0) { - raw->obs.data[index].L [idx]=-adr; - raw->obs.data[index].P [idx]=psr; - raw->obs.data[index].D [idx]=(float)dop; - raw->obs.data[index].SNR[idx]=snr; - raw->obs.data[index].LLI[idx]=(uint8_t)lli; - raw->obs.data[index].code[idx]=(uint8_t)code; - } - } - return 1; +static int decode_rangeb(raw_t *raw) { + uint8_t *p = raw->buff + OEM4HLEN; + char *q; + double psr, adr, dop, snr, lockt, tt, freq, glo_bias = 0.0; + int i, index, nobs, prn, sat, sys, code, idx, track, plock, clock, parity, halfc, lli; + int gfrq; + + if ((q = strstr(raw->opt, "-GLOBIAS="))) sscanf(q, "-GLOBIAS=%lf", &glo_bias); + + nobs = U4(p); + if (raw->len < OEM4HLEN + 4 + nobs * 44) { + trace(2, "oem4 rangeb length error: len=%d nobs=%d\n", raw->len, nobs); + return -1; + } + if (raw->outtype) { + sprintf(raw->msgtype + strlen(raw->msgtype), " nobs=%d", nobs); + } + for (i = 0, p += 4; i < nobs; i++, p += 44) { + if ((idx = decode_track_stat(U4(p + 40), &sys, &code, &track, &plock, &clock, &parity, + &halfc)) < 0) { + continue; + } + prn = U2(p); + if (sys == SYS_GLO) prn -= 37; + if (sys == SYS_SBS && prn >= MINPRNQZS_S && prn <= MAXPRNQZS_S && code == CODE_L1C) { + sys = SYS_QZS; + prn += 10; + code = CODE_L1Z; /* QZS L1S */ + } + if (!(sat = satno(sys, prn))) { + trace(3, "oem4 rangeb satellite number error: sys=%d,prn=%d\n", sys, prn); + continue; + } + if (sys == SYS_GLO && !parity) continue; + + if ((idx = checkpri(raw->opt, sys, code, idx)) < 0) continue; + + gfrq = U2(p + 2); /* GLONASS FCN+8 */ + psr = R8(p + 4); + adr = R8(p + 16); + dop = R4(p + 28); + snr = R4(p + 32); + lockt = R4(p + 36); + + if (sys == SYS_GLO) { + freq = sat2freq(sat, (uint8_t)code, &raw->nav); + adr -= glo_bias * freq / CLIGHT; + if (!raw->nav.glo_fcn[prn - 1]) { + raw->nav.glo_fcn[prn - 1] = gfrq; /* fcn+8 */ + } + } + if (raw->tobs[sat - 1][idx].time != 0) { + tt = timediff(raw->time, raw->tobs[sat - 1][idx]); + lli = lockt - raw->lockt[sat - 1][idx] + 0.05 <= tt ? LLI_SLIP : 0; + } else { + lli = 0; + } + if (!parity) lli |= LLI_HALFC; + if (halfc) lli |= LLI_HALFA; + raw->tobs[sat - 1][idx] = raw->time; + raw->lockt[sat - 1][idx] = lockt; + raw->halfc[sat - 1][idx] = halfc; + + if (!clock) psr = 0.0; /* code unlock */ + if (!plock) adr = dop = 0.0; /* phase unlock */ + + if (fabs(timediff(raw->obs.data[0].time, raw->time)) > 1E-9) { + raw->obs.n = 0; + } + if ((index = obsindex(&raw->obs, raw->time, sat)) >= 0) { + raw->obs.data[index].L[idx] = -adr; + raw->obs.data[index].P[idx] = psr; + raw->obs.data[index].D[idx] = (float)dop; + raw->obs.data[index].SNR[idx] = snr; + raw->obs.data[index].LLI[idx] = (uint8_t)lli; + raw->obs.data[index].code[idx] = (uint8_t)code; + } + } + return 1; } /* decode RAWEPHEMB ----------------------------------------------------------*/ -static int decode_rawephemb(raw_t *raw) -{ - eph_t eph={0}; - uint8_t *p=raw->buff+OEM4HLEN,subframe[30*5]={0}; - int prn,sat; - - if (raw->lenlen); - return -1; - } - prn=U4(p); - if (!(sat=satno(SYS_GPS,prn))) { - trace(2,"oem4 rawephemb satellite number error: prn=%d\n",prn); - return -1; - } - if (raw->outtype) { - sprintf(raw->msgtype+strlen(raw->msgtype)," prn=%d",prn); - } - memcpy(subframe,p+12,30*3); /* subframe 1-3 */ - - if (!decode_frame(subframe,SYS_GPS,&eph,NULL,NULL,NULL)) { - trace(2,"oem4 rawephemb subframe error: prn=%d\n",prn); - return -1; - } - if (!strstr(raw->opt,"-EPHALL")) { - if (eph.iode==raw->nav.eph[sat-1].iode&& - eph.iodc==raw->nav.eph[sat-1].iodc) return 0; - } - eph.sat=sat; - raw->nav.eph[sat-1]=eph; - raw->ephsat=sat; - raw->ephset=0; - return 2; +static int decode_rawephemb(raw_t *raw) { + eph_t eph = {0}; + uint8_t *p = raw->buff + OEM4HLEN, subframe[30 * 5] = {0}; + int prn, sat; + + if (raw->len < OEM4HLEN + 102) { + trace(2, "oem4 rawephemb length error: len=%d\n", raw->len); + return -1; + } + prn = U4(p); + if (!(sat = satno(SYS_GPS, prn))) { + trace(2, "oem4 rawephemb satellite number error: prn=%d\n", prn); + return -1; + } + if (raw->outtype) { + sprintf(raw->msgtype + strlen(raw->msgtype), " prn=%d", prn); + } + memcpy(subframe, p + 12, 30 * 3); /* subframe 1-3 */ + + if (!decode_frame(subframe, SYS_GPS, &eph, NULL, NULL, NULL)) { + trace(2, "oem4 rawephemb subframe error: prn=%d\n", prn); + return -1; + } + if (!strstr(raw->opt, "-EPHALL")) { + if (eph.iode == raw->nav.eph[sat - 1].iode && eph.iodc == raw->nav.eph[sat - 1].iodc) return 0; + } + eph.sat = sat; + raw->nav.eph[sat - 1] = eph; + raw->ephsat = sat; + raw->ephset = 0; + return 2; } /* decode IONUTCB ------------------------------------------------------------*/ -static int decode_ionutcb(raw_t *raw) -{ - uint8_t *p=raw->buff+OEM4HLEN; - int i; - - if (raw->lenlen); - return -1; - } - for (i=0;i<8;i++) raw->nav.ion_gps[i]=R8(p+i*8); - raw->nav.utc_gps[0]=R8(p+ 72); /* A0 */ - raw->nav.utc_gps[1]=R8(p+ 80); /* A1 */ - raw->nav.utc_gps[2]=U4(p+ 68); /* tot */ - raw->nav.utc_gps[3]=U4(p+ 64); /* WNt */ - raw->nav.utc_gps[4]=I4(p+ 96); /* dt_LS */ - raw->nav.utc_gps[5]=U4(p+ 88); /* WN_LSF */ - raw->nav.utc_gps[6]=U4(p+ 92); /* DN */ - raw->nav.utc_gps[7]=I4(p+100); /* dt_LSF */ - return 9; +static int decode_ionutcb(raw_t *raw) { + uint8_t *p = raw->buff + OEM4HLEN; + int i; + + if (raw->len < OEM4HLEN + 108) { + trace(2, "oem4 ionutcb length error: len=%d\n", raw->len); + return -1; + } + for (i = 0; i < 8; i++) raw->nav.ion_gps[i] = R8(p + i * 8); + raw->nav.utc_gps[0] = R8(p + 72); /* A0 */ + raw->nav.utc_gps[1] = R8(p + 80); /* A1 */ + raw->nav.utc_gps[2] = U4(p + 68); /* tot */ + raw->nav.utc_gps[3] = U4(p + 64); /* WNt */ + raw->nav.utc_gps[4] = I4(p + 96); /* dt_LS */ + raw->nav.utc_gps[5] = U4(p + 88); /* WN_LSF */ + raw->nav.utc_gps[6] = U4(p + 92); /* DN */ + raw->nav.utc_gps[7] = I4(p + 100); /* dt_LSF */ + return 9; } /* decode RAWWAASFRAMEB ------------------------------------------------------*/ -static int decode_rawwaasframeb(raw_t *raw) -{ - uint8_t *p=raw->buff+OEM4HLEN; - int prn; - - if (raw->lenlen); - return -1; - } - prn=U4(p+4); - if ((prnMAXPRNSBS)&&(prnMAXPRNQZS_S)) { - return 0; - } - if (raw->outtype) { - sprintf(raw->msgtype+strlen(raw->msgtype)," prn=%d",prn); - } - raw->sbsmsg.tow=(int)time2gpst(raw->time,&raw->sbsmsg.week); - raw->sbsmsg.prn=prn; - memcpy(raw->sbsmsg.msg,p+12,29); - raw->sbsmsg.msg[28]&=0xC0; - return 3; +static int decode_rawwaasframeb(raw_t *raw) { + uint8_t *p = raw->buff + OEM4HLEN; + int prn; + + if (raw->len < OEM4HLEN + 48) { + trace(2, "oem4 rawwaasframeb length error: len=%d\n", raw->len); + return -1; + } + prn = U4(p + 4); + if ((prn < MINPRNSBS || prn > MAXPRNSBS) && (prn < MINPRNQZS_S || prn > MAXPRNQZS_S)) { + return 0; + } + if (raw->outtype) { + sprintf(raw->msgtype + strlen(raw->msgtype), " prn=%d", prn); + } + raw->sbsmsg.tow = (int)time2gpst(raw->time, &raw->sbsmsg.week); + raw->sbsmsg.prn = prn; + memcpy(raw->sbsmsg.msg, p + 12, 29); + raw->sbsmsg.msg[28] &= 0xC0; + return 3; } /* decode RAWSBASFRAMEB ------------------------------------------------------*/ -static int decode_rawsbasframeb(raw_t *raw) -{ - return decode_rawwaasframeb(raw); -} +static int decode_rawsbasframeb(raw_t *raw) { return decode_rawwaasframeb(raw); } /* decode GLOEPHEMERISB ------------------------------------------------------*/ -static int decode_gloephemerisb(raw_t *raw) -{ - uint8_t *p=raw->buff+OEM4HLEN; - geph_t geph={0}; - double tow,tof,toff; - int prn,sat,week; - - if (raw->lenlen); - return -1; - } - prn=U2(p)-37; - - if (!(sat=satno(SYS_GLO,prn))) { - trace(2,"oem4 gloephemerisb prn error: prn=%d\n",prn); - return -1; - } - if (raw->outtype) { - sprintf(raw->msgtype+strlen(raw->msgtype)," prn=%d",prn); - } - geph.frq =U2(p+ 2)+OFF_FRQNO; - week =U2(p+ 6); - tow =floor(U4(p+8)/1000.0+0.5); /* rounded to integer sec */ - toff =U4(p+ 12); - geph.iode =U4(p+ 20)&0x7F; - geph.svh =(U4(p+24)<4)?0:1; /* 0:healthy,1:unhealthy */ - geph.pos[0]=R8(p+ 28); - geph.pos[1]=R8(p+ 36); - geph.pos[2]=R8(p+ 44); - geph.vel[0]=R8(p+ 52); - geph.vel[1]=R8(p+ 60); - geph.vel[2]=R8(p+ 68); - geph.acc[0]=R8(p+ 76); - geph.acc[1]=R8(p+ 84); - geph.acc[2]=R8(p+ 92); - geph.taun =R8(p+100); - geph.dtaun =R8(p+108); - geph.gamn =R8(p+116); - tof =U4(p+124)-toff; /* glonasst->gpst */ - geph.age =U4(p+136); - geph.toe=gpst2time(week,tow); - tof+=floor(tow/86400.0)*86400; - if (toftow+43200.0) tof-=86400.0; - geph.tof=gpst2time(week,tof); - - if (!strstr(raw->opt,"-EPHALL")) { - if (fabs(timediff(geph.toe,raw->nav.geph[prn-1].toe))<1.0&& - geph.svh==raw->nav.geph[prn-1].svh) return 0; /* unchanged */ - } - geph.sat=sat; - raw->nav.geph[prn-1]=geph; - raw->ephsat=sat; - raw->ephset=0; - return 2; +static int decode_gloephemerisb(raw_t *raw) { + uint8_t *p = raw->buff + OEM4HLEN; + geph_t geph = {0}; + double tow, tof, toff; + int prn, sat, week; + + if (raw->len < OEM4HLEN + 144) { + trace(2, "oem4 gloephemerisb length error: len=%d\n", raw->len); + return -1; + } + prn = U2(p) - 37; + + if (!(sat = satno(SYS_GLO, prn))) { + trace(2, "oem4 gloephemerisb prn error: prn=%d\n", prn); + return -1; + } + if (raw->outtype) { + sprintf(raw->msgtype + strlen(raw->msgtype), " prn=%d", prn); + } + geph.frq = U2(p + 2) + OFF_FRQNO; + week = U2(p + 6); + tow = floor(U4(p + 8) / 1000.0 + 0.5); /* rounded to integer sec */ + toff = U4(p + 12); + geph.iode = U4(p + 20) & 0x7F; + geph.svh = (U4(p + 24) < 4) ? 0 : 1; /* 0:healthy,1:unhealthy */ + geph.pos[0] = R8(p + 28); + geph.pos[1] = R8(p + 36); + geph.pos[2] = R8(p + 44); + geph.vel[0] = R8(p + 52); + geph.vel[1] = R8(p + 60); + geph.vel[2] = R8(p + 68); + geph.acc[0] = R8(p + 76); + geph.acc[1] = R8(p + 84); + geph.acc[2] = R8(p + 92); + geph.taun = R8(p + 100); + geph.dtaun = R8(p + 108); + geph.gamn = R8(p + 116); + tof = U4(p + 124) - toff; /* glonasst->gpst */ + geph.age = U4(p + 136); + geph.toe = gpst2time(week, tow); + tof += floor(tow / 86400.0) * 86400; + if (tof < tow - 43200.0) + tof += 86400.0; + else if (tof > tow + 43200.0) + tof -= 86400.0; + geph.tof = gpst2time(week, tof); + + if (!strstr(raw->opt, "-EPHALL")) { + if (fabs(timediff(geph.toe, raw->nav.geph[prn - 1].toe)) < 1.0 && + geph.svh == raw->nav.geph[prn - 1].svh) + return 0; /* unchanged */ + } + geph.sat = sat; + raw->nav.geph[prn - 1] = geph; + raw->ephsat = sat; + raw->ephset = 0; + return 2; } /* decode QZSSRAWEPHEMB ------------------------------------------------------*/ -static int decode_qzssrawephemb(raw_t *raw) -{ - eph_t eph={0}; - uint8_t *p=raw->buff+OEM4HLEN,subfrm[90]; - int prn,sat; - - if (raw->lenlen); - return -1; - } - prn=U4(p); - if (!(sat=satno(SYS_QZS,prn))) { - trace(2,"oem4 qzssrawephemb satellite number error: prn=%d\n",prn); - return -1; - } - if (raw->outtype) { - sprintf(raw->msgtype+strlen(raw->msgtype)," prn=%d",prn); - } - memcpy(subfrm,p+12,90); - - if (!decode_frame(subfrm,SYS_QZS,&eph,NULL,NULL,NULL)) { - trace(3,"oem4 qzssrawephemb ephemeris error: prn=%d\n",prn); - return 0; - } - if (!strstr(raw->opt,"-EPHALL")) { - if (eph.iodc==raw->nav.eph[sat-1].iodc&& - eph.iode==raw->nav.eph[sat-1].iode) return 0; /* unchanged */ - } - eph.sat=sat; - raw->nav.eph[sat-1]=eph; - raw->ephsat=sat; - raw->ephset=0; - return 2; +static int decode_qzssrawephemb(raw_t *raw) { + eph_t eph = {0}; + uint8_t *p = raw->buff + OEM4HLEN, subfrm[90]; + int prn, sat; + + if (raw->len < OEM4HLEN + 106) { + trace(2, "oem4 qzssrawephemb length error: len=%d\n", raw->len); + return -1; + } + prn = U4(p); + if (!(sat = satno(SYS_QZS, prn))) { + trace(2, "oem4 qzssrawephemb satellite number error: prn=%d\n", prn); + return -1; + } + if (raw->outtype) { + sprintf(raw->msgtype + strlen(raw->msgtype), " prn=%d", prn); + } + memcpy(subfrm, p + 12, 90); + + if (!decode_frame(subfrm, SYS_QZS, &eph, NULL, NULL, NULL)) { + trace(3, "oem4 qzssrawephemb ephemeris error: prn=%d\n", prn); + return 0; + } + if (!strstr(raw->opt, "-EPHALL")) { + if (eph.iodc == raw->nav.eph[sat - 1].iodc && eph.iode == raw->nav.eph[sat - 1].iode) + return 0; /* unchanged */ + } + eph.sat = sat; + raw->nav.eph[sat - 1] = eph; + raw->ephsat = sat; + raw->ephset = 0; + return 2; } /* decode QZSSRAWSUBFRAMEB ---------------------------------------------------*/ -static int decode_qzssrawsubframeb(raw_t *raw) -{ - eph_t eph={0}; - double ion[8],utc[8]; - uint8_t *p=raw->buff+OEM4HLEN; - int prn,sat,id; - - if (raw->lenlen); - return -1; - } - prn=U4(p); - id =U4(p+4); - if (!(sat=satno(SYS_QZS,prn))) { - trace(2,"oem4 qzssrawsubframeb satellite error: prn=%d\n",prn); - return -1; - } - if (raw->outtype) { - sprintf(raw->msgtype+strlen(raw->msgtype)," prn=%d id=%d",prn,id); - } - if (id<1||id>5) { - trace(2,"oem4 qzssrawsubframeb subfrm id error: prn=%d id=%d\n",prn,id); - return -1; - } - memcpy(raw->subfrm[sat-1]+30*(id-1),p+8,30); - - if (id==3) { - if (!decode_frame(raw->subfrm[sat-1],SYS_QZS,&eph,NULL,NULL,NULL)) return 0; - if (!strstr(raw->opt,"-EPHALL")) { - if (eph.iodc==raw->nav.eph[sat-1].iodc&& - eph.iode==raw->nav.eph[sat-1].iode) return 0; /* unchanged */ - } - eph.sat=sat; - raw->nav.eph[sat-1]=eph; - raw->ephsat=sat; - raw->ephset=0; - return 2; - } - else if (id==4||id==5) { - if (!decode_frame(raw->subfrm[sat-1],SYS_QZS,NULL,NULL,ion,utc)) return 0; - adj_utcweek(raw->time,utc); - matcpy(raw->nav.ion_qzs,ion,8,1); - matcpy(raw->nav.utc_qzs,utc,8,1); - return 9; - } - return 0; +static int decode_qzssrawsubframeb(raw_t *raw) { + eph_t eph = {0}; + double ion[8], utc[8]; + uint8_t *p = raw->buff + OEM4HLEN; + int prn, sat, id; + + if (raw->len < OEM4HLEN + 44) { + trace(2, "oem4 qzssrawsubframeb length error: len=%d\n", raw->len); + return -1; + } + prn = U4(p); + id = U4(p + 4); + if (!(sat = satno(SYS_QZS, prn))) { + trace(2, "oem4 qzssrawsubframeb satellite error: prn=%d\n", prn); + return -1; + } + if (raw->outtype) { + sprintf(raw->msgtype + strlen(raw->msgtype), " prn=%d id=%d", prn, id); + } + if (id < 1 || id > 5) { + trace(2, "oem4 qzssrawsubframeb subfrm id error: prn=%d id=%d\n", prn, id); + return -1; + } + memcpy(raw->subfrm[sat - 1] + 30 * (id - 1), p + 8, 30); + + if (id == 3) { + if (!decode_frame(raw->subfrm[sat - 1], SYS_QZS, &eph, NULL, NULL, NULL)) return 0; + if (!strstr(raw->opt, "-EPHALL")) { + if (eph.iodc == raw->nav.eph[sat - 1].iodc && eph.iode == raw->nav.eph[sat - 1].iode) + return 0; /* unchanged */ + } + eph.sat = sat; + raw->nav.eph[sat - 1] = eph; + raw->ephsat = sat; + raw->ephset = 0; + return 2; + } else if (id == 4 || id == 5) { + if (!decode_frame(raw->subfrm[sat - 1], SYS_QZS, NULL, NULL, ion, utc)) return 0; + adj_utcweek(raw->time, utc); + matcpy(raw->nav.ion_qzs, ion, 8, 1); + matcpy(raw->nav.utc_qzs, utc, 8, 1); + return 9; + } + return 0; } /* decode QZSSIONUTCB --------------------------------------------------------*/ -static int decode_qzssionutcb(raw_t *raw) -{ - uint8_t *p=raw->buff+OEM4HLEN; - int i; - - if (raw->lenlen); - return -1; - } - for (i=0;i<8;i++) raw->nav.ion_qzs[i]=R8(p+i*8); - raw->nav.utc_qzs[0]=R8(p+72); - raw->nav.utc_qzs[1]=R8(p+80); - raw->nav.utc_qzs[2]=U4(p+68); - raw->nav.utc_qzs[3]=U4(p+64); - raw->nav.utc_qzs[4]=I4(p+96); - return 9; +static int decode_qzssionutcb(raw_t *raw) { + uint8_t *p = raw->buff + OEM4HLEN; + int i; + + if (raw->len < OEM4HLEN + 108) { + trace(2, "oem4 qzssionutcb length error: len=%d\n", raw->len); + return -1; + } + for (i = 0; i < 8; i++) raw->nav.ion_qzs[i] = R8(p + i * 8); + raw->nav.utc_qzs[0] = R8(p + 72); + raw->nav.utc_qzs[1] = R8(p + 80); + raw->nav.utc_qzs[2] = U4(p + 68); + raw->nav.utc_qzs[3] = U4(p + 64); + raw->nav.utc_qzs[4] = I4(p + 96); + return 9; } /* decode GALEPHEMERISB ------------------------------------------------------*/ -static int decode_galephemerisb(raw_t *raw) -{ - eph_t eph={0}; - uint8_t *p=raw->buff+OEM4HLEN; - double tow,sqrtA,af0_fnav,af1_fnav,af2_fnav,af0_inav,af1_inav,af2_inav,tt; - int prn,sat,week,rcv_fnav,rcv_inav,svh_e1b,svh_e5a,svh_e5b,dvs_e1b,dvs_e5a; - int dvs_e5b,toc_fnav,toc_inav,set,sel_eph=3; /* 1:I/NAV+2:F/NAV */ - - if (strstr(raw->opt,"-GALINAV")) sel_eph=1; - if (strstr(raw->opt,"-GALFNAV")) sel_eph=2; - - if (raw->lenlen); - return -1; - } - prn =U4(p); p+=4; - rcv_fnav =U4(p)&1; p+=4; - rcv_inav =U4(p)&1; p+=4; - svh_e1b =U1(p)&3; p+=1; - svh_e5a =U1(p)&3; p+=1; - svh_e5b =U1(p)&3; p+=1; - dvs_e1b =U1(p)&1; p+=1; - dvs_e5a =U1(p)&1; p+=1; - dvs_e5b =U1(p)&1; p+=1; - eph.sva =U1(p); p+=1+1; /* SISA index */ - eph.iode =U4(p); p+=4; /* IODNav */ - eph.toes =U4(p); p+=4; - sqrtA =R8(p); p+=8; - eph.deln =R8(p); p+=8; - eph.M0 =R8(p); p+=8; - eph.e =R8(p); p+=8; - eph.omg =R8(p); p+=8; - eph.cuc =R8(p); p+=8; - eph.cus =R8(p); p+=8; - eph.crc =R8(p); p+=8; - eph.crs =R8(p); p+=8; - eph.cic =R8(p); p+=8; - eph.cis =R8(p); p+=8; - eph.i0 =R8(p); p+=8; - eph.idot =R8(p); p+=8; - eph.OMG0 =R8(p); p+=8; - eph.OMGd =R8(p); p+=8; - toc_fnav =U4(p); p+=4; - af0_fnav =R8(p); p+=8; - af1_fnav =R8(p); p+=8; - af2_fnav =R8(p); p+=8; - toc_inav =U4(p); p+=4; - af0_inav =R8(p); p+=8; - af1_inav =R8(p); p+=8; - af2_inav =R8(p); p+=8; - eph.tgd[0]=R8(p); p+=8; /* BGD: E5A-E1 (s) */ - eph.tgd[1]=R8(p); /* BGD: E5B-E1 (s) */ - - if (!(sat=satno(SYS_GAL,prn))) { - trace(2,"oemv galephemeris satellite error: prn=%d\n",prn); - return -1; - } - if (raw->outtype) { - sprintf(raw->msgtype+strlen(raw->msgtype)," prn=%d",prn); - } - set=rcv_fnav?1:0; /* 0:I/NAV,1:F/NAV */ - if (!(sel_eph&1)&&set==0) return 0; - if (!(sel_eph&2)&&set==1) return 0; - - eph.sat =sat; - eph.A =SQR(sqrtA); - eph.f0 =set?af0_fnav:af0_inav; - eph.f1 =set?af1_fnav:af1_inav; - eph.f2 =set?af2_fnav:af2_inav; - eph.svh =((svh_e5b<<7)|(dvs_e5b<<6)|(svh_e5a<<4)|(dvs_e5a<<3)| - (svh_e1b<<1)|dvs_e1b); - eph.code=set?((1<<1)+(1<<8)):((1<<0)+(1<<2)+(1<<9)); - eph.iodc=eph.iode; - tow=time2gpst(raw->time,&week); - eph.week=week; /* gps-week = gal-week */ - eph.toe=gpst2time(eph.week,eph.toes); - - tt=timediff(eph.toe,raw->time); - if (tt<-302400.0) eph.week++; - else if (tt> 302400.0) eph.week--; - eph.toe=gpst2time(eph.week,eph.toes); - eph.toc=adjweek(raw->time,set?toc_fnav:toc_inav); - eph.ttr=raw->time; - - if (!strstr(raw->opt,"-EPHALL")) { - if (eph.iode==raw->nav.eph[sat-1+MAXSAT*set].iode&& - fabs(timediff(eph.toe,raw->nav.eph[sat-1+MAXSAT*set].toe)) < 1e-9 && - fabs(timediff(eph.toc,raw->nav.eph[sat-1+MAXSAT*set].toc)) < 1e-9) { - return 0; /* unchanged */ - } - } - raw->nav.eph[sat-1+MAXSAT*set]=eph; - raw->ephsat=sat; - raw->ephset=set; - return 2; +static int decode_galephemerisb(raw_t *raw) { + eph_t eph = {0}; + uint8_t *p = raw->buff + OEM4HLEN; + double tow, sqrtA, af0_fnav, af1_fnav, af2_fnav, af0_inav, af1_inav, af2_inav, tt; + int prn, sat, week, rcv_fnav, rcv_inav, svh_e1b, svh_e5a, svh_e5b, dvs_e1b, dvs_e5a; + int dvs_e5b, toc_fnav, toc_inav, set, sel_eph = 3; /* 1:I/NAV+2:F/NAV */ + + if (strstr(raw->opt, "-GALINAV")) sel_eph = 1; + if (strstr(raw->opt, "-GALFNAV")) sel_eph = 2; + + if (raw->len < OEM4HLEN + 220) { + trace(2, "oem4 galephemrisb length error: len=%d\n", raw->len); + return -1; + } + prn = U4(p); + p += 4; + rcv_fnav = U4(p) & 1; + p += 4; + rcv_inav = U4(p) & 1; + p += 4; + svh_e1b = U1(p) & 3; + p += 1; + svh_e5a = U1(p) & 3; + p += 1; + svh_e5b = U1(p) & 3; + p += 1; + dvs_e1b = U1(p) & 1; + p += 1; + dvs_e5a = U1(p) & 1; + p += 1; + dvs_e5b = U1(p) & 1; + p += 1; + eph.sva = U1(p); + p += 1 + 1; /* SISA index */ + eph.iode = U4(p); + p += 4; /* IODNav */ + eph.toes = U4(p); + p += 4; + sqrtA = R8(p); + p += 8; + eph.deln = R8(p); + p += 8; + eph.M0 = R8(p); + p += 8; + eph.e = R8(p); + p += 8; + eph.omg = R8(p); + p += 8; + eph.cuc = R8(p); + p += 8; + eph.cus = R8(p); + p += 8; + eph.crc = R8(p); + p += 8; + eph.crs = R8(p); + p += 8; + eph.cic = R8(p); + p += 8; + eph.cis = R8(p); + p += 8; + eph.i0 = R8(p); + p += 8; + eph.idot = R8(p); + p += 8; + eph.OMG0 = R8(p); + p += 8; + eph.OMGd = R8(p); + p += 8; + toc_fnav = U4(p); + p += 4; + af0_fnav = R8(p); + p += 8; + af1_fnav = R8(p); + p += 8; + af2_fnav = R8(p); + p += 8; + toc_inav = U4(p); + p += 4; + af0_inav = R8(p); + p += 8; + af1_inav = R8(p); + p += 8; + af2_inav = R8(p); + p += 8; + eph.tgd[0] = R8(p); + p += 8; /* BGD: E5A-E1 (s) */ + eph.tgd[1] = R8(p); /* BGD: E5B-E1 (s) */ + + if (!(sat = satno(SYS_GAL, prn))) { + trace(2, "oemv galephemeris satellite error: prn=%d\n", prn); + return -1; + } + if (raw->outtype) { + sprintf(raw->msgtype + strlen(raw->msgtype), " prn=%d", prn); + } + set = rcv_fnav ? 1 : 0; /* 0:I/NAV,1:F/NAV */ + if (!(sel_eph & 1) && set == 0) return 0; + if (!(sel_eph & 2) && set == 1) return 0; + + eph.sat = sat; + eph.A = SQR(sqrtA); + eph.f0 = set ? af0_fnav : af0_inav; + eph.f1 = set ? af1_fnav : af1_inav; + eph.f2 = set ? af2_fnav : af2_inav; + eph.svh = ((svh_e5b << 7) | (dvs_e5b << 6) | (svh_e5a << 4) | (dvs_e5a << 3) | (svh_e1b << 1) | + dvs_e1b); + eph.code = set ? ((1 << 1) + (1 << 8)) : ((1 << 0) + (1 << 2) + (1 << 9)); + eph.iodc = eph.iode; + tow = time2gpst(raw->time, &week); + eph.week = week; /* gps-week = gal-week */ + eph.toe = gpst2time(eph.week, eph.toes); + + tt = timediff(eph.toe, raw->time); + if (tt < -302400.0) + eph.week++; + else if (tt > 302400.0) + eph.week--; + eph.toe = gpst2time(eph.week, eph.toes); + eph.toc = adjweek(raw->time, set ? toc_fnav : toc_inav); + eph.ttr = raw->time; + + if (!strstr(raw->opt, "-EPHALL")) { + if (eph.iode == raw->nav.eph[sat - 1 + MAXSAT * set].iode && + fabs(timediff(eph.toe, raw->nav.eph[sat - 1 + MAXSAT * set].toe)) < 1e-9 && + fabs(timediff(eph.toc, raw->nav.eph[sat - 1 + MAXSAT * set].toc)) < 1e-9) { + return 0; /* unchanged */ + } + } + raw->nav.eph[sat - 1 + MAXSAT * set] = eph; + raw->ephsat = sat; + raw->ephset = set; + return 2; } /* decode GALCLOCKB ----------------------------------------------------------*/ -static int decode_galclockb(raw_t *raw) -{ - uint8_t *p=raw->buff+OEM4HLEN; - double a0,a1,a0g,a1g; - int dtls,tot,wnt,wnlsf,dn,dtlsf,t0g,wn0g; - - if (raw->lenlen); - return -1; - } - a0 =R8(p); p+=8; - a1 =R8(p); p+=8; - dtls =I4(p); p+=4; - tot =U4(p); p+=4; - wnt =U4(p); p+=4; - wnlsf=U4(p); p+=4; - dn =U4(p); p+=4; - dtlsf=U4(p); p+=4; - a0g =R8(p); p+=8; - a1g =R8(p); p+=8; - t0g =U4(p); p+=4; - wn0g =U4(p); - raw->nav.utc_gal[0]=a0; - raw->nav.utc_gal[1]=a1; - raw->nav.utc_gal[2]=tot; - raw->nav.utc_gal[3]=wnt; - raw->nav.utc_gal[4]=dtls; - raw->nav.utc_gal[5]=wnlsf; - raw->nav.utc_gal[6]=dn; - raw->nav.utc_gal[7]=dtlsf; - return 9; +static int decode_galclockb(raw_t *raw) { + uint8_t *p = raw->buff + OEM4HLEN; + double a0, a1, a0g, a1g; + int dtls, tot, wnt, wnlsf, dn, dtlsf, t0g, wn0g; + + if (raw->len < OEM4HLEN + 64) { + trace(2, "oem4 galclockb length error: len=%d\n", raw->len); + return -1; + } + a0 = R8(p); + p += 8; + a1 = R8(p); + p += 8; + dtls = I4(p); + p += 4; + tot = U4(p); + p += 4; + wnt = U4(p); + p += 4; + wnlsf = U4(p); + p += 4; + dn = U4(p); + p += 4; + dtlsf = U4(p); + p += 4; + a0g = R8(p); + p += 8; + a1g = R8(p); + p += 8; + t0g = U4(p); + p += 4; + wn0g = U4(p); + raw->nav.utc_gal[0] = a0; + raw->nav.utc_gal[1] = a1; + raw->nav.utc_gal[2] = tot; + raw->nav.utc_gal[3] = wnt; + raw->nav.utc_gal[4] = dtls; + raw->nav.utc_gal[5] = wnlsf; + raw->nav.utc_gal[6] = dn; + raw->nav.utc_gal[7] = dtlsf; + return 9; } /* decode GALIONOB -----------------------------------------------------------*/ -static int decode_galionob(raw_t *raw) -{ - uint8_t *p=raw->buff+OEM4HLEN; - double ai[3]; - int i,sf[5]; - - if (raw->lenlen); - return -1; - } - ai[0]=R8(p); p+=8; - ai[1]=R8(p); p+=8; - ai[2]=R8(p); p+=8; - sf[0]=U1(p); p+=1; - sf[1]=U1(p); p+=1; - sf[2]=U1(p); p+=1; - sf[3]=U1(p); p+=1; - sf[4]=U1(p); - - for (i=0;i<3;i++) raw->nav.ion_gal[i]=ai[i]; - return 9; +static int decode_galionob(raw_t *raw) { + uint8_t *p = raw->buff + OEM4HLEN; + double ai[3]; + int i, sf[5]; + + if (raw->len < OEM4HLEN + 29) { + trace(2, "oem4 galionob length error: len=%d\n", raw->len); + return -1; + } + ai[0] = R8(p); + p += 8; + ai[1] = R8(p); + p += 8; + ai[2] = R8(p); + p += 8; + sf[0] = U1(p); + p += 1; + sf[1] = U1(p); + p += 1; + sf[2] = U1(p); + p += 1; + sf[3] = U1(p); + p += 1; + sf[4] = U1(p); + + for (i = 0; i < 3; i++) raw->nav.ion_gal[i] = ai[i]; + return 9; } /* decode BDSEPHEMERISB ------------------------------------------------------*/ -static int decode_bdsephemerisb(raw_t *raw) -{ - eph_t eph={0}; - uint8_t *p=raw->buff+OEM4HLEN; - double ura,sqrtA; - int prn,sat,toc; - - if (raw->lenlen); - return -1; - } - prn =U4(p); p+=4; - eph.week =U4(p); p+=4; - ura =R8(p); p+=8; - eph.svh =U4(p)&1; p+=4; - eph.tgd[0]=R8(p); p+=8; /* TGD1 for B1 (s) */ - eph.tgd[1]=R8(p); p+=8; /* TGD2 for B2 (s) */ - eph.iodc =U4(p); p+=4; /* AODC */ - toc =U4(p); p+=4; - eph.f0 =R8(p); p+=8; - eph.f1 =R8(p); p+=8; - eph.f2 =R8(p); p+=8; - eph.iode =U4(p); p+=4; /* AODE */ - eph.toes =U4(p); p+=4; - sqrtA =R8(p); p+=8; - eph.e =R8(p); p+=8; - eph.omg =R8(p); p+=8; - eph.deln =R8(p); p+=8; - eph.M0 =R8(p); p+=8; - eph.OMG0 =R8(p); p+=8; - eph.OMGd =R8(p); p+=8; - eph.i0 =R8(p); p+=8; - eph.idot =R8(p); p+=8; - eph.cuc =R8(p); p+=8; - eph.cus =R8(p); p+=8; - eph.crc =R8(p); p+=8; - eph.crs =R8(p); p+=8; - eph.cic =R8(p); p+=8; - eph.cis =R8(p); - - if (!(sat=satno(SYS_CMP,prn))) { - trace(2,"oemv bdsephemeris satellite error: prn=%d\n",prn); - return -1; - } - if (raw->outtype) { - sprintf(raw->msgtype+strlen(raw->msgtype)," prn=%d",prn); - } - eph.sat=sat; - eph.A =SQR(sqrtA); - eph.sva=uraindex(ura); - eph.toe=bdt2gpst(bdt2time(eph.week,eph.toes)); /* bdt -> gpst */ - eph.toc=bdt2gpst(bdt2time(eph.week,toc)); /* bdt -> gpst */ - eph.ttr=raw->time; - - if (!strstr(raw->opt,"-EPHALL")) { - if (fabs(timediff(raw->nav.eph[sat-1].toe,eph.toe)) < 1e-9 && - fabs(timediff(raw->nav.eph[sat-1].toc,eph.toc)) < 1e-9) return 0; - } - raw->nav.eph[sat-1]=eph; - raw->ephsat=sat; - raw->ephset=0; - return 2; +static int decode_bdsephemerisb(raw_t *raw) { + eph_t eph = {0}; + uint8_t *p = raw->buff + OEM4HLEN; + double ura, sqrtA; + int prn, sat, toc; + + if (raw->len < OEM4HLEN + 196) { + trace(2, "oem4 bdsephemrisb length error: len=%d\n", raw->len); + return -1; + } + prn = U4(p); + p += 4; + eph.week = U4(p); + p += 4; + ura = R8(p); + p += 8; + eph.svh = U4(p) & 1; + p += 4; + eph.tgd[0] = R8(p); + p += 8; /* TGD1 for B1 (s) */ + eph.tgd[1] = R8(p); + p += 8; /* TGD2 for B2 (s) */ + eph.iodc = U4(p); + p += 4; /* AODC */ + toc = U4(p); + p += 4; + eph.f0 = R8(p); + p += 8; + eph.f1 = R8(p); + p += 8; + eph.f2 = R8(p); + p += 8; + eph.iode = U4(p); + p += 4; /* AODE */ + eph.toes = U4(p); + p += 4; + sqrtA = R8(p); + p += 8; + eph.e = R8(p); + p += 8; + eph.omg = R8(p); + p += 8; + eph.deln = R8(p); + p += 8; + eph.M0 = R8(p); + p += 8; + eph.OMG0 = R8(p); + p += 8; + eph.OMGd = R8(p); + p += 8; + eph.i0 = R8(p); + p += 8; + eph.idot = R8(p); + p += 8; + eph.cuc = R8(p); + p += 8; + eph.cus = R8(p); + p += 8; + eph.crc = R8(p); + p += 8; + eph.crs = R8(p); + p += 8; + eph.cic = R8(p); + p += 8; + eph.cis = R8(p); + + if (!(sat = satno(SYS_CMP, prn))) { + trace(2, "oemv bdsephemeris satellite error: prn=%d\n", prn); + return -1; + } + if (raw->outtype) { + sprintf(raw->msgtype + strlen(raw->msgtype), " prn=%d", prn); + } + eph.sat = sat; + eph.A = SQR(sqrtA); + eph.sva = uraindex(ura); + eph.toe = bdt2gpst(bdt2time(eph.week, eph.toes)); /* bdt -> gpst */ + eph.toc = bdt2gpst(bdt2time(eph.week, toc)); /* bdt -> gpst */ + eph.ttr = raw->time; + + if (!strstr(raw->opt, "-EPHALL")) { + if (fabs(timediff(raw->nav.eph[sat - 1].toe, eph.toe)) < 1e-9 && + fabs(timediff(raw->nav.eph[sat - 1].toc, eph.toc)) < 1e-9) + return 0; + } + raw->nav.eph[sat - 1] = eph; + raw->ephsat = sat; + raw->ephset = 0; + return 2; } /* decode NAVICEPHEMERISB ----------------------------------------------------*/ -static int decode_navicephemerisb(raw_t *raw) -{ - eph_t eph={0}; - uint8_t *p=raw->buff+OEM4HLEN; - double sqrtA; - int prn,sat,toc,rsv,l5_health,s_health,alert,autonav; - - if (raw->lenlen); - return -1; - } - prn =U4(p); p+=4; - eph.week =U4(p); p+=4; - eph.f0 =R8(p); p+=8; - eph.f1 =R8(p); p+=8; - eph.f2 =R8(p); p+=8; - eph.sva =U4(p); p+=4; /* URA index */ - toc =U4(p); p+=4; - eph.tgd[0]=R8(p); p+=8; /* TGD */ - eph.deln =R8(p); p+=8; - eph.iode =U4(p); p+=4; /* IODEC */ - rsv =U4(p); p+=4; - l5_health =U4(p)&1; p+=4; - s_health =U4(p)&1; p+=4; - eph.cuc =R8(p); p+=8; - eph.cus =R8(p); p+=8; - eph.cic =R8(p); p+=8; - eph.cis =R8(p); p+=8; - eph.crc =R8(p); p+=8; - eph.crs =R8(p); p+=8; - eph.idot =R8(p); p+=8; - rsv =U4(p); p+=4; - eph.M0 =R8(p); p+=8; - eph.toes =U4(p); p+=4; - eph.e =R8(p); p+=8; - sqrtA =R8(p); p+=8; - eph.OMG0 =R8(p); p+=8; - eph.omg =R8(p); p+=8; - eph.OMGd =R8(p); p+=8; - eph.i0 =R8(p); p+=8; - rsv =U4(p); p+=4; - alert =U4(p); p+=4; - autonav =U4(p); - - if (toc!=eph.toes) { /* toe and toc should be matched */ - trace(2,"oem4 navicephemrisb toe and toc unmatch prn=%d\n",prn); - return -1; - } - if (!(sat=satno(SYS_IRN,prn))) { - trace(2,"oemv navicephemeris satellite error: prn=%d\n",prn); - return 0; - } - if (raw->outtype) { - sprintf(raw->msgtype+strlen(raw->msgtype)," prn=%d",prn); - } - eph.sat =sat; - eph.A =SQR(sqrtA); - eph.svh =(l5_health<<1)|s_health; - eph.iodc=eph.iode; - eph.week+=1024; /* irnss-week -> gps-week */ - eph.toe=gpst2time(eph.week,eph.toes); - eph.toc=gpst2time(eph.week,toc); - eph.ttr=raw->time; - eph.tgd[1]=0.0; - - if (!strstr(raw->opt,"-EPHALL")) { - if (fabs(timediff(raw->nav.eph[sat-1].toe,eph.toe)) < 1e-9 && - raw->nav.eph[sat-1].iode==eph.iode) return 0; /* unchanged */ - } - raw->nav.eph[sat-1]=eph; - raw->ephsat=sat; - raw->ephset=0; - return 2; +static int decode_navicephemerisb(raw_t *raw) { + eph_t eph = {0}; + uint8_t *p = raw->buff + OEM4HLEN; + double sqrtA; + int prn, sat, toc, rsv, l5_health, s_health, alert, autonav; + + if (raw->len < OEM4HLEN + 204) { + trace(2, "oem4 navicephemrisb length error: len=%d\n", raw->len); + return -1; + } + prn = U4(p); + p += 4; + eph.week = U4(p); + p += 4; + eph.f0 = R8(p); + p += 8; + eph.f1 = R8(p); + p += 8; + eph.f2 = R8(p); + p += 8; + eph.sva = U4(p); + p += 4; /* URA index */ + toc = U4(p); + p += 4; + eph.tgd[0] = R8(p); + p += 8; /* TGD */ + eph.deln = R8(p); + p += 8; + eph.iode = U4(p); + p += 4; /* IODEC */ + rsv = U4(p); + p += 4; + l5_health = U4(p) & 1; + p += 4; + s_health = U4(p) & 1; + p += 4; + eph.cuc = R8(p); + p += 8; + eph.cus = R8(p); + p += 8; + eph.cic = R8(p); + p += 8; + eph.cis = R8(p); + p += 8; + eph.crc = R8(p); + p += 8; + eph.crs = R8(p); + p += 8; + eph.idot = R8(p); + p += 8; + rsv = U4(p); + p += 4; + eph.M0 = R8(p); + p += 8; + eph.toes = U4(p); + p += 4; + eph.e = R8(p); + p += 8; + sqrtA = R8(p); + p += 8; + eph.OMG0 = R8(p); + p += 8; + eph.omg = R8(p); + p += 8; + eph.OMGd = R8(p); + p += 8; + eph.i0 = R8(p); + p += 8; + rsv = U4(p); + p += 4; + alert = U4(p); + p += 4; + autonav = U4(p); + + if (toc != eph.toes) { /* toe and toc should be matched */ + trace(2, "oem4 navicephemrisb toe and toc unmatch prn=%d\n", prn); + return -1; + } + if (!(sat = satno(SYS_IRN, prn))) { + trace(2, "oemv navicephemeris satellite error: prn=%d\n", prn); + return 0; + } + if (raw->outtype) { + sprintf(raw->msgtype + strlen(raw->msgtype), " prn=%d", prn); + } + eph.sat = sat; + eph.A = SQR(sqrtA); + eph.svh = (l5_health << 1) | s_health; + eph.iodc = eph.iode; + eph.week += 1024; /* irnss-week -> gps-week */ + eph.toe = gpst2time(eph.week, eph.toes); + eph.toc = gpst2time(eph.week, toc); + eph.ttr = raw->time; + eph.tgd[1] = 0.0; + + if (!strstr(raw->opt, "-EPHALL")) { + if (fabs(timediff(raw->nav.eph[sat - 1].toe, eph.toe)) < 1e-9 && + raw->nav.eph[sat - 1].iode == eph.iode) + return 0; /* unchanged */ + } + raw->nav.eph[sat - 1] = eph; + raw->ephsat = sat; + raw->ephset = 0; + return 2; } /* decode RGEB ---------------------------------------------------------------*/ -static int decode_rgeb(raw_t *raw) -{ - uint8_t *p=raw->buff+OEM3HLEN; - double tow,psr,adr,tt,lockt,dop,snr; - int i,week,nobs,prn,sat,stat,sys,parity,lli,index,freq; - - week=adjgpsweek(U4(p)); - tow =R8(p+ 4); - nobs=U4(p+12); - raw->time=gpst2time(week,tow); - - if (raw->len!=OEM3HLEN+20+nobs*44) { - trace(2,"oem3 regb length error: len=%d nobs=%d\n",raw->len,nobs); - return -1; - } - for (i=0,p+=20;i>20)&1; /* L1:0,L2:1 */ - sys =(stat>>15)&7; /* satellite sys (0:GPS,1:GLONASS,2:WAAS) */ - parity=(stat>>10)&1; /* parity known */ - if (!(sat=satno(sys==1?SYS_GLO:(sys==2?SYS_SBS:SYS_GPS),prn))) { - trace(2,"oem3 regb satellite number error: sys=%d prn=%d\n",sys,prn); - continue; - } - if (raw->tobs[sat-1][freq].time!=0) { - tt=timediff(raw->time,raw->tobs[sat-1][freq]); - lli=lockt-raw->lockt[sat-1][freq]+0.05halfc[sat-1][freq]; - } - else { - lli=0; - } - if (!parity) lli|=2; - raw->tobs [sat-1][freq]=raw->time; - raw->lockt[sat-1][freq]=lockt; - raw->halfc[sat-1][freq]=parity; - - if (fabs(timediff(raw->obs.data[0].time,raw->time))>1E-9) { - raw->obs.n=0; - } - if ((index=obsindex(&raw->obs,raw->time,sat))>=0) { - raw->obs.data[index].L [freq]=-adr; /* flip sign */ - raw->obs.data[index].P [freq]=psr; - raw->obs.data[index].D [freq]=(float)dop; - raw->obs.data[index].SNR[freq]=0.0<=snr&&snr<255.0?snr:0; - raw->obs.data[index].LLI[freq]=(uint8_t)lli; - raw->obs.data[index].code[freq]=freq==0?CODE_L1C:CODE_L2P; - } - } - return 1; +static int decode_rgeb(raw_t *raw) { + uint8_t *p = raw->buff + OEM3HLEN; + double tow, psr, adr, tt, lockt, dop, snr; + int i, week, nobs, prn, sat, stat, sys, parity, lli, index, freq; + + week = adjgpsweek(U4(p)); + tow = R8(p + 4); + nobs = U4(p + 12); + raw->time = gpst2time(week, tow); + + if (raw->len != OEM3HLEN + 20 + nobs * 44) { + trace(2, "oem3 regb length error: len=%d nobs=%d\n", raw->len, nobs); + return -1; + } + for (i = 0, p += 20; i < nobs; i++, p += 44) { + prn = U4(p); + psr = R8(p + 4); + adr = R8(p + 16); + dop = R4(p + 28); + snr = R4(p + 32); + lockt = R4(p + 36); /* lock time (s) */ + stat = I4(p + 40); /* tracking status */ + freq = (stat >> 20) & 1; /* L1:0,L2:1 */ + sys = (stat >> 15) & 7; /* satellite sys (0:GPS,1:GLONASS,2:WAAS) */ + parity = (stat >> 10) & 1; /* parity known */ + if (!(sat = satno(sys == 1 ? SYS_GLO : (sys == 2 ? SYS_SBS : SYS_GPS), prn))) { + trace(2, "oem3 regb satellite number error: sys=%d prn=%d\n", sys, prn); + continue; + } + if (raw->tobs[sat - 1][freq].time != 0) { + tt = timediff(raw->time, raw->tobs[sat - 1][freq]); + lli = lockt - raw->lockt[sat - 1][freq] + 0.05 < tt || parity != raw->halfc[sat - 1][freq]; + } else { + lli = 0; + } + if (!parity) lli |= 2; + raw->tobs[sat - 1][freq] = raw->time; + raw->lockt[sat - 1][freq] = lockt; + raw->halfc[sat - 1][freq] = parity; + + if (fabs(timediff(raw->obs.data[0].time, raw->time)) > 1E-9) { + raw->obs.n = 0; + } + if ((index = obsindex(&raw->obs, raw->time, sat)) >= 0) { + raw->obs.data[index].L[freq] = -adr; /* flip sign */ + raw->obs.data[index].P[freq] = psr; + raw->obs.data[index].D[freq] = (float)dop; + raw->obs.data[index].SNR[freq] = 0.0 <= snr && snr < 255.0 ? snr : 0; + raw->obs.data[index].LLI[freq] = (uint8_t)lli; + raw->obs.data[index].code[freq] = freq == 0 ? CODE_L1C : CODE_L2P; + } + } + return 1; } /* decode RGED ---------------------------------------------------------------*/ -static int decode_rged(raw_t *raw) -{ - uint32_t word; - uint8_t *p=raw->buff+OEM3HLEN; - double tow,psrh,psrl,psr,adr,adr_rolls,tt,lockt,dop; - int i,week,nobs,prn,sat,stat,sys,parity,lli,index,freq,snr; - - nobs=U2(p); - week=adjgpsweek(U2(p+2)); - tow =U4(p+4)/100.0; - raw->time=gpst2time(week,tow); - if (raw->len!=OEM3HLEN+12+nobs*20) { - trace(2,"oem3 regd length error: len=%d nobs=%d\n",raw->len,nobs); - return -1; - } - for (i=0,p+=12;i>6)&0x1F)+20; - lockt =(word>>11)/32.0; - adr =-I4(p+4)/256.0; - word =U4(p+8); - psrh =word&0xF; - dop =exsign(word>>4,28)/256.0; - psrl =U4(p+12); - stat =U4(p+16)>>8; - freq =(stat>>20)&1; /* L1:0,L2:1 */ - sys =(stat>>15)&7; /* satellite sys (0:GPS,1:GLONASS,2:WAAS) */ - parity=(stat>>10)&1; /* parity known */ - if (!(sat=satno(sys==1?SYS_GLO:(sys==2?SYS_SBS:SYS_GPS),prn))) { - trace(2,"oem3 regd satellite number error: sys=%d prn=%d\n",sys,prn); - continue; - } - psr=(psrh*4294967296.0+psrl)/128.0; - adr_rolls=floor((psr/(freq==0?WL1:WL2)-adr)/MAXVAL+0.5); - adr=adr+MAXVAL*adr_rolls; - - if (raw->tobs[sat-1][freq].time!=0) { - tt=timediff(raw->time,raw->tobs[sat-1][freq]); - lli=lockt-raw->lockt[sat-1][freq]+0.05halfc[sat-1][freq]; - } - else { - lli=0; - } - if (!parity) lli|=2; - raw->tobs [sat-1][freq]=raw->time; - raw->lockt[sat-1][freq]=lockt; - raw->halfc[sat-1][freq]=parity; - - if (fabs(timediff(raw->obs.data[0].time,raw->time))>1E-9) { - raw->obs.n=0; - } - if ((index=obsindex(&raw->obs,raw->time,sat))>=0) { - raw->obs.data[index].L [freq]=adr; - raw->obs.data[index].P [freq]=psr; - raw->obs.data[index].D [freq]=(float)dop; - raw->obs.data[index].SNR[freq]=snr; - raw->obs.data[index].LLI[freq]=(uint8_t)lli; - raw->obs.data[index].code[freq]=freq==0?CODE_L1C:CODE_L2P; - } - } - return 1; +static int decode_rged(raw_t *raw) { + uint32_t word; + uint8_t *p = raw->buff + OEM3HLEN; + double tow, psrh, psrl, psr, adr, adr_rolls, tt, lockt, dop; + int i, week, nobs, prn, sat, stat, sys, parity, lli, index, freq, snr; + + nobs = U2(p); + week = adjgpsweek(U2(p + 2)); + tow = U4(p + 4) / 100.0; + raw->time = gpst2time(week, tow); + if (raw->len != OEM3HLEN + 12 + nobs * 20) { + trace(2, "oem3 regd length error: len=%d nobs=%d\n", raw->len, nobs); + return -1; + } + for (i = 0, p += 12; i < nobs; i++, p += 20) { + word = U4(p); + prn = word & 0x3F; + snr = ((word >> 6) & 0x1F) + 20; + lockt = (word >> 11) / 32.0; + adr = -I4(p + 4) / 256.0; + word = U4(p + 8); + psrh = word & 0xF; + dop = exsign(word >> 4, 28) / 256.0; + psrl = U4(p + 12); + stat = U4(p + 16) >> 8; + freq = (stat >> 20) & 1; /* L1:0,L2:1 */ + sys = (stat >> 15) & 7; /* satellite sys (0:GPS,1:GLONASS,2:WAAS) */ + parity = (stat >> 10) & 1; /* parity known */ + if (!(sat = satno(sys == 1 ? SYS_GLO : (sys == 2 ? SYS_SBS : SYS_GPS), prn))) { + trace(2, "oem3 regd satellite number error: sys=%d prn=%d\n", sys, prn); + continue; + } + psr = (psrh * 4294967296.0 + psrl) / 128.0; + adr_rolls = floor((psr / (freq == 0 ? WL1 : WL2) - adr) / MAXVAL + 0.5); + adr = adr + MAXVAL * adr_rolls; + + if (raw->tobs[sat - 1][freq].time != 0) { + tt = timediff(raw->time, raw->tobs[sat - 1][freq]); + lli = lockt - raw->lockt[sat - 1][freq] + 0.05 < tt || parity != raw->halfc[sat - 1][freq]; + } else { + lli = 0; + } + if (!parity) lli |= 2; + raw->tobs[sat - 1][freq] = raw->time; + raw->lockt[sat - 1][freq] = lockt; + raw->halfc[sat - 1][freq] = parity; + + if (fabs(timediff(raw->obs.data[0].time, raw->time)) > 1E-9) { + raw->obs.n = 0; + } + if ((index = obsindex(&raw->obs, raw->time, sat)) >= 0) { + raw->obs.data[index].L[freq] = adr; + raw->obs.data[index].P[freq] = psr; + raw->obs.data[index].D[freq] = (float)dop; + raw->obs.data[index].SNR[freq] = snr; + raw->obs.data[index].LLI[freq] = (uint8_t)lli; + raw->obs.data[index].code[freq] = freq == 0 ? CODE_L1C : CODE_L2P; + } + } + return 1; } /* decode REPB ---------------------------------------------------------------*/ -static int decode_repb(raw_t *raw) -{ - uint8_t *p=raw->buff+OEM3HLEN; - eph_t eph={0}; - int prn,sat; - - if (raw->len!=OEM3HLEN+96) { - trace(2,"oem3 repb length error: len=%d\n",raw->len); - return -1; - } - prn=U4(p); - if (!(sat=satno(SYS_GPS,prn))) { - trace(2,"oem3 repb satellite number error: prn=%d\n",prn); - return -1; - } - if (!decode_frame(p+4,SYS_GPS,&eph,NULL,NULL,NULL)) { - trace(2,"oem3 repb subframe error: prn=%d\n",prn); - return -1; - } - if (!strstr(raw->opt,"-EPHALL")) { - if (eph.iode==raw->nav.eph[sat-1].iode) return 0; /* unchanged */ - } - eph.sat=sat; - raw->nav.eph[sat-1]=eph; - raw->ephsat=sat; - raw->ephset=0; - return 2; +static int decode_repb(raw_t *raw) { + uint8_t *p = raw->buff + OEM3HLEN; + eph_t eph = {0}; + int prn, sat; + + if (raw->len != OEM3HLEN + 96) { + trace(2, "oem3 repb length error: len=%d\n", raw->len); + return -1; + } + prn = U4(p); + if (!(sat = satno(SYS_GPS, prn))) { + trace(2, "oem3 repb satellite number error: prn=%d\n", prn); + return -1; + } + if (!decode_frame(p + 4, SYS_GPS, &eph, NULL, NULL, NULL)) { + trace(2, "oem3 repb subframe error: prn=%d\n", prn); + return -1; + } + if (!strstr(raw->opt, "-EPHALL")) { + if (eph.iode == raw->nav.eph[sat - 1].iode) return 0; /* unchanged */ + } + eph.sat = sat; + raw->nav.eph[sat - 1] = eph; + raw->ephsat = sat; + raw->ephset = 0; + return 2; } /* decode FRMB --------------------------------------------------------------*/ -static int decode_frmb(raw_t *raw) -{ - uint8_t *p=raw->buff+OEM3HLEN; - double tow; - int i,week,prn,nbit; - - trace(3,"decode_frmb: len=%d\n",raw->len); - - week=adjgpsweek(U4(p)); - tow =R8(p+ 4); - prn =U4(p+12); - nbit=U4(p+20); - raw->time=gpst2time(week,tow); - if (nbit!=250) return 0; - if (prnsbsmsg.week=week; - raw->sbsmsg.tow=(int)tow; - raw->sbsmsg.prn=prn; - for (i=0;i<29;i++) raw->sbsmsg.msg[i]=p[24+i]; - return 3; +static int decode_frmb(raw_t *raw) { + uint8_t *p = raw->buff + OEM3HLEN; + double tow; + int i, week, prn, nbit; + + trace(3, "decode_frmb: len=%d\n", raw->len); + + week = adjgpsweek(U4(p)); + tow = R8(p + 4); + prn = U4(p + 12); + nbit = U4(p + 20); + raw->time = gpst2time(week, tow); + if (nbit != 250) return 0; + if (prn < MINPRNSBS || MAXPRNSBS < prn) { + trace(2, "oem3 frmb satellite number error: prn=%d\n", prn); + return -1; + } + raw->sbsmsg.week = week; + raw->sbsmsg.tow = (int)tow; + raw->sbsmsg.prn = prn; + for (i = 0; i < 29; i++) raw->sbsmsg.msg[i] = p[24 + i]; + return 3; } /* decode IONB ---------------------------------------------------------------*/ -static int decode_ionb(raw_t *raw) -{ - uint8_t *p=raw->buff+OEM3HLEN; - int i; - - if (raw->len!=64+OEM3HLEN) { - trace(2,"oem3 ionb length error: len=%d\n",raw->len); - return -1; - } - for (i=0;i<8;i++) raw->nav.ion_gps[i]=R8(p+i*8); - return 9; +static int decode_ionb(raw_t *raw) { + uint8_t *p = raw->buff + OEM3HLEN; + int i; + + if (raw->len != 64 + OEM3HLEN) { + trace(2, "oem3 ionb length error: len=%d\n", raw->len); + return -1; + } + for (i = 0; i < 8; i++) raw->nav.ion_gps[i] = R8(p + i * 8); + return 9; } /* decode UTCB ---------------------------------------------------------------*/ -static int decode_utcb(raw_t *raw) -{ - uint8_t *p=raw->buff+OEM3HLEN; - - if (raw->len!=40+OEM3HLEN) { - trace(2,"oem3 utcb length error: len=%d\n",raw->len); - return -1; - } - raw->nav.utc_gps[0]=R8(p ); - raw->nav.utc_gps[1]=R8(p+ 8); - raw->nav.utc_gps[2]=U4(p+16); - raw->nav.utc_gps[3]=adjgpsweek(U4(p+20)); - raw->nav.utc_gps[4]=I4(p+28); - return 9; +static int decode_utcb(raw_t *raw) { + uint8_t *p = raw->buff + OEM3HLEN; + + if (raw->len != 40 + OEM3HLEN) { + trace(2, "oem3 utcb length error: len=%d\n", raw->len); + return -1; + } + raw->nav.utc_gps[0] = R8(p); + raw->nav.utc_gps[1] = R8(p + 8); + raw->nav.utc_gps[2] = U4(p + 16); + raw->nav.utc_gps[3] = adjgpsweek(U4(p + 20)); + raw->nav.utc_gps[4] = I4(p + 28); + return 9; } /* decode NovAtel OEM4/V/6/7 message -----------------------------------------*/ -static int decode_oem4(raw_t *raw) -{ - double tow; - char tstr[40]; - int msg,stat,week,type=U2(raw->buff+4); - - trace(3,"decode_oem4: type=%3d len=%d\n",type,raw->len); - - /* check crc32 */ - if (rtk_crc32(raw->buff,raw->len)!=U4(raw->buff+raw->len)) { - trace(2,"oem4 crc error: type=%3d len=%d\n",type,raw->len); - return -1; - } - msg =(U1(raw->buff+6)>>4)&0x3; /* message type: 0=binary,1=ascii */ - stat=U1(raw->buff+13); - week=U2(raw->buff+14); - - if (stat==20||week==0) { - trace(3,"oem4 time error: type=%3d msg=%d stat=%d week=%d\n",type,msg, - stat,week); - return 0; - } - week=adjgpsweek(week); - tow =U4(raw->buff+16)*0.001; - raw->time=gpst2time(week,tow); - if (msg!=0) return 0; - - if (raw->outtype) { - time2str(gpst2time(week,tow),tstr,2); - sprintf(raw->msgtype,"OEM4 %4d (%4d): %s",type,raw->len,tstr); - } - switch (type) { - case ID_RANGECMP : return decode_rangecmpb (raw); - case ID_RANGE : return decode_rangeb (raw); - case ID_RAWEPHEM : return decode_rawephemb (raw); - case ID_IONUTC : return decode_ionutcb (raw); - case ID_RAWWAASFRAME : return decode_rawwaasframeb (raw); - case ID_RAWSBASFRAME : return decode_rawsbasframeb (raw); - case ID_GLOEPHEMERIS : return decode_gloephemerisb (raw); - case ID_GALEPHEMERIS : return decode_galephemerisb (raw); - case ID_GALIONO : return decode_galionob (raw); - case ID_GALCLOCK : return decode_galclockb (raw); - case ID_QZSSRAWEPHEM : return decode_qzssrawephemb (raw); - case ID_QZSSRAWSUBFRAME: return decode_qzssrawsubframeb(raw); - case ID_QZSSIONUTC : return decode_qzssionutcb (raw); - case ID_BDSEPHEMERIS : return decode_bdsephemerisb (raw); - case ID_NAVICEPHEMERIS : return decode_navicephemerisb (raw); - } +static int decode_oem4(raw_t *raw) { + double tow; + char tstr[40]; + int msg, stat, week, type = U2(raw->buff + 4); + + trace(3, "decode_oem4: type=%3d len=%d\n", type, raw->len); + + /* check crc32 */ + if (rtk_crc32(raw->buff, raw->len) != U4(raw->buff + raw->len)) { + trace(2, "oem4 crc error: type=%3d len=%d\n", type, raw->len); + return -1; + } + msg = (U1(raw->buff + 6) >> 4) & 0x3; /* message type: 0=binary,1=ascii */ + stat = U1(raw->buff + 13); + week = U2(raw->buff + 14); + + if (stat == 20 || week == 0) { + trace(3, "oem4 time error: type=%3d msg=%d stat=%d week=%d\n", type, msg, stat, week); return 0; + } + week = adjgpsweek(week); + tow = U4(raw->buff + 16) * 0.001; + raw->time = gpst2time(week, tow); + if (msg != 0) return 0; + + if (raw->outtype) { + time2str(gpst2time(week, tow), tstr, 2); + sprintf(raw->msgtype, "OEM4 %4d (%4d): %s", type, raw->len, tstr); + } + switch (type) { + case ID_RANGECMP: + return decode_rangecmpb(raw); + case ID_RANGE: + return decode_rangeb(raw); + case ID_RAWEPHEM: + return decode_rawephemb(raw); + case ID_IONUTC: + return decode_ionutcb(raw); + case ID_RAWWAASFRAME: + return decode_rawwaasframeb(raw); + case ID_RAWSBASFRAME: + return decode_rawsbasframeb(raw); + case ID_GLOEPHEMERIS: + return decode_gloephemerisb(raw); + case ID_GALEPHEMERIS: + return decode_galephemerisb(raw); + case ID_GALIONO: + return decode_galionob(raw); + case ID_GALCLOCK: + return decode_galclockb(raw); + case ID_QZSSRAWEPHEM: + return decode_qzssrawephemb(raw); + case ID_QZSSRAWSUBFRAME: + return decode_qzssrawsubframeb(raw); + case ID_QZSSIONUTC: + return decode_qzssionutcb(raw); + case ID_BDSEPHEMERIS: + return decode_bdsephemerisb(raw); + case ID_NAVICEPHEMERIS: + return decode_navicephemerisb(raw); + } + return 0; } /* decode NovAtel OEM3 message -----------------------------------------------*/ -static int decode_oem3(raw_t *raw) -{ - int type=U4(raw->buff+4); - - trace(3,"decode_oem3: type=%3d len=%d\n",type,raw->len); - - /* checksum */ - if (chksum(raw->buff,raw->len)) { - trace(2,"oem3 checksum error: type=%3d len=%d\n",type,raw->len); - return -1; - } - if (raw->outtype) { - sprintf(raw->msgtype,"OEM3 %4d (%4d):",type,raw->len); - } - switch (type) { - case ID_RGEB: return decode_rgeb(raw); - case ID_RGED: return decode_rged(raw); - case ID_REPB: return decode_repb(raw); - case ID_FRMB: return decode_frmb(raw); - case ID_IONB: return decode_ionb(raw); - case ID_UTCB: return decode_utcb(raw); - } - return 0; +static int decode_oem3(raw_t *raw) { + int type = U4(raw->buff + 4); + + trace(3, "decode_oem3: type=%3d len=%d\n", type, raw->len); + + /* checksum */ + if (chksum(raw->buff, raw->len)) { + trace(2, "oem3 checksum error: type=%3d len=%d\n", type, raw->len); + return -1; + } + if (raw->outtype) { + sprintf(raw->msgtype, "OEM3 %4d (%4d):", type, raw->len); + } + switch (type) { + case ID_RGEB: + return decode_rgeb(raw); + case ID_RGED: + return decode_rged(raw); + case ID_REPB: + return decode_repb(raw); + case ID_FRMB: + return decode_frmb(raw); + case ID_IONB: + return decode_ionb(raw); + case ID_UTCB: + return decode_utcb(raw); + } + return 0; } /* sync header ---------------------------------------------------------------*/ -static int sync_oem4(uint8_t *buff, uint8_t data) -{ - buff[0]=buff[1]; buff[1]=buff[2]; buff[2]=data; - return buff[0]==OEM4SYNC1&&buff[1]==OEM4SYNC2&&buff[2]==OEM4SYNC3; +static int sync_oem4(uint8_t *buff, uint8_t data) { + buff[0] = buff[1]; + buff[1] = buff[2]; + buff[2] = data; + return buff[0] == OEM4SYNC1 && buff[1] == OEM4SYNC2 && buff[2] == OEM4SYNC3; } -static int sync_oem3(uint8_t *buff, uint8_t data) -{ - buff[0]=buff[1]; buff[1]=buff[2]; buff[2]=data; - return buff[0]==OEM3SYNC1&&buff[1]==OEM3SYNC2&&buff[2]==OEM3SYNC3; +static int sync_oem3(uint8_t *buff, uint8_t data) { + buff[0] = buff[1]; + buff[1] = buff[2]; + buff[2] = data; + return buff[0] == OEM3SYNC1 && buff[1] == OEM3SYNC2 && buff[2] == OEM3SYNC3; } /* input NovAtel OEM4/V/6/7 raw data from stream ------------------------------- -* fetch next NovAtel OEM4/V/6/7 raw data and input a mesasge from stream -* args : raw_t *raw IO receiver raw data control struct -* uint8_t data I stream data (1 byte) -* return : status (-1: error message, 0: no message, 1: input observation data, -* 2: input ephemeris, 3: input sbas message, -* 9: input ion/utc parameter) -* -* notes : to specify input options for oem4, set raw->opt to the following -* option strings separated by spaces. -* -* -EPHALL : input all ephemerides -* -GL1L : select 1L for GPS L1 (default 1C) -* -GL2S : select 2S for GPS L2 (default 2W) -* -GL2P : select 2P for GPS L2 (default 2W) -* -RL2C : select 2C for GLO G2 (default 2P) -* -EL6B : select 6B for GAL E6 (default 6C) -* -JL1L : select 1L for QZS L1 (default 1C) -* -JL1Z : select 1Z for QZS L1 (default 1C) -* -CL1P : select 1P for BDS B1 (default 2I) -* -CL7D : select 7D for BDS B2 (default 7I) -* -GALINAV: select I/NAV for Galileo ephemeris (default: all) -* -GALFNAV: select F/NAV for Galileo ephemeris (default: all) -* -GLOBIAS=bias: GLONASS code-phase bias (m) -*-----------------------------------------------------------------------------*/ -extern int input_oem4(raw_t *raw, uint8_t data) -{ - trace(5,"input_oem4: data=%02x\n",data); - - /* synchronize frame */ - if (raw->nbyte==0) { - if (sync_oem4(raw->buff,data)) raw->nbyte=3; - return 0; - } - raw->buff[raw->nbyte++]=data; - - if (raw->nbyte==10&&(raw->len=U2(raw->buff+8)+OEM4HLEN)>MAXRAWLEN-4) { - trace(2,"oem4 length error: len=%d\n",raw->len); - raw->nbyte=0; - return -1; - } - if (raw->nbyte<10||raw->nbytelen+4) return 0; - raw->nbyte=0; - - /* decode oem7/6/4 message */ - return decode_oem4(raw); + * fetch next NovAtel OEM4/V/6/7 raw data and input a mesasge from stream + * args : raw_t *raw IO receiver raw data control struct + * uint8_t data I stream data (1 byte) + * return : status (-1: error message, 0: no message, 1: input observation data, + * 2: input ephemeris, 3: input sbas message, + * 9: input ion/utc parameter) + * + * notes : to specify input options for oem4, set raw->opt to the following + * option strings separated by spaces. + * + * -EPHALL : input all ephemerides + * -GL1L : select 1L for GPS L1 (default 1C) + * -GL2S : select 2S for GPS L2 (default 2W) + * -GL2P : select 2P for GPS L2 (default 2W) + * -RL2C : select 2C for GLO G2 (default 2P) + * -EL6B : select 6B for GAL E6 (default 6C) + * -JL1L : select 1L for QZS L1 (default 1C) + * -JL1Z : select 1Z for QZS L1 (default 1C) + * -CL1P : select 1P for BDS B1 (default 2I) + * -CL7D : select 7D for BDS B2 (default 7I) + * -GALINAV: select I/NAV for Galileo ephemeris (default: all) + * -GALFNAV: select F/NAV for Galileo ephemeris (default: all) + * -GLOBIAS=bias: GLONASS code-phase bias (m) + *-----------------------------------------------------------------------------*/ +extern int input_oem4(raw_t *raw, uint8_t data) { + trace(5, "input_oem4: data=%02x\n", data); + + /* synchronize frame */ + if (raw->nbyte == 0) { + if (sync_oem4(raw->buff, data)) raw->nbyte = 3; + return 0; + } + raw->buff[raw->nbyte++] = data; + + if (raw->nbyte == 10 && (raw->len = U2(raw->buff + 8) + OEM4HLEN) > MAXRAWLEN - 4) { + trace(2, "oem4 length error: len=%d\n", raw->len); + raw->nbyte = 0; + return -1; + } + if (raw->nbyte < 10 || raw->nbyte < raw->len + 4) return 0; + raw->nbyte = 0; + + /* decode oem7/6/4 message */ + return decode_oem4(raw); } /* input NovAtel OEM3 raw data from stream ------------------------------------- -* fetch next NovAtel OEM3 raw data and input a mesasge from stream -* args : raw_t *raw IO receiver raw data control struct -* uint8_t data I stream data (1 byte) -* return : same as above -*-----------------------------------------------------------------------------*/ -extern int input_oem3(raw_t *raw, uint8_t data) -{ - trace(5,"input_oem3: data=%02x\n",data); - - /* synchronize frame */ - if (raw->nbyte==0) { - if (sync_oem3(raw->buff,data)) raw->nbyte=3; - return 0; - } - raw->buff[raw->nbyte++]=data; - - if (raw->nbyte==12&&(raw->len=U4(raw->buff+8))>MAXRAWLEN) { - trace(2,"oem3 length error: len=%d\n",raw->len); - raw->nbyte=0; - return -1; - } - if (raw->nbyte<12||raw->nbytelen) return 0; - raw->nbyte=0; - - /* decode oem3 message */ - return decode_oem3(raw); + * fetch next NovAtel OEM3 raw data and input a mesasge from stream + * args : raw_t *raw IO receiver raw data control struct + * uint8_t data I stream data (1 byte) + * return : same as above + *-----------------------------------------------------------------------------*/ +extern int input_oem3(raw_t *raw, uint8_t data) { + trace(5, "input_oem3: data=%02x\n", data); + + /* synchronize frame */ + if (raw->nbyte == 0) { + if (sync_oem3(raw->buff, data)) raw->nbyte = 3; + return 0; + } + raw->buff[raw->nbyte++] = data; + + if (raw->nbyte == 12 && (raw->len = U4(raw->buff + 8)) > MAXRAWLEN) { + trace(2, "oem3 length error: len=%d\n", raw->len); + raw->nbyte = 0; + return -1; + } + if (raw->nbyte < 12 || raw->nbyte < raw->len) return 0; + raw->nbyte = 0; + + /* decode oem3 message */ + return decode_oem3(raw); } /* input NovAtel OEM4/V/6/7 raw data from file --------------------------------- -* fetch next NovAtel OEM4/V/6/7 raw data and input a message from file -* args : raw_t *raw IO receiver raw data control struct -* FILE *fp I file pointer -* return : status(-2: end of file, -1...9: same as above) -*-----------------------------------------------------------------------------*/ -extern int input_oem4f(raw_t *raw, FILE *fp) -{ - int i,data; - - trace(4,"input_oem4f:\n"); - - /* synchronize frame */ - if (raw->nbyte==0) { - for (i=0;;i++) { - if ((data=fgetc(fp))==EOF) return -2; - if (sync_oem4(raw->buff,(uint8_t)data)) break; - if (i>=4096) return 0; - } - } - if (fread(raw->buff+3,7,1,fp)<1) return -2; - raw->nbyte=10; - - if ((raw->len=U2(raw->buff+8)+OEM4HLEN)>MAXRAWLEN-4) { - trace(2,"oem4 length error: len=%d\n",raw->len); - raw->nbyte=0; - return -1; - } - if (fread(raw->buff+10,raw->len-6,1,fp)<1) return -2; - raw->nbyte=0; - - /* decode NovAtel OEM4/V/6/7 message */ - return decode_oem4(raw); + * fetch next NovAtel OEM4/V/6/7 raw data and input a message from file + * args : raw_t *raw IO receiver raw data control struct + * FILE *fp I file pointer + * return : status(-2: end of file, -1...9: same as above) + *-----------------------------------------------------------------------------*/ +extern int input_oem4f(raw_t *raw, FILE *fp) { + int i, data; + + trace(4, "input_oem4f:\n"); + + /* synchronize frame */ + if (raw->nbyte == 0) { + for (i = 0;; i++) { + if ((data = fgetc(fp)) == EOF) return -2; + if (sync_oem4(raw->buff, (uint8_t)data)) break; + if (i >= 4096) return 0; + } + } + if (fread(raw->buff + 3, 7, 1, fp) < 1) return -2; + raw->nbyte = 10; + + if ((raw->len = U2(raw->buff + 8) + OEM4HLEN) > MAXRAWLEN - 4) { + trace(2, "oem4 length error: len=%d\n", raw->len); + raw->nbyte = 0; + return -1; + } + if (fread(raw->buff + 10, raw->len - 6, 1, fp) < 1) return -2; + raw->nbyte = 0; + + /* decode NovAtel OEM4/V/6/7 message */ + return decode_oem4(raw); } /* input NovAtel OEM3 raw data from file --------------------------------------- -* fetch next NovAtel OEM3 raw data and input a message from file -* args : raw_t *raw IO receiver raw data control struct -* FILE *fp I file pointer -* return : status(-2: end of file, -1...9: same as above) -*-----------------------------------------------------------------------------*/ -extern int input_oem3f(raw_t *raw, FILE *fp) -{ - int i,data; - - trace(4,"input_oem3f:\n"); - - /* synchronize frame */ - if (raw->nbyte==0) { - for (i=0;;i++) { - if ((data=fgetc(fp))==EOF) return -2; - if (sync_oem3(raw->buff,(uint8_t)data)) break; - if (i>=4096) return 0; - } - } - if (fread(raw->buff+3,1,9,fp)<9) return -2; - raw->nbyte=12; - - if ((raw->len=U4(raw->buff+8))>MAXRAWLEN) { - trace(2,"oem3 length error: len=%d\n",raw->len); - raw->nbyte=0; - return -1; - } - if (fread(raw->buff+12,1,raw->len-12,fp)<(size_t)(raw->len-12)) return -2; - raw->nbyte=0; - - /* decode oem3 message */ - return decode_oem3(raw); + * fetch next NovAtel OEM3 raw data and input a message from file + * args : raw_t *raw IO receiver raw data control struct + * FILE *fp I file pointer + * return : status(-2: end of file, -1...9: same as above) + *-----------------------------------------------------------------------------*/ +extern int input_oem3f(raw_t *raw, FILE *fp) { + int i, data; + + trace(4, "input_oem3f:\n"); + + /* synchronize frame */ + if (raw->nbyte == 0) { + for (i = 0;; i++) { + if ((data = fgetc(fp)) == EOF) return -2; + if (sync_oem3(raw->buff, (uint8_t)data)) break; + if (i >= 4096) return 0; + } + } + if (fread(raw->buff + 3, 1, 9, fp) < 9) return -2; + raw->nbyte = 12; + + if ((raw->len = U4(raw->buff + 8)) > MAXRAWLEN) { + trace(2, "oem3 length error: len=%d\n", raw->len); + raw->nbyte = 0; + return -1; + } + if (fread(raw->buff + 12, 1, raw->len - 12, fp) < (size_t)(raw->len - 12)) return -2; + raw->nbyte = 0; + + /* decode oem3 message */ + return decode_oem3(raw); } diff --git a/src/rcv/nvs.c b/src/rcv/nvs.c index 5fabde24b..aa9e318a1 100644 --- a/src/rcv/nvs.c +++ b/src/rcv/nvs.c @@ -1,620 +1,636 @@ /*------------------------------------------------------------------------------ -* nvs.c : NVS receiver dependent functions -* -* Copyright (C) 2012-2016 by M.BAVARO and T.TAKASU, All rights reserved. -* Copyright (C) 2014-2020 by T.TAKASU, All rights reserved. -* -* [1] Description of BINR messages which is used by RC program for RINEX -* files accumulation, NVS -* [2] NAVIS Navis Standard Interface Protocol BINR, NVS -* -* version : $Revision:$ $Date:$ -* history : 2012/01/30 1.0 first version by M.BAVARO -* 2012/11/08 1.1 modified by T.TAKASU -* 2013/02/23 1.2 fix memory access violation problem on arm -* 2013/04/24 1.3 fix bug on cycle-slip detection -* add range check of gps ephemeris week -* 2013/09/01 1.4 add check error of week, time jump, obs data range -* 2014/08/26 1.5 fix bug on iode in glonass ephemeris -* 2016/01/26 1.6 fix bug on unrecognized meas data (#130) -* 2017/04/11 1.7 (char *) -> (signed char *) -* 2020/07/10 1.8 suppress warnings -* 2020/11/30 1.9 use integer type in stdint.h -*-----------------------------------------------------------------------------*/ + * nvs.c : NVS receiver dependent functions + * + * Copyright (C) 2012-2016 by M.BAVARO and T.TAKASU, All rights reserved. + * Copyright (C) 2014-2020 by T.TAKASU, All rights reserved. + * + * [1] Description of BINR messages which is used by RC program for RINEX + * files accumulation, NVS + * [2] NAVIS Navis Standard Interface Protocol BINR, NVS + * + * version : $Revision:$ $Date:$ + * history : 2012/01/30 1.0 first version by M.BAVARO + * 2012/11/08 1.1 modified by T.TAKASU + * 2013/02/23 1.2 fix memory access violation problem on arm + * 2013/04/24 1.3 fix bug on cycle-slip detection + * add range check of gps ephemeris week + * 2013/09/01 1.4 add check error of week, time jump, obs data range + * 2014/08/26 1.5 fix bug on iode in glonass ephemeris + * 2016/01/26 1.6 fix bug on unrecognized meas data (#130) + * 2017/04/11 1.7 (char *) -> (signed char *) + * 2020/07/10 1.8 suppress warnings + * 2020/11/30 1.9 use integer type in stdint.h + *-----------------------------------------------------------------------------*/ #define _POSIX_C_SOURCE 199506 #include "rtklib.h" -#define NVSSYNC 0x10 /* nvs message sync code 1 */ -#define NVSENDMSG 0x03 /* nvs message sync code 1 */ -#define NVSCFG 0x06 /* nvs message cfg-??? */ +#define NVSSYNC 0x10 /* nvs message sync code 1 */ +#define NVSENDMSG 0x03 /* nvs message sync code 1 */ +#define NVSCFG 0x06 /* nvs message cfg-??? */ -#define ID_XF5RAW 0xf5 /* nvs msg id: raw measurement data */ -#define ID_X4AIONO 0x4a /* nvs msg id: gps ionospheric data */ -#define ID_X4BTIME 0x4b /* nvs msg id: GPS/GLONASS/UTC timescale data */ -#define ID_XF7EPH 0xf7 /* nvs msg id: subframe buffer */ -#define ID_XE5BIT 0xe5 /* nvs msg id: bit information */ +#define ID_XF5RAW 0xf5 /* nvs msg id: raw measurement data */ +#define ID_X4AIONO 0x4a /* nvs msg id: gps ionospheric data */ +#define ID_X4BTIME 0x4b /* nvs msg id: GPS/GLONASS/UTC timescale data */ +#define ID_XF7EPH 0xf7 /* nvs msg id: subframe buffer */ +#define ID_XE5BIT 0xe5 /* nvs msg id: bit information */ -#define ID_XD7ADVANCED 0xd7 /* */ -#define ID_X02RATEPVT 0x02 /* */ -#define ID_XF4RATERAW 0xf4 /* */ -#define ID_XD7SMOOTH 0xd7 /* */ -#define ID_XD5BIT 0xd5 /* */ +#define ID_XD7ADVANCED 0xd7 /* */ +#define ID_X02RATEPVT 0x02 /* */ +#define ID_XF4RATERAW 0xf4 /* */ +#define ID_XD7SMOOTH 0xd7 /* */ +#define ID_XD5BIT 0xd5 /* */ /* get fields (little-endian) ------------------------------------------------*/ #define U1(p) (*((uint8_t *)(p))) -#define I1(p) (*((int8_t *)(p))) -static uint16_t U2(uint8_t *p) {uint16_t u; memcpy(&u,p,2); return u;} -static uint32_t U4(uint8_t *p) {uint32_t u; memcpy(&u,p,4); return u;} -static int16_t I2(uint8_t *p) {int16_t i; memcpy(&i,p,2); return i;} -static int32_t I4(uint8_t *p) {int32_t i; memcpy(&i,p,4); return i;} -static float R4(uint8_t *p) {float r; memcpy(&r,p,4); return r;} -static double R8(uint8_t *p) {double r; memcpy(&r,p,8); return r;} +#define I1(p) (*((int8_t *)(p))) +static uint16_t U2(uint8_t *p) { + uint16_t u; + memcpy(&u, p, 2); + return u; +} +static uint32_t U4(uint8_t *p) { + uint32_t u; + memcpy(&u, p, 4); + return u; +} +static int16_t I2(uint8_t *p) { + int16_t i; + memcpy(&i, p, 2); + return i; +} +static int32_t I4(uint8_t *p) { + int32_t i; + memcpy(&i, p, 4); + return i; +} +static float R4(uint8_t *p) { + float r; + memcpy(&r, p, 4); + return r; +} +static double R8(uint8_t *p) { + double r; + memcpy(&r, p, 8); + return r; +} /* ura values (ref [3] 20.3.3.3.1.1) -----------------------------------------*/ -static const double ura_eph[]={ - 2.4,3.4,4.85,6.85,9.65,13.65,24.0,48.0,96.0,192.0,384.0,768.0,1536.0, - 3072.0,6144.0,0.0 -}; +static const double ura_eph[] = {2.4, 3.4, 4.85, 6.85, 9.65, 13.65, 24.0, 48.0, + 96.0, 192.0, 384.0, 768.0, 1536.0, 3072.0, 6144.0, 0.0}; /* ura value (m) to ura index ------------------------------------------------*/ -static int uraindex(double value) -{ - int i; - for (i=0;i<15;i++) if (ura_eph[i]>=value) break; - return i; +static int uraindex(double value) { + int i; + for (i = 0; i < 15; i++) + if (ura_eph[i] >= value) break; + return i; } /* decode NVS xf5-raw: raw measurement data ----------------------------------*/ -static int decode_xf5raw(raw_t *raw) -{ - gtime_t time; - double tadj=0.0,toff=0.0,tn; - int dTowInt; - double dTowUTC, dTowGPS, dTowFrac, L1, P1, D1; - double gpsutcTimescale; - uint8_t rcvTimeScaleCorr, sys, carrNo; - int i,j,prn,sat,n=0,nsat,week; - uint8_t *p=raw->buff+2; - char *q,tstr[40],flag; - - trace(4,"decode_xf5raw: len=%d\n",raw->len); - - /* time tag adjustment option (-TADJ) */ - if ((q=strstr(raw->opt,"-tadj"))) { - sscanf(q,"-TADJ=%lf",&tadj); - } - dTowUTC =R8(p); - week = U2(p+8); - gpsutcTimescale = R8(p+10); - /* glonassutcTimescale = R8(p+18); */ - rcvTimeScaleCorr = I1(p+26); - - /* check gps week range */ - if (week>=4096) { - trace(2,"nvs xf5raw obs week error: week=%d\n",week); - return -1; - } - week=adjgpsweek(week); - - if ((raw->len - 31)%30) { - - /* Message length is not correct: there could be an error in the stream */ - trace(2,"nvs xf5raw len=%d seems not be correct\n",raw->len); - return -1; - } - nsat = (raw->len - 31)/30; - - dTowGPS = dTowUTC + gpsutcTimescale; - - /* Tweak pseudoranges to allow Rinex to represent the NVS time of measure */ - dTowInt = 10.0*floor((dTowGPS/10.0)+0.5); - dTowFrac = dTowGPS - (double) dTowInt; - time=gpst2time(week, dTowInt*0.001); - - /* time tag adjustment */ - if (tadj>0.0) { - tn=time2gpst(time,&week)/tadj; - toff=(tn-floor(tn+0.5))*tadj; - time=timeadd(time,-toff); - } - /* check time tag jump and output warning */ - if (raw->time.time&&fabs(timediff(time,raw->time))>86400.0) { - time2str(time,tstr,3); - trace(2,"nvs xf5raw time tag jump warning: time=%s\n",tstr); - } - if (fabs(timediff(time,raw->time))<=1e-3) { - time2str(time,tstr,3); - trace(2,"nvs xf5raw time tag duplicated: time=%s\n",tstr); - return 0; - } - for (i=0,p+=27;(iobs.data[n].time = time; - sys = (U1(p)==1)?SYS_GLO:((U1(p)==2)?SYS_GPS:((U1(p)==4)?SYS_SBS:SYS_NONE)); - prn = U1(p+1); - if (sys == SYS_SBS) prn += 120; /* Correct this */ - if (!(sat=satno(sys,prn))) { - trace(2,"nvs xf5raw satellite number error: sys=%d prn=%d\n",sys,prn); - continue; - } - carrNo = I1(p+2); - L1 = R8(p+ 4); - P1 = R8(p+12); - D1 = R8(p+20); - - /* check range error */ - if (L1<-1E10||L1>1E10||P1<-1E10||P1>1E10||D1<-1E5||D1>1E5) { - trace(2,"nvs xf5raw obs range error: sat=%2d L1=%12.5e P1=%12.5e D1=%12.5e\n", - sat,L1,P1,D1); - continue; - } - raw->obs.data[n].SNR[0]=I1(p+3); - if (sys==SYS_GLO) { - raw->obs.data[n].L[0] = L1 - toff*(FREQ1_GLO+DFRQ1_GLO*carrNo); - } else { - raw->obs.data[n].L[0] = L1 - toff*FREQL1; - } - raw->obs.data[n].P[0] = (P1-dTowFrac)*CLIGHT*0.001 - toff*CLIGHT; /* in ms, needs to be converted */ - raw->obs.data[n].D[0] = (float)D1; - - /* set LLI if meas flag 4 (carrier phase present) off -> on */ - flag=U1(p+28); - raw->obs.data[n].LLI[0]=(flag&0x08)&&!(raw->halfc[sat-1][0]&0x08)?1:0; - raw->halfc[sat-1][0]=flag; - - raw->obs.data[n].code[0] = CODE_L1C; - raw->obs.data[n].sat = sat; - - for (j=1;jobs.data[n].L[j]=raw->obs.data[n].P[j]=0.0; - raw->obs.data[n].D[j]=raw->obs.data[n].SNR[j]=0.0; - raw->obs.data[n].LLI[j]=0; - raw->obs.data[n].code[j]=CODE_NONE; - } - n++; - } - raw->time=time; - raw->obs.n=n; - return 1; +static int decode_xf5raw(raw_t *raw) { + gtime_t time; + double tadj = 0.0, toff = 0.0, tn; + int dTowInt; + double dTowUTC, dTowGPS, dTowFrac, L1, P1, D1; + double gpsutcTimescale; + uint8_t rcvTimeScaleCorr, sys, carrNo; + int i, j, prn, sat, n = 0, nsat, week; + uint8_t *p = raw->buff + 2; + char *q, tstr[40], flag; + + trace(4, "decode_xf5raw: len=%d\n", raw->len); + + /* time tag adjustment option (-TADJ) */ + if ((q = strstr(raw->opt, "-tadj"))) { + sscanf(q, "-TADJ=%lf", &tadj); + } + dTowUTC = R8(p); + week = U2(p + 8); + gpsutcTimescale = R8(p + 10); + /* glonassutcTimescale = R8(p+18); */ + rcvTimeScaleCorr = I1(p + 26); + + /* check gps week range */ + if (week >= 4096) { + trace(2, "nvs xf5raw obs week error: week=%d\n", week); + return -1; + } + week = adjgpsweek(week); + + if ((raw->len - 31) % 30) { + /* Message length is not correct: there could be an error in the stream */ + trace(2, "nvs xf5raw len=%d seems not be correct\n", raw->len); + return -1; + } + nsat = (raw->len - 31) / 30; + + dTowGPS = dTowUTC + gpsutcTimescale; + + /* Tweak pseudoranges to allow Rinex to represent the NVS time of measure */ + dTowInt = 10.0 * floor((dTowGPS / 10.0) + 0.5); + dTowFrac = dTowGPS - (double)dTowInt; + time = gpst2time(week, dTowInt * 0.001); + + /* time tag adjustment */ + if (tadj > 0.0) { + tn = time2gpst(time, &week) / tadj; + toff = (tn - floor(tn + 0.5)) * tadj; + time = timeadd(time, -toff); + } + /* check time tag jump and output warning */ + if (raw->time.time && fabs(timediff(time, raw->time)) > 86400.0) { + time2str(time, tstr, 3); + trace(2, "nvs xf5raw time tag jump warning: time=%s\n", tstr); + } + if (fabs(timediff(time, raw->time)) <= 1e-3) { + time2str(time, tstr, 3); + trace(2, "nvs xf5raw time tag duplicated: time=%s\n", tstr); + return 0; + } + for (i = 0, p += 27; (i < nsat) && (n < MAXOBS); i++, p += 30) { + raw->obs.data[n].time = time; + sys = (U1(p) == 1) ? SYS_GLO : ((U1(p) == 2) ? SYS_GPS : ((U1(p) == 4) ? SYS_SBS : SYS_NONE)); + prn = U1(p + 1); + if (sys == SYS_SBS) prn += 120; /* Correct this */ + if (!(sat = satno(sys, prn))) { + trace(2, "nvs xf5raw satellite number error: sys=%d prn=%d\n", sys, prn); + continue; + } + carrNo = I1(p + 2); + L1 = R8(p + 4); + P1 = R8(p + 12); + D1 = R8(p + 20); + + /* check range error */ + if (L1 < -1E10 || L1 > 1E10 || P1 < -1E10 || P1 > 1E10 || D1 < -1E5 || D1 > 1E5) { + trace(2, "nvs xf5raw obs range error: sat=%2d L1=%12.5e P1=%12.5e D1=%12.5e\n", sat, L1, P1, + D1); + continue; + } + raw->obs.data[n].SNR[0] = I1(p + 3); + if (sys == SYS_GLO) { + raw->obs.data[n].L[0] = L1 - toff * (FREQ1_GLO + DFRQ1_GLO * carrNo); + } else { + raw->obs.data[n].L[0] = L1 - toff * FREQL1; + } + raw->obs.data[n].P[0] = + (P1 - dTowFrac) * CLIGHT * 0.001 - toff * CLIGHT; /* in ms, needs to be converted */ + raw->obs.data[n].D[0] = (float)D1; + + /* set LLI if meas flag 4 (carrier phase present) off -> on */ + flag = U1(p + 28); + raw->obs.data[n].LLI[0] = (flag & 0x08) && !(raw->halfc[sat - 1][0] & 0x08) ? 1 : 0; + raw->halfc[sat - 1][0] = flag; + + raw->obs.data[n].code[0] = CODE_L1C; + raw->obs.data[n].sat = sat; + + for (j = 1; j < NFREQ + NEXOBS; j++) { + raw->obs.data[n].L[j] = raw->obs.data[n].P[j] = 0.0; + raw->obs.data[n].D[j] = raw->obs.data[n].SNR[j] = 0.0; + raw->obs.data[n].LLI[j] = 0; + raw->obs.data[n].code[j] = CODE_NONE; + } + n++; + } + raw->time = time; + raw->obs.n = n; + return 1; } /* decode ephemeris ----------------------------------------------------------*/ -static int decode_gpsephem(int sat, raw_t *raw) -{ - eph_t eph={0}; - uint8_t *puiTmp = (raw->buff)+2; - uint16_t week; - double toc; - - trace(4,"decode_ephem: sat=%2d\n",sat); - - eph.crs = R4(&puiTmp[ 2]); - eph.deln = R4(&puiTmp[ 6]) * 1e+3; - eph.M0 = R8(&puiTmp[ 10]); - eph.cuc = R4(&puiTmp[ 18]); - eph.e = R8(&puiTmp[ 22]); - eph.cus = R4(&puiTmp[ 30]); - eph.A = pow(R8(&puiTmp[ 34]), 2); - eph.toes = R8(&puiTmp[ 42]) * 1e-3; - eph.cic = R4(&puiTmp[ 50]); - eph.OMG0 = R8(&puiTmp[ 54]); - eph.cis = R4(&puiTmp[ 62]); - eph.i0 = R8(&puiTmp[ 66]); - eph.crc = R4(&puiTmp[ 74]); - eph.omg = R8(&puiTmp[ 78]); - eph.OMGd = R8(&puiTmp[ 86]) * 1e+3; - eph.idot = R8(&puiTmp[ 94]) * 1e+3; - eph.tgd[0] = R4(&puiTmp[102]) * 1e-3; - toc = R8(&puiTmp[106]) * 1e-3; - eph.f2 = R4(&puiTmp[114]) * 1e+3; - eph.f1 = R4(&puiTmp[118]); - eph.f0 = R4(&puiTmp[122]) * 1e-3; - eph.sva = uraindex(I2(&puiTmp[126])); - eph.iode = I2(&puiTmp[128]); - eph.iodc = I2(&puiTmp[130]); - eph.code = I2(&puiTmp[132]); - eph.flag = I2(&puiTmp[134]); - week = I2(&puiTmp[136]); - eph.fit = 0; - - if (week>=4096) { - trace(2,"nvs gps ephemeris week error: sat=%2d week=%d\n",sat,week); - return -1; - } - eph.week=adjgpsweek(week); - eph.toe=gpst2time(eph.week,eph.toes); - eph.toc=gpst2time(eph.week,toc); - eph.ttr=raw->time; - - if (!strstr(raw->opt,"-EPHALL")) { - if (eph.iode==raw->nav.eph[sat-1].iode) return 0; /* unchanged */ - } - eph.sat=sat; - raw->nav.eph[sat-1]=eph; - raw->ephsat=sat; - raw->ephset=0; - return 2; +static int decode_gpsephem(int sat, raw_t *raw) { + eph_t eph = {0}; + uint8_t *puiTmp = (raw->buff) + 2; + uint16_t week; + double toc; + + trace(4, "decode_ephem: sat=%2d\n", sat); + + eph.crs = R4(&puiTmp[2]); + eph.deln = R4(&puiTmp[6]) * 1e+3; + eph.M0 = R8(&puiTmp[10]); + eph.cuc = R4(&puiTmp[18]); + eph.e = R8(&puiTmp[22]); + eph.cus = R4(&puiTmp[30]); + eph.A = pow(R8(&puiTmp[34]), 2); + eph.toes = R8(&puiTmp[42]) * 1e-3; + eph.cic = R4(&puiTmp[50]); + eph.OMG0 = R8(&puiTmp[54]); + eph.cis = R4(&puiTmp[62]); + eph.i0 = R8(&puiTmp[66]); + eph.crc = R4(&puiTmp[74]); + eph.omg = R8(&puiTmp[78]); + eph.OMGd = R8(&puiTmp[86]) * 1e+3; + eph.idot = R8(&puiTmp[94]) * 1e+3; + eph.tgd[0] = R4(&puiTmp[102]) * 1e-3; + toc = R8(&puiTmp[106]) * 1e-3; + eph.f2 = R4(&puiTmp[114]) * 1e+3; + eph.f1 = R4(&puiTmp[118]); + eph.f0 = R4(&puiTmp[122]) * 1e-3; + eph.sva = uraindex(I2(&puiTmp[126])); + eph.iode = I2(&puiTmp[128]); + eph.iodc = I2(&puiTmp[130]); + eph.code = I2(&puiTmp[132]); + eph.flag = I2(&puiTmp[134]); + week = I2(&puiTmp[136]); + eph.fit = 0; + + if (week >= 4096) { + trace(2, "nvs gps ephemeris week error: sat=%2d week=%d\n", sat, week); + return -1; + } + eph.week = adjgpsweek(week); + eph.toe = gpst2time(eph.week, eph.toes); + eph.toc = gpst2time(eph.week, toc); + eph.ttr = raw->time; + + if (!strstr(raw->opt, "-EPHALL")) { + if (eph.iode == raw->nav.eph[sat - 1].iode) return 0; /* unchanged */ + } + eph.sat = sat; + raw->nav.eph[sat - 1] = eph; + raw->ephsat = sat; + raw->ephset = 0; + return 2; } /* adjust daily rollover of time ---------------------------------------------*/ -static gtime_t adjday(gtime_t time, double tod) -{ - double ep[6],tod_p; - time2epoch(time,ep); - tod_p=ep[3]*3600.0+ep[4]*60.0+ep[5]; - if (todtod_p+43200.0) tod-=86400.0; - ep[3]=ep[4]=ep[5]=0.0; - return timeadd(epoch2time(ep),tod); +static gtime_t adjday(gtime_t time, double tod) { + double ep[6], tod_p; + time2epoch(time, ep); + tod_p = ep[3] * 3600.0 + ep[4] * 60.0 + ep[5]; + if (tod < tod_p - 43200.0) + tod += 86400.0; + else if (tod > tod_p + 43200.0) + tod -= 86400.0; + ep[3] = ep[4] = ep[5] = 0.0; + return timeadd(epoch2time(ep), tod); } /* decode gloephem -----------------------------------------------------------*/ -static int decode_gloephem(int sat, raw_t *raw) -{ - (void)sat; - geph_t geph={0}; - uint8_t *p=(raw->buff)+2; - int prn,tk,tb; - - if (raw->len>=93) { - prn =I1(p+ 1); - geph.frq =I1(p+ 2); - geph.pos[0]=R8(p+ 3); - geph.pos[1]=R8(p+11); - geph.pos[2]=R8(p+19); - geph.vel[0]=R8(p+27) * 1e+3; - geph.vel[1]=R8(p+35) * 1e+3; - geph.vel[2]=R8(p+43) * 1e+3; - geph.acc[0]=R8(p+51) * 1e+6; - geph.acc[1]=R8(p+59) * 1e+6; - geph.acc[2]=R8(p+67) * 1e+6; - tb = R8(p+75) * 1e-3; - tk = tb; - geph.gamn =R4(p+83); - geph.taun =R4(p+87) * 1e-3; - geph.age =I2(p+91); - } - else { - trace(2,"nvs NE length error: len=%d\n",raw->len); - return -1; - } - if (!(geph.sat=satno(SYS_GLO,prn))) { - trace(2,"nvs NE satellite error: prn=%d\n",prn); - return -1; - } - if (raw->time.time==0) return 0; - - geph.iode=(tb/900)&0x7F; - geph.toe=utc2gpst(adjday(raw->time,tb-10800.0)); - geph.tof=utc2gpst(adjday(raw->time,tk-10800.0)); +static int decode_gloephem(int sat, raw_t *raw) { + (void)sat; + geph_t geph = {0}; + uint8_t *p = (raw->buff) + 2; + int prn, tk, tb; + + if (raw->len >= 93) { + prn = I1(p + 1); + geph.frq = I1(p + 2); + geph.pos[0] = R8(p + 3); + geph.pos[1] = R8(p + 11); + geph.pos[2] = R8(p + 19); + geph.vel[0] = R8(p + 27) * 1e+3; + geph.vel[1] = R8(p + 35) * 1e+3; + geph.vel[2] = R8(p + 43) * 1e+3; + geph.acc[0] = R8(p + 51) * 1e+6; + geph.acc[1] = R8(p + 59) * 1e+6; + geph.acc[2] = R8(p + 67) * 1e+6; + tb = R8(p + 75) * 1e-3; + tk = tb; + geph.gamn = R4(p + 83); + geph.taun = R4(p + 87) * 1e-3; + geph.age = I2(p + 91); + } else { + trace(2, "nvs NE length error: len=%d\n", raw->len); + return -1; + } + if (!(geph.sat = satno(SYS_GLO, prn))) { + trace(2, "nvs NE satellite error: prn=%d\n", prn); + return -1; + } + if (raw->time.time == 0) return 0; + + geph.iode = (tb / 900) & 0x7F; + geph.toe = utc2gpst(adjday(raw->time, tb - 10800.0)); + geph.tof = utc2gpst(adjday(raw->time, tk - 10800.0)); #ifdef RTK_DISABLED - /* check illegal ephemeris by toe */ - double tt=timediff(raw->time,geph.toe); - if (fabs(tt)>3600.0) { - trace(3,"nvs NE illegal toe: prn=%2d tt=%6.0f\n",prn,tt); - return 0; - } + /* check illegal ephemeris by toe */ + double tt = timediff(raw->time, geph.toe); + if (fabs(tt) > 3600.0) { + trace(3, "nvs NE illegal toe: prn=%2d tt=%6.0f\n", prn, tt); + return 0; + } #endif #ifdef RTK_DISABLED - /* check illegal ephemeris by frequency number consistency */ - if (raw->nav.geph[prn-MINPRNGLO].toe.time&& - geph.frq!=raw->nav.geph[prn-MINPRNGLO].frq) { - trace(2,"nvs NE illegal freq change: prn=%2d frq=%2d->%2d\n",prn, - raw->nav.geph[prn-MINPRNGLO].frq,geph.frq); - return -1; - } - if (!strstr(raw->opt,"-EPHALL")) { - if (fabs(timediff(geph.toe,raw->nav.geph[prn-MINPRNGLO].toe))<1.0&& - geph.svh==raw->nav.geph[prn-MINPRNGLO].svh) return 0; - } + /* check illegal ephemeris by frequency number consistency */ + if (raw->nav.geph[prn - MINPRNGLO].toe.time && geph.frq != raw->nav.geph[prn - MINPRNGLO].frq) { + trace(2, "nvs NE illegal freq change: prn=%2d frq=%2d->%2d\n", prn, + raw->nav.geph[prn - MINPRNGLO].frq, geph.frq); + return -1; + } + if (!strstr(raw->opt, "-EPHALL")) { + if (fabs(timediff(geph.toe, raw->nav.geph[prn - MINPRNGLO].toe)) < 1.0 && + geph.svh == raw->nav.geph[prn - MINPRNGLO].svh) + return 0; + } #endif - raw->nav.geph[prn-1]=geph; - raw->ephsat=geph.sat; - raw->ephset=0; - - return 2; + raw->nav.geph[prn - 1] = geph; + raw->ephsat = geph.sat; + raw->ephset = 0; + + return 2; } /* decode NVS ephemerides in clear -------------------------------------------*/ -static int decode_xf7eph(raw_t *raw) -{ - int prn,sat,sys; - uint8_t *p=raw->buff; - - trace(4,"decode_xf7eph: len=%d\n",raw->len); - - if ((raw->len)<93) { - trace(2,"nvs xf7eph length error: len=%d\n",raw->len); - return -1; - } - sys = (U1(p+2)==1)?SYS_GPS:((U1(p+2)==2)?SYS_GLO:SYS_NONE); - prn = U1(p+3); - if (!(sat=satno(sys==1?SYS_GPS:SYS_GLO,prn))) { - trace(2,"nvs xf7eph satellite number error: prn=%d\n",prn); - return -1; - } - if (sys==SYS_GPS) { - return decode_gpsephem(sat,raw); - } - else if (sys==SYS_GLO) { - return decode_gloephem(sat,raw); - } - return 0; +static int decode_xf7eph(raw_t *raw) { + int prn, sat, sys; + uint8_t *p = raw->buff; + + trace(4, "decode_xf7eph: len=%d\n", raw->len); + + if ((raw->len) < 93) { + trace(2, "nvs xf7eph length error: len=%d\n", raw->len); + return -1; + } + sys = (U1(p + 2) == 1) ? SYS_GPS : ((U1(p + 2) == 2) ? SYS_GLO : SYS_NONE); + prn = U1(p + 3); + if (!(sat = satno(sys == 1 ? SYS_GPS : SYS_GLO, prn))) { + trace(2, "nvs xf7eph satellite number error: prn=%d\n", prn); + return -1; + } + if (sys == SYS_GPS) { + return decode_gpsephem(sat, raw); + } else if (sys == SYS_GLO) { + return decode_gloephem(sat, raw); + } + return 0; } /* decode NVS rxm-sfrb: subframe buffer --------------------------------------*/ -static int decode_xe5bit(raw_t *raw) -{ - int prn; - int iBlkStartIdx, iExpLen, iIdx; - uint32_t words[10]; - uint8_t uiDataBlocks, uiDataType; - uint8_t *p=raw->buff; - - trace(4,"decode_xe5bit: len=%d\n",raw->len); - - p += 2; /* Discard preamble and message identifier */ - uiDataBlocks = U1(p); - - if (uiDataBlocks>=16) { - trace(2,"nvs xf5bit message error: data blocks %u\n", uiDataBlocks); - return -1; - } - iBlkStartIdx = 1; - for (iIdx = 0; iIdx < uiDataBlocks; iIdx++) { - iExpLen = (iBlkStartIdx+10); - if ((raw->len) < iExpLen) { - trace(2,"nvs xf5bit message too short (expected at least %d)\n", iExpLen); - return -1; - } - uiDataType = U1(p+iBlkStartIdx+1); - - switch (uiDataType) { - case 1: /* Glonass */ - iBlkStartIdx += 19; - break; - case 2: /* GPS */ - iBlkStartIdx += 47; - break; - case 4: /* SBAS */ - prn = U1(p+(iBlkStartIdx+2)) + 120; - - /* sat = satno(SYS_SBS, prn); */ - /* sys = satsys(sat,&prn); */ - memset(words, 0, 10*sizeof(uint32_t)); - for (iIdx=0, iBlkStartIdx+=7; iIdx<10; iIdx++, iBlkStartIdx+=4) { - words[iIdx]=U4(p+iBlkStartIdx); - } - words[7] >>= 6; - return sbsdecodemsg(raw->time,prn,words,&raw->sbsmsg) ? 3 : 0; - default: - trace(2,"nvs xf5bit SNS type unknown (got %d)\n", uiDataType); - return -1; +static int decode_xe5bit(raw_t *raw) { + int prn; + int iBlkStartIdx, iExpLen, iIdx; + uint32_t words[10]; + uint8_t uiDataBlocks, uiDataType; + uint8_t *p = raw->buff; + + trace(4, "decode_xe5bit: len=%d\n", raw->len); + + p += 2; /* Discard preamble and message identifier */ + uiDataBlocks = U1(p); + + if (uiDataBlocks >= 16) { + trace(2, "nvs xf5bit message error: data blocks %u\n", uiDataBlocks); + return -1; + } + iBlkStartIdx = 1; + for (iIdx = 0; iIdx < uiDataBlocks; iIdx++) { + iExpLen = (iBlkStartIdx + 10); + if ((raw->len) < iExpLen) { + trace(2, "nvs xf5bit message too short (expected at least %d)\n", iExpLen); + return -1; + } + uiDataType = U1(p + iBlkStartIdx + 1); + + switch (uiDataType) { + case 1: /* Glonass */ + iBlkStartIdx += 19; + break; + case 2: /* GPS */ + iBlkStartIdx += 47; + break; + case 4: /* SBAS */ + prn = U1(p + (iBlkStartIdx + 2)) + 120; + + /* sat = satno(SYS_SBS, prn); */ + /* sys = satsys(sat,&prn); */ + memset(words, 0, 10 * sizeof(uint32_t)); + for (iIdx = 0, iBlkStartIdx += 7; iIdx < 10; iIdx++, iBlkStartIdx += 4) { + words[iIdx] = U4(p + iBlkStartIdx); } + words[7] >>= 6; + return sbsdecodemsg(raw->time, prn, words, &raw->sbsmsg) ? 3 : 0; + default: + trace(2, "nvs xf5bit SNS type unknown (got %d)\n", uiDataType); + return -1; } - return 0; + } + return 0; } /* decode NVS x4aiono --------------------------------------------------------*/ -static int decode_x4aiono(raw_t *raw) -{ - uint8_t *p=raw->buff+2; - - trace(4,"decode_x4aiono: len=%d\n", raw->len); - - raw->nav.ion_gps[0] = R4(p ); - raw->nav.ion_gps[1] = R4(p+ 4); - raw->nav.ion_gps[2] = R4(p+ 8); - raw->nav.ion_gps[3] = R4(p+12); - raw->nav.ion_gps[4] = R4(p+16); - raw->nav.ion_gps[5] = R4(p+20); - raw->nav.ion_gps[6] = R4(p+24); - raw->nav.ion_gps[7] = R4(p+28); - - return 9; +static int decode_x4aiono(raw_t *raw) { + uint8_t *p = raw->buff + 2; + + trace(4, "decode_x4aiono: len=%d\n", raw->len); + + raw->nav.ion_gps[0] = R4(p); + raw->nav.ion_gps[1] = R4(p + 4); + raw->nav.ion_gps[2] = R4(p + 8); + raw->nav.ion_gps[3] = R4(p + 12); + raw->nav.ion_gps[4] = R4(p + 16); + raw->nav.ion_gps[5] = R4(p + 20); + raw->nav.ion_gps[6] = R4(p + 24); + raw->nav.ion_gps[7] = R4(p + 28); + + return 9; } /* decode NVS x4btime --------------------------------------------------------*/ -static int decode_x4btime(raw_t *raw) -{ - uint8_t *p=raw->buff+2; - - trace(4,"decode_x4btime: len=%d\n", raw->len); - - raw->nav.utc_gps[1] = R8(p ); - raw->nav.utc_gps[0] = R8(p+ 8); - raw->nav.utc_gps[2] = I4(p+16); - raw->nav.utc_gps[3] = I2(p+20); - raw->nav.utc_gps[4] = I1(p+22); - - return 9; +static int decode_x4btime(raw_t *raw) { + uint8_t *p = raw->buff + 2; + + trace(4, "decode_x4btime: len=%d\n", raw->len); + + raw->nav.utc_gps[1] = R8(p); + raw->nav.utc_gps[0] = R8(p + 8); + raw->nav.utc_gps[2] = I4(p + 16); + raw->nav.utc_gps[3] = I2(p + 20); + raw->nav.utc_gps[4] = I1(p + 22); + + return 9; } /* decode NVS raw message ----------------------------------------------------*/ -static int decode_nvs(raw_t *raw) -{ - int type=U1(raw->buff+1); - - trace(3,"decode_nvs: type=%02x len=%d\n",type,raw->len); - - sprintf(raw->msgtype,"NVS: type=%2d len=%3d",type,raw->len); - - switch (type) { - case ID_XF5RAW: return decode_xf5raw (raw); - case ID_XF7EPH: return decode_xf7eph (raw); - case ID_XE5BIT: return decode_xe5bit (raw); - case ID_X4AIONO: return decode_x4aiono(raw); - case ID_X4BTIME: return decode_x4btime(raw); - default: break; - } - return 0; +static int decode_nvs(raw_t *raw) { + int type = U1(raw->buff + 1); + + trace(3, "decode_nvs: type=%02x len=%d\n", type, raw->len); + + sprintf(raw->msgtype, "NVS: type=%2d len=%3d", type, raw->len); + + switch (type) { + case ID_XF5RAW: + return decode_xf5raw(raw); + case ID_XF7EPH: + return decode_xf7eph(raw); + case ID_XE5BIT: + return decode_xe5bit(raw); + case ID_X4AIONO: + return decode_x4aiono(raw); + case ID_X4BTIME: + return decode_x4btime(raw); + default: + break; + } + return 0; } /* input NVS raw message from stream ------------------------------------------- -* fetch next NVS raw data and input a message from stream -* args : raw_t *raw IO receiver raw data control struct -* uint8_t data I stream data (1 byte) -* return : status (-1: error message, 0: no message, 1: input observation data, -* 2: input ephemeris, 3: input sbas message, -* 9: input ion/utc parameter) -* -* notes : to specify input options, set raw->opt to the following option -* strings separated by spaces. -* -* -EPHALL : input all ephemerides -* -TADJ=tint : adjust time tags to multiples of tint (sec) -* -*-----------------------------------------------------------------------------*/ -extern int input_nvs(raw_t *raw, uint8_t data) -{ - trace(5,"input_nvs: data=%02x\n",data); - - /* synchronize frame */ - if ((raw->nbyte==0) && (data==NVSSYNC)) { - - /* Search a 0x10 */ - raw->buff[0] = data; - raw->nbyte=1; - return 0; - } - if ((raw->nbyte==1) && (data != NVSSYNC) && (data != NVSENDMSG)) { - - /* Discard double 0x10 and 0x10 0x03 at beginning of frame */ - raw->buff[1]=data; - raw->nbyte=2; - raw->flag=0; - return 0; - } - /* This is all done to discard a double 0x10 */ - if (data==NVSSYNC) raw->flag = (raw->flag +1) % 2; - if ((data!=NVSSYNC) || (raw->flag)) { - - /* Store the new byte */ - raw->buff[(raw->nbyte++)] = data; - } - /* Detect ending sequence */ - if ((data==NVSENDMSG) && (raw->flag)) { - raw->len = raw->nbyte; - raw->nbyte = 0; - - /* Decode NVS raw message */ - return decode_nvs(raw); - } - if (raw->nbyte == MAXRAWLEN) { - trace(2,"nvs message size error: len=%d\n",raw->nbyte); - raw->nbyte=0; - return -1; - } + * fetch next NVS raw data and input a message from stream + * args : raw_t *raw IO receiver raw data control struct + * uint8_t data I stream data (1 byte) + * return : status (-1: error message, 0: no message, 1: input observation data, + * 2: input ephemeris, 3: input sbas message, + * 9: input ion/utc parameter) + * + * notes : to specify input options, set raw->opt to the following option + * strings separated by spaces. + * + * -EPHALL : input all ephemerides + * -TADJ=tint : adjust time tags to multiples of tint (sec) + * + *-----------------------------------------------------------------------------*/ +extern int input_nvs(raw_t *raw, uint8_t data) { + trace(5, "input_nvs: data=%02x\n", data); + + /* synchronize frame */ + if ((raw->nbyte == 0) && (data == NVSSYNC)) { + /* Search a 0x10 */ + raw->buff[0] = data; + raw->nbyte = 1; return 0; -} -/* input NVS raw message from file --------------------------------------------- -* fetch next NVS raw data and input a message from file -* args : raw_t *raw IO receiver raw data control struct -* FILE *fp I file pointer -* return : status(-2: end of file, -1...9: same as above) -*-----------------------------------------------------------------------------*/ -extern int input_nvsf(raw_t *raw, FILE *fp) -{ - int i,data, odd=0; - - trace(4,"input_nvsf:\n"); - - /* synchronize frame */ - for (i=0;;i++) { - if ((data=fgetc(fp))==EOF) return -2; - - /* Search a 0x10 */ - if (data==NVSSYNC) { - - /* Store the frame begin */ - raw->buff[0] = data; - if ((data=fgetc(fp))==EOF) return -2; - - /* Discard double 0x10 and 0x10 0x03 */ - if ((data != NVSSYNC) && (data != NVSENDMSG)) { - raw->buff[1]=data; - break; - } - } - if (i>=4096) return 0; - } + } + if ((raw->nbyte == 1) && (data != NVSSYNC) && (data != NVSENDMSG)) { + /* Discard double 0x10 and 0x10 0x03 at beginning of frame */ + raw->buff[1] = data; raw->nbyte = 2; - for (i=0;;i++) { - if ((data=fgetc(fp))==EOF) return -2; - if (data==NVSSYNC) odd=(odd+1)%2; - if ((data!=NVSSYNC) || odd) { - - /* Store the new byte */ - raw->buff[(raw->nbyte++)] = data; - } - /* Detect ending sequence */ - if ((data==NVSENDMSG) && odd) break; - if (i>=4096) return 0; - } + raw->flag = 0; + return 0; + } + /* This is all done to discard a double 0x10 */ + if (data == NVSSYNC) raw->flag = (raw->flag + 1) % 2; + if ((data != NVSSYNC) || (raw->flag)) { + /* Store the new byte */ + raw->buff[(raw->nbyte++)] = data; + } + /* Detect ending sequence */ + if ((data == NVSENDMSG) && (raw->flag)) { raw->len = raw->nbyte; - if ((raw->len) > MAXRAWLEN) { - trace(2,"nvs length error: len=%d\n",raw->len); - return -1; - } - /* decode nvs raw message */ + raw->nbyte = 0; + + /* Decode NVS raw message */ return decode_nvs(raw); + } + if (raw->nbyte == MAXRAWLEN) { + trace(2, "nvs message size error: len=%d\n", raw->nbyte); + raw->nbyte = 0; + return -1; + } + return 0; } -/* generate NVS binary message ------------------------------------------------- -* generate NVS binary message from message string -* args : char *msg I message string -* "RESTART [arg...]" system reset -* "CFG-SERI [arg...]" configure serial port property -* "CFG-FMT [arg...]" configure output message format -* "CFG-RATE [arg...]" configure binary measurement output rates -* uint8_t *buff O binary message -* return : length of binary message (0: error) -* note : see reference [1][2] for details. -*-----------------------------------------------------------------------------*/ -extern int gen_nvs(const char *msg, uint8_t *buff) -{ - uint8_t *q=buff; - char mbuff[1024],*args[32],*p; - uint32_t byte; - int iRate,n,narg=0; - uint8_t ui100Ms; - - trace(4,"gen_nvs: msg=%s\n",msg); - - strcpy(mbuff,msg); - char *r; - for (p=strtok_r(mbuff," ",&r);p&&narg<32;p=strtok_r(NULL," ",&r)) { - args[narg++]=p; - } - if (narg<1) { - return 0; - } - *q++=NVSSYNC; /* DLE */ - - if (!strcmp(args[0],"CFG-PVTRATE")) { - *q++=ID_XD7ADVANCED; - *q++=ID_X02RATEPVT; - if (narg>1) { - iRate = atoi(args[1]); - *q++ = (uint8_t) iRate; - } - } - else if (!strcmp(args[0],"CFG-RAWRATE")) { - *q++=ID_XF4RATERAW; - if (narg>1) { - iRate = atoi(args[1]); - switch(iRate) { - case 2: ui100Ms = 5; break; - case 5: ui100Ms = 2; break; - case 10: ui100Ms = 1; break; - default: ui100Ms = 10; break; - } - *q++ = ui100Ms; - } - } - else if (!strcmp(args[0],"CFG-SMOOTH")) { - *q++=ID_XD7SMOOTH; - *q++ = 0x03; - *q++ = 0x01; - *q++ = 0x00; - } - else if (!strcmp(args[0],"CFG-BINR")) { - for (n=1;(nbuff[0] = data; + if ((data = fgetc(fp)) == EOF) return -2; + + /* Discard double 0x10 and 0x10 0x03 */ + if ((data != NVSSYNC) && (data != NVSENDMSG)) { + raw->buff[1] = data; + break; + } + } + if (i >= 4096) return 0; + } + raw->nbyte = 2; + for (i = 0;; i++) { + if ((data = fgetc(fp)) == EOF) return -2; + if (data == NVSSYNC) odd = (odd + 1) % 2; + if ((data != NVSSYNC) || odd) { + /* Store the new byte */ + raw->buff[(raw->nbyte++)] = data; } - else return 0; - - n=(int)(q-buff); - - *q++=0x10; /* ETX */ - *q=0x03; /* DLE */ - return n+2; + /* Detect ending sequence */ + if ((data == NVSENDMSG) && odd) break; + if (i >= 4096) return 0; + } + raw->len = raw->nbyte; + if ((raw->len) > MAXRAWLEN) { + trace(2, "nvs length error: len=%d\n", raw->len); + return -1; + } + /* decode nvs raw message */ + return decode_nvs(raw); +} +/* generate NVS binary message ------------------------------------------------- + * generate NVS binary message from message string + * args : char *msg I message string + * "RESTART [arg...]" system reset + * "CFG-SERI [arg...]" configure serial port property + * "CFG-FMT [arg...]" configure output message format + * "CFG-RATE [arg...]" configure binary measurement output rates + * uint8_t *buff O binary message + * return : length of binary message (0: error) + * note : see reference [1][2] for details. + *-----------------------------------------------------------------------------*/ +extern int gen_nvs(const char *msg, uint8_t *buff) { + uint8_t *q = buff; + char mbuff[1024], *args[32], *p; + uint32_t byte; + int iRate, n, narg = 0; + uint8_t ui100Ms; + + trace(4, "gen_nvs: msg=%s\n", msg); + + strcpy(mbuff, msg); + char *r; + for (p = strtok_r(mbuff, " ", &r); p && narg < 32; p = strtok_r(NULL, " ", &r)) { + args[narg++] = p; + } + if (narg < 1) { + return 0; + } + *q++ = NVSSYNC; /* DLE */ + + if (!strcmp(args[0], "CFG-PVTRATE")) { + *q++ = ID_XD7ADVANCED; + *q++ = ID_X02RATEPVT; + if (narg > 1) { + iRate = atoi(args[1]); + *q++ = (uint8_t)iRate; + } + } else if (!strcmp(args[0], "CFG-RAWRATE")) { + *q++ = ID_XF4RATERAW; + if (narg > 1) { + iRate = atoi(args[1]); + switch (iRate) { + case 2: + ui100Ms = 5; + break; + case 5: + ui100Ms = 2; + break; + case 10: + ui100Ms = 1; + break; + default: + ui100Ms = 10; + break; + } + *q++ = ui100Ms; + } + } else if (!strcmp(args[0], "CFG-SMOOTH")) { + *q++ = ID_XD7SMOOTH; + *q++ = 0x03; + *q++ = 0x01; + *q++ = 0x00; + } else if (!strcmp(args[0], "CFG-BINR")) { + for (n = 1; (n < narg); n++) { + if (sscanf(args[n], "%2x", &byte)) *q++ = (uint8_t)byte; + } + } else + return 0; + + n = (int)(q - buff); + + *q++ = 0x10; /* ETX */ + *q = 0x03; /* DLE */ + return n + 2; } diff --git a/src/rcv/rt17.c b/src/rcv/rt17.c index 10e41643c..ab54e91b2 100644 --- a/src/rcv/rt17.c +++ b/src/rcv/rt17.c @@ -1,32 +1,32 @@ /*------------------------------------------------------------------------------ -* rt17.c : Trimble RT-17 dependent functions -* -* Copyright (C) 2016 Daniel A. Cook, All rights reserved. -* Copyright (C) 2020 T.TAKASU, All rights reserved. -* -* references: -* [1] https://github.com/astrodanco/RTKLIB/tree/cmr/src/rcv/rt17.c -* [2] Trimble, Trimble OEM BD9xx GNSS Receiver Family IDC, version 4.82 -* Revision A, December, 2013 -* -* version : $Revision:$ $Date:$ -* history : 2014/08/26 1.0 imported from GitHub (ref [1]) -* modified to get initial week number -* modified obs types for raw obs data -* function added to output message type -* 2014/09/06 1.1 Remove prehistorical revision history -* Remove dead code -* Fix len vs. plen typo -* Check week/time valid flag in GSOF 16 message -* Set time when reading GSOF messages, where possible. -* 2016/06/16 1.2 Refactored -* 2016/07/16 1.3 modified by T.T -* raw->strfmt -> raw->format -* int free_rt17() -> void free_rt17() -* 2016/07/29 1.4 suppress warning -* 2017/04/11 1.5 (char *) -> (signed char *) -* 2020/11/30 1.6 use integer type in stdint.h -*-----------------------------------------------------------------------------*/ + * rt17.c : Trimble RT-17 dependent functions + * + * Copyright (C) 2016 Daniel A. Cook, All rights reserved. + * Copyright (C) 2020 T.TAKASU, All rights reserved. + * + * references: + * [1] https://github.com/astrodanco/RTKLIB/tree/cmr/src/rcv/rt17.c + * [2] Trimble, Trimble OEM BD9xx GNSS Receiver Family IDC, version 4.82 + * Revision A, December, 2013 + * + * version : $Revision:$ $Date:$ + * history : 2014/08/26 1.0 imported from GitHub (ref [1]) + * modified to get initial week number + * modified obs types for raw obs data + * function added to output message type + * 2014/09/06 1.1 Remove prehistorical revision history + * Remove dead code + * Fix len vs. plen typo + * Check week/time valid flag in GSOF 16 message + * Set time when reading GSOF messages, where possible. + * 2016/06/16 1.2 Refactored + * 2016/07/16 1.3 modified by T.T + * raw->strfmt -> raw->format + * int free_rt17() -> void free_rt17() + * 2016/07/29 1.4 suppress warning + * 2017/04/11 1.5 (char *) -> (signed char *) + * 2020/11/30 1.6 use integer type in stdint.h + *-----------------------------------------------------------------------------*/ /* | Trimble real-time binary data stream and file handler functions. @@ -88,7 +88,7 @@ | Format Data Ephemerides Parameters GSOF | ------- --------------- ---------------- ---------------- ------------ | Trimble 0x57 (RAWDATA) 0x55 (RETSVDATA) 0x55 (RETSVDATA) 1, 16, -| RT-17 Recordtype 0 & 7 Subtype 1 Subtype 3 26, 41 +| RT-17 Recordtype 0 & 7 Subtype 1 Subtype 3 26, 41 | | When the -WEEK=n option is NOT used, the GPS week number is set from any | RAWDATA record type 7 or GENOUT (GSOF) 1, 16, 26, 41 records encountered @@ -183,7 +183,7 @@ | into the file. | | Therefore it is assumed that: -| +| | 1. RAWDATA and GENOUT packets are never interleaved or interspersed | with packets of other types. | @@ -266,36 +266,39 @@ #define M_BIT15 (1 << 15) /* Constant definitions: */ -#define STX 2 /* Start of packet character */ -#define ETX 3 /* End of packet character */ -#define GENOUT 0x40 /* General Serial Output Format (GSOF) */ -#define RETSVDATA 0x55 /* Satellite information reports */ -#define RAWDATA 0x57 /* Position or real-time survey data report */ -#define MBUFF_LENGTH 8192 /* Message buffer length */ -#define PBUFF_LENGTH (4+255+2) /* Packet buffer length */ +#define STX 2 /* Start of packet character */ +#define ETX 3 /* End of packet character */ +#define GENOUT 0x40 /* General Serial Output Format (GSOF) */ +#define RETSVDATA 0x55 /* Satellite information reports */ +#define RAWDATA 0x57 /* Position or real-time survey data report */ +#define MBUFF_LENGTH 8192 /* Message buffer length */ +#define PBUFF_LENGTH (4 + 255 + 2) /* Packet buffer length */ /* Record Interpretation Flags bit masks: */ -#define M_CONCISE M_BIT0 /* Concise format */ -#define M_ENHANCED M_BIT1 /* Enhanced record with real-time flags and IODE information */ +#define M_CONCISE M_BIT0 /* Concise format */ +#define M_ENHANCED M_BIT1 /* Enhanced record with real-time flags and IODE information */ /* rt17.flag bit definitions: */ -#define M_WEEK_OPTION M_BIT0 /* GPS week number set by WEEK=n option */ -#define M_WEEK_EPH M_BIT1 /* GPS week number set by ephemeris week */ -#define M_WEEK_TIME M_BIT2 /* GPS week set by computer time */ -#define M_WEEK_SCAN M_BIT3 /* WEEK=n option already looked for, no need to do it again */ +#define M_WEEK_OPTION M_BIT0 /* GPS week number set by WEEK=n option */ +#define M_WEEK_EPH M_BIT1 /* GPS week number set by ephemeris week */ +#define M_WEEK_TIME M_BIT2 /* GPS week set by computer time */ +#define M_WEEK_SCAN M_BIT3 /* WEEK=n option already looked for, no need to do it again */ /* Data conversion macros: */ -#define I1(p) (*((int8_t *)(p))) /* One byte signed integer */ -#define U1(p) (*((uint8_t *)(p))) /* One byte uint32_teger */ -#define I2(p) ReadI2(p) /* Two byte signed integer */ -#define U2(p) ReadU2(p) /* Two byte uint32_teger */ -#define I4(p) ReadI4(p) /* Four byte signed integer */ -#define U4(p) ReadU4(p) /* Four byte uint32_teger */ -#define R4(p) ReadR4(p) /* IEEE S_FLOAT floating point number */ -#define R8(p) ReadR8(p) /* IEEE T_FLOAT floating point number */ +#define I1(p) (*((int8_t *)(p))) /* One byte signed integer */ +#define U1(p) (*((uint8_t *)(p))) /* One byte uint32_teger */ +#define I2(p) ReadI2(p) /* Two byte signed integer */ +#define U2(p) ReadU2(p) /* Two byte uint32_teger */ +#define I4(p) ReadI4(p) /* Four byte signed integer */ +#define U4(p) ReadU4(p) /* Four byte uint32_teger */ +#define R4(p) ReadR4(p) /* IEEE S_FLOAT floating point number */ +#define R8(p) ReadR8(p) /* IEEE T_FLOAT floating point number */ /* Internal structure definitions. */ -typedef union {uint16_t u2; uint8_t c[2];} ENDIAN_TEST; +typedef union { + uint16_t u2; + uint8_t c[2]; +} ENDIAN_TEST; /* GENOUT 0x40 message types: */ static const char *GSOFTable[] = { @@ -340,8 +343,7 @@ static const char *GSOFTable[] = { /* 38 */ NULL, /* 39 */ NULL, /* 40 */ "L-Band Status Information", - /* 41 */ "Base Position and Quality Indicator" -}; + /* 41 */ "Base Position and Quality Indicator"}; /* RAWDATA 0x57 message types: */ static const char *RawdataTable[] = { @@ -352,8 +354,7 @@ static const char *RawdataTable[] = { /* 04 */ NULL, /* 05 */ NULL, /* 06 */ "Real-time GNSS Survey Data, type 27", - /* 07 */ "Enhanced Position Record, type 29" -}; + /* 07 */ "Enhanced Position Record, type 29"}; /* RETSVDATA 0x55 message types: */ static const char *RetsvdataTable[] = { @@ -379,25 +380,24 @@ static const char *RetsvdataTable[] = { /* 19 */ NULL, /* 20 */ "SV Flags", /* 21 */ "BeiDou Ephemeris", - /* 22 */ "BeiDou Almanac" -}; + /* 22 */ "BeiDou Almanac"}; /* | Typedefs. */ -typedef struct { /* RT17 information struct type */ - uint8_t *MessageBuffer; /* Message buffer */ - uint8_t *PacketBuffer; /* Packet buffer */ - double Tow; /* Receive time of week */ - uint32_t Flags; /* Miscellaneous internal flag bits */ - uint32_t MessageBytes; /* Number of bytes in message buffer */ - uint32_t MessageLength; /* Message length (bytes) */ - uint32_t PacketBytes; /* How many packet bytes have been read so far */ - uint32_t PacketLength; /* Total size of packet to be read */ - uint32_t Page; /* Last page number */ - uint32_t Reply; /* Current reply number */ - int Week; /* GPS week number */ +typedef struct { /* RT17 information struct type */ + uint8_t *MessageBuffer; /* Message buffer */ + uint8_t *PacketBuffer; /* Packet buffer */ + double Tow; /* Receive time of week */ + uint32_t Flags; /* Miscellaneous internal flag bits */ + uint32_t MessageBytes; /* Number of bytes in message buffer */ + uint32_t MessageLength; /* Message length (bytes) */ + uint32_t PacketBytes; /* How many packet bytes have been read so far */ + uint32_t PacketLength; /* Total size of packet to be read */ + uint32_t Page; /* Last page number */ + uint32_t Reply; /* Current reply number */ + int Week; /* GPS week number */ } rt17_t; /* @@ -438,72 +438,62 @@ static void UnwrapGenout(rt17_t *rt17); /* Public functions (in alphabetical order): */ /* free_rt17 - Free up RT17 dependent private storage */ -EXPORT void free_rt17(raw_t *Raw) -{ - rt17_t *rt17 = NULL; - - if (Raw->format != STRFMT_RT17) - return; - - if ((rt17 = (rt17_t*) Raw->rcv_data)) - { - if (rt17->MessageBuffer) - { - memset(rt17->MessageBuffer, 0, MBUFF_LENGTH); - free(rt17->MessageBuffer); - rt17->MessageBuffer = NULL; - } - - if (rt17->PacketBuffer) - { - memset(rt17->PacketBuffer, 0, PBUFF_LENGTH); - free(rt17->PacketBuffer); - rt17->PacketBuffer = NULL; - } - - memset(rt17, 0, sizeof(rt17_t)); - free(rt17); - Raw->rcv_data = NULL; +EXPORT void free_rt17(raw_t *Raw) { + rt17_t *rt17 = NULL; + + if (Raw->format != STRFMT_RT17) return; + + if ((rt17 = (rt17_t *)Raw->rcv_data)) { + if (rt17->MessageBuffer) { + memset(rt17->MessageBuffer, 0, MBUFF_LENGTH); + free(rt17->MessageBuffer); + rt17->MessageBuffer = NULL; } + + if (rt17->PacketBuffer) { + memset(rt17->PacketBuffer, 0, PBUFF_LENGTH); + free(rt17->PacketBuffer); + rt17->PacketBuffer = NULL; + } + + memset(rt17, 0, sizeof(rt17_t)); + free(rt17); + Raw->rcv_data = NULL; + } } /* init_rt17 = Initialize RT17 dependent private storage */ -EXPORT int init_rt17(raw_t *Raw) -{ - rt17_t *rt17 = NULL; - uint8_t *MessageBuffer = NULL, *PacketBuffer = NULL; - - if (Raw->format != STRFMT_RT17) - return 0; - - if (!(rt17 = (rt17_t*) calloc(1, sizeof(rt17_t)))) - { - tracet(0, "RT17: unable to allocate RT17 dependent private data structure.\n"); - return 0; - } - Raw->rcv_data = (void*) rt17; - - if (!(MessageBuffer = (uint8_t*) calloc(MBUFF_LENGTH, sizeof(uint8_t)))) - { - tracet(0, "RT17: unable to allocate RT17 message buffer.\n"); - free_rt17(Raw); - return 0; - } - rt17->MessageBuffer = MessageBuffer; +EXPORT int init_rt17(raw_t *Raw) { + rt17_t *rt17 = NULL; + uint8_t *MessageBuffer = NULL, *PacketBuffer = NULL; - if (!(PacketBuffer = (uint8_t*) calloc(PBUFF_LENGTH, sizeof(uint8_t)))) - { - tracet(0, "RT17: unable to allocate RT17 packet buffer.\n"); - free_rt17(Raw); - return 0; - } - rt17->PacketBuffer = PacketBuffer; + if (Raw->format != STRFMT_RT17) return 0; - return 1; + if (!(rt17 = (rt17_t *)calloc(1, sizeof(rt17_t)))) { + tracet(0, "RT17: unable to allocate RT17 dependent private data structure.\n"); + return 0; + } + Raw->rcv_data = (void *)rt17; + + if (!(MessageBuffer = (uint8_t *)calloc(MBUFF_LENGTH, sizeof(uint8_t)))) { + tracet(0, "RT17: unable to allocate RT17 message buffer.\n"); + free_rt17(Raw); + return 0; + } + rt17->MessageBuffer = MessageBuffer; + + if (!(PacketBuffer = (uint8_t *)calloc(PBUFF_LENGTH, sizeof(uint8_t)))) { + tracet(0, "RT17: unable to allocate RT17 packet buffer.\n"); + free_rt17(Raw); + return 0; + } + rt17->PacketBuffer = PacketBuffer; + + return 1; } /* -| input_rt17 - Read an RT-17 mesasge from a raw data stream +| input_rt17 - Read an RT-17 mesasge from a raw data stream | | Returns: | @@ -517,204 +507,188 @@ EXPORT int init_rt17(raw_t *Raw) | and the packet ends with a 2-byte trailer. Byte 3 is set to 0 (00h) when the packet | contains no data. */ -EXPORT int input_rt17(raw_t *Raw, uint8_t Data) -{ - rt17_t *rt17 = (rt17_t*) Raw->rcv_data; - uint8_t *MessageBuffer = rt17->MessageBuffer; - uint8_t *PacketBuffer = rt17->PacketBuffer; - uint32_t Page, Pages, Reply; - int Ret = 0; - - /* If no current packet */ - if (rt17->PacketBytes == 0) - { - /* Find something that looks like a packet. */ - if (SyncPacket(rt17, Data)) - { - /* Found one. */ - rt17->PacketLength = 4 + PacketBuffer[3] + 2; /* 4 (header) + length + 2 (trailer) */ - rt17->PacketBytes = 4; /* We now have four bytes in the packet buffer */ - } - - /* Continue reading the rest of the packet from the stream */ - return 0; +EXPORT int input_rt17(raw_t *Raw, uint8_t Data) { + rt17_t *rt17 = (rt17_t *)Raw->rcv_data; + uint8_t *MessageBuffer = rt17->MessageBuffer; + uint8_t *PacketBuffer = rt17->PacketBuffer; + uint32_t Page, Pages, Reply; + int Ret = 0; + + /* If no current packet */ + if (rt17->PacketBytes == 0) { + /* Find something that looks like a packet. */ + if (SyncPacket(rt17, Data)) { + /* Found one. */ + rt17->PacketLength = 4 + PacketBuffer[3] + 2; /* 4 (header) + length + 2 (trailer) */ + rt17->PacketBytes = 4; /* We now have four bytes in the packet buffer */ } - /* Store the next byte of the packet */ - PacketBuffer[rt17->PacketBytes++] = Data; + /* Continue reading the rest of the packet from the stream */ + return 0; + } + + /* Store the next byte of the packet */ + PacketBuffer[rt17->PacketBytes++] = Data; + + /* + | Keep storing bytes into the current packet + | until we have what we think are all of them. + */ + if (rt17->PacketBytes < rt17->PacketLength) return 0; + + /* + | At this point we think have an entire packet. + | The prospective packet must end with an ETX. + */ + if (rt17->PacketBuffer[rt17->PacketLength - 1] != ETX) { + tracet(2, "RT17: Prospective packet did not end with an ETX character. Some data lost.\n"); + ClearPacketBuffer(rt17); + return 0; + } + + /* + | We do indeed have an entire packet. + | Check the packet checksum. + */ + if (!CheckPacketChecksum(PacketBuffer)) { + tracet(2, "RT17: Packet checksum failure. Packet discarded.\n"); + ClearPacketBuffer(rt17); + return 0; + } + + if (Raw->outtype) sprintf(Raw->msgtype, "RT17 0x%02X (%4u)", PacketBuffer[2], rt17->PacketLength); - /* - | Keep storing bytes into the current packet - | until we have what we think are all of them. - */ - if (rt17->PacketBytes < rt17->PacketLength) - return 0; + /* If this is a SVDATA packet, then process it immediately */ + if (PacketBuffer[2] == RETSVDATA) { + Ret = DecodeRetsvdata(Raw); + ClearPacketBuffer(rt17); + return Ret; + } + + /* Accumulate a sequence of RAWDATA packets (pages) */ + if (PacketBuffer[2] == RAWDATA) { + Page = PacketBuffer[5] >> 4; + Pages = PacketBuffer[5] & 15; + Reply = PacketBuffer[6]; /* - | At this point we think have an entire packet. - | The prospective packet must end with an ETX. + | If this is the first RAWDATA packet in a sequence of RAWDATA packets, + | then make sure it's page one and not a packet somewhere in the middle. + | If not page one, then skip it and continue reading from the stream + | until we find one that starts at page one. Otherwise make sure it is + | a part of the same requence of packets as the last one, that it's + | page number is in sequence. */ - if (rt17->PacketBuffer[rt17->PacketLength-1] != ETX) - { - tracet(2, "RT17: Prospective packet did not end with an ETX character. Some data lost.\n"); + if (rt17->MessageBytes == 0) { + if (Page != 1) { + tracet(2, "RT17: First RAWDATA packet is not page #1. Packet discarded.\n"); ClearPacketBuffer(rt17); return 0; + } + + rt17->Reply = PacketBuffer[6]; + } else if ((Reply != rt17->Reply) || (Page != (rt17->Page + 1))) { + tracet(2, + "RT17: RAWDATA packet sequence number mismatch or page out of order. %u RAWDATA " + "packets discarded.\n", + Page); + ClearMessageBuffer(rt17); + ClearPacketBuffer(rt17); + return 0; } - /* - | We do indeed have an entire packet. - | Check the packet checksum. - */ - if (!CheckPacketChecksum(PacketBuffer)) - { - tracet(2, "RT17: Packet checksum failure. Packet discarded.\n"); - ClearPacketBuffer(rt17); - return 0; + /* Check for message buffer overflow */ + if ((rt17->MessageBytes + rt17->PacketBytes) > MBUFF_LENGTH) { + tracet(2, "RT17: Buffer would overflow. %u RAWDATA packets discarded.\n", Page); + ClearMessageBuffer(rt17); + ClearPacketBuffer(rt17); + return 0; } - if (Raw->outtype) - sprintf(Raw->msgtype, "RT17 0x%02X (%4u)", PacketBuffer[2], rt17->PacketLength); + memcpy(MessageBuffer + rt17->MessageBytes, PacketBuffer, rt17->PacketBytes); + rt17->MessageBytes += rt17->PacketBytes; + rt17->MessageLength += rt17->PacketLength; + ClearPacketBuffer(rt17); - /* If this is a SVDATA packet, then process it immediately */ - if (PacketBuffer[2] == RETSVDATA) - { - Ret = DecodeRetsvdata(Raw); - ClearPacketBuffer(rt17); - return Ret; + if (Page == Pages) { + Ret = DecodeRawdata(Raw); + ClearMessageBuffer(rt17); + return Ret; } - - /* Accumulate a sequence of RAWDATA packets (pages) */ - if (PacketBuffer[2] == RAWDATA) - { - Page = PacketBuffer[5] >> 4; - Pages = PacketBuffer[5] & 15; - Reply = PacketBuffer[6]; - /* - | If this is the first RAWDATA packet in a sequence of RAWDATA packets, - | then make sure it's page one and not a packet somewhere in the middle. - | If not page one, then skip it and continue reading from the stream - | until we find one that starts at page one. Otherwise make sure it is - | a part of the same requence of packets as the last one, that it's - | page number is in sequence. - */ - if (rt17->MessageBytes == 0) - { - if (Page != 1) - { - tracet(2, "RT17: First RAWDATA packet is not page #1. Packet discarded.\n"); - ClearPacketBuffer(rt17); - return 0; - } - - rt17->Reply = PacketBuffer[6]; - } - else if ((Reply != rt17->Reply) || (Page != (rt17->Page + 1))) - { - tracet(2, "RT17: RAWDATA packet sequence number mismatch or page out of order. %u RAWDATA packets discarded.\n", Page); - ClearMessageBuffer(rt17); - ClearPacketBuffer(rt17); - return 0; - } - - /* Check for message buffer overflow */ - if ((rt17->MessageBytes + rt17->PacketBytes) > MBUFF_LENGTH) - { - tracet(2, "RT17: Buffer would overflow. %u RAWDATA packets discarded.\n", Page); - ClearMessageBuffer(rt17); - ClearPacketBuffer(rt17); - return 0; - } - - memcpy(MessageBuffer + rt17->MessageBytes, PacketBuffer, rt17->PacketBytes); - rt17->MessageBytes += rt17->PacketBytes; - rt17->MessageLength += rt17->PacketLength; - ClearPacketBuffer(rt17); + rt17->Page = Page; - if (Page == Pages) - { - Ret = DecodeRawdata(Raw); - ClearMessageBuffer(rt17); - return Ret; - } + return 0; + } - rt17->Page = Page; + /* Accumulate a sequence of GENOUT (GSOF) packets (pages) */ + if (PacketBuffer[2] == GENOUT) { + Reply = PacketBuffer[4]; + Page = PacketBuffer[5]; + Pages = PacketBuffer[6]; + /* + | If this is the first GENOUT packet in a sequence of GENOUT packets, + | then make sure it's page zero and not a packet somewhere in the middle. + | If not page zero, then skip it and continue reading from the stream + | until we find one that starts at page zero. Otherwise make sure it is + | a part of the same requence of packets as the last one, that it's + | page number is in sequence. + */ + if (rt17->MessageBytes == 0) { + if (Page != 0) { + tracet(3, "RT17: First GENOUT packet is not page #0. Packet discarded.\n"); + ClearPacketBuffer(rt17); return 0; + } + + rt17->Reply = PacketBuffer[4]; + } else if ((Reply != rt17->Reply) || (Page != (rt17->Page + 1))) { + tracet(2, + "RT17: GENOUT packet sequence number mismatch or page out of order. %u GENOUT packets " + "discarded.\n", + Page); + ClearMessageBuffer(rt17); + ClearPacketBuffer(rt17); + return 0; } - /* Accumulate a sequence of GENOUT (GSOF) packets (pages) */ - if (PacketBuffer[2] == GENOUT) - { - Reply = PacketBuffer[4]; - Page = PacketBuffer[5]; - Pages = PacketBuffer[6]; - - /* - | If this is the first GENOUT packet in a sequence of GENOUT packets, - | then make sure it's page zero and not a packet somewhere in the middle. - | If not page zero, then skip it and continue reading from the stream - | until we find one that starts at page zero. Otherwise make sure it is - | a part of the same requence of packets as the last one, that it's - | page number is in sequence. - */ - if (rt17->MessageBytes == 0) - { - if (Page != 0) - { - tracet(3, "RT17: First GENOUT packet is not page #0. Packet discarded.\n"); - ClearPacketBuffer(rt17); - return 0; - } - - rt17->Reply = PacketBuffer[4]; - } - else if ((Reply != rt17->Reply) || (Page != (rt17->Page + 1))) - { - tracet(2, "RT17: GENOUT packet sequence number mismatch or page out of order. %u GENOUT packets discarded.\n", Page); - ClearMessageBuffer(rt17); - ClearPacketBuffer(rt17); - return 0; - } - - /* Check for message buffer overflow. */ - if ((rt17->MessageBytes + rt17->PacketBytes) > MBUFF_LENGTH) - { - tracet(2, "RT17: Buffer would overflow. %u GENOUT packets discarded.\n", Page); - ClearMessageBuffer(rt17); - ClearPacketBuffer(rt17); - return 0; - } - - memcpy(MessageBuffer + rt17->MessageBytes, PacketBuffer, rt17->PacketBytes); - rt17->MessageBytes += rt17->PacketBytes; - rt17->MessageLength += rt17->PacketLength; - ClearPacketBuffer(rt17); - - if (Page == Pages) - { - Ret = DecodeGSOF(Raw); - ClearMessageBuffer(rt17); - return Ret; - } + /* Check for message buffer overflow. */ + if ((rt17->MessageBytes + rt17->PacketBytes) > MBUFF_LENGTH) { + tracet(2, "RT17: Buffer would overflow. %u GENOUT packets discarded.\n", Page); + ClearMessageBuffer(rt17); + ClearPacketBuffer(rt17); + return 0; + } - rt17->Page = Page; + memcpy(MessageBuffer + rt17->MessageBytes, PacketBuffer, rt17->PacketBytes); + rt17->MessageBytes += rt17->PacketBytes; + rt17->MessageLength += rt17->PacketLength; + ClearPacketBuffer(rt17); - return 0; + if (Page == Pages) { + Ret = DecodeGSOF(Raw); + ClearMessageBuffer(rt17); + return Ret; } - /* - | If we fall through to here, then the packet is not one that we support - | (and hence we can't really even get here). Dump the packet on the floor - | and continue reading from the stream. - */ - tracet(2, "RT17: Packet is not GENOUT, RAWDATA or RETSVDATA. Packet discarded.\n"); - ClearPacketBuffer(rt17); + rt17->Page = Page; + return 0; + } + + /* + | If we fall through to here, then the packet is not one that we support + | (and hence we can't really even get here). Dump the packet on the floor + | and continue reading from the stream. + */ + tracet(2, "RT17: Packet is not GENOUT, RAWDATA or RETSVDATA. Packet discarded.\n"); + ClearPacketBuffer(rt17); + return 0; } /* -| input_rt17f - Read an RT-17 mesasge from a file +| input_rt17f - Read an RT-17 mesasge from a file | | Returns: | @@ -725,17 +699,15 @@ EXPORT int input_rt17(raw_t *Raw, uint8_t Data) | 2: input ephemeris | 9: input ion/utc parameter */ -EXPORT int input_rt17f(raw_t *Raw, FILE *fp) -{ - int i, Data, Ret; - - for (i = 0; i < 4096; i++) - { - if ((Data = fgetc(fp)) == EOF) return -2; - if ((Ret = input_rt17(Raw, (uint8_t) Data))) return Ret; - } +EXPORT int input_rt17f(raw_t *Raw, FILE *fp) { + int i, Data, Ret; + + for (i = 0; i < 4096; i++) { + if ((Data = fgetc(fp)) == EOF) return -2; + if ((Ret = input_rt17(Raw, (uint8_t)Data))) return Ret; + } - return 0; /* return at every 4k bytes */ + return 0; /* return at every 4k bytes */ } /* @@ -751,50 +723,44 @@ EXPORT int input_rt17f(raw_t *Raw, FILE *fp) | of the data bytes. It does not include the STX leader, the ETX trailer | nor the checksum byte. */ -static int CheckPacketChecksum(uint8_t *PacketBuffer) -{ - uint8_t Checksum = 0; - uint8_t *p = &PacketBuffer[1]; /* Starting with status */ - uint32_t Length = PacketBuffer[3] + 3; /* status, type, length, data */ - - /* Compute the packet checksum */ - while (Length > 0) - { - Checksum += *p++; - Length--; - } - - /* - | Make sure our computed checksum matches the one at the end of the packet. - | (Note that the above loop by design very conveniently left *p pointing - | to the checksum byte at the end of the packet.) - */ - return (Checksum == *p); +static int CheckPacketChecksum(uint8_t *PacketBuffer) { + uint8_t Checksum = 0; + uint8_t *p = &PacketBuffer[1]; /* Starting with status */ + uint32_t Length = PacketBuffer[3] + 3; /* status, type, length, data */ + + /* Compute the packet checksum */ + while (Length > 0) { + Checksum += *p++; + Length--; + } + + /* + | Make sure our computed checksum matches the one at the end of the packet. + | (Note that the above loop by design very conveniently left *p pointing + | to the checksum byte at the end of the packet.) + */ + return (Checksum == *p); } /* ClearMessageBuffer - Clear the raw data stream buffer */ -static void ClearMessageBuffer(rt17_t *rt17) -{ - uint8_t *MessageBuffer = rt17->MessageBuffer; - int i; - - for (i = 0; i < 4; i++) - MessageBuffer[i] = 0; - - rt17->MessageLength = rt17->MessageBytes = 0; - rt17->Reply = 0; +static void ClearMessageBuffer(rt17_t *rt17) { + uint8_t *MessageBuffer = rt17->MessageBuffer; + int i; + + for (i = 0; i < 4; i++) MessageBuffer[i] = 0; + + rt17->MessageLength = rt17->MessageBytes = 0; + rt17->Reply = 0; } /* ClearPacketBuffer - Clear the packet buffer */ -static void ClearPacketBuffer(rt17_t *rt17) -{ - uint8_t *PacketBuffer = rt17->PacketBuffer; - int i; +static void ClearPacketBuffer(rt17_t *rt17) { + uint8_t *PacketBuffer = rt17->PacketBuffer; + int i; - for (i = 0; i < 4; i++) - PacketBuffer[i] = 0; + for (i = 0; i < 4; i++) PacketBuffer[i] = 0; - rt17->PacketLength = rt17->PacketBytes = 0; + rt17->PacketLength = rt17->PacketBytes = 0; } /* @@ -807,126 +773,122 @@ static void ClearPacketBuffer(rt17_t *rt17) | | See reference #1 above for documentation of the RETSVDATA Beidou Ephemeris. */ -static int DecodeBeidouEphemeris(raw_t *Raw) -{ - (void)Raw; - tracet(3, "DecodeBeidouEphemeris(); not yet implemented.\n"); - return 0; +static int DecodeBeidouEphemeris(raw_t *Raw) { + (void)Raw; + tracet(3, "DecodeBeidouEphemeris(); not yet implemented.\n"); + return 0; #ifdef RTK_DISABLED - rt17_t *rt17 = (rt17_t*) Raw->rcv_data; - uint8_t *p = rt17->PacketBuffer; - int prn, sat, toc, tow; - uint32_t Flags, toe; - double sqrtA; - eph_t eph={0}; - tracet(3, "RT17: DecodeBeidouEphemeris(); Length=%d\n", rt17->PacketLength); - if (rt17->PacketLength < 182) - { - tracet(2, "RT17: RETSVDATA packet length %d < 182 bytes. GPS ephemeris packet discarded.\n", rt17->PacketLength); - return -1; - } - prn = U1(p+5); - if (!(sat=satno(SYS_CMP, prn))) - { - tracet(2, "RT17: Beidou ephemeris satellite number error, PRN=%d.\n", prn); - return -1; - } - - eph.week = U2(p+6); /* 006-007: Ephemeris Week number (weeks) */ - eph.iodc = U2(p+8); /* 008-009: IODC */ - /* Reserved byte */ /* 010-010: RESERVED */ - eph.iode = U1(p+11); /* 011-011: IODE */ - tow = I4(p+12); /* 012-015: TOW */ - toc = I4(p+16); /* 016-019: TOC (seconds) */ - toe = U4(p+20); /* 020-023: TOE (seconds) */ - eph.tgd[0]= R8(p+24); /* 024-031: TGD (seconds) */ - eph.f2 = R8(p+32); /* 032-029: AF2 (seconds/seconds^2) */ - eph.f1 = R8(p+40); /* 040-047: AF1 (seconds/seconds) */ - eph.f0 = R8(p+48); /* 048-055: AF0 (seconds) */ - eph.crs = R8(p+56); /* 056-063: CRS (meters) */ - eph.deln = R8(p+64); /* 064-071: DELTA N (semi-circles/second) */ - eph.M0 = R8(p+72); /* 072-079: M SUB 0 (semi-circles) */ - eph.cuc = R8(p+80); /* 080-087: CUC (semi-circles) */ - eph.e = R8(p+88); /* 088-095: ECCENTRICITY (dimensionless) */ - eph.cus = R8(p+96); /* 096-103: CUS (semi-circles) */ - sqrtA = R8(p+104); /* 104-111: SQRT A (meters ^ 0.5) */ - eph.cic = R8(p+112); /* 112-119: CIC (semi-circles) */ - eph.OMG0 = R8(p+120); /* 120-127: OMEGA SUB 0 (semi-circles) */ - eph.cis = R8(p+128); /* 128-135: CIS (semi-circlces) */ - eph.i0 = R8(p+136); /* 136-143: I SUB 0 (semi-circles) */ - eph.crc = R8(p+144); /* 144-151: CRC (meters) */ - eph.omg = R8(p+152); /* 152-159: OMEGA (semi-circles?) */ - eph.OMGd = R8(p+160); /* 160-167: OMEGA DOT (semi-circles/second) */ - eph.idot = R8(p+168); /* 168-175: I DOT (semi-circles/second) */ - Flags = U4(p+176); /* 176-179: FLAGS */ - - /* - | Multiply these by PI to make semi-circle units into radian units for RTKLIB. - */ - eph.deln *= SC2RAD; - eph.i0 *= SC2RAD; - eph.idot *= SC2RAD; - eph.M0 *= SC2RAD; - eph.omg *= SC2RAD; - eph.OMG0 *= SC2RAD; - eph.OMGd *= SC2RAD; - /* - | As specifically directed to do so by Reference #1, multiply these by PI. - | to make semi-circle units into radian units, which is what RTKLIB needs. - */ - eph.cic *= SC2RAD; - eph.cis *= SC2RAD; - eph.cuc *= SC2RAD; - eph.cus *= SC2RAD; - - /* - | Select the correct curve fit interval as per ICD-GPS-200 sections - | 20.3.3.4.3.1 and 20.3.4.4 using IODC, fit flag and Table 20-XII. - */ - if (Flags & M_BIT10) /* Subframe 2, word 10, bit 17 (fit flag) */ - { - if ((eph.iodc >= 240) && (eph.iodc <= 247)) - eph.fit = 8; - else if (((eph.iodc >= 248) && (eph.iodc <= 255)) || (eph.iodc == 496)) - eph.fit = 14; - else if ((eph.iodc >= 497) && (eph.iodc <= 503)) - eph.fit = 26; - else if ((eph.iodc >= 504) && (eph.iodc <= 510)) - eph.fit = 50; - else if ((eph.iodc == 511) || ((eph.iodc >= 752) && (eph.iodc <= 756))) - eph.fit = 74; - else if ((eph.iodc >= 757) && (eph.iodc <= 763)) - eph.fit = 98; - else if (((eph.iodc >= 764) && (eph.iodc <= 767)) || ((eph.iodc >= 1008) && (eph.iodc <= 1010))) - eph.fit = 122; - else if ((eph.iodc >= 1011) && (eph.iodc <= 1020)) - eph.fit = 146; - else - eph.fit = 6; - } + rt17_t *rt17 = (rt17_t *)Raw->rcv_data; + uint8_t *p = rt17->PacketBuffer; + int prn, sat, toc, tow; + uint32_t Flags, toe; + double sqrtA; + eph_t eph = {0}; + tracet(3, "RT17: DecodeBeidouEphemeris(); Length=%d\n", rt17->PacketLength); + if (rt17->PacketLength < 182) { + tracet(2, "RT17: RETSVDATA packet length %d < 182 bytes. GPS ephemeris packet discarded.\n", + rt17->PacketLength); + return -1; + } + prn = U1(p + 5); + if (!(sat = satno(SYS_CMP, prn))) { + tracet(2, "RT17: Beidou ephemeris satellite number error, PRN=%d.\n", prn); + return -1; + } + + eph.week = U2(p + 6); /* 006-007: Ephemeris Week number (weeks) */ + eph.iodc = U2(p + 8); /* 008-009: IODC */ + /* Reserved byte */ /* 010-010: RESERVED */ + eph.iode = U1(p + 11); /* 011-011: IODE */ + tow = I4(p + 12); /* 012-015: TOW */ + toc = I4(p + 16); /* 016-019: TOC (seconds) */ + toe = U4(p + 20); /* 020-023: TOE (seconds) */ + eph.tgd[0] = R8(p + 24); /* 024-031: TGD (seconds) */ + eph.f2 = R8(p + 32); /* 032-029: AF2 (seconds/seconds^2) */ + eph.f1 = R8(p + 40); /* 040-047: AF1 (seconds/seconds) */ + eph.f0 = R8(p + 48); /* 048-055: AF0 (seconds) */ + eph.crs = R8(p + 56); /* 056-063: CRS (meters) */ + eph.deln = R8(p + 64); /* 064-071: DELTA N (semi-circles/second) */ + eph.M0 = R8(p + 72); /* 072-079: M SUB 0 (semi-circles) */ + eph.cuc = R8(p + 80); /* 080-087: CUC (semi-circles) */ + eph.e = R8(p + 88); /* 088-095: ECCENTRICITY (dimensionless) */ + eph.cus = R8(p + 96); /* 096-103: CUS (semi-circles) */ + sqrtA = R8(p + 104); /* 104-111: SQRT A (meters ^ 0.5) */ + eph.cic = R8(p + 112); /* 112-119: CIC (semi-circles) */ + eph.OMG0 = R8(p + 120); /* 120-127: OMEGA SUB 0 (semi-circles) */ + eph.cis = R8(p + 128); /* 128-135: CIS (semi-circlces) */ + eph.i0 = R8(p + 136); /* 136-143: I SUB 0 (semi-circles) */ + eph.crc = R8(p + 144); /* 144-151: CRC (meters) */ + eph.omg = R8(p + 152); /* 152-159: OMEGA (semi-circles?) */ + eph.OMGd = R8(p + 160); /* 160-167: OMEGA DOT (semi-circles/second) */ + eph.idot = R8(p + 168); /* 168-175: I DOT (semi-circles/second) */ + Flags = U4(p + 176); /* 176-179: FLAGS */ + + /* + | Multiply these by PI to make semi-circle units into radian units for RTKLIB. + */ + eph.deln *= SC2RAD; + eph.i0 *= SC2RAD; + eph.idot *= SC2RAD; + eph.M0 *= SC2RAD; + eph.omg *= SC2RAD; + eph.OMG0 *= SC2RAD; + eph.OMGd *= SC2RAD; + /* + | As specifically directed to do so by Reference #1, multiply these by PI. + | to make semi-circle units into radian units, which is what RTKLIB needs. + */ + eph.cic *= SC2RAD; + eph.cis *= SC2RAD; + eph.cuc *= SC2RAD; + eph.cus *= SC2RAD; + + /* + | Select the correct curve fit interval as per ICD-GPS-200 sections + | 20.3.3.4.3.1 and 20.3.4.4 using IODC, fit flag and Table 20-XII. + */ + if (Flags & M_BIT10) /* Subframe 2, word 10, bit 17 (fit flag) */ + { + if ((eph.iodc >= 240) && (eph.iodc <= 247)) + eph.fit = 8; + else if (((eph.iodc >= 248) && (eph.iodc <= 255)) || (eph.iodc == 496)) + eph.fit = 14; + else if ((eph.iodc >= 497) && (eph.iodc <= 503)) + eph.fit = 26; + else if ((eph.iodc >= 504) && (eph.iodc <= 510)) + eph.fit = 50; + else if ((eph.iodc == 511) || ((eph.iodc >= 752) && (eph.iodc <= 756))) + eph.fit = 74; + else if ((eph.iodc >= 757) && (eph.iodc <= 763)) + eph.fit = 98; + else if (((eph.iodc >= 764) && (eph.iodc <= 767)) || ((eph.iodc >= 1008) && (eph.iodc <= 1010))) + eph.fit = 122; + else if ((eph.iodc >= 1011) && (eph.iodc <= 1020)) + eph.fit = 146; else - eph.fit = 4; - - eph.flag = (Flags & M_BIT0); /* Subframe 1, word 4, bit 1, Data flag for L2 P-code */ - eph.code = (Flags >> 1) & 3; /* Subframe 1, word 3, bits 11-12, Codes on L2 channel */ - eph.svh = (Flags >> 4) & 127; /* Subframe 1, word 3, bits 17-22, SV health from ephemeris */ - eph.sva = (Flags >> 11) & 15; /* Subframe 1, word 3, bits 13-16, User Range Accuracy index */ - eph.A = sqrtA * sqrtA; - eph.toes = toe; - eph.toc = bdt2gpst(bdt2time(eph.week, toc)); - eph.toe = bdt2gpst(bdt2time(eph.week, toe)); - eph.ttr = bdt2gpst(bdt2time(eph.week, tow)); - tracet(3, "RT17: DecodeBeidouEphemeris(); SAT=%d, IODC=%d, IODE=%d, WEEK=%d.\n", sat, eph.iodc, eph.iode, eph.week); - if (!strstr(Raw->opt,"-EPHALL")) - { - if (eph.iode == Raw->nav.eph[sat-1].iode) - return 0; /* unchanged */ - } - eph.sat = sat; - Raw->nav.eph[sat-1] = eph; - Raw->ephsat = sat; - return 2; + eph.fit = 6; + } else + eph.fit = 4; + + eph.flag = (Flags & M_BIT0); /* Subframe 1, word 4, bit 1, Data flag for L2 P-code */ + eph.code = (Flags >> 1) & 3; /* Subframe 1, word 3, bits 11-12, Codes on L2 channel */ + eph.svh = (Flags >> 4) & 127; /* Subframe 1, word 3, bits 17-22, SV health from ephemeris */ + eph.sva = (Flags >> 11) & 15; /* Subframe 1, word 3, bits 13-16, User Range Accuracy index */ + eph.A = sqrtA * sqrtA; + eph.toes = toe; + eph.toc = bdt2gpst(bdt2time(eph.week, toc)); + eph.toe = bdt2gpst(bdt2time(eph.week, toe)); + eph.ttr = bdt2gpst(bdt2time(eph.week, tow)); + tracet(3, "RT17: DecodeBeidouEphemeris(); SAT=%d, IODC=%d, IODE=%d, WEEK=%d.\n", sat, eph.iodc, + eph.iode, eph.week); + if (!strstr(Raw->opt, "-EPHALL")) { + if (eph.iode == Raw->nav.eph[sat - 1].iode) return 0; /* unchanged */ + } + eph.sat = sat; + Raw->nav.eph[sat - 1] = eph; + Raw->ephsat = sat; + return 2; #endif } @@ -940,99 +902,96 @@ static int DecodeBeidouEphemeris(raw_t *Raw) | | See reference #1 above for documentation of the RETSVDATA Galileo Ephemeris. */ -static int DecodeGalileoEphemeris(raw_t *Raw) -{ - (void)Raw; - tracet(3, "DecodeGalileoEphemeris(); not yet implemented.\n"); - return 0; +static int DecodeGalileoEphemeris(raw_t *Raw) { + (void)Raw; + tracet(3, "DecodeGalileoEphemeris(); not yet implemented.\n"); + return 0; #ifdef RTK_DISABLED - rt17_t *rt17 = (rt17_t*) Raw->rcv_data; - uint8_t *p = rt17->PacketBuffer; - int prn, sat, toc, tow; - uint32_t toe; - double sqrtA; - eph_t eph={0}; - uint8_t SISA, MODEL1, MODEL2; - uint16_t IODnav, HSDVS; - double BDG1, BDG2; - tracet(3, "RT17: DecodeGalileoEphemeris(); Length=%d\n", rt17->PacketLength); - if (rt17->PacketLength < 190) - { - tracet(2, "RT17: RETSVDATA packet length %d < 190 bytes. Galileo ephemeris packet discarded.\n", rt17->PacketLength); - return -1; - } - prn = U1(p+5); - if (!(sat=satno(SYS_GAL, prn))) - { - tracet(2, "RT17: Galileo ephemeris satellite number error, PRN=%d.\n", prn); - return -1; - } - - eph.code = U1(p+6); /* 006-006: Data source 0:E1B 1:E5B 2:E5A */ - eph.week = U2(p+7); /* 007-008: Ephemeris Week number (weeks) */ - tow = I4(p+9); /* 008-012: TOW */ - IODnav = U2(p+13); /* 013-014: Ephemeris and clock correction issue of data */ - toe = U4(p+15); /* 015-018: TOE (seconds) */ - eph.crs = R8(p+19); /* 019-026: CRS (meters) */ - eph.deln = R8(p+27); /* 027-034: DELTA N (semi-circles/second) */ - eph.M0 = R8(p+35); /* 035-042: M SUB 0 (semi-circles) */ - eph.cuc = R8(p+43); /* 043-050: CUC (semi-circles) */ - eph.e = R8(p+51); /* 051-058: ECCENTRICITY (dimensionless) */ - eph.cus = R8(p+59); /* 059-066: CUS (semi-circles) */ - sqrtA = R8(p+67); /* 067-074: SQRT A (meters ^ 0.5) */ - eph.cic = R8(p+75); /* 075-082: CIC (semi-circles) */ - eph.OMG0 = R8(p+83); /* 083-090: OMEGA SUB 0 (semi-circles) */ - eph.cis = R8(p+91); /* 091-098: CIS (semi-circlces) */ - eph.i0 = R8(p+99); /* 099-106: I SUB 0 (semi-circles) */ - eph.crc = R8(p+107); /* 107-114: CRC (meters) */ - eph.omg = R8(p+115); /* 115-122: OMEGA (semi-circles?) */ - eph.OMGd = R8(p+123); /* 123-130: OMEGA DOT (semi-circles/second) */ - eph.idot = R8(p+131); /* 131-138: I DOT (semi-circles/second) */ - SISA = U1(p+149); /* 149-149: ? */ - HSDVS = U2(p+150); /* 150-151: Signal Health Flag */ - toc = I4(p+142); /* 142-145: TOC (seconds) */ - eph.f0 = R8(p+146); /* 146-153: AF0 (seconds) */ - eph.f1 = R8(p+154); /* 154-161: AF1 (seconds/seconds) */ - eph.f2 = R8(p+162); /* 162-169: AF2 (seconds/seconds^2) */ - BDG1 = R8(p+170); /* 170-177: Seconds */ - MODEL1 = U1(p+178); /* 178-178: Clock model for TOC/AF0?2/BGD1 */ - BDG2 = R8(p+179); /* 179-186: Seconds */ - MODEL2 = U1(p+187); /* 187-187: Clock model for BGD2 */ - /* - | Multiply these by PI to make semi-circle units into radian units for RTKLIB. - */ - eph.deln *= SC2RAD; - eph.i0 *= SC2RAD; - eph.idot *= SC2RAD; - eph.M0 *= SC2RAD; - eph.omg *= SC2RAD; - eph.OMG0 *= SC2RAD; - eph.OMGd *= SC2RAD; - /* - | As specifically directed to do so by Reference #1, multiply these by PI. - | to make semi-circle units into radian units, which is what RTKLIB needs. - */ - eph.cic *= SC2RAD; - eph.cis *= SC2RAD; - eph.cuc *= SC2RAD; - eph.cus *= SC2RAD; - - eph.A = sqrtA * sqrtA; - eph.toes = toe; - eph.toc = gst2time(eph.week, toc); - eph.toe = gst2time(eph.week, toe); - eph.ttr = gst2time(eph.week, tow); - tracet(3, "RT17: DecodeGalileoEphemeris(); SAT=%d, IODC=%d, IODE=%d, WEEK=%d.\n", sat, eph.iodc, eph.iode, eph.week); - if (!strstr(Raw->opt,"-EPHALL")) - { - if (eph.iode == Raw->nav.eph[sat-1].iode) - return 0; /* unchanged */ - } - eph.sat = sat; - Raw->nav.eph[sat-1] = eph; - Raw->ephsat = sat; - return 2; + rt17_t *rt17 = (rt17_t *)Raw->rcv_data; + uint8_t *p = rt17->PacketBuffer; + int prn, sat, toc, tow; + uint32_t toe; + double sqrtA; + eph_t eph = {0}; + uint8_t SISA, MODEL1, MODEL2; + uint16_t IODnav, HSDVS; + double BDG1, BDG2; + tracet(3, "RT17: DecodeGalileoEphemeris(); Length=%d\n", rt17->PacketLength); + if (rt17->PacketLength < 190) { + tracet(2, "RT17: RETSVDATA packet length %d < 190 bytes. Galileo ephemeris packet discarded.\n", + rt17->PacketLength); + return -1; + } + prn = U1(p + 5); + if (!(sat = satno(SYS_GAL, prn))) { + tracet(2, "RT17: Galileo ephemeris satellite number error, PRN=%d.\n", prn); + return -1; + } + + eph.code = U1(p + 6); /* 006-006: Data source 0:E1B 1:E5B 2:E5A */ + eph.week = U2(p + 7); /* 007-008: Ephemeris Week number (weeks) */ + tow = I4(p + 9); /* 008-012: TOW */ + IODnav = U2(p + 13); /* 013-014: Ephemeris and clock correction issue of data */ + toe = U4(p + 15); /* 015-018: TOE (seconds) */ + eph.crs = R8(p + 19); /* 019-026: CRS (meters) */ + eph.deln = R8(p + 27); /* 027-034: DELTA N (semi-circles/second) */ + eph.M0 = R8(p + 35); /* 035-042: M SUB 0 (semi-circles) */ + eph.cuc = R8(p + 43); /* 043-050: CUC (semi-circles) */ + eph.e = R8(p + 51); /* 051-058: ECCENTRICITY (dimensionless) */ + eph.cus = R8(p + 59); /* 059-066: CUS (semi-circles) */ + sqrtA = R8(p + 67); /* 067-074: SQRT A (meters ^ 0.5) */ + eph.cic = R8(p + 75); /* 075-082: CIC (semi-circles) */ + eph.OMG0 = R8(p + 83); /* 083-090: OMEGA SUB 0 (semi-circles) */ + eph.cis = R8(p + 91); /* 091-098: CIS (semi-circlces) */ + eph.i0 = R8(p + 99); /* 099-106: I SUB 0 (semi-circles) */ + eph.crc = R8(p + 107); /* 107-114: CRC (meters) */ + eph.omg = R8(p + 115); /* 115-122: OMEGA (semi-circles?) */ + eph.OMGd = R8(p + 123); /* 123-130: OMEGA DOT (semi-circles/second) */ + eph.idot = R8(p + 131); /* 131-138: I DOT (semi-circles/second) */ + SISA = U1(p + 149); /* 149-149: ? */ + HSDVS = U2(p + 150); /* 150-151: Signal Health Flag */ + toc = I4(p + 142); /* 142-145: TOC (seconds) */ + eph.f0 = R8(p + 146); /* 146-153: AF0 (seconds) */ + eph.f1 = R8(p + 154); /* 154-161: AF1 (seconds/seconds) */ + eph.f2 = R8(p + 162); /* 162-169: AF2 (seconds/seconds^2) */ + BDG1 = R8(p + 170); /* 170-177: Seconds */ + MODEL1 = U1(p + 178); /* 178-178: Clock model for TOC/AF0?2/BGD1 */ + BDG2 = R8(p + 179); /* 179-186: Seconds */ + MODEL2 = U1(p + 187); /* 187-187: Clock model for BGD2 */ + /* + | Multiply these by PI to make semi-circle units into radian units for RTKLIB. + */ + eph.deln *= SC2RAD; + eph.i0 *= SC2RAD; + eph.idot *= SC2RAD; + eph.M0 *= SC2RAD; + eph.omg *= SC2RAD; + eph.OMG0 *= SC2RAD; + eph.OMGd *= SC2RAD; + /* + | As specifically directed to do so by Reference #1, multiply these by PI. + | to make semi-circle units into radian units, which is what RTKLIB needs. + */ + eph.cic *= SC2RAD; + eph.cis *= SC2RAD; + eph.cuc *= SC2RAD; + eph.cus *= SC2RAD; + + eph.A = sqrtA * sqrtA; + eph.toes = toe; + eph.toc = gst2time(eph.week, toc); + eph.toe = gst2time(eph.week, toe); + eph.ttr = gst2time(eph.week, tow); + tracet(3, "RT17: DecodeGalileoEphemeris(); SAT=%d, IODC=%d, IODE=%d, WEEK=%d.\n", sat, eph.iodc, + eph.iode, eph.week); + if (!strstr(Raw->opt, "-EPHALL")) { + if (eph.iode == Raw->nav.eph[sat - 1].iode) return 0; /* unchanged */ + } + eph.sat = sat; + Raw->nav.eph[sat - 1] = eph; + Raw->ephsat = sat; + return 2; #endif } @@ -1046,13 +1005,12 @@ static int DecodeGalileoEphemeris(raw_t *Raw) | | See reference #1 above for documentation of the RETSVDATA GLONASS Ephemeris. */ -static int DecodeGLONASSEphemeris(raw_t *Raw) -{ - (void)Raw; - tracet(3, "DecodeGLONASSEphemeris(); not yet implemented.\n"); - return 0; +static int DecodeGLONASSEphemeris(raw_t *Raw) { + (void)Raw; + tracet(3, "DecodeGLONASSEphemeris(); not yet implemented.\n"); + return 0; } - + /* | DecodeGPSEphemeris - Decode a GPS Ephemeris record | @@ -1064,295 +1022,287 @@ static int DecodeGLONASSEphemeris(raw_t *Raw) | See ICD-GPS-200C.PDF for documentation of the GPS satellite ephemeris. | See reference #1 above for documentation of the RETSVDATA GPS Ephemeris. */ -static int DecodeGPSEphemeris(raw_t *Raw) -{ - rt17_t *rt17 = (rt17_t*) Raw->rcv_data; - uint8_t *p = rt17->PacketBuffer; - int prn, sat, toc, tow; - uint32_t Flags, toe; - double sqrtA; - eph_t eph={0}; - - tracet(3, "RT17: DecodeGPSEphemeris(); Length=%d\n", rt17->PacketLength); - - if (rt17->PacketLength < 182) - { - tracet(2, "RT17: RETSVDATA packet length %d < 182 bytes. GPS ephemeris packet discarded.\n", rt17->PacketLength); - return -1; - } - - prn = U1(p+5); - - if (!(sat=satno(SYS_GPS, prn))) - { - tracet(2, "RT17: GPS ephemeris satellite number error, PRN=%d.\n", prn); - return -1; - } - - eph.week = U2(p+6); /* 006-007: Ephemeris Week number (weeks) */ - eph.iodc = U2(p+8); /* 008-009: IODC */ - /* Reserved byte */ /* 010-010: RESERVED */ - eph.iode = U1(p+11); /* 011-011: IODE */ - tow = I4(p+12); /* 012-015: TOW */ - toc = I4(p+16); /* 016-019: TOC (seconds) */ - toe = U4(p+20); /* 020-023: TOE (seconds) */ - eph.tgd[0]= R8(p+24); /* 024-031: TGD (seconds) */ - eph.f2 = R8(p+32); /* 032-029: AF2 (seconds/seconds^2) */ - eph.f1 = R8(p+40); /* 040-047: AF1 (seconds/seconds) */ - eph.f0 = R8(p+48); /* 048-055: AF0 (seconds) */ - eph.crs = R8(p+56); /* 056-063: CRS (meters) */ - eph.deln = R8(p+64); /* 064-071: DELTA N (semi-circles/second) */ - eph.M0 = R8(p+72); /* 072-079: M SUB 0 (semi-circles) */ - eph.cuc = R8(p+80); /* 080-087: CUC (semi-circles) */ - eph.e = R8(p+88); /* 088-095: ECCENTRICITY (dimensionless) */ - eph.cus = R8(p+96); /* 096-103: CUS (semi-circles) */ - sqrtA = R8(p+104); /* 104-111: SQRT A (meters ^ 0.5) */ - eph.cic = R8(p+112); /* 112-119: CIC (semi-circles) */ - eph.OMG0 = R8(p+120); /* 120-127: OMEGA SUB 0 (semi-circles) */ - eph.cis = R8(p+128); /* 128-135: CIS (semi-circlces) */ - eph.i0 = R8(p+136); /* 136-143: I SUB 0 (semi-circles) */ - eph.crc = R8(p+144); /* 144-151: CRC (meters) */ - eph.omg = R8(p+152); /* 152-159: OMEGA (semi-circles?) */ - eph.OMGd = R8(p+160); /* 160-167: OMEGA DOT (semi-circles/second) */ - eph.idot = R8(p+168); /* 168-175: I DOT (semi-circles/second) */ - Flags = U4(p+176); /* 176-179: FLAGS */ - - /* - | Multiply these by PI to make ICD specified semi-circle units into radian - | units for RTKLIB. - */ - eph.deln *= SC2RAD; - eph.i0 *= SC2RAD; - eph.idot *= SC2RAD; - eph.M0 *= SC2RAD; - eph.omg *= SC2RAD; - eph.OMG0 *= SC2RAD; - eph.OMGd *= SC2RAD; - - /* - | As specifically directed to do so by Reference #1, multiply these by PI. - | to make semi-circle units into radian units, which is what ICD-GPS-200C - | calls for and also what RTKLIB needs. - */ - eph.cic *= SC2RAD; - eph.cis *= SC2RAD; - eph.cuc *= SC2RAD; - eph.cus *= SC2RAD; - - /* - | Select the correct curve fit interval as per ICD-GPS-200 sections - | 20.3.3.4.3.1 and 20.3.4.4 using IODC, fit flag and Table 20-XII. - */ - if (Flags & M_BIT10) /* Subframe 2, word 10, bit 17 (fit flag) */ - { - if ((eph.iodc >= 240) && (eph.iodc <= 247)) - eph.fit = 8; - else if (((eph.iodc >= 248) && (eph.iodc <= 255)) || (eph.iodc == 496)) - eph.fit = 14; - else if ((eph.iodc >= 497) && (eph.iodc <= 503)) - eph.fit = 26; - else if ((eph.iodc >= 504) && (eph.iodc <= 510)) - eph.fit = 50; - else if ((eph.iodc == 511) || ((eph.iodc >= 752) && (eph.iodc <= 756))) - eph.fit = 74; - else if ((eph.iodc >= 757) && (eph.iodc <= 763)) - eph.fit = 98; - else if (((eph.iodc >= 764) && (eph.iodc <= 767)) || ((eph.iodc >= 1008) && (eph.iodc <= 1010))) - eph.fit = 122; - else if ((eph.iodc >= 1011) && (eph.iodc <= 1020)) - eph.fit = 146; - else - eph.fit = 6; - } +static int DecodeGPSEphemeris(raw_t *Raw) { + rt17_t *rt17 = (rt17_t *)Raw->rcv_data; + uint8_t *p = rt17->PacketBuffer; + int prn, sat, toc, tow; + uint32_t Flags, toe; + double sqrtA; + eph_t eph = {0}; + + tracet(3, "RT17: DecodeGPSEphemeris(); Length=%d\n", rt17->PacketLength); + + if (rt17->PacketLength < 182) { + tracet(2, "RT17: RETSVDATA packet length %d < 182 bytes. GPS ephemeris packet discarded.\n", + rt17->PacketLength); + return -1; + } + + prn = U1(p + 5); + + if (!(sat = satno(SYS_GPS, prn))) { + tracet(2, "RT17: GPS ephemeris satellite number error, PRN=%d.\n", prn); + return -1; + } + + eph.week = U2(p + 6); /* 006-007: Ephemeris Week number (weeks) */ + eph.iodc = U2(p + 8); /* 008-009: IODC */ + /* Reserved byte */ /* 010-010: RESERVED */ + eph.iode = U1(p + 11); /* 011-011: IODE */ + tow = I4(p + 12); /* 012-015: TOW */ + toc = I4(p + 16); /* 016-019: TOC (seconds) */ + toe = U4(p + 20); /* 020-023: TOE (seconds) */ + eph.tgd[0] = R8(p + 24); /* 024-031: TGD (seconds) */ + eph.f2 = R8(p + 32); /* 032-029: AF2 (seconds/seconds^2) */ + eph.f1 = R8(p + 40); /* 040-047: AF1 (seconds/seconds) */ + eph.f0 = R8(p + 48); /* 048-055: AF0 (seconds) */ + eph.crs = R8(p + 56); /* 056-063: CRS (meters) */ + eph.deln = R8(p + 64); /* 064-071: DELTA N (semi-circles/second) */ + eph.M0 = R8(p + 72); /* 072-079: M SUB 0 (semi-circles) */ + eph.cuc = R8(p + 80); /* 080-087: CUC (semi-circles) */ + eph.e = R8(p + 88); /* 088-095: ECCENTRICITY (dimensionless) */ + eph.cus = R8(p + 96); /* 096-103: CUS (semi-circles) */ + sqrtA = R8(p + 104); /* 104-111: SQRT A (meters ^ 0.5) */ + eph.cic = R8(p + 112); /* 112-119: CIC (semi-circles) */ + eph.OMG0 = R8(p + 120); /* 120-127: OMEGA SUB 0 (semi-circles) */ + eph.cis = R8(p + 128); /* 128-135: CIS (semi-circlces) */ + eph.i0 = R8(p + 136); /* 136-143: I SUB 0 (semi-circles) */ + eph.crc = R8(p + 144); /* 144-151: CRC (meters) */ + eph.omg = R8(p + 152); /* 152-159: OMEGA (semi-circles?) */ + eph.OMGd = R8(p + 160); /* 160-167: OMEGA DOT (semi-circles/second) */ + eph.idot = R8(p + 168); /* 168-175: I DOT (semi-circles/second) */ + Flags = U4(p + 176); /* 176-179: FLAGS */ + + /* + | Multiply these by PI to make ICD specified semi-circle units into radian + | units for RTKLIB. + */ + eph.deln *= SC2RAD; + eph.i0 *= SC2RAD; + eph.idot *= SC2RAD; + eph.M0 *= SC2RAD; + eph.omg *= SC2RAD; + eph.OMG0 *= SC2RAD; + eph.OMGd *= SC2RAD; + + /* + | As specifically directed to do so by Reference #1, multiply these by PI. + | to make semi-circle units into radian units, which is what ICD-GPS-200C + | calls for and also what RTKLIB needs. + */ + eph.cic *= SC2RAD; + eph.cis *= SC2RAD; + eph.cuc *= SC2RAD; + eph.cus *= SC2RAD; + + /* + | Select the correct curve fit interval as per ICD-GPS-200 sections + | 20.3.3.4.3.1 and 20.3.4.4 using IODC, fit flag and Table 20-XII. + */ + if (Flags & M_BIT10) /* Subframe 2, word 10, bit 17 (fit flag) */ + { + if ((eph.iodc >= 240) && (eph.iodc <= 247)) + eph.fit = 8; + else if (((eph.iodc >= 248) && (eph.iodc <= 255)) || (eph.iodc == 496)) + eph.fit = 14; + else if ((eph.iodc >= 497) && (eph.iodc <= 503)) + eph.fit = 26; + else if ((eph.iodc >= 504) && (eph.iodc <= 510)) + eph.fit = 50; + else if ((eph.iodc == 511) || ((eph.iodc >= 752) && (eph.iodc <= 756))) + eph.fit = 74; + else if ((eph.iodc >= 757) && (eph.iodc <= 763)) + eph.fit = 98; + else if (((eph.iodc >= 764) && (eph.iodc <= 767)) || ((eph.iodc >= 1008) && (eph.iodc <= 1010))) + eph.fit = 122; + else if ((eph.iodc >= 1011) && (eph.iodc <= 1020)) + eph.fit = 146; else - eph.fit = 4; - - eph.flag = (Flags & M_BIT0); /* Subframe 1, word 4, bit 1, Data flag for L2 P-code */ - eph.code = (Flags >> 1) & 3; /* Subframe 1, word 3, bits 11-12, Codes on L2 channel */ - eph.svh = (Flags >> 4) & 127; /* Subframe 1, word 3, bits 17-22, SV health from ephemeris */ - eph.sva = (Flags >> 11) & 15; /* Subframe 1, word 3, bits 13-16, User Range Accuracy index */ - - eph.A = sqrtA * sqrtA; - - eph.toes = toe; - eph.toc = gpst2time(eph.week, toc); - eph.toe = gpst2time(eph.week, toe); - eph.ttr = gpst2time(eph.week, tow); - - tracet(3, "RT17: DecodeGPSEphemeris(); SAT=%d, IODC=%d, IODE=%d, WEEK=%d.\n", sat, eph.iodc, eph.iode, eph.week); - - if (rt17->Week && (rt17->Week != eph.week)) - { - tracet(2, "RT17: Currently set or assumed GPS week does not match received ephemeris week.\n"); - tracet(2, "RT17: Set or assumed GPS week: %d Received ephemeris week: %d\n", rt17->Week, eph.week); + eph.fit = 6; + } else + eph.fit = 4; + + eph.flag = (Flags & M_BIT0); /* Subframe 1, word 4, bit 1, Data flag for L2 P-code */ + eph.code = (Flags >> 1) & 3; /* Subframe 1, word 3, bits 11-12, Codes on L2 channel */ + eph.svh = (Flags >> 4) & 127; /* Subframe 1, word 3, bits 17-22, SV health from ephemeris */ + eph.sva = (Flags >> 11) & 15; /* Subframe 1, word 3, bits 13-16, User Range Accuracy index */ + + eph.A = sqrtA * sqrtA; + + eph.toes = toe; + eph.toc = gpst2time(eph.week, toc); + eph.toe = gpst2time(eph.week, toe); + eph.ttr = gpst2time(eph.week, tow); + + tracet(3, "RT17: DecodeGPSEphemeris(); SAT=%d, IODC=%d, IODE=%d, WEEK=%d.\n", sat, eph.iodc, + eph.iode, eph.week); + + if (rt17->Week && (rt17->Week != eph.week)) { + tracet(2, "RT17: Currently set or assumed GPS week does not match received ephemeris week.\n"); + tracet(2, "RT17: Set or assumed GPS week: %d Received ephemeris week: %d\n", rt17->Week, + eph.week); + } + + if (!(rt17->Flags & M_WEEK_OPTION)) { + if (!rt17->Week || (rt17->Flags & M_WEEK_TIME) || (eph.week > rt17->Week)) { + if (!rt17->Week) + tracet(2, "RT17: Initial GPS WEEK number unknown; WEEK number %d assumed for now.\n", + eph.week); + else + tracet(2, "RT17: Changing assumed week number from %d to %d.\n", rt17->Week, eph.week); + rt17->Flags &= ~M_WEEK_TIME; + rt17->Flags |= M_WEEK_EPH; + rt17->Week = eph.week; } + } - if (!(rt17->Flags & M_WEEK_OPTION)) - { - if (!rt17->Week || (rt17->Flags & M_WEEK_TIME) || (eph.week > rt17->Week)) - { - if (!rt17->Week) - tracet(2, "RT17: Initial GPS WEEK number unknown; WEEK number %d assumed for now.\n", eph.week); - else - tracet(2, "RT17: Changing assumed week number from %d to %d.\n", rt17->Week, eph.week); - rt17->Flags &= ~M_WEEK_TIME; - rt17->Flags |= M_WEEK_EPH; - rt17->Week = eph.week; - } - } - - if (!strstr(Raw->opt,"-EPHALL")) - { - if (eph.iode == Raw->nav.eph[sat-1].iode) - return 0; /* unchanged */ - } + if (!strstr(Raw->opt, "-EPHALL")) { + if (eph.iode == Raw->nav.eph[sat - 1].iode) return 0; /* unchanged */ + } - eph.sat = sat; - Raw->nav.eph[sat-1] = eph; - Raw->ephsat = sat; + eph.sat = sat; + Raw->nav.eph[sat - 1] = eph; + Raw->ephsat = sat; - return 2; + return 2; } /* DecodeGSOF - Decode a General Serial Output Format (GSOF) message */ -static int DecodeGSOF(raw_t *Raw) -{ - rt17_t *rt17 = (rt17_t*) Raw->rcv_data; - int InputLength, Ret = 0; - uint8_t RecordLength, RecordType, *p; - char *RecordType_s = NULL; - - /* - | Reassemble origional message by removing packet headers, - | trailers and page framing. - */ - UnwrapGenout(rt17); +static int DecodeGSOF(raw_t *Raw) { + rt17_t *rt17 = (rt17_t *)Raw->rcv_data; + int InputLength, Ret = 0; + uint8_t RecordLength, RecordType, *p; + char *RecordType_s = NULL; - p = rt17->MessageBuffer; - InputLength = rt17->MessageLength; + /* + | Reassemble origional message by removing packet headers, + | trailers and page framing. + */ + UnwrapGenout(rt17); - while (InputLength) - { - RecordType = p[0]; - RecordLength = p[1]; - - if (RecordType < (sizeof(GSOFTable) / sizeof(char*))) - RecordType_s = (char*) GSOFTable[RecordType]; - - if (!RecordType_s) - RecordType_s = "Unknown"; - - tracet(3, "RT17: Trimble packet type=0x40 (GENOUT), GSOF record type=%d (%s), Length=%d.\n", RecordType, RecordType_s, RecordLength); - - /* Process (or possibly ignore) the message */ - switch (RecordType) - { - case 1: - Ret = DecodeGSOF1(Raw, p); - break; - case 3: - Ret = DecodeGSOF3(Raw, p); - break; - case 15: - Ret = DecodeGSOF15(Raw, p); - break; - case 16: - Ret = DecodeGSOF16(Raw, p); - break; - case 26: - Ret = DecodeGSOF26(Raw, p); - break; - case 41: - Ret = DecodeGSOF41(Raw, p); - break; - default: - tracet(3, "RT17: GSOF message not processed.\n"); - } - - RecordLength += 2; - p += RecordLength; - InputLength -= RecordLength; + p = rt17->MessageBuffer; + InputLength = rt17->MessageLength; + + while (InputLength) { + RecordType = p[0]; + RecordLength = p[1]; + + if (RecordType < (sizeof(GSOFTable) / sizeof(char *))) + RecordType_s = (char *)GSOFTable[RecordType]; + + if (!RecordType_s) RecordType_s = "Unknown"; + + tracet(3, "RT17: Trimble packet type=0x40 (GENOUT), GSOF record type=%d (%s), Length=%d.\n", + RecordType, RecordType_s, RecordLength); + + /* Process (or possibly ignore) the message */ + switch (RecordType) { + case 1: + Ret = DecodeGSOF1(Raw, p); + break; + case 3: + Ret = DecodeGSOF3(Raw, p); + break; + case 15: + Ret = DecodeGSOF15(Raw, p); + break; + case 16: + Ret = DecodeGSOF16(Raw, p); + break; + case 26: + Ret = DecodeGSOF26(Raw, p); + break; + case 41: + Ret = DecodeGSOF41(Raw, p); + break; + default: + tracet(3, "RT17: GSOF message not processed.\n"); } - return Ret; + RecordLength += 2; + p += RecordLength; + InputLength -= RecordLength; + } + + return Ret; } /* DecodeGSOF1 - Decode a Position Time GSOF message */ -static int DecodeGSOF1(raw_t *Raw, uint8_t *p) -{ - - if (p[1] < 6) - tracet(2, "RT17: GSOF Position Time message record length %d < 6 bytes. Record discarded.\n", p[1]); - else - SetWeek(Raw, I2(p+6), ((double) I4(p+2)) * 0.001); - - return 0; +static int DecodeGSOF1(raw_t *Raw, uint8_t *p) { + if (p[1] < 6) + tracet(2, "RT17: GSOF Position Time message record length %d < 6 bytes. Record discarded.\n", + p[1]); + else + SetWeek(Raw, I2(p + 6), ((double)I4(p + 2)) * 0.001); + + return 0; } - -/* DecodeGSOF3 - Decode an ECEF Position GSOF message */ -static int DecodeGSOF3(raw_t *Raw, uint8_t *p) -{ - sta_t *sta = &Raw->sta; - - if (p[1] < 24) - tracet( 2, "RT17: GSOF ECEF Position record length %d < 24 bytes. Record discarded.\n", p[1] ); - else - { - sta->pos[0] = R8(p+2); - sta->pos[1] = R8(p+10); - sta->pos[2] = R8(p+18); - sta->del[0] = 0.0; - sta->del[1] = 0.0; - sta->del[2] = 0.0; - sta->hgt = 0.0; - sta->deltype = 0; /* e/n/u */ - } - return 5; +/* DecodeGSOF3 - Decode an ECEF Position GSOF message */ +static int DecodeGSOF3(raw_t *Raw, uint8_t *p) { + sta_t *sta = &Raw->sta; + + if (p[1] < 24) + tracet(2, "RT17: GSOF ECEF Position record length %d < 24 bytes. Record discarded.\n", p[1]); + else { + sta->pos[0] = R8(p + 2); + sta->pos[1] = R8(p + 10); + sta->pos[2] = R8(p + 18); + sta->del[0] = 0.0; + sta->del[1] = 0.0; + sta->del[2] = 0.0; + sta->hgt = 0.0; + sta->deltype = 0; /* e/n/u */ + } + + return 5; } /* DecodeGSOF15 - Decode a Receiver Serial Number GSOF message */ -static int DecodeGSOF15(raw_t *Raw, uint8_t *p) -{ - if (p[1] < 15) - tracet(2, "RT17: GSOF Receiver Serial Number record length %d < 15 bytes. Record discarded.\n", p[1]); - else - sprintf(Raw->sta.recsno, "%u", U4(p+2)); - - return 0; +static int DecodeGSOF15(raw_t *Raw, uint8_t *p) { + if (p[1] < 15) + tracet(2, "RT17: GSOF Receiver Serial Number record length %d < 15 bytes. Record discarded.\n", + p[1]); + else + sprintf(Raw->sta.recsno, "%u", U4(p + 2)); + + return 0; } /* DecodeGSOF16 - Decode a Current Time GSOF message */ -static int DecodeGSOF16(raw_t *Raw, uint8_t *p) -{ - if (p[1] < 9) - tracet( 2, "RT17: GSOF Current Time message record length %d < 9 bytes. Record discarded.\n", p[1] ); - else if (U1(p+10) & M_BIT0) /* If week and milliseconds of week are valid */ - SetWeek(Raw, I2(p+6), ((double) I4(p+2)) * 0.001); - - return 0; +static int DecodeGSOF16(raw_t *Raw, uint8_t *p) { + if (p[1] < 9) + tracet(2, "RT17: GSOF Current Time message record length %d < 9 bytes. Record discarded.\n", + p[1]); + else if (U1(p + 10) & M_BIT0) /* If week and milliseconds of week are valid */ + SetWeek(Raw, I2(p + 6), ((double)I4(p + 2)) * 0.001); + + return 0; } /* DecodeGSOF26 - Decode a Position Time UTC GSOF message */ -static int DecodeGSOF26(raw_t *Raw, uint8_t *p) -{ - if (p[1] < 6) - tracet(2, "RT17: GSOF Position Time UTC message record length %d < 6 bytes. Record discarded.\n", p[1]); - else - SetWeek(Raw, I2(p+6), ((double) I4(p+2)) * 0.001); - - return 0; +static int DecodeGSOF26(raw_t *Raw, uint8_t *p) { + if (p[1] < 6) + tracet(2, + "RT17: GSOF Position Time UTC message record length %d < 6 bytes. Record discarded.\n", + p[1]); + else + SetWeek(Raw, I2(p + 6), ((double)I4(p + 2)) * 0.001); + + return 0; } /* DecodeGSOF41 - Decode a Base Position and Quality Indicator GSOF message */ -static int DecodeGSOF41(raw_t *raw, uint8_t *p) -{ - if (p[1] < 6) - tracet(2, "RT17: GSOF Base Position and Quality Indicator message record length %d < 6 bytes. Record discarded.\n", p[1]); - else - SetWeek(raw, I2(p+6), ((double) I4(p+2)) * 0.001); - - return 0; +static int DecodeGSOF41(raw_t *raw, uint8_t *p) { + if (p[1] < 6) + tracet(2, + "RT17: GSOF Base Position and Quality Indicator message record length %d < 6 bytes. " + "Record discarded.\n", + p[1]); + else + SetWeek(raw, I2(p + 6), ((double)I4(p + 2)) * 0.001); + + return 0; } /* @@ -1366,47 +1316,47 @@ static int DecodeGSOF41(raw_t *raw, uint8_t *p) | See ICD-GPS-200C.PDF for documetation of GPS ION / UTC data. | See reference #1 above for documentation of RETSVDATA and ION / UTC data. */ -static int DecodeIONAndUTCData(raw_t *Raw) -{ - rt17_t *rt17 = (rt17_t*) Raw->rcv_data; - int week; - uint8_t *p = rt17->PacketBuffer; - nav_t *nav = &Raw->nav; - double *ion_gps = nav->ion_gps; - double *utc_gps = nav->utc_gps; - - tracet(3, "RT17: DecodeIONAndUTCData, Length=%d.\n", rt17->PacketLength); - - if (rt17->PacketLength < 129) - { - tracet(2, "RT17: RETSVDATA packet length %d < 129 bytes. GPS ION / UTC data packet discarded.\n", rt17->PacketLength); - return -1; - } - - /* ION / UTC data does not have the current GPS week number. Punt! */ - week = GetWeek(Raw, 0.0); - - ion_gps[0] = R8(p+6); /* 006-013: ALPHA 0 (seconds) */ - ion_gps[1] = R8(p+14); /* 014-021: ALPHA 1 (seconds/semi-circle) */ - ion_gps[2] = R8(p+22); /* 022-029: ALPHA 2 (seconds/semi-circle)^2 */ - ion_gps[3] = R8(p+30); /* 030-037: ALPHA 3 (seconds/semi-circle)^3 */ - ion_gps[4] = R8(p+38); /* 038-045: BETA 0 (seconds) */ - ion_gps[5] = R8(p+46); /* 046-053: BETA 1 (seconds/semi-circle) */ - ion_gps[6] = R8(p+54); /* 054-061: BETA 2 (seconds/semi-circle)^2 */ - ion_gps[7] = R8(p+62); /* 062-069: BETA 3 (seconds/semi-circle)^3 */ - utc_gps[0] = R8(p+70); /* 070-077: ASUB0 (seconds)*/ - utc_gps[1] = R8(p+78); /* 078-085: ASUB1 (seconds/seconds) */ - utc_gps[2] = R8(p+86); /* 086-093: TSUB0T */ - utc_gps[3] = week; - utc_gps[4] = R8(p+94); /* 094-101: DELTATLS (seconds) */ - /* Unused by RTKLIB R8 */ /* 102-109: DELTATLSF */ - /* Unused by RTKLIB R8 */ /* 110-117: IONTIME */ - /* Unused by RTKLIB U1 */ /* 118-118: WNSUBT */ - /* Unused by RTKLIB U1 */ /* 119-119: WNSUBLSF */ - /* Unused by RTKLIB U1 */ /* 120-120: DN */ - /* Reserved six bytes */ /* 121-126: RESERVED */ - - return 9; +static int DecodeIONAndUTCData(raw_t *Raw) { + rt17_t *rt17 = (rt17_t *)Raw->rcv_data; + int week; + uint8_t *p = rt17->PacketBuffer; + nav_t *nav = &Raw->nav; + double *ion_gps = nav->ion_gps; + double *utc_gps = nav->utc_gps; + + tracet(3, "RT17: DecodeIONAndUTCData, Length=%d.\n", rt17->PacketLength); + + if (rt17->PacketLength < 129) { + tracet(2, + "RT17: RETSVDATA packet length %d < 129 bytes. GPS ION / UTC data packet discarded.\n", + rt17->PacketLength); + return -1; + } + + /* ION / UTC data does not have the current GPS week number. Punt! */ + week = GetWeek(Raw, 0.0); + + ion_gps[0] = R8(p + 6); /* 006-013: ALPHA 0 (seconds) */ + ion_gps[1] = R8(p + 14); /* 014-021: ALPHA 1 (seconds/semi-circle) */ + ion_gps[2] = R8(p + 22); /* 022-029: ALPHA 2 (seconds/semi-circle)^2 */ + ion_gps[3] = R8(p + 30); /* 030-037: ALPHA 3 (seconds/semi-circle)^3 */ + ion_gps[4] = R8(p + 38); /* 038-045: BETA 0 (seconds) */ + ion_gps[5] = R8(p + 46); /* 046-053: BETA 1 (seconds/semi-circle) */ + ion_gps[6] = R8(p + 54); /* 054-061: BETA 2 (seconds/semi-circle)^2 */ + ion_gps[7] = R8(p + 62); /* 062-069: BETA 3 (seconds/semi-circle)^3 */ + utc_gps[0] = R8(p + 70); /* 070-077: ASUB0 (seconds)*/ + utc_gps[1] = R8(p + 78); /* 078-085: ASUB1 (seconds/seconds) */ + utc_gps[2] = R8(p + 86); /* 086-093: TSUB0T */ + utc_gps[3] = week; + utc_gps[4] = R8(p + 94); /* 094-101: DELTATLS (seconds) */ + /* Unused by RTKLIB R8 */ /* 102-109: DELTATLSF */ + /* Unused by RTKLIB R8 */ /* 110-117: IONTIME */ + /* Unused by RTKLIB U1 */ /* 118-118: WNSUBT */ + /* Unused by RTKLIB U1 */ /* 119-119: WNSUBLSF */ + /* Unused by RTKLIB U1 */ /* 120-120: DN */ + /* Reserved six bytes */ /* 121-126: RESERVED */ + + return 9; } /* @@ -1419,134 +1369,130 @@ static int DecodeIONAndUTCData(raw_t *Raw) | | See reference #1 above for documentation of the RETSVDATA QZSS Ephemeris. */ -static int DecodeQZSSEphemeris(raw_t *Raw) -{ - (void)Raw; - tracet(3, "DecodeQZSSEphemeris(); not yet implemented.\n"); - return 0; +static int DecodeQZSSEphemeris(raw_t *Raw) { + (void)Raw; + tracet(3, "DecodeQZSSEphemeris(); not yet implemented.\n"); + return 0; #ifdef RTK_DISABLED - rt17_t *rt17 = (rt17_t*) Raw->rcv_data; - uint8_t *p = rt17->PacketBuffer; - int prn, sat, toc, tow; - uint32_t Flags, toe; - double sqrtA; - eph_t eph={0}; - tracet(3, "RT17: DecodeQZSSEphemeris(); Length=%d\n", rt17->PacketLength); - if (rt17->PacketLength < 184) - { - tracet(2, "RT17: RETSVDATA packet length %d < 184 bytes. QZSS ephemeris packet discarded.\n", rt17->PacketLength); - return -1; - } - prn = U1(p+5); - if (!(sat=satno(SYS_GPS, prn))) - { - tracet(2, "RT17: QZSS ephemeris satellite number error, PRN=%d.\n", prn); - return -1; - } - - /* Not used by RTKLIB 006-006: Source: 0:L1CA 1:L1C 2:L2C 3:L5 */ - eph.week = U2(p+8); /* 008-009: Ephemeris Week number (weeks) */ - eph.iodc = U2(p+10); /* 010-011: IODC */ - /* Reserved byte 012-012: RESERVED */ - eph.iode = U1(p+13); /* 013-013: IODE */ - tow = I4(p+14); /* 014-017: TOW */ - toc = I4(p+18); /* 018-021: TOC (seconds) */ - toe = U4(p+22); /* 022-025: TOE (seconds) */ - eph.tgd[0]= R8(p+26); /* 026-033: TGD (seconds) */ - eph.f2 = R8(p+34); /* 034-041: AF2 (seconds/seconds^2) */ - eph.f1 = R8(p+42); /* 042-049: AF1 (seconds/seconds) */ - eph.f0 = R8(p+50); /* 050-057: AF0 (seconds) */ - eph.crs = R8(p+58); /* 058-065: CRS (meters) */ - eph.deln = R8(p+66); /* 066-073: DELTA N (semi-circles/second) */ - eph.M0 = R8(p+74); /* 074-081: M SUB 0 (semi-circles) */ - eph.cuc = R8(p+82); /* 082-089: CUC (semi-circles) */ - eph.e = R8(p+90); /* 090-097: ECCENTRICITY (dimensionless) */ - eph.cus = R8(p+98); /* 098-105: CUS (semi-circles) */ - sqrtA = R8(p+106); /* 106-113: SQRT A (meters ^ 0.5) */ - eph.cic = R8(p+114); /* 114-121: CIC (semi-circles) */ - eph.OMG0 = R8(p+122); /* 122-129: OMEGA SUB 0 (semi-circles) */ - eph.cis = R8(p+130); /* 130-137: CIS (semi-circlces) */ - eph.i0 = R8(p+138); /* 138-145: I SUB 0 (semi-circles) */ - eph.crc = R8(p+146); /* 146-153: CRC (meters) */ - eph.omg = R8(p+154); /* 154-161: OMEGA (semi-circles?) */ - eph.OMGd = R8(p+162); /* 162-169: OMEGA DOT (semi-circles/second) */ - eph.idot = R8(p+170); /* 170-177: I DOT (semi-circles/second) */ - Flags = U4(p+178); /* 178-181: FLAGS */ - - /* - | Multiply these by PI to make ICD specified semi-circle units into radian - | units for RTKLIB. - */ - eph.deln *= SC2RAD; - eph.i0 *= SC2RAD; - eph.idot *= SC2RAD; - eph.M0 *= SC2RAD; - eph.omg *= SC2RAD; - eph.OMG0 *= SC2RAD; - eph.OMGd *= SC2RAD; - /* - | As specifically directed to do so by Reference #1, multiply these by PI. - | to make semi-circle units into radian units, which is what ICD-GPS-200C - | calls for and also what RTKLIB needs. - */ - eph.cic *= SC2RAD; - eph.cis *= SC2RAD; - eph.cuc *= SC2RAD; - eph.cus *= SC2RAD; - - /* - | Select the correct curve fit interval as per ICD-GPS-200 sections - | 20.3.3.4.3.1 and 20.3.4.4 using IODC, fit flag and Table 20-XII. - */ - if (Flags & M_BIT10) /* Subframe 2, word 10, bit 17 (fit flag) */ - { - if ((eph.iodc >= 240) && (eph.iodc <= 247)) - eph.fit = 8; - else if (((eph.iodc >= 248) && (eph.iodc <= 255)) || (eph.iodc == 496)) - eph.fit = 14; - else if ((eph.iodc >= 497) && (eph.iodc <= 503)) - eph.fit = 26; - else if ((eph.iodc >= 504) && (eph.iodc <= 510)) - eph.fit = 50; - else if ((eph.iodc == 511) || ((eph.iodc >= 752) && (eph.iodc <= 756))) - eph.fit = 74; - else if ((eph.iodc >= 757) && (eph.iodc <= 763)) - eph.fit = 98; - else if (((eph.iodc >= 764) && (eph.iodc <= 767)) || ((eph.iodc >= 1008) && (eph.iodc <= 1010))) - eph.fit = 122; - else if ((eph.iodc >= 1011) && (eph.iodc <= 1020)) - eph.fit = 146; - else - eph.fit = 6; - } + rt17_t *rt17 = (rt17_t *)Raw->rcv_data; + uint8_t *p = rt17->PacketBuffer; + int prn, sat, toc, tow; + uint32_t Flags, toe; + double sqrtA; + eph_t eph = {0}; + tracet(3, "RT17: DecodeQZSSEphemeris(); Length=%d\n", rt17->PacketLength); + if (rt17->PacketLength < 184) { + tracet(2, "RT17: RETSVDATA packet length %d < 184 bytes. QZSS ephemeris packet discarded.\n", + rt17->PacketLength); + return -1; + } + prn = U1(p + 5); + if (!(sat = satno(SYS_GPS, prn))) { + tracet(2, "RT17: QZSS ephemeris satellite number error, PRN=%d.\n", prn); + return -1; + } + + /* Not used by RTKLIB 006-006: Source: 0:L1CA 1:L1C 2:L2C 3:L5 */ + eph.week = U2(p + 8); /* 008-009: Ephemeris Week number (weeks) */ + eph.iodc = U2(p + 10); /* 010-011: IODC */ + /* Reserved byte 012-012: RESERVED */ + eph.iode = U1(p + 13); /* 013-013: IODE */ + tow = I4(p + 14); /* 014-017: TOW */ + toc = I4(p + 18); /* 018-021: TOC (seconds) */ + toe = U4(p + 22); /* 022-025: TOE (seconds) */ + eph.tgd[0] = R8(p + 26); /* 026-033: TGD (seconds) */ + eph.f2 = R8(p + 34); /* 034-041: AF2 (seconds/seconds^2) */ + eph.f1 = R8(p + 42); /* 042-049: AF1 (seconds/seconds) */ + eph.f0 = R8(p + 50); /* 050-057: AF0 (seconds) */ + eph.crs = R8(p + 58); /* 058-065: CRS (meters) */ + eph.deln = R8(p + 66); /* 066-073: DELTA N (semi-circles/second) */ + eph.M0 = R8(p + 74); /* 074-081: M SUB 0 (semi-circles) */ + eph.cuc = R8(p + 82); /* 082-089: CUC (semi-circles) */ + eph.e = R8(p + 90); /* 090-097: ECCENTRICITY (dimensionless) */ + eph.cus = R8(p + 98); /* 098-105: CUS (semi-circles) */ + sqrtA = R8(p + 106); /* 106-113: SQRT A (meters ^ 0.5) */ + eph.cic = R8(p + 114); /* 114-121: CIC (semi-circles) */ + eph.OMG0 = R8(p + 122); /* 122-129: OMEGA SUB 0 (semi-circles) */ + eph.cis = R8(p + 130); /* 130-137: CIS (semi-circlces) */ + eph.i0 = R8(p + 138); /* 138-145: I SUB 0 (semi-circles) */ + eph.crc = R8(p + 146); /* 146-153: CRC (meters) */ + eph.omg = R8(p + 154); /* 154-161: OMEGA (semi-circles?) */ + eph.OMGd = R8(p + 162); /* 162-169: OMEGA DOT (semi-circles/second) */ + eph.idot = R8(p + 170); /* 170-177: I DOT (semi-circles/second) */ + Flags = U4(p + 178); /* 178-181: FLAGS */ + + /* + | Multiply these by PI to make ICD specified semi-circle units into radian + | units for RTKLIB. + */ + eph.deln *= SC2RAD; + eph.i0 *= SC2RAD; + eph.idot *= SC2RAD; + eph.M0 *= SC2RAD; + eph.omg *= SC2RAD; + eph.OMG0 *= SC2RAD; + eph.OMGd *= SC2RAD; + /* + | As specifically directed to do so by Reference #1, multiply these by PI. + | to make semi-circle units into radian units, which is what ICD-GPS-200C + | calls for and also what RTKLIB needs. + */ + eph.cic *= SC2RAD; + eph.cis *= SC2RAD; + eph.cuc *= SC2RAD; + eph.cus *= SC2RAD; + + /* + | Select the correct curve fit interval as per ICD-GPS-200 sections + | 20.3.3.4.3.1 and 20.3.4.4 using IODC, fit flag and Table 20-XII. + */ + if (Flags & M_BIT10) /* Subframe 2, word 10, bit 17 (fit flag) */ + { + if ((eph.iodc >= 240) && (eph.iodc <= 247)) + eph.fit = 8; + else if (((eph.iodc >= 248) && (eph.iodc <= 255)) || (eph.iodc == 496)) + eph.fit = 14; + else if ((eph.iodc >= 497) && (eph.iodc <= 503)) + eph.fit = 26; + else if ((eph.iodc >= 504) && (eph.iodc <= 510)) + eph.fit = 50; + else if ((eph.iodc == 511) || ((eph.iodc >= 752) && (eph.iodc <= 756))) + eph.fit = 74; + else if ((eph.iodc >= 757) && (eph.iodc <= 763)) + eph.fit = 98; + else if (((eph.iodc >= 764) && (eph.iodc <= 767)) || ((eph.iodc >= 1008) && (eph.iodc <= 1010))) + eph.fit = 122; + else if ((eph.iodc >= 1011) && (eph.iodc <= 1020)) + eph.fit = 146; else - eph.fit = 4; - - eph.flag = (Flags & M_BIT0); /* Subframe 1, word 4, bit 1, Data flag for L2 P-code */ - eph.code = (Flags >> 1) & 3; /* Subframe 1, word 3, bits 11-12, Codes on L2 channel */ - eph.svh = (Flags >> 4) & 127; /* Subframe 1, word 3, bits 17-22, SV health from ephemeris */ - eph.sva = (Flags >> 11) & 15; /* Subframe 1, word 3, bits 13-16, User Range Accuracy index */ - eph.A = sqrtA * sqrtA; - eph.toes = toe; - eph.toc = gpst2time(eph.week, toc); - eph.toe = gpst2time(eph.week, toe); - eph.ttr = gpst2time(eph.week, tow); - tracet(3, "RT17: DecodeQZSSEphemeris(); SAT=%d, IODC=%d, IODE=%d, WEEK=%d.\n", sat, eph.iodc, eph.iode, eph.week); - if (!strstr(Raw->opt,"-EPHALL")) - { - if (eph.iode == Raw->nav.eph[sat-1].iode) - return 0; /* unchanged */ - } - eph.sat = sat; - Raw->nav.eph[sat-1] = eph; - Raw->ephsat = sat; - return 2; + eph.fit = 6; + } else + eph.fit = 4; + + eph.flag = (Flags & M_BIT0); /* Subframe 1, word 4, bit 1, Data flag for L2 P-code */ + eph.code = (Flags >> 1) & 3; /* Subframe 1, word 3, bits 11-12, Codes on L2 channel */ + eph.svh = (Flags >> 4) & 127; /* Subframe 1, word 3, bits 17-22, SV health from ephemeris */ + eph.sva = (Flags >> 11) & 15; /* Subframe 1, word 3, bits 13-16, User Range Accuracy index */ + eph.A = sqrtA * sqrtA; + eph.toes = toe; + eph.toc = gpst2time(eph.week, toc); + eph.toe = gpst2time(eph.week, toe); + eph.ttr = gpst2time(eph.week, tow); + tracet(3, "RT17: DecodeQZSSEphemeris(); SAT=%d, IODC=%d, IODE=%d, WEEK=%d.\n", sat, eph.iodc, + eph.iode, eph.week); + if (!strstr(Raw->opt, "-EPHALL")) { + if (eph.iode == Raw->nav.eph[sat - 1].iode) return 0; /* unchanged */ + } + eph.sat = sat; + Raw->nav.eph[sat - 1] = eph; + Raw->ephsat = sat; + return 2; #endif } /* -| DecodeRawdata - Decode an RAWDATA packet sequence +| DecodeRawdata - Decode an RAWDATA packet sequence | | Returns: | @@ -1554,47 +1500,45 @@ static int DecodeQZSSEphemeris(raw_t *Raw) | 0: no message (tells caller to please read more data from the stream) | 1: input observation data */ -static int DecodeRawdata(raw_t *Raw) -{ - rt17_t *rt17 = (rt17_t*) Raw->rcv_data; - uint8_t *MessageBuffer = rt17->MessageBuffer; - int Ret = 0; - uint32_t rif; - char *RecordType_s = NULL; - uint8_t RecordType = MessageBuffer[4]; - - if (RecordType < (sizeof(RawdataTable) / sizeof(char*))) - RecordType_s = (char*) RawdataTable[RecordType]; - - if (!RecordType_s) - RecordType_s = "Unknown"; - - tracet(3, "RT17: Trimble packet type=0x57 (RAWDATA), Recordtype=%d (%s), Length=%d.\n", RecordType, RecordType_s, rt17->MessageLength); - - /* - | Reassemble origional message by removing packet headers, - | trailers and page framing. - */ - UnwrapRawdata(rt17, &rif); - - /* Process (or possibly ignore) the message */ - switch (RecordType) - { +static int DecodeRawdata(raw_t *Raw) { + rt17_t *rt17 = (rt17_t *)Raw->rcv_data; + uint8_t *MessageBuffer = rt17->MessageBuffer; + int Ret = 0; + uint32_t rif; + char *RecordType_s = NULL; + uint8_t RecordType = MessageBuffer[4]; + + if (RecordType < (sizeof(RawdataTable) / sizeof(char *))) + RecordType_s = (char *)RawdataTable[RecordType]; + + if (!RecordType_s) RecordType_s = "Unknown"; + + tracet(3, "RT17: Trimble packet type=0x57 (RAWDATA), Recordtype=%d (%s), Length=%d.\n", + RecordType, RecordType_s, rt17->MessageLength); + + /* + | Reassemble origional message by removing packet headers, + | trailers and page framing. + */ + UnwrapRawdata(rt17, &rif); + + /* Process (or possibly ignore) the message */ + switch (RecordType) { case 0: - Ret = DecodeType17(Raw, rif); - break; + Ret = DecodeType17(Raw, rif); + break; case 7: - Ret = DecodeType29(Raw); - break; + Ret = DecodeType29(Raw); + break; default: - tracet(3, "RT17: Packet not processed.\n"); - } + tracet(3, "RT17: Packet not processed.\n"); + } - return Ret; + return Ret; } /* -| DecodeRetsvdata - Decode an SVDATA packet +| DecodeRetsvdata - Decode an SVDATA packet | | Returns: | @@ -1603,48 +1547,46 @@ static int DecodeRawdata(raw_t *Raw) | 2: input ephemeris | 9: input ion/utc parameter */ -static int DecodeRetsvdata(raw_t *Raw) -{ - rt17_t *rt17 = (rt17_t*) Raw->rcv_data; - uint8_t *PacketBuffer = rt17->PacketBuffer; - int Ret = 0; - char *Subtype_s = NULL; - uint8_t Subtype = PacketBuffer[4]; - - if (Subtype < (sizeof(RetsvdataTable) / sizeof(char*))) - Subtype_s = (char*) RetsvdataTable[Subtype]; - - if (!Subtype_s) - Subtype_s = "Unknown"; - - tracet(3, "RT17: Trimble packet type=0x55 (RETSVDATA), Subtype=%d (%s), Length=%d.\n", Subtype, Subtype_s, rt17->PacketLength); - - /* Process (or possibly ignore) the message */ - switch (Subtype) - { +static int DecodeRetsvdata(raw_t *Raw) { + rt17_t *rt17 = (rt17_t *)Raw->rcv_data; + uint8_t *PacketBuffer = rt17->PacketBuffer; + int Ret = 0; + char *Subtype_s = NULL; + uint8_t Subtype = PacketBuffer[4]; + + if (Subtype < (sizeof(RetsvdataTable) / sizeof(char *))) + Subtype_s = (char *)RetsvdataTable[Subtype]; + + if (!Subtype_s) Subtype_s = "Unknown"; + + tracet(3, "RT17: Trimble packet type=0x55 (RETSVDATA), Subtype=%d (%s), Length=%d.\n", Subtype, + Subtype_s, rt17->PacketLength); + + /* Process (or possibly ignore) the message */ + switch (Subtype) { case 1: - Ret = DecodeGPSEphemeris(Raw); - break; + Ret = DecodeGPSEphemeris(Raw); + break; case 3: - Ret = DecodeIONAndUTCData(Raw); - break; + Ret = DecodeIONAndUTCData(Raw); + break; case 9: - Ret = DecodeGLONASSEphemeris(Raw); - break; + Ret = DecodeGLONASSEphemeris(Raw); + break; case 11: - Ret = DecodeGalileoEphemeris(Raw); - break; + Ret = DecodeGalileoEphemeris(Raw); + break; case 14: - Ret = DecodeQZSSEphemeris(Raw); - break; + Ret = DecodeQZSSEphemeris(Raw); + break; case 21: - Ret = DecodeBeidouEphemeris(Raw); - break; + Ret = DecodeBeidouEphemeris(Raw); + break; default: - tracet(3, "RT17: Packet not processed.\n"); - } + tracet(3, "RT17: Packet not processed.\n"); + } - return Ret; + return Ret; } /* @@ -1658,240 +1600,233 @@ static int DecodeRetsvdata(raw_t *Raw) | | Handles expanded and concise formats with and without enhanced record data. */ -static int DecodeType17(raw_t *Raw, uint32_t rif) -{ - rt17_t *rt17 = (rt17_t*) Raw->rcv_data; - uint8_t *p = rt17->MessageBuffer; - double ClockOffset, tow; - int Flags1, Flags2, FlagStatus, i, n, nsat, prn, Week; - gtime_t Time; - obsd_t *obs; - - tow = R8(p) * 0.001; p += 8; /* Receive time within the current GPS week. */ - ClockOffset = R8(p) * 0.001; p += 8; /* Clock offset value. 0.0 = not known */ +static int DecodeType17(raw_t *Raw, uint32_t rif) { + rt17_t *rt17 = (rt17_t *)Raw->rcv_data; + uint8_t *p = rt17->MessageBuffer; + double ClockOffset, tow; + int Flags1, Flags2, FlagStatus, i, n, nsat, prn, Week; + gtime_t Time; + obsd_t *obs; + + tow = R8(p) * 0.001; + p += 8; /* Receive time within the current GPS week. */ + ClockOffset = R8(p) * 0.001; + p += 8; /* Clock offset value. 0.0 = not known */ #ifdef RTK_DISABLED - tow += ClockOffset; + tow += ClockOffset; #endif - - /* The observation data does not have the current GPS week number. Punt! */ - Week = GetWeek(Raw, tow); - Time = gpst2time(Week, tow); - nsat = U1(p); p++; /* Number of SV data blocks in the record */ - - for (i = n = 0; (i < nsat) && (i < MAXOBS); i++) + /* The observation data does not have the current GPS week number. Punt! */ + Week = GetWeek(Raw, tow); + Time = gpst2time(Week, tow); + + nsat = U1(p); + p++; /* Number of SV data blocks in the record */ + + for (i = n = 0; (i < nsat) && (i < MAXOBS); i++) { + obs = &Raw->obs.data[n]; + memset(obs, 0, sizeof(obsd_t)); + obs->time = Time; + + if (rif & M_CONCISE) { + /* Satellite number (1-32). */ + prn = U1(p); + p++; + + /* These indicate what data is loaded, is valid, etc */ + Flags1 = U1(p); + p++; + Flags2 = U1(p); + p++; + + /* These are not needed by RTKLIB */ + p++; /* I1 Satellite Elevation Angle (degrees) */ + p += 2; /* I2 Satellite Azimuth (degrees) */ + + if (Flags1 & M_BIT6) /* L1 data valid */ + { + /* Measure of L1 signal strength (dB * 4) */ + obs->SNR[0] = U1(p) * 0.25; + p++; + + /* Full L1 C/A code or P-code pseudorange (meters) */ + obs->P[0] = R8(p); + p += 8; + + /* L1 Continuous Phase (cycles) */ + if (Flags1 & M_BIT4) /* L1 phase valid */ + obs->L[0] = -R8(p); + p += 8; + + /* L1 Doppler (Hz) */ + obs->D[0] = R4(p); + p += 4; + } + + if (Flags1 & M_BIT0) /* L2 data loaded */ + { + /* Measure of L2 signal strength (dB * 4) */ + obs->SNR[1] = U1(p) * 0.25; + p++; + + /* L2 Continuous Phase (cycles) */ + if (Flags1 & M_BIT5) obs->L[1] = -R8(p); + p += 8; + + /* L2 P-Code or L2 Encrypted Code */ + if (Flags1 & M_BIT5) /* L2 range valid */ + obs->P[1] = obs->P[0] + R4(p); + p += 4; + } + + /* + | We can't use the IODE flags in this context. + | We already have slip flags and don't need slip counters. + */ + if (rif & M_ENHANCED) { + p++; /* U1 IODE, Issue of Data Ephemeris */ + p++; /* U1 L1 cycle slip roll-over counter */ + p++; /* U1 L2 cycle slip roll-over counter */ + } + } else /* Expanded Format */ { - obs = &Raw->obs.data[n]; - memset(obs, 0, sizeof(obsd_t)); - obs->time = Time; - - if (rif & M_CONCISE) - { - /* Satellite number (1-32). */ - prn = U1(p); - p++; - - /* These indicate what data is loaded, is valid, etc */ - Flags1 = U1(p); - p++; - Flags2 = U1(p); - p++; - - /* These are not needed by RTKLIB */ - p++; /* I1 Satellite Elevation Angle (degrees) */ - p += 2; /* I2 Satellite Azimuth (degrees) */ - - if (Flags1 & M_BIT6) /* L1 data valid */ - { - /* Measure of L1 signal strength (dB * 4) */ - obs->SNR[0] = U1(p)*0.25; - p++; - - /* Full L1 C/A code or P-code pseudorange (meters) */ - obs->P[0] = R8(p); - p += 8; - - /* L1 Continuous Phase (cycles) */ - if (Flags1 & M_BIT4) /* L1 phase valid */ - obs->L[0] = -R8(p); - p += 8; - - /* L1 Doppler (Hz) */ - obs->D[0] = R4(p); - p += 4; - } - - if (Flags1 & M_BIT0) /* L2 data loaded */ - { - /* Measure of L2 signal strength (dB * 4) */ - obs->SNR[1] = U1(p)*0.25; - p++; - - /* L2 Continuous Phase (cycles) */ - if (Flags1 & M_BIT5) - obs->L[1] = -R8(p); - p += 8; - - /* L2 P-Code or L2 Encrypted Code */ - if (Flags1 & M_BIT5) /* L2 range valid */ - obs->P[1] = obs->P[0] + R4(p); - p += 4; - } - - /* - | We can't use the IODE flags in this context. - | We already have slip flags and don't need slip counters. - */ - if (rif & M_ENHANCED) - { - p++; /* U1 IODE, Issue of Data Ephemeris */ - p++; /* U1 L1 cycle slip roll-over counter */ - p++; /* U1 L2 cycle slip roll-over counter */ - } - } - else /* Expanded Format */ - { - /* Satellite number (1-32) */ - prn = U1(p); - p++; - - /* These indicate what data is loaded, is valid, etc */ - Flags1 = U1(p); - p++; - Flags2 = U1(p); - p++; - - /* Indicates whether FLAGS1 bit 6 and FLAGS2 are valid */ - FlagStatus = U1(p); - p++; - - /* These are not needed by RTKLIB */ - p += 2; /* I2 Satellite Elevation Angle (degrees) */ - p += 2; /* I2 Satellite Azimuth (degrees) */ - - /* - | FLAG STATUS bit 0 set = Bit 6 of FLAGS1 and bit 0-7 of FLAGS2 are valid. - | FLAG STATUS bit 0 clear = Bit 6 of FLAGS1 and bit 0-7 of FLAGS2 are UNDEFINED. - | - | According to reference #1 above, this bit should ALWAYS be set - | for RAWDATA. If this bit is not set, then we're lost and cannot - | process this message any further. - */ - if (!(FlagStatus & M_BIT0)) /* Flags invalid */ - return 0; - - if (Flags1 & M_BIT6) /* L1 data valid */ - { - /* Measure of satellite signal strength (dB) */ - obs->SNR[0] = R8(p); - p += 8; - - /* Full L1 C/A code or P-code pseudorange (meters) */ - obs->P[0] = R8(p); - p += 8; - - /* L1 Continuous Phase (cycles) */ - if (Flags1 & M_BIT4) /* L1 phase valid */ - obs->L[0] = -R8(p); - p += 8; - - /* L1 Doppler (Hz) */ - obs->D[0] = R8(p); - p += 8; - - /* Reserved 8 bytes */ - p += 8; - } - - if (Flags1 & M_BIT0) /* L2 data loaded */ - { - /* Measure of L2 signal strength (dB) */ - obs->SNR[1] = R8(p); - p += 8; - - /* L2 Continuous Phase (cycles) */ - if (Flags1 & M_BIT5) /* L2 phase valid */ - obs->L[1] = -R8(p); - p += 8; - - /* L2 P-Code or L2 Encrypted Code */ - if (Flags1 & M_BIT5) /* L2 pseudorange valid */ - obs->P[1] = obs->P[0] + R8(p); - p += 8; - } - - if (rif & M_ENHANCED) - { - /* - | We can't use the IODE flags in this context. - | We already have slip flags and don't need slip counters. - */ - p++; /* U1 IODE, Issue of Data Ephemeris */ - p++; /* U1 L1 cycle slip roll-over counter */ - p++; /* U1 L2 cycle slip roll-over counter */ - p++; /* U1 Reserved byte */ - - /* L2 Doppler (Hz) */ - obs->D[1] = R8(p); - p += 8; - } - } - - obs->code[0] = (obs->P[0] == 0.0) ? CODE_NONE : (Flags2 & M_BIT0) ? CODE_L1P : CODE_L1C; - obs->code[1] = (obs->P[1] == 0.0) ? CODE_NONE : (Flags2 & M_BIT2) ? CODE_L2W : (Flags2 & M_BIT1) ? CODE_L2P : CODE_L2C; - - if (Flags1 & M_BIT1) - obs->LLI[0] |= 1; /* L1 cycle slip */ - - if (Flags1 & M_BIT2) - obs->LLI[1] |= 1; /* L2 cycle slip */ - if ((Flags2 & M_BIT2) && (obs->P[1] != 0.0)) - obs->LLI[1] |= 4; /* Tracking encrypted code */ - - if (!(obs->sat = satno(SYS_GPS, prn))) - { - tracet(2, "RT17: Satellite number error, PRN=%d.\n", prn); - continue; - } + /* Satellite number (1-32) */ + prn = U1(p); + p++; + + /* These indicate what data is loaded, is valid, etc */ + Flags1 = U1(p); + p++; + Flags2 = U1(p); + p++; + + /* Indicates whether FLAGS1 bit 6 and FLAGS2 are valid */ + FlagStatus = U1(p); + p++; + + /* These are not needed by RTKLIB */ + p += 2; /* I2 Satellite Elevation Angle (degrees) */ + p += 2; /* I2 Satellite Azimuth (degrees) */ + + /* + | FLAG STATUS bit 0 set = Bit 6 of FLAGS1 and bit 0-7 of FLAGS2 are valid. + | FLAG STATUS bit 0 clear = Bit 6 of FLAGS1 and bit 0-7 of FLAGS2 are UNDEFINED. + | + | According to reference #1 above, this bit should ALWAYS be set + | for RAWDATA. If this bit is not set, then we're lost and cannot + | process this message any further. + */ + if (!(FlagStatus & M_BIT0)) /* Flags invalid */ + return 0; -#ifdef RTK_DISABLED - /* Apply clock offset to observables */ - if (ClockOffset != 0.0) - { - obs->P[0] += ClockOffset * (CLIGHT/FREQL1); - obs->P[1] += ClockOffset * (CLIGHT/FREQL2); - obs->L[0] += ClockOffset * FREQL1; - obs->L[1] += ClockOffset * FREQL2; - } -#endif - n++; + if (Flags1 & M_BIT6) /* L1 data valid */ + { + /* Measure of satellite signal strength (dB) */ + obs->SNR[0] = R8(p); + p += 8; + + /* Full L1 C/A code or P-code pseudorange (meters) */ + obs->P[0] = R8(p); + p += 8; + + /* L1 Continuous Phase (cycles) */ + if (Flags1 & M_BIT4) /* L1 phase valid */ + obs->L[0] = -R8(p); + p += 8; + + /* L1 Doppler (Hz) */ + obs->D[0] = R8(p); + p += 8; + + /* Reserved 8 bytes */ + p += 8; + } + + if (Flags1 & M_BIT0) /* L2 data loaded */ + { + /* Measure of L2 signal strength (dB) */ + obs->SNR[1] = R8(p); + p += 8; + + /* L2 Continuous Phase (cycles) */ + if (Flags1 & M_BIT5) /* L2 phase valid */ + obs->L[1] = -R8(p); + p += 8; + + /* L2 P-Code or L2 Encrypted Code */ + if (Flags1 & M_BIT5) /* L2 pseudorange valid */ + obs->P[1] = obs->P[0] + R8(p); + p += 8; + } + + if (rif & M_ENHANCED) { + /* + | We can't use the IODE flags in this context. + | We already have slip flags and don't need slip counters. + */ + p++; /* U1 IODE, Issue of Data Ephemeris */ + p++; /* U1 L1 cycle slip roll-over counter */ + p++; /* U1 L2 cycle slip roll-over counter */ + p++; /* U1 Reserved byte */ + + /* L2 Doppler (Hz) */ + obs->D[1] = R8(p); + p += 8; + } } - Raw->time = Time; - Raw->obs.n = n; - - if (n > 0) - { - tracet(2, "RT17: Observations output:\n"); - traceobs(2, Raw->obs.data, Raw->obs.n); + obs->code[0] = (obs->P[0] == 0.0) ? CODE_NONE : (Flags2 & M_BIT0) ? CODE_L1P : CODE_L1C; + obs->code[1] = (obs->P[1] == 0.0) ? CODE_NONE + : (Flags2 & M_BIT2) ? CODE_L2W + : (Flags2 & M_BIT1) ? CODE_L2P + : CODE_L2C; + + if (Flags1 & M_BIT1) obs->LLI[0] |= 1; /* L1 cycle slip */ + + if (Flags1 & M_BIT2) obs->LLI[1] |= 1; /* L2 cycle slip */ + if ((Flags2 & M_BIT2) && (obs->P[1] != 0.0)) obs->LLI[1] |= 4; /* Tracking encrypted code */ + + if (!(obs->sat = satno(SYS_GPS, prn))) { + tracet(2, "RT17: Satellite number error, PRN=%d.\n", prn); + continue; } - return (n > 0); +#ifdef RTK_DISABLED + /* Apply clock offset to observables */ + if (ClockOffset != 0.0) { + obs->P[0] += ClockOffset * (CLIGHT / FREQL1); + obs->P[1] += ClockOffset * (CLIGHT / FREQL2); + obs->L[0] += ClockOffset * FREQL1; + obs->L[1] += ClockOffset * FREQL2; + } +#endif + n++; + } + + Raw->time = Time; + Raw->obs.n = n; + + if (n > 0) { + tracet(2, "RT17: Observations output:\n"); + traceobs(2, Raw->obs.data, Raw->obs.n); + } + + return (n > 0); } /* DecodeType29 - Decode Enhanced position (record type 29) */ -static int DecodeType29(raw_t *Raw) -{ - rt17_t *rt17 = (rt17_t*) Raw->rcv_data; - uint8_t *p = rt17->MessageBuffer; +static int DecodeType29(raw_t *Raw) { + rt17_t *rt17 = (rt17_t *)Raw->rcv_data; + uint8_t *p = rt17->MessageBuffer; - if (*p < 7) - tracet(2, "RT17: Enhanced Position record block #1 length %d < 7 bytes. Record discarded.\n", *p); - else - SetWeek(Raw, I2(p+1), ((double) I4(p+3)) * 0.001); + if (*p < 7) + tracet(2, "RT17: Enhanced Position record block #1 length %d < 7 bytes. Record discarded.\n", + *p); + else + SetWeek(Raw, I2(p + 1), ((double)I4(p + 3)) * 0.001); - return 0; + return 0; } /* @@ -1903,157 +1838,178 @@ static int DecodeType29(raw_t *Raw) | Week rollover and increment from the initial week and | subsequent weeks is handled. */ -static int GetWeek(raw_t *Raw, double Tow) -{ - rt17_t *rt17 = (rt17_t*) Raw->rcv_data; - int Week = 0; - - if (rt17->Flags & M_WEEK_OPTION) - { - if ((Tow && rt17->Tow) && (Tow < rt17->Tow)) - { - tracet(2, "RT17: GPS WEEK rolled over from %d to %d.\n", rt17->Week, rt17->Week + 1); - rt17->Week++; - } - - if (Tow != 0.0) - rt17->Tow = Tow; - } - else if (!(rt17->Flags & M_WEEK_SCAN)) - { - char *opt = strstr(Raw->opt, "-WEEK="); - - rt17->Flags |= M_WEEK_SCAN; - - if (opt) - { - if (!sscanf(opt+6, "%d", &Week) || (Week <= 0)) - tracet(0, "RT17: Invalid -WEEK=n receiver option value.\n"); - else - { - rt17->Week = Week; - rt17->Flags |= M_WEEK_OPTION; - tracet(2, "RT17: Initial GPS WEEK explicitly set to %d by user.\n", Week, Week); - } - } +static int GetWeek(raw_t *Raw, double Tow) { + rt17_t *rt17 = (rt17_t *)Raw->rcv_data; + int Week = 0; + + if (rt17->Flags & M_WEEK_OPTION) { + if ((Tow && rt17->Tow) && (Tow < rt17->Tow)) { + tracet(2, "RT17: GPS WEEK rolled over from %d to %d.\n", rt17->Week, rt17->Week + 1); + rt17->Week++; } - Week = rt17->Week; + if (Tow != 0.0) rt17->Tow = Tow; + } else if (!(rt17->Flags & M_WEEK_SCAN)) { + char *opt = strstr(Raw->opt, "-WEEK="); - if (!Week && !(rt17->Flags & (M_WEEK_OPTION|M_WEEK_EPH))) - { - if ((Raw->time.time == 0) && (Raw->time.sec == 0.0)) - Raw->time = timeget(); - - time2gpst(Raw->time, &Week); - - if (Tow != 0.0) - Raw->time = gpst2time(Week, Tow); + rt17->Flags |= M_WEEK_SCAN; + if (opt) { + if (!sscanf(opt + 6, "%d", &Week) || (Week <= 0)) + tracet(0, "RT17: Invalid -WEEK=n receiver option value.\n"); + else { rt17->Week = Week; - rt17->Flags |= M_WEEK_TIME; - tracet(2, "RT17: Initial GPS WEEK number unknown; WEEK number %d assumed for now.\n", Week); + rt17->Flags |= M_WEEK_OPTION; + tracet(2, "RT17: Initial GPS WEEK explicitly set to %d by user.\n", Week, Week); + } } - - return Week; -} + } -/* ReadI2 - Fetch & convert a signed two byte integer (short) */ -static int16_t ReadI2(uint8_t *p) -{ - union I2 {int16_t i2; uint8_t c[2];} u; - ENDIAN_TEST et; + Week = rt17->Week; - memcpy(&u.i2, p, sizeof(u.i2)); + if (!Week && !(rt17->Flags & (M_WEEK_OPTION | M_WEEK_EPH))) { + if ((Raw->time.time == 0) && (Raw->time.sec == 0.0)) Raw->time = timeget(); - et.u2 = 0; et.c[0] = 1; - if (et.u2 == 1) - { - uint8_t t; - t = u.c[0]; u.c[0] = u.c[1]; u.c[1] = t; - } - return u.i2; -} + time2gpst(Raw->time, &Week); -/* ReadI4 - Fetch & convert a four byte signed integer (int) */ -static int32_t ReadI4(uint8_t *p) -{ - union i4 {int32_t i4; uint8_t c[4];} u; - ENDIAN_TEST et; + if (Tow != 0.0) Raw->time = gpst2time(Week, Tow); - memcpy(&u.i4, p, sizeof(u.i4)); + rt17->Week = Week; + rt17->Flags |= M_WEEK_TIME; + tracet(2, "RT17: Initial GPS WEEK number unknown; WEEK number %d assumed for now.\n", Week); + } - et.u2 = 0; et.c[0] = 1; - if (et.u2 == 1) - { - uint8_t t; - t = u.c[0]; u.c[0] = u.c[3]; u.c[3] = t; - t = u.c[1]; u.c[1] = u.c[2]; u.c[2] = t; - } - return u.i4; + return Week; +} + +/* ReadI2 - Fetch & convert a signed two byte integer (short) */ +static int16_t ReadI2(uint8_t *p) { + union I2 { + int16_t i2; + uint8_t c[2]; + } u; + ENDIAN_TEST et; + + memcpy(&u.i2, p, sizeof(u.i2)); + + et.u2 = 0; + et.c[0] = 1; + if (et.u2 == 1) { + uint8_t t; + t = u.c[0]; + u.c[0] = u.c[1]; + u.c[1] = t; + } + return u.i2; +} + +/* ReadI4 - Fetch & convert a four byte signed integer (int) */ +static int32_t ReadI4(uint8_t *p) { + union i4 { + int32_t i4; + uint8_t c[4]; + } u; + ENDIAN_TEST et; + + memcpy(&u.i4, p, sizeof(u.i4)); + + et.u2 = 0; + et.c[0] = 1; + if (et.u2 == 1) { + uint8_t t; + t = u.c[0]; + u.c[0] = u.c[3]; + u.c[3] = t; + t = u.c[1]; + u.c[1] = u.c[2]; + u.c[2] = t; + } + return u.i4; } /* ReadR4 - Fetch & convert an IEEE S_FLOAT (float) */ -static float ReadR4(uint8_t *p) -{ - union R4 {float f; uint32_t u4;} u; - u.u4 = U4(p); - return u.f; +static float ReadR4(uint8_t *p) { + union R4 { + float f; + uint32_t u4; + } u; + u.u4 = U4(p); + return u.f; } /* ReadR8 - Fetch & convert an IEEE T_FLOAT (double) */ -static double ReadR8(uint8_t *p) -{ - ENDIAN_TEST et; - union R8 {double d; uint8_t c[8];} u; - - memcpy(&u.d, p, sizeof(u.d)); - - et.u2 = 0; et.c[0] = 1; - if (et.u2 == 1) - { - uint8_t t; - t = u.c[0]; u.c[0] = u.c[7]; u.c[7] = t; - t = u.c[1]; u.c[1] = u.c[6]; u.c[6] = t; - t = u.c[2]; u.c[2] = u.c[5]; u.c[5] = t; - t = u.c[3]; u.c[3] = u.c[4]; u.c[4] = t; - } - return u.d; +static double ReadR8(uint8_t *p) { + ENDIAN_TEST et; + union R8 { + double d; + uint8_t c[8]; + } u; + + memcpy(&u.d, p, sizeof(u.d)); + + et.u2 = 0; + et.c[0] = 1; + if (et.u2 == 1) { + uint8_t t; + t = u.c[0]; + u.c[0] = u.c[7]; + u.c[7] = t; + t = u.c[1]; + u.c[1] = u.c[6]; + u.c[6] = t; + t = u.c[2]; + u.c[2] = u.c[5]; + u.c[5] = t; + t = u.c[3]; + u.c[3] = u.c[4]; + u.c[4] = t; + } + return u.d; } /* ReadU2 - Fetch & convert an unsigned twe byte integer (uint16_t) */ -static uint16_t ReadU2(uint8_t *p) -{ - ENDIAN_TEST et; - union U2 {uint16_t u2; uint8_t c[2];} u; - - memcpy(&u.u2, p, sizeof(u.u2)); - - et.u2 = 0; et.c[0] = 1; - if (et.u2 == 1) - { - uint8_t t; - t = u.c[0]; u.c[0] = u.c[1]; u.c[1] = t; - } - return u.u2; +static uint16_t ReadU2(uint8_t *p) { + ENDIAN_TEST et; + union U2 { + uint16_t u2; + uint8_t c[2]; + } u; + + memcpy(&u.u2, p, sizeof(u.u2)); + + et.u2 = 0; + et.c[0] = 1; + if (et.u2 == 1) { + uint8_t t; + t = u.c[0]; + u.c[0] = u.c[1]; + u.c[1] = t; + } + return u.u2; } /* ReadU4 - Fetch & convert a four byte uint32_teger (uint32_t) */ -static uint32_t ReadU4(uint8_t *p) -{ - ENDIAN_TEST et; - union U4 {uint32_t u4; uint8_t c[4];} u; - - memcpy(&u.u4, p, sizeof(u.u4)); - - et.u2 = 0; et.c[0] = 1; - if (et.u2 == 1) - { - uint8_t t; - t = u.c[0]; u.c[0] = u.c[3]; u.c[3] = t; - t = u.c[1]; u.c[1] = u.c[2]; u.c[2] = t; - } - return u.u4; +static uint32_t ReadU4(uint8_t *p) { + ENDIAN_TEST et; + union U4 { + uint32_t u4; + uint8_t c[4]; + } u; + + memcpy(&u.u4, p, sizeof(u.u4)); + + et.u2 = 0; + et.c[0] = 1; + if (et.u2 == 1) { + uint8_t t; + t = u.c[0]; + u.c[0] = u.c[3]; + u.c[3] = t; + t = u.c[1]; + u.c[1] = u.c[2]; + u.c[2] = t; + } + return u.u4; } /* @@ -2061,52 +2017,46 @@ static uint32_t ReadU4(uint8_t *p) | | The -WEEK=n initial week option overrides us. */ -static void SetWeek(raw_t *Raw, int Week, double Tow) -{ - rt17_t *rt17 = (rt17_t*) Raw->rcv_data; - - if (!(rt17->Flags & M_WEEK_OPTION)) - { - if (rt17->Week) - { - if (Week != rt17->Week) - { - if (Week == (rt17->Week + 1)) - tracet(2, "RT17: GPS WEEK rolled over from %d to %d.\n", rt17->Week, Week); - else - tracet(2, "RT17: GPS WEEK changed from %d to %d.\n", rt17->Week, Week); - } - } +static void SetWeek(raw_t *Raw, int Week, double Tow) { + rt17_t *rt17 = (rt17_t *)Raw->rcv_data; + + if (!(rt17->Flags & M_WEEK_OPTION)) { + if (rt17->Week) { + if (Week != rt17->Week) { + if (Week == (rt17->Week + 1)) + tracet(2, "RT17: GPS WEEK rolled over from %d to %d.\n", rt17->Week, Week); else - tracet(2, "RT17: GPS WEEK initially set to %d.\n", Week); + tracet(2, "RT17: GPS WEEK changed from %d to %d.\n", rt17->Week, Week); + } + } else + tracet(2, "RT17: GPS WEEK initially set to %d.\n", Week); - rt17->Week = Week; - } + rt17->Week = Week; + } - /* Also update the time if we can */ - if (Week && (Tow != 0.0)) - Raw->time = gpst2time(Week, Tow); + /* Also update the time if we can */ + if (Week && (Tow != 0.0)) Raw->time = gpst2time(Week, Tow); } /* SyncPacket - Synchronize the raw data stream to the start of a series of RT-17 packets */ -static int SyncPacket(rt17_t *rt17, uint8_t Data) -{ - uint8_t Type, *PacketBuffer = rt17->PacketBuffer; - - PacketBuffer[0] = PacketBuffer[1]; - PacketBuffer[1] = PacketBuffer[2]; - PacketBuffer[2] = PacketBuffer[3]; - PacketBuffer[3] = Data; - - Type = PacketBuffer[2]; - - /* - | Byte 0 must be an STX character. - | Byte 1 = status byte which we always ignore (for now). - | Byte 2 = packet type which must be GENOUT (0x40) RAWDATA (0x57) or RETSVDATA (0x55) (for now). - | Byte 3 = data length which must be non-zero for any packet we're interested in. - */ - return ((PacketBuffer[0] == STX) && (Data != 0) && ((Type == GENOUT) || (Type == RAWDATA) || (Type == RETSVDATA))); +static int SyncPacket(rt17_t *rt17, uint8_t Data) { + uint8_t Type, *PacketBuffer = rt17->PacketBuffer; + + PacketBuffer[0] = PacketBuffer[1]; + PacketBuffer[1] = PacketBuffer[2]; + PacketBuffer[2] = PacketBuffer[3]; + PacketBuffer[3] = Data; + + Type = PacketBuffer[2]; + + /* + | Byte 0 must be an STX character. + | Byte 1 = status byte which we always ignore (for now). + | Byte 2 = packet type which must be GENOUT (0x40) RAWDATA (0x57) or RETSVDATA (0x55) (for now). + | Byte 3 = data length which must be non-zero for any packet we're interested in. + */ + return ((PacketBuffer[0] == STX) && (Data != 0) && + ((Type == GENOUT) || (Type == RAWDATA) || (Type == RETSVDATA))); } /* @@ -2118,24 +2068,22 @@ static int SyncPacket(rt17_t *rt17, uint8_t Data) | so that it is uninterrupted by removing the extraneous packet headers, | trailers and page framing. */ -static void UnwrapGenout(rt17_t *rt17) -{ - uint8_t *p_in = rt17->MessageBuffer; - uint8_t *p_out = p_in; - uint32_t InputLength, InputLengthTotal = rt17->MessageLength; - uint32_t OutputLength, OutputLengthTotal = 0; - - while (InputLengthTotal > 0) - { - InputLength = p_in[3] + 6; - OutputLength = p_in[3] - 3; - memmove(p_out, p_in + 7, OutputLength); - p_in += InputLength; - p_out += OutputLength; - OutputLengthTotal += OutputLength; - InputLengthTotal -= InputLength; - } - rt17->MessageBytes = rt17->MessageLength = OutputLengthTotal; +static void UnwrapGenout(rt17_t *rt17) { + uint8_t *p_in = rt17->MessageBuffer; + uint8_t *p_out = p_in; + uint32_t InputLength, InputLengthTotal = rt17->MessageLength; + uint32_t OutputLength, OutputLengthTotal = 0; + + while (InputLengthTotal > 0) { + InputLength = p_in[3] + 6; + OutputLength = p_in[3] - 3; + memmove(p_out, p_in + 7, OutputLength); + p_in += InputLength; + p_out += OutputLength; + OutputLengthTotal += OutputLength; + InputLengthTotal -= InputLength; + } + rt17->MessageBytes = rt17->MessageLength = OutputLengthTotal; } /* @@ -2150,27 +2098,26 @@ static void UnwrapGenout(rt17_t *rt17) | While we're at it we also check to make sure the Record Interpretation | Flags are consistent. They should be the same in every page frame. */ -static void UnwrapRawdata(rt17_t *rt17, uint32_t *rif) -{ - uint8_t *p_in = rt17->MessageBuffer; - uint8_t *p_out = p_in; - uint32_t InputLength, InputLengthTotal = rt17->MessageLength; - uint32_t OutputLength, OutputLengthTotal = 0; - - *rif = p_in[7]; - - while (InputLengthTotal > 0) - { - if ((uint32_t)p_in[7] != *rif) - tracet(2, "RT17: Inconsistent Record Interpretation Flags within a single RAWDATA message.\n"); - - InputLength = p_in[3] + 6; - OutputLength = p_in[3] - 4; - memmove(p_out, p_in + 8, OutputLength); - p_in += InputLength; - p_out += OutputLength; - OutputLengthTotal += OutputLength; - InputLengthTotal -= InputLength; - } - rt17->MessageBytes = rt17->MessageLength = OutputLengthTotal; +static void UnwrapRawdata(rt17_t *rt17, uint32_t *rif) { + uint8_t *p_in = rt17->MessageBuffer; + uint8_t *p_out = p_in; + uint32_t InputLength, InputLengthTotal = rt17->MessageLength; + uint32_t OutputLength, OutputLengthTotal = 0; + + *rif = p_in[7]; + + while (InputLengthTotal > 0) { + if ((uint32_t)p_in[7] != *rif) + tracet(2, + "RT17: Inconsistent Record Interpretation Flags within a single RAWDATA message.\n"); + + InputLength = p_in[3] + 6; + OutputLength = p_in[3] - 4; + memmove(p_out, p_in + 8, OutputLength); + p_in += InputLength; + p_out += OutputLength; + OutputLengthTotal += OutputLength; + InputLengthTotal -= InputLength; + } + rt17->MessageBytes = rt17->MessageLength = OutputLengthTotal; } diff --git a/src/rcv/septentrio.c b/src/rcv/septentrio.c index 313029869..581293dad 100644 --- a/src/rcv/septentrio.c +++ b/src/rcv/septentrio.c @@ -1,51 +1,51 @@ /*------------------------------------------------------------------------------ -* septentrio.c : Septentrio Binary Format decoder (All Septentrio receivers) -* -* Copyright (C) 2013 by Fabrizio Tappero. -* Copyright (C) 2015 by Jens Reimann -* -* reference : -* [1] Septentrio, SBF Reference Guide, Version 130722r38600, 07/2013 -* -* note: - IRN is deactivated. The code is not tested. Use -DTESTING to activate. -* -* -* version : $Revision: 1.4 $ $Date: 2016/01/29 15:05:00 $ -* -* history : 2013/07/17 1.0 begin writing -* 2013/10/24 1.1 GPS L1 working -* 2013/11/02 1.2 modified by TTAKASU -* 2015/01/26 1.3 fix some problems by Jens Reimann -* 2016/02/04 1.4 by Jens Reimann -* - added more sanity checks -* - added galileon raw decoding -* - added usage of decoded SBAS messages for testing -* - add QZSS and Compass/Beidou navigation messages -* - fixed code and Doppler for 2nd and following frequency -* - fixed bug in glonass ephemeris -* - fixed decoding of galileo ephemeris -* - fixed lost lock indicator -* - fixed sbas decoding -* - cleanups -* 2016/03/03 1.5 - fixed TOW in SBAS messages -* 2016/03/12 1.6 - respect code priorities -* - fixed bug in carrier phase calculation of type2 data -* - unify frequency determination -* - improve lock handling -* - various bug fixes -* 2016/05/25 1.7 rtk_crc24q() -> crc24q() by T.T -* 2016/07/29 1.8 crc24q() -> rtk_crc24q() by T.T -* 2017/04/11 1.9 (char *) -> (signed char *) by T.T -* 2017/09/01 1.10 suppress warnings -* 2024/01/12 1.11 update with new code from Tomoji TAKASU -* 2024/06/16 1.12 restructed code, tested with Mosaic and PolarRx receivers -* 2024/06/26 1.13 implemented reading new Meas3 records -*-----------------------------------------------------------------------------*/ -#include "rtklib.h" - + * septentrio.c : Septentrio Binary Format decoder (All Septentrio receivers) + * + * Copyright (C) 2013 by Fabrizio Tappero. + * Copyright (C) 2015 by Jens Reimann + * + * reference : + * [1] Septentrio, SBF Reference Guide, Version 130722r38600, 07/2013 + * + * note: - IRN is deactivated. The code is not tested. Use -DTESTING to activate. + * + * + * version : $Revision: 1.4 $ $Date: 2016/01/29 15:05:00 $ + * + * history : 2013/07/17 1.0 begin writing + * 2013/10/24 1.1 GPS L1 working + * 2013/11/02 1.2 modified by TTAKASU + * 2015/01/26 1.3 fix some problems by Jens Reimann + * 2016/02/04 1.4 by Jens Reimann + * - added more sanity checks + * - added galileon raw decoding + * - added usage of decoded SBAS messages for testing + * - add QZSS and Compass/Beidou navigation messages + * - fixed code and Doppler for 2nd and following frequency + * - fixed bug in glonass ephemeris + * - fixed decoding of galileo ephemeris + * - fixed lost lock indicator + * - fixed sbas decoding + * - cleanups + * 2016/03/03 1.5 - fixed TOW in SBAS messages + * 2016/03/12 1.6 - respect code priorities + * - fixed bug in carrier phase calculation of type2 data + * - unify frequency determination + * - improve lock handling + * - various bug fixes + * 2016/05/25 1.7 rtk_crc24q() -> crc24q() by T.T + * 2016/07/29 1.8 crc24q() -> rtk_crc24q() by T.T + * 2017/04/11 1.9 (char *) -> (signed char *) by T.T + * 2017/09/01 1.10 suppress warnings + * 2024/01/12 1.11 update with new code from Tomoji TAKASU + * 2024/06/16 1.12 restructed code, tested with Mosaic and PolarRx receivers + * 2024/06/26 1.13 implemented reading new Meas3 records + *-----------------------------------------------------------------------------*/ #include #include +#include "rtklib.h" + extern const sbsigpband_t igpband1[][8]; /* SBAS IGP band 0-8 */ extern const sbsigpband_t igpband2[][5]; /* SBAS IGP band 9-10 */ @@ -53,21 +53,30 @@ extern const sbsigpband_t igpband2[][5]; /* SBAS IGP band 9-10 */ #define MEAS3_SAT_MAX 64 #define MEAS3_SIG_MAX 16 -static uint32_t const Meas3_EpochIntervals[] = {1, 500, 1000, 2000, 5000, 10000, 15000, 30000, 60000, 120000, 1, 1, 1, 1, 1, 1}; /* epoche interval index to epoche time in [ms] */ -static uint8_t const Meas3_NavSys[] = {SYS_GPS, SYS_GLO, SYS_GAL, SYS_CMP, SYS_SBS, SYS_QZS, SYS_IRN}; /* meas3 navsys to rtklib navsys conversion */ -static uint8_t const Meas3_SVIDBase[] = {MINPRNGPS, MINPRNGLO, MINPRNGAL, MINPRNCMP, MINPRNSBS, MINPRNQZS, MINPRNIRN}; /* rtklib satelite number start for rtklib navigation systems */ +static uint32_t const Meas3_EpochIntervals[] = { + 1, 500, 1000, 2000, 5000, 10000, 15000, 30000, 60000, + 120000, 1, 1, 1, 1, 1, 1}; /* epoche interval index to epoche time in [ms] */ +static uint8_t const Meas3_NavSys[] = { + SYS_GPS, SYS_GLO, SYS_GAL, SYS_CMP, + SYS_SBS, SYS_QZS, SYS_IRN}; /* meas3 navsys to rtklib navsys conversion */ +static uint8_t const Meas3_SVIDBase[] = { + MINPRNGPS, MINPRNGLO, MINPRNGAL, MINPRNCMP, + MINPRNSBS, MINPRNQZS, MINPRNIRN}; /* rtklib satelite number start for rtklib navigation systems + */ /* base pseudorange for the different constellations */ -static const double PRBase[] /* base distance for navigation systems in [m] */ - = { 19e6, /* GPS */ - 19e6, /* GLO */ - 22e6, /* GAL */ - 20e6, /* BDS !!redefined to 34000km for GEO/IGSO */ - 34e6, /* SBAS */ - 34e6, /* QZS */ - 34e6 /* IRN */ +static const double PRBase[] /* base distance for navigation systems in [m] */ + = { + 19e6, /* GPS */ + 19e6, /* GLO */ + 22e6, /* GAL */ + 20e6, /* BDS !!redefined to 34000km for GEO/IGSO */ + 34e6, /* SBAS */ + 34e6, /* QZS */ + 34e6 /* IRN */ }; /* mapping of the Meas3 lock time indicator into actual lock time in milliseconds */ -static const uint32_t Meas3_LTItoPLLTime[16] = { 0, 60000, 30000, 15000, 10000, 5000, 2000, 1000, 500, 200, 100, 50, 40, 20, 10, 0}; +static const uint32_t Meas3_LTItoPLLTime[16] = {0, 60000, 30000, 15000, 10000, 5000, 2000, 1000, + 500, 200, 100, 50, 40, 20, 10, 0}; // Data from the last reference epoch when decoding Meas3 blocks. typedef struct { @@ -111,271 +120,334 @@ extern int init_sbf(raw_t *raw) { } /* SBF definitions 2020 */ -#define SBF_SYNC1 0x24 /* SBF message header sync field 1 (correspond to $) */ -#define SBF_SYNC2 0x40 /* SBF message header sync field 2 (correspont to @)*/ -#define SBF_MAXSIG 39 /* SBF max signal number */ +#define SBF_SYNC1 0x24 /* SBF message header sync field 1 (correspond to $) */ +#define SBF_SYNC2 0x40 /* SBF message header sync field 2 (correspont to @)*/ +#define SBF_MAXSIG 39 /* SBF max signal number */ /* Measurement Blocks */ -#define ID_GENMEASEPOCH 5944 /* SBF message id: Measurement set of one epoch */ -#define ID_MEASEPOCH 4027 /* SBF message id: Measurement set of one epoch */ -#define ID_MEASEPOCHEXTRA 4000 /* SBF message id: Additional info such as observable variance */ -#define ID_MEASFULLRANGE 4098 /* SBF message id: Extended-range code and phase measurements */ -#define ID_MEASE3RNG 4109 /* SBF message id: Code, phase and CN0 measurements */ -#define ID_MEASE3CN 4110 /* SBF message id: Extension of Meas3Ranges containing fractional C/N0 values */ -#define ID_MEASE3DOPPLER 4111 /* SBF message id: Extension of Meas3Ranges containing Doppler values */ -#define ID_MEASE3PP 4112 /* SBF message id: Extension of Meas3Ranges containing proprietary flags for data post-processing. (undocumented) */ -#define ID_MEASE3MP 4113 /* SBF message id: Extension of Meas3Ranges containing multipath corrections applied by the receiver. (undocumented */ -#define ID_IQCORR 4046 /* SBF message id: Real and imaginary post-correlation values */ -#define ID_ISMR 4086 /* SBF message id: Ionospheric scintillation monitor (ISMR) data */ -#define ID_SQMSAMPLES 4087 /* SBF message id: Correlation samples for signal quality monitoring */ -#define ID_MEASEPOCH_END 5922 /* SBF message id: Measurement epoch marker */ +#define ID_GENMEASEPOCH 5944 /* SBF message id: Measurement set of one epoch */ +#define ID_MEASEPOCH 4027 /* SBF message id: Measurement set of one epoch */ +#define ID_MEASEPOCHEXTRA 4000 /* SBF message id: Additional info such as observable variance */ +#define ID_MEASFULLRANGE 4098 /* SBF message id: Extended-range code and phase measurements */ +#define ID_MEASE3RNG 4109 /* SBF message id: Code, phase and CN0 measurements */ +#define ID_MEASE3CN \ + 4110 /* SBF message id: Extension of Meas3Ranges containing fractional C/N0 values */ +#define ID_MEASE3DOPPLER \ + 4111 /* SBF message id: Extension of Meas3Ranges containing Doppler values */ +#define ID_MEASE3PP \ + 4112 /* SBF message id: Extension of Meas3Ranges containing proprietary flags for data \ + post-processing. (undocumented) */ +#define ID_MEASE3MP \ + 4113 /* SBF message id: Extension of Meas3Ranges containing multipath corrections applied by the \ + receiver. (undocumented */ +#define ID_IQCORR 4046 /* SBF message id: Real and imaginary post-correlation values */ +#define ID_ISMR 4086 /* SBF message id: Ionospheric scintillation monitor (ISMR) data */ +#define ID_SQMSAMPLES 4087 /* SBF message id: Correlation samples for signal quality monitoring */ +#define ID_MEASEPOCH_END 5922 /* SBF message id: Measurement epoch marker */ /* Navigation Page Blocks */ -//#define ID_GPSRaw 5895 /* SBF message id: GPS CA navigation frame */ -//#define ID_CNAVRaw 5947 /* SBF message id: GPS L2C navigation frame */ -//#define ID_GEORaw 5898 /* SBF message id: SBAS L1 navigation frame */ -#define ID_GPSRAWCA 4017 /* SBF message id: GPS CA navigation subframe */ -#define ID_GPSRAWL2C 4018 /* SBF message id: GPS L2C navigation frame */ -#define ID_GPSRAWL5 4019 /* SBF message id: GPS L5 navigation frame */ -//#define ID_GPSRAWL1C 4221 /* SBF message id: GPS L1C navigation frame */ -#define ID_GLORAWCA 4026 /* SBF message id: GLONASS CA navigation string */ -#define ID_GALRAWFNAV 4022 /* SBF message id: Galileo F/NAV navigation page */ -#define ID_GALRAWINAV 4023 /* SBF message id: Galileo I/NAV navigation page */ -#define ID_GALRAWCNAV 4024 /* SBF message id: Galileo C/NAV navigation page */ -//#define ID_GALRAWGNAV 4025 /* SBF message id: Galileo G/NAV navigation page */ -//#define ID_GALRAWGNAVE 4029 /* SBF message id: Galileo G/NAVe navigation page */ -#define ID_GEORAWL1 4020 /* SBF message id: SBAS L1 navigation message */ -#define ID_GEORAWL5 4021 /* SBF message id: SBAS L5 navigation message */ -#define ID_BDSRAW 4047 /* SBF message id: BeiDou navigation page */ -#define ID_BDSRAWB1C 4218 /* SBF message id: BeiDou B1C navigation frame */ -#define ID_BDSRAWB2A 4219 /* SBF message id: BeiDou B2A navigation frame */ -#define ID_BDSRAWB2B 4242 /* SBF message id: BeiDou B2B navigation frame */ -#define ID_QZSRAWL1CA 4066 /* SBF message id: QZSS L1C/A or L1C/B navigation frame */ -#define ID_QZSRAWL2C 4067 /* SBF message id: QZSS L2C navigation frame */ -#define ID_QZSRAWL5 4068 /* SBF message id: QZSS L5 navigation frame */ -#define ID_QZSSL6 4069 /* SBF message id: QZSS L6 navigation frame */ -#define ID_QZSSL1C 4227 /* SBF message id: QZSS L1C navigation message */ -#define ID_QZSSL1S 4228 /* SBF message id: QZSS L1S navigation message */ -#define ID_QZSSL5S 4246 /* SBF message id: QZSS L5S navigation message */ -#define ID_IRNSSRAW 4093 /* SBF message id: IRNSS raw navigation page or frame */ -//#define ID_IRNSSRAWL1 4262 /* SBF message id: IRNSS raw navigation page or frame */ -#define ID_GNSSNAVBITS 4088 /* SBF message id: Raw navigation bits during last second */ -#define ID_GNSSSYMBOLS 4099 /* SBF message id: Raw navigation symbols */ +// #define ID_GPSRaw 5895 /* SBF message id: GPS CA navigation frame */ +// #define ID_CNAVRaw 5947 /* SBF message id: GPS L2C navigation frame */ +// #define ID_GEORaw 5898 /* SBF message id: SBAS L1 navigation frame */ +#define ID_GPSRAWCA 4017 /* SBF message id: GPS CA navigation subframe */ +#define ID_GPSRAWL2C 4018 /* SBF message id: GPS L2C navigation frame */ +#define ID_GPSRAWL5 4019 /* SBF message id: GPS L5 navigation frame */ +// #define ID_GPSRAWL1C 4221 /* SBF message id: GPS L1C navigation frame */ +#define ID_GLORAWCA 4026 /* SBF message id: GLONASS CA navigation string */ +#define ID_GALRAWFNAV 4022 /* SBF message id: Galileo F/NAV navigation page */ +#define ID_GALRAWINAV 4023 /* SBF message id: Galileo I/NAV navigation page */ +#define ID_GALRAWCNAV 4024 /* SBF message id: Galileo C/NAV navigation page */ +// #define ID_GALRAWGNAV 4025 /* SBF message id: Galileo G/NAV navigation page */ +// #define ID_GALRAWGNAVE 4029 /* SBF message id: Galileo G/NAVe navigation page */ +#define ID_GEORAWL1 4020 /* SBF message id: SBAS L1 navigation message */ +#define ID_GEORAWL5 4021 /* SBF message id: SBAS L5 navigation message */ +#define ID_BDSRAW 4047 /* SBF message id: BeiDou navigation page */ +#define ID_BDSRAWB1C 4218 /* SBF message id: BeiDou B1C navigation frame */ +#define ID_BDSRAWB2A 4219 /* SBF message id: BeiDou B2A navigation frame */ +#define ID_BDSRAWB2B 4242 /* SBF message id: BeiDou B2B navigation frame */ +#define ID_QZSRAWL1CA 4066 /* SBF message id: QZSS L1C/A or L1C/B navigation frame */ +#define ID_QZSRAWL2C 4067 /* SBF message id: QZSS L2C navigation frame */ +#define ID_QZSRAWL5 4068 /* SBF message id: QZSS L5 navigation frame */ +#define ID_QZSSL6 4069 /* SBF message id: QZSS L6 navigation frame */ +#define ID_QZSSL1C 4227 /* SBF message id: QZSS L1C navigation message */ +#define ID_QZSSL1S 4228 /* SBF message id: QZSS L1S navigation message */ +#define ID_QZSSL5S 4246 /* SBF message id: QZSS L5S navigation message */ +#define ID_IRNSSRAW 4093 /* SBF message id: IRNSS raw navigation page or frame */ +// #define ID_IRNSSRAWL1 4262 /* SBF message id: IRNSS raw navigation page or frame */ +#define ID_GNSSNAVBITS 4088 /* SBF message id: Raw navigation bits during last second */ +#define ID_GNSSSYMBOLS 4099 /* SBF message id: Raw navigation symbols */ /* GPS Decoded Message Blocks */ -#define ID_GPSNAV 5891 /* SBF message id: GPS ephemeris and clock */ -#define ID_GPSALM 5892 /* SBF message id: Almanac data for a GPS satellite */ -#define ID_GPSION 5893 /* SBF message id: Ionosphere data from the GPS subframe 5 */ -#define ID_GPSUTC 5894 /* SBF message id: GPS-UTC data from GPS subframe 5 */ -#define ID_GPSCNAV 4042 /* SBF message id: CNAV Ephemeris data for one satellite. */ -#define ID_GPSCNAV2 4258 /* SBF message id: CNAV Ephemeris data for one satellite. */ +#define ID_GPSNAV 5891 /* SBF message id: GPS ephemeris and clock */ +#define ID_GPSALM 5892 /* SBF message id: Almanac data for a GPS satellite */ +#define ID_GPSION 5893 /* SBF message id: Ionosphere data from the GPS subframe 5 */ +#define ID_GPSUTC 5894 /* SBF message id: GPS-UTC data from GPS subframe 5 */ +#define ID_GPSCNAV 4042 /* SBF message id: CNAV Ephemeris data for one satellite. */ +#define ID_GPSCNAV2 4258 /* SBF message id: CNAV Ephemeris data for one satellite. */ /* GLONASS Decoded Message Blocks */ -#define ID_GLONAV 4004 /* SBF message id: GLONASS ephemeris and clock */ -#define ID_GLOALM 4005 /* SBF message id: Almanac data for a GLONASS satellite */ -#define ID_GLOTIME 4036 /* SBF message id: GLO-UTC, GLO-GPS and GLO-UT1 data */ +#define ID_GLONAV 4004 /* SBF message id: GLONASS ephemeris and clock */ +#define ID_GLOALM 4005 /* SBF message id: Almanac data for a GLONASS satellite */ +#define ID_GLOTIME 4036 /* SBF message id: GLO-UTC, GLO-GPS and GLO-UT1 data */ /* Galileo Decoded Message Blocks */ -#define ID_GALNAV 4002 /* SBF message id: Galileo ephemeris, clock, health and BGD */ -#define ID_GALALM 4003 /* SBF message id: Almanac data for a Galileo satellite */ -#define ID_GALION 4030 /* SBF message id: NeQuick Ionosphere model parameters*/ -#define ID_GALUTC 4031 /* SBF message id: GST-UTC data */ -#define ID_GALGSTGPS 4032 /* SBF message id: GST-GPS data */ -#define ID_GALARRLM 4034 /* SBF message id: Search-and-rescue return link message */ +#define ID_GALNAV 4002 /* SBF message id: Galileo ephemeris, clock, health and BGD */ +#define ID_GALALM 4003 /* SBF message id: Almanac data for a Galileo satellite */ +#define ID_GALION 4030 /* SBF message id: NeQuick Ionosphere model parameters*/ +#define ID_GALUTC 4031 /* SBF message id: GST-UTC data */ +#define ID_GALGSTGPS 4032 /* SBF message id: GST-GPS data */ +#define ID_GALARRLM 4034 /* SBF message id: Search-and-rescue return link message */ /* BeiDou Decoded Message Blocks */ -#define ID_BDSNAV 4081 /* SBF message id: BeiDou ephemeris and clock */ -#define ID_BDSCNAV1 4251 /* SBF message id: BeiDou B-CNAV1 ephemeris data for one satellite. */ -#define ID_BDSCNAV2 4252 /* SBF message id: BeiDou B-CNAV2 ephemeris data for one satellite. */ -#define ID_BDSCNAV3 4253 /* SBF message id: BeiDou B-CNAV3 ephemeris data for one satellite. */ -#define ID_BDSALM 4119 /* SBF message id: Almanac data for a BeiDou satellite */ -#define ID_BDSION 4120 /* SBF message id: BeiDou Ionospheric delay model parameters */ -#define ID_BDSUTC 4121 /* SBF message id: BDT-UTC data */ +#define ID_BDSNAV 4081 /* SBF message id: BeiDou ephemeris and clock */ +#define ID_BDSCNAV1 4251 /* SBF message id: BeiDou B-CNAV1 ephemeris data for one satellite. */ +#define ID_BDSCNAV2 4252 /* SBF message id: BeiDou B-CNAV2 ephemeris data for one satellite. */ +#define ID_BDSCNAV3 4253 /* SBF message id: BeiDou B-CNAV3 ephemeris data for one satellite. */ +#define ID_BDSALM 4119 /* SBF message id: Almanac data for a BeiDou satellite */ +#define ID_BDSION 4120 /* SBF message id: BeiDou Ionospheric delay model parameters */ +#define ID_BDSUTC 4121 /* SBF message id: BDT-UTC data */ /* QZSS Decoded Message Blocks */ -#define ID_QZSSNAV 4095 /* SBF message id: QZSS ephemeris and clock */ -//#define ID_QZSSCNAV 4259 /* SBF message id: QZSS ephemeris and clock */ -//#define ID_QZSSCNAV2 4260 /* SBF message id: QZSS ephemeris and clock */ -#define ID_QZSSALM 4116 /* SBF message id: Almanac data for a QZSS satellite */ +#define ID_QZSSNAV 4095 /* SBF message id: QZSS ephemeris and clock */ +// #define ID_QZSSCNAV 4259 /* SBF message id: QZSS ephemeris and clock */ +// #define ID_QZSSCNAV2 4260 /* SBF message id: QZSS ephemeris and clock */ +#define ID_QZSSALM 4116 /* SBF message id: Almanac data for a QZSS satellite */ /* NavIC/IRNSS Decoded Message Blocks */ -#define ID_NAVICLNAV 4254 /* SBF message id: NavIC/IRNSS ephemeris and clock */ +#define ID_NAVICLNAV 4254 /* SBF message id: NavIC/IRNSS ephemeris and clock */ /* SBAS L1 Decoded Message Blocks */ -#define ID_GEOMT00 5925 /* SBF message id: SBAS: Don't use for safety application */ -#define ID_GEOPRNMASK 5926 /* SBF message id: PRN Mask assignments */ -#define ID_GEOFASTCORR 5927 /* SBF message id: Fast Corrections */ -#define ID_GEOINTEGRITY 5928 /* SBF message id: Integrity information */ -#define ID_GEOFASTCORRDEGR 5929 /* SBF message id: Fast correction degradation factor */ -#define ID_GEONAV 5896 /* SBF message id: SBAS navigation message */ -#define ID_GEODEGRFACTORS 5930 /* SBF message id: Degration factors */ -#define ID_GEONETWORKTIME 5918 /* SBF message id: SBAS Network Time/UTC offset parameters */ -#define ID_GEOALM 5897 /* SBF message id: SBAS satellite almanac */ -#define ID_GEOIGPMASK 5931 /* SBF message id: Ionospheric grid point mask */ -#define ID_GEOLONGTERMCOR 5932 /* SBF message id: Long term satellite error corrections */ -#define ID_GEOIONODELAY 5933 /* SBF message id: Inospheric delay correction */ -#define ID_GEOSERVICELEVEL 5917 /* SBF message id: SBAS Service Message */ -#define ID_GEOCLOCKEPHCOVMATRIX 5934 /* SBF message id: Clock-Ephemeris Covariance Matrix l*/ +#define ID_GEOMT00 5925 /* SBF message id: SBAS: Don't use for safety application */ +#define ID_GEOPRNMASK 5926 /* SBF message id: PRN Mask assignments */ +#define ID_GEOFASTCORR 5927 /* SBF message id: Fast Corrections */ +#define ID_GEOINTEGRITY 5928 /* SBF message id: Integrity information */ +#define ID_GEOFASTCORRDEGR 5929 /* SBF message id: Fast correction degradation factor */ +#define ID_GEONAV 5896 /* SBF message id: SBAS navigation message */ +#define ID_GEODEGRFACTORS 5930 /* SBF message id: Degration factors */ +#define ID_GEONETWORKTIME 5918 /* SBF message id: SBAS Network Time/UTC offset parameters */ +#define ID_GEOALM 5897 /* SBF message id: SBAS satellite almanac */ +#define ID_GEOIGPMASK 5931 /* SBF message id: Ionospheric grid point mask */ +#define ID_GEOLONGTERMCOR 5932 /* SBF message id: Long term satellite error corrections */ +#define ID_GEOIONODELAY 5933 /* SBF message id: Inospheric delay correction */ +#define ID_GEOSERVICELEVEL 5917 /* SBF message id: SBAS Service Message */ +#define ID_GEOCLOCKEPHCOVMATRIX 5934 /* SBF message id: Clock-Ephemeris Covariance Matrix l*/ /* SBAS L5 Decoded Message Blocks */ -#define ID_SBASL5NAV 5958 /* SBF message id: DFMC SBAS ephemeris and clock data */ -#define ID_SBASL5ALM 5959 /* SBF message id: DFMC SBAS almanac data */ +#define ID_SBASL5NAV 5958 /* SBF message id: DFMC SBAS ephemeris and clock data */ +#define ID_SBASL5ALM 5959 /* SBF message id: DFMC SBAS almanac data */ /* GNSS Position, Velocity and Time Blocks */ -#define ID_PVTCART1 5903 /* SBF message id: GNSS position, velocity, and time in Cartesian coordinates */ -#define ID_PVTGEOD1 5904 /* SBF message id: GNSS position, velocity, and time in Geodetic coordinates */ -#define ID_DOP1 5909 /* SBF message id: Dilution of precision */ -#define ID_PVTRESIDUALS1 5910 /* SBF message id: Measurement residuals */ -#define ID_RAIMSTATS1 5915 /* SBF message id: Integrity statistics */ -#define ID_PVTCART2 4006 /* SBF message id: GNSS position, velocity, and time in Cartesian coordinates */ -#define ID_PVTGEOD2 4007 /* SBF message id: GNSS position, velocity, and time in Geodetic coordinates */ -#define ID_PVTGEODAUTH 4232 /* SBF message id: OSNMA-Authenticated Position, velocity, and time in geodetic coordinate */ -#define ID_COVCART 5905 /* SBF message id: Position covariance matrix (X,Y, Z) */ -#define ID_COVGEOD 5906 /* SBF message id: Position covariance matrix (Lat, Lon, Alt) */ -#define ID_VELCOVCART 5907 /* SBF message id: Velocity covariance matrix (X, Y, Z) */ -#define ID_VELCOVGEOD 5908 /* SBF message id: Velocity covariance matrix (North, East, Up) */ -#define ID_DOP2 4001 /* SBF message id: Dilution of precision */ -#define ID_DOPAUTH 4247 /* SBF message id: Dilution of Precision Authenticated Data */ -#define ID_POSCART 4044 /* SBF message id: Position, variance and baseline in Cartesian coordinates */ -#define ID_PVTLOCAL 4052 /* SBF message id: Position in a local datum */ -#define ID_POSPROJ 4094 /* SBF message id: Plane grid coordinates */ -#define ID_PVTSATCART 4008 /* SBF message id: Satellite positions */ -#define ID_PVTRESIDUALS2 4009 /* SBF message id: Measurement residuals */ -#define ID_RAIMSTATS2 4011 /* SBF message id: Integrity statistics */ -#define ID_GEOCORR 5935 /* SBF message id: Orbit, Clock and pseudoranges SBAS corrections */ -#define ID_BASEVECCART 4043 /* SBF message id: XYZ relative position and velocity with respect to base(s) */ -#define ID_BASEVECGEOD 4028 /* SBF message id: ENU relative position and velocity with respect to base(s) */ -#define ID_AMBIGUITIES 4240 /* SBF message id: Carrier phase ambiguity states */ -#define ID_PVTSUPPORT 4076 /* SBF message id: Internal parameters for maintenance and support */ -#define ID_PVTSUPPORTA 4079 /* SBF message id: Internal parameters for maintenance and support */ -#define ID_PVTEND 5921 /* SBF message id: PVT epoch marke */ -#define ID_BASELINE 5950 /* SBF message id: Base-rover vector (deprecated block - not to be used) */ +#define ID_PVTCART1 \ + 5903 /* SBF message id: GNSS position, velocity, and time in Cartesian coordinates */ +#define ID_PVTGEOD1 \ + 5904 /* SBF message id: GNSS position, velocity, and time in Geodetic coordinates */ +#define ID_DOP1 5909 /* SBF message id: Dilution of precision */ +#define ID_PVTRESIDUALS1 5910 /* SBF message id: Measurement residuals */ +#define ID_RAIMSTATS1 5915 /* SBF message id: Integrity statistics */ +#define ID_PVTCART2 \ + 4006 /* SBF message id: GNSS position, velocity, and time in Cartesian coordinates */ +#define ID_PVTGEOD2 \ + 4007 /* SBF message id: GNSS position, velocity, and time in Geodetic coordinates */ +#define ID_PVTGEODAUTH \ + 4232 /* SBF message id: OSNMA-Authenticated Position, velocity, and time in geodetic coordinate \ + */ +#define ID_COVCART 5905 /* SBF message id: Position covariance matrix (X,Y, Z) */ +#define ID_COVGEOD 5906 /* SBF message id: Position covariance matrix (Lat, Lon, Alt) */ +#define ID_VELCOVCART 5907 /* SBF message id: Velocity covariance matrix (X, Y, Z) */ +#define ID_VELCOVGEOD 5908 /* SBF message id: Velocity covariance matrix (North, East, Up) */ +#define ID_DOP2 4001 /* SBF message id: Dilution of precision */ +#define ID_DOPAUTH 4247 /* SBF message id: Dilution of Precision Authenticated Data */ +#define ID_POSCART \ + 4044 /* SBF message id: Position, variance and baseline in Cartesian coordinates */ +#define ID_PVTLOCAL 4052 /* SBF message id: Position in a local datum */ +#define ID_POSPROJ 4094 /* SBF message id: Plane grid coordinates */ +#define ID_PVTSATCART 4008 /* SBF message id: Satellite positions */ +#define ID_PVTRESIDUALS2 4009 /* SBF message id: Measurement residuals */ +#define ID_RAIMSTATS2 4011 /* SBF message id: Integrity statistics */ +#define ID_GEOCORR 5935 /* SBF message id: Orbit, Clock and pseudoranges SBAS corrections */ +#define ID_BASEVECCART \ + 4043 /* SBF message id: XYZ relative position and velocity with respect to base(s) */ +#define ID_BASEVECGEOD \ + 4028 /* SBF message id: ENU relative position and velocity with respect to base(s) */ +#define ID_AMBIGUITIES 4240 /* SBF message id: Carrier phase ambiguity states */ +#define ID_PVTSUPPORT 4076 /* SBF message id: Internal parameters for maintenance and support */ +#define ID_PVTSUPPORTA 4079 /* SBF message id: Internal parameters for maintenance and support */ +#define ID_PVTEND 5921 /* SBF message id: PVT epoch marke */ +#define ID_BASELINE \ + 5950 /* SBF message id: Base-rover vector (deprecated block - not to be used) */ /* INS/GNSS Integrated Blocks */ -#define ID_INTPVCART 4060 /* SBF message id: Integrated PV in Cartesian coordinates */ -#define ID_INTPVGEOD 4061 /* SBF message id: Integrated PV in Geodetic coordinates */ -#define ID_INTPOSCOVCART 4062 /* SBF message id: Integrated position covariance matrix (X, Y, Z) */ -#define ID_INTVELCOVCART 4063 /* SBF message id: Integrated velocity covariance matrix (X, Y, Z) */ -#define ID_INTPOSCOVGEOD 4064 /* SBF message id: Integrated position covariance matrix (Lat, Lon, Alt) */ -#define ID_INTVELCOVGEOD 4065 /* SBF message id: Integrated velocity covariance matrix (North, East, Up) */ -#define ID_INTATTEULER 4070 /* SBF message id: Integrated attitude in Euler angles */ -#define ID_INTATTCCOEULER 4072 /* SBF message id: Integrated attitude covariance matrix of Euler angles */ -#define ID_INTPVAAGEOD 4045 /* SBF message id: Integrated position, velocity, acceleration and attitude */ -#define ID_INSNAVCART 4225 /* SBF message id: INS solution in Cartesian coordinates */ -#define ID_INSNAVGEOD 4226 /* SBF message id: INS solution in Geodetic coordinates */ -#define ID_IMUBIAS 4241 /* SBF message id: Estimated parameters of the IMU, such as the IMU biases and their standard deviation */ +#define ID_INTPVCART 4060 /* SBF message id: Integrated PV in Cartesian coordinates */ +#define ID_INTPVGEOD 4061 /* SBF message id: Integrated PV in Geodetic coordinates */ +#define ID_INTPOSCOVCART 4062 /* SBF message id: Integrated position covariance matrix (X, Y, Z) \ + */ +#define ID_INTVELCOVCART 4063 /* SBF message id: Integrated velocity covariance matrix (X, Y, Z) \ + */ +#define ID_INTPOSCOVGEOD \ + 4064 /* SBF message id: Integrated position covariance matrix (Lat, Lon, Alt) */ +#define ID_INTVELCOVGEOD \ + 4065 /* SBF message id: Integrated velocity covariance matrix (North, East, Up) */ +#define ID_INTATTEULER 4070 /* SBF message id: Integrated attitude in Euler angles */ +#define ID_INTATTCCOEULER \ + 4072 /* SBF message id: Integrated attitude covariance matrix of Euler angles */ +#define ID_INTPVAAGEOD \ + 4045 /* SBF message id: Integrated position, velocity, acceleration and attitude */ +#define ID_INSNAVCART 4225 /* SBF message id: INS solution in Cartesian coordinates */ +#define ID_INSNAVGEOD 4226 /* SBF message id: INS solution in Geodetic coordinates */ +#define ID_IMUBIAS \ + 4241 /* SBF message id: Estimated parameters of the IMU, such as the IMU biases and their \ + standard deviation */ /* GNSS Attitude Blocks */ -#define ID_ATTEULER 5938 /* SBF message id: GNSS attitude expressed as Euler angles */ -#define ID_ATTCOVEULER 5939 /* SBF message id: Covariance matrix of attitude */ -#define ID_AUXPOS 5942 /* SBF message id: Relative position and velocity estimates of auxiliary antennas */ -#define ID_ENDATT 5943 /* SBF message id: GNSS attitude epoch marker */ -#define ID_ATTQUAD 5940 /* SBF message id: GNSS attitude expressed as Quaternions */ -#define ID_ATTCOVQUAD 5941 /* SBF message id: Covariance matrix of attitude as Quaternions */ +#define ID_ATTEULER 5938 /* SBF message id: GNSS attitude expressed as Euler angles */ +#define ID_ATTCOVEULER 5939 /* SBF message id: Covariance matrix of attitude */ +#define ID_AUXPOS \ + 5942 /* SBF message id: Relative position and velocity estimates of auxiliary antennas */ +#define ID_ENDATT 5943 /* SBF message id: GNSS attitude epoch marker */ +#define ID_ATTQUAD 5940 /* SBF message id: GNSS attitude expressed as Quaternions */ +#define ID_ATTCOVQUAD 5941 /* SBF message id: Covariance matrix of attitude as Quaternions */ /* Receiver Time Blocks */ -#define ID_RXTIME 5914 /* SBF message id: Current receiver and UTC time */ -#define ID_PPSOFFSET 5911 /* SBF message id: Offset of the xPPS pulse with respect to GNSS time */ -#define ID_SYSTIMEOFF 4039 /* SBF message id: Time offset between different constellations */ -#define ID_FUGROTIMEOFF 4255 /* SBF message id: Fugro clock biases */ +#define ID_RXTIME 5914 /* SBF message id: Current receiver and UTC time */ +#define ID_PPSOFFSET 5911 /* SBF message id: Offset of the xPPS pulse with respect to GNSS time */ +#define ID_SYSTIMEOFF 4039 /* SBF message id: Time offset between different constellations */ +#define ID_FUGROTIMEOFF 4255 /* SBF message id: Fugro clock biases */ /* External Event Blocks */ -#define ID_EXTEVENT 5924 /* SBF message id: Time at the instant of an external event */ -#define ID_EXTEVENTCART 4937 /* SBF message id: Cartesian position at the instant of an event */ -#define ID_EXTEVENTGEO 4938 /* SBF message id: Geodetic position at the instant of an event */ -#define ID_EXTEVENTBASEVECCART 4216 /* SBF message id: XYZ relative position with respect to base(s) at the instant of an event */ -#define ID_EXTEVENTBASEVECGEOD 4217 /* SBF message id: ENU relative position with respect to base(s) at the instant of an event */ -#define ID_EXTEVENTINSNAVCART 4229 /* SBF message id: INS solution in Cartesian coordinates at the instant of an event */ -#define ID_EXTEVENTINSNAVGEOD 4230 /* SBF message id: INS solution in Geodetic coordinates at the instant of an event */ -#define ID_EXTEEVENTAATTEULER 4237 /* GNSS attitude expressed as Euler angles at the instant of an event */ +#define ID_EXTEVENT 5924 /* SBF message id: Time at the instant of an external event */ +#define ID_EXTEVENTCART 4937 /* SBF message id: Cartesian position at the instant of an event */ +#define ID_EXTEVENTGEO 4938 /* SBF message id: Geodetic position at the instant of an event */ +#define ID_EXTEVENTBASEVECCART \ + 4216 /* SBF message id: XYZ relative position with respect to base(s) at the instant of an event \ + */ +#define ID_EXTEVENTBASEVECGEOD \ + 4217 /* SBF message id: ENU relative position with respect to base(s) at the instant of an event \ + */ +#define ID_EXTEVENTINSNAVCART \ + 4229 /* SBF message id: INS solution in Cartesian coordinates at the instant of an event */ +#define ID_EXTEVENTINSNAVGEOD \ + 4230 /* SBF message id: INS solution in Geodetic coordinates at the instant of an event */ +#define ID_EXTEEVENTAATTEULER \ + 4237 /* GNSS attitude expressed as Euler angles at the instant of an event */ /* Differential Correction Blocks */ -#define ID_DIFFCORRIN 5919 /* SBF message id: Incoming RTCM or CMR message */ -#define ID_BASESTATION 5949 /* SBF message id: Base station coordinates */ -#define ID_RTCMDATUM 4049 /* SBF message id: Datum information from the RTK service provider */ -#define ID_BASELINK 5948 /* SBF message id: Number of received and transmitted byte */ +#define ID_DIFFCORRIN 5919 /* SBF message id: Incoming RTCM or CMR message */ +#define ID_BASESTATION 5949 /* SBF message id: Base station coordinates */ +#define ID_RTCMDATUM 4049 /* SBF message id: Datum information from the RTK service provider */ +#define ID_BASELINK 5948 /* SBF message id: Number of received and transmitted byte */ /* L-Band Demodulator Blocks */ -#define ID_LRECEIVER 4200 /* SBF message id: L-Band Receiver Status */ -#define ID_LTRACK 4201 /* SBF message id: Status of the L-band signal tracking */ -#define ID_LDECODE 4202 /* SBF message id: Status of the LBAS1 L-band service */ -//#define ID_LMESSAGE 4203 /* SBF message id: LBAS1 over-the-air message */ -#define ID_LBEAMS 4204 /* SBF message id: L-band satellite/beam information */ -#define ID_FUGRODSS 4211 /* SBF message id: DDS (Debug Data Stream) from Fugro */ -//#define ID_LRAW 4212 /* SBF message id: L-Band raw user data */ -#define ID_FUGROSTAT 4214 /* SBF message id: Fugro Status Information */ +#define ID_LRECEIVER 4200 /* SBF message id: L-Band Receiver Status */ +#define ID_LTRACK 4201 /* SBF message id: Status of the L-band signal tracking */ +#define ID_LDECODE 4202 /* SBF message id: Status of the LBAS1 L-band service */ +// #define ID_LMESSAGE 4203 /* SBF message id: LBAS1 over-the-air message */ +#define ID_LBEAMS 4204 /* SBF message id: L-band satellite/beam information */ +#define ID_FUGRODSS 4211 /* SBF message id: DDS (Debug Data Stream) from Fugro */ +// #define ID_LRAW 4212 /* SBF message id: L-Band raw user data */ +#define ID_FUGROSTAT 4214 /* SBF message id: Fugro Status Information */ /* External Sensor Blocks */ -#define ID_EXTSENSORMEAS 4050 /* SBF message id: Measurement set of external sensors of one epoch */ -#define ID_EXTSENSORSTATUS 4056 /* SBF message id: Overall status of external sensors */ -#define ID_EXTSENSORSETUP 4057 /* SBF message id: General information about the setup of external sensors */ -#define ID_EXTSENSORSTATUS2 4223 /* SBF message id: Overall status of external sensors */ -#define ID_EXTSENSORINFO 4222 /* SBF message id: Configuration information of external sensors */ -#define ID_IMUSETUP 4224 /* SBF message id: General information about the setup of the IMU */ -#define ID_VELSENSORSETUP 4244 /* SBF message id: General information about the setup of the velocity sensor */ -#define ID_LEVERARMSUPPORT1 4248 /* SBF message id: LeverArm estimation */ +#define ID_EXTSENSORMEAS 4050 /* SBF message id: Measurement set of external sensors of one epoch \ + */ +#define ID_EXTSENSORSTATUS 4056 /* SBF message id: Overall status of external sensors */ +#define ID_EXTSENSORSETUP \ + 4057 /* SBF message id: General information about the setup of external sensors */ +#define ID_EXTSENSORSTATUS2 4223 /* SBF message id: Overall status of external sensors */ +#define ID_EXTSENSORINFO 4222 /* SBF message id: Configuration information of external sensors */ +#define ID_IMUSETUP 4224 /* SBF message id: General information about the setup of the IMU */ +#define ID_VELSENSORSETUP \ + 4244 /* SBF message id: General information about the setup of the velocity sensor */ +#define ID_LEVERARMSUPPORT1 4248 /* SBF message id: LeverArm estimation */ /* Status Blocks */ -#define ID_RXSTATUS1 5913 /* SBF message id: Overall status information of the receiver */ -#define ID_TRACKSTATUS 5912 /* SBF message id: Status of the tracking for all receiver channels */ -#define ID_CHNSTATUS 4013 /* SBF message id: Status of the tracking for all receiver channels */ -#define ID_RXSTATUS2 4014 /* SBF message id: Overall status information of the receiver */ -#define ID_SATVISIBILITY 4012 /* SBF message id: Azimuth/elevation of visible satellites */ -#define ID_INPUTLINK 4090 /* SBF message id: Statistics on input streams */ -#define ID_OUTPUTLINK 4091 /* SBF message id: Statistics on in´output streams */ -#define ID_NTRIPCLTSTAT 4053 /* SBF message id: NTRIP client connection status */ -#define ID_NTRIPSVRSTAT 4122 /* SBF message id: NTRIP server connection status */ -#define ID_IPSTATUS 4058 /* SBF message id: IP address, gateway and MAC address of Ethernet interface */ -#define ID_WIFIAPSTATUS 4054 /* SBF message id: WiFi status in access point mode */ -#define ID_WIFICLTSTATUS 4096 /* SBF message id: WiFi status in client mode */ -#define ID_CELLULARSTATUS 4055 /* SBF message id: Cellular status */ -#define ID_BLUETOOTHSTATUS 4051 /* SBF message id: Bluethooth status */ -#define ID_DYNDNSSTATUS 4105 /* SBF message id: DynDNS status */ -#define ID_BATTERYSTATUS 4083 /* SBF message id: Battery status */ -#define ID_POWERSTATUS 4101 /* SBF message id: Power supply source and voltage */ -#define ID_QUALIND 4082 /* SBF message id: Quality indicators */ -#define ID_DISKSTATUS 4059 /* SBF message id: Internal logging status */ -#define ID_LOGSTATUS 4102 /* SBF message id: Log sessions status */ -#define ID_UHFSTATUS 4085 /* SBF message id: UHF status */ -#define ID_RFSTATUS 4092 /* SBF message id: Radio-frequency interference mitigation status */ -#define ID_RIMSHEALTH 4089 /* SBF message id: Health status of the receiver */ -#define ID_OSNMASTATUS 4231 /* SBF message id: OSNMA status information */ -#define ID_GALNAVMONITOR 4108 /* SBF message id: Monitoring navigation data per Galileo satellite. */ -#define ID_GALNAVRCEDMONITOR 4249 /* SBF message id: Monitoring Reduced CED per Galileo satellite. */ -#define ID_INAVMONITOR 4233 /* SBF message id: Reed-Solomon and SSP status information */ -#define ID_P2PPSTATUS 4238 /* SBF message id: P2PP client/server status */ -//#define ID_AUTHSTATUS 4239 -#define ID_COSMOSTATUS 4243 /* SBF message id: Cosmos receiver service status */ -#define ID_GALAUTHSTATUS 4245 /* SBF message id: Galileo OSNMA authentication status */ -#define ID_FUGROAUTHSTATUS 4256 /* SBF message id: Fugro authentication status */ +#define ID_RXSTATUS1 5913 /* SBF message id: Overall status information of the receiver */ +#define ID_TRACKSTATUS 5912 /* SBF message id: Status of the tracking for all receiver channels */ +#define ID_CHNSTATUS 4013 /* SBF message id: Status of the tracking for all receiver channels */ +#define ID_RXSTATUS2 4014 /* SBF message id: Overall status information of the receiver */ +#define ID_SATVISIBILITY 4012 /* SBF message id: Azimuth/elevation of visible satellites */ +#define ID_INPUTLINK 4090 /* SBF message id: Statistics on input streams */ +#define ID_OUTPUTLINK 4091 /* SBF message id: Statistics on in´output streams */ +#define ID_NTRIPCLTSTAT 4053 /* SBF message id: NTRIP client connection status */ +#define ID_NTRIPSVRSTAT 4122 /* SBF message id: NTRIP server connection status */ +#define ID_IPSTATUS \ + 4058 /* SBF message id: IP address, gateway and MAC address of Ethernet interface */ +#define ID_WIFIAPSTATUS 4054 /* SBF message id: WiFi status in access point mode */ +#define ID_WIFICLTSTATUS 4096 /* SBF message id: WiFi status in client mode */ +#define ID_CELLULARSTATUS 4055 /* SBF message id: Cellular status */ +#define ID_BLUETOOTHSTATUS 4051 /* SBF message id: Bluethooth status */ +#define ID_DYNDNSSTATUS 4105 /* SBF message id: DynDNS status */ +#define ID_BATTERYSTATUS 4083 /* SBF message id: Battery status */ +#define ID_POWERSTATUS 4101 /* SBF message id: Power supply source and voltage */ +#define ID_QUALIND 4082 /* SBF message id: Quality indicators */ +#define ID_DISKSTATUS 4059 /* SBF message id: Internal logging status */ +#define ID_LOGSTATUS 4102 /* SBF message id: Log sessions status */ +#define ID_UHFSTATUS 4085 /* SBF message id: UHF status */ +#define ID_RFSTATUS 4092 /* SBF message id: Radio-frequency interference mitigation status */ +#define ID_RIMSHEALTH 4089 /* SBF message id: Health status of the receiver */ +#define ID_OSNMASTATUS 4231 /* SBF message id: OSNMA status information */ +#define ID_GALNAVMONITOR \ + 4108 /* SBF message id: Monitoring navigation data per Galileo satellite. */ +#define ID_GALNAVRCEDMONITOR \ + 4249 /* SBF message id: Monitoring Reduced CED per Galileo satellite. */ +#define ID_INAVMONITOR 4233 /* SBF message id: Reed-Solomon and SSP status information */ +#define ID_P2PPSTATUS 4238 /* SBF message id: P2PP client/server status */ +// #define ID_AUTHSTATUS 4239 +#define ID_COSMOSTATUS 4243 /* SBF message id: Cosmos receiver service status */ +#define ID_GALAUTHSTATUS 4245 /* SBF message id: Galileo OSNMA authentication status */ +#define ID_FUGROAUTHSTATUS 4256 /* SBF message id: Fugro authentication status */ /* Miscellaneous Blocks */ -#define ID_RXSETUP 5902 /* SBF message id: General information about the receiver installation*/ -#define ID_RXCOMPS 4084 /* SBF message id: Information on various receiver components */ -#define ID_RXMESSAGE 4103 /* SBF message id: Receiver Messages */ -#define ID_COMMANDS 4015 /* SBF message id: Commands entered by the user */ -#define ID_COMMENT 5936 /* SBF message id: Comment entered by the user */ -#define ID_BBSMPS 4040 /* SBF message id: Baseband samples */ -#define ID_ASCIIIN 4075 /* SBF message id: ASCII input from external sensor */ -#define ID_ENCAPSOUT 4097 /* SBF message id: SBF encapsulation of non-SBF messages */ -#define ID_RAWDATAIN 4236 /* SBF message id: Incoming raw data message */ -#define ID_IMURAWSAMPLES 4250 /* SBF message id: IMU Raw samples */ -#define ID_INTERFACESTATS 4261 /* SBF message id: Statistics (data traffic and Internet availability) of every interface. */ +#define ID_RXSETUP 5902 /* SBF message id: General information about the receiver installation*/ +#define ID_RXCOMPS 4084 /* SBF message id: Information on various receiver components */ +#define ID_RXMESSAGE 4103 /* SBF message id: Receiver Messages */ +#define ID_COMMANDS 4015 /* SBF message id: Commands entered by the user */ +#define ID_COMMENT 5936 /* SBF message id: Comment entered by the user */ +#define ID_BBSMPS 4040 /* SBF message id: Baseband samples */ +#define ID_ASCIIIN 4075 /* SBF message id: ASCII input from external sensor */ +#define ID_ENCAPSOUT 4097 /* SBF message id: SBF encapsulation of non-SBF messages */ +#define ID_RAWDATAIN 4236 /* SBF message id: Incoming raw data message */ +#define ID_IMURAWSAMPLES 4250 /* SBF message id: IMU Raw samples */ +#define ID_INTERFACESTATS \ + 4261 /* SBF message id: Statistics (data traffic and Internet availability) of every interface. \ + */ /* Advanced Blocks */ -#define ID_SYSINFO 6000 /* SBF message id: System parameters for maintenance and support */ - +#define ID_SYSINFO 6000 /* SBF message id: System parameters for maintenance and support */ /* get fields (little-endian) ------------------------------------------------*/ #define U1(p) (*((const uint8_t *)(p))) #define I1(p) (*((const int8_t *)(p))) -static uint16_t U2(const uint8_t *p) {uint16_t u; memcpy(&u, p, 2); return u;} -static uint32_t U4(const uint8_t *p) {uint32_t u; memcpy(&u, p, 4); return u;} -static float R4(const uint8_t *p) {float r; memcpy(&r, p, 4); return r;} -static double R8(const uint8_t *p) {double r; memcpy(&r, p, 8); return r;} -static int32_t I4(const uint8_t *p) {int32_t u; memcpy(&u, p, 4); return u;} -static int16_t I2(const uint8_t *p) {int16_t i; memcpy(&i, p, 2); return i;} +static uint16_t U2(const uint8_t *p) { + uint16_t u; + memcpy(&u, p, 2); + return u; +} +static uint32_t U4(const uint8_t *p) { + uint32_t u; + memcpy(&u, p, 4); + return u; +} +static float R4(const uint8_t *p) { + float r; + memcpy(&r, p, 4); + return r; +} +static double R8(const uint8_t *p) { + double r; + memcpy(&r, p, 8); + return r; +} +static int32_t I4(const uint8_t *p) { + int32_t u; + memcpy(&u, p, 4); + return u; +} +static int16_t I2(const uint8_t *p) { + int16_t i; + memcpy(&i, p, 2); + return i; +} static void STR(const uint8_t *p, size_t size, char *string) { memcpy(string, p, size); @@ -384,85 +456,72 @@ static void STR(const uint8_t *p, size_t size, char *string) { /* checksum lookup table -----------------------------------------------------*/ static const unsigned short CRC_16CCIT_LookUp[256] = { - 0x0000, 0x1021, 0x2042, 0x3063, 0x4084, 0x50a5, 0x60c6, 0x70e7, - 0x8108, 0x9129, 0xa14a, 0xb16b, 0xc18c, 0xd1ad, 0xe1ce, 0xf1ef, - 0x1231, 0x0210, 0x3273, 0x2252, 0x52b5, 0x4294, 0x72f7, 0x62d6, - 0x9339, 0x8318, 0xb37b, 0xa35a, 0xd3bd, 0xc39c, 0xf3ff, 0xe3de, - 0x2462, 0x3443, 0x0420, 0x1401, 0x64e6, 0x74c7, 0x44a4, 0x5485, - 0xa56a, 0xb54b, 0x8528, 0x9509, 0xe5ee, 0xf5cf, 0xc5ac, 0xd58d, - 0x3653, 0x2672, 0x1611, 0x0630, 0x76d7, 0x66f6, 0x5695, 0x46b4, - 0xb75b, 0xa77a, 0x9719, 0x8738, 0xf7df, 0xe7fe, 0xd79d, 0xc7bc, - 0x48c4, 0x58e5, 0x6886, 0x78a7, 0x0840, 0x1861, 0x2802, 0x3823, - 0xc9cc, 0xd9ed, 0xe98e, 0xf9af, 0x8948, 0x9969, 0xa90a, 0xb92b, - 0x5af5, 0x4ad4, 0x7ab7, 0x6a96, 0x1a71, 0x0a50, 0x3a33, 0x2a12, - 0xdbfd, 0xcbdc, 0xfbbf, 0xeb9e, 0x9b79, 0x8b58, 0xbb3b, 0xab1a, - 0x6ca6, 0x7c87, 0x4ce4, 0x5cc5, 0x2c22, 0x3c03, 0x0c60, 0x1c41, - 0xedae, 0xfd8f, 0xcdec, 0xddcd, 0xad2a, 0xbd0b, 0x8d68, 0x9d49, - 0x7e97, 0x6eb6, 0x5ed5, 0x4ef4, 0x3e13, 0x2e32, 0x1e51, 0x0e70, - 0xff9f, 0xefbe, 0xdfdd, 0xcffc, 0xbf1b, 0xaf3a, 0x9f59, 0x8f78, - 0x9188, 0x81a9, 0xb1ca, 0xa1eb, 0xd10c, 0xc12d, 0xf14e, 0xe16f, - 0x1080, 0x00a1, 0x30c2, 0x20e3, 0x5004, 0x4025, 0x7046, 0x6067, - 0x83b9, 0x9398, 0xa3fb, 0xb3da, 0xc33d, 0xd31c, 0xe37f, 0xf35e, - 0x02b1, 0x1290, 0x22f3, 0x32d2, 0x4235, 0x5214, 0x6277, 0x7256, - 0xb5ea, 0xa5cb, 0x95a8, 0x8589, 0xf56e, 0xe54f, 0xd52c, 0xc50d, - 0x34e2, 0x24c3, 0x14a0, 0x0481, 0x7466, 0x6447, 0x5424, 0x4405, - 0xa7db, 0xb7fa, 0x8799, 0x97b8, 0xe75f, 0xf77e, 0xc71d, 0xd73c, - 0x26d3, 0x36f2, 0x0691, 0x16b0, 0x6657, 0x7676, 0x4615, 0x5634, - 0xd94c, 0xc96d, 0xf90e, 0xe92f, 0x99c8, 0x89e9, 0xb98a, 0xa9ab, - 0x5844, 0x4865, 0x7806, 0x6827, 0x18c0, 0x08e1, 0x3882, 0x28a3, - 0xcb7d, 0xdb5c, 0xeb3f, 0xfb1e, 0x8bf9, 0x9bd8, 0xabbb, 0xbb9a, - 0x4a75, 0x5a54, 0x6a37, 0x7a16, 0x0af1, 0x1ad0, 0x2ab3, 0x3a92, - 0xfd2e, 0xed0f, 0xdd6c, 0xcd4d, 0xbdaa, 0xad8b, 0x9de8, 0x8dc9, - 0x7c26, 0x6c07, 0x5c64, 0x4c45, 0x3ca2, 0x2c83, 0x1ce0, 0x0cc1, - 0xef1f, 0xff3e, 0xcf5d, 0xdf7c, 0xaf9b, 0xbfba, 0x8fd9, 0x9ff8, - 0x6e17, 0x7e36, 0x4e55, 0x5e74, 0x2e93, 0x3eb2, 0x0ed1, 0x1ef0}; + 0x0000, 0x1021, 0x2042, 0x3063, 0x4084, 0x50a5, 0x60c6, 0x70e7, 0x8108, 0x9129, 0xa14a, 0xb16b, + 0xc18c, 0xd1ad, 0xe1ce, 0xf1ef, 0x1231, 0x0210, 0x3273, 0x2252, 0x52b5, 0x4294, 0x72f7, 0x62d6, + 0x9339, 0x8318, 0xb37b, 0xa35a, 0xd3bd, 0xc39c, 0xf3ff, 0xe3de, 0x2462, 0x3443, 0x0420, 0x1401, + 0x64e6, 0x74c7, 0x44a4, 0x5485, 0xa56a, 0xb54b, 0x8528, 0x9509, 0xe5ee, 0xf5cf, 0xc5ac, 0xd58d, + 0x3653, 0x2672, 0x1611, 0x0630, 0x76d7, 0x66f6, 0x5695, 0x46b4, 0xb75b, 0xa77a, 0x9719, 0x8738, + 0xf7df, 0xe7fe, 0xd79d, 0xc7bc, 0x48c4, 0x58e5, 0x6886, 0x78a7, 0x0840, 0x1861, 0x2802, 0x3823, + 0xc9cc, 0xd9ed, 0xe98e, 0xf9af, 0x8948, 0x9969, 0xa90a, 0xb92b, 0x5af5, 0x4ad4, 0x7ab7, 0x6a96, + 0x1a71, 0x0a50, 0x3a33, 0x2a12, 0xdbfd, 0xcbdc, 0xfbbf, 0xeb9e, 0x9b79, 0x8b58, 0xbb3b, 0xab1a, + 0x6ca6, 0x7c87, 0x4ce4, 0x5cc5, 0x2c22, 0x3c03, 0x0c60, 0x1c41, 0xedae, 0xfd8f, 0xcdec, 0xddcd, + 0xad2a, 0xbd0b, 0x8d68, 0x9d49, 0x7e97, 0x6eb6, 0x5ed5, 0x4ef4, 0x3e13, 0x2e32, 0x1e51, 0x0e70, + 0xff9f, 0xefbe, 0xdfdd, 0xcffc, 0xbf1b, 0xaf3a, 0x9f59, 0x8f78, 0x9188, 0x81a9, 0xb1ca, 0xa1eb, + 0xd10c, 0xc12d, 0xf14e, 0xe16f, 0x1080, 0x00a1, 0x30c2, 0x20e3, 0x5004, 0x4025, 0x7046, 0x6067, + 0x83b9, 0x9398, 0xa3fb, 0xb3da, 0xc33d, 0xd31c, 0xe37f, 0xf35e, 0x02b1, 0x1290, 0x22f3, 0x32d2, + 0x4235, 0x5214, 0x6277, 0x7256, 0xb5ea, 0xa5cb, 0x95a8, 0x8589, 0xf56e, 0xe54f, 0xd52c, 0xc50d, + 0x34e2, 0x24c3, 0x14a0, 0x0481, 0x7466, 0x6447, 0x5424, 0x4405, 0xa7db, 0xb7fa, 0x8799, 0x97b8, + 0xe75f, 0xf77e, 0xc71d, 0xd73c, 0x26d3, 0x36f2, 0x0691, 0x16b0, 0x6657, 0x7676, 0x4615, 0x5634, + 0xd94c, 0xc96d, 0xf90e, 0xe92f, 0x99c8, 0x89e9, 0xb98a, 0xa9ab, 0x5844, 0x4865, 0x7806, 0x6827, + 0x18c0, 0x08e1, 0x3882, 0x28a3, 0xcb7d, 0xdb5c, 0xeb3f, 0xfb1e, 0x8bf9, 0x9bd8, 0xabbb, 0xbb9a, + 0x4a75, 0x5a54, 0x6a37, 0x7a16, 0x0af1, 0x1ad0, 0x2ab3, 0x3a92, 0xfd2e, 0xed0f, 0xdd6c, 0xcd4d, + 0xbdaa, 0xad8b, 0x9de8, 0x8dc9, 0x7c26, 0x6c07, 0x5c64, 0x4c45, 0x3ca2, 0x2c83, 0x1ce0, 0x0cc1, + 0xef1f, 0xff3e, 0xcf5d, 0xdf7c, 0xaf9b, 0xbfba, 0x8fd9, 0x9ff8, 0x6e17, 0x7e36, 0x4e55, 0x5e74, + 0x2e93, 0x3eb2, 0x0ed1, 0x1ef0}; /* SBF checksum calculation --------------------------------------------------*/ -static unsigned short sbf_checksum(unsigned char *buff, int len) -{ - int i; - unsigned short crc = 0; - for (i=0; i> 8) ^ buff[i] ]; - } - return crc; +static unsigned short sbf_checksum(unsigned char *buff, int len) { + int i; + unsigned short crc = 0; + for (i = 0; i < len; i++) { + crc = (crc << 8) ^ CRC_16CCIT_LookUp[(crc >> 8) ^ buff[i]]; + } + return crc; } /* count number of bits set in byte ------------------------------------------*/ -static uint8_t bitcnt(uint8_t b) -{ - uint8_t n = 0; +static uint8_t bitcnt(uint8_t b) { + uint8_t n = 0; - for (uint8_t i = 0; i < 8; i++) - n += ((b >> i) & 1); + for (uint8_t i = 0; i < 8; i++) n += ((b >> i) & 1); - return n; + return n; } /* svid to satellite number ([1] 4.1.9) --------------------------------------*/ -static int svid2sat(int svid) -{ - if (svid == 0) return 0; - if (svid <= 37) return satno(SYS_GPS, svid); - if (svid <= 61) return satno(SYS_GLO, svid-37); - if (svid <= 62) return 0; /* GLONASS unknown slot */ - if (svid <= 68) return satno(SYS_GLO, svid-38); - if (svid <= 70) return 0; - if (svid <= 106) return satno(SYS_GAL, svid-70); - if (svid <= 119) return 0; - if (svid <= 140) return satno(SYS_SBS, svid); - if (svid <= 180) return satno(SYS_CMP, svid-140); - if (svid <= 187) return satno(SYS_QZS, svid-180+192); - if (svid <= 190) return 0; /* L-Band (MMS) Satellite */ - if (svid <= 197) return satno(SYS_IRN, svid-190); - if (svid <= 215) return satno(SYS_SBS, svid-57); - if (svid <= 222) return satno(SYS_IRN, svid-208); - if (svid <= 245) return satno(SYS_CMP, svid-182); - return 0; /* error */ +static int svid2sat(int svid) { + if (svid == 0) return 0; + if (svid <= 37) return satno(SYS_GPS, svid); + if (svid <= 61) return satno(SYS_GLO, svid - 37); + if (svid <= 62) return 0; /* GLONASS unknown slot */ + if (svid <= 68) return satno(SYS_GLO, svid - 38); + if (svid <= 70) return 0; + if (svid <= 106) return satno(SYS_GAL, svid - 70); + if (svid <= 119) return 0; + if (svid <= 140) return satno(SYS_SBS, svid); + if (svid <= 180) return satno(SYS_CMP, svid - 140); + if (svid <= 187) return satno(SYS_QZS, svid - 180 + 192); + if (svid <= 190) return 0; /* L-Band (MMS) Satellite */ + if (svid <= 197) return satno(SYS_IRN, svid - 190); + if (svid <= 215) return satno(SYS_SBS, svid - 57); + if (svid <= 222) return satno(SYS_IRN, svid - 208); + if (svid <= 245) return satno(SYS_CMP, svid - 182); + return 0; /* error */ } /* signal number table ([1] 4.1.10) ------------------------------------------*/ -static uint8_t sig_tbl[SBF_MAXSIG+1][2] = { /* system, obs-code */ +static uint8_t sig_tbl[SBF_MAXSIG + 1][2] = { + /* system, obs-code */ {SYS_GPS, CODE_L1C}, /* 0: GPS L1C/A */ {SYS_GPS, CODE_L1W}, /* 1: GPS L1P */ {SYS_GPS, CODE_L2W}, /* 2: GPS L2P */ @@ -479,14 +538,14 @@ static uint8_t sig_tbl[SBF_MAXSIG+1][2] = { /* system, obs-code */ {SYS_CMP, CODE_L1P}, /* 13: BDS B1C */ {SYS_CMP, CODE_L5P}, /* 14: BDS B2a */ {SYS_IRN, CODE_L5A}, /* 15: IRN L5 */ - { 0, 0}, /* 16: reserved */ + {0, 0}, /* 16: reserved */ {SYS_GAL, CODE_L1C}, /* 17: GAL E1(L1BC) */ - { 0, 0}, /* 18: reserved */ + {0, 0}, /* 18: reserved */ {SYS_GAL, CODE_L6C}, /* 19: GAL E6(E6BC) */ {SYS_GAL, CODE_L5Q}, /* 20: GAL E5a */ {SYS_GAL, CODE_L7Q}, /* 21: GAL E5b */ {SYS_GAL, CODE_L8Q}, /* 22: GAL E5 AltBoc */ - { 0, 0}, /* 23: LBand */ + {0, 0}, /* 23: LBand */ {SYS_SBS, CODE_L1C}, /* 24: SBS L1C/A */ {SYS_SBS, CODE_L5I}, /* 25: SBS L5 */ {SYS_QZS, CODE_L5Q}, /* 26: QZS L5 */ @@ -494,189 +553,194 @@ static uint8_t sig_tbl[SBF_MAXSIG+1][2] = { /* system, obs-code */ {SYS_CMP, CODE_L2I}, /* 28: BDS B1I */ {SYS_CMP, CODE_L7I}, /* 29: BDS B2I */ {SYS_CMP, CODE_L6I}, /* 30: BDS B3I */ - { 0, 0}, /* 31: reserved */ + {0, 0}, /* 31: reserved */ {SYS_QZS, CODE_L1L}, /* 32: QZS L1C */ {SYS_QZS, CODE_L1Z}, /* 33: QZS L1S */ {SYS_CMP, CODE_L7D}, /* 34: BDS B2b */ - { 0, 0}, /* 35: reserved */ + {0, 0}, /* 35: reserved */ {SYS_IRN, CODE_L9A}, /* 36: IRN S */ - {SYS_IRN, 0}, /* 37: IRN L1 */ + {SYS_IRN, 0}, /* 37: IRN L1 */ {SYS_QZS, CODE_L1E}, /* 38: (tentative) QZSS L1CB */ {SYS_QZS, CODE_L5P}, /* 39: QZSS L5S */ }; -static const int Meas3SigIdx2SignalType_Default[7][16] = - { - /* Idx: 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 */ - /* GPS */ {CODE_L1C, CODE_L2L, CODE_L5Q, CODE_L1W, CODE_L2W, CODE_L1L, CODE_NONE, CODE_NONE, CODE_NONE, CODE_NONE, CODE_NONE, CODE_NONE, CODE_NONE, CODE_NONE, CODE_NONE, CODE_NONE}, - /* GLO */ {CODE_L1C, CODE_L2C, CODE_L1P, CODE_L2P, CODE_L3Q, CODE_NONE, CODE_NONE, CODE_NONE, CODE_NONE, CODE_NONE, CODE_NONE, CODE_NONE, CODE_NONE, CODE_NONE, CODE_NONE, CODE_NONE}, - /* GAL */ {CODE_L1C, CODE_L5Q, CODE_L7Q, CODE_L6C, CODE_L8Q, CODE_NONE, CODE_NONE, CODE_NONE, CODE_NONE, CODE_NONE, CODE_NONE, CODE_NONE, CODE_NONE, CODE_NONE, CODE_NONE, CODE_NONE}, - /* BDS */ {CODE_L2I, CODE_L7I, CODE_L6I, CODE_L1P, CODE_L5P, CODE_L7D, CODE_NONE, CODE_NONE, CODE_NONE, CODE_NONE, CODE_NONE, CODE_NONE, CODE_NONE, CODE_NONE, CODE_NONE, CODE_NONE}, - /* SBA */ {CODE_L1C, CODE_L5I, CODE_NONE, CODE_NONE, CODE_NONE, CODE_NONE, CODE_NONE, CODE_NONE, CODE_NONE, CODE_NONE, CODE_NONE, CODE_NONE, CODE_NONE, CODE_NONE, CODE_NONE, CODE_NONE}, - /* QZS */ {CODE_L1C, CODE_L2L, CODE_L5Q, CODE_L6L, CODE_L1L, CODE_L1Z, CODE_L5P, CODE_NONE/*L1CB*/,CODE_NONE, CODE_NONE, CODE_NONE, CODE_NONE, CODE_NONE, CODE_NONE, CODE_NONE, CODE_NONE}, - /* IRN */ {CODE_L5A, CODE_L1E, CODE_L9A, CODE_NONE, CODE_NONE, CODE_NONE, CODE_NONE, CODE_NONE, CODE_NONE, CODE_NONE, CODE_NONE, CODE_NONE, CODE_NONE, CODE_NONE, CODE_NONE, CODE_NONE} -}; - -static int sigPriority(int sys, int idx, const char *opt, uint8_t *code) -{ - int nex = NEXOBS; - /* resolve code priority in a freq-index */ - if (sys == SYS_GPS) { - if (strstr(opt, "-GL1W") && idx==0) return (*code == CODE_L1W) ? 0 : -1; - if (strstr(opt, "-GL1L") && idx==0) return (*code == CODE_L1L) ? 0 : -1; - if (strstr(opt, "-GL2L") && idx==1) return (*code == CODE_L2L) ? 1 : -1; - if (*code == CODE_L1W) return (nex<1) ? -1 : NFREQ; - if (*code == CODE_L2L) return (nex<2) ? -1 : NFREQ + 1; - if (*code == CODE_L1L) return (nex<3) ? -1 : NFREQ + 2; - } - else if (sys == SYS_GLO) { - if (strstr(opt, "-RL1P") && idx==0) return (*code == CODE_L1P) ? 0 : -1; - if (strstr(opt, "-RL2C") && idx==1) return (*code == CODE_L2C) ? 1 : -1; - if (*code == CODE_L1P) return (nex<1) ? -1 : NFREQ; - if (*code == CODE_L2C) return (nex<2) ? -1 : NFREQ + 1; - } - else if (sys == SYS_QZS) { - if (strstr(opt, "-JL1L") && idx==0) return (*code == CODE_L1L) ? 0 : -1; - if (strstr(opt, "-JL1Z") && idx==0) return (*code == CODE_L1Z) ? 0 : -1; - if (*code == CODE_L1L) return (nex<1) ? -1 : NFREQ; - if (*code == CODE_L1Z) return (nex<2) ? -1 : NFREQ + 1; - } - else if (sys == SYS_CMP) { - if (strstr(opt, "-CL1P") && idx==0) return (*code == CODE_L1P) ? 0 : -1; - if (*code == CODE_L1P) return (nex<1) ? -1 : NFREQ; - } - return (idx < NFREQ + nex) ? idx : -1; +static const int Meas3SigIdx2SignalType_Default[7][16] = { + /* Idx: 0 1 2 3 4 5 6 7 8 + 9 10 11 12 13 14 15 */ + /* GPS */ {CODE_L1C, CODE_L2L, CODE_L5Q, CODE_L1W, CODE_L2W, CODE_L1L, CODE_NONE, CODE_NONE, + CODE_NONE, CODE_NONE, CODE_NONE, CODE_NONE, CODE_NONE, CODE_NONE, CODE_NONE, + CODE_NONE}, + /* GLO */ + {CODE_L1C, CODE_L2C, CODE_L1P, CODE_L2P, CODE_L3Q, CODE_NONE, CODE_NONE, CODE_NONE, CODE_NONE, + CODE_NONE, CODE_NONE, CODE_NONE, CODE_NONE, CODE_NONE, CODE_NONE, CODE_NONE}, + /* GAL */ + {CODE_L1C, CODE_L5Q, CODE_L7Q, CODE_L6C, CODE_L8Q, CODE_NONE, CODE_NONE, CODE_NONE, CODE_NONE, + CODE_NONE, CODE_NONE, CODE_NONE, CODE_NONE, CODE_NONE, CODE_NONE, CODE_NONE}, + /* BDS */ + {CODE_L2I, CODE_L7I, CODE_L6I, CODE_L1P, CODE_L5P, CODE_L7D, CODE_NONE, CODE_NONE, CODE_NONE, + CODE_NONE, CODE_NONE, CODE_NONE, CODE_NONE, CODE_NONE, CODE_NONE, CODE_NONE}, + /* SBA */ + {CODE_L1C, CODE_L5I, CODE_NONE, CODE_NONE, CODE_NONE, CODE_NONE, CODE_NONE, CODE_NONE, + CODE_NONE, CODE_NONE, CODE_NONE, CODE_NONE, CODE_NONE, CODE_NONE, CODE_NONE, CODE_NONE}, + /* QZS */ + {CODE_L1C, CODE_L2L, CODE_L5Q, CODE_L6L, CODE_L1L, CODE_L1Z, CODE_L5P, CODE_NONE /*L1CB*/, + CODE_NONE, CODE_NONE, CODE_NONE, CODE_NONE, CODE_NONE, CODE_NONE, CODE_NONE, CODE_NONE}, + /* IRN */ + {CODE_L5A, CODE_L1E, CODE_L9A, CODE_NONE, CODE_NONE, CODE_NONE, CODE_NONE, CODE_NONE, CODE_NONE, + CODE_NONE, CODE_NONE, CODE_NONE, CODE_NONE, CODE_NONE, CODE_NONE, CODE_NONE}}; + +static int sigPriority(int sys, int idx, const char *opt, uint8_t *code) { + int nex = NEXOBS; + /* resolve code priority in a freq-index */ + if (sys == SYS_GPS) { + if (strstr(opt, "-GL1W") && idx == 0) return (*code == CODE_L1W) ? 0 : -1; + if (strstr(opt, "-GL1L") && idx == 0) return (*code == CODE_L1L) ? 0 : -1; + if (strstr(opt, "-GL2L") && idx == 1) return (*code == CODE_L2L) ? 1 : -1; + if (*code == CODE_L1W) return (nex < 1) ? -1 : NFREQ; + if (*code == CODE_L2L) return (nex < 2) ? -1 : NFREQ + 1; + if (*code == CODE_L1L) return (nex < 3) ? -1 : NFREQ + 2; + } else if (sys == SYS_GLO) { + if (strstr(opt, "-RL1P") && idx == 0) return (*code == CODE_L1P) ? 0 : -1; + if (strstr(opt, "-RL2C") && idx == 1) return (*code == CODE_L2C) ? 1 : -1; + if (*code == CODE_L1P) return (nex < 1) ? -1 : NFREQ; + if (*code == CODE_L2C) return (nex < 2) ? -1 : NFREQ + 1; + } else if (sys == SYS_QZS) { + if (strstr(opt, "-JL1L") && idx == 0) return (*code == CODE_L1L) ? 0 : -1; + if (strstr(opt, "-JL1Z") && idx == 0) return (*code == CODE_L1Z) ? 0 : -1; + if (*code == CODE_L1L) return (nex < 1) ? -1 : NFREQ; + if (*code == CODE_L1Z) return (nex < 2) ? -1 : NFREQ + 1; + } else if (sys == SYS_CMP) { + if (strstr(opt, "-CL1P") && idx == 0) return (*code == CODE_L1P) ? 0 : -1; + if (*code == CODE_L1P) return (nex < 1) ? -1 : NFREQ; + } + return (idx < NFREQ + nex) ? idx : -1; } /* signal number to freq-index and code --------------------------------------*/ -static int meas2_sig2idx(int sat, int sig, const char *opt, uint8_t *code) -{ - int idx, sys = satsys(sat, NULL); +static int meas2_sig2idx(int sat, int sig, const char *opt, uint8_t *code) { + int idx, sys = satsys(sat, NULL); - if (sig<0 || sig>SBF_MAXSIG || sig_tbl[sig][0]!=sys) return -1; - *code = sig_tbl[sig][1]; - idx = code2idx(sys, *code); + if (sig < 0 || sig > SBF_MAXSIG || sig_tbl[sig][0] != sys) return -1; + *code = sig_tbl[sig][1]; + idx = code2idx(sys, *code); - return sigPriority(sys, idx, opt, code); + return sigPriority(sys, idx, opt, code); } /* signal number to freq-index and code for meas3 data -----------------------*/ -static int meas3_sig2idx(int sbf_navsys, int sig, const char *opt, uint8_t *code, int sigTable[7][16]) -{ - int idx; +static int meas3_sig2idx(int sbf_navsys, int sig, const char *opt, uint8_t *code, + int sigTable[7][16]) { + int idx; - if (sig<0 || sig>=MEAS3_SIG_MAX) return -1; - if (sbf_navsys<0 || sbf_navsys>=MEAS3_SYS_MAX) return -1; - *code = sigTable[sbf_navsys][sig]; - idx = code2idx(Meas3_NavSys[sbf_navsys], *code); + if (sig < 0 || sig >= MEAS3_SIG_MAX) return -1; + if (sbf_navsys < 0 || sbf_navsys >= MEAS3_SYS_MAX) return -1; + *code = sigTable[sbf_navsys][sig]; + idx = code2idx(Meas3_NavSys[sbf_navsys], *code); - return sigPriority(Meas3_NavSys[sbf_navsys], idx, opt, code); + return sigPriority(Meas3_NavSys[sbf_navsys], idx, opt, code); } /* initialize obs data fields ------------------------------------------------*/ -static void init_obsd(gtime_t time, int sat, obsd_t *data) -{ - int i; - - data->time = time; - data->sat = (uint8_t)sat; - - for (i = 0; i < NFREQ+NEXOBS; i++) { - data->L[i] = data->P[i] = 0.0; - data->D[i] = data->SNR[i] = 0.0; - data->Lstd[i] = data->Pstd[i] = 0.0; - data->LLI[i] = 0; - data->code[i] = CODE_NONE; - } +static void init_obsd(gtime_t time, int sat, obsd_t *data) { + int i; + + data->time = time; + data->sat = (uint8_t)sat; + + for (i = 0; i < NFREQ + NEXOBS; i++) { + data->L[i] = data->P[i] = 0.0; + data->D[i] = data->SNR[i] = 0.0; + data->Lstd[i] = data->Pstd[i] = 0.0; + data->LLI[i] = 0; + data->code[i] = CODE_NONE; + } } /* 8-bit week -> full week ---------------------------------------------------*/ -static void adj_utcweek(gtime_t time, double *utc) -{ - int week; - - if (*utc >= 256.0) return; - time2gpst(time, &week); - *utc += (week / 256) * 256; - if (*utc < week-128) *utc += 256.0; - else if (*utc > week+128) *utc -= 256.0; +static void adj_utcweek(gtime_t time, double *utc) { + int week; + + if (*utc >= 256.0) return; + time2gpst(time, &week); + *utc += (week / 256) * 256; + if (*utc < week - 128) + *utc += 256.0; + else if (*utc > week + 128) + *utc -= 256.0; } /* convert 8-bit week -> full week --------------------------------------------*/ -static uint16_t adjust_WN8(uint16_t ref_WN, uint8_t WN) -{ - int16_t offset = (ref_WN % 256) - WN; - if (offset > 128) offset -= 256; - if (offset < -127) offset += 256; - return ref_WN + offset; +static uint16_t adjust_WN8(uint16_t ref_WN, uint8_t WN) { + int16_t offset = (ref_WN % 256) - WN; + if (offset > 128) offset -= 256; + if (offset < -127) offset += 256; + return ref_WN + offset; } /* convert 10-bit week -> full week --------------------------------------------*/ -static uint16_t adjust_WN10(uint16_t ref_WN, uint16_t WN) -{ - int16_t offset = (ref_WN % 1024) - WN; - if (offset > 512) offset -= 1024; - if (offset < -511) offset += 1024; - return ref_WN + offset; +static uint16_t adjust_WN10(uint16_t ref_WN, uint16_t WN) { + int16_t offset = (ref_WN % 1024) - WN; + if (offset > 512) offset -= 1024; + if (offset < -511) offset += 1024; + return ref_WN + offset; } /* convert 12-bit week -> full week --------------------------------------------*/ -static uint16_t adjust_WN12(uint16_t ref_WN, uint16_t WN) -{ - int16_t offset = (ref_WN % 4096) - WN; - if (offset > 2048) offset -= 4096; - if (offset < -2047) offset += 4096; - return ref_WN + offset; +static uint16_t adjust_WN12(uint16_t ref_WN, uint16_t WN) { + int16_t offset = (ref_WN % 4096) - WN; + if (offset > 2048) offset -= 4096; + if (offset < -2047) offset += 4096; + return ref_WN + offset; } /* convert 14-bit week -> full week --------------------------------------------*/ -static uint16_t adjust_WN14(uint16_t ref_WN, uint16_t WN) -{ - int16_t offset = (ref_WN % 8192) - WN; - if (offset > 4096) offset -= 8192; - if (offset < -4095) offset += 8192; - return ref_WN + offset; -}/* adjust daily rollover of time ---------------------------------------------*/ -static gtime_t adjday(gtime_t time, double tod) -{ - double ep[6], tod_p; - time2epoch(time, ep); - tod_p = ep[3]*3600.0 + ep[4]*60.0 + ep[5]; - if (tod < tod_p-43200.0) tod += 86400.0; - else if (tod > tod_p+43200.0) tod -= 86400.0; - ep[3] = ep[4] = ep[5] = 0.0; - return timeadd(epoch2time(ep), tod); +static uint16_t adjust_WN14(uint16_t ref_WN, uint16_t WN) { + int16_t offset = (ref_WN % 8192) - WN; + if (offset > 4096) offset -= 8192; + if (offset < -4095) offset += 8192; + return ref_WN + offset; +} /* adjust daily rollover of time ---------------------------------------------*/ +static gtime_t adjday(gtime_t time, double tod) { + double ep[6], tod_p; + time2epoch(time, ep); + tod_p = ep[3] * 3600.0 + ep[4] * 60.0 + ep[5]; + if (tod < tod_p - 43200.0) + tod += 86400.0; + else if (tod > tod_p + 43200.0) + tod -= 86400.0; + ep[3] = ep[4] = ep[5] = 0.0; + return timeadd(epoch2time(ep), tod); } /* Measurement Blocks */ /* flush observation data buffer ---------------------------------------------*/ static int flushobuf(raw_t *raw) { - int i, j, n = 0; + int i, j, n = 0; - trace(3, "flushobuf: n=%d\n", raw->obuf.n); + trace(3, "flushobuf: n=%d\n", raw->obuf.n); - /* copy observation data buffer */ - for (i = 0; i < raw->obuf.n && i < MAXOBS; i++) { - if (!satsys(raw->obuf.data[i].sat, NULL)) continue; - if (raw->obuf.data[i].time.time == 0) continue; - raw->obs.data[n++] = raw->obuf.data[i]; - } - raw->obs.n = n; - - /* clear observation data buffer */ - for (i = 0; i < MAXOBS; i++) { - raw->obuf.data[i].time.time = 0; - raw->obuf.data[i].time.sec = 0; - for (j = 0; j < NFREQ + NEXOBS; j++) { - raw->obuf.data[i].L[j] = raw->obuf.data[i].P[j] = 0.0; - raw->obuf.data[i].D[j] = raw->obuf.data[i].SNR[j] = 0.0; - raw->obuf.data[i].Lstd[j] = raw->obuf.data[i].Pstd[j] = 0.0; - raw->obuf.data[i].LLI[j] = 0; - raw->obuf.data[i].code[j] = CODE_NONE; - } - } - for (i = 0; i < MAXSAT; i++) { - raw->prCA[i] = raw->dpCA[i] = 0.0; + /* copy observation data buffer */ + for (i = 0; i < raw->obuf.n && i < MAXOBS; i++) { + if (!satsys(raw->obuf.data[i].sat, NULL)) continue; + if (raw->obuf.data[i].time.time == 0) continue; + raw->obs.data[n++] = raw->obuf.data[i]; + } + raw->obs.n = n; + + /* clear observation data buffer */ + for (i = 0; i < MAXOBS; i++) { + raw->obuf.data[i].time.time = 0; + raw->obuf.data[i].time.sec = 0; + for (j = 0; j < NFREQ + NEXOBS; j++) { + raw->obuf.data[i].L[j] = raw->obuf.data[i].P[j] = 0.0; + raw->obuf.data[i].D[j] = raw->obuf.data[i].SNR[j] = 0.0; + raw->obuf.data[i].Lstd[j] = raw->obuf.data[i].Pstd[j] = 0.0; + raw->obuf.data[i].LLI[j] = 0; + raw->obuf.data[i].code[j] = CODE_NONE; } - return n > 0 ? 1 : 0; + } + for (i = 0; i < MAXSAT; i++) { + raw->prCA[i] = raw->dpCA[i] = 0.0; + } + return n > 0 ? 1 : 0; } /* decode SBF measurements message (observables) -----------------------------*/ @@ -693,949 +757,1013 @@ static int flushobuf(raw_t *raw) { * expressed as difference from the data in signType1 sub-block. This makes the * format a little more compact. * -*/ -static int decode_measepoch(raw_t *raw) -{ - sbf_t *sbf = (sbf_t *)raw->rcv_data; - uint8_t *p = raw->buff+14, code; - double P1, P2, L1, L2, D1, D2, S1, S2, freq1, freq2; - int i, j, idx, n, n1, n2, len1, len2, sig, ant, svid, info, sat, sys, lock, fcn, LLI, chn, ret=0; - int ant_sel = 0; /* antenna selection (0:main) */ - - if (timediff(raw->time, sbf->current_time) > 0) { - sbf->current_time = raw->time; - ret = flushobuf(raw); - } - - if (strstr(raw->opt, "-NO_MEAS2")) return ret; - - if (strstr(raw->opt, "-AUX1")) ant_sel = 1; - else if (strstr(raw->opt, "-AUX2")) ant_sel = 2; + */ +static int decode_measepoch(raw_t *raw) { + sbf_t *sbf = (sbf_t *)raw->rcv_data; + uint8_t *p = raw->buff + 14, code; + double P1, P2, L1, L2, D1, D2, S1, S2, freq1, freq2; + int i, j, idx, n, n1, n2, len1, len2, sig, ant, svid, info, sat, sys, lock, fcn, LLI, chn, + ret = 0; + int ant_sel = 0; /* antenna selection (0:main) */ + + if (timediff(raw->time, sbf->current_time) > 0) { + sbf->current_time = raw->time; + ret = flushobuf(raw); + } - if (raw->len < 20) { - trace(2, "sbf measepoch length error: len=%d\n", raw->len); - return ret ? ret : -1; - } - n1 = U1(p); - len1 = U1(p+1); /* size of measurement block type 1 */ - len2 = U1(p+2); /* size of measurement block type 2 */ + if (strstr(raw->opt, "-NO_MEAS2")) return ret; - if (U1(p+3) & 0x80) { - trace(2, "sbf measepoch scrambled\n"); - return ret ? ret : -1; - } + if (strstr(raw->opt, "-AUX1")) + ant_sel = 1; + else if (strstr(raw->opt, "-AUX2")) + ant_sel = 2; - // reset channel assignment - memset(&sbf->meas2_channelAssignment, -1, 2048*sizeof(int)); + if (raw->len < 20) { + trace(2, "sbf measepoch length error: len=%d\n", raw->len); + return ret ? ret : -1; + } + n1 = U1(p); + len1 = U1(p + 1); /* size of measurement block type 1 */ + len2 = U1(p + 2); /* size of measurement block type 2 */ - if (raw->outtype) { - sprintf(raw->msgtype+strlen(raw->msgtype), " nsat=%d", n1); - } + if (U1(p + 3) & 0x80) { + trace(2, "sbf measepoch scrambled\n"); + return ret ? ret : -1; + } - for (i=n=0, p+=6; ibuff+raw->len; i++) { - /* byte 0: receiver channel */ - chn = U1(p); - ant = U1(p+1) >> 5; - sig = U1(p+1) & 0x1f; - svid = U1(p+2); - info = U1(p+18); - n2 = U1(p+19); /* number of type 2 measurement blocks */ - fcn = 0; - if (sig == 31) sig = (info>>3)+32; - else if (sig>=8 && sig<=11) fcn = (info>>3)-8; - raw->obuf.data[n].freq = fcn+7; - - if (ant != ant_sel) { - trace(3, "sbf measepoch ant error: svid=%d ant=%d\n", svid, ant); - p += len1 + len2*n2; /* skip block (and its sub-blocks)*/ - continue; - } - sat = svid2sat(svid); - if (!sat) { - trace(3, "sbf measepoch svid error: svid=%d\n", svid); - p += len1 + len2*n2; /* skip block (and its sub-blocks)*/ - continue; - } - idx = meas2_sig2idx(sat, sig, raw->opt, &code); - if (idx < 0) { - trace(2, "sbf measepoch sig error: sat=%d sig=%d\n", sat, sig); - p+= len1 + len2*n2; /* skip block (and its sub-blocks)*/ - continue; - } - init_obsd(raw->time, sat, raw->obuf.data+n); - sbf->meas2_channelAssignment[chn] = n; - P1 = D1 = 0.0; - sys = satsys(sat, NULL); - freq1 = code2freq(sys, code, fcn); - - if ((U1(p+3) & 0x0f) !=0 || U4(p+4) != 0) { - P1 = (U1(p+3) & 0x0f)*4294967.296 + U4(p+4)*0.001; - raw->obuf.data[n].P[idx] = P1; - } - if (I4(p+8) != -2147483648) { - D1 = I4(p+8)*0.0001; - raw->obuf.data[n].D[idx] = (float)D1; - } + // reset channel assignment + memset(&sbf->meas2_channelAssignment, -1, 2048 * sizeof(int)); - lock = U2(p+16); - if (P1!=0.0 && freq1>0.0 && lock!=65535 && (I1(p+14) != -128 || U2(p+12) != 0)) { - L1 = I1(p+14)*65.536 + U2(p+12)*0.001; - raw->obuf.data[n].L[idx] = P1*freq1/CLIGHT + L1; - LLI = (locklockt[sat-1][idx] ? 1 : 0) + ((info & (1<<2)) ? 2 : 0); - raw->obuf.data[n].LLI[idx] = (uint8_t)LLI; - raw->lockt[sat-1][idx] = lock; - } - if (U1(p+15) != 255) { - S1 = U1(p+15)*0.25 + ((sig==1 || sig==2) ? 0.0 : 10.0); - raw->obuf.data[n].SNR[idx] = S1; - } - raw->obuf.data[n].code[idx] = code; - - for (j=0, p+=len1; jbuff+raw->len); j++, p+=len2) { - sig = U1(p) & 0x1f; - ant = U1(p) >> 5; - lock = U1(p+1); - info = U1(p+5); - if (sig == 31) sig = (info>>3)+32; - - if (ant != ant_sel) { - trace(3, "sbf measepoch ant error: sat=%d ant=%d\n", sat, ant); - continue; - } - if ((idx = meas2_sig2idx(sat, sig, raw->opt, &code)) < 0) { - trace(3, "sbf measepoch sig error: sat=%d sig=%d\n", sat, sig); - continue; - } - P2 = 0.0; - freq2 = code2freq(sys, code, fcn); - if (lock != 255) { - LLI = (locklockt[sat-1][idx] ? 1 : 0) + ((info&(1<<2)) ? 2 : 0); - raw->obuf.data[n].LLI[idx] = (uint8_t)LLI; - raw->lockt[sat-1][idx] = lock; - } - if (U1(p+2) != 255) { - S2 = U1(p+2)*0.25 + ((sig==1 || sig==2) ? 0.0 : 10.0); - raw->obuf.data[n].SNR[idx] = S2; - } - if (P1!=0.0 && (getbits(p+3, 5, 3)!=-4 || U2(p+6)!=0)) { - P2 = P1+getbits(p+3, 5, 3)*65.536 + U2(p+6)*0.001; - raw->obuf.data[n].P[idx] = P2; - } - if (P2!=0.0 && freq2>0.0 && (I1(p+4)!=-128 || U2(p+8)!=0)) { - L2 = I1(p+4)*65.536 + U2(p+8)*0.001; - raw->obuf.data[n].L[idx] = P2*freq2/CLIGHT+L2; - } - if (D1!=0.0 && freq1>0.0 && freq2>0.0 && (getbits(p+3, 0, 5)!=-16 || U2(p+10)!=0)) { - D2 = getbits(p+3, 0, 5)*6.5536 + U2(p+10)*0.0001; - raw->obuf.data[n].D[idx] = (float)(D1*freq2/freq1)+D2; - } + if (raw->outtype) { + sprintf(raw->msgtype + strlen(raw->msgtype), " nsat=%d", n1); + } - raw->obuf.data[n].code[idx] = code; - } - n++; + for (i = n = 0, p += 6; i < n1 && n < MAXOBS && p + 20 <= raw->buff + raw->len; i++) { + /* byte 0: receiver channel */ + chn = U1(p); + ant = U1(p + 1) >> 5; + sig = U1(p + 1) & 0x1f; + svid = U1(p + 2); + info = U1(p + 18); + n2 = U1(p + 19); /* number of type 2 measurement blocks */ + fcn = 0; + if (sig == 31) + sig = (info >> 3) + 32; + else if (sig >= 8 && sig <= 11) + fcn = (info >> 3) - 8; + raw->obuf.data[n].freq = fcn + 7; + + if (ant != ant_sel) { + trace(3, "sbf measepoch ant error: svid=%d ant=%d\n", svid, ant); + p += len1 + len2 * n2; /* skip block (and its sub-blocks)*/ + continue; } - raw->obuf.n = n; + sat = svid2sat(svid); + if (!sat) { + trace(3, "sbf measepoch svid error: svid=%d\n", svid); + p += len1 + len2 * n2; /* skip block (and its sub-blocks)*/ + continue; + } + idx = meas2_sig2idx(sat, sig, raw->opt, &code); + if (idx < 0) { + trace(2, "sbf measepoch sig error: sat=%d sig=%d\n", sat, sig); + p += len1 + len2 * n2; /* skip block (and its sub-blocks)*/ + continue; + } + init_obsd(raw->time, sat, raw->obuf.data + n); + sbf->meas2_channelAssignment[chn] = n; + P1 = D1 = 0.0; + sys = satsys(sat, NULL); + freq1 = code2freq(sys, code, fcn); + + if ((U1(p + 3) & 0x0f) != 0 || U4(p + 4) != 0) { + P1 = (U1(p + 3) & 0x0f) * 4294967.296 + U4(p + 4) * 0.001; + raw->obuf.data[n].P[idx] = P1; + } + if (I4(p + 8) != -2147483648) { + D1 = I4(p + 8) * 0.0001; + raw->obuf.data[n].D[idx] = (float)D1; + } + + lock = U2(p + 16); + if (P1 != 0.0 && freq1 > 0.0 && lock != 65535 && (I1(p + 14) != -128 || U2(p + 12) != 0)) { + L1 = I1(p + 14) * 65.536 + U2(p + 12) * 0.001; + raw->obuf.data[n].L[idx] = P1 * freq1 / CLIGHT + L1; + LLI = (lock < raw->lockt[sat - 1][idx] ? 1 : 0) + ((info & (1 << 2)) ? 2 : 0); + raw->obuf.data[n].LLI[idx] = (uint8_t)LLI; + raw->lockt[sat - 1][idx] = lock; + } + if (U1(p + 15) != 255) { + S1 = U1(p + 15) * 0.25 + ((sig == 1 || sig == 2) ? 0.0 : 10.0); + raw->obuf.data[n].SNR[idx] = S1; + } + raw->obuf.data[n].code[idx] = code; + + for (j = 0, p += len1; j < n2 && p + 12 <= (raw->buff + raw->len); j++, p += len2) { + sig = U1(p) & 0x1f; + ant = U1(p) >> 5; + lock = U1(p + 1); + info = U1(p + 5); + if (sig == 31) sig = (info >> 3) + 32; + + if (ant != ant_sel) { + trace(3, "sbf measepoch ant error: sat=%d ant=%d\n", sat, ant); + continue; + } + if ((idx = meas2_sig2idx(sat, sig, raw->opt, &code)) < 0) { + trace(3, "sbf measepoch sig error: sat=%d sig=%d\n", sat, sig); + continue; + } + P2 = 0.0; + freq2 = code2freq(sys, code, fcn); + if (lock != 255) { + LLI = (lock < raw->lockt[sat - 1][idx] ? 1 : 0) + ((info & (1 << 2)) ? 2 : 0); + raw->obuf.data[n].LLI[idx] = (uint8_t)LLI; + raw->lockt[sat - 1][idx] = lock; + } + if (U1(p + 2) != 255) { + S2 = U1(p + 2) * 0.25 + ((sig == 1 || sig == 2) ? 0.0 : 10.0); + raw->obuf.data[n].SNR[idx] = S2; + } + if (P1 != 0.0 && (getbits(p + 3, 5, 3) != -4 || U2(p + 6) != 0)) { + P2 = P1 + getbits(p + 3, 5, 3) * 65.536 + U2(p + 6) * 0.001; + raw->obuf.data[n].P[idx] = P2; + } + if (P2 != 0.0 && freq2 > 0.0 && (I1(p + 4) != -128 || U2(p + 8) != 0)) { + L2 = I1(p + 4) * 65.536 + U2(p + 8) * 0.001; + raw->obuf.data[n].L[idx] = P2 * freq2 / CLIGHT + L2; + } + if (D1 != 0.0 && freq1 > 0.0 && freq2 > 0.0 && + (getbits(p + 3, 0, 5) != -16 || U2(p + 10) != 0)) { + D2 = getbits(p + 3, 0, 5) * 6.5536 + U2(p + 10) * 0.0001; + raw->obuf.data[n].D[idx] = (float)(D1 * freq2 / freq1) + D2; + } + + raw->obuf.data[n].code[idx] = code; + } + n++; + } + raw->obuf.n = n; - return ret; + return ret; } -static int decode_measepochextra(raw_t *raw) -{ - sbf_t *sbf = (sbf_t *)raw->rcv_data; - uint8_t *p = raw->buff+8; - uint8_t n_chn, sbLen, i, misc; - uint8_t code, type, chn; - uint16_t revision; - int sig, n, idx, sat, ret = 0; - int ant_sel = 0; /* antenna selection (0:main) */ - - if (timediff(raw->time, sbf->current_time) != 0) { - sbf->current_time = raw->time; - ret = flushobuf(raw); - } +static int decode_measepochextra(raw_t *raw) { + sbf_t *sbf = (sbf_t *)raw->rcv_data; + uint8_t *p = raw->buff + 8; + uint8_t n_chn, sbLen, i, misc; + uint8_t code, type, chn; + uint16_t revision; + int sig, n, idx, sat, ret = 0; + int ant_sel = 0; /* antenna selection (0:main) */ + + if (timediff(raw->time, sbf->current_time) != 0) { + sbf->current_time = raw->time; + ret = flushobuf(raw); + } - if (raw->outtype) { - sprintf(raw->msgtype, "SBF Measurement Data Extra"); - } + if (raw->outtype) { + sprintf(raw->msgtype, "SBF Measurement Data Extra"); + } - if (strstr(raw->opt, "-NO_MEAS2")) return ret; + if (strstr(raw->opt, "-NO_MEAS2")) return ret; - if (strstr(raw->opt, "-AUX1")) ant_sel = 1; - else if (strstr(raw->opt, "-AUX2")) ant_sel = 2; + if (strstr(raw->opt, "-AUX1")) + ant_sel = 1; + else if (strstr(raw->opt, "-AUX2")) + ant_sel = 2; - revision = U2(raw->buff+4) >> 13; - n_chn = U1 (p+6); - sbLen = U1(p+7); + revision = U2(raw->buff + 4) >> 13; + n_chn = U1(p + 6); + sbLen = U1(p + 7); - int rcvstds = 0; - if (strstr(raw->opt, "-RCVSTDS")) rcvstds = 1; + int rcvstds = 0; + if (strstr(raw->opt, "-RCVSTDS")) rcvstds = 1; - for (i = 0; i < n_chn; i++) - { - uint8_t *p_chan = p+12+i*sbLen; + for (i = 0; i < n_chn; i++) { + uint8_t *p_chan = p + 12 + i * sbLen; - chn = U1(p_chan); - type = U1(p_chan+1); - if ((type >> 5) != ant_sel) /* check selected antenna */ - continue; - sig = type & 0x1f; - if (sig == 31) - sig = (U1(p_chan + 15) >> 3) + 32; + chn = U1(p_chan); + type = U1(p_chan + 1); + if ((type >> 5) != ant_sel) /* check selected antenna */ + continue; + sig = type & 0x1f; + if (sig == 31) sig = (U1(p_chan + 15) >> 3) + 32; - n = sbf->meas2_channelAssignment[chn]; - if (n < 0) { - continue; /* channel is acquired but not tracked */ - } - sat = raw->obuf.data[n].sat; - idx = meas2_sig2idx(sat, sig, raw->opt, &code); - if (idx < 0) { - trace(2, "sbf measepochextra sig error: sat=%d sig=%d\n", sat, sig); - continue; - } + n = sbf->meas2_channelAssignment[chn]; + if (n < 0) { + continue; /* channel is acquired but not tracked */ + } + sat = raw->obuf.data[n].sat; + idx = meas2_sig2idx(sat, sig, raw->opt, &code); + if (idx < 0) { + trace(2, "sbf measepochextra sig error: sat=%d sig=%d\n", sat, sig); + continue; + } - /* Write rcvr stdevs to unused RINEX fields */ - if (rcvstds) { - uint16_t codeVarU = U2(p_chan + 6); - if (codeVarU != 65535) { - double codeVar = codeVarU / 10000.0; /* meters^2 */ - raw->obuf.data[n].Pstd[idx] = sqrt(codeVar); - } + /* Write rcvr stdevs to unused RINEX fields */ + if (rcvstds) { + uint16_t codeVarU = U2(p_chan + 6); + if (codeVarU != 65535) { + double codeVar = codeVarU / 10000.0; /* meters^2 */ + raw->obuf.data[n].Pstd[idx] = sqrt(codeVar); + } - uint16_t carrierVarU = U2(p_chan + 8); - if (carrierVarU != 65535) { - double carrierVar = carrierVarU / 1000000.0; /* cycles^2 */ - raw->obuf.data[n].Lstd[idx] = sqrt(carrierVar); - } - } + uint16_t carrierVarU = U2(p_chan + 8); + if (carrierVarU != 65535) { + double carrierVar = carrierVarU / 1000000.0; /* cycles^2 */ + raw->obuf.data[n].Lstd[idx] = sqrt(carrierVar); + } + } - if ((revision >= 3) && (sbLen >= 16)) { /* later revision contains high-resolution extension for CN0 values*/ - misc = U1(p_chan+15); - raw->obuf.data[n].SNR[idx] += (misc & 0x7) * 0.03125; - } + if ((revision >= 3) && + (sbLen >= 16)) { /* later revision contains high-resolution extension for CN0 values*/ + misc = U1(p_chan + 15); + raw->obuf.data[n].SNR[idx] += (misc & 0x7) * 0.03125; } + } - return ret; + return ret; } /* decode meas3 bloack -------------------------------------------------*/ static int decode_meas3ranges(raw_t *raw) { - sbf_t *sbf = (sbf_t *)raw->rcv_data; - uint8_t *p = raw->buff+8; - int n = 0, idx = 0, ret = 0; - int ant_sel = 0; /* antenna selection (0:main) */ - - if (timediff(raw->time, sbf->current_time) != 0) { - sbf->current_time = raw->time; - ret = flushobuf(raw); - } + sbf_t *sbf = (sbf_t *)raw->rcv_data; + uint8_t *p = raw->buff + 8; + int n = 0, idx = 0, ret = 0; + int ant_sel = 0; /* antenna selection (0:main) */ + + if (timediff(raw->time, sbf->current_time) != 0) { + sbf->current_time = raw->time; + ret = flushobuf(raw); + } - if (strstr(raw->opt, "-NO_MEAS3")) return ret; + if (strstr(raw->opt, "-NO_MEAS3")) return ret; - if (strstr(raw->opt, "-AUX1")) ant_sel = 1; - else if (strstr(raw->opt, "-AUX2")) ant_sel = 2; + if (strstr(raw->opt, "-AUX1")) + ant_sel = 1; + else if (strstr(raw->opt, "-AUX2")) + ant_sel = 2; - if (raw->len < 12) { - trace(2, "sbf meas3ranges length error: len=%d\n", raw->len); - return ret ? ret : -1; - } + if (raw->len < 12) { + trace(2, "sbf meas3ranges length error: len=%d\n", raw->len); + return ret ? ret : -1; + } - uint32_t TOW = U4(p + 0); - /* bit 0: multipath mitigation, bit 1: at least one smoothing, bit 2: reserved, bit 3: clock steering active - bit 4: measurement from data component, bit 5: high-dynamic mode, bit 6: E6B used, bit 7: scrambled data */ - /* uint8_t commonFlags = U1(p+6); */ - // int16_t clkJumps = U1(p+7); - // if (clkJumps >= 128) clkJumps -= 256; /* cummulated clock jumps in ms */ - uint8_t constellations = U2(p+8); - uint8_t misc = U1(p+10); /* bit 3: PPR available */ - uint8_t reserved = U1(p+11); /* is actually a version indicator */ - uint8_t prrAvailable = (misc & 8) != 0; /* pseudo-range change rate available in data */ - - if (reserved > 31) { - trace(2, "sbf meas3ranges invalid data version: len=%d\n", raw->len); - return ret ? ret : -1; - } + uint32_t TOW = U4(p + 0); + /* bit 0: multipath mitigation, bit 1: at least one smoothing, bit 2: reserved, bit 3: clock + steering active bit 4: measurement from data component, bit 5: high-dynamic mode, bit 6: E6B + used, bit 7: scrambled data */ + /* uint8_t commonFlags = U1(p+6); */ + // int16_t clkJumps = U1(p+7); + // if (clkJumps >= 128) clkJumps -= 256; /* cummulated clock jumps in ms */ + uint8_t constellations = U2(p + 8); + uint8_t misc = U1(p + 10); /* bit 3: PPR available */ + uint8_t reserved = U1(p + 11); /* is actually a version indicator */ + uint8_t prrAvailable = (misc & 8) != 0; /* pseudo-range change rate available in data */ + + if (reserved > 31) { + trace(2, "sbf meas3ranges invalid data version: len=%d\n", raw->len); + return ret ? ret : -1; + } - int antennaIdx = misc & 7; - if (ant_sel != antennaIdx) return ret; - uint32_t refEpochInterval = Meas3_EpochIntervals[misc >> 4]; /* interval for full epoche data */ + int antennaIdx = misc & 7; + if (ant_sel != antennaIdx) return ret; + uint32_t refEpochInterval = Meas3_EpochIntervals[misc >> 4]; /* interval for full epoche data */ - // if this is a reference epoch? - if ((TOW % refEpochInterval) == 0) // clean-up old data - { - memset(&sbf->meas3_refEpoch, 0, sizeof(Meas3_RefEpoch_t)); - sbf->meas3_refEpoch.TOW = TOW; - } + // if this is a reference epoch? + if ((TOW % refEpochInterval) == 0) // clean-up old data + { + memset(&sbf->meas3_refEpoch, 0, sizeof(Meas3_RefEpoch_t)); + sbf->meas3_refEpoch.TOW = TOW; + } - p += 12; // jump to start of data + p += 12; // jump to start of data - /* invalidate frequency assignments */ - memset(sbf->meas3_freqAssignment, -1, MEAS3_SYS_MAX*MEAS3_SAT_MAX*MEAS3_SIG_MAX*sizeof(uint8_t)); + /* invalidate frequency assignments */ + memset(sbf->meas3_freqAssignment, -1, + MEAS3_SYS_MAX * MEAS3_SAT_MAX * MEAS3_SIG_MAX * sizeof(uint8_t)); - if (((TOW % refEpochInterval) != 0) && // check reference epoch - (sbf->meas3_refEpoch.TOW != (uint32_t)(TOW / refEpochInterval)*refEpochInterval)) { // or reference epoch is available - raw->obuf.n = 0; - return ret; - } + if (((TOW % refEpochInterval) != 0) && // check reference epoch + (sbf->meas3_refEpoch.TOW != + (uint32_t)(TOW / refEpochInterval) * refEpochInterval)) { // or reference epoch is available + raw->obuf.n = 0; + return ret; + } - for (int navsys = 0; navsys < MEAS3_SYS_MAX; navsys++) { - if ((constellations & (1 << navsys)) == 0) - continue; /* no data for this navigation system */ - - uint8_t *p_navsys = p+idx, idx_navsys = 0; - uint8_t nSats = 0, satCnt = 0, sigExcluded; - uint16_t bdsLongRange = 0; - uint8_t gloFncs[8] = {0, 0, 0, 0, 0, 0, 0, 0}; - uint64_t satMask = 0; - int sigTable[MEAS3_SYS_MAX][MEAS3_SIG_MAX]; - - // read satellite data - if (U1(p+idx) == 0) - p_navsys = sbf->meas3_refEpoch.constellationHeader[navsys]; - - uint8_t BF1 = U1(p_navsys+idx_navsys); - uint8_t nB = BF1 & 0x7; - uint8_t signalIndexMasterShort = (BF1 >> 3) & 0xf; - uint8_t signalExcludedPresent = (BF1 >> 7) != 0; - idx_navsys++; - if (nB == 7) nB = 8; - - // read satellite mask - for (int i = 0; i < nB; i++) { - satMask |= (uint64_t)U1(p_navsys+idx_navsys+i) << (i*8); - nSats += bitcnt(U1(p_navsys+idx_navsys+i)); - } - idx_navsys += nB; - - // Read GLONASS fcn list - if (navsys == 1) { // GLONASS - memcpy(gloFncs, p_navsys+idx_navsys, (nSats+1) / 2); - idx_navsys += (nSats+1) / 2; - } else if (navsys == 3) { // BDS - bdsLongRange = U2(p_navsys+idx_navsys); - idx_navsys += 2; - } + for (int navsys = 0; navsys < MEAS3_SYS_MAX; navsys++) { + if ((constellations & (1 << navsys)) == 0) continue; /* no data for this navigation system */ + + uint8_t *p_navsys = p + idx, idx_navsys = 0; + uint8_t nSats = 0, satCnt = 0, sigExcluded; + uint16_t bdsLongRange = 0; + uint8_t gloFncs[8] = {0, 0, 0, 0, 0, 0, 0, 0}; + uint64_t satMask = 0; + int sigTable[MEAS3_SYS_MAX][MEAS3_SIG_MAX]; + + // read satellite data + if (U1(p + idx) == 0) p_navsys = sbf->meas3_refEpoch.constellationHeader[navsys]; + + uint8_t BF1 = U1(p_navsys + idx_navsys); + uint8_t nB = BF1 & 0x7; + uint8_t signalIndexMasterShort = (BF1 >> 3) & 0xf; + uint8_t signalExcludedPresent = (BF1 >> 7) != 0; + idx_navsys++; + if (nB == 7) nB = 8; + + // read satellite mask + for (int i = 0; i < nB; i++) { + satMask |= (uint64_t)U1(p_navsys + idx_navsys + i) << (i * 8); + nSats += bitcnt(U1(p_navsys + idx_navsys + i)); + } + idx_navsys += nB; + + // Read GLONASS fcn list + if (navsys == 1) { // GLONASS + memcpy(gloFncs, p_navsys + idx_navsys, (nSats + 1) / 2); + idx_navsys += (nSats + 1) / 2; + } else if (navsys == 3) { // BDS + bdsLongRange = U2(p_navsys + idx_navsys); + idx_navsys += 2; + } + + if (signalExcludedPresent) { + sigExcluded = U1(p_navsys + idx_navsys); + idx_navsys++; + } else { + sigExcluded = 0; + } + + if ((TOW % refEpochInterval) == 0) { // reference epoche + if (idx_navsys > 23) trace(2, "sbf meas3ranges idx_navsys too large\n"); + memcpy(sbf->meas3_refEpoch.constellationHeader[navsys], p + idx, idx_navsys); + } + + if (U1(p + idx) == 0) // if data were from the reference block + idx += 1; + else + idx += idx_navsys; + + // prepare signal table + uint8_t j = 0; + for (uint8_t i = 0; i < MEAS3_SIG_MAX; i++) + /* signals that correspond to the zero bits must be included */ + if (((uint32_t)sigExcluded & (1 << i)) == 0) { + sigTable[navsys][j] = Meas3SigIdx2SignalType_Default[navsys][i]; + j++; + } + /* remaining signals do not exist */ + for (; j < MEAS3_SIG_MAX; j++) sigTable[navsys][j] = CODE_NONE; + + for (int svid = 0; svid < MEAS3_SAT_MAX && satCnt < nSats; svid++) { + if ((satMask & (1ULL << svid)) == 0) continue; + + int8_t glofnc = 0; + if (navsys == 1) { // GLONASS + glofnc = (int)((gloFncs[satCnt / 2] >> (4 * (satCnt % 2))) & 0xf) - 8; + } + int satNo; + int masterFreqIndex; + uint8_t codeMaster; + double freqMaster = 0; + uint32_t slaveSignalMask = 0, masterSignalIndex; + int16_t prRate; + + satNo = satno(Meas3_NavSys[navsys], Meas3_SVIDBase[navsys] + svid); + + // decode master measurement + double prbase = (bdsLongRange & (1 << satCnt)) != 0 ? 34e6 : PRBase[navsys]; + int blockTypeMaster = U1(p + idx); + init_obsd(raw->time, satNo, raw->obuf.data + n); + + if ((blockTypeMaster & 1) == 1) { + // Master short + uint32_t BF1 = U4(p + idx); + uint32_t pr_lsb = U4(p + idx + 4); + + uint32_t cmc = (BF1 >> 1) & 0x3ffff; + uint32_t prMsb = (BF1 >> 19) & 1; + uint32_t lti3 = (BF1 >> 20) & 0x7; + uint32_t CN0 = (BF1 >> 23) & 0x1f; + uint32_t signalList = (BF1 >> 28) & 0xf; + uint32_t lockTime = Meas3_LTItoPLLTime[lti3]; + + masterSignalIndex = signalIndexMasterShort; + slaveSignalMask = signalList << (masterSignalIndex + 1); + + if ((masterFreqIndex = + meas3_sig2idx(navsys, masterSignalIndex, raw->opt, &codeMaster, sigTable)) >= 0 && + satNo > 0) { + freqMaster = code2freq(Meas3_NavSys[navsys], codeMaster, glofnc); + double pr = prbase + ((double)pr_lsb + 4294967296.0 * (double)prMsb) * .001; + raw->obuf.data[n].P[masterFreqIndex] = pr; + raw->obuf.data[n].SNR[masterFreqIndex] = CN0 + 24.0; + raw->obuf.data[n].code[masterFreqIndex] = codeMaster; + if (cmc != 0) + raw->obuf.data[n].L[masterFreqIndex] = + pr / (CLIGHT / freqMaster) - 131.072 + (double)cmc * .001; + + raw->obuf.data[n].LLI[masterFreqIndex] = + (lockTime < raw->lockt[satNo - 1][masterFreqIndex] ? LLI_SLIP : 0) | + (lti3 == 0 ? LLI_HALFC : 0); + raw->lockt[satNo - 1][masterFreqIndex] = lockTime; + raw->obuf.data[n].freq = glofnc + 7; + sbf->meas3_freqAssignment[navsys][svid][0] = masterFreqIndex; + }; + + if (prrAvailable) + prRate = I2(p + idx + 8); + else + prRate = 0; + + idx += prrAvailable ? 10 : 8; + } else if ((blockTypeMaster & 3) == 0) { + // Master long + uint32_t BF1 = U4(p + idx); + uint32_t prLsb = U4(p + idx + 4); + uint16_t BF2 = U2(p + idx + 8); + uint8_t BF3 = U1(p + idx + 10); + + uint32_t prMsb = (BF1 >> 2) & 0xf; + uint32_t cmc = (BF1 >> 6) & 0x3fffff; + uint32_t lti4 = (BF1 >> 28) & 0xf; + uint32_t CN0 = (BF2 >> 0) & 0x3f; + uint32_t signalMask = (BF2 >> 6) & 0x1ff; + uint32_t cont = (BF2 >> 15) & 0x1; + uint32_t lockTime = Meas3_LTItoPLLTime[lti4]; + + if (cont != 0) signalMask |= (uint32_t)(BF3 & 0x7f) << 9; + + /* masterSignalIdx is the index of the right-most bit set to 1 */ + for (masterSignalIndex = 0; masterSignalIndex < 32; masterSignalIndex++) + if (((signalMask >> masterSignalIndex) & 1) != 0) break; + slaveSignalMask = signalMask ^ 1UL << (masterSignalIndex); + + if ((masterFreqIndex = + meas3_sig2idx(navsys, masterSignalIndex, raw->opt, &codeMaster, sigTable)) >= 0 && + satNo > 0) { + freqMaster = code2freq(Meas3_NavSys[navsys], codeMaster, glofnc); + uint8_t isGPSPCode = (navsys == 0) && (codeMaster == CODE_L1W || codeMaster == CODE_L2W); + + raw->obuf.data[n].P[masterFreqIndex] = + ((double)prLsb + 4294967296.0 * (double)prMsb) * .001; + raw->obuf.data[n].SNR[masterFreqIndex] = isGPSPCode ? CN0 : CN0 + 10.0; + raw->obuf.data[n].code[masterFreqIndex] = codeMaster; + if (cmc != 0) + raw->obuf.data[n].L[masterFreqIndex] = + raw->obuf.data[n].P[masterFreqIndex] / (CLIGHT / freqMaster) - 2097.152 + + (double)cmc * .001; + + raw->obuf.data[n].LLI[masterFreqIndex] = + (lockTime < raw->lockt[satNo - 1][masterFreqIndex] ? LLI_SLIP : 0) | + (lti4 == 0 ? LLI_HALFC : 0); + raw->lockt[satNo - 1][masterFreqIndex] = lockTime; + raw->obuf.data[n].freq = glofnc + 7; + sbf->meas3_freqAssignment[navsys][svid][0] = masterFreqIndex; + }; + + if (prrAvailable) + prRate = I2(p + idx + 10); + else + prRate = 0; + + idx += prrAvailable ? 12 + cont : 10 + cont; + } else if ((blockTypeMaster & 0xc) == 0xc) { + // Master long delta + masterSignalIndex = sbf->meas3_refEpoch.signalIdx[navsys][svid][0]; + slaveSignalMask = sbf->meas3_refEpoch.slaveSignalMask[navsys][svid]; + if ((masterFreqIndex = + meas3_sig2idx(navsys, masterSignalIndex, raw->opt, &codeMaster, sigTable)) >= 0 && + satNo > 0) { + uint8_t BF1 = U1(p + idx); + uint32_t BF2 = U4(p + idx + 1); + + uint32_t pr = (((uint32_t)(BF1 >> 4) << 13) | (BF2 & 0x1fff)); + uint32_t CN0 = (BF2 >> 13) & 0x7; + uint32_t cmc = BF2 >> 16; + + obsd_t *master_reference = &(sbf->meas3_refEpoch.obsData[navsys][svid]); + freqMaster = code2freq(Meas3_NavSys[navsys], codeMaster, glofnc); + + raw->obuf.data[n].P[masterFreqIndex] = + master_reference->P[masterFreqIndex] + + ((int64_t)sbf->meas3_refEpoch.prRate[navsys][svid] * 64 * + (int32_t)(TOW % refEpochInterval) / 1000) * + .001 + + (double)pr * .001 - 65.536; + raw->obuf.data[n].SNR[masterFreqIndex] = + master_reference->SNR[masterFreqIndex] - 4.0 + CN0; + raw->obuf.data[n].code[masterFreqIndex] = codeMaster; + if (cmc != 0) + raw->obuf.data[n].L[masterFreqIndex] = + (raw->obuf.data[n].P[masterFreqIndex] - master_reference->P[masterFreqIndex]) / + (CLIGHT / freqMaster) + + master_reference->L[masterFreqIndex] - 32.768 + (double)cmc * .001; + + raw->obuf.data[n].LLI[masterFreqIndex] = master_reference->LLI[masterFreqIndex]; + raw->lockt[satNo - 1][masterFreqIndex] = + sbf->meas3_refEpoch.lockt[navsys][svid][masterFreqIndex]; + raw->obuf.data[n].freq = glofnc + 7; + sbf->meas3_freqAssignment[navsys][svid][0] = masterFreqIndex; + } + + prRate = 0; + + idx += 5; + } else { + // Master short delta + uint32_t BF1 = U4(p + idx); + + uint32_t pr = (BF1 >> 4) & 0x3fff; + uint32_t cmc = (BF1 >> 18) & 0x3fff; + uint32_t CN0 = (BF1 >> 2) & 0x3; + + masterSignalIndex = sbf->meas3_refEpoch.signalIdx[navsys][svid][0]; + if ((masterFreqIndex = + meas3_sig2idx(navsys, masterSignalIndex, raw->opt, &codeMaster, sigTable)) >= 0 && + satNo > 0) { + obsd_t *masterReference = &(sbf->meas3_refEpoch.obsData[navsys][svid]); + freqMaster = code2freq(Meas3_NavSys[navsys], codeMaster, glofnc); + + raw->obuf.data[n].P[masterFreqIndex] = + masterReference->P[masterFreqIndex] + + ((int64_t)sbf->meas3_refEpoch.prRate[navsys][svid] * 64 * + (int32_t)(TOW % refEpochInterval) / 1000) * + .001 + + (double)pr * .001 - 8.192; + if (cmc != 0) + raw->obuf.data[n].L[masterFreqIndex] = + (raw->obuf.data[n].P[masterFreqIndex] - masterReference->P[masterFreqIndex]) / + (CLIGHT / freqMaster) + + masterReference->L[masterFreqIndex] - 8.192 + (double)cmc * .001; + raw->obuf.data[n].SNR[masterFreqIndex] = + masterReference->SNR[masterFreqIndex] - 1.0 + CN0; + raw->obuf.data[n].LLI[masterFreqIndex] = masterReference->LLI[masterFreqIndex]; + raw->lockt[satNo - 1][masterFreqIndex] = + sbf->meas3_refEpoch.lockt[navsys][svid][masterFreqIndex]; + raw->obuf.data[n].code[masterFreqIndex] = codeMaster; + raw->obuf.data[n].freq = glofnc + 8; + sbf->meas3_freqAssignment[navsys][svid][0] = masterFreqIndex; + } - if (signalExcludedPresent) { - sigExcluded = U1(p_navsys+idx_navsys); - idx_navsys++; - } else { - sigExcluded = 0; + prRate = 0; + slaveSignalMask = sbf->meas3_refEpoch.slaveSignalMask[navsys][svid]; + + idx += 4; + } + + /* keep reference measurement to decode the delta measurements */ + if (TOW % refEpochInterval == 0 && satNo > 0) { + if ((masterFreqIndex > NFREQ + NEXOBS) || (masterFreqIndex < 0)) + trace(2, "sbf meas3ranges index out of bounds: %d\n", masterFreqIndex); + + sbf->meas3_refEpoch.signalIdx[navsys][svid][0] = (uint8_t)masterSignalIndex; + sbf->meas3_refEpoch.slaveSignalMask[navsys][svid] = slaveSignalMask; + sbf->meas3_refEpoch.prRate[navsys][svid] = prRate; + sbf->meas3_refEpoch.obsData[navsys][svid].P[masterFreqIndex] = + raw->obuf.data[n].P[masterFreqIndex]; + sbf->meas3_refEpoch.obsData[navsys][svid].L[masterFreqIndex] = + raw->obuf.data[n].L[masterFreqIndex]; + sbf->meas3_refEpoch.obsData[navsys][svid].SNR[masterFreqIndex] = + raw->obuf.data[n].SNR[masterFreqIndex]; + sbf->meas3_refEpoch.obsData[navsys][svid].LLI[masterFreqIndex] = + raw->obuf.data[n].LLI[masterFreqIndex]; + sbf->meas3_refEpoch.lockt[navsys][svid][masterFreqIndex] = + raw->lockt[satNo - 1][masterFreqIndex]; + } + + // update PLL lock time + if (satNo > 0 && raw->lockt[satNo - 1][masterFreqIndex] > + sbf->meas3_refEpoch.lockt[navsys][svid][masterFreqIndex]) + sbf->meas3_refEpoch.lockt[navsys][svid][masterFreqIndex] = + raw->lockt[satNo - 1][masterFreqIndex]; + + /* decode slave data */ + int slaveCnt = 0; + for (int slaveSignalIndex = 1; slaveSignalIndex < MEAS3_SIG_MAX && slaveSignalMask != 0; + slaveSignalIndex++) { + if ((slaveSignalMask & (1 << slaveSignalIndex)) != 0) { + int slaveFreqIndex; + double freqSlave; + uint8_t codeSlave; + int blockTypeSlave = U1(p + idx); + + if ((blockTypeSlave & 1) == 1) { + /* Slave Short */ + uint32_t BF1 = U4(p + idx); + uint8_t BF2 = U1(p + idx + 4); + + uint32_t cmcRes = (BF1 >> 1) & 0xffff; + uint32_t prRel = BF1 >> 17; + uint32_t lti3 = BF2 & 0x7; + uint32_t CN0 = BF2 >> 3; + uint32_t lockTime = Meas3_LTItoPLLTime[lti3]; + + if ((slaveFreqIndex = meas3_sig2idx(navsys, slaveSignalIndex, raw->opt, &codeSlave, + sigTable)) >= 0 && + satNo > 0) { + freqSlave = code2freq(Meas3_NavSys[navsys], codeSlave, glofnc); + + if (freqMaster > freqSlave) + raw->obuf.data[n].P[slaveFreqIndex] = + raw->obuf.data[n].P[masterFreqIndex] + prRel * .001 - 10; + else + raw->obuf.data[n].P[slaveFreqIndex] = + raw->obuf.data[n].P[masterFreqIndex] - prRel * .001 + 10; + + if (cmcRes != 0) + raw->obuf.data[n].L[slaveFreqIndex] = + raw->obuf.data[n].P[slaveFreqIndex] / (CLIGHT / freqSlave) + + (raw->obuf.data[n].L[masterFreqIndex] - + raw->obuf.data[n].P[masterFreqIndex] / (CLIGHT / freqMaster)) * + (freqMaster / freqSlave) - + 32.768 + cmcRes * .001; + + if ((navsys == 0) && (codeSlave == CODE_L1W || codeSlave == CODE_L2W)) + raw->obuf.data[n].SNR[slaveFreqIndex] = + raw->obuf.data[n].SNR[masterFreqIndex] - 3.0 - CN0; + else + raw->obuf.data[n].SNR[slaveFreqIndex] = CN0 + 24.0; + + raw->obuf.data[n].code[slaveFreqIndex] = codeSlave; + raw->obuf.data[n].LLI[slaveFreqIndex] = + (lockTime < raw->lockt[satNo - 1][slaveFreqIndex] ? LLI_SLIP : 0) | + (lti3 == 0 ? LLI_HALFC : 0); + raw->lockt[satNo - 1][slaveFreqIndex] = lockTime; + sbf->meas3_freqAssignment[navsys][svid][slaveCnt + 1] = slaveFreqIndex; } - if ((TOW % refEpochInterval) == 0) { // reference epoche - if (idx_navsys > 23) - trace(2, "sbf meas3ranges idx_navsys too large\n"); - memcpy(sbf->meas3_refEpoch.constellationHeader[navsys], p+idx, idx_navsys); + idx += 5; + } else if ((blockTypeSlave & 3) == 0) { + /* Slave Long */ + uint32_t BF1 = U4(p + idx); + uint16_t prLsbRel = U2(p + idx + 4); + uint8_t BF3 = U1(p + idx + 6); + + uint32_t cmc = (BF1 >> 2) & 0x3fffff; + uint32_t lti4 = (BF1 >> 24) & 0xf; + uint32_t prMsbRel = (BF1 >> 28) & 0x7; + uint32_t CN0 = BF3 & 0x3f; + uint32_t lockTime = Meas3_LTItoPLLTime[lti4]; + + if ((slaveFreqIndex = meas3_sig2idx(navsys, slaveSignalIndex, raw->opt, &codeSlave, + sigTable)) >= 0 && + satNo > 0) { + freqSlave = code2freq(Meas3_NavSys[navsys], codeSlave, glofnc); + raw->obuf.data[n].P[slaveFreqIndex] = raw->obuf.data[n].P[masterFreqIndex] + + (prMsbRel * 65536 + prLsbRel) * .001 - 262.144; + + if (cmc != 0) + raw->obuf.data[n].L[slaveFreqIndex] = + raw->obuf.data[n].P[slaveFreqIndex] / (CLIGHT / freqSlave) - 2097.152 + + cmc * 0.001; + + if ((navsys == 0) && (codeSlave == CODE_L1W || codeSlave == CODE_L2W)) + raw->obuf.data[n].SNR[slaveFreqIndex] = CN0; + else + raw->obuf.data[n].SNR[slaveFreqIndex] = CN0 + 10.0; + + raw->obuf.data[n].code[slaveFreqIndex] = codeSlave; + raw->obuf.data[n].LLI[slaveFreqIndex] = + (lockTime < raw->lockt[satNo - 1][slaveFreqIndex] ? LLI_SLIP : 0) | + (lti4 == 0 ? LLI_HALFC : 0); + raw->lockt[satNo - 1][slaveFreqIndex] = lockTime; + sbf->meas3_freqAssignment[navsys][svid][slaveCnt + 1] = slaveFreqIndex; } - if (U1(p+idx) == 0) // if data were from the reference block - idx += 1; - else - idx += idx_navsys; - - // prepare signal table - uint8_t j = 0; - for (uint8_t i = 0; i < MEAS3_SIG_MAX; i++) - /* signals that correspond to the zero bits must be included */ - if (((uint32_t)sigExcluded & (1 << i)) == 0) { - sigTable[navsys][j] = Meas3SigIdx2SignalType_Default[navsys][i]; - j++; - } - /* remaining signals do not exist */ - for (;j < MEAS3_SIG_MAX; j++) - sigTable[navsys][j] = CODE_NONE; - - for (int svid = 0; svid < MEAS3_SAT_MAX && satCnt < nSats; svid++) - { - if ((satMask & (1ULL << svid)) == 0) - continue; - - int8_t glofnc = 0; - if (navsys == 1) { // GLONASS - glofnc = (int)((gloFncs[satCnt / 2] >> (4 * (satCnt % 2))) & 0xf) - 8; - } - int satNo; - int masterFreqIndex; - uint8_t codeMaster; - double freqMaster = 0; - uint32_t slaveSignalMask = 0, masterSignalIndex; - int16_t prRate; - - satNo = satno(Meas3_NavSys[navsys], Meas3_SVIDBase[navsys]+svid); - - // decode master measurement - double prbase = (bdsLongRange & (1 << satCnt)) != 0 ? 34e6 : PRBase[navsys]; - int blockTypeMaster = U1(p+idx); - init_obsd(raw->time, satNo, raw->obuf.data+n); - - if ((blockTypeMaster & 1) == 1) { - // Master short - uint32_t BF1 = U4(p+idx); - uint32_t pr_lsb = U4(p+idx+4); - - uint32_t cmc = (BF1 >> 1) & 0x3ffff; - uint32_t prMsb = (BF1 >> 19) & 1; - uint32_t lti3 = (BF1 >> 20) & 0x7; - uint32_t CN0 = (BF1 >> 23) & 0x1f; - uint32_t signalList = (BF1 >> 28) & 0xf; - uint32_t lockTime = Meas3_LTItoPLLTime[lti3]; - - masterSignalIndex = signalIndexMasterShort; - slaveSignalMask = signalList << (masterSignalIndex + 1); - - if ((masterFreqIndex = meas3_sig2idx(navsys, masterSignalIndex, raw->opt, &codeMaster, sigTable)) >= 0 && satNo > 0) { - freqMaster = code2freq(Meas3_NavSys[navsys], codeMaster, glofnc); - double pr = prbase + ((double)pr_lsb + 4294967296.0 * (double)prMsb) * .001; - raw->obuf.data[n].P[masterFreqIndex] = pr; - raw->obuf.data[n].SNR[masterFreqIndex] = CN0 + 24.0; - raw->obuf.data[n].code[masterFreqIndex] = codeMaster; - if (cmc != 0) - raw->obuf.data[n].L[masterFreqIndex] = pr / (CLIGHT/freqMaster) - 131.072 + (double)cmc * .001; - - raw->obuf.data[n].LLI[masterFreqIndex] = (lockTime < raw->lockt[satNo-1][masterFreqIndex] ? LLI_SLIP : 0) | (lti3 == 0 ? LLI_HALFC : 0); - raw->lockt[satNo-1][masterFreqIndex] = lockTime; - raw->obuf.data[n].freq = glofnc+7; - sbf->meas3_freqAssignment[navsys][svid][0] = masterFreqIndex; - }; - - if (prrAvailable) - prRate = I2(p+idx+8); - else - prRate = 0; - - idx += prrAvailable ? 10 : 8; - } else if ((blockTypeMaster & 3) == 0) { - // Master long - uint32_t BF1 = U4(p+idx); - uint32_t prLsb = U4(p+idx+4); - uint16_t BF2 = U2(p+idx+8); - uint8_t BF3 = U1(p+idx+10); - - uint32_t prMsb = (BF1 >> 2) & 0xf; - uint32_t cmc = (BF1 >> 6) & 0x3fffff; - uint32_t lti4 = (BF1 >> 28) & 0xf; - uint32_t CN0 = (BF2 >> 0) & 0x3f; - uint32_t signalMask = (BF2 >> 6) & 0x1ff; - uint32_t cont = (BF2 >> 15) & 0x1; - uint32_t lockTime = Meas3_LTItoPLLTime[lti4]; - - if (cont != 0) - signalMask |= (uint32_t)(BF3 & 0x7f) << 9; - - /* masterSignalIdx is the index of the right-most bit set to 1 */ - for (masterSignalIndex = 0; masterSignalIndex < 32; masterSignalIndex++) - if (((signalMask >> masterSignalIndex) & 1) != 0) - break; - slaveSignalMask = signalMask ^ 1UL << (masterSignalIndex); - - if ((masterFreqIndex = meas3_sig2idx(navsys, masterSignalIndex, raw->opt, &codeMaster, sigTable)) >= 0 && satNo > 0) { - freqMaster = code2freq(Meas3_NavSys[navsys], codeMaster, glofnc); - uint8_t isGPSPCode = (navsys == 0) && (codeMaster == CODE_L1W || codeMaster == CODE_L2W); - - raw->obuf.data[n].P[masterFreqIndex] = ((double)prLsb + 4294967296.0 * (double)prMsb) * .001; - raw->obuf.data[n].SNR[masterFreqIndex] = isGPSPCode ? CN0 : CN0 + 10.0; - raw->obuf.data[n].code[masterFreqIndex] = codeMaster; - if (cmc != 0) - raw->obuf.data[n].L[masterFreqIndex] = raw->obuf.data[n].P[masterFreqIndex] / (CLIGHT/freqMaster) - 2097.152 + (double)cmc * .001; - - raw->obuf.data[n].LLI[masterFreqIndex] = (lockTime < raw->lockt[satNo-1][masterFreqIndex] ? LLI_SLIP : 0) | (lti4 == 0 ? LLI_HALFC : 0); - raw->lockt[satNo-1][masterFreqIndex] = lockTime; - raw->obuf.data[n].freq = glofnc+7; - sbf->meas3_freqAssignment[navsys][svid][0] = masterFreqIndex; - }; - - if (prrAvailable) - prRate = I2(p+idx+10); - else - prRate = 0; - - idx += prrAvailable ? 12 + cont : 10 + cont; - } else if ((blockTypeMaster & 0xc) == 0xc) { - // Master long delta - masterSignalIndex = sbf->meas3_refEpoch.signalIdx[navsys][svid][0]; - slaveSignalMask = sbf->meas3_refEpoch.slaveSignalMask[navsys][svid]; - if ((masterFreqIndex = meas3_sig2idx(navsys, masterSignalIndex, raw->opt, &codeMaster, sigTable)) >= 0 && satNo > 0) { - uint8_t BF1 = U1(p+idx); - uint32_t BF2 = U4(p+idx+1); - - uint32_t pr = (((uint32_t)(BF1 >> 4) << 13) | (BF2 & 0x1fff)); - uint32_t CN0 = (BF2 >> 13) & 0x7; - uint32_t cmc = BF2 >> 16; - - obsd_t * master_reference = &(sbf->meas3_refEpoch.obsData[navsys][svid]); - freqMaster = code2freq(Meas3_NavSys[navsys], codeMaster, glofnc); - - raw->obuf.data[n].P[masterFreqIndex] = master_reference->P[masterFreqIndex] + - ((int64_t)sbf->meas3_refEpoch.prRate[navsys][svid] * 64 * (int32_t)(TOW % refEpochInterval) / 1000) * .001 + - (double)pr * .001 - 65.536; - raw->obuf.data[n].SNR[masterFreqIndex] = master_reference->SNR[masterFreqIndex] - 4.0 + CN0; - raw->obuf.data[n].code[masterFreqIndex] = codeMaster; - if (cmc != 0) - raw->obuf.data[n].L[masterFreqIndex] = (raw->obuf.data[n].P[masterFreqIndex] - master_reference->P[masterFreqIndex]) / (CLIGHT/freqMaster) + - master_reference->L[masterFreqIndex] - 32.768 + (double)cmc * .001; - - raw->obuf.data[n].LLI[masterFreqIndex] = master_reference->LLI[masterFreqIndex]; - raw->lockt[satNo-1][masterFreqIndex] = sbf->meas3_refEpoch.lockt[navsys][svid][masterFreqIndex]; - raw->obuf.data[n].freq = glofnc+7; - sbf->meas3_freqAssignment[navsys][svid][0] = masterFreqIndex; - } - - prRate = 0; - - idx += 5; - } else { - // Master short delta - uint32_t BF1 = U4(p+idx); - - uint32_t pr = (BF1 >> 4) & 0x3fff; - uint32_t cmc = (BF1 >> 18) & 0x3fff; - uint32_t CN0 = (BF1 >> 2) & 0x3; - - masterSignalIndex = sbf->meas3_refEpoch.signalIdx[navsys][svid][0]; - if ((masterFreqIndex = meas3_sig2idx(navsys, masterSignalIndex, raw->opt, &codeMaster, sigTable)) >= 0 && satNo > 0) { - obsd_t * masterReference = &(sbf->meas3_refEpoch.obsData[navsys][svid]); - freqMaster = code2freq(Meas3_NavSys[navsys], codeMaster, glofnc); - - raw->obuf.data[n].P[masterFreqIndex] = masterReference->P[masterFreqIndex] + ((int64_t)sbf->meas3_refEpoch.prRate[navsys][svid] * 64 * (int32_t)(TOW % refEpochInterval) / 1000) * .001 + (double)pr * .001 - 8.192; - if (cmc != 0) - raw->obuf.data[n].L[masterFreqIndex] = (raw->obuf.data[n].P[masterFreqIndex] - masterReference->P[masterFreqIndex]) / (CLIGHT/freqMaster) + masterReference->L[masterFreqIndex] - 8.192 + (double)cmc * .001; - raw->obuf.data[n].SNR[masterFreqIndex] = masterReference->SNR[masterFreqIndex] - 1.0 + CN0; - raw->obuf.data[n].LLI[masterFreqIndex] = masterReference->LLI[masterFreqIndex]; - raw->lockt[satNo-1][masterFreqIndex] = sbf->meas3_refEpoch.lockt[navsys][svid][masterFreqIndex]; - raw->obuf.data[n].code[masterFreqIndex] = codeMaster; - raw->obuf.data[n].freq = glofnc+8; - sbf->meas3_freqAssignment[navsys][svid][0] = masterFreqIndex; - } - - prRate = 0; - slaveSignalMask = sbf->meas3_refEpoch.slaveSignalMask[navsys][svid]; - - idx += 4; - } - - /* keep reference measurement to decode the delta measurements */ - if (TOW % refEpochInterval == 0 && satNo > 0) - { - if ((masterFreqIndex > NFREQ+NEXOBS) || (masterFreqIndex < 0)) - trace(2, "sbf meas3ranges index out of bounds: %d\n", masterFreqIndex); - - sbf->meas3_refEpoch.signalIdx[navsys][svid][0] = (uint8_t)masterSignalIndex; - sbf->meas3_refEpoch.slaveSignalMask[navsys][svid] = slaveSignalMask; - sbf->meas3_refEpoch.prRate[navsys][svid] = prRate; - sbf->meas3_refEpoch.obsData[navsys][svid].P[masterFreqIndex] = raw->obuf.data[n].P[masterFreqIndex]; - sbf->meas3_refEpoch.obsData[navsys][svid].L[masterFreqIndex] = raw->obuf.data[n].L[masterFreqIndex]; - sbf->meas3_refEpoch.obsData[navsys][svid].SNR[masterFreqIndex] = raw->obuf.data[n].SNR[masterFreqIndex]; - sbf->meas3_refEpoch.obsData[navsys][svid].LLI[masterFreqIndex] = raw->obuf.data[n].LLI[masterFreqIndex]; - sbf->meas3_refEpoch.lockt[navsys][svid][masterFreqIndex] = raw->lockt[satNo-1][masterFreqIndex]; - } - - // update PLL lock time - if (satNo > 0 && raw->lockt[satNo-1][masterFreqIndex] > sbf->meas3_refEpoch.lockt[navsys][svid][masterFreqIndex]) - sbf->meas3_refEpoch.lockt[navsys][svid][masterFreqIndex] = raw->lockt[satNo-1][masterFreqIndex]; - - /* decode slave data */ - int slaveCnt = 0; - for (int slaveSignalIndex = 1; slaveSignalIndex < MEAS3_SIG_MAX && slaveSignalMask != 0; slaveSignalIndex++) - { - if ((slaveSignalMask & (1 << slaveSignalIndex)) != 0) - { - int slaveFreqIndex; - double freqSlave; - uint8_t codeSlave; - int blockTypeSlave = U1(p+idx); - - if ((blockTypeSlave & 1) == 1) { - /* Slave Short */ - uint32_t BF1 = U4(p+idx); - uint8_t BF2 = U1(p+idx+4); - - uint32_t cmcRes = (BF1 >> 1) & 0xffff; - uint32_t prRel = BF1 >> 17; - uint32_t lti3 = BF2 & 0x7; - uint32_t CN0 = BF2 >> 3; - uint32_t lockTime = Meas3_LTItoPLLTime[lti3]; - - if ((slaveFreqIndex = meas3_sig2idx(navsys, slaveSignalIndex, raw->opt, &codeSlave, sigTable)) >= 0 && satNo > 0) { - freqSlave = code2freq(Meas3_NavSys[navsys], codeSlave, glofnc); - - if (freqMaster > freqSlave) - raw->obuf.data[n].P[slaveFreqIndex] = raw->obuf.data[n].P[masterFreqIndex] + prRel * .001 - 10; - else - raw->obuf.data[n].P[slaveFreqIndex] = raw->obuf.data[n].P[masterFreqIndex] - prRel * .001 + 10; - - if (cmcRes != 0) - raw->obuf.data[n].L[slaveFreqIndex] = - raw->obuf.data[n].P[slaveFreqIndex] / (CLIGHT/freqSlave) + - (raw->obuf.data[n].L[masterFreqIndex] - raw->obuf.data[n].P[masterFreqIndex] / (CLIGHT/freqMaster)) * (freqMaster / freqSlave) - - 32.768 + cmcRes * .001; - - if ((navsys == 0) && (codeSlave == CODE_L1W || codeSlave == CODE_L2W)) - raw->obuf.data[n].SNR[slaveFreqIndex] = raw->obuf.data[n].SNR[masterFreqIndex] - 3.0 - CN0; - else - raw->obuf.data[n].SNR[slaveFreqIndex] = CN0 + 24.0; - - raw->obuf.data[n].code[slaveFreqIndex] = codeSlave; - raw->obuf.data[n].LLI[slaveFreqIndex] = (lockTime < raw->lockt[satNo-1][slaveFreqIndex] ? LLI_SLIP : 0) | (lti3 == 0 ? LLI_HALFC : 0); - raw->lockt[satNo-1][slaveFreqIndex] = lockTime; - sbf->meas3_freqAssignment[navsys][svid][slaveCnt+1] = slaveFreqIndex; - } - - idx += 5; - } else if ((blockTypeSlave & 3) == 0) { - /* Slave Long */ - uint32_t BF1 = U4(p+idx); - uint16_t prLsbRel = U2(p+idx + 4); - uint8_t BF3 = U1(p+idx + 6); - - uint32_t cmc = (BF1 >> 2) & 0x3fffff; - uint32_t lti4 = (BF1 >> 24) & 0xf; - uint32_t prMsbRel = (BF1 >> 28) & 0x7; - uint32_t CN0 = BF3 & 0x3f; - uint32_t lockTime = Meas3_LTItoPLLTime[lti4]; - - if ((slaveFreqIndex = meas3_sig2idx(navsys, slaveSignalIndex, raw->opt, &codeSlave, sigTable)) >= 0 && satNo > 0) { - freqSlave = code2freq(Meas3_NavSys[navsys], codeSlave, glofnc); - raw->obuf.data[n].P[slaveFreqIndex] = raw->obuf.data[n].P[masterFreqIndex] + (prMsbRel * 65536 + prLsbRel) * .001 - 262.144; - - if (cmc != 0) - raw->obuf.data[n].L[slaveFreqIndex] = raw->obuf.data[n].P[slaveFreqIndex] / (CLIGHT/freqSlave) - 2097.152 + cmc * 0.001; - - if ((navsys == 0) && (codeSlave == CODE_L1W || codeSlave == CODE_L2W)) - raw->obuf.data[n].SNR[slaveFreqIndex] = CN0; - else - raw->obuf.data[n].SNR[slaveFreqIndex] = CN0 + 10.0; - - raw->obuf.data[n].code[slaveFreqIndex] = codeSlave; - raw->obuf.data[n].LLI[slaveFreqIndex] = (lockTime < raw->lockt[satNo-1][slaveFreqIndex] ? LLI_SLIP : 0) | (lti4 == 0 ? LLI_HALFC : 0); - raw->lockt[satNo-1][slaveFreqIndex] = lockTime; - sbf->meas3_freqAssignment[navsys][svid][slaveCnt+1] = slaveFreqIndex; - } - - idx += 7; - } else { - /* Slave Delta */ - uint16_t BF1 = U2(p+idx); - uint8_t dC = U1(p+idx + 2); - - uint32_t dPr = (BF1 >> 2) & 0xfff; - uint32_t CN0 = BF1 >> 14; - - if ((slaveFreqIndex = meas3_sig2idx(navsys, slaveSignalIndex, raw->opt, &codeSlave, sigTable)) >= 0 && satNo > 0) { - freqSlave = code2freq(Meas3_NavSys[navsys], codeSlave, glofnc); - - obsd_t * masterReference = &(sbf->meas3_refEpoch.obsData[navsys][svid]); - obsd_t * slaveReference = &(sbf->meas3_refEpoch.obsData[navsys][svid]); - int masterRefFreqIdx = meas3_sig2idx(navsys, sbf->meas3_refEpoch.signalIdx[navsys][svid][0], raw->opt, &codeSlave, sigTable); - int slaveRefFreqIdx = meas3_sig2idx(navsys, sbf->meas3_refEpoch.signalIdx[navsys][svid][slaveCnt+1], raw->opt, &codeSlave, sigTable); - - raw->obuf.data[n].L[slaveFreqIndex] = (slaveReference->L[slaveRefFreqIdx] - + (raw->obuf.data[n].L[masterFreqIndex] - masterReference->L[masterRefFreqIdx]) * freqSlave / freqMaster - 0.128 + dC * 0.001); - - raw->obuf.data[n].P[slaveFreqIndex] = (slaveReference->P[slaveRefFreqIdx] + - (raw->obuf.data[n].L[slaveFreqIndex] - slaveReference->L[slaveRefFreqIdx]) * (CLIGHT/freqSlave) - - 2.048 + dPr * 0.001); - - raw->obuf.data[n].SNR[slaveFreqIndex] = slaveReference->SNR[slaveRefFreqIdx] - 2.0 + CN0; - - raw->obuf.data[n].code[slaveFreqIndex] = codeSlave; - raw->obuf.data[n].LLI[slaveFreqIndex] = slaveReference->LLI[slaveRefFreqIdx]; - raw->lockt[satNo-1][slaveFreqIndex] = sbf->meas3_refEpoch.lockt[navsys][svid][slaveCnt+1]; - sbf->meas3_freqAssignment[navsys][svid][slaveCnt+1] = slaveFreqIndex; - } - - idx += 3; - }; - - /* keep reference measurement to decode delta measurements */ - if (TOW % refEpochInterval == 0 && satNo > 0) - { - if ((slaveFreqIndex > NFREQ+NEXOBS) || (slaveFreqIndex < 0)) - trace(2, "sbf meas3ranges index out of bounds: %d\n", slaveFreqIndex); - sbf->meas3_refEpoch.signalIdx[navsys][svid][slaveCnt + 1] = (uint8_t)slaveSignalIndex; - - sbf->meas3_refEpoch.obsData[navsys][svid].P[slaveFreqIndex] = raw->obuf.data[n].P[slaveFreqIndex]; //TODO: save all parameters - sbf->meas3_refEpoch.obsData[navsys][svid].L[slaveFreqIndex] = raw->obuf.data[n].L[slaveFreqIndex]; - sbf->meas3_refEpoch.obsData[navsys][svid].SNR[slaveFreqIndex] = raw->obuf.data[n].SNR[slaveFreqIndex]; - sbf->meas3_refEpoch.obsData[navsys][svid].LLI[slaveFreqIndex] = raw->obuf.data[n].LLI[slaveFreqIndex]; - sbf->meas3_refEpoch.lockt[navsys][svid][slaveFreqIndex] = raw->lockt[satNo-1][slaveFreqIndex]; - } - - if (raw->lockt[satNo-1][slaveFreqIndex] > sbf->meas3_refEpoch.lockt[navsys][svid][slaveFreqIndex]) - sbf->meas3_refEpoch.lockt[navsys][svid][slaveFreqIndex] = raw->lockt[satNo-1][slaveFreqIndex]; - - slaveCnt++; - /* delete this bit of the mask */ - slaveSignalMask ^= (1 << slaveSignalIndex); - } - } - n++; - satCnt++; + idx += 7; + } else { + /* Slave Delta */ + uint16_t BF1 = U2(p + idx); + uint8_t dC = U1(p + idx + 2); + + uint32_t dPr = (BF1 >> 2) & 0xfff; + uint32_t CN0 = BF1 >> 14; + + if ((slaveFreqIndex = meas3_sig2idx(navsys, slaveSignalIndex, raw->opt, &codeSlave, + sigTable)) >= 0 && + satNo > 0) { + freqSlave = code2freq(Meas3_NavSys[navsys], codeSlave, glofnc); + + obsd_t *masterReference = &(sbf->meas3_refEpoch.obsData[navsys][svid]); + obsd_t *slaveReference = &(sbf->meas3_refEpoch.obsData[navsys][svid]); + int masterRefFreqIdx = + meas3_sig2idx(navsys, sbf->meas3_refEpoch.signalIdx[navsys][svid][0], raw->opt, + &codeSlave, sigTable); + int slaveRefFreqIdx = + meas3_sig2idx(navsys, sbf->meas3_refEpoch.signalIdx[navsys][svid][slaveCnt + 1], + raw->opt, &codeSlave, sigTable); + + raw->obuf.data[n].L[slaveFreqIndex] = + (slaveReference->L[slaveRefFreqIdx] + + (raw->obuf.data[n].L[masterFreqIndex] - masterReference->L[masterRefFreqIdx]) * + freqSlave / freqMaster - + 0.128 + dC * 0.001); + + raw->obuf.data[n].P[slaveFreqIndex] = + (slaveReference->P[slaveRefFreqIdx] + + (raw->obuf.data[n].L[slaveFreqIndex] - slaveReference->L[slaveRefFreqIdx]) * + (CLIGHT / freqSlave) - + 2.048 + dPr * 0.001); + + raw->obuf.data[n].SNR[slaveFreqIndex] = + slaveReference->SNR[slaveRefFreqIdx] - 2.0 + CN0; + + raw->obuf.data[n].code[slaveFreqIndex] = codeSlave; + raw->obuf.data[n].LLI[slaveFreqIndex] = slaveReference->LLI[slaveRefFreqIdx]; + raw->lockt[satNo - 1][slaveFreqIndex] = + sbf->meas3_refEpoch.lockt[navsys][svid][slaveCnt + 1]; + sbf->meas3_freqAssignment[navsys][svid][slaveCnt + 1] = slaveFreqIndex; } + + idx += 3; + }; + + /* keep reference measurement to decode delta measurements */ + if (TOW % refEpochInterval == 0 && satNo > 0) { + if ((slaveFreqIndex > NFREQ + NEXOBS) || (slaveFreqIndex < 0)) + trace(2, "sbf meas3ranges index out of bounds: %d\n", slaveFreqIndex); + sbf->meas3_refEpoch.signalIdx[navsys][svid][slaveCnt + 1] = (uint8_t)slaveSignalIndex; + + sbf->meas3_refEpoch.obsData[navsys][svid].P[slaveFreqIndex] = + raw->obuf.data[n].P[slaveFreqIndex]; // TODO: save all parameters + sbf->meas3_refEpoch.obsData[navsys][svid].L[slaveFreqIndex] = + raw->obuf.data[n].L[slaveFreqIndex]; + sbf->meas3_refEpoch.obsData[navsys][svid].SNR[slaveFreqIndex] = + raw->obuf.data[n].SNR[slaveFreqIndex]; + sbf->meas3_refEpoch.obsData[navsys][svid].LLI[slaveFreqIndex] = + raw->obuf.data[n].LLI[slaveFreqIndex]; + sbf->meas3_refEpoch.lockt[navsys][svid][slaveFreqIndex] = + raw->lockt[satNo - 1][slaveFreqIndex]; + } + + if (raw->lockt[satNo - 1][slaveFreqIndex] > + sbf->meas3_refEpoch.lockt[navsys][svid][slaveFreqIndex]) + sbf->meas3_refEpoch.lockt[navsys][svid][slaveFreqIndex] = + raw->lockt[satNo - 1][slaveFreqIndex]; + + slaveCnt++; + /* delete this bit of the mask */ + slaveSignalMask ^= (1 << slaveSignalIndex); } + } + n++; + satCnt++; + } + } - raw->obuf.n = n; + raw->obuf.n = n; - return ret; + return ret; } -int32_t meas3_DopplerPrRate(raw_t* raw, uint32_t *offset) -{ - int32_t prRate; - - uint32_t value = U4(raw->buff + 16 + *offset); - - if ((value & 2) == 0) - { - /* 1 byte */ - prRate = (int32_t)((value & 0xff) >> 2); - *offset += 1; - } - else if ((value & 6) == 2) - { - /* 2 bytes */ - prRate = (int32_t)((value & 0xffff) >> 3); - *offset += 2; - } - else if ((value & 0xe) == 6) { - /* 3 bytes */ - prRate = (int32_t)((value & 0xffffff) >> 4); - *offset += 3; - } - else { - /* 4 bytes */ - prRate = (int32_t)(value >> 4); - *offset += 4; - } +int32_t meas3_DopplerPrRate(raw_t *raw, uint32_t *offset) { + int32_t prRate; + + uint32_t value = U4(raw->buff + 16 + *offset); + + if ((value & 2) == 0) { + /* 1 byte */ + prRate = (int32_t)((value & 0xff) >> 2); + *offset += 1; + } else if ((value & 6) == 2) { + /* 2 bytes */ + prRate = (int32_t)((value & 0xffff) >> 3); + *offset += 2; + } else if ((value & 0xe) == 6) { + /* 3 bytes */ + prRate = (int32_t)((value & 0xffffff) >> 4); + *offset += 3; + } else { + /* 4 bytes */ + prRate = (int32_t)(value >> 4); + *offset += 4; + } - if ((value & 1) == 1) - prRate = -prRate; + if ((value & 1) == 1) prRate = -prRate; - return prRate; + return prRate; } -int decode_meas3Doppler(raw_t* raw) -{ - sbf_t *sbf = (sbf_t *)raw->rcv_data; - int n; - uint32_t offset = 0, ret = 0; - int ant_sel = 0; /* antenna selection (0:main) */ - - if (timediff(raw->time, sbf->current_time) != 0) { - sbf->current_time = raw->time; - ret = flushobuf(raw); - } +int decode_meas3Doppler(raw_t *raw) { + sbf_t *sbf = (sbf_t *)raw->rcv_data; + int n; + uint32_t offset = 0, ret = 0; + int ant_sel = 0; /* antenna selection (0:main) */ + + if (timediff(raw->time, sbf->current_time) != 0) { + sbf->current_time = raw->time; + ret = flushobuf(raw); + } - if (strstr(raw->opt, "-NO_MEAS3")) return ret; + if (strstr(raw->opt, "-NO_MEAS3")) return ret; - uint16_t flags = U2(raw->buff + 14); - if (strstr(raw->opt, "-AUX1")) ant_sel = 1; - else if (strstr(raw->opt, "-AUX2")) ant_sel = 2; - if ((flags & 0x7) != ant_sel) return ret; + uint16_t flags = U2(raw->buff + 14); + if (strstr(raw->opt, "-AUX1")) + ant_sel = 1; + else if (strstr(raw->opt, "-AUX2")) + ant_sel = 2; + if ((flags & 0x7) != ant_sel) return ret; - for (n = 0; n < raw->obuf.n && offset+16 < (uint32_t)raw->len; n++) { - int navsys, sys, prn; - int8_t masterFreqIndex, slaveFreqIndex; - int32_t prRate = meas3_DopplerPrRate(raw, &offset); + for (n = 0; n < raw->obuf.n && offset + 16 < (uint32_t)raw->len; n++) { + int navsys, sys, prn; + int8_t masterFreqIndex, slaveFreqIndex; + int32_t prRate = meas3_DopplerPrRate(raw, &offset); - if (prRate == (int32_t)0x80000000 || prRate == (int32_t) -268435455) - continue; + if (prRate == (int32_t)0x80000000 || prRate == (int32_t)-268435455) continue; - sys = satsys(raw->obuf.data[n].sat, &prn); + sys = satsys(raw->obuf.data[n].sat, &prn); - for (navsys = 0; navsys < 7; navsys++) - if (Meas3_NavSys[navsys] == sys) - break; - if (navsys == 7) - continue; + for (navsys = 0; navsys < 7; navsys++) + if (Meas3_NavSys[navsys] == sys) break; + if (navsys == 7) continue; - int svid = prn - Meas3_SVIDBase[navsys]; - if (svid >= MEAS3_SAT_MAX) { - // Give up on the remainder, sync with the buffer offset would be lost. - trace(1, "SBF decode_meas3Doppler: svid=%d out of bounds %d\n", svid, MEAS3_SAT_MAX); - return ret; - } + int svid = prn - Meas3_SVIDBase[navsys]; + if (svid >= MEAS3_SAT_MAX) { + // Give up on the remainder, sync with the buffer offset would be lost. + trace(1, "SBF decode_meas3Doppler: svid=%d out of bounds %d\n", svid, MEAS3_SAT_MAX); + return ret; + } - masterFreqIndex = sbf->meas3_freqAssignment[navsys][svid][0]; + masterFreqIndex = sbf->meas3_freqAssignment[navsys][svid][0]; - double freqMaster = code2freq(sys, raw->obuf.data[n].code[masterFreqIndex], raw->obuf.data[n].freq - 7); + double freqMaster = + code2freq(sys, raw->obuf.data[n].code[masterFreqIndex], raw->obuf.data[n].freq - 7); - raw->obuf.data[n].D[masterFreqIndex] = (float)(-(prRate + (int32_t)sbf->meas3_refEpoch.prRate[navsys][svid] * 64) * 0.001 / (CLIGHT/freqMaster)); - for (int i = 1; imeas3_freqAssignment[navsys][svid][i]; - if (slaveFreqIndex < 0) - break; - prRate = meas3_DopplerPrRate(raw, &offset); - double freqSlave = code2freq(sys, raw->obuf.data[n].code[slaveFreqIndex], raw->obuf.data[n].freq - 7); - raw->obuf.data[n].D[slaveFreqIndex] = (float)((raw->obuf.data[n].D[masterFreqIndex] * (CLIGHT/freqMaster) * 1000 - prRate) * 0.001 / (CLIGHT/freqSlave)); - } + raw->obuf.data[n].D[masterFreqIndex] = + (float)(-(prRate + (int32_t)sbf->meas3_refEpoch.prRate[navsys][svid] * 64) * 0.001 / + (CLIGHT / freqMaster)); + for (int i = 1; i < MEAS3_SIG_MAX; i++) { + slaveFreqIndex = sbf->meas3_freqAssignment[navsys][svid][i]; + if (slaveFreqIndex < 0) break; + prRate = meas3_DopplerPrRate(raw, &offset); + double freqSlave = + code2freq(sys, raw->obuf.data[n].code[slaveFreqIndex], raw->obuf.data[n].freq - 7); + raw->obuf.data[n].D[slaveFreqIndex] = + (float)((raw->obuf.data[n].D[masterFreqIndex] * (CLIGHT / freqMaster) * 1000 - prRate) * + 0.001 / (CLIGHT / freqSlave)); } + } - return ret; + return ret; } -int decode_meas3CN(raw_t* raw) -{ - sbf_t *sbf = (sbf_t *)raw->rcv_data; - int n, ret = 0; - uint32_t offset = 0; - int ant_sel = 0; /* antenna selection (0:main) */ - - if (timediff(raw->time, sbf->current_time) != 0) { - sbf->current_time = raw->time; - ret = flushobuf(raw); +int decode_meas3CN(raw_t *raw) { + sbf_t *sbf = (sbf_t *)raw->rcv_data; + int n, ret = 0; + uint32_t offset = 0; + int ant_sel = 0; /* antenna selection (0:main) */ + + if (timediff(raw->time, sbf->current_time) != 0) { + sbf->current_time = raw->time; + ret = flushobuf(raw); + } + + if (strstr(raw->opt, "-NO_MEAS3")) return ret; + + uint16_t flags = U2(raw->buff + 14); + if (strstr(raw->opt, "-AUX1")) + ant_sel = 1; + else if (strstr(raw->opt, "-AUX2")) + ant_sel = 2; + if ((flags & 0x7) != ant_sel) return ret; + + for (n = 0; n < raw->obuf.n && offset / 2 + 16 < (uint32_t)raw->len; n++) { + int navsys, sys, prn; + int8_t masterFreqIndex, slaveFreqIndex; + sys = satsys(raw->obuf.data[n].sat, &prn); + + for (navsys = 0; navsys < 7; navsys++) + if (Meas3_NavSys[navsys] == sys) break; + if (navsys == 7) continue; + + int svid = prn - Meas3_SVIDBase[navsys]; + if (svid >= MEAS3_SAT_MAX) { + // Give up correcting the remainder. + trace(1, "SBF decode_meas3CN: svid=%d out of bounds %d\n", svid, MEAS3_SAT_MAX); + return ret; } - if (strstr(raw->opt, "-NO_MEAS3")) return ret; - - uint16_t flags = U2(raw->buff + 14); - if (strstr(raw->opt, "-AUX1")) ant_sel = 1; - else if (strstr(raw->opt, "-AUX2")) ant_sel = 2; - if ((flags & 0x7) != ant_sel) return ret; - - for (n = 0; n < raw->obuf.n && offset/2+16 < (uint32_t)raw->len; n++) { - int navsys, sys, prn; - int8_t masterFreqIndex, slaveFreqIndex; - sys = satsys(raw->obuf.data[n].sat, &prn); - - for (navsys = 0; navsys < 7; navsys++) - if (Meas3_NavSys[navsys] == sys) - break; - if (navsys == 7) - continue; - - int svid = prn - Meas3_SVIDBase[navsys]; - if (svid >= MEAS3_SAT_MAX) { - // Give up correcting the remainder. - trace(1, "SBF decode_meas3CN: svid=%d out of bounds %d\n", svid, MEAS3_SAT_MAX); - return ret; - } + masterFreqIndex = sbf->meas3_freqAssignment[navsys][svid][0]; - masterFreqIndex = sbf->meas3_freqAssignment[navsys][svid][0]; - - uint8_t mc = (U1(raw->buff + 16 + offset / 2) >> ((offset % 2) * 4)) & 0xf; - raw->obuf.data[n].SNR[masterFreqIndex] += mc * 0.0625 - 0.5; - offset++; - for (int i = 1; imeas3_freqAssignment[navsys][svid][i]; - if (slaveFreqIndex < 0) - break; - raw->obuf.data[n].SNR[slaveFreqIndex] += ((U1(raw->buff + 16 + offset / 2) >> ((offset % 2) * 4)) & 0xf) * .0625 - 0.5; - offset++; - } + uint8_t mc = (U1(raw->buff + 16 + offset / 2) >> ((offset % 2) * 4)) & 0xf; + raw->obuf.data[n].SNR[masterFreqIndex] += mc * 0.0625 - 0.5; + offset++; + for (int i = 1; i < MEAS3_SIG_MAX; i++) { + slaveFreqIndex = sbf->meas3_freqAssignment[navsys][svid][i]; + if (slaveFreqIndex < 0) break; + raw->obuf.data[n].SNR[slaveFreqIndex] += + ((U1(raw->buff + 16 + offset / 2) >> ((offset % 2) * 4)) & 0xf) * .0625 - 0.5; + offset++; } + } - return ret; + return ret; } /* Navigation Page Blocks */ /* decode ION/UTC parameters -------------------------------------------------*/ -static int decode_gpsionutc(raw_t *raw, int sat) -{ - double ion[8], utc[8]; - - if (!decode_frame(raw->subfrm[sat-1], SYS_GPS, NULL, NULL, ion, utc)) return 0; - - adj_utcweek(raw->time, &utc[3]); - adj_utcweek(raw->time, &utc[5]); - int sys = satsys(sat, NULL); - if (sys == SYS_QZS) { - matcpy(raw->nav.ion_qzs, ion, 8, 1); - matcpy(raw->nav.utc_qzs, utc, 8, 1); - } else { - matcpy(raw->nav.ion_gps, ion, 8, 1); - matcpy(raw->nav.utc_gps, utc, 8, 1); - } - return 9; +static int decode_gpsionutc(raw_t *raw, int sat) { + double ion[8], utc[8]; + + if (!decode_frame(raw->subfrm[sat - 1], SYS_GPS, NULL, NULL, ion, utc)) return 0; + + adj_utcweek(raw->time, &utc[3]); + adj_utcweek(raw->time, &utc[5]); + int sys = satsys(sat, NULL); + if (sys == SYS_QZS) { + matcpy(raw->nav.ion_qzs, ion, 8, 1); + matcpy(raw->nav.utc_qzs, utc, 8, 1); + } else { + matcpy(raw->nav.ion_gps, ion, 8, 1); + matcpy(raw->nav.utc_gps, utc, 8, 1); + } + return 9; } - /* Decode SBF raw nav message (raw navigation data) --------------------------*/ -static int decode_gpsrawcanav(raw_t *raw, int sys){ +static int decode_gpsrawcanav(raw_t *raw, int sys) { + /* NOTE. This function works quite well but it somestimes fails in line: + * if (resp>5 || resp<=0){ + * To debug the problem an understanding of the whole RTK code is needed + */ - /* NOTE. This function works quite well but it somestimes fails in line: - * if (resp>5 || resp<=0){ - * To debug the problem an understanding of the whole RTK code is needed - */ + trace(3, "SBF decode_gpsrawcanav: len=%d\n", raw->len); - trace(3, "SBF decode_gpsrawcanav: len=%d\n", raw->len); - - if (raw->len < 60) { - trace(2, "SBF decode_gpsrawcanav block length error: len=%d\n", raw->len); - return -1; - } + if (raw->len < 60) { + trace(2, "SBF decode_gpsrawcanav block length error: len=%d\n", raw->len); + return -1; + } - /* Get GPS satellite number */ - int svid = U1(raw->buff+14); - int sat = svid2sat(svid); - int prn; - if (!sat || satsys(sat, &prn) != sys) { - trace(2, "sbf rawca svid error: sys=%d svid=%d\n", sys, svid); - return -1; - } + /* Get GPS satellite number */ + int svid = U1(raw->buff + 14); + int sat = svid2sat(svid); + int prn; + if (!sat || satsys(sat, &prn) != sys) { + trace(2, "sbf rawca svid error: sys=%d svid=%d\n", sys, svid); + return -1; + } - if (!U1(raw->buff+15)) { - trace(3, "sbf rawca parity/crc error: sys=%d prn=%d\n", sys, prn); - return 0; - } + if (!U1(raw->buff + 15)) { + trace(3, "sbf rawca parity/crc error: sys=%d prn=%d\n", sys, prn); + return 0; + } - if (raw->outtype) { - if (sys == SYS_GPS) - sprintf(raw->msgtype, "SBF GPS Raw Navigation Data (PRN=%d)", prn); - if (sys == SYS_QZS) - sprintf(raw->msgtype, "SBF QZSS Raw Navigation Data (PRN=%d)", prn); - } + if (raw->outtype) { + if (sys == SYS_GPS) sprintf(raw->msgtype, "SBF GPS Raw Navigation Data (PRN=%d)", prn); + if (sys == SYS_QZS) sprintf(raw->msgtype, "SBF QZSS Raw Navigation Data (PRN=%d)", prn); + } - /* Clean up subframe from Septentrio. This is a little bit of work because - * Septentrio Rx add some parity bits to this message. - * We have to throw away the reserved bits as well as the parity bits. - */ - - /* | 2bits | 24bits | 6bits | <- SBF 32-bit word - ------------------------------------------ - | byte1 | bite2 | byte3 | <- sat nav message - */ - uint8_t _buf[30] = {0}; - for (int i=0; i<10; i++) { /* 24 x 10 bits w/o parity */ - setbitu(_buf, 24*i, 24, U4(raw->buff+20+4*i)>>6); - } + /* Clean up subframe from Septentrio. This is a little bit of work because + * Septentrio Rx add some parity bits to this message. + * We have to throw away the reserved bits as well as the parity bits. + */ + + /* | 2bits | 24bits | 6bits | <- SBF 32-bit word + ------------------------------------------ + | byte1 | bite2 | byte3 | <- sat nav message + */ + uint8_t _buf[30] = {0}; + for (int i = 0; i < 10; i++) { /* 24 x 10 bits w/o parity */ + setbitu(_buf, 24 * i, 24, U4(raw->buff + 20 + 4 * i) >> 6); + } - /* Now that we have a classic subframe we call the generic function */ - int id = getbitu(_buf, 43, 3); /* get subframe id */ - if (id<1 || id>5) { - trace(2, "sbf rawca subframe id error: sys=%d prn=%d id=%d\n", sys, prn, id); - return -1; - } + /* Now that we have a classic subframe we call the generic function */ + int id = getbitu(_buf, 43, 3); /* get subframe id */ + if (id < 1 || id > 5) { + trace(2, "sbf rawca subframe id error: sys=%d prn=%d id=%d\n", sys, prn, id); + return -1; + } - memcpy(raw->subfrm[sat-1]+(id-1)*30, _buf, 30); + memcpy(raw->subfrm[sat - 1] + (id - 1) * 30, _buf, 30); - if (id == 3) { - eph_t eph = {0}; - if (!decode_frame(raw->subfrm[sat-1], sys, &eph, NULL, NULL, NULL)) - return 0; - - if (!strstr(raw->opt, "-EPHALL")) { - if (eph.iode == raw->nav.eph[sat-1].iode && - eph.iodc == raw->nav.eph[sat-1].iodc && - timediff(eph.toe, raw->nav.eph[sat-1].toe) == 0.0 && - timediff(eph.toc, raw->nav.eph[sat-1].toc) == 0.0) return 0; - } - eph.sat = sat; - raw->nav.eph[sat-1] = eph; - raw->ephsat = sat; - raw->ephset = 0; + if (id == 3) { + eph_t eph = {0}; + if (!decode_frame(raw->subfrm[sat - 1], sys, &eph, NULL, NULL, NULL)) return 0; - return 2; + if (!strstr(raw->opt, "-EPHALL")) { + if (eph.iode == raw->nav.eph[sat - 1].iode && eph.iodc == raw->nav.eph[sat - 1].iodc && + timediff(eph.toe, raw->nav.eph[sat - 1].toe) == 0.0 && + timediff(eph.toc, raw->nav.eph[sat - 1].toc) == 0.0) + return 0; } - if (id==4 || id==5) { - int ret = decode_gpsionutc(raw, sat); - memset(raw->subfrm[sat-1]+(id-1)*30, 0, 30); + eph.sat = sat; + raw->nav.eph[sat - 1] = eph; + raw->ephsat = sat; + raw->ephset = 0; - return ret; - } + return 2; + } + if (id == 4 || id == 5) { + int ret = decode_gpsionutc(raw, sat); + memset(raw->subfrm[sat - 1] + (id - 1) * 30, 0, 30); - trace(4, "SBF, decode_gpsrawcanav: sat=%2d\n", sat); - return 0; + return ret; + } + + trace(4, "SBF, decode_gpsrawcanav: sat=%2d\n", sat); + return 0; } /* Decode SBF GPS raw cnav message (raw navigation data) ----------------------*/ @@ -1687,21 +1815,21 @@ static int decode_gpsrawcnav(raw_t *raw, int sys) { offset += 1; switch (type) { - case 10: // Ephemeris 1 - case 11: // Ephemeris 2 - case 12: // Reduced Almanac - case 13: // Clock Differential Correction - case 14: // Ephemeris Differential Correction - case 15: // Text - case 30: // Clock, IONO & Group Delay - case 31: // Clock & Reduced Almanac - case 32: // Clock & EOP - case 33: // Clock & UTC - case 34: // Clock & Differential Correction - case 35: // Clock & GGTO - case 36: // Clock & Text - case 37: // Clock & Midi Almanac - case 40: // Integrity Support Message + case 10: // Ephemeris 1 + case 11: // Ephemeris 2 + case 12: // Reduced Almanac + case 13: // Clock Differential Correction + case 14: // Ephemeris Differential Correction + case 15: // Text + case 30: // Clock, IONO & Group Delay + case 31: // Clock & Reduced Almanac + case 32: // Clock & EOP + case 33: // Clock & UTC + case 34: // Clock & Differential Correction + case 35: // Clock & GGTO + case 36: // Clock & Text + case 37: // Clock & Midi Almanac + case 40: // Integrity Support Message trace(3, "sbf rawcnav unsupported message type %d\n", type); break; default: @@ -1715,2488 +1843,2492 @@ static int decode_gpsrawcnav(raw_t *raw, int sys) { } /* Decode SBF raw nav message (raw navigation data) for GLONASS---------------*/ -static int decode_glorawcanav(raw_t *raw){ - if (raw->len < 32) { - trace(2, "sbf glorawca length error: len=%d\n", raw->len); - return -1; - } - int svid = U1(raw->buff+14); - int sat=svid2sat(svid); - int prn; - if (!sat || satsys(sat,&prn)!=SYS_GLO) { - trace(3, "sbf glorawca svid error: svid=%d\n", svid); - return (svid==62) ? 0 : -1; /* svid=62: slot unknown */ - } - if (!U1(raw->buff+15)) { - trace(3, "sbf glorawca parity/crc error: prn=%d\n", prn); - return 0; - } - if (raw->outtype) { - sprintf(raw->msgtype+strlen(raw->msgtype), " prn=%d", prn); - } - uint8_t buff[12]; - for (int i=0; i<3; i++) { - setbitu(buff, 32*i, 32, U4(raw->buff+20+4*i)); /* 85 bits */ - } - int m = getbitu(buff, 1, 4); - if (m<1 || m>15) { - trace(2, "sbf glorawca string number error: prn=%d m=%d\n", prn, m); - return -1; - } - int32_t time = raw->time.time; - int32_t dt = time - I4(raw->subfrm[sat - 1] + 152); - if (dt > 30 || dt < -30) { - memset(raw->subfrm[sat-1], 0, 40); - memcpy(raw->subfrm[sat-1]+152, &time, sizeof(time)); - } - memcpy(raw->subfrm[sat-1]+(m-1)*10, buff, 10); - if (m != 4) return 0; +static int decode_glorawcanav(raw_t *raw) { + if (raw->len < 32) { + trace(2, "sbf glorawca length error: len=%d\n", raw->len); + return -1; + } + int svid = U1(raw->buff + 14); + int sat = svid2sat(svid); + int prn; + if (!sat || satsys(sat, &prn) != SYS_GLO) { + trace(3, "sbf glorawca svid error: svid=%d\n", svid); + return (svid == 62) ? 0 : -1; /* svid=62: slot unknown */ + } + if (!U1(raw->buff + 15)) { + trace(3, "sbf glorawca parity/crc error: prn=%d\n", prn); + return 0; + } + if (raw->outtype) { + sprintf(raw->msgtype + strlen(raw->msgtype), " prn=%d", prn); + } + uint8_t buff[12]; + for (int i = 0; i < 3; i++) { + setbitu(buff, 32 * i, 32, U4(raw->buff + 20 + 4 * i)); /* 85 bits */ + } + int m = getbitu(buff, 1, 4); + if (m < 1 || m > 15) { + trace(2, "sbf glorawca string number error: prn=%d m=%d\n", prn, m); + return -1; + } + int32_t time = raw->time.time; + int32_t dt = time - I4(raw->subfrm[sat - 1] + 152); + if (dt > 30 || dt < -30) { + memset(raw->subfrm[sat - 1], 0, 40); + memcpy(raw->subfrm[sat - 1] + 152, &time, sizeof(time)); + } + memcpy(raw->subfrm[sat - 1] + (m - 1) * 10, buff, 10); + if (m != 4) return 0; - geph_t geph = {0}; - geph.tof = raw->time; - double utc[8] = {0}; - if (!decode_glostr(raw->subfrm[sat-1], &geph, utc)) return 0; + geph_t geph = {0}; + geph.tof = raw->time; + double utc[8] = {0}; + if (!decode_glostr(raw->subfrm[sat - 1], &geph, utc)) return 0; - matcpy(raw->nav.utc_glo, utc, 8, 1); + matcpy(raw->nav.utc_glo, utc, 8, 1); - if (geph.sat != sat) { - trace(2, "sbf glorawca satellite error: sat=%d %d\n", sat, geph.sat); - return -1; - } - geph.frq = (int)U1(raw->buff+18)-8; + if (geph.sat != sat) { + trace(2, "sbf glorawca satellite error: sat=%d %d\n", sat, geph.sat); + return -1; + } + geph.frq = (int)U1(raw->buff + 18) - 8; - if (!strstr(raw->opt, "-EPHALL")) { - if (geph.iode == raw->nav.geph[prn-1].iode && - geph.svh == raw->nav.geph[prn - 1].svh && - timediff(geph.toe, raw->nav.geph[prn-1].toe) == 0.0) return 0; - } - raw->nav.geph[prn-1] = geph; - raw->ephsat = sat; - raw->ephset = 0; + if (!strstr(raw->opt, "-EPHALL")) { + if (geph.iode == raw->nav.geph[prn - 1].iode && geph.svh == raw->nav.geph[prn - 1].svh && + timediff(geph.toe, raw->nav.geph[prn - 1].toe) == 0.0) + return 0; + } + raw->nav.geph[prn - 1] = geph; + raw->ephsat = sat; + raw->ephset = 0; - return 2; + return 2; } /* decode SBF Galileo F/NAV navigation page ----------------------------------*/ -static int decode_galrawfnav(raw_t *raw) -{ - if (strstr(raw->opt, "-GALINAV")) return 0; - - if (raw->len < 52) { - trace(2, "sbf galrawfnav length error: len=%d\n", raw->len); - return -1; - } - int svid = U1(raw->buff+14); - int src = U1(raw->buff+17) & 0x1f; - - int sat = svid2sat(svid); - int prn; - if (!sat || satsys(sat, &prn) != SYS_GAL) { - trace(2, "sbf galrawfnav svid error: svid=%d src=%d\n", svid, src); - return -1; - } - if (!U1(raw->buff+15)) { - trace(3, "sbf galrawfnav parity/crc error: prn=%d src=%d\n", prn, src); - return 0; - } - if (raw->outtype) { - sprintf(raw->msgtype+strlen(raw->msgtype), " prn=%d src=%d", prn, src); - } - if (src!=20 && src!=22) { /* E5a or E5 AltBOC */ - trace(2, "sbf galrawfnav source error: prn=%d src=%d\n", prn, src); - return -1; - } - uint8_t buff[32]; - for (int i=0; i<8; i++) { - setbitu(buff, 32*i, 32, U4(raw->buff+20+4*i)); /* 244 bits page */ - } - int type = getbitu(buff, 0, 6); /* page type */ - - if (type == 63) return 0; /* dummy page */ - if (type<1 || type>6) { - trace(2, "sbf galrawfnav page type error: prn=%d type=%d\n", prn, type); - return -1; - } - /* save 244 bits page (31 bytes * 6 page) */ - memcpy(raw->subfrm[sat-1]+128+(type-1)*31, buff, 31); - - if (type != 4) return 0; - eph_t eph = {0}; - double ion[4] = {0}, utc[8] = {0}; - if (!decode_gal_fnav(raw->subfrm[sat-1]+128, &eph, ion, utc)) return 0; - - if (eph.sat != sat) { - trace(2, "sbf galrawfnav satellite error: sat=%d %d\n", sat, eph.sat); - return -1; - } - /* Data source: E5a */ - eph.code |= (1<<1)|(1<<8); - - adj_utcweek(raw->time, utc); - matcpy(raw->nav.ion_gal, ion, 4, 1); - matcpy(raw->nav.utc_gal, utc, 8, 1); +static int decode_galrawfnav(raw_t *raw) { + if (strstr(raw->opt, "-GALINAV")) return 0; - if (!strstr(raw->opt, "-EPHALL")) { - if (eph.iode == raw->nav.eph[sat-1+MAXSAT].iode && - timediff(eph.toe, raw->nav.eph[sat-1+MAXSAT].toe) == 0.0 && - timediff(eph.toc, raw->nav.eph[sat-1+MAXSAT].toc) == 0.0) return 0; - } - raw->nav.eph[sat-1+MAXSAT] = eph; - raw->ephsat = sat; - raw->ephset = 1; /* 1:F/NAV */ + if (raw->len < 52) { + trace(2, "sbf galrawfnav length error: len=%d\n", raw->len); + return -1; + } + int svid = U1(raw->buff + 14); + int src = U1(raw->buff + 17) & 0x1f; - return 2; + int sat = svid2sat(svid); + int prn; + if (!sat || satsys(sat, &prn) != SYS_GAL) { + trace(2, "sbf galrawfnav svid error: svid=%d src=%d\n", svid, src); + return -1; + } + if (!U1(raw->buff + 15)) { + trace(3, "sbf galrawfnav parity/crc error: prn=%d src=%d\n", prn, src); + return 0; + } + if (raw->outtype) { + sprintf(raw->msgtype + strlen(raw->msgtype), " prn=%d src=%d", prn, src); + } + if (src != 20 && src != 22) { /* E5a or E5 AltBOC */ + trace(2, "sbf galrawfnav source error: prn=%d src=%d\n", prn, src); + return -1; + } + uint8_t buff[32]; + for (int i = 0; i < 8; i++) { + setbitu(buff, 32 * i, 32, U4(raw->buff + 20 + 4 * i)); /* 244 bits page */ + } + int type = getbitu(buff, 0, 6); /* page type */ + + if (type == 63) return 0; /* dummy page */ + if (type < 1 || type > 6) { + trace(2, "sbf galrawfnav page type error: prn=%d type=%d\n", prn, type); + return -1; + } + /* save 244 bits page (31 bytes * 6 page) */ + memcpy(raw->subfrm[sat - 1] + 128 + (type - 1) * 31, buff, 31); + + if (type != 4) return 0; + eph_t eph = {0}; + double ion[4] = {0}, utc[8] = {0}; + if (!decode_gal_fnav(raw->subfrm[sat - 1] + 128, &eph, ion, utc)) return 0; + + if (eph.sat != sat) { + trace(2, "sbf galrawfnav satellite error: sat=%d %d\n", sat, eph.sat); + return -1; + } + /* Data source: E5a */ + eph.code |= (1 << 1) | (1 << 8); + + adj_utcweek(raw->time, utc); + matcpy(raw->nav.ion_gal, ion, 4, 1); + matcpy(raw->nav.utc_gal, utc, 8, 1); + + if (!strstr(raw->opt, "-EPHALL")) { + if (eph.iode == raw->nav.eph[sat - 1 + MAXSAT].iode && + timediff(eph.toe, raw->nav.eph[sat - 1 + MAXSAT].toe) == 0.0 && + timediff(eph.toc, raw->nav.eph[sat - 1 + MAXSAT].toc) == 0.0) + return 0; + } + raw->nav.eph[sat - 1 + MAXSAT] = eph; + raw->ephsat = sat; + raw->ephset = 1; /* 1:F/NAV */ + + return 2; } /* decode SBF raw nav message (raw navigation data) for galileo I/NAV---------*/ -static int decode_galrawinav(raw_t *raw){ - eph_t eph = {0}; - double ion[4] = {0}, utc[8] = {0}; - uint8_t *p = raw->buff+14, buff[32], type, part1, part2, page1, page2; - int i, j, svid, src, sat, prn; - - if (strstr(raw->opt, "-GALFNAV")) return 0; +static int decode_galrawinav(raw_t *raw) { + eph_t eph = {0}; + double ion[4] = {0}, utc[8] = {0}; + uint8_t *p = raw->buff + 14, buff[32], type, part1, part2, page1, page2; + int i, j, svid, src, sat, prn; - if (raw->len < 52) { - trace(2, "sbf galrawinav length error: len=%d\n", raw->len); - return -1; - } - svid = U1(p); - src = U1(p+3) & 0x1f; + if (strstr(raw->opt, "-GALFNAV")) return 0; - sat=svid2sat(svid); - if (!sat || satsys(sat, &prn)!=SYS_GAL) { - trace(2, "sbf galrawinav svid error: svid=%d src=%d\n", svid, src); - return -1; - } - if (!U1(p+1)) { - trace(3, "sbf galrawinav parity/crc error: prn=%d src=%d\n", prn, src); - return 0; - } - if (raw->outtype) { - sprintf(raw->msgtype+strlen(raw->msgtype), " prn=%d src=%d", prn, src); - } - if (src!=17 && src!=21 && src!=22) { /* E1, E5b or E5 AltBOC */ - trace(2, "sbf galrawinav source error: prn=%d src=%d\n", prn, src); - return -1; - } - for (i=0, p+=6; i<8; i++, p+=4) { - setbitu(buff, 32*i, 32, U4(p)); /* 114(even) + 120(odd) bits */ - } - part1 = getbitu(buff, 0, 1); - page1 = getbitu(buff, 1, 1); - part2 = getbitu(buff, 114, 1); - page2 = getbitu(buff, 115, 1); - - if (part1!=0 || part2!=1) { - trace(3, "sbf galrawinav part error: prn=%d even/odd=%d %d\n", prn, part1, part2); - return -1; - } - if (page1==1 || page2==1) return 0; /* alert page */ + if (raw->len < 52) { + trace(2, "sbf galrawinav length error: len=%d\n", raw->len); + return -1; + } + svid = U1(p); + src = U1(p + 3) & 0x1f; - type = getbitu(buff, 2, 6); /* word type */ + sat = svid2sat(svid); + if (!sat || satsys(sat, &prn) != SYS_GAL) { + trace(2, "sbf galrawinav svid error: svid=%d src=%d\n", svid, src); + return -1; + } + if (!U1(p + 1)) { + trace(3, "sbf galrawinav parity/crc error: prn=%d src=%d\n", prn, src); + return 0; + } + if (raw->outtype) { + sprintf(raw->msgtype + strlen(raw->msgtype), " prn=%d src=%d", prn, src); + } + if (src != 17 && src != 21 && src != 22) { /* E1, E5b or E5 AltBOC */ + trace(2, "sbf galrawinav source error: prn=%d src=%d\n", prn, src); + return -1; + } + for (i = 0, p += 6; i < 8; i++, p += 4) { + setbitu(buff, 32 * i, 32, U4(p)); /* 114(even) + 120(odd) bits */ + } + part1 = getbitu(buff, 0, 1); + page1 = getbitu(buff, 1, 1); + part2 = getbitu(buff, 114, 1); + page2 = getbitu(buff, 115, 1); - if (type > 6) return 0; + if (part1 != 0 || part2 != 1) { + trace(3, "sbf galrawinav part error: prn=%d even/odd=%d %d\n", prn, part1, part2); + return -1; + } + if (page1 == 1 || page2 == 1) return 0; /* alert page */ - /* save 128 (112:even+16:odd) bits word (16 bytes * 7 word) */ - for (i=0, j=2; i<14; i++, j+=8) { - raw->subfrm[sat-1][type*16+i] = getbitu(buff, j, 8); - } - for (i=14,j=116;i<16;i++,j+=8) { - raw->subfrm[sat-1][type*16+i] = getbitu(buff, j, 8); - } - if (type != 5) return 0; - if (!decode_gal_inav(raw->subfrm[sat-1], &eph, ion, utc)) return 0; + type = getbitu(buff, 2, 6); /* word type */ - if (eph.sat != sat) { - trace(2, "sbf galrawinav satellite error: sat=%d %d\n", sat, eph.sat); - return -1; - } - /* Data source: E1 or E5b */ - eph.code |= src==17 ? 1<<0 : (1<<2)|(1<<9); - if (U1(raw->buff + 17)&0x20) eph.code |= 1<<2; // Mix of E1 and E5b + if (type > 6) return 0; - adj_utcweek(raw->time, utc); - matcpy(raw->nav.ion_gal, ion, 4, 1); - matcpy(raw->nav.utc_gal, utc, 8, 1); + /* save 128 (112:even+16:odd) bits word (16 bytes * 7 word) */ + for (i = 0, j = 2; i < 14; i++, j += 8) { + raw->subfrm[sat - 1][type * 16 + i] = getbitu(buff, j, 8); + } + for (i = 14, j = 116; i < 16; i++, j += 8) { + raw->subfrm[sat - 1][type * 16 + i] = getbitu(buff, j, 8); + } + if (type != 5) return 0; + if (!decode_gal_inav(raw->subfrm[sat - 1], &eph, ion, utc)) return 0; - if (!strstr(raw->opt, "-EPHALL")) { - if (eph.iode == raw->nav.eph[sat-1].iode && - timediff(eph.toe,raw->nav.eph[sat-1].toe) == 0.0 && - timediff(eph.toc,raw->nav.eph[sat-1].toc) == 0.0) return 0; - } - raw->nav.eph[sat-1] = eph; - raw->ephsat = sat; - raw->ephset = 0; /* 0:I/NAV */ + if (eph.sat != sat) { + trace(2, "sbf galrawinav satellite error: sat=%d %d\n", sat, eph.sat); + return -1; + } + /* Data source: E1 or E5b */ + eph.code |= src == 17 ? 1 << 0 : (1 << 2) | (1 << 9); + if (U1(raw->buff + 17) & 0x20) eph.code |= 1 << 2; // Mix of E1 and E5b + + adj_utcweek(raw->time, utc); + matcpy(raw->nav.ion_gal, ion, 4, 1); + matcpy(raw->nav.utc_gal, utc, 8, 1); + + if (!strstr(raw->opt, "-EPHALL")) { + if (eph.iode == raw->nav.eph[sat - 1].iode && + timediff(eph.toe, raw->nav.eph[sat - 1].toe) == 0.0 && + timediff(eph.toc, raw->nav.eph[sat - 1].toc) == 0.0) + return 0; + } + raw->nav.eph[sat - 1] = eph; + raw->ephsat = sat; + raw->ephset = 0; /* 0:I/NAV */ - return 2; + return 2; } /* decode SBF raw nav message (raw navigation data) --------------------------*/ -static int decode_georaw(raw_t *raw){ - uint8_t *p = raw->buff+14, buff[32]; - int i, svid, sat, prn; +static int decode_georaw(raw_t *raw) { + uint8_t *p = raw->buff + 14, buff[32]; + int i, svid, sat, prn; - if (raw->len < 52) { - trace(2, "sbf georawl1 length error: len=%d\n", raw->len); - return -1; - } + if (raw->len < 52) { + trace(2, "sbf georawl1 length error: len=%d\n", raw->len); + return -1; + } - svid = U1(p); - sat = svid2sat(svid); - if (!sat || satsys(sat, &prn)!=SYS_SBS) { - trace(2, "sbf georawl1 svid error: svid=%d\n", svid); - return -1; - } - if (!U1(p+1)) { - trace(3, "sbf georaw parity/crc error: prn=%d err=%d\n", prn, U1(p+2)); - return 0; - } - if (raw->outtype) { - sprintf(raw->msgtype+strlen(raw->msgtype), " prn=%d", prn); - } - raw->sbsmsg.tow = (int)time2gpst(raw->time, &raw->sbsmsg.week); - raw->sbsmsg.prn = prn; + svid = U1(p); + sat = svid2sat(svid); + if (!sat || satsys(sat, &prn) != SYS_SBS) { + trace(2, "sbf georawl1 svid error: svid=%d\n", svid); + return -1; + } + if (!U1(p + 1)) { + trace(3, "sbf georaw parity/crc error: prn=%d err=%d\n", prn, U1(p + 2)); + return 0; + } + if (raw->outtype) { + sprintf(raw->msgtype + strlen(raw->msgtype), " prn=%d", prn); + } + raw->sbsmsg.tow = (int)time2gpst(raw->time, &raw->sbsmsg.week); + raw->sbsmsg.prn = prn; - for (i=0; i<8; i++) { - setbitu(buff, 32*i, 32, U4(p+6+4*i)); - } - memcpy(raw->sbsmsg.msg, buff, 29); /* 226 bits w/o CRC */ - raw->sbsmsg.msg[28] &= 0xC0; + for (i = 0; i < 8; i++) { + setbitu(buff, 32 * i, 32, U4(p + 6 + 4 * i)); + } + memcpy(raw->sbsmsg.msg, buff, 29); /* 226 bits w/o CRC */ + raw->sbsmsg.msg[28] &= 0xC0; - return 3; + return 3; } /* decode SBF raw nav message (raw navigation data) for COMPASS ---------*/ -static int decode_cmpraw(raw_t *raw){ - eph_t eph = {0}; - double ion[8], utc[8]; - uint8_t *p = raw->buff+14, buff[40]; - int i, id, svid, sat, prn; - - if (raw->len < 52) { - trace(2, "sbf cmpraw length error: len=%d\n", raw->len); - return -1; - } - svid = U1(p); - sat = svid2sat(svid); - if (!sat || satsys(sat, &prn) != SYS_CMP) { - trace(2, "sbf cmpraw svid error: svid=%d\n", svid); - return -1; - } - if (!U1(p+1)) { - trace(3, "sbf cmpraw parity/crc error: prn=%d\n", prn); - return 0; - } - if (raw->outtype) { - sprintf(raw->msgtype+strlen(raw->msgtype), " prn=%d", prn); - } - for (i=0, p+=6; i<10; i++, p+=4) { - setbitu(buff, 32*i, 32, U4(p)); - } - id = getbitu(buff, 15, 3); /* subframe ID */ - if (id<1 || id>5) { - trace(2, "sbf cmpraw id error: prn=%d id=%d\n", prn, id); - return -1; - } - if (prn>=6 && prn<=58) { /* IGSO/MEO */ - memcpy(raw->subfrm[sat-1]+(id-1)*38, buff, 38); +static int decode_cmpraw(raw_t *raw) { + eph_t eph = {0}; + double ion[8], utc[8]; + uint8_t *p = raw->buff + 14, buff[40]; + int i, id, svid, sat, prn; + + if (raw->len < 52) { + trace(2, "sbf cmpraw length error: len=%d\n", raw->len); + return -1; + } + svid = U1(p); + sat = svid2sat(svid); + if (!sat || satsys(sat, &prn) != SYS_CMP) { + trace(2, "sbf cmpraw svid error: svid=%d\n", svid); + return -1; + } + if (!U1(p + 1)) { + trace(3, "sbf cmpraw parity/crc error: prn=%d\n", prn); + return 0; + } + if (raw->outtype) { + sprintf(raw->msgtype + strlen(raw->msgtype), " prn=%d", prn); + } + for (i = 0, p += 6; i < 10; i++, p += 4) { + setbitu(buff, 32 * i, 32, U4(p)); + } + id = getbitu(buff, 15, 3); /* subframe ID */ + if (id < 1 || id > 5) { + trace(2, "sbf cmpraw id error: prn=%d id=%d\n", prn, id); + return -1; + } + if (prn >= 6 && prn <= 58) { /* IGSO/MEO */ + memcpy(raw->subfrm[sat - 1] + (id - 1) * 38, buff, 38); - if (id == 3) { - if (!decode_bds_d1(raw->subfrm[sat-1], &eph, NULL, NULL)) return 0; - } - else if (id == 5) { - if (!decode_bds_d1(raw->subfrm[sat-1], NULL, ion, utc)) return 0; - matcpy(raw->nav.ion_cmp, ion, 8, 1); - matcpy(raw->nav.utc_cmp, utc, 8, 1); - return 9; - } - else return 0; - } - else { /* GEO */ - if (id == 1) { - int pgn = getbitu(buff, 42, 4); // Page number. - if (pgn < 1 || pgn > 10) return 0; - memcpy(raw->subfrm[sat - 1] + (pgn - 1) * 38, buff, 38); - if (pgn != 10) return 0; - if (!decode_bds_d2(raw->subfrm[sat - 1], &eph, NULL)) return 0; - } else if (id == 5) { - int pgn = getbitu(buff, 43, 7); // Page number. - if (pgn != 102) return 0; - memcpy(raw->subfrm[sat - 1] + 10 * 38, buff, 38); - double utc[8]; - if (!decode_bds_d2(raw->subfrm[sat - 1], NULL, utc)) return 0; - matcpy(raw->nav.utc_cmp, utc, 8, 1); - return 9; - } else - return 0; - } - if (!strstr(raw->opt, "-EPHALL")) { - if (timediff(eph.toe, raw->nav.eph[sat-1].toe) == 0.0) - return 0; - } - eph.sat = sat; - raw->nav.eph[sat-1] = eph; - raw->ephsat = sat; - raw->ephset = 0; - return 2; + if (id == 3) { + if (!decode_bds_d1(raw->subfrm[sat - 1], &eph, NULL, NULL)) return 0; + } else if (id == 5) { + if (!decode_bds_d1(raw->subfrm[sat - 1], NULL, ion, utc)) return 0; + matcpy(raw->nav.ion_cmp, ion, 8, 1); + matcpy(raw->nav.utc_cmp, utc, 8, 1); + return 9; + } else + return 0; + } else { /* GEO */ + if (id == 1) { + int pgn = getbitu(buff, 42, 4); // Page number. + if (pgn < 1 || pgn > 10) return 0; + memcpy(raw->subfrm[sat - 1] + (pgn - 1) * 38, buff, 38); + if (pgn != 10) return 0; + if (!decode_bds_d2(raw->subfrm[sat - 1], &eph, NULL)) return 0; + } else if (id == 5) { + int pgn = getbitu(buff, 43, 7); // Page number. + if (pgn != 102) return 0; + memcpy(raw->subfrm[sat - 1] + 10 * 38, buff, 38); + double utc[8]; + if (!decode_bds_d2(raw->subfrm[sat - 1], NULL, utc)) return 0; + matcpy(raw->nav.utc_cmp, utc, 8, 1); + return 9; + } else + return 0; + } + if (!strstr(raw->opt, "-EPHALL")) { + if (timediff(eph.toe, raw->nav.eph[sat - 1].toe) == 0.0) return 0; + } + eph.sat = sat; + raw->nav.eph[sat - 1] = eph; + raw->ephsat = sat; + raw->ephset = 0; + return 2; } #ifdef ENAIRN /* decode SBF NavIC/IRNSS subframe -------------------------------------------*/ -static int decode_navicraw(raw_t *raw) -{ - if (raw->len < 52) { - trace(2, "sbf navicraw length error: len=%d\n", raw->len); - return -1; - } - int svid = U1(raw->buff+14); - int sat=svid2sat(svid), prn; - if (!sat || satsys(sat,&prn)!=SYS_IRN) { - trace(2, "sbf navicraw svid error: svid=%d\n", svid); - return -1; - } - if (!U1(raw->buff+15)) { - trace(3, "sbf navicraw parity/crc error: prn=%d err=%d\n", prn, U1(raw->buff+16)); - return 0; - } - if (raw->outtype) { - sprintf(raw->msgtype+strlen(raw->msgtype), " prn=%d", prn); - } - uint8_t buff[40]; - for (int i=0; i<10; i++) { - setbitu(buff, 32*i, 32, U4(raw->buff+20+i*4)); - } - int id = getbitu(buff, 27, 2); /* subframe ID (0-3) */ +static int decode_navicraw(raw_t *raw) { + if (raw->len < 52) { + trace(2, "sbf navicraw length error: len=%d\n", raw->len); + return -1; + } + int svid = U1(raw->buff + 14); + int sat = svid2sat(svid), prn; + if (!sat || satsys(sat, &prn) != SYS_IRN) { + trace(2, "sbf navicraw svid error: svid=%d\n", svid); + return -1; + } + if (!U1(raw->buff + 15)) { + trace(3, "sbf navicraw parity/crc error: prn=%d err=%d\n", prn, U1(raw->buff + 16)); + return 0; + } + if (raw->outtype) { + sprintf(raw->msgtype + strlen(raw->msgtype), " prn=%d", prn); + } + uint8_t buff[40]; + for (int i = 0; i < 10; i++) { + setbitu(buff, 32 * i, 32, U4(raw->buff + 20 + i * 4)); + } + int id = getbitu(buff, 27, 2); /* subframe ID (0-3) */ - memcpy(raw->subfrm[sat-1]+id*37, buff, 37); + memcpy(raw->subfrm[sat - 1] + id * 37, buff, 37); - if (id==1) { /* subframe 2 */ - eph_t eph = {0}; - if (!decode_irn_nav(raw->subfrm[sat-1], &eph, NULL, NULL)) return 0; + if (id == 1) { /* subframe 2 */ + eph_t eph = {0}; + if (!decode_irn_nav(raw->subfrm[sat - 1], &eph, NULL, NULL)) return 0; - if (!strstr(raw->opt, "-EPHALL")) { - if (eph.iode==raw->nav.eph[sat-1].iode && - timediff(eph.toe, raw->nav.eph[sat-1].toe)==0.0) { - return 0; - } - } - eph.sat = sat; - raw->nav.eph[sat-1] = eph; - raw->ephsat = sat; - raw->ephset = 0; - return 2; - } - else if (id==2 || id==3) { /* subframe 3 or 4 */ - double ion[8], utc[9]; - int ret = 0; - if (decode_irn_nav(raw->subfrm[sat-1], NULL, ion, NULL)) { - matcpy(raw->nav.ion_irn, ion, 8, 1); - ret = 9; - } - if (decode_irn_nav(raw->subfrm[sat-1], NULL, NULL, utc)) { - adj_utcweek(raw->time, utc); - matcpy(raw->nav.utc_irn, utc, 9, 1); - ret = 9; - } - memset(raw->subfrm[sat-1]+id*37, 0, 37); - return ret; + if (!strstr(raw->opt, "-EPHALL")) { + if (eph.iode == raw->nav.eph[sat - 1].iode && + timediff(eph.toe, raw->nav.eph[sat - 1].toe) == 0.0) { + return 0; + } } - return 0; + eph.sat = sat; + raw->nav.eph[sat - 1] = eph; + raw->ephsat = sat; + raw->ephset = 0; + return 2; + } else if (id == 2 || id == 3) { /* subframe 3 or 4 */ + double ion[8], utc[9]; + int ret = 0; + if (decode_irn_nav(raw->subfrm[sat - 1], NULL, ion, NULL)) { + matcpy(raw->nav.ion_irn, ion, 8, 1); + ret = 9; + } + if (decode_irn_nav(raw->subfrm[sat - 1], NULL, NULL, utc)) { + adj_utcweek(raw->time, utc); + matcpy(raw->nav.utc_irn, utc, 9, 1); + ret = 9; + } + memset(raw->subfrm[sat - 1] + id * 37, 0, 37); + return ret; + } + return 0; } #ifdef TESTING /* decode SBF lnav message for NavIC (navigation data) --------------------------*/ -static int decode_naviclnav(raw_t *raw) -{ - uint8_t *p = raw->buff+8; /* points at TOW location */ - eph_t eph = {0}; - uint32_t tocs; - uint8_t prn, sat, iodec; +static int decode_naviclnav(raw_t *raw) { + uint8_t *p = raw->buff + 8; /* points at TOW location */ + eph_t eph = {0}; + uint32_t tocs; + uint8_t prn, sat, iodec; - trace(4, "SBF decode_naviclnav: len=%d\n", raw->len); + trace(4, "SBF decode_naviclnav: len=%d\n", raw->len); - if (raw->len < 148) { - trace(2, "SBF decode_naviclnav frame length error: len=%d\n", raw->len); - return -1; - } + if (raw->len < 148) { + trace(2, "SBF decode_naviclnav frame length error: len=%d\n", raw->len); + return -1; + } - prn = U1(p+6); - sat = satno(SYS_IRN, prn); + prn = U1(p + 6); + sat = satno(SYS_IRN, prn); - if (sat == 0) return -1; + if (sat == 0) return -1; - if (!(prn>=1 && prn<=37)){ - trace(2, "SBF decode_naviclnav prn error: sat=%d\n", prn); - return -1; - } + if (!(prn >= 1 && prn <= 37)) { + trace(2, "SBF decode_naviclnav prn error: sat=%d\n", prn); + return -1; + } - eph.week = U2(p + 4); - iodec = U1(p + 7); - eph.toes = U4(p + 8); - eph.A = pow(R8(p + 12), 2); - eph.deln = R4(p + 20) * PI; - eph.M0 = R8(p + 24) * PI; - eph.e = R8(p + 32); - eph.omg = R8(p + 40) * PI; - eph.OMG0 = R8(p + 48) * PI; - eph.OMGd = R8(p + 56) * PI; - eph.i0 = R8(p + 64) * PI; - eph.idot = R4(p + 72) * PI; - eph.cis = R4(p + 76); - eph.cic = R4(p + 80); - eph.crs = R4(p + 84); - eph.crc = R4(p + 88); - eph.cus = R4(p + 92); - eph.cuc = R4(p + 96); - tocs = U4(p + 100); - eph.f2 = R4(p + 104); - eph.f1 = R4(p + 108); - eph.f0 = R8(p + 112); - eph.tgd[0] = R4(p + 120); - eph.flag = U1(p + 124); - eph.sva = U1(p + 125); - eph.svh = U1(p + 140); - - eph.code = 0; - eph.fit = 0; - - eph.iodc = iodec; - eph.iode = iodec; - - eph.toe = gpst2time(eph.week, eph.toes); - eph.toc = gpst2time(eph.week, tocs); - eph.ttr = raw->time; - - if (raw->outtype) { - sprintf(raw->msgtype, "SBF NavIC Decoded L-Navigation Data (PRN=%d, IODE=%d, IODC=%d, TOES=%6.0f )", prn, eph.iode, eph.iodc, eph.toes); - } + eph.week = U2(p + 4); + iodec = U1(p + 7); + eph.toes = U4(p + 8); + eph.A = pow(R8(p + 12), 2); + eph.deln = R4(p + 20) * PI; + eph.M0 = R8(p + 24) * PI; + eph.e = R8(p + 32); + eph.omg = R8(p + 40) * PI; + eph.OMG0 = R8(p + 48) * PI; + eph.OMGd = R8(p + 56) * PI; + eph.i0 = R8(p + 64) * PI; + eph.idot = R4(p + 72) * PI; + eph.cis = R4(p + 76); + eph.cic = R4(p + 80); + eph.crs = R4(p + 84); + eph.crc = R4(p + 88); + eph.cus = R4(p + 92); + eph.cuc = R4(p + 96); + tocs = U4(p + 100); + eph.f2 = R4(p + 104); + eph.f1 = R4(p + 108); + eph.f0 = R8(p + 112); + eph.tgd[0] = R4(p + 120); + eph.flag = U1(p + 124); + eph.sva = U1(p + 125); + eph.svh = U1(p + 140); + + eph.code = 0; + eph.fit = 0; + + eph.iodc = iodec; + eph.iode = iodec; + + eph.toe = gpst2time(eph.week, eph.toes); + eph.toc = gpst2time(eph.week, tocs); + eph.ttr = raw->time; + + if (raw->outtype) { + sprintf(raw->msgtype, + "SBF NavIC Decoded L-Navigation Data (PRN=%d, IODE=%d, IODC=%d, TOES=%6.0f )", prn, + eph.iode, eph.iodc, eph.toes); + } - if (!strstr(raw->opt, "-EPHALL")) { - if ((eph.iode == raw->nav.eph[sat-1].iode) && - (eph.iodc == raw->nav.eph[sat-1].iodc)) return 0; - } + if (!strstr(raw->opt, "-EPHALL")) { + if ((eph.iode == raw->nav.eph[sat - 1].iode) && (eph.iodc == raw->nav.eph[sat - 1].iodc)) + return 0; + } - eph.sat = sat; - raw->nav.eph[sat-1] = eph; - raw->ephsat = sat; - raw->ephset = 0; + eph.sat = sat; + raw->nav.eph[sat - 1] = eph; + raw->ephsat = sat; + raw->ephset = 0; - return 2; + return 2; } #endif #endif - - /* GPS Decoded Message Block */ /* decode SBF nav message for GPS (navigation data) --------------------------*/ -static int decode_gpsnav(raw_t *raw) -{ - trace(4, "SBF decode_gpsnav: len=%d\n", raw->len); +static int decode_gpsnav(raw_t *raw) { + trace(4, "SBF decode_gpsnav: len=%d\n", raw->len); - if (raw->len < 140) { - trace(2, "SBF decode_gpsnav frame length error: len=%d\n", raw->len); - return -1; - } + if (raw->len < 140) { + trace(2, "SBF decode_gpsnav frame length error: len=%d\n", raw->len); + return -1; + } - uint8_t prn = U1(raw->buff + 14); - uint8_t sat = satno(SYS_GPS, prn); + uint8_t prn = U1(raw->buff + 14); + uint8_t sat = satno(SYS_GPS, prn); - if (sat == 0) return -1; + if (sat == 0) return -1; - if (!(prn >= 1 && prn <= 37)) { - trace(2, "SBF decode_gpsnav prn error: sat=%d\n", prn); - return -1; - } + if (!(prn >= 1 && prn <= 37)) { + trace(2, "SBF decode_gpsnav prn error: sat=%d\n", prn); + return -1; + } - uint16_t week = U2(raw->buff + 12); /* WN */ - /* byte 15: reserved */ - /* byte 16-17: WN (modulo 1024) */ - eph_t eph = {0}; - eph.code = U1(raw->buff + 18); - eph.sva = U1(raw->buff + 19); /* URA */ - eph.svh = U1(raw->buff + 20); - eph.flag = U1(raw->buff + 21); - eph.iodc = U2(raw->buff + 22); - eph.iode = U1(raw->buff + 24); - uint8_t iode3 = U1(raw->buff + 25); - if (eph.iode != iode3) - trace(2, "SBF decode_gpsnav: mismatch of IODE in subframe 2 and 3: iode2=%d iode3=%d\n", - eph.iode, iode3); - eph.fit = U1(raw->buff + 26) ? 6 : 4; - /* byte 27: reserved */ - eph.tgd[0] = R4(raw->buff + 28); - uint32_t tocs = U4(raw->buff + 32); - eph.f2 = R4(raw->buff + 36); - eph.f1 = R4(raw->buff + 40); - eph.f0 = R4(raw->buff + 44); - eph.crs = R4(raw->buff + 48); - eph.deln = R4(raw->buff + 52) * PI; - eph.M0 = R8(raw->buff + 56) * PI; - eph.cuc = R4(raw->buff + 64); - eph.e = R8(raw->buff + 68); - eph.cus = R4(raw->buff + 76); - eph.A = pow(R8(raw->buff + 80), 2); - eph.toes = U4(raw->buff + 88); - eph.cic = R4(raw->buff + 92); - eph.OMG0 = R8(raw->buff + 96) * PI; - eph.cis = R4(raw->buff + 104); - eph.i0 = R8(raw->buff + 108) * PI; - eph.crc = R4(raw->buff + 116); - eph.omg = R8(raw->buff + 120) * PI; - eph.OMGd = R4(raw->buff + 128) * PI; - eph.idot = R4(raw->buff + 132) * PI; - uint16_t week_toc = adjust_WN10(week, U2(raw->buff + 136)); /* WNt_oc, modulo 1024 */ - uint16_t week_toe = adjust_WN10(week, U2(raw->buff + 138)); /* WNt_oe, modulo 1024*/ - - eph.week = adjgpsweek(week); - eph.toe = gpst2time(adjgpsweek(week_toe), eph.toes); - eph.toc = gpst2time(adjgpsweek(week_toc), tocs); - eph.ttr = raw->time; - - if (raw->outtype) { - sprintf(raw->msgtype, "SBF GPS Decoded Navigation Data (PRN=%d, IODE=%d, IODC=%d, TOES=%6.0f )", prn, eph.iode, eph.iodc, eph.toes); - } + uint16_t week = U2(raw->buff + 12); /* WN */ + /* byte 15: reserved */ + /* byte 16-17: WN (modulo 1024) */ + eph_t eph = {0}; + eph.code = U1(raw->buff + 18); + eph.sva = U1(raw->buff + 19); /* URA */ + eph.svh = U1(raw->buff + 20); + eph.flag = U1(raw->buff + 21); + eph.iodc = U2(raw->buff + 22); + eph.iode = U1(raw->buff + 24); + uint8_t iode3 = U1(raw->buff + 25); + if (eph.iode != iode3) + trace(2, "SBF decode_gpsnav: mismatch of IODE in subframe 2 and 3: iode2=%d iode3=%d\n", + eph.iode, iode3); + eph.fit = U1(raw->buff + 26) ? 6 : 4; + /* byte 27: reserved */ + eph.tgd[0] = R4(raw->buff + 28); + uint32_t tocs = U4(raw->buff + 32); + eph.f2 = R4(raw->buff + 36); + eph.f1 = R4(raw->buff + 40); + eph.f0 = R4(raw->buff + 44); + eph.crs = R4(raw->buff + 48); + eph.deln = R4(raw->buff + 52) * PI; + eph.M0 = R8(raw->buff + 56) * PI; + eph.cuc = R4(raw->buff + 64); + eph.e = R8(raw->buff + 68); + eph.cus = R4(raw->buff + 76); + eph.A = pow(R8(raw->buff + 80), 2); + eph.toes = U4(raw->buff + 88); + eph.cic = R4(raw->buff + 92); + eph.OMG0 = R8(raw->buff + 96) * PI; + eph.cis = R4(raw->buff + 104); + eph.i0 = R8(raw->buff + 108) * PI; + eph.crc = R4(raw->buff + 116); + eph.omg = R8(raw->buff + 120) * PI; + eph.OMGd = R4(raw->buff + 128) * PI; + eph.idot = R4(raw->buff + 132) * PI; + uint16_t week_toc = adjust_WN10(week, U2(raw->buff + 136)); /* WNt_oc, modulo 1024 */ + uint16_t week_toe = adjust_WN10(week, U2(raw->buff + 138)); /* WNt_oe, modulo 1024*/ + + eph.week = adjgpsweek(week); + eph.toe = gpst2time(adjgpsweek(week_toe), eph.toes); + eph.toc = gpst2time(adjgpsweek(week_toc), tocs); + eph.ttr = raw->time; + + if (raw->outtype) { + sprintf(raw->msgtype, "SBF GPS Decoded Navigation Data (PRN=%d, IODE=%d, IODC=%d, TOES=%6.0f )", + prn, eph.iode, eph.iodc, eph.toes); + } - if (!strstr(raw->opt, "-EPHALL")) { - if ((eph.iode == raw->nav.eph[sat-1].iode) && - (eph.iodc == raw->nav.eph[sat-1].iodc)) return 0; - } + if (!strstr(raw->opt, "-EPHALL")) { + if ((eph.iode == raw->nav.eph[sat - 1].iode) && (eph.iodc == raw->nav.eph[sat - 1].iodc)) + return 0; + } - eph.sat = sat; - raw->nav.eph[sat-1] = eph; - raw->ephsat = sat; - raw->ephset = 0; + eph.sat = sat; + raw->nav.eph[sat - 1] = eph; + raw->ephsat = sat; + raw->ephset = 0; - return 2; + return 2; } /* decode SBF gpsalm --------------------------------------------------------*/ -static int decode_gpsalm(raw_t *raw) -{ - uint8_t *p = raw->buff+8; /* points at TOW location */ - alm_t alm; - uint16_t week; +static int decode_gpsalm(raw_t *raw) { + uint8_t *p = raw->buff + 8; /* points at TOW location */ + alm_t alm; + uint16_t week; - trace(4,"SBF decode_gpsalm: len=%d\n", raw->len); + trace(4, "SBF decode_gpsalm: len=%d\n", raw->len); - if (raw->len < 60) - { - trace(1, "SBF decode_gpsalm: Block too short\n"); - return -1; - } + if (raw->len < 60) { + trace(1, "SBF decode_gpsalm: Block too short\n"); + return -1; + } - week = U2(p + 4); - alm.sat = satno(SYS_GPS, U1(p + 6)); - /* byte 7: reserved */ - alm.e = R4(p + 8); - alm.toas = U4(p + 12); - alm.i0 = R4(p + 16); - alm.OMGd = R4(p + 20); - alm.A = pow(R4(p + 24),2); - alm.OMG0 = R4(p + 28); - alm.omg = R4(p + 32); - alm.M0 = R4(p + 36); - alm.f1 = R4(p + 40); - alm.f0 = R4(p + 44); - alm.week = adjust_WN8(week, U1(p + 48)); - alm.svconf= U1(p + 49); - alm.svh = U1(p + 50); /* 8 bit health */ - /* byte 51: health summary on 6 bits (from subframe 4, page 25 and sub-frame 5 page 25) */ - - if (alm.sat == 0) return -1; - - alm.toa = gpst2time(alm.week, alm.toas); - - raw->nav.alm[alm.sat-1] = alm; - - if (raw->outtype) { - sprintf(raw->msgtype,"SBF GPS Almanach (PRN=%d)", U1(p + 6)); - } + week = U2(p + 4); + alm.sat = satno(SYS_GPS, U1(p + 6)); + /* byte 7: reserved */ + alm.e = R4(p + 8); + alm.toas = U4(p + 12); + alm.i0 = R4(p + 16); + alm.OMGd = R4(p + 20); + alm.A = pow(R4(p + 24), 2); + alm.OMG0 = R4(p + 28); + alm.omg = R4(p + 32); + alm.M0 = R4(p + 36); + alm.f1 = R4(p + 40); + alm.f0 = R4(p + 44); + alm.week = adjust_WN8(week, U1(p + 48)); + alm.svconf = U1(p + 49); + alm.svh = U1(p + 50); /* 8 bit health */ + /* byte 51: health summary on 6 bits (from subframe 4, page 25 and sub-frame 5 page 25) */ + + if (alm.sat == 0) return -1; + + alm.toa = gpst2time(alm.week, alm.toas); + + raw->nav.alm[alm.sat - 1] = alm; + + if (raw->outtype) { + sprintf(raw->msgtype, "SBF GPS Almanach (PRN=%d)", U1(p + 6)); + } - return 9; + return 9; } /* decode SBF gpsion --------------------------------------------------------*/ -static int decode_gpsion(raw_t *raw){ - uint8_t *p = raw->buff+8; /* points at TOW location */ +static int decode_gpsion(raw_t *raw) { + uint8_t *p = raw->buff + 8; /* points at TOW location */ - trace(4,"SBF decode_gpsion: len=%d\n", raw->len); + trace(4, "SBF decode_gpsion: len=%d\n", raw->len); - if (raw->len < 48) - { - trace(1,"SBF decode_gpsion: Block too short\n"); - return -1; - } + if (raw->len < 48) { + trace(1, "SBF decode_gpsion: Block too short\n"); + return -1; + } - raw->nav.ion_gps[0] = R4(p + 8); /* alpha_0 */ - raw->nav.ion_gps[1] = R4(p + 12); /* alpha_1 */ - raw->nav.ion_gps[2] = R4(p + 16); /* alpha_2 */ - raw->nav.ion_gps[3] = R4(p + 20); /* alpha_3 */ - raw->nav.ion_gps[4] = R4(p + 24); /* beta_0 */ - raw->nav.ion_gps[5] = R4(p + 28); /* beta_1 */ - raw->nav.ion_gps[6] = R4(p + 32); /* beta_2 */ - raw->nav.ion_gps[7] = R4(p + 36); /* beta_3 */ - - if (raw->outtype) { - sprintf(raw->msgtype,"SBF GPS Ionospheric Data"); - } + raw->nav.ion_gps[0] = R4(p + 8); /* alpha_0 */ + raw->nav.ion_gps[1] = R4(p + 12); /* alpha_1 */ + raw->nav.ion_gps[2] = R4(p + 16); /* alpha_2 */ + raw->nav.ion_gps[3] = R4(p + 20); /* alpha_3 */ + raw->nav.ion_gps[4] = R4(p + 24); /* beta_0 */ + raw->nav.ion_gps[5] = R4(p + 28); /* beta_1 */ + raw->nav.ion_gps[6] = R4(p + 32); /* beta_2 */ + raw->nav.ion_gps[7] = R4(p + 36); /* beta_3 */ + + if (raw->outtype) { + sprintf(raw->msgtype, "SBF GPS Ionospheric Data"); + } - return 9; + return 9; } /* decode SBF gpsutc --------------------------------------------------------*/ -static int decode_gpsutc(raw_t *raw) -{ - uint8_t *p = raw->buff+8; /* points at TOW location */ - uint16_t week; +static int decode_gpsutc(raw_t *raw) { + uint8_t *p = raw->buff + 8; /* points at TOW location */ + uint16_t week; - trace(4,"SBF decode_gpsutc: len=%d\n", raw->len); + trace(4, "SBF decode_gpsutc: len=%d\n", raw->len); - if (raw->len < 37) - { - trace(1, "SBF decode_gpsutc: Block too short\n"); - return -1; - } + if (raw->len < 37) { + trace(1, "SBF decode_gpsutc: Block too short\n"); + return -1; + } - week = U2(p + 4); - /* GPS delta-UTC parameters */ - raw->nav.utc_gps[1] = R4(p + 8); /* A1 */ - raw->nav.utc_gps[0] = R8(p + 12); /* A0 */ - raw->nav.utc_gps[2] = U4(p + 20); /* tot */ - raw->nav.utc_gps[3] = adjust_WN8(week, U1(p + 24)); /* WNt */ - raw->nav.utc_gps[4] = I1(p + 25); /* DEL_t_LS */ - raw->nav.utc_gps[5] = adjust_WN8(week, U1(p + 26)); /* WN_LSF */ - raw->nav.utc_gps[6] = U1(p + 27); /* DN */ - raw->nav.utc_gps[7] = I1(p + 28); /* DEL_t_LSF */ - - if (raw->outtype) { - sprintf(raw->msgtype, "SBF GPS UTC Offsets"); - } + week = U2(p + 4); + /* GPS delta-UTC parameters */ + raw->nav.utc_gps[1] = R4(p + 8); /* A1 */ + raw->nav.utc_gps[0] = R8(p + 12); /* A0 */ + raw->nav.utc_gps[2] = U4(p + 20); /* tot */ + raw->nav.utc_gps[3] = adjust_WN8(week, U1(p + 24)); /* WNt */ + raw->nav.utc_gps[4] = I1(p + 25); /* DEL_t_LS */ + raw->nav.utc_gps[5] = adjust_WN8(week, U1(p + 26)); /* WN_LSF */ + raw->nav.utc_gps[6] = U1(p + 27); /* DN */ + raw->nav.utc_gps[7] = I1(p + 28); /* DEL_t_LSF */ + + if (raw->outtype) { + sprintf(raw->msgtype, "SBF GPS UTC Offsets"); + } - return 9; + return 9; } /* decode SBF cnav message for GPS (navigation data) --------------------------*/ -static int decode_gpscnav(raw_t *raw, uint32_t sbf_id) -{ - uint8_t *p = raw->buff+8; /* points at TOW location */ - eph_t eph = {0}; - uint32_t tocs, tops; - uint8_t prn, sat; +static int decode_gpscnav(raw_t *raw, uint32_t sbf_id) { + uint8_t *p = raw->buff + 8; /* points at TOW location */ + eph_t eph = {0}; + uint32_t tocs, tops; + uint8_t prn, sat; - trace(4, "SBF decode_gpscnav: len=%d\n", raw->len); + trace(4, "SBF decode_gpscnav: len=%d\n", raw->len); - if (raw->len < 172) { - trace(2, "SBF decode_gpscnav frame length error: len=%d\n", raw->len); - return -1; - } + if (raw->len < 172) { + trace(2, "SBF decode_gpscnav frame length error: len=%d\n", raw->len); + return -1; + } - prn = U1(p+6); - sat = satno(SYS_GPS, prn); + prn = U1(p + 6); + sat = satno(SYS_GPS, prn); - if (sat == 0) return -1; + if (sat == 0) return -1; - if (!(prn>=1 && prn<=37)){ - trace(2, "SBF decode_gpscnav prn error: sat=%d\n", prn); - return -1; - } + if (!(prn >= 1 && prn <= 37)) { + trace(2, "SBF decode_gpscnav prn error: sat=%d\n", prn); + return -1; + } - eph.code = 0; - eph.flag = U1(p + 7); - eph.week = U2(p + 8); - eph.svh = U1(p + 10); - eph.sva = I1(p + 11); /* URA */ - tops = U4(p + 12); - eph.toes = U4(p + 16); - eph.A = R8(p + 20); - eph.Adot = R8(p + 28); - eph.deln = R4(p + 36) * PI; - eph.ndot = R4(p + 40); - eph.M0 = R8(p + 44) * PI; - eph.e = R8(p + 52); - eph.omg = R8(p + 60) * PI; - eph.OMG0 = R8(p + 68) * PI; - eph.OMGd = R8(p + 76) * PI; - eph.i0 = R8(p + 84) * PI; - eph.idot = R4(p + 92) * PI; - eph.cis = R4(p + 96); - eph.cic = R4(p + 100); - eph.crs = R4(p + 104); - eph.crc = R4(p + 108); - eph.cus = R4(p + 112); - eph.cuc = R4(p + 116); - tocs = U4(p + 120); - /* byte 124: URA_NED0 */ - /* byte 125: URA_NED1 */ - /* byte 126: URA_NED2 */ - /* byte 127: WN_op */ - eph.f2 = R4(p + 128); - eph.f1 = R4(p + 132); - eph.f0 = R8(p + 136); - if (sbf_id == ID_GPSCNAV) { - if (R4(p + 144) != -2.e10) - eph.tgd[0] = R4(p + 144); - /* 144-147: ISC_L1CA */ - /* 148-151: ISC_L2C */ - /* 152-155: ISC_L5I5 */ - /* 156-159: ISC_L5Q5 */ - } else if (sbf_id == ID_GPSCNAV2) { - /* 144-147: ISC_L1CP */ - /* 148-151: ISC_L1CD */ - /* 152-155: ISC_L1CA */ - /* 156-159: ISC_L2C */ - /* 160-163: ISC_L5Q5 */ - /* 164-167: ISC_L5Q5 */ - } - eph.fit = 0; + eph.code = 0; + eph.flag = U1(p + 7); + eph.week = U2(p + 8); + eph.svh = U1(p + 10); + eph.sva = I1(p + 11); /* URA */ + tops = U4(p + 12); + eph.toes = U4(p + 16); + eph.A = R8(p + 20); + eph.Adot = R8(p + 28); + eph.deln = R4(p + 36) * PI; + eph.ndot = R4(p + 40); + eph.M0 = R8(p + 44) * PI; + eph.e = R8(p + 52); + eph.omg = R8(p + 60) * PI; + eph.OMG0 = R8(p + 68) * PI; + eph.OMGd = R8(p + 76) * PI; + eph.i0 = R8(p + 84) * PI; + eph.idot = R4(p + 92) * PI; + eph.cis = R4(p + 96); + eph.cic = R4(p + 100); + eph.crs = R4(p + 104); + eph.crc = R4(p + 108); + eph.cus = R4(p + 112); + eph.cuc = R4(p + 116); + tocs = U4(p + 120); + /* byte 124: URA_NED0 */ + /* byte 125: URA_NED1 */ + /* byte 126: URA_NED2 */ + /* byte 127: WN_op */ + eph.f2 = R4(p + 128); + eph.f1 = R4(p + 132); + eph.f0 = R8(p + 136); + if (sbf_id == ID_GPSCNAV) { + if (R4(p + 144) != -2.e10) eph.tgd[0] = R4(p + 144); + /* 144-147: ISC_L1CA */ + /* 148-151: ISC_L2C */ + /* 152-155: ISC_L5I5 */ + /* 156-159: ISC_L5Q5 */ + } else if (sbf_id == ID_GPSCNAV2) { + /* 144-147: ISC_L1CP */ + /* 148-151: ISC_L1CD */ + /* 152-155: ISC_L1CA */ + /* 156-159: ISC_L2C */ + /* 160-163: ISC_L5Q5 */ + /* 164-167: ISC_L5Q5 */ + } + eph.fit = 0; - eph.iodc = tops; // IODC/IODE is not present in CNAV, use t_op instead - eph.iode = tops; + eph.iodc = tops; // IODC/IODE is not present in CNAV, use t_op instead + eph.iode = tops; - eph.toe = gpst2time(eph.week, eph.toes); - eph.toc = gpst2time(eph.week, tocs); - eph.ttr = raw->time; + eph.toe = gpst2time(eph.week, eph.toes); + eph.toc = gpst2time(eph.week, tocs); + eph.ttr = raw->time; - if (raw->outtype) { - sprintf(raw->msgtype, "SBF GPS Decoded C-Navigation Data (PRN=%d, IODE=%d, IODC=%d, TOES=%6.0f )", prn, eph.iode, eph.iodc, eph.toes); - } + if (raw->outtype) { + sprintf(raw->msgtype, + "SBF GPS Decoded C-Navigation Data (PRN=%d, IODE=%d, IODC=%d, TOES=%6.0f )", prn, + eph.iode, eph.iodc, eph.toes); + } - if (!strstr(raw->opt, "-EPHALL")) { - if ((eph.iode == raw->nav.eph[sat-1].iode) && - (eph.iodc == raw->nav.eph[sat-1].iodc)) return 0; - } + if (!strstr(raw->opt, "-EPHALL")) { + if ((eph.iode == raw->nav.eph[sat - 1].iode) && (eph.iodc == raw->nav.eph[sat - 1].iodc)) + return 0; + } - eph.sat = sat; - raw->nav.eph[sat-1] = eph; - raw->ephsat = sat; - raw->ephset = 0; + eph.sat = sat; + raw->nav.eph[sat - 1] = eph; + raw->ephsat = sat; + raw->ephset = 0; - return 2; + return 2; } - /* GLONASS Decoded Message Blocks */ /* decode SBF nav message for glonass (navigation data) ----------------------*/ -static int decode_glonav(raw_t *raw){ - - uint8_t *p = raw->buff+8; /* points at TOW location */ - geph_t eph = {0}; - int prn, sat; - uint16_t week_toes; - uint32_t toes; +static int decode_glonav(raw_t *raw) { + uint8_t *p = raw->buff + 8; /* points at TOW location */ + geph_t eph = {0}; + int prn, sat; + uint16_t week_toes; + uint32_t toes; - trace(4, "SBF decode_glonav: len=%d\n", raw->len); + trace(4, "SBF decode_glonav: len=%d\n", raw->len); - if (raw->len < 96) { - trace(2, "SBF decode_glonav frame length error: len=%d\n", raw->len); - return -1; - } - prn = U1(p+6)-37; - sat = satno(SYS_GLO, prn); + if (raw->len < 96) { + trace(2, "SBF decode_glonav frame length error: len=%d\n", raw->len); + return -1; + } + prn = U1(p + 6) - 37; + sat = satno(SYS_GLO, prn); - if (sat == 0) return -1; + if (sat == 0) return -1; - if (!(prn>=1 && prn<=24)){ - trace(2, "SBF decode_glonav prn error: sat=%d\n", prn); - return -1; - } + if (!(prn >= 1 && prn <= 24)) { + trace(2, "SBF decode_glonav prn error: sat=%d\n", prn); + return -1; + } - double tow = U4(p + 0) * 0.001; - uint16_t week = U2(p + 4); - eph.frq = U1(p + 7) - 8; - eph.pos[0] = R8(p + 8) * 1000; - eph.pos[1] = R8(p + 16) * 1000; - eph.pos[2] = R8(p + 24) * 1000; - eph.vel[0] = R4(p + 32) * 1000.0; - eph.vel[1] = R4(p + 36) * 1000.0; - eph.vel[2] = R4(p + 40) * 1000.0; - eph.acc[0] = R4(p + 44) * 1000.0; - eph.acc[1] = R4(p + 48) * 1000.0; - eph.acc[2] = R4(p + 52) * 1000.0; - eph.gamn = R4(p + 56); - eph.taun = R4(p + 60); - eph.dtaun = R4(p + 64); - toes = U4(p + 68); - week_toes = adjust_WN10(week, U2(p + 72)); /* WN_toe modulo 1024 */ - /* byte 74: P1, time interval between adjacent values of t_b */ - /* byte 75: P2, 1-bit odd/eent flag of t_b */ - eph.age = U1(p + 76); - eph.svh = U1(p + 77) >> 2; /* 3-bit health flag, satellite unhealthy if MSB set */ - eph.iode = U2(p + 78); - /* byte 80: M, 2-bit GLONASS-M satellite identifier (01, otherwise 00) */ - /* byte 81: P, 2-bit mode of computation of time parameters */ - /* byte 82: l, 1-bit health flag, 0=healthy, 1=unhealthy */ - /* byte 83: P4, 1-bit ’updated’ flag of ephemeris data */ - /* byte 84-85: N_T, 1-bit current day number within 4-year interval */ - eph.sva = U2(p + 86); - - eph.tof = gpst2time(week, tow); - eph.toe = gpst2time(week_toes, toes); - - if (raw->outtype) { - sprintf(raw->msgtype, "SBF GLONASS Decoded Navigation Data (PRN=%d, Frequency Number=%d IODE=%d, AGE=%d )", prn, eph.frq, eph.iode, eph.age); - } + double tow = U4(p + 0) * 0.001; + uint16_t week = U2(p + 4); + eph.frq = U1(p + 7) - 8; + eph.pos[0] = R8(p + 8) * 1000; + eph.pos[1] = R8(p + 16) * 1000; + eph.pos[2] = R8(p + 24) * 1000; + eph.vel[0] = R4(p + 32) * 1000.0; + eph.vel[1] = R4(p + 36) * 1000.0; + eph.vel[2] = R4(p + 40) * 1000.0; + eph.acc[0] = R4(p + 44) * 1000.0; + eph.acc[1] = R4(p + 48) * 1000.0; + eph.acc[2] = R4(p + 52) * 1000.0; + eph.gamn = R4(p + 56); + eph.taun = R4(p + 60); + eph.dtaun = R4(p + 64); + toes = U4(p + 68); + week_toes = adjust_WN10(week, U2(p + 72)); /* WN_toe modulo 1024 */ + /* byte 74: P1, time interval between adjacent values of t_b */ + /* byte 75: P2, 1-bit odd/eent flag of t_b */ + eph.age = U1(p + 76); + eph.svh = U1(p + 77) >> 2; /* 3-bit health flag, satellite unhealthy if MSB set */ + eph.iode = U2(p + 78); + /* byte 80: M, 2-bit GLONASS-M satellite identifier (01, otherwise 00) */ + /* byte 81: P, 2-bit mode of computation of time parameters */ + /* byte 82: l, 1-bit health flag, 0=healthy, 1=unhealthy */ + /* byte 83: P4, 1-bit ’updated’ flag of ephemeris data */ + /* byte 84-85: N_T, 1-bit current day number within 4-year interval */ + eph.sva = U2(p + 86); + + eph.tof = gpst2time(week, tow); + eph.toe = gpst2time(week_toes, toes); + + if (raw->outtype) { + sprintf(raw->msgtype, + "SBF GLONASS Decoded Navigation Data (PRN=%d, Frequency Number=%d IODE=%d, AGE=%d )", + prn, eph.frq, eph.iode, eph.age); + } - if (!strstr(raw->opt, "-EPHALL")) { - if (eph.iode == raw->nav.geph[prn-1].iode) return 0; - } + if (!strstr(raw->opt, "-EPHALL")) { + if (eph.iode == raw->nav.geph[prn - 1].iode) return 0; + } - eph.sat = sat; - raw->nav.geph[prn-1] = eph; - raw->ephsat = sat; - raw->ephset = 0; - raw->nav.glo_fcn[prn-1] = eph.frq + 8; /* save frequency number */ + eph.sat = sat; + raw->nav.geph[prn - 1] = eph; + raw->ephsat = sat; + raw->ephset = 0; + raw->nav.glo_fcn[prn - 1] = eph.frq + 8; /* save frequency number */ - return 2; + return 2; } /* decode SBF gloutc --------------------------------------------------------*/ -static int decode_gloutc(raw_t *raw) -{ - uint8_t *p = raw->buff+8; /* points at TOW location */ +static int decode_gloutc(raw_t *raw) { + uint8_t *p = raw->buff + 8; /* points at TOW location */ - trace(4, "SBF decode_gloutc: len=%d\n", raw->len); + trace(4, "SBF decode_gloutc: len=%d\n", raw->len); - if (raw->len<40) - { - trace(1, "SBF decode_gloutc: Block too short\n"); - return -1; - } + if (raw->len < 40) { + trace(1, "SBF decode_gloutc: Block too short\n"); + return -1; + } - /* GPS delta-UTC parameters */ + /* GPS delta-UTC parameters */ - /* byte 8: N_4: 4 year interval number, starting from 1996 */ - /* byte 9: KP: notification of leap second */ - /* byte 10-11: N: calendar day number within 4 year period */ - raw->nav.utc_glo[1] = R4(p + 12); /* tau_GPS */ - raw->nav.utc_glo[0] = R8(p + 16); /* tau_c */ - raw->nav.utc_glo[2] = U4(p + 24); /* B1 */ - raw->nav.utc_glo[3] = R4(p + 28); /* B2 */ + /* byte 8: N_4: 4 year interval number, starting from 1996 */ + /* byte 9: KP: notification of leap second */ + /* byte 10-11: N: calendar day number within 4 year period */ + raw->nav.utc_glo[1] = R4(p + 12); /* tau_GPS */ + raw->nav.utc_glo[0] = R8(p + 16); /* tau_c */ + raw->nav.utc_glo[2] = U4(p + 24); /* B1 */ + raw->nav.utc_glo[3] = R4(p + 28); /* B2 */ - if (raw->outtype) { - sprintf(raw->msgtype, "SBF GLONASS UTC Offsets"); - } + if (raw->outtype) { + sprintf(raw->msgtype, "SBF GLONASS UTC Offsets"); + } - return 9; + return 9; } - /* Galileo Decoded Message Blocks */ /* decode SBF nav message for Galileo (navigation data) --------------------------*/ -static int decode_galnav(raw_t *raw){ - - uint8_t *p = raw->buff+8; /* points at TOW location */ - eph_t eph = {0}; - uint32_t tocs; - int prn, sat; - uint16_t week_toe, week_toc; +static int decode_galnav(raw_t *raw) { + uint8_t *p = raw->buff + 8; /* points at TOW location */ + eph_t eph = {0}; + uint32_t tocs; + int prn, sat; + uint16_t week_toe, week_toc; - trace(4, "SBF decode_galnav: len=%d\n", raw->len); + trace(4, "SBF decode_galnav: len=%d\n", raw->len); - if (raw->len < 149) { - trace(2, "SBF decode_galnav frame length error: len=%d\n", raw->len); - return -1; - } + if (raw->len < 149) { + trace(2, "SBF decode_galnav frame length error: len=%d\n", raw->len); + return -1; + } - prn = U1(p+6)-70; - sat = satno(SYS_GAL, prn); + prn = U1(p + 6) - 70; + sat = satno(SYS_GAL, prn); - if (sat == 0) return -1; + if (sat == 0) return -1; - if (!(prn>=1 && prn<=36)){ - trace(2, "SBF decode_galnav prn error: sat=%d\n", prn); - return -1; - } + if (!(prn >= 1 && prn <= 36)) { + trace(2, "SBF decode_galnav prn error: sat=%d\n", prn); + return -1; + } - double tow = U4(p + 0) * 0.001; - eph.week = U2(p + 4); /* GAL week number */ - /* byte 6: satellite id, see above */ - int code = U1(p + 7); /* 2:INAV, 16:FNAV */ - if (code != 2 && code != 16) { - trace(2, "SBF decode_galnav code error: sat=%d code=%d\n", prn, code); - return -1; - } - eph.code = code == 2 ? (1 << 0 ) | (1 << 2) | (1 << 9) : (1 << 1) | (1 << 8); - eph.A = pow(R8(p + 8), 2); - eph.M0 = R8(p + 16) * PI; - eph.e = R8(p + 24); - eph.i0 = R8(p + 32) * PI; - eph.omg = R8(p + 40) * PI; - eph.OMG0 = R8(p + 48) * PI; - eph.OMGd = R4(p + 56) * PI; - eph.idot = R4(p + 60) * PI; - eph.deln = R4(p + 64) * PI; - eph.cuc = R4(p + 68); - eph.cus = R4(p + 72); - eph.crc = R4(p + 76); - eph.crs = R4(p + 80); - eph.cic = R4(p + 84); - eph.cis = R4(p + 88); - eph.toes = U4(p + 92); - tocs = U4(p + 96); - eph.f2 = R4(p + 100); - eph.f1 = R4(p + 104); - eph.f0 = R8(p + 108); - week_toe = adjust_WN12(eph.week, U2(p + 116)); /* WNt_oc */ - week_toc = adjust_WN12(eph.week, U2(p + 118)); - eph.iode = U2(p + 120); - eph.iodc = 0; - - uint16_t health = U2(p + 122); - int svh = 0; - if (health & 0x001) - svh |= (health >> 1) & 7; // L1B when code==2 - if (health & 0x010) - svh |= ((health >> 5) & 7) << 6; // L5B when code==2 - if (health & 0x100) - svh |= ((health >> 9) & 7) << 3; // L5A when code==16 - eph.svh = svh; - /* byte 124: Health_PRS, reserved */ - uint8_t sva = U1(p + (code == 2 ? 126 : 125)); - eph.sva = sva == 255 ? 0 : sva; - /* byte 127: SISA_L1AE6A, reserved */ - if (R4(p + 128) != -2.e10) - eph.tgd[0] = R4(p + 128); - if (R4(p + 132) != -2.e10) - eph.tgd[1] = R4(p + 132); - /* byte 136-139: BGD_L1AE6A, reserved */ - eph.fit = 0; - /* byte 140: CNAVenc: 2-bit C/NAV encryption status */ - - eph.toe = gpst2time(week_toe, eph.toes); - eph.toc = gpst2time(week_toc, tocs); - eph.ttr = gpst2time(eph.week, tow); - - if (raw->outtype) { - sprintf(raw->msgtype, "SBF Galileo Decoded Navigation Data (PRN=%d, IODE=%d, IODC=%d, TOES=%6.0f )", prn, eph.iode, eph.iodc, eph.toes); - } + double tow = U4(p + 0) * 0.001; + eph.week = U2(p + 4); /* GAL week number */ + /* byte 6: satellite id, see above */ + int code = U1(p + 7); /* 2:INAV, 16:FNAV */ + if (code != 2 && code != 16) { + trace(2, "SBF decode_galnav code error: sat=%d code=%d\n", prn, code); + return -1; + } + eph.code = code == 2 ? (1 << 0) | (1 << 2) | (1 << 9) : (1 << 1) | (1 << 8); + eph.A = pow(R8(p + 8), 2); + eph.M0 = R8(p + 16) * PI; + eph.e = R8(p + 24); + eph.i0 = R8(p + 32) * PI; + eph.omg = R8(p + 40) * PI; + eph.OMG0 = R8(p + 48) * PI; + eph.OMGd = R4(p + 56) * PI; + eph.idot = R4(p + 60) * PI; + eph.deln = R4(p + 64) * PI; + eph.cuc = R4(p + 68); + eph.cus = R4(p + 72); + eph.crc = R4(p + 76); + eph.crs = R4(p + 80); + eph.cic = R4(p + 84); + eph.cis = R4(p + 88); + eph.toes = U4(p + 92); + tocs = U4(p + 96); + eph.f2 = R4(p + 100); + eph.f1 = R4(p + 104); + eph.f0 = R8(p + 108); + week_toe = adjust_WN12(eph.week, U2(p + 116)); /* WNt_oc */ + week_toc = adjust_WN12(eph.week, U2(p + 118)); + eph.iode = U2(p + 120); + eph.iodc = 0; + + uint16_t health = U2(p + 122); + int svh = 0; + if (health & 0x001) svh |= (health >> 1) & 7; // L1B when code==2 + if (health & 0x010) svh |= ((health >> 5) & 7) << 6; // L5B when code==2 + if (health & 0x100) svh |= ((health >> 9) & 7) << 3; // L5A when code==16 + eph.svh = svh; + /* byte 124: Health_PRS, reserved */ + uint8_t sva = U1(p + (code == 2 ? 126 : 125)); + eph.sva = sva == 255 ? 0 : sva; + /* byte 127: SISA_L1AE6A, reserved */ + if (R4(p + 128) != -2.e10) eph.tgd[0] = R4(p + 128); + if (R4(p + 132) != -2.e10) eph.tgd[1] = R4(p + 132); + /* byte 136-139: BGD_L1AE6A, reserved */ + eph.fit = 0; + /* byte 140: CNAVenc: 2-bit C/NAV encryption status */ + + eph.toe = gpst2time(week_toe, eph.toes); + eph.toc = gpst2time(week_toc, tocs); + eph.ttr = gpst2time(eph.week, tow); + + if (raw->outtype) { + sprintf(raw->msgtype, + "SBF Galileo Decoded Navigation Data (PRN=%d, IODE=%d, IODC=%d, TOES=%6.0f )", prn, + eph.iode, eph.iodc, eph.toes); + } - if (!strstr(raw->opt, "-EPHALL")) { - if (eph.iode == raw->nav.eph[sat-1].iode) return 0; - } + if (!strstr(raw->opt, "-EPHALL")) { + if (eph.iode == raw->nav.eph[sat - 1].iode) return 0; + } - eph.sat = sat; - raw->nav.eph[sat-1] = eph; - raw->ephsat = sat; - raw->ephset = 0; + eph.sat = sat; + raw->nav.eph[sat - 1] = eph; + raw->ephsat = sat; + raw->ephset = 0; - return 2; + return 2; } /* decode SBF galalm --------------------------------------------------------*/ -static int decode_galalm(raw_t *raw) -{ - uint8_t *p = raw->buff+8; /* points at TOW location */ - alm_t alm; - uint16_t week, health; +static int decode_galalm(raw_t *raw) { + uint8_t *p = raw->buff + 8; /* points at TOW location */ + alm_t alm; + uint16_t week, health; - trace(4, "SBF decode_galalm: len=%d\n", raw->len); + trace(4, "SBF decode_galalm: len=%d\n", raw->len); - if (raw->len<61) - { - trace(1, "SBF decode_galalm: Block too short\n"); - return -1; - } + if (raw->len < 61) { + trace(1, "SBF decode_galalm: Block too short\n"); + return -1; + } - week = U2(p + 4); - alm.e = R4(p + 8); - alm.toas = U4(p + 12); - alm.i0 = R4(p + 16) + 0.3; /* TODO: is this offset right? */ - alm.OMGd = R4(p + 20); - alm.A = pow(R4(p + 24), 2); - alm.OMG0 = R4(p + 28); - alm.omg = R4(p + 32); - alm.M0 = R4(p + 36); - alm.f1 = R4(p + 40); - alm.f0 = R4(p + 44); - alm.week = week + U1(p + 48); - alm.sat = satno(SYS_GAL, U1(p + 49) - 70); - health = U2(p + 50); - if (health & 0x01) health &= ~0x007; - if (health & 0x08) health &= ~0x038; - if (health & 0x40) health &= ~0x1B0; - alm.svh = health; - - alm.toa = gpst2time(alm.week, alm.toas); - alm.svconf= 0; - /* byte 51: IODa, 4-bit Issue of Data for the almanac */ - - if (alm.sat == 0) return -1; - raw->nav.alm[alm.sat-1] = alm; - - if (raw->outtype) { - sprintf(raw->msgtype, "SBF Galileo Almanach (PRN=%d)", U1(p + 49) - 70); - } + week = U2(p + 4); + alm.e = R4(p + 8); + alm.toas = U4(p + 12); + alm.i0 = R4(p + 16) + 0.3; /* TODO: is this offset right? */ + alm.OMGd = R4(p + 20); + alm.A = pow(R4(p + 24), 2); + alm.OMG0 = R4(p + 28); + alm.omg = R4(p + 32); + alm.M0 = R4(p + 36); + alm.f1 = R4(p + 40); + alm.f0 = R4(p + 44); + alm.week = week + U1(p + 48); + alm.sat = satno(SYS_GAL, U1(p + 49) - 70); + health = U2(p + 50); + if (health & 0x01) health &= ~0x007; + if (health & 0x08) health &= ~0x038; + if (health & 0x40) health &= ~0x1B0; + alm.svh = health; + + alm.toa = gpst2time(alm.week, alm.toas); + alm.svconf = 0; + /* byte 51: IODa, 4-bit Issue of Data for the almanac */ + + if (alm.sat == 0) return -1; + raw->nav.alm[alm.sat - 1] = alm; + + if (raw->outtype) { + sprintf(raw->msgtype, "SBF Galileo Almanach (PRN=%d)", U1(p + 49) - 70); + } - return 9; + return 9; } /* decode SBF galion --------------------------------------------------------*/ -static int decode_galion(raw_t *raw){ - uint8_t *p = raw->buff+8; /* points at TOW location */ +static int decode_galion(raw_t *raw) { + uint8_t *p = raw->buff + 8; /* points at TOW location */ - trace(4, "SBF decode_galion: len=%d\n", raw->len); + trace(4, "SBF decode_galion: len=%d\n", raw->len); - if (raw->len<29) - { - trace(1, "SBF decode_galion: Block too short\n"); - return -1; - } + if (raw->len < 29) { + trace(1, "SBF decode_galion: Block too short\n"); + return -1; + } - raw->nav.ion_gal[0] = R4(p + 8); - raw->nav.ion_gal[1] = R4(p + 12); - raw->nav.ion_gal[2] = R4(p + 16); - raw->nav.ion_gal[3] = 0; - /* byte 20: Bit field containing the five ionospheric storm flags */ + raw->nav.ion_gal[0] = R4(p + 8); + raw->nav.ion_gal[1] = R4(p + 12); + raw->nav.ion_gal[2] = R4(p + 16); + raw->nav.ion_gal[3] = 0; + /* byte 20: Bit field containing the five ionospheric storm flags */ - if (raw->outtype) { - sprintf(raw->msgtype, "SBF Galileo Ionospheric Data"); - } + if (raw->outtype) { + sprintf(raw->msgtype, "SBF Galileo Ionospheric Data"); + } - return 9; + return 9; } /* decode SBF galutc --------------------------------------------------------*/ -static int decode_galutc(raw_t *raw) -{ - uint8_t *p = raw->buff+8; /* points at TOW location */ - uint16_t week; +static int decode_galutc(raw_t *raw) { + uint8_t *p = raw->buff + 8; /* points at TOW location */ + uint16_t week; - trace(4, "SBF decode_galutc: len=%d\n", raw->len); + trace(4, "SBF decode_galutc: len=%d\n", raw->len); - if (raw->len<37) - { - trace(1, "SBF decode_galutc: Block too short\n"); - return -1; - } + if (raw->len < 37) { + trace(1, "SBF decode_galutc: Block too short\n"); + return -1; + } - /* Galileo delta-UTC parameters */ - week = U2(p + 4); - raw->nav.utc_gal[1] = R4(p + 8); /* A1 */ - raw->nav.utc_gal[0] = R8(p + 12); /* A0 */ - raw->nav.utc_gal[2] = U4(p + 20); /* tot */ - raw->nav.utc_gal[3] = adjust_WN8(week, U1(p + 24)); /* WN */ - raw->nav.utc_gal[4] = I1(p + 25); /* D_tls */ - raw->nav.utc_gal[5] = adjust_WN8(week, U1(p + 26)); /* WN_LSF */ - raw->nav.utc_gal[6] = U1(p + 27); /* DN */ - raw->nav.utc_gal[7] = I1(p + 28); /* D_tlsf */ - - if (raw->outtype) { - sprintf(raw->msgtype, "SBF Galileo UTC Offsets"); - } + /* Galileo delta-UTC parameters */ + week = U2(p + 4); + raw->nav.utc_gal[1] = R4(p + 8); /* A1 */ + raw->nav.utc_gal[0] = R8(p + 12); /* A0 */ + raw->nav.utc_gal[2] = U4(p + 20); /* tot */ + raw->nav.utc_gal[3] = adjust_WN8(week, U1(p + 24)); /* WN */ + raw->nav.utc_gal[4] = I1(p + 25); /* D_tls */ + raw->nav.utc_gal[5] = adjust_WN8(week, U1(p + 26)); /* WN_LSF */ + raw->nav.utc_gal[6] = U1(p + 27); /* DN */ + raw->nav.utc_gal[7] = I1(p + 28); /* D_tlsf */ + + if (raw->outtype) { + sprintf(raw->msgtype, "SBF Galileo UTC Offsets"); + } - return 9; + return 9; } /* BeiDou Decoded Message Blocks */ /* decode SBF nav message for Compass/Beidou (navigation data) --------------------------*/ -static int decode_cmpnav(raw_t *raw) -{ - trace(4, "SBF decode_cmpnav: len=%d\n", raw->len); +static int decode_cmpnav(raw_t *raw) { + trace(4, "SBF decode_cmpnav: len=%d\n", raw->len); - if (raw->len < 140) { - trace(2, "SBF decode_cmpnav frame length error: len=%d\n", raw->len); - return -1; - } + if (raw->len < 140) { + trace(2, "SBF decode_cmpnav frame length error: len=%d\n", raw->len); + return -1; + } - uint8_t prn = U1(raw->buff + 14) - 140; - int sat = satno(SYS_CMP, prn); + uint8_t prn = U1(raw->buff + 14) - 140; + int sat = satno(SYS_CMP, prn); - if (sat == 0) return -1; + if (sat == 0) return -1; - if (!((prn >= 1) && (prn <= 32))) { - trace(2, "SBF decode_cmpnav prn error: sat=%d\n", prn); - return -1; - } + if (!((prn >= 1) && (prn <= 32))) { + trace(2, "SBF decode_cmpnav prn error: sat=%d\n", prn); + return -1; + } - eph_t eph = {0}; - eph.code = 0; - eph.sva = U1(raw->buff + 18); - eph.svh = U1(raw->buff + 19); - eph.iodc = U1(raw->buff + 20); - eph.iode = U1(raw->buff + 21); - /* byte 22, 23: reserved */ - eph.tgd[0] = R4(raw->buff + 24); - if (R4(raw->buff + 28) != -2.e10) eph.tgd[1] = R4(raw->buff + 28); - uint32_t tocs = U4(raw->buff + 32); // BDT - eph.f2 = R4(raw->buff + 36); - eph.f1 = R4(raw->buff + 40); - eph.f0 = R4(raw->buff + 44); - eph.crs = R4(raw->buff + 48); - eph.deln = R4(raw->buff + 52) * PI; - eph.M0 = R8(raw->buff + 56) * PI; - eph.cuc = R4(raw->buff + 64); - eph.e = R8(raw->buff + 68); - eph.cus = R4(raw->buff + 76); - eph.A = pow(R8(raw->buff + 80), 2); - eph.toes = U4(raw->buff + 88); // BDT - eph.cic = R4(raw->buff + 92); - eph.OMG0 = R8(raw->buff + 96) * PI; - eph.cis = R4(raw->buff + 104); - eph.i0 = R8(raw->buff + 108) * PI; - eph.crc = R4(raw->buff + 116); - eph.omg = R8(raw->buff + 120) * PI; - eph.OMGd = R4(raw->buff + 128) * PI; - eph.idot = R4(raw->buff + 132) * PI; - uint16_t week = U2(raw->buff + 12) - 1356; // GPS week to approx BDS week (14 sec diff) - uint16_t week_toc = adjust_WN14(week, U2(raw->buff + 136)); /* WNt_oc */ - uint16_t week_toe = adjust_WN14(week, U2(raw->buff + 138)); /* WNt_oe */ - eph.week = week_toe; - eph.fit = 0; - - eph.toe = bdt2gpst(bdt2time(week_toe, eph.toes)); // BDS to GPS - eph.toc = bdt2gpst(bdt2time(week_toc, tocs)); // BDS to GPS - eph.ttr = raw->time; - - if (raw->outtype) { - sprintf(raw->msgtype, "SBF Compass Decoded Navigation Data (PRN=%d, IODE=%d, IODC=%d, TOES=%6.0f )", prn, eph.iode, eph.iodc, eph.toes); - } + eph_t eph = {0}; + eph.code = 0; + eph.sva = U1(raw->buff + 18); + eph.svh = U1(raw->buff + 19); + eph.iodc = U1(raw->buff + 20); + eph.iode = U1(raw->buff + 21); + /* byte 22, 23: reserved */ + eph.tgd[0] = R4(raw->buff + 24); + if (R4(raw->buff + 28) != -2.e10) eph.tgd[1] = R4(raw->buff + 28); + uint32_t tocs = U4(raw->buff + 32); // BDT + eph.f2 = R4(raw->buff + 36); + eph.f1 = R4(raw->buff + 40); + eph.f0 = R4(raw->buff + 44); + eph.crs = R4(raw->buff + 48); + eph.deln = R4(raw->buff + 52) * PI; + eph.M0 = R8(raw->buff + 56) * PI; + eph.cuc = R4(raw->buff + 64); + eph.e = R8(raw->buff + 68); + eph.cus = R4(raw->buff + 76); + eph.A = pow(R8(raw->buff + 80), 2); + eph.toes = U4(raw->buff + 88); // BDT + eph.cic = R4(raw->buff + 92); + eph.OMG0 = R8(raw->buff + 96) * PI; + eph.cis = R4(raw->buff + 104); + eph.i0 = R8(raw->buff + 108) * PI; + eph.crc = R4(raw->buff + 116); + eph.omg = R8(raw->buff + 120) * PI; + eph.OMGd = R4(raw->buff + 128) * PI; + eph.idot = R4(raw->buff + 132) * PI; + uint16_t week = U2(raw->buff + 12) - 1356; // GPS week to approx BDS week (14 sec diff) + uint16_t week_toc = adjust_WN14(week, U2(raw->buff + 136)); /* WNt_oc */ + uint16_t week_toe = adjust_WN14(week, U2(raw->buff + 138)); /* WNt_oe */ + eph.week = week_toe; + eph.fit = 0; + + eph.toe = bdt2gpst(bdt2time(week_toe, eph.toes)); // BDS to GPS + eph.toc = bdt2gpst(bdt2time(week_toc, tocs)); // BDS to GPS + eph.ttr = raw->time; + + if (raw->outtype) { + sprintf(raw->msgtype, + "SBF Compass Decoded Navigation Data (PRN=%d, IODE=%d, IODC=%d, TOES=%6.0f )", prn, + eph.iode, eph.iodc, eph.toes); + } - if (!strstr(raw->opt, "-EPHALL")) { - if (eph.iode == raw->nav.eph[sat - 1].iode) return 0; - } + if (!strstr(raw->opt, "-EPHALL")) { + if (eph.iode == raw->nav.eph[sat - 1].iode) return 0; + } - eph.sat = sat; - raw->nav.eph[sat - 1] = eph; - raw->ephsat = sat; - raw->ephset = 0; + eph.sat = sat; + raw->nav.eph[sat - 1] = eph; + raw->ephsat = sat; + raw->ephset = 0; - return 2; + return 2; } /* decode SBF cnav2 message for BDS (navigation data) --------------------------*/ -static int decode_cmpcnav2(raw_t *raw, uint32_t sbf_id) -{ - uint8_t *p = raw->buff+8; /* points at TOW location */ - eph_t eph = {0}; - uint32_t tocs, tops; - uint8_t prn, sat; +static int decode_cmpcnav2(raw_t *raw, uint32_t sbf_id) { + uint8_t *p = raw->buff + 8; /* points at TOW location */ + eph_t eph = {0}; + uint32_t tocs, tops; + uint8_t prn, sat; - trace(4, "SBF decode_cmpcnav2: len=%d\n", raw->len); + trace(4, "SBF decode_cmpcnav2: len=%d\n", raw->len); - if (raw->len < 164) { - trace(2, "SBF decode_cmpcnav2 frame length error: len=%d\n", raw->len); - return -1; - } + if (raw->len < 164) { + trace(2, "SBF decode_cmpcnav2 frame length error: len=%d\n", raw->len); + return -1; + } - prn = U1(p+6); - sat = satno(SYS_CMP, prn); + prn = U1(p + 6); + sat = satno(SYS_CMP, prn); - if (sat == 0) return -1; + if (sat == 0) return -1; - if (!(prn>=1 && prn<=37)){ - trace(2, "SBF decode_cmpcnav2 prn error: sat=%d\n", prn); - return -1; - } + if (!(prn >= 1 && prn <= 37)) { + trace(2, "SBF decode_cmpcnav2 prn error: sat=%d\n", prn); + return -1; + } - eph.week = U2(p + 4); - eph.code = 0; - eph.flag = U1(p + 7); - eph.toes = U4(p + 8); - eph.A = R8(p + 12); - eph.Adot = R8(p + 20); - eph.deln = R4(p + 28) * PI; - eph.ndot = R4(p + 32); - eph.M0 = R8(p + 36) * PI; - eph.e = R8(p + 44); - eph.omg = R8(p + 52) * PI; - eph.OMG0 = R8(p + 60) * PI; - eph.OMGd = R8(p + 68) * PI; - eph.i0 = R8(p + 76) * PI; - eph.idot = R4(p + 84) * PI; - eph.cis = R4(p + 88); - eph.cic = R4(p + 92); - eph.crs = R4(p + 96); - eph.crc = R4(p + 100); - eph.cus = R4(p + 104); - eph.cuc = R4(p + 108); - tocs = U4(p + 112); - eph.f2 = R4(p + 116); - eph.f1 = R4(p + 120); - eph.f0 = R8(p + 124); - tops = U4(p + 132); - eph.sva = U1(p + 139); /* to be checked */ - eph.svh = U1(p + 140); - - if (sbf_id == ID_BDSCNAV1) { - if (R4(p + 144) != -2.e10) - eph.tgd[4] = R4(p + 144); /* ISC_B1Cd */ - if (R4(p + 148) != -2.e10) - eph.tgd[2] = R4(p + 148); /* T_GDB1Cp */ - if (R4(p + 152) != -2.e10) - eph.tgd[3] = R4(p + 152); /* T_GDB2ap */ - } else if (sbf_id == ID_BDSCNAV2) { - if (R4(p + 144) != -2.e10) - eph.tgd[5] = R4(p + 144); /* ISC_B2ad */ - if (R4(p + 148) != -2.e10) - eph.tgd[3] = R4(p + 148); /* T_GDB2ap */ - if (R4(p + 152) != -2.e10) - eph.tgd[2] = R4(p + 152); /* T_GDB1Cp */ - } else if (sbf_id == ID_BDSCNAV3) { - if (R4(p + 144) != -2.e10) - eph.tgd[1] = R4(p + 144); /* T_GDB2bI */ - } + eph.week = U2(p + 4); + eph.code = 0; + eph.flag = U1(p + 7); + eph.toes = U4(p + 8); + eph.A = R8(p + 12); + eph.Adot = R8(p + 20); + eph.deln = R4(p + 28) * PI; + eph.ndot = R4(p + 32); + eph.M0 = R8(p + 36) * PI; + eph.e = R8(p + 44); + eph.omg = R8(p + 52) * PI; + eph.OMG0 = R8(p + 60) * PI; + eph.OMGd = R8(p + 68) * PI; + eph.i0 = R8(p + 76) * PI; + eph.idot = R4(p + 84) * PI; + eph.cis = R4(p + 88); + eph.cic = R4(p + 92); + eph.crs = R4(p + 96); + eph.crc = R4(p + 100); + eph.cus = R4(p + 104); + eph.cuc = R4(p + 108); + tocs = U4(p + 112); + eph.f2 = R4(p + 116); + eph.f1 = R4(p + 120); + eph.f0 = R8(p + 124); + tops = U4(p + 132); + eph.sva = U1(p + 139); /* to be checked */ + eph.svh = U1(p + 140); + + if (sbf_id == ID_BDSCNAV1) { + if (R4(p + 144) != -2.e10) eph.tgd[4] = R4(p + 144); /* ISC_B1Cd */ + if (R4(p + 148) != -2.e10) eph.tgd[2] = R4(p + 148); /* T_GDB1Cp */ + if (R4(p + 152) != -2.e10) eph.tgd[3] = R4(p + 152); /* T_GDB2ap */ + } else if (sbf_id == ID_BDSCNAV2) { + if (R4(p + 144) != -2.e10) eph.tgd[5] = R4(p + 144); /* ISC_B2ad */ + if (R4(p + 148) != -2.e10) eph.tgd[3] = R4(p + 148); /* T_GDB2ap */ + if (R4(p + 152) != -2.e10) eph.tgd[2] = R4(p + 152); /* T_GDB1Cp */ + } else if (sbf_id == ID_BDSCNAV3) { + if (R4(p + 144) != -2.e10) eph.tgd[1] = R4(p + 144); /* T_GDB2bI */ + } - eph.fit = 0; + eph.fit = 0; - eph.iodc = tops; // IODC/IODE is not present in CNAV, use t_op instead - eph.iode = tops; + eph.iodc = tops; // IODC/IODE is not present in CNAV, use t_op instead + eph.iode = tops; - eph.toe = gpst2time(eph.week, eph.toes); - eph.toc = gpst2time(eph.week, tocs); - eph.ttr = raw->time; + eph.toe = gpst2time(eph.week, eph.toes); + eph.toc = gpst2time(eph.week, tocs); + eph.ttr = raw->time; - if (raw->outtype) { - sprintf(raw->msgtype, "SBF BDS Decoded C-Navigation 2 Data (PRN=%d, IODE=%d, IODC=%d, TOES=%6.0f )", prn, eph.iode, eph.iodc, eph.toes); - } + if (raw->outtype) { + sprintf(raw->msgtype, + "SBF BDS Decoded C-Navigation 2 Data (PRN=%d, IODE=%d, IODC=%d, TOES=%6.0f )", prn, + eph.iode, eph.iodc, eph.toes); + } - if (!strstr(raw->opt, "-EPHALL")) { - if ((eph.iode == raw->nav.eph[sat-1].iode) && - (eph.iodc == raw->nav.eph[sat-1].iodc)) return 0; - } + if (!strstr(raw->opt, "-EPHALL")) { + if ((eph.iode == raw->nav.eph[sat - 1].iode) && (eph.iodc == raw->nav.eph[sat - 1].iodc)) + return 0; + } - eph.sat = sat; - raw->nav.eph[sat-1] = eph; - raw->ephsat = sat; - raw->ephset = 0; + eph.sat = sat; + raw->nav.eph[sat - 1] = eph; + raw->ephsat = sat; + raw->ephset = 0; - return 2; + return 2; } - /* decode SBF cmpalm --------------------------------------------------------*/ -static int decode_cmpalm(raw_t *raw) -{ - uint8_t *p = raw->buff + 8; /* points at TOW location */ - alm_t alm; - uint16_t week; +static int decode_cmpalm(raw_t *raw) { + uint8_t *p = raw->buff + 8; /* points at TOW location */ + alm_t alm; + uint16_t week; - trace(4, "SBF decode_cmpalm: len=%d\n", raw->len); + trace(4, "SBF decode_cmpalm: len=%d\n", raw->len); - if (raw->len < 60) - { - trace(1, "SBF decode_cmpalm: Block too short\n"); - return -1; - } + if (raw->len < 60) { + trace(1, "SBF decode_cmpalm: Block too short\n"); + return -1; + } - week = U2(p + 4); - alm.sat = satno(SYS_CMP, U1(p + 6) - 140); - alm.week = adjust_WN8(week, U1(p + 7)); - alm.toas = U4(p + 8); - alm.A = pow(R4(p + 12), 2); - alm.e = R4(p + 16); - alm.omg = R4(p + 20); - alm.M0 = R4(p + 24); - alm.OMG0 = R4(p + 28); - alm.OMGd = R4(p + 32); - alm.i0 = R4(p + 36); - alm.f0 = R4(p + 40); - alm.f1 = R4(p + 44); - alm.svh = U2(p + 48); - alm.svconf= 0; - - alm.toa = gpst2time(alm.week, alm.toas); - - if (alm.sat == 0) return -1; - - raw->nav.alm[alm.sat-1] = alm; - - if (raw->outtype) { - sprintf(raw->msgtype, "SBF Compass Almanach (PRN=%d)", U1(p + 6)); - } + week = U2(p + 4); + alm.sat = satno(SYS_CMP, U1(p + 6) - 140); + alm.week = adjust_WN8(week, U1(p + 7)); + alm.toas = U4(p + 8); + alm.A = pow(R4(p + 12), 2); + alm.e = R4(p + 16); + alm.omg = R4(p + 20); + alm.M0 = R4(p + 24); + alm.OMG0 = R4(p + 28); + alm.OMGd = R4(p + 32); + alm.i0 = R4(p + 36); + alm.f0 = R4(p + 40); + alm.f1 = R4(p + 44); + alm.svh = U2(p + 48); + alm.svconf = 0; + + alm.toa = gpst2time(alm.week, alm.toas); + + if (alm.sat == 0) return -1; + + raw->nav.alm[alm.sat - 1] = alm; + + if (raw->outtype) { + sprintf(raw->msgtype, "SBF Compass Almanach (PRN=%d)", U1(p + 6)); + } - return 9; + return 9; } - /* decode SBF cmpion --------------------------------------------------------*/ -static int decode_cmpion(raw_t *raw){ - uint8_t *p = raw->buff+8; /* points at TOW location */ +static int decode_cmpion(raw_t *raw) { + uint8_t *p = raw->buff + 8; /* points at TOW location */ - trace(4, "SBF decode_cmpion: len=%d\n", raw->len); + trace(4, "SBF decode_cmpion: len=%d\n", raw->len); - if (raw->len < 48) - { - trace(1, "SBF decode_cmpion: Block too short\n"); - return -1; - } + if (raw->len < 48) { + trace(1, "SBF decode_cmpion: Block too short\n"); + return -1; + } - raw->nav.ion_cmp[0] = R4(p + 8); - raw->nav.ion_cmp[1] = R4(p + 12); - raw->nav.ion_cmp[2] = R4(p + 16); - raw->nav.ion_cmp[3] = R4(p + 20); - raw->nav.ion_cmp[4] = R4(p + 24); - raw->nav.ion_cmp[5] = R4(p + 28); - raw->nav.ion_cmp[6] = R4(p + 32); - raw->nav.ion_cmp[7] = R4(p + 36); - - if (raw->outtype) { - sprintf(raw->msgtype,"SBF Compass Ionospheric Data"); - } + raw->nav.ion_cmp[0] = R4(p + 8); + raw->nav.ion_cmp[1] = R4(p + 12); + raw->nav.ion_cmp[2] = R4(p + 16); + raw->nav.ion_cmp[3] = R4(p + 20); + raw->nav.ion_cmp[4] = R4(p + 24); + raw->nav.ion_cmp[5] = R4(p + 28); + raw->nav.ion_cmp[6] = R4(p + 32); + raw->nav.ion_cmp[7] = R4(p + 36); + + if (raw->outtype) { + sprintf(raw->msgtype, "SBF Compass Ionospheric Data"); + } - return 9; + return 9; } - /* decode SBF cmputc --------------------------------------------------------*/ -static int decode_cmputc(raw_t *raw) -{ - uint8_t *p = raw->buff+8; /* points at TOW location */ - uint16_t week; +static int decode_cmputc(raw_t *raw) { + uint8_t *p = raw->buff + 8; /* points at TOW location */ + uint16_t week; - trace(4, "SBF decode_cmputc: len=%d\n", raw->len); + trace(4, "SBF decode_cmputc: len=%d\n", raw->len); - if (raw->len < 32) - { - trace(1, "SBF decode_cmputc: Block too short\n"); - return -1; - } + if (raw->len < 32) { + trace(1, "SBF decode_cmputc: Block too short\n"); + return -1; + } - week = U2(p + 4); + week = U2(p + 4); - /* Compass delta-UTC parameters */ - raw->nav.utc_cmp[1] = R4(p + 8); /* A1 */ - raw->nav.utc_cmp[0] = R8(p + 12); /* A0 */ - raw->nav.utc_cmp[2] = 0; /* tot */ - raw->nav.utc_cmp[3] = 0; /* WNt */ - raw->nav.utc_cmp[4] = I1(p + 20); /* dt_LS */ - raw->nav.utc_cmp[5] = adjust_WN8(week, U1(p + 21)); /* WN_LSF */ - raw->nav.utc_cmp[6] = U1(p + 22); /* DN */ - raw->nav.utc_cmp[7] = I1(p + 23); /* DEL_t_LSF */ + /* Compass delta-UTC parameters */ + raw->nav.utc_cmp[1] = R4(p + 8); /* A1 */ + raw->nav.utc_cmp[0] = R8(p + 12); /* A0 */ + raw->nav.utc_cmp[2] = 0; /* tot */ + raw->nav.utc_cmp[3] = 0; /* WNt */ + raw->nav.utc_cmp[4] = I1(p + 20); /* dt_LS */ + raw->nav.utc_cmp[5] = adjust_WN8(week, U1(p + 21)); /* WN_LSF */ + raw->nav.utc_cmp[6] = U1(p + 22); /* DN */ + raw->nav.utc_cmp[7] = I1(p + 23); /* DEL_t_LSF */ - if (raw->outtype) { - sprintf(raw->msgtype, "SBF Compass UTC Offsets"); - } + if (raw->outtype) { + sprintf(raw->msgtype, "SBF Compass UTC Offsets"); + } - return 9; + return 9; } /* QZSS Decoded Message Blocks */ /* decode SBF nav message for QZSS (navigation data) --------------------------*/ -static int decode_qzssnav(raw_t *raw){ - trace(4, "SBF decode_qzssnav: len=%d\n", raw->len); +static int decode_qzssnav(raw_t *raw) { + trace(4, "SBF decode_qzssnav: len=%d\n", raw->len); - if (raw->len < 140) { - trace(2, "SBF decode_qzssnav frame length error: len=%d\n", raw->len); - return -1; - } + if (raw->len < 140) { + trace(2, "SBF decode_qzssnav frame length error: len=%d\n", raw->len); + return -1; + } - int svid = U1(raw->buff + 14); - int sat = svid2sat(svid); + int svid = U1(raw->buff + 14); + int sat = svid2sat(svid); - if (sat == 0) { - trace(2, "SBF decode_qzssnav svid error: svid=%d prn=%d\n", svid, svid - 180); - return -1; - } + if (sat == 0) { + trace(2, "SBF decode_qzssnav svid error: svid=%d prn=%d\n", svid, svid - 180); + return -1; + } - uint16_t week = U2(raw->buff + 12); /* WN */ - eph_t eph = {0}; - eph.code = U1(raw->buff + 18); - eph.sva = U1(raw->buff + 19); - eph.svh = U1(raw->buff + 20); - /* byte 21 L2 P data flag */ - eph.iodc = U2(raw->buff + 22); - eph.iode = U1(raw->buff + 24); - /* byte 25: IODE from frame 3 */ - eph.fit = U1(raw->buff + 26) ? 4 : 2; - /* byte 27: reserved */ - if (R4(raw->buff + 28) != -2.e10) eph.tgd[0] = R4(raw->buff + 28); - double toc = U4(raw->buff + 32); - eph.f2 = R4(raw->buff + 36); - eph.f1 = R4(raw->buff + 40); - eph.f0 = R4(raw->buff + 44); - eph.crs = R4(raw->buff + 48); - eph.deln = R4(raw->buff + 52) * PI; - eph.M0 = R8(raw->buff + 56) * PI; - eph.cuc = R4(raw->buff + 64); - eph.e = R8(raw->buff + 68); - eph.cus = R4(raw->buff + 76); - eph.A = pow(R8(raw->buff + 80), 2); - eph.toes = U4(raw->buff + 88); - eph.cic = R4(raw->buff + 92); - eph.OMG0 = R8(raw->buff + 96) * PI; - eph.cis = R4(raw->buff + 104); - eph.i0 = R8(raw->buff + 108) * PI; - eph.crc = R4(raw->buff + 116); - eph.omg = R8(raw->buff + 120) * PI; - eph.OMGd = R4(raw->buff + 128) * PI; - eph.idot = R4(raw->buff + 132) * PI; - uint16_t week_oc = U2(raw->buff + 136); /* WNt_oc */ - uint16_t week_oe = U2(raw->buff + 138); /* WNt_oe l*/ - - eph.week = adjust_WN10(week, week_oc); - eph.toe = gpst2time(adjust_WN10(week, week_oe), eph.toes); - eph.toc = gpst2time(eph.week, toc); - eph.ttr = raw->time; - - if (raw->outtype) { - sprintf(raw->msgtype, "SBF QZSS Decoded Navigation Data (PRN=%d, IODE=%d, IODC=%d, TOES=%6.0f )", svid - 180, eph.iode, eph.iodc, eph.toes); - } + uint16_t week = U2(raw->buff + 12); /* WN */ + eph_t eph = {0}; + eph.code = U1(raw->buff + 18); + eph.sva = U1(raw->buff + 19); + eph.svh = U1(raw->buff + 20); + /* byte 21 L2 P data flag */ + eph.iodc = U2(raw->buff + 22); + eph.iode = U1(raw->buff + 24); + /* byte 25: IODE from frame 3 */ + eph.fit = U1(raw->buff + 26) ? 4 : 2; + /* byte 27: reserved */ + if (R4(raw->buff + 28) != -2.e10) eph.tgd[0] = R4(raw->buff + 28); + double toc = U4(raw->buff + 32); + eph.f2 = R4(raw->buff + 36); + eph.f1 = R4(raw->buff + 40); + eph.f0 = R4(raw->buff + 44); + eph.crs = R4(raw->buff + 48); + eph.deln = R4(raw->buff + 52) * PI; + eph.M0 = R8(raw->buff + 56) * PI; + eph.cuc = R4(raw->buff + 64); + eph.e = R8(raw->buff + 68); + eph.cus = R4(raw->buff + 76); + eph.A = pow(R8(raw->buff + 80), 2); + eph.toes = U4(raw->buff + 88); + eph.cic = R4(raw->buff + 92); + eph.OMG0 = R8(raw->buff + 96) * PI; + eph.cis = R4(raw->buff + 104); + eph.i0 = R8(raw->buff + 108) * PI; + eph.crc = R4(raw->buff + 116); + eph.omg = R8(raw->buff + 120) * PI; + eph.OMGd = R4(raw->buff + 128) * PI; + eph.idot = R4(raw->buff + 132) * PI; + uint16_t week_oc = U2(raw->buff + 136); /* WNt_oc */ + uint16_t week_oe = U2(raw->buff + 138); /* WNt_oe l*/ + + eph.week = adjust_WN10(week, week_oc); + eph.toe = gpst2time(adjust_WN10(week, week_oe), eph.toes); + eph.toc = gpst2time(eph.week, toc); + eph.ttr = raw->time; + + if (raw->outtype) { + sprintf(raw->msgtype, + "SBF QZSS Decoded Navigation Data (PRN=%d, IODE=%d, IODC=%d, TOES=%6.0f )", svid - 180, + eph.iode, eph.iodc, eph.toes); + } - if (!strstr(raw->opt, "-EPHALL")) { - if (eph.iode == raw->nav.eph[sat-1].iode) return 0; - } + if (!strstr(raw->opt, "-EPHALL")) { + if (eph.iode == raw->nav.eph[sat - 1].iode) return 0; + } - eph.sat = sat; - raw->nav.eph[sat-1] = eph; - raw->ephsat = sat; - raw->ephset = 0; - return 2; + eph.sat = sat; + raw->nav.eph[sat - 1] = eph; + raw->ephsat = sat; + raw->ephset = 0; + return 2; } #ifdef TESTING /* decode SBF almanach message for QZSS --------------------------*/ -static int decode_qzssalm(raw_t *raw) -{ - uint8_t *p = raw->buff+8; /* points at TOW location */ - alm_t alm; - uint16_t week; +static int decode_qzssalm(raw_t *raw) { + uint8_t *p = raw->buff + 8; /* points at TOW location */ + alm_t alm; + uint16_t week; - trace(4, "SBF decode_cmpalm: len=%d\n", raw->len); + trace(4, "SBF decode_cmpalm: len=%d\n", raw->len); - if (raw->len < 60) - { - trace(1, "SBF decode_cmpalm: Block too short\n"); - return -1; - } + if (raw->len < 60) { + trace(1, "SBF decode_cmpalm: Block too short\n"); + return -1; + } - week = U2(p + 4); - alm.sat = satno(SYS_QZS, U1(p + 6) - 180); - /* byte 7: reserved */ - alm.e = R4(p + 8); - alm.toas = U4(p + 12); - alm.i0 = R4(p + 16); - alm.OMGd = R4(p + 20); - alm.A = pow(R4(p + 24), 2); - alm.OMG0 = R4(p + 28); - alm.omg = R4(p + 32); - alm.M0 = R4(p + 36); - alm.f1 = R4(p + 40); - alm.f0 = R4(p + 44); - alm.week = adjust_WN8(week, U1(p + 48)); - /* byte 49: reserved */ - alm.svh = U1(p + 50); - alm.svconf= 0; - - alm.toa = gpst2time(alm.week, alm.toas); - - if (alm.sat == 0) return -1; - - raw->nav.alm[alm.sat-1] = alm; - - if (raw->outtype) { - sprintf(raw->msgtype, "SBF QZSS Almanach (PRN=%d)", U1(p + 6)); - } + week = U2(p + 4); + alm.sat = satno(SYS_QZS, U1(p + 6) - 180); + /* byte 7: reserved */ + alm.e = R4(p + 8); + alm.toas = U4(p + 12); + alm.i0 = R4(p + 16); + alm.OMGd = R4(p + 20); + alm.A = pow(R4(p + 24), 2); + alm.OMG0 = R4(p + 28); + alm.omg = R4(p + 32); + alm.M0 = R4(p + 36); + alm.f1 = R4(p + 40); + alm.f0 = R4(p + 44); + alm.week = adjust_WN8(week, U1(p + 48)); + /* byte 49: reserved */ + alm.svh = U1(p + 50); + alm.svconf = 0; + + alm.toa = gpst2time(alm.week, alm.toas); + + if (alm.sat == 0) return -1; + + raw->nav.alm[alm.sat - 1] = alm; + + if (raw->outtype) { + sprintf(raw->msgtype, "SBF QZSS Almanach (PRN=%d)", U1(p + 6)); + } - return 9; + return 9; } #endif /* TESTING */ - - /* decode SBF nav message for sbas (navigation data) ----------------------*/ -static int decode_geonav(raw_t *raw) -{ - uint8_t *p = raw->buff+8; /* points at TOW location */ - seph_t eph = {0}; - int prn, sat; - uint32_t tod; +static int decode_geonav(raw_t *raw) { + uint8_t *p = raw->buff + 8; /* points at TOW location */ + seph_t eph = {0}; + int prn, sat; + uint32_t tod; - trace(4, "SBF decode_geonav: len=%d\n", raw->len); + trace(4, "SBF decode_geonav: len=%d\n", raw->len); - if (raw->len < 104) { - trace(2, "SBF decode_geonav frame length error: len=%d\n", raw->len); - return -1; - } - prn = U1(p+6); - sat = satno(SYS_SBS, prn); + if (raw->len < 104) { + trace(2, "SBF decode_geonav frame length error: len=%d\n", raw->len); + return -1; + } + prn = U1(p + 6); + sat = satno(SYS_SBS, prn); - if (!(prn>=120 && prn<=140)){ - trace(2, "SBF decode_geonav prn error: sat=%d\n", prn); - return -1; - } + if (!(prn >= 120 && prn <= 140)) { + trace(2, "SBF decode_geonav prn error: sat=%d\n", prn); + return -1; + } - if (sat == 0) return -1; - - double tow = U4(p + 0) * 0.001; - uint16_t week = U2(p + 4); - /* byte 7: reserved */ - /* byte 8, 9: IODN */ - eph.sva = U2(p + 10); - tod = U4(p + 12); - eph.pos[0] = R8(p + 16); - eph.pos[1] = R8(p + 24); - eph.pos[2] = R8(p + 32); - eph.vel[0] = R8(p + 40); - eph.vel[1] = R8(p + 48); - eph.vel[2] = R8(p + 56); - eph.acc[0] = R8(p + 64); - eph.acc[1] = R8(p + 72); - eph.acc[2] = R8(p + 80); - eph.af0 = R4(p + 88); - eph.af1 = R4(p + 92); - - eph.tof = gpst2time(week, tow); - eph.t0 = adjday(eph.tof, tod); - eph.svh = eph.sva==15 ? 1 : 0; - - /* debug */ - trace(2, "sat=%2d, week=%d, tow=%f\n", sat, week, tow); - - if (raw->outtype) { - sprintf(raw->msgtype, "SBF SBAS Decoded Navigation Data (PRN=%d, TOW=%lf, SVA=%d )", prn, tow, eph.sva); - } + if (sat == 0) return -1; + + double tow = U4(p + 0) * 0.001; + uint16_t week = U2(p + 4); + /* byte 7: reserved */ + /* byte 8, 9: IODN */ + eph.sva = U2(p + 10); + tod = U4(p + 12); + eph.pos[0] = R8(p + 16); + eph.pos[1] = R8(p + 24); + eph.pos[2] = R8(p + 32); + eph.vel[0] = R8(p + 40); + eph.vel[1] = R8(p + 48); + eph.vel[2] = R8(p + 56); + eph.acc[0] = R8(p + 64); + eph.acc[1] = R8(p + 72); + eph.acc[2] = R8(p + 80); + eph.af0 = R4(p + 88); + eph.af1 = R4(p + 92); + + eph.tof = gpst2time(week, tow); + eph.t0 = adjday(eph.tof, tod); + eph.svh = eph.sva == 15 ? 1 : 0; + + /* debug */ + trace(2, "sat=%2d, week=%d, tow=%f\n", sat, week, tow); + + if (raw->outtype) { + sprintf(raw->msgtype, "SBF SBAS Decoded Navigation Data (PRN=%d, TOW=%lf, SVA=%d )", prn, tow, + eph.sva); + } - if (!strstr(raw->opt, "-EPHALL")) { - if (fabs(timediff(eph.t0, raw->nav.seph[prn-120].t0)) < 1.0 && - eph.sva == raw->nav.seph[prn-120].sva) - return 0; - } + if (!strstr(raw->opt, "-EPHALL")) { + if (fabs(timediff(eph.t0, raw->nav.seph[prn - 120].t0)) < 1.0 && + eph.sva == raw->nav.seph[prn - 120].sva) + return 0; + } - eph.sat = sat; - raw->nav.seph[prn-120] = eph; - raw->ephsat = eph.sat; - raw->ephset = 0; + eph.sat = sat; + raw->nav.seph[prn - 120] = eph; + raw->ephsat = eph.sat; + raw->ephset = 0; - return 2; + return 2; } #if 1 /* UNUSED */ /* type 2-5,0: fast corrections ---------------------------------------*/ -static int decode_sbsfast(raw_t *raw) -{ - int i, j; - int prn, sat; - uint8_t sbLength, sbCount, iodf, type; - double prc_old, dt; - gtime_t t0_old; - uint8_t *p = raw->buff+8; - - trace(4, "SBF decode_sbsfast: len=%d\n", raw->len); - - if (raw->len < 20) - { - trace(1, "SBF decode_sbsfast: Block too short\n"); - return -1; - } +static int decode_sbsfast(raw_t *raw) { + int i, j; + int prn, sat; + uint8_t sbLength, sbCount, iodf, type; + double prc_old, dt; + gtime_t t0_old; + uint8_t *p = raw->buff + 8; + + trace(4, "SBF decode_sbsfast: len=%d\n", raw->len); + + if (raw->len < 20) { + trace(1, "SBF decode_sbsfast: Block too short\n"); + return -1; + } - /* get satellite number */ - prn = U1(p+6); - if (prn < 120) return -1; - if (prn > 140) return -1; + /* get satellite number */ + prn = U1(p + 6); + if (prn < 120) return -1; + if (prn > 140) return -1; - sat = satno(SYS_SBS, prn); - if (sat == 0) return -1; + sat = satno(SYS_SBS, prn); + if (sat == 0) return -1; - if (raw->outtype) { - sprintf(raw->msgtype, "SBF SBAS Ionosphere Fast Correction from PRN=%d", prn); - } + if (raw->outtype) { + sprintf(raw->msgtype, "SBF SBAS Ionosphere Fast Correction from PRN=%d", prn); + } - double tow = U4(p+0) * 0.001; - uint16_t week = U2(p+4); + double tow = U4(p + 0) * 0.001; + uint16_t week = U2(p + 4); - type = U1(p+7); - if (raw->nav.sbssat.iodp != U1(p+8)) return 0; - iodf = U1(p+9); - sbCount = U1(p+10); - sbLength = U1(p+11); + type = U1(p + 7); + if (raw->nav.sbssat.iodp != U1(p + 8)) return 0; + iodf = U1(p + 9); + sbCount = U1(p + 10); + sbLength = U1(p + 11); - if (type > 5 || type == 1) return -1; + if (type > 5 || type == 1) return -1; - for (i=0; i= raw->nav.sbssat.nsat) break; - t0_old = raw->nav.sbssat.sat[j].fcorr.t0; - prc_old = raw->nav.sbssat.sat[j].fcorr.prc; + for (i = 0; i < sbCount; i++) { + j = U1(p + 12 + i * sbLength + 1); + if (j >= raw->nav.sbssat.nsat) break; + t0_old = raw->nav.sbssat.sat[j].fcorr.t0; + prc_old = raw->nav.sbssat.sat[j].fcorr.prc; - raw->nav.sbssat.sat[j].fcorr.t0 = gpst2time(week, tow); - raw->nav.sbssat.sat[j].fcorr.udre = U1(p+12+i*sbLength+1); - raw->nav.sbssat.sat[j].fcorr.prc = R4(p+12+i*sbLength+4); + raw->nav.sbssat.sat[j].fcorr.t0 = gpst2time(week, tow); + raw->nav.sbssat.sat[j].fcorr.udre = U1(p + 12 + i * sbLength + 1); + raw->nav.sbssat.sat[j].fcorr.prc = R4(p + 12 + i * sbLength + 4); - dt = timediff(raw->nav.sbssat.sat[j].fcorr.t0, t0_old); - if (t0_old.time==0 || dt<=0.0 || 18.0
nav.sbssat.sat[j].fcorr.ai==0) { - raw->nav.sbssat.sat[j].fcorr.rrc = 0.0; - raw->nav.sbssat.sat[j].fcorr.dt = 0.0; - } - else { - raw->nav.sbssat.sat[j].fcorr.rrc = (raw->nav.sbssat.sat[j].fcorr.prc-prc_old)/dt; - raw->nav.sbssat.sat[j].fcorr.dt = dt; - } - raw->nav.sbssat.sat[j].fcorr.iodf = iodf; + dt = timediff(raw->nav.sbssat.sat[j].fcorr.t0, t0_old); + if (t0_old.time == 0 || dt <= 0.0 || 18.0 < dt || raw->nav.sbssat.sat[j].fcorr.ai == 0) { + raw->nav.sbssat.sat[j].fcorr.rrc = 0.0; + raw->nav.sbssat.sat[j].fcorr.dt = 0.0; + } else { + raw->nav.sbssat.sat[j].fcorr.rrc = (raw->nav.sbssat.sat[j].fcorr.prc - prc_old) / dt; + raw->nav.sbssat.sat[j].fcorr.dt = dt; } - trace(5, "SBF decode_sbsfast: type=%d iodf=%d\n", U1(p+9), iodf); - return 3; + raw->nav.sbssat.sat[j].fcorr.iodf = iodf; + } + trace(5, "SBF decode_sbsfast: type=%d iodf=%d\n", U1(p + 9), iodf); + return 3; } /* decode type 1: prn masks --------------------------------------------------*/ -static int decode_sbsprnmask(raw_t *raw) -{ - int i, n, sat, prn; - uint8_t *p = raw->buff+8; +static int decode_sbsprnmask(raw_t *raw) { + int i, n, sat, prn; + uint8_t *p = raw->buff + 8; - trace(4, "SBF decode_sbsprnmask:\n"); + trace(4, "SBF decode_sbsprnmask:\n"); - if (raw->len < 17) - { - trace(1, "SBF decode_sbsprnmask: Block too short\n"); - return -1; - } + if (raw->len < 17) { + trace(1, "SBF decode_sbsprnmask: Block too short\n"); + return -1; + } - /* get satellite number */ - prn = U1(p+6); - if (prn < 120) return -1; - if (prn > 139) return -1; + /* get satellite number */ + prn = U1(p + 6); + if (prn < 120) return -1; + if (prn > 139) return -1; - raw->nav.sbssat.iodp = U1(p+7); - raw->nav.sbssat.nsat = U1(p+8); + raw->nav.sbssat.iodp = U1(p + 7); + raw->nav.sbssat.nsat = U1(p + 8); - if (raw->outtype) { - sprintf(raw->msgtype, "SBF SBAS PRN Mask from PRN=%d", prn); - } + if (raw->outtype) { + sprintf(raw->msgtype, "SBF SBAS PRN Mask from PRN=%d", prn); + } - for (n=0; nnav.sbssat.nsat && nnav.sbssat.sat[n].sat = sat; - } + for (n = 0; n < raw->nav.sbssat.nsat && n < MAXSAT; n++) { + i = U1(p + 9 + n); + if (i <= 37) + sat = satno(SYS_GPS, i); /* 0- 37: GPS */ + else if (i <= 61) + sat = satno(SYS_GLO, i - 37); /* 38- 61: GLONASSs */ + else if (i <= 119) + sat = 0; /* 62-119: future GNSS */ + else if (i <= 138) + sat = satno(SYS_SBS, i); /* 120-138: geo/waas */ + else if (i <= 182) + sat = 0; /* 139-182: reserved */ + else if (i <= 192) + sat = satno(SYS_SBS, i + 10); /* 183-192: QZSS ref [2] */ + else if (i <= 202) + sat = satno(SYS_QZS, i); /* 193-202: QZSS ref [2] */ + else + sat = 0; /* 203- : reserved */ + raw->nav.sbssat.sat[n].sat = sat; + } - trace(5, "SBF decode_sbsprnmask: nprn=%d iodp=%d\n", n, raw->nav.sbssat.iodp); + trace(5, "SBF decode_sbsprnmask: nprn=%d iodp=%d\n", n, raw->nav.sbssat.iodp); - return 3; + return 3; } /* decode type 6: integrity info ---------------------------------------------*/ -static int decode_sbsintegriy(raw_t *raw) -{ - int i, prn; - uint8_t *p = raw->buff+6; - uint8_t iodf[4], udre; +static int decode_sbsintegriy(raw_t *raw) { + int i, prn; + uint8_t *p = raw->buff + 6; + uint8_t iodf[4], udre; + trace(4, "decode_sbsintegriy:\n"); - trace(4, "decode_sbsintegriy:\n"); - - if (raw->len < 71) - { - trace(1, "SBF decode_sbsintegriy: Block too short\n"); - return -1; - } + if (raw->len < 71) { + trace(1, "SBF decode_sbsintegriy: Block too short\n"); + return -1; + } - /* get satellite number */ - prn = U1(p+8); - if (prn < 120) return -1; - if (prn > 139) return -1; + /* get satellite number */ + prn = U1(p + 8); + if (prn < 120) return -1; + if (prn > 139) return -1; - if (raw->outtype) { - sprintf(raw->msgtype, "SBF SABS Integrity Data from PRN=%d", prn); - } + if (raw->outtype) { + sprintf(raw->msgtype, "SBF SABS Integrity Data from PRN=%d", prn); + } - for (i=0; i<4; i++) { - iodf[i] = U1(p+10+i); - } - /* Limited to 51 to avoid overflow of iodf[]. TODO check the logic */ - for (i=0; inav.sbssat.nsat && i<51; i++) { - if (raw->nav.sbssat.sat[i].fcorr.iodf != iodf[i/13]) continue; - udre = U1(p+14+i); - raw->nav.sbssat.sat[i].fcorr.udre = udre; - } - trace(5, "SBF decode_sbsintegriy: iodf=%d %d %d %d\n", iodf[0], iodf[1], iodf[2], iodf[3]); - return 3; + for (i = 0; i < 4; i++) { + iodf[i] = U1(p + 10 + i); + } + /* Limited to 51 to avoid overflow of iodf[]. TODO check the logic */ + for (i = 0; i < raw->nav.sbssat.nsat && i < 51; i++) { + if (raw->nav.sbssat.sat[i].fcorr.iodf != iodf[i / 13]) continue; + udre = U1(p + 14 + i); + raw->nav.sbssat.sat[i].fcorr.udre = udre; + } + trace(5, "SBF decode_sbsintegriy: iodf=%d %d %d %d\n", iodf[0], iodf[1], iodf[2], iodf[3]); + return 3; } /* decode type 7: fast correction degradation factor -------------------------*/ -static int decode_sbsfastcorrdegr(raw_t *raw) -{ - int i,prn; - uint8_t *p = raw->buff+6; - +static int decode_sbsfastcorrdegr(raw_t *raw) { + int i, prn; + uint8_t *p = raw->buff + 6; - trace(4, "SBF decode_sbsfastcorrdegr:\n"); + trace(4, "SBF decode_sbsfastcorrdegr:\n"); - if (raw->len < 68) - { - trace(1, "SBF decode_sbsfastcorrdegr: Block too short\n"); - return -1; - } + if (raw->len < 68) { + trace(1, "SBF decode_sbsfastcorrdegr: Block too short\n"); + return -1; + } - /* get satellite number */ - prn = U1(p+8); - if (prn < 120) return -1; - if (prn > 139) return -1; + /* get satellite number */ + prn = U1(p + 8); + if (prn < 120) return -1; + if (prn > 139) return -1; - if (raw->outtype) { - sprintf(raw->msgtype, "SBF SBAS Fast Correction Degradation Factor from PRN=%d", prn); - } + if (raw->outtype) { + sprintf(raw->msgtype, "SBF SBAS Fast Correction Degradation Factor from PRN=%d", prn); + } - if (raw->nav.sbssat.iodp != U1(p+9)) return 0; + if (raw->nav.sbssat.iodp != U1(p + 9)) return 0; - raw->nav.sbssat.tlat = U1(p+10); + raw->nav.sbssat.tlat = U1(p + 10); - for (i=0; inav.sbssat.nsat && inav.sbssat.sat[i].fcorr.ai = U1(p+11+i); - } - return 0; + for (i = 0; i < raw->nav.sbssat.nsat && i < MAXSAT; i++) { + raw->nav.sbssat.sat[i].fcorr.ai = U1(p + 11 + i); + } + return 0; } /* decode type 26: ionospheric delay corrections -----------------------------*/ -static int decode_sbsionodelay(raw_t *raw) -{ - int i, j, give, prn; - int band; - uint8_t *p = raw->buff+8, sbLength, count; +static int decode_sbsionodelay(raw_t *raw) { + int i, j, give, prn; + int band; + uint8_t *p = raw->buff + 8, sbLength, count; - trace(4, "SBF decode_sbsionodelay:\n"); + trace(4, "SBF decode_sbsionodelay:\n"); - if (raw->len < 20) - { - trace(1, "SBF decode_sbsionodelay: Block too short\n"); - return -1; - } + if (raw->len < 20) { + trace(1, "SBF decode_sbsionodelay: Block too short\n"); + return -1; + } - /* get satellite number */ - prn = U1(p+6); - if (prn < 120) return -1; - if (prn > 139) return -1; + /* get satellite number */ + prn = U1(p + 6); + if (prn < 120) return -1; + if (prn > 139) return -1; - if (raw->outtype) { - sprintf(raw->msgtype, "SBF SBAS Ionospheric Delay Correction from PRN=%d", prn); - } + if (raw->outtype) { + sprintf(raw->msgtype, "SBF SBAS Ionospheric Delay Correction from PRN=%d", prn); + } - band = U1(p+7); + band = U1(p + 7); - if (band>MAXBAND || raw->nav.sbsion[band].iodi != U1(p+8)) return 0; + if (band > MAXBAND || raw->nav.sbsion[band].iodi != U1(p + 8)) return 0; - double tow = U4(p) * 0.001; - uint16_t week = U2(p+4); + double tow = U4(p) * 0.001; + uint16_t week = U2(p + 4); - count = U1(p+9); - sbLength = U1(p+10); + count = U1(p + 9); + sbLength = U1(p + 10); - if (count != 15) - { - trace(1, "SBF decode_sbsionodelay: wrong number of IDC blocks: %d\n", count); - return -1; - } + if (count != 15) { + trace(1, "SBF decode_sbsionodelay: wrong number of IDC blocks: %d\n", count); + return -1; + } - for (i=0; inav.sbsion[band].igp[j].t0 = gpst2time(week, tow); - raw->nav.sbsion[band].igp[j].delay = R4(p+12+i*sbLength+4); - raw->nav.sbsion[band].igp[j].give = give; + raw->nav.sbsion[band].igp[j].t0 = gpst2time(week, tow); + raw->nav.sbsion[band].igp[j].delay = R4(p + 12 + i * sbLength + 4); + raw->nav.sbsion[band].igp[j].give = give; - if (raw->nav.sbsion[band].igp[j].give >= 16) { - raw->nav.sbsion[band].igp[j].give = 0; - } + if (raw->nav.sbsion[band].igp[j].give >= 16) { + raw->nav.sbsion[band].igp[j].give = 0; } - trace(5, "decode_sbsionodelay: band=%d\n", band); - return 3; + } + trace(5, "decode_sbsionodelay: band=%d\n", band); + return 3; } /* decode type 18: ionospheric grid point masks ------------------------------*/ static int decode_sbsigpmask(raw_t *raw) /* TODO: verify this function */ { - const sbsigpband_t *b; - int i, j, n, m, prn; - uint8_t band; + const sbsigpband_t *b; + int i, j, n, m, prn; + uint8_t band; - uint8_t *p = raw->buff+8; + uint8_t *p = raw->buff + 8; - trace(4, "SBF decode_sbsigpmask:\n"); + trace(4, "SBF decode_sbsigpmask:\n"); - if (raw->len < 20) - { - trace(1, "SBF decode_sbsigpmask: Block too short\n"); - return -1; - } + if (raw->len < 20) { + trace(1, "SBF decode_sbsigpmask: Block too short\n"); + return -1; + } - /* get satellite number */ - prn = U1(p+6); - if (prn < 120) return -1; - if (prn > 139) return -1; + /* get satellite number */ + prn = U1(p + 6); + if (prn < 120) return -1; + if (prn > 139) return -1; - if (raw->outtype) { - sprintf(raw->msgtype, "SBF SBAS Ionospheric Grid Points from PRN=%d", prn); - } + if (raw->outtype) { + sprintf(raw->msgtype, "SBF SBAS Ionospheric Grid Points from PRN=%d", prn); + } - band = U1(p+8); + band = U1(p + 8); - if (band <= 8) {b = igpband1[band]; m = 8;} - else if (band <= 10) {b = igpband2[band-9]; m = 5;} - else return 0; + if (band <= 8) { + b = igpband1[band]; + m = 8; + } else if (band <= 10) { + b = igpband2[band - 9]; + m = 5; + } else + return 0; - raw->nav.sbsion[band].iodi = U1(p+9); - raw->nav.sbsion[band].nigp = U1(p+10); + raw->nav.sbsion[band].iodi = U1(p + 9); + raw->nav.sbsion[band].nigp = U1(p + 10); - for (n=0; nnav.sbsion[band].nigp; n++) - { - i = U1(p+11+n); - for (j=0; jnav.sbsion[band].igp[n].lat = band<=8 ? b[j].y[i-b[j].bits] : b[j].x; - raw->nav.sbsion[band].igp[n++].lon = band<=8 ? b[j].x : b[j].y[i-b[j].bits]; - break; - } + for (n = 0; n < raw->nav.sbsion[band].nigp; n++) { + i = U1(p + 11 + n); + for (j = 0; j < m; j++) { + if (i < b[j].bits || b[j].bite < i) continue; + raw->nav.sbsion[band].igp[n].lat = band <= 8 ? b[j].y[i - b[j].bits] : b[j].x; + raw->nav.sbsion[band].igp[n++].lon = band <= 8 ? b[j].x : b[j].y[i - b[j].bits]; + break; } + } - trace(5, "decode_sbsigpmask: band=%d nigp=%d\n", band, n); + trace(5, "decode_sbsigpmask: band=%d nigp=%d\n", band, n); - return 3; + return 3; } /* decode long term correction ------------------------------------------*/ -static int decode_sbslongcorrh(raw_t* raw) -{ - int prn, i; - uint8_t *p = raw->buff+8; - uint8_t count, sbLength, no; +static int decode_sbslongcorrh(raw_t *raw) { + int prn, i; + uint8_t *p = raw->buff + 8; + uint8_t count, sbLength, no; - trace(4, "SBF decode_sbslongcorrh:\n"); + trace(4, "SBF decode_sbslongcorrh:\n"); - if (raw->len<20) - { - trace(1, "SBF decode_sbslongcorrh: Block too short\n"); - return -1; - } - - /* get satellite number */ - prn = U1(p+6); - if (prn < 120) return -1; - if (prn > 139) return -1; + if (raw->len < 20) { + trace(1, "SBF decode_sbslongcorrh: Block too short\n"); + return -1; + } - if (raw->outtype) { - sprintf(raw->msgtype, "SBF SBAS Long Term Corrections from PRN=%d", prn); - } + /* get satellite number */ + prn = U1(p + 6); + if (prn < 120) return -1; + if (prn > 139) return -1; - double tow = U4(p + 0) * 0.001; - uint16_t week = U2(p+4); - - count = U1(p+7); - sbLength = U1(p+8); - - if (count > 4) return -1; - - for (i=0; inav.sbssat.sat[no-1].lcorr.iode = U1(p+12+i*sbLength+ 3); - raw->nav.sbssat.sat[no-1].lcorr.dpos[0] = R4(p+12+i*sbLength+ 4); - raw->nav.sbssat.sat[no-1].lcorr.dpos[1] = R4(p+12+i*sbLength+ 8); - raw->nav.sbssat.sat[no-1].lcorr.dpos[2] = R4(p+12+i*sbLength+12); - raw->nav.sbssat.sat[no-1].lcorr.daf0 = R4(p+12+i*sbLength+28); - if (U1(p+12+i*sbLength+0) == 1) - { - raw->nav.sbssat.sat[no-1].lcorr.dvel[i] = R4(p+12+i*sbLength+16); - raw->nav.sbssat.sat[no-1].lcorr.dvel[i] = R4(p+12+i*sbLength+20); - raw->nav.sbssat.sat[no-1].lcorr.dvel[i] = R4(p+12+i*sbLength+24); - - raw->nav.sbssat.sat[no-1].lcorr.daf1 = R4(p+12+i*sbLength+32); - - /* Time of day. Calculate day offset from TOW. */ - double t = U4(p+12+i*sbLength+36) - fmod(tow, 86400); - if (t <= -43200) t += 86400; - else if (t > 43200) t -= 86400; - raw->nav.sbssat.sat[no-1].lcorr.t0 = gpst2time(week, tow+t); - } else - { - raw->nav.sbssat.sat[no-1].lcorr.dvel[0] = raw->nav.sbssat.sat[no-1].lcorr.dvel[1] = raw->nav.sbssat.sat[no-1].lcorr.dvel[2] = 0.0; - raw->nav.sbssat.sat[no-1].lcorr.daf1 = 0; - raw->nav.sbssat.sat[no-1].lcorr.t0 = gpst2time(week, tow); - }; + if (raw->outtype) { + sprintf(raw->msgtype, "SBF SBAS Long Term Corrections from PRN=%d", prn); + } + double tow = U4(p + 0) * 0.001; + uint16_t week = U2(p + 4); + + count = U1(p + 7); + sbLength = U1(p + 8); + + if (count > 4) return -1; + + for (i = 0; i < count; i++) { + no = U1(p + 12 + i * sbLength + 1); + raw->nav.sbssat.sat[no - 1].lcorr.iode = U1(p + 12 + i * sbLength + 3); + raw->nav.sbssat.sat[no - 1].lcorr.dpos[0] = R4(p + 12 + i * sbLength + 4); + raw->nav.sbssat.sat[no - 1].lcorr.dpos[1] = R4(p + 12 + i * sbLength + 8); + raw->nav.sbssat.sat[no - 1].lcorr.dpos[2] = R4(p + 12 + i * sbLength + 12); + raw->nav.sbssat.sat[no - 1].lcorr.daf0 = R4(p + 12 + i * sbLength + 28); + if (U1(p + 12 + i * sbLength + 0) == 1) { + raw->nav.sbssat.sat[no - 1].lcorr.dvel[i] = R4(p + 12 + i * sbLength + 16); + raw->nav.sbssat.sat[no - 1].lcorr.dvel[i] = R4(p + 12 + i * sbLength + 20); + raw->nav.sbssat.sat[no - 1].lcorr.dvel[i] = R4(p + 12 + i * sbLength + 24); + + raw->nav.sbssat.sat[no - 1].lcorr.daf1 = R4(p + 12 + i * sbLength + 32); + + /* Time of day. Calculate day offset from TOW. */ + double t = U4(p + 12 + i * sbLength + 36) - fmod(tow, 86400); + if (t <= -43200) + t += 86400; + else if (t > 43200) + t -= 86400; + raw->nav.sbssat.sat[no - 1].lcorr.t0 = gpst2time(week, tow + t); + } else { + raw->nav.sbssat.sat[no - 1].lcorr.dvel[0] = raw->nav.sbssat.sat[no - 1].lcorr.dvel[1] = + raw->nav.sbssat.sat[no - 1].lcorr.dvel[2] = 0.0; + raw->nav.sbssat.sat[no - 1].lcorr.daf1 = 0; + raw->nav.sbssat.sat[no - 1].lcorr.t0 = gpst2time(week, tow); }; + }; - return 3; + return 3; } #endif /* UNUSED */ /* decode external event block -----------------------------*/ -static int decode_extevent(raw_t *raw) -{ - uint8_t *p = raw->buff+8; - gtime_t eventime; - uint8_t source, polarity; - double offset, clk_bias; +static int decode_extevent(raw_t *raw) { + uint8_t *p = raw->buff + 8; + gtime_t eventime; + uint8_t source, polarity; + double offset, clk_bias; - trace(4, "SBF decode_extevent:\n"); + trace(4, "SBF decode_extevent:\n"); - if (raw->len < 20) - { - trace(1, "SBF decode_extevent: Block too short\n"); - return -1; - } + if (raw->len < 20) { + trace(1, "SBF decode_extevent: Block too short\n"); + return -1; + } - double tow = U4(p+0) * 0.001; - uint16_t week = U2(p+4); - source = U1(p+6); - polarity = U1(p+7); - offset = R4(p+8); - clk_bias = R8(p+12); + double tow = U4(p + 0) * 0.001; + uint16_t week = U2(p + 4); + source = U1(p + 6); + polarity = U1(p + 7); + offset = R4(p + 8); + clk_bias = R8(p + 12); - if (clk_bias == -2e10) /* do-not-use value*/ - clk_bias = 0; + if (clk_bias == -2e10) /* do-not-use value*/ + clk_bias = 0; - eventime = gpst2time(week, tow + offset - clk_bias); + eventime = gpst2time(week, tow + offset - clk_bias); - raw->obs.flag = 1 + source; /* Event flag */ - raw->obs.data[0].eventime = eventime; - raw->obs.tmcount++; + raw->obs.flag = 1 + source; /* Event flag */ + raw->obs.data[0].eventime = eventime; + raw->obs.tmcount++; - if (raw->outtype) { - sprintf(raw->msgtype, "SBF external event WN=%d, tow=%f: source=%d, polarity=%d", - week, tow + offset - clk_bias, source, polarity); - } + if (raw->outtype) { + sprintf(raw->msgtype, "SBF external event WN=%d, tow=%f: source=%d, polarity=%d", week, + tow + offset - clk_bias, source, polarity); + } - return 0; + return 0; } -static int decode_rxsetup(raw_t *raw) -{ - if (raw->len < 264) { - trace(1, "SBF decode_rxsetup: Block too short len=%d\n", raw->len); - return -1; - } - - if (raw->outtype) { - sprintf(raw->msgtype, "SBF RX Setup"); - } - char marker_name[61]; - STR(raw->buff + 16, 60, marker_name); - strcpy(raw->sta.name, marker_name); - char markerno[21]; - STR(raw->buff + 76, 20, markerno); - strcpy(raw->sta.markerno, markerno); - trace(2, "decode_rxsetup: marker_name='%s' markerno='%s'\n", marker_name, markerno); - - char observer[21]; - STR(raw->buff + 96, 20, observer); - strcpy(raw->sta.observer, observer); - char agency[41]; - STR(raw->buff + 116, 40, agency); - strcpy(raw->sta.agency, agency); - trace(2, "decode_rxsetup: observer='%s' agency='%s'\n", observer, agency); - - char rx_serial_num[21]; - STR(raw->buff + 156, 20, rx_serial_num); - strcpy(raw->sta.recsno, rx_serial_num); - char rx_name[21]; - STR(raw->buff + 176, 20, rx_name); - // Is this the appropriate mapping? - strcpy(raw->sta.rectype, rx_name); - char rx_version[21]; - STR(raw->buff + 196, 20, rx_version); - strcpy(raw->sta.recver, rx_version); - trace(2, "decode_rxsetup: rx_serial_no='%s' rx_name='%s' rx_version='%s'\n", rx_serial_num, rx_name, rx_version); - - char ant_serial_num[21]; - STR(raw->buff + 216, 20, ant_serial_num); - strcpy(raw->sta.antsno, ant_serial_num); - char ant_type[21]; - STR(raw->buff + 236, 20, ant_type); - // Is this the appropriate mapping? - strcpy(raw->sta.antdes, ant_type); - trace(2, "decode_rxsetup: ant_serial_num='%s' ant_type='%s'\n", ant_serial_num, ant_type); - - double deltah = R4(raw->buff + 256); - double deltae = R4(raw->buff + 260); - double deltan = R4(raw->buff + 264); - trace(2, "decode_rxsetup: delta h=%lf e=%lf n=%lf\n", deltah, deltae, deltan); - raw->sta.del[2] = deltah; - raw->sta.del[0] = deltae; - raw->sta.del[1] = deltan; - raw->sta.deltype = 0; // enu - - if (raw->len > 288) { - // Rev 1 - char marker_type[21]; - STR(raw->buff + 268, 20, marker_type); - strcpy(raw->sta.markertype, marker_type); - trace(2, "decode_rxsetup: marker type '%s'\n", marker_type); - } - if (raw->len > 328) { - // Rev 2. - char gnss_firmware_ver[41]; - STR(raw->buff + 288, 40, gnss_firmware_ver); - trace(2, "decode_rxsetup: gnss_firmware_ver='%s'\n", gnss_firmware_ver); - // TODO user this? - } - if (raw->len > 368) { - // Rev 3. - char product_name[41]; - STR(raw->buff + 328, 40, product_name); - trace(2, "decode_rxsetup: product='%s'\n", product_name); - // TODO user this? - } - if (raw->len > 402) { - // Rev 4 - double pos[3]; - pos[0] = R8(raw->buff + 368); // Lat - pos[1] = R8(raw->buff + 376); // Lon - pos[2] = R4(raw->buff + 384); // Height - if (pos[0] != -2e10 && pos[1] != -2e10 && pos[2] != -2e10) { - pos2ecef(pos, raw->sta.pos); - trace(2, "decode_rxsetup: lat=%lf lon=%lf height=%lf\n", pos[0]*R2D, pos[1]*R2D, pos[2]); - } - - char station_code[11]; - STR(raw->buff + 388, 10, station_code); - trace(2, "decode_rxsetup: station_code='%s'\n", station_code); - // TODO use the station code? +static int decode_rxsetup(raw_t *raw) { + if (raw->len < 264) { + trace(1, "SBF decode_rxsetup: Block too short len=%d\n", raw->len); + return -1; + } - uint8_t monument_idx = U1(raw->buff + 398); - uint8_t receiver_idx = U1(raw->buff + 399); - trace(2, "decode_rxsetup: monument_idx=%u receiver_idx=%u\n", monument_idx, receiver_idx); - // TODO use these idx's? + if (raw->outtype) { + sprintf(raw->msgtype, "SBF RX Setup"); + } + char marker_name[61]; + STR(raw->buff + 16, 60, marker_name); + strcpy(raw->sta.name, marker_name); + char markerno[21]; + STR(raw->buff + 76, 20, markerno); + strcpy(raw->sta.markerno, markerno); + trace(2, "decode_rxsetup: marker_name='%s' markerno='%s'\n", marker_name, markerno); + + char observer[21]; + STR(raw->buff + 96, 20, observer); + strcpy(raw->sta.observer, observer); + char agency[41]; + STR(raw->buff + 116, 40, agency); + strcpy(raw->sta.agency, agency); + trace(2, "decode_rxsetup: observer='%s' agency='%s'\n", observer, agency); + + char rx_serial_num[21]; + STR(raw->buff + 156, 20, rx_serial_num); + strcpy(raw->sta.recsno, rx_serial_num); + char rx_name[21]; + STR(raw->buff + 176, 20, rx_name); + // Is this the appropriate mapping? + strcpy(raw->sta.rectype, rx_name); + char rx_version[21]; + STR(raw->buff + 196, 20, rx_version); + strcpy(raw->sta.recver, rx_version); + trace(2, "decode_rxsetup: rx_serial_no='%s' rx_name='%s' rx_version='%s'\n", rx_serial_num, + rx_name, rx_version); + + char ant_serial_num[21]; + STR(raw->buff + 216, 20, ant_serial_num); + strcpy(raw->sta.antsno, ant_serial_num); + char ant_type[21]; + STR(raw->buff + 236, 20, ant_type); + // Is this the appropriate mapping? + strcpy(raw->sta.antdes, ant_type); + trace(2, "decode_rxsetup: ant_serial_num='%s' ant_type='%s'\n", ant_serial_num, ant_type); + + double deltah = R4(raw->buff + 256); + double deltae = R4(raw->buff + 260); + double deltan = R4(raw->buff + 264); + trace(2, "decode_rxsetup: delta h=%lf e=%lf n=%lf\n", deltah, deltae, deltan); + raw->sta.del[2] = deltah; + raw->sta.del[0] = deltae; + raw->sta.del[1] = deltan; + raw->sta.deltype = 0; // enu + + if (raw->len > 288) { + // Rev 1 + char marker_type[21]; + STR(raw->buff + 268, 20, marker_type); + strcpy(raw->sta.markertype, marker_type); + trace(2, "decode_rxsetup: marker type '%s'\n", marker_type); + } + if (raw->len > 328) { + // Rev 2. + char gnss_firmware_ver[41]; + STR(raw->buff + 288, 40, gnss_firmware_ver); + trace(2, "decode_rxsetup: gnss_firmware_ver='%s'\n", gnss_firmware_ver); + // TODO user this? + } + if (raw->len > 368) { + // Rev 3. + char product_name[41]; + STR(raw->buff + 328, 40, product_name); + trace(2, "decode_rxsetup: product='%s'\n", product_name); + // TODO user this? + } + if (raw->len > 402) { + // Rev 4 + double pos[3]; + pos[0] = R8(raw->buff + 368); // Lat + pos[1] = R8(raw->buff + 376); // Lon + pos[2] = R4(raw->buff + 384); // Height + if (pos[0] != -2e10 && pos[1] != -2e10 && pos[2] != -2e10) { + pos2ecef(pos, raw->sta.pos); + trace(2, "decode_rxsetup: lat=%lf lon=%lf height=%lf\n", pos[0] * R2D, pos[1] * R2D, pos[2]); + } + + char station_code[11]; + STR(raw->buff + 388, 10, station_code); + trace(2, "decode_rxsetup: station_code='%s'\n", station_code); + // TODO use the station code? + + uint8_t monument_idx = U1(raw->buff + 398); + uint8_t receiver_idx = U1(raw->buff + 399); + trace(2, "decode_rxsetup: monument_idx=%u receiver_idx=%u\n", monument_idx, receiver_idx); + // TODO use these idx's? + + char country_code[4]; + STR(raw->buff + 400, 3, country_code); + trace(2, "decode_rxsetup: country_code='%s'\n", country_code); + } - char country_code[4]; - STR(raw->buff + 400, 3, country_code); - trace(2, "decode_rxsetup: country_code='%s'\n", country_code); - } - - return 5; + return 5; } /* decode SBF raw message --------------------------------------------------*/ -static int decode_sbf(raw_t *raw) -{ - unsigned short crc; - char tstr[40]; +static int decode_sbf(raw_t *raw) { + unsigned short crc; + char tstr[40]; - /* read the SBF block ID and revision */ - int type = U2(raw->buff+4) & 0x1fff << 0; - int revision = U2(raw->buff+4) >> 13; - (void)revision; /* unused */ + /* read the SBF block ID and revision */ + int type = U2(raw->buff + 4) & 0x1fff << 0; + int revision = U2(raw->buff + 4) >> 13; + (void)revision; /* unused */ - trace(3, "decode_sbf: type=%04x len=%d\n", type, raw->len); + trace(3, "decode_sbf: type=%04x len=%d\n", type, raw->len); - /* read the SBF block CRC */ - crc = U2(raw->buff+2); - - /* checksum skipping first 4 bytes */ - if (sbf_checksum(raw->buff+4, raw->len-4) != crc){ - trace(2, "sbf checksum error: type=%04x len=%d\n", type, raw->len); - return -1; - } + /* read the SBF block CRC */ + crc = U2(raw->buff + 2); - if (raw->len < 14) { - trace(2, "sbf length error: type=%d len=%d\n", type, raw->len); - return -1; - } - uint32_t tow = U4(raw->buff+8); - uint16_t week = U2(raw->buff+12); - if (tow != 4294967295u && week != 65535u) { - raw->time = gpst2time(week, tow*0.001); - } else { - trace(2, "sbf tow/week error: type=%d len=%d\n", type, raw->len); - // Don't want to miss some blocks, that don't need the time. - if (type != ID_RXSETUP) { - return -1; - } - } + /* checksum skipping first 4 bytes */ + if (sbf_checksum(raw->buff + 4, raw->len - 4) != crc) { + trace(2, "sbf checksum error: type=%04x len=%d\n", type, raw->len); + return -1; + } - if (raw->outtype) { - time2str(raw->time, tstr, 2); - sprintf(raw->msgtype, "SBF %4d (%4d): %s", type, raw->len, tstr); + if (raw->len < 14) { + trace(2, "sbf length error: type=%d len=%d\n", type, raw->len); + return -1; + } + uint32_t tow = U4(raw->buff + 8); + uint16_t week = U2(raw->buff + 12); + if (tow != 4294967295u && week != 65535u) { + raw->time = gpst2time(week, tow * 0.001); + } else { + trace(2, "sbf tow/week error: type=%d len=%d\n", type, raw->len); + // Don't want to miss some blocks, that don't need the time. + if (type != ID_RXSETUP) { + return -1; } + } - switch (type) { - /* Measurement Blocks */ - - /* only read and store data and indicate new obs data only at ID_MEASEPOCH_END */ - case ID_MEASEPOCH: return decode_measepoch(raw); - case ID_MEASEPOCHEXTRA: return decode_measepochextra(raw); - case ID_MEASE3RNG: return decode_meas3ranges(raw); - case ID_MEASE3DOPPLER: return decode_meas3Doppler(raw); - case ID_MEASE3CN: return decode_meas3CN(raw); - case ID_MEASEPOCH_END: - if (raw->outtype) { - sprintf(raw->msgtype, "SBF Measurement Epoch End"); - } - return flushobuf(raw); - + if (raw->outtype) { + time2str(raw->time, tstr, 2); + sprintf(raw->msgtype, "SBF %4d (%4d): %s", type, raw->len, tstr); + } - /* Navigation Page Blocks */ - case ID_GPSRAWCA: return decode_gpsrawcanav(raw, SYS_GPS); - case ID_GPSRAWL2C: - case ID_GPSRAWL5: return decode_gpsrawcnav(raw, SYS_GPS); + switch (type) { + /* Measurement Blocks */ + + /* only read and store data and indicate new obs data only at ID_MEASEPOCH_END */ + case ID_MEASEPOCH: + return decode_measepoch(raw); + case ID_MEASEPOCHEXTRA: + return decode_measepochextra(raw); + case ID_MEASE3RNG: + return decode_meas3ranges(raw); + case ID_MEASE3DOPPLER: + return decode_meas3Doppler(raw); + case ID_MEASE3CN: + return decode_meas3CN(raw); + case ID_MEASEPOCH_END: + if (raw->outtype) { + sprintf(raw->msgtype, "SBF Measurement Epoch End"); + } + return flushobuf(raw); + + /* Navigation Page Blocks */ + case ID_GPSRAWCA: + return decode_gpsrawcanav(raw, SYS_GPS); + case ID_GPSRAWL2C: + case ID_GPSRAWL5: + return decode_gpsrawcnav(raw, SYS_GPS); #ifdef ENAGLO - case ID_GLORAWCA: return decode_glorawcanav(raw); + case ID_GLORAWCA: + return decode_glorawcanav(raw); #endif #ifdef ENAGAL - case ID_GALRAWINAV: return decode_galrawinav(raw); - case ID_GALRAWFNAV: return decode_galrawfnav(raw); - /*case ID_GALRAWCNAV: return decode_galrawcnav(raw); */ + case ID_GALRAWINAV: + return decode_galrawinav(raw); + case ID_GALRAWFNAV: + return decode_galrawfnav(raw); + /*case ID_GALRAWCNAV: return decode_galrawcnav(raw); */ #endif - case ID_GEORAWL1: - case ID_GEORAWL5: return decode_georaw(raw); + case ID_GEORAWL1: + case ID_GEORAWL5: + return decode_georaw(raw); #ifdef ENACMP - case ID_BDSRAW: return decode_cmpraw(raw); - case ID_BDSRAWB1C: - case ID_BDSRAWB2A: - case ID_BDSRAWB2B: return 0; /* yet unsupported by rtklib */ + case ID_BDSRAW: + return decode_cmpraw(raw); + case ID_BDSRAWB1C: + case ID_BDSRAWB2A: + case ID_BDSRAWB2B: + return 0; /* yet unsupported by rtklib */ #endif #ifdef ENAQZS - case ID_QZSRAWL1CA: return decode_gpsrawcanav(raw, SYS_QZS); - case ID_QZSRAWL2C: - case ID_QZSRAWL5: return decode_gpsrawcnav(raw, SYS_QZS); - case ID_QZSSL6: - case ID_QZSSL1C: - case ID_QZSSL1S: - case ID_QZSSL5S: - return 0; + case ID_QZSRAWL1CA: + return decode_gpsrawcanav(raw, SYS_QZS); + case ID_QZSRAWL2C: + case ID_QZSRAWL5: + return decode_gpsrawcnav(raw, SYS_QZS); + case ID_QZSSL6: + case ID_QZSSL1C: + case ID_QZSSL1S: + case ID_QZSSL5S: + return 0; #endif #ifdef ENAIRN - case ID_IRNSSRAW: return decode_navicraw(raw); + case ID_IRNSSRAW: + return decode_navicraw(raw); #ifdef TESTING /* not tested */ - case ID_NAVICLNAV: return decode_naviclnav(raw); + case ID_NAVICLNAV: + return decode_naviclnav(raw); #else - case ID_NAVICLNAV: return 0; + case ID_NAVICLNAV: + return 0; #endif #endif - /* GPS Decoded Message Blocks */ - case ID_GPSNAV: return decode_gpsnav(raw); - case ID_GPSALM: return decode_gpsalm(raw); - case ID_GPSION: return decode_gpsion(raw); - case ID_GPSUTC: return decode_gpsutc(raw); - case ID_GPSCNAV: - case ID_GPSCNAV2: return decode_gpscnav(raw, type); - - /* GLONASS Decoded Message Blocks */ + /* GPS Decoded Message Blocks */ + case ID_GPSNAV: + return decode_gpsnav(raw); + case ID_GPSALM: + return decode_gpsalm(raw); + case ID_GPSION: + return decode_gpsion(raw); + case ID_GPSUTC: + return decode_gpsutc(raw); + case ID_GPSCNAV: + case ID_GPSCNAV2: + return decode_gpscnav(raw, type); + + /* GLONASS Decoded Message Blocks */ #ifdef ENAGLO - case ID_GLONAV: return decode_glonav(raw); - case ID_GLOALM: return 0; /* not suppported by rtklib */ - case ID_GLOTIME: return decode_gloutc(raw); + case ID_GLONAV: + return decode_glonav(raw); + case ID_GLOALM: + return 0; /* not suppported by rtklib */ + case ID_GLOTIME: + return decode_gloutc(raw); #endif - /* Galileo Decoded Message Blocks */ + /* Galileo Decoded Message Blocks */ #ifdef ENAGAL - case ID_GALNAV: return decode_galnav(raw); - case ID_GALALM: return decode_galalm(raw); - case ID_GALION: return decode_galion(raw); - case ID_GALUTC: return decode_galutc(raw); + case ID_GALNAV: + return decode_galnav(raw); + case ID_GALALM: + return decode_galalm(raw); + case ID_GALION: + return decode_galion(raw); + case ID_GALUTC: + return decode_galutc(raw); #endif - /* BeiDou Decoded Message Blocks */ + /* BeiDou Decoded Message Blocks */ #ifdef ENACMP - case ID_BDSNAV: return decode_cmpnav(raw); - case ID_BDSCNAV1: - case ID_BDSCNAV2: - case ID_BDSCNAV3: - return decode_cmpcnav2(raw, type); - case ID_BDSALM: return decode_cmpalm(raw); - case ID_BDSION: return decode_cmpion(raw); - case ID_BDSUTC: return decode_cmputc(raw); + case ID_BDSNAV: + return decode_cmpnav(raw); + case ID_BDSCNAV1: + case ID_BDSCNAV2: + case ID_BDSCNAV3: + return decode_cmpcnav2(raw, type); + case ID_BDSALM: + return decode_cmpalm(raw); + case ID_BDSION: + return decode_cmpion(raw); + case ID_BDSUTC: + return decode_cmputc(raw); #endif - /* QZSS Decoded Message Blocks */ + /* QZSS Decoded Message Blocks */ #ifdef ENAQZS - case ID_QZSSNAV: return decode_qzssnav(raw); + case ID_QZSSNAV: + return decode_qzssnav(raw); #ifdef TESTING /* not tested */ - case ID_QZSSALM: return decode_qzssalm(raw); + case ID_QZSSALM: + return decode_qzssalm(raw); #else - case ID_QZSSALM: - return 0; + case ID_QZSSALM: + return 0; #endif #endif - /* NavIC/IRNSS Decoded Message Blocks */ - - /* SBAS L1 Decoded Message Blocks */ - case ID_GEOMT00: return decode_sbsfast(raw); - case ID_GEOPRNMASK: return decode_sbsprnmask(raw); - case ID_GEOFASTCORR: return decode_sbsfast(raw); - case ID_GEOINTEGRITY: return decode_sbsintegriy(raw); - case ID_GEOFASTCORRDEGR:return decode_sbsfastcorrdegr(raw); - case ID_GEONAV: return decode_geonav(raw); - case ID_GEOIGPMASK: return decode_sbsigpmask(raw); - case ID_GEOLONGTERMCOR: return decode_sbslongcorrh(raw); - case ID_GEOIONODELAY: return decode_sbsionodelay(raw); - - /* External Event Blocks */ - case ID_EXTEVENT: return decode_extevent(raw); - + /* NavIC/IRNSS Decoded Message Blocks */ + + /* SBAS L1 Decoded Message Blocks */ + case ID_GEOMT00: + return decode_sbsfast(raw); + case ID_GEOPRNMASK: + return decode_sbsprnmask(raw); + case ID_GEOFASTCORR: + return decode_sbsfast(raw); + case ID_GEOINTEGRITY: + return decode_sbsintegriy(raw); + case ID_GEOFASTCORRDEGR: + return decode_sbsfastcorrdegr(raw); + case ID_GEONAV: + return decode_geonav(raw); + case ID_GEOIGPMASK: + return decode_sbsigpmask(raw); + case ID_GEOLONGTERMCOR: + return decode_sbslongcorrh(raw); + case ID_GEOIONODELAY: + return decode_sbsionodelay(raw); + + /* External Event Blocks */ + case ID_EXTEVENT: + return decode_extevent(raw); #if 1 /* UNUSED */ - case ID_GENMEASEPOCH: return 0; /* to be implemented */ - case ID_MEASFULLRANGE: return 0; /* to be implemented */ - case ID_SBASL5NAV: return 0; /* to be implemented */ - case ID_SBASL5ALM: return 0; /* to be implemented */ - /* Differential Correction Blocks */ - case ID_DIFFCORRIN: return 0; /* not yet supported */ - - case ID_GEONETWORKTIME: return 0; /* not suppported by rtklib */ - case ID_GEOALM: return 0; - case ID_PVTSATCART: return 0; /* to be checked */ - case ID_GEOCORR: return 0; /* to be checked */ -#endif /* UNUSED */ - - /* commands that don't need to be handled */ - /* Measurement Blocks */ - case ID_MEASE3PP: - case ID_MEASE3MP: - case ID_IQCORR: - case ID_ISMR: - case ID_SQMSAMPLES: - /* Navigation Page Blocks */ - case ID_GNSSNAVBITS: - case ID_GNSSSYMBOLS: - /* Galileo Decoded Message Blocks */ - case ID_GALGSTGPS: - case ID_GALARRLM: - /* SBAS L1 Decoded Message Blocks */ - case ID_GEOSERVICELEVEL: - case ID_GEOCLOCKEPHCOVMATRIX: - case ID_GEODEGRFACTORS: - /* GNSS Position, Velocity and Time Blocks */ - case ID_PVTCART1: - case ID_PVTGEOD1: - case ID_DOP1: - case ID_PVTRESIDUALS1: - case ID_RAIMSTATS1: - case ID_PVTRESIDUALS2: - case ID_PVTCART2: - case ID_PVTGEOD2: - case ID_PVTGEODAUTH: - case ID_COVCART: - case ID_COVGEOD: - case ID_VELCOVCART: - case ID_VELCOVGEOD: - case ID_DOP2: - case ID_DOPAUTH: - case ID_POSCART: - case ID_PVTLOCAL: - case ID_POSPROJ: - case ID_RAIMSTATS2: - case ID_BASEVECCART: - case ID_BASEVECGEOD: - case ID_AMBIGUITIES: - case ID_PVTSUPPORT: - case ID_PVTSUPPORTA: - case ID_PVTEND: - case ID_BASELINE: - /* INS/GNSS Integrated Blocks */ - case ID_INTPVCART: - case ID_INTPVGEOD: - case ID_INTPOSCOVCART: - case ID_INTVELCOVCART: - case ID_INTPOSCOVGEOD: - case ID_INTVELCOVGEOD: - case ID_INTATTEULER: - case ID_INTATTCCOEULER: - case ID_INTPVAAGEOD: - case ID_INSNAVCART: - case ID_INSNAVGEOD: - case ID_IMUBIAS: - /* GNSS Attitude Blocks */ - case ID_ATTEULER: - case ID_ATTCOVEULER: - case ID_AUXPOS: - case ID_ENDATT: - case ID_ATTQUAD: - case ID_ATTCOVQUAD: - /* Receiver Time Blocks */ - case ID_RXTIME: - case ID_PPSOFFSET: - case ID_SYSTIMEOFF: - case ID_FUGROTIMEOFF: - /* External Event Blocks */ - case ID_EXTEVENTCART: - case ID_EXTEVENTGEO: - case ID_EXTEVENTBASEVECCART: - case ID_EXTEVENTBASEVECGEOD: - case ID_EXTEVENTINSNAVCART: - case ID_EXTEVENTINSNAVGEOD: - case ID_EXTEEVENTAATTEULER: - /* Differential Correction Blocks */ - case ID_BASESTATION: - case ID_RTCMDATUM: - case ID_BASELINK: - /* L-Band Demodulator Blocks */ - case ID_LRECEIVER: - case ID_LTRACK: - case ID_LDECODE: - case ID_LBEAMS: - case ID_FUGRODSS: - case ID_FUGROSTAT: - /* External Sensor Blocks */ - case ID_EXTSENSORMEAS: - case ID_EXTSENSORSTATUS: - case ID_EXTSENSORSETUP: - case ID_EXTSENSORSTATUS2: - case ID_EXTSENSORINFO: - case ID_IMUSETUP: - case ID_VELSENSORSETUP: - case ID_LEVERARMSUPPORT1: - /* Status Blocks */ - case ID_RXSTATUS1: - case ID_TRACKSTATUS: - case ID_CHNSTATUS: - case ID_RXSTATUS2: - case ID_SATVISIBILITY: - case ID_INPUTLINK: - case ID_OUTPUTLINK: - case ID_NTRIPCLTSTAT: - case ID_NTRIPSVRSTAT: - case ID_IPSTATUS: - case ID_WIFIAPSTATUS: - case ID_WIFICLTSTATUS: - case ID_CELLULARSTATUS: - case ID_BLUETOOTHSTATUS: - case ID_DYNDNSSTATUS: - case ID_POWERSTATUS: - case ID_QUALIND: - case ID_DISKSTATUS: - case ID_LOGSTATUS: - case ID_UHFSTATUS: - case ID_RFSTATUS: - case ID_RIMSHEALTH: - case ID_OSNMASTATUS: - case ID_GALNAVMONITOR: - case ID_GALNAVRCEDMONITOR: - case ID_INAVMONITOR: - case ID_P2PPSTATUS: - case ID_COSMOSTATUS: - case ID_GALAUTHSTATUS: - case ID_FUGROAUTHSTATUS: - return 0; - /* Miscellaneous Blocks */ - case ID_RXSETUP: - return decode_rxsetup(raw); - case ID_RXMESSAGE: - case ID_COMMANDS: - case ID_COMMENT: - case ID_BBSMPS: - case ID_RXCOMPS: - case ID_ASCIIIN: - case ID_ENCAPSOUT: - case ID_RAWDATAIN: - case ID_IMURAWSAMPLES: - case ID_INTERFACESTATS: - /* Advanced Blocks */ - case ID_SYSINFO: - - return 0; - default: + case ID_GENMEASEPOCH: + return 0; /* to be implemented */ + case ID_MEASFULLRANGE: + return 0; /* to be implemented */ + case ID_SBASL5NAV: + return 0; /* to be implemented */ + case ID_SBASL5ALM: + return 0; /* to be implemented */ + /* Differential Correction Blocks */ + case ID_DIFFCORRIN: + return 0; /* not yet supported */ + + case ID_GEONETWORKTIME: + return 0; /* not suppported by rtklib */ + case ID_GEOALM: + return 0; + case ID_PVTSATCART: + return 0; /* to be checked */ + case ID_GEOCORR: + return 0; /* to be checked */ +#endif /* UNUSED */ + + /* commands that don't need to be handled */ + /* Measurement Blocks */ + case ID_MEASE3PP: + case ID_MEASE3MP: + case ID_IQCORR: + case ID_ISMR: + case ID_SQMSAMPLES: + /* Navigation Page Blocks */ + case ID_GNSSNAVBITS: + case ID_GNSSSYMBOLS: + /* Galileo Decoded Message Blocks */ + case ID_GALGSTGPS: + case ID_GALARRLM: + /* SBAS L1 Decoded Message Blocks */ + case ID_GEOSERVICELEVEL: + case ID_GEOCLOCKEPHCOVMATRIX: + case ID_GEODEGRFACTORS: + /* GNSS Position, Velocity and Time Blocks */ + case ID_PVTCART1: + case ID_PVTGEOD1: + case ID_DOP1: + case ID_PVTRESIDUALS1: + case ID_RAIMSTATS1: + case ID_PVTRESIDUALS2: + case ID_PVTCART2: + case ID_PVTGEOD2: + case ID_PVTGEODAUTH: + case ID_COVCART: + case ID_COVGEOD: + case ID_VELCOVCART: + case ID_VELCOVGEOD: + case ID_DOP2: + case ID_DOPAUTH: + case ID_POSCART: + case ID_PVTLOCAL: + case ID_POSPROJ: + case ID_RAIMSTATS2: + case ID_BASEVECCART: + case ID_BASEVECGEOD: + case ID_AMBIGUITIES: + case ID_PVTSUPPORT: + case ID_PVTSUPPORTA: + case ID_PVTEND: + case ID_BASELINE: + /* INS/GNSS Integrated Blocks */ + case ID_INTPVCART: + case ID_INTPVGEOD: + case ID_INTPOSCOVCART: + case ID_INTVELCOVCART: + case ID_INTPOSCOVGEOD: + case ID_INTVELCOVGEOD: + case ID_INTATTEULER: + case ID_INTATTCCOEULER: + case ID_INTPVAAGEOD: + case ID_INSNAVCART: + case ID_INSNAVGEOD: + case ID_IMUBIAS: + /* GNSS Attitude Blocks */ + case ID_ATTEULER: + case ID_ATTCOVEULER: + case ID_AUXPOS: + case ID_ENDATT: + case ID_ATTQUAD: + case ID_ATTCOVQUAD: + /* Receiver Time Blocks */ + case ID_RXTIME: + case ID_PPSOFFSET: + case ID_SYSTIMEOFF: + case ID_FUGROTIMEOFF: + /* External Event Blocks */ + case ID_EXTEVENTCART: + case ID_EXTEVENTGEO: + case ID_EXTEVENTBASEVECCART: + case ID_EXTEVENTBASEVECGEOD: + case ID_EXTEVENTINSNAVCART: + case ID_EXTEVENTINSNAVGEOD: + case ID_EXTEEVENTAATTEULER: + /* Differential Correction Blocks */ + case ID_BASESTATION: + case ID_RTCMDATUM: + case ID_BASELINK: + /* L-Band Demodulator Blocks */ + case ID_LRECEIVER: + case ID_LTRACK: + case ID_LDECODE: + case ID_LBEAMS: + case ID_FUGRODSS: + case ID_FUGROSTAT: + /* External Sensor Blocks */ + case ID_EXTSENSORMEAS: + case ID_EXTSENSORSTATUS: + case ID_EXTSENSORSETUP: + case ID_EXTSENSORSTATUS2: + case ID_EXTSENSORINFO: + case ID_IMUSETUP: + case ID_VELSENSORSETUP: + case ID_LEVERARMSUPPORT1: + /* Status Blocks */ + case ID_RXSTATUS1: + case ID_TRACKSTATUS: + case ID_CHNSTATUS: + case ID_RXSTATUS2: + case ID_SATVISIBILITY: + case ID_INPUTLINK: + case ID_OUTPUTLINK: + case ID_NTRIPCLTSTAT: + case ID_NTRIPSVRSTAT: + case ID_IPSTATUS: + case ID_WIFIAPSTATUS: + case ID_WIFICLTSTATUS: + case ID_CELLULARSTATUS: + case ID_BLUETOOTHSTATUS: + case ID_DYNDNSSTATUS: + case ID_POWERSTATUS: + case ID_QUALIND: + case ID_DISKSTATUS: + case ID_LOGSTATUS: + case ID_UHFSTATUS: + case ID_RFSTATUS: + case ID_RIMSHEALTH: + case ID_OSNMASTATUS: + case ID_GALNAVMONITOR: + case ID_GALNAVRCEDMONITOR: + case ID_INAVMONITOR: + case ID_P2PPSTATUS: + case ID_COSMOSTATUS: + case ID_GALAUTHSTATUS: + case ID_FUGROAUTHSTATUS: + return 0; + /* Miscellaneous Blocks */ + case ID_RXSETUP: + return decode_rxsetup(raw); + case ID_RXMESSAGE: + case ID_COMMANDS: + case ID_COMMENT: + case ID_BBSMPS: + case ID_RXCOMPS: + case ID_ASCIIIN: + case ID_ENCAPSOUT: + case ID_RAWDATAIN: + case ID_IMURAWSAMPLES: + case ID_INTERFACESTATS: + /* Advanced Blocks */ + case ID_SYSINFO: + + return 0; + default: #ifdef RTK_DISABLED /* debug output */ - if (raw->outtype) { - sprintf(raw->msgtype,"SBF 0x%04X (%4d):",type, raw->len); - } + if (raw->outtype) { + sprintf(raw->msgtype, "SBF 0x%04X (%4d):", type, raw->len); + } #endif - trace(3, "decode_sbf: unused frame type=%04x len=%d\n", type, raw->len); - /* there are many more SBF blocks to be extracted */ - } - return 0; + trace(3, "decode_sbf: unused frame type=%04x len=%d\n", type, raw->len); + /* there are many more SBF blocks to be extracted */ + } + return 0; } /* sync to the beginning of a block ------------------------------------------*/ -static int sync_sbf(unsigned char *buff, unsigned char data) -{ - buff[0] = buff[1]; - buff[1] = data; - return buff[0]== SBF_SYNC1 && buff[1]==SBF_SYNC2; +static int sync_sbf(unsigned char *buff, unsigned char data) { + buff[0] = buff[1]; + buff[1] = data; + return buff[0] == SBF_SYNC1 && buff[1] == SBF_SYNC2; } /* input sbf raw data from stream ---------------------------------------------- -* get to the next sbf raw block from stream -* args : raw_t *raw IO receiver raw data control struct -* unsigned char data I stream data (1byte) -* return : status (-1: error message, 0: no message, 1: input observation data, -* 2: input ephemeris, 3: input sbas message, -* 9: input ion/utc parameter) -* to specify input options for sbf, set raw->opt to the following -* option strings separated by spaces. -* -* -* -EPHALL : input all ephemerides -* -AUX1 : select antenna Aux1 (default: main) -* -AUX2 : select antenna Aux2 (default: main) -* -GL1W : select 1W for GPS L1 (default: 1C) -* -GL1L : select 1L for GPS L1 (default: 1C) -* -GL2L : select 2L for GPS L2 (default: 2W) -* -RL1P : select 1P for GLO G1 (default: 1C) -* -RL2C : select 2C for GLO G2 (default: 2P) -* -JL1L : select 1L for QZS L1 (default: 1C) -* -JL1Z : select 1Z for QZS L1 (default: 1C) -* -CL1P : select 1P for BDS B1 (default: 2I) -* -GALINAV : select I/NAV for Galileo ephemeris (default: all) -* -GALFNAV : select F/NAV for Galileo ephemeris (default: all) -* -NO_MEAS2: ignore range measurements version 2 blocks -* -NO_MEAS3: ignore range measurements version 3 blocks -* -RCVSTDS : save receiver stdevs to unused RINEX fields -*-----------------------------------------------------------------------------*/ -extern int input_sbf(raw_t *raw, unsigned char data) -{ - trace(5, "input_sbf: data=%02x\n",data); - - if (raw->nbyte == 0) { - if (sync_sbf(raw->buff, data)) raw->nbyte = 2; - return 0; - } - raw->buff[raw->nbyte++] = data; + * get to the next sbf raw block from stream + * args : raw_t *raw IO receiver raw data control struct + * unsigned char data I stream data (1byte) + * return : status (-1: error message, 0: no message, 1: input observation data, + * 2: input ephemeris, 3: input sbas message, + * 9: input ion/utc parameter) + * to specify input options for sbf, set raw->opt to the following + * option strings separated by spaces. + * + * + * -EPHALL : input all ephemerides + * -AUX1 : select antenna Aux1 (default: main) + * -AUX2 : select antenna Aux2 (default: main) + * -GL1W : select 1W for GPS L1 (default: 1C) + * -GL1L : select 1L for GPS L1 (default: 1C) + * -GL2L : select 2L for GPS L2 (default: 2W) + * -RL1P : select 1P for GLO G1 (default: 1C) + * -RL2C : select 2C for GLO G2 (default: 2P) + * -JL1L : select 1L for QZS L1 (default: 1C) + * -JL1Z : select 1Z for QZS L1 (default: 1C) + * -CL1P : select 1P for BDS B1 (default: 2I) + * -GALINAV : select I/NAV for Galileo ephemeris (default: all) + * -GALFNAV : select F/NAV for Galileo ephemeris (default: all) + * -NO_MEAS2: ignore range measurements version 2 blocks + * -NO_MEAS3: ignore range measurements version 3 blocks + * -RCVSTDS : save receiver stdevs to unused RINEX fields + *-----------------------------------------------------------------------------*/ +extern int input_sbf(raw_t *raw, unsigned char data) { + trace(5, "input_sbf: data=%02x\n", data); + + if (raw->nbyte == 0) { + if (sync_sbf(raw->buff, data)) raw->nbyte = 2; + return 0; + } + raw->buff[raw->nbyte++] = data; - if (raw->nbyte < 8) return 0; + if (raw->nbyte < 8) return 0; - if ((raw->len = U2(raw->buff+6)) > MAXRAWLEN) { - trace(2, "sbf length error: len=%d\n", raw->len); - raw->nbyte = 0; - return -1; - } - if (raw->nbytelen) return 0; + if ((raw->len = U2(raw->buff + 6)) > MAXRAWLEN) { + trace(2, "sbf length error: len=%d\n", raw->len); raw->nbyte = 0; + return -1; + } + if (raw->nbyte < raw->len) return 0; + raw->nbyte = 0; - return decode_sbf(raw); + return decode_sbf(raw); } /* sbf raw block finder -------------------------------------------------------- -* get to the next sbf raw block from file -* args : raw_t *raw IO receiver raw data control struct -* FILE *fp I file pointer -* return : status(-2: end of file, -1...9: same as above) -*-----------------------------------------------------------------------------*/ -extern int input_sbff(raw_t *raw, FILE *fp) -{ - int i, data; - trace(4, "input_sbff:\n"); - - /* go to the beginning of the first block */ - if (raw->nbyte == 0) { - for (i=0;;i++) { - data=fgetc(fp); - if (data == EOF) return -2; - if (sync_sbf(raw->buff, (unsigned char)data)) break; - if (i >= MAXRAWLEN) return 0; - } + * get to the next sbf raw block from file + * args : raw_t *raw IO receiver raw data control struct + * FILE *fp I file pointer + * return : status(-2: end of file, -1...9: same as above) + *-----------------------------------------------------------------------------*/ +extern int input_sbff(raw_t *raw, FILE *fp) { + int i, data; + trace(4, "input_sbff:\n"); + + /* go to the beginning of the first block */ + if (raw->nbyte == 0) { + for (i = 0;; i++) { + data = fgetc(fp); + if (data == EOF) return -2; + if (sync_sbf(raw->buff, (unsigned char)data)) break; + if (i >= MAXRAWLEN) return 0; } + } - /* load block header content (8 bytes) in raw->buff */ - /* since we already read the first two, we just read the next 6 bytes */ - if (fread(raw->buff+2, 1, 6, fp) < 6) return -2; - raw->nbyte = 8; + /* load block header content (8 bytes) in raw->buff */ + /* since we already read the first two, we just read the next 6 bytes */ + if (fread(raw->buff + 2, 1, 6, fp) < 6) return -2; + raw->nbyte = 8; - /* decode the length of the block and store it in len*/ - if ((raw->len = U2(raw->buff+6)) > MAXRAWLEN) { - trace(2, "sbf length error: len=%d\n", raw->len); - raw->nbyte = 0; - return -1; - } + /* decode the length of the block and store it in len*/ + if ((raw->len = U2(raw->buff + 6)) > MAXRAWLEN) { + trace(2, "sbf length error: len=%d\n", raw->len); + raw->nbyte = 0; + return -1; + } - /* let's store in raw->buff the whole block of length len */ - /* 8 bytes have been already read, we read raw->len-8 more */ - if (fread(raw->buff+8, 1, raw->len-8, fp) < (size_t)(raw->len-8)) return -2; - raw->nbyte = 0; /* this indicates where we point inside raw->buff */ + /* let's store in raw->buff the whole block of length len */ + /* 8 bytes have been already read, we read raw->len-8 more */ + if (fread(raw->buff + 8, 1, raw->len - 8, fp) < (size_t)(raw->len - 8)) return -2; + raw->nbyte = 0; /* this indicates where we point inside raw->buff */ - /* decode SBF block */ - return decode_sbf(raw); + /* decode SBF block */ + return decode_sbf(raw); } diff --git a/src/rcv/skytraq.c b/src/rcv/skytraq.c index ce84cf410..543b0f5e3 100644 --- a/src/rcv/skytraq.c +++ b/src/rcv/skytraq.c @@ -1,943 +1,950 @@ /*------------------------------------------------------------------------------ -* skytraq.c : skytraq receiver dependent functions -* -* Copyright (C) 2009-2020 by T.TAKASU, All rights reserved. -* -* reference : -* [1] Skytraq, Application Note AN0023 Binary Message of SkyTraq Venus 6 -* GPS Receiver, ver 1.4.8, August 21, 2008 -* [2] Skytraq, Application Note AN0024 Raw Measurement Binary Message -* Extension of SkyTraq Venus 6 GPS Receiver, ver 0.5, October 9, 2009 -* [3] Skytraq, Application Note AN0024G2 Binary Message of SkyTraq Venus 7 -* GLONASS/GPS Receiver (Raw Measurement F/W), ver 1.4.26, April 26, 2012 -* [4] Skytraq, Application Note AN0030 Binary Message of Raw Measurement -* Data Extension of SkyTraq Venus 8 GNSS Receiver, ver.1.4.29, -* April 3, 2014 -* [5] Skytraq, Application Note AN0030 Binary Message of Raw Measurement -* Data Extension of SkyTraq Venus 8 GNSS Receiver, ver.1.4.31, -* August 12, 2014 -* [6] Skytraq, Application Note AN0030 Binary Message of Raw Measurement -* Data Extension of SkyTraq Venus 8 GNSS Receiver, ver.1.4.32, -* Sep 26, 2016 -* [7] Skytraq, Application Note AN0039 Binary Messages of Raw Measurement -* Data Extension of SkyTraq Phoneix GNSS Receiver, ver.1.4.39, -* Dec 30, 2020 -* -* notes : -* The byte order of S1315F raw message is big-endian inconsistent to [1]. -* -* version : $Revision:$ -* history : 2009/10/10 1.0 new -* 2009/11/08 1.1 flip carrier-phase polarity for F/W 1.8.23-20091106 -* 2011/05/27 1.2 add almanac decoding -* fix problem with ARM compiler -* 2011/07/01 1.3 suppress warning -* 2013/03/10 1.5 change option -invcp to -INVCP -* 2014/11/09 1.6 support glonass, qzss and beidou -* 2016/10/09 1.7 support F/W version specified as ref [6] -* 2017/04/11 1.8 (char *) -> (signed char *) -* 2017/05/08 1.9 fix bug on decoding extended raw meas v.1 (0xE5) -* fix bug on encoding CFG-BIN message (0x1E) -* add decode of ack/nack to request msg (0x83/0x84) -* 2020/10/30 1.10 add adjustment of gps week by cpu time -* CODE_L1I -> CODE_L2I for BDS -* use integer type in stdint.h -* suppress warnings -*-----------------------------------------------------------------------------*/ + * skytraq.c : skytraq receiver dependent functions + * + * Copyright (C) 2009-2020 by T.TAKASU, All rights reserved. + * + * reference : + * [1] Skytraq, Application Note AN0023 Binary Message of SkyTraq Venus 6 + * GPS Receiver, ver 1.4.8, August 21, 2008 + * [2] Skytraq, Application Note AN0024 Raw Measurement Binary Message + * Extension of SkyTraq Venus 6 GPS Receiver, ver 0.5, October 9, 2009 + * [3] Skytraq, Application Note AN0024G2 Binary Message of SkyTraq Venus 7 + * GLONASS/GPS Receiver (Raw Measurement F/W), ver 1.4.26, April 26, 2012 + * [4] Skytraq, Application Note AN0030 Binary Message of Raw Measurement + * Data Extension of SkyTraq Venus 8 GNSS Receiver, ver.1.4.29, + * April 3, 2014 + * [5] Skytraq, Application Note AN0030 Binary Message of Raw Measurement + * Data Extension of SkyTraq Venus 8 GNSS Receiver, ver.1.4.31, + * August 12, 2014 + * [6] Skytraq, Application Note AN0030 Binary Message of Raw Measurement + * Data Extension of SkyTraq Venus 8 GNSS Receiver, ver.1.4.32, + * Sep 26, 2016 + * [7] Skytraq, Application Note AN0039 Binary Messages of Raw Measurement + * Data Extension of SkyTraq Phoneix GNSS Receiver, ver.1.4.39, + * Dec 30, 2020 + * + * notes : + * The byte order of S1315F raw message is big-endian inconsistent to [1]. + * + * version : $Revision:$ + * history : 2009/10/10 1.0 new + * 2009/11/08 1.1 flip carrier-phase polarity for F/W 1.8.23-20091106 + * 2011/05/27 1.2 add almanac decoding + * fix problem with ARM compiler + * 2011/07/01 1.3 suppress warning + * 2013/03/10 1.5 change option -invcp to -INVCP + * 2014/11/09 1.6 support glonass, qzss and beidou + * 2016/10/09 1.7 support F/W version specified as ref [6] + * 2017/04/11 1.8 (char *) -> (signed char *) + * 2017/05/08 1.9 fix bug on decoding extended raw meas v.1 (0xE5) + * fix bug on encoding CFG-BIN message (0x1E) + * add decode of ack/nack to request msg (0x83/0x84) + * 2020/10/30 1.10 add adjustment of gps week by cpu time + * CODE_L1I -> CODE_L2I for BDS + * use integer type in stdint.h + * suppress warnings + *-----------------------------------------------------------------------------*/ #define _POSIX_C_SOURCE 199506 #include "rtklib.h" -#define STQSYNC1 0xA0 /* skytraq binary sync code 1 */ -#define STQSYNC2 0xA1 /* skytraq binary sync code 2 */ - -#define ID_STQTIME 0xDC /* skytraq message id: measurement epoch */ -#define ID_STQRAW 0xDD /* skytraq message id: raw measurement */ -#define ID_STQSVCH 0xDE /* skytraq message id: SV and channel status */ -#define ID_STQSTAT 0xDF /* skytraq message id: navigation status */ -#define ID_STQGPS 0xE0 /* skytraq message id: gps/qzs subframe */ -#define ID_STQGLO 0xE1 /* skytraq message id: glonass string */ -#define ID_STQBDSD1 0xE2 /* skytraq message id: beidou d1 subframe */ -#define ID_STQBDSD2 0xE3 /* skytraq message id: beidou d2 subframe */ -#define ID_STQRAWX 0xE5 /* skytraq message id: extended raw meas v.1 */ -#define ID_STQGENE 0xE6 /* skytraq message id: general subframe data */ -#define ID_STQGLOE 0x5C /* skytraq message id: glonass ephemeris */ -#define ID_STQACK 0x83 /* skytraq message id: ack to request msg */ -#define ID_STQNACK 0x84 /* skytraq message id: nack to request msg */ - -#define ID_RESTART 0x01 /* skytraq message id: system restart */ -#define ID_CFGSERI 0x05 /* skytraq message id: configure serial port */ -#define ID_CFGFMT 0x09 /* skytraq message id: configure message format */ -#define ID_CFGRATE 0x12 /* skytraq message id: configure message rate */ -#define ID_CFGBIN 0x1E /* skytraq message id: configure binary message */ -#define ID_GETGLOEPH 0x5B /* skytraq message id: get glonass ephemeris */ +#define STQSYNC1 0xA0 /* skytraq binary sync code 1 */ +#define STQSYNC2 0xA1 /* skytraq binary sync code 2 */ + +#define ID_STQTIME 0xDC /* skytraq message id: measurement epoch */ +#define ID_STQRAW 0xDD /* skytraq message id: raw measurement */ +#define ID_STQSVCH 0xDE /* skytraq message id: SV and channel status */ +#define ID_STQSTAT 0xDF /* skytraq message id: navigation status */ +#define ID_STQGPS 0xE0 /* skytraq message id: gps/qzs subframe */ +#define ID_STQGLO 0xE1 /* skytraq message id: glonass string */ +#define ID_STQBDSD1 0xE2 /* skytraq message id: beidou d1 subframe */ +#define ID_STQBDSD2 0xE3 /* skytraq message id: beidou d2 subframe */ +#define ID_STQRAWX 0xE5 /* skytraq message id: extended raw meas v.1 */ +#define ID_STQGENE 0xE6 /* skytraq message id: general subframe data */ +#define ID_STQGLOE 0x5C /* skytraq message id: glonass ephemeris */ +#define ID_STQACK 0x83 /* skytraq message id: ack to request msg */ +#define ID_STQNACK 0x84 /* skytraq message id: nack to request msg */ + +#define ID_RESTART 0x01 /* skytraq message id: system restart */ +#define ID_CFGSERI 0x05 /* skytraq message id: configure serial port */ +#define ID_CFGFMT 0x09 /* skytraq message id: configure message format */ +#define ID_CFGRATE 0x12 /* skytraq message id: configure message rate */ +#define ID_CFGBIN 0x1E /* skytraq message id: configure binary message */ +#define ID_GETGLOEPH 0x5B /* skytraq message id: get glonass ephemeris */ /* extract field (big-endian) ------------------------------------------------*/ -#define U1(p) (*((uint8_t *)(p))) -#define I1(p) (*((int8_t *)(p))) - -static uint16_t U2(uint8_t *p) -{ - uint16_t value; - uint8_t *q=(uint8_t *)&value+1; - int i; - for (i=0;i<2;i++) *q--=*p++; - return value; +#define U1(p) (*((uint8_t *)(p))) +#define I1(p) (*((int8_t *)(p))) + +static uint16_t U2(uint8_t *p) { + uint16_t value; + uint8_t *q = (uint8_t *)&value + 1; + int i; + for (i = 0; i < 2; i++) *q-- = *p++; + return value; } -static uint32_t U4(uint8_t *p) -{ - uint32_t value; - uint8_t *q=(uint8_t *)&value+3; - int i; - for (i=0;i<4;i++) *q--=*p++; - return value; +static uint32_t U4(uint8_t *p) { + uint32_t value; + uint8_t *q = (uint8_t *)&value + 3; + int i; + for (i = 0; i < 4; i++) *q-- = *p++; + return value; } -static float R4(uint8_t *p) -{ - float value; - uint8_t *q=(uint8_t *)&value+3; - int i; - for (i=0;i<4;i++) *q--=*p++; - return value; +static float R4(uint8_t *p) { + float value; + uint8_t *q = (uint8_t *)&value + 3; + int i; + for (i = 0; i < 4; i++) *q-- = *p++; + return value; } -static double R8(uint8_t *p) -{ - double value; - uint8_t *q=(uint8_t *)&value+7; - int i; - for (i=0;i<8;i++) *q--=*p++; - return value; +static double R8(uint8_t *p) { + double value; + uint8_t *q = (uint8_t *)&value + 7; + int i; + for (i = 0; i < 8; i++) *q-- = *p++; + return value; } /* checksum ------------------------------------------------------------------*/ -static uint8_t checksum(uint8_t *buff, int len) -{ - uint8_t cs=0; - int i; - - for (i=4;i full week ---------------------------------------------------*/ -static void adj_utcweek(gtime_t time, double *utc) -{ - int week; - - if (utc[3]>=256.0) return; - time2gpst(time,&week); - utc[3]+=week/256*256; - if (utc[3]week+128) utc[3]-=256.0; +static void adj_utcweek(gtime_t time, double *utc) { + int week; + + if (utc[3] >= 256.0) return; + time2gpst(time, &week); + utc[3] += week / 256 * 256; + if (utc[3] < week - 128) + utc[3] += 256.0; + else if (utc[3] > week + 128) + utc[3] -= 256.0; } /* GNSSId to system ---------------------------------------------------------*/ -static int sky_sys(int gnssid) -{ - switch (gnssid) { - case 0: return SYS_GPS; - case 1: return SYS_SBS; - case 2: return SYS_GLO; - case 3: return SYS_GAL; - case 4: return SYS_QZS; - case 5: return SYS_CMP; - case 6: return SYS_IRN; - } - return 0; +static int sky_sys(int gnssid) { + switch (gnssid) { + case 0: + return SYS_GPS; + case 1: + return SYS_SBS; + case 2: + return SYS_GLO; + case 3: + return SYS_GAL; + case 4: + return SYS_QZS; + case 5: + return SYS_CMP; + case 6: + return SYS_IRN; + } + return 0; } /* UBX SigId to signal (ref [5] 1.5.4) ---------------------------------------*/ static int sky_sig(int sys, int signal_type) { - if (sys==SYS_GPS) { - switch (signal_type) { - case 1: return CODE_L1X; - case 2: return CODE_L2X; - case 4: return CODE_L5X; - default: return CODE_L1C; - } - } - else if (sys==SYS_SBS) { + if (sys == SYS_GPS) { + switch (signal_type) { + case 1: + return CODE_L1X; + case 2: + return CODE_L2X; + case 4: + return CODE_L5X; + default: return CODE_L1C; } - else if (sys==SYS_GLO) { - switch (signal_type) { - case 2: return CODE_L2C; - case 4: return CODE_L3X; - default: return CODE_L1C; - } - } - else if (sys==SYS_GAL) { - switch (signal_type) { - case 4: return CODE_L5X; - case 5: return CODE_L7X; - case 6: return CODE_L6X; - default: return CODE_L1C; - } - } - else if (sys==SYS_QZS) { - switch (signal_type) { - case 1: return CODE_L1X; - case 2: return CODE_L2X; - case 4: return CODE_L5X; - case 6: return CODE_L6X; - default: return CODE_L1C; - } + } else if (sys == SYS_SBS) { + return CODE_L1C; + } else if (sys == SYS_GLO) { + switch (signal_type) { + case 2: + return CODE_L2C; + case 4: + return CODE_L3X; + default: + return CODE_L1C; } - else if (sys==SYS_CMP) { /* BeiDou */ - switch (signal_type) { - case 1: return CODE_L1X; - case 4: return CODE_L5X; - case 5: return CODE_L7I; - case 7: return CODE_L6I; - default: return CODE_L2I; - } + } else if (sys == SYS_GAL) { + switch (signal_type) { + case 4: + return CODE_L5X; + case 5: + return CODE_L7X; + case 6: + return CODE_L6X; + default: + return CODE_L1C; } - else { - trace(2,"stq rawx gnss type error: type=%d\n",sys); - return(CODE_NONE); + } else if (sys == SYS_QZS) { + switch (signal_type) { + case 1: + return CODE_L1X; + case 2: + return CODE_L2X; + case 4: + return CODE_L5X; + case 6: + return CODE_L6X; + default: + return CODE_L1C; } + } else if (sys == SYS_CMP) { /* BeiDou */ + switch (signal_type) { + case 1: + return CODE_L1X; + case 4: + return CODE_L5X; + case 5: + return CODE_L7I; + case 7: + return CODE_L6I; + default: + return CODE_L2I; + } + } else { + trace(2, "stq rawx gnss type error: type=%d\n", sys); + return (CODE_NONE); + } } /* decode skytraq measurement epoch (0xDC) -----------------------------------*/ -static int decode_stqtime(raw_t *raw) -{ - uint8_t *p=raw->buff+4; - double tow; - int week; - - trace(4,"decode_stqtime: len=%d\n",raw->len); - - raw->iod=U1(p+1); - week =U2(p+2); - week =adjgpsweek(week); - tow =U4(p+4)*0.001; - raw->time=gpst2time(week,tow); - - if (raw->outtype) { - sprintf(raw->msgtype,"SKYTRAQ EPOCH (%4d): iod=%d week=%d tow=%.3f", - raw->len,raw->iod,week,tow); - } - return 0; +static int decode_stqtime(raw_t *raw) { + uint8_t *p = raw->buff + 4; + double tow; + int week; + + trace(4, "decode_stqtime: len=%d\n", raw->len); + + raw->iod = U1(p + 1); + week = U2(p + 2); + week = adjgpsweek(week); + tow = U4(p + 4) * 0.001; + raw->time = gpst2time(week, tow); + + if (raw->outtype) { + sprintf(raw->msgtype, "SKYTRAQ EPOCH (%4d): iod=%d week=%d tow=%.3f", raw->len, raw->iod, week, + tow); + } + return 0; } /* decode skytraq raw measurement (0xDD) -------------------------------------*/ -static int decode_stqraw(raw_t *raw) -{ - uint8_t *p=raw->buff+4,ind; - double pr1,cp1; - int i,j,iod,prn,sys,sat,n=0,nsat; - - trace(4,"decode_stqraw: len=%d\n",raw->len); - - if (raw->outtype) { - sprintf(raw->msgtype,"SKYTRAQ RAW (%4d): nsat=%d",raw->len,U1(p+2)); - } - iod=U1(p+1); - if (iod!=raw->iod) { /* need preceding measurement epoch (0xDC) */ - trace(2,"stq raw iod error: iod=%d %d\n",iod,raw->iod); - return -1; - } - nsat=U1(p+2); - if (raw->len<8+23*nsat) { - trace(2,"stq raw length error: len=%d nsat=%d\n",raw->len,nsat); - return -1; +static int decode_stqraw(raw_t *raw) { + uint8_t *p = raw->buff + 4, ind; + double pr1, cp1; + int i, j, iod, prn, sys, sat, n = 0, nsat; + + trace(4, "decode_stqraw: len=%d\n", raw->len); + + if (raw->outtype) { + sprintf(raw->msgtype, "SKYTRAQ RAW (%4d): nsat=%d", raw->len, U1(p + 2)); + } + iod = U1(p + 1); + if (iod != raw->iod) { /* need preceding measurement epoch (0xDC) */ + trace(2, "stq raw iod error: iod=%d %d\n", iod, raw->iod); + return -1; + } + nsat = U1(p + 2); + if (raw->len < 8 + 23 * nsat) { + trace(2, "stq raw length error: len=%d nsat=%d\n", raw->len, nsat); + return -1; + } + for (i = 0, p += 3; i < nsat && i < MAXOBS; i++, p += 23) { + prn = U1(p); + + if (MINPRNGPS <= prn && prn <= MAXPRNGPS) { + sys = SYS_GPS; + } else if (MINPRNGLO <= prn - 64 && prn - 64 <= MAXPRNGLO) { + sys = SYS_GLO; + prn -= 64; + } else if (MINPRNQZS <= prn && prn <= MAXPRNQZS) { + sys = SYS_QZS; + } else if (MINPRNCMP <= prn - 200 && prn - 200 <= MAXPRNCMP) { + sys = SYS_CMP; + prn -= 200; + } else { + trace(2, "stq raw satellite number error: prn=%d\n", prn); + continue; + } + if (!(sat = satno(sys, prn))) { + trace(2, "stq raw satellite number error: sys=%d prn=%d\n", sys, prn); + continue; + } + ind = U1(p + 22); + pr1 = !(ind & 1) ? 0.0 : R8(p + 2); + cp1 = !(ind & 4) ? 0.0 : R8(p + 10); + cp1 -= floor((cp1 + 1E9) / 2E9) * 2E9; /* -10^9 < cp1 < 10^9 */ + + raw->obs.data[n].P[0] = pr1; + raw->obs.data[n].L[0] = cp1; + raw->obs.data[n].D[0] = !(ind & 2) ? 0.0 : R4(p + 18); + raw->obs.data[n].SNR[0] = U1(p + 1); + raw->obs.data[n].LLI[0] = 0; + raw->obs.data[n].code[0] = sys == SYS_CMP ? CODE_L2I : CODE_L1C; + + raw->lockt[sat - 1][0] = ind & 8 ? 1 : 0; /* cycle slip */ + + if (raw->obs.data[n].L[0] != 0.0) { + raw->obs.data[n].LLI[0] = (uint8_t)raw->lockt[sat - 1][0]; + raw->lockt[sat - 1][0] = 0; } - for (i=0,p+=3;iobs.data[n].P[0]=pr1; - raw->obs.data[n].L[0]=cp1; - raw->obs.data[n].D[0]=!(ind&2)?0.0:R4(p+18); - raw->obs.data[n].SNR[0]=U1(p+1); - raw->obs.data[n].LLI[0]=0; - raw->obs.data[n].code[0]=sys==SYS_CMP?CODE_L2I:CODE_L1C; - - raw->lockt[sat-1][0]=ind&8?1:0; /* cycle slip */ - - if (raw->obs.data[n].L[0]!=0.0) { - raw->obs.data[n].LLI[0]=(uint8_t)raw->lockt[sat-1][0]; - raw->lockt[sat-1][0]=0; - } - /* receiver dependent options */ - if (strstr(raw->opt,"-INVCP")) { - raw->obs.data[n].L[0]*=-1.0; - } - raw->obs.data[n].time=raw->time; - raw->obs.data[n].sat =sat; - - for (j=1;jobs.data[n].L[j]=raw->obs.data[n].P[j]=0.0; - raw->obs.data[n].D[j]=raw->obs.data[n].SNR[j]=0.0; - raw->obs.data[n].LLI[j]=0; - raw->obs.data[n].code[j]=CODE_NONE; - } - n++; + /* receiver dependent options */ + if (strstr(raw->opt, "-INVCP")) { + raw->obs.data[n].L[0] *= -1.0; } - raw->obs.n=n; - return n>0?1:0; + raw->obs.data[n].time = raw->time; + raw->obs.data[n].sat = sat; + + for (j = 1; j < NFREQ + NEXOBS; j++) { + raw->obs.data[n].L[j] = raw->obs.data[n].P[j] = 0.0; + raw->obs.data[n].D[j] = raw->obs.data[n].SNR[j] = 0.0; + raw->obs.data[n].LLI[j] = 0; + raw->obs.data[n].code[j] = CODE_NONE; + } + n++; + } + raw->obs.n = n; + return n > 0 ? 1 : 0; } /* decode skytraq extended raw measurement data v.1 (0xE5) -------------------*/ -static int decode_stqrawx(raw_t *raw) -{ - uint8_t *p=raw->buff+4,ind; - double tow,peri,pr1,cp1; - int i,j,k,ver,week,nsat,sys,sig,prn,sat,n=0,idx; - - trace(4,"decode_stqraw: len=%d\n",raw->len); - - if (raw->outtype) { - sprintf(raw->msgtype,"SKYTRAQ RAWX (%4d): nsat=%2d",raw->len,U1(p+13)); - } - ver=U1(p+1); - raw->iod=U1(p+2); - week=U2(p+3); - week=adjgpsweek(week); - tow =U4(p+5)*0.001; - raw->time=gpst2time(week,tow); - peri=U2(p+9)*0.001; - nsat=U1(p+13); - if (raw->len<19+31*nsat) { - trace(2,"stq raw length error: len=%d nsat=%d\n",raw->len,nsat); - return -1; - } - for (i=0,p+=14;i>4)&0xF); - idx=code2idx(sys,sig); - prn=U1(p+1); - if (!(sat=satno(sys,prn))) { - trace(2,"stq raw satellite number error: sys=%d prn=%d\n",sys,prn); - continue; - } - /* set glonass freq channel number */ - if (sys==SYS_GLO) { - raw->nav.geph[prn-1].frq=(int)(U1(p+2)&0xF)-7; - } - ind=U2(p+27); - pr1=!(ind&1)?0.0:R8(p+ 4); - cp1=!(ind&4)?0.0:R8(p+12); - cp1-=floor((cp1+1E9)/2E9)*2E9; /* -10^9 < cp1 < 10^9 */ - - for (j=0;jobs.data[j].sat==sat) break; - } - if (j>=n) { - raw->obs.data[n].time=raw->time; - raw->obs.data[n].sat=sat; - raw->obs.data[n].rcv=0; - for (k=0;kobs.data[n].L[k]=raw->obs.data[n].P[k]=0.0; - raw->obs.data[n].D[k]=raw->obs.data[n].SNR[k]=0.0; - raw->obs.data[n].LLI[k]=0; - raw->obs.data[n].code[k]=CODE_NONE; - } - n++; - } - raw->obs.data[j].P[idx]=pr1; - raw->obs.data[j].L[idx]=cp1; - raw->obs.data[j].D[idx]=!(ind&2)?0.0:R4(p+20); - raw->obs.data[j].SNR[idx]=U1(p+3); - raw->obs.data[j].LLI[idx]=0; - raw->obs.data[j].code[idx]=sig; - - raw->lockt[sat-1][idx]=ind&8?1:0; /* cycle slip */ - - if (raw->obs.data[j].L[idx]!=0.0) { - raw->obs.data[j].LLI[idx]=(uint8_t)raw->lockt[sat-1][idx]; - raw->lockt[sat-1][idx]=0; - } - /* receiver dependent options */ - if (strstr(raw->opt,"-INVCP")) { - raw->obs.data[n].L[idx]*=-1.0; - } - raw->obs.data[n].time=raw->time; - raw->obs.data[n].sat =sat; - } - raw->obs.n=n; - return n>0?1:0; +static int decode_stqrawx(raw_t *raw) { + uint8_t *p = raw->buff + 4, ind; + double tow, peri, pr1, cp1; + int i, j, k, ver, week, nsat, sys, sig, prn, sat, n = 0, idx; + + trace(4, "decode_stqraw: len=%d\n", raw->len); + + if (raw->outtype) { + sprintf(raw->msgtype, "SKYTRAQ RAWX (%4d): nsat=%2d", raw->len, U1(p + 13)); + } + ver = U1(p + 1); + raw->iod = U1(p + 2); + week = U2(p + 3); + week = adjgpsweek(week); + tow = U4(p + 5) * 0.001; + raw->time = gpst2time(week, tow); + peri = U2(p + 9) * 0.001; + nsat = U1(p + 13); + if (raw->len < 19 + 31 * nsat) { + trace(2, "stq raw length error: len=%d nsat=%d\n", raw->len, nsat); + return -1; + } + for (i = 0, p += 14; i < nsat && i < MAXOBS; i++, p += 31) { + sys = sky_sys(U1(p) & 0xF); + sig = sky_sig(sys, (U1(p) >> 4) & 0xF); + idx = code2idx(sys, sig); + prn = U1(p + 1); + if (!(sat = satno(sys, prn))) { + trace(2, "stq raw satellite number error: sys=%d prn=%d\n", sys, prn); + continue; + } + /* set glonass freq channel number */ + if (sys == SYS_GLO) { + raw->nav.geph[prn - 1].frq = (int)(U1(p + 2) & 0xF) - 7; + } + ind = U2(p + 27); + pr1 = !(ind & 1) ? 0.0 : R8(p + 4); + cp1 = !(ind & 4) ? 0.0 : R8(p + 12); + cp1 -= floor((cp1 + 1E9) / 2E9) * 2E9; /* -10^9 < cp1 < 10^9 */ + + for (j = 0; j < n; j++) { + if (raw->obs.data[j].sat == sat) break; + } + if (j >= n) { + raw->obs.data[n].time = raw->time; + raw->obs.data[n].sat = sat; + raw->obs.data[n].rcv = 0; + for (k = 0; k < NFREQ + NEXOBS; k++) { + raw->obs.data[n].L[k] = raw->obs.data[n].P[k] = 0.0; + raw->obs.data[n].D[k] = raw->obs.data[n].SNR[k] = 0.0; + raw->obs.data[n].LLI[k] = 0; + raw->obs.data[n].code[k] = CODE_NONE; + } + n++; + } + raw->obs.data[j].P[idx] = pr1; + raw->obs.data[j].L[idx] = cp1; + raw->obs.data[j].D[idx] = !(ind & 2) ? 0.0 : R4(p + 20); + raw->obs.data[j].SNR[idx] = U1(p + 3); + raw->obs.data[j].LLI[idx] = 0; + raw->obs.data[j].code[idx] = sig; + + raw->lockt[sat - 1][idx] = ind & 8 ? 1 : 0; /* cycle slip */ + + if (raw->obs.data[j].L[idx] != 0.0) { + raw->obs.data[j].LLI[idx] = (uint8_t)raw->lockt[sat - 1][idx]; + raw->lockt[sat - 1][idx] = 0; + } + /* receiver dependent options */ + if (strstr(raw->opt, "-INVCP")) { + raw->obs.data[n].L[idx] *= -1.0; + } + raw->obs.data[n].time = raw->time; + raw->obs.data[n].sat = sat; + } + raw->obs.n = n; + return n > 0 ? 1 : 0; } /* decode galileo ephemeris (0xE6) ----------------------------------------------*/ -static int decode_stqgene(raw_t *raw) -{ - eph_t eph={0}; - int i,j,prn,sat,sys; - int part1,page1,part2,page2,type; - double ion[4]={0},utc[8]={0}; - uint8_t *p=raw->buff+4,buff[32],crc_buff[26]={0}; - - trace(4,"decode_stqgene: len=%d\n",raw->len); - - if (raw->len<44) { - trace(2,"stq gene string length error: len=%d\n",raw->len); - return -1; - } - prn=U1(p+3); - sys=sky_sys(U1(p+2)&0xF); - if (!(sat=satno(sys,prn))) { - trace(2,"stq raw satellite number error: sys=%d prn=%d\n",sys,prn); - return 0; - } - if (sys!=SYS_GAL) { - trace(2,"stq sys not supported: sys=%d\n",sys); - return 0; - } - if (raw->outtype) { - sprintf(raw->msgtype,"SKYTRAQ GENE (%4d): prn=%2d",raw->len,prn); - } - for (i=0;i<8;i++,p+=4) { - setbitu(buff,32*i,32,U4(p+5)); - } - part1=getbitu(buff ,0,1); - page1=getbitu(buff ,1,1); - part2=getbitu(buff,128,1); - page2=getbitu(buff,129,1); - - if (part1!=0||part2!=1) { - trace(3,"ubx rxmsfrbx enav page even/odd error: sat=%d\n",sat); - return -1; - } - if (page1==1||page2==1) return 0; /* alert page */ - - /* test crc (4(pad) + 114 + 82 bits) */ - for (i=0,j= 4;i<15;i++,j+=8) setbitu(crc_buff,j,8,getbitu(buff ,i*8,8)); - for (i=0,j=118;i<11;i++,j+=8) setbitu(crc_buff,j,8,getbitu(buff,i*8+128,8)); - if (rtk_crc24q(crc_buff,25)!=getbitu(buff,128+82,24)) { - trace(2,"ubx rxmsfrbx enav crc error: sat=%d\n",sat); - return -1; - } - type=getbitu(buff,2,6); /* word type */ +static int decode_stqgene(raw_t *raw) { + eph_t eph = {0}; + int i, j, prn, sat, sys; + int part1, page1, part2, page2, type; + double ion[4] = {0}, utc[8] = {0}; + uint8_t *p = raw->buff + 4, buff[32], crc_buff[26] = {0}; - if (type>6) return 0; + trace(4, "decode_stqgene: len=%d\n", raw->len); - /* save 128 (112:even+16:odd) bits word */ - for (i=0,j=2;i<14;i++,j+=8) { - raw->subfrm[sat-1][type*16+i]=getbitu(buff,j,8); - } - for (i=14,j=130;i<16;i++,j+=8) { - raw->subfrm[sat-1][type*16+i]=getbitu(buff,j,8); - } - if (type!=5) return 0; - if (!decode_gal_inav(raw->subfrm[sat-1],&eph,ion,utc)) return 0; + if (raw->len < 44) { + trace(2, "stq gene string length error: len=%d\n", raw->len); + return -1; + } + prn = U1(p + 3); + sys = sky_sys(U1(p + 2) & 0xF); + if (!(sat = satno(sys, prn))) { + trace(2, "stq raw satellite number error: sys=%d prn=%d\n", sys, prn); + return 0; + } + if (sys != SYS_GAL) { + trace(2, "stq sys not supported: sys=%d\n", sys); + return 0; + } + if (raw->outtype) { + sprintf(raw->msgtype, "SKYTRAQ GENE (%4d): prn=%2d", raw->len, prn); + } + for (i = 0; i < 8; i++, p += 4) { + setbitu(buff, 32 * i, 32, U4(p + 5)); + } + part1 = getbitu(buff, 0, 1); + page1 = getbitu(buff, 1, 1); + part2 = getbitu(buff, 128, 1); + page2 = getbitu(buff, 129, 1); - if (eph.sat!=sat) { - trace(2,"skytraq enav satellite error: sat=%d %d\n",sat,eph.sat); - return -1; - } - eph.code|=(1<<0); /* data source: E1 */ + if (part1 != 0 || part2 != 1) { + trace(3, "ubx rxmsfrbx enav page even/odd error: sat=%d\n", sat); + return -1; + } + if (page1 == 1 || page2 == 1) return 0; /* alert page */ - adj_utcweek(raw->time,utc); - matcpy(raw->nav.ion_gal,ion,4,1); - matcpy(raw->nav.utc_gal,utc,8,1); + /* test crc (4(pad) + 114 + 82 bits) */ + for (i = 0, j = 4; i < 15; i++, j += 8) setbitu(crc_buff, j, 8, getbitu(buff, i * 8, 8)); + for (i = 0, j = 118; i < 11; i++, j += 8) setbitu(crc_buff, j, 8, getbitu(buff, i * 8 + 128, 8)); + if (rtk_crc24q(crc_buff, 25) != getbitu(buff, 128 + 82, 24)) { + trace(2, "ubx rxmsfrbx enav crc error: sat=%d\n", sat); + return -1; + } + type = getbitu(buff, 2, 6); /* word type */ - if (!strstr(raw->opt,"-EPHALL")) { - if (eph.iode==raw->nav.eph[sat-1].iode&& - timediff(eph.toe,raw->nav.eph[sat-1].toe)==0.0&& - timediff(eph.toc,raw->nav.eph[sat-1].toc)==0.0) return 0; - } - raw->nav.eph[sat-1]=eph; - raw->ephsat=sat; - raw->ephset=0; /* 0:I/NAV */ - return 2; + if (type > 6) return 0; + + /* save 128 (112:even+16:odd) bits word */ + for (i = 0, j = 2; i < 14; i++, j += 8) { + raw->subfrm[sat - 1][type * 16 + i] = getbitu(buff, j, 8); + } + for (i = 14, j = 130; i < 16; i++, j += 8) { + raw->subfrm[sat - 1][type * 16 + i] = getbitu(buff, j, 8); + } + if (type != 5) return 0; + if (!decode_gal_inav(raw->subfrm[sat - 1], &eph, ion, utc)) return 0; + + if (eph.sat != sat) { + trace(2, "skytraq enav satellite error: sat=%d %d\n", sat, eph.sat); + return -1; + } + eph.code |= (1 << 0); /* data source: E1 */ + + adj_utcweek(raw->time, utc); + matcpy(raw->nav.ion_gal, ion, 4, 1); + matcpy(raw->nav.utc_gal, utc, 8, 1); + + if (!strstr(raw->opt, "-EPHALL")) { + if (eph.iode == raw->nav.eph[sat - 1].iode && + timediff(eph.toe, raw->nav.eph[sat - 1].toe) == 0.0 && + timediff(eph.toc, raw->nav.eph[sat - 1].toc) == 0.0) + return 0; + } + raw->nav.eph[sat - 1] = eph; + raw->ephsat = sat; + raw->ephset = 0; /* 0:I/NAV */ + return 2; } /* save gps/qzss subframe -------------------------------------------------------------*/ -static int save_subfrm_gps(int sat, raw_t *raw) -{ - uint8_t *p=raw->buff+7,*q; - int i,id; +static int save_subfrm_gps(int sat, raw_t *raw) { + uint8_t *p = raw->buff + 7, *q; + int i, id; - trace(4,"save_subfrm_gps: sat=%2d\n",sat); + trace(4, "save_subfrm_gps: sat=%2d\n", sat); - /* check navigation subframe preamble */ - if (p[0]!=0x8B) { - trace(2,"stq subframe preamble error: 0x%02X\n",p[0]); - return 0; - } - id=(p[5]>>2)&0x7; + /* check navigation subframe preamble */ + if (p[0] != 0x8B) { + trace(2, "stq subframe preamble error: 0x%02X\n", p[0]); + return 0; + } + id = (p[5] >> 2) & 0x7; - /* check subframe id */ - if (id<1||5subfrm[sat-1]+(id-1)*30; + /* check subframe id */ + if (id < 1 || 5 < id) { + trace(2, "stq subframe id error: id=%d\n", id); + return 0; + } + q = raw->subfrm[sat - 1] + (id - 1) * 30; - for (i=0;i<30;i++) q[i]=p[i]; + for (i = 0; i < 30; i++) q[i] = p[i]; - return id; + return id; } /* decode ephemeris ----------------------------------------------------------*/ -static int decode_ephem(int sat, raw_t *raw) -{ - eph_t eph={0}; - - trace(4,"decode_ephem: sat=%2d\n",sat); - - int sys = satsys(sat, NULL); - if (!decode_frame(raw->subfrm[sat-1],sys,&eph,NULL,NULL,NULL)) return 0; - - if (!strstr(raw->opt,"-EPHALL")) { - if (eph.iode==raw->nav.eph[sat-1].iode&& - eph.iodc==raw->nav.eph[sat-1].iodc) return 0; /* unchanged */ - } - eph.sat=sat; - raw->nav.eph[sat-1]=eph; - raw->ephsat=sat; - raw->ephset=0; - return 2; +static int decode_ephem(int sat, raw_t *raw) { + eph_t eph = {0}; + + trace(4, "decode_ephem: sat=%2d\n", sat); + + int sys = satsys(sat, NULL); + if (!decode_frame(raw->subfrm[sat - 1], sys, &eph, NULL, NULL, NULL)) return 0; + + if (!strstr(raw->opt, "-EPHALL")) { + if (eph.iode == raw->nav.eph[sat - 1].iode && eph.iodc == raw->nav.eph[sat - 1].iodc) + return 0; /* unchanged */ + } + eph.sat = sat; + raw->nav.eph[sat - 1] = eph; + raw->ephsat = sat; + raw->ephset = 0; + return 2; } /* decode almanac and ion/utc ------------------------------------------------*/ -static int decode_alm1(int sat, raw_t *raw) -{ - int sys=satsys(sat,NULL); - - trace(4,"decode_alm1 : sat=%2d\n",sat); - - if (sys==SYS_GPS) { - decode_frame(raw->subfrm[sat-1],sys,NULL,raw->nav.alm,raw->nav.ion_gps, - raw->nav.utc_gps); - adj_utcweek(raw->time,raw->nav.utc_gps); - } - else if (sys==SYS_QZS) { - decode_frame(raw->subfrm[sat-1],sys,NULL,raw->nav.alm,raw->nav.ion_qzs, - raw->nav.utc_qzs); - adj_utcweek(raw->time,raw->nav.utc_qzs); - } - return 9; +static int decode_alm1(int sat, raw_t *raw) { + int sys = satsys(sat, NULL); + + trace(4, "decode_alm1 : sat=%2d\n", sat); + + if (sys == SYS_GPS) { + decode_frame(raw->subfrm[sat - 1], sys, NULL, raw->nav.alm, raw->nav.ion_gps, raw->nav.utc_gps); + adj_utcweek(raw->time, raw->nav.utc_gps); + } else if (sys == SYS_QZS) { + decode_frame(raw->subfrm[sat - 1], sys, NULL, raw->nav.alm, raw->nav.ion_qzs, raw->nav.utc_qzs); + adj_utcweek(raw->time, raw->nav.utc_qzs); + } + return 9; } /* decode almanac ------------------------------------------------------------*/ -static int decode_alm2(int sat, raw_t *raw) -{ - int sys=satsys(sat,NULL); - - trace(4,"decode_alm2 : sat=%2d\n",sat); - - if (sys==SYS_GPS) { - decode_frame(raw->subfrm[sat-1],sys,NULL,raw->nav.alm,NULL,NULL); - } - else if (sys==SYS_QZS) { - decode_frame(raw->subfrm[sat-1],sys,NULL,raw->nav.alm,raw->nav.ion_qzs, - raw->nav.utc_qzs); - adj_utcweek(raw->time,raw->nav.utc_qzs); - } - return 0; +static int decode_alm2(int sat, raw_t *raw) { + int sys = satsys(sat, NULL); + + trace(4, "decode_alm2 : sat=%2d\n", sat); + + if (sys == SYS_GPS) { + decode_frame(raw->subfrm[sat - 1], sys, NULL, raw->nav.alm, NULL, NULL); + } else if (sys == SYS_QZS) { + decode_frame(raw->subfrm[sat - 1], sys, NULL, raw->nav.alm, raw->nav.ion_qzs, raw->nav.utc_qzs); + adj_utcweek(raw->time, raw->nav.utc_qzs); + } + return 0; } /* decode gps/qzss subframe (0xE0) -------------------------------------------*/ -static int decode_stqgps(raw_t *raw) -{ - int prn,sat,id; - uint8_t *p=raw->buff+4; +static int decode_stqgps(raw_t *raw) { + int prn, sat, id; + uint8_t *p = raw->buff + 4; - trace(4,"decode_stqgps: len=%d\n",raw->len); + trace(4, "decode_stqgps: len=%d\n", raw->len); - if (raw->len<40) { - trace(2,"stq gps/qzss subframe length error: len=%d\n",raw->len); - return -1; - } - if (raw->outtype) { - sprintf(raw->msgtype,"SKYTRAQ GPSSF (%4d): prn=%2d id=%d",raw->len, - U1(p+1),(p[8]>>2)&0x7); - } - prn=U1(p+1); - if (!(sat=satno(MINPRNQZS<=prn&&prn<=MAXPRNQZS?SYS_QZS:SYS_GPS,prn))) { - trace(2,"stq gps/qzss subframe satellite number error: prn=%d\n",prn); - return -1; - } - id=save_subfrm_gps(sat,raw); - if (id==3) return decode_ephem(sat,raw); - if (id==4) return decode_alm1 (sat,raw); - if (id==5) return decode_alm2 (sat,raw); - return 0; + if (raw->len < 40) { + trace(2, "stq gps/qzss subframe length error: len=%d\n", raw->len); + return -1; + } + if (raw->outtype) { + sprintf(raw->msgtype, "SKYTRAQ GPSSF (%4d): prn=%2d id=%d", raw->len, U1(p + 1), + (p[8] >> 2) & 0x7); + } + prn = U1(p + 1); + if (!(sat = satno(MINPRNQZS <= prn && prn <= MAXPRNQZS ? SYS_QZS : SYS_GPS, prn))) { + trace(2, "stq gps/qzss subframe satellite number error: prn=%d\n", prn); + return -1; + } + id = save_subfrm_gps(sat, raw); + if (id == 3) return decode_ephem(sat, raw); + if (id == 4) return decode_alm1(sat, raw); + if (id == 5) return decode_alm2(sat, raw); + return 0; } /* decode glonass string (0xE1) ----------------------------------------------*/ -static int decode_stqglo(raw_t *raw) -{ - geph_t geph={0}; - int i,prn,sat,m; - uint8_t *p=raw->buff+4; +static int decode_stqglo(raw_t *raw) { + geph_t geph = {0}; + int i, prn, sat, m; + uint8_t *p = raw->buff + 4; - trace(4,"decode_stqglo: len=%d\n",raw->len); + trace(4, "decode_stqglo: len=%d\n", raw->len); - if (raw->len<19) { - trace(2,"stq glo string length error: len=%d\n",raw->len); - return -1; - } - if (raw->outtype) { - sprintf(raw->msgtype,"SKYTRAQ GLSTR (%4d): prn=%2d no=%d",raw->len, - U1(p+1)-64,U1(p+2)); - } - prn=U1(p+1)-64; - if (!(sat=satno(SYS_GLO,prn))) { - trace(2,"stq glo string satellite number error: prn=%d\n",prn); - return -1; - } - m=U1(p+2); /* string number */ - if (m<1||4subfrm[sat-1]+(m-1)*10,1,4,m); - for (i=0;i<9;i++) { - setbitu(raw->subfrm[sat-1]+(m-1)*10,5+i*8,8,p[3+i]); - } - if (m!=4) return 0; + if (raw->len < 19) { + trace(2, "stq glo string length error: len=%d\n", raw->len); + return -1; + } + if (raw->outtype) { + sprintf(raw->msgtype, "SKYTRAQ GLSTR (%4d): prn=%2d no=%d", raw->len, U1(p + 1) - 64, + U1(p + 2)); + } + prn = U1(p + 1) - 64; + if (!(sat = satno(SYS_GLO, prn))) { + trace(2, "stq glo string satellite number error: prn=%d\n", prn); + return -1; + } + m = U1(p + 2); /* string number */ + if (m < 1 || 4 < m) { + return 0; /* non-immediate info and almanac */ + } + setbitu(raw->subfrm[sat - 1] + (m - 1) * 10, 1, 4, m); + for (i = 0; i < 9; i++) { + setbitu(raw->subfrm[sat - 1] + (m - 1) * 10, 5 + i * 8, 8, p[3 + i]); + } + if (m != 4) return 0; - /* decode glonass ephemeris strings */ - geph.tof=raw->time; - if (!decode_glostr(raw->subfrm[sat-1],&geph,NULL)||geph.sat!=sat) return 0; + /* decode glonass ephemeris strings */ + geph.tof = raw->time; + if (!decode_glostr(raw->subfrm[sat - 1], &geph, NULL) || geph.sat != sat) return 0; - if (!strstr(raw->opt,"-EPHALL")) { - if (geph.iode==raw->nav.geph[prn-1].iode) return 0; /* unchanged */ - } - /* keep freq channel number */ - geph.frq=raw->nav.geph[prn-1].frq; - raw->nav.geph[prn-1]=geph; - raw->ephsat=sat; - raw->ephset=0; - return 2; + if (!strstr(raw->opt, "-EPHALL")) { + if (geph.iode == raw->nav.geph[prn - 1].iode) return 0; /* unchanged */ + } + /* keep freq channel number */ + geph.frq = raw->nav.geph[prn - 1].frq; + raw->nav.geph[prn - 1] = geph; + raw->ephsat = sat; + raw->ephset = 0; + return 2; } /* decode glonass string (requested) (0x5C) ----------------------------------*/ -static int decode_stqgloe(raw_t *raw) -{ - int prn,sat; - uint8_t *p=raw->buff+4; - - trace(4,"decode_stqgloe: len=%d\n",raw->len); - - if (raw->len<50) { - trace(2,"stq glo string length error: len=%d\n",raw->len); - return -1; - } - prn=U1(p+1); - if (!(sat=satno(SYS_GLO,prn))) { - trace(2,"stq gloe string satellite number error: prn=%d\n",prn); - return -1; - } - /* set frequency channel number */ - raw->nav.geph[prn-1].frq=I1(p+2); - - return 0; +static int decode_stqgloe(raw_t *raw) { + int prn, sat; + uint8_t *p = raw->buff + 4; + + trace(4, "decode_stqgloe: len=%d\n", raw->len); + + if (raw->len < 50) { + trace(2, "stq glo string length error: len=%d\n", raw->len); + return -1; + } + prn = U1(p + 1); + if (!(sat = satno(SYS_GLO, prn))) { + trace(2, "stq gloe string satellite number error: prn=%d\n", prn); + return -1; + } + /* set frequency channel number */ + raw->nav.geph[prn - 1].frq = I1(p + 2); + + return 0; } /* decode beidou subframe (0xE2,0xE3) ----------------------------------------*/ -static int decode_stqbds(raw_t *raw) -{ - eph_t eph={0}; - uint32_t word; - int i,j=0,id,pgn,prn,sat; - uint8_t *p=raw->buff+4; - - trace(4,"decode_stqbds: len=%d\n",raw->len); - - if (raw->len<38) { - trace(2,"stq bds subframe length error: len=%d\n",raw->len); - return -1; - } - if (raw->outtype) { - sprintf(raw->msgtype,"SKYTRAQ BDSSF (%4d): prn=%2d id=%d",raw->len, - U1(p+1)-200,U1(p+2)); - } - prn=U1(p+1)-200; - if (!(sat=satno(SYS_CMP,prn))) { - trace(2,"stq bds subframe satellite number error: prn=%d\n",prn); - return -1; - } - id=U1(p+2); /* subframe id */ - if (id<1||55) { /* IGSO/MEO */ - word=getbitu(p+3,j,26)<<4; j+=26; - setbitu(raw->subfrm[sat-1]+(id-1)*38,0,30,word); - - for (i=1;i<10;i++) { - word=getbitu(p+3,j,22)<<8; j+=22; - setbitu(raw->subfrm[sat-1]+(id-1)*38,i*30,30,word); - } - if (id!=3) return 0; - if (!decode_bds_d1(raw->subfrm[sat-1],&eph,NULL,NULL)) return 0; - } - else { /* GEO */ - if (id!=1) return 0; - - pgn=getbitu(p+3,26+12,4); /* page number */ - if (pgn<1||10subfrm[sat-1]+(pgn-1)*38,0,30,word); - - for (i=1;i<10;i++) { - word=getbitu(p+3,j,22)<<8; j+=22; - setbitu(raw->subfrm[sat-1]+(pgn-1)*38,i*30,30,word); - } - if (pgn!=10) return 0; - if (!decode_bds_d2(raw->subfrm[sat-1],&eph,NULL)) return 0; - } - if (!strstr(raw->opt,"-EPHALL")) { - if (timediff(eph.toe,raw->nav.eph[sat-1].toe)==0.0) return 0; /* unchanged */ - } - eph.sat=sat; - raw->nav.eph[sat-1]=eph; - raw->ephsat=sat; - raw->ephset=0; - return 2; +static int decode_stqbds(raw_t *raw) { + eph_t eph = {0}; + uint32_t word; + int i, j = 0, id, pgn, prn, sat; + uint8_t *p = raw->buff + 4; + + trace(4, "decode_stqbds: len=%d\n", raw->len); + + if (raw->len < 38) { + trace(2, "stq bds subframe length error: len=%d\n", raw->len); + return -1; + } + if (raw->outtype) { + sprintf(raw->msgtype, "SKYTRAQ BDSSF (%4d): prn=%2d id=%d", raw->len, U1(p + 1) - 200, + U1(p + 2)); + } + prn = U1(p + 1) - 200; + if (!(sat = satno(SYS_CMP, prn))) { + trace(2, "stq bds subframe satellite number error: prn=%d\n", prn); + return -1; + } + id = U1(p + 2); /* subframe id */ + if (id < 1 || 5 < id) { + trace(2, "stq bds subframe id error: prn=%2d\n", prn); + return -1; + } + if (prn > 5) { /* IGSO/MEO */ + word = getbitu(p + 3, j, 26) << 4; + j += 26; + setbitu(raw->subfrm[sat - 1] + (id - 1) * 38, 0, 30, word); + + for (i = 1; i < 10; i++) { + word = getbitu(p + 3, j, 22) << 8; + j += 22; + setbitu(raw->subfrm[sat - 1] + (id - 1) * 38, i * 30, 30, word); + } + if (id != 3) return 0; + if (!decode_bds_d1(raw->subfrm[sat - 1], &eph, NULL, NULL)) return 0; + } else { /* GEO */ + if (id != 1) return 0; + + pgn = getbitu(p + 3, 26 + 12, 4); /* page number */ + if (pgn < 1 || 10 < pgn) { + trace(2, "stq bds subframe page number error: prn=%2d pgn=%d\n", prn, pgn); + return -1; + } + word = getbitu(p + 3, j, 26) << 4; + j += 26; + setbitu(raw->subfrm[sat - 1] + (pgn - 1) * 38, 0, 30, word); + + for (i = 1; i < 10; i++) { + word = getbitu(p + 3, j, 22) << 8; + j += 22; + setbitu(raw->subfrm[sat - 1] + (pgn - 1) * 38, i * 30, 30, word); + } + if (pgn != 10) return 0; + if (!decode_bds_d2(raw->subfrm[sat - 1], &eph, NULL)) return 0; + } + if (!strstr(raw->opt, "-EPHALL")) { + if (timediff(eph.toe, raw->nav.eph[sat - 1].toe) == 0.0) return 0; /* unchanged */ + } + eph.sat = sat; + raw->nav.eph[sat - 1] = eph; + raw->ephsat = sat; + raw->ephset = 0; + return 2; } /* decode ack to request msg (0x83) ------------------------------------------*/ -static int decode_stqack(raw_t *raw) -{ - uint8_t *p=raw->buff+4; - - trace(4,"decode_stqack: len=%d\n",raw->len); - - if (raw->len<9) { - trace(2,"stq ack length error: len=%d\n",raw->len); - return -1; - } - if (raw->outtype) { - sprintf(raw->msgtype,"SKYTRAQ ACK (%4d): msg=0x%02X",raw->len, - U1(p+1)); - } - return 0; +static int decode_stqack(raw_t *raw) { + uint8_t *p = raw->buff + 4; + + trace(4, "decode_stqack: len=%d\n", raw->len); + + if (raw->len < 9) { + trace(2, "stq ack length error: len=%d\n", raw->len); + return -1; + } + if (raw->outtype) { + sprintf(raw->msgtype, "SKYTRAQ ACK (%4d): msg=0x%02X", raw->len, U1(p + 1)); + } + return 0; } /* decode nack to request msg (0x84) -----------------------------------------*/ -static int decode_stqnack(raw_t *raw) -{ - uint8_t *p=raw->buff+4; - - trace(4,"decode_stqnack: len=%d\n",raw->len); - - if (raw->len<9) { - trace(2,"stq nack length error: len=%d\n",raw->len); - return -1; - } - if (raw->outtype) { - sprintf(raw->msgtype,"SKYTRAQ NACK (%4d): msg=0x%02X",raw->len, - U1(p+1)); - } - return 0; +static int decode_stqnack(raw_t *raw) { + uint8_t *p = raw->buff + 4; + + trace(4, "decode_stqnack: len=%d\n", raw->len); + + if (raw->len < 9) { + trace(2, "stq nack length error: len=%d\n", raw->len); + return -1; + } + if (raw->outtype) { + sprintf(raw->msgtype, "SKYTRAQ NACK (%4d): msg=0x%02X", raw->len, U1(p + 1)); + } + return 0; } /* decode skytraq message ----------------------------------------------------*/ -static int decode_stq(raw_t *raw) -{ - int type=U1(raw->buff+4); - uint8_t cs,*p=raw->buff+raw->len-3; - - trace(3,"decode_stq: type=%02x len=%d\n",type,raw->len); - - /* checksum */ - cs=checksum(raw->buff,raw->len); - - if (cs!=*p||*(p+1)!=0x0D||*(p+2)!=0x0A) { - trace(2,"stq checksum error: type=%02X cs=%02X tail=%02X%02X%02X\n", - type,cs,*p,*(p+1),*(p+2)); - return -1; - } - if (raw->outtype) { - sprintf(raw->msgtype,"SKYTRAQ 0x%02X (%4d):",type,raw->len); - } - switch (type) { - case ID_STQTIME : return decode_stqtime(raw); - case ID_STQRAW : return decode_stqraw (raw); - case ID_STQRAWX : return decode_stqrawx(raw); - case ID_STQGPS : return decode_stqgps (raw); - case ID_STQGLO : return decode_stqglo (raw); - case ID_STQGLOE : return decode_stqgloe(raw); - case ID_STQGENE : return decode_stqgene(raw); - case ID_STQBDSD1: return decode_stqbds (raw); - case ID_STQBDSD2: return decode_stqbds (raw); - /* case ID_STQGENE : return decode_stqgene(raw); */ - case ID_STQACK : return decode_stqack (raw); - case ID_STQNACK : return decode_stqnack(raw); - } - return 0; +static int decode_stq(raw_t *raw) { + int type = U1(raw->buff + 4); + uint8_t cs, *p = raw->buff + raw->len - 3; + + trace(3, "decode_stq: type=%02x len=%d\n", type, raw->len); + + /* checksum */ + cs = checksum(raw->buff, raw->len); + + if (cs != *p || *(p + 1) != 0x0D || *(p + 2) != 0x0A) { + trace(2, "stq checksum error: type=%02X cs=%02X tail=%02X%02X%02X\n", type, cs, *p, *(p + 1), + *(p + 2)); + return -1; + } + if (raw->outtype) { + sprintf(raw->msgtype, "SKYTRAQ 0x%02X (%4d):", type, raw->len); + } + switch (type) { + case ID_STQTIME: + return decode_stqtime(raw); + case ID_STQRAW: + return decode_stqraw(raw); + case ID_STQRAWX: + return decode_stqrawx(raw); + case ID_STQGPS: + return decode_stqgps(raw); + case ID_STQGLO: + return decode_stqglo(raw); + case ID_STQGLOE: + return decode_stqgloe(raw); + case ID_STQGENE: + return decode_stqgene(raw); + case ID_STQBDSD1: + return decode_stqbds(raw); + case ID_STQBDSD2: + return decode_stqbds(raw); + /* case ID_STQGENE : return decode_stqgene(raw); */ + case ID_STQACK: + return decode_stqack(raw); + case ID_STQNACK: + return decode_stqnack(raw); + } + return 0; } /* sync code -----------------------------------------------------------------*/ -static int sync_stq(uint8_t *buff, uint8_t data) -{ - buff[0]=buff[1]; buff[1]=data; - return buff[0]==STQSYNC1&&buff[1]==STQSYNC2; +static int sync_stq(uint8_t *buff, uint8_t data) { + buff[0] = buff[1]; + buff[1] = data; + return buff[0] == STQSYNC1 && buff[1] == STQSYNC2; } /* input skytraq raw message from stream --------------------------------------- -* fetch next skytraq raw data and input a mesasge from stream -* args : raw_t *raw IO receiver raw data control struct -* uint8_t data I stream data (1 byte) -* return : status (-1: error message, 0: no message, 1: input observation data, -* 2: input ephemeris, 3: input sbas message, -* 9: input ion/utc parameter) -* -* notes : to specify input options, set raw->opt to the following option -* strings separated by spaces. -* -* -INVCP : inverse polarity of carrier-phase -* -*-----------------------------------------------------------------------------*/ -extern int input_stq(raw_t *raw, uint8_t data) -{ - trace(5,"input_stq: data=%02x\n",data); - - /* synchronize frame */ - if (raw->nbyte==0) { - if (!sync_stq(raw->buff,data)) return 0; - raw->nbyte=2; - return 0; - } - raw->buff[raw->nbyte++]=data; - - if (raw->nbyte==4) { - if ((raw->len=U2(raw->buff+2)+7)>MAXRAWLEN) { - trace(2,"stq message length error: len=%d\n",raw->len); - raw->nbyte=0; - return -1; - } - } - if (raw->nbyte<4||raw->nbytelen) return 0; - raw->nbyte=0; - - /* decode skytraq raw message */ - return decode_stq(raw); + * fetch next skytraq raw data and input a mesasge from stream + * args : raw_t *raw IO receiver raw data control struct + * uint8_t data I stream data (1 byte) + * return : status (-1: error message, 0: no message, 1: input observation data, + * 2: input ephemeris, 3: input sbas message, + * 9: input ion/utc parameter) + * + * notes : to specify input options, set raw->opt to the following option + * strings separated by spaces. + * + * -INVCP : inverse polarity of carrier-phase + * + *-----------------------------------------------------------------------------*/ +extern int input_stq(raw_t *raw, uint8_t data) { + trace(5, "input_stq: data=%02x\n", data); + + /* synchronize frame */ + if (raw->nbyte == 0) { + if (!sync_stq(raw->buff, data)) return 0; + raw->nbyte = 2; + return 0; + } + raw->buff[raw->nbyte++] = data; + + if (raw->nbyte == 4) { + if ((raw->len = U2(raw->buff + 2) + 7) > MAXRAWLEN) { + trace(2, "stq message length error: len=%d\n", raw->len); + raw->nbyte = 0; + return -1; + } + } + if (raw->nbyte < 4 || raw->nbyte < raw->len) return 0; + raw->nbyte = 0; + + /* decode skytraq raw message */ + return decode_stq(raw); } /* input skytraq raw message from file ----------------------------------------- -* fetch next skytraq raw data and input a message from file -* args : raw_t *raw IO receiver raw data control struct -* FILE *fp I file pointer -* return : status(-2: end of file, -1...9: same as above) -*-----------------------------------------------------------------------------*/ -extern int input_stqf(raw_t *raw, FILE *fp) -{ - int i,data; - - trace(4,"input_stqf:\n"); - - /* synchronize frame */ - if (raw->nbyte==0) { - for (i=0;;i++) { - if ((data=fgetc(fp))==EOF) return -2; - if (sync_stq(raw->buff,(uint8_t)data)) break; - if (i>=4096) return 0; - } - } - if (fread(raw->buff+2,1,2,fp)<2) return -2; - raw->nbyte=4; - - if ((raw->len=U2(raw->buff+2)+7)>MAXRAWLEN) { - trace(2,"stq message length error: len=%d\n",raw->len); - raw->nbyte=0; - return -1; - } - if (fread(raw->buff+4,1,raw->len-4,fp)<(size_t)(raw->len-4)) return -2; - raw->nbyte=0; - - /* decode skytraq raw message */ - return decode_stq(raw); + * fetch next skytraq raw data and input a message from file + * args : raw_t *raw IO receiver raw data control struct + * FILE *fp I file pointer + * return : status(-2: end of file, -1...9: same as above) + *-----------------------------------------------------------------------------*/ +extern int input_stqf(raw_t *raw, FILE *fp) { + int i, data; + + trace(4, "input_stqf:\n"); + + /* synchronize frame */ + if (raw->nbyte == 0) { + for (i = 0;; i++) { + if ((data = fgetc(fp)) == EOF) return -2; + if (sync_stq(raw->buff, (uint8_t)data)) break; + if (i >= 4096) return 0; + } + } + if (fread(raw->buff + 2, 1, 2, fp) < 2) return -2; + raw->nbyte = 4; + + if ((raw->len = U2(raw->buff + 2) + 7) > MAXRAWLEN) { + trace(2, "stq message length error: len=%d\n", raw->len); + raw->nbyte = 0; + return -1; + } + if (fread(raw->buff + 4, 1, raw->len - 4, fp) < (size_t)(raw->len - 4)) return -2; + raw->nbyte = 0; + + /* decode skytraq raw message */ + return decode_stq(raw); } /* generate skytraq binary message --------------------------------------------- -* generate skytraq binary message from message string -* args : char *msg I message string -* "RESTART [arg...]" system restart -* "CFG-SERI [arg...]" configure serial port propperty -* "CFG-FMT [arg...]" configure output message format -* "CFG-RATE [arg...]" configure binary measurement output rates -* "CFG-BIN [arg...]" configure general binary -* "GET-GLOEPH [slot]" get glonass ephemeris for freq channel number -* uint8_t *buff O binary message -* return : length of binary message (0: error) -* note : see reference [1][2][3][4] for details. -*-----------------------------------------------------------------------------*/ -extern int gen_stq(const char *msg, uint8_t *buff) -{ - const char *hz[]={"1Hz","2Hz","4Hz","5Hz","10Hz","20Hz",""}; - uint8_t *q=buff; - char mbuff[1024],*args[32],*p; - int i,n,narg=0; - - trace(4,"gen_stq: msg=%s\n",msg); - - strcpy(mbuff,msg); - char *r; - for (p=strtok_r(mbuff," ",&r);p&&narg<32;p=strtok_r(NULL," ",&r)) { - args[narg++]=p; - } - if (narg<1) { - return 0; - } - *q++=STQSYNC1; - *q++=STQSYNC2; - if (!strcmp(args[0],"RESTART")) { - *q++=0; - *q++=15; - *q++=ID_RESTART; - *q++=narg>2?(uint8_t)atoi(args[1]):0; - for (i=1;i<15;i++) *q++=0; /* set all 0 */ - } - else if (!strcmp(args[0],"CFG-SERI")) { - *q++=0; - *q++=4; - *q++=ID_CFGSERI; - for (i=1;i<4;i++) *q++=narg>i+1?(uint8_t)atoi(args[i]):0; - } - else if (!strcmp(args[0],"CFG-FMT")) { - *q++=0; - *q++=3; - *q++=ID_CFGFMT; - for (i=1;i<3;i++) *q++=narg>i+1?(uint8_t)atoi(args[i]):0; - } - else if (!strcmp(args[0],"CFG-RATE")) { - *q++=0; - *q++=8; - *q++=ID_CFGRATE; - if (narg>2) { - for (i=0;*hz[i];i++) if (!strcmp(args[1],hz[i])) break; - if (*hz[i]) *q++=i; else *q++=(uint8_t)atoi(args[1]); - } - else *q++=0; - for (i=2;i<8;i++) *q++=narg>i+1?(uint8_t)atoi(args[i]):0; - } - else if (!strcmp(args[0],"CFG-BIN")) { - *q++=0; - *q++=9; /* F/W 1.4.32 */ - *q++=ID_CFGBIN; - if (narg>2) { - for (i=0;*hz[i];i++) if (!strcmp(args[1],hz[i])) break; - if (*hz[i]) *q++=i; else *q++=(uint8_t)atoi(args[1]); - } - else *q++=0; - for (i=2;i<9;i++) *q++=narg>i+1?(uint8_t)atoi(args[i]):0; - } - else if (!strcmp(args[0],"GET-GLOEPH")) { - *q++=0; - *q++=2; - *q++=ID_GETGLOEPH; - *q++=narg>=2?(uint8_t)atoi(args[1]):0; - } - else return 0; - - n=(int)(q-buff); - *q++=checksum(buff,n+3); - *q++=0x0D; - *q=0x0A; - - trace(4,"gen_stq: buff=\n"); traceb(4,buff,n+3); - return n+3; + * generate skytraq binary message from message string + * args : char *msg I message string + * "RESTART [arg...]" system restart + * "CFG-SERI [arg...]" configure serial port propperty + * "CFG-FMT [arg...]" configure output message format + * "CFG-RATE [arg...]" configure binary measurement output rates + * "CFG-BIN [arg...]" configure general binary + * "GET-GLOEPH [slot]" get glonass ephemeris for freq channel number + * uint8_t *buff O binary message + * return : length of binary message (0: error) + * note : see reference [1][2][3][4] for details. + *-----------------------------------------------------------------------------*/ +extern int gen_stq(const char *msg, uint8_t *buff) { + const char *hz[] = {"1Hz", "2Hz", "4Hz", "5Hz", "10Hz", "20Hz", ""}; + uint8_t *q = buff; + char mbuff[1024], *args[32], *p; + int i, n, narg = 0; + + trace(4, "gen_stq: msg=%s\n", msg); + + strcpy(mbuff, msg); + char *r; + for (p = strtok_r(mbuff, " ", &r); p && narg < 32; p = strtok_r(NULL, " ", &r)) { + args[narg++] = p; + } + if (narg < 1) { + return 0; + } + *q++ = STQSYNC1; + *q++ = STQSYNC2; + if (!strcmp(args[0], "RESTART")) { + *q++ = 0; + *q++ = 15; + *q++ = ID_RESTART; + *q++ = narg > 2 ? (uint8_t)atoi(args[1]) : 0; + for (i = 1; i < 15; i++) *q++ = 0; /* set all 0 */ + } else if (!strcmp(args[0], "CFG-SERI")) { + *q++ = 0; + *q++ = 4; + *q++ = ID_CFGSERI; + for (i = 1; i < 4; i++) *q++ = narg > i + 1 ? (uint8_t)atoi(args[i]) : 0; + } else if (!strcmp(args[0], "CFG-FMT")) { + *q++ = 0; + *q++ = 3; + *q++ = ID_CFGFMT; + for (i = 1; i < 3; i++) *q++ = narg > i + 1 ? (uint8_t)atoi(args[i]) : 0; + } else if (!strcmp(args[0], "CFG-RATE")) { + *q++ = 0; + *q++ = 8; + *q++ = ID_CFGRATE; + if (narg > 2) { + for (i = 0; *hz[i]; i++) + if (!strcmp(args[1], hz[i])) break; + if (*hz[i]) + *q++ = i; + else + *q++ = (uint8_t)atoi(args[1]); + } else + *q++ = 0; + for (i = 2; i < 8; i++) *q++ = narg > i + 1 ? (uint8_t)atoi(args[i]) : 0; + } else if (!strcmp(args[0], "CFG-BIN")) { + *q++ = 0; + *q++ = 9; /* F/W 1.4.32 */ + *q++ = ID_CFGBIN; + if (narg > 2) { + for (i = 0; *hz[i]; i++) + if (!strcmp(args[1], hz[i])) break; + if (*hz[i]) + *q++ = i; + else + *q++ = (uint8_t)atoi(args[1]); + } else + *q++ = 0; + for (i = 2; i < 9; i++) *q++ = narg > i + 1 ? (uint8_t)atoi(args[i]) : 0; + } else if (!strcmp(args[0], "GET-GLOEPH")) { + *q++ = 0; + *q++ = 2; + *q++ = ID_GETGLOEPH; + *q++ = narg >= 2 ? (uint8_t)atoi(args[1]) : 0; + } else + return 0; + + n = (int)(q - buff); + *q++ = checksum(buff, n + 3); + *q++ = 0x0D; + *q = 0x0A; + + trace(4, "gen_stq: buff=\n"); + traceb(4, buff, n + 3); + return n + 3; } diff --git a/src/rcv/swiftnav.c b/src/rcv/swiftnav.c index 2fba8f2e3..6b0acb1e9 100644 --- a/src/rcv/swiftnav.c +++ b/src/rcv/swiftnav.c @@ -9,21 +9,21 @@ * version : $Revision: 1.0 $ $Date: 2017/01/30 09:00:00 $ * * history : 2017/01/30 1.0 begin writing - *-----------------------------------------------------------------------------*/ -#include "rtklib.h" - + *-----------------------------------------------------------------------------*/ #include #include +#include "rtklib.h" + #define SBP_SYNC1 0x55 /* SBP message header sync */ #define ID_MSGOBS 0x004A /* observation */ #define ID_MSGEPHGPS_DEP_E 0x0081 /* GPS L1 C/A nav message (deprecated) */ #define ID_MSGEPHGPS_DEP_F 0x0086 /* GPS L1 C/A nav message (deprecated) */ -#define ID_MSGEPHGPS 0x008A /* GPS L1 C/A nav message */ +#define ID_MSGEPHGPS 0x008A /* GPS L1 C/A nav message */ -#define ID_MSGEPHBDS 0x0089 /* BDS B1/B2 D1 nav message */ +#define ID_MSGEPHBDS 0x0089 /* BDS B1/B2 D1 nav message */ #define ID_MSGEPHQZSS 0x008E /* QZSS nav message */ @@ -36,8 +36,8 @@ #define ID_MSGEPHGLO_DEP_D 0x0088 /* Glonass ephemeris (deprecated) */ #define ID_MSGEPHGLO 0x008B /* Glonass L1/L2 ephemeris */ -#define ID_MSGIONGPS 0x0090 /* GPS ionospheric parameters */ -#define ID_MSG_SBAS_RAW 0x7777 /* SBAS data */ +#define ID_MSGIONGPS 0x0090 /* GPS ionospheric parameters */ +#define ID_MSG_SBAS_RAW 0x7777 /* SBAS data */ #define SEC_DAY 86400.0 @@ -93,12 +93,12 @@ typedef enum code_e { CODE_GPS_L2CX = 8, /* combined L2C tracking */ CODE_GPS_L5I = 9, CODE_GPS_L5Q = 10, - CODE_GPS_L5X = 11, /* combined L5 tracking */ + CODE_GPS_L5X = 11, /* combined L5 tracking */ CODE_BDS2_B1 = 12, /* data channel at 1526 * 1.023 MHz */ - CODE_BDS2_B2 = 13, /* data channel at 1180 * 1.023 MHz */ - CODE_GAL_E1B = 14, /* data channel at E1 (1540 * 1.023 MHz) */ - CODE_GAL_E1C = 15, /* pilot channel at E1 */ - CODE_GAL_E1X = 16, /* combined tracking on E1 */ + CODE_BDS2_B2 = 13, /* data channel at 1180 * 1.023 MHz */ + CODE_GAL_E1B = 14, /* data channel at E1 (1540 * 1.023 MHz) */ + CODE_GAL_E1C = 15, /* pilot channel at E1 */ + CODE_GAL_E1X = 16, /* combined tracking on E1 */ CODE_GAL_E6B = 17, CODE_GAL_E6C = 18, CODE_GAL_E6X = 19, /* combined tracking on E6 */ @@ -155,41 +155,40 @@ typedef struct { uint32_t freq; } bandcode_t; -static bandcode_t rtklib_bandcode_map[CODE_COUNT] = - {{CODE_L1C, SYS_GPS, 0}, /* [CODE_GPS_L1CA] */ - {CODE_L2S, SYS_GPS, 1}, /* [CODE_GPS_L2CM] */ - {CODE_L1C, SYS_SBS, 0}, /* [CODE_SBAS_L1CA]*/ - {CODE_L1C, SYS_GLO, 0}, /* [CODE_GLO_L1OF] */ - {CODE_L2C, SYS_GLO, 1}, /* [CODE_GLO_L2OF] */ - {CODE_L1P, SYS_GPS, 0}, /* [CODE_GPS_L1P] */ - {CODE_L2P, SYS_GPS, 1}, /* [CODE_GPS_L2P] */ - {CODE_L2L, SYS_GPS, 1}, /* [CODE_GPS_L2CL] */ - {CODE_L2X, SYS_GPS, 1}, /* [CODE_GPS_L2CX] */ - {CODE_L5I, SYS_GPS, 3}, /* [CODE_GPS_L5I] */ - {CODE_L5Q, SYS_GPS, 3}, /* [CODE_GPS_L5Q] */ - {CODE_L5X, SYS_GPS, 3}, /* [CODE_GPS_L5X] */ - {CODE_L2I, SYS_CMP, 0}, /* [CODE_BDS2_B1] */ - {CODE_L7I, SYS_CMP, 1}, /* [CODE_BDS2_B2] */ - {CODE_L1B, SYS_GAL, 0}, /* [CODE_GAL_E1B] */ - {CODE_L1C, SYS_GAL, 0}, /* [CODE_GAL_E1C] */ - {CODE_L1X, SYS_GAL, 0}, /* [CODE_GAL_E1X] */ - {CODE_L6B, SYS_GAL, 4}, /* [CODE_GAL_E6B] */ - {CODE_L6C, SYS_GAL, 4}, /* [CODE_GAL_E6C] */ - {CODE_L6X, SYS_GAL, 4}, /* [CODE_GAL_E6X] */ - {CODE_L7I, SYS_GAL, 2}, /* [CODE_GAL_E7I] */ - {CODE_L7Q, SYS_GAL, 2}, /* [CODE_GAL_E7Q] */ - {CODE_L7X, SYS_GAL, 2}, /* [CODE_GAL_E7X] */ - {CODE_L8X, SYS_GAL, 3}, /* [CODE_GAL_E8] */ - {CODE_L5I, SYS_GAL, 3}, /* [CODE_GAL_E5I] */ - {CODE_L5Q, SYS_GAL, 3}, /* [CODE_GAL_E5Q] */ - {CODE_L5X, SYS_GAL, 3}, /* [CODE_GAL_E5X] */ - {CODE_L1C, SYS_QZS, 0}, /* [CODE_QZS_L1CA] */ - {CODE_L2S, SYS_QZS, 1}, /* [CODE_QZS_L2CM] */ - {CODE_L2L, SYS_QZS, 1}, /* [CODE_QZS_L2CL] */ - {CODE_L2X, SYS_QZS, 1}, /* [CODE_QZS_L2CX] */ - {CODE_L5I, SYS_QZS, 3}, /* [CODE_QZS_L5I] */ - {CODE_L5Q, SYS_QZS, 3}, /* [CODE_QZS_L5Q] */ - {CODE_L5X, SYS_QZS, 3}}; /* [CODE_QZS_L5X] */ +static bandcode_t rtklib_bandcode_map[CODE_COUNT] = {{CODE_L1C, SYS_GPS, 0}, /* [CODE_GPS_L1CA] */ + {CODE_L2S, SYS_GPS, 1}, /* [CODE_GPS_L2CM] */ + {CODE_L1C, SYS_SBS, 0}, /* [CODE_SBAS_L1CA]*/ + {CODE_L1C, SYS_GLO, 0}, /* [CODE_GLO_L1OF] */ + {CODE_L2C, SYS_GLO, 1}, /* [CODE_GLO_L2OF] */ + {CODE_L1P, SYS_GPS, 0}, /* [CODE_GPS_L1P] */ + {CODE_L2P, SYS_GPS, 1}, /* [CODE_GPS_L2P] */ + {CODE_L2L, SYS_GPS, 1}, /* [CODE_GPS_L2CL] */ + {CODE_L2X, SYS_GPS, 1}, /* [CODE_GPS_L2CX] */ + {CODE_L5I, SYS_GPS, 3}, /* [CODE_GPS_L5I] */ + {CODE_L5Q, SYS_GPS, 3}, /* [CODE_GPS_L5Q] */ + {CODE_L5X, SYS_GPS, 3}, /* [CODE_GPS_L5X] */ + {CODE_L2I, SYS_CMP, 0}, /* [CODE_BDS2_B1] */ + {CODE_L7I, SYS_CMP, 1}, /* [CODE_BDS2_B2] */ + {CODE_L1B, SYS_GAL, 0}, /* [CODE_GAL_E1B] */ + {CODE_L1C, SYS_GAL, 0}, /* [CODE_GAL_E1C] */ + {CODE_L1X, SYS_GAL, 0}, /* [CODE_GAL_E1X] */ + {CODE_L6B, SYS_GAL, 4}, /* [CODE_GAL_E6B] */ + {CODE_L6C, SYS_GAL, 4}, /* [CODE_GAL_E6C] */ + {CODE_L6X, SYS_GAL, 4}, /* [CODE_GAL_E6X] */ + {CODE_L7I, SYS_GAL, 2}, /* [CODE_GAL_E7I] */ + {CODE_L7Q, SYS_GAL, 2}, /* [CODE_GAL_E7Q] */ + {CODE_L7X, SYS_GAL, 2}, /* [CODE_GAL_E7X] */ + {CODE_L8X, SYS_GAL, 3}, /* [CODE_GAL_E8] */ + {CODE_L5I, SYS_GAL, 3}, /* [CODE_GAL_E5I] */ + {CODE_L5Q, SYS_GAL, 3}, /* [CODE_GAL_E5Q] */ + {CODE_L5X, SYS_GAL, 3}, /* [CODE_GAL_E5X] */ + {CODE_L1C, SYS_QZS, 0}, /* [CODE_QZS_L1CA] */ + {CODE_L2S, SYS_QZS, 1}, /* [CODE_QZS_L2CM] */ + {CODE_L2L, SYS_QZS, 1}, /* [CODE_QZS_L2CL] */ + {CODE_L2X, SYS_QZS, 1}, /* [CODE_QZS_L2CX] */ + {CODE_L5I, SYS_QZS, 3}, /* [CODE_QZS_L5I] */ + {CODE_L5Q, SYS_QZS, 3}, /* [CODE_QZS_L5Q] */ + {CODE_L5X, SYS_QZS, 3}}; /* [CODE_QZS_L5X] */ #define IS_GPS(c) (SYS_GPS == rtklib_bandcode_map[(c)].sys) #define IS_QZSS(c) (SYS_QZS == rtklib_bandcode_map[(c)].sys) #define IS_BDS(c) (SYS_CMP == rtklib_bandcode_map[(c)].sys) @@ -199,86 +198,57 @@ static bandcode_t rtklib_bandcode_map[CODE_COUNT] = /* checksum lookup table -----------------------------------------------------*/ static const uint32_t CRC_16CCIT_LookUp[256] = { - 0x0000, 0x1021, 0x2042, 0x3063, 0x4084, 0x50a5, 0x60c6, 0x70e7, 0x8108, - 0x9129, 0xa14a, 0xb16b, 0xc18c, 0xd1ad, 0xe1ce, 0xf1ef, 0x1231, 0x0210, - 0x3273, 0x2252, 0x52b5, 0x4294, 0x72f7, 0x62d6, 0x9339, 0x8318, 0xb37b, - 0xa35a, 0xd3bd, 0xc39c, 0xf3ff, 0xe3de, 0x2462, 0x3443, 0x0420, 0x1401, - 0x64e6, 0x74c7, 0x44a4, 0x5485, 0xa56a, 0xb54b, 0x8528, 0x9509, 0xe5ee, - 0xf5cf, 0xc5ac, 0xd58d, 0x3653, 0x2672, 0x1611, 0x0630, 0x76d7, 0x66f6, - 0x5695, 0x46b4, 0xb75b, 0xa77a, 0x9719, 0x8738, 0xf7df, 0xe7fe, 0xd79d, - 0xc7bc, 0x48c4, 0x58e5, 0x6886, 0x78a7, 0x0840, 0x1861, 0x2802, 0x3823, - 0xc9cc, 0xd9ed, 0xe98e, 0xf9af, 0x8948, 0x9969, 0xa90a, 0xb92b, 0x5af5, - 0x4ad4, 0x7ab7, 0x6a96, 0x1a71, 0x0a50, 0x3a33, 0x2a12, 0xdbfd, 0xcbdc, - 0xfbbf, 0xeb9e, 0x9b79, 0x8b58, 0xbb3b, 0xab1a, 0x6ca6, 0x7c87, 0x4ce4, - 0x5cc5, 0x2c22, 0x3c03, 0x0c60, 0x1c41, 0xedae, 0xfd8f, 0xcdec, 0xddcd, - 0xad2a, 0xbd0b, 0x8d68, 0x9d49, 0x7e97, 0x6eb6, 0x5ed5, 0x4ef4, 0x3e13, - 0x2e32, 0x1e51, 0x0e70, 0xff9f, 0xefbe, 0xdfdd, 0xcffc, 0xbf1b, 0xaf3a, - 0x9f59, 0x8f78, 0x9188, 0x81a9, 0xb1ca, 0xa1eb, 0xd10c, 0xc12d, 0xf14e, - 0xe16f, 0x1080, 0x00a1, 0x30c2, 0x20e3, 0x5004, 0x4025, 0x7046, 0x6067, - 0x83b9, 0x9398, 0xa3fb, 0xb3da, 0xc33d, 0xd31c, 0xe37f, 0xf35e, 0x02b1, - 0x1290, 0x22f3, 0x32d2, 0x4235, 0x5214, 0x6277, 0x7256, 0xb5ea, 0xa5cb, - 0x95a8, 0x8589, 0xf56e, 0xe54f, 0xd52c, 0xc50d, 0x34e2, 0x24c3, 0x14a0, - 0x0481, 0x7466, 0x6447, 0x5424, 0x4405, 0xa7db, 0xb7fa, 0x8799, 0x97b8, - 0xe75f, 0xf77e, 0xc71d, 0xd73c, 0x26d3, 0x36f2, 0x0691, 0x16b0, 0x6657, - 0x7676, 0x4615, 0x5634, 0xd94c, 0xc96d, 0xf90e, 0xe92f, 0x99c8, 0x89e9, - 0xb98a, 0xa9ab, 0x5844, 0x4865, 0x7806, 0x6827, 0x18c0, 0x08e1, 0x3882, - 0x28a3, 0xcb7d, 0xdb5c, 0xeb3f, 0xfb1e, 0x8bf9, 0x9bd8, 0xabbb, 0xbb9a, - 0x4a75, 0x5a54, 0x6a37, 0x7a16, 0x0af1, 0x1ad0, 0x2ab3, 0x3a92, 0xfd2e, - 0xed0f, 0xdd6c, 0xcd4d, 0xbdaa, 0xad8b, 0x9de8, 0x8dc9, 0x7c26, 0x6c07, - 0x5c64, 0x4c45, 0x3ca2, 0x2c83, 0x1ce0, 0x0cc1, 0xef1f, 0xff3e, 0xcf5d, - 0xdf7c, 0xaf9b, 0xbfba, 0x8fd9, 0x9ff8, 0x6e17, 0x7e36, 0x4e55, 0x5e74, + 0x0000, 0x1021, 0x2042, 0x3063, 0x4084, 0x50a5, 0x60c6, 0x70e7, 0x8108, 0x9129, 0xa14a, 0xb16b, + 0xc18c, 0xd1ad, 0xe1ce, 0xf1ef, 0x1231, 0x0210, 0x3273, 0x2252, 0x52b5, 0x4294, 0x72f7, 0x62d6, + 0x9339, 0x8318, 0xb37b, 0xa35a, 0xd3bd, 0xc39c, 0xf3ff, 0xe3de, 0x2462, 0x3443, 0x0420, 0x1401, + 0x64e6, 0x74c7, 0x44a4, 0x5485, 0xa56a, 0xb54b, 0x8528, 0x9509, 0xe5ee, 0xf5cf, 0xc5ac, 0xd58d, + 0x3653, 0x2672, 0x1611, 0x0630, 0x76d7, 0x66f6, 0x5695, 0x46b4, 0xb75b, 0xa77a, 0x9719, 0x8738, + 0xf7df, 0xe7fe, 0xd79d, 0xc7bc, 0x48c4, 0x58e5, 0x6886, 0x78a7, 0x0840, 0x1861, 0x2802, 0x3823, + 0xc9cc, 0xd9ed, 0xe98e, 0xf9af, 0x8948, 0x9969, 0xa90a, 0xb92b, 0x5af5, 0x4ad4, 0x7ab7, 0x6a96, + 0x1a71, 0x0a50, 0x3a33, 0x2a12, 0xdbfd, 0xcbdc, 0xfbbf, 0xeb9e, 0x9b79, 0x8b58, 0xbb3b, 0xab1a, + 0x6ca6, 0x7c87, 0x4ce4, 0x5cc5, 0x2c22, 0x3c03, 0x0c60, 0x1c41, 0xedae, 0xfd8f, 0xcdec, 0xddcd, + 0xad2a, 0xbd0b, 0x8d68, 0x9d49, 0x7e97, 0x6eb6, 0x5ed5, 0x4ef4, 0x3e13, 0x2e32, 0x1e51, 0x0e70, + 0xff9f, 0xefbe, 0xdfdd, 0xcffc, 0xbf1b, 0xaf3a, 0x9f59, 0x8f78, 0x9188, 0x81a9, 0xb1ca, 0xa1eb, + 0xd10c, 0xc12d, 0xf14e, 0xe16f, 0x1080, 0x00a1, 0x30c2, 0x20e3, 0x5004, 0x4025, 0x7046, 0x6067, + 0x83b9, 0x9398, 0xa3fb, 0xb3da, 0xc33d, 0xd31c, 0xe37f, 0xf35e, 0x02b1, 0x1290, 0x22f3, 0x32d2, + 0x4235, 0x5214, 0x6277, 0x7256, 0xb5ea, 0xa5cb, 0x95a8, 0x8589, 0xf56e, 0xe54f, 0xd52c, 0xc50d, + 0x34e2, 0x24c3, 0x14a0, 0x0481, 0x7466, 0x6447, 0x5424, 0x4405, 0xa7db, 0xb7fa, 0x8799, 0x97b8, + 0xe75f, 0xf77e, 0xc71d, 0xd73c, 0x26d3, 0x36f2, 0x0691, 0x16b0, 0x6657, 0x7676, 0x4615, 0x5634, + 0xd94c, 0xc96d, 0xf90e, 0xe92f, 0x99c8, 0x89e9, 0xb98a, 0xa9ab, 0x5844, 0x4865, 0x7806, 0x6827, + 0x18c0, 0x08e1, 0x3882, 0x28a3, 0xcb7d, 0xdb5c, 0xeb3f, 0xfb1e, 0x8bf9, 0x9bd8, 0xabbb, 0xbb9a, + 0x4a75, 0x5a54, 0x6a37, 0x7a16, 0x0af1, 0x1ad0, 0x2ab3, 0x3a92, 0xfd2e, 0xed0f, 0xdd6c, 0xcd4d, + 0xbdaa, 0xad8b, 0x9de8, 0x8dc9, 0x7c26, 0x6c07, 0x5c64, 0x4c45, 0x3ca2, 0x2c83, 0x1ce0, 0x0cc1, + 0xef1f, 0xff3e, 0xcf5d, 0xdf7c, 0xaf9b, 0xbfba, 0x8fd9, 0x9ff8, 0x6e17, 0x7e36, 0x4e55, 0x5e74, 0x2e93, 0x3eb2, 0x0ed1, 0x1ef0}; /* it's easy to derive a function for the values below, but I'd rather map the * table explicitly from the RTCM standard document */ -static const uint32_t rtcm_phase_lock_table[16] = {0, - 32, - 64, - 128, - 256, - 512, - 1024, - 2048, - 4096, - 8192, - 16384, - 32768, - 65536, - 131072, - 262144, - 524288}; +static const uint32_t rtcm_phase_lock_table[16] = { + 0, 32, 64, 128, 256, 512, 1024, 2048, 4096, 8192, 16384, 32768, 65536, 131072, 262144, 524288}; static const uint8_t decoding_table[256] = { - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3E, 0x00, 0x00, 0x00, 0x3F, - 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, - 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12, - 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, 0x20, 0x21, 0x22, 0x23, 0x24, - 0x25, 0x26, 0x27, 0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F, 0x30, - 0x31, 0x32, 0x33, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00}; + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3E, 0x00, 0x00, 0x00, 0x3F, + 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, + 0x0F, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, + 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F, 0x30, 0x31, 0x32, 0x33, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; static uint8_t puPayloadTmp[256]; static const gtime_t time0 = {0}; -static int Base64_Decode(uint8_t *_pcData, - uint32_t _uDataLen, - uint8_t *_puDecodedData, +static int Base64_Decode(uint8_t *_pcData, uint32_t _uDataLen, uint8_t *_puDecodedData, uint32_t *_puDecodedDataLen) { uint32_t i, j; uint32_t output_length; @@ -334,24 +304,25 @@ static int Base64_Decode(uint8_t *_pcData, } /* Base64_Decode() */ /* URA value (m) to URA index ------------------------------------------------*/ -static int uraindex(double value) -{ - static const double ura_eph[]={ - 2.4,3.4,4.85,6.85,9.65,13.65,24.0,48.0,96.0,192.0,384.0,768.0,1536.0, - 3072.0,6144.0,0.0 - }; - int i; - for (i=0;i<15;i++) if (ura_eph[i]>=value) break; - return i; +static int uraindex(double value) { + static const double ura_eph[] = {2.4, 3.4, 4.85, 6.85, 9.65, 13.65, 24.0, 48.0, + 96.0, 192.0, 384.0, 768.0, 1536.0, 3072.0, 6144.0, 0.0}; + int i; + for (i = 0; i < 15; i++) + if (ura_eph[i] >= value) break; + return i; } -static int sisa_index(double value) -{ - if (value<0.0 || value>6.0) return 255; /* unknown or NAPA */ - else if (value<=0.5) return (int)(value/0.01); - else if (value<=1.0) return (int)((value-0.5)/0.02)+50; - else if (value<=2.0) return (int)((value-1.0)/0.04)+75; - return ((int)(value-2.0)/0.16)+100; +static int sisa_index(double value) { + if (value < 0.0 || value > 6.0) + return 255; /* unknown or NAPA */ + else if (value <= 0.5) + return (int)(value / 0.01); + else if (value <= 1.0) + return (int)((value - 0.5) / 0.02) + 50; + else if (value <= 2.0) + return (int)((value - 1.0) / 0.04) + 75; + return ((int)(value - 2.0) / 0.16) + 100; } /* SBP checksum calculation --------------------------------------------------*/ @@ -413,9 +384,7 @@ static void clearbuff(raw_t *raw) { } /* appropriate calculation of LLI for SBP */ -static uint8_t calculate_loss_of_lock(double dt, - uint32_t prev_lock_time, - uint32_t curr_lock_time) { +static uint8_t calculate_loss_of_lock(double dt, uint32_t prev_lock_time, uint32_t curr_lock_time) { if (prev_lock_time > curr_lock_time) { /* fprintf(stderr, "prev_lock_time %d curr_lock_time %d\n", * prev_lock_time, curr_lock_time);*/ @@ -425,13 +394,11 @@ static uint8_t calculate_loss_of_lock(double dt, return 1; } else if ((prev_lock_time == curr_lock_time) && (dt < prev_lock_time)) { return 0; - } else if ((prev_lock_time < curr_lock_time) && - (dt >= (2 * curr_lock_time - prev_lock_time))) { + } else if ((prev_lock_time < curr_lock_time) && (dt >= (2 * curr_lock_time - prev_lock_time))) { /*fprintf(stderr, "3\n");*/ return 1; } else if ((prev_lock_time < curr_lock_time) && - (curr_lock_time < dt && - dt < (2 * curr_lock_time - prev_lock_time))) { + (curr_lock_time < dt && dt < (2 * curr_lock_time - prev_lock_time))) { /*fprintf(stderr, "4\n");*/ return 1; } else if ((prev_lock_time < curr_lock_time) && (dt <= curr_lock_time)) @@ -462,7 +429,7 @@ static int decode_msgobs(raw_t *raw) { dResTow = I4(p + 4); /* residual Time Of Week */ week = U2(p + 8); /* GPS week */ week = adjgpsweek(week); - num_obs = p[10]; /* number of observations in message */ + num_obs = p[10]; /* number of observations in message */ /* uSeqSize = num_obs>>4; */ /* uSeqIdx = num_obs&0xf; */ num_obs = ((raw->len) - 19) / 17; @@ -483,14 +450,14 @@ static int decode_msgobs(raw_t *raw) { /* add observations */ for (i = 0; i < num_obs && i < MAXOBS; i++, p += 17) { - pseudorange = U4(p) * 0.02; /* pseudorange observation in 2cm units */ - carr_phase = I4(p + 4); /* carrier phase integer cycles */ - carr_phase += p[8] / 256.0; /* carrier phase fractional cycles */ - freq_doppler = I2(p + 9); /* Doppler shift in integer Hz */ - freq_doppler += p[11] / 256.0; /* fractional part of Doppler shift */ + pseudorange = U4(p) * 0.02; /* pseudorange observation in 2cm units */ + carr_phase = I4(p + 4); /* carrier phase integer cycles */ + carr_phase += p[8] / 256.0; /* carrier phase fractional cycles */ + freq_doppler = I2(p + 9); /* Doppler shift in integer Hz */ + freq_doppler += p[11] / 256.0; /* fractional part of Doppler shift */ cn0_int = p[12]; /* C/N0 */ - lock_info = p[13] & 0xf; /* lock time */ - flags = p[14]; /* observation flags */ + lock_info = p[13] & 0xf; /* lock time */ + flags = p[14]; /* observation flags */ sat_id = p[15]; band_code = p[16]; @@ -539,8 +506,7 @@ static int decode_msgobs(raw_t *raw) { if (flags & 0x2) { prev_lockt = rtcm_phase_lock_table[(raw->halfc[sat - 1][freq])]; curr_lockt = rtcm_phase_lock_table[lock_info]; - slip = - calculate_loss_of_lock(delta_time * 1000.0, prev_lockt, curr_lockt); + slip = calculate_loss_of_lock(delta_time * 1000.0, prev_lockt, curr_lockt); half_cycle_amb = (flags & 0x4) ? 0 : 1; if (half_cycle_amb) { slip |= 0x2; /* half-cycle ambiguity unresolved */ @@ -775,15 +741,10 @@ static int decode_gpsnav_dep_e(raw_t *raw) { } if (!strstr(raw->opt, "EPHALL")) { - if ((eph.iode == raw->nav.eph[sat - 1].iode) && - (eph.iodc == raw->nav.eph[sat - 1].iodc)) { - trace(3, - "decode_gpsnav_dep_e: eph.iode %d raw->nav.eph[sat - 1].iode %d\n", - eph.iode, + if ((eph.iode == raw->nav.eph[sat - 1].iode) && (eph.iodc == raw->nav.eph[sat - 1].iodc)) { + trace(3, "decode_gpsnav_dep_e: eph.iode %d raw->nav.eph[sat - 1].iode %d\n", eph.iode, raw->nav.eph[sat - 1].iode); - trace(3, - "%decode_gpsnav_dep_e: eph.iodc %d raw->nav.eph[sat - 1].iodc %d\n", - eph.iode, + trace(3, "%decode_gpsnav_dep_e: eph.iodc %d raw->nav.eph[sat - 1].iodc %d\n", eph.iode, raw->nav.eph[sat - 1].iode); return 0; } @@ -792,7 +753,7 @@ static int decode_gpsnav_dep_e(raw_t *raw) { eph.sat = sat; raw->nav.eph[sat - 1] = eph; raw->ephsat = sat; - raw->ephset=0; + raw->ephset = 0; return 2; } @@ -822,8 +783,7 @@ static int decode_gpsnav_dep_f(raw_t *raw) { eph.code = puiTmp[1]; if (!IS_GPS(eph.code)) { - trace( - 2, "decode_gpsnav_dep_f: unrecognised code %d for G%02d\n", eph.code, prn); + trace(2, "decode_gpsnav_dep_f: unrecognised code %d for G%02d\n", eph.code, prn); return -1; } @@ -832,14 +792,13 @@ static int decode_gpsnav_dep_f(raw_t *raw) { if (0 == timediff(raw->time, time0)) { eph.ttr = timeget(); } else { - eph.ttr = raw->time; + eph.ttr = raw->time; } if (!strstr(raw->opt, "EPHALL")) { - if ((eph.iode == raw->nav.eph[sat - 1].iode) && - (eph.iodc == raw->nav.eph[sat - 1].iodc)) { + if ((eph.iode == raw->nav.eph[sat - 1].iode) && (eph.iodc == raw->nav.eph[sat - 1].iodc)) { return 0; - } + } } trace(3, "decode_gpsnav_dep_f: decoded eph for G%02d\n", prn); @@ -877,8 +836,7 @@ static int decode_gpsnav(raw_t *raw) { eph.code = puiTmp[1]; if (!IS_GPS(eph.code)) { - trace( - 2, "decode_gpsnav: unrecognised code %d for G%02d\n", eph.code, prn); + trace(2, "decode_gpsnav: unrecognised code %d for G%02d\n", eph.code, prn); return -1; } @@ -891,16 +849,9 @@ static int decode_gpsnav(raw_t *raw) { } if (!strstr(raw->opt, "EPHALL")) { - if ((eph.iode == raw->nav.eph[sat - 1].iode) && - (eph.iodc == raw->nav.eph[sat - 1].iodc)) { - trace(3, - "eph.iode %d raw->nav.eph[sat - 1].iode %d\n", - eph.iode, - raw->nav.eph[sat - 1].iode); - trace(3, - "eph.iodc %d raw->nav.eph[sat - 1].iodc %d\n", - eph.iode, - raw->nav.eph[sat - 1].iode); + if ((eph.iode == raw->nav.eph[sat - 1].iode) && (eph.iodc == raw->nav.eph[sat - 1].iodc)) { + trace(3, "eph.iode %d raw->nav.eph[sat - 1].iode %d\n", eph.iode, raw->nav.eph[sat - 1].iode); + trace(3, "eph.iodc %d raw->nav.eph[sat - 1].iodc %d\n", eph.iode, raw->nav.eph[sat - 1].iode); return 0; } } @@ -940,8 +891,7 @@ static int decode_qzssnav(raw_t *raw) { eph.code = puiTmp[1]; if (!IS_QZSS(eph.code)) { - trace( - 2, "decode_qzssnav: unrecognised code %d for G%02d\n", eph.code, prn); + trace(2, "decode_qzssnav: unrecognised code %d for G%02d\n", eph.code, prn); return -1; } @@ -950,20 +900,13 @@ static int decode_qzssnav(raw_t *raw) { if (0 == timediff(raw->time, time0)) { eph.ttr = timeget(); } else { - eph.ttr = raw->time; + eph.ttr = raw->time; } if (!strstr(raw->opt, "EPHALL")) { - if ((eph.iode == raw->nav.eph[sat - 1].iode) && - (eph.iodc == raw->nav.eph[sat - 1].iodc)) { - trace(3, - "eph.iode %d raw->nav.eph[sat - 1].iode %d\n", - eph.iode, - raw->nav.eph[sat - 1].iode); - trace(3, - "eph.iodc %d raw->nav.eph[sat - 1].iodc %d\n", - eph.iode, - raw->nav.eph[sat - 1].iode); + if ((eph.iode == raw->nav.eph[sat - 1].iode) && (eph.iodc == raw->nav.eph[sat - 1].iodc)) { + trace(3, "eph.iode %d raw->nav.eph[sat - 1].iode %d\n", eph.iode, raw->nav.eph[sat - 1].iode); + trace(3, "eph.iodc %d raw->nav.eph[sat - 1].iodc %d\n", eph.iode, raw->nav.eph[sat - 1].iode); return 0; } } @@ -1003,8 +946,7 @@ static int decode_bdsnav(raw_t *raw) { eph.code = puiTmp[1]; if (!IS_BDS(eph.code)) { - trace( - 2, "decode_bdsnav: unrecognised code %d for C%02d\n", eph.code, prn); + trace(2, "decode_bdsnav: unrecognised code %d for C%02d\n", eph.code, prn); return -1; } @@ -1013,8 +955,7 @@ static int decode_bdsnav(raw_t *raw) { eph.ttr = raw->time; if (!strstr(raw->opt, "EPHALL")) { - if ((eph.iode == raw->nav.eph[sat - 1].iode) && - (eph.iodc == raw->nav.eph[sat - 1].iodc)) { + if ((eph.iode == raw->nav.eph[sat - 1].iode) && (eph.iodc == raw->nav.eph[sat - 1].iodc)) { return 0; } } @@ -1048,15 +989,13 @@ static int decode_galnav_dep_a(raw_t *raw) { sat = satno(SYS_GAL, prn); if (sat == 0) { - trace( - 2, "decode_galnav_dep_a: can't work out Galileo sat for PRN %02d\n", prn); + trace(2, "decode_galnav_dep_a: can't work out Galileo sat for PRN %02d\n", prn); return -1; } eph.code = puiTmp[1]; if (!IS_GAL(eph.code)) { - trace( - 2, "decode_galnav_dep_a: unrecognised code %d for E%02d\n", eph.code, prn); + trace(2, "decode_galnav_dep_a: unrecognised code %d for E%02d\n", eph.code, prn); return -1; } @@ -1065,8 +1004,7 @@ static int decode_galnav_dep_a(raw_t *raw) { eph.ttr = raw->time; if (!strstr(raw->opt, "EPHALL")) { - if ((eph.iode == raw->nav.eph[sat - 1].iode) && - (eph.iodc == raw->nav.eph[sat - 1].iodc)) { + if ((eph.iode == raw->nav.eph[sat - 1].iode) && (eph.iodc == raw->nav.eph[sat - 1].iodc)) { return 0; } } @@ -1100,15 +1038,13 @@ static int decode_galnav(raw_t *raw) { sat = satno(SYS_GAL, prn); if (sat == 0) { - trace( - 2, "decode_galnav: can't work out Galileo sat for PRN %02d\n", prn); + trace(2, "decode_galnav: can't work out Galileo sat for PRN %02d\n", prn); return -1; } eph.code = puiTmp[1]; if (!IS_GAL(eph.code)) { - trace( - 2, "decode_galnav: unrecognised code %d for E%02d\n", eph.code, prn); + trace(2, "decode_galnav: unrecognised code %d for E%02d\n", eph.code, prn); return -1; } @@ -1117,8 +1053,7 @@ static int decode_galnav(raw_t *raw) { eph.ttr = raw->time; if (!strstr(raw->opt, "EPHALL")) { - if ((eph.iode == raw->nav.eph[sat - 1].iode) && - (eph.iodc == raw->nav.eph[sat - 1].iodc)) { + if ((eph.iode == raw->nav.eph[sat - 1].iode) && (eph.iodc == raw->nav.eph[sat - 1].iodc)) { return 0; } } @@ -1378,32 +1313,32 @@ static int decode_sbp(raw_t *raw) { switch (type) { case ID_MSGOBS: - return decode_msgobs(raw); + return decode_msgobs(raw); case ID_MSGEPHGPS_DEP_E: return decode_gpsnav_dep_e(raw); case ID_MSGEPHGPS_DEP_F: return decode_gpsnav_dep_f(raw); - case ID_MSGEPHGPS: - return decode_gpsnav(raw); - case ID_MSGEPHBDS: - return decode_bdsnav(raw); + case ID_MSGEPHGPS: + return decode_gpsnav(raw); + case ID_MSGEPHBDS: + return decode_bdsnav(raw); case ID_MSGEPHQZSS: return decode_qzssnav(raw); - case ID_MSGEPHGAL: - return decode_galnav(raw); + case ID_MSGEPHGAL: + return decode_galnav(raw); case ID_MSGEPHGAL_DEP_A: return decode_galnav_dep_a(raw); case ID_MSGEPHGLO_DEP_D: return decode_glonav_dep_d(raw); - case ID_MSGEPHGLO: - return decode_glonav(raw); - case ID_MSGIONGPS: - return decode_gpsion(raw); - case ID_MSG_SBAS_RAW: - return decode_snav(raw); - default: + case ID_MSGEPHGLO: + return decode_glonav(raw); + case ID_MSGIONGPS: + return decode_gpsion(raw); + case ID_MSG_SBAS_RAW: + return decode_snav(raw); + default: trace(3, "decode_sbp: unused frame type=%04x len=%d\n", type, raw->len); - /* there are many more SBF blocks to be extracted */ + /* there are many more SBF blocks to be extracted */ } return 0; } @@ -1496,8 +1431,7 @@ extern int input_sbpf(raw_t *raw, FILE *fp) { /* let's store in raw->buff the whole block of length len */ /* 8 bytes have been already read, we read raw->len-8 more */ - if (fread(raw->buff + 6, 1, raw->len - 6, fp) < (size_t)(raw->len - 6)) - return endfile(raw); + if (fread(raw->buff + 6, 1, raw->len - 6, fp) < (size_t)(raw->len - 6)) return endfile(raw); /* decode SBF block */ stat = decode_sbp(raw); diff --git a/src/rcv/tersus.c b/src/rcv/tersus.c index 372de6958..01287998a 100644 --- a/src/rcv/tersus.c +++ b/src/rcv/tersus.c @@ -1,784 +1,977 @@ /*------------------------------------------------------------------------------ -* tersus.c : Tersus Precis receiver functions -* -* Copyright (C) 2017-2019 by T.TAKASU, All rights reserved. -* -* reference : -* [1] Tersus GNSS Inc., Command & Log Reference For Precis-BX306 & BX316 -* GNSS RTK Board, Version V1.0-20170421 -* -* version : $Revision:$ $Date:$ -* history : 2017/05/26 1.0 new -* 2019/05/10 1.1 save galileo E5b data to obs index 2 -*-----------------------------------------------------------------------------*/ + * tersus.c : Tersus Precis receiver functions + * + * Copyright (C) 2017-2019 by T.TAKASU, All rights reserved. + * + * reference : + * [1] Tersus GNSS Inc., Command & Log Reference For Precis-BX306 & BX316 + * GNSS RTK Board, Version V1.0-20170421 + * + * version : $Revision:$ $Date:$ + * history : 2017/05/26 1.0 new + * 2019/05/10 1.1 save galileo E5b data to obs index 2 + *-----------------------------------------------------------------------------*/ #include "rtklib.h" -#define TERSUSSYNC1 0xAA /* tersus message start sync code 1 */ -#define TERSUSSYNC2 0x44 /* tersus message start sync code 2 */ -#define TERSUSSYNC3 0x12 /* tersus message start sync code 3 */ +#define TERSUSSYNC1 0xAA /* tersus message start sync code 1 */ +#define TERSUSSYNC2 0x44 /* tersus message start sync code 2 */ +#define TERSUSSYNC3 0x12 /* tersus message start sync code 3 */ -#define TERSUSHLEN 28 /* tersus message header length (bytes) */ +#define TERSUSHLEN 28 /* tersus message header length (bytes) */ -#define ID_RANGE 43 /* message id: tersus range measurement */ -#define ID_RANGECMP 140 /* message id: tersus range compressed */ -#define ID_IONUTC 8 /* message id: tersus iono and utc data */ -#define ID_GPSEPHEM 7 /* message id: tersus gps ephemeris */ -#define ID_GLOEPHEMERIS 723 /* message id: tersus glonass ephemeris */ -#define ID_BDSEPHEMERIS 1696 /* message id: tersus beidou ephemeris BX306 */ -#define ID_BD2EPHEM 1047 /* message id: tersus beidou ephemeris BX305 */ +#define ID_RANGE 43 /* message id: tersus range measurement */ +#define ID_RANGECMP 140 /* message id: tersus range compressed */ +#define ID_IONUTC 8 /* message id: tersus iono and utc data */ +#define ID_GPSEPHEM 7 /* message id: tersus gps ephemeris */ +#define ID_GLOEPHEMERIS 723 /* message id: tersus glonass ephemeris */ +#define ID_BDSEPHEMERIS 1696 /* message id: tersus beidou ephemeris BX306 */ +#define ID_BD2EPHEM 1047 /* message id: tersus beidou ephemeris BX305 */ -#define MAXVAL 8388608.0 +#define MAXVAL 8388608.0 -#define OFF_FRQNO -7 /* offset of glonass freq number */ +#define OFF_FRQNO -7 /* offset of glonass freq number */ /* get fields (little-endian) ------------------------------------------------*/ #define U1(p) (*((unsigned char *)(p))) -static unsigned short U2(unsigned char *p) {unsigned short u; memcpy(&u,p,2); return u;} -static unsigned int U4(unsigned char *p) {unsigned int u; memcpy(&u,p,4); return u;} -static int I4(unsigned char *p) {int i; memcpy(&i,p,4); return i;} -static float R4(unsigned char *p) {float r; memcpy(&r,p,4); return r;} -static double R8(unsigned char *p) {double r; memcpy(&r,p,8); return r;} +static unsigned short U2(unsigned char *p) { + unsigned short u; + memcpy(&u, p, 2); + return u; +} +static unsigned int U4(unsigned char *p) { + unsigned int u; + memcpy(&u, p, 4); + return u; +} +static int I4(unsigned char *p) { + int i; + memcpy(&i, p, 4); + return i; +} +static float R4(unsigned char *p) { + float r; + memcpy(&r, p, 4); + return r; +} +static double R8(unsigned char *p) { + double r; + memcpy(&r, p, 8); + return r; +} /* extend sign ---------------------------------------------------------------*/ -static int exsign(unsigned int v, int bits) -{ - return (int)(v&(1<<(bits-1))?v|(~0u<tow_p+302400.0) tow-=604800.0; - return gpst2time(week,tow); +static gtime_t adjweek(gtime_t time, double tow) { + double tow_p; + int week; + tow_p = time2gpst(time, &week); + if (tow < tow_p - 302400.0) + tow += 604800.0; + else if (tow > tow_p + 302400.0) + tow -= 604800.0; + return gpst2time(week, tow); } /* get observation data index ------------------------------------------------*/ -static int obsindex(obs_t *obs, gtime_t time, int sat) -{ - int i,j; - - if (obs->n>=MAXOBS) return -1; - for (i=0;in;i++) { - if (obs->data[i].sat==sat) return i; - } - obs->data[i].time=time; - obs->data[i].sat=sat; - for (j=0;jdata[i].L[j]=obs->data[i].P[j]=0.0; - obs->data[i].D[j]=obs->data[i].SNR[j]=0.0; - obs->data[i].LLI[j]=0; - obs->data[i].code[j]=CODE_NONE; - } - obs->n++; - return i; +static int obsindex(obs_t *obs, gtime_t time, int sat) { + int i, j; + + if (obs->n >= MAXOBS) return -1; + for (i = 0; i < obs->n; i++) { + if (obs->data[i].sat == sat) return i; + } + obs->data[i].time = time; + obs->data[i].sat = sat; + for (j = 0; j < NFREQ + NEXOBS; j++) { + obs->data[i].L[j] = obs->data[i].P[j] = 0.0; + obs->data[i].D[j] = obs->data[i].SNR[j] = 0.0; + obs->data[i].LLI[j] = 0; + obs->data[i].code[j] = CODE_NONE; + } + obs->n++; + return i; } /* decode tersus tracking status ----------------------------------------------- -* deocode tersus tracking status -* args : unsigned int stat I tracking status field -* int *sys O system (SYS_???) -* int *code O signal code (CODE_L??) -* int *track O tracking state -* 0=idle 7=freq-lock loop -* 2=wide freq band pull-in 9=channel alignment -* 3=narrow freq band pull-in 10=code search -* 4=phase lock loop 11=aided phase lock loop -* int *plock O phase-lock flag (0=not locked, 1=locked) -* int *clock O code-lock flag (0=not locked, 1=locked) -* int *parity O parity known flag (0=not known, 1=known) -* int *halfc O phase measurement (0=half-cycle not added, -* 1=added) -* return : signal frequency (0:L1,1:L2,2:L5,3:L6,4:L7,5:L8,-1:error) -*-----------------------------------------------------------------------------*/ -static int decode_trackstat(unsigned int stat, int *sys, int *code, int *track, - int *plock, int *clock, int *parity, int *halfc) -{ - int satsys,sigtype,freq=0; - - *track =stat&0x1F; - *plock =(stat>>10)&1; - *parity=(stat>>11)&1; - *clock =(stat>>12)&1; - satsys =(stat>>16)&7; - *halfc =(stat>>28)&1; - sigtype=(stat>>21)&0x1F; - - switch (satsys) { - case 0: *sys=SYS_GPS; break; - case 1: *sys=SYS_GLO; break; - case 2: *sys=SYS_SBS; break; - case 3: *sys=SYS_GAL; break; - case 4: *sys=SYS_CMP; break; - case 5: *sys=SYS_QZS; break; - default: - trace(2,"tersus unknown system: sys=%d\n",satsys); - return -1; - } - if (*sys==SYS_GPS||*sys==SYS_QZS) { - switch (sigtype) { - case 0: freq=0; *code=CODE_L1C; break; /* L1C/A */ - case 5: freq=0; *code=CODE_L1P; break; /* L1P */ - case 9: freq=1; *code=CODE_L2D; break; /* L2Pcodeless */ - case 14: freq=2; *code=CODE_L5Q; break; /* L5Q */ - case 17: freq=1; *code=CODE_L2X; break; /* L2C(M+L) */ - default: freq=-1; break; - } - } - else if (*sys==SYS_GLO) { - switch (sigtype) { - case 0: freq=0; *code=CODE_L1C; break; /* L1C/A */ - case 1: freq=1; *code=CODE_L2C; break; /* L2C/A (OEM6) */ - case 5: freq=1; *code=CODE_L2P; break; /* L2P */ - default: freq=-1; break; - } - } - else if (*sys==SYS_GAL) { - switch (sigtype) { - case 1: freq=0; *code=CODE_L1B; break; /* E1B */ - case 2: freq=0; *code=CODE_L1C; break; /* E1C */ - case 12: freq=2; *code=CODE_L5Q; break; /* E5aQ */ - case 17: freq=1; *code=CODE_L7Q; break; /* E5bQ */ - case 20: freq=5; *code=CODE_L8Q; break; /* AltBOCQ */ - default: freq=-1; break; - } - } - else if (*sys==SYS_CMP) { - switch (sigtype) { - case 0: freq=0; *code=CODE_L1I; break; /* B1 with D1 */ - case 1: freq=1; *code=CODE_L7I; break; /* B2 with D1 */ - case 4: freq=0; *code=CODE_L1I; break; /* B1 with D2 */ - case 5: freq=1; *code=CODE_L7I; break; /* B2 with D2 */ - case 21: freq=2; *code=CODE_L6I; break; /* B3 */ - default: freq=-1; break; - } - } - else if (*sys==SYS_SBS) { - switch (sigtype) { - case 0: freq=0; *code=CODE_L1C; break; /* L1C/A */ - case 6: freq=2; *code=CODE_L5I; break; /* L5I */ - default: freq=-1; break; - } - } - if (freq<0) { - trace(2,"tersus signal type error: sys=%d sigtype=%d\n",*sys,sigtype); - return -1; - } - return freq; + * deocode tersus tracking status + * args : unsigned int stat I tracking status field + * int *sys O system (SYS_???) + * int *code O signal code (CODE_L??) + * int *track O tracking state + * 0=idle 7=freq-lock loop + * 2=wide freq band pull-in 9=channel alignment + * 3=narrow freq band pull-in 10=code search + * 4=phase lock loop 11=aided phase lock loop + * int *plock O phase-lock flag (0=not locked, 1=locked) + * int *clock O code-lock flag (0=not locked, 1=locked) + * int *parity O parity known flag (0=not known, 1=known) + * int *halfc O phase measurement (0=half-cycle not added, + * 1=added) + * return : signal frequency (0:L1,1:L2,2:L5,3:L6,4:L7,5:L8,-1:error) + *-----------------------------------------------------------------------------*/ +static int decode_trackstat(unsigned int stat, int *sys, int *code, int *track, int *plock, + int *clock, int *parity, int *halfc) { + int satsys, sigtype, freq = 0; + + *track = stat & 0x1F; + *plock = (stat >> 10) & 1; + *parity = (stat >> 11) & 1; + *clock = (stat >> 12) & 1; + satsys = (stat >> 16) & 7; + *halfc = (stat >> 28) & 1; + sigtype = (stat >> 21) & 0x1F; + + switch (satsys) { + case 0: + *sys = SYS_GPS; + break; + case 1: + *sys = SYS_GLO; + break; + case 2: + *sys = SYS_SBS; + break; + case 3: + *sys = SYS_GAL; + break; + case 4: + *sys = SYS_CMP; + break; + case 5: + *sys = SYS_QZS; + break; + default: + trace(2, "tersus unknown system: sys=%d\n", satsys); + return -1; + } + if (*sys == SYS_GPS || *sys == SYS_QZS) { + switch (sigtype) { + case 0: + freq = 0; + *code = CODE_L1C; + break; /* L1C/A */ + case 5: + freq = 0; + *code = CODE_L1P; + break; /* L1P */ + case 9: + freq = 1; + *code = CODE_L2D; + break; /* L2Pcodeless */ + case 14: + freq = 2; + *code = CODE_L5Q; + break; /* L5Q */ + case 17: + freq = 1; + *code = CODE_L2X; + break; /* L2C(M+L) */ + default: + freq = -1; + break; + } + } else if (*sys == SYS_GLO) { + switch (sigtype) { + case 0: + freq = 0; + *code = CODE_L1C; + break; /* L1C/A */ + case 1: + freq = 1; + *code = CODE_L2C; + break; /* L2C/A (OEM6) */ + case 5: + freq = 1; + *code = CODE_L2P; + break; /* L2P */ + default: + freq = -1; + break; + } + } else if (*sys == SYS_GAL) { + switch (sigtype) { + case 1: + freq = 0; + *code = CODE_L1B; + break; /* E1B */ + case 2: + freq = 0; + *code = CODE_L1C; + break; /* E1C */ + case 12: + freq = 2; + *code = CODE_L5Q; + break; /* E5aQ */ + case 17: + freq = 1; + *code = CODE_L7Q; + break; /* E5bQ */ + case 20: + freq = 5; + *code = CODE_L8Q; + break; /* AltBOCQ */ + default: + freq = -1; + break; + } + } else if (*sys == SYS_CMP) { + switch (sigtype) { + case 0: + freq = 0; + *code = CODE_L1I; + break; /* B1 with D1 */ + case 1: + freq = 1; + *code = CODE_L7I; + break; /* B2 with D1 */ + case 4: + freq = 0; + *code = CODE_L1I; + break; /* B1 with D2 */ + case 5: + freq = 1; + *code = CODE_L7I; + break; /* B2 with D2 */ + case 21: + freq = 2; + *code = CODE_L6I; + break; /* B3 */ + default: + freq = -1; + break; + } + } else if (*sys == SYS_SBS) { + switch (sigtype) { + case 0: + freq = 0; + *code = CODE_L1C; + break; /* L1C/A */ + case 6: + freq = 2; + *code = CODE_L5I; + break; /* L5I */ + default: + freq = -1; + break; + } + } + if (freq < 0) { + trace(2, "tersus signal type error: sys=%d sigtype=%d\n", *sys, sigtype); + return -1; + } + return freq; } /* check code priority and return obs position -------------------------------*/ -static int checkpri(const char *opt, int sys, int code, int freq) -{ - int nex=NEXOBS; /* number of extended obs data */ - - if (sys==SYS_GPS) { - if (strstr(opt,"-GL1P")&&freq==0) return code==CODE_L1P?0:-1; - if (strstr(opt,"-GL2X")&&freq==1) return code==CODE_L2X?1:-1; - if (code==CODE_L1P) return nex<1?-1:NFREQ; - if (code==CODE_L2X) return nex<2?-1:NFREQ+1; - } - else if (sys==SYS_GLO) { - if (strstr(opt,"-RL2C")&&freq==1) return code==CODE_L2C?1:-1; - if (code==CODE_L2C) return nex<1?-1:NFREQ; - } - else if (sys==SYS_GAL) { - if (strstr(opt,"-EL1B")&&freq==0) return code==CODE_L1B?0:-1; - if (code==CODE_L1B) return nex<1?-1:NFREQ; - if (code==CODE_L8Q) return nex<3?-1:NFREQ+2; - } - return freqbuff+TERSUSHLEN; - - trace(3,"decode_rangeb: len=%d\n",raw->len); - - nobs=U4(p); - - if (raw->outtype) { - msg=raw->msgtype+strlen(raw->msgtype); - sprintf(msg," nobs=%2d",nobs); - } - if (raw->lenlen,nobs); - return -1; - } - for (i=0,p+=4;iopt,sys,code,freq))<0) continue; - - prn=U2(p); - if (sys==SYS_GLO) prn-=37; - else if (sys==SYS_CMP) prn-=160; - - if (!(sat=satno(sys,prn))) { - trace(3,"tersus rangeb satellite number error: sys=%d,prn=%d\n",sys,prn); - continue; - } - if (sys==SYS_GLO&&!parity) continue; /* invalid if GLO parity unknown */ - - gfrq =U2(p+ 2); - psr =R8(p+ 4); - adr =R8(p+16); - dop =R4(p+28); - snr =R4(p+32); - lockt=R4(p+36); - - /* set glonass frequency channel number */ - if (sys==SYS_GLO&&raw->nav.geph[prn-1].sat!=sat) { - raw->nav.geph[prn-1].frq=gfrq-7; - } - if (raw->tobs[sat-1][pos].time!=0) { - tt=timediff(raw->time,raw->tobs[sat-1][pos]); - lli=lockt-raw->lockt[sat-1][pos]+0.05<=tt?LLI_SLIP:0; - } - else { - lli=0; - } - if (!parity) lli|=LLI_HALFC; - if (halfc ) lli|=LLI_HALFA; - raw->tobs [sat-1][pos]=raw->time; - raw->lockt[sat-1][pos]=lockt; - raw->halfc[sat-1][pos]=halfc; - - if (!clock) psr=0.0; /* code unlock */ - if (!plock) adr=dop=0.0; /* phase unlock */ - - if (fabs(timediff(raw->obs.data[0].time,raw->time))>1E-9) { - raw->obs.n=0; - } - if ((index=obsindex(&raw->obs,raw->time,sat))>=0) { - raw->obs.data[index].L [pos]=-adr; - raw->obs.data[index].P [pos]=psr; - raw->obs.data[index].D [pos]=(float)dop; - raw->obs.data[index].SNR[pos]=0.0<=snr&&snr<255.0?snr:0; - raw->obs.data[index].LLI[pos]=(unsigned char)lli; - raw->obs.data[index].code[pos]=code; - } +static int decode_rangeb(raw_t *raw) { + double psr, adr, dop, snr, lockt, tt; + char *msg; + int i, index, nobs, prn, sat, sys, code, freq, pos; + int track, plock, clock, parity, halfc, lli, gfrq; + unsigned char *p = raw->buff + TERSUSHLEN; + + trace(3, "decode_rangeb: len=%d\n", raw->len); + + nobs = U4(p); + + if (raw->outtype) { + msg = raw->msgtype + strlen(raw->msgtype); + sprintf(msg, " nobs=%2d", nobs); + } + if (raw->len < TERSUSHLEN + 4 + nobs * 44) { + trace(2, "tersus rangeb length error: len=%d nobs=%d\n", raw->len, nobs); + return -1; + } + for (i = 0, p += 4; i < nobs; i++, p += 44) { + /* decode tracking status */ + if ((freq = decode_trackstat(U4(p + 40), &sys, &code, &track, &plock, &clock, &parity, + &halfc)) < 0) + continue; + + /* obs position */ + if ((pos = checkpri(raw->opt, sys, code, freq)) < 0) continue; + + prn = U2(p); + if (sys == SYS_GLO) + prn -= 37; + else if (sys == SYS_CMP) + prn -= 160; + + if (!(sat = satno(sys, prn))) { + trace(3, "tersus rangeb satellite number error: sys=%d,prn=%d\n", sys, prn); + continue; } - return 1; + if (sys == SYS_GLO && !parity) continue; /* invalid if GLO parity unknown */ + + gfrq = U2(p + 2); + psr = R8(p + 4); + adr = R8(p + 16); + dop = R4(p + 28); + snr = R4(p + 32); + lockt = R4(p + 36); + + /* set glonass frequency channel number */ + if (sys == SYS_GLO && raw->nav.geph[prn - 1].sat != sat) { + raw->nav.geph[prn - 1].frq = gfrq - 7; + } + if (raw->tobs[sat - 1][pos].time != 0) { + tt = timediff(raw->time, raw->tobs[sat - 1][pos]); + lli = lockt - raw->lockt[sat - 1][pos] + 0.05 <= tt ? LLI_SLIP : 0; + } else { + lli = 0; + } + if (!parity) lli |= LLI_HALFC; + if (halfc) lli |= LLI_HALFA; + raw->tobs[sat - 1][pos] = raw->time; + raw->lockt[sat - 1][pos] = lockt; + raw->halfc[sat - 1][pos] = halfc; + + if (!clock) psr = 0.0; /* code unlock */ + if (!plock) adr = dop = 0.0; /* phase unlock */ + + if (fabs(timediff(raw->obs.data[0].time, raw->time)) > 1E-9) { + raw->obs.n = 0; + } + if ((index = obsindex(&raw->obs, raw->time, sat)) >= 0) { + raw->obs.data[index].L[pos] = -adr; + raw->obs.data[index].P[pos] = psr; + raw->obs.data[index].D[pos] = (float)dop; + raw->obs.data[index].SNR[pos] = 0.0 <= snr && snr < 255.0 ? snr : 0; + raw->obs.data[index].LLI[pos] = (unsigned char)lli; + raw->obs.data[index].code[pos] = code; + } + } + return 1; } /* decode rangecmpb ----------------------------------------------------------*/ -static int decode_rangecmpb(raw_t *raw) -{ - double psr,adr,adr_rolls,lockt,tt,dop,snr,wavelen; - int i,index,nobs,prn,sat,sys,code,freq,pos; - int track,plock,clock,parity,halfc,lli; - char *msg; - unsigned char *p=raw->buff+TERSUSHLEN; - - trace(3,"decode_rangecmpb: len=%d\n",raw->len); - - nobs=U4(p); - - if (raw->outtype) { - msg=raw->msgtype+strlen(raw->msgtype); - sprintf(msg," nobs=%2d",nobs); +static int decode_rangecmpb(raw_t *raw) { + double psr, adr, adr_rolls, lockt, tt, dop, snr, wavelen; + int i, index, nobs, prn, sat, sys, code, freq, pos; + int track, plock, clock, parity, halfc, lli; + char *msg; + unsigned char *p = raw->buff + TERSUSHLEN; + + trace(3, "decode_rangecmpb: len=%d\n", raw->len); + + nobs = U4(p); + + if (raw->outtype) { + msg = raw->msgtype + strlen(raw->msgtype); + sprintf(msg, " nobs=%2d", nobs); + } + if (raw->len < TERSUSHLEN + 4 + nobs * 24) { + trace(2, "tersus rangecmpb length error: len=%d nobs=%d\n", raw->len, nobs); + return -1; + } + for (i = 0, p += 4; i < nobs; i++, p += 24) { + /* decode tracking status */ + if ((freq = decode_trackstat(U4(p), &sys, &code, &track, &plock, &clock, &parity, &halfc)) < 0) + continue; + + /* obs position */ + if ((pos = checkpri(raw->opt, sys, code, freq)) < 0) continue; + + prn = U1(p + 17); + if (sys == SYS_GLO) + prn -= 37; + else if (sys == SYS_CMP) + prn -= 160; + + if (!(sat = satno(sys, prn))) { + trace(3, "tersus rangecmpb satellite number error: sys=%d,prn=%d\n", sys, prn); + continue; + } + if (sys == SYS_GLO && !parity) continue; /* invalid if GLO parity unknown */ + + dop = exsign(U4(p + 4) & 0xFFFFFFF, 28) / 256.0; + psr = (U4(p + 7) >> 4) / 128.0 + U1(p + 11) * 2097152.0; + + if ((wavelen = satwavelen(sat, freq, &raw->nav)) <= 0.0) { + if (sys == SYS_GLO) + wavelen = CLIGHT / (freq == 0 ? FREQ1_GLO : FREQ2_GLO); + else + wavelen = lam_carr[freq]; + } + adr = I4(p + 12) / 256.0; + adr_rolls = (psr / wavelen + adr) / MAXVAL; + adr = -adr + MAXVAL * floor(adr_rolls + (adr_rolls <= 0 ? -0.5 : 0.5)); + + lockt = (U4(p + 18) & 0x1FFFFF) / 32.0; /* lock time */ + + if (raw->tobs[sat - 1][pos].time != 0) { + tt = timediff(raw->time, raw->tobs[sat - 1][pos]); + lli = (lockt < 65535.968 && lockt - raw->lockt[sat - 1][pos] + 0.05 <= tt) ? LLI_SLIP : 0; + } else { + lli = 0; + } + if (!parity) lli |= LLI_HALFC; + if (halfc) lli |= LLI_HALFA; + raw->tobs[sat - 1][pos] = raw->time; + raw->lockt[sat - 1][pos] = lockt; + raw->halfc[sat - 1][pos] = halfc; + + snr = ((U2(p + 20) & 0x3FF) >> 5) + 20.0; + if (!clock) psr = 0.0; /* code unlock */ + if (!plock) adr = dop = 0.0; /* phase unlock */ + + if (fabs(timediff(raw->obs.data[0].time, raw->time)) > 1E-9) { + raw->obs.n = 0; } - if (raw->lenlen,nobs); - return -1; + if ((index = obsindex(&raw->obs, raw->time, sat)) >= 0) { + raw->obs.data[index].L[pos] = adr; + raw->obs.data[index].P[pos] = psr; + raw->obs.data[index].D[pos] = (float)dop; + raw->obs.data[index].SNR[pos] = 0.0 <= snr && snr < 255.0 ? snr : 0; + raw->obs.data[index].LLI[pos] = (unsigned char)lli; + raw->obs.data[index].code[pos] = code; } - for (i=0,p+=4;iopt,sys,code,freq))<0) continue; - - prn=U1(p+17); - if (sys==SYS_GLO) prn-=37; - else if (sys==SYS_CMP) prn-=160; - - if (!(sat=satno(sys,prn))) { - trace(3,"tersus rangecmpb satellite number error: sys=%d,prn=%d\n",sys,prn); - continue; - } - if (sys==SYS_GLO&&!parity) continue; /* invalid if GLO parity unknown */ - - dop=exsign(U4(p+4)&0xFFFFFFF,28)/256.0; - psr=(U4(p+7)>>4)/128.0+U1(p+11)*2097152.0; - - if ((wavelen=satwavelen(sat,freq,&raw->nav))<=0.0) { - if (sys==SYS_GLO) wavelen=CLIGHT/(freq==0?FREQ1_GLO:FREQ2_GLO); - else wavelen=lam_carr[freq]; - } - adr=I4(p+12)/256.0; - adr_rolls=(psr/wavelen+adr)/MAXVAL; - adr=-adr+MAXVAL*floor(adr_rolls+(adr_rolls<=0?-0.5:0.5)); - - lockt=(U4(p+18)&0x1FFFFF)/32.0; /* lock time */ - - if (raw->tobs[sat-1][pos].time!=0) { - tt=timediff(raw->time,raw->tobs[sat-1][pos]); - lli=(lockt<65535.968&&lockt-raw->lockt[sat-1][pos]+0.05<=tt)?LLI_SLIP:0; - } - else { - lli=0; - } - if (!parity) lli|=LLI_HALFC; - if (halfc ) lli|=LLI_HALFA; - raw->tobs [sat-1][pos]=raw->time; - raw->lockt[sat-1][pos]=lockt; - raw->halfc[sat-1][pos]=halfc; - - snr=((U2(p+20)&0x3FF)>>5)+20.0; - if (!clock) psr=0.0; /* code unlock */ - if (!plock) adr=dop=0.0; /* phase unlock */ - - if (fabs(timediff(raw->obs.data[0].time,raw->time))>1E-9) { - raw->obs.n=0; - } - if ((index=obsindex(&raw->obs,raw->time,sat))>=0) { - raw->obs.data[index].L [pos]=adr; - raw->obs.data[index].P [pos]=psr; - raw->obs.data[index].D [pos]=(float)dop; - raw->obs.data[index].SNR[pos]=0.0<=snr&&snr<255.0?snr:0; - raw->obs.data[index].LLI[pos]=(unsigned char)lli; - raw->obs.data[index].code[pos]=code; - } #ifdef RTK_DISABLED /* for debug */ - char tstr[40]; - trace(3,"sys=%d prn=%3d cp=%12.5f lli=%2d plock=%2d clock=%2d lockt=%4.2f halfc=%2d parity=%2d ts=%s\n", - sys,prn,adr,lli,plock,clock,lockt,halfc,parity,time2str(raw->tobs,tstr,3)); + char tstr[40]; + trace(3, + "sys=%d prn=%3d cp=%12.5f lli=%2d plock=%2d clock=%2d lockt=%4.2f halfc=%2d parity=%2d " + "ts=%s\n", + sys, prn, adr, lli, plock, clock, lockt, halfc, parity, time2str(raw->tobs, tstr, 3)); #endif - - } - return 1; + } + return 1; } /* decode gpsphemb -----------------------------------------------------------*/ -static int decode_gpsephemb(raw_t *raw) -{ - unsigned char *p=raw->buff+TERSUSHLEN; - eph_t eph={0}; - char *msg; - double tow,toc,n,ura,tt; - int prn,week,zweek,iode2,as; - - trace(3,"decode_gpsephemb: len=%d\n",raw->len); - - if (raw->lenlen); - return -1; - } - prn =U2(p); p+=4; - - if (raw->outtype) { - msg=raw->msgtype+strlen(raw->msgtype); - sprintf(msg," prn=%3d",prn); - } - if (!(eph.sat=satno(SYS_GPS,prn))) { - trace(2,"tersus gpsephemb prn error: prn=%d\n",prn); - return -1; - } - tow =R8(p); p+=8; - eph.svh =(int)U4(p); p+=4; - eph.iode =(int)U4(p); p+=4; - iode2 =(int)U4(p); p+=4; - week =(int)U4(p); p+=4; - zweek =U4(p); p+=4; - eph.toes =R8(p); p+=8; - eph.A =R8(p); p+=8; - eph.deln =R8(p); p+=8; - eph.M0 =R8(p); p+=8; - eph.e =R8(p); p+=8; - eph.omg =R8(p); p+=8; - eph.cuc =R8(p); p+=8; - eph.cus =R8(p); p+=8; - eph.crc =R8(p); p+=8; - eph.crs =R8(p); p+=8; - eph.cic =R8(p); p+=8; - eph.cis =R8(p); p+=8; - eph.i0 =R8(p); p+=8; - eph.idot =R8(p); p+=8; - eph.OMG0 =R8(p); p+=8; - eph.OMGd =R8(p); p+=8; - eph.iodc =(int)U4(p); p+=4; - toc =R8(p); p+=8; - eph.tgd[0] =R8(p); p+=8; - eph.f0 =R8(p); p+=8; - eph.f1 =R8(p); p+=8; - eph.f2 =R8(p); p+=8; - as =(int)U4(p); p+=4; /* AS-ON */ - n =R8(p); p+=8; - ura =R8(p); p+=8; - - if (eph.iode!=iode2) { - trace(2,"tersus gpsephemb iode error: iode=%d %d\n",eph.iode,iode2); - return -1; - } - eph.week=adjgpsweek(week); - eph.toe=gpst2time(eph.week,eph.toes); - tt=timediff(eph.toe,raw->time); - if (tt<-302400.0) eph.week++; - else if (tt> 302400.0) eph.week--; - eph.toe=gpst2time(eph.week,eph.toes); - eph.toc=gpst2time(eph.week,toc); - eph.ttr=adjweek(eph.toe,tow); - eph.sva=uraindex(ura); - - if (!strstr(raw->opt,"-EPHALL")) { - if (timediff(raw->nav.eph[eph.sat-1].toe,eph.toe)==0.0&& - raw->nav.eph[eph.sat-1].iode==eph.iode&& - raw->nav.eph[eph.sat-1].iodc==eph.iodc) return 0; /* unchanged */ - } - raw->nav.eph[eph.sat-1]=eph; - raw->ephsat=eph.sat; - return 2; +static int decode_gpsephemb(raw_t *raw) { + unsigned char *p = raw->buff + TERSUSHLEN; + eph_t eph = {0}; + char *msg; + double tow, toc, n, ura, tt; + int prn, week, zweek, iode2, as; + + trace(3, "decode_gpsephemb: len=%d\n", raw->len); + + if (raw->len < TERSUSHLEN + 224) { + trace(2, "tersus gpsephemb length error: len=%d\n", raw->len); + return -1; + } + prn = U2(p); + p += 4; + + if (raw->outtype) { + msg = raw->msgtype + strlen(raw->msgtype); + sprintf(msg, " prn=%3d", prn); + } + if (!(eph.sat = satno(SYS_GPS, prn))) { + trace(2, "tersus gpsephemb prn error: prn=%d\n", prn); + return -1; + } + tow = R8(p); + p += 8; + eph.svh = (int)U4(p); + p += 4; + eph.iode = (int)U4(p); + p += 4; + iode2 = (int)U4(p); + p += 4; + week = (int)U4(p); + p += 4; + zweek = U4(p); + p += 4; + eph.toes = R8(p); + p += 8; + eph.A = R8(p); + p += 8; + eph.deln = R8(p); + p += 8; + eph.M0 = R8(p); + p += 8; + eph.e = R8(p); + p += 8; + eph.omg = R8(p); + p += 8; + eph.cuc = R8(p); + p += 8; + eph.cus = R8(p); + p += 8; + eph.crc = R8(p); + p += 8; + eph.crs = R8(p); + p += 8; + eph.cic = R8(p); + p += 8; + eph.cis = R8(p); + p += 8; + eph.i0 = R8(p); + p += 8; + eph.idot = R8(p); + p += 8; + eph.OMG0 = R8(p); + p += 8; + eph.OMGd = R8(p); + p += 8; + eph.iodc = (int)U4(p); + p += 4; + toc = R8(p); + p += 8; + eph.tgd[0] = R8(p); + p += 8; + eph.f0 = R8(p); + p += 8; + eph.f1 = R8(p); + p += 8; + eph.f2 = R8(p); + p += 8; + as = (int)U4(p); + p += 4; /* AS-ON */ + n = R8(p); + p += 8; + ura = R8(p); + p += 8; + + if (eph.iode != iode2) { + trace(2, "tersus gpsephemb iode error: iode=%d %d\n", eph.iode, iode2); + return -1; + } + eph.week = adjgpsweek(week); + eph.toe = gpst2time(eph.week, eph.toes); + tt = timediff(eph.toe, raw->time); + if (tt < -302400.0) + eph.week++; + else if (tt > 302400.0) + eph.week--; + eph.toe = gpst2time(eph.week, eph.toes); + eph.toc = gpst2time(eph.week, toc); + eph.ttr = adjweek(eph.toe, tow); + eph.sva = uraindex(ura); + + if (!strstr(raw->opt, "-EPHALL")) { + if (timediff(raw->nav.eph[eph.sat - 1].toe, eph.toe) == 0.0 && + raw->nav.eph[eph.sat - 1].iode == eph.iode && raw->nav.eph[eph.sat - 1].iodc == eph.iodc) + return 0; /* unchanged */ + } + raw->nav.eph[eph.sat - 1] = eph; + raw->ephsat = eph.sat; + return 2; } /* decode gloephemerisb ------------------------------------------------------*/ -static int decode_gloephemerisb(raw_t *raw) -{ - unsigned char *p=raw->buff+TERSUSHLEN; - geph_t geph={0}; - char *msg; - double tow,tof,toff; - int prn,sat,week; - - trace(3,"decode_gloephemerisb: len=%d\n",raw->len); - - if (raw->lenlen); - return -1; - } - prn =U2(p)-37; - - if (raw->outtype) { - msg=raw->msgtype+strlen(raw->msgtype); - sprintf(msg," prn=%3d",prn); - } - if (!(sat=satno(SYS_GLO,prn))) { - trace(2,"tersus gloephemerisb prn error: prn=%d\n",prn); - return -1; - } - geph.frq =U2(p+ 2)+OFF_FRQNO; - week =U2(p+ 6); - tow =floor(U4(p+8)/1000.0+0.5); /* rounded to integer sec */ - toff =U4(p+ 12); - geph.iode =U4(p+ 20)&0x7F; - geph.svh =U4(p+ 24); - geph.pos[0]=R8(p+ 28); - geph.pos[1]=R8(p+ 36); - geph.pos[2]=R8(p+ 44); - geph.vel[0]=R8(p+ 52); - geph.vel[1]=R8(p+ 60); - geph.vel[2]=R8(p+ 68); - geph.acc[0]=R8(p+ 76); - geph.acc[1]=R8(p+ 84); - geph.acc[2]=R8(p+ 92); - geph.taun =R8(p+100); - geph.gamn =R8(p+116); - tof =U4(p+124)-toff; /* glonasst->gpst */ - geph.age =U4(p+136); - geph.toe=gpst2time(week,tow); - tof+=floor(tow/86400.0)*86400; - if (toftow+43200.0) tof-=86400.0; - geph.tof=gpst2time(week,tof); - - if (!strstr(raw->opt,"-EPHALL")) { - if (fabs(timediff(geph.toe,raw->nav.geph[prn-1].toe))<1.0&& - geph.svh==raw->nav.geph[prn-1].svh) return 0; /* unchanged */ - } - geph.sat=sat; - raw->nav.geph[prn-1]=geph; - raw->ephsat=sat; - return 2; +static int decode_gloephemerisb(raw_t *raw) { + unsigned char *p = raw->buff + TERSUSHLEN; + geph_t geph = {0}; + char *msg; + double tow, tof, toff; + int prn, sat, week; + + trace(3, "decode_gloephemerisb: len=%d\n", raw->len); + + if (raw->len < TERSUSHLEN + 144) { + trace(2, "tersus gloephemerisb length error: len=%d\n", raw->len); + return -1; + } + prn = U2(p) - 37; + + if (raw->outtype) { + msg = raw->msgtype + strlen(raw->msgtype); + sprintf(msg, " prn=%3d", prn); + } + if (!(sat = satno(SYS_GLO, prn))) { + trace(2, "tersus gloephemerisb prn error: prn=%d\n", prn); + return -1; + } + geph.frq = U2(p + 2) + OFF_FRQNO; + week = U2(p + 6); + tow = floor(U4(p + 8) / 1000.0 + 0.5); /* rounded to integer sec */ + toff = U4(p + 12); + geph.iode = U4(p + 20) & 0x7F; + geph.svh = U4(p + 24); + geph.pos[0] = R8(p + 28); + geph.pos[1] = R8(p + 36); + geph.pos[2] = R8(p + 44); + geph.vel[0] = R8(p + 52); + geph.vel[1] = R8(p + 60); + geph.vel[2] = R8(p + 68); + geph.acc[0] = R8(p + 76); + geph.acc[1] = R8(p + 84); + geph.acc[2] = R8(p + 92); + geph.taun = R8(p + 100); + geph.gamn = R8(p + 116); + tof = U4(p + 124) - toff; /* glonasst->gpst */ + geph.age = U4(p + 136); + geph.toe = gpst2time(week, tow); + tof += floor(tow / 86400.0) * 86400; + if (tof < tow - 43200.0) + tof += 86400.0; + else if (tof > tow + 43200.0) + tof -= 86400.0; + geph.tof = gpst2time(week, tof); + + if (!strstr(raw->opt, "-EPHALL")) { + if (fabs(timediff(geph.toe, raw->nav.geph[prn - 1].toe)) < 1.0 && + geph.svh == raw->nav.geph[prn - 1].svh) + return 0; /* unchanged */ + } + geph.sat = sat; + raw->nav.geph[prn - 1] = geph; + raw->ephsat = sat; + return 2; } /* decode bdsephemeris -------------------------------------------------------*/ -static int decode_bdsephemerisb(raw_t *raw) -{ - eph_t eph={0}; - unsigned char *p=raw->buff+TERSUSHLEN; - double ura,sqrtA; - char *msg; - int prn,toc; - - trace(3,"decode_bdsephemerisb: len=%d\n",raw->len); - - if (raw->lenlen); - return -1; - } - prn =U4(p)-160; p+=4; - eph.week =U4(p); p+=4; - ura =R8(p); p+=8; - eph.svh =U4(p)&1; p+=4; - eph.tgd[0]=R8(p); p+=8; /* TGD1 for B1 (s) */ - eph.tgd[1]=R8(p); p+=8; /* TGD2 for B2 (s) */ - eph.iodc =U4(p); p+=4; /* AODC */ - toc =U4(p); p+=4; - eph.f0 =R8(p); p+=8; - eph.f1 =R8(p); p+=8; - eph.f2 =R8(p); p+=8; - eph.iode =U4(p); p+=4; /* AODE */ - eph.toes =U4(p); p+=4; - sqrtA =R8(p); p+=8; - eph.e =R8(p); p+=8; - eph.omg =R8(p); p+=8; - eph.deln =R8(p); p+=8; - eph.M0 =R8(p); p+=8; - eph.OMG0 =R8(p); p+=8; - eph.OMGd =R8(p); p+=8; - eph.i0 =R8(p); p+=8; - eph.idot =R8(p); p+=8; - eph.cuc =R8(p); p+=8; - eph.cus =R8(p); p+=8; - eph.crc =R8(p); p+=8; - eph.crs =R8(p); p+=8; - eph.cic =R8(p); p+=8; - eph.cis =R8(p); - eph.A =sqrtA*sqrtA; - eph.sva =uraindex(ura); - - if (raw->outtype) { - msg=raw->msgtype+strlen(raw->msgtype); - sprintf(msg," prn=%3d iod=%3d toes=%6.0f",prn,eph.iode,eph.toes); - } - if (!(eph.sat=satno(SYS_CMP,prn))) { - trace(2,"tersus bdsephemeris satellite error: prn=%d\n",prn); - return -1; - } - eph.toe=bdt2gpst(bdt2time(eph.week,eph.toes)); /* bdt -> gpst */ - eph.toc=bdt2gpst(bdt2time(eph.week,toc)); /* bdt -> gpst */ - eph.ttr=raw->time; - - if (!strstr(raw->opt,"-EPHALL")) { - if (timediff(raw->nav.eph[eph.sat-1].toe,eph.toe)==0.0&& - raw->nav.eph[eph.sat-1].iode==eph.iode&& - raw->nav.eph[eph.sat-1].iodc==eph.iodc) return 0; /* unchanged */ - } - raw->nav.eph[eph.sat-1]=eph; - raw->ephsat=eph.sat; - return 2; +static int decode_bdsephemerisb(raw_t *raw) { + eph_t eph = {0}; + unsigned char *p = raw->buff + TERSUSHLEN; + double ura, sqrtA; + char *msg; + int prn, toc; + + trace(3, "decode_bdsephemerisb: len=%d\n", raw->len); + + if (raw->len < TERSUSHLEN + 196) { + trace(2, "tersus bdsephemrisb length error: len=%d\n", raw->len); + return -1; + } + prn = U4(p) - 160; + p += 4; + eph.week = U4(p); + p += 4; + ura = R8(p); + p += 8; + eph.svh = U4(p) & 1; + p += 4; + eph.tgd[0] = R8(p); + p += 8; /* TGD1 for B1 (s) */ + eph.tgd[1] = R8(p); + p += 8; /* TGD2 for B2 (s) */ + eph.iodc = U4(p); + p += 4; /* AODC */ + toc = U4(p); + p += 4; + eph.f0 = R8(p); + p += 8; + eph.f1 = R8(p); + p += 8; + eph.f2 = R8(p); + p += 8; + eph.iode = U4(p); + p += 4; /* AODE */ + eph.toes = U4(p); + p += 4; + sqrtA = R8(p); + p += 8; + eph.e = R8(p); + p += 8; + eph.omg = R8(p); + p += 8; + eph.deln = R8(p); + p += 8; + eph.M0 = R8(p); + p += 8; + eph.OMG0 = R8(p); + p += 8; + eph.OMGd = R8(p); + p += 8; + eph.i0 = R8(p); + p += 8; + eph.idot = R8(p); + p += 8; + eph.cuc = R8(p); + p += 8; + eph.cus = R8(p); + p += 8; + eph.crc = R8(p); + p += 8; + eph.crs = R8(p); + p += 8; + eph.cic = R8(p); + p += 8; + eph.cis = R8(p); + eph.A = sqrtA * sqrtA; + eph.sva = uraindex(ura); + + if (raw->outtype) { + msg = raw->msgtype + strlen(raw->msgtype); + sprintf(msg, " prn=%3d iod=%3d toes=%6.0f", prn, eph.iode, eph.toes); + } + if (!(eph.sat = satno(SYS_CMP, prn))) { + trace(2, "tersus bdsephemeris satellite error: prn=%d\n", prn); + return -1; + } + eph.toe = bdt2gpst(bdt2time(eph.week, eph.toes)); /* bdt -> gpst */ + eph.toc = bdt2gpst(bdt2time(eph.week, toc)); /* bdt -> gpst */ + eph.ttr = raw->time; + + if (!strstr(raw->opt, "-EPHALL")) { + if (timediff(raw->nav.eph[eph.sat - 1].toe, eph.toe) == 0.0 && + raw->nav.eph[eph.sat - 1].iode == eph.iode && raw->nav.eph[eph.sat - 1].iodc == eph.iodc) + return 0; /* unchanged */ + } + raw->nav.eph[eph.sat - 1] = eph; + raw->ephsat = eph.sat; + return 2; } /* decode bd2ephemb ----------------------------------------------------------*/ -static int decode_bd2ephemb(raw_t *raw) -{ - unsigned char *p=raw->buff+TERSUSHLEN; - eph_t eph={0}; - char *msg; - double tow,toc,n,ura,tt; - int prn,week,zweek,iode2,as; - - trace(3,"decode_bd2ephemb: len=%d\n",raw->len); - - if (raw->lenlen); - return -1; - } - prn =U2(p); p+=4; +static int decode_bd2ephemb(raw_t *raw) { + unsigned char *p = raw->buff + TERSUSHLEN; + eph_t eph = {0}; + char *msg; + double tow, toc, n, ura, tt; + int prn, week, zweek, iode2, as; - if (raw->outtype) { - msg=raw->msgtype+strlen(raw->msgtype); - sprintf(msg," prn=%3d",prn); - } + trace(3, "decode_bd2ephemb: len=%d\n", raw->len); - if (!(eph.sat=satno(SYS_CMP,prn))) { - trace(2,"tersus bd2ephemb prn error: prn=%d\n",prn); - return -1; - } + if (raw->len < TERSUSHLEN + 232) { + trace(2, "tersus bd2ephemb length error: len=%d\n", raw->len); + return -1; + } + prn = U2(p); + p += 4; - tow =R8(p); p+=8; - eph.svh =(int)U4(p); p+=4; - eph.iode =(int)U4(p); p+=4; - iode2 =(int)U4(p); p+=4; - week =(int)U4(p); p+=4; - zweek =U4(p); p+=4; - eph.toes =R8(p); p+=8; - eph.A =R8(p); p+=8; - eph.deln =R8(p); p+=8; - eph.M0 =R8(p); p+=8; - eph.e =R8(p); p+=8; - eph.omg =R8(p); p+=8; - eph.cuc =R8(p); p+=8; - eph.cus =R8(p); p+=8; - eph.crc =R8(p); p+=8; - eph.crs =R8(p); p+=8; - eph.cic =R8(p); p+=8; - eph.cis =R8(p); p+=8; - eph.i0 =R8(p); p+=8; - eph.idot =R8(p); p+=8; - eph.OMG0 =R8(p); p+=8; - eph.OMGd =R8(p); p+=8; - eph.iodc =(int)U4(p); p+=4; - toc =R8(p); p+=8; - eph.tgd[0] =R8(p); p+=8; - eph.tgd[1] =R8(p); p+=8; - eph.f0 =R8(p); p+=8; - eph.f1 =R8(p); p+=8; - eph.f2 =R8(p); p+=8; - as =(int)U4(p); p+=4; /* AS-ON */ - n =R8(p); p+=8; - ura =R8(p); p+=8; - - - if (eph.iode!=iode2) { - trace(2,"tersus bd2ephemb iode error: iode=%d %d\n",eph.iode,iode2); - return -1; - } - eph.week=adjgpsweek(week); - eph.toe=gpst2time(eph.week,eph.toes); - tt=timediff(eph.toe,raw->time); - if (tt<-302400.0) eph.week++; - else if (tt> 302400.0) eph.week--; - eph.toe=gpst2time(eph.week,eph.toes); - eph.toc=gpst2time(eph.week,toc); - eph.ttr=adjweek(eph.toe,tow); - eph.sva=uraindex(ura); - - if (!strstr(raw->opt,"-EPHALL")) { - if (timediff(raw->nav.eph[eph.sat-1].toe,eph.toe)==0.0&& - raw->nav.eph[eph.sat-1].iode==eph.iode&& - raw->nav.eph[eph.sat-1].iodc==eph.iodc) return 0; /* unchanged */ - } - raw->nav.eph[eph.sat-1]=eph; - raw->ephsat=eph.sat; - return 2; + if (raw->outtype) { + msg = raw->msgtype + strlen(raw->msgtype); + sprintf(msg, " prn=%3d", prn); + } + + if (!(eph.sat = satno(SYS_CMP, prn))) { + trace(2, "tersus bd2ephemb prn error: prn=%d\n", prn); + return -1; + } + + tow = R8(p); + p += 8; + eph.svh = (int)U4(p); + p += 4; + eph.iode = (int)U4(p); + p += 4; + iode2 = (int)U4(p); + p += 4; + week = (int)U4(p); + p += 4; + zweek = U4(p); + p += 4; + eph.toes = R8(p); + p += 8; + eph.A = R8(p); + p += 8; + eph.deln = R8(p); + p += 8; + eph.M0 = R8(p); + p += 8; + eph.e = R8(p); + p += 8; + eph.omg = R8(p); + p += 8; + eph.cuc = R8(p); + p += 8; + eph.cus = R8(p); + p += 8; + eph.crc = R8(p); + p += 8; + eph.crs = R8(p); + p += 8; + eph.cic = R8(p); + p += 8; + eph.cis = R8(p); + p += 8; + eph.i0 = R8(p); + p += 8; + eph.idot = R8(p); + p += 8; + eph.OMG0 = R8(p); + p += 8; + eph.OMGd = R8(p); + p += 8; + eph.iodc = (int)U4(p); + p += 4; + toc = R8(p); + p += 8; + eph.tgd[0] = R8(p); + p += 8; + eph.tgd[1] = R8(p); + p += 8; + eph.f0 = R8(p); + p += 8; + eph.f1 = R8(p); + p += 8; + eph.f2 = R8(p); + p += 8; + as = (int)U4(p); + p += 4; /* AS-ON */ + n = R8(p); + p += 8; + ura = R8(p); + p += 8; + + if (eph.iode != iode2) { + trace(2, "tersus bd2ephemb iode error: iode=%d %d\n", eph.iode, iode2); + return -1; + } + eph.week = adjgpsweek(week); + eph.toe = gpst2time(eph.week, eph.toes); + tt = timediff(eph.toe, raw->time); + if (tt < -302400.0) + eph.week++; + else if (tt > 302400.0) + eph.week--; + eph.toe = gpst2time(eph.week, eph.toes); + eph.toc = gpst2time(eph.week, toc); + eph.ttr = adjweek(eph.toe, tow); + eph.sva = uraindex(ura); + + if (!strstr(raw->opt, "-EPHALL")) { + if (timediff(raw->nav.eph[eph.sat - 1].toe, eph.toe) == 0.0 && + raw->nav.eph[eph.sat - 1].iode == eph.iode && raw->nav.eph[eph.sat - 1].iodc == eph.iodc) + return 0; /* unchanged */ + } + raw->nav.eph[eph.sat - 1] = eph; + raw->ephsat = eph.sat; + return 2; } /* decode ionutcb ------------------------------------------------------------*/ -static int decode_ionutcb(raw_t *raw) -{ - unsigned char *p=raw->buff+TERSUSHLEN; - int i; - - trace(3,"decode_ionutcb: len=%d\n",raw->len); - - if (raw->lenlen); - return -1; - } - for (i=0;i<8;i++) raw->nav.ion_gps[i]=R8(p+i*8); - raw->nav.utc_gps[0]=R8(p+72); - raw->nav.utc_gps[1]=R8(p+80); - raw->nav.utc_gps[2]=U4(p+68); - raw->nav.utc_gps[3]=U4(p+64); - raw->nav.leaps =I4(p+96); - return 9; +static int decode_ionutcb(raw_t *raw) { + unsigned char *p = raw->buff + TERSUSHLEN; + int i; + + trace(3, "decode_ionutcb: len=%d\n", raw->len); + + if (raw->len < TERSUSHLEN + 108) { + trace(2, "tersus ionutcb length error: len=%d\n", raw->len); + return -1; + } + for (i = 0; i < 8; i++) raw->nav.ion_gps[i] = R8(p + i * 8); + raw->nav.utc_gps[0] = R8(p + 72); + raw->nav.utc_gps[1] = R8(p + 80); + raw->nav.utc_gps[2] = U4(p + 68); + raw->nav.utc_gps[3] = U4(p + 64); + raw->nav.leaps = I4(p + 96); + return 9; } /* decode tersus message -----------------------------------------------------*/ -static int decode_tersus(raw_t *raw) -{ - double tow; - int msg,week,type=U2(raw->buff+4); - - trace(3,"decode_tersus: type=%3d len=%d\n",type,raw->len); - - /* check crc32 */ - if (rtk_crc32(raw->buff,raw->len)!=U4(raw->buff+raw->len)) { - trace(2,"tersus crc error: type=%3d len=%d\n",type,raw->len); - return -1; - } - msg =(U1(raw->buff+6)>>4)&0x3; - if (!(week=U2(raw->buff+14))) { - return -1; - } - week=adjgpsweek(week); - tow =U4(raw->buff+16)*0.001; - raw->time=gpst2time(week,tow); - - if (raw->outtype) { - char tstr[40]; - sprintf(raw->msgtype,"TERSUS%4d (%4d): msg=%d %s",type,raw->len,msg, - time2str(gpst2time(week,tow),tstr,2)); - } - switch (type) { - case ID_RANGE : return decode_rangeb (raw); - case ID_RANGECMP : return decode_rangecmpb (raw); - case ID_IONUTC : return decode_ionutcb (raw); - case ID_GPSEPHEM : return decode_gpsephemb (raw); - case ID_GLOEPHEMERIS : return decode_gloephemerisb(raw); - case ID_BDSEPHEMERIS : return decode_bdsephemerisb(raw); - case ID_BD2EPHEM : return decode_bd2ephemb (raw); - } - return 0; +static int decode_tersus(raw_t *raw) { + double tow; + int msg, week, type = U2(raw->buff + 4); + + trace(3, "decode_tersus: type=%3d len=%d\n", type, raw->len); + + /* check crc32 */ + if (rtk_crc32(raw->buff, raw->len) != U4(raw->buff + raw->len)) { + trace(2, "tersus crc error: type=%3d len=%d\n", type, raw->len); + return -1; + } + msg = (U1(raw->buff + 6) >> 4) & 0x3; + if (!(week = U2(raw->buff + 14))) { + return -1; + } + week = adjgpsweek(week); + tow = U4(raw->buff + 16) * 0.001; + raw->time = gpst2time(week, tow); + + if (raw->outtype) { + char tstr[40]; + sprintf(raw->msgtype, "TERSUS%4d (%4d): msg=%d %s", type, raw->len, msg, + time2str(gpst2time(week, tow), tstr, 2)); + } + switch (type) { + case ID_RANGE: + return decode_rangeb(raw); + case ID_RANGECMP: + return decode_rangecmpb(raw); + case ID_IONUTC: + return decode_ionutcb(raw); + case ID_GPSEPHEM: + return decode_gpsephemb(raw); + case ID_GLOEPHEMERIS: + return decode_gloephemerisb(raw); + case ID_BDSEPHEMERIS: + return decode_bdsephemerisb(raw); + case ID_BD2EPHEM: + return decode_bd2ephemb(raw); + } + return 0; } /* sync header ---------------------------------------------------------------*/ -static int sync_tersus(unsigned char *buff, unsigned char data) -{ - buff[0]=buff[1]; buff[1]=buff[2]; buff[2]=data; - return buff[0]==TERSUSSYNC1&&buff[1]==TERSUSSYNC2&&buff[2]==TERSUSSYNC3; +static int sync_tersus(unsigned char *buff, unsigned char data) { + buff[0] = buff[1]; + buff[1] = buff[2]; + buff[2] = data; + return buff[0] == TERSUSSYNC1 && buff[1] == TERSUSSYNC2 && buff[2] == TERSUSSYNC3; } /* input tersus raw data from stream ------------------------------------------- -* fetch next tersus raw data and input a mesasge from stream -* args : raw_t *raw IO receiver raw data control struct -* unsigned char data I stream data (1 byte) -* return : status (-1: error message, 0: no message, 1: input observation data, -* 2: input ephemeris, 3: input sbas message, -* 9: input ion/utc parameter) -* -* notes : to specify input options for tersus, set raw->opt to the following -* option strings separated by spaces. -* -* -EPHALL : input all ephemerides -*-----------------------------------------------------------------------------*/ -extern int input_tersus(raw_t *raw, unsigned char data) -{ - trace(5,"input_tersus: data=%02x\n",data); - - /* synchronize frame */ - if (raw->nbyte==0) { - if (sync_tersus(raw->buff,data)) raw->nbyte=3; - return 0; - } - raw->buff[raw->nbyte++]=data; - - if (raw->nbyte==10&&(raw->len=U2(raw->buff+8)+TERSUSHLEN)>MAXRAWLEN-4) { - trace(2,"tersus length error: len=%d\n",raw->len); - raw->nbyte=0; - return -1; - } - if (raw->nbyte<10||raw->nbytelen+4) return 0; - raw->nbyte=0; - - /* decode tersus message */ - return decode_tersus(raw); + * fetch next tersus raw data and input a mesasge from stream + * args : raw_t *raw IO receiver raw data control struct + * unsigned char data I stream data (1 byte) + * return : status (-1: error message, 0: no message, 1: input observation data, + * 2: input ephemeris, 3: input sbas message, + * 9: input ion/utc parameter) + * + * notes : to specify input options for tersus, set raw->opt to the following + * option strings separated by spaces. + * + * -EPHALL : input all ephemerides + *-----------------------------------------------------------------------------*/ +extern int input_tersus(raw_t *raw, unsigned char data) { + trace(5, "input_tersus: data=%02x\n", data); + + /* synchronize frame */ + if (raw->nbyte == 0) { + if (sync_tersus(raw->buff, data)) raw->nbyte = 3; + return 0; + } + raw->buff[raw->nbyte++] = data; + + if (raw->nbyte == 10 && (raw->len = U2(raw->buff + 8) + TERSUSHLEN) > MAXRAWLEN - 4) { + trace(2, "tersus length error: len=%d\n", raw->len); + raw->nbyte = 0; + return -1; + } + if (raw->nbyte < 10 || raw->nbyte < raw->len + 4) return 0; + raw->nbyte = 0; + + /* decode tersus message */ + return decode_tersus(raw); } /* input tersus raw data from file --------------------------------------------- -* fetch next tersus raw data and input a message from file -* args : raw_t *raw IO receiver raw data control struct -* int format I receiver raw data format (STRFMT_???) -* FILE *fp I file pointer -* return : status(-2: end of file, -1...9: same as above) -*-----------------------------------------------------------------------------*/ -extern int input_tersusf(raw_t *raw, FILE *fp) -{ - int i,data; - - trace(4,"input_tersusf:\n"); - - /* synchronize frame */ - if (raw->nbyte==0) { - for (i=0;;i++) { - if ((data=fgetc(fp))==EOF) return -2; - if (sync_tersus(raw->buff,(unsigned char)data)) break; - if (i>=4096) return 0; - } - } - if (fread(raw->buff+3,7,1,fp)<1) return -2; - raw->nbyte=10; - - if ((raw->len=U2(raw->buff+8)+TERSUSHLEN)>MAXRAWLEN-4) { - trace(2,"tersus length error: len=%d\n",raw->len); - raw->nbyte=0; - return -1; - } - if (fread(raw->buff+10,raw->len-6,1,fp)<1) return -2; - raw->nbyte=0; - - /* decode tersus message */ - return decode_tersus(raw); + * fetch next tersus raw data and input a message from file + * args : raw_t *raw IO receiver raw data control struct + * int format I receiver raw data format (STRFMT_???) + * FILE *fp I file pointer + * return : status(-2: end of file, -1...9: same as above) + *-----------------------------------------------------------------------------*/ +extern int input_tersusf(raw_t *raw, FILE *fp) { + int i, data; + + trace(4, "input_tersusf:\n"); + + /* synchronize frame */ + if (raw->nbyte == 0) { + for (i = 0;; i++) { + if ((data = fgetc(fp)) == EOF) return -2; + if (sync_tersus(raw->buff, (unsigned char)data)) break; + if (i >= 4096) return 0; + } + } + if (fread(raw->buff + 3, 7, 1, fp) < 1) return -2; + raw->nbyte = 10; + + if ((raw->len = U2(raw->buff + 8) + TERSUSHLEN) > MAXRAWLEN - 4) { + trace(2, "tersus length error: len=%d\n", raw->len); + raw->nbyte = 0; + return -1; + } + if (fread(raw->buff + 10, raw->len - 6, 1, fp) < 1) return -2; + raw->nbyte = 0; + + /* decode tersus message */ + return decode_tersus(raw); } diff --git a/src/rcv/ublox.c b/src/rcv/ublox.c index ebf9acd7a..5e7116100 100644 --- a/src/rcv/ublox.c +++ b/src/rcv/ublox.c @@ -1,1891 +1,2550 @@ /*------------------------------------------------------------------------------ -* ublox.c : ublox receiver dependent functions -* -* Copyright (C) 2007-2020 by T.TAKASU, All rights reserved. -* Copyright (C) 2014 by T.SUZUKI, All rights reserved. -* -* reference : -* [1] ublox-AG, GPS.G3-X-03002-D, ANTARIS Positioning Engine NMEA and UBX -* Protocol Specification, Version 5.00, 2003 -* [2] ublox-AG, UBX-13003221-R03, u-blox M8 Receiver Description including -* Protocol Specification V5, Dec 20, 2013 -* [3] ublox-AG, UBX-13003221-R07, u-blox M8 Receiver Description including -* Protocol Specification V15.00-17.00, Nov 3, 2014 -* [4] ublox-AG, UBX-13003221-R09, u-blox 8 /u-blox M8 Receiver Description -* including Protocol Specification V15.00-18.00, January, 2016 -* [5] ublox-AG, UBX-18010854-R08, u-blox ZED-F9P Interface Description, -* May, 2020 -* -* version : $Revision: 1.2 $ $Date: 2008/07/14 00:05:05 $ -* history : 2007/10/08 1.0 new -* 2008/06/16 1.1 separate common functions to rcvcmn.c -* 2009/04/01 1.2 add range check of prn number -* 2009/04/10 1.3 refactored -* 2009/09/25 1.4 add function gen_ubx() -* 2010/01/17 1.5 add time tag adjustment option -tadj sec -* 2010/10/31 1.6 fix bug on playback disabled for raw data (2.4.0_p9) -* 2011/05/27 1.7 add almanac decoding -* add -EPHALL option -* fix problem with ARM compiler -* 2013/02/23 1.8 fix memory access violation problem on arm -* change options -tadj to -TADJ, -invcp to -INVCP -* 2014/05/26 1.9 fix bug on message size of CFG-MSG -* fix bug on return code of decode_alm1() -* 2014/06/21 1.10 support message TRK-MEAS and TRK-SFRBX -* support message NAV-SOL and NAV-TIMEGPS to get time -* support message GFG-GNSS generation -* 2014/06/23 1.11 support message TRK-MEAS for beidou ephemeris -* 2014/08/11 1.12 fix bug on unable to read RXM-RAW -* fix problem on decoding glo ephemeris in TRK-SFRBX -* support message TRK-TRKD5 -* 2014/08/31 1.13 suppress warning -* 2014/11/04 1.14 support message RXM-RAWX and RXM-SFRBX -* 2015/03/20 1.15 omit time adjustment for RXM-RAWX -* 2016/01/22 1.16 add time-tag in raw-message-type -* 2016/01/26 1.17 support galileo navigation data in RXM-SFRBX -* enable option -TADJ for RXM-RAWX -* 2016/05/25 1.18 fix bug on crc-buffer-overflow by decoding galileo -* navigation data -* 2016/07/04 1.19 add half-cycle vaild check for ubx-trk-meas -* 2016/07/29 1.20 support RXM-CFG-TMODE3 (0x06 0x71) for M8P -* crc24q() -> rtk_crc24q() -* check week number zero for ubx-rxm-raw and rawx -* 2016/08/20 1.21 add test of std-dev for carrier-phase valid -* 2016/08/26 1.22 add option -STD_SLIP to test slip by std-dev of cp -* fix on half-cyc valid for sbas in trkmeas -* 2017/04/11 1.23 (char *) -> (signed char *) -* fix bug on week handover in decode_trkmeas/trkd5() -* fix bug on prn for geo in decode_cnav() -* 2017/06/10 1.24 output half-cycle-subtracted flag -* 2018/10/09 1.25 support ZED-F9P according to [5] -* beidou C17 is handled as GEO (navigation D2). -* 2018/11/05 1.26 fix problem on missing QZSS L2C signal -* save signal in obs data by signal index -* suppress warning for cnav in ubx-rxm-sfrbx -* 2019/05/10 1.27 disable half-cyc-subtract flag on LLI for RXM-RAWX -* save galileo E5b data to obs index 2 -* handle C17 as no-GEO (MEO/IGSO) -* 2020/11/30 1.28 update reference [5] -* support UBX-CFG-VALDEL,VALGET,VALSET -* support hex field format for ubx binary message -* add quality test for receiver time in decode_trkd5() -* add half cycle shift correction for BDS GEO -* delete receiver option -GALFNAV -* use API code2idx() and code2freq() -* support QZSS L1S (CODE_L1Z) -* CODE_L1I -> CODE_L2I for BDS B1I (RINEX 3.04) -* use integer types in stdint.h -*-----------------------------------------------------------------------------*/ + * ublox.c : ublox receiver dependent functions + * + * Copyright (C) 2007-2020 by T.TAKASU, All rights reserved. + * Copyright (C) 2014 by T.SUZUKI, All rights reserved. + * + * reference : + * [1] ublox-AG, GPS.G3-X-03002-D, ANTARIS Positioning Engine NMEA and UBX + * Protocol Specification, Version 5.00, 2003 + * [2] ublox-AG, UBX-13003221-R03, u-blox M8 Receiver Description including + * Protocol Specification V5, Dec 20, 2013 + * [3] ublox-AG, UBX-13003221-R07, u-blox M8 Receiver Description including + * Protocol Specification V15.00-17.00, Nov 3, 2014 + * [4] ublox-AG, UBX-13003221-R09, u-blox 8 /u-blox M8 Receiver Description + * including Protocol Specification V15.00-18.00, January, 2016 + * [5] ublox-AG, UBX-18010854-R08, u-blox ZED-F9P Interface Description, + * May, 2020 + * + * version : $Revision: 1.2 $ $Date: 2008/07/14 00:05:05 $ + * history : 2007/10/08 1.0 new + * 2008/06/16 1.1 separate common functions to rcvcmn.c + * 2009/04/01 1.2 add range check of prn number + * 2009/04/10 1.3 refactored + * 2009/09/25 1.4 add function gen_ubx() + * 2010/01/17 1.5 add time tag adjustment option -tadj sec + * 2010/10/31 1.6 fix bug on playback disabled for raw data (2.4.0_p9) + * 2011/05/27 1.7 add almanac decoding + * add -EPHALL option + * fix problem with ARM compiler + * 2013/02/23 1.8 fix memory access violation problem on arm + * change options -tadj to -TADJ, -invcp to -INVCP + * 2014/05/26 1.9 fix bug on message size of CFG-MSG + * fix bug on return code of decode_alm1() + * 2014/06/21 1.10 support message TRK-MEAS and TRK-SFRBX + * support message NAV-SOL and NAV-TIMEGPS to get time + * support message GFG-GNSS generation + * 2014/06/23 1.11 support message TRK-MEAS for beidou ephemeris + * 2014/08/11 1.12 fix bug on unable to read RXM-RAW + * fix problem on decoding glo ephemeris in TRK-SFRBX + * support message TRK-TRKD5 + * 2014/08/31 1.13 suppress warning + * 2014/11/04 1.14 support message RXM-RAWX and RXM-SFRBX + * 2015/03/20 1.15 omit time adjustment for RXM-RAWX + * 2016/01/22 1.16 add time-tag in raw-message-type + * 2016/01/26 1.17 support galileo navigation data in RXM-SFRBX + * enable option -TADJ for RXM-RAWX + * 2016/05/25 1.18 fix bug on crc-buffer-overflow by decoding galileo + * navigation data + * 2016/07/04 1.19 add half-cycle vaild check for ubx-trk-meas + * 2016/07/29 1.20 support RXM-CFG-TMODE3 (0x06 0x71) for M8P + * crc24q() -> rtk_crc24q() + * check week number zero for ubx-rxm-raw and rawx + * 2016/08/20 1.21 add test of std-dev for carrier-phase valid + * 2016/08/26 1.22 add option -STD_SLIP to test slip by std-dev of cp + * fix on half-cyc valid for sbas in trkmeas + * 2017/04/11 1.23 (char *) -> (signed char *) + * fix bug on week handover in decode_trkmeas/trkd5() + * fix bug on prn for geo in decode_cnav() + * 2017/06/10 1.24 output half-cycle-subtracted flag + * 2018/10/09 1.25 support ZED-F9P according to [5] + * beidou C17 is handled as GEO (navigation D2). + * 2018/11/05 1.26 fix problem on missing QZSS L2C signal + * save signal in obs data by signal index + * suppress warning for cnav in ubx-rxm-sfrbx + * 2019/05/10 1.27 disable half-cyc-subtract flag on LLI for RXM-RAWX + * save galileo E5b data to obs index 2 + * handle C17 as no-GEO (MEO/IGSO) + * 2020/11/30 1.28 update reference [5] + * support UBX-CFG-VALDEL,VALGET,VALSET + * support hex field format for ubx binary message + * add quality test for receiver time in decode_trkd5() + * add half cycle shift correction for BDS GEO + * delete receiver option -GALFNAV + * use API code2idx() and code2freq() + * support QZSS L1S (CODE_L1Z) + * CODE_L1I -> CODE_L2I for BDS B1I (RINEX 3.04) + * use integer types in stdint.h + *-----------------------------------------------------------------------------*/ #define _POSIX_C_SOURCE 199506 #include "rtklib.h" -#define UBXSYNC1 0xB5 /* ubx message sync code 1 */ -#define UBXSYNC2 0x62 /* ubx message sync code 2 */ -#define UBXCFG 0x06 /* ubx message cfg-??? */ - -#define PREAMB_CNAV 0x8B /* cnav preamble */ - -#define ID_NAVSOL 0x0106 /* ubx message id: nav solution info */ -#define ID_NAVTIME 0x0120 /* ubx message id: nav time gps */ -#define ID_RXMRAW 0x0210 /* ubx message id: raw measurement data */ -#define ID_RXMSFRB 0x0211 /* ubx message id: subframe buffer */ -#define ID_RXMSFRBX 0x0213 /* ubx message id: raw subframe data */ -#define ID_RXMRAWX 0x0215 /* ubx message id: multi-gnss raw meas data */ -#define ID_TRKD5 0x030A /* ubx message id: trace mesurement data */ -#define ID_TRKMEAS 0x0310 /* ubx message id: trace mesurement data */ -#define ID_TRKSFRBX 0x030F /* ubx message id: trace subframe buffer */ -#define ID_TIMTM2 0x0D03 /* ubx message id: time mark data */ - -#define FU1 1 /* ubx message field types */ -#define FU2 2 -#define FU4 3 -#define FU8 4 -#define FI1 5 -#define FI2 6 -#define FI4 7 -#define FR4 8 -#define FR8 9 -#define FS32 10 +#define UBXSYNC1 0xB5 /* ubx message sync code 1 */ +#define UBXSYNC2 0x62 /* ubx message sync code 2 */ +#define UBXCFG 0x06 /* ubx message cfg-??? */ + +#define PREAMB_CNAV 0x8B /* cnav preamble */ + +#define ID_NAVSOL 0x0106 /* ubx message id: nav solution info */ +#define ID_NAVTIME 0x0120 /* ubx message id: nav time gps */ +#define ID_RXMRAW 0x0210 /* ubx message id: raw measurement data */ +#define ID_RXMSFRB 0x0211 /* ubx message id: subframe buffer */ +#define ID_RXMSFRBX 0x0213 /* ubx message id: raw subframe data */ +#define ID_RXMRAWX 0x0215 /* ubx message id: multi-gnss raw meas data */ +#define ID_TRKD5 0x030A /* ubx message id: trace mesurement data */ +#define ID_TRKMEAS 0x0310 /* ubx message id: trace mesurement data */ +#define ID_TRKSFRBX 0x030F /* ubx message id: trace subframe buffer */ +#define ID_TIMTM2 0x0D03 /* ubx message id: time mark data */ + +#define FU1 1 /* ubx message field types */ +#define FU2 2 +#define FU4 3 +#define FU8 4 +#define FI1 5 +#define FI2 6 +#define FI4 7 +#define FR4 8 +#define FR8 9 +#define FS32 10 typedef enum { false, true } bool; -#define P2_10 0.0009765625 /* 2^-10 */ +#define P2_10 0.0009765625 /* 2^-10 */ /* max std-dev for valid carrier-phases */ -#define MAX_CPSTD_VALID_GEN8 5 /* optimal value for Gen8 modules */ -#define MAX_CPSTD_VALID_GEN9 14 /* optimal value for Gen9 modules */ -#define CPSTD_SLIP 15 /* std-dev threshold for slip */ +#define MAX_CPSTD_VALID_GEN8 5 /* optimal value for Gen8 modules */ +#define MAX_CPSTD_VALID_GEN9 14 /* optimal value for Gen9 modules */ +#define CPSTD_SLIP 15 /* std-dev threshold for slip */ -#define ROUND(x) (int)floor((x)+0.5) +#define ROUND(x) (int)floor((x) + 0.5) /* get fields (little-endian) ------------------------------------------------*/ #define U1(p) (*((uint8_t *)(p))) -#define I1(p) (*((int8_t *)(p))) -static uint16_t U2(uint8_t *p) {uint16_t u; memcpy(&u,p,2); return u;} -static uint32_t U4(uint8_t *p) {uint32_t u; memcpy(&u,p,4); return u;} -static int32_t I4(uint8_t *p) {int32_t u; memcpy(&u,p,4); return u;} -static float R4(uint8_t *p) {float r; memcpy(&r,p,4); return r;} -static double R8(uint8_t *p) {double r; memcpy(&r,p,8); return r;} -static double I8(uint8_t *p) {return I4(p+4)*4294967296.0+U4(p);} +#define I1(p) (*((int8_t *)(p))) +static uint16_t U2(uint8_t *p) { + uint16_t u; + memcpy(&u, p, 2); + return u; +} +static uint32_t U4(uint8_t *p) { + uint32_t u; + memcpy(&u, p, 4); + return u; +} +static int32_t I4(uint8_t *p) { + int32_t u; + memcpy(&u, p, 4); + return u; +} +static float R4(uint8_t *p) { + float r; + memcpy(&r, p, 4); + return r; +} +static double R8(uint8_t *p) { + double r; + memcpy(&r, p, 8); + return r; +} +static double I8(uint8_t *p) { return I4(p + 4) * 4294967296.0 + U4(p); } /* set fields (little-endian) ------------------------------------------------*/ -static void setU1(uint8_t *p, uint8_t u) {*p=u;} -static void setU2(uint8_t *p, uint16_t u) {memcpy(p,&u,2);} -static void setU4(uint8_t *p, uint32_t u) {memcpy(p,&u,4);} -static void setI1(uint8_t *p, int8_t i) {*p=(uint8_t)i;} -static void setI2(uint8_t *p, int16_t i) {memcpy(p,&i,2);} -static void setI4(uint8_t *p, int32_t i) {memcpy(p,&i,4);} -static void setR4(uint8_t *p, float r) {memcpy(p,&r,4);} -static void setR8(uint8_t *p, double r) {memcpy(p,&r,8);} +static void setU1(uint8_t *p, uint8_t u) { *p = u; } +static void setU2(uint8_t *p, uint16_t u) { memcpy(p, &u, 2); } +static void setU4(uint8_t *p, uint32_t u) { memcpy(p, &u, 4); } +static void setI1(uint8_t *p, int8_t i) { *p = (uint8_t)i; } +static void setI2(uint8_t *p, int16_t i) { memcpy(p, &i, 2); } +static void setI4(uint8_t *p, int32_t i) { memcpy(p, &i, 4); } +static void setR4(uint8_t *p, float r) { memcpy(p, &r, 4); } +static void setR8(uint8_t *p, double r) { memcpy(p, &r, 8); } /* checksum ------------------------------------------------------------------*/ -static int checksum(uint8_t *buff, int len) -{ - uint8_t cka=0,ckb=0; - int i; - - for (i=2;ibuff+6; - gtime_t time; - double tow,tt,tadj=0.0,toff=0.0,tn; - int i,j,prn,sat,n=0,nsat,week; - char *q; - - trace(4,"decode_rxmraw: len=%d\n",raw->len); - - if (raw->outtype) { - sprintf(raw->msgtype,"UBX RXM-RAW (%4d): nsat=%d",raw->len,U1(p+6)); - } - /* time tag adjustment option (-TADJ) */ - if ((q=strstr(raw->opt,"-TADJ="))) { - sscanf(q,"-TADJ=%lf",&tadj); - } - nsat=U1(p+6); - if (raw->len<12+24*nsat) { - trace(2,"ubx rxmraw length error: len=%d nsat=%d\n",raw->len,nsat); - return -1; - } - tow =U4(p ); - week=U2(p+4); - time=gpst2time(week,tow*0.001); - - if (week==0) { - trace(3,"ubx rxmraw week=0 error: len=%d nsat=%d\n",raw->len,nsat); - return 0; - } - /* time tag adjustment */ - if (tadj>0.0) { - tn=time2gpst(time,&week)/tadj; - toff=(tn-floor(tn+0.5))*tadj; - time=timeadd(time,-toff); +static int decode_rxmraw(raw_t *raw) { + uint8_t *p = raw->buff + 6; + gtime_t time; + double tow, tt, tadj = 0.0, toff = 0.0, tn; + int i, j, prn, sat, n = 0, nsat, week; + char *q; + + trace(4, "decode_rxmraw: len=%d\n", raw->len); + + if (raw->outtype) { + sprintf(raw->msgtype, "UBX RXM-RAW (%4d): nsat=%d", raw->len, U1(p + 6)); + } + /* time tag adjustment option (-TADJ) */ + if ((q = strstr(raw->opt, "-TADJ="))) { + sscanf(q, "-TADJ=%lf", &tadj); + } + nsat = U1(p + 6); + if (raw->len < 12 + 24 * nsat) { + trace(2, "ubx rxmraw length error: len=%d nsat=%d\n", raw->len, nsat); + return -1; + } + tow = U4(p); + week = U2(p + 4); + time = gpst2time(week, tow * 0.001); + + if (week == 0) { + trace(3, "ubx rxmraw week=0 error: len=%d nsat=%d\n", raw->len, nsat); + return 0; + } + /* time tag adjustment */ + if (tadj > 0.0) { + tn = time2gpst(time, &week) / tadj; + toff = (tn - floor(tn + 0.5)) * tadj; + time = timeadd(time, -toff); + } + tt = timediff(time, raw->time); + + for (i = 0, p += 8; i < nsat && i < MAXOBS; i++, p += 24) { + raw->obs.data[n].time = time; + raw->obs.data[n].L[0] = R8(p) - toff * FREQL1; + raw->obs.data[n].P[0] = R8(p + 8) - toff * CLIGHT; + raw->obs.data[n].D[0] = R4(p + 16); + prn = U1(p + 20); + raw->obs.data[n].SNR[0] = I1(p + 22); + raw->obs.data[n].LLI[0] = U1(p + 23); + raw->obs.data[n].code[0] = CODE_L1C; + + /* phase polarity flip option (-INVCP) */ + if (strstr(raw->opt, "-INVCP")) { + raw->obs.data[n].L[0] = -raw->obs.data[n].L[0]; } - tt=timediff(time,raw->time); - - for (i=0,p+=8;iobs.data[n].time=time; - raw->obs.data[n].L[0] =R8(p )-toff*FREQL1; - raw->obs.data[n].P[0] =R8(p+ 8)-toff*CLIGHT; - raw->obs.data[n].D[0] =R4(p+16); - prn =U1(p+20); - raw->obs.data[n].SNR[0]=I1(p+22); - raw->obs.data[n].LLI[0]=U1(p+23); - raw->obs.data[n].code[0]=CODE_L1C; - - /* phase polarity flip option (-INVCP) */ - if (strstr(raw->opt,"-INVCP")) { - raw->obs.data[n].L[0]=-raw->obs.data[n].L[0]; - } - if (!(sat=satno(MINPRNSBS<=prn?SYS_SBS:SYS_GPS,prn))) { - trace(2,"ubx rxmraw sat number error: prn=%d\n",prn); - continue; - } - raw->obs.data[n].sat=sat; - - if (raw->obs.data[n].LLI[0]&1) raw->lockt[sat-1][0]=0.0; - else if (tt<1.0||10.0lockt[sat-1][0]=0.0; - else raw->lockt[sat-1][0]+=tt; - - for (j=1;jobs.data[n].L[j]=raw->obs.data[n].P[j]=0.0; - raw->obs.data[n].D[j]=raw->obs.data[n].SNR[j]=0.0; - raw->obs.data[n].Lstd[j]=raw->obs.data[n].Pstd[j]=0.0; - raw->obs.data[n].LLI[j]=0; - raw->obs.data[n].code[j]=CODE_NONE; - } - n++; + if (!(sat = satno(MINPRNSBS <= prn ? SYS_SBS : SYS_GPS, prn))) { + trace(2, "ubx rxmraw sat number error: prn=%d\n", prn); + continue; } - raw->time=time; - raw->obs.n=n; - return 1; + raw->obs.data[n].sat = sat; + + if (raw->obs.data[n].LLI[0] & 1) + raw->lockt[sat - 1][0] = 0.0; + else if (tt < 1.0 || 10.0 < tt) + raw->lockt[sat - 1][0] = 0.0; + else + raw->lockt[sat - 1][0] += tt; + + for (j = 1; j < NFREQ + NEXOBS; j++) { + raw->obs.data[n].L[j] = raw->obs.data[n].P[j] = 0.0; + raw->obs.data[n].D[j] = raw->obs.data[n].SNR[j] = 0.0; + raw->obs.data[n].Lstd[j] = raw->obs.data[n].Pstd[j] = 0.0; + raw->obs.data[n].LLI[j] = 0; + raw->obs.data[n].code[j] = CODE_NONE; + } + n++; + } + raw->time = time; + raw->obs.n = n; + return 1; } /* decode UBX-RXM-RAWX: multi-GNSS raw measurement data (ref [3][4][5]) ------*/ -static int decode_rxmrawx(raw_t *raw) -{ - uint8_t *p=raw->buff+6; - gtime_t time; - char *q,tstr[40]; - double tow,P,L,D,tn,tadj=0.0,toff=0.0; - int i,j,k,idx,sys,prn,sat,code,slip,halfv,halfc,LLI,n=0; - int week,nmeas,ver,gnss,svid,sigid,frqid,lockt,cn0,cpstd=0,prstd=0,tstat; - int multicode=0, rcvstds=0; - - trace(4,"decode_rxmrawx: len=%d\n",raw->len); - - if (raw->len<24) { - trace(2,"ubx rxmrawx length error: len=%d\n",raw->len); - return -1; - } - tow =R8(p ); /* rcvTow (s) */ - week =U2(p+ 8); /* week */ - nmeas=U1(p+11); /* numMeas */ - ver =U1(p+13); /* version ([5] 5.15.3.1) */ - - if (raw->len<24+32*nmeas) { - trace(2,"ubx rxmrawx length error: len=%d nmeas=%d\n",raw->len,nmeas); - return -1; +static int decode_rxmrawx(raw_t *raw) { + uint8_t *p = raw->buff + 6; + gtime_t time; + char *q, tstr[40]; + double tow, P, L, D, tn, tadj = 0.0, toff = 0.0; + int i, j, k, idx, sys, prn, sat, code, slip, halfv, halfc, LLI, n = 0; + int week, nmeas, ver, gnss, svid, sigid, frqid, lockt, cn0, cpstd = 0, prstd = 0, tstat; + int multicode = 0, rcvstds = 0; + + trace(4, "decode_rxmrawx: len=%d\n", raw->len); + + if (raw->len < 24) { + trace(2, "ubx rxmrawx length error: len=%d\n", raw->len); + return -1; + } + tow = R8(p); /* rcvTow (s) */ + week = U2(p + 8); /* week */ + nmeas = U1(p + 11); /* numMeas */ + ver = U1(p + 13); /* version ([5] 5.15.3.1) */ + + if (raw->len < 24 + 32 * nmeas) { + trace(2, "ubx rxmrawx length error: len=%d nmeas=%d\n", raw->len, nmeas); + return -1; + } + if (week == 0) { + trace(3, "ubx rxmrawx week=0 error: len=%d nmeas=%d\n", raw->len, nmeas); + return 0; + } + time = gpst2time(week, tow); + + if (raw->outtype) { + time2str(time, tstr, 2); + sprintf(raw->msgtype, "UBX RXM-RAWX (%4d): time=%s nmeas=%d ver=%d", raw->len, tstr, nmeas, + ver); + } + /* time tag adjustment option (-TADJ) */ + if ((q = strstr(raw->opt, "-TADJ="))) { + sscanf(q, "-TADJ=%lf", &tadj); + } + /* max valid std-dev of carrier-phase (-MAX_STD_CP) */ + int cpstd_valid; + if (raw->rcvtype == 1) + cpstd_valid = MAX_CPSTD_VALID_GEN9; /* F9P */ + else + cpstd_valid = MAX_CPSTD_VALID_GEN8; /* M8T, M8P */ + q = strstr(raw->opt, "-MAX_STD_CP="); + if (q) sscanf(q, "-MAX_STD_CP=%d", &cpstd_valid); + + /* slip threshold of std-dev of carrier-phase (-STD_SLIP) */ + int cpstd_slip = CPSTD_SLIP; + q = strstr(raw->opt, "-STD_SLIP="); + if (q) sscanf(q, "-STD_SLIP=%d", &cpstd_slip); + + /* use multiple codes for each freq (-MULTICODE) */ + if (strstr(raw->opt, "-MULTICODE")) multicode = 1; + /* write rcvr stdevs to unused rinex fields */ + if (strstr(raw->opt, "-RCVSTDS")) rcvstds = 1; + + /* time tag adjustment */ + if (tadj > 0.0) { + tn = time2gpst(time, &week) / tadj; + toff = (tn - floor(tn + 0.5)) * tadj; + time = timeadd(time, -toff); + } + for (i = 0, p += 16; i < nmeas && n < MAXOBS; i++, p += 32) { + P = R8(p); /* prMes (m) */ + L = R8(p + 8); /* cpMes (cyc) */ + D = R4(p + 16); /* doMes (hz) */ + gnss = U1(p + 20); /* gnssId */ + svid = U1(p + 21); /* svId */ + sigid = U1(p + 22); /* sigId ([5] 5.15.3.1) */ + frqid = U1(p + 23); /* freqId (fcn + 7) */ + lockt = U2(p + 24); /* locktime (ms) */ + cn0 = U1(p + 26); /* cn0 (dBHz) */ + prstd = U1(p + 27) & 15; /* pseudorange std-dev: (0.01*2^n meters) */ + cpstd = U1(p + 28) & 15; /* cpStdev (n*0.004 m) */ + tstat = U1(p + 30); /* trkStat */ + if (!(tstat & 1)) P = 0.0; + if (!(tstat & 2) || L == -0.5 || cpstd > cpstd_valid) L = 0.0; /* invalid phase */ + if (sigid > 1) raw->rcvtype = 1; /* flag as Gen9 receiver */ + + if (!(sys = ubx_sys(gnss))) { + trace(2, "ubx rxmrawx: system error gnss=%d\n", gnss); + continue; + } + prn = svid + (sys == SYS_QZS ? 192 : 0); + if (!(sat = satno(sys, prn))) { + if (sys == SYS_GLO && prn == 255) { + continue; /* suppress warning for unknown glo satellite */ + } + trace(2, "ubx rxmrawx sat number error: sys=%2d prn=%2d\n", sys, prn); + continue; + } + if (sys == SYS_GLO && !raw->nav.glo_fcn[prn - 1]) { + raw->nav.glo_fcn[prn - 1] = frqid - 7 + 8; + } + if (ver >= 1) { + if (multicode) + code = ubx_sig(sys, sigid); + else + code = ubx_sig_combined(sys, sigid); + } else { + code = (sys == SYS_CMP) ? CODE_L2I : ((sys == SYS_GAL) ? CODE_L1X : CODE_L1C); } - if (week==0) { - trace(3,"ubx rxmrawx week=0 error: len=%d nmeas=%d\n",raw->len,nmeas); - return 0; + /* signal index in obs data */ + if ((idx = sig_idx(sys, code)) < 0) { + trace(2, "ubx rxmrawx signal error: sat=%2d sigid=%d\n", sat, sigid); + continue; } - time=gpst2time(week,tow); - - if (raw->outtype) { - time2str(time,tstr,2); - sprintf(raw->msgtype,"UBX RXM-RAWX (%4d): time=%s nmeas=%d ver=%d", - raw->len,tstr,nmeas,ver); + /* offset by time tag adjustment */ + if (toff != 0.0) { + P -= P != 0.0 ? toff * CLIGHT : 0.0; + L -= L != 0.0 ? toff * code2freq(sys, code, frqid - 7) : 0.0; } - /* time tag adjustment option (-TADJ) */ - if ((q=strstr(raw->opt,"-TADJ="))) { - sscanf(q,"-TADJ=%lf",&tadj); + /* half-cycle shift correction for BDS GEO */ + if (sys == SYS_CMP && (prn <= 5 || prn >= 59) && L != 0.0) { + L += 0.5; } - /* max valid std-dev of carrier-phase (-MAX_STD_CP) */ - int cpstd_valid; - if (raw->rcvtype == 1) - cpstd_valid = MAX_CPSTD_VALID_GEN9; /* F9P */ + if (sys == SYS_SBS) + halfv = lockt > 8000 ? 1 : 0; /* half-cycle valid */ else - cpstd_valid = MAX_CPSTD_VALID_GEN8; /* M8T, M8P */ - q = strstr(raw->opt, "-MAX_STD_CP="); - if (q) sscanf(q, "-MAX_STD_CP=%d", &cpstd_valid); - - /* slip threshold of std-dev of carrier-phase (-STD_SLIP) */ - int cpstd_slip = CPSTD_SLIP; - q = strstr(raw->opt, "-STD_SLIP="); - if (q) sscanf(q, "-STD_SLIP=%d", &cpstd_slip); - - /* use multiple codes for each freq (-MULTICODE) */ - if (strstr(raw->opt,"-MULTICODE")) multicode=1; - /* write rcvr stdevs to unused rinex fields */ - if (strstr(raw->opt,"-RCVSTDS")) rcvstds=1; - - /* time tag adjustment */ - if (tadj>0.0) { - tn=time2gpst(time,&week)/tadj; - toff=(tn-floor(tn+0.5))*tadj; - time=timeadd(time,-toff); - } - for (i=0,p+=16;icpstd_valid) L=0.0; /* invalid phase */ - if (sigid>1) raw->rcvtype=1; /* flag as Gen9 receiver */ - - if (!(sys=ubx_sys(gnss))) { - trace(2,"ubx rxmrawx: system error gnss=%d\n", gnss); - continue; - } - prn=svid+(sys==SYS_QZS?192:0); - if (!(sat=satno(sys,prn))) { - if (sys==SYS_GLO&&prn==255) { - continue; /* suppress warning for unknown glo satellite */ - } - trace(2,"ubx rxmrawx sat number error: sys=%2d prn=%2d\n",sys,prn); - continue; - } - if (sys==SYS_GLO&&!raw->nav.glo_fcn[prn-1]) { - raw->nav.glo_fcn[prn-1]=frqid-7+8; - } - if (ver>=1) { - if (multicode) - code=ubx_sig(sys,sigid); - else - code=ubx_sig_combined(sys,sigid); - } - else { - code=(sys==SYS_CMP)?CODE_L2I:((sys==SYS_GAL)?CODE_L1X:CODE_L1C); - } - /* signal index in obs data */ - if ((idx=sig_idx(sys,code))<0) { - trace(2,"ubx rxmrawx signal error: sat=%2d sigid=%d\n",sat,sigid); - continue; - } - /* offset by time tag adjustment */ - if (toff!=0.0) { - P-=P!=0.0?toff*CLIGHT:0.0; - L-=L!=0.0?toff*code2freq(sys,code,frqid-7):0.0; - } - /* half-cycle shift correction for BDS GEO */ - if (sys==SYS_CMP&&(prn<=5||prn>=59)&&L!=0.0) { - L+=0.5; - } - if (sys==SYS_SBS) - halfv=lockt>8000?1:0; /* half-cycle valid */ - else - halfv=(tstat&4)?1:0; /* half cycle valid */ - halfc=(tstat&8)?1:0; /* half cycle subtracted from phase */ - slip=lockt==0||lockt*1E-3lockt[sat-1][idx]|| - halfc!=raw->halfc[sat-1][idx]; - if (cpstd>=cpstd_slip) slip=LLI_SLIP; - if (slip) raw->lockflag[sat-1][idx]=slip; - raw->lockt[sat-1][idx]=lockt*1E-3; - /* LLI: bit0=slip,bit1=half-cycle-unresolved */ - LLI=!halfv&&L!=0.0?LLI_HALFC:0; - /* half cycle adjusted */ - LLI|=halfc?LLI_HALFA:0; - /* set cycle slip if half cycle subtract bit changed state */ - LLI|=halfc!=raw->halfc[sat-1][idx]?LLI_SLIP:0; - raw->halfc[sat-1][idx]=halfc; - /* set cycle slip flag if first valid phase since slip */ - if (L!=0.0) LLI|=raw->lockflag[sat-1][idx]>0.0?LLI_SLIP:0; - - for (j=0;jobs.data[j].sat==sat) break; - } - if (j>=n) { - raw->obs.data[n].time=time; - raw->obs.data[n].sat=sat; - raw->obs.data[n].rcv=0; - for (k=0;kobs.data[n].L[k]=raw->obs.data[n].P[k]=0.0; - raw->obs.data[n].D[k]=raw->obs.data[n].SNR[k]=0.0; - raw->obs.data[n].Lstd[k]=raw->obs.data[n].Pstd[k]=0.0; - raw->obs.data[n].LLI[k]=0; - raw->obs.data[n].code[k]=CODE_NONE; - } - n++; - } - raw->obs.data[j].L[idx]=L; - raw->obs.data[j].P[idx]=P; - raw->obs.data[j].Lstd[idx] = rcvstds ? cpstd * 0.004 : 0; - raw->obs.data[j].Pstd[idx] = rcvstds ? 0.01 * pow(2, prstd) : 0.0; - raw->obs.data[j].D[idx]=(float)D; - raw->obs.data[j].SNR[idx]=cn0; - raw->obs.data[j].LLI[idx]=(uint8_t)LLI; - raw->obs.data[j].code[idx]=(uint8_t)code; - if (L!=0.0) raw->lockflag[sat-1][idx]=0; /* clear slip carry-forward flag if valid phase*/ - } - raw->time=time; - raw->obs.n=n; - return 1; + halfv = (tstat & 4) ? 1 : 0; /* half cycle valid */ + halfc = (tstat & 8) ? 1 : 0; /* half cycle subtracted from phase */ + slip = + lockt == 0 || lockt * 1E-3 < raw->lockt[sat - 1][idx] || halfc != raw->halfc[sat - 1][idx]; + if (cpstd >= cpstd_slip) slip = LLI_SLIP; + if (slip) raw->lockflag[sat - 1][idx] = slip; + raw->lockt[sat - 1][idx] = lockt * 1E-3; + /* LLI: bit0=slip,bit1=half-cycle-unresolved */ + LLI = !halfv && L != 0.0 ? LLI_HALFC : 0; + /* half cycle adjusted */ + LLI |= halfc ? LLI_HALFA : 0; + /* set cycle slip if half cycle subtract bit changed state */ + LLI |= halfc != raw->halfc[sat - 1][idx] ? LLI_SLIP : 0; + raw->halfc[sat - 1][idx] = halfc; + /* set cycle slip flag if first valid phase since slip */ + if (L != 0.0) LLI |= raw->lockflag[sat - 1][idx] > 0.0 ? LLI_SLIP : 0; + + for (j = 0; j < n; j++) { + if (raw->obs.data[j].sat == sat) break; + } + if (j >= n) { + raw->obs.data[n].time = time; + raw->obs.data[n].sat = sat; + raw->obs.data[n].rcv = 0; + for (k = 0; k < NFREQ + NEXOBS; k++) { + raw->obs.data[n].L[k] = raw->obs.data[n].P[k] = 0.0; + raw->obs.data[n].D[k] = raw->obs.data[n].SNR[k] = 0.0; + raw->obs.data[n].Lstd[k] = raw->obs.data[n].Pstd[k] = 0.0; + raw->obs.data[n].LLI[k] = 0; + raw->obs.data[n].code[k] = CODE_NONE; + } + n++; + } + raw->obs.data[j].L[idx] = L; + raw->obs.data[j].P[idx] = P; + raw->obs.data[j].Lstd[idx] = rcvstds ? cpstd * 0.004 : 0; + raw->obs.data[j].Pstd[idx] = rcvstds ? 0.01 * pow(2, prstd) : 0.0; + raw->obs.data[j].D[idx] = (float)D; + raw->obs.data[j].SNR[idx] = cn0; + raw->obs.data[j].LLI[idx] = (uint8_t)LLI; + raw->obs.data[j].code[idx] = (uint8_t)code; + if (L != 0.0) raw->lockflag[sat - 1][idx] = 0; /* clear slip carry-forward flag if valid phase*/ + } + raw->time = time; + raw->obs.n = n; + return 1; } /* decode UBX-NAV-SOL: navigation solution -----------------------------------*/ -static int decode_navsol(raw_t *raw) -{ - uint8_t *p=raw->buff+6; - int itow,ftow,week; - - trace(4,"decode_navsol: len=%d\n",raw->len); - - if (raw->outtype) { - sprintf(raw->msgtype,"UBX NAV-SOL (%4d):",raw->len); - } - itow=U4(p); - ftow=I4(p+4); - week=U2(p+8); - if ((U1(p+11)&0x0C)==0x0C) { - raw->time=gpst2time(week,itow*1E-3+ftow*1E-9); - } - return 0; +static int decode_navsol(raw_t *raw) { + uint8_t *p = raw->buff + 6; + int itow, ftow, week; + + trace(4, "decode_navsol: len=%d\n", raw->len); + + if (raw->outtype) { + sprintf(raw->msgtype, "UBX NAV-SOL (%4d):", raw->len); + } + itow = U4(p); + ftow = I4(p + 4); + week = U2(p + 8); + if ((U1(p + 11) & 0x0C) == 0x0C) { + raw->time = gpst2time(week, itow * 1E-3 + ftow * 1E-9); + } + return 0; } /* decode UBX-NAV-TIMEGPS: GPS time solution ---------------------------------*/ -static int decode_navtime(raw_t *raw) -{ - int itow,ftow,week; - uint8_t *p=raw->buff+6; - - trace(4,"decode_navtime: len=%d\n",raw->len); - - if (raw->outtype) { - sprintf(raw->msgtype,"UBX NAV-TIME (%4d):",raw->len); - } - itow=U4(p); - ftow=I4(p+4); - week=U2(p+8); - if ((U1(p+11)&0x03)==0x03) { - raw->time=gpst2time(week,itow*1E-3+ftow*1E-9); - } - return 0; +static int decode_navtime(raw_t *raw) { + int itow, ftow, week; + uint8_t *p = raw->buff + 6; + + trace(4, "decode_navtime: len=%d\n", raw->len); + + if (raw->outtype) { + sprintf(raw->msgtype, "UBX NAV-TIME (%4d):", raw->len); + } + itow = U4(p); + ftow = I4(p + 4); + week = U2(p + 8); + if ((U1(p + 11) & 0x03) == 0x03) { + raw->time = gpst2time(week, itow * 1E-3 + ftow * 1E-9); + } + return 0; } /* decode UBX-TRK-MEAS: trace measurement data (unofficial) ------------------*/ -static int decode_trkmeas(raw_t *raw) -{ - static double adrs[MAXSAT]={0}; - uint8_t *p=raw->buff+6; - gtime_t time; - double ts,tr=-1.0,t,tau,utc_gpst,snr,adr,dop; - int i,j,n=0,nch,sys,prn,sat,qi,frq,flag,lock1,lock2,week,fw=0; - char *q; - /* adjustment to code measurement in meters, based on GLONASS freq, - values based on difference between TRK_MEAS values and RXM-RAWX values */ - const char P_adj_fw2[]={ 0, 0, 0, 0, 1, 3, 2, 0,-4,-3,-9,-8,-7,-4, 0}; /* fw 2.30 */ - const char P_adj_fw3[]={11,13,13,14,14,13,12,10, 8, 6, 5, 5, 5, 7, 0}; /* fw 3.01 */ - - trace(4,"decode_trkmeas: len=%d\n",raw->len); - - if (raw->outtype) { - sprintf(raw->msgtype,"UBX TRK-MEAS (%4d):",raw->len); - } - if (!raw->time.time) return 0; +static int decode_trkmeas(raw_t *raw) { + static double adrs[MAXSAT] = {0}; + uint8_t *p = raw->buff + 6; + gtime_t time; + double ts, tr = -1.0, t, tau, utc_gpst, snr, adr, dop; + int i, j, n = 0, nch, sys, prn, sat, qi, frq, flag, lock1, lock2, week, fw = 0; + char *q; + /* adjustment to code measurement in meters, based on GLONASS freq, + values based on difference between TRK_MEAS values and RXM-RAWX values */ + const char P_adj_fw2[] = {0, 0, 0, 0, 1, 3, 2, 0, -4, -3, -9, -8, -7, -4, 0}; /* fw 2.30 */ + const char P_adj_fw3[] = {11, 13, 13, 14, 14, 13, 12, 10, 8, 6, 5, 5, 5, 7, 0}; /* fw 3.01 */ + + trace(4, "decode_trkmeas: len=%d\n", raw->len); + + if (raw->outtype) { + sprintf(raw->msgtype, "UBX TRK-MEAS (%4d):", raw->len); + } + if (!raw->time.time) return 0; + + /* trk meas code adjust (-TRKM_ADJ) */ + if ((q = strstr(raw->opt, "-TRKM_ADJ="))) { + sscanf(q, "-TRKM_ADJ=%d", &fw); + } + + /* number of channels */ + nch = U1(p + 2); + + if (raw->len < 112 + nch * 56) { + trace(2, "decode_trkmeas: length error len=%d nch=%2d\n", raw->len, nch); + return -1; + } + /* time-tag = max(transmission time + 0.08) rounded by 100 ms */ + for (i = 0, p = raw->buff + 110; i < nch; i++, p += 56) { + if (U1(p + 1) < 4 || ubx_sys(U1(p + 4)) != SYS_GPS) continue; + if ((t = I8(p + 24) * P2_32 / 1000.0) > tr) tr = t; + } + if (tr < 0.0) return 0; + + tr = ROUND((tr + 0.08) / 0.1) * 0.1; + + /* adjust week handover */ + t = time2gpst(raw->time, &week); + if (tr < t - 302400.0) + week++; + else if (tr > t + 302400.0) + week--; + time = gpst2time(week, tr); + + utc_gpst = timediff(gpst2utc(time), time); + + int rcvstds = 0; + if (strstr(raw->opt, "-RCVSTDS")) rcvstds = 1; + + for (i = 0, p = raw->buff + 110; i < nch; i++, p += 56) { + /* quality indicator (0:idle,1:search,2:aquired,3:unusable, */ + /* 4:code lock,5,6,7:code/carrier lock) */ + qi = U1(p + 1); + if (qi < 4 || 7 < qi) continue; + + /* system and satellite number */ + if (!(sys = ubx_sys(U1(p + 4)))) { + trace(2, "ubx trkmeas: system error\n"); + continue; + } + prn = U1(p + 5) + (sys == SYS_QZS ? 192 : 0); + if (!(sat = satno(sys, prn))) { + trace(2, "ubx trkmeas sat number error: sys=%2d prn=%2d\n", sys, prn); + continue; + } + /* transmission time */ + ts = I8(p + 24) * P2_32 / 1000.0; + if (sys == SYS_CMP) + ts += 14.0; /* bdt -> gpst */ + else if (sys == SYS_GLO) + ts -= 10800.0 + utc_gpst; /* glot -> gpst */ + + /* signal travel time */ + tau = tr - ts; + if (tau < -302400.0) + tau += 604800.0; + else if (tau > 302400.0) + tau -= 604800.0; + + frq = U1(p + 7) - 7; /* frequency */ + flag = U1(p + 8); /* tracking status */ + lock1 = U1(p + 16); /* code lock count */ + lock2 = U1(p + 17); /* phase lock count */ + snr = U2(p + 20) / 256.0; + adr = I8(p + 32) * P2_32 + (flag & 0x40 ? 0.5 : 0.0); + dop = I4(p + 40) * P2_10 * 10.0; + + /* set slip flag */ + if (lock2 == 0 || lock2 < raw->lockt[sat - 1][0]) raw->lockt[sat - 1][1] = 1.0; + raw->lockt[sat - 1][0] = lock2; - /* trk meas code adjust (-TRKM_ADJ) */ - if ((q=strstr(raw->opt,"-TRKM_ADJ="))) { - sscanf(q,"-TRKM_ADJ=%d",&fw); - } - - /* number of channels */ - nch=U1(p+2); - - if (raw->len<112+nch*56) { - trace(2,"decode_trkmeas: length error len=%d nch=%2d\n",raw->len,nch); - return -1; - } - /* time-tag = max(transmission time + 0.08) rounded by 100 ms */ - for (i=0,p=raw->buff+110;itr) tr=t; - } - if (tr<0.0) return 0; - - tr=ROUND((tr+0.08)/0.1)*0.1; - - /* adjust week handover */ - t=time2gpst(raw->time,&week); - if (trt+302400.0) week--; - time=gpst2time(week,tr); - - utc_gpst=timediff(gpst2utc(time),time); - - int rcvstds = 0; - if (strstr(raw->opt,"-RCVSTDS")) rcvstds=1; - - for (i=0,p=raw->buff+110;i gpst */ - else if (sys==SYS_GLO) ts-=10800.0+utc_gpst; /* glot -> gpst */ - - /* signal travel time */ - tau=tr-ts; - if (tau<-302400.0) tau+=604800.0; - else if (tau> 302400.0) tau-=604800.0; - - frq =U1(p+ 7)-7; /* frequency */ - flag =U1(p+ 8); /* tracking status */ - lock1=U1(p+16); /* code lock count */ - lock2=U1(p+17); /* phase lock count */ - snr =U2(p+20)/256.0; - adr =I8(p+32)*P2_32+(flag&0x40?0.5:0.0); - dop =I4(p+40)*P2_10*10.0; - - /* set slip flag */ - if (lock2==0||lock2lockt[sat-1][0]) raw->lockt[sat-1][1]=1.0; - raw->lockt[sat-1][0]=lock2; - #ifdef RTK_DISABLED /* for debug */ - trace(2,"[%2d] qi=%d sys=%d prn=%3d frq=%2d flag=%02X ?=%02X %02X " - "%02X %02X %02X %02X %02X lock=%3d %3d ts=%10.3f snr=%4.1f " - "dop=%9.3f adr=%13.3f %6.3f\n",U1(p),qi,U1(p+4),prn,frq,flag, - U1(p+9),U1(p+10),U1(p+11),U1(p+12),U1(p+13),U1(p+14),U1(p+15), - lock1,lock2,ts,snr,dop,adr, - adrs[sat-1]==0.0||dop==0.0?0.0:(adr-adrs[sat-1])-dop); + trace(2, + "[%2d] qi=%d sys=%d prn=%3d frq=%2d flag=%02X ?=%02X %02X " + "%02X %02X %02X %02X %02X lock=%3d %3d ts=%10.3f snr=%4.1f " + "dop=%9.3f adr=%13.3f %6.3f\n", + U1(p), qi, U1(p + 4), prn, frq, flag, U1(p + 9), U1(p + 10), U1(p + 11), U1(p + 12), + U1(p + 13), U1(p + 14), U1(p + 15), lock1, lock2, ts, snr, dop, adr, + adrs[sat - 1] == 0.0 || dop == 0.0 ? 0.0 : (adr - adrs[sat - 1]) - dop); #endif - adrs[sat-1]=adr; - - /* check phase lock */ - if (!(flag&0x20)) continue; - - raw->obs.data[n].time=time; - raw->obs.data[n].sat=sat; - raw->obs.data[n].P[0]=tau*CLIGHT; - raw->obs.data[n].L[0]=-adr; - raw->obs.data[n].D[0]=(float)dop; - raw->obs.data[n].SNR[0]=snr; - raw->obs.data[n].code[0]=sys==SYS_CMP?CODE_L2I:CODE_L1C; - raw->obs.data[n].Lstd[0] = rcvstds ? (8 - qi) * 0.004 : 0; - raw->obs.data[n].LLI[0]=raw->lockt[sat-1][1]>0.0?1:0; - if (sys==SYS_SBS) { /* half-cycle valid */ - raw->obs.data[n].LLI[0]|=lock2>142?0:2; - } - else { - raw->obs.data[n].LLI[0]|=flag&0x80?0:2; - } - raw->lockt[sat-1][1]=0.0; - /* adjust code measurements for GLONASS sats */ - if (sys==SYS_GLO&&frq>=-7&&frq<=7) { - if (fw==2) raw->obs.data[n].P[0]+=(double)P_adj_fw2[frq+7]; - if (fw==3) raw->obs.data[n].P[0]+=(double)P_adj_fw3[frq+7]; - } - for (j=1;jobs.data[n].L[j]=raw->obs.data[n].P[j]=0.0; - raw->obs.data[n].D[j]=raw->obs.data[n].SNR[j]=0.0; - raw->obs.data[n].Lstd[j]=raw->obs.data[n].Pstd[j]=0.0; - raw->obs.data[n].LLI[j]=0; - raw->obs.data[n].code[j]=CODE_NONE; - } - n++; - } - if (n<=0) return 0; - raw->time=time; - raw->obs.n=n; - return 1; + adrs[sat - 1] = adr; + + /* check phase lock */ + if (!(flag & 0x20)) continue; + + raw->obs.data[n].time = time; + raw->obs.data[n].sat = sat; + raw->obs.data[n].P[0] = tau * CLIGHT; + raw->obs.data[n].L[0] = -adr; + raw->obs.data[n].D[0] = (float)dop; + raw->obs.data[n].SNR[0] = snr; + raw->obs.data[n].code[0] = sys == SYS_CMP ? CODE_L2I : CODE_L1C; + raw->obs.data[n].Lstd[0] = rcvstds ? (8 - qi) * 0.004 : 0; + raw->obs.data[n].LLI[0] = raw->lockt[sat - 1][1] > 0.0 ? 1 : 0; + if (sys == SYS_SBS) { /* half-cycle valid */ + raw->obs.data[n].LLI[0] |= lock2 > 142 ? 0 : 2; + } else { + raw->obs.data[n].LLI[0] |= flag & 0x80 ? 0 : 2; + } + raw->lockt[sat - 1][1] = 0.0; + /* adjust code measurements for GLONASS sats */ + if (sys == SYS_GLO && frq >= -7 && frq <= 7) { + if (fw == 2) raw->obs.data[n].P[0] += (double)P_adj_fw2[frq + 7]; + if (fw == 3) raw->obs.data[n].P[0] += (double)P_adj_fw3[frq + 7]; + } + for (j = 1; j < NFREQ + NEXOBS; j++) { + raw->obs.data[n].L[j] = raw->obs.data[n].P[j] = 0.0; + raw->obs.data[n].D[j] = raw->obs.data[n].SNR[j] = 0.0; + raw->obs.data[n].Lstd[j] = raw->obs.data[n].Pstd[j] = 0.0; + raw->obs.data[n].LLI[j] = 0; + raw->obs.data[n].code[j] = CODE_NONE; + } + n++; + } + if (n <= 0) return 0; + raw->time = time; + raw->obs.n = n; + return 1; } /* decode UBX-TRKD5: trace measurement data (unofficial) ---------------------*/ -static int decode_trkd5(raw_t *raw) -{ - static double adrs[MAXSAT]={0}; - gtime_t time; - double ts,tr=-1.0,t,tau,adr,dop,snr,utc_gpst; - int i,j,n=0,type,off,len,sys,prn,sat,qi,frq,flag,week; - uint8_t *p=raw->buff+6; - - trace(4,"decode_trkd5: len=%d\n",raw->len); - - if (raw->outtype) { - sprintf(raw->msgtype,"UBX TRK-D5 (%4d):",raw->len); - } - if (!raw->time.time) return 0; - - utc_gpst=timediff(gpst2utc(raw->time),raw->time); - - switch ((type=U1(p))) { - case 3 : off=86; len=56; break; - case 6 : off=86; len=64; break; /* u-blox 7 */ - default: off=78; len=56; break; +static int decode_trkd5(raw_t *raw) { + static double adrs[MAXSAT] = {0}; + gtime_t time; + double ts, tr = -1.0, t, tau, adr, dop, snr, utc_gpst; + int i, j, n = 0, type, off, len, sys, prn, sat, qi, frq, flag, week; + uint8_t *p = raw->buff + 6; + + trace(4, "decode_trkd5: len=%d\n", raw->len); + + if (raw->outtype) { + sprintf(raw->msgtype, "UBX TRK-D5 (%4d):", raw->len); + } + if (!raw->time.time) return 0; + + utc_gpst = timediff(gpst2utc(raw->time), raw->time); + + switch ((type = U1(p))) { + case 3: + off = 86; + len = 56; + break; + case 6: + off = 86; + len = 64; + break; /* u-blox 7 */ + default: + off = 78; + len = 56; + break; + } + for (i = 0, p = raw->buff + off; p - raw->buff < raw->len - 2; i++, p += len) { + qi = U1(p + 41) & 7; + if (qi < 4 || 7 < qi) continue; + t = I8(p) * P2_32 / 1000.0; + if (ubx_sys(U1(p + 56)) == SYS_GLO) t -= 10800.0 + utc_gpst; + if (t > tr) { + tr = t; + break; + } + } + if (tr < 0.0) return 0; + + tr = ROUND((tr + 0.08) / 0.1) * 0.1; + + /* adjust week handover */ + t = time2gpst(raw->time, &week); + if (tr < t - 302400.0) + week++; + else if (tr > t + 302400.0) + week--; + time = gpst2time(week, tr); + + char tstr[40]; + trace(4, "time=%s\n", time2str(time, tstr, 0)); + + for (i = 0, p = raw->buff + off; p - raw->buff < raw->len - 2; i++, p += len) { + /* quality indicator */ + qi = U1(p + 41) & 7; + if (qi < 4 || 7 < qi) continue; + + if (type == 6) { + if (!(sys = ubx_sys(U1(p + 56)))) { + trace(2, "ubx trkd5: system error\n"); + continue; + } + prn = U1(p + 57) + (sys == SYS_QZS ? 192 : 0); + frq = U1(p + 59) - 7; + } else { + prn = U1(p + 34); + sys = prn < MINPRNSBS ? SYS_GPS : SYS_SBS; } - for (i=0,p=raw->buff+off;p-raw->bufflen-2;i++,p+=len) { - qi=U1(p+41)&7; - if (qi<4||7tr) {tr=t; break;} + if (!(sat = satno(sys, prn))) { + trace(2, "ubx trkd5 sat number error: sys=%2d prn=%2d\n", sys, prn); + continue; } - if (tr<0.0) return 0; - - tr=ROUND((tr+0.08)/0.1)*0.1; - - /* adjust week handover */ - t=time2gpst(raw->time,&week); - if (trt+302400.0) week--; - time=gpst2time(week,tr); - - char tstr[40]; - trace(4,"time=%s\n",time2str(time,tstr,0)); - - for (i=0,p=raw->buff+off;p-raw->bufflen-2;i++,p+=len) { - - /* quality indicator */ - qi =U1(p+41)&7; - if (qi<4||7 gpst */ - - /* signal travel time */ - tau=tr-ts; - if (tau<-302400.0) tau+=604800.0; - else if (tau> 302400.0) tau-=604800.0; - - flag=U1(p+54); /* tracking status */ - adr=qi<6?0.0:I8(p+8)*P2_32+(flag&0x01?0.5:0.0); - dop=I4(p+16)*P2_10/4.0; - snr=U2(p+32)/256.0; - - if (snr<=10.0) raw->lockt[sat-1][1]=1.0; - + /* transmission time */ + ts = I8(p) * P2_32 / 1000.0; + if (sys == SYS_GLO) ts -= 10800.0 + utc_gpst; /* glot -> gpst */ + + /* signal travel time */ + tau = tr - ts; + if (tau < -302400.0) + tau += 604800.0; + else if (tau > 302400.0) + tau -= 604800.0; + + flag = U1(p + 54); /* tracking status */ + adr = qi < 6 ? 0.0 : I8(p + 8) * P2_32 + (flag & 0x01 ? 0.5 : 0.0); + dop = I4(p + 16) * P2_10 / 4.0; + snr = U2(p + 32) / 256.0; + + if (snr <= 10.0) raw->lockt[sat - 1][1] = 1.0; + #ifdef RTK_DISABLED /* for debug */ - trace(2,"[%2d] qi=%d sys=%d prn=%3d frq=%2d flag=%02X ts=%1.3f " - "snr=%4.1f dop=%9.3f adr=%13.3f %6.3f\n",U1(p+35),qi,U1(p+56), - prn,frq,flag,ts,snr,dop,adr, - adrs[sat-1]==0.0||dop==0.0?0.0:(adr-adrs[sat-1])-dop); + trace(2, + "[%2d] qi=%d sys=%d prn=%3d frq=%2d flag=%02X ts=%1.3f " + "snr=%4.1f dop=%9.3f adr=%13.3f %6.3f\n", + U1(p + 35), qi, U1(p + 56), prn, frq, flag, ts, snr, dop, adr, + adrs[sat - 1] == 0.0 || dop == 0.0 ? 0.0 : (adr - adrs[sat - 1]) - dop); #endif - adrs[sat-1]=adr; - - /* check phase lock */ - if (!(flag&0x08)) continue; - - raw->obs.data[n].time=time; - raw->obs.data[n].sat=sat; - raw->obs.data[n].P[0]=tau*CLIGHT; - raw->obs.data[n].L[0]=-adr; - raw->obs.data[n].D[0]=(float)dop; - raw->obs.data[n].SNR[0]=snr; - raw->obs.data[n].code[0]=sys==SYS_CMP?CODE_L2I:CODE_L1C; - raw->obs.data[n].LLI[0]=raw->lockt[sat-1][1]>0.0?1:0; - raw->lockt[sat-1][1]=0.0; - - for (j=1;jobs.data[n].L[j]=raw->obs.data[n].P[j]=0.0; - raw->obs.data[n].D[j]=raw->obs.data[n].SNR[j]=0.0; - raw->obs.data[n].LLI[j]=0; - raw->obs.data[n].code[j]=CODE_NONE; - } - n++; - } - if (n<=0) return 0; - raw->time=time; - raw->obs.n=n; - return 1; + adrs[sat - 1] = adr; + + /* check phase lock */ + if (!(flag & 0x08)) continue; + + raw->obs.data[n].time = time; + raw->obs.data[n].sat = sat; + raw->obs.data[n].P[0] = tau * CLIGHT; + raw->obs.data[n].L[0] = -adr; + raw->obs.data[n].D[0] = (float)dop; + raw->obs.data[n].SNR[0] = snr; + raw->obs.data[n].code[0] = sys == SYS_CMP ? CODE_L2I : CODE_L1C; + raw->obs.data[n].LLI[0] = raw->lockt[sat - 1][1] > 0.0 ? 1 : 0; + raw->lockt[sat - 1][1] = 0.0; + + for (j = 1; j < NFREQ + NEXOBS; j++) { + raw->obs.data[n].L[j] = raw->obs.data[n].P[j] = 0.0; + raw->obs.data[n].D[j] = raw->obs.data[n].SNR[j] = 0.0; + raw->obs.data[n].LLI[j] = 0; + raw->obs.data[n].code[j] = CODE_NONE; + } + n++; + } + if (n <= 0) return 0; + raw->time = time; + raw->obs.n = n; + return 1; } /* UTC 8-bit week -> full week -----------------------------------------------*/ -static void adj_utcweek(gtime_t time, double *utc) -{ - int week; - - time2gpst(time,&week); - utc[3]+=week/256*256; - if (utc[3]week+127) utc[3]-=256.0; - utc[5]+=utc[3]/256*256; - if (utc[5]utc[3]+127) utc[5]-=256.0; +static void adj_utcweek(gtime_t time, double *utc) { + int week; + + time2gpst(time, &week); + utc[3] += week / 256 * 256; + if (utc[3] < week - 127) + utc[3] += 256.0; + else if (utc[3] > week + 127) + utc[3] -= 256.0; + utc[5] += utc[3] / 256 * 256; + if (utc[5] < utc[3] - 127) + utc[5] += 256.0; + else if (utc[5] > utc[3] + 127) + utc[5] -= 256.0; } /* decode GPS/QZSS ephemeris -------------------------------------------------*/ -static int decode_eph(raw_t *raw, int sat) -{ - eph_t eph={0}; - int sys = satsys(sat, NULL); - if (!decode_frame(raw->subfrm[sat-1],sys,&eph,NULL,NULL,NULL)) return 0; - - if (!strstr(raw->opt,"-EPHALL")) { - if (eph.iode==raw->nav.eph[sat-1].iode&& - eph.iodc==raw->nav.eph[sat-1].iodc&& - timediff(eph.toe,raw->nav.eph[sat-1].toe)==0.0&& - timediff(eph.toc,raw->nav.eph[sat-1].toc)==0.0) return 0; - } - eph.sat=sat; - raw->nav.eph[sat-1]=eph; - raw->ephsat=sat; - raw->ephset=0; - return 2; +static int decode_eph(raw_t *raw, int sat) { + eph_t eph = {0}; + int sys = satsys(sat, NULL); + if (!decode_frame(raw->subfrm[sat - 1], sys, &eph, NULL, NULL, NULL)) return 0; + + if (!strstr(raw->opt, "-EPHALL")) { + if (eph.iode == raw->nav.eph[sat - 1].iode && eph.iodc == raw->nav.eph[sat - 1].iodc && + timediff(eph.toe, raw->nav.eph[sat - 1].toe) == 0.0 && + timediff(eph.toc, raw->nav.eph[sat - 1].toc) == 0.0) + return 0; + } + eph.sat = sat; + raw->nav.eph[sat - 1] = eph; + raw->ephsat = sat; + raw->ephset = 0; + return 2; } /* decode GPS/QZSS ION/UTC parameters ----------------------------------------*/ -static int decode_ionutc(raw_t *raw, int sat) -{ - double ion[8],utc[8]; - int sys=satsys(sat,NULL); - if (!decode_frame(raw->subfrm[sat-1],sys,NULL,NULL,ion,utc)) return 0; - - adj_utcweek(raw->time,utc); - if (sys==SYS_QZS) { - matcpy(raw->nav.ion_qzs,ion,8,1); - matcpy(raw->nav.utc_qzs,utc,8,1); - } - else { - matcpy(raw->nav.ion_gps,ion,8,1); - matcpy(raw->nav.utc_gps,utc,8,1); - } - return 9; +static int decode_ionutc(raw_t *raw, int sat) { + double ion[8], utc[8]; + int sys = satsys(sat, NULL); + if (!decode_frame(raw->subfrm[sat - 1], sys, NULL, NULL, ion, utc)) return 0; + + adj_utcweek(raw->time, utc); + if (sys == SYS_QZS) { + matcpy(raw->nav.ion_qzs, ion, 8, 1); + matcpy(raw->nav.utc_qzs, utc, 8, 1); + } else { + matcpy(raw->nav.ion_gps, ion, 8, 1); + matcpy(raw->nav.utc_gps, utc, 8, 1); + } + return 9; } /* decode GPS/QZSS navigation data -------------------------------------------*/ -static int decode_nav(raw_t *raw, int sat, int off) -{ - uint8_t *p=raw->buff+6+off,buff[30]; - int i,id,ret; - - if (raw->len<48+off) { - trace(2,"ubx rxmsfrbx nav length error: sat=%d len=%d\n",sat,raw->len); - return -1; - } - if ((U4(p)>>24)==PREAMB_CNAV) { - trace(3,"ubx rxmsfrbx nav unsupported sat=%d len=%d\n",sat,raw->len); - return 0; - } - for (i=0;i<10;i++,p+=4) { /* 24 x 10 bits w/o parity */ - setbitu(buff,24*i,24,U4(p)>>6); - } - id=getbitu(buff,43,3); - if (id<1||id>5) { - trace(2,"ubx rxmsfrbx nav subframe id error: sat=%d id=%d\n",sat,id); - return -1; - } - memcpy(raw->subfrm[sat-1]+(id-1)*30,buff,30); - - if (id==3) { - return decode_eph(raw,sat); - } - if (id==4||id==5) { - ret=decode_ionutc(raw,sat); - memset(raw->subfrm[sat-1]+(id-1)*30,0,30); - return ret; - } +static int decode_nav(raw_t *raw, int sat, int off) { + uint8_t *p = raw->buff + 6 + off, buff[30]; + int i, id, ret; + + if (raw->len < 48 + off) { + trace(2, "ubx rxmsfrbx nav length error: sat=%d len=%d\n", sat, raw->len); + return -1; + } + if ((U4(p) >> 24) == PREAMB_CNAV) { + trace(3, "ubx rxmsfrbx nav unsupported sat=%d len=%d\n", sat, raw->len); return 0; + } + for (i = 0; i < 10; i++, p += 4) { /* 24 x 10 bits w/o parity */ + setbitu(buff, 24 * i, 24, U4(p) >> 6); + } + id = getbitu(buff, 43, 3); + if (id < 1 || id > 5) { + trace(2, "ubx rxmsfrbx nav subframe id error: sat=%d id=%d\n", sat, id); + return -1; + } + memcpy(raw->subfrm[sat - 1] + (id - 1) * 30, buff, 30); + + if (id == 3) { + return decode_eph(raw, sat); + } + if (id == 4 || id == 5) { + ret = decode_ionutc(raw, sat); + memset(raw->subfrm[sat - 1] + (id - 1) * 30, 0, 30); + return ret; + } + return 0; } /* decode Galileo I/NAV navigation data --------------------------------------*/ -static int decode_inav(raw_t *raw, int sat, int off) -{ - if (strstr(raw->opt, "-GALFNAV")) return 0; - eph_t eph={0}; - double ion[4]={0},utc[8]={0}; - uint8_t *p=raw->buff+6+off,buff[32],crc_buff[26]={0}; - int i,j,part1,page1,part2,page2,type; - - if (raw->len<40+off) { - trace(2,"ubx rxmsfrbx inav length error: sat=%d len=%d\n",sat,raw->len); - return -1; - } - if (raw->len<36+off) return 0; /* E5b I/NAV */ - - for (i=0;i<8;i++,p+=4) { - setbitu(buff,32*i,32,U4(p)); - } - part1=getbitu(buff ,0,1); - page1=getbitu(buff ,1,1); - part2=getbitu(buff,128,1); - page2=getbitu(buff,129,1); - - if (part1!=0||part2!=1) { - trace(3,"ubx rxmsfrbx inav page even/odd error: sat=%d\n",sat); - return -1; - } - if (page1==1||page2==1) return 0; /* alert page */ - - /* test crc (4(pad) + 114 + 82 bits) */ - for (i=0,j= 4;i<15;i++,j+=8) setbitu(crc_buff,j,8,getbitu(buff ,i*8,8)); - for (i=0,j=118;i<11;i++,j+=8) setbitu(crc_buff,j,8,getbitu(buff,i*8+128,8)); - if (rtk_crc24q(crc_buff,25)!=getbitu(buff,128+82,24)) { - trace(2,"ubx rxmsfrbx inav crc error: sat=%d\n",sat); - return -1; - } - type=getbitu(buff,2,6); /* word type */ - - if (type>6) return 0; - - /* save 128 (112:even+16:odd) bits word */ - for (i=0,j=2;i<14;i++,j+=8) { - raw->subfrm[sat-1][type*16+i]=getbitu(buff,j,8); - } - for (i=14,j=130;i<16;i++,j+=8) { - raw->subfrm[sat-1][type*16+i]=getbitu(buff,j,8); - } - if (type!=5) return 0; - if (!decode_gal_inav(raw->subfrm[sat-1],&eph,ion,utc)) return 0; - - if (eph.sat!=sat) { - trace(2,"ubx rxmsfrbx inav satellite error: sat=%d %d\n",sat,eph.sat); - return -1; - } - eph.code|=(1<<0); /* data source: E1 */ - - adj_utcweek(raw->time,utc); - matcpy(raw->nav.ion_gal,ion,4,1); - matcpy(raw->nav.utc_gal,utc,8,1); - - if (!strstr(raw->opt,"-EPHALL")) { - if (eph.iode==raw->nav.eph[sat-1].iode&& - timediff(eph.toe,raw->nav.eph[sat-1].toe)==0.0&& - timediff(eph.toc,raw->nav.eph[sat-1].toc)==0.0) return 0; - } - raw->nav.eph[sat-1]=eph; - raw->ephsat=sat; - raw->ephset=0; /* 0:I/NAV */ - return 2; +static int decode_inav(raw_t *raw, int sat, int off) { + if (strstr(raw->opt, "-GALFNAV")) return 0; + eph_t eph = {0}; + double ion[4] = {0}, utc[8] = {0}; + uint8_t *p = raw->buff + 6 + off, buff[32], crc_buff[26] = {0}; + int i, j, part1, page1, part2, page2, type; + + if (raw->len < 40 + off) { + trace(2, "ubx rxmsfrbx inav length error: sat=%d len=%d\n", sat, raw->len); + return -1; + } + if (raw->len < 36 + off) return 0; /* E5b I/NAV */ + + for (i = 0; i < 8; i++, p += 4) { + setbitu(buff, 32 * i, 32, U4(p)); + } + part1 = getbitu(buff, 0, 1); + page1 = getbitu(buff, 1, 1); + part2 = getbitu(buff, 128, 1); + page2 = getbitu(buff, 129, 1); + + if (part1 != 0 || part2 != 1) { + trace(3, "ubx rxmsfrbx inav page even/odd error: sat=%d\n", sat); + return -1; + } + if (page1 == 1 || page2 == 1) return 0; /* alert page */ + + /* test crc (4(pad) + 114 + 82 bits) */ + for (i = 0, j = 4; i < 15; i++, j += 8) setbitu(crc_buff, j, 8, getbitu(buff, i * 8, 8)); + for (i = 0, j = 118; i < 11; i++, j += 8) setbitu(crc_buff, j, 8, getbitu(buff, i * 8 + 128, 8)); + if (rtk_crc24q(crc_buff, 25) != getbitu(buff, 128 + 82, 24)) { + trace(2, "ubx rxmsfrbx inav crc error: sat=%d\n", sat); + return -1; + } + type = getbitu(buff, 2, 6); /* word type */ + + if (type > 6) return 0; + + /* save 128 (112:even+16:odd) bits word */ + for (i = 0, j = 2; i < 14; i++, j += 8) { + raw->subfrm[sat - 1][type * 16 + i] = getbitu(buff, j, 8); + } + for (i = 14, j = 130; i < 16; i++, j += 8) { + raw->subfrm[sat - 1][type * 16 + i] = getbitu(buff, j, 8); + } + if (type != 5) return 0; + if (!decode_gal_inav(raw->subfrm[sat - 1], &eph, ion, utc)) return 0; + + if (eph.sat != sat) { + trace(2, "ubx rxmsfrbx inav satellite error: sat=%d %d\n", sat, eph.sat); + return -1; + } + eph.code |= (1 << 0); /* data source: E1 */ + + adj_utcweek(raw->time, utc); + matcpy(raw->nav.ion_gal, ion, 4, 1); + matcpy(raw->nav.utc_gal, utc, 8, 1); + + if (!strstr(raw->opt, "-EPHALL")) { + if (eph.iode == raw->nav.eph[sat - 1].iode && + timediff(eph.toe, raw->nav.eph[sat - 1].toe) == 0.0 && + timediff(eph.toc, raw->nav.eph[sat - 1].toc) == 0.0) + return 0; + } + raw->nav.eph[sat - 1] = eph; + raw->ephsat = sat; + raw->ephset = 0; /* 0:I/NAV */ + return 2; } // Decode Galileo F/NAV navigation data -------------------------------------- -static int decode_fnav(raw_t *raw, int sat, int off) -{ - if (strstr(raw->opt, "-GALINAV")) return 0; +static int decode_fnav(raw_t *raw, int sat, int off) { + if (strstr(raw->opt, "-GALINAV")) return 0; - if (raw->len < 40 + off) { - trace(2,"ubx rxmsfrbx fnav length error: sat=%d len=%d\n", sat, raw->len); - return -1; - } + if (raw->len < 40 + off) { + trace(2, "ubx rxmsfrbx fnav length error: sat=%d len=%d\n", sat, raw->len); + return -1; + } - uint8_t buff[32]; - for (int i = 0; i < 8; i++) { - setbitu(buff, 32 * i, 32, U4(raw->buff + 6 + off + 4 * i)); // 244 bits page. - } - int type = getbitu(buff, 0, 6); // Page type. - if (type == 63) return 0; // Dummy page. - if (type < 1 || type > 6) { - trace(2, "ubx rxmsfrbx fnav page type error: sat=%d type=%d\n", sat, type); - return -1; - } + uint8_t buff[32]; + for (int i = 0; i < 8; i++) { + setbitu(buff, 32 * i, 32, U4(raw->buff + 6 + off + 4 * i)); // 244 bits page. + } + int type = getbitu(buff, 0, 6); // Page type. + if (type == 63) return 0; // Dummy page. + if (type < 1 || type > 6) { + trace(2, "ubx rxmsfrbx fnav page type error: sat=%d type=%d\n", sat, type); + return -1; + } - // Save 244 bits page (31 bytes * 6 page). - memcpy(raw->subfrm[sat - 1] + 128 + (type - 1) * 31, buff, 31); + // Save 244 bits page (31 bytes * 6 page). + memcpy(raw->subfrm[sat - 1] + 128 + (type - 1) * 31, buff, 31); - if (type != 4) return 0; - eph_t eph = {0}; - double ion[4] = {0}, utc[8] = {0}; - if (!decode_gal_fnav(raw->subfrm[sat - 1] + 128, &eph, ion, utc)) return 0; + if (type != 4) return 0; + eph_t eph = {0}; + double ion[4] = {0}, utc[8] = {0}; + if (!decode_gal_fnav(raw->subfrm[sat - 1] + 128, &eph, ion, utc)) return 0; - if (eph.sat != sat) { - trace(2,"ubx rxmsfrbx fnav satellite error: sat=%d %d\n", sat, eph.sat); - return -1; - } - // Data source: E5a. - eph.code |= (1 << 1) | (1 << 8); + if (eph.sat != sat) { + trace(2, "ubx rxmsfrbx fnav satellite error: sat=%d %d\n", sat, eph.sat); + return -1; + } + // Data source: E5a. + eph.code |= (1 << 1) | (1 << 8); - adj_utcweek(raw->time, utc); - matcpy(raw->nav.ion_gal, ion, 4, 1); - matcpy(raw->nav.utc_gal, utc, 8, 1); + adj_utcweek(raw->time, utc); + matcpy(raw->nav.ion_gal, ion, 4, 1); + matcpy(raw->nav.utc_gal, utc, 8, 1); - if (!strstr(raw->opt, "-EPHALL")) { - if (eph.iode == raw->nav.eph[sat - 1 + MAXSAT].iode && - fabs(timediff(eph.toe, raw->nav.eph[sat - 1 + MAXSAT].toe)) < 1e-9 && - fabs(timediff(eph.toc, raw->nav.eph[sat - 1 + MAXSAT].toc)) < 1e-9) - return 0; - } - raw->nav.eph[sat - 1 + MAXSAT] = eph; - raw->ephsat = sat; - raw->ephset = 1; // 1:F/NAV - return 2; + if (!strstr(raw->opt, "-EPHALL")) { + if (eph.iode == raw->nav.eph[sat - 1 + MAXSAT].iode && + fabs(timediff(eph.toe, raw->nav.eph[sat - 1 + MAXSAT].toe)) < 1e-9 && + fabs(timediff(eph.toc, raw->nav.eph[sat - 1 + MAXSAT].toc)) < 1e-9) + return 0; + } + raw->nav.eph[sat - 1 + MAXSAT] = eph; + raw->ephsat = sat; + raw->ephset = 1; // 1:F/NAV + return 2; } /* decode BDS navigation data ------------------------------------------------*/ -static int decode_cnav(raw_t *raw, int sat, int off) -{ - eph_t eph={0}; - double ion[8],utc[8]; - uint8_t *p=raw->buff+6+off,buff[38]={0}; - int i,id,pgn,prn; - - if (raw->len<48+off) { - trace(2,"ubx rxmsfrbx cnav length error: sat=%d len=%d\n",sat,raw->len); - return -1; - } - for (i=0;i<10;i++,p+=4) { - setbitu(buff,30*i,30,U4(p)); - } - id=getbitu(buff,15,3); /* subframe ID */ - if (id<1||5=6&&prn<=58) { /* IGSO/MEO */ - memcpy(raw->subfrm[sat-1]+(id-1)*38,buff,38); - - if (id==3) { - if (!decode_bds_d1(raw->subfrm[sat-1],&eph,NULL,NULL)) return 0; - } - else if (id==5) { - if (!decode_bds_d1(raw->subfrm[sat-1],NULL,ion,utc)) return 0; - matcpy(raw->nav.ion_cmp,ion,8,1); - matcpy(raw->nav.utc_cmp,utc,8,1); - return 9; - } - else return 0; - } - else { /* GEO */ - if (id == 1) { - pgn = getbitu(buff, 42, 4); // Page numuber. - if (pgn < 1 || pgn > 10) return 0; - memcpy(raw->subfrm[sat-1]+(pgn-1)*38,buff,38); - if (pgn!=10) return 0; - if (!decode_bds_d2(raw->subfrm[sat-1],&eph,NULL)) return 0; - } - else if (id == 5) { - int pgn = getbitu(buff, 43, 7); // Page number. - if (pgn != 102) return 0; - memcpy(raw->subfrm[sat-1]+10*38,buff,38); - if (!decode_bds_d2(raw->subfrm[sat-1],NULL,utc)) return 0; - matcpy(raw->nav.utc_cmp,utc,8,1); - return 9; - } - else return 0; - } - if (!strstr(raw->opt,"-EPHALL")) { - if (timediff(eph.toe,raw->nav.eph[sat-1].toe)==0.0) return 0; - } - eph.sat=sat; - raw->nav.eph[sat-1]=eph; - raw->ephsat=sat; - raw->ephset=0; - return 2; +static int decode_cnav(raw_t *raw, int sat, int off) { + eph_t eph = {0}; + double ion[8], utc[8]; + uint8_t *p = raw->buff + 6 + off, buff[38] = {0}; + int i, id, pgn, prn; + + if (raw->len < 48 + off) { + trace(2, "ubx rxmsfrbx cnav length error: sat=%d len=%d\n", sat, raw->len); + return -1; + } + for (i = 0; i < 10; i++, p += 4) { + setbitu(buff, 30 * i, 30, U4(p)); + } + id = getbitu(buff, 15, 3); /* subframe ID */ + if (id < 1 || 5 < id) { + trace(2, "ubx rxmsfrbx cnav subframe id error: sat=%2d\n", sat); + return -1; + } + satsys(sat, &prn); + + if (prn >= 6 && prn <= 58) { /* IGSO/MEO */ + memcpy(raw->subfrm[sat - 1] + (id - 1) * 38, buff, 38); + + if (id == 3) { + if (!decode_bds_d1(raw->subfrm[sat - 1], &eph, NULL, NULL)) return 0; + } else if (id == 5) { + if (!decode_bds_d1(raw->subfrm[sat - 1], NULL, ion, utc)) return 0; + matcpy(raw->nav.ion_cmp, ion, 8, 1); + matcpy(raw->nav.utc_cmp, utc, 8, 1); + return 9; + } else + return 0; + } else { /* GEO */ + if (id == 1) { + pgn = getbitu(buff, 42, 4); // Page numuber. + if (pgn < 1 || pgn > 10) return 0; + memcpy(raw->subfrm[sat - 1] + (pgn - 1) * 38, buff, 38); + if (pgn != 10) return 0; + if (!decode_bds_d2(raw->subfrm[sat - 1], &eph, NULL)) return 0; + } else if (id == 5) { + int pgn = getbitu(buff, 43, 7); // Page number. + if (pgn != 102) return 0; + memcpy(raw->subfrm[sat - 1] + 10 * 38, buff, 38); + if (!decode_bds_d2(raw->subfrm[sat - 1], NULL, utc)) return 0; + matcpy(raw->nav.utc_cmp, utc, 8, 1); + return 9; + } else + return 0; + } + if (!strstr(raw->opt, "-EPHALL")) { + if (timediff(eph.toe, raw->nav.eph[sat - 1].toe) == 0.0) return 0; + } + eph.sat = sat; + raw->nav.eph[sat - 1] = eph; + raw->ephsat = sat; + raw->ephset = 0; + return 2; } /* decode GLONASS navigation data --------------------------------------------*/ -static int decode_gnav(raw_t *raw, int sat, int off, int frq) -{ - geph_t geph={0}; - double utc_glo[8]={0}; - int i,j,k,m,prn; - uint8_t *p=raw->buff+6+off,buff[64],*fid; - - satsys(sat,&prn); - - if (raw->len<24+off) { - trace(2,"ubx rxmsfrbx gnav length error: len=%d\n",raw->len); - return -1; - } - for (i=k=0;i<4;i++,p+=4) for (j=0;j<4;j++) { - buff[k++]=p[3-j]; - } - /* test hamming of GLONASS string */ - if (!test_glostr(buff)) { - trace(2,"ubx rxmsfrbx gnav hamming error: sat=%2d\n",sat); - return -1; - } - m=getbitu(buff,1,4); - if (m<1||15subfrm[sat-1]+150; - if (fid[0]!=buff[12]||fid[1]!=buff[13]) { - for (i=0;i<4;i++) memset(raw->subfrm[sat-1]+i*10,0,10); - memcpy(fid,buff+12,2); /* save frame-id */ - } - memcpy(raw->subfrm[sat-1]+(m-1)*10,buff,10); - - if (m==4) { - /* decode GLONASS ephemeris strings */ - geph.tof=raw->time; - if (!decode_glostr(raw->subfrm[sat-1],&geph,NULL)||geph.sat!=sat) { - return 0; - } - geph.frq=frq-7; - - if (!strstr(raw->opt,"-EPHALL")) { - if (geph.iode==raw->nav.geph[prn-1].iode) return 0; - } - raw->nav.geph[prn-1]=geph; - raw->ephsat=sat; - raw->ephset=0; - return 2; +static int decode_gnav(raw_t *raw, int sat, int off, int frq) { + geph_t geph = {0}; + double utc_glo[8] = {0}; + int i, j, k, m, prn; + uint8_t *p = raw->buff + 6 + off, buff[64], *fid; + + satsys(sat, &prn); + + if (raw->len < 24 + off) { + trace(2, "ubx rxmsfrbx gnav length error: len=%d\n", raw->len); + return -1; + } + for (i = k = 0; i < 4; i++, p += 4) + for (j = 0; j < 4; j++) { + buff[k++] = p[3 - j]; + } + /* test hamming of GLONASS string */ + if (!test_glostr(buff)) { + trace(2, "ubx rxmsfrbx gnav hamming error: sat=%2d\n", sat); + return -1; + } + m = getbitu(buff, 1, 4); + if (m < 1 || 15 < m) { + trace(2, "ubx rxmsfrbx gnav string no error: sat=%2d\n", sat); + return -1; + } + /* flush frame buffer if frame-ID changed */ + fid = raw->subfrm[sat - 1] + 150; + if (fid[0] != buff[12] || fid[1] != buff[13]) { + for (i = 0; i < 4; i++) memset(raw->subfrm[sat - 1] + i * 10, 0, 10); + memcpy(fid, buff + 12, 2); /* save frame-id */ + } + memcpy(raw->subfrm[sat - 1] + (m - 1) * 10, buff, 10); + + if (m == 4) { + /* decode GLONASS ephemeris strings */ + geph.tof = raw->time; + if (!decode_glostr(raw->subfrm[sat - 1], &geph, NULL) || geph.sat != sat) { + return 0; } - else if (m==5) { - if (!decode_glostr(raw->subfrm[sat-1],NULL,utc_glo)) return 0; - matcpy(raw->nav.utc_glo,utc_glo,8,1); - return 9; + geph.frq = frq - 7; + + if (!strstr(raw->opt, "-EPHALL")) { + if (geph.iode == raw->nav.geph[prn - 1].iode) return 0; } - return 0; + raw->nav.geph[prn - 1] = geph; + raw->ephsat = sat; + raw->ephset = 0; + return 2; + } else if (m == 5) { + if (!decode_glostr(raw->subfrm[sat - 1], NULL, utc_glo)) return 0; + matcpy(raw->nav.utc_glo, utc_glo, 8, 1); + return 9; + } + return 0; } /* decode SBAS navigation data -----------------------------------------------*/ -static int decode_snav(raw_t *raw, int prn, int off) -{ - int i,tow,week; - uint8_t *p=raw->buff+6+off,buff[32]; - - if (raw->len<40+off) { - trace(2,"ubx rxmsfrbx snav length error: len=%d\n",raw->len); - return -1; - } - tow=(int)time2gpst(timeadd(raw->time,-1.0),&week); - raw->sbsmsg.prn=prn; - raw->sbsmsg.tow=tow; - raw->sbsmsg.week=week; - for (i=0;i<8;i++,p+=4) { - setbitu(buff,32*i,32,U4(p)); - } - memcpy(raw->sbsmsg.msg,buff,29); - raw->sbsmsg.msg[28]&=0xC0; - return 3; +static int decode_snav(raw_t *raw, int prn, int off) { + int i, tow, week; + uint8_t *p = raw->buff + 6 + off, buff[32]; + + if (raw->len < 40 + off) { + trace(2, "ubx rxmsfrbx snav length error: len=%d\n", raw->len); + return -1; + } + tow = (int)time2gpst(timeadd(raw->time, -1.0), &week); + raw->sbsmsg.prn = prn; + raw->sbsmsg.tow = tow; + raw->sbsmsg.week = week; + for (i = 0; i < 8; i++, p += 4) { + setbitu(buff, 32 * i, 32, U4(p)); + } + memcpy(raw->sbsmsg.msg, buff, 29); + raw->sbsmsg.msg[28] &= 0xC0; + return 3; } /* decode UBX-RXM-SFRBX: raw subframe data (ref [3][4][5]) -------------------*/ -static int decode_rxmsfrbx(raw_t *raw) -{ - uint8_t *p=raw->buff+6; - int prn,sat,sys; - - trace(4,"decode_rxmsfrbx: len=%d\n",raw->len); - - if (raw->outtype) { - sprintf(raw->msgtype,"UBX RXM-SFRBX (%4d): sys=%d prn=%3d sigid=%d",raw->len, - U1(p),U1(p+1),U1(p+2)); - } - if (!(sys=ubx_sys(U1(p)))) { - trace(2,"ubx rxmsfrbx sys id error: sys=%d\n",U1(p)); - return -1; - } - prn=U1(p+1)+((sys==SYS_QZS)?192:0); - if (!(sat=satno(sys,prn))) { - if (sys==SYS_GLO&&prn==255) { - return 0; /* suppress error for unknown GLONASS satellite */ - } - trace(2,"ubx rxmsfrbx sat number error: sys=%d prn=%d\n",sys,prn); - return -1; - } - if (sys==SYS_QZS&&raw->len==52) { /* QZSS L1S */ - sys=SYS_SBS; - prn-=10; - } - switch (sys) { - case SYS_GPS: return decode_nav (raw,sat,8); - case SYS_QZS: return decode_nav (raw,sat,8); - case SYS_GAL: - if (U1(p + 2) == 8) { - // Signal E6B, E6 CNAV. - trace(3, "ubx rxmsfrbx Galileo E6 CNAV unsupported: sys=%d prn=%3d sigid=%d\n", U1(p), U1(p + 1), U1(p + 2)); - return 0; - } - if (U1(p + 2) == 3) { - // Signal E5a, F/NAV - return decode_fnav(raw, sat, 8); - } - return decode_inav(raw, sat, 8); - case SYS_CMP: - if (U1(p + 2) == 6) { - // Signal B1C, B-CNAV1. - trace(3, "ubx rxmsfrbx BDS B-CNAV1 unsupported: sys=%d prn=%3d sigid=%d\n", U1(p), U1(p + 1), U1(p + 2)); - return 0; - } - if (U1(p + 2) == 8) { - // Signal B2a, B-CNAV2. - trace(3, "ubx rxmsfrbx BDS B-CNAV2 unsupported: sys=%d prn=%3d sigid=%d\n", U1(p), U1(p + 1), U1(p + 2)); - return 0; - } - return decode_cnav(raw, sat, 8); - case SYS_GLO: return decode_gnav(raw,sat,8,U1(p+3)); - case SYS_SBS: return decode_snav(raw,prn,8); - } - return 0; +static int decode_rxmsfrbx(raw_t *raw) { + uint8_t *p = raw->buff + 6; + int prn, sat, sys; + + trace(4, "decode_rxmsfrbx: len=%d\n", raw->len); + + if (raw->outtype) { + sprintf(raw->msgtype, "UBX RXM-SFRBX (%4d): sys=%d prn=%3d sigid=%d", raw->len, U1(p), + U1(p + 1), U1(p + 2)); + } + if (!(sys = ubx_sys(U1(p)))) { + trace(2, "ubx rxmsfrbx sys id error: sys=%d\n", U1(p)); + return -1; + } + prn = U1(p + 1) + ((sys == SYS_QZS) ? 192 : 0); + if (!(sat = satno(sys, prn))) { + if (sys == SYS_GLO && prn == 255) { + return 0; /* suppress error for unknown GLONASS satellite */ + } + trace(2, "ubx rxmsfrbx sat number error: sys=%d prn=%d\n", sys, prn); + return -1; + } + if (sys == SYS_QZS && raw->len == 52) { /* QZSS L1S */ + sys = SYS_SBS; + prn -= 10; + } + switch (sys) { + case SYS_GPS: + return decode_nav(raw, sat, 8); + case SYS_QZS: + return decode_nav(raw, sat, 8); + case SYS_GAL: + if (U1(p + 2) == 8) { + // Signal E6B, E6 CNAV. + trace(3, "ubx rxmsfrbx Galileo E6 CNAV unsupported: sys=%d prn=%3d sigid=%d\n", U1(p), + U1(p + 1), U1(p + 2)); + return 0; + } + if (U1(p + 2) == 3) { + // Signal E5a, F/NAV + return decode_fnav(raw, sat, 8); + } + return decode_inav(raw, sat, 8); + case SYS_CMP: + if (U1(p + 2) == 6) { + // Signal B1C, B-CNAV1. + trace(3, "ubx rxmsfrbx BDS B-CNAV1 unsupported: sys=%d prn=%3d sigid=%d\n", U1(p), + U1(p + 1), U1(p + 2)); + return 0; + } + if (U1(p + 2) == 8) { + // Signal B2a, B-CNAV2. + trace(3, "ubx rxmsfrbx BDS B-CNAV2 unsupported: sys=%d prn=%3d sigid=%d\n", U1(p), + U1(p + 1), U1(p + 2)); + return 0; + } + return decode_cnav(raw, sat, 8); + case SYS_GLO: + return decode_gnav(raw, sat, 8, U1(p + 3)); + case SYS_SBS: + return decode_snav(raw, prn, 8); + } + return 0; } /* decode UBX-TRK-SFRBX: subframe buffer extension (unofficial) --------------*/ -static int decode_trksfrbx(raw_t *raw) -{ - uint8_t *p=raw->buff+6; - int prn,sat,sys; - - if (raw->outtype) { - sprintf(raw->msgtype,"UBX TRK-SFRBX (%4d): sys=%d prn=%3d",raw->len, - U1(p+1),U1(p+2)); - } - if (!(sys=ubx_sys(U1(p+1)))) { - trace(2,"ubx trksfrbx sys id error: sys=%d\n",U1(p+1)); - return -1; - } - prn=U1(p+2)+(sys==SYS_QZS?192:0); - if (!(sat=satno(sys,prn))) { - trace(2,"ubx trksfrbx sat number error: sys=%d prn=%d\n",sys,prn); - return -1; - } - switch (sys) { - case SYS_GPS: return decode_nav (raw,sat,13); - case SYS_QZS: return decode_nav (raw,sat,13); - case SYS_GAL: return decode_inav(raw,sat,13); - case SYS_CMP: return decode_cnav(raw,sat,13); - case SYS_GLO: return decode_gnav(raw,sat,13,U1(p+4)); - case SYS_SBS: return decode_snav(raw,sat,13); - } - return 0; +static int decode_trksfrbx(raw_t *raw) { + uint8_t *p = raw->buff + 6; + int prn, sat, sys; + + if (raw->outtype) { + sprintf(raw->msgtype, "UBX TRK-SFRBX (%4d): sys=%d prn=%3d", raw->len, U1(p + 1), U1(p + 2)); + } + if (!(sys = ubx_sys(U1(p + 1)))) { + trace(2, "ubx trksfrbx sys id error: sys=%d\n", U1(p + 1)); + return -1; + } + prn = U1(p + 2) + (sys == SYS_QZS ? 192 : 0); + if (!(sat = satno(sys, prn))) { + trace(2, "ubx trksfrbx sat number error: sys=%d prn=%d\n", sys, prn); + return -1; + } + switch (sys) { + case SYS_GPS: + return decode_nav(raw, sat, 13); + case SYS_QZS: + return decode_nav(raw, sat, 13); + case SYS_GAL: + return decode_inav(raw, sat, 13); + case SYS_CMP: + return decode_cnav(raw, sat, 13); + case SYS_GLO: + return decode_gnav(raw, sat, 13, U1(p + 4)); + case SYS_SBS: + return decode_snav(raw, sat, 13); + } + return 0; } /* decode UBX-RXM-SFRB: subframe buffer (GPS/SBAS) ---------------------------*/ -static int decode_rxmsfrb(raw_t *raw) -{ - uint32_t words[10]; - uint8_t *p=raw->buff+6,buff[30]; - int i,sys,prn,sat,id; - - if (raw->outtype) { - sprintf(raw->msgtype,"UBX RXM-SFRB (%4d): prn=%2d",raw->len,U1(p+1)); - } - if (raw->len<42) { - trace(2,"ubx rxmsfrb length error: len=%d\n",raw->len); - return -1; - } - prn=U1(p+1); - sys=(prn>=MINPRNSBS)?SYS_SBS:SYS_GPS; - - if (!(sat=satno(sys,prn))) { - trace(2,"ubx rxmsfrb satellite error: prn=%d\n",prn); - return -1; - } - if (sys==SYS_GPS) { - for (i=0,p+=2;i<10;i++,p+=4) setbitu(buff,24*i,24,U4(p)); - id=getbitu(buff,43,3); - if (id>=1&&id<=5) { - memcpy(raw->subfrm[sat-1]+(id-1)*30,buff,30); - if (id==3) return decode_eph (raw,sat); - else if (id==4) return decode_ionutc(raw,sat); - } - } - else { - for (i=0,p+=2;i<10;i++,p+=4) words[i]=U4(p); - if (!sbsdecodemsg(raw->time,prn,words,&raw->sbsmsg)) return 0; - return 3; - } - return 0; +static int decode_rxmsfrb(raw_t *raw) { + uint32_t words[10]; + uint8_t *p = raw->buff + 6, buff[30]; + int i, sys, prn, sat, id; + + if (raw->outtype) { + sprintf(raw->msgtype, "UBX RXM-SFRB (%4d): prn=%2d", raw->len, U1(p + 1)); + } + if (raw->len < 42) { + trace(2, "ubx rxmsfrb length error: len=%d\n", raw->len); + return -1; + } + prn = U1(p + 1); + sys = (prn >= MINPRNSBS) ? SYS_SBS : SYS_GPS; + + if (!(sat = satno(sys, prn))) { + trace(2, "ubx rxmsfrb satellite error: prn=%d\n", prn); + return -1; + } + if (sys == SYS_GPS) { + for (i = 0, p += 2; i < 10; i++, p += 4) setbitu(buff, 24 * i, 24, U4(p)); + id = getbitu(buff, 43, 3); + if (id >= 1 && id <= 5) { + memcpy(raw->subfrm[sat - 1] + (id - 1) * 30, buff, 30); + if (id == 3) + return decode_eph(raw, sat); + else if (id == 4) + return decode_ionutc(raw, sat); + } + } else { + for (i = 0, p += 2; i < 10; i++, p += 4) words[i] = U4(p); + if (!sbsdecodemsg(raw->time, prn, words, &raw->sbsmsg)) return 0; + return 3; + } + return 0; } /* decode ubx-tim-tm2: time mark data ----------------------------------------*/ -static int decode_timtm2(raw_t *raw) -{ - gtime_t eventime; - char ch, flags; - unsigned int count, wnR, wnF; - unsigned long towMsR, towSubMsR, towMsF, towSubMsF, accEst; - int time, timeBase, newRisingEdge, newFallingEdge; - unsigned char *p=raw->buff+6; - double tr[6],tf[6]; - - trace(4, "decode_timtm2: len=%d\n", raw->len); - - if (raw->outtype) { - sprintf(raw->msgtype, "UBX TIM-TM2 (%4d)", raw->len); - } - ch = U1(p); - flags = *(p+1); - count = U2(p+2); - wnR = U2(p+4); - wnF = U2(p+6); - towMsR = U4(p+8); - towSubMsR = U4(p+12); - towMsF = U4(p+16); - towSubMsF = U4(p+20); - accEst = U4(p+24); - - /* extract flags to variables */ - newFallingEdge = ((flags >> 2) & 0x01); - timeBase = ((flags >> 3) & 0x03); - time = ((flags >> 6) & 0x01); - newRisingEdge = ((flags >> 7) & 0x01); - - if (newFallingEdge) - { - eventime = gpst2time(wnF,towMsF*1E-3+towSubMsF*1E-9); - if (timeBase==2) /* if timeBase is UTC, convert to GPS */ - eventime = utc2gpst(eventime); - raw->obs.flag = 5; /* Event flag */ - raw->obs.data[0].eventime = eventime; - raw->obs.rcvcount = count; - raw->obs.tmcount++; - raw->obs.data[0].timevalid = time; - } else { - raw->obs.flag = 0; - } - time2epoch(gpst2time(wnR,towMsR*1E-3+towSubMsR*1E-9),tr); - time2epoch(gpst2time(wnF,towMsF*1E-3+towSubMsF*1E-9),tf); - trace(3,"time mark rise: %f:%f:%.3f\n",tr[3],tr[4],tr[5]); - trace(3,"time mark fall: %f:%f:%.3f\n",tf[3],tf[4],tf[5]); - return 0; +static int decode_timtm2(raw_t *raw) { + gtime_t eventime; + char ch, flags; + unsigned int count, wnR, wnF; + unsigned long towMsR, towSubMsR, towMsF, towSubMsF, accEst; + int time, timeBase, newRisingEdge, newFallingEdge; + unsigned char *p = raw->buff + 6; + double tr[6], tf[6]; + + trace(4, "decode_timtm2: len=%d\n", raw->len); + + if (raw->outtype) { + sprintf(raw->msgtype, "UBX TIM-TM2 (%4d)", raw->len); + } + ch = U1(p); + flags = *(p + 1); + count = U2(p + 2); + wnR = U2(p + 4); + wnF = U2(p + 6); + towMsR = U4(p + 8); + towSubMsR = U4(p + 12); + towMsF = U4(p + 16); + towSubMsF = U4(p + 20); + accEst = U4(p + 24); + + /* extract flags to variables */ + newFallingEdge = ((flags >> 2) & 0x01); + timeBase = ((flags >> 3) & 0x03); + time = ((flags >> 6) & 0x01); + newRisingEdge = ((flags >> 7) & 0x01); + + if (newFallingEdge) { + eventime = gpst2time(wnF, towMsF * 1E-3 + towSubMsF * 1E-9); + if (timeBase == 2) /* if timeBase is UTC, convert to GPS */ + eventime = utc2gpst(eventime); + raw->obs.flag = 5; /* Event flag */ + raw->obs.data[0].eventime = eventime; + raw->obs.rcvcount = count; + raw->obs.tmcount++; + raw->obs.data[0].timevalid = time; + } else { + raw->obs.flag = 0; + } + time2epoch(gpst2time(wnR, towMsR * 1E-3 + towSubMsR * 1E-9), tr); + time2epoch(gpst2time(wnF, towMsF * 1E-3 + towSubMsF * 1E-9), tf); + trace(3, "time mark rise: %f:%f:%.3f\n", tr[3], tr[4], tr[5]); + trace(3, "time mark fall: %f:%f:%.3f\n", tf[3], tf[4], tf[5]); + return 0; } /* decode ublox raw message --------------------------------------------------*/ -static int decode_ubx(raw_t *raw) -{ - int type=(U1(raw->buff+2)<<8)+U1(raw->buff+3); - - trace(3,"decode_ubx: type=%04x len=%d\n",type,raw->len); - - /* checksum */ - if (!checksum(raw->buff,raw->len)) { - trace(2,"ubx checksum error: type=%04x len=%d\n",type,raw->len); - return -1; - } - switch (type) { - case ID_RXMRAW : return decode_rxmraw (raw); - case ID_RXMRAWX : return decode_rxmrawx (raw); - case ID_RXMSFRB : return decode_rxmsfrb (raw); - case ID_RXMSFRBX: return decode_rxmsfrbx(raw); - case ID_NAVSOL : return decode_navsol (raw); - case ID_NAVTIME : return decode_navtime (raw); - case ID_TRKMEAS : return decode_trkmeas (raw); - case ID_TRKD5 : return decode_trkd5 (raw); - case ID_TRKSFRBX: return decode_trksfrbx(raw); - case ID_TIMTM2 : return decode_timtm2 (raw); - } - if (raw->outtype) { - sprintf(raw->msgtype,"UBX 0x%02X 0x%02X (%4d)",type>>8,type&0xFF, - raw->len); - } - return 0; +static int decode_ubx(raw_t *raw) { + int type = (U1(raw->buff + 2) << 8) + U1(raw->buff + 3); + + trace(3, "decode_ubx: type=%04x len=%d\n", type, raw->len); + + /* checksum */ + if (!checksum(raw->buff, raw->len)) { + trace(2, "ubx checksum error: type=%04x len=%d\n", type, raw->len); + return -1; + } + switch (type) { + case ID_RXMRAW: + return decode_rxmraw(raw); + case ID_RXMRAWX: + return decode_rxmrawx(raw); + case ID_RXMSFRB: + return decode_rxmsfrb(raw); + case ID_RXMSFRBX: + return decode_rxmsfrbx(raw); + case ID_NAVSOL: + return decode_navsol(raw); + case ID_NAVTIME: + return decode_navtime(raw); + case ID_TRKMEAS: + return decode_trkmeas(raw); + case ID_TRKD5: + return decode_trkd5(raw); + case ID_TRKSFRBX: + return decode_trksfrbx(raw); + case ID_TIMTM2: + return decode_timtm2(raw); + } + if (raw->outtype) { + sprintf(raw->msgtype, "UBX 0x%02X 0x%02X (%4d)", type >> 8, type & 0xFF, raw->len); + } + return 0; } /* sync code -----------------------------------------------------------------*/ -static int sync_ubx(uint8_t *buff, uint8_t data) -{ - buff[0]=buff[1]; buff[1]=data; - return buff[0]==UBXSYNC1&&buff[1]==UBXSYNC2; +static int sync_ubx(uint8_t *buff, uint8_t data) { + buff[0] = buff[1]; + buff[1] = data; + return buff[0] == UBXSYNC1 && buff[1] == UBXSYNC2; } /* input ublox raw message from stream ----------------------------------------- -* fetch next ublox raw data and input a message from stream -* args : raw_t *raw IO receiver raw data control struct -* uint8_t data I stream data (1 byte) -* return : status (-1: error message, 0: no message, 1: input observation data, -* 2: input ephemeris, 3: input sbas message, -* 9: input ion/utc parameter) -* -* notes : to specify input options, set raw->opt to the following option -* strings separated by spaces. -* -* -EPHALL : input all ephemerides -* -INVCP : invert polarity of carrier-phase -* -TADJ=tint : adjust time tags to multiples of tint (sec) -* -STD_SLIP=std: slip by std-dev of carrier phase under std -* -MAX_STD_CP=std: max std-dev of carrier phase -* -MULTICODE : preserve multiple signal codes for single freq -* -RCVSTDS : save receiver stdevs to unused rinex fields -* -GALINAV : select I/NAV for Galileo ephemeris (default: all) -* -GALFNAV : select F/NAV for Galileo ephemeris (default: all) -* -* -* The supported messages are as follows. -* -* UBX-RXM-RAW : raw measurement data -* UBX-RXM-RAWX : multi-gnss measurement data -* UBX-RXM-SFRB : subframe buffer -* UBX-RXM-SFRBX: subframe buffer extension -* -* UBX-TRK-MEAS and UBX-TRK-SFRBX are based on NEO-M8N (F/W 2.01). -* UBX-TRK-D5 is based on NEO-7N (F/W 1.00). They are not formally -* documented and not supported by u-blox. -* Users can use these messages by their own risk. -*-----------------------------------------------------------------------------*/ -extern int input_ubx(raw_t *raw, uint8_t data) -{ - trace(5,"input_ubx: data=%02x\n",data); - - /* synchronize frame */ - if (raw->nbyte==0) { - if (!sync_ubx(raw->buff,data)) return 0; - raw->nbyte=2; - return 0; - } - raw->buff[raw->nbyte++]=data; - - if (raw->nbyte==6) { - if ((raw->len=U2(raw->buff+4)+8)>MAXRAWLEN) { - trace(2,"ubx length error: len=%d\n",raw->len); - raw->nbyte=0; - return -1; - } + * fetch next ublox raw data and input a message from stream + * args : raw_t *raw IO receiver raw data control struct + * uint8_t data I stream data (1 byte) + * return : status (-1: error message, 0: no message, 1: input observation data, + * 2: input ephemeris, 3: input sbas message, + * 9: input ion/utc parameter) + * + * notes : to specify input options, set raw->opt to the following option + * strings separated by spaces. + * + * -EPHALL : input all ephemerides + * -INVCP : invert polarity of carrier-phase + * -TADJ=tint : adjust time tags to multiples of tint (sec) + * -STD_SLIP=std: slip by std-dev of carrier phase under std + * -MAX_STD_CP=std: max std-dev of carrier phase + * -MULTICODE : preserve multiple signal codes for single freq + * -RCVSTDS : save receiver stdevs to unused rinex fields + * -GALINAV : select I/NAV for Galileo ephemeris (default: all) + * -GALFNAV : select F/NAV for Galileo ephemeris (default: all) + * + * + * The supported messages are as follows. + * + * UBX-RXM-RAW : raw measurement data + * UBX-RXM-RAWX : multi-gnss measurement data + * UBX-RXM-SFRB : subframe buffer + * UBX-RXM-SFRBX: subframe buffer extension + * + * UBX-TRK-MEAS and UBX-TRK-SFRBX are based on NEO-M8N (F/W 2.01). + * UBX-TRK-D5 is based on NEO-7N (F/W 1.00). They are not formally + * documented and not supported by u-blox. + * Users can use these messages by their own risk. + *-----------------------------------------------------------------------------*/ +extern int input_ubx(raw_t *raw, uint8_t data) { + trace(5, "input_ubx: data=%02x\n", data); + + /* synchronize frame */ + if (raw->nbyte == 0) { + if (!sync_ubx(raw->buff, data)) return 0; + raw->nbyte = 2; + return 0; + } + raw->buff[raw->nbyte++] = data; + + if (raw->nbyte == 6) { + if ((raw->len = U2(raw->buff + 4) + 8) > MAXRAWLEN) { + trace(2, "ubx length error: len=%d\n", raw->len); + raw->nbyte = 0; + return -1; } - if (raw->nbyte<6||raw->nbytelen) return 0; - raw->nbyte=0; - - /* decode ublox raw message */ - return decode_ubx(raw); + } + if (raw->nbyte < 6 || raw->nbyte < raw->len) return 0; + raw->nbyte = 0; + + /* decode ublox raw message */ + return decode_ubx(raw); } /* input ublox raw message from file ------------------------------------------- -* fetch next ublox raw data and input a message from file -* args : raw_t *raw IO receiver raw data control struct -* FILE *fp I file pointer -* return : status(-2: end of file, -1...9: same as above) -*-----------------------------------------------------------------------------*/ -extern int input_ubxf(raw_t *raw, FILE *fp) -{ - int i,data; - - trace(4,"input_ubxf:\n"); - - /* synchronize frame */ - if (raw->nbyte==0) { - for (i=0;;i++) { - if ((data=fgetc(fp))==EOF) return -2; - if (sync_ubx(raw->buff,(uint8_t)data)) break; - if (i>=4096) return 0; - } - } - if (fread(raw->buff+2,1,4,fp)<4) return -2; - raw->nbyte=6; - - if ((raw->len=U2(raw->buff+4)+8)>MAXRAWLEN) { - trace(2,"ubx length error: len=%d\n",raw->len); - raw->nbyte=0; - return -1; - } - if (fread(raw->buff+6,1,raw->len-6,fp)<(size_t)(raw->len-6)) return -2; - raw->nbyte=0; - - /* decode ubx raw message */ - return decode_ubx(raw); + * fetch next ublox raw data and input a message from file + * args : raw_t *raw IO receiver raw data control struct + * FILE *fp I file pointer + * return : status(-2: end of file, -1...9: same as above) + *-----------------------------------------------------------------------------*/ +extern int input_ubxf(raw_t *raw, FILE *fp) { + int i, data; + + trace(4, "input_ubxf:\n"); + + /* synchronize frame */ + if (raw->nbyte == 0) { + for (i = 0;; i++) { + if ((data = fgetc(fp)) == EOF) return -2; + if (sync_ubx(raw->buff, (uint8_t)data)) break; + if (i >= 4096) return 0; + } + } + if (fread(raw->buff + 2, 1, 4, fp) < 4) return -2; + raw->nbyte = 6; + + if ((raw->len = U2(raw->buff + 4) + 8) > MAXRAWLEN) { + trace(2, "ubx length error: len=%d\n", raw->len); + raw->nbyte = 0; + return -1; + } + if (fread(raw->buff + 6, 1, raw->len - 6, fp) < (size_t)(raw->len - 6)) return -2; + raw->nbyte = 0; + + /* decode ubx raw message */ + return decode_ubx(raw); } /* convert string to integer -------------------------------------------------*/ -static int stoi(const char *s) -{ - uint32_t n; - if (sscanf(s,"0x%X",&n)==1) return (int)n; /* hex (0xXXXX) */ - return atoi(s); +static int stoi(const char *s) { + uint32_t n; + if (sscanf(s, "0x%X", &n) == 1) return (int)n; /* hex (0xXXXX) */ + return atoi(s); } /* generate ublox binary message ----------------------------------------------- -* generate ublox binary message from message string -* args : char *msg IO message string -* "CFG-PRT portid res0 res1 mode baudrate inmask outmask flags" -* "CFG-USB vendid prodid res1 res2 power flags vstr pstr serino" -* "CFG-MSG msgid rate0 rate1 rate2 rate3 rate4 rate5 rate6" -* "CFG-NMEA filter version numsv flags" -* "CFG-RATE meas nav time" -* "CFG-CFG clear_mask save_mask load_mask [dev_mask]" -* "CFG-TP interval length status time_ref res adelay rdelay udelay" -* "CFG-NAV2 ..." -* "CFG-DAT maja flat dx dy dz rotx roty rotz scale" -* "CFG-INF protocolid res0 res1 res2 mask0 mask1 mask2 ... mask5" -* "CFG-RST navbbr reset res" -* "CFG-RXM gpsmode lpmode" -* "CFG-ANT flags pins" -* "CFG-FXN flags treacq tacq treacqoff tacqoff ton toff res basetow" -* "CFG-SBAS mode usage maxsbas res scanmode" -* "CFG-LIC key0 key1 key2 key3 key4 key5" -* "CFG-TM intid rate flags" -* "CFG-TM2 ch res0 res1 rate flags" -* "CFG-TMODE tmode posx posy posz posvar svinmindur svinvarlimit" -* "CFG-EKF ..." -* "CFG-GNSS ..." -* "CFG-ITFM conf conf2" -* "CFG-LOGFILTER ver flag min_int time_thr speed_thr pos_thr" -* "CFG-NAV5 ..." -* "CFG-NAVX5 ..." -* "CFG-ODO ..." -* "CFG-PM2 ..." -* "CFG-PWR ver rsv1 rsv2 rsv3 state" -* "CFG-RINV flag data ..." -* "CFG-SMGR ..." -* "CFG-TMODE2 ..." -* "CFG-TMODE3 ..." -* "CFG-TPS ..." -* "CFG-TXSLOT ..." -* "CFG-VALDEL ver layer res0 res1 key [key ...]" -* "CFG-VALGET ver layer pos key [key ...]" -* "CFG-VALSET ver layer res0 res1 key value [key value ...]" -* uint8_t *buff O binary message -* return : length of binary message (0: error) -* note : see reference [1][3][5] for details. -* the following messages are not supported: -* CFG-DOSC,CFG-ESRC -*-----------------------------------------------------------------------------*/ -extern int gen_ubx(const char *msg, uint8_t *buff) -{ - const char *cmd[]={ - "PRT","USB","MSG","NMEA","RATE","CFG","TP","NAV2","DAT","INF", - "RST","RXM","ANT","FXN","SBAS","LIC","TM","TM2","TMODE","EKF", - "GNSS","ITFM","LOGFILTER","NAV5","NAVX5","ODO","PM2","PWR","RINV","SMGR", - "TMODE2","TMODE3","TPS","TXSLOT", - "VALDEL","VALGET","VALSET","" - }; - const uint8_t id[]={ - 0x00,0x1B,0x01,0x17,0x08,0x09,0x07,0x1A,0x06,0x02, - 0x04,0x11,0x13,0x0E,0x16,0x80,0x10,0x19,0x1D,0x12, - 0x3E,0x39,0x47,0x24,0x23,0x1E,0x3B,0x57,0x34,0x62, - 0x36,0x71,0x31,0x53, - 0x8c,0x8b,0x8a - }; - const int prm[][32]={ - {FU1,FU1,FU2,FU4,FU4,FU2,FU2,FU2,FU2}, /* PRT */ - {FU2,FU2,FU2,FU2,FU2,FU2,FS32,FS32,FS32}, /* USB */ - {FU1,FU1,FU1,FU1,FU1,FU1,FU1,FU1}, /* MSG */ - {FU1,FU1,FU1,FU1}, /* NMEA */ - {FU2,FU2,FU2}, /* RATE */ - {FU4,FU4,FU4,FU1}, /* CFG */ - {FU4,FU4,FI1,FU1,FU2,FI2,FI2,FI4}, /* TP */ - {FU1,FU1,FU2,FU1,FU1,FU1,FU1,FI4,FU1,FU1,FU1,FU1,FU1,FU1,FU2,FU2,FU2,FU2, - FU2,FU1,FU1,FU2,FU4,FU4}, /* NAV2 */ - {FR8,FR8,FR4,FR4,FR4,FR4,FR4,FR4,FR4}, /* DAT */ - {FU1,FU1,FU1,FU1,FU1,FU1,FU1,FU1,FU1,FU1}, /* INF */ - {FU2,FU1,FU1}, /* RST */ - {FU1,FU1}, /* RXM */ - {FU2,FU2}, /* ANT */ - {FU4,FU4,FU4,FU4,FU4,FU4,FU4,FU4}, /* FXN */ - {FU1,FU1,FU1,FU1,FU4}, /* SBAS */ - {FU2,FU2,FU2,FU2,FU2,FU2}, /* LIC */ - {FU4,FU4,FU4}, /* TM */ - {FU1,FU1,FU2,FU4,FU4}, /* TM2 */ - {FU4,FI4,FI4,FI4,FU4,FU4,FU4}, /* TMODE */ - {FU1,FU1,FU1,FU1,FU4,FU2,FU2,FU1,FU1,FU2}, /* EKF */ - {FU1,FU1,FU1,FU1,FU1,FU1,FU1,FU1,FU4}, /* GNSS */ - {FU4,FU4}, /* ITFM */ - {FU1,FU1,FU2,FU2,FU2,FU4}, /* LOGFILTER */ - {FU2,FU1,FU1,FI4,FU4,FI1,FU1,FU2,FU2,FU2,FU2,FU1,FU1,FU1,FU1,FU1,FU1,FU2, - FU1,FU1,FU1,FU1,FU1,FU1}, /* NAV5 */ - {FU2,FU2,FU4,FU1,FU1,FU1,FU1,FU1,FU1,FU1,FU1,FU1,FU1,FU2,FU1,FU1,FU1,FU1, - FU1,FU1,FU1,FU1,FU1,FU1,FU2}, /* NAVX5 */ - {FU1,FU1,FU1,FU1,FU1,FU1,FU1,FU1,FU1}, /* ODO */ - {FU1,FU1,FU1,FU1,FU4,FU4,FU4,FU4,FU2,FU2}, /* PM2 */ - {FU1,FU1,FU1,FU1,FU4}, /* PWR */ - {FU1,FU1}, /* RINV */ - {FU1,FU1,FU2,FU2,FU1,FU1,FU2,FU2,FU2,FU2,FU4}, /* SMGR */ - {FU1,FU1,FU2,FI4,FI4,FI4,FU4,FU4,FU4}, /* TMODE2 */ - {FU1,FU1,FU2,FI4,FI4,FI4,FU4,FU4,FU4}, /* TMODE3 */ - {FU1,FU1,FU1,FU1,FI2,FI2,FU4,FU4,FU4,FU4,FI4,FU4}, /* TPS */ - {FU1,FU1,FU1,FU1,FU4,FU4,FU4,FU4,FU4}, /* TXSLOT */ - {FU1,FU1,FU1,FU1}, /* VALDEL */ - {FU1,FU1,FU2}, /* VALGET */ - {FU1,FU1,FU1,FU1} /* VALSET */ - }; - uint8_t *q=buff; - char mbuff[1024],*args[32],*p; - int i,j,n,narg=0; - bool isvalset = false; - - trace(4,"gen_ubxf: msg=%s\n",msg); - - strcpy(mbuff,msg); - char *r; - for (p=strtok_r(mbuff," ",&r);p&&narg<32;p=strtok_r(NULL," ",&r)) { - args[narg++]=p; - } - if (narg<1||strncmp(args[0],"CFG-",4)) return 0; - - for (i=0;*cmd[i];i++) { - if (!strcmp(args[0]+4,cmd[i])) break; - } - if (!*cmd[i]) return 0; - - *q++=UBXSYNC1; - *q++=UBXSYNC2; - *q++=UBXCFG; - *q++=id[i]; - q+=2; + * generate ublox binary message from message string + * args : char *msg IO message string + * "CFG-PRT portid res0 res1 mode baudrate inmask outmask flags" + * "CFG-USB vendid prodid res1 res2 power flags vstr pstr serino" + * "CFG-MSG msgid rate0 rate1 rate2 rate3 rate4 rate5 rate6" + * "CFG-NMEA filter version numsv flags" + * "CFG-RATE meas nav time" + * "CFG-CFG clear_mask save_mask load_mask [dev_mask]" + * "CFG-TP interval length status time_ref res adelay rdelay udelay" + * "CFG-NAV2 ..." + * "CFG-DAT maja flat dx dy dz rotx roty rotz scale" + * "CFG-INF protocolid res0 res1 res2 mask0 mask1 mask2 ... mask5" + * "CFG-RST navbbr reset res" + * "CFG-RXM gpsmode lpmode" + * "CFG-ANT flags pins" + * "CFG-FXN flags treacq tacq treacqoff tacqoff ton toff res basetow" + * "CFG-SBAS mode usage maxsbas res scanmode" + * "CFG-LIC key0 key1 key2 key3 key4 key5" + * "CFG-TM intid rate flags" + * "CFG-TM2 ch res0 res1 rate flags" + * "CFG-TMODE tmode posx posy posz posvar svinmindur svinvarlimit" + * "CFG-EKF ..." + * "CFG-GNSS ..." + * "CFG-ITFM conf conf2" + * "CFG-LOGFILTER ver flag min_int time_thr speed_thr pos_thr" + * "CFG-NAV5 ..." + * "CFG-NAVX5 ..." + * "CFG-ODO ..." + * "CFG-PM2 ..." + * "CFG-PWR ver rsv1 rsv2 rsv3 state" + * "CFG-RINV flag data ..." + * "CFG-SMGR ..." + * "CFG-TMODE2 ..." + * "CFG-TMODE3 ..." + * "CFG-TPS ..." + * "CFG-TXSLOT ..." + * "CFG-VALDEL ver layer res0 res1 key [key ...]" + * "CFG-VALGET ver layer pos key [key ...]" + * "CFG-VALSET ver layer res0 res1 key value [key value ...]" + * uint8_t *buff O binary message + * return : length of binary message (0: error) + * note : see reference [1][3][5] for details. + * the following messages are not supported: + * CFG-DOSC,CFG-ESRC + *-----------------------------------------------------------------------------*/ +extern int gen_ubx(const char *msg, uint8_t *buff) { + const char *cmd[] = {"PRT", "USB", "MSG", "NMEA", "RATE", "CFG", "TP", + "NAV2", "DAT", "INF", "RST", "RXM", "ANT", "FXN", + "SBAS", "LIC", "TM", "TM2", "TMODE", "EKF", "GNSS", + "ITFM", "LOGFILTER", "NAV5", "NAVX5", "ODO", "PM2", "PWR", + "RINV", "SMGR", "TMODE2", "TMODE3", "TPS", "TXSLOT", "VALDEL", + "VALGET", "VALSET", ""}; + const uint8_t id[] = {0x00, 0x1B, 0x01, 0x17, 0x08, 0x09, 0x07, 0x1A, 0x06, 0x02, + 0x04, 0x11, 0x13, 0x0E, 0x16, 0x80, 0x10, 0x19, 0x1D, 0x12, + 0x3E, 0x39, 0x47, 0x24, 0x23, 0x1E, 0x3B, 0x57, 0x34, 0x62, + 0x36, 0x71, 0x31, 0x53, 0x8c, 0x8b, 0x8a}; + const int prm[][32] = { + {FU1, FU1, FU2, FU4, FU4, FU2, FU2, FU2, FU2}, /* PRT */ + {FU2, FU2, FU2, FU2, FU2, FU2, FS32, FS32, FS32}, /* USB */ + {FU1, FU1, FU1, FU1, FU1, FU1, FU1, FU1}, /* MSG */ + {FU1, FU1, FU1, FU1}, /* NMEA */ + {FU2, FU2, FU2}, /* RATE */ + {FU4, FU4, FU4, FU1}, /* CFG */ + {FU4, FU4, FI1, FU1, FU2, FI2, FI2, FI4}, /* TP */ + {FU1, FU1, FU2, FU1, FU1, FU1, FU1, FI4, FU1, FU1, FU1, FU1, + FU1, FU1, FU2, FU2, FU2, FU2, FU2, FU1, FU1, FU2, FU4, FU4}, /* NAV2 */ + {FR8, FR8, FR4, FR4, FR4, FR4, FR4, FR4, FR4}, /* DAT */ + {FU1, FU1, FU1, FU1, FU1, FU1, FU1, FU1, FU1, FU1}, /* INF */ + {FU2, FU1, FU1}, /* RST */ + {FU1, FU1}, /* RXM */ + {FU2, FU2}, /* ANT */ + {FU4, FU4, FU4, FU4, FU4, FU4, FU4, FU4}, /* FXN */ + {FU1, FU1, FU1, FU1, FU4}, /* SBAS */ + {FU2, FU2, FU2, FU2, FU2, FU2}, /* LIC */ + {FU4, FU4, FU4}, /* TM */ + {FU1, FU1, FU2, FU4, FU4}, /* TM2 */ + {FU4, FI4, FI4, FI4, FU4, FU4, FU4}, /* TMODE */ + {FU1, FU1, FU1, FU1, FU4, FU2, FU2, FU1, FU1, FU2}, /* EKF */ + {FU1, FU1, FU1, FU1, FU1, FU1, FU1, FU1, FU4}, /* GNSS */ + {FU4, FU4}, /* ITFM */ + {FU1, FU1, FU2, FU2, FU2, FU4}, /* LOGFILTER */ + {FU2, FU1, FU1, FI4, FU4, FI1, FU1, FU2, FU2, FU2, FU2, FU1, + FU1, FU1, FU1, FU1, FU1, FU2, FU1, FU1, FU1, FU1, FU1, FU1}, /* NAV5 */ + {FU2, FU2, FU4, FU1, FU1, FU1, FU1, FU1, FU1, FU1, FU1, FU1, FU1, + FU2, FU1, FU1, FU1, FU1, FU1, FU1, FU1, FU1, FU1, FU1, FU2}, /* NAVX5 */ + {FU1, FU1, FU1, FU1, FU1, FU1, FU1, FU1, FU1}, /* ODO */ + {FU1, FU1, FU1, FU1, FU4, FU4, FU4, FU4, FU2, FU2}, /* PM2 */ + {FU1, FU1, FU1, FU1, FU4}, /* PWR */ + {FU1, FU1}, /* RINV */ + {FU1, FU1, FU2, FU2, FU1, FU1, FU2, FU2, FU2, FU2, FU4}, /* SMGR */ + {FU1, FU1, FU2, FI4, FI4, FI4, FU4, FU4, FU4}, /* TMODE2 */ + {FU1, FU1, FU2, FI4, FI4, FI4, FU4, FU4, FU4}, /* TMODE3 */ + {FU1, FU1, FU1, FU1, FI2, FI2, FU4, FU4, FU4, FU4, FI4, FU4}, /* TPS */ + {FU1, FU1, FU1, FU1, FU4, FU4, FU4, FU4, FU4}, /* TXSLOT */ + {FU1, FU1, FU1, FU1}, /* VALDEL */ + {FU1, FU1, FU2}, /* VALGET */ + {FU1, FU1, FU1, FU1} /* VALSET */ + }; + uint8_t *q = buff; + char mbuff[1024], *args[32], *p; + int i, j, n, narg = 0; + bool isvalset = false; + trace(4, "gen_ubxf: msg=%s\n", msg); - if (i == 36) isvalset = true; + strcpy(mbuff, msg); + char *r; + for (p = strtok_r(mbuff, " ", &r); p && narg < 32; p = strtok_r(NULL, " ", &r)) { + args[narg++] = p; + } + if (narg < 1 || strncmp(args[0], "CFG-", 4)) return 0; - /* VALSET sanity check */ - if (isvalset) { - if (narg == 7) narg = narg - 2; /* Adjusting for key value addition */ - else return 0; - } - for (j=1;prm[i][j-1]||j= value) break; - return i; +static int uraindex(double value) { + static const double ura_eph[] = {2.4, 3.4, 4.85, 6.85, 9.65, 13.65, 24.0, 48.0, + 96.0, 192.0, 384.0, 768.0, 1536.0, 3072.0, 6144.0, 0.0}; + int i; + for (i = 0; i < 15; i++) + if (ura_eph[i] >= value) break; + return i; } /* get observation data index ------------------------------------------------*/ -static int obsindex(obs_t* obs, gtime_t time, int sat) -{ - int i, j; - - if (obs->n >= MAXOBS) return -1; - for (i = 0; i < obs->n; i++) { - if (obs->data[i].sat == sat) return i; - } - obs->data[i].time = time; - obs->data[i].sat = sat; - for (j = 0; j < NFREQ + NEXOBS; j++) { - obs->data[i].L[j] = obs->data[i].P[j] = 0.0; - obs->data[i].D[j] = obs->data[i].SNR[j] = 0.0; - obs->data[i].Lstd[j] = obs->data[i].Pstd[j] = 0.0; - obs->data[i].LLI[j] = 0; - obs->data[i].code[j] = CODE_NONE; - } - obs->n++; - return i; +static int obsindex(obs_t* obs, gtime_t time, int sat) { + int i, j; + + if (obs->n >= MAXOBS) return -1; + for (i = 0; i < obs->n; i++) { + if (obs->data[i].sat == sat) return i; + } + obs->data[i].time = time; + obs->data[i].sat = sat; + for (j = 0; j < NFREQ + NEXOBS; j++) { + obs->data[i].L[j] = obs->data[i].P[j] = 0.0; + obs->data[i].D[j] = obs->data[i].SNR[j] = 0.0; + obs->data[i].Lstd[j] = obs->data[i].Pstd[j] = 0.0; + obs->data[i].LLI[j] = 0; + obs->data[i].code[j] = CODE_NONE; + } + obs->n++; + return i; } /* adjust weekly rollover of GPS time ----------------------------------------*/ -static gtime_t adjweek(gtime_t time, double tow) -{ - double tow_p; - int week; - tow_p = time2gpst(time, &week); - if (tow < tow_p - 302400.0) tow += 604800.0; - else if (tow > tow_p + 302400.0) tow -= 604800.0; - return gpst2time(week, tow); +static gtime_t adjweek(gtime_t time, double tow) { + double tow_p; + int week; + tow_p = time2gpst(time, &week); + if (tow < tow_p - 302400.0) + tow += 604800.0; + else if (tow > tow_p + 302400.0) + tow -= 604800.0; + return gpst2time(week, tow); } /* check code priority and return freq-index ---------------------------------*/ -static int checkpri(const char* opt, int sys, int code, int idx) -{ - int nex = NEXOBS; - - if (sys == SYS_GPS) { - if (strstr(opt, "-GL1L") && idx == 0) return (code == CODE_L1L) ? 0 : -1; - if (strstr(opt, "-GL2S") && idx == 1) return (code == CODE_L2X) ? 1 : -1; - if (strstr(opt, "-GL2P") && idx == 1) return (code == CODE_L2P) ? 1 : -1; - if (code == CODE_L1L) return (nex < 1) ? -1 : NFREQ; - if (code == CODE_L2S) return (nex < 2) ? -1 : NFREQ + 1; - if (code == CODE_L2P) return (nex < 3) ? -1 : NFREQ + 2; - } - else if (sys == SYS_GLO) { - if (strstr(opt, "-RL2C") && idx == 1) return (code == CODE_L2C) ? 1 : -1; - if (code == CODE_L2C) return (nex < 1) ? -1 : NFREQ; - } - else if (sys == SYS_GAL) { - if (strstr(opt, "-EL6B") && idx == 3) return (code == CODE_L6B) ? 3 : -1; - if (code == CODE_L6B) return (nex < 2) ? -1 : NFREQ; - } - else if (sys == SYS_QZS) { - if (strstr(opt, "-JL1L") && idx == 0) return (code == CODE_L1L) ? 0 : -1; - if (strstr(opt, "-JL1Z") && idx == 0) return (code == CODE_L1Z) ? 0 : -1; - if (code == CODE_L1L) return (nex < 1) ? -1 : NFREQ; - if (code == CODE_L1Z) return (nex < 2) ? -1 : NFREQ + 1; - } - else if (sys == SYS_CMP) { - if (strstr(opt, "-CL1P") && idx == 0) return (code == CODE_L1P) ? 0 : -1; - if (strstr(opt, "-CL7D") && idx == 0) return (code == CODE_L7D) ? 0 : -1; - if (code == CODE_L1P) return (nex < 1) ? -1 : NFREQ; - if (code == CODE_L7D) return (nex < 2) ? -1 : NFREQ + 1; - } - return idx < NFREQ ? idx : -1; +static int checkpri(const char* opt, int sys, int code, int idx) { + int nex = NEXOBS; + + if (sys == SYS_GPS) { + if (strstr(opt, "-GL1L") && idx == 0) return (code == CODE_L1L) ? 0 : -1; + if (strstr(opt, "-GL2S") && idx == 1) return (code == CODE_L2X) ? 1 : -1; + if (strstr(opt, "-GL2P") && idx == 1) return (code == CODE_L2P) ? 1 : -1; + if (code == CODE_L1L) return (nex < 1) ? -1 : NFREQ; + if (code == CODE_L2S) return (nex < 2) ? -1 : NFREQ + 1; + if (code == CODE_L2P) return (nex < 3) ? -1 : NFREQ + 2; + } else if (sys == SYS_GLO) { + if (strstr(opt, "-RL2C") && idx == 1) return (code == CODE_L2C) ? 1 : -1; + if (code == CODE_L2C) return (nex < 1) ? -1 : NFREQ; + } else if (sys == SYS_GAL) { + if (strstr(opt, "-EL6B") && idx == 3) return (code == CODE_L6B) ? 3 : -1; + if (code == CODE_L6B) return (nex < 2) ? -1 : NFREQ; + } else if (sys == SYS_QZS) { + if (strstr(opt, "-JL1L") && idx == 0) return (code == CODE_L1L) ? 0 : -1; + if (strstr(opt, "-JL1Z") && idx == 0) return (code == CODE_L1Z) ? 0 : -1; + if (code == CODE_L1L) return (nex < 1) ? -1 : NFREQ; + if (code == CODE_L1Z) return (nex < 2) ? -1 : NFREQ + 1; + } else if (sys == SYS_CMP) { + if (strstr(opt, "-CL1P") && idx == 0) return (code == CODE_L1P) ? 0 : -1; + if (strstr(opt, "-CL7D") && idx == 0) return (code == CODE_L7D) ? 0 : -1; + if (code == CODE_L1P) return (nex < 1) ? -1 : NFREQ; + if (code == CODE_L7D) return (nex < 2) ? -1 : NFREQ + 1; + } + return idx < NFREQ ? idx : -1; } /* signal type to obs code ---------------------------------------------------*/ -static int sig2code(int sys, int sigtype, int l2c) -{ - if (sys == SYS_GPS) { - switch (sigtype) { - case 0: return CODE_L1C; // L1C/A - case 9: return l2c == 1 ? CODE_L2S : CODE_L2W; // L2P(Y),semi-codeless or L2C(M) - case 3: return CODE_L1L; // L1C Pilot - case 11: return CODE_L1S; // L1C Data, semi-codeless - case 6: return CODE_L5I; // L5 Data - case 14: return CODE_L5Q; // L5 Pilot - case 17: return CODE_L2L; // L2C(L) - default: return 0; - } +static int sig2code(int sys, int sigtype, int l2c) { + if (sys == SYS_GPS) { + switch (sigtype) { + case 0: + return CODE_L1C; // L1C/A + case 9: + return l2c == 1 ? CODE_L2S : CODE_L2W; // L2P(Y),semi-codeless or L2C(M) + case 3: + return CODE_L1L; // L1C Pilot + case 11: + return CODE_L1S; // L1C Data, semi-codeless + case 6: + return CODE_L5I; // L5 Data + case 14: + return CODE_L5Q; // L5 Pilot + case 17: + return CODE_L2L; // L2C(L) + default: + return 0; } - else if (sys == SYS_GLO) { - switch (sigtype) { - case 0: return CODE_L1C; // L1C/A - case 5: return CODE_L2C; // L2C/A - case 6: return CODE_L3I; // G3I - case 7: return CODE_L3Q; // G3Q - default: return 0; - } + } else if (sys == SYS_GLO) { + switch (sigtype) { + case 0: + return CODE_L1C; // L1C/A + case 5: + return CODE_L2C; // L2C/A + case 6: + return CODE_L3I; // G3I + case 7: + return CODE_L3Q; // G3Q + default: + return 0; } - else if (sys == SYS_GAL) { - switch (sigtype) { - case 1: return CODE_L1B; // E1B - case 2: return CODE_L1C; // E1C - case 12: return CODE_L5Q; // E5A Pilot - case 17: return CODE_L7Q; // E5B Pilot - case 18: return CODE_L6B; // E6B - case 22: return CODE_L6C; // E6C - default: return 0; - } + } else if (sys == SYS_GAL) { + switch (sigtype) { + case 1: + return CODE_L1B; // E1B + case 2: + return CODE_L1C; // E1C + case 12: + return CODE_L5Q; // E5A Pilot + case 17: + return CODE_L7Q; // E5B Pilot + case 18: + return CODE_L6B; // E6B + case 22: + return CODE_L6C; // E6C + default: + return 0; } - else if (sys == SYS_QZS) { - switch (sigtype) { - case 0: return CODE_L1C; // L1C/A - case 1: return CODE_L1E; // L1C/B - case 3: return CODE_L1L; // L1C pilot - case 4: return CODE_L1Z; // L1S - case 6: return CODE_L5I; // L5 Data - case 9: return l2c == 1 ? CODE_L2S : CODE_L2W; // L2P(Y),semi-codeless or L2C(M) - case 11: return CODE_L1S; // L1C Data - case 14: return CODE_L5Q; // L5 Pilot - case 17: return CODE_L2L; // L2C(L) - case 21: return CODE_L6Z; // L6D - case 27: return CODE_L6E; // L6E - default: return 0; - } + } else if (sys == SYS_QZS) { + switch (sigtype) { + case 0: + return CODE_L1C; // L1C/A + case 1: + return CODE_L1E; // L1C/B + case 3: + return CODE_L1L; // L1C pilot + case 4: + return CODE_L1Z; // L1S + case 6: + return CODE_L5I; // L5 Data + case 9: + return l2c == 1 ? CODE_L2S : CODE_L2W; // L2P(Y),semi-codeless or L2C(M) + case 11: + return CODE_L1S; // L1C Data + case 14: + return CODE_L5Q; // L5 Pilot + case 17: + return CODE_L2L; // L2C(L) + case 21: + return CODE_L6Z; // L6D + case 27: + return CODE_L6E; // L6E + default: + return 0; } - else if (sys == SYS_CMP) { - switch (sigtype) { - case 0: return CODE_L2I; // B1I - case 4: return CODE_L2Q; // B1Q - case 8: return CODE_L1P; // B1C pilot - case 23: return CODE_L1D; // B1C Data - case 5: return CODE_L7Q; // B2Q - case 17: return CODE_L7I; // B2I - case 12: return CODE_L5P; // B2a Pilot - case 28: return CODE_L5D; // B2a Data - case 6: return CODE_L6Q; // B3Q - case 21: return CODE_L6I; // B3I - case 13: return CODE_L7P; // B2b (I) - default: return 0; - } + } else if (sys == SYS_CMP) { + switch (sigtype) { + case 0: + return CODE_L2I; // B1I + case 4: + return CODE_L2Q; // B1Q + case 8: + return CODE_L1P; // B1C pilot + case 23: + return CODE_L1D; // B1C Data + case 5: + return CODE_L7Q; // B2Q + case 17: + return CODE_L7I; // B2I + case 12: + return CODE_L5P; // B2a Pilot + case 28: + return CODE_L5D; // B2a Data + case 6: + return CODE_L6Q; // B3Q + case 21: + return CODE_L6I; // B3I + case 13: + return CODE_L7P; // B2b (I) + default: + return 0; } - else if (sys == SYS_IRN) { - switch (sigtype) { - case 6: return CODE_L5A; // L5 Data - case 14: return CODE_L5C; // L5 Pilot - default: return 0; - } + } else if (sys == SYS_IRN) { + switch (sigtype) { + case 6: + return CODE_L5A; // L5 Data + case 14: + return CODE_L5C; // L5 Pilot + default: + return 0; } - else if (sys == SYS_SBS) { - switch (sigtype) { - case 0: return CODE_L1C; // L1C/A - case 6: return CODE_L5I; // L5I - default: return 0; - } + } else if (sys == SYS_SBS) { + switch (sigtype) { + case 0: + return CODE_L1C; // L1C/A + case 6: + return CODE_L5I; // L5I + default: + return 0; } - return 0; + } + return 0; } -static int decode_track_stat(uint32_t stat, int* sys, int* code, int* plock, int* clock) -{ - int satsys, sigtype, idx = -1; - int l2c; - - *code = CODE_NONE; - *plock = (stat >> 10) & 1; - *clock = (stat >> 12) & 1; - satsys = (stat >> 16) & 7; - sigtype = (stat >> 21) & 0x1F; - l2c = (stat >> 26) & 0x01; - - - switch (satsys) { - case 0: *sys = SYS_GPS; break; - case 1: *sys = SYS_GLO; break; - case 2: *sys = SYS_SBS; break; - case 3: *sys = SYS_GAL; break; - case 4: *sys = SYS_CMP; break; - case 5: *sys = SYS_QZS; break; - case 6: *sys = SYS_IRN; break; +static int decode_track_stat(uint32_t stat, int* sys, int* code, int* plock, int* clock) { + int satsys, sigtype, idx = -1; + int l2c; + + *code = CODE_NONE; + *plock = (stat >> 10) & 1; + *clock = (stat >> 12) & 1; + satsys = (stat >> 16) & 7; + sigtype = (stat >> 21) & 0x1F; + l2c = (stat >> 26) & 0x01; + + switch (satsys) { + case 0: + *sys = SYS_GPS; + break; + case 1: + *sys = SYS_GLO; + break; + case 2: + *sys = SYS_SBS; + break; + case 3: + *sys = SYS_GAL; + break; + case 4: + *sys = SYS_CMP; + break; + case 5: + *sys = SYS_QZS; + break; + case 6: + *sys = SYS_IRN; + break; default: - trace(2, "unicore unknown system: sys=%d\n", satsys); - return -1; - } - if (!(*code = sig2code(*sys, sigtype, l2c)) || (idx = code2idx(*sys, *code)) < 0) { - trace(2, "unicore signal type error: sys=%d sigtype=%d\n", *sys, sigtype); - return -1; - } - return idx; + trace(2, "unicore unknown system: sys=%d\n", satsys); + return -1; + } + if (!(*code = sig2code(*sys, sigtype, l2c)) || (idx = code2idx(*sys, *code)) < 0) { + trace(2, "unicore signal type error: sys=%d sigtype=%d\n", *sys, sigtype); + return -1; + } + return idx; } -static int decode_gpsephb(raw_t* raw) -{ - eph_t eph = { 0 }; - uint8_t* p = raw->buff + HLEN; - - double tow, tocs, N; - int prn, as, sat, week, zweek, health; - - if (raw->len < HLEN + 224) { - trace(2, "unicore gpsephb length error: len=%d\n", raw->len); - return -1; - } - - prn = U4(p); p += 4; - tow = R8(p); p += 8; - health = U4(p) & 0x3f; p += 4; - eph.iode = U4(p); p += 4; - int iode2 = U4(p); p += 4; - (void)iode2; - - eph.week = U4(p); p += 4; - zweek = U4(p); p += 4; - eph.toes = R8(p); p += 8; - eph.A = R8(p); p += 8; - eph.deln = R8(p); p += 8; - eph.M0 = R8(p); p += 8; - eph.e = R8(p); p += 8; - eph.omg = R8(p); p += 8; - eph.cuc = R8(p); p += 8; - eph.cus = R8(p); p += 8; - eph.crc = R8(p); p += 8; - eph.crs = R8(p); p += 8; - eph.cic = R8(p); p += 8; - eph.cis = R8(p); p += 8; - eph.i0 = R8(p); p += 8; - eph.idot = R8(p); p += 8; - eph.OMG0 = R8(p); p += 8; - eph.OMGd = R8(p); p += 8; - eph.iodc = U4(p); p += 4; - tocs = R8(p); p += 8; - eph.tgd[0] = R8(p); p += 8; - eph.f0 = R8(p); p += 8; - eph.f1 = R8(p); p += 8; - eph.f2 = R8(p); p += 8; - as = U4(p); p += 4; - N = R8(p); p += 8; - eph.sva = uraindex(R8(p)); p += 8; - - if (!(sat = satno(SYS_GPS, prn))) { - trace(2, "unicore gpsephb satellite error: prn=%d\n", prn); - return -1; - } - if (raw->outtype) { - sprintf(raw->msgtype + strlen(raw->msgtype), " prn=%d", prn); - } - - eph.sat = sat; - eph.code = 0; - eph.iodc = eph.iode; - tow = time2gpst(raw->time, &week); - eph.week = week; /* gps-week = gal-week */ - eph.toe = gpst2time(eph.week, eph.toes); - - double tt = timediff(eph.toe, raw->time); - if (tt < -302400.0) eph.week++; - else if (tt > 302400.0) eph.week--; - eph.toe = gpst2time(eph.week, eph.toes); - eph.toc = adjweek(raw->time, tocs); - eph.ttr = raw->time; - - if (!strstr(raw->opt, "-EPHALL")) { - if (fabs(timediff(raw->nav.eph[sat - 1].toe, eph.toe)) < 1e-9 && - fabs(timediff(raw->nav.eph[sat - 1].toc, eph.toc)) < 1e-9) return 0; - } - - raw->nav.eph[sat - 1] = eph; - raw->ephsat = sat; - raw->ephset = 0; - return 2; +static int decode_gpsephb(raw_t* raw) { + eph_t eph = {0}; + uint8_t* p = raw->buff + HLEN; + + double tow, tocs, N; + int prn, as, sat, week, zweek, health; + + if (raw->len < HLEN + 224) { + trace(2, "unicore gpsephb length error: len=%d\n", raw->len); + return -1; + } + + prn = U4(p); + p += 4; + tow = R8(p); + p += 8; + health = U4(p) & 0x3f; + p += 4; + eph.iode = U4(p); + p += 4; + int iode2 = U4(p); + p += 4; + (void)iode2; + + eph.week = U4(p); + p += 4; + zweek = U4(p); + p += 4; + eph.toes = R8(p); + p += 8; + eph.A = R8(p); + p += 8; + eph.deln = R8(p); + p += 8; + eph.M0 = R8(p); + p += 8; + eph.e = R8(p); + p += 8; + eph.omg = R8(p); + p += 8; + eph.cuc = R8(p); + p += 8; + eph.cus = R8(p); + p += 8; + eph.crc = R8(p); + p += 8; + eph.crs = R8(p); + p += 8; + eph.cic = R8(p); + p += 8; + eph.cis = R8(p); + p += 8; + eph.i0 = R8(p); + p += 8; + eph.idot = R8(p); + p += 8; + eph.OMG0 = R8(p); + p += 8; + eph.OMGd = R8(p); + p += 8; + eph.iodc = U4(p); + p += 4; + tocs = R8(p); + p += 8; + eph.tgd[0] = R8(p); + p += 8; + eph.f0 = R8(p); + p += 8; + eph.f1 = R8(p); + p += 8; + eph.f2 = R8(p); + p += 8; + as = U4(p); + p += 4; + N = R8(p); + p += 8; + eph.sva = uraindex(R8(p)); + p += 8; + + if (!(sat = satno(SYS_GPS, prn))) { + trace(2, "unicore gpsephb satellite error: prn=%d\n", prn); + return -1; + } + if (raw->outtype) { + sprintf(raw->msgtype + strlen(raw->msgtype), " prn=%d", prn); + } + + eph.sat = sat; + eph.code = 0; + eph.iodc = eph.iode; + tow = time2gpst(raw->time, &week); + eph.week = week; /* gps-week = gal-week */ + eph.toe = gpst2time(eph.week, eph.toes); + + double tt = timediff(eph.toe, raw->time); + if (tt < -302400.0) + eph.week++; + else if (tt > 302400.0) + eph.week--; + eph.toe = gpst2time(eph.week, eph.toes); + eph.toc = adjweek(raw->time, tocs); + eph.ttr = raw->time; + + if (!strstr(raw->opt, "-EPHALL")) { + if (fabs(timediff(raw->nav.eph[sat - 1].toe, eph.toe)) < 1e-9 && + fabs(timediff(raw->nav.eph[sat - 1].toc, eph.toc)) < 1e-9) + return 0; + } + + raw->nav.eph[sat - 1] = eph; + raw->ephsat = sat; + raw->ephset = 0; + return 2; } -static int decode_gloephb(raw_t* raw) -{ - uint8_t* p = raw->buff + HLEN; - geph_t geph = { 0 }; - double tow, tof, toff; - int prn, sat, week; - - if (raw->len < HLEN + 144) { - trace(2, "unicore gloephb length error: len=%d\n", raw->len); - return -1; - } - prn = U2(p) - 37; p += 2; //Slot o - - if (!(sat = satno(SYS_GLO, prn))) { - trace(2, "unicore gloephb prn error: prn=%d\n", prn); - return -1; - } - if (raw->outtype) { - sprintf(raw->msgtype + strlen(raw->msgtype), " prn=%d", prn); - } - geph.frq = U2(p) + OFF_FRQNO; p += 2; - int satType = U1(p); p += 1 + 1; - (void)satType; - - week = U2(p); p += 2; - tow = floor(U4(p) / 1000.0 + 0.5); p += 4; /* rounded to integer sec */ - toff = U4(p); p += 4; - int Nt = U2(p); p += 2 + 2; - (void)Nt; - geph.iode = U4(p) & 0x7F; p += 4; - geph.svh = (U4(p) < 4) ? 0 : 1; p += 4; /* 0:healthy,1:unhealthy */ - geph.pos[0] = R8(p); p += 8; - geph.pos[1] = R8(p); p += 8; - geph.pos[2] = R8(p); p += 8; - geph.vel[0] = R8(p); p += 8; - geph.vel[1] = R8(p); p += 8; - geph.vel[2] = R8(p); p += 8; - geph.acc[0] = R8(p); p += 8; - geph.acc[1] = R8(p); p += 8; - geph.acc[2] = R8(p); p += 8; - geph.taun = R8(p); p += 8; - geph.dtaun = R8(p); p += 8; - geph.gamn = R8(p); p += 8; - tof = U4(p) - toff; p += 4; /* glonasst->gpst */ - - int P = U4(p); p += 4; - (void) P; - int Ft = U4(p); p += 4; - (void) Ft; - geph.age = U4(p); p += 4; - - geph.toe = gpst2time(week, tow); - tof += floor(tow / 86400.0) * 86400; - if (tof < tow - 43200.0) tof += 86400.0; - else if (tof > tow + 43200.0) tof -= 86400.0; - geph.tof = gpst2time(week, tof); - - if (!strstr(raw->opt, "-EPHALL")) { - if (fabs(timediff(geph.toe, raw->nav.geph[prn - 1].toe)) < 1.0 && - geph.svh == raw->nav.geph[prn - 1].svh) return 0; /* unchanged */ - } - geph.sat = sat; - raw->nav.geph[prn - 1] = geph; - raw->ephsat = sat; - raw->ephset = 0; - return 2; +static int decode_gloephb(raw_t* raw) { + uint8_t* p = raw->buff + HLEN; + geph_t geph = {0}; + double tow, tof, toff; + int prn, sat, week; + + if (raw->len < HLEN + 144) { + trace(2, "unicore gloephb length error: len=%d\n", raw->len); + return -1; + } + prn = U2(p) - 37; + p += 2; // Slot o + + if (!(sat = satno(SYS_GLO, prn))) { + trace(2, "unicore gloephb prn error: prn=%d\n", prn); + return -1; + } + if (raw->outtype) { + sprintf(raw->msgtype + strlen(raw->msgtype), " prn=%d", prn); + } + geph.frq = U2(p) + OFF_FRQNO; + p += 2; + int satType = U1(p); + p += 1 + 1; + (void)satType; + + week = U2(p); + p += 2; + tow = floor(U4(p) / 1000.0 + 0.5); + p += 4; /* rounded to integer sec */ + toff = U4(p); + p += 4; + int Nt = U2(p); + p += 2 + 2; + (void)Nt; + geph.iode = U4(p) & 0x7F; + p += 4; + geph.svh = (U4(p) < 4) ? 0 : 1; + p += 4; /* 0:healthy,1:unhealthy */ + geph.pos[0] = R8(p); + p += 8; + geph.pos[1] = R8(p); + p += 8; + geph.pos[2] = R8(p); + p += 8; + geph.vel[0] = R8(p); + p += 8; + geph.vel[1] = R8(p); + p += 8; + geph.vel[2] = R8(p); + p += 8; + geph.acc[0] = R8(p); + p += 8; + geph.acc[1] = R8(p); + p += 8; + geph.acc[2] = R8(p); + p += 8; + geph.taun = R8(p); + p += 8; + geph.dtaun = R8(p); + p += 8; + geph.gamn = R8(p); + p += 8; + tof = U4(p) - toff; + p += 4; /* glonasst->gpst */ + + int P = U4(p); + p += 4; + (void)P; + int Ft = U4(p); + p += 4; + (void)Ft; + geph.age = U4(p); + p += 4; + + geph.toe = gpst2time(week, tow); + tof += floor(tow / 86400.0) * 86400; + if (tof < tow - 43200.0) + tof += 86400.0; + else if (tof > tow + 43200.0) + tof -= 86400.0; + geph.tof = gpst2time(week, tof); + + if (!strstr(raw->opt, "-EPHALL")) { + if (fabs(timediff(geph.toe, raw->nav.geph[prn - 1].toe)) < 1.0 && + geph.svh == raw->nav.geph[prn - 1].svh) + return 0; /* unchanged */ + } + geph.sat = sat; + raw->nav.geph[prn - 1] = geph; + raw->ephsat = sat; + raw->ephset = 0; + return 2; } static int decode_galephb(raw_t* raw) { - eph_t eph = { 0 }; - uint8_t* p = raw->buff + HLEN; - double tow, sqrtA, af0_fnav, af1_fnav, af2_fnav, af0_inav, af1_inav, af2_inav, tt; - int prn, sat, week, rcv_fnav, rcv_inav, svh_e1b, svh_e5a, svh_e5b, dvs_e1b, dvs_e5a; - int dvs_e5b, toc_fnav, toc_inav, set, sel_eph = 3; /* 1:I/NAV+2:F/NAV */ - - if (strstr(raw->opt, "-GALINAV")) sel_eph = 1; - if (strstr(raw->opt, "-GALFNAV")) sel_eph = 2; - - if (raw->len < HLEN + 220) { - trace(2, "unicore galephb length error: len=%d\n", raw->len); - return -1; - } - prn = U4(p); p += 4; - rcv_fnav = U4(p) & 1; p += 4; - rcv_inav = U4(p) & 1; p += 4; - svh_e1b = U1(p) & 3; p += 1; - svh_e5a = U1(p) & 3; p += 1; - svh_e5b = U1(p) & 3; p += 1; - dvs_e1b = U1(p) & 1; p += 1; - dvs_e5a = U1(p) & 1; p += 1; - dvs_e5b = U1(p) & 1; p += 1; - eph.sva = U1(p); p += 1 + 1; /* SISA index */ - eph.iode = U4(p); p += 4; /* IODNav */ - eph.toes = U4(p); p += 4; - sqrtA = R8(p); p += 8; - eph.deln = R8(p); p += 8; - eph.M0 = R8(p); p += 8; - eph.e = R8(p); p += 8; - eph.omg = R8(p); p += 8; - eph.cuc = R8(p); p += 8; - eph.cus = R8(p); p += 8; - eph.crc = R8(p); p += 8; - eph.crs = R8(p); p += 8; - eph.cic = R8(p); p += 8; - eph.cis = R8(p); p += 8; - eph.i0 = R8(p); p += 8; - eph.idot = R8(p); p += 8; - eph.OMG0 = R8(p); p += 8; - eph.OMGd = R8(p); p += 8; - toc_fnav = U4(p); p += 4; - af0_fnav = R8(p); p += 8; - af1_fnav = R8(p); p += 8; - af2_fnav = R8(p); p += 8; - toc_inav = U4(p); p += 4; - af0_inav = R8(p); p += 8; - af1_inav = R8(p); p += 8; - af2_inav = R8(p); p += 8; - eph.tgd[0] = R8(p); p += 8; /* BGD: E5A-E1 (s) */ - eph.tgd[1] = R8(p); /* BGD: E5B-E1 (s) */ - - if (!(sat = satno(SYS_GAL, prn))) { - trace(2, "unicore galephb satellite error: prn=%d\n", prn); - return -1; - } - if (raw->outtype) { - sprintf(raw->msgtype + strlen(raw->msgtype), " prn=%d", prn); + eph_t eph = {0}; + uint8_t* p = raw->buff + HLEN; + double tow, sqrtA, af0_fnav, af1_fnav, af2_fnav, af0_inav, af1_inav, af2_inav, tt; + int prn, sat, week, rcv_fnav, rcv_inav, svh_e1b, svh_e5a, svh_e5b, dvs_e1b, dvs_e5a; + int dvs_e5b, toc_fnav, toc_inav, set, sel_eph = 3; /* 1:I/NAV+2:F/NAV */ + + if (strstr(raw->opt, "-GALINAV")) sel_eph = 1; + if (strstr(raw->opt, "-GALFNAV")) sel_eph = 2; + + if (raw->len < HLEN + 220) { + trace(2, "unicore galephb length error: len=%d\n", raw->len); + return -1; + } + prn = U4(p); + p += 4; + rcv_fnav = U4(p) & 1; + p += 4; + rcv_inav = U4(p) & 1; + p += 4; + svh_e1b = U1(p) & 3; + p += 1; + svh_e5a = U1(p) & 3; + p += 1; + svh_e5b = U1(p) & 3; + p += 1; + dvs_e1b = U1(p) & 1; + p += 1; + dvs_e5a = U1(p) & 1; + p += 1; + dvs_e5b = U1(p) & 1; + p += 1; + eph.sva = U1(p); + p += 1 + 1; /* SISA index */ + eph.iode = U4(p); + p += 4; /* IODNav */ + eph.toes = U4(p); + p += 4; + sqrtA = R8(p); + p += 8; + eph.deln = R8(p); + p += 8; + eph.M0 = R8(p); + p += 8; + eph.e = R8(p); + p += 8; + eph.omg = R8(p); + p += 8; + eph.cuc = R8(p); + p += 8; + eph.cus = R8(p); + p += 8; + eph.crc = R8(p); + p += 8; + eph.crs = R8(p); + p += 8; + eph.cic = R8(p); + p += 8; + eph.cis = R8(p); + p += 8; + eph.i0 = R8(p); + p += 8; + eph.idot = R8(p); + p += 8; + eph.OMG0 = R8(p); + p += 8; + eph.OMGd = R8(p); + p += 8; + toc_fnav = U4(p); + p += 4; + af0_fnav = R8(p); + p += 8; + af1_fnav = R8(p); + p += 8; + af2_fnav = R8(p); + p += 8; + toc_inav = U4(p); + p += 4; + af0_inav = R8(p); + p += 8; + af1_inav = R8(p); + p += 8; + af2_inav = R8(p); + p += 8; + eph.tgd[0] = R8(p); + p += 8; /* BGD: E5A-E1 (s) */ + eph.tgd[1] = R8(p); /* BGD: E5B-E1 (s) */ + + if (!(sat = satno(SYS_GAL, prn))) { + trace(2, "unicore galephb satellite error: prn=%d\n", prn); + return -1; + } + if (raw->outtype) { + sprintf(raw->msgtype + strlen(raw->msgtype), " prn=%d", prn); + } + set = rcv_fnav ? 1 : 0; /* 0:I/NAV,1:F/NAV */ + if (!(sel_eph & 1) && set == 0) return 0; + if (!(sel_eph & 2) && set == 1) return 0; + + eph.sat = sat; + eph.A = sqrtA * sqrtA; + eph.f0 = set ? af0_fnav : af0_inav; + eph.f1 = set ? af1_fnav : af1_inav; + eph.f2 = set ? af2_fnav : af2_inav; + eph.svh = ((svh_e5b << 7) | (dvs_e5b << 6) | (svh_e5a << 4) | (dvs_e5a << 3) | (svh_e1b << 1) | + dvs_e1b); + eph.code = set ? ((1 << 1) + (1 << 8)) : ((1 << 0) + (1 << 2) + (1 << 9)); + eph.iodc = eph.iode; + tow = time2gpst(raw->time, &week); + eph.week = week; /* gps-week = gal-week */ + eph.toe = gpst2time(eph.week, eph.toes); + + tt = timediff(eph.toe, raw->time); + if (tt < -302400.0) + eph.week++; + else if (tt > 302400.0) + eph.week--; + eph.toe = gpst2time(eph.week, eph.toes); + eph.toc = adjweek(raw->time, set ? toc_fnav : toc_inav); + eph.ttr = raw->time; + + if (!strstr(raw->opt, "-EPHALL")) { + if (eph.iode == raw->nav.eph[sat - 1 + MAXSAT * set].iode && + fabs(timediff(eph.toe, raw->nav.eph[sat - 1 + MAXSAT * set].toe)) < 1e-9 && + fabs(timediff(eph.toc, raw->nav.eph[sat - 1 + MAXSAT * set].toc)) < 1e-9) { + return 0; /* unchanged */ } - set = rcv_fnav ? 1 : 0; /* 0:I/NAV,1:F/NAV */ - if (!(sel_eph & 1) && set == 0) return 0; - if (!(sel_eph & 2) && set == 1) return 0; - - eph.sat = sat; - eph.A = sqrtA * sqrtA; - eph.f0 = set ? af0_fnav : af0_inav; - eph.f1 = set ? af1_fnav : af1_inav; - eph.f2 = set ? af2_fnav : af2_inav; - eph.svh = ((svh_e5b << 7) | (dvs_e5b << 6) | (svh_e5a << 4) | (dvs_e5a << 3) | - (svh_e1b << 1) | dvs_e1b); - eph.code = set ? ((1 << 1) + (1 << 8)) : ((1 << 0) + (1 << 2) + (1 << 9)); - eph.iodc = eph.iode; - tow = time2gpst(raw->time, &week); - eph.week = week; /* gps-week = gal-week */ - eph.toe = gpst2time(eph.week, eph.toes); - - tt = timediff(eph.toe, raw->time); - if (tt < -302400.0) eph.week++; - else if (tt > 302400.0) eph.week--; - eph.toe = gpst2time(eph.week, eph.toes); - eph.toc = adjweek(raw->time, set ? toc_fnav : toc_inav); - eph.ttr = raw->time; - - if (!strstr(raw->opt, "-EPHALL")) { - if (eph.iode == raw->nav.eph[sat - 1 + MAXSAT * set].iode && - fabs(timediff(eph.toe, raw->nav.eph[sat - 1 + MAXSAT * set].toe)) < 1e-9 && - fabs(timediff(eph.toc, raw->nav.eph[sat - 1 + MAXSAT * set].toc)) < 1e-9) { - return 0; /* unchanged */ - } - } - raw->nav.eph[sat - 1 + MAXSAT * set] = eph; - raw->ephsat = sat; - raw->ephset = set; - return 2; + } + raw->nav.eph[sat - 1 + MAXSAT * set] = eph; + raw->ephsat = sat; + raw->ephset = set; + return 2; } -static int decode_bdsephb(raw_t* raw) -{ - eph_t eph = { 0 }; - uint8_t* p = raw->buff + HLEN; - double ura; - int prn, sat, toc; - - if (raw->len < HLEN + 232) { - trace(2, "unicore bdsephb length error: len=%d\n", raw->len); - return -1; - } - prn = U4(p); p += 4; - double tow = R8(p); p += 8; - (void)tow; - eph.svh = U4(p); p += 4; - eph.iode = U4(p); p += 4; - uint32_t AODE2 = U4(p); p += 4; - (void)AODE2; - eph.week = U4(p) - 1356; p += 4; - int zweek = U4(p); p += 4; - (void)zweek; - eph.toes = R8(p); p += 8; - eph.A = R8(p); p += 8; - eph.deln = R8(p); p += 8; - eph.M0 = R8(p); p += 8; - eph.e = R8(p); p += 8; - eph.omg = R8(p); p += 8; - eph.cuc = R8(p); p += 8; - eph.cus = R8(p); p += 8; - eph.crc = R8(p); p += 8; - eph.crs = R8(p); p += 8; - eph.cic = R8(p); p += 8; - eph.cis = R8(p); p += 8; - eph.i0 = R8(p); p += 8; - eph.idot = R8(p); p += 8; - eph.OMG0 = R8(p); p += 8; - eph.OMGd = R8(p); p += 8; - - eph.iodc = U4(p); p += 4; - toc = R8(p); p += 8; - - eph.tgd[0] = R8(p); p += 8; /* TGD1 for B1 (s) */ - eph.tgd[1] = R8(p); p += 8; /* TGD2 for B2 (s) */ - - eph.f0 = R8(p); p += 8; - eph.f1 = R8(p); p += 8; - eph.f2 = R8(p); p += 8; - - int as = U4(p); p += 4; - (void)as; - double N = R8(p); p += 8; - (void)N; - ura = R8(p); p += 8; - - - if (!(sat = satno(SYS_CMP, prn))) { - trace(2, "unicore bdsephb satellite error: prn=%d\n", prn); - return -1; - } - if (raw->outtype) { - sprintf(raw->msgtype + strlen(raw->msgtype), " prn=%d", prn); - } - eph.sat = sat; - eph.sva = uraindex(ura); - eph.toe = bdt2gpst(bdt2time(eph.week, eph.toes)); /* bdt -> gpst */ - eph.toc = bdt2gpst(bdt2time(eph.week, toc)); /* bdt -> gpst */ - eph.ttr = raw->time; - - if (!strstr(raw->opt, "-EPHALL")) { - if (fabs(timediff(raw->nav.eph[sat - 1].toe, eph.toe)) < 1e-9 && - fabs(timediff(raw->nav.eph[sat - 1].toc, eph.toc)) < 1e-9) return 0; - } - raw->nav.eph[sat - 1] = eph; - raw->ephsat = sat; - raw->ephset = 0; - return 2; +static int decode_bdsephb(raw_t* raw) { + eph_t eph = {0}; + uint8_t* p = raw->buff + HLEN; + double ura; + int prn, sat, toc; + + if (raw->len < HLEN + 232) { + trace(2, "unicore bdsephb length error: len=%d\n", raw->len); + return -1; + } + prn = U4(p); + p += 4; + double tow = R8(p); + p += 8; + (void)tow; + eph.svh = U4(p); + p += 4; + eph.iode = U4(p); + p += 4; + uint32_t AODE2 = U4(p); + p += 4; + (void)AODE2; + eph.week = U4(p) - 1356; + p += 4; + int zweek = U4(p); + p += 4; + (void)zweek; + eph.toes = R8(p); + p += 8; + eph.A = R8(p); + p += 8; + eph.deln = R8(p); + p += 8; + eph.M0 = R8(p); + p += 8; + eph.e = R8(p); + p += 8; + eph.omg = R8(p); + p += 8; + eph.cuc = R8(p); + p += 8; + eph.cus = R8(p); + p += 8; + eph.crc = R8(p); + p += 8; + eph.crs = R8(p); + p += 8; + eph.cic = R8(p); + p += 8; + eph.cis = R8(p); + p += 8; + eph.i0 = R8(p); + p += 8; + eph.idot = R8(p); + p += 8; + eph.OMG0 = R8(p); + p += 8; + eph.OMGd = R8(p); + p += 8; + + eph.iodc = U4(p); + p += 4; + toc = R8(p); + p += 8; + + eph.tgd[0] = R8(p); + p += 8; /* TGD1 for B1 (s) */ + eph.tgd[1] = R8(p); + p += 8; /* TGD2 for B2 (s) */ + + eph.f0 = R8(p); + p += 8; + eph.f1 = R8(p); + p += 8; + eph.f2 = R8(p); + p += 8; + + int as = U4(p); + p += 4; + (void)as; + double N = R8(p); + p += 8; + (void)N; + ura = R8(p); + p += 8; + + if (!(sat = satno(SYS_CMP, prn))) { + trace(2, "unicore bdsephb satellite error: prn=%d\n", prn); + return -1; + } + if (raw->outtype) { + sprintf(raw->msgtype + strlen(raw->msgtype), " prn=%d", prn); + } + eph.sat = sat; + eph.sva = uraindex(ura); + eph.toe = bdt2gpst(bdt2time(eph.week, eph.toes)); /* bdt -> gpst */ + eph.toc = bdt2gpst(bdt2time(eph.week, toc)); /* bdt -> gpst */ + eph.ttr = raw->time; + + if (!strstr(raw->opt, "-EPHALL")) { + if (fabs(timediff(raw->nav.eph[sat - 1].toe, eph.toe)) < 1e-9 && + fabs(timediff(raw->nav.eph[sat - 1].toc, eph.toc)) < 1e-9) + return 0; + } + raw->nav.eph[sat - 1] = eph; + raw->ephsat = sat; + raw->ephset = 0; + return 2; } static int decode_qzssephb(raw_t* raw) { - eph_t eph = { 0 }; - uint8_t* p = raw->buff + HLEN; - - double tow, tocs, N; - int prn, as, sat, week, zweek, health; - - if (raw->len < HLEN + 224) { - trace(2, "unicore qzssephemrisb length error: len=%d\n", raw->len); - return -1; - } - - prn = U4(p) + MINPRNQZS - 1; p += 4; - tow = R8(p); p += 8; - health = U4(p) & 0x3f; p += 4; - eph.iode = U4(p); p += 4; - int iode2 = U4(p); p += 4; - (void)iode2; - - eph.week = U4(p); p += 4; - zweek = U4(p); p += 4; - eph.toes = R8(p); p += 8; - eph.A = R8(p); p += 8; - eph.deln = R8(p); p += 8; - eph.M0 = R8(p); p += 8; - eph.e = R8(p); p += 8; - eph.omg = R8(p); p += 8; - eph.cuc = R8(p); p += 8; - eph.cus = R8(p); p += 8; - eph.crc = R8(p); p += 8; - eph.crs = R8(p); p += 8; - eph.cic = R8(p); p += 8; - eph.cis = R8(p); p += 8; - eph.i0 = R8(p); p += 8; - eph.idot = R8(p); p += 8; - eph.OMG0 = R8(p); p += 8; - eph.OMGd = R8(p); p += 8; - eph.iodc = U4(p); p += 4; - tocs = R8(p); p += 8; - eph.tgd[0] = R8(p); p += 8; - eph.f0 = R8(p); p += 8; - eph.f1 = R8(p); p += 8; - eph.f2 = R8(p); p += 8; - as = U4(p); p += 4; - N = R8(p); p += 8; - eph.sva = uraindex(R8(p)); p += 8; - - if (!(sat = satno(SYS_QZS, prn))) { - trace(2, "unicore qzsseph satellite error: prn=%d\n", prn); - return -1; - } - if (raw->outtype) { - sprintf(raw->msgtype + strlen(raw->msgtype), " prn=%d", prn); - } - - eph.sat = sat; - eph.code = 0; - eph.iodc = eph.iode; - tow = time2gpst(raw->time, &week); - eph.week = week; /* gps-week = gal-week */ - eph.toe = gpst2time(eph.week, eph.toes); - - double tt = timediff(eph.toe, raw->time); - if (tt < -302400.0) eph.week++; - else if (tt > 302400.0) eph.week--; - eph.toe = gpst2time(eph.week, eph.toes); - eph.toc = adjweek(raw->time, tocs); - eph.ttr = raw->time; - - if (!strstr(raw->opt, "-EPHALL")) { - if (fabs(timediff(raw->nav.eph[sat - 1].toe, eph.toe)) < 1e-9 && - fabs(timediff(raw->nav.eph[sat - 1].toc, eph.toc)) < 1e-9) return 0; - } - - raw->nav.eph[sat - 1] = eph; - raw->ephsat = sat; - raw->ephset = 0; - return 2; + eph_t eph = {0}; + uint8_t* p = raw->buff + HLEN; + + double tow, tocs, N; + int prn, as, sat, week, zweek, health; + + if (raw->len < HLEN + 224) { + trace(2, "unicore qzssephemrisb length error: len=%d\n", raw->len); + return -1; + } + + prn = U4(p) + MINPRNQZS - 1; + p += 4; + tow = R8(p); + p += 8; + health = U4(p) & 0x3f; + p += 4; + eph.iode = U4(p); + p += 4; + int iode2 = U4(p); + p += 4; + (void)iode2; + + eph.week = U4(p); + p += 4; + zweek = U4(p); + p += 4; + eph.toes = R8(p); + p += 8; + eph.A = R8(p); + p += 8; + eph.deln = R8(p); + p += 8; + eph.M0 = R8(p); + p += 8; + eph.e = R8(p); + p += 8; + eph.omg = R8(p); + p += 8; + eph.cuc = R8(p); + p += 8; + eph.cus = R8(p); + p += 8; + eph.crc = R8(p); + p += 8; + eph.crs = R8(p); + p += 8; + eph.cic = R8(p); + p += 8; + eph.cis = R8(p); + p += 8; + eph.i0 = R8(p); + p += 8; + eph.idot = R8(p); + p += 8; + eph.OMG0 = R8(p); + p += 8; + eph.OMGd = R8(p); + p += 8; + eph.iodc = U4(p); + p += 4; + tocs = R8(p); + p += 8; + eph.tgd[0] = R8(p); + p += 8; + eph.f0 = R8(p); + p += 8; + eph.f1 = R8(p); + p += 8; + eph.f2 = R8(p); + p += 8; + as = U4(p); + p += 4; + N = R8(p); + p += 8; + eph.sva = uraindex(R8(p)); + p += 8; + + if (!(sat = satno(SYS_QZS, prn))) { + trace(2, "unicore qzsseph satellite error: prn=%d\n", prn); + return -1; + } + if (raw->outtype) { + sprintf(raw->msgtype + strlen(raw->msgtype), " prn=%d", prn); + } + + eph.sat = sat; + eph.code = 0; + eph.iodc = eph.iode; + tow = time2gpst(raw->time, &week); + eph.week = week; /* gps-week = gal-week */ + eph.toe = gpst2time(eph.week, eph.toes); + + double tt = timediff(eph.toe, raw->time); + if (tt < -302400.0) + eph.week++; + else if (tt > 302400.0) + eph.week--; + eph.toe = gpst2time(eph.week, eph.toes); + eph.toc = adjweek(raw->time, tocs); + eph.ttr = raw->time; + + if (!strstr(raw->opt, "-EPHALL")) { + if (fabs(timediff(raw->nav.eph[sat - 1].toe, eph.toe)) < 1e-9 && + fabs(timediff(raw->nav.eph[sat - 1].toc, eph.toc)) < 1e-9) + return 0; + } + + raw->nav.eph[sat - 1] = eph; + raw->ephsat = sat; + raw->ephset = 0; + return 2; } static int decode_irnssephb(raw_t* raw) { - eph_t eph = { 0 }; - uint8_t* p = raw->buff + HLEN; - int prn, sat, l5_health, s_health; - double toc; - - if (raw->len < HLEN + 224) { - trace(2, "unicore irnssephb length error: len=%d\n", raw->len); - return -1; - } - - prn = U4(p); p += 4; - double towc = R8(p); p += 8; - (void)towc; - l5_health = U4(p) & 1; p += 4; - eph.iode = U4(p); p += 4; /* IODEC */ - s_health = U4(p); p += 4; - eph.week = U4(p); p += 4 + 4; - eph.toes = R8(p); p += 8; - eph.A = R8(p); p += 8; - eph.deln = R8(p); p += 8; - eph.M0 = R8(p); p += 8; - eph.e = R8(p); p += 8; - eph.omg = R8(p); p += 8; - - eph.cuc = R8(p); p += 8; - eph.cus = R8(p); p += 8; - eph.crc = R8(p); p += 8; - eph.crs = R8(p); p += 8; - eph.cic = R8(p); p += 8; - eph.cis = R8(p); p += 8; - - eph.i0 = R8(p); p += 8; - eph.idot = R8(p); p += 8; - eph.OMG0 = R8(p); p += 8; - eph.OMGd = R8(p); p += 8 + 4; - - toc = R8(p); p += 8; - eph.tgd[0] = R8(p); p += 8; /* TGD */ - - eph.f0 = R8(p); p += 8; - eph.f1 = R8(p); p += 8; - eph.f2 = R8(p); p += 8; - - uint32_t flag = U4(p); p += 4; - (void)flag; - double N = R8(p); p += 8; - (void)N; - eph.sva = uraindex(R8(p)); p += 8; - - if (toc != eph.toes) { /* toe and toc should be matched */ - trace(2, "unicore irnssephb toe and toc unmatch prn=%d\n", prn); - return -1; - } - if (!(sat = satno(SYS_IRN, prn))) { - trace(2, "unicore irnssephb satellite error: prn=%d\n", prn); - return 0; - } - if (raw->outtype) { - sprintf(raw->msgtype + strlen(raw->msgtype), " prn=%d", prn); - } - - eph.sat = sat; - eph.svh = (l5_health << 1) | s_health; - eph.iodc = eph.iode; - //eph.week += 1024; /* irnss-week -> gps-week */ - eph.toe = gpst2time(eph.week, eph.toes); - eph.toc = gpst2time(eph.week, toc); - eph.ttr = raw->time; - eph.tgd[1] = 0.0; - - if (!strstr(raw->opt, "-EPHALL")) { - if (fabs(timediff(raw->nav.eph[sat - 1].toe, eph.toe)) < 1e-9 && - raw->nav.eph[sat - 1].iode == eph.iode) return 0; /* unchanged */ - } - raw->nav.eph[sat - 1] = eph; - raw->ephsat = sat; - raw->ephset = 0; - return 2; + eph_t eph = {0}; + uint8_t* p = raw->buff + HLEN; + int prn, sat, l5_health, s_health; + double toc; + + if (raw->len < HLEN + 224) { + trace(2, "unicore irnssephb length error: len=%d\n", raw->len); + return -1; + } + + prn = U4(p); + p += 4; + double towc = R8(p); + p += 8; + (void)towc; + l5_health = U4(p) & 1; + p += 4; + eph.iode = U4(p); + p += 4; /* IODEC */ + s_health = U4(p); + p += 4; + eph.week = U4(p); + p += 4 + 4; + eph.toes = R8(p); + p += 8; + eph.A = R8(p); + p += 8; + eph.deln = R8(p); + p += 8; + eph.M0 = R8(p); + p += 8; + eph.e = R8(p); + p += 8; + eph.omg = R8(p); + p += 8; + + eph.cuc = R8(p); + p += 8; + eph.cus = R8(p); + p += 8; + eph.crc = R8(p); + p += 8; + eph.crs = R8(p); + p += 8; + eph.cic = R8(p); + p += 8; + eph.cis = R8(p); + p += 8; + + eph.i0 = R8(p); + p += 8; + eph.idot = R8(p); + p += 8; + eph.OMG0 = R8(p); + p += 8; + eph.OMGd = R8(p); + p += 8 + 4; + + toc = R8(p); + p += 8; + eph.tgd[0] = R8(p); + p += 8; /* TGD */ + + eph.f0 = R8(p); + p += 8; + eph.f1 = R8(p); + p += 8; + eph.f2 = R8(p); + p += 8; + + uint32_t flag = U4(p); + p += 4; + (void)flag; + double N = R8(p); + p += 8; + (void)N; + eph.sva = uraindex(R8(p)); + p += 8; + + if (toc != eph.toes) { /* toe and toc should be matched */ + trace(2, "unicore irnssephb toe and toc unmatch prn=%d\n", prn); + return -1; + } + if (!(sat = satno(SYS_IRN, prn))) { + trace(2, "unicore irnssephb satellite error: prn=%d\n", prn); + return 0; + } + if (raw->outtype) { + sprintf(raw->msgtype + strlen(raw->msgtype), " prn=%d", prn); + } + + eph.sat = sat; + eph.svh = (l5_health << 1) | s_health; + eph.iodc = eph.iode; + // eph.week += 1024; /* irnss-week -> gps-week */ + eph.toe = gpst2time(eph.week, eph.toes); + eph.toc = gpst2time(eph.week, toc); + eph.ttr = raw->time; + eph.tgd[1] = 0.0; + + if (!strstr(raw->opt, "-EPHALL")) { + if (fabs(timediff(raw->nav.eph[sat - 1].toe, eph.toe)) < 1e-9 && + raw->nav.eph[sat - 1].iode == eph.iode) + return 0; /* unchanged */ + } + raw->nav.eph[sat - 1] = eph; + raw->ephsat = sat; + raw->ephset = 0; + return 2; } // decode OBSVMB -static int decode_obsvmb(raw_t* raw) -{ - uint8_t* p = raw->buff + HLEN; - char* q; - double psr, adr, dop, snr, lockt, tt, freq, glo_bias = 0.0; - int i, index, prn, sat, sys, code, idx, plock, clock, lli; - int gfrq; - - if ((q = strstr(raw->opt, "-GLOBIAS="))) sscanf(q, "-GLOBIAS=%lf", &glo_bias); - - int rcvstds = 0; - if (strstr(raw->opt, "-RCVSTDS")) rcvstds = 1; - - int nobs = U4(p); - if (nobs == 0) return 0; - if (raw->len < HLEN + 4 + nobs * 40) { - trace(2, "unicore obsvmb length error: len=%d nobs=%d\n", raw->len, nobs); - return -1; - } - if (raw->outtype) { - sprintf(raw->msgtype + strlen(raw->msgtype), " nobs=%d", nobs); +static int decode_obsvmb(raw_t* raw) { + uint8_t* p = raw->buff + HLEN; + char* q; + double psr, adr, dop, snr, lockt, tt, freq, glo_bias = 0.0; + int i, index, prn, sat, sys, code, idx, plock, clock, lli; + int gfrq; + + if ((q = strstr(raw->opt, "-GLOBIAS="))) sscanf(q, "-GLOBIAS=%lf", &glo_bias); + + int rcvstds = 0; + if (strstr(raw->opt, "-RCVSTDS")) rcvstds = 1; + + int nobs = U4(p); + if (nobs == 0) return 0; + if (raw->len < HLEN + 4 + nobs * 40) { + trace(2, "unicore obsvmb length error: len=%d nobs=%d\n", raw->len, nobs); + return -1; + } + if (raw->outtype) { + sprintf(raw->msgtype + strlen(raw->msgtype), " nobs=%d", nobs); + } + + p += 4; // Number of observation messages + + for (i = 0; i < nobs; i++, p += 40) { + uint32_t trk_stat = U4(p + 36); + + if ((idx = decode_track_stat(trk_stat, &sys, &code, &plock, &clock)) < 0) { + continue; } + prn = U2(p + 2); - p += 4; // Number of observation messages - - for (i = 0; i < nobs; i++, p += 40) { - uint32_t trk_stat = U4(p + 36); - - if ((idx = decode_track_stat(trk_stat, &sys, &code, &plock, &clock)) < 0) { - continue; - } - prn = U2(p + 2); - - - if (sys == SYS_GLO) prn -= 37; - if (sys == SYS_SBS && prn >= MINPRNQZS_S && prn <= MAXPRNQZS_S && code == CODE_L1C) { - sys = SYS_QZS; - prn += 10; - code = CODE_L1Z; /* QZS L1S */ - } - if (!(sat = satno(sys, prn))) { - trace(3, "unicore obsvm satellite number error: sys=%d,prn=%d\n", sys, prn); - continue; - } - //if (sys == SYS_GLO && !parity) continue; - - if ((idx = checkpri(raw->opt, sys, code, idx)) < 0) continue; - - gfrq = U2(p) + 1; /* GLONASS FCN+8 */ - psr = R8(p + 4); - adr = R8(p + 12); - dop = R4(p + 24); - snr = U2(p + 28) / 100.0; - lockt = R4(p + 32); - - if (sys == SYS_GLO) { - freq = sat2freq(sat, (uint8_t)code, &raw->nav); - adr -= glo_bias * freq / CLIGHT; - if (!raw->nav.glo_fcn[prn - 1]) { - raw->nav.glo_fcn[prn - 1] = gfrq; /* fcn+8 */ - } - } - if (raw->tobs[sat - 1][idx].time != 0) { - tt = timediff(raw->time, raw->tobs[sat - 1][idx]); - lli = lockt - raw->lockt[sat - 1][idx] + 0.05 <= tt ? LLI_SLIP : 0; - } - else { - lli = 0; - } - // if (!parity) lli |= LLI_HALFC; - // if (halfc) lli |= LLI_HALFA; - raw->tobs[sat - 1][idx] = raw->time; - raw->lockt[sat - 1][idx] = lockt; - raw->halfc[sat - 1][idx] = 0; - - if (!clock) psr = 0.0; /* code unlock */ - if (!plock) adr = dop = 0.0; /* phase unlock */ - - if (fabs(timediff(raw->obs.data[0].time, raw->time)) > 1E-9) { - raw->obs.n = 0; - } - if ((index = obsindex(&raw->obs, raw->time, sat)) >= 0) { - raw->obs.data[index].L[idx] = -adr; - raw->obs.data[index].P[idx] = psr; - raw->obs.data[index].D[idx] = (float)dop; - raw->obs.data[index].SNR[idx] = snr; - raw->obs.data[index].LLI[idx] = (uint8_t)lli; - raw->obs.data[index].code[idx] = (uint8_t)code; - if (rcvstds) { - double pstd = U2(p + 20) * 0.01; // Meters - raw->obs.data[index].Pstd[idx] = pstd; - double lstd = U2(p + 22) * 0.0001; // Cycles - raw->obs.data[index].Lstd[idx] = lstd; - } - } + if (sys == SYS_GLO) prn -= 37; + if (sys == SYS_SBS && prn >= MINPRNQZS_S && prn <= MAXPRNQZS_S && code == CODE_L1C) { + sys = SYS_QZS; + prn += 10; + code = CODE_L1Z; /* QZS L1S */ } - return 1; -} - - -/* decode Unicore message -----------------------------------------*/ -static int decode_unicore(raw_t* raw) -{ - double tow; - char tstr[40]; - int stat, week, type = U2(raw->buff + 4); - - trace(3, "decode_unicore: type=%3d len=%d\n", type, raw->len); - - /* check crc32 */ - if (rtk_crc32(raw->buff, raw->len) != U4(raw->buff + raw->len)) { - trace(2, "unicore crc error: type=%3d len=%d\n", type, raw->len); - return -1; + if (!(sat = satno(sys, prn))) { + trace(3, "unicore obsvm satellite number error: sys=%d,prn=%d\n", sys, prn); + continue; } - stat = U1(raw->buff + 9); - week = U2(raw->buff + 10); - - if (stat == 201 || week == 0) { - trace(3, "unicore time error: type=%3d stat=%d week=%d\n", type, - stat, week); - return 0; + // if (sys == SYS_GLO && !parity) continue; + + if ((idx = checkpri(raw->opt, sys, code, idx)) < 0) continue; + + gfrq = U2(p) + 1; /* GLONASS FCN+8 */ + psr = R8(p + 4); + adr = R8(p + 12); + dop = R4(p + 24); + snr = U2(p + 28) / 100.0; + lockt = R4(p + 32); + + if (sys == SYS_GLO) { + freq = sat2freq(sat, (uint8_t)code, &raw->nav); + adr -= glo_bias * freq / CLIGHT; + if (!raw->nav.glo_fcn[prn - 1]) { + raw->nav.glo_fcn[prn - 1] = gfrq; /* fcn+8 */ + } } - week = adjgpsweek(week); - tow = U4(raw->buff + 12) * 0.001; - raw->time = gpst2time(week, tow); - double ep[6]; - time2epoch_n(raw->time, ep, 7); + if (raw->tobs[sat - 1][idx].time != 0) { + tt = timediff(raw->time, raw->tobs[sat - 1][idx]); + lli = lockt - raw->lockt[sat - 1][idx] + 0.05 <= tt ? LLI_SLIP : 0; + } else { + lli = 0; + } + // if (!parity) lli |= LLI_HALFC; + // if (halfc) lli |= LLI_HALFA; + raw->tobs[sat - 1][idx] = raw->time; + raw->lockt[sat - 1][idx] = lockt; + raw->halfc[sat - 1][idx] = 0; + if (!clock) psr = 0.0; /* code unlock */ + if (!plock) adr = dop = 0.0; /* phase unlock */ - if (raw->outtype) { - time2str(gpst2time(week, tow), tstr, 2); - sprintf(raw->msgtype, "UNICORE %4d (%4d): %s", type, raw->len, tstr); + if (fabs(timediff(raw->obs.data[0].time, raw->time)) > 1E-9) { + raw->obs.n = 0; } - - switch (type) { - case ID_OBSVM: return decode_obsvmb(raw); - case ID_GPSEPH: return decode_gpsephb(raw); - case ID_GLOEPH: return decode_gloephb(raw); - case ID_GALEPH: return decode_galephb(raw); - case ID_BDSEPH: return decode_bdsephb(raw); - case ID_QZSSEPH: return decode_qzssephb(raw); - case ID_IRNSSEPH: return decode_irnssephb(raw); + if ((index = obsindex(&raw->obs, raw->time, sat)) >= 0) { + raw->obs.data[index].L[idx] = -adr; + raw->obs.data[index].P[idx] = psr; + raw->obs.data[index].D[idx] = (float)dop; + raw->obs.data[index].SNR[idx] = snr; + raw->obs.data[index].LLI[idx] = (uint8_t)lli; + raw->obs.data[index].code[idx] = (uint8_t)code; + if (rcvstds) { + double pstd = U2(p + 20) * 0.01; // Meters + raw->obs.data[index].Pstd[idx] = pstd; + double lstd = U2(p + 22) * 0.0001; // Cycles + raw->obs.data[index].Lstd[idx] = lstd; + } } - return 0; + } + return 1; } +/* decode Unicore message -----------------------------------------*/ +static int decode_unicore(raw_t* raw) { + double tow; + char tstr[40]; + int stat, week, type = U2(raw->buff + 4); + + trace(3, "decode_unicore: type=%3d len=%d\n", type, raw->len); + + /* check crc32 */ + if (rtk_crc32(raw->buff, raw->len) != U4(raw->buff + raw->len)) { + trace(2, "unicore crc error: type=%3d len=%d\n", type, raw->len); + return -1; + } + stat = U1(raw->buff + 9); + week = U2(raw->buff + 10); + + if (stat == 201 || week == 0) { + trace(3, "unicore time error: type=%3d stat=%d week=%d\n", type, stat, week); + return 0; + } + week = adjgpsweek(week); + tow = U4(raw->buff + 12) * 0.001; + raw->time = gpst2time(week, tow); + double ep[6]; + time2epoch_n(raw->time, ep, 7); + + if (raw->outtype) { + time2str(gpst2time(week, tow), tstr, 2); + sprintf(raw->msgtype, "UNICORE %4d (%4d): %s", type, raw->len, tstr); + } + + switch (type) { + case ID_OBSVM: + return decode_obsvmb(raw); + case ID_GPSEPH: + return decode_gpsephb(raw); + case ID_GLOEPH: + return decode_gloephb(raw); + case ID_GALEPH: + return decode_galephb(raw); + case ID_BDSEPH: + return decode_bdsephb(raw); + case ID_QZSSEPH: + return decode_qzssephb(raw); + case ID_IRNSSEPH: + return decode_irnssephb(raw); + } + return 0; +} /* input Unicore raw data from stream ------------------------------- -* fetch next Unicore raw data and input a mesasge from stream -* args : raw_t *raw IO receiver raw data control struct -* uint8_t data I stream data (1 byte) -* return : status (-1: error message, 0: no message, 1: input observation data, -* 2: input ephemeris, 3: input sbas message, -* 9: input ion/utc parameter) -*/ -extern int input_unicore(raw_t* raw, uint8_t data) -{ - trace(5, "input_unicore: data=%02x\n", data); - - /* synchronize frame */ - if (raw->nbyte == 0) { - if (sync_unicore(raw->buff, data)) raw->nbyte = 3; - return 0; - } - raw->buff[raw->nbyte++] = data; + * fetch next Unicore raw data and input a mesasge from stream + * args : raw_t *raw IO receiver raw data control struct + * uint8_t data I stream data (1 byte) + * return : status (-1: error message, 0: no message, 1: input observation data, + * 2: input ephemeris, 3: input sbas message, + * 9: input ion/utc parameter) + */ +extern int input_unicore(raw_t* raw, uint8_t data) { + trace(5, "input_unicore: data=%02x\n", data); + + /* synchronize frame */ + if (raw->nbyte == 0) { + if (sync_unicore(raw->buff, data)) raw->nbyte = 3; + return 0; + } + raw->buff[raw->nbyte++] = data; - if (raw->nbyte == 8 && (raw->len = U2(raw->buff + 6) + HLEN) > MAXRAWLEN - 4) { - trace(2, "unicore length error: len=%d\n", raw->len); - raw->nbyte = 0; - return -1; - } - if (raw->nbyte < 8 || raw->nbyte < raw->len + 4) return 0; + if (raw->nbyte == 8 && (raw->len = U2(raw->buff + 6) + HLEN) > MAXRAWLEN - 4) { + trace(2, "unicore length error: len=%d\n", raw->len); raw->nbyte = 0; + return -1; + } + if (raw->nbyte < 8 || raw->nbyte < raw->len + 4) return 0; + raw->nbyte = 0; - return decode_unicore(raw); + return decode_unicore(raw); } - /* input Unicore raw data from file --------------------------------- -* fetch next Unicore raw data and input a message from file -* args : raw_t *raw IO receiver raw data control struct -* FILE *fp I file pointer -* return : status(-2: end of file, -1...9: same as above) -*-----------------------------------------------------------------------------*/ -extern int input_unicoref(raw_t* raw, FILE* fp) -{ - int i, data; - - trace(4, "input_unicoref:\n"); - - /* synchronize frame */ - if (raw->nbyte == 0) { - for (i = 0;; i++) { - if ((data = fgetc(fp)) == EOF) return -2; - if (sync_unicore(raw->buff, (uint8_t)data)) break; - if (i >= 4096) return 0; - } + * fetch next Unicore raw data and input a message from file + * args : raw_t *raw IO receiver raw data control struct + * FILE *fp I file pointer + * return : status(-2: end of file, -1...9: same as above) + *-----------------------------------------------------------------------------*/ +extern int input_unicoref(raw_t* raw, FILE* fp) { + int i, data; + + trace(4, "input_unicoref:\n"); + + /* synchronize frame */ + if (raw->nbyte == 0) { + for (i = 0;; i++) { + if ((data = fgetc(fp)) == EOF) return -2; + if (sync_unicore(raw->buff, (uint8_t)data)) break; + if (i >= 4096) return 0; } - if (fread(raw->buff + 3, 7, 1, fp) < 1) return -2; - raw->nbyte = 10; + } + if (fread(raw->buff + 3, 7, 1, fp) < 1) return -2; + raw->nbyte = 10; - if ((raw->len = U2(raw->buff + 6) + HLEN) > MAXRAWLEN - 4) { - trace(2, "unicore length error: len=%d\n", raw->len); - raw->nbyte = 0; - return -1; - } - if (fread(raw->buff + 10, raw->len - 6, 1, fp) < 1) return -2; + if ((raw->len = U2(raw->buff + 6) + HLEN) > MAXRAWLEN - 4) { + trace(2, "unicore length error: len=%d\n", raw->len); raw->nbyte = 0; + return -1; + } + if (fread(raw->buff + 10, raw->len - 6, 1, fp) < 1) return -2; + raw->nbyte = 0; - return decode_unicore(raw); + return decode_unicore(raw); } diff --git a/src/rcvraw.c b/src/rcvraw.c index 99ce3ad92..bd9a1d0d6 100644 --- a/src/rcvraw.c +++ b/src/rcvraw.c @@ -1,1475 +1,1708 @@ /*------------------------------------------------------------------------------ -* rcvraw.c : receiver raw data functions -* -* Copyright (C) 2009-2020 by T.TAKASU, All rights reserved. -* Copyright (C) 2014 by T.SUZUKI, All rights reserved. -* -* references : -* [1] IS-GPS-200K, Navstar GPS Space Segment/Navigation User Interfaces, -* March 4, 2019 -* [2] Global navigation satellite system GLONASS interface control document -* navigation radiosignal in bands L1,L2 (version 5.1), 2008 -* [3] BeiDou satellite navigation system signal in space interface control -* document open service signal B1I (version 3.0), February, 2019 -* [4] Quasi-Zenith Satellite System Interface Specification Satellite -* Positioning, Navigation and Timing Service (IS-QZSS-PN-003), November -* 5, 2018 -* [5] European GNSS (Galileo) Open Service Signal In Space Interface Control -* Document, Issue 1.3, December, 2016 -* [6] ISRO-IRNSS-ICD-SPS-1.1, Indian Regional Navigation Satellite System -* Signal in Space ICD for Standard Positioning Service version 1.1, -* August, 2017 -* -* version : $Revision:$ $Date:$ -* history : 2009/04/10 1.0 new -* 2009/06/02 1.1 support glonass -* 2010/07/31 1.2 support eph_t struct change -* 2010/12/06 1.3 add almanac decoding, support of GW10 -* change api decode_frame() -* 2013/04/11 1.4 fix bug on decode fit interval -* 2014/01/31 1.5 fix bug on decode fit interval -* 2014/06/22 1.6 add api decode_glostr() -* 2014/06/22 1.7 add api decode_bds_d1(), decode_bds_d2() -* 2014/08/14 1.8 add test_glostr() -* add support input format rt17 -* 2014/08/31 1.9 suppress warning -* 2014/11/07 1.10 support qzss navigation subframes -* 2016/01/23 1.11 enable septentrio -* 2016/01/28 1.12 add decode_gal_inav() for galileo I/NAV -* 2016/07/04 1.13 support CMR/CMR+ -* 2017/05/26 1.14 support TERSUS -* 2018/10/10 1.15 update reference [5] -* add set of eph->code/flag for galileo and beidou -* 2018/12/05 1.16 add test of galileo i/nav word type 5 -* 2020/11/30 1.17 add API decode_gal_fnav() and decode_irn_nav() -* allocate double size of raw->nav.eph[] for multiple -* ephemeris sets (e.g. Gallieo I/NAV and F/NAV) -* no support of STRFMT_LEXR by API input_raw/rawf() -* update references [1], [3] and [4] -* add reference [6] -* use integer types in stdint.h -*-----------------------------------------------------------------------------*/ + * rcvraw.c : receiver raw data functions + * + * Copyright (C) 2009-2020 by T.TAKASU, All rights reserved. + * Copyright (C) 2014 by T.SUZUKI, All rights reserved. + * + * references : + * [1] IS-GPS-200K, Navstar GPS Space Segment/Navigation User Interfaces, + * March 4, 2019 + * [2] Global navigation satellite system GLONASS interface control document + * navigation radiosignal in bands L1,L2 (version 5.1), 2008 + * [3] BeiDou satellite navigation system signal in space interface control + * document open service signal B1I (version 3.0), February, 2019 + * [4] Quasi-Zenith Satellite System Interface Specification Satellite + * Positioning, Navigation and Timing Service (IS-QZSS-PN-003), November + * 5, 2018 + * [5] European GNSS (Galileo) Open Service Signal In Space Interface Control + * Document, Issue 1.3, December, 2016 + * [6] ISRO-IRNSS-ICD-SPS-1.1, Indian Regional Navigation Satellite System + * Signal in Space ICD for Standard Positioning Service version 1.1, + * August, 2017 + * + * version : $Revision:$ $Date:$ + * history : 2009/04/10 1.0 new + * 2009/06/02 1.1 support glonass + * 2010/07/31 1.2 support eph_t struct change + * 2010/12/06 1.3 add almanac decoding, support of GW10 + * change api decode_frame() + * 2013/04/11 1.4 fix bug on decode fit interval + * 2014/01/31 1.5 fix bug on decode fit interval + * 2014/06/22 1.6 add api decode_glostr() + * 2014/06/22 1.7 add api decode_bds_d1(), decode_bds_d2() + * 2014/08/14 1.8 add test_glostr() + * add support input format rt17 + * 2014/08/31 1.9 suppress warning + * 2014/11/07 1.10 support qzss navigation subframes + * 2016/01/23 1.11 enable septentrio + * 2016/01/28 1.12 add decode_gal_inav() for galileo I/NAV + * 2016/07/04 1.13 support CMR/CMR+ + * 2017/05/26 1.14 support TERSUS + * 2018/10/10 1.15 update reference [5] + * add set of eph->code/flag for galileo and beidou + * 2018/12/05 1.16 add test of galileo i/nav word type 5 + * 2020/11/30 1.17 add API decode_gal_fnav() and decode_irn_nav() + * allocate double size of raw->nav.eph[] for multiple + * ephemeris sets (e.g. Gallieo I/NAV and F/NAV) + * no support of STRFMT_LEXR by API input_raw/rawf() + * update references [1], [3] and [4] + * add reference [6] + * use integer types in stdint.h + *-----------------------------------------------------------------------------*/ #include "rtklib.h" -#define P2_8 0.00390625 /* 2^-8 */ -#define P2_15 3.051757812500000E-05 /* 2^-15 */ -#define P2_28 3.725290298461914E-09 /* 2^-28 */ -#define P2_34 5.820766091346740E-11 /* 2^-34 */ -#define P2_41 4.547473508864641E-13 /* 2^-41 */ -#define P2_46 1.421085471520200E-14 /* 2^-46 */ -#define P2_51 4.440892098500626E-16 /* 2^-51 */ -#define P2_59 1.734723475976810E-18 /* 2^-59 */ -#define P2_66 1.355252715606881E-20 /* 2^-66 */ -#define P2_68 3.388131789017201E-21 /* 2^-68 */ -#define P2P11 2048.0 /* 2^11 */ -#define P2P12 4096.0 /* 2^12 */ -#define P2P14 16384.0 /* 2^14 */ -#define P2P15 32768.0 /* 2^15 */ -#define P2P16 65536.0 /* 2^16 */ - -#define SQR(x) ((x)*(x)) +#define P2_8 0.00390625 /* 2^-8 */ +#define P2_15 3.051757812500000E-05 /* 2^-15 */ +#define P2_28 3.725290298461914E-09 /* 2^-28 */ +#define P2_34 5.820766091346740E-11 /* 2^-34 */ +#define P2_41 4.547473508864641E-13 /* 2^-41 */ +#define P2_46 1.421085471520200E-14 /* 2^-46 */ +#define P2_51 4.440892098500626E-16 /* 2^-51 */ +#define P2_59 1.734723475976810E-18 /* 2^-59 */ +#define P2_66 1.355252715606881E-20 /* 2^-66 */ +#define P2_68 3.388131789017201E-21 /* 2^-68 */ +#define P2P11 2048.0 /* 2^11 */ +#define P2P12 4096.0 /* 2^12 */ +#define P2P14 16384.0 /* 2^14 */ +#define P2P15 32768.0 /* 2^15 */ +#define P2P16 65536.0 /* 2^16 */ + +#define SQR(x) ((x) * (x)) /* get two component bits ----------------------------------------------------*/ -static uint32_t getbitu2(const uint8_t *buff, int p1, int l1, int p2, int l2) -{ - return (getbitu(buff,p1,l1)<eph_irn.toes+302400.0) week--; - eph_irn.ttr=gpst2time(week,tow1); - *eph=eph_irn; - return 1; +static int decode_irn_eph(const uint8_t *buff, eph_t *eph) { + eph_t eph_irn = {0}; + double tow1, tow2, toc, sqrtA; + int i, id1, id2, week; + + trace(4, "decode_irn_eph:\n"); + + i = 8; /* subframe 1 */ + tow1 = getbitu(buff, i, 17) * 12.0; + i += 17 + 2; + id1 = getbitu(buff, i, 2); + i += 2 + 1; + week = getbitu(buff, i, 10); + i += 10; + eph_irn.f0 = getbits(buff, i, 22) * P2_31; + i += 22; + eph_irn.f1 = getbits(buff, i, 16) * P2_43; + i += 16; + eph_irn.f2 = getbits(buff, i, 8) * P2_55; + i += 8; + eph_irn.sva = getbitu(buff, i, 4); + i += 4; + toc = getbitu(buff, i, 16) * 16.0; + i += 16; + eph_irn.tgd[0] = getbits(buff, i, 8) * P2_31; + i += 8; + eph_irn.deln = getbits(buff, i, 22) * P2_41 * SC2RAD; + i += 22; + eph_irn.iode = getbitu(buff, i, 8); + i += 8 + 10; + eph_irn.svh = getbitu(buff, i, 2); + i += 2; + eph_irn.cuc = getbits(buff, i, 15) * P2_28; + i += 15; + eph_irn.cus = getbits(buff, i, 15) * P2_28; + i += 15; + eph_irn.cic = getbits(buff, i, 15) * P2_28; + i += 15; + eph_irn.cis = getbits(buff, i, 15) * P2_28; + i += 15; + eph_irn.crc = getbits(buff, i, 15) * 0.0625; + i += 15; + eph_irn.crs = getbits(buff, i, 15) * 0.0625; + i += 15; + eph_irn.idot = getbits(buff, i, 14) * P2_43 * SC2RAD; + + i = 8 * 37 + 8; /* subframe 2 */ + tow2 = getbitu(buff, i, 17) * 12.0; + i += 17 + 2; + id2 = getbitu(buff, i, 2); + i += 2 + 1; + eph_irn.M0 = getbits(buff, i, 32) * P2_31 * SC2RAD; + i += 32; + eph_irn.toes = getbitu(buff, i, 16) * 16.0; + i += 16; + eph_irn.e = getbitu(buff, i, 32) * P2_33; + i += 32; + sqrtA = getbitu(buff, i, 32) * P2_19; + i += 32; + eph_irn.OMG0 = getbits(buff, i, 32) * P2_31 * SC2RAD; + i += 32; + eph_irn.omg = getbits(buff, i, 32) * P2_31 * SC2RAD; + i += 32; + eph_irn.OMGd = getbits(buff, i, 22) * P2_41 * SC2RAD; + i += 22; + eph_irn.i0 = getbits(buff, i, 32) * P2_31 * SC2RAD; + + /* test subframe id, tow and consistency of toe and toc */ + if (id1 != 0 || id2 != 1 || tow1 + 12.0 != tow2 || toc != eph_irn.toes) { + return 0; + } + eph_irn.A = SQR(sqrtA); + eph_irn.iodc = eph_irn.iode; + week = adjgpsweek(week); + eph_irn.week = week; /* week number consistent to toe */ + eph_irn.toe = eph_irn.toc = gpst2time(eph_irn.week, eph_irn.toes); + if (tow1 < eph_irn.toes - 302400.0) + week++; + else if (tow1 > eph_irn.toes + 302400.0) + week--; + eph_irn.ttr = gpst2time(week, tow1); + *eph = eph_irn; + return 1; } /* decode NavIC/IRNSS iono parameters ----------------------------------------*/ -static int decode_irn_ion(const uint8_t *buff, double *ion) -{ - int i,id3,id4; - - trace(4,"decode_irn_ion:\n"); - - /* subframe 3 and 4 message ids */ - id3=getbitu(buff,8*37*2+30,6); - id4=getbitu(buff,8*37*3+30,6); - - /* 11: eop and ionosphere coefficients */ - if (id3==11) i=8*37*2+174; - else if (id4==11) i=8*37*3+174; - else return 0; - - ion[0]=getbits(buff,i,8)*P2_30; i+=8; - ion[1]=getbits(buff,i,8)*P2_27; i+=8; - ion[2]=getbits(buff,i,8)*P2_24; i+=8; - ion[3]=getbits(buff,i,8)*P2_24; i+=8; - ion[4]=getbits(buff,i,8)*P2P11; i+=8; - ion[5]=getbits(buff,i,8)*P2P14; i+=8; - ion[6]=getbits(buff,i,8)*P2P16; i+=8; - ion[7]=getbits(buff,i,8)*P2P16; - return 1; +static int decode_irn_ion(const uint8_t *buff, double *ion) { + int i, id3, id4; + + trace(4, "decode_irn_ion:\n"); + + /* subframe 3 and 4 message ids */ + id3 = getbitu(buff, 8 * 37 * 2 + 30, 6); + id4 = getbitu(buff, 8 * 37 * 3 + 30, 6); + + /* 11: eop and ionosphere coefficients */ + if (id3 == 11) + i = 8 * 37 * 2 + 174; + else if (id4 == 11) + i = 8 * 37 * 3 + 174; + else + return 0; + + ion[0] = getbits(buff, i, 8) * P2_30; + i += 8; + ion[1] = getbits(buff, i, 8) * P2_27; + i += 8; + ion[2] = getbits(buff, i, 8) * P2_24; + i += 8; + ion[3] = getbits(buff, i, 8) * P2_24; + i += 8; + ion[4] = getbits(buff, i, 8) * P2P11; + i += 8; + ion[5] = getbits(buff, i, 8) * P2P14; + i += 8; + ion[6] = getbits(buff, i, 8) * P2P16; + i += 8; + ion[7] = getbits(buff, i, 8) * P2P16; + return 1; } /* decode NavIC/IRNSS UTC parameters -----------------------------------------*/ -static int decode_irn_utc(const uint8_t *buff, double *utc) -{ - int i,id3,id4; - - trace(4,"decode_irn_utc:\n"); - - /* subframe 3 and 4 message ids */ - id3=getbitu(buff,8*37*2+30,6); - id4=getbitu(buff,8*37*3+30,6); - - /* 9 or 26: utc and time sync parameters */ - if (id3==9||id3==26) i=8*37*2+36; - else if (id4==9||id4==26) i=8*37*3+36; - else return 0; - - utc[0]=getbits(buff,i,16)*P2_35; i+=16; /* A0 */ - utc[1]=getbits(buff,i,13)*P2_51; i+=13; /* A1 */ - utc[8]=getbits(buff,i, 7)*P2_68; i+= 7; /* A2 */ - utc[4]=getbits(buff,i, 8); i+= 8; /* dt_LS */ - utc[2]=getbitu(buff,i,16)*16.0; i+=16; /* tot */ - utc[3]=getbitu(buff,i,10); i+=10; /* WNt */ - utc[5]=getbitu(buff,i,10); i+=10; /* WN_LSF */ - utc[6]=getbitu(buff,i, 4); i+= 4; /* DN */ - utc[7]=getbits(buff,i, 8); /* dt_LSF */ - return 1; +static int decode_irn_utc(const uint8_t *buff, double *utc) { + int i, id3, id4; + + trace(4, "decode_irn_utc:\n"); + + /* subframe 3 and 4 message ids */ + id3 = getbitu(buff, 8 * 37 * 2 + 30, 6); + id4 = getbitu(buff, 8 * 37 * 3 + 30, 6); + + /* 9 or 26: utc and time sync parameters */ + if (id3 == 9 || id3 == 26) + i = 8 * 37 * 2 + 36; + else if (id4 == 9 || id4 == 26) + i = 8 * 37 * 3 + 36; + else + return 0; + + utc[0] = getbits(buff, i, 16) * P2_35; + i += 16; /* A0 */ + utc[1] = getbits(buff, i, 13) * P2_51; + i += 13; /* A1 */ + utc[8] = getbits(buff, i, 7) * P2_68; + i += 7; /* A2 */ + utc[4] = getbits(buff, i, 8); + i += 8; /* dt_LS */ + utc[2] = getbitu(buff, i, 16) * 16.0; + i += 16; /* tot */ + utc[3] = getbitu(buff, i, 10); + i += 10; /* WNt */ + utc[5] = getbitu(buff, i, 10); + i += 10; /* WN_LSF */ + utc[6] = getbitu(buff, i, 4); + i += 4; /* DN */ + utc[7] = getbits(buff, i, 8); /* dt_LSF */ + return 1; } /* decode NavIC/IRNSS navigation data ------------------------------------------ -* decode NavIC/IRNSS navigation data (ref [6] 5.9-6) -* args : uint8_t *buff I NavIC/IRNSS subframe data (CRC checked) -* buff[ 0- 36]: subframe 1 (292 bits) -* buff[ 37- 73]: subframe 2 -* buff[ 74-110]: subframe 3 -* buff[111-147]: subframe 4 -* eph_t *eph IO NavIC/IRNSS ephemeris (NULL: not output) -* double *ion IO NavIC/IRNSS iono parametgers (NULL: not output) -* ion[0-3]: alpha_0,...,alpha_3 -* ion[4-7]: beta_0,...,beta_3 -* double *utc IO NavIC/IRNSS UTC parametgers (NULL: not output) -* utc[0-3]: A0,A1,tot,WNt -* utc[4-7]: dt_LS,WN_LSF,DN,dt_LSF -* utc[8] : A2 -* return : status (1:ok,0:error) -*-----------------------------------------------------------------------------*/ -extern int decode_irn_nav(const uint8_t *buff, eph_t *eph, double *ion, - double *utc) -{ - trace(4,"decode_irn_nav:\n"); - - if (eph&&!decode_irn_eph(buff,eph)) return 0; - if (ion&&!decode_irn_ion(buff,ion)) return 0; - if (utc&&!decode_irn_utc(buff,utc)) return 0; - return 1; + * decode NavIC/IRNSS navigation data (ref [6] 5.9-6) + * args : uint8_t *buff I NavIC/IRNSS subframe data (CRC checked) + * buff[ 0- 36]: subframe 1 (292 bits) + * buff[ 37- 73]: subframe 2 + * buff[ 74-110]: subframe 3 + * buff[111-147]: subframe 4 + * eph_t *eph IO NavIC/IRNSS ephemeris (NULL: not output) + * double *ion IO NavIC/IRNSS iono parametgers (NULL: not output) + * ion[0-3]: alpha_0,...,alpha_3 + * ion[4-7]: beta_0,...,beta_3 + * double *utc IO NavIC/IRNSS UTC parametgers (NULL: not output) + * utc[0-3]: A0,A1,tot,WNt + * utc[4-7]: dt_LS,WN_LSF,DN,dt_LSF + * utc[8] : A2 + * return : status (1:ok,0:error) + *-----------------------------------------------------------------------------*/ +extern int decode_irn_nav(const uint8_t *buff, eph_t *eph, double *ion, double *utc) { + trace(4, "decode_irn_nav:\n"); + + if (eph && !decode_irn_eph(buff, eph)) return 0; + if (ion && !decode_irn_ion(buff, ion)) return 0; + if (utc && !decode_irn_utc(buff, utc)) return 0; + return 1; } /* decode Galileo I/NAV ephemeris --------------------------------------------*/ -static int decode_gal_inav_eph(const uint8_t *buff, eph_t *eph) -{ - eph_t eph_gal={0}; - double tow,toc,tt,sqrtA; - int i,week,svid,e5b_hs,e1b_hs,e5b_dvs,e1b_dvs,type[6],iod_nav[4]; - - trace(4,"decode_gal_inav_eph:\n"); - - i=128; /* word type 1 */ - type[0] =getbitu(buff,i, 6); i+= 6; - iod_nav[0] =getbitu(buff,i,10); i+=10; - eph_gal.toes=getbitu(buff,i,14)*60.0; i+=14; - eph_gal.M0 =getbits(buff,i,32)*P2_31*SC2RAD; i+=32; - eph_gal.e =getbitu(buff,i,32)*P2_33; i+=32; - sqrtA =getbitu(buff,i,32)*P2_19; - - i=128*2; /* word type 2 */ - type[1] =getbitu(buff,i, 6); i+= 6; - iod_nav[1] =getbitu(buff,i,10); i+=10; - eph_gal.OMG0=getbits(buff,i,32)*P2_31*SC2RAD; i+=32; - eph_gal.i0 =getbits(buff,i,32)*P2_31*SC2RAD; i+=32; - eph_gal.omg =getbits(buff,i,32)*P2_31*SC2RAD; i+=32; - eph_gal.idot=getbits(buff,i,14)*P2_43*SC2RAD; - - i=128*3; /* word type 3 */ - type[2] =getbitu(buff,i, 6); i+= 6; - iod_nav[2] =getbitu(buff,i,10); i+=10; - eph_gal.OMGd=getbits(buff,i,24)*P2_43*SC2RAD; i+=24; - eph_gal.deln=getbits(buff,i,16)*P2_43*SC2RAD; i+=16; - eph_gal.cuc =getbits(buff,i,16)*P2_29; i+=16; - eph_gal.cus =getbits(buff,i,16)*P2_29; i+=16; - eph_gal.crc =getbits(buff,i,16)*P2_5; i+=16; - eph_gal.crs =getbits(buff,i,16)*P2_5; i+=16; - eph_gal.sva =getbitu(buff,i, 8); - - i=128*4; /* word type 4 */ - type[3] =getbitu(buff,i, 6); i+= 6; - iod_nav[3] =getbitu(buff,i,10); i+=10; - svid =getbitu(buff,i, 6); i+= 6; - eph_gal.cic =getbits(buff,i,16)*P2_29; i+=16; - eph_gal.cis =getbits(buff,i,16)*P2_29; i+=16; - toc =getbitu(buff,i,14)*60.0; i+=14; - eph_gal.f0 =getbits(buff,i,31)*P2_34; i+=31; - eph_gal.f1 =getbits(buff,i,21)*P2_46; i+=21; - eph_gal.f2 =getbits(buff,i, 6)*P2_59; - - i=128*5; /* word type 5 */ - type[4] =getbitu(buff,i, 6); i+= 6+11+11+14+5; - eph_gal.tgd[0]=getbits(buff,i,10)*P2_32; i+=10; /* BGD E5a/E1 */ - eph_gal.tgd[1]=getbits(buff,i,10)*P2_32; i+=10; /* BGD E5b/E1 */ - e5b_hs =getbitu(buff,i, 2); i+= 2; - e1b_hs =getbitu(buff,i, 2); i+= 2; - e5b_dvs =getbitu(buff,i, 1); i+= 1; - e1b_dvs =getbitu(buff,i, 1); i+= 1; - week =getbitu(buff,i,12); i+=12; /* gst-week */ - tow =getbitu(buff,i,20); - - /* test word types */ - if (type[0]!=1||type[1]!=2||type[2]!=3||type[3]!=4||type[4]!=5) { - trace(3,"decode_gal_inav error: type=%d %d %d %d %d\n",type[0],type[1], - type[2],type[3],type[4]); - return 0; - } - /* test consistency of iod_nav */ - if (iod_nav[0]!=iod_nav[1]||iod_nav[0]!=iod_nav[2]||iod_nav[0]!=iod_nav[3]) { - trace(3,"decode_gal_inav error: iod_nav=%d %d %d %d\n",iod_nav[0], - iod_nav[1],iod_nav[2],iod_nav[3]); - return 0; - } - if (!(eph_gal.sat=satno(SYS_GAL,svid))) { - trace(2,"decode_gal_inav svid error: svid=%d\n",svid); - return 0; - } - eph_gal.A=sqrtA*sqrtA; - eph_gal.iode=eph_gal.iodc=iod_nav[0]; - eph_gal.svh=(e5b_hs<<7)|(e5b_dvs<<6)|(e1b_hs<<1)|e1b_dvs; - eph_gal.ttr=gst2time(week,tow); - tt=timediff(gst2time(week,eph_gal.toes),eph_gal.ttr); - if (tt> 302400.0) week--; /* week consistent with toe */ - else if (tt<-302400.0) week++; - eph_gal.toe=gst2time(week,eph_gal.toes); - eph_gal.toc=gst2time(week,toc); - eph_gal.week=week+1024; /* gal-week = gst-week + 1024 */ - eph_gal.code=(1<<9); /* I/NAV: af0-2,Toc,SISA for E5b-E1 */ - *eph=eph_gal; - return 1; +static int decode_gal_inav_eph(const uint8_t *buff, eph_t *eph) { + eph_t eph_gal = {0}; + double tow, toc, tt, sqrtA; + int i, week, svid, e5b_hs, e1b_hs, e5b_dvs, e1b_dvs, type[6], iod_nav[4]; + + trace(4, "decode_gal_inav_eph:\n"); + + i = 128; /* word type 1 */ + type[0] = getbitu(buff, i, 6); + i += 6; + iod_nav[0] = getbitu(buff, i, 10); + i += 10; + eph_gal.toes = getbitu(buff, i, 14) * 60.0; + i += 14; + eph_gal.M0 = getbits(buff, i, 32) * P2_31 * SC2RAD; + i += 32; + eph_gal.e = getbitu(buff, i, 32) * P2_33; + i += 32; + sqrtA = getbitu(buff, i, 32) * P2_19; + + i = 128 * 2; /* word type 2 */ + type[1] = getbitu(buff, i, 6); + i += 6; + iod_nav[1] = getbitu(buff, i, 10); + i += 10; + eph_gal.OMG0 = getbits(buff, i, 32) * P2_31 * SC2RAD; + i += 32; + eph_gal.i0 = getbits(buff, i, 32) * P2_31 * SC2RAD; + i += 32; + eph_gal.omg = getbits(buff, i, 32) * P2_31 * SC2RAD; + i += 32; + eph_gal.idot = getbits(buff, i, 14) * P2_43 * SC2RAD; + + i = 128 * 3; /* word type 3 */ + type[2] = getbitu(buff, i, 6); + i += 6; + iod_nav[2] = getbitu(buff, i, 10); + i += 10; + eph_gal.OMGd = getbits(buff, i, 24) * P2_43 * SC2RAD; + i += 24; + eph_gal.deln = getbits(buff, i, 16) * P2_43 * SC2RAD; + i += 16; + eph_gal.cuc = getbits(buff, i, 16) * P2_29; + i += 16; + eph_gal.cus = getbits(buff, i, 16) * P2_29; + i += 16; + eph_gal.crc = getbits(buff, i, 16) * P2_5; + i += 16; + eph_gal.crs = getbits(buff, i, 16) * P2_5; + i += 16; + eph_gal.sva = getbitu(buff, i, 8); + + i = 128 * 4; /* word type 4 */ + type[3] = getbitu(buff, i, 6); + i += 6; + iod_nav[3] = getbitu(buff, i, 10); + i += 10; + svid = getbitu(buff, i, 6); + i += 6; + eph_gal.cic = getbits(buff, i, 16) * P2_29; + i += 16; + eph_gal.cis = getbits(buff, i, 16) * P2_29; + i += 16; + toc = getbitu(buff, i, 14) * 60.0; + i += 14; + eph_gal.f0 = getbits(buff, i, 31) * P2_34; + i += 31; + eph_gal.f1 = getbits(buff, i, 21) * P2_46; + i += 21; + eph_gal.f2 = getbits(buff, i, 6) * P2_59; + + i = 128 * 5; /* word type 5 */ + type[4] = getbitu(buff, i, 6); + i += 6 + 11 + 11 + 14 + 5; + eph_gal.tgd[0] = getbits(buff, i, 10) * P2_32; + i += 10; /* BGD E5a/E1 */ + eph_gal.tgd[1] = getbits(buff, i, 10) * P2_32; + i += 10; /* BGD E5b/E1 */ + e5b_hs = getbitu(buff, i, 2); + i += 2; + e1b_hs = getbitu(buff, i, 2); + i += 2; + e5b_dvs = getbitu(buff, i, 1); + i += 1; + e1b_dvs = getbitu(buff, i, 1); + i += 1; + week = getbitu(buff, i, 12); + i += 12; /* gst-week */ + tow = getbitu(buff, i, 20); + + /* test word types */ + if (type[0] != 1 || type[1] != 2 || type[2] != 3 || type[3] != 4 || type[4] != 5) { + trace(3, "decode_gal_inav error: type=%d %d %d %d %d\n", type[0], type[1], type[2], type[3], + type[4]); + return 0; + } + /* test consistency of iod_nav */ + if (iod_nav[0] != iod_nav[1] || iod_nav[0] != iod_nav[2] || iod_nav[0] != iod_nav[3]) { + trace(3, "decode_gal_inav error: iod_nav=%d %d %d %d\n", iod_nav[0], iod_nav[1], iod_nav[2], + iod_nav[3]); + return 0; + } + if (!(eph_gal.sat = satno(SYS_GAL, svid))) { + trace(2, "decode_gal_inav svid error: svid=%d\n", svid); + return 0; + } + eph_gal.A = sqrtA * sqrtA; + eph_gal.iode = eph_gal.iodc = iod_nav[0]; + eph_gal.svh = (e5b_hs << 7) | (e5b_dvs << 6) | (e1b_hs << 1) | e1b_dvs; + eph_gal.ttr = gst2time(week, tow); + tt = timediff(gst2time(week, eph_gal.toes), eph_gal.ttr); + if (tt > 302400.0) + week--; /* week consistent with toe */ + else if (tt < -302400.0) + week++; + eph_gal.toe = gst2time(week, eph_gal.toes); + eph_gal.toc = gst2time(week, toc); + eph_gal.week = week + 1024; /* gal-week = gst-week + 1024 */ + eph_gal.code = (1 << 9); /* I/NAV: af0-2,Toc,SISA for E5b-E1 */ + *eph = eph_gal; + return 1; } /* decode Galileo I/NAV iono parameters --------------------------------------*/ -static int decode_gal_inav_ion(const uint8_t *buff, double *ion) -{ - int i=128*5; /* word type 5 */ - - trace(4,"decode_gal_inav_ion:\n"); - - if (getbitu(buff,i,6)!=5) return 0; - i+=6; - ion[0]=getbitu(buff,i,11)*0.25; i+=11; - ion[1]=getbits(buff,i,11)*P2_8; i+=11; - ion[2]=getbits(buff,i,14)*P2_15; i+=14; - ion[3]=getbitu(buff,i, 5); - return 1; +static int decode_gal_inav_ion(const uint8_t *buff, double *ion) { + int i = 128 * 5; /* word type 5 */ + + trace(4, "decode_gal_inav_ion:\n"); + + if (getbitu(buff, i, 6) != 5) return 0; + i += 6; + ion[0] = getbitu(buff, i, 11) * 0.25; + i += 11; + ion[1] = getbits(buff, i, 11) * P2_8; + i += 11; + ion[2] = getbits(buff, i, 14) * P2_15; + i += 14; + ion[3] = getbitu(buff, i, 5); + return 1; } /* decode Galileo I/NAV UTC parameters ---------------------------------------*/ -static int decode_gal_inav_utc(const uint8_t *buff, double *utc) -{ - int i=128*6; /* word type 6 */ - - trace(4,"decode_gal_inav_utc:\n"); - - if (getbitu(buff,i,6)!=6) return 0; - i+=6; - utc[0]=getbits(buff,i,32)*P2_30; i+=32; /* A0 */ - utc[1]=getbits(buff,i,24)*P2_50; i+=24; /* A1 */ - utc[4]=getbits(buff,i, 8); i+= 8; /* dt_LS */ - utc[2]=getbitu(buff,i, 8)*3600.0; i+= 8; /* tot */ - utc[3]=getbitu(buff,i, 8); i+= 8; /* WNt */ - utc[5]=getbitu(buff,i, 8); i+= 8; /* WN_LSF */ - utc[6]=getbitu(buff,i, 3); i+= 3; /* DN */ - utc[7]=getbits(buff,i, 8); /* dt_LSF */ - return 1; +static int decode_gal_inav_utc(const uint8_t *buff, double *utc) { + int i = 128 * 6; /* word type 6 */ + + trace(4, "decode_gal_inav_utc:\n"); + + if (getbitu(buff, i, 6) != 6) return 0; + i += 6; + utc[0] = getbits(buff, i, 32) * P2_30; + i += 32; /* A0 */ + utc[1] = getbits(buff, i, 24) * P2_50; + i += 24; /* A1 */ + utc[4] = getbits(buff, i, 8); + i += 8; /* dt_LS */ + utc[2] = getbitu(buff, i, 8) * 3600.0; + i += 8; /* tot */ + utc[3] = getbitu(buff, i, 8); + i += 8; /* WNt */ + utc[5] = getbitu(buff, i, 8); + i += 8; /* WN_LSF */ + utc[6] = getbitu(buff, i, 3); + i += 3; /* DN */ + utc[7] = getbits(buff, i, 8); /* dt_LSF */ + return 1; } /* decode Galileo I/NAV navigation data ---------------------------------------- -* decode Galileo I/NAV navigation data (ref [5] 4.3) -* args : uint8_t *buff I Galileo I/NAV subframe data (CRC checked) -* buff[ 0- 15]: word type 0 (128 bits) -* buff[16- 31]: word type 1 -* buff[32- 47]: word type 2 -* buff[48- 63]: word type 3 -* buff[64- 79]: word type 4 -* buff[80- 95]: word type 5 -* buff[96-111]: word type 6 -* eph_t *eph IO Galileo I/NAV ephemeris (NULL: not output) -* double *ion IO Galileo I/NAV iono parameters (NULL: not output) -* ion[0-3]: a_i0,a_i1,a_i2,flags -* double *utc IO Galileo I/NAV UTC parameters (NULL: not output) -* utc[0-3]: A0,A1,tot,WNt -* utc[4-7]: dt_LS,WN_LSF,DN,dt_LSF -* return : status (1:ok,0:error) -*-----------------------------------------------------------------------------*/ -extern int decode_gal_inav(const uint8_t *buff, eph_t *eph, double *ion, - double *utc) -{ - trace(4,"decode_gal_inav:\n"); - - if (eph&&!decode_gal_inav_eph(buff,eph)) return 0; - if (ion&&!decode_gal_inav_ion(buff,ion)) return 0; - if (utc&&!decode_gal_inav_utc(buff,utc)) return 0; - return 1; + * decode Galileo I/NAV navigation data (ref [5] 4.3) + * args : uint8_t *buff I Galileo I/NAV subframe data (CRC checked) + * buff[ 0- 15]: word type 0 (128 bits) + * buff[16- 31]: word type 1 + * buff[32- 47]: word type 2 + * buff[48- 63]: word type 3 + * buff[64- 79]: word type 4 + * buff[80- 95]: word type 5 + * buff[96-111]: word type 6 + * eph_t *eph IO Galileo I/NAV ephemeris (NULL: not output) + * double *ion IO Galileo I/NAV iono parameters (NULL: not output) + * ion[0-3]: a_i0,a_i1,a_i2,flags + * double *utc IO Galileo I/NAV UTC parameters (NULL: not output) + * utc[0-3]: A0,A1,tot,WNt + * utc[4-7]: dt_LS,WN_LSF,DN,dt_LSF + * return : status (1:ok,0:error) + *-----------------------------------------------------------------------------*/ +extern int decode_gal_inav(const uint8_t *buff, eph_t *eph, double *ion, double *utc) { + trace(4, "decode_gal_inav:\n"); + + if (eph && !decode_gal_inav_eph(buff, eph)) return 0; + if (ion && !decode_gal_inav_ion(buff, ion)) return 0; + if (utc && !decode_gal_inav_utc(buff, utc)) return 0; + return 1; } /* decode Galileo F/NAV ephemeris --------------------------------------------*/ -static int decode_gal_fnav_eph(const uint8_t *buff, eph_t *eph) -{ - eph_t eph_gal={0}; - double tow[4],toc,tt,sqrtA; - int i,week[3],svid,e5a_hs,e5a_dvs,type[4],iod_nav[4]; - - trace(4,"decode_gal_fnav_eph:\n"); - - i=0; /* page type 1 */ - type[0] =getbitu(buff,i, 6); i+= 6; - svid =getbitu(buff,i, 6); i+= 6; - iod_nav[0] =getbitu(buff,i,10); i+=10; - toc =getbitu(buff,i,14)*60.0; i+=14; - eph_gal.f0 =getbits(buff,i,31)*P2_34; i+=31; - eph_gal.f1 =getbits(buff,i,21)*P2_46; i+=21; - eph_gal.f2 =getbits(buff,i, 6)*P2_59; i+= 6; - eph_gal.sva =getbitu(buff,i, 8); i+= 8+11+11+14+5; - eph_gal.tgd[0]=getbits(buff,i,10)*P2_32; i+=10; /* BGD E5a/E1 */ - e5a_hs =getbitu(buff,i, 2); i+= 2; - week[0] =getbitu(buff,i,12); i+=12; /* gst-week */ - tow[0] =getbitu(buff,i,20); i+=20; - e5a_dvs =getbitu(buff,i, 1); - - i=31*8; /* page type 2 */ - type[1] =getbitu(buff,i, 6); i+= 6; - iod_nav[1] =getbitu(buff,i,10); i+=10; - eph_gal.M0 =getbits(buff,i,32)*P2_31*SC2RAD; i+=32; - eph_gal.OMGd=getbits(buff,i,24)*P2_43*SC2RAD; i+=24; - eph_gal.e =getbitu(buff,i,32)*P2_33; i+=32; - sqrtA =getbitu(buff,i,32)*P2_19; i+=32; - eph_gal.OMG0=getbits(buff,i,32)*P2_31*SC2RAD; i+=32; - eph_gal.idot=getbits(buff,i,14)*P2_43*SC2RAD; i+=14; - week[1] =getbitu(buff,i,12); i+=12; - tow[1] =getbitu(buff,i,20); - - i=62*8; /* page type 3 */ - type[2] =getbitu(buff,i, 6); i+= 6; - iod_nav[2] =getbitu(buff,i,10); i+=10; - eph_gal.i0 =getbits(buff,i,32)*P2_31*SC2RAD; i+=32; - eph_gal.omg =getbits(buff,i,32)*P2_31*SC2RAD; i+=32; - eph_gal.deln=getbits(buff,i,16)*P2_43*SC2RAD; i+=16; - eph_gal.cuc =getbits(buff,i,16)*P2_29; i+=16; - eph_gal.cus =getbits(buff,i,16)*P2_29; i+=16; - eph_gal.crc =getbits(buff,i,16)*P2_5; i+=16; - eph_gal.crs =getbits(buff,i,16)*P2_5; i+=16; - eph_gal.toes=getbitu(buff,i,14)*60.0; i+=14; - week[2] =getbitu(buff,i,12); i+=12; - tow[2] =getbitu(buff,i,20); - - i=93*8; /* page type 4 */ - type[3] =getbitu(buff,i, 6); i+= 6; - iod_nav[3] =getbitu(buff,i,10); i+=10; - eph_gal.cic =getbits(buff,i,16)*P2_29; i+=16; - eph_gal.cis =getbits(buff,i,16)*P2_29; - - /* test page types */ - if (type[0]!=1||type[1]!=2||type[2]!=3||type[3]!=4) { - trace(3,"decode_gal_fnav error: svid=%d type=%d %d %d %d\n",svid, - type[0],type[1],type[2],type[3]); - return 0; - } - /* test consistency of iod_nav */ - if (iod_nav[0]!=iod_nav[1]||iod_nav[0]!=iod_nav[2]||iod_nav[0]!=iod_nav[3]) { - trace(3,"decode_gal_fnav error: svid=%d iod_nav=%d %d %d %d\n",svid, - iod_nav[0],iod_nav[1],iod_nav[2],iod_nav[3]); - return 0; - } - if (!(eph_gal.sat=satno(SYS_GAL,svid))) { - trace(2,"decode_gal_fnav svid error: svid=%d\n",svid); - return 0; - } - eph_gal.A=sqrtA*sqrtA; - eph_gal.tgd[1]=0.0; /* BGD E5b/E1 */ - eph_gal.iode=eph_gal.iodc=iod_nav[0]; - eph_gal.svh=(e5a_hs<<4)|(e5a_dvs<<3); - eph_gal.ttr=gst2time(week[0],tow[0]); - tt=timediff(gst2time(week[0],eph_gal.toes),eph_gal.ttr); - if (tt> 302400.0) week[0]--; /* week consistent with toe */ - else if (tt<-302400.0) week[0]++; - eph_gal.toe=gst2time(week[0],eph_gal.toes); - eph_gal.toc=gst2time(week[0],toc); - eph_gal.week=week[0]+1024; /* gal-week = gst-week + 1024 */ - eph_gal.code=(1<<8); /* F/NAV: af0-af2,Toc,SISA for E5a,E1 */ - *eph=eph_gal; - return 1; +static int decode_gal_fnav_eph(const uint8_t *buff, eph_t *eph) { + eph_t eph_gal = {0}; + double tow[4], toc, tt, sqrtA; + int i, week[3], svid, e5a_hs, e5a_dvs, type[4], iod_nav[4]; + + trace(4, "decode_gal_fnav_eph:\n"); + + i = 0; /* page type 1 */ + type[0] = getbitu(buff, i, 6); + i += 6; + svid = getbitu(buff, i, 6); + i += 6; + iod_nav[0] = getbitu(buff, i, 10); + i += 10; + toc = getbitu(buff, i, 14) * 60.0; + i += 14; + eph_gal.f0 = getbits(buff, i, 31) * P2_34; + i += 31; + eph_gal.f1 = getbits(buff, i, 21) * P2_46; + i += 21; + eph_gal.f2 = getbits(buff, i, 6) * P2_59; + i += 6; + eph_gal.sva = getbitu(buff, i, 8); + i += 8 + 11 + 11 + 14 + 5; + eph_gal.tgd[0] = getbits(buff, i, 10) * P2_32; + i += 10; /* BGD E5a/E1 */ + e5a_hs = getbitu(buff, i, 2); + i += 2; + week[0] = getbitu(buff, i, 12); + i += 12; /* gst-week */ + tow[0] = getbitu(buff, i, 20); + i += 20; + e5a_dvs = getbitu(buff, i, 1); + + i = 31 * 8; /* page type 2 */ + type[1] = getbitu(buff, i, 6); + i += 6; + iod_nav[1] = getbitu(buff, i, 10); + i += 10; + eph_gal.M0 = getbits(buff, i, 32) * P2_31 * SC2RAD; + i += 32; + eph_gal.OMGd = getbits(buff, i, 24) * P2_43 * SC2RAD; + i += 24; + eph_gal.e = getbitu(buff, i, 32) * P2_33; + i += 32; + sqrtA = getbitu(buff, i, 32) * P2_19; + i += 32; + eph_gal.OMG0 = getbits(buff, i, 32) * P2_31 * SC2RAD; + i += 32; + eph_gal.idot = getbits(buff, i, 14) * P2_43 * SC2RAD; + i += 14; + week[1] = getbitu(buff, i, 12); + i += 12; + tow[1] = getbitu(buff, i, 20); + + i = 62 * 8; /* page type 3 */ + type[2] = getbitu(buff, i, 6); + i += 6; + iod_nav[2] = getbitu(buff, i, 10); + i += 10; + eph_gal.i0 = getbits(buff, i, 32) * P2_31 * SC2RAD; + i += 32; + eph_gal.omg = getbits(buff, i, 32) * P2_31 * SC2RAD; + i += 32; + eph_gal.deln = getbits(buff, i, 16) * P2_43 * SC2RAD; + i += 16; + eph_gal.cuc = getbits(buff, i, 16) * P2_29; + i += 16; + eph_gal.cus = getbits(buff, i, 16) * P2_29; + i += 16; + eph_gal.crc = getbits(buff, i, 16) * P2_5; + i += 16; + eph_gal.crs = getbits(buff, i, 16) * P2_5; + i += 16; + eph_gal.toes = getbitu(buff, i, 14) * 60.0; + i += 14; + week[2] = getbitu(buff, i, 12); + i += 12; + tow[2] = getbitu(buff, i, 20); + + i = 93 * 8; /* page type 4 */ + type[3] = getbitu(buff, i, 6); + i += 6; + iod_nav[3] = getbitu(buff, i, 10); + i += 10; + eph_gal.cic = getbits(buff, i, 16) * P2_29; + i += 16; + eph_gal.cis = getbits(buff, i, 16) * P2_29; + + /* test page types */ + if (type[0] != 1 || type[1] != 2 || type[2] != 3 || type[3] != 4) { + trace(3, "decode_gal_fnav error: svid=%d type=%d %d %d %d\n", svid, type[0], type[1], type[2], + type[3]); + return 0; + } + /* test consistency of iod_nav */ + if (iod_nav[0] != iod_nav[1] || iod_nav[0] != iod_nav[2] || iod_nav[0] != iod_nav[3]) { + trace(3, "decode_gal_fnav error: svid=%d iod_nav=%d %d %d %d\n", svid, iod_nav[0], iod_nav[1], + iod_nav[2], iod_nav[3]); + return 0; + } + if (!(eph_gal.sat = satno(SYS_GAL, svid))) { + trace(2, "decode_gal_fnav svid error: svid=%d\n", svid); + return 0; + } + eph_gal.A = sqrtA * sqrtA; + eph_gal.tgd[1] = 0.0; /* BGD E5b/E1 */ + eph_gal.iode = eph_gal.iodc = iod_nav[0]; + eph_gal.svh = (e5a_hs << 4) | (e5a_dvs << 3); + eph_gal.ttr = gst2time(week[0], tow[0]); + tt = timediff(gst2time(week[0], eph_gal.toes), eph_gal.ttr); + if (tt > 302400.0) + week[0]--; /* week consistent with toe */ + else if (tt < -302400.0) + week[0]++; + eph_gal.toe = gst2time(week[0], eph_gal.toes); + eph_gal.toc = gst2time(week[0], toc); + eph_gal.week = week[0] + 1024; /* gal-week = gst-week + 1024 */ + eph_gal.code = (1 << 8); /* F/NAV: af0-af2,Toc,SISA for E5a,E1 */ + *eph = eph_gal; + return 1; } /* decode Galileo F/NAV iono parameters --------------------------------------*/ -static int decode_gal_fnav_ion(const uint8_t *buff, double *ion) -{ - int i=0; /* page type 1 */ - - trace(4,"decode_gal_fnav_ion:\n"); - - if (getbitu(buff,i,6)!=1) return 0; - i+=6+6+10+14+31+21+6+8; - ion[0]=getbitu(buff,i,11)*0.25; i+=11; - ion[1]=getbits(buff,i,11)*P2_8; i+=11; - ion[2]=getbits(buff,i,14)*P2_15; i+=14; - ion[3]=getbitu(buff,i, 5); - return 1; +static int decode_gal_fnav_ion(const uint8_t *buff, double *ion) { + int i = 0; /* page type 1 */ + + trace(4, "decode_gal_fnav_ion:\n"); + + if (getbitu(buff, i, 6) != 1) return 0; + i += 6 + 6 + 10 + 14 + 31 + 21 + 6 + 8; + ion[0] = getbitu(buff, i, 11) * 0.25; + i += 11; + ion[1] = getbits(buff, i, 11) * P2_8; + i += 11; + ion[2] = getbits(buff, i, 14) * P2_15; + i += 14; + ion[3] = getbitu(buff, i, 5); + return 1; } /* decode Galileo F/NAV UTC parameters ---------------------------------------*/ -static int decode_gal_fnav_utc(const uint8_t *buff, double *utc) -{ - int i=93*8; /* page type 4 */ - - trace(4,"decode_gal_fnav_utc:\n"); - - if (getbitu(buff,i,6)!=4) return 0; - i+=6+10+16+16; - utc[0]=getbits(buff,i,32)*P2_30; i+=32; /* A0 */ - utc[1]=getbits(buff,i,24)*P2_50; i+=24; /* A1 */ - utc[4]=getbits(buff,i, 8); i+= 8; /* dt_LS */ - utc[2]=getbitu(buff,i, 8)*3600.0; i+= 8; /* tot */ - utc[3]=getbitu(buff,i, 8); i+= 8; /* WN_ot */ - utc[5]=getbitu(buff,i, 8); i+= 8; /* WN_LSF */ - utc[6]=getbitu(buff,i, 3); i+= 3; /* DN */ - utc[7]=getbits(buff,i, 8); /* dt_LSF */ - return 1; +static int decode_gal_fnav_utc(const uint8_t *buff, double *utc) { + int i = 93 * 8; /* page type 4 */ + + trace(4, "decode_gal_fnav_utc:\n"); + + if (getbitu(buff, i, 6) != 4) return 0; + i += 6 + 10 + 16 + 16; + utc[0] = getbits(buff, i, 32) * P2_30; + i += 32; /* A0 */ + utc[1] = getbits(buff, i, 24) * P2_50; + i += 24; /* A1 */ + utc[4] = getbits(buff, i, 8); + i += 8; /* dt_LS */ + utc[2] = getbitu(buff, i, 8) * 3600.0; + i += 8; /* tot */ + utc[3] = getbitu(buff, i, 8); + i += 8; /* WN_ot */ + utc[5] = getbitu(buff, i, 8); + i += 8; /* WN_LSF */ + utc[6] = getbitu(buff, i, 3); + i += 3; /* DN */ + utc[7] = getbits(buff, i, 8); /* dt_LSF */ + return 1; } /* decode Galileo F/NAV navigation data ---------------------------------------- -* decode Galileo F/NAV navigation data (ref [5] 4.2) -* args : uint8_t *buff I Galileo F/NAV subframe data (CRC checked) -* buff[ 0- 30]: page type 1 (244 bit) -* buff[ 31- 61]: page type 2 -* buff[ 62- 92]: page type 3 -* buff[ 93-123]: page type 4 -* buff[124-154]: page type 5 -* buff[155-185]: page type 6 -* eph_t *eph IO Galileo F/NAV ephemeris (NULL: not output) -* double *ion IO Galileo F/NAV iono parameters (NULL: not output) -* ion[0-3]: a_i0,a_i1,a_i2,flags -* double *utc IO Galileo F/NAV UTC parameters (NULL: not output) -* utc[0-3]: A0,A1,tot,WNt -* utc[4-7]: dt_LS,WN_LSF,DN,dt_LSF -* return : status (1:ok,0:error) -*-----------------------------------------------------------------------------*/ -extern int decode_gal_fnav(const uint8_t *buff, eph_t *eph, double *ion, - double *utc) -{ - trace(4,"decode_gal_fnav:\n"); - - if (eph&&!decode_gal_fnav_eph(buff,eph)) return 0; - if (ion&&!decode_gal_fnav_ion(buff,ion)) return 0; - if (utc&&!decode_gal_fnav_utc(buff,utc)) return 0; - return 1; + * decode Galileo F/NAV navigation data (ref [5] 4.2) + * args : uint8_t *buff I Galileo F/NAV subframe data (CRC checked) + * buff[ 0- 30]: page type 1 (244 bit) + * buff[ 31- 61]: page type 2 + * buff[ 62- 92]: page type 3 + * buff[ 93-123]: page type 4 + * buff[124-154]: page type 5 + * buff[155-185]: page type 6 + * eph_t *eph IO Galileo F/NAV ephemeris (NULL: not output) + * double *ion IO Galileo F/NAV iono parameters (NULL: not output) + * ion[0-3]: a_i0,a_i1,a_i2,flags + * double *utc IO Galileo F/NAV UTC parameters (NULL: not output) + * utc[0-3]: A0,A1,tot,WNt + * utc[4-7]: dt_LS,WN_LSF,DN,dt_LSF + * return : status (1:ok,0:error) + *-----------------------------------------------------------------------------*/ +extern int decode_gal_fnav(const uint8_t *buff, eph_t *eph, double *ion, double *utc) { + trace(4, "decode_gal_fnav:\n"); + + if (eph && !decode_gal_fnav_eph(buff, eph)) return 0; + if (ion && !decode_gal_fnav_ion(buff, ion)) return 0; + if (utc && !decode_gal_fnav_utc(buff, utc)) return 0; + return 1; } /* decode BDS D1 navigation data ---------------------------------------------*/ -static int decode_bds_d1_eph(const uint8_t *buff, eph_t *eph) -{ - eph_t eph_bds={0}; - double toc_bds,sqrtA; - uint32_t toe1,toe2,sow1,sow2,sow3; - int i,frn1,frn2,frn3; - - i=8*38*0; /* subframe 1 */ - frn1 =getbitu (buff,i+ 15, 3); - sow1 =getbitu2(buff,i+ 18, 8,i+30,12); - eph_bds.svh =getbitu (buff,i+ 42, 1); /* SatH1 */ - eph_bds.iodc =getbitu (buff,i+ 43, 5); /* AODC */ - eph_bds.sva =getbitu (buff,i+ 48, 4); - eph_bds.week =getbitu (buff,i+ 60,13); /* week in BDT */ - toc_bds =getbitu2(buff,i+ 73, 9,i+ 90, 8)*8.0; - eph_bds.tgd[0]=getbits (buff,i+ 98,10)*0.1*1E-9; - eph_bds.tgd[1]=getbits2(buff,i+108, 4,i+120, 6)*0.1*1E-9; - eph_bds.f2 =getbits (buff,i+214,11)*P2_66; - eph_bds.f0 =getbits2(buff,i+225, 7,i+240,17)*P2_33; - eph_bds.f1 =getbits2(buff,i+257, 5,i+270,17)*P2_50; - eph_bds.iode =getbitu (buff,i+287, 5); /* AODE */ - - i=8*38*1; /* subframe 2 */ - frn2 =getbitu (buff,i+ 15, 3); - sow2 =getbitu2(buff,i+ 18, 8,i+30,12); - eph_bds.deln =getbits2(buff,i+ 42,10,i+ 60, 6)*P2_43*SC2RAD; - eph_bds.cuc =getbits2(buff,i+ 66,16,i+ 90, 2)*P2_31; - eph_bds.M0 =getbits2(buff,i+ 92,20,i+120,12)*P2_31*SC2RAD; - eph_bds.e =getbitu2(buff,i+132,10,i+150,22)*P2_33; - eph_bds.cus =getbits (buff,i+180,18)*P2_31; - eph_bds.crc =getbits2(buff,i+198, 4,i+210,14)*P2_6; - eph_bds.crs =getbits2(buff,i+224, 8,i+240,10)*P2_6; - sqrtA =getbitu2(buff,i+250,12,i+270,20)*P2_19; - toe1 =getbitu (buff,i+290, 2); /* TOE 2-MSB */ - eph_bds.A =sqrtA*sqrtA; - - i=8*38*2; /* subframe 3 */ - frn3 =getbitu (buff,i+ 15, 3); - sow3 =getbitu2(buff,i+ 18, 8,i+30,12); - toe2 =getbitu2(buff,i+ 42,10,i+ 60, 5); /* TOE 5-LSB */ - eph_bds.i0 =getbits2(buff,i+ 65,17,i+ 90,15)*P2_31*SC2RAD; - eph_bds.cic =getbits2(buff,i+105, 7,i+120,11)*P2_31; - eph_bds.OMGd =getbits2(buff,i+131,11,i+150,13)*P2_43*SC2RAD; - eph_bds.cis =getbits2(buff,i+163, 9,i+180, 9)*P2_31; - eph_bds.idot =getbits2(buff,i+189,13,i+210, 1)*P2_43*SC2RAD; - eph_bds.OMG0 =getbits2(buff,i+211,21,i+240,11)*P2_31*SC2RAD; - eph_bds.omg =getbits2(buff,i+251,11,i+270,21)*P2_31*SC2RAD; - eph_bds.toes =merge_two_u(toe1,toe2,15)*8.0; - - /* check consistency of subframe ids, sows and toe/toc */ - if (frn1!=1||frn2!=2||frn3!=3) { - trace(3,"decode_bds_d1_eph error: frn=%d %d %d\n",frn1,frn2,frn3); - return 0; - } - if (sow2!=sow1+6||sow3!=sow2+6) { - trace(3,"decode_bds_d1_eph error: sow=%d %d %d\n",sow1,sow2,sow3); - return 0; - } - if (toc_bds!=eph_bds.toes) { - trace(3,"decode_bds_d1_eph error: toe=%.0f toc=%.0f\n",eph_bds.toes, - toc_bds); - return 0; - } - eph_bds.ttr=bdt2gpst(bdt2time(eph_bds.week,sow1)); /* bdt -> gpst */ - if (eph_bds.toes>sow1+302400.0) eph_bds.week++; - else if (eph_bds.toes gpst */ + if (eph_bds.toes > sow1 + 302400.0) + eph_bds.week++; + else if (eph_bds.toes < sow1 - 302400.0) + eph_bds.week--; + eph_bds.toe = bdt2gpst(bdt2time(eph_bds.week, eph_bds.toes)); + eph_bds.toc = bdt2gpst(bdt2time(eph_bds.week, toc_bds)); + eph_bds.code = 0; /* data source = unknown */ + eph_bds.flag = 1; /* nav type = IGSO/MEO */ + *eph = eph_bds; + return 1; } /* decode BDS D1 iono parameters ---------------------------------------------*/ -static int decode_bds_d1_ion(const uint8_t *buff, double *ion) -{ - int i=8*38*0; /* subframe 1 */ - - trace(4,"decode_bds_d1_ion:\n"); - - /* subframe 1 */ - if (getbitu(buff,i+15,3)!=1) return 0; - - ion[0]=getbits (buff,i+126, 8)*P2_30; - ion[1]=getbits (buff,i+134, 8)*P2_27; - ion[2]=getbits (buff,i+150, 8)*P2_24; - ion[3]=getbits (buff,i+158, 8)*P2_24; - ion[4]=getbits2(buff,i+166, 6,i+180, 2)*P2P11; - ion[5]=getbits (buff,i+182, 8)*P2P14; - ion[6]=getbits (buff,i+190, 8)*P2P16; - ion[7]=getbits2(buff,i+198, 4,i+210, 4)*P2P16; - return 1; +static int decode_bds_d1_ion(const uint8_t *buff, double *ion) { + int i = 8 * 38 * 0; /* subframe 1 */ + + trace(4, "decode_bds_d1_ion:\n"); + + /* subframe 1 */ + if (getbitu(buff, i + 15, 3) != 1) return 0; + + ion[0] = getbits(buff, i + 126, 8) * P2_30; + ion[1] = getbits(buff, i + 134, 8) * P2_27; + ion[2] = getbits(buff, i + 150, 8) * P2_24; + ion[3] = getbits(buff, i + 158, 8) * P2_24; + ion[4] = getbits2(buff, i + 166, 6, i + 180, 2) * P2P11; + ion[5] = getbits(buff, i + 182, 8) * P2P14; + ion[6] = getbits(buff, i + 190, 8) * P2P16; + ion[7] = getbits2(buff, i + 198, 4, i + 210, 4) * P2P16; + return 1; } /* decode BDS D1 UTC parameters ----------------------------------------------*/ -static int decode_bds_d1_utc(const uint8_t *buff, double *utc) -{ - int i=8*38*4; /* subframe 5 */ - - trace(4,"decode_bds_d1_utc:\n"); - - if (getbitu(buff,15,3)!=1) return 0; /* subframe 1 */ - - /* subframe 5 page 10 */ - if (getbitu(buff,i+15,3)!=5||getbitu(buff,i+43,7)!=10) return 0; - - utc[4]=getbits2(buff,i+ 50, 2,i+ 60, 6); /* dt_LS */ - utc[7]=getbits (buff,i+ 66, 8); /* dt_LSF */ - utc[5]=getbitu (buff,i+ 74, 8); /* WN_LSF */ - utc[0]=getbits2(buff,i+ 90,22,i+120,10)*P2_30; /* A0 */ - utc[1]=getbits2(buff,i+130,12,i+150,12)*P2_50; /* A1 */ - utc[6]=getbitu (buff,i+162, 8); /* DN */ - utc[2]=getbitu2(buff,i+ 18, 8,i+ 30,12); /* SOW */ - utc[3]=getbitu (buff,60,13); /* WN */ - return 1; +static int decode_bds_d1_utc(const uint8_t *buff, double *utc) { + int i = 8 * 38 * 4; /* subframe 5 */ + + trace(4, "decode_bds_d1_utc:\n"); + + if (getbitu(buff, 15, 3) != 1) return 0; /* subframe 1 */ + + /* subframe 5 page 10 */ + if (getbitu(buff, i + 15, 3) != 5 || getbitu(buff, i + 43, 7) != 10) return 0; + + utc[4] = getbits2(buff, i + 50, 2, i + 60, 6); /* dt_LS */ + utc[7] = getbits(buff, i + 66, 8); /* dt_LSF */ + utc[5] = getbitu(buff, i + 74, 8); /* WN_LSF */ + utc[0] = getbits2(buff, i + 90, 22, i + 120, 10) * P2_30; /* A0 */ + utc[1] = getbits2(buff, i + 130, 12, i + 150, 12) * P2_50; /* A1 */ + utc[6] = getbitu(buff, i + 162, 8); /* DN */ + utc[2] = getbitu2(buff, i + 18, 8, i + 30, 12); /* SOW */ + utc[3] = getbitu(buff, 60, 13); /* WN */ + return 1; } /* decode BDS D1 navigation data ----------------------------------------------- -* decode BDS D1 navigation data (IGSO/MEO) (ref [3] 5.2) -* args : uint8_t *buff I BDS D1 subframe data (CRC checked with parity) -* buff[ 0- 37]: subframe 1 (300 bits) -* buff[ 38- 75]: subframe 2 -* buff[ 76-113]: subframe 3 -* buff[114-141]: subframe 4 -* buff[152-189]: subframe 5 -* eph_t *eph IO BDS D1 ephemeris (NULL: not output) -* double *ion IO BDS D1 iono parameters (NULL: not output) -* ion[0-3]: alpha_0,...,alpha_3 -* ion[4-7]: beta_0,...,beta_3 -* double *utc IO BDS D1 UTC parameters (NULL: not output) -* utc[0-2]: A0,A1,tot,WNt -* utc[4-7]: dt_LS,WN_LSF,DN,dt_LSF -* return : status (1:ok,0:error) -*-----------------------------------------------------------------------------*/ -extern int decode_bds_d1(const uint8_t *buff, eph_t *eph, double *ion, - double *utc) -{ - trace(4,"decode_bds_d1:\n"); - - if (eph&&!decode_bds_d1_eph(buff,eph)) return 0; - if (ion&&!decode_bds_d1_ion(buff,ion)) return 0; - if (utc&&!decode_bds_d1_utc(buff,utc)) return 0; - return 1; + * decode BDS D1 navigation data (IGSO/MEO) (ref [3] 5.2) + * args : uint8_t *buff I BDS D1 subframe data (CRC checked with parity) + * buff[ 0- 37]: subframe 1 (300 bits) + * buff[ 38- 75]: subframe 2 + * buff[ 76-113]: subframe 3 + * buff[114-141]: subframe 4 + * buff[152-189]: subframe 5 + * eph_t *eph IO BDS D1 ephemeris (NULL: not output) + * double *ion IO BDS D1 iono parameters (NULL: not output) + * ion[0-3]: alpha_0,...,alpha_3 + * ion[4-7]: beta_0,...,beta_3 + * double *utc IO BDS D1 UTC parameters (NULL: not output) + * utc[0-2]: A0,A1,tot,WNt + * utc[4-7]: dt_LS,WN_LSF,DN,dt_LSF + * return : status (1:ok,0:error) + *-----------------------------------------------------------------------------*/ +extern int decode_bds_d1(const uint8_t *buff, eph_t *eph, double *ion, double *utc) { + trace(4, "decode_bds_d1:\n"); + + if (eph && !decode_bds_d1_eph(buff, eph)) return 0; + if (ion && !decode_bds_d1_ion(buff, ion)) return 0; + if (utc && !decode_bds_d1_utc(buff, utc)) return 0; + return 1; } /* decode BDS D2 ephemeris ---------------------------------------------------*/ -static int decode_bds_d2_eph(const uint8_t *buff, eph_t *eph) -{ - eph_t eph_bds={0}; - double toc_bds,sqrtA; - uint32_t f1p4,cucp5,ep6,cicp7,i0p8,OMGdp9,omgp10; - uint32_t sow1,sow3,sow4,sow5,sow6,sow7,sow8,sow9,sow10; - int i,f1p3,cucp4,ep5,cicp6,i0p7,OMGdp8,omgp9; - int pgn1,pgn3,pgn4,pgn5,pgn6,pgn7,pgn8,pgn9,pgn10; - - trace(4,"decode_bds_d1_eph:\n"); - - i=8*38*0; /* page 1 */ - pgn1 =getbitu (buff,i+ 42, 4); - sow1 =getbitu2(buff,i+ 18, 8,i+ 30,12); - eph_bds.svh =getbitu (buff,i+ 46, 1); /* SatH1 */ - eph_bds.iodc =getbitu (buff,i+ 47, 5); /* AODC */ - eph_bds.sva =getbitu (buff,i+ 60, 4); - eph_bds.week =getbitu (buff,i+ 64,13); /* week in BDT */ - toc_bds =getbitu2(buff,i+ 77, 5,i+ 90,12)*8.0; - eph_bds.tgd[0]=getbits (buff,i+102,10)*0.1*1E-9; - eph_bds.tgd[1]=getbits (buff,i+120,10)*0.1*1E-9; - - i=8*38*2; /* page 3 */ - pgn3 =getbitu (buff,i+ 42, 4); - sow3 =getbitu2(buff,i+ 18, 8,i+ 30,12); - eph_bds.f0 =getbits2(buff,i+100,12,i+120,12)*P2_33; - f1p3 =getbits (buff,i+132,4); - - i=8*38*3; /* page 4 */ - pgn4 =getbitu (buff,i+ 42, 4); - sow4 =getbitu2(buff,i+ 18, 8,i+ 30,12); - f1p4 =getbitu2(buff,i+ 46, 6,i+ 60,12); - eph_bds.f2 =getbits2(buff,i+ 72,10,i+ 90, 1)*P2_66; - eph_bds.iode =getbitu (buff,i+ 91, 5); /* AODE */ - eph_bds.deln =getbits (buff,i+ 96,16)*P2_43*SC2RAD; - cucp4 =getbits (buff,i+120,14); - - i=8*38*4; /* page 5 */ - pgn5 =getbitu (buff,i+ 42, 4); - sow5 =getbitu2(buff,i+ 18, 8,i+ 30,12); - cucp5 =getbitu (buff,i+ 46, 4); - eph_bds.M0 =getbits3(buff,i+ 50, 2,i+ 60,22,i+ 90, 8)*P2_31*SC2RAD; - eph_bds.cus =getbits2(buff,i+ 98,14,i+120, 4)*P2_31; - ep5 =getbits (buff,i+124,10); - - i=8*38*5; /* page 6 */ - pgn6 =getbitu (buff,i+ 42, 4); - sow6 =getbitu2(buff,i+ 18, 8,i+ 30,12); - ep6 =getbitu2(buff,i+ 46, 6,i+ 60,16); - sqrtA =getbitu3(buff,i+ 76, 6,i+ 90,22,i+120,4)*P2_19; - cicp6 =getbits (buff,i+124,10); - eph_bds.A =sqrtA*sqrtA; - - i=8*38*6; /* page 7 */ - pgn7 =getbitu (buff,i+ 42, 4); - sow7 =getbitu2(buff,i+ 18, 8,i+ 30,12); - cicp7 =getbitu2(buff,i+ 46, 6,i+ 60, 2); - eph_bds.cis =getbits (buff,i+ 62,18)*P2_31; - eph_bds.toes =getbitu2(buff,i+ 80, 2,i+ 90,15)*8.0; - i0p7 =getbits2(buff,i+105, 7,i+120,14); - - i=8*38*7; /* page 8 */ - pgn8 =getbitu (buff,i+ 42, 4); - sow8 =getbitu2(buff,i+ 18, 8,i+ 30,12); - i0p8 =getbitu2(buff,i+ 46, 6,i+ 60, 5); - eph_bds.crc =getbits2(buff,i+ 65,17,i+ 90, 1)*P2_6; - eph_bds.crs =getbits (buff,i+ 91,18)*P2_6; - OMGdp8 =getbits2(buff,i+109, 3,i+120,16); - - i=8*38*8; /* page 9 */ - pgn9 =getbitu (buff,i+ 42, 4); - sow9 =getbitu2(buff,i+ 18, 8,i+ 30,12); - OMGdp9 =getbitu (buff,i+ 46, 5); - eph_bds.OMG0 =getbits3(buff,i+ 51, 1,i+ 60,22,i+ 90, 9)*P2_31*SC2RAD; - omgp9 =getbits2(buff,i+ 99,13,i+120,14); - - i=8*38*9; /* page 10 */ - pgn10 =getbitu (buff,i+ 42, 4); - sow10 =getbitu2(buff,i+ 18, 8,i+ 30,12); - omgp10 =getbitu (buff,i+ 46, 5); - eph_bds.idot =getbits2(buff,i+ 51, 1,i+ 60,13)*P2_43*SC2RAD; - - /* check consistency of page numbers, sows and toe/toc */ - if (pgn1!=1||pgn3!=3||pgn4!=4||pgn5!=5||pgn6!=6||pgn7!=7||pgn8!=8||pgn9!=9|| - pgn10!=10) { - trace(3,"decode_bds_d2 error: pgn=%d %d %d %d %d %d %d %d %d\n", - pgn1,pgn3,pgn4,pgn5,pgn6,pgn7,pgn8,pgn9,pgn10); - return 0; - } - if (sow3!=sow1+6||sow4!=sow3+3||sow5!=sow4+3||sow6!=sow5+3|| - sow7!=sow6+3||sow8!=sow7+3||sow9!=sow8+3||sow10!=sow9+3) { - trace(3,"decode_bds_d2 error: sow=%d %d %d %d %d %d %d %d %d\n", - sow1,sow3,sow4,sow5,sow6,sow7,sow8,sow9,sow10); - return 0; - } - if (toc_bds!=eph_bds.toes) { - trace(3,"decode_bds_d2 error: toe=%.0f toc=%.0f\n",eph_bds.toes, - toc_bds); - return 0; - } - eph_bds.f1 =merge_two_s(f1p3 ,f1p4 ,18)*P2_50; - eph_bds.cuc =merge_two_s(cucp4 ,cucp5 , 4)*P2_31; - eph_bds.e =merge_two_s(ep5 ,ep6 ,22)*P2_33; - eph_bds.cic =merge_two_s(cicp6 ,cicp7 , 8)*P2_31; - eph_bds.i0 =merge_two_s(i0p7 ,i0p8 ,11)*P2_31*SC2RAD; - eph_bds.OMGd=merge_two_s(OMGdp8,OMGdp9, 5)*P2_43*SC2RAD; - eph_bds.omg =merge_two_s(omgp9 ,omgp10, 5)*P2_31*SC2RAD; - - eph_bds.ttr=bdt2gpst(bdt2time(eph_bds.week,sow1)); /* bdt -> gpst */ - if (eph_bds.toes>sow1+302400.0) eph_bds.week++; - else if (eph_bds.toes gpst */ + if (eph_bds.toes > sow1 + 302400.0) + eph_bds.week++; + else if (eph_bds.toes < sow1 - 302400.0) + eph_bds.week--; + eph_bds.toe = bdt2gpst(bdt2time(eph_bds.week, eph_bds.toes)); + eph_bds.toc = bdt2gpst(bdt2time(eph_bds.week, toc_bds)); + eph_bds.code = 0; /* data source = unknown */ + eph_bds.flag = 2; /* nav type = GEO */ + *eph = eph_bds; + return 1; } /* decode BDS D2 UTC parameters ----------------------------------------------*/ -static int decode_bds_d2_utc(const uint8_t *buff, double *utc) -{ - int i=8*38*10; /* subframe 5 page 102 */ - - trace(4,"decode_bds_d2_utc:\n"); - - /* subframe 1 page 1 */ - if (getbitu(buff,15,3)!=1||getbitu(buff,42,4)!=1) return 0; - - /* subframe 5 page 102 */ - if (getbitu(buff,i+15,3)!=5||getbitu(buff,i+43,7)!=102) return 0; - - utc[4]=getbits2(buff,i+ 50, 2,i+ 60, 6); /* dt_LS */ - utc[7]=getbits (buff,i+ 66, 8); /* dt_LSF */ - utc[5]=getbitu (buff,i+ 74, 8); /* WN_LSF */ - utc[0]=getbits2(buff,i+ 90,22,i+120,10)*P2_30; /* A0 */ - utc[1]=getbits2(buff,i+130,12,i+150,12)*P2_50; /* A1 */ - utc[6]=getbitu (buff,i+162, 8); /* DN */ - utc[2]=getbits2(buff,i+ 18, 8,i+ 30,12); /* SOW */ - utc[3]=getbitu (buff,64,13); /* WN */ - return 1; +static int decode_bds_d2_utc(const uint8_t *buff, double *utc) { + int i = 8 * 38 * 10; /* subframe 5 page 102 */ + + trace(4, "decode_bds_d2_utc:\n"); + + /* subframe 1 page 1 */ + if (getbitu(buff, 15, 3) != 1 || getbitu(buff, 42, 4) != 1) return 0; + + /* subframe 5 page 102 */ + if (getbitu(buff, i + 15, 3) != 5 || getbitu(buff, i + 43, 7) != 102) return 0; + + utc[4] = getbits2(buff, i + 50, 2, i + 60, 6); /* dt_LS */ + utc[7] = getbits(buff, i + 66, 8); /* dt_LSF */ + utc[5] = getbitu(buff, i + 74, 8); /* WN_LSF */ + utc[0] = getbits2(buff, i + 90, 22, i + 120, 10) * P2_30; /* A0 */ + utc[1] = getbits2(buff, i + 130, 12, i + 150, 12) * P2_50; /* A1 */ + utc[6] = getbitu(buff, i + 162, 8); /* DN */ + utc[2] = getbits2(buff, i + 18, 8, i + 30, 12); /* SOW */ + utc[3] = getbitu(buff, 64, 13); /* WN */ + return 1; } /* decode BDS D2 navigation data ----------------------------------------------- -* decode BDS D2 navigation data (GEO) (ref [3] 5.3) -* args : uint8_t *buff I BDS D2 subframe data (CRC checked with parity) -* buff[ 0- 37]: subframe 1 page 1 (300 bits) -* buff[ 38- 75]: subframe 1 page 2 -* ... -* buff[342-379]: subframe 1 page 10 -* buff[380-417]: subframe 5 page 102 -* eph_t *eph IO BDS D2 ephemeris (NULL: not output) -* double *utc IO BDS D2 UTC parameters (NULL: not output) -* utc[0-2]: A0,A1,tot,WNt -* utc[4-7]: dt_LS,WN_LSF,DN,dt_LSF -* return : status (1:ok,0:error) -*-----------------------------------------------------------------------------*/ -extern int decode_bds_d2(const uint8_t *buff, eph_t *eph, double *utc) -{ - trace(4,"decode_bds_d2:\n"); - - if (eph&&!decode_bds_d2_eph(buff,eph)) return 0; - if (utc&&!decode_bds_d2_utc(buff,utc)) return 0; - return 1; + * decode BDS D2 navigation data (GEO) (ref [3] 5.3) + * args : uint8_t *buff I BDS D2 subframe data (CRC checked with parity) + * buff[ 0- 37]: subframe 1 page 1 (300 bits) + * buff[ 38- 75]: subframe 1 page 2 + * ... + * buff[342-379]: subframe 1 page 10 + * buff[380-417]: subframe 5 page 102 + * eph_t *eph IO BDS D2 ephemeris (NULL: not output) + * double *utc IO BDS D2 UTC parameters (NULL: not output) + * utc[0-2]: A0,A1,tot,WNt + * utc[4-7]: dt_LS,WN_LSF,DN,dt_LSF + * return : status (1:ok,0:error) + *-----------------------------------------------------------------------------*/ +extern int decode_bds_d2(const uint8_t *buff, eph_t *eph, double *utc) { + trace(4, "decode_bds_d2:\n"); + + if (eph && !decode_bds_d2_eph(buff, eph)) return 0; + if (utc && !decode_bds_d2_utc(buff, utc)) return 0; + return 1; } /* test hamming code of GLONASS navigation string ------------------------------ -* test hamming code of GLONASS navigation string (ref [2] 4.7) -* args : uint8_t *buff I GLONASS navigation string with hamming code -* buff[ 0]: string bit 85-78 -* buff[ 1]: string bit 77-70 -* ... -* buff[10]: string bit 5- 1 (0 padded) -* return : status (1:ok,0:error) -*-----------------------------------------------------------------------------*/ -extern int test_glostr(const uint8_t *buff) -{ - static const uint8_t xor_8bit[256]={ /* xor of 8 bits */ - 0,1,1,0,1,0,0,1,1,0,0,1,0,1,1,0,1,0,0,1,0,1,1,0,0,1,1,0,1,0,0,1, - 1,0,0,1,0,1,1,0,0,1,1,0,1,0,0,1,0,1,1,0,1,0,0,1,1,0,0,1,0,1,1,0, - 1,0,0,1,0,1,1,0,0,1,1,0,1,0,0,1,0,1,1,0,1,0,0,1,1,0,0,1,0,1,1,0, - 0,1,1,0,1,0,0,1,1,0,0,1,0,1,1,0,1,0,0,1,0,1,1,0,0,1,1,0,1,0,0,1, - 1,0,0,1,0,1,1,0,0,1,1,0,1,0,0,1,0,1,1,0,1,0,0,1,1,0,0,1,0,1,1,0, - 0,1,1,0,1,0,0,1,1,0,0,1,0,1,1,0,1,0,0,1,0,1,1,0,0,1,1,0,1,0,0,1, - 0,1,1,0,1,0,0,1,1,0,0,1,0,1,1,0,1,0,0,1,0,1,1,0,0,1,1,0,1,0,0,1, - 1,0,0,1,0,1,1,0,0,1,1,0,1,0,0,1,0,1,1,0,1,0,0,1,1,0,0,1,0,1,1,0 - }; - static const uint8_t mask_hamming[][12]={ /* mask of hamming codes */ - {0x55,0x55,0x5A,0xAA,0xAA,0xAA,0xB5,0x55,0x6A,0xD8,0x08}, - {0x66,0x66,0x6C,0xCC,0xCC,0xCC,0xD9,0x99,0xB3,0x68,0x10}, - {0x87,0x87,0x8F,0x0F,0x0F,0x0F,0x1E,0x1E,0x3C,0x70,0x20}, - {0x07,0xF8,0x0F,0xF0,0x0F,0xF0,0x1F,0xE0,0x3F,0x80,0x40}, - {0xF8,0x00,0x0F,0xFF,0xF0,0x00,0x1F,0xFF,0xC0,0x00,0x80}, - {0x00,0x00,0x0F,0xFF,0xFF,0xFF,0xE0,0x00,0x00,0x01,0x00}, - {0xFF,0xFF,0xF0,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x00}, - {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xF8} - }; - uint8_t cs; - int i,j,n=0; - - for (i=0;i<8;i++) { - for (j=0,cs=0;j<11;j++) { - cs^=xor_8bit[buff[j]&mask_hamming[i][j]]; - } - if (cs) n++; + * test hamming code of GLONASS navigation string (ref [2] 4.7) + * args : uint8_t *buff I GLONASS navigation string with hamming code + * buff[ 0]: string bit 85-78 + * buff[ 1]: string bit 77-70 + * ... + * buff[10]: string bit 5- 1 (0 padded) + * return : status (1:ok,0:error) + *-----------------------------------------------------------------------------*/ +extern int test_glostr(const uint8_t *buff) { + static const uint8_t xor_8bit[256] = { + /* xor of 8 bits */ + 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0, 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, + 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1, 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, + 0, 1, 0, 1, 1, 0, 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1, 0, 1, 1, 0, 1, 0, 0, + 1, 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0, 1, 0, 0, 1, + 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1, 0, + 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, + 1, 0, 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1, 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, + 1, 0, 1, 1, 0, 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0, + 0, 1, 1, 0, 1, 0, 0, 1, 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0}; + static const uint8_t mask_hamming[][12] = { + /* mask of hamming codes */ + {0x55, 0x55, 0x5A, 0xAA, 0xAA, 0xAA, 0xB5, 0x55, 0x6A, 0xD8, 0x08}, + {0x66, 0x66, 0x6C, 0xCC, 0xCC, 0xCC, 0xD9, 0x99, 0xB3, 0x68, 0x10}, + {0x87, 0x87, 0x8F, 0x0F, 0x0F, 0x0F, 0x1E, 0x1E, 0x3C, 0x70, 0x20}, + {0x07, 0xF8, 0x0F, 0xF0, 0x0F, 0xF0, 0x1F, 0xE0, 0x3F, 0x80, 0x40}, + {0xF8, 0x00, 0x0F, 0xFF, 0xF0, 0x00, 0x1F, 0xFF, 0xC0, 0x00, 0x80}, + {0x00, 0x00, 0x0F, 0xFF, 0xFF, 0xFF, 0xE0, 0x00, 0x00, 0x01, 0x00}, + {0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00}, + {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF8}}; + uint8_t cs; + int i, j, n = 0; + + for (i = 0; i < 8; i++) { + for (j = 0, cs = 0; j < 11; j++) { + cs ^= xor_8bit[buff[j] & mask_hamming[i][j]]; } - return n==0||(n==2&&cs); + if (cs) n++; + } + return n == 0 || (n == 2 && cs); } /* decode GLONASS ephemeris --------------------------------------------------*/ -static int decode_glostr_eph(const uint8_t *buff, geph_t *geph) -{ - geph_t geph_glo={0}; - double tow,tod,tof,toe; - int P,P1,P2,P3,P4,tk_h,tk_m,tk_s,tb,ln,NT,slot,M,week; - int i=1,frn1,frn2,frn3,frn4; - - trace(4,"decode_glostr_eph:\n"); - - /* frame 1 */ - frn1 =getbitu(buff,i, 4); i+= 4+2; - P1 =getbitu(buff,i, 2); i+= 2; - tk_h =getbitu(buff,i, 5); i+= 5; - tk_m =getbitu(buff,i, 6); i+= 6; - tk_s =getbitu(buff,i, 1)*30; i+= 1; - geph_glo.vel[0]=getbitg(buff,i,24)*P2_20*1E3; i+=24; - geph_glo.acc[0]=getbitg(buff,i, 5)*P2_30*1E3; i+= 5; - geph_glo.pos[0]=getbitg(buff,i,27)*P2_11*1E3; i+=27+4; - - /* frame 2 */ - frn2 =getbitu(buff,i, 4); i+= 4; - int Bn =getbitu(buff,i, 1); i+= 1+2; /* MSB of Bn */ - P2 =getbitu(buff,i, 1); i+= 1; - tb =getbitu(buff,i, 7); i+= 7+5; - geph_glo.vel[1]=getbitg(buff,i,24)*P2_20*1E3; i+=24; - geph_glo.acc[1]=getbitg(buff,i, 5)*P2_30*1E3; i+= 5; - geph_glo.pos[1]=getbitg(buff,i,27)*P2_11*1E3; i+=27+4; - - /* frame 3 */ - frn3 =getbitu(buff,i, 4); i+= 4; - P3 =getbitu(buff,i, 1); i+= 1; - geph_glo.gamn =getbitg(buff,i,11)*P2_40; i+=11+1; - P =getbitu(buff,i, 2); i+= 2; - ln =getbitu(buff,i, 1); i+= 1; - geph_glo.vel[2]=getbitg(buff,i,24)*P2_20*1E3; i+=24; - geph_glo.acc[2]=getbitg(buff,i, 5)*P2_30*1E3; i+= 5; - geph_glo.pos[2]=getbitg(buff,i,27)*P2_11*1E3; i+=27+4; - - /* frame 4 */ - frn4 =getbitu(buff,i, 4); i+= 4; - geph_glo.taun =getbitg(buff,i,22)*P2_30; i+=22; - geph_glo.dtaun =getbitg(buff,i, 5)*P2_30; i+= 5; - geph_glo.age =getbitu(buff,i, 5); i+= 5+14; - P4 =getbitu(buff,i, 1); i+= 1; - geph_glo.sva =getbitu(buff,i, 4); i+= 4+3; - NT =getbitu(buff,i,11); i+=11; - slot =getbitu(buff,i, 5); i+= 5; - M =getbitu(buff,i, 2); - - if (frn1!=1||frn2!=2||frn3!=3||frn4!=4) { - trace(3,"decode_glostr error: frn=%d %d %d %d\n",frn1,frn2,frn3,frn4); - return 0; - } - if (!(geph_glo.sat=satno(SYS_GLO,slot))) { - trace(2,"decode_glostr error: slot=%d\n",slot); - return 0; - } - geph_glo.frq=0; /* set default */ - geph_glo.iode=tb; - geph_glo.svh = (ln << 3) | Bn; // Extended SVH - geph_glo.flags = (M << 7) | (P4 << 6) | (P3 << 5) | (P2 << 4) | (P1 << 2) | P; // Status flags - tow=time2gpst(gpst2utc(geph->tof),&week); - tod=fmod(tow,86400.0); tow-=tod; - tof=tk_h*3600.0+tk_m*60.0+tk_s-10800.0; /* lt->utc */ - if (toftod+43200.0) tof-=86400.0; - geph_glo.tof=utc2gpst(gpst2time(week,tow+tof)); - toe=tb*900.0-10800.0; /* lt->utc */ - if (toetod+43200.0) toe-=86400.0; - geph_glo.toe=utc2gpst(gpst2time(week,tow+toe)); /* utc->gpst */ - *geph=geph_glo; - return 1; +static int decode_glostr_eph(const uint8_t *buff, geph_t *geph) { + geph_t geph_glo = {0}; + double tow, tod, tof, toe; + int P, P1, P2, P3, P4, tk_h, tk_m, tk_s, tb, ln, NT, slot, M, week; + int i = 1, frn1, frn2, frn3, frn4; + + trace(4, "decode_glostr_eph:\n"); + + /* frame 1 */ + frn1 = getbitu(buff, i, 4); + i += 4 + 2; + P1 = getbitu(buff, i, 2); + i += 2; + tk_h = getbitu(buff, i, 5); + i += 5; + tk_m = getbitu(buff, i, 6); + i += 6; + tk_s = getbitu(buff, i, 1) * 30; + i += 1; + geph_glo.vel[0] = getbitg(buff, i, 24) * P2_20 * 1E3; + i += 24; + geph_glo.acc[0] = getbitg(buff, i, 5) * P2_30 * 1E3; + i += 5; + geph_glo.pos[0] = getbitg(buff, i, 27) * P2_11 * 1E3; + i += 27 + 4; + + /* frame 2 */ + frn2 = getbitu(buff, i, 4); + i += 4; + int Bn = getbitu(buff, i, 1); + i += 1 + 2; /* MSB of Bn */ + P2 = getbitu(buff, i, 1); + i += 1; + tb = getbitu(buff, i, 7); + i += 7 + 5; + geph_glo.vel[1] = getbitg(buff, i, 24) * P2_20 * 1E3; + i += 24; + geph_glo.acc[1] = getbitg(buff, i, 5) * P2_30 * 1E3; + i += 5; + geph_glo.pos[1] = getbitg(buff, i, 27) * P2_11 * 1E3; + i += 27 + 4; + + /* frame 3 */ + frn3 = getbitu(buff, i, 4); + i += 4; + P3 = getbitu(buff, i, 1); + i += 1; + geph_glo.gamn = getbitg(buff, i, 11) * P2_40; + i += 11 + 1; + P = getbitu(buff, i, 2); + i += 2; + ln = getbitu(buff, i, 1); + i += 1; + geph_glo.vel[2] = getbitg(buff, i, 24) * P2_20 * 1E3; + i += 24; + geph_glo.acc[2] = getbitg(buff, i, 5) * P2_30 * 1E3; + i += 5; + geph_glo.pos[2] = getbitg(buff, i, 27) * P2_11 * 1E3; + i += 27 + 4; + + /* frame 4 */ + frn4 = getbitu(buff, i, 4); + i += 4; + geph_glo.taun = getbitg(buff, i, 22) * P2_30; + i += 22; + geph_glo.dtaun = getbitg(buff, i, 5) * P2_30; + i += 5; + geph_glo.age = getbitu(buff, i, 5); + i += 5 + 14; + P4 = getbitu(buff, i, 1); + i += 1; + geph_glo.sva = getbitu(buff, i, 4); + i += 4 + 3; + NT = getbitu(buff, i, 11); + i += 11; + slot = getbitu(buff, i, 5); + i += 5; + M = getbitu(buff, i, 2); + + if (frn1 != 1 || frn2 != 2 || frn3 != 3 || frn4 != 4) { + trace(3, "decode_glostr error: frn=%d %d %d %d\n", frn1, frn2, frn3, frn4); + return 0; + } + if (!(geph_glo.sat = satno(SYS_GLO, slot))) { + trace(2, "decode_glostr error: slot=%d\n", slot); + return 0; + } + geph_glo.frq = 0; /* set default */ + geph_glo.iode = tb; + geph_glo.svh = (ln << 3) | Bn; // Extended SVH + geph_glo.flags = (M << 7) | (P4 << 6) | (P3 << 5) | (P2 << 4) | (P1 << 2) | P; // Status flags + tow = time2gpst(gpst2utc(geph->tof), &week); + tod = fmod(tow, 86400.0); + tow -= tod; + tof = tk_h * 3600.0 + tk_m * 60.0 + tk_s - 10800.0; /* lt->utc */ + if (tof < tod - 43200.0) + tof += 86400.0; + else if (tof > tod + 43200.0) + tof -= 86400.0; + geph_glo.tof = utc2gpst(gpst2time(week, tow + tof)); + toe = tb * 900.0 - 10800.0; /* lt->utc */ + if (toe < tod - 43200.0) + toe += 86400.0; + else if (toe > tod + 43200.0) + toe -= 86400.0; + geph_glo.toe = utc2gpst(gpst2time(week, tow + toe)); /* utc->gpst */ + *geph = geph_glo; + return 1; } /* decode GLONASS UTC parameters ---------------------------------------------*/ -static int decode_glostr_utc(const uint8_t *buff, double *utc) -{ - int i=1+80*4; /* frame 5 */ - - trace(4,"decode_glostr_utc:\n"); - - /* frame 5 */ - if (getbitu(buff,i,4)!=5) return 0; - i+=4+11; - utc[0]=getbits(buff,i,32)*P2_31; i+=32+1+6; /* tau_C */ - utc[1]=getbits(buff,i,22)*P2_30; /* tau_GPS */ - utc[2]=utc[3]=utc[4]=utc[5]=utc[6]=utc[7]=0.0; - return 1; +static int decode_glostr_utc(const uint8_t *buff, double *utc) { + int i = 1 + 80 * 4; /* frame 5 */ + + trace(4, "decode_glostr_utc:\n"); + + /* frame 5 */ + if (getbitu(buff, i, 4) != 5) return 0; + i += 4 + 11; + utc[0] = getbits(buff, i, 32) * P2_31; + i += 32 + 1 + 6; /* tau_C */ + utc[1] = getbits(buff, i, 22) * P2_30; /* tau_GPS */ + utc[2] = utc[3] = utc[4] = utc[5] = utc[6] = utc[7] = 0.0; + return 1; } /* decode GLONASS navigation data strings -------------------------------------- -* decode GLONASS navigation data string (ref [2]) -* args : uint8_t *buff I GLONASS navigation data string -* (w/o hamming and time mark) -* buff[ 0- 9]: string 1 (77 bits) -* buff[10-19]: string 2 -* buff[20-29]: string 3 -* buff[30-39]: string 4 -* buff[40-49]: string 5 -* geph_t *geph IO GLONASS ephemeris (NULL: not output) -* double *utc IO GLONASS UTC parameters (NULL: not output) -* utc[0] : A0 (=-tau_C) -* utc[1-7]: reserved -* return : status (1:ok,0:error) -* notes : geph->tof should be set to frame time within 1/2 day before calling -* geph->frq is set to 0 -*-----------------------------------------------------------------------------*/ -extern int decode_glostr(const uint8_t *buff, geph_t *geph, double *utc) -{ - trace(4,"decode_glostr:\n"); - - if (geph&&!decode_glostr_eph(buff,geph)) return 0; - if (utc &&!decode_glostr_utc(buff,utc )) return 0; - return 1; + * decode GLONASS navigation data string (ref [2]) + * args : uint8_t *buff I GLONASS navigation data string + * (w/o hamming and time mark) + * buff[ 0- 9]: string 1 (77 bits) + * buff[10-19]: string 2 + * buff[20-29]: string 3 + * buff[30-39]: string 4 + * buff[40-49]: string 5 + * geph_t *geph IO GLONASS ephemeris (NULL: not output) + * double *utc IO GLONASS UTC parameters (NULL: not output) + * utc[0] : A0 (=-tau_C) + * utc[1-7]: reserved + * return : status (1:ok,0:error) + * notes : geph->tof should be set to frame time within 1/2 day before calling + * geph->frq is set to 0 + *-----------------------------------------------------------------------------*/ +extern int decode_glostr(const uint8_t *buff, geph_t *geph, double *utc) { + trace(4, "decode_glostr:\n"); + + if (geph && !decode_glostr_eph(buff, geph)) return 0; + if (utc && !decode_glostr_utc(buff, utc)) return 0; + return 1; } /* decode GPS/QZSS ephemeris -------------------------------------------------*/ -static int decode_frame_eph(const uint8_t *buff, int sys, eph_t *eph) -{ - trace(4, "decode_frame_eph: sys=%d\n", sys); - - eph_t eph_sat={0}; - double tow1,tow2,tow3,toc,sqrtA; - int i=48,id1,id2,id3,week,iodc0,iodc1,iode,tgd; - - i=240*0+24; /* subframe 1 */ - tow1 =getbitu(buff,i,17)*6.0; i+=17+2; - id1 =getbitu(buff,i, 3); i+=3+2; - week =getbitu(buff,i,10); i+=10; - eph_sat.code=getbitu(buff,i, 2); i+= 2; - eph_sat.sva =getbitu(buff,i, 4); i+= 4; /* ura index */ - eph_sat.svh =getbitu(buff,i, 6); i+= 6; - iodc0 =getbitu(buff,i, 2); i+= 2; - eph_sat.flag=getbitu(buff,i, 1); i+= 1+87; - tgd =getbits(buff,i, 8); i+= 8; - iodc1 =getbitu(buff,i, 8); i+= 8; - toc =getbitu(buff,i,16)*16.0; i+=16; - eph_sat.f2 =getbits(buff,i, 8)*P2_55; i+= 8; - eph_sat.f1 =getbits(buff,i,16)*P2_43; i+=16; - eph_sat.f0 =getbits(buff,i,22)*P2_31; - - i=240*1+24; /* subframe 2 */ - tow2 =getbitu(buff,i,17)*6.0; i+=17+2; - id2 =getbitu(buff,i, 3); i+=3+2; - eph_sat.iode=getbitu(buff,i, 8); i+= 8; - eph_sat.crs =getbits(buff,i,16)*P2_5; i+=16; - eph_sat.deln=getbits(buff,i,16)*P2_43*SC2RAD; i+=16; - eph_sat.M0 =getbits(buff,i,32)*P2_31*SC2RAD; i+=32; - eph_sat.cuc =getbits(buff,i,16)*P2_29; i+=16; - eph_sat.e =getbitu(buff,i,32)*P2_33; i+=32; - eph_sat.cus =getbits(buff,i,16)*P2_29; i+=16; - sqrtA =getbitu(buff,i,32)*P2_19; i+=32; - eph_sat.toes=getbitu(buff,i,16)*16.0; i+=16; - if (sys==SYS_GPS) - eph_sat.fit=getbitu(buff,i,1)?6:4; /* 0:4hr,1:>4hr */ - else if (sys==SYS_QZS) - eph_sat.fit=getbitu(buff,i,1)?4:2; /* 0:2hr,1:>2hr */ - - i=240*2+24; /* subframe 3 */ - tow3 =getbitu(buff,i,17)*6.0; i+=17+2; - id3 =getbitu(buff,i, 3); i+=3+2; - eph_sat.cic =getbits(buff,i,16)*P2_29; i+=16; - eph_sat.OMG0=getbits(buff,i,32)*P2_31*SC2RAD; i+=32; - eph_sat.cis =getbits(buff,i,16)*P2_29; i+=16; - eph_sat.i0 =getbits(buff,i,32)*P2_31*SC2RAD; i+=32; - eph_sat.crc =getbits(buff,i,16)*P2_5; i+=16; - eph_sat.omg =getbits(buff,i,32)*P2_31*SC2RAD; i+=32; - eph_sat.OMGd=getbits(buff,i,24)*P2_43*SC2RAD; i+=24; - iode =getbitu(buff,i, 8); i+= 8; - eph_sat.idot=getbits(buff,i,14)*P2_43*SC2RAD; - - eph_sat.A=sqrtA*sqrtA; - eph_sat.iodc=(iodc0<<8)+iodc1; - eph_sat.tgd[0]=(tgd==-128)?0.0:tgd*P2_31; /* ref [4] */ - - /* test subframe ids */ - if (id1!=1||id2!=2||id3!=3) { - trace(3,"decode_frame_eph error: id=%d %d %d\n",id1,id2,id3); - return 0; - } - /* test iode and iodc consistency */ - if (iode!=eph_sat.iode||iode!=(eph_sat.iodc&0xFF)) { - trace(3,"decode_frame_eph error: iode=%d %d iodc=%d\n",eph_sat.iode, - iode,eph_sat.iodc); - return 0; -} - eph_sat.week=adjgpsweek(week); - eph_sat.ttr=gpst2time(eph_sat.week,tow1); - if (eph_sat.toestow1+302400.0) eph_sat.week--; - eph_sat.toe=gpst2time(eph_sat.week,eph_sat.toes); - eph_sat.toc=gpst2time(eph_sat.week,toc); - *eph=eph_sat; - return 1; +static int decode_frame_eph(const uint8_t *buff, int sys, eph_t *eph) { + trace(4, "decode_frame_eph: sys=%d\n", sys); + + eph_t eph_sat = {0}; + double tow1, tow2, tow3, toc, sqrtA; + int i = 48, id1, id2, id3, week, iodc0, iodc1, iode, tgd; + + i = 240 * 0 + 24; /* subframe 1 */ + tow1 = getbitu(buff, i, 17) * 6.0; + i += 17 + 2; + id1 = getbitu(buff, i, 3); + i += 3 + 2; + week = getbitu(buff, i, 10); + i += 10; + eph_sat.code = getbitu(buff, i, 2); + i += 2; + eph_sat.sva = getbitu(buff, i, 4); + i += 4; /* ura index */ + eph_sat.svh = getbitu(buff, i, 6); + i += 6; + iodc0 = getbitu(buff, i, 2); + i += 2; + eph_sat.flag = getbitu(buff, i, 1); + i += 1 + 87; + tgd = getbits(buff, i, 8); + i += 8; + iodc1 = getbitu(buff, i, 8); + i += 8; + toc = getbitu(buff, i, 16) * 16.0; + i += 16; + eph_sat.f2 = getbits(buff, i, 8) * P2_55; + i += 8; + eph_sat.f1 = getbits(buff, i, 16) * P2_43; + i += 16; + eph_sat.f0 = getbits(buff, i, 22) * P2_31; + + i = 240 * 1 + 24; /* subframe 2 */ + tow2 = getbitu(buff, i, 17) * 6.0; + i += 17 + 2; + id2 = getbitu(buff, i, 3); + i += 3 + 2; + eph_sat.iode = getbitu(buff, i, 8); + i += 8; + eph_sat.crs = getbits(buff, i, 16) * P2_5; + i += 16; + eph_sat.deln = getbits(buff, i, 16) * P2_43 * SC2RAD; + i += 16; + eph_sat.M0 = getbits(buff, i, 32) * P2_31 * SC2RAD; + i += 32; + eph_sat.cuc = getbits(buff, i, 16) * P2_29; + i += 16; + eph_sat.e = getbitu(buff, i, 32) * P2_33; + i += 32; + eph_sat.cus = getbits(buff, i, 16) * P2_29; + i += 16; + sqrtA = getbitu(buff, i, 32) * P2_19; + i += 32; + eph_sat.toes = getbitu(buff, i, 16) * 16.0; + i += 16; + if (sys == SYS_GPS) + eph_sat.fit = getbitu(buff, i, 1) ? 6 : 4; /* 0:4hr,1:>4hr */ + else if (sys == SYS_QZS) + eph_sat.fit = getbitu(buff, i, 1) ? 4 : 2; /* 0:2hr,1:>2hr */ + + i = 240 * 2 + 24; /* subframe 3 */ + tow3 = getbitu(buff, i, 17) * 6.0; + i += 17 + 2; + id3 = getbitu(buff, i, 3); + i += 3 + 2; + eph_sat.cic = getbits(buff, i, 16) * P2_29; + i += 16; + eph_sat.OMG0 = getbits(buff, i, 32) * P2_31 * SC2RAD; + i += 32; + eph_sat.cis = getbits(buff, i, 16) * P2_29; + i += 16; + eph_sat.i0 = getbits(buff, i, 32) * P2_31 * SC2RAD; + i += 32; + eph_sat.crc = getbits(buff, i, 16) * P2_5; + i += 16; + eph_sat.omg = getbits(buff, i, 32) * P2_31 * SC2RAD; + i += 32; + eph_sat.OMGd = getbits(buff, i, 24) * P2_43 * SC2RAD; + i += 24; + iode = getbitu(buff, i, 8); + i += 8; + eph_sat.idot = getbits(buff, i, 14) * P2_43 * SC2RAD; + + eph_sat.A = sqrtA * sqrtA; + eph_sat.iodc = (iodc0 << 8) + iodc1; + eph_sat.tgd[0] = (tgd == -128) ? 0.0 : tgd * P2_31; /* ref [4] */ + + /* test subframe ids */ + if (id1 != 1 || id2 != 2 || id3 != 3) { + trace(3, "decode_frame_eph error: id=%d %d %d\n", id1, id2, id3); + return 0; + } + /* test iode and iodc consistency */ + if (iode != eph_sat.iode || iode != (eph_sat.iodc & 0xFF)) { + trace(3, "decode_frame_eph error: iode=%d %d iodc=%d\n", eph_sat.iode, iode, eph_sat.iodc); + return 0; + } + eph_sat.week = adjgpsweek(week); + eph_sat.ttr = gpst2time(eph_sat.week, tow1); + if (eph_sat.toes < tow1 - 302400.0) + eph_sat.week++; + else if (eph_sat.toes > tow1 + 302400.0) + eph_sat.week--; + eph_sat.toe = gpst2time(eph_sat.week, eph_sat.toes); + eph_sat.toc = gpst2time(eph_sat.week, toc); + *eph = eph_sat; + return 1; } /* decode GPS/QZSS satellite almanac -----------------------------------------*/ -static void decode_alm_sat(const uint8_t *buff, int type, alm_t *alm) -{ - gtime_t toa0={0}; - double deltai,sqrtA,i_ref,e_ref; - int i=50,f0; - - trace(4,"decode_alm_sat:\n"); - - /* type=0:GPS,1:QZS-QZO,2:QZS-GEO */ - e_ref=(type==0)?0.0:((type==1)?0.06:0.0); - i_ref=(type==0)?0.3:((type==1)?0.25:0.0); - - alm->e =getbits(buff,i,16)*P2_21+e_ref; i+=16; - alm->toas=getbitu(buff,i, 8)*4096.0; i+= 8; - deltai =getbits(buff,i,16)*P2_19; i+=16; - alm->OMGd=getbits(buff,i,16)*P2_38*SC2RAD; i+=16; - alm->svh =getbitu(buff,i, 8); i+= 8; - sqrtA =getbitu(buff,i,24)*P2_11; i+=24; - alm->OMG0=getbits(buff,i,24)*P2_23*SC2RAD; i+=24; - alm->omg =getbits(buff,i,24)*P2_23*SC2RAD; i+=24; - alm->M0 =getbits(buff,i,24)*P2_23*SC2RAD; i+=24; - f0 =getbits(buff,i, 8); i+= 8; - alm->f1 =getbits(buff,i,11)*P2_38; i+=11; - alm->f0 =getbitu(buff,i, 3)*P2_17+f0*P2_20; - alm->A =sqrtA*sqrtA; - alm->i0 =(i_ref+deltai)*SC2RAD; - alm->week=0; - alm->toa=toa0; +static void decode_alm_sat(const uint8_t *buff, int type, alm_t *alm) { + gtime_t toa0 = {0}; + double deltai, sqrtA, i_ref, e_ref; + int i = 50, f0; + + trace(4, "decode_alm_sat:\n"); + + /* type=0:GPS,1:QZS-QZO,2:QZS-GEO */ + e_ref = (type == 0) ? 0.0 : ((type == 1) ? 0.06 : 0.0); + i_ref = (type == 0) ? 0.3 : ((type == 1) ? 0.25 : 0.0); + + alm->e = getbits(buff, i, 16) * P2_21 + e_ref; + i += 16; + alm->toas = getbitu(buff, i, 8) * 4096.0; + i += 8; + deltai = getbits(buff, i, 16) * P2_19; + i += 16; + alm->OMGd = getbits(buff, i, 16) * P2_38 * SC2RAD; + i += 16; + alm->svh = getbitu(buff, i, 8); + i += 8; + sqrtA = getbitu(buff, i, 24) * P2_11; + i += 24; + alm->OMG0 = getbits(buff, i, 24) * P2_23 * SC2RAD; + i += 24; + alm->omg = getbits(buff, i, 24) * P2_23 * SC2RAD; + i += 24; + alm->M0 = getbits(buff, i, 24) * P2_23 * SC2RAD; + i += 24; + f0 = getbits(buff, i, 8); + i += 8; + alm->f1 = getbits(buff, i, 11) * P2_38; + i += 11; + alm->f0 = getbitu(buff, i, 3) * P2_17 + f0 * P2_20; + alm->A = sqrtA * sqrtA; + alm->i0 = (i_ref + deltai) * SC2RAD; + alm->week = 0; + alm->toa = toa0; } /* decode GPS almanac/health -------------------------------------------------*/ -static int decode_alm_gps(const uint8_t *buff, int frm, alm_t *alm) -{ - int i,j,sat,toas,week,svid=getbitu(buff,50,6); - - trace(4,"decode_alm_gps:\n"); - - if ((frm==5&&svid>=1&&svid<=24)||(frm==4&&svid>=25&&svid<=32)) { - if (!(sat=satno(SYS_GPS,svid))) return 0; - alm[sat-1].sat =sat; - decode_alm_sat(buff,0,alm+sat); - return 1; +static int decode_alm_gps(const uint8_t *buff, int frm, alm_t *alm) { + int i, j, sat, toas, week, svid = getbitu(buff, 50, 6); + + trace(4, "decode_alm_gps:\n"); + + if ((frm == 5 && svid >= 1 && svid <= 24) || (frm == 4 && svid >= 25 && svid <= 32)) { + if (!(sat = satno(SYS_GPS, svid))) return 0; + alm[sat - 1].sat = sat; + decode_alm_sat(buff, 0, alm + sat); + return 1; + } else if (frm == 5 && svid == 51) { /* subframe 5 page 25 */ + i = 56; + toas = getbitu(buff, i, 8) * 4096; + i += 8; + week = getbitu(buff, i, 8); + i += 8; + for (j = 0; j < 24; j++, i += 6) { + if (!(sat = satno(SYS_GPS, j + 1))) continue; + alm[sat - 1].svh = getbitu(buff, i, 6); } - else if (frm==5&&svid==51) { /* subframe 5 page 25 */ - i=56; - toas=getbitu(buff,i,8)*4096; i+=8; - week=getbitu(buff,i,8); i+=8; - for (j=0;j<24;j++,i+=6) { - if (!(sat=satno(SYS_GPS,j+1))) continue; - alm[sat-1].svh=getbitu(buff,i,6); - } - for (j=0;j<32;j++) { - if (!(sat=satno(SYS_GPS,j+1))||alm[sat-1].sat!=sat|| - alm[sat-1].toas!=toas) continue; - alm[sat-1].week=adjgpsweek(week); - alm[sat-1].toa=gpst2time(alm[sat-1].week,toas); - } - return 1; + for (j = 0; j < 32; j++) { + if (!(sat = satno(SYS_GPS, j + 1)) || alm[sat - 1].sat != sat || alm[sat - 1].toas != toas) + continue; + alm[sat - 1].week = adjgpsweek(week); + alm[sat - 1].toa = gpst2time(alm[sat - 1].week, toas); } - else if (frm==4&&svid==63) { /* subframe 4 page 25 */ - i=186; - for (j=0;j<8;j++,i+=6) { - if (!(sat=satno(SYS_GPS,j+25))) continue; - alm[sat-1].svh=getbitu(buff,i,6); - } - return 1; + return 1; + } else if (frm == 4 && svid == 63) { /* subframe 4 page 25 */ + i = 186; + for (j = 0; j < 8; j++, i += 6) { + if (!(sat = satno(SYS_GPS, j + 25))) continue; + alm[sat - 1].svh = getbitu(buff, i, 6); } - return 0; + return 1; + } + return 0; } /* decode QZSS almanac/health ------------------------------------------------*/ -static int decode_alm_qzs(const uint8_t *buff, alm_t *alm) -{ - int i,j,sat,toas,week,svid=getbitu(buff,50,6); - - trace(4,"decode_alm_qzs:\n"); - - if (svid>=1&&svid<=9) { - if (!(sat=satno(SYS_QZS,192+svid))) return 0; - alm[sat-1].sat=sat; - decode_alm_sat(buff,(svid<=6)?1:2,alm+sat); - return 1; +static int decode_alm_qzs(const uint8_t *buff, alm_t *alm) { + int i, j, sat, toas, week, svid = getbitu(buff, 50, 6); + + trace(4, "decode_alm_qzs:\n"); + + if (svid >= 1 && svid <= 9) { + if (!(sat = satno(SYS_QZS, 192 + svid))) return 0; + alm[sat - 1].sat = sat; + decode_alm_sat(buff, (svid <= 6) ? 1 : 2, alm + sat); + return 1; + } else if (svid == 51) { + i = 56; + toas = getbitu(buff, i, 8) * 4096; + i += 8; + week = getbitu(buff, i, 8); + i += 8; + for (j = 0; j < 10; j++, i += 6) { + if (!(sat = satno(SYS_QZS, 193 + j))) continue; + alm[sat - 1].svh = getbitu(buff, i, 6); } - else if (svid==51) { - i=56; - toas=getbitu(buff,i,8)*4096; i+=8; - week=getbitu(buff,i,8); i+=8; - for (j=0;j<10;j++,i+=6) { - if (!(sat=satno(SYS_QZS,193+j))) continue; - alm[sat-1].svh=getbitu(buff,i,6); - } - for (j=0;j<10;j++) { - if (!(sat=satno(SYS_QZS,193+j))||alm[sat-1].sat!=sat|| - alm[sat-1].toas!=toas) continue; - alm[sat-1].week=adjgpsweek(week); - alm[sat-1].toa=gpst2time(alm[sat-1].week,toas); - } - return 1; + for (j = 0; j < 10; j++) { + if (!(sat = satno(SYS_QZS, 193 + j)) || alm[sat - 1].sat != sat || alm[sat - 1].toas != toas) + continue; + alm[sat - 1].week = adjgpsweek(week); + alm[sat - 1].toa = gpst2time(alm[sat - 1].week, toas); } - return 0; + return 1; + } + return 0; } /* decode GPS/QZSS almanac/health --------------------------------------------*/ -static int decode_frame_alm(const uint8_t *buff, alm_t *alm) -{ - uint32_t frm,dataid; - int ret=0; - - trace(4,"decode_frame_alm:\n"); - - for (frm=4,buff+=90;frm<=5;frm++,buff+=30) { /* subframe 4/5 */ - if (getbitu(buff,43,3)!=frm) continue; - dataid=getbitu(buff,48,2); - - if (dataid==1) { /* GPS */ - ret|=decode_alm_gps(buff,frm,alm); - } - else if (dataid==3) { /* QZSS */ - ret|=decode_alm_qzs(buff,alm); - } - } - return ret; +static int decode_frame_alm(const uint8_t *buff, alm_t *alm) { + uint32_t frm, dataid; + int ret = 0; + + trace(4, "decode_frame_alm:\n"); + + for (frm = 4, buff += 90; frm <= 5; frm++, buff += 30) { /* subframe 4/5 */ + if (getbitu(buff, 43, 3) != frm) continue; + dataid = getbitu(buff, 48, 2); + + if (dataid == 1) { /* GPS */ + ret |= decode_alm_gps(buff, frm, alm); + } else if (dataid == 3) { /* QZSS */ + ret |= decode_alm_qzs(buff, alm); } + } + return ret; +} /* decode GPS/QZSS iono parameters -------------------------------------------*/ -static int decode_frame_ion(const uint8_t *buff, double *ion) -{ - trace(4,"decode_frame_ion:\n"); - - /* subframe 4/5 and svid=56 (page18) (wide area for QZSS) */ - buff += 90; - for (unsigned frm=4;frm<=5;frm++,buff+=30) { - if (frm==5&&getbitu(buff,48,2)==1) continue; - if (getbitu(buff,43,3)!=frm||getbitu(buff,50,6)!=56) continue; - int i=56; - ion[0]=getbits(buff,i, 8)*P2_30; i+= 8; - ion[1]=getbits(buff,i, 8)*P2_27; i+= 8; - ion[2]=getbits(buff,i, 8)*P2_24; i+= 8; - ion[3]=getbits(buff,i, 8)*P2_24; i+= 8; - ion[4]=getbits(buff,i,8)*P2P11; i+=8; - ion[5]=getbits(buff,i,8)*P2P14; i+=8; - ion[6]=getbits(buff,i,8)*P2P16; i+=8; - ion[7]=getbits(buff,i,8)*P2P16; - return 1; - } - return 0; - } +static int decode_frame_ion(const uint8_t *buff, double *ion) { + trace(4, "decode_frame_ion:\n"); + + /* subframe 4/5 and svid=56 (page18) (wide area for QZSS) */ + buff += 90; + for (unsigned frm = 4; frm <= 5; frm++, buff += 30) { + if (frm == 5 && getbitu(buff, 48, 2) == 1) continue; + if (getbitu(buff, 43, 3) != frm || getbitu(buff, 50, 6) != 56) continue; + int i = 56; + ion[0] = getbits(buff, i, 8) * P2_30; + i += 8; + ion[1] = getbits(buff, i, 8) * P2_27; + i += 8; + ion[2] = getbits(buff, i, 8) * P2_24; + i += 8; + ion[3] = getbits(buff, i, 8) * P2_24; + i += 8; + ion[4] = getbits(buff, i, 8) * P2P11; + i += 8; + ion[5] = getbits(buff, i, 8) * P2P14; + i += 8; + ion[6] = getbits(buff, i, 8) * P2P16; + i += 8; + ion[7] = getbits(buff, i, 8) * P2P16; + return 1; + } + return 0; +} /* decode GPS/QZSS UTC parameters --------------------------------------------*/ -static int decode_frame_utc(const uint8_t *buff, double *utc) -{ - trace(4,"decode_frame_utc:\n"); - - /* subframe 4/5 and svid=56 (page18) */ - buff += 90; - for (unsigned frm=4;frm<=5;frm++,buff+=30) { - if (frm==5&&getbitu(buff,48,2)==1) continue; - if (getbitu(buff,43,3)!=frm||getbitu(buff,50,6)!=56) continue; - int i=120; - utc[1]=getbits(buff,i,24)*P2_50; i+=24; /* A1 (s) */ - utc[0]=getbits(buff,i,32)*P2_30; i+=32; /* A0 (s) */ - utc[2]=getbitu(buff,i, 8)*P2P12; i+= 8; /* tot (s) */ - utc[3]=getbitu(buff,i, 8); i+= 8; /* WNt */ - utc[4]=getbits(buff,i, 8); i+= 8; /* dt_LS */ - utc[5]=getbitu(buff,i, 8); i+= 8; /* WN_LSF */ - utc[6]=getbitu(buff,i, 8); i+= 8; /* DN */ - utc[7]=getbits(buff,i, 8); /* dt_LSF */ - return 1; - } - return 0; - } -/* decode GPS/QZSS navigation data --------------------------------------------- -* decode GPS/QZSS navigation data (ref [1],[4]) -* args : uint8_t *buff I GPS/QZSS navigation data (w/o parity bits) -* buff[ 0- 29]: subframe 1 (240 bits) -* buff[ 30- 59]: subframe 2 -* buff[ 60- 89]: subframe 3 -* buff[ 90-119]: subframe 4 -* buff[120-149]: subframe 5 -* int sys I SYS_GPS or SYS_QZSS -* eph_t *eph IO GPS/QZSS ephemeris (NULL: not output) -* alm_t *alm IO GPS/QZSS almanac/health (NULL: not output) -* alm[sat-1]: almanac/health (sat=sat no) -* double *ion IO GPS/QZSS iono parameters (NULL: not output) -* ion[0-3]: alpha_0,...,alpha_3 -* ion[4-7]: beta_0,...,beta_3 -* double *utc IO GPST/QZSS UTC parameters (NULL: not output) -* utc[0-3]: A0,A1,tot,WNt(8bit) -* utc[4-7]: dt_LS,WN_LSF(8bit),DN,dt_LSF -* return : status (1:ok,0:error or no data) -* notes : use CPU time to resolve modulo 1024 ambiguity of the week number -* see ref [1] -*-----------------------------------------------------------------------------*/ -extern int decode_frame(const uint8_t *buff, int sys, eph_t *eph, alm_t *alm, - double *ion, double *utc) -{ - trace(4,"decode_frame:\n"); - - if (eph&&!decode_frame_eph(buff,sys,eph)) return 0; - if (alm&&!decode_frame_alm(buff,alm)) return 0; - if (ion&&!decode_frame_ion(buff,ion)) return 0; - if (utc&&!decode_frame_utc(buff,utc)) return 0; +static int decode_frame_utc(const uint8_t *buff, double *utc) { + trace(4, "decode_frame_utc:\n"); + + /* subframe 4/5 and svid=56 (page18) */ + buff += 90; + for (unsigned frm = 4; frm <= 5; frm++, buff += 30) { + if (frm == 5 && getbitu(buff, 48, 2) == 1) continue; + if (getbitu(buff, 43, 3) != frm || getbitu(buff, 50, 6) != 56) continue; + int i = 120; + utc[1] = getbits(buff, i, 24) * P2_50; + i += 24; /* A1 (s) */ + utc[0] = getbits(buff, i, 32) * P2_30; + i += 32; /* A0 (s) */ + utc[2] = getbitu(buff, i, 8) * P2P12; + i += 8; /* tot (s) */ + utc[3] = getbitu(buff, i, 8); + i += 8; /* WNt */ + utc[4] = getbits(buff, i, 8); + i += 8; /* dt_LS */ + utc[5] = getbitu(buff, i, 8); + i += 8; /* WN_LSF */ + utc[6] = getbitu(buff, i, 8); + i += 8; /* DN */ + utc[7] = getbits(buff, i, 8); /* dt_LSF */ return 1; + } + return 0; +} +/* decode GPS/QZSS navigation data --------------------------------------------- + * decode GPS/QZSS navigation data (ref [1],[4]) + * args : uint8_t *buff I GPS/QZSS navigation data (w/o parity bits) + * buff[ 0- 29]: subframe 1 (240 bits) + * buff[ 30- 59]: subframe 2 + * buff[ 60- 89]: subframe 3 + * buff[ 90-119]: subframe 4 + * buff[120-149]: subframe 5 + * int sys I SYS_GPS or SYS_QZSS + * eph_t *eph IO GPS/QZSS ephemeris (NULL: not output) + * alm_t *alm IO GPS/QZSS almanac/health (NULL: not output) + * alm[sat-1]: almanac/health (sat=sat no) + * double *ion IO GPS/QZSS iono parameters (NULL: not output) + * ion[0-3]: alpha_0,...,alpha_3 + * ion[4-7]: beta_0,...,beta_3 + * double *utc IO GPST/QZSS UTC parameters (NULL: not output) + * utc[0-3]: A0,A1,tot,WNt(8bit) + * utc[4-7]: dt_LS,WN_LSF(8bit),DN,dt_LSF + * return : status (1:ok,0:error or no data) + * notes : use CPU time to resolve modulo 1024 ambiguity of the week number + * see ref [1] + *-----------------------------------------------------------------------------*/ +extern int decode_frame(const uint8_t *buff, int sys, eph_t *eph, alm_t *alm, double *ion, + double *utc) { + trace(4, "decode_frame:\n"); + + if (eph && !decode_frame_eph(buff, sys, eph)) return 0; + if (alm && !decode_frame_alm(buff, alm)) return 0; + if (ion && !decode_frame_ion(buff, ion)) return 0; + if (utc && !decode_frame_utc(buff, utc)) return 0; + return 1; } /* initialize receiver raw data control ---------------------------------------- -* initialize receiver raw data control struct and reallocate observation and -* epheris buffer -* args : raw_t *raw IO receiver raw data control struct -* int format I stream format (STRFMT_???) -* return : status (1:ok,0:memory allocation error) -*-----------------------------------------------------------------------------*/ -extern int init_raw(raw_t *raw, int format) -{ - gtime_t time0={0}; - obsd_t data0={{0}}; - eph_t eph0 ={0,-1,-1}; - alm_t alm0 ={0,-1}; - seph_t seph0={0}; - sbsmsg_t sbsmsg0={0}; - int i,j,ret=1; - - trace(3,"init_raw: format=%d\n",format); - - raw->time=time0; - raw->ephset=raw->ephsat=0; - raw->sbsmsg=sbsmsg0; - raw->msgtype[0]='\0'; - for (i=0;isubfrm[i][j]=0; - for (j=0;jtobs [i][j]=time0; - raw->lockt[i][j]=0.0; - raw->halfc[i][j]=0; - raw->lockflag[i][j]=0; - } - raw->icpp[i]=raw->off[i]=raw->prCA[i]=raw->dpCA[i]=0.0; - } - for (i=0;ifreqn[i]=0; - raw->icpc=0.0; - raw->nbyte=raw->len=0; - raw->iod=raw->flag=raw->tbase=raw->outtype=0; - raw->tod=-1; - for (i=0;ibuff[i]=0; - raw->opt[0]='\0'; - raw->format=-1; - raw->rcvtype=0; - - raw->obs.data =NULL; - raw->obuf.data=NULL; - raw->nav.eph =NULL; - raw->nav.alm =NULL; - raw->nav.geph =NULL; - raw->nav.seph =NULL; - raw->rcv_data =NULL; - - if (!(raw->obs.data =(obsd_t *)malloc(sizeof(obsd_t)*MAXOBS))|| - !(raw->obuf.data=(obsd_t *)malloc(sizeof(obsd_t)*MAXOBS))|| - !(raw->nav.eph =(eph_t *)malloc(sizeof(eph_t )*MAXSAT*2))|| - !(raw->nav.alm =(alm_t *)malloc(sizeof(alm_t )*MAXSAT))|| - !(raw->nav.seph =(seph_t *)malloc(sizeof(seph_t)*NSATSBS*2))) { - free_raw(raw); - return 0; - } - raw->obs.n =0; - raw->obuf.n=0; - raw->nav.n =raw->nav.nmax =MAXSAT*2; - raw->nav.na=raw->nav.namax=MAXSAT; - raw->nav.ns=raw->nav.nsmax=NSATSBS*2; - for (i=0;iobs.data [i]=data0; - for (i=0;iobuf.data[i]=data0; - for (i=0;inav.eph [i]=eph0; - for (i=0;inav.alm [i]=alm0; - for (i=0;inav.seph [i]=seph0; - raw->sta.name[0]=raw->sta.markerno[0]=raw->sta.markertype[0]='\0'; - raw->sta.observer[0]=raw->sta.agency[0]='\0'; - raw->sta.antdes[0]=raw->sta.antsno[0]='\0'; - raw->sta.rectype[0]=raw->sta.recver[0]=raw->sta.recsno[0]='\0'; - raw->sta.antsetup=raw->sta.itrf=raw->sta.deltype=0; - for (i=0;i<3;i++) { - raw->sta.pos[i]=raw->sta.del[i]=0.0; - } - raw->sta.hgt=0.0; - - if (MAXPRNGLO > 0) { - raw->nav.geph = (geph_t *)malloc(sizeof(geph_t) * MAXPRNGLO); - if (raw->nav.geph == NULL) { - free_raw(raw); - return 0; - } - geph_t geph0 = {0, -1}; - for (int i = 0; i < MAXPRNGLO; i++) raw->nav.geph[i] = geph0; - } - raw->nav.ng = raw->nav.ngmax = MAXPRNGLO; + * initialize receiver raw data control struct and reallocate observation and + * epheris buffer + * args : raw_t *raw IO receiver raw data control struct + * int format I stream format (STRFMT_???) + * return : status (1:ok,0:memory allocation error) + *-----------------------------------------------------------------------------*/ +extern int init_raw(raw_t *raw, int format) { + gtime_t time0 = {0}; + obsd_t data0 = {{0}}; + eph_t eph0 = {0, -1, -1}; + alm_t alm0 = {0, -1}; + seph_t seph0 = {0}; + sbsmsg_t sbsmsg0 = {0}; + int i, j, ret = 1; + + trace(3, "init_raw: format=%d\n", format); - /* initialize receiver dependent data */ - raw->format=format; - switch (format) { - case STRFMT_RT17: ret=init_rt17(raw); break; - case STRFMT_SEPT: ret=init_sbf(raw); break; + raw->time = time0; + raw->ephset = raw->ephsat = 0; + raw->sbsmsg = sbsmsg0; + raw->msgtype[0] = '\0'; + for (i = 0; i < MAXSAT; i++) { + for (j = 0; j < 380; j++) raw->subfrm[i][j] = 0; + for (j = 0; j < NFREQ + NEXOBS; j++) { + raw->tobs[i][j] = time0; + raw->lockt[i][j] = 0.0; + raw->halfc[i][j] = 0; + raw->lockflag[i][j] = 0; } - if (!ret) { - free_raw(raw); - return 0; + raw->icpp[i] = raw->off[i] = raw->prCA[i] = raw->dpCA[i] = 0.0; + } + for (i = 0; i < MAXOBS; i++) raw->freqn[i] = 0; + raw->icpc = 0.0; + raw->nbyte = raw->len = 0; + raw->iod = raw->flag = raw->tbase = raw->outtype = 0; + raw->tod = -1; + for (i = 0; i < MAXRAWLEN; i++) raw->buff[i] = 0; + raw->opt[0] = '\0'; + raw->format = -1; + raw->rcvtype = 0; + + raw->obs.data = NULL; + raw->obuf.data = NULL; + raw->nav.eph = NULL; + raw->nav.alm = NULL; + raw->nav.geph = NULL; + raw->nav.seph = NULL; + raw->rcv_data = NULL; + + if (!(raw->obs.data = (obsd_t *)malloc(sizeof(obsd_t) * MAXOBS)) || + !(raw->obuf.data = (obsd_t *)malloc(sizeof(obsd_t) * MAXOBS)) || + !(raw->nav.eph = (eph_t *)malloc(sizeof(eph_t) * MAXSAT * 2)) || + !(raw->nav.alm = (alm_t *)malloc(sizeof(alm_t) * MAXSAT)) || + !(raw->nav.seph = (seph_t *)malloc(sizeof(seph_t) * NSATSBS * 2))) { + free_raw(raw); + return 0; + } + raw->obs.n = 0; + raw->obuf.n = 0; + raw->nav.n = raw->nav.nmax = MAXSAT * 2; + raw->nav.na = raw->nav.namax = MAXSAT; + raw->nav.ns = raw->nav.nsmax = NSATSBS * 2; + for (i = 0; i < MAXOBS; i++) raw->obs.data[i] = data0; + for (i = 0; i < MAXOBS; i++) raw->obuf.data[i] = data0; + for (i = 0; i < MAXSAT * 2; i++) raw->nav.eph[i] = eph0; + for (i = 0; i < MAXSAT; i++) raw->nav.alm[i] = alm0; + for (i = 0; i < NSATSBS * 2; i++) raw->nav.seph[i] = seph0; + raw->sta.name[0] = raw->sta.markerno[0] = raw->sta.markertype[0] = '\0'; + raw->sta.observer[0] = raw->sta.agency[0] = '\0'; + raw->sta.antdes[0] = raw->sta.antsno[0] = '\0'; + raw->sta.rectype[0] = raw->sta.recver[0] = raw->sta.recsno[0] = '\0'; + raw->sta.antsetup = raw->sta.itrf = raw->sta.deltype = 0; + for (i = 0; i < 3; i++) { + raw->sta.pos[i] = raw->sta.del[i] = 0.0; + } + raw->sta.hgt = 0.0; + + if (MAXPRNGLO > 0) { + raw->nav.geph = (geph_t *)malloc(sizeof(geph_t) * MAXPRNGLO); + if (raw->nav.geph == NULL) { + free_raw(raw); + return 0; } - return 1; + geph_t geph0 = {0, -1}; + for (int i = 0; i < MAXPRNGLO; i++) raw->nav.geph[i] = geph0; + } + raw->nav.ng = raw->nav.ngmax = MAXPRNGLO; + + /* initialize receiver dependent data */ + raw->format = format; + switch (format) { + case STRFMT_RT17: + ret = init_rt17(raw); + break; + case STRFMT_SEPT: + ret = init_sbf(raw); + break; + } + if (!ret) { + free_raw(raw); + return 0; + } + return 1; } /* free receiver raw data control ---------------------------------------------- -* free observation and ephemeris buffer in receiver raw data control struct -* args : raw_t *raw IO receiver raw data control struct -* return : none -*-----------------------------------------------------------------------------*/ -extern void free_raw(raw_t *raw) -{ - trace(3,"free_raw:\n"); - - free(raw->obs.data ); raw->obs.data =NULL; raw->obs.n =0; - free(raw->obuf.data); raw->obuf.data=NULL; raw->obuf.n=0; - free(raw->nav.eph ); raw->nav.eph =NULL; raw->nav.n =raw->nav.nmax =0; - free(raw->nav.alm ); raw->nav.alm =NULL; raw->nav.na=raw->nav.namax=0; - free(raw->nav.geph ); raw->nav.geph =NULL; raw->nav.ng=raw->nav.ngmax=0; - free(raw->nav.seph ); raw->nav.seph =NULL; raw->nav.ns=raw->nav.nsmax=0; - - /* free receiver dependent data */ - switch (raw->format) { - case STRFMT_RT17: free_rt17(raw); break; - case STRFMT_SEPT: free_sbf(raw); break; - } - raw->rcv_data=NULL; + * free observation and ephemeris buffer in receiver raw data control struct + * args : raw_t *raw IO receiver raw data control struct + * return : none + *-----------------------------------------------------------------------------*/ +extern void free_raw(raw_t *raw) { + trace(3, "free_raw:\n"); + + free(raw->obs.data); + raw->obs.data = NULL; + raw->obs.n = 0; + free(raw->obuf.data); + raw->obuf.data = NULL; + raw->obuf.n = 0; + free(raw->nav.eph); + raw->nav.eph = NULL; + raw->nav.n = raw->nav.nmax = 0; + free(raw->nav.alm); + raw->nav.alm = NULL; + raw->nav.na = raw->nav.namax = 0; + free(raw->nav.geph); + raw->nav.geph = NULL; + raw->nav.ng = raw->nav.ngmax = 0; + free(raw->nav.seph); + raw->nav.seph = NULL; + raw->nav.ns = raw->nav.nsmax = 0; + + /* free receiver dependent data */ + switch (raw->format) { + case STRFMT_RT17: + free_rt17(raw); + break; + case STRFMT_SEPT: + free_sbf(raw); + break; + } + raw->rcv_data = NULL; } /* input receiver raw data from stream ----------------------------------------- -* fetch next receiver raw data and input a message from stream -* args : raw_t *raw IO receiver raw data control struct -* int format I receiver raw data format (STRFMT_???) -* uint8_t data I stream data (1 byte) -* return : status (-1: error message, 0: no message, 1: input observation data, -* 2: input ephemeris, 3: input sbas message, -* 9: input ion/utc parameter) -*-----------------------------------------------------------------------------*/ -extern int input_raw(raw_t *raw, int format, uint8_t data) -{ - trace(5,"input_raw: format=%d data=0x%02x\n",format,data); - - switch (format) { - case STRFMT_OEM4 : return input_oem4 (raw,data); - /* case STRFMT_CNAV : return input_cnav (raw,data); */ - case STRFMT_UBX : return input_ubx (raw,data); - case STRFMT_SBP : return input_sbp (raw,data); - case STRFMT_CRES : return input_cres (raw,data); - case STRFMT_STQ : return input_stq (raw,data); - case STRFMT_JAVAD: return input_javad(raw,data); - case STRFMT_NVS : return input_nvs (raw,data); - case STRFMT_BINEX: return input_bnx (raw,data); - case STRFMT_RT17 : return input_rt17 (raw,data); - case STRFMT_SEPT : return input_sbf (raw,data); - /*case STRFMT_TERSUS: return input_tersus(raw,data);*/ - case STRFMT_UNICORE : return input_unicore (raw,data); - } - return 0; + * fetch next receiver raw data and input a message from stream + * args : raw_t *raw IO receiver raw data control struct + * int format I receiver raw data format (STRFMT_???) + * uint8_t data I stream data (1 byte) + * return : status (-1: error message, 0: no message, 1: input observation data, + * 2: input ephemeris, 3: input sbas message, + * 9: input ion/utc parameter) + *-----------------------------------------------------------------------------*/ +extern int input_raw(raw_t *raw, int format, uint8_t data) { + trace(5, "input_raw: format=%d data=0x%02x\n", format, data); + + switch (format) { + case STRFMT_OEM4: + return input_oem4(raw, data); + /* case STRFMT_CNAV : return input_cnav (raw,data); */ + case STRFMT_UBX: + return input_ubx(raw, data); + case STRFMT_SBP: + return input_sbp(raw, data); + case STRFMT_CRES: + return input_cres(raw, data); + case STRFMT_STQ: + return input_stq(raw, data); + case STRFMT_JAVAD: + return input_javad(raw, data); + case STRFMT_NVS: + return input_nvs(raw, data); + case STRFMT_BINEX: + return input_bnx(raw, data); + case STRFMT_RT17: + return input_rt17(raw, data); + case STRFMT_SEPT: + return input_sbf(raw, data); + /*case STRFMT_TERSUS: return input_tersus(raw,data);*/ + case STRFMT_UNICORE: + return input_unicore(raw, data); + } + return 0; } /* input receiver raw data from file ------------------------------------------- -* fetch next receiver raw data and input a message from file -* args : raw_t *raw IO receiver raw data control struct -* int format I receiver raw data format (STRFMT_???) -* FILE *fp I file pointer -* return : status(-2: end of file/format error, -1...31: same as above) -*-----------------------------------------------------------------------------*/ -extern int input_rawf(raw_t *raw, int format, FILE *fp) -{ - trace(4,"input_rawf: format=%d\n",format); - - switch (format) { - case STRFMT_OEM4 : return input_oem4f (raw,fp); - /* case STRFMT_CNAV : return input_cnavf (raw,fp); */ - case STRFMT_UBX : return input_ubxf (raw,fp); - case STRFMT_SBP : return input_sbpf (raw,fp); - case STRFMT_CRES : return input_cresf (raw,fp); - case STRFMT_STQ : return input_stqf (raw,fp); - case STRFMT_JAVAD: return input_javadf(raw,fp); - case STRFMT_NVS : return input_nvsf (raw,fp); - case STRFMT_BINEX: return input_bnxf (raw,fp); - case STRFMT_RT17 : return input_rt17f (raw,fp); - case STRFMT_SEPT : return input_sbff (raw,fp); - /*case STRFMT_TERSUS: return input_tersusf(raw,fp); */ - case STRFMT_UNICORE : return input_unicoref (raw,fp); - } - return -2; + * fetch next receiver raw data and input a message from file + * args : raw_t *raw IO receiver raw data control struct + * int format I receiver raw data format (STRFMT_???) + * FILE *fp I file pointer + * return : status(-2: end of file/format error, -1...31: same as above) + *-----------------------------------------------------------------------------*/ +extern int input_rawf(raw_t *raw, int format, FILE *fp) { + trace(4, "input_rawf: format=%d\n", format); + + switch (format) { + case STRFMT_OEM4: + return input_oem4f(raw, fp); + /* case STRFMT_CNAV : return input_cnavf (raw,fp); */ + case STRFMT_UBX: + return input_ubxf(raw, fp); + case STRFMT_SBP: + return input_sbpf(raw, fp); + case STRFMT_CRES: + return input_cresf(raw, fp); + case STRFMT_STQ: + return input_stqf(raw, fp); + case STRFMT_JAVAD: + return input_javadf(raw, fp); + case STRFMT_NVS: + return input_nvsf(raw, fp); + case STRFMT_BINEX: + return input_bnxf(raw, fp); + case STRFMT_RT17: + return input_rt17f(raw, fp); + case STRFMT_SEPT: + return input_sbff(raw, fp); + /*case STRFMT_TERSUS: return input_tersusf(raw,fp); */ + case STRFMT_UNICORE: + return input_unicoref(raw, fp); + } + return -2; } diff --git a/src/rinex.c b/src/rinex.c index 1bcd288b0..352f35914 100644 --- a/src/rinex.c +++ b/src/rinex.c @@ -1,2176 +1,2284 @@ /*------------------------------------------------------------------------------ -* rinex.c : RINEX functions -* -* Copyright (C) 2007-2020 by T.TAKASU, All rights reserved. -* -* reference : -* [1] W.Gurtner and L.Estey, RINEX The Receiver Independent Exchange Format -* Version 2.11, December 10, 2007 -* [2] W.Gurtner and L.Estey, RINEX The Receiver Independent Exchange Format -* Version 3.00, November 28, 2007 -* [3] IS-GPS-200D, Navstar GPS Space Segment/Navigation User Interfaces, -* 7 March, 2006 -* [4] W.Gurtner and L.Estey, RINEX The Receiver Independent Exchange Format -* Version 2.12, June 23, 2009 -* [5] W.Gurtner and L.Estey, RINEX The Receiver Independent Exchange Format -* Version 3.01, June 22, 2009 -* [6] J.Ray and W.Gurtner, RINEX extensions to handle clock information -* version 3.02, September 2, 2010 -* [7] RINEX The Receiver Independent Exchange Format Version 3.02, -* International GNSS Service (IGS), RINEX Working Group and Radio -* Technical Commission for Maritime Services Special Committee 104 -* (RTCM-SC104), December 10, 2012 -* [8] RINEX The Receiver Independent Exchange Format Version 3.03, -* International GNSS Service (IGS), RINEX Working Group and Radio -* Technical Commission for Maritime Services Special Committee 104 -* (RTCM-SC104), July 14, 2015 -* [9] RINEX The Receiver Independent Exchange Format Version 3.04, -* International GNSS Service (IGS), RINEX Working Group and Radio -* Technical Commission for Maritime Services Special Committee 104 -* (RTCM-SC104), November 23, 2018 -* -* version : $Revision:$ -* history : 2006/01/16 1.0 new -* 2007/03/14 1.1 read P1 if no obstype of C1 -* 2007/04/27 1.2 add readrnxt() function -* 2007/05/25 1.3 add support of file path with wild-card (*) -* add support of compressed files -* 2007/11/02 1.4 support sbas/geo satellite -* support doppler observables -* support rinex bug of week handover -* add rinex obs/nav output functions -* 2008/06/16 1.5 export readrnxf(), add compress() -* separate sortobs(), uniqeph(), screent() -* 2008/10/28 1.6 fix bug on reading rinex obs header types of observ -* 2009/04/09 1.7 support rinex 2.11 -* change api of outrnxobsh(),outrnxobsb(),outrnxnavb() -* 2009/06/02 1.8 add api outrnxgnavb() -* 2009/08/15 1.9 support glonass -* add slip save/restore functions -* 2010/03/03 1.10 fix bug of array access by disabled satellite -* 2010/07/21 1.11 support rinex ver.2.12, 3.00 -* support rinex extension for qzss -* support geo navigation messages -* added api: -* setrnxcodepri(),outrnxhnavh(),outrnxhnavb(), -* changed api: -* readrnx(),readrnxt(),outrnxnavh(),outrnxgnavh() -* 2010/05/29 1.12 fix bug on skipping invalid satellite data -* fix bug on frequency number overflow -* output P1 instead of C1 if rnxopt.rcvopt=-L1P -* output C2 instead of P2 if rnxopt.rcvopt=-L2C -* change api: -* outrnxgnavh(),outrnxhnavh(),readrnx(), -* readrnxt() -* add api: -* outrnxlnavh(), outrnxqnav() -* move uniqeph(),uniqgeph,uniqseph() -* 2010/08/19 1.13 suppress warning -* 2012/03/01 1.14 add function to read cnes widelane fcb in rnxclk -* support compass rinex nav -* change api: setcodepri() -* 2012/10/17 1.15 support ver.2.12, ver.3.01 -* add api init_rnxctr(),free_rnxctr(),open_rnxctr(), -* input_rnxctr() -* change api readrnxt(),readrnx() -* delete api setrnxcodepri() -* fix bug on message frame time in v.3 glonass nav -* 2013/02/09 1.16 add reading geph.iode derived from toe -* 2013/02/23 1.17 support rinex 3.02 (ref [7]) -* change api outrnxobsh() -* add api outrnxcnavh() -* fix bug on output of fit interval -* 2013/05/08 1.18 fix bug on reading glo and geo nav in rinex 3 -* 2013/09/01 1.19 fix bug on reading galileo "C1" in rinex 2.12 -* 2013/12/16 1.20 reject C1 for 2.12 -* 2014/05/26 1.21 fix bug on reading gps "C2" in rinex 2.11 or 2.12 -* fix problem on type incompatibility -* support beidou -* 2014/08/29 1.22 fix bug on reading gps "C2" in rinex 2.11 or 2.12 -* 2014/10/20 1.23 recognize "C2" in 2.12 as "C2W" instead of "C2D" -* 2014/12/07 1.24 add read rinex option -SYS=... -* 2016/07/01 1.25 support RINEX 3.03 -* support IRNSS -* 2016/09/17 1.26 fix bug on fit interval in QZSS RINEX nav -* URA output value compliant to RINEX 3.03 -* 2016/10/10 1.27 add api outrnxinavh() -* 2018/10/10 1.28 support galileo sisa value for rinex nav output -* fix bug on handling beidou B1 code in rinex 3.03 -* 2019/08/19 1.29 support galileo sisa index for rinex nav input -* 2020/11/30 1.30 support RINEX 3.04 (ref [9]) -* support phase shift in RINEX options rnxopt_t -* support high-resolution (16bit) C/N0 in obsd_t -* support dual sets of ephemerides in RINEX control -* (for Galileo I/NAV and F/NAV) -* no support RINEX 2 NAV extensions (QZS and BDS) -* no support CNES/GRG clock extension in comments -* fix bug on segfault to read NavIC/IRNSS OBS data -* fix bug on segfault with # obs data >= MAXOBS -* fix bug on reading/writing GLONASS slot/frq # lines -* fix bug on reading SBAS UTC parameters in RINEX nav -* fix bug on saving slip info in extended OBS slots -* add iono/utc param. in separated output RINEX NAV -* zero-padded satellite number (e.g. "G 1" -> "G01") -* zero-padded month/date/hour/min/sec -* use exponent letter D instead of E for RINEX NAV -* use API code2idx() to get frequency index -* use integer types in stdint.h -* suppress warnings -*-----------------------------------------------------------------------------*/ + * rinex.c : RINEX functions + * + * Copyright (C) 2007-2020 by T.TAKASU, All rights reserved. + * + * reference : + * [1] W.Gurtner and L.Estey, RINEX The Receiver Independent Exchange Format + * Version 2.11, December 10, 2007 + * [2] W.Gurtner and L.Estey, RINEX The Receiver Independent Exchange Format + * Version 3.00, November 28, 2007 + * [3] IS-GPS-200D, Navstar GPS Space Segment/Navigation User Interfaces, + * 7 March, 2006 + * [4] W.Gurtner and L.Estey, RINEX The Receiver Independent Exchange Format + * Version 2.12, June 23, 2009 + * [5] W.Gurtner and L.Estey, RINEX The Receiver Independent Exchange Format + * Version 3.01, June 22, 2009 + * [6] J.Ray and W.Gurtner, RINEX extensions to handle clock information + * version 3.02, September 2, 2010 + * [7] RINEX The Receiver Independent Exchange Format Version 3.02, + * International GNSS Service (IGS), RINEX Working Group and Radio + * Technical Commission for Maritime Services Special Committee 104 + * (RTCM-SC104), December 10, 2012 + * [8] RINEX The Receiver Independent Exchange Format Version 3.03, + * International GNSS Service (IGS), RINEX Working Group and Radio + * Technical Commission for Maritime Services Special Committee 104 + * (RTCM-SC104), July 14, 2015 + * [9] RINEX The Receiver Independent Exchange Format Version 3.04, + * International GNSS Service (IGS), RINEX Working Group and Radio + * Technical Commission for Maritime Services Special Committee 104 + * (RTCM-SC104), November 23, 2018 + * + * version : $Revision:$ + * history : 2006/01/16 1.0 new + * 2007/03/14 1.1 read P1 if no obstype of C1 + * 2007/04/27 1.2 add readrnxt() function + * 2007/05/25 1.3 add support of file path with wild-card (*) + * add support of compressed files + * 2007/11/02 1.4 support sbas/geo satellite + * support doppler observables + * support rinex bug of week handover + * add rinex obs/nav output functions + * 2008/06/16 1.5 export readrnxf(), add compress() + * separate sortobs(), uniqeph(), screent() + * 2008/10/28 1.6 fix bug on reading rinex obs header types of observ + * 2009/04/09 1.7 support rinex 2.11 + * change api of outrnxobsh(),outrnxobsb(),outrnxnavb() + * 2009/06/02 1.8 add api outrnxgnavb() + * 2009/08/15 1.9 support glonass + * add slip save/restore functions + * 2010/03/03 1.10 fix bug of array access by disabled satellite + * 2010/07/21 1.11 support rinex ver.2.12, 3.00 + * support rinex extension for qzss + * support geo navigation messages + * added api: + * setrnxcodepri(),outrnxhnavh(),outrnxhnavb(), + * changed api: + * readrnx(),readrnxt(),outrnxnavh(),outrnxgnavh() + * 2010/05/29 1.12 fix bug on skipping invalid satellite data + * fix bug on frequency number overflow + * output P1 instead of C1 if rnxopt.rcvopt=-L1P + * output C2 instead of P2 if rnxopt.rcvopt=-L2C + * change api: + * outrnxgnavh(),outrnxhnavh(),readrnx(), + * readrnxt() + * add api: + * outrnxlnavh(), outrnxqnav() + * move uniqeph(),uniqgeph,uniqseph() + * 2010/08/19 1.13 suppress warning + * 2012/03/01 1.14 add function to read cnes widelane fcb in rnxclk + * support compass rinex nav + * change api: setcodepri() + * 2012/10/17 1.15 support ver.2.12, ver.3.01 + * add api init_rnxctr(),free_rnxctr(),open_rnxctr(), + * input_rnxctr() + * change api readrnxt(),readrnx() + * delete api setrnxcodepri() + * fix bug on message frame time in v.3 glonass nav + * 2013/02/09 1.16 add reading geph.iode derived from toe + * 2013/02/23 1.17 support rinex 3.02 (ref [7]) + * change api outrnxobsh() + * add api outrnxcnavh() + * fix bug on output of fit interval + * 2013/05/08 1.18 fix bug on reading glo and geo nav in rinex 3 + * 2013/09/01 1.19 fix bug on reading galileo "C1" in rinex 2.12 + * 2013/12/16 1.20 reject C1 for 2.12 + * 2014/05/26 1.21 fix bug on reading gps "C2" in rinex 2.11 or 2.12 + * fix problem on type incompatibility + * support beidou + * 2014/08/29 1.22 fix bug on reading gps "C2" in rinex 2.11 or 2.12 + * 2014/10/20 1.23 recognize "C2" in 2.12 as "C2W" instead of "C2D" + * 2014/12/07 1.24 add read rinex option -SYS=... + * 2016/07/01 1.25 support RINEX 3.03 + * support IRNSS + * 2016/09/17 1.26 fix bug on fit interval in QZSS RINEX nav + * URA output value compliant to RINEX 3.03 + * 2016/10/10 1.27 add api outrnxinavh() + * 2018/10/10 1.28 support galileo sisa value for rinex nav output + * fix bug on handling beidou B1 code in rinex 3.03 + * 2019/08/19 1.29 support galileo sisa index for rinex nav input + * 2020/11/30 1.30 support RINEX 3.04 (ref [9]) + * support phase shift in RINEX options rnxopt_t + * support high-resolution (16bit) C/N0 in obsd_t + * support dual sets of ephemerides in RINEX control + * (for Galileo I/NAV and F/NAV) + * no support RINEX 2 NAV extensions (QZS and BDS) + * no support CNES/GRG clock extension in comments + * fix bug on segfault to read NavIC/IRNSS OBS data + * fix bug on segfault with # obs data >= MAXOBS + * fix bug on reading/writing GLONASS slot/frq # lines + * fix bug on reading SBAS UTC parameters in RINEX nav + * fix bug on saving slip info in extended OBS slots + * add iono/utc param. in separated output RINEX NAV + * zero-padded satellite number (e.g. "G 1" -> "G01") + * zero-padded month/date/hour/min/sec + * use exponent letter D instead of E for RINEX NAV + * use API code2idx() to get frequency index + * use integer types in stdint.h + * suppress warnings + *-----------------------------------------------------------------------------*/ #include "rtklib.h" /* constants/macros ----------------------------------------------------------*/ -#define SQR(x) ((x)*(x)) +#define SQR(x) ((x) * (x)) -#define NAVEXP "D" /* exponent letter in RINEX NAV */ -#define MAXRNXLEN (16*MAXOBSTYPE+4) /* max RINEX record length */ -#define MAXPOSHEAD 1024 /* max head line position */ +#define NAVEXP "D" /* exponent letter in RINEX NAV */ +#define MAXRNXLEN (16 * MAXOBSTYPE + 4) /* max RINEX record length */ +#define MAXPOSHEAD 1024 /* max head line position */ #define MINFREQ_GLO -7 /* min frequency number GLONASS */ #define MAXFREQ_GLO 13 /* max frequency number GLONASS */ -#define NINCOBS 262144 /* incremental number of obs data */ +#define NINCOBS 262144 /* incremental number of obs data */ -static const int navsys[RNX_NUMSYS]={ /* satellite systems */ - SYS_GPS,SYS_GLO,SYS_GAL,SYS_QZS,SYS_SBS,SYS_CMP,SYS_IRN -}; +static const int navsys[RNX_NUMSYS] = {/* satellite systems */ + SYS_GPS, SYS_GLO, SYS_GAL, SYS_QZS, + SYS_SBS, SYS_CMP, SYS_IRN}; /* Satellite system codes, nul terminated. RNX_SYS_ */ -static const char syscodes[RNX_NUMSYS+1]="GREJSCI"; - -static const char obscodes[]="CLDS"; /* observation type codes */ - -static const double ura_eph[]={ /* RAa values (ref [3] 20.3.3.3.1.1) */ - 2.4,3.4,4.85,6.85,9.65,13.65,24.0,48.0,96.0,192.0,384.0,768.0,1536.0, - 3072.0,6144.0,0.0 -}; -static const double ura_nominal[]={ /* URA nominal values */ - 2.0,2.8,4.0,5.7,8.0,11.3,16.0,32.0,64.0,128.0,256.0,512.0,1024.0, - 2048.0,4096.0,8192.0 -}; +static const char syscodes[RNX_NUMSYS + 1] = "GREJSCI"; + +static const char obscodes[] = "CLDS"; /* observation type codes */ + +static const double ura_eph[] = {/* RAa values (ref [3] 20.3.3.3.1.1) */ + 2.4, 3.4, 4.85, 6.85, 9.65, 13.65, 24.0, 48.0, + 96.0, 192.0, 384.0, 768.0, 1536.0, 3072.0, 6144.0, 0.0}; +static const double ura_nominal[] = {/* URA nominal values */ + 2.0, 2.8, 4.0, 5.7, 8.0, 11.3, 16.0, 32.0, + 64.0, 128.0, 256.0, 512.0, 1024.0, 2048.0, 4096.0, 8192.0}; /* type definition -----------------------------------------------------------*/ -typedef struct { /* signal index type */ - int n; /* number of index */ - int idx[MAXOBSTYPE]; /* signal freq-index */ - int pos[MAXOBSTYPE]; /* signal index in obs data (-1:no) */ - uint8_t pri [MAXOBSTYPE]; /* signal priority (15-0) */ - uint8_t type[MAXOBSTYPE]; /* type (0:C,1:L,2:D,3:S) */ - uint8_t code[MAXOBSTYPE]; /* obs-code (CODE_L??) */ - double shift[MAXOBSTYPE]; /* phase shift (cycle) */ +typedef struct { /* signal index type */ + int n; /* number of index */ + int idx[MAXOBSTYPE]; /* signal freq-index */ + int pos[MAXOBSTYPE]; /* signal index in obs data (-1:no) */ + uint8_t pri[MAXOBSTYPE]; /* signal priority (15-0) */ + uint8_t type[MAXOBSTYPE]; /* type (0:C,1:L,2:D,3:S) */ + uint8_t code[MAXOBSTYPE]; /* obs-code (CODE_L??) */ + double shift[MAXOBSTYPE]; /* phase shift (cycle) */ } sigind_t; /* adjust time considering week handover -------------------------------------*/ -static gtime_t adjweek(gtime_t t, gtime_t t0) -{ - double tt=timediff(t,t0); - if (tt<-302400.0) return timeadd(t, 604800.0); - if (tt> 302400.0) return timeadd(t,-604800.0); - return t; +static gtime_t adjweek(gtime_t t, gtime_t t0) { + double tt = timediff(t, t0); + if (tt < -302400.0) return timeadd(t, 604800.0); + if (tt > 302400.0) return timeadd(t, -604800.0); + return t; } /* adjust time considering week handover -------------------------------------*/ -static gtime_t adjday(gtime_t t, gtime_t t0) -{ - double tt=timediff(t,t0); - if (tt<-43200.0) return timeadd(t, 86400.0); - if (tt> 43200.0) return timeadd(t,-86400.0); - return t; +static gtime_t adjday(gtime_t t, gtime_t t0) { + double tt = timediff(t, t0); + if (tt < -43200.0) return timeadd(t, 86400.0); + if (tt > 43200.0) return timeadd(t, -86400.0); + return t; } /* time string for ver.3 (yyyymmdd hhmmss UTC) -------------------------------*/ -static void timestr_rnx(char str[32]) -{ - gtime_t time; - double ep[6]; - time=timeget(); - time.sec=0.0; - time2epoch(time,ep); - snprintf(str,32,"%04.0f%02.0f%02.0f %02.0f%02.0f%02.0f UTC",ep[0],ep[1],ep[2], - ep[3],ep[4],ep[5]); +static void timestr_rnx(char str[32]) { + gtime_t time; + double ep[6]; + time = timeget(); + time.sec = 0.0; + time2epoch(time, ep); + snprintf(str, 32, "%04.0f%02.0f%02.0f %02.0f%02.0f%02.0f UTC", ep[0], ep[1], ep[2], ep[3], ep[4], + ep[5]); } /* satellite to satellite code -----------------------------------------------*/ -static int sat2code(int sat, char *code) -{ - int prn; - switch (satsys(sat,&prn)) { - case SYS_GPS: sprintf(code,"G%02d",prn-MINPRNGPS+1); break; - case SYS_GLO: sprintf(code,"R%02d",prn-MINPRNGLO+1); break; - case SYS_GAL: sprintf(code,"E%02d",prn-MINPRNGAL+1); break; - case SYS_SBS: sprintf(code,"S%02d",prn-100); break; - case SYS_QZS: sprintf(code,"J%02d",prn-MINPRNQZS+1); break; - case SYS_CMP: sprintf(code,"C%02d",prn-MINPRNCMP+1); break; - case SYS_IRN: sprintf(code,"I%02d",prn-MINPRNIRN+1); break; - default: return 0; - } - return 1; +static int sat2code(int sat, char *code) { + int prn; + switch (satsys(sat, &prn)) { + case SYS_GPS: + sprintf(code, "G%02d", prn - MINPRNGPS + 1); + break; + case SYS_GLO: + sprintf(code, "R%02d", prn - MINPRNGLO + 1); + break; + case SYS_GAL: + sprintf(code, "E%02d", prn - MINPRNGAL + 1); + break; + case SYS_SBS: + sprintf(code, "S%02d", prn - 100); + break; + case SYS_QZS: + sprintf(code, "J%02d", prn - MINPRNQZS + 1); + break; + case SYS_CMP: + sprintf(code, "C%02d", prn - MINPRNCMP + 1); + break; + case SYS_IRN: + sprintf(code, "I%02d", prn - MINPRNIRN + 1); + break; + default: + return 0; + } + return 1; } /* URA index to URA nominal value (m) ----------------------------------------*/ -static double uravalue(int sva) -{ - return 0<=sva&&sva<15?ura_nominal[sva]:8192.0; -} +static double uravalue(int sva) { return 0 <= sva && sva < 15 ? ura_nominal[sva] : 8192.0; } /* URA value (m) to URA index ------------------------------------------------*/ -static int uraindex(double value) -{ - int i; - for (i=0;i<15;i++) if (ura_eph[i]>=value) break; - return i; +static int uraindex(double value) { + int i; + for (i = 0; i < 15; i++) + if (ura_eph[i] >= value) break; + return i; } /* Galileo SISA index to SISA nominal value (m) ------------------------------*/ -static double sisa_value(int sisa) -{ - if (sisa< 0) return -1.0; - if (sisa<= 49) return sisa*0.01; - if (sisa<= 74) return 0.5+(sisa- 50)*0.02; - if (sisa<= 99) return 1.0+(sisa- 75)*0.04; - if (sisa<=125) return 2.0+(sisa-100)*0.16; - return -1.0; /* unknown or NAPA */ +static double sisa_value(int sisa) { + if (sisa < 0) return -1.0; + if (sisa <= 49) return sisa * 0.01; + if (sisa <= 74) return 0.5 + (sisa - 50) * 0.02; + if (sisa <= 99) return 1.0 + (sisa - 75) * 0.04; + if (sisa <= 125) return 2.0 + (sisa - 100) * 0.16; + return -1.0; /* unknown or NAPA */ } /* Galileo SISA value (m) to SISA index --------------------------------------*/ -static int sisa_index(double value) -{ - /* - * kudos to https://core.ac.uk/download/pdf/328854682.pdf for this ... - * Signal-in-Space Accuracy : SISA flag is a prediction at 1-sigma standard deviation of the quality of - * the transmitted signal.The flag can take values from 0 to 255. The transmitted standard index is 107 that - * corresponds to a SISA value of 3.12m.If the prediction is not available, the transmitted index is 255 and - * corresponds to No Accurate Prediction Available(NAPA).NAPA is an indicator of a potential anomalous - * signal-in-space[6].Please notice that SISA flag refers to the dual-frequency signal combinations. - */ - if (value<0.0 || value>6.0) return 255; /* unknown or NAPA */ - else if (value<=0.49) return (int)round(value/0.01); - else if (value<=0.98) return (int)round((value-0.5)/0.02)+50; - else if (value<=1.96) return (int)round((value-1.0)/0.04)+75; - return (int)round((value-2.0)/0.16)+100; +static int sisa_index(double value) { + /* + * kudos to https://core.ac.uk/download/pdf/328854682.pdf for this ... + * Signal-in-Space Accuracy : SISA flag is a prediction at 1-sigma standard deviation of the + * quality of the transmitted signal.The flag can take values from 0 to 255. The transmitted + * standard index is 107 that corresponds to a SISA value of 3.12m.If the prediction is not + * available, the transmitted index is 255 and corresponds to No Accurate Prediction + * Available(NAPA).NAPA is an indicator of a potential anomalous signal-in-space[6].Please notice + * that SISA flag refers to the dual-frequency signal combinations. + */ + if (value < 0.0 || value > 6.0) + return 255; /* unknown or NAPA */ + else if (value <= 0.49) + return (int)round(value / 0.01); + else if (value <= 0.98) + return (int)round((value - 0.5) / 0.02) + 50; + else if (value <= 1.96) + return (int)round((value - 1.0) / 0.04) + 75; + return (int)round((value - 2.0) / 0.16) + 100; } /* initialize station parameter ----------------------------------------------*/ -static void init_sta(sta_t *sta) -{ - int i; - *sta->name ='\0'; - *sta->markerno ='\0'; - *sta->markertype ='\0'; - *sta->observer = '\0'; - *sta->agency = '\0'; - *sta->antdes ='\0'; - *sta->antsno ='\0'; - *sta->rectype='\0'; - *sta->recver ='\0'; - *sta->recsno ='\0'; - sta->antsetup=sta->itrf=sta->deltype=0; - for (i=0;i<3;i++) sta->pos[i]=0.0; - for (i=0;i<3;i++) sta->del[i]=0.0; - sta->hgt=0.0; +static void init_sta(sta_t *sta) { + int i; + *sta->name = '\0'; + *sta->markerno = '\0'; + *sta->markertype = '\0'; + *sta->observer = '\0'; + *sta->agency = '\0'; + *sta->antdes = '\0'; + *sta->antsno = '\0'; + *sta->rectype = '\0'; + *sta->recver = '\0'; + *sta->recsno = '\0'; + sta->antsetup = sta->itrf = sta->deltype = 0; + for (i = 0; i < 3; i++) sta->pos[i] = 0.0; + for (i = 0; i < 3; i++) sta->del[i] = 0.0; + sta->hgt = 0.0; } /*------------------------------------------------------------------------------ -* input RINEX functions -*-----------------------------------------------------------------------------*/ + * input RINEX functions + *-----------------------------------------------------------------------------*/ /* convert RINEX obs-type ver.2 -> ver.3 -------------------------------------*/ -static void convcode(double ver, int sys, const char *str, char *type) -{ - strcpy(type," "); - - if (!strcmp(str,"P1")) { /* ver.2.11 GPS L1PY,GLO L2P */ - if (sys==SYS_GPS) sprintf(type,"%c1W",'C'); - else if (sys==SYS_GLO) sprintf(type,"%c1P",'C'); - } - else if (!strcmp(str,"P2")) { /* ver.2.11 GPS L2PY,GLO L2P */ - if (sys==SYS_GPS) sprintf(type,"%c2W",'C'); - else if (sys==SYS_GLO) sprintf(type,"%c2P",'C'); - } - else if (!strcmp(str,"C1")) { /* ver.2.11 GPS L1C,GLO L1C/A */ - if (ver>=2.12) ; /* reject C1 for 2.12 */ - else if (sys==SYS_GPS) sprintf(type,"%c1C",'C'); - else if (sys==SYS_GLO) sprintf(type,"%c1C",'C'); - else if (sys==SYS_GAL) sprintf(type,"%c1X",'C'); /* ver.2.12 */ - else if (sys==SYS_QZS) sprintf(type,"%c1C",'C'); - else if (sys==SYS_SBS) sprintf(type,"%c1C",'C'); - } - else if (!strcmp(str,"C2")) { - if (sys==SYS_GPS) { - if (ver>=2.12) sprintf(type,"%c2W",'C'); /* L2P(Y) */ - else sprintf(type,"%c2X",'C'); /* L2C */ - } - else if (sys==SYS_GLO) sprintf(type,"%c2C",'C'); - else if (sys==SYS_QZS) sprintf(type,"%c2X",'C'); - else if (sys==SYS_CMP) sprintf(type,"%c2X",'C'); /* ver.2.12 B1_2 */ - } - else if (ver>=2.12&&str[1]=='A') { /* ver.2.12 L1C/A */ - if (sys==SYS_GPS) sprintf(type,"%c1C",str[0]); - else if (sys==SYS_GLO) sprintf(type,"%c1C",str[0]); - else if (sys==SYS_QZS) sprintf(type,"%c1C",str[0]); - else if (sys==SYS_SBS) sprintf(type,"%c1C",str[0]); - } - else if (ver>=2.12&&str[1]=='B') { /* ver.2.12 GPS L1C */ - if (sys==SYS_GPS) sprintf(type,"%c1X",str[0]); - else if (sys==SYS_QZS) sprintf(type,"%c1X",str[0]); - } - else if (ver>=2.12&&str[1]=='C') { /* ver.2.12 GPS L2C */ - if (sys==SYS_GPS) sprintf(type,"%c2X",str[0]); - else if (sys==SYS_QZS) sprintf(type,"%c2X",str[0]); - } - else if (ver>=2.12&&str[1]=='D') { /* ver.2.12 GLO L2C/A */ - if (sys==SYS_GLO) sprintf(type,"%c2C",str[0]); - } - else if (ver>=2.12&&str[1]=='1') { /* ver.2.12 GPS L1PY,GLO L1P */ - if (sys==SYS_GPS) sprintf(type,"%c1W",str[0]); - else if (sys==SYS_GLO) sprintf(type,"%c1P",str[0]); - else if (sys==SYS_GAL) sprintf(type,"%c1X",str[0]); /* tentative */ - else if (sys==SYS_CMP) sprintf(type,"%c2X",str[0]); /* extension */ - } - else if (ver<2.12&&str[1]=='1') { - if (sys==SYS_GPS) sprintf(type,"%c1C",str[0]); - else if (sys==SYS_GLO) sprintf(type,"%c1C",str[0]); - else if (sys==SYS_GAL) sprintf(type,"%c1X",str[0]); /* tentative */ - else if (sys==SYS_QZS) sprintf(type,"%c1C",str[0]); - else if (sys==SYS_SBS) sprintf(type,"%c1C",str[0]); - } - else if (str[1]=='2') { - if (sys==SYS_GPS) sprintf(type,"%c2W",str[0]); - else if (sys==SYS_GLO) sprintf(type,"%c2P",str[0]); - else if (sys==SYS_QZS) sprintf(type,"%c2X",str[0]); - else if (sys==SYS_CMP) sprintf(type,"%c2X",str[0]); /* ver.2.12 B1_2 */ - } - else if (str[1]=='5') { - if (sys==SYS_GPS) sprintf(type,"%c5X",str[0]); - else if (sys==SYS_GAL) sprintf(type,"%c5X",str[0]); - else if (sys==SYS_QZS) sprintf(type,"%c5X",str[0]); - else if (sys==SYS_SBS) sprintf(type,"%c5X",str[0]); - } - else if (str[1]=='6') { - if (sys==SYS_GAL) sprintf(type,"%c6X",str[0]); - else if (sys==SYS_QZS) sprintf(type,"%c6X",str[0]); - else if (sys==SYS_CMP) sprintf(type,"%c6X",str[0]); /* ver.2.12 B3 */ - } - else if (str[1]=='7') { - if (sys==SYS_GAL) sprintf(type,"%c7X",str[0]); - else if (sys==SYS_CMP) sprintf(type,"%c7X",str[0]); /* ver.2.12 B2b */ - } - else if (str[1]=='8') { - if (sys==SYS_GAL) sprintf(type,"%c8X",str[0]); - } - trace(3,"convcode: ver=%.2f sys=%2d type= %s -> %s\n",ver,sys,str,type); +static void convcode(double ver, int sys, const char *str, char *type) { + strcpy(type, " "); + + if (!strcmp(str, "P1")) { /* ver.2.11 GPS L1PY,GLO L2P */ + if (sys == SYS_GPS) + sprintf(type, "%c1W", 'C'); + else if (sys == SYS_GLO) + sprintf(type, "%c1P", 'C'); + } else if (!strcmp(str, "P2")) { /* ver.2.11 GPS L2PY,GLO L2P */ + if (sys == SYS_GPS) + sprintf(type, "%c2W", 'C'); + else if (sys == SYS_GLO) + sprintf(type, "%c2P", 'C'); + } else if (!strcmp(str, "C1")) { /* ver.2.11 GPS L1C,GLO L1C/A */ + if (ver >= 2.12) + ; /* reject C1 for 2.12 */ + else if (sys == SYS_GPS) + sprintf(type, "%c1C", 'C'); + else if (sys == SYS_GLO) + sprintf(type, "%c1C", 'C'); + else if (sys == SYS_GAL) + sprintf(type, "%c1X", 'C'); /* ver.2.12 */ + else if (sys == SYS_QZS) + sprintf(type, "%c1C", 'C'); + else if (sys == SYS_SBS) + sprintf(type, "%c1C", 'C'); + } else if (!strcmp(str, "C2")) { + if (sys == SYS_GPS) { + if (ver >= 2.12) + sprintf(type, "%c2W", 'C'); /* L2P(Y) */ + else + sprintf(type, "%c2X", 'C'); /* L2C */ + } else if (sys == SYS_GLO) + sprintf(type, "%c2C", 'C'); + else if (sys == SYS_QZS) + sprintf(type, "%c2X", 'C'); + else if (sys == SYS_CMP) + sprintf(type, "%c2X", 'C'); /* ver.2.12 B1_2 */ + } else if (ver >= 2.12 && str[1] == 'A') { /* ver.2.12 L1C/A */ + if (sys == SYS_GPS) + sprintf(type, "%c1C", str[0]); + else if (sys == SYS_GLO) + sprintf(type, "%c1C", str[0]); + else if (sys == SYS_QZS) + sprintf(type, "%c1C", str[0]); + else if (sys == SYS_SBS) + sprintf(type, "%c1C", str[0]); + } else if (ver >= 2.12 && str[1] == 'B') { /* ver.2.12 GPS L1C */ + if (sys == SYS_GPS) + sprintf(type, "%c1X", str[0]); + else if (sys == SYS_QZS) + sprintf(type, "%c1X", str[0]); + } else if (ver >= 2.12 && str[1] == 'C') { /* ver.2.12 GPS L2C */ + if (sys == SYS_GPS) + sprintf(type, "%c2X", str[0]); + else if (sys == SYS_QZS) + sprintf(type, "%c2X", str[0]); + } else if (ver >= 2.12 && str[1] == 'D') { /* ver.2.12 GLO L2C/A */ + if (sys == SYS_GLO) sprintf(type, "%c2C", str[0]); + } else if (ver >= 2.12 && str[1] == '1') { /* ver.2.12 GPS L1PY,GLO L1P */ + if (sys == SYS_GPS) + sprintf(type, "%c1W", str[0]); + else if (sys == SYS_GLO) + sprintf(type, "%c1P", str[0]); + else if (sys == SYS_GAL) + sprintf(type, "%c1X", str[0]); /* tentative */ + else if (sys == SYS_CMP) + sprintf(type, "%c2X", str[0]); /* extension */ + } else if (ver < 2.12 && str[1] == '1') { + if (sys == SYS_GPS) + sprintf(type, "%c1C", str[0]); + else if (sys == SYS_GLO) + sprintf(type, "%c1C", str[0]); + else if (sys == SYS_GAL) + sprintf(type, "%c1X", str[0]); /* tentative */ + else if (sys == SYS_QZS) + sprintf(type, "%c1C", str[0]); + else if (sys == SYS_SBS) + sprintf(type, "%c1C", str[0]); + } else if (str[1] == '2') { + if (sys == SYS_GPS) + sprintf(type, "%c2W", str[0]); + else if (sys == SYS_GLO) + sprintf(type, "%c2P", str[0]); + else if (sys == SYS_QZS) + sprintf(type, "%c2X", str[0]); + else if (sys == SYS_CMP) + sprintf(type, "%c2X", str[0]); /* ver.2.12 B1_2 */ + } else if (str[1] == '5') { + if (sys == SYS_GPS) + sprintf(type, "%c5X", str[0]); + else if (sys == SYS_GAL) + sprintf(type, "%c5X", str[0]); + else if (sys == SYS_QZS) + sprintf(type, "%c5X", str[0]); + else if (sys == SYS_SBS) + sprintf(type, "%c5X", str[0]); + } else if (str[1] == '6') { + if (sys == SYS_GAL) + sprintf(type, "%c6X", str[0]); + else if (sys == SYS_QZS) + sprintf(type, "%c6X", str[0]); + else if (sys == SYS_CMP) + sprintf(type, "%c6X", str[0]); /* ver.2.12 B3 */ + } else if (str[1] == '7') { + if (sys == SYS_GAL) + sprintf(type, "%c7X", str[0]); + else if (sys == SYS_CMP) + sprintf(type, "%c7X", str[0]); /* ver.2.12 B2b */ + } else if (str[1] == '8') { + if (sys == SYS_GAL) sprintf(type, "%c8X", str[0]); + } + trace(3, "convcode: ver=%.2f sys=%2d type= %s -> %s\n", ver, sys, str, type); } /* decode RINEX observation data file header ---------------------------------*/ -static void decode_obsh(FILE *fp, char *buff, double ver, int *tsys, - char tobs[][MAXOBSTYPE][4], nav_t *nav, sta_t *sta) -{ - /* default codes for unknown code */ - double del[3]; - int i,j,k,n,nt,prn,fcn; - char *label=buff+60,str[4]; - - trace(4,"decode_obsh: ver=%.2f\n",ver); - - if (strstr(label,"MARKER NAME" )) { - if (sta) setstr(sta->name,buff,60); - } - else if (strstr(label,"MARKER NUMBER" )) { /* opt */ - if (sta) setstr(sta->markerno,buff,20); - } - else if (strstr(label,"MARKER TYPE" )) { /* ver.3 */ - if (sta) setstr(sta->markertype,buff,20); - } - else if (strstr(label,"OBSERVER / AGENCY" )) { - if (sta) { - setstr(sta->observer, buff, 20); - setstr(sta->agency, buff+20, 40); - } - } - else if (strstr(label,"REC # / TYPE / VERS" )) { - if (sta) { - setstr(sta->recsno, buff, 20); - setstr(sta->rectype,buff+20,20); - setstr(sta->recver, buff+40,20); - } - } - else if (strstr(label,"ANT # / TYPE" )) { - if (sta) { - setstr(sta->antsno,buff ,20); - setstr(sta->antdes,buff+20,20); - } - } - else if (strstr(label,"APPROX POSITION XYZ" )) { - if (sta) { - for (i=0,j=0;i<3;i++,j+=14) sta->pos[i]=str2num(buff,j,14); - } - } - else if (strstr(label,"ANTENNA: DELTA H/E/N")) { - if (sta) { - for (i=0,j=0;i<3;i++,j+=14) del[i]=str2num(buff,j,14); - sta->del[2]=del[0]; /* h */ - sta->del[0]=del[1]; /* e */ - sta->del[1]=del[2]; /* n */ - } +static void decode_obsh(FILE *fp, char *buff, double ver, int *tsys, char tobs[][MAXOBSTYPE][4], + nav_t *nav, sta_t *sta) { + /* default codes for unknown code */ + double del[3]; + int i, j, k, n, nt, prn, fcn; + char *label = buff + 60, str[4]; + + trace(4, "decode_obsh: ver=%.2f\n", ver); + + if (strstr(label, "MARKER NAME")) { + if (sta) setstr(sta->name, buff, 60); + } else if (strstr(label, "MARKER NUMBER")) { /* opt */ + if (sta) setstr(sta->markerno, buff, 20); + } else if (strstr(label, "MARKER TYPE")) { /* ver.3 */ + if (sta) setstr(sta->markertype, buff, 20); + } else if (strstr(label, "OBSERVER / AGENCY")) { + if (sta) { + setstr(sta->observer, buff, 20); + setstr(sta->agency, buff + 20, 40); + } + } else if (strstr(label, "REC # / TYPE / VERS")) { + if (sta) { + setstr(sta->recsno, buff, 20); + setstr(sta->rectype, buff + 20, 20); + setstr(sta->recver, buff + 40, 20); + } + } else if (strstr(label, "ANT # / TYPE")) { + if (sta) { + setstr(sta->antsno, buff, 20); + setstr(sta->antdes, buff + 20, 20); + } + } else if (strstr(label, "APPROX POSITION XYZ")) { + if (sta) { + for (i = 0, j = 0; i < 3; i++, j += 14) sta->pos[i] = str2num(buff, j, 14); + } + } else if (strstr(label, "ANTENNA: DELTA H/E/N")) { + if (sta) { + for (i = 0, j = 0; i < 3; i++, j += 14) del[i] = str2num(buff, j, 14); + sta->del[2] = del[0]; /* h */ + sta->del[0] = del[1]; /* e */ + sta->del[1] = del[2]; /* n */ + } + } else if (strstr(label, "ANTENNA: DELTA X/Y/Z")) + ; /* opt ver.3 */ + else if (strstr(label, "ANTENNA: PHASECENTER")) + ; /* opt ver.3 */ + else if (strstr(label, "ANTENNA: B.SIGHT XYZ")) + ; /* opt ver.3 */ + else if (strstr(label, "ANTENNA: ZERODIR AZI")) + ; /* opt ver.3 */ + else if (strstr(label, "ANTENNA: ZERODIR XYZ")) + ; /* opt ver.3 */ + else if (strstr(label, "CENTER OF MASS: XYZ")) + ; /* opt ver.3 */ + else if (strstr(label, "SYS / # / OBS TYPES")) { /* ver.3 */ + const char *p = strchr(syscodes, buff[0]); + if (!p) { + trace(2, "invalid system code: sys=%c\n", buff[0]); + return; + } + i = (int)(p - syscodes); + n = (int)str2num(buff, 3, 3); + for (j = nt = 0, k = 7; j < n; j++, k += 4) { + if (k > 58) { + if (!fgets(buff, MAXRNXLEN, fp)) break; + k = 7; + } + if (nt < MAXOBSTYPE - 1) setstr(tobs[i][nt++], buff + k, 3); } - else if (strstr(label,"ANTENNA: DELTA X/Y/Z")) ; /* opt ver.3 */ - else if (strstr(label,"ANTENNA: PHASECENTER")) ; /* opt ver.3 */ - else if (strstr(label,"ANTENNA: B.SIGHT XYZ")) ; /* opt ver.3 */ - else if (strstr(label,"ANTENNA: ZERODIR AZI")) ; /* opt ver.3 */ - else if (strstr(label,"ANTENNA: ZERODIR XYZ")) ; /* opt ver.3 */ - else if (strstr(label,"CENTER OF MASS: XYZ" )) ; /* opt ver.3 */ - else if (strstr(label,"SYS / # / OBS TYPES" )) { /* ver.3 */ - const char *p = strchr(syscodes,buff[0]); - if (!p) { - trace(2,"invalid system code: sys=%c\n",buff[0]); - return; - } - i=(int)(p-syscodes); - n=(int)str2num(buff,3,3); - for (j=nt=0,k=7;j58) { - if (!fgets(buff,MAXRNXLEN,fp)) break; - k=7; - } - if (nt58) { - if (!fgets(buff,MAXRNXLEN,fp)) break; - j=10; - } - if (nt>=MAXOBSTYPE-1) continue; - if (ver<=2.99) { - setstr(str,buff+j,2); - convcode(ver,SYS_GPS,str,tobs[RNX_SYS_GPS][nt]); - convcode(ver,SYS_GLO,str,tobs[RNX_SYS_GLO][nt]); - convcode(ver,SYS_GAL,str,tobs[RNX_SYS_GAL][nt]); - convcode(ver,SYS_QZS,str,tobs[RNX_SYS_QZS][nt]); - convcode(ver,SYS_SBS,str,tobs[RNX_SYS_SBS][nt]); - convcode(ver,SYS_CMP,str,tobs[RNX_SYS_CMP][nt]); - /* IRN missing, assumed to be not applicable? */ - } - nt++; - } - *tobs[0][nt]='\0'; - } - else if (strstr(label,"SIGNAL STRENGTH UNIT")) ; /* opt ver.3 */ - else if (strstr(label,"INTERVAL" )) ; /* opt */ - else if (strstr(label,"TIME OF FIRST OBS" )) { - if (!strncmp(buff+48,"GPS",3)) *tsys=TSYS_GPS; - else if (!strncmp(buff+48,"GLO",3)) *tsys=TSYS_UTC; - else if (!strncmp(buff+48,"GAL",3)) *tsys=TSYS_GAL; - else if (!strncmp(buff+48,"QZS",3)) *tsys=TSYS_QZS; /* ver.3.02 */ - else if (!strncmp(buff+48,"BDT",3)) *tsys=TSYS_CMP; /* ver.3.02 */ - else if (!strncmp(buff+48,"IRN",3)) *tsys=TSYS_IRN; /* ver.3.03 */ - } - else if (strstr(label,"TIME OF LAST OBS" )) ; /* opt */ - else if (strstr(label,"RCV CLOCK OFFS APPL" )) ; /* opt */ - else if (strstr(label,"SYS / DCBS APPLIED" )) ; /* opt ver.3 */ - else if (strstr(label,"SYS / PCVS APPLIED" )) ; /* opt ver.3 */ - else if (strstr(label,"SYS / SCALE FACTOR" )) ; /* opt ver.3 */ - else if (strstr(label,"SYS / PHASE SHIFTS" )) ; /* ver.3.01 */ - else if (strstr(label,"GLONASS SLOT / FRQ #")) { /* ver.3.02 */ - for (i=0;i<8;i++) { - if (buff[4+i*7]!='R') continue; - prn=(int)str2num(buff,5+i*7,2); - fcn=(int)str2num(buff,8+i*7,2); - if (prn<1||prn>MAXPRNGLO||fcn<-7||fcn>6) continue; - if (nav) nav->glo_fcn[prn-1]=fcn+8; - } + /* change BDS B1 code: 3.02 */ + if (i == RNX_SYS_CMP && fabs(ver - 3.02) < 1e-3) { + for (j = 0; j < nt; j++) + if (tobs[i][j][1] == '1') tobs[i][j][1] = '2'; } - else if (strstr(label,"GLONASS COD/PHS/BIS" )) { /* ver.3.02 */ - if (sta) { - sta->glo_cp_bias[0]=str2num(buff, 5,8); - sta->glo_cp_bias[1]=str2num(buff,18,8); - sta->glo_cp_bias[2]=str2num(buff,31,8); - sta->glo_cp_bias[3]=str2num(buff,44,8); - } - } - else if (strstr(label,"LEAP SECONDS" )) { /* opt */ - if (nav) { - nav->utc_gps[4]=str2num(buff, 0,6); - nav->utc_gps[7]=str2num(buff, 6,6); - nav->utc_gps[5]=str2num(buff,12,6); - nav->utc_gps[6]=str2num(buff,18,6); - } - } - else if (strstr(label,"# OF SATELLITES" )) { /* opt */ - /* skip */ ; - } - else if (strstr(label,"PRN / # OF OBS" )) { /* opt */ - /* skip */ ; +#ifdef RTK_DISABLED + // Uncomment this code to convert unknown codes to defaults. + const char frqcodes[] = "1256789"; + const char *defcodes[] = { + "CWX ", // GPS: L125____ + "CCXX X ", // GLO: L1234_6_ + "CXXXXX ", // GAL: L125678_ FIXME: Galileo should not have L2! + "CXXX ", // QZS: L1256___ + "C X ", // SBS: L1_5____ + "XIXIIX ", // BDS: L125678_ + " A A" // IRN: L__5___9 + }; + for (int j = 0; j < nt; j++) { + if (tobs[i][j][2]) continue; + const char *p = strchr(frqcodes, tobs[i][j][1]); + if (!p) continue; + tobs[i][j][2] = defcodes[i][(int)(p - frqcodes)]; + trace(2, "set default for unknown code: sys=%c code=%s\n", buff[0], tobs[i][j]); } +#endif + } else if (strstr(label, "WAVELENGTH FACT L1/2")) + ; /* opt ver.2 */ + else if (strstr(label, "# / TYPES OF OBSERV")) { /* ver.2 */ + n = (int)str2num(buff, 0, 6); + for (i = nt = 0, j = 10; i < n; i++, j += 6) { + if (j > 58) { + if (!fgets(buff, MAXRNXLEN, fp)) break; + j = 10; + } + if (nt >= MAXOBSTYPE - 1) continue; + if (ver <= 2.99) { + setstr(str, buff + j, 2); + convcode(ver, SYS_GPS, str, tobs[RNX_SYS_GPS][nt]); + convcode(ver, SYS_GLO, str, tobs[RNX_SYS_GLO][nt]); + convcode(ver, SYS_GAL, str, tobs[RNX_SYS_GAL][nt]); + convcode(ver, SYS_QZS, str, tobs[RNX_SYS_QZS][nt]); + convcode(ver, SYS_SBS, str, tobs[RNX_SYS_SBS][nt]); + convcode(ver, SYS_CMP, str, tobs[RNX_SYS_CMP][nt]); + /* IRN missing, assumed to be not applicable? */ + } + nt++; + } + *tobs[0][nt] = '\0'; + } else if (strstr(label, "SIGNAL STRENGTH UNIT")) + ; /* opt ver.3 */ + else if (strstr(label, "INTERVAL")) + ; /* opt */ + else if (strstr(label, "TIME OF FIRST OBS")) { + if (!strncmp(buff + 48, "GPS", 3)) + *tsys = TSYS_GPS; + else if (!strncmp(buff + 48, "GLO", 3)) + *tsys = TSYS_UTC; + else if (!strncmp(buff + 48, "GAL", 3)) + *tsys = TSYS_GAL; + else if (!strncmp(buff + 48, "QZS", 3)) + *tsys = TSYS_QZS; /* ver.3.02 */ + else if (!strncmp(buff + 48, "BDT", 3)) + *tsys = TSYS_CMP; /* ver.3.02 */ + else if (!strncmp(buff + 48, "IRN", 3)) + *tsys = TSYS_IRN; /* ver.3.03 */ + } else if (strstr(label, "TIME OF LAST OBS")) + ; /* opt */ + else if (strstr(label, "RCV CLOCK OFFS APPL")) + ; /* opt */ + else if (strstr(label, "SYS / DCBS APPLIED")) + ; /* opt ver.3 */ + else if (strstr(label, "SYS / PCVS APPLIED")) + ; /* opt ver.3 */ + else if (strstr(label, "SYS / SCALE FACTOR")) + ; /* opt ver.3 */ + else if (strstr(label, "SYS / PHASE SHIFTS")) + ; /* ver.3.01 */ + else if (strstr(label, "GLONASS SLOT / FRQ #")) { /* ver.3.02 */ + for (i = 0; i < 8; i++) { + if (buff[4 + i * 7] != 'R') continue; + prn = (int)str2num(buff, 5 + i * 7, 2); + fcn = (int)str2num(buff, 8 + i * 7, 2); + if (prn < 1 || prn > MAXPRNGLO || fcn < -7 || fcn > 6) continue; + if (nav) nav->glo_fcn[prn - 1] = fcn + 8; + } + } else if (strstr(label, "GLONASS COD/PHS/BIS")) { /* ver.3.02 */ + if (sta) { + sta->glo_cp_bias[0] = str2num(buff, 5, 8); + sta->glo_cp_bias[1] = str2num(buff, 18, 8); + sta->glo_cp_bias[2] = str2num(buff, 31, 8); + sta->glo_cp_bias[3] = str2num(buff, 44, 8); + } + } else if (strstr(label, "LEAP SECONDS")) { /* opt */ + if (nav) { + nav->utc_gps[4] = str2num(buff, 0, 6); + nav->utc_gps[7] = str2num(buff, 6, 6); + nav->utc_gps[5] = str2num(buff, 12, 6); + nav->utc_gps[6] = str2num(buff, 18, 6); + } + } else if (strstr(label, "# OF SATELLITES")) { /* opt */ + /* skip */; + } else if (strstr(label, "PRN / # OF OBS")) { /* opt */ + /* skip */; + } } /* decode RINEX NAV header ---------------------------------------------------*/ -static void decode_navh(char *buff, nav_t *nav) -{ - int i,j; - char *label=buff+60; - - trace(4,"decode_navh:\n"); - - if (strstr(label,"ION ALPHA" )) { /* opt ver.2 */ - if (nav) { - for (i=0,j=2;i<4;i++,j+=12) nav->ion_gps[i]=str2num(buff,j,12); - } - } - else if (strstr(label,"ION BETA" )) { /* opt ver.2 */ - if (nav) { - for (i=0,j=2;i<4;i++,j+=12) nav->ion_gps[i+4]=str2num(buff,j,12); - } - } - else if (strstr(label,"DELTA-UTC: A0,A1,T,W")) { /* opt ver.2 */ - if (nav) { - for (i=0,j=3;i<2;i++,j+=19) nav->utc_gps[i]=str2num(buff,j,19); - for (;i<4;i++,j+=9) nav->utc_gps[i]=str2num(buff,j,9); - } - } - else if (strstr(label,"IONOSPHERIC CORR" )) { /* opt ver.3 */ - if (nav) { - if (!strncmp(buff,"GPSA",4)) { - for (i=0,j=5;i<4;i++,j+=12) nav->ion_gps[i]=str2num(buff,j,12); - } - else if (!strncmp(buff,"GPSB",4)) { - for (i=0,j=5;i<4;i++,j+=12) nav->ion_gps[i+4]=str2num(buff,j,12); - } - else if (!strncmp(buff,"GAL",3)) { - for (i=0,j=5;i<4;i++,j+=12) nav->ion_gal[i]=str2num(buff,j,12); - } - else if (!strncmp(buff,"QZSA",4)) { /* v.3.02 */ - for (i=0,j=5;i<4;i++,j+=12) nav->ion_qzs[i]=str2num(buff,j,12); - } - else if (!strncmp(buff,"QZSB",4)) { /* v.3.02 */ - for (i=0,j=5;i<4;i++,j+=12) nav->ion_qzs[i+4]=str2num(buff,j,12); - } - else if (!strncmp(buff,"BDSA",4)) { /* v.3.02 */ - for (i=0,j=5;i<4;i++,j+=12) nav->ion_cmp[i]=str2num(buff,j,12); - } - else if (!strncmp(buff,"BDSB",4)) { /* v.3.02 */ - for (i=0,j=5;i<4;i++,j+=12) nav->ion_cmp[i+4]=str2num(buff,j,12); - } - else if (!strncmp(buff,"IRNA",4)) { /* v.3.03 */ - for (i=0,j=5;i<4;i++,j+=12) nav->ion_irn[i]=str2num(buff,j,12); - } - else if (!strncmp(buff,"IRNB",4)) { /* v.3.03 */ - for (i=0,j=5;i<4;i++,j+=12) nav->ion_irn[i+4]=str2num(buff,j,12); - } - } +static void decode_navh(char *buff, nav_t *nav) { + int i, j; + char *label = buff + 60; + + trace(4, "decode_navh:\n"); + + if (strstr(label, "ION ALPHA")) { /* opt ver.2 */ + if (nav) { + for (i = 0, j = 2; i < 4; i++, j += 12) nav->ion_gps[i] = str2num(buff, j, 12); + } + } else if (strstr(label, "ION BETA")) { /* opt ver.2 */ + if (nav) { + for (i = 0, j = 2; i < 4; i++, j += 12) nav->ion_gps[i + 4] = str2num(buff, j, 12); + } + } else if (strstr(label, "DELTA-UTC: A0,A1,T,W")) { /* opt ver.2 */ + if (nav) { + for (i = 0, j = 3; i < 2; i++, j += 19) nav->utc_gps[i] = str2num(buff, j, 19); + for (; i < 4; i++, j += 9) nav->utc_gps[i] = str2num(buff, j, 9); + } + } else if (strstr(label, "IONOSPHERIC CORR")) { /* opt ver.3 */ + if (nav) { + if (!strncmp(buff, "GPSA", 4)) { + for (i = 0, j = 5; i < 4; i++, j += 12) nav->ion_gps[i] = str2num(buff, j, 12); + } else if (!strncmp(buff, "GPSB", 4)) { + for (i = 0, j = 5; i < 4; i++, j += 12) nav->ion_gps[i + 4] = str2num(buff, j, 12); + } else if (!strncmp(buff, "GAL", 3)) { + for (i = 0, j = 5; i < 4; i++, j += 12) nav->ion_gal[i] = str2num(buff, j, 12); + } else if (!strncmp(buff, "QZSA", 4)) { /* v.3.02 */ + for (i = 0, j = 5; i < 4; i++, j += 12) nav->ion_qzs[i] = str2num(buff, j, 12); + } else if (!strncmp(buff, "QZSB", 4)) { /* v.3.02 */ + for (i = 0, j = 5; i < 4; i++, j += 12) nav->ion_qzs[i + 4] = str2num(buff, j, 12); + } else if (!strncmp(buff, "BDSA", 4)) { /* v.3.02 */ + for (i = 0, j = 5; i < 4; i++, j += 12) nav->ion_cmp[i] = str2num(buff, j, 12); + } else if (!strncmp(buff, "BDSB", 4)) { /* v.3.02 */ + for (i = 0, j = 5; i < 4; i++, j += 12) nav->ion_cmp[i + 4] = str2num(buff, j, 12); + } else if (!strncmp(buff, "IRNA", 4)) { /* v.3.03 */ + for (i = 0, j = 5; i < 4; i++, j += 12) nav->ion_irn[i] = str2num(buff, j, 12); + } else if (!strncmp(buff, "IRNB", 4)) { /* v.3.03 */ + for (i = 0, j = 5; i < 4; i++, j += 12) nav->ion_irn[i + 4] = str2num(buff, j, 12); + } } - else if (strstr(label,"TIME SYSTEM CORR" )) { /* opt ver.3 */ - if (nav) { - if (!strncmp(buff,"GPUT",4)) { - nav->utc_gps[0]=str2num(buff, 5,17); - nav->utc_gps[1]=str2num(buff,22,16); - nav->utc_gps[2]=str2num(buff,38, 7); - nav->utc_gps[3]=str2num(buff,45, 5); - } - else if (!strncmp(buff,"GLUT",4)) { - nav->utc_glo[0]=-str2num(buff,5,17); /* tau_C */ - } - else if (!strncmp(buff,"GLGP",4)) { - nav->utc_glo[1]=str2num(buff, 5,17); /* tau_GPS */ - } - else if (!strncmp(buff,"GAUT",4)) { /* v.3.02 */ - nav->utc_gal[0]=str2num(buff, 5,17); - nav->utc_gal[1]=str2num(buff,22,16); - nav->utc_gal[2]=str2num(buff,38, 7); - nav->utc_gal[3]=str2num(buff,45, 5); - } - else if (!strncmp(buff,"QZUT",4)) { /* v.3.02 */ - nav->utc_qzs[0]=str2num(buff, 5,17); - nav->utc_qzs[1]=str2num(buff,22,16); - nav->utc_qzs[2]=str2num(buff,38, 7); - nav->utc_qzs[3]=str2num(buff,45, 5); - } - else if (!strncmp(buff,"BDUT",4)) { /* v.3.02 */ - nav->utc_cmp[0]=str2num(buff, 5,17); - nav->utc_cmp[1]=str2num(buff,22,16); - nav->utc_cmp[2]=str2num(buff,38, 7); - nav->utc_cmp[3]=str2num(buff,45, 5); - } - else if (!strncmp(buff,"SBUT",4)) { /* v.3.02 */ - nav->utc_sbs[0]=str2num(buff, 5,17); - nav->utc_sbs[1]=str2num(buff,22,16); - nav->utc_sbs[2]=str2num(buff,38, 7); - nav->utc_sbs[3]=str2num(buff,45, 5); - } - else if (!strncmp(buff,"IRUT",4)) { /* v.3.03 */ - nav->utc_irn[0]=str2num(buff, 5,17); - nav->utc_irn[1]=str2num(buff,22,16); - nav->utc_irn[2]=str2num(buff,38, 7); - nav->utc_irn[3]=str2num(buff,45, 5); - nav->utc_irn[8]=0.0; /* A2 */ - } - } + } else if (strstr(label, "TIME SYSTEM CORR")) { /* opt ver.3 */ + if (nav) { + if (!strncmp(buff, "GPUT", 4)) { + nav->utc_gps[0] = str2num(buff, 5, 17); + nav->utc_gps[1] = str2num(buff, 22, 16); + nav->utc_gps[2] = str2num(buff, 38, 7); + nav->utc_gps[3] = str2num(buff, 45, 5); + } else if (!strncmp(buff, "GLUT", 4)) { + nav->utc_glo[0] = -str2num(buff, 5, 17); /* tau_C */ + } else if (!strncmp(buff, "GLGP", 4)) { + nav->utc_glo[1] = str2num(buff, 5, 17); /* tau_GPS */ + } else if (!strncmp(buff, "GAUT", 4)) { /* v.3.02 */ + nav->utc_gal[0] = str2num(buff, 5, 17); + nav->utc_gal[1] = str2num(buff, 22, 16); + nav->utc_gal[2] = str2num(buff, 38, 7); + nav->utc_gal[3] = str2num(buff, 45, 5); + } else if (!strncmp(buff, "QZUT", 4)) { /* v.3.02 */ + nav->utc_qzs[0] = str2num(buff, 5, 17); + nav->utc_qzs[1] = str2num(buff, 22, 16); + nav->utc_qzs[2] = str2num(buff, 38, 7); + nav->utc_qzs[3] = str2num(buff, 45, 5); + } else if (!strncmp(buff, "BDUT", 4)) { /* v.3.02 */ + nav->utc_cmp[0] = str2num(buff, 5, 17); + nav->utc_cmp[1] = str2num(buff, 22, 16); + nav->utc_cmp[2] = str2num(buff, 38, 7); + nav->utc_cmp[3] = str2num(buff, 45, 5); + } else if (!strncmp(buff, "SBUT", 4)) { /* v.3.02 */ + nav->utc_sbs[0] = str2num(buff, 5, 17); + nav->utc_sbs[1] = str2num(buff, 22, 16); + nav->utc_sbs[2] = str2num(buff, 38, 7); + nav->utc_sbs[3] = str2num(buff, 45, 5); + } else if (!strncmp(buff, "IRUT", 4)) { /* v.3.03 */ + nav->utc_irn[0] = str2num(buff, 5, 17); + nav->utc_irn[1] = str2num(buff, 22, 16); + nav->utc_irn[2] = str2num(buff, 38, 7); + nav->utc_irn[3] = str2num(buff, 45, 5); + nav->utc_irn[8] = 0.0; /* A2 */ + } } - else if (strstr(label,"LEAP SECONDS" )) { /* opt */ - if (nav) { - nav->utc_gps[4]=str2num(buff, 0,6); - nav->utc_gps[7]=str2num(buff, 6,6); - nav->utc_gps[5]=str2num(buff,12,6); - nav->utc_gps[6]=str2num(buff,18,6); - } + } else if (strstr(label, "LEAP SECONDS")) { /* opt */ + if (nav) { + nav->utc_gps[4] = str2num(buff, 0, 6); + nav->utc_gps[7] = str2num(buff, 6, 6); + nav->utc_gps[5] = str2num(buff, 12, 6); + nav->utc_gps[6] = str2num(buff, 18, 6); } + } } /* decode GNAV header --------------------------------------------------------*/ -static void decode_gnavh(char *buff, nav_t *nav) -{ - (void)nav; - char *label=buff+60; +static void decode_gnavh(char *buff, nav_t *nav) { + (void)nav; + char *label = buff + 60; - trace(4,"decode_gnavh:\n"); + trace(4, "decode_gnavh:\n"); - if (strstr(label,"CORR TO SYSTEM TIME" )) {} /* opt */ - else if (strstr(label,"LEAP SECONDS" )) {} /* opt */ + if (strstr(label, "CORR TO SYSTEM TIME")) { + } /* opt */ + else if (strstr(label, "LEAP SECONDS")) { + } /* opt */ } /* decode GEO NAV header -----------------------------------------------------*/ -static void decode_hnavh(char *buff, nav_t *nav) -{ - (void)nav; - char *label=buff+60; +static void decode_hnavh(char *buff, nav_t *nav) { + (void)nav; + char *label = buff + 60; - trace(4,"decode_hnavh:\n"); + trace(4, "decode_hnavh:\n"); - if (strstr(label,"CORR TO SYSTEM TIME" )) {} /* opt */ - else if (strstr(label,"D-UTC A0,A1,T,W,S,U" )) {} /* opt */ - else if (strstr(label,"LEAP SECONDS" )) {} /* opt */ + if (strstr(label, "CORR TO SYSTEM TIME")) { + } /* opt */ + else if (strstr(label, "D-UTC A0,A1,T,W,S,U")) { + } /* opt */ + else if (strstr(label, "LEAP SECONDS")) { + } /* opt */ } /* read RINEX file header ----------------------------------------------------*/ static int readrnxh(FILE *fp, double *ver, char *type, int *sys, int *tsys, - char tobs[][MAXOBSTYPE][4], nav_t *nav, sta_t *sta, int flag) -{ - char buff[MAXRNXLEN],*label=buff+60; - int i=0; - - trace(3,"readrnxh:\n"); - - *ver=2.10; *type=' '; *sys=SYS_GPS; *tsys=TSYS_GPS; - - while (fgets(buff,MAXRNXLEN,fp)) { - - if (strlen(buff)<=60) { - continue; - } - else if (strstr(label,"RINEX VERSION / TYPE")) { - *ver=str2num(buff,0,9); - // Format change for clock files >=3.04 - *type=(*ver<3.04||flag==0)?*(buff+20):*(buff+21); - - // Satellite system - switch ((*ver<3.04||flag==0)?*(buff+40):*(buff+42)) { - case ' ': - case 'G': *sys=SYS_GPS; *tsys=TSYS_GPS; break; - case 'R': *sys=SYS_GLO; *tsys=TSYS_UTC; break; - case 'E': *sys=SYS_GAL; *tsys=TSYS_GAL; break; /* v.2.12 */ - case 'S': *sys=SYS_SBS; *tsys=TSYS_GPS; break; - case 'J': *sys=SYS_QZS; *tsys=TSYS_QZS; break; /* v.3.02 */ - case 'C': *sys=SYS_CMP; *tsys=TSYS_CMP; break; /* v.2.12 */ - case 'I': *sys=SYS_IRN; *tsys=TSYS_IRN; break; /* v.3.03 */ - case 'M': *sys=SYS_NONE; *tsys=TSYS_GPS; break; /* mixed */ - default : - trace(2,"not supported satellite system: %c\n",*(buff+40)); - break; - } - continue; - } - else if (strstr(label,"PGM / RUN BY / DATE")) { - continue; - } - else if (strstr(label,"COMMENT")) { - continue; - } - switch (*type) { /* file type */ - case 'O': decode_obsh(fp,buff,*ver,tsys,tobs,nav,sta); break; - case 'N': decode_navh (buff,nav); break; - case 'G': decode_gnavh(buff,nav); break; - case 'H': decode_hnavh(buff,nav); break; - case 'J': decode_navh (buff,nav); break; /* extension */ - case 'L': decode_navh (buff,nav); break; /* extension */ - } - if (strstr(label,"END OF HEADER")) return 1; + char tobs[][MAXOBSTYPE][4], nav_t *nav, sta_t *sta, int flag) { + char buff[MAXRNXLEN], *label = buff + 60; + int i = 0; - if (++i>=MAXPOSHEAD&&*type==' ') break; /* no RINEX file */ + trace(3, "readrnxh:\n"); + + *ver = 2.10; + *type = ' '; + *sys = SYS_GPS; + *tsys = TSYS_GPS; + + while (fgets(buff, MAXRNXLEN, fp)) { + if (strlen(buff) <= 60) { + continue; + } else if (strstr(label, "RINEX VERSION / TYPE")) { + *ver = str2num(buff, 0, 9); + // Format change for clock files >=3.04 + *type = (*ver < 3.04 || flag == 0) ? *(buff + 20) : *(buff + 21); + + // Satellite system + switch ((*ver < 3.04 || flag == 0) ? *(buff + 40) : *(buff + 42)) { + case ' ': + case 'G': + *sys = SYS_GPS; + *tsys = TSYS_GPS; + break; + case 'R': + *sys = SYS_GLO; + *tsys = TSYS_UTC; + break; + case 'E': + *sys = SYS_GAL; + *tsys = TSYS_GAL; + break; /* v.2.12 */ + case 'S': + *sys = SYS_SBS; + *tsys = TSYS_GPS; + break; + case 'J': + *sys = SYS_QZS; + *tsys = TSYS_QZS; + break; /* v.3.02 */ + case 'C': + *sys = SYS_CMP; + *tsys = TSYS_CMP; + break; /* v.2.12 */ + case 'I': + *sys = SYS_IRN; + *tsys = TSYS_IRN; + break; /* v.3.03 */ + case 'M': + *sys = SYS_NONE; + *tsys = TSYS_GPS; + break; /* mixed */ + default: + trace(2, "not supported satellite system: %c\n", *(buff + 40)); + break; + } + continue; + } else if (strstr(label, "PGM / RUN BY / DATE")) { + continue; + } else if (strstr(label, "COMMENT")) { + continue; + } + switch (*type) { /* file type */ + case 'O': + decode_obsh(fp, buff, *ver, tsys, tobs, nav, sta); + break; + case 'N': + decode_navh(buff, nav); + break; + case 'G': + decode_gnavh(buff, nav); + break; + case 'H': + decode_hnavh(buff, nav); + break; + case 'J': + decode_navh(buff, nav); + break; /* extension */ + case 'L': + decode_navh(buff, nav); + break; /* extension */ } - return 0; + if (strstr(label, "END OF HEADER")) return 1; + + if (++i >= MAXPOSHEAD && *type == ' ') break; /* no RINEX file */ + } + return 0; } /* decode observation epoch --------------------------------------------------*/ -static int decode_obsepoch(FILE *fp, char *buff, double ver, gtime_t *time, - int *flag, int *sats) -{ - int i,j,n; - char satid[8]={'\0'}; +static int decode_obsepoch(FILE *fp, char *buff, double ver, gtime_t *time, int *flag, int *sats) { + int i, j, n; + char satid[8] = {'\0'}; - trace(4,"decode_obsepoch: ver=%.2f\n",ver); + trace(4, "decode_obsepoch: ver=%.2f\n", ver); - if (ver<=2.99) { /* ver.2 */ - /* epoch flag: 3:new site,4:header info,5:external event */ - *flag=(int)str2num(buff,28,1); + if (ver <= 2.99) { /* ver.2 */ + /* epoch flag: 3:new site,4:header info,5:external event */ + *flag = (int)str2num(buff, 28, 1); - /* handle external event */ - if (*flag == 5) { - str2time(buff,0,26,time); - } + /* handle external event */ + if (*flag == 5) { + str2time(buff, 0, 26, time); + } - if ((n=(int)str2num(buff,29,3))<=0) return 0; + if ((n = (int)str2num(buff, 29, 3)) <= 0) return 0; - if (3<=*flag&&*flag<=5) return n; + if (3 <= *flag && *flag <= 5) return n; - if (str2time(buff,0,26,time)) { - trace(2,"rinex obs invalid epoch: epoch=%26.26s\n",buff); - return 0; - } - for (i=0,j=32;i=68) { - if (!fgets(buff,MAXRNXLEN,fp)) break; - j=32; - } - if (i= 68) { + if (!fgets(buff, MAXRNXLEN, fp)) break; + j = 32; + } + if (i < MAXOBS) { + strncpy(satid, buff + j, 3); + sats[i] = satid2no(satid); + } + } + } else { /* ver.3 */ + *flag = (int)str2num(buff, 31, 1); - /* handle external event */ - if (*flag == 5) { - str2time(buff,1,28,time); - } + /* handle external event */ + if (*flag == 5) { + str2time(buff, 1, 28, time); + } - if ((n=(int)str2num(buff,32,3))<=0) return 0; + if ((n = (int)str2num(buff, 32, 3)) <= 0) return 0; - if (3<=*flag&&*flag<=5) return n; + if (3 <= *flag && *flag <= 5) return n; - if (buff[0]!='>'||str2time(buff,1,28,time)) { - trace(2,"rinex obs invalid epoch: epoch=%29.29s\n",buff); - return 0; - } + if (buff[0] != '>' || str2time(buff, 1, 28, time)) { + trace(2, "rinex obs invalid epoch: epoch=%29.29s\n", buff); + return 0; } - char tstr[40]; - trace(4,"decode_obsepoch: time=%s flag=%d\n",time2str(*time,tstr,3),*flag); - return n; + } + char tstr[40]; + trace(4, "decode_obsepoch: time=%s flag=%d\n", time2str(*time, tstr, 3), *flag); + return n; } /* decode observation data ---------------------------------------------------*/ -static int decode_obsdata(FILE *fp, char *buff, double ver, int mask, - sigind_t *index, obsd_t *obs) -{ - sigind_t *ind; - double val[MAXOBSTYPE]={0}; - uint8_t lli[MAXOBSTYPE]={0}; - double std[MAXOBSTYPE]={0}; - char satid[8]=""; - int i,j,n,m,q,stat=1,p[MAXOBSTYPE],k[16],l[16],r[16]; - - trace(4,"decode_obsdata: ver=%.2f\n",ver); - - if (ver>2.99) { /* ver.3 */ - snprintf(satid,8,"%.3s",buff); - obs->sat=(uint8_t)satid2no(satid); - } - if (!obs->sat) { - trace(4,"decode_obsdata: unsupported sat sat=%s\n",satid); - stat=0; - } - else if (!(satsys(obs->sat,NULL)&mask)) { - stat=0; - } - /* read observation data fields */ - switch (satsys(obs->sat,NULL)) { - case SYS_GLO: ind=index+1; break; - case SYS_GAL: ind=index+2; break; - case SYS_QZS: ind=index+3; break; - case SYS_SBS: ind=index+4; break; - case SYS_CMP: ind=index+5; break; - case SYS_IRN: ind=index+6; break; - default: ind=index ; break; - } - for (i=0,j=ver<=2.99?0:3;in;i++,j+=16) { - - if (ver<=2.99&&j>=80) { /* ver.2 */ - if (!fgets(buff,MAXRNXLEN,fp)) break; - j=0; - } - if (stat) { - val[i]=str2num(buff,j,14)+ind->shift[i]; - lli[i]=(uint8_t)str2num(buff,j+14,1)&3; - /* measurement std from receiver, encoded */ - std[i]=str2num(buff,j+15,1); - } +static int decode_obsdata(FILE *fp, char *buff, double ver, int mask, sigind_t *index, + obsd_t *obs) { + sigind_t *ind; + double val[MAXOBSTYPE] = {0}; + uint8_t lli[MAXOBSTYPE] = {0}; + double std[MAXOBSTYPE] = {0}; + char satid[8] = ""; + int i, j, n, m, q, stat = 1, p[MAXOBSTYPE], k[16], l[16], r[16]; + + trace(4, "decode_obsdata: ver=%.2f\n", ver); + + if (ver > 2.99) { /* ver.3 */ + snprintf(satid, 8, "%.3s", buff); + obs->sat = (uint8_t)satid2no(satid); + } + if (!obs->sat) { + trace(4, "decode_obsdata: unsupported sat sat=%s\n", satid); + stat = 0; + } else if (!(satsys(obs->sat, NULL) & mask)) { + stat = 0; + } + /* read observation data fields */ + switch (satsys(obs->sat, NULL)) { + case SYS_GLO: + ind = index + 1; + break; + case SYS_GAL: + ind = index + 2; + break; + case SYS_QZS: + ind = index + 3; + break; + case SYS_SBS: + ind = index + 4; + break; + case SYS_CMP: + ind = index + 5; + break; + case SYS_IRN: + ind = index + 6; + break; + default: + ind = index; + break; + } + for (i = 0, j = ver <= 2.99 ? 0 : 3; i < ind->n; i++, j += 16) { + if (ver <= 2.99 && j >= 80) { /* ver.2 */ + if (!fgets(buff, MAXRNXLEN, fp)) break; + j = 0; } - if (!stat) return 0; - - for (i=0;iP[i]=obs->L[i]=0.0; - obs->D[i]=obs->SNR[i]=0.0; - obs->LLI[i]=obs->code[i]=0; - obs->Lstd[i]=obs->Pstd[i]=0.0; - } - /* assign position in observation data */ - for (i=n=m=q=0;in;i++) { - - p[i]=(ver<=2.11)?ind->idx[i]:ind->pos[i]; - - if (ind->type[i]==0&&p[i]==0) k[n++]=i; /* C1? index */ - if (ind->type[i]==0&&p[i]==1) l[m++]=i; /* C2? index */ - if (ind->type[i]==0&&p[i]==2) r[q++]=i; /* C3? index */ - } - - /* if multiple codes (C1/P1,C2/P2), select higher priority */ - if (ver<=2.11) { - if (n>=2) { - if (val[k[0]]==0.0&&val[k[1]]==0.0) { - p[k[0]]=-1; p[k[1]]=-1; - } - else if (val[k[0]]!=0.0&&val[k[1]]==0.0) { - p[k[0]]=0; p[k[1]]=-1; - } - else if (val[k[0]]==0.0&&val[k[1]]!=0.0) { - p[k[0]]=-1; p[k[1]]=0; - } - else if (ind->pri[k[1]]>ind->pri[k[0]]) { - p[k[1]]=0; p[k[0]]=NEXOBS<1?-1:NFREQ; - } - else { - p[k[0]]=0; p[k[1]]=NEXOBS<1?-1:NFREQ; - } - } - if (m>=2) { - if (val[l[0]]==0.0&&val[l[1]]==0.0) { - p[l[0]]=-1; p[l[1]]=-1; - } - else if (val[l[0]]!=0.0&&val[l[1]]==0.0) { - p[l[0]]=1; p[l[1]]=-1; - } - else if (val[l[0]]==0.0&&val[l[1]]!=0.0) { - p[l[0]]=-1; p[l[1]]=1; - } - else if (ind->pri[l[1]]>ind->pri[l[0]]) { - p[l[1]]=1; p[l[0]]=NEXOBS<2?-1:NFREQ+1; - } - else { - p[l[0]]=1; p[l[1]]=NEXOBS<2?-1:NFREQ+1; - } - } - if (q>=2) { - if (val[r[0]]==0.0&&val[r[1]]==0.0) { - p[r[0]]=-1; p[r[1]]=-1; - } - else if (val[r[0]]!=0.0&&val[r[1]]==0.0) { - p[r[0]]=2; p[r[1]]=-1; - } - else if (val[r[0]]==0.0&&val[r[1]]!=0.0) { - p[r[0]]=-1; p[r[1]]=2; - } - else if (ind->pri[r[1]]>ind->pri[r[0]]) { - p[r[1]]=2; p[r[0]]=NEXOBS<3?-1:NFREQ+2; - } - else { - p[r[0]]=2; p[r[1]]=NEXOBS<3?-1:NFREQ+2; - } - } + if (stat) { + val[i] = str2num(buff, j, 14) + ind->shift[i]; + lli[i] = (uint8_t)str2num(buff, j + 14, 1) & 3; + /* measurement std from receiver, encoded */ + std[i] = str2num(buff, j + 15, 1); } - - /* save observation data */ - for (i=0;in;i++) { - if (p[i]<0||(val[i]==0.0&&lli[i]==0)) continue; - switch (ind->type[i]) { - case 0: obs->P[p[i]]=val[i]; - obs->code[p[i]]=ind->code[i]; - obs->Pstd[p[i]] = std[i] > 0 ? 0.01 * pow(2, std[i] + 5) : 0; - break; - case 1: obs->L[p[i]]=val[i]; - obs->LLI[p[i]]=lli[i]; - obs->Lstd[p[i]] = std[i] > 0 ? std[i] * 0.004 : 0; - break; - case 2: obs->D[p[i]]=(float)val[i]; break; - case 3: obs->SNR[p[i]]=val[i]; break; - } - trace(4, "obs: i=%d f=%d P=%14.3f L=%14.3f LLI=%d code=%d\n",i,p[i],obs->P[p[i]], - obs->L[p[i]],obs->LLI[p[i]],obs->code[p[i]]); + } + if (!stat) return 0; + + for (i = 0; i < NFREQ + NEXOBS; i++) { + obs->P[i] = obs->L[i] = 0.0; + obs->D[i] = obs->SNR[i] = 0.0; + obs->LLI[i] = obs->code[i] = 0; + obs->Lstd[i] = obs->Pstd[i] = 0.0; + } + /* assign position in observation data */ + for (i = n = m = q = 0; i < ind->n; i++) { + p[i] = (ver <= 2.11) ? ind->idx[i] : ind->pos[i]; + + if (ind->type[i] == 0 && p[i] == 0) k[n++] = i; /* C1? index */ + if (ind->type[i] == 0 && p[i] == 1) l[m++] = i; /* C2? index */ + if (ind->type[i] == 0 && p[i] == 2) r[q++] = i; /* C3? index */ + } + + /* if multiple codes (C1/P1,C2/P2), select higher priority */ + if (ver <= 2.11) { + if (n >= 2) { + if (val[k[0]] == 0.0 && val[k[1]] == 0.0) { + p[k[0]] = -1; + p[k[1]] = -1; + } else if (val[k[0]] != 0.0 && val[k[1]] == 0.0) { + p[k[0]] = 0; + p[k[1]] = -1; + } else if (val[k[0]] == 0.0 && val[k[1]] != 0.0) { + p[k[0]] = -1; + p[k[1]] = 0; + } else if (ind->pri[k[1]] > ind->pri[k[0]]) { + p[k[1]] = 0; + p[k[0]] = NEXOBS < 1 ? -1 : NFREQ; + } else { + p[k[0]] = 0; + p[k[1]] = NEXOBS < 1 ? -1 : NFREQ; + } } - char tstr[40]; - trace(4,"decode_obsdata: time=%s sat=%2d\n",time2str(obs->time,tstr,0),obs->sat); - return 1; + if (m >= 2) { + if (val[l[0]] == 0.0 && val[l[1]] == 0.0) { + p[l[0]] = -1; + p[l[1]] = -1; + } else if (val[l[0]] != 0.0 && val[l[1]] == 0.0) { + p[l[0]] = 1; + p[l[1]] = -1; + } else if (val[l[0]] == 0.0 && val[l[1]] != 0.0) { + p[l[0]] = -1; + p[l[1]] = 1; + } else if (ind->pri[l[1]] > ind->pri[l[0]]) { + p[l[1]] = 1; + p[l[0]] = NEXOBS < 2 ? -1 : NFREQ + 1; + } else { + p[l[0]] = 1; + p[l[1]] = NEXOBS < 2 ? -1 : NFREQ + 1; + } + } + if (q >= 2) { + if (val[r[0]] == 0.0 && val[r[1]] == 0.0) { + p[r[0]] = -1; + p[r[1]] = -1; + } else if (val[r[0]] != 0.0 && val[r[1]] == 0.0) { + p[r[0]] = 2; + p[r[1]] = -1; + } else if (val[r[0]] == 0.0 && val[r[1]] != 0.0) { + p[r[0]] = -1; + p[r[1]] = 2; + } else if (ind->pri[r[1]] > ind->pri[r[0]]) { + p[r[1]] = 2; + p[r[0]] = NEXOBS < 3 ? -1 : NFREQ + 2; + } else { + p[r[0]] = 2; + p[r[1]] = NEXOBS < 3 ? -1 : NFREQ + 2; + } + } + } + + /* save observation data */ + for (i = 0; i < ind->n; i++) { + if (p[i] < 0 || (val[i] == 0.0 && lli[i] == 0)) continue; + switch (ind->type[i]) { + case 0: + obs->P[p[i]] = val[i]; + obs->code[p[i]] = ind->code[i]; + obs->Pstd[p[i]] = std[i] > 0 ? 0.01 * pow(2, std[i] + 5) : 0; + break; + case 1: + obs->L[p[i]] = val[i]; + obs->LLI[p[i]] = lli[i]; + obs->Lstd[p[i]] = std[i] > 0 ? std[i] * 0.004 : 0; + break; + case 2: + obs->D[p[i]] = (float)val[i]; + break; + case 3: + obs->SNR[p[i]] = val[i]; + break; + } + trace(4, "obs: i=%d f=%d P=%14.3f L=%14.3f LLI=%d code=%d\n", i, p[i], obs->P[p[i]], + obs->L[p[i]], obs->LLI[p[i]], obs->code[p[i]]); + } + char tstr[40]; + trace(4, "decode_obsdata: time=%s sat=%2d\n", time2str(obs->time, tstr, 0), obs->sat); + return 1; } /* save cycle slips ----------------------------------------------------------*/ -static void saveslips(uint8_t slips[][NFREQ+NEXOBS], obsd_t *data) -{ - int i; - for (i=0;iLLI[i]&1) slips[data->sat-1][i]|=LLI_SLIP; - } +static void saveslips(uint8_t slips[][NFREQ + NEXOBS], obsd_t *data) { + int i; + for (i = 0; i < NFREQ + NEXOBS; i++) { + if (data->LLI[i] & 1) slips[data->sat - 1][i] |= LLI_SLIP; + } } /* restore cycle slips -------------------------------------------------------*/ -static void restslips(uint8_t slips[][NFREQ+NEXOBS], obsd_t *data) -{ - int i; - for (i=0;isat-1][i]&1) data->LLI[i]|=LLI_SLIP; - slips[data->sat-1][i]=0; - } +static void restslips(uint8_t slips[][NFREQ + NEXOBS], obsd_t *data) { + int i; + for (i = 0; i < NFREQ + NEXOBS; i++) { + if (slips[data->sat - 1][i] & 1) data->LLI[i] |= LLI_SLIP; + slips[data->sat - 1][i] = 0; + } } /* add observation data ------------------------------------------------------*/ -static int addobsdata(obs_t *obs, const obsd_t *data) -{ - obsd_t *obs_data; - - if (obs->nmax<=obs->n) { - if (obs->nmax<=0) obs->nmax=NINCOBS; else obs->nmax*=2; - if (!(obs_data=(obsd_t *)realloc(obs->data,sizeof(obsd_t)*obs->nmax))) { - trace(1,"addobsdata: malloc error n=%zdx%d\n",sizeof(obsd_t),obs->nmax); - free(obs->data); obs->data=NULL; obs->n=obs->nmax=0; - return -1; - } - obs->data=obs_data; - } - obs->data[obs->n++]=*data; - return 1; +static int addobsdata(obs_t *obs, const obsd_t *data) { + obsd_t *obs_data; + + if (obs->nmax <= obs->n) { + if (obs->nmax <= 0) + obs->nmax = NINCOBS; + else + obs->nmax *= 2; + if (!(obs_data = (obsd_t *)realloc(obs->data, sizeof(obsd_t) * obs->nmax))) { + trace(1, "addobsdata: malloc error n=%zdx%d\n", sizeof(obsd_t), obs->nmax); + free(obs->data); + obs->data = NULL; + obs->n = obs->nmax = 0; + return -1; + } + obs->data = obs_data; + } + obs->data[obs->n++] = *data; + return 1; } /* set system mask -----------------------------------------------------------*/ -static int set_sysmask(const char *opt) -{ - const char *p; - int mask=SYS_NONE; - - if (!(p=strstr(opt,"-SYS="))) return SYS_ALL; - - for (p+=5;*p&&*p!=' ';p++) { - switch (*p) { - case 'G': mask|=SYS_GPS; break; - case 'R': mask|=SYS_GLO; break; - case 'E': mask|=SYS_GAL; break; - case 'J': mask|=SYS_QZS; break; - case 'C': mask|=SYS_CMP; break; - case 'I': mask|=SYS_IRN; break; - case 'S': mask|=SYS_SBS; break; - } +static int set_sysmask(const char *opt) { + const char *p; + int mask = SYS_NONE; + + if (!(p = strstr(opt, "-SYS="))) return SYS_ALL; + + for (p += 5; *p && *p != ' '; p++) { + switch (*p) { + case 'G': + mask |= SYS_GPS; + break; + case 'R': + mask |= SYS_GLO; + break; + case 'E': + mask |= SYS_GAL; + break; + case 'J': + mask |= SYS_QZS; + break; + case 'C': + mask |= SYS_CMP; + break; + case 'I': + mask |= SYS_IRN; + break; + case 'S': + mask |= SYS_SBS; + break; } - return mask; + } + return mask; } /* set signal index ----------------------------------------------------------*/ -static void set_index(double ver, int sys, const char *opt, - char tobs[MAXOBSTYPE][4], sigind_t *ind) -{ - (void)ver; - const char *p; - char str[8],*optstr=""; - double shift; - int i,j,k,n; - - for (i=n=0;*tobs[i];i++,n++) { - ind->code[i]=obs2code(tobs[i]+1); - ind->type[i]=(p=strchr(obscodes,tobs[i][0]))?(int)(p-obscodes):0; - ind->idx[i]=code2idx(sys,ind->code[i]); - ind->pri[i]=getcodepri(sys,ind->code[i],opt); - ind->pos[i]=-1; - } - /* parse phase shift options */ - switch (sys) { - case SYS_GPS: optstr="-GL%2s=%lf"; break; - case SYS_GLO: optstr="-RL%2s=%lf"; break; - case SYS_GAL: optstr="-EL%2s=%lf"; break; - case SYS_QZS: optstr="-JL%2s=%lf"; break; - case SYS_SBS: optstr="-SL%2s=%lf"; break; - case SYS_CMP: optstr="-CL%2s=%lf"; break; - case SYS_IRN: optstr="-IL%2s=%lf"; break; - } - for (p=opt;p&&(p=strchr(p,'-'));p++) { - if (sscanf(p,optstr,str,&shift)<2) continue; - for (i=0;icode[i]),str)) continue; - ind->shift[i]=shift; - trace(2,"phase shift: sys=%2d tobs=%s shift=%.3f\n",sys, - tobs[i],shift); - } +static void set_index(double ver, int sys, const char *opt, char tobs[MAXOBSTYPE][4], + sigind_t *ind) { + (void)ver; + const char *p; + char str[8], *optstr = ""; + double shift; + int i, j, k, n; + + for (i = n = 0; *tobs[i]; i++, n++) { + ind->code[i] = obs2code(tobs[i] + 1); + ind->type[i] = (p = strchr(obscodes, tobs[i][0])) ? (int)(p - obscodes) : 0; + ind->idx[i] = code2idx(sys, ind->code[i]); + ind->pri[i] = getcodepri(sys, ind->code[i], opt); + ind->pos[i] = -1; + } + /* parse phase shift options */ + switch (sys) { + case SYS_GPS: + optstr = "-GL%2s=%lf"; + break; + case SYS_GLO: + optstr = "-RL%2s=%lf"; + break; + case SYS_GAL: + optstr = "-EL%2s=%lf"; + break; + case SYS_QZS: + optstr = "-JL%2s=%lf"; + break; + case SYS_SBS: + optstr = "-SL%2s=%lf"; + break; + case SYS_CMP: + optstr = "-CL%2s=%lf"; + break; + case SYS_IRN: + optstr = "-IL%2s=%lf"; + break; + } + for (p = opt; p && (p = strchr(p, '-')); p++) { + if (sscanf(p, optstr, str, &shift) < 2) continue; + for (i = 0; i < n; i++) { + if (strcmp(code2obs(ind->code[i]), str)) continue; + ind->shift[i] = shift; + trace(2, "phase shift: sys=%2d tobs=%s shift=%.3f\n", sys, tobs[i], shift); } - /* assign index for highest priority code */ - for (i=0;iidx[j]==i&&ind->pri[j]&&(k<0||ind->pri[j]>ind->pri[k])) { - k=j; - } - } - if (k<0) continue; - - for (j=0;jcode[j]==ind->code[k]) ind->pos[j]=i; - } + } + /* assign index for highest priority code */ + for (i = 0; i < NFREQ; i++) { + for (j = 0, k = -1; j < n; j++) { + if (ind->idx[j] == i && ind->pri[j] && (k < 0 || ind->pri[j] > ind->pri[k])) { + k = j; + } } - /* assign index of extended observation data */ - for (i=0;icode[j]&&ind->pri[j]&&ind->pos[j]<0) break; - } - if (j>=n) break; + if (k < 0) continue; - for (k=0;kcode[k]==ind->code[j]) ind->pos[k]=NFREQ+i; - } + for (j = 0; j < n; j++) { + if (ind->code[j] == ind->code[k]) ind->pos[j] = i; } - /* list rejected observation types */ - for (i=0;icode[i]||!ind->pri[i]||ind->pos[i]>=0) continue; - trace(4,"reject obs type: sys=%2d, obs=%s\n",sys,tobs[i]); + } + /* assign index of extended observation data */ + for (i = 0; i < NEXOBS; i++) { + for (j = 0; j < n; j++) { + if (ind->code[j] && ind->pri[j] && ind->pos[j] < 0) break; } - ind->n=n; - -#ifdef RTK_DISABLED /* for debug */ - for (int i=0;icode[i],ind->pri[i],ind->idx[i],ind->pos[i], - ind->shift[i]); + if (j >= n) break; + + for (k = 0; k < n; k++) { + if (ind->code[k] == ind->code[j]) ind->pos[k] = NFREQ + i; } + } + /* list rejected observation types */ + for (i = 0; i < n; i++) { + if (!ind->code[i] || !ind->pri[i] || ind->pos[i] >= 0) continue; + trace(4, "reject obs type: sys=%2d, obs=%s\n", sys, tobs[i]); + } + ind->n = n; + +#ifdef RTK_DISABLED /* for debug */ + for (int i = 0; i < n; i++) { + trace(2, "set_index: sys=%2d,tobs=%s code=%2d pri=%2d idx=%d pos=%d shift=%5.2f\n", sys, + tobs[i], ind->code[i], ind->pri[i], ind->idx[i], ind->pos[i], ind->shift[i]); + } #endif } /* read RINEX observation data body ------------------------------------------*/ -static int readrnxobsb(FILE *fp, const char *opt, double ver, int *tsys, - char tobs[][MAXOBSTYPE][4], int *flag, obsd_t *data, - sta_t *sta) -{ - gtime_t time={0}; - sigind_t index[RNX_NUMSYS]={{0}}; - char buff[MAXRNXLEN]; - int i=0,n=0,nsat=0,sats[MAXOBS]={0},mask; - - /* set system mask */ - mask=set_sysmask(opt); - - /* set signal index */ -#if RNX_NUMSYS>=1 - set_index(ver,SYS_GPS,opt,tobs[RNX_SYS_GPS],index ); +static int readrnxobsb(FILE *fp, const char *opt, double ver, int *tsys, char tobs[][MAXOBSTYPE][4], + int *flag, obsd_t *data, sta_t *sta) { + gtime_t time = {0}; + sigind_t index[RNX_NUMSYS] = {{0}}; + char buff[MAXRNXLEN]; + int i = 0, n = 0, nsat = 0, sats[MAXOBS] = {0}, mask; + + /* set system mask */ + mask = set_sysmask(opt); + + /* set signal index */ +#if RNX_NUMSYS >= 1 + set_index(ver, SYS_GPS, opt, tobs[RNX_SYS_GPS], index); #endif -#if RNX_NUMSYS>=2 - set_index(ver,SYS_GLO,opt,tobs[RNX_SYS_GLO],index+1); +#if RNX_NUMSYS >= 2 + set_index(ver, SYS_GLO, opt, tobs[RNX_SYS_GLO], index + 1); #endif -#if RNX_NUMSYS>=3 - set_index(ver,SYS_GAL,opt,tobs[RNX_SYS_GAL],index+2); +#if RNX_NUMSYS >= 3 + set_index(ver, SYS_GAL, opt, tobs[RNX_SYS_GAL], index + 2); #endif -#if RNX_NUMSYS>=4 - set_index(ver,SYS_QZS,opt,tobs[RNX_SYS_QZS],index+3); +#if RNX_NUMSYS >= 4 + set_index(ver, SYS_QZS, opt, tobs[RNX_SYS_QZS], index + 3); #endif -#if RNX_NUMSYS>=5 - set_index(ver,SYS_SBS,opt,tobs[RNX_SYS_SBS],index+4); +#if RNX_NUMSYS >= 5 + set_index(ver, SYS_SBS, opt, tobs[RNX_SYS_SBS], index + 4); #endif -#if RNX_NUMSYS>=6 - set_index(ver,SYS_CMP,opt,tobs[RNX_SYS_CMP],index+5); +#if RNX_NUMSYS >= 6 + set_index(ver, SYS_CMP, opt, tobs[RNX_SYS_CMP], index + 5); #endif -#if RNX_NUMSYS>=7 - set_index(ver,SYS_IRN,opt,tobs[RNX_SYS_IRN],index+6); +#if RNX_NUMSYS >= 7 + set_index(ver, SYS_IRN, opt, tobs[RNX_SYS_IRN], index + 6); #endif - - /* read record */ - while (fgets(buff,MAXRNXLEN,fp)) { - - /* decode observation epoch */ - if (i==0) { - if ((nsat=decode_obsepoch(fp,buff,ver,&time,flag,sats))<=0 && (*flag != 5)) { - continue; - } - if (*flag == 5) { - data[0].eventime = time; - return 0; - } - } - else if ((*flag<=2||*flag==6)&&nnsat) return n; + /* decode RINEX observation data */ + if (decode_obsdata(fp, buff, ver, mask, index, data + n)) n++; + } else if (*flag == 3 || *flag == 4) { /* new site or header info follows */ + + /* decode RINEX observation data file header */ + decode_obsh(fp, buff, ver, tsys, tobs, NULL, sta); } - return -1; + if (++i > nsat) return n; + } + return -1; } /* read RINEX observation data -----------------------------------------------*/ -static int readrnxobs(FILE *fp, gtime_t ts, gtime_t te, double tint, - const char *opt, int rcv, double ver, int *tsys, - char tobs[][MAXOBSTYPE][4], obs_t *obs, sta_t *sta) -{ - gtime_t eventime={0},time0={0},time1={0}; - obsd_t *data; - uint8_t slips[MAXSAT][NFREQ+NEXOBS]={{0}}; - int i,n,n1=0,flag=0,stat=0; - double dtime1=0; - - trace(4,"readrnxobs: rcv=%d ver=%.2f tsys=%d\n",rcv,ver,*tsys); - - if (!obs||rcv>MAXRCV) return 0; - - if (!(data=(obsd_t *)malloc(sizeof(obsd_t)*MAXOBS))) return 0; - - /* read RINEX observation data body */ - while ((n=readrnxobsb(fp,opt,ver,tsys,tobs,&flag,data,sta))>=0&&stat>=0) { - - if (flag == 5) { - eventime = data[0].eventime; - n = readrnxobsb(fp,opt,ver,tsys,tobs,&flag,data,sta); - if (fabs(timediff(data[0].time,time1)-dtime1)>=DTTOL) - n = readrnxobsb(fp,opt,ver,tsys,tobs,&flag,data,sta); - } - - if (eventime.time==0 || obs->n-n1<=0 || timediff(eventime,time1)>=0) { - for (i=0;idata[obs->n-i-1].eventime = eventime; - for (i=0;i GPST */ - if (*tsys==TSYS_UTC) data[i].time=utc2gpst(data[i].time); + if (!obs || rcv > MAXRCV) return 0; - /* save cycle slip */ - saveslips(slips,data+i); - } - /* screen data by time */ - if (n>0&&!screent(data[0].time,ts,te,tint)) continue; - - for (i=0;i= 0 && stat >= 0) { + if (flag == 5) { + eventime = data[0].eventime; + n = readrnxobsb(fp, opt, ver, tsys, tobs, &flag, data, sta); + if (fabs(timediff(data[0].time, time1) - dtime1) >= DTTOL) + n = readrnxobsb(fp, opt, ver, tsys, tobs, &flag, data, sta); + } - /* save obs data */ - if ((stat=addobsdata(obs,data+i))<0) break; - } - n1=n;dtime1=timediff(data[0].time,time1);time1=data[0].time; + if (eventime.time == 0 || obs->n - n1 <= 0 || timediff(eventime, time1) >= 0) { + for (i = 0; i < n; i++) data[i].eventime = eventime; + } else { + /* add event to previous epoch if delayed */ + for (i = 0; i < n1; i++) obs->data[obs->n - i - 1].eventime = eventime; + for (i = 0; i < n; i++) data[i].eventime = time0; } - trace(4,"readrnxobs: nobs=%d stat=%d\n",obs->n,stat); + /* set to zero eventime for the next iteration */ + eventime.time = 0; + eventime.sec = 0; - free(data); + for (i = 0; i < n; i++) { + /* UTC -> GPST */ + if (*tsys == TSYS_UTC) data[i].time = utc2gpst(data[i].time); - return stat; -} -/* decode ephemeris ----------------------------------------------------------*/ -static int decode_eph(double ver, int sat, gtime_t toc, const double *data, - eph_t *eph) -{ - eph_t eph0={0}; - int sys; + /* save cycle slip */ + saveslips(slips, data + i); + } + /* screen data by time */ + if (n > 0 && !screent(data[0].time, ts, te, tint)) continue; - trace(4,"decode_eph: ver=%.2f sat=%2d\n",ver,sat); + for (i = 0; i < n; i++) { + /* restore cycle slip */ + restslips(slips, data + i); - sys=satsys(sat,NULL); + data[i].rcv = (uint8_t)rcv; - if (!(sys&(SYS_GPS|SYS_GAL|SYS_QZS|SYS_CMP|SYS_IRN))) { - trace(4,"ephemeris error: invalid satellite sat=%2d\n",sat); - return 0; + /* save obs data */ + if ((stat = addobsdata(obs, data + i)) < 0) break; } - *eph=eph0; - - eph->sat=sat; - eph->toc=toc; + n1 = n; + dtime1 = timediff(data[0].time, time1); + time1 = data[0].time; + } + trace(4, "readrnxobs: nobs=%d stat=%d\n", obs->n, stat); - eph->f0=data[0]; - eph->f1=data[1]; - eph->f2=data[2]; + free(data); - eph->A=SQR(data[10]); eph->e=data[ 8]; eph->i0 =data[15]; eph->OMG0=data[13]; - eph->omg =data[17]; eph->M0 =data[ 6]; eph->deln=data[ 5]; eph->OMGd=data[18]; - eph->idot=data[19]; eph->crc=data[16]; eph->crs =data[ 4]; eph->cuc =data[ 7]; - eph->cus =data[ 9]; eph->cic=data[12]; eph->cis =data[14]; + return stat; +} +/* decode ephemeris ----------------------------------------------------------*/ +static int decode_eph(double ver, int sat, gtime_t toc, const double *data, eph_t *eph) { + eph_t eph0 = {0}; + int sys; - if (sys==SYS_GPS||sys==SYS_QZS) { - eph->iode=(int)data[ 3]; /* IODE */ - eph->iodc=(int)data[26]; /* IODC */ - eph->toes= data[11]; /* Toe (s) in GPS week */ - eph->week=(int)data[21]; /* GPS week */ - eph->toe=adjweek(gpst2time(eph->week,data[11]),toc); - eph->ttr=adjweek(gpst2time(eph->week,data[27]),toc); + trace(4, "decode_eph: ver=%.2f sat=%2d\n", ver, sat); - eph->code=(int)data[20]; /* GPS: codes on L2 ch */ - eph->svh =(int)data[24]; /* SV health */ - eph->sva=uraindex(data[23]); /* URA index (m->index) */ - eph->flag=(int)data[22]; /* GPS: L2 P data flag */ + sys = satsys(sat, NULL); - eph->tgd[0]= data[25]; /* TGD */ - if (sys==SYS_GPS) { - eph->fit=data[28]; /* fit interval (h) */ - } - else if (sys==SYS_QZS) { - eph->fit=data[28]==0.0?2:4; /* fit interval (0:2h,1:>2h) */ - } - } - else if (sys==SYS_GAL) { /* GAL ver.3 */ - eph->iode=(int)data[ 3]; /* IODnav */ - eph->toes= data[11]; /* Toe (s) in Galileo week */ - eph->week=(int)data[21]; /* Galileo week = GPS week */ - eph->toe=adjweek(gpst2time(eph->week,data[11]),toc); - eph->ttr=adjweek(gpst2time(eph->week,data[27]),toc); - - eph->code=(int)data[20]; /* data sources */ - /* bit 0 set: I/NAV E1-B */ - /* bit 1 set: F/NAV E5a-I */ - /* bit 2 set: I/NAV E5b-I */ - /* bit 8 set: af0-af2 toc are for E5a.E1 */ - /* bit 9 set: af0-af2 toc are for E5b.E1 */ - eph->svh =(int)data[24]; /* sv health */ - /* bit 0: E1B DVS */ - /* bit 1-2: E1B HS */ - /* bit 3: E5a DVS */ - /* bit 4-5: E5a HS */ - /* bit 6: E5b DVS */ - /* bit 7-8: E5b HS */ - eph->sva =sisa_index(data[23]); /* sisa (m->index) */ - - eph->tgd[0]= data[25]; /* BGD E5a/E1 */ - eph->tgd[1]= data[26]; /* BGD E5b/E1 */ - } - else if (sys==SYS_CMP) { /* BeiDou v.3.02 */ - eph->toc=bdt2gpst(eph->toc); /* bdt -> gpst */ - eph->iode=(int)data[ 3]; /* AODE */ - eph->iodc=(int)data[28]; /* AODC */ - eph->toes= data[11]; /* Toe (s) in BDT week */ - eph->week=(int)data[21]; /* bdt week */ - eph->toe=bdt2gpst(bdt2time(eph->week,data[11])); /* BDT -> GPST */ - eph->ttr=bdt2gpst(bdt2time(eph->week,data[27])); /* BDT -> GPST */ - eph->toe=adjweek(eph->toe,toc); - eph->ttr=adjweek(eph->ttr,toc); - - eph->svh =(int)data[24]; /* satH1 */ - eph->sva=uraindex(data[23]); /* URA index (m->index) */ - - eph->tgd[0]= data[25]; /* TGD1 B1/B3 */ - eph->tgd[1]= data[26]; /* TGD2 B2/B3 */ - } - else if (sys==SYS_IRN) { /* IRNSS v.3.03 */ - eph->iode=(int)data[ 3]; /* IODEC */ - eph->toes= data[11]; /* Toe (s) in IRNSS week */ - eph->week=(int)data[21]; /* IRNSS week */ - eph->toe=adjweek(gpst2time(eph->week,data[11]),toc); - eph->ttr=adjweek(gpst2time(eph->week,data[27]),toc); - eph->svh =(int)data[24]; /* SV health */ - eph->sva=uraindex(data[23]); /* URA index (m->index) */ - eph->tgd[0]= data[25]; /* TGD */ - } - if (eph->iode<0||1023iode) { - trace(2,"rinex nav invalid: sat=%2d iode=%d\n",sat,eph->iode); - } - if (eph->iodc<0||1023iodc) { - trace(2,"rinex nav invalid: sat=%2d iodc=%d\n",sat,eph->iodc); - } - return 1; + if (!(sys & (SYS_GPS | SYS_GAL | SYS_QZS | SYS_CMP | SYS_IRN))) { + trace(4, "ephemeris error: invalid satellite sat=%2d\n", sat); + return 0; + } + *eph = eph0; + + eph->sat = sat; + eph->toc = toc; + + eph->f0 = data[0]; + eph->f1 = data[1]; + eph->f2 = data[2]; + + eph->A = SQR(data[10]); + eph->e = data[8]; + eph->i0 = data[15]; + eph->OMG0 = data[13]; + eph->omg = data[17]; + eph->M0 = data[6]; + eph->deln = data[5]; + eph->OMGd = data[18]; + eph->idot = data[19]; + eph->crc = data[16]; + eph->crs = data[4]; + eph->cuc = data[7]; + eph->cus = data[9]; + eph->cic = data[12]; + eph->cis = data[14]; + + if (sys == SYS_GPS || sys == SYS_QZS) { + eph->iode = (int)data[3]; /* IODE */ + eph->iodc = (int)data[26]; /* IODC */ + eph->toes = data[11]; /* Toe (s) in GPS week */ + eph->week = (int)data[21]; /* GPS week */ + eph->toe = adjweek(gpst2time(eph->week, data[11]), toc); + eph->ttr = adjweek(gpst2time(eph->week, data[27]), toc); + + eph->code = (int)data[20]; /* GPS: codes on L2 ch */ + eph->svh = (int)data[24]; /* SV health */ + eph->sva = uraindex(data[23]); /* URA index (m->index) */ + eph->flag = (int)data[22]; /* GPS: L2 P data flag */ + + eph->tgd[0] = data[25]; /* TGD */ + if (sys == SYS_GPS) { + eph->fit = data[28]; /* fit interval (h) */ + } else if (sys == SYS_QZS) { + eph->fit = data[28] == 0.0 ? 2 : 4; /* fit interval (0:2h,1:>2h) */ + } + } else if (sys == SYS_GAL) { /* GAL ver.3 */ + eph->iode = (int)data[3]; /* IODnav */ + eph->toes = data[11]; /* Toe (s) in Galileo week */ + eph->week = (int)data[21]; /* Galileo week = GPS week */ + eph->toe = adjweek(gpst2time(eph->week, data[11]), toc); + eph->ttr = adjweek(gpst2time(eph->week, data[27]), toc); + + eph->code = (int)data[20]; /* data sources */ + /* bit 0 set: I/NAV E1-B */ + /* bit 1 set: F/NAV E5a-I */ + /* bit 2 set: I/NAV E5b-I */ + /* bit 8 set: af0-af2 toc are for E5a.E1 */ + /* bit 9 set: af0-af2 toc are for E5b.E1 */ + eph->svh = (int)data[24]; /* sv health */ + /* bit 0: E1B DVS */ + /* bit 1-2: E1B HS */ + /* bit 3: E5a DVS */ + /* bit 4-5: E5a HS */ + /* bit 6: E5b DVS */ + /* bit 7-8: E5b HS */ + eph->sva = sisa_index(data[23]); /* sisa (m->index) */ + + eph->tgd[0] = data[25]; /* BGD E5a/E1 */ + eph->tgd[1] = data[26]; /* BGD E5b/E1 */ + } else if (sys == SYS_CMP) { /* BeiDou v.3.02 */ + eph->toc = bdt2gpst(eph->toc); /* bdt -> gpst */ + eph->iode = (int)data[3]; /* AODE */ + eph->iodc = (int)data[28]; /* AODC */ + eph->toes = data[11]; /* Toe (s) in BDT week */ + eph->week = (int)data[21]; /* bdt week */ + eph->toe = bdt2gpst(bdt2time(eph->week, data[11])); /* BDT -> GPST */ + eph->ttr = bdt2gpst(bdt2time(eph->week, data[27])); /* BDT -> GPST */ + eph->toe = adjweek(eph->toe, toc); + eph->ttr = adjweek(eph->ttr, toc); + + eph->svh = (int)data[24]; /* satH1 */ + eph->sva = uraindex(data[23]); /* URA index (m->index) */ + + eph->tgd[0] = data[25]; /* TGD1 B1/B3 */ + eph->tgd[1] = data[26]; /* TGD2 B2/B3 */ + } else if (sys == SYS_IRN) { /* IRNSS v.3.03 */ + eph->iode = (int)data[3]; /* IODEC */ + eph->toes = data[11]; /* Toe (s) in IRNSS week */ + eph->week = (int)data[21]; /* IRNSS week */ + eph->toe = adjweek(gpst2time(eph->week, data[11]), toc); + eph->ttr = adjweek(gpst2time(eph->week, data[27]), toc); + eph->svh = (int)data[24]; /* SV health */ + eph->sva = uraindex(data[23]); /* URA index (m->index) */ + eph->tgd[0] = data[25]; /* TGD */ + } + if (eph->iode < 0 || 1023 < eph->iode) { + trace(2, "rinex nav invalid: sat=%2d iode=%d\n", sat, eph->iode); + } + if (eph->iodc < 0 || 1023 < eph->iodc) { + trace(2, "rinex nav invalid: sat=%2d iodc=%d\n", sat, eph->iodc); + } + return 1; } /* decode GLONASS ephemeris --------------------------------------------------*/ -static int decode_geph(double ver, int sat, gtime_t toc, double *data, - geph_t *geph) -{ - geph_t geph0={0}; - gtime_t tof; - double tow,tod; - int week,dow; - - trace(4,"decode_geph: ver=%.2f sat=%2d\n",ver,sat); - - if (satsys(sat,NULL)!=SYS_GLO) { - trace(4,"glonass ephemeris error: invalid satellite sat=%2d\n",sat); - return 0; - } - *geph=geph0; - - geph->sat=sat; - - /* Toc rounded by 15 min in utc */ - tow=time2gpst(toc,&week); - toc=gpst2time(week,floor((tow+450.0)/900.0)*900); - dow=(int)floor(tow/86400.0); - - /* time of frame in UTC */ - tod=ver<=2.99?data[2]:fmod(data[2],86400.0); /* Tod (v.2), Tow (v.3) in UTC */ - tof=gpst2time(week,tod+dow*86400.0); - tof=adjday(tof,toc); - - geph->toe=utc2gpst(toc); /* Toc (GPST) */ - geph->tof=utc2gpst(tof); /* Tof (GPST) */ - - /* IODE = Tb (7bit), Tb =index of UTC+3H within current day */ - geph->iode=(int)(fmod(tow+10800.0,86400.0)/900.0+0.5); - - geph->taun=-data[0]; /* -taun */ - geph->gamn= data[1]; /* +gamman */ +static int decode_geph(double ver, int sat, gtime_t toc, double *data, geph_t *geph) { + geph_t geph0 = {0}; + gtime_t tof; + double tow, tod; + int week, dow; - geph->pos[0]=data[3]*1E3; geph->pos[1]=data[7]*1E3; geph->pos[2]=data[11]*1E3; - geph->vel[0]=data[4]*1E3; geph->vel[1]=data[8]*1E3; geph->vel[2]=data[12]*1E3; - geph->acc[0]=data[5]*1E3; geph->acc[1]=data[9]*1E3; geph->acc[2]=data[13]*1E3; + trace(4, "decode_geph: ver=%.2f sat=%2d\n", ver, sat); - geph->svh=(int)data[ 6]; // MSB of 3 bit Bn - geph->frq=(int)data[10]; - geph->age=(int)data[14]; - - if (ver >= 3.05) { - geph->flags = (int)data[15]; // Status flags - geph->dtaun = data[16]; - geph->sva = data[17]; - geph->svh |= ((int)data[18]) << 1; // Extended SVH - } - /* some receiver output >128 for minus frequency number */ - if (geph->frq>128) geph->frq-=256; + if (satsys(sat, NULL) != SYS_GLO) { + trace(4, "glonass ephemeris error: invalid satellite sat=%2d\n", sat); + return 0; + } + *geph = geph0; + + geph->sat = sat; + + /* Toc rounded by 15 min in utc */ + tow = time2gpst(toc, &week); + toc = gpst2time(week, floor((tow + 450.0) / 900.0) * 900); + dow = (int)floor(tow / 86400.0); + + /* time of frame in UTC */ + tod = ver <= 2.99 ? data[2] : fmod(data[2], 86400.0); /* Tod (v.2), Tow (v.3) in UTC */ + tof = gpst2time(week, tod + dow * 86400.0); + tof = adjday(tof, toc); + + geph->toe = utc2gpst(toc); /* Toc (GPST) */ + geph->tof = utc2gpst(tof); /* Tof (GPST) */ + + /* IODE = Tb (7bit), Tb =index of UTC+3H within current day */ + geph->iode = (int)(fmod(tow + 10800.0, 86400.0) / 900.0 + 0.5); + + geph->taun = -data[0]; /* -taun */ + geph->gamn = data[1]; /* +gamman */ + + geph->pos[0] = data[3] * 1E3; + geph->pos[1] = data[7] * 1E3; + geph->pos[2] = data[11] * 1E3; + geph->vel[0] = data[4] * 1E3; + geph->vel[1] = data[8] * 1E3; + geph->vel[2] = data[12] * 1E3; + geph->acc[0] = data[5] * 1E3; + geph->acc[1] = data[9] * 1E3; + geph->acc[2] = data[13] * 1E3; + + geph->svh = (int)data[6]; // MSB of 3 bit Bn + geph->frq = (int)data[10]; + geph->age = (int)data[14]; + + if (ver >= 3.05) { + geph->flags = (int)data[15]; // Status flags + geph->dtaun = data[16]; + geph->sva = data[17]; + geph->svh |= ((int)data[18]) << 1; // Extended SVH + } + /* some receiver output >128 for minus frequency number */ + if (geph->frq > 128) geph->frq -= 256; - if (geph->frqfrq) { - trace(2,"rinex gnav invalid freq: sat=%2d fn=%d\n",sat,geph->frq); - } - return 1; + if (geph->frq < MINFREQ_GLO || MAXFREQ_GLO < geph->frq) { + trace(2, "rinex gnav invalid freq: sat=%2d fn=%d\n", sat, geph->frq); + } + return 1; } /* decode GEO ephemeris ------------------------------------------------------*/ -static int decode_seph(double ver, int sat, gtime_t toc, double *data, - seph_t *seph) -{ - seph_t seph0={0}; - int week; +static int decode_seph(double ver, int sat, gtime_t toc, double *data, seph_t *seph) { + seph_t seph0 = {0}; + int week; - trace(4,"decode_seph: ver=%.2f sat=%2d\n",ver,sat); + trace(4, "decode_seph: ver=%.2f sat=%2d\n", ver, sat); - if (satsys(sat,NULL)!=SYS_SBS) { - trace(4,"geo ephemeris error: invalid satellite sat=%2d\n",sat); - return 0; - } - *seph=seph0; + if (satsys(sat, NULL) != SYS_SBS) { + trace(4, "geo ephemeris error: invalid satellite sat=%2d\n", sat); + return 0; + } + *seph = seph0; - seph->sat=sat; - seph->t0 =toc; + seph->sat = sat; + seph->t0 = toc; - time2gpst(toc,&week); - seph->tof=adjweek(gpst2time(week,data[2]),toc); + time2gpst(toc, &week); + seph->tof = adjweek(gpst2time(week, data[2]), toc); - seph->af0=data[0]; - seph->af1=data[1]; + seph->af0 = data[0]; + seph->af1 = data[1]; - seph->pos[0]=data[3]*1E3; seph->pos[1]=data[7]*1E3; seph->pos[2]=data[11]*1E3; - seph->vel[0]=data[4]*1E3; seph->vel[1]=data[8]*1E3; seph->vel[2]=data[12]*1E3; - seph->acc[0]=data[5]*1E3; seph->acc[1]=data[9]*1E3; seph->acc[2]=data[13]*1E3; + seph->pos[0] = data[3] * 1E3; + seph->pos[1] = data[7] * 1E3; + seph->pos[2] = data[11] * 1E3; + seph->vel[0] = data[4] * 1E3; + seph->vel[1] = data[8] * 1E3; + seph->vel[2] = data[12] * 1E3; + seph->acc[0] = data[5] * 1E3; + seph->acc[1] = data[9] * 1E3; + seph->acc[2] = data[13] * 1E3; - seph->svh=(int)data[6]; - seph->sva=uraindex(data[10]); + seph->svh = (int)data[6]; + seph->sva = uraindex(data[10]); - return 1; + return 1; } /* read RINEX navigation data body -------------------------------------------*/ -static int readrnxnavb(FILE *fp, const char *opt, double ver, int sys, - int *type, eph_t *eph, geph_t *geph, seph_t *seph) -{ - gtime_t toc; - double data[64]; - int i=0,j,prn,sat=0,sp=3,mask; - char buff[MAXRNXLEN],id[8]="",*p; - - trace(4,"readrnxnavb: ver=%.2f sys=%d\n",ver,sys); - - /* set system mask */ - mask=set_sysmask(opt); - - // Number of elements for GLONASS. - int nglo = ver >= 3.05 ? 19 : 15; - - while (fgets(buff,MAXRNXLEN,fp)) { - - if (i==0) { - - /* decode satellite field */ - if (ver>=3.0||sys==SYS_GAL||sys==SYS_QZS) { /* ver.3 or GAL/QZS */ - snprintf(id,8,"%.3s",buff); - sat=satid2no(id); - sp=4; - if (ver>=3.0) { - sys=satsys(sat,NULL); - if (!sys) { - sys=(id[0]=='S')?SYS_SBS:((id[0]=='R')?SYS_GLO:SYS_GPS); - } - } - } - else { - prn=(int)str2num(buff,0,2); - - if (sys==SYS_SBS) { - sat=satno(SYS_SBS,prn+100); - } - else if (sys==SYS_GLO) { - sat=satno(SYS_GLO,prn); - } - else if (93<=prn&&prn<=97) { /* extension */ - sat=satno(SYS_QZS,prn+100); - } - else sat=satno(SYS_GPS,prn); - } - /* decode Toc field */ - if (str2time(buff+sp,0,19,&toc)) { - trace(2,"rinex nav toc error: %23.23s\n",buff); - return 0; - } - /* decode data fields */ - for (j=0,p=buff+sp+19;j<3;j++,p+=19) { - data[i++]=str2num(p,0,19); - } - } - else { - /* decode data fields */ - for (j=0,p=buff+sp;j<4;j++,p+=19) { - data[i++]=str2num(p,0,19); - } - /* decode ephemeris */ - if (sys==SYS_GLO&&i>=nglo) { - if (!(mask&sys)) return 0; - *type=1; - return decode_geph(ver,sat,toc,data,geph); - } - else if (sys==SYS_SBS&&i>=15) { - if (!(mask&sys)) return 0; - *type=2; - return decode_seph(ver,sat,toc,data,seph); - } - else if (i>=31) { - if (!(mask&sys)) return 0; - *type=0; - return decode_eph(ver,sat,toc,data,eph); - } - } +static int readrnxnavb(FILE *fp, const char *opt, double ver, int sys, int *type, eph_t *eph, + geph_t *geph, seph_t *seph) { + gtime_t toc; + double data[64]; + int i = 0, j, prn, sat = 0, sp = 3, mask; + char buff[MAXRNXLEN], id[8] = "", *p; + + trace(4, "readrnxnavb: ver=%.2f sys=%d\n", ver, sys); + + /* set system mask */ + mask = set_sysmask(opt); + + // Number of elements for GLONASS. + int nglo = ver >= 3.05 ? 19 : 15; + + while (fgets(buff, MAXRNXLEN, fp)) { + if (i == 0) { + /* decode satellite field */ + if (ver >= 3.0 || sys == SYS_GAL || sys == SYS_QZS) { /* ver.3 or GAL/QZS */ + snprintf(id, 8, "%.3s", buff); + sat = satid2no(id); + sp = 4; + if (ver >= 3.0) { + sys = satsys(sat, NULL); + if (!sys) { + sys = (id[0] == 'S') ? SYS_SBS : ((id[0] == 'R') ? SYS_GLO : SYS_GPS); + } + } + } else { + prn = (int)str2num(buff, 0, 2); + + if (sys == SYS_SBS) { + sat = satno(SYS_SBS, prn + 100); + } else if (sys == SYS_GLO) { + sat = satno(SYS_GLO, prn); + } else if (93 <= prn && prn <= 97) { /* extension */ + sat = satno(SYS_QZS, prn + 100); + } else + sat = satno(SYS_GPS, prn); + } + /* decode Toc field */ + if (str2time(buff + sp, 0, 19, &toc)) { + trace(2, "rinex nav toc error: %23.23s\n", buff); + return 0; + } + /* decode data fields */ + for (j = 0, p = buff + sp + 19; j < 3; j++, p += 19) { + data[i++] = str2num(p, 0, 19); + } + } else { + /* decode data fields */ + for (j = 0, p = buff + sp; j < 4; j++, p += 19) { + data[i++] = str2num(p, 0, 19); + } + /* decode ephemeris */ + if (sys == SYS_GLO && i >= nglo) { + if (!(mask & sys)) return 0; + *type = 1; + return decode_geph(ver, sat, toc, data, geph); + } else if (sys == SYS_SBS && i >= 15) { + if (!(mask & sys)) return 0; + *type = 2; + return decode_seph(ver, sat, toc, data, seph); + } else if (i >= 31) { + if (!(mask & sys)) return 0; + *type = 0; + return decode_eph(ver, sat, toc, data, eph); + } } - return -1; + } + return -1; } /* add ephemeris to navigation data ------------------------------------------*/ -static int add_eph(nav_t *nav, const eph_t *eph) -{ - eph_t *nav_eph; - - if (nav->nmax<=nav->n) { - nav->nmax+=1024; - if (!(nav_eph=(eph_t *)realloc(nav->eph,sizeof(eph_t)*nav->nmax))) { - trace(1,"decode_eph malloc error: n=%d\n",nav->nmax); - free(nav->eph); nav->eph=NULL; nav->n=nav->nmax=0; - return 0; - } - nav->eph=nav_eph; - } - nav->eph[nav->n++]=*eph; - return 1; -} -static int add_geph(nav_t *nav, const geph_t *geph) -{ - geph_t *nav_geph; - - if (nav->ngmax<=nav->ng) { - nav->ngmax+=1024; - if (!(nav_geph=(geph_t *)realloc(nav->geph,sizeof(geph_t)*nav->ngmax))) { - trace(1,"decode_geph malloc error: n=%d\n",nav->ngmax); - free(nav->geph); nav->geph=NULL; nav->ng=nav->ngmax=0; - return 0; - } - nav->geph=nav_geph; - } - nav->geph[nav->ng++]=*geph; - return 1; -} -static int add_seph(nav_t *nav, const seph_t *seph) -{ - seph_t *nav_seph; - - if (nav->nsmax<=nav->ns) { - nav->nsmax+=1024; - if (!(nav_seph=(seph_t *)realloc(nav->seph,sizeof(seph_t)*nav->nsmax))) { - trace(1,"decode_seph malloc error: n=%d\n",nav->nsmax); - free(nav->seph); nav->seph=NULL; nav->ns=nav->nsmax=0; - return 0; - } - nav->seph=nav_seph; - } - nav->seph[nav->ns++]=*seph; - return 1; +static int add_eph(nav_t *nav, const eph_t *eph) { + eph_t *nav_eph; + + if (nav->nmax <= nav->n) { + nav->nmax += 1024; + if (!(nav_eph = (eph_t *)realloc(nav->eph, sizeof(eph_t) * nav->nmax))) { + trace(1, "decode_eph malloc error: n=%d\n", nav->nmax); + free(nav->eph); + nav->eph = NULL; + nav->n = nav->nmax = 0; + return 0; + } + nav->eph = nav_eph; + } + nav->eph[nav->n++] = *eph; + return 1; +} +static int add_geph(nav_t *nav, const geph_t *geph) { + geph_t *nav_geph; + + if (nav->ngmax <= nav->ng) { + nav->ngmax += 1024; + if (!(nav_geph = (geph_t *)realloc(nav->geph, sizeof(geph_t) * nav->ngmax))) { + trace(1, "decode_geph malloc error: n=%d\n", nav->ngmax); + free(nav->geph); + nav->geph = NULL; + nav->ng = nav->ngmax = 0; + return 0; + } + nav->geph = nav_geph; + } + nav->geph[nav->ng++] = *geph; + return 1; +} +static int add_seph(nav_t *nav, const seph_t *seph) { + seph_t *nav_seph; + + if (nav->nsmax <= nav->ns) { + nav->nsmax += 1024; + if (!(nav_seph = (seph_t *)realloc(nav->seph, sizeof(seph_t) * nav->nsmax))) { + trace(1, "decode_seph malloc error: n=%d\n", nav->nsmax); + free(nav->seph); + nav->seph = NULL; + nav->ns = nav->nsmax = 0; + return 0; + } + nav->seph = nav_seph; + } + nav->seph[nav->ns++] = *seph; + return 1; } /* read RINEX navigation data ------------------------------------------------*/ -static int readrnxnav(FILE *fp, const char *opt, double ver, int sys, - nav_t *nav) -{ - eph_t eph; - geph_t geph; - seph_t seph; - int stat,type; - - trace(3,"readrnxnav: ver=%.2f sys=%d\n",ver,sys); - - if (!nav) return 0; - - /* read RINEX navigation data body */ - while ((stat=readrnxnavb(fp,opt,ver,sys,&type,&eph,&geph,&seph))>=0) { - - /* add ephemeris to navigation data */ - if (stat) { - switch (type) { - case 1 : stat=add_geph(nav,&geph); break; - case 2 : stat=add_seph(nav,&seph); break; - default: stat=add_eph (nav,&eph ); break; - } - if (!stat) return 0; - } +static int readrnxnav(FILE *fp, const char *opt, double ver, int sys, nav_t *nav) { + eph_t eph; + geph_t geph; + seph_t seph; + int stat, type; + + trace(3, "readrnxnav: ver=%.2f sys=%d\n", ver, sys); + + if (!nav) return 0; + + /* read RINEX navigation data body */ + while ((stat = readrnxnavb(fp, opt, ver, sys, &type, &eph, &geph, &seph)) >= 0) { + /* add ephemeris to navigation data */ + if (stat) { + switch (type) { + case 1: + stat = add_geph(nav, &geph); + break; + case 2: + stat = add_seph(nav, &seph); + break; + default: + stat = add_eph(nav, &eph); + break; + } + if (!stat) return 0; } - return nav->n>0||nav->ng>0||nav->ns>0; + } + return nav->n > 0 || nav->ng > 0 || nav->ns > 0; } /* read RINEX clock ----------------------------------------------------------*/ -static int readrnxclk(FILE *fp, const char *opt, double ver, int index, nav_t *nav) -{ - pclk_t *nav_pclk; - gtime_t time; - double data[2]; - int i,j,sat,mask,off; - char buff[MAXRNXLEN],satid[8]=""; +static int readrnxclk(FILE *fp, const char *opt, double ver, int index, nav_t *nav) { + pclk_t *nav_pclk; + gtime_t time; + double data[2]; + int i, j, sat, mask, off; + char buff[MAXRNXLEN], satid[8] = ""; - trace(3,"readrnxclk: index=%d\n", index); + trace(3, "readrnxclk: index=%d\n", index); - if (!nav) return 0; + if (!nav) return 0; - /* set system mask */ - mask=set_sysmask(opt); - off=ver>=3.04?5:0; /* format change for ver>=3.04 */ + /* set system mask */ + mask = set_sysmask(opt); + off = ver >= 3.04 ? 5 : 0; /* format change for ver>=3.04 */ - while (fgets(buff,sizeof(buff),fp)) { - - if (str2time(buff,8+off,26,&time)) { - trace(2,"rinex clk invalid epoch: %34.34s\n",buff); - continue; - } - memcpy(satid,buff+3,4); + while (fgets(buff, sizeof(buff), fp)) { + if (str2time(buff, 8 + off, 26, &time)) { + trace(2, "rinex clk invalid epoch: %34.34s\n", buff); + continue; + } + memcpy(satid, buff + 3, 4); - /* only read AS (satellite clock) record */ - if (strncmp(buff,"AS",2)||!(sat=satid2no(satid))) continue; + /* only read AS (satellite clock) record */ + if (strncmp(buff, "AS", 2) || !(sat = satid2no(satid))) continue; - if (!(satsys(sat,NULL)&mask)) continue; + if (!(satsys(sat, NULL) & mask)) continue; - for (i=0,j=40+off;i<2;i++,j+=20) data[i]=str2num(buff,j,19); + for (i = 0, j = 40 + off; i < 2; i++, j += 20) data[i] = str2num(buff, j, 19); - if (nav->nc>=nav->ncmax) { - nav->ncmax+=1024; - if (!(nav_pclk=(pclk_t *)realloc(nav->pclk,sizeof(pclk_t)*(nav->ncmax)))) { - trace(1,"readrnxclk malloc error: nmax=%d\n",nav->ncmax); - free(nav->pclk); nav->pclk=NULL; nav->nc=nav->ncmax=0; - return -1; - } - nav->pclk=nav_pclk; - } - if (nav->nc<=0||fabs(timediff(time,nav->pclk[nav->nc-1].time))>1E-9) { - nav->nc++; - nav->pclk[nav->nc-1].time =time; - nav->pclk[nav->nc-1].index=index; - for (i=0;ipclk[nav->nc-1].clk[i][0]=0.0; - nav->pclk[nav->nc-1].std[i][0]=0.0f; - } - } - nav->pclk[nav->nc-1].clk[sat-1][0]=data[0]; - nav->pclk[nav->nc-1].std[sat-1][0]=(float)data[1]; + if (nav->nc >= nav->ncmax) { + nav->ncmax += 1024; + if (!(nav_pclk = (pclk_t *)realloc(nav->pclk, sizeof(pclk_t) * (nav->ncmax)))) { + trace(1, "readrnxclk malloc error: nmax=%d\n", nav->ncmax); + free(nav->pclk); + nav->pclk = NULL; + nav->nc = nav->ncmax = 0; + return -1; + } + nav->pclk = nav_pclk; + } + if (nav->nc <= 0 || fabs(timediff(time, nav->pclk[nav->nc - 1].time)) > 1E-9) { + nav->nc++; + nav->pclk[nav->nc - 1].time = time; + nav->pclk[nav->nc - 1].index = index; + for (i = 0; i < MAXSAT; i++) { + nav->pclk[nav->nc - 1].clk[i][0] = 0.0; + nav->pclk[nav->nc - 1].std[i][0] = 0.0f; + } } - return nav->nc>0; + nav->pclk[nav->nc - 1].clk[sat - 1][0] = data[0]; + nav->pclk[nav->nc - 1].std[sat - 1][0] = (float)data[1]; + } + return nav->nc > 0; } /* read RINEX file -----------------------------------------------------------*/ -static int readrnxfp(FILE *fp, gtime_t ts, gtime_t te, double tint, - const char *opt, int flag, int index, char *type, - obs_t *obs, nav_t *nav, sta_t *sta) -{ - double ver; - int sys,tsys=TSYS_GPS; - char tobs[RNX_NUMSYS][MAXOBSTYPE][4]={{""}}; - - trace(3,"readrnxfp: flag=%d index=%d\n",flag,index); - - /* read RINEX file header */ - if (!readrnxh(fp,&ver,type,&sys,&tsys,tobs,nav,sta,flag)) return 0; - - /* flag=0:except for clock,1:clock */ - if ((!flag&&*type=='C')||(flag&&*type!='C')) return 0; - - /* read RINEX file body */ - switch (*type) { - case 'O': return readrnxobs(fp,ts,te,tint,opt,index,ver,&tsys,tobs,obs, - sta); - case 'N': return readrnxnav(fp,opt,ver,sys ,nav); - case 'G': return readrnxnav(fp,opt,ver,SYS_GLO,nav); - case 'H': return readrnxnav(fp,opt,ver,SYS_SBS,nav); - case 'J': return readrnxnav(fp,opt,ver,SYS_QZS,nav); /* extension */ - case 'L': return readrnxnav(fp,opt,ver,SYS_GAL,nav); /* extension */ - case 'C': return readrnxclk(fp,opt,ver,index,nav); - } - trace(2,"unsupported rinex type ver=%.2f type=%c\n",ver,*type); - return 0; +static int readrnxfp(FILE *fp, gtime_t ts, gtime_t te, double tint, const char *opt, int flag, + int index, char *type, obs_t *obs, nav_t *nav, sta_t *sta) { + double ver; + int sys, tsys = TSYS_GPS; + char tobs[RNX_NUMSYS][MAXOBSTYPE][4] = {{""}}; + + trace(3, "readrnxfp: flag=%d index=%d\n", flag, index); + + /* read RINEX file header */ + if (!readrnxh(fp, &ver, type, &sys, &tsys, tobs, nav, sta, flag)) return 0; + + /* flag=0:except for clock,1:clock */ + if ((!flag && *type == 'C') || (flag && *type != 'C')) return 0; + + /* read RINEX file body */ + switch (*type) { + case 'O': + return readrnxobs(fp, ts, te, tint, opt, index, ver, &tsys, tobs, obs, sta); + case 'N': + return readrnxnav(fp, opt, ver, sys, nav); + case 'G': + return readrnxnav(fp, opt, ver, SYS_GLO, nav); + case 'H': + return readrnxnav(fp, opt, ver, SYS_SBS, nav); + case 'J': + return readrnxnav(fp, opt, ver, SYS_QZS, nav); /* extension */ + case 'L': + return readrnxnav(fp, opt, ver, SYS_GAL, nav); /* extension */ + case 'C': + return readrnxclk(fp, opt, ver, index, nav); + } + trace(2, "unsupported rinex type ver=%.2f type=%c\n", ver, *type); + return 0; } /* uncompress and read RINEX file --------------------------------------------*/ -static int readrnxfile(const char *file, gtime_t ts, gtime_t te, double tint, - const char *opt, int flag, int index, char *type, - obs_t *obs, nav_t *nav, sta_t *sta) -{ - FILE *fp; - int cstat,stat; - char tmpfile[1024]; +static int readrnxfile(const char *file, gtime_t ts, gtime_t te, double tint, const char *opt, + int flag, int index, char *type, obs_t *obs, nav_t *nav, sta_t *sta) { + FILE *fp; + int cstat, stat; + char tmpfile[1024]; - trace(3,"readrnxfile: file=%s flag=%d index=%d\n",file,flag,index); + trace(3, "readrnxfile: file=%s flag=%d index=%d\n", file, flag, index); - if (sta) init_sta(sta); + if (sta) init_sta(sta); - /* uncompress file */ - if ((cstat=rtk_uncompress(file,tmpfile))<0) { - trace(2,"rinex file uncompact error: %s\n",file); - return 0; - } - if (!(fp=fopen(cstat?tmpfile:file,"r"))) { - trace(2,"rinex file open error: %s\n",cstat?tmpfile:file); - return 0; - } - /* read RINEX file */ - stat=readrnxfp(fp,ts,te,tint,opt,flag,index,type,obs,nav,sta); + /* uncompress file */ + if ((cstat = rtk_uncompress(file, tmpfile)) < 0) { + trace(2, "rinex file uncompact error: %s\n", file); + return 0; + } + if (!(fp = fopen(cstat ? tmpfile : file, "r"))) { + trace(2, "rinex file open error: %s\n", cstat ? tmpfile : file); + return 0; + } + /* read RINEX file */ + stat = readrnxfp(fp, ts, te, tint, opt, flag, index, type, obs, nav, sta); - fclose(fp); + fclose(fp); - /* delete temporary file */ - if (cstat) remove(tmpfile); + /* delete temporary file */ + if (cstat) remove(tmpfile); - return stat; + return stat; } /* Add a RINEX comment, taking care of overflow ------------------------------ -* Returns 1 on success, and 0 if omitted or truncated. -* The comment is append from the first empty comment, and it is assumed that -* comments are added without empty comments. */ + * Returns 1 on success, and 0 if omitted or truncated. + * The comment is append from the first empty comment, and it is assumed that + * comments are added without empty comments. */ extern int rnxcomment(rnxopt_t *opt, const char *format, ...) { - char buff[256]; - va_list ap; - va_start(ap, format); - int req = vsnprintf(buff, sizeof(buff), format, ap); - va_end(ap); - if (req < 0) { - trace(2,"rnxcomment: format error in '%s'\n", format); - return 0; - } - if ((unsigned)req >= sizeof(buff)) { - trace(3, "rnxcomment: buffer overflow\n"); - } - // Don't attempt to leave an empty comment - if (req == 0) - return 1; - // Find the start of empty comment lines. - int i; - for (i = 0; i < MAXCOMMENT; i++) { - if (!*opt->comment[i]) break; - } - // Copy while wrapping overflow into the next comment line. - for (int j = 0, rem = strlen(buff); rem > 0; i++) { - if (i >= MAXCOMMENT) return 0; - int indent = j > 0 ? 2 : 0; // Indent overflow lines - int n = rem > 60 - indent ? 60 - indent : rem; - if (indent > 0) strcpy(opt->comment[i], " "); - memcpy(opt->comment[i] + indent, buff + j, n); - opt->comment[i][indent + n] = '\0'; - rem -= n; - j += n; - } - return 1; + char buff[256]; + va_list ap; + va_start(ap, format); + int req = vsnprintf(buff, sizeof(buff), format, ap); + va_end(ap); + if (req < 0) { + trace(2, "rnxcomment: format error in '%s'\n", format); + return 0; + } + if ((unsigned)req >= sizeof(buff)) { + trace(3, "rnxcomment: buffer overflow\n"); + } + // Don't attempt to leave an empty comment + if (req == 0) return 1; + // Find the start of empty comment lines. + int i; + for (i = 0; i < MAXCOMMENT; i++) { + if (!*opt->comment[i]) break; + } + // Copy while wrapping overflow into the next comment line. + for (int j = 0, rem = strlen(buff); rem > 0; i++) { + if (i >= MAXCOMMENT) return 0; + int indent = j > 0 ? 2 : 0; // Indent overflow lines + int n = rem > 60 - indent ? 60 - indent : rem; + if (indent > 0) strcpy(opt->comment[i], " "); + memcpy(opt->comment[i] + indent, buff + j, n); + opt->comment[i][indent + n] = '\0'; + rem -= n; + j += n; + } + return 1; } /* read RINEX OBS and NAV files ------------------------------------------------ -* read RINEX OBS and NAV files -* args : char *file I file (wild-card * expanded) ("": stdin) -* int rcv I receiver number for obs data -* (gtime_t ts) I observation time start (ts.time==0: no limit) -* (gtime_t te) I observation time end (te.time==0: no limit) -* (double tint) I observation time interval (s) (0:all) -* char *opt I RINEX options (see below,"": no option) -* obs_t *obs IO observation data (NULL: no input) -* nav_t *nav IO navigation data (NULL: no input) -* sta_t *sta IO station parameters (NULL: no input) -* return : status (1:ok,0:no data,-1:error) -* notes : read data are appended to obs and nav struct -* before calling the function, obs and nav should be initialized. -* observation data and navigation data are not sorted. -* navigation data may be duplicated. -* call sortobs() or uniqnav() to sort data or delete duplicated eph. -* -* RINEX options (separated by spaces) : -* -* -GLss[=shift]: select GPS signal ss (ss: RINEX 3 code, "1C","2W"...) -* -RLss[=shift]: select GLO signal ss -* -ELss[=shift]: select GAL signal ss -* -JLss[=shift]: select QZS signal ss -* -CLss[=shift]: select BDS signal ss -* -ILss[=shift]: select IRN signal ss -* -SLss[=shift]: select SBS signal ss -* -* shift: carrier phase shift to be added (cycle) -* -* -SYS=sys[,sys...]: select navigation systems -* (sys=G:GPS,R:GLO,E:GAL,J:QZS,C:BDS,I:IRN,S:SBS) -* -*-----------------------------------------------------------------------------*/ -extern int readrnxt(const char *file, int rcv, gtime_t ts, gtime_t te, - double tint, const char *opt, obs_t *obs, nav_t *nav, - sta_t *sta) -{ - int i,n,stat=0; - const char *p; - char type=' ',*files[MAXEXFILE]={0}; - - trace(3,"readrnxt: file=%s rcv=%d\n",file,rcv); - - if (!*file) { - return readrnxfp(stdin,ts,te,tint,opt,0,1,&type,obs,nav,sta); - } - for (i=0;i=0;i--) free(files[i]); - return -1; - } - } - /* expand wild-card */ - if ((n=expath(file,files,MAXEXFILE))<=0) { - for (i=0;i=0;i++) { - stat=readrnxfile(files[i],ts,te,tint,opt,0,rcv,&type,obs,nav,sta); - } - /* if station name empty, set 4-char name from file head */ - if (type=='O'&&sta) { - if (!(p=strrchr(file,RTKLIB_FILEPATHSEP))) p=file-1; - if (!*sta->name) setstr(sta->name,p+1,4); + * read RINEX OBS and NAV files + * args : char *file I file (wild-card * expanded) ("": stdin) + * int rcv I receiver number for obs data + * (gtime_t ts) I observation time start (ts.time==0: no limit) + * (gtime_t te) I observation time end (te.time==0: no limit) + * (double tint) I observation time interval (s) (0:all) + * char *opt I RINEX options (see below,"": no option) + * obs_t *obs IO observation data (NULL: no input) + * nav_t *nav IO navigation data (NULL: no input) + * sta_t *sta IO station parameters (NULL: no input) + * return : status (1:ok,0:no data,-1:error) + * notes : read data are appended to obs and nav struct + * before calling the function, obs and nav should be initialized. + * observation data and navigation data are not sorted. + * navigation data may be duplicated. + * call sortobs() or uniqnav() to sort data or delete duplicated eph. + * + * RINEX options (separated by spaces) : + * + * -GLss[=shift]: select GPS signal ss (ss: RINEX 3 code, "1C","2W"...) + * -RLss[=shift]: select GLO signal ss + * -ELss[=shift]: select GAL signal ss + * -JLss[=shift]: select QZS signal ss + * -CLss[=shift]: select BDS signal ss + * -ILss[=shift]: select IRN signal ss + * -SLss[=shift]: select SBS signal ss + * + * shift: carrier phase shift to be added (cycle) + * + * -SYS=sys[,sys...]: select navigation systems + * (sys=G:GPS,R:GLO,E:GAL,J:QZS,C:BDS,I:IRN,S:SBS) + * + *-----------------------------------------------------------------------------*/ +extern int readrnxt(const char *file, int rcv, gtime_t ts, gtime_t te, double tint, const char *opt, + obs_t *obs, nav_t *nav, sta_t *sta) { + int i, n, stat = 0; + const char *p; + char type = ' ', *files[MAXEXFILE] = {0}; + + trace(3, "readrnxt: file=%s rcv=%d\n", file, rcv); + + if (!*file) { + return readrnxfp(stdin, ts, te, tint, opt, 0, 1, &type, obs, nav, sta); + } + for (i = 0; i < MAXEXFILE; i++) { + if (!(files[i] = (char *)malloc(1024))) { + for (i--; i >= 0; i--) free(files[i]); + return -1; } - for (i=0;i= 0; i++) { + stat = readrnxfile(files[i], ts, te, tint, opt, 0, rcv, &type, obs, nav, sta); + } + /* if station name empty, set 4-char name from file head */ + if (type == 'O' && sta) { + if (!(p = strrchr(file, RTKLIB_FILEPATHSEP))) p = file - 1; + if (!*sta->name) setstr(sta->name, p + 1, 4); + } + for (i = 0; i < MAXEXFILE; i++) free(files[i]); - return stat; + return stat; } -extern int readrnx(const char *file, int rcv, const char *opt, obs_t *obs, - nav_t *nav, sta_t *sta) -{ - gtime_t t={0}; +extern int readrnx(const char *file, int rcv, const char *opt, obs_t *obs, nav_t *nav, sta_t *sta) { + gtime_t t = {0}; - trace(3,"readrnx : file=%s rcv=%d\n",file,rcv); + trace(3, "readrnx : file=%s rcv=%d\n", file, rcv); - return readrnxt(file,rcv,t,t,0.0,opt,obs,nav,sta); + return readrnxt(file, rcv, t, t, 0.0, opt, obs, nav, sta); } /* compare precise clock -----------------------------------------------------*/ -static int cmppclk(const void *p1, const void *p2) -{ - pclk_t *q1=(pclk_t *)p1,*q2=(pclk_t *)p2; - double tt=timediff(q1->time,q2->time); - return tt<-1E-9?-1:(tt>1E-9?1:q1->index-q2->index); +static int cmppclk(const void *p1, const void *p2) { + pclk_t *q1 = (pclk_t *)p1, *q2 = (pclk_t *)p2; + double tt = timediff(q1->time, q2->time); + return tt < -1E-9 ? -1 : (tt > 1E-9 ? 1 : q1->index - q2->index); } /* combine precise clock -----------------------------------------------------*/ -static void combpclk(nav_t *nav) -{ - pclk_t *nav_pclk; - int i,j,k; - - trace(3,"combpclk: nc=%d\n",nav->nc); +static void combpclk(nav_t *nav) { + pclk_t *nav_pclk; + int i, j, k; - if (nav->nc<=0) return; + trace(3, "combpclk: nc=%d\n", nav->nc); - qsort(nav->pclk,nav->nc,sizeof(pclk_t),cmppclk); + if (nav->nc <= 0) return; - for (i=0,j=1;jnc;j++) { - if (fabs(timediff(nav->pclk[i].time,nav->pclk[j].time))<1E-9) { - for (k=0;kpclk[j].clk[k][0]==0.0) continue; - nav->pclk[i].clk[k][0]=nav->pclk[j].clk[k][0]; - nav->pclk[i].std[k][0]=nav->pclk[j].std[k][0]; - } - } - else if (++ipclk[i]=nav->pclk[j]; - } - nav->nc=i+1; + qsort(nav->pclk, nav->nc, sizeof(pclk_t), cmppclk); - if (!(nav_pclk=(pclk_t *)realloc(nav->pclk,sizeof(pclk_t)*nav->nc))) { - free(nav->pclk); nav->pclk=NULL; nav->nc=nav->ncmax=0; - trace(1,"combpclk malloc error nc=%d\n",nav->nc); - return; - } - nav->pclk=nav_pclk; - nav->ncmax=nav->nc; + for (i = 0, j = 1; j < nav->nc; j++) { + if (fabs(timediff(nav->pclk[i].time, nav->pclk[j].time)) < 1E-9) { + for (k = 0; k < MAXSAT; k++) { + if (nav->pclk[j].clk[k][0] == 0.0) continue; + nav->pclk[i].clk[k][0] = nav->pclk[j].clk[k][0]; + nav->pclk[i].std[k][0] = nav->pclk[j].std[k][0]; + } + } else if (++i < j) + nav->pclk[i] = nav->pclk[j]; + } + nav->nc = i + 1; + + if (!(nav_pclk = (pclk_t *)realloc(nav->pclk, sizeof(pclk_t) * nav->nc))) { + free(nav->pclk); + nav->pclk = NULL; + nav->nc = nav->ncmax = 0; + trace(1, "combpclk malloc error nc=%d\n", nav->nc); + return; + } + nav->pclk = nav_pclk; + nav->ncmax = nav->nc; - trace(4,"combpclk: nc=%d\n",nav->nc); + trace(4, "combpclk: nc=%d\n", nav->nc); } /* read RINEX clock files ------------------------------------------------------ -* read RINEX clock files -* args : char *file I file (wild-card * expanded) -* nav_t *nav IO navigation data (NULL: no input) -* return : number of precise clock -*-----------------------------------------------------------------------------*/ -extern int readrnxc(const char *file, nav_t *nav) -{ - gtime_t t={0}; - int i,n,index=0,stat=1; - char *files[MAXEXFILE]={0},type; - - trace(3,"readrnxc: file=%s\n",file); - - for (i=0;i=0;i--) free(files[i]); - return 0; - } + * read RINEX clock files + * args : char *file I file (wild-card * expanded) + * nav_t *nav IO navigation data (NULL: no input) + * return : number of precise clock + *-----------------------------------------------------------------------------*/ +extern int readrnxc(const char *file, nav_t *nav) { + gtime_t t = {0}; + int i, n, index = 0, stat = 1; + char *files[MAXEXFILE] = {0}, type; + + trace(3, "readrnxc: file=%s\n", file); + + for (i = 0; i < MAXEXFILE; i++) { + if (!(files[i] = (char *)malloc(1024))) { + for (i--; i >= 0; i--) free(files[i]); + return 0; } - /* expand wild-card */ - n=expath(file,files,MAXEXFILE); + } + /* expand wild-card */ + n = expath(file, files, MAXEXFILE); - /* read rinex clock files */ - for (i=0;inc; + return nav->nc; } /* initialize RINEX control ---------------------------------------------------- -* initialize RINEX control struct and reallocate memory for observation and -* ephemeris buffer in RINEX control struct -* args : rnxctr_t *rnx IO RINEX control struct -* return : status (1:ok,0:memory allocation error) -*-----------------------------------------------------------------------------*/ -extern int init_rnxctr(rnxctr_t *rnx) -{ - gtime_t time0={0}; - obsd_t data0={{0}}; - eph_t eph0={0,-1,-1}; - seph_t seph0={0}; - int i,j; - - trace(3,"init_rnxctr:\n"); - - rnx->obs.data=NULL; - rnx->nav.eph =NULL; - rnx->nav.geph=NULL; - rnx->nav.seph=NULL; - - if (!(rnx->obs.data=(obsd_t *)malloc(sizeof(obsd_t)*MAXOBS ))|| - !(rnx->nav.eph =(eph_t *)malloc(sizeof(eph_t )*MAXSAT*2 ))|| - !(rnx->nav.seph=(seph_t *)malloc(sizeof(seph_t)*NSATSBS*2))) { - free_rnxctr(rnx); - return 0; - } - rnx->time=time0; - rnx->ver=0.0; - rnx->sys=rnx->tsys=0; - for (i=0;itobs[i][j][0]='\0'; - rnx->obs.n=0; - rnx->obs.nmax=MAXOBS; - rnx->nav.n=rnx->nav.nmax=MAXSAT*2; - rnx->nav.ns=rnx->nav.nsmax=NSATSBS*2; - for (i=0;iobs.data[i]=data0; - for (i=0;inav.eph [i]=eph0; - for (i=0;inav.seph[i]=seph0; - rnx->ephsat=rnx->ephset=0; - rnx->opt[0]='\0'; - - if (MAXPRNGLO > 0) { - rnx->nav.geph = (geph_t *)malloc(sizeof(geph_t) * MAXPRNGLO); - if (rnx->nav.geph == NULL) { - free_rnxctr(rnx); - return 0; - } - geph_t geph0 = {0, -1}; - for (int i = 0; i < MAXPRNGLO ; i++) rnx->nav.geph[i] = geph0; - } - rnx->nav.ng = rnx->nav.ngmax = MAXPRNGLO; + * initialize RINEX control struct and reallocate memory for observation and + * ephemeris buffer in RINEX control struct + * args : rnxctr_t *rnx IO RINEX control struct + * return : status (1:ok,0:memory allocation error) + *-----------------------------------------------------------------------------*/ +extern int init_rnxctr(rnxctr_t *rnx) { + gtime_t time0 = {0}; + obsd_t data0 = {{0}}; + eph_t eph0 = {0, -1, -1}; + seph_t seph0 = {0}; + int i, j; + + trace(3, "init_rnxctr:\n"); + + rnx->obs.data = NULL; + rnx->nav.eph = NULL; + rnx->nav.geph = NULL; + rnx->nav.seph = NULL; + + if (!(rnx->obs.data = (obsd_t *)malloc(sizeof(obsd_t) * MAXOBS)) || + !(rnx->nav.eph = (eph_t *)malloc(sizeof(eph_t) * MAXSAT * 2)) || + !(rnx->nav.seph = (seph_t *)malloc(sizeof(seph_t) * NSATSBS * 2))) { + free_rnxctr(rnx); + return 0; + } + rnx->time = time0; + rnx->ver = 0.0; + rnx->sys = rnx->tsys = 0; + for (i = 0; i < RNX_NUMSYS; i++) + for (j = 0; j < MAXOBSTYPE; j++) rnx->tobs[i][j][0] = '\0'; + rnx->obs.n = 0; + rnx->obs.nmax = MAXOBS; + rnx->nav.n = rnx->nav.nmax = MAXSAT * 2; + rnx->nav.ns = rnx->nav.nsmax = NSATSBS * 2; + for (i = 0; i < MAXOBS; i++) rnx->obs.data[i] = data0; + for (i = 0; i < MAXSAT * 2; i++) rnx->nav.eph[i] = eph0; + for (i = 0; i < NSATSBS * 2; i++) rnx->nav.seph[i] = seph0; + rnx->ephsat = rnx->ephset = 0; + rnx->opt[0] = '\0'; + + if (MAXPRNGLO > 0) { + rnx->nav.geph = (geph_t *)malloc(sizeof(geph_t) * MAXPRNGLO); + if (rnx->nav.geph == NULL) { + free_rnxctr(rnx); + return 0; + } + geph_t geph0 = {0, -1}; + for (int i = 0; i < MAXPRNGLO; i++) rnx->nav.geph[i] = geph0; + } + rnx->nav.ng = rnx->nav.ngmax = MAXPRNGLO; - return 1; + return 1; } /* free RINEX control ---------------------------------------------------------- -* free observation and ephemeris buffer in RINEX control struct -* args : rnxctr_t *rnx IO RINEX control struct -* return : none -*-----------------------------------------------------------------------------*/ -extern void free_rnxctr(rnxctr_t *rnx) -{ - trace(3,"free_rnxctr:\n"); - - free(rnx->obs.data); rnx->obs.data=NULL; rnx->obs.n =rnx->obs.nmax =0; - free(rnx->nav.eph ); rnx->nav.eph =NULL; rnx->nav.n =rnx->nav.nmax =0; - free(rnx->nav.geph); rnx->nav.geph=NULL; rnx->nav.ng=rnx->nav.ngmax=0; - free(rnx->nav.seph); rnx->nav.seph=NULL; rnx->nav.ns=rnx->nav.nsmax=0; + * free observation and ephemeris buffer in RINEX control struct + * args : rnxctr_t *rnx IO RINEX control struct + * return : none + *-----------------------------------------------------------------------------*/ +extern void free_rnxctr(rnxctr_t *rnx) { + trace(3, "free_rnxctr:\n"); + + free(rnx->obs.data); + rnx->obs.data = NULL; + rnx->obs.n = rnx->obs.nmax = 0; + free(rnx->nav.eph); + rnx->nav.eph = NULL; + rnx->nav.n = rnx->nav.nmax = 0; + free(rnx->nav.geph); + rnx->nav.geph = NULL; + rnx->nav.ng = rnx->nav.ngmax = 0; + free(rnx->nav.seph); + rnx->nav.seph = NULL; + rnx->nav.ns = rnx->nav.nsmax = 0; } /* open RINEX data ------------------------------------------------------------- -* fetch next RINEX message and input a message from file -* args : rnxctr_t *rnx IO RINEX control struct -* FILE *fp I file pointer -* return : status (-2: end of file, 0: no message, 1: input observation data, -* 2: input navigation data) -*-----------------------------------------------------------------------------*/ -extern int open_rnxctr(rnxctr_t *rnx, FILE *fp) -{ - const char *rnxtypes="ONGLJHC"; - double ver; - char type,tobs[RNX_NUMSYS][MAXOBSTYPE][4]={{""}}; - int i,j,sys,tsys; - - trace(3,"open_rnxctr:\n"); - - /* read RINEX header from file */ - if (!readrnxh(fp,&ver,&type,&sys,&tsys,tobs,&rnx->nav,&rnx->sta,0)) { - trace(2,"open_rnxctr: rinex header read error\n"); - return 0; - } - if (!strchr(rnxtypes,type)) { - trace(2,"open_rnxctr: not supported rinex type type=%c\n",type); - return 0; - } - rnx->ver=ver; - rnx->type=type; - rnx->sys=sys; - rnx->tsys=tsys; - for (i=0;itobs[i][j],tobs[i][j]); + * fetch next RINEX message and input a message from file + * args : rnxctr_t *rnx IO RINEX control struct + * FILE *fp I file pointer + * return : status (-2: end of file, 0: no message, 1: input observation data, + * 2: input navigation data) + *-----------------------------------------------------------------------------*/ +extern int open_rnxctr(rnxctr_t *rnx, FILE *fp) { + const char *rnxtypes = "ONGLJHC"; + double ver; + char type, tobs[RNX_NUMSYS][MAXOBSTYPE][4] = {{""}}; + int i, j, sys, tsys; + + trace(3, "open_rnxctr:\n"); + + /* read RINEX header from file */ + if (!readrnxh(fp, &ver, &type, &sys, &tsys, tobs, &rnx->nav, &rnx->sta, 0)) { + trace(2, "open_rnxctr: rinex header read error\n"); + return 0; + } + if (!strchr(rnxtypes, type)) { + trace(2, "open_rnxctr: not supported rinex type type=%c\n", type); + return 0; + } + rnx->ver = ver; + rnx->type = type; + rnx->sys = sys; + rnx->tsys = tsys; + for (i = 0; i < RNX_NUMSYS; i++) + for (j = 0; j < MAXOBSTYPE && *tobs[i][j]; j++) { + strcpy(rnx->tobs[i][j], tobs[i][j]); } - rnx->ephset=rnx->ephsat=0; - return 1; + rnx->ephset = rnx->ephsat = 0; + return 1; } /* input RINEX control --------------------------------------------------------- -* fetch next RINEX message and input a message from file -* args : rnxctr_t *rnx IO RINEX control struct -* FILE *fp I file pointer -* return : status (-2: end of file, 0: no message, 1: input observation data, -* 2: input navigation data) -* notes : if status=1, input obs data are set to rnx as follows: -* rnx->time : obs data epoch time -* rnx->obs.n : number of obs data -* rnx->obs.data[]: obs data -* if status=2, input nav data are set to rnx as follows: -* rnx->time : ephemeris frame time -* rnx->ephsat : sat-no of input ephemeris -* rnx->ephset : set-no of input ephemeris (0:set1,1:set2) -* rnx->nav.geph[prn-1] : GLOASS ephemeris (prn=slot-no) -* rnx->nav.seph[prn-MINPRNSBS]: SBAS ephemeris (prn=PRN-no) -* rnx->nav.eph [sat-1] : other ephemeris set1 (sat=sat-no) -* rnx->nav.eph [sat-1+MAXSAT] : other ephemeris set2 (sat=sat-no) -*-----------------------------------------------------------------------------*/ -extern int input_rnxctr(rnxctr_t *rnx, FILE *fp) -{ - eph_t eph={0}; - geph_t geph={0}; - seph_t seph={0}; - int n,sys,stat,flag,prn,type,set; - - trace(4,"input_rnxctr:\n"); - - /* read RINEX OBS data */ - if (rnx->type=='O') { - if ((n=readrnxobsb(fp,rnx->opt,rnx->ver,&rnx->tsys,rnx->tobs,&flag, - rnx->obs.data,&rnx->sta))<=0) { - rnx->obs.n=0; - return n<0?-2:0; - } - rnx->time=rnx->obs.data[0].time; - rnx->obs.n=n; - return 1; - } - /* read RINEX NAV data */ - switch (rnx->type) { - case 'N': sys=SYS_NONE; break; - case 'G': sys=SYS_GLO ; break; - case 'H': sys=SYS_SBS ; break; - case 'L': sys=SYS_GAL ; break; /* extension */ - case 'J': sys=SYS_QZS ; break; /* extension */ - default: return 0; - } - if ((stat=readrnxnavb(fp,rnx->opt,rnx->ver,sys,&type,&eph,&geph,&seph))<=0) { - return stat<0?-2:0; - } - if (type==1) { /* GLONASS ephemeris */ - sys=satsys(geph.sat,&prn); - rnx->nav.geph[prn-1]=geph; - rnx->time=geph.tof; - rnx->ephsat=geph.sat; - rnx->ephset=0; - } - else if (type==2) { /* SBAS ephemeris */ - sys=satsys(seph.sat,&prn); - rnx->nav.seph[prn-MINPRNSBS]=seph; - rnx->time=seph.tof; - rnx->ephsat=seph.sat; - rnx->ephset=0; - } - else { /* other ephemeris */ - sys=satsys(eph.sat,&prn); - set=(sys==SYS_GAL&&(eph.code&((1<<8)|(1<<1))))?1:0; /* GAL 0:I/NAV,1:F/NAV */ - rnx->nav.eph[eph.sat-1+MAXSAT*set]=eph; - rnx->time=eph.ttr; - rnx->ephsat=eph.sat; - rnx->ephset=set; - } - return 2; + * fetch next RINEX message and input a message from file + * args : rnxctr_t *rnx IO RINEX control struct + * FILE *fp I file pointer + * return : status (-2: end of file, 0: no message, 1: input observation data, + * 2: input navigation data) + * notes : if status=1, input obs data are set to rnx as follows: + * rnx->time : obs data epoch time + * rnx->obs.n : number of obs data + * rnx->obs.data[]: obs data + * if status=2, input nav data are set to rnx as follows: + * rnx->time : ephemeris frame time + * rnx->ephsat : sat-no of input ephemeris + * rnx->ephset : set-no of input ephemeris (0:set1,1:set2) + * rnx->nav.geph[prn-1] : GLOASS ephemeris (prn=slot-no) + * rnx->nav.seph[prn-MINPRNSBS]: SBAS ephemeris (prn=PRN-no) + * rnx->nav.eph [sat-1] : other ephemeris set1 (sat=sat-no) + * rnx->nav.eph [sat-1+MAXSAT] : other ephemeris set2 (sat=sat-no) + *-----------------------------------------------------------------------------*/ +extern int input_rnxctr(rnxctr_t *rnx, FILE *fp) { + eph_t eph = {0}; + geph_t geph = {0}; + seph_t seph = {0}; + int n, sys, stat, flag, prn, type, set; + + trace(4, "input_rnxctr:\n"); + + /* read RINEX OBS data */ + if (rnx->type == 'O') { + if ((n = readrnxobsb(fp, rnx->opt, rnx->ver, &rnx->tsys, rnx->tobs, &flag, rnx->obs.data, + &rnx->sta)) <= 0) { + rnx->obs.n = 0; + return n < 0 ? -2 : 0; + } + rnx->time = rnx->obs.data[0].time; + rnx->obs.n = n; + return 1; + } + /* read RINEX NAV data */ + switch (rnx->type) { + case 'N': + sys = SYS_NONE; + break; + case 'G': + sys = SYS_GLO; + break; + case 'H': + sys = SYS_SBS; + break; + case 'L': + sys = SYS_GAL; + break; /* extension */ + case 'J': + sys = SYS_QZS; + break; /* extension */ + default: + return 0; + } + if ((stat = readrnxnavb(fp, rnx->opt, rnx->ver, sys, &type, &eph, &geph, &seph)) <= 0) { + return stat < 0 ? -2 : 0; + } + if (type == 1) { /* GLONASS ephemeris */ + sys = satsys(geph.sat, &prn); + rnx->nav.geph[prn - 1] = geph; + rnx->time = geph.tof; + rnx->ephsat = geph.sat; + rnx->ephset = 0; + } else if (type == 2) { /* SBAS ephemeris */ + sys = satsys(seph.sat, &prn); + rnx->nav.seph[prn - MINPRNSBS] = seph; + rnx->time = seph.tof; + rnx->ephsat = seph.sat; + rnx->ephset = 0; + } else { /* other ephemeris */ + sys = satsys(eph.sat, &prn); + set = (sys == SYS_GAL && (eph.code & ((1 << 8) | (1 << 1)))) ? 1 : 0; /* GAL 0:I/NAV,1:F/NAV */ + rnx->nav.eph[eph.sat - 1 + MAXSAT * set] = eph; + rnx->time = eph.ttr; + rnx->ephsat = eph.sat; + rnx->ephset = set; + } + return 2; } /*------------------------------------------------------------------------------ -* output RINEX functions -*-----------------------------------------------------------------------------*/ + * output RINEX functions + *-----------------------------------------------------------------------------*/ /* output obs-types RINEX ver.2 ----------------------------------------------*/ -static void outobstype_ver2(FILE *fp, const rnxopt_t *opt) -{ - const char label[]="# / TYPES OF OBSERV"; - int i; +static void outobstype_ver2(FILE *fp, const rnxopt_t *opt) { + const char label[] = "# / TYPES OF OBSERV"; + int i; - trace(3,"outobstype_ver2:\n"); - - fprintf(fp,"%6d",opt->nobs[RNX_SYS_GPS]); - - for (i=0;inobs[RNX_SYS_GPS];i++) { - if (i>0&&i%9==0) fprintf(fp," "); + trace(3, "outobstype_ver2:\n"); - fprintf(fp,"%6s",opt->tobs[RNX_SYS_GPS][i]); - - if (i%9==8) fprintf(fp,"%-20s\n",label); - } - if (opt->nobs[RNX_SYS_GPS]==0||i%9>0) { - fprintf(fp,"%*s%-20s\n",(9-i%9)*6,"",label); - } + fprintf(fp, "%6d", opt->nobs[RNX_SYS_GPS]); + + for (i = 0; i < opt->nobs[RNX_SYS_GPS]; i++) { + if (i > 0 && i % 9 == 0) fprintf(fp, " "); + + fprintf(fp, "%6s", opt->tobs[RNX_SYS_GPS][i]); + + if (i % 9 == 8) fprintf(fp, "%-20s\n", label); + } + if (opt->nobs[RNX_SYS_GPS] == 0 || i % 9 > 0) { + fprintf(fp, "%*s%-20s\n", (9 - i % 9) * 6, "", label); + } } /* output obs-types RINEX ver.3 ----------------------------------------------*/ -static void outobstype_ver3(FILE *fp, const rnxopt_t *opt) -{ - const char label[]="SYS / # / OBS TYPES"; - char tobs[4]; - int i,j; +static void outobstype_ver3(FILE *fp, const rnxopt_t *opt) { + const char label[] = "SYS / # / OBS TYPES"; + char tobs[4]; + int i, j; - trace(3,"outobstype_ver3:\n"); - - for (i=0;inavsys)||!opt->nobs[i]) continue; + trace(3, "outobstype_ver3:\n"); - fprintf(fp,"%c %3d",syscodes[i],opt->nobs[i]); + for (i = 0; i < RNX_NUMSYS; i++) { + if (!(navsys[i] & opt->navsys) || !opt->nobs[i]) continue; - for (j=0;jnobs[i];j++) { - if (j>0&&j%13==0) fprintf(fp," "); + fprintf(fp, "%c %3d", syscodes[i], opt->nobs[i]); - strcpy(tobs,opt->tobs[i][j]); + for (j = 0; j < opt->nobs[i]; j++) { + if (j > 0 && j % 13 == 0) fprintf(fp, " "); - /* BDS B2x -> 1x (3.02), 2x (other) */ - if (i==RNX_SYS_CMP) { - if (opt->rnxver==302&&tobs[1]=='2') tobs[1]='1'; - } - fprintf(fp," %3s", tobs); + strcpy(tobs, opt->tobs[i][j]); - if (j%13==12) fprintf(fp," %-20s\n",label); - } - if (j%13>0) { - fprintf(fp,"%*s %-20s\n",(13-j%13)*4,"",label); - } + /* BDS B2x -> 1x (3.02), 2x (other) */ + if (i == RNX_SYS_CMP) { + if (opt->rnxver == 302 && tobs[1] == '2') tobs[1] = '1'; + } + fprintf(fp, " %3s", tobs); + + if (j % 13 == 12) fprintf(fp, " %-20s\n", label); } + if (j % 13 > 0) { + fprintf(fp, "%*s %-20s\n", (13 - j % 13) * 4, "", label); + } + } } /* output RINEX phase shift --------------------------------------------------*/ -static void outrnx_phase_shift(FILE *fp, const rnxopt_t *opt, const nav_t *nav) -{ - (void)nav; - static const uint8_t ref_code[RNX_NUMSYS][10]={ /* reference signal [9] table A23 */ - {CODE_L1C,CODE_L2P,CODE_L5I,0}, /* GPS */ - {CODE_L1C,CODE_L4A,CODE_L2C,CODE_L6A,CODE_L3I,0}, /* GLO */ - {CODE_L1B,CODE_L5I,CODE_L7I,CODE_L8I,CODE_L6B,0}, /* GAL */ - {CODE_L1C,CODE_L2S,CODE_L5I,CODE_L5D,CODE_L6S,0}, /* QZS */ - {CODE_L1C,CODE_L5I,0}, /* SBS */ - {CODE_L2I,CODE_L1D,CODE_L5D,CODE_L7I,CODE_L7D,CODE_L8D,CODE_L6I,0}, /* BDS */ - {CODE_L5A,CODE_L9A,0} /* IRN */ - }; - const char *label="SYS / PHASE SHIFT"; - char obs[8]; - int i,j,k; - - for (i=0;inavsys)||!opt->nobs[i]) continue; - for (j=0;jnobs[i];j++) { - if (opt->tobs[i][j][0]!='L') continue; - strcpy(obs,opt->tobs[i][j]); - for (k=0;ref_code[i][k];k++) { - if (obs2code(obs+1)==ref_code[i][k]) break; - } - if (i==RNX_SYS_CMP) { /* BDS B2x -> 1x (3.02), 2x (other) */ - if (opt->rnxver==302&&obs[1]=='2') obs[1]='1'; - } - if (ref_code[i][k]) { - fprintf(fp,"%c %3s %54s%-20s\n",syscodes[i],obs,"",label); - } - else { - fprintf(fp,"%c %3s %8.5f%46s%-20s\n",syscodes[i],obs, - opt->shift[i][j],"",label); - } - } +static void outrnx_phase_shift(FILE *fp, const rnxopt_t *opt, const nav_t *nav) { + (void)nav; + static const uint8_t ref_code[RNX_NUMSYS][10] = { + /* reference signal [9] table A23 */ + {CODE_L1C, CODE_L2P, CODE_L5I, 0}, /* GPS */ + {CODE_L1C, CODE_L4A, CODE_L2C, CODE_L6A, CODE_L3I, 0}, /* GLO */ + {CODE_L1B, CODE_L5I, CODE_L7I, CODE_L8I, CODE_L6B, 0}, /* GAL */ + {CODE_L1C, CODE_L2S, CODE_L5I, CODE_L5D, CODE_L6S, 0}, /* QZS */ + {CODE_L1C, CODE_L5I, 0}, /* SBS */ + {CODE_L2I, CODE_L1D, CODE_L5D, CODE_L7I, CODE_L7D, CODE_L8D, CODE_L6I, 0}, /* BDS */ + {CODE_L5A, CODE_L9A, 0} /* IRN */ + }; + const char *label = "SYS / PHASE SHIFT"; + char obs[8]; + int i, j, k; + + for (i = 0; i < RNX_NUMSYS; i++) { + if (!(navsys[i] & opt->navsys) || !opt->nobs[i]) continue; + for (j = 0; j < opt->nobs[i]; j++) { + if (opt->tobs[i][j][0] != 'L') continue; + strcpy(obs, opt->tobs[i][j]); + for (k = 0; ref_code[i][k]; k++) { + if (obs2code(obs + 1) == ref_code[i][k]) break; + } + if (i == RNX_SYS_CMP) { /* BDS B2x -> 1x (3.02), 2x (other) */ + if (opt->rnxver == 302 && obs[1] == '2') obs[1] = '1'; + } + if (ref_code[i][k]) { + fprintf(fp, "%c %3s %54s%-20s\n", syscodes[i], obs, "", label); + } else { + fprintf(fp, "%c %3s %8.5f%46s%-20s\n", syscodes[i], obs, opt->shift[i][j], "", label); + } } + } } /* output RINEX GLONASS slot/freq # ------------------------------------------*/ -static void outrnx_glo_fcn(FILE *fp, const rnxopt_t *opt, const nav_t *nav) -{ - const char *label="GLONASS SLOT / FRQ #"; - int i,j,k,n=0,sat,prn[MAXPRNGLO],fcn[MAXPRNGLO]; - - if (opt->navsys&SYS_GLO) { - for (i=0;ing;j++) { - if (nav->geph[j].sat==sat) break; - }; - if (jng) { - prn[n]=i+1; - fcn[n++]=nav->geph[j].frq; - } - else if (nav->glo_fcn[i]) { - prn[n]=i+1; - fcn[n++]=nav->glo_fcn[i]-8; - } - } - } - for (i=j=0;i<(n<=0?1:(n-1)/8+1);i++) { - if (i==0) fprintf(fp,"%3d",n); else fprintf(fp," "); - for (k=0;k<8&&jnavsys & SYS_GLO) { + for (i = 0; i < MAXPRNGLO; i++) { + sat = satno(SYS_GLO, i + 1); + for (j = 0; j < nav->ng; j++) { + if (nav->geph[j].sat == sat) break; + }; + if (j < nav->ng) { + prn[n] = i + 1; + fcn[n++] = nav->geph[j].frq; + } else if (nav->glo_fcn[i]) { + prn[n] = i + 1; + fcn[n++] = nav->glo_fcn[i] - 8; + } } + } + for (i = j = 0; i < (n <= 0 ? 1 : (n - 1) / 8 + 1); i++) { + if (i == 0) + fprintf(fp, "%3d", n); + else + fprintf(fp, " "); + for (k = 0; k < 8 && j < n; k++, j++) { + fprintf(fp, " R%02d %2d", prn[j], fcn[j]); + } + fprintf(fp, "%*s %-20s\n", (8 - k) * 7, "", label); + } } /* output RINEX GLONASS code/phase/bias --------------------------------------*/ -static void outrnx_glo_bias(FILE *fp, const rnxopt_t *opt) -{ - const char *label="GLONASS COD/PHS/BIS"; - const char *tobs[4]={"C1C","C1P","C2C","C2P"}; - - if (opt->navsys&SYS_GLO) { - fprintf(fp," %s %8.3f %s %8.3f %s %8.3f %s %8.3f%8s%-20s\n", - tobs[0],opt->glo_cp_bias[0],tobs[1],opt->glo_cp_bias[1], - tobs[2],opt->glo_cp_bias[2],tobs[3],opt->glo_cp_bias[3],"", - label); - } - else { - fprintf(fp,"%*s%-20s\n",60,"",label); - } +static void outrnx_glo_bias(FILE *fp, const rnxopt_t *opt) { + const char *label = "GLONASS COD/PHS/BIS"; + const char *tobs[4] = {"C1C", "C1P", "C2C", "C2P"}; + + if (opt->navsys & SYS_GLO) { + fprintf(fp, " %s %8.3f %s %8.3f %s %8.3f %s %8.3f%8s%-20s\n", tobs[0], opt->glo_cp_bias[0], + tobs[1], opt->glo_cp_bias[1], tobs[2], opt->glo_cp_bias[2], tobs[3], + opt->glo_cp_bias[3], "", label); + } else { + fprintf(fp, "%*s%-20s\n", 60, "", label); + } } // Canonicalize to IGS antenna format @@ -2218,953 +2326,935 @@ static char *igsanttype(const char *anttype, char buff[21]) { } /* output RINEX observation data file header ----------------------------------- -* output RINEX observation data file header -* args : FILE *fp I output file pointer -* rnxopt_t *opt I RINEX options -* nav_t *nav I navigation data -* return : status (1:ok, 0:output error) -*-----------------------------------------------------------------------------*/ -extern int outrnxobsh(FILE *fp, const rnxopt_t *opt, const nav_t *nav) -{ - double ep[6],pos[3]={0},del[3]={0}; - char date[32],*sys,*tsys="GPS"; - int i; - - trace(3,"outrnxobsh:\n"); - - timestr_rnx(date); - - if (opt->navsys==SYS_GPS) sys="G: GPS"; - else if (opt->navsys==SYS_GLO) sys="R: GLONASS"; - else if (opt->navsys==SYS_GAL) sys="E: Galileo"; - else if (opt->navsys==SYS_QZS) sys="J: QZSS"; /* ver.3.02 */ - else if (opt->navsys==SYS_CMP) sys="C: BeiDou"; /* ver.3.02 */ - else if (opt->navsys==SYS_IRN) sys="I: IRNSS"; /* ver.3.03 */ - else if (opt->navsys==SYS_SBS) sys="S: SBAS Payload"; - else sys="M: Mixed"; - - fprintf(fp,"%9.2f%-11s%-20s%-20s%-20s\n",opt->rnxver/100.0,"", - "OBSERVATION DATA",sys,"RINEX VERSION / TYPE"); - fprintf(fp,"%-20.20s%-20.20s%-20.20s%-20s\n",opt->prog,opt->runby,date, - "PGM / RUN BY / DATE"); - - for (i=0;icomment[i]) continue; - fprintf(fp,"%-60.60s%-20s\n",opt->comment[i],"COMMENT"); - } - fprintf(fp,"%-60.60s%-20s\n",opt->marker,"MARKER NAME"); - fprintf(fp,"%-20.20s%-40.40s%-20s\n",opt->markerno,"","MARKER NUMBER"); - - if (opt->rnxver>=300) { - fprintf(fp,"%-20.20s%-40.40s%-20s\n",opt->markertype,"","MARKER TYPE"); - } - fprintf(fp,"%-20.20s%-40.40s%-20s\n",opt->name[0],opt->name[1], - "OBSERVER / AGENCY"); - fprintf(fp,"%-20.20s%-20.20s%-20.20s%-20s\n",opt->rec[0],opt->rec[1], - opt->rec[2],"REC # / TYPE / VERS"); - char buff[21]; - fprintf(fp,"%-20.20s%-20.20s%-20.20s%-20s\n",opt->ant[0], igsanttype(opt->ant[1], buff), - "","ANT # / TYPE"); - - for (i=0;i<3;i++) if (fabs(opt->apppos[i])<1E8) pos[i]=opt->apppos[i]; - for (i=0;i<3;i++) if (fabs(opt->antdel[i])<1E8) del[i]=opt->antdel[i]; - fprintf(fp,"%14.4f%14.4f%14.4f%-18s%-20s\n",pos[0],pos[1],pos[2],"", - "APPROX POSITION XYZ"); - fprintf(fp,"%14.4f%14.4f%14.4f%-18s%-20s\n",del[0],del[1],del[2],"", - "ANTENNA: DELTA H/E/N"); - - if (opt->rnxver<=299) { /* ver.2 */ - fprintf(fp,"%6d%6d%-48s%-20s\n",1,1,"","WAVELENGTH FACT L1/2"); - outobstype_ver2(fp,opt); - } - else { /* ver.3 */ - outobstype_ver3(fp,opt); - } - if (opt->tint>0.0) { - fprintf(fp,"%10.3f%50s%-20s\n",opt->tint,"","INTERVAL"); - } - time2epoch(opt->tstart,ep); - fprintf(fp," %04.0f %02.0f %02.0f %02.0f %02.0f %010.7f %-12s%-20s\n", - ep[0],ep[1],ep[2],ep[3],ep[4],ep[5],tsys,"TIME OF FIRST OBS"); - - time2epoch(opt->tend,ep); - fprintf(fp," %04.0f %02.0f %02.0f %02.0f %02.0f %010.7f %-12s%-20s\n", - ep[0],ep[1],ep[2],ep[3],ep[4],ep[5],tsys,"TIME OF LAST OBS"); - - if (opt->rnxver>=301) { - outrnx_phase_shift(fp,opt,nav); /* SYS / PHASE SHIFT */ - } - if (opt->rnxver>=302) { - outrnx_glo_fcn(fp,opt,nav); /* GLONASS SLOT / FRQ # */ - outrnx_glo_bias(fp,opt); /* GLONASS COD/PHS/BIS */ - } - return fprintf(fp,"%-60.60s%-20s\n","","END OF HEADER")!=EOF; + * output RINEX observation data file header + * args : FILE *fp I output file pointer + * rnxopt_t *opt I RINEX options + * nav_t *nav I navigation data + * return : status (1:ok, 0:output error) + *-----------------------------------------------------------------------------*/ +extern int outrnxobsh(FILE *fp, const rnxopt_t *opt, const nav_t *nav) { + double ep[6], pos[3] = {0}, del[3] = {0}; + char date[32], *sys, *tsys = "GPS"; + int i; + + trace(3, "outrnxobsh:\n"); + + timestr_rnx(date); + + if (opt->navsys == SYS_GPS) + sys = "G: GPS"; + else if (opt->navsys == SYS_GLO) + sys = "R: GLONASS"; + else if (opt->navsys == SYS_GAL) + sys = "E: Galileo"; + else if (opt->navsys == SYS_QZS) + sys = "J: QZSS"; /* ver.3.02 */ + else if (opt->navsys == SYS_CMP) + sys = "C: BeiDou"; /* ver.3.02 */ + else if (opt->navsys == SYS_IRN) + sys = "I: IRNSS"; /* ver.3.03 */ + else if (opt->navsys == SYS_SBS) + sys = "S: SBAS Payload"; + else + sys = "M: Mixed"; + + fprintf(fp, "%9.2f%-11s%-20s%-20s%-20s\n", opt->rnxver / 100.0, "", "OBSERVATION DATA", sys, + "RINEX VERSION / TYPE"); + fprintf(fp, "%-20.20s%-20.20s%-20.20s%-20s\n", opt->prog, opt->runby, date, + "PGM / RUN BY / DATE"); + + for (i = 0; i < MAXCOMMENT; i++) { + if (!*opt->comment[i]) continue; + fprintf(fp, "%-60.60s%-20s\n", opt->comment[i], "COMMENT"); + } + fprintf(fp, "%-60.60s%-20s\n", opt->marker, "MARKER NAME"); + fprintf(fp, "%-20.20s%-40.40s%-20s\n", opt->markerno, "", "MARKER NUMBER"); + + if (opt->rnxver >= 300) { + fprintf(fp, "%-20.20s%-40.40s%-20s\n", opt->markertype, "", "MARKER TYPE"); + } + fprintf(fp, "%-20.20s%-40.40s%-20s\n", opt->name[0], opt->name[1], "OBSERVER / AGENCY"); + fprintf(fp, "%-20.20s%-20.20s%-20.20s%-20s\n", opt->rec[0], opt->rec[1], opt->rec[2], + "REC # / TYPE / VERS"); + char buff[21]; + fprintf(fp, "%-20.20s%-20.20s%-20.20s%-20s\n", opt->ant[0], igsanttype(opt->ant[1], buff), "", + "ANT # / TYPE"); + + for (i = 0; i < 3; i++) + if (fabs(opt->apppos[i]) < 1E8) pos[i] = opt->apppos[i]; + for (i = 0; i < 3; i++) + if (fabs(opt->antdel[i]) < 1E8) del[i] = opt->antdel[i]; + fprintf(fp, "%14.4f%14.4f%14.4f%-18s%-20s\n", pos[0], pos[1], pos[2], "", "APPROX POSITION XYZ"); + fprintf(fp, "%14.4f%14.4f%14.4f%-18s%-20s\n", del[0], del[1], del[2], "", "ANTENNA: DELTA H/E/N"); + + if (opt->rnxver <= 299) { /* ver.2 */ + fprintf(fp, "%6d%6d%-48s%-20s\n", 1, 1, "", "WAVELENGTH FACT L1/2"); + outobstype_ver2(fp, opt); + } else { /* ver.3 */ + outobstype_ver3(fp, opt); + } + if (opt->tint > 0.0) { + fprintf(fp, "%10.3f%50s%-20s\n", opt->tint, "", "INTERVAL"); + } + time2epoch(opt->tstart, ep); + fprintf(fp, " %04.0f %02.0f %02.0f %02.0f %02.0f %010.7f %-12s%-20s\n", ep[0], + ep[1], ep[2], ep[3], ep[4], ep[5], tsys, "TIME OF FIRST OBS"); + + time2epoch(opt->tend, ep); + fprintf(fp, " %04.0f %02.0f %02.0f %02.0f %02.0f %010.7f %-12s%-20s\n", ep[0], + ep[1], ep[2], ep[3], ep[4], ep[5], tsys, "TIME OF LAST OBS"); + + if (opt->rnxver >= 301) { + outrnx_phase_shift(fp, opt, nav); /* SYS / PHASE SHIFT */ + } + if (opt->rnxver >= 302) { + outrnx_glo_fcn(fp, opt, nav); /* GLONASS SLOT / FRQ # */ + outrnx_glo_bias(fp, opt); /* GLONASS COD/PHS/BIS */ + } + return fprintf(fp, "%-60.60s%-20s\n", "", "END OF HEADER") != EOF; } /* output observation data field ---------------------------------------------*/ -static void outrnxobsf(FILE *fp, double obs, int lli, int std) -{ - if (obs==0.0) { - fprintf(fp," "); - } - else { - fprintf(fp,"%14.3f",fmod(obs,1e9)); - } - if (lli<0||!(lli&(LLI_SLIP|LLI_HALFC|LLI_BOCTRK))) { - fprintf(fp," "); - } - else { - fprintf(fp,"%1.1d",lli&(LLI_SLIP|LLI_HALFC|LLI_BOCTRK)); - } - if (std<=0) fprintf(fp," "); else fprintf(fp,"%1.1x", std > 9 ? 9 : std); +static void outrnxobsf(FILE *fp, double obs, int lli, int std) { + if (obs == 0.0) { + fprintf(fp, " "); + } else { + fprintf(fp, "%14.3f", fmod(obs, 1e9)); + } + if (lli < 0 || !(lli & (LLI_SLIP | LLI_HALFC | LLI_BOCTRK))) { + fprintf(fp, " "); + } else { + fprintf(fp, "%1.1d", lli & (LLI_SLIP | LLI_HALFC | LLI_BOCTRK)); + } + if (std <= 0) + fprintf(fp, " "); + else + fprintf(fp, "%1.1x", std > 9 ? 9 : std); } /* search observation data index -------------------------------------------*/ -static int obsindex(int rnxver, int sys, const uint8_t *code, const char *tobs, - const char *mask) -{ - char *id; - int i; - - for (i=0;i=212&&tobs[1]=='A') { /* L1C/A */ - if (c==CODE_L1C) return i; - } - else if (rnxver>=212&&tobs[1]=='B') { /* L1C */ - if (c==CODE_L1S||c==CODE_L1L||c==CODE_L1X) - return i; - } - else if (rnxver>=212&&tobs[1]=='C') { /* L2C */ - if (c==CODE_L2S||c==CODE_L2L||c==CODE_L2X) - return i; - } - else if (rnxver>=212&&tobs[1]=='D'&&sys==SYS_GLO) { /* GLO L2C/A */ - if (c==CODE_L2C) return i; - } - else if (tobs[1]=='2'&&sys==SYS_CMP) { /* BDS B1 */ - if (c==CODE_L2I||c==CODE_L2Q||c==CODE_L2X) - return i; - } - else { - id=code2obs(c); - if (id[0]==tobs[1]) return i; - } - } - else { /* ver.3 */ - id=code2obs(c); - if (!strcmp(id,tobs+1)) return i; - } +static int obsindex(int rnxver, int sys, const uint8_t *code, const char *tobs, const char *mask) { + char *id; + int i; + + for (i = 0; i < NFREQ + NEXOBS; i++) { + int c = code[i]; + if (c == CODE_NONE) continue; + + /* signal mask */ + if (mask[c - 1] == '0') continue; + + if (rnxver <= 299) { /* ver.2 */ + if (!strcmp(tobs, "C1") && (sys == SYS_GPS || sys == SYS_GLO || sys == SYS_QZS || + sys == SYS_SBS || sys == SYS_CMP)) { + if (c == CODE_L1C) return i; + } else if (!strcmp(tobs, "P1")) { + if (c == CODE_L1P || c == CODE_L1W || c == CODE_L1Y || c == CODE_L1N) return i; + } else if (!strcmp(tobs, "C2") && (sys == SYS_GPS || sys == SYS_QZS)) { + if (c == CODE_L2S || c == CODE_L2L || c == CODE_L2X) return i; + } else if (!strcmp(tobs, "C2") && sys == SYS_GLO) { + if (c == CODE_L2C) return i; + } else if (!strcmp(tobs, "P2")) { + if (c == CODE_L2P || c == CODE_L2W || c == CODE_L2Y || c == CODE_L2N || c == CODE_L2D) + return i; + } else if (rnxver >= 212 && tobs[1] == 'A') { /* L1C/A */ + if (c == CODE_L1C) return i; + } else if (rnxver >= 212 && tobs[1] == 'B') { /* L1C */ + if (c == CODE_L1S || c == CODE_L1L || c == CODE_L1X) return i; + } else if (rnxver >= 212 && tobs[1] == 'C') { /* L2C */ + if (c == CODE_L2S || c == CODE_L2L || c == CODE_L2X) return i; + } else if (rnxver >= 212 && tobs[1] == 'D' && sys == SYS_GLO) { /* GLO L2C/A */ + if (c == CODE_L2C) return i; + } else if (tobs[1] == '2' && sys == SYS_CMP) { /* BDS B1 */ + if (c == CODE_L2I || c == CODE_L2Q || c == CODE_L2X) return i; + } else { + id = code2obs(c); + if (id[0] == tobs[1]) return i; + } + } else { /* ver.3 */ + id = code2obs(c); + if (!strcmp(id, tobs + 1)) return i; } - return -1; + } + return -1; } /* output rinex event time ---------------------------------------------------*/ -static void outrinexevent(FILE *fp, const rnxopt_t *opt, const obsd_t *obs, - const double epdiff) -{ - int n; - double epe[6]; - - /* reject invalid time events (> 1 minute from timestamp of epoch) */ - if (fabs(epdiff)>60) { - return; - } +static void outrinexevent(FILE *fp, const rnxopt_t *opt, const obsd_t *obs, const double epdiff) { + int n; + double epe[6]; - time2epoch(obs[0].eventime,epe); - n = obs->timevalid ? 0 : 1; + /* reject invalid time events (> 1 minute from timestamp of epoch) */ + if (fabs(epdiff) > 60) { + return; + } - if (opt->rnxver<=299) { /* ver.2 */ - if (epdiff < 0) fprintf(fp,"\n"); - fprintf(fp," %02d %02.0f %02.0f %02.0f %02.0f%11.7f %d%3d", - (int)epe[0]%100,epe[1],epe[2],epe[3],epe[4],epe[5],5,n); - if (epdiff >= 0) fprintf(fp,"\n"); - } else { /* ver.3 */ - fprintf(fp,"> %04.0f %02.0f %02.0f %02.0f %02.0f%11.7f %d%3d\n", - epe[0],epe[1],epe[2],epe[3],epe[4],epe[5],5,n); - } - if (n) fprintf(fp,"%-60.60s%-20s\n"," Time mark is not valid","COMMENT"); + time2epoch(obs[0].eventime, epe); + n = obs->timevalid ? 0 : 1; + + if (opt->rnxver <= 299) { /* ver.2 */ + if (epdiff < 0) fprintf(fp, "\n"); + fprintf(fp, " %02d %02.0f %02.0f %02.0f %02.0f%11.7f %d%3d", (int)epe[0] % 100, epe[1], epe[2], + epe[3], epe[4], epe[5], 5, n); + if (epdiff >= 0) fprintf(fp, "\n"); + } else { /* ver.3 */ + fprintf(fp, "> %04.0f %02.0f %02.0f %02.0f %02.0f%11.7f %d%3d\n", epe[0], epe[1], epe[2], + epe[3], epe[4], epe[5], 5, n); + } + if (n) fprintf(fp, "%-60.60s%-20s\n", " Time mark is not valid", "COMMENT"); } /* output RINEX observation data body ------------------------------------------ -* output RINEX observation data body -* args : FILE *fp I output file pointer -* rnxopt_t *opt I RINEX options -* obsd_t *obs I observation data -* int n I number of observation data -* int flag I epoch flag (0:ok,1:power failure,>1:event flag) -* return : status (1:ok, 0:output error) -*-----------------------------------------------------------------------------*/ -extern int outrnxobsb(FILE *fp, const rnxopt_t *opt, const obsd_t *obs, int n, - int flag) -{ - double epdiff,ep[6],dL; - char sats[MAXOBS][4]={""}; - int i,k,ns,sys,ind[MAXOBS],s[MAXOBS]={0}; - - trace(3,"outrnxobsb: n=%d\n",n); - - time2epoch_n(obs[0].time,ep,7); /* output rounded to 7 decimals */ - - for (i=ns=0;inavsys)||opt->exsats[obs[i].sat-1]) continue; - if (!sat2code(obs[i].sat,sats[ns])) continue; - switch (sys) { - case SYS_GPS: s[ns]=RNX_SYS_GPS; break; - case SYS_GLO: s[ns]=RNX_SYS_GLO; break; - case SYS_GAL: s[ns]=RNX_SYS_GAL; break; - case SYS_QZS: s[ns]=RNX_SYS_QZS; break; - case SYS_SBS: s[ns]=RNX_SYS_SBS; break; - case SYS_CMP: s[ns]=RNX_SYS_CMP; break; - case SYS_IRN: s[ns]=RNX_SYS_IRN; break; - default: continue; - } - int m = (opt->rnxver <= 299) ? RNX_SYS_GPS : s[ns]; - const char *mask = opt->mask[m]; - int nobs = 0; - for (int j = 0; j < opt->nobs[m]; j++) - if (obsindex(opt->rnxver, sys, obs[i].code, opt->tobs[m][j], mask) >= 0) nobs++; - if (nobs == 0) continue; - ind[ns++] = i; - } - if (ns<=0) return 1; - /* if epoch of event less than epoch of observation, then first output - time mark, else first output observation record */ - epdiff = timediff(obs[0].time,obs[0].eventime); - if (flag == 5 && epdiff >= 0) { - outrinexevent(fp, opt, obs, epdiff); - } - if (opt->rnxver<=299) { /* ver.2 */ - fprintf(fp," %02d %02.0f %02.0f %02.0f %02.0f %010.7f %d%3d", - (int)ep[0]%100,ep[1],ep[2],ep[3],ep[4],ep[5],0,ns); - for (i=0;i0&&i%12==0) fprintf(fp,"\n%32s",""); - fprintf(fp,"%-3s",sats[i]); - } + * output RINEX observation data body + * args : FILE *fp I output file pointer + * rnxopt_t *opt I RINEX options + * obsd_t *obs I observation data + * int n I number of observation data + * int flag I epoch flag (0:ok,1:power failure,>1:event flag) + * return : status (1:ok, 0:output error) + *-----------------------------------------------------------------------------*/ +extern int outrnxobsb(FILE *fp, const rnxopt_t *opt, const obsd_t *obs, int n, int flag) { + double epdiff, ep[6], dL; + char sats[MAXOBS][4] = {""}; + int i, k, ns, sys, ind[MAXOBS], s[MAXOBS] = {0}; + + trace(3, "outrnxobsb: n=%d\n", n); + + time2epoch_n(obs[0].time, ep, 7); /* output rounded to 7 decimals */ + + for (i = ns = 0; i < n && ns < MAXOBS; i++) { + sys = satsys(obs[i].sat, NULL); + if (!(sys & opt->navsys) || opt->exsats[obs[i].sat - 1]) continue; + if (!sat2code(obs[i].sat, sats[ns])) continue; + switch (sys) { + case SYS_GPS: + s[ns] = RNX_SYS_GPS; + break; + case SYS_GLO: + s[ns] = RNX_SYS_GLO; + break; + case SYS_GAL: + s[ns] = RNX_SYS_GAL; + break; + case SYS_QZS: + s[ns] = RNX_SYS_QZS; + break; + case SYS_SBS: + s[ns] = RNX_SYS_SBS; + break; + case SYS_CMP: + s[ns] = RNX_SYS_CMP; + break; + case SYS_IRN: + s[ns] = RNX_SYS_IRN; + break; + default: + continue; + } + int m = (opt->rnxver <= 299) ? RNX_SYS_GPS : s[ns]; + const char *mask = opt->mask[m]; + int nobs = 0; + for (int j = 0; j < opt->nobs[m]; j++) + if (obsindex(opt->rnxver, sys, obs[i].code, opt->tobs[m][j], mask) >= 0) nobs++; + if (nobs == 0) continue; + ind[ns++] = i; + } + if (ns <= 0) return 1; + /* if epoch of event less than epoch of observation, then first output + time mark, else first output observation record */ + epdiff = timediff(obs[0].time, obs[0].eventime); + if (flag == 5 && epdiff >= 0) { + outrinexevent(fp, opt, obs, epdiff); + } + if (opt->rnxver <= 299) { /* ver.2 */ + fprintf(fp, " %02d %02.0f %02.0f %02.0f %02.0f %010.7f %d%3d", (int)ep[0] % 100, ep[1], ep[2], + ep[3], ep[4], ep[5], 0, ns); + for (i = 0; i < ns; i++) { + if (i > 0 && i % 12 == 0) fprintf(fp, "\n%32s", ""); + fprintf(fp, "%-3s", sats[i]); + } + } else { /* ver.3 */ + fprintf(fp, "> %04.0f %02.0f %02.0f %02.0f %02.0f %010.7f %d%3d%21s\n", ep[0], ep[1], ep[2], + ep[3], ep[4], ep[5], 0, ns, ""); + } + for (i = 0; i < ns; i++) { + sys = satsys(obs[ind[i]].sat, NULL); + + int m; + const char *mask; + if (opt->rnxver <= 299) { /* ver.2 */ + m = RNX_SYS_GPS; + mask = opt->mask[s[i]]; + } else { /* ver.3 */ + fprintf(fp, "%-3s", sats[i]); + m = s[i]; + mask = opt->mask[m]; } - else { /* ver.3 */ - fprintf(fp,"> %04.0f %02.0f %02.0f %02.0f %02.0f %010.7f %d%3d%21s\n", - ep[0],ep[1],ep[2],ep[3],ep[4],ep[5],0,ns,""); + for (int j = 0; j < opt->nobs[m]; j++) { + if (opt->rnxver <= 299) { /* ver.2 */ + if (j % 5 == 0) fprintf(fp, "\n"); + } + /* search obs data index */ + if ((k = obsindex(opt->rnxver, sys, obs[ind[i]].code, opt->tobs[m][j], mask)) < 0) { + outrnxobsf(fp, 0.0, -1, -1); + continue; + } + /* phase shift (cyc) */ + dL = (obs[ind[i]].L[k] != 0.0) ? opt->shift[m][j] : 0.0; + + /* output field */ + switch (opt->tobs[m][j][0]) { + case 'C': + case 'P': { + // To RTKLib RINEX encoding + float std = obs[ind[i]].Pstd[k]; + int stdi = std > 0.0003125 ? log2(std * 100) - 5 + 0.5 : 0; + outrnxobsf(fp, obs[ind[i]].P[k], -1, stdi); + break; + } + case 'L': { + // To RTKLib RINEX encoding + int lstdi = obs[ind[i]].Lstd[k] / 0.004 + 0.5; + outrnxobsf(fp, obs[ind[i]].L[k] + dL, obs[ind[i]].LLI[k], lstdi); + break; + } + case 'D': + outrnxobsf(fp, obs[ind[i]].D[k], -1, -1); + break; + case 'S': + outrnxobsf(fp, obs[ind[i]].SNR[k], -1, -1); + break; + } } - for (i=0;irnxver<=299) { /* ver.2 */ - m=RNX_SYS_GPS; - mask=opt->mask[s[i]]; - } - else { /* ver.3 */ - fprintf(fp,"%-3s",sats[i]); - m=s[i]; - mask=opt->mask[m]; - } - for (int j=0;jnobs[m];j++) { - - if (opt->rnxver<=299) { /* ver.2 */ - if (j%5==0) fprintf(fp,"\n"); - } - /* search obs data index */ - if ((k=obsindex(opt->rnxver,sys,obs[ind[i]].code,opt->tobs[m][j], - mask))<0) { - outrnxobsf(fp,0.0,-1,-1); - continue; - } - /* phase shift (cyc) */ - dL=(obs[ind[i]].L[k]!=0.0)?opt->shift[m][j]:0.0; - - /* output field */ - switch (opt->tobs[m][j][0]) { - case 'C': - case 'P': { - // To RTKLib RINEX encoding - float std = obs[ind[i]].Pstd[k]; - int stdi = std > 0.0003125 ? log2(std * 100) - 5 + 0.5 : 0; - outrnxobsf(fp,obs[ind[i]].P[k],-1,stdi); - break; - } - case 'L': { - // To RTKLib RINEX encoding - int lstdi = obs[ind[i]].Lstd[k] / 0.004 + 0.5; - outrnxobsf(fp,obs[ind[i]].L[k]+dL,obs[ind[i]].LLI[k],lstdi); - break; - } - case 'D': outrnxobsf(fp,obs[ind[i]].D[k],-1,-1); break; - case 'S': outrnxobsf(fp,obs[ind[i]].SNR[k],-1,-1); break; - } - } - /* set trace level to 1 generate CSV file of raw observations */ + /* set trace level to 1 generate CSV file of raw observations */ #ifdef TRACE - if (gettracelevel()==1) { - trace(1,",%16.2f,%3d,%13.2f,%13.2f,%9.2f,%2.0f,%1d,%3.4f,%13.2f,%13.2f,%9.2f,%2.0f,%1d,%3.4f\n", - obs[0].time.time + obs[0].time.sec, obs[ind[i]].sat, - obs[ind[i]].P[0], obs[ind[i]].L[0], obs[ind[i]].D[0], - obs[ind[i]].SNR[0], obs[ind[i]].LLI[0], obs[ind[i]].Lstd[0], - obs[ind[i]].P[1], obs[ind[i]].L[1], obs[ind[i]].D[1], - obs[ind[i]].SNR[1], obs[ind[i]].LLI[1], obs[ind[i]].Lstd[1]); - } + if (gettracelevel() == 1) { + trace(1, + ",%16.2f,%3d,%13.2f,%13.2f,%9.2f,%2.0f,%1d,%3.4f,%13.2f,%13.2f,%9.2f,%2.0f,%1d,%3.4f\n", + obs[0].time.time + obs[0].time.sec, obs[ind[i]].sat, obs[ind[i]].P[0], obs[ind[i]].L[0], + obs[ind[i]].D[0], obs[ind[i]].SNR[0], obs[ind[i]].LLI[0], obs[ind[i]].Lstd[0], + obs[ind[i]].P[1], obs[ind[i]].L[1], obs[ind[i]].D[1], obs[ind[i]].SNR[1], + obs[ind[i]].LLI[1], obs[ind[i]].Lstd[1]); + } #endif - if (opt->rnxver>=300&&fprintf(fp,"\n")==EOF) return 0; - } + if (opt->rnxver >= 300 && fprintf(fp, "\n") == EOF) return 0; + } - if (flag == 5 && epdiff < 0) { - outrinexevent(fp, opt, obs, epdiff); - } - if (opt->rnxver>=300) return 1; + if (flag == 5 && epdiff < 0) { + outrinexevent(fp, opt, obs, epdiff); + } + if (opt->rnxver >= 300) return 1; - return fprintf(fp,"\n")!=EOF; + return fprintf(fp, "\n") != EOF; } /* output data field in RINEX navigation data --------------------------------*/ -static void outnavf_n(FILE *fp, double value, int n) -{ - double e=(fabs(value)<1E-99)?0.0:floor(log10(fabs(value))+1.0); +static void outnavf_n(FILE *fp, double value, int n) { + double e = (fabs(value) < 1E-99) ? 0.0 : floor(log10(fabs(value)) + 1.0); - fprintf(fp," %s.%0*.0f%s%+03.0f",value<0.0?"-":" ",n, - fabs(value)/pow(10.0,e-n),NAVEXP,e); -} -static void outnavf(FILE *fp, double value) -{ - outnavf_n(fp,value,12); + fprintf(fp, " %s.%0*.0f%s%+03.0f", value < 0.0 ? "-" : " ", n, fabs(value) / pow(10.0, e - n), + NAVEXP, e); } +static void outnavf(FILE *fp, double value) { outnavf_n(fp, value, 12); } /* output iono correction for a system ---------------------------------------*/ -static void out_iono_sys(FILE *fp, const char *sys, const double *ion, int n) -{ - const char *label1[]={"ION ALPHA","ION BETA"},*label2="IONOSPHERIC CORR"; - char str[32]; - int i,j; - - if (norm(ion,n)<=0.0) return; - - for (i=0;i<(n+3)/4;i++) { - sprintf(str,"%s%c",sys,(!*sys||n<4)?' ':'A'+i); - fprintf(fp,"%-*s ",!*sys?1:4,str); - for (j=0;j<4&&i*4+joutiono) return; - - if (sys&opt->navsys&SYS_GPS) { - if (opt->rnxver<=211) out_iono_sys(fp,"",nav->ion_gps,8); - else out_iono_sys(fp,"GPS",nav->ion_gps,8); - } - if ((sys&opt->navsys&SYS_GAL)&&opt->rnxver>=212) { - out_iono_sys(fp,"GAL",nav->ion_gal,3); - } - if ((sys&opt->navsys&SYS_QZS)&&opt->rnxver>=302) { - out_iono_sys(fp,"QZS",nav->ion_qzs,8); - } - if ((sys&opt->navsys&SYS_CMP)&&opt->rnxver>=302) { - out_iono_sys(fp,"BDS",nav->ion_cmp,8); - } - if ((sys&opt->navsys&SYS_IRN)&&opt->rnxver>=303) { - out_iono_sys(fp,"IRN",nav->ion_irn,8); - } +static void out_iono(FILE *fp, int sys, const rnxopt_t *opt, const nav_t *nav) { + if (!opt->outiono) return; + + if (sys & opt->navsys & SYS_GPS) { + if (opt->rnxver <= 211) + out_iono_sys(fp, "", nav->ion_gps, 8); + else + out_iono_sys(fp, "GPS", nav->ion_gps, 8); + } + if ((sys & opt->navsys & SYS_GAL) && opt->rnxver >= 212) { + out_iono_sys(fp, "GAL", nav->ion_gal, 3); + } + if ((sys & opt->navsys & SYS_QZS) && opt->rnxver >= 302) { + out_iono_sys(fp, "QZS", nav->ion_qzs, 8); + } + if ((sys & opt->navsys & SYS_CMP) && opt->rnxver >= 302) { + out_iono_sys(fp, "BDS", nav->ion_cmp, 8); + } + if ((sys & opt->navsys & SYS_IRN) && opt->rnxver >= 303) { + out_iono_sys(fp, "IRN", nav->ion_irn, 8); + } } /* output time system correction for a system --------------------------------*/ -static void out_time_sys(FILE *fp, const char *sys, const double *utc) -{ - const char *label1="TIME SYSTEM CORR",*label2="DELTA-UTC: A0,A1,T,W"; - - if (norm(utc,3)<=0.0) return; - - if (*sys) { - fprintf(fp,"%-4s ",sys); - outnavf_n(fp,utc[0],10); - outnavf_n(fp,utc[1],9); - fprintf(fp,"%7.0f%5.0f%10s%-20s\n",utc[2],utc[3],"",label1); - } - else { - fprintf(fp," "); - outnavf_n(fp,utc[0],12); - outnavf_n(fp,utc[1],12); - fprintf(fp,"%9.0f%9.0f %-20s\n",utc[2],utc[3],label2); - } +static void out_time_sys(FILE *fp, const char *sys, const double *utc) { + const char *label1 = "TIME SYSTEM CORR", *label2 = "DELTA-UTC: A0,A1,T,W"; + + if (norm(utc, 3) <= 0.0) return; + + if (*sys) { + fprintf(fp, "%-4s ", sys); + outnavf_n(fp, utc[0], 10); + outnavf_n(fp, utc[1], 9); + fprintf(fp, "%7.0f%5.0f%10s%-20s\n", utc[2], utc[3], "", label1); + } else { + fprintf(fp, " "); + outnavf_n(fp, utc[0], 12); + outnavf_n(fp, utc[1], 12); + fprintf(fp, "%9.0f%9.0f %-20s\n", utc[2], utc[3], label2); + } } /* output time system corrections --------------------------------------------*/ -static void out_time(FILE *fp, int sys, const rnxopt_t *opt, const nav_t *nav) -{ - double utc[8]={0}; +static void out_time(FILE *fp, int sys, const rnxopt_t *opt, const nav_t *nav) { + double utc[8] = {0}; - if (!opt->outtime) return; + if (!opt->outtime) return; - if (sys&opt->navsys&SYS_GPS) { - if (opt->rnxver<=211) out_time_sys(fp,"",nav->utc_gps); - else out_time_sys(fp,"GPUT",nav->utc_gps); - } - if ((sys&opt->navsys&SYS_GLO)&&opt->rnxver>=212) { - /* RINEX 2.12-3.02: tau_C, 3.03- : -tau_C */ - utc[0]=(opt->rnxver<=302)?nav->utc_glo[0]:-nav->utc_glo[0]; - out_time_sys(fp,"GLUT",utc); - } - if ((sys&opt->navsys&SYS_SBS)&&opt->rnxver>=212) { - out_time_sys(fp,"SBUT",nav->utc_sbs); - } - if ((sys&opt->navsys&SYS_GAL)&&opt->rnxver>=212) { - out_time_sys(fp,"GAUT",nav->utc_gal); - } - if ((sys&opt->navsys&SYS_QZS)&&opt->rnxver>=302) { - out_time_sys(fp,"QZUT",nav->utc_qzs); - } - if ((sys&opt->navsys&SYS_CMP)&&opt->rnxver>=302) { - out_time_sys(fp,"BDUT",nav->utc_cmp); - } - if ((sys&opt->navsys&SYS_IRN)&&opt->rnxver>=303) { - out_time_sys(fp,"IRUT",nav->utc_irn); - } + if (sys & opt->navsys & SYS_GPS) { + if (opt->rnxver <= 211) + out_time_sys(fp, "", nav->utc_gps); + else + out_time_sys(fp, "GPUT", nav->utc_gps); + } + if ((sys & opt->navsys & SYS_GLO) && opt->rnxver >= 212) { + /* RINEX 2.12-3.02: tau_C, 3.03- : -tau_C */ + utc[0] = (opt->rnxver <= 302) ? nav->utc_glo[0] : -nav->utc_glo[0]; + out_time_sys(fp, "GLUT", utc); + } + if ((sys & opt->navsys & SYS_SBS) && opt->rnxver >= 212) { + out_time_sys(fp, "SBUT", nav->utc_sbs); + } + if ((sys & opt->navsys & SYS_GAL) && opt->rnxver >= 212) { + out_time_sys(fp, "GAUT", nav->utc_gal); + } + if ((sys & opt->navsys & SYS_QZS) && opt->rnxver >= 302) { + out_time_sys(fp, "QZUT", nav->utc_qzs); + } + if ((sys & opt->navsys & SYS_CMP) && opt->rnxver >= 302) { + out_time_sys(fp, "BDUT", nav->utc_cmp); + } + if ((sys & opt->navsys & SYS_IRN) && opt->rnxver >= 303) { + out_time_sys(fp, "IRUT", nav->utc_irn); + } } /* output leap seconds -------------------------------------------------------*/ -static void out_leaps(FILE *fp, int sys, const rnxopt_t *opt, const nav_t *nav) -{ - const char *label="LEAP SECONDS"; - const double *leaps; - - if (!opt->outleaps) return; - - switch (sys) { - case SYS_GAL: leaps=nav->utc_gal+4; break; - case SYS_QZS: leaps=nav->utc_qzs+4; break; - case SYS_CMP: leaps=nav->utc_cmp+4; break; - case SYS_IRN: leaps=nav->utc_irn+4; break; - default : leaps=nav->utc_gps+4; break; - } - if (leaps[0]==0.0) return; - - if (opt->rnxver<=300) { - if (sys==SYS_GPS) fprintf(fp,"%6.0f%54s%-20s\n",leaps[0],"",label); - } - else if (norm(leaps+1,3)<=0.0) { - fprintf(fp,"%6.0f%18s%3s%33s%-20s\n",leaps[0],"", - (sys==SYS_CMP)?"BDS":"","",label); - } - else { - fprintf(fp,"%6.0f%6.0f%6.0f%6.0f%3s%33s%-20s\n",leaps[0], - leaps[3],leaps[1],leaps[2],(sys==SYS_CMP)?"BDS":"","",label); - } +static void out_leaps(FILE *fp, int sys, const rnxopt_t *opt, const nav_t *nav) { + const char *label = "LEAP SECONDS"; + const double *leaps; + + if (!opt->outleaps) return; + + switch (sys) { + case SYS_GAL: + leaps = nav->utc_gal + 4; + break; + case SYS_QZS: + leaps = nav->utc_qzs + 4; + break; + case SYS_CMP: + leaps = nav->utc_cmp + 4; + break; + case SYS_IRN: + leaps = nav->utc_irn + 4; + break; + default: + leaps = nav->utc_gps + 4; + break; + } + if (leaps[0] == 0.0) return; + + if (opt->rnxver <= 300) { + if (sys == SYS_GPS) fprintf(fp, "%6.0f%54s%-20s\n", leaps[0], "", label); + } else if (norm(leaps + 1, 3) <= 0.0) { + fprintf(fp, "%6.0f%18s%3s%33s%-20s\n", leaps[0], "", (sys == SYS_CMP) ? "BDS" : "", "", label); + } else { + fprintf(fp, "%6.0f%6.0f%6.0f%6.0f%3s%33s%-20s\n", leaps[0], leaps[3], leaps[1], leaps[2], + (sys == SYS_CMP) ? "BDS" : "", "", label); + } } /* output RINEX navigation data file header ------------------------------------ -* output RINEX navigation data file header -* args : FILE *fp I output file pointer -* rnxopt_t *opt I RINEX options -* nav_t nav I navigation data (NULL: no input) -* return : status (1:ok, 0:output error) -*-----------------------------------------------------------------------------*/ -extern int outrnxnavh(FILE *fp, const rnxopt_t *opt, const nav_t *nav) -{ - int i; - char date[32],*sys; - - trace(3,"outrnxnavh:\n"); - - timestr_rnx(date); - - if (opt->rnxver<=299) { /* ver.2 */ - fprintf(fp,"%9.2f %-20s%-20s%-20s\n",opt->rnxver/100.0, - "N: GPS NAV DATA","","RINEX VERSION / TYPE"); - } - else { /* ver.3 */ - if (opt->navsys==SYS_GPS) sys="G: GPS"; - else if (opt->navsys==SYS_GLO) sys="R: GLONASS"; - else if (opt->navsys==SYS_GAL) sys="E: Galileo"; - else if (opt->navsys==SYS_QZS) sys="J: QZSS"; /* v.3.02 */ - else if (opt->navsys==SYS_CMP) sys="C: BeiDou"; /* v.3.02 */ - else if (opt->navsys==SYS_IRN) sys="I: IRNSS"; /* v.3.03 */ - else if (opt->navsys==SYS_SBS) sys="S: SBAS Payload"; - else if (opt->sep_nav) sys="G: GPS"; - else sys="M: Mixed"; - - fprintf(fp,"%9.2f %-20s%-20s%-20s\n",opt->rnxver/100.0, - "N: GNSS NAV DATA",sys,"RINEX VERSION / TYPE"); - } - fprintf(fp,"%-20.20s%-20.20s%-20.20s%-20s\n",opt->prog,opt->runby,date, - "PGM / RUN BY / DATE"); - - for (i=0;icomment[i]) continue; - fprintf(fp,"%-60.60s%-20s\n",opt->comment[i],"COMMENT"); - } - out_iono(fp,opt->sep_nav?SYS_GPS:SYS_ALL,opt,nav); - out_time(fp,opt->sep_nav?SYS_GPS:SYS_ALL,opt,nav); - out_leaps(fp,SYS_GPS,opt,nav); - - return fprintf(fp,"%60s%-20s\n","","END OF HEADER")!=EOF; -} -/* output RINEX navigation data file body -------------------------------------- -* output RINEX navigation data file body -* args : FILE *fp I output file pointer -* rnxopt_t *opt I RINEX options -* eph_t *eph I ephemeris -* return : status (1:ok, 0:output error) -*-----------------------------------------------------------------------------*/ -extern int outrnxnavb(FILE *fp, const rnxopt_t *opt, const eph_t *eph) -{ - double ep[6],ttr; - int week,sys,prn; - char code[32],*sep; - - trace(3,"outrnxnavb: sat=%2d\n",eph->sat); - - if (!(sys=satsys(eph->sat,&prn))||!(sys&opt->navsys)) return 0; - - if (sys!=SYS_CMP) { - time2epoch(eph->toc,ep); - } - else { - time2epoch(gpst2bdt(eph->toc),ep); /* gpst -> bdt */ - } - if ((opt->rnxver>=300&&sys==SYS_GPS)||(opt->rnxver>=212&&sys==SYS_GAL)|| - (opt->rnxver>=302&&sys==SYS_QZS)||(opt->rnxver>=302&&sys==SYS_CMP)|| - (opt->rnxver>=303&&sys==SYS_IRN)) { - if (!sat2code(eph->sat,code)) return 0; - fprintf(fp,"%-3s %04.0f %02.0f %02.0f %02.0f %02.0f %02.0f",code,ep[0], - ep[1],ep[2],ep[3],ep[4],ep[5]); - sep=" "; - } - else if (opt->rnxver<=299&&sys==SYS_GPS) { - fprintf(fp,"%2d %02d %02.0f %02.0f %02.0f %02.0f %04.1f",prn, - (int)ep[0]%100,ep[1],ep[2],ep[3],ep[4],ep[5]); - sep=" "; - } - else { - return 0; - } - outnavf(fp,eph->f0 ); - outnavf(fp,eph->f1 ); - outnavf(fp,eph->f2 ); - fprintf(fp,"\n%s",sep ); - - outnavf(fp,eph->iode ); /* GPS/QZS: IODE, GAL: IODnav, BDS: AODE */ - outnavf(fp,eph->crs ); - outnavf(fp,eph->deln ); - outnavf(fp,eph->M0 ); - fprintf(fp,"\n%s",sep ); - - outnavf(fp,eph->cuc ); - outnavf(fp,eph->e ); - outnavf(fp,eph->cus ); - outnavf(fp,sqrt(eph->A)); - fprintf(fp,"\n%s",sep ); - - outnavf(fp,eph->toes ); - outnavf(fp,eph->cic ); - outnavf(fp,eph->OMG0 ); - outnavf(fp,eph->cis ); - fprintf(fp,"\n%s",sep ); - - outnavf(fp,eph->i0 ); - outnavf(fp,eph->crc ); - outnavf(fp,eph->omg ); - outnavf(fp,eph->OMGd ); - fprintf(fp,"\n%s",sep ); + * output RINEX navigation data file header + * args : FILE *fp I output file pointer + * rnxopt_t *opt I RINEX options + * nav_t nav I navigation data (NULL: no input) + * return : status (1:ok, 0:output error) + *-----------------------------------------------------------------------------*/ +extern int outrnxnavh(FILE *fp, const rnxopt_t *opt, const nav_t *nav) { + int i; + char date[32], *sys; + + trace(3, "outrnxnavh:\n"); + + timestr_rnx(date); + + if (opt->rnxver <= 299) { /* ver.2 */ + fprintf(fp, "%9.2f %-20s%-20s%-20s\n", opt->rnxver / 100.0, "N: GPS NAV DATA", "", + "RINEX VERSION / TYPE"); + } else { /* ver.3 */ + if (opt->navsys == SYS_GPS) + sys = "G: GPS"; + else if (opt->navsys == SYS_GLO) + sys = "R: GLONASS"; + else if (opt->navsys == SYS_GAL) + sys = "E: Galileo"; + else if (opt->navsys == SYS_QZS) + sys = "J: QZSS"; /* v.3.02 */ + else if (opt->navsys == SYS_CMP) + sys = "C: BeiDou"; /* v.3.02 */ + else if (opt->navsys == SYS_IRN) + sys = "I: IRNSS"; /* v.3.03 */ + else if (opt->navsys == SYS_SBS) + sys = "S: SBAS Payload"; + else if (opt->sep_nav) + sys = "G: GPS"; + else + sys = "M: Mixed"; + + fprintf(fp, "%9.2f %-20s%-20s%-20s\n", opt->rnxver / 100.0, "N: GNSS NAV DATA", sys, + "RINEX VERSION / TYPE"); + } + fprintf(fp, "%-20.20s%-20.20s%-20.20s%-20s\n", opt->prog, opt->runby, date, + "PGM / RUN BY / DATE"); - outnavf(fp,eph->idot ); - outnavf(fp,eph->code ); - outnavf(fp,eph->week ); /* GPS/QZS: GPS week, GAL: GAL week, BDS: BDT week */ - if (sys==SYS_GPS||sys==SYS_QZS) { - outnavf(fp,eph->flag); - } - else { - outnavf(fp,0.0); /* spare */ - } - fprintf(fp,"\n%s",sep ); + for (i = 0; i < MAXCOMMENT; i++) { + if (!*opt->comment[i]) continue; + fprintf(fp, "%-60.60s%-20s\n", opt->comment[i], "COMMENT"); + } + out_iono(fp, opt->sep_nav ? SYS_GPS : SYS_ALL, opt, nav); + out_time(fp, opt->sep_nav ? SYS_GPS : SYS_ALL, opt, nav); + out_leaps(fp, SYS_GPS, opt, nav); - if (sys==SYS_GAL) { - outnavf(fp,sisa_value(eph->sva)); - } - else { - outnavf(fp,uravalue(eph->sva)); - } - outnavf(fp,eph->svh ); - outnavf(fp,eph->tgd[0] ); /* GPS/QZS:TGD, GAL:BGD E5a/E1, BDS: TGD1 B1/B3 */ - if (sys==SYS_GAL||sys==SYS_CMP) { - outnavf(fp,eph->tgd[1]); /* GAL:BGD E5b/E1, BDS: TGD2 B2/B3 */ - } - else if (sys==SYS_GPS||sys==SYS_QZS) { - outnavf(fp,eph->iodc); /* GPS/QZS:IODC */ - } - else { - outnavf(fp,0.0); /* spare */ - } - fprintf(fp,"\n%s",sep ); + return fprintf(fp, "%60s%-20s\n", "", "END OF HEADER") != EOF; +} +/* output RINEX navigation data file body -------------------------------------- + * output RINEX navigation data file body + * args : FILE *fp I output file pointer + * rnxopt_t *opt I RINEX options + * eph_t *eph I ephemeris + * return : status (1:ok, 0:output error) + *-----------------------------------------------------------------------------*/ +extern int outrnxnavb(FILE *fp, const rnxopt_t *opt, const eph_t *eph) { + double ep[6], ttr; + int week, sys, prn; + char code[32], *sep; + + trace(3, "outrnxnavb: sat=%2d\n", eph->sat); + + if (!(sys = satsys(eph->sat, &prn)) || !(sys & opt->navsys)) return 0; + + if (sys != SYS_CMP) { + time2epoch(eph->toc, ep); + } else { + time2epoch(gpst2bdt(eph->toc), ep); /* gpst -> bdt */ + } + if ((opt->rnxver >= 300 && sys == SYS_GPS) || (opt->rnxver >= 212 && sys == SYS_GAL) || + (opt->rnxver >= 302 && sys == SYS_QZS) || (opt->rnxver >= 302 && sys == SYS_CMP) || + (opt->rnxver >= 303 && sys == SYS_IRN)) { + if (!sat2code(eph->sat, code)) return 0; + fprintf(fp, "%-3s %04.0f %02.0f %02.0f %02.0f %02.0f %02.0f", code, ep[0], ep[1], ep[2], ep[3], + ep[4], ep[5]); + sep = " "; + } else if (opt->rnxver <= 299 && sys == SYS_GPS) { + fprintf(fp, "%2d %02d %02.0f %02.0f %02.0f %02.0f %04.1f", prn, (int)ep[0] % 100, ep[1], ep[2], + ep[3], ep[4], ep[5]); + sep = " "; + } else { + return 0; + } + outnavf(fp, eph->f0); + outnavf(fp, eph->f1); + outnavf(fp, eph->f2); + fprintf(fp, "\n%s", sep); + + outnavf(fp, eph->iode); /* GPS/QZS: IODE, GAL: IODnav, BDS: AODE */ + outnavf(fp, eph->crs); + outnavf(fp, eph->deln); + outnavf(fp, eph->M0); + fprintf(fp, "\n%s", sep); + + outnavf(fp, eph->cuc); + outnavf(fp, eph->e); + outnavf(fp, eph->cus); + outnavf(fp, sqrt(eph->A)); + fprintf(fp, "\n%s", sep); + + outnavf(fp, eph->toes); + outnavf(fp, eph->cic); + outnavf(fp, eph->OMG0); + outnavf(fp, eph->cis); + fprintf(fp, "\n%s", sep); + + outnavf(fp, eph->i0); + outnavf(fp, eph->crc); + outnavf(fp, eph->omg); + outnavf(fp, eph->OMGd); + fprintf(fp, "\n%s", sep); + + outnavf(fp, eph->idot); + outnavf(fp, eph->code); + outnavf(fp, eph->week); /* GPS/QZS: GPS week, GAL: GAL week, BDS: BDT week */ + if (sys == SYS_GPS || sys == SYS_QZS) { + outnavf(fp, eph->flag); + } else { + outnavf(fp, 0.0); /* spare */ + } + fprintf(fp, "\n%s", sep); - if (sys!=SYS_CMP) { - ttr=time2gpst(eph->ttr,&week); - } - else { - ttr=time2bdt(gpst2bdt(eph->ttr),&week); /* gpst -> bdt */ - } - outnavf(fp,ttr+(week-eph->week)*604800.0); + if (sys == SYS_GAL) { + outnavf(fp, sisa_value(eph->sva)); + } else { + outnavf(fp, uravalue(eph->sva)); + } + outnavf(fp, eph->svh); + outnavf(fp, eph->tgd[0]); /* GPS/QZS:TGD, GAL:BGD E5a/E1, BDS: TGD1 B1/B3 */ + if (sys == SYS_GAL || sys == SYS_CMP) { + outnavf(fp, eph->tgd[1]); /* GAL:BGD E5b/E1, BDS: TGD2 B2/B3 */ + } else if (sys == SYS_GPS || sys == SYS_QZS) { + outnavf(fp, eph->iodc); /* GPS/QZS:IODC */ + } else { + outnavf(fp, 0.0); /* spare */ + } + fprintf(fp, "\n%s", sep); - if (sys==SYS_GPS) { - outnavf(fp,eph->fit); - } - else if (sys==SYS_QZS) { - outnavf(fp,eph->fit>2?1.0:0.0); - } - else if (sys==SYS_CMP) { - outnavf(fp,eph->iodc); /* AODC */ - } - else { - outnavf(fp,0.0); /* spare */ - } - return fprintf(fp,"\n")!=EOF; + if (sys != SYS_CMP) { + ttr = time2gpst(eph->ttr, &week); + } else { + ttr = time2bdt(gpst2bdt(eph->ttr), &week); /* gpst -> bdt */ + } + outnavf(fp, ttr + (week - eph->week) * 604800.0); + + if (sys == SYS_GPS) { + outnavf(fp, eph->fit); + } else if (sys == SYS_QZS) { + outnavf(fp, eph->fit > 2 ? 1.0 : 0.0); + } else if (sys == SYS_CMP) { + outnavf(fp, eph->iodc); /* AODC */ + } else { + outnavf(fp, 0.0); /* spare */ + } + return fprintf(fp, "\n") != EOF; } /* output RINEX GNAV file header ----------------------------------------------- -* output RINEX GNAV (GLONASS navigation data) file header -* args : FILE *fp I output file pointer -* rnxopt_t *opt I RINEX options -* nav_t nav I navigation data (NULL: no input) -* return : status (1:ok, 0:output error) -*-----------------------------------------------------------------------------*/ -extern int outrnxgnavh(FILE *fp, const rnxopt_t *opt, const nav_t *nav) -{ - int i; - char date[32]; - - trace(3,"outrnxgnavh:\n"); - - timestr_rnx(date); - - if (opt->rnxver<=299) { /* ver.2 */ - fprintf(fp,"%9.2f %-20s%-20s%-20s\n",opt->rnxver/100.0, - "GLONASS NAV DATA","","RINEX VERSION / TYPE"); - } - else { /* ver.3 */ - fprintf(fp,"%9.2f %-20s%-20s%-20s\n",opt->rnxver/100.0, - "N: GNSS NAV DATA","R: GLONASS","RINEX VERSION / TYPE"); - } - fprintf(fp,"%-20.20s%-20.20s%-20.20s%-20s\n",opt->prog,opt->runby,date, - "PGM / RUN BY / DATE"); + * output RINEX GNAV (GLONASS navigation data) file header + * args : FILE *fp I output file pointer + * rnxopt_t *opt I RINEX options + * nav_t nav I navigation data (NULL: no input) + * return : status (1:ok, 0:output error) + *-----------------------------------------------------------------------------*/ +extern int outrnxgnavh(FILE *fp, const rnxopt_t *opt, const nav_t *nav) { + int i; + char date[32]; + + trace(3, "outrnxgnavh:\n"); + + timestr_rnx(date); + + if (opt->rnxver <= 299) { /* ver.2 */ + fprintf(fp, "%9.2f %-20s%-20s%-20s\n", opt->rnxver / 100.0, "GLONASS NAV DATA", "", + "RINEX VERSION / TYPE"); + } else { /* ver.3 */ + fprintf(fp, "%9.2f %-20s%-20s%-20s\n", opt->rnxver / 100.0, "N: GNSS NAV DATA", + "R: GLONASS", "RINEX VERSION / TYPE"); + } + fprintf(fp, "%-20.20s%-20.20s%-20.20s%-20s\n", opt->prog, opt->runby, date, + "PGM / RUN BY / DATE"); - for (i=0;icomment[i]) continue; - fprintf(fp,"%-60.60s%-20s\n",opt->comment[i],"COMMENT"); - } - out_time(fp,SYS_GLO,opt,nav); - out_leaps(fp,SYS_GPS,opt,nav); + for (i = 0; i < MAXCOMMENT; i++) { + if (!*opt->comment[i]) continue; + fprintf(fp, "%-60.60s%-20s\n", opt->comment[i], "COMMENT"); + } + out_time(fp, SYS_GLO, opt, nav); + out_leaps(fp, SYS_GPS, opt, nav); - return fprintf(fp,"%60s%-20s\n","","END OF HEADER")!=EOF; + return fprintf(fp, "%60s%-20s\n", "", "END OF HEADER") != EOF; } /* output RINEX GNAV file body ------------------------------------------------- -* output RINEX GNAV (GLONASS navigation data) file body -* args : FILE *fp I output file pointer -* rnxopt_t *opt I rinex options -* geph_t *geph I glonass ephemeris -* return : status (1:ok, 0:output error) -*-----------------------------------------------------------------------------*/ -extern int outrnxgnavb(FILE *fp, const rnxopt_t *opt, const geph_t *geph) -{ - gtime_t toe; - double ep[6],tof; - int prn; - char code[32],*sep; - - trace(3,"outrnxgnavb: sat=%2d\n",geph->sat); - - if ((satsys(geph->sat,&prn)&opt->navsys)!=SYS_GLO) return 0; - - tof=time2gpst(gpst2utc(geph->tof),NULL); /* v.3: tow in utc */ - if (opt->rnxver<=299) tof=fmod(tof,86400.0); /* v.2: tod in utc */ - - toe=gpst2utc(geph->toe); /* gpst -> utc */ - time2epoch(toe,ep); - - if (opt->rnxver<=299) { /* ver.2 */ - fprintf(fp,"%2d %02d %02.0f %02.0f %02.0f %02.0f %04.1f",prn, - (int)ep[0]%100,ep[1],ep[2],ep[3],ep[4],ep[5]); - sep=" "; - } - else { /* ver.3 */ - if (!sat2code(geph->sat,code)) return 0; - fprintf(fp,"%-3s %04.0f %02.0f %02.0f %02.0f %02.0f %02.0f",code,ep[0], - ep[1],ep[2],ep[3],ep[4],ep[5]); - sep=" "; - } - outnavf(fp,-geph->taun ); - outnavf(fp,geph->gamn ); - outnavf(fp,tof ); - fprintf(fp,"\n%s",sep ); - - outnavf(fp,geph->pos[0]/1E3); - outnavf(fp,geph->vel[0]/1E3); - outnavf(fp,geph->acc[0]/1E3); - outnavf(fp,geph->svh & 1 ); - fprintf(fp,"\n%s",sep ); - - outnavf(fp,geph->pos[1]/1E3); - outnavf(fp,geph->vel[1]/1E3); - outnavf(fp,geph->acc[1]/1E3); - outnavf(fp,geph->frq ); - fprintf(fp,"\n%s",sep ); - - outnavf(fp,geph->pos[2]/1E3); - outnavf(fp,geph->vel[2]/1E3); - outnavf(fp,geph->acc[2]/1E3); - outnavf(fp,geph->age ); - - if (opt->rnxver>=305) { - fprintf(fp,"\n%s",sep ); - outnavf(fp,geph->flags ); - outnavf(fp,geph->dtaun ); - outnavf(fp,geph->sva ); - outnavf(fp,(geph->svh >> 1) & 7); - } - return fprintf(fp,"\n")!=EOF; + * output RINEX GNAV (GLONASS navigation data) file body + * args : FILE *fp I output file pointer + * rnxopt_t *opt I rinex options + * geph_t *geph I glonass ephemeris + * return : status (1:ok, 0:output error) + *-----------------------------------------------------------------------------*/ +extern int outrnxgnavb(FILE *fp, const rnxopt_t *opt, const geph_t *geph) { + gtime_t toe; + double ep[6], tof; + int prn; + char code[32], *sep; + + trace(3, "outrnxgnavb: sat=%2d\n", geph->sat); + + if ((satsys(geph->sat, &prn) & opt->navsys) != SYS_GLO) return 0; + + tof = time2gpst(gpst2utc(geph->tof), NULL); /* v.3: tow in utc */ + if (opt->rnxver <= 299) tof = fmod(tof, 86400.0); /* v.2: tod in utc */ + + toe = gpst2utc(geph->toe); /* gpst -> utc */ + time2epoch(toe, ep); + + if (opt->rnxver <= 299) { /* ver.2 */ + fprintf(fp, "%2d %02d %02.0f %02.0f %02.0f %02.0f %04.1f", prn, (int)ep[0] % 100, ep[1], ep[2], + ep[3], ep[4], ep[5]); + sep = " "; + } else { /* ver.3 */ + if (!sat2code(geph->sat, code)) return 0; + fprintf(fp, "%-3s %04.0f %02.0f %02.0f %02.0f %02.0f %02.0f", code, ep[0], ep[1], ep[2], ep[3], + ep[4], ep[5]); + sep = " "; + } + outnavf(fp, -geph->taun); + outnavf(fp, geph->gamn); + outnavf(fp, tof); + fprintf(fp, "\n%s", sep); + + outnavf(fp, geph->pos[0] / 1E3); + outnavf(fp, geph->vel[0] / 1E3); + outnavf(fp, geph->acc[0] / 1E3); + outnavf(fp, geph->svh & 1); + fprintf(fp, "\n%s", sep); + + outnavf(fp, geph->pos[1] / 1E3); + outnavf(fp, geph->vel[1] / 1E3); + outnavf(fp, geph->acc[1] / 1E3); + outnavf(fp, geph->frq); + fprintf(fp, "\n%s", sep); + + outnavf(fp, geph->pos[2] / 1E3); + outnavf(fp, geph->vel[2] / 1E3); + outnavf(fp, geph->acc[2] / 1E3); + outnavf(fp, geph->age); + + if (opt->rnxver >= 305) { + fprintf(fp, "\n%s", sep); + outnavf(fp, geph->flags); + outnavf(fp, geph->dtaun); + outnavf(fp, geph->sva); + outnavf(fp, (geph->svh >> 1) & 7); + } + return fprintf(fp, "\n") != EOF; } /* output RINEX GEO navigation data file header -------------------------------- -* output RINEX GEO navigation data file header -* args : FILE *fp I output file pointer -* rnxopt_t *opt I RINEX options -* nav_t nav I navigation data (NULL: no input) -* return : status (1:ok, 0:output error) -*-----------------------------------------------------------------------------*/ -extern int outrnxhnavh(FILE *fp, const rnxopt_t *opt, const nav_t *nav) -{ - int i; - char date[32]; - - trace(3,"outrnxhnavh:\n"); - - timestr_rnx(date); - - if (opt->rnxver<=299) { /* ver.2 */ - fprintf(fp,"%9.2f %-20s%-20s%-20s\n",opt->rnxver/100.0, - "H: GEO NAV MSG DATA","","RINEX VERSION / TYPE"); - } - else { /* ver.3 */ - fprintf(fp,"%9.2f %-20s%-20s%-20s\n",opt->rnxver/100.0, - "N: GNSS NAV DATA","S: SBAS Payload","RINEX VERSION / TYPE"); - } - fprintf(fp,"%-20.20s%-20.20s%-20.20s%-20s\n",opt->prog,opt->runby,date, - "PGM / RUN BY / DATE"); + * output RINEX GEO navigation data file header + * args : FILE *fp I output file pointer + * rnxopt_t *opt I RINEX options + * nav_t nav I navigation data (NULL: no input) + * return : status (1:ok, 0:output error) + *-----------------------------------------------------------------------------*/ +extern int outrnxhnavh(FILE *fp, const rnxopt_t *opt, const nav_t *nav) { + int i; + char date[32]; + + trace(3, "outrnxhnavh:\n"); + + timestr_rnx(date); + + if (opt->rnxver <= 299) { /* ver.2 */ + fprintf(fp, "%9.2f %-20s%-20s%-20s\n", opt->rnxver / 100.0, "H: GEO NAV MSG DATA", "", + "RINEX VERSION / TYPE"); + } else { /* ver.3 */ + fprintf(fp, "%9.2f %-20s%-20s%-20s\n", opt->rnxver / 100.0, "N: GNSS NAV DATA", + "S: SBAS Payload", "RINEX VERSION / TYPE"); + } + fprintf(fp, "%-20.20s%-20.20s%-20.20s%-20s\n", opt->prog, opt->runby, date, + "PGM / RUN BY / DATE"); - for (i=0;icomment[i]) continue; - fprintf(fp,"%-60.60s%-20s\n",opt->comment[i],"COMMENT"); - } - out_time(fp,SYS_SBS,opt,nav); - out_leaps(fp,SYS_GPS,opt,nav); + for (i = 0; i < MAXCOMMENT; i++) { + if (!*opt->comment[i]) continue; + fprintf(fp, "%-60.60s%-20s\n", opt->comment[i], "COMMENT"); + } + out_time(fp, SYS_SBS, opt, nav); + out_leaps(fp, SYS_GPS, opt, nav); - return fprintf(fp,"%60s%-20s\n","","END OF HEADER")!=EOF; + return fprintf(fp, "%60s%-20s\n", "", "END OF HEADER") != EOF; } /* output RINEX GEO navigation data file body ---------------------------------- -* output RINEX GEO navigation data file body -* args : FILE *fp I output file pointer -* rnxopt_t *opt I RINEX options -* seph_t *seph I SBAS ephemeris -* return : status (1:ok, 0:output error) -*-----------------------------------------------------------------------------*/ -extern int outrnxhnavb(FILE *fp, const rnxopt_t *opt, const seph_t *seph) -{ - double ep[6]; - int prn; - char code[32],*sep; - - trace(3,"outrnxhnavb: sat=%2d\n",seph->sat); - - if ((satsys(seph->sat,&prn)&opt->navsys)!=SYS_SBS) return 0; - - time2epoch(seph->t0,ep); - - if (opt->rnxver<=299) { /* ver.2 */ - fprintf(fp,"%2d %02d %02.0f %02.0f %02.0f %02.0f %04.1f",prn-100, - (int)ep[0]%100,ep[1],ep[2],ep[3],ep[4],ep[5]); - sep=" "; - } - else { /* ver.3 */ - if (!sat2code(seph->sat,code)) return 0; - fprintf(fp,"%-3s %04.0f %02.0f %02.0f %02.0f %02.0f %02.0f",code,ep[0],ep[1], - ep[2],ep[3],ep[4],ep[5]); - sep=" "; - } - outnavf(fp,seph->af0 ); - outnavf(fp,seph->af1 ); - outnavf(fp,time2gpst(seph->tof,NULL)); - fprintf(fp,"\n%s",sep ); - - outnavf(fp,seph->pos[0]/1E3 ); - outnavf(fp,seph->vel[0]/1E3 ); - outnavf(fp,seph->acc[0]/1E3 ); - outnavf(fp,seph->svh ); - fprintf(fp,"\n%s",sep ); - - outnavf(fp,seph->pos[1]/1E3 ); - outnavf(fp,seph->vel[1]/1E3 ); - outnavf(fp,seph->acc[1]/1E3 ); - outnavf(fp,uravalue(seph->sva)); - fprintf(fp,"\n%s",sep ); - - outnavf(fp,seph->pos[2]/1E3 ); - outnavf(fp,seph->vel[2]/1E3 ); - outnavf(fp,seph->acc[2]/1E3 ); - outnavf(fp,0 ); - - return fprintf(fp,"\n")!=EOF; + * output RINEX GEO navigation data file body + * args : FILE *fp I output file pointer + * rnxopt_t *opt I RINEX options + * seph_t *seph I SBAS ephemeris + * return : status (1:ok, 0:output error) + *-----------------------------------------------------------------------------*/ +extern int outrnxhnavb(FILE *fp, const rnxopt_t *opt, const seph_t *seph) { + double ep[6]; + int prn; + char code[32], *sep; + + trace(3, "outrnxhnavb: sat=%2d\n", seph->sat); + + if ((satsys(seph->sat, &prn) & opt->navsys) != SYS_SBS) return 0; + + time2epoch(seph->t0, ep); + + if (opt->rnxver <= 299) { /* ver.2 */ + fprintf(fp, "%2d %02d %02.0f %02.0f %02.0f %02.0f %04.1f", prn - 100, (int)ep[0] % 100, ep[1], + ep[2], ep[3], ep[4], ep[5]); + sep = " "; + } else { /* ver.3 */ + if (!sat2code(seph->sat, code)) return 0; + fprintf(fp, "%-3s %04.0f %02.0f %02.0f %02.0f %02.0f %02.0f", code, ep[0], ep[1], ep[2], ep[3], + ep[4], ep[5]); + sep = " "; + } + outnavf(fp, seph->af0); + outnavf(fp, seph->af1); + outnavf(fp, time2gpst(seph->tof, NULL)); + fprintf(fp, "\n%s", sep); + + outnavf(fp, seph->pos[0] / 1E3); + outnavf(fp, seph->vel[0] / 1E3); + outnavf(fp, seph->acc[0] / 1E3); + outnavf(fp, seph->svh); + fprintf(fp, "\n%s", sep); + + outnavf(fp, seph->pos[1] / 1E3); + outnavf(fp, seph->vel[1] / 1E3); + outnavf(fp, seph->acc[1] / 1E3); + outnavf(fp, uravalue(seph->sva)); + fprintf(fp, "\n%s", sep); + + outnavf(fp, seph->pos[2] / 1E3); + outnavf(fp, seph->vel[2] / 1E3); + outnavf(fp, seph->acc[2] / 1E3); + outnavf(fp, 0); + + return fprintf(fp, "\n") != EOF; } /* output RINEX Galileo NAV header --------------------------------------------- -* output RINEX Galileo NAV file header (2.12) -* args : FILE *fp I output file pointer -* rnxopt_t *opt I RINEX options -* nav_t nav I navigation data (NULL: no input) -* return : status (1:ok, 0:output error) -*-----------------------------------------------------------------------------*/ -extern int outrnxlnavh(FILE *fp, const rnxopt_t *opt, const nav_t *nav) -{ - int i; - char date[32]; + * output RINEX Galileo NAV file header (2.12) + * args : FILE *fp I output file pointer + * rnxopt_t *opt I RINEX options + * nav_t nav I navigation data (NULL: no input) + * return : status (1:ok, 0:output error) + *-----------------------------------------------------------------------------*/ +extern int outrnxlnavh(FILE *fp, const rnxopt_t *opt, const nav_t *nav) { + int i; + char date[32]; - trace(3,"outrnxlnavh:\n"); + trace(3, "outrnxlnavh:\n"); - if (opt->rnxver<212) return 0; + if (opt->rnxver < 212) return 0; - timestr_rnx(date); + timestr_rnx(date); - fprintf(fp,"%9.2f %-20s%-20s%-20s\n",opt->rnxver/100.0, - "N: GNSS NAV DATA","E: Galileo","RINEX VERSION / TYPE"); + fprintf(fp, "%9.2f %-20s%-20s%-20s\n", opt->rnxver / 100.0, "N: GNSS NAV DATA", + "E: Galileo", "RINEX VERSION / TYPE"); - fprintf(fp,"%-20.20s%-20.20s%-20.20s%-20s\n",opt->prog,opt->runby,date, - "PGM / RUN BY / DATE"); + fprintf(fp, "%-20.20s%-20.20s%-20.20s%-20s\n", opt->prog, opt->runby, date, + "PGM / RUN BY / DATE"); - for (i=0;icomment[i]) continue; - fprintf(fp,"%-60.60s%-20s\n",opt->comment[i],"COMMENT"); - } - out_iono(fp,SYS_GAL,opt,nav); - out_time(fp,SYS_GAL,opt,nav); - out_leaps(fp,SYS_GAL,opt,nav); + for (i = 0; i < MAXCOMMENT; i++) { + if (!*opt->comment[i]) continue; + fprintf(fp, "%-60.60s%-20s\n", opt->comment[i], "COMMENT"); + } + out_iono(fp, SYS_GAL, opt, nav); + out_time(fp, SYS_GAL, opt, nav); + out_leaps(fp, SYS_GAL, opt, nav); - return fprintf(fp,"%60s%-20s\n","","END OF HEADER")!=EOF; + return fprintf(fp, "%60s%-20s\n", "", "END OF HEADER") != EOF; } /* output RINEX QZSS navigation data file header ------------------------------- -* output RINEX QZSS navigation data file header -* args : FILE *fp I output file pointer -* rnxopt_t *opt I RINEX options -* nav_t nav I navigation data (NULL: no input) -* return : status (1:ok, 0:output error) -*-----------------------------------------------------------------------------*/ -extern int outrnxqnavh(FILE *fp, const rnxopt_t *opt, const nav_t *nav) -{ - int i; - char date[32]; + * output RINEX QZSS navigation data file header + * args : FILE *fp I output file pointer + * rnxopt_t *opt I RINEX options + * nav_t nav I navigation data (NULL: no input) + * return : status (1:ok, 0:output error) + *-----------------------------------------------------------------------------*/ +extern int outrnxqnavh(FILE *fp, const rnxopt_t *opt, const nav_t *nav) { + int i; + char date[32]; - trace(3,"outrnxqnavh:\n"); + trace(3, "outrnxqnavh:\n"); - if (opt->rnxver<302) return 0; + if (opt->rnxver < 302) return 0; - timestr_rnx(date); + timestr_rnx(date); - fprintf(fp,"%9.2f %-20s%-20s%-20s\n",opt->rnxver/100.0, - "N: GNSS NAV DATA","J: QZSS","RINEX VERSION / TYPE"); + fprintf(fp, "%9.2f %-20s%-20s%-20s\n", opt->rnxver / 100.0, "N: GNSS NAV DATA", + "J: QZSS", "RINEX VERSION / TYPE"); - fprintf(fp,"%-20.20s%-20.20s%-20.20s%-20s\n",opt->prog,opt->runby,date, - "PGM / RUN BY / DATE"); + fprintf(fp, "%-20.20s%-20.20s%-20.20s%-20s\n", opt->prog, opt->runby, date, + "PGM / RUN BY / DATE"); - for (i=0;icomment[i]) continue; - fprintf(fp,"%-60.60s%-20s\n",opt->comment[i],"COMMENT"); - } - out_iono(fp,SYS_QZS,opt,nav); - out_time(fp,SYS_QZS,opt,nav); - out_leaps(fp,SYS_QZS,opt,nav); + for (i = 0; i < MAXCOMMENT; i++) { + if (!*opt->comment[i]) continue; + fprintf(fp, "%-60.60s%-20s\n", opt->comment[i], "COMMENT"); + } + out_iono(fp, SYS_QZS, opt, nav); + out_time(fp, SYS_QZS, opt, nav); + out_leaps(fp, SYS_QZS, opt, nav); - return fprintf(fp,"%60s%-20s\n","","END OF HEADER")!=EOF; + return fprintf(fp, "%60s%-20s\n", "", "END OF HEADER") != EOF; } /* output RINEX BDS navigation data file header -------------------------------- -* output RINEX BDS navigation data file header -* args : FILE *fp I output file pointer -* rnxopt_t *opt I RINEX options -* nav_t nav I navigation data (NULL: no input) -* return : status (1:ok, 0:output error) -*-----------------------------------------------------------------------------*/ -extern int outrnxcnavh(FILE *fp, const rnxopt_t *opt, const nav_t *nav) -{ - int i; - char date[32]; + * output RINEX BDS navigation data file header + * args : FILE *fp I output file pointer + * rnxopt_t *opt I RINEX options + * nav_t nav I navigation data (NULL: no input) + * return : status (1:ok, 0:output error) + *-----------------------------------------------------------------------------*/ +extern int outrnxcnavh(FILE *fp, const rnxopt_t *opt, const nav_t *nav) { + int i; + char date[32]; - trace(3,"outrnxcnavh:\n"); + trace(3, "outrnxcnavh:\n"); - if (opt->rnxver<302) return 0; + if (opt->rnxver < 302) return 0; - timestr_rnx(date); + timestr_rnx(date); - fprintf(fp,"%9.2f %-20s%-20s%-20s\n",opt->rnxver/100.0, - "N: GNSS NAV DATA","C: BeiDou","RINEX VERSION / TYPE"); + fprintf(fp, "%9.2f %-20s%-20s%-20s\n", opt->rnxver / 100.0, "N: GNSS NAV DATA", + "C: BeiDou", "RINEX VERSION / TYPE"); - fprintf(fp,"%-20.20s%-20.20s%-20.20s%-20s\n",opt->prog,opt->runby,date, - "PGM / RUN BY / DATE"); + fprintf(fp, "%-20.20s%-20.20s%-20.20s%-20s\n", opt->prog, opt->runby, date, + "PGM / RUN BY / DATE"); - for (i=0;icomment[i]) continue; - fprintf(fp,"%-60.60s%-20s\n",opt->comment[i],"COMMENT"); - } - out_iono(fp,SYS_CMP,opt,nav); - out_time(fp,SYS_CMP,opt,nav); - out_leaps(fp,SYS_CMP,opt,nav); + for (i = 0; i < MAXCOMMENT; i++) { + if (!*opt->comment[i]) continue; + fprintf(fp, "%-60.60s%-20s\n", opt->comment[i], "COMMENT"); + } + out_iono(fp, SYS_CMP, opt, nav); + out_time(fp, SYS_CMP, opt, nav); + out_leaps(fp, SYS_CMP, opt, nav); - return fprintf(fp,"%60s%-20s\n","","END OF HEADER")!=EOF; + return fprintf(fp, "%60s%-20s\n", "", "END OF HEADER") != EOF; } /* output RINEX NavIC/IRNSS navigation data file header ------------------------ -* output RINEX NavIC/IRNSS navigation data file header -* args : FILE *fp I output file pointer -* rnxopt_t *opt I RINEX options -* nav_t nav I navigation data (NULL: no input) -* return : status (1:ok, 0:output error) -*-----------------------------------------------------------------------------*/ -extern int outrnxinavh(FILE *fp, const rnxopt_t *opt, const nav_t *nav) -{ - int i; - char date[32]; + * output RINEX NavIC/IRNSS navigation data file header + * args : FILE *fp I output file pointer + * rnxopt_t *opt I RINEX options + * nav_t nav I navigation data (NULL: no input) + * return : status (1:ok, 0:output error) + *-----------------------------------------------------------------------------*/ +extern int outrnxinavh(FILE *fp, const rnxopt_t *opt, const nav_t *nav) { + int i; + char date[32]; - trace(3,"outrnxinavh:\n"); + trace(3, "outrnxinavh:\n"); - if (opt->rnxver<303) return 0; + if (opt->rnxver < 303) return 0; - timestr_rnx(date); + timestr_rnx(date); - fprintf(fp,"%9.2f %-20s%-20s%-20s\n",opt->rnxver/100.0, - "N: GNSS NAV DATA","I: IRNSS","RINEX VERSION / TYPE"); + fprintf(fp, "%9.2f %-20s%-20s%-20s\n", opt->rnxver / 100.0, "N: GNSS NAV DATA", + "I: IRNSS", "RINEX VERSION / TYPE"); - fprintf(fp,"%-20.20s%-20.20s%-20.20s%-20s\n",opt->prog,opt->runby,date, - "PGM / RUN BY / DATE"); + fprintf(fp, "%-20.20s%-20.20s%-20.20s%-20s\n", opt->prog, opt->runby, date, + "PGM / RUN BY / DATE"); - for (i=0;icomment[i]) continue; - fprintf(fp,"%-60.60s%-20s\n",opt->comment[i],"COMMENT"); - } - out_iono(fp,SYS_IRN,opt,nav); - out_time(fp,SYS_IRN,opt,nav); - out_leaps(fp,SYS_IRN,opt,nav); + for (i = 0; i < MAXCOMMENT; i++) { + if (!*opt->comment[i]) continue; + fprintf(fp, "%-60.60s%-20s\n", opt->comment[i], "COMMENT"); + } + out_iono(fp, SYS_IRN, opt, nav); + out_time(fp, SYS_IRN, opt, nav); + out_leaps(fp, SYS_IRN, opt, nav); - return fprintf(fp,"%60s%-20s\n","","END OF HEADER")!=EOF; + return fprintf(fp, "%60s%-20s\n", "", "END OF HEADER") != EOF; } diff --git a/src/rtcm.c b/src/rtcm.c index 6781336e1..3ae376240 100644 --- a/src/rtcm.c +++ b/src/rtcm.c @@ -1,50 +1,50 @@ /*------------------------------------------------------------------------------ -* rtcm.c : rtcm functions -* -* Copyright (C) 2009-2020 by T.TAKASU, All rights reserved. -* -* references : -* [1] RTCM Recommended Standards for Differential GNSS (Global Navigation -* Satellite Systems) Service version 2.3, August 20, 2001 -* [7] RTCM Standard 10403.1 - Amendment 5, Differential GNSS (Global -* Navigation Satellite Systems) Services - version 3, July 1, 2011 -* [10] RTCM Paper 059-2011-SC104-635 (draft Galileo and QZSS ssr messages) -* [15] RTCM Standard 10403.2, Differential GNSS (Global Navigation Satellite -* Systems) Services - version 3, with amendment 1/2, November 7, 2013 -* [16] Proposal of new RTCM SSR Messages (ssr_1_gal_qzss_sbas_dbs_v05) -* 2014/04/17 -* [17] RTCM Standard 10403.3, Differential GNSS (Global Navigation Satellite -* Systems) Services - version 3, with amendment 1, April 28, 2020 -* [18] IGS State Space Representation (SSR) Format version 1.00, October 5, -* 2020 -* -* version : $Revision:$ $Date:$ -* history : 2009/04/10 1.0 new -* 2009/06/29 1.1 support type 1009-1012 to get synchronous-gnss-flag -* 2009/12/04 1.2 support type 1010,1012,1020 -* 2010/07/15 1.3 support type 1057-1068 for ssr corrections -* support type 1007,1008,1033 for antenna info -* 2010/09/08 1.4 fix problem of ephemeris and ssr sequence upset -* (2.4.0_p8) -* 2012/05/11 1.5 comply with RTCM 3 final SSR format (RTCM 3 -* Amendment 5) (ref [7]) (2.4.1_p6) -* 2012/05/14 1.6 separate rtcm2.c, rtcm3.c -* add options to select used codes for msm -* 2013/04/27 1.7 comply with rtcm 3.2 with amendment 1/2 (ref[15]) -* 2013/12/06 1.8 support SBAS/BeiDou SSR messages (ref[16]) -* 2018/01/29 1.9 support RTCM 3.3 (ref[17]) -* crc24q() -> rtk_crc24q() -* 2018/10/10 1.10 fix bug on initializing rtcm struct -* add rtcm option -GALINAV, -GALFNAV -* 2018/11/05 1.11 add notes for api gen_rtcm3() -* 2020/11/30 1.12 modify API gen_rtcm3() -* support NavIC/IRNSS MSM and ephemeris (ref [17]) -* allocate double size of ephemeris buffer to support -* multiple ephemeris sets in init_rtcm() -* delete references [2]-[6],[8],[9],[11]-[14] -* update reference [17] -* use integer types in stdint.h -*-----------------------------------------------------------------------------*/ + * rtcm.c : rtcm functions + * + * Copyright (C) 2009-2020 by T.TAKASU, All rights reserved. + * + * references : + * [1] RTCM Recommended Standards for Differential GNSS (Global Navigation + * Satellite Systems) Service version 2.3, August 20, 2001 + * [7] RTCM Standard 10403.1 - Amendment 5, Differential GNSS (Global + * Navigation Satellite Systems) Services - version 3, July 1, 2011 + * [10] RTCM Paper 059-2011-SC104-635 (draft Galileo and QZSS ssr messages) + * [15] RTCM Standard 10403.2, Differential GNSS (Global Navigation Satellite + * Systems) Services - version 3, with amendment 1/2, November 7, 2013 + * [16] Proposal of new RTCM SSR Messages (ssr_1_gal_qzss_sbas_dbs_v05) + * 2014/04/17 + * [17] RTCM Standard 10403.3, Differential GNSS (Global Navigation Satellite + * Systems) Services - version 3, with amendment 1, April 28, 2020 + * [18] IGS State Space Representation (SSR) Format version 1.00, October 5, + * 2020 + * + * version : $Revision:$ $Date:$ + * history : 2009/04/10 1.0 new + * 2009/06/29 1.1 support type 1009-1012 to get synchronous-gnss-flag + * 2009/12/04 1.2 support type 1010,1012,1020 + * 2010/07/15 1.3 support type 1057-1068 for ssr corrections + * support type 1007,1008,1033 for antenna info + * 2010/09/08 1.4 fix problem of ephemeris and ssr sequence upset + * (2.4.0_p8) + * 2012/05/11 1.5 comply with RTCM 3 final SSR format (RTCM 3 + * Amendment 5) (ref [7]) (2.4.1_p6) + * 2012/05/14 1.6 separate rtcm2.c, rtcm3.c + * add options to select used codes for msm + * 2013/04/27 1.7 comply with rtcm 3.2 with amendment 1/2 (ref[15]) + * 2013/12/06 1.8 support SBAS/BeiDou SSR messages (ref[16]) + * 2018/01/29 1.9 support RTCM 3.3 (ref[17]) + * crc24q() -> rtk_crc24q() + * 2018/10/10 1.10 fix bug on initializing rtcm struct + * add rtcm option -GALINAV, -GALFNAV + * 2018/11/05 1.11 add notes for api gen_rtcm3() + * 2020/11/30 1.12 modify API gen_rtcm3() + * support NavIC/IRNSS MSM and ephemeris (ref [17]) + * allocate double size of ephemeris buffer to support + * multiple ephemeris sets in init_rtcm() + * delete references [2]-[6],[8],[9],[11]-[14] + * update reference [17] + * use integer types in stdint.h + *-----------------------------------------------------------------------------*/ #include "rtklib.h" /* function prototypes -------------------------------------------------------*/ @@ -54,366 +54,375 @@ extern int encode_rtcm3(rtcm_t *rtcm, int type, int subtype, int sync); /* constants -----------------------------------------------------------------*/ -#define RTCM2PREAMB 0x66 /* rtcm ver.2 frame preamble */ -#define RTCM3PREAMB 0xD3 /* rtcm ver.3 frame preamble */ +#define RTCM2PREAMB 0x66 /* rtcm ver.2 frame preamble */ +#define RTCM3PREAMB 0xD3 /* rtcm ver.3 frame preamble */ /* initialize rtcm control ----------------------------------------------------- -* initialize rtcm control struct and reallocate memory for observation and -* ephemeris buffer in rtcm control struct -* args : rtcm_t *raw IO rtcm control struct -* return : status (1:ok,0:memory allocation error) -*-----------------------------------------------------------------------------*/ -extern int init_rtcm(rtcm_t *rtcm) -{ - gtime_t time0={0}; - obsd_t data0={{0}}; - eph_t eph0 ={0,-1,-1}; - ssr_t ssr0={{{0}}}; - int i,j; - - trace(3,"init_rtcm:\n"); - - rtcm->staid=rtcm->stah=rtcm->seqno=rtcm->outtype=0; - rtcm->time=rtcm->time_s=time0; - rtcm->sta.name[0]=rtcm->sta.markerno[0]=rtcm->sta.markertype[0]='\0'; - rtcm->sta.observer[0]=rtcm->sta.agency[0]='\0'; - rtcm->sta.antdes[0]=rtcm->sta.antsno[0]='\0'; - rtcm->sta.rectype[0]=rtcm->sta.recver[0]=rtcm->sta.recsno[0]='\0'; - rtcm->sta.antsetup=rtcm->sta.itrf=rtcm->sta.deltype=0; - for (i=0;i<3;i++) { - rtcm->sta.pos[i]=rtcm->sta.del[i]=0.0; - } - rtcm->sta.hgt=0.0; - rtcm->dgps=NULL; - for (i=0;issr[i]=ssr0; - } - rtcm->msg[0]=rtcm->msgtype[0]=rtcm->opt[0]='\0'; - for (i=0;i<6;i++) rtcm->msmtype[i][0]='\0'; - rtcm->obsflag=rtcm->ephsat=0; - for (i=0;icp[i][j]=0.0; - rtcm->lock[i][j]=rtcm->loss[i][j]=0; - rtcm->lltime[i][j]=time0; - } - rtcm->nbyte=rtcm->nbit=rtcm->len=0; - rtcm->word=0; - for (i=0;i<100;i++) rtcm->nmsg2[i]=0; - for (i=0;i<400;i++) rtcm->nmsg3[i]=0; - - rtcm->obs.data=NULL; - rtcm->nav.eph =NULL; - rtcm->nav.geph=NULL; - rtcm->nav.seph=NULL; - - // Allocate memory for observation and ephemeris buffer. - if (!(rtcm->obs.data=(obsd_t *)malloc(sizeof(obsd_t)*MAXOBS))|| - !(rtcm->nav.eph =(eph_t *)malloc(sizeof(eph_t )*MAXSAT*2))) { - free_rtcm(rtcm); - return 0; + * initialize rtcm control struct and reallocate memory for observation and + * ephemeris buffer in rtcm control struct + * args : rtcm_t *raw IO rtcm control struct + * return : status (1:ok,0:memory allocation error) + *-----------------------------------------------------------------------------*/ +extern int init_rtcm(rtcm_t *rtcm) { + gtime_t time0 = {0}; + obsd_t data0 = {{0}}; + eph_t eph0 = {0, -1, -1}; + ssr_t ssr0 = {{{0}}}; + int i, j; + + trace(3, "init_rtcm:\n"); + + rtcm->staid = rtcm->stah = rtcm->seqno = rtcm->outtype = 0; + rtcm->time = rtcm->time_s = time0; + rtcm->sta.name[0] = rtcm->sta.markerno[0] = rtcm->sta.markertype[0] = '\0'; + rtcm->sta.observer[0] = rtcm->sta.agency[0] = '\0'; + rtcm->sta.antdes[0] = rtcm->sta.antsno[0] = '\0'; + rtcm->sta.rectype[0] = rtcm->sta.recver[0] = rtcm->sta.recsno[0] = '\0'; + rtcm->sta.antsetup = rtcm->sta.itrf = rtcm->sta.deltype = 0; + for (i = 0; i < 3; i++) { + rtcm->sta.pos[i] = rtcm->sta.del[i] = 0.0; + } + rtcm->sta.hgt = 0.0; + rtcm->dgps = NULL; + for (i = 0; i < MAXSAT; i++) { + rtcm->ssr[i] = ssr0; + } + rtcm->msg[0] = rtcm->msgtype[0] = rtcm->opt[0] = '\0'; + for (i = 0; i < 6; i++) rtcm->msmtype[i][0] = '\0'; + rtcm->obsflag = rtcm->ephsat = 0; + for (i = 0; i < MAXSAT; i++) + for (j = 0; j < NFREQ + NEXOBS; j++) { + rtcm->cp[i][j] = 0.0; + rtcm->lock[i][j] = rtcm->loss[i][j] = 0; + rtcm->lltime[i][j] = time0; } - rtcm->obs.n=0; - rtcm->nav.n=rtcm->nav.nmax=MAXSAT*2; - rtcm->nav.ns=rtcm->nav.nsmax=0; - for (i=0;iobs.data[i]=data0; - for (i=0;inav.eph [i]=eph0; - - if (MAXPRNGLO > 0) { - rtcm->nav.geph = (geph_t *)malloc(sizeof(geph_t) * MAXPRNGLO); - if (rtcm->nav.geph == NULL) { - free_rtcm(rtcm); - return 0; - } - geph_t geph0 = {0, -1}; - for (int i = 0; i < MAXPRNGLO; i++) rtcm->nav.geph[i] = geph0; + rtcm->nbyte = rtcm->nbit = rtcm->len = 0; + rtcm->word = 0; + for (i = 0; i < 100; i++) rtcm->nmsg2[i] = 0; + for (i = 0; i < 400; i++) rtcm->nmsg3[i] = 0; + + rtcm->obs.data = NULL; + rtcm->nav.eph = NULL; + rtcm->nav.geph = NULL; + rtcm->nav.seph = NULL; + + // Allocate memory for observation and ephemeris buffer. + if (!(rtcm->obs.data = (obsd_t *)malloc(sizeof(obsd_t) * MAXOBS)) || + !(rtcm->nav.eph = (eph_t *)malloc(sizeof(eph_t) * MAXSAT * 2))) { + free_rtcm(rtcm); + return 0; + } + rtcm->obs.n = 0; + rtcm->nav.n = rtcm->nav.nmax = MAXSAT * 2; + rtcm->nav.ns = rtcm->nav.nsmax = 0; + for (i = 0; i < MAXOBS; i++) rtcm->obs.data[i] = data0; + for (i = 0; i < MAXSAT * 2; i++) rtcm->nav.eph[i] = eph0; + + if (MAXPRNGLO > 0) { + rtcm->nav.geph = (geph_t *)malloc(sizeof(geph_t) * MAXPRNGLO); + if (rtcm->nav.geph == NULL) { + free_rtcm(rtcm); + return 0; } - rtcm->nav.ng = rtcm->nav.ngmax = MAXPRNGLO; + geph_t geph0 = {0, -1}; + for (int i = 0; i < MAXPRNGLO; i++) rtcm->nav.geph[i] = geph0; + } + rtcm->nav.ng = rtcm->nav.ngmax = MAXPRNGLO; - return 1; + return 1; } /* free rtcm control ---------------------------------------------------------- -* free observation and ephemeris buffer in rtcm control struct -* args : rtcm_t *raw IO rtcm control struct -* return : none -*-----------------------------------------------------------------------------*/ -extern void free_rtcm(rtcm_t *rtcm) -{ - trace(3,"free_rtcm:\n"); - - /* free memory for observation and ephemeris buffer */ - free(rtcm->obs.data); rtcm->obs.data=NULL; rtcm->obs.n=0; - free(rtcm->nav.eph ); rtcm->nav.eph =NULL; rtcm->nav.n=rtcm->nav.nmax=0; - free(rtcm->nav.geph); rtcm->nav.geph=NULL; rtcm->nav.ng=rtcm->nav.ngmax=0; + * free observation and ephemeris buffer in rtcm control struct + * args : rtcm_t *raw IO rtcm control struct + * return : none + *-----------------------------------------------------------------------------*/ +extern void free_rtcm(rtcm_t *rtcm) { + trace(3, "free_rtcm:\n"); + + /* free memory for observation and ephemeris buffer */ + free(rtcm->obs.data); + rtcm->obs.data = NULL; + rtcm->obs.n = 0; + free(rtcm->nav.eph); + rtcm->nav.eph = NULL; + rtcm->nav.n = rtcm->nav.nmax = 0; + free(rtcm->nav.geph); + rtcm->nav.geph = NULL; + rtcm->nav.ng = rtcm->nav.ngmax = 0; } /* input RTCM 2 message from stream -------------------------------------------- -* fetch next RTCM 2 message and input a message from byte stream -* args : rtcm_t *rtcm IO rtcm control struct -* uint8_t data I stream data (1 byte) -* return : status (-1: error message, 0: no message, 1: input observation data, -* 2: input ephemeris, 5: input station pos/ant parameters, -* 6: input time parameter, 7: input dgps corrections, -* 9: input special message) -* notes : before firstly calling the function, time in rtcm control struct has -* to be set to the approximate time within 1/2 hour in order to resolve -* ambiguity of time in rtcm messages. -* supported msgs RTCM ver.2: 1,3,9,14,16,17,18,19,22 -* refer [1] for RTCM ver.2 -*-----------------------------------------------------------------------------*/ -extern int input_rtcm2(rtcm_t *rtcm, uint8_t data) -{ - uint8_t preamb; - int i; - - trace(5,"input_rtcm2: data=%02x\n",data); - - if ((data&0xC0)!=0x40) return 0; /* ignore if upper 2bit != 01 */ - - for (i=0;i<6;i++,data>>=1) { /* decode 6-of-8 form */ - rtcm->word=(rtcm->word<<1)+(data&1); - - /* synchronize frame */ - if (rtcm->nbyte==0) { - preamb=(uint8_t)(rtcm->word>>22); - if (rtcm->word&0x40000000) preamb^=0xFF; /* decode preamble */ - if (preamb!=RTCM2PREAMB) continue; - - /* check parity */ - if (!decode_word(rtcm->word,rtcm->buff)) continue; - rtcm->nbyte=3; rtcm->nbit=0; - continue; - } - if (++rtcm->nbit<30) continue; else rtcm->nbit=0; - - /* check parity */ - if (!decode_word(rtcm->word,rtcm->buff+rtcm->nbyte)) { - trace(2,"rtcm2 partity error: i=%d word=%08x\n",i,rtcm->word); - rtcm->nbyte=0; rtcm->word&=0x3; - continue; - } - rtcm->nbyte+=3; - if (rtcm->nbyte==6) rtcm->len=(rtcm->buff[5]>>3)*3+6; - if (rtcm->nbytelen) continue; - rtcm->nbyte=0; rtcm->word&=0x3; - - /* decode rtcm2 message */ - return decode_rtcm2(rtcm); - } - return 0; -} -/* input RTCM 3 message from stream -------------------------------------------- -* fetch next RTCM 3 message and input a message from byte stream -* args : rtcm_t *rtcm IO rtcm control struct -* uint8_t data I stream data (1 byte) -* return : status (-1: error message, 0: no message, 1: input observation data, -* 2: input ephemeris, 5: input station pos/ant parameters, -* 10: input ssr messages) -* notes : before firstly calling the function, time in rtcm control struct has -* to be set to the approximate time within 1/2 week in order to resolve -* ambiguity of time in rtcm messages. -* -* to specify input options, set rtcm->opt to the following option -* strings separated by spaces. -* -* -EPHALL : input all ephemerides (default: only new) -* -INVPRR : invert polarity of PhaseRangeRate -* -STA=nnn : input only message with STAID=nnn (default: all) -* -GLss : select signal ss for GPS MSM (ss=1C,1P,...) -* -RLss : select signal ss for GLO MSM (ss=1C,1P,...) -* -ELss : select signal ss for GAL MSM (ss=1C,1B,...) -* -JLss : select signal ss for QZS MSM (ss=1C,2C,...) -* -CLss : select signal ss for BDS MSM (ss=2I,7I,...) -* -ILss : select signal ss for IRN MSM (ss=5A,9A,...) -* -GALINAV : select I/NAV for Galileo ephemeris (default: all) -* -GALFNAV : select F/NAV for Galileo ephemeris (default: all) -* -RT_INP : select real-time input -* -* supported RTCM 3 messages (ref [7][10][15][16][17][18]) -* -* TYPE : GPS GLONASS Galileo QZSS BDS SBAS NavIC -* ---------------------------------------------------------------------- -* OBS COMP L1 : 1001~ 1009~ - - - - - -* FULL L1 : 1002 1010 - - - - - -* COMP L1L2: 1003~ 1011~ - - - - - -* FULL L1L2: 1004 1012 - - - - - -* -* NAV : 1019 1020 1045** 1044 1042 - 1041 -* - - 1046** - 63* - - -* -* MSM 1 : 1071~ 1081~ 1091~ 1111~ 1121~ 1101~ 1131~ -* 2 : 1072~ 1082~ 1092~ 1112~ 1122~ 1102~ 1132~ -* 3 : 1073~ 1083~ 1093~ 1113~ 1123~ 1103~ 1133~ -* 4 : 1074 1084 1094 1114 1124 1104 1134 -* 5 : 1075 1085 1095 1115 1125 1105 1135 -* 6 : 1076 1086 1096 1116 1126 1106 1136 -* 7 : 1077 1087 1097 1117 1127 1107 1137 -* -* SSR ORBIT : 1057 1063 1240* 1246* 1258* - - -* CLOCK : 1058 1064 1241* 1247* 1259* - - -* CODE BIAS: 1059 1065 1242* 1248* 1260* - - -* OBT/CLK : 1060 1066 1243* 1249* 1261* - - -* URA : 1061 1067 1244* 1250* 1262* - - -* HR-CLOCK : 1062 1068 1245* 1251* 1263* - - -* PHAS BIAS: 11* - 12* 13* 14* - - -* -* ANT/RCV INFO : 1007 1008 1033 -* STA POSITION : 1005 1006 -* -* PROPRIETARY : 4076 (IGS) -* ---------------------------------------------------------------------- -* (* draft, ** 1045:F/NAV,1046:I/NAV, ~ only encode) -* -* for MSM observation data with multiple signals for a frequency, -* a signal is selected according to internal priority. to select -* a specified signal, use the input options. -* -* RTCM 3 message format: -* +----------+--------+-----------+--------------------+----------+ -* | preamble | 000000 | length | data message | parity | -* +----------+--------+-----------+--------------------+----------+ -* |<-- 8 --->|<- 6 -->|<-- 10 --->|<--- length x 8 --->|<-- 24 -->| -* -*-----------------------------------------------------------------------------*/ -extern int input_rtcm3(rtcm_t *rtcm, uint8_t data) -{ - trace(5,"input_rtcm3: data=%02x\n",data); - + * fetch next RTCM 2 message and input a message from byte stream + * args : rtcm_t *rtcm IO rtcm control struct + * uint8_t data I stream data (1 byte) + * return : status (-1: error message, 0: no message, 1: input observation data, + * 2: input ephemeris, 5: input station pos/ant parameters, + * 6: input time parameter, 7: input dgps corrections, + * 9: input special message) + * notes : before firstly calling the function, time in rtcm control struct has + * to be set to the approximate time within 1/2 hour in order to resolve + * ambiguity of time in rtcm messages. + * supported msgs RTCM ver.2: 1,3,9,14,16,17,18,19,22 + * refer [1] for RTCM ver.2 + *-----------------------------------------------------------------------------*/ +extern int input_rtcm2(rtcm_t *rtcm, uint8_t data) { + uint8_t preamb; + int i; + + trace(5, "input_rtcm2: data=%02x\n", data); + + if ((data & 0xC0) != 0x40) return 0; /* ignore if upper 2bit != 01 */ + + for (i = 0; i < 6; i++, data >>= 1) { /* decode 6-of-8 form */ + rtcm->word = (rtcm->word << 1) + (data & 1); + /* synchronize frame */ - if (rtcm->nbyte==0) { - if (data!=RTCM3PREAMB) return 0; - rtcm->buff[rtcm->nbyte++]=data; - return 0; - } - rtcm->buff[rtcm->nbyte++]=data; - - if (rtcm->nbyte==3) { - rtcm->len=getbitu(rtcm->buff,14,10)+3; /* length without parity */ - trace(4,"msg len=%d\n",rtcm->len); + if (rtcm->nbyte == 0) { + preamb = (uint8_t)(rtcm->word >> 22); + if (rtcm->word & 0x40000000) preamb ^= 0xFF; /* decode preamble */ + if (preamb != RTCM2PREAMB) continue; + + /* check parity */ + if (!decode_word(rtcm->word, rtcm->buff)) continue; + rtcm->nbyte = 3; + rtcm->nbit = 0; + continue; } - if (rtcm->nbyte<3||rtcm->nbytelen+3) return 0; /* return if message not complete */ - /* message complete, start parsing */ - rtcm->nbyte_invalid=rtcm->nbyte; /* length of potentially invalid bytes */ - rtcm->nbyte=0; - + if (++rtcm->nbit < 30) + continue; + else + rtcm->nbit = 0; + /* check parity */ - if (rtk_crc24q(rtcm->buff,rtcm->len)!=getbitu(rtcm->buff,rtcm->len*8,24)) { - trace(2,"rtcm3 parity error: len=%d\n",rtcm->len); - return 0; + if (!decode_word(rtcm->word, rtcm->buff + rtcm->nbyte)) { + trace(2, "rtcm2 partity error: i=%d word=%08x\n", i, rtcm->word); + rtcm->nbyte = 0; + rtcm->word &= 0x3; + continue; } - rtcm->nbyte_invalid=0; /* no error, so clear invalid_byte count */ - /* decode rtcm3 message */ - return decode_rtcm3(rtcm); + rtcm->nbyte += 3; + if (rtcm->nbyte == 6) rtcm->len = (rtcm->buff[5] >> 3) * 3 + 6; + if (rtcm->nbyte < rtcm->len) continue; + rtcm->nbyte = 0; + rtcm->word &= 0x3; + + /* decode rtcm2 message */ + return decode_rtcm2(rtcm); + } + return 0; +} +/* input RTCM 3 message from stream -------------------------------------------- + * fetch next RTCM 3 message and input a message from byte stream + * args : rtcm_t *rtcm IO rtcm control struct + * uint8_t data I stream data (1 byte) + * return : status (-1: error message, 0: no message, 1: input observation data, + * 2: input ephemeris, 5: input station pos/ant parameters, + * 10: input ssr messages) + * notes : before firstly calling the function, time in rtcm control struct has + * to be set to the approximate time within 1/2 week in order to resolve + * ambiguity of time in rtcm messages. + * + * to specify input options, set rtcm->opt to the following option + * strings separated by spaces. + * + * -EPHALL : input all ephemerides (default: only new) + * -INVPRR : invert polarity of PhaseRangeRate + * -STA=nnn : input only message with STAID=nnn (default: all) + * -GLss : select signal ss for GPS MSM (ss=1C,1P,...) + * -RLss : select signal ss for GLO MSM (ss=1C,1P,...) + * -ELss : select signal ss for GAL MSM (ss=1C,1B,...) + * -JLss : select signal ss for QZS MSM (ss=1C,2C,...) + * -CLss : select signal ss for BDS MSM (ss=2I,7I,...) + * -ILss : select signal ss for IRN MSM (ss=5A,9A,...) + * -GALINAV : select I/NAV for Galileo ephemeris (default: all) + * -GALFNAV : select F/NAV for Galileo ephemeris (default: all) + * -RT_INP : select real-time input + * + * supported RTCM 3 messages (ref [7][10][15][16][17][18]) + * + * TYPE : GPS GLONASS Galileo QZSS BDS SBAS NavIC + * ---------------------------------------------------------------------- + * OBS COMP L1 : 1001~ 1009~ - - - - - + * FULL L1 : 1002 1010 - - - - - + * COMP L1L2: 1003~ 1011~ - - - - - + * FULL L1L2: 1004 1012 - - - - - + * + * NAV : 1019 1020 1045** 1044 1042 - 1041 + * - - 1046** - 63* - - + * + * MSM 1 : 1071~ 1081~ 1091~ 1111~ 1121~ 1101~ 1131~ + * 2 : 1072~ 1082~ 1092~ 1112~ 1122~ 1102~ 1132~ + * 3 : 1073~ 1083~ 1093~ 1113~ 1123~ 1103~ 1133~ + * 4 : 1074 1084 1094 1114 1124 1104 1134 + * 5 : 1075 1085 1095 1115 1125 1105 1135 + * 6 : 1076 1086 1096 1116 1126 1106 1136 + * 7 : 1077 1087 1097 1117 1127 1107 1137 + * + * SSR ORBIT : 1057 1063 1240* 1246* 1258* - - + * CLOCK : 1058 1064 1241* 1247* 1259* - - + * CODE BIAS: 1059 1065 1242* 1248* 1260* - - + * OBT/CLK : 1060 1066 1243* 1249* 1261* - - + * URA : 1061 1067 1244* 1250* 1262* - - + * HR-CLOCK : 1062 1068 1245* 1251* 1263* - - + * PHAS BIAS: 11* - 12* 13* 14* - - + * + * ANT/RCV INFO : 1007 1008 1033 + * STA POSITION : 1005 1006 + * + * PROPRIETARY : 4076 (IGS) + * ---------------------------------------------------------------------- + * (* draft, ** 1045:F/NAV,1046:I/NAV, ~ only encode) + * + * for MSM observation data with multiple signals for a frequency, + * a signal is selected according to internal priority. to select + * a specified signal, use the input options. + * + * RTCM 3 message format: + * +----------+--------+-----------+--------------------+----------+ + * | preamble | 000000 | length | data message | parity | + * +----------+--------+-----------+--------------------+----------+ + * |<-- 8 --->|<- 6 -->|<-- 10 --->|<--- length x 8 --->|<-- 24 -->| + * + *-----------------------------------------------------------------------------*/ +extern int input_rtcm3(rtcm_t *rtcm, uint8_t data) { + trace(5, "input_rtcm3: data=%02x\n", data); + + /* synchronize frame */ + if (rtcm->nbyte == 0) { + if (data != RTCM3PREAMB) return 0; + rtcm->buff[rtcm->nbyte++] = data; + return 0; + } + rtcm->buff[rtcm->nbyte++] = data; + + if (rtcm->nbyte == 3) { + rtcm->len = getbitu(rtcm->buff, 14, 10) + 3; /* length without parity */ + trace(4, "msg len=%d\n", rtcm->len); + } + if (rtcm->nbyte < 3 || rtcm->nbyte < rtcm->len + 3) return 0; /* return if message not complete */ + /* message complete, start parsing */ + rtcm->nbyte_invalid = rtcm->nbyte; /* length of potentially invalid bytes */ + rtcm->nbyte = 0; + + /* check parity */ + if (rtk_crc24q(rtcm->buff, rtcm->len) != getbitu(rtcm->buff, rtcm->len * 8, 24)) { + trace(2, "rtcm3 parity error: len=%d\n", rtcm->len); + return 0; + } + rtcm->nbyte_invalid = 0; /* no error, so clear invalid_byte count */ + /* decode rtcm3 message */ + return decode_rtcm3(rtcm); } /* input RTCM 2 message from file ---------------------------------------------- -* fetch next RTCM 2 message and input a message from file -* args : rtcm_t *rtcm IO rtcm control struct -* FILE *fp I file pointer -* return : status (-2: end of file, -1...10: same as above) -* notes : same as above -*-----------------------------------------------------------------------------*/ -extern int input_rtcm2f(rtcm_t *rtcm, FILE *fp) -{ - int i,data=0,ret; - - trace(4,"input_rtcm2f: data=%02x\n",data); - - for (i=0;i<4096;i++) { - if ((data=fgetc(fp))==EOF) return -2; - if ((ret=input_rtcm2(rtcm,(uint8_t)data))) return ret; - } - return 0; /* return at every 4k bytes */ + * fetch next RTCM 2 message and input a message from file + * args : rtcm_t *rtcm IO rtcm control struct + * FILE *fp I file pointer + * return : status (-2: end of file, -1...10: same as above) + * notes : same as above + *-----------------------------------------------------------------------------*/ +extern int input_rtcm2f(rtcm_t *rtcm, FILE *fp) { + int i, data = 0, ret; + + trace(4, "input_rtcm2f: data=%02x\n", data); + + for (i = 0; i < 4096; i++) { + if ((data = fgetc(fp)) == EOF) return -2; + if ((ret = input_rtcm2(rtcm, (uint8_t)data))) return ret; + } + return 0; /* return at every 4k bytes */ } /* input RTCM 3 message from file ---------------------------------------------- -* fetch next RTCM 3 message and input a message from file -* args : rtcm_t *rtcm IO rtcm control struct -* FILE *fp I file pointer -* return : status (-2: end of file, -1...10: same as above) -* notes : same as above -*-----------------------------------------------------------------------------*/ -extern int input_rtcm3f(rtcm_t *rtcm, FILE *fp) -{ - int i,data=0,ret; - - trace(4,"input_rtcm3f: data=%02x\n",data); - - for (i=0;i<4096;i++) { - if ((data=fgetc(fp))==EOF) return -2; - if ((ret=input_rtcm3(rtcm,(uint8_t)data))) return ret; /* ret!=0 indicates message complete */ - if (rtcm->nbyte_invalid!=0) { /* if last message had error: */ - fseek(fp,-rtcm->nbyte_invalid+1,SEEK_CUR); /* rewind to last preamble+1 */ - i -= rtcm->nbyte_invalid-1; - trace(4,"rewind buff %3d bytes, i=%d\n",rtcm->nbyte_invalid-1,i); - rtcm->nbyte_invalid=0; - } + * fetch next RTCM 3 message and input a message from file + * args : rtcm_t *rtcm IO rtcm control struct + * FILE *fp I file pointer + * return : status (-2: end of file, -1...10: same as above) + * notes : same as above + *-----------------------------------------------------------------------------*/ +extern int input_rtcm3f(rtcm_t *rtcm, FILE *fp) { + int i, data = 0, ret; + + trace(4, "input_rtcm3f: data=%02x\n", data); + + for (i = 0; i < 4096; i++) { + if ((data = fgetc(fp)) == EOF) return -2; + if ((ret = input_rtcm3(rtcm, (uint8_t)data))) + return ret; /* ret!=0 indicates message complete */ + if (rtcm->nbyte_invalid != 0) { /* if last message had error: */ + fseek(fp, -rtcm->nbyte_invalid + 1, SEEK_CUR); /* rewind to last preamble+1 */ + i -= rtcm->nbyte_invalid - 1; + trace(4, "rewind buff %3d bytes, i=%d\n", rtcm->nbyte_invalid - 1, i); + rtcm->nbyte_invalid = 0; } - return 0; /* return at every 4k bytes */ + } + return 0; /* return at every 4k bytes */ } /* generate RTCM 2 message ----------------------------------------------------- -* generate RTCM 2 message -* args : rtcm_t *rtcm IO rtcm control struct -* int type I message type -* int sync I sync flag (1:another message follows) -* return : status (1:ok,0:error) -*-----------------------------------------------------------------------------*/ -extern int gen_rtcm2(rtcm_t *rtcm, int type, int sync) -{ - trace(4,"gen_rtcm2: type=%d sync=%d\n",type,sync); - - rtcm->nbit=rtcm->len=rtcm->nbyte=0; - - /* not yet implemented */ - - return 0; + * generate RTCM 2 message + * args : rtcm_t *rtcm IO rtcm control struct + * int type I message type + * int sync I sync flag (1:another message follows) + * return : status (1:ok,0:error) + *-----------------------------------------------------------------------------*/ +extern int gen_rtcm2(rtcm_t *rtcm, int type, int sync) { + trace(4, "gen_rtcm2: type=%d sync=%d\n", type, sync); + + rtcm->nbit = rtcm->len = rtcm->nbyte = 0; + + /* not yet implemented */ + + return 0; } /* generate RTCM 3 message ----------------------------------------------------- -* generate RTCM 3 message -* args : rtcm_t *rtcm IO rtcm control struct -* int type I message type -* int subtype I message subtype -* int sync I sync flag (1:another message follows) -* return : status (1:ok,0:error) -* notes : For rtcm 3 msm, the {nsat} x {nsig} in rtcm->obs should not exceed -* 64. If {nsat} x {nsig} of the input obs data exceeds 64, separate -* them to multiple ones and call gen_rtcm3() multiple times as user -* responsibility. -* ({nsat} = number of valid satellites, {nsig} = number of signals in -* the obs data) -*-----------------------------------------------------------------------------*/ -extern int gen_rtcm3(rtcm_t *rtcm, int type, int subtype, int sync) -{ - uint32_t crc; - int i=0; - - trace(4,"gen_rtcm3: type=%d subtype=%d sync=%d\n",type,subtype,sync); - - rtcm->nbit=rtcm->len=rtcm->nbyte=0; - - /* set preamble and reserved */ - setbitu(rtcm->buff,i, 8,RTCM3PREAMB); i+= 8; - setbitu(rtcm->buff,i, 6,0 ); i+= 6; - setbitu(rtcm->buff,i,10,0 ); i+=10; - - /* encode rtcm 3 message body */ - if (!encode_rtcm3(rtcm,type,subtype,sync)) return 0; - - /* padding to align 8 bit boundary */ - for (i=rtcm->nbit;i%8;i++) { - setbitu(rtcm->buff,i,1,0); - } - /* message length (header+data) (bytes) */ - if ((rtcm->len=i/8)>=3+1024) { - trace(2,"generate rtcm 3 message length error len=%d\n",rtcm->len-3); - rtcm->nbit=rtcm->len=0; - return 0; - } - /* message length without header and parity */ - setbitu(rtcm->buff,14,10,rtcm->len-3); - - /* crc-24q */ - crc=rtk_crc24q(rtcm->buff,rtcm->len); - setbitu(rtcm->buff,i,24,crc); - - /* length total (bytes) */ - rtcm->nbyte=rtcm->len+3; - - return 1; + * generate RTCM 3 message + * args : rtcm_t *rtcm IO rtcm control struct + * int type I message type + * int subtype I message subtype + * int sync I sync flag (1:another message follows) + * return : status (1:ok,0:error) + * notes : For rtcm 3 msm, the {nsat} x {nsig} in rtcm->obs should not exceed + * 64. If {nsat} x {nsig} of the input obs data exceeds 64, separate + * them to multiple ones and call gen_rtcm3() multiple times as user + * responsibility. + * ({nsat} = number of valid satellites, {nsig} = number of signals in + * the obs data) + *-----------------------------------------------------------------------------*/ +extern int gen_rtcm3(rtcm_t *rtcm, int type, int subtype, int sync) { + uint32_t crc; + int i = 0; + + trace(4, "gen_rtcm3: type=%d subtype=%d sync=%d\n", type, subtype, sync); + + rtcm->nbit = rtcm->len = rtcm->nbyte = 0; + + /* set preamble and reserved */ + setbitu(rtcm->buff, i, 8, RTCM3PREAMB); + i += 8; + setbitu(rtcm->buff, i, 6, 0); + i += 6; + setbitu(rtcm->buff, i, 10, 0); + i += 10; + + /* encode rtcm 3 message body */ + if (!encode_rtcm3(rtcm, type, subtype, sync)) return 0; + + /* padding to align 8 bit boundary */ + for (i = rtcm->nbit; i % 8; i++) { + setbitu(rtcm->buff, i, 1, 0); + } + /* message length (header+data) (bytes) */ + if ((rtcm->len = i / 8) >= 3 + 1024) { + trace(2, "generate rtcm 3 message length error len=%d\n", rtcm->len - 3); + rtcm->nbit = rtcm->len = 0; + return 0; + } + /* message length without header and parity */ + setbitu(rtcm->buff, 14, 10, rtcm->len - 3); + + /* crc-24q */ + crc = rtk_crc24q(rtcm->buff, rtcm->len); + setbitu(rtcm->buff, i, 24, crc); + + /* length total (bytes) */ + rtcm->nbyte = rtcm->len + 3; + + return 1; } diff --git a/src/rtcm2.c b/src/rtcm2.c index d0d251272..f58ad603b 100644 --- a/src/rtcm2.c +++ b/src/rtcm2.c @@ -1,448 +1,525 @@ /*------------------------------------------------------------------------------ -* rtcm2.c : rtcm ver.2 message functions -* -* Copyright (C) 2009-2014 by T.TAKASU, All rights reserved. -* -* references : -* see rtcm.c -* -* version : $Revision:$ $Date:$ -* history : 2011/11/28 1.0 separated from rtcm.c -* 2014/10/21 1.1 fix problem on week rollover in rtcm 2 type 14 -*-----------------------------------------------------------------------------*/ + * rtcm2.c : rtcm ver.2 message functions + * + * Copyright (C) 2009-2014 by T.TAKASU, All rights reserved. + * + * references : + * see rtcm.c + * + * version : $Revision:$ $Date:$ + * history : 2011/11/28 1.0 separated from rtcm.c + * 2014/10/21 1.1 fix problem on week rollover in rtcm 2 type 14 + *-----------------------------------------------------------------------------*/ #include "rtklib.h" /* adjust hourly rollover of rtcm 2 time -------------------------------------*/ -static void adjhour(rtcm_t *rtcm, double zcnt) -{ - double tow,hour,sec; - int week; - - /* if no time, get cpu time */ - if (rtcm->time.time==0) rtcm->time=utc2gpst(timeget()); - tow=time2gpst(rtcm->time,&week); - hour=floor(tow/3600.0); - sec=tow-hour*3600.0; - if (zcntsec+1800.0) zcnt-=3600.0; - rtcm->time=gpst2time(week,hour*3600+zcnt); +static void adjhour(rtcm_t *rtcm, double zcnt) { + double tow, hour, sec; + int week; + + /* if no time, get cpu time */ + if (rtcm->time.time == 0) rtcm->time = utc2gpst(timeget()); + tow = time2gpst(rtcm->time, &week); + hour = floor(tow / 3600.0); + sec = tow - hour * 3600.0; + if (zcnt < sec - 1800.0) + zcnt += 3600.0; + else if (zcnt > sec + 1800.0) + zcnt -= 3600.0; + rtcm->time = gpst2time(week, hour * 3600 + zcnt); } /* get observation data index ------------------------------------------------*/ -static int obsindex(obs_t *obs, gtime_t time, int sat) -{ - int i,j; - - for (i=0;in;i++) { - if (obs->data[i].sat==sat) return i; /* field already exists */ - } - if (i>=MAXOBS) return -1; /* overflow */ - - /* add new field */ - obs->data[i].time=time; - obs->data[i].sat=sat; - for (j=0;jdata[i].L[j]=obs->data[i].P[j]=0.0; - obs->data[i].D[j]=obs->data[i].SNR[j]=0.0; - obs->data[i].LLI[j]=obs->data[i].code[j]=0; - } - obs->n++; - return i; +static int obsindex(obs_t *obs, gtime_t time, int sat) { + int i, j; + + for (i = 0; i < obs->n; i++) { + if (obs->data[i].sat == sat) return i; /* field already exists */ + } + if (i >= MAXOBS) return -1; /* overflow */ + + /* add new field */ + obs->data[i].time = time; + obs->data[i].sat = sat; + for (j = 0; j < NFREQ; j++) { + obs->data[i].L[j] = obs->data[i].P[j] = 0.0; + obs->data[i].D[j] = obs->data[i].SNR[j] = 0.0; + obs->data[i].LLI[j] = obs->data[i].code[j] = 0; + } + obs->n++; + return i; } /* decode type 1/9: differential gps correction/partial correction set -------*/ -static int decode_type1(rtcm_t *rtcm) -{ - int i=48,fact,udre,prn,sat,iod; - double prc,rrc; - - trace(4,"decode_type1: len=%d\n",rtcm->len); - - while (i+40<=rtcm->len*8) { - fact=getbitu(rtcm->buff,i, 1); i+= 1; - udre=getbitu(rtcm->buff,i, 2); i+= 2; - prn =getbitu(rtcm->buff,i, 5); i+= 5; - prc =getbits(rtcm->buff,i,16); i+=16; - rrc =getbits(rtcm->buff,i, 8); i+= 8; - iod =getbits(rtcm->buff,i, 8); i+= 8; - if (prn==0) prn=32; - if (prc==0x80000000||rrc==0xFFFF8000) { - trace(2,"rtcm2 1 prc/rrc indicates satellite problem: prn=%d\n",prn); - continue; - } - if (rtcm->dgps) { - sat=satno(SYS_GPS,prn); - rtcm->dgps[sat-1].t0=rtcm->time; - rtcm->dgps[sat-1].prc=prc*(fact?0.32:0.02); - rtcm->dgps[sat-1].rrc=rrc*(fact?0.032:0.002); - rtcm->dgps[sat-1].iod=iod; - rtcm->dgps[sat-1].udre=udre; - } +static int decode_type1(rtcm_t *rtcm) { + int i = 48, fact, udre, prn, sat, iod; + double prc, rrc; + + trace(4, "decode_type1: len=%d\n", rtcm->len); + + while (i + 40 <= rtcm->len * 8) { + fact = getbitu(rtcm->buff, i, 1); + i += 1; + udre = getbitu(rtcm->buff, i, 2); + i += 2; + prn = getbitu(rtcm->buff, i, 5); + i += 5; + prc = getbits(rtcm->buff, i, 16); + i += 16; + rrc = getbits(rtcm->buff, i, 8); + i += 8; + iod = getbits(rtcm->buff, i, 8); + i += 8; + if (prn == 0) prn = 32; + if (prc == 0x80000000 || rrc == 0xFFFF8000) { + trace(2, "rtcm2 1 prc/rrc indicates satellite problem: prn=%d\n", prn); + continue; } - return 7; + if (rtcm->dgps) { + sat = satno(SYS_GPS, prn); + rtcm->dgps[sat - 1].t0 = rtcm->time; + rtcm->dgps[sat - 1].prc = prc * (fact ? 0.32 : 0.02); + rtcm->dgps[sat - 1].rrc = rrc * (fact ? 0.032 : 0.002); + rtcm->dgps[sat - 1].iod = iod; + rtcm->dgps[sat - 1].udre = udre; + } + } + return 7; } /* decode type 3: reference station parameter --------------------------------*/ -static int decode_type3(rtcm_t *rtcm) -{ - int i=48; - - trace(4,"decode_type3: len=%d\n",rtcm->len); - - if (i+96<=rtcm->len*8) { - rtcm->sta.pos[0]=getbits(rtcm->buff,i,32)*0.01; i+=32; - rtcm->sta.pos[1]=getbits(rtcm->buff,i,32)*0.01; i+=32; - rtcm->sta.pos[2]=getbits(rtcm->buff,i,32)*0.01; - } - else { - trace(2,"rtcm2 3 length error: len=%d\n",rtcm->len); - return -1; - } - return 5; +static int decode_type3(rtcm_t *rtcm) { + int i = 48; + + trace(4, "decode_type3: len=%d\n", rtcm->len); + + if (i + 96 <= rtcm->len * 8) { + rtcm->sta.pos[0] = getbits(rtcm->buff, i, 32) * 0.01; + i += 32; + rtcm->sta.pos[1] = getbits(rtcm->buff, i, 32) * 0.01; + i += 32; + rtcm->sta.pos[2] = getbits(rtcm->buff, i, 32) * 0.01; + } else { + trace(2, "rtcm2 3 length error: len=%d\n", rtcm->len); + return -1; + } + return 5; } /* decode type 14: gps time of week ------------------------------------------*/ -static int decode_type14(rtcm_t *rtcm) -{ - double zcnt; - int i=48,week,hour,leaps; - - trace(4,"decode_type14: len=%d\n",rtcm->len); - - zcnt=getbitu(rtcm->buff,24,13); - if (i+24<=rtcm->len*8) { - week =getbitu(rtcm->buff,i,10); i+=10; - hour =getbitu(rtcm->buff,i, 8); i+= 8; - leaps=getbitu(rtcm->buff,i, 6); - } - else { - trace(2,"rtcm2 14 length error: len=%d\n",rtcm->len); - return -1; - } - week=adjgpsweek(week); - rtcm->time=gpst2time(week,hour*3600.0+zcnt*0.6); - rtcm->nav.utc_gps[4]=leaps; - return 6; +static int decode_type14(rtcm_t *rtcm) { + double zcnt; + int i = 48, week, hour, leaps; + + trace(4, "decode_type14: len=%d\n", rtcm->len); + + zcnt = getbitu(rtcm->buff, 24, 13); + if (i + 24 <= rtcm->len * 8) { + week = getbitu(rtcm->buff, i, 10); + i += 10; + hour = getbitu(rtcm->buff, i, 8); + i += 8; + leaps = getbitu(rtcm->buff, i, 6); + } else { + trace(2, "rtcm2 14 length error: len=%d\n", rtcm->len); + return -1; + } + week = adjgpsweek(week); + rtcm->time = gpst2time(week, hour * 3600.0 + zcnt * 0.6); + rtcm->nav.utc_gps[4] = leaps; + return 6; } /* decode type 16: gps special message ---------------------------------------*/ -static int decode_type16(rtcm_t *rtcm) -{ - int i=48,n=0; - - trace(4,"decode_type16: len=%d\n",rtcm->len); - - while (i+8<=rtcm->len*8&&n<90) { - rtcm->msg[n++]=getbitu(rtcm->buff,i,8); i+=8; - } - rtcm->msg[n]='\0'; - - trace(3,"rtcm2 16 message: %s\n",rtcm->msg); - return 9; +static int decode_type16(rtcm_t *rtcm) { + int i = 48, n = 0; + + trace(4, "decode_type16: len=%d\n", rtcm->len); + + while (i + 8 <= rtcm->len * 8 && n < 90) { + rtcm->msg[n++] = getbitu(rtcm->buff, i, 8); + i += 8; + } + rtcm->msg[n] = '\0'; + + trace(3, "rtcm2 16 message: %s\n", rtcm->msg); + return 9; } /* decode type 17: gps ephemerides -------------------------------------------*/ -static int decode_type17(rtcm_t *rtcm) -{ - eph_t eph={0}; - double toc,sqrtA; - int i=48,week,prn,sat; - - trace(4,"decode_type17: len=%d\n",rtcm->len); - - if (i+480<=rtcm->len*8) { - week =getbitu(rtcm->buff,i,10); i+=10; - eph.idot =getbits(rtcm->buff,i,14)*P2_43*SC2RAD; i+=14; - eph.iode =getbitu(rtcm->buff,i, 8); i+= 8; - toc =getbitu(rtcm->buff,i,16)*16.0; i+=16; - eph.f1 =getbits(rtcm->buff,i,16)*P2_43; i+=16; - eph.f2 =getbits(rtcm->buff,i, 8)*P2_55; i+= 8; - eph.crs =getbits(rtcm->buff,i,16)*P2_5; i+=16; - eph.deln =getbits(rtcm->buff,i,16)*P2_43*SC2RAD; i+=16; - eph.cuc =getbits(rtcm->buff,i,16)*P2_29; i+=16; - eph.e =getbitu(rtcm->buff,i,32)*P2_33; i+=32; - eph.cus =getbits(rtcm->buff,i,16); i+=16; - sqrtA =getbitu(rtcm->buff,i,32)*P2_19; i+=32; - eph.toes =getbitu(rtcm->buff,i,16); i+=16; - eph.OMG0 =getbits(rtcm->buff,i,32)*P2_31*SC2RAD; i+=32; - eph.cic =getbits(rtcm->buff,i,16)*P2_29; i+=16; - eph.i0 =getbits(rtcm->buff,i,32)*P2_31*SC2RAD; i+=32; - eph.cis =getbits(rtcm->buff,i,16)*P2_29; i+=16; - eph.omg =getbits(rtcm->buff,i,32)*P2_31*SC2RAD; i+=32; - eph.crc =getbits(rtcm->buff,i,16)*P2_5; i+=16; - eph.OMGd =getbits(rtcm->buff,i,24)*P2_43*SC2RAD; i+=24; - eph.M0 =getbits(rtcm->buff,i,32)*P2_31*SC2RAD; i+=32; - eph.iodc =getbitu(rtcm->buff,i,10); i+=10; - eph.f0 =getbits(rtcm->buff,i,22)*P2_31; i+=22; - prn =getbitu(rtcm->buff,i, 5); i+= 5+3; - eph.tgd[0]=getbits(rtcm->buff,i, 8)*P2_31; i+= 8; - eph.code =getbitu(rtcm->buff,i, 2); i+= 2; - eph.sva =getbitu(rtcm->buff,i, 4); i+= 4; - eph.svh =getbitu(rtcm->buff,i, 6); i+= 6; - eph.flag =getbitu(rtcm->buff,i, 1); - } - else { - trace(2,"rtcm2 17 length error: len=%d\n",rtcm->len); - return -1; - } - if (prn==0) prn=32; - sat=satno(SYS_GPS,prn); - eph.sat=sat; - eph.week=adjgpsweek(week); - eph.toe=gpst2time(eph.week,eph.toes); - eph.toc=gpst2time(eph.week,toc); - eph.ttr=rtcm->time; - eph.A=sqrtA*sqrtA; - rtcm->nav.eph[sat-1]=eph; - rtcm->ephset=0; - rtcm->ephsat=sat; - return 2; +static int decode_type17(rtcm_t *rtcm) { + eph_t eph = {0}; + double toc, sqrtA; + int i = 48, week, prn, sat; + + trace(4, "decode_type17: len=%d\n", rtcm->len); + + if (i + 480 <= rtcm->len * 8) { + week = getbitu(rtcm->buff, i, 10); + i += 10; + eph.idot = getbits(rtcm->buff, i, 14) * P2_43 * SC2RAD; + i += 14; + eph.iode = getbitu(rtcm->buff, i, 8); + i += 8; + toc = getbitu(rtcm->buff, i, 16) * 16.0; + i += 16; + eph.f1 = getbits(rtcm->buff, i, 16) * P2_43; + i += 16; + eph.f2 = getbits(rtcm->buff, i, 8) * P2_55; + i += 8; + eph.crs = getbits(rtcm->buff, i, 16) * P2_5; + i += 16; + eph.deln = getbits(rtcm->buff, i, 16) * P2_43 * SC2RAD; + i += 16; + eph.cuc = getbits(rtcm->buff, i, 16) * P2_29; + i += 16; + eph.e = getbitu(rtcm->buff, i, 32) * P2_33; + i += 32; + eph.cus = getbits(rtcm->buff, i, 16); + i += 16; + sqrtA = getbitu(rtcm->buff, i, 32) * P2_19; + i += 32; + eph.toes = getbitu(rtcm->buff, i, 16); + i += 16; + eph.OMG0 = getbits(rtcm->buff, i, 32) * P2_31 * SC2RAD; + i += 32; + eph.cic = getbits(rtcm->buff, i, 16) * P2_29; + i += 16; + eph.i0 = getbits(rtcm->buff, i, 32) * P2_31 * SC2RAD; + i += 32; + eph.cis = getbits(rtcm->buff, i, 16) * P2_29; + i += 16; + eph.omg = getbits(rtcm->buff, i, 32) * P2_31 * SC2RAD; + i += 32; + eph.crc = getbits(rtcm->buff, i, 16) * P2_5; + i += 16; + eph.OMGd = getbits(rtcm->buff, i, 24) * P2_43 * SC2RAD; + i += 24; + eph.M0 = getbits(rtcm->buff, i, 32) * P2_31 * SC2RAD; + i += 32; + eph.iodc = getbitu(rtcm->buff, i, 10); + i += 10; + eph.f0 = getbits(rtcm->buff, i, 22) * P2_31; + i += 22; + prn = getbitu(rtcm->buff, i, 5); + i += 5 + 3; + eph.tgd[0] = getbits(rtcm->buff, i, 8) * P2_31; + i += 8; + eph.code = getbitu(rtcm->buff, i, 2); + i += 2; + eph.sva = getbitu(rtcm->buff, i, 4); + i += 4; + eph.svh = getbitu(rtcm->buff, i, 6); + i += 6; + eph.flag = getbitu(rtcm->buff, i, 1); + } else { + trace(2, "rtcm2 17 length error: len=%d\n", rtcm->len); + return -1; + } + if (prn == 0) prn = 32; + sat = satno(SYS_GPS, prn); + eph.sat = sat; + eph.week = adjgpsweek(week); + eph.toe = gpst2time(eph.week, eph.toes); + eph.toc = gpst2time(eph.week, toc); + eph.ttr = rtcm->time; + eph.A = sqrtA * sqrtA; + rtcm->nav.eph[sat - 1] = eph; + rtcm->ephset = 0; + rtcm->ephsat = sat; + return 2; } /* decode type 18: rtk uncorrected carrier-phase -----------------------------*/ -static int decode_type18(rtcm_t *rtcm) -{ - double usec,cp; - int i=48,index,freq,sync=1,code,sys,prn,sat,loss; - - if (rtcm->obsflag) rtcm->obs.n = rtcm->obsflag = 0; +static int decode_type18(rtcm_t *rtcm) { + double usec, cp; + int i = 48, index, freq, sync = 1, code, sys, prn, sat, loss; - trace(4,"decode_type18: len=%d\n",rtcm->len); - - if (i+24<=rtcm->len*8) { - freq=getbitu(rtcm->buff,i, 2); i+= 2+2; - usec=getbitu(rtcm->buff,i,20); i+=20; - } - else { - trace(2,"rtcm2 18 length error: len=%d\n",rtcm->len); - return -1; - } - if (freq&0x1) { - trace(2,"rtcm2 18 not supported frequency: freq=%d\n",freq); - return -1; + if (rtcm->obsflag) rtcm->obs.n = rtcm->obsflag = 0; + + trace(4, "decode_type18: len=%d\n", rtcm->len); + + if (i + 24 <= rtcm->len * 8) { + freq = getbitu(rtcm->buff, i, 2); + i += 2 + 2; + usec = getbitu(rtcm->buff, i, 20); + i += 20; + } else { + trace(2, "rtcm2 18 length error: len=%d\n", rtcm->len); + return -1; + } + if (freq & 0x1) { + trace(2, "rtcm2 18 not supported frequency: freq=%d\n", freq); + return -1; + } + freq >>= 1; + + gtime_t rtime = timeadd(rtcm->time, usec * 1E-6); + + while (i + 48 <= rtcm->len * 8) { + sync = getbitu(rtcm->buff, i, 1); + i += 1; + code = getbitu(rtcm->buff, i, 1); + i += 1; + sys = getbitu(rtcm->buff, i, 1); + i += 1; + prn = getbitu(rtcm->buff, i, 5); + i += 5 + 3; + loss = getbitu(rtcm->buff, i, 5); + i += 5; + cp = getbits(rtcm->buff, i, 32); + i += 32; + if (prn == 0) prn = 32; + if (!(sat = satno(sys ? SYS_GLO : SYS_GPS, prn))) { + trace(2, "rtcm2 18 satellite number error: sys=%d prn=%d\n", sys, prn); + continue; } - freq>>=1; - - gtime_t rtime = timeadd(rtcm->time, usec * 1E-6); + gtime_t time; + if (sys) + time = utc2gpst(rtime); /* convert glonass time to gpst */ + else + time = rtime; - while (i+48<=rtcm->len*8) { - sync=getbitu(rtcm->buff,i, 1); i+= 1; - code=getbitu(rtcm->buff,i, 1); i+= 1; - sys =getbitu(rtcm->buff,i, 1); i+= 1; - prn =getbitu(rtcm->buff,i, 5); i+= 5+3; - loss=getbitu(rtcm->buff,i, 5); i+= 5; - cp =getbits(rtcm->buff,i,32); i+=32; - if (prn==0) prn=32; - if (!(sat=satno(sys?SYS_GLO:SYS_GPS,prn))) { - trace(2,"rtcm2 18 satellite number error: sys=%d prn=%d\n",sys,prn); - continue; - } - gtime_t time; - if (sys) time=utc2gpst(rtime); /* convert glonass time to gpst */ - else time=rtime; - - double tt=timediff(time,rtcm->obs.data[0].time); - if (fabs(tt)>1E-9) rtcm->obs.n=rtcm->obsflag=0; - if ((index=obsindex(&rtcm->obs,time,sat))>=0) { - rtcm->obs.data[index].L[freq]=-cp/256.0; - rtcm->obs.data[index].LLI[freq]=rtcm->loss[sat-1][freq]!=loss?LLI_SLIP:0; - rtcm->obs.data[index].code[freq]= - !freq?(code?CODE_L1P:CODE_L1C):(code?CODE_L2P:CODE_L2C); - rtcm->loss[sat-1][freq]=loss; - } + double tt = timediff(time, rtcm->obs.data[0].time); + if (fabs(tt) > 1E-9) rtcm->obs.n = rtcm->obsflag = 0; + if ((index = obsindex(&rtcm->obs, time, sat)) >= 0) { + rtcm->obs.data[index].L[freq] = -cp / 256.0; + rtcm->obs.data[index].LLI[freq] = rtcm->loss[sat - 1][freq] != loss ? LLI_SLIP : 0; + rtcm->obs.data[index].code[freq] = + !freq ? (code ? CODE_L1P : CODE_L1C) : (code ? CODE_L2P : CODE_L2C); + rtcm->loss[sat - 1][freq] = loss; } - rtcm->obsflag=!sync; - return sync?0:1; + } + rtcm->obsflag = !sync; + return sync ? 0 : 1; } /* decode type 19: rtk uncorrected pseudorange -------------------------------*/ -static int decode_type19(rtcm_t *rtcm) -{ - double usec,pr; - int i=48,freq,sync=1,code,sys,prn,sat; - - trace(4,"decode_type19: len=%d\n",rtcm->len); - - if (rtcm->obsflag) rtcm->obs.n = rtcm->obsflag = 0; +static int decode_type19(rtcm_t *rtcm) { + double usec, pr; + int i = 48, freq, sync = 1, code, sys, prn, sat; - if (i+24<=rtcm->len*8) { - freq=getbitu(rtcm->buff,i, 2); i+= 2+2; - usec=getbitu(rtcm->buff,i,20); i+=20; - } - else { - trace(2,"rtcm2 19 length error: len=%d\n",rtcm->len); - return -1; - } - if (freq&0x1) { - trace(2,"rtcm2 19 not supported frequency: freq=%d\n",freq); - return -1; + trace(4, "decode_type19: len=%d\n", rtcm->len); + + if (rtcm->obsflag) rtcm->obs.n = rtcm->obsflag = 0; + + if (i + 24 <= rtcm->len * 8) { + freq = getbitu(rtcm->buff, i, 2); + i += 2 + 2; + usec = getbitu(rtcm->buff, i, 20); + i += 20; + } else { + trace(2, "rtcm2 19 length error: len=%d\n", rtcm->len); + return -1; + } + if (freq & 0x1) { + trace(2, "rtcm2 19 not supported frequency: freq=%d\n", freq); + return -1; + } + freq >>= 1; + + while (i + 48 <= rtcm->len * 8) { + sync = getbitu(rtcm->buff, i, 1); + i += 1; + code = getbitu(rtcm->buff, i, 1); + i += 1; + sys = getbitu(rtcm->buff, i, 1); + i += 1; + prn = getbitu(rtcm->buff, i, 5); + i += 5 + 8; + pr = getbitu(rtcm->buff, i, 32); + i += 32; + if (prn == 0) prn = 32; + if (!(sat = satno(sys ? SYS_GLO : SYS_GPS, prn))) { + trace(2, "rtcm2 19 satellite number error: sys=%d prn=%d\n", sys, prn); + continue; } - freq>>=1; - - while (i+48<=rtcm->len*8) { - sync=getbitu(rtcm->buff,i, 1); i+= 1; - code=getbitu(rtcm->buff,i, 1); i+= 1; - sys =getbitu(rtcm->buff,i, 1); i+= 1; - prn =getbitu(rtcm->buff,i, 5); i+= 5+8; - pr =getbitu(rtcm->buff,i,32); i+=32; - if (prn==0) prn=32; - if (!(sat=satno(sys?SYS_GLO:SYS_GPS,prn))) { - trace(2,"rtcm2 19 satellite number error: sys=%d prn=%d\n",sys,prn); - continue; - } - gtime_t time=timeadd(rtcm->time,usec*1E-6); - if (sys) time=utc2gpst(time); /* convert glonass time to gpst */ - - double tt=timediff(time, rtcm->obs.data[0].time); - if (fabs(tt)>1E-9) rtcm->obs.n=rtcm->obsflag=0; - int index=obsindex(&rtcm->obs,time,sat); - if (index>=0) { - double P = pr * 0.02; - rtcm->obs.data[index].P[freq] = P; - int lcode = rtcm->obs.data[index].code[freq]; - int pcode = !freq ? (code ? CODE_L1P : CODE_L1C) : (code ? CODE_L2P : CODE_L2C); - rtcm->obs.data[index].code[freq] = pcode; - if (lcode > 0) { - if (pcode != lcode) trace(2, "rtcm2 19 code mismatch Lcode=%d Pcode=%d\n", lcode, pcode); - double L = rtcm->obs.data[index].L[freq]; - double lam = freq ? CLIGHT / FREQL2 : CLIGHT / FREQL1; - double n = floor((P / lam - L) / pow(2, 23) + 0.5); - rtcm->obs.data[index].L[freq] = n * pow(2, 23) + L; - } - } + gtime_t time = timeadd(rtcm->time, usec * 1E-6); + if (sys) time = utc2gpst(time); /* convert glonass time to gpst */ + + double tt = timediff(time, rtcm->obs.data[0].time); + if (fabs(tt) > 1E-9) rtcm->obs.n = rtcm->obsflag = 0; + int index = obsindex(&rtcm->obs, time, sat); + if (index >= 0) { + double P = pr * 0.02; + rtcm->obs.data[index].P[freq] = P; + int lcode = rtcm->obs.data[index].code[freq]; + int pcode = !freq ? (code ? CODE_L1P : CODE_L1C) : (code ? CODE_L2P : CODE_L2C); + rtcm->obs.data[index].code[freq] = pcode; + if (lcode > 0) { + if (pcode != lcode) trace(2, "rtcm2 19 code mismatch Lcode=%d Pcode=%d\n", lcode, pcode); + double L = rtcm->obs.data[index].L[freq]; + double lam = freq ? CLIGHT / FREQL2 : CLIGHT / FREQL1; + double n = floor((P / lam - L) / pow(2, 23) + 0.5); + rtcm->obs.data[index].L[freq] = n * pow(2, 23) + L; + } } - rtcm->obsflag=!sync; - return sync?0:1; + } + rtcm->obsflag = !sync; + return sync ? 0 : 1; } /* decode type 22: extended reference station parameter ----------------------*/ -static int decode_type22(rtcm_t *rtcm) -{ - double del[2][3]={{0}},hgt=0.0; - int i=48,j,noh; - - trace(4,"decode_type22: len=%d\n",rtcm->len); - - if (i+24<=rtcm->len*8) { - del[0][0]=getbits(rtcm->buff,i,8)/25600.0; i+=8; - del[0][1]=getbits(rtcm->buff,i,8)/25600.0; i+=8; - del[0][2]=getbits(rtcm->buff,i,8)/25600.0; i+=8; - } - else { - trace(2,"rtcm2 22 length error: len=%d\n",rtcm->len); - return -1; - } - if (i+24<=rtcm->len*8) { - i+=5; noh=getbits(rtcm->buff,i,1); i+=1; - hgt=noh?0.0:getbitu(rtcm->buff,i,18)/25600.0; - i+=18; - } - if (i+24<=rtcm->len*8) { - del[1][0]=getbits(rtcm->buff,i,8)/1600.0; i+=8; - del[1][1]=getbits(rtcm->buff,i,8)/1600.0; i+=8; - del[1][2]=getbits(rtcm->buff,i,8)/1600.0; - } - rtcm->sta.deltype=1; /* xyz */ - for (j=0;j<3;j++) rtcm->sta.del[j]=del[0][j]; - rtcm->sta.hgt=hgt; - return 5; +static int decode_type22(rtcm_t *rtcm) { + double del[2][3] = {{0}}, hgt = 0.0; + int i = 48, j, noh; + + trace(4, "decode_type22: len=%d\n", rtcm->len); + + if (i + 24 <= rtcm->len * 8) { + del[0][0] = getbits(rtcm->buff, i, 8) / 25600.0; + i += 8; + del[0][1] = getbits(rtcm->buff, i, 8) / 25600.0; + i += 8; + del[0][2] = getbits(rtcm->buff, i, 8) / 25600.0; + i += 8; + } else { + trace(2, "rtcm2 22 length error: len=%d\n", rtcm->len); + return -1; + } + if (i + 24 <= rtcm->len * 8) { + i += 5; + noh = getbits(rtcm->buff, i, 1); + i += 1; + hgt = noh ? 0.0 : getbitu(rtcm->buff, i, 18) / 25600.0; + i += 18; + } + if (i + 24 <= rtcm->len * 8) { + del[1][0] = getbits(rtcm->buff, i, 8) / 1600.0; + i += 8; + del[1][1] = getbits(rtcm->buff, i, 8) / 1600.0; + i += 8; + del[1][2] = getbits(rtcm->buff, i, 8) / 1600.0; + } + rtcm->sta.deltype = 1; /* xyz */ + for (j = 0; j < 3; j++) rtcm->sta.del[j] = del[0][j]; + rtcm->sta.hgt = hgt; + return 5; } /* decode type 23: antenna type definition record ----------------------------*/ -static int decode_type23(rtcm_t *rtcm) -{ - (void)rtcm; - return 0; +static int decode_type23(rtcm_t *rtcm) { + (void)rtcm; + return 0; } /* decode type 24: antenna reference point (arp) -----------------------------*/ -static int decode_type24(rtcm_t *rtcm) -{ - (void)rtcm; - return 0; +static int decode_type24(rtcm_t *rtcm) { + (void)rtcm; + return 0; } /* decode type 31: differential glonass correction ---------------------------*/ -static int decode_type31(rtcm_t *rtcm) -{ - (void)rtcm; - return 0; +static int decode_type31(rtcm_t *rtcm) { + (void)rtcm; + return 0; } /* decode type 32: differential glonass reference station parameters ---------*/ -static int decode_type32(rtcm_t *rtcm) -{ - (void)rtcm; - return 0; +static int decode_type32(rtcm_t *rtcm) { + (void)rtcm; + return 0; } /* decode type 34: glonass partial differential correction set ---------------*/ -static int decode_type34(rtcm_t *rtcm) -{ - (void)rtcm; - return 0; +static int decode_type34(rtcm_t *rtcm) { + (void)rtcm; + return 0; } /* decode type 36: glonass special message -----------------------------------*/ -static int decode_type36(rtcm_t *rtcm) -{ - (void)rtcm; - return 0; +static int decode_type36(rtcm_t *rtcm) { + (void)rtcm; + return 0; } /* decode type 37: gnss system time offset -----------------------------------*/ -static int decode_type37(rtcm_t *rtcm) -{ - (void)rtcm; - return 0; +static int decode_type37(rtcm_t *rtcm) { + (void)rtcm; + return 0; } /* decode type 59: proprietary message ---------------------------------------*/ -static int decode_type59(rtcm_t *rtcm) -{ - (void)rtcm; - return 0; +static int decode_type59(rtcm_t *rtcm) { + (void)rtcm; + return 0; } /* decode rtcm ver.2 message -------------------------------------------------*/ -extern int decode_rtcm2(rtcm_t *rtcm) -{ - double zcnt; - int staid,seqno,stah,ret=0,type=getbitu(rtcm->buff,8,6); - - trace(3,"decode_rtcm2: type=%2d len=%3d\n",type,rtcm->len); - - if ((zcnt=getbitu(rtcm->buff,24,13)*0.6)>=3600.0) { - trace(2,"rtcm2 modified z-count error: zcnt=%.1f\n",zcnt); - return -1; - } - adjhour(rtcm,zcnt); - staid=getbitu(rtcm->buff,14,10); - seqno=getbitu(rtcm->buff,37, 3); - stah =getbitu(rtcm->buff,45, 3); - if (seqno-rtcm->seqno!=1&&seqno-rtcm->seqno!=-7) { - trace(2,"rtcm2 message outage: seqno=%d->%d\n",rtcm->seqno,seqno); - } - rtcm->seqno=seqno; - rtcm->stah =stah; - - if (rtcm->outtype) { - sprintf(rtcm->msgtype,"RTCM %2d (%4d) zcnt=%7.1f staid=%3d seqno=%d", - type,rtcm->len,zcnt,staid,seqno); - } - if (type==3||type==22||type==23||type==24) { - if (rtcm->staid!=0&&staid!=rtcm->staid) { - trace(2,"rtcm2 station id changed: %d->%d\n",rtcm->staid,staid); - } - rtcm->staid=staid; - } - if (rtcm->staid!=0&&staid!=rtcm->staid) { - trace(2,"rtcm2 station id invalid: %d %d\n",staid,rtcm->staid); - return -1; - } - switch (type) { - case 1: ret=decode_type1 (rtcm); break; - case 3: ret=decode_type3 (rtcm); break; - case 9: ret=decode_type1 (rtcm); break; - case 14: ret=decode_type14(rtcm); break; - case 16: ret=decode_type16(rtcm); break; - case 17: ret=decode_type17(rtcm); break; - case 18: ret=decode_type18(rtcm); break; - case 19: ret=decode_type19(rtcm); break; - case 22: ret=decode_type22(rtcm); break; - case 23: ret=decode_type23(rtcm); break; /* not supported */ - case 24: ret=decode_type24(rtcm); break; /* not supported */ - case 31: ret=decode_type31(rtcm); break; /* not supported */ - case 32: ret=decode_type32(rtcm); break; /* not supported */ - case 34: ret=decode_type34(rtcm); break; /* not supported */ - case 36: ret=decode_type36(rtcm); break; /* not supported */ - case 37: ret=decode_type37(rtcm); break; /* not supported */ - case 59: ret=decode_type59(rtcm); break; /* not supported */ - } - if (ret>=0) { - if (1<=type&&type<=99) rtcm->nmsg2[type]++; else rtcm->nmsg2[0]++; +extern int decode_rtcm2(rtcm_t *rtcm) { + double zcnt; + int staid, seqno, stah, ret = 0, type = getbitu(rtcm->buff, 8, 6); + + trace(3, "decode_rtcm2: type=%2d len=%3d\n", type, rtcm->len); + + if ((zcnt = getbitu(rtcm->buff, 24, 13) * 0.6) >= 3600.0) { + trace(2, "rtcm2 modified z-count error: zcnt=%.1f\n", zcnt); + return -1; + } + adjhour(rtcm, zcnt); + staid = getbitu(rtcm->buff, 14, 10); + seqno = getbitu(rtcm->buff, 37, 3); + stah = getbitu(rtcm->buff, 45, 3); + if (seqno - rtcm->seqno != 1 && seqno - rtcm->seqno != -7) { + trace(2, "rtcm2 message outage: seqno=%d->%d\n", rtcm->seqno, seqno); + } + rtcm->seqno = seqno; + rtcm->stah = stah; + + if (rtcm->outtype) { + sprintf(rtcm->msgtype, "RTCM %2d (%4d) zcnt=%7.1f staid=%3d seqno=%d", type, rtcm->len, zcnt, + staid, seqno); + } + if (type == 3 || type == 22 || type == 23 || type == 24) { + if (rtcm->staid != 0 && staid != rtcm->staid) { + trace(2, "rtcm2 station id changed: %d->%d\n", rtcm->staid, staid); } - return ret; + rtcm->staid = staid; + } + if (rtcm->staid != 0 && staid != rtcm->staid) { + trace(2, "rtcm2 station id invalid: %d %d\n", staid, rtcm->staid); + return -1; + } + switch (type) { + case 1: + ret = decode_type1(rtcm); + break; + case 3: + ret = decode_type3(rtcm); + break; + case 9: + ret = decode_type1(rtcm); + break; + case 14: + ret = decode_type14(rtcm); + break; + case 16: + ret = decode_type16(rtcm); + break; + case 17: + ret = decode_type17(rtcm); + break; + case 18: + ret = decode_type18(rtcm); + break; + case 19: + ret = decode_type19(rtcm); + break; + case 22: + ret = decode_type22(rtcm); + break; + case 23: + ret = decode_type23(rtcm); + break; /* not supported */ + case 24: + ret = decode_type24(rtcm); + break; /* not supported */ + case 31: + ret = decode_type31(rtcm); + break; /* not supported */ + case 32: + ret = decode_type32(rtcm); + break; /* not supported */ + case 34: + ret = decode_type34(rtcm); + break; /* not supported */ + case 36: + ret = decode_type36(rtcm); + break; /* not supported */ + case 37: + ret = decode_type37(rtcm); + break; /* not supported */ + case 59: + ret = decode_type59(rtcm); + break; /* not supported */ + } + if (ret >= 0) { + if (1 <= type && type <= 99) + rtcm->nmsg2[type]++; + else + rtcm->nmsg2[0]++; + } + return ret; } diff --git a/src/rtcm3.c b/src/rtcm3.c index 474612384..46c5d2692 100644 --- a/src/rtcm3.c +++ b/src/rtcm3.c @@ -1,82 +1,82 @@ /*------------------------------------------------------------------------------ -* rtcm3.c : RTCM ver.3 message decorder functions -* -* Copyright (C) 2009-2020 by T.TAKASU, All rights reserved. -* -* references : -* see rtcm.c -* -* version : $Revision:$ $Date:$ -* history : 2012/05/14 1.0 separated from rtcm.c -* 2012/12/12 1.1 support gal/qzs ephemeris, gal/qzs ssr, msm -* add station id consistency test for obs data -* 2012/12/25 1.2 change compass msm id table -* 2013/01/31 1.3 change signal id by the latest draft (ref [13]) -* 2013/02/23 1.4 change reference for rtcm 3 message (ref [14]) -* 2013/05/19 1.5 gpst -> bdt of time-tag in beidou msm message -* 2014/05/02 1.6 fix bug on dropping last field of ssr message -* comply with rtcm 3.2 with amendment 1/2 (ref[15]) -* delete MT 1046 according to ref [15] -* 2014/09/14 1.7 add receiver option -RT_INP -* 2014/12/06 1.8 support SBAS/BeiDou SSR messages (ref [16]) -* 2015/03/22 1.9 add handling of iodcrc for beidou/sbas ssr messages -* 2015/04/27 1.10 support phase bias messages (MT2065-2070) -* 2015/09/07 1.11 add message count of MT 2000-2099 -* 2015/10/21 1.12 add MT1046 support for IGS MGEX -* fix bug on decode of SSR 3/7 (code/phase bias) -* 2015/12/04 1.13 add MT63 beidou ephemeris (rtcm draft) -* fix bug on ssr 3 message decoding (#321) -* 2016/01/22 1.14 fix bug on L2C code in MT1004 (#131) -* 2016/08/20 1.15 fix bug on loss-of-lock detection in MSM 6/7 (#134) -* 2016/09/20 1.16 fix bug on MT1045 Galileo week rollover -* 2016/10/09 1.17 support MT1029 unicode text string -* 2017/04/11 1.18 fix bug on unchange-test of beidou ephemeris -* fix bug on week number in galileo ephemeris struct -* 2018/10/10 1.19 merge changes for 2.4.2 p13 -* fix problem on eph.code for galileo ephemeris -* change mt for ssr 7 phase biases -* add rtcm option -GALINAV, -GALFNAV -* 2018/11/05 1.20 fix problem on invalid time in message monitor -* 2019/05/10 1.21 save galileo E5b data to obs index 2 -* 2020/11/30 1.22 support MT1230 GLONASS code-phase biases -* support MT1131-1137,1041 (NavIC MSM and ephemeris) -* support MT4076 IGS SSR -* update MSM signal ID table (ref [17]) -* update SSR signal and tracking mode ID table -* add week adjustment in MT1019,1044,1045,1046,1042 -* use API code2idx() to get freq-index -* use API code2freq() to get carrier frequency -* use integer types in stdint.h -*-----------------------------------------------------------------------------*/ + * rtcm3.c : RTCM ver.3 message decorder functions + * + * Copyright (C) 2009-2020 by T.TAKASU, All rights reserved. + * + * references : + * see rtcm.c + * + * version : $Revision:$ $Date:$ + * history : 2012/05/14 1.0 separated from rtcm.c + * 2012/12/12 1.1 support gal/qzs ephemeris, gal/qzs ssr, msm + * add station id consistency test for obs data + * 2012/12/25 1.2 change compass msm id table + * 2013/01/31 1.3 change signal id by the latest draft (ref [13]) + * 2013/02/23 1.4 change reference for rtcm 3 message (ref [14]) + * 2013/05/19 1.5 gpst -> bdt of time-tag in beidou msm message + * 2014/05/02 1.6 fix bug on dropping last field of ssr message + * comply with rtcm 3.2 with amendment 1/2 (ref[15]) + * delete MT 1046 according to ref [15] + * 2014/09/14 1.7 add receiver option -RT_INP + * 2014/12/06 1.8 support SBAS/BeiDou SSR messages (ref [16]) + * 2015/03/22 1.9 add handling of iodcrc for beidou/sbas ssr messages + * 2015/04/27 1.10 support phase bias messages (MT2065-2070) + * 2015/09/07 1.11 add message count of MT 2000-2099 + * 2015/10/21 1.12 add MT1046 support for IGS MGEX + * fix bug on decode of SSR 3/7 (code/phase bias) + * 2015/12/04 1.13 add MT63 beidou ephemeris (rtcm draft) + * fix bug on ssr 3 message decoding (#321) + * 2016/01/22 1.14 fix bug on L2C code in MT1004 (#131) + * 2016/08/20 1.15 fix bug on loss-of-lock detection in MSM 6/7 (#134) + * 2016/09/20 1.16 fix bug on MT1045 Galileo week rollover + * 2016/10/09 1.17 support MT1029 unicode text string + * 2017/04/11 1.18 fix bug on unchange-test of beidou ephemeris + * fix bug on week number in galileo ephemeris struct + * 2018/10/10 1.19 merge changes for 2.4.2 p13 + * fix problem on eph.code for galileo ephemeris + * change mt for ssr 7 phase biases + * add rtcm option -GALINAV, -GALFNAV + * 2018/11/05 1.20 fix problem on invalid time in message monitor + * 2019/05/10 1.21 save galileo E5b data to obs index 2 + * 2020/11/30 1.22 support MT1230 GLONASS code-phase biases + * support MT1131-1137,1041 (NavIC MSM and ephemeris) + * support MT4076 IGS SSR + * update MSM signal ID table (ref [17]) + * update SSR signal and tracking mode ID table + * add week adjustment in MT1019,1044,1045,1046,1042 + * use API code2idx() to get freq-index + * use API code2freq() to get carrier frequency + * use integer types in stdint.h + *-----------------------------------------------------------------------------*/ #include "rtklib.h" /* constants -----------------------------------------------------------------*/ -#define PRUNIT_GPS 299792.458 /* rtcm ver.3 unit of gps pseudorange (m) */ -#define PRUNIT_GLO 599584.916 /* rtcm ver.3 unit of glonass pseudorange (m) */ -#define RANGE_MS (CLIGHT*0.001) /* range in 1 ms */ +#define PRUNIT_GPS 299792.458 /* rtcm ver.3 unit of gps pseudorange (m) */ +#define PRUNIT_GLO 599584.916 /* rtcm ver.3 unit of glonass pseudorange (m) */ +#define RANGE_MS (CLIGHT * 0.001) /* range in 1 ms */ -#define P2_10 0.0009765625 /* 2^-10 */ -#define P2_28 3.725290298461914E-09 /* 2^-28 */ -#define P2_34 5.820766091346740E-11 /* 2^-34 */ -#define P2_41 4.547473508864641E-13 /* 2^-41 */ -#define P2_46 1.421085471520200E-14 /* 2^-46 */ -#define P2_59 1.734723475976810E-18 /* 2^-59 */ -#define P2_66 1.355252715606880E-20 /* 2^-66 */ +#define P2_10 0.0009765625 /* 2^-10 */ +#define P2_28 3.725290298461914E-09 /* 2^-28 */ +#define P2_34 5.820766091346740E-11 /* 2^-34 */ +#define P2_41 4.547473508864641E-13 /* 2^-41 */ +#define P2_46 1.421085471520200E-14 /* 2^-46 */ +#define P2_59 1.734723475976810E-18 /* 2^-59 */ +#define P2_66 1.355252715606880E-20 /* 2^-66 */ /* type definition -----------------------------------------------------------*/ -typedef struct { /* multi-signal-message header type */ - uint8_t iod; /* issue of data station */ - uint8_t time_s; /* cumulative session transmitting time */ - uint8_t clk_str; /* clock steering indicator */ - uint8_t clk_ext; /* external clock indicator */ - uint8_t smooth; /* divergence free smoothing indicator */ - uint8_t tint_s; /* soothing interval */ - uint8_t nsat,nsig; /* number of satellites/signals */ - uint8_t sats[64]; /* satellites */ - uint8_t sigs[32]; /* signals */ - uint8_t cellmask[64]; /* cell mask */ +typedef struct { /* multi-signal-message header type */ + uint8_t iod; /* issue of data station */ + uint8_t time_s; /* cumulative session transmitting time */ + uint8_t clk_str; /* clock steering indicator */ + uint8_t clk_ext; /* external clock indicator */ + uint8_t smooth; /* divergence free smoothing indicator */ + uint8_t tint_s; /* soothing interval */ + uint8_t nsat, nsig; /* number of satellites/signals */ + uint8_t sats[64]; /* satellites */ + uint8_t sigs[32]; /* signals */ + uint8_t cellmask[64]; /* cell mask */ } msm_h_t; /* MSM signal ID table -------------------------------------------------------*/ @@ -125,2602 +125,3431 @@ const char *msm_sig_irn[32] = { "5X", "", "", "", "", "", "", ""}; // 25-32 /* SSR signal and tracking mode IDs ------------------------------------------*/ -const uint8_t ssr_sig_gps[32]={ - CODE_L1C,CODE_L1P,CODE_L1W,CODE_L1S,CODE_L1L,CODE_L2C,CODE_L2D,CODE_L2S, - CODE_L2L,CODE_L2X,CODE_L2P,CODE_L2W, 0, 0,CODE_L5I,CODE_L5Q -}; -const uint8_t ssr_sig_glo[32]={ - CODE_L1C,CODE_L1P,CODE_L2C,CODE_L2P,CODE_L4A,CODE_L4B,CODE_L6A,CODE_L6B, - CODE_L3I,CODE_L3Q -}; -const uint8_t ssr_sig_gal[32]={ - CODE_L1A,CODE_L1B,CODE_L1C, 0, 0,CODE_L5I,CODE_L5Q, 0, - CODE_L7I,CODE_L7Q, 0,CODE_L8I,CODE_L8Q, 0,CODE_L6A,CODE_L6B, - CODE_L6C -}; -const uint8_t ssr_sig_qzs[32]={ - CODE_L1C,CODE_L1S,CODE_L1L,CODE_L2S,CODE_L2L, 0,CODE_L5I,CODE_L5Q, - 0,CODE_L6S,CODE_L6L, 0, 0, 0, 0, 0, - 0,CODE_L6E -}; -const uint8_t ssr_sig_cmp[32]={ - CODE_L2I,CODE_L2Q, 0,CODE_L6I,CODE_L6Q, 0,CODE_L7I,CODE_L7Q, - 0,CODE_L1D,CODE_L1P, 0,CODE_L5D,CODE_L5P, 0,CODE_L1A, - 0, 0,CODE_L6A -}; -const uint8_t ssr_sig_sbs[32]={ - CODE_L1C,CODE_L5I,CODE_L5Q -}; +const uint8_t ssr_sig_gps[32] = {CODE_L1C, CODE_L1P, CODE_L1W, CODE_L1S, CODE_L1L, CODE_L2C, + CODE_L2D, CODE_L2S, CODE_L2L, CODE_L2X, CODE_L2P, CODE_L2W, + 0, 0, CODE_L5I, CODE_L5Q}; +const uint8_t ssr_sig_glo[32] = {CODE_L1C, CODE_L1P, CODE_L2C, CODE_L2P, CODE_L4A, + CODE_L4B, CODE_L6A, CODE_L6B, CODE_L3I, CODE_L3Q}; +const uint8_t ssr_sig_gal[32] = {CODE_L1A, CODE_L1B, CODE_L1C, 0, 0, CODE_L5I, + CODE_L5Q, 0, CODE_L7I, CODE_L7Q, 0, CODE_L8I, + CODE_L8Q, 0, CODE_L6A, CODE_L6B, CODE_L6C}; +const uint8_t ssr_sig_qzs[32] = {CODE_L1C, CODE_L1S, CODE_L1L, CODE_L2S, CODE_L2L, 0, + CODE_L5I, CODE_L5Q, 0, CODE_L6S, CODE_L6L, 0, + 0, 0, 0, 0, 0, CODE_L6E}; +const uint8_t ssr_sig_cmp[32] = { + CODE_L2I, CODE_L2Q, 0, CODE_L6I, CODE_L6Q, 0, CODE_L7I, CODE_L7Q, 0, CODE_L1D, CODE_L1P, + 0, CODE_L5D, CODE_L5P, 0, CODE_L1A, 0, 0, CODE_L6A}; +const uint8_t ssr_sig_sbs[32] = {CODE_L1C, CODE_L5I, CODE_L5Q}; /* SSR update intervals ------------------------------------------------------*/ -static const double ssrudint[16]={ - 1,2,5,10,15,30,60,120,240,300,600,900,1800,3600,7200,10800 -}; +static const double ssrudint[16] = {1, 2, 5, 10, 15, 30, 60, 120, + 240, 300, 600, 900, 1800, 3600, 7200, 10800}; /* get sign-magnitude bits ---------------------------------------------------*/ -static double getbitg(const uint8_t *buff, int pos, int len) -{ - double value=getbitu(buff,pos+1,len-1); - return getbitu(buff,pos,1)?-value:value; +static double getbitg(const uint8_t *buff, int pos, int len) { + double value = getbitu(buff, pos + 1, len - 1); + return getbitu(buff, pos, 1) ? -value : value; } /* adjust weekly rollover of GPS time ----------------------------------------*/ -static void adjweek(rtcm_t *rtcm, double tow) -{ - double tow_p; - int week; - - /* if no time, get cpu time */ - if (rtcm->time.time==0) rtcm->time=utc2gpst(timeget()); - tow_p=time2gpst(rtcm->time,&week); - if (towtow_p+302400.0) tow-=604800.0; - rtcm->time=gpst2time(week,tow); +static void adjweek(rtcm_t *rtcm, double tow) { + double tow_p; + int week; + + /* if no time, get cpu time */ + if (rtcm->time.time == 0) rtcm->time = utc2gpst(timeget()); + tow_p = time2gpst(rtcm->time, &week); + if (tow < tow_p - 302400.0) + tow += 604800.0; + else if (tow > tow_p + 302400.0) + tow -= 604800.0; + rtcm->time = gpst2time(week, tow); } /* adjust weekly rollover of BDS time ----------------------------------------*/ -static int adjbdtweek(int week) -{ - int w; - (void)time2bdt(gpst2bdt(utc2gpst(timeget())),&w); - if (w<1) w=1; /* use 2006/1/1 if time is earlier than 2006/1/1 */ - return week+(w-week+4095)/8192*8192; +static int adjbdtweek(int week) { + int w; + (void)time2bdt(gpst2bdt(utc2gpst(timeget())), &w); + if (w < 1) w = 1; /* use 2006/1/1 if time is earlier than 2006/1/1 */ + return week + (w - week + 4095) / 8192 * 8192; } /* adjust daily rollover of GLONASS time -------------------------------------*/ -static void adjday_glot(rtcm_t *rtcm, double tod) -{ - gtime_t time; - double tow,tod_p; - int week; - - if (rtcm->time.time==0) rtcm->time=utc2gpst(timeget()); - time=timeadd(gpst2utc(rtcm->time),10800.0); /* glonass time */ - tow=time2gpst(time,&week); - tod_p=fmod(tow,86400.0); tow-=tod_p; - if (todtod_p+43200.0) tod-=86400.0; - time=gpst2time(week,tow+tod); - rtcm->time=utc2gpst(timeadd(time,-10800.0)); +static void adjday_glot(rtcm_t *rtcm, double tod) { + gtime_t time; + double tow, tod_p; + int week; + + if (rtcm->time.time == 0) rtcm->time = utc2gpst(timeget()); + time = timeadd(gpst2utc(rtcm->time), 10800.0); /* glonass time */ + tow = time2gpst(time, &week); + tod_p = fmod(tow, 86400.0); + tow -= tod_p; + if (tod < tod_p - 43200.0) + tod += 86400.0; + else if (tod > tod_p + 43200.0) + tod -= 86400.0; + time = gpst2time(week, tow + tod); + rtcm->time = utc2gpst(timeadd(time, -10800.0)); } /* adjust carrier-phase rollover ---------------------------------------------*/ -static double adjcp(rtcm_t *rtcm, int sat, int idx, double cp) -{ - if (rtcm->cp[sat-1][idx]==0.0) ; - else if (cpcp[sat-1][idx]-750.0) cp+=1500.0; - else if (cp>rtcm->cp[sat-1][idx]+750.0) cp-=1500.0; - rtcm->cp[sat-1][idx]=cp; - return cp; +static double adjcp(rtcm_t *rtcm, int sat, int idx, double cp) { + if (rtcm->cp[sat - 1][idx] == 0.0) + ; + else if (cp < rtcm->cp[sat - 1][idx] - 750.0) + cp += 1500.0; + else if (cp > rtcm->cp[sat - 1][idx] + 750.0) + cp -= 1500.0; + rtcm->cp[sat - 1][idx] = cp; + return cp; } /* loss-of-lock indicator ----------------------------------------------------*/ -static int lossoflock(rtcm_t *rtcm, int sat, int idx, int lock) -{ - int lli=(!lock&&!rtcm->lock[sat-1][idx])||locklock[sat-1][idx]; - rtcm->lock[sat-1][idx]=(uint16_t)lock; - return lli; +static int lossoflock(rtcm_t *rtcm, int sat, int idx, int lock) { + int lli = (!lock && !rtcm->lock[sat - 1][idx]) || lock < rtcm->lock[sat - 1][idx]; + rtcm->lock[sat - 1][idx] = (uint16_t)lock; + return lli; } /* S/N ratio -----------------------------------------------------------------*/ -static double snratio(double snr) -{ - return snr<=0.0||100.0<=snr?0.0:snr; -} +static double snratio(double snr) { return snr <= 0.0 || 100.0 <= snr ? 0.0 : snr; } /* get observation data index ------------------------------------------------*/ -static int obsindex(obs_t *obs, gtime_t time, int sat) -{ - int i,j; - - for (i=0;in;i++) { - if (obs->data[i].sat==sat) return i; /* field already exists */ - } - if (i>=MAXOBS) return -1; /* overflow */ - - /* add new field */ - obs->data[i].time=time; - obs->data[i].sat=sat; - for (j=0;jdata[i].L[j]=obs->data[i].P[j]=0.0; - obs->data[i].D[j]=0.0; - obs->data[i].SNR[j]=obs->data[i].LLI[j]=obs->data[i].code[j]=0; - } - obs->n++; - return i; +static int obsindex(obs_t *obs, gtime_t time, int sat) { + int i, j; + + for (i = 0; i < obs->n; i++) { + if (obs->data[i].sat == sat) return i; /* field already exists */ + } + if (i >= MAXOBS) return -1; /* overflow */ + + /* add new field */ + obs->data[i].time = time; + obs->data[i].sat = sat; + for (j = 0; j < NFREQ + NEXOBS; j++) { + obs->data[i].L[j] = obs->data[i].P[j] = 0.0; + obs->data[i].D[j] = 0.0; + obs->data[i].SNR[j] = obs->data[i].LLI[j] = obs->data[i].code[j] = 0; + } + obs->n++; + return i; } /* test station ID consistency -----------------------------------------------*/ -static int test_staid(rtcm_t *rtcm, int staid) -{ - char *p; - int type,id; - - /* test station id option */ - if ((p=strstr(rtcm->opt,"-STA="))&&sscanf(p,"-STA=%d",&id)==1) { - if (staid!=id) return 0; - } - /* save station id */ - if (rtcm->staid==0||rtcm->obsflag) { - rtcm->staid=staid; - } - else if (staid!=rtcm->staid) { - type=getbitu(rtcm->buff,24,12); - trace(2,"rtcm3 %d staid invalid id=%d %d\n",type,staid,rtcm->staid); - - /* reset station id if station id error */ - rtcm->staid=0; - return 0; - } - return 1; +static int test_staid(rtcm_t *rtcm, int staid) { + char *p; + int type, id; + + /* test station id option */ + if ((p = strstr(rtcm->opt, "-STA=")) && sscanf(p, "-STA=%d", &id) == 1) { + if (staid != id) return 0; + } + /* save station id */ + if (rtcm->staid == 0 || rtcm->obsflag) { + rtcm->staid = staid; + } else if (staid != rtcm->staid) { + type = getbitu(rtcm->buff, 24, 12); + trace(2, "rtcm3 %d staid invalid id=%d %d\n", type, staid, rtcm->staid); + + /* reset station id if station id error */ + rtcm->staid = 0; + return 0; + } + return 1; } /* decode type 1001-1004 message header --------------------------------------*/ -static int decode_head1001(rtcm_t *rtcm, int *sync) -{ - double tow; - char *msg,tstr[40]; - int i=24,staid,nsat,type; - - if (rtcm->obsflag) rtcm->obs.n = rtcm->obsflag = 0; - - type=getbitu(rtcm->buff,i,12); i+=12; - - if (i+52<=rtcm->len*8) { - staid=getbitu(rtcm->buff,i,12); i+=12; - tow =getbitu(rtcm->buff,i,30)*0.001; i+=30; - *sync=getbitu(rtcm->buff,i, 1); i+= 1; - nsat =getbitu(rtcm->buff,i, 5); - } - else { - trace(2,"rtcm3 %d length error: len=%d\n",type,rtcm->len); - return -1; - } - /* test station ID */ - if (!test_staid(rtcm,staid)) return -1; - - adjweek(rtcm,tow); - - time2str(rtcm->time,tstr,2); - trace(4,"decode_head1001: time=%s nsat=%d sync=%d\n",tstr,nsat,*sync); - - if (rtcm->outtype) { - msg=rtcm->msgtype+strlen(rtcm->msgtype); - sprintf(msg," staid=%4d %s nsat=%2d sync=%d",staid,tstr,nsat,*sync); - } - return nsat; +static int decode_head1001(rtcm_t *rtcm, int *sync) { + double tow; + char *msg, tstr[40]; + int i = 24, staid, nsat, type; + + if (rtcm->obsflag) rtcm->obs.n = rtcm->obsflag = 0; + + type = getbitu(rtcm->buff, i, 12); + i += 12; + + if (i + 52 <= rtcm->len * 8) { + staid = getbitu(rtcm->buff, i, 12); + i += 12; + tow = getbitu(rtcm->buff, i, 30) * 0.001; + i += 30; + *sync = getbitu(rtcm->buff, i, 1); + i += 1; + nsat = getbitu(rtcm->buff, i, 5); + } else { + trace(2, "rtcm3 %d length error: len=%d\n", type, rtcm->len); + return -1; + } + /* test station ID */ + if (!test_staid(rtcm, staid)) return -1; + + adjweek(rtcm, tow); + + time2str(rtcm->time, tstr, 2); + trace(4, "decode_head1001: time=%s nsat=%d sync=%d\n", tstr, nsat, *sync); + + if (rtcm->outtype) { + msg = rtcm->msgtype + strlen(rtcm->msgtype); + sprintf(msg, " staid=%4d %s nsat=%2d sync=%d", staid, tstr, nsat, *sync); + } + return nsat; } /* decode type 1001: L1-only GPS RTK observation -----------------------------*/ -static int decode_type1001(rtcm_t *rtcm) -{ - int sync; - if (decode_head1001(rtcm,&sync)<0) return -1; - rtcm->obsflag=!sync; - return sync?0:1; +static int decode_type1001(rtcm_t *rtcm) { + int sync; + if (decode_head1001(rtcm, &sync) < 0) return -1; + rtcm->obsflag = !sync; + return sync ? 0 : 1; } /* decode type 1002: extended L1-only GPS RTK observables --------------------*/ -static int decode_type1002(rtcm_t *rtcm) -{ - double pr1,cnr1,tt,cp1,freq=FREQL1; - int i=24+64,j,index,nsat,sync,prn,code,sat,ppr1,lock1,amb,sys; - - if ((nsat=decode_head1001(rtcm,&sync))<0) return -1; - - for (j=0;jlen*8;j++) { - prn =getbitu(rtcm->buff,i, 6); i+= 6; - code =getbitu(rtcm->buff,i, 1); i+= 1; - pr1 =getbitu(rtcm->buff,i,24); i+=24; - ppr1 =getbits(rtcm->buff,i,20); i+=20; - lock1=getbitu(rtcm->buff,i, 7); i+= 7; - amb =getbitu(rtcm->buff,i, 8); i+= 8; - cnr1 =getbitu(rtcm->buff,i, 8); i+= 8; - if (prn<40) { - sys=SYS_GPS; - } - else { - sys=SYS_SBS; prn+=80; - } - if (!(sat=satno(sys,prn))) { - trace(2,"rtcm3 1002 satellite number error: prn=%d\n",prn); - continue; - } - tt=timediff(rtcm->obs.data[0].time,rtcm->time); - if (fabs(tt)>1E-9) rtcm->obs.n=rtcm->obsflag=0; - if ((index=obsindex(&rtcm->obs,rtcm->time,sat))<0) continue; - pr1=pr1*0.02+amb*PRUNIT_GPS; - rtcm->obs.data[index].P[0]=pr1; - - if (ppr1!=(int)0xFFF80000) { - cp1=adjcp(rtcm,sat,0,ppr1*0.0005*freq/CLIGHT); - rtcm->obs.data[index].L[0]=pr1*freq/CLIGHT+cp1; - } - rtcm->obs.data[index].LLI[0]=lossoflock(rtcm,sat,0,lock1); - rtcm->obs.data[index].SNR[0]=snratio(cnr1*0.25); - rtcm->obs.data[index].code[0]=code?CODE_L1P:CODE_L1C; +static int decode_type1002(rtcm_t *rtcm) { + double pr1, cnr1, tt, cp1, freq = FREQL1; + int i = 24 + 64, j, index, nsat, sync, prn, code, sat, ppr1, lock1, amb, sys; + + if ((nsat = decode_head1001(rtcm, &sync)) < 0) return -1; + + for (j = 0; j < nsat && i + 74 <= rtcm->len * 8; j++) { + prn = getbitu(rtcm->buff, i, 6); + i += 6; + code = getbitu(rtcm->buff, i, 1); + i += 1; + pr1 = getbitu(rtcm->buff, i, 24); + i += 24; + ppr1 = getbits(rtcm->buff, i, 20); + i += 20; + lock1 = getbitu(rtcm->buff, i, 7); + i += 7; + amb = getbitu(rtcm->buff, i, 8); + i += 8; + cnr1 = getbitu(rtcm->buff, i, 8); + i += 8; + if (prn < 40) { + sys = SYS_GPS; + } else { + sys = SYS_SBS; + prn += 80; + } + if (!(sat = satno(sys, prn))) { + trace(2, "rtcm3 1002 satellite number error: prn=%d\n", prn); + continue; + } + tt = timediff(rtcm->obs.data[0].time, rtcm->time); + if (fabs(tt) > 1E-9) rtcm->obs.n = rtcm->obsflag = 0; + if ((index = obsindex(&rtcm->obs, rtcm->time, sat)) < 0) continue; + pr1 = pr1 * 0.02 + amb * PRUNIT_GPS; + rtcm->obs.data[index].P[0] = pr1; + + if (ppr1 != (int)0xFFF80000) { + cp1 = adjcp(rtcm, sat, 0, ppr1 * 0.0005 * freq / CLIGHT); + rtcm->obs.data[index].L[0] = pr1 * freq / CLIGHT + cp1; } - return sync?0:1; + rtcm->obs.data[index].LLI[0] = lossoflock(rtcm, sat, 0, lock1); + rtcm->obs.data[index].SNR[0] = snratio(cnr1 * 0.25); + rtcm->obs.data[index].code[0] = code ? CODE_L1P : CODE_L1C; + } + return sync ? 0 : 1; } /* decode type 1003: L1&L2 gps rtk observables -------------------------------*/ -static int decode_type1003(rtcm_t *rtcm) -{ - int sync; - if (decode_head1001(rtcm,&sync)<0) return -1; - rtcm->obsflag=!sync; - return sync?0:1; +static int decode_type1003(rtcm_t *rtcm) { + int sync; + if (decode_head1001(rtcm, &sync) < 0) return -1; + rtcm->obsflag = !sync; + return sync ? 0 : 1; } /* decode type 1004: extended L1&L2 GPS RTK observables ----------------------*/ -static int decode_type1004(rtcm_t *rtcm) -{ - const int L2codes[]={CODE_L2X,CODE_L2P,CODE_L2D,CODE_L2W}; - double pr1,cnr1,cnr2,tt,cp1,cp2,freq[2]={FREQL1,FREQL2}; - int i=24+64,j,index,nsat,sync,prn,sat,code1,code2,pr21,ppr1,ppr2; - int lock1,lock2,amb,sys; - - if ((nsat=decode_head1001(rtcm,&sync))<0) return -1; - - for (j=0;jlen*8;j++) { - prn =getbitu(rtcm->buff,i, 6); i+= 6; - code1=getbitu(rtcm->buff,i, 1); i+= 1; - pr1 =getbitu(rtcm->buff,i,24); i+=24; - ppr1 =getbits(rtcm->buff,i,20); i+=20; - lock1=getbitu(rtcm->buff,i, 7); i+= 7; - amb =getbitu(rtcm->buff,i, 8); i+= 8; - cnr1 =getbitu(rtcm->buff,i, 8); i+= 8; - code2=getbitu(rtcm->buff,i, 2); i+= 2; - pr21 =getbits(rtcm->buff,i,14); i+=14; - ppr2 =getbits(rtcm->buff,i,20); i+=20; - lock2=getbitu(rtcm->buff,i, 7); i+= 7; - cnr2 =getbitu(rtcm->buff,i, 8); i+= 8; - if (prn<40) { - sys=SYS_GPS; - } - else { - sys=SYS_SBS; prn+=80; - } - if (!(sat=satno(sys,prn))) { - trace(2,"rtcm3 1004 satellite number error: sys=%d prn=%d\n",sys,prn); - continue; - } - tt=timediff(rtcm->obs.data[0].time,rtcm->time); - if (fabs(tt)>1E-9) rtcm->obs.n=rtcm->obsflag=0; - if ((index=obsindex(&rtcm->obs,rtcm->time,sat))<0) continue; - pr1=pr1*0.02+amb*PRUNIT_GPS; - rtcm->obs.data[index].P[0]=pr1; - - if (ppr1!=(int)0xFFF80000) { - cp1=adjcp(rtcm,sat,0,ppr1*0.0005*freq[0]/CLIGHT); - rtcm->obs.data[index].L[0]=pr1*freq[0]/CLIGHT+cp1; - } - rtcm->obs.data[index].LLI[0]=lossoflock(rtcm,sat,0,lock1); - rtcm->obs.data[index].SNR[0]=snratio(cnr1*0.25); - rtcm->obs.data[index].code[0]=code1?CODE_L1P:CODE_L1C; - - if (pr21!=(int)0xFFFFE000) { - rtcm->obs.data[index].P[1]=pr1+pr21*0.02; - } - if (ppr2!=(int)0xFFF80000) { - cp2=adjcp(rtcm,sat,1,ppr2*0.0005*freq[1]/CLIGHT); - rtcm->obs.data[index].L[1]=pr1*freq[1]/CLIGHT+cp2; - } - rtcm->obs.data[index].LLI[1]=lossoflock(rtcm,sat,1,lock2); - rtcm->obs.data[index].SNR[1]=snratio(cnr2*0.25); - rtcm->obs.data[index].code[1]=L2codes[code2]; +static int decode_type1004(rtcm_t *rtcm) { + const int L2codes[] = {CODE_L2X, CODE_L2P, CODE_L2D, CODE_L2W}; + double pr1, cnr1, cnr2, tt, cp1, cp2, freq[2] = {FREQL1, FREQL2}; + int i = 24 + 64, j, index, nsat, sync, prn, sat, code1, code2, pr21, ppr1, ppr2; + int lock1, lock2, amb, sys; + + if ((nsat = decode_head1001(rtcm, &sync)) < 0) return -1; + + for (j = 0; j < nsat && i + 125 <= rtcm->len * 8; j++) { + prn = getbitu(rtcm->buff, i, 6); + i += 6; + code1 = getbitu(rtcm->buff, i, 1); + i += 1; + pr1 = getbitu(rtcm->buff, i, 24); + i += 24; + ppr1 = getbits(rtcm->buff, i, 20); + i += 20; + lock1 = getbitu(rtcm->buff, i, 7); + i += 7; + amb = getbitu(rtcm->buff, i, 8); + i += 8; + cnr1 = getbitu(rtcm->buff, i, 8); + i += 8; + code2 = getbitu(rtcm->buff, i, 2); + i += 2; + pr21 = getbits(rtcm->buff, i, 14); + i += 14; + ppr2 = getbits(rtcm->buff, i, 20); + i += 20; + lock2 = getbitu(rtcm->buff, i, 7); + i += 7; + cnr2 = getbitu(rtcm->buff, i, 8); + i += 8; + if (prn < 40) { + sys = SYS_GPS; + } else { + sys = SYS_SBS; + prn += 80; + } + if (!(sat = satno(sys, prn))) { + trace(2, "rtcm3 1004 satellite number error: sys=%d prn=%d\n", sys, prn); + continue; + } + tt = timediff(rtcm->obs.data[0].time, rtcm->time); + if (fabs(tt) > 1E-9) rtcm->obs.n = rtcm->obsflag = 0; + if ((index = obsindex(&rtcm->obs, rtcm->time, sat)) < 0) continue; + pr1 = pr1 * 0.02 + amb * PRUNIT_GPS; + rtcm->obs.data[index].P[0] = pr1; + + if (ppr1 != (int)0xFFF80000) { + cp1 = adjcp(rtcm, sat, 0, ppr1 * 0.0005 * freq[0] / CLIGHT); + rtcm->obs.data[index].L[0] = pr1 * freq[0] / CLIGHT + cp1; } - rtcm->obsflag=!sync; - return sync?0:1; + rtcm->obs.data[index].LLI[0] = lossoflock(rtcm, sat, 0, lock1); + rtcm->obs.data[index].SNR[0] = snratio(cnr1 * 0.25); + rtcm->obs.data[index].code[0] = code1 ? CODE_L1P : CODE_L1C; + + if (pr21 != (int)0xFFFFE000) { + rtcm->obs.data[index].P[1] = pr1 + pr21 * 0.02; + } + if (ppr2 != (int)0xFFF80000) { + cp2 = adjcp(rtcm, sat, 1, ppr2 * 0.0005 * freq[1] / CLIGHT); + rtcm->obs.data[index].L[1] = pr1 * freq[1] / CLIGHT + cp2; + } + rtcm->obs.data[index].LLI[1] = lossoflock(rtcm, sat, 1, lock2); + rtcm->obs.data[index].SNR[1] = snratio(cnr2 * 0.25); + rtcm->obs.data[index].code[1] = L2codes[code2]; + } + rtcm->obsflag = !sync; + return sync ? 0 : 1; } /* get signed 38bit field ----------------------------------------------------*/ -static double getbits_38(const uint8_t *buff, int pos) -{ - return (double)getbits(buff,pos,32)*64.0+getbitu(buff,pos+32,6); +static double getbits_38(const uint8_t *buff, int pos) { + return (double)getbits(buff, pos, 32) * 64.0 + getbitu(buff, pos + 32, 6); } /* decode type 1005: stationary RTK reference station ARP --------------------*/ -static int decode_type1005(rtcm_t *rtcm) -{ - double rr[3],re[3],pos[3]; - char *msg; - int i=24+12,j,staid,itrf; - - if (i+140==rtcm->len*8) { - staid=getbitu(rtcm->buff,i,12); i+=12; - itrf =getbitu(rtcm->buff,i, 6); i+= 6+4; - rr[0]=getbits_38(rtcm->buff,i); i+=38+2; - rr[1]=getbits_38(rtcm->buff,i); i+=38+2; - rr[2]=getbits_38(rtcm->buff,i); - } - else { - trace(2,"rtcm3 1005 length error: len=%d\n",rtcm->len); - return -1; - } - if (rtcm->outtype) { - msg=rtcm->msgtype+strlen(rtcm->msgtype); - for (j=0;j<3;j++) re[j]=rr[j]*0.0001; - ecef2pos(re,pos); - sprintf(msg," staid=%4d pos=%.8f %.8f %.3f",staid,pos[0]*R2D,pos[1]*R2D, - pos[2]); - } - /* test station id */ - if (!test_staid(rtcm,staid)) return -1; - - sprintf(rtcm->sta.name,"%04d",staid); - rtcm->sta.deltype=0; /* xyz */ - for (j=0;j<3;j++) { - rtcm->sta.pos[j]=rr[j]*0.0001; - rtcm->sta.del[j]=0.0; - } - rtcm->sta.hgt=0.0; - rtcm->sta.itrf=itrf; - return 5; +static int decode_type1005(rtcm_t *rtcm) { + double rr[3], re[3], pos[3]; + char *msg; + int i = 24 + 12, j, staid, itrf; + + if (i + 140 == rtcm->len * 8) { + staid = getbitu(rtcm->buff, i, 12); + i += 12; + itrf = getbitu(rtcm->buff, i, 6); + i += 6 + 4; + rr[0] = getbits_38(rtcm->buff, i); + i += 38 + 2; + rr[1] = getbits_38(rtcm->buff, i); + i += 38 + 2; + rr[2] = getbits_38(rtcm->buff, i); + } else { + trace(2, "rtcm3 1005 length error: len=%d\n", rtcm->len); + return -1; + } + if (rtcm->outtype) { + msg = rtcm->msgtype + strlen(rtcm->msgtype); + for (j = 0; j < 3; j++) re[j] = rr[j] * 0.0001; + ecef2pos(re, pos); + sprintf(msg, " staid=%4d pos=%.8f %.8f %.3f", staid, pos[0] * R2D, pos[1] * R2D, pos[2]); + } + /* test station id */ + if (!test_staid(rtcm, staid)) return -1; + + sprintf(rtcm->sta.name, "%04d", staid); + rtcm->sta.deltype = 0; /* xyz */ + for (j = 0; j < 3; j++) { + rtcm->sta.pos[j] = rr[j] * 0.0001; + rtcm->sta.del[j] = 0.0; + } + rtcm->sta.hgt = 0.0; + rtcm->sta.itrf = itrf; + return 5; } /* decode type 1006: stationary RTK reference station ARP with height --------*/ -static int decode_type1006(rtcm_t *rtcm) -{ - double rr[3],re[3],pos[3],anth; - char *msg; - int i=24+12,j,staid,itrf; - - if (i+156<=rtcm->len*8) { - staid=getbitu(rtcm->buff,i,12); i+=12; - itrf =getbitu(rtcm->buff,i, 6); i+= 6+4; - rr[0]=getbits_38(rtcm->buff,i); i+=38+2; - rr[1]=getbits_38(rtcm->buff,i); i+=38+2; - rr[2]=getbits_38(rtcm->buff,i); i+=38; - anth =getbitu(rtcm->buff,i,16); - } - else { - trace(2,"rtcm3 1006 length error: len=%d\n",rtcm->len); - return -1; - } - if (rtcm->outtype) { - msg=rtcm->msgtype+strlen(rtcm->msgtype); - for (j=0;j<3;j++) re[j]=rr[j]*0.0001; - ecef2pos(re,pos); - sprintf(msg," staid=%4d pos=%.8f %.8f %.3f anth=%.3f",staid,pos[0]*R2D, - pos[1]*R2D,pos[2],anth*0.0001); - } - /* test station id */ - if (!test_staid(rtcm,staid)) return -1; - - sprintf(rtcm->sta.name,"%04d",staid); - rtcm->sta.deltype=1; /* xyz */ - for (j=0;j<3;j++) { - rtcm->sta.pos[j]=rr[j]*0.0001; - rtcm->sta.del[j]=0.0; - } - rtcm->sta.hgt=anth*0.0001; - rtcm->sta.itrf=itrf; - return 5; +static int decode_type1006(rtcm_t *rtcm) { + double rr[3], re[3], pos[3], anth; + char *msg; + int i = 24 + 12, j, staid, itrf; + + if (i + 156 <= rtcm->len * 8) { + staid = getbitu(rtcm->buff, i, 12); + i += 12; + itrf = getbitu(rtcm->buff, i, 6); + i += 6 + 4; + rr[0] = getbits_38(rtcm->buff, i); + i += 38 + 2; + rr[1] = getbits_38(rtcm->buff, i); + i += 38 + 2; + rr[2] = getbits_38(rtcm->buff, i); + i += 38; + anth = getbitu(rtcm->buff, i, 16); + } else { + trace(2, "rtcm3 1006 length error: len=%d\n", rtcm->len); + return -1; + } + if (rtcm->outtype) { + msg = rtcm->msgtype + strlen(rtcm->msgtype); + for (j = 0; j < 3; j++) re[j] = rr[j] * 0.0001; + ecef2pos(re, pos); + sprintf(msg, " staid=%4d pos=%.8f %.8f %.3f anth=%.3f", staid, pos[0] * R2D, pos[1] * R2D, + pos[2], anth * 0.0001); + } + /* test station id */ + if (!test_staid(rtcm, staid)) return -1; + + sprintf(rtcm->sta.name, "%04d", staid); + rtcm->sta.deltype = 1; /* xyz */ + for (j = 0; j < 3; j++) { + rtcm->sta.pos[j] = rr[j] * 0.0001; + rtcm->sta.del[j] = 0.0; + } + rtcm->sta.hgt = anth * 0.0001; + rtcm->sta.itrf = itrf; + return 5; } /* decode type 1007: antenna descriptor --------------------------------------*/ -static int decode_type1007(rtcm_t *rtcm) -{ - char des[32]=""; - char *msg; - int i=24+12,j,staid,n,setup; - - n=getbitu(rtcm->buff,i+12,8); - - if (i+28+8*n<=rtcm->len*8) { - staid=getbitu(rtcm->buff,i,12); i+=12+8; - for (j=0;jbuff,i,8); i+=8; - } - setup=getbitu(rtcm->buff,i, 8); - } - else { - trace(2,"rtcm3 1007 length error: len=%d\n",rtcm->len); - return -1; - } - if (rtcm->outtype) { - msg=rtcm->msgtype+strlen(rtcm->msgtype); - sprintf(msg," staid=%4d",staid); - } - /* test station ID */ - if (!test_staid(rtcm,staid)) return -1; - - sprintf(rtcm->sta.name,"%04d",staid); - strncpy(rtcm->sta.antdes,des,n); rtcm->sta.antdes[n]='\0'; - rtcm->sta.antsetup=setup; - rtcm->sta.antsno[0]='\0'; - return 5; +static int decode_type1007(rtcm_t *rtcm) { + char des[32] = ""; + char *msg; + int i = 24 + 12, j, staid, n, setup; + + n = getbitu(rtcm->buff, i + 12, 8); + + if (i + 28 + 8 * n <= rtcm->len * 8) { + staid = getbitu(rtcm->buff, i, 12); + i += 12 + 8; + for (j = 0; j < n && j < 31; j++) { + des[j] = (char)getbitu(rtcm->buff, i, 8); + i += 8; + } + setup = getbitu(rtcm->buff, i, 8); + } else { + trace(2, "rtcm3 1007 length error: len=%d\n", rtcm->len); + return -1; + } + if (rtcm->outtype) { + msg = rtcm->msgtype + strlen(rtcm->msgtype); + sprintf(msg, " staid=%4d", staid); + } + /* test station ID */ + if (!test_staid(rtcm, staid)) return -1; + + sprintf(rtcm->sta.name, "%04d", staid); + strncpy(rtcm->sta.antdes, des, n); + rtcm->sta.antdes[n] = '\0'; + rtcm->sta.antsetup = setup; + rtcm->sta.antsno[0] = '\0'; + return 5; } /* decode type 1008: antenna descriptor & serial number ----------------------*/ -static int decode_type1008(rtcm_t *rtcm) -{ - char des[32]="",sno[32]=""; - char *msg; - int i=24+12,j,staid,n,m,setup; - - n=getbitu(rtcm->buff,i+12,8); - m=getbitu(rtcm->buff,i+28+8*n,8); - - if (i+36+8*(n+m)<=rtcm->len*8) { - staid=getbitu(rtcm->buff,i,12); i+=12+8; - for (j=0;jbuff,i,8); i+=8; - } - setup=getbitu(rtcm->buff,i, 8); i+=8+8; - for (j=0;jbuff,i,8); i+=8; - } - } - else { - trace(2,"rtcm3 1008 length error: len=%d\n",rtcm->len); - return -1; - } - if (rtcm->outtype) { - msg=rtcm->msgtype+strlen(rtcm->msgtype); - sprintf(msg," staid=%4d",staid); - } - /* test station ID */ - if (!test_staid(rtcm,staid)) return -1; - - sprintf(rtcm->sta.name,"%04d",staid); - strncpy(rtcm->sta.antdes,des,n); rtcm->sta.antdes[n]='\0'; - rtcm->sta.antsetup=setup; - strncpy(rtcm->sta.antsno,sno,m); rtcm->sta.antsno[m]='\0'; - return 5; +static int decode_type1008(rtcm_t *rtcm) { + char des[32] = "", sno[32] = ""; + char *msg; + int i = 24 + 12, j, staid, n, m, setup; + + n = getbitu(rtcm->buff, i + 12, 8); + m = getbitu(rtcm->buff, i + 28 + 8 * n, 8); + + if (i + 36 + 8 * (n + m) <= rtcm->len * 8) { + staid = getbitu(rtcm->buff, i, 12); + i += 12 + 8; + for (j = 0; j < n && j < 31; j++) { + des[j] = (char)getbitu(rtcm->buff, i, 8); + i += 8; + } + setup = getbitu(rtcm->buff, i, 8); + i += 8 + 8; + for (j = 0; j < m && j < 31; j++) { + sno[j] = (char)getbitu(rtcm->buff, i, 8); + i += 8; + } + } else { + trace(2, "rtcm3 1008 length error: len=%d\n", rtcm->len); + return -1; + } + if (rtcm->outtype) { + msg = rtcm->msgtype + strlen(rtcm->msgtype); + sprintf(msg, " staid=%4d", staid); + } + /* test station ID */ + if (!test_staid(rtcm, staid)) return -1; + + sprintf(rtcm->sta.name, "%04d", staid); + strncpy(rtcm->sta.antdes, des, n); + rtcm->sta.antdes[n] = '\0'; + rtcm->sta.antsetup = setup; + strncpy(rtcm->sta.antsno, sno, m); + rtcm->sta.antsno[m] = '\0'; + return 5; } /* decode type 1009-1012 message header --------------------------------------*/ -static int decode_head1009(rtcm_t *rtcm, int *sync) -{ - double tod; - char *msg,tstr[40]; - int i=24,staid,nsat,type; - - if (rtcm->obsflag) rtcm->obs.n = rtcm->obsflag = 0; - - type=getbitu(rtcm->buff,i,12); i+=12; - - if (i+49<=rtcm->len*8) { - staid=getbitu(rtcm->buff,i,12); i+=12; - tod =getbitu(rtcm->buff,i,27)*0.001; i+=27; /* sec in a day */ - *sync=getbitu(rtcm->buff,i, 1); i+= 1; - nsat =getbitu(rtcm->buff,i, 5); - } - else { - trace(2,"rtcm3 %d length error: len=%d\n",type,rtcm->len); - return -1; - } - /* test station ID */ - if (!test_staid(rtcm,staid)) return -1; - - adjday_glot(rtcm,tod); - - time2str(rtcm->time,tstr,2); - trace(4,"decode_head1009: time=%s nsat=%d sync=%d\n",tstr,nsat,*sync); - - if (rtcm->outtype) { - msg=rtcm->msgtype+strlen(rtcm->msgtype); - sprintf(msg," staid=%4d %s nsat=%2d sync=%d",staid,tstr,nsat,*sync); - } - return nsat; +static int decode_head1009(rtcm_t *rtcm, int *sync) { + double tod; + char *msg, tstr[40]; + int i = 24, staid, nsat, type; + + if (rtcm->obsflag) rtcm->obs.n = rtcm->obsflag = 0; + + type = getbitu(rtcm->buff, i, 12); + i += 12; + + if (i + 49 <= rtcm->len * 8) { + staid = getbitu(rtcm->buff, i, 12); + i += 12; + tod = getbitu(rtcm->buff, i, 27) * 0.001; + i += 27; /* sec in a day */ + *sync = getbitu(rtcm->buff, i, 1); + i += 1; + nsat = getbitu(rtcm->buff, i, 5); + } else { + trace(2, "rtcm3 %d length error: len=%d\n", type, rtcm->len); + return -1; + } + /* test station ID */ + if (!test_staid(rtcm, staid)) return -1; + + adjday_glot(rtcm, tod); + + time2str(rtcm->time, tstr, 2); + trace(4, "decode_head1009: time=%s nsat=%d sync=%d\n", tstr, nsat, *sync); + + if (rtcm->outtype) { + msg = rtcm->msgtype + strlen(rtcm->msgtype); + sprintf(msg, " staid=%4d %s nsat=%2d sync=%d", staid, tstr, nsat, *sync); + } + return nsat; } /* decode type 1009: L1-only glonass rtk observables -------------------------*/ -static int decode_type1009(rtcm_t *rtcm) -{ - int sync; - if (decode_head1009(rtcm,&sync)<0) return -1; - rtcm->obsflag=!sync; - return sync?0:1; +static int decode_type1009(rtcm_t *rtcm) { + int sync; + if (decode_head1009(rtcm, &sync) < 0) return -1; + rtcm->obsflag = !sync; + return sync ? 0 : 1; } /* decode type 1010: extended L1-only glonass rtk observables ----------------*/ -static int decode_type1010(rtcm_t *rtcm) -{ - double pr1,cnr1,tt,cp1,freq1; - int i=24+61,j,index,nsat,sync,prn,sat,code,fcn,ppr1,lock1,amb,sys=SYS_GLO; - - if ((nsat=decode_head1009(rtcm,&sync))<0) return -1; - - for (j=0;jlen*8;j++) { - prn =getbitu(rtcm->buff,i, 6); i+= 6; - code =getbitu(rtcm->buff,i, 1); i+= 1; - fcn =getbitu(rtcm->buff,i, 5); i+= 5; /* fcn+7 */ - pr1 =getbitu(rtcm->buff,i,25); i+=25; - ppr1 =getbits(rtcm->buff,i,20); i+=20; - lock1=getbitu(rtcm->buff,i, 7); i+= 7; - amb =getbitu(rtcm->buff,i, 7); i+= 7; - cnr1 =getbitu(rtcm->buff,i, 8); i+= 8; - if (!(sat=satno(sys,prn))) { - trace(2,"rtcm3 1010 satellite number error: prn=%d\n",prn); - continue; - } - if (!rtcm->nav.glo_fcn[prn-1]) { - rtcm->nav.glo_fcn[prn-1]=fcn-7+8; /* fcn+8 */ - } - tt=timediff(rtcm->obs.data[0].time,rtcm->time); - if (fabs(tt)>1E-9) rtcm->obs.n=rtcm->obsflag=0; - if ((index=obsindex(&rtcm->obs,rtcm->time,sat))<0) continue; - pr1=pr1*0.02+amb*PRUNIT_GLO; - rtcm->obs.data[index].P[0]=pr1; - - if (ppr1!=(int)0xFFF80000) { - freq1=code2freq(SYS_GLO,CODE_L1C,fcn-7); - cp1=adjcp(rtcm,sat,0,ppr1*0.0005*freq1/CLIGHT); - rtcm->obs.data[index].L[0]=pr1*freq1/CLIGHT+cp1; - } - rtcm->obs.data[index].LLI[0]=lossoflock(rtcm,sat,0,lock1); - rtcm->obs.data[index].SNR[0]=snratio(cnr1*0.25); - rtcm->obs.data[index].code[0]=code?CODE_L1P:CODE_L1C; +static int decode_type1010(rtcm_t *rtcm) { + double pr1, cnr1, tt, cp1, freq1; + int i = 24 + 61, j, index, nsat, sync, prn, sat, code, fcn, ppr1, lock1, amb, sys = SYS_GLO; + + if ((nsat = decode_head1009(rtcm, &sync)) < 0) return -1; + + for (j = 0; j < nsat && i + 79 <= rtcm->len * 8; j++) { + prn = getbitu(rtcm->buff, i, 6); + i += 6; + code = getbitu(rtcm->buff, i, 1); + i += 1; + fcn = getbitu(rtcm->buff, i, 5); + i += 5; /* fcn+7 */ + pr1 = getbitu(rtcm->buff, i, 25); + i += 25; + ppr1 = getbits(rtcm->buff, i, 20); + i += 20; + lock1 = getbitu(rtcm->buff, i, 7); + i += 7; + amb = getbitu(rtcm->buff, i, 7); + i += 7; + cnr1 = getbitu(rtcm->buff, i, 8); + i += 8; + if (!(sat = satno(sys, prn))) { + trace(2, "rtcm3 1010 satellite number error: prn=%d\n", prn); + continue; + } + if (!rtcm->nav.glo_fcn[prn - 1]) { + rtcm->nav.glo_fcn[prn - 1] = fcn - 7 + 8; /* fcn+8 */ + } + tt = timediff(rtcm->obs.data[0].time, rtcm->time); + if (fabs(tt) > 1E-9) rtcm->obs.n = rtcm->obsflag = 0; + if ((index = obsindex(&rtcm->obs, rtcm->time, sat)) < 0) continue; + pr1 = pr1 * 0.02 + amb * PRUNIT_GLO; + rtcm->obs.data[index].P[0] = pr1; + + if (ppr1 != (int)0xFFF80000) { + freq1 = code2freq(SYS_GLO, CODE_L1C, fcn - 7); + cp1 = adjcp(rtcm, sat, 0, ppr1 * 0.0005 * freq1 / CLIGHT); + rtcm->obs.data[index].L[0] = pr1 * freq1 / CLIGHT + cp1; } - return sync?0:1; + rtcm->obs.data[index].LLI[0] = lossoflock(rtcm, sat, 0, lock1); + rtcm->obs.data[index].SNR[0] = snratio(cnr1 * 0.25); + rtcm->obs.data[index].code[0] = code ? CODE_L1P : CODE_L1C; + } + return sync ? 0 : 1; } /* decode type 1011: L1&L2 GLONASS RTK observables ---------------------------*/ -static int decode_type1011(rtcm_t *rtcm) -{ - int sync; - if (decode_head1009(rtcm,&sync)<0) return -1; - rtcm->obsflag=!sync; - return sync?0:1; +static int decode_type1011(rtcm_t *rtcm) { + int sync; + if (decode_head1009(rtcm, &sync) < 0) return -1; + rtcm->obsflag = !sync; + return sync ? 0 : 1; } /* decode type 1012: extended L1&L2 GLONASS RTK observables ------------------*/ -static int decode_type1012(rtcm_t *rtcm) -{ - double pr1,cnr1,cnr2,tt,cp1,cp2,freq1,freq2; - int i=24+61,j,index,nsat,sync,prn,sat,fcn,code1,code2,pr21,ppr1,ppr2; - int lock1,lock2,amb,sys=SYS_GLO; - - if ((nsat=decode_head1009(rtcm,&sync))<0) return -1; - - for (j=0;jlen*8;j++) { - prn =getbitu(rtcm->buff,i, 6); i+= 6; - code1=getbitu(rtcm->buff,i, 1); i+= 1; - fcn =getbitu(rtcm->buff,i, 5); i+= 5; /* fcn+7 */ - pr1 =getbitu(rtcm->buff,i,25); i+=25; - ppr1 =getbits(rtcm->buff,i,20); i+=20; - lock1=getbitu(rtcm->buff,i, 7); i+= 7; - amb =getbitu(rtcm->buff,i, 7); i+= 7; - cnr1 =getbitu(rtcm->buff,i, 8); i+= 8; - code2=getbitu(rtcm->buff,i, 2); i+= 2; - pr21 =getbits(rtcm->buff,i,14); i+=14; - ppr2 =getbits(rtcm->buff,i,20); i+=20; - lock2=getbitu(rtcm->buff,i, 7); i+= 7; - cnr2 =getbitu(rtcm->buff,i, 8); i+= 8; - if (!(sat=satno(sys,prn))) { - trace(2,"rtcm3 1012 satellite number error: sys=%d prn=%d\n",sys,prn); - continue; - } - if (!rtcm->nav.glo_fcn[prn-1]) { - rtcm->nav.glo_fcn[prn-1]=fcn-7+8; /* fcn+8 */ - } - tt=timediff(rtcm->obs.data[0].time,rtcm->time); - if (fabs(tt)>1E-9) rtcm->obs.n=rtcm->obsflag=0; - if ((index=obsindex(&rtcm->obs,rtcm->time,sat))<0) continue; - pr1=pr1*0.02+amb*PRUNIT_GLO; - rtcm->obs.data[index].P[0]=pr1; - - if (ppr1!=(int)0xFFF80000) { - freq1=code2freq(SYS_GLO,CODE_L1C,fcn-7); - cp1=adjcp(rtcm,sat,0,ppr1*0.0005*freq1/CLIGHT); - rtcm->obs.data[index].L[0]=pr1*freq1/CLIGHT+cp1; - } - rtcm->obs.data[index].LLI[0]=lossoflock(rtcm,sat,0,lock1); - rtcm->obs.data[index].SNR[0]=snratio(cnr1*0.25); - rtcm->obs.data[index].code[0]=code1?CODE_L1P:CODE_L1C; - - if (pr21!=(int)0xFFFFE000) { - rtcm->obs.data[index].P[1]=pr1+pr21*0.02; - } - if (ppr2!=(int)0xFFF80000) { - freq2=code2freq(SYS_GLO,CODE_L2C,fcn-7); - cp2=adjcp(rtcm,sat,1,ppr2*0.0005*freq2/CLIGHT); - rtcm->obs.data[index].L[1]=pr1*freq2/CLIGHT+cp2; - } - rtcm->obs.data[index].LLI[1]=lossoflock(rtcm,sat,1,lock2); - rtcm->obs.data[index].SNR[1]=snratio(cnr2*0.25); - rtcm->obs.data[index].code[1]=code2?CODE_L2P:CODE_L2C; +static int decode_type1012(rtcm_t *rtcm) { + double pr1, cnr1, cnr2, tt, cp1, cp2, freq1, freq2; + int i = 24 + 61, j, index, nsat, sync, prn, sat, fcn, code1, code2, pr21, ppr1, ppr2; + int lock1, lock2, amb, sys = SYS_GLO; + + if ((nsat = decode_head1009(rtcm, &sync)) < 0) return -1; + + for (j = 0; j < nsat && i + 130 <= rtcm->len * 8; j++) { + prn = getbitu(rtcm->buff, i, 6); + i += 6; + code1 = getbitu(rtcm->buff, i, 1); + i += 1; + fcn = getbitu(rtcm->buff, i, 5); + i += 5; /* fcn+7 */ + pr1 = getbitu(rtcm->buff, i, 25); + i += 25; + ppr1 = getbits(rtcm->buff, i, 20); + i += 20; + lock1 = getbitu(rtcm->buff, i, 7); + i += 7; + amb = getbitu(rtcm->buff, i, 7); + i += 7; + cnr1 = getbitu(rtcm->buff, i, 8); + i += 8; + code2 = getbitu(rtcm->buff, i, 2); + i += 2; + pr21 = getbits(rtcm->buff, i, 14); + i += 14; + ppr2 = getbits(rtcm->buff, i, 20); + i += 20; + lock2 = getbitu(rtcm->buff, i, 7); + i += 7; + cnr2 = getbitu(rtcm->buff, i, 8); + i += 8; + if (!(sat = satno(sys, prn))) { + trace(2, "rtcm3 1012 satellite number error: sys=%d prn=%d\n", sys, prn); + continue; + } + if (!rtcm->nav.glo_fcn[prn - 1]) { + rtcm->nav.glo_fcn[prn - 1] = fcn - 7 + 8; /* fcn+8 */ + } + tt = timediff(rtcm->obs.data[0].time, rtcm->time); + if (fabs(tt) > 1E-9) rtcm->obs.n = rtcm->obsflag = 0; + if ((index = obsindex(&rtcm->obs, rtcm->time, sat)) < 0) continue; + pr1 = pr1 * 0.02 + amb * PRUNIT_GLO; + rtcm->obs.data[index].P[0] = pr1; + + if (ppr1 != (int)0xFFF80000) { + freq1 = code2freq(SYS_GLO, CODE_L1C, fcn - 7); + cp1 = adjcp(rtcm, sat, 0, ppr1 * 0.0005 * freq1 / CLIGHT); + rtcm->obs.data[index].L[0] = pr1 * freq1 / CLIGHT + cp1; + } + rtcm->obs.data[index].LLI[0] = lossoflock(rtcm, sat, 0, lock1); + rtcm->obs.data[index].SNR[0] = snratio(cnr1 * 0.25); + rtcm->obs.data[index].code[0] = code1 ? CODE_L1P : CODE_L1C; + + if (pr21 != (int)0xFFFFE000) { + rtcm->obs.data[index].P[1] = pr1 + pr21 * 0.02; + } + if (ppr2 != (int)0xFFF80000) { + freq2 = code2freq(SYS_GLO, CODE_L2C, fcn - 7); + cp2 = adjcp(rtcm, sat, 1, ppr2 * 0.0005 * freq2 / CLIGHT); + rtcm->obs.data[index].L[1] = pr1 * freq2 / CLIGHT + cp2; } - rtcm->obsflag=!sync; - return sync?0:1; + rtcm->obs.data[index].LLI[1] = lossoflock(rtcm, sat, 1, lock2); + rtcm->obs.data[index].SNR[1] = snratio(cnr2 * 0.25); + rtcm->obs.data[index].code[1] = code2 ? CODE_L2P : CODE_L2C; + } + rtcm->obsflag = !sync; + return sync ? 0 : 1; } /* decode type 1013: system parameters ---------------------------------------*/ -static int decode_type1013(rtcm_t *rtcm) -{ - (void)rtcm; - return 0; +static int decode_type1013(rtcm_t *rtcm) { + (void)rtcm; + return 0; } /* decode type 1019: GPS ephemerides -----------------------------------------*/ -static int decode_type1019(rtcm_t *rtcm) -{ - eph_t eph={0}; - double toc,sqrtA,tt; - char *msg; - int i=24+12,prn,sat,week,sys=SYS_GPS; - - if (i+476<=rtcm->len*8) { - prn =getbitu(rtcm->buff,i, 6); i+= 6; - week =getbitu(rtcm->buff,i,10); i+=10; - eph.sva =getbitu(rtcm->buff,i, 4); i+= 4; - eph.code =getbitu(rtcm->buff,i, 2); i+= 2; - eph.idot =getbits(rtcm->buff,i,14)*P2_43*SC2RAD; i+=14; - eph.iode =getbitu(rtcm->buff,i, 8); i+= 8; - toc =getbitu(rtcm->buff,i,16)*16.0; i+=16; - eph.f2 =getbits(rtcm->buff,i, 8)*P2_55; i+= 8; - eph.f1 =getbits(rtcm->buff,i,16)*P2_43; i+=16; - eph.f0 =getbits(rtcm->buff,i,22)*P2_31; i+=22; - eph.iodc =getbitu(rtcm->buff,i,10); i+=10; - eph.crs =getbits(rtcm->buff,i,16)*P2_5; i+=16; - eph.deln =getbits(rtcm->buff,i,16)*P2_43*SC2RAD; i+=16; - eph.M0 =getbits(rtcm->buff,i,32)*P2_31*SC2RAD; i+=32; - eph.cuc =getbits(rtcm->buff,i,16)*P2_29; i+=16; - eph.e =getbitu(rtcm->buff,i,32)*P2_33; i+=32; - eph.cus =getbits(rtcm->buff,i,16)*P2_29; i+=16; - sqrtA =getbitu(rtcm->buff,i,32)*P2_19; i+=32; - eph.toes =getbitu(rtcm->buff,i,16)*16.0; i+=16; - eph.cic =getbits(rtcm->buff,i,16)*P2_29; i+=16; - eph.OMG0 =getbits(rtcm->buff,i,32)*P2_31*SC2RAD; i+=32; - eph.cis =getbits(rtcm->buff,i,16)*P2_29; i+=16; - eph.i0 =getbits(rtcm->buff,i,32)*P2_31*SC2RAD; i+=32; - eph.crc =getbits(rtcm->buff,i,16)*P2_5; i+=16; - eph.omg =getbits(rtcm->buff,i,32)*P2_31*SC2RAD; i+=32; - eph.OMGd =getbits(rtcm->buff,i,24)*P2_43*SC2RAD; i+=24; - eph.tgd[0]=getbits(rtcm->buff,i, 8)*P2_31; i+= 8; - eph.svh =getbitu(rtcm->buff,i, 6); i+= 6; - eph.flag =getbitu(rtcm->buff,i, 1); i+= 1; - eph.fit =getbitu(rtcm->buff,i, 1)?6:4; /* 0:4hr,1:>4hr */ - } - else { - trace(2,"rtcm3 1019 length error: len=%d\n",rtcm->len); - return -1; - } - if (prn>=40) { - sys=SYS_SBS; prn+=80; - } - trace(4,"decode_type1019: prn=%d iode=%d toe=%.0f\n",prn,eph.iode,eph.toes); - - if (rtcm->outtype) { - msg=rtcm->msgtype+strlen(rtcm->msgtype); - sprintf(msg," prn=%2d iode=%3d iodc=%3d week=%d toe=%6.0f toc=%6.0f svh=%02X", - prn,eph.iode,eph.iodc,week,eph.toes,toc,eph.svh); - } - if (!(sat=satno(sys,prn))) { - trace(2,"rtcm3 1019 satellite number error: prn=%d\n",prn); - return -1; - } - eph.sat=sat; - eph.week=adjgpsweek(week); - if (rtcm->time.time==0) rtcm->time=utc2gpst(timeget()); - tt=timediff(gpst2time(eph.week,eph.toes),rtcm->time); - if (tt<-302400.0) eph.week++; - else if (tt>=302400.0) eph.week--; - eph.toe=gpst2time(eph.week,eph.toes); - eph.toc=gpst2time(eph.week,toc); - eph.ttr=rtcm->time; - eph.A=sqrtA*sqrtA; - if (!strstr(rtcm->opt,"-EPHALL")) { - if (eph.iode==rtcm->nav.eph[sat-1].iode) return 0; /* unchanged */ - } - rtcm->nav.eph[sat-1]=eph; - rtcm->ephsat=sat; - rtcm->ephset=0; - return 2; +static int decode_type1019(rtcm_t *rtcm) { + eph_t eph = {0}; + double toc, sqrtA, tt; + char *msg; + int i = 24 + 12, prn, sat, week, sys = SYS_GPS; + + if (i + 476 <= rtcm->len * 8) { + prn = getbitu(rtcm->buff, i, 6); + i += 6; + week = getbitu(rtcm->buff, i, 10); + i += 10; + eph.sva = getbitu(rtcm->buff, i, 4); + i += 4; + eph.code = getbitu(rtcm->buff, i, 2); + i += 2; + eph.idot = getbits(rtcm->buff, i, 14) * P2_43 * SC2RAD; + i += 14; + eph.iode = getbitu(rtcm->buff, i, 8); + i += 8; + toc = getbitu(rtcm->buff, i, 16) * 16.0; + i += 16; + eph.f2 = getbits(rtcm->buff, i, 8) * P2_55; + i += 8; + eph.f1 = getbits(rtcm->buff, i, 16) * P2_43; + i += 16; + eph.f0 = getbits(rtcm->buff, i, 22) * P2_31; + i += 22; + eph.iodc = getbitu(rtcm->buff, i, 10); + i += 10; + eph.crs = getbits(rtcm->buff, i, 16) * P2_5; + i += 16; + eph.deln = getbits(rtcm->buff, i, 16) * P2_43 * SC2RAD; + i += 16; + eph.M0 = getbits(rtcm->buff, i, 32) * P2_31 * SC2RAD; + i += 32; + eph.cuc = getbits(rtcm->buff, i, 16) * P2_29; + i += 16; + eph.e = getbitu(rtcm->buff, i, 32) * P2_33; + i += 32; + eph.cus = getbits(rtcm->buff, i, 16) * P2_29; + i += 16; + sqrtA = getbitu(rtcm->buff, i, 32) * P2_19; + i += 32; + eph.toes = getbitu(rtcm->buff, i, 16) * 16.0; + i += 16; + eph.cic = getbits(rtcm->buff, i, 16) * P2_29; + i += 16; + eph.OMG0 = getbits(rtcm->buff, i, 32) * P2_31 * SC2RAD; + i += 32; + eph.cis = getbits(rtcm->buff, i, 16) * P2_29; + i += 16; + eph.i0 = getbits(rtcm->buff, i, 32) * P2_31 * SC2RAD; + i += 32; + eph.crc = getbits(rtcm->buff, i, 16) * P2_5; + i += 16; + eph.omg = getbits(rtcm->buff, i, 32) * P2_31 * SC2RAD; + i += 32; + eph.OMGd = getbits(rtcm->buff, i, 24) * P2_43 * SC2RAD; + i += 24; + eph.tgd[0] = getbits(rtcm->buff, i, 8) * P2_31; + i += 8; + eph.svh = getbitu(rtcm->buff, i, 6); + i += 6; + eph.flag = getbitu(rtcm->buff, i, 1); + i += 1; + eph.fit = getbitu(rtcm->buff, i, 1) ? 6 : 4; /* 0:4hr,1:>4hr */ + } else { + trace(2, "rtcm3 1019 length error: len=%d\n", rtcm->len); + return -1; + } + if (prn >= 40) { + sys = SYS_SBS; + prn += 80; + } + trace(4, "decode_type1019: prn=%d iode=%d toe=%.0f\n", prn, eph.iode, eph.toes); + + if (rtcm->outtype) { + msg = rtcm->msgtype + strlen(rtcm->msgtype); + sprintf(msg, " prn=%2d iode=%3d iodc=%3d week=%d toe=%6.0f toc=%6.0f svh=%02X", prn, eph.iode, + eph.iodc, week, eph.toes, toc, eph.svh); + } + if (!(sat = satno(sys, prn))) { + trace(2, "rtcm3 1019 satellite number error: prn=%d\n", prn); + return -1; + } + eph.sat = sat; + eph.week = adjgpsweek(week); + if (rtcm->time.time == 0) rtcm->time = utc2gpst(timeget()); + tt = timediff(gpst2time(eph.week, eph.toes), rtcm->time); + if (tt < -302400.0) + eph.week++; + else if (tt >= 302400.0) + eph.week--; + eph.toe = gpst2time(eph.week, eph.toes); + eph.toc = gpst2time(eph.week, toc); + eph.ttr = rtcm->time; + eph.A = sqrtA * sqrtA; + if (!strstr(rtcm->opt, "-EPHALL")) { + if (eph.iode == rtcm->nav.eph[sat - 1].iode) return 0; /* unchanged */ + } + rtcm->nav.eph[sat - 1] = eph; + rtcm->ephsat = sat; + rtcm->ephset = 0; + return 2; } /* decode type 1020: GLONASS ephemerides -------------------------------------*/ -static int decode_type1020(rtcm_t *rtcm) -{ - geph_t geph={0}; - double toe,tow,tod,tof; - char *msg; - int i=24+12,sat,week,sys=SYS_GLO; - - if (i+348 > rtcm->len*8) { - trace(2,"rtcm3 1020 length error: len=%d\n",rtcm->len); - return -1; - } - int prn =getbitu(rtcm->buff,i, 6); i+= 6; - geph.frq =getbitu(rtcm->buff,i, 5)-7; i+= 5; - int Cn =getbitu(rtcm->buff,i, 1); i+= 1; - int Cn_a =getbitu(rtcm->buff,i, 1); i+= 1; - int P1 =getbitu(rtcm->buff,i, 2); i+= 2; - double tk_h=getbitu(rtcm->buff,i, 5); i+= 5; - double tk_m=getbitu(rtcm->buff,i, 6); i+= 6; - double tk_s=getbitu(rtcm->buff,i, 1)*30.0; i+= 1; - int Bn =getbitu(rtcm->buff,i, 1); i+= 1; - int P2 =getbitu(rtcm->buff,i, 1); i+= 1; - int tb =getbitu(rtcm->buff,i, 7); i+= 7; - geph.vel[0]=getbitg(rtcm->buff,i,24)*P2_20*1E3; i+=24; - geph.pos[0]=getbitg(rtcm->buff,i,27)*P2_11*1E3; i+=27; - geph.acc[0]=getbitg(rtcm->buff,i, 5)*P2_30*1E3; i+= 5; - geph.vel[1]=getbitg(rtcm->buff,i,24)*P2_20*1E3; i+=24; - geph.pos[1]=getbitg(rtcm->buff,i,27)*P2_11*1E3; i+=27; - geph.acc[1]=getbitg(rtcm->buff,i, 5)*P2_30*1E3; i+= 5; - geph.vel[2]=getbitg(rtcm->buff,i,24)*P2_20*1E3; i+=24; - geph.pos[2]=getbitg(rtcm->buff,i,27)*P2_11*1E3; i+=27; - geph.acc[2]=getbitg(rtcm->buff,i, 5)*P2_30*1E3; i+= 5; - int P3 =getbitu(rtcm->buff,i, 1); i+= 1; - geph.gamn =getbitg(rtcm->buff,i,11)*P2_40; i+=11; - int P =getbitu(rtcm->buff,i, 2); i+= 2; - int ln =getbitu(rtcm->buff,i, 1); i+= 1; - geph.taun =getbitg(rtcm->buff,i,22)*P2_30; i+=22; - geph.dtaun =getbitg(rtcm->buff,i, 5)*P2_30; i+= 5; - geph.age =getbitu(rtcm->buff,i, 5); i+= 5; - int P4 =getbitu(rtcm->buff,i, 1); i+= 1; - geph.sva =getbitu(rtcm->buff,i, 4); i+= 4; - int M =getbitu(rtcm->buff,i, 2); - - if (!(sat=satno(sys,prn))) { - trace(2,"rtcm3 1020 satellite number error: prn=%d\n",prn); - return -1; - } - trace(4,"decode_type1020: prn=%d tk=%02.0f:%02.0f:%02.0f\n",prn,tk_h,tk_m,tk_s); - - if (rtcm->outtype) { - msg=rtcm->msgtype+strlen(rtcm->msgtype); - sprintf(msg," prn=%2d tk=%02.0f:%02.0f:%02.0f frq=%2d Bn=%d tb=%d", - prn,tk_h,tk_m,tk_s,geph.frq,Bn,tb); - } - geph.sat=sat; - geph.svh = (ln << 3) | (Cn_a << 2) | (Cn << 1) | Bn; - geph.flags = (M << 7) | (P4 << 6) | (P3 << 5) | (P2 << 4) | (P1 << 2) | P; - geph.iode=tb&0x7F; - if (rtcm->time.time==0) rtcm->time=utc2gpst(timeget()); - tow=time2gpst(gpst2utc(rtcm->time),&week); - tod=fmod(tow,86400.0); tow-=tod; - tof=tk_h*3600.0+tk_m*60.0+tk_s-10800.0; /* lt->utc */ - if (toftod+43200.0) tof-=86400.0; - geph.tof=utc2gpst(gpst2time(week,tow+tof)); - toe=tb*900.0-10800.0; /* lt->utc */ - if (toetod+43200.0) toe-=86400.0; - geph.toe=utc2gpst(gpst2time(week,tow+toe)); /* utc->gpst */ - - if (!strstr(rtcm->opt,"-EPHALL")) { - if (fabs(timediff(geph.toe,rtcm->nav.geph[prn-1].toe))<1.0&& - geph.svh==rtcm->nav.geph[prn-1].svh) return 0; /* unchanged */ - } - rtcm->nav.geph[prn-1]=geph; - rtcm->ephsat=sat; - rtcm->ephset=0; - return 2; +static int decode_type1020(rtcm_t *rtcm) { + geph_t geph = {0}; + double toe, tow, tod, tof; + char *msg; + int i = 24 + 12, sat, week, sys = SYS_GLO; + + if (i + 348 > rtcm->len * 8) { + trace(2, "rtcm3 1020 length error: len=%d\n", rtcm->len); + return -1; + } + int prn = getbitu(rtcm->buff, i, 6); + i += 6; + geph.frq = getbitu(rtcm->buff, i, 5) - 7; + i += 5; + int Cn = getbitu(rtcm->buff, i, 1); + i += 1; + int Cn_a = getbitu(rtcm->buff, i, 1); + i += 1; + int P1 = getbitu(rtcm->buff, i, 2); + i += 2; + double tk_h = getbitu(rtcm->buff, i, 5); + i += 5; + double tk_m = getbitu(rtcm->buff, i, 6); + i += 6; + double tk_s = getbitu(rtcm->buff, i, 1) * 30.0; + i += 1; + int Bn = getbitu(rtcm->buff, i, 1); + i += 1; + int P2 = getbitu(rtcm->buff, i, 1); + i += 1; + int tb = getbitu(rtcm->buff, i, 7); + i += 7; + geph.vel[0] = getbitg(rtcm->buff, i, 24) * P2_20 * 1E3; + i += 24; + geph.pos[0] = getbitg(rtcm->buff, i, 27) * P2_11 * 1E3; + i += 27; + geph.acc[0] = getbitg(rtcm->buff, i, 5) * P2_30 * 1E3; + i += 5; + geph.vel[1] = getbitg(rtcm->buff, i, 24) * P2_20 * 1E3; + i += 24; + geph.pos[1] = getbitg(rtcm->buff, i, 27) * P2_11 * 1E3; + i += 27; + geph.acc[1] = getbitg(rtcm->buff, i, 5) * P2_30 * 1E3; + i += 5; + geph.vel[2] = getbitg(rtcm->buff, i, 24) * P2_20 * 1E3; + i += 24; + geph.pos[2] = getbitg(rtcm->buff, i, 27) * P2_11 * 1E3; + i += 27; + geph.acc[2] = getbitg(rtcm->buff, i, 5) * P2_30 * 1E3; + i += 5; + int P3 = getbitu(rtcm->buff, i, 1); + i += 1; + geph.gamn = getbitg(rtcm->buff, i, 11) * P2_40; + i += 11; + int P = getbitu(rtcm->buff, i, 2); + i += 2; + int ln = getbitu(rtcm->buff, i, 1); + i += 1; + geph.taun = getbitg(rtcm->buff, i, 22) * P2_30; + i += 22; + geph.dtaun = getbitg(rtcm->buff, i, 5) * P2_30; + i += 5; + geph.age = getbitu(rtcm->buff, i, 5); + i += 5; + int P4 = getbitu(rtcm->buff, i, 1); + i += 1; + geph.sva = getbitu(rtcm->buff, i, 4); + i += 4; + int M = getbitu(rtcm->buff, i, 2); + + if (!(sat = satno(sys, prn))) { + trace(2, "rtcm3 1020 satellite number error: prn=%d\n", prn); + return -1; + } + trace(4, "decode_type1020: prn=%d tk=%02.0f:%02.0f:%02.0f\n", prn, tk_h, tk_m, tk_s); + + if (rtcm->outtype) { + msg = rtcm->msgtype + strlen(rtcm->msgtype); + sprintf(msg, " prn=%2d tk=%02.0f:%02.0f:%02.0f frq=%2d Bn=%d tb=%d", prn, tk_h, tk_m, tk_s, + geph.frq, Bn, tb); + } + geph.sat = sat; + geph.svh = (ln << 3) | (Cn_a << 2) | (Cn << 1) | Bn; + geph.flags = (M << 7) | (P4 << 6) | (P3 << 5) | (P2 << 4) | (P1 << 2) | P; + geph.iode = tb & 0x7F; + if (rtcm->time.time == 0) rtcm->time = utc2gpst(timeget()); + tow = time2gpst(gpst2utc(rtcm->time), &week); + tod = fmod(tow, 86400.0); + tow -= tod; + tof = tk_h * 3600.0 + tk_m * 60.0 + tk_s - 10800.0; /* lt->utc */ + if (tof < tod - 43200.0) + tof += 86400.0; + else if (tof > tod + 43200.0) + tof -= 86400.0; + geph.tof = utc2gpst(gpst2time(week, tow + tof)); + toe = tb * 900.0 - 10800.0; /* lt->utc */ + if (toe < tod - 43200.0) + toe += 86400.0; + else if (toe > tod + 43200.0) + toe -= 86400.0; + geph.toe = utc2gpst(gpst2time(week, tow + toe)); /* utc->gpst */ + + if (!strstr(rtcm->opt, "-EPHALL")) { + if (fabs(timediff(geph.toe, rtcm->nav.geph[prn - 1].toe)) < 1.0 && + geph.svh == rtcm->nav.geph[prn - 1].svh) + return 0; /* unchanged */ + } + rtcm->nav.geph[prn - 1] = geph; + rtcm->ephsat = sat; + rtcm->ephset = 0; + return 2; } /* decode type 1021: helmert/abridged molodenski -----------------------------*/ -static int decode_type1021(rtcm_t *rtcm) -{ - (void)rtcm; - trace(2,"rtcm3 1021: not supported message\n"); - return 0; +static int decode_type1021(rtcm_t *rtcm) { + (void)rtcm; + trace(2, "rtcm3 1021: not supported message\n"); + return 0; } /* decode type 1022: Moledenski-Badekas transfromation -----------------------*/ -static int decode_type1022(rtcm_t *rtcm) -{ - (void)rtcm; - trace(2,"rtcm3 1022: not supported message\n"); - return 0; +static int decode_type1022(rtcm_t *rtcm) { + (void)rtcm; + trace(2, "rtcm3 1022: not supported message\n"); + return 0; } /* decode type 1023: residual, ellipsoidal grid representation ---------------*/ -static int decode_type1023(rtcm_t *rtcm) -{ - (void)rtcm; - trace(2,"rtcm3 1023: not supported message\n"); - return 0; +static int decode_type1023(rtcm_t *rtcm) { + (void)rtcm; + trace(2, "rtcm3 1023: not supported message\n"); + return 0; } /* decode type 1024: residual, plane grid representation ---------------------*/ -static int decode_type1024(rtcm_t *rtcm) -{ - (void)rtcm; - trace(2,"rtcm3 1024: not supported message\n"); - return 0; +static int decode_type1024(rtcm_t *rtcm) { + (void)rtcm; + trace(2, "rtcm3 1024: not supported message\n"); + return 0; } /* decode type 1025: projection (types except LCC2SP,OM) ---------------------*/ -static int decode_type1025(rtcm_t *rtcm) -{ - (void)rtcm; - trace(2,"rtcm3 1025: not supported message\n"); - return 0; +static int decode_type1025(rtcm_t *rtcm) { + (void)rtcm; + trace(2, "rtcm3 1025: not supported message\n"); + return 0; } /* decode type 1026: projection (LCC2SP - lambert conic conformal (2sp)) -----*/ -static int decode_type1026(rtcm_t *rtcm) -{ - (void)rtcm; - trace(2,"rtcm3 1026: not supported message\n"); - return 0; +static int decode_type1026(rtcm_t *rtcm) { + (void)rtcm; + trace(2, "rtcm3 1026: not supported message\n"); + return 0; } /* decode type 1027: projection (type OM - oblique mercator) -----------------*/ -static int decode_type1027(rtcm_t *rtcm) -{ - (void)rtcm; - trace(2,"rtcm3 1027: not supported message\n"); - return 0; +static int decode_type1027(rtcm_t *rtcm) { + (void)rtcm; + trace(2, "rtcm3 1027: not supported message\n"); + return 0; } /* decode type 1029: UNICODE text string -------------------------------------*/ -static int decode_type1029(rtcm_t *rtcm) -{ - char *msg; - int i=24+12,j,staid,mjd,tod,nchar,cunit; - - if (i+60<=rtcm->len*8) { - staid=getbitu(rtcm->buff,i,12); i+=12; - mjd =getbitu(rtcm->buff,i,16); i+=16; - tod =getbitu(rtcm->buff,i,17); i+=17; - nchar=getbitu(rtcm->buff,i, 7); i+= 7; - cunit=getbitu(rtcm->buff,i, 8); i+= 8; - } - else { - trace(2,"rtcm3 1029 length error: len=%d\n",rtcm->len); - return -1; - } - if (i+nchar*8>rtcm->len*8) { - trace(2,"rtcm3 1029 length error: len=%d nchar=%d\n",rtcm->len,nchar); - return -1; - } - for (j=0;jmsg[j]=getbitu(rtcm->buff,i,8); i+=8; - } - rtcm->msg[j]='\0'; - - if (rtcm->outtype) { - msg=rtcm->msgtype+strlen(rtcm->msgtype); - sprintf(msg," staid=%4d text=%s",staid,rtcm->msg); - } - return 0; +static int decode_type1029(rtcm_t *rtcm) { + char *msg; + int i = 24 + 12, j, staid, mjd, tod, nchar, cunit; + + if (i + 60 <= rtcm->len * 8) { + staid = getbitu(rtcm->buff, i, 12); + i += 12; + mjd = getbitu(rtcm->buff, i, 16); + i += 16; + tod = getbitu(rtcm->buff, i, 17); + i += 17; + nchar = getbitu(rtcm->buff, i, 7); + i += 7; + cunit = getbitu(rtcm->buff, i, 8); + i += 8; + } else { + trace(2, "rtcm3 1029 length error: len=%d\n", rtcm->len); + return -1; + } + if (i + nchar * 8 > rtcm->len * 8) { + trace(2, "rtcm3 1029 length error: len=%d nchar=%d\n", rtcm->len, nchar); + return -1; + } + for (j = 0; j < nchar && j < 126; j++) { + rtcm->msg[j] = getbitu(rtcm->buff, i, 8); + i += 8; + } + rtcm->msg[j] = '\0'; + + if (rtcm->outtype) { + msg = rtcm->msgtype + strlen(rtcm->msgtype); + sprintf(msg, " staid=%4d text=%s", staid, rtcm->msg); + } + return 0; } /* decode type 1030: network RTK residual ------------------------------------*/ -static int decode_type1030(rtcm_t *rtcm) -{ - (void)rtcm; - trace(2,"rtcm3 1030: not supported message\n"); - return 0; +static int decode_type1030(rtcm_t *rtcm) { + (void)rtcm; + trace(2, "rtcm3 1030: not supported message\n"); + return 0; } /* decode type 1031: GLONASS network RTK residual ----------------------------*/ -static int decode_type1031(rtcm_t *rtcm) -{ - (void)rtcm; - trace(2,"rtcm3 1031: not supported message\n"); - return 0; +static int decode_type1031(rtcm_t *rtcm) { + (void)rtcm; + trace(2, "rtcm3 1031: not supported message\n"); + return 0; } /* decode type 1032: physical reference station position information ---------*/ -static int decode_type1032(rtcm_t *rtcm) -{ - (void)rtcm; - trace(2,"rtcm3 1032: not supported message\n"); - return 0; +static int decode_type1032(rtcm_t *rtcm) { + (void)rtcm; + trace(2, "rtcm3 1032: not supported message\n"); + return 0; } /* decode type 1033: receiver and antenna descriptor -------------------------*/ -static int decode_type1033(rtcm_t *rtcm) -{ - char des[32]="",sno[32]="",rec[32]="",ver[32]="",rsn[32]=""; - char *msg; - int i=24+12,j,staid,n,m,n1,n2,n3,setup; - - n =getbitu(rtcm->buff,i+12,8); - m =getbitu(rtcm->buff,i+28+8*n,8); - n1=getbitu(rtcm->buff,i+36+8*(n+m),8); - n2=getbitu(rtcm->buff,i+44+8*(n+m+n1),8); - n3=getbitu(rtcm->buff,i+52+8*(n+m+n1+n2),8); - - if (i+60+8*(n+m+n1+n2+n3)<=rtcm->len*8) { - staid=getbitu(rtcm->buff,i,12); i+=12+8; - for (j=0;jbuff,i,8); i+=8; - } - setup=getbitu(rtcm->buff,i, 8); i+=8+8; - for (j=0;jbuff,i,8); i+=8; - } - i+=8; - for (j=0;jbuff,i,8); i+=8; - } - i+=8; - for (j=0;jbuff,i,8); i+=8; - } - i+=8; - for (j=0;jbuff,i,8); i+=8; - } - } - else { - trace(2,"rtcm3 1033 length error: len=%d\n",rtcm->len); - return -1; - } - if (rtcm->outtype) { - msg=rtcm->msgtype+strlen(rtcm->msgtype); - sprintf(msg," staid=%4d",staid); - } - /* test station id */ - if (!test_staid(rtcm,staid)) return -1; - - sprintf(rtcm->sta.name,"%04d",staid); - strncpy(rtcm->sta.antdes, des,n ); rtcm->sta.antdes [n] ='\0'; - rtcm->sta.antsetup=setup; - strncpy(rtcm->sta.antsno, sno,m ); rtcm->sta.antsno [m] ='\0'; - strncpy(rtcm->sta.rectype,rec,n1); rtcm->sta.rectype[n1]='\0'; - strncpy(rtcm->sta.recver, ver,n2); rtcm->sta.recver [n2]='\0'; - strncpy(rtcm->sta.recsno, rsn,n3); rtcm->sta.recsno [n3]='\0'; - - trace(3,"rtcm3 1033: ant=%s:%s rec=%s:%s:%s\n",des,sno,rec,ver,rsn); - return 5; +static int decode_type1033(rtcm_t *rtcm) { + char des[32] = "", sno[32] = "", rec[32] = "", ver[32] = "", rsn[32] = ""; + char *msg; + int i = 24 + 12, j, staid, n, m, n1, n2, n3, setup; + + n = getbitu(rtcm->buff, i + 12, 8); + m = getbitu(rtcm->buff, i + 28 + 8 * n, 8); + n1 = getbitu(rtcm->buff, i + 36 + 8 * (n + m), 8); + n2 = getbitu(rtcm->buff, i + 44 + 8 * (n + m + n1), 8); + n3 = getbitu(rtcm->buff, i + 52 + 8 * (n + m + n1 + n2), 8); + + if (i + 60 + 8 * (n + m + n1 + n2 + n3) <= rtcm->len * 8) { + staid = getbitu(rtcm->buff, i, 12); + i += 12 + 8; + for (j = 0; j < n && j < 31; j++) { + des[j] = (char)getbitu(rtcm->buff, i, 8); + i += 8; + } + setup = getbitu(rtcm->buff, i, 8); + i += 8 + 8; + for (j = 0; j < m && j < 31; j++) { + sno[j] = (char)getbitu(rtcm->buff, i, 8); + i += 8; + } + i += 8; + for (j = 0; j < n1 && j < 31; j++) { + rec[j] = (char)getbitu(rtcm->buff, i, 8); + i += 8; + } + i += 8; + for (j = 0; j < n2 && j < 31; j++) { + ver[j] = (char)getbitu(rtcm->buff, i, 8); + i += 8; + } + i += 8; + for (j = 0; j < n3 && j < 31; j++) { + rsn[j] = (char)getbitu(rtcm->buff, i, 8); + i += 8; + } + } else { + trace(2, "rtcm3 1033 length error: len=%d\n", rtcm->len); + return -1; + } + if (rtcm->outtype) { + msg = rtcm->msgtype + strlen(rtcm->msgtype); + sprintf(msg, " staid=%4d", staid); + } + /* test station id */ + if (!test_staid(rtcm, staid)) return -1; + + sprintf(rtcm->sta.name, "%04d", staid); + strncpy(rtcm->sta.antdes, des, n); + rtcm->sta.antdes[n] = '\0'; + rtcm->sta.antsetup = setup; + strncpy(rtcm->sta.antsno, sno, m); + rtcm->sta.antsno[m] = '\0'; + strncpy(rtcm->sta.rectype, rec, n1); + rtcm->sta.rectype[n1] = '\0'; + strncpy(rtcm->sta.recver, ver, n2); + rtcm->sta.recver[n2] = '\0'; + strncpy(rtcm->sta.recsno, rsn, n3); + rtcm->sta.recsno[n3] = '\0'; + + trace(3, "rtcm3 1033: ant=%s:%s rec=%s:%s:%s\n", des, sno, rec, ver, rsn); + return 5; } /* decode type 1034: GPS network FKP gradient --------------------------------*/ -static int decode_type1034(rtcm_t *rtcm) -{ - (void)rtcm; - trace(2,"rtcm3 1034: not supported message\n"); - return 0; +static int decode_type1034(rtcm_t *rtcm) { + (void)rtcm; + trace(2, "rtcm3 1034: not supported message\n"); + return 0; } /* decode type 1035: GLONASS network FKP gradient ----------------------------*/ -static int decode_type1035(rtcm_t *rtcm) -{ - (void)rtcm; - trace(2,"rtcm3 1035: not supported message\n"); - return 0; +static int decode_type1035(rtcm_t *rtcm) { + (void)rtcm; + trace(2, "rtcm3 1035: not supported message\n"); + return 0; } /* decode type 1037: GLONASS network RTK ionospheric correction difference ---*/ -static int decode_type1037(rtcm_t *rtcm) -{ - (void)rtcm; - trace(2,"rtcm3 1037: not supported message\n"); - return 0; +static int decode_type1037(rtcm_t *rtcm) { + (void)rtcm; + trace(2, "rtcm3 1037: not supported message\n"); + return 0; } /* decode type 1038: GLONASS network RTK geometic correction difference ------*/ -static int decode_type1038(rtcm_t *rtcm) -{ - (void)rtcm; - trace(2,"rtcm3 1038: not supported message\n"); - return 0; +static int decode_type1038(rtcm_t *rtcm) { + (void)rtcm; + trace(2, "rtcm3 1038: not supported message\n"); + return 0; } /* decode type 1039: GLONASS network RTK combined correction difference ------*/ -static int decode_type1039(rtcm_t *rtcm) -{ - (void)rtcm; - trace(2,"rtcm3 1039: not supported message\n"); - return 0; +static int decode_type1039(rtcm_t *rtcm) { + (void)rtcm; + trace(2, "rtcm3 1039: not supported message\n"); + return 0; } /* decode type 1041: NavIC/IRNSS ephemerides ---------------------------------*/ -static int decode_type1041(rtcm_t *rtcm) -{ - eph_t eph={0}; - double toc,sqrtA,tt; - char *msg; - int i=24+12,prn,sat,week,sys=SYS_IRN; - - if (i+482-12<=rtcm->len*8) { - prn =getbitu(rtcm->buff,i, 6); i+= 6; - week =getbitu(rtcm->buff,i,10); i+=10; - eph.f0 =getbits(rtcm->buff,i,22)*P2_31; i+=22; - eph.f1 =getbits(rtcm->buff,i,16)*P2_43; i+=16; - eph.f2 =getbits(rtcm->buff,i, 8)*P2_55; i+= 8; - eph.sva =getbitu(rtcm->buff,i, 4); i+= 4; - toc =getbitu(rtcm->buff,i,16)*16.0; i+=16; - eph.tgd[0]=getbits(rtcm->buff,i, 8)*P2_31; i+= 8; - eph.deln =getbits(rtcm->buff,i,22)*P2_41*SC2RAD; i+=22; - eph.iode =getbitu(rtcm->buff,i, 8); i+= 8+10; /* IODEC */ - eph.svh =getbitu(rtcm->buff,i, 2); i+= 2; /* L5+Sflag */ - eph.cuc =getbits(rtcm->buff,i,15)*P2_28; i+=15; - eph.cus =getbits(rtcm->buff,i,15)*P2_28; i+=15; - eph.cic =getbits(rtcm->buff,i,15)*P2_28; i+=15; - eph.cis =getbits(rtcm->buff,i,15)*P2_28; i+=15; - eph.crc =getbits(rtcm->buff,i,15)*0.0625; i+=15; - eph.crs =getbits(rtcm->buff,i,15)*0.0625; i+=15; - eph.idot =getbits(rtcm->buff,i,14)*P2_43*SC2RAD; i+=14; - eph.M0 =getbits(rtcm->buff,i,32)*P2_31*SC2RAD; i+=32; - eph.toes =getbitu(rtcm->buff,i,16)*16.0; i+=16; - eph.e =getbitu(rtcm->buff,i,32)*P2_33; i+=32; - sqrtA =getbitu(rtcm->buff,i,32)*P2_19; i+=32; - eph.OMG0 =getbits(rtcm->buff,i,32)*P2_31*SC2RAD; i+=32; - eph.omg =getbits(rtcm->buff,i,32)*P2_31*SC2RAD; i+=32; - eph.OMGd =getbits(rtcm->buff,i,22)*P2_41*SC2RAD; i+=22; - eph.i0 =getbits(rtcm->buff,i,32)*P2_31*SC2RAD; - } - else { - trace(2,"rtcm3 1041 length error: len=%d\n",rtcm->len); - return -1; - } - trace(4,"decode_type1041: prn=%d iode=%d toe=%.0f\n",prn,eph.iode,eph.toes); - - if (rtcm->outtype) { - msg=rtcm->msgtype+strlen(rtcm->msgtype); - sprintf(msg," prn=%2d iode=%3d week=%d toe=%6.0f toc=%6.0f svh=%02X", - prn,eph.iode,week,eph.toes,toc,eph.svh); - } - if (!(sat=satno(sys,prn))) { - trace(2,"rtcm3 1041 satellite number error: prn=%d\n",prn); - return -1; - } - eph.sat=sat; - eph.week=adjgpsweek(week); - if (rtcm->time.time==0) rtcm->time=utc2gpst(timeget()); - tt=timediff(gpst2time(eph.week,eph.toes),rtcm->time); - if (tt<-302400.0) eph.week++; - else if (tt>=302400.0) eph.week--; - eph.toe=gpst2time(eph.week,eph.toes); - eph.toc=gpst2time(eph.week,toc); - eph.ttr=rtcm->time; - eph.A=sqrtA*sqrtA; - eph.iodc=eph.iode; - if (!strstr(rtcm->opt,"-EPHALL")) { - if (eph.iode==rtcm->nav.eph[sat-1].iode) return 0; /* unchanged */ - } - rtcm->nav.eph[sat-1]=eph; - rtcm->ephsat=sat; - rtcm->ephset=0; - return 2; +static int decode_type1041(rtcm_t *rtcm) { + eph_t eph = {0}; + double toc, sqrtA, tt; + char *msg; + int i = 24 + 12, prn, sat, week, sys = SYS_IRN; + + if (i + 482 - 12 <= rtcm->len * 8) { + prn = getbitu(rtcm->buff, i, 6); + i += 6; + week = getbitu(rtcm->buff, i, 10); + i += 10; + eph.f0 = getbits(rtcm->buff, i, 22) * P2_31; + i += 22; + eph.f1 = getbits(rtcm->buff, i, 16) * P2_43; + i += 16; + eph.f2 = getbits(rtcm->buff, i, 8) * P2_55; + i += 8; + eph.sva = getbitu(rtcm->buff, i, 4); + i += 4; + toc = getbitu(rtcm->buff, i, 16) * 16.0; + i += 16; + eph.tgd[0] = getbits(rtcm->buff, i, 8) * P2_31; + i += 8; + eph.deln = getbits(rtcm->buff, i, 22) * P2_41 * SC2RAD; + i += 22; + eph.iode = getbitu(rtcm->buff, i, 8); + i += 8 + 10; /* IODEC */ + eph.svh = getbitu(rtcm->buff, i, 2); + i += 2; /* L5+Sflag */ + eph.cuc = getbits(rtcm->buff, i, 15) * P2_28; + i += 15; + eph.cus = getbits(rtcm->buff, i, 15) * P2_28; + i += 15; + eph.cic = getbits(rtcm->buff, i, 15) * P2_28; + i += 15; + eph.cis = getbits(rtcm->buff, i, 15) * P2_28; + i += 15; + eph.crc = getbits(rtcm->buff, i, 15) * 0.0625; + i += 15; + eph.crs = getbits(rtcm->buff, i, 15) * 0.0625; + i += 15; + eph.idot = getbits(rtcm->buff, i, 14) * P2_43 * SC2RAD; + i += 14; + eph.M0 = getbits(rtcm->buff, i, 32) * P2_31 * SC2RAD; + i += 32; + eph.toes = getbitu(rtcm->buff, i, 16) * 16.0; + i += 16; + eph.e = getbitu(rtcm->buff, i, 32) * P2_33; + i += 32; + sqrtA = getbitu(rtcm->buff, i, 32) * P2_19; + i += 32; + eph.OMG0 = getbits(rtcm->buff, i, 32) * P2_31 * SC2RAD; + i += 32; + eph.omg = getbits(rtcm->buff, i, 32) * P2_31 * SC2RAD; + i += 32; + eph.OMGd = getbits(rtcm->buff, i, 22) * P2_41 * SC2RAD; + i += 22; + eph.i0 = getbits(rtcm->buff, i, 32) * P2_31 * SC2RAD; + } else { + trace(2, "rtcm3 1041 length error: len=%d\n", rtcm->len); + return -1; + } + trace(4, "decode_type1041: prn=%d iode=%d toe=%.0f\n", prn, eph.iode, eph.toes); + + if (rtcm->outtype) { + msg = rtcm->msgtype + strlen(rtcm->msgtype); + sprintf(msg, " prn=%2d iode=%3d week=%d toe=%6.0f toc=%6.0f svh=%02X", prn, eph.iode, week, + eph.toes, toc, eph.svh); + } + if (!(sat = satno(sys, prn))) { + trace(2, "rtcm3 1041 satellite number error: prn=%d\n", prn); + return -1; + } + eph.sat = sat; + eph.week = adjgpsweek(week); + if (rtcm->time.time == 0) rtcm->time = utc2gpst(timeget()); + tt = timediff(gpst2time(eph.week, eph.toes), rtcm->time); + if (tt < -302400.0) + eph.week++; + else if (tt >= 302400.0) + eph.week--; + eph.toe = gpst2time(eph.week, eph.toes); + eph.toc = gpst2time(eph.week, toc); + eph.ttr = rtcm->time; + eph.A = sqrtA * sqrtA; + eph.iodc = eph.iode; + if (!strstr(rtcm->opt, "-EPHALL")) { + if (eph.iode == rtcm->nav.eph[sat - 1].iode) return 0; /* unchanged */ + } + rtcm->nav.eph[sat - 1] = eph; + rtcm->ephsat = sat; + rtcm->ephset = 0; + return 2; } /* decode type 1044: QZSS ephemerides ----------------------------------------*/ -static int decode_type1044(rtcm_t *rtcm) -{ - eph_t eph={0}; - double toc,sqrtA,tt; - char *msg; - int i=24+12,prn,sat,week,sys=SYS_QZS; - - if (i+473<=rtcm->len*8) { - prn =getbitu(rtcm->buff,i, 4)+192; i+= 4; - toc =getbitu(rtcm->buff,i,16)*16.0; i+=16; - eph.f2 =getbits(rtcm->buff,i, 8)*P2_55; i+= 8; - eph.f1 =getbits(rtcm->buff,i,16)*P2_43; i+=16; - eph.f0 =getbits(rtcm->buff,i,22)*P2_31; i+=22; - eph.iode =getbitu(rtcm->buff,i, 8); i+= 8; - eph.crs =getbits(rtcm->buff,i,16)*P2_5; i+=16; - eph.deln =getbits(rtcm->buff,i,16)*P2_43*SC2RAD; i+=16; - eph.M0 =getbits(rtcm->buff,i,32)*P2_31*SC2RAD; i+=32; - eph.cuc =getbits(rtcm->buff,i,16)*P2_29; i+=16; - eph.e =getbitu(rtcm->buff,i,32)*P2_33; i+=32; - eph.cus =getbits(rtcm->buff,i,16)*P2_29; i+=16; - sqrtA =getbitu(rtcm->buff,i,32)*P2_19; i+=32; - eph.toes =getbitu(rtcm->buff,i,16)*16.0; i+=16; - eph.cic =getbits(rtcm->buff,i,16)*P2_29; i+=16; - eph.OMG0 =getbits(rtcm->buff,i,32)*P2_31*SC2RAD; i+=32; - eph.cis =getbits(rtcm->buff,i,16)*P2_29; i+=16; - eph.i0 =getbits(rtcm->buff,i,32)*P2_31*SC2RAD; i+=32; - eph.crc =getbits(rtcm->buff,i,16)*P2_5; i+=16; - eph.omg =getbits(rtcm->buff,i,32)*P2_31*SC2RAD; i+=32; - eph.OMGd =getbits(rtcm->buff,i,24)*P2_43*SC2RAD; i+=24; - eph.idot =getbits(rtcm->buff,i,14)*P2_43*SC2RAD; i+=14; - eph.code =getbitu(rtcm->buff,i, 2); i+= 2; - week =getbitu(rtcm->buff,i,10); i+=10; - eph.sva =getbitu(rtcm->buff,i, 4); i+= 4; - eph.svh =getbitu(rtcm->buff,i, 6); i+= 6; - eph.tgd[0]=getbits(rtcm->buff,i, 8)*P2_31; i+= 8; - eph.iodc =getbitu(rtcm->buff,i,10); i+=10; - eph.fit =getbitu(rtcm->buff,i, 1)?4:2; /* 0:2hr,1:>2hr */ - } - else { - trace(2,"rtcm3 1044 length error: len=%d\n",rtcm->len); - return -1; - } - trace(4,"decode_type1044: prn=%d iode=%d toe=%.0f\n",prn,eph.iode,eph.toes); - - if (rtcm->outtype) { - msg=rtcm->msgtype+strlen(rtcm->msgtype); - sprintf(msg," prn=%3d iode=%3d iodc=%3d week=%d toe=%6.0f toc=%6.0f svh=%02X", - prn,eph.iode,eph.iodc,week,eph.toes,toc,eph.svh); - } - if (!(sat=satno(sys,prn))) { - trace(2,"rtcm3 1044 satellite number error: prn=%d\n",prn); - return -1; - } - eph.sat=sat; - eph.week=adjgpsweek(week); - if (rtcm->time.time==0) rtcm->time=utc2gpst(timeget()); - tt=timediff(gpst2time(eph.week,eph.toes),rtcm->time); - if (tt<-302400.0) eph.week++; - else if (tt>=302400.0) eph.week--; - eph.toe=gpst2time(eph.week,eph.toes); - eph.toc=gpst2time(eph.week,toc); - eph.ttr=rtcm->time; - eph.A=sqrtA*sqrtA; - eph.flag=1; /* fixed to 1 */ - if (!strstr(rtcm->opt,"-EPHALL")) { - if (eph.iode==rtcm->nav.eph[sat-1].iode&& - eph.iodc==rtcm->nav.eph[sat-1].iodc) return 0; /* unchanged */ - } - rtcm->nav.eph[sat-1]=eph; - rtcm->ephsat=sat; - rtcm->ephset=0; - return 2; +static int decode_type1044(rtcm_t *rtcm) { + eph_t eph = {0}; + double toc, sqrtA, tt; + char *msg; + int i = 24 + 12, prn, sat, week, sys = SYS_QZS; + + if (i + 473 <= rtcm->len * 8) { + prn = getbitu(rtcm->buff, i, 4) + 192; + i += 4; + toc = getbitu(rtcm->buff, i, 16) * 16.0; + i += 16; + eph.f2 = getbits(rtcm->buff, i, 8) * P2_55; + i += 8; + eph.f1 = getbits(rtcm->buff, i, 16) * P2_43; + i += 16; + eph.f0 = getbits(rtcm->buff, i, 22) * P2_31; + i += 22; + eph.iode = getbitu(rtcm->buff, i, 8); + i += 8; + eph.crs = getbits(rtcm->buff, i, 16) * P2_5; + i += 16; + eph.deln = getbits(rtcm->buff, i, 16) * P2_43 * SC2RAD; + i += 16; + eph.M0 = getbits(rtcm->buff, i, 32) * P2_31 * SC2RAD; + i += 32; + eph.cuc = getbits(rtcm->buff, i, 16) * P2_29; + i += 16; + eph.e = getbitu(rtcm->buff, i, 32) * P2_33; + i += 32; + eph.cus = getbits(rtcm->buff, i, 16) * P2_29; + i += 16; + sqrtA = getbitu(rtcm->buff, i, 32) * P2_19; + i += 32; + eph.toes = getbitu(rtcm->buff, i, 16) * 16.0; + i += 16; + eph.cic = getbits(rtcm->buff, i, 16) * P2_29; + i += 16; + eph.OMG0 = getbits(rtcm->buff, i, 32) * P2_31 * SC2RAD; + i += 32; + eph.cis = getbits(rtcm->buff, i, 16) * P2_29; + i += 16; + eph.i0 = getbits(rtcm->buff, i, 32) * P2_31 * SC2RAD; + i += 32; + eph.crc = getbits(rtcm->buff, i, 16) * P2_5; + i += 16; + eph.omg = getbits(rtcm->buff, i, 32) * P2_31 * SC2RAD; + i += 32; + eph.OMGd = getbits(rtcm->buff, i, 24) * P2_43 * SC2RAD; + i += 24; + eph.idot = getbits(rtcm->buff, i, 14) * P2_43 * SC2RAD; + i += 14; + eph.code = getbitu(rtcm->buff, i, 2); + i += 2; + week = getbitu(rtcm->buff, i, 10); + i += 10; + eph.sva = getbitu(rtcm->buff, i, 4); + i += 4; + eph.svh = getbitu(rtcm->buff, i, 6); + i += 6; + eph.tgd[0] = getbits(rtcm->buff, i, 8) * P2_31; + i += 8; + eph.iodc = getbitu(rtcm->buff, i, 10); + i += 10; + eph.fit = getbitu(rtcm->buff, i, 1) ? 4 : 2; /* 0:2hr,1:>2hr */ + } else { + trace(2, "rtcm3 1044 length error: len=%d\n", rtcm->len); + return -1; + } + trace(4, "decode_type1044: prn=%d iode=%d toe=%.0f\n", prn, eph.iode, eph.toes); + + if (rtcm->outtype) { + msg = rtcm->msgtype + strlen(rtcm->msgtype); + sprintf(msg, " prn=%3d iode=%3d iodc=%3d week=%d toe=%6.0f toc=%6.0f svh=%02X", prn, eph.iode, + eph.iodc, week, eph.toes, toc, eph.svh); + } + if (!(sat = satno(sys, prn))) { + trace(2, "rtcm3 1044 satellite number error: prn=%d\n", prn); + return -1; + } + eph.sat = sat; + eph.week = adjgpsweek(week); + if (rtcm->time.time == 0) rtcm->time = utc2gpst(timeget()); + tt = timediff(gpst2time(eph.week, eph.toes), rtcm->time); + if (tt < -302400.0) + eph.week++; + else if (tt >= 302400.0) + eph.week--; + eph.toe = gpst2time(eph.week, eph.toes); + eph.toc = gpst2time(eph.week, toc); + eph.ttr = rtcm->time; + eph.A = sqrtA * sqrtA; + eph.flag = 1; /* fixed to 1 */ + if (!strstr(rtcm->opt, "-EPHALL")) { + if (eph.iode == rtcm->nav.eph[sat - 1].iode && eph.iodc == rtcm->nav.eph[sat - 1].iodc) + return 0; /* unchanged */ + } + rtcm->nav.eph[sat - 1] = eph; + rtcm->ephsat = sat; + rtcm->ephset = 0; + return 2; } /* decode type 1045: Galileo F/NAV satellite ephemerides ---------------------*/ -static int decode_type1045(rtcm_t *rtcm) -{ - eph_t eph={0}; - double toc,sqrtA,tt; - char *msg; - int i=24+12,prn,sat,week,e5a_hs,e5a_dvs,rsv,sys=SYS_GAL; - - if (strstr(rtcm->opt,"-GALINAV")) return 0; - - if (i+484<=rtcm->len*8) { - prn =getbitu(rtcm->buff,i, 6); i+= 6; - week =getbitu(rtcm->buff,i,12); i+=12; /* gst-week */ - eph.iode =getbitu(rtcm->buff,i,10); i+=10; - eph.sva =getbitu(rtcm->buff,i, 8); i+= 8; - eph.idot =getbits(rtcm->buff,i,14)*P2_43*SC2RAD; i+=14; - toc =getbitu(rtcm->buff,i,14)*60.0; i+=14; - eph.f2 =getbits(rtcm->buff,i, 6)*P2_59; i+= 6; - eph.f1 =getbits(rtcm->buff,i,21)*P2_46; i+=21; - eph.f0 =getbits(rtcm->buff,i,31)*P2_34; i+=31; - eph.crs =getbits(rtcm->buff,i,16)*P2_5; i+=16; - eph.deln =getbits(rtcm->buff,i,16)*P2_43*SC2RAD; i+=16; - eph.M0 =getbits(rtcm->buff,i,32)*P2_31*SC2RAD; i+=32; - eph.cuc =getbits(rtcm->buff,i,16)*P2_29; i+=16; - eph.e =getbitu(rtcm->buff,i,32)*P2_33; i+=32; - eph.cus =getbits(rtcm->buff,i,16)*P2_29; i+=16; - sqrtA =getbitu(rtcm->buff,i,32)*P2_19; i+=32; - eph.toes =getbitu(rtcm->buff,i,14)*60.0; i+=14; - eph.cic =getbits(rtcm->buff,i,16)*P2_29; i+=16; - eph.OMG0 =getbits(rtcm->buff,i,32)*P2_31*SC2RAD; i+=32; - eph.cis =getbits(rtcm->buff,i,16)*P2_29; i+=16; - eph.i0 =getbits(rtcm->buff,i,32)*P2_31*SC2RAD; i+=32; - eph.crc =getbits(rtcm->buff,i,16)*P2_5; i+=16; - eph.omg =getbits(rtcm->buff,i,32)*P2_31*SC2RAD; i+=32; - eph.OMGd =getbits(rtcm->buff,i,24)*P2_43*SC2RAD; i+=24; - eph.tgd[0]=getbits(rtcm->buff,i,10)*P2_32; i+=10; /* E5a/E1 */ - e5a_hs =getbitu(rtcm->buff,i, 2); i+= 2; /* OSHS */ - e5a_dvs =getbitu(rtcm->buff,i, 1); i+= 1; /* OSDVS */ - rsv =getbitu(rtcm->buff,i, 7); - } - else { - trace(2,"rtcm3 1045 length error: len=%d\n",rtcm->len); - return -1; - } - trace(4,"decode_type1045: prn=%d iode=%d toe=%.0f\n",prn,eph.iode,eph.toes); - - if (rtcm->outtype) { - msg=rtcm->msgtype+strlen(rtcm->msgtype); - sprintf(msg," prn=%2d iode=%3d week=%d toe=%6.0f toc=%6.0f hs=%d dvs=%d", - prn,eph.iode,week,eph.toes,toc,e5a_hs,e5a_dvs); - } - if (!(sat=satno(sys,prn))) { - trace(2,"rtcm3 1045 satellite number error: prn=%d\n",prn); - return -1; - } - if (strstr(rtcm->opt,"-GALINAV")) { - return 0; - } - eph.sat=sat; - eph.week=week+1024; /* gal-week = gst-week + 1024 */ - if (rtcm->time.time==0) rtcm->time=utc2gpst(timeget()); - tt=timediff(gpst2time(eph.week,eph.toes),rtcm->time); - if (tt<-302400.0) eph.week++; - else if (tt>=302400.0) eph.week--; - eph.toe=gpst2time(eph.week,eph.toes); - eph.toc=gpst2time(eph.week,toc); - eph.ttr=rtcm->time; - eph.A=sqrtA*sqrtA; - eph.svh=(e5a_hs<<4)+(e5a_dvs<<3); - eph.code=(1<<1)+(1<<8); /* data source = F/NAV+E5a */ - eph.iodc=eph.iode; - if (!strstr(rtcm->opt,"-EPHALL")) { - if (eph.iode==rtcm->nav.eph[sat-1+MAXSAT].iode) return 0; /* unchanged */ - } - rtcm->nav.eph[sat-1+MAXSAT]=eph; - rtcm->ephsat=sat; - rtcm->ephset=1; /* F/NAV */ - return 2; +static int decode_type1045(rtcm_t *rtcm) { + eph_t eph = {0}; + double toc, sqrtA, tt; + char *msg; + int i = 24 + 12, prn, sat, week, e5a_hs, e5a_dvs, rsv, sys = SYS_GAL; + + if (strstr(rtcm->opt, "-GALINAV")) return 0; + + if (i + 484 <= rtcm->len * 8) { + prn = getbitu(rtcm->buff, i, 6); + i += 6; + week = getbitu(rtcm->buff, i, 12); + i += 12; /* gst-week */ + eph.iode = getbitu(rtcm->buff, i, 10); + i += 10; + eph.sva = getbitu(rtcm->buff, i, 8); + i += 8; + eph.idot = getbits(rtcm->buff, i, 14) * P2_43 * SC2RAD; + i += 14; + toc = getbitu(rtcm->buff, i, 14) * 60.0; + i += 14; + eph.f2 = getbits(rtcm->buff, i, 6) * P2_59; + i += 6; + eph.f1 = getbits(rtcm->buff, i, 21) * P2_46; + i += 21; + eph.f0 = getbits(rtcm->buff, i, 31) * P2_34; + i += 31; + eph.crs = getbits(rtcm->buff, i, 16) * P2_5; + i += 16; + eph.deln = getbits(rtcm->buff, i, 16) * P2_43 * SC2RAD; + i += 16; + eph.M0 = getbits(rtcm->buff, i, 32) * P2_31 * SC2RAD; + i += 32; + eph.cuc = getbits(rtcm->buff, i, 16) * P2_29; + i += 16; + eph.e = getbitu(rtcm->buff, i, 32) * P2_33; + i += 32; + eph.cus = getbits(rtcm->buff, i, 16) * P2_29; + i += 16; + sqrtA = getbitu(rtcm->buff, i, 32) * P2_19; + i += 32; + eph.toes = getbitu(rtcm->buff, i, 14) * 60.0; + i += 14; + eph.cic = getbits(rtcm->buff, i, 16) * P2_29; + i += 16; + eph.OMG0 = getbits(rtcm->buff, i, 32) * P2_31 * SC2RAD; + i += 32; + eph.cis = getbits(rtcm->buff, i, 16) * P2_29; + i += 16; + eph.i0 = getbits(rtcm->buff, i, 32) * P2_31 * SC2RAD; + i += 32; + eph.crc = getbits(rtcm->buff, i, 16) * P2_5; + i += 16; + eph.omg = getbits(rtcm->buff, i, 32) * P2_31 * SC2RAD; + i += 32; + eph.OMGd = getbits(rtcm->buff, i, 24) * P2_43 * SC2RAD; + i += 24; + eph.tgd[0] = getbits(rtcm->buff, i, 10) * P2_32; + i += 10; /* E5a/E1 */ + e5a_hs = getbitu(rtcm->buff, i, 2); + i += 2; /* OSHS */ + e5a_dvs = getbitu(rtcm->buff, i, 1); + i += 1; /* OSDVS */ + rsv = getbitu(rtcm->buff, i, 7); + } else { + trace(2, "rtcm3 1045 length error: len=%d\n", rtcm->len); + return -1; + } + trace(4, "decode_type1045: prn=%d iode=%d toe=%.0f\n", prn, eph.iode, eph.toes); + + if (rtcm->outtype) { + msg = rtcm->msgtype + strlen(rtcm->msgtype); + sprintf(msg, " prn=%2d iode=%3d week=%d toe=%6.0f toc=%6.0f hs=%d dvs=%d", prn, eph.iode, week, + eph.toes, toc, e5a_hs, e5a_dvs); + } + if (!(sat = satno(sys, prn))) { + trace(2, "rtcm3 1045 satellite number error: prn=%d\n", prn); + return -1; + } + if (strstr(rtcm->opt, "-GALINAV")) { + return 0; + } + eph.sat = sat; + eph.week = week + 1024; /* gal-week = gst-week + 1024 */ + if (rtcm->time.time == 0) rtcm->time = utc2gpst(timeget()); + tt = timediff(gpst2time(eph.week, eph.toes), rtcm->time); + if (tt < -302400.0) + eph.week++; + else if (tt >= 302400.0) + eph.week--; + eph.toe = gpst2time(eph.week, eph.toes); + eph.toc = gpst2time(eph.week, toc); + eph.ttr = rtcm->time; + eph.A = sqrtA * sqrtA; + eph.svh = (e5a_hs << 4) + (e5a_dvs << 3); + eph.code = (1 << 1) + (1 << 8); /* data source = F/NAV+E5a */ + eph.iodc = eph.iode; + if (!strstr(rtcm->opt, "-EPHALL")) { + if (eph.iode == rtcm->nav.eph[sat - 1 + MAXSAT].iode) return 0; /* unchanged */ + } + rtcm->nav.eph[sat - 1 + MAXSAT] = eph; + rtcm->ephsat = sat; + rtcm->ephset = 1; /* F/NAV */ + return 2; } /* decode type 1046: Galileo I/NAV satellite ephemerides ---------------------*/ -static int decode_type1046(rtcm_t *rtcm) -{ - eph_t eph={0}; - double toc,sqrtA,tt; - char *msg; - int i=24+12,prn,sat,week,e5b_hs,e5b_dvs,e1_hs,e1_dvs,sys=SYS_GAL; - - if (strstr(rtcm->opt,"-GALFNAV")) return 0; - - if (i+492<=rtcm->len*8) { - prn =getbitu(rtcm->buff,i, 6); i+= 6; - week =getbitu(rtcm->buff,i,12); i+=12; - eph.iode =getbitu(rtcm->buff,i,10); i+=10; - eph.sva =getbitu(rtcm->buff,i, 8); i+= 8; - eph.idot =getbits(rtcm->buff,i,14)*P2_43*SC2RAD; i+=14; - toc =getbitu(rtcm->buff,i,14)*60.0; i+=14; - eph.f2 =getbits(rtcm->buff,i, 6)*P2_59; i+= 6; - eph.f1 =getbits(rtcm->buff,i,21)*P2_46; i+=21; - eph.f0 =getbits(rtcm->buff,i,31)*P2_34; i+=31; - eph.crs =getbits(rtcm->buff,i,16)*P2_5; i+=16; - eph.deln =getbits(rtcm->buff,i,16)*P2_43*SC2RAD; i+=16; - eph.M0 =getbits(rtcm->buff,i,32)*P2_31*SC2RAD; i+=32; - eph.cuc =getbits(rtcm->buff,i,16)*P2_29; i+=16; - eph.e =getbitu(rtcm->buff,i,32)*P2_33; i+=32; - eph.cus =getbits(rtcm->buff,i,16)*P2_29; i+=16; - sqrtA =getbitu(rtcm->buff,i,32)*P2_19; i+=32; - eph.toes =getbitu(rtcm->buff,i,14)*60.0; i+=14; - eph.cic =getbits(rtcm->buff,i,16)*P2_29; i+=16; - eph.OMG0 =getbits(rtcm->buff,i,32)*P2_31*SC2RAD; i+=32; - eph.cis =getbits(rtcm->buff,i,16)*P2_29; i+=16; - eph.i0 =getbits(rtcm->buff,i,32)*P2_31*SC2RAD; i+=32; - eph.crc =getbits(rtcm->buff,i,16)*P2_5; i+=16; - eph.omg =getbits(rtcm->buff,i,32)*P2_31*SC2RAD; i+=32; - eph.OMGd =getbits(rtcm->buff,i,24)*P2_43*SC2RAD; i+=24; - eph.tgd[0]=getbits(rtcm->buff,i,10)*P2_32; i+=10; /* E5a/E1 */ - eph.tgd[1]=getbits(rtcm->buff,i,10)*P2_32; i+=10; /* E5b/E1 */ - e5b_hs =getbitu(rtcm->buff,i, 2); i+= 2; /* E5b OSHS */ - e5b_dvs =getbitu(rtcm->buff,i, 1); i+= 1; /* E5b OSDVS */ - e1_hs =getbitu(rtcm->buff,i, 2); i+= 2; /* E1 OSHS */ - e1_dvs =getbitu(rtcm->buff,i, 1); i+= 1; /* E1 OSDVS */ - } - else { - trace(2,"rtcm3 1046 length error: len=%d\n",rtcm->len); - return -1; - } - trace(4,"decode_type1046: prn=%d iode=%d toe=%.0f\n",prn,eph.iode,eph.toes); - - if (rtcm->outtype) { - msg=rtcm->msgtype+strlen(rtcm->msgtype); - sprintf(msg," prn=%2d iode=%3d week=%d toe=%6.0f toc=%6.0f hs=%d %d dvs=%d %d", - prn,eph.iode,week,eph.toes,toc,e5b_hs,e1_hs,e5b_dvs,e1_dvs); - } - if (!(sat=satno(sys,prn))) { - trace(2,"rtcm3 1046 satellite number error: prn=%d\n",prn); - return -1; - } - if (strstr(rtcm->opt,"-GALFNAV")) { - return 0; - } - eph.sat=sat; - eph.week=week+1024; /* gal-week = gst-week + 1024 */ - if (rtcm->time.time==0) rtcm->time=utc2gpst(timeget()); - tt=timediff(gpst2time(eph.week,eph.toes),rtcm->time); - if (tt<-302400.0) eph.week++; - else if (tt>=302400.0) eph.week--; - eph.toe=gpst2time(eph.week,eph.toes); - eph.toc=gpst2time(eph.week,toc); - eph.ttr=rtcm->time; - eph.A=sqrtA*sqrtA; - eph.svh=(e5b_hs<<7)+(e5b_dvs<<6)+(e1_hs<<1)+(e1_dvs<<0); - eph.code=(1<<0)+(1<<2)+(1<<9); /* data source = I/NAV+E1+E5b */ - eph.iodc=eph.iode; - if (!strstr(rtcm->opt,"-EPHALL")) { - if (eph.iode==rtcm->nav.eph[sat-1].iode) return 0; /* unchanged */ - } - rtcm->nav.eph[sat-1]=eph; - rtcm->ephsat=sat; - rtcm->ephset=0; /* I/NAV */ - return 2; +static int decode_type1046(rtcm_t *rtcm) { + eph_t eph = {0}; + double toc, sqrtA, tt; + char *msg; + int i = 24 + 12, prn, sat, week, e5b_hs, e5b_dvs, e1_hs, e1_dvs, sys = SYS_GAL; + + if (strstr(rtcm->opt, "-GALFNAV")) return 0; + + if (i + 492 <= rtcm->len * 8) { + prn = getbitu(rtcm->buff, i, 6); + i += 6; + week = getbitu(rtcm->buff, i, 12); + i += 12; + eph.iode = getbitu(rtcm->buff, i, 10); + i += 10; + eph.sva = getbitu(rtcm->buff, i, 8); + i += 8; + eph.idot = getbits(rtcm->buff, i, 14) * P2_43 * SC2RAD; + i += 14; + toc = getbitu(rtcm->buff, i, 14) * 60.0; + i += 14; + eph.f2 = getbits(rtcm->buff, i, 6) * P2_59; + i += 6; + eph.f1 = getbits(rtcm->buff, i, 21) * P2_46; + i += 21; + eph.f0 = getbits(rtcm->buff, i, 31) * P2_34; + i += 31; + eph.crs = getbits(rtcm->buff, i, 16) * P2_5; + i += 16; + eph.deln = getbits(rtcm->buff, i, 16) * P2_43 * SC2RAD; + i += 16; + eph.M0 = getbits(rtcm->buff, i, 32) * P2_31 * SC2RAD; + i += 32; + eph.cuc = getbits(rtcm->buff, i, 16) * P2_29; + i += 16; + eph.e = getbitu(rtcm->buff, i, 32) * P2_33; + i += 32; + eph.cus = getbits(rtcm->buff, i, 16) * P2_29; + i += 16; + sqrtA = getbitu(rtcm->buff, i, 32) * P2_19; + i += 32; + eph.toes = getbitu(rtcm->buff, i, 14) * 60.0; + i += 14; + eph.cic = getbits(rtcm->buff, i, 16) * P2_29; + i += 16; + eph.OMG0 = getbits(rtcm->buff, i, 32) * P2_31 * SC2RAD; + i += 32; + eph.cis = getbits(rtcm->buff, i, 16) * P2_29; + i += 16; + eph.i0 = getbits(rtcm->buff, i, 32) * P2_31 * SC2RAD; + i += 32; + eph.crc = getbits(rtcm->buff, i, 16) * P2_5; + i += 16; + eph.omg = getbits(rtcm->buff, i, 32) * P2_31 * SC2RAD; + i += 32; + eph.OMGd = getbits(rtcm->buff, i, 24) * P2_43 * SC2RAD; + i += 24; + eph.tgd[0] = getbits(rtcm->buff, i, 10) * P2_32; + i += 10; /* E5a/E1 */ + eph.tgd[1] = getbits(rtcm->buff, i, 10) * P2_32; + i += 10; /* E5b/E1 */ + e5b_hs = getbitu(rtcm->buff, i, 2); + i += 2; /* E5b OSHS */ + e5b_dvs = getbitu(rtcm->buff, i, 1); + i += 1; /* E5b OSDVS */ + e1_hs = getbitu(rtcm->buff, i, 2); + i += 2; /* E1 OSHS */ + e1_dvs = getbitu(rtcm->buff, i, 1); + i += 1; /* E1 OSDVS */ + } else { + trace(2, "rtcm3 1046 length error: len=%d\n", rtcm->len); + return -1; + } + trace(4, "decode_type1046: prn=%d iode=%d toe=%.0f\n", prn, eph.iode, eph.toes); + + if (rtcm->outtype) { + msg = rtcm->msgtype + strlen(rtcm->msgtype); + sprintf(msg, " prn=%2d iode=%3d week=%d toe=%6.0f toc=%6.0f hs=%d %d dvs=%d %d", prn, eph.iode, + week, eph.toes, toc, e5b_hs, e1_hs, e5b_dvs, e1_dvs); + } + if (!(sat = satno(sys, prn))) { + trace(2, "rtcm3 1046 satellite number error: prn=%d\n", prn); + return -1; + } + if (strstr(rtcm->opt, "-GALFNAV")) { + return 0; + } + eph.sat = sat; + eph.week = week + 1024; /* gal-week = gst-week + 1024 */ + if (rtcm->time.time == 0) rtcm->time = utc2gpst(timeget()); + tt = timediff(gpst2time(eph.week, eph.toes), rtcm->time); + if (tt < -302400.0) + eph.week++; + else if (tt >= 302400.0) + eph.week--; + eph.toe = gpst2time(eph.week, eph.toes); + eph.toc = gpst2time(eph.week, toc); + eph.ttr = rtcm->time; + eph.A = sqrtA * sqrtA; + eph.svh = (e5b_hs << 7) + (e5b_dvs << 6) + (e1_hs << 1) + (e1_dvs << 0); + eph.code = (1 << 0) + (1 << 2) + (1 << 9); /* data source = I/NAV+E1+E5b */ + eph.iodc = eph.iode; + if (!strstr(rtcm->opt, "-EPHALL")) { + if (eph.iode == rtcm->nav.eph[sat - 1].iode) return 0; /* unchanged */ + } + rtcm->nav.eph[sat - 1] = eph; + rtcm->ephsat = sat; + rtcm->ephset = 0; /* I/NAV */ + return 2; } /* decode type 1042/63: Beidou ephemerides -----------------------------------*/ -static int decode_type1042(rtcm_t *rtcm) -{ - eph_t eph={0}; - double toc,sqrtA,tt; - char *msg; - int i=24+12,prn,sat,week,sys=SYS_CMP; - - if (i+499<=rtcm->len*8) { - prn =getbitu(rtcm->buff,i, 6); i+= 6; - week =getbitu(rtcm->buff,i,13); i+=13; - eph.sva =getbitu(rtcm->buff,i, 4); i+= 4; - eph.idot =getbits(rtcm->buff,i,14)*P2_43*SC2RAD; i+=14; - eph.iode =getbitu(rtcm->buff,i, 5); i+= 5; /* AODE */ - toc =getbitu(rtcm->buff,i,17)*8.0; i+=17; - eph.f2 =getbits(rtcm->buff,i,11)*P2_66; i+=11; - eph.f1 =getbits(rtcm->buff,i,22)*P2_50; i+=22; - eph.f0 =getbits(rtcm->buff,i,24)*P2_33; i+=24; - eph.iodc =getbitu(rtcm->buff,i, 5); i+= 5; /* AODC */ - eph.crs =getbits(rtcm->buff,i,18)*P2_6; i+=18; - eph.deln =getbits(rtcm->buff,i,16)*P2_43*SC2RAD; i+=16; - eph.M0 =getbits(rtcm->buff,i,32)*P2_31*SC2RAD; i+=32; - eph.cuc =getbits(rtcm->buff,i,18)*P2_31; i+=18; - eph.e =getbitu(rtcm->buff,i,32)*P2_33; i+=32; - eph.cus =getbits(rtcm->buff,i,18)*P2_31; i+=18; - sqrtA =getbitu(rtcm->buff,i,32)*P2_19; i+=32; - eph.toes =getbitu(rtcm->buff,i,17)*8.0; i+=17; - eph.cic =getbits(rtcm->buff,i,18)*P2_31; i+=18; - eph.OMG0 =getbits(rtcm->buff,i,32)*P2_31*SC2RAD; i+=32; - eph.cis =getbits(rtcm->buff,i,18)*P2_31; i+=18; - eph.i0 =getbits(rtcm->buff,i,32)*P2_31*SC2RAD; i+=32; - eph.crc =getbits(rtcm->buff,i,18)*P2_6; i+=18; - eph.omg =getbits(rtcm->buff,i,32)*P2_31*SC2RAD; i+=32; - eph.OMGd =getbits(rtcm->buff,i,24)*P2_43*SC2RAD; i+=24; - eph.tgd[0]=getbits(rtcm->buff,i,10)*1E-10; i+=10; - eph.tgd[1]=getbits(rtcm->buff,i,10)*1E-10; i+=10; - eph.svh =getbitu(rtcm->buff,i, 1); i+= 1; - } - else { - trace(2,"rtcm3 1042 length error: len=%d\n",rtcm->len); - return -1; - } - trace(4,"decode_type1042: prn=%d iode=%d toe=%.0f\n",prn,eph.iode,eph.toes); - - if (rtcm->outtype) { - msg=rtcm->msgtype+strlen(rtcm->msgtype); - sprintf(msg," prn=%2d iode=%3d iodc=%3d week=%d toe=%6.0f toc=%6.0f svh=%02X", - prn,eph.iode,eph.iodc,week,eph.toes,toc,eph.svh); - } - if (!(sat=satno(sys,prn))) { - trace(2,"rtcm3 1042 satellite number error: prn=%d\n",prn); - return -1; - } - eph.sat=sat; - eph.week=adjbdtweek(week); - if (rtcm->time.time==0) rtcm->time=utc2gpst(timeget()); - tt=timediff(bdt2gpst(bdt2time(eph.week,eph.toes)),rtcm->time); - if (tt<-302400.0) eph.week++; - else if (tt>=302400.0) eph.week--; - eph.toe=bdt2gpst(bdt2time(eph.week,eph.toes)); /* bdt -> gpst */ - eph.toc=bdt2gpst(bdt2time(eph.week,toc)); /* bdt -> gpst */ - eph.ttr=rtcm->time; - eph.A=sqrtA*sqrtA; - if (!strstr(rtcm->opt,"-EPHALL")) { - if (fabs(timediff(eph.toe,rtcm->nav.eph[sat-1].toe)) < 1.0 && - eph.iode==rtcm->nav.eph[sat-1].iode&& - eph.iodc==rtcm->nav.eph[sat-1].iodc) return 0; /* unchanged */ - } - rtcm->nav.eph[sat-1]=eph; - rtcm->ephset=0; - rtcm->ephsat=sat; - return 2; +static int decode_type1042(rtcm_t *rtcm) { + eph_t eph = {0}; + double toc, sqrtA, tt; + char *msg; + int i = 24 + 12, prn, sat, week, sys = SYS_CMP; + + if (i + 499 <= rtcm->len * 8) { + prn = getbitu(rtcm->buff, i, 6); + i += 6; + week = getbitu(rtcm->buff, i, 13); + i += 13; + eph.sva = getbitu(rtcm->buff, i, 4); + i += 4; + eph.idot = getbits(rtcm->buff, i, 14) * P2_43 * SC2RAD; + i += 14; + eph.iode = getbitu(rtcm->buff, i, 5); + i += 5; /* AODE */ + toc = getbitu(rtcm->buff, i, 17) * 8.0; + i += 17; + eph.f2 = getbits(rtcm->buff, i, 11) * P2_66; + i += 11; + eph.f1 = getbits(rtcm->buff, i, 22) * P2_50; + i += 22; + eph.f0 = getbits(rtcm->buff, i, 24) * P2_33; + i += 24; + eph.iodc = getbitu(rtcm->buff, i, 5); + i += 5; /* AODC */ + eph.crs = getbits(rtcm->buff, i, 18) * P2_6; + i += 18; + eph.deln = getbits(rtcm->buff, i, 16) * P2_43 * SC2RAD; + i += 16; + eph.M0 = getbits(rtcm->buff, i, 32) * P2_31 * SC2RAD; + i += 32; + eph.cuc = getbits(rtcm->buff, i, 18) * P2_31; + i += 18; + eph.e = getbitu(rtcm->buff, i, 32) * P2_33; + i += 32; + eph.cus = getbits(rtcm->buff, i, 18) * P2_31; + i += 18; + sqrtA = getbitu(rtcm->buff, i, 32) * P2_19; + i += 32; + eph.toes = getbitu(rtcm->buff, i, 17) * 8.0; + i += 17; + eph.cic = getbits(rtcm->buff, i, 18) * P2_31; + i += 18; + eph.OMG0 = getbits(rtcm->buff, i, 32) * P2_31 * SC2RAD; + i += 32; + eph.cis = getbits(rtcm->buff, i, 18) * P2_31; + i += 18; + eph.i0 = getbits(rtcm->buff, i, 32) * P2_31 * SC2RAD; + i += 32; + eph.crc = getbits(rtcm->buff, i, 18) * P2_6; + i += 18; + eph.omg = getbits(rtcm->buff, i, 32) * P2_31 * SC2RAD; + i += 32; + eph.OMGd = getbits(rtcm->buff, i, 24) * P2_43 * SC2RAD; + i += 24; + eph.tgd[0] = getbits(rtcm->buff, i, 10) * 1E-10; + i += 10; + eph.tgd[1] = getbits(rtcm->buff, i, 10) * 1E-10; + i += 10; + eph.svh = getbitu(rtcm->buff, i, 1); + i += 1; + } else { + trace(2, "rtcm3 1042 length error: len=%d\n", rtcm->len); + return -1; + } + trace(4, "decode_type1042: prn=%d iode=%d toe=%.0f\n", prn, eph.iode, eph.toes); + + if (rtcm->outtype) { + msg = rtcm->msgtype + strlen(rtcm->msgtype); + sprintf(msg, " prn=%2d iode=%3d iodc=%3d week=%d toe=%6.0f toc=%6.0f svh=%02X", prn, eph.iode, + eph.iodc, week, eph.toes, toc, eph.svh); + } + if (!(sat = satno(sys, prn))) { + trace(2, "rtcm3 1042 satellite number error: prn=%d\n", prn); + return -1; + } + eph.sat = sat; + eph.week = adjbdtweek(week); + if (rtcm->time.time == 0) rtcm->time = utc2gpst(timeget()); + tt = timediff(bdt2gpst(bdt2time(eph.week, eph.toes)), rtcm->time); + if (tt < -302400.0) + eph.week++; + else if (tt >= 302400.0) + eph.week--; + eph.toe = bdt2gpst(bdt2time(eph.week, eph.toes)); /* bdt -> gpst */ + eph.toc = bdt2gpst(bdt2time(eph.week, toc)); /* bdt -> gpst */ + eph.ttr = rtcm->time; + eph.A = sqrtA * sqrtA; + if (!strstr(rtcm->opt, "-EPHALL")) { + if (fabs(timediff(eph.toe, rtcm->nav.eph[sat - 1].toe)) < 1.0 && + eph.iode == rtcm->nav.eph[sat - 1].iode && eph.iodc == rtcm->nav.eph[sat - 1].iodc) + return 0; /* unchanged */ + } + rtcm->nav.eph[sat - 1] = eph; + rtcm->ephset = 0; + rtcm->ephsat = sat; + return 2; } /* decode SSR message epoch time ---------------------------------------------*/ -static int decode_ssr_epoch(rtcm_t *rtcm, int sys, int subtype) -{ - double tod,tow; - int i=24+12; - - if (subtype==0) { /* RTCM SSR */ - - if (sys==SYS_GLO) { - tod=getbitu(rtcm->buff,i,17); i+=17; - adjday_glot(rtcm,tod); - } - else { - tow=getbitu(rtcm->buff,i,20); i+=20; - adjweek(rtcm,tow); - } - } - else { /* IGS SSR */ - i+=3+8; - tow=getbitu(rtcm->buff,i,20); i+=20; - adjweek(rtcm,tow); - } - return i; +static int decode_ssr_epoch(rtcm_t *rtcm, int sys, int subtype) { + double tod, tow; + int i = 24 + 12; + + if (subtype == 0) { /* RTCM SSR */ + + if (sys == SYS_GLO) { + tod = getbitu(rtcm->buff, i, 17); + i += 17; + adjday_glot(rtcm, tod); + } else { + tow = getbitu(rtcm->buff, i, 20); + i += 20; + adjweek(rtcm, tow); + } + } else { /* IGS SSR */ + i += 3 + 8; + tow = getbitu(rtcm->buff, i, 20); + i += 20; + adjweek(rtcm, tow); + } + return i; } /* decode SSR 1,4 message header ---------------------------------------------*/ -static int decode_ssr1_head(rtcm_t *rtcm, int sys, int subtype, int *sync, - int *iod, double *udint, int *refd, int *hsize) -{ - char *msg,tstr[40]; - int i=24+12,nsat,udi,provid=0,solid=0,ns; - - if (subtype==0) { /* RTCM SSR */ - ns=(sys==SYS_QZS)?4:6; - if (i+((sys==SYS_GLO)?53:50+ns)>rtcm->len*8) return -1; - } - else { /* IGS SSR */ - ns=6; - if (i+3+8+50+ns>rtcm->len*8) return -1; - } - i=decode_ssr_epoch(rtcm,sys,subtype); - udi =getbitu(rtcm->buff,i, 4); i+= 4; - *sync =getbitu(rtcm->buff,i, 1); i+= 1; - if (subtype==0) { /* RTCM SSR */ - *refd =getbitu(rtcm->buff,i, 1); i+= 1; /* satellite ref datum */ - } - *iod =getbitu(rtcm->buff,i, 4); i+= 4; /* IOD SSR */ - provid=getbitu(rtcm->buff,i,16); i+=16; /* provider ID */ - solid =getbitu(rtcm->buff,i, 4); i+= 4; /* solution ID */ - if (subtype>0) { /* IGS SSR */ - *refd=getbitu(rtcm->buff,i,1); i+=1; /* global/regional CRS indicator */ - } - nsat =getbitu(rtcm->buff,i,ns); i+=ns; - *udint=ssrudint[udi]; - - time2str(rtcm->time,tstr,2); - trace(4,"decode_ssr1_head: time=%s sys=%d subtype=%d nsat=%d sync=%d iod=%d" - " provid=%d solid=%d\n",tstr,sys,subtype,nsat,*sync,*iod,provid,solid); - - if (rtcm->outtype) { - msg=rtcm->msgtype+strlen(rtcm->msgtype); - sprintf(msg," %s nsat=%2d iod=%2d udi=%2d sync=%d",tstr,nsat,*iod,udi, - *sync); - } - *hsize=i; - return nsat; +static int decode_ssr1_head(rtcm_t *rtcm, int sys, int subtype, int *sync, int *iod, double *udint, + int *refd, int *hsize) { + char *msg, tstr[40]; + int i = 24 + 12, nsat, udi, provid = 0, solid = 0, ns; + + if (subtype == 0) { /* RTCM SSR */ + ns = (sys == SYS_QZS) ? 4 : 6; + if (i + ((sys == SYS_GLO) ? 53 : 50 + ns) > rtcm->len * 8) return -1; + } else { /* IGS SSR */ + ns = 6; + if (i + 3 + 8 + 50 + ns > rtcm->len * 8) return -1; + } + i = decode_ssr_epoch(rtcm, sys, subtype); + udi = getbitu(rtcm->buff, i, 4); + i += 4; + *sync = getbitu(rtcm->buff, i, 1); + i += 1; + if (subtype == 0) { /* RTCM SSR */ + *refd = getbitu(rtcm->buff, i, 1); + i += 1; /* satellite ref datum */ + } + *iod = getbitu(rtcm->buff, i, 4); + i += 4; /* IOD SSR */ + provid = getbitu(rtcm->buff, i, 16); + i += 16; /* provider ID */ + solid = getbitu(rtcm->buff, i, 4); + i += 4; /* solution ID */ + if (subtype > 0) { /* IGS SSR */ + *refd = getbitu(rtcm->buff, i, 1); + i += 1; /* global/regional CRS indicator */ + } + nsat = getbitu(rtcm->buff, i, ns); + i += ns; + *udint = ssrudint[udi]; + + time2str(rtcm->time, tstr, 2); + trace(4, + "decode_ssr1_head: time=%s sys=%d subtype=%d nsat=%d sync=%d iod=%d" + " provid=%d solid=%d\n", + tstr, sys, subtype, nsat, *sync, *iod, provid, solid); + + if (rtcm->outtype) { + msg = rtcm->msgtype + strlen(rtcm->msgtype); + sprintf(msg, " %s nsat=%2d iod=%2d udi=%2d sync=%d", tstr, nsat, *iod, udi, *sync); + } + *hsize = i; + return nsat; } /* decode SSR 2,3,5,6 message header -----------------------------------------*/ -static int decode_ssr2_head(rtcm_t *rtcm, int sys, int subtype, int *sync, - int *iod, double *udint, int *hsize) -{ - char *msg,tstr[40]; - int i=24+12,nsat,udi,provid=0,solid=0,ns; - - if (subtype==0) { /* RTCM SSR */ - ns=(sys==SYS_QZS)?4:6; - if (i+((sys==SYS_GLO)?52:49+ns)>rtcm->len*8) return -1; - } - else { - ns=6; - if (i+3+8+49+ns>rtcm->len*8) return -1; - } - i=decode_ssr_epoch(rtcm,sys,subtype); - udi =getbitu(rtcm->buff,i, 4); i+= 4; - *sync =getbitu(rtcm->buff,i, 1); i+= 1; - *iod =getbitu(rtcm->buff,i, 4); i+= 4; - provid=getbitu(rtcm->buff,i,16); i+=16; /* provider ID */ - solid =getbitu(rtcm->buff,i, 4); i+= 4; /* solution ID */ - nsat =getbitu(rtcm->buff,i,ns); i+=ns; - *udint=ssrudint[udi]; - - time2str(rtcm->time,tstr,2); - trace(4,"decode_ssr2_head: time=%s sys=%d subtype=%d nsat=%d sync=%d iod=%d" - " provid=%d solid=%d\n",tstr,sys,subtype,nsat,*sync,*iod,provid,solid); - - if (rtcm->outtype) { - msg=rtcm->msgtype+strlen(rtcm->msgtype); - sprintf(msg," %s nsat=%2d iod=%2d udi=%2d sync=%d",tstr,nsat,*iod,udi, - *sync); - } - *hsize=i; - return nsat; +static int decode_ssr2_head(rtcm_t *rtcm, int sys, int subtype, int *sync, int *iod, double *udint, + int *hsize) { + char *msg, tstr[40]; + int i = 24 + 12, nsat, udi, provid = 0, solid = 0, ns; + + if (subtype == 0) { /* RTCM SSR */ + ns = (sys == SYS_QZS) ? 4 : 6; + if (i + ((sys == SYS_GLO) ? 52 : 49 + ns) > rtcm->len * 8) return -1; + } else { + ns = 6; + if (i + 3 + 8 + 49 + ns > rtcm->len * 8) return -1; + } + i = decode_ssr_epoch(rtcm, sys, subtype); + udi = getbitu(rtcm->buff, i, 4); + i += 4; + *sync = getbitu(rtcm->buff, i, 1); + i += 1; + *iod = getbitu(rtcm->buff, i, 4); + i += 4; + provid = getbitu(rtcm->buff, i, 16); + i += 16; /* provider ID */ + solid = getbitu(rtcm->buff, i, 4); + i += 4; /* solution ID */ + nsat = getbitu(rtcm->buff, i, ns); + i += ns; + *udint = ssrudint[udi]; + + time2str(rtcm->time, tstr, 2); + trace(4, + "decode_ssr2_head: time=%s sys=%d subtype=%d nsat=%d sync=%d iod=%d" + " provid=%d solid=%d\n", + tstr, sys, subtype, nsat, *sync, *iod, provid, solid); + + if (rtcm->outtype) { + msg = rtcm->msgtype + strlen(rtcm->msgtype); + sprintf(msg, " %s nsat=%2d iod=%2d udi=%2d sync=%d", tstr, nsat, *iod, udi, *sync); + } + *hsize = i; + return nsat; } /* decode SSR 1: orbit corrections -------------------------------------------*/ -static int decode_ssr1(rtcm_t *rtcm, int sys, int subtype) -{ - double udint,deph[3],ddeph[3]; - int i,j,k,type,sync,iod,nsat,prn,sat,iode,iodcrc=0,refd=0,np,ni,nj,offp; - - type=getbitu(rtcm->buff,24,12); - - if ((nsat=decode_ssr1_head(rtcm,sys,subtype,&sync,&iod,&udint,&refd,&i))<0) { - trace(2,"rtcm3 %d length error: len=%d\n",type,rtcm->len); - return -1; - } - switch (sys) { - case SYS_GPS: np=6; ni= 8; nj= 0; offp= 0; break; - case SYS_GLO: np=5; ni= 8; nj= 0; offp= 0; break; - case SYS_GAL: np=6; ni=10; nj= 0; offp= 0; break; - case SYS_QZS: np=4; ni= 8; nj= 0; offp=192; break; - case SYS_CMP: np=6; ni=10; nj=24; offp= 1; break; - case SYS_SBS: np=6; ni= 9; nj=24; offp=120; break; - default: return sync?0:10; - } - if (subtype>0) { /* IGS SSR */ - np=6; ni=8; nj=0; - if (sys==SYS_CMP) offp=0; - else if (sys==SYS_SBS) offp=119; - } - for (j=0;jlen*8;j++) { - prn =getbitu(rtcm->buff,i,np)+offp; i+=np; - iode =getbitu(rtcm->buff,i,ni); i+=ni; - iodcrc =getbitu(rtcm->buff,i,nj); i+=nj; - deph [0]=getbits(rtcm->buff,i,22)*1E-4; i+=22; - deph [1]=getbits(rtcm->buff,i,20)*4E-4; i+=20; - deph [2]=getbits(rtcm->buff,i,20)*4E-4; i+=20; - ddeph[0]=getbits(rtcm->buff,i,21)*1E-6; i+=21; - ddeph[1]=getbits(rtcm->buff,i,19)*4E-6; i+=19; - ddeph[2]=getbits(rtcm->buff,i,19)*4E-6; i+=19; - - if (!(sat=satno(sys,prn))) { - trace(2,"rtcm3 %d satellite number error: prn=%d\n",type,prn); - continue; - } - rtcm->ssr[sat-1].t0 [0]=rtcm->time; - rtcm->ssr[sat-1].udi[0]=udint; - rtcm->ssr[sat-1].iod[0]=iod; - rtcm->ssr[sat-1].iode=iode; /* SBAS/BDS: toe/t0 modulo */ - rtcm->ssr[sat-1].iodcrc=iodcrc; /* SBAS/BDS: IOD CRC */ - rtcm->ssr[sat-1].refd=refd; - - for (k=0;k<3;k++) { - rtcm->ssr[sat-1].deph [k]=deph [k]; - rtcm->ssr[sat-1].ddeph[k]=ddeph[k]; - } - rtcm->ssr[sat-1].update=1; +static int decode_ssr1(rtcm_t *rtcm, int sys, int subtype) { + double udint, deph[3], ddeph[3]; + int i, j, k, type, sync, iod, nsat, prn, sat, iode, iodcrc = 0, refd = 0, np, ni, nj, offp; + + type = getbitu(rtcm->buff, 24, 12); + + if ((nsat = decode_ssr1_head(rtcm, sys, subtype, &sync, &iod, &udint, &refd, &i)) < 0) { + trace(2, "rtcm3 %d length error: len=%d\n", type, rtcm->len); + return -1; + } + switch (sys) { + case SYS_GPS: + np = 6; + ni = 8; + nj = 0; + offp = 0; + break; + case SYS_GLO: + np = 5; + ni = 8; + nj = 0; + offp = 0; + break; + case SYS_GAL: + np = 6; + ni = 10; + nj = 0; + offp = 0; + break; + case SYS_QZS: + np = 4; + ni = 8; + nj = 0; + offp = 192; + break; + case SYS_CMP: + np = 6; + ni = 10; + nj = 24; + offp = 1; + break; + case SYS_SBS: + np = 6; + ni = 9; + nj = 24; + offp = 120; + break; + default: + return sync ? 0 : 10; + } + if (subtype > 0) { /* IGS SSR */ + np = 6; + ni = 8; + nj = 0; + if (sys == SYS_CMP) + offp = 0; + else if (sys == SYS_SBS) + offp = 119; + } + for (j = 0; j < nsat && i + 121 + np + ni + nj <= rtcm->len * 8; j++) { + prn = getbitu(rtcm->buff, i, np) + offp; + i += np; + iode = getbitu(rtcm->buff, i, ni); + i += ni; + iodcrc = getbitu(rtcm->buff, i, nj); + i += nj; + deph[0] = getbits(rtcm->buff, i, 22) * 1E-4; + i += 22; + deph[1] = getbits(rtcm->buff, i, 20) * 4E-4; + i += 20; + deph[2] = getbits(rtcm->buff, i, 20) * 4E-4; + i += 20; + ddeph[0] = getbits(rtcm->buff, i, 21) * 1E-6; + i += 21; + ddeph[1] = getbits(rtcm->buff, i, 19) * 4E-6; + i += 19; + ddeph[2] = getbits(rtcm->buff, i, 19) * 4E-6; + i += 19; + + if (!(sat = satno(sys, prn))) { + trace(2, "rtcm3 %d satellite number error: prn=%d\n", type, prn); + continue; + } + rtcm->ssr[sat - 1].t0[0] = rtcm->time; + rtcm->ssr[sat - 1].udi[0] = udint; + rtcm->ssr[sat - 1].iod[0] = iod; + rtcm->ssr[sat - 1].iode = iode; /* SBAS/BDS: toe/t0 modulo */ + rtcm->ssr[sat - 1].iodcrc = iodcrc; /* SBAS/BDS: IOD CRC */ + rtcm->ssr[sat - 1].refd = refd; + + for (k = 0; k < 3; k++) { + rtcm->ssr[sat - 1].deph[k] = deph[k]; + rtcm->ssr[sat - 1].ddeph[k] = ddeph[k]; } - return sync?0:10; + rtcm->ssr[sat - 1].update = 1; + } + return sync ? 0 : 10; } /* decode SSR 2: clock corrections -------------------------------------------*/ -static int decode_ssr2(rtcm_t *rtcm, int sys, int subtype) -{ - double udint,dclk[3]; - int i,j,k,type,sync,iod,nsat,prn,sat,np,offp; - - type=getbitu(rtcm->buff,24,12); - - if ((nsat=decode_ssr2_head(rtcm,sys,subtype,&sync,&iod,&udint,&i))<0) { - trace(2,"rtcm3 %d length error: len=%d\n",type,rtcm->len); - return -1; - } - switch (sys) { - case SYS_GPS: np=6; offp= 0; break; - case SYS_GLO: np=5; offp= 0; break; - case SYS_GAL: np=6; offp= 0; break; - case SYS_QZS: np=4; offp=192; break; - case SYS_CMP: np=6; offp= 1; break; - case SYS_SBS: np=6; offp=120; break; - default: return sync?0:10; - } - if (subtype>0) { /* IGS SSR */ - np=6; - if (sys==SYS_CMP) offp=0; - else if (sys==SYS_SBS) offp=119; +static int decode_ssr2(rtcm_t *rtcm, int sys, int subtype) { + double udint, dclk[3]; + int i, j, k, type, sync, iod, nsat, prn, sat, np, offp; + + type = getbitu(rtcm->buff, 24, 12); + + if ((nsat = decode_ssr2_head(rtcm, sys, subtype, &sync, &iod, &udint, &i)) < 0) { + trace(2, "rtcm3 %d length error: len=%d\n", type, rtcm->len); + return -1; + } + switch (sys) { + case SYS_GPS: + np = 6; + offp = 0; + break; + case SYS_GLO: + np = 5; + offp = 0; + break; + case SYS_GAL: + np = 6; + offp = 0; + break; + case SYS_QZS: + np = 4; + offp = 192; + break; + case SYS_CMP: + np = 6; + offp = 1; + break; + case SYS_SBS: + np = 6; + offp = 120; + break; + default: + return sync ? 0 : 10; + } + if (subtype > 0) { /* IGS SSR */ + np = 6; + if (sys == SYS_CMP) + offp = 0; + else if (sys == SYS_SBS) + offp = 119; + } + for (j = 0; j < nsat && i + 70 + np <= rtcm->len * 8; j++) { + prn = getbitu(rtcm->buff, i, np) + offp; + i += np; + dclk[0] = getbits(rtcm->buff, i, 22) * 1E-4; + i += 22; + dclk[1] = getbits(rtcm->buff, i, 21) * 1E-6; + i += 21; + dclk[2] = getbits(rtcm->buff, i, 27) * 2E-8; + i += 27; + + if (!(sat = satno(sys, prn))) { + trace(2, "rtcm3 %d satellite number error: prn=%d\n", type, prn); + continue; } - for (j=0;jlen*8;j++) { - prn =getbitu(rtcm->buff,i,np)+offp; i+=np; - dclk[0]=getbits(rtcm->buff,i,22)*1E-4; i+=22; - dclk[1]=getbits(rtcm->buff,i,21)*1E-6; i+=21; - dclk[2]=getbits(rtcm->buff,i,27)*2E-8; i+=27; - - if (!(sat=satno(sys,prn))) { - trace(2,"rtcm3 %d satellite number error: prn=%d\n",type,prn); - continue; - } - rtcm->ssr[sat-1].t0 [1]=rtcm->time; - rtcm->ssr[sat-1].udi[1]=udint; - rtcm->ssr[sat-1].iod[1]=iod; - - for (k=0;k<3;k++) { - rtcm->ssr[sat-1].dclk[k]=dclk[k]; - } - rtcm->ssr[sat-1].update=1; + rtcm->ssr[sat - 1].t0[1] = rtcm->time; + rtcm->ssr[sat - 1].udi[1] = udint; + rtcm->ssr[sat - 1].iod[1] = iod; + + for (k = 0; k < 3; k++) { + rtcm->ssr[sat - 1].dclk[k] = dclk[k]; } - return sync?0:10; + rtcm->ssr[sat - 1].update = 1; + } + return sync ? 0 : 10; } /* decode SSR 3: satellite code biases ---------------------------------------*/ -static int decode_ssr3(rtcm_t *rtcm, int sys, int subtype) -{ - const uint8_t *sigs; - double udint,bias,cbias[MAXCODE]; - int i,j,k,type,mode,sync,iod,nsat,prn,sat,nbias,np,offp; - - type=getbitu(rtcm->buff,24,12); - - if ((nsat=decode_ssr2_head(rtcm,sys,subtype,&sync,&iod,&udint,&i))<0) { - trace(2,"rtcm3 %d length error: len=%d\n",type,rtcm->len); - return -1; - } - switch (sys) { - case SYS_GPS: np=6; offp= 0; sigs=ssr_sig_gps; break; - case SYS_GLO: np=5; offp= 0; sigs=ssr_sig_glo; break; - case SYS_GAL: np=6; offp= 0; sigs=ssr_sig_gal; break; - case SYS_QZS: np=4; offp=192; sigs=ssr_sig_qzs; break; - case SYS_CMP: np=6; offp= 1; sigs=ssr_sig_cmp; break; - case SYS_SBS: np=6; offp=120; sigs=ssr_sig_sbs; break; - default: return sync?0:10; - } - if (subtype>0) { /* IGS SSR */ - np=6; - if (sys==SYS_CMP) offp=0; - else if (sys==SYS_SBS) offp=119; - } - for (j=0;jlen*8;j++) { - prn =getbitu(rtcm->buff,i,np)+offp; i+=np; - nbias=getbitu(rtcm->buff,i, 5); i+= 5; - - for (k=0;klen*8;k++) { - mode=getbitu(rtcm->buff,i, 5); i+= 5; - bias=getbits(rtcm->buff,i,14)*0.01; i+=14; - if (sigs[mode]) { - cbias[sigs[mode]-1]=bias; - } - else { - trace(2,"rtcm3 %d not supported mode: mode=%d\n",type,mode); - } - } - if (!(sat=satno(sys,prn))) { - trace(2,"rtcm3 %d satellite number error: prn=%d\n",type,prn); - continue; - } - rtcm->ssr[sat-1].t0 [4]=rtcm->time; - rtcm->ssr[sat-1].udi[4]=udint; - rtcm->ssr[sat-1].iod[4]=iod; - - for (k=0;kssr[sat-1].cbias[k]=(float)cbias[k]; - } - rtcm->ssr[sat-1].update=1; +static int decode_ssr3(rtcm_t *rtcm, int sys, int subtype) { + const uint8_t *sigs; + double udint, bias, cbias[MAXCODE]; + int i, j, k, type, mode, sync, iod, nsat, prn, sat, nbias, np, offp; + + type = getbitu(rtcm->buff, 24, 12); + + if ((nsat = decode_ssr2_head(rtcm, sys, subtype, &sync, &iod, &udint, &i)) < 0) { + trace(2, "rtcm3 %d length error: len=%d\n", type, rtcm->len); + return -1; + } + switch (sys) { + case SYS_GPS: + np = 6; + offp = 0; + sigs = ssr_sig_gps; + break; + case SYS_GLO: + np = 5; + offp = 0; + sigs = ssr_sig_glo; + break; + case SYS_GAL: + np = 6; + offp = 0; + sigs = ssr_sig_gal; + break; + case SYS_QZS: + np = 4; + offp = 192; + sigs = ssr_sig_qzs; + break; + case SYS_CMP: + np = 6; + offp = 1; + sigs = ssr_sig_cmp; + break; + case SYS_SBS: + np = 6; + offp = 120; + sigs = ssr_sig_sbs; + break; + default: + return sync ? 0 : 10; + } + if (subtype > 0) { /* IGS SSR */ + np = 6; + if (sys == SYS_CMP) + offp = 0; + else if (sys == SYS_SBS) + offp = 119; + } + for (j = 0; j < nsat && i + 5 + np <= rtcm->len * 8; j++) { + prn = getbitu(rtcm->buff, i, np) + offp; + i += np; + nbias = getbitu(rtcm->buff, i, 5); + i += 5; + + for (k = 0; k < MAXCODE; k++) cbias[k] = 0.0; + for (k = 0; k < nbias && i + 19 <= rtcm->len * 8; k++) { + mode = getbitu(rtcm->buff, i, 5); + i += 5; + bias = getbits(rtcm->buff, i, 14) * 0.01; + i += 14; + if (sigs[mode]) { + cbias[sigs[mode] - 1] = bias; + } else { + trace(2, "rtcm3 %d not supported mode: mode=%d\n", type, mode); + } + } + if (!(sat = satno(sys, prn))) { + trace(2, "rtcm3 %d satellite number error: prn=%d\n", type, prn); + continue; + } + rtcm->ssr[sat - 1].t0[4] = rtcm->time; + rtcm->ssr[sat - 1].udi[4] = udint; + rtcm->ssr[sat - 1].iod[4] = iod; + + for (k = 0; k < MAXCODE; k++) { + rtcm->ssr[sat - 1].cbias[k] = (float)cbias[k]; } - return sync?0:10; + rtcm->ssr[sat - 1].update = 1; + } + return sync ? 0 : 10; } /* decode SSR 4: combined orbit and clock corrections ------------------------*/ -static int decode_ssr4(rtcm_t *rtcm, int sys, int subtype) -{ - double udint,deph[3],ddeph[3],dclk[3]; - int i,j,k,type,nsat,sync,iod,prn,sat,iode,iodcrc=0,refd=0,np,ni,nj,offp; - - type=getbitu(rtcm->buff,24,12); - - if ((nsat=decode_ssr1_head(rtcm,sys,subtype,&sync,&iod,&udint,&refd,&i))<0) { - trace(2,"rtcm3 %d length error: len=%d\n",type,rtcm->len); - return -1; - } - switch (sys) { - case SYS_GPS: np=6; ni= 8; nj= 0; offp= 0; break; - case SYS_GLO: np=5; ni= 8; nj= 0; offp= 0; break; - case SYS_GAL: np=6; ni=10; nj= 0; offp= 0; break; - case SYS_QZS: np=4; ni= 8; nj= 0; offp=192; break; - case SYS_CMP: np=6; ni=10; nj=24; offp= 1; break; - case SYS_SBS: np=6; ni= 9; nj=24; offp=120; break; - default: return sync?0:10; - } - if (subtype>0) { /* IGS SSR */ - np=6; ni=8; nj=0; - if (sys==SYS_CMP) offp=0; - else if (sys==SYS_SBS) offp=119; - } - for (j=0;jlen*8;j++) { - prn =getbitu(rtcm->buff,i,np)+offp; i+=np; - iode =getbitu(rtcm->buff,i,ni); i+=ni; - iodcrc =getbitu(rtcm->buff,i,nj); i+=nj; - deph [0]=getbits(rtcm->buff,i,22)*1E-4; i+=22; - deph [1]=getbits(rtcm->buff,i,20)*4E-4; i+=20; - deph [2]=getbits(rtcm->buff,i,20)*4E-4; i+=20; - ddeph[0]=getbits(rtcm->buff,i,21)*1E-6; i+=21; - ddeph[1]=getbits(rtcm->buff,i,19)*4E-6; i+=19; - ddeph[2]=getbits(rtcm->buff,i,19)*4E-6; i+=19; - - dclk [0]=getbits(rtcm->buff,i,22)*1E-4; i+=22; - dclk [1]=getbits(rtcm->buff,i,21)*1E-6; i+=21; - dclk [2]=getbits(rtcm->buff,i,27)*2E-8; i+=27; - - if (!(sat=satno(sys,prn))) { - trace(2,"rtcm3 %d satellite number error: prn=%d\n",type,prn); - continue; - } - rtcm->ssr[sat-1].t0 [0]=rtcm->ssr[sat-1].t0 [1]=rtcm->time; - rtcm->ssr[sat-1].udi[0]=rtcm->ssr[sat-1].udi[1]=udint; - rtcm->ssr[sat-1].iod[0]=rtcm->ssr[sat-1].iod[1]=iod; - rtcm->ssr[sat-1].iode=iode; - rtcm->ssr[sat-1].iodcrc=iodcrc; - rtcm->ssr[sat-1].refd=refd; - - for (k=0;k<3;k++) { - rtcm->ssr[sat-1].deph [k]=deph [k]; - rtcm->ssr[sat-1].ddeph[k]=ddeph[k]; - rtcm->ssr[sat-1].dclk [k]=dclk [k]; - } - rtcm->ssr[sat-1].update=1; +static int decode_ssr4(rtcm_t *rtcm, int sys, int subtype) { + double udint, deph[3], ddeph[3], dclk[3]; + int i, j, k, type, nsat, sync, iod, prn, sat, iode, iodcrc = 0, refd = 0, np, ni, nj, offp; + + type = getbitu(rtcm->buff, 24, 12); + + if ((nsat = decode_ssr1_head(rtcm, sys, subtype, &sync, &iod, &udint, &refd, &i)) < 0) { + trace(2, "rtcm3 %d length error: len=%d\n", type, rtcm->len); + return -1; + } + switch (sys) { + case SYS_GPS: + np = 6; + ni = 8; + nj = 0; + offp = 0; + break; + case SYS_GLO: + np = 5; + ni = 8; + nj = 0; + offp = 0; + break; + case SYS_GAL: + np = 6; + ni = 10; + nj = 0; + offp = 0; + break; + case SYS_QZS: + np = 4; + ni = 8; + nj = 0; + offp = 192; + break; + case SYS_CMP: + np = 6; + ni = 10; + nj = 24; + offp = 1; + break; + case SYS_SBS: + np = 6; + ni = 9; + nj = 24; + offp = 120; + break; + default: + return sync ? 0 : 10; + } + if (subtype > 0) { /* IGS SSR */ + np = 6; + ni = 8; + nj = 0; + if (sys == SYS_CMP) + offp = 0; + else if (sys == SYS_SBS) + offp = 119; + } + for (j = 0; j < nsat && i + 191 + np + ni + nj <= rtcm->len * 8; j++) { + prn = getbitu(rtcm->buff, i, np) + offp; + i += np; + iode = getbitu(rtcm->buff, i, ni); + i += ni; + iodcrc = getbitu(rtcm->buff, i, nj); + i += nj; + deph[0] = getbits(rtcm->buff, i, 22) * 1E-4; + i += 22; + deph[1] = getbits(rtcm->buff, i, 20) * 4E-4; + i += 20; + deph[2] = getbits(rtcm->buff, i, 20) * 4E-4; + i += 20; + ddeph[0] = getbits(rtcm->buff, i, 21) * 1E-6; + i += 21; + ddeph[1] = getbits(rtcm->buff, i, 19) * 4E-6; + i += 19; + ddeph[2] = getbits(rtcm->buff, i, 19) * 4E-6; + i += 19; + + dclk[0] = getbits(rtcm->buff, i, 22) * 1E-4; + i += 22; + dclk[1] = getbits(rtcm->buff, i, 21) * 1E-6; + i += 21; + dclk[2] = getbits(rtcm->buff, i, 27) * 2E-8; + i += 27; + + if (!(sat = satno(sys, prn))) { + trace(2, "rtcm3 %d satellite number error: prn=%d\n", type, prn); + continue; + } + rtcm->ssr[sat - 1].t0[0] = rtcm->ssr[sat - 1].t0[1] = rtcm->time; + rtcm->ssr[sat - 1].udi[0] = rtcm->ssr[sat - 1].udi[1] = udint; + rtcm->ssr[sat - 1].iod[0] = rtcm->ssr[sat - 1].iod[1] = iod; + rtcm->ssr[sat - 1].iode = iode; + rtcm->ssr[sat - 1].iodcrc = iodcrc; + rtcm->ssr[sat - 1].refd = refd; + + for (k = 0; k < 3; k++) { + rtcm->ssr[sat - 1].deph[k] = deph[k]; + rtcm->ssr[sat - 1].ddeph[k] = ddeph[k]; + rtcm->ssr[sat - 1].dclk[k] = dclk[k]; } - return sync?0:10; + rtcm->ssr[sat - 1].update = 1; + } + return sync ? 0 : 10; } /* decode SSR 5: URA ---------------------------------------------------------*/ -static int decode_ssr5(rtcm_t *rtcm, int sys, int subtype) -{ - double udint; - int i,j,type,nsat,sync,iod,prn,sat,ura,np,offp; - - type=getbitu(rtcm->buff,24,12); - - if ((nsat=decode_ssr2_head(rtcm,sys,subtype,&sync,&iod,&udint,&i))<0) { - trace(2,"rtcm3 %d length error: len=%d\n",type,rtcm->len); - return -1; - } - switch (sys) { - case SYS_GPS: np=6; offp= 0; break; - case SYS_GLO: np=5; offp= 0; break; - case SYS_GAL: np=6; offp= 0; break; - case SYS_QZS: np=4; offp=192; break; - case SYS_CMP: np=6; offp= 1; break; - case SYS_SBS: np=6; offp=120; break; - default: return sync?0:10; - } - if (subtype>0) { /* IGS SSR */ - np=6; - if (sys==SYS_CMP) offp=0; - else if (sys==SYS_SBS) offp=119; - } - for (j=0;jlen*8;j++) { - prn=getbitu(rtcm->buff,i,np)+offp; i+=np; - ura=getbitu(rtcm->buff,i, 6); i+= 6; - - if (!(sat=satno(sys,prn))) { - trace(2,"rtcm3 %d satellite number error: prn=%d\n",type,prn); - continue; - } - rtcm->ssr[sat-1].t0 [3]=rtcm->time; - rtcm->ssr[sat-1].udi[3]=udint; - rtcm->ssr[sat-1].iod[3]=iod; - rtcm->ssr[sat-1].ura=ura; - rtcm->ssr[sat-1].update=1; - } - return sync?0:10; +static int decode_ssr5(rtcm_t *rtcm, int sys, int subtype) { + double udint; + int i, j, type, nsat, sync, iod, prn, sat, ura, np, offp; + + type = getbitu(rtcm->buff, 24, 12); + + if ((nsat = decode_ssr2_head(rtcm, sys, subtype, &sync, &iod, &udint, &i)) < 0) { + trace(2, "rtcm3 %d length error: len=%d\n", type, rtcm->len); + return -1; + } + switch (sys) { + case SYS_GPS: + np = 6; + offp = 0; + break; + case SYS_GLO: + np = 5; + offp = 0; + break; + case SYS_GAL: + np = 6; + offp = 0; + break; + case SYS_QZS: + np = 4; + offp = 192; + break; + case SYS_CMP: + np = 6; + offp = 1; + break; + case SYS_SBS: + np = 6; + offp = 120; + break; + default: + return sync ? 0 : 10; + } + if (subtype > 0) { /* IGS SSR */ + np = 6; + if (sys == SYS_CMP) + offp = 0; + else if (sys == SYS_SBS) + offp = 119; + } + for (j = 0; j < nsat && i + 6 + np <= rtcm->len * 8; j++) { + prn = getbitu(rtcm->buff, i, np) + offp; + i += np; + ura = getbitu(rtcm->buff, i, 6); + i += 6; + + if (!(sat = satno(sys, prn))) { + trace(2, "rtcm3 %d satellite number error: prn=%d\n", type, prn); + continue; + } + rtcm->ssr[sat - 1].t0[3] = rtcm->time; + rtcm->ssr[sat - 1].udi[3] = udint; + rtcm->ssr[sat - 1].iod[3] = iod; + rtcm->ssr[sat - 1].ura = ura; + rtcm->ssr[sat - 1].update = 1; + } + return sync ? 0 : 10; } /* decode SSR 6: high rate clock correction ----------------------------------*/ -static int decode_ssr6(rtcm_t *rtcm, int sys, int subtype) -{ - double udint,hrclk; - int i,j,type,nsat,sync,iod,prn,sat,np,offp; - - type=getbitu(rtcm->buff,24,12); - - if ((nsat=decode_ssr2_head(rtcm,sys,subtype,&sync,&iod,&udint,&i))<0) { - trace(2,"rtcm3 %d length error: len=%d\n",type,rtcm->len); - return -1; - } - switch (sys) { - case SYS_GPS: np=6; offp= 0; break; - case SYS_GLO: np=5; offp= 0; break; - case SYS_GAL: np=6; offp= 0; break; - case SYS_QZS: np=4; offp=192; break; - case SYS_CMP: np=6; offp= 1; break; - case SYS_SBS: np=6; offp=120; break; - default: return sync?0:10; - } - if (subtype>0) { /* IGS SSR */ - np=6; - if (sys==SYS_CMP) offp=0; - else if (sys==SYS_SBS) offp=119; - } - for (j=0;jlen*8;j++) { - prn =getbitu(rtcm->buff,i,np)+offp; i+=np; - hrclk=getbits(rtcm->buff,i,22)*1E-4; i+=22; - - if (!(sat=satno(sys,prn))) { - trace(2,"rtcm3 %d satellite number error: prn=%d\n",type,prn); - continue; - } - rtcm->ssr[sat-1].t0 [2]=rtcm->time; - rtcm->ssr[sat-1].udi[2]=udint; - rtcm->ssr[sat-1].iod[2]=iod; - rtcm->ssr[sat-1].hrclk=hrclk; - rtcm->ssr[sat-1].update=1; - } - return sync?0:10; +static int decode_ssr6(rtcm_t *rtcm, int sys, int subtype) { + double udint, hrclk; + int i, j, type, nsat, sync, iod, prn, sat, np, offp; + + type = getbitu(rtcm->buff, 24, 12); + + if ((nsat = decode_ssr2_head(rtcm, sys, subtype, &sync, &iod, &udint, &i)) < 0) { + trace(2, "rtcm3 %d length error: len=%d\n", type, rtcm->len); + return -1; + } + switch (sys) { + case SYS_GPS: + np = 6; + offp = 0; + break; + case SYS_GLO: + np = 5; + offp = 0; + break; + case SYS_GAL: + np = 6; + offp = 0; + break; + case SYS_QZS: + np = 4; + offp = 192; + break; + case SYS_CMP: + np = 6; + offp = 1; + break; + case SYS_SBS: + np = 6; + offp = 120; + break; + default: + return sync ? 0 : 10; + } + if (subtype > 0) { /* IGS SSR */ + np = 6; + if (sys == SYS_CMP) + offp = 0; + else if (sys == SYS_SBS) + offp = 119; + } + for (j = 0; j < nsat && i + 22 + np <= rtcm->len * 8; j++) { + prn = getbitu(rtcm->buff, i, np) + offp; + i += np; + hrclk = getbits(rtcm->buff, i, 22) * 1E-4; + i += 22; + + if (!(sat = satno(sys, prn))) { + trace(2, "rtcm3 %d satellite number error: prn=%d\n", type, prn); + continue; + } + rtcm->ssr[sat - 1].t0[2] = rtcm->time; + rtcm->ssr[sat - 1].udi[2] = udint; + rtcm->ssr[sat - 1].iod[2] = iod; + rtcm->ssr[sat - 1].hrclk = hrclk; + rtcm->ssr[sat - 1].update = 1; + } + return sync ? 0 : 10; } /* decode SSR 7 message header -----------------------------------------------*/ -static int decode_ssr7_head(rtcm_t *rtcm, int sys, int subtype, int *sync, - int *iod, double *udint, int *dispe, int *mw, - int *hsize) -{ - char *msg,tstr[40]; - int i=24+12,nsat,udi,provid=0,solid=0,ns; - - if (subtype==0) { /* RTCM SSR */ - ns=(sys==SYS_QZS)?4:6; - if (i+((sys==SYS_GLO)?54:51+ns)>rtcm->len*8) return -1; - } - else { /* IGS SSR */ - ns=6; - if (i+3+8+51+ns>rtcm->len*8) return -1; - } - i=decode_ssr_epoch(rtcm,sys,subtype); - udi =getbitu(rtcm->buff,i, 4); i+= 4; - *sync =getbitu(rtcm->buff,i, 1); i+= 1; - *iod =getbitu(rtcm->buff,i, 4); i+= 4; - provid=getbitu(rtcm->buff,i,16); i+=16; /* provider ID */ - solid =getbitu(rtcm->buff,i, 4); i+= 4; /* solution ID */ - *dispe=getbitu(rtcm->buff,i, 1); i+= 1; /* dispersive bias consistency ind */ - *mw =getbitu(rtcm->buff,i, 1); i+= 1; /* MW consistency indicator */ - nsat =getbitu(rtcm->buff,i,ns); i+=ns; - *udint=ssrudint[udi]; - - time2str(rtcm->time,tstr,2); - trace(4,"decode_ssr7_head: time=%s sys=%d subtype=%d nsat=%d sync=%d iod=%d" - " provid=%d solid=%d\n",tstr,sys,subtype,nsat,*sync,*iod,provid,solid); - - if (rtcm->outtype) { - msg=rtcm->msgtype+strlen(rtcm->msgtype); - sprintf(msg," %s nsat=%2d iod=%2d udi=%2d sync=%d",tstr,nsat,*iod,udi, - *sync); - } - *hsize=i; - return nsat; +static int decode_ssr7_head(rtcm_t *rtcm, int sys, int subtype, int *sync, int *iod, double *udint, + int *dispe, int *mw, int *hsize) { + char *msg, tstr[40]; + int i = 24 + 12, nsat, udi, provid = 0, solid = 0, ns; + + if (subtype == 0) { /* RTCM SSR */ + ns = (sys == SYS_QZS) ? 4 : 6; + if (i + ((sys == SYS_GLO) ? 54 : 51 + ns) > rtcm->len * 8) return -1; + } else { /* IGS SSR */ + ns = 6; + if (i + 3 + 8 + 51 + ns > rtcm->len * 8) return -1; + } + i = decode_ssr_epoch(rtcm, sys, subtype); + udi = getbitu(rtcm->buff, i, 4); + i += 4; + *sync = getbitu(rtcm->buff, i, 1); + i += 1; + *iod = getbitu(rtcm->buff, i, 4); + i += 4; + provid = getbitu(rtcm->buff, i, 16); + i += 16; /* provider ID */ + solid = getbitu(rtcm->buff, i, 4); + i += 4; /* solution ID */ + *dispe = getbitu(rtcm->buff, i, 1); + i += 1; /* dispersive bias consistency ind */ + *mw = getbitu(rtcm->buff, i, 1); + i += 1; /* MW consistency indicator */ + nsat = getbitu(rtcm->buff, i, ns); + i += ns; + *udint = ssrudint[udi]; + + time2str(rtcm->time, tstr, 2); + trace(4, + "decode_ssr7_head: time=%s sys=%d subtype=%d nsat=%d sync=%d iod=%d" + " provid=%d solid=%d\n", + tstr, sys, subtype, nsat, *sync, *iod, provid, solid); + + if (rtcm->outtype) { + msg = rtcm->msgtype + strlen(rtcm->msgtype); + sprintf(msg, " %s nsat=%2d iod=%2d udi=%2d sync=%d", tstr, nsat, *iod, udi, *sync); + } + *hsize = i; + return nsat; } /* decode SSR 7: phase bias --------------------------------------------------*/ -static int decode_ssr7(rtcm_t *rtcm, int sys, int subtype) -{ - const uint8_t *sigs; - double udint,bias,std=0.0,pbias[MAXCODE],stdpb[MAXCODE]; - int i,j,k,type,mode,sync,iod,nsat,prn,sat,nbias,np,mw,offp,sii,swl; - int dispe,sdc,yaw_ang,yaw_rate; - - type=getbitu(rtcm->buff,24,12); - - if ((nsat=decode_ssr7_head(rtcm,sys,subtype,&sync,&iod,&udint,&dispe,&mw, - &i))<0) { - trace(2,"rtcm3 %d length error: len=%d\n",type,rtcm->len); - return -1; - } - switch (sys) { - case SYS_GPS: np=6; offp= 0; sigs=ssr_sig_gps; break; - case SYS_GLO: np=5; offp= 0; sigs=ssr_sig_glo; break; - case SYS_GAL: np=6; offp= 0; sigs=ssr_sig_gal; break; - case SYS_QZS: np=4; offp=192; sigs=ssr_sig_qzs; break; - case SYS_CMP: np=6; offp= 1; sigs=ssr_sig_cmp; break; - default: return sync?0:10; - } - if (subtype>0) { /* IGS SSR */ - np=6; - if (sys==SYS_CMP) offp=0; - else if (sys==SYS_SBS) offp=119; - } - for (j=0;jlen*8;j++) { - prn =getbitu(rtcm->buff,i,np)+offp; i+=np; - nbias =getbitu(rtcm->buff,i, 5); i+= 5; - yaw_ang =getbitu(rtcm->buff,i, 9); i+= 9; - yaw_rate=getbits(rtcm->buff,i, 8); i+= 8; - - for (k=0;klen*8;k++) { - mode=getbitu(rtcm->buff,i, 5); i+= 5; - sii =getbitu(rtcm->buff,i, 1); i+= 1; /* integer-indicator */ - swl =getbitu(rtcm->buff,i, 2); i+= 2; /* WL integer-indicator */ - sdc =getbitu(rtcm->buff,i, 4); i+= 4; /* discontinuity counter */ - bias=getbits(rtcm->buff,i,20); i+=20; /* phase bias (m) */ - if (subtype==0) { - std =getbitu(rtcm->buff,i,17); i+=17; /* phase bias std-dev (m) */ - } - if (sigs[mode]) { - pbias[sigs[mode]-1]=bias*0.0001; /* (m) */ - stdpb[sigs[mode]-1]=std *0.0001; /* (m) */ - } - else { - trace(2,"rtcm3 %d not supported mode: mode=%d\n",type,mode); - } - } - if (!(sat=satno(sys,prn))) { - trace(2,"rtcm3 %d satellite number error: prn=%d\n",type,prn); - continue; - } - rtcm->ssr[sat-1].t0 [5]=rtcm->time; - rtcm->ssr[sat-1].udi[5]=udint; - rtcm->ssr[sat-1].iod[5]=iod; - rtcm->ssr[sat-1].yaw_ang =yaw_ang / 256.0*180.0; /* (deg) */ - rtcm->ssr[sat-1].yaw_rate=yaw_rate/8192.0*180.0; /* (deg/s) */ - - for (k=0;kssr[sat-1].pbias[k]=pbias[k]; - rtcm->ssr[sat-1].stdpb[k]=(float)stdpb[k]; - } +static int decode_ssr7(rtcm_t *rtcm, int sys, int subtype) { + const uint8_t *sigs; + double udint, bias, std = 0.0, pbias[MAXCODE], stdpb[MAXCODE]; + int i, j, k, type, mode, sync, iod, nsat, prn, sat, nbias, np, mw, offp, sii, swl; + int dispe, sdc, yaw_ang, yaw_rate; + + type = getbitu(rtcm->buff, 24, 12); + + if ((nsat = decode_ssr7_head(rtcm, sys, subtype, &sync, &iod, &udint, &dispe, &mw, &i)) < 0) { + trace(2, "rtcm3 %d length error: len=%d\n", type, rtcm->len); + return -1; + } + switch (sys) { + case SYS_GPS: + np = 6; + offp = 0; + sigs = ssr_sig_gps; + break; + case SYS_GLO: + np = 5; + offp = 0; + sigs = ssr_sig_glo; + break; + case SYS_GAL: + np = 6; + offp = 0; + sigs = ssr_sig_gal; + break; + case SYS_QZS: + np = 4; + offp = 192; + sigs = ssr_sig_qzs; + break; + case SYS_CMP: + np = 6; + offp = 1; + sigs = ssr_sig_cmp; + break; + default: + return sync ? 0 : 10; + } + if (subtype > 0) { /* IGS SSR */ + np = 6; + if (sys == SYS_CMP) + offp = 0; + else if (sys == SYS_SBS) + offp = 119; + } + for (j = 0; j < nsat && i + 5 + 17 + np <= rtcm->len * 8; j++) { + prn = getbitu(rtcm->buff, i, np) + offp; + i += np; + nbias = getbitu(rtcm->buff, i, 5); + i += 5; + yaw_ang = getbitu(rtcm->buff, i, 9); + i += 9; + yaw_rate = getbits(rtcm->buff, i, 8); + i += 8; + + for (k = 0; k < MAXCODE; k++) pbias[k] = stdpb[k] = 0.0; + for (k = 0; k < nbias && i + ((subtype == 0) ? 49 : 32) <= rtcm->len * 8; k++) { + mode = getbitu(rtcm->buff, i, 5); + i += 5; + sii = getbitu(rtcm->buff, i, 1); + i += 1; /* integer-indicator */ + swl = getbitu(rtcm->buff, i, 2); + i += 2; /* WL integer-indicator */ + sdc = getbitu(rtcm->buff, i, 4); + i += 4; /* discontinuity counter */ + bias = getbits(rtcm->buff, i, 20); + i += 20; /* phase bias (m) */ + if (subtype == 0) { + std = getbitu(rtcm->buff, i, 17); + i += 17; /* phase bias std-dev (m) */ + } + if (sigs[mode]) { + pbias[sigs[mode] - 1] = bias * 0.0001; /* (m) */ + stdpb[sigs[mode] - 1] = std * 0.0001; /* (m) */ + } else { + trace(2, "rtcm3 %d not supported mode: mode=%d\n", type, mode); + } + } + if (!(sat = satno(sys, prn))) { + trace(2, "rtcm3 %d satellite number error: prn=%d\n", type, prn); + continue; + } + rtcm->ssr[sat - 1].t0[5] = rtcm->time; + rtcm->ssr[sat - 1].udi[5] = udint; + rtcm->ssr[sat - 1].iod[5] = iod; + rtcm->ssr[sat - 1].yaw_ang = yaw_ang / 256.0 * 180.0; /* (deg) */ + rtcm->ssr[sat - 1].yaw_rate = yaw_rate / 8192.0 * 180.0; /* (deg/s) */ + + for (k = 0; k < MAXCODE; k++) { + rtcm->ssr[sat - 1].pbias[k] = pbias[k]; + rtcm->ssr[sat - 1].stdpb[k] = (float)stdpb[k]; } - return 20; + } + return 20; } /* get signal index ----------------------------------------------------------*/ -static void sigindex(int sys, const uint8_t *code, int n, const char *opt, - int *idx) -{ - int i,nex,pri,pri_h[8]={0},index[8]={0},ex[32]={0}; - - /* test code priority */ - for (i=0;i=NFREQ) { /* save as extended signal if idx >= NFREQ */ - ex[i]=1; - continue; - } - /* code priority */ - pri=getcodepri(sys,code[i],opt); - - /* select highest priority signal */ - if (pri>pri_h[idx[i]]) { - if (index[idx[i]]) ex[index[idx[i]]-1]=1; - pri_h[idx[i]]=pri; - index[idx[i]]=i+1; - } - else ex[i]=1; +static void sigindex(int sys, const uint8_t *code, int n, const char *opt, int *idx) { + int i, nex, pri, pri_h[8] = {0}, index[8] = {0}, ex[32] = {0}; + + /* test code priority */ + for (i = 0; i < n; i++) { + if (!code[i]) continue; + + if (idx[i] >= NFREQ) { /* save as extended signal if idx >= NFREQ */ + ex[i] = 1; + continue; + } + /* code priority */ + pri = getcodepri(sys, code[i], opt); + + /* select highest priority signal */ + if (pri > pri_h[idx[i]]) { + if (index[idx[i]]) ex[index[idx[i]] - 1] = 1; + pri_h[idx[i]] = pri; + index[idx[i]] = i + 1; + } else + ex[i] = 1; + } + /* signal index in obs data */ + for (i = nex = 0; i < n; i++) { + if (ex[i] == 0) + ; + else if (nex < NEXOBS) + idx[i] = NFREQ + nex++; + else { /* no space in obs data */ + trace(2, "rtcm msm: no space in obs data sys=%d code=%d\n", sys, code[i]); + idx[i] = -1; } - /* signal index in obs data */ - for (i=nex=0;ibuff,24,12); - +static void save_msm_obs(rtcm_t *rtcm, int sys, msm_h_t *h, const double *r, const double *pr, + const double *cp, const double *rr, const double *rrf, const double *cnr, + const int *lock, const int *ex, const int *half) { + const char *sig[32]; + double tt, freq; + uint8_t code[32]; + char *msm_type = "", *q = NULL; + int i, j, k, type, prn, sat, fcn, index = 0, idx[32]; + + type = getbitu(rtcm->buff, 24, 12); + + switch (sys) { + case SYS_GPS: + msm_type = q = rtcm->msmtype[0]; + break; + case SYS_GLO: + msm_type = q = rtcm->msmtype[1]; + break; + case SYS_GAL: + msm_type = q = rtcm->msmtype[2]; + break; + case SYS_QZS: + msm_type = q = rtcm->msmtype[3]; + break; + case SYS_SBS: + msm_type = q = rtcm->msmtype[4]; + break; + case SYS_CMP: + msm_type = q = rtcm->msmtype[5]; + break; + case SYS_IRN: + msm_type = q = rtcm->msmtype[6]; + break; + } + /* id to signal */ + for (i = 0; i < h->nsig; i++) { switch (sys) { - case SYS_GPS: msm_type=q=rtcm->msmtype[0]; break; - case SYS_GLO: msm_type=q=rtcm->msmtype[1]; break; - case SYS_GAL: msm_type=q=rtcm->msmtype[2]; break; - case SYS_QZS: msm_type=q=rtcm->msmtype[3]; break; - case SYS_SBS: msm_type=q=rtcm->msmtype[4]; break; - case SYS_CMP: msm_type=q=rtcm->msmtype[5]; break; - case SYS_IRN: msm_type=q=rtcm->msmtype[6]; break; - } - /* id to signal */ - for (i=0;insig;i++) { - switch (sys) { - case SYS_GPS: sig[i]=msm_sig_gps[h->sigs[i]-1]; break; - case SYS_GLO: sig[i]=msm_sig_glo[h->sigs[i]-1]; break; - case SYS_GAL: sig[i]=msm_sig_gal[h->sigs[i]-1]; break; - case SYS_QZS: sig[i]=msm_sig_qzs[h->sigs[i]-1]; break; - case SYS_SBS: sig[i]=msm_sig_sbs[h->sigs[i]-1]; break; - case SYS_CMP: sig[i]=msm_sig_cmp[h->sigs[i]-1]; break; - case SYS_IRN: sig[i]=msm_sig_irn[h->sigs[i]-1]; break; - default: sig[i]=""; break; - } - /* signal to rinex obs type */ - code[i]=obs2code(sig[i]); - idx[i]=code2idx(sys,code[i]); - - if (code[i]!=CODE_NONE) { - if (q) q+=sprintf(q,"L%s%s",sig[i],insig-1?",":""); - } - else { - if (q) q+=sprintf(q,"(%d)%s",h->sigs[i],insig-1?",":""); - - trace(2,"rtcm3 %d: unknown signal id=%2d\n",type,h->sigs[i]); - } + case SYS_GPS: + sig[i] = msm_sig_gps[h->sigs[i] - 1]; + break; + case SYS_GLO: + sig[i] = msm_sig_glo[h->sigs[i] - 1]; + break; + case SYS_GAL: + sig[i] = msm_sig_gal[h->sigs[i] - 1]; + break; + case SYS_QZS: + sig[i] = msm_sig_qzs[h->sigs[i] - 1]; + break; + case SYS_SBS: + sig[i] = msm_sig_sbs[h->sigs[i] - 1]; + break; + case SYS_CMP: + sig[i] = msm_sig_cmp[h->sigs[i] - 1]; + break; + case SYS_IRN: + sig[i] = msm_sig_irn[h->sigs[i] - 1]; + break; + default: + sig[i] = ""; + break; + } + /* signal to rinex obs type */ + code[i] = obs2code(sig[i]); + idx[i] = code2idx(sys, code[i]); + + if (code[i] != CODE_NONE) { + if (q) q += sprintf(q, "L%s%s", sig[i], i < h->nsig - 1 ? "," : ""); + } else { + if (q) q += sprintf(q, "(%d)%s", h->sigs[i], i < h->nsig - 1 ? "," : ""); + + trace(2, "rtcm3 %d: unknown signal id=%2d\n", type, h->sigs[i]); } - trace(3,"rtcm3 %d: signals=%s\n",type,msm_type); - - /* get signal index */ - sigindex(sys,code,h->nsig,rtcm->opt,idx); - - for (i=j=0;insat;i++) { - - prn=h->sats[i]; - if (sys==SYS_QZS) prn+=MINPRNQZS-1; - else if (sys==SYS_SBS) prn+=MINPRNSBS-1; - - if ((sat=satno(sys,prn))) { - tt=timediff(rtcm->obs.data[0].time,rtcm->time); - if (rtcm->obsflag||fabs(tt)>1E-9) { - rtcm->obs.n=rtcm->obsflag=0; - } - index=obsindex(&rtcm->obs,rtcm->time,sat); + } + trace(3, "rtcm3 %d: signals=%s\n", type, msm_type); + + /* get signal index */ + sigindex(sys, code, h->nsig, rtcm->opt, idx); + + for (i = j = 0; i < h->nsat; i++) { + prn = h->sats[i]; + if (sys == SYS_QZS) + prn += MINPRNQZS - 1; + else if (sys == SYS_SBS) + prn += MINPRNSBS - 1; + + if ((sat = satno(sys, prn))) { + tt = timediff(rtcm->obs.data[0].time, rtcm->time); + if (rtcm->obsflag || fabs(tt) > 1E-9) { + rtcm->obs.n = rtcm->obsflag = 0; + } + index = obsindex(&rtcm->obs, rtcm->time, sat); + } else { + trace(2, "rtcm3 %d satellite error: prn=%d\n", type, prn); + } + fcn = 0; + if (sys == SYS_GLO) { + fcn = -8; /* no glonass fcn info */ + if (ex && ex[i] <= 13) { + fcn = ex[i] - 7; + if (!rtcm->nav.glo_fcn[prn - 1]) { + rtcm->nav.glo_fcn[prn - 1] = fcn + 8; /* fcn+8 */ } - else { - trace(2,"rtcm3 %d satellite error: prn=%d\n",type,prn); + } else if (sat && rtcm->nav.geph[prn - 1].sat == sat) { + fcn = rtcm->nav.geph[prn - 1].frq; + } else if (rtcm->nav.glo_fcn[prn - 1] > 0) { + fcn = rtcm->nav.glo_fcn[prn - 1] - 8; + } + } + for (k = 0; k < h->nsig; k++) { + if (!h->cellmask[k + i * h->nsig]) continue; + + if (sat && index >= 0 && idx[k] >= 0) { + freq = fcn < -7 ? 0.0 : code2freq(sys, code[k], fcn); + + /* pseudorange (m) */ + if (r[i] != 0.0 && pr[j] > -1E12) { + rtcm->obs.data[index].P[idx[k]] = r[i] + pr[j]; } - fcn=0; - if (sys==SYS_GLO) { - fcn=-8; /* no glonass fcn info */ - if (ex&&ex[i]<=13) { - fcn=ex[i]-7; - if (!rtcm->nav.glo_fcn[prn-1]) { - rtcm->nav.glo_fcn[prn-1]=fcn+8; /* fcn+8 */ - } - } - else if (sat && rtcm->nav.geph[prn-1].sat == sat) { - fcn=rtcm->nav.geph[prn-1].frq; - } - else if (rtcm->nav.glo_fcn[prn-1]>0) { - fcn=rtcm->nav.glo_fcn[prn-1]-8; - } + /* carrier-phase (cycle) */ + if (r[i] != 0.0 && cp[j] > -1E12) { + rtcm->obs.data[index].L[idx[k]] = (r[i] + cp[j]) * freq / CLIGHT; } - for (k=0;knsig;k++) { - if (!h->cellmask[k+i*h->nsig]) continue; - - if (sat&&index>=0&&idx[k]>=0) { - freq=fcn<-7?0.0:code2freq(sys,code[k],fcn); - - /* pseudorange (m) */ - if (r[i]!=0.0&&pr[j]>-1E12) { - rtcm->obs.data[index].P[idx[k]]=r[i]+pr[j]; - } - /* carrier-phase (cycle) */ - if (r[i]!=0.0&&cp[j]>-1E12) { - rtcm->obs.data[index].L[idx[k]]=(r[i]+cp[j])*freq/CLIGHT; - } - /* doppler (hz) */ - if (rr&&rrf&&rrf[j]>-1E12) { - rtcm->obs.data[index].D[idx[k]]= - (float)(-(rr[i]+rrf[j])*freq/CLIGHT); - } - rtcm->obs.data[index].LLI[idx[k]]= - lossoflock(rtcm,sat,idx[k],lock[j])+(half[j]?2:0); - rtcm->obs.data[index].SNR [idx[k]]=cnr[j]; - rtcm->obs.data[index].code[idx[k]]=code[k]; - } - j++; + /* doppler (hz) */ + if (rr && rrf && rrf[j] > -1E12) { + rtcm->obs.data[index].D[idx[k]] = (float)(-(rr[i] + rrf[j]) * freq / CLIGHT); } + rtcm->obs.data[index].LLI[idx[k]] = + lossoflock(rtcm, sat, idx[k], lock[j]) + (half[j] ? 2 : 0); + rtcm->obs.data[index].SNR[idx[k]] = cnr[j]; + rtcm->obs.data[index].code[idx[k]] = code[k]; + } + j++; } + } } /* decode type MSM message header --------------------------------------------*/ -static int decode_msm_head(rtcm_t *rtcm, int sys, int *sync, int *iod, - msm_h_t *h, int *hsize) -{ - msm_h_t h0={0}; - double tow,tod; - char *msg,tstr[40]; - int i=24,j,dow,mask,staid,type,ncell=0; - - if (rtcm->obsflag) rtcm->obs.n = rtcm->obsflag = 0; - - type=getbitu(rtcm->buff,i,12); i+=12; - - *h=h0; - if (i+157<=rtcm->len*8) { - staid =getbitu(rtcm->buff,i,12); i+=12; - - if (sys==SYS_GLO) { - dow =getbitu(rtcm->buff,i, 3); i+= 3; - tod =getbitu(rtcm->buff,i,27)*0.001; i+=27; - adjday_glot(rtcm,tod); - } - else if (sys==SYS_CMP) { - tow =getbitu(rtcm->buff,i,30)*0.001; i+=30; - tow+=14.0; /* BDT -> GPST */ - adjweek(rtcm,tow); - } - else { - tow =getbitu(rtcm->buff,i,30)*0.001; i+=30; - adjweek(rtcm,tow); - } - *sync =getbitu(rtcm->buff,i, 1); i+= 1; - *iod =getbitu(rtcm->buff,i, 3); i+= 3; - h->time_s =getbitu(rtcm->buff,i, 7); i+= 7; - h->clk_str=getbitu(rtcm->buff,i, 2); i+= 2; - h->clk_ext=getbitu(rtcm->buff,i, 2); i+= 2; - h->smooth =getbitu(rtcm->buff,i, 1); i+= 1; - h->tint_s =getbitu(rtcm->buff,i, 3); i+= 3; - for (j=1;j<=64;j++) { - mask=getbitu(rtcm->buff,i,1); i+=1; - if (mask) h->sats[h->nsat++]=j; - } - for (j=1;j<=32;j++) { - mask=getbitu(rtcm->buff,i,1); i+=1; - if (mask) h->sigs[h->nsig++]=j; - } - } - else { - trace(2,"rtcm3 %d length error: len=%d\n",type,rtcm->len); - return -1; - } - /* test station id */ - if (!test_staid(rtcm,staid)) return -1; - - if (h->nsat*h->nsig>64) { - trace(2,"rtcm3 %d number of sats and sigs error: nsat=%d nsig=%d\n", - type,h->nsat,h->nsig); - return -1; - } - if (i+h->nsat*h->nsig>rtcm->len*8) { - trace(2,"rtcm3 %d length error: len=%d nsat=%d nsig=%d\n",type, - rtcm->len,h->nsat,h->nsig); - return -1; - } - for (j=0;jnsat*h->nsig;j++) { - h->cellmask[j]=getbitu(rtcm->buff,i,1); i+=1; - if (h->cellmask[j]) ncell++; - } - *hsize=i; - - time2str(rtcm->time,tstr,2); - trace(4,"decode_head_msm: time=%s sys=%d staid=%d nsat=%d nsig=%d sync=%d iod=%d ncell=%d\n", - tstr,sys,staid,h->nsat,h->nsig,*sync,*iod,ncell); - - if (rtcm->outtype) { - msg=rtcm->msgtype+strlen(rtcm->msgtype); - sprintf(msg," staid=%4d %s nsat=%2d nsig=%2d iod=%2d ncell=%2d sync=%d", - staid,tstr,h->nsat,h->nsig,*iod,ncell,*sync); - } - return ncell; +static int decode_msm_head(rtcm_t *rtcm, int sys, int *sync, int *iod, msm_h_t *h, int *hsize) { + msm_h_t h0 = {0}; + double tow, tod; + char *msg, tstr[40]; + int i = 24, j, dow, mask, staid, type, ncell = 0; + + if (rtcm->obsflag) rtcm->obs.n = rtcm->obsflag = 0; + + type = getbitu(rtcm->buff, i, 12); + i += 12; + + *h = h0; + if (i + 157 <= rtcm->len * 8) { + staid = getbitu(rtcm->buff, i, 12); + i += 12; + + if (sys == SYS_GLO) { + dow = getbitu(rtcm->buff, i, 3); + i += 3; + tod = getbitu(rtcm->buff, i, 27) * 0.001; + i += 27; + adjday_glot(rtcm, tod); + } else if (sys == SYS_CMP) { + tow = getbitu(rtcm->buff, i, 30) * 0.001; + i += 30; + tow += 14.0; /* BDT -> GPST */ + adjweek(rtcm, tow); + } else { + tow = getbitu(rtcm->buff, i, 30) * 0.001; + i += 30; + adjweek(rtcm, tow); + } + *sync = getbitu(rtcm->buff, i, 1); + i += 1; + *iod = getbitu(rtcm->buff, i, 3); + i += 3; + h->time_s = getbitu(rtcm->buff, i, 7); + i += 7; + h->clk_str = getbitu(rtcm->buff, i, 2); + i += 2; + h->clk_ext = getbitu(rtcm->buff, i, 2); + i += 2; + h->smooth = getbitu(rtcm->buff, i, 1); + i += 1; + h->tint_s = getbitu(rtcm->buff, i, 3); + i += 3; + for (j = 1; j <= 64; j++) { + mask = getbitu(rtcm->buff, i, 1); + i += 1; + if (mask) h->sats[h->nsat++] = j; + } + for (j = 1; j <= 32; j++) { + mask = getbitu(rtcm->buff, i, 1); + i += 1; + if (mask) h->sigs[h->nsig++] = j; + } + } else { + trace(2, "rtcm3 %d length error: len=%d\n", type, rtcm->len); + return -1; + } + /* test station id */ + if (!test_staid(rtcm, staid)) return -1; + + if (h->nsat * h->nsig > 64) { + trace(2, "rtcm3 %d number of sats and sigs error: nsat=%d nsig=%d\n", type, h->nsat, h->nsig); + return -1; + } + if (i + h->nsat * h->nsig > rtcm->len * 8) { + trace(2, "rtcm3 %d length error: len=%d nsat=%d nsig=%d\n", type, rtcm->len, h->nsat, h->nsig); + return -1; + } + for (j = 0; j < h->nsat * h->nsig; j++) { + h->cellmask[j] = getbitu(rtcm->buff, i, 1); + i += 1; + if (h->cellmask[j]) ncell++; + } + *hsize = i; + + time2str(rtcm->time, tstr, 2); + trace(4, "decode_head_msm: time=%s sys=%d staid=%d nsat=%d nsig=%d sync=%d iod=%d ncell=%d\n", + tstr, sys, staid, h->nsat, h->nsig, *sync, *iod, ncell); + + if (rtcm->outtype) { + msg = rtcm->msgtype + strlen(rtcm->msgtype); + sprintf(msg, " staid=%4d %s nsat=%2d nsig=%2d iod=%2d ncell=%2d sync=%d", staid, tstr, h->nsat, + h->nsig, *iod, ncell, *sync); + } + return ncell; } /* decode unsupported MSM message --------------------------------------------*/ -static int decode_msm0(rtcm_t *rtcm, int sys) -{ - msm_h_t h={0}; - int i,sync,iod; - if (decode_msm_head(rtcm,sys,&sync,&iod,&h,&i)<0) return -1; - rtcm->obsflag=!sync; - return sync?0:1; +static int decode_msm0(rtcm_t *rtcm, int sys) { + msm_h_t h = {0}; + int i, sync, iod; + if (decode_msm_head(rtcm, sys, &sync, &iod, &h, &i) < 0) return -1; + rtcm->obsflag = !sync; + return sync ? 0 : 1; } /* decode MSM 4: full pseudorange and phaserange plus CNR --------------------*/ -static int decode_msm4(rtcm_t *rtcm, int sys) -{ - msm_h_t h={0}; - double r[64],pr[64],cp[64],cnr[64]; - int i,j,type,sync,iod,ncell,rng,rng_m,prv,cpv,lock[64],half[64]; - - type=getbitu(rtcm->buff,24,12); - - /* decode msm header */ - if ((ncell=decode_msm_head(rtcm,sys,&sync,&iod,&h,&i))<0) return -1; - - if (i+h.nsat*18+ncell*48>rtcm->len*8) { - trace(2,"rtcm3 %d length error: nsat=%d ncell=%d len=%d\n",type,h.nsat, - ncell,rtcm->len); - rtcm->obsflag=!sync; /* header ok, so return sync bit */ - return sync?0:1; - } - for (j=0;jbuff,i, 8); i+= 8; - if (rng!=255) r[j]=rng*RANGE_MS; - } - for (j=0;jbuff,i,10); i+=10; - if (r[j]!=0.0) r[j]+=rng_m*P2_10*RANGE_MS; - } - /* decode signal data */ - for (j=0;jbuff,i,15); i+=15; - if (prv!=-16384) pr[j]=prv*P2_24*RANGE_MS; - } - for (j=0;jbuff,i,22); i+=22; - if (cpv!=-2097152) cp[j]=cpv*P2_29*RANGE_MS; - } - for (j=0;jbuff,i,4); i+=4; - } - for (j=0;jbuff,i,1); i+=1; - } - for (j=0;jbuff,i,6)*1.0; i+=6; - } - /* save obs data in msm message */ - save_msm_obs(rtcm,sys,&h,r,pr,cp,NULL,NULL,cnr,lock,NULL,half); - - rtcm->obsflag=!sync; - return sync?0:1; +static int decode_msm4(rtcm_t *rtcm, int sys) { + msm_h_t h = {0}; + double r[64], pr[64], cp[64], cnr[64]; + int i, j, type, sync, iod, ncell, rng, rng_m, prv, cpv, lock[64], half[64]; + + type = getbitu(rtcm->buff, 24, 12); + + /* decode msm header */ + if ((ncell = decode_msm_head(rtcm, sys, &sync, &iod, &h, &i)) < 0) return -1; + + if (i + h.nsat * 18 + ncell * 48 > rtcm->len * 8) { + trace(2, "rtcm3 %d length error: nsat=%d ncell=%d len=%d\n", type, h.nsat, ncell, rtcm->len); + rtcm->obsflag = !sync; /* header ok, so return sync bit */ + return sync ? 0 : 1; + } + for (j = 0; j < h.nsat; j++) r[j] = 0.0; + for (j = 0; j < ncell; j++) pr[j] = cp[j] = -1E16; + + /* decode satellite data */ + for (j = 0; j < h.nsat; j++) { /* range */ + rng = getbitu(rtcm->buff, i, 8); + i += 8; + if (rng != 255) r[j] = rng * RANGE_MS; + } + for (j = 0; j < h.nsat; j++) { + rng_m = getbitu(rtcm->buff, i, 10); + i += 10; + if (r[j] != 0.0) r[j] += rng_m * P2_10 * RANGE_MS; + } + /* decode signal data */ + for (j = 0; j < ncell; j++) { /* pseudorange */ + prv = getbits(rtcm->buff, i, 15); + i += 15; + if (prv != -16384) pr[j] = prv * P2_24 * RANGE_MS; + } + for (j = 0; j < ncell; j++) { /* phaserange */ + cpv = getbits(rtcm->buff, i, 22); + i += 22; + if (cpv != -2097152) cp[j] = cpv * P2_29 * RANGE_MS; + } + for (j = 0; j < ncell; j++) { /* lock time */ + lock[j] = getbitu(rtcm->buff, i, 4); + i += 4; + } + for (j = 0; j < ncell; j++) { /* half-cycle ambiguity */ + half[j] = getbitu(rtcm->buff, i, 1); + i += 1; + } + for (j = 0; j < ncell; j++) { /* cnr */ + cnr[j] = getbitu(rtcm->buff, i, 6) * 1.0; + i += 6; + } + /* save obs data in msm message */ + save_msm_obs(rtcm, sys, &h, r, pr, cp, NULL, NULL, cnr, lock, NULL, half); + + rtcm->obsflag = !sync; + return sync ? 0 : 1; } /* decode MSM 5: full pseudorange, phaserange, phaserangerate and CNR --------*/ -static int decode_msm5(rtcm_t *rtcm, int sys) -{ - msm_h_t h={0}; - double r[64],rr[64],pr[64],cp[64],rrf[64],cnr[64]; - int i,j,type,sync,iod,ncell,rng,rng_m,rate,prv,cpv,rrv,lock[64]; - int ex[64],half[64]; - - type=getbitu(rtcm->buff,24,12); - - /* decode msm header */ - if ((ncell=decode_msm_head(rtcm,sys,&sync,&iod,&h,&i))<0) return -1; - - if (i+h.nsat*36+ncell*63>rtcm->len*8) { - trace(2,"rtcm3 %d length error: nsat=%d ncell=%d len=%d\n",type,h.nsat, - ncell,rtcm->len); - rtcm->obsflag=!sync; /* header ok, so return sync bit */ - return sync?0:1; - } - for (j=0;jbuff,i, 8); i+= 8; - if (rng!=255) r[j]=rng*RANGE_MS; - } - for (j=0;jbuff,i, 4); i+= 4; - } - for (j=0;jbuff,i,10); i+=10; - if (r[j]!=0.0) r[j]+=rng_m*P2_10*RANGE_MS; - } - for (j=0;jbuff,i,14); i+=14; - if (rate!=-8192) rr[j]=rate*1.0; - } - /* decode signal data */ - for (j=0;jbuff,i,15); i+=15; - if (prv!=-16384) pr[j]=prv*P2_24*RANGE_MS; - } - for (j=0;jbuff,i,22); i+=22; - if (cpv!=-2097152) cp[j]=cpv*P2_29*RANGE_MS; - } - for (j=0;jbuff,i,4); i+=4; - } - for (j=0;jbuff,i,1); i+=1; - } - for (j=0;jbuff,i,6)*1.0; i+=6; - } - for (j=0;jbuff,i,15); i+=15; - if (rrv!=-16384) rrf[j]=rrv*0.0001; - } - /* save obs data in msm message */ - save_msm_obs(rtcm,sys,&h,r,pr,cp,rr,rrf,cnr,lock,ex,half); - - rtcm->obsflag=!sync; - return sync?0:1; +static int decode_msm5(rtcm_t *rtcm, int sys) { + msm_h_t h = {0}; + double r[64], rr[64], pr[64], cp[64], rrf[64], cnr[64]; + int i, j, type, sync, iod, ncell, rng, rng_m, rate, prv, cpv, rrv, lock[64]; + int ex[64], half[64]; + + type = getbitu(rtcm->buff, 24, 12); + + /* decode msm header */ + if ((ncell = decode_msm_head(rtcm, sys, &sync, &iod, &h, &i)) < 0) return -1; + + if (i + h.nsat * 36 + ncell * 63 > rtcm->len * 8) { + trace(2, "rtcm3 %d length error: nsat=%d ncell=%d len=%d\n", type, h.nsat, ncell, rtcm->len); + rtcm->obsflag = !sync; /* header ok, so return sync bit */ + return sync ? 0 : 1; + } + for (j = 0; j < h.nsat; j++) { + r[j] = rr[j] = 0.0; + ex[j] = 15; + } + for (j = 0; j < ncell; j++) pr[j] = cp[j] = rrf[j] = -1E16; + + /* decode satellite data */ + for (j = 0; j < h.nsat; j++) { /* range */ + rng = getbitu(rtcm->buff, i, 8); + i += 8; + if (rng != 255) r[j] = rng * RANGE_MS; + } + for (j = 0; j < h.nsat; j++) { /* extended info */ + ex[j] = getbitu(rtcm->buff, i, 4); + i += 4; + } + for (j = 0; j < h.nsat; j++) { + rng_m = getbitu(rtcm->buff, i, 10); + i += 10; + if (r[j] != 0.0) r[j] += rng_m * P2_10 * RANGE_MS; + } + for (j = 0; j < h.nsat; j++) { /* phaserangerate */ + rate = getbits(rtcm->buff, i, 14); + i += 14; + if (rate != -8192) rr[j] = rate * 1.0; + } + /* decode signal data */ + for (j = 0; j < ncell; j++) { /* pseudorange */ + prv = getbits(rtcm->buff, i, 15); + i += 15; + if (prv != -16384) pr[j] = prv * P2_24 * RANGE_MS; + } + for (j = 0; j < ncell; j++) { /* phaserange */ + cpv = getbits(rtcm->buff, i, 22); + i += 22; + if (cpv != -2097152) cp[j] = cpv * P2_29 * RANGE_MS; + } + for (j = 0; j < ncell; j++) { /* lock time */ + lock[j] = getbitu(rtcm->buff, i, 4); + i += 4; + } + for (j = 0; j < ncell; j++) { /* half-cycle ambiguity */ + half[j] = getbitu(rtcm->buff, i, 1); + i += 1; + } + for (j = 0; j < ncell; j++) { /* cnr */ + cnr[j] = getbitu(rtcm->buff, i, 6) * 1.0; + i += 6; + } + for (j = 0; j < ncell; j++) { /* phaserangerate */ + rrv = getbits(rtcm->buff, i, 15); + i += 15; + if (rrv != -16384) rrf[j] = rrv * 0.0001; + } + /* save obs data in msm message */ + save_msm_obs(rtcm, sys, &h, r, pr, cp, rr, rrf, cnr, lock, ex, half); + + rtcm->obsflag = !sync; + return sync ? 0 : 1; } /* decode MSM 6: full pseudorange and phaserange plus CNR (high-res) ---------*/ -static int decode_msm6(rtcm_t *rtcm, int sys) -{ - msm_h_t h={0}; - double r[64],pr[64],cp[64],cnr[64]; - int i,j,type,sync,iod,ncell,rng,rng_m,prv,cpv,lock[64],half[64]; - - type=getbitu(rtcm->buff,24,12); - - /* decode msm header */ - if ((ncell=decode_msm_head(rtcm,sys,&sync,&iod,&h,&i))<0) return -1; - - if (i+h.nsat*18+ncell*65>rtcm->len*8) { - trace(2,"rtcm3 %d length error: nsat=%d ncell=%d len=%d\n",type,h.nsat, - ncell,rtcm->len); - rtcm->obsflag=!sync; /* header ok, so return sync bit */ - return sync?0:1; - } - for (j=0;jbuff,i, 8); i+= 8; - if (rng!=255) r[j]=rng*RANGE_MS; - } - for (j=0;jbuff,i,10); i+=10; - if (r[j]!=0.0) r[j]+=rng_m*P2_10*RANGE_MS; - } - /* decode signal data */ - for (j=0;jbuff,i,20); i+=20; - if (prv!=-524288) pr[j]=prv*P2_29*RANGE_MS; - } - for (j=0;jbuff,i,24); i+=24; - if (cpv!=-8388608) cp[j]=cpv*P2_31*RANGE_MS; - } - for (j=0;jbuff,i,10); i+=10; - } - for (j=0;jbuff,i,1); i+=1; - } - for (j=0;jbuff,i,10)*0.0625; i+=10; - } - /* save obs data in msm message */ - save_msm_obs(rtcm,sys,&h,r,pr,cp,NULL,NULL,cnr,lock,NULL,half); - - rtcm->obsflag=!sync; - return sync?0:1; +static int decode_msm6(rtcm_t *rtcm, int sys) { + msm_h_t h = {0}; + double r[64], pr[64], cp[64], cnr[64]; + int i, j, type, sync, iod, ncell, rng, rng_m, prv, cpv, lock[64], half[64]; + + type = getbitu(rtcm->buff, 24, 12); + + /* decode msm header */ + if ((ncell = decode_msm_head(rtcm, sys, &sync, &iod, &h, &i)) < 0) return -1; + + if (i + h.nsat * 18 + ncell * 65 > rtcm->len * 8) { + trace(2, "rtcm3 %d length error: nsat=%d ncell=%d len=%d\n", type, h.nsat, ncell, rtcm->len); + rtcm->obsflag = !sync; /* header ok, so return sync bit */ + return sync ? 0 : 1; + } + for (j = 0; j < h.nsat; j++) r[j] = 0.0; + for (j = 0; j < ncell; j++) pr[j] = cp[j] = -1E16; + + /* decode satellite data */ + for (j = 0; j < h.nsat; j++) { /* range */ + rng = getbitu(rtcm->buff, i, 8); + i += 8; + if (rng != 255) r[j] = rng * RANGE_MS; + } + for (j = 0; j < h.nsat; j++) { + rng_m = getbitu(rtcm->buff, i, 10); + i += 10; + if (r[j] != 0.0) r[j] += rng_m * P2_10 * RANGE_MS; + } + /* decode signal data */ + for (j = 0; j < ncell; j++) { /* pseudorange */ + prv = getbits(rtcm->buff, i, 20); + i += 20; + if (prv != -524288) pr[j] = prv * P2_29 * RANGE_MS; + } + for (j = 0; j < ncell; j++) { /* phaserange */ + cpv = getbits(rtcm->buff, i, 24); + i += 24; + if (cpv != -8388608) cp[j] = cpv * P2_31 * RANGE_MS; + } + for (j = 0; j < ncell; j++) { /* lock time */ + lock[j] = getbitu(rtcm->buff, i, 10); + i += 10; + } + for (j = 0; j < ncell; j++) { /* half-cycle ambiguity */ + half[j] = getbitu(rtcm->buff, i, 1); + i += 1; + } + for (j = 0; j < ncell; j++) { /* cnr */ + cnr[j] = getbitu(rtcm->buff, i, 10) * 0.0625; + i += 10; + } + /* save obs data in msm message */ + save_msm_obs(rtcm, sys, &h, r, pr, cp, NULL, NULL, cnr, lock, NULL, half); + + rtcm->obsflag = !sync; + return sync ? 0 : 1; } /* decode MSM 7: full pseudorange, phaserange, phaserangerate and CNR (h-res) */ -static int decode_msm7(rtcm_t *rtcm, int sys) -{ - msm_h_t h={0}; - double r[64],rr[64],pr[64],cp[64],rrf[64],cnr[64]; - int i,j,type,sync,iod,ncell,rng,rng_m,rate,prv,cpv,rrv,lock[64]; - int ex[64],half[64]; - - type=getbitu(rtcm->buff,24,12); - - /* decode msm header */ - if ((ncell=decode_msm_head(rtcm,sys,&sync,&iod,&h,&i))<0) return -1; - - if (i+h.nsat*36+ncell*80>rtcm->len*8) { - trace(2,"rtcm3 %d length error: nsat=%d ncell=%d len=%d\n",type,h.nsat, - ncell,rtcm->len); - rtcm->obsflag=!sync; /* header ok, so return sync bit */ - return sync?0:1; - } - for (j=0;jbuff,i, 8); i+= 8; - if (rng!=255) r[j]=rng*RANGE_MS; - } - for (j=0;jbuff,i, 4); i+= 4; - } - for (j=0;jbuff,i,10); i+=10; - if (r[j]!=0.0) r[j]+=rng_m*P2_10*RANGE_MS; - } - for (j=0;jbuff,i,14); i+=14; - if (rate!=-8192) { - rr[j]=rate*1.0; - if (strstr(rtcm->opt,"-INVPRR")) rr[j] = -rr[j]; - } - } - /* decode signal data */ - for (j=0;jbuff,i,20); i+=20; - if (prv!=-524288) pr[j]=prv*P2_29*RANGE_MS; - } - for (j=0;jbuff,i,24); i+=24; - if (cpv!=-8388608) cp[j]=cpv*P2_31*RANGE_MS; - } - for (j=0;jbuff,i,10); i+=10; - } - for (j=0;jbuff,i,1); i+=1; - } - for (j=0;jbuff,i,10)*0.0625; i+=10; - } - for (j=0;jbuff,i,15); i+=15; - if (rrv!=-16384) { - rrf[j]=rrv*0.0001; - if (strstr(rtcm->opt,"-INVPRR")) rrf[j] = -rrf[j]; - } - } - /* save obs data in msm message */ - save_msm_obs(rtcm,sys,&h,r,pr,cp,rr,rrf,cnr,lock,ex,half); - - rtcm->obsflag=!sync; - return sync?0:1; +static int decode_msm7(rtcm_t *rtcm, int sys) { + msm_h_t h = {0}; + double r[64], rr[64], pr[64], cp[64], rrf[64], cnr[64]; + int i, j, type, sync, iod, ncell, rng, rng_m, rate, prv, cpv, rrv, lock[64]; + int ex[64], half[64]; + + type = getbitu(rtcm->buff, 24, 12); + + /* decode msm header */ + if ((ncell = decode_msm_head(rtcm, sys, &sync, &iod, &h, &i)) < 0) return -1; + + if (i + h.nsat * 36 + ncell * 80 > rtcm->len * 8) { + trace(2, "rtcm3 %d length error: nsat=%d ncell=%d len=%d\n", type, h.nsat, ncell, rtcm->len); + rtcm->obsflag = !sync; /* header ok, so return sync bit */ + return sync ? 0 : 1; + } + for (j = 0; j < h.nsat; j++) { + r[j] = rr[j] = 0.0; + ex[j] = 15; + } + for (j = 0; j < ncell; j++) pr[j] = cp[j] = rrf[j] = -1E16; + + /* decode satellite data */ + for (j = 0; j < h.nsat; j++) { /* range */ + rng = getbitu(rtcm->buff, i, 8); + i += 8; + if (rng != 255) r[j] = rng * RANGE_MS; + } + for (j = 0; j < h.nsat; j++) { /* extended info */ + ex[j] = getbitu(rtcm->buff, i, 4); + i += 4; + } + for (j = 0; j < h.nsat; j++) { + rng_m = getbitu(rtcm->buff, i, 10); + i += 10; + if (r[j] != 0.0) r[j] += rng_m * P2_10 * RANGE_MS; + } + for (j = 0; j < h.nsat; j++) { /* phaserangerate */ + rate = getbits(rtcm->buff, i, 14); + i += 14; + if (rate != -8192) { + rr[j] = rate * 1.0; + if (strstr(rtcm->opt, "-INVPRR")) rr[j] = -rr[j]; + } + } + /* decode signal data */ + for (j = 0; j < ncell; j++) { /* pseudorange */ + prv = getbits(rtcm->buff, i, 20); + i += 20; + if (prv != -524288) pr[j] = prv * P2_29 * RANGE_MS; + } + for (j = 0; j < ncell; j++) { /* phaserange */ + cpv = getbits(rtcm->buff, i, 24); + i += 24; + if (cpv != -8388608) cp[j] = cpv * P2_31 * RANGE_MS; + } + for (j = 0; j < ncell; j++) { /* lock time */ + lock[j] = getbitu(rtcm->buff, i, 10); + i += 10; + } + for (j = 0; j < ncell; j++) { /* half-cycle amiguity */ + half[j] = getbitu(rtcm->buff, i, 1); + i += 1; + } + for (j = 0; j < ncell; j++) { /* cnr */ + cnr[j] = getbitu(rtcm->buff, i, 10) * 0.0625; + i += 10; + } + for (j = 0; j < ncell; j++) { /* phaserangerate */ + rrv = getbits(rtcm->buff, i, 15); + i += 15; + if (rrv != -16384) { + rrf[j] = rrv * 0.0001; + if (strstr(rtcm->opt, "-INVPRR")) rrf[j] = -rrf[j]; + } + } + /* save obs data in msm message */ + save_msm_obs(rtcm, sys, &h, r, pr, cp, rr, rrf, cnr, lock, ex, half); + + rtcm->obsflag = !sync; + return sync ? 0 : 1; } /* decode type 1230: GLONASS L1 and L2 code-phase biases ---------------------*/ -static int decode_type1230(rtcm_t *rtcm) -{ - int i=24+12,j,staid,align,mask,bias; - - if (i+20>=rtcm->len*8) { - trace(2,"rtcm3 1230: length error len=%d\n",rtcm->len); - return -1; - } - staid=getbitu(rtcm->buff,i,12); i+=12; - align=getbitu(rtcm->buff,i, 1); i+= 1+3; - mask =getbitu(rtcm->buff,i, 4); i+= 4; - - if (rtcm->outtype) { - sprintf(rtcm->msgtype+strlen(rtcm->msgtype), - " staid=%4d align=%d mask=0x%X",staid,align,mask); - } - /* test station ID */ - if (!test_staid(rtcm,staid)) return -1; - - rtcm->sta.glo_cp_align=align; - for (j=0;j<4;j++) { - rtcm->sta.glo_cp_bias[j]=0.0; - } - for (j=0;j<4&&i+16<=rtcm->len*8;j++) { - if (!(mask&(1<<(3-j)))) continue; - bias=getbits(rtcm->buff,i,16); i+=16; - if (bias!=-32768) { - rtcm->sta.glo_cp_bias[j]=bias*0.02; - } - } - return 5; +static int decode_type1230(rtcm_t *rtcm) { + int i = 24 + 12, j, staid, align, mask, bias; + + if (i + 20 >= rtcm->len * 8) { + trace(2, "rtcm3 1230: length error len=%d\n", rtcm->len); + return -1; + } + staid = getbitu(rtcm->buff, i, 12); + i += 12; + align = getbitu(rtcm->buff, i, 1); + i += 1 + 3; + mask = getbitu(rtcm->buff, i, 4); + i += 4; + + if (rtcm->outtype) { + sprintf(rtcm->msgtype + strlen(rtcm->msgtype), " staid=%4d align=%d mask=0x%X", staid, align, + mask); + } + /* test station ID */ + if (!test_staid(rtcm, staid)) return -1; + + rtcm->sta.glo_cp_align = align; + for (j = 0; j < 4; j++) { + rtcm->sta.glo_cp_bias[j] = 0.0; + } + for (j = 0; j < 4 && i + 16 <= rtcm->len * 8; j++) { + if (!(mask & (1 << (3 - j)))) continue; + bias = getbits(rtcm->buff, i, 16); + i += 16; + if (bias != -32768) { + rtcm->sta.glo_cp_bias[j] = bias * 0.02; + } + } + return 5; } /* decode type 4073: proprietary message Mitsubishi Electric -----------------*/ -static int decode_type4073(rtcm_t *rtcm) -{ - int i=24+12,subtype; - - subtype=getbitu(rtcm->buff,i,4); i+=4; - - if (rtcm->outtype) { - sprintf(rtcm->msgtype+strlen(rtcm->msgtype)," subtype=%d",subtype); - } - trace(2,"rtcm3 4073: unsupported message subtype=%d\n",subtype); - return 0; +static int decode_type4073(rtcm_t *rtcm) { + int i = 24 + 12, subtype; + + subtype = getbitu(rtcm->buff, i, 4); + i += 4; + + if (rtcm->outtype) { + sprintf(rtcm->msgtype + strlen(rtcm->msgtype), " subtype=%d", subtype); + } + trace(2, "rtcm3 4073: unsupported message subtype=%d\n", subtype); + return 0; } /* decode type 4076: proprietary message IGS ---------------------------------*/ -static int decode_type4076(rtcm_t *rtcm) -{ - int i=24+12,ver,subtype; - - if (i+3+8>=rtcm->len*8) { - trace(2,"rtcm3 4076: length error len=%d\n",rtcm->len); - return -1; - } - ver =getbitu(rtcm->buff,i,3); i+=3; - subtype=getbitu(rtcm->buff,i,8); i+=8; - - if (rtcm->outtype) { - sprintf(rtcm->msgtype+strlen(rtcm->msgtype)," ver=%d subtype=%3d",ver, - subtype); - } - switch (subtype) { - case 21: return decode_ssr1(rtcm,SYS_GPS,subtype); - case 22: return decode_ssr2(rtcm,SYS_GPS,subtype); - case 23: return decode_ssr4(rtcm,SYS_GPS,subtype); - case 24: return decode_ssr6(rtcm,SYS_GPS,subtype); - case 25: return decode_ssr3(rtcm,SYS_GPS,subtype); - case 26: return decode_ssr7(rtcm,SYS_GPS,subtype); - case 27: return decode_ssr5(rtcm,SYS_GPS,subtype); - case 41: return decode_ssr1(rtcm,SYS_GLO,subtype); - case 42: return decode_ssr2(rtcm,SYS_GLO,subtype); - case 43: return decode_ssr4(rtcm,SYS_GLO,subtype); - case 44: return decode_ssr6(rtcm,SYS_GLO,subtype); - case 45: return decode_ssr3(rtcm,SYS_GLO,subtype); - case 46: return decode_ssr7(rtcm,SYS_GLO,subtype); - case 47: return decode_ssr5(rtcm,SYS_GLO,subtype); - case 61: return decode_ssr1(rtcm,SYS_GAL,subtype); - case 62: return decode_ssr2(rtcm,SYS_GAL,subtype); - case 63: return decode_ssr4(rtcm,SYS_GAL,subtype); - case 64: return decode_ssr6(rtcm,SYS_GAL,subtype); - case 65: return decode_ssr3(rtcm,SYS_GAL,subtype); - case 66: return decode_ssr7(rtcm,SYS_GAL,subtype); - case 67: return decode_ssr5(rtcm,SYS_GAL,subtype); - case 81: return decode_ssr1(rtcm,SYS_QZS,subtype); - case 82: return decode_ssr2(rtcm,SYS_QZS,subtype); - case 83: return decode_ssr4(rtcm,SYS_QZS,subtype); - case 84: return decode_ssr6(rtcm,SYS_QZS,subtype); - case 85: return decode_ssr3(rtcm,SYS_QZS,subtype); - case 86: return decode_ssr7(rtcm,SYS_QZS,subtype); - case 87: return decode_ssr5(rtcm,SYS_QZS,subtype); - case 101: return decode_ssr1(rtcm,SYS_CMP,subtype); - case 102: return decode_ssr2(rtcm,SYS_CMP,subtype); - case 103: return decode_ssr4(rtcm,SYS_CMP,subtype); - case 104: return decode_ssr6(rtcm,SYS_CMP,subtype); - case 105: return decode_ssr3(rtcm,SYS_CMP,subtype); - case 106: return decode_ssr7(rtcm,SYS_CMP,subtype); - case 107: return decode_ssr5(rtcm,SYS_CMP,subtype); - case 121: return decode_ssr1(rtcm,SYS_SBS,subtype); - case 122: return decode_ssr2(rtcm,SYS_SBS,subtype); - case 123: return decode_ssr4(rtcm,SYS_SBS,subtype); - case 124: return decode_ssr6(rtcm,SYS_SBS,subtype); - case 125: return decode_ssr3(rtcm,SYS_SBS,subtype); - case 126: return decode_ssr7(rtcm,SYS_SBS,subtype); - case 127: return decode_ssr5(rtcm,SYS_SBS,subtype); - } - trace(2,"rtcm3 4076: unsupported message subtype=%d\n",subtype); - return 0; +static int decode_type4076(rtcm_t *rtcm) { + int i = 24 + 12, ver, subtype; + + if (i + 3 + 8 >= rtcm->len * 8) { + trace(2, "rtcm3 4076: length error len=%d\n", rtcm->len); + return -1; + } + ver = getbitu(rtcm->buff, i, 3); + i += 3; + subtype = getbitu(rtcm->buff, i, 8); + i += 8; + + if (rtcm->outtype) { + sprintf(rtcm->msgtype + strlen(rtcm->msgtype), " ver=%d subtype=%3d", ver, subtype); + } + switch (subtype) { + case 21: + return decode_ssr1(rtcm, SYS_GPS, subtype); + case 22: + return decode_ssr2(rtcm, SYS_GPS, subtype); + case 23: + return decode_ssr4(rtcm, SYS_GPS, subtype); + case 24: + return decode_ssr6(rtcm, SYS_GPS, subtype); + case 25: + return decode_ssr3(rtcm, SYS_GPS, subtype); + case 26: + return decode_ssr7(rtcm, SYS_GPS, subtype); + case 27: + return decode_ssr5(rtcm, SYS_GPS, subtype); + case 41: + return decode_ssr1(rtcm, SYS_GLO, subtype); + case 42: + return decode_ssr2(rtcm, SYS_GLO, subtype); + case 43: + return decode_ssr4(rtcm, SYS_GLO, subtype); + case 44: + return decode_ssr6(rtcm, SYS_GLO, subtype); + case 45: + return decode_ssr3(rtcm, SYS_GLO, subtype); + case 46: + return decode_ssr7(rtcm, SYS_GLO, subtype); + case 47: + return decode_ssr5(rtcm, SYS_GLO, subtype); + case 61: + return decode_ssr1(rtcm, SYS_GAL, subtype); + case 62: + return decode_ssr2(rtcm, SYS_GAL, subtype); + case 63: + return decode_ssr4(rtcm, SYS_GAL, subtype); + case 64: + return decode_ssr6(rtcm, SYS_GAL, subtype); + case 65: + return decode_ssr3(rtcm, SYS_GAL, subtype); + case 66: + return decode_ssr7(rtcm, SYS_GAL, subtype); + case 67: + return decode_ssr5(rtcm, SYS_GAL, subtype); + case 81: + return decode_ssr1(rtcm, SYS_QZS, subtype); + case 82: + return decode_ssr2(rtcm, SYS_QZS, subtype); + case 83: + return decode_ssr4(rtcm, SYS_QZS, subtype); + case 84: + return decode_ssr6(rtcm, SYS_QZS, subtype); + case 85: + return decode_ssr3(rtcm, SYS_QZS, subtype); + case 86: + return decode_ssr7(rtcm, SYS_QZS, subtype); + case 87: + return decode_ssr5(rtcm, SYS_QZS, subtype); + case 101: + return decode_ssr1(rtcm, SYS_CMP, subtype); + case 102: + return decode_ssr2(rtcm, SYS_CMP, subtype); + case 103: + return decode_ssr4(rtcm, SYS_CMP, subtype); + case 104: + return decode_ssr6(rtcm, SYS_CMP, subtype); + case 105: + return decode_ssr3(rtcm, SYS_CMP, subtype); + case 106: + return decode_ssr7(rtcm, SYS_CMP, subtype); + case 107: + return decode_ssr5(rtcm, SYS_CMP, subtype); + case 121: + return decode_ssr1(rtcm, SYS_SBS, subtype); + case 122: + return decode_ssr2(rtcm, SYS_SBS, subtype); + case 123: + return decode_ssr4(rtcm, SYS_SBS, subtype); + case 124: + return decode_ssr6(rtcm, SYS_SBS, subtype); + case 125: + return decode_ssr3(rtcm, SYS_SBS, subtype); + case 126: + return decode_ssr7(rtcm, SYS_SBS, subtype); + case 127: + return decode_ssr5(rtcm, SYS_SBS, subtype); + } + trace(2, "rtcm3 4076: unsupported message subtype=%d\n", subtype); + return 0; } /* decode RTCM ver.3 message -------------------------------------------------*/ -extern int decode_rtcm3(rtcm_t *rtcm) -{ - double tow; - int ret=0,type=getbitu(rtcm->buff,24,12),week; - - trace(3,"decode_rtcm3: len=%3d type=%d\n",rtcm->len,type); - - if (rtcm->outtype) { - sprintf(rtcm->msgtype,"RTCM %4d (%4d):",type,rtcm->len); - } - /* real-time input option */ - if (strstr(rtcm->opt,"-RT_INP")) { - tow=time2gpst(utc2gpst(timeget()),&week); - rtcm->time=gpst2time(week,floor(tow)); - } - switch (type) { - case 1001: ret=decode_type1001(rtcm); break; /* not supported */ - case 1002: ret=decode_type1002(rtcm); break; - case 1003: ret=decode_type1003(rtcm); break; /* not supported */ - case 1004: ret=decode_type1004(rtcm); break; - case 1005: ret=decode_type1005(rtcm); break; - case 1006: ret=decode_type1006(rtcm); break; - case 1007: ret=decode_type1007(rtcm); break; - case 1008: ret=decode_type1008(rtcm); break; - case 1009: ret=decode_type1009(rtcm); break; /* not supported */ - case 1010: ret=decode_type1010(rtcm); break; - case 1011: ret=decode_type1011(rtcm); break; /* not supported */ - case 1012: ret=decode_type1012(rtcm); break; - case 1013: ret=decode_type1013(rtcm); break; /* not supported */ - case 1019: ret=decode_type1019(rtcm); break; - case 1020: ret=decode_type1020(rtcm); break; - case 1021: ret=decode_type1021(rtcm); break; /* not supported */ - case 1022: ret=decode_type1022(rtcm); break; /* not supported */ - case 1023: ret=decode_type1023(rtcm); break; /* not supported */ - case 1024: ret=decode_type1024(rtcm); break; /* not supported */ - case 1025: ret=decode_type1025(rtcm); break; /* not supported */ - case 1026: ret=decode_type1026(rtcm); break; /* not supported */ - case 1027: ret=decode_type1027(rtcm); break; /* not supported */ - case 1029: ret=decode_type1029(rtcm); break; - case 1030: ret=decode_type1030(rtcm); break; /* not supported */ - case 1031: ret=decode_type1031(rtcm); break; /* not supported */ - case 1032: ret=decode_type1032(rtcm); break; /* not supported */ - case 1033: ret=decode_type1033(rtcm); break; - case 1034: ret=decode_type1034(rtcm); break; /* not supported */ - case 1035: ret=decode_type1035(rtcm); break; /* not supported */ - case 1037: ret=decode_type1037(rtcm); break; /* not supported */ - case 1038: ret=decode_type1038(rtcm); break; /* not supported */ - case 1039: ret=decode_type1039(rtcm); break; /* not supported */ - case 1041: ret=decode_type1041(rtcm); break; - case 1044: ret=decode_type1044(rtcm); break; - case 1045: ret=decode_type1045(rtcm); break; - case 1046: ret=decode_type1046(rtcm); break; - case 63: ret=decode_type1042(rtcm); break; /* RTCM draft */ - case 1042: ret=decode_type1042(rtcm); break; - case 1057: ret=decode_ssr1(rtcm,SYS_GPS,0); break; - case 1058: ret=decode_ssr2(rtcm,SYS_GPS,0); break; - case 1059: ret=decode_ssr3(rtcm,SYS_GPS,0); break; - case 1060: ret=decode_ssr4(rtcm,SYS_GPS,0); break; - case 1061: ret=decode_ssr5(rtcm,SYS_GPS,0); break; - case 1062: ret=decode_ssr6(rtcm,SYS_GPS,0); break; - case 1063: ret=decode_ssr1(rtcm,SYS_GLO,0); break; - case 1064: ret=decode_ssr2(rtcm,SYS_GLO,0); break; - case 1065: ret=decode_ssr3(rtcm,SYS_GLO,0); break; - case 1066: ret=decode_ssr4(rtcm,SYS_GLO,0); break; - case 1067: ret=decode_ssr5(rtcm,SYS_GLO,0); break; - case 1068: ret=decode_ssr6(rtcm,SYS_GLO,0); break; - case 1071: ret=decode_msm0(rtcm,SYS_GPS); break; /* not supported */ - case 1072: ret=decode_msm0(rtcm,SYS_GPS); break; /* not supported */ - case 1073: ret=decode_msm0(rtcm,SYS_GPS); break; /* not supported */ - case 1074: ret=decode_msm4(rtcm,SYS_GPS); break; - case 1075: ret=decode_msm5(rtcm,SYS_GPS); break; - case 1076: ret=decode_msm6(rtcm,SYS_GPS); break; - case 1077: ret=decode_msm7(rtcm,SYS_GPS); break; - case 1081: ret=decode_msm0(rtcm,SYS_GLO); break; /* not supported */ - case 1082: ret=decode_msm0(rtcm,SYS_GLO); break; /* not supported */ - case 1083: ret=decode_msm0(rtcm,SYS_GLO); break; /* not supported */ - case 1084: ret=decode_msm4(rtcm,SYS_GLO); break; - case 1085: ret=decode_msm5(rtcm,SYS_GLO); break; - case 1086: ret=decode_msm6(rtcm,SYS_GLO); break; - case 1087: ret=decode_msm7(rtcm,SYS_GLO); break; - case 1091: ret=decode_msm0(rtcm,SYS_GAL); break; /* not supported */ - case 1092: ret=decode_msm0(rtcm,SYS_GAL); break; /* not supported */ - case 1093: ret=decode_msm0(rtcm,SYS_GAL); break; /* not supported */ - case 1094: ret=decode_msm4(rtcm,SYS_GAL); break; - case 1095: ret=decode_msm5(rtcm,SYS_GAL); break; - case 1096: ret=decode_msm6(rtcm,SYS_GAL); break; - case 1097: ret=decode_msm7(rtcm,SYS_GAL); break; - case 1101: ret=decode_msm0(rtcm,SYS_SBS); break; /* not supported */ - case 1102: ret=decode_msm0(rtcm,SYS_SBS); break; /* not supported */ - case 1103: ret=decode_msm0(rtcm,SYS_SBS); break; /* not supported */ - case 1104: ret=decode_msm4(rtcm,SYS_SBS); break; - case 1105: ret=decode_msm5(rtcm,SYS_SBS); break; - case 1106: ret=decode_msm6(rtcm,SYS_SBS); break; - case 1107: ret=decode_msm7(rtcm,SYS_SBS); break; - case 1111: ret=decode_msm0(rtcm,SYS_QZS); break; /* not supported */ - case 1112: ret=decode_msm0(rtcm,SYS_QZS); break; /* not supported */ - case 1113: ret=decode_msm0(rtcm,SYS_QZS); break; /* not supported */ - case 1114: ret=decode_msm4(rtcm,SYS_QZS); break; - case 1115: ret=decode_msm5(rtcm,SYS_QZS); break; - case 1116: ret=decode_msm6(rtcm,SYS_QZS); break; - case 1117: ret=decode_msm7(rtcm,SYS_QZS); break; - case 1121: ret=decode_msm0(rtcm,SYS_CMP); break; /* not supported */ - case 1122: ret=decode_msm0(rtcm,SYS_CMP); break; /* not supported */ - case 1123: ret=decode_msm0(rtcm,SYS_CMP); break; /* not supported */ - case 1124: ret=decode_msm4(rtcm,SYS_CMP); break; - case 1125: ret=decode_msm5(rtcm,SYS_CMP); break; - case 1126: ret=decode_msm6(rtcm,SYS_CMP); break; - case 1127: ret=decode_msm7(rtcm,SYS_CMP); break; - case 1131: ret=decode_msm0(rtcm,SYS_IRN); break; /* not supported */ - case 1132: ret=decode_msm0(rtcm,SYS_IRN); break; /* not supported */ - case 1133: ret=decode_msm0(rtcm,SYS_IRN); break; /* not supported */ - case 1134: ret=decode_msm4(rtcm,SYS_IRN); break; - case 1135: ret=decode_msm5(rtcm,SYS_IRN); break; - case 1136: ret=decode_msm6(rtcm,SYS_IRN); break; - case 1137: ret=decode_msm7(rtcm,SYS_IRN); break; - case 1230: ret=decode_type1230(rtcm); break; - case 1240: ret=decode_ssr1(rtcm,SYS_GAL,0); break; /* draft */ - case 1241: ret=decode_ssr2(rtcm,SYS_GAL,0); break; /* draft */ - case 1242: ret=decode_ssr3(rtcm,SYS_GAL,0); break; /* draft */ - case 1243: ret=decode_ssr4(rtcm,SYS_GAL,0); break; /* draft */ - case 1244: ret=decode_ssr5(rtcm,SYS_GAL,0); break; /* draft */ - case 1245: ret=decode_ssr6(rtcm,SYS_GAL,0); break; /* draft */ - case 1246: ret=decode_ssr1(rtcm,SYS_QZS,0); break; /* draft */ - case 1247: ret=decode_ssr2(rtcm,SYS_QZS,0); break; /* draft */ - case 1248: ret=decode_ssr3(rtcm,SYS_QZS,0); break; /* draft */ - case 1249: ret=decode_ssr4(rtcm,SYS_QZS,0); break; /* draft */ - case 1250: ret=decode_ssr5(rtcm,SYS_QZS,0); break; /* draft */ - case 1251: ret=decode_ssr6(rtcm,SYS_QZS,0); break; /* draft */ - case 1252: ret=decode_ssr1(rtcm,SYS_SBS,0); break; /* draft */ - case 1253: ret=decode_ssr2(rtcm,SYS_SBS,0); break; /* draft */ - case 1254: ret=decode_ssr3(rtcm,SYS_SBS,0); break; /* draft */ - case 1255: ret=decode_ssr4(rtcm,SYS_SBS,0); break; /* draft */ - case 1256: ret=decode_ssr5(rtcm,SYS_SBS,0); break; /* draft */ - case 1257: ret=decode_ssr6(rtcm,SYS_SBS,0); break; /* draft */ - case 1258: ret=decode_ssr1(rtcm,SYS_CMP,0); break; /* draft */ - case 1259: ret=decode_ssr2(rtcm,SYS_CMP,0); break; /* draft */ - case 1260: ret=decode_ssr3(rtcm,SYS_CMP,0); break; /* draft */ - case 1261: ret=decode_ssr4(rtcm,SYS_CMP,0); break; /* draft */ - case 1262: ret=decode_ssr5(rtcm,SYS_CMP,0); break; /* draft */ - case 1263: ret=decode_ssr6(rtcm,SYS_CMP,0); break; /* draft */ - case 11: ret=decode_ssr7(rtcm,SYS_GPS,0); break; /* tentative */ - case 12: ret=decode_ssr7(rtcm,SYS_GAL,0); break; /* tentative */ - case 13: ret=decode_ssr7(rtcm,SYS_QZS,0); break; /* tentative */ - case 14: ret=decode_ssr7(rtcm,SYS_CMP,0); break; /* tentative */ - case 4073: ret=decode_type4073(rtcm); break; - case 4076: ret=decode_type4076(rtcm); break; - } - if (ret>=0) { - if (1001<=type&&type<=1299) rtcm->nmsg3[type-1000]++; /* 1-299 */ - else if (4070<=type&&type<=4099) rtcm->nmsg3[type-3770]++; /* 300-329 */ - else rtcm->nmsg3[0]++; /* other */ - } - return ret; +extern int decode_rtcm3(rtcm_t *rtcm) { + double tow; + int ret = 0, type = getbitu(rtcm->buff, 24, 12), week; + + trace(3, "decode_rtcm3: len=%3d type=%d\n", rtcm->len, type); + + if (rtcm->outtype) { + sprintf(rtcm->msgtype, "RTCM %4d (%4d):", type, rtcm->len); + } + /* real-time input option */ + if (strstr(rtcm->opt, "-RT_INP")) { + tow = time2gpst(utc2gpst(timeget()), &week); + rtcm->time = gpst2time(week, floor(tow)); + } + switch (type) { + case 1001: + ret = decode_type1001(rtcm); + break; /* not supported */ + case 1002: + ret = decode_type1002(rtcm); + break; + case 1003: + ret = decode_type1003(rtcm); + break; /* not supported */ + case 1004: + ret = decode_type1004(rtcm); + break; + case 1005: + ret = decode_type1005(rtcm); + break; + case 1006: + ret = decode_type1006(rtcm); + break; + case 1007: + ret = decode_type1007(rtcm); + break; + case 1008: + ret = decode_type1008(rtcm); + break; + case 1009: + ret = decode_type1009(rtcm); + break; /* not supported */ + case 1010: + ret = decode_type1010(rtcm); + break; + case 1011: + ret = decode_type1011(rtcm); + break; /* not supported */ + case 1012: + ret = decode_type1012(rtcm); + break; + case 1013: + ret = decode_type1013(rtcm); + break; /* not supported */ + case 1019: + ret = decode_type1019(rtcm); + break; + case 1020: + ret = decode_type1020(rtcm); + break; + case 1021: + ret = decode_type1021(rtcm); + break; /* not supported */ + case 1022: + ret = decode_type1022(rtcm); + break; /* not supported */ + case 1023: + ret = decode_type1023(rtcm); + break; /* not supported */ + case 1024: + ret = decode_type1024(rtcm); + break; /* not supported */ + case 1025: + ret = decode_type1025(rtcm); + break; /* not supported */ + case 1026: + ret = decode_type1026(rtcm); + break; /* not supported */ + case 1027: + ret = decode_type1027(rtcm); + break; /* not supported */ + case 1029: + ret = decode_type1029(rtcm); + break; + case 1030: + ret = decode_type1030(rtcm); + break; /* not supported */ + case 1031: + ret = decode_type1031(rtcm); + break; /* not supported */ + case 1032: + ret = decode_type1032(rtcm); + break; /* not supported */ + case 1033: + ret = decode_type1033(rtcm); + break; + case 1034: + ret = decode_type1034(rtcm); + break; /* not supported */ + case 1035: + ret = decode_type1035(rtcm); + break; /* not supported */ + case 1037: + ret = decode_type1037(rtcm); + break; /* not supported */ + case 1038: + ret = decode_type1038(rtcm); + break; /* not supported */ + case 1039: + ret = decode_type1039(rtcm); + break; /* not supported */ + case 1041: + ret = decode_type1041(rtcm); + break; + case 1044: + ret = decode_type1044(rtcm); + break; + case 1045: + ret = decode_type1045(rtcm); + break; + case 1046: + ret = decode_type1046(rtcm); + break; + case 63: + ret = decode_type1042(rtcm); + break; /* RTCM draft */ + case 1042: + ret = decode_type1042(rtcm); + break; + case 1057: + ret = decode_ssr1(rtcm, SYS_GPS, 0); + break; + case 1058: + ret = decode_ssr2(rtcm, SYS_GPS, 0); + break; + case 1059: + ret = decode_ssr3(rtcm, SYS_GPS, 0); + break; + case 1060: + ret = decode_ssr4(rtcm, SYS_GPS, 0); + break; + case 1061: + ret = decode_ssr5(rtcm, SYS_GPS, 0); + break; + case 1062: + ret = decode_ssr6(rtcm, SYS_GPS, 0); + break; + case 1063: + ret = decode_ssr1(rtcm, SYS_GLO, 0); + break; + case 1064: + ret = decode_ssr2(rtcm, SYS_GLO, 0); + break; + case 1065: + ret = decode_ssr3(rtcm, SYS_GLO, 0); + break; + case 1066: + ret = decode_ssr4(rtcm, SYS_GLO, 0); + break; + case 1067: + ret = decode_ssr5(rtcm, SYS_GLO, 0); + break; + case 1068: + ret = decode_ssr6(rtcm, SYS_GLO, 0); + break; + case 1071: + ret = decode_msm0(rtcm, SYS_GPS); + break; /* not supported */ + case 1072: + ret = decode_msm0(rtcm, SYS_GPS); + break; /* not supported */ + case 1073: + ret = decode_msm0(rtcm, SYS_GPS); + break; /* not supported */ + case 1074: + ret = decode_msm4(rtcm, SYS_GPS); + break; + case 1075: + ret = decode_msm5(rtcm, SYS_GPS); + break; + case 1076: + ret = decode_msm6(rtcm, SYS_GPS); + break; + case 1077: + ret = decode_msm7(rtcm, SYS_GPS); + break; + case 1081: + ret = decode_msm0(rtcm, SYS_GLO); + break; /* not supported */ + case 1082: + ret = decode_msm0(rtcm, SYS_GLO); + break; /* not supported */ + case 1083: + ret = decode_msm0(rtcm, SYS_GLO); + break; /* not supported */ + case 1084: + ret = decode_msm4(rtcm, SYS_GLO); + break; + case 1085: + ret = decode_msm5(rtcm, SYS_GLO); + break; + case 1086: + ret = decode_msm6(rtcm, SYS_GLO); + break; + case 1087: + ret = decode_msm7(rtcm, SYS_GLO); + break; + case 1091: + ret = decode_msm0(rtcm, SYS_GAL); + break; /* not supported */ + case 1092: + ret = decode_msm0(rtcm, SYS_GAL); + break; /* not supported */ + case 1093: + ret = decode_msm0(rtcm, SYS_GAL); + break; /* not supported */ + case 1094: + ret = decode_msm4(rtcm, SYS_GAL); + break; + case 1095: + ret = decode_msm5(rtcm, SYS_GAL); + break; + case 1096: + ret = decode_msm6(rtcm, SYS_GAL); + break; + case 1097: + ret = decode_msm7(rtcm, SYS_GAL); + break; + case 1101: + ret = decode_msm0(rtcm, SYS_SBS); + break; /* not supported */ + case 1102: + ret = decode_msm0(rtcm, SYS_SBS); + break; /* not supported */ + case 1103: + ret = decode_msm0(rtcm, SYS_SBS); + break; /* not supported */ + case 1104: + ret = decode_msm4(rtcm, SYS_SBS); + break; + case 1105: + ret = decode_msm5(rtcm, SYS_SBS); + break; + case 1106: + ret = decode_msm6(rtcm, SYS_SBS); + break; + case 1107: + ret = decode_msm7(rtcm, SYS_SBS); + break; + case 1111: + ret = decode_msm0(rtcm, SYS_QZS); + break; /* not supported */ + case 1112: + ret = decode_msm0(rtcm, SYS_QZS); + break; /* not supported */ + case 1113: + ret = decode_msm0(rtcm, SYS_QZS); + break; /* not supported */ + case 1114: + ret = decode_msm4(rtcm, SYS_QZS); + break; + case 1115: + ret = decode_msm5(rtcm, SYS_QZS); + break; + case 1116: + ret = decode_msm6(rtcm, SYS_QZS); + break; + case 1117: + ret = decode_msm7(rtcm, SYS_QZS); + break; + case 1121: + ret = decode_msm0(rtcm, SYS_CMP); + break; /* not supported */ + case 1122: + ret = decode_msm0(rtcm, SYS_CMP); + break; /* not supported */ + case 1123: + ret = decode_msm0(rtcm, SYS_CMP); + break; /* not supported */ + case 1124: + ret = decode_msm4(rtcm, SYS_CMP); + break; + case 1125: + ret = decode_msm5(rtcm, SYS_CMP); + break; + case 1126: + ret = decode_msm6(rtcm, SYS_CMP); + break; + case 1127: + ret = decode_msm7(rtcm, SYS_CMP); + break; + case 1131: + ret = decode_msm0(rtcm, SYS_IRN); + break; /* not supported */ + case 1132: + ret = decode_msm0(rtcm, SYS_IRN); + break; /* not supported */ + case 1133: + ret = decode_msm0(rtcm, SYS_IRN); + break; /* not supported */ + case 1134: + ret = decode_msm4(rtcm, SYS_IRN); + break; + case 1135: + ret = decode_msm5(rtcm, SYS_IRN); + break; + case 1136: + ret = decode_msm6(rtcm, SYS_IRN); + break; + case 1137: + ret = decode_msm7(rtcm, SYS_IRN); + break; + case 1230: + ret = decode_type1230(rtcm); + break; + case 1240: + ret = decode_ssr1(rtcm, SYS_GAL, 0); + break; /* draft */ + case 1241: + ret = decode_ssr2(rtcm, SYS_GAL, 0); + break; /* draft */ + case 1242: + ret = decode_ssr3(rtcm, SYS_GAL, 0); + break; /* draft */ + case 1243: + ret = decode_ssr4(rtcm, SYS_GAL, 0); + break; /* draft */ + case 1244: + ret = decode_ssr5(rtcm, SYS_GAL, 0); + break; /* draft */ + case 1245: + ret = decode_ssr6(rtcm, SYS_GAL, 0); + break; /* draft */ + case 1246: + ret = decode_ssr1(rtcm, SYS_QZS, 0); + break; /* draft */ + case 1247: + ret = decode_ssr2(rtcm, SYS_QZS, 0); + break; /* draft */ + case 1248: + ret = decode_ssr3(rtcm, SYS_QZS, 0); + break; /* draft */ + case 1249: + ret = decode_ssr4(rtcm, SYS_QZS, 0); + break; /* draft */ + case 1250: + ret = decode_ssr5(rtcm, SYS_QZS, 0); + break; /* draft */ + case 1251: + ret = decode_ssr6(rtcm, SYS_QZS, 0); + break; /* draft */ + case 1252: + ret = decode_ssr1(rtcm, SYS_SBS, 0); + break; /* draft */ + case 1253: + ret = decode_ssr2(rtcm, SYS_SBS, 0); + break; /* draft */ + case 1254: + ret = decode_ssr3(rtcm, SYS_SBS, 0); + break; /* draft */ + case 1255: + ret = decode_ssr4(rtcm, SYS_SBS, 0); + break; /* draft */ + case 1256: + ret = decode_ssr5(rtcm, SYS_SBS, 0); + break; /* draft */ + case 1257: + ret = decode_ssr6(rtcm, SYS_SBS, 0); + break; /* draft */ + case 1258: + ret = decode_ssr1(rtcm, SYS_CMP, 0); + break; /* draft */ + case 1259: + ret = decode_ssr2(rtcm, SYS_CMP, 0); + break; /* draft */ + case 1260: + ret = decode_ssr3(rtcm, SYS_CMP, 0); + break; /* draft */ + case 1261: + ret = decode_ssr4(rtcm, SYS_CMP, 0); + break; /* draft */ + case 1262: + ret = decode_ssr5(rtcm, SYS_CMP, 0); + break; /* draft */ + case 1263: + ret = decode_ssr6(rtcm, SYS_CMP, 0); + break; /* draft */ + case 11: + ret = decode_ssr7(rtcm, SYS_GPS, 0); + break; /* tentative */ + case 12: + ret = decode_ssr7(rtcm, SYS_GAL, 0); + break; /* tentative */ + case 13: + ret = decode_ssr7(rtcm, SYS_QZS, 0); + break; /* tentative */ + case 14: + ret = decode_ssr7(rtcm, SYS_CMP, 0); + break; /* tentative */ + case 4073: + ret = decode_type4073(rtcm); + break; + case 4076: + ret = decode_type4076(rtcm); + break; + } + if (ret >= 0) { + if (1001 <= type && type <= 1299) + rtcm->nmsg3[type - 1000]++; /* 1-299 */ + else if (4070 <= type && type <= 4099) + rtcm->nmsg3[type - 3770]++; /* 300-329 */ + else + rtcm->nmsg3[0]++; /* other */ + } + return ret; } diff --git a/src/rtcm3e.c b/src/rtcm3e.c index 83ca757cc..191e906fd 100644 --- a/src/rtcm3e.c +++ b/src/rtcm3e.c @@ -1,69 +1,69 @@ /*------------------------------------------------------------------------------ -* rtcm3e.c : rtcm ver.3 message encoder functions -* -* Copyright (C) 2012-2020 by T.TAKASU, All rights reserved. -* -* references : -* see rtcm.c -* -* version : $Revision:$ $Date:$ -* history : 2012/12/05 1.0 new -* 2012/12/16 1.1 fix bug on ssr high rate clock correction -* 2012/12/24 1.2 fix bug on msm carrier-phase offset correction -* fix bug on SBAS sat id in 1001-1004 -* fix bug on carrier-phase in 1001-1004,1009-1012 -* 2012/12/28 1.3 fix bug on compass carrier wave length -* 2013/01/18 1.4 fix bug on ssr message generation -* 2013/05/11 1.5 change type of arg value of setbig() -* 2013/05/19 1.5 gpst -> bdt of time-tag in beidou msm message -* 2013/04/27 1.7 comply with rtcm 3.2 with amendment 1/2 (ref[15]) -* delete MT 1046 according to ref [15] -* 2014/05/15 1.8 set NT field in MT 1020 glonass ephemeris -* 2014/12/06 1.9 support SBAS/BeiDou SSR messages (ref [16]) -* fix bug on invalid staid in qzss ssr messages -* 2015/03/22 1.9 add handling of iodcrc for beidou/sbas ssr messages -* 2015/08/03 1.10 fix bug on wrong udint and iod in ssr 7. -* support rtcm ssr fcb message mt 2065-2069. -* 2015/09/07 1.11 add message count of MT 2000-2099 -* 2015/10/21 1.12 add MT1046 support for IGS MGEX -* 2015/12/04 1.13 add MT63 beidou ephemeris (rtcm draft) -* fix bug on msm message generation of beidou -* fix bug on ssr 3 message generation (#321) -* 2016/06/12 1.14 fix bug on segmentation fault by generating msm1 -* 2016/09/20 1.15 fix bug on MT1045 Galileo week rollover -* 2017/04/11 1.16 fix bug on gst-week in MT1045/1046 -* 2018/10/10 1.17 merge changes for 2.4.2 p13 -* change mt for ssr 7 phase biases -* 2019/05/10 1.21 save galileo E5b data to obs index 2 -* 2020/11/30 1.22 support MT1230 GLONASS code-phase biases -* support MT1131-1137,1041 (NavIC MSM and ephemeris) -* support MT4076 IGS SSR -* fixed invalid delta clock C2 value for SSR 2 and 4 -* delete SSR signal and tracking mode ID table -* use API code2idx() to get freq-index -* use API code2freq() to get carrier frequency -* use integer types in stdint.h -*-----------------------------------------------------------------------------*/ + * rtcm3e.c : rtcm ver.3 message encoder functions + * + * Copyright (C) 2012-2020 by T.TAKASU, All rights reserved. + * + * references : + * see rtcm.c + * + * version : $Revision:$ $Date:$ + * history : 2012/12/05 1.0 new + * 2012/12/16 1.1 fix bug on ssr high rate clock correction + * 2012/12/24 1.2 fix bug on msm carrier-phase offset correction + * fix bug on SBAS sat id in 1001-1004 + * fix bug on carrier-phase in 1001-1004,1009-1012 + * 2012/12/28 1.3 fix bug on compass carrier wave length + * 2013/01/18 1.4 fix bug on ssr message generation + * 2013/05/11 1.5 change type of arg value of setbig() + * 2013/05/19 1.5 gpst -> bdt of time-tag in beidou msm message + * 2013/04/27 1.7 comply with rtcm 3.2 with amendment 1/2 (ref[15]) + * delete MT 1046 according to ref [15] + * 2014/05/15 1.8 set NT field in MT 1020 glonass ephemeris + * 2014/12/06 1.9 support SBAS/BeiDou SSR messages (ref [16]) + * fix bug on invalid staid in qzss ssr messages + * 2015/03/22 1.9 add handling of iodcrc for beidou/sbas ssr messages + * 2015/08/03 1.10 fix bug on wrong udint and iod in ssr 7. + * support rtcm ssr fcb message mt 2065-2069. + * 2015/09/07 1.11 add message count of MT 2000-2099 + * 2015/10/21 1.12 add MT1046 support for IGS MGEX + * 2015/12/04 1.13 add MT63 beidou ephemeris (rtcm draft) + * fix bug on msm message generation of beidou + * fix bug on ssr 3 message generation (#321) + * 2016/06/12 1.14 fix bug on segmentation fault by generating msm1 + * 2016/09/20 1.15 fix bug on MT1045 Galileo week rollover + * 2017/04/11 1.16 fix bug on gst-week in MT1045/1046 + * 2018/10/10 1.17 merge changes for 2.4.2 p13 + * change mt for ssr 7 phase biases + * 2019/05/10 1.21 save galileo E5b data to obs index 2 + * 2020/11/30 1.22 support MT1230 GLONASS code-phase biases + * support MT1131-1137,1041 (NavIC MSM and ephemeris) + * support MT4076 IGS SSR + * fixed invalid delta clock C2 value for SSR 2 and 4 + * delete SSR signal and tracking mode ID table + * use API code2idx() to get freq-index + * use API code2freq() to get carrier frequency + * use integer types in stdint.h + *-----------------------------------------------------------------------------*/ #include "rtklib.h" /* constants and macros ------------------------------------------------------*/ -#define PRUNIT_GPS 299792.458 /* rtcm 3 unit of gps pseudorange (m) */ -#define PRUNIT_GLO 599584.916 /* rtcm 3 unit of glo pseudorange (m) */ -#define RANGE_MS (CLIGHT*0.001) /* range in 1 ms */ -#define P2_10 0.0009765625 /* 2^-10 */ -#define P2_28 3.725290298461914E-09 /* 2^-28 */ -#define P2_34 5.820766091346740E-11 /* 2^-34 */ -#define P2_41 4.547473508864641E-13 /* 2^-41 */ -#define P2_46 1.421085471520200E-14 /* 2^-46 */ -#define P2_59 1.734723475976810E-18 /* 2^-59 */ -#define P2_66 1.355252715606880E-20 /* 2^-66 */ +#define PRUNIT_GPS 299792.458 /* rtcm 3 unit of gps pseudorange (m) */ +#define PRUNIT_GLO 599584.916 /* rtcm 3 unit of glo pseudorange (m) */ +#define RANGE_MS (CLIGHT * 0.001) /* range in 1 ms */ +#define P2_10 0.0009765625 /* 2^-10 */ +#define P2_28 3.725290298461914E-09 /* 2^-28 */ +#define P2_34 5.820766091346740E-11 /* 2^-34 */ +#define P2_41 4.547473508864641E-13 /* 2^-41 */ +#define P2_46 1.421085471520200E-14 /* 2^-46 */ +#define P2_59 1.734723475976810E-18 /* 2^-59 */ +#define P2_66 1.355252715606880E-20 /* 2^-66 */ -#define ROUND(x) ((int)floor((x)+0.5)) -#define ROUND_U(x) ((uint32_t)floor((x)+0.5)) -#define MIN(x,y) ((x)<(y)?(x):(y)) +#define ROUND(x) ((int)floor((x) + 0.5)) +#define ROUND_U(x) ((uint32_t)floor((x) + 0.5)) +#define MIN(x, y) ((x) < (y) ? (x) : (y)) -#define RTCMSATS 31 // Max sats in 1001-1004 and 1009-1012 headers +#define RTCMSATS 31 // Max sats in 1001-1004 and 1009-1012 headers /* MSM signal ID table -------------------------------------------------------*/ extern const char *msm_sig_gps[32]; @@ -83,2694 +83,3565 @@ extern const uint8_t ssr_sig_cmp[32]; extern const uint8_t ssr_sig_sbs[32]; /* SSR update intervals ------------------------------------------------------*/ -static const double ssrudint[16]={ - 1,2,5,10,15,30,60,120,240,300,600,900,1800,3600,7200,10800 -}; +static const double ssrudint[16] = {1, 2, 5, 10, 15, 30, 60, 120, + 240, 300, 600, 900, 1800, 3600, 7200, 10800}; /* set sign-magnitude bits ---------------------------------------------------*/ -static void setbitg(uint8_t *buff, int pos, int len, int32_t value) -{ - setbitu(buff,pos,1,value<0?1:0); - setbitu(buff,pos+1,len-1,value<0?-value:value); +static void setbitg(uint8_t *buff, int pos, int len, int32_t value) { + setbitu(buff, pos, 1, value < 0 ? 1 : 0); + setbitu(buff, pos + 1, len - 1, value < 0 ? -value : value); } /* set signed 38 bit field ---------------------------------------------------*/ -static void set38bits(uint8_t *buff, int pos, double value) -{ - int word_h=(int)floor(value/64.0); - uint32_t word_l=(uint32_t)(value-word_h*64.0); - setbits(buff,pos ,32,word_h); - setbitu(buff,pos+32,6,word_l); +static void set38bits(uint8_t *buff, int pos, double value) { + int word_h = (int)floor(value / 64.0); + uint32_t word_l = (uint32_t)(value - word_h * 64.0); + setbits(buff, pos, 32, word_h); + setbitu(buff, pos + 32, 6, word_l); } /* lock time -----------------------------------------------------------------*/ -static int locktime(gtime_t time, gtime_t *lltime, uint8_t LLI) -{ - if (!lltime->time||(LLI&1)) *lltime=time; - return (int)timediff(time,*lltime); +static int locktime(gtime_t time, gtime_t *lltime, uint8_t LLI) { + if (!lltime->time || (LLI & 1)) *lltime = time; + return (int)timediff(time, *lltime); } /* lock time in double -------------------------------------------------------*/ -static double locktime_d(gtime_t time, gtime_t *lltime, uint8_t LLI) -{ - if (!lltime->time||(LLI&1)) *lltime=time; - return timediff(time,*lltime); +static double locktime_d(gtime_t time, gtime_t *lltime, uint8_t LLI) { + if (!lltime->time || (LLI & 1)) *lltime = time; + return timediff(time, *lltime); } /* GLONASS frequency channel number in RTCM (FCN+7,-1:error) -----------------*/ -static int fcn_glo(int sat, rtcm_t *rtcm) -{ - int prn; +static int fcn_glo(int sat, rtcm_t *rtcm) { + int prn; - if (satsys(sat,&prn)!=SYS_GLO) { - return -1; - } - if (rtcm->nav.geph[prn-1].sat==sat) { - return rtcm->nav.geph[prn-1].frq+7; - } - if (rtcm->nav.glo_fcn[prn-1]>0) { /* fcn+8 (0: no data) */ - return rtcm->nav.glo_fcn[prn-1]-8+7; -} + if (satsys(sat, &prn) != SYS_GLO) { return -1; + } + if (rtcm->nav.geph[prn - 1].sat == sat) { + return rtcm->nav.geph[prn - 1].frq + 7; + } + if (rtcm->nav.glo_fcn[prn - 1] > 0) { /* fcn+8 (0: no data) */ + return rtcm->nav.glo_fcn[prn - 1] - 8 + 7; + } + return -1; } /* lock time indicator (ref [17] table 3.4-2) --------------------------------*/ -static int to_lock(int lock) -{ - if (lock<0 ) return 0; - if (lock<24 ) return lock; - if (lock<72 ) return (lock+24 )/2; - if (lock<168) return (lock+120 )/4; - if (lock<360) return (lock+408 )/8; - if (lock<744) return (lock+1176)/16; - if (lock<937) return (lock+3096)/32; - return 127; +static int to_lock(int lock) { + if (lock < 0) return 0; + if (lock < 24) return lock; + if (lock < 72) return (lock + 24) / 2; + if (lock < 168) return (lock + 120) / 4; + if (lock < 360) return (lock + 408) / 8; + if (lock < 744) return (lock + 1176) / 16; + if (lock < 937) return (lock + 3096) / 32; + return 127; } /* MSM lock time indicator (ref [17] table 3.5-74) ---------------------------*/ -static int to_msm_lock(double lock) -{ - if (lock<0.032 ) return 0; - if (lock<0.064 ) return 1; - if (lock<0.128 ) return 2; - if (lock<0.256 ) return 3; - if (lock<0.512 ) return 4; - if (lock<1.024 ) return 5; - if (lock<2.048 ) return 6; - if (lock<4.096 ) return 7; - if (lock<8.192 ) return 8; - if (lock<16.384 ) return 9; - if (lock<32.768 ) return 10; - if (lock<65.536 ) return 11; - if (lock<131.072) return 12; - if (lock<262.144) return 13; - if (lock<524.288) return 14; - return 15; +static int to_msm_lock(double lock) { + if (lock < 0.032) return 0; + if (lock < 0.064) return 1; + if (lock < 0.128) return 2; + if (lock < 0.256) return 3; + if (lock < 0.512) return 4; + if (lock < 1.024) return 5; + if (lock < 2.048) return 6; + if (lock < 4.096) return 7; + if (lock < 8.192) return 8; + if (lock < 16.384) return 9; + if (lock < 32.768) return 10; + if (lock < 65.536) return 11; + if (lock < 131.072) return 12; + if (lock < 262.144) return 13; + if (lock < 524.288) return 14; + return 15; } /* MSM lock time indicator with extended-resolution (ref [17] table 3.5-76) --*/ -static int to_msm_lock_ex(double lock) -{ - int lock_ms = (int)(lock * 1000.0); - - if (lock<0.0 ) return 0; - if (lock<0.064 ) return lock_ms; - if (lock<0.128 ) return (lock_ms+64 )/2; - if (lock<0.256 ) return (lock_ms+256 )/4; - if (lock<0.512 ) return (lock_ms+768 )/8; - if (lock<1.024 ) return (lock_ms+2048 )/16; - if (lock<2.048 ) return (lock_ms+5120 )/32; - if (lock<4.096 ) return (lock_ms+12288 )/64; - if (lock<8.192 ) return (lock_ms+28672 )/128; - if (lock<16.384 ) return (lock_ms+65536 )/256; - if (lock<32.768 ) return (lock_ms+147456 )/512; - if (lock<65.536 ) return (lock_ms+327680 )/1024; - if (lock<131.072 ) return (lock_ms+720896 )/2048; - if (lock<262.144 ) return (lock_ms+1572864 )/4096; - if (lock<524.288 ) return (lock_ms+3407872 )/8192; - if (lock<1048.576 ) return (lock_ms+7340032 )/16384; - if (lock<2097.152 ) return (lock_ms+15728640 )/32768; - if (lock<4194.304 ) return (lock_ms+33554432 )/65536; - if (lock<8388.608 ) return (lock_ms+71303168 )/131072; - if (lock<16777.216) return (lock_ms+150994944)/262144; - if (lock<33554.432) return (lock_ms+318767104)/524288; - if (lock<67108.864) return (lock_ms+671088640)/1048576; - return 704; +static int to_msm_lock_ex(double lock) { + int lock_ms = (int)(lock * 1000.0); + + if (lock < 0.0) return 0; + if (lock < 0.064) return lock_ms; + if (lock < 0.128) return (lock_ms + 64) / 2; + if (lock < 0.256) return (lock_ms + 256) / 4; + if (lock < 0.512) return (lock_ms + 768) / 8; + if (lock < 1.024) return (lock_ms + 2048) / 16; + if (lock < 2.048) return (lock_ms + 5120) / 32; + if (lock < 4.096) return (lock_ms + 12288) / 64; + if (lock < 8.192) return (lock_ms + 28672) / 128; + if (lock < 16.384) return (lock_ms + 65536) / 256; + if (lock < 32.768) return (lock_ms + 147456) / 512; + if (lock < 65.536) return (lock_ms + 327680) / 1024; + if (lock < 131.072) return (lock_ms + 720896) / 2048; + if (lock < 262.144) return (lock_ms + 1572864) / 4096; + if (lock < 524.288) return (lock_ms + 3407872) / 8192; + if (lock < 1048.576) return (lock_ms + 7340032) / 16384; + if (lock < 2097.152) return (lock_ms + 15728640) / 32768; + if (lock < 4194.304) return (lock_ms + 33554432) / 65536; + if (lock < 8388.608) return (lock_ms + 71303168) / 131072; + if (lock < 16777.216) return (lock_ms + 150994944) / 262144; + if (lock < 33554.432) return (lock_ms + 318767104) / 524288; + if (lock < 67108.864) return (lock_ms + 671088640) / 1048576; + return 704; } /* L1 code indicator GPS -----------------------------------------------------*/ -static int to_code1_gps(uint8_t code) -{ - switch (code) { - case CODE_L1C: return 0; /* L1 C/A */ - case CODE_L1P: - case CODE_L1W: - case CODE_L1Y: - case CODE_L1N: return 1; /* L1 P(Y) direct */ - } - return 0; +static int to_code1_gps(uint8_t code) { + switch (code) { + case CODE_L1C: + return 0; /* L1 C/A */ + case CODE_L1P: + case CODE_L1W: + case CODE_L1Y: + case CODE_L1N: + return 1; /* L1 P(Y) direct */ + } + return 0; } /* L2 code indicator GPS -----------------------------------------------------*/ -static int to_code2_gps(uint8_t code) -{ - switch (code) { - case CODE_L2C: - case CODE_L2S: - case CODE_L2L: - case CODE_L2X: return 0; /* L2 C/A or L2C */ - case CODE_L2P: - case CODE_L2Y: return 1; /* L2 P(Y) direct */ - case CODE_L2D: return 2; /* L2 P(Y) cross-correlated */ - case CODE_L2W: - case CODE_L2N: return 3; /* L2 correlated P/Y */ - } - return 0; +static int to_code2_gps(uint8_t code) { + switch (code) { + case CODE_L2C: + case CODE_L2S: + case CODE_L2L: + case CODE_L2X: + return 0; /* L2 C/A or L2C */ + case CODE_L2P: + case CODE_L2Y: + return 1; /* L2 P(Y) direct */ + case CODE_L2D: + return 2; /* L2 P(Y) cross-correlated */ + case CODE_L2W: + case CODE_L2N: + return 3; /* L2 correlated P/Y */ + } + return 0; } /* L1 code indicator GLONASS -------------------------------------------------*/ -static int to_code1_glo(uint8_t code) -{ - switch (code) { - case CODE_L1C: return 0; /* L1 C/A */ - case CODE_L1P: return 1; /* L1 P */ - } - return 0; +static int to_code1_glo(uint8_t code) { + switch (code) { + case CODE_L1C: + return 0; /* L1 C/A */ + case CODE_L1P: + return 1; /* L1 P */ + } + return 0; } /* L2 code indicator GLONASS -------------------------------------------------*/ -static int to_code2_glo(uint8_t code) -{ - switch (code) { - case CODE_L2C: return 0; /* L2 C/A */ - case CODE_L2P: return 1; /* L2 P */ - } - return 0; +static int to_code2_glo(uint8_t code) { + switch (code) { + case CODE_L2C: + return 0; /* L2 C/A */ + case CODE_L2P: + return 1; /* L2 P */ + } + return 0; } /* carrier-phase - pseudorange in cycle --------------------------------------*/ -static double cp_pr(double cp, double pr_cyc) -{ - return fmod(cp-pr_cyc+750.0,1500.0)-750.0; -} +static double cp_pr(double cp, double pr_cyc) { return fmod(cp - pr_cyc + 750.0, 1500.0) - 750.0; } /* generate obs field data GPS -----------------------------------------------*/ -static void gen_obs_gps(rtcm_t *rtcm, const obsd_t *data, int *code1, int *pr1, - int *ppr1, int *lock1, int *amb, int *cnr1, int *code2, - int *pr21, int *ppr2, int *lock2, int *cnr2) -{ - double lam1,lam2,pr1c=0.0,ppr; - int lt1,lt2; - - lam1=CLIGHT/FREQL1; - lam2=CLIGHT/FREQL2; - *pr1=*amb=0; - if (ppr1) *ppr1=0xFFF80000; /* invalid values */ - if (pr21) *pr21=0xFFFFE000; - if (ppr2) *ppr2=0xFFF80000; - - /* L1 peudorange */ - if (data->P[0]!=0.0&&data->code[0]) { - *amb=(int)floor(data->P[0]/PRUNIT_GPS); - *pr1=ROUND((data->P[0]-*amb*PRUNIT_GPS)/0.02); - pr1c=*pr1*0.02+*amb*PRUNIT_GPS; - } - /* L1 phaserange - L1 pseudorange */ - if (data->P[0]!=0.0&&data->L[0]!=0.0&&data->code[0]) { - ppr=cp_pr(data->L[0],pr1c/lam1); - if (ppr1) *ppr1=ROUND(ppr*lam1/0.0005); - } - /* L2 -L1 pseudorange */ - if (data->P[0]!=0.0&&data->P[1]!=0.0&&data->code[0]&&data->code[1]&& - fabs(data->P[1]-pr1c)<=163.82) { - if (pr21) *pr21=ROUND((data->P[1]-pr1c)/0.02); - } - /* L2 phaserange - L1 pseudorange */ - if (data->P[0]!=0.0&&data->L[1]!=0.0&&data->code[0]&&data->code[1]) { - ppr=cp_pr(data->L[1],pr1c/lam2); - if (ppr2) *ppr2=ROUND(ppr*lam2/0.0005); - } - lt1=locktime(data->time,rtcm->lltime[data->sat-1] ,data->LLI[0]); - lt2=locktime(data->time,rtcm->lltime[data->sat-1]+1,data->LLI[1]); - - if (lock1) *lock1=to_lock(lt1); - if (lock2) *lock2=to_lock(lt2); - if (cnr1 ) *cnr1=ROUND(data->SNR[0]/0.25); - if (cnr2 ) *cnr2=ROUND(data->SNR[1]/0.25); - if (code1) *code1=to_code1_gps(data->code[0]); - if (code2) *code2=to_code2_gps(data->code[1]); +static void gen_obs_gps(rtcm_t *rtcm, const obsd_t *data, int *code1, int *pr1, int *ppr1, + int *lock1, int *amb, int *cnr1, int *code2, int *pr21, int *ppr2, + int *lock2, int *cnr2) { + double lam1, lam2, pr1c = 0.0, ppr; + int lt1, lt2; + + lam1 = CLIGHT / FREQL1; + lam2 = CLIGHT / FREQL2; + *pr1 = *amb = 0; + if (ppr1) *ppr1 = 0xFFF80000; /* invalid values */ + if (pr21) *pr21 = 0xFFFFE000; + if (ppr2) *ppr2 = 0xFFF80000; + + /* L1 peudorange */ + if (data->P[0] != 0.0 && data->code[0]) { + *amb = (int)floor(data->P[0] / PRUNIT_GPS); + *pr1 = ROUND((data->P[0] - *amb * PRUNIT_GPS) / 0.02); + pr1c = *pr1 * 0.02 + *amb * PRUNIT_GPS; + } + /* L1 phaserange - L1 pseudorange */ + if (data->P[0] != 0.0 && data->L[0] != 0.0 && data->code[0]) { + ppr = cp_pr(data->L[0], pr1c / lam1); + if (ppr1) *ppr1 = ROUND(ppr * lam1 / 0.0005); + } + /* L2 -L1 pseudorange */ + if (data->P[0] != 0.0 && data->P[1] != 0.0 && data->code[0] && data->code[1] && + fabs(data->P[1] - pr1c) <= 163.82) { + if (pr21) *pr21 = ROUND((data->P[1] - pr1c) / 0.02); + } + /* L2 phaserange - L1 pseudorange */ + if (data->P[0] != 0.0 && data->L[1] != 0.0 && data->code[0] && data->code[1]) { + ppr = cp_pr(data->L[1], pr1c / lam2); + if (ppr2) *ppr2 = ROUND(ppr * lam2 / 0.0005); + } + lt1 = locktime(data->time, rtcm->lltime[data->sat - 1], data->LLI[0]); + lt2 = locktime(data->time, rtcm->lltime[data->sat - 1] + 1, data->LLI[1]); + + if (lock1) *lock1 = to_lock(lt1); + if (lock2) *lock2 = to_lock(lt2); + if (cnr1) *cnr1 = ROUND(data->SNR[0] / 0.25); + if (cnr2) *cnr2 = ROUND(data->SNR[1] / 0.25); + if (code1) *code1 = to_code1_gps(data->code[0]); + if (code2) *code2 = to_code2_gps(data->code[1]); } /* generate obs field data GLONASS -------------------------------------------*/ -static void gen_obs_glo(rtcm_t *rtcm, const obsd_t *data, int fcn, int *code1, - int *pr1, int *ppr1, int *lock1, int *amb, int *cnr1, - int *code2, int *pr21, int *ppr2, int *lock2, int *cnr2) -{ - double lam1=0.0,lam2=0.0,pr1c=0.0,ppr; - int lt1,lt2; - - if (fcn>=0) { /* fcn+7 */ - lam1=CLIGHT/(FREQ1_GLO+DFRQ1_GLO*(fcn-7)); - lam2=CLIGHT/(FREQ2_GLO+DFRQ2_GLO*(fcn-7)); - } - *pr1=*amb=0; - if (ppr1) *ppr1=0xFFF80000; /* invalid values */ - if (pr21) *pr21=0xFFFFE000; - if (ppr2) *ppr2=0xFFF80000; - - /* L1 pseudorange */ - if (data->P[0]!=0.0) { - *amb=(int)floor(data->P[0]/PRUNIT_GLO); - *pr1=ROUND((data->P[0]-*amb*PRUNIT_GLO)/0.02); - pr1c=*pr1*0.02+*amb*PRUNIT_GLO; - } - /* L1 phaserange - L1 pseudorange */ - if (data->P[0]!=0.0&&data->L[0]!=0.0&&data->code[0]&&lam1>0.0) { - ppr=cp_pr(data->L[0],pr1c/lam1); - if (ppr1) *ppr1=ROUND(ppr*lam1/0.0005); - } - /* L2 -L1 pseudorange */ - if (data->P[0]!=0.0&&data->P[1]!=0.0&&data->code[0]&&data->code[1]&& - fabs(data->P[1]-pr1c)<=163.82) { - if (pr21) *pr21=ROUND((data->P[1]-pr1c)/0.02); - } - /* L2 phaserange - L1 pseudorange */ - if (data->P[0]!=0.0&&data->L[1]!=0.0&&data->code[0]&&data->code[1]&& - lam2>0.0) { - ppr=cp_pr(data->L[1],pr1c/lam2); - if (ppr2) *ppr2=ROUND(ppr*lam2/0.0005); - } - lt1=locktime(data->time,rtcm->lltime[data->sat-1] ,data->LLI[0]); - lt2=locktime(data->time,rtcm->lltime[data->sat-1]+1,data->LLI[1]); - - if (lock1) *lock1=to_lock(lt1); - if (lock2) *lock2=to_lock(lt2); - if (cnr1 ) *cnr1=ROUND(data->SNR[0]/0.25); - if (cnr2 ) *cnr2=ROUND(data->SNR[1]/0.25); - if (code1) *code1=to_code1_glo(data->code[0]); - if (code2) *code2=to_code2_glo(data->code[1]); +static void gen_obs_glo(rtcm_t *rtcm, const obsd_t *data, int fcn, int *code1, int *pr1, int *ppr1, + int *lock1, int *amb, int *cnr1, int *code2, int *pr21, int *ppr2, + int *lock2, int *cnr2) { + double lam1 = 0.0, lam2 = 0.0, pr1c = 0.0, ppr; + int lt1, lt2; + + if (fcn >= 0) { /* fcn+7 */ + lam1 = CLIGHT / (FREQ1_GLO + DFRQ1_GLO * (fcn - 7)); + lam2 = CLIGHT / (FREQ2_GLO + DFRQ2_GLO * (fcn - 7)); + } + *pr1 = *amb = 0; + if (ppr1) *ppr1 = 0xFFF80000; /* invalid values */ + if (pr21) *pr21 = 0xFFFFE000; + if (ppr2) *ppr2 = 0xFFF80000; + + /* L1 pseudorange */ + if (data->P[0] != 0.0) { + *amb = (int)floor(data->P[0] / PRUNIT_GLO); + *pr1 = ROUND((data->P[0] - *amb * PRUNIT_GLO) / 0.02); + pr1c = *pr1 * 0.02 + *amb * PRUNIT_GLO; + } + /* L1 phaserange - L1 pseudorange */ + if (data->P[0] != 0.0 && data->L[0] != 0.0 && data->code[0] && lam1 > 0.0) { + ppr = cp_pr(data->L[0], pr1c / lam1); + if (ppr1) *ppr1 = ROUND(ppr * lam1 / 0.0005); + } + /* L2 -L1 pseudorange */ + if (data->P[0] != 0.0 && data->P[1] != 0.0 && data->code[0] && data->code[1] && + fabs(data->P[1] - pr1c) <= 163.82) { + if (pr21) *pr21 = ROUND((data->P[1] - pr1c) / 0.02); + } + /* L2 phaserange - L1 pseudorange */ + if (data->P[0] != 0.0 && data->L[1] != 0.0 && data->code[0] && data->code[1] && lam2 > 0.0) { + ppr = cp_pr(data->L[1], pr1c / lam2); + if (ppr2) *ppr2 = ROUND(ppr * lam2 / 0.0005); + } + lt1 = locktime(data->time, rtcm->lltime[data->sat - 1], data->LLI[0]); + lt2 = locktime(data->time, rtcm->lltime[data->sat - 1] + 1, data->LLI[1]); + + if (lock1) *lock1 = to_lock(lt1); + if (lock2) *lock2 = to_lock(lt2); + if (cnr1) *cnr1 = ROUND(data->SNR[0] / 0.25); + if (cnr2) *cnr2 = ROUND(data->SNR[1] / 0.25); + if (code1) *code1 = to_code1_glo(data->code[0]); + if (code2) *code2 = to_code2_glo(data->code[1]); } /* encode RTCM header --------------------------------------------------------*/ -static int encode_head(int type, rtcm_t *rtcm, int sys, int sync, int nsat) -{ - double tow; - int i=24,week,epoch; - - trace(4,"encode_head: type=%d sync=%d sys=%d nsat=%d\n",type,sync,sys,nsat); - - setbitu(rtcm->buff,i,12,type ); i+=12; /* message no */ - setbitu(rtcm->buff,i,12,rtcm->staid); i+=12; /* ref station id */ - - if (sys==SYS_GLO) { - tow=time2gpst(timeadd(gpst2utc(rtcm->time),10800.0),&week); - epoch=ROUND(fmod(tow,86400.0)/0.001); - setbitu(rtcm->buff,i,27,epoch); i+=27; /* glonass epoch time */ - } - else { - tow=time2gpst(rtcm->time,&week); - epoch=ROUND(tow/0.001); - setbitu(rtcm->buff,i,30,epoch); i+=30; /* gps epoch time */ - } - setbitu(rtcm->buff,i, 1,sync); i+= 1; /* synchronous gnss flag */ - setbitu(rtcm->buff,i, 5,nsat); i+= 5; /* no of satellites */ - setbitu(rtcm->buff,i, 1,0 ); i+= 1; /* smoothing indicator */ - setbitu(rtcm->buff,i, 3,0 ); i+= 3; /* smoothing interval */ - return i; +static int encode_head(int type, rtcm_t *rtcm, int sys, int sync, int nsat) { + double tow; + int i = 24, week, epoch; + + trace(4, "encode_head: type=%d sync=%d sys=%d nsat=%d\n", type, sync, sys, nsat); + + setbitu(rtcm->buff, i, 12, type); + i += 12; /* message no */ + setbitu(rtcm->buff, i, 12, rtcm->staid); + i += 12; /* ref station id */ + + if (sys == SYS_GLO) { + tow = time2gpst(timeadd(gpst2utc(rtcm->time), 10800.0), &week); + epoch = ROUND(fmod(tow, 86400.0) / 0.001); + setbitu(rtcm->buff, i, 27, epoch); + i += 27; /* glonass epoch time */ + } else { + tow = time2gpst(rtcm->time, &week); + epoch = ROUND(tow / 0.001); + setbitu(rtcm->buff, i, 30, epoch); + i += 30; /* gps epoch time */ + } + setbitu(rtcm->buff, i, 1, sync); + i += 1; /* synchronous gnss flag */ + setbitu(rtcm->buff, i, 5, nsat); + i += 5; /* no of satellites */ + setbitu(rtcm->buff, i, 1, 0); + i += 1; /* smoothing indicator */ + setbitu(rtcm->buff, i, 3, 0); + i += 3; /* smoothing interval */ + return i; } /* encode type 1001: basic L1-only GPS RTK observables -----------------------*/ -static int encode_type1001(rtcm_t *rtcm, int sync) -{ - int code1,pr1,ppr1,lock1,amb; - - trace(3,"encode_type1001: sync=%d\n",sync); - - int nsat = 0; - for (int j=0;jobs.n&&nsatobs.data[j].sat,NULL); - if (!(sys&(SYS_GPS|SYS_SBS))) continue; - nsat++; - } - /* encode header */ - int i = encode_head(1001,rtcm,SYS_GPS,sync,nsat); - - nsat = 0; - for (int j=0;jobs.n&&nsatobs.data[j].sat,&prn); - if (!(sys&(SYS_GPS|SYS_SBS))) continue; - nsat++; - - if (sys==SYS_SBS) prn-=80; /* 40-58: sbas 120-138 */ - - /* generate obs field data gps */ - gen_obs_gps(rtcm,rtcm->obs.data+j,&code1,&pr1,&ppr1,&lock1,&amb,NULL, - NULL,NULL,NULL,NULL,NULL); - - setbitu(rtcm->buff,i, 6,prn ); i+= 6; - setbitu(rtcm->buff,i, 1,code1); i+= 1; - setbitu(rtcm->buff,i,24,pr1 ); i+=24; - setbits(rtcm->buff,i,20,ppr1 ); i+=20; - setbitu(rtcm->buff,i, 7,lock1); i+= 7; - } - rtcm->nbit=i; - return 1; +static int encode_type1001(rtcm_t *rtcm, int sync) { + int code1, pr1, ppr1, lock1, amb; + + trace(3, "encode_type1001: sync=%d\n", sync); + + int nsat = 0; + for (int j = 0; j < rtcm->obs.n && nsat < RTCMSATS; j++) { + int sys = satsys(rtcm->obs.data[j].sat, NULL); + if (!(sys & (SYS_GPS | SYS_SBS))) continue; + nsat++; + } + /* encode header */ + int i = encode_head(1001, rtcm, SYS_GPS, sync, nsat); + + nsat = 0; + for (int j = 0; j < rtcm->obs.n && nsat < RTCMSATS; j++) { + int prn, sys = satsys(rtcm->obs.data[j].sat, &prn); + if (!(sys & (SYS_GPS | SYS_SBS))) continue; + nsat++; + + if (sys == SYS_SBS) prn -= 80; /* 40-58: sbas 120-138 */ + + /* generate obs field data gps */ + gen_obs_gps(rtcm, rtcm->obs.data + j, &code1, &pr1, &ppr1, &lock1, &amb, NULL, NULL, NULL, NULL, + NULL, NULL); + + setbitu(rtcm->buff, i, 6, prn); + i += 6; + setbitu(rtcm->buff, i, 1, code1); + i += 1; + setbitu(rtcm->buff, i, 24, pr1); + i += 24; + setbits(rtcm->buff, i, 20, ppr1); + i += 20; + setbitu(rtcm->buff, i, 7, lock1); + i += 7; + } + rtcm->nbit = i; + return 1; } /* encode type 1002: extended L1-only GPS RTK observables --------------------*/ -static int encode_type1002(rtcm_t *rtcm, int sync) -{ - int code1,pr1,ppr1,lock1,amb,cnr1; - - trace(3,"encode_type1002: sync=%d\n",sync); - - int nsat = 0; - for (int j=0;jobs.n&&nsatobs.data[j].sat,NULL); - if (!(sys&(SYS_GPS|SYS_SBS))) continue; - nsat++; - } - /* encode header */ - int i = encode_head(1002,rtcm,SYS_GPS,sync,nsat); - - nsat = 0; - for (int j=0;jobs.n&&nsatobs.data[j].sat,&prn); - if (!(sys&(SYS_GPS|SYS_SBS))) continue; - nsat++; - - if (sys==SYS_SBS) prn-=80; /* 40-58: sbas 120-138 */ - - /* generate obs field data gps */ - gen_obs_gps(rtcm,rtcm->obs.data+j,&code1,&pr1,&ppr1,&lock1,&amb,&cnr1, - NULL,NULL,NULL,NULL,NULL); - - setbitu(rtcm->buff,i, 6,prn ); i+= 6; - setbitu(rtcm->buff,i, 1,code1); i+= 1; - setbitu(rtcm->buff,i,24,pr1 ); i+=24; - setbits(rtcm->buff,i,20,ppr1 ); i+=20; - setbitu(rtcm->buff,i, 7,lock1); i+= 7; - setbitu(rtcm->buff,i, 8,amb ); i+= 8; - setbitu(rtcm->buff,i, 8,cnr1 ); i+= 8; - } - rtcm->nbit=i; - return 1; +static int encode_type1002(rtcm_t *rtcm, int sync) { + int code1, pr1, ppr1, lock1, amb, cnr1; + + trace(3, "encode_type1002: sync=%d\n", sync); + + int nsat = 0; + for (int j = 0; j < rtcm->obs.n && nsat < RTCMSATS; j++) { + int sys = satsys(rtcm->obs.data[j].sat, NULL); + if (!(sys & (SYS_GPS | SYS_SBS))) continue; + nsat++; + } + /* encode header */ + int i = encode_head(1002, rtcm, SYS_GPS, sync, nsat); + + nsat = 0; + for (int j = 0; j < rtcm->obs.n && nsat < RTCMSATS; j++) { + int prn, sys = satsys(rtcm->obs.data[j].sat, &prn); + if (!(sys & (SYS_GPS | SYS_SBS))) continue; + nsat++; + + if (sys == SYS_SBS) prn -= 80; /* 40-58: sbas 120-138 */ + + /* generate obs field data gps */ + gen_obs_gps(rtcm, rtcm->obs.data + j, &code1, &pr1, &ppr1, &lock1, &amb, &cnr1, NULL, NULL, + NULL, NULL, NULL); + + setbitu(rtcm->buff, i, 6, prn); + i += 6; + setbitu(rtcm->buff, i, 1, code1); + i += 1; + setbitu(rtcm->buff, i, 24, pr1); + i += 24; + setbits(rtcm->buff, i, 20, ppr1); + i += 20; + setbitu(rtcm->buff, i, 7, lock1); + i += 7; + setbitu(rtcm->buff, i, 8, amb); + i += 8; + setbitu(rtcm->buff, i, 8, cnr1); + i += 8; + } + rtcm->nbit = i; + return 1; } /* encode type 1003: basic L1&L2 GPS RTK observables -------------------------*/ -static int encode_type1003(rtcm_t *rtcm, int sync) -{ - int code1,pr1,ppr1,lock1,amb,code2,pr21,ppr2,lock2; - - trace(3,"encode_type1003: sync=%d\n",sync); - - int nsat = 0; - for (int j=0;jobs.n&&nsatobs.data[j].sat,NULL); - if (!(sys&(SYS_GPS|SYS_SBS))) continue; - nsat++; - } - /* encode header */ - int i = encode_head(1003,rtcm,SYS_GPS,sync,nsat); - - nsat = 0; - for (int j=0;jobs.n&&nsatobs.data[j].sat,&prn); - if (!(sys&(SYS_GPS|SYS_SBS))) continue; - nsat++; - - if (sys==SYS_SBS) prn-=80; /* 40-58: sbas 120-138 */ - - /* generate obs field data gps */ - gen_obs_gps(rtcm,rtcm->obs.data+j,&code1,&pr1,&ppr1,&lock1,&amb, - NULL,&code2,&pr21,&ppr2,&lock2,NULL); - - setbitu(rtcm->buff,i, 6,prn ); i+= 6; - setbitu(rtcm->buff,i, 1,code1); i+= 1; - setbitu(rtcm->buff,i,24,pr1 ); i+=24; - setbits(rtcm->buff,i,20,ppr1 ); i+=20; - setbitu(rtcm->buff,i, 7,lock1); i+= 7; - setbitu(rtcm->buff,i, 2,code2); i+= 2; - setbits(rtcm->buff,i,14,pr21 ); i+=14; - setbits(rtcm->buff,i,20,ppr2 ); i+=20; - setbitu(rtcm->buff,i, 7,lock2); i+= 7; - } - rtcm->nbit=i; - return 1; +static int encode_type1003(rtcm_t *rtcm, int sync) { + int code1, pr1, ppr1, lock1, amb, code2, pr21, ppr2, lock2; + + trace(3, "encode_type1003: sync=%d\n", sync); + + int nsat = 0; + for (int j = 0; j < rtcm->obs.n && nsat < RTCMSATS; j++) { + int sys = satsys(rtcm->obs.data[j].sat, NULL); + if (!(sys & (SYS_GPS | SYS_SBS))) continue; + nsat++; + } + /* encode header */ + int i = encode_head(1003, rtcm, SYS_GPS, sync, nsat); + + nsat = 0; + for (int j = 0; j < rtcm->obs.n && nsat < RTCMSATS; j++) { + int prn, sys = satsys(rtcm->obs.data[j].sat, &prn); + if (!(sys & (SYS_GPS | SYS_SBS))) continue; + nsat++; + + if (sys == SYS_SBS) prn -= 80; /* 40-58: sbas 120-138 */ + + /* generate obs field data gps */ + gen_obs_gps(rtcm, rtcm->obs.data + j, &code1, &pr1, &ppr1, &lock1, &amb, NULL, &code2, &pr21, + &ppr2, &lock2, NULL); + + setbitu(rtcm->buff, i, 6, prn); + i += 6; + setbitu(rtcm->buff, i, 1, code1); + i += 1; + setbitu(rtcm->buff, i, 24, pr1); + i += 24; + setbits(rtcm->buff, i, 20, ppr1); + i += 20; + setbitu(rtcm->buff, i, 7, lock1); + i += 7; + setbitu(rtcm->buff, i, 2, code2); + i += 2; + setbits(rtcm->buff, i, 14, pr21); + i += 14; + setbits(rtcm->buff, i, 20, ppr2); + i += 20; + setbitu(rtcm->buff, i, 7, lock2); + i += 7; + } + rtcm->nbit = i; + return 1; } /* encode type 1004: extended L1&L2 GPS RTK observables ----------------------*/ -static int encode_type1004(rtcm_t *rtcm, int sync) -{ - int code1,pr1,ppr1,lock1,amb,cnr1,code2,pr21,ppr2,lock2,cnr2; - - trace(3,"encode_type1004: sync=%d\n",sync); - - int nsat = 0; - for (int j=0;jobs.n&&nsatobs.data[j].sat,NULL); - if (!(sys&(SYS_GPS|SYS_SBS))) continue; - nsat++; - } - /* encode header */ - int i = encode_head(1004,rtcm,SYS_GPS,sync,nsat); - - nsat = 0; - for (int j=0;jobs.n&&nsatobs.data[j].sat,&prn); - if (!(sys&(SYS_GPS|SYS_SBS))) continue; - nsat++; - - if (sys==SYS_SBS) prn-=80; /* 40-58: sbas 120-138 */ - - /* generate obs field data gps */ - gen_obs_gps(rtcm,rtcm->obs.data+j,&code1,&pr1,&ppr1,&lock1,&amb, - &cnr1,&code2,&pr21,&ppr2,&lock2,&cnr2); - - setbitu(rtcm->buff,i, 6,prn ); i+= 6; - setbitu(rtcm->buff,i, 1,code1); i+= 1; - setbitu(rtcm->buff,i,24,pr1 ); i+=24; - setbits(rtcm->buff,i,20,ppr1 ); i+=20; - setbitu(rtcm->buff,i, 7,lock1); i+= 7; - setbitu(rtcm->buff,i, 8,amb ); i+= 8; - setbitu(rtcm->buff,i, 8,cnr1 ); i+= 8; - setbitu(rtcm->buff,i, 2,code2); i+= 2; - setbits(rtcm->buff,i,14,pr21 ); i+=14; - setbits(rtcm->buff,i,20,ppr2 ); i+=20; - setbitu(rtcm->buff,i, 7,lock2); i+= 7; - setbitu(rtcm->buff,i, 8,cnr2 ); i+= 8; - } - rtcm->nbit=i; - return 1; +static int encode_type1004(rtcm_t *rtcm, int sync) { + int code1, pr1, ppr1, lock1, amb, cnr1, code2, pr21, ppr2, lock2, cnr2; + + trace(3, "encode_type1004: sync=%d\n", sync); + + int nsat = 0; + for (int j = 0; j < rtcm->obs.n && nsat < RTCMSATS; j++) { + int sys = satsys(rtcm->obs.data[j].sat, NULL); + if (!(sys & (SYS_GPS | SYS_SBS))) continue; + nsat++; + } + /* encode header */ + int i = encode_head(1004, rtcm, SYS_GPS, sync, nsat); + + nsat = 0; + for (int j = 0; j < rtcm->obs.n && nsat < RTCMSATS; j++) { + int prn, sys = satsys(rtcm->obs.data[j].sat, &prn); + if (!(sys & (SYS_GPS | SYS_SBS))) continue; + nsat++; + + if (sys == SYS_SBS) prn -= 80; /* 40-58: sbas 120-138 */ + + /* generate obs field data gps */ + gen_obs_gps(rtcm, rtcm->obs.data + j, &code1, &pr1, &ppr1, &lock1, &amb, &cnr1, &code2, &pr21, + &ppr2, &lock2, &cnr2); + + setbitu(rtcm->buff, i, 6, prn); + i += 6; + setbitu(rtcm->buff, i, 1, code1); + i += 1; + setbitu(rtcm->buff, i, 24, pr1); + i += 24; + setbits(rtcm->buff, i, 20, ppr1); + i += 20; + setbitu(rtcm->buff, i, 7, lock1); + i += 7; + setbitu(rtcm->buff, i, 8, amb); + i += 8; + setbitu(rtcm->buff, i, 8, cnr1); + i += 8; + setbitu(rtcm->buff, i, 2, code2); + i += 2; + setbits(rtcm->buff, i, 14, pr21); + i += 14; + setbits(rtcm->buff, i, 20, ppr2); + i += 20; + setbitu(rtcm->buff, i, 7, lock2); + i += 7; + setbitu(rtcm->buff, i, 8, cnr2); + i += 8; + } + rtcm->nbit = i; + return 1; } /* encode type 1005: stationary RTK reference station ARP --------------------*/ -static int encode_type1005(rtcm_t *rtcm, int sync) -{ - double *p=rtcm->sta.pos; - int i=24; - - trace(3,"encode_type1005: sync=%d\n",sync); - - setbitu(rtcm->buff,i,12,1005 ); i+=12; /* message no */ - setbitu(rtcm->buff,i,12,rtcm->staid); i+=12; /* ref station id */ - setbitu(rtcm->buff,i, 6,0 ); i+= 6; /* itrf realization year */ - setbitu(rtcm->buff,i, 1,1 ); i+= 1; /* gps indicator */ - setbitu(rtcm->buff,i, 1,1 ); i+= 1; /* glonass indicator */ - setbitu(rtcm->buff,i, 1,0 ); i+= 1; /* galileo indicator */ - setbitu(rtcm->buff,i, 1,0 ); i+= 1; /* ref station indicator */ - set38bits(rtcm->buff,i,p[0]/0.0001 ); i+=38; /* antenna ref point ecef-x */ - setbitu(rtcm->buff,i, 1,1 ); i+= 1; /* oscillator indicator */ - setbitu(rtcm->buff,i, 1,0 ); i+= 1; /* reserved */ - set38bits(rtcm->buff,i,p[1]/0.0001 ); i+=38; /* antenna ref point ecef-y */ - setbitu(rtcm->buff,i, 2,0 ); i+= 2; /* quarter cycle indicator */ - set38bits(rtcm->buff,i,p[2]/0.0001 ); i+=38; /* antenna ref point ecef-z */ - rtcm->nbit=i; - return 1; +static int encode_type1005(rtcm_t *rtcm, int sync) { + double *p = rtcm->sta.pos; + int i = 24; + + trace(3, "encode_type1005: sync=%d\n", sync); + + setbitu(rtcm->buff, i, 12, 1005); + i += 12; /* message no */ + setbitu(rtcm->buff, i, 12, rtcm->staid); + i += 12; /* ref station id */ + setbitu(rtcm->buff, i, 6, 0); + i += 6; /* itrf realization year */ + setbitu(rtcm->buff, i, 1, 1); + i += 1; /* gps indicator */ + setbitu(rtcm->buff, i, 1, 1); + i += 1; /* glonass indicator */ + setbitu(rtcm->buff, i, 1, 0); + i += 1; /* galileo indicator */ + setbitu(rtcm->buff, i, 1, 0); + i += 1; /* ref station indicator */ + set38bits(rtcm->buff, i, p[0] / 0.0001); + i += 38; /* antenna ref point ecef-x */ + setbitu(rtcm->buff, i, 1, 1); + i += 1; /* oscillator indicator */ + setbitu(rtcm->buff, i, 1, 0); + i += 1; /* reserved */ + set38bits(rtcm->buff, i, p[1] / 0.0001); + i += 38; /* antenna ref point ecef-y */ + setbitu(rtcm->buff, i, 2, 0); + i += 2; /* quarter cycle indicator */ + set38bits(rtcm->buff, i, p[2] / 0.0001); + i += 38; /* antenna ref point ecef-z */ + rtcm->nbit = i; + return 1; } /* encode type 1006: stationary RTK reference station ARP with height --------*/ -static int encode_type1006(rtcm_t *rtcm, int sync) -{ - double *p=rtcm->sta.pos; - int i=24,hgt=0; - - trace(3,"encode_type1006: sync=%d\n",sync); - - if (0.0<=rtcm->sta.hgt&&rtcm->sta.hgt<=6.5535) { - hgt=ROUND(rtcm->sta.hgt/0.0001); - } - else { - trace(2,"antenna height error: h=%.4f\n",rtcm->sta.hgt); - } - setbitu(rtcm->buff,i,12,1006 ); i+=12; /* message no */ - setbitu(rtcm->buff,i,12,rtcm->staid); i+=12; /* ref station id */ - setbitu(rtcm->buff,i, 6,0 ); i+= 6; /* itrf realization year */ - setbitu(rtcm->buff,i, 1,1 ); i+= 1; /* gps indicator */ - setbitu(rtcm->buff,i, 1,1 ); i+= 1; /* glonass indicator */ - setbitu(rtcm->buff,i, 1,0 ); i+= 1; /* galileo indicator */ - setbitu(rtcm->buff,i, 1,0 ); i+= 1; /* ref station indicator */ - set38bits(rtcm->buff,i,p[0]/0.0001 ); i+=38; /* antenna ref point ecef-x */ - setbitu(rtcm->buff,i, 1,1 ); i+= 1; /* oscillator indicator */ - setbitu(rtcm->buff,i, 1,0 ); i+= 1; /* reserved */ - set38bits(rtcm->buff,i,p[1]/0.0001 ); i+=38; /* antenna ref point ecef-y */ - setbitu(rtcm->buff,i, 2,0 ); i+= 2; /* quarter cycle indicator */ - set38bits(rtcm->buff,i,p[2]/0.0001 ); i+=38; /* antenna ref point ecef-z */ - setbitu(rtcm->buff,i,16,hgt ); i+=16; /* antenna height */ - rtcm->nbit=i; - return 1; +static int encode_type1006(rtcm_t *rtcm, int sync) { + double *p = rtcm->sta.pos; + int i = 24, hgt = 0; + + trace(3, "encode_type1006: sync=%d\n", sync); + + if (0.0 <= rtcm->sta.hgt && rtcm->sta.hgt <= 6.5535) { + hgt = ROUND(rtcm->sta.hgt / 0.0001); + } else { + trace(2, "antenna height error: h=%.4f\n", rtcm->sta.hgt); + } + setbitu(rtcm->buff, i, 12, 1006); + i += 12; /* message no */ + setbitu(rtcm->buff, i, 12, rtcm->staid); + i += 12; /* ref station id */ + setbitu(rtcm->buff, i, 6, 0); + i += 6; /* itrf realization year */ + setbitu(rtcm->buff, i, 1, 1); + i += 1; /* gps indicator */ + setbitu(rtcm->buff, i, 1, 1); + i += 1; /* glonass indicator */ + setbitu(rtcm->buff, i, 1, 0); + i += 1; /* galileo indicator */ + setbitu(rtcm->buff, i, 1, 0); + i += 1; /* ref station indicator */ + set38bits(rtcm->buff, i, p[0] / 0.0001); + i += 38; /* antenna ref point ecef-x */ + setbitu(rtcm->buff, i, 1, 1); + i += 1; /* oscillator indicator */ + setbitu(rtcm->buff, i, 1, 0); + i += 1; /* reserved */ + set38bits(rtcm->buff, i, p[1] / 0.0001); + i += 38; /* antenna ref point ecef-y */ + setbitu(rtcm->buff, i, 2, 0); + i += 2; /* quarter cycle indicator */ + set38bits(rtcm->buff, i, p[2] / 0.0001); + i += 38; /* antenna ref point ecef-z */ + setbitu(rtcm->buff, i, 16, hgt); + i += 16; /* antenna height */ + rtcm->nbit = i; + return 1; } /* encode type 1007: antenna descriptor --------------------------------------*/ -static int encode_type1007(rtcm_t *rtcm, int sync) -{ - int i=24,j,antsetup=rtcm->sta.antsetup; - int n=MIN((int)strlen(rtcm->sta.antdes),31); - - trace(3,"encode_type1007: sync=%d\n",sync); - - setbitu(rtcm->buff,i,12,1007 ); i+=12; /* message no */ - setbitu(rtcm->buff,i,12,rtcm->staid); i+=12; /* ref station id */ - - /* antenna descriptor */ - setbitu(rtcm->buff,i,8,n); i+=8; - for (j=0;jbuff,i,8,rtcm->sta.antdes[j]); i+=8; - } - setbitu(rtcm->buff,i,8,antsetup); i+=8; /* antetnna setup id */ - rtcm->nbit=i; - return 1; +static int encode_type1007(rtcm_t *rtcm, int sync) { + int i = 24, j, antsetup = rtcm->sta.antsetup; + int n = MIN((int)strlen(rtcm->sta.antdes), 31); + + trace(3, "encode_type1007: sync=%d\n", sync); + + setbitu(rtcm->buff, i, 12, 1007); + i += 12; /* message no */ + setbitu(rtcm->buff, i, 12, rtcm->staid); + i += 12; /* ref station id */ + + /* antenna descriptor */ + setbitu(rtcm->buff, i, 8, n); + i += 8; + for (j = 0; j < n; j++) { + setbitu(rtcm->buff, i, 8, rtcm->sta.antdes[j]); + i += 8; + } + setbitu(rtcm->buff, i, 8, antsetup); + i += 8; /* antetnna setup id */ + rtcm->nbit = i; + return 1; } /* encode type 1008: antenna descriptor & serial number ----------------------*/ -static int encode_type1008(rtcm_t *rtcm, int sync) -{ - int i=24,j,antsetup=rtcm->sta.antsetup; - int n=MIN((int)strlen(rtcm->sta.antdes),31); - int m=MIN((int)strlen(rtcm->sta.antsno),31); - - trace(3,"encode_type1008: sync=%d\n",sync); - - setbitu(rtcm->buff,i,12,1008 ); i+=12; /* message no */ - setbitu(rtcm->buff,i,12,rtcm->staid); i+=12; /* ref station id */ - - /* antenna descriptor */ - setbitu(rtcm->buff,i,8,n); i+=8; - for (j=0;jbuff,i,8,rtcm->sta.antdes[j]); i+=8; - } - setbitu(rtcm->buff,i,8,antsetup); i+=8; /* antenna setup id */ - - /* antenna serial number */ - setbitu(rtcm->buff,i,8,m); i+=8; - for (j=0;jbuff,i,8,rtcm->sta.antsno[j]); i+=8; - } - rtcm->nbit=i; - return 1; +static int encode_type1008(rtcm_t *rtcm, int sync) { + int i = 24, j, antsetup = rtcm->sta.antsetup; + int n = MIN((int)strlen(rtcm->sta.antdes), 31); + int m = MIN((int)strlen(rtcm->sta.antsno), 31); + + trace(3, "encode_type1008: sync=%d\n", sync); + + setbitu(rtcm->buff, i, 12, 1008); + i += 12; /* message no */ + setbitu(rtcm->buff, i, 12, rtcm->staid); + i += 12; /* ref station id */ + + /* antenna descriptor */ + setbitu(rtcm->buff, i, 8, n); + i += 8; + for (j = 0; j < n; j++) { + setbitu(rtcm->buff, i, 8, rtcm->sta.antdes[j]); + i += 8; + } + setbitu(rtcm->buff, i, 8, antsetup); + i += 8; /* antenna setup id */ + + /* antenna serial number */ + setbitu(rtcm->buff, i, 8, m); + i += 8; + for (j = 0; j < m; j++) { + setbitu(rtcm->buff, i, 8, rtcm->sta.antsno[j]); + i += 8; + } + rtcm->nbit = i; + return 1; } /* encode type 1009: basic L1-only GLONASS RTK observables -------------------*/ -static int encode_type1009(rtcm_t *rtcm, int sync) -{ - int nsat = 0; - for (int j=0;jobs.n&&nsatobs.data[j].sat; - if (satsys(sat,NULL)!=SYS_GLO) continue; - if (fcn_glo(sat,rtcm) < 0) continue; /* fcn+7 */ - nsat++; - } - /* encode header */ - int i = encode_head(1009,rtcm,SYS_GLO,sync,nsat); - - nsat = 0; - for (int j=0;jobs.n&&nsatobs.data[j].sat, prn; - if (satsys(sat,&prn)!=SYS_GLO) continue; - int fcn = fcn_glo(sat,rtcm); - if (fcn < 0) continue; /* fcn+7 */ - nsat++; - - /* generate obs field data glonass */ - int code1,pr1,ppr1,lock1,amb; - gen_obs_glo(rtcm,rtcm->obs.data+j,fcn,&code1,&pr1,&ppr1,&lock1,&amb, - NULL,NULL,NULL,NULL,NULL,NULL); - - setbitu(rtcm->buff,i, 6,prn ); i+= 6; - setbitu(rtcm->buff,i, 1,code1); i+= 1; - setbitu(rtcm->buff,i, 5,fcn ); i+= 5; /* fcn+7 */ - setbitu(rtcm->buff,i,25,pr1 ); i+=25; - setbits(rtcm->buff,i,20,ppr1 ); i+=20; - setbitu(rtcm->buff,i, 7,lock1); i+= 7; - } - rtcm->nbit=i; - return 1; +static int encode_type1009(rtcm_t *rtcm, int sync) { + int nsat = 0; + for (int j = 0; j < rtcm->obs.n && nsat < RTCMSATS; j++) { + int sat = rtcm->obs.data[j].sat; + if (satsys(sat, NULL) != SYS_GLO) continue; + if (fcn_glo(sat, rtcm) < 0) continue; /* fcn+7 */ + nsat++; + } + /* encode header */ + int i = encode_head(1009, rtcm, SYS_GLO, sync, nsat); + + nsat = 0; + for (int j = 0; j < rtcm->obs.n && nsat < RTCMSATS; j++) { + int sat = rtcm->obs.data[j].sat, prn; + if (satsys(sat, &prn) != SYS_GLO) continue; + int fcn = fcn_glo(sat, rtcm); + if (fcn < 0) continue; /* fcn+7 */ + nsat++; + + /* generate obs field data glonass */ + int code1, pr1, ppr1, lock1, amb; + gen_obs_glo(rtcm, rtcm->obs.data + j, fcn, &code1, &pr1, &ppr1, &lock1, &amb, NULL, NULL, NULL, + NULL, NULL, NULL); + + setbitu(rtcm->buff, i, 6, prn); + i += 6; + setbitu(rtcm->buff, i, 1, code1); + i += 1; + setbitu(rtcm->buff, i, 5, fcn); + i += 5; /* fcn+7 */ + setbitu(rtcm->buff, i, 25, pr1); + i += 25; + setbits(rtcm->buff, i, 20, ppr1); + i += 20; + setbitu(rtcm->buff, i, 7, lock1); + i += 7; + } + rtcm->nbit = i; + return 1; } /* encode type 1010: extended L1-only GLONASS RTK observables ----------------*/ -static int encode_type1010(rtcm_t *rtcm, int sync) -{ - trace(3,"encode_type1010: sync=%d\n",sync); - - int nsat = 0; - for (int j=0;jobs.n&&nsatobs.data[j].sat; - if (satsys(sat,NULL)!=SYS_GLO) continue; - if (fcn_glo(sat,rtcm) < 0) continue; /* fcn+7 */ - nsat++; - } - /* encode header */ - int i = encode_head(1010,rtcm,SYS_GLO,sync,nsat); - - nsat = 0; - for (int j=0;jobs.n&&nsatobs.data[j].sat, prn; - if (satsys(sat,&prn)!=SYS_GLO) continue; - int fcn = fcn_glo(sat,rtcm); - if (fcn < 0) continue; /* fcn+7 */ - nsat++; - - /* generate obs field data glonass */ - int code1,pr1,ppr1,lock1,amb,cnr1; - gen_obs_glo(rtcm,rtcm->obs.data+j,fcn,&code1,&pr1,&ppr1,&lock1,&amb, - &cnr1,NULL,NULL,NULL,NULL,NULL); - - setbitu(rtcm->buff,i, 6,prn ); i+= 6; - setbitu(rtcm->buff,i, 1,code1); i+= 1; - setbitu(rtcm->buff,i, 5,fcn ); i+= 5; /* fcn+7 */ - setbitu(rtcm->buff,i,25,pr1 ); i+=25; - setbits(rtcm->buff,i,20,ppr1 ); i+=20; - setbitu(rtcm->buff,i, 7,lock1); i+= 7; - setbitu(rtcm->buff,i, 7,amb ); i+= 7; - setbitu(rtcm->buff,i, 8,cnr1 ); i+= 8; - } - rtcm->nbit=i; - return 1; +static int encode_type1010(rtcm_t *rtcm, int sync) { + trace(3, "encode_type1010: sync=%d\n", sync); + + int nsat = 0; + for (int j = 0; j < rtcm->obs.n && nsat < RTCMSATS; j++) { + int sat = rtcm->obs.data[j].sat; + if (satsys(sat, NULL) != SYS_GLO) continue; + if (fcn_glo(sat, rtcm) < 0) continue; /* fcn+7 */ + nsat++; + } + /* encode header */ + int i = encode_head(1010, rtcm, SYS_GLO, sync, nsat); + + nsat = 0; + for (int j = 0; j < rtcm->obs.n && nsat < RTCMSATS; j++) { + int sat = rtcm->obs.data[j].sat, prn; + if (satsys(sat, &prn) != SYS_GLO) continue; + int fcn = fcn_glo(sat, rtcm); + if (fcn < 0) continue; /* fcn+7 */ + nsat++; + + /* generate obs field data glonass */ + int code1, pr1, ppr1, lock1, amb, cnr1; + gen_obs_glo(rtcm, rtcm->obs.data + j, fcn, &code1, &pr1, &ppr1, &lock1, &amb, &cnr1, NULL, NULL, + NULL, NULL, NULL); + + setbitu(rtcm->buff, i, 6, prn); + i += 6; + setbitu(rtcm->buff, i, 1, code1); + i += 1; + setbitu(rtcm->buff, i, 5, fcn); + i += 5; /* fcn+7 */ + setbitu(rtcm->buff, i, 25, pr1); + i += 25; + setbits(rtcm->buff, i, 20, ppr1); + i += 20; + setbitu(rtcm->buff, i, 7, lock1); + i += 7; + setbitu(rtcm->buff, i, 7, amb); + i += 7; + setbitu(rtcm->buff, i, 8, cnr1); + i += 8; + } + rtcm->nbit = i; + return 1; } /* encode type 1011: basic L1&L2 GLONASS RTK observables --------------------*/ -static int encode_type1011(rtcm_t *rtcm, int sync) -{ - trace(3,"encode_type1011: sync=%d\n",sync); - - int nsat = 0; - for (int j=0;jobs.n&&nsatobs.data[j].sat; - if (satsys(sat,NULL)!=SYS_GLO) continue; - if (fcn_glo(sat,rtcm)<0) continue; /* fcn+7 */ - nsat++; - } - /* encode header */ - int i = encode_head(1011,rtcm,SYS_GLO,sync,nsat); - - nsat = 0; - for (int j=0;jobs.n&&nsatobs.data[j].sat, prn; - if (satsys(sat,&prn)!=SYS_GLO) continue; - int fcn = fcn_glo(sat,rtcm); - if (fcn < 0) continue; /* fcn+7 */ - nsat++; - - /* generate obs field data glonass */ - int code1,pr1,ppr1,lock1,amb,code2,pr21,ppr2,lock2; - gen_obs_glo(rtcm,rtcm->obs.data+j,fcn,&code1,&pr1,&ppr1,&lock1,&amb, - NULL,&code2,&pr21,&ppr2,&lock2,NULL); - - setbitu(rtcm->buff,i, 6,prn ); i+= 6; - setbitu(rtcm->buff,i, 1,code1); i+= 1; - setbitu(rtcm->buff,i, 5,fcn ); i+= 5; /* fcn+7 */ - setbitu(rtcm->buff,i,25,pr1 ); i+=25; - setbits(rtcm->buff,i,20,ppr1 ); i+=20; - setbitu(rtcm->buff,i, 7,lock1); i+= 7; - setbitu(rtcm->buff,i, 2,code2); i+= 2; - setbits(rtcm->buff,i,14,pr21 ); i+=14; - setbits(rtcm->buff,i,20,ppr2 ); i+=20; - setbitu(rtcm->buff,i, 7,lock2); i+= 7; - } - rtcm->nbit=i; - return 1; +static int encode_type1011(rtcm_t *rtcm, int sync) { + trace(3, "encode_type1011: sync=%d\n", sync); + + int nsat = 0; + for (int j = 0; j < rtcm->obs.n && nsat < RTCMSATS; j++) { + int sat = rtcm->obs.data[j].sat; + if (satsys(sat, NULL) != SYS_GLO) continue; + if (fcn_glo(sat, rtcm) < 0) continue; /* fcn+7 */ + nsat++; + } + /* encode header */ + int i = encode_head(1011, rtcm, SYS_GLO, sync, nsat); + + nsat = 0; + for (int j = 0; j < rtcm->obs.n && nsat < RTCMSATS; j++) { + int sat = rtcm->obs.data[j].sat, prn; + if (satsys(sat, &prn) != SYS_GLO) continue; + int fcn = fcn_glo(sat, rtcm); + if (fcn < 0) continue; /* fcn+7 */ + nsat++; + + /* generate obs field data glonass */ + int code1, pr1, ppr1, lock1, amb, code2, pr21, ppr2, lock2; + gen_obs_glo(rtcm, rtcm->obs.data + j, fcn, &code1, &pr1, &ppr1, &lock1, &amb, NULL, &code2, + &pr21, &ppr2, &lock2, NULL); + + setbitu(rtcm->buff, i, 6, prn); + i += 6; + setbitu(rtcm->buff, i, 1, code1); + i += 1; + setbitu(rtcm->buff, i, 5, fcn); + i += 5; /* fcn+7 */ + setbitu(rtcm->buff, i, 25, pr1); + i += 25; + setbits(rtcm->buff, i, 20, ppr1); + i += 20; + setbitu(rtcm->buff, i, 7, lock1); + i += 7; + setbitu(rtcm->buff, i, 2, code2); + i += 2; + setbits(rtcm->buff, i, 14, pr21); + i += 14; + setbits(rtcm->buff, i, 20, ppr2); + i += 20; + setbitu(rtcm->buff, i, 7, lock2); + i += 7; + } + rtcm->nbit = i; + return 1; } /* encode type 1012: extended L1&L2 GLONASS RTK observables ------------------*/ -static int encode_type1012(rtcm_t *rtcm, int sync) -{ - trace(3,"encode_type1012: sync=%d\n",sync); - - int nsat = 0; - for (int j=0;jobs.n&&nsatobs.data[j].sat; - if (satsys(sat,NULL)!=SYS_GLO) continue; - if (fcn_glo(sat,rtcm)<0) continue; /* fcn+7 */ - nsat++; - } - /* encode header */ - int i = encode_head(1012,rtcm,SYS_GLO,sync,nsat); - - nsat = 0; - for (int j=0;jobs.n&&nsatobs.data[j].sat, prn; - if (satsys(sat,&prn)!=SYS_GLO) continue; - int fcn = fcn_glo(sat,rtcm); - if (fcn < 0) continue; /* fcn+7 */ - nsat++; - - /* generate obs field data glonass */ - int code1,pr1,ppr1,lock1,amb,cnr1,code2,pr21,ppr2,lock2,cnr2; - gen_obs_glo(rtcm,rtcm->obs.data+j,fcn,&code1,&pr1,&ppr1,&lock1,&amb, - &cnr1,&code2,&pr21,&ppr2,&lock2,&cnr2); - - setbitu(rtcm->buff,i, 6,prn ); i+= 6; - setbitu(rtcm->buff,i, 1,code1); i+= 1; - setbitu(rtcm->buff,i, 5,fcn ); i+= 5; /* fcn+7 */ - setbitu(rtcm->buff,i,25,pr1 ); i+=25; - setbits(rtcm->buff,i,20,ppr1 ); i+=20; - setbitu(rtcm->buff,i, 7,lock1); i+= 7; - setbitu(rtcm->buff,i, 7,amb ); i+= 7; - setbitu(rtcm->buff,i, 8,cnr1 ); i+= 8; - setbitu(rtcm->buff,i, 2,code2); i+= 2; - setbits(rtcm->buff,i,14,pr21 ); i+=14; - setbits(rtcm->buff,i,20,ppr2 ); i+=20; - setbitu(rtcm->buff,i, 7,lock2); i+= 7; - setbitu(rtcm->buff,i, 8,cnr2 ); i+= 8; - } - rtcm->nbit=i; - return 1; +static int encode_type1012(rtcm_t *rtcm, int sync) { + trace(3, "encode_type1012: sync=%d\n", sync); + + int nsat = 0; + for (int j = 0; j < rtcm->obs.n && nsat < RTCMSATS; j++) { + int sat = rtcm->obs.data[j].sat; + if (satsys(sat, NULL) != SYS_GLO) continue; + if (fcn_glo(sat, rtcm) < 0) continue; /* fcn+7 */ + nsat++; + } + /* encode header */ + int i = encode_head(1012, rtcm, SYS_GLO, sync, nsat); + + nsat = 0; + for (int j = 0; j < rtcm->obs.n && nsat < RTCMSATS; j++) { + int sat = rtcm->obs.data[j].sat, prn; + if (satsys(sat, &prn) != SYS_GLO) continue; + int fcn = fcn_glo(sat, rtcm); + if (fcn < 0) continue; /* fcn+7 */ + nsat++; + + /* generate obs field data glonass */ + int code1, pr1, ppr1, lock1, amb, cnr1, code2, pr21, ppr2, lock2, cnr2; + gen_obs_glo(rtcm, rtcm->obs.data + j, fcn, &code1, &pr1, &ppr1, &lock1, &amb, &cnr1, &code2, + &pr21, &ppr2, &lock2, &cnr2); + + setbitu(rtcm->buff, i, 6, prn); + i += 6; + setbitu(rtcm->buff, i, 1, code1); + i += 1; + setbitu(rtcm->buff, i, 5, fcn); + i += 5; /* fcn+7 */ + setbitu(rtcm->buff, i, 25, pr1); + i += 25; + setbits(rtcm->buff, i, 20, ppr1); + i += 20; + setbitu(rtcm->buff, i, 7, lock1); + i += 7; + setbitu(rtcm->buff, i, 7, amb); + i += 7; + setbitu(rtcm->buff, i, 8, cnr1); + i += 8; + setbitu(rtcm->buff, i, 2, code2); + i += 2; + setbits(rtcm->buff, i, 14, pr21); + i += 14; + setbits(rtcm->buff, i, 20, ppr2); + i += 20; + setbitu(rtcm->buff, i, 7, lock2); + i += 7; + setbitu(rtcm->buff, i, 8, cnr2); + i += 8; + } + rtcm->nbit = i; + return 1; } /* encode type 1019: GPS ephemerides -----------------------------------------*/ -static int encode_type1019(rtcm_t *rtcm, int sync) -{ - eph_t *eph; - uint32_t sqrtA,e; - int i=24,prn,week,toe,toc,i0,OMG0,omg,M0,deln,idot,OMGd,crs,crc; - int cus,cuc,cis,cic,af0,af1,af2,tgd; - - trace(3,"encode_type1019: sync=%d\n",sync); - - if (satsys(rtcm->ephsat,&prn)!=SYS_GPS) return 0; - eph=rtcm->nav.eph+rtcm->ephsat-1; - if (eph->sat!=rtcm->ephsat) return 0; - week=eph->week%1024; - toe =ROUND(eph->toes/16.0); - toc =ROUND(time2gpst(eph->toc,NULL)/16.0); - sqrtA=ROUND_U(sqrt(eph->A)/P2_19); - e =ROUND_U(eph->e/P2_33); - i0 =ROUND(eph->i0 /P2_31/SC2RAD); - OMG0 =ROUND(eph->OMG0/P2_31/SC2RAD); - omg =ROUND(eph->omg /P2_31/SC2RAD); - M0 =ROUND(eph->M0 /P2_31/SC2RAD); - deln =ROUND(eph->deln/P2_43/SC2RAD); - idot =ROUND(eph->idot/P2_43/SC2RAD); - OMGd =ROUND(eph->OMGd/P2_43/SC2RAD); - crs =ROUND(eph->crs/P2_5 ); - crc =ROUND(eph->crc/P2_5 ); - cus =ROUND(eph->cus/P2_29); - cuc =ROUND(eph->cuc/P2_29); - cis =ROUND(eph->cis/P2_29); - cic =ROUND(eph->cic/P2_29); - af0 =ROUND(eph->f0 /P2_31); - af1 =ROUND(eph->f1 /P2_43); - af2 =ROUND(eph->f2 /P2_55); - tgd =ROUND(eph->tgd[0]/P2_31); - - setbitu(rtcm->buff,i,12,1019 ); i+=12; - setbitu(rtcm->buff,i, 6,prn ); i+= 6; - setbitu(rtcm->buff,i,10,week ); i+=10; - setbitu(rtcm->buff,i, 4,eph->sva ); i+= 4; - setbitu(rtcm->buff,i, 2,eph->code); i+= 2; - setbits(rtcm->buff,i,14,idot ); i+=14; - setbitu(rtcm->buff,i, 8,eph->iode); i+= 8; - setbitu(rtcm->buff,i,16,toc ); i+=16; - setbits(rtcm->buff,i, 8,af2 ); i+= 8; - setbits(rtcm->buff,i,16,af1 ); i+=16; - setbits(rtcm->buff,i,22,af0 ); i+=22; - setbitu(rtcm->buff,i,10,eph->iodc); i+=10; - setbits(rtcm->buff,i,16,crs ); i+=16; - setbits(rtcm->buff,i,16,deln ); i+=16; - setbits(rtcm->buff,i,32,M0 ); i+=32; - setbits(rtcm->buff,i,16,cuc ); i+=16; - setbitu(rtcm->buff,i,32,e ); i+=32; - setbits(rtcm->buff,i,16,cus ); i+=16; - setbitu(rtcm->buff,i,32,sqrtA ); i+=32; - setbitu(rtcm->buff,i,16,toe ); i+=16; - setbits(rtcm->buff,i,16,cic ); i+=16; - setbits(rtcm->buff,i,32,OMG0 ); i+=32; - setbits(rtcm->buff,i,16,cis ); i+=16; - setbits(rtcm->buff,i,32,i0 ); i+=32; - setbits(rtcm->buff,i,16,crc ); i+=16; - setbits(rtcm->buff,i,32,omg ); i+=32; - setbits(rtcm->buff,i,24,OMGd ); i+=24; - setbits(rtcm->buff,i, 8,tgd ); i+= 8; - setbitu(rtcm->buff,i, 6,eph->svh ); i+= 6; - setbitu(rtcm->buff,i, 1,eph->flag); i+= 1; - setbitu(rtcm->buff,i, 1,eph->fit>4?1:0); i+=1; - rtcm->nbit=i; - return 1; +static int encode_type1019(rtcm_t *rtcm, int sync) { + eph_t *eph; + uint32_t sqrtA, e; + int i = 24, prn, week, toe, toc, i0, OMG0, omg, M0, deln, idot, OMGd, crs, crc; + int cus, cuc, cis, cic, af0, af1, af2, tgd; + + trace(3, "encode_type1019: sync=%d\n", sync); + + if (satsys(rtcm->ephsat, &prn) != SYS_GPS) return 0; + eph = rtcm->nav.eph + rtcm->ephsat - 1; + if (eph->sat != rtcm->ephsat) return 0; + week = eph->week % 1024; + toe = ROUND(eph->toes / 16.0); + toc = ROUND(time2gpst(eph->toc, NULL) / 16.0); + sqrtA = ROUND_U(sqrt(eph->A) / P2_19); + e = ROUND_U(eph->e / P2_33); + i0 = ROUND(eph->i0 / P2_31 / SC2RAD); + OMG0 = ROUND(eph->OMG0 / P2_31 / SC2RAD); + omg = ROUND(eph->omg / P2_31 / SC2RAD); + M0 = ROUND(eph->M0 / P2_31 / SC2RAD); + deln = ROUND(eph->deln / P2_43 / SC2RAD); + idot = ROUND(eph->idot / P2_43 / SC2RAD); + OMGd = ROUND(eph->OMGd / P2_43 / SC2RAD); + crs = ROUND(eph->crs / P2_5); + crc = ROUND(eph->crc / P2_5); + cus = ROUND(eph->cus / P2_29); + cuc = ROUND(eph->cuc / P2_29); + cis = ROUND(eph->cis / P2_29); + cic = ROUND(eph->cic / P2_29); + af0 = ROUND(eph->f0 / P2_31); + af1 = ROUND(eph->f1 / P2_43); + af2 = ROUND(eph->f2 / P2_55); + tgd = ROUND(eph->tgd[0] / P2_31); + + setbitu(rtcm->buff, i, 12, 1019); + i += 12; + setbitu(rtcm->buff, i, 6, prn); + i += 6; + setbitu(rtcm->buff, i, 10, week); + i += 10; + setbitu(rtcm->buff, i, 4, eph->sva); + i += 4; + setbitu(rtcm->buff, i, 2, eph->code); + i += 2; + setbits(rtcm->buff, i, 14, idot); + i += 14; + setbitu(rtcm->buff, i, 8, eph->iode); + i += 8; + setbitu(rtcm->buff, i, 16, toc); + i += 16; + setbits(rtcm->buff, i, 8, af2); + i += 8; + setbits(rtcm->buff, i, 16, af1); + i += 16; + setbits(rtcm->buff, i, 22, af0); + i += 22; + setbitu(rtcm->buff, i, 10, eph->iodc); + i += 10; + setbits(rtcm->buff, i, 16, crs); + i += 16; + setbits(rtcm->buff, i, 16, deln); + i += 16; + setbits(rtcm->buff, i, 32, M0); + i += 32; + setbits(rtcm->buff, i, 16, cuc); + i += 16; + setbitu(rtcm->buff, i, 32, e); + i += 32; + setbits(rtcm->buff, i, 16, cus); + i += 16; + setbitu(rtcm->buff, i, 32, sqrtA); + i += 32; + setbitu(rtcm->buff, i, 16, toe); + i += 16; + setbits(rtcm->buff, i, 16, cic); + i += 16; + setbits(rtcm->buff, i, 32, OMG0); + i += 32; + setbits(rtcm->buff, i, 16, cis); + i += 16; + setbits(rtcm->buff, i, 32, i0); + i += 32; + setbits(rtcm->buff, i, 16, crc); + i += 16; + setbits(rtcm->buff, i, 32, omg); + i += 32; + setbits(rtcm->buff, i, 24, OMGd); + i += 24; + setbits(rtcm->buff, i, 8, tgd); + i += 8; + setbitu(rtcm->buff, i, 6, eph->svh); + i += 6; + setbitu(rtcm->buff, i, 1, eph->flag); + i += 1; + setbitu(rtcm->buff, i, 1, eph->fit > 4 ? 1 : 0); + i += 1; + rtcm->nbit = i; + return 1; } /* encode type 1020: GLONASS ephemerides -------------------------------------*/ -static int encode_type1020(rtcm_t *rtcm, int sync) -{ - geph_t *geph; - gtime_t time; - double ep[6]; - int i=24,j,prn,tk_h,tk_m,tk_s,tb,pos[3],vel[3],acc[3],gamn,taun,dtaun; - int fcn,NT; - - trace(3,"encode_type1020: sync=%d\n",sync); - - if (satsys(rtcm->ephsat,&prn)!=SYS_GLO) return 0; - geph=rtcm->nav.geph+prn-1; - if (geph->sat!=rtcm->ephsat) return 0; - fcn=geph->frq+7; - - /* time of frame within day (utc(su) + 3 hr) */ - time=timeadd(gpst2utc(geph->tof),10800.0); - time2epoch(time,ep); - tk_h=(int)ep[3]; - tk_m=(int)ep[4]; - tk_s=ROUND(ep[5]/30.0); - - /* # of days since jan 1 in leap year */ - ep[0]=floor(ep[0]/4.0)*4.0; ep[1]=ep[2]=1.0; - ep[3]=ep[4]=ep[5]=0.0; - NT=(int)floor(timediff(time,epoch2time(ep))/86400.+1.0); - - /* index of time interval within day (utc(su) + 3 hr) */ - time=timeadd(gpst2utc(geph->toe),10800.0); - time2epoch(time,ep); - tb=ROUND((ep[3]*3600.0+ep[4]*60.0+ep[5])/900.0); - - for (j=0;j<3;j++) { - pos[j]=ROUND(geph->pos[j]/P2_11/1E3); - vel[j]=ROUND(geph->vel[j]/P2_20/1E3); - acc[j]=ROUND(geph->acc[j]/P2_30/1E3); - } - gamn =ROUND(geph->gamn /P2_40); - taun =ROUND(geph->taun /P2_30); - dtaun=ROUND(geph->dtaun/P2_30); - int Bn = (geph->svh >> 0) & 1; - int Cn = (geph->svh >> 1) & 1; - int Cn_a = (geph->svh >> 2) & 1; - int ln = (geph->svh >> 2) & 1; - int M = (geph->flags >> 7) & 3; - int P4 = (geph->flags >> 6) & 1; - int P3 = (geph->flags >> 5) & 1; - int P2 = (geph->flags >> 4) & 1; - int P1 = (geph->flags >> 2) & 3; - int P = geph->flags & 3; - - setbitu(rtcm->buff,i,12,1020 ); i+=12; - setbitu(rtcm->buff,i, 6,prn ); i+= 6; - setbitu(rtcm->buff,i, 5,fcn ); i+= 5; - setbitu(rtcm->buff,i, 1,Cn ); i+= 1; - setbitu(rtcm->buff,i, 1,Cn_a ); i+= 1; - setbitu(rtcm->buff,i, 2,P1 ); i+= 2; - setbitu(rtcm->buff,i, 5,tk_h ); i+= 5; - setbitu(rtcm->buff,i, 6,tk_m ); i+= 6; - setbitu(rtcm->buff,i, 1,tk_s ); i+= 1; - setbitu(rtcm->buff,i, 1,Bn ); i+= 1; - setbitu(rtcm->buff,i, 1,P2 ); i+= 1; - setbitu(rtcm->buff,i, 7,tb ); i+= 7; - setbitg(rtcm->buff,i,24,vel[0] ); i+=24; - setbitg(rtcm->buff,i,27,pos[0] ); i+=27; - setbitg(rtcm->buff,i, 5,acc[0] ); i+= 5; - setbitg(rtcm->buff,i,24,vel[1] ); i+=24; - setbitg(rtcm->buff,i,27,pos[1] ); i+=27; - setbitg(rtcm->buff,i, 5,acc[1] ); i+= 5; - setbitg(rtcm->buff,i,24,vel[2] ); i+=24; - setbitg(rtcm->buff,i,27,pos[2] ); i+=27; - setbitg(rtcm->buff,i, 5,acc[2] ); i+= 5; - setbitu(rtcm->buff,i, 1,P3 ); i+= 1; - setbitg(rtcm->buff,i,11,gamn ); i+=11; - setbitu(rtcm->buff,i, 2,P ); i+= 2; - setbitu(rtcm->buff,i, 1,ln ); i+= 1; - setbitg(rtcm->buff,i,22,taun ); i+=22; - setbitg(rtcm->buff,i, 5,dtaun ); i+= 5; - setbitu(rtcm->buff,i, 5,geph->age); i+= 5; /* En */ - setbitu(rtcm->buff,i, 1,P4 ); i+= 1; - setbitu(rtcm->buff,i, 4,geph->sva); i+= 4; - setbitu(rtcm->buff,i,11,NT ); i+=11; - setbitu(rtcm->buff,i, 2,M ); i+= 2; - setbitu(rtcm->buff,i, 1,0 ); i+= 1; /* flag for additional data */ - setbitu(rtcm->buff,i,11,0 ); i+=11; /* NA */ - setbitu(rtcm->buff,i,32,0 ); i+=32; /* tauc */ - setbitu(rtcm->buff,i, 5,0 ); i+= 5; /* N4 */ - setbitu(rtcm->buff,i,22,0 ); i+=22; /* taugps */ - setbitu(rtcm->buff,i, 1,0 ); i+= 1; /* ln (fifth string) */ - setbitu(rtcm->buff,i, 7,0 ); i+= 7; - rtcm->nbit=i; - return 1; +static int encode_type1020(rtcm_t *rtcm, int sync) { + geph_t *geph; + gtime_t time; + double ep[6]; + int i = 24, j, prn, tk_h, tk_m, tk_s, tb, pos[3], vel[3], acc[3], gamn, taun, dtaun; + int fcn, NT; + + trace(3, "encode_type1020: sync=%d\n", sync); + + if (satsys(rtcm->ephsat, &prn) != SYS_GLO) return 0; + geph = rtcm->nav.geph + prn - 1; + if (geph->sat != rtcm->ephsat) return 0; + fcn = geph->frq + 7; + + /* time of frame within day (utc(su) + 3 hr) */ + time = timeadd(gpst2utc(geph->tof), 10800.0); + time2epoch(time, ep); + tk_h = (int)ep[3]; + tk_m = (int)ep[4]; + tk_s = ROUND(ep[5] / 30.0); + + /* # of days since jan 1 in leap year */ + ep[0] = floor(ep[0] / 4.0) * 4.0; + ep[1] = ep[2] = 1.0; + ep[3] = ep[4] = ep[5] = 0.0; + NT = (int)floor(timediff(time, epoch2time(ep)) / 86400. + 1.0); + + /* index of time interval within day (utc(su) + 3 hr) */ + time = timeadd(gpst2utc(geph->toe), 10800.0); + time2epoch(time, ep); + tb = ROUND((ep[3] * 3600.0 + ep[4] * 60.0 + ep[5]) / 900.0); + + for (j = 0; j < 3; j++) { + pos[j] = ROUND(geph->pos[j] / P2_11 / 1E3); + vel[j] = ROUND(geph->vel[j] / P2_20 / 1E3); + acc[j] = ROUND(geph->acc[j] / P2_30 / 1E3); + } + gamn = ROUND(geph->gamn / P2_40); + taun = ROUND(geph->taun / P2_30); + dtaun = ROUND(geph->dtaun / P2_30); + int Bn = (geph->svh >> 0) & 1; + int Cn = (geph->svh >> 1) & 1; + int Cn_a = (geph->svh >> 2) & 1; + int ln = (geph->svh >> 2) & 1; + int M = (geph->flags >> 7) & 3; + int P4 = (geph->flags >> 6) & 1; + int P3 = (geph->flags >> 5) & 1; + int P2 = (geph->flags >> 4) & 1; + int P1 = (geph->flags >> 2) & 3; + int P = geph->flags & 3; + + setbitu(rtcm->buff, i, 12, 1020); + i += 12; + setbitu(rtcm->buff, i, 6, prn); + i += 6; + setbitu(rtcm->buff, i, 5, fcn); + i += 5; + setbitu(rtcm->buff, i, 1, Cn); + i += 1; + setbitu(rtcm->buff, i, 1, Cn_a); + i += 1; + setbitu(rtcm->buff, i, 2, P1); + i += 2; + setbitu(rtcm->buff, i, 5, tk_h); + i += 5; + setbitu(rtcm->buff, i, 6, tk_m); + i += 6; + setbitu(rtcm->buff, i, 1, tk_s); + i += 1; + setbitu(rtcm->buff, i, 1, Bn); + i += 1; + setbitu(rtcm->buff, i, 1, P2); + i += 1; + setbitu(rtcm->buff, i, 7, tb); + i += 7; + setbitg(rtcm->buff, i, 24, vel[0]); + i += 24; + setbitg(rtcm->buff, i, 27, pos[0]); + i += 27; + setbitg(rtcm->buff, i, 5, acc[0]); + i += 5; + setbitg(rtcm->buff, i, 24, vel[1]); + i += 24; + setbitg(rtcm->buff, i, 27, pos[1]); + i += 27; + setbitg(rtcm->buff, i, 5, acc[1]); + i += 5; + setbitg(rtcm->buff, i, 24, vel[2]); + i += 24; + setbitg(rtcm->buff, i, 27, pos[2]); + i += 27; + setbitg(rtcm->buff, i, 5, acc[2]); + i += 5; + setbitu(rtcm->buff, i, 1, P3); + i += 1; + setbitg(rtcm->buff, i, 11, gamn); + i += 11; + setbitu(rtcm->buff, i, 2, P); + i += 2; + setbitu(rtcm->buff, i, 1, ln); + i += 1; + setbitg(rtcm->buff, i, 22, taun); + i += 22; + setbitg(rtcm->buff, i, 5, dtaun); + i += 5; + setbitu(rtcm->buff, i, 5, geph->age); + i += 5; /* En */ + setbitu(rtcm->buff, i, 1, P4); + i += 1; + setbitu(rtcm->buff, i, 4, geph->sva); + i += 4; + setbitu(rtcm->buff, i, 11, NT); + i += 11; + setbitu(rtcm->buff, i, 2, M); + i += 2; + setbitu(rtcm->buff, i, 1, 0); + i += 1; /* flag for additional data */ + setbitu(rtcm->buff, i, 11, 0); + i += 11; /* NA */ + setbitu(rtcm->buff, i, 32, 0); + i += 32; /* tauc */ + setbitu(rtcm->buff, i, 5, 0); + i += 5; /* N4 */ + setbitu(rtcm->buff, i, 22, 0); + i += 22; /* taugps */ + setbitu(rtcm->buff, i, 1, 0); + i += 1; /* ln (fifth string) */ + setbitu(rtcm->buff, i, 7, 0); + i += 7; + rtcm->nbit = i; + return 1; } /* encode type 1033: receiver and antenna descriptor -------------------------*/ -static int encode_type1033(rtcm_t *rtcm, int sync) -{ - int i=24,j,antsetup=rtcm->sta.antsetup; - int n=MIN((int)strlen(rtcm->sta.antdes ),31); - int m=MIN((int)strlen(rtcm->sta.antsno ),31); - int I=MIN((int)strlen(rtcm->sta.rectype),31); - int J=MIN((int)strlen(rtcm->sta.recver ),31); - int K=MIN((int)strlen(rtcm->sta.recsno ),31); - - trace(3,"encode_type1033: sync=%d\n",sync); - - setbitu(rtcm->buff,i,12,1033 ); i+=12; - setbitu(rtcm->buff,i,12,rtcm->staid); i+=12; - - setbitu(rtcm->buff,i,8,n); i+= 8; - for (j=0;jbuff,i,8,rtcm->sta.antdes[j]); i+=8; - } - setbitu(rtcm->buff,i,8,antsetup); i+= 8; - - setbitu(rtcm->buff,i,8,m); i+= 8; - for (j=0;jbuff,i,8,rtcm->sta.antsno[j]); i+=8; - } - setbitu(rtcm->buff,i,8,I); i+= 8; - for (j=0;jbuff,i,8,rtcm->sta.rectype[j]); i+=8; - } - setbitu(rtcm->buff,i,8,J); i+= 8; - for (j=0;jbuff,i,8,rtcm->sta.recver[j]); i+=8; - } - setbitu(rtcm->buff,i,8,K); i+= 8; - for (j=0;jbuff,i,8,rtcm->sta.recsno[j]); i+=8; - } - rtcm->nbit=i; - return 1; +static int encode_type1033(rtcm_t *rtcm, int sync) { + int i = 24, j, antsetup = rtcm->sta.antsetup; + int n = MIN((int)strlen(rtcm->sta.antdes), 31); + int m = MIN((int)strlen(rtcm->sta.antsno), 31); + int I = MIN((int)strlen(rtcm->sta.rectype), 31); + int J = MIN((int)strlen(rtcm->sta.recver), 31); + int K = MIN((int)strlen(rtcm->sta.recsno), 31); + + trace(3, "encode_type1033: sync=%d\n", sync); + + setbitu(rtcm->buff, i, 12, 1033); + i += 12; + setbitu(rtcm->buff, i, 12, rtcm->staid); + i += 12; + + setbitu(rtcm->buff, i, 8, n); + i += 8; + for (j = 0; j < n; j++) { + setbitu(rtcm->buff, i, 8, rtcm->sta.antdes[j]); + i += 8; + } + setbitu(rtcm->buff, i, 8, antsetup); + i += 8; + + setbitu(rtcm->buff, i, 8, m); + i += 8; + for (j = 0; j < m; j++) { + setbitu(rtcm->buff, i, 8, rtcm->sta.antsno[j]); + i += 8; + } + setbitu(rtcm->buff, i, 8, I); + i += 8; + for (j = 0; j < I; j++) { + setbitu(rtcm->buff, i, 8, rtcm->sta.rectype[j]); + i += 8; + } + setbitu(rtcm->buff, i, 8, J); + i += 8; + for (j = 0; j < J; j++) { + setbitu(rtcm->buff, i, 8, rtcm->sta.recver[j]); + i += 8; + } + setbitu(rtcm->buff, i, 8, K); + i += 8; + for (j = 0; j < K; j++) { + setbitu(rtcm->buff, i, 8, rtcm->sta.recsno[j]); + i += 8; + } + rtcm->nbit = i; + return 1; } /* encode type 1041: NavIC/IRNSS ephemerides ---------------------------------*/ -static int encode_type1041(rtcm_t *rtcm, int sync) -{ - eph_t *eph; - uint32_t sqrtA,e; - int i=24,prn,week,toe,toc,i0,OMG0,omg,M0,deln,idot,OMGd,crs,crc; - int cus,cuc,cis,cic,af0,af1,af2,tgd; - - trace(3,"encode_type1041: sync=%d\n",sync); - - if (satsys(rtcm->ephsat,&prn)!=SYS_IRN) return 0; - eph=rtcm->nav.eph+rtcm->ephsat-1; - if (eph->sat!=rtcm->ephsat) return 0; - week=eph->week%1024; - toe =ROUND(eph->toes/16.0); - toc =ROUND(time2gpst(eph->toc,NULL)/16.0); - sqrtA=ROUND_U(sqrt(eph->A)/P2_19); - e =ROUND_U(eph->e/P2_33); - i0 =ROUND(eph->i0 /P2_31/SC2RAD); - OMG0 =ROUND(eph->OMG0/P2_31/SC2RAD); - omg =ROUND(eph->omg /P2_31/SC2RAD); - M0 =ROUND(eph->M0 /P2_31/SC2RAD); - deln =ROUND(eph->deln/P2_41/SC2RAD); - idot =ROUND(eph->idot/P2_43/SC2RAD); - OMGd =ROUND(eph->OMGd/P2_41/SC2RAD); - crs =ROUND(eph->crs/0.0625); - crc =ROUND(eph->crc/0.0625); - cus =ROUND(eph->cus/P2_28); - cuc =ROUND(eph->cuc/P2_28); - cis =ROUND(eph->cis/P2_28); - cic =ROUND(eph->cic/P2_28); - af0 =ROUND(eph->f0 /P2_31); - af1 =ROUND(eph->f1 /P2_43); - af2 =ROUND(eph->f2 /P2_55); - tgd =ROUND(eph->tgd[0]/P2_31); - - setbitu(rtcm->buff,i,12,1041 ); i+=12; - setbitu(rtcm->buff,i, 6,prn ); i+= 6; - setbitu(rtcm->buff,i,10,week ); i+=10; - setbits(rtcm->buff,i,22,af0 ); i+=22; - setbits(rtcm->buff,i,16,af1 ); i+=16; - setbits(rtcm->buff,i, 8,af2 ); i+= 8; - setbitu(rtcm->buff,i, 4,eph->sva ); i+= 4; - setbitu(rtcm->buff,i,16,toc ); i+=16; - setbits(rtcm->buff,i, 8,tgd ); i+= 8; - setbits(rtcm->buff,i,22,deln ); i+=22; - setbitu(rtcm->buff,i, 8,eph->iode); i+= 8+10; /* IODEC */ - setbitu(rtcm->buff,i, 2,eph->svh ); i+= 2; /* L5+Sflag */ - setbits(rtcm->buff,i,15,cuc ); i+=15; - setbits(rtcm->buff,i,15,cus ); i+=15; - setbits(rtcm->buff,i,15,cic ); i+=15; - setbits(rtcm->buff,i,15,cis ); i+=15; - setbits(rtcm->buff,i,15,crc ); i+=15; - setbits(rtcm->buff,i,15,crs ); i+=15; - setbits(rtcm->buff,i,14,idot ); i+=14; - setbits(rtcm->buff,i,32,M0 ); i+=32; - setbitu(rtcm->buff,i,16,toe ); i+=16; - setbitu(rtcm->buff,i,32,e ); i+=32; - setbitu(rtcm->buff,i,32,sqrtA ); i+=32; - setbits(rtcm->buff,i,32,OMG0 ); i+=32; - setbits(rtcm->buff,i,32,omg ); i+=32; - setbits(rtcm->buff,i,22,OMGd ); i+=22; - setbits(rtcm->buff,i,32,i0 ); i+=32+4; - rtcm->nbit=i; - return 1; +static int encode_type1041(rtcm_t *rtcm, int sync) { + eph_t *eph; + uint32_t sqrtA, e; + int i = 24, prn, week, toe, toc, i0, OMG0, omg, M0, deln, idot, OMGd, crs, crc; + int cus, cuc, cis, cic, af0, af1, af2, tgd; + + trace(3, "encode_type1041: sync=%d\n", sync); + + if (satsys(rtcm->ephsat, &prn) != SYS_IRN) return 0; + eph = rtcm->nav.eph + rtcm->ephsat - 1; + if (eph->sat != rtcm->ephsat) return 0; + week = eph->week % 1024; + toe = ROUND(eph->toes / 16.0); + toc = ROUND(time2gpst(eph->toc, NULL) / 16.0); + sqrtA = ROUND_U(sqrt(eph->A) / P2_19); + e = ROUND_U(eph->e / P2_33); + i0 = ROUND(eph->i0 / P2_31 / SC2RAD); + OMG0 = ROUND(eph->OMG0 / P2_31 / SC2RAD); + omg = ROUND(eph->omg / P2_31 / SC2RAD); + M0 = ROUND(eph->M0 / P2_31 / SC2RAD); + deln = ROUND(eph->deln / P2_41 / SC2RAD); + idot = ROUND(eph->idot / P2_43 / SC2RAD); + OMGd = ROUND(eph->OMGd / P2_41 / SC2RAD); + crs = ROUND(eph->crs / 0.0625); + crc = ROUND(eph->crc / 0.0625); + cus = ROUND(eph->cus / P2_28); + cuc = ROUND(eph->cuc / P2_28); + cis = ROUND(eph->cis / P2_28); + cic = ROUND(eph->cic / P2_28); + af0 = ROUND(eph->f0 / P2_31); + af1 = ROUND(eph->f1 / P2_43); + af2 = ROUND(eph->f2 / P2_55); + tgd = ROUND(eph->tgd[0] / P2_31); + + setbitu(rtcm->buff, i, 12, 1041); + i += 12; + setbitu(rtcm->buff, i, 6, prn); + i += 6; + setbitu(rtcm->buff, i, 10, week); + i += 10; + setbits(rtcm->buff, i, 22, af0); + i += 22; + setbits(rtcm->buff, i, 16, af1); + i += 16; + setbits(rtcm->buff, i, 8, af2); + i += 8; + setbitu(rtcm->buff, i, 4, eph->sva); + i += 4; + setbitu(rtcm->buff, i, 16, toc); + i += 16; + setbits(rtcm->buff, i, 8, tgd); + i += 8; + setbits(rtcm->buff, i, 22, deln); + i += 22; + setbitu(rtcm->buff, i, 8, eph->iode); + i += 8 + 10; /* IODEC */ + setbitu(rtcm->buff, i, 2, eph->svh); + i += 2; /* L5+Sflag */ + setbits(rtcm->buff, i, 15, cuc); + i += 15; + setbits(rtcm->buff, i, 15, cus); + i += 15; + setbits(rtcm->buff, i, 15, cic); + i += 15; + setbits(rtcm->buff, i, 15, cis); + i += 15; + setbits(rtcm->buff, i, 15, crc); + i += 15; + setbits(rtcm->buff, i, 15, crs); + i += 15; + setbits(rtcm->buff, i, 14, idot); + i += 14; + setbits(rtcm->buff, i, 32, M0); + i += 32; + setbitu(rtcm->buff, i, 16, toe); + i += 16; + setbitu(rtcm->buff, i, 32, e); + i += 32; + setbitu(rtcm->buff, i, 32, sqrtA); + i += 32; + setbits(rtcm->buff, i, 32, OMG0); + i += 32; + setbits(rtcm->buff, i, 32, omg); + i += 32; + setbits(rtcm->buff, i, 22, OMGd); + i += 22; + setbits(rtcm->buff, i, 32, i0); + i += 32 + 4; + rtcm->nbit = i; + return 1; } /* encode type 1044: QZSS ephemerides ----------------------------------------*/ -static int encode_type1044(rtcm_t *rtcm, int sync) -{ - eph_t *eph; - uint32_t sqrtA,e; - int i=24,prn,week,toe,toc,i0,OMG0,omg,M0,deln,idot,OMGd,crs,crc; - int cus,cuc,cis,cic,af0,af1,af2,tgd; - - trace(3,"encode_type1044: sync=%d\n",sync); - - if (satsys(rtcm->ephsat,&prn)!=SYS_QZS) return 0; - eph=rtcm->nav.eph+rtcm->ephsat-1; - if (eph->sat!=rtcm->ephsat) return 0; - week=eph->week%1024; - toe =ROUND(eph->toes/16.0); - toc =ROUND(time2gpst(eph->toc,NULL)/16.0); - sqrtA=ROUND_U(sqrt(eph->A)/P2_19); - e =ROUND_U(eph->e/P2_33); - i0 =ROUND(eph->i0 /P2_31/SC2RAD); - OMG0 =ROUND(eph->OMG0/P2_31/SC2RAD); - omg =ROUND(eph->omg /P2_31/SC2RAD); - M0 =ROUND(eph->M0 /P2_31/SC2RAD); - deln =ROUND(eph->deln/P2_43/SC2RAD); - idot =ROUND(eph->idot/P2_43/SC2RAD); - OMGd =ROUND(eph->OMGd/P2_43/SC2RAD); - crs =ROUND(eph->crs/P2_5 ); - crc =ROUND(eph->crc/P2_5 ); - cus =ROUND(eph->cus/P2_29); - cuc =ROUND(eph->cuc/P2_29); - cis =ROUND(eph->cis/P2_29); - cic =ROUND(eph->cic/P2_29); - af0 =ROUND(eph->f0 /P2_31); - af1 =ROUND(eph->f1 /P2_43); - af2 =ROUND(eph->f2 /P2_55); - tgd =ROUND(eph->tgd[0]/P2_31); - - setbitu(rtcm->buff,i,12,1044 ); i+=12; - setbitu(rtcm->buff,i, 4,prn-192 ); i+= 4; - setbitu(rtcm->buff,i,16,toc ); i+=16; - setbits(rtcm->buff,i, 8,af2 ); i+= 8; - setbits(rtcm->buff,i,16,af1 ); i+=16; - setbits(rtcm->buff,i,22,af0 ); i+=22; - setbitu(rtcm->buff,i, 8,eph->iode); i+= 8; - setbits(rtcm->buff,i,16,crs ); i+=16; - setbits(rtcm->buff,i,16,deln ); i+=16; - setbits(rtcm->buff,i,32,M0 ); i+=32; - setbits(rtcm->buff,i,16,cuc ); i+=16; - setbitu(rtcm->buff,i,32,e ); i+=32; - setbits(rtcm->buff,i,16,cus ); i+=16; - setbitu(rtcm->buff,i,32,sqrtA ); i+=32; - setbitu(rtcm->buff,i,16,toe ); i+=16; - setbits(rtcm->buff,i,16,cic ); i+=16; - setbits(rtcm->buff,i,32,OMG0 ); i+=32; - setbits(rtcm->buff,i,16,cis ); i+=16; - setbits(rtcm->buff,i,32,i0 ); i+=32; - setbits(rtcm->buff,i,16,crc ); i+=16; - setbits(rtcm->buff,i,32,omg ); i+=32; - setbits(rtcm->buff,i,24,OMGd ); i+=24; - setbits(rtcm->buff,i,14,idot ); i+=14; - setbitu(rtcm->buff,i, 2,eph->code); i+= 2; - setbitu(rtcm->buff,i,10,week ); i+=10; - setbitu(rtcm->buff,i, 4,eph->sva ); i+= 4; - setbitu(rtcm->buff,i, 6,eph->svh ); i+= 6; - setbits(rtcm->buff,i, 8,tgd ); i+= 8; - setbitu(rtcm->buff,i,10,eph->iodc); i+=10; - setbitu(rtcm->buff,i, 1,eph->fit>2?1:0); i+=1; - rtcm->nbit=i; - return 1; +static int encode_type1044(rtcm_t *rtcm, int sync) { + eph_t *eph; + uint32_t sqrtA, e; + int i = 24, prn, week, toe, toc, i0, OMG0, omg, M0, deln, idot, OMGd, crs, crc; + int cus, cuc, cis, cic, af0, af1, af2, tgd; + + trace(3, "encode_type1044: sync=%d\n", sync); + + if (satsys(rtcm->ephsat, &prn) != SYS_QZS) return 0; + eph = rtcm->nav.eph + rtcm->ephsat - 1; + if (eph->sat != rtcm->ephsat) return 0; + week = eph->week % 1024; + toe = ROUND(eph->toes / 16.0); + toc = ROUND(time2gpst(eph->toc, NULL) / 16.0); + sqrtA = ROUND_U(sqrt(eph->A) / P2_19); + e = ROUND_U(eph->e / P2_33); + i0 = ROUND(eph->i0 / P2_31 / SC2RAD); + OMG0 = ROUND(eph->OMG0 / P2_31 / SC2RAD); + omg = ROUND(eph->omg / P2_31 / SC2RAD); + M0 = ROUND(eph->M0 / P2_31 / SC2RAD); + deln = ROUND(eph->deln / P2_43 / SC2RAD); + idot = ROUND(eph->idot / P2_43 / SC2RAD); + OMGd = ROUND(eph->OMGd / P2_43 / SC2RAD); + crs = ROUND(eph->crs / P2_5); + crc = ROUND(eph->crc / P2_5); + cus = ROUND(eph->cus / P2_29); + cuc = ROUND(eph->cuc / P2_29); + cis = ROUND(eph->cis / P2_29); + cic = ROUND(eph->cic / P2_29); + af0 = ROUND(eph->f0 / P2_31); + af1 = ROUND(eph->f1 / P2_43); + af2 = ROUND(eph->f2 / P2_55); + tgd = ROUND(eph->tgd[0] / P2_31); + + setbitu(rtcm->buff, i, 12, 1044); + i += 12; + setbitu(rtcm->buff, i, 4, prn - 192); + i += 4; + setbitu(rtcm->buff, i, 16, toc); + i += 16; + setbits(rtcm->buff, i, 8, af2); + i += 8; + setbits(rtcm->buff, i, 16, af1); + i += 16; + setbits(rtcm->buff, i, 22, af0); + i += 22; + setbitu(rtcm->buff, i, 8, eph->iode); + i += 8; + setbits(rtcm->buff, i, 16, crs); + i += 16; + setbits(rtcm->buff, i, 16, deln); + i += 16; + setbits(rtcm->buff, i, 32, M0); + i += 32; + setbits(rtcm->buff, i, 16, cuc); + i += 16; + setbitu(rtcm->buff, i, 32, e); + i += 32; + setbits(rtcm->buff, i, 16, cus); + i += 16; + setbitu(rtcm->buff, i, 32, sqrtA); + i += 32; + setbitu(rtcm->buff, i, 16, toe); + i += 16; + setbits(rtcm->buff, i, 16, cic); + i += 16; + setbits(rtcm->buff, i, 32, OMG0); + i += 32; + setbits(rtcm->buff, i, 16, cis); + i += 16; + setbits(rtcm->buff, i, 32, i0); + i += 32; + setbits(rtcm->buff, i, 16, crc); + i += 16; + setbits(rtcm->buff, i, 32, omg); + i += 32; + setbits(rtcm->buff, i, 24, OMGd); + i += 24; + setbits(rtcm->buff, i, 14, idot); + i += 14; + setbitu(rtcm->buff, i, 2, eph->code); + i += 2; + setbitu(rtcm->buff, i, 10, week); + i += 10; + setbitu(rtcm->buff, i, 4, eph->sva); + i += 4; + setbitu(rtcm->buff, i, 6, eph->svh); + i += 6; + setbits(rtcm->buff, i, 8, tgd); + i += 8; + setbitu(rtcm->buff, i, 10, eph->iodc); + i += 10; + setbitu(rtcm->buff, i, 1, eph->fit > 2 ? 1 : 0); + i += 1; + rtcm->nbit = i; + return 1; } /* encode type 1045: Galileo F/NAV satellite ephemerides ---------------------*/ -static int encode_type1045(rtcm_t *rtcm, int sync) -{ - eph_t *eph; - uint32_t sqrtA,e; - int i=24,prn,week,toe,toc,i0,OMG0,omg,M0,deln,idot,OMGd,crs,crc; - int cus,cuc,cis,cic,af0,af1,af2,bgd1,bgd2,oshs,osdvs; - - trace(3,"encode_type1045: sync=%d\n",sync); - - if (satsys(rtcm->ephsat,&prn)!=SYS_GAL) return 0; - eph=rtcm->nav.eph+rtcm->ephsat-1+MAXSAT; /* F/NAV */ - if (eph->sat!=rtcm->ephsat) return 0; - week=(eph->week-1024)%4096; /* gst-week = gal-week - 1024 */ - toe =ROUND(eph->toes/60.0); - toc =ROUND(time2gpst(eph->toc,NULL)/60.0); - sqrtA=ROUND_U(sqrt(eph->A)/P2_19); - e =ROUND_U(eph->e/P2_33); - i0 =ROUND(eph->i0 /P2_31/SC2RAD); - OMG0 =ROUND(eph->OMG0/P2_31/SC2RAD); - omg =ROUND(eph->omg /P2_31/SC2RAD); - M0 =ROUND(eph->M0 /P2_31/SC2RAD); - deln =ROUND(eph->deln/P2_43/SC2RAD); - idot =ROUND(eph->idot/P2_43/SC2RAD); - OMGd =ROUND(eph->OMGd/P2_43/SC2RAD); - crs =ROUND(eph->crs/P2_5 ); - crc =ROUND(eph->crc/P2_5 ); - cus =ROUND(eph->cus/P2_29); - cuc =ROUND(eph->cuc/P2_29); - cis =ROUND(eph->cis/P2_29); - cic =ROUND(eph->cic/P2_29); - af0 =ROUND(eph->f0 /P2_34); - af1 =ROUND(eph->f1 /P2_46); - af2 =ROUND(eph->f2 /P2_59); - bgd1 =ROUND(eph->tgd[0]/P2_32); /* E5a/E1 */ - bgd2 =ROUND(eph->tgd[1]/P2_32); /* E5b/E1 */ - oshs =(eph->svh>>4)&3; /* E5a SVH */ - osdvs=(eph->svh>>3)&1; /* E5a DVS */ - setbitu(rtcm->buff,i,12,1045 ); i+=12; - setbitu(rtcm->buff,i, 6,prn ); i+= 6; - setbitu(rtcm->buff,i,12,week ); i+=12; - setbitu(rtcm->buff,i,10,eph->iode); i+=10; - setbitu(rtcm->buff,i, 8,eph->sva ); i+= 8; - setbits(rtcm->buff,i,14,idot ); i+=14; - setbitu(rtcm->buff,i,14,toc ); i+=14; - setbits(rtcm->buff,i, 6,af2 ); i+= 6; - setbits(rtcm->buff,i,21,af1 ); i+=21; - setbits(rtcm->buff,i,31,af0 ); i+=31; - setbits(rtcm->buff,i,16,crs ); i+=16; - setbits(rtcm->buff,i,16,deln ); i+=16; - setbits(rtcm->buff,i,32,M0 ); i+=32; - setbits(rtcm->buff,i,16,cuc ); i+=16; - setbitu(rtcm->buff,i,32,e ); i+=32; - setbits(rtcm->buff,i,16,cus ); i+=16; - setbitu(rtcm->buff,i,32,sqrtA ); i+=32; - setbitu(rtcm->buff,i,14,toe ); i+=14; - setbits(rtcm->buff,i,16,cic ); i+=16; - setbits(rtcm->buff,i,32,OMG0 ); i+=32; - setbits(rtcm->buff,i,16,cis ); i+=16; - setbits(rtcm->buff,i,32,i0 ); i+=32; - setbits(rtcm->buff,i,16,crc ); i+=16; - setbits(rtcm->buff,i,32,omg ); i+=32; - setbits(rtcm->buff,i,24,OMGd ); i+=24; - setbits(rtcm->buff,i,10,bgd1 ); i+=10; - setbitu(rtcm->buff,i, 2,oshs ); i+= 2; /* E5a SVH */ - setbitu(rtcm->buff,i, 1,osdvs ); i+= 1; /* E5a DVS */ - setbitu(rtcm->buff,i, 7,0 ); i+= 7; /* reserved */ - rtcm->nbit=i; - return 1; +static int encode_type1045(rtcm_t *rtcm, int sync) { + eph_t *eph; + uint32_t sqrtA, e; + int i = 24, prn, week, toe, toc, i0, OMG0, omg, M0, deln, idot, OMGd, crs, crc; + int cus, cuc, cis, cic, af0, af1, af2, bgd1, bgd2, oshs, osdvs; + + trace(3, "encode_type1045: sync=%d\n", sync); + + if (satsys(rtcm->ephsat, &prn) != SYS_GAL) return 0; + eph = rtcm->nav.eph + rtcm->ephsat - 1 + MAXSAT; /* F/NAV */ + if (eph->sat != rtcm->ephsat) return 0; + week = (eph->week - 1024) % 4096; /* gst-week = gal-week - 1024 */ + toe = ROUND(eph->toes / 60.0); + toc = ROUND(time2gpst(eph->toc, NULL) / 60.0); + sqrtA = ROUND_U(sqrt(eph->A) / P2_19); + e = ROUND_U(eph->e / P2_33); + i0 = ROUND(eph->i0 / P2_31 / SC2RAD); + OMG0 = ROUND(eph->OMG0 / P2_31 / SC2RAD); + omg = ROUND(eph->omg / P2_31 / SC2RAD); + M0 = ROUND(eph->M0 / P2_31 / SC2RAD); + deln = ROUND(eph->deln / P2_43 / SC2RAD); + idot = ROUND(eph->idot / P2_43 / SC2RAD); + OMGd = ROUND(eph->OMGd / P2_43 / SC2RAD); + crs = ROUND(eph->crs / P2_5); + crc = ROUND(eph->crc / P2_5); + cus = ROUND(eph->cus / P2_29); + cuc = ROUND(eph->cuc / P2_29); + cis = ROUND(eph->cis / P2_29); + cic = ROUND(eph->cic / P2_29); + af0 = ROUND(eph->f0 / P2_34); + af1 = ROUND(eph->f1 / P2_46); + af2 = ROUND(eph->f2 / P2_59); + bgd1 = ROUND(eph->tgd[0] / P2_32); /* E5a/E1 */ + bgd2 = ROUND(eph->tgd[1] / P2_32); /* E5b/E1 */ + oshs = (eph->svh >> 4) & 3; /* E5a SVH */ + osdvs = (eph->svh >> 3) & 1; /* E5a DVS */ + setbitu(rtcm->buff, i, 12, 1045); + i += 12; + setbitu(rtcm->buff, i, 6, prn); + i += 6; + setbitu(rtcm->buff, i, 12, week); + i += 12; + setbitu(rtcm->buff, i, 10, eph->iode); + i += 10; + setbitu(rtcm->buff, i, 8, eph->sva); + i += 8; + setbits(rtcm->buff, i, 14, idot); + i += 14; + setbitu(rtcm->buff, i, 14, toc); + i += 14; + setbits(rtcm->buff, i, 6, af2); + i += 6; + setbits(rtcm->buff, i, 21, af1); + i += 21; + setbits(rtcm->buff, i, 31, af0); + i += 31; + setbits(rtcm->buff, i, 16, crs); + i += 16; + setbits(rtcm->buff, i, 16, deln); + i += 16; + setbits(rtcm->buff, i, 32, M0); + i += 32; + setbits(rtcm->buff, i, 16, cuc); + i += 16; + setbitu(rtcm->buff, i, 32, e); + i += 32; + setbits(rtcm->buff, i, 16, cus); + i += 16; + setbitu(rtcm->buff, i, 32, sqrtA); + i += 32; + setbitu(rtcm->buff, i, 14, toe); + i += 14; + setbits(rtcm->buff, i, 16, cic); + i += 16; + setbits(rtcm->buff, i, 32, OMG0); + i += 32; + setbits(rtcm->buff, i, 16, cis); + i += 16; + setbits(rtcm->buff, i, 32, i0); + i += 32; + setbits(rtcm->buff, i, 16, crc); + i += 16; + setbits(rtcm->buff, i, 32, omg); + i += 32; + setbits(rtcm->buff, i, 24, OMGd); + i += 24; + setbits(rtcm->buff, i, 10, bgd1); + i += 10; + setbitu(rtcm->buff, i, 2, oshs); + i += 2; /* E5a SVH */ + setbitu(rtcm->buff, i, 1, osdvs); + i += 1; /* E5a DVS */ + setbitu(rtcm->buff, i, 7, 0); + i += 7; /* reserved */ + rtcm->nbit = i; + return 1; } /* encode type 1046: Galileo I/NAV satellite ephemerides ---------------------*/ -static int encode_type1046(rtcm_t *rtcm, int sync) -{ - eph_t *eph; - uint32_t sqrtA,e; - int i=24,prn,week,toe,toc,i0,OMG0,omg,M0,deln,idot,OMGd,crs,crc; - int cus,cuc,cis,cic,af0,af1,af2,bgd1,bgd2,oshs1,osdvs1,oshs2,osdvs2; - - trace(3,"encode_type1046: sync=%d\n",sync); - - if (satsys(rtcm->ephsat,&prn)!=SYS_GAL) return 0; - eph=rtcm->nav.eph+rtcm->ephsat-1; /* I/NAV */ - if (eph->sat!=rtcm->ephsat) return 0; - week=(eph->week-1024)%4096; /* gst-week = gal-week - 1024 */ - toe =ROUND(eph->toes/60.0); - toc =ROUND(time2gpst(eph->toc,NULL)/60.0); - sqrtA=ROUND_U(sqrt(eph->A)/P2_19); - e =ROUND_U(eph->e/P2_33); - i0 =ROUND(eph->i0 /P2_31/SC2RAD); - OMG0 =ROUND(eph->OMG0/P2_31/SC2RAD); - omg =ROUND(eph->omg /P2_31/SC2RAD); - M0 =ROUND(eph->M0 /P2_31/SC2RAD); - deln =ROUND(eph->deln/P2_43/SC2RAD); - idot =ROUND(eph->idot/P2_43/SC2RAD); - OMGd =ROUND(eph->OMGd/P2_43/SC2RAD); - crs =ROUND(eph->crs/P2_5 ); - crc =ROUND(eph->crc/P2_5 ); - cus =ROUND(eph->cus/P2_29); - cuc =ROUND(eph->cuc/P2_29); - cis =ROUND(eph->cis/P2_29); - cic =ROUND(eph->cic/P2_29); - af0 =ROUND(eph->f0 /P2_34); - af1 =ROUND(eph->f1 /P2_46); - af2 =ROUND(eph->f2 /P2_59); - bgd1 =ROUND(eph->tgd[0]/P2_32); /* E5a/E1 */ - bgd2 =ROUND(eph->tgd[1]/P2_32); /* E5b/E1 */ - oshs1 =(eph->svh>>7)&3; /* E5b SVH */ - osdvs1=(eph->svh>>6)&1; /* E5b DVS */ - oshs2 =(eph->svh>>1)&3; /* E1 SVH */ - osdvs2=(eph->svh>>0)&1; /* E1 DVS */ - setbitu(rtcm->buff,i,12,1046 ); i+=12; - setbitu(rtcm->buff,i, 6,prn ); i+= 6; - setbitu(rtcm->buff,i,12,week ); i+=12; - setbitu(rtcm->buff,i,10,eph->iode); i+=10; - setbitu(rtcm->buff,i, 8,eph->sva ); i+= 8; - setbits(rtcm->buff,i,14,idot ); i+=14; - setbitu(rtcm->buff,i,14,toc ); i+=14; - setbits(rtcm->buff,i, 6,af2 ); i+= 6; - setbits(rtcm->buff,i,21,af1 ); i+=21; - setbits(rtcm->buff,i,31,af0 ); i+=31; - setbits(rtcm->buff,i,16,crs ); i+=16; - setbits(rtcm->buff,i,16,deln ); i+=16; - setbits(rtcm->buff,i,32,M0 ); i+=32; - setbits(rtcm->buff,i,16,cuc ); i+=16; - setbitu(rtcm->buff,i,32,e ); i+=32; - setbits(rtcm->buff,i,16,cus ); i+=16; - setbitu(rtcm->buff,i,32,sqrtA ); i+=32; - setbitu(rtcm->buff,i,14,toe ); i+=14; - setbits(rtcm->buff,i,16,cic ); i+=16; - setbits(rtcm->buff,i,32,OMG0 ); i+=32; - setbits(rtcm->buff,i,16,cis ); i+=16; - setbits(rtcm->buff,i,32,i0 ); i+=32; - setbits(rtcm->buff,i,16,crc ); i+=16; - setbits(rtcm->buff,i,32,omg ); i+=32; - setbits(rtcm->buff,i,24,OMGd ); i+=24; - setbits(rtcm->buff,i,10,bgd1 ); i+=10; - setbits(rtcm->buff,i,10,bgd2 ); i+=10; - setbitu(rtcm->buff,i, 2,oshs1 ); i+= 2; /* E5b SVH */ - setbitu(rtcm->buff,i, 1,osdvs1 ); i+= 1; /* E5b DVS */ - setbitu(rtcm->buff,i, 2,oshs2 ); i+= 2; /* E1 SVH */ - setbitu(rtcm->buff,i, 1,osdvs2 ); i+= 1; /* E1 DVS */ - rtcm->nbit=i; - return 1; +static int encode_type1046(rtcm_t *rtcm, int sync) { + eph_t *eph; + uint32_t sqrtA, e; + int i = 24, prn, week, toe, toc, i0, OMG0, omg, M0, deln, idot, OMGd, crs, crc; + int cus, cuc, cis, cic, af0, af1, af2, bgd1, bgd2, oshs1, osdvs1, oshs2, osdvs2; + + trace(3, "encode_type1046: sync=%d\n", sync); + + if (satsys(rtcm->ephsat, &prn) != SYS_GAL) return 0; + eph = rtcm->nav.eph + rtcm->ephsat - 1; /* I/NAV */ + if (eph->sat != rtcm->ephsat) return 0; + week = (eph->week - 1024) % 4096; /* gst-week = gal-week - 1024 */ + toe = ROUND(eph->toes / 60.0); + toc = ROUND(time2gpst(eph->toc, NULL) / 60.0); + sqrtA = ROUND_U(sqrt(eph->A) / P2_19); + e = ROUND_U(eph->e / P2_33); + i0 = ROUND(eph->i0 / P2_31 / SC2RAD); + OMG0 = ROUND(eph->OMG0 / P2_31 / SC2RAD); + omg = ROUND(eph->omg / P2_31 / SC2RAD); + M0 = ROUND(eph->M0 / P2_31 / SC2RAD); + deln = ROUND(eph->deln / P2_43 / SC2RAD); + idot = ROUND(eph->idot / P2_43 / SC2RAD); + OMGd = ROUND(eph->OMGd / P2_43 / SC2RAD); + crs = ROUND(eph->crs / P2_5); + crc = ROUND(eph->crc / P2_5); + cus = ROUND(eph->cus / P2_29); + cuc = ROUND(eph->cuc / P2_29); + cis = ROUND(eph->cis / P2_29); + cic = ROUND(eph->cic / P2_29); + af0 = ROUND(eph->f0 / P2_34); + af1 = ROUND(eph->f1 / P2_46); + af2 = ROUND(eph->f2 / P2_59); + bgd1 = ROUND(eph->tgd[0] / P2_32); /* E5a/E1 */ + bgd2 = ROUND(eph->tgd[1] / P2_32); /* E5b/E1 */ + oshs1 = (eph->svh >> 7) & 3; /* E5b SVH */ + osdvs1 = (eph->svh >> 6) & 1; /* E5b DVS */ + oshs2 = (eph->svh >> 1) & 3; /* E1 SVH */ + osdvs2 = (eph->svh >> 0) & 1; /* E1 DVS */ + setbitu(rtcm->buff, i, 12, 1046); + i += 12; + setbitu(rtcm->buff, i, 6, prn); + i += 6; + setbitu(rtcm->buff, i, 12, week); + i += 12; + setbitu(rtcm->buff, i, 10, eph->iode); + i += 10; + setbitu(rtcm->buff, i, 8, eph->sva); + i += 8; + setbits(rtcm->buff, i, 14, idot); + i += 14; + setbitu(rtcm->buff, i, 14, toc); + i += 14; + setbits(rtcm->buff, i, 6, af2); + i += 6; + setbits(rtcm->buff, i, 21, af1); + i += 21; + setbits(rtcm->buff, i, 31, af0); + i += 31; + setbits(rtcm->buff, i, 16, crs); + i += 16; + setbits(rtcm->buff, i, 16, deln); + i += 16; + setbits(rtcm->buff, i, 32, M0); + i += 32; + setbits(rtcm->buff, i, 16, cuc); + i += 16; + setbitu(rtcm->buff, i, 32, e); + i += 32; + setbits(rtcm->buff, i, 16, cus); + i += 16; + setbitu(rtcm->buff, i, 32, sqrtA); + i += 32; + setbitu(rtcm->buff, i, 14, toe); + i += 14; + setbits(rtcm->buff, i, 16, cic); + i += 16; + setbits(rtcm->buff, i, 32, OMG0); + i += 32; + setbits(rtcm->buff, i, 16, cis); + i += 16; + setbits(rtcm->buff, i, 32, i0); + i += 32; + setbits(rtcm->buff, i, 16, crc); + i += 16; + setbits(rtcm->buff, i, 32, omg); + i += 32; + setbits(rtcm->buff, i, 24, OMGd); + i += 24; + setbits(rtcm->buff, i, 10, bgd1); + i += 10; + setbits(rtcm->buff, i, 10, bgd2); + i += 10; + setbitu(rtcm->buff, i, 2, oshs1); + i += 2; /* E5b SVH */ + setbitu(rtcm->buff, i, 1, osdvs1); + i += 1; /* E5b DVS */ + setbitu(rtcm->buff, i, 2, oshs2); + i += 2; /* E1 SVH */ + setbitu(rtcm->buff, i, 1, osdvs2); + i += 1; /* E1 DVS */ + rtcm->nbit = i; + return 1; } /* encode type 1042: Beidou ephemerides --------------------------------------*/ -static int encode_type1042(rtcm_t *rtcm, int sync) -{ - eph_t *eph; - uint32_t sqrtA,e; - int i=24,prn,week,toe,toc,i0,OMG0,omg,M0,deln,idot,OMGd,crs,crc; - int cus,cuc,cis,cic,af0,af1,af2,tgd1,tgd2; - - trace(3,"encode_type1042: sync=%d\n",sync); - - if (satsys(rtcm->ephsat,&prn)!=SYS_CMP) return 0; - eph=rtcm->nav.eph+rtcm->ephsat-1; - if (eph->sat!=rtcm->ephsat) return 0; - week =eph->week%8192; - toe =ROUND(eph->toes/8.0); - toc =ROUND(time2bdt(gpst2bdt(eph->toc),NULL)/8.0); /* gpst -> bdt */ - sqrtA=ROUND_U(sqrt(eph->A)/P2_19); - e =ROUND_U(eph->e/P2_33); - i0 =ROUND(eph->i0 /P2_31/SC2RAD); - OMG0 =ROUND(eph->OMG0/P2_31/SC2RAD); - omg =ROUND(eph->omg /P2_31/SC2RAD); - M0 =ROUND(eph->M0 /P2_31/SC2RAD); - deln =ROUND(eph->deln/P2_43/SC2RAD); - idot =ROUND(eph->idot/P2_43/SC2RAD); - OMGd =ROUND(eph->OMGd/P2_43/SC2RAD); - crs =ROUND(eph->crs/P2_6 ); - crc =ROUND(eph->crc/P2_6 ); - cus =ROUND(eph->cus/P2_31); - cuc =ROUND(eph->cuc/P2_31); - cis =ROUND(eph->cis/P2_31); - cic =ROUND(eph->cic/P2_31); - af0 =ROUND(eph->f0 /P2_33); - af1 =ROUND(eph->f1 /P2_50); - af2 =ROUND(eph->f2 /P2_66); - tgd1 =ROUND(eph->tgd[0]/1E-10); - tgd2 =ROUND(eph->tgd[1]/1E-10); - - setbitu(rtcm->buff,i,12,1042 ); i+=12; - setbitu(rtcm->buff,i, 6,prn ); i+= 6; - setbitu(rtcm->buff,i,13,week ); i+=13; - setbitu(rtcm->buff,i, 4,eph->sva ); i+= 4; - setbits(rtcm->buff,i,14,idot ); i+=14; - setbitu(rtcm->buff,i, 5,eph->iode); i+= 5; - setbitu(rtcm->buff,i,17,toc ); i+=17; - setbits(rtcm->buff,i,11,af2 ); i+=11; - setbits(rtcm->buff,i,22,af1 ); i+=22; - setbits(rtcm->buff,i,24,af0 ); i+=24; - setbitu(rtcm->buff,i, 5,eph->iodc); i+= 5; - setbits(rtcm->buff,i,18,crs ); i+=18; - setbits(rtcm->buff,i,16,deln ); i+=16; - setbits(rtcm->buff,i,32,M0 ); i+=32; - setbits(rtcm->buff,i,18,cuc ); i+=18; - setbitu(rtcm->buff,i,32,e ); i+=32; - setbits(rtcm->buff,i,18,cus ); i+=18; - setbitu(rtcm->buff,i,32,sqrtA ); i+=32; - setbitu(rtcm->buff,i,17,toe ); i+=17; - setbits(rtcm->buff,i,18,cic ); i+=18; - setbits(rtcm->buff,i,32,OMG0 ); i+=32; - setbits(rtcm->buff,i,18,cis ); i+=18; - setbits(rtcm->buff,i,32,i0 ); i+=32; - setbits(rtcm->buff,i,18,crc ); i+=18; - setbits(rtcm->buff,i,32,omg ); i+=32; - setbits(rtcm->buff,i,24,OMGd ); i+=24; - setbits(rtcm->buff,i,10,tgd1 ); i+=10; - setbits(rtcm->buff,i,10,tgd2 ); i+=10; - setbitu(rtcm->buff,i, 1,eph->svh ); i+= 1; - rtcm->nbit=i; - return 1; +static int encode_type1042(rtcm_t *rtcm, int sync) { + eph_t *eph; + uint32_t sqrtA, e; + int i = 24, prn, week, toe, toc, i0, OMG0, omg, M0, deln, idot, OMGd, crs, crc; + int cus, cuc, cis, cic, af0, af1, af2, tgd1, tgd2; + + trace(3, "encode_type1042: sync=%d\n", sync); + + if (satsys(rtcm->ephsat, &prn) != SYS_CMP) return 0; + eph = rtcm->nav.eph + rtcm->ephsat - 1; + if (eph->sat != rtcm->ephsat) return 0; + week = eph->week % 8192; + toe = ROUND(eph->toes / 8.0); + toc = ROUND(time2bdt(gpst2bdt(eph->toc), NULL) / 8.0); /* gpst -> bdt */ + sqrtA = ROUND_U(sqrt(eph->A) / P2_19); + e = ROUND_U(eph->e / P2_33); + i0 = ROUND(eph->i0 / P2_31 / SC2RAD); + OMG0 = ROUND(eph->OMG0 / P2_31 / SC2RAD); + omg = ROUND(eph->omg / P2_31 / SC2RAD); + M0 = ROUND(eph->M0 / P2_31 / SC2RAD); + deln = ROUND(eph->deln / P2_43 / SC2RAD); + idot = ROUND(eph->idot / P2_43 / SC2RAD); + OMGd = ROUND(eph->OMGd / P2_43 / SC2RAD); + crs = ROUND(eph->crs / P2_6); + crc = ROUND(eph->crc / P2_6); + cus = ROUND(eph->cus / P2_31); + cuc = ROUND(eph->cuc / P2_31); + cis = ROUND(eph->cis / P2_31); + cic = ROUND(eph->cic / P2_31); + af0 = ROUND(eph->f0 / P2_33); + af1 = ROUND(eph->f1 / P2_50); + af2 = ROUND(eph->f2 / P2_66); + tgd1 = ROUND(eph->tgd[0] / 1E-10); + tgd2 = ROUND(eph->tgd[1] / 1E-10); + + setbitu(rtcm->buff, i, 12, 1042); + i += 12; + setbitu(rtcm->buff, i, 6, prn); + i += 6; + setbitu(rtcm->buff, i, 13, week); + i += 13; + setbitu(rtcm->buff, i, 4, eph->sva); + i += 4; + setbits(rtcm->buff, i, 14, idot); + i += 14; + setbitu(rtcm->buff, i, 5, eph->iode); + i += 5; + setbitu(rtcm->buff, i, 17, toc); + i += 17; + setbits(rtcm->buff, i, 11, af2); + i += 11; + setbits(rtcm->buff, i, 22, af1); + i += 22; + setbits(rtcm->buff, i, 24, af0); + i += 24; + setbitu(rtcm->buff, i, 5, eph->iodc); + i += 5; + setbits(rtcm->buff, i, 18, crs); + i += 18; + setbits(rtcm->buff, i, 16, deln); + i += 16; + setbits(rtcm->buff, i, 32, M0); + i += 32; + setbits(rtcm->buff, i, 18, cuc); + i += 18; + setbitu(rtcm->buff, i, 32, e); + i += 32; + setbits(rtcm->buff, i, 18, cus); + i += 18; + setbitu(rtcm->buff, i, 32, sqrtA); + i += 32; + setbitu(rtcm->buff, i, 17, toe); + i += 17; + setbits(rtcm->buff, i, 18, cic); + i += 18; + setbits(rtcm->buff, i, 32, OMG0); + i += 32; + setbits(rtcm->buff, i, 18, cis); + i += 18; + setbits(rtcm->buff, i, 32, i0); + i += 32; + setbits(rtcm->buff, i, 18, crc); + i += 18; + setbits(rtcm->buff, i, 32, omg); + i += 32; + setbits(rtcm->buff, i, 24, OMGd); + i += 24; + setbits(rtcm->buff, i, 10, tgd1); + i += 10; + setbits(rtcm->buff, i, 10, tgd2); + i += 10; + setbitu(rtcm->buff, i, 1, eph->svh); + i += 1; + rtcm->nbit = i; + return 1; } /* encode type 63: Beidou ephemerides (RTCM draft) ---------------------------*/ -static int encode_type63(rtcm_t *rtcm, int sync) -{ - eph_t *eph; - uint32_t sqrtA,e; - int i=24,prn,week,toe,toc,i0,OMG0,omg,M0,deln,idot,OMGd,crs,crc; - int cus,cuc,cis,cic,af0,af1,af2,tgd1,tgd2; - - trace(3,"encode_type63: sync=%d\n",sync); - - if (satsys(rtcm->ephsat,&prn)!=SYS_CMP) return 0; - eph=rtcm->nav.eph+rtcm->ephsat-1; - if (eph->sat!=rtcm->ephsat) return 0; - week =eph->week%8192; - toe =ROUND(eph->toes/8.0); - toc =ROUND(time2bdt(gpst2bdt(eph->toc),NULL)/8.0); /* gpst -> bdt */ - sqrtA=ROUND_U(sqrt(eph->A)/P2_19); - e =ROUND_U(eph->e/P2_33); - i0 =ROUND(eph->i0 /P2_31/SC2RAD); - OMG0 =ROUND(eph->OMG0/P2_31/SC2RAD); - omg =ROUND(eph->omg /P2_31/SC2RAD); - M0 =ROUND(eph->M0 /P2_31/SC2RAD); - deln =ROUND(eph->deln/P2_43/SC2RAD); - idot =ROUND(eph->idot/P2_43/SC2RAD); - OMGd =ROUND(eph->OMGd/P2_43/SC2RAD); - crs =ROUND(eph->crs/P2_6 ); - crc =ROUND(eph->crc/P2_6 ); - cus =ROUND(eph->cus/P2_31); - cuc =ROUND(eph->cuc/P2_31); - cis =ROUND(eph->cis/P2_31); - cic =ROUND(eph->cic/P2_31); - af0 =ROUND(eph->f0 /P2_33); - af1 =ROUND(eph->f1 /P2_50); - af2 =ROUND(eph->f2 /P2_66); - tgd1 =ROUND(eph->tgd[0]/1E-10); - tgd2 =ROUND(eph->tgd[1]/1E-10); - - setbitu(rtcm->buff,i,12,63 ); i+=12; - setbitu(rtcm->buff,i, 6,prn ); i+= 6; - setbitu(rtcm->buff,i,13,week ); i+=13; - setbitu(rtcm->buff,i, 4,eph->sva ); i+= 4; - setbits(rtcm->buff,i,14,idot ); i+=14; - setbitu(rtcm->buff,i, 5,eph->iode); i+= 5; - setbitu(rtcm->buff,i,17,toc ); i+=17; - setbits(rtcm->buff,i,11,af2 ); i+=11; - setbits(rtcm->buff,i,22,af1 ); i+=22; - setbits(rtcm->buff,i,24,af0 ); i+=24; - setbitu(rtcm->buff,i, 5,eph->iodc); i+= 5; - setbits(rtcm->buff,i,18,crs ); i+=18; - setbits(rtcm->buff,i,16,deln ); i+=16; - setbits(rtcm->buff,i,32,M0 ); i+=32; - setbits(rtcm->buff,i,18,cuc ); i+=18; - setbitu(rtcm->buff,i,32,e ); i+=32; - setbits(rtcm->buff,i,18,cus ); i+=18; - setbitu(rtcm->buff,i,32,sqrtA ); i+=32; - setbitu(rtcm->buff,i,17,toe ); i+=17; - setbits(rtcm->buff,i,18,cic ); i+=18; - setbits(rtcm->buff,i,32,OMG0 ); i+=32; - setbits(rtcm->buff,i,18,cis ); i+=18; - setbits(rtcm->buff,i,32,i0 ); i+=32; - setbits(rtcm->buff,i,18,crc ); i+=18; - setbits(rtcm->buff,i,32,omg ); i+=32; - setbits(rtcm->buff,i,24,OMGd ); i+=24; - setbits(rtcm->buff,i,10,tgd1 ); i+=10; - setbits(rtcm->buff,i,10,tgd2 ); i+=10; - setbitu(rtcm->buff,i, 1,eph->svh ); i+= 1; - rtcm->nbit=i; - return 1; +static int encode_type63(rtcm_t *rtcm, int sync) { + eph_t *eph; + uint32_t sqrtA, e; + int i = 24, prn, week, toe, toc, i0, OMG0, omg, M0, deln, idot, OMGd, crs, crc; + int cus, cuc, cis, cic, af0, af1, af2, tgd1, tgd2; + + trace(3, "encode_type63: sync=%d\n", sync); + + if (satsys(rtcm->ephsat, &prn) != SYS_CMP) return 0; + eph = rtcm->nav.eph + rtcm->ephsat - 1; + if (eph->sat != rtcm->ephsat) return 0; + week = eph->week % 8192; + toe = ROUND(eph->toes / 8.0); + toc = ROUND(time2bdt(gpst2bdt(eph->toc), NULL) / 8.0); /* gpst -> bdt */ + sqrtA = ROUND_U(sqrt(eph->A) / P2_19); + e = ROUND_U(eph->e / P2_33); + i0 = ROUND(eph->i0 / P2_31 / SC2RAD); + OMG0 = ROUND(eph->OMG0 / P2_31 / SC2RAD); + omg = ROUND(eph->omg / P2_31 / SC2RAD); + M0 = ROUND(eph->M0 / P2_31 / SC2RAD); + deln = ROUND(eph->deln / P2_43 / SC2RAD); + idot = ROUND(eph->idot / P2_43 / SC2RAD); + OMGd = ROUND(eph->OMGd / P2_43 / SC2RAD); + crs = ROUND(eph->crs / P2_6); + crc = ROUND(eph->crc / P2_6); + cus = ROUND(eph->cus / P2_31); + cuc = ROUND(eph->cuc / P2_31); + cis = ROUND(eph->cis / P2_31); + cic = ROUND(eph->cic / P2_31); + af0 = ROUND(eph->f0 / P2_33); + af1 = ROUND(eph->f1 / P2_50); + af2 = ROUND(eph->f2 / P2_66); + tgd1 = ROUND(eph->tgd[0] / 1E-10); + tgd2 = ROUND(eph->tgd[1] / 1E-10); + + setbitu(rtcm->buff, i, 12, 63); + i += 12; + setbitu(rtcm->buff, i, 6, prn); + i += 6; + setbitu(rtcm->buff, i, 13, week); + i += 13; + setbitu(rtcm->buff, i, 4, eph->sva); + i += 4; + setbits(rtcm->buff, i, 14, idot); + i += 14; + setbitu(rtcm->buff, i, 5, eph->iode); + i += 5; + setbitu(rtcm->buff, i, 17, toc); + i += 17; + setbits(rtcm->buff, i, 11, af2); + i += 11; + setbits(rtcm->buff, i, 22, af1); + i += 22; + setbits(rtcm->buff, i, 24, af0); + i += 24; + setbitu(rtcm->buff, i, 5, eph->iodc); + i += 5; + setbits(rtcm->buff, i, 18, crs); + i += 18; + setbits(rtcm->buff, i, 16, deln); + i += 16; + setbits(rtcm->buff, i, 32, M0); + i += 32; + setbits(rtcm->buff, i, 18, cuc); + i += 18; + setbitu(rtcm->buff, i, 32, e); + i += 32; + setbits(rtcm->buff, i, 18, cus); + i += 18; + setbitu(rtcm->buff, i, 32, sqrtA); + i += 32; + setbitu(rtcm->buff, i, 17, toe); + i += 17; + setbits(rtcm->buff, i, 18, cic); + i += 18; + setbits(rtcm->buff, i, 32, OMG0); + i += 32; + setbits(rtcm->buff, i, 18, cis); + i += 18; + setbits(rtcm->buff, i, 32, i0); + i += 32; + setbits(rtcm->buff, i, 18, crc); + i += 18; + setbits(rtcm->buff, i, 32, omg); + i += 32; + setbits(rtcm->buff, i, 24, OMGd); + i += 24; + setbits(rtcm->buff, i, 10, tgd1); + i += 10; + setbits(rtcm->buff, i, 10, tgd2); + i += 10; + setbitu(rtcm->buff, i, 1, eph->svh); + i += 1; + rtcm->nbit = i; + return 1; } /* encode SSR header ---------------------------------------------------------*/ -static int encode_ssr_head(int type, rtcm_t *rtcm, int sys, int subtype, - int nsat, int sync, int iod, double udint, int refd, - int provid, int solid) -{ - double tow; - int i=24,msgno,epoch,week,udi,ns; - - trace(4,"encode_ssr_head: type=%d sys=%d subtype=%d nsat=%d sync=%d iod=%d " - "udint=%.0f\n",type,sys,subtype,nsat,sync,iod,udint); - - if (subtype==0) { /* RTCM SSR */ - ns=(sys==SYS_QZS)?4:6; +static int encode_ssr_head(int type, rtcm_t *rtcm, int sys, int subtype, int nsat, int sync, + int iod, double udint, int refd, int provid, int solid) { + double tow; + int i = 24, msgno, epoch, week, udi, ns; + + trace(4, + "encode_ssr_head: type=%d sys=%d subtype=%d nsat=%d sync=%d iod=%d " + "udint=%.0f\n", + type, sys, subtype, nsat, sync, iod, udint); + + if (subtype == 0) { /* RTCM SSR */ + ns = (sys == SYS_QZS) ? 4 : 6; switch (sys) { - case SYS_GPS: msgno=(type==7)?11:1056+type; break; - case SYS_GLO: msgno=(type==7)? 0:1062+type; break; - case SYS_GAL: msgno=(type==7)?12:1239+type; break; /* draft */ - case SYS_QZS: msgno=(type==7)?13:1245+type; break; /* draft */ - case SYS_CMP: msgno=(type==7)?14:1257+type; break; /* draft */ - case SYS_SBS: msgno=(type==7)? 0:1251+type; break; /* draft */ - default: return 0; - } - if (msgno==0) { + case SYS_GPS: + msgno = (type == 7) ? 11 : 1056 + type; + break; + case SYS_GLO: + msgno = (type == 7) ? 0 : 1062 + type; + break; + case SYS_GAL: + msgno = (type == 7) ? 12 : 1239 + type; + break; /* draft */ + case SYS_QZS: + msgno = (type == 7) ? 13 : 1245 + type; + break; /* draft */ + case SYS_CMP: + msgno = (type == 7) ? 14 : 1257 + type; + break; /* draft */ + case SYS_SBS: + msgno = (type == 7) ? 0 : 1251 + type; + break; /* draft */ + default: return 0; } - setbitu(rtcm->buff,i,12,msgno); i+=12; /* message type */ - - if (sys==SYS_GLO) { - tow=time2gpst(timeadd(gpst2utc(rtcm->time),10800.0),&week); - epoch=ROUND(tow)%86400; - setbitu(rtcm->buff,i,17,epoch); i+=17; /* GLONASS epoch time */ + if (msgno == 0) { + return 0; } - else { - tow=time2gpst(rtcm->time,&week); - epoch=ROUND(tow)%604800; - setbitu(rtcm->buff,i,20,epoch); i+=20; /* GPS epoch time */ - } - } - else { /* IGS SSR */ - ns=6; - tow=time2gpst(rtcm->time,&week); - epoch=ROUND(tow)%604800; - setbitu(rtcm->buff,i,12,4076 ); i+=12; /* message type */ - setbitu(rtcm->buff,i, 3,1 ); i+= 3; /* version */ - setbitu(rtcm->buff,i, 8,subtype); i+= 8; /* subtype */ - setbitu(rtcm->buff,i,20,epoch ); i+=20; /* SSR epoch time */ - } - for (udi=0;udi<15;udi++) { - if (ssrudint[udi]>=udint) break; - } - setbitu(rtcm->buff,i, 4,udi ); i+= 4; /* update interval */ - setbitu(rtcm->buff,i, 1,sync ); i+= 1; /* multiple message indicator */ - if (subtype==0&&(type==1||type==4)) { - setbitu(rtcm->buff,i,1,refd); i+= 1; /* satellite ref datum */ - } - setbitu(rtcm->buff,i, 4,iod ); i+= 4; /* IOD SSR */ - setbitu(rtcm->buff,i,16,provid ); i+=16; /* provider ID */ - setbitu(rtcm->buff,i, 4,solid ); i+= 4; /* solution ID */ - if (subtype>0&&(type==1||type==4)) { - setbitu(rtcm->buff,i,1,refd); i+= 1; /* global/regional CRS indicator */ - } - if (type==7) { - setbitu(rtcm->buff,i,1,0); i+=1; /* dispersive bias consistency ind */ - setbitu(rtcm->buff,i,1,0); i+=1; /* MW consistency indicator */ - } - setbitu(rtcm->buff,i,ns,nsat ); i+=ns; /* no of satellites */ - return i; + setbitu(rtcm->buff, i, 12, msgno); + i += 12; /* message type */ + + if (sys == SYS_GLO) { + tow = time2gpst(timeadd(gpst2utc(rtcm->time), 10800.0), &week); + epoch = ROUND(tow) % 86400; + setbitu(rtcm->buff, i, 17, epoch); + i += 17; /* GLONASS epoch time */ + } else { + tow = time2gpst(rtcm->time, &week); + epoch = ROUND(tow) % 604800; + setbitu(rtcm->buff, i, 20, epoch); + i += 20; /* GPS epoch time */ + } + } else { /* IGS SSR */ + ns = 6; + tow = time2gpst(rtcm->time, &week); + epoch = ROUND(tow) % 604800; + setbitu(rtcm->buff, i, 12, 4076); + i += 12; /* message type */ + setbitu(rtcm->buff, i, 3, 1); + i += 3; /* version */ + setbitu(rtcm->buff, i, 8, subtype); + i += 8; /* subtype */ + setbitu(rtcm->buff, i, 20, epoch); + i += 20; /* SSR epoch time */ + } + for (udi = 0; udi < 15; udi++) { + if (ssrudint[udi] >= udint) break; + } + setbitu(rtcm->buff, i, 4, udi); + i += 4; /* update interval */ + setbitu(rtcm->buff, i, 1, sync); + i += 1; /* multiple message indicator */ + if (subtype == 0 && (type == 1 || type == 4)) { + setbitu(rtcm->buff, i, 1, refd); + i += 1; /* satellite ref datum */ + } + setbitu(rtcm->buff, i, 4, iod); + i += 4; /* IOD SSR */ + setbitu(rtcm->buff, i, 16, provid); + i += 16; /* provider ID */ + setbitu(rtcm->buff, i, 4, solid); + i += 4; /* solution ID */ + if (subtype > 0 && (type == 1 || type == 4)) { + setbitu(rtcm->buff, i, 1, refd); + i += 1; /* global/regional CRS indicator */ + } + if (type == 7) { + setbitu(rtcm->buff, i, 1, 0); + i += 1; /* dispersive bias consistency ind */ + setbitu(rtcm->buff, i, 1, 0); + i += 1; /* MW consistency indicator */ + } + setbitu(rtcm->buff, i, ns, nsat); + i += ns; /* no of satellites */ + return i; } /* SSR signal and tracking mode IDs ------------------------------------------*/ -static const int codes_gps[32]={ - CODE_L1C,CODE_L1P,CODE_L1W,CODE_L1S,CODE_L1L,CODE_L2C,CODE_L2D,CODE_L2S, - CODE_L2L,CODE_L2X,CODE_L2P,CODE_L2W, 0, 0,CODE_L5I,CODE_L5Q -}; -static const int codes_glo[32]={ - CODE_L1C,CODE_L1P,CODE_L2C,CODE_L2P,CODE_L4A,CODE_L4B,CODE_L6A,CODE_L6B, - CODE_L3I,CODE_L3Q -}; -static const int codes_gal[32]={ - CODE_L1A,CODE_L1B,CODE_L1C, 0, 0,CODE_L5I,CODE_L5Q, 0, - CODE_L7I,CODE_L7Q, 0,CODE_L8I,CODE_L8Q, 0,CODE_L6A,CODE_L6B, - CODE_L6C -}; -static const int codes_qzs[32]={ - CODE_L1C,CODE_L1S,CODE_L1L,CODE_L2S,CODE_L2L, 0,CODE_L5I,CODE_L5Q, - 0,CODE_L6S,CODE_L6L, 0, 0, 0, 0, 0, - 0,CODE_L6E -}; -static const int codes_bds[32]={ - CODE_L2I,CODE_L2Q, 0,CODE_L6I,CODE_L6Q, 0,CODE_L7I,CODE_L7Q, - 0,CODE_L1D,CODE_L1P, 0,CODE_L5D,CODE_L5P, 0,CODE_L1A, - 0, 0,CODE_L6A -}; -static const int codes_sbs[32]={ - CODE_L1C,CODE_L5I,CODE_L5Q -}; +static const int codes_gps[32] = {CODE_L1C, CODE_L1P, CODE_L1W, CODE_L1S, CODE_L1L, CODE_L2C, + CODE_L2D, CODE_L2S, CODE_L2L, CODE_L2X, CODE_L2P, CODE_L2W, + 0, 0, CODE_L5I, CODE_L5Q}; +static const int codes_glo[32] = {CODE_L1C, CODE_L1P, CODE_L2C, CODE_L2P, CODE_L4A, + CODE_L4B, CODE_L6A, CODE_L6B, CODE_L3I, CODE_L3Q}; +static const int codes_gal[32] = {CODE_L1A, CODE_L1B, CODE_L1C, 0, 0, CODE_L5I, + CODE_L5Q, 0, CODE_L7I, CODE_L7Q, 0, CODE_L8I, + CODE_L8Q, 0, CODE_L6A, CODE_L6B, CODE_L6C}; +static const int codes_qzs[32] = {CODE_L1C, CODE_L1S, CODE_L1L, CODE_L2S, CODE_L2L, 0, + CODE_L5I, CODE_L5Q, 0, CODE_L6S, CODE_L6L, 0, + 0, 0, 0, 0, 0, CODE_L6E}; +static const int codes_bds[32] = { + CODE_L2I, CODE_L2Q, 0, CODE_L6I, CODE_L6Q, 0, CODE_L7I, CODE_L7Q, 0, CODE_L1D, CODE_L1P, + 0, CODE_L5D, CODE_L5P, 0, CODE_L1A, 0, 0, CODE_L6A}; +static const int codes_sbs[32] = {CODE_L1C, CODE_L5I, CODE_L5Q}; /* encode SSR 1: orbit corrections -------------------------------------------*/ -static int encode_ssr1(rtcm_t *rtcm, int sys, int subtype, int sync) -{ - double udint=0.0; - int i,j,iod=0,nsat,prn,iode,iodcrc,refd=0,np,ni,nj,offp,deph[3],ddeph[3]; - - trace(3,"encode_ssr1: sys=%d subtype=%d sync=%d\n",sys,subtype,sync); - - switch (sys) { - case SYS_GPS: np=6; ni= 8; nj= 0; offp= 0; break; - case SYS_GLO: np=5; ni= 8; nj= 0; offp= 0; break; - case SYS_GAL: np=6; ni=10; nj= 0; offp= 0; break; - case SYS_QZS: np=4; ni= 8; nj= 0; offp=192; break; - case SYS_CMP: np=6; ni=10; nj=24; offp= 1; break; - case SYS_SBS: np=6; ni= 9; nj=24; offp=120; break; - default: return 0; - } - if (subtype>0) { /* IGS SSR */ - np=6; ni=8; nj=0; - if (sys==SYS_CMP) offp=0; - else if (sys==SYS_SBS) offp=119; - } - /* number of satellites */ - for (j=nsat=0;jssr[j].update) continue; - nsat++; - udint=rtcm->ssr[j].udi[0]; - iod =rtcm->ssr[j].iod[0]; - refd =rtcm->ssr[j].refd; - } - /* encode SSR header */ - i=encode_ssr_head(1,rtcm,sys,subtype,nsat,sync,iod,udint,refd,0,0); - - for (j=0;jssr[j].update) continue; - - iode=rtcm->ssr[j].iode; /* SBAS/BDS: toe/t0 modulo */ - iodcrc=rtcm->ssr[j].iodcrc; /* SBAS/BDS: IOD CRC */ - - if (subtype>0) { /* IGS SSR */ - iode&=0xFF; - } - deph [0]=ROUND(rtcm->ssr[j].deph [0]/1E-4); - deph [1]=ROUND(rtcm->ssr[j].deph [1]/4E-4); - deph [2]=ROUND(rtcm->ssr[j].deph [2]/4E-4); - ddeph[0]=ROUND(rtcm->ssr[j].ddeph[0]/1E-6); - ddeph[1]=ROUND(rtcm->ssr[j].ddeph[1]/4E-6); - ddeph[2]=ROUND(rtcm->ssr[j].ddeph[2]/4E-6); - - setbitu(rtcm->buff,i,np,prn-offp); i+=np; /* satellite ID */ - setbitu(rtcm->buff,i,ni,iode ); i+=ni; /* IODE */ - setbitu(rtcm->buff,i,nj,iodcrc ); i+=nj; /* IODCRC */ - setbits(rtcm->buff,i,22,deph [0]); i+=22; /* delta radial */ - setbits(rtcm->buff,i,20,deph [1]); i+=20; /* delta along-track */ - setbits(rtcm->buff,i,20,deph [2]); i+=20; /* delta cross-track */ - setbits(rtcm->buff,i,21,ddeph[0]); i+=21; /* dot delta radial */ - setbits(rtcm->buff,i,19,ddeph[1]); i+=19; /* dot delta along-track */ - setbits(rtcm->buff,i,19,ddeph[2]); i+=19; /* dot delta cross-track */ - } - rtcm->nbit=i; - return 1; +static int encode_ssr1(rtcm_t *rtcm, int sys, int subtype, int sync) { + double udint = 0.0; + int i, j, iod = 0, nsat, prn, iode, iodcrc, refd = 0, np, ni, nj, offp, deph[3], ddeph[3]; + + trace(3, "encode_ssr1: sys=%d subtype=%d sync=%d\n", sys, subtype, sync); + + switch (sys) { + case SYS_GPS: + np = 6; + ni = 8; + nj = 0; + offp = 0; + break; + case SYS_GLO: + np = 5; + ni = 8; + nj = 0; + offp = 0; + break; + case SYS_GAL: + np = 6; + ni = 10; + nj = 0; + offp = 0; + break; + case SYS_QZS: + np = 4; + ni = 8; + nj = 0; + offp = 192; + break; + case SYS_CMP: + np = 6; + ni = 10; + nj = 24; + offp = 1; + break; + case SYS_SBS: + np = 6; + ni = 9; + nj = 24; + offp = 120; + break; + default: + return 0; + } + if (subtype > 0) { /* IGS SSR */ + np = 6; + ni = 8; + nj = 0; + if (sys == SYS_CMP) + offp = 0; + else if (sys == SYS_SBS) + offp = 119; + } + /* number of satellites */ + for (j = nsat = 0; j < MAXSAT; j++) { + if (satsys(j + 1, &prn) != sys || !rtcm->ssr[j].update) continue; + nsat++; + udint = rtcm->ssr[j].udi[0]; + iod = rtcm->ssr[j].iod[0]; + refd = rtcm->ssr[j].refd; + } + /* encode SSR header */ + i = encode_ssr_head(1, rtcm, sys, subtype, nsat, sync, iod, udint, refd, 0, 0); + + for (j = 0; j < MAXSAT; j++) { + if (satsys(j + 1, &prn) != sys || !rtcm->ssr[j].update) continue; + + iode = rtcm->ssr[j].iode; /* SBAS/BDS: toe/t0 modulo */ + iodcrc = rtcm->ssr[j].iodcrc; /* SBAS/BDS: IOD CRC */ + + if (subtype > 0) { /* IGS SSR */ + iode &= 0xFF; + } + deph[0] = ROUND(rtcm->ssr[j].deph[0] / 1E-4); + deph[1] = ROUND(rtcm->ssr[j].deph[1] / 4E-4); + deph[2] = ROUND(rtcm->ssr[j].deph[2] / 4E-4); + ddeph[0] = ROUND(rtcm->ssr[j].ddeph[0] / 1E-6); + ddeph[1] = ROUND(rtcm->ssr[j].ddeph[1] / 4E-6); + ddeph[2] = ROUND(rtcm->ssr[j].ddeph[2] / 4E-6); + + setbitu(rtcm->buff, i, np, prn - offp); + i += np; /* satellite ID */ + setbitu(rtcm->buff, i, ni, iode); + i += ni; /* IODE */ + setbitu(rtcm->buff, i, nj, iodcrc); + i += nj; /* IODCRC */ + setbits(rtcm->buff, i, 22, deph[0]); + i += 22; /* delta radial */ + setbits(rtcm->buff, i, 20, deph[1]); + i += 20; /* delta along-track */ + setbits(rtcm->buff, i, 20, deph[2]); + i += 20; /* delta cross-track */ + setbits(rtcm->buff, i, 21, ddeph[0]); + i += 21; /* dot delta radial */ + setbits(rtcm->buff, i, 19, ddeph[1]); + i += 19; /* dot delta along-track */ + setbits(rtcm->buff, i, 19, ddeph[2]); + i += 19; /* dot delta cross-track */ + } + rtcm->nbit = i; + return 1; } /* encode SSR 2: clock corrections -------------------------------------------*/ -static int encode_ssr2(rtcm_t *rtcm, int sys, int subtype, int sync) -{ - double udint=0.0; - int i,j,iod=0,nsat,prn,np,offp,dclk[3]; - - trace(3,"encode_ssr2: sys=%d subtype=%d sync=%d\n",sys,subtype,sync); - - switch (sys) { - case SYS_GPS: np=6; offp= 0; break; - case SYS_GLO: np=5; offp= 0; break; - case SYS_GAL: np=6; offp= 0; break; - case SYS_QZS: np=4; offp=192; break; - case SYS_CMP: np=6; offp= 1; break; - case SYS_SBS: np=6; offp=120; break; - default: return 0; - } - if (subtype>0) { /* IGS SSR */ - np=6; - if (sys==SYS_CMP) offp=0; - else if (sys==SYS_SBS) offp=119; - } - /* number of satellites */ - for (j=nsat=0;jssr[j].update) continue; - nsat++; - udint=rtcm->ssr[j].udi[1]; - iod =rtcm->ssr[j].iod[1]; - } - /* encode SSR header */ - i=encode_ssr_head(2,rtcm,sys,subtype,nsat,sync,iod,udint,0,0,0); - - for (j=0;jssr[j].update) continue; - - dclk[0]=ROUND(rtcm->ssr[j].dclk[0]/1E-4); - dclk[1]=ROUND(rtcm->ssr[j].dclk[1]/1E-6); - dclk[2]=ROUND(rtcm->ssr[j].dclk[2]/2E-8); - - setbitu(rtcm->buff,i,np,prn-offp); i+=np; /* satellite ID */ - setbits(rtcm->buff,i,22,dclk[0] ); i+=22; /* delta clock C0 */ - setbits(rtcm->buff,i,21,dclk[1] ); i+=21; /* delta clock C1 */ - setbits(rtcm->buff,i,27,dclk[2] ); i+=27; /* delta clock C2 */ - } - rtcm->nbit=i; - return 1; +static int encode_ssr2(rtcm_t *rtcm, int sys, int subtype, int sync) { + double udint = 0.0; + int i, j, iod = 0, nsat, prn, np, offp, dclk[3]; + + trace(3, "encode_ssr2: sys=%d subtype=%d sync=%d\n", sys, subtype, sync); + + switch (sys) { + case SYS_GPS: + np = 6; + offp = 0; + break; + case SYS_GLO: + np = 5; + offp = 0; + break; + case SYS_GAL: + np = 6; + offp = 0; + break; + case SYS_QZS: + np = 4; + offp = 192; + break; + case SYS_CMP: + np = 6; + offp = 1; + break; + case SYS_SBS: + np = 6; + offp = 120; + break; + default: + return 0; + } + if (subtype > 0) { /* IGS SSR */ + np = 6; + if (sys == SYS_CMP) + offp = 0; + else if (sys == SYS_SBS) + offp = 119; + } + /* number of satellites */ + for (j = nsat = 0; j < MAXSAT; j++) { + if (satsys(j + 1, &prn) != sys || !rtcm->ssr[j].update) continue; + nsat++; + udint = rtcm->ssr[j].udi[1]; + iod = rtcm->ssr[j].iod[1]; + } + /* encode SSR header */ + i = encode_ssr_head(2, rtcm, sys, subtype, nsat, sync, iod, udint, 0, 0, 0); + + for (j = 0; j < MAXSAT; j++) { + if (satsys(j + 1, &prn) != sys || !rtcm->ssr[j].update) continue; + + dclk[0] = ROUND(rtcm->ssr[j].dclk[0] / 1E-4); + dclk[1] = ROUND(rtcm->ssr[j].dclk[1] / 1E-6); + dclk[2] = ROUND(rtcm->ssr[j].dclk[2] / 2E-8); + + setbitu(rtcm->buff, i, np, prn - offp); + i += np; /* satellite ID */ + setbits(rtcm->buff, i, 22, dclk[0]); + i += 22; /* delta clock C0 */ + setbits(rtcm->buff, i, 21, dclk[1]); + i += 21; /* delta clock C1 */ + setbits(rtcm->buff, i, 27, dclk[2]); + i += 27; /* delta clock C2 */ + } + rtcm->nbit = i; + return 1; } /* encode SSR 3: satellite code biases ---------------------------------------*/ -static int encode_ssr3(rtcm_t *rtcm, int sys, int subtype, int sync) -{ - const int *codes; - double udint=0.0; - int i,j,k,iod=0,nsat,prn,nbias,np,offp; - int code[MAXCODE],bias[MAXCODE]; - - trace(3,"encode_ssr3: sys=%d subtype=%d sync=%d\n",sys,subtype,sync); - - switch (sys) { - case SYS_GPS: np=6; offp= 0; codes=codes_gps; break; - case SYS_GLO: np=5; offp= 0; codes=codes_glo; break; - case SYS_GAL: np=6; offp= 0; codes=codes_gal; break; - case SYS_QZS: np=4; offp=192; codes=codes_qzs; break; - case SYS_CMP: np=6; offp= 1; codes=codes_bds; break; - case SYS_SBS: np=6; offp=120; codes=codes_sbs; break; - default: return 0; - } - if (subtype>0) { /* IGS SSR */ - np=6; - if (sys==SYS_CMP) offp=0; - else if (sys==SYS_SBS) offp=119; - } - /* number of satellites */ - for (j=nsat=0;jssr[j].update) continue; - nsat++; - udint=rtcm->ssr[j].udi[4]; - iod =rtcm->ssr[j].iod[4]; - } - /* encode SSR header */ - i=encode_ssr_head(3,rtcm,sys,subtype,nsat,sync,iod,udint,0,0,0); - - for (j=0;jssr[j].update) continue; - - for (k=nbias=0;k<32;k++) { - if (!codes[k]||rtcm->ssr[j].cbias[codes[k]-1]==0.0) continue; - code[nbias]=k; - bias[nbias++]=ROUND(rtcm->ssr[j].cbias[codes[k]-1]/0.01); - } - setbitu(rtcm->buff,i,np,prn-offp); i+=np; /* satellite ID */ - setbitu(rtcm->buff,i, 5,nbias); i+= 5; /* number of code biases */ - - for (k=0;kbuff,i, 5,code[k]); i+= 5; /* signal indicator */ - setbits(rtcm->buff,i,14,bias[k]); i+=14; /* code bias */ - } +static int encode_ssr3(rtcm_t *rtcm, int sys, int subtype, int sync) { + const int *codes; + double udint = 0.0; + int i, j, k, iod = 0, nsat, prn, nbias, np, offp; + int code[MAXCODE], bias[MAXCODE]; + + trace(3, "encode_ssr3: sys=%d subtype=%d sync=%d\n", sys, subtype, sync); + + switch (sys) { + case SYS_GPS: + np = 6; + offp = 0; + codes = codes_gps; + break; + case SYS_GLO: + np = 5; + offp = 0; + codes = codes_glo; + break; + case SYS_GAL: + np = 6; + offp = 0; + codes = codes_gal; + break; + case SYS_QZS: + np = 4; + offp = 192; + codes = codes_qzs; + break; + case SYS_CMP: + np = 6; + offp = 1; + codes = codes_bds; + break; + case SYS_SBS: + np = 6; + offp = 120; + codes = codes_sbs; + break; + default: + return 0; + } + if (subtype > 0) { /* IGS SSR */ + np = 6; + if (sys == SYS_CMP) + offp = 0; + else if (sys == SYS_SBS) + offp = 119; + } + /* number of satellites */ + for (j = nsat = 0; j < MAXSAT; j++) { + if (satsys(j + 1, &prn) != sys || !rtcm->ssr[j].update) continue; + nsat++; + udint = rtcm->ssr[j].udi[4]; + iod = rtcm->ssr[j].iod[4]; + } + /* encode SSR header */ + i = encode_ssr_head(3, rtcm, sys, subtype, nsat, sync, iod, udint, 0, 0, 0); + + for (j = 0; j < MAXSAT; j++) { + if (satsys(j + 1, &prn) != sys || !rtcm->ssr[j].update) continue; + + for (k = nbias = 0; k < 32; k++) { + if (!codes[k] || rtcm->ssr[j].cbias[codes[k] - 1] == 0.0) continue; + code[nbias] = k; + bias[nbias++] = ROUND(rtcm->ssr[j].cbias[codes[k] - 1] / 0.01); + } + setbitu(rtcm->buff, i, np, prn - offp); + i += np; /* satellite ID */ + setbitu(rtcm->buff, i, 5, nbias); + i += 5; /* number of code biases */ + + for (k = 0; k < nbias; k++) { + setbitu(rtcm->buff, i, 5, code[k]); + i += 5; /* signal indicator */ + setbits(rtcm->buff, i, 14, bias[k]); + i += 14; /* code bias */ } - rtcm->nbit=i; - return 1; + } + rtcm->nbit = i; + return 1; } /* encode SSR 4: combined orbit and clock corrections ------------------------*/ -static int encode_ssr4(rtcm_t *rtcm, int sys, int subtype, int sync) -{ - double udint=0.0; - int i,j,iod=0,nsat,prn,iode,iodcrc,refd=0,np,ni,nj,offp; - int deph[3],ddeph[3],dclk[3]; - - trace(3,"encode_ssr4: sys=%d subtype=%d sync=%d\n",sys,subtype,sync); - - switch (sys) { - case SYS_GPS: np=6; ni= 8; nj= 0; offp= 0; break; - case SYS_GLO: np=5; ni= 8; nj= 0; offp= 0; break; - case SYS_GAL: np=6; ni=10; nj= 0; offp= 0; break; - case SYS_QZS: np=4; ni= 8; nj= 0; offp=192; break; - case SYS_CMP: np=6; ni=10; nj=24; offp= 1; break; - case SYS_SBS: np=6; ni= 9; nj=24; offp=120; break; - default: return 0; - } - if (subtype>0) { /* IGS SSR */ - np=6; ni=8; nj=0; - if (sys==SYS_CMP) offp=0; - else if (sys==SYS_SBS) offp=119; - } - /* number of satellites */ - for (j=nsat=0;jssr[j].update) continue; - nsat++; - udint=rtcm->ssr[j].udi[0]; - iod =rtcm->ssr[j].iod[0]; - refd =rtcm->ssr[j].refd; - } - /* encode SSR header */ - i=encode_ssr_head(4,rtcm,sys,subtype,nsat,sync,iod,udint,refd,0,0); - - for (j=0;jssr[j].update) continue; - - iode=rtcm->ssr[j].iode; - iodcrc=rtcm->ssr[j].iodcrc; - - if (subtype>0) { /* IGS SSR */ - iode&=0xFF; - } - deph [0]=ROUND(rtcm->ssr[j].deph [0]/1E-4); - deph [1]=ROUND(rtcm->ssr[j].deph [1]/4E-4); - deph [2]=ROUND(rtcm->ssr[j].deph [2]/4E-4); - ddeph[0]=ROUND(rtcm->ssr[j].ddeph[0]/1E-6); - ddeph[1]=ROUND(rtcm->ssr[j].ddeph[1]/4E-6); - ddeph[2]=ROUND(rtcm->ssr[j].ddeph[2]/4E-6); - dclk [0]=ROUND(rtcm->ssr[j].dclk [0]/1E-4); - dclk [1]=ROUND(rtcm->ssr[j].dclk [1]/1E-6); - dclk [2]=ROUND(rtcm->ssr[j].dclk [2]/2E-8); - - setbitu(rtcm->buff,i,np,prn-offp); i+=np; /* satellite ID */ - setbitu(rtcm->buff,i,ni,iode ); i+=ni; /* IODE */ - setbitu(rtcm->buff,i,nj,iodcrc ); i+=nj; /* IODCRC */ - setbits(rtcm->buff,i,22,deph [0]); i+=22; /* delta raidal */ - setbits(rtcm->buff,i,20,deph [1]); i+=20; /* delta along-track */ - setbits(rtcm->buff,i,20,deph [2]); i+=20; /* delta cross-track */ - setbits(rtcm->buff,i,21,ddeph[0]); i+=21; /* dot delta radial */ - setbits(rtcm->buff,i,19,ddeph[1]); i+=19; /* dot delta along-track */ - setbits(rtcm->buff,i,19,ddeph[2]); i+=19; /* dot delta cross-track */ - setbits(rtcm->buff,i,22,dclk [0]); i+=22; /* delta clock C0 */ - setbits(rtcm->buff,i,21,dclk [1]); i+=21; /* delta clock C1 */ - setbits(rtcm->buff,i,27,dclk [2]); i+=27; /* delta clock C2 */ - } - rtcm->nbit=i; - return 1; +static int encode_ssr4(rtcm_t *rtcm, int sys, int subtype, int sync) { + double udint = 0.0; + int i, j, iod = 0, nsat, prn, iode, iodcrc, refd = 0, np, ni, nj, offp; + int deph[3], ddeph[3], dclk[3]; + + trace(3, "encode_ssr4: sys=%d subtype=%d sync=%d\n", sys, subtype, sync); + + switch (sys) { + case SYS_GPS: + np = 6; + ni = 8; + nj = 0; + offp = 0; + break; + case SYS_GLO: + np = 5; + ni = 8; + nj = 0; + offp = 0; + break; + case SYS_GAL: + np = 6; + ni = 10; + nj = 0; + offp = 0; + break; + case SYS_QZS: + np = 4; + ni = 8; + nj = 0; + offp = 192; + break; + case SYS_CMP: + np = 6; + ni = 10; + nj = 24; + offp = 1; + break; + case SYS_SBS: + np = 6; + ni = 9; + nj = 24; + offp = 120; + break; + default: + return 0; + } + if (subtype > 0) { /* IGS SSR */ + np = 6; + ni = 8; + nj = 0; + if (sys == SYS_CMP) + offp = 0; + else if (sys == SYS_SBS) + offp = 119; + } + /* number of satellites */ + for (j = nsat = 0; j < MAXSAT; j++) { + if (satsys(j + 1, &prn) != sys || !rtcm->ssr[j].update) continue; + nsat++; + udint = rtcm->ssr[j].udi[0]; + iod = rtcm->ssr[j].iod[0]; + refd = rtcm->ssr[j].refd; + } + /* encode SSR header */ + i = encode_ssr_head(4, rtcm, sys, subtype, nsat, sync, iod, udint, refd, 0, 0); + + for (j = 0; j < MAXSAT; j++) { + if (satsys(j + 1, &prn) != sys || !rtcm->ssr[j].update) continue; + + iode = rtcm->ssr[j].iode; + iodcrc = rtcm->ssr[j].iodcrc; + + if (subtype > 0) { /* IGS SSR */ + iode &= 0xFF; + } + deph[0] = ROUND(rtcm->ssr[j].deph[0] / 1E-4); + deph[1] = ROUND(rtcm->ssr[j].deph[1] / 4E-4); + deph[2] = ROUND(rtcm->ssr[j].deph[2] / 4E-4); + ddeph[0] = ROUND(rtcm->ssr[j].ddeph[0] / 1E-6); + ddeph[1] = ROUND(rtcm->ssr[j].ddeph[1] / 4E-6); + ddeph[2] = ROUND(rtcm->ssr[j].ddeph[2] / 4E-6); + dclk[0] = ROUND(rtcm->ssr[j].dclk[0] / 1E-4); + dclk[1] = ROUND(rtcm->ssr[j].dclk[1] / 1E-6); + dclk[2] = ROUND(rtcm->ssr[j].dclk[2] / 2E-8); + + setbitu(rtcm->buff, i, np, prn - offp); + i += np; /* satellite ID */ + setbitu(rtcm->buff, i, ni, iode); + i += ni; /* IODE */ + setbitu(rtcm->buff, i, nj, iodcrc); + i += nj; /* IODCRC */ + setbits(rtcm->buff, i, 22, deph[0]); + i += 22; /* delta raidal */ + setbits(rtcm->buff, i, 20, deph[1]); + i += 20; /* delta along-track */ + setbits(rtcm->buff, i, 20, deph[2]); + i += 20; /* delta cross-track */ + setbits(rtcm->buff, i, 21, ddeph[0]); + i += 21; /* dot delta radial */ + setbits(rtcm->buff, i, 19, ddeph[1]); + i += 19; /* dot delta along-track */ + setbits(rtcm->buff, i, 19, ddeph[2]); + i += 19; /* dot delta cross-track */ + setbits(rtcm->buff, i, 22, dclk[0]); + i += 22; /* delta clock C0 */ + setbits(rtcm->buff, i, 21, dclk[1]); + i += 21; /* delta clock C1 */ + setbits(rtcm->buff, i, 27, dclk[2]); + i += 27; /* delta clock C2 */ + } + rtcm->nbit = i; + return 1; } /* encode SSR 5: URA ---------------------------------------------------------*/ -static int encode_ssr5(rtcm_t *rtcm, int sys, int subtype, int sync) -{ - double udint=0.0; - int i,j,nsat,iod=0,prn,ura,np,offp; - - trace(3,"encode_ssr5: sys=%d subtype=%d sync=%d\n",sys,subtype,sync); - - switch (sys) { - case SYS_GPS: np=6; offp= 0; break; - case SYS_GLO: np=5; offp= 0; break; - case SYS_GAL: np=6; offp= 0; break; - case SYS_QZS: np=4; offp=192; break; - case SYS_CMP: np=6; offp= 1; break; - case SYS_SBS: np=6; offp=120; break; - default: return 0; - } - if (subtype>0) { /* IGS SSR */ - np=6; - if (sys==SYS_CMP) offp=0; - else if (sys==SYS_SBS) offp=119; - } - /* number of satellites */ - for (j=nsat=0;jssr[j].update) continue; - nsat++; - udint=rtcm->ssr[j].udi[3]; - iod =rtcm->ssr[j].iod[3]; - } - /* encode ssr header */ - i=encode_ssr_head(5,rtcm,sys,subtype,nsat,sync,iod,udint,0,0,0); - - for (j=0;jssr[j].update) continue; - - ura=rtcm->ssr[j].ura; - setbitu(rtcm->buff,i,np,prn-offp); i+=np; /* satellite id */ - setbitu(rtcm->buff,i, 6,ura ); i+= 6; /* ssr ura */ - } - rtcm->nbit=i; - return 1; +static int encode_ssr5(rtcm_t *rtcm, int sys, int subtype, int sync) { + double udint = 0.0; + int i, j, nsat, iod = 0, prn, ura, np, offp; + + trace(3, "encode_ssr5: sys=%d subtype=%d sync=%d\n", sys, subtype, sync); + + switch (sys) { + case SYS_GPS: + np = 6; + offp = 0; + break; + case SYS_GLO: + np = 5; + offp = 0; + break; + case SYS_GAL: + np = 6; + offp = 0; + break; + case SYS_QZS: + np = 4; + offp = 192; + break; + case SYS_CMP: + np = 6; + offp = 1; + break; + case SYS_SBS: + np = 6; + offp = 120; + break; + default: + return 0; + } + if (subtype > 0) { /* IGS SSR */ + np = 6; + if (sys == SYS_CMP) + offp = 0; + else if (sys == SYS_SBS) + offp = 119; + } + /* number of satellites */ + for (j = nsat = 0; j < MAXSAT; j++) { + if (satsys(j + 1, &prn) != sys || !rtcm->ssr[j].update) continue; + nsat++; + udint = rtcm->ssr[j].udi[3]; + iod = rtcm->ssr[j].iod[3]; + } + /* encode ssr header */ + i = encode_ssr_head(5, rtcm, sys, subtype, nsat, sync, iod, udint, 0, 0, 0); + + for (j = 0; j < MAXSAT; j++) { + if (satsys(j + 1, &prn) != sys || !rtcm->ssr[j].update) continue; + + ura = rtcm->ssr[j].ura; + setbitu(rtcm->buff, i, np, prn - offp); + i += np; /* satellite id */ + setbitu(rtcm->buff, i, 6, ura); + i += 6; /* ssr ura */ + } + rtcm->nbit = i; + return 1; } /* encode SSR 6: high rate clock correction ----------------------------------*/ -static int encode_ssr6(rtcm_t *rtcm, int sys, int subtype, int sync) -{ - double udint=0.0; - int i,j,nsat,iod=0,prn,hrclk,np,offp; - - trace(3,"encode_ssr6: sys=%d subtype=%d sync=%d\n",sys,subtype,sync); - - switch (sys) { - case SYS_GPS: np=6; offp= 0; break; - case SYS_GLO: np=5; offp= 0; break; - case SYS_GAL: np=6; offp= 0; break; - case SYS_QZS: np=4; offp=192; break; - case SYS_CMP: np=6; offp= 1; break; - case SYS_SBS: np=6; offp=120; break; - default: return 0; - } - if (subtype>0) { /* IGS SSR */ - np=6; - if (sys==SYS_CMP) offp=0; - else if (sys==SYS_SBS) offp=119; - } - /* number of satellites */ - for (j=nsat=0;jssr[j].update) continue; - nsat++; - udint=rtcm->ssr[j].udi[2]; - iod =rtcm->ssr[j].iod[2]; - } - /* encode SSR header */ - i=encode_ssr_head(6,rtcm,sys,subtype,nsat,sync,iod,udint,0,0,0); - - for (j=0;jssr[j].update) continue; - - hrclk=ROUND(rtcm->ssr[j].hrclk/1E-4); - - setbitu(rtcm->buff,i,np,prn-offp); i+=np; /* satellite ID */ - setbits(rtcm->buff,i,22,hrclk ); i+=22; /* high rate clock corr */ - } - rtcm->nbit=i; - return 1; +static int encode_ssr6(rtcm_t *rtcm, int sys, int subtype, int sync) { + double udint = 0.0; + int i, j, nsat, iod = 0, prn, hrclk, np, offp; + + trace(3, "encode_ssr6: sys=%d subtype=%d sync=%d\n", sys, subtype, sync); + + switch (sys) { + case SYS_GPS: + np = 6; + offp = 0; + break; + case SYS_GLO: + np = 5; + offp = 0; + break; + case SYS_GAL: + np = 6; + offp = 0; + break; + case SYS_QZS: + np = 4; + offp = 192; + break; + case SYS_CMP: + np = 6; + offp = 1; + break; + case SYS_SBS: + np = 6; + offp = 120; + break; + default: + return 0; + } + if (subtype > 0) { /* IGS SSR */ + np = 6; + if (sys == SYS_CMP) + offp = 0; + else if (sys == SYS_SBS) + offp = 119; + } + /* number of satellites */ + for (j = nsat = 0; j < MAXSAT; j++) { + if (satsys(j + 1, &prn) != sys || !rtcm->ssr[j].update) continue; + nsat++; + udint = rtcm->ssr[j].udi[2]; + iod = rtcm->ssr[j].iod[2]; + } + /* encode SSR header */ + i = encode_ssr_head(6, rtcm, sys, subtype, nsat, sync, iod, udint, 0, 0, 0); + + for (j = 0; j < MAXSAT; j++) { + if (satsys(j + 1, &prn) != sys || !rtcm->ssr[j].update) continue; + + hrclk = ROUND(rtcm->ssr[j].hrclk / 1E-4); + + setbitu(rtcm->buff, i, np, prn - offp); + i += np; /* satellite ID */ + setbits(rtcm->buff, i, 22, hrclk); + i += 22; /* high rate clock corr */ + } + rtcm->nbit = i; + return 1; } /* encode SSR 7: satellite phase biases --------------------------------------*/ -static int encode_ssr7(rtcm_t *rtcm, int sys, int subtype, int sync) -{ - const int *codes; - double udint=0.0; - int i,j,k,iod=0,nsat,prn,nbias,np,offp; - int code[MAXCODE],pbias[MAXCODE],stdpb[MAXCODE],yaw_ang,yaw_rate; - - trace(3,"encode_ssr7: sys=%d subtype=%d sync=%d\n",sys,subtype,sync); - - switch (sys) { - case SYS_GPS: np=6; offp= 0; codes=codes_gps; break; - case SYS_GLO: np=5; offp= 0; codes=codes_glo; break; - case SYS_GAL: np=6; offp= 0; codes=codes_gal; break; - case SYS_QZS: np=4; offp=192; codes=codes_qzs; break; - case SYS_CMP: np=6; offp= 1; codes=codes_bds; break; - case SYS_SBS: np=6; offp=120; codes=codes_sbs; break; - default: return 0; - } - if (subtype>0) { /* IGS SSR */ - np=6; - if (sys==SYS_CMP) offp=0; - else if (sys==SYS_SBS) offp=119; - } - /* number of satellites */ - for (j=nsat=0;jssr[j].update) continue; - nsat++; - udint=rtcm->ssr[j].udi[5]; - iod =rtcm->ssr[j].iod[5]; - } - /* encode SSR header */ - i=encode_ssr_head(7,rtcm,sys,subtype,nsat,sync,iod,udint,0,0,0); - - for (j=0;jssr[j].update) continue; - - for (k=nbias=0;k<32;k++) { - if (!codes[k]||rtcm->ssr[j].pbias[codes[k]-1]==0.0) continue; - code[nbias]=k; - pbias[nbias ]=ROUND(rtcm->ssr[j].pbias[codes[k]-1]/0.0001); - stdpb[nbias++]=ROUND(rtcm->ssr[j].stdpb[codes[k]-1]/0.0001); - } - yaw_ang =ROUND(rtcm->ssr[j].yaw_ang /180.0* 256.0); - yaw_rate=ROUND(rtcm->ssr[j].yaw_rate/180.0*8192.0); - setbitu(rtcm->buff,i,np,prn-offp); i+=np; /* satellite ID */ - setbitu(rtcm->buff,i, 5,nbias); i+= 5; /* number of code biases */ - setbitu(rtcm->buff,i, 9,yaw_ang); i+= 9; /* yaw angle */ - setbits(rtcm->buff,i, 8,yaw_rate); i+= 8; /* yaw rate */ - - for (k=0;kbuff,i, 5,code[k] ); i+= 5; /* signal indicator */ - setbitu(rtcm->buff,i, 1,0 ); i+= 1; /* integer-indicator */ - setbitu(rtcm->buff,i, 2,0 ); i+= 2; /* WL integer-indicator */ - setbitu(rtcm->buff,i, 4,0 ); i+= 4; /* discont counter */ - setbits(rtcm->buff,i,20,pbias[k]); i+=20; /* phase bias */ - if (subtype==0) { - setbits(rtcm->buff,i,17,stdpb[k]); i+=17; /* std-dev ph-bias */ - } - } - } - rtcm->nbit=i; - return 1; +static int encode_ssr7(rtcm_t *rtcm, int sys, int subtype, int sync) { + const int *codes; + double udint = 0.0; + int i, j, k, iod = 0, nsat, prn, nbias, np, offp; + int code[MAXCODE], pbias[MAXCODE], stdpb[MAXCODE], yaw_ang, yaw_rate; + + trace(3, "encode_ssr7: sys=%d subtype=%d sync=%d\n", sys, subtype, sync); + + switch (sys) { + case SYS_GPS: + np = 6; + offp = 0; + codes = codes_gps; + break; + case SYS_GLO: + np = 5; + offp = 0; + codes = codes_glo; + break; + case SYS_GAL: + np = 6; + offp = 0; + codes = codes_gal; + break; + case SYS_QZS: + np = 4; + offp = 192; + codes = codes_qzs; + break; + case SYS_CMP: + np = 6; + offp = 1; + codes = codes_bds; + break; + case SYS_SBS: + np = 6; + offp = 120; + codes = codes_sbs; + break; + default: + return 0; + } + if (subtype > 0) { /* IGS SSR */ + np = 6; + if (sys == SYS_CMP) + offp = 0; + else if (sys == SYS_SBS) + offp = 119; + } + /* number of satellites */ + for (j = nsat = 0; j < MAXSAT; j++) { + if (satsys(j + 1, &prn) != sys || !rtcm->ssr[j].update) continue; + nsat++; + udint = rtcm->ssr[j].udi[5]; + iod = rtcm->ssr[j].iod[5]; + } + /* encode SSR header */ + i = encode_ssr_head(7, rtcm, sys, subtype, nsat, sync, iod, udint, 0, 0, 0); + + for (j = 0; j < MAXSAT; j++) { + if (satsys(j + 1, &prn) != sys || !rtcm->ssr[j].update) continue; + + for (k = nbias = 0; k < 32; k++) { + if (!codes[k] || rtcm->ssr[j].pbias[codes[k] - 1] == 0.0) continue; + code[nbias] = k; + pbias[nbias] = ROUND(rtcm->ssr[j].pbias[codes[k] - 1] / 0.0001); + stdpb[nbias++] = ROUND(rtcm->ssr[j].stdpb[codes[k] - 1] / 0.0001); + } + yaw_ang = ROUND(rtcm->ssr[j].yaw_ang / 180.0 * 256.0); + yaw_rate = ROUND(rtcm->ssr[j].yaw_rate / 180.0 * 8192.0); + setbitu(rtcm->buff, i, np, prn - offp); + i += np; /* satellite ID */ + setbitu(rtcm->buff, i, 5, nbias); + i += 5; /* number of code biases */ + setbitu(rtcm->buff, i, 9, yaw_ang); + i += 9; /* yaw angle */ + setbits(rtcm->buff, i, 8, yaw_rate); + i += 8; /* yaw rate */ + + for (k = 0; k < nbias; k++) { + setbitu(rtcm->buff, i, 5, code[k]); + i += 5; /* signal indicator */ + setbitu(rtcm->buff, i, 1, 0); + i += 1; /* integer-indicator */ + setbitu(rtcm->buff, i, 2, 0); + i += 2; /* WL integer-indicator */ + setbitu(rtcm->buff, i, 4, 0); + i += 4; /* discont counter */ + setbits(rtcm->buff, i, 20, pbias[k]); + i += 20; /* phase bias */ + if (subtype == 0) { + setbits(rtcm->buff, i, 17, stdpb[k]); + i += 17; /* std-dev ph-bias */ + } + } + } + rtcm->nbit = i; + return 1; } /* satellite no to MSM satellite ID ------------------------------------------*/ -static int to_satid(int sys, int sat) -{ - int prn; - - if (satsys(sat,&prn)!=sys) return 0; - - if (sys==SYS_QZS) prn-=MINPRNQZS-1; - else if (sys==SYS_SBS) prn-=MINPRNSBS-1; - - return prn; +static int to_satid(int sys, int sat) { + int prn; + + if (satsys(sat, &prn) != sys) return 0; + + if (sys == SYS_QZS) + prn -= MINPRNQZS - 1; + else if (sys == SYS_SBS) + prn -= MINPRNSBS - 1; + + return prn; } /* observation code to MSM signal ID -----------------------------------------*/ -static int to_sigid(int sys, uint8_t code) -{ - const char **msm_sig; - char *sig; - int i; - - /* signal conversion for undefined signal by rtcm */ - if (sys==SYS_GPS) { - if (code==CODE_L1Y) code=CODE_L1P; - else if (code==CODE_L1M) code=CODE_L1P; - else if (code==CODE_L1N) code=CODE_L1P; - else if (code==CODE_L2D) code=CODE_L2P; - else if (code==CODE_L2Y) code=CODE_L2P; - else if (code==CODE_L2M) code=CODE_L2P; - else if (code==CODE_L2N) code=CODE_L2P; - } - if (!*(sig=code2obs(code))) return 0; - - switch (sys) { - case SYS_GPS: msm_sig=msm_sig_gps; break; - case SYS_GLO: msm_sig=msm_sig_glo; break; - case SYS_GAL: msm_sig=msm_sig_gal; break; - case SYS_QZS: msm_sig=msm_sig_qzs; break; - case SYS_SBS: msm_sig=msm_sig_sbs; break; - case SYS_CMP: msm_sig=msm_sig_cmp; break; - case SYS_IRN: msm_sig=msm_sig_irn; break; - default: return 0; - } - for (i=0;i<32;i++) { - if (!strcmp(sig,msm_sig[i])) return i+1; - } - return 0; +static int to_sigid(int sys, uint8_t code) { + const char **msm_sig; + char *sig; + int i; + + /* signal conversion for undefined signal by rtcm */ + if (sys == SYS_GPS) { + if (code == CODE_L1Y) + code = CODE_L1P; + else if (code == CODE_L1M) + code = CODE_L1P; + else if (code == CODE_L1N) + code = CODE_L1P; + else if (code == CODE_L2D) + code = CODE_L2P; + else if (code == CODE_L2Y) + code = CODE_L2P; + else if (code == CODE_L2M) + code = CODE_L2P; + else if (code == CODE_L2N) + code = CODE_L2P; + } + if (!*(sig = code2obs(code))) return 0; + + switch (sys) { + case SYS_GPS: + msm_sig = msm_sig_gps; + break; + case SYS_GLO: + msm_sig = msm_sig_glo; + break; + case SYS_GAL: + msm_sig = msm_sig_gal; + break; + case SYS_QZS: + msm_sig = msm_sig_qzs; + break; + case SYS_SBS: + msm_sig = msm_sig_sbs; + break; + case SYS_CMP: + msm_sig = msm_sig_cmp; + break; + case SYS_IRN: + msm_sig = msm_sig_irn; + break; + default: + return 0; + } + for (i = 0; i < 32; i++) { + if (!strcmp(sig, msm_sig[i])) return i + 1; + } + return 0; } /* generate MSM satellite, signal and cell index -----------------------------*/ -static void gen_msm_index(const rtcm_t *rtcm, int sys, int *nsat, int *nsig, - int *ncell, uint8_t *sat_ind, uint8_t *sig_ind, - uint8_t *cell_ind) -{ - int i,j,sat,sig,cell; - - *nsat=*nsig=*ncell=0; - - /* generate satellite and signal index */ - for (i=0;iobs.n;i++) { - if (!(sat=to_satid(sys,rtcm->obs.data[i].sat))) continue; - - for (j=0;jobs.data[i].code[j]))) continue; - - sat_ind[sat-1]=sig_ind[sig-1]=1; - } - } - for (i=0;i<64;i++) { - if (sat_ind[i]) sat_ind[i]=++(*nsat); - } - for (i=0;i<32;i++) { - if (sig_ind[i]) sig_ind[i]=++(*nsig); - } - /* generate cell index */ - for (i=0;iobs.n;i++) { - if (!(sat=to_satid(sys,rtcm->obs.data[i].sat))) continue; - - for (j=0;jobs.data[i].code[j]))) continue; - - cell=sig_ind[sig-1]-1+(sat_ind[sat-1]-1)*(*nsig); - cell_ind[cell]=1; - } - } - for (i=0;i<*nsat*(*nsig);i++) { - if (cell_ind[i]&&*ncell<64) cell_ind[i]=++(*ncell); +static void gen_msm_index(const rtcm_t *rtcm, int sys, int *nsat, int *nsig, int *ncell, + uint8_t *sat_ind, uint8_t *sig_ind, uint8_t *cell_ind) { + int i, j, sat, sig, cell; + + *nsat = *nsig = *ncell = 0; + + /* generate satellite and signal index */ + for (i = 0; i < rtcm->obs.n; i++) { + if (!(sat = to_satid(sys, rtcm->obs.data[i].sat))) continue; + + for (j = 0; j < NFREQ + NEXOBS; j++) { + if (!(sig = to_sigid(sys, rtcm->obs.data[i].code[j]))) continue; + + sat_ind[sat - 1] = sig_ind[sig - 1] = 1; + } + } + for (i = 0; i < 64; i++) { + if (sat_ind[i]) sat_ind[i] = ++(*nsat); + } + for (i = 0; i < 32; i++) { + if (sig_ind[i]) sig_ind[i] = ++(*nsig); + } + /* generate cell index */ + for (i = 0; i < rtcm->obs.n; i++) { + if (!(sat = to_satid(sys, rtcm->obs.data[i].sat))) continue; + + for (j = 0; j < NFREQ + NEXOBS; j++) { + if (!(sig = to_sigid(sys, rtcm->obs.data[i].code[j]))) continue; + + cell = sig_ind[sig - 1] - 1 + (sat_ind[sat - 1] - 1) * (*nsig); + cell_ind[cell] = 1; } + } + for (i = 0; i < *nsat * (*nsig); i++) { + if (cell_ind[i] && *ncell < 64) cell_ind[i] = ++(*ncell); + } } /* generate MSM satellite data fields ----------------------------------------*/ -static void gen_msm_sat(rtcm_t *rtcm, int sys, int nsat, const uint8_t *sat_ind, - double *rrng, double *rrate, uint8_t *info) -{ - (void)nsat; - obsd_t *data; - double freq; - int i,j,k,sat,sig,fcn; - - for (i=0;i<64;i++) rrng[i]=rrate[i]=0.0; - - for (i=0;iobs.n;i++) { - data=rtcm->obs.data+i; - fcn=fcn_glo(data->sat,rtcm); /* fcn+7 */ - - if (!(sat=to_satid(sys,data->sat))) continue; - - for (j=0;jcode[j]))) continue; - k=sat_ind[sat-1]-1; - freq=code2freq(sys,data->code[j],fcn-7); - - /* rough range (ms) and rough phase-range-rate (m/s) */ - if (rrng[k]==0.0&&data->P[j]!=0.0) { - rrng[k]=ROUND( data->P[j]/RANGE_MS/P2_10)*RANGE_MS*P2_10; - } - if (rrate[k]==0.0&&data->D[j]!=0.0&&freq>0.0) { - rrate[k]=ROUND(-data->D[j]*CLIGHT/freq)*1.0; - } - /* extended satellite info */ - if (info) info[k]=sys!=SYS_GLO?0:(fcn<0?15:fcn); - } - } +static void gen_msm_sat(rtcm_t *rtcm, int sys, int nsat, const uint8_t *sat_ind, double *rrng, + double *rrate, uint8_t *info) { + (void)nsat; + obsd_t *data; + double freq; + int i, j, k, sat, sig, fcn; + + for (i = 0; i < 64; i++) rrng[i] = rrate[i] = 0.0; + + for (i = 0; i < rtcm->obs.n; i++) { + data = rtcm->obs.data + i; + fcn = fcn_glo(data->sat, rtcm); /* fcn+7 */ + + if (!(sat = to_satid(sys, data->sat))) continue; + + for (j = 0; j < NFREQ + NEXOBS; j++) { + if (!(sig = to_sigid(sys, data->code[j]))) continue; + k = sat_ind[sat - 1] - 1; + freq = code2freq(sys, data->code[j], fcn - 7); + + /* rough range (ms) and rough phase-range-rate (m/s) */ + if (rrng[k] == 0.0 && data->P[j] != 0.0) { + rrng[k] = ROUND(data->P[j] / RANGE_MS / P2_10) * RANGE_MS * P2_10; + } + if (rrate[k] == 0.0 && data->D[j] != 0.0 && freq > 0.0) { + rrate[k] = ROUND(-data->D[j] * CLIGHT / freq) * 1.0; + } + /* extended satellite info */ + if (info) info[k] = sys != SYS_GLO ? 0 : (fcn < 0 ? 15 : fcn); + } + } } /* generate MSM signal data fields -------------------------------------------*/ static void gen_msm_sig(rtcm_t *rtcm, int sys, int nsat, int nsig, int ncell, - const uint8_t *sat_ind, const uint8_t *sig_ind, - const uint8_t *cell_ind, const double *rrng, - const double *rrate, double *psrng, double *phrng, - double *rate, double *lock, uint8_t *half, float *cnr) -{ - (void)nsat; - obsd_t *data; - double freq,lambda,psrng_s,phrng_s,rate_s,lt; - int i,j,k,sat,sig,fcn,cell,LLI; - - for (i=0;iobs.n;i++) { - data=rtcm->obs.data+i; - fcn=fcn_glo(data->sat,rtcm); /* fcn+7 */ - - if (!(sat=to_satid(sys,data->sat))) continue; - - for (j=0;jcode[j]))) continue; - - k=sat_ind[sat-1]-1; - if ((cell=cell_ind[sig_ind[sig-1]-1+k*nsig])>=64) continue; - - freq=code2freq(sys,data->code[j],fcn-7); - lambda=freq==0.0?0.0:CLIGHT/freq; - psrng_s=data->P[j]==0.0?0.0:data->P[j]-rrng[k]; - phrng_s=data->L[j]==0.0||lambda<=0.0?0.0: data->L[j]*lambda-rrng [k]; - rate_s =data->D[j]==0.0||lambda<=0.0?0.0:-data->D[j]*lambda-rrate[k]; - - /* subtract phase - psudorange integer cycle offset */ - LLI=data->LLI[j]; - if ((LLI&1)||fabs(phrng_s-rtcm->cp[data->sat-1][j])>1171.0) { - rtcm->cp[data->sat-1][j]=ROUND(phrng_s/lambda)*lambda; - LLI|=1; - } - phrng_s-=rtcm->cp[data->sat-1][j]; - - lt=locktime_d(data->time,rtcm->lltime[data->sat-1]+j,LLI); - - if (psrng&&psrng_s!=0.0) psrng[cell-1]=psrng_s; - if (phrng&&phrng_s!=0.0) phrng[cell-1]=phrng_s; - if (rate &&rate_s !=0.0) rate [cell-1]=rate_s; - if (lock) lock[cell-1]=lt; - if (half) half[cell-1]=(data->LLI[j]&2)?1:0; - if (cnr ) cnr [cell-1]=data->SNR[j]; - } + const uint8_t *sat_ind, const uint8_t *sig_ind, const uint8_t *cell_ind, + const double *rrng, const double *rrate, double *psrng, double *phrng, + double *rate, double *lock, uint8_t *half, float *cnr) { + (void)nsat; + obsd_t *data; + double freq, lambda, psrng_s, phrng_s, rate_s, lt; + int i, j, k, sat, sig, fcn, cell, LLI; + + for (i = 0; i < ncell; i++) { + if (psrng) psrng[i] = 0.0; + if (phrng) phrng[i] = 0.0; + if (rate) rate[i] = 0.0; + } + for (i = 0; i < rtcm->obs.n; i++) { + data = rtcm->obs.data + i; + fcn = fcn_glo(data->sat, rtcm); /* fcn+7 */ + + if (!(sat = to_satid(sys, data->sat))) continue; + + for (j = 0; j < NFREQ + NEXOBS; j++) { + if (!(sig = to_sigid(sys, data->code[j]))) continue; + + k = sat_ind[sat - 1] - 1; + if ((cell = cell_ind[sig_ind[sig - 1] - 1 + k * nsig]) >= 64) continue; + + freq = code2freq(sys, data->code[j], fcn - 7); + lambda = freq == 0.0 ? 0.0 : CLIGHT / freq; + psrng_s = data->P[j] == 0.0 ? 0.0 : data->P[j] - rrng[k]; + phrng_s = data->L[j] == 0.0 || lambda <= 0.0 ? 0.0 : data->L[j] * lambda - rrng[k]; + rate_s = data->D[j] == 0.0 || lambda <= 0.0 ? 0.0 : -data->D[j] * lambda - rrate[k]; + + /* subtract phase - psudorange integer cycle offset */ + LLI = data->LLI[j]; + if ((LLI & 1) || fabs(phrng_s - rtcm->cp[data->sat - 1][j]) > 1171.0) { + rtcm->cp[data->sat - 1][j] = ROUND(phrng_s / lambda) * lambda; + LLI |= 1; + } + phrng_s -= rtcm->cp[data->sat - 1][j]; + + lt = locktime_d(data->time, rtcm->lltime[data->sat - 1] + j, LLI); + + if (psrng && psrng_s != 0.0) psrng[cell - 1] = psrng_s; + if (phrng && phrng_s != 0.0) phrng[cell - 1] = phrng_s; + if (rate && rate_s != 0.0) rate[cell - 1] = rate_s; + if (lock) lock[cell - 1] = lt; + if (half) half[cell - 1] = (data->LLI[j] & 2) ? 1 : 0; + if (cnr) cnr[cell - 1] = data->SNR[j]; } + } } /* encode MSM header ---------------------------------------------------------*/ -static int encode_msm_head(int type, rtcm_t *rtcm, int sys, int sync, int *nsat, - int *ncell, double *rrng, double *rrate, - uint8_t *info, double *psrng, double *phrng, - double *rate, double *lock, uint8_t *half, - float *cnr) -{ - double tow; - uint8_t sat_ind[64]={0},sig_ind[32]={0},cell_ind[32*64]={0}; - uint32_t dow,epoch; - int i=24,j,nsig=0; - - switch (sys) { - case SYS_GPS: type+=1070; break; - case SYS_GLO: type+=1080; break; - case SYS_GAL: type+=1090; break; - case SYS_QZS: type+=1110; break; - case SYS_SBS: type+=1100; break; - case SYS_CMP: type+=1120; break; - case SYS_IRN: type+=1130; break; - default: return 0; - } - /* generate msm satellite, signal and cell index */ - gen_msm_index(rtcm,sys,nsat,&nsig,ncell,sat_ind,sig_ind,cell_ind); - - if (sys==SYS_GLO) { - /* GLONASS time (dow + tod-ms) */ - tow=time2gpst(timeadd(gpst2utc(rtcm->time),10800.0),NULL); - dow=(uint32_t)(tow/86400.0); - epoch=(dow<<27)+ROUND_U(fmod(tow,86400.0)*1E3); - } - else if (sys==SYS_CMP) { - /* BDS time (tow-ms) */ - epoch=ROUND_U(time2gpst(gpst2bdt(rtcm->time),NULL)*1E3); - } - else { - /* GPS, QZSS, Galileo and IRNSS time (tow-ms) */ - epoch=ROUND_U(time2gpst(rtcm->time,NULL)*1E3); - } - /* encode msm header (ref [15] table 3.5-78) */ - setbitu(rtcm->buff,i,12,type ); i+=12; /* message number */ - setbitu(rtcm->buff,i,12,rtcm->staid); i+=12; /* reference station id */ - setbitu(rtcm->buff,i,30,epoch ); i+=30; /* epoch time */ - setbitu(rtcm->buff,i, 1,sync ); i+= 1; /* multiple message bit */ - setbitu(rtcm->buff,i, 3,rtcm->seqno); i+= 3; /* issue of data station */ - setbitu(rtcm->buff,i, 7,0 ); i+= 7; /* reserved */ - setbitu(rtcm->buff,i, 2,0 ); i+= 2; /* clock streering indicator */ - setbitu(rtcm->buff,i, 2,0 ); i+= 2; /* external clock indicator */ - setbitu(rtcm->buff,i, 1,0 ); i+= 1; /* smoothing indicator */ - setbitu(rtcm->buff,i, 3,0 ); i+= 3; /* smoothing interval */ - - /* satellite mask */ - for (j=0;j<64;j++) { - setbitu(rtcm->buff,i,1,sat_ind[j]?1:0); i+=1; - } - /* signal mask */ - for (j=0;j<32;j++) { - setbitu(rtcm->buff,i,1,sig_ind[j]?1:0); i+=1; - } - /* cell mask */ - for (j=0;j<*nsat*nsig&&j<64;j++) { - setbitu(rtcm->buff,i,1,cell_ind[j]?1:0); i+=1; - } - /* generate msm satellite data fields */ - gen_msm_sat(rtcm,sys,*nsat,sat_ind,rrng,rrate,info); - - /* generate msm signal data fields */ - gen_msm_sig(rtcm,sys,*nsat,nsig,*ncell,sat_ind,sig_ind,cell_ind,rrng,rrate, - psrng,phrng,rate,lock,half,cnr); - - return i; +static int encode_msm_head(int type, rtcm_t *rtcm, int sys, int sync, int *nsat, int *ncell, + double *rrng, double *rrate, uint8_t *info, double *psrng, double *phrng, + double *rate, double *lock, uint8_t *half, float *cnr) { + double tow; + uint8_t sat_ind[64] = {0}, sig_ind[32] = {0}, cell_ind[32 * 64] = {0}; + uint32_t dow, epoch; + int i = 24, j, nsig = 0; + + switch (sys) { + case SYS_GPS: + type += 1070; + break; + case SYS_GLO: + type += 1080; + break; + case SYS_GAL: + type += 1090; + break; + case SYS_QZS: + type += 1110; + break; + case SYS_SBS: + type += 1100; + break; + case SYS_CMP: + type += 1120; + break; + case SYS_IRN: + type += 1130; + break; + default: + return 0; + } + /* generate msm satellite, signal and cell index */ + gen_msm_index(rtcm, sys, nsat, &nsig, ncell, sat_ind, sig_ind, cell_ind); + + if (sys == SYS_GLO) { + /* GLONASS time (dow + tod-ms) */ + tow = time2gpst(timeadd(gpst2utc(rtcm->time), 10800.0), NULL); + dow = (uint32_t)(tow / 86400.0); + epoch = (dow << 27) + ROUND_U(fmod(tow, 86400.0) * 1E3); + } else if (sys == SYS_CMP) { + /* BDS time (tow-ms) */ + epoch = ROUND_U(time2gpst(gpst2bdt(rtcm->time), NULL) * 1E3); + } else { + /* GPS, QZSS, Galileo and IRNSS time (tow-ms) */ + epoch = ROUND_U(time2gpst(rtcm->time, NULL) * 1E3); + } + /* encode msm header (ref [15] table 3.5-78) */ + setbitu(rtcm->buff, i, 12, type); + i += 12; /* message number */ + setbitu(rtcm->buff, i, 12, rtcm->staid); + i += 12; /* reference station id */ + setbitu(rtcm->buff, i, 30, epoch); + i += 30; /* epoch time */ + setbitu(rtcm->buff, i, 1, sync); + i += 1; /* multiple message bit */ + setbitu(rtcm->buff, i, 3, rtcm->seqno); + i += 3; /* issue of data station */ + setbitu(rtcm->buff, i, 7, 0); + i += 7; /* reserved */ + setbitu(rtcm->buff, i, 2, 0); + i += 2; /* clock streering indicator */ + setbitu(rtcm->buff, i, 2, 0); + i += 2; /* external clock indicator */ + setbitu(rtcm->buff, i, 1, 0); + i += 1; /* smoothing indicator */ + setbitu(rtcm->buff, i, 3, 0); + i += 3; /* smoothing interval */ + + /* satellite mask */ + for (j = 0; j < 64; j++) { + setbitu(rtcm->buff, i, 1, sat_ind[j] ? 1 : 0); + i += 1; + } + /* signal mask */ + for (j = 0; j < 32; j++) { + setbitu(rtcm->buff, i, 1, sig_ind[j] ? 1 : 0); + i += 1; + } + /* cell mask */ + for (j = 0; j < *nsat * nsig && j < 64; j++) { + setbitu(rtcm->buff, i, 1, cell_ind[j] ? 1 : 0); + i += 1; + } + /* generate msm satellite data fields */ + gen_msm_sat(rtcm, sys, *nsat, sat_ind, rrng, rrate, info); + + /* generate msm signal data fields */ + gen_msm_sig(rtcm, sys, *nsat, nsig, *ncell, sat_ind, sig_ind, cell_ind, rrng, rrate, psrng, phrng, + rate, lock, half, cnr); + + return i; } /* encode rough range integer ms ---------------------------------------------*/ -static int encode_msm_int_rrng(rtcm_t *rtcm, int i, const double *rrng, - int nsat) -{ - uint32_t int_ms; - int j; - - for (j=0;jRANGE_MS*255.0) { - char tstr[40]; - trace(2,"msm rough range overflow %s rrng=%.3f\n", - time2str(rtcm->time,tstr,0),rrng[j]); - int_ms=255; - } - else { - int_ms=ROUND_U(rrng[j]/RANGE_MS/P2_10)>>10; - } - setbitu(rtcm->buff,i,8,int_ms); i+=8; - } - return i; +static int encode_msm_int_rrng(rtcm_t *rtcm, int i, const double *rrng, int nsat) { + uint32_t int_ms; + int j; + + for (j = 0; j < nsat; j++) { + if (rrng[j] == 0.0) { + int_ms = 255; + } else if (rrng[j] < 0.0 || rrng[j] > RANGE_MS * 255.0) { + char tstr[40]; + trace(2, "msm rough range overflow %s rrng=%.3f\n", time2str(rtcm->time, tstr, 0), rrng[j]); + int_ms = 255; + } else { + int_ms = ROUND_U(rrng[j] / RANGE_MS / P2_10) >> 10; + } + setbitu(rtcm->buff, i, 8, int_ms); + i += 8; + } + return i; } /* encode rough range modulo 1 ms --------------------------------------------*/ -static int encode_msm_mod_rrng(rtcm_t *rtcm, int i, const double *rrng, - int nsat) -{ - uint32_t mod_ms; - int j; - - for (j=0;jRANGE_MS*255.0) { - mod_ms=0; - } - else { - mod_ms=ROUND_U(rrng[j]/RANGE_MS/P2_10)&0x3FFu; - } - setbitu(rtcm->buff,i,10,mod_ms); i+=10; +static int encode_msm_mod_rrng(rtcm_t *rtcm, int i, const double *rrng, int nsat) { + uint32_t mod_ms; + int j; + + for (j = 0; j < nsat; j++) { + if (rrng[j] <= 0.0 || rrng[j] > RANGE_MS * 255.0) { + mod_ms = 0; + } else { + mod_ms = ROUND_U(rrng[j] / RANGE_MS / P2_10) & 0x3FFu; } - return i; + setbitu(rtcm->buff, i, 10, mod_ms); + i += 10; + } + return i; } /* encode extended satellite info --------------------------------------------*/ -static int encode_msm_info(rtcm_t *rtcm, int i, const uint8_t *info, int nsat) -{ - int j; - - for (j=0;jbuff,i,4,info[j]); i+=4; - } - return i; +static int encode_msm_info(rtcm_t *rtcm, int i, const uint8_t *info, int nsat) { + int j; + + for (j = 0; j < nsat; j++) { + setbitu(rtcm->buff, i, 4, info[j]); + i += 4; + } + return i; } /* encode rough phase-range-rate ---------------------------------------------*/ -static int encode_msm_rrate(rtcm_t *rtcm, int i, const double *rrate, int nsat) -{ - int j,rrate_val; - - for (j=0;j8191.0) { - char tstr[40]; - trace(2,"msm rough phase-range-rate overflow %s rrate=%.4f\n", - time2str(rtcm->time,tstr,0),rrate[j]); - rrate_val=-8192; - } - else { - rrate_val=ROUND(rrate[j]/1.0); - } - setbits(rtcm->buff,i,14,rrate_val); i+=14; - } - return i; +static int encode_msm_rrate(rtcm_t *rtcm, int i, const double *rrate, int nsat) { + int j, rrate_val; + + for (j = 0; j < nsat; j++) { + if (fabs(rrate[j]) > 8191.0) { + char tstr[40]; + trace(2, "msm rough phase-range-rate overflow %s rrate=%.4f\n", time2str(rtcm->time, tstr, 0), + rrate[j]); + rrate_val = -8192; + } else { + rrate_val = ROUND(rrate[j] / 1.0); + } + setbits(rtcm->buff, i, 14, rrate_val); + i += 14; + } + return i; } /* encode fine pseudorange ---------------------------------------------------*/ -static int encode_msm_psrng(rtcm_t *rtcm, int i, const double *psrng, int ncell) -{ - int j,psrng_val; - - for (j=0;j292.7) { - char tstr[40]; - trace(2,"msm fine pseudorange overflow %s psrng=%.3f\n", - time2str(rtcm->time,tstr,0),psrng[j]); - psrng_val=-16384; - } - else { - psrng_val=ROUND(psrng[j]/RANGE_MS/P2_24); - } - setbits(rtcm->buff,i,15,psrng_val); i+=15; - } - return i; +static int encode_msm_psrng(rtcm_t *rtcm, int i, const double *psrng, int ncell) { + int j, psrng_val; + + for (j = 0; j < ncell; j++) { + if (psrng[j] == 0.0) { + psrng_val = -16384; + } else if (fabs(psrng[j]) > 292.7) { + char tstr[40]; + trace(2, "msm fine pseudorange overflow %s psrng=%.3f\n", time2str(rtcm->time, tstr, 0), + psrng[j]); + psrng_val = -16384; + } else { + psrng_val = ROUND(psrng[j] / RANGE_MS / P2_24); + } + setbits(rtcm->buff, i, 15, psrng_val); + i += 15; + } + return i; } /* encode fine pseudorange with extended resolution --------------------------*/ -static int encode_msm_psrng_ex(rtcm_t *rtcm, int i, const double *psrng, - int ncell) -{ - int j,psrng_val; - - for (j=0;j292.7) { - char tstr[40]; - trace(2,"msm fine pseudorange ext overflow %s psrng=%.3f\n", - time2str(rtcm->time,tstr,0),psrng[j]); - psrng_val=-524288; - } - else { - psrng_val=ROUND(psrng[j]/RANGE_MS/P2_29); - } - setbits(rtcm->buff,i,20,psrng_val); i+=20; - } - return i; +static int encode_msm_psrng_ex(rtcm_t *rtcm, int i, const double *psrng, int ncell) { + int j, psrng_val; + + for (j = 0; j < ncell; j++) { + if (psrng[j] == 0.0) { + psrng_val = -524288; + } else if (fabs(psrng[j]) > 292.7) { + char tstr[40]; + trace(2, "msm fine pseudorange ext overflow %s psrng=%.3f\n", time2str(rtcm->time, tstr, 0), + psrng[j]); + psrng_val = -524288; + } else { + psrng_val = ROUND(psrng[j] / RANGE_MS / P2_29); + } + setbits(rtcm->buff, i, 20, psrng_val); + i += 20; + } + return i; } /* encode fine phase-range ---------------------------------------------------*/ -static int encode_msm_phrng(rtcm_t *rtcm, int i, const double *phrng, int ncell) -{ - int j,phrng_val; - - for (j=0;j1171.0) { - char tstr[40]; - trace(2,"msm fine phase-range overflow %s phrng=%.3f\n", - time2str(rtcm->time,tstr,0),phrng[j]); - phrng_val=-2097152; - } - else { - phrng_val=ROUND(phrng[j]/RANGE_MS/P2_29); - } - setbits(rtcm->buff,i,22,phrng_val); i+=22; - } - return i; +static int encode_msm_phrng(rtcm_t *rtcm, int i, const double *phrng, int ncell) { + int j, phrng_val; + + for (j = 0; j < ncell; j++) { + if (phrng[j] == 0.0) { + phrng_val = -2097152; + } else if (fabs(phrng[j]) > 1171.0) { + char tstr[40]; + trace(2, "msm fine phase-range overflow %s phrng=%.3f\n", time2str(rtcm->time, tstr, 0), + phrng[j]); + phrng_val = -2097152; + } else { + phrng_val = ROUND(phrng[j] / RANGE_MS / P2_29); + } + setbits(rtcm->buff, i, 22, phrng_val); + i += 22; + } + return i; } /* encode fine phase-range with extended resolution --------------------------*/ -static int encode_msm_phrng_ex(rtcm_t *rtcm, int i, const double *phrng, - int ncell) -{ - int j,phrng_val; - - for (j=0;j1171.0) { - char tstr[40]; - trace(2,"msm fine phase-range ext overflow %s phrng=%.3f\n", - time2str(rtcm->time,tstr,0),phrng[j]); - phrng_val=-8388608; - } - else { - phrng_val=ROUND(phrng[j]/RANGE_MS/P2_31); - } - setbits(rtcm->buff,i,24,phrng_val); i+=24; - } - return i; +static int encode_msm_phrng_ex(rtcm_t *rtcm, int i, const double *phrng, int ncell) { + int j, phrng_val; + + for (j = 0; j < ncell; j++) { + if (phrng[j] == 0.0) { + phrng_val = -8388608; + } else if (fabs(phrng[j]) > 1171.0) { + char tstr[40]; + trace(2, "msm fine phase-range ext overflow %s phrng=%.3f\n", time2str(rtcm->time, tstr, 0), + phrng[j]); + phrng_val = -8388608; + } else { + phrng_val = ROUND(phrng[j] / RANGE_MS / P2_31); + } + setbits(rtcm->buff, i, 24, phrng_val); + i += 24; + } + return i; } /* encode lock-time indicator ------------------------------------------------*/ -static int encode_msm_lock(rtcm_t *rtcm, int i, const double *lock, int ncell) -{ - int j,lock_val; - - for (j=0;jbuff,i,4,lock_val); i+=4; - } - return i; +static int encode_msm_lock(rtcm_t *rtcm, int i, const double *lock, int ncell) { + int j, lock_val; + + for (j = 0; j < ncell; j++) { + lock_val = to_msm_lock(lock[j]); + setbitu(rtcm->buff, i, 4, lock_val); + i += 4; + } + return i; } /* encode lock-time indicator with extended range and resolution -------------*/ -static int encode_msm_lock_ex(rtcm_t *rtcm, int i, const double *lock, - int ncell) -{ - int j,lock_val; - - for (j=0;jbuff,i,10,lock_val); i+=10; - } - return i; +static int encode_msm_lock_ex(rtcm_t *rtcm, int i, const double *lock, int ncell) { + int j, lock_val; + + for (j = 0; j < ncell; j++) { + lock_val = to_msm_lock_ex(lock[j]); + setbitu(rtcm->buff, i, 10, lock_val); + i += 10; + } + return i; } /* encode half-cycle-ambiguity indicator -------------------------------------*/ -static int encode_msm_half_amb(rtcm_t *rtcm, int i, const uint8_t *half, - int ncell) -{ - int j; - - for (j=0;jbuff,i,1,half[j]); i+=1; - } - return i; +static int encode_msm_half_amb(rtcm_t *rtcm, int i, const uint8_t *half, int ncell) { + int j; + + for (j = 0; j < ncell; j++) { + setbitu(rtcm->buff, i, 1, half[j]); + i += 1; + } + return i; } /* encode signal CNR ---------------------------------------------------------*/ -static int encode_msm_cnr(rtcm_t *rtcm, int i, const float *cnr, int ncell) -{ - int j,cnr_val; - - for (j=0;jbuff,i,6,cnr_val); i+=6; - } - return i; +static int encode_msm_cnr(rtcm_t *rtcm, int i, const float *cnr, int ncell) { + int j, cnr_val; + + for (j = 0; j < ncell; j++) { + cnr_val = ROUND(cnr[j] / 1.0); + setbitu(rtcm->buff, i, 6, cnr_val); + i += 6; + } + return i; } /* encode signal CNR with extended resolution --------------------------------*/ -static int encode_msm_cnr_ex(rtcm_t *rtcm, int i, const float *cnr, int ncell) -{ - int j,cnr_val; - - for (j=0;jbuff,i,10,cnr_val); i+=10; - } - return i; +static int encode_msm_cnr_ex(rtcm_t *rtcm, int i, const float *cnr, int ncell) { + int j, cnr_val; + + for (j = 0; j < ncell; j++) { + cnr_val = ROUND(cnr[j] / 0.0625); + setbitu(rtcm->buff, i, 10, cnr_val); + i += 10; + } + return i; } /* encode fine phase-range-rate ----------------------------------------------*/ -static int encode_msm_rate(rtcm_t *rtcm, int i, const double *rate, int ncell) -{ - int j,rate_val; - - for (j=0;j1.6384) { - char tstr[40]; - trace(2,"msm fine phase-range-rate overflow %s rate=%.3f\n", - time2str(rtcm->time,tstr,0),rate[j]); - rate_val=-16384; - } - else { - rate_val=ROUND(rate[j]/0.0001); - } - setbitu(rtcm->buff,i,15,rate_val); i+=15; - } - return i; +static int encode_msm_rate(rtcm_t *rtcm, int i, const double *rate, int ncell) { + int j, rate_val; + + for (j = 0; j < ncell; j++) { + if (rate[j] == 0.0) { + rate_val = -16384; + } else if (fabs(rate[j]) > 1.6384) { + char tstr[40]; + trace(2, "msm fine phase-range-rate overflow %s rate=%.3f\n", time2str(rtcm->time, tstr, 0), + rate[j]); + rate_val = -16384; + } else { + rate_val = ROUND(rate[j] / 0.0001); + } + setbitu(rtcm->buff, i, 15, rate_val); + i += 15; + } + return i; } /* encode MSM 1: compact pseudorange -----------------------------------------*/ -static int encode_msm1(rtcm_t *rtcm, int sys, int sync) -{ - double rrng[64],rrate[64],psrng[64]; - int i,nsat,ncell; - - trace(3,"encode_msm1: sys=%d sync=%d\n",sys,sync); - - /* encode msm header */ - if (!(i=encode_msm_head(1,rtcm,sys,sync,&nsat,&ncell,rrng,rrate,NULL,psrng, - NULL,NULL,NULL,NULL,NULL))) { - return 0; - } - /* encode msm satellite data */ - i=encode_msm_mod_rrng(rtcm,i,rrng ,nsat ); /* rough range modulo 1 ms */ - - /* encode msm signal data */ - i=encode_msm_psrng (rtcm,i,psrng,ncell); /* fine pseudorange */ - - rtcm->nbit=i; - return 1; +static int encode_msm1(rtcm_t *rtcm, int sys, int sync) { + double rrng[64], rrate[64], psrng[64]; + int i, nsat, ncell; + + trace(3, "encode_msm1: sys=%d sync=%d\n", sys, sync); + + /* encode msm header */ + if (!(i = encode_msm_head(1, rtcm, sys, sync, &nsat, &ncell, rrng, rrate, NULL, psrng, NULL, NULL, + NULL, NULL, NULL))) { + return 0; + } + /* encode msm satellite data */ + i = encode_msm_mod_rrng(rtcm, i, rrng, nsat); /* rough range modulo 1 ms */ + + /* encode msm signal data */ + i = encode_msm_psrng(rtcm, i, psrng, ncell); /* fine pseudorange */ + + rtcm->nbit = i; + return 1; } /* encode MSM 2: compact phaserange ------------------------------------------*/ -static int encode_msm2(rtcm_t *rtcm, int sys, int sync) -{ - double rrng[64],rrate[64],phrng[64],lock[64]; - uint8_t half[64]; - int i,nsat,ncell; - - trace(3,"encode_msm2: sys=%d sync=%d\n",sys,sync); - - /* encode msm header */ - if (!(i=encode_msm_head(2,rtcm,sys,sync,&nsat,&ncell,rrng,rrate,NULL,NULL, - phrng,NULL,lock,half,NULL))) { - return 0; - } - /* encode msm satellite data */ - i=encode_msm_mod_rrng(rtcm,i,rrng ,nsat ); /* rough range modulo 1 ms */ - - /* encode msm signal data */ - i=encode_msm_phrng (rtcm,i,phrng,ncell); /* fine phase-range */ - i=encode_msm_lock (rtcm,i,lock ,ncell); /* lock-time indicator */ - i=encode_msm_half_amb(rtcm,i,half ,ncell); /* half-cycle-amb indicator */ - - rtcm->nbit=i; - return 1; +static int encode_msm2(rtcm_t *rtcm, int sys, int sync) { + double rrng[64], rrate[64], phrng[64], lock[64]; + uint8_t half[64]; + int i, nsat, ncell; + + trace(3, "encode_msm2: sys=%d sync=%d\n", sys, sync); + + /* encode msm header */ + if (!(i = encode_msm_head(2, rtcm, sys, sync, &nsat, &ncell, rrng, rrate, NULL, NULL, phrng, NULL, + lock, half, NULL))) { + return 0; + } + /* encode msm satellite data */ + i = encode_msm_mod_rrng(rtcm, i, rrng, nsat); /* rough range modulo 1 ms */ + + /* encode msm signal data */ + i = encode_msm_phrng(rtcm, i, phrng, ncell); /* fine phase-range */ + i = encode_msm_lock(rtcm, i, lock, ncell); /* lock-time indicator */ + i = encode_msm_half_amb(rtcm, i, half, ncell); /* half-cycle-amb indicator */ + + rtcm->nbit = i; + return 1; } /* encode MSM 3: compact pseudorange and phaserange --------------------------*/ -static int encode_msm3(rtcm_t *rtcm, int sys, int sync) -{ - double rrng[64],rrate[64],psrng[64],phrng[64],lock[64]; - uint8_t half[64]; - int i,nsat,ncell; - - trace(3,"encode_msm3: sys=%d sync=%d\n",sys,sync); - - /* encode msm header */ - if (!(i=encode_msm_head(3,rtcm,sys,sync,&nsat,&ncell,rrng,rrate,NULL,psrng, - phrng,NULL,lock,half,NULL))) { - return 0; - } - /* encode msm satellite data */ - i=encode_msm_mod_rrng(rtcm,i,rrng ,nsat ); /* rough range modulo 1 ms */ - - /* encode msm signal data */ - i=encode_msm_psrng (rtcm,i,psrng,ncell); /* fine pseudorange */ - i=encode_msm_phrng (rtcm,i,phrng,ncell); /* fine phase-range */ - i=encode_msm_lock (rtcm,i,lock ,ncell); /* lock-time indicator */ - i=encode_msm_half_amb(rtcm,i,half ,ncell); /* half-cycle-amb indicator */ - - rtcm->nbit=i; - return 1; +static int encode_msm3(rtcm_t *rtcm, int sys, int sync) { + double rrng[64], rrate[64], psrng[64], phrng[64], lock[64]; + uint8_t half[64]; + int i, nsat, ncell; + + trace(3, "encode_msm3: sys=%d sync=%d\n", sys, sync); + + /* encode msm header */ + if (!(i = encode_msm_head(3, rtcm, sys, sync, &nsat, &ncell, rrng, rrate, NULL, psrng, phrng, + NULL, lock, half, NULL))) { + return 0; + } + /* encode msm satellite data */ + i = encode_msm_mod_rrng(rtcm, i, rrng, nsat); /* rough range modulo 1 ms */ + + /* encode msm signal data */ + i = encode_msm_psrng(rtcm, i, psrng, ncell); /* fine pseudorange */ + i = encode_msm_phrng(rtcm, i, phrng, ncell); /* fine phase-range */ + i = encode_msm_lock(rtcm, i, lock, ncell); /* lock-time indicator */ + i = encode_msm_half_amb(rtcm, i, half, ncell); /* half-cycle-amb indicator */ + + rtcm->nbit = i; + return 1; } /* encode MSM 4: full pseudorange and phaserange plus CNR --------------------*/ -static int encode_msm4(rtcm_t *rtcm, int sys, int sync) -{ - double rrng[64],rrate[64],psrng[64],phrng[64],lock[64]; - float cnr[64]; - uint8_t half[64]; - int i,nsat,ncell; - - trace(3,"encode_msm4: sys=%d sync=%d\n",sys,sync); - - /* encode msm header */ - if (!(i=encode_msm_head(4,rtcm,sys,sync,&nsat,&ncell,rrng,rrate,NULL,psrng, - phrng,NULL,lock,half,cnr))) { - return 0; - } - /* encode msm satellite data */ - i=encode_msm_int_rrng(rtcm,i,rrng ,nsat ); /* rough range integer ms */ - i=encode_msm_mod_rrng(rtcm,i,rrng ,nsat ); /* rough range modulo 1 ms */ - - /* encode msm signal data */ - i=encode_msm_psrng (rtcm,i,psrng,ncell); /* fine pseudorange */ - i=encode_msm_phrng (rtcm,i,phrng,ncell); /* fine phase-range */ - i=encode_msm_lock (rtcm,i,lock ,ncell); /* lock-time indicator */ - i=encode_msm_half_amb(rtcm,i,half ,ncell); /* half-cycle-amb indicator */ - i=encode_msm_cnr (rtcm,i,cnr ,ncell); /* signal cnr */ - rtcm->nbit=i; - return 1; +static int encode_msm4(rtcm_t *rtcm, int sys, int sync) { + double rrng[64], rrate[64], psrng[64], phrng[64], lock[64]; + float cnr[64]; + uint8_t half[64]; + int i, nsat, ncell; + + trace(3, "encode_msm4: sys=%d sync=%d\n", sys, sync); + + /* encode msm header */ + if (!(i = encode_msm_head(4, rtcm, sys, sync, &nsat, &ncell, rrng, rrate, NULL, psrng, phrng, + NULL, lock, half, cnr))) { + return 0; + } + /* encode msm satellite data */ + i = encode_msm_int_rrng(rtcm, i, rrng, nsat); /* rough range integer ms */ + i = encode_msm_mod_rrng(rtcm, i, rrng, nsat); /* rough range modulo 1 ms */ + + /* encode msm signal data */ + i = encode_msm_psrng(rtcm, i, psrng, ncell); /* fine pseudorange */ + i = encode_msm_phrng(rtcm, i, phrng, ncell); /* fine phase-range */ + i = encode_msm_lock(rtcm, i, lock, ncell); /* lock-time indicator */ + i = encode_msm_half_amb(rtcm, i, half, ncell); /* half-cycle-amb indicator */ + i = encode_msm_cnr(rtcm, i, cnr, ncell); /* signal cnr */ + rtcm->nbit = i; + return 1; } /* encode MSM 5: full pseudorange, phaserange, phaserangerate and CNR --------*/ -static int encode_msm5(rtcm_t *rtcm, int sys, int sync) -{ - double rrng[64],rrate[64],psrng[64],phrng[64],rate[64],lock[64]; - float cnr[64]; - uint8_t info[64],half[64]; - int i,nsat,ncell; - - trace(3,"encode_msm5: sys=%d sync=%d\n",sys,sync); - - /* encode msm header */ - if (!(i=encode_msm_head(5,rtcm,sys,sync,&nsat,&ncell,rrng,rrate,info,psrng, - phrng,rate,lock,half,cnr))) { - return 0; - } - /* encode msm satellite data */ - i=encode_msm_int_rrng(rtcm,i,rrng ,nsat ); /* rough range integer ms */ - i=encode_msm_info (rtcm,i,info ,nsat ); /* extended satellite info */ - i=encode_msm_mod_rrng(rtcm,i,rrng ,nsat ); /* rough range modulo 1 ms */ - i=encode_msm_rrate (rtcm,i,rrate,nsat ); /* rough phase-range-rate */ - - /* encode msm signal data */ - i=encode_msm_psrng (rtcm,i,psrng,ncell); /* fine pseudorange */ - i=encode_msm_phrng (rtcm,i,phrng,ncell); /* fine phase-range */ - i=encode_msm_lock (rtcm,i,lock ,ncell); /* lock-time indicator */ - i=encode_msm_half_amb(rtcm,i,half ,ncell); /* half-cycle-amb indicator */ - i=encode_msm_cnr (rtcm,i,cnr ,ncell); /* signal cnr */ - i=encode_msm_rate (rtcm,i,rate ,ncell); /* fine phase-range-rate */ - rtcm->nbit=i; - return 1; +static int encode_msm5(rtcm_t *rtcm, int sys, int sync) { + double rrng[64], rrate[64], psrng[64], phrng[64], rate[64], lock[64]; + float cnr[64]; + uint8_t info[64], half[64]; + int i, nsat, ncell; + + trace(3, "encode_msm5: sys=%d sync=%d\n", sys, sync); + + /* encode msm header */ + if (!(i = encode_msm_head(5, rtcm, sys, sync, &nsat, &ncell, rrng, rrate, info, psrng, phrng, + rate, lock, half, cnr))) { + return 0; + } + /* encode msm satellite data */ + i = encode_msm_int_rrng(rtcm, i, rrng, nsat); /* rough range integer ms */ + i = encode_msm_info(rtcm, i, info, nsat); /* extended satellite info */ + i = encode_msm_mod_rrng(rtcm, i, rrng, nsat); /* rough range modulo 1 ms */ + i = encode_msm_rrate(rtcm, i, rrate, nsat); /* rough phase-range-rate */ + + /* encode msm signal data */ + i = encode_msm_psrng(rtcm, i, psrng, ncell); /* fine pseudorange */ + i = encode_msm_phrng(rtcm, i, phrng, ncell); /* fine phase-range */ + i = encode_msm_lock(rtcm, i, lock, ncell); /* lock-time indicator */ + i = encode_msm_half_amb(rtcm, i, half, ncell); /* half-cycle-amb indicator */ + i = encode_msm_cnr(rtcm, i, cnr, ncell); /* signal cnr */ + i = encode_msm_rate(rtcm, i, rate, ncell); /* fine phase-range-rate */ + rtcm->nbit = i; + return 1; } /* encode MSM 6: full pseudorange and phaserange plus CNR (high-res) ---------*/ -static int encode_msm6(rtcm_t *rtcm, int sys, int sync) -{ - double rrng[64],rrate[64],psrng[64],phrng[64],lock[64]; - float cnr[64]; - uint8_t half[64]; - int i,nsat,ncell; - - trace(3,"encode_msm6: sys=%d sync=%d\n",sys,sync); - - /* encode msm header */ - if (!(i=encode_msm_head(6,rtcm,sys,sync,&nsat,&ncell,rrng,rrate,NULL,psrng, - phrng,NULL,lock,half,cnr))) { - return 0; - } - /* encode msm satellite data */ - i=encode_msm_int_rrng(rtcm,i,rrng ,nsat ); /* rough range integer ms */ - i=encode_msm_mod_rrng(rtcm,i,rrng ,nsat ); /* rough range modulo 1 ms */ - - /* encode msm signal data */ - i=encode_msm_psrng_ex(rtcm,i,psrng,ncell); /* fine pseudorange ext */ - i=encode_msm_phrng_ex(rtcm,i,phrng,ncell); /* fine phase-range ext */ - i=encode_msm_lock_ex (rtcm,i,lock ,ncell); /* lock-time indicator ext */ - i=encode_msm_half_amb(rtcm,i,half ,ncell); /* half-cycle-amb indicator */ - i=encode_msm_cnr_ex (rtcm,i,cnr ,ncell); /* signal cnr ext */ - rtcm->nbit=i; - return 1; +static int encode_msm6(rtcm_t *rtcm, int sys, int sync) { + double rrng[64], rrate[64], psrng[64], phrng[64], lock[64]; + float cnr[64]; + uint8_t half[64]; + int i, nsat, ncell; + + trace(3, "encode_msm6: sys=%d sync=%d\n", sys, sync); + + /* encode msm header */ + if (!(i = encode_msm_head(6, rtcm, sys, sync, &nsat, &ncell, rrng, rrate, NULL, psrng, phrng, + NULL, lock, half, cnr))) { + return 0; + } + /* encode msm satellite data */ + i = encode_msm_int_rrng(rtcm, i, rrng, nsat); /* rough range integer ms */ + i = encode_msm_mod_rrng(rtcm, i, rrng, nsat); /* rough range modulo 1 ms */ + + /* encode msm signal data */ + i = encode_msm_psrng_ex(rtcm, i, psrng, ncell); /* fine pseudorange ext */ + i = encode_msm_phrng_ex(rtcm, i, phrng, ncell); /* fine phase-range ext */ + i = encode_msm_lock_ex(rtcm, i, lock, ncell); /* lock-time indicator ext */ + i = encode_msm_half_amb(rtcm, i, half, ncell); /* half-cycle-amb indicator */ + i = encode_msm_cnr_ex(rtcm, i, cnr, ncell); /* signal cnr ext */ + rtcm->nbit = i; + return 1; } /* encode MSM 7: full pseudorange, phaserange, phaserangerate and CNR (h-res) */ -static int encode_msm7(rtcm_t *rtcm, int sys, int sync) -{ - double rrng[64],rrate[64],psrng[64],phrng[64],rate[64],lock[64]; - float cnr[64]; - uint8_t info[64],half[64]; - int i,nsat,ncell; - - trace(3,"encode_msm7: sys=%d sync=%d\n",sys,sync); - - /* encode msm header */ - if (!(i=encode_msm_head(7,rtcm,sys,sync,&nsat,&ncell,rrng,rrate,info,psrng, - phrng,rate,lock,half,cnr))) { - return 0; - } - /* encode msm satellite data */ - i=encode_msm_int_rrng(rtcm,i,rrng ,nsat ); /* rough range integer ms */ - i=encode_msm_info (rtcm,i,info ,nsat ); /* extended satellite info */ - i=encode_msm_mod_rrng(rtcm,i,rrng ,nsat ); /* rough range modulo 1 ms */ - i=encode_msm_rrate (rtcm,i,rrate,nsat ); /* rough phase-range-rate */ - - /* encode msm signal data */ - i=encode_msm_psrng_ex(rtcm,i,psrng,ncell); /* fine pseudorange ext */ - i=encode_msm_phrng_ex(rtcm,i,phrng,ncell); /* fine phase-range ext */ - i=encode_msm_lock_ex (rtcm,i,lock ,ncell); /* lock-time indicator ext */ - i=encode_msm_half_amb(rtcm,i,half ,ncell); /* half-cycle-amb indicator */ - i=encode_msm_cnr_ex (rtcm,i,cnr ,ncell); /* signal cnr ext */ - i=encode_msm_rate (rtcm,i,rate ,ncell); /* fine phase-range-rate */ - rtcm->nbit=i; - return 1; +static int encode_msm7(rtcm_t *rtcm, int sys, int sync) { + double rrng[64], rrate[64], psrng[64], phrng[64], rate[64], lock[64]; + float cnr[64]; + uint8_t info[64], half[64]; + int i, nsat, ncell; + + trace(3, "encode_msm7: sys=%d sync=%d\n", sys, sync); + + /* encode msm header */ + if (!(i = encode_msm_head(7, rtcm, sys, sync, &nsat, &ncell, rrng, rrate, info, psrng, phrng, + rate, lock, half, cnr))) { + return 0; + } + /* encode msm satellite data */ + i = encode_msm_int_rrng(rtcm, i, rrng, nsat); /* rough range integer ms */ + i = encode_msm_info(rtcm, i, info, nsat); /* extended satellite info */ + i = encode_msm_mod_rrng(rtcm, i, rrng, nsat); /* rough range modulo 1 ms */ + i = encode_msm_rrate(rtcm, i, rrate, nsat); /* rough phase-range-rate */ + + /* encode msm signal data */ + i = encode_msm_psrng_ex(rtcm, i, psrng, ncell); /* fine pseudorange ext */ + i = encode_msm_phrng_ex(rtcm, i, phrng, ncell); /* fine phase-range ext */ + i = encode_msm_lock_ex(rtcm, i, lock, ncell); /* lock-time indicator ext */ + i = encode_msm_half_amb(rtcm, i, half, ncell); /* half-cycle-amb indicator */ + i = encode_msm_cnr_ex(rtcm, i, cnr, ncell); /* signal cnr ext */ + i = encode_msm_rate(rtcm, i, rate, ncell); /* fine phase-range-rate */ + rtcm->nbit = i; + return 1; } /* encode type 1230: GLONASS L1 and L2 code-phase biases ---------------------*/ -static int encode_type1230(rtcm_t *rtcm, int sync) -{ - int i=24,j,align,mask=15,bias[4]; - - trace(3,"encode_type1230: sync=%d\n",sync); - - align=rtcm->sta.glo_cp_align; - - for (j=0;j<4;j++) { - bias[j]=ROUND(rtcm->sta.glo_cp_bias[j]/0.02); - if (bias[j]<=-32768||bias[j]>32767) { - bias[j]=-32768; /* invalid value */ - } - } - setbitu(rtcm->buff,i,12,1230 ); i+=12; /* message no */ - setbitu(rtcm->buff,i,12,rtcm->staid); i+=12; /* station ID */ - setbitu(rtcm->buff,i, 1,align ); i+= 1; /* GLO code-phase bias ind */ - setbitu(rtcm->buff,i, 3,0 ); i+= 3; /* reserved */ - setbitu(rtcm->buff,i, 4,mask ); i+= 4; /* GLO FDMA signals mask */ - setbits(rtcm->buff,i,16,bias[0] ); i+=16; /* GLO C1 code-phase bias */ - setbits(rtcm->buff,i,16,bias[1] ); i+=16; /* GLO P1 code-phase bias */ - setbits(rtcm->buff,i,16,bias[2] ); i+=16; /* GLO C2 code-phase bias */ - setbits(rtcm->buff,i,16,bias[3] ); i+=16; /* GLO P2 code-phase bias */ - rtcm->nbit=i; - return 1; +static int encode_type1230(rtcm_t *rtcm, int sync) { + int i = 24, j, align, mask = 15, bias[4]; + + trace(3, "encode_type1230: sync=%d\n", sync); + + align = rtcm->sta.glo_cp_align; + + for (j = 0; j < 4; j++) { + bias[j] = ROUND(rtcm->sta.glo_cp_bias[j] / 0.02); + if (bias[j] <= -32768 || bias[j] > 32767) { + bias[j] = -32768; /* invalid value */ + } + } + setbitu(rtcm->buff, i, 12, 1230); + i += 12; /* message no */ + setbitu(rtcm->buff, i, 12, rtcm->staid); + i += 12; /* station ID */ + setbitu(rtcm->buff, i, 1, align); + i += 1; /* GLO code-phase bias ind */ + setbitu(rtcm->buff, i, 3, 0); + i += 3; /* reserved */ + setbitu(rtcm->buff, i, 4, mask); + i += 4; /* GLO FDMA signals mask */ + setbits(rtcm->buff, i, 16, bias[0]); + i += 16; /* GLO C1 code-phase bias */ + setbits(rtcm->buff, i, 16, bias[1]); + i += 16; /* GLO P1 code-phase bias */ + setbits(rtcm->buff, i, 16, bias[2]); + i += 16; /* GLO C2 code-phase bias */ + setbits(rtcm->buff, i, 16, bias[3]); + i += 16; /* GLO P2 code-phase bias */ + rtcm->nbit = i; + return 1; } /* encode type 4073: proprietary message Mitsubishi Electric -----------------*/ -static int encode_type4073(rtcm_t *rtcm, int subtype, int sync) -{ - (void)rtcm; - (void)sync; - trace(2,"rtcm3 4073: unsupported message subtype=%d\n",subtype); - return 0; +static int encode_type4073(rtcm_t *rtcm, int subtype, int sync) { + (void)rtcm; + (void)sync; + trace(2, "rtcm3 4073: unsupported message subtype=%d\n", subtype); + return 0; } /* encode type 4076: proprietary message IGS ---------------------------------*/ -static int encode_type4076(rtcm_t *rtcm, int subtype, int sync) -{ - switch (subtype) { - case 21: return encode_ssr1(rtcm,SYS_GPS,subtype,sync); - case 22: return encode_ssr2(rtcm,SYS_GPS,subtype,sync); - case 23: return encode_ssr4(rtcm,SYS_GPS,subtype,sync); - case 24: return encode_ssr6(rtcm,SYS_GPS,subtype,sync); - case 25: return encode_ssr3(rtcm,SYS_GPS,subtype,sync); - case 26: return encode_ssr7(rtcm,SYS_GPS,subtype,sync); - case 27: return encode_ssr5(rtcm,SYS_GPS,subtype,sync); - case 41: return encode_ssr1(rtcm,SYS_GLO,subtype,sync); - case 42: return encode_ssr2(rtcm,SYS_GLO,subtype,sync); - case 43: return encode_ssr4(rtcm,SYS_GLO,subtype,sync); - case 44: return encode_ssr6(rtcm,SYS_GLO,subtype,sync); - case 45: return encode_ssr3(rtcm,SYS_GLO,subtype,sync); - case 46: return encode_ssr7(rtcm,SYS_GLO,subtype,sync); - case 47: return encode_ssr5(rtcm,SYS_GLO,subtype,sync); - case 61: return encode_ssr1(rtcm,SYS_GAL,subtype,sync); - case 62: return encode_ssr2(rtcm,SYS_GAL,subtype,sync); - case 63: return encode_ssr4(rtcm,SYS_GAL,subtype,sync); - case 64: return encode_ssr6(rtcm,SYS_GAL,subtype,sync); - case 65: return encode_ssr3(rtcm,SYS_GAL,subtype,sync); - case 66: return encode_ssr7(rtcm,SYS_GAL,subtype,sync); - case 67: return encode_ssr5(rtcm,SYS_GAL,subtype,sync); - case 81: return encode_ssr1(rtcm,SYS_QZS,subtype,sync); - case 82: return encode_ssr2(rtcm,SYS_QZS,subtype,sync); - case 83: return encode_ssr4(rtcm,SYS_QZS,subtype,sync); - case 84: return encode_ssr6(rtcm,SYS_QZS,subtype,sync); - case 85: return encode_ssr3(rtcm,SYS_QZS,subtype,sync); - case 86: return encode_ssr7(rtcm,SYS_QZS,subtype,sync); - case 87: return encode_ssr5(rtcm,SYS_QZS,subtype,sync); - case 101: return encode_ssr1(rtcm,SYS_CMP,subtype,sync); - case 102: return encode_ssr2(rtcm,SYS_CMP,subtype,sync); - case 103: return encode_ssr4(rtcm,SYS_CMP,subtype,sync); - case 104: return encode_ssr6(rtcm,SYS_CMP,subtype,sync); - case 105: return encode_ssr3(rtcm,SYS_CMP,subtype,sync); - case 106: return encode_ssr7(rtcm,SYS_CMP,subtype,sync); - case 107: return encode_ssr5(rtcm,SYS_CMP,subtype,sync); - case 121: return encode_ssr1(rtcm,SYS_SBS,subtype,sync); - case 122: return encode_ssr2(rtcm,SYS_SBS,subtype,sync); - case 123: return encode_ssr4(rtcm,SYS_SBS,subtype,sync); - case 124: return encode_ssr6(rtcm,SYS_SBS,subtype,sync); - case 125: return encode_ssr3(rtcm,SYS_SBS,subtype,sync); - case 126: return encode_ssr7(rtcm,SYS_SBS,subtype,sync); - case 127: return encode_ssr5(rtcm,SYS_SBS,subtype,sync); - } - trace(2,"rtcm3 4076: unsupported message subtype=%d\n",subtype); - return 0; +static int encode_type4076(rtcm_t *rtcm, int subtype, int sync) { + switch (subtype) { + case 21: + return encode_ssr1(rtcm, SYS_GPS, subtype, sync); + case 22: + return encode_ssr2(rtcm, SYS_GPS, subtype, sync); + case 23: + return encode_ssr4(rtcm, SYS_GPS, subtype, sync); + case 24: + return encode_ssr6(rtcm, SYS_GPS, subtype, sync); + case 25: + return encode_ssr3(rtcm, SYS_GPS, subtype, sync); + case 26: + return encode_ssr7(rtcm, SYS_GPS, subtype, sync); + case 27: + return encode_ssr5(rtcm, SYS_GPS, subtype, sync); + case 41: + return encode_ssr1(rtcm, SYS_GLO, subtype, sync); + case 42: + return encode_ssr2(rtcm, SYS_GLO, subtype, sync); + case 43: + return encode_ssr4(rtcm, SYS_GLO, subtype, sync); + case 44: + return encode_ssr6(rtcm, SYS_GLO, subtype, sync); + case 45: + return encode_ssr3(rtcm, SYS_GLO, subtype, sync); + case 46: + return encode_ssr7(rtcm, SYS_GLO, subtype, sync); + case 47: + return encode_ssr5(rtcm, SYS_GLO, subtype, sync); + case 61: + return encode_ssr1(rtcm, SYS_GAL, subtype, sync); + case 62: + return encode_ssr2(rtcm, SYS_GAL, subtype, sync); + case 63: + return encode_ssr4(rtcm, SYS_GAL, subtype, sync); + case 64: + return encode_ssr6(rtcm, SYS_GAL, subtype, sync); + case 65: + return encode_ssr3(rtcm, SYS_GAL, subtype, sync); + case 66: + return encode_ssr7(rtcm, SYS_GAL, subtype, sync); + case 67: + return encode_ssr5(rtcm, SYS_GAL, subtype, sync); + case 81: + return encode_ssr1(rtcm, SYS_QZS, subtype, sync); + case 82: + return encode_ssr2(rtcm, SYS_QZS, subtype, sync); + case 83: + return encode_ssr4(rtcm, SYS_QZS, subtype, sync); + case 84: + return encode_ssr6(rtcm, SYS_QZS, subtype, sync); + case 85: + return encode_ssr3(rtcm, SYS_QZS, subtype, sync); + case 86: + return encode_ssr7(rtcm, SYS_QZS, subtype, sync); + case 87: + return encode_ssr5(rtcm, SYS_QZS, subtype, sync); + case 101: + return encode_ssr1(rtcm, SYS_CMP, subtype, sync); + case 102: + return encode_ssr2(rtcm, SYS_CMP, subtype, sync); + case 103: + return encode_ssr4(rtcm, SYS_CMP, subtype, sync); + case 104: + return encode_ssr6(rtcm, SYS_CMP, subtype, sync); + case 105: + return encode_ssr3(rtcm, SYS_CMP, subtype, sync); + case 106: + return encode_ssr7(rtcm, SYS_CMP, subtype, sync); + case 107: + return encode_ssr5(rtcm, SYS_CMP, subtype, sync); + case 121: + return encode_ssr1(rtcm, SYS_SBS, subtype, sync); + case 122: + return encode_ssr2(rtcm, SYS_SBS, subtype, sync); + case 123: + return encode_ssr4(rtcm, SYS_SBS, subtype, sync); + case 124: + return encode_ssr6(rtcm, SYS_SBS, subtype, sync); + case 125: + return encode_ssr3(rtcm, SYS_SBS, subtype, sync); + case 126: + return encode_ssr7(rtcm, SYS_SBS, subtype, sync); + case 127: + return encode_ssr5(rtcm, SYS_SBS, subtype, sync); + } + trace(2, "rtcm3 4076: unsupported message subtype=%d\n", subtype); + return 0; } /* encode RTCM ver.3 message -------------------------------------------------*/ -extern int encode_rtcm3(rtcm_t *rtcm, int type, int subtype, int sync) -{ - int ret=0; - - trace(3,"encode_rtcm3: type=%d subtype=%d sync=%d\n",type,subtype,sync); - - switch (type) { - case 1001: ret=encode_type1001(rtcm,sync); break; - case 1002: ret=encode_type1002(rtcm,sync); break; - case 1003: ret=encode_type1003(rtcm,sync); break; - case 1004: ret=encode_type1004(rtcm,sync); break; - case 1005: ret=encode_type1005(rtcm,sync); break; - case 1006: ret=encode_type1006(rtcm,sync); break; - case 1007: ret=encode_type1007(rtcm,sync); break; - case 1008: ret=encode_type1008(rtcm,sync); break; - case 1009: ret=encode_type1009(rtcm,sync); break; - case 1010: ret=encode_type1010(rtcm,sync); break; - case 1011: ret=encode_type1011(rtcm,sync); break; - case 1012: ret=encode_type1012(rtcm,sync); break; - case 1019: ret=encode_type1019(rtcm,sync); break; - case 1020: ret=encode_type1020(rtcm,sync); break; - case 1033: ret=encode_type1033(rtcm,sync); break; - case 1041: ret=encode_type1041(rtcm,sync); break; - case 1042: ret=encode_type1042(rtcm,sync); break; - case 1044: ret=encode_type1044(rtcm,sync); break; - case 1045: ret=encode_type1045(rtcm,sync); break; - case 1046: ret=encode_type1046(rtcm,sync); break; - case 63: ret=encode_type63 (rtcm,sync); break; /* draft */ - case 1057: ret=encode_ssr1(rtcm,SYS_GPS,0,sync); break; - case 1058: ret=encode_ssr2(rtcm,SYS_GPS,0,sync); break; - case 1059: ret=encode_ssr3(rtcm,SYS_GPS,0,sync); break; - case 1060: ret=encode_ssr4(rtcm,SYS_GPS,0,sync); break; - case 1061: ret=encode_ssr5(rtcm,SYS_GPS,0,sync); break; - case 1062: ret=encode_ssr6(rtcm,SYS_GPS,0,sync); break; - case 1063: ret=encode_ssr1(rtcm,SYS_GLO,0,sync); break; - case 1064: ret=encode_ssr2(rtcm,SYS_GLO,0,sync); break; - case 1065: ret=encode_ssr3(rtcm,SYS_GLO,0,sync); break; - case 1066: ret=encode_ssr4(rtcm,SYS_GLO,0,sync); break; - case 1067: ret=encode_ssr5(rtcm,SYS_GLO,0,sync); break; - case 1068: ret=encode_ssr6(rtcm,SYS_GLO,0,sync); break; - case 1071: ret=encode_msm1(rtcm,SYS_GPS,sync); break; - case 1072: ret=encode_msm2(rtcm,SYS_GPS,sync); break; - case 1073: ret=encode_msm3(rtcm,SYS_GPS,sync); break; - case 1074: ret=encode_msm4(rtcm,SYS_GPS,sync); break; - case 1075: ret=encode_msm5(rtcm,SYS_GPS,sync); break; - case 1076: ret=encode_msm6(rtcm,SYS_GPS,sync); break; - case 1077: ret=encode_msm7(rtcm,SYS_GPS,sync); break; - case 1081: ret=encode_msm1(rtcm,SYS_GLO,sync); break; - case 1082: ret=encode_msm2(rtcm,SYS_GLO,sync); break; - case 1083: ret=encode_msm3(rtcm,SYS_GLO,sync); break; - case 1084: ret=encode_msm4(rtcm,SYS_GLO,sync); break; - case 1085: ret=encode_msm5(rtcm,SYS_GLO,sync); break; - case 1086: ret=encode_msm6(rtcm,SYS_GLO,sync); break; - case 1087: ret=encode_msm7(rtcm,SYS_GLO,sync); break; - case 1091: ret=encode_msm1(rtcm,SYS_GAL,sync); break; - case 1092: ret=encode_msm2(rtcm,SYS_GAL,sync); break; - case 1093: ret=encode_msm3(rtcm,SYS_GAL,sync); break; - case 1094: ret=encode_msm4(rtcm,SYS_GAL,sync); break; - case 1095: ret=encode_msm5(rtcm,SYS_GAL,sync); break; - case 1096: ret=encode_msm6(rtcm,SYS_GAL,sync); break; - case 1097: ret=encode_msm7(rtcm,SYS_GAL,sync); break; - case 1101: ret=encode_msm1(rtcm,SYS_SBS,sync); break; - case 1102: ret=encode_msm2(rtcm,SYS_SBS,sync); break; - case 1103: ret=encode_msm3(rtcm,SYS_SBS,sync); break; - case 1104: ret=encode_msm4(rtcm,SYS_SBS,sync); break; - case 1105: ret=encode_msm5(rtcm,SYS_SBS,sync); break; - case 1106: ret=encode_msm6(rtcm,SYS_SBS,sync); break; - case 1107: ret=encode_msm7(rtcm,SYS_SBS,sync); break; - case 1111: ret=encode_msm1(rtcm,SYS_QZS,sync); break; - case 1112: ret=encode_msm2(rtcm,SYS_QZS,sync); break; - case 1113: ret=encode_msm3(rtcm,SYS_QZS,sync); break; - case 1114: ret=encode_msm4(rtcm,SYS_QZS,sync); break; - case 1115: ret=encode_msm5(rtcm,SYS_QZS,sync); break; - case 1116: ret=encode_msm6(rtcm,SYS_QZS,sync); break; - case 1117: ret=encode_msm7(rtcm,SYS_QZS,sync); break; - case 1121: ret=encode_msm1(rtcm,SYS_CMP,sync); break; - case 1122: ret=encode_msm2(rtcm,SYS_CMP,sync); break; - case 1123: ret=encode_msm3(rtcm,SYS_CMP,sync); break; - case 1124: ret=encode_msm4(rtcm,SYS_CMP,sync); break; - case 1125: ret=encode_msm5(rtcm,SYS_CMP,sync); break; - case 1126: ret=encode_msm6(rtcm,SYS_CMP,sync); break; - case 1127: ret=encode_msm7(rtcm,SYS_CMP,sync); break; - case 1131: ret=encode_msm1(rtcm,SYS_IRN,sync); break; - case 1132: ret=encode_msm2(rtcm,SYS_IRN,sync); break; - case 1133: ret=encode_msm3(rtcm,SYS_IRN,sync); break; - case 1134: ret=encode_msm4(rtcm,SYS_IRN,sync); break; - case 1135: ret=encode_msm5(rtcm,SYS_IRN,sync); break; - case 1136: ret=encode_msm6(rtcm,SYS_IRN,sync); break; - case 1137: ret=encode_msm7(rtcm,SYS_IRN,sync); break; - case 1230: ret=encode_type1230(rtcm,sync); break; - case 1240: ret=encode_ssr1(rtcm,SYS_GAL,0,sync); break; /* draft */ - case 1241: ret=encode_ssr2(rtcm,SYS_GAL,0,sync); break; /* draft */ - case 1242: ret=encode_ssr3(rtcm,SYS_GAL,0,sync); break; /* draft */ - case 1243: ret=encode_ssr4(rtcm,SYS_GAL,0,sync); break; /* draft */ - case 1244: ret=encode_ssr5(rtcm,SYS_GAL,0,sync); break; /* draft */ - case 1245: ret=encode_ssr6(rtcm,SYS_GAL,0,sync); break; /* draft */ - case 1246: ret=encode_ssr1(rtcm,SYS_QZS,0,sync); break; /* draft */ - case 1247: ret=encode_ssr2(rtcm,SYS_QZS,0,sync); break; /* draft */ - case 1248: ret=encode_ssr3(rtcm,SYS_QZS,0,sync); break; /* draft */ - case 1249: ret=encode_ssr4(rtcm,SYS_QZS,0,sync); break; /* draft */ - case 1250: ret=encode_ssr5(rtcm,SYS_QZS,0,sync); break; /* draft */ - case 1251: ret=encode_ssr6(rtcm,SYS_QZS,0,sync); break; /* draft */ - case 1252: ret=encode_ssr1(rtcm,SYS_SBS,0,sync); break; /* draft */ - case 1253: ret=encode_ssr2(rtcm,SYS_SBS,0,sync); break; /* draft */ - case 1254: ret=encode_ssr3(rtcm,SYS_SBS,0,sync); break; /* draft */ - case 1255: ret=encode_ssr4(rtcm,SYS_SBS,0,sync); break; /* draft */ - case 1256: ret=encode_ssr5(rtcm,SYS_SBS,0,sync); break; /* draft */ - case 1257: ret=encode_ssr6(rtcm,SYS_SBS,0,sync); break; /* draft */ - case 1258: ret=encode_ssr1(rtcm,SYS_CMP,0,sync); break; /* draft */ - case 1259: ret=encode_ssr2(rtcm,SYS_CMP,0,sync); break; /* draft */ - case 1260: ret=encode_ssr3(rtcm,SYS_CMP,0,sync); break; /* draft */ - case 1261: ret=encode_ssr4(rtcm,SYS_CMP,0,sync); break; /* draft */ - case 1262: ret=encode_ssr5(rtcm,SYS_CMP,0,sync); break; /* draft */ - case 1263: ret=encode_ssr6(rtcm,SYS_CMP,0,sync); break; /* draft */ - case 11: ret=encode_ssr7(rtcm,SYS_GPS,0,sync); break; /* tentative */ - case 12: ret=encode_ssr7(rtcm,SYS_GAL,0,sync); break; /* tentative */ - case 13: ret=encode_ssr7(rtcm,SYS_QZS,0,sync); break; /* tentative */ - case 14: ret=encode_ssr7(rtcm,SYS_CMP,0,sync); break; /* tentative */ - case 4073: ret=encode_type4073(rtcm,subtype,sync); break; - case 4076: ret=encode_type4076(rtcm,subtype,sync); break; - } - if (ret>0) { - if (1001<=type&&type<=1299) rtcm->nmsg3[type-1000]++; /* 1-299 */ - else if (4070<=type&&type<=4099) rtcm->nmsg3[type-3770]++; /* 300-329 */ - else rtcm->nmsg3[0]++; /* other */ - } - return ret; +extern int encode_rtcm3(rtcm_t *rtcm, int type, int subtype, int sync) { + int ret = 0; + + trace(3, "encode_rtcm3: type=%d subtype=%d sync=%d\n", type, subtype, sync); + + switch (type) { + case 1001: + ret = encode_type1001(rtcm, sync); + break; + case 1002: + ret = encode_type1002(rtcm, sync); + break; + case 1003: + ret = encode_type1003(rtcm, sync); + break; + case 1004: + ret = encode_type1004(rtcm, sync); + break; + case 1005: + ret = encode_type1005(rtcm, sync); + break; + case 1006: + ret = encode_type1006(rtcm, sync); + break; + case 1007: + ret = encode_type1007(rtcm, sync); + break; + case 1008: + ret = encode_type1008(rtcm, sync); + break; + case 1009: + ret = encode_type1009(rtcm, sync); + break; + case 1010: + ret = encode_type1010(rtcm, sync); + break; + case 1011: + ret = encode_type1011(rtcm, sync); + break; + case 1012: + ret = encode_type1012(rtcm, sync); + break; + case 1019: + ret = encode_type1019(rtcm, sync); + break; + case 1020: + ret = encode_type1020(rtcm, sync); + break; + case 1033: + ret = encode_type1033(rtcm, sync); + break; + case 1041: + ret = encode_type1041(rtcm, sync); + break; + case 1042: + ret = encode_type1042(rtcm, sync); + break; + case 1044: + ret = encode_type1044(rtcm, sync); + break; + case 1045: + ret = encode_type1045(rtcm, sync); + break; + case 1046: + ret = encode_type1046(rtcm, sync); + break; + case 63: + ret = encode_type63(rtcm, sync); + break; /* draft */ + case 1057: + ret = encode_ssr1(rtcm, SYS_GPS, 0, sync); + break; + case 1058: + ret = encode_ssr2(rtcm, SYS_GPS, 0, sync); + break; + case 1059: + ret = encode_ssr3(rtcm, SYS_GPS, 0, sync); + break; + case 1060: + ret = encode_ssr4(rtcm, SYS_GPS, 0, sync); + break; + case 1061: + ret = encode_ssr5(rtcm, SYS_GPS, 0, sync); + break; + case 1062: + ret = encode_ssr6(rtcm, SYS_GPS, 0, sync); + break; + case 1063: + ret = encode_ssr1(rtcm, SYS_GLO, 0, sync); + break; + case 1064: + ret = encode_ssr2(rtcm, SYS_GLO, 0, sync); + break; + case 1065: + ret = encode_ssr3(rtcm, SYS_GLO, 0, sync); + break; + case 1066: + ret = encode_ssr4(rtcm, SYS_GLO, 0, sync); + break; + case 1067: + ret = encode_ssr5(rtcm, SYS_GLO, 0, sync); + break; + case 1068: + ret = encode_ssr6(rtcm, SYS_GLO, 0, sync); + break; + case 1071: + ret = encode_msm1(rtcm, SYS_GPS, sync); + break; + case 1072: + ret = encode_msm2(rtcm, SYS_GPS, sync); + break; + case 1073: + ret = encode_msm3(rtcm, SYS_GPS, sync); + break; + case 1074: + ret = encode_msm4(rtcm, SYS_GPS, sync); + break; + case 1075: + ret = encode_msm5(rtcm, SYS_GPS, sync); + break; + case 1076: + ret = encode_msm6(rtcm, SYS_GPS, sync); + break; + case 1077: + ret = encode_msm7(rtcm, SYS_GPS, sync); + break; + case 1081: + ret = encode_msm1(rtcm, SYS_GLO, sync); + break; + case 1082: + ret = encode_msm2(rtcm, SYS_GLO, sync); + break; + case 1083: + ret = encode_msm3(rtcm, SYS_GLO, sync); + break; + case 1084: + ret = encode_msm4(rtcm, SYS_GLO, sync); + break; + case 1085: + ret = encode_msm5(rtcm, SYS_GLO, sync); + break; + case 1086: + ret = encode_msm6(rtcm, SYS_GLO, sync); + break; + case 1087: + ret = encode_msm7(rtcm, SYS_GLO, sync); + break; + case 1091: + ret = encode_msm1(rtcm, SYS_GAL, sync); + break; + case 1092: + ret = encode_msm2(rtcm, SYS_GAL, sync); + break; + case 1093: + ret = encode_msm3(rtcm, SYS_GAL, sync); + break; + case 1094: + ret = encode_msm4(rtcm, SYS_GAL, sync); + break; + case 1095: + ret = encode_msm5(rtcm, SYS_GAL, sync); + break; + case 1096: + ret = encode_msm6(rtcm, SYS_GAL, sync); + break; + case 1097: + ret = encode_msm7(rtcm, SYS_GAL, sync); + break; + case 1101: + ret = encode_msm1(rtcm, SYS_SBS, sync); + break; + case 1102: + ret = encode_msm2(rtcm, SYS_SBS, sync); + break; + case 1103: + ret = encode_msm3(rtcm, SYS_SBS, sync); + break; + case 1104: + ret = encode_msm4(rtcm, SYS_SBS, sync); + break; + case 1105: + ret = encode_msm5(rtcm, SYS_SBS, sync); + break; + case 1106: + ret = encode_msm6(rtcm, SYS_SBS, sync); + break; + case 1107: + ret = encode_msm7(rtcm, SYS_SBS, sync); + break; + case 1111: + ret = encode_msm1(rtcm, SYS_QZS, sync); + break; + case 1112: + ret = encode_msm2(rtcm, SYS_QZS, sync); + break; + case 1113: + ret = encode_msm3(rtcm, SYS_QZS, sync); + break; + case 1114: + ret = encode_msm4(rtcm, SYS_QZS, sync); + break; + case 1115: + ret = encode_msm5(rtcm, SYS_QZS, sync); + break; + case 1116: + ret = encode_msm6(rtcm, SYS_QZS, sync); + break; + case 1117: + ret = encode_msm7(rtcm, SYS_QZS, sync); + break; + case 1121: + ret = encode_msm1(rtcm, SYS_CMP, sync); + break; + case 1122: + ret = encode_msm2(rtcm, SYS_CMP, sync); + break; + case 1123: + ret = encode_msm3(rtcm, SYS_CMP, sync); + break; + case 1124: + ret = encode_msm4(rtcm, SYS_CMP, sync); + break; + case 1125: + ret = encode_msm5(rtcm, SYS_CMP, sync); + break; + case 1126: + ret = encode_msm6(rtcm, SYS_CMP, sync); + break; + case 1127: + ret = encode_msm7(rtcm, SYS_CMP, sync); + break; + case 1131: + ret = encode_msm1(rtcm, SYS_IRN, sync); + break; + case 1132: + ret = encode_msm2(rtcm, SYS_IRN, sync); + break; + case 1133: + ret = encode_msm3(rtcm, SYS_IRN, sync); + break; + case 1134: + ret = encode_msm4(rtcm, SYS_IRN, sync); + break; + case 1135: + ret = encode_msm5(rtcm, SYS_IRN, sync); + break; + case 1136: + ret = encode_msm6(rtcm, SYS_IRN, sync); + break; + case 1137: + ret = encode_msm7(rtcm, SYS_IRN, sync); + break; + case 1230: + ret = encode_type1230(rtcm, sync); + break; + case 1240: + ret = encode_ssr1(rtcm, SYS_GAL, 0, sync); + break; /* draft */ + case 1241: + ret = encode_ssr2(rtcm, SYS_GAL, 0, sync); + break; /* draft */ + case 1242: + ret = encode_ssr3(rtcm, SYS_GAL, 0, sync); + break; /* draft */ + case 1243: + ret = encode_ssr4(rtcm, SYS_GAL, 0, sync); + break; /* draft */ + case 1244: + ret = encode_ssr5(rtcm, SYS_GAL, 0, sync); + break; /* draft */ + case 1245: + ret = encode_ssr6(rtcm, SYS_GAL, 0, sync); + break; /* draft */ + case 1246: + ret = encode_ssr1(rtcm, SYS_QZS, 0, sync); + break; /* draft */ + case 1247: + ret = encode_ssr2(rtcm, SYS_QZS, 0, sync); + break; /* draft */ + case 1248: + ret = encode_ssr3(rtcm, SYS_QZS, 0, sync); + break; /* draft */ + case 1249: + ret = encode_ssr4(rtcm, SYS_QZS, 0, sync); + break; /* draft */ + case 1250: + ret = encode_ssr5(rtcm, SYS_QZS, 0, sync); + break; /* draft */ + case 1251: + ret = encode_ssr6(rtcm, SYS_QZS, 0, sync); + break; /* draft */ + case 1252: + ret = encode_ssr1(rtcm, SYS_SBS, 0, sync); + break; /* draft */ + case 1253: + ret = encode_ssr2(rtcm, SYS_SBS, 0, sync); + break; /* draft */ + case 1254: + ret = encode_ssr3(rtcm, SYS_SBS, 0, sync); + break; /* draft */ + case 1255: + ret = encode_ssr4(rtcm, SYS_SBS, 0, sync); + break; /* draft */ + case 1256: + ret = encode_ssr5(rtcm, SYS_SBS, 0, sync); + break; /* draft */ + case 1257: + ret = encode_ssr6(rtcm, SYS_SBS, 0, sync); + break; /* draft */ + case 1258: + ret = encode_ssr1(rtcm, SYS_CMP, 0, sync); + break; /* draft */ + case 1259: + ret = encode_ssr2(rtcm, SYS_CMP, 0, sync); + break; /* draft */ + case 1260: + ret = encode_ssr3(rtcm, SYS_CMP, 0, sync); + break; /* draft */ + case 1261: + ret = encode_ssr4(rtcm, SYS_CMP, 0, sync); + break; /* draft */ + case 1262: + ret = encode_ssr5(rtcm, SYS_CMP, 0, sync); + break; /* draft */ + case 1263: + ret = encode_ssr6(rtcm, SYS_CMP, 0, sync); + break; /* draft */ + case 11: + ret = encode_ssr7(rtcm, SYS_GPS, 0, sync); + break; /* tentative */ + case 12: + ret = encode_ssr7(rtcm, SYS_GAL, 0, sync); + break; /* tentative */ + case 13: + ret = encode_ssr7(rtcm, SYS_QZS, 0, sync); + break; /* tentative */ + case 14: + ret = encode_ssr7(rtcm, SYS_CMP, 0, sync); + break; /* tentative */ + case 4073: + ret = encode_type4073(rtcm, subtype, sync); + break; + case 4076: + ret = encode_type4076(rtcm, subtype, sync); + break; + } + if (ret > 0) { + if (1001 <= type && type <= 1299) + rtcm->nmsg3[type - 1000]++; /* 1-299 */ + else if (4070 <= type && type <= 4099) + rtcm->nmsg3[type - 3770]++; /* 300-329 */ + else + rtcm->nmsg3[0]++; /* other */ + } + return ret; } diff --git a/src/rtkcmn.c b/src/rtkcmn.c index f2f890b30..5a486c096 100644 --- a/src/rtkcmn.c +++ b/src/rtkcmn.c @@ -1,1034 +1,1170 @@ /*------------------------------------------------------------------------------ -* rtkcmn.c : rtklib common functions -* -* Copyright (C) 2007-2020 by T.TAKASU, All rights reserved. -* -* options : -DLAPACK use LAPACK/BLAS -* -DMKL use Intel MKL -* -DTRACE enable debug trace -* -DWIN32 use WIN32 API -* -DNOCALLOC no use calloc for zero matrix -* -DIERS_MODEL use GMF instead of NMF -* -DDLL built for shared library -* -DCPUTIME_IN_GPST cputime operated in gpst -* -* references : -* [1] IS-GPS-200D, Navstar GPS Space Segment/Navigation User Interfaces, -* 7 March, 2006 -* [2] RTCA/DO-229C, Minimum operational performance standards for global -* positioning system/wide area augmentation system airborne equipment, -* November 28, 2001 -* [3] M.Rothacher, R.Schmid, ANTEX: The Antenna Exchange Format Version 1.4, -* 15 September, 2010 -* [4] A.Gelb ed., Applied Optimal Estimation, The M.I.T Press, 1974 -* [5] A.E.Niell, Global mapping functions for the atmosphere delay at radio -* wavelengths, Journal of geophysical research, 1996 -* [6] W.Gurtner and L.Estey, RINEX The Receiver Independent Exchange Format -* Version 3.00, November 28, 2007 -* [7] J.Kouba, A Guide to using International GNSS Service (IGS) products, -* May 2009 -* [8] China Satellite Navigation Office, BeiDou navigation satellite system -* signal in space interface control document, open service signal B1I -* (version 1.0), Dec 2012 -* [9] J.Boehm, A.Niell, P.Tregoning and H.Shuh, Global Mapping Function -* (GMF): A new empirical mapping function base on numerical weather -* model data, Geophysical Research Letters, 33, L07304, 2006 -* [10] GLONASS/GPS/Galileo/Compass/SBAS NV08C receiver series BINR interface -* protocol specification ver.1.3, August, 2012 -* -* version : $Revision: 1.1 $ $Date: 2008/07/17 21:48:06 $ -* history : 2007/01/12 1.0 new -* 2007/03/06 1.1 input initial rover pos of pntpos() -* update only effective states of filter() -* fix bug of atan2() domain error -* 2007/04/11 1.2 add function antmodel() -* add gdop mask for pntpos() -* change constant MAXDTOE value -* 2007/05/25 1.3 add function execcmd(),expandpath() -* 2008/06/21 1.4 add funciton sortobs(),uniqeph(),screent() -* replace geodist() by sagnac correction way -* 2008/10/29 1.5 fix bug of ionospheric mapping function -* fix bug of seasonal variation term of tropmapf -* 2008/12/27 1.6 add function tickget(), sleepms(), tracenav(), -* xyz2enu(), satposv(), pntvel(), covecef() -* 2009/03/12 1.7 fix bug on error-stop when localtime() returns NULL -* 2009/03/13 1.8 fix bug on time adjustment for summer time -* 2009/04/10 1.9 add function adjgpsweek(),getbits(),getbitu() -* add function geph2pos() -* 2009/06/08 1.10 add function seph2pos() -* 2009/11/28 1.11 change function pntpos() -* add function tracegnav(),tracepeph() -* 2009/12/22 1.12 change default parameter of ionos std -* valid under second for timeget() -* 2010/07/28 1.13 fix bug in tropmapf() -* added api: -* obs2code(),code2obs(),cross3(),normv3(), -* gst2time(),time2gst(),time_str(),timeset(), -* deg2dms(),dms2deg(),searchpcv(),antmodel_s(), -* tracehnav(),tracepclk(),reppath(),reppaths(), -* createdir() -* changed api: -* readpcv(), -* deleted api: -* uniqeph() -* 2010/08/20 1.14 omit to include mkl header files -* fix bug on chi-sqr(n) table -* 2010/12/11 1.15 added api: -* freeobs(),freenav(),ionppp() -* 2011/05/28 1.16 fix bug on half-hour offset by time2epoch() -* added api: -* uniqnav() -* 2012/06/09 1.17 add a leap second after 2012-6-30 -* 2012/07/15 1.18 add api setbits(),setbitu(),utc2gmst() -* fix bug on interpolation of antenna pcv -* fix bug on str2num() for string with over 256 char -* add api readblq(),satexclude(),setcodepri(), -* getcodepri() -* change api obs2code(),code2obs(),antmodel() -* 2012/12/25 1.19 fix bug on satwavelen(),code2obs(),obs2code() -* add api testsnr() -* 2013/01/04 1.20 add api gpst2bdt(),bdt2gpst(),bdt2time(),time2bdt() -* readblq(),readerp(),geterp(),crc16() -* change api eci2ecef(),sunmoonpos() -* 2013/03/26 1.21 tickget() uses clock_gettime() for linux -* 2013/05/08 1.22 fix bug on nutation coefficients for ast_args() -* 2013/06/02 1.23 add #ifdef for undefined CLOCK_MONOTONIC_RAW -* 2013/09/01 1.24 fix bug on interpolation of satellite antenna pcv -* 2013/09/06 1.25 fix bug on extrapolation of erp -* 2014/04/27 1.26 add SYS_LEO for satellite system -* add BDS L1 code for RINEX 3.02 and RTCM 3.2 -* support BDS L1 in satwavelen() -* 2014/05/29 1.27 fix bug on obs2code() to search obs code table -* 2014/08/26 1.28 fix problem on output of uncompress() for tar file -* add function to swap trace file with keywords -* 2014/10/21 1.29 strtok() -> strtok_r() in expath() for thread-safe -* add bdsmodear in procopt_default -* 2015/03/19 1.30 fix bug on interpolation of erp values in geterp() -* add leap second insertion before 2015/07/01 00:00 -* add api read_leaps() -* 2015/05/31 1.31 delete api windupcorr() -* 2015/08/08 1.32 add compile option CPUTIME_IN_GPST -* add api add_fatal() -* support usno leapsec.dat for api read_leaps() -* 2016/01/23 1.33 enable septentrio -* 2016/02/05 1.34 support GLONASS for savenav(), loadnav() -* 2016/06/11 1.35 delete trace() in reppath() to avoid deadlock -* 2016/07/01 1.36 support IRNSS -* add leap second before 2017/1/1 00:00:00 -* 2016/07/29 1.37 rename api compress() -> rtk_uncompress() -* rename api crc16() -> rtk_crc16() -* rename api crc24q() -> rtk_crc24q() -* rename api crc32() -> rtk_crc32() -* 2016/08/20 1.38 fix type incompatibility in win64 environment -* change constant _POSIX_C_SOURCE 199309 -> 199506 -* 2016/08/21 1.39 fix bug on week overflow in time2gpst()/gpst2time() -* 2016/09/05 1.40 fix bug on invalid nav data read in readnav() -* 2016/09/17 1.41 suppress warnings -* 2016/09/19 1.42 modify api deg2dms() to consider numerical error -* 2017/04/11 1.43 delete EXPORT for global variables -* 2018/10/10 1.44 modify api satexclude() -* 2020/11/30 1.45 add API code2idx() to get freq-index -* add API code2freq() to get carrier frequency -* add API timereset() to reset current time -* modify API obs2code(), code2obs() and setcodepri() -* delete API satwavelen() -* delete API csmooth() -* delete global variable lam_carr[] -* compensate L3,L4,... PCVs by L2 PCV if no PCV data -* in input file by API readpcv() -* add support hatanaka-compressed RINEX files with -* extension ".crx" or ".CRX" -* update stream format strings table -* update obs code strings and priority table -* use integer types in stdint.h -* suppress warnings -*-----------------------------------------------------------------------------*/ + * rtkcmn.c : rtklib common functions + * + * Copyright (C) 2007-2020 by T.TAKASU, All rights reserved. + * + * options : -DLAPACK use LAPACK/BLAS + * -DMKL use Intel MKL + * -DTRACE enable debug trace + * -DWIN32 use WIN32 API + * -DNOCALLOC no use calloc for zero matrix + * -DIERS_MODEL use GMF instead of NMF + * -DDLL built for shared library + * -DCPUTIME_IN_GPST cputime operated in gpst + * + * references : + * [1] IS-GPS-200D, Navstar GPS Space Segment/Navigation User Interfaces, + * 7 March, 2006 + * [2] RTCA/DO-229C, Minimum operational performance standards for global + * positioning system/wide area augmentation system airborne equipment, + * November 28, 2001 + * [3] M.Rothacher, R.Schmid, ANTEX: The Antenna Exchange Format Version 1.4, + * 15 September, 2010 + * [4] A.Gelb ed., Applied Optimal Estimation, The M.I.T Press, 1974 + * [5] A.E.Niell, Global mapping functions for the atmosphere delay at radio + * wavelengths, Journal of geophysical research, 1996 + * [6] W.Gurtner and L.Estey, RINEX The Receiver Independent Exchange Format + * Version 3.00, November 28, 2007 + * [7] J.Kouba, A Guide to using International GNSS Service (IGS) products, + * May 2009 + * [8] China Satellite Navigation Office, BeiDou navigation satellite system + * signal in space interface control document, open service signal B1I + * (version 1.0), Dec 2012 + * [9] J.Boehm, A.Niell, P.Tregoning and H.Shuh, Global Mapping Function + * (GMF): A new empirical mapping function base on numerical weather + * model data, Geophysical Research Letters, 33, L07304, 2006 + * [10] GLONASS/GPS/Galileo/Compass/SBAS NV08C receiver series BINR interface + * protocol specification ver.1.3, August, 2012 + * + * version : $Revision: 1.1 $ $Date: 2008/07/17 21:48:06 $ + * history : 2007/01/12 1.0 new + * 2007/03/06 1.1 input initial rover pos of pntpos() + * update only effective states of filter() + * fix bug of atan2() domain error + * 2007/04/11 1.2 add function antmodel() + * add gdop mask for pntpos() + * change constant MAXDTOE value + * 2007/05/25 1.3 add function execcmd(),expandpath() + * 2008/06/21 1.4 add funciton sortobs(),uniqeph(),screent() + * replace geodist() by sagnac correction way + * 2008/10/29 1.5 fix bug of ionospheric mapping function + * fix bug of seasonal variation term of tropmapf + * 2008/12/27 1.6 add function tickget(), sleepms(), tracenav(), + * xyz2enu(), satposv(), pntvel(), covecef() + * 2009/03/12 1.7 fix bug on error-stop when localtime() returns NULL + * 2009/03/13 1.8 fix bug on time adjustment for summer time + * 2009/04/10 1.9 add function adjgpsweek(),getbits(),getbitu() + * add function geph2pos() + * 2009/06/08 1.10 add function seph2pos() + * 2009/11/28 1.11 change function pntpos() + * add function tracegnav(),tracepeph() + * 2009/12/22 1.12 change default parameter of ionos std + * valid under second for timeget() + * 2010/07/28 1.13 fix bug in tropmapf() + * added api: + * obs2code(),code2obs(),cross3(),normv3(), + * gst2time(),time2gst(),time_str(),timeset(), + * deg2dms(),dms2deg(),searchpcv(),antmodel_s(), + * tracehnav(),tracepclk(),reppath(),reppaths(), + * createdir() + * changed api: + * readpcv(), + * deleted api: + * uniqeph() + * 2010/08/20 1.14 omit to include mkl header files + * fix bug on chi-sqr(n) table + * 2010/12/11 1.15 added api: + * freeobs(),freenav(),ionppp() + * 2011/05/28 1.16 fix bug on half-hour offset by time2epoch() + * added api: + * uniqnav() + * 2012/06/09 1.17 add a leap second after 2012-6-30 + * 2012/07/15 1.18 add api setbits(),setbitu(),utc2gmst() + * fix bug on interpolation of antenna pcv + * fix bug on str2num() for string with over 256 char + * add api readblq(),satexclude(),setcodepri(), + * getcodepri() + * change api obs2code(),code2obs(),antmodel() + * 2012/12/25 1.19 fix bug on satwavelen(),code2obs(),obs2code() + * add api testsnr() + * 2013/01/04 1.20 add api gpst2bdt(),bdt2gpst(),bdt2time(),time2bdt() + * readblq(),readerp(),geterp(),crc16() + * change api eci2ecef(),sunmoonpos() + * 2013/03/26 1.21 tickget() uses clock_gettime() for linux + * 2013/05/08 1.22 fix bug on nutation coefficients for ast_args() + * 2013/06/02 1.23 add #ifdef for undefined CLOCK_MONOTONIC_RAW + * 2013/09/01 1.24 fix bug on interpolation of satellite antenna pcv + * 2013/09/06 1.25 fix bug on extrapolation of erp + * 2014/04/27 1.26 add SYS_LEO for satellite system + * add BDS L1 code for RINEX 3.02 and RTCM 3.2 + * support BDS L1 in satwavelen() + * 2014/05/29 1.27 fix bug on obs2code() to search obs code table + * 2014/08/26 1.28 fix problem on output of uncompress() for tar file + * add function to swap trace file with keywords + * 2014/10/21 1.29 strtok() -> strtok_r() in expath() for thread-safe + * add bdsmodear in procopt_default + * 2015/03/19 1.30 fix bug on interpolation of erp values in geterp() + * add leap second insertion before 2015/07/01 00:00 + * add api read_leaps() + * 2015/05/31 1.31 delete api windupcorr() + * 2015/08/08 1.32 add compile option CPUTIME_IN_GPST + * add api add_fatal() + * support usno leapsec.dat for api read_leaps() + * 2016/01/23 1.33 enable septentrio + * 2016/02/05 1.34 support GLONASS for savenav(), loadnav() + * 2016/06/11 1.35 delete trace() in reppath() to avoid deadlock + * 2016/07/01 1.36 support IRNSS + * add leap second before 2017/1/1 00:00:00 + * 2016/07/29 1.37 rename api compress() -> rtk_uncompress() + * rename api crc16() -> rtk_crc16() + * rename api crc24q() -> rtk_crc24q() + * rename api crc32() -> rtk_crc32() + * 2016/08/20 1.38 fix type incompatibility in win64 environment + * change constant _POSIX_C_SOURCE 199309 -> 199506 + * 2016/08/21 1.39 fix bug on week overflow in time2gpst()/gpst2time() + * 2016/09/05 1.40 fix bug on invalid nav data read in readnav() + * 2016/09/17 1.41 suppress warnings + * 2016/09/19 1.42 modify api deg2dms() to consider numerical error + * 2017/04/11 1.43 delete EXPORT for global variables + * 2018/10/10 1.44 modify api satexclude() + * 2020/11/30 1.45 add API code2idx() to get freq-index + * add API code2freq() to get carrier frequency + * add API timereset() to reset current time + * modify API obs2code(), code2obs() and setcodepri() + * delete API satwavelen() + * delete API csmooth() + * delete global variable lam_carr[] + * compensate L3,L4,... PCVs by L2 PCV if no PCV data + * in input file by API readpcv() + * add support hatanaka-compressed RINEX files with + * extension ".crx" or ".CRX" + * update stream format strings table + * update obs code strings and priority table + * use integer types in stdint.h + * suppress warnings + *-----------------------------------------------------------------------------*/ #define _POSIX_C_SOURCE 199506 -#include #include #include +#include #ifndef WIN32 #include -#include -#include #include +#include #include +#include #endif #include "rtklib.h" /* constants -----------------------------------------------------------------*/ -#define POLYCRC32 0xEDB88320u /* CRC32 polynomial */ -#define POLYCRC24Q 0x1864CFBu /* CRC24Q polynomial */ - -#define SQR(x) ((x)*(x)) -#define MAX_VAR_EPH SQR(300.0) /* max variance eph to reject satellite (m^2) */ - -static const double gpst0[]={1980,1, 6,0,0,0}; /* gps time reference */ -static const double gst0 []={1999,8,22,0,0,0}; /* galileo system time reference */ -static const double bdt0 []={2006,1, 1,0,0,0}; /* beidou time reference */ - -static double leaps[MAXLEAPS+1][7]={ /* leap seconds (y,m,d,h,m,s,utc-gpst) */ - {2017,1,1,0,0,0,-18}, - {2015,7,1,0,0,0,-17}, - {2012,7,1,0,0,0,-16}, - {2009,1,1,0,0,0,-15}, - {2006,1,1,0,0,0,-14}, - {1999,1,1,0,0,0,-13}, - {1997,7,1,0,0,0,-12}, - {1996,1,1,0,0,0,-11}, - {1994,7,1,0,0,0,-10}, - {1993,7,1,0,0,0, -9}, - {1992,7,1,0,0,0, -8}, - {1991,1,1,0,0,0, -7}, - {1990,1,1,0,0,0, -6}, - {1988,1,1,0,0,0, -5}, - {1985,7,1,0,0,0, -4}, - {1983,7,1,0,0,0, -3}, - {1982,7,1,0,0,0, -2}, - {1981,7,1,0,0,0, -1}, - {0} -}; -const double chisqr[100]={ /* chi-sqr(n) (alpha=0.001) */ - 10.8,13.8,16.3,18.5,20.5,22.5,24.3,26.1,27.9,29.6, - 31.3,32.9,34.5,36.1,37.7,39.3,40.8,42.3,43.8,45.3, - 46.8,48.3,49.7,51.2,52.6,54.1,55.5,56.9,58.3,59.7, - 61.1,62.5,63.9,65.2,66.6,68.0,69.3,70.7,72.1,73.4, - 74.7,76.0,77.3,78.6,80.0,81.3,82.6,84.0,85.4,86.7, - 88.0,89.3,90.6,91.9,93.3,94.7,96.0,97.4,98.7,100 , - 101 ,102 ,103 ,104 ,105 ,107 ,108 ,109 ,110 ,112 , - 113 ,114 ,115 ,116 ,118 ,119 ,120 ,122 ,123 ,125 , - 126 ,127 ,128 ,129 ,131 ,132 ,133 ,134 ,135 ,137 , - 138 ,139 ,140 ,142 ,143 ,144 ,145 ,147 ,148 ,149 +#define POLYCRC32 0xEDB88320u /* CRC32 polynomial */ +#define POLYCRC24Q 0x1864CFBu /* CRC24Q polynomial */ + +#define SQR(x) ((x) * (x)) +#define MAX_VAR_EPH SQR(300.0) /* max variance eph to reject satellite (m^2) */ + +static const double gpst0[] = {1980, 1, 6, 0, 0, 0}; /* gps time reference */ +static const double gst0[] = {1999, 8, 22, 0, 0, 0}; /* galileo system time reference */ +static const double bdt0[] = {2006, 1, 1, 0, 0, 0}; /* beidou time reference */ + +static double leaps[MAXLEAPS + 1][7] = {/* leap seconds (y,m,d,h,m,s,utc-gpst) */ + {2017, 1, 1, 0, 0, 0, -18}, + {2015, 7, 1, 0, 0, 0, -17}, + {2012, 7, 1, 0, 0, 0, -16}, + {2009, 1, 1, 0, 0, 0, -15}, + {2006, 1, 1, 0, 0, 0, -14}, + {1999, 1, 1, 0, 0, 0, -13}, + {1997, 7, 1, 0, 0, 0, -12}, + {1996, 1, 1, 0, 0, 0, -11}, + {1994, 7, 1, 0, 0, 0, -10}, + {1993, 7, 1, 0, 0, 0, -9}, + {1992, 7, 1, 0, 0, 0, -8}, + {1991, 1, 1, 0, 0, 0, -7}, + {1990, 1, 1, 0, 0, 0, -6}, + {1988, 1, 1, 0, 0, 0, -5}, + {1985, 7, 1, 0, 0, 0, -4}, + {1983, 7, 1, 0, 0, 0, -3}, + {1982, 7, 1, 0, 0, 0, -2}, + {1981, 7, 1, 0, 0, 0, -1}, + {0}}; +const double chisqr[100] = {/* chi-sqr(n) (alpha=0.001) */ + 10.8, 13.8, 16.3, 18.5, 20.5, 22.5, 24.3, 26.1, 27.9, 29.6, 31.3, 32.9, + 34.5, 36.1, 37.7, 39.3, 40.8, 42.3, 43.8, 45.3, 46.8, 48.3, 49.7, 51.2, + 52.6, 54.1, 55.5, 56.9, 58.3, 59.7, 61.1, 62.5, 63.9, 65.2, 66.6, 68.0, + 69.3, 70.7, 72.1, 73.4, 74.7, 76.0, 77.3, 78.6, 80.0, 81.3, 82.6, 84.0, + 85.4, 86.7, 88.0, 89.3, 90.6, 91.9, 93.3, 94.7, 96.0, 97.4, 98.7, 100, + 101, 102, 103, 104, 105, 107, 108, 109, 110, 112, 113, 114, + 115, 116, 118, 119, 120, 122, 123, 125, 126, 127, 128, 129, + 131, 132, 133, 134, 135, 137, 138, 139, 140, 142, 143, 144, + 145, 147, 148, 149}; +const prcopt_t prcopt_default = { + /* defaults processing options */ + PMODE_KINEMA, + SOLTYPE_FORWARD, /* mode,soltype */ + 2, + SYS_GPS | SYS_GLO | SYS_GAL, /* nf, navsys */ + 15.0 * D2R, + {{0, 0}}, /* elmin,snrmask */ + 0, + 3, + 3, + 1, + 0, + 1, /* sateph,modear,glomodear,gpsmodear,bdsmodear,arfilter */ + 20, + 0, + 4, + 5, + 10, + 20, /* maxout,minlock,minfixsats,minholdsats,mindropsats,minfix */ + 1, + 1, + 1, + 1, + 0, /* armaxiter,estion,esttrop,dynamics,tidecorr */ + 1, + 0, + 0, + 0, + 0, /* niter,codesmooth,intpref,sbascorr,sbassatsel */ + 0, + 0, /* rovpos,refpos */ + {300.0, 300.0, 300.0, 300.0}, /* eratio[] */ + {100.0, 0.003, 0.003, 0.0, 1.0, 52.0, 0.0, 0.0}, /* err[-,base,el,bl,dop,snr_max,snr,rcverr] */ + {30.0, 0.03, 0.3}, /* std[] */ + {1E-4, 1E-3, 1E-4, 1E-1, 1E-2, 0.0}, /* prn[] */ + 5E-12, /* sclkstab */ + {3.0, 0.25, 0.0, 1E-9, 1E-5, 3.0, 3.0, 0.0}, /* thresar */ + 0.0, + 0.0, + 0.05, + 0, /* elmaskar,elmaskhold,thresslip,thresdop, */ + 0.1, + 0.01, + 30.0, /* varholdamb,gainholdamb,maxtdif */ + {5.0, 30.0}, /* maxinno {phase,code} */ + {0}, + {0}, + {0}, /* baseline,ru,rb */ + {"", ""}, /* anttype */ + {{0}}, + {{0}}, + {0}, /* antdel,pcv,exsats */ + 1, + 1 /* maxaveep,initrst */ }; -const prcopt_t prcopt_default={ /* defaults processing options */ - PMODE_KINEMA,SOLTYPE_FORWARD, /* mode,soltype */ - 2,SYS_GPS|SYS_GLO|SYS_GAL, /* nf, navsys */ - 15.0*D2R,{{0,0}}, /* elmin,snrmask */ - 0,3,3,1,0,1, /* sateph,modear,glomodear,gpsmodear,bdsmodear,arfilter */ - 20,0,4,5,10,20, /* maxout,minlock,minfixsats,minholdsats,mindropsats,minfix */ - 1,1,1,1,0, /* armaxiter,estion,esttrop,dynamics,tidecorr */ - 1,0,0,0,0, /* niter,codesmooth,intpref,sbascorr,sbassatsel */ - 0,0, /* rovpos,refpos */ - {300.0,300.0,300.0,300.0}, /* eratio[] */ - {100.0,0.003,0.003,0.0,1.0,52.0,0.0,0.0}, /* err[-,base,el,bl,dop,snr_max,snr,rcverr] */ - {30.0,0.03,0.3}, /* std[] */ - {1E-4,1E-3,1E-4,1E-1,1E-2,0.0}, /* prn[] */ - 5E-12, /* sclkstab */ - {3.0,0.25,0.0,1E-9,1E-5,3.0,3.0,0.0}, /* thresar */ - 0.0,0.0,0.05,0, /* elmaskar,elmaskhold,thresslip,thresdop, */ - 0.1,0.01,30.0, /* varholdamb,gainholdamb,maxtdif */ - {5.0,30.0}, /* maxinno {phase,code} */ - {0},{0},{0}, /* baseline,ru,rb */ - {"",""}, /* anttype */ - {{0}},{{0}},{0}, /* antdel,pcv,exsats */ - 1,1 /* maxaveep,initrst */ +const solopt_t solopt_default = { + /* defaults solution output options */ + SOLF_LLH, TIMES_GPST, 1, 3, /* posf,times,timef,timeu */ + 0, 1, 0, 0, 0, 0, 0, /* degf,outhead,outopt,outvel,datum,height,geoid */ + 0, 0, 0, /* solstatic,sstat,trace */ + {0.0, 0.0}, /* nmeaintv */ + " ", "" /* separator/program name */ }; -const solopt_t solopt_default={ /* defaults solution output options */ - SOLF_LLH,TIMES_GPST,1,3, /* posf,times,timef,timeu */ - 0,1,0,0,0,0,0, /* degf,outhead,outopt,outvel,datum,height,geoid */ - 0,0,0, /* solstatic,sstat,trace */ - {0.0,0.0}, /* nmeaintv */ - " ","" /* separator/program name */ -}; -const char *formatstrs[32]={ /* stream format strings */ - "RTCM 2", /* 0 */ - "RTCM 3", /* 1 */ - "NovAtel OEM7", /* 2 */ - "------", /* 3 Comnav currently not supported*/ - "u-blox UBX", /* 4 */ - "Swift Navigation SBP", /* 5 */ - "Hemisphere", /* 6 */ - "SkyTraq", /* 7 */ - "Javad GREIS", /* 8 */ - "NVS BINR", /* 9 */ - "BINEX", /* 10 */ - "Trimble RT17", /* 11 */ - "Septentrio SBF", /* 12 */ - "------", /* 13 Tersus currently not supported */ - "Unicore", /* 14 */ - "RINEX", /* 15 */ - "SP3", /* 16 */ - "RINEX CLK", /* 17 */ - "SBAS", /* 18 */ - "NMEA 0183", /* 19 */ - NULL -}; - -static char *obscodes[MAXCODE + 1]={ /* observation code strings */ - - "" ,"1C","1P","1W","1Y", "1M","1N","1S","1L","1E", /* 0- 9 */ - "1A","1B","1X","1Z","2C", "2D","2S","2L","2X","2P", /* 10-19 */ - "2W","2Y","2M","2N","5I", "5Q","5X","7I","7Q","7X", /* 20-29 */ - "6A","6B","6C","6X","6Z", "6S","6L","8I","8Q","8X", /* 30-39 */ - "2I","2Q","6I","6Q","3I", "3Q","3X","1I","1Q","5A", /* 40-49 */ - "5B","5C","9A","9B","9C", "9X","1D","5D","5P","5Z", /* 50-59 */ - "6E","7D","7P","7Z","8D", "8P","4A","4B","4X","6D", /* 60-69 */ - "6P" -}; -static char codepris[7][MAXFREQ][16]={ /* code priority for each freq-index */ +const char *formatstrs[32] = { /* stream format strings */ + "RTCM 2", /* 0 */ + "RTCM 3", /* 1 */ + "NovAtel OEM7", /* 2 */ + "------", /* 3 Comnav currently not supported*/ + "u-blox UBX", /* 4 */ + "Swift Navigation SBP", /* 5 */ + "Hemisphere", /* 6 */ + "SkyTraq", /* 7 */ + "Javad GREIS", /* 8 */ + "NVS BINR", /* 9 */ + "BINEX", /* 10 */ + "Trimble RT17", /* 11 */ + "Septentrio SBF", /* 12 */ + "------", /* 13 Tersus currently not supported */ + "Unicore", /* 14 */ + "RINEX", /* 15 */ + "SP3", /* 16 */ + "RINEX CLK", /* 17 */ + "SBAS", /* 18 */ + "NMEA 0183", /* 19 */ + NULL}; + +static char *obscodes[MAXCODE + 1] = + {/* observation code strings */ + + "", "1C", "1P", "1W", "1Y", "1M", "1N", "1S", "1L", "1E", /* 0- 9 */ + "1A", "1B", "1X", "1Z", "2C", "2D", "2S", "2L", "2X", "2P", /* 10-19 */ + "2W", "2Y", "2M", "2N", "5I", "5Q", "5X", "7I", "7Q", "7X", /* 20-29 */ + "6A", "6B", "6C", "6X", "6Z", "6S", "6L", "8I", "8Q", "8X", /* 30-39 */ + "2I", "2Q", "6I", "6Q", "3I", "3Q", "3X", "1I", "1Q", "5A", /* 40-49 */ + "5B", "5C", "9A", "9B", "9C", "9X", "1D", "5D", "5P", "5Z", /* 50-59 */ + "6E", "7D", "7P", "7Z", "8D", "8P", "4A", "4B", "4X", "6D", /* 60-69 */ + "6P"}; +static char codepris[7][MAXFREQ][16] = { + /* code priority for each freq-index */ /* L1/E1/B1 L2/E5b/B2b L5/E5a/B2a E6/LEX/B3 E5(a+b) */ - {"CPYWMNSLX","CPYWMNDLSX","IQX" ,"" ,"" ,""}, /* GPS */ - {"CPABX" ,"CPABX" ,"IQX" ,"" ,"" ,""}, /* GLO */ - {"CABXZ" ,"XIQ" ,"XIQ" ,"ABCXZ" ,"IQX" ,""}, /* GAL */ - {"CLSXZBE" ,"LSX" ,"IQXDPZ" ,"LSXEZ" ,"" ,""}, /* QZS */ - {"C" ,"IQX" ,"" ,"" ,"" ,""}, /* SBS */ - {"IQX" ,"IQXDPZ" ,"DPX" ,"IQXDPZA","DPXSLZAN","DPX"}, /* BDS */ - {"ABCX" ,"ABCX" ,"DPX" ,"" ,"" ,""} /* IRN */ + {"CPYWMNSLX", "CPYWMNDLSX", "IQX", "", "", ""}, /* GPS */ + {"CPABX", "CPABX", "IQX", "", "", ""}, /* GLO */ + {"CABXZ", "XIQ", "XIQ", "ABCXZ", "IQX", ""}, /* GAL */ + {"CLSXZBE", "LSX", "IQXDPZ", "LSXEZ", "", ""}, /* QZS */ + {"C", "IQX", "", "", "", ""}, /* SBS */ + {"IQX", "IQXDPZ", "DPX", "IQXDPZA", "DPXSLZAN", "DPX"}, /* BDS */ + {"ABCX", "ABCX", "DPX", "", "", ""} /* IRN */ }; -static fatalfunc_t *fatalfunc=NULL; /* fatal callback function */ +static fatalfunc_t *fatalfunc = NULL; /* fatal callback function */ /* crc tables generated by util/gencrc ---------------------------------------*/ -static const uint16_t tbl_CRC16[]={ - 0x0000,0x1021,0x2042,0x3063,0x4084,0x50A5,0x60C6,0x70E7, - 0x8108,0x9129,0xA14A,0xB16B,0xC18C,0xD1AD,0xE1CE,0xF1EF, - 0x1231,0x0210,0x3273,0x2252,0x52B5,0x4294,0x72F7,0x62D6, - 0x9339,0x8318,0xB37B,0xA35A,0xD3BD,0xC39C,0xF3FF,0xE3DE, - 0x2462,0x3443,0x0420,0x1401,0x64E6,0x74C7,0x44A4,0x5485, - 0xA56A,0xB54B,0x8528,0x9509,0xE5EE,0xF5CF,0xC5AC,0xD58D, - 0x3653,0x2672,0x1611,0x0630,0x76D7,0x66F6,0x5695,0x46B4, - 0xB75B,0xA77A,0x9719,0x8738,0xF7DF,0xE7FE,0xD79D,0xC7BC, - 0x48C4,0x58E5,0x6886,0x78A7,0x0840,0x1861,0x2802,0x3823, - 0xC9CC,0xD9ED,0xE98E,0xF9AF,0x8948,0x9969,0xA90A,0xB92B, - 0x5AF5,0x4AD4,0x7AB7,0x6A96,0x1A71,0x0A50,0x3A33,0x2A12, - 0xDBFD,0xCBDC,0xFBBF,0xEB9E,0x9B79,0x8B58,0xBB3B,0xAB1A, - 0x6CA6,0x7C87,0x4CE4,0x5CC5,0x2C22,0x3C03,0x0C60,0x1C41, - 0xEDAE,0xFD8F,0xCDEC,0xDDCD,0xAD2A,0xBD0B,0x8D68,0x9D49, - 0x7E97,0x6EB6,0x5ED5,0x4EF4,0x3E13,0x2E32,0x1E51,0x0E70, - 0xFF9F,0xEFBE,0xDFDD,0xCFFC,0xBF1B,0xAF3A,0x9F59,0x8F78, - 0x9188,0x81A9,0xB1CA,0xA1EB,0xD10C,0xC12D,0xF14E,0xE16F, - 0x1080,0x00A1,0x30C2,0x20E3,0x5004,0x4025,0x7046,0x6067, - 0x83B9,0x9398,0xA3FB,0xB3DA,0xC33D,0xD31C,0xE37F,0xF35E, - 0x02B1,0x1290,0x22F3,0x32D2,0x4235,0x5214,0x6277,0x7256, - 0xB5EA,0xA5CB,0x95A8,0x8589,0xF56E,0xE54F,0xD52C,0xC50D, - 0x34E2,0x24C3,0x14A0,0x0481,0x7466,0x6447,0x5424,0x4405, - 0xA7DB,0xB7FA,0x8799,0x97B8,0xE75F,0xF77E,0xC71D,0xD73C, - 0x26D3,0x36F2,0x0691,0x16B0,0x6657,0x7676,0x4615,0x5634, - 0xD94C,0xC96D,0xF90E,0xE92F,0x99C8,0x89E9,0xB98A,0xA9AB, - 0x5844,0x4865,0x7806,0x6827,0x18C0,0x08E1,0x3882,0x28A3, - 0xCB7D,0xDB5C,0xEB3F,0xFB1E,0x8BF9,0x9BD8,0xABBB,0xBB9A, - 0x4A75,0x5A54,0x6A37,0x7A16,0x0AF1,0x1AD0,0x2AB3,0x3A92, - 0xFD2E,0xED0F,0xDD6C,0xCD4D,0xBDAA,0xAD8B,0x9DE8,0x8DC9, - 0x7C26,0x6C07,0x5C64,0x4C45,0x3CA2,0x2C83,0x1CE0,0x0CC1, - 0xEF1F,0xFF3E,0xCF5D,0xDF7C,0xAF9B,0xBFBA,0x8FD9,0x9FF8, - 0x6E17,0x7E36,0x4E55,0x5E74,0x2E93,0x3EB2,0x0ED1,0x1EF0 -}; -static const uint32_t tbl_CRC24Q[]={ - 0x000000,0x864CFB,0x8AD50D,0x0C99F6,0x93E6E1,0x15AA1A,0x1933EC,0x9F7F17, - 0xA18139,0x27CDC2,0x2B5434,0xAD18CF,0x3267D8,0xB42B23,0xB8B2D5,0x3EFE2E, - 0xC54E89,0x430272,0x4F9B84,0xC9D77F,0x56A868,0xD0E493,0xDC7D65,0x5A319E, - 0x64CFB0,0xE2834B,0xEE1ABD,0x685646,0xF72951,0x7165AA,0x7DFC5C,0xFBB0A7, - 0x0CD1E9,0x8A9D12,0x8604E4,0x00481F,0x9F3708,0x197BF3,0x15E205,0x93AEFE, - 0xAD50D0,0x2B1C2B,0x2785DD,0xA1C926,0x3EB631,0xB8FACA,0xB4633C,0x322FC7, - 0xC99F60,0x4FD39B,0x434A6D,0xC50696,0x5A7981,0xDC357A,0xD0AC8C,0x56E077, - 0x681E59,0xEE52A2,0xE2CB54,0x6487AF,0xFBF8B8,0x7DB443,0x712DB5,0xF7614E, - 0x19A3D2,0x9FEF29,0x9376DF,0x153A24,0x8A4533,0x0C09C8,0x00903E,0x86DCC5, - 0xB822EB,0x3E6E10,0x32F7E6,0xB4BB1D,0x2BC40A,0xAD88F1,0xA11107,0x275DFC, - 0xDCED5B,0x5AA1A0,0x563856,0xD074AD,0x4F0BBA,0xC94741,0xC5DEB7,0x43924C, - 0x7D6C62,0xFB2099,0xF7B96F,0x71F594,0xEE8A83,0x68C678,0x645F8E,0xE21375, - 0x15723B,0x933EC0,0x9FA736,0x19EBCD,0x8694DA,0x00D821,0x0C41D7,0x8A0D2C, - 0xB4F302,0x32BFF9,0x3E260F,0xB86AF4,0x2715E3,0xA15918,0xADC0EE,0x2B8C15, - 0xD03CB2,0x567049,0x5AE9BF,0xDCA544,0x43DA53,0xC596A8,0xC90F5E,0x4F43A5, - 0x71BD8B,0xF7F170,0xFB6886,0x7D247D,0xE25B6A,0x641791,0x688E67,0xEEC29C, - 0x3347A4,0xB50B5F,0xB992A9,0x3FDE52,0xA0A145,0x26EDBE,0x2A7448,0xAC38B3, - 0x92C69D,0x148A66,0x181390,0x9E5F6B,0x01207C,0x876C87,0x8BF571,0x0DB98A, - 0xF6092D,0x7045D6,0x7CDC20,0xFA90DB,0x65EFCC,0xE3A337,0xEF3AC1,0x69763A, - 0x578814,0xD1C4EF,0xDD5D19,0x5B11E2,0xC46EF5,0x42220E,0x4EBBF8,0xC8F703, - 0x3F964D,0xB9DAB6,0xB54340,0x330FBB,0xAC70AC,0x2A3C57,0x26A5A1,0xA0E95A, - 0x9E1774,0x185B8F,0x14C279,0x928E82,0x0DF195,0x8BBD6E,0x872498,0x016863, - 0xFAD8C4,0x7C943F,0x700DC9,0xF64132,0x693E25,0xEF72DE,0xE3EB28,0x65A7D3, - 0x5B59FD,0xDD1506,0xD18CF0,0x57C00B,0xC8BF1C,0x4EF3E7,0x426A11,0xC426EA, - 0x2AE476,0xACA88D,0xA0317B,0x267D80,0xB90297,0x3F4E6C,0x33D79A,0xB59B61, - 0x8B654F,0x0D29B4,0x01B042,0x87FCB9,0x1883AE,0x9ECF55,0x9256A3,0x141A58, - 0xEFAAFF,0x69E604,0x657FF2,0xE33309,0x7C4C1E,0xFA00E5,0xF69913,0x70D5E8, - 0x4E2BC6,0xC8673D,0xC4FECB,0x42B230,0xDDCD27,0x5B81DC,0x57182A,0xD154D1, - 0x26359F,0xA07964,0xACE092,0x2AAC69,0xB5D37E,0x339F85,0x3F0673,0xB94A88, - 0x87B4A6,0x01F85D,0x0D61AB,0x8B2D50,0x145247,0x921EBC,0x9E874A,0x18CBB1, - 0xE37B16,0x6537ED,0x69AE1B,0xEFE2E0,0x709DF7,0xF6D10C,0xFA48FA,0x7C0401, - 0x42FA2F,0xC4B6D4,0xC82F22,0x4E63D9,0xD11CCE,0x575035,0x5BC9C3,0xDD8538 -}; +static const uint16_t tbl_CRC16[] = { + 0x0000, 0x1021, 0x2042, 0x3063, 0x4084, 0x50A5, 0x60C6, 0x70E7, 0x8108, 0x9129, 0xA14A, 0xB16B, + 0xC18C, 0xD1AD, 0xE1CE, 0xF1EF, 0x1231, 0x0210, 0x3273, 0x2252, 0x52B5, 0x4294, 0x72F7, 0x62D6, + 0x9339, 0x8318, 0xB37B, 0xA35A, 0xD3BD, 0xC39C, 0xF3FF, 0xE3DE, 0x2462, 0x3443, 0x0420, 0x1401, + 0x64E6, 0x74C7, 0x44A4, 0x5485, 0xA56A, 0xB54B, 0x8528, 0x9509, 0xE5EE, 0xF5CF, 0xC5AC, 0xD58D, + 0x3653, 0x2672, 0x1611, 0x0630, 0x76D7, 0x66F6, 0x5695, 0x46B4, 0xB75B, 0xA77A, 0x9719, 0x8738, + 0xF7DF, 0xE7FE, 0xD79D, 0xC7BC, 0x48C4, 0x58E5, 0x6886, 0x78A7, 0x0840, 0x1861, 0x2802, 0x3823, + 0xC9CC, 0xD9ED, 0xE98E, 0xF9AF, 0x8948, 0x9969, 0xA90A, 0xB92B, 0x5AF5, 0x4AD4, 0x7AB7, 0x6A96, + 0x1A71, 0x0A50, 0x3A33, 0x2A12, 0xDBFD, 0xCBDC, 0xFBBF, 0xEB9E, 0x9B79, 0x8B58, 0xBB3B, 0xAB1A, + 0x6CA6, 0x7C87, 0x4CE4, 0x5CC5, 0x2C22, 0x3C03, 0x0C60, 0x1C41, 0xEDAE, 0xFD8F, 0xCDEC, 0xDDCD, + 0xAD2A, 0xBD0B, 0x8D68, 0x9D49, 0x7E97, 0x6EB6, 0x5ED5, 0x4EF4, 0x3E13, 0x2E32, 0x1E51, 0x0E70, + 0xFF9F, 0xEFBE, 0xDFDD, 0xCFFC, 0xBF1B, 0xAF3A, 0x9F59, 0x8F78, 0x9188, 0x81A9, 0xB1CA, 0xA1EB, + 0xD10C, 0xC12D, 0xF14E, 0xE16F, 0x1080, 0x00A1, 0x30C2, 0x20E3, 0x5004, 0x4025, 0x7046, 0x6067, + 0x83B9, 0x9398, 0xA3FB, 0xB3DA, 0xC33D, 0xD31C, 0xE37F, 0xF35E, 0x02B1, 0x1290, 0x22F3, 0x32D2, + 0x4235, 0x5214, 0x6277, 0x7256, 0xB5EA, 0xA5CB, 0x95A8, 0x8589, 0xF56E, 0xE54F, 0xD52C, 0xC50D, + 0x34E2, 0x24C3, 0x14A0, 0x0481, 0x7466, 0x6447, 0x5424, 0x4405, 0xA7DB, 0xB7FA, 0x8799, 0x97B8, + 0xE75F, 0xF77E, 0xC71D, 0xD73C, 0x26D3, 0x36F2, 0x0691, 0x16B0, 0x6657, 0x7676, 0x4615, 0x5634, + 0xD94C, 0xC96D, 0xF90E, 0xE92F, 0x99C8, 0x89E9, 0xB98A, 0xA9AB, 0x5844, 0x4865, 0x7806, 0x6827, + 0x18C0, 0x08E1, 0x3882, 0x28A3, 0xCB7D, 0xDB5C, 0xEB3F, 0xFB1E, 0x8BF9, 0x9BD8, 0xABBB, 0xBB9A, + 0x4A75, 0x5A54, 0x6A37, 0x7A16, 0x0AF1, 0x1AD0, 0x2AB3, 0x3A92, 0xFD2E, 0xED0F, 0xDD6C, 0xCD4D, + 0xBDAA, 0xAD8B, 0x9DE8, 0x8DC9, 0x7C26, 0x6C07, 0x5C64, 0x4C45, 0x3CA2, 0x2C83, 0x1CE0, 0x0CC1, + 0xEF1F, 0xFF3E, 0xCF5D, 0xDF7C, 0xAF9B, 0xBFBA, 0x8FD9, 0x9FF8, 0x6E17, 0x7E36, 0x4E55, 0x5E74, + 0x2E93, 0x3EB2, 0x0ED1, 0x1EF0}; +static const uint32_t tbl_CRC24Q[] = { + 0x000000, 0x864CFB, 0x8AD50D, 0x0C99F6, 0x93E6E1, 0x15AA1A, 0x1933EC, 0x9F7F17, 0xA18139, + 0x27CDC2, 0x2B5434, 0xAD18CF, 0x3267D8, 0xB42B23, 0xB8B2D5, 0x3EFE2E, 0xC54E89, 0x430272, + 0x4F9B84, 0xC9D77F, 0x56A868, 0xD0E493, 0xDC7D65, 0x5A319E, 0x64CFB0, 0xE2834B, 0xEE1ABD, + 0x685646, 0xF72951, 0x7165AA, 0x7DFC5C, 0xFBB0A7, 0x0CD1E9, 0x8A9D12, 0x8604E4, 0x00481F, + 0x9F3708, 0x197BF3, 0x15E205, 0x93AEFE, 0xAD50D0, 0x2B1C2B, 0x2785DD, 0xA1C926, 0x3EB631, + 0xB8FACA, 0xB4633C, 0x322FC7, 0xC99F60, 0x4FD39B, 0x434A6D, 0xC50696, 0x5A7981, 0xDC357A, + 0xD0AC8C, 0x56E077, 0x681E59, 0xEE52A2, 0xE2CB54, 0x6487AF, 0xFBF8B8, 0x7DB443, 0x712DB5, + 0xF7614E, 0x19A3D2, 0x9FEF29, 0x9376DF, 0x153A24, 0x8A4533, 0x0C09C8, 0x00903E, 0x86DCC5, + 0xB822EB, 0x3E6E10, 0x32F7E6, 0xB4BB1D, 0x2BC40A, 0xAD88F1, 0xA11107, 0x275DFC, 0xDCED5B, + 0x5AA1A0, 0x563856, 0xD074AD, 0x4F0BBA, 0xC94741, 0xC5DEB7, 0x43924C, 0x7D6C62, 0xFB2099, + 0xF7B96F, 0x71F594, 0xEE8A83, 0x68C678, 0x645F8E, 0xE21375, 0x15723B, 0x933EC0, 0x9FA736, + 0x19EBCD, 0x8694DA, 0x00D821, 0x0C41D7, 0x8A0D2C, 0xB4F302, 0x32BFF9, 0x3E260F, 0xB86AF4, + 0x2715E3, 0xA15918, 0xADC0EE, 0x2B8C15, 0xD03CB2, 0x567049, 0x5AE9BF, 0xDCA544, 0x43DA53, + 0xC596A8, 0xC90F5E, 0x4F43A5, 0x71BD8B, 0xF7F170, 0xFB6886, 0x7D247D, 0xE25B6A, 0x641791, + 0x688E67, 0xEEC29C, 0x3347A4, 0xB50B5F, 0xB992A9, 0x3FDE52, 0xA0A145, 0x26EDBE, 0x2A7448, + 0xAC38B3, 0x92C69D, 0x148A66, 0x181390, 0x9E5F6B, 0x01207C, 0x876C87, 0x8BF571, 0x0DB98A, + 0xF6092D, 0x7045D6, 0x7CDC20, 0xFA90DB, 0x65EFCC, 0xE3A337, 0xEF3AC1, 0x69763A, 0x578814, + 0xD1C4EF, 0xDD5D19, 0x5B11E2, 0xC46EF5, 0x42220E, 0x4EBBF8, 0xC8F703, 0x3F964D, 0xB9DAB6, + 0xB54340, 0x330FBB, 0xAC70AC, 0x2A3C57, 0x26A5A1, 0xA0E95A, 0x9E1774, 0x185B8F, 0x14C279, + 0x928E82, 0x0DF195, 0x8BBD6E, 0x872498, 0x016863, 0xFAD8C4, 0x7C943F, 0x700DC9, 0xF64132, + 0x693E25, 0xEF72DE, 0xE3EB28, 0x65A7D3, 0x5B59FD, 0xDD1506, 0xD18CF0, 0x57C00B, 0xC8BF1C, + 0x4EF3E7, 0x426A11, 0xC426EA, 0x2AE476, 0xACA88D, 0xA0317B, 0x267D80, 0xB90297, 0x3F4E6C, + 0x33D79A, 0xB59B61, 0x8B654F, 0x0D29B4, 0x01B042, 0x87FCB9, 0x1883AE, 0x9ECF55, 0x9256A3, + 0x141A58, 0xEFAAFF, 0x69E604, 0x657FF2, 0xE33309, 0x7C4C1E, 0xFA00E5, 0xF69913, 0x70D5E8, + 0x4E2BC6, 0xC8673D, 0xC4FECB, 0x42B230, 0xDDCD27, 0x5B81DC, 0x57182A, 0xD154D1, 0x26359F, + 0xA07964, 0xACE092, 0x2AAC69, 0xB5D37E, 0x339F85, 0x3F0673, 0xB94A88, 0x87B4A6, 0x01F85D, + 0x0D61AB, 0x8B2D50, 0x145247, 0x921EBC, 0x9E874A, 0x18CBB1, 0xE37B16, 0x6537ED, 0x69AE1B, + 0xEFE2E0, 0x709DF7, 0xF6D10C, 0xFA48FA, 0x7C0401, 0x42FA2F, 0xC4B6D4, 0xC82F22, 0x4E63D9, + 0xD11CCE, 0x575035, 0x5BC9C3, 0xDD8538}; /* function prototypes -------------------------------------------------------*/ #ifdef MKL #define LAPACK -#define dgemm_ dgemm -#define dgetrf_ dgetrf -#define dgetri_ dgetri -#define dgetrs_ dgetrs +#define dgemm_ dgemm +#define dgetrf_ dgetrf +#define dgetri_ dgetri +#define dgetrs_ dgetrs #endif #ifdef LAPACK -extern void dgemm_(char *, char *, int *, int *, int *, double *, double *, - int *, double *, int *, double *, double *, int *); +extern void dgemm_(char *, char *, int *, int *, int *, double *, double *, int *, double *, int *, + double *, double *, int *); extern void dgetrf_(int *, int *, double *, int *, int *, int *); extern void dgetri_(int *, double *, int *, int *, double *, int *, int *); -extern void dgetrs_(char *, int *, int *, double *, int *, int *, double *, - int *, int *); +extern void dgetrs_(char *, int *, int *, double *, int *, int *, double *, int *, int *); #endif #ifdef IERS_MODEL -extern int gmf_(double *mjd, double *lat, double *lon, double *hgt, double *zd, - double *gmfh, double *gmfw); +extern int gmf_(double *mjd, double *lat, double *lon, double *hgt, double *zd, double *gmfh, + double *gmfw); #endif /* fatal error ---------------------------------------------------------------*/ -static void fatalerr(const char *format, ...) -{ - char msg[1024]; - va_list ap; - va_start(ap,format); vsprintf(msg,format,ap); va_end(ap); - if (fatalfunc) fatalfunc(msg); - else fprintf(stderr,"%s",msg); - exit(-9); +static void fatalerr(const char *format, ...) { + char msg[1024]; + va_list ap; + va_start(ap, format); + vsprintf(msg, format, ap); + va_end(ap); + if (fatalfunc) + fatalfunc(msg); + else + fprintf(stderr, "%s", msg); + exit(-9); } /* add fatal callback function ------------------------------------------------- -* add fatal callback function for mat(),zeros(),imat() -* args : fatalfunc_t *func I callback function -* return : none -* notes : if malloc() failed in return : none -*-----------------------------------------------------------------------------*/ -extern void add_fatal(fatalfunc_t *func) -{ - fatalfunc=func; -} + * add fatal callback function for mat(),zeros(),imat() + * args : fatalfunc_t *func I callback function + * return : none + * notes : if malloc() failed in return : none + *-----------------------------------------------------------------------------*/ +extern void add_fatal(fatalfunc_t *func) { fatalfunc = func; } /* satellite system+prn/slot number to satellite number ------------------------ -* convert satellite system+prn/slot number to satellite number -* args : int sys I satellite system (SYS_GPS,SYS_GLO,...) -* int prn I satellite prn/slot number -* return : satellite number (0:error) -*-----------------------------------------------------------------------------*/ -extern int satno(int sys, int prn) -{ - if (prn<=0) return 0; - switch (sys) { - case SYS_GPS: - if (prnexsats[sat-1]==1) return 1; /* excluded satellite */ - if (opt->exsats[sat-1]==2) return 0; /* included satellite */ - if (!(sys&opt->navsys)) return 1; /* unselected sat sys */ - } - if (sys==SYS_QZS) svh&=0xFE; /* mask QZSS LEX health */ - if (sys == SYS_GLO) { - if ((svh & 9) != 0 || (svh & 6) == 4) { - trace(3,"unhealthy GLO satellite: sat=%3d svh=%02X\n",sat,svh); - return 1; - } - } else if (svh) { - trace(3,"unhealthy satellite: sat=%3d svh=%02X\n",sat,svh); - return 1; - } - if (var>MAX_VAR_EPH) { - trace(3,"invalid ura satellite: sat=%3d ura=%.2f\n",sat,sqrt(var)); - return 1; + * test excluded satellite + * args : int sat I satellite number + * double var I variance of ephemeris (m^2) + * int svh I sv health flag + * prcopt_t *opt I processing options (NULL: not used) + * return : status (1:excluded,0:not excluded) + *-----------------------------------------------------------------------------*/ +extern int satexclude(int sat, double var, int svh, const prcopt_t *opt) { + int sys = satsys(sat, NULL); + + if (svh < 0) return 1; /* ephemeris unavailable */ + + if (opt) { + if (opt->exsats[sat - 1] == 1) return 1; /* excluded satellite */ + if (opt->exsats[sat - 1] == 2) return 0; /* included satellite */ + if (!(sys & opt->navsys)) return 1; /* unselected sat sys */ + } + if (sys == SYS_QZS) svh &= 0xFE; /* mask QZSS LEX health */ + if (sys == SYS_GLO) { + if ((svh & 9) != 0 || (svh & 6) == 4) { + trace(3, "unhealthy GLO satellite: sat=%3d svh=%02X\n", sat, svh); + return 1; } - return 0; + } else if (svh) { + trace(3, "unhealthy satellite: sat=%3d svh=%02X\n", sat, svh); + return 1; + } + if (var > MAX_VAR_EPH) { + trace(3, "invalid ura satellite: sat=%3d ura=%.2f\n", sat, sqrt(var)); + return 1; + } + return 0; } /* test SNR mask --------------------------------------------------------------- -* test SNR mask -* args : int base I rover or base-station (0:rover,1:base station) -* int idx I frequency index (0:L1,1:L2,2:L3,...) -* double el I elevation angle (rad) -* double snr I C/N0 (dBHz) -* snrmask_t *mask I SNR mask -* return : status (1:masked,0:unmasked) -*-----------------------------------------------------------------------------*/ -extern int testsnr(int base, int idx, double el, double snr, - const snrmask_t *mask) -{ - double minsnr,a; - int i; - - if (!mask->ena[base]||idx<0||idx>=NFREQ) return 0; - - a=(el*R2D+5.0)/10.0; - i=(int)floor(a); a-=i; - if (i<1) minsnr=mask->mask[idx][0]; - else if (i>8) minsnr=mask->mask[idx][8]; - else minsnr=(1.0-a)*mask->mask[idx][i-1]+a*mask->mask[idx][i]; - - return snrena[base] || idx < 0 || idx >= NFREQ) return 0; + + a = (el * R2D + 5.0) / 10.0; + i = (int)floor(a); + a -= i; + if (i < 1) + minsnr = mask->mask[idx][0]; + else if (i > 8) + minsnr = mask->mask[idx][8]; + else + minsnr = (1.0 - a) * mask->mask[idx][i - 1] + a * mask->mask[idx][i]; + + return snr < minsnr; } /* obs type string to obs code ------------------------------------------------- -* convert obs code type string to obs code -* args : char *str I obs code string ("1C","1P","1Y",...) -* return : obs code (CODE_???) -* notes : obs codes are based on RINEX 3.04 -*-----------------------------------------------------------------------------*/ -extern uint8_t obs2code(const char *obs) -{ - int i; - - for (i=1;i <= MAXCODE;i++) { - if (strcmp(obscodes[i],obs)) continue; - return (uint8_t)i; - } - return CODE_NONE; + * convert obs code type string to obs code + * args : char *str I obs code string ("1C","1P","1Y",...) + * return : obs code (CODE_???) + * notes : obs codes are based on RINEX 3.04 + *-----------------------------------------------------------------------------*/ +extern uint8_t obs2code(const char *obs) { + int i; + + for (i = 1; i <= MAXCODE; i++) { + if (strcmp(obscodes[i], obs)) continue; + return (uint8_t)i; + } + return CODE_NONE; } /* obs code to obs code string ------------------------------------------------- -* convert obs code to obs code string -* args : uint8_t code I obs code (CODE_???) -* return : obs code string ("1C","1P","1P",...) -* notes : obs codes are based on RINEX 3.04 -*-----------------------------------------------------------------------------*/ -extern char *code2obs(uint8_t code) -{ - if (code<=CODE_NONE||MAXCODE6) return -1; - *freq=FREQ1_GLO+DFRQ1_GLO*fcn; - return 0; - case '2': /* G2 */ - if (fcn<-7||fcn>6) return -1; - *freq=FREQ2_GLO+DFRQ2_GLO*fcn; - return 1; - case '3': *freq=FREQ3_GLO; return 2; /* G3 */ - case '4': *freq=FREQ1a_GLO; return 0; /* G1a */ - case '6': *freq=FREQ2a_GLO; return 1; /* G2a */ - } - return -1; +static int code2freq_GLO(uint8_t code, int fcn, double *freq) { + char *obs = code2obs(code); + + switch (obs[0]) { + case '1': /* G1 */ + if (fcn < -7 || fcn > 6) return -1; + *freq = FREQ1_GLO + DFRQ1_GLO * fcn; + return 0; + case '2': /* G2 */ + if (fcn < -7 || fcn > 6) return -1; + *freq = FREQ2_GLO + DFRQ2_GLO * fcn; + return 1; + case '3': + *freq = FREQ3_GLO; + return 2; /* G3 */ + case '4': + *freq = FREQ1a_GLO; + return 0; /* G1a */ + case '6': + *freq = FREQ2a_GLO; + return 1; /* G2a */ + } + return -1; } /* Galileo obs code to frequency ---------------------------------------------*/ -static int code2freq_GAL(uint8_t code, double *freq) -{ - char *obs=code2obs(code); - - switch (obs[0]) { - case '1': *freq=FREQL1; return 0; /* E1 */ - case '7': *freq=FREQE5b; return 1; /* E5b */ - case '5': *freq=FREQL5; return 2; /* E5a */ - case '6': *freq=FREQL6; return 3; /* E6 */ - case '8': *freq=FREQE5ab; return 4; /* E5ab */ - } - return -1; +static int code2freq_GAL(uint8_t code, double *freq) { + char *obs = code2obs(code); + + switch (obs[0]) { + case '1': + *freq = FREQL1; + return 0; /* E1 */ + case '7': + *freq = FREQE5b; + return 1; /* E5b */ + case '5': + *freq = FREQL5; + return 2; /* E5a */ + case '6': + *freq = FREQL6; + return 3; /* E6 */ + case '8': + *freq = FREQE5ab; + return 4; /* E5ab */ + } + return -1; } /* QZSS obs code to frequency ------------------------------------------------*/ -static int code2freq_QZS(uint8_t code, double *freq) -{ - char *obs=code2obs(code); - - switch (obs[0]) { - case '1': *freq=FREQL1; return 0; /* L1 */ - case '2': *freq=FREQL2; return 1; /* L2 */ - case '5': *freq=FREQL5; return 2; /* L5 */ - case '6': *freq=FREQL6; return 3; /* L6 */ - } - return -1; +static int code2freq_QZS(uint8_t code, double *freq) { + char *obs = code2obs(code); + + switch (obs[0]) { + case '1': + *freq = FREQL1; + return 0; /* L1 */ + case '2': + *freq = FREQL2; + return 1; /* L2 */ + case '5': + *freq = FREQL5; + return 2; /* L5 */ + case '6': + *freq = FREQL6; + return 3; /* L6 */ + } + return -1; } /* SBAS obs code to frequency ------------------------------------------------*/ -static int code2freq_SBS(uint8_t code, double *freq) -{ - char *obs=code2obs(code); - - switch (obs[0]) { - case '1': *freq=FREQL1; return 0; /* L1 */ - case '5': *freq=FREQL5; return 1; /* L5 */ - } - return -1; +static int code2freq_SBS(uint8_t code, double *freq) { + char *obs = code2obs(code); + + switch (obs[0]) { + case '1': + *freq = FREQL1; + return 0; /* L1 */ + case '5': + *freq = FREQL5; + return 1; /* L5 */ + } + return -1; } /* BDS obs code to frequency -------------------------------------------------*/ -static int code2freq_BDS(uint8_t code, double *freq) -{ - char *obs=code2obs(code); - - switch (obs[0]) { - case '2': *freq=FREQ1_CMP; return 0; /* B1I */ - case '7': *freq=FREQ2_CMP; return 1; /* B2,B2b */ - case '5': *freq=FREQL5; return 2; /* B2a */ - case '6': *freq=FREQ3_CMP; return 3; /* B3 */ - case '1': *freq=FREQL1; return 4; /* B1C,B1A */ - case '8': *freq=FREQE5ab; return 5; /* B2ab */ - } - return -1; +static int code2freq_BDS(uint8_t code, double *freq) { + char *obs = code2obs(code); + + switch (obs[0]) { + case '2': + *freq = FREQ1_CMP; + return 0; /* B1I */ + case '7': + *freq = FREQ2_CMP; + return 1; /* B2,B2b */ + case '5': + *freq = FREQL5; + return 2; /* B2a */ + case '6': + *freq = FREQ3_CMP; + return 3; /* B3 */ + case '1': + *freq = FREQL1; + return 4; /* B1C,B1A */ + case '8': + *freq = FREQE5ab; + return 5; /* B2ab */ + } + return -1; } /* NavIC obs code to frequency -----------------------------------------------*/ -static int code2freq_IRN(uint8_t code, double *freq) -{ - char *obs=code2obs(code); - - switch (obs[0]) { - case '5': *freq=FREQL5; return 0; /* L5 */ - case '9': *freq=FREQs; return 1; /* S */ - case '1': *freq=FREQL1; return 2; /* L1 */ - } - return -1; +static int code2freq_IRN(uint8_t code, double *freq) { + char *obs = code2obs(code); + + switch (obs[0]) { + case '5': + *freq = FREQL5; + return 0; /* L5 */ + case '9': + *freq = FREQs; + return 1; /* S */ + case '1': + *freq = FREQL1; + return 2; /* L1 */ + } + return -1; } /* system and obs code to frequency index -------------------------------------- -* convert system and obs code to frequency index -* args : int sys I satellite system (SYS_???) -* uint8_t code I obs code (CODE_???) -* return : frequency index (-1: error) -* 0 1 2 3 4 5 -* --------------------------------------------- -* GPS L1 L2 L5 - - - -* GLONASS G1 G2 G3 - - - (G1=G1,G1a,G2=G2,G2a) -* Galileo E1 E5b E5a E6 E5ab - -* QZSS L1 L2 L5 L6 - - -* SBAS L1 - L5 - - - -* BDS B1 B2b B2a B3 B1C B2ab -* NavIC L5 S L1 - - - -*-----------------------------------------------------------------------------*/ -extern int code2idx(int sys, uint8_t code) -{ - double freq; - - switch (sys) { - case SYS_GPS: return code2freq_GPS(code,&freq); - case SYS_GLO: return code2freq_GLO(code,0,&freq); - case SYS_GAL: return code2freq_GAL(code,&freq); - case SYS_QZS: return code2freq_QZS(code,&freq); - case SYS_SBS: return code2freq_SBS(code,&freq); - case SYS_CMP: return code2freq_BDS(code,&freq); - case SYS_IRN: return code2freq_IRN(code,&freq); - } - return -1; + * convert system and obs code to frequency index + * args : int sys I satellite system (SYS_???) + * uint8_t code I obs code (CODE_???) + * return : frequency index (-1: error) + * 0 1 2 3 4 5 + * --------------------------------------------- + * GPS L1 L2 L5 - - - + * GLONASS G1 G2 G3 - - - (G1=G1,G1a,G2=G2,G2a) + * Galileo E1 E5b E5a E6 E5ab - + * QZSS L1 L2 L5 L6 - - + * SBAS L1 - L5 - - - + * BDS B1 B2b B2a B3 B1C B2ab + * NavIC L5 S L1 - - - + *-----------------------------------------------------------------------------*/ +extern int code2idx(int sys, uint8_t code) { + double freq; + + switch (sys) { + case SYS_GPS: + return code2freq_GPS(code, &freq); + case SYS_GLO: + return code2freq_GLO(code, 0, &freq); + case SYS_GAL: + return code2freq_GAL(code, &freq); + case SYS_QZS: + return code2freq_QZS(code, &freq); + case SYS_SBS: + return code2freq_SBS(code, &freq); + case SYS_CMP: + return code2freq_BDS(code, &freq); + case SYS_IRN: + return code2freq_IRN(code, &freq); + } + return -1; } /* system and obs code to frequency -------------------------------------------- -* convert system and obs code to carrier frequency -* args : int sys I satellite system (SYS_???) -* uint8_t code I obs code (CODE_???) -* int fcn I frequency channel number for GLONASS -* return : carrier frequency (Hz) (0.0: error) -*-----------------------------------------------------------------------------*/ -extern double code2freq(int sys, uint8_t code, int fcn) -{ - double freq=0.0; - - switch (sys) { - case SYS_GPS: (void)code2freq_GPS(code,&freq); break; - case SYS_GLO: (void)code2freq_GLO(code,fcn,&freq); break; - case SYS_GAL: (void)code2freq_GAL(code,&freq); break; - case SYS_QZS: (void)code2freq_QZS(code,&freq); break; - case SYS_SBS: (void)code2freq_SBS(code,&freq); break; - case SYS_CMP: (void)code2freq_BDS(code,&freq); break; - case SYS_IRN: (void)code2freq_IRN(code,&freq); break; - } - return freq; + * convert system and obs code to carrier frequency + * args : int sys I satellite system (SYS_???) + * uint8_t code I obs code (CODE_???) + * int fcn I frequency channel number for GLONASS + * return : carrier frequency (Hz) (0.0: error) + *-----------------------------------------------------------------------------*/ +extern double code2freq(int sys, uint8_t code, int fcn) { + double freq = 0.0; + + switch (sys) { + case SYS_GPS: + (void)code2freq_GPS(code, &freq); + break; + case SYS_GLO: + (void)code2freq_GLO(code, fcn, &freq); + break; + case SYS_GAL: + (void)code2freq_GAL(code, &freq); + break; + case SYS_QZS: + (void)code2freq_QZS(code, &freq); + break; + case SYS_SBS: + (void)code2freq_SBS(code, &freq); + break; + case SYS_CMP: + (void)code2freq_BDS(code, &freq); + break; + case SYS_IRN: + (void)code2freq_IRN(code, &freq); + break; + } + return freq; } /* satellite and obs code to frequency ----------------------------------------- -* convert satellite and obs code to carrier frequency -* args : int sat I satellite number -* uint8_t code I obs code (CODE_???) -* nav_t *nav_t I navigation data for GLONASS (NULL: not used) -* return : carrier frequency (Hz) (0.0: error) -*-----------------------------------------------------------------------------*/ -extern double sat2freq(int sat, uint8_t code, const nav_t *nav) -{ - int i,fcn=-8,sys,prn; - - sys=satsys(sat,&prn); - - if (sys==SYS_GLO && nav) { - /* First non-empty entry */ - for (i=0;ing;i++) { - if (nav->geph[i].sat==sat) break; - } - if (ing) { - fcn=nav->geph[i].frq; - } - else if (nav->glo_fcn[prn-1]>0) { - fcn=nav->glo_fcn[prn-1]-8; - } + * convert satellite and obs code to carrier frequency + * args : int sat I satellite number + * uint8_t code I obs code (CODE_???) + * nav_t *nav_t I navigation data for GLONASS (NULL: not used) + * return : carrier frequency (Hz) (0.0: error) + *-----------------------------------------------------------------------------*/ +extern double sat2freq(int sat, uint8_t code, const nav_t *nav) { + int i, fcn = -8, sys, prn; + + sys = satsys(sat, &prn); + + if (sys == SYS_GLO && nav) { + /* First non-empty entry */ + for (i = 0; i < nav->ng; i++) { + if (nav->geph[i].sat == sat) break; + } + if (i < nav->ng) { + fcn = nav->geph[i].frq; + } else if (nav->glo_fcn[prn - 1] > 0) { + fcn = nav->glo_fcn[prn - 1] - 8; } - return code2freq(sys,code,fcn); + } + return code2freq(sys, code, fcn); } /* set code priority ----------------------------------------------------------- -* set code priority for multiple codes in a frequency -* args : int sys I system (or of SYS_???) -* int idx I frequency index (0- ) -* char *pri I priority of codes (series of code characters) -* (higher priority precedes lower) -* return : none -*-----------------------------------------------------------------------------*/ -extern void setcodepri(int sys, int idx, const char *pri) -{ - trace(3,"setcodepri:sys=%d idx=%d pri=%s\n",sys,idx,pri); - - if (idx<0||idx>=MAXFREQ) return; - if (sys&SYS_GPS) strcpy(codepris[0][idx],pri); - if (sys&SYS_GLO) strcpy(codepris[1][idx],pri); - if (sys&SYS_GAL) strcpy(codepris[2][idx],pri); - if (sys&SYS_QZS) strcpy(codepris[3][idx],pri); - if (sys&SYS_SBS) strcpy(codepris[4][idx],pri); - if (sys&SYS_CMP) strcpy(codepris[5][idx],pri); - if (sys&SYS_IRN) strcpy(codepris[6][idx],pri); + * set code priority for multiple codes in a frequency + * args : int sys I system (or of SYS_???) + * int idx I frequency index (0- ) + * char *pri I priority of codes (series of code characters) + * (higher priority precedes lower) + * return : none + *-----------------------------------------------------------------------------*/ +extern void setcodepri(int sys, int idx, const char *pri) { + trace(3, "setcodepri:sys=%d idx=%d pri=%s\n", sys, idx, pri); + + if (idx < 0 || idx >= MAXFREQ) return; + if (sys & SYS_GPS) strcpy(codepris[0][idx], pri); + if (sys & SYS_GLO) strcpy(codepris[1][idx], pri); + if (sys & SYS_GAL) strcpy(codepris[2][idx], pri); + if (sys & SYS_QZS) strcpy(codepris[3][idx], pri); + if (sys & SYS_SBS) strcpy(codepris[4][idx], pri); + if (sys & SYS_CMP) strcpy(codepris[5][idx], pri); + if (sys & SYS_IRN) strcpy(codepris[6][idx], pri); } /* get code priority ----------------------------------------------------------- -* get code priority for multiple codes in a frequency -* args : int sys I system (SYS_???) -* uint8_t code I obs code (CODE_???) -* char *opt I code options (NULL:no option) -* return : priority (15:highest-1:lowest,0:error) -*-----------------------------------------------------------------------------*/ -extern int getcodepri(int sys, uint8_t code, const char *opt) -{ - const char *p,*optstr; - char *obs,str[8]=""; - int i,j; - - switch (sys) { - case SYS_GPS: i=0; optstr="-GL%2s"; break; - case SYS_GLO: i=1; optstr="-RL%2s"; break; - case SYS_GAL: i=2; optstr="-EL%2s"; break; - case SYS_QZS: i=3; optstr="-JL%2s"; break; - case SYS_SBS: i=4; optstr="-SL%2s"; break; - case SYS_CMP: i=5; optstr="-CL%2s"; break; - case SYS_IRN: i=6; optstr="-IL%2s"; break; - default: return 0; - } - if ((j=code2idx(sys,code))<0) return 0; - obs=code2obs(code); + * get code priority for multiple codes in a frequency + * args : int sys I system (SYS_???) + * uint8_t code I obs code (CODE_???) + * char *opt I code options (NULL:no option) + * return : priority (15:highest-1:lowest,0:error) + *-----------------------------------------------------------------------------*/ +extern int getcodepri(int sys, uint8_t code, const char *opt) { + const char *p, *optstr; + char *obs, str[8] = ""; + int i, j; + + switch (sys) { + case SYS_GPS: + i = 0; + optstr = "-GL%2s"; + break; + case SYS_GLO: + i = 1; + optstr = "-RL%2s"; + break; + case SYS_GAL: + i = 2; + optstr = "-EL%2s"; + break; + case SYS_QZS: + i = 3; + optstr = "-JL%2s"; + break; + case SYS_SBS: + i = 4; + optstr = "-SL%2s"; + break; + case SYS_CMP: + i = 5; + optstr = "-CL%2s"; + break; + case SYS_IRN: + i = 6; + optstr = "-IL%2s"; + break; + default: + return 0; + } + if ((j = code2idx(sys, code)) < 0) return 0; + obs = code2obs(code); - /* parse code options */ - for (p=opt;p&&(p=strchr(p,'-'));p++) { - if (sscanf(p,optstr,str)<1||str[0]!=obs[0]) continue; - return str[1]==obs[1]?15:0; - } - /* search code priority */ - return (p=strchr(codepris[i][j],obs[1]))?14-(int)(p-codepris[i][j]):0; + /* parse code options */ + for (p = opt; p && (p = strchr(p, '-')); p++) { + if (sscanf(p, optstr, str) < 1 || str[0] != obs[0]) continue; + return str[1] == obs[1] ? 15 : 0; + } + /* search code priority */ + return (p = strchr(codepris[i][j], obs[1])) ? 14 - (int)(p - codepris[i][j]) : 0; } /* extract unsigned/signed bits ------------------------------------------------ -* extract unsigned/signed bits from byte data -* args : uint8_t *buff I byte data -* int pos I bit position from start of data (bits) -* int len I bit length (bits) (len<=32) -* return : extracted unsigned/signed bits -*-----------------------------------------------------------------------------*/ -extern uint32_t getbitu(const uint8_t *buff, int pos, int len) -{ - uint32_t bits=0; - int i; - for (i=pos;i>(7-i%8))&1u); - return bits; -} -extern int32_t getbits(const uint8_t *buff, int pos, int len) -{ - uint32_t bits=getbitu(buff,pos,len); - if (len<=0||32<=len||!(bits&(1u<<(len-1)))) return (int32_t)bits; - return (int32_t)(bits|(~0u<> (7 - i % 8)) & 1u); + return bits; +} +extern int32_t getbits(const uint8_t *buff, int pos, int len) { + uint32_t bits = getbitu(buff, pos, len); + if (len <= 0 || 32 <= len || !(bits & (1u << (len - 1)))) return (int32_t)bits; + return (int32_t)(bits | (~0u << len)); /* extend sign */ } /* set unsigned/signed bits ---------------------------------------------------- -* set unsigned/signed bits to byte data -* args : uint8_t *buff IO byte data -* int pos I bit position from start of data (bits) -* int len I bit length (bits) (len<=32) -* [u]int32_t data I unsigned/signed data -* return : none -*-----------------------------------------------------------------------------*/ -extern void setbitu(uint8_t *buff, int pos, int len, uint32_t data) -{ - uint32_t mask=1u<<(len-1); - int i; - if (len<=0||32>=1) { - if (data&mask) buff[i/8]|=1u<<(7-i%8); else buff[i/8]&=~(1u<<(7-i%8)); - } + * set unsigned/signed bits to byte data + * args : uint8_t *buff IO byte data + * int pos I bit position from start of data (bits) + * int len I bit length (bits) (len<=32) + * [u]int32_t data I unsigned/signed data + * return : none + *-----------------------------------------------------------------------------*/ +extern void setbitu(uint8_t *buff, int pos, int len, uint32_t data) { + uint32_t mask = 1u << (len - 1); + int i; + if (len <= 0 || 32 < len) return; + for (i = pos; i < pos + len; i++, mask >>= 1) { + if (data & mask) + buff[i / 8] |= 1u << (7 - i % 8); + else + buff[i / 8] &= ~(1u << (7 - i % 8)); + } } -extern void setbits(uint8_t *buff, int pos, int len, int32_t data) -{ - if (data<0) data|=1<<(len-1); else data&=~(1<<(len-1)); /* set sign bit */ - setbitu(buff,pos,len,(uint32_t)data); +extern void setbits(uint8_t *buff, int pos, int len, int32_t data) { + if (data < 0) + data |= 1 << (len - 1); + else + data &= ~(1 << (len - 1)); /* set sign bit */ + setbitu(buff, pos, len, (uint32_t)data); } /* crc-32 parity --------------------------------------------------------------- -* compute crc-32 parity for novatel raw -* args : uint8_t *buff I data -* int len I data length (bytes) -* return : crc-32 parity -* notes : see NovAtel OEMV firmware manual 1.7 32-bit CRC -*-----------------------------------------------------------------------------*/ -extern uint32_t rtk_crc32(const uint8_t *buff, int len) -{ - uint32_t crc=0; - int i,j; - - trace(4,"rtk_crc32: len=%d\n",len); - - for (i=0;i>1)^POLYCRC32; else crc>>=1; - } + * compute crc-32 parity for novatel raw + * args : uint8_t *buff I data + * int len I data length (bytes) + * return : crc-32 parity + * notes : see NovAtel OEMV firmware manual 1.7 32-bit CRC + *-----------------------------------------------------------------------------*/ +extern uint32_t rtk_crc32(const uint8_t *buff, int len) { + uint32_t crc = 0; + int i, j; + + trace(4, "rtk_crc32: len=%d\n", len); + + for (i = 0; i < len; i++) { + crc ^= buff[i]; + for (j = 0; j < 8; j++) { + if (crc & 1) + crc = (crc >> 1) ^ POLYCRC32; + else + crc >>= 1; } - return crc; + } + return crc; } /* crc-24q parity -------------------------------------------------------------- -* compute crc-24q parity for sbas, rtcm3 -* args : uint8_t *buff I data -* int len I data length (bytes) -* return : crc-24Q parity -* notes : see reference [2] A.4.3.3 Parity -*-----------------------------------------------------------------------------*/ -extern uint32_t rtk_crc24q(const uint8_t *buff, int len) -{ - uint32_t crc=0; - int i; - - trace(4,"rtk_crc24q: len=%d\n",len); - - for (i=0;i>16)^buff[i]]; - return crc; + * compute crc-24q parity for sbas, rtcm3 + * args : uint8_t *buff I data + * int len I data length (bytes) + * return : crc-24Q parity + * notes : see reference [2] A.4.3.3 Parity + *-----------------------------------------------------------------------------*/ +extern uint32_t rtk_crc24q(const uint8_t *buff, int len) { + uint32_t crc = 0; + int i; + + trace(4, "rtk_crc24q: len=%d\n", len); + + for (i = 0; i < len; i++) crc = ((crc << 8) & 0xFFFFFF) ^ tbl_CRC24Q[(crc >> 16) ^ buff[i]]; + return crc; } /* crc-16 parity --------------------------------------------------------------- -* compute crc-16 parity for binex, nvs -* args : uint8_t *buff I data -* int len I data length (bytes) -* return : crc-16 parity -* notes : see reference [10] A.3. -*-----------------------------------------------------------------------------*/ -extern uint16_t rtk_crc16(const uint8_t *buff, int len) -{ - uint16_t crc=0; - int i; - - trace(4,"rtk_crc16: len=%d\n",len); - - for (i=0;i>8)^buff[i])&0xFF]; - } - return crc; + * compute crc-16 parity for binex, nvs + * args : uint8_t *buff I data + * int len I data length (bytes) + * return : crc-16 parity + * notes : see reference [10] A.3. + *-----------------------------------------------------------------------------*/ +extern uint16_t rtk_crc16(const uint8_t *buff, int len) { + uint16_t crc = 0; + int i; + + trace(4, "rtk_crc16: len=%d\n", len); + + for (i = 0; i < len; i++) { + crc = (crc << 8) ^ tbl_CRC16[((crc >> 8) ^ buff[i]) & 0xFF]; + } + return crc; } /* decode navigation data word ------------------------------------------------- -* check party and decode navigation data word -* args : uint32_t word I navigation data word (2+30bit) -* (previous word D29*-30* + current word D1-30) -* uint8_t *data O decoded navigation data without parity -* (8bitx3) -* return : status (1:ok,0:parity error) -* notes : see reference [1] 20.3.5.2 user parity algorithm -*-----------------------------------------------------------------------------*/ -extern int decode_word(uint32_t word, uint8_t *data) -{ - const uint32_t hamming[]={ - 0xBB1F3480,0x5D8F9A40,0xAEC7CD00,0x5763E680,0x6BB1F340,0x8B7A89C0 - }; - uint32_t parity=0,w; - int i; - - trace(5,"decodeword: word=%08x\n",word); - - if (word&0x40000000) word^=0x3FFFFFC0; - - for (i=0;i<6;i++) { - parity<<=1; - for (w=(word&hamming[i])>>6;w;w>>=1) parity^=w&1; - } - if (parity!=(word&0x3F)) return 0; + * check party and decode navigation data word + * args : uint32_t word I navigation data word (2+30bit) + * (previous word D29*-30* + current word D1-30) + * uint8_t *data O decoded navigation data without parity + * (8bitx3) + * return : status (1:ok,0:parity error) + * notes : see reference [1] 20.3.5.2 user parity algorithm + *-----------------------------------------------------------------------------*/ +extern int decode_word(uint32_t word, uint8_t *data) { + const uint32_t hamming[] = {0xBB1F3480, 0x5D8F9A40, 0xAEC7CD00, + 0x5763E680, 0x6BB1F340, 0x8B7A89C0}; + uint32_t parity = 0, w; + int i; - for (i=0;i<3;i++) data[i]=(uint8_t)(word>>(22-i*8)); - return 1; + trace(5, "decodeword: word=%08x\n", word); + + if (word & 0x40000000) word ^= 0x3FFFFFC0; + + for (i = 0; i < 6; i++) { + parity <<= 1; + for (w = (word & hamming[i]) >> 6; w; w >>= 1) parity ^= w & 1; + } + if (parity != (word & 0x3F)) return 0; + + for (i = 0; i < 3; i++) data[i] = (uint8_t)(word >> (22 - i * 8)); + return 1; } /* new matrix ------------------------------------------------------------------ -* allocate memory of matrix -* args : int n,m I number of rows and columns of matrix -* return : matrix pointer (if n<=0 or m<=0, return NULL) -*-----------------------------------------------------------------------------*/ -extern double *mat(int n, int m) -{ - double *p; - - if (n<=0||m<=0) return NULL; - if (!(p=(double *)malloc(sizeof(double)*n*m))) { - fatalerr("matrix memory allocation error: n=%d,m=%d\n",n,m); - } - return p; + * allocate memory of matrix + * args : int n,m I number of rows and columns of matrix + * return : matrix pointer (if n<=0 or m<=0, return NULL) + *-----------------------------------------------------------------------------*/ +extern double *mat(int n, int m) { + double *p; + + if (n <= 0 || m <= 0) return NULL; + if (!(p = (double *)malloc(sizeof(double) * n * m))) { + fatalerr("matrix memory allocation error: n=%d,m=%d\n", n, m); + } + return p; } /* new integer matrix ---------------------------------------------------------- -* allocate memory of integer matrix -* args : int n,m I number of rows and columns of matrix -* return : matrix pointer (if n<=0 or m<=0, return NULL) -*-----------------------------------------------------------------------------*/ -extern int *imat(int n, int m) -{ - int *p; - - if (n<=0||m<=0) return NULL; - if (!(p=(int *)malloc(sizeof(int)*n*m))) { - fatalerr("integer matrix memory allocation error: n=%d,m=%d\n",n,m); - } - return p; + * allocate memory of integer matrix + * args : int n,m I number of rows and columns of matrix + * return : matrix pointer (if n<=0 or m<=0, return NULL) + *-----------------------------------------------------------------------------*/ +extern int *imat(int n, int m) { + int *p; + + if (n <= 0 || m <= 0) return NULL; + if (!(p = (int *)malloc(sizeof(int) * n * m))) { + fatalerr("integer matrix memory allocation error: n=%d,m=%d\n", n, m); + } + return p; } /* zero matrix ----------------------------------------------------------------- -* generate new zero matrix -* args : int n,m I number of rows and columns of matrix -* return : matrix pointer (if n<=0 or m<=0, return NULL) -*-----------------------------------------------------------------------------*/ -extern double *zeros(int n, int m) -{ - double *p; + * generate new zero matrix + * args : int n,m I number of rows and columns of matrix + * return : matrix pointer (if n<=0 or m<=0, return NULL) + *-----------------------------------------------------------------------------*/ +extern double *zeros(int n, int m) { + double *p; #if NOCALLOC - if ((p=mat(n,m))) for (n=n*m-1;n>=0;n--) p[n]=0.0; + if ((p = mat(n, m))) + for (n = n * m - 1; n >= 0; n--) p[n] = 0.0; #else - if (n<=0||m<=0) return NULL; - if (!(p=(double *)calloc(n*m,sizeof(double)))) { - fatalerr("matrix memory allocation error: n=%d,m=%d\n",n,m); - } + if (n <= 0 || m <= 0) return NULL; + if (!(p = (double *)calloc(n * m, sizeof(double)))) { + fatalerr("matrix memory allocation error: n=%d,m=%d\n", n, m); + } #endif - return p; + return p; } /* identity matrix ------------------------------------------------------------- -* generate new identity matrix -* args : int n I number of rows and columns of matrix -* return : matrix pointer (if n<=0, return NULL) -*-----------------------------------------------------------------------------*/ -extern double *eye(int n) -{ - double *p; - int i; + * generate new identity matrix + * args : int n I number of rows and columns of matrix + * return : matrix pointer (if n<=0, return NULL) + *-----------------------------------------------------------------------------*/ +extern double *eye(int n) { + double *p; + int i; - if ((p=zeros(n,n))) for (i=0;i=0) c+=a[n]*b[n]; - return c; + while (--n >= 0) c += a[n] * b[n]; + return c; } /* euclid norm ----------------------------------------------------------------- -* euclid norm of vector -* args : double *a I vector a (n x 1) -* int n I size of vector a -* return : || a || -*-----------------------------------------------------------------------------*/ -extern double norm(const double *a, int n) -{ - return sqrt(dot(a,a,n)); -} + * euclid norm of vector + * args : double *a I vector a (n x 1) + * int n I size of vector a + * return : || a || + *-----------------------------------------------------------------------------*/ +extern double norm(const double *a, int n) { return sqrt(dot(a, a, n)); } /* outer product of 3d vectors ------------------------------------------------- -* outer product of 3d vectors -* args : double *a,*b I vector a,b (3 x 1) -* double *c O outer product (a x b) (3 x 1) -* return : none -*-----------------------------------------------------------------------------*/ -extern void cross3(const double *a, const double *b, double *c) -{ - c[0]=a[1]*b[2]-a[2]*b[1]; - c[1]=a[2]*b[0]-a[0]*b[2]; - c[2]=a[0]*b[1]-a[1]*b[0]; + * outer product of 3d vectors + * args : double *a,*b I vector a,b (3 x 1) + * double *c O outer product (a x b) (3 x 1) + * return : none + *-----------------------------------------------------------------------------*/ +extern void cross3(const double *a, const double *b, double *c) { + c[0] = a[1] * b[2] - a[2] * b[1]; + c[1] = a[2] * b[0] - a[0] * b[2]; + c[2] = a[0] * b[1] - a[1] * b[0]; } /* normalize 3d vector --------------------------------------------------------- -* normalize 3d vector -* args : double *a I vector a (3 x 1) -* double *b O normalized vector (3 x 1) || b || = 1 -* return : status (1:ok,0:error) -*-----------------------------------------------------------------------------*/ -extern int normv3(const double *a, double *b) -{ - double r; - if ((r=norm(a,3))<=0.0) return 0; - b[0]=a[0]/r; - b[1]=a[1]/r; - b[2]=a[2]/r; - return 1; + * normalize 3d vector + * args : double *a I vector a (3 x 1) + * double *b O normalized vector (3 x 1) || b || = 1 + * return : status (1:ok,0:error) + *-----------------------------------------------------------------------------*/ +extern int normv3(const double *a, double *b) { + double r; + if ((r = norm(a, 3)) <= 0.0) return 0; + b[0] = a[0] / r; + b[1] = a[1] / r; + b[2] = a[2] / r; + return 1; } /* copy matrix ----------------------------------------------------------------- -* copy matrix -* args : double *A O destination matrix A (n x m) -* double *B I source matrix B (n x m) -* int n,m I number of rows and columns of matrix -* return : none -*-----------------------------------------------------------------------------*/ -extern void matcpy(double *A, const double *B, int n, int m) -{ - memcpy(A,B,sizeof(double)*n*m); + * copy matrix + * args : double *A O destination matrix A (n x m) + * double *B I source matrix B (n x m) + * int n,m I number of rows and columns of matrix + * return : none + *-----------------------------------------------------------------------------*/ +extern void matcpy(double *A, const double *B, int n, int m) { + memcpy(A, B, sizeof(double) * n * m); } /* matrix routines -----------------------------------------------------------*/ #ifdef LAPACK /* with LAPACK/BLAS or MKL */ /* multiply matrix (wrapper of blas dgemm) ------------------------------------- -* multiply matrix by matrix (C=A*B) -* args : char *tr I transpose flags ("N":normal,"T":transpose) -* int n,k,m I size of (transposed) matrix A,B -* double *A,*B I (transposed) matrix A (n x m), B (m x k) -* double *C O matrix C (n x k) -* return : none -*-----------------------------------------------------------------------------*/ -extern void matmul(const char *tr, int n, int k, int m, - const double *A, const double *B, double *C) -{ - int lda=tr[0]=='T'?m:n,ldb=tr[1]=='T'?k:m; - const double alpha=1,beta=0; - - dgemm_((char *)tr,(char *)tr+1,&n,&k,&m,&alpha,(double *)A,&lda,(double *)B, - &ldb,&beta,C,&n); + * multiply matrix by matrix (C=A*B) + * args : char *tr I transpose flags ("N":normal,"T":transpose) + * int n,k,m I size of (transposed) matrix A,B + * double *A,*B I (transposed) matrix A (n x m), B (m x k) + * double *C O matrix C (n x k) + * return : none + *-----------------------------------------------------------------------------*/ +extern void matmul(const char *tr, int n, int k, int m, const double *A, const double *B, + double *C) { + int lda = tr[0] == 'T' ? m : n, ldb = tr[1] == 'T' ? k : m; + const double alpha = 1, beta = 0; + + dgemm_((char *)tr, (char *)tr + 1, &n, &k, &m, &alpha, (double *)A, &lda, (double *)B, &ldb, + &beta, C, &n); } /* multiply matrix (wrapper of blas dgemm) ------------------------------------- -* multiply matrix by matrix (C=C+A*B) -*-----------------------------------------------------------------------------*/ -extern void matmulp(const char *tr, int n, int k, int m, - const double *A, const double *B, double *C) -{ - int lda=tr[0]=='T'?m:n,ldb=tr[1]=='T'?k:m; - const double alpha=1,beta=1; + * multiply matrix by matrix (C=C+A*B) + *-----------------------------------------------------------------------------*/ +extern void matmulp(const char *tr, int n, int k, int m, const double *A, const double *B, + double *C) { + int lda = tr[0] == 'T' ? m : n, ldb = tr[1] == 'T' ? k : m; + const double alpha = 1, beta = 1; - dgemm_((char *)tr,(char *)tr+1,&n,&k,&m,&alpha,(double *)A,&lda,(double *)B, - &ldb,&beta,C,&n); + dgemm_((char *)tr, (char *)tr + 1, &n, &k, &m, &alpha, (double *)A, &lda, (double *)B, &ldb, + &beta, C, &n); } /* multiply matrix (wrapper of blas dgemm) ------------------------------------- -* multiply matrix by matrix (C=C-A*B) -*-----------------------------------------------------------------------------*/ -extern void matmulm(const char *tr, int n, int k, int m, - const double *A, const double *B, double *C) -{ - int lda=tr[0]=='T'?m:n,ldb=tr[1]=='T'?k:m; - const double alpha=-1,beta=1; - - dgemm_((char *)tr,(char *)tr+1,&n,&k,&m,&alpha,(double *)A,&lda,(double *)B, - &ldb,&beta,C,&n); + * multiply matrix by matrix (C=C-A*B) + *-----------------------------------------------------------------------------*/ +extern void matmulm(const char *tr, int n, int k, int m, const double *A, const double *B, + double *C) { + int lda = tr[0] == 'T' ? m : n, ldb = tr[1] == 'T' ? k : m; + const double alpha = -1, beta = 1; + + dgemm_((char *)tr, (char *)tr + 1, &n, &k, &m, &alpha, (double *)A, &lda, (double *)B, &ldb, + &beta, C, &n); } /* inverse of matrix ----------------------------------------------------------- -* inverse of matrix (A=A^-1) -* args : double *A IO matrix (n x n) -* int n I size of matrix A -* return : status (0:ok,0>:error) -*-----------------------------------------------------------------------------*/ -extern int matinv(double *A, int n) -{ - double *work; - int info,lwork=n*16,*ipiv=imat(n,1); - - work=mat(lwork,1); - dgetrf_(&n,&n,A,&n,ipiv,&info); - if (!info) dgetri_(&n,A,&n,ipiv,work,&lwork,&info); - free(ipiv); free(work); - return info; + * inverse of matrix (A=A^-1) + * args : double *A IO matrix (n x n) + * int n I size of matrix A + * return : status (0:ok,0>:error) + *-----------------------------------------------------------------------------*/ +extern int matinv(double *A, int n) { + double *work; + int info, lwork = n * 16, *ipiv = imat(n, 1); + + work = mat(lwork, 1); + dgetrf_(&n, &n, A, &n, ipiv, &info); + if (!info) dgetri_(&n, A, &n, ipiv, work, &lwork, &info); + free(ipiv); + free(work); + return info; } /* solve linear equation ------------------------------------------------------- -* solve linear equation (X=A\Y or X=A'\Y) -* args : char *tr I transpose flag ("N":normal,"T":transpose) -* double *A I input matrix A (n x n) -* double *Y I input matrix Y (n x m) -* int n,m I size of matrix A,Y -* double *X O X=A\Y or X=A'\Y (n x m) -* return : status (0:ok,0>:error) -* notes : matrix stored by column-major order (fortran convention) -* X can be same as Y -*-----------------------------------------------------------------------------*/ -extern int solve(const char *tr, const double *A, const double *Y, int n, - int m, double *X) -{ - double *B=mat(n,n); - int info,*ipiv=imat(n,1); - - matcpy(B,A,n,n); - matcpy(X,Y,n,m); - dgetrf_(&n,&n,B,&n,ipiv,&info); - if (!info) dgetrs_((char *)tr,&n,&m,B,&n,ipiv,X,&n,&info); - free(ipiv); free(B); - return info; + * solve linear equation (X=A\Y or X=A'\Y) + * args : char *tr I transpose flag ("N":normal,"T":transpose) + * double *A I input matrix A (n x n) + * double *Y I input matrix Y (n x m) + * int n,m I size of matrix A,Y + * double *X O X=A\Y or X=A'\Y (n x m) + * return : status (0:ok,0>:error) + * notes : matrix stored by column-major order (fortran convention) + * X can be same as Y + *-----------------------------------------------------------------------------*/ +extern int solve(const char *tr, const double *A, const double *Y, int n, int m, double *X) { + double *B = mat(n, n); + int info, *ipiv = imat(n, 1); + + matcpy(B, A, n, n); + matcpy(X, Y, n, m); + dgetrf_(&n, &n, B, &n, ipiv, &info); + if (!info) dgetrs_((char *)tr, &n, &m, B, &n, ipiv, X, &n, &info); + free(ipiv); + free(B); + return info; } #else /* without LAPACK/BLAS or MKL */ /* multiply matrix -----------------------------------------------------------*/ -extern void matmul(const char *tr, int n, int k, int m, - const double *A, const double *B, double *C) -{ - int f=(tr[0]!='N')*2+(tr[1]!='N'); - - switch (f) { - case 0: /* NN */ - for (int j=0;jbig) big=tmp; - if (big>0.0) vv[i]=1.0/big; else {free(vv); return -1;} - } - for (j=0;j=big) {big=tmp; imax=i;} + } + break; + case 1: /* NT */ + for (int j = 0; j < k; j++) { + for (int i = 0; i < n; i++) { + double d = 0.0; + for (int x = 0; x < m; x++) d += A[i + x * n] * B[j + x * k]; + C[i + j * n] -= d; } - if (j!=imax) { - for (k=0;k=0) for (j=ii;j big) big = tmp; + if (big > 0.0) + vv[i] = 1.0 / big; + else { + free(vv); + return -1; + } + } + for (j = 0; j < n; j++) { + for (i = 0; i < j; i++) { + s = A[i + j * n]; + for (k = 0; k < i; k++) s -= A[i + k * n] * A[k + j * n]; + A[i + j * n] = s; + } + big = 0.0; + for (i = j; i < n; i++) { + s = A[i + j * n]; + for (k = 0; k < j; k++) s -= A[i + k * n] * A[k + j * n]; + A[i + j * n] = s; + if ((tmp = vv[i] * fabs(s)) >= big) { + big = tmp; + imax = i; + } } - for (i=n-1;i>=0;i--) { - s=b[i]; for (j=i+1;j= 0) + for (j = ii; j < i; j++) s -= A[i + j * n] * b[j]; + else if (s) + ii = i; + b[i] = s; + } + for (i = n - 1; i >= 0; i--) { + s = b[i]; + for (j = i + 1; j < n; j++) s -= A[i + j * n] * b[j]; + b[i] = s / A[i + i * n]; + } } /* inverse of matrix ---------------------------------------------------------*/ -extern int matinv(double *A, int n) -{ - double d,*B; - int i,j,*indx; - - indx=imat(n,1); B=mat(n,n); matcpy(B,A,n,n); - if (ludcmp(B,n,indx,&d)) {free(indx); free(B); return -1;} - for (j=0;j:error) -* notes : for weighted least square, replace A and y by A*w and w*y (w=W^(1/2)) -* matrix stored by column-major order (fortran convention) -*-----------------------------------------------------------------------------*/ -extern int lsq(const double *A, const double *y, int n, int m, double *x, - double *Q) -{ - double *Ay; - int info; - - if (m:error) + * notes : for weighted least square, replace A and y by A*w and w*y (w=W^(1/2)) + * matrix stored by column-major order (fortran convention) + *-----------------------------------------------------------------------------*/ +extern int lsq(const double *A, const double *y, int n, int m, double *x, double *Q) { + double *Ay; + int info; + + if (m < n) return -1; + Ay = mat(n, 1); + matmul("NN", n, 1, m, A, y, Ay); /* Ay=A*y */ + matmul("NT", n, n, m, A, A, Q); /* Q=A*A' */ + if (!(info = matinv(Q, n))) matmul("NN", n, 1, n, Q, Ay, x); /* x=Q^-1*Ay */ + free(Ay); + return info; } /* kalman filter --------------------------------------------------------------- -* kalman filter state update as follows: -* -* K=P*H*(H'*P*H+R)^-1, xp=x+K*v, Pp=(I-K*H')*P -* -* args : double *x I states vector (n x 1) -* double *P I covariance matrix of states (n x n) -* double *H I transpose of design matrix (n x m) -* double *v I innovation (measurement - model) (m x 1) -* double *R I covariance matrix of measurement error (m x m) -* int n,m I number of states and measurements -* double *xp O states vector after update (n x 1) -* double *Pp O covariance matrix of states after update (n x n) -* return : status (0:ok,<0:error) -* notes : matrix stored by column-major order (fortran convention) -* if state x[i]==0.0, not updates state x[i]/P[i+i*n] -*-----------------------------------------------------------------------------*/ -static int filter_(const double *x, const double *P, const double *H, - const double *v, const double *R, int n, int m, - double *xp, double *Pp) -{ - double *F=mat(n,m),*Q=mat(m,m),*K=mat(n,m),*I=eye(n); - int info; - - matcpy(Q,R,m,m); - matcpy(xp,x,n,1); - matmul("NN",n,m,n,P,H,F); /* Q=H'*P*H+R */ - matmulp("TN",m,m,n,H,F,Q); - if (!(info=matinv(Q,m))) { - matmul("NN",n,m,m,F,Q,K); /* K=P*H*Q^-1 */ - matmulp("NN",n,1,m,K,v,xp); /* xp=x+K*v */ - matmulm("NT",n,n,m,K,H,I); /* Pp=(I-K*H')*P */ - matmul("NN",n,n,n,I,P,Pp); - } - free(F); free(Q); free(K); free(I); - return info; -} -extern int filter(double *x, double *P, const double *H, const double *v, - const double *R, int n, int m) -{ - double *x_,*xp_,*P_,*Pp_,*H_; - int i,j,k,info,*ix; - - /* create list of non-zero states */ - ix=imat(n,1); for (i=k=0;i0.0) ix[k++]=i; - x_=mat(k,1); xp_=mat(k,1); P_=mat(k,k); Pp_=mat(k,k); H_=mat(k,m); - /* compress array by removing zero elements to save computation time */ - for (i=0;i 0.0) ix[k++] = i; + x_ = mat(k, 1); + xp_ = mat(k, 1); + P_ = mat(k, k); + Pp_ = mat(k, k); + H_ = mat(k, m); + /* compress array by removing zero elements to save computation time */ + for (i = 0; i < k; i++) { + x_[i] = x[ix[i]]; + for (j = 0; j < k; j++) P_[i + j * k] = P[ix[i] + ix[j] * n]; + for (j = 0; j < m; j++) H_[i + j * k] = H[ix[i] + j * n]; + } + /* do kalman filter state update on compressed arrays */ + info = filter_(x_, P_, H_, v, R, k, m, xp_, Pp_); + /* copy values from compressed arrays back to full arrays */ + for (i = 0; i < k; i++) { + x[ix[i]] = xp_[i]; + for (j = 0; j < k; j++) P[ix[i] + ix[j] * n] = Pp_[i + j * k]; + } + free(ix); + free(x_); + free(xp_); + free(P_); + free(Pp_); + free(H_); + return info; } /* smoother -------------------------------------------------------------------- -* combine forward and backward filters by fixed-interval smoother as follows: -* -* xs=Qs*(Qf^-1*xf+Qb^-1*xb), Qs=(Qf^-1+Qb^-1)^-1) -* -* args : double *xf I forward solutions (n x 1) -* args : double *Qf I forward solutions covariance matrix (n x n) -* double *xb I backward solutions (n x 1) -* double *Qb I backward solutions covariance matrix (n x n) -* int n I number of solutions -* double *xs O smoothed solutions (n x 1) -* double *Qs O smoothed solutions covariance matrix (n x n) -* return : status (0:ok,0>:error) -* notes : see reference [4] 5.2 -* matrix stored by column-major order (fortran convention) -*-----------------------------------------------------------------------------*/ -extern int smoother(const double *xf, const double *Qf, const double *xb, - const double *Qb, int n, double *xs, double *Qs) -{ - double *invQf=mat(n,n),*invQb=mat(n,n),*xx=mat(n,1); - int i,info=-1; - - matcpy(invQf,Qf,n,n); - matcpy(invQb,Qb,n,n); - if (!matinv(invQf,n)&&!matinv(invQb,n)) { - for (i=0;i:error) + * notes : see reference [4] 5.2 + * matrix stored by column-major order (fortran convention) + *-----------------------------------------------------------------------------*/ +extern int smoother(const double *xf, const double *Qf, const double *xb, const double *Qb, int n, + double *xs, double *Qs) { + double *invQf = mat(n, n), *invQb = mat(n, n), *xx = mat(n, 1); + int i, info = -1; + + matcpy(invQf, Qf, n, n); + matcpy(invQb, Qb, n, n); + if (!matinv(invQf, n) && !matinv(invQb, n)) { + for (i = 0; i < n * n; i++) Qs[i] = invQf[i] + invQb[i]; + if (!(info = matinv(Qs, n))) { + matmul("NN", n, 1, n, invQf, xf, xx); + matmulp("NN", n, 1, n, invQb, xb, xx); + matmul("NN", n, 1, n, Qs, xx, xs); } - free(invQf); free(invQb); free(xx); - return info; + } + free(invQf); + free(invQb); + free(xx); + return info; } /* print matrix ---------------------------------------------------------------- -* print matrix to stdout -* args : double *A I matrix A (n x m) -* int n,m I number of rows and columns of A -* int p,q I total columns, columns under decimal point -* (FILE *fp I output file pointer) -* return : none -* notes : matrix stored by column-major order (fortran convention) -*-----------------------------------------------------------------------------*/ -extern void matfprint(const double A[], int n, int m, int p, int q, FILE *fp) -{ - int i,j; - - for (i=0;i=dst&&(*p==' '||*p=='\r'||*p=='\n'||*p=='\t')) *p--='\0'; +extern void setstr(char *dst, const char *src, int n) { + char *p = dst; + const char *q = src; + while (*q && q < src + n) *p++ = *q++; + *p-- = '\0'; + while (p >= dst && (*p == ' ' || *p == '\r' || *p == '\n' || *p == '\t')) *p-- = '\0'; } /* string to number ------------------------------------------------------------ -* convert substring in string to number -* args : char *s I string ("... nnn.nnn ...") -* int i,n I substring position and width -* return : converted number (0.0:error) -*-----------------------------------------------------------------------------*/ -extern double str2num(const char *s, int i, int n) -{ - char str[256],*p=str; - - if (i<0||(int)sizeof(str)-10&&(int)strlen(s)=0;s++) { - char c=*s; - if (!c) break; - *p++=((c|0x20)=='d')?'E':c; - } - *p='\0'; - return strtod(str,NULL); + * convert substring in string to number + * args : char *s I string ("... nnn.nnn ...") + * int i,n I substring position and width + * return : converted number (0.0:error) + *-----------------------------------------------------------------------------*/ +extern double str2num(const char *s, int i, int n) { + char str[256], *p = str; + + if (i < 0 || (int)sizeof(str) - 1 < n) return 0.0; + /* Special case i==0, skipping the strlen check. + * Note: Could usefully use strnlen(s,i) here */ + if (i > 0 && (int)strlen(s) < i) return 0.0; + + for (s += i; --n >= 0; s++) { + char c = *s; + if (!c) break; + *p++ = ((c | 0x20) == 'd') ? 'E' : c; + } + *p = '\0'; + return strtod(str, NULL); } /* string to time -------------------------------------------------------------- -* convert substring in string to gtime_t struct -* args : char *s I string ("... yyyy mm dd hh mm ss ...") -* int i,n I substring position and width -* gtime_t *t O gtime_t struct -* return : status (0:ok,0>:error) -*-----------------------------------------------------------------------------*/ -extern int str2time(const char *s, int i, int n, gtime_t *t) -{ - double ep[6]; - char str[256],*p=str; - - if (i<0||(int)strlen(s)=0;) *p++=*s++; - *p='\0'; - if (sscanf(str,"%lf %lf %lf %lf %lf %lf",ep,ep+1,ep+2,ep+3,ep+4,ep+5)<6) - return -1; - if (ep[0]<100.0) ep[0]+=ep[0]<80.0?2000.0:1900.0; - *t=epoch2time(ep); - return 0; + * convert substring in string to gtime_t struct + * args : char *s I string ("... yyyy mm dd hh mm ss ...") + * int i,n I substring position and width + * gtime_t *t O gtime_t struct + * return : status (0:ok,0>:error) + *-----------------------------------------------------------------------------*/ +extern int str2time(const char *s, int i, int n, gtime_t *t) { + double ep[6]; + char str[256], *p = str; + + if (i < 0 || (int)strlen(s) < i || (int)sizeof(str) - 1 < i) return -1; + for (s += i; *s && --n >= 0;) *p++ = *s++; + *p = '\0'; + if (sscanf(str, "%lf %lf %lf %lf %lf %lf", ep, ep + 1, ep + 2, ep + 3, ep + 4, ep + 5) < 6) + return -1; + if (ep[0] < 100.0) ep[0] += ep[0] < 80.0 ? 2000.0 : 1900.0; + *t = epoch2time(ep); + return 0; } /* convert calendar day/time to time ------------------------------------------- -* convert calendar day/time to gtime_t struct -* args : double *ep I day/time {year,month,day,hour,min,sec} -* return : gtime_t struct -* notes : proper in 1970-2037 or 1970-2099 (64bit time_t) -*-----------------------------------------------------------------------------*/ -extern gtime_t epoch2time(const double *ep) -{ - const int doy[]={1,32,60,91,121,152,182,213,244,274,305,335}; - gtime_t time={0}; - int days,sec,year=(int)ep[0],mon=(int)ep[1],day=(int)ep[2]; - - if (year<1970||2099=3?1:0); - sec=(int)floor(ep[5]); - time.time=(time_t)days*86400+(int)ep[3]*3600+(int)ep[4]*60+sec; - time.sec=ep[5]-sec; - return time; + * convert calendar day/time to gtime_t struct + * args : double *ep I day/time {year,month,day,hour,min,sec} + * return : gtime_t struct + * notes : proper in 1970-2037 or 1970-2099 (64bit time_t) + *-----------------------------------------------------------------------------*/ +extern gtime_t epoch2time(const double *ep) { + const int doy[] = {1, 32, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335}; + gtime_t time = {0}; + int days, sec, year = (int)ep[0], mon = (int)ep[1], day = (int)ep[2]; + + if (year < 1970 || 2099 < year || mon < 1 || 12 < mon) return time; + + /* leap year if year%4==0 in 1901-2099 */ + days = (year - 1970) * 365 + (year - 1969) / 4 + doy[mon - 1] + day - 2 + + (year % 4 == 0 && mon >= 3 ? 1 : 0); + sec = (int)floor(ep[5]); + time.time = (time_t)days * 86400 + (int)ep[3] * 3600 + (int)ep[4] * 60 + sec; + time.sec = ep[5] - sec; + return time; } /* time to calendar day/time --------------------------------------------------- -* convert gtime_t struct to calendar day/time -* args : gtime_t t I gtime_t struct -* double *ep O day/time {year,month,day,hour,min,sec} -* return : none -* notes : proper in 1970-2037 or 1970-2099 (64bit time_t) -*-----------------------------------------------------------------------------*/ -extern void time2epoch(gtime_t t, double *ep) -{ - const int mday[]={ /* # of days in a month */ - 31,28,31,30,31,30,31,31,30,31,30,31,31,28,31,30,31,30,31,31,30,31,30,31, - 31,29,31,30,31,30,31,31,30,31,30,31,31,28,31,30,31,30,31,31,30,31,30,31 - }; - int days,sec,mon,day; - - /* leap year if year%4==0 in 1901-2099 */ - days=(int)(t.time/86400); - sec=(int)(t.time-(time_t)days*86400); - for (day=days%1461,mon=0;mon<48;mon++) { - if (day>=mday[mon]) day-=mday[mon]; else break; - } - ep[0]=1970+days/1461*4+mon/12; ep[1]=mon%12+1; ep[2]=day+1; - ep[3]=sec/3600; ep[4]=sec%3600/60; ep[5]=sec%60+t.sec; + * convert gtime_t struct to calendar day/time + * args : gtime_t t I gtime_t struct + * double *ep O day/time {year,month,day,hour,min,sec} + * return : none + * notes : proper in 1970-2037 or 1970-2099 (64bit time_t) + *-----------------------------------------------------------------------------*/ +extern void time2epoch(gtime_t t, double *ep) { + const int mday[] = {/* # of days in a month */ + 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31, 31, 28, 31, 30, + 31, 30, 31, 31, 30, 31, 30, 31, 31, 29, 31, 30, 31, 30, 31, 31, + 30, 31, 30, 31, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; + int days, sec, mon, day; + + /* leap year if year%4==0 in 1901-2099 */ + days = (int)(t.time / 86400); + sec = (int)(t.time - (time_t)days * 86400); + for (day = days % 1461, mon = 0; mon < 48; mon++) { + if (day >= mday[mon]) + day -= mday[mon]; + else + break; + } + ep[0] = 1970 + days / 1461 * 4 + mon / 12; + ep[1] = mon % 12 + 1; + ep[2] = day + 1; + ep[3] = sec / 3600; + ep[4] = sec % 3600 / 60; + ep[5] = sec % 60 + t.sec; } /* same as above but output limited to n decimals for formatted output */ -extern void time2epoch_n(gtime_t t, double *ep, int n) -{ - if (n<0) n=0; else if (n>12) n=12; - if (1.0-t.sec<0.5/pow(10.0,n)) {t.time++; t.sec=0.0;}; - time2epoch(t,ep); +extern void time2epoch_n(gtime_t t, double *ep, int n) { + if (n < 0) + n = 0; + else if (n > 12) + n = 12; + if (1.0 - t.sec < 0.5 / pow(10.0, n)) { + t.time++; + t.sec = 0.0; + }; + time2epoch(t, ep); } /* gps time to time ------------------------------------------------------------ -* convert week and tow in gps time to gtime_t struct -* args : int week I week number in gps time -* double sec I time of week in gps time (s) -* return : gtime_t struct -*-----------------------------------------------------------------------------*/ -extern gtime_t gpst2time(int week, double sec) -{ - gtime_t t=epoch2time(gpst0); - - if (sec<-1E9||1E9=13) continue; - ls[n][0]=y; - ls[n][1]=m; - ls[n][2]=d; - ls[n++][6]=(char)(19.0-tai_utc); - } - for (i=0;i= 13) continue; + ls[n][0] = y; + ls[n][1] = m; + ls[n][2] = d; + ls[n++][6] = (char)(19.0 - tai_utc); + } + for (i = 0; i < n; i++) + for (j = 0; j < 7; j++) { + leaps[i][j] = ls[n - i - 1][j]; } - return n; + return n; } /* read leap seconds table ----------------------------------------------------- -* read leap seconds table -* args : char *file I leap seconds table file -* return : status (1:ok,0:error) -* notes : The leap second table should be as follows or leapsec.dat provided -* by USNO. -* (1) The records in the table file consist of the following fields: -* year month day hour min sec UTC-GPST(s) -* (2) The date and time indicate the start UTC time for the UTC-GPST -* (3) The date and time should be descending order. -*-----------------------------------------------------------------------------*/ -extern int read_leaps(const char *file) -{ - FILE *fp; - int i,n; - - if (!(fp=fopen(file,"r"))) return 0; - - /* read leap seconds table by text or usno */ - if (!(n=read_leaps_text(fp))&&!(n=read_leaps_usno(fp))) { - fclose(fp); - return 0; - } - for (i=0;i<7;i++) leaps[n][i]=0.0; + * read leap seconds table + * args : char *file I leap seconds table file + * return : status (1:ok,0:error) + * notes : The leap second table should be as follows or leapsec.dat provided + * by USNO. + * (1) The records in the table file consist of the following fields: + * year month day hour min sec UTC-GPST(s) + * (2) The date and time indicate the start UTC time for the UTC-GPST + * (3) The date and time should be descending order. + *-----------------------------------------------------------------------------*/ +extern int read_leaps(const char *file) { + FILE *fp; + int i, n; + + if (!(fp = fopen(file, "r"))) return 0; + + /* read leap seconds table by text or usno */ + if (!(n = read_leaps_text(fp)) && !(n = read_leaps_usno(fp))) { fclose(fp); - return 1; + return 0; + } + for (i = 0; i < 7; i++) leaps[n][i] = 0.0; + fclose(fp); + return 1; } /* gpstime to utc -------------------------------------------------------------- -* convert gpstime to utc considering leap seconds -* args : gtime_t t I time expressed in gpstime -* return : time expressed in utc -* notes : ignore slight time offset under 100 ns -*-----------------------------------------------------------------------------*/ -extern gtime_t gpst2utc(gtime_t t) -{ - gtime_t tu; - int i; - - for (i=0;leaps[i][0]>0;i++) { - tu=timeadd(t,leaps[i][6]); - if (timediff(tu,epoch2time(leaps[i]))>=0.0) return tu; - } - return t; + * convert gpstime to utc considering leap seconds + * args : gtime_t t I time expressed in gpstime + * return : time expressed in utc + * notes : ignore slight time offset under 100 ns + *-----------------------------------------------------------------------------*/ +extern gtime_t gpst2utc(gtime_t t) { + gtime_t tu; + int i; + + for (i = 0; leaps[i][0] > 0; i++) { + tu = timeadd(t, leaps[i][6]); + if (timediff(tu, epoch2time(leaps[i])) >= 0.0) return tu; + } + return t; } /* utc to gpstime -------------------------------------------------------------- -* convert utc to gpstime considering leap seconds -* args : gtime_t t I time expressed in utc -* return : time expressed in gpstime -* notes : ignore slight time offset under 100 ns -*-----------------------------------------------------------------------------*/ -extern gtime_t utc2gpst(gtime_t t) -{ - int i; - - for (i=0;leaps[i][0]>0;i++) { - if (timediff(t,epoch2time(leaps[i]))>=0.0) return timeadd(t,-leaps[i][6]); - } - return t; + * convert utc to gpstime considering leap seconds + * args : gtime_t t I time expressed in utc + * return : time expressed in gpstime + * notes : ignore slight time offset under 100 ns + *-----------------------------------------------------------------------------*/ +extern gtime_t utc2gpst(gtime_t t) { + int i; + + for (i = 0; leaps[i][0] > 0; i++) { + if (timediff(t, epoch2time(leaps[i])) >= 0.0) return timeadd(t, -leaps[i][6]); + } + return t; } /* gpstime to bdt -------------------------------------------------------------- -* convert gpstime to bdt (beidou navigation satellite system time) -* args : gtime_t t I time expressed in gpstime -* return : time expressed in bdt -* notes : ref [8] 3.3, 2006/1/1 00:00 BDT = 2006/1/1 00:00 UTC -* no leap seconds in BDT -* ignore slight time offset under 100 ns -*-----------------------------------------------------------------------------*/ -extern gtime_t gpst2bdt(gtime_t t) -{ - return timeadd(t,-14.0); -} + * convert gpstime to bdt (beidou navigation satellite system time) + * args : gtime_t t I time expressed in gpstime + * return : time expressed in bdt + * notes : ref [8] 3.3, 2006/1/1 00:00 BDT = 2006/1/1 00:00 UTC + * no leap seconds in BDT + * ignore slight time offset under 100 ns + *-----------------------------------------------------------------------------*/ +extern gtime_t gpst2bdt(gtime_t t) { return timeadd(t, -14.0); } /* bdt to gpstime -------------------------------------------------------------- -* convert bdt (beidou navigation satellite system time) to gpstime -* args : gtime_t t I time expressed in bdt -* return : time expressed in gpstime -* notes : see gpst2bdt() -*-----------------------------------------------------------------------------*/ -extern gtime_t bdt2gpst(gtime_t t) -{ - return timeadd(t,14.0); -} + * convert bdt (beidou navigation satellite system time) to gpstime + * args : gtime_t t I time expressed in bdt + * return : time expressed in gpstime + * notes : see gpst2bdt() + *-----------------------------------------------------------------------------*/ +extern gtime_t bdt2gpst(gtime_t t) { return timeadd(t, 14.0); } /* time to day and sec -------------------------------------------------------*/ -static double time2sec(gtime_t time, gtime_t *day) -{ - double ep[6],sec; - time2epoch(time,ep); - sec=ep[3]*3600.0+ep[4]*60.0+ep[5]; - ep[3]=ep[4]=ep[5]=0.0; - *day=epoch2time(ep); - return sec; +static double time2sec(gtime_t time, gtime_t *day) { + double ep[6], sec; + time2epoch(time, ep); + sec = ep[3] * 3600.0 + ep[4] * 60.0 + ep[5]; + ep[3] = ep[4] = ep[5] = 0.0; + *day = epoch2time(ep); + return sec; } /* utc to gmst ----------------------------------------------------------------- -* convert utc to gmst (Greenwich mean sidereal time) -* args : gtime_t t I time expressed in utc -* double ut1_utc I UT1-UTC (s) -* return : gmst (rad) -*-----------------------------------------------------------------------------*/ -extern double utc2gmst(gtime_t t, double ut1_utc) -{ - const double ep2000[]={2000,1,1,12,0,0}; - gtime_t tut,tut0; - double ut,t1,t2,t3,gmst0,gmst; - - tut=timeadd(t,ut1_utc); - ut=time2sec(tut,&tut0); - t1=timediff(tut0,epoch2time(ep2000))/86400.0/36525.0; - t2=t1*t1; t3=t2*t1; - gmst0=24110.54841+8640184.812866*t1+0.093104*t2-6.2E-6*t3; - gmst=gmst0+1.002737909350795*ut; - - return fmod(gmst,86400.0)*PI/43200.0; /* 0 <= gmst <= 2*PI */ + * convert utc to gmst (Greenwich mean sidereal time) + * args : gtime_t t I time expressed in utc + * double ut1_utc I UT1-UTC (s) + * return : gmst (rad) + *-----------------------------------------------------------------------------*/ +extern double utc2gmst(gtime_t t, double ut1_utc) { + const double ep2000[] = {2000, 1, 1, 12, 0, 0}; + gtime_t tut, tut0; + double ut, t1, t2, t3, gmst0, gmst; + + tut = timeadd(t, ut1_utc); + ut = time2sec(tut, &tut0); + t1 = timediff(tut0, epoch2time(ep2000)) / 86400.0 / 36525.0; + t2 = t1 * t1; + t3 = t2 * t1; + gmst0 = 24110.54841 + 8640184.812866 * t1 + 0.093104 * t2 - 6.2E-6 * t3; + gmst = gmst0 + 1.002737909350795 * ut; + + return fmod(gmst, 86400.0) * PI / 43200.0; /* 0 <= gmst <= 2*PI */ } /* time to string -------------------------------------------------------------- -* convert gtime_t struct to string -* args : gtime_t t I gtime_t struct -* char [40] O string ("yyyy/mm/dd hh:mm:ss.ssss") -* int n I number of decimals -* return : time string -*-----------------------------------------------------------------------------*/ -extern char *time2str(gtime_t t, char s[40], int n) -{ - double ep[6]; - - if (n<0) n=0; else if (n>12) n=12; - if (1.0-t.sec<0.5/pow(10.0,n)) {t.time++; t.sec=0.0;}; - time2epoch(t,ep); - snprintf(s,40,"%04.0f/%02.0f/%02.0f %02.0f:%02.0f:%0*.*f",ep[0],ep[1],ep[2], - ep[3],ep[4],n<=0?2:n+3,n<=0?0:n,ep[5]); - return s; + * convert gtime_t struct to string + * args : gtime_t t I gtime_t struct + * char [40] O string ("yyyy/mm/dd hh:mm:ss.ssss") + * int n I number of decimals + * return : time string + *-----------------------------------------------------------------------------*/ +extern char *time2str(gtime_t t, char s[40], int n) { + double ep[6]; + + if (n < 0) + n = 0; + else if (n > 12) + n = 12; + if (1.0 - t.sec < 0.5 / pow(10.0, n)) { + t.time++; + t.sec = 0.0; + }; + time2epoch(t, ep); + snprintf(s, 40, "%04.0f/%02.0f/%02.0f %02.0f:%02.0f:%0*.*f", ep[0], ep[1], ep[2], ep[3], ep[4], + n <= 0 ? 2 : n + 3, n <= 0 ? 0 : n, ep[5]); + return s; } /* time to day of year --------------------------------------------------------- -* convert time to day of year -* args : gtime_t t I gtime_t struct -* return : day of year (days) -*-----------------------------------------------------------------------------*/ -extern double time2doy(gtime_t t) -{ - double ep[6]; - - time2epoch(t,ep); - ep[1]=ep[2]=1.0; ep[3]=ep[4]=ep[5]=0.0; - return timediff(t,epoch2time(ep))/86400.0+1.0; + * convert time to day of year + * args : gtime_t t I gtime_t struct + * return : day of year (days) + *-----------------------------------------------------------------------------*/ +extern double time2doy(gtime_t t) { + double ep[6]; + + time2epoch(t, ep); + ep[1] = ep[2] = 1.0; + ep[3] = ep[4] = ep[5] = 0.0; + return timediff(t, epoch2time(ep)) / 86400.0 + 1.0; } /* adjust gps week number ------------------------------------------------------ -* adjust gps week number using cpu time -* args : int week I not-adjusted gps week number (0-1023) -* return : adjusted gps week number -*-----------------------------------------------------------------------------*/ -extern int adjgpsweek(int week) -{ - int w; - (void)time2gpst(utc2gpst(timeget()),&w); - if (w<1560) w=1560; /* use 2009/12/1 if time is earlier than 2009/12/1 */ - return week+(w-week+1)/1024*1024; + * adjust gps week number using cpu time + * args : int week I not-adjusted gps week number (0-1023) + * return : adjusted gps week number + *-----------------------------------------------------------------------------*/ +extern int adjgpsweek(int week) { + int w; + (void)time2gpst(utc2gpst(timeget()), &w); + if (w < 1560) w = 1560; /* use 2009/12/1 if time is earlier than 2009/12/1 */ + return week + (w - week + 1) / 1024 * 1024; } /* get tick time --------------------------------------------------------------- -* get current tick in ms -* args : none -* return : current tick in ms -*-----------------------------------------------------------------------------*/ -extern uint32_t tickget(void) -{ + * get current tick in ms + * args : none + * return : current tick in ms + *-----------------------------------------------------------------------------*/ +extern uint32_t tickget(void) { #ifdef WIN32 - return (uint32_t)timeGetTime(); + return (uint32_t)timeGetTime(); #else - struct timespec tp={0}; - struct timeval tv={0}; + struct timespec tp = {0}; + struct timeval tv = {0}; #ifdef CLOCK_MONOTONIC_RAW - /* linux kernel > 2.6.28 */ - if (!clock_gettime(CLOCK_MONOTONIC_RAW,&tp)) { - return tp.tv_sec*1000u+tp.tv_nsec/1000000u; - } - else { - gettimeofday(&tv,NULL); - return tv.tv_sec*1000u+tv.tv_usec/1000u; - } + /* linux kernel > 2.6.28 */ + if (!clock_gettime(CLOCK_MONOTONIC_RAW, &tp)) { + return tp.tv_sec * 1000u + tp.tv_nsec / 1000000u; + } else { + gettimeofday(&tv, NULL); + return tv.tv_sec * 1000u + tv.tv_usec / 1000u; + } #else - gettimeofday(&tv,NULL); - return tv.tv_sec*1000u+tv.tv_usec/1000u; + gettimeofday(&tv, NULL); + return tv.tv_sec * 1000u + tv.tv_usec / 1000u; #endif #endif /* WIN32 */ } /* sleep ms -------------------------------------------------------------------- -* sleep ms -* args : int ms I milliseconds to sleep (<0:no sleep) -* return : none -*-----------------------------------------------------------------------------*/ -extern void sleepms(int ms) -{ + * sleep ms + * args : int ms I milliseconds to sleep (<0:no sleep) + * return : none + *-----------------------------------------------------------------------------*/ +extern void sleepms(int ms) { #ifdef WIN32 - if (ms<5) Sleep(1); else Sleep(ms); + if (ms < 5) + Sleep(1); + else + Sleep(ms); #else - struct timespec ts; - if (ms<=0) return; - ts.tv_sec=(time_t)(ms/1000); - ts.tv_nsec=(long)(ms%1000*1000000); - nanosleep(&ts,NULL); + struct timespec ts; + if (ms <= 0) return; + ts.tv_sec = (time_t)(ms / 1000); + ts.tv_nsec = (long)(ms % 1000 * 1000000); + nanosleep(&ts, NULL); #endif } /* convert degree to deg-min-sec ----------------------------------------------- -* convert degree to degree-minute-second -* args : double deg I degree -* double *dms O degree-minute-second {deg,min,sec} -* int ndec I number of decimals of second -* return : none -*-----------------------------------------------------------------------------*/ -extern void deg2dms(double deg, double *dms, int ndec) -{ - double sign=deg<0.0?-1.0:1.0,a=fabs(deg); - double unit=pow(0.1,ndec); - dms[0]=floor(a); a=(a-dms[0])*60.0; - dms[1]=floor(a); a=(a-dms[1])*60.0; - dms[2]=floor(a/unit+0.5)*unit; - if (dms[2]>=60.0) { - dms[2]=0.0; - dms[1]+=1.0; - if (dms[1]>=60.0) { - dms[1]=0.0; - dms[0]+=1.0; - } + * convert degree to degree-minute-second + * args : double deg I degree + * double *dms O degree-minute-second {deg,min,sec} + * int ndec I number of decimals of second + * return : none + *-----------------------------------------------------------------------------*/ +extern void deg2dms(double deg, double *dms, int ndec) { + double sign = deg < 0.0 ? -1.0 : 1.0, a = fabs(deg); + double unit = pow(0.1, ndec); + dms[0] = floor(a); + a = (a - dms[0]) * 60.0; + dms[1] = floor(a); + a = (a - dms[1]) * 60.0; + dms[2] = floor(a / unit + 0.5) * unit; + if (dms[2] >= 60.0) { + dms[2] = 0.0; + dms[1] += 1.0; + if (dms[1] >= 60.0) { + dms[1] = 0.0; + dms[0] += 1.0; } - dms[0]*=sign; + } + dms[0] *= sign; } /* convert deg-min-sec to degree ----------------------------------------------- -* convert degree-minute-second to degree -* args : double *dms I degree-minute-second {deg,min,sec} -* return : degree -*-----------------------------------------------------------------------------*/ -extern double dms2deg(const double *dms) -{ - double sign=dms[0]<0.0?-1.0:1.0; - return sign*(fabs(dms[0])+dms[1]/60.0+dms[2]/3600.0); + * convert degree-minute-second to degree + * args : double *dms I degree-minute-second {deg,min,sec} + * return : degree + *-----------------------------------------------------------------------------*/ +extern double dms2deg(const double *dms) { + double sign = dms[0] < 0.0 ? -1.0 : 1.0; + return sign * (fabs(dms[0]) + dms[1] / 60.0 + dms[2] / 3600.0); } /* transform ecef to geodetic position ----------------------------------------- -* transform ecef position to geodetic position -* args : double *r I ecef position {x,y,z} (m) -* double *pos O geodetic position {lat,lon,h} (rad,m) -* return : none -* notes : WGS84, ellipsoidal height -*-----------------------------------------------------------------------------*/ -extern void ecef2pos(const double *r, double *pos) -{ - double e2=FE_WGS84*(2.0-FE_WGS84),r2=dot2(r,r),z,zk,v=RE_WGS84,sinp; - - for (z=r[2],zk=0.0;fabs(z-zk)>=1E-4;) { - zk=z; - sinp=z/sqrt(r2+z*z); - v=RE_WGS84/sqrt(1.0-e2*sinp*sinp); - z=r[2]+v*e2*sinp; - } - pos[0]=r2>1E-12?atan(z/sqrt(r2)):(r[2]>0.0?PI/2.0:-PI/2.0); - pos[1]=r2>1E-12?atan2(r[1],r[0]):0.0; - pos[2]=sqrt(r2+z*z)-v; + * transform ecef position to geodetic position + * args : double *r I ecef position {x,y,z} (m) + * double *pos O geodetic position {lat,lon,h} (rad,m) + * return : none + * notes : WGS84, ellipsoidal height + *-----------------------------------------------------------------------------*/ +extern void ecef2pos(const double *r, double *pos) { + double e2 = FE_WGS84 * (2.0 - FE_WGS84), r2 = dot2(r, r), z, zk, v = RE_WGS84, sinp; + + for (z = r[2], zk = 0.0; fabs(z - zk) >= 1E-4;) { + zk = z; + sinp = z / sqrt(r2 + z * z); + v = RE_WGS84 / sqrt(1.0 - e2 * sinp * sinp); + z = r[2] + v * e2 * sinp; + } + pos[0] = r2 > 1E-12 ? atan(z / sqrt(r2)) : (r[2] > 0.0 ? PI / 2.0 : -PI / 2.0); + pos[1] = r2 > 1E-12 ? atan2(r[1], r[0]) : 0.0; + pos[2] = sqrt(r2 + z * z) - v; } /* transform geodetic to ecef position ----------------------------------------- -* transform geodetic position to ecef position -* args : double *pos I geodetic position {lat,lon,h} (rad,m) -* double *r O ecef position {x,y,z} (m) -* return : none -* notes : WGS84, ellipsoidal height -*-----------------------------------------------------------------------------*/ -extern void pos2ecef(const double *pos, double *r) -{ - double sinp=sin(pos[0]),cosp=cos(pos[0]),sinl=sin(pos[1]),cosl=cos(pos[1]); - double e2=FE_WGS84*(2.0-FE_WGS84),v=RE_WGS84/sqrt(1.0-e2*sinp*sinp); - - r[0]=(v+pos[2])*cosp*cosl; - r[1]=(v+pos[2])*cosp*sinl; - r[2]=(v*(1.0-e2)+pos[2])*sinp; + * transform geodetic position to ecef position + * args : double *pos I geodetic position {lat,lon,h} (rad,m) + * double *r O ecef position {x,y,z} (m) + * return : none + * notes : WGS84, ellipsoidal height + *-----------------------------------------------------------------------------*/ +extern void pos2ecef(const double *pos, double *r) { + double sinp = sin(pos[0]), cosp = cos(pos[0]), sinl = sin(pos[1]), cosl = cos(pos[1]); + double e2 = FE_WGS84 * (2.0 - FE_WGS84), v = RE_WGS84 / sqrt(1.0 - e2 * sinp * sinp); + + r[0] = (v + pos[2]) * cosp * cosl; + r[1] = (v + pos[2]) * cosp * sinl; + r[2] = (v * (1.0 - e2) + pos[2]) * sinp; } /* ecef to local coordinate transformation matrix ------------------------------ -* compute ecef to local coordinate transformation matrix -* args : double *pos I geodetic position {lat,lon} (rad) -* double *E O ecef to local coord transformation matrix (3x3) -* return : none -* notes : matrix stored by column-major order (fortran convention) -*-----------------------------------------------------------------------------*/ -extern void xyz2enu(const double *pos, double *E) -{ - double sinp=sin(pos[0]),cosp=cos(pos[0]),sinl=sin(pos[1]),cosl=cos(pos[1]); - - E[0]=-sinl; E[3]=cosl; E[6]=0.0; - E[1]=-sinp*cosl; E[4]=-sinp*sinl; E[7]=cosp; - E[2]=cosp*cosl; E[5]=cosp*sinl; E[8]=sinp; + * compute ecef to local coordinate transformation matrix + * args : double *pos I geodetic position {lat,lon} (rad) + * double *E O ecef to local coord transformation matrix (3x3) + * return : none + * notes : matrix stored by column-major order (fortran convention) + *-----------------------------------------------------------------------------*/ +extern void xyz2enu(const double *pos, double *E) { + double sinp = sin(pos[0]), cosp = cos(pos[0]), sinl = sin(pos[1]), cosl = cos(pos[1]); + + E[0] = -sinl; + E[3] = cosl; + E[6] = 0.0; + E[1] = -sinp * cosl; + E[4] = -sinp * sinl; + E[7] = cosp; + E[2] = cosp * cosl; + E[5] = cosp * sinl; + E[8] = sinp; } /* transform ecef vector to local tangential coordinate ------------------------- -* transform ecef vector to local tangential coordinate -* args : double *pos I geodetic position {lat,lon} (rad) -* double *r I vector in ecef coordinate {x,y,z} -* double *e O vector in local tangential coordinate {e,n,u} -* return : none -*-----------------------------------------------------------------------------*/ -extern void ecef2enu(const double *pos, const double *r, double *e) -{ - double E[9]; - - xyz2enu(pos,E); - matmul("NN",3,1,3,E,r,e); + * transform ecef vector to local tangential coordinate + * args : double *pos I geodetic position {lat,lon} (rad) + * double *r I vector in ecef coordinate {x,y,z} + * double *e O vector in local tangential coordinate {e,n,u} + * return : none + *-----------------------------------------------------------------------------*/ +extern void ecef2enu(const double *pos, const double *r, double *e) { + double E[9]; + + xyz2enu(pos, E); + matmul("NN", 3, 1, 3, E, r, e); } /* transform local vector to ecef coordinate ----------------------------------- -* transform local tangential coordinate vector to ecef -* args : double *pos I geodetic position {lat,lon} (rad) -* double *e I vector in local tangential coordinate {e,n,u} -* double *r O vector in ecef coordinate {x,y,z} -* return : none -*-----------------------------------------------------------------------------*/ -extern void enu2ecef(const double *pos, const double *e, double *r) -{ - double E[9]; - - xyz2enu(pos,E); - matmul("TN",3,1,3,E,e,r); + * transform local tangential coordinate vector to ecef + * args : double *pos I geodetic position {lat,lon} (rad) + * double *e I vector in local tangential coordinate {e,n,u} + * double *r O vector in ecef coordinate {x,y,z} + * return : none + *-----------------------------------------------------------------------------*/ +extern void enu2ecef(const double *pos, const double *e, double *r) { + double E[9]; + + xyz2enu(pos, E); + matmul("TN", 3, 1, 3, E, e, r); } /* transform covariance to local tangential coordinate -------------------------- -* transform ecef covariance to local tangential coordinate -* args : double *pos I geodetic position {lat,lon} (rad) -* double *P I covariance in ecef coordinate -* double *Q O covariance in local tangential coordinate -* return : none -*-----------------------------------------------------------------------------*/ -extern void covenu(const double *pos, const double *P, double *Q) -{ - double E[9],EP[9]; - - xyz2enu(pos,E); - matmul("NN",3,3,3,E,P,EP); - matmul("NT",3,3,3,EP,E,Q); + * transform ecef covariance to local tangential coordinate + * args : double *pos I geodetic position {lat,lon} (rad) + * double *P I covariance in ecef coordinate + * double *Q O covariance in local tangential coordinate + * return : none + *-----------------------------------------------------------------------------*/ +extern void covenu(const double *pos, const double *P, double *Q) { + double E[9], EP[9]; + + xyz2enu(pos, E); + matmul("NN", 3, 3, 3, E, P, EP); + matmul("NT", 3, 3, 3, EP, E, Q); } /* transform local enu coordinate covariance to xyz-ecef ----------------------- -* transform local enu covariance to xyz-ecef coordinate -* args : double *pos I geodetic position {lat,lon} (rad) -* double *Q I covariance in local enu coordinate -* double *P O covariance in xyz-ecef coordinate -* return : none -*-----------------------------------------------------------------------------*/ -extern void covecef(const double *pos, const double *Q, double *P) -{ - double E[9],EQ[9]; - - xyz2enu(pos,E); - matmul("TN",3,3,3,E,Q,EQ); - matmul("NN",3,3,3,EQ,E,P); + * transform local enu covariance to xyz-ecef coordinate + * args : double *pos I geodetic position {lat,lon} (rad) + * double *Q I covariance in local enu coordinate + * double *P O covariance in xyz-ecef coordinate + * return : none + *-----------------------------------------------------------------------------*/ +extern void covecef(const double *pos, const double *Q, double *P) { + double E[9], EQ[9]; + + xyz2enu(pos, E); + matmul("TN", 3, 3, 3, E, Q, EQ); + matmul("NN", 3, 3, 3, EQ, E, P); } /* coordinate rotation matrix ------------------------------------------------*/ -#define Rx(t,X) do { \ - (X)[0]=1.0; (X)[1]=(X)[2]=(X)[3]=(X)[6]=0.0; \ - (X)[4]=(X)[8]=cos(t); (X)[7]=sin(t); (X)[5]=-(X)[7]; \ -} while (0) - -#define Ry(t,X) do { \ - (X)[4]=1.0; (X)[1]=(X)[3]=(X)[5]=(X)[7]=0.0; \ - (X)[0]=(X)[8]=cos(t); (X)[2]=sin(t); (X)[6]=-(X)[2]; \ -} while (0) - -#define Rz(t,X) do { \ - (X)[8]=1.0; (X)[2]=(X)[5]=(X)[6]=(X)[7]=0.0; \ - (X)[0]=(X)[4]=cos(t); (X)[3]=sin(t); (X)[1]=-(X)[3]; \ -} while (0) +#define Rx(t, X) \ + do { \ + (X)[0] = 1.0; \ + (X)[1] = (X)[2] = (X)[3] = (X)[6] = 0.0; \ + (X)[4] = (X)[8] = cos(t); \ + (X)[7] = sin(t); \ + (X)[5] = -(X)[7]; \ + } while (0) + +#define Ry(t, X) \ + do { \ + (X)[4] = 1.0; \ + (X)[1] = (X)[3] = (X)[5] = (X)[7] = 0.0; \ + (X)[0] = (X)[8] = cos(t); \ + (X)[2] = sin(t); \ + (X)[6] = -(X)[2]; \ + } while (0) + +#define Rz(t, X) \ + do { \ + (X)[8] = 1.0; \ + (X)[2] = (X)[5] = (X)[6] = (X)[7] = 0.0; \ + (X)[0] = (X)[4] = cos(t); \ + (X)[3] = sin(t); \ + (X)[1] = -(X)[3]; \ + } while (0) /* astronomical arguments: f={l,l',F,D,OMG} (rad) ----------------------------*/ -static void ast_args(double t, double *f) -{ - static const double fc[][5]={ /* coefficients for iau 1980 nutation */ - { 134.96340251, 1717915923.2178, 31.8792, 0.051635, -0.00024470}, - { 357.52910918, 129596581.0481, -0.5532, 0.000136, -0.00001149}, - { 93.27209062, 1739527262.8478, -12.7512, -0.001037, 0.00000417}, - { 297.85019547, 1602961601.2090, -6.3706, 0.006593, -0.00003169}, - { 125.04455501, -6962890.2665, 7.4722, 0.007702, -0.00005939} - }; - double tt[4]; - int i,j; - - for (tt[0]=t,i=1;i<4;i++) tt[i]=tt[i-1]*t; - for (i=0;i<5;i++) { - f[i]=fc[i][0]*3600.0; - for (j=0;j<4;j++) f[i]+=fc[i][j+1]*tt[j]; - f[i]=fmod(f[i]*AS2R,2.0*PI); - } +static void ast_args(double t, double *f) { + static const double fc[][5] = {/* coefficients for iau 1980 nutation */ + {134.96340251, 1717915923.2178, 31.8792, 0.051635, -0.00024470}, + {357.52910918, 129596581.0481, -0.5532, 0.000136, -0.00001149}, + {93.27209062, 1739527262.8478, -12.7512, -0.001037, 0.00000417}, + {297.85019547, 1602961601.2090, -6.3706, 0.006593, -0.00003169}, + {125.04455501, -6962890.2665, 7.4722, 0.007702, -0.00005939}}; + double tt[4]; + int i, j; + + for (tt[0] = t, i = 1; i < 4; i++) tt[i] = tt[i - 1] * t; + for (i = 0; i < 5; i++) { + f[i] = fc[i][0] * 3600.0; + for (j = 0; j < 4; j++) f[i] += fc[i][j + 1] * tt[j]; + f[i] = fmod(f[i] * AS2R, 2.0 * PI); + } } /* iau 1980 nutation ---------------------------------------------------------*/ -static void nut_iau1980(double t, const double *f, double *dpsi, double *deps) -{ - static const double nut[106][10]={ - { 0, 0, 0, 0, 1, -6798.4, -171996, -174.2, 92025, 8.9}, - { 0, 0, 2, -2, 2, 182.6, -13187, -1.6, 5736, -3.1}, - { 0, 0, 2, 0, 2, 13.7, -2274, -0.2, 977, -0.5}, - { 0, 0, 0, 0, 2, -3399.2, 2062, 0.2, -895, 0.5}, - { 0, -1, 0, 0, 0, -365.3, -1426, 3.4, 54, -0.1}, - { 1, 0, 0, 0, 0, 27.6, 712, 0.1, -7, 0.0}, - { 0, 1, 2, -2, 2, 121.7, -517, 1.2, 224, -0.6}, - { 0, 0, 2, 0, 1, 13.6, -386, -0.4, 200, 0.0}, - { 1, 0, 2, 0, 2, 9.1, -301, 0.0, 129, -0.1}, - { 0, -1, 2, -2, 2, 365.2, 217, -0.5, -95, 0.3}, - { -1, 0, 0, 2, 0, 31.8, 158, 0.0, -1, 0.0}, - { 0, 0, 2, -2, 1, 177.8, 129, 0.1, -70, 0.0}, - { -1, 0, 2, 0, 2, 27.1, 123, 0.0, -53, 0.0}, - { 1, 0, 0, 0, 1, 27.7, 63, 0.1, -33, 0.0}, - { 0, 0, 0, 2, 0, 14.8, 63, 0.0, -2, 0.0}, - { -1, 0, 2, 2, 2, 9.6, -59, 0.0, 26, 0.0}, - { -1, 0, 0, 0, 1, -27.4, -58, -0.1, 32, 0.0}, - { 1, 0, 2, 0, 1, 9.1, -51, 0.0, 27, 0.0}, - { -2, 0, 0, 2, 0, -205.9, -48, 0.0, 1, 0.0}, - { -2, 0, 2, 0, 1, 1305.5, 46, 0.0, -24, 0.0}, - { 0, 0, 2, 2, 2, 7.1, -38, 0.0, 16, 0.0}, - { 2, 0, 2, 0, 2, 6.9, -31, 0.0, 13, 0.0}, - { 2, 0, 0, 0, 0, 13.8, 29, 0.0, -1, 0.0}, - { 1, 0, 2, -2, 2, 23.9, 29, 0.0, -12, 0.0}, - { 0, 0, 2, 0, 0, 13.6, 26, 0.0, -1, 0.0}, - { 0, 0, 2, -2, 0, 173.3, -22, 0.0, 0, 0.0}, - { -1, 0, 2, 0, 1, 27.0, 21, 0.0, -10, 0.0}, - { 0, 2, 0, 0, 0, 182.6, 17, -0.1, 0, 0.0}, - { 0, 2, 2, -2, 2, 91.3, -16, 0.1, 7, 0.0}, - { -1, 0, 0, 2, 1, 32.0, 16, 0.0, -8, 0.0}, - { 0, 1, 0, 0, 1, 386.0, -15, 0.0, 9, 0.0}, - { 1, 0, 0, -2, 1, -31.7, -13, 0.0, 7, 0.0}, - { 0, -1, 0, 0, 1, -346.6, -12, 0.0, 6, 0.0}, - { 2, 0, -2, 0, 0, -1095.2, 11, 0.0, 0, 0.0}, - { -1, 0, 2, 2, 1, 9.5, -10, 0.0, 5, 0.0}, - { 1, 0, 2, 2, 2, 5.6, -8, 0.0, 3, 0.0}, - { 0, -1, 2, 0, 2, 14.2, -7, 0.0, 3, 0.0}, - { 0, 0, 2, 2, 1, 7.1, -7, 0.0, 3, 0.0}, - { 1, 1, 0, -2, 0, -34.8, -7, 0.0, 0, 0.0}, - { 0, 1, 2, 0, 2, 13.2, 7, 0.0, -3, 0.0}, - { -2, 0, 0, 2, 1, -199.8, -6, 0.0, 3, 0.0}, - { 0, 0, 0, 2, 1, 14.8, -6, 0.0, 3, 0.0}, - { 2, 0, 2, -2, 2, 12.8, 6, 0.0, -3, 0.0}, - { 1, 0, 0, 2, 0, 9.6, 6, 0.0, 0, 0.0}, - { 1, 0, 2, -2, 1, 23.9, 6, 0.0, -3, 0.0}, - { 0, 0, 0, -2, 1, -14.7, -5, 0.0, 3, 0.0}, - { 0, -1, 2, -2, 1, 346.6, -5, 0.0, 3, 0.0}, - { 2, 0, 2, 0, 1, 6.9, -5, 0.0, 3, 0.0}, - { 1, -1, 0, 0, 0, 29.8, 5, 0.0, 0, 0.0}, - { 1, 0, 0, -1, 0, 411.8, -4, 0.0, 0, 0.0}, - { 0, 0, 0, 1, 0, 29.5, -4, 0.0, 0, 0.0}, - { 0, 1, 0, -2, 0, -15.4, -4, 0.0, 0, 0.0}, - { 1, 0, -2, 0, 0, -26.9, 4, 0.0, 0, 0.0}, - { 2, 0, 0, -2, 1, 212.3, 4, 0.0, -2, 0.0}, - { 0, 1, 2, -2, 1, 119.6, 4, 0.0, -2, 0.0}, - { 1, 1, 0, 0, 0, 25.6, -3, 0.0, 0, 0.0}, - { 1, -1, 0, -1, 0, -3232.9, -3, 0.0, 0, 0.0}, - { -1, -1, 2, 2, 2, 9.8, -3, 0.0, 1, 0.0}, - { 0, -1, 2, 2, 2, 7.2, -3, 0.0, 1, 0.0}, - { 1, -1, 2, 0, 2, 9.4, -3, 0.0, 1, 0.0}, - { 3, 0, 2, 0, 2, 5.5, -3, 0.0, 1, 0.0}, - { -2, 0, 2, 0, 2, 1615.7, -3, 0.0, 1, 0.0}, - { 1, 0, 2, 0, 0, 9.1, 3, 0.0, 0, 0.0}, - { -1, 0, 2, 4, 2, 5.8, -2, 0.0, 1, 0.0}, - { 1, 0, 0, 0, 2, 27.8, -2, 0.0, 1, 0.0}, - { -1, 0, 2, -2, 1, -32.6, -2, 0.0, 1, 0.0}, - { 0, -2, 2, -2, 1, 6786.3, -2, 0.0, 1, 0.0}, - { -2, 0, 0, 0, 1, -13.7, -2, 0.0, 1, 0.0}, - { 2, 0, 0, 0, 1, 13.8, 2, 0.0, -1, 0.0}, - { 3, 0, 0, 0, 0, 9.2, 2, 0.0, 0, 0.0}, - { 1, 1, 2, 0, 2, 8.9, 2, 0.0, -1, 0.0}, - { 0, 0, 2, 1, 2, 9.3, 2, 0.0, -1, 0.0}, - { 1, 0, 0, 2, 1, 9.6, -1, 0.0, 0, 0.0}, - { 1, 0, 2, 2, 1, 5.6, -1, 0.0, 1, 0.0}, - { 1, 1, 0, -2, 1, -34.7, -1, 0.0, 0, 0.0}, - { 0, 1, 0, 2, 0, 14.2, -1, 0.0, 0, 0.0}, - { 0, 1, 2, -2, 0, 117.5, -1, 0.0, 0, 0.0}, - { 0, 1, -2, 2, 0, -329.8, -1, 0.0, 0, 0.0}, - { 1, 0, -2, 2, 0, 23.8, -1, 0.0, 0, 0.0}, - { 1, 0, -2, -2, 0, -9.5, -1, 0.0, 0, 0.0}, - { 1, 0, 2, -2, 0, 32.8, -1, 0.0, 0, 0.0}, - { 1, 0, 0, -4, 0, -10.1, -1, 0.0, 0, 0.0}, - { 2, 0, 0, -4, 0, -15.9, -1, 0.0, 0, 0.0}, - { 0, 0, 2, 4, 2, 4.8, -1, 0.0, 0, 0.0}, - { 0, 0, 2, -1, 2, 25.4, -1, 0.0, 0, 0.0}, - { -2, 0, 2, 4, 2, 7.3, -1, 0.0, 1, 0.0}, - { 2, 0, 2, 2, 2, 4.7, -1, 0.0, 0, 0.0}, - { 0, -1, 2, 0, 1, 14.2, -1, 0.0, 0, 0.0}, - { 0, 0, -2, 0, 1, -13.6, -1, 0.0, 0, 0.0}, - { 0, 0, 4, -2, 2, 12.7, 1, 0.0, 0, 0.0}, - { 0, 1, 0, 0, 2, 409.2, 1, 0.0, 0, 0.0}, - { 1, 1, 2, -2, 2, 22.5, 1, 0.0, -1, 0.0}, - { 3, 0, 2, -2, 2, 8.7, 1, 0.0, 0, 0.0}, - { -2, 0, 2, 2, 2, 14.6, 1, 0.0, -1, 0.0}, - { -1, 0, 0, 0, 2, -27.3, 1, 0.0, -1, 0.0}, - { 0, 0, -2, 2, 1, -169.0, 1, 0.0, 0, 0.0}, - { 0, 1, 2, 0, 1, 13.1, 1, 0.0, 0, 0.0}, - { -1, 0, 4, 0, 2, 9.1, 1, 0.0, 0, 0.0}, - { 2, 1, 0, -2, 0, 131.7, 1, 0.0, 0, 0.0}, - { 2, 0, 0, 2, 0, 7.1, 1, 0.0, 0, 0.0}, - { 2, 0, 2, -2, 1, 12.8, 1, 0.0, -1, 0.0}, - { 2, 0, -2, 0, 1, -943.2, 1, 0.0, 0, 0.0}, - { 1, -1, 0, -2, 0, -29.3, 1, 0.0, 0, 0.0}, - { -1, 0, 0, 1, 1, -388.3, 1, 0.0, 0, 0.0}, - { -1, -1, 0, 2, 1, 35.0, 1, 0.0, 0, 0.0}, - { 0, 1, 0, 1, 0, 27.3, 1, 0.0, 0, 0.0} - }; - double ang; - int i,j; - - *dpsi=*deps=0.0; - - for (i=0;i<106;i++) { - ang=0.0; - for (j=0;j<5;j++) ang+=nut[i][j]*f[j]; - *dpsi+=(nut[i][6]+nut[i][7]*t)*sin(ang); - *deps+=(nut[i][8]+nut[i][9]*t)*cos(ang); - } - *dpsi*=1E-4*AS2R; /* 0.1 mas -> rad */ - *deps*=1E-4*AS2R; +static void nut_iau1980(double t, const double *f, double *dpsi, double *deps) { + static const double nut[106][10] = {{0, 0, 0, 0, 1, -6798.4, -171996, -174.2, 92025, 8.9}, + {0, 0, 2, -2, 2, 182.6, -13187, -1.6, 5736, -3.1}, + {0, 0, 2, 0, 2, 13.7, -2274, -0.2, 977, -0.5}, + {0, 0, 0, 0, 2, -3399.2, 2062, 0.2, -895, 0.5}, + {0, -1, 0, 0, 0, -365.3, -1426, 3.4, 54, -0.1}, + {1, 0, 0, 0, 0, 27.6, 712, 0.1, -7, 0.0}, + {0, 1, 2, -2, 2, 121.7, -517, 1.2, 224, -0.6}, + {0, 0, 2, 0, 1, 13.6, -386, -0.4, 200, 0.0}, + {1, 0, 2, 0, 2, 9.1, -301, 0.0, 129, -0.1}, + {0, -1, 2, -2, 2, 365.2, 217, -0.5, -95, 0.3}, + {-1, 0, 0, 2, 0, 31.8, 158, 0.0, -1, 0.0}, + {0, 0, 2, -2, 1, 177.8, 129, 0.1, -70, 0.0}, + {-1, 0, 2, 0, 2, 27.1, 123, 0.0, -53, 0.0}, + {1, 0, 0, 0, 1, 27.7, 63, 0.1, -33, 0.0}, + {0, 0, 0, 2, 0, 14.8, 63, 0.0, -2, 0.0}, + {-1, 0, 2, 2, 2, 9.6, -59, 0.0, 26, 0.0}, + {-1, 0, 0, 0, 1, -27.4, -58, -0.1, 32, 0.0}, + {1, 0, 2, 0, 1, 9.1, -51, 0.0, 27, 0.0}, + {-2, 0, 0, 2, 0, -205.9, -48, 0.0, 1, 0.0}, + {-2, 0, 2, 0, 1, 1305.5, 46, 0.0, -24, 0.0}, + {0, 0, 2, 2, 2, 7.1, -38, 0.0, 16, 0.0}, + {2, 0, 2, 0, 2, 6.9, -31, 0.0, 13, 0.0}, + {2, 0, 0, 0, 0, 13.8, 29, 0.0, -1, 0.0}, + {1, 0, 2, -2, 2, 23.9, 29, 0.0, -12, 0.0}, + {0, 0, 2, 0, 0, 13.6, 26, 0.0, -1, 0.0}, + {0, 0, 2, -2, 0, 173.3, -22, 0.0, 0, 0.0}, + {-1, 0, 2, 0, 1, 27.0, 21, 0.0, -10, 0.0}, + {0, 2, 0, 0, 0, 182.6, 17, -0.1, 0, 0.0}, + {0, 2, 2, -2, 2, 91.3, -16, 0.1, 7, 0.0}, + {-1, 0, 0, 2, 1, 32.0, 16, 0.0, -8, 0.0}, + {0, 1, 0, 0, 1, 386.0, -15, 0.0, 9, 0.0}, + {1, 0, 0, -2, 1, -31.7, -13, 0.0, 7, 0.0}, + {0, -1, 0, 0, 1, -346.6, -12, 0.0, 6, 0.0}, + {2, 0, -2, 0, 0, -1095.2, 11, 0.0, 0, 0.0}, + {-1, 0, 2, 2, 1, 9.5, -10, 0.0, 5, 0.0}, + {1, 0, 2, 2, 2, 5.6, -8, 0.0, 3, 0.0}, + {0, -1, 2, 0, 2, 14.2, -7, 0.0, 3, 0.0}, + {0, 0, 2, 2, 1, 7.1, -7, 0.0, 3, 0.0}, + {1, 1, 0, -2, 0, -34.8, -7, 0.0, 0, 0.0}, + {0, 1, 2, 0, 2, 13.2, 7, 0.0, -3, 0.0}, + {-2, 0, 0, 2, 1, -199.8, -6, 0.0, 3, 0.0}, + {0, 0, 0, 2, 1, 14.8, -6, 0.0, 3, 0.0}, + {2, 0, 2, -2, 2, 12.8, 6, 0.0, -3, 0.0}, + {1, 0, 0, 2, 0, 9.6, 6, 0.0, 0, 0.0}, + {1, 0, 2, -2, 1, 23.9, 6, 0.0, -3, 0.0}, + {0, 0, 0, -2, 1, -14.7, -5, 0.0, 3, 0.0}, + {0, -1, 2, -2, 1, 346.6, -5, 0.0, 3, 0.0}, + {2, 0, 2, 0, 1, 6.9, -5, 0.0, 3, 0.0}, + {1, -1, 0, 0, 0, 29.8, 5, 0.0, 0, 0.0}, + {1, 0, 0, -1, 0, 411.8, -4, 0.0, 0, 0.0}, + {0, 0, 0, 1, 0, 29.5, -4, 0.0, 0, 0.0}, + {0, 1, 0, -2, 0, -15.4, -4, 0.0, 0, 0.0}, + {1, 0, -2, 0, 0, -26.9, 4, 0.0, 0, 0.0}, + {2, 0, 0, -2, 1, 212.3, 4, 0.0, -2, 0.0}, + {0, 1, 2, -2, 1, 119.6, 4, 0.0, -2, 0.0}, + {1, 1, 0, 0, 0, 25.6, -3, 0.0, 0, 0.0}, + {1, -1, 0, -1, 0, -3232.9, -3, 0.0, 0, 0.0}, + {-1, -1, 2, 2, 2, 9.8, -3, 0.0, 1, 0.0}, + {0, -1, 2, 2, 2, 7.2, -3, 0.0, 1, 0.0}, + {1, -1, 2, 0, 2, 9.4, -3, 0.0, 1, 0.0}, + {3, 0, 2, 0, 2, 5.5, -3, 0.0, 1, 0.0}, + {-2, 0, 2, 0, 2, 1615.7, -3, 0.0, 1, 0.0}, + {1, 0, 2, 0, 0, 9.1, 3, 0.0, 0, 0.0}, + {-1, 0, 2, 4, 2, 5.8, -2, 0.0, 1, 0.0}, + {1, 0, 0, 0, 2, 27.8, -2, 0.0, 1, 0.0}, + {-1, 0, 2, -2, 1, -32.6, -2, 0.0, 1, 0.0}, + {0, -2, 2, -2, 1, 6786.3, -2, 0.0, 1, 0.0}, + {-2, 0, 0, 0, 1, -13.7, -2, 0.0, 1, 0.0}, + {2, 0, 0, 0, 1, 13.8, 2, 0.0, -1, 0.0}, + {3, 0, 0, 0, 0, 9.2, 2, 0.0, 0, 0.0}, + {1, 1, 2, 0, 2, 8.9, 2, 0.0, -1, 0.0}, + {0, 0, 2, 1, 2, 9.3, 2, 0.0, -1, 0.0}, + {1, 0, 0, 2, 1, 9.6, -1, 0.0, 0, 0.0}, + {1, 0, 2, 2, 1, 5.6, -1, 0.0, 1, 0.0}, + {1, 1, 0, -2, 1, -34.7, -1, 0.0, 0, 0.0}, + {0, 1, 0, 2, 0, 14.2, -1, 0.0, 0, 0.0}, + {0, 1, 2, -2, 0, 117.5, -1, 0.0, 0, 0.0}, + {0, 1, -2, 2, 0, -329.8, -1, 0.0, 0, 0.0}, + {1, 0, -2, 2, 0, 23.8, -1, 0.0, 0, 0.0}, + {1, 0, -2, -2, 0, -9.5, -1, 0.0, 0, 0.0}, + {1, 0, 2, -2, 0, 32.8, -1, 0.0, 0, 0.0}, + {1, 0, 0, -4, 0, -10.1, -1, 0.0, 0, 0.0}, + {2, 0, 0, -4, 0, -15.9, -1, 0.0, 0, 0.0}, + {0, 0, 2, 4, 2, 4.8, -1, 0.0, 0, 0.0}, + {0, 0, 2, -1, 2, 25.4, -1, 0.0, 0, 0.0}, + {-2, 0, 2, 4, 2, 7.3, -1, 0.0, 1, 0.0}, + {2, 0, 2, 2, 2, 4.7, -1, 0.0, 0, 0.0}, + {0, -1, 2, 0, 1, 14.2, -1, 0.0, 0, 0.0}, + {0, 0, -2, 0, 1, -13.6, -1, 0.0, 0, 0.0}, + {0, 0, 4, -2, 2, 12.7, 1, 0.0, 0, 0.0}, + {0, 1, 0, 0, 2, 409.2, 1, 0.0, 0, 0.0}, + {1, 1, 2, -2, 2, 22.5, 1, 0.0, -1, 0.0}, + {3, 0, 2, -2, 2, 8.7, 1, 0.0, 0, 0.0}, + {-2, 0, 2, 2, 2, 14.6, 1, 0.0, -1, 0.0}, + {-1, 0, 0, 0, 2, -27.3, 1, 0.0, -1, 0.0}, + {0, 0, -2, 2, 1, -169.0, 1, 0.0, 0, 0.0}, + {0, 1, 2, 0, 1, 13.1, 1, 0.0, 0, 0.0}, + {-1, 0, 4, 0, 2, 9.1, 1, 0.0, 0, 0.0}, + {2, 1, 0, -2, 0, 131.7, 1, 0.0, 0, 0.0}, + {2, 0, 0, 2, 0, 7.1, 1, 0.0, 0, 0.0}, + {2, 0, 2, -2, 1, 12.8, 1, 0.0, -1, 0.0}, + {2, 0, -2, 0, 1, -943.2, 1, 0.0, 0, 0.0}, + {1, -1, 0, -2, 0, -29.3, 1, 0.0, 0, 0.0}, + {-1, 0, 0, 1, 1, -388.3, 1, 0.0, 0, 0.0}, + {-1, -1, 0, 2, 1, 35.0, 1, 0.0, 0, 0.0}, + {0, 1, 0, 1, 0, 27.3, 1, 0.0, 0, 0.0}}; + double ang; + int i, j; + + *dpsi = *deps = 0.0; + + for (i = 0; i < 106; i++) { + ang = 0.0; + for (j = 0; j < 5; j++) ang += nut[i][j] * f[j]; + *dpsi += (nut[i][6] + nut[i][7] * t) * sin(ang); + *deps += (nut[i][8] + nut[i][9] * t) * cos(ang); + } + *dpsi *= 1E-4 * AS2R; /* 0.1 mas -> rad */ + *deps *= 1E-4 * AS2R; } /* eci to ecef transformation matrix ------------------------------------------- -* compute eci to ecef transformation matrix -* args : gtime_t tutc I time in utc -* double *erpv I erp values {xp,yp,ut1_utc,lod} (rad,rad,s,s/d) -* double *U O eci to ecef transformation matrix (3 x 3) -* double *gmst IO greenwich mean sidereal time (rad) -* (NULL: no output) -* return : none -* note : see ref [3] chap 5 -* not thread-safe -*-----------------------------------------------------------------------------*/ -extern void eci2ecef(gtime_t tutc, const double *erpv, double *U, double *gmst) -{ - const double ep2000[]={2000,1,1,12,0,0}; - static THREADLOCAL gtime_t tutc_ = {0, 0}; - static THREADLOCAL double U_[9], gmst_; - gtime_t tgps; - double eps,ze,th,z,t,t2,t3,dpsi,deps,gast,f[5]; - double R1[9],R2[9],R3[9],R[9],W[9],N[9],P[9],NP[9]; - int i; - - char tstr[40]; - trace(4,"eci2ecef: tutc=%s\n",time2str(tutc,tstr,3)); - - if (fabs(timediff(tutc,tutc_))<0.01) { /* read cache */ - for (i=0;i<9;i++) U[i]=U_[i]; - if (gmst) *gmst=gmst_; - return; - } - tutc_=tutc; - - /* terrestrial time */ - tgps=utc2gpst(tutc_); - t=(timediff(tgps,epoch2time(ep2000))+19.0+32.184)/86400.0/36525.0; - t2=t*t; t3=t2*t; - - /* astronomical arguments */ - ast_args(t,f); - - /* iau 1976 precession */ - ze=(2306.2181*t+0.30188*t2+0.017998*t3)*AS2R; - th=(2004.3109*t-0.42665*t2-0.041833*t3)*AS2R; - z =(2306.2181*t+1.09468*t2+0.018203*t3)*AS2R; - eps=(84381.448-46.8150*t-0.00059*t2+0.001813*t3)*AS2R; - Rz(-z,R1); Ry(th,R2); Rz(-ze,R3); - matmul("NN",3,3,3,R1,R2,R); - matmul("NN",3,3,3,R, R3,P); /* P=Rz(-z)*Ry(th)*Rz(-ze) */ - - /* iau 1980 nutation */ - nut_iau1980(t,f,&dpsi,&deps); - Rx(-eps-deps,R1); Rz(-dpsi,R2); Rx(eps,R3); - matmul("NN",3,3,3,R1,R2,R); - matmul("NN",3,3,3,R ,R3,N); /* N=Rx(-eps)*Rz(-dspi)*Rx(eps) */ - - /* greenwich aparent sidereal time (rad) */ - gmst_=utc2gmst(tutc_,erpv[2]); - gast=gmst_+dpsi*cos(eps); - gast+=(0.00264*sin(f[4])+0.000063*sin(2.0*f[4]))*AS2R; - - /* eci to ecef transformation matrix */ - Ry(-erpv[0],R1); Rx(-erpv[1],R2); Rz(gast,R3); - matmul("NN",3,3,3,R1,R2,W ); - matmul("NN",3,3,3,W ,R3,R ); /* W=Ry(-xp)*Rx(-yp) */ - matmul("NN",3,3,3,N ,P ,NP); - matmul("NN",3,3,3,R ,NP,U_); /* U=W*Rz(gast)*N*P */ - - for (i=0;i<9;i++) U[i]=U_[i]; - if (gmst) *gmst=gmst_; - - trace(5,"gmst=%.12f gast=%.12f\n",gmst_,gast); - trace(5,"P=\n"); tracemat(5,P,3,3,15,12); - trace(5,"N=\n"); tracemat(5,N,3,3,15,12); - trace(5,"W=\n"); tracemat(5,W,3,3,15,12); - trace(5,"U=\n"); tracemat(5,U,3,3,15,12); + * compute eci to ecef transformation matrix + * args : gtime_t tutc I time in utc + * double *erpv I erp values {xp,yp,ut1_utc,lod} (rad,rad,s,s/d) + * double *U O eci to ecef transformation matrix (3 x 3) + * double *gmst IO greenwich mean sidereal time (rad) + * (NULL: no output) + * return : none + * note : see ref [3] chap 5 + * not thread-safe + *-----------------------------------------------------------------------------*/ +extern void eci2ecef(gtime_t tutc, const double *erpv, double *U, double *gmst) { + const double ep2000[] = {2000, 1, 1, 12, 0, 0}; + static THREADLOCAL gtime_t tutc_ = {0, 0}; + static THREADLOCAL double U_[9], gmst_; + gtime_t tgps; + double eps, ze, th, z, t, t2, t3, dpsi, deps, gast, f[5]; + double R1[9], R2[9], R3[9], R[9], W[9], N[9], P[9], NP[9]; + int i; + + char tstr[40]; + trace(4, "eci2ecef: tutc=%s\n", time2str(tutc, tstr, 3)); + + if (fabs(timediff(tutc, tutc_)) < 0.01) { /* read cache */ + for (i = 0; i < 9; i++) U[i] = U_[i]; + if (gmst) *gmst = gmst_; + return; + } + tutc_ = tutc; + + /* terrestrial time */ + tgps = utc2gpst(tutc_); + t = (timediff(tgps, epoch2time(ep2000)) + 19.0 + 32.184) / 86400.0 / 36525.0; + t2 = t * t; + t3 = t2 * t; + + /* astronomical arguments */ + ast_args(t, f); + + /* iau 1976 precession */ + ze = (2306.2181 * t + 0.30188 * t2 + 0.017998 * t3) * AS2R; + th = (2004.3109 * t - 0.42665 * t2 - 0.041833 * t3) * AS2R; + z = (2306.2181 * t + 1.09468 * t2 + 0.018203 * t3) * AS2R; + eps = (84381.448 - 46.8150 * t - 0.00059 * t2 + 0.001813 * t3) * AS2R; + Rz(-z, R1); + Ry(th, R2); + Rz(-ze, R3); + matmul("NN", 3, 3, 3, R1, R2, R); + matmul("NN", 3, 3, 3, R, R3, P); /* P=Rz(-z)*Ry(th)*Rz(-ze) */ + + /* iau 1980 nutation */ + nut_iau1980(t, f, &dpsi, &deps); + Rx(-eps - deps, R1); + Rz(-dpsi, R2); + Rx(eps, R3); + matmul("NN", 3, 3, 3, R1, R2, R); + matmul("NN", 3, 3, 3, R, R3, N); /* N=Rx(-eps)*Rz(-dspi)*Rx(eps) */ + + /* greenwich aparent sidereal time (rad) */ + gmst_ = utc2gmst(tutc_, erpv[2]); + gast = gmst_ + dpsi * cos(eps); + gast += (0.00264 * sin(f[4]) + 0.000063 * sin(2.0 * f[4])) * AS2R; + + /* eci to ecef transformation matrix */ + Ry(-erpv[0], R1); + Rx(-erpv[1], R2); + Rz(gast, R3); + matmul("NN", 3, 3, 3, R1, R2, W); + matmul("NN", 3, 3, 3, W, R3, R); /* W=Ry(-xp)*Rx(-yp) */ + matmul("NN", 3, 3, 3, N, P, NP); + matmul("NN", 3, 3, 3, R, NP, U_); /* U=W*Rz(gast)*N*P */ + + for (i = 0; i < 9; i++) U[i] = U_[i]; + if (gmst) *gmst = gmst_; + + trace(5, "gmst=%.12f gast=%.12f\n", gmst_, gast); + trace(5, "P=\n"); + tracemat(5, P, 3, 3, 15, 12); + trace(5, "N=\n"); + tracemat(5, N, 3, 3, 15, 12); + trace(5, "W=\n"); + tracemat(5, W, 3, 3, 15, 12); + trace(5, "U=\n"); + tracemat(5, U, 3, 3, 15, 12); } /* decode antenna parameter field --------------------------------------------*/ -static int decodef(char *p, int n, double *v) -{ - int i; +static int decodef(char *p, int n, double *v) { + int i; - for (i=0;inmax<=pcvs->n) { - pcvs->nmax+=256; - if (!(pcvs_pcv=(pcv_t *)realloc(pcvs->pcv,sizeof(pcv_t)*pcvs->nmax))) { - trace(1,"addpcv: memory allocation error\n"); - free(pcvs->pcv); pcvs->pcv=NULL; pcvs->n=pcvs->nmax=0; - return; - } - pcvs->pcv=pcvs_pcv; - } - pcvs->pcv[pcvs->n++]=*pcv; +static void addpcv(const pcv_t *pcv, pcvs_t *pcvs) { + pcv_t *pcvs_pcv; + + if (pcvs->nmax <= pcvs->n) { + pcvs->nmax += 256; + if (!(pcvs_pcv = (pcv_t *)realloc(pcvs->pcv, sizeof(pcv_t) * pcvs->nmax))) { + trace(1, "addpcv: memory allocation error\n"); + free(pcvs->pcv); + pcvs->pcv = NULL; + pcvs->n = pcvs->nmax = 0; + return; + } + pcvs->pcv = pcvs_pcv; + } + pcvs->pcv[pcvs->n++] = *pcv; } /* read ngs antenna parameter file -------------------------------------------*/ -static int readngspcv(const char *file, pcvs_t *pcvs) -{ - FILE *fp; - static const pcv_t pcv0={0}; - pcv_t pcv; - double neu[3]; - int n=0; - char buff[256]; - - if (!(fp=fopen(file,"r"))) { - trace(2,"ngs pcv file open error: %s\n",file); - return 0; - } - while (fgets(buff,sizeof(buff),fp)) { - - if (strlen(buff)>=62&&buff[61]=='|') continue; +static int readngspcv(const char *file, pcvs_t *pcvs) { + FILE *fp; + static const pcv_t pcv0 = {0}; + pcv_t pcv; + double neu[3]; + int n = 0; + char buff[256]; - if (buff[0]!=' ') n=0; /* start line */ - if (++n==1) { - pcv=pcv0; - setstr(pcv.type,buff,61); - } - else if (n==2) { - if (decodef(buff,3,neu)<3) continue; - pcv.off[0][0]=neu[1]; - pcv.off[0][1]=neu[0]; - pcv.off[0][2]=neu[2]; - } - else if (n==3) decodef(buff,10,pcv.var[0]); - else if (n==4) decodef(buff,9,pcv.var[0]+10); - else if (n==5) { - if (decodef(buff,3,neu)<3) continue; - pcv.off[1][0]=neu[1]; - pcv.off[1][1]=neu[0]; - pcv.off[1][2]=neu[2]; - } - else if (n==6) decodef(buff,10,pcv.var[1]); - else if (n==7) { - decodef(buff,9,pcv.var[1]+10); - addpcv(&pcv,pcvs); - } + if (!(fp = fopen(file, "r"))) { + trace(2, "ngs pcv file open error: %s\n", file); + return 0; + } + while (fgets(buff, sizeof(buff), fp)) { + if (strlen(buff) >= 62 && buff[61] == '|') continue; + + if (buff[0] != ' ') n = 0; /* start line */ + if (++n == 1) { + pcv = pcv0; + setstr(pcv.type, buff, 61); + } else if (n == 2) { + if (decodef(buff, 3, neu) < 3) continue; + pcv.off[0][0] = neu[1]; + pcv.off[0][1] = neu[0]; + pcv.off[0][2] = neu[2]; + } else if (n == 3) + decodef(buff, 10, pcv.var[0]); + else if (n == 4) + decodef(buff, 9, pcv.var[0] + 10); + else if (n == 5) { + if (decodef(buff, 3, neu) < 3) continue; + pcv.off[1][0] = neu[1]; + pcv.off[1][1] = neu[0]; + pcv.off[1][2] = neu[2]; + } else if (n == 6) + decodef(buff, 10, pcv.var[1]); + else if (n == 7) { + decodef(buff, 9, pcv.var[1] + 10); + addpcv(&pcv, pcvs); } - fclose(fp); + } + fclose(fp); - return 1; + return 1; } /* read antex file ----------------------------------------------------------*/ -static int readantex(const char *file, pcvs_t *pcvs) -{ - FILE *fp; - static const pcv_t pcv0={0}; - pcv_t pcv; - double neu[3]; - int i,f,freq=0,state=0,freqs[]={1,2,5,0}; - char buff[256]; - - trace(3,"readantex: file=%s\n",file); - - if (!(fp=fopen(file,"r"))) { - trace(2,"antex pcv file open error: %s\n",file); - return 0; - } - while (fgets(buff,sizeof(buff),fp)) { +static int readantex(const char *file, pcvs_t *pcvs) { + FILE *fp; + static const pcv_t pcv0 = {0}; + pcv_t pcv; + double neu[3]; + int i, f, freq = 0, state = 0, freqs[] = {1, 2, 5, 0}; + char buff[256]; - if (strlen(buff)<60||strstr(buff+60,"COMMENT")) continue; + trace(3, "readantex: file=%s\n", file); - if (strstr(buff+60,"START OF ANTENNA")) { - pcv=pcv0; - state=1; - } - if (strstr(buff+60,"END OF ANTENNA")) { - addpcv(&pcv,pcvs); - state=0; - } - if (!state) continue; - - if (strstr(buff+60,"TYPE / SERIAL NO")) { - setstr(pcv.type,buff,20); - setstr(pcv.code,buff+20,20); - if (strlen(pcv.code)==3) { - pcv.sat=satid2no(pcv.code); - } - } - else if (strstr(buff+60,"VALID FROM")) { - if (!str2time(buff,0,43,&pcv.ts)) continue; - } - else if (strstr(buff+60,"VALID UNTIL")) { - if (!str2time(buff,0,43,&pcv.te)) continue; - } - else if (strstr(buff+60,"START OF FREQUENCY")) { - if (!pcv.sat&&buff[3]!='G') continue; /* only read rec ant for GPS */ - if (sscanf(buff+4,"%d",&f)<1) continue; - for (i=0;freqs[i];i++) if (freqs[i]==f) break; - if (freqs[i]) freq=i+1; - /* for Galileo E5b: save to E2, not E7 */ - if (satsys(pcv.sat,NULL)==SYS_GAL&&f==7) freq=2; - } - else if (strstr(buff+60,"END OF FREQUENCY")) { - freq=0; - } - else if (strstr(buff+60,"NORTH / EAST / UP")) { - if (freq<1||NFREQn;i++) { - pcv=pcvs->pcv+i; - trace(4,"sat=%2d type=%20s code=%s off=%8.4f %8.4f %8.4f %8.4f %8.4f %8.4f\n", - pcv->sat,pcv->type,pcv->code,pcv->off[0][0],pcv->off[0][1], - pcv->off[0][2],pcv->off[1][0],pcv->off[1][1],pcv->off[1][2]); + if (!state) continue; + + if (strstr(buff + 60, "TYPE / SERIAL NO")) { + setstr(pcv.type, buff, 20); + setstr(pcv.code, buff + 20, 20); + if (strlen(pcv.code) == 3) { + pcv.sat = satid2no(pcv.code); + } + } else if (strstr(buff + 60, "VALID FROM")) { + if (!str2time(buff, 0, 43, &pcv.ts)) continue; + } else if (strstr(buff + 60, "VALID UNTIL")) { + if (!str2time(buff, 0, 43, &pcv.te)) continue; + } else if (strstr(buff + 60, "START OF FREQUENCY")) { + if (!pcv.sat && buff[3] != 'G') continue; /* only read rec ant for GPS */ + if (sscanf(buff + 4, "%d", &f) < 1) continue; + for (i = 0; freqs[i]; i++) + if (freqs[i] == f) break; + if (freqs[i]) freq = i + 1; + /* for Galileo E5b: save to E2, not E7 */ + if (satsys(pcv.sat, NULL) == SYS_GAL && f == 7) freq = 2; + } else if (strstr(buff + 60, "END OF FREQUENCY")) { + freq = 0; + } else if (strstr(buff + 60, "NORTH / EAST / UP")) { + if (freq < 1 || NFREQ < freq) continue; + if (decodef(buff, 3, neu) < 3) continue; + pcv.off[freq - 1][0] = neu[pcv.sat ? 0 : 1]; /* x or e */ + pcv.off[freq - 1][1] = neu[pcv.sat ? 1 : 0]; /* y or n */ + pcv.off[freq - 1][2] = neu[2]; /* z or u */ + } else if (strstr(buff, "NOAZI")) { + if (freq < 1 || NFREQ < freq) continue; + if ((i = decodef(buff + 8, 19, pcv.var[freq - 1])) <= 0) continue; + for (; i < 19; i++) pcv.var[freq - 1][i] = pcv.var[freq - 1][i - 1]; } - return stat; + } + fclose(fp); + + return 1; +} +/* read antenna parameters ------------------------------------------------------ + * read antenna parameters + * args : char *file I antenna parameter file (antex) + * pcvs_t *pcvs IO antenna parameters + * return : status (1:ok,0:file open error) + * notes : file with the extension .atx or .ATX is recognized as antex + * file except for antex is recognized ngs antenna parameters + * see reference [3] + * only support non-azimuth-depedent parameters + *-----------------------------------------------------------------------------*/ +extern int readpcv(const char *file, pcvs_t *pcvs) { + pcv_t *pcv; + char *ext; + int i, stat; + + trace(3, "readpcv: file=%s\n", file); + + if (!(ext = strrchr(file, '.'))) ext = ""; + + if (!strcmp(ext, ".atx") || !strcmp(ext, ".ATX")) { + stat = readantex(file, pcvs); + } else { + stat = readngspcv(file, pcvs); + } + for (i = 0; i < pcvs->n; i++) { + pcv = pcvs->pcv + i; + trace(4, "sat=%2d type=%20s code=%s off=%8.4f %8.4f %8.4f %8.4f %8.4f %8.4f\n", pcv->sat, + pcv->type, pcv->code, pcv->off[0][0], pcv->off[0][1], pcv->off[0][2], pcv->off[1][0], + pcv->off[1][1], pcv->off[1][2]); + } + return stat; } /* search antenna parameter ---------------------------------------------------- -* read satellite antenna phase center position -* args : int sat I satellite number (0: receiver antenna) -* char *type I antenna type for receiver antenna -* gtime_t time I time to search parameters -* pcvs_t *pcvs IO antenna parameters -* return : antenna parameter (NULL: no antenna) -*-----------------------------------------------------------------------------*/ -extern pcv_t *searchpcv(int sat, const char *type, gtime_t time, - const pcvs_t *pcvs) -{ - pcv_t *pcv; - char buff[MAXANT],*types[2],*p; - int i,j,n=0; - - trace(4,"searchpcv: sat=%2d type=%s\n",sat,type); - - if (sat) { /* search satellite antenna */ - for (i=0;in;i++) { - pcv=pcvs->pcv+i; - if (pcv->sat!=sat) continue; - if (pcv->ts.time!=0&&timediff(pcv->ts,time)>0.0) continue; - if (pcv->te.time!=0&&timediff(pcv->te,time)<0.0) continue; - return pcv; - } + * read satellite antenna phase center position + * args : int sat I satellite number (0: receiver antenna) + * char *type I antenna type for receiver antenna + * gtime_t time I time to search parameters + * pcvs_t *pcvs IO antenna parameters + * return : antenna parameter (NULL: no antenna) + *-----------------------------------------------------------------------------*/ +extern pcv_t *searchpcv(int sat, const char *type, gtime_t time, const pcvs_t *pcvs) { + pcv_t *pcv; + char buff[MAXANT], *types[2], *p; + int i, j, n = 0; + + trace(4, "searchpcv: sat=%2d type=%s\n", sat, type); + + if (sat) { /* search satellite antenna */ + for (i = 0; i < pcvs->n; i++) { + pcv = pcvs->pcv + i; + if (pcv->sat != sat) continue; + if (pcv->ts.time != 0 && timediff(pcv->ts, time) > 0.0) continue; + if (pcv->te.time != 0 && timediff(pcv->te, time) < 0.0) continue; + return pcv; + } + } else { + strcpy(buff, type); + char *q; + for (p = strtok_r(buff, " ", &q); p && n < 2; p = strtok_r(NULL, " ", &q)) types[n++] = p; + if (n <= 0) return NULL; + + /* search receiver antenna with radome at first */ + for (i = 0; i < pcvs->n; i++) { + pcv = pcvs->pcv + i; + for (j = 0; j < n; j++) + if (!strstr(pcv->type, types[j])) break; + if (j >= n) return pcv; } - else { - strcpy(buff,type); - char *q; - for (p=strtok_r(buff," ",&q);p&&n<2;p=strtok_r(NULL," ",&q)) types[n++]=p; - if (n<=0) return NULL; - - /* search receiver antenna with radome at first */ - for (i=0;in;i++) { - pcv=pcvs->pcv+i; - for (j=0;jtype,types[j])) break; - if (j>=n) return pcv; - } - /* search receiver antenna without radome */ - for (i=0;in;i++) { - pcv=pcvs->pcv+i; - if (strstr(pcv->type,types[0])!=pcv->type) continue; + /* search receiver antenna without radome */ + for (i = 0; i < pcvs->n; i++) { + pcv = pcvs->pcv + i; + if (strstr(pcv->type, types[0]) != pcv->type) continue; - trace(2,"pcv without radome is used type=%s\n",type); - return pcv; - } + trace(2, "pcv without radome is used type=%s\n", type); + return pcv; } - return NULL; + } + return NULL; } /* read station positions ------------------------------------------------------ -* read positions from station position file -* args : char *file I station position file containing -* lat(deg) lon(deg) height(m) name in a line -* char *rcvs I station name -* double *pos O station position {lat,lon,h} (rad/m) -* (all 0 if search error) -* return : none -*-----------------------------------------------------------------------------*/ -extern void readpos(const char *file, const char *rcv, double *pos) -{ - static double poss[2048][3]; - static char stas[2048][16]; - FILE *fp; - int i,j,len,np=0; - char buff[256],str[256]; - - trace(3,"readpos: file=%s\n",file); - - if (!(fp=fopen(file,"r"))) { - fprintf(stderr,"reference position file open error : %s\n",file); - return; - } - while (np<2048&&fgets(buff,sizeof(buff),fp)) { - if (buff[0]=='%'||buff[0]=='#') continue; - if (sscanf(buff,"%lf %lf %lf %255s",&poss[np][0],&poss[np][1],&poss[np][2], - str)<4) continue; - sprintf(stas[np++],"%.15s",str); - } - fclose(fp); - len=(int)strlen(rcv); - for (i=0;in<=0) return 0; - - mjd=51544.5+(timediff(gpst2utc(time),epoch2time(ep)))/86400.0; - - if (mjd<=erp->data[0].mjd) { - day=mjd-erp->data[0].mjd; - erpv[0]=erp->data[0].xp +erp->data[0].xpr*day; - erpv[1]=erp->data[0].yp +erp->data[0].ypr*day; - erpv[2]=erp->data[0].ut1_utc-erp->data[0].lod*day; - erpv[3]=erp->data[0].lod; - return 1; - } - if (mjd>=erp->data[erp->n-1].mjd) { - day=mjd-erp->data[erp->n-1].mjd; - erpv[0]=erp->data[erp->n-1].xp +erp->data[erp->n-1].xpr*day; - erpv[1]=erp->data[erp->n-1].yp +erp->data[erp->n-1].ypr*day; - erpv[2]=erp->data[erp->n-1].ut1_utc-erp->data[erp->n-1].lod*day; - erpv[3]=erp->data[erp->n-1].lod; - return 1; - } - for (j=0,k=erp->n-1;jdata[i].mjd) k=i; else j=i; - } - if (erp->data[j].mjd==erp->data[j+1].mjd) { - a=0.5; - } - else { - a=(mjd-erp->data[j].mjd)/(erp->data[j+1].mjd-erp->data[j].mjd); - } - erpv[0]=(1.0-a)*erp->data[j].xp +a*erp->data[j+1].xp; - erpv[1]=(1.0-a)*erp->data[j].yp +a*erp->data[j+1].yp; - erpv[2]=(1.0-a)*erp->data[j].ut1_utc+a*erp->data[j+1].ut1_utc; - erpv[3]=(1.0-a)*erp->data[j].lod +a*erp->data[j+1].lod; + * get earth rotation parameter values + * args : erp_t *erp I earth rotation parameters + * gtime_t time I time (gpst) + * double *erpv O erp values {xp,yp,ut1_utc,lod} (rad,rad,s,s/d) + * return : status (1:ok,0:error) + *-----------------------------------------------------------------------------*/ +extern int geterp(const erp_t *erp, gtime_t time, double *erpv) { + const double ep[] = {2000, 1, 1, 12, 0, 0}; + double mjd, day, a; + int i, j, k; + + trace(4, "geterp:\n"); + + if (erp->n <= 0) return 0; + + mjd = 51544.5 + (timediff(gpst2utc(time), epoch2time(ep))) / 86400.0; + + if (mjd <= erp->data[0].mjd) { + day = mjd - erp->data[0].mjd; + erpv[0] = erp->data[0].xp + erp->data[0].xpr * day; + erpv[1] = erp->data[0].yp + erp->data[0].ypr * day; + erpv[2] = erp->data[0].ut1_utc - erp->data[0].lod * day; + erpv[3] = erp->data[0].lod; + return 1; + } + if (mjd >= erp->data[erp->n - 1].mjd) { + day = mjd - erp->data[erp->n - 1].mjd; + erpv[0] = erp->data[erp->n - 1].xp + erp->data[erp->n - 1].xpr * day; + erpv[1] = erp->data[erp->n - 1].yp + erp->data[erp->n - 1].ypr * day; + erpv[2] = erp->data[erp->n - 1].ut1_utc - erp->data[erp->n - 1].lod * day; + erpv[3] = erp->data[erp->n - 1].lod; return 1; + } + for (j = 0, k = erp->n - 1; j < k - 1;) { + i = (j + k) / 2; + if (mjd < erp->data[i].mjd) + k = i; + else + j = i; + } + if (erp->data[j].mjd == erp->data[j + 1].mjd) { + a = 0.5; + } else { + a = (mjd - erp->data[j].mjd) / (erp->data[j + 1].mjd - erp->data[j].mjd); + } + erpv[0] = (1.0 - a) * erp->data[j].xp + a * erp->data[j + 1].xp; + erpv[1] = (1.0 - a) * erp->data[j].yp + a * erp->data[j + 1].yp; + erpv[2] = (1.0 - a) * erp->data[j].ut1_utc + a * erp->data[j + 1].ut1_utc; + erpv[3] = (1.0 - a) * erp->data[j].lod + a * erp->data[j + 1].lod; + return 1; } /* compare ephemeris ---------------------------------------------------------*/ -static int cmpeph(const void *p1, const void *p2) -{ +static int cmpeph(const void *p1, const void *p2) { eph_t *q1 = (eph_t *)p1, *q2 = (eph_t *)p2; if (q1->ttr.time != q2->ttr.time) return (int)(q1->ttr.time - q2->ttr.time); if (q1->toe.time != q2->toe.time) return (int)(q1->toe.time - q2->toe.time); @@ -2945,40 +3098,40 @@ static int cmpeph(const void *p1, const void *p2) return 0; } /* sort and unique ephemeris -------------------------------------------------*/ -static void uniqeph(nav_t *nav) -{ - trace(3,"uniqeph: n=%d\n",nav->n); +static void uniqeph(nav_t *nav) { + trace(3, "uniqeph: n=%d\n", nav->n); - if (nav->n<=0) return; + if (nav->n <= 0) return; - qsort(nav->eph,nav->n,sizeof(eph_t),cmpeph); + qsort(nav->eph, nav->n, sizeof(eph_t), cmpeph); - int j = 0; - for (int i=1;in;i++) { - if (nav->eph[i].sat!=nav->eph[j].sat|| - nav->eph[i].toe.time != nav->eph[j].toe.time || - nav->eph[i].iode!=nav->eph[j].iode) { - nav->eph[++j]=nav->eph[i]; - continue; - } - if (satsys(nav->eph[i].sat, NULL) == SYS_GAL) { - int setj = (nav->eph[j].code & ((1 << 8) | (1 << 1))) ? 1 : 0; - int seti = (nav->eph[i].code & ((1 << 8) | (1 << 1))) ? 1 : 0; - if (seti != setj) nav->eph[++j] = nav->eph[i]; - } + int j = 0; + for (int i = 1; i < nav->n; i++) { + if (nav->eph[i].sat != nav->eph[j].sat || nav->eph[i].toe.time != nav->eph[j].toe.time || + nav->eph[i].iode != nav->eph[j].iode) { + nav->eph[++j] = nav->eph[i]; + continue; } - nav->n=j+1; - - eph_t *nav_eph; - if (!(nav_eph=(eph_t *)realloc(nav->eph,sizeof(eph_t)*nav->n))) { - trace(1,"uniqeph malloc error n=%d\n",nav->n); - free(nav->eph); nav->eph=NULL; nav->n=nav->nmax=0; - return; + if (satsys(nav->eph[i].sat, NULL) == SYS_GAL) { + int setj = (nav->eph[j].code & ((1 << 8) | (1 << 1))) ? 1 : 0; + int seti = (nav->eph[i].code & ((1 << 8) | (1 << 1))) ? 1 : 0; + if (seti != setj) nav->eph[++j] = nav->eph[i]; } - nav->eph=nav_eph; - nav->nmax=nav->n; + } + nav->n = j + 1; + + eph_t *nav_eph; + if (!(nav_eph = (eph_t *)realloc(nav->eph, sizeof(eph_t) * nav->n))) { + trace(1, "uniqeph malloc error n=%d\n", nav->n); + free(nav->eph); + nav->eph = NULL; + nav->n = nav->nmax = 0; + return; + } + nav->eph = nav_eph; + nav->nmax = nav->n; - trace(4,"uniqeph: n=%d\n",nav->n); + trace(4, "uniqeph: n=%d\n", nav->n); } /* compare glonass ephemeris -------------------------------------------------*/ static int cmpgeph(const void *p1, const void *p2) { @@ -2988,35 +3141,35 @@ static int cmpgeph(const void *p1, const void *p2) { return q1->sat - q2->sat; } /* sort and unique glonass ephemeris -----------------------------------------*/ -static void uniqgeph(nav_t *nav) -{ - geph_t *nav_geph; - int i,j; +static void uniqgeph(nav_t *nav) { + geph_t *nav_geph; + int i, j; - trace(3,"uniqgeph: ng=%d\n",nav->ng); + trace(3, "uniqgeph: ng=%d\n", nav->ng); - if (nav->ng<=0) return; + if (nav->ng <= 0) return; - qsort(nav->geph,nav->ng,sizeof(geph_t),cmpgeph); + qsort(nav->geph, nav->ng, sizeof(geph_t), cmpgeph); - for (i=j=0;ing;i++) { - if (nav->geph[i].sat!=nav->geph[j].sat|| - nav->geph[i].toe.time!=nav->geph[j].toe.time|| - nav->geph[i].svh!=nav->geph[j].svh) { - nav->geph[++j]=nav->geph[i]; - } + for (i = j = 0; i < nav->ng; i++) { + if (nav->geph[i].sat != nav->geph[j].sat || nav->geph[i].toe.time != nav->geph[j].toe.time || + nav->geph[i].svh != nav->geph[j].svh) { + nav->geph[++j] = nav->geph[i]; } - nav->ng=j+1; + } + nav->ng = j + 1; - if (!(nav_geph=(geph_t *)realloc(nav->geph,sizeof(geph_t)*nav->ng))) { - trace(1,"uniqgeph malloc error ng=%d\n",nav->ng); - free(nav->geph); nav->geph=NULL; nav->ng=nav->ngmax=0; - return; - } - nav->geph=nav_geph; - nav->ngmax=nav->ng; + if (!(nav_geph = (geph_t *)realloc(nav->geph, sizeof(geph_t) * nav->ng))) { + trace(1, "uniqgeph malloc error ng=%d\n", nav->ng); + free(nav->geph); + nav->geph = NULL; + nav->ng = nav->ngmax = 0; + return; + } + nav->geph = nav_geph; + nav->ngmax = nav->ng; - trace(4,"uniqgeph: ng=%d\n",nav->ng); + trace(4, "uniqgeph: ng=%d\n", nav->ng); } /* compare sbas ephemeris ----------------------------------------------------*/ static int cmpseph(const void *p1, const void *p2) { @@ -3026,908 +3179,933 @@ static int cmpseph(const void *p1, const void *p2) { return q1->sat - q2->sat; } /* sort and unique sbas ephemeris --------------------------------------------*/ -static void uniqseph(nav_t *nav) -{ - seph_t *nav_seph; - int i,j; +static void uniqseph(nav_t *nav) { + seph_t *nav_seph; + int i, j; - trace(3,"uniqseph: ns=%d\n",nav->ns); + trace(3, "uniqseph: ns=%d\n", nav->ns); - if (nav->ns<=0) return; + if (nav->ns <= 0) return; - qsort(nav->seph,nav->ns,sizeof(seph_t),cmpseph); + qsort(nav->seph, nav->ns, sizeof(seph_t), cmpseph); - for (i=j=0;ins;i++) { - if (nav->seph[i].sat!=nav->seph[j].sat|| - nav->seph[i].t0.time!=nav->seph[j].t0.time) { - nav->seph[++j]=nav->seph[i]; - } + for (i = j = 0; i < nav->ns; i++) { + if (nav->seph[i].sat != nav->seph[j].sat || nav->seph[i].t0.time != nav->seph[j].t0.time) { + nav->seph[++j] = nav->seph[i]; } - nav->ns=j+1; + } + nav->ns = j + 1; - if (!(nav_seph=(seph_t *)realloc(nav->seph,sizeof(seph_t)*nav->ns))) { - trace(1,"uniqseph malloc error ns=%d\n",nav->ns); - free(nav->seph); nav->seph=NULL; nav->ns=nav->nsmax=0; - return; - } - nav->seph=nav_seph; - nav->nsmax=nav->ns; + if (!(nav_seph = (seph_t *)realloc(nav->seph, sizeof(seph_t) * nav->ns))) { + trace(1, "uniqseph malloc error ns=%d\n", nav->ns); + free(nav->seph); + nav->seph = NULL; + nav->ns = nav->nsmax = 0; + return; + } + nav->seph = nav_seph; + nav->nsmax = nav->ns; - trace(4,"uniqseph: ns=%d\n",nav->ns); + trace(4, "uniqseph: ns=%d\n", nav->ns); } /* unique ephemerides ---------------------------------------------------------- -* unique ephemerides in navigation data and update carrier wave length -* args : nav_t *nav IO navigation data -* return : number of epochs -*-----------------------------------------------------------------------------*/ -extern void uniqnav(nav_t *nav) -{ - trace(3,"uniqnav: neph=%d ngeph=%d nseph=%d\n",nav->n,nav->ng,nav->ns); - - /* unique ephemeris */ - uniqeph (nav); - uniqgeph(nav); - uniqseph(nav); + * unique ephemerides in navigation data and update carrier wave length + * args : nav_t *nav IO navigation data + * return : number of epochs + *-----------------------------------------------------------------------------*/ +extern void uniqnav(nav_t *nav) { + trace(3, "uniqnav: neph=%d ngeph=%d nseph=%d\n", nav->n, nav->ng, nav->ns); + + /* unique ephemeris */ + uniqeph(nav); + uniqgeph(nav); + uniqseph(nav); } /* compare observation data -------------------------------------------------*/ -static int cmpobs(const void *p1, const void *p2) -{ - obsd_t *q1=(obsd_t *)p1,*q2=(obsd_t *)p2; - double tt=timediff(q1->time,q2->time); - if (fabs(tt)>DTTOL) return tt<0?-1:1; - if (q1->rcv!=q2->rcv) return (int)q1->rcv-(int)q2->rcv; - return (int)q1->sat-(int)q2->sat; +static int cmpobs(const void *p1, const void *p2) { + obsd_t *q1 = (obsd_t *)p1, *q2 = (obsd_t *)p2; + double tt = timediff(q1->time, q2->time); + if (fabs(tt) > DTTOL) return tt < 0 ? -1 : 1; + if (q1->rcv != q2->rcv) return (int)q1->rcv - (int)q2->rcv; + return (int)q1->sat - (int)q2->sat; } /* sort and unique observation data -------------------------------------------- -* sort and unique observation data by time, rcv, sat -* args : obs_t *obs IO observation data -* return : number of epochs -*-----------------------------------------------------------------------------*/ -extern int sortobs(obs_t *obs) -{ - int i,j,n; - - trace(3,"sortobs: nobs=%d\n",obs->n); - - if (obs->n<=0) return 0; - - qsort(obs->data,obs->n,sizeof(obsd_t),cmpobs); - - /* delete duplicated data */ - for (i=j=0;in;i++) { - if (obs->data[i].sat!=obs->data[j].sat|| - obs->data[i].rcv!=obs->data[j].rcv|| - timediff(obs->data[i].time,obs->data[j].time)!=0.0) { - obs->data[++j]=obs->data[i]; - } + * sort and unique observation data by time, rcv, sat + * args : obs_t *obs IO observation data + * return : number of epochs + *-----------------------------------------------------------------------------*/ +extern int sortobs(obs_t *obs) { + int i, j, n; + + trace(3, "sortobs: nobs=%d\n", obs->n); + + if (obs->n <= 0) return 0; + + qsort(obs->data, obs->n, sizeof(obsd_t), cmpobs); + + /* delete duplicated data */ + for (i = j = 0; i < obs->n; i++) { + if (obs->data[i].sat != obs->data[j].sat || obs->data[i].rcv != obs->data[j].rcv || + timediff(obs->data[i].time, obs->data[j].time) != 0.0) { + obs->data[++j] = obs->data[i]; } - obs->n=j+1; + } + obs->n = j + 1; - for (i=n=0;in;i=j,n++) { - for (j=i+1;jn;j++) { - if (timediff(obs->data[j].time,obs->data[i].time)>DTTOL) break; - } + for (i = n = 0; i < obs->n; i = j, n++) { + for (j = i + 1; j < obs->n; j++) { + if (timediff(obs->data[j].time, obs->data[i].time) > DTTOL) break; } - return n; + } + return n; } /* screen by time -------------------------------------------------------------- -* screening by time start, time end, and time interval -* args : gtime_t time I time -* gtime_t ts I time start (ts.time==0:no screening by ts) -* gtime_t te I time end (te.time==0:no screening by te) -* double tint I time interval (s) (0.0:no screen by tint) -* return : 1:on condition, 0:not on condition -*-----------------------------------------------------------------------------*/ -extern int screent(gtime_t time, gtime_t ts, gtime_t te, double tint) -{ - return (tint<=0.0||fmod(time2gpst(time,NULL)+DTTOL,tint)<=DTTOL*2.0)&& - (ts.time==0||timediff(time,ts)>=-DTTOL)&& - (te.time==0||timediff(time,te)< DTTOL); + * screening by time start, time end, and time interval + * args : gtime_t time I time + * gtime_t ts I time start (ts.time==0:no screening by ts) + * gtime_t te I time end (te.time==0:no screening by te) + * double tint I time interval (s) (0.0:no screen by tint) + * return : 1:on condition, 0:not on condition + *-----------------------------------------------------------------------------*/ +extern int screent(gtime_t time, gtime_t ts, gtime_t te, double tint) { + return (tint <= 0.0 || fmod(time2gpst(time, NULL) + DTTOL, tint) <= DTTOL * 2.0) && + (ts.time == 0 || timediff(time, ts) >= -DTTOL) && + (te.time == 0 || timediff(time, te) < DTTOL); } /* read/save navigation data --------------------------------------------------- -* save or load navigation data -* args : char file I file path -* nav_t nav O/I navigation data -* return : status (1:ok,0:no file) -*-----------------------------------------------------------------------------*/ -extern int readnav(const char *file, nav_t *nav) -{ - FILE *fp; - eph_t eph0={0}; - geph_t geph0={0}; - char buff[4096],*p; - long toe_time,tof_time,toc_time,ttr_time; - int i,sat,prn; - - trace(3,"loadnav: file=%s\n",file); - - if (!(fp=fopen(file,"r"))) return 0; - - while (fgets(buff,sizeof(buff),fp)) { - if (!strncmp(buff,"IONUTC",6)) { - for (i=0;i<8;i++) nav->ion_gps[i]=0.0; - for (i=0;i<8;i++) nav->utc_gps[i]=0.0; - (void)sscanf(buff,"IONUTC,%lf,%lf,%lf,%lf,%lf,%lf,%lf,%lf,%lf,%lf,%lf,%lf,%lf", - &nav->ion_gps[0],&nav->ion_gps[1],&nav->ion_gps[2],&nav->ion_gps[3], - &nav->ion_gps[4],&nav->ion_gps[5],&nav->ion_gps[6],&nav->ion_gps[7], - &nav->utc_gps[0],&nav->utc_gps[1],&nav->utc_gps[2],&nav->utc_gps[3], + * save or load navigation data + * args : char file I file path + * nav_t nav O/I navigation data + * return : status (1:ok,0:no file) + *-----------------------------------------------------------------------------*/ +extern int readnav(const char *file, nav_t *nav) { + FILE *fp; + eph_t eph0 = {0}; + geph_t geph0 = {0}; + char buff[4096], *p; + long toe_time, tof_time, toc_time, ttr_time; + int i, sat, prn; + + trace(3, "loadnav: file=%s\n", file); + + if (!(fp = fopen(file, "r"))) return 0; + + while (fgets(buff, sizeof(buff), fp)) { + if (!strncmp(buff, "IONUTC", 6)) { + for (i = 0; i < 8; i++) nav->ion_gps[i] = 0.0; + for (i = 0; i < 8; i++) nav->utc_gps[i] = 0.0; + (void)sscanf(buff, "IONUTC,%lf,%lf,%lf,%lf,%lf,%lf,%lf,%lf,%lf,%lf,%lf,%lf,%lf", + &nav->ion_gps[0], &nav->ion_gps[1], &nav->ion_gps[2], &nav->ion_gps[3], + &nav->ion_gps[4], &nav->ion_gps[5], &nav->ion_gps[6], &nav->ion_gps[7], + &nav->utc_gps[0], &nav->utc_gps[1], &nav->utc_gps[2], &nav->utc_gps[3], &nav->utc_gps[4]); - continue; - } - if ((p=strchr(buff,','))) *p='\0'; else continue; - if (!(sat=satid2no(buff))) continue; - if (satsys(sat,&prn)==SYS_GLO) { - nav->geph[prn-1]=geph0; - nav->geph[prn-1].sat=sat; - toe_time=tof_time=0; - (void)sscanf(p+1,"%d,%d,%d,%d,%d,%d,%ld,%ld,%lf,%lf,%lf,%lf,%lf,%lf,%lf,%lf," - "%lf,%lf,%lf,%lf", - &nav->geph[prn-1].iode,&nav->geph[prn-1].frq,&nav->geph[prn-1].svh, - &nav->geph[prn-1].flags,&nav->geph[prn-1].sva,&nav->geph[prn-1].age, - &toe_time,&tof_time, - &nav->geph[prn-1].pos[0],&nav->geph[prn-1].pos[1],&nav->geph[prn-1].pos[2], - &nav->geph[prn-1].vel[0],&nav->geph[prn-1].vel[1],&nav->geph[prn-1].vel[2], - &nav->geph[prn-1].acc[0],&nav->geph[prn-1].acc[1],&nav->geph[prn-1].acc[2], - &nav->geph[prn-1].taun ,&nav->geph[prn-1].gamn ,&nav->geph[prn-1].dtaun); - nav->geph[prn-1].toe.time=toe_time; - nav->geph[prn-1].tof.time=tof_time; - } - else { - nav->eph[sat-1]=eph0; - nav->eph[sat-1].sat=sat; - toe_time=toc_time=ttr_time=0; - (void)sscanf(p+1,"%d,%d,%d,%d,%ld,%ld,%ld,%lf,%lf,%lf,%lf,%lf,%lf,%lf,%lf," - "%lf,%lf,%lf,%lf,%lf,%lf,%lf,%lf,%lf,%lf,%lf,%lf,%lf,%d,%d", - &nav->eph[sat-1].iode,&nav->eph[sat-1].iodc,&nav->eph[sat-1].sva , - &nav->eph[sat-1].svh , - &toe_time,&toc_time,&ttr_time, - &nav->eph[sat-1].A ,&nav->eph[sat-1].e ,&nav->eph[sat-1].i0 , - &nav->eph[sat-1].OMG0,&nav->eph[sat-1].omg ,&nav->eph[sat-1].M0 , - &nav->eph[sat-1].deln,&nav->eph[sat-1].OMGd,&nav->eph[sat-1].idot, - &nav->eph[sat-1].crc ,&nav->eph[sat-1].crs ,&nav->eph[sat-1].cuc , - &nav->eph[sat-1].cus ,&nav->eph[sat-1].cic ,&nav->eph[sat-1].cis , - &nav->eph[sat-1].toes,&nav->eph[sat-1].fit ,&nav->eph[sat-1].f0 , - &nav->eph[sat-1].f1 ,&nav->eph[sat-1].f2 ,&nav->eph[sat-1].tgd[0], - &nav->eph[sat-1].code, &nav->eph[sat-1].flag); - nav->eph[sat-1].toe.time=toe_time; - nav->eph[sat-1].toc.time=toc_time; - nav->eph[sat-1].ttr.time=ttr_time; - } - } - fclose(fp); - return 1; -} -extern int savenav(const char *file, const nav_t *nav) -{ - FILE *fp; - int i; - char id[8]; - - trace(3,"savenav: file=%s\n",file); - - if (!(fp=fopen(file,"w"))) return 0; - - for (i=0;ieph[i].ttr.time==0) continue; - satno2id(nav->eph[i].sat,id); - fprintf(fp,"%s,%d,%d,%d,%d,%d,%d,%d,%.14E,%.14E,%.14E,%.14E,%.14E,%.14E," - "%.14E,%.14E,%.14E,%.14E,%.14E,%.14E,%.14E,%.14E,%.14E,%.14E," - "%.14E,%.14E,%.14E,%.14E,%.14E,%d,%d\n", - id,nav->eph[i].iode,nav->eph[i].iodc,nav->eph[i].sva , - nav->eph[i].svh ,(int)nav->eph[i].toe.time, - (int)nav->eph[i].toc.time,(int)nav->eph[i].ttr.time, - nav->eph[i].A ,nav->eph[i].e ,nav->eph[i].i0 ,nav->eph[i].OMG0, - nav->eph[i].omg ,nav->eph[i].M0 ,nav->eph[i].deln,nav->eph[i].OMGd, - nav->eph[i].idot,nav->eph[i].crc,nav->eph[i].crs ,nav->eph[i].cuc , - nav->eph[i].cus ,nav->eph[i].cic,nav->eph[i].cis ,nav->eph[i].toes, - nav->eph[i].fit ,nav->eph[i].f0 ,nav->eph[i].f1 ,nav->eph[i].f2 , - nav->eph[i].tgd[0],nav->eph[i].code,nav->eph[i].flag); + continue; } - for (i=0;igeph[i].tof.time==0) continue; - satno2id(nav->geph[i].sat,id); - fprintf(fp,"%s,%d,%d,%d,%d,%d,%d,%d,%d,%.14E,%.14E,%.14E,%.14E,%.14E,%.14E," - "%.14E,%.14E,%.14E,%.14E,%.14E,%.14E\n", - id,nav->geph[i].iode,nav->geph[i].frq,nav->geph[i].svh, - nav->geph[i].flags, - nav->geph[i].sva,nav->geph[i].age,(int)nav->geph[i].toe.time, - (int)nav->geph[i].tof.time, - nav->geph[i].pos[0],nav->geph[i].pos[1],nav->geph[i].pos[2], - nav->geph[i].vel[0],nav->geph[i].vel[1],nav->geph[i].vel[2], - nav->geph[i].acc[0],nav->geph[i].acc[1],nav->geph[i].acc[2], - nav->geph[i].taun,nav->geph[i].gamn,nav->geph[i].dtaun); + if ((p = strchr(buff, ','))) + *p = '\0'; + else + continue; + if (!(sat = satid2no(buff))) continue; + if (satsys(sat, &prn) == SYS_GLO) { + nav->geph[prn - 1] = geph0; + nav->geph[prn - 1].sat = sat; + toe_time = tof_time = 0; + (void)sscanf(p + 1, + "%d,%d,%d,%d,%d,%d,%ld,%ld,%lf,%lf,%lf,%lf,%lf,%lf,%lf,%lf," + "%lf,%lf,%lf,%lf", + &nav->geph[prn - 1].iode, &nav->geph[prn - 1].frq, &nav->geph[prn - 1].svh, + &nav->geph[prn - 1].flags, &nav->geph[prn - 1].sva, &nav->geph[prn - 1].age, + &toe_time, &tof_time, &nav->geph[prn - 1].pos[0], &nav->geph[prn - 1].pos[1], + &nav->geph[prn - 1].pos[2], &nav->geph[prn - 1].vel[0], + &nav->geph[prn - 1].vel[1], &nav->geph[prn - 1].vel[2], + &nav->geph[prn - 1].acc[0], &nav->geph[prn - 1].acc[1], + &nav->geph[prn - 1].acc[2], &nav->geph[prn - 1].taun, &nav->geph[prn - 1].gamn, + &nav->geph[prn - 1].dtaun); + nav->geph[prn - 1].toe.time = toe_time; + nav->geph[prn - 1].tof.time = tof_time; + } else { + nav->eph[sat - 1] = eph0; + nav->eph[sat - 1].sat = sat; + toe_time = toc_time = ttr_time = 0; + (void)sscanf(p + 1, + "%d,%d,%d,%d,%ld,%ld,%ld,%lf,%lf,%lf,%lf,%lf,%lf,%lf,%lf," + "%lf,%lf,%lf,%lf,%lf,%lf,%lf,%lf,%lf,%lf,%lf,%lf,%lf,%d,%d", + &nav->eph[sat - 1].iode, &nav->eph[sat - 1].iodc, &nav->eph[sat - 1].sva, + &nav->eph[sat - 1].svh, &toe_time, &toc_time, &ttr_time, &nav->eph[sat - 1].A, + &nav->eph[sat - 1].e, &nav->eph[sat - 1].i0, &nav->eph[sat - 1].OMG0, + &nav->eph[sat - 1].omg, &nav->eph[sat - 1].M0, &nav->eph[sat - 1].deln, + &nav->eph[sat - 1].OMGd, &nav->eph[sat - 1].idot, &nav->eph[sat - 1].crc, + &nav->eph[sat - 1].crs, &nav->eph[sat - 1].cuc, &nav->eph[sat - 1].cus, + &nav->eph[sat - 1].cic, &nav->eph[sat - 1].cis, &nav->eph[sat - 1].toes, + &nav->eph[sat - 1].fit, &nav->eph[sat - 1].f0, &nav->eph[sat - 1].f1, + &nav->eph[sat - 1].f2, &nav->eph[sat - 1].tgd[0], &nav->eph[sat - 1].code, + &nav->eph[sat - 1].flag); + nav->eph[sat - 1].toe.time = toe_time; + nav->eph[sat - 1].toc.time = toc_time; + nav->eph[sat - 1].ttr.time = ttr_time; } - /*fprintf(fp,"IONUTC,%.14E,%.14E,%.14E,%.14E,%.14E,%.14E,%.14E,%.14E,%.14E," - "%.14E,%.14E,%.14E,%.0f", - nav->ion_gps[0],nav->ion_gps[1],nav->ion_gps[2],nav->ion_gps[3], - nav->ion_gps[4],nav->ion_gps[5],nav->ion_gps[6],nav->ion_gps[7], - nav->utc_gps[0],nav->utc_gps[1],nav->utc_gps[2],nav->utc_gps[3], - nav->utc_gps[4]);*/ + } + fclose(fp); + return 1; +} +extern int savenav(const char *file, const nav_t *nav) { + FILE *fp; + int i; + char id[8]; + + trace(3, "savenav: file=%s\n", file); + + if (!(fp = fopen(file, "w"))) return 0; + + for (i = 0; i < MAXSAT; i++) { + if (nav->eph[i].ttr.time == 0) continue; + satno2id(nav->eph[i].sat, id); + fprintf(fp, + "%s,%d,%d,%d,%d,%d,%d,%d,%.14E,%.14E,%.14E,%.14E,%.14E,%.14E," + "%.14E,%.14E,%.14E,%.14E,%.14E,%.14E,%.14E,%.14E,%.14E,%.14E," + "%.14E,%.14E,%.14E,%.14E,%.14E,%d,%d\n", + id, nav->eph[i].iode, nav->eph[i].iodc, nav->eph[i].sva, nav->eph[i].svh, + (int)nav->eph[i].toe.time, (int)nav->eph[i].toc.time, (int)nav->eph[i].ttr.time, + nav->eph[i].A, nav->eph[i].e, nav->eph[i].i0, nav->eph[i].OMG0, nav->eph[i].omg, + nav->eph[i].M0, nav->eph[i].deln, nav->eph[i].OMGd, nav->eph[i].idot, nav->eph[i].crc, + nav->eph[i].crs, nav->eph[i].cuc, nav->eph[i].cus, nav->eph[i].cic, nav->eph[i].cis, + nav->eph[i].toes, nav->eph[i].fit, nav->eph[i].f0, nav->eph[i].f1, nav->eph[i].f2, + nav->eph[i].tgd[0], nav->eph[i].code, nav->eph[i].flag); + } + for (i = 0; i < MAXPRNGLO; i++) { + if (nav->geph[i].tof.time == 0) continue; + satno2id(nav->geph[i].sat, id); + fprintf(fp, + "%s,%d,%d,%d,%d,%d,%d,%d,%d,%.14E,%.14E,%.14E,%.14E,%.14E,%.14E," + "%.14E,%.14E,%.14E,%.14E,%.14E,%.14E\n", + id, nav->geph[i].iode, nav->geph[i].frq, nav->geph[i].svh, nav->geph[i].flags, + nav->geph[i].sva, nav->geph[i].age, (int)nav->geph[i].toe.time, + (int)nav->geph[i].tof.time, nav->geph[i].pos[0], nav->geph[i].pos[1], + nav->geph[i].pos[2], nav->geph[i].vel[0], nav->geph[i].vel[1], nav->geph[i].vel[2], + nav->geph[i].acc[0], nav->geph[i].acc[1], nav->geph[i].acc[2], nav->geph[i].taun, + nav->geph[i].gamn, nav->geph[i].dtaun); + } + /*fprintf(fp,"IONUTC,%.14E,%.14E,%.14E,%.14E,%.14E,%.14E,%.14E,%.14E,%.14E," + "%.14E,%.14E,%.14E,%.0f", + nav->ion_gps[0],nav->ion_gps[1],nav->ion_gps[2],nav->ion_gps[3], + nav->ion_gps[4],nav->ion_gps[5],nav->ion_gps[6],nav->ion_gps[7], + nav->utc_gps[0],nav->utc_gps[1],nav->utc_gps[2],nav->utc_gps[3], + nav->utc_gps[4]);*/ - fclose(fp); - return 1; + fclose(fp); + return 1; } /* free observation data ------------------------------------------------------- -* free memory for observation data -* args : obs_t *obs IO observation data -* return : none -*-----------------------------------------------------------------------------*/ -extern void freeobs(obs_t *obs) -{ - free(obs->data); obs->data=NULL; obs->n=obs->nmax=0; + * free memory for observation data + * args : obs_t *obs IO observation data + * return : none + *-----------------------------------------------------------------------------*/ +extern void freeobs(obs_t *obs) { + free(obs->data); + obs->data = NULL; + obs->n = obs->nmax = 0; } /* free navigation data --------------------------------------------------------- -* free memory for navigation data -* args : nav_t *nav IO navigation data -* int opt I option (or of followings) -* (0x01: gps/qzs ephemeris, 0x02: glonass ephemeris, -* 0x04: sbas ephemeris, 0x08: precise ephemeris, -* 0x10: precise clock 0x20: almanac, -* 0x40: tec data) -* return : none -*-----------------------------------------------------------------------------*/ -extern void freenav(nav_t *nav, int opt) -{ - if (opt&0x01) {free(nav->eph ); nav->eph =NULL; nav->n =nav->nmax =0;} - if (opt&0x02) {free(nav->geph); nav->geph=NULL; nav->ng=nav->ngmax=0;} - if (opt&0x04) {free(nav->seph); nav->seph=NULL; nav->ns=nav->nsmax=0;} - if (opt&0x08) {free(nav->peph); nav->peph=NULL; nav->ne=nav->nemax=0;} - if (opt&0x10) {free(nav->pclk); nav->pclk=NULL; nav->nc=nav->ncmax=0;} - if (opt&0x20) {free(nav->alm ); nav->alm =NULL; nav->na=nav->namax=0;} - if (opt&0x40) {free(nav->tec ); nav->tec =NULL; nav->nt=nav->ntmax=0;} + * free memory for navigation data + * args : nav_t *nav IO navigation data + * int opt I option (or of followings) + * (0x01: gps/qzs ephemeris, 0x02: glonass ephemeris, + * 0x04: sbas ephemeris, 0x08: precise ephemeris, + * 0x10: precise clock 0x20: almanac, + * 0x40: tec data) + * return : none + *-----------------------------------------------------------------------------*/ +extern void freenav(nav_t *nav, int opt) { + if (opt & 0x01) { + free(nav->eph); + nav->eph = NULL; + nav->n = nav->nmax = 0; + } + if (opt & 0x02) { + free(nav->geph); + nav->geph = NULL; + nav->ng = nav->ngmax = 0; + } + if (opt & 0x04) { + free(nav->seph); + nav->seph = NULL; + nav->ns = nav->nsmax = 0; + } + if (opt & 0x08) { + free(nav->peph); + nav->peph = NULL; + nav->ne = nav->nemax = 0; + } + if (opt & 0x10) { + free(nav->pclk); + nav->pclk = NULL; + nav->nc = nav->ncmax = 0; + } + if (opt & 0x20) { + free(nav->alm); + nav->alm = NULL; + nav->na = nav->namax = 0; + } + if (opt & 0x40) { + free(nav->tec); + nav->tec = NULL; + nav->nt = nav->ntmax = 0; + } } /* execute command ------------------------------------------------------------- -* execute command line by operating system shell -* args : char *cmd I command line -* return : execution status (0:ok,0>:error) -*-----------------------------------------------------------------------------*/ -extern int execcmd(const char *cmd) -{ + * execute command line by operating system shell + * args : char *cmd I command line + * return : execution status (0:ok,0>:error) + *-----------------------------------------------------------------------------*/ +extern int execcmd(const char *cmd) { #ifdef WIN32 - PROCESS_INFORMATION info; - STARTUPINFO si={0}; - DWORD stat; - char cmds[1024]; - - trace(3,"execcmd: cmd=%s\n",cmd); - - si.cb=sizeof(si); - sprintf(cmds,"cmd /c %s",cmd); - if (!CreateProcess(NULL,(LPTSTR)cmds,NULL,NULL,FALSE,CREATE_NO_WINDOW,NULL, - NULL,&si,&info)) return -1; - WaitForSingleObject(info.hProcess,INFINITE); - if (!GetExitCodeProcess(info.hProcess,&stat)) stat=-1; - CloseHandle(info.hProcess); - CloseHandle(info.hThread); - return (int)stat; + PROCESS_INFORMATION info; + STARTUPINFO si = {0}; + DWORD stat; + char cmds[1024]; + + trace(3, "execcmd: cmd=%s\n", cmd); + + si.cb = sizeof(si); + sprintf(cmds, "cmd /c %s", cmd); + if (!CreateProcess(NULL, (LPTSTR)cmds, NULL, NULL, FALSE, CREATE_NO_WINDOW, NULL, NULL, &si, + &info)) + return -1; + WaitForSingleObject(info.hProcess, INFINITE); + if (!GetExitCodeProcess(info.hProcess, &stat)) stat = -1; + CloseHandle(info.hProcess); + CloseHandle(info.hThread); + return (int)stat; #else - trace(3,"execcmd: cmd=%s\n",cmd); + trace(3, "execcmd: cmd=%s\n", cmd); - return system(cmd); + return system(cmd); #endif } /* expand file path ------------------------------------------------------------ -* expand file path with wild-card (*) in file -* args : char *path I file path to expand (captal insensitive) -* char *paths O expanded file paths -* int nmax I max number of expanded file paths -* return : number of expanded file paths -* notes : the order of expanded files is alphabetical order -*-----------------------------------------------------------------------------*/ -extern int expath(const char *path, char *paths[], int nmax) -{ - int i,j,n=0; - char tmp[1024]; + * expand file path with wild-card (*) in file + * args : char *path I file path to expand (captal insensitive) + * char *paths O expanded file paths + * int nmax I max number of expanded file paths + * return : number of expanded file paths + * notes : the order of expanded files is alphabetical order + *-----------------------------------------------------------------------------*/ +extern int expath(const char *path, char *paths[], int nmax) { + int i, j, n = 0; + char tmp[1024]; #ifdef WIN32 - WIN32_FIND_DATA file; - HANDLE h; - char dir[1024]="",*p; + WIN32_FIND_DATA file; + HANDLE h; + char dir[1024] = "", *p; - trace(3,"expath : path=%s nmax=%d\n",path,nmax); + trace(3, "expath : path=%s nmax=%d\n", path, nmax); - if ((p=strrchr(path,'\\'))) { - strncpy(dir,path,p-path+1); dir[p-path+1]='\0'; - } - if ((h=FindFirstFile((LPCTSTR)path,&file))==INVALID_HANDLE_VALUE) { - strcpy(paths[0],path); - return 1; - } - sprintf(paths[n++],"%s%s",dir,file.cFileName); - while (FindNextFile(h,&file)&&nd_name)=='.') continue; - sprintf(s1,"^%s$",d->d_name); - sprintf(s2,"^%s$",file); - for (p=s1;*p;p++) *p=(char)tolower((int)*p); - for (p=s2;*p;p++) *p=(char)tolower((int)*p); - - for (p=s1,q=strtok_r(s2,"*",&r);q;q=strtok_r(NULL,"*",&r)) { - if ((p=strstr(p,q))) p+=strlen(q); else break; - } - if (p&&nd_name); - } - closedir(dp); + if ((p = strrchr(path, '/')) || (p = strrchr(path, '\\'))) { + file = p + 1; + strncpy(dir, path, p - path + 1); + dir[p - path + 1] = '\0'; + } + if (!(dp = opendir(*dir ? dir : "."))) return 0; + while ((d = readdir(dp))) { + if (*(d->d_name) == '.') continue; + sprintf(s1, "^%s$", d->d_name); + sprintf(s2, "^%s$", file); + for (p = s1; *p; p++) *p = (char)tolower((int)*p); + for (p = s2; *p; p++) *p = (char)tolower((int)*p); + + for (p = s1, q = strtok_r(s2, "*", &r); q; q = strtok_r(NULL, "*", &r)) { + if ((p = strstr(p, q))) + p += strlen(q); + else + break; + } + if (p && n < nmax) sprintf(paths[n++], "%s%s", dir, d->d_name); + } + closedir(dp); #endif - /* sort paths in alphabetical order */ - for (i=0;i0) { - strcpy(tmp,paths[i]); - strcpy(paths[i],paths[j]); - strcpy(paths[j],tmp); - } - } + /* sort paths in alphabetical order */ + for (i = 0; i < n - 1; i++) { + for (j = i + 1; j < n; j++) { + if (strcmp(paths[i], paths[j]) > 0) { + strcpy(tmp, paths[i]); + strcpy(paths[i], paths[j]); + strcpy(paths[j], tmp); + } } - for (i=0;i yyyy : year (4 digits) (1900-2099) -* %y -> yy : year (2 digits) (00-99) -* %m -> mm : month (01-12) -* %d -> dd : day of month (01-31) -* %h -> hh : hours (00-23) -* %M -> mm : minutes (00-59) -* %S -> ss : seconds (00-59) -* %n -> ddd : day of year (001-366) -* %W -> wwww : gps week (0001-9999) -* %D -> d : day of gps week (0-6) -* %H -> h : hour code (a=0,b=1,c=2,...,x=23) -* %ha-> hh : 3 hours (00,03,06,...,21) -* %hb-> hh : 6 hours (00,06,12,18) -* %hc-> hh : 12 hours (00,12) -* %t -> mm : 15 minutes (00,15,30,45) -* %r -> rrrr : rover id -* %b -> bbbb : base station id -*-----------------------------------------------------------------------------*/ -extern int reppath(const char *path, char *rpath, gtime_t time, const char *rov, - const char *base) -{ - double ep[6],ep0[6]={2000,1,1,0,0,0}; - int week,dow,doy,stat=0; - char rep[64]; - - strcpy(rpath,path); - - if (!strstr(rpath,"%")) return 0; - if (*rov ) stat|=repstr(rpath,"%r",rov ); - if (*base) stat|=repstr(rpath,"%b",base); - if (time.time!=0) { - time2epoch(time,ep); - ep0[0]=ep[0]; - dow=(int)floor(time2gpst(time,&week)/86400.0); - doy=(int)floor(timediff(time,epoch2time(ep0))/86400.0)+1; - sprintf(rep,"%02d", ((int)ep[3]/3)*3); stat|=repstr(rpath,"%ha",rep); - sprintf(rep,"%02d", ((int)ep[3]/6)*6); stat|=repstr(rpath,"%hb",rep); - sprintf(rep,"%02d", ((int)ep[3]/12)*12); stat|=repstr(rpath,"%hc",rep); - sprintf(rep,"%04.0f",ep[0]); stat|=repstr(rpath,"%Y",rep); - sprintf(rep,"%02.0f",fmod(ep[0],100.0)); stat|=repstr(rpath,"%y",rep); - sprintf(rep,"%02.0f",ep[1]); stat|=repstr(rpath,"%m",rep); - sprintf(rep,"%02.0f",ep[2]); stat|=repstr(rpath,"%d",rep); - sprintf(rep,"%02.0f",ep[3]); stat|=repstr(rpath,"%h",rep); - sprintf(rep,"%02.0f",ep[4]); stat|=repstr(rpath,"%M",rep); - sprintf(rep,"%02.0f",floor(ep[5])); stat|=repstr(rpath,"%S",rep); - sprintf(rep,"%03d", doy); stat|=repstr(rpath,"%n",rep); - sprintf(rep,"%04d", week); stat|=repstr(rpath,"%W",rep); - sprintf(rep,"%d", dow); stat|=repstr(rpath,"%D",rep); - sprintf(rep,"%c", 'a'+(int)ep[3]); stat|=repstr(rpath,"%H",rep); - sprintf(rep,"%02d", ((int)ep[4]/15)*15); stat|=repstr(rpath,"%t",rep); - } - else if (strstr(rpath,"%ha")||strstr(rpath,"%hb")||strstr(rpath,"%hc")|| - strstr(rpath,"%Y" )||strstr(rpath,"%y" )||strstr(rpath,"%m" )|| - strstr(rpath,"%d" )||strstr(rpath,"%h" )||strstr(rpath,"%M" )|| - strstr(rpath,"%S" )||strstr(rpath,"%n" )||strstr(rpath,"%W" )|| - strstr(rpath,"%D" )||strstr(rpath,"%H" )||strstr(rpath,"%t" )) { - return -1; /* no valid time */ - } - return stat; + * replace keywords in file path with date, time, rover and base station id + * args : char *path I file path (see below) + * char *rpath O file path in which keywords replaced (see below) + * gtime_t time I time (gpst) (time.time==0: not replaced) + * char *rov I rover id string ("": not replaced) + * char *base I base station id string ("": not replaced) + * return : status (1:keywords replaced, 0:no valid keyword in the path, + * -1:no valid time) + * notes : the following keywords in path are replaced by date, time and name + * %Y -> yyyy : year (4 digits) (1900-2099) + * %y -> yy : year (2 digits) (00-99) + * %m -> mm : month (01-12) + * %d -> dd : day of month (01-31) + * %h -> hh : hours (00-23) + * %M -> mm : minutes (00-59) + * %S -> ss : seconds (00-59) + * %n -> ddd : day of year (001-366) + * %W -> wwww : gps week (0001-9999) + * %D -> d : day of gps week (0-6) + * %H -> h : hour code (a=0,b=1,c=2,...,x=23) + * %ha-> hh : 3 hours (00,03,06,...,21) + * %hb-> hh : 6 hours (00,06,12,18) + * %hc-> hh : 12 hours (00,12) + * %t -> mm : 15 minutes (00,15,30,45) + * %r -> rrrr : rover id + * %b -> bbbb : base station id + *-----------------------------------------------------------------------------*/ +extern int reppath(const char *path, char *rpath, gtime_t time, const char *rov, const char *base) { + double ep[6], ep0[6] = {2000, 1, 1, 0, 0, 0}; + int week, dow, doy, stat = 0; + char rep[64]; + + strcpy(rpath, path); + + if (!strstr(rpath, "%")) return 0; + if (*rov) stat |= repstr(rpath, "%r", rov); + if (*base) stat |= repstr(rpath, "%b", base); + if (time.time != 0) { + time2epoch(time, ep); + ep0[0] = ep[0]; + dow = (int)floor(time2gpst(time, &week) / 86400.0); + doy = (int)floor(timediff(time, epoch2time(ep0)) / 86400.0) + 1; + sprintf(rep, "%02d", ((int)ep[3] / 3) * 3); + stat |= repstr(rpath, "%ha", rep); + sprintf(rep, "%02d", ((int)ep[3] / 6) * 6); + stat |= repstr(rpath, "%hb", rep); + sprintf(rep, "%02d", ((int)ep[3] / 12) * 12); + stat |= repstr(rpath, "%hc", rep); + sprintf(rep, "%04.0f", ep[0]); + stat |= repstr(rpath, "%Y", rep); + sprintf(rep, "%02.0f", fmod(ep[0], 100.0)); + stat |= repstr(rpath, "%y", rep); + sprintf(rep, "%02.0f", ep[1]); + stat |= repstr(rpath, "%m", rep); + sprintf(rep, "%02.0f", ep[2]); + stat |= repstr(rpath, "%d", rep); + sprintf(rep, "%02.0f", ep[3]); + stat |= repstr(rpath, "%h", rep); + sprintf(rep, "%02.0f", ep[4]); + stat |= repstr(rpath, "%M", rep); + sprintf(rep, "%02.0f", floor(ep[5])); + stat |= repstr(rpath, "%S", rep); + sprintf(rep, "%03d", doy); + stat |= repstr(rpath, "%n", rep); + sprintf(rep, "%04d", week); + stat |= repstr(rpath, "%W", rep); + sprintf(rep, "%d", dow); + stat |= repstr(rpath, "%D", rep); + sprintf(rep, "%c", 'a' + (int)ep[3]); + stat |= repstr(rpath, "%H", rep); + sprintf(rep, "%02d", ((int)ep[4] / 15) * 15); + stat |= repstr(rpath, "%t", rep); + } else if (strstr(rpath, "%ha") || strstr(rpath, "%hb") || strstr(rpath, "%hc") || + strstr(rpath, "%Y") || strstr(rpath, "%y") || strstr(rpath, "%m") || + strstr(rpath, "%d") || strstr(rpath, "%h") || strstr(rpath, "%M") || + strstr(rpath, "%S") || strstr(rpath, "%n") || strstr(rpath, "%W") || + strstr(rpath, "%D") || strstr(rpath, "%H") || strstr(rpath, "%t")) { + return -1; /* no valid time */ + } + return stat; } /* replace keywords in file path and generate multiple paths ------------------- -* replace keywords in file path with date, time, rover and base station id -* generate multiple keywords-replaced paths -* args : char *path I file path (see below) -* char *rpath[] O file paths in which keywords replaced -* int nmax I max number of output file paths -* gtime_t ts I time start (gpst) -* gtime_t te I time end (gpst) -* char *rov I rover id string ("": not replaced) -* char *base I base station id string ("": not replaced) -* return : number of replaced file paths -* notes : see reppath() for replacements of keywords. -* minimum interval of time replaced is 900s. -*-----------------------------------------------------------------------------*/ -extern int reppaths(const char *path, char *rpath[], int nmax, gtime_t ts, - gtime_t te, const char *rov, const char *base) -{ - gtime_t time; - double tow,tint=86400.0; - int i,n=0,week; - - trace(3,"reppaths: path =%s nmax=%d rov=%s base=%s\n",path,nmax,rov,base); - - if (ts.time==0||te.time==0||timediff(ts,te)>0.0) return 0; - - if (strstr(path,"%S")||strstr(path,"%M")||strstr(path,"%t")) tint=900.0; - else if (strstr(path,"%h")||strstr(path,"%H")) tint=3600.0; - - tow=time2gpst(ts,&week); - time=gpst2time(week,floor(tow/tint)*tint); - - while (timediff(time,te)<=0.0&&n 0.0) return 0; + + if (strstr(path, "%S") || strstr(path, "%M") || strstr(path, "%t")) + tint = 900.0; + else if (strstr(path, "%h") || strstr(path, "%H")) + tint = 3600.0; + + tow = time2gpst(ts, &week); + time = gpst2time(week, floor(tow / tint) * tint); + + while (timediff(time, te) <= 0.0 && n < nmax) { + reppath(path, rpath[n], time, rov, base); + if (n == 0 || strcmp(rpath[n], rpath[n - 1])) n++; + time = timeadd(time, tint); + } + for (i = 0; i < n; i++) trace(3, "reppaths: rpath=%s\n", rpath[i]); + return n; } /* geometric distance ---------------------------------------------------------- -* compute geometric distance and receiver-to-satellite unit vector -* args : double *rs I satellite position (ecef at transmission) (m) -* double *rr I receiver position (ecef at reception) (m) -* double *e O line-of-sight vector (ecef) -* return : geometric distance (m) (0>:error/no satellite position) -* notes : distance includes sagnac effect correction -*-----------------------------------------------------------------------------*/ -extern double geodist(const double *rs, const double *rr, double *e) -{ - double r; - int i; - - if (norm(rs,3):error/no satellite position) + * notes : distance includes sagnac effect correction + *-----------------------------------------------------------------------------*/ +extern double geodist(const double *rs, const double *rr, double *e) { + double r; + int i; + + if (norm(rs, 3) < RE_WGS84) return -1.0; + for (i = 0; i < 3; i++) e[i] = rs[i] - rr[i]; + r = norm(e, 3); + for (i = 0; i < 3; i++) e[i] /= r; + return r + OMGE * (rs[0] * rr[1] - rs[1] * rr[0]) / CLIGHT; } /* satellite azimuth/elevation angle ------------------------------------------- -* compute satellite azimuth/elevation angle -* args : double *pos I geodetic position {lat,lon,h} (rad,m) -* double *e I receiver-to-satellilte unit vevtor (ecef) -* double *azel IO azimuth/elevation {az,el} (rad) (NULL: no output) -* (0.0<=azel[0]<2*pi,-pi/2<=azel[1]<=pi/2) -* return : elevation angle (rad) -*-----------------------------------------------------------------------------*/ -extern double satazel(const double *pos, const double *e, double *azel) -{ - double az=0.0,el=PI/2.0,enu[3]; - - if (pos[2]>-RE_WGS84) { - ecef2enu(pos,e,enu); - az=dot2(enu,enu)<1E-12?0.0:atan2(enu[0],enu[1]); - if (az<0.0) az+=2*PI; - el=asin(enu[2]); - } - if (azel) {azel[0]=az; azel[1]=el;} - return el; + * compute satellite azimuth/elevation angle + * args : double *pos I geodetic position {lat,lon,h} (rad,m) + * double *e I receiver-to-satellilte unit vevtor (ecef) + * double *azel IO azimuth/elevation {az,el} (rad) (NULL: no output) + * (0.0<=azel[0]<2*pi,-pi/2<=azel[1]<=pi/2) + * return : elevation angle (rad) + *-----------------------------------------------------------------------------*/ +extern double satazel(const double *pos, const double *e, double *azel) { + double az = 0.0, el = PI / 2.0, enu[3]; + + if (pos[2] > -RE_WGS84) { + ecef2enu(pos, e, enu); + az = dot2(enu, enu) < 1E-12 ? 0.0 : atan2(enu[0], enu[1]); + if (az < 0.0) az += 2 * PI; + el = asin(enu[2]); + } + if (azel) { + azel[0] = az; + azel[1] = el; + } + return el; } /* compute dops ---------------------------------------------------------------- -* compute DOP (dilution of precision) -* args : int ns I number of satellites -* double *azel I satellite azimuth/elevation angle (rad) -* double elmin I elevation cutoff angle (rad) -* double *dop O DOPs {GDOP,PDOP,HDOP,VDOP} -* return : none -* notes : dop[0]-[3] return 0 in case of dop computation error -*-----------------------------------------------------------------------------*/ -#define SQRT(x) ((x)<0.0||(x)!=(x)?0.0:sqrt(x)) - -extern void dops(int ns, const double *azel, double elmin, double *dop) -{ - double H[4*MAXSAT],Q[16],cosel,sinel; - int i,n; - - for (i=0;i<4;i++) dop[i]=0.0; - for (i=n=0;i 0.416) phi= 0.416; - else if (phi<-0.416) phi=-0.416; - lam=pos[1]/PI+psi*sin(azel[0])/cos(phi*PI); - - /* geomagnetic latitude (semi-circle) */ - phi+=0.064*cos((lam-1.617)*PI); - - /* local time (s) */ - tt=43200.0*lam+time2gpst(t,&week); - tt-=floor(tt/86400.0)*86400.0; /* 0<=tt<86400 */ - - /* slant factor */ - f=1.0+16.0*pow(0.53-azel[1]/PI,3.0); - - /* ionospheric delay */ - amp=ion[0]+phi*(ion[1]+phi*(ion[2]+phi*ion[3])); - per=ion[4]+phi*(ion[5]+phi*(ion[6]+phi*ion[7])); - amp=amp< 0.0? 0.0:amp; - per=per<72000.0?72000.0:per; - x=2.0*PI*(tt-50400.0)/per; - - return CLIGHT*f*(fabs(x)<1.57?5E-9+amp*(1.0+x*x*(-0.5+x*x/24.0)):5E-9); + * compute ionospheric delay by broadcast ionosphere model (klobuchar model) + * args : gtime_t t I time (gpst) + * double *ion I iono model parameters {a0,a1,a2,a3,b0,b1,b2,b3} + * double *pos I receiver position {lat,lon,h} (rad,m) + * double *azel I azimuth/elevation angle {az,el} (rad) + * return : ionospheric delay (L1) (m) + *-----------------------------------------------------------------------------*/ +extern double ionmodel(gtime_t t, const double *ion, const double *pos, const double *azel) { + const double ion_default[] = {/* 2004/1/1 */ + 0.1118E-07, -0.7451E-08, -0.5961E-07, 0.1192E-06, + 0.1167E+06, -0.2294E+06, -0.1311E+06, 0.1049E+07}; + double tt, f, psi, phi, lam, amp, per, x; + int week; + + if (pos[2] < -1E3 || azel[1] <= 0) return 0.0; + if (norm(ion, 8) <= 0.0) ion = ion_default; + + /* earth centered angle (semi-circle) */ + psi = 0.0137 / (azel[1] / PI + 0.11) - 0.022; + + /* subionospheric latitude/longitude (semi-circle) */ + phi = pos[0] / PI + psi * cos(azel[0]); + if (phi > 0.416) + phi = 0.416; + else if (phi < -0.416) + phi = -0.416; + lam = pos[1] / PI + psi * sin(azel[0]) / cos(phi * PI); + + /* geomagnetic latitude (semi-circle) */ + phi += 0.064 * cos((lam - 1.617) * PI); + + /* local time (s) */ + tt = 43200.0 * lam + time2gpst(t, &week); + tt -= floor(tt / 86400.0) * 86400.0; /* 0<=tt<86400 */ + + /* slant factor */ + f = 1.0 + 16.0 * pow(0.53 - azel[1] / PI, 3.0); + + /* ionospheric delay */ + amp = ion[0] + phi * (ion[1] + phi * (ion[2] + phi * ion[3])); + per = ion[4] + phi * (ion[5] + phi * (ion[6] + phi * ion[7])); + amp = amp < 0.0 ? 0.0 : amp; + per = per < 72000.0 ? 72000.0 : per; + x = 2.0 * PI * (tt - 50400.0) / per; + + return CLIGHT * f * (fabs(x) < 1.57 ? 5E-9 + amp * (1.0 + x * x * (-0.5 + x * x / 24.0)) : 5E-9); } /* ionosphere mapping function ------------------------------------------------- -* compute ionospheric delay mapping function by single layer model -* args : double *pos I receiver position {lat,lon,h} (rad,m) -* double *azel I azimuth/elevation angle {az,el} (rad) -* return : ionospheric mapping function -*-----------------------------------------------------------------------------*/ -extern double ionmapf(const double *pos, const double *azel) -{ - if (pos[2]>=HION) return 1.0; - return 1.0/cos(asin((RE_WGS84+pos[2])/(RE_WGS84+HION)*sin(PI/2.0-azel[1]))); + * compute ionospheric delay mapping function by single layer model + * args : double *pos I receiver position {lat,lon,h} (rad,m) + * double *azel I azimuth/elevation angle {az,el} (rad) + * return : ionospheric mapping function + *-----------------------------------------------------------------------------*/ +extern double ionmapf(const double *pos, const double *azel) { + if (pos[2] >= HION) return 1.0; + return 1.0 / cos(asin((RE_WGS84 + pos[2]) / (RE_WGS84 + HION) * sin(PI / 2.0 - azel[1]))); } /* ionospheric pierce point position ------------------------------------------- -* compute ionospheric pierce point (ipp) position and slant factor -* args : double *pos I receiver position {lat,lon,h} (rad,m) -* double *azel I azimuth/elevation angle {az,el} (rad) -* double re I earth radius (km) -* double hion I altitude of ionosphere (km) -* double *posp O pierce point position {lat,lon,h} (rad,m) -* return : slant factor, the single-layer mapping function. -* notes : see ref [2], only valid on the earth surface -* fixing bug on ref [2] A.4.4.10.1 A-22,23 -*-----------------------------------------------------------------------------*/ -extern double ionppp(const double *pos, const double *azel, double re, - double hion, double *posp) -{ - double cosaz,r,rp,ap,sinap,tanap; - - /* The radius at the receiver station. */ - r=re+pos[2]/1000.0; - /* asin(rp) is the zenith angle at the IPP. */ - rp=r/(re+hion)*cos(azel[1]); - /* The angle at the center of the earth. */ - ap=PI/2.0-azel[1]-asin(rp); - sinap=sin(ap); - tanap=tan(ap); - cosaz=cos(azel[0]); - posp[0]=asin(sin(pos[0])*cos(ap)+cos(pos[0])*sinap*cosaz); - - if ((pos[0]> 70.0*D2R&& tanap*cosaz>tan(PI/2.0-pos[0]))|| - (pos[0]<-70.0*D2R&&-tanap*cosaz>tan(PI/2.0+pos[0]))) { - posp[1]=pos[1]+PI-asin(sinap*sin(azel[0])/cos(posp[0])); - } - else { - posp[1]=pos[1]+asin(sinap*sin(azel[0])/cos(posp[0])); - } - /* Equivalent to 1/cos(asin(rp)) */ - return 1.0/sqrt(1.0-rp*rp); + * compute ionospheric pierce point (ipp) position and slant factor + * args : double *pos I receiver position {lat,lon,h} (rad,m) + * double *azel I azimuth/elevation angle {az,el} (rad) + * double re I earth radius (km) + * double hion I altitude of ionosphere (km) + * double *posp O pierce point position {lat,lon,h} (rad,m) + * return : slant factor, the single-layer mapping function. + * notes : see ref [2], only valid on the earth surface + * fixing bug on ref [2] A.4.4.10.1 A-22,23 + *-----------------------------------------------------------------------------*/ +extern double ionppp(const double *pos, const double *azel, double re, double hion, double *posp) { + double cosaz, r, rp, ap, sinap, tanap; + + /* The radius at the receiver station. */ + r = re + pos[2] / 1000.0; + /* asin(rp) is the zenith angle at the IPP. */ + rp = r / (re + hion) * cos(azel[1]); + /* The angle at the center of the earth. */ + ap = PI / 2.0 - azel[1] - asin(rp); + sinap = sin(ap); + tanap = tan(ap); + cosaz = cos(azel[0]); + posp[0] = asin(sin(pos[0]) * cos(ap) + cos(pos[0]) * sinap * cosaz); + + if ((pos[0] > 70.0 * D2R && tanap * cosaz > tan(PI / 2.0 - pos[0])) || + (pos[0] < -70.0 * D2R && -tanap * cosaz > tan(PI / 2.0 + pos[0]))) { + posp[1] = pos[1] + PI - asin(sinap * sin(azel[0]) / cos(posp[0])); + } else { + posp[1] = pos[1] + asin(sinap * sin(azel[0]) / cos(posp[0])); + } + /* Equivalent to 1/cos(asin(rp)) */ + return 1.0 / sqrt(1.0 - rp * rp); } /* select iono-free linear combination (L1/L2 or L1/L5) ----------------------*/ -extern int seliflc(int optnf,int sys) -{ - /* use L1/L5 for Galileo if L5 is enabled */ - return((optnf==2||sys!=SYS_GAL)?1:2); +extern int seliflc(int optnf, int sys) { + /* use L1/L5 for Galileo if L5 is enabled */ + return ((optnf == 2 || sys != SYS_GAL) ? 1 : 2); } /* troposphere model ----------------------------------------------------------- -* compute tropospheric delay by standard atmosphere and saastamoinen model -* args : gtime_t time I time -* double *pos I receiver position {lat,lon,h} (rad,m) -* double *azel I azimuth/elevation angle {az,el} (rad) -* double humi I relative humidity -* return : tropospheric delay (m) -*-----------------------------------------------------------------------------*/ -extern double tropmodel(gtime_t time, const double *pos, const double *azel, - double humi) -{ - (void)time; - const double temp0=15.0; /* temperature at sea level */ - double hgt,pres,temp,e,z,trph,trpw; - - if (pos[2]<-100.0||1E44) return coef[4]; - return coef[i-1]*(1.0-lat/15.0+i)+coef[i]*(lat/15.0-i); -} -static double mapf(double el, double a, double b, double c) -{ - double sinel=sin(el); - return (1.0+a/(1.0+b/(1.0+c)))/(sinel+(a/(sinel+b/(sinel+c)))); -} -static double nmf(gtime_t time, const double pos[], const double azel[], - double *mapfw) -{ - /* ref [5] table 3 */ - /* hydro-ave-a,b,c, hydro-amp-a,b,c, wet-a,b,c at latitude 15,30,45,60,75 */ - const double coef[][5]={ - { 1.2769934E-3, 1.2683230E-3, 1.2465397E-3, 1.2196049E-3, 1.2045996E-3}, - { 2.9153695E-3, 2.9152299E-3, 2.9288445E-3, 2.9022565E-3, 2.9024912E-3}, - { 62.610505E-3, 62.837393E-3, 63.721774E-3, 63.824265E-3, 64.258455E-3}, - - { 0.0000000E-0, 1.2709626E-5, 2.6523662E-5, 3.4000452E-5, 4.1202191E-5}, - { 0.0000000E-0, 2.1414979E-5, 3.0160779E-5, 7.2562722E-5, 11.723375E-5}, - { 0.0000000E-0, 9.0128400E-5, 4.3497037E-5, 84.795348E-5, 170.37206E-5}, - - { 5.8021897E-4, 5.6794847E-4, 5.8118019E-4, 5.9727542E-4, 6.1641693E-4}, - { 1.4275268E-3, 1.5138625E-3, 1.4572752E-3, 1.5007428E-3, 1.7599082E-3}, - { 4.3472961E-2, 4.6729510E-2, 4.3908931E-2, 4.4626982E-2, 5.4736038E-2} - }; - const double aht[]={ 2.53E-5, 5.49E-3, 1.14E-3}; /* height correction */ - - double y,cosy,ah[3],aw[3],dm,el=azel[1],lat=pos[0]*R2D,hgt=pos[2]; - int i; - - if (el<=0.0) { - if (mapfw) *mapfw=0.0; - return 0.0; - } - /* year from doy 28, added half a year for southern latitudes */ - y=(time2doy(time)-28.0)/365.25+(lat<0.0?0.5:0.0); +static double interpc(const double coef[], double lat) { + int i = (int)(lat / 15.0); + if (i < 1) + return coef[0]; + else if (i > 4) + return coef[4]; + return coef[i - 1] * (1.0 - lat / 15.0 + i) + coef[i] * (lat / 15.0 - i); +} +static double mapf(double el, double a, double b, double c) { + double sinel = sin(el); + return (1.0 + a / (1.0 + b / (1.0 + c))) / (sinel + (a / (sinel + b / (sinel + c)))); +} +static double nmf(gtime_t time, const double pos[], const double azel[], double *mapfw) { + /* ref [5] table 3 */ + /* hydro-ave-a,b,c, hydro-amp-a,b,c, wet-a,b,c at latitude 15,30,45,60,75 */ + const double coef[][5] = {{1.2769934E-3, 1.2683230E-3, 1.2465397E-3, 1.2196049E-3, 1.2045996E-3}, + {2.9153695E-3, 2.9152299E-3, 2.9288445E-3, 2.9022565E-3, 2.9024912E-3}, + {62.610505E-3, 62.837393E-3, 63.721774E-3, 63.824265E-3, 64.258455E-3}, + + {0.0000000E-0, 1.2709626E-5, 2.6523662E-5, 3.4000452E-5, 4.1202191E-5}, + {0.0000000E-0, 2.1414979E-5, 3.0160779E-5, 7.2562722E-5, 11.723375E-5}, + {0.0000000E-0, 9.0128400E-5, 4.3497037E-5, 84.795348E-5, 170.37206E-5}, + + {5.8021897E-4, 5.6794847E-4, 5.8118019E-4, 5.9727542E-4, 6.1641693E-4}, + {1.4275268E-3, 1.5138625E-3, 1.4572752E-3, 1.5007428E-3, 1.7599082E-3}, + {4.3472961E-2, 4.6729510E-2, 4.3908931E-2, 4.4626982E-2, 5.4736038E-2}}; + const double aht[] = {2.53E-5, 5.49E-3, 1.14E-3}; /* height correction */ + + double y, cosy, ah[3], aw[3], dm, el = azel[1], lat = pos[0] * R2D, hgt = pos[2]; + int i; + + if (el <= 0.0) { + if (mapfw) *mapfw = 0.0; + return 0.0; + } + /* year from doy 28, added half a year for southern latitudes */ + y = (time2doy(time) - 28.0) / 365.25 + (lat < 0.0 ? 0.5 : 0.0); - cosy=cos(2.0*PI*y); - lat=fabs(lat); + cosy = cos(2.0 * PI * y); + lat = fabs(lat); - for (i=0;i<3;i++) { - ah[i]=interpc(coef[i ],lat)-interpc(coef[i+3],lat)*cosy; - aw[i]=interpc(coef[i+6],lat); - } - /* ellipsoidal height is used instead of height above sea level */ - dm=(1.0/sin(el)-mapf(el,aht[0],aht[1],aht[2]))*hgt/1E3; + for (i = 0; i < 3; i++) { + ah[i] = interpc(coef[i], lat) - interpc(coef[i + 3], lat) * cosy; + aw[i] = interpc(coef[i + 6], lat); + } + /* ellipsoidal height is used instead of height above sea level */ + dm = (1.0 / sin(el) - mapf(el, aht[0], aht[1], aht[2])) * hgt / 1E3; - if (mapfw) *mapfw=mapf(el,aw[0],aw[1],aw[2]); + if (mapfw) *mapfw = mapf(el, aw[0], aw[1], aw[2]); - return mapf(el,ah[0],ah[1],ah[2])+dm; + return mapf(el, ah[0], ah[1], ah[2]) + dm; } #endif /* !IERS_MODEL */ /* troposphere mapping function ------------------------------------------------ -* compute tropospheric mapping function by NMF -* args : gtime_t t I time -* double *pos I receiver position {lat,lon,h} (rad,m) -* double *azel I azimuth/elevation angle {az,el} (rad) -* double *mapfw IO wet mapping function (NULL: not output) -* return : dry mapping function -* note : see ref [5] (NMF) and [9] (GMF) -* original JGR paper of [5] has bugs in eq.(4) and (5). the corrected -* paper is obtained from: -* ftp://web.haystack.edu/pub/aen/nmf/NMF_JGR.pdf -*-----------------------------------------------------------------------------*/ -extern double tropmapf(gtime_t time, const double pos[], const double azel[], - double *mapfw) -{ + * compute tropospheric mapping function by NMF + * args : gtime_t t I time + * double *pos I receiver position {lat,lon,h} (rad,m) + * double *azel I azimuth/elevation angle {az,el} (rad) + * double *mapfw IO wet mapping function (NULL: not output) + * return : dry mapping function + * note : see ref [5] (NMF) and [9] (GMF) + * original JGR paper of [5] has bugs in eq.(4) and (5). the corrected + * paper is obtained from: + * ftp://web.haystack.edu/pub/aen/nmf/NMF_JGR.pdf + *-----------------------------------------------------------------------------*/ +extern double tropmapf(gtime_t time, const double pos[], const double azel[], double *mapfw) { #ifdef IERS_MODEL - const double ep[]={2000,1,1,12,0,0}; - double mjd,lat,lon,hgt,zd,gmfh,gmfw; + const double ep[] = {2000, 1, 1, 12, 0, 0}; + double mjd, lat, lon, hgt, zd, gmfh, gmfw; #endif - trace(4,"tropmapf: pos=%10.6f %11.6f %6.1f azel=%5.1f %4.1f\n", - pos[0]*R2D,pos[1]*R2D,pos[2],azel[0]*R2D,azel[1]*R2D); + trace(4, "tropmapf: pos=%10.6f %11.6f %6.1f azel=%5.1f %4.1f\n", pos[0] * R2D, pos[1] * R2D, + pos[2], azel[0] * R2D, azel[1] * R2D); - if (pos[2]<-1000.0||pos[2]>20000.0) { - if (mapfw) *mapfw=0.0; - return 0.0; - } + if (pos[2] < -1000.0 || pos[2] > 20000.0) { + if (mapfw) *mapfw = 0.0; + return 0.0; + } #ifdef IERS_MODEL - mjd=51544.5+(timediff(time,epoch2time(ep)))/86400.0; - lat=pos[0]; - lon=pos[1]; - hgt=pos[2]-geoidh(pos); /* height in m (mean sea level) */ - zd =PI/2.0-azel[1]; + mjd = 51544.5 + (timediff(time, epoch2time(ep))) / 86400.0; + lat = pos[0]; + lon = pos[1]; + hgt = pos[2] - geoidh(pos); /* height in m (mean sea level) */ + zd = PI / 2.0 - azel[1]; - /* call GMF */ - gmf_(&mjd,&lat,&lon,&hgt,&zd,&gmfh,&gmfw); + /* call GMF */ + gmf_(&mjd, &lat, &lon, &hgt, &zd, &gmfh, &gmfw); - if (mapfw) *mapfw=gmfw; - return gmfh; + if (mapfw) *mapfw = gmfw; + return gmfh; #else - return nmf(time,pos,azel,mapfw); /* NMF */ + return nmf(time, pos, azel, mapfw); /* NMF */ #endif } /* interpolate antenna phase center variation --------------------------------*/ -static double interpvar(double ang, const double *var) -{ - double a=ang/5.0; /* ang=0-90 */ - int i=(int)a; - if (i<0) return var[0]; else if (i>=18) return var[18]; - return var[i]*(1.0-a+i)+var[i+1]*(a-i); +static double interpvar(double ang, const double *var) { + double a = ang / 5.0; /* ang=0-90 */ + int i = (int)a; + if (i < 0) + return var[0]; + else if (i >= 18) + return var[18]; + return var[i] * (1.0 - a + i) + var[i + 1] * (a - i); } /* receiver antenna model ------------------------------------------------------ -* compute antenna offset by antenna phase center parameters -* args : pcv_t *pcv I antenna phase center parameters -* double *del I antenna delta {e,n,u} (m) -* double *azel I azimuth/elevation for receiver {az,el} (rad) -* int opt I option (0:only offset,1:offset+pcv) -* double *dant O range offsets for each frequency (m) -* return : none -* notes : current version does not support azimuth dependent terms -*-----------------------------------------------------------------------------*/ -extern void antmodel(const pcv_t *pcv, const double *del, const double *azel, - int opt, double *dant) -{ - double e[3],off[3],cosel=cos(azel[1]); - int i,j; - - trace(4,"antmodel: azel=%6.1f %4.1f opt=%d\n",azel[0]*R2D,azel[1]*R2D,opt); - - e[0]=sin(azel[0])*cosel; - e[1]=cos(azel[0])*cosel; - e[2]=sin(azel[1]); - - for (i=0;ioff[i][j]+del[j]; - - dant[i]=-dot3(off,e)+(opt?interpvar(90.0-azel[1]*R2D,pcv->var[i]):0.0); - } - trace(4,"antmodel: dant=%6.3f %6.3f\n",dant[0],dant[1]); + * compute antenna offset by antenna phase center parameters + * args : pcv_t *pcv I antenna phase center parameters + * double *del I antenna delta {e,n,u} (m) + * double *azel I azimuth/elevation for receiver {az,el} (rad) + * int opt I option (0:only offset,1:offset+pcv) + * double *dant O range offsets for each frequency (m) + * return : none + * notes : current version does not support azimuth dependent terms + *-----------------------------------------------------------------------------*/ +extern void antmodel(const pcv_t *pcv, const double *del, const double *azel, int opt, + double *dant) { + double e[3], off[3], cosel = cos(azel[1]); + int i, j; + + trace(4, "antmodel: azel=%6.1f %4.1f opt=%d\n", azel[0] * R2D, azel[1] * R2D, opt); + + e[0] = sin(azel[0]) * cosel; + e[1] = cos(azel[0]) * cosel; + e[2] = sin(azel[1]); + + for (i = 0; i < NFREQ; i++) { + for (j = 0; j < 3; j++) off[j] = pcv->off[i][j] + del[j]; + + dant[i] = -dot3(off, e) + (opt ? interpvar(90.0 - azel[1] * R2D, pcv->var[i]) : 0.0); + } + trace(4, "antmodel: dant=%6.3f %6.3f\n", dant[0], dant[1]); } /* satellite antenna model ------------------------------------------------------ -* compute satellite antenna phase center parameters -* args : pcv_t *pcv I antenna phase center parameters -* double nadir I nadir angle for satellite (rad) -* double *dant O range offsets for each frequency (m) -* return : none -*-----------------------------------------------------------------------------*/ -extern void antmodel_s(const pcv_t *pcv, double nadir, double *dant) -{ - int i; - - trace(4,"antmodel_s: nadir=%6.1f\n",nadir*R2D); - - for (i=0;ivar[i]); - } - trace(4,"antmodel_s: dant=%6.3f %6.3f\n",dant[0],dant[1]); + * compute satellite antenna phase center parameters + * args : pcv_t *pcv I antenna phase center parameters + * double nadir I nadir angle for satellite (rad) + * double *dant O range offsets for each frequency (m) + * return : none + *-----------------------------------------------------------------------------*/ +extern void antmodel_s(const pcv_t *pcv, double nadir, double *dant) { + int i; + + trace(4, "antmodel_s: nadir=%6.1f\n", nadir * R2D); + + for (i = 0; i < NFREQ; i++) { + dant[i] = interpvar(nadir * R2D * 5.0, pcv->var[i]); + } + trace(4, "antmodel_s: dant=%6.3f %6.3f\n", dant[0], dant[1]); } // Free the pcv array. void free_pcvs(pcvs_t *pcvs) { @@ -3943,7 +4121,7 @@ static void sunpos_eci(gtime_t tutc, const double *erpv, double *rsun) { char tstr[40]; trace(4, "sunpos_eci: tutc=%s\n", time2str(tutc, tstr, 3)); -#ifdef SUNPOS_SOFA /* use high accuracy functions in sofa.c */ +#ifdef SUNPOS_SOFA /* use high accuracy functions in sofa.c */ (void)erpv; static THREADLOCAL gtime_t tutc_ = {0, 0}; static THREADLOCAL double rsun_[3]; @@ -3995,7 +4173,7 @@ static void moonpos_eci(gtime_t tutc, const double *erpv, double *rmoon) { char tstr[40]; trace(4, "moonpos_eci: tutc=%s\n", time2str(tutc, tstr, 3)); -#ifdef MOONPOS_SOFA /* use high accuracy functions in sofa.c */ +#ifdef MOONPOS_SOFA /* use high accuracy functions in sofa.c */ (void)erpv; static THREADLOCAL gtime_t tutc_ = {0, 0}; static THREADLOCAL double rmoon_[3]; @@ -4080,198 +4258,195 @@ extern void sunmoonpos(gtime_t tutc, const double *erpv, double *rsun, double *r } /* uncompress file ------------------------------------------------------------- -* uncompress (uncompress/unzip/uncompact hatanaka-compression/tar) file -* args : char *file I input file -* char *uncfile O uncompressed file -* return : status (-1:error,0:not compressed file,1:uncompress completed) -* note : creates uncompressed file in temporary directory -* gzip, tar and crx2rnx commands have to be installed in commands path -*-----------------------------------------------------------------------------*/ -extern int rtk_uncompress(const char *file, char *uncfile) -{ - int stat=0; - char *p,cmd[64+2048]="",tmpfile[1024]="",buff[1024],*fname,*dir=""; - - trace(3,"rtk_uncompress: file=%s\n",file); - - strcpy(tmpfile,file); - if (!(p=strrchr(tmpfile,'.'))) return 0; - - /* uncompress by gzip */ - if (!strcmp(p,".z" )||!strcmp(p,".Z" )|| - !strcmp(p,".gz" )||!strcmp(p,".GZ" )|| - !strcmp(p,".zip")||!strcmp(p,".ZIP")) { - - strcpy(uncfile,tmpfile); uncfile[p-tmpfile]='\0'; - sprintf(cmd,"gzip -f -d -c \"%s\" > \"%s\"",tmpfile,uncfile); - - if (execcmd(cmd)) { - remove(uncfile); - return -1; - } - strcpy(tmpfile,uncfile); - stat=1; - } - /* extract tar file */ - if ((p=strrchr(tmpfile,'.'))&&!strcmp(p,".tar")) { + * uncompress (uncompress/unzip/uncompact hatanaka-compression/tar) file + * args : char *file I input file + * char *uncfile O uncompressed file + * return : status (-1:error,0:not compressed file,1:uncompress completed) + * note : creates uncompressed file in temporary directory + * gzip, tar and crx2rnx commands have to be installed in commands path + *-----------------------------------------------------------------------------*/ +extern int rtk_uncompress(const char *file, char *uncfile) { + int stat = 0; + char *p, cmd[64 + 2048] = "", tmpfile[1024] = "", buff[1024], *fname, *dir = ""; + + trace(3, "rtk_uncompress: file=%s\n", file); - strcpy(uncfile,tmpfile); uncfile[p-tmpfile]='\0'; - strcpy(buff,tmpfile); - fname=buff; + strcpy(tmpfile, file); + if (!(p = strrchr(tmpfile, '.'))) return 0; + + /* uncompress by gzip */ + if (!strcmp(p, ".z") || !strcmp(p, ".Z") || !strcmp(p, ".gz") || !strcmp(p, ".GZ") || + !strcmp(p, ".zip") || !strcmp(p, ".ZIP")) { + strcpy(uncfile, tmpfile); + uncfile[p - tmpfile] = '\0'; + sprintf(cmd, "gzip -f -d -c \"%s\" > \"%s\"", tmpfile, uncfile); + + if (execcmd(cmd)) { + remove(uncfile); + return -1; + } + strcpy(tmpfile, uncfile); + stat = 1; + } + /* extract tar file */ + if ((p = strrchr(tmpfile, '.')) && !strcmp(p, ".tar")) { + strcpy(uncfile, tmpfile); + uncfile[p - tmpfile] = '\0'; + strcpy(buff, tmpfile); + fname = buff; #ifdef WIN32 - if ((p=strrchr(buff,'\\'))) { - *p='\0'; dir=fname; fname=p+1; - } - sprintf(cmd,"set PATH=%%CD%%;%%PATH%% & cd /D \"%s\" & tar -xf \"%s\"", - dir,fname); + if ((p = strrchr(buff, '\\'))) { + *p = '\0'; + dir = fname; + fname = p + 1; + } + sprintf(cmd, "set PATH=%%CD%%;%%PATH%% & cd /D \"%s\" & tar -xf \"%s\"", dir, fname); #else - if ((p=strrchr(buff,'/'))) { - *p='\0'; dir=fname; - } - sprintf(cmd,"tar -C \"%s\" -xf \"%s\"",dir,tmpfile); -#endif - if (execcmd(cmd)) { - if (stat) remove(tmpfile); - return -1; - } - if (stat) remove(tmpfile); - stat=1; + if ((p = strrchr(buff, '/'))) { + *p = '\0'; + dir = fname; } - /* extract hatanaka-compressed file by cnx2rnx */ - else if ((p=strrchr(tmpfile,'.'))&& - ((strlen(p)>3&&(*(p+3)=='d'||*(p+3)=='D'))|| - !strcmp(p,".crx")||!strcmp(p,".CRX"))) { - - strcpy(uncfile,tmpfile); - uncfile[p-tmpfile+3]=*(p+3)=='D'?'O':'o'; - sprintf(cmd,"crx2rnx < \"%s\" > \"%s\"",tmpfile,uncfile); - - if (execcmd(cmd)) { - remove(uncfile); - if (stat) remove(tmpfile); - return -1; - } - if (stat) remove(tmpfile); - stat=1; + sprintf(cmd, "tar -C \"%s\" -xf \"%s\"", dir, tmpfile); +#endif + if (execcmd(cmd)) { + if (stat) remove(tmpfile); + return -1; } - trace(3,"rtk_uncompress: stat=%d\n",stat); - return stat; + if (stat) remove(tmpfile); + stat = 1; + } + /* extract hatanaka-compressed file by cnx2rnx */ + else if ((p = strrchr(tmpfile, '.')) && + ((strlen(p) > 3 && (*(p + 3) == 'd' || *(p + 3) == 'D')) || !strcmp(p, ".crx") || + !strcmp(p, ".CRX"))) { + strcpy(uncfile, tmpfile); + uncfile[p - tmpfile + 3] = *(p + 3) == 'D' ? 'O' : 'o'; + sprintf(cmd, "crx2rnx < \"%s\" > \"%s\"", tmpfile, uncfile); + + if (execcmd(cmd)) { + remove(uncfile); + if (stat) remove(tmpfile); + return -1; + } + if (stat) remove(tmpfile); + stat = 1; + } + trace(3, "rtk_uncompress: stat=%d\n", stat); + return stat; } /* station position from file ------------------------------------------------*/ -extern int getstapos(const char *file, const char *name, double *r) -{ - trace(3, "getstapos: file=%s name=%s\n", file, name); - - FILE *fp = fopen(file, "r"); - if (!fp) { - trace(1,"station position file open error: %s\n",file); - return 0; - } - - char buff[256]; - int state = 0; // 0 pos file, 1 sinex misc, 2 sinex pos estimates. - int n = 0, posp = 0; - double poss[3]; - while (fgets(buff, sizeof(buff), fp)) { - size_t len = strlen(buff); - if (state == 0) { - if (len >= 4 && strncmp(buff, "%=SNX", 4) == 0) { - state = 1; - continue; - } - // RTKLIB Position file - char *p = strchr(buff,'%'); - if (p) *p='\0'; - - // Match either the full extended name or the 4 character - // prefix, giving priority to a full match. - char sname[256]; - double pos[3]; - if (sscanf(buff, "%lf %lf %lf %255s", pos, pos+1, pos+2, sname) < 4) continue; - - int i = 0; - for (; sname[i] && name[i]; i++) { - if (toupper(sname[i]) != toupper(name[i])) break; - } - - if (sname[i] == '\0' && name[i] == '\0') { - // Exact match. - pos[0] *= D2R; - pos[1] *= D2R; - pos2ecef(pos, r); - fclose(fp); - return 1; - } +extern int getstapos(const char *file, const char *name, double *r) { + trace(3, "getstapos: file=%s name=%s\n", file, name); - if (i > 3 && (sname[i] == '\0' || name[i] == '\0') && i > posp) { - // Prefix match, save position. - posp = i; - for (int i = 0; i < 3; i++) poss[i] = pos[i]; - } - } - - // Sinex position file. - if (buff[0] == '*') continue; // Comment - if (strncmp(buff, "+SOLUTION/ESTIMATE", 18) == 0) { - state = 2; - continue; - } - if (state != 2) continue; + FILE *fp = fopen(file, "r"); + if (!fp) { + trace(1, "station position file open error: %s\n", file); + return 0; + } - if (strncmp(buff, "-SOLUTION/ESTIMATE", 18) == 0) { + char buff[256]; + int state = 0; // 0 pos file, 1 sinex misc, 2 sinex pos estimates. + int n = 0, posp = 0; + double poss[3]; + while (fgets(buff, sizeof(buff), fp)) { + size_t len = strlen(buff); + if (state == 0) { + if (len >= 4 && strncmp(buff, "%=SNX", 4) == 0) { state = 1; continue; } - if (len < 68) { - trace(2, "getstapos: unexpected sinex line '%s'\n", buff); - continue; - } + // RTKLIB Position file + char *p = strchr(buff, '%'); + if (p) *p = '\0'; + + // Match either the full extended name or the 4 character + // prefix, giving priority to a full match. + char sname[256]; + double pos[3]; + if (sscanf(buff, "%lf %lf %lf %255s", pos, pos + 1, pos + 2, sname) < 4) continue; - // The solution sinex site codes are limited to 4 characters - // and only the 4 character prefix of the 'name' is matched. - char sname[5]; - setstr(sname, buff + 14, 4); int i = 0; - for (; i < 4 && sname[i] && name[i]; i++) { + for (; sname[i] && name[i]; i++) { if (toupper(sname[i]) != toupper(name[i])) break; } - if (sname[i]) continue; - if (i < 4 && name[i]) continue; - if (strncmp(buff + 7, "STAX", 4) == 0) { - r[0] = str2num(buff, 47, 21); - n |= 1; - } - if (strncmp(buff + 7, "STAY", 4) == 0) { - r[1] = str2num(buff, 47, 21); - n |= 2; - } - if (strncmp(buff + 7, "STAZ", 4) == 0) { - r[2] = str2num(buff, 47, 21); - n |= 4; - } - if (n == 7) { + if (sname[i] == '\0' && name[i] == '\0') { + // Exact match. + pos[0] *= D2R; + pos[1] *= D2R; + pos2ecef(pos, r); fclose(fp); return 1; } + + if (i > 3 && (sname[i] == '\0' || name[i] == '\0') && i > posp) { + // Prefix match, save position. + posp = i; + for (int i = 0; i < 3; i++) poss[i] = pos[i]; + } } - fclose(fp); - if (state == 0 && posp > 0) { - // Return the longest prefix match. - poss[0] *= D2R; - poss[1] *= D2R; - pos2ecef(poss, r); + // Sinex position file. + if (buff[0] == '*') continue; // Comment + if (strncmp(buff, "+SOLUTION/ESTIMATE", 18) == 0) { + state = 2; + continue; + } + if (state != 2) continue; + + if (strncmp(buff, "-SOLUTION/ESTIMATE", 18) == 0) { + state = 1; + continue; + } + if (len < 68) { + trace(2, "getstapos: unexpected sinex line '%s'\n", buff); + continue; + } + + // The solution sinex site codes are limited to 4 characters + // and only the 4 character prefix of the 'name' is matched. + char sname[5]; + setstr(sname, buff + 14, 4); + int i = 0; + for (; i < 4 && sname[i] && name[i]; i++) { + if (toupper(sname[i]) != toupper(name[i])) break; + } + if (sname[i]) continue; + if (i < 4 && name[i]) continue; + + if (strncmp(buff + 7, "STAX", 4) == 0) { + r[0] = str2num(buff, 47, 21); + n |= 1; + } + if (strncmp(buff + 7, "STAY", 4) == 0) { + r[1] = str2num(buff, 47, 21); + n |= 2; + } + if (strncmp(buff + 7, "STAZ", 4) == 0) { + r[2] = str2num(buff, 47, 21); + n |= 4; + } + if (n == 7) { + fclose(fp); return 1; } + } + fclose(fp); - trace(1, "no station position: %s %s\n", name, file); - return 0; + if (state == 0 && posp > 0) { + // Return the longest prefix match. + poss[0] *= D2R; + poss[1] *= D2R; + pos2ecef(poss, r); + return 1; + } + + trace(1, "no station position: %s %s\n", name, file); + return 0; } /* dummy application functions for shared library ----------------------------*/ #if defined(WIN_DLL) || defined(DLL) -extern int showmsg(const char *format,...) {return 0;} +extern int showmsg(const char *format, ...) { return 0; } extern void settspan(gtime_t ts, gtime_t te) {} extern void settime(gtime_t time) {} #endif - diff --git a/src/rtklib.h b/src/rtklib.h index b77e4038b..1a89dda1c 100644 --- a/src/rtklib.h +++ b/src/rtklib.h @@ -1,46 +1,46 @@ /*------------------------------------------------------------------------------ -* rtklib.h : RTKLIB constants, types and function prototypes -* -* Copyright (C) 2007-2020 by T.TAKASU, All rights reserved. -* -* options : -DENAGLO enable GLONASS -* -DENAGAL enable Galileo -* -DENAQZS enable QZSS -* -DENACMP enable BeiDou -* -DENAIRN enable IRNSS -* -DNFREQ=n set number of obs codes/frequencies -* -DNEXOBS=n set number of extended obs codes -* -DMAXOBS=n set max number of obs data in an epoch -* -DWIN32 use WIN32 API -* -DWIN_DLL generate library as Windows DLL -* -* version : $Revision:$ $Date:$ -* history : 2007/01/13 1.0 rtklib ver.1.0.0 -* 2007/03/20 1.1 rtklib ver.1.1.0 -* 2008/07/15 1.2 rtklib ver.2.1.0 -* 2008/10/19 1.3 rtklib ver.2.1.1 -* 2009/01/31 1.4 rtklib ver.2.2.0 -* 2009/04/30 1.5 rtklib ver.2.2.1 -* 2009/07/30 1.6 rtklib ver.2.2.2 -* 2009/12/25 1.7 rtklib ver.2.3.0 -* 2010/07/29 1.8 rtklib ver.2.4.0 -* 2011/05/27 1.9 rtklib ver.2.4.1 -* 2013/03/28 1.10 rtklib ver.2.4.2 -* 2020/11/30 1.11 rtklib ver.2.4.3 b34 -*-----------------------------------------------------------------------------*/ + * rtklib.h : RTKLIB constants, types and function prototypes + * + * Copyright (C) 2007-2020 by T.TAKASU, All rights reserved. + * + * options : -DENAGLO enable GLONASS + * -DENAGAL enable Galileo + * -DENAQZS enable QZSS + * -DENACMP enable BeiDou + * -DENAIRN enable IRNSS + * -DNFREQ=n set number of obs codes/frequencies + * -DNEXOBS=n set number of extended obs codes + * -DMAXOBS=n set max number of obs data in an epoch + * -DWIN32 use WIN32 API + * -DWIN_DLL generate library as Windows DLL + * + * version : $Revision:$ $Date:$ + * history : 2007/01/13 1.0 rtklib ver.1.0.0 + * 2007/03/20 1.1 rtklib ver.1.1.0 + * 2008/07/15 1.2 rtklib ver.2.1.0 + * 2008/10/19 1.3 rtklib ver.2.1.1 + * 2009/01/31 1.4 rtklib ver.2.2.0 + * 2009/04/30 1.5 rtklib ver.2.2.1 + * 2009/07/30 1.6 rtklib ver.2.2.2 + * 2009/12/25 1.7 rtklib ver.2.3.0 + * 2010/07/29 1.8 rtklib ver.2.4.0 + * 2011/05/27 1.9 rtklib ver.2.4.1 + * 2013/03/28 1.10 rtklib ver.2.4.2 + * 2020/11/30 1.11 rtklib ver.2.4.3 b34 + *-----------------------------------------------------------------------------*/ #ifndef RTKLIB_H #define RTKLIB_H +#include +#include +#include +#include #include #include -#include #include -#include #include -#include -#include #ifdef WIN32 -#include #include +#include #else #include #include @@ -71,1483 +71,1511 @@ extern "C" { /* constants -----------------------------------------------------------------*/ -#define VER_RTKLIB "EX" /* library version */ - -#define PATCH_LEVEL "2.5.0" /* patch level */ - -#define COPYRIGHT_RTKLIB \ - "Copyright (C) 2007-2020 T.Takasu\nAll rights reserved." - -#define PI 3.1415926535897932 /* pi */ -#define D2R (PI/180.0) /* deg to rad */ -#define R2D (180.0/PI) /* rad to deg */ -#define CLIGHT 299792458.0 /* speed of light (m/s) */ -#define SC2RAD 3.1415926535898 /* semi-circle to radian (IS-GPS) */ -#define AU 149597870691.0 /* 1 AU (m) */ -#define AS2R (D2R/3600.0) /* arc sec to radian */ - -#define OMGE 7.2921151467E-5 /* earth angular velocity (IS-GPS) (rad/s) */ - -#define RE_WGS84 6378137.0 /* earth semimajor axis (WGS84) (m) */ -#define FE_WGS84 (1.0/298.257223563) /* earth flattening (WGS84) */ - -#define HION 350000.0 /* ionosphere height (m) */ - -#define MAXFREQ 6 /* max NFREQ */ - -#define FREQL1 1.57542E9 /* L1/E1 frequency (Hz) */ -#define FREQL2 1.22760E9 /* L2 frequency (Hz) */ -#define FREQE5b 1.20714E9 /* E5b frequency (Hz) */ -#define FREQL5 1.17645E9 /* L5/E5a/B2a frequency (Hz) */ -#define FREQL6 1.27875E9 /* E6/L6 frequency (Hz) */ -#define FREQE5ab 1.191795E9 /* E5a+b frequency (Hz) */ -#define FREQs 2.492028E9 /* S frequency (Hz) */ -#define FREQ1_GLO 1.60200E9 /* GLONASS G1 base frequency (Hz) */ -#define DFRQ1_GLO 0.56250E6 /* GLONASS G1 bias frequency (Hz/n) */ -#define FREQ2_GLO 1.24600E9 /* GLONASS G2 base frequency (Hz) */ -#define DFRQ2_GLO 0.43750E6 /* GLONASS G2 bias frequency (Hz/n) */ -#define FREQ3_GLO 1.202025E9 /* GLONASS G3 frequency (Hz) */ -#define FREQ1a_GLO 1.600995E9 /* GLONASS G1a frequency (Hz) */ -#define FREQ2a_GLO 1.248060E9 /* GLONASS G2a frequency (Hz) */ -#define FREQ1_CMP 1.561098E9 /* BDS B1I frequency (Hz) */ -#define FREQ2_CMP 1.20714E9 /* BDS B2I/B2b frequency (Hz) */ -#define FREQ3_CMP 1.26852E9 /* BDS B3 frequency (Hz) */ - -#define EFACT_GPS 1.0 /* error factor: GPS */ -#define EFACT_GLO 1.5 /* error factor: GLONASS */ -#define EFACT_GAL 1.0 /* error factor: Galileo */ -#define EFACT_QZS 1.0 /* error factor: QZSS */ -#define EFACT_CMP 1.0 /* error factor: BeiDou */ -#define EFACT_IRN 1.5 /* error factor: IRNSS */ -#define EFACT_SBS 3.0 /* error factor: SBAS */ - -#define SYS_NONE 0x00 /* navigation system: none */ -#define SYS_GPS 0x01 /* navigation system: GPS */ -#define SYS_SBS 0x02 /* navigation system: SBAS */ -#define SYS_GLO 0x04 /* navigation system: GLONASS */ -#define SYS_GAL 0x08 /* navigation system: Galileo */ -#define SYS_QZS 0x10 /* navigation system: QZSS */ -#define SYS_CMP 0x20 /* navigation system: BeiDou */ -#define SYS_IRN 0x40 /* navigation system: IRNS */ -#define SYS_LEO 0x80 /* navigation system: LEO */ -#define SYS_ALL 0xFF /* navigation system: all */ +#define VER_RTKLIB "EX" /* library version */ + +#define PATCH_LEVEL "2.5.0" /* patch level */ + +#define COPYRIGHT_RTKLIB "Copyright (C) 2007-2020 T.Takasu\nAll rights reserved." + +#define PI 3.1415926535897932 /* pi */ +#define D2R (PI / 180.0) /* deg to rad */ +#define R2D (180.0 / PI) /* rad to deg */ +#define CLIGHT 299792458.0 /* speed of light (m/s) */ +#define SC2RAD 3.1415926535898 /* semi-circle to radian (IS-GPS) */ +#define AU 149597870691.0 /* 1 AU (m) */ +#define AS2R (D2R / 3600.0) /* arc sec to radian */ + +#define OMGE 7.2921151467E-5 /* earth angular velocity (IS-GPS) (rad/s) */ + +#define RE_WGS84 6378137.0 /* earth semimajor axis (WGS84) (m) */ +#define FE_WGS84 (1.0 / 298.257223563) /* earth flattening (WGS84) */ + +#define HION 350000.0 /* ionosphere height (m) */ + +#define MAXFREQ 6 /* max NFREQ */ + +#define FREQL1 1.57542E9 /* L1/E1 frequency (Hz) */ +#define FREQL2 1.22760E9 /* L2 frequency (Hz) */ +#define FREQE5b 1.20714E9 /* E5b frequency (Hz) */ +#define FREQL5 1.17645E9 /* L5/E5a/B2a frequency (Hz) */ +#define FREQL6 1.27875E9 /* E6/L6 frequency (Hz) */ +#define FREQE5ab 1.191795E9 /* E5a+b frequency (Hz) */ +#define FREQs 2.492028E9 /* S frequency (Hz) */ +#define FREQ1_GLO 1.60200E9 /* GLONASS G1 base frequency (Hz) */ +#define DFRQ1_GLO 0.56250E6 /* GLONASS G1 bias frequency (Hz/n) */ +#define FREQ2_GLO 1.24600E9 /* GLONASS G2 base frequency (Hz) */ +#define DFRQ2_GLO 0.43750E6 /* GLONASS G2 bias frequency (Hz/n) */ +#define FREQ3_GLO 1.202025E9 /* GLONASS G3 frequency (Hz) */ +#define FREQ1a_GLO 1.600995E9 /* GLONASS G1a frequency (Hz) */ +#define FREQ2a_GLO 1.248060E9 /* GLONASS G2a frequency (Hz) */ +#define FREQ1_CMP 1.561098E9 /* BDS B1I frequency (Hz) */ +#define FREQ2_CMP 1.20714E9 /* BDS B2I/B2b frequency (Hz) */ +#define FREQ3_CMP 1.26852E9 /* BDS B3 frequency (Hz) */ + +#define EFACT_GPS 1.0 /* error factor: GPS */ +#define EFACT_GLO 1.5 /* error factor: GLONASS */ +#define EFACT_GAL 1.0 /* error factor: Galileo */ +#define EFACT_QZS 1.0 /* error factor: QZSS */ +#define EFACT_CMP 1.0 /* error factor: BeiDou */ +#define EFACT_IRN 1.5 /* error factor: IRNSS */ +#define EFACT_SBS 3.0 /* error factor: SBAS */ + +#define SYS_NONE 0x00 /* navigation system: none */ +#define SYS_GPS 0x01 /* navigation system: GPS */ +#define SYS_SBS 0x02 /* navigation system: SBAS */ +#define SYS_GLO 0x04 /* navigation system: GLONASS */ +#define SYS_GAL 0x08 /* navigation system: Galileo */ +#define SYS_QZS 0x10 /* navigation system: QZSS */ +#define SYS_CMP 0x20 /* navigation system: BeiDou */ +#define SYS_IRN 0x40 /* navigation system: IRNS */ +#define SYS_LEO 0x80 /* navigation system: LEO */ +#define SYS_ALL 0xFF /* navigation system: all */ /* System codes used in rnxopt_t mask, tobs, shift, and nobs. */ -#define RNX_SYS_GPS 0 /* Navigation system: GPS */ -#define RNX_SYS_GLO 1 /* Navigation system: GLONASS */ -#define RNX_SYS_GAL 2 /* Navigation system: Galileo */ -#define RNX_SYS_QZS 3 /* Navigation system: QZSS */ -#define RNX_SYS_SBS 4 /* Navigation system: SBAS */ -#define RNX_SYS_CMP 5 /* Navigation system: BeiDou */ -#define RNX_SYS_IRN 6 /* Navigation system: IRNS */ -#define RNX_NUMSYS 7 - -#define TSYS_GPS 0 /* time system: GPS time */ -#define TSYS_UTC 1 /* time system: UTC */ -#define TSYS_GLO 2 /* time system: GLONASS time */ -#define TSYS_GAL 3 /* time system: Galileo time */ -#define TSYS_QZS 4 /* time system: QZSS time */ -#define TSYS_CMP 5 /* time system: BeiDou time */ -#define TSYS_IRN 6 /* time system: IRNSS time */ +#define RNX_SYS_GPS 0 /* Navigation system: GPS */ +#define RNX_SYS_GLO 1 /* Navigation system: GLONASS */ +#define RNX_SYS_GAL 2 /* Navigation system: Galileo */ +#define RNX_SYS_QZS 3 /* Navigation system: QZSS */ +#define RNX_SYS_SBS 4 /* Navigation system: SBAS */ +#define RNX_SYS_CMP 5 /* Navigation system: BeiDou */ +#define RNX_SYS_IRN 6 /* Navigation system: IRNS */ +#define RNX_NUMSYS 7 + +#define TSYS_GPS 0 /* time system: GPS time */ +#define TSYS_UTC 1 /* time system: UTC */ +#define TSYS_GLO 2 /* time system: GLONASS time */ +#define TSYS_GAL 3 /* time system: Galileo time */ +#define TSYS_QZS 4 /* time system: QZSS time */ +#define TSYS_CMP 5 /* time system: BeiDou time */ +#define TSYS_IRN 6 /* time system: IRNSS time */ #ifndef NFREQ -#define NFREQ 3 /* number of carrier frequencies */ +#define NFREQ 3 /* number of carrier frequencies */ #endif -#define NFREQGLO 2 /* number of carrier frequencies of GLONASS */ +#define NFREQGLO 2 /* number of carrier frequencies of GLONASS */ #ifndef NEXOBS -#define NEXOBS 0 /* number of extended obs codes */ +#define NEXOBS 0 /* number of extended obs codes */ #endif -#define MINPRNGPS 1 /* min satellite PRN number of GPS */ -#define MAXPRNGPS 32 /* max satellite PRN number of GPS */ -#define NSATGPS (MAXPRNGPS-MINPRNGPS+1) /* number of GPS satellites */ -#define NSYSGPS 1 +#define MINPRNGPS 1 /* min satellite PRN number of GPS */ +#define MAXPRNGPS 32 /* max satellite PRN number of GPS */ +#define NSATGPS (MAXPRNGPS - MINPRNGPS + 1) /* number of GPS satellites */ +#define NSYSGPS 1 #ifdef ENAGLO -#define MINPRNGLO 1 /* min satellite slot number of GLONASS */ -#define MAXPRNGLO 27 /* max satellite slot number of GLONASS */ -#define NSATGLO (MAXPRNGLO-MINPRNGLO+1) /* number of GLONASS satellites */ -#define NSYSGLO 1 +#define MINPRNGLO 1 /* min satellite slot number of GLONASS */ +#define MAXPRNGLO 27 /* max satellite slot number of GLONASS */ +#define NSATGLO (MAXPRNGLO - MINPRNGLO + 1) /* number of GLONASS satellites */ +#define NSYSGLO 1 #else -#define MINPRNGLO 0 -#define MAXPRNGLO 0 -#define NSATGLO 0 -#define NSYSGLO 0 +#define MINPRNGLO 0 +#define MAXPRNGLO 0 +#define NSATGLO 0 +#define NSYSGLO 0 #endif #ifdef ENAGAL -#define MINPRNGAL 1 /* min satellite PRN number of Galileo */ -#define MAXPRNGAL 36 /* max satellite PRN number of Galileo */ -#define NSATGAL (MAXPRNGAL-MINPRNGAL+1) /* number of Galileo satellites */ -#define NSYSGAL 1 +#define MINPRNGAL 1 /* min satellite PRN number of Galileo */ +#define MAXPRNGAL 36 /* max satellite PRN number of Galileo */ +#define NSATGAL (MAXPRNGAL - MINPRNGAL + 1) /* number of Galileo satellites */ +#define NSYSGAL 1 #else -#define MINPRNGAL 0 -#define MAXPRNGAL 0 -#define NSATGAL 0 -#define NSYSGAL 0 +#define MINPRNGAL 0 +#define MAXPRNGAL 0 +#define NSATGAL 0 +#define NSYSGAL 0 #endif #ifdef ENAQZS -#define MINPRNQZS 193 /* min satellite PRN number of QZSS */ -#define MAXPRNQZS 202 /* max satellite PRN number of QZSS */ -#define MINPRNQZS_S 183 /* min satellite PRN number of QZSS L1S */ -#define MAXPRNQZS_S 191 /* max satellite PRN number of QZSS L1S */ -#define NSATQZS (MAXPRNQZS-MINPRNQZS+1) /* number of QZSS satellites */ -#define NSYSQZS 1 +#define MINPRNQZS 193 /* min satellite PRN number of QZSS */ +#define MAXPRNQZS 202 /* max satellite PRN number of QZSS */ +#define MINPRNQZS_S 183 /* min satellite PRN number of QZSS L1S */ +#define MAXPRNQZS_S 191 /* max satellite PRN number of QZSS L1S */ +#define NSATQZS (MAXPRNQZS - MINPRNQZS + 1) /* number of QZSS satellites */ +#define NSYSQZS 1 #else -#define MINPRNQZS 0 -#define MAXPRNQZS 0 +#define MINPRNQZS 0 +#define MAXPRNQZS 0 #define MINPRNQZS_S 0 #define MAXPRNQZS_S 0 -#define NSATQZS 0 -#define NSYSQZS 0 +#define NSATQZS 0 +#define NSYSQZS 0 #endif #ifdef ENACMP -#define MINPRNCMP 1 /* min satellite sat number of BeiDou */ -#define MAXPRNCMP 46 /* max satellite sat number of BeiDou */ -#define NSATCMP (MAXPRNCMP-MINPRNCMP+1) /* number of BeiDou satellites */ -#define NSYSCMP 1 +#define MINPRNCMP 1 /* min satellite sat number of BeiDou */ +#define MAXPRNCMP 46 /* max satellite sat number of BeiDou */ +#define NSATCMP (MAXPRNCMP - MINPRNCMP + 1) /* number of BeiDou satellites */ +#define NSYSCMP 1 #else -#define MINPRNCMP 0 -#define MAXPRNCMP 0 -#define NSATCMP 0 -#define NSYSCMP 0 +#define MINPRNCMP 0 +#define MAXPRNCMP 0 +#define NSATCMP 0 +#define NSYSCMP 0 #endif #ifdef ENAIRN -#define MINPRNIRN 1 /* min satellite sat number of IRNSS */ -#define MAXPRNIRN 14 /* max satellite sat number of IRNSS */ -#define NSATIRN (MAXPRNIRN-MINPRNIRN+1) /* number of IRNSS satellites */ -#define NSYSIRN 1 +#define MINPRNIRN 1 /* min satellite sat number of IRNSS */ +#define MAXPRNIRN 14 /* max satellite sat number of IRNSS */ +#define NSATIRN (MAXPRNIRN - MINPRNIRN + 1) /* number of IRNSS satellites */ +#define NSYSIRN 1 #else -#define MINPRNIRN 0 -#define MAXPRNIRN 0 -#define NSATIRN 0 -#define NSYSIRN 0 +#define MINPRNIRN 0 +#define MAXPRNIRN 0 +#define NSATIRN 0 +#define NSYSIRN 0 #endif #ifdef ENALEO -#define MINPRNLEO 1 /* min satellite sat number of LEO */ -#define MAXPRNLEO 10 /* max satellite sat number of LEO */ -#define NSATLEO (MAXPRNLEO-MINPRNLEO+1) /* number of LEO satellites */ -#define NSYSLEO 1 +#define MINPRNLEO 1 /* min satellite sat number of LEO */ +#define MAXPRNLEO 10 /* max satellite sat number of LEO */ +#define NSATLEO (MAXPRNLEO - MINPRNLEO + 1) /* number of LEO satellites */ +#define NSYSLEO 1 #else -#define MINPRNLEO 0 -#define MAXPRNLEO 0 -#define NSATLEO 0 -#define NSYSLEO 0 +#define MINPRNLEO 0 +#define MAXPRNLEO 0 +#define NSATLEO 0 +#define NSYSLEO 0 #endif -#define NSYS (NSYSGPS+NSYSGLO+NSYSGAL+NSYSQZS+NSYSCMP+NSYSIRN+NSYSLEO) /* number of systems */ +#define NSYS \ + (NSYSGPS + NSYSGLO + NSYSGAL + NSYSQZS + NSYSCMP + NSYSIRN + NSYSLEO) /* number of systems */ -#define MINPRNSBS 120 /* min satellite PRN number of SBAS */ -#define MAXPRNSBS 158 /* max satellite PRN number of SBAS */ -#define NSATSBS (MAXPRNSBS-MINPRNSBS+1) /* number of SBAS satellites */ +#define MINPRNSBS 120 /* min satellite PRN number of SBAS */ +#define MAXPRNSBS 158 /* max satellite PRN number of SBAS */ +#define NSATSBS (MAXPRNSBS - MINPRNSBS + 1) /* number of SBAS satellites */ -#define MAXSAT (NSATGPS+NSATGLO+NSATGAL+NSATQZS+NSATCMP+NSATIRN+NSATSBS+NSATLEO) - /* max satellite number (1 to MAXSAT) */ -#define MAXSTA 255 +#define MAXSAT (NSATGPS + NSATGLO + NSATGAL + NSATQZS + NSATCMP + NSATIRN + NSATSBS + NSATLEO) +/* max satellite number (1 to MAXSAT) */ +#define MAXSTA 255 #ifndef MAXOBS -#define MAXOBS 96 /* max number of obs in an epoch */ +#define MAXOBS 96 /* max number of obs in an epoch */ #endif -#define MAXRCV 64 /* max receiver number (1 to MAXRCV) */ -#define MAXOBSTYPE 64 /* max number of obs type in RINEX */ +#define MAXRCV 64 /* max receiver number (1 to MAXRCV) */ +#define MAXOBSTYPE 64 /* max number of obs type in RINEX */ #ifdef OBS_100HZ -#define DTTOL 0.005 /* tolerance of time difference (s) */ +#define DTTOL 0.005 /* tolerance of time difference (s) */ #else -#define DTTOL 0.025 /* tolerance of time difference (s) */ +#define DTTOL 0.025 /* tolerance of time difference (s) */ #endif -#define MAXDTOE 7200.0 /* max time difference to GPS Toe (s) */ -#define MAXDTOE_QZS 7200.0 /* max time difference to QZSS Toe (s) */ -#define MAXDTOE_GAL 14400.0 /* max time difference to Galileo Toe (s) */ -#define MAXDTOE_CMP 21600.0 /* max time difference to BeiDou Toe (s) */ -#define MAXDTOE_GLO 1800.0 /* max time difference to GLONASS Toe (s) */ -#define MAXDTOE_IRN 7200.0 /* max time difference to IRNSS Toe (s) */ -#define MAXDTOE_SBS 360.0 /* max time difference to SBAS Toe (s) */ -#define MAXDTOE_S 86400.0 /* max time difference to ephem toe (s) for other */ -#define MAXGDOP 300.0 /* max GDOP */ - -#define INT_SWAP_TRAC 86400.0 /* swap interval of trace file (s) */ -#define INT_SWAP_STAT 86400.0 /* swap interval of solution status file (s) */ - -#define MAXEXFILE 1024 /* max number of expanded files */ -#define MAXSBSAGEF 30.0 /* max age of SBAS fast correction (s) */ -#define MAXSBSAGEL 1800.0 /* max age of SBAS long term corr (s) */ -#define MAXSBSURA 8 /* max URA of SBAS satellite */ -#define MAXBAND 10 /* max SBAS band of IGP */ -#define MAXNIGP 201 /* max number of IGP in SBAS band */ -#define MAXNGEO 4 /* max number of GEO satellites */ -#define MAXCOMMENT 100 /* max number of RINEX comments */ -#define MAXSTRPATH 1024 /* max length of stream path */ -#define MAXSTRMSG 1024 /* max length of stream message */ -#define MAXSTRRTK 8 /* max number of stream in RTK server */ -#define MAXSBSMSG 32 /* max number of SBAS msg in RTK server */ -#define MAXSOLLEN 512 /* max line length of solution message */ -#define MAXSOLMSG 32768 /* max length of solution messages */ -#define MAXRAWLEN 16384 /* max length of receiver raw message */ -#define MAXERRMSG 4096 /* max length of error/warning message */ -#define MAXANT 64 /* max length of station name/antenna type */ -#define MAXSOLBUF 256 /* max number of solution buffer */ -#define MAXOBSBUF 128 /* max number of observation data buffer */ -#define MAXNRPOS 16 /* max number of reference positions */ -#define MAXLEAPS 64 /* max number of leap seconds table */ -#define MAXGISLAYER 32 /* max number of GIS data layers */ -#define MAXRCVCMD 4096 /* max length of receiver commands */ -#define MAX_CODE_BIASES 3 /* max # of different code biases per freq */ -#define MAX_CODE_BIAS_FREQS 2 /* max # of freqs supported for code biases */ - -#define RNX2VER 2.10 /* RINEX ver.2 default output version */ -#define RNX3VER 3.00 /* RINEX ver.3 default output version */ - -#define OBSTYPE_PR 0x01 /* observation type: pseudorange */ -#define OBSTYPE_CP 0x02 /* observation type: carrier-phase */ -#define OBSTYPE_DOP 0x04 /* observation type: doppler-freq */ -#define OBSTYPE_SNR 0x08 /* observation type: SNR */ -#define OBSTYPE_ALL 0x0F /* observation type: all */ - -#define FREQTYPE_L1 0x01 /* Frequency type: L1/G1/E1/B1 */ -#define FREQTYPE_L2 0x02 /* Frequency type: L2/G2/E5b/B2 */ -#define FREQTYPE_L3 0x04 /* Frequency type: L5/G3/E5a/B2a */ -#define FREQTYPE_L4 0x08 /* Frequency type: L6/E6/B3 */ -#define FREQTYPE_L5 0x10 /* Frequency type: E5ab/B1C/B1A */ -#define FREQTYPE_L6 0x20 /* Frequency type: B2ab */ -#define FREQTYPE_ALL 0x3F /* Frequency type: all */ - -#define CODE_NONE 0 /* obs code: none or unknown */ -#define CODE_L1C 1 /* obs code: L1C/A,G1C/A,E1C (GPS,GLO,GAL,QZS,SBS) */ -#define CODE_L1P 2 /* obs code: L1P,G1P,B1P (GPS,GLO,BDS) */ -#define CODE_L1W 3 /* obs code: L1 Z-track (GPS) */ -#define CODE_L1Y 4 /* obs code: L1Y (GPS) */ -#define CODE_L1M 5 /* obs code: L1M (GPS) */ -#define CODE_L1N 6 /* obs code: L1codeless,B1codeless (GPS,BDS) */ -#define CODE_L1S 7 /* obs code: L1C(D) (GPS,QZS) */ -#define CODE_L1L 8 /* obs code: L1C(P) (GPS,QZS) */ -#define CODE_L1E 9 /* obs code: L1C/B (QZS) */ -#define CODE_L1A 10 /* obs code: E1A,B1A (GAL,BDS) */ -#define CODE_L1B 11 /* obs code: E1B (GAL) */ -#define CODE_L1X 12 /* obs code: E1B+C,L1C(D+P),B1D+P (GAL,QZS,BDS) */ -#define CODE_L1Z 13 /* obs code: E1A+B+C,L1S (GAL,QZS) */ -#define CODE_L2C 14 /* obs code: L2C/A,G1C/A (GPS,GLO) */ -#define CODE_L2D 15 /* obs code: L2 L1C/A-(P2-P1) (GPS) */ -#define CODE_L2S 16 /* obs code: L2C(M) (GPS,QZS) */ -#define CODE_L2L 17 /* obs code: L2C(L) (GPS,QZS) */ -#define CODE_L2X 18 /* obs code: L2C(M+L),B1_2I+Q (GPS,QZS,BDS) */ -#define CODE_L2P 19 /* obs code: L2P,G2P (GPS,GLO) */ -#define CODE_L2W 20 /* obs code: L2 Z-track (GPS) */ -#define CODE_L2Y 21 /* obs code: L2Y (GPS) */ -#define CODE_L2M 22 /* obs code: L2M (GPS) */ -#define CODE_L2N 23 /* obs code: L2codeless (GPS) */ -#define CODE_L5I 24 /* obs code: L5I,E5aI (GPS,GAL,QZS,SBS) */ -#define CODE_L5Q 25 /* obs code: L5Q,E5aQ (GPS,GAL,QZS,SBS) */ -#define CODE_L5X 26 /* obs code: L5I+Q,E5aI+Q,L5B+C,B2aD+P (GPS,GAL,QZS,IRN,SBS,BDS) */ -#define CODE_L7I 27 /* obs code: E5bI,B2bI (GAL,BDS) */ -#define CODE_L7Q 28 /* obs code: E5bQ,B2bQ (GAL,BDS) */ -#define CODE_L7X 29 /* obs code: E5bI+Q,B2bI+Q (GAL,BDS) */ -#define CODE_L6A 30 /* obs code: E6A,B3A (GAL,BDS) */ -#define CODE_L6B 31 /* obs code: E6B (GAL) */ -#define CODE_L6C 32 /* obs code: E6C (GAL) */ -#define CODE_L6X 33 /* obs code: E6B+C,LEXS+L,B3I+Q (GAL,QZS,BDS) */ -#define CODE_L6Z 34 /* obs code: E6A+B+C,L6D+E (GAL,QZS) */ -#define CODE_L6S 35 /* obs code: L6S (QZS) */ -#define CODE_L6L 36 /* obs code: L6L (QZS) */ -#define CODE_L8I 37 /* obs code: E5abI (GAL) */ -#define CODE_L8Q 38 /* obs code: E5abQ (GAL) */ -#define CODE_L8X 39 /* obs code: E5abI+Q,B2abD+P (GAL,BDS) */ -#define CODE_L2I 40 /* obs code: B1_2I (BDS) */ -#define CODE_L2Q 41 /* obs code: B1_2Q (BDS) */ -#define CODE_L6I 42 /* obs code: B3I (BDS) */ -#define CODE_L6Q 43 /* obs code: B3Q (BDS) */ -#define CODE_L3I 44 /* obs code: G3I (GLO) */ -#define CODE_L3Q 45 /* obs code: G3Q (GLO) */ -#define CODE_L3X 46 /* obs code: G3I+Q (GLO) */ -#define CODE_L1I 47 /* obs code: B1I (BDS) (obsolete) */ -#define CODE_L1Q 48 /* obs code: B1Q (BDS) (obsolete) */ -#define CODE_L5A 49 /* obs code: L5A SPS (IRN) */ -#define CODE_L5B 50 /* obs code: L5B RS(D) (IRN) */ -#define CODE_L5C 51 /* obs code: L5C RS(P) (IRN) */ -#define CODE_L9A 52 /* obs code: SA SPS (IRN) */ -#define CODE_L9B 53 /* obs code: SB RS(D) (IRN) */ -#define CODE_L9C 54 /* obs code: SC RS(P) (IRN) */ -#define CODE_L9X 55 /* obs code: SB+C (IRN) */ -#define CODE_L1D 56 /* obs code: B1D (BDS) */ -#define CODE_L5D 57 /* obs code: L5D(L5S),B2aD (QZS,BDS) */ -#define CODE_L5P 58 /* obs code: L5P(L5S),B2aP (QZS,BDS) */ -#define CODE_L5Z 59 /* obs code: L5D+P(L5S) (QZS) */ -#define CODE_L6E 60 /* obs code: L6E (QZS) */ -#define CODE_L7D 61 /* obs code: B2bD (BDS) */ -#define CODE_L7P 62 /* obs code: B2bP (BDS) */ -#define CODE_L7Z 63 /* obs code: B2bD+P (BDS) */ -#define CODE_L8D 64 /* obs code: B2abD (BDS) */ -#define CODE_L8P 65 /* obs code: B2abP (BDS) */ -#define CODE_L4A 66 /* obs code: G1aL1OCd (GLO) */ -#define CODE_L4B 67 /* obs code: G1aL1OCd (GLO) */ -#define CODE_L4X 68 /* obs code: G1al1OCd+p (GLO) */ -#define CODE_L6D 69 /* obs code: B3A(D) (BDS) */ -#define CODE_L6P 70 /* obs code: B3A(P) (BDS) */ -#define MAXCODE 70 /* max number of obs code */ - -#define PMODE_SINGLE 0 /* positioning mode: single */ -#define PMODE_DGPS 1 /* positioning mode: DGPS/DGNSS */ -#define PMODE_KINEMA 2 /* positioning mode: kinematic */ -#define PMODE_STATIC 3 /* positioning mode: static */ -#define PMODE_STATIC_START 4 /* positioning mode: static */ -#define PMODE_MOVEB 5 /* positioning mode: moving-base */ -#define PMODE_FIXED 6 /* positioning mode: fixed */ -#define PMODE_PPP_KINEMA 7 /* positioning mode: PPP-kinemaric */ -#define PMODE_PPP_STATIC 8 /* positioning mode: PPP-static */ -#define PMODE_PPP_FIXED 9 /* positioning mode: PPP-fixed */ - -#define SOLF_LLH 0 /* solution format: lat/lon/height */ -#define SOLF_XYZ 1 /* solution format: x/y/z-ecef */ -#define SOLF_ENU 2 /* solution format: e/n/u-baseline */ -#define SOLF_NMEA 3 /* solution format: NMEA-183 */ -#define SOLF_STAT 4 /* solution format: solution status */ -#define SOLF_GSIF 5 /* solution format: GSI F1/F2 */ - -#define SOLQ_NONE 0 /* solution status: no solution */ -#define SOLQ_FIX 1 /* solution status: fix */ -#define SOLQ_FLOAT 2 /* solution status: float */ -#define SOLQ_SBAS 3 /* solution status: SBAS */ -#define SOLQ_DGPS 4 /* solution status: DGPS/DGNSS */ -#define SOLQ_SINGLE 5 /* solution status: single */ -#define SOLQ_PPP 6 /* solution status: PPP */ -#define SOLQ_DR 7 /* solution status: dead reckoning */ -#define MAXSOLQ 7 /* max number of solution status */ - -#define SOLTYPE_FORWARD 0 /* solution type: forward */ -#define SOLTYPE_BACKWARD 1 /* solution type: backward */ -#define SOLTYPE_COMBINED 2 /* solution type: combined */ -#define SOLTYPE_COMBINED_NORESET 3 /* solution type: combined no phase reset*/ -#define SOLMODE_SINGLE_DIR 0 /* single direction solution */ -#define SOLMODE_COMBINED 1 /* combined solution */ - -#define TIMES_GPST 0 /* time system: gps time */ -#define TIMES_UTC 1 /* time system: utc */ -#define TIMES_JST 2 /* time system: jst */ - -#define IONOOPT_OFF 0 /* ionosphere option: correction off */ -#define IONOOPT_BRDC 1 /* ionosphere option: broadcast model */ -#define IONOOPT_SBAS 2 /* ionosphere option: SBAS model */ -#define IONOOPT_IFLC 3 /* ionosphere option: L1/L2 or L1/L5 iono-free LC */ -#define IONOOPT_EST 4 /* ionosphere option: estimation */ -#define IONOOPT_TEC 5 /* ionosphere option: IONEX TEC model */ -#define IONOOPT_QZS 6 /* ionosphere option: QZSS broadcast model */ - -#define TROPOPT_OFF 0 /* troposphere option: correction off */ -#define TROPOPT_SAAS 1 /* troposphere option: Saastamoinen model */ -#define TROPOPT_SBAS 2 /* troposphere option: SBAS model */ -#define TROPOPT_EST 3 /* troposphere option: ZTD estimation */ -#define TROPOPT_ESTG 4 /* troposphere option: ZTD+grad estimation */ - -#define EPHOPT_BRDC 0 /* ephemeris option: broadcast ephemeris */ -#define EPHOPT_PREC 1 /* ephemeris option: precise ephemeris */ -#define EPHOPT_SBAS 2 /* ephemeris option: broadcast + SBAS */ -#define EPHOPT_SSRAPC 3 /* ephemeris option: broadcast + SSR_APC */ -#define EPHOPT_SSRCOM 4 /* ephemeris option: broadcast + SSR_COM */ - -#define ARMODE_OFF 0 /* AR mode: off */ -#define ARMODE_CONT 1 /* AR mode: continuous */ -#define ARMODE_INST 2 /* AR mode: instantaneous */ -#define ARMODE_FIXHOLD 3 /* AR mode: fix and hold */ - -#define GLO_ARMODE_OFF 0 /* GLO AR mode: off */ -#define GLO_ARMODE_ON 1 /* GLO AR mode: on */ -#define GLO_ARMODE_AUTOCAL 2 /* GLO AR mode: autocal */ -#define GLO_ARMODE_FIXHOLD 3 /* GLO AR mode: fix and hold */ - -#define SBSOPT_LCORR 1 /* SBAS option: long term correction */ -#define SBSOPT_FCORR 2 /* SBAS option: fast correction */ -#define SBSOPT_ICORR 4 /* SBAS option: ionosphere correction */ -#define SBSOPT_RANGE 8 /* SBAS option: ranging */ - -#define POSOPT_POS_LLH 0 /* pos option: LLH */ -#define POSOPT_POS_XYZ 1 /* pos option: XYZ */ -#define POSOPT_SINGLE 2 /* pos option: average of single pos */ -#define POSOPT_FILE 3 /* pos option: read from pos file */ -#define POSOPT_RINEX 4 /* pos option: rinex header pos */ -#define POSOPT_RTCM 5 /* pos option: rtcm/raw station pos */ - -#define STR_NONE 0 /* stream type: none */ -#define STR_SERIAL 1 /* stream type: serial */ -#define STR_FILE 2 /* stream type: file */ -#define STR_TCPSVR 3 /* stream type: TCP server */ -#define STR_TCPCLI 4 /* stream type: TCP client */ -#define STR_NTRIPSVR 5 /* stream type: NTRIP server */ -#define STR_NTRIPCLI 6 /* stream type: NTRIP client */ -#define STR_FTP 7 /* stream type: ftp */ -#define STR_HTTP 8 /* stream type: http */ -#define STR_NTRIPCAS 9 /* stream type: NTRIP caster */ -#define STR_UDPSVR 10 /* stream type: UDP server */ -#define STR_UDPCLI 11 /* stream type: UDP server */ -#define STR_MEMBUF 12 /* stream type: memory buffer */ - -#define STRFMT_RTCM2 0 /* stream format: RTCM 2 */ -#define STRFMT_RTCM3 1 /* stream format: RTCM 3 */ -#define STRFMT_OEM4 2 /* stream format: NovAtel OEMV/4 */ +#define MAXDTOE 7200.0 /* max time difference to GPS Toe (s) */ +#define MAXDTOE_QZS 7200.0 /* max time difference to QZSS Toe (s) */ +#define MAXDTOE_GAL 14400.0 /* max time difference to Galileo Toe (s) */ +#define MAXDTOE_CMP 21600.0 /* max time difference to BeiDou Toe (s) */ +#define MAXDTOE_GLO 1800.0 /* max time difference to GLONASS Toe (s) */ +#define MAXDTOE_IRN 7200.0 /* max time difference to IRNSS Toe (s) */ +#define MAXDTOE_SBS 360.0 /* max time difference to SBAS Toe (s) */ +#define MAXDTOE_S 86400.0 /* max time difference to ephem toe (s) for other */ +#define MAXGDOP 300.0 /* max GDOP */ + +#define INT_SWAP_TRAC 86400.0 /* swap interval of trace file (s) */ +#define INT_SWAP_STAT 86400.0 /* swap interval of solution status file (s) */ + +#define MAXEXFILE 1024 /* max number of expanded files */ +#define MAXSBSAGEF 30.0 /* max age of SBAS fast correction (s) */ +#define MAXSBSAGEL 1800.0 /* max age of SBAS long term corr (s) */ +#define MAXSBSURA 8 /* max URA of SBAS satellite */ +#define MAXBAND 10 /* max SBAS band of IGP */ +#define MAXNIGP 201 /* max number of IGP in SBAS band */ +#define MAXNGEO 4 /* max number of GEO satellites */ +#define MAXCOMMENT 100 /* max number of RINEX comments */ +#define MAXSTRPATH 1024 /* max length of stream path */ +#define MAXSTRMSG 1024 /* max length of stream message */ +#define MAXSTRRTK 8 /* max number of stream in RTK server */ +#define MAXSBSMSG 32 /* max number of SBAS msg in RTK server */ +#define MAXSOLLEN 512 /* max line length of solution message */ +#define MAXSOLMSG 32768 /* max length of solution messages */ +#define MAXRAWLEN 16384 /* max length of receiver raw message */ +#define MAXERRMSG 4096 /* max length of error/warning message */ +#define MAXANT 64 /* max length of station name/antenna type */ +#define MAXSOLBUF 256 /* max number of solution buffer */ +#define MAXOBSBUF 128 /* max number of observation data buffer */ +#define MAXNRPOS 16 /* max number of reference positions */ +#define MAXLEAPS 64 /* max number of leap seconds table */ +#define MAXGISLAYER 32 /* max number of GIS data layers */ +#define MAXRCVCMD 4096 /* max length of receiver commands */ +#define MAX_CODE_BIASES 3 /* max # of different code biases per freq */ +#define MAX_CODE_BIAS_FREQS 2 /* max # of freqs supported for code biases */ + +#define RNX2VER 2.10 /* RINEX ver.2 default output version */ +#define RNX3VER 3.00 /* RINEX ver.3 default output version */ + +#define OBSTYPE_PR 0x01 /* observation type: pseudorange */ +#define OBSTYPE_CP 0x02 /* observation type: carrier-phase */ +#define OBSTYPE_DOP 0x04 /* observation type: doppler-freq */ +#define OBSTYPE_SNR 0x08 /* observation type: SNR */ +#define OBSTYPE_ALL 0x0F /* observation type: all */ + +#define FREQTYPE_L1 0x01 /* Frequency type: L1/G1/E1/B1 */ +#define FREQTYPE_L2 0x02 /* Frequency type: L2/G2/E5b/B2 */ +#define FREQTYPE_L3 0x04 /* Frequency type: L5/G3/E5a/B2a */ +#define FREQTYPE_L4 0x08 /* Frequency type: L6/E6/B3 */ +#define FREQTYPE_L5 0x10 /* Frequency type: E5ab/B1C/B1A */ +#define FREQTYPE_L6 0x20 /* Frequency type: B2ab */ +#define FREQTYPE_ALL 0x3F /* Frequency type: all */ + +#define CODE_NONE 0 /* obs code: none or unknown */ +#define CODE_L1C 1 /* obs code: L1C/A,G1C/A,E1C (GPS,GLO,GAL,QZS,SBS) */ +#define CODE_L1P 2 /* obs code: L1P,G1P,B1P (GPS,GLO,BDS) */ +#define CODE_L1W 3 /* obs code: L1 Z-track (GPS) */ +#define CODE_L1Y 4 /* obs code: L1Y (GPS) */ +#define CODE_L1M 5 /* obs code: L1M (GPS) */ +#define CODE_L1N 6 /* obs code: L1codeless,B1codeless (GPS,BDS) */ +#define CODE_L1S 7 /* obs code: L1C(D) (GPS,QZS) */ +#define CODE_L1L 8 /* obs code: L1C(P) (GPS,QZS) */ +#define CODE_L1E 9 /* obs code: L1C/B (QZS) */ +#define CODE_L1A 10 /* obs code: E1A,B1A (GAL,BDS) */ +#define CODE_L1B 11 /* obs code: E1B (GAL) */ +#define CODE_L1X 12 /* obs code: E1B+C,L1C(D+P),B1D+P (GAL,QZS,BDS) */ +#define CODE_L1Z 13 /* obs code: E1A+B+C,L1S (GAL,QZS) */ +#define CODE_L2C 14 /* obs code: L2C/A,G1C/A (GPS,GLO) */ +#define CODE_L2D 15 /* obs code: L2 L1C/A-(P2-P1) (GPS) */ +#define CODE_L2S 16 /* obs code: L2C(M) (GPS,QZS) */ +#define CODE_L2L 17 /* obs code: L2C(L) (GPS,QZS) */ +#define CODE_L2X 18 /* obs code: L2C(M+L),B1_2I+Q (GPS,QZS,BDS) */ +#define CODE_L2P 19 /* obs code: L2P,G2P (GPS,GLO) */ +#define CODE_L2W 20 /* obs code: L2 Z-track (GPS) */ +#define CODE_L2Y 21 /* obs code: L2Y (GPS) */ +#define CODE_L2M 22 /* obs code: L2M (GPS) */ +#define CODE_L2N 23 /* obs code: L2codeless (GPS) */ +#define CODE_L5I 24 /* obs code: L5I,E5aI (GPS,GAL,QZS,SBS) */ +#define CODE_L5Q 25 /* obs code: L5Q,E5aQ (GPS,GAL,QZS,SBS) */ +#define CODE_L5X 26 /* obs code: L5I+Q,E5aI+Q,L5B+C,B2aD+P (GPS,GAL,QZS,IRN,SBS,BDS) */ +#define CODE_L7I 27 /* obs code: E5bI,B2bI (GAL,BDS) */ +#define CODE_L7Q 28 /* obs code: E5bQ,B2bQ (GAL,BDS) */ +#define CODE_L7X 29 /* obs code: E5bI+Q,B2bI+Q (GAL,BDS) */ +#define CODE_L6A 30 /* obs code: E6A,B3A (GAL,BDS) */ +#define CODE_L6B 31 /* obs code: E6B (GAL) */ +#define CODE_L6C 32 /* obs code: E6C (GAL) */ +#define CODE_L6X 33 /* obs code: E6B+C,LEXS+L,B3I+Q (GAL,QZS,BDS) */ +#define CODE_L6Z 34 /* obs code: E6A+B+C,L6D+E (GAL,QZS) */ +#define CODE_L6S 35 /* obs code: L6S (QZS) */ +#define CODE_L6L 36 /* obs code: L6L (QZS) */ +#define CODE_L8I 37 /* obs code: E5abI (GAL) */ +#define CODE_L8Q 38 /* obs code: E5abQ (GAL) */ +#define CODE_L8X 39 /* obs code: E5abI+Q,B2abD+P (GAL,BDS) */ +#define CODE_L2I 40 /* obs code: B1_2I (BDS) */ +#define CODE_L2Q 41 /* obs code: B1_2Q (BDS) */ +#define CODE_L6I 42 /* obs code: B3I (BDS) */ +#define CODE_L6Q 43 /* obs code: B3Q (BDS) */ +#define CODE_L3I 44 /* obs code: G3I (GLO) */ +#define CODE_L3Q 45 /* obs code: G3Q (GLO) */ +#define CODE_L3X 46 /* obs code: G3I+Q (GLO) */ +#define CODE_L1I 47 /* obs code: B1I (BDS) (obsolete) */ +#define CODE_L1Q 48 /* obs code: B1Q (BDS) (obsolete) */ +#define CODE_L5A 49 /* obs code: L5A SPS (IRN) */ +#define CODE_L5B 50 /* obs code: L5B RS(D) (IRN) */ +#define CODE_L5C 51 /* obs code: L5C RS(P) (IRN) */ +#define CODE_L9A 52 /* obs code: SA SPS (IRN) */ +#define CODE_L9B 53 /* obs code: SB RS(D) (IRN) */ +#define CODE_L9C 54 /* obs code: SC RS(P) (IRN) */ +#define CODE_L9X 55 /* obs code: SB+C (IRN) */ +#define CODE_L1D 56 /* obs code: B1D (BDS) */ +#define CODE_L5D 57 /* obs code: L5D(L5S),B2aD (QZS,BDS) */ +#define CODE_L5P 58 /* obs code: L5P(L5S),B2aP (QZS,BDS) */ +#define CODE_L5Z 59 /* obs code: L5D+P(L5S) (QZS) */ +#define CODE_L6E 60 /* obs code: L6E (QZS) */ +#define CODE_L7D 61 /* obs code: B2bD (BDS) */ +#define CODE_L7P 62 /* obs code: B2bP (BDS) */ +#define CODE_L7Z 63 /* obs code: B2bD+P (BDS) */ +#define CODE_L8D 64 /* obs code: B2abD (BDS) */ +#define CODE_L8P 65 /* obs code: B2abP (BDS) */ +#define CODE_L4A 66 /* obs code: G1aL1OCd (GLO) */ +#define CODE_L4B 67 /* obs code: G1aL1OCd (GLO) */ +#define CODE_L4X 68 /* obs code: G1al1OCd+p (GLO) */ +#define CODE_L6D 69 /* obs code: B3A(D) (BDS) */ +#define CODE_L6P 70 /* obs code: B3A(P) (BDS) */ +#define MAXCODE 70 /* max number of obs code */ + +#define PMODE_SINGLE 0 /* positioning mode: single */ +#define PMODE_DGPS 1 /* positioning mode: DGPS/DGNSS */ +#define PMODE_KINEMA 2 /* positioning mode: kinematic */ +#define PMODE_STATIC 3 /* positioning mode: static */ +#define PMODE_STATIC_START 4 /* positioning mode: static */ +#define PMODE_MOVEB 5 /* positioning mode: moving-base */ +#define PMODE_FIXED 6 /* positioning mode: fixed */ +#define PMODE_PPP_KINEMA 7 /* positioning mode: PPP-kinemaric */ +#define PMODE_PPP_STATIC 8 /* positioning mode: PPP-static */ +#define PMODE_PPP_FIXED 9 /* positioning mode: PPP-fixed */ + +#define SOLF_LLH 0 /* solution format: lat/lon/height */ +#define SOLF_XYZ 1 /* solution format: x/y/z-ecef */ +#define SOLF_ENU 2 /* solution format: e/n/u-baseline */ +#define SOLF_NMEA 3 /* solution format: NMEA-183 */ +#define SOLF_STAT 4 /* solution format: solution status */ +#define SOLF_GSIF 5 /* solution format: GSI F1/F2 */ + +#define SOLQ_NONE 0 /* solution status: no solution */ +#define SOLQ_FIX 1 /* solution status: fix */ +#define SOLQ_FLOAT 2 /* solution status: float */ +#define SOLQ_SBAS 3 /* solution status: SBAS */ +#define SOLQ_DGPS 4 /* solution status: DGPS/DGNSS */ +#define SOLQ_SINGLE 5 /* solution status: single */ +#define SOLQ_PPP 6 /* solution status: PPP */ +#define SOLQ_DR 7 /* solution status: dead reckoning */ +#define MAXSOLQ 7 /* max number of solution status */ + +#define SOLTYPE_FORWARD 0 /* solution type: forward */ +#define SOLTYPE_BACKWARD 1 /* solution type: backward */ +#define SOLTYPE_COMBINED 2 /* solution type: combined */ +#define SOLTYPE_COMBINED_NORESET 3 /* solution type: combined no phase reset*/ +#define SOLMODE_SINGLE_DIR 0 /* single direction solution */ +#define SOLMODE_COMBINED 1 /* combined solution */ + +#define TIMES_GPST 0 /* time system: gps time */ +#define TIMES_UTC 1 /* time system: utc */ +#define TIMES_JST 2 /* time system: jst */ + +#define IONOOPT_OFF 0 /* ionosphere option: correction off */ +#define IONOOPT_BRDC 1 /* ionosphere option: broadcast model */ +#define IONOOPT_SBAS 2 /* ionosphere option: SBAS model */ +#define IONOOPT_IFLC 3 /* ionosphere option: L1/L2 or L1/L5 iono-free LC */ +#define IONOOPT_EST 4 /* ionosphere option: estimation */ +#define IONOOPT_TEC 5 /* ionosphere option: IONEX TEC model */ +#define IONOOPT_QZS 6 /* ionosphere option: QZSS broadcast model */ + +#define TROPOPT_OFF 0 /* troposphere option: correction off */ +#define TROPOPT_SAAS 1 /* troposphere option: Saastamoinen model */ +#define TROPOPT_SBAS 2 /* troposphere option: SBAS model */ +#define TROPOPT_EST 3 /* troposphere option: ZTD estimation */ +#define TROPOPT_ESTG 4 /* troposphere option: ZTD+grad estimation */ + +#define EPHOPT_BRDC 0 /* ephemeris option: broadcast ephemeris */ +#define EPHOPT_PREC 1 /* ephemeris option: precise ephemeris */ +#define EPHOPT_SBAS 2 /* ephemeris option: broadcast + SBAS */ +#define EPHOPT_SSRAPC 3 /* ephemeris option: broadcast + SSR_APC */ +#define EPHOPT_SSRCOM 4 /* ephemeris option: broadcast + SSR_COM */ + +#define ARMODE_OFF 0 /* AR mode: off */ +#define ARMODE_CONT 1 /* AR mode: continuous */ +#define ARMODE_INST 2 /* AR mode: instantaneous */ +#define ARMODE_FIXHOLD 3 /* AR mode: fix and hold */ + +#define GLO_ARMODE_OFF 0 /* GLO AR mode: off */ +#define GLO_ARMODE_ON 1 /* GLO AR mode: on */ +#define GLO_ARMODE_AUTOCAL 2 /* GLO AR mode: autocal */ +#define GLO_ARMODE_FIXHOLD 3 /* GLO AR mode: fix and hold */ + +#define SBSOPT_LCORR 1 /* SBAS option: long term correction */ +#define SBSOPT_FCORR 2 /* SBAS option: fast correction */ +#define SBSOPT_ICORR 4 /* SBAS option: ionosphere correction */ +#define SBSOPT_RANGE 8 /* SBAS option: ranging */ + +#define POSOPT_POS_LLH 0 /* pos option: LLH */ +#define POSOPT_POS_XYZ 1 /* pos option: XYZ */ +#define POSOPT_SINGLE 2 /* pos option: average of single pos */ +#define POSOPT_FILE 3 /* pos option: read from pos file */ +#define POSOPT_RINEX 4 /* pos option: rinex header pos */ +#define POSOPT_RTCM 5 /* pos option: rtcm/raw station pos */ + +#define STR_NONE 0 /* stream type: none */ +#define STR_SERIAL 1 /* stream type: serial */ +#define STR_FILE 2 /* stream type: file */ +#define STR_TCPSVR 3 /* stream type: TCP server */ +#define STR_TCPCLI 4 /* stream type: TCP client */ +#define STR_NTRIPSVR 5 /* stream type: NTRIP server */ +#define STR_NTRIPCLI 6 /* stream type: NTRIP client */ +#define STR_FTP 7 /* stream type: ftp */ +#define STR_HTTP 8 /* stream type: http */ +#define STR_NTRIPCAS 9 /* stream type: NTRIP caster */ +#define STR_UDPSVR 10 /* stream type: UDP server */ +#define STR_UDPCLI 11 /* stream type: UDP server */ +#define STR_MEMBUF 12 /* stream type: memory buffer */ + +#define STRFMT_RTCM2 0 /* stream format: RTCM 2 */ +#define STRFMT_RTCM3 1 /* stream format: RTCM 3 */ +#define STRFMT_OEM4 2 /* stream format: NovAtel OEMV/4 */ /* Comnav currently not supported */ -/* #define STRFMT_CNAV 3 */ /* stream format: ComNav */ -#define STRFMT_UBX 4 /* stream format: u-blox LEA-*T */ -#define STRFMT_SBP 5 /* stream format: Swift Navigation SBP */ -#define STRFMT_CRES 6 /* stream format: Hemisphere */ -#define STRFMT_STQ 7 /* stream format: SkyTraq S1315F */ -#define STRFMT_JAVAD 8 /* stream format: JAVAD GRIL/GREIS */ -#define STRFMT_NVS 9 /* stream format: NVS NVC08C */ -#define STRFMT_BINEX 10 /* stream format: BINEX */ -#define STRFMT_RT17 11 /* stream format: Trimble RT17 */ -#define STRFMT_SEPT 12 /* stream format: Septentrio */ +/* #define STRFMT_CNAV 3 */ /* stream format: ComNav */ +#define STRFMT_UBX 4 /* stream format: u-blox LEA-*T */ +#define STRFMT_SBP 5 /* stream format: Swift Navigation SBP */ +#define STRFMT_CRES 6 /* stream format: Hemisphere */ +#define STRFMT_STQ 7 /* stream format: SkyTraq S1315F */ +#define STRFMT_JAVAD 8 /* stream format: JAVAD GRIL/GREIS */ +#define STRFMT_NVS 9 /* stream format: NVS NVC08C */ +#define STRFMT_BINEX 10 /* stream format: BINEX */ +#define STRFMT_RT17 11 /* stream format: Trimble RT17 */ +#define STRFMT_SEPT 12 /* stream format: Septentrio */ /* Tersus currently not supported */ -/* #define STRFMT_TERSUS 13 */ /* stream format: TERSUS */ -#define STRFMT_UNICORE 14 /* stream format: UNICORE */ -#define STRFMT_RINEX 15 /* stream format: RINEX */ -#define STRFMT_SP3 16 /* stream format: SP3 */ -#define STRFMT_RNXCLK 17 /* stream format: RINEX CLK */ -#define STRFMT_SBAS 18 /* stream format: SBAS messages */ -#define STRFMT_NMEA 19 /* stream format: NMEA 0183 */ -#define MAXRCVFMT 14 /* max number of receiver format */ - -#define STR_MODE_R 0x1 /* stream mode: read */ -#define STR_MODE_W 0x2 /* stream mode: write */ -#define STR_MODE_RW 0x3 /* stream mode: read/write */ - -#define GEOID_EMBEDDED 0 /* geoid model: embedded geoid */ -#define GEOID_EGM96_M150 1 /* geoid model: EGM96 15x15" */ -#define GEOID_EGM2008_M25 2 /* geoid model: EGM2008 2.5x2.5" */ -#define GEOID_EGM2008_M10 3 /* geoid model: EGM2008 1.0x1.0" */ -#define GEOID_GSI2000_M15 4 /* geoid model: GSI geoid 2000 1.0x1.5" */ -#define GEOID_RAF09 5 /* geoid model: IGN RAF09 for France 1.5"x2" */ - -#define COMMENTH "%" /* comment line indicator for solution */ -#define MSG_DISCONN "$_DISCONNECT\r\n" /* disconnect message */ - -#define DLOPT_FORCE 0x01 /* download option: force download existing */ -#define DLOPT_KEEPCMP 0x02 /* download option: keep compressed file */ -#define DLOPT_HOLDERR 0x04 /* download option: hold on error file */ -#define DLOPT_HOLDLST 0x08 /* download option: hold on listing file */ - -#define LLI_SLIP 0x01 /* LLI: cycle-slip */ -#define LLI_HALFC 0x02 /* LLI: half-cycle not resolved */ -#define LLI_BOCTRK 0x04 /* LLI: boc tracking of mboc signal */ -#define LLI_HALFA 0x40 /* LLI: half-cycle added */ -#define LLI_HALFS 0x80 /* LLI: half-cycle subtracted */ - -#define P2_5 0.03125 /* 2^-5 */ -#define P2_6 0.015625 /* 2^-6 */ -#define P2_11 4.882812500000000E-04 /* 2^-11 */ -#define P2_15 3.051757812500000E-05 /* 2^-15 */ -#define P2_17 7.629394531250000E-06 /* 2^-17 */ -#define P2_19 1.907348632812500E-06 /* 2^-19 */ -#define P2_20 9.536743164062500E-07 /* 2^-20 */ -#define P2_21 4.768371582031250E-07 /* 2^-21 */ -#define P2_23 1.192092895507810E-07 /* 2^-23 */ -#define P2_24 5.960464477539063E-08 /* 2^-24 */ -#define P2_27 7.450580596923828E-09 /* 2^-27 */ -#define P2_29 1.862645149230957E-09 /* 2^-29 */ -#define P2_30 9.313225746154785E-10 /* 2^-30 */ -#define P2_31 4.656612873077393E-10 /* 2^-31 */ -#define P2_32 2.328306436538696E-10 /* 2^-32 */ -#define P2_33 1.164153218269348E-10 /* 2^-33 */ -#define P2_35 2.910383045673370E-11 /* 2^-35 */ -#define P2_38 3.637978807091710E-12 /* 2^-38 */ -#define P2_39 1.818989403545856E-12 /* 2^-39 */ -#define P2_40 9.094947017729280E-13 /* 2^-40 */ -#define P2_43 1.136868377216160E-13 /* 2^-43 */ -#define P2_48 3.552713678800501E-15 /* 2^-48 */ -#define P2_50 8.881784197001252E-16 /* 2^-50 */ -#define P2_55 2.775557561562891E-17 /* 2^-55 */ +/* #define STRFMT_TERSUS 13 */ /* stream format: TERSUS */ +#define STRFMT_UNICORE 14 /* stream format: UNICORE */ +#define STRFMT_RINEX 15 /* stream format: RINEX */ +#define STRFMT_SP3 16 /* stream format: SP3 */ +#define STRFMT_RNXCLK 17 /* stream format: RINEX CLK */ +#define STRFMT_SBAS 18 /* stream format: SBAS messages */ +#define STRFMT_NMEA 19 /* stream format: NMEA 0183 */ +#define MAXRCVFMT 14 /* max number of receiver format */ + +#define STR_MODE_R 0x1 /* stream mode: read */ +#define STR_MODE_W 0x2 /* stream mode: write */ +#define STR_MODE_RW 0x3 /* stream mode: read/write */ + +#define GEOID_EMBEDDED 0 /* geoid model: embedded geoid */ +#define GEOID_EGM96_M150 1 /* geoid model: EGM96 15x15" */ +#define GEOID_EGM2008_M25 2 /* geoid model: EGM2008 2.5x2.5" */ +#define GEOID_EGM2008_M10 3 /* geoid model: EGM2008 1.0x1.0" */ +#define GEOID_GSI2000_M15 4 /* geoid model: GSI geoid 2000 1.0x1.5" */ +#define GEOID_RAF09 5 /* geoid model: IGN RAF09 for France 1.5"x2" */ + +#define COMMENTH "%" /* comment line indicator for solution */ +#define MSG_DISCONN "$_DISCONNECT\r\n" /* disconnect message */ + +#define DLOPT_FORCE 0x01 /* download option: force download existing */ +#define DLOPT_KEEPCMP 0x02 /* download option: keep compressed file */ +#define DLOPT_HOLDERR 0x04 /* download option: hold on error file */ +#define DLOPT_HOLDLST 0x08 /* download option: hold on listing file */ + +#define LLI_SLIP 0x01 /* LLI: cycle-slip */ +#define LLI_HALFC 0x02 /* LLI: half-cycle not resolved */ +#define LLI_BOCTRK 0x04 /* LLI: boc tracking of mboc signal */ +#define LLI_HALFA 0x40 /* LLI: half-cycle added */ +#define LLI_HALFS 0x80 /* LLI: half-cycle subtracted */ + +#define P2_5 0.03125 /* 2^-5 */ +#define P2_6 0.015625 /* 2^-6 */ +#define P2_11 4.882812500000000E-04 /* 2^-11 */ +#define P2_15 3.051757812500000E-05 /* 2^-15 */ +#define P2_17 7.629394531250000E-06 /* 2^-17 */ +#define P2_19 1.907348632812500E-06 /* 2^-19 */ +#define P2_20 9.536743164062500E-07 /* 2^-20 */ +#define P2_21 4.768371582031250E-07 /* 2^-21 */ +#define P2_23 1.192092895507810E-07 /* 2^-23 */ +#define P2_24 5.960464477539063E-08 /* 2^-24 */ +#define P2_27 7.450580596923828E-09 /* 2^-27 */ +#define P2_29 1.862645149230957E-09 /* 2^-29 */ +#define P2_30 9.313225746154785E-10 /* 2^-30 */ +#define P2_31 4.656612873077393E-10 /* 2^-31 */ +#define P2_32 2.328306436538696E-10 /* 2^-32 */ +#define P2_33 1.164153218269348E-10 /* 2^-33 */ +#define P2_35 2.910383045673370E-11 /* 2^-35 */ +#define P2_38 3.637978807091710E-12 /* 2^-38 */ +#define P2_39 1.818989403545856E-12 /* 2^-39 */ +#define P2_40 9.094947017729280E-13 /* 2^-40 */ +#define P2_43 1.136868377216160E-13 /* 2^-43 */ +#define P2_48 3.552713678800501E-15 /* 2^-48 */ +#define P2_50 8.881784197001252E-16 /* 2^-50 */ +#define P2_55 2.775557561562891E-17 /* 2^-55 */ #ifdef WIN32 -#define rtklib_thread_t HANDLE -#define rtklib_lock_t CRITICAL_SECTION +#define rtklib_thread_t HANDLE +#define rtklib_lock_t CRITICAL_SECTION #define rtklib_initlock(f) InitializeCriticalSection(f) -#define rtklib_lock(f) EnterCriticalSection(f) -#define rtklib_unlock(f) LeaveCriticalSection(f) +#define rtklib_lock(f) EnterCriticalSection(f) +#define rtklib_unlock(f) LeaveCriticalSection(f) #define RTKLIB_FILEPATHSEP '\\' /* strtok_r not supported in Windows */ -#define strtok_r(str,delim,ptr) strtok(str,delim) +#define strtok_r(str, delim, ptr) strtok(str, delim) #else -#define rtklib_thread_t pthread_t -#define rtklib_lock_t pthread_mutex_t -#define rtklib_initlock(f) pthread_mutex_init(f,NULL) -#define rtklib_lock(f) pthread_mutex_lock(f) -#define rtklib_unlock(f) pthread_mutex_unlock(f) +#define rtklib_thread_t pthread_t +#define rtklib_lock_t pthread_mutex_t +#define rtklib_initlock(f) pthread_mutex_init(f, NULL) +#define rtklib_lock(f) pthread_mutex_lock(f) +#define rtklib_unlock(f) pthread_mutex_unlock(f) #define RTKLIB_FILEPATHSEP '/' #endif /* type definitions ----------------------------------------------------------*/ -typedef struct { /* time struct */ - time_t time; /* time (s) expressed by standard time_t */ - double sec; /* fraction of second under 1 s */ +typedef struct { /* time struct */ + time_t time; /* time (s) expressed by standard time_t */ + double sec; /* fraction of second under 1 s */ } gtime_t; -typedef struct { /* observation data record */ - gtime_t time; /* receiver sampling time (GPST) */ - uint8_t sat,rcv; /* satellite/receiver number */ - uint8_t freq; /* GLONASS frequency channel (0-13) */ - uint8_t LLI[NFREQ+NEXOBS]; /* loss of lock indicator */ - uint8_t code[NFREQ+NEXOBS]; /* code indicator (CODE_???) */ - double L[NFREQ+NEXOBS]; /* observation data carrier-phase (cycle) */ - double P[NFREQ+NEXOBS]; /* observation data pseudorange (m) */ - float D[NFREQ+NEXOBS]; /* observation data doppler frequency (Hz) */ - float SNR[NFREQ+NEXOBS]; /* signal strength (dBHz) */ - float Lstd[NFREQ+NEXOBS]; /* stdev of carrier phase (cycles) */ - float Pstd[NFREQ+NEXOBS]; /* stdev of pseudorange (meters) */ - - int timevalid; /* time is valid (Valid GNSS fix) for time mark */ - gtime_t eventime; /* time of event (GPST) */ +typedef struct { /* observation data record */ + gtime_t time; /* receiver sampling time (GPST) */ + uint8_t sat, rcv; /* satellite/receiver number */ + uint8_t freq; /* GLONASS frequency channel (0-13) */ + uint8_t LLI[NFREQ + NEXOBS]; /* loss of lock indicator */ + uint8_t code[NFREQ + NEXOBS]; /* code indicator (CODE_???) */ + double L[NFREQ + NEXOBS]; /* observation data carrier-phase (cycle) */ + double P[NFREQ + NEXOBS]; /* observation data pseudorange (m) */ + float D[NFREQ + NEXOBS]; /* observation data doppler frequency (Hz) */ + float SNR[NFREQ + NEXOBS]; /* signal strength (dBHz) */ + float Lstd[NFREQ + NEXOBS]; /* stdev of carrier phase (cycles) */ + float Pstd[NFREQ + NEXOBS]; /* stdev of pseudorange (meters) */ + + int timevalid; /* time is valid (Valid GNSS fix) for time mark */ + gtime_t eventime; /* time of event (GPST) */ } obsd_t; -typedef struct { /* observation data */ - int n,nmax; /* number of observation data/allocated */ - int flag; /* epoch flag (0:ok,1:power failure,>1:event flag) */ - int rcvcount; /* count of rcv event */ - int tmcount; /* time mark count */ - obsd_t *data; /* observation data records */ +typedef struct { /* observation data */ + int n, nmax; /* number of observation data/allocated */ + int flag; /* epoch flag (0:ok,1:power failure,>1:event flag) */ + int rcvcount; /* count of rcv event */ + int tmcount; /* time mark count */ + obsd_t *data; /* observation data records */ } obs_t; -typedef struct { /* earth rotation parameter data type */ - double mjd; /* mjd (days) */ - double xp,yp; /* pole offset (rad) */ - double xpr,ypr; /* pole offset rate (rad/day) */ - double ut1_utc; /* ut1-utc (s) */ - double lod; /* length of day (s/day) */ +typedef struct { /* earth rotation parameter data type */ + double mjd; /* mjd (days) */ + double xp, yp; /* pole offset (rad) */ + double xpr, ypr; /* pole offset rate (rad/day) */ + double ut1_utc; /* ut1-utc (s) */ + double lod; /* length of day (s/day) */ } erpd_t; -typedef struct { /* earth rotation parameter type */ - int n,nmax; /* number and max number of data */ - erpd_t *data; /* earth rotation parameter data */ +typedef struct { /* earth rotation parameter type */ + int n, nmax; /* number and max number of data */ + erpd_t *data; /* earth rotation parameter data */ } erp_t; -typedef struct { /* antenna parameter type */ - int sat; /* satellite number (0:receiver) */ - char type[MAXANT]; /* antenna type */ - char code[MAXANT]; /* serial number or satellite code */ - gtime_t ts,te; /* valid time start and end */ - double off[NFREQ][ 3]; /* phase center offset e/n/u or x/y/z (m) */ - double var[NFREQ][19]; /* phase center variation (m) */ - /* el=90,85,...,0 or nadir=0,1,2,3,... (deg) */ +typedef struct { /* antenna parameter type */ + int sat; /* satellite number (0:receiver) */ + char type[MAXANT]; /* antenna type */ + char code[MAXANT]; /* serial number or satellite code */ + gtime_t ts, te; /* valid time start and end */ + double off[NFREQ][3]; /* phase center offset e/n/u or x/y/z (m) */ + double var[NFREQ][19]; /* phase center variation (m) */ + /* el=90,85,...,0 or nadir=0,1,2,3,... (deg) */ } pcv_t; -typedef struct { /* antenna parameters type */ - int n,nmax; /* number of data/allocated */ - pcv_t *pcv; /* antenna parameters data */ +typedef struct { /* antenna parameters type */ + int n, nmax; /* number of data/allocated */ + pcv_t *pcv; /* antenna parameters data */ } pcvs_t; -typedef struct { /* almanac type */ - int sat; /* satellite number */ - int svh; /* sv health (0:ok) */ - int svconf; /* as and sv config */ - int week; /* GPS/QZS: gps week, GAL: galileo week */ - gtime_t toa; /* Toa */ - /* SV orbit parameters */ - double A,e,i0,OMG0,omg,M0,OMGd; - double toas; /* Toa (s) in week */ - double f0,f1; /* SV clock parameters (af0,af1) */ +typedef struct { /* almanac type */ + int sat; /* satellite number */ + int svh; /* sv health (0:ok) */ + int svconf; /* as and sv config */ + int week; /* GPS/QZS: gps week, GAL: galileo week */ + gtime_t toa; /* Toa */ + /* SV orbit parameters */ + double A, e, i0, OMG0, omg, M0, OMGd; + double toas; /* Toa (s) in week */ + double f0, f1; /* SV clock parameters (af0,af1) */ } alm_t; -typedef struct { /* GPS/QZS/GAL broadcast ephemeris type */ - int sat; /* satellite number */ - int iode,iodc; /* IODE,IODC */ - int sva; /* SV accuracy (URA index) */ - int svh; /* SV health (0:ok) */ - int week; /* GPS/QZS: gps week, GAL: galileo week */ - int code; /* GPS/QZS: code on L2 */ - /* GAL: data source defined as rinex 3.03 */ - /* BDS: data source (0:unknown,1:B1I,2:B1Q,3:B2I,4:B2Q,5:B3I,6:B3Q) */ - int flag; /* GPS/QZS: L2 P data flag */ - /* BDS: nav type (0:unknown,1:IGSO/MEO,2:GEO) */ - gtime_t toe,toc,ttr; /* Toe,Toc,T_trans */ - /* SV orbit parameters */ - double A,e,i0,OMG0,omg,M0,deln,OMGd,idot; - double crc,crs,cuc,cus,cic,cis; - double toes; /* Toe (s) in week */ - double fit; /* fit interval (h) */ - double f0,f1,f2; /* SV clock parameters (af0,af1,af2) */ - double tgd[6]; /* group delay parameters */ - /* GPS/QZS:tgd[0]=TGD */ - /* GAL:tgd[0]=BGD_E1E5a,tgd[1]=BGD_E1E5b */ - /* CMP:tgd[0]=TGD_B1I ,tgd[1]=TGD_B2I/B2b,tgd[2]=TGD_B1Cp */ - /* tgd[3]=TGD_B2ap,tgd[4]=ISC_B1Cd ,tgd[5]=ISC_B2ad */ - double Adot,ndot; /* Adot,ndot for CNAV */ +typedef struct { /* GPS/QZS/GAL broadcast ephemeris type */ + int sat; /* satellite number */ + int iode, iodc; /* IODE,IODC */ + int sva; /* SV accuracy (URA index) */ + int svh; /* SV health (0:ok) */ + int week; /* GPS/QZS: gps week, GAL: galileo week */ + int code; /* GPS/QZS: code on L2 */ + /* GAL: data source defined as rinex 3.03 */ + /* BDS: data source (0:unknown,1:B1I,2:B1Q,3:B2I,4:B2Q,5:B3I,6:B3Q) */ + int flag; /* GPS/QZS: L2 P data flag */ + /* BDS: nav type (0:unknown,1:IGSO/MEO,2:GEO) */ + gtime_t toe, toc, ttr; /* Toe,Toc,T_trans */ + /* SV orbit parameters */ + double A, e, i0, OMG0, omg, M0, deln, OMGd, idot; + double crc, crs, cuc, cus, cic, cis; + double toes; /* Toe (s) in week */ + double fit; /* fit interval (h) */ + double f0, f1, f2; /* SV clock parameters (af0,af1,af2) */ + double tgd[6]; /* group delay parameters */ + /* GPS/QZS:tgd[0]=TGD */ + /* GAL:tgd[0]=BGD_E1E5a,tgd[1]=BGD_E1E5b */ + /* CMP:tgd[0]=TGD_B1I ,tgd[1]=TGD_B2I/B2b,tgd[2]=TGD_B1Cp */ + /* tgd[3]=TGD_B2ap,tgd[4]=ISC_B1Cd ,tgd[5]=ISC_B2ad */ + double Adot, ndot; /* Adot,ndot for CNAV */ } eph_t; -typedef struct { /* GLONASS broadcast ephemeris type */ - int sat; /* satellite number */ - int iode; /* IODE (0-6 bit of tb field) */ - int frq; /* Satellite frequency number (-7 to 13) */ - int svh; // Extended SVH (bit 3:ln, bit 2:Cn_a, bit 1:Cn, bit 0:Bn) - int flags; // Status flags (bits 7 8:M, bit 6:P4, bit 5:P3, bit 4:P2, bits 2 3:P1, bits 0 1:P) - int sva, age; /* accuracy, age of operation */ - gtime_t toe; /* epoch of ephemerides (gpst) */ - gtime_t tof; /* message frame time (gpst) */ - double pos[3]; /* satellite position (ecef) (m) */ - double vel[3]; /* satellite velocity (ecef) (m/s) */ - double acc[3]; /* satellite acceleration (ecef) (m/s^2) */ - double taun,gamn; /* SV clock bias (s)/relative freq bias */ - double dtaun; /* delay between L1 and L2 (s) */ +typedef struct { /* GLONASS broadcast ephemeris type */ + int sat; /* satellite number */ + int iode; /* IODE (0-6 bit of tb field) */ + int frq; /* Satellite frequency number (-7 to 13) */ + int svh; // Extended SVH (bit 3:ln, bit 2:Cn_a, bit 1:Cn, bit 0:Bn) + int flags; // Status flags (bits 7 8:M, bit 6:P4, bit 5:P3, bit 4:P2, bits 2 3:P1, bits 0 1:P) + int sva, age; /* accuracy, age of operation */ + gtime_t toe; /* epoch of ephemerides (gpst) */ + gtime_t tof; /* message frame time (gpst) */ + double pos[3]; /* satellite position (ecef) (m) */ + double vel[3]; /* satellite velocity (ecef) (m/s) */ + double acc[3]; /* satellite acceleration (ecef) (m/s^2) */ + double taun, gamn; /* SV clock bias (s)/relative freq bias */ + double dtaun; /* delay between L1 and L2 (s) */ } geph_t; -typedef struct { /* precise ephemeris type */ - gtime_t time; /* time (GPST) */ - int index; /* ephemeris index for multiple files */ - double pos[MAXSAT][4]; /* satellite position/clock (ecef) (m|s) */ - float std[MAXSAT][4]; /* satellite position/clock std (m|s) */ - double vel[MAXSAT][4]; /* satellite velocity/clk-rate (m/s|s/s) */ - float vst[MAXSAT][4]; /* satellite velocity/clk-rate std (m/s|s/s) */ - float cov[MAXSAT][3]; /* satellite position covariance (m^2) */ - float vco[MAXSAT][3]; /* satellite velocity covariance (m^2) */ +typedef struct { /* precise ephemeris type */ + gtime_t time; /* time (GPST) */ + int index; /* ephemeris index for multiple files */ + double pos[MAXSAT][4]; /* satellite position/clock (ecef) (m|s) */ + float std[MAXSAT][4]; /* satellite position/clock std (m|s) */ + double vel[MAXSAT][4]; /* satellite velocity/clk-rate (m/s|s/s) */ + float vst[MAXSAT][4]; /* satellite velocity/clk-rate std (m/s|s/s) */ + float cov[MAXSAT][3]; /* satellite position covariance (m^2) */ + float vco[MAXSAT][3]; /* satellite velocity covariance (m^2) */ } peph_t; -typedef struct { /* precise clock type */ - gtime_t time; /* time (GPST) */ - int index; /* clock index for multiple files */ - double clk[MAXSAT][1]; /* satellite clock (s) */ - float std[MAXSAT][1]; /* satellite clock std (s) */ +typedef struct { /* precise clock type */ + gtime_t time; /* time (GPST) */ + int index; /* clock index for multiple files */ + double clk[MAXSAT][1]; /* satellite clock (s) */ + float std[MAXSAT][1]; /* satellite clock std (s) */ } pclk_t; -typedef struct { /* SBAS ephemeris type */ - int sat; /* satellite number */ - gtime_t t0; /* reference epoch time (GPST) */ - gtime_t tof; /* time of message frame (GPST) */ - int sva; /* SV accuracy (URA index) */ - int svh; /* SV health (0:ok) */ - double pos[3]; /* satellite position (m) (ecef) */ - double vel[3]; /* satellite velocity (m/s) (ecef) */ - double acc[3]; /* satellite acceleration (m/s^2) (ecef) */ - double af0,af1; /* satellite clock-offset/drift (s,s/s) */ +typedef struct { /* SBAS ephemeris type */ + int sat; /* satellite number */ + gtime_t t0; /* reference epoch time (GPST) */ + gtime_t tof; /* time of message frame (GPST) */ + int sva; /* SV accuracy (URA index) */ + int svh; /* SV health (0:ok) */ + double pos[3]; /* satellite position (m) (ecef) */ + double vel[3]; /* satellite velocity (m/s) (ecef) */ + double acc[3]; /* satellite acceleration (m/s^2) (ecef) */ + double af0, af1; /* satellite clock-offset/drift (s,s/s) */ } seph_t; -typedef struct { /* NORAD TLE data type */ - char name [32]; /* common name */ - char alias[32]; /* alias name */ - char satno[16]; /* satellite catalog number */ - char satclass; /* classification */ - char desig[16]; /* international designator */ - gtime_t epoch; /* element set epoch (UTC) */ - double ndot; /* 1st derivative of mean motion */ - double nddot; /* 2st derivative of mean motion */ - double bstar; /* B* drag term */ - int etype; /* element set type */ - int eleno; /* element number */ - double inc; /* orbit inclination (deg) */ - double OMG; /* right ascension of ascending node (deg) */ - double ecc; /* eccentricity */ - double omg; /* argument of perigee (deg) */ - double M; /* mean anomaly (deg) */ - double n; /* mean motion (rev/day) */ - int rev; /* revolution number at epoch */ +typedef struct { /* NORAD TLE data type */ + char name[32]; /* common name */ + char alias[32]; /* alias name */ + char satno[16]; /* satellite catalog number */ + char satclass; /* classification */ + char desig[16]; /* international designator */ + gtime_t epoch; /* element set epoch (UTC) */ + double ndot; /* 1st derivative of mean motion */ + double nddot; /* 2st derivative of mean motion */ + double bstar; /* B* drag term */ + int etype; /* element set type */ + int eleno; /* element number */ + double inc; /* orbit inclination (deg) */ + double OMG; /* right ascension of ascending node (deg) */ + double ecc; /* eccentricity */ + double omg; /* argument of perigee (deg) */ + double M; /* mean anomaly (deg) */ + double n; /* mean motion (rev/day) */ + int rev; /* revolution number at epoch */ } tled_t; -typedef struct { /* NORAD TLE (two line element) type */ - int n,nmax; /* number/max number of two line element data */ - tled_t *data; /* NORAD TLE data */ +typedef struct { /* NORAD TLE (two line element) type */ + int n, nmax; /* number/max number of two line element data */ + tled_t *data; /* NORAD TLE data */ } tle_t; -typedef struct { /* TEC grid type */ - gtime_t time; /* epoch time (GPST) */ - int ndata[3]; /* TEC grid data size {nlat,nlon,nhgt} */ - double rb; /* earth radius (km) */ - double lats[3]; /* latitude start/interval (deg) */ - double lons[3]; /* longitude start/interval (deg) */ - double hgts[3]; /* heights start/interval (km) */ - double *data; /* TEC grid data (tecu) */ - float *rms; /* RMS values (tecu) */ +typedef struct { /* TEC grid type */ + gtime_t time; /* epoch time (GPST) */ + int ndata[3]; /* TEC grid data size {nlat,nlon,nhgt} */ + double rb; /* earth radius (km) */ + double lats[3]; /* latitude start/interval (deg) */ + double lons[3]; /* longitude start/interval (deg) */ + double hgts[3]; /* heights start/interval (km) */ + double *data; /* TEC grid data (tecu) */ + float *rms; /* RMS values (tecu) */ } tec_t; -typedef struct { /* SBAS message type */ - int week,tow; /* reception time */ - uint8_t prn,rcv; /* SBAS satellite PRN,receiver number */ - uint8_t msg[29]; /* SBAS message (226bit) padded by 0 */ +typedef struct { /* SBAS message type */ + int week, tow; /* reception time */ + uint8_t prn, rcv; /* SBAS satellite PRN,receiver number */ + uint8_t msg[29]; /* SBAS message (226bit) padded by 0 */ } sbsmsg_t; -typedef struct { /* SBAS messages type */ - int n,nmax; /* number of SBAS messages/allocated */ - sbsmsg_t *msgs; /* SBAS messages */ +typedef struct { /* SBAS messages type */ + int n, nmax; /* number of SBAS messages/allocated */ + sbsmsg_t *msgs; /* SBAS messages */ } sbs_t; -typedef struct { /* SBAS fast correction type */ - gtime_t t0; /* time of applicability (TOF) */ - double prc; /* pseudorange correction (PRC) (m) */ - double rrc; /* range-rate correction (RRC) (m/s) */ - double dt; /* range-rate correction delta-time (s) */ - int iodf; /* IODF (issue of date fast corr) */ - int16_t udre; /* UDRE+1 */ - int16_t ai; /* degradation factor indicator */ +typedef struct { /* SBAS fast correction type */ + gtime_t t0; /* time of applicability (TOF) */ + double prc; /* pseudorange correction (PRC) (m) */ + double rrc; /* range-rate correction (RRC) (m/s) */ + double dt; /* range-rate correction delta-time (s) */ + int iodf; /* IODF (issue of date fast corr) */ + int16_t udre; /* UDRE+1 */ + int16_t ai; /* degradation factor indicator */ } sbsfcorr_t; -typedef struct { /* SBAS long term satellite error correction type */ - gtime_t t0; /* correction time */ - int iode; /* IODE (issue of date ephemeris) */ - double dpos[3]; /* delta position (m) (ecef) */ - double dvel[3]; /* delta velocity (m/s) (ecef) */ - double daf0,daf1; /* delta clock-offset/drift (s,s/s) */ +typedef struct { /* SBAS long term satellite error correction type */ + gtime_t t0; /* correction time */ + int iode; /* IODE (issue of date ephemeris) */ + double dpos[3]; /* delta position (m) (ecef) */ + double dvel[3]; /* delta velocity (m/s) (ecef) */ + double daf0, daf1; /* delta clock-offset/drift (s,s/s) */ } sbslcorr_t; -typedef struct { /* SBAS satellite correction type */ - int sat; /* satellite number */ - sbsfcorr_t fcorr; /* fast correction */ - sbslcorr_t lcorr; /* long term correction */ +typedef struct { /* SBAS satellite correction type */ + int sat; /* satellite number */ + sbsfcorr_t fcorr; /* fast correction */ + sbslcorr_t lcorr; /* long term correction */ } sbssatp_t; -typedef struct { /* SBAS satellite corrections type */ - int iodp; /* IODP (issue of date mask) */ - int nsat; /* number of satellites */ - int tlat; /* system latency (s) */ - sbssatp_t sat[MAXSAT]; /* satellite correction */ +typedef struct { /* SBAS satellite corrections type */ + int iodp; /* IODP (issue of date mask) */ + int nsat; /* number of satellites */ + int tlat; /* system latency (s) */ + sbssatp_t sat[MAXSAT]; /* satellite correction */ } sbssat_t; -typedef struct { /* SBAS ionospheric correction type */ - gtime_t t0; /* correction time */ - int16_t lat,lon; /* latitude/longitude (deg) */ - int16_t give; /* GIVI+1 */ - float delay; /* vertical delay estimate (m) */ +typedef struct { /* SBAS ionospheric correction type */ + gtime_t t0; /* correction time */ + int16_t lat, lon; /* latitude/longitude (deg) */ + int16_t give; /* GIVI+1 */ + float delay; /* vertical delay estimate (m) */ } sbsigp_t; -typedef struct { /* IGP band type */ - int16_t x; /* longitude/latitude (deg) */ - const int16_t *y; /* latitudes/longitudes (deg) */ - uint8_t bits; /* IGP mask start bit */ - uint8_t bite; /* IGP mask end bit */ +typedef struct { /* IGP band type */ + int16_t x; /* longitude/latitude (deg) */ + const int16_t *y; /* latitudes/longitudes (deg) */ + uint8_t bits; /* IGP mask start bit */ + uint8_t bite; /* IGP mask end bit */ } sbsigpband_t; -typedef struct { /* SBAS ionospheric corrections type */ - int iodi; /* IODI (issue of date ionos corr) */ - int nigp; /* number of igps */ - sbsigp_t igp[MAXNIGP]; /* ionospheric correction */ +typedef struct { /* SBAS ionospheric corrections type */ + int iodi; /* IODI (issue of date ionos corr) */ + int nigp; /* number of igps */ + sbsigp_t igp[MAXNIGP]; /* ionospheric correction */ } sbsion_t; -typedef struct { /* DGPS/GNSS correction type */ - gtime_t t0; /* correction time */ - double prc; /* pseudorange correction (PRC) (m) */ - double rrc; /* range rate correction (RRC) (m/s) */ - int iod; /* issue of data (IOD) */ - double udre; /* UDRE */ +typedef struct { /* DGPS/GNSS correction type */ + gtime_t t0; /* correction time */ + double prc; /* pseudorange correction (PRC) (m) */ + double rrc; /* range rate correction (RRC) (m/s) */ + int iod; /* issue of data (IOD) */ + double udre; /* UDRE */ } dgps_t; -typedef struct { /* SSR correction type */ - gtime_t t0[6]; /* epoch time (GPST) {eph,clk,hrclk,ura,bias,pbias} */ - double udi[6]; /* SSR update interval (s) */ - int iod[6]; /* iod ssr {eph,clk,hrclk,ura,bias,pbias} */ - int iode; /* issue of data */ - int iodcrc; /* issue of data crc for beidou/sbas */ - int ura; /* URA indicator */ - int refd; /* sat ref datum (0:ITRF,1:regional) */ - double deph [3]; /* delta orbit {radial,along,cross} (m) */ - double ddeph[3]; /* dot delta orbit {radial,along,cross} (m/s) */ - double dclk [3]; /* delta clock {c0,c1,c2} (m,m/s,m/s^2) */ - double hrclk; /* high-rate clock correction (m) */ - float cbias[MAXCODE]; /* code biases (m) */ - double pbias[MAXCODE]; /* phase biases (m) */ - float stdpb[MAXCODE]; /* std-dev of phase biases (m) */ - double yaw_ang,yaw_rate; /* yaw angle and yaw rate (deg,deg/s) */ - uint8_t update; /* update flag (0:no update,1:update) */ +typedef struct { /* SSR correction type */ + gtime_t t0[6]; /* epoch time (GPST) {eph,clk,hrclk,ura,bias,pbias} */ + double udi[6]; /* SSR update interval (s) */ + int iod[6]; /* iod ssr {eph,clk,hrclk,ura,bias,pbias} */ + int iode; /* issue of data */ + int iodcrc; /* issue of data crc for beidou/sbas */ + int ura; /* URA indicator */ + int refd; /* sat ref datum (0:ITRF,1:regional) */ + double deph[3]; /* delta orbit {radial,along,cross} (m) */ + double ddeph[3]; /* dot delta orbit {radial,along,cross} (m/s) */ + double dclk[3]; /* delta clock {c0,c1,c2} (m,m/s,m/s^2) */ + double hrclk; /* high-rate clock correction (m) */ + float cbias[MAXCODE]; /* code biases (m) */ + double pbias[MAXCODE]; /* phase biases (m) */ + float stdpb[MAXCODE]; /* std-dev of phase biases (m) */ + double yaw_ang, yaw_rate; /* yaw angle and yaw rate (deg,deg/s) */ + uint8_t update; /* update flag (0:no update,1:update) */ } ssr_t; -typedef struct { /* navigation data type */ - int n,nmax; /* number of broadcast ephemeris */ - int ng,ngmax; /* number of glonass ephemeris */ - int ns,nsmax; /* number of sbas ephemeris */ - int ne,nemax; /* number of precise ephemeris */ - int nc,ncmax; /* number of precise clock */ - int na,namax; /* number of almanac data */ - int nt,ntmax; /* number of tec grid data */ - eph_t *eph; /* GPS/QZS/GAL/BDS/IRN ephemeris */ - geph_t *geph; /* GLONASS ephemeris */ - seph_t *seph; /* SBAS ephemeris */ - peph_t *peph; /* precise ephemeris */ - pclk_t *pclk; /* precise clock */ - alm_t *alm; /* almanac data */ - tec_t *tec; /* tec grid data */ - erp_t erp; /* earth rotation parameters */ - double utc_gps[8]; /* GPS delta-UTC parameters {A0,A1,Tot,WNt,dt_LS,WN_LSF,DN,dt_LSF} */ - double utc_glo[8]; /* GLONASS UTC time parameters {tau_C,tau_GPS} */ - double utc_gal[8]; /* Galileo UTC parameters */ - double utc_qzs[8]; /* QZS UTC parameters */ - double utc_cmp[8]; /* BeiDou UTC parameters */ - double utc_irn[9]; /* IRNSS UTC parameters {A0,A1,Tot,...,dt_LSF,A2} */ - double utc_sbs[4]; /* SBAS UTC parameters */ - double ion_gps[8]; /* GPS iono model parameters {a0,a1,a2,a3,b0,b1,b2,b3} */ - double ion_gal[4]; /* Galileo iono model parameters {ai0,ai1,ai2,0} */ - double ion_qzs[8]; /* QZSS iono model parameters {a0,a1,a2,a3,b0,b1,b2,b3} */ - double ion_cmp[8]; /* BeiDou iono model parameters {a0,a1,a2,a3,b0,b1,b2,b3} */ - double ion_irn[8]; /* IRNSS iono model parameters {a0,a1,a2,a3,b0,b1,b2,b3} */ - int glo_fcn[32]; /* GLONASS FCN + 8 */ - double cbias[MAXSAT][MAX_CODE_BIAS_FREQS][MAX_CODE_BIASES]; /* satellite DCB [0:P1-C1,1:P2-C2][code] (m) */ - double rbias[MAXRCV][MAX_CODE_BIAS_FREQS][MAX_CODE_BIASES]; /* receiver DCB (0:P1-P2,1:P1-C1,2:P2-C2) (m) */ - pcv_t pcvs[MAXSAT]; /* satellite antenna pcv */ - sbssat_t sbssat; /* SBAS satellite corrections */ - sbsion_t sbsion[MAXBAND+1]; /* SBAS ionosphere corrections */ - dgps_t dgps[MAXSAT]; /* DGPS corrections */ - ssr_t ssr[MAXSAT]; /* SSR corrections */ +typedef struct { /* navigation data type */ + int n, nmax; /* number of broadcast ephemeris */ + int ng, ngmax; /* number of glonass ephemeris */ + int ns, nsmax; /* number of sbas ephemeris */ + int ne, nemax; /* number of precise ephemeris */ + int nc, ncmax; /* number of precise clock */ + int na, namax; /* number of almanac data */ + int nt, ntmax; /* number of tec grid data */ + eph_t *eph; /* GPS/QZS/GAL/BDS/IRN ephemeris */ + geph_t *geph; /* GLONASS ephemeris */ + seph_t *seph; /* SBAS ephemeris */ + peph_t *peph; /* precise ephemeris */ + pclk_t *pclk; /* precise clock */ + alm_t *alm; /* almanac data */ + tec_t *tec; /* tec grid data */ + erp_t erp; /* earth rotation parameters */ + double utc_gps[8]; /* GPS delta-UTC parameters {A0,A1,Tot,WNt,dt_LS,WN_LSF,DN,dt_LSF} */ + double utc_glo[8]; /* GLONASS UTC time parameters {tau_C,tau_GPS} */ + double utc_gal[8]; /* Galileo UTC parameters */ + double utc_qzs[8]; /* QZS UTC parameters */ + double utc_cmp[8]; /* BeiDou UTC parameters */ + double utc_irn[9]; /* IRNSS UTC parameters {A0,A1,Tot,...,dt_LSF,A2} */ + double utc_sbs[4]; /* SBAS UTC parameters */ + double ion_gps[8]; /* GPS iono model parameters {a0,a1,a2,a3,b0,b1,b2,b3} */ + double ion_gal[4]; /* Galileo iono model parameters {ai0,ai1,ai2,0} */ + double ion_qzs[8]; /* QZSS iono model parameters {a0,a1,a2,a3,b0,b1,b2,b3} */ + double ion_cmp[8]; /* BeiDou iono model parameters {a0,a1,a2,a3,b0,b1,b2,b3} */ + double ion_irn[8]; /* IRNSS iono model parameters {a0,a1,a2,a3,b0,b1,b2,b3} */ + int glo_fcn[32]; /* GLONASS FCN + 8 */ + double cbias[MAXSAT][MAX_CODE_BIAS_FREQS] + [MAX_CODE_BIASES]; /* satellite DCB [0:P1-C1,1:P2-C2][code] (m) */ + double rbias[MAXRCV][MAX_CODE_BIAS_FREQS] + [MAX_CODE_BIASES]; /* receiver DCB (0:P1-P2,1:P1-C1,2:P2-C2) (m) */ + pcv_t pcvs[MAXSAT]; /* satellite antenna pcv */ + sbssat_t sbssat; /* SBAS satellite corrections */ + sbsion_t sbsion[MAXBAND + 1]; /* SBAS ionosphere corrections */ + dgps_t dgps[MAXSAT]; /* DGPS corrections */ + ssr_t ssr[MAXSAT]; /* SSR corrections */ } nav_t; -typedef struct { /* station parameter type */ - char name [MAXANT]; /* marker name */ - char markerno[MAXANT]; /* marker number */ - char markertype[MAXANT]; /* marker type */ - char observer[MAXANT]; /* Observer */ - char agency[MAXANT]; /* Agency */ - char antdes [MAXANT]; /* antenna descriptor */ - char antsno [MAXANT]; /* antenna serial number */ - char rectype[MAXANT]; /* receiver type descriptor */ - char recver [MAXANT]; /* receiver firmware version */ - char recsno [MAXANT]; /* receiver serial number */ - int antsetup; /* antenna setup id */ - int itrf; /* ITRF realization year */ - int deltype; /* antenna delta type (0:enu,1:xyz) */ - double pos[3]; /* station position (ecef) (m) */ - double del[3]; /* antenna position delta (e/n/u or x/y/z) (m) */ - double hgt; /* antenna height (m) */ - int glo_cp_align; /* GLONASS code-phase alignment (0:no,1:yes) */ - double glo_cp_bias[4]; /* GLONASS code-phase biases {1C,1P,2C,2P} (m) */ +typedef struct { /* station parameter type */ + char name[MAXANT]; /* marker name */ + char markerno[MAXANT]; /* marker number */ + char markertype[MAXANT]; /* marker type */ + char observer[MAXANT]; /* Observer */ + char agency[MAXANT]; /* Agency */ + char antdes[MAXANT]; /* antenna descriptor */ + char antsno[MAXANT]; /* antenna serial number */ + char rectype[MAXANT]; /* receiver type descriptor */ + char recver[MAXANT]; /* receiver firmware version */ + char recsno[MAXANT]; /* receiver serial number */ + int antsetup; /* antenna setup id */ + int itrf; /* ITRF realization year */ + int deltype; /* antenna delta type (0:enu,1:xyz) */ + double pos[3]; /* station position (ecef) (m) */ + double del[3]; /* antenna position delta (e/n/u or x/y/z) (m) */ + double hgt; /* antenna height (m) */ + int glo_cp_align; /* GLONASS code-phase alignment (0:no,1:yes) */ + double glo_cp_bias[4]; /* GLONASS code-phase biases {1C,1P,2C,2P} (m) */ } sta_t; -typedef struct { /* solution type */ - gtime_t time; /* time (GPST) */ - gtime_t eventime; /* time of event (GPST) */ - double rr[6]; /* position/velocity (m|m/s) */ - /* {x,y,z,vx,vy,vz} or {e,n,u,ve,vn,vu} */ - float qr[6]; /* position variance/covariance (m^2) */ - /* {c_xx,c_yy,c_zz,c_xy,c_yz,c_zx} or */ - /* {c_ee,c_nn,c_uu,c_en,c_nu,c_ue} */ - float qv[6]; /* velocity variance/covariance (m^2/s^2) */ - double dtr[6]; /* receiver clock bias to time systems (s) */ - uint8_t type; /* type (0:xyz-ecef,1:enu-baseline) */ - uint8_t stat; /* solution status (SOLQ_???) */ - uint8_t ns; /* number of valid satellites */ - float age; /* age of differential (s) */ - float ratio; /* AR ratio factor for validation */ - float prev_ratio1; /* previous initial AR ratio factor for validation */ - float prev_ratio2; /* previous final AR ratio factor for validation */ - float thres; /* AR ratio threshold for validation */ - int refstationid; /* ref station ID */ +typedef struct { /* solution type */ + gtime_t time; /* time (GPST) */ + gtime_t eventime; /* time of event (GPST) */ + double rr[6]; /* position/velocity (m|m/s) */ + /* {x,y,z,vx,vy,vz} or {e,n,u,ve,vn,vu} */ + float qr[6]; /* position variance/covariance (m^2) */ + /* {c_xx,c_yy,c_zz,c_xy,c_yz,c_zx} or */ + /* {c_ee,c_nn,c_uu,c_en,c_nu,c_ue} */ + float qv[6]; /* velocity variance/covariance (m^2/s^2) */ + double dtr[6]; /* receiver clock bias to time systems (s) */ + uint8_t type; /* type (0:xyz-ecef,1:enu-baseline) */ + uint8_t stat; /* solution status (SOLQ_???) */ + uint8_t ns; /* number of valid satellites */ + float age; /* age of differential (s) */ + float ratio; /* AR ratio factor for validation */ + float prev_ratio1; /* previous initial AR ratio factor for validation */ + float prev_ratio2; /* previous final AR ratio factor for validation */ + float thres; /* AR ratio threshold for validation */ + int refstationid; /* ref station ID */ } sol_t; -typedef struct { /* solution buffer type */ - int n,nmax; /* number of solution/max number of buffer */ - int cyclic; /* cyclic buffer flag */ - int start,end; /* start/end index */ - gtime_t time; /* current solution time */ - sol_t *data; /* solution data */ - double rb[3]; /* reference position {x,y,z} (ecef) (m) */ - uint8_t buff[MAXSOLLEN+1]; /* message line buffer */ - int nb; /* number of byte in message buffer */ +typedef struct { /* solution buffer type */ + int n, nmax; /* number of solution/max number of buffer */ + int cyclic; /* cyclic buffer flag */ + int start, end; /* start/end index */ + gtime_t time; /* current solution time */ + sol_t *data; /* solution data */ + double rb[3]; /* reference position {x,y,z} (ecef) (m) */ + uint8_t buff[MAXSOLLEN + 1]; /* message line buffer */ + int nb; /* number of byte in message buffer */ } solbuf_t; -typedef struct { /* solution status type */ - gtime_t time; /* time (GPST) */ - uint8_t sat; /* satellite number */ - uint8_t frq; /* frequency (1:L1,2:L2,...) */ - float az,el; /* azimuth/elevation angle (rad) */ - float resp; /* pseudorange residual (m) */ - float resc; /* carrier-phase residual (m) */ - uint8_t flag; /* flags: (vsat<<5)+(slip<<3)+fix */ - float snr; /* signal strength (dBHz) */ - uint16_t lock; /* lock counter */ - uint16_t outc; /* outage counter */ - uint16_t slipc; /* slip counter */ - uint16_t rejc; /* reject counter */ +typedef struct { /* solution status type */ + gtime_t time; /* time (GPST) */ + uint8_t sat; /* satellite number */ + uint8_t frq; /* frequency (1:L1,2:L2,...) */ + float az, el; /* azimuth/elevation angle (rad) */ + float resp; /* pseudorange residual (m) */ + float resc; /* carrier-phase residual (m) */ + uint8_t flag; /* flags: (vsat<<5)+(slip<<3)+fix */ + float snr; /* signal strength (dBHz) */ + uint16_t lock; /* lock counter */ + uint16_t outc; /* outage counter */ + uint16_t slipc; /* slip counter */ + uint16_t rejc; /* reject counter */ } solstat_t; -typedef struct { /* solution status buffer type */ - int n,nmax; /* number of solution/max number of buffer */ - solstat_t *data; /* solution status data */ +typedef struct { /* solution status buffer type */ + int n, nmax; /* number of solution/max number of buffer */ + solstat_t *data; /* solution status data */ } solstatbuf_t; -typedef struct { /* RTCM control struct type */ - int staid; /* station id */ - int stah; /* station health */ - int seqno; /* sequence number for rtcm 2 or iods msm */ - int outtype; /* output message type */ - gtime_t time; /* message time */ - gtime_t time_s; /* message start time */ - obs_t obs; /* observation data (uncorrected) */ - nav_t nav; /* satellite ephemerides */ - sta_t sta; /* station parameters */ - dgps_t *dgps; /* output of dgps corrections */ - ssr_t ssr[MAXSAT]; /* output of ssr corrections */ - char msg[128]; /* special message */ - char msgtype[256]; /* last message type */ - char msmtype[7][128]; /* msm signal types */ - int obsflag; /* obs data complete flag (1:ok,0:not complete) */ - int ephsat; /* input ephemeris satellite number */ - int ephset; /* input ephemeris set (0-1) */ - double cp[MAXSAT][NFREQ+NEXOBS]; /* carrier-phase measurement */ - uint16_t lock[MAXSAT][NFREQ+NEXOBS]; /* lock time */ - uint16_t loss[MAXSAT][NFREQ+NEXOBS]; /* loss of lock count */ - gtime_t lltime[MAXSAT][NFREQ+NEXOBS]; /* last lock time */ - int nbyte; /* number of bytes in message buffer */ - int nbyte_invalid; /* number of bytes in invalid message, used to rewind buffer */ - int nbit; /* number of bits in word buffer */ - int len; /* message length (bytes) */ - uint8_t buff[1200]; /* message buffer */ - uint32_t word; /* word buffer for rtcm 2 */ - uint32_t nmsg2[100]; /* message count of RTCM 2 (1-99:1-99,0:other) */ - uint32_t nmsg3[400]; /* message count of RTCM 3 (1-299:1001-1299,300-329:4070-4099,0:other) */ - char opt[256]; /* RTCM dependent options */ +typedef struct { /* RTCM control struct type */ + int staid; /* station id */ + int stah; /* station health */ + int seqno; /* sequence number for rtcm 2 or iods msm */ + int outtype; /* output message type */ + gtime_t time; /* message time */ + gtime_t time_s; /* message start time */ + obs_t obs; /* observation data (uncorrected) */ + nav_t nav; /* satellite ephemerides */ + sta_t sta; /* station parameters */ + dgps_t *dgps; /* output of dgps corrections */ + ssr_t ssr[MAXSAT]; /* output of ssr corrections */ + char msg[128]; /* special message */ + char msgtype[256]; /* last message type */ + char msmtype[7][128]; /* msm signal types */ + int obsflag; /* obs data complete flag (1:ok,0:not complete) */ + int ephsat; /* input ephemeris satellite number */ + int ephset; /* input ephemeris set (0-1) */ + double cp[MAXSAT][NFREQ + NEXOBS]; /* carrier-phase measurement */ + uint16_t lock[MAXSAT][NFREQ + NEXOBS]; /* lock time */ + uint16_t loss[MAXSAT][NFREQ + NEXOBS]; /* loss of lock count */ + gtime_t lltime[MAXSAT][NFREQ + NEXOBS]; /* last lock time */ + int nbyte; /* number of bytes in message buffer */ + int nbyte_invalid; /* number of bytes in invalid message, used to rewind buffer */ + int nbit; /* number of bits in word buffer */ + int len; /* message length (bytes) */ + uint8_t buff[1200]; /* message buffer */ + uint32_t word; /* word buffer for rtcm 2 */ + uint32_t nmsg2[100]; /* message count of RTCM 2 (1-99:1-99,0:other) */ + uint32_t nmsg3[400]; /* message count of RTCM 3 (1-299:1001-1299,300-329:4070-4099,0:other) */ + char opt[256]; /* RTCM dependent options */ } rtcm_t; -typedef struct { /* RINEX control struct type */ - gtime_t time; /* message time */ - double ver; /* RINEX version */ - char type; /* RINEX file type ('O','N',...) */ - int sys; /* navigation system */ - int tsys; /* time system */ - char tobs[RNX_NUMSYS][MAXOBSTYPE][4]; /* rinex obs types */ - obs_t obs; /* observation data */ - nav_t nav; /* navigation data */ - sta_t sta; /* station info */ - int ephsat; /* input ephemeris satellite number */ - int ephset; /* input ephemeris set (0-1) */ - char opt[256]; /* rinex dependent options */ +typedef struct { /* RINEX control struct type */ + gtime_t time; /* message time */ + double ver; /* RINEX version */ + char type; /* RINEX file type ('O','N',...) */ + int sys; /* navigation system */ + int tsys; /* time system */ + char tobs[RNX_NUMSYS][MAXOBSTYPE][4]; /* rinex obs types */ + obs_t obs; /* observation data */ + nav_t nav; /* navigation data */ + sta_t sta; /* station info */ + int ephsat; /* input ephemeris satellite number */ + int ephset; /* input ephemeris set (0-1) */ + char opt[256]; /* rinex dependent options */ } rnxctr_t; -typedef struct { /* download URL type */ - char type[32]; /* data type */ - char path[1024]; /* URL path */ - char dir [1024]; /* local directory */ - double tint; /* time interval (s) */ +typedef struct { /* download URL type */ + char type[32]; /* data type */ + char path[1024]; /* URL path */ + char dir[1024]; /* local directory */ + double tint; /* time interval (s) */ } url_t; -typedef struct { /* option type */ - const char *name; /* option name */ - int format; /* option format (0:int,1:double,2:string,3:enum) */ - void *var; /* pointer to option variable */ - const char *comment; /* option comment/enum labels/unit */ +typedef struct { /* option type */ + const char *name; /* option name */ + int format; /* option format (0:int,1:double,2:string,3:enum) */ + void *var; /* pointer to option variable */ + const char *comment; /* option comment/enum labels/unit */ } opt_t; -typedef struct { /* SNR mask type */ - int ena[2]; /* enable flag {rover,base} */ - double mask[MAXFREQ][9]; /* mask (dBHz) at 5,10,...85 deg */ +typedef struct { /* SNR mask type */ + int ena[2]; /* enable flag {rover,base} */ + double mask[MAXFREQ][9]; /* mask (dBHz) at 5,10,...85 deg */ } snrmask_t; -typedef struct { /* processing options type */ - int mode; /* positioning mode (PMODE_???) */ - int soltype; /* solution type (0:forward,1:backward,2:combined) */ - int nf; /* number of frequencies (1:L1,2:L1+L2,3:L1+L2+L5) */ - int navsys; /* navigation system */ - double elmin; /* elevation mask angle (rad) */ - snrmask_t snrmask; /* SNR mask */ - int sateph; /* satellite ephemeris/clock (EPHOPT_???) */ - int modear; /* AR mode (0:off,1:continuous,2:instantaneous,3:fix and hold,4:ppp-ar) */ - int glomodear; /* GLONASS AR mode (0:off,1:on,2:auto cal,3:ext cal) */ - int gpsmodear; /* GPS AR mode, debug/learning only (0:off,1:on) */ - int bdsmodear; /* BeiDou AR mode (0:off,1:on) */ - int arfilter; /* AR filtering to reject bad sats (0:off,1:on) */ - int maxout; /* obs outage count to reset bias */ - int minlock; /* min lock count to fix ambiguity */ - int minfixsats; /* min sats to fix integer ambiguities */ - int minholdsats; /* min sats to hold integer ambiguities */ - int mindropsats; /* min sats to drop sats in AR */ - int minfix; /* min fix count to hold ambiguity */ - int armaxiter; /* max iteration to resolve ambiguity */ - int ionoopt; /* ionosphere option (IONOOPT_???) */ - int tropopt; /* troposphere option (TROPOPT_???) */ - int dynamics; /* dynamics model (0:none,1:velocity,2:accel) */ - int tidecorr; /* earth tide correction (0:off+1:solid+2:otl+4:spole) */ - int niter; /* number of filter iteration */ - int codesmooth; /* code smoothing window size (0:none) */ - int intpref; /* interpolate reference obs (for post mission) */ - int sbascorr; /* SBAS correction options */ - int sbassatsel; /* SBAS satellite selection (0:all) */ - int rovpos; /* rover position for fixed mode */ - int refpos; /* base position for relative mode */ - /* (0:pos in prcopt, 1:average of single pos, */ - /* 2:read from file, 3:rinex header, 4:rtcm pos) */ - double eratio[MAXFREQ]; /* code/phase error ratio */ - double err[8]; /* observation error terms */ - /* [reserved,constant,elevation,baseline,doppler,snr-max,snr, rcv_std] */ - double std[3]; /* initial-state std [0]bias,[1]iono [2]trop */ - double prn[6]; /* process-noise std [0]bias,[1]iono [2]trop [3]acch [4]accv [5] pos */ - double sclkstab; /* satellite clock stability (sec/sec) */ - double thresar[8]; /* AR validation threshold */ - double elmaskar; /* elevation mask of AR for rising satellite (deg) */ - double elmaskhold; /* elevation mask to hold ambiguity (deg) */ - double thresslip; /* slip threshold of geometry-free phase (m) */ - double thresdop; /* slip threshold of doppler (m) */ - double varholdamb; /* variance for fix-and-hold pseudo measurements (cycle^2) */ - double gainholdamb; /* gain used for GLO and SBAS sats to adjust ambiguity */ - double maxtdiff; /* max difference of time (sec) */ - double maxinno[2]; /* reject threshold of innovation for phase and code (m) */ - double baseline[2]; /* baseline length constraint {const,sigma} (m) */ - double ru[3]; /* rover position for fixed mode {x,y,z} (ecef) (m) */ - double rb[3]; /* base position for relative mode {x,y,z} (ecef) (m) */ - char anttype[2][MAXANT]; /* antenna types {rover,base} */ - double antdel[2][3]; /* antenna delta {{rov_e,rov_n,rov_u},{ref_e,ref_n,ref_u}} */ - pcv_t pcvr[2]; /* receiver antenna parameters {rov,base} */ - uint8_t exsats[MAXSAT]; /* excluded satellites (1:excluded,2:included) */ - int maxaveep; /* max averaging epochs */ - int initrst; /* initialize by restart */ - int outsingle; /* output single by dgps/float/fix/ppp outage */ - char rnxopt[2][256]; /* rinex options {rover,base} */ - int posopt[6]; /* positioning options */ - int syncsol; /* solution sync mode (0:off,1:on) */ - double odisp[2][2][11][3]; // Ocean tide loading parameters {rov,base}{amp,phase} - int freqopt; /* disable L2-AR */ - char pppopt[256]; /* ppp option */ +typedef struct { /* processing options type */ + int mode; /* positioning mode (PMODE_???) */ + int soltype; /* solution type (0:forward,1:backward,2:combined) */ + int nf; /* number of frequencies (1:L1,2:L1+L2,3:L1+L2+L5) */ + int navsys; /* navigation system */ + double elmin; /* elevation mask angle (rad) */ + snrmask_t snrmask; /* SNR mask */ + int sateph; /* satellite ephemeris/clock (EPHOPT_???) */ + int modear; /* AR mode (0:off,1:continuous,2:instantaneous,3:fix and hold,4:ppp-ar) */ + int glomodear; /* GLONASS AR mode (0:off,1:on,2:auto cal,3:ext cal) */ + int gpsmodear; /* GPS AR mode, debug/learning only (0:off,1:on) */ + int bdsmodear; /* BeiDou AR mode (0:off,1:on) */ + int arfilter; /* AR filtering to reject bad sats (0:off,1:on) */ + int maxout; /* obs outage count to reset bias */ + int minlock; /* min lock count to fix ambiguity */ + int minfixsats; /* min sats to fix integer ambiguities */ + int minholdsats; /* min sats to hold integer ambiguities */ + int mindropsats; /* min sats to drop sats in AR */ + int minfix; /* min fix count to hold ambiguity */ + int armaxiter; /* max iteration to resolve ambiguity */ + int ionoopt; /* ionosphere option (IONOOPT_???) */ + int tropopt; /* troposphere option (TROPOPT_???) */ + int dynamics; /* dynamics model (0:none,1:velocity,2:accel) */ + int tidecorr; /* earth tide correction (0:off+1:solid+2:otl+4:spole) */ + int niter; /* number of filter iteration */ + int codesmooth; /* code smoothing window size (0:none) */ + int intpref; /* interpolate reference obs (for post mission) */ + int sbascorr; /* SBAS correction options */ + int sbassatsel; /* SBAS satellite selection (0:all) */ + int rovpos; /* rover position for fixed mode */ + int refpos; /* base position for relative mode */ + /* (0:pos in prcopt, 1:average of single pos, */ + /* 2:read from file, 3:rinex header, 4:rtcm pos) */ + double eratio[MAXFREQ]; /* code/phase error ratio */ + double err[8]; /* observation error terms */ + /* [reserved,constant,elevation,baseline,doppler,snr-max,snr, rcv_std] */ + double std[3]; /* initial-state std [0]bias,[1]iono [2]trop */ + double prn[6]; /* process-noise std [0]bias,[1]iono [2]trop [3]acch [4]accv [5] pos */ + double sclkstab; /* satellite clock stability (sec/sec) */ + double thresar[8]; /* AR validation threshold */ + double elmaskar; /* elevation mask of AR for rising satellite (deg) */ + double elmaskhold; /* elevation mask to hold ambiguity (deg) */ + double thresslip; /* slip threshold of geometry-free phase (m) */ + double thresdop; /* slip threshold of doppler (m) */ + double varholdamb; /* variance for fix-and-hold pseudo measurements (cycle^2) */ + double gainholdamb; /* gain used for GLO and SBAS sats to adjust ambiguity */ + double maxtdiff; /* max difference of time (sec) */ + double maxinno[2]; /* reject threshold of innovation for phase and code (m) */ + double baseline[2]; /* baseline length constraint {const,sigma} (m) */ + double ru[3]; /* rover position for fixed mode {x,y,z} (ecef) (m) */ + double rb[3]; /* base position for relative mode {x,y,z} (ecef) (m) */ + char anttype[2][MAXANT]; /* antenna types {rover,base} */ + double antdel[2][3]; /* antenna delta {{rov_e,rov_n,rov_u},{ref_e,ref_n,ref_u}} */ + pcv_t pcvr[2]; /* receiver antenna parameters {rov,base} */ + uint8_t exsats[MAXSAT]; /* excluded satellites (1:excluded,2:included) */ + int maxaveep; /* max averaging epochs */ + int initrst; /* initialize by restart */ + int outsingle; /* output single by dgps/float/fix/ppp outage */ + char rnxopt[2][256]; /* rinex options {rover,base} */ + int posopt[6]; /* positioning options */ + int syncsol; /* solution sync mode (0:off,1:on) */ + double odisp[2][2][11][3]; // Ocean tide loading parameters {rov,base}{amp,phase} + int freqopt; /* disable L2-AR */ + char pppopt[256]; /* ppp option */ } prcopt_t; -typedef struct { /* solution options type */ - int posf; /* solution format (SOLF_???) */ - int times; /* time system (TIMES_???) */ - int timef; /* time format (0:sssss.s,1:yyyy/mm/dd hh:mm:ss.s) */ - int timeu; /* time digits under decimal point */ - int degf; /* latitude/longitude format (0:ddd.ddd,1:ddd mm ss) */ - int outhead; /* output header (0:no,1:yes) */ - int outopt; /* output processing options (0:no,1:yes) */ - int outvel; /* output velocity options (0:no,1:yes) */ - int datum; /* datum (0:WGS84,1:Tokyo) */ - int height; /* height (0:ellipsoidal,1:geodetic) */ - int geoid; /* geoid model (0:EGM96,1:JGD2000) */ - int solstatic; /* solution of static mode (0:all,1:single) */ - int sstat; /* solution statistics level (0:off,1:states,2:residuals) */ - int trace; /* debug trace level (0:off,1-5:debug) */ - double nmeaintv[2]; /* nmea output interval (s) (<0:no,0:all) */ - /* nmeaintv[0]:gprmc,gpgga,nmeaintv[1]:gpgsv */ - char sep[64]; /* field separator */ - char prog[64]; /* program name */ - double maxsolstd; /* max std-dev for solution output (m) (0:all) */ +typedef struct { /* solution options type */ + int posf; /* solution format (SOLF_???) */ + int times; /* time system (TIMES_???) */ + int timef; /* time format (0:sssss.s,1:yyyy/mm/dd hh:mm:ss.s) */ + int timeu; /* time digits under decimal point */ + int degf; /* latitude/longitude format (0:ddd.ddd,1:ddd mm ss) */ + int outhead; /* output header (0:no,1:yes) */ + int outopt; /* output processing options (0:no,1:yes) */ + int outvel; /* output velocity options (0:no,1:yes) */ + int datum; /* datum (0:WGS84,1:Tokyo) */ + int height; /* height (0:ellipsoidal,1:geodetic) */ + int geoid; /* geoid model (0:EGM96,1:JGD2000) */ + int solstatic; /* solution of static mode (0:all,1:single) */ + int sstat; /* solution statistics level (0:off,1:states,2:residuals) */ + int trace; /* debug trace level (0:off,1-5:debug) */ + double nmeaintv[2]; /* nmea output interval (s) (<0:no,0:all) */ + /* nmeaintv[0]:gprmc,gpgga,nmeaintv[1]:gpgsv */ + char sep[64]; /* field separator */ + char prog[64]; /* program name */ + double maxsolstd; /* max std-dev for solution output (m) (0:all) */ } solopt_t; -typedef struct { /* file options type */ - char satantp[MAXSTRPATH]; /* satellite antenna parameters file */ - char rcvantp[MAXSTRPATH]; /* receiver antenna parameters file */ - char stapos [MAXSTRPATH]; /* station positions file */ - char geoid [MAXSTRPATH]; /* external geoid data file */ - char iono [MAXSTRPATH]; /* ionosphere data file */ - char dcb [MAXSTRPATH]; /* dcb data file */ - char eop [MAXSTRPATH]; /* eop data file */ - char blq [MAXSTRPATH]; /* ocean tide loading blq file */ - char tempdir[MAXSTRPATH]; /* ftp/http temporary directory */ - char geexe [MAXSTRPATH]; /* google earth exec file */ - char solstat[MAXSTRPATH]; /* solution statistics file */ - char trace [MAXSTRPATH]; /* debug trace file */ +typedef struct { /* file options type */ + char satantp[MAXSTRPATH]; /* satellite antenna parameters file */ + char rcvantp[MAXSTRPATH]; /* receiver antenna parameters file */ + char stapos[MAXSTRPATH]; /* station positions file */ + char geoid[MAXSTRPATH]; /* external geoid data file */ + char iono[MAXSTRPATH]; /* ionosphere data file */ + char dcb[MAXSTRPATH]; /* dcb data file */ + char eop[MAXSTRPATH]; /* eop data file */ + char blq[MAXSTRPATH]; /* ocean tide loading blq file */ + char tempdir[MAXSTRPATH]; /* ftp/http temporary directory */ + char geexe[MAXSTRPATH]; /* google earth exec file */ + char solstat[MAXSTRPATH]; /* solution statistics file */ + char trace[MAXSTRPATH]; /* debug trace file */ } filopt_t; -typedef struct { /* RINEX options type */ - gtime_t ts,te; /* time start/end */ - double tint; /* time interval (s) */ - double ttol; /* time tolerance (s) */ - double tunit; /* time unit for multiple-session (s) */ - int rnxver; /* RINEX version (x100) */ - int navsys; /* navigation system, SYS_ mask */ - int obstype; /* observation type */ - int freqtype; /* frequency type */ - /* The mask allocates room for a nul terminator in the last element to - * support access as a string, but it is accessed randomly and must be full - * length. */ - char mask[RNX_NUMSYS][MAXCODE+1]; /* code mask {GPS,GLO,GAL,QZS,SBS,CMP,IRN} */ - char staid [32]; /* station id for rinex file name */ - char prog [32]; /* program */ - char runby [32]; /* run-by */ - char marker[64]; /* marker name */ - char markerno[32]; /* marker number */ - char markertype[32]; /* marker type (ver.3) */ - char name[2][32]; /* observer/agency */ - char rec [3][32]; /* receiver #/type/vers */ - char ant [3][32]; /* antenna #/type */ - double apppos[3]; /* approx position x/y/z */ - double antdel[3]; /* antenna delta h/e/n */ - double glo_cp_bias[4]; /* GLONASS code-phase biases (m) */ - char comment[MAXCOMMENT][64]; /* comments */ - char rcvopt[256]; /* receiver dependent options */ - uint8_t exsats[MAXSAT]; /* excluded satellites */ - int glofcn[32]; /* glonass fcn+8 */ - int outiono; /* output iono correction */ - int outtime; /* output time system correction */ - int outleaps; /* output leap seconds */ - int autopos; /* auto approx position */ - int phshift; /* phase shift correction */ - int halfcyc; /* half cycle correction */ - int sortsats; /* Sort by satellite index */ - int sep_nav; /* separated nav files */ - gtime_t tstart; /* first obs time */ - gtime_t tend; /* last obs time */ - gtime_t trtcm; /* approx log start time for rtcm */ - char tobs[RNX_NUMSYS][MAXOBSTYPE][4]; /* obs types {GPS,GLO,GAL,QZS,SBS,CMP,IRN} */ - double shift[RNX_NUMSYS][MAXOBSTYPE]; /* phase shift (cyc) {GPS,GLO,GAL,QZS,SBS,CMP,IRN} */ - int nobs[RNX_NUMSYS]; /* number of obs types {GPS,GLO,GAL,QZS,SBS,CMP,IRN} */ +typedef struct { /* RINEX options type */ + gtime_t ts, te; /* time start/end */ + double tint; /* time interval (s) */ + double ttol; /* time tolerance (s) */ + double tunit; /* time unit for multiple-session (s) */ + int rnxver; /* RINEX version (x100) */ + int navsys; /* navigation system, SYS_ mask */ + int obstype; /* observation type */ + int freqtype; /* frequency type */ + /* The mask allocates room for a nul terminator in the last element to + * support access as a string, but it is accessed randomly and must be full + * length. */ + char mask[RNX_NUMSYS][MAXCODE + 1]; /* code mask {GPS,GLO,GAL,QZS,SBS,CMP,IRN} */ + char staid[32]; /* station id for rinex file name */ + char prog[32]; /* program */ + char runby[32]; /* run-by */ + char marker[64]; /* marker name */ + char markerno[32]; /* marker number */ + char markertype[32]; /* marker type (ver.3) */ + char name[2][32]; /* observer/agency */ + char rec[3][32]; /* receiver #/type/vers */ + char ant[3][32]; /* antenna #/type */ + double apppos[3]; /* approx position x/y/z */ + double antdel[3]; /* antenna delta h/e/n */ + double glo_cp_bias[4]; /* GLONASS code-phase biases (m) */ + char comment[MAXCOMMENT][64]; /* comments */ + char rcvopt[256]; /* receiver dependent options */ + uint8_t exsats[MAXSAT]; /* excluded satellites */ + int glofcn[32]; /* glonass fcn+8 */ + int outiono; /* output iono correction */ + int outtime; /* output time system correction */ + int outleaps; /* output leap seconds */ + int autopos; /* auto approx position */ + int phshift; /* phase shift correction */ + int halfcyc; /* half cycle correction */ + int sortsats; /* Sort by satellite index */ + int sep_nav; /* separated nav files */ + gtime_t tstart; /* first obs time */ + gtime_t tend; /* last obs time */ + gtime_t trtcm; /* approx log start time for rtcm */ + char tobs[RNX_NUMSYS][MAXOBSTYPE][4]; /* obs types {GPS,GLO,GAL,QZS,SBS,CMP,IRN} */ + double shift[RNX_NUMSYS][MAXOBSTYPE]; /* phase shift (cyc) {GPS,GLO,GAL,QZS,SBS,CMP,IRN} */ + int nobs[RNX_NUMSYS]; /* number of obs types {GPS,GLO,GAL,QZS,SBS,CMP,IRN} */ } rnxopt_t; -typedef struct { /* satellite status type */ - uint8_t sys; /* navigation system */ - uint8_t vs; /* valid satellite flag single */ - double azel[2]; /* azimuth/elevation angles {az,el} (rad) */ - double resp[NFREQ]; /* residuals of pseudorange (m) */ - double resc[NFREQ]; /* residuals of carrier-phase (m) */ - double icbias[NFREQ]; /* glonass IC bias (cycles) */ - uint8_t vsat[NFREQ]; /* valid satellite flag */ - float snr_rover [NFREQ]; /* rover signal strength (dBHz) */ - float snr_base [NFREQ]; /* base signal strength (dBHz) */ - uint8_t fix [NFREQ]; /* ambiguity fix flag (1:float,2:fix,3:hold) */ - int code[NFREQ][2]; // Current code per frequency index for the base and rover. - uint8_t slip[NFREQ]; /* cycle-slip flag */ - uint8_t half[NFREQ]; /* half-cycle valid flag */ - int lock [NFREQ]; /* lock counter of phase */ - uint32_t outc [NFREQ]; /* obs outage counter of phase */ - uint32_t slipc[NFREQ]; /* cycle-slip counter */ - uint32_t rejc [NFREQ]; /* reject counter */ - double gf[NFREQ-1]; /* geometry-free phase (m) */ - double mw[NFREQ-1]; /* MW-LC (m) */ - double phw; /* phase windup (cycle) */ - gtime_t pt[2][NFREQ]; /* previous carrier-phase time */ - double ph[2][NFREQ]; /* previous carrier-phase observable (cycle) */ +typedef struct { /* satellite status type */ + uint8_t sys; /* navigation system */ + uint8_t vs; /* valid satellite flag single */ + double azel[2]; /* azimuth/elevation angles {az,el} (rad) */ + double resp[NFREQ]; /* residuals of pseudorange (m) */ + double resc[NFREQ]; /* residuals of carrier-phase (m) */ + double icbias[NFREQ]; /* glonass IC bias (cycles) */ + uint8_t vsat[NFREQ]; /* valid satellite flag */ + float snr_rover[NFREQ]; /* rover signal strength (dBHz) */ + float snr_base[NFREQ]; /* base signal strength (dBHz) */ + uint8_t fix[NFREQ]; /* ambiguity fix flag (1:float,2:fix,3:hold) */ + int code[NFREQ][2]; // Current code per frequency index for the base and rover. + uint8_t slip[NFREQ]; /* cycle-slip flag */ + uint8_t half[NFREQ]; /* half-cycle valid flag */ + int lock[NFREQ]; /* lock counter of phase */ + uint32_t outc[NFREQ]; /* obs outage counter of phase */ + uint32_t slipc[NFREQ]; /* cycle-slip counter */ + uint32_t rejc[NFREQ]; /* reject counter */ + double gf[NFREQ - 1]; /* geometry-free phase (m) */ + double mw[NFREQ - 1]; /* MW-LC (m) */ + double phw; /* phase windup (cycle) */ + gtime_t pt[2][NFREQ]; /* previous carrier-phase time */ + double ph[2][NFREQ]; /* previous carrier-phase observable (cycle) */ } ssat_t; -typedef struct { /* ambiguity control type */ - gtime_t epoch[4]; /* last epoch */ - int n[4]; /* number of epochs */ - double LC [4]; /* linear combination average */ - double LCv[4]; /* linear combination variance */ - int fixcnt; /* fix count */ - char flags[MAXSAT]; /* fix flags */ +typedef struct { /* ambiguity control type */ + gtime_t epoch[4]; /* last epoch */ + int n[4]; /* number of epochs */ + double LC[4]; /* linear combination average */ + double LCv[4]; /* linear combination variance */ + int fixcnt; /* fix count */ + char flags[MAXSAT]; /* fix flags */ } ambc_t; -typedef struct { /* RTK control/result type */ - sol_t sol; /* RTK solution */ - double rb[6]; /* base position/velocity (ecef) (m|m/s) */ - int nx,na; /* number of float states/fixed states */ - double tt; /* time difference between current and previous (s) */ - double *x, *P; /* float states and their covariance */ - double *xa,*Pa; /* fixed states and their covariance */ - int nfix; /* number of continuous fixes of ambiguity */ - int excsat; /* index of next satellite to be excluded for partial ambiguity resolution */ - int nb_ar; /* number of ambiguities used for AR last epoch */ - char holdamb; /* set if fix-and-hold has occurred at least once */ - ambc_t ambc[MAXSAT]; /* ambiguity control */ - ssat_t ssat[MAXSAT]; /* satellite status */ - int neb; /* bytes in error message buffer */ - char errbuf[MAXERRMSG]; /* error message buffer */ - prcopt_t opt; /* processing options */ - int initial_mode; /* initial positioning mode */ - int epoch; /* epoch number */ - int intpres_nb; // Time interpolation of residuals, number of previous base observations. - obsd_t intpres_obsb[MAXOBS]; // Time interpolation of residuals, previous base observations. +typedef struct { /* RTK control/result type */ + sol_t sol; /* RTK solution */ + double rb[6]; /* base position/velocity (ecef) (m|m/s) */ + int nx, na; /* number of float states/fixed states */ + double tt; /* time difference between current and previous (s) */ + double *x, *P; /* float states and their covariance */ + double *xa, *Pa; /* fixed states and their covariance */ + int nfix; /* number of continuous fixes of ambiguity */ + int excsat; /* index of next satellite to be excluded for partial ambiguity resolution */ + int nb_ar; /* number of ambiguities used for AR last epoch */ + char holdamb; /* set if fix-and-hold has occurred at least once */ + ambc_t ambc[MAXSAT]; /* ambiguity control */ + ssat_t ssat[MAXSAT]; /* satellite status */ + int neb; /* bytes in error message buffer */ + char errbuf[MAXERRMSG]; /* error message buffer */ + prcopt_t opt; /* processing options */ + int initial_mode; /* initial positioning mode */ + int epoch; /* epoch number */ + int intpres_nb; // Time interpolation of residuals, number of previous base observations. + obsd_t intpres_obsb[MAXOBS]; // Time interpolation of residuals, previous base observations. } rtk_t; -typedef struct { /* receiver raw data control type */ - gtime_t time; /* message time */ - gtime_t tobs[MAXSAT][NFREQ+NEXOBS]; /* observation data time */ - obs_t obs; /* observation data */ - obs_t obuf; /* observation data buffer */ - nav_t nav; /* satellite ephemerides */ - sta_t sta; /* station parameters */ - int ephsat; /* update satellite of ephemeris (0:no satellite) */ - int ephset; /* update set of ephemeris (0-1) */ - sbsmsg_t sbsmsg; /* SBAS message */ - char msgtype[256]; /* last message type */ - uint8_t subfrm[MAXSAT][380]; /* subframe buffer */ - double lockt[MAXSAT][NFREQ+NEXOBS]; /* lock time (s) */ - unsigned char lockflag[MAXSAT][NFREQ+NEXOBS]; /* used for carrying forward cycle slip */ - double icpp[MAXSAT],off[MAXSAT],icpc; /* carrier params for ss2 */ - double prCA[MAXSAT],dpCA[MAXSAT]; /* L1/CA pseudorange/doppler for javad */ - uint8_t halfc[MAXSAT][NFREQ+NEXOBS]; /* half-cycle resolved */ - char freqn[MAXOBS]; /* frequency number for javad */ - int nbyte; /* number of bytes in message buffer */ - int len; /* message length (bytes) */ - int iod; /* issue of data */ - int tod; /* time of day (ms) */ - int tbase; /* time base (0:gpst,1:utc(usno),2:glonass,3:utc(su) */ - int flag; /* general purpose flag */ - int outtype; /* output message type */ - uint8_t buff[MAXRAWLEN]; /* message buffer */ - char opt[256]; /* receiver dependent options */ - int format; /* receiver stream format */ - int rcvtype; /* receiver type within format */ - void *rcv_data; /* receiver dependent data */ +typedef struct { /* receiver raw data control type */ + gtime_t time; /* message time */ + gtime_t tobs[MAXSAT][NFREQ + NEXOBS]; /* observation data time */ + obs_t obs; /* observation data */ + obs_t obuf; /* observation data buffer */ + nav_t nav; /* satellite ephemerides */ + sta_t sta; /* station parameters */ + int ephsat; /* update satellite of ephemeris (0:no satellite) */ + int ephset; /* update set of ephemeris (0-1) */ + sbsmsg_t sbsmsg; /* SBAS message */ + char msgtype[256]; /* last message type */ + uint8_t subfrm[MAXSAT][380]; /* subframe buffer */ + double lockt[MAXSAT][NFREQ + NEXOBS]; /* lock time (s) */ + unsigned char lockflag[MAXSAT][NFREQ + NEXOBS]; /* used for carrying forward cycle slip */ + double icpp[MAXSAT], off[MAXSAT], icpc; /* carrier params for ss2 */ + double prCA[MAXSAT], dpCA[MAXSAT]; /* L1/CA pseudorange/doppler for javad */ + uint8_t halfc[MAXSAT][NFREQ + NEXOBS]; /* half-cycle resolved */ + char freqn[MAXOBS]; /* frequency number for javad */ + int nbyte; /* number of bytes in message buffer */ + int len; /* message length (bytes) */ + int iod; /* issue of data */ + int tod; /* time of day (ms) */ + int tbase; /* time base (0:gpst,1:utc(usno),2:glonass,3:utc(su) */ + int flag; /* general purpose flag */ + int outtype; /* output message type */ + uint8_t buff[MAXRAWLEN]; /* message buffer */ + char opt[256]; /* receiver dependent options */ + int format; /* receiver stream format */ + int rcvtype; /* receiver type within format */ + void *rcv_data; /* receiver dependent data */ } raw_t; -typedef struct { /* stream type */ - int type; /* type (STR_???) */ - int mode; /* mode (STR_MODE_?) */ - int state; /* state (-1:error,0:close,1:open) */ - uint32_t inb,inr; /* input bytes/rate */ - uint32_t outb,outr; /* output bytes/rate */ - uint32_t tick_i; /* input tick tick */ - uint32_t tick_o; /* output tick */ - uint32_t tact; /* active tick */ - uint32_t inbt,outbt; /* input/output bytes at tick */ - rtklib_lock_t lock; /* lock flag */ - void *port; /* type dependent port control struct */ - char path[MAXSTRPATH]; /* stream path */ - char msg [MAXSTRMSG]; /* stream message */ +typedef struct { /* stream type */ + int type; /* type (STR_???) */ + int mode; /* mode (STR_MODE_?) */ + int state; /* state (-1:error,0:close,1:open) */ + uint32_t inb, inr; /* input bytes/rate */ + uint32_t outb, outr; /* output bytes/rate */ + uint32_t tick_i; /* input tick tick */ + uint32_t tick_o; /* output tick */ + uint32_t tact; /* active tick */ + uint32_t inbt, outbt; /* input/output bytes at tick */ + rtklib_lock_t lock; /* lock flag */ + void *port; /* type dependent port control struct */ + char path[MAXSTRPATH]; /* stream path */ + char msg[MAXSTRMSG]; /* stream message */ } stream_t; -typedef struct { /* stream converter type */ - int itype,otype; /* input and output stream type */ - int nmsg; /* number of output messages */ - int msgs[32]; /* output message types */ - double tint[32]; /* output message intervals (s) */ - uint32_t tick[32]; /* cycle tick of output message */ - int ephsat[32]; /* satellites of output ephemeris */ - int stasel; /* station info selection (0:remote,1:local) */ - rtcm_t rtcm; /* rtcm input data buffer */ - raw_t raw; /* raw input data buffer */ - rtcm_t out; /* rtcm output data buffer */ +typedef struct { /* stream converter type */ + int itype, otype; /* input and output stream type */ + int nmsg; /* number of output messages */ + int msgs[32]; /* output message types */ + double tint[32]; /* output message intervals (s) */ + uint32_t tick[32]; /* cycle tick of output message */ + int ephsat[32]; /* satellites of output ephemeris */ + int stasel; /* station info selection (0:remote,1:local) */ + rtcm_t rtcm; /* rtcm input data buffer */ + raw_t raw; /* raw input data buffer */ + rtcm_t out; /* rtcm output data buffer */ } strconv_t; -typedef struct { /* stream server type */ - int state; /* server state (0:stop,1:running) */ - int cycle; /* server cycle (ms) */ - int buffsize; /* input/monitor buffer size (bytes) */ - int nmeacycle; /* NMEA request cycle (ms) (0:no) */ - int relayback; /* relay back of output streams (0:no) */ - int nstr; /* number of streams (1 input + (nstr-1) outputs */ - int npb; /* data length in peek buffer (bytes) */ - char cmds_periodic[16][MAXRCVCMD]; /* periodic commands */ - double nmeapos[3]; /* NMEA request position (ecef) (m) */ - uint8_t *buff; /* input buffers */ - uint8_t *pbuf; /* peek buffer */ - uint32_t tick; /* start tick */ - stream_t stream[16]; /* input/output streams */ - stream_t strlog[16]; /* return log streams */ - strconv_t *conv[16]; /* stream converter */ - rtklib_thread_t thread; /* server thread */ - rtklib_lock_t lock; /* lock flag */ +typedef struct { /* stream server type */ + int state; /* server state (0:stop,1:running) */ + int cycle; /* server cycle (ms) */ + int buffsize; /* input/monitor buffer size (bytes) */ + int nmeacycle; /* NMEA request cycle (ms) (0:no) */ + int relayback; /* relay back of output streams (0:no) */ + int nstr; /* number of streams (1 input + (nstr-1) outputs */ + int npb; /* data length in peek buffer (bytes) */ + char cmds_periodic[16][MAXRCVCMD]; /* periodic commands */ + double nmeapos[3]; /* NMEA request position (ecef) (m) */ + uint8_t *buff; /* input buffers */ + uint8_t *pbuf; /* peek buffer */ + uint32_t tick; /* start tick */ + stream_t stream[16]; /* input/output streams */ + stream_t strlog[16]; /* return log streams */ + strconv_t *conv[16]; /* stream converter */ + rtklib_thread_t thread; /* server thread */ + rtklib_lock_t lock; /* lock flag */ } strsvr_t; -typedef struct { /* RTK server type */ - int state; /* server state (0:stop,1:running) */ - int cycle; /* processing cycle (ms) */ - int nmeacycle; /* NMEA request cycle (ms) (0:no req) */ - int nmeareq; /* NMEA request (0:no,1:nmeapos,2:single sol) */ - double nmeapos[3]; /* NMEA request position (ecef) (m) */ - int buffsize; /* input buffer size (bytes) */ - int format[3]; /* input format {rov,base,corr} */ - solopt_t solopt[2]; /* output solution options {sol1,sol2} */ - int navsel; /* ephemeris select (0:all,1:rover,2:base,3:corr) */ - int nsbs; /* number of sbas message */ - int nsol; /* number of solution buffer */ - rtk_t rtk; /* RTK control/result struct */ - int nb [3]; /* bytes in input buffers {rov,base} */ - int nsb[2]; /* bytes in solution buffers */ - int npb[3]; /* bytes in input peek buffers */ - uint8_t *buff[3]; /* input buffers {rov,base,corr} */ - uint8_t *sbuf[2]; /* output buffers {sol1,sol2} */ - uint8_t *pbuf[3]; /* peek buffers {rov,base,corr} */ - sol_t solbuf[MAXSOLBUF]; /* solution line buffer */ - uint32_t nmsg[3][10]; /* input message counts */ - raw_t raw [3]; /* receiver raw control {rov,base,corr} */ - rtcm_t rtcm[3]; /* RTCM control {rov,base,corr} */ - gtime_t ftime[3]; /* download time {rov,base,corr} */ - char files[3][MAXSTRPATH]; /* download paths {rov,base,corr} */ - obs_t obs[3][MAXOBSBUF]; /* observation data {rov,base,corr} */ - nav_t nav; /* navigation data */ - sbsmsg_t sbsmsg[MAXSBSMSG]; /* SBAS message buffer */ - stream_t stream[8]; /* streams {rov,base,corr,sol1,sol2,logr,logb,logc} */ - stream_t *moni; /* monitor stream */ - uint32_t tick; /* start tick */ - rtklib_thread_t thread; /* server thread */ - int cputime; /* CPU time (ms) for a processing cycle */ - int prcout; /* missing observation data count */ - int nave; /* number of averaging base pos */ - double rb_ave[3]; /* averaging base pos */ - char cmds_periodic[3][MAXRCVCMD]; /* periodic commands */ - char cmd_reset[MAXRCVCMD]; /* reset command */ - double bl_reset; /* baseline length to reset (km) */ - pcvs_t pcvsr; // Receiver antenna parameters. - rtklib_lock_t lock; /* lock flag */ +typedef struct { /* RTK server type */ + int state; /* server state (0:stop,1:running) */ + int cycle; /* processing cycle (ms) */ + int nmeacycle; /* NMEA request cycle (ms) (0:no req) */ + int nmeareq; /* NMEA request (0:no,1:nmeapos,2:single sol) */ + double nmeapos[3]; /* NMEA request position (ecef) (m) */ + int buffsize; /* input buffer size (bytes) */ + int format[3]; /* input format {rov,base,corr} */ + solopt_t solopt[2]; /* output solution options {sol1,sol2} */ + int navsel; /* ephemeris select (0:all,1:rover,2:base,3:corr) */ + int nsbs; /* number of sbas message */ + int nsol; /* number of solution buffer */ + rtk_t rtk; /* RTK control/result struct */ + int nb[3]; /* bytes in input buffers {rov,base} */ + int nsb[2]; /* bytes in solution buffers */ + int npb[3]; /* bytes in input peek buffers */ + uint8_t *buff[3]; /* input buffers {rov,base,corr} */ + uint8_t *sbuf[2]; /* output buffers {sol1,sol2} */ + uint8_t *pbuf[3]; /* peek buffers {rov,base,corr} */ + sol_t solbuf[MAXSOLBUF]; /* solution line buffer */ + uint32_t nmsg[3][10]; /* input message counts */ + raw_t raw[3]; /* receiver raw control {rov,base,corr} */ + rtcm_t rtcm[3]; /* RTCM control {rov,base,corr} */ + gtime_t ftime[3]; /* download time {rov,base,corr} */ + char files[3][MAXSTRPATH]; /* download paths {rov,base,corr} */ + obs_t obs[3][MAXOBSBUF]; /* observation data {rov,base,corr} */ + nav_t nav; /* navigation data */ + sbsmsg_t sbsmsg[MAXSBSMSG]; /* SBAS message buffer */ + stream_t stream[8]; /* streams {rov,base,corr,sol1,sol2,logr,logb,logc} */ + stream_t *moni; /* monitor stream */ + uint32_t tick; /* start tick */ + rtklib_thread_t thread; /* server thread */ + int cputime; /* CPU time (ms) for a processing cycle */ + int prcout; /* missing observation data count */ + int nave; /* number of averaging base pos */ + double rb_ave[3]; /* averaging base pos */ + char cmds_periodic[3][MAXRCVCMD]; /* periodic commands */ + char cmd_reset[MAXRCVCMD]; /* reset command */ + double bl_reset; /* baseline length to reset (km) */ + pcvs_t pcvsr; // Receiver antenna parameters. + rtklib_lock_t lock; /* lock flag */ } rtksvr_t; -typedef struct { /* GIS data point type */ - double pos[3]; /* point data {lat,lon,height} (rad,m) */ +typedef struct { /* GIS data point type */ + double pos[3]; /* point data {lat,lon,height} (rad,m) */ } gis_pnt_t; -typedef struct { /* GIS data polyline type */ - int npnt; /* number of points */ - double bound[4]; /* boundary {lat0,lat1,lon0,lon1} */ - double *pos; /* position data (3 x npnt) */ +typedef struct { /* GIS data polyline type */ + int npnt; /* number of points */ + double bound[4]; /* boundary {lat0,lat1,lon0,lon1} */ + double *pos; /* position data (3 x npnt) */ } gis_poly_t; -typedef struct { /* GIS data polygon type */ - int npnt; /* number of points */ - double bound[4]; /* boundary {lat0,lat1,lon0,lon1} */ - double *pos; /* position data (3 x npnt) */ +typedef struct { /* GIS data polygon type */ + int npnt; /* number of points */ + double bound[4]; /* boundary {lat0,lat1,lon0,lon1} */ + double *pos; /* position data (3 x npnt) */ } gis_polygon_t; typedef struct gisd_tag { /* GIS data list type */ - int type; /* data type (1:point,2:polyline,3:polygon) */ - void *data; /* data body */ - struct gisd_tag *next; /* pointer to next */ + int type; /* data type (1:point,2:polyline,3:polygon) */ + void *data; /* data body */ + struct gisd_tag *next; /* pointer to next */ } gisd_t; -typedef struct { /* GIS type */ - char name[MAXGISLAYER][256]; /* name */ - int flag[MAXGISLAYER]; /* flag */ - gisd_t *data[MAXGISLAYER]; /* gis data list */ - double bound[4]; /* boundary {lat0,lat1,lon0,lon1} */ +typedef struct { /* GIS type */ + char name[MAXGISLAYER][256]; /* name */ + int flag[MAXGISLAYER]; /* flag */ + gisd_t *data[MAXGISLAYER]; /* gis data list */ + double bound[4]; /* boundary {lat0,lat1,lon0,lon1} */ } gis_t; typedef void fatalfunc_t(const char *); /* fatal callback function type */ /* global variables ----------------------------------------------------------*/ -EXPORT extern const double chisqr[]; /* chi-sqr(n) table (alpha=0.001) */ -EXPORT extern const prcopt_t prcopt_default; /* default positioning options */ -EXPORT extern const solopt_t solopt_default; /* default solution output options */ +EXPORT extern const double chisqr[]; /* chi-sqr(n) table (alpha=0.001) */ +EXPORT extern const prcopt_t prcopt_default; /* default positioning options */ +EXPORT extern const solopt_t solopt_default; /* default solution output options */ EXPORT extern const sbsigpband_t igpband1[9][8]; /* SBAS IGP band 0-8 */ EXPORT extern const sbsigpband_t igpband2[2][5]; /* SBAS IGP band 9-10 */ -EXPORT extern const char *formatstrs[]; /* stream format strings */ -EXPORT extern opt_t sysopts[]; /* system options table */ +EXPORT extern const char *formatstrs[]; /* stream format strings */ +EXPORT extern opt_t sysopts[]; /* system options table */ /* satellites, systems, codes functions --------------------------------------*/ -EXPORT int satno (int sys, int prn); -EXPORT int satsys (int sat, int *prn); -EXPORT int satid2no(const char *id); +EXPORT int satno(int sys, int prn); +EXPORT int satsys(int sat, int *prn); +EXPORT int satid2no(const char *id); EXPORT void satno2id(int sat, char id[8]); EXPORT uint8_t obs2code(const char *obs); EXPORT char *code2obs(uint8_t code); EXPORT double code2freq(int sys, uint8_t code, int fcn); EXPORT double sat2freq(int sat, uint8_t code, const nav_t *nav); -EXPORT int code2idx(int sys, uint8_t code); -EXPORT int satexclude(int sat, double var, int svh, const prcopt_t *opt); -EXPORT int testsnr(int base, int freq, double el, double snr, - const snrmask_t *mask); +EXPORT int code2idx(int sys, uint8_t code); +EXPORT int satexclude(int sat, double var, int svh, const prcopt_t *opt); +EXPORT int testsnr(int base, int freq, double el, double snr, const snrmask_t *mask); EXPORT void setcodepri(int sys, int idx, const char *pri); -EXPORT int getcodepri(int sys, uint8_t code, const char *opt); +EXPORT int getcodepri(int sys, uint8_t code, const char *opt); /* matrix and vector functions -----------------------------------------------*/ -EXPORT double *mat (int n, int m); -EXPORT int *imat (int n, int m); +EXPORT double *mat(int n, int m); +EXPORT int *imat(int n, int m); EXPORT double *zeros(int n, int m); -EXPORT double *eye (int n); +EXPORT double *eye(int n); EXPORT double dot2(const double *a, const double *b); EXPORT double dot3(const double *a, const double *b); -EXPORT double dot (const double *a, const double *b, int n); +EXPORT double dot(const double *a, const double *b, int n); EXPORT double norm(const double *a, int n); EXPORT void cross3(const double *a, const double *b, double *c); -EXPORT int normv3(const double *a, double *b); +EXPORT int normv3(const double *a, double *b); EXPORT void matcpy(double *A, const double *B, int n, int m); -EXPORT void matmul(const char *tr, int n, int k, int m, - const double *A, const double *B, double *C); -EXPORT void matmulp(const char *tr, int n, int k, int m, - const double *A, const double *B, double *C); -EXPORT void matmulm(const char *tr, int n, int k, int m, - const double *A, const double *B, double *C); -EXPORT int matinv(double *A, int n); -EXPORT int solve (const char *tr, const double *A, const double *Y, int n, - int m, double *X); -EXPORT int lsq (const double *A, const double *y, int n, int m, double *x, - double *Q); -EXPORT int filter(double *x, double *P, const double *H, const double *v, - const double *R, int n, int m); -EXPORT int smoother(const double *xf, const double *Qf, const double *xb, - const double *Qb, int n, double *xs, double *Qs); -EXPORT void matprint (const double *A, int n, int m, int p, int q); +EXPORT void matmul(const char *tr, int n, int k, int m, const double *A, const double *B, + double *C); +EXPORT void matmulp(const char *tr, int n, int k, int m, const double *A, const double *B, + double *C); +EXPORT void matmulm(const char *tr, int n, int k, int m, const double *A, const double *B, + double *C); +EXPORT int matinv(double *A, int n); +EXPORT int solve(const char *tr, const double *A, const double *Y, int n, int m, double *X); +EXPORT int lsq(const double *A, const double *y, int n, int m, double *x, double *Q); +EXPORT int filter(double *x, double *P, const double *H, const double *v, const double *R, int n, + int m); +EXPORT int smoother(const double *xf, const double *Qf, const double *xb, const double *Qb, int n, + double *xs, double *Qs); +EXPORT void matprint(const double *A, int n, int m, int p, int q); EXPORT void matfprint(const double *A, int n, int m, int p, int q, FILE *fp); EXPORT void add_fatal(fatalfunc_t *func); /* time and string functions -------------------------------------------------*/ -EXPORT void setstr(char *dst, const char *src, int n); -EXPORT double str2num(const char *s, int i, int n); -EXPORT int str2time(const char *s, int i, int n, gtime_t *t); -EXPORT char *time2str(gtime_t t, char str[40], int n); +EXPORT void setstr(char *dst, const char *src, int n); +EXPORT double str2num(const char *s, int i, int n); +EXPORT int str2time(const char *s, int i, int n, gtime_t *t); +EXPORT char *time2str(gtime_t t, char str[40], int n); EXPORT gtime_t epoch2time(const double *ep); -EXPORT void time2epoch(gtime_t t, double *ep); -EXPORT void time2epoch_n(gtime_t t, double *ep, int n); +EXPORT void time2epoch(gtime_t t, double *ep); +EXPORT void time2epoch_n(gtime_t t, double *ep, int n); EXPORT gtime_t gpst2time(int week, double sec); -EXPORT double time2gpst(gtime_t t, int *week); +EXPORT double time2gpst(gtime_t t, int *week); EXPORT gtime_t gst2time(int week, double sec); -EXPORT double time2gst(gtime_t t, int *week); +EXPORT double time2gst(gtime_t t, int *week); EXPORT gtime_t bdt2time(int week, double sec); -EXPORT double time2bdt(gtime_t t, int *week); - -EXPORT gtime_t timeadd (gtime_t t, double sec); -EXPORT double timediff (gtime_t t1, gtime_t t2); -EXPORT gtime_t gpst2utc (gtime_t t); -EXPORT gtime_t utc2gpst (gtime_t t); -EXPORT gtime_t gpst2bdt (gtime_t t); -EXPORT gtime_t bdt2gpst (gtime_t t); -EXPORT gtime_t timeget (void); -EXPORT void timeset (gtime_t t); -EXPORT void timereset(void); -EXPORT double time2doy (gtime_t t); -EXPORT double utc2gmst (gtime_t t, double ut1_utc); +EXPORT double time2bdt(gtime_t t, int *week); + +EXPORT gtime_t timeadd(gtime_t t, double sec); +EXPORT double timediff(gtime_t t1, gtime_t t2); +EXPORT gtime_t gpst2utc(gtime_t t); +EXPORT gtime_t utc2gpst(gtime_t t); +EXPORT gtime_t gpst2bdt(gtime_t t); +EXPORT gtime_t bdt2gpst(gtime_t t); +EXPORT gtime_t timeget(void); +EXPORT void timeset(gtime_t t); +EXPORT void timereset(void); +EXPORT double time2doy(gtime_t t); +EXPORT double utc2gmst(gtime_t t, double ut1_utc); EXPORT int read_leaps(const char *file); EXPORT int adjgpsweek(int week); EXPORT uint32_t tickget(void); EXPORT void sleepms(int ms); -EXPORT int reppath(const char *path, char *rpath, gtime_t time, const char *rov, - const char *base); -EXPORT int reppaths(const char *path, char *rpaths[], int nmax, gtime_t ts, - gtime_t te, const char *rov, const char *base); +EXPORT int reppath(const char *path, char *rpath, gtime_t time, const char *rov, const char *base); +EXPORT int reppaths(const char *path, char *rpaths[], int nmax, gtime_t ts, gtime_t te, + const char *rov, const char *base); /* coordinates transformation ------------------------------------------------*/ EXPORT void ecef2pos(const double *r, double *pos); EXPORT void pos2ecef(const double *pos, double *r); EXPORT void ecef2enu(const double *pos, const double *r, double *e); EXPORT void enu2ecef(const double *pos, const double *e, double *r); -EXPORT void covenu (const double *pos, const double *P, double *Q); -EXPORT void covecef (const double *pos, const double *Q, double *P); -EXPORT void xyz2enu (const double *pos, double *E); +EXPORT void covenu(const double *pos, const double *P, double *Q); +EXPORT void covecef(const double *pos, const double *Q, double *P); +EXPORT void xyz2enu(const double *pos, double *E); EXPORT void eci2ecef(gtime_t tutc, const double *erpv, double *U, double *gmst); -EXPORT void deg2dms (double deg, double *dms, int ndec); +EXPORT void deg2dms(double deg, double *dms, int ndec); EXPORT double dms2deg(const double *dms); /* input and output functions ------------------------------------------------*/ EXPORT void readpos(const char *file, const char *rcv, double *pos); -EXPORT int sortobs(obs_t *obs); +EXPORT int sortobs(obs_t *obs); EXPORT void uniqnav(nav_t *nav); -EXPORT int screent(gtime_t time, gtime_t ts, gtime_t te, double tint); -EXPORT int readnav(const char *file, nav_t *nav); -EXPORT int savenav(const char *file, const nav_t *nav); +EXPORT int screent(gtime_t time, gtime_t ts, gtime_t te, double tint); +EXPORT int readnav(const char *file, nav_t *nav); +EXPORT int savenav(const char *file, const nav_t *nav); EXPORT void freeobs(obs_t *obs); EXPORT void freenav(nav_t *nav, int opt); -EXPORT int readblq(const char *file, const char *sta, double odisp[2][11][3]); -EXPORT int readerp(const char *file, erp_t *erp); -EXPORT int geterp (const erp_t *erp, gtime_t time, double *val); +EXPORT int readblq(const char *file, const char *sta, double odisp[2][11][3]); +EXPORT int readerp(const char *file, erp_t *erp); +EXPORT int geterp(const erp_t *erp, gtime_t time, double *val); /* debug trace functions -----------------------------------------------------*/ #ifdef TRACE -#define trace(level, ...) do { if (level <= gettracelevel()) trace_impl(level, __VA_ARGS__); } while (0) -#define tracet(level, ...) do { if (level <= gettracelevel()) tracet_impl(level, __VA_ARGS__); } while (0) -#define tracemat(level, ...) do { if (level <= gettracelevel()) tracemat_impl(level, __VA_ARGS__); } while (0) -#define traceobs(level, ...) do { if (level <= gettracelevel()) traceobs_impl(level, __VA_ARGS__); } while (0) -#define tracenav(level, ...) do { if (level <= gettracelevel()) tracenav_impl(level, __VA_ARGS__); } while (0) -#define tracegnav(level, ...) do { if (level <= gettracelevel()) tracegnav_impl(level, __VA_ARGS__); } while (0) -#define tracehnav(level, ...) do { if (level <= gettracelevel()) tracehnav_impl(level, __VA_ARGS__); } while (0) -#define tracepeph(level, ...) do { if (level <= gettracelevel()) tracepeph_impl(level, __VA_ARGS__); } while (0) -#define tracepclk(level, ...) do { if (level <= gettracelevel()) tracepclk_impl(level, __VA_ARGS__); } while (0) -#define traceb(level, ...) do { if (level <= gettracelevel()) traceb_impl(level, __VA_ARGS__); } while (0) +#define trace(level, ...) \ + do { \ + if (level <= gettracelevel()) trace_impl(level, __VA_ARGS__); \ + } while (0) +#define tracet(level, ...) \ + do { \ + if (level <= gettracelevel()) tracet_impl(level, __VA_ARGS__); \ + } while (0) +#define tracemat(level, ...) \ + do { \ + if (level <= gettracelevel()) tracemat_impl(level, __VA_ARGS__); \ + } while (0) +#define traceobs(level, ...) \ + do { \ + if (level <= gettracelevel()) traceobs_impl(level, __VA_ARGS__); \ + } while (0) +#define tracenav(level, ...) \ + do { \ + if (level <= gettracelevel()) tracenav_impl(level, __VA_ARGS__); \ + } while (0) +#define tracegnav(level, ...) \ + do { \ + if (level <= gettracelevel()) tracegnav_impl(level, __VA_ARGS__); \ + } while (0) +#define tracehnav(level, ...) \ + do { \ + if (level <= gettracelevel()) tracehnav_impl(level, __VA_ARGS__); \ + } while (0) +#define tracepeph(level, ...) \ + do { \ + if (level <= gettracelevel()) tracepeph_impl(level, __VA_ARGS__); \ + } while (0) +#define tracepclk(level, ...) \ + do { \ + if (level <= gettracelevel()) tracepclk_impl(level, __VA_ARGS__); \ + } while (0) +#define traceb(level, ...) \ + do { \ + if (level <= gettracelevel()) traceb_impl(level, __VA_ARGS__); \ + } while (0) EXPORT void traceopen(const char *file); EXPORT void traceclose(void); EXPORT void tracelevel(int level); EXPORT int gettracelevel(void); -EXPORT void trace_impl (int level, const char *format, ...); -EXPORT void tracet_impl (int level, const char *format, ...); -EXPORT void tracemat_impl (int level, const double *A, int n, int m, int p, int q); -EXPORT void traceobs_impl (int level, const obsd_t *obs, int n); -EXPORT void tracenav_impl (int level, const nav_t *nav); +EXPORT void trace_impl(int level, const char *format, ...); +EXPORT void tracet_impl(int level, const char *format, ...); +EXPORT void tracemat_impl(int level, const double *A, int n, int m, int p, int q); +EXPORT void traceobs_impl(int level, const obsd_t *obs, int n); +EXPORT void tracenav_impl(int level, const nav_t *nav); EXPORT void tracegnav_impl(int level, const nav_t *nav); EXPORT void tracehnav_impl(int level, const nav_t *nav); EXPORT void tracepeph_impl(int level, const nav_t *nav); EXPORT void tracepclk_impl(int level, const nav_t *nav); -EXPORT void traceb_impl (int level, const uint8_t *p, int n); +EXPORT void traceb_impl(int level, const uint8_t *p, int n); #else -#define traceopen(file) ((void)0) -#define traceclose() ((void)0) -#define tracelevel(level) ((void)0) +#define traceopen(file) ((void)0) +#define traceclose() ((void)0) +#define tracelevel(level) ((void)0) #define gettracelevel() 0 -#define trace(level, ...) ((void)0) -#define tracet(level, ...) ((void)0) -#define tracemat(level, ...) ((void)0) -#define traceobs(level, ...) ((void)0) -#define tracenav(level, ...) ((void)0) +#define trace(level, ...) ((void)0) +#define tracet(level, ...) ((void)0) +#define tracemat(level, ...) ((void)0) +#define traceobs(level, ...) ((void)0) +#define tracenav(level, ...) ((void)0) #define tracegnav(level, ...) ((void)0) #define tracehnav(level, ...) ((void)0) #define tracepeph(level, ...) ((void)0) #define tracepclk(level, ...) ((void)0) -#define traceb(level, ...) ((void)0) +#define traceb(level, ...) ((void)0) #endif /* TRACE */ /* platform dependent functions ----------------------------------------------*/ EXPORT int execcmd(const char *cmd); -EXPORT int expath (const char *path, char *paths[], int nmax); +EXPORT int expath(const char *path, char *paths[], int nmax); EXPORT void createdir(const char *path); /* positioning models --------------------------------------------------------*/ @@ -1556,36 +1584,30 @@ EXPORT double geodist(const double *rs, const double *rr, double *e); EXPORT void dops(int ns, const double *azel, double elmin, double *dop); /* atmosphere models ---------------------------------------------------------*/ -EXPORT double ionmodel(gtime_t t, const double *ion, const double *pos, - const double *azel); +EXPORT double ionmodel(gtime_t t, const double *ion, const double *pos, const double *azel); EXPORT double ionmapf(const double *pos, const double *azel); -EXPORT double ionppp(const double *pos, const double *azel, double re, - double hion, double *pppos); -EXPORT double tropmodel(gtime_t time, const double *pos, const double *azel, - double humi); -EXPORT double tropmapf(gtime_t time, const double *pos, const double *azel, - double *mapfw); -EXPORT int iontec(gtime_t time, const nav_t *nav, const double *pos, - const double *azel, int opt, double *delay, double *var); +EXPORT double ionppp(const double *pos, const double *azel, double re, double hion, double *pppos); +EXPORT double tropmodel(gtime_t time, const double *pos, const double *azel, double humi); +EXPORT double tropmapf(gtime_t time, const double *pos, const double *azel, double *mapfw); +EXPORT int iontec(gtime_t time, const nav_t *nav, const double *pos, const double *azel, int opt, + double *delay, double *var); EXPORT void readtec(const char *file, nav_t *nav, int opt); -EXPORT int ionocorr(gtime_t time, const nav_t *nav, int sat, const double *pos, - const double *azel, int ionoopt, double *ion, double *var); -EXPORT int tropcorr(gtime_t time, const nav_t *nav, const double *pos, - const double *azel, int tropopt, double *trp, double *var); +EXPORT int ionocorr(gtime_t time, const nav_t *nav, int sat, const double *pos, const double *azel, + int ionoopt, double *ion, double *var); +EXPORT int tropcorr(gtime_t time, const nav_t *nav, const double *pos, const double *azel, + int tropopt, double *trp, double *var); EXPORT int seliflc(int optnf, int sys); /* antenna models ------------------------------------------------------------*/ -EXPORT int readpcv(const char *file, pcvs_t *pcvs); -EXPORT pcv_t *searchpcv(int sat, const char *type, gtime_t time, - const pcvs_t *pcvs); -EXPORT void antmodel(const pcv_t *pcv, const double *del, const double *azel, - int opt, double *dant); +EXPORT int readpcv(const char *file, pcvs_t *pcvs); +EXPORT pcv_t *searchpcv(int sat, const char *type, gtime_t time, const pcvs_t *pcvs); +EXPORT void antmodel(const pcv_t *pcv, const double *del, const double *azel, int opt, + double *dant); EXPORT void antmodel_s(const pcv_t *pcv, double nadir, double *dant); EXPORT void free_pcvs(pcvs_t *pcvs); /* earth tide models ---------------------------------------------------------*/ -EXPORT void sunmoonpos(gtime_t tutc, const double *erpv, double *rsun, - double *rmoon, double *gmst); +EXPORT void sunmoonpos(gtime_t tutc, const double *erpv, double *rsun, double *rmoon, double *gmst); EXPORT void tidedisp(gtime_t tutc, const double *rr, int opt, const erp_t *erp, const double odisp[2][11][3], double *dr); @@ -1600,140 +1622,127 @@ EXPORT int tokyo2jgd(double *pos); EXPORT int jgd2tokyo(double *pos); /* rinex functions -----------------------------------------------------------*/ -EXPORT int readrnx (const char *file, int rcv, const char *opt, obs_t *obs, - nav_t *nav, sta_t *sta); -EXPORT int readrnxt(const char *file, int rcv, gtime_t ts, gtime_t te, - double tint, const char *opt, obs_t *obs, nav_t *nav, - sta_t *sta); +EXPORT int readrnx(const char *file, int rcv, const char *opt, obs_t *obs, nav_t *nav, sta_t *sta); +EXPORT int readrnxt(const char *file, int rcv, gtime_t ts, gtime_t te, double tint, const char *opt, + obs_t *obs, nav_t *nav, sta_t *sta); EXPORT int readrnxc(const char *file, nav_t *nav); EXPORT int outrnxobsh(FILE *fp, const rnxopt_t *opt, const nav_t *nav); -EXPORT int outrnxobsb(FILE *fp, const rnxopt_t *opt, const obsd_t *obs, int n, - int epflag); -EXPORT int outrnxnavh (FILE *fp, const rnxopt_t *opt, const nav_t *nav); +EXPORT int outrnxobsb(FILE *fp, const rnxopt_t *opt, const obsd_t *obs, int n, int epflag); +EXPORT int outrnxnavh(FILE *fp, const rnxopt_t *opt, const nav_t *nav); EXPORT int outrnxgnavh(FILE *fp, const rnxopt_t *opt, const nav_t *nav); EXPORT int outrnxhnavh(FILE *fp, const rnxopt_t *opt, const nav_t *nav); EXPORT int outrnxlnavh(FILE *fp, const rnxopt_t *opt, const nav_t *nav); EXPORT int outrnxqnavh(FILE *fp, const rnxopt_t *opt, const nav_t *nav); EXPORT int outrnxcnavh(FILE *fp, const rnxopt_t *opt, const nav_t *nav); EXPORT int outrnxinavh(FILE *fp, const rnxopt_t *opt, const nav_t *nav); -EXPORT int outrnxnavb (FILE *fp, const rnxopt_t *opt, const eph_t *eph); +EXPORT int outrnxnavb(FILE *fp, const rnxopt_t *opt, const eph_t *eph); EXPORT int outrnxgnavb(FILE *fp, const rnxopt_t *opt, const geph_t *geph); EXPORT int outrnxhnavb(FILE *fp, const rnxopt_t *opt, const seph_t *seph); EXPORT int rnxcomment(rnxopt_t *opt, const char *format, ...); EXPORT int rtk_uncompress(const char *file, char *uncfile); EXPORT int convrnx(int format, rnxopt_t *opt, const char *file, char **ofile); -EXPORT int init_rnxctr (rnxctr_t *rnx); -EXPORT void free_rnxctr (rnxctr_t *rnx); -EXPORT int open_rnxctr (rnxctr_t *rnx, FILE *fp); -EXPORT int input_rnxctr(rnxctr_t *rnx, FILE *fp); +EXPORT int init_rnxctr(rnxctr_t *rnx); +EXPORT void free_rnxctr(rnxctr_t *rnx); +EXPORT int open_rnxctr(rnxctr_t *rnx, FILE *fp); +EXPORT int input_rnxctr(rnxctr_t *rnx, FILE *fp); /* ephemeris and clock functions ---------------------------------------------*/ -EXPORT double eph2clk (gtime_t time, const eph_t *eph); +EXPORT double eph2clk(gtime_t time, const eph_t *eph); EXPORT double geph2clk(gtime_t time, const geph_t *geph); EXPORT double seph2clk(gtime_t time, const seph_t *seph); -EXPORT void eph2pos (gtime_t time, const eph_t *eph, double *rs, double *dts, - double *var); -EXPORT void geph2pos(gtime_t time, const geph_t *geph, double *rs, double *dts, - double *var); -EXPORT void seph2pos(gtime_t time, const seph_t *seph, double *rs, double *dts, - double *var); -EXPORT int peph2pos(gtime_t time, int sat, const nav_t *nav, int opt, - double *rs, double *dts, double *var); -EXPORT void satantoff(gtime_t time, const double *rs, int sat, const nav_t *nav, - double *dant); -EXPORT int satpos(gtime_t time, gtime_t teph, int sat, int ephopt, - const nav_t *nav, double *rs, double *dts, double *var, - int *svh); -EXPORT void satposs(gtime_t time, const obsd_t *obs, int n, const nav_t *nav, - int sateph, double *rs, double *dts, double *var, int *svh); +EXPORT void eph2pos(gtime_t time, const eph_t *eph, double *rs, double *dts, double *var); +EXPORT void geph2pos(gtime_t time, const geph_t *geph, double *rs, double *dts, double *var); +EXPORT void seph2pos(gtime_t time, const seph_t *seph, double *rs, double *dts, double *var); +EXPORT int peph2pos(gtime_t time, int sat, const nav_t *nav, int opt, double *rs, double *dts, + double *var); +EXPORT void satantoff(gtime_t time, const double *rs, int sat, const nav_t *nav, double *dant); +EXPORT int satpos(gtime_t time, gtime_t teph, int sat, int ephopt, const nav_t *nav, double *rs, + double *dts, double *var, int *svh); +EXPORT void satposs(gtime_t time, const obsd_t *obs, int n, const nav_t *nav, int sateph, + double *rs, double *dts, double *var, int *svh); EXPORT void setseleph(int sys, int sel); -EXPORT int getseleph(int sys); +EXPORT int getseleph(int sys); EXPORT void readsp3(const char *file, nav_t *nav, int opt); -EXPORT int readsap(const char *file, gtime_t time, nav_t *nav); -EXPORT int readdcb(const char *file, nav_t *nav, const sta_t *sta); -EXPORT int code2bias_ix(const int sys,const int code); +EXPORT int readsap(const char *file, gtime_t time, nav_t *nav); +EXPORT int readdcb(const char *file, nav_t *nav, const sta_t *sta); +EXPORT int code2bias_ix(const int sys, const int code); /*EXPORT int readfcb(const char *file, nav_t *nav);*/ EXPORT void alm2pos(gtime_t time, const alm_t *alm, double *rs, double *dts); EXPORT int tle_read(const char *file, tle_t *tle); EXPORT int tle_name_read(const char *file, tle_t *tle); -EXPORT int tle_pos(gtime_t time, const char *name, const char *satno, - const char *desig, const tle_t *tle, const erp_t *erp, - double *rs); +EXPORT int tle_pos(gtime_t time, const char *name, const char *satno, const char *desig, + const tle_t *tle, const erp_t *erp, double *rs); /* receiver raw data functions -----------------------------------------------*/ EXPORT uint32_t getbitu(const uint8_t *buff, int pos, int len); -EXPORT int32_t getbits(const uint8_t *buff, int pos, int len); +EXPORT int32_t getbits(const uint8_t *buff, int pos, int len); EXPORT void setbitu(uint8_t *buff, int pos, int len, uint32_t data); -EXPORT void setbits(uint8_t *buff, int pos, int len, int32_t data); -EXPORT uint32_t rtk_crc32 (const uint8_t *buff, int len); +EXPORT void setbits(uint8_t *buff, int pos, int len, int32_t data); +EXPORT uint32_t rtk_crc32(const uint8_t *buff, int len); EXPORT uint32_t rtk_crc24q(const uint8_t *buff, int len); -EXPORT uint16_t rtk_crc16 (const uint8_t *buff, int len); -EXPORT int decode_word (uint32_t word, uint8_t *data); -EXPORT int decode_frame(const uint8_t *buff, int sys, eph_t *eph, alm_t *alm, - double *ion, double *utc); +EXPORT uint16_t rtk_crc16(const uint8_t *buff, int len); +EXPORT int decode_word(uint32_t word, uint8_t *data); +EXPORT int decode_frame(const uint8_t *buff, int sys, eph_t *eph, alm_t *alm, double *ion, + double *utc); EXPORT int test_glostr(const uint8_t *buff); EXPORT int decode_glostr(const uint8_t *buff, geph_t *geph, double *utc); -EXPORT int decode_bds_d1(const uint8_t *buff, eph_t *eph, double *ion, - double *utc); +EXPORT int decode_bds_d1(const uint8_t *buff, eph_t *eph, double *ion, double *utc); EXPORT int decode_bds_d2(const uint8_t *buff, eph_t *eph, double *utc); -EXPORT int decode_gal_inav(const uint8_t *buff, eph_t *eph, double *ion, - double *utc); -EXPORT int decode_gal_fnav(const uint8_t *buff, eph_t *eph, double *ion, - double *utc); -EXPORT int decode_irn_nav(const uint8_t *buff, eph_t *eph, double *ion, - double *utc); - -EXPORT int init_raw (raw_t *raw, int format); -EXPORT void free_raw (raw_t *raw); -EXPORT int input_raw (raw_t *raw, int format, uint8_t data); -EXPORT int input_rawf (raw_t *raw, int format, FILE *fp); - -EXPORT int init_rt17 (raw_t *raw); -EXPORT int init_sbf (raw_t *raw); -EXPORT void free_rt17 (raw_t *raw); -EXPORT void free_sbf (raw_t *raw); - -EXPORT int input_oem4 (raw_t *raw, uint8_t data); -EXPORT int input_cnav (raw_t *raw, uint8_t data); -EXPORT int input_ubx (raw_t *raw, uint8_t data); -EXPORT int input_sbp (raw_t *raw, uint8_t data); -EXPORT int input_cres (raw_t *raw, uint8_t data); -EXPORT int input_stq (raw_t *raw, uint8_t data); -EXPORT int input_javad (raw_t *raw, uint8_t data); -EXPORT int input_nvs (raw_t *raw, uint8_t data); -EXPORT int input_bnx (raw_t *raw, uint8_t data); -EXPORT int input_rt17 (raw_t *raw, uint8_t data); -EXPORT int input_sbf (raw_t *raw, uint8_t data); +EXPORT int decode_gal_inav(const uint8_t *buff, eph_t *eph, double *ion, double *utc); +EXPORT int decode_gal_fnav(const uint8_t *buff, eph_t *eph, double *ion, double *utc); +EXPORT int decode_irn_nav(const uint8_t *buff, eph_t *eph, double *ion, double *utc); + +EXPORT int init_raw(raw_t *raw, int format); +EXPORT void free_raw(raw_t *raw); +EXPORT int input_raw(raw_t *raw, int format, uint8_t data); +EXPORT int input_rawf(raw_t *raw, int format, FILE *fp); + +EXPORT int init_rt17(raw_t *raw); +EXPORT int init_sbf(raw_t *raw); +EXPORT void free_rt17(raw_t *raw); +EXPORT void free_sbf(raw_t *raw); + +EXPORT int input_oem4(raw_t *raw, uint8_t data); +EXPORT int input_cnav(raw_t *raw, uint8_t data); +EXPORT int input_ubx(raw_t *raw, uint8_t data); +EXPORT int input_sbp(raw_t *raw, uint8_t data); +EXPORT int input_cres(raw_t *raw, uint8_t data); +EXPORT int input_stq(raw_t *raw, uint8_t data); +EXPORT int input_javad(raw_t *raw, uint8_t data); +EXPORT int input_nvs(raw_t *raw, uint8_t data); +EXPORT int input_bnx(raw_t *raw, uint8_t data); +EXPORT int input_rt17(raw_t *raw, uint8_t data); +EXPORT int input_sbf(raw_t *raw, uint8_t data); EXPORT int input_tersus(raw_t *raw, uint8_t data); EXPORT int input_unicore(raw_t *raw, uint8_t data); -EXPORT int input_oem4f (raw_t *raw, FILE *fp); -EXPORT int input_cnavf (raw_t *raw, FILE *fp); -EXPORT int input_ubxf (raw_t *raw, FILE *fp); -EXPORT int input_sbpf (raw_t *raw, FILE *fp); -EXPORT int input_cresf (raw_t *raw, FILE *fp); -EXPORT int input_stqf (raw_t *raw, FILE *fp); +EXPORT int input_oem4f(raw_t *raw, FILE *fp); +EXPORT int input_cnavf(raw_t *raw, FILE *fp); +EXPORT int input_ubxf(raw_t *raw, FILE *fp); +EXPORT int input_sbpf(raw_t *raw, FILE *fp); +EXPORT int input_cresf(raw_t *raw, FILE *fp); +EXPORT int input_stqf(raw_t *raw, FILE *fp); EXPORT int input_javadf(raw_t *raw, FILE *fp); -EXPORT int input_nvsf (raw_t *raw, FILE *fp); -EXPORT int input_bnxf (raw_t *raw, FILE *fp); -EXPORT int input_rt17f (raw_t *raw, FILE *fp); -EXPORT int input_sbff (raw_t *raw, FILE *fp); +EXPORT int input_nvsf(raw_t *raw, FILE *fp); +EXPORT int input_bnxf(raw_t *raw, FILE *fp); +EXPORT int input_rt17f(raw_t *raw, FILE *fp); +EXPORT int input_sbff(raw_t *raw, FILE *fp); EXPORT int input_tersusf(raw_t *raw, FILE *fp); EXPORT int input_unicoref(raw_t *raw, FILE *fp); -EXPORT int gen_ubx (const char *msg, uint8_t *buff); -EXPORT int gen_stq (const char *msg, uint8_t *buff); -EXPORT int gen_nvs (const char *msg, uint8_t *buff); +EXPORT int gen_ubx(const char *msg, uint8_t *buff); +EXPORT int gen_stq(const char *msg, uint8_t *buff); +EXPORT int gen_nvs(const char *msg, uint8_t *buff); /* rtcm functions ------------------------------------------------------------*/ -EXPORT int init_rtcm (rtcm_t *rtcm); -EXPORT void free_rtcm (rtcm_t *rtcm); -EXPORT int input_rtcm2 (rtcm_t *rtcm, uint8_t data); -EXPORT int input_rtcm3 (rtcm_t *rtcm, uint8_t data); +EXPORT int init_rtcm(rtcm_t *rtcm); +EXPORT void free_rtcm(rtcm_t *rtcm); +EXPORT int input_rtcm2(rtcm_t *rtcm, uint8_t data); +EXPORT int input_rtcm3(rtcm_t *rtcm, uint8_t data); EXPORT int input_rtcm2f(rtcm_t *rtcm, FILE *fp); EXPORT int input_rtcm3f(rtcm_t *rtcm, FILE *fp); -EXPORT int gen_rtcm2 (rtcm_t *rtcm, int type, int sync); -EXPORT int gen_rtcm3 (rtcm_t *rtcm, int type, int subtype, int sync); +EXPORT int gen_rtcm2(rtcm_t *rtcm, int type, int sync); +EXPORT int gen_rtcm3(rtcm_t *rtcm, int type, int subtype, int sync); /* solution functions --------------------------------------------------------*/ EXPORT void initsolbuf(solbuf_t *solbuf, int cyclic, int nmax); @@ -1741,63 +1750,54 @@ EXPORT void freesolbuf(solbuf_t *solbuf); EXPORT void freesolstatbuf(solstatbuf_t *solstatbuf); EXPORT sol_t *getsol(solbuf_t *solbuf, int index); EXPORT int addsol(solbuf_t *solbuf, const sol_t *sol); -EXPORT int readsol (const char *files[], int nfile, solbuf_t *sol); -EXPORT int readsolt(const char *files[], int nfile, gtime_t ts, gtime_t te, - double tint, int qflag, int mean, solbuf_t *sol); +EXPORT int readsol(const char *files[], int nfile, solbuf_t *sol); +EXPORT int readsolt(const char *files[], int nfile, gtime_t ts, gtime_t te, double tint, int qflag, + int mean, solbuf_t *sol); EXPORT int readsolstat(const char *files[], int nfile, solstatbuf_t *statbuf); -EXPORT int readsolstatt(const char *files[], int nfile, gtime_t ts, gtime_t te, - double tint, solstatbuf_t *statbuf); -EXPORT int inputsol(uint8_t data, gtime_t ts, gtime_t te, double tint, - int qflag, const solopt_t *opt, solbuf_t *solbuf); +EXPORT int readsolstatt(const char *files[], int nfile, gtime_t ts, gtime_t te, double tint, + solstatbuf_t *statbuf); +EXPORT int inputsol(uint8_t data, gtime_t ts, gtime_t te, double tint, int qflag, + const solopt_t *opt, solbuf_t *solbuf); EXPORT int outprcopts(uint8_t *buff, const prcopt_t *opt); EXPORT int outsolheads(uint8_t *buff, const solopt_t *opt); -EXPORT int outsols (uint8_t *buff, const sol_t *sol, const double *rb, - const solopt_t *opt); -EXPORT int outsolexs(uint8_t *buff, const sol_t *sol, const ssat_t *ssat, - const solopt_t *opt); +EXPORT int outsols(uint8_t *buff, const sol_t *sol, const double *rb, const solopt_t *opt); +EXPORT int outsolexs(uint8_t *buff, const sol_t *sol, const ssat_t *ssat, const solopt_t *opt); EXPORT void outprcopt(FILE *fp, const prcopt_t *opt); EXPORT void outsolhead(FILE *fp, const solopt_t *opt); -EXPORT void outsol (FILE *fp, const sol_t *sol, const double *rb, - const solopt_t *opt); -EXPORT void outsolex(FILE *fp, const sol_t *sol, const ssat_t *ssat, - const solopt_t *opt); +EXPORT void outsol(FILE *fp, const sol_t *sol, const double *rb, const solopt_t *opt); +EXPORT void outsolex(FILE *fp, const sol_t *sol, const ssat_t *ssat, const solopt_t *opt); EXPORT int outnmea_rmc(uint8_t *buff, const sol_t *sol); EXPORT int outnmea_gga(uint8_t *buff, const sol_t *sol); -EXPORT int outnmea_gsa(uint8_t *buff, const sol_t *sol, - const ssat_t *ssat); -EXPORT int outnmea_gsv(uint8_t *buff, const sol_t *sol, - const ssat_t *ssat); +EXPORT int outnmea_gsa(uint8_t *buff, const sol_t *sol, const ssat_t *ssat); +EXPORT int outnmea_gsv(uint8_t *buff, const sol_t *sol, const ssat_t *ssat); /* google earth kml converter ------------------------------------------------*/ -EXPORT int convkml(const char *infile, const char *outfile, gtime_t ts, - gtime_t te, double tint, int qflg, int mean, const char *name, - double *offset, int tcolor, int pcolor, int outalt, int outtime); +EXPORT int convkml(const char *infile, const char *outfile, gtime_t ts, gtime_t te, double tint, + int qflg, int mean, const char *name, double *offset, int tcolor, int pcolor, + int outalt, int outtime); /* gpx converter -------------------------------------------------------------*/ -EXPORT int convgpx(const char *infile, const char *outfile, gtime_t ts, - gtime_t te, double tint, int qflg, int mean, const char *name, - double *offset, int outtrk, int outpnt, int outalt, int outtime); +EXPORT int convgpx(const char *infile, const char *outfile, gtime_t ts, gtime_t te, double tint, + int qflg, int mean, const char *name, double *offset, int outtrk, int outpnt, + int outalt, int outtime); // CSV converter ------------------------------------------------------------- -EXPORT int convcsv(const char *infile, const char *outfile, gtime_t ts, - gtime_t te, double tint, int qflg, int mean, const char *name, - double *offset, int outalt, int outtime, int outorder); +EXPORT int convcsv(const char *infile, const char *outfile, gtime_t ts, gtime_t te, double tint, + int qflg, int mean, const char *name, double *offset, int outalt, int outtime, + int outorder); /* sbas functions ------------------------------------------------------------*/ -EXPORT int sbsreadmsg (const char *file, int sel, sbs_t *sbs); -EXPORT int sbsreadmsgt(const char *file, int sel, gtime_t ts, gtime_t te, - sbs_t *sbs); +EXPORT int sbsreadmsg(const char *file, int sel, sbs_t *sbs); +EXPORT int sbsreadmsgt(const char *file, int sel, gtime_t ts, gtime_t te, sbs_t *sbs); EXPORT void sbsoutmsg(FILE *fp, sbsmsg_t *sbsmsg); -EXPORT int sbsdecodemsg(gtime_t time, int prn, const uint32_t *words, - sbsmsg_t *sbsmsg); +EXPORT int sbsdecodemsg(gtime_t time, int prn, const uint32_t *words, sbsmsg_t *sbsmsg); EXPORT int sbsupdatecorr(const sbsmsg_t *msg, nav_t *nav); -EXPORT int sbssatcorr(gtime_t time, int sat, const nav_t *nav, double *rs, - double *dts, double *var); -EXPORT int sbsioncorr(gtime_t time, const nav_t *nav, const double *pos, - const double *azel, double *delay, double *var); -EXPORT double sbstropcorr(gtime_t time, const double *pos, const double *azel, - double *var); +EXPORT int sbssatcorr(gtime_t time, int sat, const nav_t *nav, double *rs, double *dts, + double *var); +EXPORT int sbsioncorr(gtime_t time, const nav_t *nav, const double *pos, const double *azel, + double *delay, double *var); +EXPORT double sbstropcorr(gtime_t time, const double *pos, const double *azel, double *var); /* options functions ---------------------------------------------------------*/ EXPORT opt_t *searchopt(const char *name, const opt_t *opts); @@ -1805,26 +1805,24 @@ EXPORT int str2opt(opt_t *opt, const char *str); EXPORT int opt2str(const opt_t *opt, char *str); EXPORT int opt2buf(const opt_t *opt, char *buff); EXPORT int loadopts(const char *file, opt_t *opts); -EXPORT int saveopts(const char *file, const char *mode, const char *comment, - const opt_t *opts); +EXPORT int saveopts(const char *file, const char *mode, const char *comment, const opt_t *opts); EXPORT void resetsysopts(void); EXPORT void getsysopts(prcopt_t *popt, solopt_t *sopt, filopt_t *fopt); -EXPORT void setsysopts(const prcopt_t *popt, const solopt_t *sopt, - const filopt_t *fopt); +EXPORT void setsysopts(const prcopt_t *popt, const solopt_t *sopt, const filopt_t *fopt); /* stream data input and output functions ------------------------------------*/ EXPORT void strinitcom(void); -EXPORT void strinit (stream_t *stream); -EXPORT void strlock (stream_t *stream); +EXPORT void strinit(stream_t *stream); +EXPORT void strlock(stream_t *stream); EXPORT void strunlock(stream_t *stream); -EXPORT int stropen (stream_t *stream, int type, int mode, const char *path); -EXPORT void strclose (stream_t *stream); -EXPORT int strread (stream_t *stream, uint8_t *buff, int n); -EXPORT int strwrite (stream_t *stream, uint8_t *buff, int n); -EXPORT void strsync (stream_t *stream1, stream_t *stream2); -EXPORT int strstat (stream_t *stream, char *msg); -EXPORT int strstatx (stream_t *stream, char *msg); -EXPORT void strsum (stream_t *stream, int *inb, int *inr, int *outb, int *outr); +EXPORT int stropen(stream_t *stream, int type, int mode, const char *path); +EXPORT void strclose(stream_t *stream); +EXPORT int strread(stream_t *stream, uint8_t *buff, int n); +EXPORT int strwrite(stream_t *stream, uint8_t *buff, int n); +EXPORT void strsync(stream_t *stream1, stream_t *stream2); +EXPORT int strstat(stream_t *stream, char *msg); +EXPORT int strstatx(stream_t *stream, char *msg); +EXPORT void strsum(stream_t *stream, int *inb, int *inr, int *outb, int *outr); EXPORT void strsetopt(const int *opt); EXPORT gtime_t strgettime(stream_t *stream); EXPORT void strsendnmea(stream_t *stream, const sol_t *sol); @@ -1834,89 +1832,80 @@ EXPORT void strsetdir(const char *dir); EXPORT void strsetproxy(const char *addr); /* integer ambiguity resolution ----------------------------------------------*/ -EXPORT int lambda(int n, int m, const double *a, const double *Q, double *F, - double *s); +EXPORT int lambda(int n, int m, const double *a, const double *Q, double *F, double *s); EXPORT int lambda_reduction(int n, const double *Q, double *Z); -EXPORT int lambda_search(int n, int m, const double *a, const double *Q, - double *F, double *s); +EXPORT int lambda_search(int n, int m, const double *a, const double *Q, double *F, double *s); /* standard positioning ------------------------------------------------------*/ -EXPORT int pntpos(const obsd_t *obs, int n, const nav_t *nav, - const prcopt_t *opt, sol_t *sol, double *azel, - ssat_t *ssat, char *msg); +EXPORT int pntpos(const obsd_t *obs, int n, const nav_t *nav, const prcopt_t *opt, sol_t *sol, + double *azel, ssat_t *ssat, char *msg); /* precise positioning -------------------------------------------------------*/ EXPORT void rtkinit(rtk_t *rtk, const prcopt_t *opt); EXPORT void rtkfree(rtk_t *rtk); -EXPORT int rtkpos (rtk_t *rtk, const obsd_t *obs, int nobs, const nav_t *nav); -EXPORT int rtkopenstat(const char *file, int level); +EXPORT int rtkpos(rtk_t *rtk, const obsd_t *obs, int nobs, const nav_t *nav); +EXPORT int rtkopenstat(const char *file, int level); EXPORT void rtkclosestat(void); -EXPORT int rtkoutstat(rtk_t *rtk, int level, char *buff); +EXPORT int rtkoutstat(rtk_t *rtk, int level, char *buff); /* precise point positioning -------------------------------------------------*/ EXPORT void pppos(rtk_t *rtk, const obsd_t *obs, int n, const nav_t *nav); EXPORT int pppnx(const prcopt_t *opt); EXPORT int pppoutstat(rtk_t *rtk, char *buff); -EXPORT int ppp_ar(rtk_t *rtk, const obsd_t *obs, int n, int *exc, - const nav_t *nav, const double *azel, double *x, double *P); +EXPORT int ppp_ar(rtk_t *rtk, const obsd_t *obs, int n, int *exc, const nav_t *nav, + const double *azel, double *x, double *P); /* post-processing positioning -----------------------------------------------*/ -EXPORT int postpos(gtime_t ts, gtime_t te, double ti, double tu, - const prcopt_t *popt, const solopt_t *sopt, - const filopt_t *fopt, const char **infile, int n, const char *outfile, - const char *rov, const char *base); +EXPORT int postpos(gtime_t ts, gtime_t te, double ti, double tu, const prcopt_t *popt, + const solopt_t *sopt, const filopt_t *fopt, const char **infile, int n, + const char *outfile, const char *rov, const char *base); EXPORT int getstapos(const char *file, const char *name, double *r); /* stream server functions ---------------------------------------------------*/ -EXPORT void strsvrinit (strsvr_t *svr, int nout); -EXPORT int strsvrstart(strsvr_t *svr, int *opts, int *strs, const char **paths, - const char **logs, strconv_t **conv, const char **cmds, - const char **cmds_periodic, const double *nmeapos); -EXPORT void strsvrstop (strsvr_t *svr, const char **cmds); -EXPORT void strsvrstat (strsvr_t *svr, int *stat, int *log_stat, int *byte, - int *bps, char *msg); -EXPORT strconv_t *strconvnew(int itype, int otype, const char *msgs, int staid, - int stasel, const char *opt); +EXPORT void strsvrinit(strsvr_t *svr, int nout); +EXPORT int strsvrstart(strsvr_t *svr, int *opts, int *strs, const char **paths, const char **logs, + strconv_t **conv, const char **cmds, const char **cmds_periodic, + const double *nmeapos); +EXPORT void strsvrstop(strsvr_t *svr, const char **cmds); +EXPORT void strsvrstat(strsvr_t *svr, int *stat, int *log_stat, int *byte, int *bps, char *msg); +EXPORT strconv_t *strconvnew(int itype, int otype, const char *msgs, int staid, int stasel, + const char *opt); EXPORT void strconvfree(strconv_t *conv); /* rtk server functions ------------------------------------------------------*/ -EXPORT int rtksvrinit (rtksvr_t *svr); -EXPORT void rtksvrfree (rtksvr_t *svr); -EXPORT int rtksvrstart (rtksvr_t *svr, int cycle, int buffsize, int *strs, - const char **paths, int *formats, int navsel, const char **cmds, - const char **cmds_periodic, const char **rcvopts, int nmeacycle, - int nmeareq, const double *nmeapos, prcopt_t *prcopt, - solopt_t *solopt, stream_t *moni, char *errmsg); -EXPORT void rtksvrstop (rtksvr_t *svr, const char **cmds); -EXPORT int rtksvropenstr(rtksvr_t *svr, int index, int str, const char *path, - const solopt_t *solopt, const prcopt_t *prcopt); +EXPORT int rtksvrinit(rtksvr_t *svr); +EXPORT void rtksvrfree(rtksvr_t *svr); +EXPORT int rtksvrstart(rtksvr_t *svr, int cycle, int buffsize, int *strs, const char **paths, + int *formats, int navsel, const char **cmds, const char **cmds_periodic, + const char **rcvopts, int nmeacycle, int nmeareq, const double *nmeapos, + prcopt_t *prcopt, solopt_t *solopt, stream_t *moni, char *errmsg); +EXPORT void rtksvrstop(rtksvr_t *svr, const char **cmds); +EXPORT int rtksvropenstr(rtksvr_t *svr, int index, int str, const char *path, + const solopt_t *solopt, const prcopt_t *prcopt); EXPORT void rtksvrclosestr(rtksvr_t *svr, int index); -EXPORT void rtksvrlock (rtksvr_t *svr); +EXPORT void rtksvrlock(rtksvr_t *svr); EXPORT void rtksvrunlock(rtksvr_t *svr); -EXPORT int rtksvrostat (rtksvr_t *svr, int type, gtime_t *time, int *sat, - double *az, double *el, int **snr, int *vsat); -EXPORT void rtksvrsstat (rtksvr_t *svr, int *sstat, char *msg); -EXPORT int rtksvrmark(rtksvr_t *svr, const char *name, const char *comment); +EXPORT int rtksvrostat(rtksvr_t *svr, int type, gtime_t *time, int *sat, double *az, double *el, + int **snr, int *vsat); +EXPORT void rtksvrsstat(rtksvr_t *svr, int *sstat, char *msg); +EXPORT int rtksvrmark(rtksvr_t *svr, const char *name, const char *comment); /* downloader functions ------------------------------------------------------*/ -EXPORT int dl_readurls(const char *file, const char **types, int ntype, url_t *urls, - int nmax); +EXPORT int dl_readurls(const char *file, const char **types, int ntype, url_t *urls, int nmax); EXPORT int dl_readstas(const char *file, char **stas, int nmax); -EXPORT int dl_exec(gtime_t ts, gtime_t te, double ti, int seqnos, int seqnoe, - const url_t *urls, int nurl, const char **stas, int nsta, - const char *dir, const char *usr, const char *pwd, - const char *proxy, int opts, char *msg, FILE *fp); -EXPORT void dl_test(gtime_t ts, gtime_t te, double ti, const url_t *urls, - int nurl, const char **stas, int nsta, const char *dir, - int ncol, int datefmt, FILE *fp); +EXPORT int dl_exec(gtime_t ts, gtime_t te, double ti, int seqnos, int seqnoe, const url_t *urls, + int nurl, const char **stas, int nsta, const char *dir, const char *usr, + const char *pwd, const char *proxy, int opts, char *msg, FILE *fp); +EXPORT void dl_test(gtime_t ts, gtime_t te, double ti, const url_t *urls, int nurl, + const char **stas, int nsta, const char *dir, int ncol, int datefmt, FILE *fp); /* GIS data functions --------------------------------------------------------*/ EXPORT int gis_read(const char *file, gis_t *gis, int layer); EXPORT void gis_free(gis_t *gis); /* application defined functions ---------------------------------------------*/ -extern int showmsg(const char *format,...); +extern int showmsg(const char *format, ...); extern void settspan(gtime_t ts, gtime_t te); extern void settime(gtime_t time); diff --git a/src/rtkpos.c b/src/rtkpos.c index 48f54ae6d..642a638be 100644 --- a/src/rtkpos.c +++ b/src/rtkpos.c @@ -1,654 +1,669 @@ /*------------------------------------------------------------------------------ -* rtkpos.c : precise positioning -* -* Copyright (C) 2007-2020 by T.TAKASU, All rights reserved. -* -* version : $Revision: 1.1 $ $Date: 2008/07/17 21:48:06 $ -* history : 2007/01/12 1.0 new -* 2007/03/13 1.1 add slip detection by LLI flag -* 2007/04/18 1.2 add antenna pcv correction -* change rtkpos argin -* 2008/07/18 1.3 refactored -* 2009/01/02 1.4 modify rtk positioning api -* 2009/03/09 1.5 support glonass, gallileo and qzs -* 2009/08/27 1.6 fix bug on numerical exception -* 2009/09/03 1.7 add check of valid satellite number -* add check time sync for moving-base -* 2009/11/23 1.8 add api rtkopenstat(),rtkclosestat() -* add receiver h/w bias estimation -* add solution status output -* 2010/04/04 1.9 support ppp-kinematic and ppp-static modes -* support earth tide correction -* changed api: -* rtkpos() -* 2010/09/07 1.10 add elevation mask to hold ambiguity -* 2012/02/01 1.11 add extended receiver error model -* add glonass interchannel bias correction -* add slip detection by L1-L5 gf jump -* output snr of rover receiver in residuals -* 2013/03/10 1.12 add otl and pole tides corrections -* 2014/05/26 1.13 support beidou and galileo -* add output of gal-gps and bds-gps time offset -* 2014/05/28 1.14 fix bug on memory exception with many sys and freq -* 2014/08/26 1.15 add function to swap sol-stat file with keywords -* 2014/10/21 1.16 fix bug on beidou amb-res with pos2-bdsarmode=0 -* 2014/11/08 1.17 fix bug on ar-degradation by unhealthy satellites -* 2015/03/23 1.18 residuals referenced to reference satellite -* 2015/05/20 1.19 no output solution status file with Q=0 -* 2015/07/22 1.20 fix bug on base station position setting -* 2016/07/30 1.21 suppress single solution if !prcopt.outsingle -* fix bug on slip detection of backward filter -* 2016/08/20 1.22 fix bug on ddres() function -* 2018/10/10 1.13 support api change of satexclude() -* 2018/12/15 1.14 disable ambiguity resolution for gps-qzss -* 2019/08/19 1.15 fix bug on return value of resamb_LAMBDA() -* 2020/11/30 1.16 support of NavIC/IRNSS in API rtkpos() -* add detecting cycle slips by L1-Lx GF phase jump -* delete GLONASS IFB correction in ddres() -* use integer types in stdint.h -*-----------------------------------------------------------------------------*/ + * rtkpos.c : precise positioning + * + * Copyright (C) 2007-2020 by T.TAKASU, All rights reserved. + * + * version : $Revision: 1.1 $ $Date: 2008/07/17 21:48:06 $ + * history : 2007/01/12 1.0 new + * 2007/03/13 1.1 add slip detection by LLI flag + * 2007/04/18 1.2 add antenna pcv correction + * change rtkpos argin + * 2008/07/18 1.3 refactored + * 2009/01/02 1.4 modify rtk positioning api + * 2009/03/09 1.5 support glonass, gallileo and qzs + * 2009/08/27 1.6 fix bug on numerical exception + * 2009/09/03 1.7 add check of valid satellite number + * add check time sync for moving-base + * 2009/11/23 1.8 add api rtkopenstat(),rtkclosestat() + * add receiver h/w bias estimation + * add solution status output + * 2010/04/04 1.9 support ppp-kinematic and ppp-static modes + * support earth tide correction + * changed api: + * rtkpos() + * 2010/09/07 1.10 add elevation mask to hold ambiguity + * 2012/02/01 1.11 add extended receiver error model + * add glonass interchannel bias correction + * add slip detection by L1-L5 gf jump + * output snr of rover receiver in residuals + * 2013/03/10 1.12 add otl and pole tides corrections + * 2014/05/26 1.13 support beidou and galileo + * add output of gal-gps and bds-gps time offset + * 2014/05/28 1.14 fix bug on memory exception with many sys and freq + * 2014/08/26 1.15 add function to swap sol-stat file with keywords + * 2014/10/21 1.16 fix bug on beidou amb-res with pos2-bdsarmode=0 + * 2014/11/08 1.17 fix bug on ar-degradation by unhealthy satellites + * 2015/03/23 1.18 residuals referenced to reference satellite + * 2015/05/20 1.19 no output solution status file with Q=0 + * 2015/07/22 1.20 fix bug on base station position setting + * 2016/07/30 1.21 suppress single solution if !prcopt.outsingle + * fix bug on slip detection of backward filter + * 2016/08/20 1.22 fix bug on ddres() function + * 2018/10/10 1.13 support api change of satexclude() + * 2018/12/15 1.14 disable ambiguity resolution for gps-qzss + * 2019/08/19 1.15 fix bug on return value of resamb_LAMBDA() + * 2020/11/30 1.16 support of NavIC/IRNSS in API rtkpos() + * add detecting cycle slips by L1-Lx GF phase jump + * delete GLONASS IFB correction in ddres() + * use integer types in stdint.h + *-----------------------------------------------------------------------------*/ #include + #include "rtklib.h" /* algorithm configuration -------------------------------------------------- */ -#define STD_PREC_VAR_THRESH 0 /* pos variance threshold to skip standard precision */ +#define STD_PREC_VAR_THRESH 0 /* pos variance threshold to skip standard precision */ /* solution: 0 = run every epoch, */ /* 0.5 = skip except for first*/ /* constants/macros ----------------------------------------------------------*/ -#define SQR(x) ((x)*(x)) -#define SQRT(x) ((x)<=0.0||(x)!=(x)?0.0:sqrt(x)) -#define MIN(x,y) ((x)<=(y)?(x):(y)) -#define MAX(x,y) ((x)>=(y)?(x):(y)) -#define ROUND(x) (int)floor((x)+0.5) +#define SQR(x) ((x) * (x)) +#define SQRT(x) ((x) <= 0.0 || (x) != (x) ? 0.0 : sqrt(x)) +#define MIN(x, y) ((x) <= (y) ? (x) : (y)) +#define MAX(x, y) ((x) >= (y) ? (x) : (y)) +#define ROUND(x) (int)floor((x) + 0.5) -#define VAR_POS SQR(30.0) /* initial variance of receiver pos (m^2) */ +#define VAR_POS SQR(30.0) /* initial variance of receiver pos (m^2) */ #define VAR_POS_FIX SQR(1e-4) /* initial variance of fixed receiver pos (m^2) */ -#define VAR_VEL SQR(10.0) /* initial variance of receiver vel ((m/s)^2) */ -#define VAR_ACC SQR(10.0) /* initial variance of receiver acc ((m/ss)^2) */ -#define VAR_GRA SQR(0.001) /* initial variance of gradient (m^2) */ -#define INIT_ZWD 0.15 /* initial zwd (m) */ +#define VAR_VEL SQR(10.0) /* initial variance of receiver vel ((m/s)^2) */ +#define VAR_ACC SQR(10.0) /* initial variance of receiver acc ((m/ss)^2) */ +#define VAR_GRA SQR(0.001) /* initial variance of gradient (m^2) */ +#define INIT_ZWD 0.15 /* initial zwd (m) */ -#define GAP_RESION 120 /* gap to reset ionosphere parameters (epochs) */ +#define GAP_RESION 120 /* gap to reset ionosphere parameters (epochs) */ -#define TTOL_MOVEB (1.0+2*DTTOL) - /* time sync tolerance for moving-baseline (s) */ +#define TTOL_MOVEB (1.0 + 2 * DTTOL) +/* time sync tolerance for moving-baseline (s) */ /* number of parameters (pos,ionos,tropos,hw-bias,phase-bias,real,estimated) */ -#define NF(opt) ((opt)->ionoopt==IONOOPT_IFLC?1:(opt)->nf) -#define NP(opt) ((opt)->dynamics==0?3:9) -#define NI(opt) ((opt)->ionoopt!=IONOOPT_EST?0:MAXSAT) -#define NT(opt) ((opt)->tropopttropoptglomodear!=GLO_ARMODE_AUTOCAL?0:NFREQGLO) -#define NB(opt) ((opt)->mode<=PMODE_DGPS?0:MAXSAT*NF(opt)) -#define NR(opt) (NP(opt)+NI(opt)+NT(opt)+NL(opt)) -#define NX(opt) (NR(opt)+NB(opt)) +#define NF(opt) ((opt)->ionoopt == IONOOPT_IFLC ? 1 : (opt)->nf) +#define NP(opt) ((opt)->dynamics == 0 ? 3 : 9) +#define NI(opt) ((opt)->ionoopt != IONOOPT_EST ? 0 : MAXSAT) +#define NT(opt) ((opt)->tropopt < TROPOPT_EST ? 0 : ((opt)->tropopt < TROPOPT_ESTG ? 2 : 6)) +#define NL(opt) ((opt)->glomodear != GLO_ARMODE_AUTOCAL ? 0 : NFREQGLO) +#define NB(opt) ((opt)->mode <= PMODE_DGPS ? 0 : MAXSAT * NF(opt)) +#define NR(opt) (NP(opt) + NI(opt) + NT(opt) + NL(opt)) +#define NX(opt) (NR(opt) + NB(opt)) /* state variable index */ -#define II(s,opt) (NP(opt)+(s)-1) /* ionos (s:satellite no) */ -#define IT(r,opt) (NP(opt)+NI(opt)+NT(opt)/2*(r)) /* tropos (r:0=rov,1:ref) */ -#define IL(f,opt) (NP(opt)+NI(opt)+NT(opt)+(f)) /* receiver h/w bias */ -#define IB(s,f,opt) (NR(opt)+MAXSAT*(f)+(s)-1) /* phase bias (s:satno,f:freq) */ +#define II(s, opt) (NP(opt) + (s) - 1) /* ionos (s:satellite no) */ +#define IT(r, opt) (NP(opt) + NI(opt) + NT(opt) / 2 * (r)) /* tropos (r:0=rov,1:ref) */ +#define IL(f, opt) (NP(opt) + NI(opt) + NT(opt) + (f)) /* receiver h/w bias */ +#define IB(s, f, opt) (NR(opt) + MAXSAT * (f) + (s) - 1) /* phase bias (s:satno,f:freq) */ /* poly coeffs used to adjust AR ratio by # of sats, derived by fitting to example from: - https://www.tudelft.nl/citg/over-faculteit/afdelingen/geoscience-remote-sensing/research/lambda/lambda */ + https://www.tudelft.nl/citg/over-faculteit/afdelingen/geoscience-remote-sensing/research/lambda/lambda + */ static double ar_poly_coeffs[3][5] = { - {-1.94058448e-01, -7.79023476e+00, 1.24231120e+02, -4.03126050e+02, 3.50413202e+02}, - {6.42237302e-01, -8.39813962e+00, 2.92107285e+01, -2.37577308e+01, -1.14307128e+00}, - {-2.22600390e-02, 3.23169103e-01, -1.39837429e+00, 2.19282996e+00, -5.34583971e-02}}; + {-1.94058448e-01, -7.79023476e+00, 1.24231120e+02, -4.03126050e+02, 3.50413202e+02}, + {6.42237302e-01, -8.39813962e+00, 2.92107285e+01, -2.37577308e+01, -1.14307128e+00}, + {-2.22600390e-02, 3.23169103e-01, -1.39837429e+00, 2.19282996e+00, -5.34583971e-02}}; /* global variables ----------------------------------------------------------*/ -static int statlevel=0; /* rtk status output level (0:off) */ -static FILE *fp_stat=NULL; /* rtk status file pointer */ -static char file_stat[1024]=""; /* rtk status file original path */ -static gtime_t time_stat={0}; /* rtk status file time */ +static int statlevel = 0; /* rtk status output level (0:off) */ +static FILE *fp_stat = NULL; /* rtk status file pointer */ +static char file_stat[1024] = ""; /* rtk status file original path */ +static gtime_t time_stat = {0}; /* rtk status file time */ /* open solution status file --------------------------------------------------- -* open solution status file and set output level -* args : char *file I rtk status file -* int level I rtk status level (0: off) -* return : status (1:ok,0:error) -* notes : file can constain time keywords (%Y,%y,%m...) defined in reppath(). -* The time to replace keywords is based on UTC of CPU time. -* output : solution status file record format -* -* $POS,week,tow,stat,posx,posy,posz,posxf,posyf,poszf -* week/tow : gps week no/time of week (s) -* stat : solution status -* posx/posy/posz : position x/y/z ecef (m) float -* posxf/posyf/poszf : position x/y/z ecef (m) fixed -* -* $VELACC,week,tow,stat,vele,veln,velu,acce,accn,accu,velef,velnf,veluf,accef,accnf,accuf -* week/tow : gps week no/time of week (s) -* stat : solution status -* vele/veln/velu : velocity e/n/u (m/s) float -* acce/accn/accu : acceleration e/n/u (m/s^2) float -* velef/velnf/veluf : velocity e/n/u (m/s) fixed -* accef/accnf/accuf : acceleration e/n/u (m/s^2) fixed -* -* $CLK,week,tow,stat,clk1,clk2,clk3,clk4,clk5,clk6 -* week/tow : gps week no/time of week (s) -* stat : solution status -* clk1 : receiver clock bias GPS (ns) -* clk2 : receiver clock bias GLO-GPS (ns) -* clk3 : receiver clock bias GAL-GPS (ns) -* clk4 : receiver clock bias BDS-GPS (ns) -* clk5 : receiver clock bias IRN-GPS (ns) -* clk6 : receiver clock bias QZS-GPS (ns) -* -* $ION,week,tow,stat,sat,az,el,ion,ion-fixed -* week/tow : gps week no/time of week (s) -* stat : solution status -* sat : satellite id -* az/el : azimuth/elevation angle(deg) -* ion : vertical ionospheric delay L1 (m) float -* ion-fixed: vertical ionospheric delay L1 (m) fixed -* -* $TROP,week,tow,stat,rcv,ztd,ztdf -* week/tow : gps week no/time of week (s) -* stat : solution status -* rcv : receiver (1:rover,2:base station) -* ztd : zenith total delay (m) float -* ztdf : zenith total delay (m) fixed -* -* $HWBIAS,week,tow,stat,frq,bias,biasf -* week/tow : gps week no/time of week (s) -* stat : solution status -* frq : frequency (1:L1,2:L2,...) -* bias : h/w bias coefficient (m/MHz) float -* biasf : h/w bias coefficient (m/MHz) fixed -* -* $SAT,week,tow,sat,frq,az,el,resp,resc,vsat,snr,fix,slip,lock,outc,slipc,rejc,icbias,bias,bias_var,lambda -* week/tow : gps week no/time of week (s) -* sat/frq : satellite id/frequency (1:L1,2:L2,...) -* az/el : azimuth/elevation angle (deg) -* resp : pseudorange residual (m) -* resc : carrier-phase residual (m) -* vsat : valid data flag (0:invalid,1:valid) -* snr : signal strength (dbHz) -* fix : ambiguity flag (0:no data,1:float,2:fixed,3:hold,4:ppp) -* slip : cycle-slip flag (bit1:slip,bit2:parity unknown) -* lock : carrier-lock count -* outc : data outage count -* slipc : cycle-slip count -* rejc : data reject (outlier) count -* icbias : interchannel bias (GLONASS) -* bias : phase bias -* bias_var : variance of phase bias -* lambda : wavelength -* -*-----------------------------------------------------------------------------*/ -extern int rtkopenstat(const char *file, int level) -{ - gtime_t time=utc2gpst(timeget()); - char path[1024]; - - trace(3,"rtkopenstat: file=%s level=%d\n",file,level); - - if (level<=0) return 0; - - reppath(file,path,time,"",""); - - if (!(fp_stat=fopen(path,"w"))) { - trace(1,"rtkopenstat: file open error path=%s\n",path); - return 0; - } - strcpy(file_stat,file); - time_stat=time; - statlevel=level; - return 1; + * open solution status file and set output level + * args : char *file I rtk status file + * int level I rtk status level (0: off) + * return : status (1:ok,0:error) + * notes : file can constain time keywords (%Y,%y,%m...) defined in reppath(). + * The time to replace keywords is based on UTC of CPU time. + * output : solution status file record format + * + * $POS,week,tow,stat,posx,posy,posz,posxf,posyf,poszf + * week/tow : gps week no/time of week (s) + * stat : solution status + * posx/posy/posz : position x/y/z ecef (m) float + * posxf/posyf/poszf : position x/y/z ecef (m) fixed + * + * $VELACC,week,tow,stat,vele,veln,velu,acce,accn,accu,velef,velnf,veluf,accef,accnf,accuf + * week/tow : gps week no/time of week (s) + * stat : solution status + * vele/veln/velu : velocity e/n/u (m/s) float + * acce/accn/accu : acceleration e/n/u (m/s^2) float + * velef/velnf/veluf : velocity e/n/u (m/s) fixed + * accef/accnf/accuf : acceleration e/n/u (m/s^2) fixed + * + * $CLK,week,tow,stat,clk1,clk2,clk3,clk4,clk5,clk6 + * week/tow : gps week no/time of week (s) + * stat : solution status + * clk1 : receiver clock bias GPS (ns) + * clk2 : receiver clock bias GLO-GPS (ns) + * clk3 : receiver clock bias GAL-GPS (ns) + * clk4 : receiver clock bias BDS-GPS (ns) + * clk5 : receiver clock bias IRN-GPS (ns) + * clk6 : receiver clock bias QZS-GPS (ns) + * + * $ION,week,tow,stat,sat,az,el,ion,ion-fixed + * week/tow : gps week no/time of week (s) + * stat : solution status + * sat : satellite id + * az/el : azimuth/elevation angle(deg) + * ion : vertical ionospheric delay L1 (m) float + * ion-fixed: vertical ionospheric delay L1 (m) fixed + * + * $TROP,week,tow,stat,rcv,ztd,ztdf + * week/tow : gps week no/time of week (s) + * stat : solution status + * rcv : receiver (1:rover,2:base station) + * ztd : zenith total delay (m) float + * ztdf : zenith total delay (m) fixed + * + * $HWBIAS,week,tow,stat,frq,bias,biasf + * week/tow : gps week no/time of week (s) + * stat : solution status + * frq : frequency (1:L1,2:L2,...) + * bias : h/w bias coefficient (m/MHz) float + * biasf : h/w bias coefficient (m/MHz) fixed + * + * $SAT,week,tow,sat,frq,az,el,resp,resc,vsat,snr,fix,slip,lock,outc,slipc,rejc,icbias,bias,bias_var,lambda + * week/tow : gps week no/time of week (s) + * sat/frq : satellite id/frequency (1:L1,2:L2,...) + * az/el : azimuth/elevation angle (deg) + * resp : pseudorange residual (m) + * resc : carrier-phase residual (m) + * vsat : valid data flag (0:invalid,1:valid) + * snr : signal strength (dbHz) + * fix : ambiguity flag (0:no data,1:float,2:fixed,3:hold,4:ppp) + * slip : cycle-slip flag (bit1:slip,bit2:parity unknown) + * lock : carrier-lock count + * outc : data outage count + * slipc : cycle-slip count + * rejc : data reject (outlier) count + * icbias : interchannel bias (GLONASS) + * bias : phase bias + * bias_var : variance of phase bias + * lambda : wavelength + * + *-----------------------------------------------------------------------------*/ +extern int rtkopenstat(const char *file, int level) { + gtime_t time = utc2gpst(timeget()); + char path[1024]; + + trace(3, "rtkopenstat: file=%s level=%d\n", file, level); + + if (level <= 0) return 0; + + reppath(file, path, time, "", ""); + + if (!(fp_stat = fopen(path, "w"))) { + trace(1, "rtkopenstat: file open error path=%s\n", path); + return 0; + } + strcpy(file_stat, file); + time_stat = time; + statlevel = level; + return 1; } /* close solution status file -------------------------------------------------- -* close solution status file -* args : none -* return : none -*-----------------------------------------------------------------------------*/ -extern void rtkclosestat(void) -{ - trace(3,"rtkclosestat:\n"); - - if (fp_stat) fclose(fp_stat); - fp_stat=NULL; - file_stat[0]='\0'; - statlevel=0; + * close solution status file + * args : none + * return : none + *-----------------------------------------------------------------------------*/ +extern void rtkclosestat(void) { + trace(3, "rtkclosestat:\n"); + + if (fp_stat) fclose(fp_stat); + fp_stat = NULL; + file_stat[0] = '\0'; + statlevel = 0; } /* Write solution status to buffer -------------------------------------------*/ -extern int rtkoutstat(rtk_t *rtk, int level, char *buff) -{ - if (level<=0||rtk->sol.stat==SOLQ_NONE) { - return 0; - } - - ssat_t *ssat; - double pos[3],vel[3],acc[3],vela[3]={0},acca[3]={0},xa[3]; - int week,nf=NF(&rtk->opt); - char id[8],*p=buff; - - int est=rtk->opt.mode>=PMODE_DGPS; - int nfreq=est?nf:1; - double tow=time2gpst(rtk->sol.time,&week); +extern int rtkoutstat(rtk_t *rtk, int level, char *buff) { + if (level <= 0 || rtk->sol.stat == SOLQ_NONE) { + return 0; + } - if (rtk->opt.mode>=PMODE_PPP_KINEMA) { - /* Write ppp solution status to buffer */ - p+=pppoutstat(rtk,buff); + ssat_t *ssat; + double pos[3], vel[3], acc[3], vela[3] = {0}, acca[3] = {0}, xa[3]; + int week, nf = NF(&rtk->opt); + char id[8], *p = buff; + + int est = rtk->opt.mode >= PMODE_DGPS; + int nfreq = est ? nf : 1; + double tow = time2gpst(rtk->sol.time, &week); + + if (rtk->opt.mode >= PMODE_PPP_KINEMA) { + /* Write ppp solution status to buffer */ + p += pppoutstat(rtk, buff); + } else { + /* Receiver position */ + if (est) { + for (int i = 0; i < 3; i++) xa[i] = i < rtk->na ? rtk->xa[i] : 0.0; + p += sprintf(p, "$POS,%d,%.3f,%d,%.4f,%.4f,%.4f,%.4f,%.4f,%.4f\n", week, tow, rtk->sol.stat, + rtk->x[0], rtk->x[1], rtk->x[2], xa[0], xa[1], xa[2]); } else { - /* Receiver position */ - if (est) { - for (int i=0;i<3;i++) xa[i]=ina?rtk->xa[i]:0.0; - p+=sprintf(p,"$POS,%d,%.3f,%d,%.4f,%.4f,%.4f,%.4f,%.4f,%.4f\n",week,tow, - rtk->sol.stat,rtk->x[0],rtk->x[1],rtk->x[2],xa[0],xa[1], - xa[2]); - } - else { - p+=sprintf(p,"$POS,%d,%.3f,%d,%.4f,%.4f,%.4f,%.4f,%.4f,%.4f\n",week,tow, - rtk->sol.stat,rtk->sol.rr[0],rtk->sol.rr[1],rtk->sol.rr[2], - 0.0,0.0,0.0); - } - /* Receiver velocity and acceleration */ - if (est&&rtk->opt.dynamics) { - ecef2pos(rtk->sol.rr,pos); - ecef2enu(pos,rtk->x+3,vel); - ecef2enu(pos,rtk->x+6,acc); - if (rtk->na>=6) ecef2enu(pos,rtk->xa+3,vela); - if (rtk->na>=9) ecef2enu(pos,rtk->xa+6,acca); - p+=sprintf(p,"$VELACC,%d,%.3f,%d,%.4f,%.4f,%.4f,%.5f,%.5f,%.5f,%.4f,%.4f,%.4f,%.5f,%.5f,%.5f\n", - week,tow,rtk->sol.stat,vel[0],vel[1],vel[2],acc[0],acc[1], - acc[2],vela[0],vela[1],vela[2],acca[0],acca[1],acca[2]); - } - else { - ecef2pos(rtk->sol.rr,pos); - ecef2enu(pos,rtk->sol.rr+3,vel); - p+=sprintf(p,"$VELACC,%d,%.3f,%d,%.4f,%.4f,%.4f,%.5f,%.5f,%.5f,%.4f,%.4f,%.4f,%.5f,%.5f,%.5f\n", - week,tow,rtk->sol.stat,vel[0],vel[1],vel[2], - 0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0); - } - /* Receiver clocks */ - p+=sprintf(p,"$CLK,%d,%.3f,%d,%d,%.3f,%.3f,%.3f,%.3f,%.3f,%.3f\n", - week,tow,rtk->sol.stat,1,rtk->sol.dtr[0]*1E9,rtk->sol.dtr[1]*1E9, - rtk->sol.dtr[2]*1E9,rtk->sol.dtr[3]*1E9, - rtk->sol.dtr[4]*1E9,rtk->sol.dtr[5]*1E9); - - /* Ionospheric parameters */ - if (est&&rtk->opt.ionoopt==IONOOPT_EST) { - for (int i=0;issat+i; - if (!ssat->vs) continue; - satno2id(i+1,id); - int j=II(i+1,&rtk->opt); - xa[0]=jna?rtk->xa[j]:0.0; - p+=sprintf(p,"$ION,%d,%.3f,%d,%s,%.1f,%.1f,%.4f,%.4f\n",week,tow, - rtk->sol.stat,id,ssat->azel[0]*R2D,ssat->azel[1]*R2D, - rtk->x[j],xa[0]); - } - } - /* Tropospheric parameters */ - if (est&&(rtk->opt.tropopt>=TROPOPT_EST)) { - for (int i=0;i<2;i++) { - int j=IT(i,&rtk->opt); - xa[0]=jna?rtk->xa[j]:0.0; - p+=sprintf(p,"$TROP,%d,%.3f,%d,%d,%.4f,%.4f\n",week,tow, - rtk->sol.stat,i+1,rtk->x[j],xa[0]); - } - } - /* Receiver h/w bias */ - if (est&&rtk->opt.glomodear==GLO_ARMODE_AUTOCAL) { - for (int i=0;iopt); - xa[0]=jna?rtk->xa[j]:0.0; - p+=sprintf(p,"$HWBIAS,%d,%.3f,%d,%d,%.4f,%.4f\n",week,tow, - rtk->sol.stat,i+1,rtk->x[j],xa[0]); - } - } + p += sprintf(p, "$POS,%d,%.3f,%d,%.4f,%.4f,%.4f,%.4f,%.4f,%.4f\n", week, tow, rtk->sol.stat, + rtk->sol.rr[0], rtk->sol.rr[1], rtk->sol.rr[2], 0.0, 0.0, 0.0); + } + /* Receiver velocity and acceleration */ + if (est && rtk->opt.dynamics) { + ecef2pos(rtk->sol.rr, pos); + ecef2enu(pos, rtk->x + 3, vel); + ecef2enu(pos, rtk->x + 6, acc); + if (rtk->na >= 6) ecef2enu(pos, rtk->xa + 3, vela); + if (rtk->na >= 9) ecef2enu(pos, rtk->xa + 6, acca); + p += sprintf( + p, "$VELACC,%d,%.3f,%d,%.4f,%.4f,%.4f,%.5f,%.5f,%.5f,%.4f,%.4f,%.4f,%.5f,%.5f,%.5f\n", + week, tow, rtk->sol.stat, vel[0], vel[1], vel[2], acc[0], acc[1], acc[2], vela[0], + vela[1], vela[2], acca[0], acca[1], acca[2]); + } else { + ecef2pos(rtk->sol.rr, pos); + ecef2enu(pos, rtk->sol.rr + 3, vel); + p += sprintf( + p, "$VELACC,%d,%.3f,%d,%.4f,%.4f,%.4f,%.5f,%.5f,%.5f,%.4f,%.4f,%.4f,%.5f,%.5f,%.5f\n", + week, tow, rtk->sol.stat, vel[0], vel[1], vel[2], 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.0); + } + /* Receiver clocks */ + p += sprintf(p, "$CLK,%d,%.3f,%d,%d,%.3f,%.3f,%.3f,%.3f,%.3f,%.3f\n", week, tow, rtk->sol.stat, + 1, rtk->sol.dtr[0] * 1E9, rtk->sol.dtr[1] * 1E9, rtk->sol.dtr[2] * 1E9, + rtk->sol.dtr[3] * 1E9, rtk->sol.dtr[4] * 1E9, rtk->sol.dtr[5] * 1E9); + + /* Ionospheric parameters */ + if (est && rtk->opt.ionoopt == IONOOPT_EST) { + for (int i = 0; i < MAXSAT; i++) { + ssat = rtk->ssat + i; + if (!ssat->vs) continue; + satno2id(i + 1, id); + int j = II(i + 1, &rtk->opt); + xa[0] = j < rtk->na ? rtk->xa[j] : 0.0; + p += sprintf(p, "$ION,%d,%.3f,%d,%s,%.1f,%.1f,%.4f,%.4f\n", week, tow, rtk->sol.stat, id, + ssat->azel[0] * R2D, ssat->azel[1] * R2D, rtk->x[j], xa[0]); + } } + /* Tropospheric parameters */ + if (est && (rtk->opt.tropopt >= TROPOPT_EST)) { + for (int i = 0; i < 2; i++) { + int j = IT(i, &rtk->opt); + xa[0] = j < rtk->na ? rtk->xa[j] : 0.0; + p += sprintf(p, "$TROP,%d,%.3f,%d,%d,%.4f,%.4f\n", week, tow, rtk->sol.stat, i + 1, + rtk->x[j], xa[0]); + } + } + /* Receiver h/w bias */ + if (est && rtk->opt.glomodear == GLO_ARMODE_AUTOCAL) { + for (int i = 0; i < nfreq; i++) { + int j = IL(i, &rtk->opt); + xa[0] = j < rtk->na ? rtk->xa[j] : 0.0; + p += sprintf(p, "$HWBIAS,%d,%.3f,%d,%d,%.4f,%.4f\n", week, tow, rtk->sol.stat, i + 1, + rtk->x[j], xa[0]); + } + } + } - if (level <= 1) return (int)(p-buff); - - /* Write residuals and status */ - for (int i=0;issat+i; - if (!ssat->vs) continue; - satno2id(i+1,id); - for (int j=0;jopt); - p+=sprintf(p,"$SAT,%d,%.3f,%s,%d,%.1f,%.1f,%.4f,%.4f,%d,%.0f,%d,%d,%d,%u,%u,%u,%.2f,%.6f,%.5f\n", - week,tow,id,j+1,ssat->azel[0]*R2D,ssat->azel[1]*R2D, - ssat->resp[j],ssat->resc[j],ssat->vsat[j],ssat->snr_rover[j], - ssat->fix[j],ssat->slip[j]&(LLI_SLIP|LLI_HALFC),ssat->lock[j],ssat->outc[j], - ssat->slipc[j],ssat->rejc[j],knx?rtk->x[k]:0, - knx?rtk->P[k+k*rtk->nx]:0,ssat->icbias[j]); - } + if (level <= 1) return (int)(p - buff); + + /* Write residuals and status */ + for (int i = 0; i < MAXSAT; i++) { + ssat = rtk->ssat + i; + if (!ssat->vs) continue; + satno2id(i + 1, id); + for (int j = 0; j < nfreq; j++) { + int k = IB(i + 1, j, &rtk->opt); + p += sprintf( + p, "$SAT,%d,%.3f,%s,%d,%.1f,%.1f,%.4f,%.4f,%d,%.0f,%d,%d,%d,%u,%u,%u,%.2f,%.6f,%.5f\n", + week, tow, id, j + 1, ssat->azel[0] * R2D, ssat->azel[1] * R2D, ssat->resp[j], + ssat->resc[j], ssat->vsat[j], ssat->snr_rover[j], ssat->fix[j], + ssat->slip[j] & (LLI_SLIP | LLI_HALFC), ssat->lock[j], ssat->outc[j], ssat->slipc[j], + ssat->rejc[j], k < rtk->nx ? rtk->x[k] : 0, k < rtk->nx ? rtk->P[k + k * rtk->nx] : 0, + ssat->icbias[j]); } + } - return (int)(p-buff); + return (int)(p - buff); } /* swap solution status file -------------------------------------------------*/ -static void swapsolstat(void) -{ - gtime_t time=utc2gpst(timeget()); - char path[1024]; +static void swapsolstat(void) { + gtime_t time = utc2gpst(timeget()); + char path[1024]; - if ((int)(time2gpst(time ,NULL)/INT_SWAP_STAT)== - (int)(time2gpst(time_stat,NULL)/INT_SWAP_STAT)) { - return; - } - time_stat=time; + if ((int)(time2gpst(time, NULL) / INT_SWAP_STAT) == + (int)(time2gpst(time_stat, NULL) / INT_SWAP_STAT)) { + return; + } + time_stat = time; - if (!reppath(file_stat,path,time,"","")) { - return; - } - if (fp_stat) fclose(fp_stat); + if (!reppath(file_stat, path, time, "", "")) { + return; + } + if (fp_stat) fclose(fp_stat); - if (!(fp_stat=fopen(path,"w"))) { - trace(2,"swapsolstat: file open error path=%s\n",path); - return; - } - trace(3,"swapsolstat: path=%s\n",path); + if (!(fp_stat = fopen(path, "w"))) { + trace(2, "swapsolstat: file open error path=%s\n", path); + return; + } + trace(3, "swapsolstat: path=%s\n", path); } /* output solution status ----------------------------------------------------*/ -static void outsolstat(rtk_t *rtk,const nav_t *nav) -{ - (void)nav; - if (statlevel<=0||!fp_stat||!rtk->sol.stat) return; - - trace(3,"outsolstat:\n"); - - /* swap solution status file */ - swapsolstat(); - - /* write solution status */ - char buff[MAXSOLMSG+1]; - int n=rtkoutstat(rtk,statlevel,buff); - buff[n]='\0'; - - fputs(buff,fp_stat); +static void outsolstat(rtk_t *rtk, const nav_t *nav) { + (void)nav; + if (statlevel <= 0 || !fp_stat || !rtk->sol.stat) return; + + trace(3, "outsolstat:\n"); + + /* swap solution status file */ + swapsolstat(); + + /* write solution status */ + char buff[MAXSOLMSG + 1]; + int n = rtkoutstat(rtk, statlevel, buff); + buff[n] = '\0'; + + fputs(buff, fp_stat); } /* save error message --------------------------------------------------------*/ -static void errmsg(rtk_t *rtk, const char *format, ...) -{ - char buff[384],tstr[40]; - int n; - va_list ap; - time2str(rtk->sol.time,tstr,2); - n=sprintf(buff,"%s: ",tstr+11); - va_start(ap,format); - n+=vsprintf(buff+n,format,ap); - va_end(ap); - n=nneb?n:MAXERRMSG-rtk->neb; - memcpy(rtk->errbuf+rtk->neb,buff,n); - rtk->neb+=n; - trace(2,"%s",buff); +static void errmsg(rtk_t *rtk, const char *format, ...) { + char buff[384], tstr[40]; + int n; + va_list ap; + time2str(rtk->sol.time, tstr, 2); + n = sprintf(buff, "%s: ", tstr + 11); + va_start(ap, format); + n += vsprintf(buff + n, format, ap); + va_end(ap); + n = n < MAXERRMSG - rtk->neb ? n : MAXERRMSG - rtk->neb; + memcpy(rtk->errbuf + rtk->neb, buff, n); + rtk->neb += n; + trace(2, "%s", buff); } /* single-differenced observable ---------------------------------------------*/ -static double sdobs(const obsd_t *obs, int i, int j, int k) -{ - double pi=(kerr[5]; - double fact; - double sinel=sin(el),var; - int nf=NF(opt),frq,code; - - frq=f%nf;code=feratio[frq]; - /* else adjust variance between freqs */ - else fact=opt->eratio[frq]/opt->eratio[0]; - - /* adjust variance for constellation */ - switch (sys) { - case SYS_GPS: fact*=EFACT_GPS;break; - case SYS_GLO: fact*=EFACT_GLO;break; - case SYS_GAL: fact*=EFACT_GAL;break; - case SYS_SBS: fact*=EFACT_SBS;break; - case SYS_QZS: fact*=EFACT_QZS;break; - case SYS_CMP: fact*=EFACT_CMP;break; - case SYS_IRN: fact*=EFACT_IRN;break; - default: fact*=EFACT_GPS;break; - } - /* adjust variance for config parameters */ - a=fact*opt->err[1]; /* base term */ - b=fact*opt->err[2]; /* el term */ - c=opt->err[3]*bl/1E4; /* baseline term */ - d=CLIGHT*opt->sclkstab*dt; /* clock term */ - /* calculate variance */ - var=2.0*(a*a+b*b/sinel/sinel+c*c)+d*d; - if (opt->err[6]>0) { /* add SNR term */ - e=fact*opt->err[6]; - var+=e*e*(pow(10,0.1*MAX(snr_max-snr_rover,0))+ - pow(10,0.1*MAX(snr_max-snr_base, 0))); - } - if (opt->err[7]>0.0) { /* add rcvr stdevs term */ - if (code) var+=SQR(opt->err[7]*obs->Pstd[frq]); - else var+=SQR(opt->err[7]*obs->Lstd[frq]*0.2); - } - - var*=(opt->ionoopt==IONOOPT_IFLC)?SQR(3.0):1.0; - return var; +static double varerr(int sat, int sys, double el, double snr_rover, double snr_base, double bl, + double dt, int f, const prcopt_t *opt, const obsd_t *obs) { + (void)sat; + double a, b, c, d, e; + double snr_max = opt->err[5]; + double fact; + double sinel = sin(el), var; + int nf = NF(opt), frq, code; + + frq = f % nf; + code = f < nf ? 0 : 1; + /* increase variance for pseudoranges */ + if (code) fact = opt->eratio[frq]; + /* else adjust variance between freqs */ + else + fact = opt->eratio[frq] / opt->eratio[0]; + + /* adjust variance for constellation */ + switch (sys) { + case SYS_GPS: + fact *= EFACT_GPS; + break; + case SYS_GLO: + fact *= EFACT_GLO; + break; + case SYS_GAL: + fact *= EFACT_GAL; + break; + case SYS_SBS: + fact *= EFACT_SBS; + break; + case SYS_QZS: + fact *= EFACT_QZS; + break; + case SYS_CMP: + fact *= EFACT_CMP; + break; + case SYS_IRN: + fact *= EFACT_IRN; + break; + default: + fact *= EFACT_GPS; + break; + } + /* adjust variance for config parameters */ + a = fact * opt->err[1]; /* base term */ + b = fact * opt->err[2]; /* el term */ + c = opt->err[3] * bl / 1E4; /* baseline term */ + d = CLIGHT * opt->sclkstab * dt; /* clock term */ + /* calculate variance */ + var = 2.0 * (a * a + b * b / sinel / sinel + c * c) + d * d; + if (opt->err[6] > 0) { /* add SNR term */ + e = fact * opt->err[6]; + var += e * e * + (pow(10, 0.1 * MAX(snr_max - snr_rover, 0)) + pow(10, 0.1 * MAX(snr_max - snr_base, 0))); + } + if (opt->err[7] > 0.0) { /* add rcvr stdevs term */ + if (code) + var += SQR(opt->err[7] * obs->Pstd[frq]); + else + var += SQR(opt->err[7] * obs->Lstd[frq] * 0.2); + } + + var *= (opt->ionoopt == IONOOPT_IFLC) ? SQR(3.0) : 1.0; + return var; } /* baseline length -----------------------------------------------------------*/ -static double baseline(const double *ru, const double *rb, double *dr) -{ - int i; - for (i=0;i<3;i++) dr[i]=ru[i]-rb[i]; - return norm(dr,3); +static double baseline(const double *ru, const double *rb, double *dr) { + int i; + for (i = 0; i < 3; i++) dr[i] = ru[i] - rb[i]; + return norm(dr, 3); } /* initialize state and covariance -------------------------------------------*/ -static inline void initx(rtk_t *rtk, double xi, double var, int i) -{ - int j; - rtk->x[i]=xi; - for (j=0;jnx;j++) rtk->P[i+j*rtk->nx]=0.0; - for (j=0;jnx;j++) rtk->P[j+i*rtk->nx]=0.0; - rtk->P[i+i*rtk->nx]=var; +static inline void initx(rtk_t *rtk, double xi, double var, int i) { + int j; + rtk->x[i] = xi; + for (j = 0; j < rtk->nx; j++) rtk->P[i + j * rtk->nx] = 0.0; + for (j = 0; j < rtk->nx; j++) rtk->P[j + i * rtk->nx] = 0.0; + rtk->P[i + i * rtk->nx] = var; } /* select common satellites between rover and reference station --------------*/ -static int selsat(const obsd_t *obs, double *azel, int nu, int nr, - const prcopt_t *opt, int *sat, int *iu, int *ir) -{ - int i,j,k=0; - - trace(3,"selsat : nu=%d nr=%d\n",nu,nr); - - for (i=0,j=nu;iobs[j].sat) i--; - else if (azel[1+j*2]>=opt->elmin) { /* elevation at base station */ - sat[k]=obs[i].sat; iu[k]=i; ir[k++]=j; - trace(4,"(%2d) sat=%3d iu=%2d ir=%2d\n",k-1,obs[i].sat,i,j); - } +static int selsat(const obsd_t *obs, double *azel, int nu, int nr, const prcopt_t *opt, int *sat, + int *iu, int *ir) { + int i, j, k = 0; + + trace(3, "selsat : nu=%d nr=%d\n", nu, nr); + + for (i = 0, j = nu; i < nu && j < nu + nr; i++, j++) { + if (obs[i].sat < obs[j].sat) + j--; + else if (obs[i].sat > obs[j].sat) + i--; + else if (azel[1 + j * 2] >= opt->elmin) { /* elevation at base station */ + sat[k] = obs[i].sat; + iu[k] = i; + ir[k++] = j; + trace(4, "(%2d) sat=%3d iu=%2d ir=%2d\n", k - 1, obs[i].sat, i, j); } - return k; + } + return k; } /* temporal update of position/velocity/acceleration -------------------------*/ -static void udpos(rtk_t *rtk, double tt) -{ - double *F,*P,*FP,*x,*xp,pos[3],Q[9]={0},Qv[9],var=0.0; - int i,j,*ix,nx; - - trace(3,"udpos : tt=%.3f\n",tt); - - /* fixed mode */ - if (rtk->opt.mode==PMODE_FIXED) { - for (i=0;i<3;i++) initx(rtk,rtk->opt.ru[i],VAR_POS_FIX,i); - return; - } - /* initialize position for first epoch */ - if (norm(rtk->x, 3) <= RE_WGS84 / 2) { - trace(3,"rr_init=");tracemat(3,rtk->sol.rr,1,6,15,6); - for (i=0;i<3;i++) initx(rtk,rtk->sol.rr[i],VAR_POS,i); - if (rtk->opt.dynamics) { - for (i=3;i<6;i++) initx(rtk,rtk->sol.rr[i],VAR_VEL,i); - for (i=6;i<9;i++) initx(rtk,1E-6,VAR_ACC,i); - } - } - /* static mode */ - if (rtk->opt.mode==PMODE_STATIC||rtk->opt.mode==PMODE_STATIC_START) return; - - /* kinmatic mode without dynamics */ - if (!rtk->opt.dynamics) { - for (i=0;i<3;i++) initx(rtk,rtk->sol.rr[i],VAR_POS,i); - return; - } - /* check variance of estimated position */ - for (i=0;i<3;i++) var+=rtk->P[i+i*rtk->nx]; - var/=3.0; - - if (var>VAR_POS) { - /* reset position with large variance */ - for (i=0;i<3;i++) initx(rtk,rtk->sol.rr[i],VAR_POS,i); - for (i=3;i<6;i++) initx(rtk,rtk->sol.rr[i],VAR_VEL,i); - for (i=6;i<9;i++) initx(rtk,1E-6,VAR_ACC,i); - trace(2,"reset rtk position due to large variance: var=%.3f\n",var); - return; - } - /* generate valid state index */ - ix=imat(rtk->nx,1); - for (i=nx=0;inx;i++) { - /* TODO: The b34 code causes issues so use b33 code for now */ - if (i<9||(rtk->x[i]!=0.0&&rtk->P[i+i*rtk->nx]>0.0)) ix[nx++]=i; - } - /* state transition of position/velocity/acceleration */ - F=eye(nx); P=mat(nx,nx); FP=mat(nx,nx); x=mat(nx,1); xp=mat(nx,1); - - for (i=0;i<6;i++) { - F[i+(i+3)*nx]=tt; - } - /* include accel terms if filter is converged */ - if (varopt.thresar[1]) { - for (i=0;i<3;i++) { - F[i+(i+6)*nx]=(tt>=0?1:-1)*SQR(tt)/2.0; - } - } - else trace(3,"pos var too high for accel term: %.4f\n", var); - for (i=0;ix[ix[i]]; - for (j=0;jP[ix[i]+ix[j]*rtk->nx]; - } +static void udpos(rtk_t *rtk, double tt) { + double *F, *P, *FP, *x, *xp, pos[3], Q[9] = {0}, Qv[9], var = 0.0; + int i, j, *ix, nx; + + trace(3, "udpos : tt=%.3f\n", tt); + + /* fixed mode */ + if (rtk->opt.mode == PMODE_FIXED) { + for (i = 0; i < 3; i++) initx(rtk, rtk->opt.ru[i], VAR_POS_FIX, i); + return; + } + /* initialize position for first epoch */ + if (norm(rtk->x, 3) <= RE_WGS84 / 2) { + trace(3, "rr_init="); + tracemat(3, rtk->sol.rr, 1, 6, 15, 6); + for (i = 0; i < 3; i++) initx(rtk, rtk->sol.rr[i], VAR_POS, i); + if (rtk->opt.dynamics) { + for (i = 3; i < 6; i++) initx(rtk, rtk->sol.rr[i], VAR_VEL, i); + for (i = 6; i < 9; i++) initx(rtk, 1E-6, VAR_ACC, i); } - /* x=F*x, P=F*P*F' */ - matmul("NN",nx,1,nx,F,x,xp); - matmul("NN",nx,nx,nx,F,P,FP); - matmul("NT",nx,nx,nx,FP,F,P); - - for (i=0;ix[ix[i]]=xp[i]; - for (j=0;jP[ix[i]+ix[j]*rtk->nx]=P[i+j*nx]; - } + } + /* static mode */ + if (rtk->opt.mode == PMODE_STATIC || rtk->opt.mode == PMODE_STATIC_START) return; + + /* kinmatic mode without dynamics */ + if (!rtk->opt.dynamics) { + for (i = 0; i < 3; i++) initx(rtk, rtk->sol.rr[i], VAR_POS, i); + return; + } + /* check variance of estimated position */ + for (i = 0; i < 3; i++) var += rtk->P[i + i * rtk->nx]; + var /= 3.0; + + if (var > VAR_POS) { + /* reset position with large variance */ + for (i = 0; i < 3; i++) initx(rtk, rtk->sol.rr[i], VAR_POS, i); + for (i = 3; i < 6; i++) initx(rtk, rtk->sol.rr[i], VAR_VEL, i); + for (i = 6; i < 9; i++) initx(rtk, 1E-6, VAR_ACC, i); + trace(2, "reset rtk position due to large variance: var=%.3f\n", var); + return; + } + /* generate valid state index */ + ix = imat(rtk->nx, 1); + for (i = nx = 0; i < rtk->nx; i++) { + /* TODO: The b34 code causes issues so use b33 code for now */ + if (i < 9 || (rtk->x[i] != 0.0 && rtk->P[i + i * rtk->nx] > 0.0)) ix[nx++] = i; + } + /* state transition of position/velocity/acceleration */ + F = eye(nx); + P = mat(nx, nx); + FP = mat(nx, nx); + x = mat(nx, 1); + xp = mat(nx, 1); + + for (i = 0; i < 6; i++) { + F[i + (i + 3) * nx] = tt; + } + /* include accel terms if filter is converged */ + if (var < rtk->opt.thresar[1]) { + for (i = 0; i < 3; i++) { + F[i + (i + 6) * nx] = (tt >= 0 ? 1 : -1) * SQR(tt) / 2.0; + } + } else + trace(3, "pos var too high for accel term: %.4f\n", var); + for (i = 0; i < nx; i++) { + x[i] = rtk->x[ix[i]]; + for (j = 0; j < nx; j++) { + P[i + j * nx] = rtk->P[ix[i] + ix[j] * rtk->nx]; } - /* process noise added to only acceleration P=P+Q */ - Q[0]=Q[4]=SQR(rtk->opt.prn[3])*fabs(tt); - Q[8]=SQR(rtk->opt.prn[4])*fabs(tt); - ecef2pos(rtk->x,pos); - covecef(pos,Q,Qv); - for (i=0;i<3;i++) for (j=0;j<3;j++) { - rtk->P[i+6+(j+6)*rtk->nx]+=Qv[i+j*3]; + } + /* x=F*x, P=F*P*F' */ + matmul("NN", nx, 1, nx, F, x, xp); + matmul("NN", nx, nx, nx, F, P, FP); + matmul("NT", nx, nx, nx, FP, F, P); + + for (i = 0; i < nx; i++) { + rtk->x[ix[i]] = xp[i]; + for (j = 0; j < nx; j++) { + rtk->P[ix[i] + ix[j] * rtk->nx] = P[i + j * nx]; } - free(ix); free(F); free(P); free(FP); free(x); free(xp); + } + /* process noise added to only acceleration P=P+Q */ + Q[0] = Q[4] = SQR(rtk->opt.prn[3]) * fabs(tt); + Q[8] = SQR(rtk->opt.prn[4]) * fabs(tt); + ecef2pos(rtk->x, pos); + covecef(pos, Q, Qv); + for (i = 0; i < 3; i++) + for (j = 0; j < 3; j++) { + rtk->P[i + 6 + (j + 6) * rtk->nx] += Qv[i + j * 3]; + } + free(ix); + free(F); + free(P); + free(FP); + free(x); + free(xp); } /* temporal update of ionospheric parameters ---------------------------------*/ -static void udion(rtk_t *rtk, double tt, double bl, const int *sat, int ns) -{ - double el,fact; - int i,j; - - trace(3,"udion : tt=%.3f bl=%.0f ns=%d\n",tt,bl,ns); - - /* reset ionospheric delays for sats with long outages */ - for (i=1;i<=MAXSAT;i++) { - j=II(i,&rtk->opt); - if (rtk->x[j]!=0.0&& - rtk->ssat[i-1].outc[0]>GAP_RESION&&rtk->ssat[i-1].outc[1]>GAP_RESION) - rtk->x[j]=0.0; - } - for (i=0;iopt); - - if (rtk->x[j]==0.0) { - /* initialize ionospheric delay state */ - initx(rtk,1E-6,SQR(rtk->opt.std[1]*bl/1E4),j); - } - else { - /* elevation dependent factor of process noise */ - el=rtk->ssat[sat[i]-1].azel[1]; - fact=cos(el); - rtk->P[j+j*rtk->nx]+=SQR(rtk->opt.prn[1]*bl/1E4*fact)*fabs(tt); - } +static void udion(rtk_t *rtk, double tt, double bl, const int *sat, int ns) { + double el, fact; + int i, j; + + trace(3, "udion : tt=%.3f bl=%.0f ns=%d\n", tt, bl, ns); + + /* reset ionospheric delays for sats with long outages */ + for (i = 1; i <= MAXSAT; i++) { + j = II(i, &rtk->opt); + if (rtk->x[j] != 0.0 && rtk->ssat[i - 1].outc[0] > GAP_RESION && + rtk->ssat[i - 1].outc[1] > GAP_RESION) + rtk->x[j] = 0.0; + } + for (i = 0; i < ns; i++) { + j = II(sat[i], &rtk->opt); + + if (rtk->x[j] == 0.0) { + /* initialize ionospheric delay state */ + initx(rtk, 1E-6, SQR(rtk->opt.std[1] * bl / 1E4), j); + } else { + /* elevation dependent factor of process noise */ + el = rtk->ssat[sat[i] - 1].azel[1]; + fact = cos(el); + rtk->P[j + j * rtk->nx] += SQR(rtk->opt.prn[1] * bl / 1E4 * fact) * fabs(tt); } + } } /* temporal update of tropospheric parameters --------------------------------*/ -static void udtrop(rtk_t *rtk, double tt, double bl) -{ - (void)bl; - int i,j,k; +static void udtrop(rtk_t *rtk, double tt, double bl) { + (void)bl; + int i, j, k; - trace(3,"udtrop : tt=%.3f\n",tt); + trace(3, "udtrop : tt=%.3f\n", tt); - for (i=0;i<2;i++) { - j=IT(i,&rtk->opt); + for (i = 0; i < 2; i++) { + j = IT(i, &rtk->opt); - if (rtk->x[j]==0.0) { - initx(rtk,INIT_ZWD,SQR(rtk->opt.std[2]),j); /* initial zwd */ + if (rtk->x[j] == 0.0) { + initx(rtk, INIT_ZWD, SQR(rtk->opt.std[2]), j); /* initial zwd */ - if (rtk->opt.tropopt>=TROPOPT_ESTG) { - for (k=0;k<2;k++) initx(rtk,1E-6,VAR_GRA,++j); - } - } - else { - rtk->P[j+j*rtk->nx]+=SQR(rtk->opt.prn[2])*fabs(tt); + if (rtk->opt.tropopt >= TROPOPT_ESTG) { + for (k = 0; k < 2; k++) initx(rtk, 1E-6, VAR_GRA, ++j); + } + } else { + rtk->P[j + j * rtk->nx] += SQR(rtk->opt.prn[2]) * fabs(tt); - if (rtk->opt.tropopt>=TROPOPT_ESTG) { - for (k=0;k<2;k++) { - rtk->P[++j*(1+rtk->nx)]+=SQR(rtk->opt.prn[2]*0.3)*fabs(tt); - } - } + if (rtk->opt.tropopt >= TROPOPT_ESTG) { + for (k = 0; k < 2; k++) { + rtk->P[++j * (1 + rtk->nx)] += SQR(rtk->opt.prn[2] * 0.3) * fabs(tt); } + } } + } } /* temporal update of receiver h/w biases ------------------------------------*/ -static void udrcvbias(rtk_t *rtk, double tt) -{ - int i,j; +static void udrcvbias(rtk_t *rtk, double tt) { + int i, j; - trace(3,"udrcvbias: tt=%.3f\n",tt); + trace(3, "udrcvbias: tt=%.3f\n", tt); - for (i=0;iopt); + for (i = 0; i < NFREQGLO; i++) { + j = IL(i, &rtk->opt); - if (rtk->x[j]==0.0) { - /* add small offset to avoid initializing with zero */ - initx(rtk,rtk->opt.thresar[2]+1e-6,rtk->opt.thresar[3],j); - } - /* hold to fixed solution */ - else if (rtk->nfix>=rtk->opt.minfix) { - initx(rtk,rtk->xa[j],rtk->Pa[j+j*rtk->na],j); - } - else { - rtk->P[j+j*rtk->nx]+=SQR(rtk->opt.thresar[4])*fabs(tt); - } + if (rtk->x[j] == 0.0) { + /* add small offset to avoid initializing with zero */ + initx(rtk, rtk->opt.thresar[2] + 1e-6, rtk->opt.thresar[3], j); } + /* hold to fixed solution */ + else if (rtk->nfix >= rtk->opt.minfix) { + initx(rtk, rtk->xa[j], rtk->Pa[j + j * rtk->na], j); + } else { + rtk->P[j + j * rtk->nx] += SQR(rtk->opt.thresar[4]) * fabs(tt); + } + } } // Detect a change in the observation code for a given frequency index. // Only one bias per frequency index per satallite is supported, so if the @@ -656,7 +671,7 @@ static void udrcvbias(rtk_t *rtk, double tt) static void detslp_code(rtk_t *rtk, const obsd_t *obs, int i, int rcv) { int sat = obs[i].sat; int nf = rtk->opt.nf; - if (nf > NFREQ) nf = NFREQ; // Quieten compiler warnings on slip[] write. + if (nf > NFREQ) nf = NFREQ; // Quieten compiler warnings on slip[] write. for (int f = 0; f < nf; f++) { int code = obs[i].code[f]; if (code == CODE_NONE) continue; @@ -666,343 +681,336 @@ static void detslp_code(rtk_t *rtk, const obsd_t *obs, int i, int rcv) { // Skip flagging a slip and emitting a message when initializing. if (ccode != CODE_NONE) { rtk->ssat[sat - 1].slip[f] |= LLI_SLIP; - errmsg(rtk, "slip detected, code change (sat=%3d rcv=%d F=%d code=%2d %2s to %2d %2s)\n", sat, - rcv, f, ccode, code2obs(ccode), code, code2obs(code)); + errmsg(rtk, "slip detected, code change (sat=%3d rcv=%d F=%d code=%2d %2s to %2d %2s)\n", + sat, rcv, f, ccode, code2obs(ccode), code, code2obs(code)); } } } } /* detect cycle slip by LLI --------------------------------------------------*/ -static void detslp_ll(rtk_t *rtk, const obsd_t *obs, int i, int rcv) -{ - uint32_t slip,LLI; - int f,sat=obs[i].sat; +static void detslp_ll(rtk_t *rtk, const obsd_t *obs, int i, int rcv) { + uint32_t slip, LLI; + int f, sat = obs[i].sat; + + trace(4, "detslp_ll: i=%d rcv=%d\n", i, rcv); + + for (f = 0; f < rtk->opt.nf; f++) { + if ((obs[i].L[f] == 0.0 && obs[i].LLI[f] == 0) || + fabs(timediff(obs[i].time, rtk->ssat[sat - 1].pt[rcv - 1][f])) < DTTOL) { + continue; + } + /* restore previous LLI */ + if (rcv == 1) + LLI = getbitu(&rtk->ssat[sat - 1].slip[f], 0, 2); /* rover */ + else + LLI = getbitu(&rtk->ssat[sat - 1].slip[f], 2, 2); /* base */ + + /* detect slip by cycle slip flag in LLI */ + if (rtk->tt >= 0.0) { /* forward */ + if (obs[i].LLI[f] & LLI_SLIP) { + errmsg(rtk, "slip detected forward (sat=%2d rcv=%d F=%d LLI=%x)\n", sat, rcv, f + 1, + obs[i].LLI[f]); + } + slip = obs[i].LLI[f]; + } else { /* backward */ + if (LLI & LLI_SLIP) { + errmsg(rtk, "slip detected backward (sat=%2d rcv=%d F=%d LLI=%x)\n", sat, rcv, f + 1, LLI); + } + slip = LLI; + } + /* detect slip by parity unknown flag transition in LLI */ + if (((LLI & LLI_HALFC) && !(obs[i].LLI[f] & LLI_HALFC)) || + (!(LLI & LLI_HALFC) && (obs[i].LLI[f] & LLI_HALFC))) { + errmsg(rtk, "slip detected half-cyc (sat=%2d rcv=%d F=%d LLI=%x->%x)\n", sat, rcv, f + 1, LLI, + obs[i].LLI[f]); + slip |= LLI_SLIP; + } + /* save current LLI */ + if (rcv == 1) + setbitu(&rtk->ssat[sat - 1].slip[f], 0, 2, obs[i].LLI[f]); + else + setbitu(&rtk->ssat[sat - 1].slip[f], 2, 2, obs[i].LLI[f]); + + /* save slip and half-cycle valid flag */ + rtk->ssat[sat - 1].slip[f] |= (uint8_t)slip; + rtk->ssat[sat - 1].half[f] = (obs[i].LLI[f] & LLI_HALFC) ? 0 : 1; + } +} +/* detect cycle slip by geometry free phase jump -----------------------------*/ +static void detslp_gf(rtk_t *rtk, const obsd_t *obs, int i, int j, const nav_t *nav) { + int k, sat = obs[i].sat; + double gf0, gf1; - trace(4,"detslp_ll: i=%d rcv=%d\n",i,rcv); + trace(4, "detslp_gf: i=%d j=%d\n", i, j); - for (f=0;fopt.nf;f++) { + /* skip check if slip already detected or check disabled*/ + if (rtk->opt.thresslip == 0) return; + for (k = 0; k < rtk->opt.nf; k++) + if (rtk->ssat[sat - 1].slip[k] & LLI_SLIP) return; - if ((obs[i].L[f]==0.0&&obs[i].LLI[f]==0)|| - fabs(timediff(obs[i].time,rtk->ssat[sat-1].pt[rcv-1][f]))ssat[sat-1].slip[f],0,2); /* rover */ - else LLI=getbitu(&rtk->ssat[sat-1].slip[f],2,2); /* base */ - - /* detect slip by cycle slip flag in LLI */ - if (rtk->tt>=0.0) { /* forward */ - if (obs[i].LLI[f]&LLI_SLIP) { - errmsg(rtk,"slip detected forward (sat=%2d rcv=%d F=%d LLI=%x)\n", - sat,rcv,f+1,obs[i].LLI[f]); - } - slip=obs[i].LLI[f]; - } - else { /* backward */ - if (LLI&LLI_SLIP) { - errmsg(rtk,"slip detected backward (sat=%2d rcv=%d F=%d LLI=%x)\n", - sat,rcv,f+1,LLI); - } - slip=LLI; - } - /* detect slip by parity unknown flag transition in LLI */ - if (((LLI&LLI_HALFC)&&!(obs[i].LLI[f]&LLI_HALFC))|| - (!(LLI&LLI_HALFC)&&(obs[i].LLI[f]&LLI_HALFC))) { - errmsg(rtk,"slip detected half-cyc (sat=%2d rcv=%d F=%d LLI=%x->%x)\n", - sat,rcv,f+1,LLI,obs[i].LLI[f]); - slip|=LLI_SLIP; - } - /* save current LLI */ - if (rcv==1) setbitu(&rtk->ssat[sat-1].slip[f],0,2,obs[i].LLI[f]); - else setbitu(&rtk->ssat[sat-1].slip[f],2,2,obs[i].LLI[f]); + for (k = 1; k < rtk->opt.nf; k++) { + /* calc SD geomotry free LC of phase between freq0 and freqk */ + if ((gf1 = gfobs(obs, i, j, k, nav)) == 0.0) continue; - /* save slip and half-cycle valid flag */ - rtk->ssat[sat-1].slip[f]|=(uint8_t)slip; - rtk->ssat[sat-1].half[f]=(obs[i].LLI[f]&LLI_HALFC)?0:1; - } -} -/* detect cycle slip by geometry free phase jump -----------------------------*/ -static void detslp_gf(rtk_t *rtk, const obsd_t *obs, int i, int j, - const nav_t *nav) -{ - int k,sat=obs[i].sat; - double gf0,gf1; - - trace(4,"detslp_gf: i=%d j=%d\n",i,j); - - /* skip check if slip already detected or check disabled*/ - if (rtk->opt.thresslip==0) return; - for (k=0;kopt.nf;k++) - if (rtk->ssat[sat-1].slip[k]&LLI_SLIP) return; - - for (k=1;kopt.nf;k++) { - /* calc SD geomotry free LC of phase between freq0 and freqk */ - if ((gf1=gfobs(obs,i,j,k,nav))==0.0) continue; - - gf0=rtk->ssat[sat-1].gf[k-1]; /* retrieve previous gf */ - rtk->ssat[sat-1].gf[k-1]=gf1; /* save current gf for next epoch */ - - if (gf0!=0.0&&fabs(gf1-gf0)>rtk->opt.thresslip) { - rtk->ssat[sat-1].slip[0]|=LLI_SLIP; - rtk->ssat[sat-1].slip[k]|=LLI_SLIP; - errmsg(rtk,"slip detected GF jump (sat=%2d L1-L%d dGF=%.3f)\n", - sat,k+1,gf0-gf1); - } + gf0 = rtk->ssat[sat - 1].gf[k - 1]; /* retrieve previous gf */ + rtk->ssat[sat - 1].gf[k - 1] = gf1; /* save current gf for next epoch */ + + if (gf0 != 0.0 && fabs(gf1 - gf0) > rtk->opt.thresslip) { + rtk->ssat[sat - 1].slip[0] |= LLI_SLIP; + rtk->ssat[sat - 1].slip[k] |= LLI_SLIP; + errmsg(rtk, "slip detected GF jump (sat=%2d L1-L%d dGF=%.3f)\n", sat, k + 1, gf0 - gf1); } + } } /* detect cycle slip by doppler and phase difference -------------------------*/ -static void detslp_dop(rtk_t *rtk, const obsd_t *obs, const int *ix, int ns, - int rcv, const nav_t *nav) -{ - (void)nav; - int i,ii,f,sat,ndop=0,nf=rtk->opt.nf; - double dph,dpt,mean_dop=0; - double dopdif[MAXSAT][NFREQ], tt[MAXSAT][NFREQ]; - - trace(4,"detslp_dop: rcv=%d\n", rcv); - if (rtk->opt.thresdop<=0) return; /* skip test if doppler thresh <= 0 */ - - /* calculate doppler differences for all sats and freqs */ - for (i=0;issat[sat-1].ph[rcv-1][f]==0.0) continue; - if (fabs(tt[i][f]=timediff(obs[ii].time,rtk->ssat[sat-1].pt[rcv-1][f]))ssat[sat-1].ph[rcv-1][f])/tt[i][f]; - dpt=-obs[ii].D[f]; - dopdif[i][f]=dph-dpt; - - /* if not outlier, use this to calculate mean */ - if (fabs(dopdif[i][f])<3*rtk->opt.thresdop) { - mean_dop+=dopdif[i][f]; - ndop++; - } - } +static void detslp_dop(rtk_t *rtk, const obsd_t *obs, const int *ix, int ns, int rcv, + const nav_t *nav) { + (void)nav; + int i, ii, f, sat, ndop = 0, nf = rtk->opt.nf; + double dph, dpt, mean_dop = 0; + double dopdif[MAXSAT][NFREQ], tt[MAXSAT][NFREQ]; + + trace(4, "detslp_dop: rcv=%d\n", rcv); + if (rtk->opt.thresdop <= 0) return; /* skip test if doppler thresh <= 0 */ + + /* calculate doppler differences for all sats and freqs */ + for (i = 0; i < ns; i++) { + ii = ix[i]; + sat = obs[ii].sat; + + for (f = 0; f < nf; f++) { + dopdif[i][f] = 0; + tt[i][f] = 0.00; + if (obs[ii].L[f] == 0.0 || obs[ii].D[f] == 0.0 || rtk->ssat[sat - 1].ph[rcv - 1][f] == 0.0) + continue; + if (fabs(tt[i][f] = timediff(obs[ii].time, rtk->ssat[sat - 1].pt[rcv - 1][f])) < DTTOL) + continue; + + /* calc phase difference and doppler x time (cycle) */ + dph = (obs[ii].L[f] - rtk->ssat[sat - 1].ph[rcv - 1][f]) / tt[i][f]; + dpt = -obs[ii].D[f]; + dopdif[i][f] = dph - dpt; + + /* if not outlier, use this to calculate mean */ + if (fabs(dopdif[i][f]) < 3 * rtk->opt.thresdop) { + mean_dop += dopdif[i][f]; + ndop++; + } } - /* calc mean doppler diff, most likely due to clock error */ - if (ndop==0) return; /* unable to calc mean doppler, usually very large clock err */ - mean_dop=mean_dop/ndop; + } + /* calc mean doppler diff, most likely due to clock error */ + if (ndop == 0) return; /* unable to calc mean doppler, usually very large clock err */ + mean_dop = mean_dop / ndop; - /* set slip if doppler difference with mean removed exceeds threshold */ - for (i=0;irtk->opt.thresdop) { - rtk->ssat[sat-1].slip[f]|=LLI_SLIP; - errmsg(rtk,"slip detected doppler (sat=%2d rcv=%d dL%d=%.3f off=%.3f tt=%.2f)\n", - sat,rcv,f+1,dopdif[i][f]-mean_dop,mean_dop,tt[i][f]); - } - } + for (f = 0; f < nf; f++) { + if (dopdif[i][f] == 0.00) continue; + if (fabs(dopdif[i][f] - mean_dop) > rtk->opt.thresdop) { + rtk->ssat[sat - 1].slip[f] |= LLI_SLIP; + errmsg(rtk, "slip detected doppler (sat=%2d rcv=%d dL%d=%.3f off=%.3f tt=%.2f)\n", sat, rcv, + f + 1, dopdif[i][f] - mean_dop, mean_dop, tt[i][f]); + } } + } } /* temporal update of phase biases -------------------------------------------*/ -static void udbias(rtk_t *rtk, double tt, const obsd_t *obs, const int *sat, - const int *iu, const int *ir, int ns, const nav_t *nav) -{ - double cp,pr,cp1,cp2,pr1,pr2,*bias,offset,freqi,freq1,freq2,C1,C2; - int i,j,k,slip,rejc,reset,nf=NF(&rtk->opt),f2; +static void udbias(rtk_t *rtk, double tt, const obsd_t *obs, const int *sat, const int *iu, + const int *ir, int ns, const nav_t *nav) { + double cp, pr, cp1, cp2, pr1, pr2, *bias, offset, freqi, freq1, freq2, C1, C2; + int i, j, k, slip, rejc, reset, nf = NF(&rtk->opt), f2; - trace(3,"udbias : tt=%.3f ns=%d\n",tt,ns); + trace(3, "udbias : tt=%.3f ns=%d\n", tt, ns); - /* clear cycle slips */ - for (i=0;iopt.nf;k++) rtk->ssat[sat[i]-1].slip[k]&=0xFC; - } + /* clear cycle slips */ + for (i = 0; i < ns; i++) { + for (k = 0; k < rtk->opt.nf; k++) rtk->ssat[sat[i] - 1].slip[k] &= 0xFC; + } - /* detect cycle slip by doppler and phase difference */ - detslp_dop(rtk,obs,iu,ns,1,nav); - detslp_dop(rtk,obs,ir,ns,2,nav); + /* detect cycle slip by doppler and phase difference */ + detslp_dop(rtk, obs, iu, ns, 1, nav); + detslp_dop(rtk, obs, ir, ns, 2, nav); - for (i=0;issat[sat[i]-1].half[k]= - !((obs[iu[i]].LLI[k]&LLI_HALFC)||(obs[ir[i]].LLI[k]&LLI_HALFC)); - } + /* update half-cycle valid flag */ + for (k = 0; k < nf; k++) { + rtk->ssat[sat[i] - 1].half[k] = + !((obs[iu[i]].LLI[k] & LLI_HALFC) || (obs[ir[i]].LLI[k] & LLI_HALFC)); } - for (k=0;kssat[i-1].outc[k]>(uint32_t)rtk->opt.maxout; - - if (rtk->opt.modear==ARMODE_INST&&rtk->x[IB(i,k,&rtk->opt)]!=0.0) { - initx(rtk,0.0,0.0,IB(i,k,&rtk->opt)); - } - else if (reset&&rtk->x[IB(i,k,&rtk->opt)]!=0.0) { - initx(rtk,0.0,0.0,IB(i,k,&rtk->opt)); - trace(3,"udbias : obs outage counter overflow (sat=%3d L%d n=%d)\n", - i,k+1,rtk->ssat[i-1].outc[k]); - rtk->ssat[i-1].outc[k]=0; - } - if (rtk->opt.modear!=ARMODE_INST&&reset) { - rtk->ssat[i-1].lock[k]=-rtk->opt.minlock; - } - } - /* update phase bias noise and check for cycle slips */ - for (i=0;iopt); - rtk->P[j+j*rtk->nx]+=rtk->opt.prn[0]*rtk->opt.prn[0]*fabs(tt); - slip=rtk->ssat[sat[i]-1].slip[k]; - rejc=rtk->ssat[sat[i]-1].rejc[k]; - if (rtk->opt.ionoopt==IONOOPT_IFLC) { - f2=seliflc(rtk->opt.nf,rtk->ssat[sat[i]-1].sys); - slip|=rtk->ssat[sat[i]-1].slip[f2]; - } - if (rtk->opt.modear==ARMODE_INST||(!(slip&LLI_SLIP)&&rejc<2)) continue; - /* reset phase-bias state if detecting cycle slip or outlier */ - rtk->x[j]=0.0; - rtk->ssat[sat[i]-1].rejc[k]=0; - rtk->ssat[sat[i]-1].lock[k]=-rtk->opt.minlock; - /* retain icbiases for GLONASS sats */ - if (rtk->ssat[sat[i]-1].sys!=SYS_GLO) rtk->ssat[sat[i]-1].icbias[k]=0; - } - bias=zeros(ns,1); - - /* estimate approximate phase-bias by delta phase - delta code */ - for (i=j=0,offset=0.0;iopt.ionoopt!=IONOOPT_IFLC) { - /* phase diff between rover and base in cycles */ - cp=sdobs(obs,iu[i],ir[i],k); /* cycle */ - /* pseudorange diff between rover and base in meters */ - pr=sdobs(obs,iu[i],ir[i],k+NFREQ); - freqi=sat2freq(sat[i],obs[iu[i]].code[k],nav); - if (cp==0.0||pr==0.0||freqi==0.0) continue; - /* estimate bias in cycles */ - bias[i]=cp-pr*freqi/CLIGHT; - } - else { /* use ionosphere free calc with 2 freqs */ - f2=seliflc(rtk->opt.nf,rtk->ssat[sat[i]-1].sys); - cp1=sdobs(obs,iu[i],ir[i],0); - cp2=sdobs(obs,iu[i],ir[i],f2); - pr1=sdobs(obs,iu[i],ir[i],NFREQ); - pr2=sdobs(obs,iu[i],ir[i],NFREQ+f2); - freq1=sat2freq(sat[i],obs[iu[i]].code[0],nav); - freq2=sat2freq(sat[i],obs[iu[i]].code[f2],nav); - if (cp1==0.0||cp2==0.0||pr1==0.0||pr2==0.0||freq1<=0.0||freq2<=0.0) continue; - - C1= SQR(freq1)/(SQR(freq1)-SQR(freq2)); - C2=-SQR(freq2)/(SQR(freq1)-SQR(freq2)); - /* estimate bias in meters */ - bias[i]=(C1*cp1*CLIGHT/freq1+C2*cp2*CLIGHT/freq2)-(C1*pr1+C2*pr2); - } - if (rtk->x[IB(sat[i],k,&rtk->opt)]!=0.0) { - offset+=bias[i]-rtk->x[IB(sat[i],k,&rtk->opt)]; - j++; - } - } - /* correct phase-bias offset to ensure phase-code coherency */ - if (j>0) { - for (i=1;i<=MAXSAT;i++) { - if (rtk->x[IB(i,k,&rtk->opt)]!=0.0) rtk->x[IB(i,k,&rtk->opt)]+=offset/j; - } - } - /* set initial states of phase-bias */ - for (i=0;ix[IB(sat[i],k,&rtk->opt)]!=0.0) continue; - initx(rtk,bias[i],SQR(rtk->opt.std[0]),IB(sat[i],k,&rtk->opt)); - trace(3," sat=%3d, F=%d: init phase=%.3f\n",sat[i],k+1,bias[i]); - if (rtk->opt.modear!=ARMODE_INST) { - rtk->ssat[sat[i]-1].lock[k]=-rtk->opt.minlock; - } - } - free(bias); + } + for (k = 0; k < nf; k++) { + /* reset phase-bias if instantaneous AR or expire obs outage counter */ + for (i = 1; i <= MAXSAT; i++) { + reset = ++rtk->ssat[i - 1].outc[k] > (uint32_t)rtk->opt.maxout; + + if (rtk->opt.modear == ARMODE_INST && rtk->x[IB(i, k, &rtk->opt)] != 0.0) { + initx(rtk, 0.0, 0.0, IB(i, k, &rtk->opt)); + } else if (reset && rtk->x[IB(i, k, &rtk->opt)] != 0.0) { + initx(rtk, 0.0, 0.0, IB(i, k, &rtk->opt)); + trace(3, "udbias : obs outage counter overflow (sat=%3d L%d n=%d)\n", i, k + 1, + rtk->ssat[i - 1].outc[k]); + rtk->ssat[i - 1].outc[k] = 0; + } + if (rtk->opt.modear != ARMODE_INST && reset) { + rtk->ssat[i - 1].lock[k] = -rtk->opt.minlock; + } + } + /* update phase bias noise and check for cycle slips */ + for (i = 0; i < ns; i++) { + j = IB(sat[i], k, &rtk->opt); + rtk->P[j + j * rtk->nx] += rtk->opt.prn[0] * rtk->opt.prn[0] * fabs(tt); + slip = rtk->ssat[sat[i] - 1].slip[k]; + rejc = rtk->ssat[sat[i] - 1].rejc[k]; + if (rtk->opt.ionoopt == IONOOPT_IFLC) { + f2 = seliflc(rtk->opt.nf, rtk->ssat[sat[i] - 1].sys); + slip |= rtk->ssat[sat[i] - 1].slip[f2]; + } + if (rtk->opt.modear == ARMODE_INST || (!(slip & LLI_SLIP) && rejc < 2)) continue; + /* reset phase-bias state if detecting cycle slip or outlier */ + rtk->x[j] = 0.0; + rtk->ssat[sat[i] - 1].rejc[k] = 0; + rtk->ssat[sat[i] - 1].lock[k] = -rtk->opt.minlock; + /* retain icbiases for GLONASS sats */ + if (rtk->ssat[sat[i] - 1].sys != SYS_GLO) rtk->ssat[sat[i] - 1].icbias[k] = 0; + } + bias = zeros(ns, 1); + + /* estimate approximate phase-bias by delta phase - delta code */ + for (i = j = 0, offset = 0.0; i < ns; i++) { + if (rtk->opt.ionoopt != IONOOPT_IFLC) { + /* phase diff between rover and base in cycles */ + cp = sdobs(obs, iu[i], ir[i], k); /* cycle */ + /* pseudorange diff between rover and base in meters */ + pr = sdobs(obs, iu[i], ir[i], k + NFREQ); + freqi = sat2freq(sat[i], obs[iu[i]].code[k], nav); + if (cp == 0.0 || pr == 0.0 || freqi == 0.0) continue; + /* estimate bias in cycles */ + bias[i] = cp - pr * freqi / CLIGHT; + } else { /* use ionosphere free calc with 2 freqs */ + f2 = seliflc(rtk->opt.nf, rtk->ssat[sat[i] - 1].sys); + cp1 = sdobs(obs, iu[i], ir[i], 0); + cp2 = sdobs(obs, iu[i], ir[i], f2); + pr1 = sdobs(obs, iu[i], ir[i], NFREQ); + pr2 = sdobs(obs, iu[i], ir[i], NFREQ + f2); + freq1 = sat2freq(sat[i], obs[iu[i]].code[0], nav); + freq2 = sat2freq(sat[i], obs[iu[i]].code[f2], nav); + if (cp1 == 0.0 || cp2 == 0.0 || pr1 == 0.0 || pr2 == 0.0 || freq1 <= 0.0 || freq2 <= 0.0) + continue; + + C1 = SQR(freq1) / (SQR(freq1) - SQR(freq2)); + C2 = -SQR(freq2) / (SQR(freq1) - SQR(freq2)); + /* estimate bias in meters */ + bias[i] = (C1 * cp1 * CLIGHT / freq1 + C2 * cp2 * CLIGHT / freq2) - (C1 * pr1 + C2 * pr2); + } + if (rtk->x[IB(sat[i], k, &rtk->opt)] != 0.0) { + offset += bias[i] - rtk->x[IB(sat[i], k, &rtk->opt)]; + j++; + } } + /* correct phase-bias offset to ensure phase-code coherency */ + if (j > 0) { + for (i = 1; i <= MAXSAT; i++) { + if (rtk->x[IB(i, k, &rtk->opt)] != 0.0) rtk->x[IB(i, k, &rtk->opt)] += offset / j; + } + } + /* set initial states of phase-bias */ + for (i = 0; i < ns; i++) { + if (bias[i] == 0.0 || rtk->x[IB(sat[i], k, &rtk->opt)] != 0.0) continue; + initx(rtk, bias[i], SQR(rtk->opt.std[0]), IB(sat[i], k, &rtk->opt)); + trace(3, " sat=%3d, F=%d: init phase=%.3f\n", sat[i], k + 1, bias[i]); + if (rtk->opt.modear != ARMODE_INST) { + rtk->ssat[sat[i] - 1].lock[k] = -rtk->opt.minlock; + } + } + free(bias); + } } /* Temporal update of states --------------------------------------------------*/ -static void udstate(rtk_t *rtk, const obsd_t *obs, const int *sat, - const int *iu, const int *ir, int ns, const nav_t *nav) -{ - trace(3,"udstate : ns=%d\n",ns); - - double tt=rtk->tt; - - /* Temporal update of position/velocity/acceleration */ - udpos(rtk,tt); - - /* Temporal update of ionospheric parameters */ - if (rtk->opt.ionoopt==IONOOPT_EST || rtk->opt.tropopt>=TROPOPT_EST) { - double dr[3], bl=baseline(rtk->x,rtk->rb,dr); - if (rtk->opt.ionoopt==IONOOPT_EST) { - udion(rtk,tt,bl,sat,ns); - } - /* Temporal update of tropospheric parameters */ - if (rtk->opt.tropopt>=TROPOPT_EST) { - udtrop(rtk,tt,bl); - } - } - /* Temporal update of receiver h/w bias */ - if (rtk->opt.glomodear==GLO_ARMODE_AUTOCAL&&(rtk->opt.navsys&SYS_GLO)) { - udrcvbias(rtk,tt); +static void udstate(rtk_t *rtk, const obsd_t *obs, const int *sat, const int *iu, const int *ir, + int ns, const nav_t *nav) { + trace(3, "udstate : ns=%d\n", ns); + + double tt = rtk->tt; + + /* Temporal update of position/velocity/acceleration */ + udpos(rtk, tt); + + /* Temporal update of ionospheric parameters */ + if (rtk->opt.ionoopt == IONOOPT_EST || rtk->opt.tropopt >= TROPOPT_EST) { + double dr[3], bl = baseline(rtk->x, rtk->rb, dr); + if (rtk->opt.ionoopt == IONOOPT_EST) { + udion(rtk, tt, bl, sat, ns); } - /* Temporal update of phase-bias */ - if (rtk->opt.mode>PMODE_DGPS) { - udbias(rtk,tt,obs,sat,iu,ir,ns,nav); + /* Temporal update of tropospheric parameters */ + if (rtk->opt.tropopt >= TROPOPT_EST) { + udtrop(rtk, tt, bl); } + } + /* Temporal update of receiver h/w bias */ + if (rtk->opt.glomodear == GLO_ARMODE_AUTOCAL && (rtk->opt.navsys & SYS_GLO)) { + udrcvbias(rtk, tt); + } + /* Temporal update of phase-bias */ + if (rtk->opt.mode > PMODE_DGPS) { + udbias(rtk, tt, obs, sat, iu, ir, ns, nav); + } } /* UD (undifferenced) phase/code residual for satellite ----------------------*/ -static void zdres_sat(int base, double r, const obsd_t *obs, const nav_t *nav, - const double *azel, const double *dant, - const prcopt_t *opt, double *y, double *freq) -{ - double freq1,freq2,C1,C2,dant_if; - int i,nf=NF(opt),f2; +static void zdres_sat(int base, double r, const obsd_t *obs, const nav_t *nav, const double *azel, + const double *dant, const prcopt_t *opt, double *y, double *freq) { + double freq1, freq2, C1, C2, dant_if; + int i, nf = NF(opt), f2; - if (opt->ionoopt==IONOOPT_IFLC) { /* iono-free linear combination */ - freq1=sat2freq(obs->sat,obs->code[0],nav); - f2=seliflc(opt->nf,satsys(obs->sat,NULL)); - freq2=sat2freq(obs->sat,obs->code[f2],nav); + if (opt->ionoopt == IONOOPT_IFLC) { /* iono-free linear combination */ + freq1 = sat2freq(obs->sat, obs->code[0], nav); + f2 = seliflc(opt->nf, satsys(obs->sat, NULL)); + freq2 = sat2freq(obs->sat, obs->code[f2], nav); - if (freq1==0.0||freq2==0.0) return; + if (freq1 == 0.0 || freq2 == 0.0) return; - if (testsnr(base,0,azel[1],obs->SNR[0],&opt->snrmask)|| - testsnr(base,f2,azel[1],obs->SNR[f2],&opt->snrmask)) return; + if (testsnr(base, 0, azel[1], obs->SNR[0], &opt->snrmask) || + testsnr(base, f2, azel[1], obs->SNR[f2], &opt->snrmask)) + return; - C1= SQR(freq1)/(SQR(freq1)-SQR(freq2)); - C2=-SQR(freq2)/(SQR(freq1)-SQR(freq2)); - dant_if=C1*dant[0]+C2*dant[f2]; + C1 = SQR(freq1) / (SQR(freq1) - SQR(freq2)); + C2 = -SQR(freq2) / (SQR(freq1) - SQR(freq2)); + dant_if = C1 * dant[0] + C2 * dant[f2]; - if (obs->L[0]!=0.0&&obs->L[f2]!=0.0) { - y[0]=C1*obs->L[0]*CLIGHT/freq1+C2*obs->L[f2]*CLIGHT/freq2-r-dant_if; - } - if (obs->P[0]!=0.0&&obs->P[f2]!=0.0) { - y[nf]=C1*obs->P[0]+C2*obs->P[f2]-r-dant_if; - } - freq[0]=1.0; + if (obs->L[0] != 0.0 && obs->L[f2] != 0.0) { + y[0] = C1 * obs->L[0] * CLIGHT / freq1 + C2 * obs->L[f2] * CLIGHT / freq2 - r - dant_if; + } + if (obs->P[0] != 0.0 && obs->P[f2] != 0.0) { + y[nf] = C1 * obs->P[0] + C2 * obs->P[f2] - r - dant_if; } - else { - for (i=0;isat,obs->code[i],nav))==0.0) continue; + freq[0] = 1.0; + } else { + for (i = 0; i < nf; i++) { + if ((freq[i] = sat2freq(obs->sat, obs->code[i], nav)) == 0.0) continue; - /* check SNR mask */ - if (testsnr(base,i,azel[1],obs->SNR[i],&opt->snrmask)) { - continue; - } - /* residuals = observable - estimated range */ - if (obs->L[i]!=0.0) y[i ]=obs->L[i]*CLIGHT/freq[i]-r-dant[i]; - if (obs->P[i]!=0.0) y[i+nf]=obs->P[i] -r-dant[i]; - trace(4,"zdres_sat: %d: L=%.6f P=%.6f r=%.6f f=%.0f\n",obs->sat,obs->L[i], - obs->P[i],r,freq[i]); - } + /* check SNR mask */ + if (testsnr(base, i, azel[1], obs->SNR[i], &opt->snrmask)) { + continue; + } + /* residuals = observable - estimated range */ + if (obs->L[i] != 0.0) y[i] = obs->L[i] * CLIGHT / freq[i] - r - dant[i]; + if (obs->P[i] != 0.0) y[i + nf] = obs->P[i] - r - dant[i]; + trace(4, "zdres_sat: %d: L=%.6f P=%.6f r=%.6f f=%.0f\n", obs->sat, obs->L[i], obs->P[i], r, + freq[i]); } + } } /* undifferenced phase/code residuals ---------------------------------------- calculate zero diff residuals [observed pseudorange - range] @@ -1020,179 +1028,177 @@ static void zdres_sat(int base, double r, const obsd_t *obs, const nav_t *nav, O y[(0:1)+i*2] = zero diff residuals {phase,code} (m) O e = line of sight unit vectors to sats O azel = [az, el] to sats */ -static int zdres(int base, const obsd_t *obs, int n, const double *rs, - const double *dts, const double *var, const int *svh, - const nav_t *nav, const double *rr, const prcopt_t *opt, - double *y, double *e, double *azel, double *freq) -{ - double r,rr_[3],pos[3],dant[NFREQ]={0},disp[3]; - double mapfh,zhd,zazel[]={0.0,90.0*D2R}; - int i,nf=NF(opt); +static int zdres(int base, const obsd_t *obs, int n, const double *rs, const double *dts, + const double *var, const int *svh, const nav_t *nav, const double *rr, + const prcopt_t *opt, double *y, double *e, double *azel, double *freq) { + double r, rr_[3], pos[3], dant[NFREQ] = {0}, disp[3]; + double mapfh, zhd, zazel[] = {0.0, 90.0 * D2R}; + int i, nf = NF(opt); - trace(3,"zdres : n=%d rr=%.2f %.2f %.2f\n",n,rr[0], rr[1], rr[2]); + trace(3, "zdres : n=%d rr=%.2f %.2f %.2f\n", n, rr[0], rr[1], rr[2]); - /* init residuals to zero */ - for (i=0;itidecorr) { - tidedisp(gpst2utc(obs[0].time),rr_,opt->tidecorr,&nav->erp, - opt->odisp[base],disp); - for (i=0;i<3;i++) rr_[i]+=disp[i]; - } - /* translate rcvr pos from ecef to geodetic */ - ecef2pos(rr_,pos); + /* adjust rcvr pos for earth tide correction */ + if (opt->tidecorr) { + tidedisp(gpst2utc(obs[0].time), rr_, opt->tidecorr, &nav->erp, opt->odisp[base], disp); + for (i = 0; i < 3; i++) rr_[i] += disp[i]; + } + /* translate rcvr pos from ecef to geodetic */ + ecef2pos(rr_, pos); - /* loop through satellites */ - for (i=0;ielmin) continue; + /* loop through satellites */ + for (i = 0; i < n; i++) { + /* compute geometric-range and azimuth/elevation angle */ + if ((r = geodist(rs + i * 6, rr_, e + i * 3)) <= 0.0) continue; + if (satazel(pos, e + i * 3, azel + i * 2) < opt->elmin) continue; - /* excluded satellite? */ - if (satexclude(obs[i].sat,var[i],svh[i],opt)) continue; + /* excluded satellite? */ + if (satexclude(obs[i].sat, var[i], svh[i], opt)) continue; - /* adjust range for satellite clock-bias */ - r+=-CLIGHT*dts[i*2]; + /* adjust range for satellite clock-bias */ + r += -CLIGHT * dts[i * 2]; - /* adjust range for troposphere delay model (hydrostatic) */ - zhd=tropmodel(obs[0].time,pos,zazel,0.0); - mapfh=tropmapf(obs[i].time,pos,azel+i*2,NULL); - r+=mapfh*zhd; + /* adjust range for troposphere delay model (hydrostatic) */ + zhd = tropmodel(obs[0].time, pos, zazel, 0.0); + mapfh = tropmapf(obs[i].time, pos, azel + i * 2, NULL); + r += mapfh * zhd; - /* calc receiver antenna phase center correction */ - antmodel(opt->pcvr+base,opt->antdel[base],azel+i*2,opt->posopt[1], - dant); + /* calc receiver antenna phase center correction */ + antmodel(opt->pcvr + base, opt->antdel[base], azel + i * 2, opt->posopt[1], dant); - /* calc undifferenced phase/code residual for satellite */ - trace(4,"sat=%d r=%.6f c*dts=%.6f zhd=%.6f map=%.6f\n",obs[i].sat,r,CLIGHT*dts[i*2],zhd,mapfh); - zdres_sat(base,r,obs+i,nav,azel+i*2,dant,opt,y+i*nf*2,freq+i*nf); - } - trace(4,"rr_=%.3f %.3f %.3f\n",rr_[0],rr_[1],rr_[2]); - trace(4,"pos=%.9f %.9f %.3f\n",pos[0]*R2D,pos[1]*R2D,pos[2]); - for (i=0;irb[i]; - b[i]=x[i]-xb[i]; - } - bb=norm(b,3); - - /* approximate variance of solution */ - if (P) { - for (i=0;i<3;i++) var+=P[i+i*rtk->nx]; - var/=3.0; - } - /* check nonlinearity */ - if (var>SQR(thres*bb)) { - trace(3,"constbl : pos variance large (bb=%.3f var=%.3f)\n",bb,var); - /* return 0; */ /* threshold too strict for all use cases, report error but continue on */ +static int constbl(rtk_t *rtk, const double *x, const double *P, double *v, double *H, double *Ri, + double *Rj, int index) { + const double thres = 0.1; /* threshold for nonlinearity (v.2.3.0) */ + double xb[3], b[3], bb, var = 0.0; + int i; + + trace(4, "constbl : \n"); + + /* time-adjusted baseline vector and length */ + for (i = 0; i < 3; i++) { + xb[i] = rtk->rb[i]; + b[i] = x[i] - xb[i]; + } + bb = norm(b, 3); - } - /* constraint to baseline length */ - v[index]=rtk->opt.baseline[0]-bb; - if (H) { - for (i=0;i<3;i++) H[i+index*rtk->nx]=b[i]/bb; - } - Ri[index]=0.0; - Rj[index]=SQR(rtk->opt.baseline[1]); + /* approximate variance of solution */ + if (P) { + for (i = 0; i < 3; i++) var += P[i + i * rtk->nx]; + var /= 3.0; + } + /* check nonlinearity */ + if (var > SQR(thres * bb)) { + trace(3, "constbl : pos variance large (bb=%.3f var=%.3f)\n", bb, var); + /* return 0; */ /* threshold too strict for all use cases, report error but continue on */ + } + /* constraint to baseline length */ + v[index] = rtk->opt.baseline[0] - bb; + if (H) { + for (i = 0; i < 3; i++) H[i + index * rtk->nx] = b[i] / bb; + } + Ri[index] = 0.0; + Rj[index] = SQR(rtk->opt.baseline[1]); - trace(3,"constbl : baseline len v=%13.3f R=%8.6f\n",v[index],Rj[index]); + trace(3, "constbl : baseline len v=%13.3f R=%8.6f\n", v[index], Rj[index]); - return 1; + return 1; } /* precise tropospheric model -------------------------------------------------*/ -static double prectrop(gtime_t time, const double *pos, int r, - const double *azel, const prcopt_t *opt, const double *x, - double *dtdx) -{ - double m_w=0.0,cotz,grad_n,grad_e; - int i=IT(r,opt); - - /* wet mapping function */ - tropmapf(time,pos,azel,&m_w); - - if (opt->tropopt>=TROPOPT_ESTG&&azel[1]>0.0) { - - /* m_w=m_0+m_0*cot(el)*(Gn*cos(az)+Ge*sin(az)): ref [6] */ - cotz=1.0/tan(azel[1]); - grad_n=m_w*cotz*cos(azel[0]); - grad_e=m_w*cotz*sin(azel[0]); - m_w+=grad_n*x[i+1]+grad_e*x[i+2]; - dtdx[1]=grad_n*x[i]; - dtdx[2]=grad_e*x[i]; - } - else dtdx[1]=dtdx[2]=0.0; - dtdx[0]=m_w; - return m_w*x[i]; +static double prectrop(gtime_t time, const double *pos, int r, const double *azel, + const prcopt_t *opt, const double *x, double *dtdx) { + double m_w = 0.0, cotz, grad_n, grad_e; + int i = IT(r, opt); + + /* wet mapping function */ + tropmapf(time, pos, azel, &m_w); + + if (opt->tropopt >= TROPOPT_ESTG && azel[1] > 0.0) { + /* m_w=m_0+m_0*cot(el)*(Gn*cos(az)+Ge*sin(az)): ref [6] */ + cotz = 1.0 / tan(azel[1]); + grad_n = m_w * cotz * cos(azel[0]); + grad_e = m_w * cotz * sin(azel[0]); + m_w += grad_n * x[i + 1] + grad_e * x[i + 2]; + dtdx[1] = grad_n * x[i]; + dtdx[2] = grad_e * x[i]; + } else + dtdx[1] = dtdx[2] = 0.0; + dtdx[0] = m_w; + return m_w * x[i]; } /* test satellite system (m=0:GPS/SBS,1:GLO,2:GAL,3:BDS,4:QZS,5:IRN) ---------*/ -static int test_sys(int sys, int m) -{ - switch (sys) { - case SYS_GPS: return m==0; - case SYS_SBS: return m==0; - case SYS_GLO: return m==1; - case SYS_GAL: return m==2; - case SYS_CMP: return m==3; - case SYS_QZS: return m==4; - case SYS_IRN: return m==5; - } - return 0; +static int test_sys(int sys, int m) { + switch (sys) { + case SYS_GPS: + return m == 0; + case SYS_SBS: + return m == 0; + case SYS_GLO: + return m == 1; + case SYS_GAL: + return m == 2; + case SYS_CMP: + return m == 3; + case SYS_QZS: + return m == 4; + case SYS_IRN: + return m == 5; + } + return 0; } /* double-differenced residuals and partial derivatives ----------------------------------- O rtk->ssat[i].resp[j] = residual pseudorange error @@ -1211,237 +1217,247 @@ static int test_sys(int sys, int m) O H = linearized translation from innovations to states (az/el to sats) O R = measurement error covariances O vflg = bit encoded list of sats used for each double diff */ -static int ddres(rtk_t *rtk, const obsd_t *obs, double dt, const double *x, - const double *P, const int *sat, double *y, double *e, - double *azel, double *freq, const int *iu, const int *ir, - int ns, double *v, double *H, double *R, int *vflg) -{ - prcopt_t *opt=&rtk->opt; - double bl,dr[3],posu[3],posr[3],didxi=0.0,didxj=0.0,*im; - double *tropr,*tropu,*dtdxr,*dtdxu,*Ri,*Rj,freqi,freqj,*Hi=NULL,df; - int i,j,k,m,f,nv=0,nb[NFREQ*NSYS*2+2]={0},b=0,sysi,sysj,nf=NF(opt); - int frq,code; - - trace(3,"ddres : dt=%.4f ns=%d\n",dt,ns); - - /* bl=distance from base to rover, dr=x,y,z components */ - bl=baseline(x,rtk->rb,dr); - /* translate ecef pos to geodetic pos */ - ecef2pos(x,posu); ecef2pos(rtk->rb,posr); - - Ri=mat(ns*nf*2+2,1); Rj=mat(ns*nf*2+2,1); im=mat(ns,1); - tropu=mat(ns,1); tropr=mat(ns,1); dtdxu=mat(ns,3); dtdxr=mat(ns,3); - - /* zero out residual phase and code biases for all satellites */ - for (i=0;issat[i].resp[j]=rtk->ssat[i].resc[j]=0.0; - } - /* compute factors of ionospheric and tropospheric delay - - only used if kalman filter contains states for ION and TROP delays - usually insignificant for short baselines (<10km)*/ - for (i=0;iionoopt==IONOOPT_EST) { - im[i]=(ionmapf(posu,azel+iu[i]*2)+ionmapf(posr,azel+ir[i]*2))/2.0; +static int ddres(rtk_t *rtk, const obsd_t *obs, double dt, const double *x, const double *P, + const int *sat, double *y, double *e, double *azel, double *freq, const int *iu, + const int *ir, int ns, double *v, double *H, double *R, int *vflg) { + prcopt_t *opt = &rtk->opt; + double bl, dr[3], posu[3], posr[3], didxi = 0.0, didxj = 0.0, *im; + double *tropr, *tropu, *dtdxr, *dtdxu, *Ri, *Rj, freqi, freqj, *Hi = NULL, df; + int i, j, k, m, f, nv = 0, nb[NFREQ * NSYS * 2 + 2] = {0}, b = 0, sysi, sysj, nf = NF(opt); + int frq, code; + + trace(3, "ddres : dt=%.4f ns=%d\n", dt, ns); + + /* bl=distance from base to rover, dr=x,y,z components */ + bl = baseline(x, rtk->rb, dr); + /* translate ecef pos to geodetic pos */ + ecef2pos(x, posu); + ecef2pos(rtk->rb, posr); + + Ri = mat(ns * nf * 2 + 2, 1); + Rj = mat(ns * nf * 2 + 2, 1); + im = mat(ns, 1); + tropu = mat(ns, 1); + tropr = mat(ns, 1); + dtdxu = mat(ns, 3); + dtdxr = mat(ns, 3); + + /* zero out residual phase and code biases for all satellites */ + for (i = 0; i < MAXSAT; i++) + for (j = 0; j < NFREQ; j++) { + rtk->ssat[i].resp[j] = rtk->ssat[i].resc[j] = 0.0; + } + /* compute factors of ionospheric and tropospheric delay + - only used if kalman filter contains states for ION and TROP delays + usually insignificant for short baselines (<10km)*/ + for (i = 0; i < ns; i++) { + if (opt->ionoopt == IONOOPT_EST) { + im[i] = (ionmapf(posu, azel + iu[i] * 2) + ionmapf(posr, azel + ir[i] * 2)) / 2.0; + } + if (opt->tropopt >= TROPOPT_EST) { + tropu[i] = prectrop(rtk->sol.time, posu, 0, azel + iu[i] * 2, opt, x, dtdxu + i * 3); + tropr[i] = prectrop(rtk->sol.time, posr, 1, azel + ir[i] * 2, opt, x, dtdxr + i * 3); + } + } + /* step through sat systems: m=0:gps/sbs,1:glo,2:gal,3:bds 4:qzs 5:irn*/ + for (m = 0; m < 6; m++) { + /* step through phases/codes */ + for (f = opt->mode > PMODE_DGPS ? 0 : nf; f < nf * 2; f++) { + frq = f % nf; + code = f < nf ? 0 : 1; + + /* find reference satellite with highest elevation, set to i */ + for (i = -1, j = 0; j < ns; j++) { + sysi = rtk->ssat[sat[j] - 1].sys; + if (!test_sys(sysi, m) || sysi == SYS_SBS) continue; + if (!validobs(iu[j], ir[j], f, nf, y)) continue; + /* skip sat with slip unless no other valid sat */ + if (i >= 0 && rtk->ssat[sat[j] - 1].slip[frq] & LLI_SLIP) continue; + if (i < 0 || azel[1 + iu[j] * 2] >= azel[1 + iu[i] * 2]) i = j; + } + if (i < 0) continue; + + /* calculate double differences of residuals (code/phase) for each sat */ + for (j = 0; j < ns; j++) { + if (i == j) continue; /* skip ref sat */ + sysi = rtk->ssat[sat[i] - 1].sys; + sysj = rtk->ssat[sat[j] - 1].sys; + freqi = freq[frq + iu[i] * nf]; + freqj = freq[frq + iu[j] * nf]; + if (freqi <= 0.0 || freqj <= 0.0) continue; + if (!test_sys(sysj, m)) continue; + if (!validobs(iu[j], ir[j], f, nf, y)) continue; + + if (H) { + Hi = H + nv * rtk->nx; + for (k = 0; k < rtk->nx; k++) Hi[k] = 0.0; + } + + /* double-differenced measurements from 2 receivers and 2 sats in meters */ + v[nv] = (y[f + iu[i] * nf * 2] - y[f + ir[i] * nf * 2]) - + (y[f + iu[j] * nf * 2] - y[f + ir[j] * nf * 2]); + + /* partial derivatives by rover position, combine unit vectors from two sats */ + if (H) { + for (k = 0; k < 3; k++) { + Hi[k] = -e[k + iu[i] * 3] + + e[k + iu[j] * 3]; /* translation of innovation to position states */ + } } - if (opt->tropopt>=TROPOPT_EST) { - tropu[i]=prectrop(rtk->sol.time,posu,0,azel+iu[i]*2,opt,x,dtdxu+i*3); - tropr[i]=prectrop(rtk->sol.time,posr,1,azel+ir[i]*2,opt,x,dtdxr+i*3); + if (opt->ionoopt == IONOOPT_EST) { + /* adjust double-differenced measurements by double-differenced ionospheric delay term */ + didxi = (code ? -1.0 : 1.0) * im[i] * SQR(FREQL1 / freqi); + didxj = (code ? -1.0 : 1.0) * im[j] * SQR(FREQL1 / freqj); + v[nv] -= didxi * x[II(sat[i], opt)] - didxj * x[II(sat[j], opt)]; + if (H) { + Hi[II(sat[i], opt)] = didxi; + Hi[II(sat[j], opt)] = -didxj; + } } - } - /* step through sat systems: m=0:gps/sbs,1:glo,2:gal,3:bds 4:qzs 5:irn*/ - for (m=0;m<6;m++) { - - /* step through phases/codes */ - for (f=opt->mode>PMODE_DGPS?0:nf;fssat[sat[j]-1].sys; - if (!test_sys(sysi,m) || sysi==SYS_SBS) continue; - if (!validobs(iu[j],ir[j],f,nf,y)) continue; - /* skip sat with slip unless no other valid sat */ - if (i>=0&&rtk->ssat[sat[j]-1].slip[frq]&LLI_SLIP) continue; - if (i<0||azel[1+iu[j]*2]>=azel[1+iu[i]*2]) i=j; + if (opt->tropopt >= TROPOPT_EST) { + /* adjust double-differenced measurements by double-differenced tropospheric delay term */ + v[nv] -= (tropu[i] - tropu[j]) - (tropr[i] - tropr[j]); + for (k = 0; k < (opt->tropopt < TROPOPT_ESTG ? 1 : 3); k++) { + if (!H) continue; + Hi[IT(0, opt) + k] = (dtdxu[k + i * 3] - dtdxu[k + j * 3]); + Hi[IT(1, opt) + k] = -(dtdxr[k + i * 3] - dtdxr[k + j * 3]); + } + } + if (opt->mode > PMODE_DGPS && !code) { + int ii = IB(sat[i], frq, opt); + int jj = IB(sat[j], frq, opt); + /* Adjust phase residual by double-differenced phase-bias term, + IB=look up index by sat&freq */ + if (opt->ionoopt != IONOOPT_IFLC) { + /* Phase-bias states are single-differenced so need to difference them */ + v[nv] -= CLIGHT / freqi * x[ii] - CLIGHT / freqj * x[jj]; + if (H) { + Hi[ii] = CLIGHT / freqi; + Hi[jj] = -CLIGHT / freqj; + } + } else { + v[nv] -= x[ii] - x[jj]; + if (H) { + Hi[ii] = 1.0; + Hi[jj] = -1.0; } - if (i<0) continue; - - /* calculate double differences of residuals (code/phase) for each sat */ - for (j=0;jssat[sat[i]-1].sys; - sysj=rtk->ssat[sat[j]-1].sys; - freqi=freq[frq+iu[i]*nf]; - freqj=freq[frq+iu[j]*nf]; - if (freqi<=0.0||freqj<=0.0) continue; - if (!test_sys(sysj,m)) continue; - if (!validobs(iu[j],ir[j],f,nf,y)) continue; - - if (H) { - Hi=H+nv*rtk->nx; - for (k=0;knx;k++) Hi[k]=0.0; - } - - /* double-differenced measurements from 2 receivers and 2 sats in meters */ - v[nv]=(y[f+iu[i]*nf*2]-y[f+ir[i]*nf*2])- - (y[f+iu[j]*nf*2]-y[f+ir[j]*nf*2]); - - /* partial derivatives by rover position, combine unit vectors from two sats */ - if (H) { - for (k=0;k<3;k++) { - Hi[k]=-e[k+iu[i]*3]+e[k+iu[j]*3]; /* translation of innovation to position states */ - } - } - if (opt->ionoopt==IONOOPT_EST) { - /* adjust double-differenced measurements by double-differenced ionospheric delay term */ - didxi=(code?-1.0:1.0)*im[i]*SQR(FREQL1/freqi); - didxj=(code?-1.0:1.0)*im[j]*SQR(FREQL1/freqj); - v[nv]-=didxi*x[II(sat[i],opt)]-didxj*x[II(sat[j],opt)]; - if (H) { - Hi[II(sat[i],opt)]= didxi; - Hi[II(sat[j],opt)]=-didxj; - } - } - if (opt->tropopt>=TROPOPT_EST) { - /* adjust double-differenced measurements by double-differenced tropospheric delay term */ - v[nv]-=(tropu[i]-tropu[j])-(tropr[i]-tropr[j]); - for (k=0;k<(opt->tropoptmode > PMODE_DGPS && !code) { - int ii = IB(sat[i], frq, opt); - int jj = IB(sat[j], frq, opt); - /* Adjust phase residual by double-differenced phase-bias term, - IB=look up index by sat&freq */ - if (opt->ionoopt!=IONOOPT_IFLC) { - /* Phase-bias states are single-differenced so need to difference them */ - v[nv]-=CLIGHT/freqi*x[ii]-CLIGHT/freqj*x[jj]; - if (H) { - Hi[ii]= CLIGHT/freqi; - Hi[jj]=-CLIGHT/freqj; - } - } - else { - v[nv]-=x[ii]-x[jj]; - if (H) { - Hi[ii]= 1.0; - Hi[jj]=-1.0; - } - } - } - - - /* adjust double-difference for glonass sats */ - if (sysi==SYS_GLO&&sysj==SYS_GLO) { - if (rtk->opt.glomodear==GLO_ARMODE_AUTOCAL && frqopt.glomodear==GLO_ARMODE_FIXHOLD && frqssat[sat[i]-1].icbias[frq]*CLIGHT/freqi - rtk->ssat[sat[j]-1].icbias[frq]*CLIGHT/freqj; - v[nv]-=icb; - } - } - - /* adjust double-difference for sbas sats */ - if (sysj==SYS_SBS&&sysi==SYS_GPS) { - if (rtk->opt.glomodear==GLO_ARMODE_FIXHOLD && frqssat[sat[i]-1].icbias[frq]*CLIGHT/freqi - rtk->ssat[sat[j]-1].icbias[frq]*CLIGHT/freqj; - v[nv]-=icb; - } - } - - /* save residuals */ - if (code) rtk->ssat[sat[j]-1].resp[frq]=v[nv]; /* pseudorange */ - else rtk->ssat[sat[j]-1].resc[frq]=v[nv]; /* carrier phase */ - - /* open up outlier threshold if one of the phase biases was just initialized */ - double threshadj = 1; - if (opt->mode > PMODE_DGPS) { - // Open up outlier threshold if one of the phase biases was just initialized. - int ii = IB(sat[i], frq, opt); - int jj = IB(sat[j], frq, opt); - if (P[ii + rtk->nx * ii] == SQR(rtk->opt.std[0]) || - P[jj + rtk->nx * jj] == SQR(rtk->opt.std[0])) - threshadj = 10; - } - /* if residual too large, flag as outlier */ - if (fabs(v[nv])>opt->maxinno[code]*threshadj) { - rtk->ssat[sat[j]-1].vsat[frq]=0; - rtk->ssat[sat[j]-1].rejc[frq]++; - errmsg(rtk,"outlier rejected (sat=%3d-%3d %s%d v=%.3f)\n", - sat[i],sat[j],code?"P":"L",frq+1,v[nv]); - continue; - } - - /* single-differenced measurement error variances (m) */ - Ri[nv] = varerr(sat[i], sysi, azel[1+iu[i]*2], - rtk->ssat[sat[i]-1].snr_rover[frq], - rtk->ssat[sat[i]-1].snr_base[frq], - bl,dt,f,opt,&obs[iu[i]]); - Rj[nv] = varerr(sat[j], sysj, azel[1+iu[j]*2], - rtk->ssat[sat[j]-1].snr_rover[frq], - rtk->ssat[sat[j]-1].snr_base[frq], - bl,dt,f,opt,&obs[iu[j]]); - /* increase variance if half cycle flags set */ - if (!code&&(obs[iu[i]].LLI[frq]&LLI_HALFC)) Ri[nv]+=0.01; - if (!code&&(obs[iu[j]].LLI[frq]&LLI_HALFC)) Rj[nv]+=0.01; - - /* set valid data flags */ - if (opt->mode>PMODE_DGPS) { - // Only valid for AR if there is phase data. - if (!code) rtk->ssat[sat[i]-1].vsat[frq]=rtk->ssat[sat[j]-1].vsat[frq]=1; - } - else { - rtk->ssat[sat[i]-1].vsat[frq]=rtk->ssat[sat[j]-1].vsat[frq]=1; - } + } + } -#ifdef TRACE - double icb; - if (rtk->opt.glomodear==GLO_ARMODE_AUTOCAL) - icb=x[IL(frq,opt)]; - else - icb=rtk->ssat[sat[i]-1].icbias[frq]*CLIGHT/freqi - - rtk->ssat[sat[j]-1].icbias[frq]*CLIGHT/freqj; - double xjj = 0.0, Pjj = 0.0; - if (opt->mode>PMODE_DGPS) { - int jj = IB(sat[j], frq, &rtk->opt); - xjj = x[jj]; - Pjj = P[jj + jj * rtk->nx]; - } - trace(3,"sat=%3d-%3d %s%d v=%13.3f R=%9.6f %9.6f icb=%9.3f lock=%5d x=%9.3f P=%.3f\n", - sat[i],sat[j],code?"P":"L",frq+1,v[nv],Ri[nv],Rj[nv],icb, - rtk->ssat[sat[j]-1].lock[frq],xjj,Pjj); -#endif + /* adjust double-difference for glonass sats */ + if (sysi == SYS_GLO && sysj == SYS_GLO) { + if (rtk->opt.glomodear == GLO_ARMODE_AUTOCAL && frq < NFREQGLO) { + /* auto-cal method */ + df = (freqi - freqj) / (f == 0 ? DFRQ1_GLO : DFRQ2_GLO); + v[nv] -= df * x[IL(frq, opt)]; + if (H) Hi[IL(frq, opt)] = df; + } else if (rtk->opt.glomodear == GLO_ARMODE_FIXHOLD && frq < NFREQGLO) { + /* fix-and-hold method */ + double icb = rtk->ssat[sat[i] - 1].icbias[frq] * CLIGHT / freqi - + rtk->ssat[sat[j] - 1].icbias[frq] * CLIGHT / freqj; + v[nv] -= icb; + } + } - vflg[nv++]=(sat[i]<<16)|(sat[j]<<8)|((code?1:0)<<4)|(frq); - nb[b]++; - } - b++; + /* adjust double-difference for sbas sats */ + if (sysj == SYS_SBS && sysi == SYS_GPS) { + if (rtk->opt.glomodear == GLO_ARMODE_FIXHOLD && frq < NFREQ) { + /* fix-and-hold method */ + double icb = rtk->ssat[sat[i] - 1].icbias[frq] * CLIGHT / freqi - + rtk->ssat[sat[j] - 1].icbias[frq] * CLIGHT / freqj; + v[nv] -= icb; + } } - } /* end of system loop */ - /* baseline length constraint, for fixed distance between base and rover */ - if (rtk->opt.baseline[0]>0.0&&constbl(rtk,x,P,v,H,Ri,Rj,nv)) { - vflg[nv++]=3<<4; - nb[b++]++; + /* save residuals */ + if (code) + rtk->ssat[sat[j] - 1].resp[frq] = v[nv]; /* pseudorange */ + else + rtk->ssat[sat[j] - 1].resc[frq] = v[nv]; /* carrier phase */ + + /* open up outlier threshold if one of the phase biases was just initialized */ + double threshadj = 1; + if (opt->mode > PMODE_DGPS) { + // Open up outlier threshold if one of the phase biases was just initialized. + int ii = IB(sat[i], frq, opt); + int jj = IB(sat[j], frq, opt); + if (P[ii + rtk->nx * ii] == SQR(rtk->opt.std[0]) || + P[jj + rtk->nx * jj] == SQR(rtk->opt.std[0])) + threshadj = 10; + } + /* if residual too large, flag as outlier */ + if (fabs(v[nv]) > opt->maxinno[code] * threshadj) { + rtk->ssat[sat[j] - 1].vsat[frq] = 0; + rtk->ssat[sat[j] - 1].rejc[frq]++; + errmsg(rtk, "outlier rejected (sat=%3d-%3d %s%d v=%.3f)\n", sat[i], sat[j], + code ? "P" : "L", frq + 1, v[nv]); + continue; + } + + /* single-differenced measurement error variances (m) */ + Ri[nv] = varerr(sat[i], sysi, azel[1 + iu[i] * 2], rtk->ssat[sat[i] - 1].snr_rover[frq], + rtk->ssat[sat[i] - 1].snr_base[frq], bl, dt, f, opt, &obs[iu[i]]); + Rj[nv] = varerr(sat[j], sysj, azel[1 + iu[j] * 2], rtk->ssat[sat[j] - 1].snr_rover[frq], + rtk->ssat[sat[j] - 1].snr_base[frq], bl, dt, f, opt, &obs[iu[j]]); + /* increase variance if half cycle flags set */ + if (!code && (obs[iu[i]].LLI[frq] & LLI_HALFC)) Ri[nv] += 0.01; + if (!code && (obs[iu[j]].LLI[frq] & LLI_HALFC)) Rj[nv] += 0.01; + + /* set valid data flags */ + if (opt->mode > PMODE_DGPS) { + // Only valid for AR if there is phase data. + if (!code) rtk->ssat[sat[i] - 1].vsat[frq] = rtk->ssat[sat[j] - 1].vsat[frq] = 1; + } else { + rtk->ssat[sat[i] - 1].vsat[frq] = rtk->ssat[sat[j] - 1].vsat[frq] = 1; + } + +#ifdef TRACE + double icb; + if (rtk->opt.glomodear == GLO_ARMODE_AUTOCAL) + icb = x[IL(frq, opt)]; + else + icb = rtk->ssat[sat[i] - 1].icbias[frq] * CLIGHT / freqi - + rtk->ssat[sat[j] - 1].icbias[frq] * CLIGHT / freqj; + double xjj = 0.0, Pjj = 0.0; + if (opt->mode > PMODE_DGPS) { + int jj = IB(sat[j], frq, &rtk->opt); + xjj = x[jj]; + Pjj = P[jj + jj * rtk->nx]; + } + trace(3, "sat=%3d-%3d %s%d v=%13.3f R=%9.6f %9.6f icb=%9.3f lock=%5d x=%9.3f P=%.3f\n", + sat[i], sat[j], code ? "P" : "L", frq + 1, v[nv], Ri[nv], Rj[nv], icb, + rtk->ssat[sat[j] - 1].lock[frq], xjj, Pjj); +#endif + + vflg[nv++] = (sat[i] << 16) | (sat[j] << 8) | ((code ? 1 : 0) << 4) | (frq); + nb[b]++; + } + b++; } - if (H) {trace(5,"H=\n"); tracemat(5,H,rtk->nx,nv,7,4);} + } /* end of system loop */ + + /* baseline length constraint, for fixed distance between base and rover */ + if (rtk->opt.baseline[0] > 0.0 && constbl(rtk, x, P, v, H, Ri, Rj, nv)) { + vflg[nv++] = 3 << 4; + nb[b++]++; + } + if (H) { + trace(5, "H=\n"); + tracemat(5, H, rtk->nx, nv, 7, 4); + } - /* double-differenced measurement error covariance */ - ddcov(nb,b,Ri,Rj,nv,R); + /* double-differenced measurement error covariance */ + ddcov(nb, b, Ri, Rj, nv, R); - free(Ri); free(Rj); free(im); - free(tropu); free(tropr); free(dtdxu); free(dtdxr); + free(Ri); + free(Rj); + free(im); + free(tropu); + free(tropr); + free(dtdxu); + free(dtdxr); - return nv; + return nv; } // Time-interpolation of residuals (for post-processing solutions) @@ -1503,467 +1519,490 @@ static double intpres(gtime_t time, const obsd_t *obs, int n, const nav_t *nav, return fabs(ttb) < fabs(tt) ? ttb : tt; } /* index for single to double-difference transformation matrix (D') --------------------*/ -static int ddidx(rtk_t *rtk, int *ix, int gps, int glo, int sbs) -{ - int i,j,k,m,f,n,nb=0,na=rtk->na,nf=NF(&rtk->opt),nofix; - double fix[MAXSAT],ref[MAXSAT]; - - trace(3,"ddidx: gps=%d/%d glo=%d/%d sbs=%d\n",gps,rtk->opt.gpsmodear,glo,rtk->opt.glomodear,sbs); - - /* clear fix flag for all sats (1=float, 2=fix) */ - for (i=0;issat[i].fix[j]=0; - } - for (m=0;m<6;m++) { /* m=0:GPS/SBS,1:GLO,2:GAL,3:BDS,4:QZS,5:IRN */ - - /* skip if ambiguity resolution turned off for this sys */ - nofix=(m==0&&gps==0)||(m==1&&glo==0)||(m==3&&rtk->opt.bdsmodear==0); - - /* step through freqs */ - for (f=0,k=na;fx[i]==0.0||!test_sys(rtk->ssat[i-k].sys,m)|| - !rtk->ssat[i-k].vsat[f]) { - continue; - } - /* set sat to use for fixing ambiguity if meets criteria */ - if (rtk->ssat[i-k].lock[f]>=0&&!(rtk->ssat[i-k].slip[f]&LLI_HALFC)&& - rtk->ssat[i-k].azel[1]>=rtk->opt.elmaskar&&!nofix) { - rtk->ssat[i-k].fix[f]=2; /* fix */ - break;/* break out of loop if find good sat */ - } - /* else don't use this sat for fixing ambiguity */ - else rtk->ssat[i-k].fix[f]=1; - } - if (i>=k+MAXSAT||rtk->ssat[i-k].fix[f]!=2) continue; /* no good sat found */ - /* step through all sats (j=state index, j-k=sat index, i-k=first good sat) */ - for (n=0,j=k;jx[j]==0.0||!test_sys(rtk->ssat[j-k].sys,m)|| - !rtk->ssat[j-k].vsat[f]) { - continue; - } - if (sbs==0 && satsys(j-k+1,NULL)==SYS_SBS) continue; - if (rtk->ssat[j-k].lock[f]>=0&&!(rtk->ssat[j-k].slip[f]&LLI_HALFC)&& - rtk->ssat[j-k].vsat[f]&& - rtk->ssat[j-k].azel[1]>=rtk->opt.elmaskar&&!nofix) { - /* set D coeffs to subtract sat j from sat i */ - ix[nb*2 ]=i; /* state index of ref bias */ - ix[nb*2+1]=j; /* state index of target bias */ - /* inc # of sats used for fix */ - ref[nb]=i-k+1; - fix[nb++]=j-k+1; - rtk->ssat[j-k].fix[f]=2; /* fix */ - n++; /* count # of sat pairs for this freq/constellation */ - } - /* else don't use this sat for fixing ambiguity */ - else rtk->ssat[j-k].fix[f]=1; - } - /* don't use ref sat if no sat pairs */ - if (n==0) rtk->ssat[i-k].fix[f]=1; - } +static int ddidx(rtk_t *rtk, int *ix, int gps, int glo, int sbs) { + int i, j, k, m, f, n, nb = 0, na = rtk->na, nf = NF(&rtk->opt), nofix; + double fix[MAXSAT], ref[MAXSAT]; + + trace(3, "ddidx: gps=%d/%d glo=%d/%d sbs=%d\n", gps, rtk->opt.gpsmodear, glo, rtk->opt.glomodear, + sbs); + + /* clear fix flag for all sats (1=float, 2=fix) */ + for (i = 0; i < MAXSAT; i++) + for (j = 0; j < NFREQ; j++) { + rtk->ssat[i].fix[j] = 0; + } + for (m = 0; m < 6; m++) { /* m=0:GPS/SBS,1:GLO,2:GAL,3:BDS,4:QZS,5:IRN */ + + /* skip if ambiguity resolution turned off for this sys */ + nofix = (m == 0 && gps == 0) || (m == 1 && glo == 0) || (m == 3 && rtk->opt.bdsmodear == 0); + + /* step through freqs */ + for (f = 0, k = na; f < nf; f++, k += MAXSAT) { + /* look for first valid sat (i=state index, i-k=sat index) */ + for (i = k; i < k + MAXSAT; i++) { + /* skip if sat not active */ + if (rtk->x[i] == 0.0 || !test_sys(rtk->ssat[i - k].sys, m) || !rtk->ssat[i - k].vsat[f]) { + continue; + } + /* set sat to use for fixing ambiguity if meets criteria */ + if (rtk->ssat[i - k].lock[f] >= 0 && !(rtk->ssat[i - k].slip[f] & LLI_HALFC) && + rtk->ssat[i - k].azel[1] >= rtk->opt.elmaskar && !nofix) { + rtk->ssat[i - k].fix[f] = 2; /* fix */ + break; /* break out of loop if find good sat */ + } + /* else don't use this sat for fixing ambiguity */ + else + rtk->ssat[i - k].fix[f] = 1; + } + if (i >= k + MAXSAT || rtk->ssat[i - k].fix[f] != 2) continue; /* no good sat found */ + /* step through all sats (j=state index, j-k=sat index, i-k=first good sat) */ + for (n = 0, j = k; j < k + MAXSAT; j++) { + if (i == j || rtk->x[j] == 0.0 || !test_sys(rtk->ssat[j - k].sys, m) || + !rtk->ssat[j - k].vsat[f]) { + continue; + } + if (sbs == 0 && satsys(j - k + 1, NULL) == SYS_SBS) continue; + if (rtk->ssat[j - k].lock[f] >= 0 && !(rtk->ssat[j - k].slip[f] & LLI_HALFC) && + rtk->ssat[j - k].vsat[f] && rtk->ssat[j - k].azel[1] >= rtk->opt.elmaskar && !nofix) { + /* set D coeffs to subtract sat j from sat i */ + ix[nb * 2] = i; /* state index of ref bias */ + ix[nb * 2 + 1] = j; /* state index of target bias */ + /* inc # of sats used for fix */ + ref[nb] = i - k + 1; + fix[nb++] = j - k + 1; + rtk->ssat[j - k].fix[f] = 2; /* fix */ + n++; /* count # of sat pairs for this freq/constellation */ + } + /* else don't use this sat for fixing ambiguity */ + else + rtk->ssat[j - k].fix[f] = 1; + } + /* don't use ref sat if no sat pairs */ + if (n == 0) rtk->ssat[i - k].fix[f] = 1; } + } - if (nb>0) { - trace(3,"refSats=");tracemat(3,ref,1,nb,7,0); - trace(3,"fixSats=");tracemat(3,fix,1,nb,7,0); - } - return nb; + if (nb > 0) { + trace(3, "refSats="); + tracemat(3, ref, 1, nb, 7, 0); + trace(3, "fixSats="); + tracemat(3, fix, 1, nb, 7, 0); + } + return nb; } /* translate double diff fixed phase-bias values to single diff fix phase-bias values */ -static void restamb(rtk_t *rtk, const double *bias, int nb, double *xa) -{ - (void)nb; - int i,n,m,f,index[MAXSAT]={0},nv=0,nf=NF(&rtk->opt); +static void restamb(rtk_t *rtk, const double *bias, int nb, double *xa) { + (void)nb; + int i, n, m, f, index[MAXSAT] = {0}, nv = 0, nf = NF(&rtk->opt); - trace(3,"restamb :\n"); + trace(3, "restamb :\n"); - for (i=0;inx;i++) xa[i]=rtk->x [i]; /* init all fixed states to float state values */ - for (i=0;ina;i++) xa[i]=rtk->xa[i]; /* overwrite non phase-bias states with fixed values */ + for (i = 0; i < rtk->nx; i++) xa[i] = rtk->x[i]; /* init all fixed states to float state values */ + for (i = 0; i < rtk->na; i++) + xa[i] = rtk->xa[i]; /* overwrite non phase-bias states with fixed values */ - for (m=0;m<6;m++) for (f=0;fssat[i].sys,m)||rtk->ssat[i].fix[f]!=2) { - continue; - } - index[n++]=IB(i+1,f,&rtk->opt); + for (m = 0; m < 6; m++) + for (f = 0; f < nf; f++) { + for (n = i = 0; i < MAXSAT; i++) { + if (!test_sys(rtk->ssat[i].sys, m) || rtk->ssat[i].fix[f] != 2) { + continue; } - if (n<2) continue; + index[n++] = IB(i + 1, f, &rtk->opt); + } + if (n < 2) continue; - xa[index[0]]=rtk->x[index[0]]; + xa[index[0]] = rtk->x[index[0]]; - for (i=1;inx-rtk->na,nv=0,nf=NF(&rtk->opt); - double dd; - - trace(3,"holdamb :\n"); - - v=mat(nb,1); H=zeros(nb,rtk->nx); - - for (m=0;m<6;m++) for (f=0;fssat[i].sys,m)||rtk->ssat[i].fix[f]!=2|| - rtk->ssat[i].azel[1]opt.elmaskhold) { - continue; - } - index[n++]=IB(i+1,f,&rtk->opt); - rtk->ssat[i].fix[f]=3; /* hold */ - } - /* use ambiguity resolution results to generate a set of pseudo-innovations - to feed to kalman filter based on error between fixed and float solutions */ - for (i=1;ix[index[0]]-rtk->x[index[i]]); - - H[index[0]+nv*rtk->nx]= 1.0; - H[index[i]+nv*rtk->nx]=-1.0; - nv++; +static void holdamb(rtk_t *rtk, const double *xa) { + double *v, *H, *R; + int i, j, n, m, f, info, index[MAXSAT], nb = rtk->nx - rtk->na, nv = 0, nf = NF(&rtk->opt); + double dd; + + trace(3, "holdamb :\n"); + + v = mat(nb, 1); + H = zeros(nb, rtk->nx); + + for (m = 0; m < 6; m++) + for (f = 0; f < nf; f++) { + for (n = i = 0; i < MAXSAT; i++) { + if (!test_sys(rtk->ssat[i].sys, m) || rtk->ssat[i].fix[f] != 2 || + rtk->ssat[i].azel[1] < rtk->opt.elmaskhold) { + continue; } + index[n++] = IB(i + 1, f, &rtk->opt); + rtk->ssat[i].fix[f] = 3; /* hold */ + } + /* use ambiguity resolution results to generate a set of pseudo-innovations + to feed to kalman filter based on error between fixed and float solutions */ + for (i = 1; i < n; i++) { + /* phase-biases are single diff, so subtract errors to get + double diff: v(nv)=err(i)-err(0) */ + v[nv] = (xa[index[0]] - xa[index[i]]) - (rtk->x[index[0]] - rtk->x[index[i]]); + + H[index[0] + nv * rtk->nx] = 1.0; + H[index[i] + nv * rtk->nx] = -1.0; + nv++; + } } - /* return if less than min sats for hold (skip if fix&hold for GLONASS only) */ - if (rtk->opt.modear==ARMODE_FIXHOLD&&nvopt.minholdsats) { - trace(3,"holdamb: not enough sats to hold ambiguity\n"); - free(v); free(H); - return; - } - - rtk->holdamb=1; /* set flag to indicate hold has occurred */ - R=zeros(nv,nv); - for (i=0;iopt.varholdamb; - - /* update states with constraints */ - if ((info=filter(rtk->x,rtk->P,H,v,R,rtk->nx,nv))) { - errmsg(rtk,"filter error (info=%d)\n",info); - } - free(R);free(v); free(H); - - /* skip glonass/sbs icbias update if not enabled */ - if (rtk->opt.glomodear!=GLO_ARMODE_FIXHOLD) return; - - /* Move fractional part of bias from phase-bias into ic bias for GLONASS sats (both in cycles) */ - for (f=0;fssat[j].sys,1)&&rtk->ssat[j].vsat[f]&&rtk->ssat[j].lock[f]>=0) { - if (i<0) { - i=j; /* use first valid sat for reference sat */ - index[nv++]=j; - } - else { /* adjust the rest */ - /* find phase-bias difference */ - dd=rtk->x[IB(j+1,f,&rtk->opt)]-rtk->x[IB(i+1,f,&rtk->opt)]; - dd=rtk->opt.gainholdamb*(dd-ROUND(dd)); /* throwout integer part of answer and multiply by filter gain */ - rtk->x[IB(j+1,f,&rtk->opt)]-=dd; /* remove fractional part from phase bias */ - rtk->ssat[j].icbias[f]+=dd; /* and move to IC bias */ - index[nv++]=j; - } - } + /* return if less than min sats for hold (skip if fix&hold for GLONASS only) */ + if (rtk->opt.modear == ARMODE_FIXHOLD && nv < rtk->opt.minholdsats) { + trace(3, "holdamb: not enough sats to hold ambiguity\n"); + free(v); + free(H); + return; + } + + rtk->holdamb = 1; /* set flag to indicate hold has occurred */ + R = zeros(nv, nv); + for (i = 0; i < nv; i++) R[i + i * nv] = rtk->opt.varholdamb; + + /* update states with constraints */ + if ((info = filter(rtk->x, rtk->P, H, v, R, rtk->nx, nv))) { + errmsg(rtk, "filter error (info=%d)\n", info); + } + free(R); + free(v); + free(H); + + /* skip glonass/sbs icbias update if not enabled */ + if (rtk->opt.glomodear != GLO_ARMODE_FIXHOLD) return; + + /* Move fractional part of bias from phase-bias into ic bias for GLONASS sats (both in cycles) */ + for (f = 0; f < nf; f++) { + i = -1; + for (j = nv = 0; j < MAXSAT; j++) { + /* check if valid GLONASS sat */ + if (test_sys(rtk->ssat[j].sys, 1) && rtk->ssat[j].vsat[f] && rtk->ssat[j].lock[f] >= 0) { + if (i < 0) { + i = j; /* use first valid sat for reference sat */ + index[nv++] = j; + } else { /* adjust the rest */ + /* find phase-bias difference */ + dd = rtk->x[IB(j + 1, f, &rtk->opt)] - rtk->x[IB(i + 1, f, &rtk->opt)]; + dd = rtk->opt.gainholdamb * + (dd - ROUND(dd)); /* throwout integer part of answer and multiply by filter gain */ + rtk->x[IB(j + 1, f, &rtk->opt)] -= dd; /* remove fractional part from phase bias */ + rtk->ssat[j].icbias[f] += dd; /* and move to IC bias */ + index[nv++] = j; } + } } - /* Move fractional part of bias from phase-bias into ic bias for SBAS sats (both in cycles) */ - for (f=0;fssat[j].sys,0)&&rtk->ssat[j].vsat[f]&&rtk->ssat[j].lock[f]>=0) { - if (i<0) { - i=j; /* use first valid GPS sat for reference sat */ - index[nv++]=j; - } - else { /* adjust the SBS sats */ - if (rtk->ssat[j].sys!=SYS_SBS) continue; - /* find phase-bias difference */ - dd=rtk->x[IB(j+1,f,&rtk->opt)]-rtk->x[IB(i+1,f,&rtk->opt)]; - dd=rtk->opt.gainholdamb*(dd-ROUND(dd)); /* throwout integer part of answer and multiply by filter gain */ - rtk->x[IB(j+1,f,&rtk->opt)]-=dd; /* remove fractional part from phase bias diff */ - rtk->ssat[j].icbias[f]+=dd; /* and move to IC bias */ - index[nv++]=j; - } - } + } + /* Move fractional part of bias from phase-bias into ic bias for SBAS sats (both in cycles) */ + for (f = 0; f < nf; f++) { + i = -1; + for (j = nv = 0; j < MAXSAT; j++) { + /* check if valid GPS/SBS sat */ + if (test_sys(rtk->ssat[j].sys, 0) && rtk->ssat[j].vsat[f] && rtk->ssat[j].lock[f] >= 0) { + if (i < 0) { + i = j; /* use first valid GPS sat for reference sat */ + index[nv++] = j; + } else { /* adjust the SBS sats */ + if (rtk->ssat[j].sys != SYS_SBS) continue; + /* find phase-bias difference */ + dd = rtk->x[IB(j + 1, f, &rtk->opt)] - rtk->x[IB(i + 1, f, &rtk->opt)]; + dd = rtk->opt.gainholdamb * + (dd - ROUND(dd)); /* throwout integer part of answer and multiply by filter gain */ + rtk->x[IB(j + 1, f, &rtk->opt)] -= dd; /* remove fractional part from phase bias diff */ + rtk->ssat[j].icbias[f] += dd; /* and move to IC bias */ + index[nv++] = j; } + } } + } } /* resolve integer ambiguity by LAMBDA ---------------------------------------*/ -static int resamb_LAMBDA(rtk_t *rtk, double *bias, double *xa,int gps,int glo,int sbs) -{ - prcopt_t *opt=&rtk->opt; - int i,j,nb,nb1,info,nx=rtk->nx,na=rtk->na; - double *DP,*y,*b,*db,*Qb,*Qab,*QQ,s[2]; - int *ix; - double coeff[3]; - - trace(3,"resamb_LAMBDA : nx=%d\n",nx); - - rtk->sol.ratio=0.0; - rtk->nb_ar=0; - /* Create index of single to double-difference transformation matrix (D') - used to translate phase biases to double difference */ - ix=imat(nx,2); - if ((nb=ddidx(rtk,ix,gps,glo,sbs))<(rtk->opt.minfixsats-1)) { /* nb is sat pairs */ - errmsg(rtk,"not enough valid double-differences\n"); - free(ix); - return -1; /* flag abort */ - } - rtk->nb_ar=nb; - /* nx=# of float states, na=# of fixed states, nb=# of double-diff phase biases */ - y=mat(nb,1); DP=mat(nb,nx-na); b=mat(nb,2); db=mat(nb,1); Qb=mat(nb,nb); - Qab=mat(na,nb); QQ=mat(na,nb); - - /* phase-bias covariance (Qb) and real-parameters to bias covariance (Qab) */ - /* y=D*xc, Qb=D*Qc*D', Qab=Qac*D' */ - for (i=0;ix[ix[i*2]]-rtk->x[ix[i*2+1]]; - } - for (j=0;jP[ix[i*2]+(na+j)*nx]-rtk->P[ix[i*2+1]+(na+j)*nx]; - } - for (j=0;jP[i+ix[j*2]*nx]-rtk->P[i+ix[j*2+1]*nx]; +static int resamb_LAMBDA(rtk_t *rtk, double *bias, double *xa, int gps, int glo, int sbs) { + prcopt_t *opt = &rtk->opt; + int i, j, nb, nb1, info, nx = rtk->nx, na = rtk->na; + double *DP, *y, *b, *db, *Qb, *Qab, *QQ, s[2]; + int *ix; + double coeff[3]; + + trace(3, "resamb_LAMBDA : nx=%d\n", nx); + + rtk->sol.ratio = 0.0; + rtk->nb_ar = 0; + /* Create index of single to double-difference transformation matrix (D') + used to translate phase biases to double difference */ + ix = imat(nx, 2); + if ((nb = ddidx(rtk, ix, gps, glo, sbs)) < (rtk->opt.minfixsats - 1)) { /* nb is sat pairs */ + errmsg(rtk, "not enough valid double-differences\n"); + free(ix); + return -1; /* flag abort */ + } + rtk->nb_ar = nb; + /* nx=# of float states, na=# of fixed states, nb=# of double-diff phase biases */ + y = mat(nb, 1); + DP = mat(nb, nx - na); + b = mat(nb, 2); + db = mat(nb, 1); + Qb = mat(nb, nb); + Qab = mat(na, nb); + QQ = mat(na, nb); + + /* phase-bias covariance (Qb) and real-parameters to bias covariance (Qab) */ + /* y=D*xc, Qb=D*Qc*D', Qab=Qac*D' */ + for (i = 0; i < nb; i++) { + y[i] = rtk->x[ix[i * 2]] - rtk->x[ix[i * 2 + 1]]; + } + for (j = 0; j < nx - na; j++) + for (i = 0; i < nb; i++) { + DP[i + j * nb] = rtk->P[ix[i * 2] + (na + j) * nx] - rtk->P[ix[i * 2 + 1] + (na + j) * nx]; + } + for (j = 0; j < nb; j++) + for (i = 0; i < nb; i++) { + Qb[i + j * nb] = DP[i + (ix[j * 2] - na) * nb] - DP[i + (ix[j * 2 + 1] - na) * nb]; + } + for (j = 0; j < nb; j++) + for (i = 0; i < na; i++) { + Qab[i + j * na] = rtk->P[i + ix[j * 2] * nx] - rtk->P[i + ix[j * 2 + 1] * nx]; } #ifdef TRACE - double QQb[MAXSAT]; - for (i=0;ixa); /* rtk->xa = rtk->x-Qab*db */ - - /* rtk->Pa=rtk->P-Qab*Qb^-1*Qab') */ - /* covariance of fixed solution (Qa=Qa-Qab*Qb^-1*Qab') */ - matmul("NN",na,nb,nb,Qab,Qb ,QQ); /* QQ = Qab*Qb^-1 */ - matmulm("NT",na,na,nb,QQ ,Qab,rtk->Pa); /* rtk->Pa = rtk->P-QQ*Qab' */ - - trace(3,"resamb : validation ok (nb=%d ratio=%.2f thresh=%.2f s=%.2f/%.2f)\n", - nb,s[0]==0.0?0.0:s[1]/s[0],rtk->sol.thres,s[0],s[1]); - - /* translate double diff fixed phase-bias values to single diff - fix phase-bias values, result in xa */ - restamb(rtk,bias,nb,xa); - } - else nb=0; - } - else { /* validation failed */ - errmsg(rtk,"ambiguity validation failed (nb=%d ratio=%.2f thresh=%.2f s=%.2f/%.2f)\n", - nb,s[1]/s[0],rtk->sol.thres,s[0],s[1]); - nb=0; - } - } - else { - errmsg(rtk,"lambda error (info=%d)\n",info); - nb=0; - } - free(ix); - free(y); free(DP); free(b); free(db); free(Qb); free(Qab); free(QQ); - - return nb; /* number of ambiguities */ + /* lambda/mlambda integer least-square estimation */ + /* return best integer solutions */ + /* b are best integer solutions, s are residuals */ + if (!(info = lambda(nb, 2, y, Qb, b, s))) { + trace(3, "N(1)= "); + tracemat(3, b, 1, nb, 7, 2); + trace(3, "N(2)= "); + tracemat(3, b + nb, 1, nb, 7, 2); + + rtk->sol.ratio = s[0] > 0 ? (float)(s[1] / s[0]) : 0.0f; + if (rtk->sol.ratio > 999.9) rtk->sol.ratio = 999.9f; + + /* adjust AR ratio based on # of sats, unless minAR==maxAR */ + if (opt->thresar[5] != opt->thresar[6]) { + nb1 = nb < 50 ? nb : 50; /* poly only fitted for upto 50 sat pairs */ + /* generate poly coeffs based on nominal AR ratio */ + for ((i = 0); i < 3; i++) { + coeff[i] = ar_poly_coeffs[i][0]; + for ((j = 1); j < 5; j++) coeff[i] = coeff[i] * opt->thresar[0] + ar_poly_coeffs[i][j]; + } + /* generate adjusted AR ratio based on # of sat pairs */ + rtk->sol.thres = coeff[0]; + for (i = 1; i < 3; i++) { + rtk->sol.thres = rtk->sol.thres * 1.0 / (nb1 + 1.0) + coeff[i]; + } + rtk->sol.thres = MIN(MAX(rtk->sol.thres, opt->thresar[5]), opt->thresar[6]); + } else + rtk->sol.thres = (float)opt->thresar[0]; + /* validation by popular ratio-test of residuals*/ + if (s[0] <= 0.0 || s[1] / s[0] >= rtk->sol.thres) { + /* init non phase-bias states and covariances with float solution values */ + /* transform float to fixed solution (xa=x-Qab*Qb\(b0-b)) */ + for (i = 0; i < na; i++) { + rtk->xa[i] = rtk->x[i]; + for (j = 0; j < na; j++) rtk->Pa[i + j * na] = rtk->P[i + j * nx]; + } + /* y = differences between float and fixed dd phase-biases + bias = fixed dd phase-biases */ + for (i = 0; i < nb; i++) { + bias[i] = b[i]; + y[i] -= b[i]; + } + /* adjust non phase-bias states and covariances using fixed solution values */ + if (!matinv(Qb, nb)) { /* returns 0 if inverse successful */ + /* rtk->xa = rtk->x-Qab*Qb^-1*(b0-b) */ + matmul("NN", nb, 1, nb, Qb, y, db); /* db = Qb^-1*(b0-b) */ + matmulm("NN", na, 1, nb, Qab, db, rtk->xa); /* rtk->xa = rtk->x-Qab*db */ + + /* rtk->Pa=rtk->P-Qab*Qb^-1*Qab') */ + /* covariance of fixed solution (Qa=Qa-Qab*Qb^-1*Qab') */ + matmul("NN", na, nb, nb, Qab, Qb, QQ); /* QQ = Qab*Qb^-1 */ + matmulm("NT", na, na, nb, QQ, Qab, rtk->Pa); /* rtk->Pa = rtk->P-QQ*Qab' */ + + trace(3, "resamb : validation ok (nb=%d ratio=%.2f thresh=%.2f s=%.2f/%.2f)\n", nb, + s[0] == 0.0 ? 0.0 : s[1] / s[0], rtk->sol.thres, s[0], s[1]); + + /* translate double diff fixed phase-bias values to single diff + fix phase-bias values, result in xa */ + restamb(rtk, bias, nb, xa); + } else + nb = 0; + } else { /* validation failed */ + errmsg(rtk, "ambiguity validation failed (nb=%d ratio=%.2f thresh=%.2f s=%.2f/%.2f)\n", nb, + s[1] / s[0], rtk->sol.thres, s[0], s[1]); + nb = 0; + } + } else { + errmsg(rtk, "lambda error (info=%d)\n", info); + nb = 0; + } + free(ix); + free(y); + free(DP); + free(b); + free(db); + free(Qb); + free(Qab); + free(QQ); + + return nb; /* number of ambiguities */ } -/* resolve integer ambiguity by LAMBDA using partial fix techniques and multiple attempts -----------------------*/ -static int manage_amb_LAMBDA(rtk_t *rtk, double *bias, double *xa, const int *sat, int nf, int ns) -{ - int gps1=-1,glo1=-1,sbas1=-1,gps2,glo2,sbas2,nb,rerun,dly; - float ratio1,posvar=0; - - /* calc position variance, will skip AR if too high to avoid false fix */ - for (int i=0;i<3;i++) posvar+=rtk->P[i+i*rtk->nx]; - posvar/=3.0; /* maintain compatibility with previous code */ - - trace(3,"posvar=%.6f\n",posvar); - trace(3,"prevRatios= %.3f %.3f\n",rtk->sol.prev_ratio1,rtk->sol.prev_ratio2); - trace(3,"num ambiguities used last AR: %d\n",rtk->nb_ar); - - /* skip AR if don't meet criteria */ - if (rtk->opt.mode<=PMODE_DGPS||rtk->opt.modear==ARMODE_OFF|| - rtk->opt.thresar[0]<1.0||posvar>rtk->opt.thresar[1]) { - trace(3,"Skip AR\n"); - rtk->sol.ratio=0.0; - rtk->sol.prev_ratio1=rtk->sol.prev_ratio2=0.0; - rtk->nb_ar=0; - return 0; - } - // If no fix on previous sample and enough sats, exclude next sat in list. - int lockc[NFREQ], excsat = 0; - if (rtk->sol.prev_ratio2 < rtk->sol.thres && rtk->nb_ar >= rtk->opt.mindropsats) { - // Find the position of the last excluded sat. - int i = 0; - if (rtk->excsat != 0) { - for (; i < ns; i++) { - if (rtk->excsat == sat[i]) { - i++; - break; - } - } - // If not found then restart from the first sat. - if (i >= ns) i = 0; - } - // Find the next sat used last time for AR. +/* resolve integer ambiguity by LAMBDA using partial fix techniques and multiple attempts + * -----------------------*/ +static int manage_amb_LAMBDA(rtk_t *rtk, double *bias, double *xa, const int *sat, int nf, int ns) { + int gps1 = -1, glo1 = -1, sbas1 = -1, gps2, glo2, sbas2, nb, rerun, dly; + float ratio1, posvar = 0; + + /* calc position variance, will skip AR if too high to avoid false fix */ + for (int i = 0; i < 3; i++) posvar += rtk->P[i + i * rtk->nx]; + posvar /= 3.0; /* maintain compatibility with previous code */ + + trace(3, "posvar=%.6f\n", posvar); + trace(3, "prevRatios= %.3f %.3f\n", rtk->sol.prev_ratio1, rtk->sol.prev_ratio2); + trace(3, "num ambiguities used last AR: %d\n", rtk->nb_ar); + + /* skip AR if don't meet criteria */ + if (rtk->opt.mode <= PMODE_DGPS || rtk->opt.modear == ARMODE_OFF || rtk->opt.thresar[0] < 1.0 || + posvar > rtk->opt.thresar[1]) { + trace(3, "Skip AR\n"); + rtk->sol.ratio = 0.0; + rtk->sol.prev_ratio1 = rtk->sol.prev_ratio2 = 0.0; + rtk->nb_ar = 0; + return 0; + } + // If no fix on previous sample and enough sats, exclude next sat in list. + int lockc[NFREQ], excsat = 0; + if (rtk->sol.prev_ratio2 < rtk->sol.thres && rtk->nb_ar >= rtk->opt.mindropsats) { + // Find the position of the last excluded sat. + int i = 0; + if (rtk->excsat != 0) { for (; i < ns; i++) { - for (int f = 0; f < nf; f++) { - if (rtk->ssat[sat[i] - 1].vsat[f] && rtk->ssat[sat[i] - 1].lock[f] >= 0 && - rtk->ssat[sat[i] - 1].azel[1] >= rtk->opt.elmin) { - excsat = sat[i]; - break; - } + if (rtk->excsat == sat[i]) { + i++; + break; } - if (excsat) break; } - if (excsat) { - for (int f = 0; f < nf; f++) { - lockc[f] = rtk->ssat[excsat - 1].lock[f]; // Save lock count. - // Remove sat from AR long enough to enable hold if stays fixed. - rtk->ssat[excsat - 1].lock[f] = -rtk->nb_ar; + // If not found then restart from the first sat. + if (i >= ns) i = 0; + } + // Find the next sat used last time for AR. + for (; i < ns; i++) { + for (int f = 0; f < nf; f++) { + if (rtk->ssat[sat[i] - 1].vsat[f] && rtk->ssat[sat[i] - 1].lock[f] >= 0 && + rtk->ssat[sat[i] - 1].azel[1] >= rtk->opt.elmin) { + excsat = sat[i]; + break; } - trace(3, "AR: exclude sat %d\n", excsat); } - rtk->excsat = excsat; - } - - /* for inital ambiguity resolution attempt, include all enabled sats */ - gps1=1; /* always enable gps for initial pass */ - glo1=(rtk->opt.navsys&SYS_GLO)?(((rtk->opt.glomodear==GLO_ARMODE_FIXHOLD)&&!rtk->holdamb)?0:1):0; - sbas1=(rtk->opt.navsys&SYS_GLO)?glo1:((rtk->opt.navsys&SYS_SBS)?1:0); - /* first attempt to resolve ambiguities */ - nb=resamb_LAMBDA(rtk,bias,xa,gps1,glo1,sbas1); - ratio1=rtk->sol.ratio; - /* reject bad satellites if AR filtering enabled */ - if (rtk->opt.arfilter) { - rerun=0; - /* if results are much poorer than previous epoch or dropped below ar ratio thresh, remove new sats */ - if (nb>=0 && rtk->sol.prev_ratio2>=rtk->sol.thres && ((rtk->sol.ratiosol.thres) || - (rtk->sol.ratioopt.thresar[0]*1.1 && rtk->sol.ratiosol.prev_ratio1/2.0))) { - trace(3,"low ratio: check for new sat\n"); - dly=2; - for (int i=0;issat[sat[i]-1].fix[f]!=2) continue; - /* check for new sats */ - if (rtk->ssat[sat[i]-1].lock[f]==0) { - trace(3,"remove sat %d:%d lock=%d\n",sat[i],f,rtk->ssat[sat[i]-1].lock[f]); - rtk->ssat[sat[i]-1].lock[f]=-rtk->opt.minlock-dly; /* delay use of this sat with stagger */ - dly+=2; /* stagger next try of new sats */ - rerun=1; - } - } - } - /* rerun if filter removed any sats */ - if (rerun) { - trace(3,"rerun AR with new sats removed\n"); - /* try again with new sats removed */ - nb=resamb_LAMBDA(rtk,bias,xa,gps1,glo1,sbas1); - } + if (excsat) break; } - rtk->sol.prev_ratio1=ratio1; - - - /* if fix-and-hold gloarmode enabled, re-run AR with final gps/glo settings if differ from above */ - if ((rtk->opt.navsys&SYS_GLO) && rtk->opt.glomodear==GLO_ARMODE_FIXHOLD && rtk->sol.ratiosol.thres) { - glo2=sbas2=0; - /* turn off gpsmode if not enabled and got good fix (used for debug and eval only) */ - gps2=rtk->opt.gpsmodear==0&&rtk->sol.ratio>=rtk->sol.thres?0:1; + if (excsat) { + for (int f = 0; f < nf; f++) { + lockc[f] = rtk->ssat[excsat - 1].lock[f]; // Save lock count. + // Remove sat from AR long enough to enable hold if stays fixed. + rtk->ssat[excsat - 1].lock[f] = -rtk->nb_ar; + } + trace(3, "AR: exclude sat %d\n", excsat); + } + rtk->excsat = excsat; + } - /* if modes changed since initial AR run or haven't run yet,re-run with new modes */ - if (glo1!=glo2||gps1!=gps2) - nb=resamb_LAMBDA(rtk,bias,xa,gps2,glo2,sbas2); + /* for inital ambiguity resolution attempt, include all enabled sats */ + gps1 = 1; /* always enable gps for initial pass */ + glo1 = (rtk->opt.navsys & SYS_GLO) + ? (((rtk->opt.glomodear == GLO_ARMODE_FIXHOLD) && !rtk->holdamb) ? 0 : 1) + : 0; + sbas1 = (rtk->opt.navsys & SYS_GLO) ? glo1 : ((rtk->opt.navsys & SYS_SBS) ? 1 : 0); + /* first attempt to resolve ambiguities */ + nb = resamb_LAMBDA(rtk, bias, xa, gps1, glo1, sbas1); + ratio1 = rtk->sol.ratio; + /* reject bad satellites if AR filtering enabled */ + if (rtk->opt.arfilter) { + rerun = 0; + /* if results are much poorer than previous epoch or dropped below ar ratio thresh, remove new + * sats */ + if (nb >= 0 && rtk->sol.prev_ratio2 >= rtk->sol.thres && + ((rtk->sol.ratio < rtk->sol.thres) || (rtk->sol.ratio < rtk->opt.thresar[0] * 1.1 && + rtk->sol.ratio < rtk->sol.prev_ratio1 / 2.0))) { + trace(3, "low ratio: check for new sat\n"); + dly = 2; + for (int i = 0; i < ns; i++) + for (int f = 0; f < nf; f++) { + if (rtk->ssat[sat[i] - 1].fix[f] != 2) continue; + /* check for new sats */ + if (rtk->ssat[sat[i] - 1].lock[f] == 0) { + trace(3, "remove sat %d:%d lock=%d\n", sat[i], f, rtk->ssat[sat[i] - 1].lock[f]); + rtk->ssat[sat[i] - 1].lock[f] = + -rtk->opt.minlock - dly; /* delay use of this sat with stagger */ + dly += 2; /* stagger next try of new sats */ + rerun = 1; + } + } } - /* Restore excluded sat if still no fix or significant increase in ar ratio */ - if (excsat && (rtk->sol.ratio < rtk->sol.thres) && - (rtk->sol.ratio < (1.5 * rtk->sol.prev_ratio2))) { - for (int f = 0; f < nf; f++) rtk->ssat[excsat - 1].lock[f] = lockc[f]; - trace(3, "AR: restore sat %d\n", excsat); + /* rerun if filter removed any sats */ + if (rerun) { + trace(3, "rerun AR with new sats removed\n"); + /* try again with new sats removed */ + nb = resamb_LAMBDA(rtk, bias, xa, gps1, glo1, sbas1); } + } + rtk->sol.prev_ratio1 = ratio1; + + /* if fix-and-hold gloarmode enabled, re-run AR with final gps/glo settings if differ from above + */ + if ((rtk->opt.navsys & SYS_GLO) && rtk->opt.glomodear == GLO_ARMODE_FIXHOLD && + rtk->sol.ratio < rtk->sol.thres) { + glo2 = sbas2 = 0; + /* turn off gpsmode if not enabled and got good fix (used for debug and eval only) */ + gps2 = rtk->opt.gpsmodear == 0 && rtk->sol.ratio >= rtk->sol.thres ? 0 : 1; + + /* if modes changed since initial AR run or haven't run yet,re-run with new modes */ + if (glo1 != glo2 || gps1 != gps2) nb = resamb_LAMBDA(rtk, bias, xa, gps2, glo2, sbas2); + } + /* Restore excluded sat if still no fix or significant increase in ar ratio */ + if (excsat && (rtk->sol.ratio < rtk->sol.thres) && + (rtk->sol.ratio < (1.5 * rtk->sol.prev_ratio2))) { + for (int f = 0; f < nf; f++) rtk->ssat[excsat - 1].lock[f] = lockc[f]; + trace(3, "AR: restore sat %d\n", excsat); + } - rtk->sol.prev_ratio1=ratio1>0?ratio1:rtk->sol.ratio; - rtk->sol.prev_ratio2=rtk->sol.ratio; + rtk->sol.prev_ratio1 = ratio1 > 0 ? ratio1 : rtk->sol.ratio; + rtk->sol.prev_ratio2 = rtk->sol.ratio; - return nb; + return nb; } /* validation of solution ----------------------------------------------------*/ -static int valpos(rtk_t *rtk, const double *v, const double *R, const int *vflg, - int nv, double thres) -{ - double fact=thres*thres; - int i,stat=1,sat1,sat2,type,freq; - char *stype; - - trace(3,"valpos : nv=%d thres=%.1f\n",nv,thres); - - /* post-fit residual test */ - for (i=0;i>16)&0xFF; - sat2=(vflg[i]>> 8)&0xFF; - type=(vflg[i]>> 4)&0xF; - freq=vflg[i]&0xF; - stype=type==0?"L":(type==1?"P":"C"); - errmsg(rtk,"large residual (sat=%2d-%2d %s%d v=%6.3f sig=%.3f)\n", - sat1,sat2,stype,freq+1,v[i],SQRT(R[i+i*nv])); - } - return stat; +static int valpos(rtk_t *rtk, const double *v, const double *R, const int *vflg, int nv, + double thres) { + double fact = thres * thres; + int i, stat = 1, sat1, sat2, type, freq; + char *stype; + + trace(3, "valpos : nv=%d thres=%.1f\n", nv, thres); + + /* post-fit residual test */ + for (i = 0; i < nv; i++) { + if (v[i] * v[i] <= fact * R[i + i * nv]) continue; + sat1 = (vflg[i] >> 16) & 0xFF; + sat2 = (vflg[i] >> 8) & 0xFF; + type = (vflg[i] >> 4) & 0xF; + freq = vflg[i] & 0xF; + stype = type == 0 ? "L" : (type == 1 ? "P" : "C"); + errmsg(rtk, "large residual (sat=%2d-%2d %s%d v=%6.3f sig=%.3f)\n", sat1, sat2, stype, freq + 1, + v[i], SQRT(R[i + i * nv])); + } + return stat; } /* relpos()relative positioning ------------------------------------------------------ * args: rtk IO gps solution structure @@ -1972,483 +2011,524 @@ static int valpos(rtk_t *rtk, const double *v, const double *R, const int *vflg, nr I # of ref observations (base) nav I satellite navigation data */ -static int relpos(rtk_t *rtk, const obsd_t *obs, int nu, int nr, - const nav_t *nav) -{ - prcopt_t *opt=&rtk->opt; - gtime_t time=obs[0].time; - double *rs,*dts,*var,*y,*e,*azel,*freq,*v,*H,*R,*xp,*Pp,*xa,*bias,dt; - int i,j,f,n=nu+nr,ns,ny,nv,sat[MAXSAT],iu[MAXSAT],ir[MAXSAT]; - int info,vflg[MAXOBS*NFREQ*2+1],svh[MAXOBS*2]; - int stat=rtk->opt.mode<=PMODE_DGPS?SOLQ_DGPS:SOLQ_FLOAT; - int nf=opt->ionoopt==IONOOPT_IFLC?1:opt->nf; - - trace(3,"relpos : nu=%d nr=%d\n",nu,nr); - - /* define local matrices, n=total observations, base + rover */ - rs=mat(6,n); /* range to satellites */ - dts=mat(2,n); /* satellite clock biases */ - var=mat(1,n); - y=mat(nf*2,n); - e=mat(3,n); - azel=zeros(2,n); /* [az, el] */ - freq=zeros(nf,n); - - /* init satellite status arrays */ - for (i=0;issat[i].sys=satsys(i+1,NULL); /* gnss system */ - for (j=0;jssat[i].vsat[j]=0; /* valid satellite */ - rtk->ssat[i].snr_rover[j]=0; - rtk->ssat[i].snr_base[j] =0; - } +static int relpos(rtk_t *rtk, const obsd_t *obs, int nu, int nr, const nav_t *nav) { + prcopt_t *opt = &rtk->opt; + gtime_t time = obs[0].time; + double *rs, *dts, *var, *y, *e, *azel, *freq, *v, *H, *R, *xp, *Pp, *xa, *bias, dt; + int i, j, f, n = nu + nr, ns, ny, nv, sat[MAXSAT], iu[MAXSAT], ir[MAXSAT]; + int info, vflg[MAXOBS * NFREQ * 2 + 1], svh[MAXOBS * 2]; + int stat = rtk->opt.mode <= PMODE_DGPS ? SOLQ_DGPS : SOLQ_FLOAT; + int nf = opt->ionoopt == IONOOPT_IFLC ? 1 : opt->nf; + + trace(3, "relpos : nu=%d nr=%d\n", nu, nr); + + /* define local matrices, n=total observations, base + rover */ + rs = mat(6, n); /* range to satellites */ + dts = mat(2, n); /* satellite clock biases */ + var = mat(1, n); + y = mat(nf * 2, n); + e = mat(3, n); + azel = zeros(2, n); /* [az, el] */ + freq = zeros(nf, n); + + /* init satellite status arrays */ + for (i = 0; i < MAXSAT; i++) { + rtk->ssat[i].sys = satsys(i + 1, NULL); /* gnss system */ + for (j = 0; j < NFREQ; j++) { + rtk->ssat[i].vsat[j] = 0; /* valid satellite */ + rtk->ssat[i].snr_rover[j] = 0; + rtk->ssat[i].snr_base[j] = 0; } - /* compute satellite positions, velocities and clocks for base and rover */ - satposs(time,obs,n,nav,opt->sateph,rs,dts,var,svh); - - /* calculate [range - measured pseudorange] for base station (phase and code) - output is in y[nu:nu+nr], see call for rover below for more details */ - trace(3,"base station:\n"); - if (!zdres(1,obs+nu,nr,rs+nu*6,dts+nu*2,var+nu,svh+nu,nav,rtk->rb,opt, - y+nu*nf*2,e+nu*3,azel+nu*2,freq+nu*nf)) { - errmsg(rtk,"initial base station position error\n"); - - free(rs); free(dts); free(var); free(y); free(e); free(azel); free(freq); - return 0; + } + /* compute satellite positions, velocities and clocks for base and rover */ + satposs(time, obs, n, nav, opt->sateph, rs, dts, var, svh); + + /* calculate [range - measured pseudorange] for base station (phase and code) + output is in y[nu:nu+nr], see call for rover below for more details */ + trace(3, "base station:\n"); + if (!zdres(1, obs + nu, nr, rs + nu * 6, dts + nu * 2, var + nu, svh + nu, nav, rtk->rb, opt, + y + nu * nf * 2, e + nu * 3, azel + nu * 2, freq + nu * nf)) { + errmsg(rtk, "initial base station position error\n"); + + free(rs); + free(dts); + free(var); + free(y); + free(e); + free(azel); + free(freq); + return 0; + } + /* time diff between base and rover observations */ + if (opt->intpref) { + /* time-interpolation of base residuals */ + dt = intpres(time, obs + nu, nr, nav, rtk, y + nu * nf * 2); + } else + dt = timediff(time, obs[nu].time); + trace(3, "relpos : dt=%.3f\n", dt); + + if (opt->mode != PMODE_MOVEB) { + /* check if exceeded max age of differential */ + rtk->sol.age = dt; + if (fabs(rtk->sol.age) > opt->maxtdiff) { + errmsg(rtk, "age of differential error (age=%.1f)\n", rtk->sol.age); + free(rs); + free(dts); + free(var); + free(y); + free(e); + free(azel); + free(freq); + return 1; } - /* time diff between base and rover observations */ - if (opt->intpref) { - /* time-interpolation of base residuals */ - dt=intpres(time,obs+nu,nr,nav,rtk,y+nu*nf*2); - } else dt=timediff(time,obs[nu].time); - trace(3,"relpos : dt=%.3f\n",dt); - - if (opt->mode!=PMODE_MOVEB) { - /* check if exceeded max age of differential */ - rtk->sol.age=dt; - if (fabs(rtk->sol.age)>opt->maxtdiff) { - errmsg(rtk,"age of differential error (age=%.1f)\n",rtk->sol.age); - free(rs); free(dts); free(var); free(y); free(e); free(azel); free(freq); - return 1; + } + /* select common satellites between rover and base-station */ + if ((ns = selsat(obs, azel, nu, nr, opt, sat, iu, ir)) <= 0) { + errmsg(rtk, "no common satellite\n"); + + free(rs); + free(dts); + free(var); + free(y); + free(e); + free(azel); + free(freq); + return 0; + } + /* update kalman filter states (pos,vel,acc,ionosp, troposp, sat phase biases) */ + trace(4, "before udstate: x="); + tracemat(4, rtk->x, 1, NR(opt), 13, 4); + udstate(rtk, obs, sat, iu, ir, ns, nav); + trace(4, "after udstate x="); + tracemat(4, rtk->x, 1, NR(opt), 13, 4); + + for (i = 0; i < ns; i++) + for (j = 0; j < nf; j++) { + /* snr of base and rover receiver */ + rtk->ssat[sat[i] - 1].snr_rover[j] = obs[iu[i]].SNR[j]; + rtk->ssat[sat[i] - 1].snr_base[j] = obs[ir[i]].SNR[j]; + } + + /* initialize Pp,xa to zero, xp to rtk->x */ + xp = mat(rtk->nx, 1); + Pp = zeros(rtk->nx, rtk->nx); + xa = mat(rtk->nx, 1); + matcpy(xp, rtk->x, rtk->nx, 1); + matcpy(Pp, rtk->P, rtk->nx, rtk->nx); + + ny = ns * nf * 2 + 2; + v = mat(ny, 1); + H = zeros(rtk->nx, ny); + R = mat(ny, ny); + bias = mat(rtk->nx, 1); + + trace(3, "rover: dt=%.3f\n", dt); + for (i = 0; i < opt->niter; i++) { + /* calculate zero diff residuals [range - measured pseudorange] for rover (phase and code) + output is in y[0:nu-1], only shared input with base is nav + obs = sat observations + nu = # of sats + rs = range to sats + dts = sat clock biases (rover) + svh = sat health flags + nav = sat nav data + xp = kalman states + opt = options + y = zero diff residuals (code and phase) + e = line of sight unit vectors to sats + azel = [az, el] to sats */ + if (!zdres(0, obs, nu, rs, dts, var, svh, nav, xp, opt, y, e, azel, freq)) { + errmsg(rtk, "rover initial position error\n"); + stat = SOLQ_NONE; + break; + } + /* calculate double-differenced residuals and create state matrix from sat angles + O rtk->ssat[i].resp[j] = residual pseudorange error + O rtk->ssat[i].resc[j] = residual carrier phase error + I dt = time diff between base and rover observations + I Pp = covariance matrix of float solution + I sat = list of common sats + I iu,ir = user and ref indices to sats + I ns = # of sats + O v = double diff residuals (phase and code) + O H = partial derivatives + O R = double diff measurement error covariances + O vflg = list of sats used for dd */ + if ((nv = ddres(rtk, obs, dt, xp, Pp, sat, y, e, azel, freq, iu, ir, ns, v, H, R, vflg)) < 4) { + errmsg(rtk, "not enough double-differenced residual, n=%d\n", nv); + stat = SOLQ_NONE; + break; + } + /* kalman filter measurement update, updates x,y,z,sat phase biases, etc + K=P*H*(H'*P*H+R)^-1 + xp=x+K*v + Pp=(I-K*H')*P */ + trace(3, "before filter x="); + tracemat(3, rtk->x, 1, 9, 13, 6); + if ((info = filter(xp, Pp, H, v, R, rtk->nx, nv))) { + errmsg(rtk, "filter error (info=%d)\n", info); + stat = SOLQ_NONE; + break; + } + trace(3, "after filter x="); + tracemat(3, xp, 1, 9, 13, 6); + trace(4, "x(%d)=", i + 1); + tracemat(4, xp, 1, NR(opt), 13, 4); + } + /* calc zero diff residuals again after kalman filter update */ + if (stat != SOLQ_NONE && zdres(0, obs, nu, rs, dts, var, svh, nav, xp, opt, y, e, azel, freq)) { + /* calc double diff residuals again after kalman filter update for float solution */ + nv = ddres(rtk, obs, dt, xp, Pp, sat, y, e, azel, freq, iu, ir, ns, v, NULL, R, vflg); + + /* validation of float solution, always returns 1, msg to trace file if large residual */ + if (valpos(rtk, v, R, vflg, nv, 4.0)) { + /* copy states */ + matcpy(rtk->x, xp, rtk->nx, 1); + matcpy(rtk->P, Pp, rtk->nx, rtk->nx); + + /* update valid satellite status for ambiguity control */ + rtk->sol.ns = 0; + for (i = 0; i < ns; i++) + for (f = 0; f < nf; f++) { + if (!rtk->ssat[sat[i] - 1].vsat[f]) continue; + rtk->ssat[sat[i] - 1].outc[f] = 0; + if (f == 0) rtk->sol.ns++; /* valid satellite count by L1 */ + } + /* too few valid phases */ + if (rtk->sol.ns < 4) stat = SOLQ_DGPS; + } else + stat = SOLQ_NONE; + } + /* resolve integer ambiguity by LAMBDA */ + if (stat == SOLQ_FLOAT) { + /* if valid fixed solution, process it */ + if (manage_amb_LAMBDA(rtk, bias, xa, sat, nf, ns) > 1) { + /* find zero-diff residuals for fixed solution */ + if (zdres(0, obs, nu, rs, dts, var, svh, nav, xa, opt, y, e, azel, freq)) { + /* post-fit residuals for fixed solution (xa includes fixed phase biases, rtk->xa does not) + */ + nv = ddres(rtk, obs, dt, xa, Pp, sat, y, e, azel, freq, iu, ir, ns, v, NULL, R, vflg); + + /* validation of fixed solution, always returns valid */ + if (valpos(rtk, v, R, vflg, nv, 4.0)) { + /* hold integer ambiguity if meet minfix count */ + if (++rtk->nfix >= rtk->opt.minfix) { + // Note that the modear needs to be fix-and-hold in + // order for glomodear fix-and-hold to be applied here, + // to prevent glomodear alone forcing fix-and-hold. + if (rtk->opt.modear == ARMODE_FIXHOLD) holdamb(rtk, xa); + /* switch to kinematic after qualify for hold if in static-start mode */ + if (rtk->opt.mode == PMODE_STATIC_START) { + rtk->opt.mode = PMODE_KINEMA; + trace(3, "Fix and hold complete: switch to kinematic mode\n"); + } + } + stat = SOLQ_FIX; } + } } - /* select common satellites between rover and base-station */ - if ((ns=selsat(obs,azel,nu,nr,opt,sat,iu,ir))<=0) { - errmsg(rtk,"no common satellite\n"); + } - free(rs); free(dts); free(var); free(y); free(e); free(azel); free(freq); - return 0; - } - /* update kalman filter states (pos,vel,acc,ionosp, troposp, sat phase biases) */ - trace(4,"before udstate: x="); tracemat(4,rtk->x,1,NR(opt),13,4); - udstate(rtk,obs,sat,iu,ir,ns,nav); - trace(4,"after udstate x="); tracemat(4,rtk->x,1,NR(opt),13,4); - - for (i=0;issat[sat[i]-1].snr_rover[j]=obs[iu[i]].SNR[j]; - rtk->ssat[sat[i]-1].snr_base[j] =obs[ir[i]].SNR[j]; - } - - /* initialize Pp,xa to zero, xp to rtk->x */ - xp=mat(rtk->nx,1); Pp=zeros(rtk->nx,rtk->nx); xa=mat(rtk->nx,1); - matcpy(xp,rtk->x,rtk->nx,1); - matcpy(Pp,rtk->P,rtk->nx,rtk->nx); - - ny=ns*nf*2+2; - v=mat(ny,1); H=zeros(rtk->nx,ny); R=mat(ny,ny); bias=mat(rtk->nx,1); - - trace(3,"rover: dt=%.3f\n",dt); - for (i=0;initer;i++) { - /* calculate zero diff residuals [range - measured pseudorange] for rover (phase and code) - output is in y[0:nu-1], only shared input with base is nav - obs = sat observations - nu = # of sats - rs = range to sats - dts = sat clock biases (rover) - svh = sat health flags - nav = sat nav data - xp = kalman states - opt = options - y = zero diff residuals (code and phase) - e = line of sight unit vectors to sats - azel = [az, el] to sats */ - if (!zdres(0,obs,nu,rs,dts,var,svh,nav,xp,opt,y,e,azel,freq)) { - errmsg(rtk,"rover initial position error\n"); - stat=SOLQ_NONE; - break; - } - /* calculate double-differenced residuals and create state matrix from sat angles - O rtk->ssat[i].resp[j] = residual pseudorange error - O rtk->ssat[i].resc[j] = residual carrier phase error - I dt = time diff between base and rover observations - I Pp = covariance matrix of float solution - I sat = list of common sats - I iu,ir = user and ref indices to sats - I ns = # of sats - O v = double diff residuals (phase and code) - O H = partial derivatives - O R = double diff measurement error covariances - O vflg = list of sats used for dd */ - if ((nv=ddres(rtk,obs,dt,xp,Pp,sat,y,e,azel,freq,iu,ir,ns,v,H,R,vflg))<4) { - errmsg(rtk,"not enough double-differenced residual, n=%d\n", nv); - stat=SOLQ_NONE; - break; - } - /* kalman filter measurement update, updates x,y,z,sat phase biases, etc - K=P*H*(H'*P*H+R)^-1 - xp=x+K*v - Pp=(I-K*H')*P */ - trace(3,"before filter x=");tracemat(3,rtk->x,1,9,13,6); - if ((info=filter(xp,Pp,H,v,R,rtk->nx,nv))) { - errmsg(rtk,"filter error (info=%d)\n",info); - stat=SOLQ_NONE; - break; - } - trace(3,"after filter x=");tracemat(3,xp,1,9,13,6); - trace(4,"x(%d)=",i+1); tracemat(4,xp,1,NR(opt),13,4); - } - /* calc zero diff residuals again after kalman filter update */ - if (stat!=SOLQ_NONE&&zdres(0,obs,nu,rs,dts,var,svh,nav,xp,opt,y,e,azel,freq)) { - - /* calc double diff residuals again after kalman filter update for float solution */ - nv=ddres(rtk,obs,dt,xp,Pp,sat,y,e,azel,freq,iu,ir,ns,v,NULL,R,vflg); - - /* validation of float solution, always returns 1, msg to trace file if large residual */ - if (valpos(rtk,v,R,vflg,nv,4.0)) { - - /* copy states */ - matcpy(rtk->x,xp,rtk->nx,1); - matcpy(rtk->P,Pp,rtk->nx,rtk->nx); - - /* update valid satellite status for ambiguity control */ - rtk->sol.ns=0; - for (i=0;issat[sat[i]-1].vsat[f]) continue; - rtk->ssat[sat[i]-1].outc[f]=0; - if (f==0) rtk->sol.ns++; /* valid satellite count by L1 */ - } - /* too few valid phases */ - if (rtk->sol.ns<4) stat=SOLQ_DGPS; - } - else stat=SOLQ_NONE; - } - /* resolve integer ambiguity by LAMBDA */ - if (stat==SOLQ_FLOAT) { - /* if valid fixed solution, process it */ - if (manage_amb_LAMBDA(rtk,bias,xa,sat,nf,ns)>1) { - - /* find zero-diff residuals for fixed solution */ - if (zdres(0,obs,nu,rs,dts,var,svh,nav,xa,opt,y,e,azel,freq)) { - - /* post-fit residuals for fixed solution (xa includes fixed phase biases, rtk->xa does not) */ - nv=ddres(rtk,obs,dt,xa,Pp,sat,y,e,azel,freq,iu,ir,ns,v,NULL,R,vflg); - - /* validation of fixed solution, always returns valid */ - if (valpos(rtk,v,R,vflg,nv,4.0)) { - - /* hold integer ambiguity if meet minfix count */ - if (++rtk->nfix>=rtk->opt.minfix) { - // Note that the modear needs to be fix-and-hold in - // order for glomodear fix-and-hold to be applied here, - // to prevent glomodear alone forcing fix-and-hold. - if (rtk->opt.modear==ARMODE_FIXHOLD) - holdamb(rtk,xa); - /* switch to kinematic after qualify for hold if in static-start mode */ - if (rtk->opt.mode==PMODE_STATIC_START) { - rtk->opt.mode=PMODE_KINEMA; - trace(3,"Fix and hold complete: switch to kinematic mode\n"); - } - } - stat=SOLQ_FIX; - } - } - } + /* save solution status (fixed or float) */ + if (stat == SOLQ_FIX) { + for (i = 0; i < 3; i++) { + rtk->sol.rr[i] = rtk->xa[i]; + rtk->sol.qr[i] = (float)rtk->Pa[i + i * rtk->na]; } + rtk->sol.qr[3] = (float)rtk->Pa[1]; + rtk->sol.qr[4] = (float)rtk->Pa[1 + 2 * rtk->na]; + rtk->sol.qr[5] = (float)rtk->Pa[2]; - /* save solution status (fixed or float) */ - if (stat==SOLQ_FIX) { - for (i=0;i<3;i++) { - rtk->sol.rr[i]=rtk->xa[i]; - rtk->sol.qr[i]=(float)rtk->Pa[i+i*rtk->na]; - } - rtk->sol.qr[3]=(float)rtk->Pa[1]; - rtk->sol.qr[4]=(float)rtk->Pa[1+2*rtk->na]; - rtk->sol.qr[5]=(float)rtk->Pa[2]; - - if (rtk->opt.dynamics) { /* velocity and covariance */ - for (i=3;i<6;i++) { - rtk->sol.rr[i]=rtk->xa[i]; - rtk->sol.qv[i-3]=(float)rtk->Pa[i+i*rtk->na]; - } - rtk->sol.qv[3]=(float)rtk->Pa[4+3*rtk->na]; - rtk->sol.qv[4]=(float)rtk->Pa[5+4*rtk->na]; - rtk->sol.qv[5]=(float)rtk->Pa[5+3*rtk->na]; - } + if (rtk->opt.dynamics) { /* velocity and covariance */ + for (i = 3; i < 6; i++) { + rtk->sol.rr[i] = rtk->xa[i]; + rtk->sol.qv[i - 3] = (float)rtk->Pa[i + i * rtk->na]; + } + rtk->sol.qv[3] = (float)rtk->Pa[4 + 3 * rtk->na]; + rtk->sol.qv[4] = (float)rtk->Pa[5 + 4 * rtk->na]; + rtk->sol.qv[5] = (float)rtk->Pa[5 + 3 * rtk->na]; + } + } else { /* float solution */ + for (i = 0; i < 3; i++) { + rtk->sol.rr[i] = rtk->x[i]; + rtk->sol.qr[i] = (float)rtk->P[i + i * rtk->nx]; + } + rtk->sol.qr[3] = (float)rtk->P[1]; + rtk->sol.qr[4] = (float)rtk->P[1 + 2 * rtk->nx]; + rtk->sol.qr[5] = (float)rtk->P[2]; + + if (rtk->opt.dynamics) { /* velocity and covariance */ + for (i = 3; i < 6; i++) { + rtk->sol.rr[i] = rtk->x[i]; + rtk->sol.qv[i - 3] = (float)rtk->P[i + i * rtk->nx]; + } + rtk->sol.qv[3] = (float)rtk->P[4 + 3 * rtk->nx]; + rtk->sol.qv[4] = (float)rtk->P[5 + 4 * rtk->nx]; + rtk->sol.qv[5] = (float)rtk->P[5 + 3 * rtk->nx]; } - else { /* float solution */ - for (i=0;i<3;i++) { - rtk->sol.rr[i]=rtk->x[i]; - rtk->sol.qr[i]=(float)rtk->P[i+i*rtk->nx]; - } - rtk->sol.qr[3]=(float)rtk->P[1]; - rtk->sol.qr[4]=(float)rtk->P[1+2*rtk->nx]; - rtk->sol.qr[5]=(float)rtk->P[2]; - - if (rtk->opt.dynamics) { /* velocity and covariance */ - for (i=3;i<6;i++) { - rtk->sol.rr[i]=rtk->x[i]; - rtk->sol.qv[i-3]=(float)rtk->P[i+i*rtk->nx]; - } - rtk->sol.qv[3]=(float)rtk->P[4+3*rtk->nx]; - rtk->sol.qv[4]=(float)rtk->P[5+4*rtk->nx]; - rtk->sol.qv[5]=(float)rtk->P[5+3*rtk->nx]; - } - rtk->nfix=0; - } - trace(3,"sol_rr= ");tracemat(3,rtk->sol.rr,1,6,15,3); - /* save phase measurements */ - for (i=0;issat[obs[i].sat-1].pt[obs[i].rcv-1][j]=obs[i].time; - rtk->ssat[obs[i].sat-1].ph[obs[i].rcv-1][j]=obs[i].L[j]; - } - for (i=0;issat[i].fix[j]==2&&stat!=SOLQ_FIX) rtk->ssat[i].fix[j]=1; */ - if (rtk->ssat[i].slip[j]&LLI_SLIP) rtk->ssat[i].slipc[j]++; - /* Inc lock count if this sat used for good fix */ - if (!rtk->ssat[i].vsat[j]) continue; - if (rtk->ssat[i].lock[j]<0||(rtk->nfix>0&&rtk->ssat[i].fix[j]>=2)) - rtk->ssat[i].lock[j]++; - } - free(rs); free(dts); free(var); free(y); free(e); free(azel); free(freq); - free(xp); free(Pp); free(xa); free(v); free(H); free(R); free(bias); - - if (stat!=SOLQ_NONE) rtk->sol.stat=stat; - - return stat!=SOLQ_NONE; + rtk->nfix = 0; + } + trace(3, "sol_rr= "); + tracemat(3, rtk->sol.rr, 1, 6, 15, 3); + /* save phase measurements */ + for (i = 0; i < n; i++) + for (j = 0; j < nf; j++) { + if (obs[i].L[j] == 0.0) continue; + rtk->ssat[obs[i].sat - 1].pt[obs[i].rcv - 1][j] = obs[i].time; + rtk->ssat[obs[i].sat - 1].ph[obs[i].rcv - 1][j] = obs[i].L[j]; + } + for (i = 0; i < MAXSAT; i++) + for (j = 0; j < nf; j++) { + /* Don't lose track of which sats were used to try and resolve the ambiguities */ + /* if (rtk->ssat[i].fix[j]==2&&stat!=SOLQ_FIX) rtk->ssat[i].fix[j]=1; */ + if (rtk->ssat[i].slip[j] & LLI_SLIP) rtk->ssat[i].slipc[j]++; + /* Inc lock count if this sat used for good fix */ + if (!rtk->ssat[i].vsat[j]) continue; + if (rtk->ssat[i].lock[j] < 0 || (rtk->nfix > 0 && rtk->ssat[i].fix[j] >= 2)) + rtk->ssat[i].lock[j]++; + } + free(rs); + free(dts); + free(var); + free(y); + free(e); + free(azel); + free(freq); + free(xp); + free(Pp); + free(xa); + free(v); + free(H); + free(R); + free(bias); + + if (stat != SOLQ_NONE) rtk->sol.stat = stat; + + return stat != SOLQ_NONE; } /* initialize RTK control ------------------------------------------------------ -* initialize RTK control struct -* args : rtk_t *rtk IO TKk control/result struct -* prcopt_t *opt I positioning options (see rtklib.h) -* return : none -*-----------------------------------------------------------------------------*/ -extern void rtkinit(rtk_t *rtk, const prcopt_t *opt) -{ - sol_t sol0={{0}}; - ambc_t ambc0={{{0}}}; - ssat_t ssat0={0}; - int i; - - trace(3,"rtkinit :\n"); - - rtk->sol=sol0; - for (i=0;i<6;i++) rtk->rb[i]=0.0; - rtk->nx=opt->mode<=PMODE_FIXED?NX(opt):pppnx(opt); - rtk->na=opt->mode<=PMODE_FIXED?NR(opt):pppnx(opt); - rtk->tt=0.0; - rtk->epoch=0; - rtk->x=zeros(rtk->nx,1); - rtk->P=zeros(rtk->nx,rtk->nx); - rtk->xa=zeros(rtk->na,1); - rtk->Pa=zeros(rtk->na,rtk->na); - rtk->nfix=rtk->neb=0; - for (i=0;iambc[i]=ambc0; - rtk->ssat[i]=ssat0; - } - rtk->holdamb=0; - rtk->excsat=0; - rtk->nb_ar=0; - for (i=0;ierrbuf[i]=0; - rtk->opt=*opt; - rtk->initial_mode=rtk->opt.mode; - rtk->sol.thres=(float)opt->thresar[0]; - rtk->intpres_nb=0; + * initialize RTK control struct + * args : rtk_t *rtk IO TKk control/result struct + * prcopt_t *opt I positioning options (see rtklib.h) + * return : none + *-----------------------------------------------------------------------------*/ +extern void rtkinit(rtk_t *rtk, const prcopt_t *opt) { + sol_t sol0 = {{0}}; + ambc_t ambc0 = {{{0}}}; + ssat_t ssat0 = {0}; + int i; + + trace(3, "rtkinit :\n"); + + rtk->sol = sol0; + for (i = 0; i < 6; i++) rtk->rb[i] = 0.0; + rtk->nx = opt->mode <= PMODE_FIXED ? NX(opt) : pppnx(opt); + rtk->na = opt->mode <= PMODE_FIXED ? NR(opt) : pppnx(opt); + rtk->tt = 0.0; + rtk->epoch = 0; + rtk->x = zeros(rtk->nx, 1); + rtk->P = zeros(rtk->nx, rtk->nx); + rtk->xa = zeros(rtk->na, 1); + rtk->Pa = zeros(rtk->na, rtk->na); + rtk->nfix = rtk->neb = 0; + for (i = 0; i < MAXSAT; i++) { + rtk->ambc[i] = ambc0; + rtk->ssat[i] = ssat0; + } + rtk->holdamb = 0; + rtk->excsat = 0; + rtk->nb_ar = 0; + for (i = 0; i < MAXERRMSG; i++) rtk->errbuf[i] = 0; + rtk->opt = *opt; + rtk->initial_mode = rtk->opt.mode; + rtk->sol.thres = (float)opt->thresar[0]; + rtk->intpres_nb = 0; } /* free rtk control ------------------------------------------------------------ -* free memory for rtk control struct -* args : rtk_t *rtk IO rtk control/result struct -* return : none -*-----------------------------------------------------------------------------*/ -extern void rtkfree(rtk_t *rtk) -{ - trace(3,"rtkfree :\n"); - - rtk->nx=rtk->na=0; - free(rtk->x ); rtk->x =NULL; - free(rtk->P ); rtk->P =NULL; - free(rtk->xa); rtk->xa=NULL; - free(rtk->Pa); rtk->Pa=NULL; + * free memory for rtk control struct + * args : rtk_t *rtk IO rtk control/result struct + * return : none + *-----------------------------------------------------------------------------*/ +extern void rtkfree(rtk_t *rtk) { + trace(3, "rtkfree :\n"); + + rtk->nx = rtk->na = 0; + free(rtk->x); + rtk->x = NULL; + free(rtk->P); + rtk->P = NULL; + free(rtk->xa); + rtk->xa = NULL; + free(rtk->Pa); + rtk->Pa = NULL; } /* precise positioning --------------------------------------------------------- -* input observation data and navigation message, compute rover position by -* precise positioning -* args : rtk_t *rtk IO RTK control/result struct -* rtk->sol IO solution -* .time O solution time -* .rr[] IO rover position/velocity -* (I:fixed mode,O:single mode) -* .dtr[0] O receiver clock bias (s) -* .dtr[1-5] O receiver GLO/GAL/BDS/IRN/QZS-GPS time offset (s) -* .Qr[] O rover position covariance -* .stat O solution status (SOLQ_???) -* .ns O number of valid satellites -* .age O age of differential (s) -* .ratio O ratio factor for ambiguity validation -* rtk->rb[] IO base station position/velocity -* (I:relative mode,O:moving-base mode) -* rtk->nx I number of all states -* rtk->na I number of integer states -* rtk->ns O number of valid satellites in use -* rtk->tt O time difference between current and previous (s) -* rtk->x[] IO float states pre-filter and post-filter -* rtk->P[] IO float covariance pre-filter and post-filter -* rtk->xa[] O fixed states after AR -* rtk->Pa[] O fixed covariance after AR -* rtk->ssat[s] IO satellite {s+1} status -* .sys O system (SYS_???) -* .az [r] O azimuth angle (rad) (r=0:rover,1:base) -* .el [r] O elevation angle (rad) (r=0:rover,1:base) -* .vs [r] O data valid single (r=0:rover,1:base) -* .resp [f] O freq(f+1) pseudorange residual (m) -* .resc [f] O freq(f+1) carrier-phase residual (m) -* .vsat [f] O freq(f+1) data valid (0:invalid,1:valid) -* .fix [f] O freq(f+1) ambiguity flag -* (0:nodata,1:float,2:fix,3:hold) -* .slip [f] O freq(f+1) cycle slip flag -* (bit8-7:rcv1 LLI, bit6-5:rcv2 LLI, -* bit2:parity unknown, bit1:slip) -* .lock [f] IO freq(f+1) carrier lock count -* .outc [f] IO freq(f+1) carrier outage count -* .slipc[f] IO freq(f+1) cycle slip count -* .rejc [f] IO freq(f+1) data reject count -* .gf IO geometry-free phase (L1-L2 or L1-L5) (m) -* rtk->nfix IO number of continuous fixes of ambiguity -* rtk->neb IO bytes of error message buffer -* rtk->errbuf IO error message buffer -* rtk->tstr O time string for debug -* rtk->opt I processing options -* obsd_t *obs I observation data for an epoch -* obs[i].rcv=1:rover,2:reference -* sorted by receiver and satellte -* int n I number of observation data -* nav_t *nav I navigation messages -* return : status (0:no solution,1:valid solution) -* notes : before calling function, base station position rtk->sol.rb[] should -* be properly set for relative mode except for moving-baseline -*-----------------------------------------------------------------------------*/ -extern int rtkpos(rtk_t *rtk, const obsd_t *obs, int n, const nav_t *nav) -{ - prcopt_t *opt=&rtk->opt; - sol_t solb={{0}}; - gtime_t time; - int i,nu,nr; - char msg[128]=""; - - char tstr[40]; - trace(3,"rtkpos : time=%s n=%d\n",time2str(obs[0].time,tstr,3),n); - trace(4,"obs=\n"); traceobs(4,obs,n); - /*trace(5,"nav=\n"); tracenav(5,nav);*/ - - /* set base station position */ - if (opt->refpos<=POSOPT_RINEX&&opt->mode!=PMODE_SINGLE&& - opt->mode!=PMODE_MOVEB) { - for (i=0;i<6;i++) rtk->rb[i]=i<3?opt->rb[i]:0.0; - } - /* count rover/base station observations */ - for (nu=0;nu sol.time; /* previous epoch */ - - /* rover position and time by single point positioning, skip if - position variance smaller than threshold */ - if (rtk->P[0]==0||rtk->P[0]>STD_PREC_VAR_THRESH) { - if (!pntpos(obs,nu,nav,&rtk->opt,&rtk->sol,NULL,rtk->ssat,msg)) { - errmsg(rtk,"point pos error (%s)\n",msg); - - if (!rtk->opt.dynamics) { - outsolstat(rtk,nav); - return 0; - } - } - } else rtk->sol.time=obs[0].time; - if (time.time!=0) rtk->tt=timediff(rtk->sol.time,time); - - /* return to static start if long delay without rover data */ - if (fabs(rtk->tt)>300&&rtk->initial_mode==PMODE_STATIC_START) { - rtk->opt.mode=PMODE_STATIC_START; - for (i=0;i<3;i++) initx(rtk,rtk->sol.rr[i],VAR_POS,i); - if (rtk->opt.dynamics) { - for (i=3;i<6;i++) initx(rtk,1E-6,VAR_VEL,i); - for (i=6;i<9;i++) initx(rtk,1E-6,VAR_ACC,i); - } - trace(3,"No data for > 5 min: switch back to static mode:\n"); - } - - /* single point positioning */ - if (opt->mode==PMODE_SINGLE) { - outsolstat(rtk,nav); - return 1; - } - /* suppress output of single solution */ - if (!opt->outsingle) { - rtk->sol.stat=SOLQ_NONE; - } - /* precise point positioning */ - if (opt->mode>=PMODE_PPP_KINEMA) { - pppos(rtk,obs,nu,nav); - outsolstat(rtk,nav); - return 1; - } - /* check number of data of base station */ - if (nr==0) { - errmsg(rtk,"no base station observation data for rtk\n"); - outsolstat(rtk,nav); - return 1; - } - if (opt->mode==PMODE_MOVEB) { /* moving baseline */ - /* estimate position/velocity of base station, - skip if position variance below threshold*/ - if (rtk->P[0]==0||rtk->P[0]>STD_PREC_VAR_THRESH) { - if (!pntpos(obs+nu,nr,nav,&rtk->opt,&solb,NULL,NULL,msg)) { - errmsg(rtk,"base station position error (%s)\n",msg); - return 0; - } - /* if base position uninitialized, use full position */ - if (fabs(rtk->rb[0])<0.1) - for (i=0;i<3;i++) rtk->rb[i]=solb.rr[i]; - /* else filter base position to reduce noise from single precision solution */ - else - for (i=0;i<3;i++) { - rtk->rb[i]=0.95*rtk->rb[i]+0.05*solb.rr[i]; - rtk->rb[i+3]=0; /* set velocity to zero */ - } - } else solb.time=obs[nu].time; - trace(3,"basex= %.3f %.3f\n",rtk->rb[0],solb.rr[0]); - - rtk->sol.age=(float)timediff(rtk->sol.time,solb.time); - - if (fabs(rtk->sol.age)>MIN(TTOL_MOVEB,opt->maxtdiff)) { - errmsg(rtk,"time sync error for moving-base (age=%.1f)\n",rtk->sol.age); - return 0; - } + * input observation data and navigation message, compute rover position by + * precise positioning + * args : rtk_t *rtk IO RTK control/result struct + * rtk->sol IO solution + * .time O solution time + * .rr[] IO rover position/velocity + * (I:fixed mode,O:single mode) + * .dtr[0] O receiver clock bias (s) + * .dtr[1-5] O receiver GLO/GAL/BDS/IRN/QZS-GPS time offset (s) + * .Qr[] O rover position covariance + * .stat O solution status (SOLQ_???) + * .ns O number of valid satellites + * .age O age of differential (s) + * .ratio O ratio factor for ambiguity validation + * rtk->rb[] IO base station position/velocity + * (I:relative mode,O:moving-base mode) + * rtk->nx I number of all states + * rtk->na I number of integer states + * rtk->ns O number of valid satellites in use + * rtk->tt O time difference between current and previous (s) + * rtk->x[] IO float states pre-filter and post-filter + * rtk->P[] IO float covariance pre-filter and post-filter + * rtk->xa[] O fixed states after AR + * rtk->Pa[] O fixed covariance after AR + * rtk->ssat[s] IO satellite {s+1} status + * .sys O system (SYS_???) + * .az [r] O azimuth angle (rad) (r=0:rover,1:base) + * .el [r] O elevation angle (rad) (r=0:rover,1:base) + * .vs [r] O data valid single (r=0:rover,1:base) + * .resp [f] O freq(f+1) pseudorange residual (m) + * .resc [f] O freq(f+1) carrier-phase residual (m) + * .vsat [f] O freq(f+1) data valid (0:invalid,1:valid) + * .fix [f] O freq(f+1) ambiguity flag + * (0:nodata,1:float,2:fix,3:hold) + * .slip [f] O freq(f+1) cycle slip flag + * (bit8-7:rcv1 LLI, bit6-5:rcv2 LLI, + * bit2:parity unknown, bit1:slip) + * .lock [f] IO freq(f+1) carrier lock count + * .outc [f] IO freq(f+1) carrier outage count + * .slipc[f] IO freq(f+1) cycle slip count + * .rejc [f] IO freq(f+1) data reject count + * .gf IO geometry-free phase (L1-L2 or L1-L5) (m) + * rtk->nfix IO number of continuous fixes of ambiguity + * rtk->neb IO bytes of error message buffer + * rtk->errbuf IO error message buffer + * rtk->tstr O time string for debug + * rtk->opt I processing options + * obsd_t *obs I observation data for an epoch + * obs[i].rcv=1:rover,2:reference + * sorted by receiver and satellte + * int n I number of observation data + * nav_t *nav I navigation messages + * return : status (0:no solution,1:valid solution) + * notes : before calling function, base station position rtk->sol.rb[] should + * be properly set for relative mode except for moving-baseline + *-----------------------------------------------------------------------------*/ +extern int rtkpos(rtk_t *rtk, const obsd_t *obs, int n, const nav_t *nav) { + prcopt_t *opt = &rtk->opt; + sol_t solb = {{0}}; + gtime_t time; + int i, nu, nr; + char msg[128] = ""; + + char tstr[40]; + trace(3, "rtkpos : time=%s n=%d\n", time2str(obs[0].time, tstr, 3), n); + trace(4, "obs=\n"); + traceobs(4, obs, n); + /*trace(5,"nav=\n"); tracenav(5,nav);*/ + + /* set base station position */ + if (opt->refpos <= POSOPT_RINEX && opt->mode != PMODE_SINGLE && opt->mode != PMODE_MOVEB) { + for (i = 0; i < 6; i++) rtk->rb[i] = i < 3 ? opt->rb[i] : 0.0; + } + /* count rover/base station observations */ + for (nu = 0; nu < n && obs[nu].rcv == 1; nu++); + for (nr = 0; nu + nr < n && obs[nu + nr].rcv == 2; nr++); + + time = rtk->sol.time; /* previous epoch */ - /* time-synchronized position of base station */ - /* single position velocity solution too noisy to be helpful */ - /*for (i=0;i<3;i++) rtk->rb[i]+=rtk->rb[i+3]*rtk->sol.age; */ + /* rover position and time by single point positioning, skip if + position variance smaller than threshold */ + if (rtk->P[0] == 0 || rtk->P[0] > STD_PREC_VAR_THRESH) { + if (!pntpos(obs, nu, nav, &rtk->opt, &rtk->sol, NULL, rtk->ssat, msg)) { + errmsg(rtk, "point pos error (%s)\n", msg); - trace(3,"base pos: "); tracemat(3,rtk->rb,1,3,13,4); + if (!rtk->opt.dynamics) { + outsolstat(rtk, nav); + return 0; + } } + } else + rtk->sol.time = obs[0].time; + if (time.time != 0) rtk->tt = timediff(rtk->sol.time, time); - /* Relative positioning */ - relpos(rtk,obs,nu,nr,nav); - rtk->epoch++; - outsolstat(rtk,nav); + /* return to static start if long delay without rover data */ + if (fabs(rtk->tt) > 300 && rtk->initial_mode == PMODE_STATIC_START) { + rtk->opt.mode = PMODE_STATIC_START; + for (i = 0; i < 3; i++) initx(rtk, rtk->sol.rr[i], VAR_POS, i); + if (rtk->opt.dynamics) { + for (i = 3; i < 6; i++) initx(rtk, 1E-6, VAR_VEL, i); + for (i = 6; i < 9; i++) initx(rtk, 1E-6, VAR_ACC, i); + } + trace(3, "No data for > 5 min: switch back to static mode:\n"); + } + /* single point positioning */ + if (opt->mode == PMODE_SINGLE) { + outsolstat(rtk, nav); return 1; + } + /* suppress output of single solution */ + if (!opt->outsingle) { + rtk->sol.stat = SOLQ_NONE; + } + /* precise point positioning */ + if (opt->mode >= PMODE_PPP_KINEMA) { + pppos(rtk, obs, nu, nav); + outsolstat(rtk, nav); + return 1; + } + /* check number of data of base station */ + if (nr == 0) { + errmsg(rtk, "no base station observation data for rtk\n"); + outsolstat(rtk, nav); + return 1; + } + if (opt->mode == PMODE_MOVEB) { /* moving baseline */ + /* estimate position/velocity of base station, + skip if position variance below threshold*/ + if (rtk->P[0] == 0 || rtk->P[0] > STD_PREC_VAR_THRESH) { + if (!pntpos(obs + nu, nr, nav, &rtk->opt, &solb, NULL, NULL, msg)) { + errmsg(rtk, "base station position error (%s)\n", msg); + return 0; + } + /* if base position uninitialized, use full position */ + if (fabs(rtk->rb[0]) < 0.1) + for (i = 0; i < 3; i++) rtk->rb[i] = solb.rr[i]; + /* else filter base position to reduce noise from single precision solution */ + else + for (i = 0; i < 3; i++) { + rtk->rb[i] = 0.95 * rtk->rb[i] + 0.05 * solb.rr[i]; + rtk->rb[i + 3] = 0; /* set velocity to zero */ + } + } else + solb.time = obs[nu].time; + trace(3, "basex= %.3f %.3f\n", rtk->rb[0], solb.rr[0]); + + rtk->sol.age = (float)timediff(rtk->sol.time, solb.time); + + if (fabs(rtk->sol.age) > MIN(TTOL_MOVEB, opt->maxtdiff)) { + errmsg(rtk, "time sync error for moving-base (age=%.1f)\n", rtk->sol.age); + return 0; + } + + /* time-synchronized position of base station */ + /* single position velocity solution too noisy to be helpful */ + /*for (i=0;i<3;i++) rtk->rb[i]+=rtk->rb[i+3]*rtk->sol.age; */ + + trace(3, "base pos: "); + tracemat(3, rtk->rb, 1, 3, 13, 4); + } + + /* Relative positioning */ + relpos(rtk, obs, nu, nr, nav); + rtk->epoch++; + outsolstat(rtk, nav); + + return 1; } diff --git a/src/rtksvr.c b/src/rtksvr.c index ac45da1c1..2c23e1f5f 100644 --- a/src/rtksvr.c +++ b/src/rtksvr.c @@ -1,63 +1,62 @@ /*------------------------------------------------------------------------------ -* rtksvr.c : rtk server functions -* -* Copyright (C) 2007-2020 by T.TAKASU, All rights reserved. -* -* options : -DWIN32 use WIN32 API -* -* version : $Revision:$ $Date:$ -* history : 2009/01/07 1.0 new -* 2009/06/02 1.1 support glonass -* 2010/07/25 1.2 support correction input/log stream -* supoort online change of output/log streams -* supoort monitor stream -* added api: -* rtksvropenstr(),rtksvrclosestr() -* changed api: -* rtksvrstart() -* 2010/08/25 1.3 fix problem of ephemeris time inversion (2.4.0_p6) -* 2010/09/08 1.4 fix problem of ephemeris and ssr squence upset -* (2.4.0_p8) -* 2011/01/10 1.5 change api: rtksvrstart(),rtksvrostat() -* 2011/06/21 1.6 fix ephemeris handover problem -* 2012/05/14 1.7 fix bugs -* 2013/03/28 1.8 fix problem on lack of glonass freq number in raw -* fix problem on ephemeris with inverted toe -* add api rtksvrfree() -* 2014/06/28 1.9 fix probram on ephemeris update of beidou -* 2015/04/29 1.10 fix probram on ssr orbit/clock inconsistency -* 2015/07/31 1.11 add phase bias (fcb) correction -* 2015/12/05 1.12 support opt->pppopt=-DIS_FCB -* 2016/07/01 1.13 support averaging single pos as base position -* 2016/07/31 1.14 fix bug on ion/utc parameters input -* 2016/08/20 1.15 support api change of sendnmea() -* 2016/09/18 1.16 fix server-crash with server-cycle > 1000 -* 2016/09/20 1.17 change api rtksvrstart() -* 2016/10/01 1.18 change api rtksvrstart() -* 2016/10/04 1.19 fix problem to send nmea of single solution -* 2016/10/09 1.20 add reset-and-single-sol mode for nmea-request -* 2017/04/11 1.21 add rtkfree() in rtksvrfree() -* 2020/11/30 1.22 add initializing svr->nav in rtksvrinit() -* allocate double size ephemeris in rtksvrinit() -* handle multiple ephemeris sets in updatesvr() -* use API sat2freq() to get carrier frequency -* use integer types in stdint.h -*-----------------------------------------------------------------------------*/ + * rtksvr.c : rtk server functions + * + * Copyright (C) 2007-2020 by T.TAKASU, All rights reserved. + * + * options : -DWIN32 use WIN32 API + * + * version : $Revision:$ $Date:$ + * history : 2009/01/07 1.0 new + * 2009/06/02 1.1 support glonass + * 2010/07/25 1.2 support correction input/log stream + * supoort online change of output/log streams + * supoort monitor stream + * added api: + * rtksvropenstr(),rtksvrclosestr() + * changed api: + * rtksvrstart() + * 2010/08/25 1.3 fix problem of ephemeris time inversion (2.4.0_p6) + * 2010/09/08 1.4 fix problem of ephemeris and ssr squence upset + * (2.4.0_p8) + * 2011/01/10 1.5 change api: rtksvrstart(),rtksvrostat() + * 2011/06/21 1.6 fix ephemeris handover problem + * 2012/05/14 1.7 fix bugs + * 2013/03/28 1.8 fix problem on lack of glonass freq number in raw + * fix problem on ephemeris with inverted toe + * add api rtksvrfree() + * 2014/06/28 1.9 fix probram on ephemeris update of beidou + * 2015/04/29 1.10 fix probram on ssr orbit/clock inconsistency + * 2015/07/31 1.11 add phase bias (fcb) correction + * 2015/12/05 1.12 support opt->pppopt=-DIS_FCB + * 2016/07/01 1.13 support averaging single pos as base position + * 2016/07/31 1.14 fix bug on ion/utc parameters input + * 2016/08/20 1.15 support api change of sendnmea() + * 2016/09/18 1.16 fix server-crash with server-cycle > 1000 + * 2016/09/20 1.17 change api rtksvrstart() + * 2016/10/01 1.18 change api rtksvrstart() + * 2016/10/04 1.19 fix problem to send nmea of single solution + * 2016/10/09 1.20 add reset-and-single-sol mode for nmea-request + * 2017/04/11 1.21 add rtkfree() in rtksvrfree() + * 2020/11/30 1.22 add initializing svr->nav in rtksvrinit() + * allocate double size ephemeris in rtksvrinit() + * handle multiple ephemeris sets in updatesvr() + * use API sat2freq() to get carrier frequency + * use integer types in stdint.h + *-----------------------------------------------------------------------------*/ #include "rtklib.h" -#define MIN_INT_RESET 30000 /* mininum interval of reset command (ms) */ +#define MIN_INT_RESET 30000 /* mininum interval of reset command (ms) */ /* write solution header to output stream ------------------------------------*/ -static void writesolhead(stream_t *stream, const solopt_t *solopt, const prcopt_t *prcopt) -{ - if (solopt->posf == SOLF_NMEA || solopt->posf == SOLF_STAT || solopt->posf==SOLF_GSIF) - return; +static void writesolhead(stream_t *stream, const solopt_t *solopt, const prcopt_t *prcopt) { + if (solopt->posf == SOLF_NMEA || solopt->posf == SOLF_STAT || solopt->posf == SOLF_GSIF) return; uint8_t buff[MAXSOLMSG + 1]; if (solopt->outhead) { if (!*solopt->prog) { - int n = snprintf((char *)buff, sizeof(buff), "%s program : RTKLIB ver.%s %s\n", COMMENTH, VER_RTKLIB, PATCH_LEVEL); + int n = snprintf((char *)buff, sizeof(buff), "%s program : RTKLIB ver.%s %s\n", COMMENTH, + VER_RTKLIB, PATCH_LEVEL); if (n < sizeof(buff)) strwrite(stream, buff, n); } else { int n = snprintf((char *)buff, sizeof(buff), "%s program : %s\n", COMMENTH, solopt->prog); @@ -76,184 +75,168 @@ static void writesolhead(stream_t *stream, const solopt_t *solopt, const prcopt_ } int n = outsolheads(buff, solopt); - strwrite(stream,buff,n); + strwrite(stream, buff, n); } /* save output buffer --------------------------------------------------------*/ // The caller is expected to hold the rtksvr lock. -static void saveoutbuf(rtksvr_t *svr, uint8_t *buff, int n, int index) -{ - n=nbuffsize-svr->nsb[index]?n:svr->buffsize-svr->nsb[index]; - memcpy(svr->sbuf[index]+svr->nsb[index],buff,n); - svr->nsb[index]+=n; +static void saveoutbuf(rtksvr_t *svr, uint8_t *buff, int n, int index) { + n = n < svr->buffsize - svr->nsb[index] ? n : svr->buffsize - svr->nsb[index]; + memcpy(svr->sbuf[index] + svr->nsb[index], buff, n); + svr->nsb[index] += n; } /* write solution to output stream -------------------------------------------*/ -static void writesol(rtksvr_t *svr, int index) -{ - solopt_t solopt=solopt_default; - uint8_t buff[MAXSOLMSG+1]; - int i,n; - - tracet(4,"writesol: index=%d\n",index); - - for (i=0;i<2;i++) { - - if (svr->solopt[i].posf==SOLF_STAT) { - /* output solution status */ - rtksvrlock(svr); - n=rtkoutstat(&svr->rtk,svr->solopt[i].sstat,(char *)buff); - rtksvrunlock(svr); - } - else { - /* output solution */ - n=outsols(buff,&svr->rtk.sol,svr->rtk.rb,svr->solopt+i); - } - strwrite(svr->stream+i+3,buff,n); - - /* save output buffer */ - rtksvrlock(svr); - saveoutbuf(svr,buff,n,i); - rtksvrunlock(svr); - - /* output extended solution */ - n=outsolexs(buff,&svr->rtk.sol,svr->rtk.ssat,svr->solopt+i); - strwrite(svr->stream+i+3,buff,n); - - /* save output buffer */ - rtksvrlock(svr); - saveoutbuf(svr,buff,n,i); - rtksvrunlock(svr); - } - /* output solution to monitor port */ - if (svr->moni) { - n=outsols(buff,&svr->rtk.sol,svr->rtk.rb,&solopt); - strwrite(svr->moni,buff,n); - } - /* save solution buffer */ - if (svr->nsolsolbuf[svr->nsol++]=svr->rtk.sol; - rtksvrunlock(svr); +static void writesol(rtksvr_t *svr, int index) { + solopt_t solopt = solopt_default; + uint8_t buff[MAXSOLMSG + 1]; + int i, n; + + tracet(4, "writesol: index=%d\n", index); + + for (i = 0; i < 2; i++) { + if (svr->solopt[i].posf == SOLF_STAT) { + /* output solution status */ + rtksvrlock(svr); + n = rtkoutstat(&svr->rtk, svr->solopt[i].sstat, (char *)buff); + rtksvrunlock(svr); + } else { + /* output solution */ + n = outsols(buff, &svr->rtk.sol, svr->rtk.rb, svr->solopt + i); } + strwrite(svr->stream + i + 3, buff, n); + + /* save output buffer */ + rtksvrlock(svr); + saveoutbuf(svr, buff, n, i); + rtksvrunlock(svr); + + /* output extended solution */ + n = outsolexs(buff, &svr->rtk.sol, svr->rtk.ssat, svr->solopt + i); + strwrite(svr->stream + i + 3, buff, n); + + /* save output buffer */ + rtksvrlock(svr); + saveoutbuf(svr, buff, n, i); + rtksvrunlock(svr); + } + /* output solution to monitor port */ + if (svr->moni) { + n = outsols(buff, &svr->rtk.sol, svr->rtk.rb, &solopt); + strwrite(svr->moni, buff, n); + } + /* save solution buffer */ + if (svr->nsol < MAXSOLBUF) { + rtksvrlock(svr); + svr->solbuf[svr->nsol++] = svr->rtk.sol; + rtksvrunlock(svr); + } } /* update glonass frequency channel number in raw data struct ----------------*/ -static void update_glofcn(rtksvr_t *svr) -{ - int i,j,sat,frq; - - for (i=0;iraw[j].nav.geph[i].sat!=sat) continue; - frq=svr->raw[j].nav.geph[i].frq; - } - if (frq<-7||frq>6) continue; - - for (j=0;j<3;j++) { - if (svr->raw[j].nav.geph[i].sat==sat) continue; - svr->raw[j].nav.geph[i].sat=sat; - svr->raw[j].nav.geph[i].frq=frq; - } +static void update_glofcn(rtksvr_t *svr) { + int i, j, sat, frq; + + for (i = 0; i < MAXPRNGLO; i++) { + sat = satno(SYS_GLO, i + 1); + + for (j = 0, frq = -999; j < 3; j++) { + if (svr->raw[j].nav.geph[i].sat != sat) continue; + frq = svr->raw[j].nav.geph[i].frq; } + if (frq < -7 || frq > 6) continue; + + for (j = 0; j < 3; j++) { + if (svr->raw[j].nav.geph[i].sat == sat) continue; + svr->raw[j].nav.geph[i].sat = sat; + svr->raw[j].nav.geph[i].frq = frq; + } + } } /* update observation data ---------------------------------------------------*/ -static void update_obs(rtksvr_t *svr, obs_t *obs, int index, int iobs) -{ - int i,n=0,sat,sys; - - if (iobsn;i++) { - sat=obs->data[i].sat; - sys=satsys(sat,NULL); - if (svr->rtk.opt.exsats[sat-1]==1||!(sys&svr->rtk.opt.navsys)) { - continue; - } - svr->obs[index][iobs].data[n]=obs->data[i]; - svr->obs[index][iobs].data[n++].rcv=index+1; - } - svr->obs[index][iobs].n=n; - sortobs(&svr->obs[index][iobs]); - } - svr->nmsg[index][0]++; +static void update_obs(rtksvr_t *svr, obs_t *obs, int index, int iobs) { + int i, n = 0, sat, sys; + + if (iobs < MAXOBSBUF) { + for (i = 0; i < obs->n; i++) { + sat = obs->data[i].sat; + sys = satsys(sat, NULL); + if (svr->rtk.opt.exsats[sat - 1] == 1 || !(sys & svr->rtk.opt.navsys)) { + continue; + } + svr->obs[index][iobs].data[n] = obs->data[i]; + svr->obs[index][iobs].data[n++].rcv = index + 1; } + svr->obs[index][iobs].n = n; + sortobs(&svr->obs[index][iobs]); + } + svr->nmsg[index][0]++; +} /* update ephemeris ----------------------------------------------------------*/ -static void update_eph(rtksvr_t *svr, nav_t *nav, int ephsat, int ephset, - int index) -{ - eph_t *eph1,*eph2,*eph3; - int prn; - - if (satsys(ephsat,&prn)!=SYS_GLO) { - if (!svr->navsel||svr->navsel==index+1) { - /* svr->nav.eph={current_set1,current_set2,prev_set1,prev_set2} */ - eph1=nav->eph+ephsat-1+MAXSAT*ephset; /* received */ - eph2=svr->nav.eph+ephsat-1+MAXSAT*ephset; /* current */ - eph3=svr->nav.eph+ephsat-1+MAXSAT*(2+ephset); /* previous */ - if (eph2->ttr.time==0|| - (eph1->iode!=eph3->iode&&eph1->iode!=eph2->iode)|| - (timediff(eph1->toe,eph3->toe)!=0.0&& - timediff(eph1->toe,eph2->toe)!=0.0)|| - (timediff(eph1->toc,eph3->toc)!=0.0&& - timediff(eph1->toc,eph2->toc)!=0.0)) { - *eph3=*eph2; /* current ->previous */ - *eph2=*eph1; /* received->current */ - } - } - svr->nmsg[index][1]++; - } - else { - if (!svr->navsel||svr->navsel==index+1) { - geph_t *geph1,*geph2,*geph3; - geph1=nav->geph+prn-1; - geph2=svr->nav.geph+prn-1; - geph3=svr->nav.geph+prn-1+MAXPRNGLO; - if (geph2->tof.time==0|| - (geph1->iode!=geph3->iode&&geph1->iode!=geph2->iode)) { - *geph3=*geph2; - *geph2=*geph1; - update_glofcn(svr); - } - } - svr->nmsg[index][6]++; +static void update_eph(rtksvr_t *svr, nav_t *nav, int ephsat, int ephset, int index) { + eph_t *eph1, *eph2, *eph3; + int prn; + + if (satsys(ephsat, &prn) != SYS_GLO) { + if (!svr->navsel || svr->navsel == index + 1) { + /* svr->nav.eph={current_set1,current_set2,prev_set1,prev_set2} */ + eph1 = nav->eph + ephsat - 1 + MAXSAT * ephset; /* received */ + eph2 = svr->nav.eph + ephsat - 1 + MAXSAT * ephset; /* current */ + eph3 = svr->nav.eph + ephsat - 1 + MAXSAT * (2 + ephset); /* previous */ + if (eph2->ttr.time == 0 || (eph1->iode != eph3->iode && eph1->iode != eph2->iode) || + (timediff(eph1->toe, eph3->toe) != 0.0 && timediff(eph1->toe, eph2->toe) != 0.0) || + (timediff(eph1->toc, eph3->toc) != 0.0 && timediff(eph1->toc, eph2->toc) != 0.0)) { + *eph3 = *eph2; /* current ->previous */ + *eph2 = *eph1; /* received->current */ + } + } + svr->nmsg[index][1]++; + } else { + if (!svr->navsel || svr->navsel == index + 1) { + geph_t *geph1, *geph2, *geph3; + geph1 = nav->geph + prn - 1; + geph2 = svr->nav.geph + prn - 1; + geph3 = svr->nav.geph + prn - 1 + MAXPRNGLO; + if (geph2->tof.time == 0 || (geph1->iode != geph3->iode && geph1->iode != geph2->iode)) { + *geph3 = *geph2; + *geph2 = *geph1; + update_glofcn(svr); + } } + svr->nmsg[index][6]++; + } } /* update sbas message -------------------------------------------------------*/ -static void update_sbs(rtksvr_t *svr, sbsmsg_t *sbsmsg, int index) -{ - int i,sbssat=svr->rtk.opt.sbassatsel; - - if (sbsmsg&&(sbssat==sbsmsg->prn||sbssat==0)) { - sbsmsg->rcv=index+1; - if (svr->nsbssbsmsg[svr->nsbs++]=*sbsmsg; - } - else { - for (i=0;isbsmsg[i]=svr->sbsmsg[i+1]; - svr->sbsmsg[i]=*sbsmsg; - } - sbsupdatecorr(sbsmsg,&svr->nav); - } - svr->nmsg[index][3]++; +static void update_sbs(rtksvr_t *svr, sbsmsg_t *sbsmsg, int index) { + int i, sbssat = svr->rtk.opt.sbassatsel; + + if (sbsmsg && (sbssat == sbsmsg->prn || sbssat == 0)) { + sbsmsg->rcv = index + 1; + if (svr->nsbs < MAXSBSMSG) { + svr->sbsmsg[svr->nsbs++] = *sbsmsg; + } else { + for (i = 0; i < MAXSBSMSG - 1; i++) svr->sbsmsg[i] = svr->sbsmsg[i + 1]; + svr->sbsmsg[i] = *sbsmsg; } + sbsupdatecorr(sbsmsg, &svr->nav); + } + svr->nmsg[index][3]++; +} /* update ion/utc parameters -------------------------------------------------*/ -static void update_ionutc(rtksvr_t *svr, nav_t *nav, int index) -{ - if (svr->navsel==0||svr->navsel==index+1) { - matcpy(svr->nav.utc_gps,nav->utc_gps,8,1); - matcpy(svr->nav.utc_glo,nav->utc_glo,8,1); - matcpy(svr->nav.utc_gal,nav->utc_gal,8,1); - matcpy(svr->nav.utc_qzs,nav->utc_qzs,8,1); - matcpy(svr->nav.utc_cmp,nav->utc_cmp,8,1); - matcpy(svr->nav.utc_irn,nav->utc_irn,9,1); - matcpy(svr->nav.utc_sbs,nav->utc_sbs,4,1); - matcpy(svr->nav.ion_gps,nav->ion_gps,8,1); - matcpy(svr->nav.ion_gal,nav->ion_gal,4,1); - matcpy(svr->nav.ion_qzs,nav->ion_qzs,8,1); - matcpy(svr->nav.ion_cmp,nav->ion_cmp,8,1); - matcpy(svr->nav.ion_irn,nav->ion_irn,8,1); - } - svr->nmsg[index][2]++; - } +static void update_ionutc(rtksvr_t *svr, nav_t *nav, int index) { + if (svr->navsel == 0 || svr->navsel == index + 1) { + matcpy(svr->nav.utc_gps, nav->utc_gps, 8, 1); + matcpy(svr->nav.utc_glo, nav->utc_glo, 8, 1); + matcpy(svr->nav.utc_gal, nav->utc_gal, 8, 1); + matcpy(svr->nav.utc_qzs, nav->utc_qzs, 8, 1); + matcpy(svr->nav.utc_cmp, nav->utc_cmp, 8, 1); + matcpy(svr->nav.utc_irn, nav->utc_irn, 9, 1); + matcpy(svr->nav.utc_sbs, nav->utc_sbs, 4, 1); + matcpy(svr->nav.ion_gps, nav->ion_gps, 8, 1); + matcpy(svr->nav.ion_gal, nav->ion_gal, 4, 1); + matcpy(svr->nav.ion_qzs, nav->ion_qzs, 8, 1); + matcpy(svr->nav.ion_cmp, nav->ion_cmp, 8, 1); + matcpy(svr->nav.ion_irn, nav->ion_irn, 8, 1); + } + svr->nmsg[index][2]++; +} // Update antenna position --------------------------------------------------- static void update_antpos(rtksvr_t *svr, int index) { sta_t *sta; @@ -265,13 +248,15 @@ static void update_antpos(rtksvr_t *svr, int index) { if (index == 1 && svr->rtk.opt.refpos == POSOPT_RTCM) { // Update base station position. for (int i = 0; i < 3; i++) svr->rtk.rb[i] = sta->pos[i]; - tracet(2, "updated antenna index=%d position to %.4f %.4f %.4f\n", index, svr->rtk.rb[0], svr->rtk.rb[1], svr->rtk.rb[2]); + tracet(2, "updated antenna index=%d position to %.4f %.4f %.4f\n", index, svr->rtk.rb[0], + svr->rtk.rb[1], svr->rtk.rb[2]); } if (index == 0 && svr->rtk.opt.rovpos == POSOPT_RTCM && (svr->rtk.opt.mode == PMODE_FIXED || svr->rtk.opt.mode == PMODE_PPP_FIXED)) { // Update rover fixed position. for (int i = 0; i < 3; i++) svr->rtk.opt.ru[i] = sta->pos[i]; - tracet(2, "updated antenna index=%d position to %.4f %.4f %.4f\n", index, svr->rtk.rb[0], svr->rtk.rb[1], svr->rtk.rb[2]); + tracet(2, "updated antenna index=%d position to %.4f %.4f %.4f\n", index, svr->rtk.rb[0], + svr->rtk.rb[1], svr->rtk.rb[2]); } // Antenna type and delta. These are updated independently of the antenna @@ -305,316 +290,297 @@ static void update_antpos(rtksvr_t *svr, int index) { svr->rtk.opt.antdel[index][2] += sta->hgt; } tracet(2, "updated antenna index=%d delta to %.4f %.4f %.4f\n", index, - svr->rtk.opt.antdel[index][0], svr->rtk.opt.antdel[index][1], svr->rtk.opt.antdel[index][2]); + svr->rtk.opt.antdel[index][0], svr->rtk.opt.antdel[index][1], + svr->rtk.opt.antdel[index][2]); } svr->nmsg[index][4]++; } /* update ssr corrections ----------------------------------------------------*/ -static void update_ssr(rtksvr_t *svr, int index) -{ - int i,sys,prn,iode; - - for (i=0;irtcm[index].ssr[i].update) continue; - - /* check consistency between iods of orbit and clock */ - if (svr->rtcm[index].ssr[i].iod[0]!=svr->rtcm[index].ssr[i].iod[1]) { - continue; - } - svr->rtcm[index].ssr[i].update=0; - - iode=svr->rtcm[index].ssr[i].iode; - sys=satsys(i+1,&prn); - - /* check corresponding ephemeris exists */ - if (sys==SYS_GPS||sys==SYS_GAL||sys==SYS_QZS) { - if (svr->nav.eph[i ].iode!=iode&& - svr->nav.eph[i+MAXSAT].iode!=iode) { - continue; - } - } - else if (sys==SYS_GLO) { - if (svr->nav.geph[prn-1 ].iode!=iode&& - svr->nav.geph[prn-1+MAXPRNGLO].iode!=iode) { - continue; - } - } - svr->nav.ssr[i]=svr->rtcm[index].ssr[i]; - } - svr->nmsg[index][7]++; - } -/* update rtk server struct --------------------------------------------------*/ -static void update_svr(rtksvr_t *svr, int ret, obs_t *obs, nav_t *nav, - int ephsat, int ephset, sbsmsg_t *sbsmsg, int index, - int iobs) -{ - tracet(4,"updatesvr: ret=%d ephsat=%d ephset=%d index=%d\n",ret,ephsat, - ephset,index); - - if (ret==1) { /* observation data */ - update_obs(svr,obs,index,iobs); - } - else if (ret==2) { /* ephemeris */ - update_eph(svr,nav,ephsat,ephset,index); - } - else if (ret==3) { /* sbas message */ - update_sbs(svr,sbsmsg,index); - } - else if (ret==9) { /* ion/utc parameters */ - update_ionutc(svr,nav,index); - } - else if (ret==5) { /* antenna position */ - update_antpos(svr,index); - } - else if (ret==7) { /* dgps correction */ - svr->nmsg[index][5]++; - } - else if (ret==10) { /* ssr message */ - update_ssr(svr,index); +static void update_ssr(rtksvr_t *svr, int index) { + int i, sys, prn, iode; + + for (i = 0; i < MAXSAT; i++) { + if (!svr->rtcm[index].ssr[i].update) continue; + + /* check consistency between iods of orbit and clock */ + if (svr->rtcm[index].ssr[i].iod[0] != svr->rtcm[index].ssr[i].iod[1]) { + continue; } - else if (ret==-1) { /* error */ - svr->nmsg[index][9]++; + svr->rtcm[index].ssr[i].update = 0; + + iode = svr->rtcm[index].ssr[i].iode; + sys = satsys(i + 1, &prn); + + /* check corresponding ephemeris exists */ + if (sys == SYS_GPS || sys == SYS_GAL || sys == SYS_QZS) { + if (svr->nav.eph[i].iode != iode && svr->nav.eph[i + MAXSAT].iode != iode) { + continue; + } + } else if (sys == SYS_GLO) { + if (svr->nav.geph[prn - 1].iode != iode && svr->nav.geph[prn - 1 + MAXPRNGLO].iode != iode) { + continue; + } } + svr->nav.ssr[i] = svr->rtcm[index].ssr[i]; + } + svr->nmsg[index][7]++; +} +/* update rtk server struct --------------------------------------------------*/ +static void update_svr(rtksvr_t *svr, int ret, obs_t *obs, nav_t *nav, int ephsat, int ephset, + sbsmsg_t *sbsmsg, int index, int iobs) { + tracet(4, "updatesvr: ret=%d ephsat=%d ephset=%d index=%d\n", ret, ephsat, ephset, index); + + if (ret == 1) { /* observation data */ + update_obs(svr, obs, index, iobs); + } else if (ret == 2) { /* ephemeris */ + update_eph(svr, nav, ephsat, ephset, index); + } else if (ret == 3) { /* sbas message */ + update_sbs(svr, sbsmsg, index); + } else if (ret == 9) { /* ion/utc parameters */ + update_ionutc(svr, nav, index); + } else if (ret == 5) { /* antenna position */ + update_antpos(svr, index); + } else if (ret == 7) { /* dgps correction */ + svr->nmsg[index][5]++; + } else if (ret == 10) { /* ssr message */ + update_ssr(svr, index); + } else if (ret == -1) { /* error */ + svr->nmsg[index][9]++; + } } /* decode receiver raw/rtcm data ---------------------------------------------*/ -static int decoderaw(rtksvr_t *svr, int index) -{ - obs_t *obs; - nav_t *nav; - sbsmsg_t *sbsmsg=NULL; - int i,ret,ephsat,ephset,fobs=0; - - tracet(4,"decoderaw: index=%d\n",index); - - rtksvrlock(svr); - - for (i=0;inb[index];i++) { - - /* input rtcm/receiver raw data from stream */ - if (svr->format[index]==STRFMT_RTCM2) { - ret=input_rtcm2(svr->rtcm+index,svr->buff[index][i]); - obs=&svr->rtcm[index].obs; - nav=&svr->rtcm[index].nav; - ephsat=svr->rtcm[index].ephsat; - ephset=svr->rtcm[index].ephset; - } - else if (svr->format[index]==STRFMT_RTCM3) { - ret=input_rtcm3(svr->rtcm+index,svr->buff[index][i]); - if (svr->rtcm[index].nbyte_invalid!=0) { /* If last message had error: */ - i-=svr->rtcm[index].nbyte_invalid-1; /* rewind to last preamble+1 */ - i=i>=0?i:0; /* or beginning of buffer */ - trace(4,"rewind buff %3d bytes, i=%d\n",svr->rtcm[index].nbyte_invalid-1,i); - svr->rtcm[index].nbyte_invalid=0; - } - obs=&svr->rtcm[index].obs; - nav=&svr->rtcm[index].nav; - ephsat=svr->rtcm[index].ephsat; - ephset=svr->rtcm[index].ephset; - } - else { - ret=input_raw(svr->raw+index,svr->format[index],svr->buff[index][i]); - obs=&svr->raw[index].obs; - nav=&svr->raw[index].nav; - ephsat=svr->raw[index].ephsat; - ephset=svr->raw[index].ephset; - sbsmsg=&svr->raw[index].sbsmsg; - } +static int decoderaw(rtksvr_t *svr, int index) { + obs_t *obs; + nav_t *nav; + sbsmsg_t *sbsmsg = NULL; + int i, ret, ephsat, ephset, fobs = 0; + + tracet(4, "decoderaw: index=%d\n", index); + + rtksvrlock(svr); + + for (i = 0; i < svr->nb[index]; i++) { + /* input rtcm/receiver raw data from stream */ + if (svr->format[index] == STRFMT_RTCM2) { + ret = input_rtcm2(svr->rtcm + index, svr->buff[index][i]); + obs = &svr->rtcm[index].obs; + nav = &svr->rtcm[index].nav; + ephsat = svr->rtcm[index].ephsat; + ephset = svr->rtcm[index].ephset; + } else if (svr->format[index] == STRFMT_RTCM3) { + ret = input_rtcm3(svr->rtcm + index, svr->buff[index][i]); + if (svr->rtcm[index].nbyte_invalid != 0) { /* If last message had error: */ + i -= svr->rtcm[index].nbyte_invalid - 1; /* rewind to last preamble+1 */ + i = i >= 0 ? i : 0; /* or beginning of buffer */ + trace(4, "rewind buff %3d bytes, i=%d\n", svr->rtcm[index].nbyte_invalid - 1, i); + svr->rtcm[index].nbyte_invalid = 0; + } + obs = &svr->rtcm[index].obs; + nav = &svr->rtcm[index].nav; + ephsat = svr->rtcm[index].ephsat; + ephset = svr->rtcm[index].ephset; + } else { + ret = input_raw(svr->raw + index, svr->format[index], svr->buff[index][i]); + obs = &svr->raw[index].obs; + nav = &svr->raw[index].nav; + ephsat = svr->raw[index].ephsat; + ephset = svr->raw[index].ephset; + sbsmsg = &svr->raw[index].sbsmsg; + } #ifdef RTK_DISABLED /* record for receiving tick for debug */ - if (ret==1) { - char tstr[40]; - trace(0,"%d %10d T=%s NS=%2d\n",index,tickget(), - time2str(obs->data[0].time,tstr,0),obs->n); - } + if (ret == 1) { + char tstr[40]; + trace(0, "%d %10d T=%s NS=%2d\n", index, tickget(), time2str(obs->data[0].time, tstr, 0), + obs->n); + } #endif - /* update rtk server */ - if (ret>0) { - update_svr(svr,ret,obs,nav,ephsat,ephset,sbsmsg,index,fobs); - } - /* observation data received */ - if (ret==1) { - if (fobsprcout++; - } + /* update rtk server */ + if (ret > 0) { + update_svr(svr, ret, obs, nav, ephsat, ephset, sbsmsg, index, fobs); } - svr->nb[index]=0; - - rtksvrunlock(svr); - - return fobs; + /* observation data received */ + if (ret == 1) { + if (fobs < MAXOBSBUF) + fobs++; + else + svr->prcout++; + } + } + svr->nb[index] = 0; + + rtksvrunlock(svr); + + return fobs; } /* decode download file ------------------------------------------------------*/ -static void decodefile(rtksvr_t *svr, int index) -{ - tracet(4,"decodefile: index=%d\n",index); +static void decodefile(rtksvr_t *svr, int index) { + tracet(4, "decodefile: index=%d\n", index); + + nav_t *nav = (nav_t *)calloc(1, sizeof(nav_t)); + if (nav == NULL) { + trace(1, "decodefile: nav alloc failed\n"); + return; + } + + rtksvrlock(svr); - nav_t *nav = (nav_t *)calloc(1, sizeof(nav_t)); - if (nav == NULL) { - trace(1, "decodefile: nav alloc failed\n"); + /* check file path completed */ + int nb = svr->nb[index]; + if (nb <= 2 || svr->buff[index][nb - 2] != '\r' || svr->buff[index][nb - 1] != '\n') { + rtksvrunlock(svr); + free(nav); + return; + } + char file[1024]; + strncpy(file, (char *)svr->buff[index], nb - 2); + file[nb - 2] = '\0'; + svr->nb[index] = 0; + + rtksvrunlock(svr); + + if (svr->format[index] == STRFMT_SP3) { /* precise ephemeris */ + + /* read sp3 precise ephemeris */ + readsp3(file, nav, 0); + if (nav->ne <= 0) { + tracet(1, "sp3 file read error: %s\n", file); + free(nav); return; } - + /* update precise ephemeris */ rtksvrlock(svr); - - /* check file path completed */ - int nb = svr->nb[index]; - if (nb<=2|| - svr->buff[index][nb-2]!='\r'||svr->buff[index][nb-1]!='\n') { - rtksvrunlock(svr); - free(nav); - return; - } - char file[1024]; - strncpy(file,(char *)svr->buff[index],nb-2); file[nb-2]='\0'; - svr->nb[index]=0; - + + if (svr->nav.peph) free(svr->nav.peph); + svr->nav.ne = nav->ne; + svr->nav.nemax = nav->nemax; + svr->nav.peph = nav->peph; + svr->ftime[index] = utc2gpst(timeget()); + strcpy(svr->files[index], file); + rtksvrunlock(svr); - - if (svr->format[index]==STRFMT_SP3) { /* precise ephemeris */ - - /* read sp3 precise ephemeris */ - readsp3(file,nav,0); - if (nav->ne<=0) { - tracet(1,"sp3 file read error: %s\n",file); - free(nav); - return; - } - /* update precise ephemeris */ - rtksvrlock(svr); - - if (svr->nav.peph) free(svr->nav.peph); - svr->nav.ne = nav->ne; - svr->nav.nemax = nav->nemax; - svr->nav.peph=nav->peph; - svr->ftime[index]=utc2gpst(timeget()); - strcpy(svr->files[index],file); - - rtksvrunlock(svr); - } - else if (svr->format[index]==STRFMT_RNXCLK) { /* precise clock */ - - /* read rinex clock */ - if (readrnxc(file,nav)<=0) { - tracet(1,"rinex clock file read error: %s\n",file); - free(nav); - return; - } - /* update precise clock */ - rtksvrlock(svr); - - if (svr->nav.pclk) free(svr->nav.pclk); - svr->nav.nc = nav->nc; - svr->nav.ncmax = nav->ncmax; - svr->nav.pclk=nav->pclk; - svr->ftime[index]=utc2gpst(timeget()); - strcpy(svr->files[index],file); - - rtksvrunlock(svr); + } else if (svr->format[index] == STRFMT_RNXCLK) { /* precise clock */ + + /* read rinex clock */ + if (readrnxc(file, nav) <= 0) { + tracet(1, "rinex clock file read error: %s\n", file); + free(nav); + return; } - free(nav); + /* update precise clock */ + rtksvrlock(svr); + + if (svr->nav.pclk) free(svr->nav.pclk); + svr->nav.nc = nav->nc; + svr->nav.ncmax = nav->ncmax; + svr->nav.pclk = nav->pclk; + svr->ftime[index] = utc2gpst(timeget()); + strcpy(svr->files[index], file); + + rtksvrunlock(svr); + } + free(nav); } /* carrier-phase bias (fcb) correction ---------------------------------------*/ -static void corr_phase_bias(obsd_t *obs, int n, const nav_t *nav) -{ - double freq; - uint8_t code; - int i,j; - - for (i=0;issr[obs[i].sat-1].pbias[code-1]*freq/CLIGHT; +static void corr_phase_bias(obsd_t *obs, int n, const nav_t *nav) { + double freq; + uint8_t code; + int i, j; + + for (i = 0; i < n; i++) + for (j = 0; j < NFREQ; j++) { + code = obs[i].code[j]; + if ((freq = sat2freq(obs[i].sat, code, nav)) == 0.0) continue; + + /* correct phase bias (cyc) */ + obs[i].L[j] -= nav->ssr[obs[i].sat - 1].pbias[code - 1] * freq / CLIGHT; } } /* periodic command ----------------------------------------------------------*/ -static void periodic_cmd(int cycle, const char *cmd, stream_t *stream) -{ - const char *p=cmd,*q; - char msg[1024],*r; - int n,period; - - for (p=cmd;;p=q+1) { - for (q=p;;q++) if (*q=='\r'||*q=='\n'||*q=='\0') break; - n=(int)(q-p); strncpy(msg,p,n); msg[n]='\0'; - - period=0; - if ((r=strrchr(msg,'#'))) { - sscanf(r,"# %d",&period); - *r='\0'; - while (*--r==' ') *r='\0'; /* delete tail spaces */ - } - if (period<=0) period=1000; - if (*msg&&cycle%period==0) { - strsendcmd(stream,msg); - } - if (!*q) break; +static void periodic_cmd(int cycle, const char *cmd, stream_t *stream) { + const char *p = cmd, *q; + char msg[1024], *r; + int n, period; + + for (p = cmd;; p = q + 1) { + for (q = p;; q++) + if (*q == '\r' || *q == '\n' || *q == '\0') break; + n = (int)(q - p); + strncpy(msg, p, n); + msg[n] = '\0'; + + period = 0; + if ((r = strrchr(msg, '#'))) { + sscanf(r, "# %d", &period); + *r = '\0'; + while (*--r == ' ') *r = '\0'; /* delete tail spaces */ } + if (period <= 0) period = 1000; + if (*msg && cycle % period == 0) { + strsendcmd(stream, msg); + } + if (!*q) break; + } } /* baseline length -----------------------------------------------------------*/ -static double baseline_len(const rtk_t *rtk) -{ - double dr[3]; - int i; +static double baseline_len(const rtk_t *rtk) { + double dr[3]; + int i; - if (norm(rtk->sol.rr,3)<=0.0||norm(rtk->rb,3)<=0.0) return 0.0; + if (norm(rtk->sol.rr, 3) <= 0.0 || norm(rtk->rb, 3) <= 0.0) return 0.0; - for (i=0;i<3;i++) { - dr[i]=rtk->sol.rr[i]-rtk->rb[i]; - } - return norm(dr,3)*0.001; /* (km) */ + for (i = 0; i < 3; i++) { + dr[i] = rtk->sol.rr[i] - rtk->rb[i]; + } + return norm(dr, 3) * 0.001; /* (km) */ } /* send nmea request to base/nrtk input stream -------------------------------*/ -static void send_nmea(rtksvr_t *svr, uint32_t *tickreset) -{ - sol_t sol_nmea={{0}}; - double vel,bl; - uint32_t tick=tickget(); - int i; - - if (svr->stream[1].state!=1) return; - sol_nmea.ns=10; /* Some servers don't like when ns = 0 */ - - if (svr->nmeareq==1) { /* lat-lon-hgt mode */ - sol_nmea.stat=SOLQ_SINGLE; - sol_nmea.time=utc2gpst(timeget()); - matcpy(sol_nmea.rr,svr->nmeapos,3,1); - strsendnmea(svr->stream+1,&sol_nmea); - } - else if (svr->nmeareq==2) { /* single-solution mode */ - if (norm(svr->rtk.sol.rr,3)<=0.0) return; - sol_nmea.stat=SOLQ_SINGLE; - sol_nmea.time=utc2gpst(timeget()); - matcpy(sol_nmea.rr,svr->rtk.sol.rr,3,1); - strsendnmea(svr->stream+1,&sol_nmea); +static void send_nmea(rtksvr_t *svr, uint32_t *tickreset) { + sol_t sol_nmea = {{0}}; + double vel, bl; + uint32_t tick = tickget(); + int i; + + if (svr->stream[1].state != 1) return; + sol_nmea.ns = 10; /* Some servers don't like when ns = 0 */ + + if (svr->nmeareq == 1) { /* lat-lon-hgt mode */ + sol_nmea.stat = SOLQ_SINGLE; + sol_nmea.time = utc2gpst(timeget()); + matcpy(sol_nmea.rr, svr->nmeapos, 3, 1); + strsendnmea(svr->stream + 1, &sol_nmea); + } else if (svr->nmeareq == 2) { /* single-solution mode */ + if (norm(svr->rtk.sol.rr, 3) <= 0.0) return; + sol_nmea.stat = SOLQ_SINGLE; + sol_nmea.time = utc2gpst(timeget()); + matcpy(sol_nmea.rr, svr->rtk.sol.rr, 3, 1); + strsendnmea(svr->stream + 1, &sol_nmea); + } else if (svr->nmeareq == 3) { /* reset-and-single-sol mode */ + + /* send reset command if baseline over threshold */ + bl = baseline_len(&svr->rtk); + if (bl >= svr->bl_reset && (int)(tick - *tickreset) > MIN_INT_RESET) { + strsendcmd(svr->stream + 1, svr->cmd_reset); + + tracet(2, "send reset: bl=%.3f rr=%.3f %.3f %.3f rb=%.3f %.3f %.3f\n", bl, svr->rtk.sol.rr[0], + svr->rtk.sol.rr[1], svr->rtk.sol.rr[2], svr->rtk.rb[0], svr->rtk.rb[1], + svr->rtk.rb[2]); + *tickreset = tick; } - else if (svr->nmeareq==3) { /* reset-and-single-sol mode */ - - /* send reset command if baseline over threshold */ - bl=baseline_len(&svr->rtk); - if (bl>=svr->bl_reset&&(int)(tick-*tickreset)>MIN_INT_RESET) { - strsendcmd(svr->stream+1,svr->cmd_reset); - - tracet(2,"send reset: bl=%.3f rr=%.3f %.3f %.3f rb=%.3f %.3f %.3f\n", - bl,svr->rtk.sol.rr[0],svr->rtk.sol.rr[1],svr->rtk.sol.rr[2], - svr->rtk.rb[0],svr->rtk.rb[1],svr->rtk.rb[2]); - *tickreset=tick; - } - if (norm(svr->rtk.sol.rr,3)<=0.0) return; - sol_nmea.stat=SOLQ_SINGLE; - sol_nmea.time=utc2gpst(timeget()); - matcpy(sol_nmea.rr,svr->rtk.sol.rr,3,1); - - /* set predicted position if velocity > 36km/h */ - if ((vel=norm(svr->rtk.sol.rr+3,3))>10.0) { - for (i=0;i<3;i++) { - sol_nmea.rr[i]+=svr->rtk.sol.rr[i+3]/vel*svr->bl_reset*0.8; - } - } - strsendnmea(svr->stream+1,&sol_nmea); + if (norm(svr->rtk.sol.rr, 3) <= 0.0) return; + sol_nmea.stat = SOLQ_SINGLE; + sol_nmea.time = utc2gpst(timeget()); + matcpy(sol_nmea.rr, svr->rtk.sol.rr, 3, 1); - tracet(3,"send nmea: rr=%.3f %.3f %.3f\n",sol_nmea.rr[0],sol_nmea.rr[1], - sol_nmea.rr[2]); + /* set predicted position if velocity > 36km/h */ + if ((vel = norm(svr->rtk.sol.rr + 3, 3)) > 10.0) { + for (i = 0; i < 3; i++) { + sol_nmea.rr[i] += svr->rtk.sol.rr[i + 3] / vel * svr->bl_reset * 0.8; + } } + strsendnmea(svr->stream + 1, &sol_nmea); + + tracet(3, "send nmea: rr=%.3f %.3f %.3f\n", sol_nmea.rr[0], sol_nmea.rr[1], sol_nmea.rr[2]); + } } /* rtk server thread ---------------------------------------------------------*/ #ifdef WIN32 @@ -623,625 +589,613 @@ static DWORD WINAPI rtksvrthread(void *arg) static void *rtksvrthread(void *arg) #endif { - rtksvr_t *svr=(rtksvr_t *)arg; - obs_t obs; - sol_t sol={{0}}; - double tt; - uint32_t tick,ticknmea,tick1hz,tickreset; - uint8_t *p,*q; - char msg[128]; - int i,j,n,cycle,cputime; - - tracet(3,"rtksvrthread:\n"); - - obsd_t *data = (obsd_t *)calloc(MAXOBS * 2, sizeof(obsd_t)); - if (data == NULL) { - trace(1, "rtksvrthread: obsd_t alloc failed\n"); - return 0; + rtksvr_t *svr = (rtksvr_t *)arg; + obs_t obs; + sol_t sol = {{0}}; + double tt; + uint32_t tick, ticknmea, tick1hz, tickreset; + uint8_t *p, *q; + char msg[128]; + int i, j, n, cycle, cputime; + + tracet(3, "rtksvrthread:\n"); + + obsd_t *data = (obsd_t *)calloc(MAXOBS * 2, sizeof(obsd_t)); + if (data == NULL) { + trace(1, "rtksvrthread: obsd_t alloc failed\n"); + return 0; + } + obs.data = data; + obs.n = 0; + obs.nmax = MAXOBS * 2; + + svr->state = 1; + svr->tick = tickget(); + ticknmea = tick1hz = svr->tick - 1000; + tickreset = svr->tick - MIN_INT_RESET; + + for (cycle = 0; svr->state; cycle++) { + tick = tickget(); + for (i = 0; i < 3; i++) { + p = svr->buff[i] + svr->nb[i]; + q = svr->buff[i] + svr->buffsize; + + /* read receiver raw/rtcm data from input stream */ + if ((n = strread(svr->stream + i, p, q - p)) <= 0) { + continue; + } + /* write receiver raw/rtcm data to log stream */ + strwrite(svr->stream + i + 5, p, n); + svr->nb[i] += n; + + /* save peek buffer */ + rtksvrlock(svr); + n = n < svr->buffsize - svr->npb[i] ? n : svr->buffsize - svr->npb[i]; + memcpy(svr->pbuf[i] + svr->npb[i], p, n); + svr->npb[i] += n; + rtksvrunlock(svr); } - obs.data = data; - obs.n = 0; - obs.nmax = MAXOBS * 2; - - svr->state=1; - svr->tick=tickget(); - ticknmea=tick1hz=svr->tick-1000; - tickreset=svr->tick-MIN_INT_RESET; - - for (cycle=0;svr->state;cycle++) { - tick=tickget(); - for (i=0;i<3;i++) { - p=svr->buff[i]+svr->nb[i]; q=svr->buff[i]+svr->buffsize; - - /* read receiver raw/rtcm data from input stream */ - if ((n=strread(svr->stream+i,p,q-p))<=0) { - continue; - } - /* write receiver raw/rtcm data to log stream */ - strwrite(svr->stream+i+5,p,n); - svr->nb[i]+=n; - - /* save peek buffer */ - rtksvrlock(svr); - n=nbuffsize-svr->npb[i]?n:svr->buffsize-svr->npb[i]; - memcpy(svr->pbuf[i]+svr->npb[i],p,n); - svr->npb[i]+=n; - rtksvrunlock(svr); - } - int fobs[3]={0}; - for (i=0;i<3;i++) { - if (svr->format[i]==STRFMT_SP3||svr->format[i]==STRFMT_RNXCLK) { - /* decode download file */ - decodefile(svr,i); - } - else { - /* decode receiver raw/rtcm data */ - fobs[i]=decoderaw(svr,i); - if (1==i&&svr->rtcm[1].staid>0) sol.refstationid=svr->rtcm[1].staid; - } - } - /* averaging single base pos */ - if (fobs[1]>0&&svr->rtk.opt.refpos==POSOPT_SINGLE) { - if ((svr->rtk.opt.maxaveep<=0||svr->navertk.opt.maxaveep)&& - pntpos(svr->obs[1][0].data,svr->obs[1][0].n,&svr->nav, - &svr->rtk.opt,&sol,NULL,NULL,msg)) { - svr->nave++; - for (i=0;i<3;i++) { - svr->rb_ave[i]+=(sol.rr[i]-svr->rb_ave[i])/svr->nave; - } - } - for (i=0;i<3;i++) svr->rtk.opt.rb[i]=svr->rb_ave[i]; - } - for (i=0;iobs[0][i].n&&obs.nobs[0][i].data[j]; - } - for (j=0;jobs[1][0].n&&obs.nobs[1][0].data[j]; - } - /* carrier phase bias correction */ - if (!strstr(svr->rtk.opt.pppopt,"-DIS_FCB")) { - corr_phase_bias(obs.data,obs.n,&svr->nav); - } - /* rtk positioning */ - rtksvrlock(svr); - rtkpos(&svr->rtk,obs.data,obs.n,&svr->nav); - rtksvrunlock(svr); - - if (svr->rtk.sol.stat!=SOLQ_NONE) { - - /* adjust current time */ - tt=(int)(tickget()-tick)/1000.0+DTTOL; - timeset(gpst2utc(timeadd(svr->rtk.sol.time,tt))); - - /* write solution */ - writesol(svr,i); - } - /* if cpu overload, increment obs outage counter and break */ - if ((int)(tickget()-tick)>=svr->cycle) { - svr->prcout+=fobs[0]-i-1; - } - } - /* send null solution if no solution (1hz) */ - if (svr->rtk.sol.stat==SOLQ_NONE&&(int)(tick-tick1hz)>=1000) { - writesol(svr,0); - tick1hz=tick; - } - /* write periodic command to input stream */ - for (i=0;i<3;i++) { - periodic_cmd(cycle*svr->cycle,svr->cmds_periodic[i],svr->stream+i); - } - /* send nmea request to base/nrtk input stream */ - if (svr->nmeacycle>0&&(int)(tick-ticknmea)>=svr->nmeacycle) { - send_nmea(svr,&tickreset); - ticknmea=tick; + int fobs[3] = {0}; + for (i = 0; i < 3; i++) { + if (svr->format[i] == STRFMT_SP3 || svr->format[i] == STRFMT_RNXCLK) { + /* decode download file */ + decodefile(svr, i); + } else { + /* decode receiver raw/rtcm data */ + fobs[i] = decoderaw(svr, i); + if (1 == i && svr->rtcm[1].staid > 0) sol.refstationid = svr->rtcm[1].staid; + } + } + /* averaging single base pos */ + if (fobs[1] > 0 && svr->rtk.opt.refpos == POSOPT_SINGLE) { + if ((svr->rtk.opt.maxaveep <= 0 || svr->nave < svr->rtk.opt.maxaveep) && + pntpos(svr->obs[1][0].data, svr->obs[1][0].n, &svr->nav, &svr->rtk.opt, &sol, NULL, NULL, + msg)) { + svr->nave++; + for (i = 0; i < 3; i++) { + svr->rb_ave[i] += (sol.rr[i] - svr->rb_ave[i]) / svr->nave; } - if ((cputime=(int)(tickget()-tick))>0) svr->cputime=cputime; - - /* sleep until next cycle */ - sleepms(svr->cycle-cputime); + } + for (i = 0; i < 3; i++) svr->rtk.opt.rb[i] = svr->rb_ave[i]; } - free(data); - for (i=0;istream+i); - for (i=0;i<3;i++) { - svr->nb[i]=svr->npb[i]=0; - free(svr->buff[i]); svr->buff[i]=NULL; - free(svr->pbuf[i]); svr->pbuf[i]=NULL; - free_raw (svr->raw +i); - free_rtcm(svr->rtcm+i); + for (i = 0; i < fobs[0]; i++) { /* for each rover observation data */ + obs.n = 0; + for (j = 0; j < svr->obs[0][i].n && obs.n < MAXOBS * 2; j++) { + obs.data[obs.n++] = svr->obs[0][i].data[j]; + } + for (j = 0; j < svr->obs[1][0].n && obs.n < MAXOBS * 2; j++) { + obs.data[obs.n++] = svr->obs[1][0].data[j]; + } + /* carrier phase bias correction */ + if (!strstr(svr->rtk.opt.pppopt, "-DIS_FCB")) { + corr_phase_bias(obs.data, obs.n, &svr->nav); + } + /* rtk positioning */ + rtksvrlock(svr); + rtkpos(&svr->rtk, obs.data, obs.n, &svr->nav); + rtksvrunlock(svr); + + if (svr->rtk.sol.stat != SOLQ_NONE) { + /* adjust current time */ + tt = (int)(tickget() - tick) / 1000.0 + DTTOL; + timeset(gpst2utc(timeadd(svr->rtk.sol.time, tt))); + + /* write solution */ + writesol(svr, i); + } + /* if cpu overload, increment obs outage counter and break */ + if ((int)(tickget() - tick) >= svr->cycle) { + svr->prcout += fobs[0] - i - 1; + } } - for (i=0;i<2;i++) { - svr->nsb[i]=0; - free(svr->sbuf[i]); svr->sbuf[i]=NULL; + /* send null solution if no solution (1hz) */ + if (svr->rtk.sol.stat == SOLQ_NONE && (int)(tick - tick1hz) >= 1000) { + writesol(svr, 0); + tick1hz = tick; } - return 0; + /* write periodic command to input stream */ + for (i = 0; i < 3; i++) { + periodic_cmd(cycle * svr->cycle, svr->cmds_periodic[i], svr->stream + i); + } + /* send nmea request to base/nrtk input stream */ + if (svr->nmeacycle > 0 && (int)(tick - ticknmea) >= svr->nmeacycle) { + send_nmea(svr, &tickreset); + ticknmea = tick; + } + if ((cputime = (int)(tickget() - tick)) > 0) svr->cputime = cputime; + + /* sleep until next cycle */ + sleepms(svr->cycle - cputime); + } + free(data); + for (i = 0; i < MAXSTRRTK; i++) strclose(svr->stream + i); + for (i = 0; i < 3; i++) { + svr->nb[i] = svr->npb[i] = 0; + free(svr->buff[i]); + svr->buff[i] = NULL; + free(svr->pbuf[i]); + svr->pbuf[i] = NULL; + free_raw(svr->raw + i); + free_rtcm(svr->rtcm + i); + } + for (i = 0; i < 2; i++) { + svr->nsb[i] = 0; + free(svr->sbuf[i]); + svr->sbuf[i] = NULL; + } + return 0; } /* initialize rtk server ------------------------------------------------------- -* initialize rtk server -* args : rtksvr_t *svr IO rtk server -* return : status (0:error,1:ok) -*-----------------------------------------------------------------------------*/ -extern int rtksvrinit(rtksvr_t *svr) -{ - gtime_t time0={0}; - sol_t sol0 ={{0}}; - eph_t eph0 ={0,-1,-1}; - seph_t seph0={0}; - int i,j; - - tracet(3,"rtksvrinit:\n"); - - svr->state=svr->cycle=svr->nmeacycle=svr->nmeareq=0; - for (i=0;i<3;i++) svr->nmeapos[i]=0.0; - svr->buffsize=0; - for (i=0;i<3;i++) svr->format[i]=0; - for (i=0;i<2;i++) svr->solopt[i]=solopt_default; - svr->navsel=svr->nsbs=svr->nsol=0; - rtkinit(&svr->rtk,&prcopt_default); - for (i=0;i<3;i++) svr->nb[i]=0; - for (i=0;i<2;i++) svr->nsb[i]=0; - for (i=0;i<3;i++) svr->npb[i]=0; - for (i=0;i<3;i++) svr->buff[i]=NULL; - for (i=0;i<2;i++) svr->sbuf[i]=NULL; - for (i=0;i<3;i++) svr->pbuf[i]=NULL; - for (i=0;isolbuf[i]=sol0; - for (i=0;i<3;i++) for (j=0;j<10;j++) svr->nmsg[i][j]=0; - for (i=0;i<3;i++) svr->ftime[i]=time0; - for (i=0;i<3;i++) svr->files[i][0]='\0'; - svr->moni=NULL; - svr->tick=0; - svr->thread=0; - svr->cputime=svr->prcout=svr->nave=0; - for (i=0;i<3;i++) svr->rb_ave[i]=0.0; - - memset(&svr->nav,0,sizeof(nav_t)); - memset(&svr->obs,0,sizeof(svr->obs)); - if (!(svr->nav.eph =(eph_t *)malloc(sizeof(eph_t )*MAXSAT*4 ))|| - !(svr->nav.seph=(seph_t *)malloc(sizeof(seph_t)*NSATSBS*2))) { - tracet(1,"rtksvrinit: malloc error\n"); - rtksvrfree(svr); - return 0; + * initialize rtk server + * args : rtksvr_t *svr IO rtk server + * return : status (0:error,1:ok) + *-----------------------------------------------------------------------------*/ +extern int rtksvrinit(rtksvr_t *svr) { + gtime_t time0 = {0}; + sol_t sol0 = {{0}}; + eph_t eph0 = {0, -1, -1}; + seph_t seph0 = {0}; + int i, j; + + tracet(3, "rtksvrinit:\n"); + + svr->state = svr->cycle = svr->nmeacycle = svr->nmeareq = 0; + for (i = 0; i < 3; i++) svr->nmeapos[i] = 0.0; + svr->buffsize = 0; + for (i = 0; i < 3; i++) svr->format[i] = 0; + for (i = 0; i < 2; i++) svr->solopt[i] = solopt_default; + svr->navsel = svr->nsbs = svr->nsol = 0; + rtkinit(&svr->rtk, &prcopt_default); + for (i = 0; i < 3; i++) svr->nb[i] = 0; + for (i = 0; i < 2; i++) svr->nsb[i] = 0; + for (i = 0; i < 3; i++) svr->npb[i] = 0; + for (i = 0; i < 3; i++) svr->buff[i] = NULL; + for (i = 0; i < 2; i++) svr->sbuf[i] = NULL; + for (i = 0; i < 3; i++) svr->pbuf[i] = NULL; + for (i = 0; i < MAXSOLBUF; i++) svr->solbuf[i] = sol0; + for (i = 0; i < 3; i++) + for (j = 0; j < 10; j++) svr->nmsg[i][j] = 0; + for (i = 0; i < 3; i++) svr->ftime[i] = time0; + for (i = 0; i < 3; i++) svr->files[i][0] = '\0'; + svr->moni = NULL; + svr->tick = 0; + svr->thread = 0; + svr->cputime = svr->prcout = svr->nave = 0; + for (i = 0; i < 3; i++) svr->rb_ave[i] = 0.0; + + memset(&svr->nav, 0, sizeof(nav_t)); + memset(&svr->obs, 0, sizeof(svr->obs)); + if (!(svr->nav.eph = (eph_t *)malloc(sizeof(eph_t) * MAXSAT * 4)) || + !(svr->nav.seph = (seph_t *)malloc(sizeof(seph_t) * NSATSBS * 2))) { + tracet(1, "rtksvrinit: malloc error\n"); + rtksvrfree(svr); + return 0; + } + for (i = 0; i < MAXSAT * 4; i++) svr->nav.eph[i] = eph0; + for (i = 0; i < NSATSBS * 2; i++) svr->nav.seph[i] = seph0; + svr->nav.n = svr->nav.nmax = MAXSAT * 4; + svr->nav.ns = svr->nav.nsmax = NSATSBS * 2; + + if (MAXPRNGLO > 0) { + svr->nav.geph = (geph_t *)malloc(sizeof(geph_t) * MAXPRNGLO * 2); + if (svr->nav.geph == NULL) { + tracet(1, "rtksvrinit: malloc error\n"); + rtksvrfree(svr); + return 0; } - for (i=0;inav.eph [i]=eph0; - for (i=0;inav.seph[i]=seph0; - svr->nav.n =svr->nav.nmax =MAXSAT *4; - svr->nav.ns=svr->nav.nsmax=NSATSBS*2; - - if (MAXPRNGLO > 0) { - svr->nav.geph = (geph_t *)malloc(sizeof(geph_t) * MAXPRNGLO * 2); - if (svr->nav.geph == NULL) { - tracet(1,"rtksvrinit: malloc error\n"); + geph_t geph0 = {0, -1}; + for (i = 0; i < MAXPRNGLO * 2; i++) svr->nav.geph[i] = geph0; + } + svr->nav.ng = svr->nav.ngmax = MAXPRNGLO * 2; + + for (i = 0; i < 3; i++) + for (j = 0; j < MAXOBSBUF; j++) { + if (!(svr->obs[i][j].data = (obsd_t *)malloc(sizeof(obsd_t) * MAXOBS))) { + tracet(1, "rtksvrinit: malloc error\n"); rtksvrfree(svr); return 0; } - geph_t geph0 = {0,-1}; - for (i = 0; i < MAXPRNGLO * 2; i++) svr->nav.geph[i] = geph0; } - svr->nav.ng = svr->nav.ngmax = MAXPRNGLO * 2; + for (i = 0; i < 3; i++) { + memset(svr->raw + i, 0, sizeof(raw_t)); + memset(svr->rtcm + i, 0, sizeof(rtcm_t)); + } + for (i = 0; i < MAXSTRRTK; i++) strinit(svr->stream + i); - for (i=0;i<3;i++) for (j=0;jobs[i][j].data=(obsd_t *)malloc(sizeof(obsd_t)*MAXOBS))) { - tracet(1,"rtksvrinit: malloc error\n"); - rtksvrfree(svr); - return 0; - } - } - for (i=0;i<3;i++) { - memset(svr->raw +i,0,sizeof(raw_t )); - memset(svr->rtcm+i,0,sizeof(rtcm_t)); - } - for (i=0;istream+i); - - for (i=0;i<3;i++) *svr->cmds_periodic[i]='\0'; - *svr->cmd_reset='\0'; - svr->bl_reset=10.0; - rtklib_initlock(&svr->lock); - - return 1; + for (i = 0; i < 3; i++) *svr->cmds_periodic[i] = '\0'; + *svr->cmd_reset = '\0'; + svr->bl_reset = 10.0; + rtklib_initlock(&svr->lock); + + return 1; } /* free rtk server ------------------------------------------------------------- -* free rtk server -* args : rtksvr_t *svr IO rtk server -* return : none -*-----------------------------------------------------------------------------*/ -extern void rtksvrfree(rtksvr_t *svr) -{ - int i,j; - - free(svr->nav.eph ); - free(svr->nav.geph); - free(svr->nav.seph); - for (i=0;i<3;i++) for (j=0;jobs[i][j].data); + * free rtk server + * args : rtksvr_t *svr IO rtk server + * return : none + *-----------------------------------------------------------------------------*/ +extern void rtksvrfree(rtksvr_t *svr) { + int i, j; + + free(svr->nav.eph); + free(svr->nav.geph); + free(svr->nav.seph); + for (i = 0; i < 3; i++) + for (j = 0; j < MAXOBSBUF; j++) { + free(svr->obs[i][j].data); } - rtkfree(&svr->rtk); + rtkfree(&svr->rtk); } /* lock/unlock rtk server ------------------------------------------------------ -* lock/unlock rtk server -* args : rtksvr_t *svr IO rtk server -* return : status (1:ok 0:error) -*-----------------------------------------------------------------------------*/ -extern void rtksvrlock (rtksvr_t *svr) {rtklib_lock (&svr->lock);} -extern void rtksvrunlock(rtksvr_t *svr) {rtklib_unlock(&svr->lock);} + * lock/unlock rtk server + * args : rtksvr_t *svr IO rtk server + * return : status (1:ok 0:error) + *-----------------------------------------------------------------------------*/ +extern void rtksvrlock(rtksvr_t *svr) { rtklib_lock(&svr->lock); } +extern void rtksvrunlock(rtksvr_t *svr) { rtklib_unlock(&svr->lock); } /* start rtk server ------------------------------------------------------------ -* start rtk server thread -* args : rtksvr_t *svr IO rtk server -* int cycle I server cycle (ms) -* int buffsize I input buffer size (bytes) -* int *strs I stream types (STR_???) -* types[0]=input stream rover -* types[1]=input stream base station -* types[2]=input stream correction -* types[3]=output stream solution 1 -* types[4]=output stream solution 2 -* types[5]=log stream rover -* types[6]=log stream base station -* types[7]=log stream correction -* char *paths I input stream paths -* int *format I input stream formats (STRFMT_???) -* format[0]=input stream rover -* format[1]=input stream base station -* format[2]=input stream correction -* int navsel I navigation message select -* (0:rover,1:base,2:ephem,3:all) -* char **cmds I input stream start commands -* cmds[0]=input stream rover (NULL: no command) -* cmds[1]=input stream base (NULL: no command) -* cmds[2]=input stream corr (NULL: no command) -* char **cmds_periodic I input stream periodic commands -* cmds[0]=input stream rover (NULL: no command) -* cmds[1]=input stream base (NULL: no command) -* cmds[2]=input stream corr (NULL: no command) -* char **rcvopts I receiver options -* rcvopt[0]=receiver option rover -* rcvopt[1]=receiver option base -* rcvopt[2]=receiver option corr -* int nmeacycle I nmea request cycle (ms) (0:no request) -* int nmeareq I nmea request type -* (0:no,1:base pos,2:single sol,3:reset and single) -* double *nmeapos I transmitted nmea position (ecef) (m) -* prcopt_t *prcopt I rtk processing options -* solopt_t *solopt I solution options -* solopt[0]=solution 1 options -* solopt[1]=solution 2 options -* stream_t *moni I monitor stream (NULL: not used) -* char *errmsg O error message -* return : status (1:ok 0:error) -*-----------------------------------------------------------------------------*/ -extern int rtksvrstart(rtksvr_t *svr, int cycle, int buffsize, int *strs, - const char **paths, int *formats, int navsel, const char **cmds, - const char **cmds_periodic, const char **rcvopts, int nmeacycle, - int nmeareq, const double *nmeapos, prcopt_t *prcopt, - solopt_t *solopt, stream_t *moni, char *errmsg) -{ - gtime_t time,time0={0}; - int i,j,rw; - - tracet(3,"rtksvrstart: cycle=%d buffsize=%d navsel=%d nmeacycle=%d nmeareq=%d\n", - cycle,buffsize,navsel,nmeacycle,nmeareq); - - if (svr->state) { - sprintf(errmsg,"server already started"); - return 0; - } - strinitcom(); - svr->cycle=cycle>1?cycle:1; - svr->nmeacycle=nmeacycle>1000?nmeacycle:1000; - svr->nmeareq=nmeareq; - for (i=0;i<3;i++) svr->nmeapos[i]=nmeapos[i]; - svr->buffsize=buffsize>4096?buffsize:4096; - for (i=0;i<3;i++) svr->format[i]=formats[i]; - svr->navsel=navsel; - svr->nsbs=0; - svr->nsol=0; - svr->prcout=0; - rtkfree(&svr->rtk); - rtkinit(&svr->rtk,prcopt); - - if (prcopt->initrst) { /* init averaging pos by restart */ - svr->nave=0; - for (i=0;i<3;i++) svr->rb_ave[i]=0.0; - } - for (i=0;i<3;i++) { /* input/log streams */ - svr->nb[i]=svr->npb[i]=0; - if (!(svr->buff[i]=(uint8_t *)malloc(buffsize))|| - !(svr->pbuf[i]=(uint8_t *)malloc(buffsize))) { - tracet(1,"rtksvrstart: malloc error\n"); - sprintf(errmsg,"rtk server malloc error"); - return 0; - } - for (j=0;j<10;j++) svr->nmsg[i][j]=0; - for (j=0;jobs[i][j].n=0; - strcpy(svr->cmds_periodic[i],!cmds_periodic[i]?"":cmds_periodic[i]); - - /* initialize receiver raw and rtcm control */ - init_raw(svr->raw+i,formats[i]); - init_rtcm(svr->rtcm+i); - - /* set receiver and rtcm option */ - strcpy(svr->raw [i].opt,rcvopts[i]); - strcpy(svr->rtcm[i].opt,rcvopts[i]); - - /* connect dgps corrections */ - svr->rtcm[i].dgps=svr->nav.dgps; - } - for (i=0;i<2;i++) { /* output peek buffer */ - if (!(svr->sbuf[i]=(uint8_t *)malloc(buffsize))) { - tracet(1,"rtksvrstart: malloc error\n"); - sprintf(errmsg,"rtk server malloc error"); - return 0; - } - } - /* set solution options */ - for (i=0;i<2;i++) { - svr->solopt[i]=solopt[i]; + * start rtk server thread + * args : rtksvr_t *svr IO rtk server + * int cycle I server cycle (ms) + * int buffsize I input buffer size (bytes) + * int *strs I stream types (STR_???) + * types[0]=input stream rover + * types[1]=input stream base station + * types[2]=input stream correction + * types[3]=output stream solution 1 + * types[4]=output stream solution 2 + * types[5]=log stream rover + * types[6]=log stream base station + * types[7]=log stream correction + * char *paths I input stream paths + * int *format I input stream formats (STRFMT_???) + * format[0]=input stream rover + * format[1]=input stream base station + * format[2]=input stream correction + * int navsel I navigation message select + * (0:rover,1:base,2:ephem,3:all) + * char **cmds I input stream start commands + * cmds[0]=input stream rover (NULL: no command) + * cmds[1]=input stream base (NULL: no command) + * cmds[2]=input stream corr (NULL: no command) + * char **cmds_periodic I input stream periodic commands + * cmds[0]=input stream rover (NULL: no command) + * cmds[1]=input stream base (NULL: no command) + * cmds[2]=input stream corr (NULL: no command) + * char **rcvopts I receiver options + * rcvopt[0]=receiver option rover + * rcvopt[1]=receiver option base + * rcvopt[2]=receiver option corr + * int nmeacycle I nmea request cycle (ms) (0:no request) + * int nmeareq I nmea request type + * (0:no,1:base pos,2:single sol,3:reset and single) + * double *nmeapos I transmitted nmea position (ecef) (m) + * prcopt_t *prcopt I rtk processing options + * solopt_t *solopt I solution options + * solopt[0]=solution 1 options + * solopt[1]=solution 2 options + * stream_t *moni I monitor stream (NULL: not used) + * char *errmsg O error message + * return : status (1:ok 0:error) + *-----------------------------------------------------------------------------*/ +extern int rtksvrstart(rtksvr_t *svr, int cycle, int buffsize, int *strs, const char **paths, + int *formats, int navsel, const char **cmds, const char **cmds_periodic, + const char **rcvopts, int nmeacycle, int nmeareq, const double *nmeapos, + prcopt_t *prcopt, solopt_t *solopt, stream_t *moni, char *errmsg) { + gtime_t time, time0 = {0}; + int i, j, rw; + + tracet(3, "rtksvrstart: cycle=%d buffsize=%d navsel=%d nmeacycle=%d nmeareq=%d\n", cycle, + buffsize, navsel, nmeacycle, nmeareq); + + if (svr->state) { + sprintf(errmsg, "server already started"); + return 0; + } + strinitcom(); + svr->cycle = cycle > 1 ? cycle : 1; + svr->nmeacycle = nmeacycle > 1000 ? nmeacycle : 1000; + svr->nmeareq = nmeareq; + for (i = 0; i < 3; i++) svr->nmeapos[i] = nmeapos[i]; + svr->buffsize = buffsize > 4096 ? buffsize : 4096; + for (i = 0; i < 3; i++) svr->format[i] = formats[i]; + svr->navsel = navsel; + svr->nsbs = 0; + svr->nsol = 0; + svr->prcout = 0; + rtkfree(&svr->rtk); + rtkinit(&svr->rtk, prcopt); + + if (prcopt->initrst) { /* init averaging pos by restart */ + svr->nave = 0; + for (i = 0; i < 3; i++) svr->rb_ave[i] = 0.0; + } + for (i = 0; i < 3; i++) { /* input/log streams */ + svr->nb[i] = svr->npb[i] = 0; + if (!(svr->buff[i] = (uint8_t *)malloc(buffsize)) || + !(svr->pbuf[i] = (uint8_t *)malloc(buffsize))) { + tracet(1, "rtksvrstart: malloc error\n"); + sprintf(errmsg, "rtk server malloc error"); + return 0; } - /* set base station position */ - if (prcopt->refpos!=POSOPT_SINGLE) { - for (i=0;i<6;i++) { - svr->rtk.rb[i]=i<3?prcopt->rb[i]:0.0; - } + for (j = 0; j < 10; j++) svr->nmsg[i][j] = 0; + for (j = 0; j < MAXOBSBUF; j++) svr->obs[i][j].n = 0; + strcpy(svr->cmds_periodic[i], !cmds_periodic[i] ? "" : cmds_periodic[i]); + + /* initialize receiver raw and rtcm control */ + init_raw(svr->raw + i, formats[i]); + init_rtcm(svr->rtcm + i); + + /* set receiver and rtcm option */ + strcpy(svr->raw[i].opt, rcvopts[i]); + strcpy(svr->rtcm[i].opt, rcvopts[i]); + + /* connect dgps corrections */ + svr->rtcm[i].dgps = svr->nav.dgps; + } + for (i = 0; i < 2; i++) { /* output peek buffer */ + if (!(svr->sbuf[i] = (uint8_t *)malloc(buffsize))) { + tracet(1, "rtksvrstart: malloc error\n"); + sprintf(errmsg, "rtk server malloc error"); + return 0; } - /* update navigation data */ - for (i=0;inav.eph [i].ttr=time0; - for (i=0;inav.geph[i].tof=time0; - for (i=0;inav.seph[i].tof=time0; - - /* set monitor stream */ - svr->moni=moni; - - /* open input streams */ - for (i=0;i<8;i++) { - rw=i<3?STR_MODE_R:STR_MODE_W; - if (strs[i]!=STR_FILE) rw|=STR_MODE_W; - if (!stropen(svr->stream+i,strs[i],rw,paths[i])) { - sprintf(errmsg,"str%d open error path=%s",i+1,paths[i]); - for (i--;i>=0;i--) strclose(svr->stream+i); - return 0; - } - /* set initial time for rtcm and raw */ - if (i<3) { - time=utc2gpst(timeget()); - svr->raw [i].time=strs[i]==STR_FILE?strgettime(svr->stream+i):time; - svr->rtcm[i].time=strs[i]==STR_FILE?strgettime(svr->stream+i):time; - } + } + /* set solution options */ + for (i = 0; i < 2; i++) { + svr->solopt[i] = solopt[i]; + } + /* set base station position */ + if (prcopt->refpos != POSOPT_SINGLE) { + for (i = 0; i < 6; i++) { + svr->rtk.rb[i] = i < 3 ? prcopt->rb[i] : 0.0; } - /* sync input streams */ - strsync(svr->stream,svr->stream+1); - strsync(svr->stream,svr->stream+2); - - /* write start commands to input streams */ - for (i=0;i<3;i++) { - if (!cmds[i]) continue; - strwrite(svr->stream+i,(unsigned char *)"",0); /* for connect */ - sleepms(100); - strsendcmd(svr->stream+i,cmds[i]); + } + /* update navigation data */ + for (i = 0; i < MAXSAT * 4; i++) svr->nav.eph[i].ttr = time0; + for (i = 0; i < MAXPRNGLO * 2; i++) svr->nav.geph[i].tof = time0; + for (i = 0; i < NSATSBS * 2; i++) svr->nav.seph[i].tof = time0; + + /* set monitor stream */ + svr->moni = moni; + + /* open input streams */ + for (i = 0; i < 8; i++) { + rw = i < 3 ? STR_MODE_R : STR_MODE_W; + if (strs[i] != STR_FILE) rw |= STR_MODE_W; + if (!stropen(svr->stream + i, strs[i], rw, paths[i])) { + sprintf(errmsg, "str%d open error path=%s", i + 1, paths[i]); + for (i--; i >= 0; i--) strclose(svr->stream + i); + return 0; } - /* write solution header to solution streams */ - for (i=3;i<5;i++) { - writesolhead(svr->stream+i,svr->solopt+(i-3), prcopt); + /* set initial time for rtcm and raw */ + if (i < 3) { + time = utc2gpst(timeget()); + svr->raw[i].time = strs[i] == STR_FILE ? strgettime(svr->stream + i) : time; + svr->rtcm[i].time = strs[i] == STR_FILE ? strgettime(svr->stream + i) : time; } - /* create rtk server thread */ + } + /* sync input streams */ + strsync(svr->stream, svr->stream + 1); + strsync(svr->stream, svr->stream + 2); + + /* write start commands to input streams */ + for (i = 0; i < 3; i++) { + if (!cmds[i]) continue; + strwrite(svr->stream + i, (unsigned char *)"", 0); /* for connect */ + sleepms(100); + strsendcmd(svr->stream + i, cmds[i]); + } + /* write solution header to solution streams */ + for (i = 3; i < 5; i++) { + writesolhead(svr->stream + i, svr->solopt + (i - 3), prcopt); + } + /* create rtk server thread */ #ifdef WIN32 - if (!(svr->thread=CreateThread(NULL,0,rtksvrthread,svr,0,NULL))) { + if (!(svr->thread = CreateThread(NULL, 0, rtksvrthread, svr, 0, NULL))) { #else - if (pthread_create(&svr->thread,NULL,rtksvrthread,svr)) { + if (pthread_create(&svr->thread, NULL, rtksvrthread, svr)) { #endif - for (i=0;istream+i); - sprintf(errmsg,"thread create error\n"); - return 0; - } - return 1; + for (i = 0; i < MAXSTRRTK; i++) strclose(svr->stream + i); + sprintf(errmsg, "thread create error\n"); + return 0; + } + return 1; } /* stop rtk server ------------------------------------------------------------- -* start rtk server thread -* args : rtksvr_t *svr IO rtk server -* char **cmds I input stream stop commands -* cmds[0]=input stream rover (NULL: no command) -* cmds[1]=input stream base (NULL: no command) -* cmds[2]=input stream ephem (NULL: no command) -* return : none -*-----------------------------------------------------------------------------*/ -extern void rtksvrstop(rtksvr_t *svr, const char **cmds) -{ - int i; - - tracet(3,"rtksvrstop:\n"); - - /* write stop commands to input streams */ - rtksvrlock(svr); - for (i=0;i<3;i++) { - if (cmds[i]) strsendcmd(svr->stream+i,cmds[i]); - } - rtksvrunlock(svr); - - /* stop rtk server */ - svr->state=0; - - /* free rtk server thread */ + * start rtk server thread + * args : rtksvr_t *svr IO rtk server + * char **cmds I input stream stop commands + * cmds[0]=input stream rover (NULL: no command) + * cmds[1]=input stream base (NULL: no command) + * cmds[2]=input stream ephem (NULL: no command) + * return : none + *-----------------------------------------------------------------------------*/ +extern void rtksvrstop(rtksvr_t *svr, const char **cmds) { + int i; + + tracet(3, "rtksvrstop:\n"); + + /* write stop commands to input streams */ + rtksvrlock(svr); + for (i = 0; i < 3; i++) { + if (cmds[i]) strsendcmd(svr->stream + i, cmds[i]); + } + rtksvrunlock(svr); + + /* stop rtk server */ + svr->state = 0; + + /* free rtk server thread */ #ifdef WIN32 - WaitForSingleObject(svr->thread,10000); - CloseHandle(svr->thread); + WaitForSingleObject(svr->thread, 10000); + CloseHandle(svr->thread); #else - pthread_join(svr->thread,NULL); + pthread_join(svr->thread, NULL); #endif } /* open output/log stream ------------------------------------------------------ -* open output/log stream -* args : rtksvr_t *svr IO rtk server -* int index I output/log stream index -* (3:solution 1,4:solution 2,5:log rover, -* 6:log base station,7:log correction) -* int str I output/log stream types (STR_???) -* char *path I output/log stream path -* solopt_t *solopt I solution options -* return : status (1:ok 0:error) -*-----------------------------------------------------------------------------*/ + * open output/log stream + * args : rtksvr_t *svr IO rtk server + * int index I output/log stream index + * (3:solution 1,4:solution 2,5:log rover, + * 6:log base station,7:log correction) + * int str I output/log stream types (STR_???) + * char *path I output/log stream path + * solopt_t *solopt I solution options + * return : status (1:ok 0:error) + *-----------------------------------------------------------------------------*/ extern int rtksvropenstr(rtksvr_t *svr, int index, int str, const char *path, - const solopt_t *solopt, const prcopt_t *prcopt) -{ - tracet(3,"rtksvropenstr: index=%d str=%d path=%s\n",index,str,path); - - if (index<3||index>7||!svr->state) return 0; - - rtksvrlock(svr); - - if (svr->stream[index].state>0) { - rtksvrunlock(svr); - return 0; - } - if (!stropen(svr->stream+index,str,STR_MODE_W,path)) { - tracet(2,"stream open error: index=%d\n",index); - rtksvrunlock(svr); - return 0; - } - if (index<=4) { - svr->solopt[index-3]=*solopt; - - /* write solution header to solution stream */ - writesolhead(svr->stream+index,svr->solopt+(index-3),prcopt); - } + const solopt_t *solopt, const prcopt_t *prcopt) { + tracet(3, "rtksvropenstr: index=%d str=%d path=%s\n", index, str, path); + + if (index < 3 || index > 7 || !svr->state) return 0; + + rtksvrlock(svr); + + if (svr->stream[index].state > 0) { rtksvrunlock(svr); - return 1; + return 0; + } + if (!stropen(svr->stream + index, str, STR_MODE_W, path)) { + tracet(2, "stream open error: index=%d\n", index); + rtksvrunlock(svr); + return 0; + } + if (index <= 4) { + svr->solopt[index - 3] = *solopt; + + /* write solution header to solution stream */ + writesolhead(svr->stream + index, svr->solopt + (index - 3), prcopt); + } + rtksvrunlock(svr); + return 1; } /* close output/log stream ----------------------------------------------------- -* close output/log stream -* args : rtksvr_t *svr IO rtk server -* int index I output/log stream index -* (3:solution 1,4:solution 2,5:log rover, -* 6:log base station,7:log correction) -* return : none -*-----------------------------------------------------------------------------*/ -extern void rtksvrclosestr(rtksvr_t *svr, int index) -{ - tracet(3,"rtksvrclosestr: index=%d\n",index); - - if (index<3||index>7||!svr->state) return; - - rtksvrlock(svr); - - strclose(svr->stream+index); - - rtksvrunlock(svr); + * close output/log stream + * args : rtksvr_t *svr IO rtk server + * int index I output/log stream index + * (3:solution 1,4:solution 2,5:log rover, + * 6:log base station,7:log correction) + * return : none + *-----------------------------------------------------------------------------*/ +extern void rtksvrclosestr(rtksvr_t *svr, int index) { + tracet(3, "rtksvrclosestr: index=%d\n", index); + + if (index < 3 || index > 7 || !svr->state) return; + + rtksvrlock(svr); + + strclose(svr->stream + index); + + rtksvrunlock(svr); } /* get observation data status ------------------------------------------------- -* get current observation data status -* args : rtksvr_t *svr I rtk server -* int rcv I receiver (0:rover,1:base,2:ephem) -* gtime_t *time O time of observation data -* int *sat O satellite prn numbers -* double *az O satellite azimuth angles (rad) -* double *el O satellite elevation angles (rad) -* int **snr O satellite snr for each freq (dBHz) -* snr[i][j] = sat i freq j snr -* int *vsat O valid satellite flag -* return : number of satellites -*-----------------------------------------------------------------------------*/ -extern int rtksvrostat(rtksvr_t *svr, int rcv, gtime_t *time, int *sat, - double *az, double *el, int **snr, int *vsat) -{ - int i,j,ns; - - tracet(4,"rtksvrostat: rcv=%d\n",rcv); - - if (!svr->state) return 0; - rtksvrlock(svr); - ns=svr->obs[rcv][0].n; - if (ns>0) { - *time=svr->obs[rcv][0].data[0].time; + * get current observation data status + * args : rtksvr_t *svr I rtk server + * int rcv I receiver (0:rover,1:base,2:ephem) + * gtime_t *time O time of observation data + * int *sat O satellite prn numbers + * double *az O satellite azimuth angles (rad) + * double *el O satellite elevation angles (rad) + * int **snr O satellite snr for each freq (dBHz) + * snr[i][j] = sat i freq j snr + * int *vsat O valid satellite flag + * return : number of satellites + *-----------------------------------------------------------------------------*/ +extern int rtksvrostat(rtksvr_t *svr, int rcv, gtime_t *time, int *sat, double *az, double *el, + int **snr, int *vsat) { + int i, j, ns; + + tracet(4, "rtksvrostat: rcv=%d\n", rcv); + + if (!svr->state) return 0; + rtksvrlock(svr); + ns = svr->obs[rcv][0].n; + if (ns > 0) { + *time = svr->obs[rcv][0].data[0].time; + } + for (i = 0; i < ns; i++) { + sat[i] = svr->obs[rcv][0].data[i].sat; + az[i] = svr->rtk.ssat[sat[i] - 1].azel[0]; + el[i] = svr->rtk.ssat[sat[i] - 1].azel[1]; + for (j = 0; j < NFREQ; j++) { + snr[i][j] = (int)(svr->obs[rcv][0].data[i].SNR[j]); } - for (i=0;iobs[rcv][0].data[i].sat; - az [i]=svr->rtk.ssat[sat[i]-1].azel[0]; - el [i]=svr->rtk.ssat[sat[i]-1].azel[1]; - for (j=0;jobs[rcv][0].data[i].SNR[j]); - } - if (svr->rtk.sol.stat==SOLQ_NONE||svr->rtk.sol.stat==SOLQ_SINGLE) { - vsat[i]=svr->rtk.ssat[sat[i]-1].vs; - } - else { - vsat[i]=svr->rtk.ssat[sat[i]-1].vsat[0]; - } + if (svr->rtk.sol.stat == SOLQ_NONE || svr->rtk.sol.stat == SOLQ_SINGLE) { + vsat[i] = svr->rtk.ssat[sat[i] - 1].vs; + } else { + vsat[i] = svr->rtk.ssat[sat[i] - 1].vsat[0]; } - rtksvrunlock(svr); - return ns; + } + rtksvrunlock(svr); + return ns; } /* get stream status ----------------------------------------------------------- -* get current stream status -* args : rtksvr_t *svr I rtk server -* int *sstat O status of streams -* char *msg O status messages -* return : none -*-----------------------------------------------------------------------------*/ -extern void rtksvrsstat(rtksvr_t *svr, int *sstat, char *msg) -{ - int i; - char s[MAXSTRMSG],*p=msg; - - tracet(4,"rtksvrsstat:\n"); - - rtksvrlock(svr); - for (i=0;istream+i,s); - if (*s) p+=sprintf(p,"(%d) %s ",i+1,s); - } - rtksvrunlock(svr); + * get current stream status + * args : rtksvr_t *svr I rtk server + * int *sstat O status of streams + * char *msg O status messages + * return : none + *-----------------------------------------------------------------------------*/ +extern void rtksvrsstat(rtksvr_t *svr, int *sstat, char *msg) { + int i; + char s[MAXSTRMSG], *p = msg; + + tracet(4, "rtksvrsstat:\n"); + + rtksvrlock(svr); + for (i = 0; i < MAXSTRRTK; i++) { + sstat[i] = strstat(svr->stream + i, s); + if (*s) p += sprintf(p, "(%d) %s ", i + 1, s); + } + rtksvrunlock(svr); } /* mark current position ------------------------------------------------------- -* open output/log stream -* args : rtksvr_t *svr IO rtk server -* char *name I marker name -* char *comment I comment string -* return : status (1:ok 0:error) -*-----------------------------------------------------------------------------*/ -extern int rtksvrmark(rtksvr_t *svr, const char *name, const char *comment) -{ - char buff[MAXSOLMSG+1],tstr[40],*p,*q; - double tow,pos[3]; - int i,sum,week; - - tracet(4,"rtksvrmark:name=%s comment=%s\n",name,comment); - - if (!svr->state) return 0; - - rtksvrlock(svr); - - time2str(svr->rtk.sol.time,tstr,3); - tow=time2gpst(svr->rtk.sol.time,&week); - ecef2pos(svr->rtk.sol.rr,pos); - - for (i=0;i<2;i++) { - p=buff; - if (svr->solopt[i].posf==SOLF_STAT) { - p+=sprintf(p,"$MARK,%d,%.3f,%d,%.4f,%.4f,%.4f,%s,%s\r\n",week,tow, - svr->rtk.sol.stat,svr->rtk.sol.rr[0],svr->rtk.sol.rr[1], - svr->rtk.sol.rr[2],name,comment); - } - else if (svr->solopt[i].posf==SOLF_NMEA) { - p+=sprintf(p,"$GPTXT,01,01,02,MARK:%s,%s,%.9f,%.9f,%.4f,%d,%s", - name,tstr,pos[0]*R2D,pos[1]*R2D,pos[2],svr->rtk.sol.stat, - comment); - for (q=(char *)buff+1,sum=0;*q;q++) sum^=*q; /* check-sum */ - p+=sprintf(p,"*%02X\r\n",sum); - } - else { - p+=sprintf(p,"%s MARK: %s,%s,%.9f,%.9f,%.4f,%d,%s\r\n",COMMENTH, - name,tstr,pos[0]*R2D,pos[1]*R2D,pos[2],svr->rtk.sol.stat, - comment); - } - strwrite(svr->stream+i+3,(uint8_t *)buff,(int)(p-buff)); - saveoutbuf(svr,(uint8_t *)buff,(int)(p-buff),i); - } - if (svr->moni) { - p=buff; - p+=sprintf(p,"%s MARK: %s,%s,%.9f,%.9f,%.4f,%d,%s\r\n",COMMENTH, - name,tstr,pos[0]*R2D,pos[1]*R2D,pos[2],svr->rtk.sol.stat, - comment); - strwrite(svr->moni,(uint8_t *)buff,(int)(p-buff)); + * open output/log stream + * args : rtksvr_t *svr IO rtk server + * char *name I marker name + * char *comment I comment string + * return : status (1:ok 0:error) + *-----------------------------------------------------------------------------*/ +extern int rtksvrmark(rtksvr_t *svr, const char *name, const char *comment) { + char buff[MAXSOLMSG + 1], tstr[40], *p, *q; + double tow, pos[3]; + int i, sum, week; + + tracet(4, "rtksvrmark:name=%s comment=%s\n", name, comment); + + if (!svr->state) return 0; + + rtksvrlock(svr); + + time2str(svr->rtk.sol.time, tstr, 3); + tow = time2gpst(svr->rtk.sol.time, &week); + ecef2pos(svr->rtk.sol.rr, pos); + + for (i = 0; i < 2; i++) { + p = buff; + if (svr->solopt[i].posf == SOLF_STAT) { + p += sprintf(p, "$MARK,%d,%.3f,%d,%.4f,%.4f,%.4f,%s,%s\r\n", week, tow, svr->rtk.sol.stat, + svr->rtk.sol.rr[0], svr->rtk.sol.rr[1], svr->rtk.sol.rr[2], name, comment); + } else if (svr->solopt[i].posf == SOLF_NMEA) { + p += sprintf(p, "$GPTXT,01,01,02,MARK:%s,%s,%.9f,%.9f,%.4f,%d,%s", name, tstr, pos[0] * R2D, + pos[1] * R2D, pos[2], svr->rtk.sol.stat, comment); + for (q = (char *)buff + 1, sum = 0; *q; q++) sum ^= *q; /* check-sum */ + p += sprintf(p, "*%02X\r\n", sum); + } else { + p += sprintf(p, "%s MARK: %s,%s,%.9f,%.9f,%.4f,%d,%s\r\n", COMMENTH, name, tstr, pos[0] * R2D, + pos[1] * R2D, pos[2], svr->rtk.sol.stat, comment); } - rtksvrunlock(svr); - return 1; + strwrite(svr->stream + i + 3, (uint8_t *)buff, (int)(p - buff)); + saveoutbuf(svr, (uint8_t *)buff, (int)(p - buff), i); + } + if (svr->moni) { + p = buff; + p += sprintf(p, "%s MARK: %s,%s,%.9f,%.9f,%.4f,%d,%s\r\n", COMMENTH, name, tstr, pos[0] * R2D, + pos[1] * R2D, pos[2], svr->rtk.sol.stat, comment); + strwrite(svr->moni, (uint8_t *)buff, (int)(p - buff)); + } + rtksvrunlock(svr); + return 1; } diff --git a/src/sbas.c b/src/sbas.c index e20fe6932..604bbb4b2 100644 --- a/src/sbas.c +++ b/src/sbas.c @@ -1,749 +1,816 @@ /*------------------------------------------------------------------------------ -* sbas.c : sbas functions -* -* Copyright (C) 2007-2020 by T.TAKASU, All rights reserved. -* -* option : -DRRCENA enable rrc correction -* -* references : -* [1] RTCA/DO-229C, Minimum operational performanc standards for global -* positioning system/wide area augmentation system airborne equipment, -* RTCA inc, November 28, 2001 -* [2] IS-QZSS v.1.1, Quasi-Zenith Satellite System Navigation Service -* Interface Specification for QZSS, Japan Aerospace Exploration Agency, -* July 31, 2009 -* -* version : $Revision: 1.1 $ $Date: 2008/07/17 21:48:06 $ -* history : 2007/10/14 1.0 new -* 2009/01/24 1.1 modify sbspntpos() api -* improve fast/ion correction update -* 2009/04/08 1.2 move function crc24q() to rcvlog.c -* support glonass, galileo and qzss -* 2009/06/08 1.3 modify sbsupdatestat() -* delete sbssatpos() -* 2009/12/12 1.4 support glonass -* 2010/01/22 1.5 support ems (egnos message service) format -* 2010/06/10 1.6 added api: -* sbssatcorr(),sbstropcorr(),sbsioncorr(), -* sbsupdatecorr() -* changed api: -* sbsreadmsgt(),sbsreadmsg() -* deleted api: -* sbspntpos(),sbsupdatestat() -* 2010/08/16 1.7 not reject udre==14 or give==15 correction message -* (2.4.0_p4) -* 2011/01/15 1.8 use api ionppp() -* add prn mask of qzss for qzss L1SAIF -* 2016/07/29 1.9 crc24q() -> rtk_crc24q() -* 2020/11/30 1.10 use integer types in stdint.h -*-----------------------------------------------------------------------------*/ + * sbas.c : sbas functions + * + * Copyright (C) 2007-2020 by T.TAKASU, All rights reserved. + * + * option : -DRRCENA enable rrc correction + * + * references : + * [1] RTCA/DO-229C, Minimum operational performanc standards for global + * positioning system/wide area augmentation system airborne equipment, + * RTCA inc, November 28, 2001 + * [2] IS-QZSS v.1.1, Quasi-Zenith Satellite System Navigation Service + * Interface Specification for QZSS, Japan Aerospace Exploration Agency, + * July 31, 2009 + * + * version : $Revision: 1.1 $ $Date: 2008/07/17 21:48:06 $ + * history : 2007/10/14 1.0 new + * 2009/01/24 1.1 modify sbspntpos() api + * improve fast/ion correction update + * 2009/04/08 1.2 move function crc24q() to rcvlog.c + * support glonass, galileo and qzss + * 2009/06/08 1.3 modify sbsupdatestat() + * delete sbssatpos() + * 2009/12/12 1.4 support glonass + * 2010/01/22 1.5 support ems (egnos message service) format + * 2010/06/10 1.6 added api: + * sbssatcorr(),sbstropcorr(),sbsioncorr(), + * sbsupdatecorr() + * changed api: + * sbsreadmsgt(),sbsreadmsg() + * deleted api: + * sbspntpos(),sbsupdatestat() + * 2010/08/16 1.7 not reject udre==14 or give==15 correction message + * (2.4.0_p4) + * 2011/01/15 1.8 use api ionppp() + * add prn mask of qzss for qzss L1SAIF + * 2016/07/29 1.9 crc24q() -> rtk_crc24q() + * 2020/11/30 1.10 use integer types in stdint.h + *-----------------------------------------------------------------------------*/ #include "rtklib.h" /* constants -----------------------------------------------------------------*/ -#define WEEKOFFSET 1024 /* gps week offset for NovAtel OEM-3 */ +#define WEEKOFFSET 1024 /* gps week offset for NovAtel OEM-3 */ /* sbas igp definition -------------------------------------------------------*/ -static const int16_t -x1[]={-75,-65,-55,-50,-45,-40,-35,-30,-25,-20,-15,-10,- 5, 0, 5, 10, 15, 20, - 25, 30, 35, 40, 45, 50, 55, 65, 75, 85}, -x2[]={-55,-50,-45,-40,-35,-30,-25,-20,-15,-10, -5, 0, 5, 10, 15, 20, 25, 30, - 35, 40, 45, 50, 55}, -x3[]={-75,-65,-55,-50,-45,-40,-35,-30,-25,-20,-15,-10,- 5, 0, 5, 10, 15, 20, - 25, 30, 35, 40, 45, 50, 55, 65, 75}, -x4[]={-85,-75,-65,-55,-50,-45,-40,-35,-30,-25,-20,-15,-10,- 5, 0, 5, 10, 15, - 20, 25, 30, 35, 40, 45, 50, 55, 65, 75}, -x5[]={-180,-175,-170,-165,-160,-155,-150,-145,-140,-135,-130,-125,-120,-115, - -110,-105,-100,- 95,- 90,- 85,- 80,- 75,- 70,- 65,- 60,- 55,- 50,- 45, - - 40,- 35,- 30,- 25,- 20,- 15,- 10,- 5, 0, 5, 10, 15, 20, 25, - 30, 35, 40, 45, 50, 55, 60, 65, 70, 75, 80, 85, 90, 95, - 100, 105, 110, 115, 120, 125, 130, 135, 140, 145, 150, 155, 160, 165, - 170, 175}, -x6[]={-180,-170,-160,-150,-140,-130,-120,-110,-100,- 90,- 80,- 70,- 60,- 50, - - 40,- 30,- 20,- 10, 0, 10, 20, 30, 40, 50, 60, 70, 80, 90, - 100, 110, 120, 130, 140, 150, 160, 170}, -x7[]={-180,-150,-120,- 90,- 60,- 30, 0, 30, 60, 90, 120, 150}, -x8[]={-170,-140,-110,- 80,- 50,- 20, 10, 40, 70, 100, 130, 160}; - -EXPORT const sbsigpband_t igpband1[9][8]={ /* band 0-8 */ - {{-180,x1, 1, 28},{-175,x2, 29, 51},{-170,x3, 52, 78},{-165,x2, 79,101}, - {-160,x3,102,128},{-155,x2,129,151},{-150,x3,152,178},{-145,x2,179,201}}, - {{-140,x4, 1, 28},{-135,x2, 29, 51},{-130,x3, 52, 78},{-125,x2, 79,101}, - {-120,x3,102,128},{-115,x2,129,151},{-110,x3,152,178},{-105,x2,179,201}}, - {{-100,x3, 1, 27},{- 95,x2, 28, 50},{- 90,x1, 51, 78},{- 85,x2, 79,101}, - {- 80,x3,102,128},{- 75,x2,129,151},{- 70,x3,152,178},{- 65,x2,179,201}}, - {{- 60,x3, 1, 27},{- 55,x2, 28, 50},{- 50,x4, 51, 78},{- 45,x2, 79,101}, - {- 40,x3,102,128},{- 35,x2,129,151},{- 30,x3,152,178},{- 25,x2,179,201}}, - {{- 20,x3, 1, 27},{- 15,x2, 28, 50},{- 10,x3, 51, 77},{- 5,x2, 78,100}, - { 0,x1,101,128},{ 5,x2,129,151},{ 10,x3,152,178},{ 15,x2,179,201}}, - {{ 20,x3, 1, 27},{ 25,x2, 28, 50},{ 30,x3, 51, 77},{ 35,x2, 78,100}, - { 40,x4,101,128},{ 45,x2,129,151},{ 50,x3,152,178},{ 55,x2,179,201}}, - {{ 60,x3, 1, 27},{ 65,x2, 28, 50},{ 70,x3, 51, 77},{ 75,x2, 78,100}, - { 80,x3,101,127},{ 85,x2,128,150},{ 90,x1,151,178},{ 95,x2,179,201}}, - {{ 100,x3, 1, 27},{ 105,x2, 28, 50},{ 110,x3, 51, 77},{ 115,x2, 78,100}, - { 120,x3,101,127},{ 125,x2,128,150},{ 130,x4,151,178},{ 135,x2,179,201}}, - {{ 140,x3, 1, 27},{ 145,x2, 28, 50},{ 150,x3, 51, 77},{ 155,x2, 78,100}, - { 160,x3,101,127},{ 165,x2,128,150},{ 170,x3,151,177},{ 175,x2,178,200}} -}; -EXPORT const sbsigpband_t igpband2[2][5]={ /* band 9-10 */ - {{ 60,x5, 1, 72},{ 65,x6, 73,108},{ 70,x6,109,144},{ 75,x6,145,180}, - { 85,x7,181,192}}, - {{- 60,x5, 1, 72},{- 65,x6, 73,108},{- 70,x6,109,144},{- 75,x6,145,180}, - {- 85,x8,181,192}} -}; +static const int16_t x1[] = {-75, -65, -55, -50, -45, -40, -35, -30, -25, -20, -15, -10, -5, 0, + 5, 10, 15, 20, 25, 30, 35, 40, 45, 50, 55, 65, 75, 85}, + x2[] = {-55, -50, -45, -40, -35, -30, -25, -20, -15, -10, -5, 0, + 5, 10, 15, 20, 25, 30, 35, 40, 45, 50, 55}, + x3[] = {-75, -65, -55, -50, -45, -40, -35, -30, -25, -20, -15, -10, -5, 0, + 5, 10, 15, 20, 25, 30, 35, 40, 45, 50, 55, 65, 75}, + x4[] = {-85, -75, -65, -55, -50, -45, -40, -35, -30, -25, -20, -15, -10, -5, + 0, 5, 10, 15, 20, 25, 30, 35, 40, 45, 50, 55, 65, 75}, + x5[] = {-180, -175, -170, -165, -160, -155, -150, -145, -140, -135, -130, -125, + -120, -115, -110, -105, -100, -95, -90, -85, -80, -75, -70, -65, + -60, -55, -50, -45, -40, -35, -30, -25, -20, -15, -10, -5, + 0, 5, 10, 15, 20, 25, 30, 35, 40, 45, 50, 55, + 60, 65, 70, 75, 80, 85, 90, 95, 100, 105, 110, 115, + 120, 125, 130, 135, 140, 145, 150, 155, 160, 165, 170, 175}, + x6[] = {-180, -170, -160, -150, -140, -130, -120, -110, -100, -90, -80, -70, + -60, -50, -40, -30, -20, -10, 0, 10, 20, 30, 40, 50, + 60, 70, 80, 90, 100, 110, 120, 130, 140, 150, 160, 170}, + x7[] = {-180, -150, -120, -90, -60, -30, 0, 30, 60, 90, 120, 150}, + x8[] = {-170, -140, -110, -80, -50, -20, 10, 40, 70, 100, 130, 160}; + +EXPORT const sbsigpband_t igpband1[9][8] = {/* band 0-8 */ + {{-180, x1, 1, 28}, + {-175, x2, 29, 51}, + {-170, x3, 52, 78}, + {-165, x2, 79, 101}, + {-160, x3, 102, 128}, + {-155, x2, 129, 151}, + {-150, x3, 152, 178}, + {-145, x2, 179, 201}}, + {{-140, x4, 1, 28}, + {-135, x2, 29, 51}, + {-130, x3, 52, 78}, + {-125, x2, 79, 101}, + {-120, x3, 102, 128}, + {-115, x2, 129, 151}, + {-110, x3, 152, 178}, + {-105, x2, 179, 201}}, + {{-100, x3, 1, 27}, + {-95, x2, 28, 50}, + {-90, x1, 51, 78}, + {-85, x2, 79, 101}, + {-80, x3, 102, 128}, + {-75, x2, 129, 151}, + {-70, x3, 152, 178}, + {-65, x2, 179, 201}}, + {{-60, x3, 1, 27}, + {-55, x2, 28, 50}, + {-50, x4, 51, 78}, + {-45, x2, 79, 101}, + {-40, x3, 102, 128}, + {-35, x2, 129, 151}, + {-30, x3, 152, 178}, + {-25, x2, 179, 201}}, + {{-20, x3, 1, 27}, + {-15, x2, 28, 50}, + {-10, x3, 51, 77}, + {-5, x2, 78, 100}, + {0, x1, 101, 128}, + {5, x2, 129, 151}, + {10, x3, 152, 178}, + {15, x2, 179, 201}}, + {{20, x3, 1, 27}, + {25, x2, 28, 50}, + {30, x3, 51, 77}, + {35, x2, 78, 100}, + {40, x4, 101, 128}, + {45, x2, 129, 151}, + {50, x3, 152, 178}, + {55, x2, 179, 201}}, + {{60, x3, 1, 27}, + {65, x2, 28, 50}, + {70, x3, 51, 77}, + {75, x2, 78, 100}, + {80, x3, 101, 127}, + {85, x2, 128, 150}, + {90, x1, 151, 178}, + {95, x2, 179, 201}}, + {{100, x3, 1, 27}, + {105, x2, 28, 50}, + {110, x3, 51, 77}, + {115, x2, 78, 100}, + {120, x3, 101, 127}, + {125, x2, 128, 150}, + {130, x4, 151, 178}, + {135, x2, 179, 201}}, + {{140, x3, 1, 27}, + {145, x2, 28, 50}, + {150, x3, 51, 77}, + {155, x2, 78, 100}, + {160, x3, 101, 127}, + {165, x2, 128, 150}, + {170, x3, 151, 177}, + {175, x2, 178, 200}}}; +EXPORT const sbsigpband_t igpband2[2][5] = {/* band 9-10 */ + {{60, x5, 1, 72}, + {65, x6, 73, 108}, + {70, x6, 109, 144}, + {75, x6, 145, 180}, + {85, x7, 181, 192}}, + {{-60, x5, 1, 72}, + {-65, x6, 73, 108}, + {-70, x6, 109, 144}, + {-75, x6, 145, 180}, + {-85, x8, 181, 192}}}; /* extract field from line ---------------------------------------------------*/ -static char *getfield(char *p, int pos) -{ - for (pos--;pos>0;pos--,p++) if (!(p=strchr(p,','))) return NULL; - return p; +static char *getfield(char *p, int pos) { + for (pos--; pos > 0; pos--, p++) + if (!(p = strchr(p, ','))) return NULL; + return p; } /* variance of fast correction (udre=UDRE+1) ---------------------------------*/ -static double varfcorr(int udre) -{ - const double var[14]={ - 0.052,0.0924,0.1444,0.283,0.4678,0.8315,1.2992,1.8709,2.5465,3.326, - 5.1968,20.7870,230.9661,2078.695 - }; - return 0msg,13+i,1)) { - if (i<= 37) sat=satno(SYS_GPS,i); /* 0- 37: gps */ - else if (i<= 61) sat=satno(SYS_GLO,i-37); /* 38- 61: glonass */ - else if (i<=119) sat=0; /* 62-119: future gnss */ - else if (i<=138) sat=satno(SYS_SBS,i); /* 120-138: geo/waas */ - else if (i<=182) sat=0; /* 139-182: reserved */ - else if (i<=192) sat=satno(SYS_SBS,i+10); /* 183-192: qzss ref [2] */ - else if (i<=202) sat=satno(SYS_QZS,i); /* 193-202: qzss ref [2] */ - else sat=0; /* 203- : reserved */ - sbssat->sat[n++].sat=sat; - } +static int decode_sbstype1(const sbsmsg_t *msg, sbssat_t *sbssat) { + int i, n, sat; + + trace(4, "decode_sbstype1:\n"); + + for (i = 1, n = 0; i <= 210 && n < MAXSAT; i++) { + if (getbitu(msg->msg, 13 + i, 1)) { + if (i <= 37) + sat = satno(SYS_GPS, i); /* 0- 37: gps */ + else if (i <= 61) + sat = satno(SYS_GLO, i - 37); /* 38- 61: glonass */ + else if (i <= 119) + sat = 0; /* 62-119: future gnss */ + else if (i <= 138) + sat = satno(SYS_SBS, i); /* 120-138: geo/waas */ + else if (i <= 182) + sat = 0; /* 139-182: reserved */ + else if (i <= 192) + sat = satno(SYS_SBS, i + 10); /* 183-192: qzss ref [2] */ + else if (i <= 202) + sat = satno(SYS_QZS, i); /* 193-202: qzss ref [2] */ + else + sat = 0; /* 203- : reserved */ + sbssat->sat[n++].sat = sat; } - sbssat->iodp=getbitu(msg->msg,224,2); - sbssat->nsat=n; - - trace(5,"decode_sbstype1: nprn=%d iodp=%d\n",n,sbssat->iodp); - return 1; + } + sbssat->iodp = getbitu(msg->msg, 224, 2); + sbssat->nsat = n; + + trace(5, "decode_sbstype1: nprn=%d iodp=%d\n", n, sbssat->iodp); + return 1; } /* decode type 2-5,0: fast corrections ---------------------------------------*/ -static int decode_sbstype2(const sbsmsg_t *msg, sbssat_t *sbssat) -{ - int i,j,iodf,type,udre; - double prc,dt; - gtime_t t0; - - trace(4,"decode_sbstype2:\n"); - - if (sbssat->iodp!=(int)getbitu(msg->msg,16,2)) return 0; - - type=getbitu(msg->msg, 8,6); - iodf=getbitu(msg->msg,14,2); - - for (i=0;i<13;i++) { - if ((j=13*((type==0?2:type)-2)+i)>=sbssat->nsat) break; - udre=getbitu(msg->msg,174+4*i,4); - t0 =sbssat->sat[j].fcorr.t0; - prc=sbssat->sat[j].fcorr.prc; - sbssat->sat[j].fcorr.t0=gpst2time(msg->week,msg->tow); - sbssat->sat[j].fcorr.prc=getbits(msg->msg,18+i*12,12)*0.125; - sbssat->sat[j].fcorr.udre=udre+1; - dt=timediff(sbssat->sat[j].fcorr.t0,t0); - if (t0.time==0||dt<=0.0||18.0sat[j].fcorr.ai==0) { - sbssat->sat[j].fcorr.rrc=0.0; - sbssat->sat[j].fcorr.dt=0.0; - } - else { - sbssat->sat[j].fcorr.rrc=(sbssat->sat[j].fcorr.prc-prc)/dt; - sbssat->sat[j].fcorr.dt=dt; - } - sbssat->sat[j].fcorr.iodf=iodf; - } - trace(5,"decode_sbstype2: type=%d iodf=%d\n",type,iodf); - return 1; +static int decode_sbstype2(const sbsmsg_t *msg, sbssat_t *sbssat) { + int i, j, iodf, type, udre; + double prc, dt; + gtime_t t0; + + trace(4, "decode_sbstype2:\n"); + + if (sbssat->iodp != (int)getbitu(msg->msg, 16, 2)) return 0; + + type = getbitu(msg->msg, 8, 6); + iodf = getbitu(msg->msg, 14, 2); + + for (i = 0; i < 13; i++) { + if ((j = 13 * ((type == 0 ? 2 : type) - 2) + i) >= sbssat->nsat) break; + udre = getbitu(msg->msg, 174 + 4 * i, 4); + t0 = sbssat->sat[j].fcorr.t0; + prc = sbssat->sat[j].fcorr.prc; + sbssat->sat[j].fcorr.t0 = gpst2time(msg->week, msg->tow); + sbssat->sat[j].fcorr.prc = getbits(msg->msg, 18 + i * 12, 12) * 0.125; + sbssat->sat[j].fcorr.udre = udre + 1; + dt = timediff(sbssat->sat[j].fcorr.t0, t0); + if (t0.time == 0 || dt <= 0.0 || 18.0 < dt || sbssat->sat[j].fcorr.ai == 0) { + sbssat->sat[j].fcorr.rrc = 0.0; + sbssat->sat[j].fcorr.dt = 0.0; + } else { + sbssat->sat[j].fcorr.rrc = (sbssat->sat[j].fcorr.prc - prc) / dt; + sbssat->sat[j].fcorr.dt = dt; + } + sbssat->sat[j].fcorr.iodf = iodf; + } + trace(5, "decode_sbstype2: type=%d iodf=%d\n", type, iodf); + return 1; } /* decode type 6: integrity info ---------------------------------------------*/ -static int decode_sbstype6(const sbsmsg_t *msg, sbssat_t *sbssat) -{ - int i,iodf[4],udre; - - trace(4,"decode_sbstype6:\n"); - - for (i=0;i<4;i++) { - iodf[i]=getbitu(msg->msg,14+i*2,2); - } - /* At most 51 entries in the message */ - for (i=0;insat&&i<=51;i++) { - if (sbssat->sat[i].fcorr.iodf!=iodf[i/13]) continue; - udre=getbitu(msg->msg,22+i*4,4); - sbssat->sat[i].fcorr.udre=udre+1; - } - trace(5,"decode_sbstype6: iodf=%d %d %d %d\n",iodf[0],iodf[1],iodf[2],iodf[3]); - return 1; +static int decode_sbstype6(const sbsmsg_t *msg, sbssat_t *sbssat) { + int i, iodf[4], udre; + + trace(4, "decode_sbstype6:\n"); + + for (i = 0; i < 4; i++) { + iodf[i] = getbitu(msg->msg, 14 + i * 2, 2); + } + /* At most 51 entries in the message */ + for (i = 0; i < sbssat->nsat && i <= 51; i++) { + if (sbssat->sat[i].fcorr.iodf != iodf[i / 13]) continue; + udre = getbitu(msg->msg, 22 + i * 4, 4); + sbssat->sat[i].fcorr.udre = udre + 1; + } + trace(5, "decode_sbstype6: iodf=%d %d %d %d\n", iodf[0], iodf[1], iodf[2], iodf[3]); + return 1; } /* decode type 7: fast correction degradation factor -------------------------*/ -static int decode_sbstype7(const sbsmsg_t *msg, sbssat_t *sbssat) -{ - int i; - - trace(4,"decode_sbstype7\n"); - - if (sbssat->iodp!=(int)getbitu(msg->msg,18,2)) return 0; - - sbssat->tlat=getbitu(msg->msg,14,4); - - /* At most 51 entries in the message */ - for (i=0;insat&&i<=51;i++) { - sbssat->sat[i].fcorr.ai=getbitu(msg->msg,22+i*4,4); - } - return 1; +static int decode_sbstype7(const sbsmsg_t *msg, sbssat_t *sbssat) { + int i; + + trace(4, "decode_sbstype7\n"); + + if (sbssat->iodp != (int)getbitu(msg->msg, 18, 2)) return 0; + + sbssat->tlat = getbitu(msg->msg, 14, 4); + + /* At most 51 entries in the message */ + for (i = 0; i < sbssat->nsat && i <= 51; i++) { + sbssat->sat[i].fcorr.ai = getbitu(msg->msg, 22 + i * 4, 4); + } + return 1; } /* decode type 9: geo navigation message -------------------------------------*/ -static int decode_sbstype9(const sbsmsg_t *msg, nav_t *nav) -{ - seph_t seph={0}; - int i,sat,t; - - trace(4,"decode_sbstype9:\n"); - - if (!(sat=satno(SYS_SBS,msg->prn))) { - trace(2,"invalid prn in sbas type 9: prn=%3d\n",msg->prn); - return 0; - } - t=(int)getbitu(msg->msg,22,13)*16-(int)msg->tow%86400; - if (t<=-43200) t+=86400; - else if (t> 43200) t-=86400; - seph.sat=sat; - seph.t0 =gpst2time(msg->week,msg->tow+t); - seph.tof=gpst2time(msg->week,msg->tow); - seph.sva=getbitu(msg->msg,35,4); - seph.svh=seph.sva==15?1:0; /* unhealthy if ura==15 */ - - seph.pos[0]=getbits(msg->msg, 39,30)*0.08; - seph.pos[1]=getbits(msg->msg, 69,30)*0.08; - seph.pos[2]=getbits(msg->msg, 99,25)*0.4; - seph.vel[0]=getbits(msg->msg,124,17)*0.000625; - seph.vel[1]=getbits(msg->msg,141,17)*0.000625; - seph.vel[2]=getbits(msg->msg,158,18)*0.004; - seph.acc[0]=getbits(msg->msg,176,10)*0.0000125; - seph.acc[1]=getbits(msg->msg,186,10)*0.0000125; - seph.acc[2]=getbits(msg->msg,196,10)*0.0000625; - - seph.af0=getbits(msg->msg,206,12)*P2_31; - seph.af1=getbits(msg->msg,218, 8)*P2_39/2.0; - - i=msg->prn-MINPRNSBS; - if (!nav->seph||fabs(timediff(nav->seph[i].t0,seph.t0))<1E-3) { /* not change */ - return 0; - } - nav->seph[NSATSBS+i]=nav->seph[i]; /* previous */ - nav->seph[i]=seph; /* current */ +static int decode_sbstype9(const sbsmsg_t *msg, nav_t *nav) { + seph_t seph = {0}; + int i, sat, t; - trace(5,"decode_sbstype9: prn=%d\n",msg->prn); - return 1; + trace(4, "decode_sbstype9:\n"); + + if (!(sat = satno(SYS_SBS, msg->prn))) { + trace(2, "invalid prn in sbas type 9: prn=%3d\n", msg->prn); + return 0; + } + t = (int)getbitu(msg->msg, 22, 13) * 16 - (int)msg->tow % 86400; + if (t <= -43200) + t += 86400; + else if (t > 43200) + t -= 86400; + seph.sat = sat; + seph.t0 = gpst2time(msg->week, msg->tow + t); + seph.tof = gpst2time(msg->week, msg->tow); + seph.sva = getbitu(msg->msg, 35, 4); + seph.svh = seph.sva == 15 ? 1 : 0; /* unhealthy if ura==15 */ + + seph.pos[0] = getbits(msg->msg, 39, 30) * 0.08; + seph.pos[1] = getbits(msg->msg, 69, 30) * 0.08; + seph.pos[2] = getbits(msg->msg, 99, 25) * 0.4; + seph.vel[0] = getbits(msg->msg, 124, 17) * 0.000625; + seph.vel[1] = getbits(msg->msg, 141, 17) * 0.000625; + seph.vel[2] = getbits(msg->msg, 158, 18) * 0.004; + seph.acc[0] = getbits(msg->msg, 176, 10) * 0.0000125; + seph.acc[1] = getbits(msg->msg, 186, 10) * 0.0000125; + seph.acc[2] = getbits(msg->msg, 196, 10) * 0.0000625; + + seph.af0 = getbits(msg->msg, 206, 12) * P2_31; + seph.af1 = getbits(msg->msg, 218, 8) * P2_39 / 2.0; + + i = msg->prn - MINPRNSBS; + if (!nav->seph || fabs(timediff(nav->seph[i].t0, seph.t0)) < 1E-3) { /* not change */ + return 0; + } + nav->seph[NSATSBS + i] = nav->seph[i]; /* previous */ + nav->seph[i] = seph; /* current */ + + trace(5, "decode_sbstype9: prn=%d\n", msg->prn); + return 1; } /* decode type 18: ionospheric grid point masks ------------------------------*/ -static int decode_sbstype18(const sbsmsg_t *msg, sbsion_t *sbsion) -{ - const sbsigpband_t *p; - int i,j,n,m,band=getbitu(msg->msg,18,4); - - trace(4,"decode_sbstype18:\n"); - - if (0<=band&&band<= 8) {p=igpband1[band ]; m=8;} - else if (9<=band&&band<=10) {p=igpband2[band-9]; m=5;} - else return 0; - - sbsion[band].iodi=(int16_t)getbitu(msg->msg,22,2); - - for (i=1,n=0;i<=201;i++) { - if (!getbitu(msg->msg,23+i,1)) continue; - for (j=0;jmsg, 18, 4); + + trace(4, "decode_sbstype18:\n"); + + if (0 <= band && band <= 8) { + p = igpband1[band]; + m = 8; + } else if (9 <= band && band <= 10) { + p = igpband2[band - 9]; + m = 5; + } else + return 0; + + sbsion[band].iodi = (int16_t)getbitu(msg->msg, 22, 2); + + for (i = 1, n = 0; i <= 201; i++) { + if (!getbitu(msg->msg, 23 + i, 1)) continue; + for (j = 0; j < m; j++) { + if (i < p[j].bits || p[j].bite < i) continue; + sbsion[band].igp[n].lat = band <= 8 ? p[j].y[i - p[j].bits] : p[j].x; + sbsion[band].igp[n++].lon = band <= 8 ? p[j].x : p[j].y[i - p[j].bits]; + break; } - sbsion[band].nigp=n; - - trace(5,"decode_sbstype18: band=%d nigp=%d\n",band,n); - return 1; + } + sbsion[band].nigp = n; + + trace(5, "decode_sbstype18: band=%d nigp=%d\n", band, n); + return 1; } /* decode half long term correction (vel code=0) -----------------------------*/ -static int decode_longcorr0(const sbsmsg_t *msg, int p, sbssat_t *sbssat) -{ - int i,n=getbitu(msg->msg,p,6); - - trace(4,"decode_longcorr0:\n"); - - if (n==0||n>MAXSAT) return 0; - - sbssat->sat[n-1].lcorr.iode=getbitu(msg->msg,p+6,8); - - for (i=0;i<3;i++) { - sbssat->sat[n-1].lcorr.dpos[i]=getbits(msg->msg,p+14+9*i,9)*0.125; - sbssat->sat[n-1].lcorr.dvel[i]=0.0; - } - sbssat->sat[n-1].lcorr.daf0=getbits(msg->msg,p+41,10)*P2_31; - sbssat->sat[n-1].lcorr.daf1=0.0; - sbssat->sat[n-1].lcorr.t0=gpst2time(msg->week,msg->tow); - - trace(5,"decode_longcorr0:sat=%2d\n",sbssat->sat[n-1].sat); - return 1; +static int decode_longcorr0(const sbsmsg_t *msg, int p, sbssat_t *sbssat) { + int i, n = getbitu(msg->msg, p, 6); + + trace(4, "decode_longcorr0:\n"); + + if (n == 0 || n > MAXSAT) return 0; + + sbssat->sat[n - 1].lcorr.iode = getbitu(msg->msg, p + 6, 8); + + for (i = 0; i < 3; i++) { + sbssat->sat[n - 1].lcorr.dpos[i] = getbits(msg->msg, p + 14 + 9 * i, 9) * 0.125; + sbssat->sat[n - 1].lcorr.dvel[i] = 0.0; + } + sbssat->sat[n - 1].lcorr.daf0 = getbits(msg->msg, p + 41, 10) * P2_31; + sbssat->sat[n - 1].lcorr.daf1 = 0.0; + sbssat->sat[n - 1].lcorr.t0 = gpst2time(msg->week, msg->tow); + + trace(5, "decode_longcorr0:sat=%2d\n", sbssat->sat[n - 1].sat); + return 1; } /* decode half long term correction (vel code=1) -----------------------------*/ -static int decode_longcorr1(const sbsmsg_t *msg, int p, sbssat_t *sbssat) -{ - int i,n=getbitu(msg->msg,p,6),t; - - trace(4,"decode_longcorr1:\n"); - - if (n==0||n>MAXSAT) return 0; - - sbssat->sat[n-1].lcorr.iode=getbitu(msg->msg,p+6,8); - - for (i=0;i<3;i++) { - sbssat->sat[n-1].lcorr.dpos[i]=getbits(msg->msg,p+14+i*11,11)*0.125; - sbssat->sat[n-1].lcorr.dvel[i]=getbits(msg->msg,p+58+i* 8, 8)*P2_11; - } - sbssat->sat[n-1].lcorr.daf0=getbits(msg->msg,p+47,11)*P2_31; - sbssat->sat[n-1].lcorr.daf1=getbits(msg->msg,p+82, 8)*P2_39; - t=(int)getbitu(msg->msg,p+90,13)*16-(int)msg->tow%86400; - if (t<=-43200) t+=86400; - else if (t> 43200) t-=86400; - sbssat->sat[n-1].lcorr.t0=gpst2time(msg->week,msg->tow+t); - - trace(5,"decode_longcorr1: sat=%2d\n",sbssat->sat[n-1].sat); - return 1; +static int decode_longcorr1(const sbsmsg_t *msg, int p, sbssat_t *sbssat) { + int i, n = getbitu(msg->msg, p, 6), t; + + trace(4, "decode_longcorr1:\n"); + + if (n == 0 || n > MAXSAT) return 0; + + sbssat->sat[n - 1].lcorr.iode = getbitu(msg->msg, p + 6, 8); + + for (i = 0; i < 3; i++) { + sbssat->sat[n - 1].lcorr.dpos[i] = getbits(msg->msg, p + 14 + i * 11, 11) * 0.125; + sbssat->sat[n - 1].lcorr.dvel[i] = getbits(msg->msg, p + 58 + i * 8, 8) * P2_11; + } + sbssat->sat[n - 1].lcorr.daf0 = getbits(msg->msg, p + 47, 11) * P2_31; + sbssat->sat[n - 1].lcorr.daf1 = getbits(msg->msg, p + 82, 8) * P2_39; + t = (int)getbitu(msg->msg, p + 90, 13) * 16 - (int)msg->tow % 86400; + if (t <= -43200) + t += 86400; + else if (t > 43200) + t -= 86400; + sbssat->sat[n - 1].lcorr.t0 = gpst2time(msg->week, msg->tow + t); + + trace(5, "decode_longcorr1: sat=%2d\n", sbssat->sat[n - 1].sat); + return 1; } /* decode half long term correction ------------------------------------------*/ -static int decode_longcorrh(const sbsmsg_t *msg, int p, sbssat_t *sbssat) -{ - trace(4,"decode_longcorrh:\n"); - - if (getbitu(msg->msg,p,1)==0) { /* vel code=0 */ - if (sbssat->iodp==(int)getbitu(msg->msg,p+103,2)) { - return decode_longcorr0(msg,p+ 1,sbssat)&& - decode_longcorr0(msg,p+52,sbssat); - } - } - else if (sbssat->iodp==(int)getbitu(msg->msg,p+104,2)) { - return decode_longcorr1(msg,p+1,sbssat); +static int decode_longcorrh(const sbsmsg_t *msg, int p, sbssat_t *sbssat) { + trace(4, "decode_longcorrh:\n"); + + if (getbitu(msg->msg, p, 1) == 0) { /* vel code=0 */ + if (sbssat->iodp == (int)getbitu(msg->msg, p + 103, 2)) { + return decode_longcorr0(msg, p + 1, sbssat) && decode_longcorr0(msg, p + 52, sbssat); } - return 0; + } else if (sbssat->iodp == (int)getbitu(msg->msg, p + 104, 2)) { + return decode_longcorr1(msg, p + 1, sbssat); + } + return 0; } /* decode type 24: mixed fast/long term correction ---------------------------*/ -static int decode_sbstype24(const sbsmsg_t *msg, sbssat_t *sbssat) -{ - int i,j,iodf,blk,udre; - - trace(4,"decode_sbstype24:\n"); - - if (sbssat->iodp!=(int)getbitu(msg->msg,110,2)) return 0; /* check IODP */ - - blk =getbitu(msg->msg,112,2); - iodf=getbitu(msg->msg,114,2); - - for (i=0;i<6;i++) { - if ((j=13*blk+i)>=sbssat->nsat) break; - udre=getbitu(msg->msg,86+4*i,4); - - sbssat->sat[j].fcorr.t0 =gpst2time(msg->week,msg->tow); - sbssat->sat[j].fcorr.prc =getbits(msg->msg,14+i*12,12)*0.125; - sbssat->sat[j].fcorr.udre=udre+1; - sbssat->sat[j].fcorr.iodf=iodf; - } - return decode_longcorrh(msg,120,sbssat); +static int decode_sbstype24(const sbsmsg_t *msg, sbssat_t *sbssat) { + int i, j, iodf, blk, udre; + + trace(4, "decode_sbstype24:\n"); + + if (sbssat->iodp != (int)getbitu(msg->msg, 110, 2)) return 0; /* check IODP */ + + blk = getbitu(msg->msg, 112, 2); + iodf = getbitu(msg->msg, 114, 2); + + for (i = 0; i < 6; i++) { + if ((j = 13 * blk + i) >= sbssat->nsat) break; + udre = getbitu(msg->msg, 86 + 4 * i, 4); + + sbssat->sat[j].fcorr.t0 = gpst2time(msg->week, msg->tow); + sbssat->sat[j].fcorr.prc = getbits(msg->msg, 14 + i * 12, 12) * 0.125; + sbssat->sat[j].fcorr.udre = udre + 1; + sbssat->sat[j].fcorr.iodf = iodf; + } + return decode_longcorrh(msg, 120, sbssat); } /* decode type 25: long term satellite error correction ----------------------*/ -static int decode_sbstype25(const sbsmsg_t *msg, sbssat_t *sbssat) -{ - trace(4,"decode_sbstype25:\n"); - - return decode_longcorrh(msg,14,sbssat)&&decode_longcorrh(msg,120,sbssat); +static int decode_sbstype25(const sbsmsg_t *msg, sbssat_t *sbssat) { + trace(4, "decode_sbstype25:\n"); + + return decode_longcorrh(msg, 14, sbssat) && decode_longcorrh(msg, 120, sbssat); } /* decode type 26: ionospheric delay corrections -----------------------------*/ -static int decode_sbstype26(const sbsmsg_t *msg, sbsion_t *sbsion) -{ - int i,j,block,delay,give,band=getbitu(msg->msg,14,4); - - trace(4,"decode_sbstype26:\n"); - - if (band>MAXBAND||sbsion[band].iodi!=(int)getbitu(msg->msg,217,2)) return 0; - - block=getbitu(msg->msg,18,4); - - for (i=0;i<15;i++) { - if ((j=block*15+i)>=sbsion[band].nigp) continue; - give=getbitu(msg->msg,22+i*13+9,4); - - delay=getbitu(msg->msg,22+i*13,9); - sbsion[band].igp[j].t0=gpst2time(msg->week,msg->tow); - sbsion[band].igp[j].delay=delay==0x1FF?0.0f:delay*0.125f; - sbsion[band].igp[j].give=give+1; - - if (sbsion[band].igp[j].give>=16) { - sbsion[band].igp[j].give=0; - } +static int decode_sbstype26(const sbsmsg_t *msg, sbsion_t *sbsion) { + int i, j, block, delay, give, band = getbitu(msg->msg, 14, 4); + + trace(4, "decode_sbstype26:\n"); + + if (band > MAXBAND || sbsion[band].iodi != (int)getbitu(msg->msg, 217, 2)) return 0; + + block = getbitu(msg->msg, 18, 4); + + for (i = 0; i < 15; i++) { + if ((j = block * 15 + i) >= sbsion[band].nigp) continue; + give = getbitu(msg->msg, 22 + i * 13 + 9, 4); + + delay = getbitu(msg->msg, 22 + i * 13, 9); + sbsion[band].igp[j].t0 = gpst2time(msg->week, msg->tow); + sbsion[band].igp[j].delay = delay == 0x1FF ? 0.0f : delay * 0.125f; + sbsion[band].igp[j].give = give + 1; + + if (sbsion[band].igp[j].give >= 16) { + sbsion[band].igp[j].give = 0; } - trace(5,"decode_sbstype26: band=%d block=%d\n",band,block); - return 1; + } + trace(5, "decode_sbstype26: band=%d block=%d\n", band, block); + return 1; } /* update sbas corrections ----------------------------------------------------- -* update sbas correction parameters in navigation data with a sbas message -* args : sbsmg_t *msg I sbas message -* nav_t *nav IO navigation data -* return : message type (-1: error or not supported type) -* notes : nav->seph must point to seph[NSATSBS*2] (array of seph_t) -* seph[prn-MINPRNSBS+1] : sat prn current epehmeris -* seph[prn-MINPRNSBS+1+MAXPRNSBS]: sat prn previous epehmeris -*-----------------------------------------------------------------------------*/ -extern int sbsupdatecorr(const sbsmsg_t *msg, nav_t *nav) -{ - int type=getbitu(msg->msg,8,6),stat=-1; - - trace(3,"sbsupdatecorr: type=%d\n",type); - - if (msg->week==0) return -1; - - switch (type) { - case 0: stat=decode_sbstype2 (msg,&nav->sbssat); break; - case 1: stat=decode_sbstype1 (msg,&nav->sbssat); break; - case 2: - case 3: - case 4: - case 5: stat=decode_sbstype2 (msg,&nav->sbssat); break; - case 6: stat=decode_sbstype6 (msg,&nav->sbssat); break; - case 7: stat=decode_sbstype7 (msg,&nav->sbssat); break; - case 9: stat=decode_sbstype9 (msg,nav); break; - case 18: stat=decode_sbstype18(msg,nav ->sbsion); break; - case 24: stat=decode_sbstype24(msg,&nav->sbssat); break; - case 25: stat=decode_sbstype25(msg,&nav->sbssat); break; - case 26: stat=decode_sbstype26(msg,nav ->sbsion); break; - case 63: break; /* null message */ - - /*default: trace(2,"unsupported sbas message: type=%d\n",type); break;*/ - } - return stat?type:-1; + * update sbas correction parameters in navigation data with a sbas message + * args : sbsmg_t *msg I sbas message + * nav_t *nav IO navigation data + * return : message type (-1: error or not supported type) + * notes : nav->seph must point to seph[NSATSBS*2] (array of seph_t) + * seph[prn-MINPRNSBS+1] : sat prn current epehmeris + * seph[prn-MINPRNSBS+1+MAXPRNSBS]: sat prn previous epehmeris + *-----------------------------------------------------------------------------*/ +extern int sbsupdatecorr(const sbsmsg_t *msg, nav_t *nav) { + int type = getbitu(msg->msg, 8, 6), stat = -1; + + trace(3, "sbsupdatecorr: type=%d\n", type); + + if (msg->week == 0) return -1; + + switch (type) { + case 0: + stat = decode_sbstype2(msg, &nav->sbssat); + break; + case 1: + stat = decode_sbstype1(msg, &nav->sbssat); + break; + case 2: + case 3: + case 4: + case 5: + stat = decode_sbstype2(msg, &nav->sbssat); + break; + case 6: + stat = decode_sbstype6(msg, &nav->sbssat); + break; + case 7: + stat = decode_sbstype7(msg, &nav->sbssat); + break; + case 9: + stat = decode_sbstype9(msg, nav); + break; + case 18: + stat = decode_sbstype18(msg, nav->sbsion); + break; + case 24: + stat = decode_sbstype24(msg, &nav->sbssat); + break; + case 25: + stat = decode_sbstype25(msg, &nav->sbssat); + break; + case 26: + stat = decode_sbstype26(msg, nav->sbsion); + break; + case 63: + break; /* null message */ + + /*default: trace(2,"unsupported sbas message: type=%d\n",type); break;*/ + } + return stat ? type : -1; } /* read sbas log file --------------------------------------------------------*/ -static void readmsgs(const char *file, int sel, gtime_t ts, gtime_t te, - sbs_t *sbs) -{ - sbsmsg_t *sbs_msgs; - int i,week,prn,ch,msg; - uint32_t b; - double tow,ep[6]={0}; - char buff[256],*p; - gtime_t time; - FILE *fp; - - trace(3,"readmsgs: file=%s sel=%d\n",file,sel); - - if (!(fp=fopen(file,"r"))) { - trace(2,"sbas message file open error: %s\n",file); +static void readmsgs(const char *file, int sel, gtime_t ts, gtime_t te, sbs_t *sbs) { + sbsmsg_t *sbs_msgs; + int i, week, prn, ch, msg; + uint32_t b; + double tow, ep[6] = {0}; + char buff[256], *p; + gtime_t time; + FILE *fp; + + trace(3, "readmsgs: file=%s sel=%d\n", file, sel); + + if (!(fp = fopen(file, "r"))) { + trace(2, "sbas message file open error: %s\n", file); + return; + } + while (fgets(buff, sizeof(buff), fp)) { + if (sscanf(buff, "%d %lf %d", &week, &tow, &prn) == 3 && (p = strstr(buff, ": "))) { + p += 2; /* rtklib form */ + } else if (sscanf(buff, "%d %lf %lf %lf %lf %lf %lf %d", &prn, ep, ep + 1, ep + 2, ep + 3, + ep + 4, ep + 5, &msg) == 8) { + /* ems (EGNOS Message Service) form */ + ep[0] += ep[0] < 70.0 ? 2000.0 : 1900.0; + tow = time2gpst(epoch2time(ep), &week); + p = buff + (msg >= 10 ? 25 : 24); + } else if (!strncmp(buff, "#RAWWAASFRAMEA", 14)) { /* NovAtel OEM4/V */ + if (!(p = getfield(buff, 6))) continue; + if (sscanf(p, "%d,%lf", &week, &tow) < 2) continue; + if (!(p = strchr(++p, ';'))) continue; + if (sscanf(++p, "%d,%d", &ch, &prn) < 2) continue; + if (!(p = getfield(p, 4))) continue; + } else if (!strncmp(buff, "$FRMA", 5)) { /* NovAtel OEM3 */ + if (!(p = getfield(buff, 2))) continue; + if (sscanf(p, "%d,%lf,%d", &week, &tow, &prn) < 3) continue; + if (!(p = getfield(p, 6))) continue; + if (week < WEEKOFFSET) week += WEEKOFFSET; + } else + continue; + + if (sel != 0 && sel != prn) continue; + + time = gpst2time(week, tow); + + if (!screent(time, ts, te, 0.0)) continue; + + if (sbs->n >= sbs->nmax) { + sbs->nmax = sbs->nmax == 0 ? 1024 : sbs->nmax * 2; + if (!(sbs_msgs = (sbsmsg_t *)realloc(sbs->msgs, sbs->nmax * sizeof(sbsmsg_t)))) { + trace(1, "readsbsmsg malloc error: nmax=%d\n", sbs->nmax); + free(sbs->msgs); + sbs->msgs = NULL; + sbs->n = sbs->nmax = 0; + fclose(fp); return; + } + sbs->msgs = sbs_msgs; } - while (fgets(buff,sizeof(buff),fp)) { - if (sscanf(buff,"%d %lf %d",&week,&tow,&prn)==3&&(p=strstr(buff,": "))) { - p+=2; /* rtklib form */ - } - else if (sscanf(buff,"%d %lf %lf %lf %lf %lf %lf %d", - &prn,ep,ep+1,ep+2,ep+3,ep+4,ep+5,&msg)==8) { - /* ems (EGNOS Message Service) form */ - ep[0]+=ep[0]<70.0?2000.0:1900.0; - tow=time2gpst(epoch2time(ep),&week); - p=buff+(msg>=10?25:24); - } - else if (!strncmp(buff,"#RAWWAASFRAMEA",14)) { /* NovAtel OEM4/V */ - if (!(p=getfield(buff,6))) continue; - if (sscanf(p,"%d,%lf",&week,&tow)<2) continue; - if (!(p=strchr(++p,';'))) continue; - if (sscanf(++p,"%d,%d",&ch,&prn)<2) continue; - if (!(p=getfield(p,4))) continue; - } - else if (!strncmp(buff,"$FRMA",5)) { /* NovAtel OEM3 */ - if (!(p=getfield(buff,2))) continue; - if (sscanf(p,"%d,%lf,%d",&week,&tow,&prn)<3) continue; - if (!(p=getfield(p,6))) continue; - if (weekn>=sbs->nmax) { - sbs->nmax=sbs->nmax==0?1024:sbs->nmax*2; - if (!(sbs_msgs=(sbsmsg_t *)realloc(sbs->msgs,sbs->nmax*sizeof(sbsmsg_t)))) { - trace(1,"readsbsmsg malloc error: nmax=%d\n",sbs->nmax); - free(sbs->msgs); sbs->msgs=NULL; sbs->n=sbs->nmax=0; - fclose(fp); - return; - } - sbs->msgs=sbs_msgs; - } - sbs->msgs[sbs->n].week=week; - sbs->msgs[sbs->n].tow=(int)(tow+0.5); - sbs->msgs[sbs->n].prn=prn; - for (i=0;i<29;i++) sbs->msgs[sbs->n].msg[i]=0; - for (i=0;*(p-1)&&*p&&i<29;p+=2,i++) { - if (sscanf(p,"%2X",&b)==1) sbs->msgs[sbs->n].msg[i]=(uint8_t)b; - } - sbs->msgs[sbs->n++].msg[28]&=0xC0; + sbs->msgs[sbs->n].week = week; + sbs->msgs[sbs->n].tow = (int)(tow + 0.5); + sbs->msgs[sbs->n].prn = prn; + for (i = 0; i < 29; i++) sbs->msgs[sbs->n].msg[i] = 0; + for (i = 0; *(p - 1) && *p && i < 29; p += 2, i++) { + if (sscanf(p, "%2X", &b) == 1) sbs->msgs[sbs->n].msg[i] = (uint8_t)b; } - fclose(fp); + sbs->msgs[sbs->n++].msg[28] &= 0xC0; + } + fclose(fp); } /* compare sbas messages -----------------------------------------------------*/ -static int cmpmsgs(const void *p1, const void *p2) -{ - sbsmsg_t *q1=(sbsmsg_t *)p1,*q2=(sbsmsg_t *)p2; - return q1->week!=q2->week?q1->week-q2->week: - (q1->towtow?-1:(q1->tow>q2->tow?1:q1->prn-q2->prn)); +static int cmpmsgs(const void *p1, const void *p2) { + sbsmsg_t *q1 = (sbsmsg_t *)p1, *q2 = (sbsmsg_t *)p2; + return q1->week != q2->week + ? q1->week - q2->week + : (q1->tow < q2->tow ? -1 : (q1->tow > q2->tow ? 1 : q1->prn - q2->prn)); } /* read sbas message file ------------------------------------------------------ -* read sbas message file -* args : char *file I sbas message file (wild-card * is expanded) -* int sel I sbas satellite prn number selection (0:all) -* (gtime_t ts I start time) -* (gtime_t te I end time ) -* sbs_t *sbs IO sbas messages -* return : number of sbas messages -* notes : sbas message are appended and sorted. before calling the funciton, -* sbs->n, sbs->nmax and sbs->msgs must be set properly. (initially -* sbs->n=sbs->nmax=0, sbs->msgs=NULL) -* only the following file extentions after wild card expanded are valid -* to read. others are skipped -* .sbs, .SBS, .ems, .EMS -*-----------------------------------------------------------------------------*/ -extern int sbsreadmsgt(const char *file, int sel, gtime_t ts, gtime_t te, - sbs_t *sbs) -{ - char *efiles[MAXEXFILE]={0},*ext; - int i,n; - - trace(3,"sbsreadmsgt: file=%s sel=%d\n",file,sel); - - for (i=0;i=0;i--) free(efiles[i]); - return 0; - } - } - /* expand wild card in file path */ - n=expath(file,efiles,MAXEXFILE); - - for (i=0;in>0) { - qsort(sbs->msgs,sbs->n,sizeof(sbsmsg_t),cmpmsgs); + * read sbas message file + * args : char *file I sbas message file (wild-card * is expanded) + * int sel I sbas satellite prn number selection (0:all) + * (gtime_t ts I start time) + * (gtime_t te I end time ) + * sbs_t *sbs IO sbas messages + * return : number of sbas messages + * notes : sbas message are appended and sorted. before calling the funciton, + * sbs->n, sbs->nmax and sbs->msgs must be set properly. (initially + * sbs->n=sbs->nmax=0, sbs->msgs=NULL) + * only the following file extentions after wild card expanded are valid + * to read. others are skipped + * .sbs, .SBS, .ems, .EMS + *-----------------------------------------------------------------------------*/ +extern int sbsreadmsgt(const char *file, int sel, gtime_t ts, gtime_t te, sbs_t *sbs) { + char *efiles[MAXEXFILE] = {0}, *ext; + int i, n; + + trace(3, "sbsreadmsgt: file=%s sel=%d\n", file, sel); + + for (i = 0; i < MAXEXFILE; i++) { + if (!(efiles[i] = (char *)malloc(1024))) { + for (i--; i >= 0; i--) free(efiles[i]); + return 0; } - return sbs->n; + } + /* expand wild card in file path */ + n = expath(file, efiles, MAXEXFILE); + + for (i = 0; i < n; i++) { + if (!(ext = strrchr(efiles[i], '.'))) continue; + if (strcmp(ext, ".sbs") && strcmp(ext, ".SBS") && strcmp(ext, ".ems") && strcmp(ext, ".EMS")) + continue; + + readmsgs(efiles[i], sel, ts, te, sbs); + } + for (i = 0; i < MAXEXFILE; i++) free(efiles[i]); + + /* sort messages */ + if (sbs->n > 0) { + qsort(sbs->msgs, sbs->n, sizeof(sbsmsg_t), cmpmsgs); + } + return sbs->n; } -extern int sbsreadmsg(const char *file, int sel, sbs_t *sbs) -{ - gtime_t ts={0},te={0}; - - trace(3,"sbsreadmsg: file=%s sel=%d\n",file,sel); - - return sbsreadmsgt(file,sel,ts,te,sbs); +extern int sbsreadmsg(const char *file, int sel, sbs_t *sbs) { + gtime_t ts = {0}, te = {0}; + + trace(3, "sbsreadmsg: file=%s sel=%d\n", file, sel); + + return sbsreadmsgt(file, sel, ts, te, sbs); } /* output sbas messages -------------------------------------------------------- -* output sbas message record to output file in rtklib sbas log format -* args : FILE *fp I output file pointer -* sbsmsg_t *sbsmsg I sbas messages -* return : none -*-----------------------------------------------------------------------------*/ -extern void sbsoutmsg(FILE *fp, sbsmsg_t *sbsmsg) -{ - int i,prn=sbsmsg->prn,type=sbsmsg->msg[1]>>2; - - trace(4,"sbsoutmsg:\n"); - - fprintf(fp,"%4d %6d %3d %2d : ",sbsmsg->week,sbsmsg->tow,prn,type); - for (i=0;i<29;i++) fprintf(fp,"%02X",sbsmsg->msg[i]); - fprintf(fp,"\n"); + * output sbas message record to output file in rtklib sbas log format + * args : FILE *fp I output file pointer + * sbsmsg_t *sbsmsg I sbas messages + * return : none + *-----------------------------------------------------------------------------*/ +extern void sbsoutmsg(FILE *fp, sbsmsg_t *sbsmsg) { + int i, prn = sbsmsg->prn, type = sbsmsg->msg[1] >> 2; + + trace(4, "sbsoutmsg:\n"); + + fprintf(fp, "%4d %6d %3d %2d : ", sbsmsg->week, sbsmsg->tow, prn, type); + for (i = 0; i < 29; i++) fprintf(fp, "%02X", sbsmsg->msg[i]); + fprintf(fp, "\n"); } /* search igps ---------------------------------------------------------------*/ -static void searchigp(gtime_t time, const double *pos, const sbsion_t *ion, - const sbsigp_t **igp, double *x, double *y) -{ - (void)time; - int i,latp[2],lonp[4]; - double lat=pos[0]*R2D,lon=pos[1]*R2D; - const sbsigp_t *p; - - trace(4,"searchigp: pos=%.3f %.3f\n",pos[0]*R2D,pos[1]*R2D); - - if (lon>=180.0) lon-=360.0; - if (-55.0<=lat&&lat<55.0) { - latp[0]=(int)floor(lat/5.0)*5; - latp[1]=latp[0]+5; - lonp[0]=lonp[1]=(int)floor(lon/5.0)*5; - lonp[2]=lonp[3]=lonp[0]+5; - *x=(lon-lonp[0])/5.0; - *y=(lat-latp[0])/5.0; - } - else { - latp[0]=(int)floor((lat-5.0)/10.0)*10+5; - latp[1]=latp[0]+10; - lonp[0]=lonp[1]=(int)floor(lon/10.0)*10; - lonp[2]=lonp[3]=lonp[0]+10; - *x=(lon-lonp[0])/10.0; - *y=(lat-latp[0])/10.0; - if (75.0<=lat&&lat<85.0) { - lonp[1]=(int)floor(lon/90.0)*90; - lonp[3]=lonp[1]+90; - } - else if (-85.0<=lat&&lat<-75.0) { - lonp[0]=(int)floor((lon-50.0)/90.0)*90+40; - lonp[2]=lonp[0]+90; - } - else if (lat>=85.0) { - for (i=0;i<4;i++) lonp[i]=(int)floor(lon/90.0)*90; - } - else if (lat<-85.0) { - for (i=0;i<4;i++) lonp[i]=(int)floor((lon-50.0)/90.0)*90+40; - } +static void searchigp(gtime_t time, const double *pos, const sbsion_t *ion, const sbsigp_t **igp, + double *x, double *y) { + (void)time; + int i, latp[2], lonp[4]; + double lat = pos[0] * R2D, lon = pos[1] * R2D; + const sbsigp_t *p; + + trace(4, "searchigp: pos=%.3f %.3f\n", pos[0] * R2D, pos[1] * R2D); + + if (lon >= 180.0) lon -= 360.0; + if (-55.0 <= lat && lat < 55.0) { + latp[0] = (int)floor(lat / 5.0) * 5; + latp[1] = latp[0] + 5; + lonp[0] = lonp[1] = (int)floor(lon / 5.0) * 5; + lonp[2] = lonp[3] = lonp[0] + 5; + *x = (lon - lonp[0]) / 5.0; + *y = (lat - latp[0]) / 5.0; + } else { + latp[0] = (int)floor((lat - 5.0) / 10.0) * 10 + 5; + latp[1] = latp[0] + 10; + lonp[0] = lonp[1] = (int)floor(lon / 10.0) * 10; + lonp[2] = lonp[3] = lonp[0] + 10; + *x = (lon - lonp[0]) / 10.0; + *y = (lat - latp[0]) / 10.0; + if (75.0 <= lat && lat < 85.0) { + lonp[1] = (int)floor(lon / 90.0) * 90; + lonp[3] = lonp[1] + 90; + } else if (-85.0 <= lat && lat < -75.0) { + lonp[0] = (int)floor((lon - 50.0) / 90.0) * 90 + 40; + lonp[2] = lonp[0] + 90; + } else if (lat >= 85.0) { + for (i = 0; i < 4; i++) lonp[i] = (int)floor(lon / 90.0) * 90; + } else if (lat < -85.0) { + for (i = 0; i < 4; i++) lonp[i] = (int)floor((lon - 50.0) / 90.0) * 90 + 40; } - for (i=0;i<4;i++) if (lonp[i]==180) lonp[i]=-180; - for (i=0;i<=MAXBAND;i++) { - for (p=ion[i].igp;pt0.time==0) continue; - if (p->lat==latp[0]&&p->lon==lonp[0]&&p->give>0) igp[0]=p; - else if (p->lat==latp[1]&&p->lon==lonp[1]&&p->give>0) igp[1]=p; - else if (p->lat==latp[0]&&p->lon==lonp[2]&&p->give>0) igp[2]=p; - else if (p->lat==latp[1]&&p->lon==lonp[3]&&p->give>0) igp[3]=p; - if (igp[0]&&igp[1]&&igp[2]&&igp[3]) return; - } + } + for (i = 0; i < 4; i++) + if (lonp[i] == 180) lonp[i] = -180; + for (i = 0; i <= MAXBAND; i++) { + for (p = ion[i].igp; p < ion[i].igp + ion[i].nigp; p++) { + if (p->t0.time == 0) continue; + if (p->lat == latp[0] && p->lon == lonp[0] && p->give > 0) + igp[0] = p; + else if (p->lat == latp[1] && p->lon == lonp[1] && p->give > 0) + igp[1] = p; + else if (p->lat == latp[0] && p->lon == lonp[2] && p->give > 0) + igp[2] = p; + else if (p->lat == latp[1] && p->lon == lonp[3] && p->give > 0) + igp[3] = p; + if (igp[0] && igp[1] && igp[2] && igp[3]) return; } + } } /* sbas ionospheric delay correction ------------------------------------------- -* compute sbas ionosphric delay correction -* args : gtime_t time I time -* nav_t *nav I navigation data -* double *pos I receiver position {lat,lon,height} (rad/m) -* double *azel I satellite azimuth/elavation angle (rad) -* double *delay O slant ionospheric delay (L1) (m) -* double *var O variance of ionospheric delay (m^2) -* return : status (1:ok, 0:no correction) -* notes : before calling the function, sbas ionosphere correction parameters -* in navigation data (nav->sbsion) must be set by callig -* sbsupdatecorr() -*-----------------------------------------------------------------------------*/ -extern int sbsioncorr(gtime_t time, const nav_t *nav, const double *pos, - const double *azel, double *delay, double *var) -{ - const double re=6378.1363,hion=350.0; - int i,err=0; - double fp,posp[2],x=0.0,y=0.0,t,w[4]={0}; - const sbsigp_t *igp[4]={0}; /* {ws,wn,es,en} */ - - trace(4,"sbsioncorr: pos=%.3f %.3f azel=%.3f %.3f\n",pos[0]*R2D,pos[1]*R2D, - azel[0]*R2D,azel[1]*R2D); - - *delay=*var=0.0; - if (pos[2]<-100.0||azel[1]<=0) return 1; - - /* ipp (ionospheric pierce point) position */ - fp=ionppp(pos,azel,re,hion,posp); - - /* search igps around ipp */ - searchigp(time,posp,nav->sbsion,igp,&x,&y); - - /* weight of igps */ - if (igp[0]&&igp[1]&&igp[2]&&igp[3]) { - w[0]=(1.0-x)*(1.0-y); w[1]=(1.0-x)*y; w[2]=x*(1.0-y); w[3]=x*y; - } - else if (igp[0]&&igp[1]&&igp[2]) { - w[1]=y; w[2]=x; - if ((w[0]=1.0-w[1]-w[2])<0.0) err=1; - } - else if (igp[0]&&igp[2]&&igp[3]) { - w[0]=1.0-x; w[3]=y; - if ((w[2]=1.0-w[0]-w[3])<0.0) err=1; - } - else if (igp[0]&&igp[1]&&igp[3]) { - w[0]=1.0-y; w[3]=x; - if ((w[1]=1.0-w[0]-w[3])<0.0) err=1; - } - else if (igp[1]&&igp[2]&&igp[3]) { - w[1]=1.0-x; w[2]=1.0-y; - if ((w[3]=1.0-w[1]-w[2])<0.0) err=1; - } - else err=1; - - if (err) { - trace(2,"no sbas iono correction: lat=%3.0f lon=%4.0f\n",posp[0]*R2D, - posp[1]*R2D); - return 0; - } - for (i=0;i<4;i++) { - if (!igp[i]) continue; - t=timediff(time,igp[i]->t0); - *delay+=w[i]*igp[i]->delay; - *var+=w[i]*varicorr(igp[i]->give)*9E-8*fabs(t); - } - *delay*=fp; *var*=fp*fp; - - trace(5,"sbsioncorr: dion=%7.2f sig=%7.2f\n",*delay,sqrt(*var)); - return 1; + * compute sbas ionosphric delay correction + * args : gtime_t time I time + * nav_t *nav I navigation data + * double *pos I receiver position {lat,lon,height} (rad/m) + * double *azel I satellite azimuth/elavation angle (rad) + * double *delay O slant ionospheric delay (L1) (m) + * double *var O variance of ionospheric delay (m^2) + * return : status (1:ok, 0:no correction) + * notes : before calling the function, sbas ionosphere correction parameters + * in navigation data (nav->sbsion) must be set by callig + * sbsupdatecorr() + *-----------------------------------------------------------------------------*/ +extern int sbsioncorr(gtime_t time, const nav_t *nav, const double *pos, const double *azel, + double *delay, double *var) { + const double re = 6378.1363, hion = 350.0; + int i, err = 0; + double fp, posp[2], x = 0.0, y = 0.0, t, w[4] = {0}; + const sbsigp_t *igp[4] = {0}; /* {ws,wn,es,en} */ + + trace(4, "sbsioncorr: pos=%.3f %.3f azel=%.3f %.3f\n", pos[0] * R2D, pos[1] * R2D, azel[0] * R2D, + azel[1] * R2D); + + *delay = *var = 0.0; + if (pos[2] < -100.0 || azel[1] <= 0) return 1; + + /* ipp (ionospheric pierce point) position */ + fp = ionppp(pos, azel, re, hion, posp); + + /* search igps around ipp */ + searchigp(time, posp, nav->sbsion, igp, &x, &y); + + /* weight of igps */ + if (igp[0] && igp[1] && igp[2] && igp[3]) { + w[0] = (1.0 - x) * (1.0 - y); + w[1] = (1.0 - x) * y; + w[2] = x * (1.0 - y); + w[3] = x * y; + } else if (igp[0] && igp[1] && igp[2]) { + w[1] = y; + w[2] = x; + if ((w[0] = 1.0 - w[1] - w[2]) < 0.0) err = 1; + } else if (igp[0] && igp[2] && igp[3]) { + w[0] = 1.0 - x; + w[3] = y; + if ((w[2] = 1.0 - w[0] - w[3]) < 0.0) err = 1; + } else if (igp[0] && igp[1] && igp[3]) { + w[0] = 1.0 - y; + w[3] = x; + if ((w[1] = 1.0 - w[0] - w[3]) < 0.0) err = 1; + } else if (igp[1] && igp[2] && igp[3]) { + w[1] = 1.0 - x; + w[2] = 1.0 - y; + if ((w[3] = 1.0 - w[1] - w[2]) < 0.0) err = 1; + } else + err = 1; + + if (err) { + trace(2, "no sbas iono correction: lat=%3.0f lon=%4.0f\n", posp[0] * R2D, posp[1] * R2D); + return 0; + } + for (i = 0; i < 4; i++) { + if (!igp[i]) continue; + t = timediff(time, igp[i]->t0); + *delay += w[i] * igp[i]->delay; + *var += w[i] * varicorr(igp[i]->give) * 9E-8 * fabs(t); + } + *delay *= fp; + *var *= fp * fp; + + trace(5, "sbsioncorr: dion=%7.2f sig=%7.2f\n", *delay, sqrt(*var)); + return 1; } /* get meterological parameters ----------------------------------------------*/ -static void getmet(double lat, double *met) -{ - static const double metprm[][10]={ /* lat=15,30,45,60,75 */ - {1013.25,299.65,26.31,6.30E-3,2.77, 0.00, 0.00,0.00,0.00E-3,0.00}, - {1017.25,294.15,21.79,6.05E-3,3.15, -3.75, 7.00,8.85,0.25E-3,0.33}, - {1015.75,283.15,11.66,5.58E-3,2.57, -2.25,11.00,7.24,0.32E-3,0.46}, - {1011.75,272.15, 6.78,5.39E-3,1.81, -1.75,15.00,5.36,0.81E-3,0.74}, - {1013.00,263.65, 4.11,4.53E-3,1.55, -0.50,14.50,3.39,0.62E-3,0.30} - }; - int i,j; - double a; - lat=fabs(lat); - if (lat<=15.0) for (i=0;i<10;i++) met[i]=metprm[0][i]; - else if (lat>=75.0) for (i=0;i<10;i++) met[i]=metprm[4][i]; - else { - j=(int)(lat/15.0); a=(lat-j*15.0)/15.0; - for (i=0;i<10;i++) met[i]=(1.0-a)*metprm[j-1][i]+a*metprm[j][i]; - } +static void getmet(double lat, double *met) { + static const double metprm[][10] = { + /* lat=15,30,45,60,75 */ + {1013.25, 299.65, 26.31, 6.30E-3, 2.77, 0.00, 0.00, 0.00, 0.00E-3, 0.00}, + {1017.25, 294.15, 21.79, 6.05E-3, 3.15, -3.75, 7.00, 8.85, 0.25E-3, 0.33}, + {1015.75, 283.15, 11.66, 5.58E-3, 2.57, -2.25, 11.00, 7.24, 0.32E-3, 0.46}, + {1011.75, 272.15, 6.78, 5.39E-3, 1.81, -1.75, 15.00, 5.36, 0.81E-3, 0.74}, + {1013.00, 263.65, 4.11, 4.53E-3, 1.55, -0.50, 14.50, 3.39, 0.62E-3, 0.30}}; + int i, j; + double a; + lat = fabs(lat); + if (lat <= 15.0) + for (i = 0; i < 10; i++) met[i] = metprm[0][i]; + else if (lat >= 75.0) + for (i = 0; i < 10; i++) met[i] = metprm[4][i]; + else { + j = (int)(lat / 15.0); + a = (lat - j * 15.0) / 15.0; + for (i = 0; i < 10; i++) met[i] = (1.0 - a) * metprm[j - 1][i] + a * metprm[j][i]; + } } /* Tropospheric delay correction ----------------------------------------------- * Compute SBAS tropospheric delay correction (mops model) @@ -785,140 +852,133 @@ extern double sbstropcorr(gtime_t time, const double *pos, const double *azel, d return (zh + zw) * m; } /* long term correction ------------------------------------------------------*/ -static int sbslongcorr(gtime_t time, int sat, const sbssat_t *sbssat, - double *drs, double *ddts) -{ - const sbssatp_t *p; - double t; - int i; - - trace(3,"sbslongcorr: sat=%2d\n",sat); - - for (p=sbssat->sat;psat+sbssat->nsat;p++) { - if (p->sat!=sat||p->lcorr.t0.time==0) continue; - t=timediff(time,p->lcorr.t0); - if (fabs(t)>MAXSBSAGEL) { - char tstr[40]; - trace(2,"sbas long-term correction expired: %s sat=%2d t=%5.0f\n", - time2str(time,tstr,0),sat,t); - return 0; - } - for (i=0;i<3;i++) drs[i]=p->lcorr.dpos[i]+p->lcorr.dvel[i]*t; - *ddts=p->lcorr.daf0+p->lcorr.daf1*t; - - trace(5,"sbslongcorr: sat=%2d drs=%7.2f%7.2f%7.2f ddts=%7.2f\n", - sat,drs[0],drs[1],drs[2],*ddts*CLIGHT); - - return 1; - } - /* if sbas satellite without correction, no correction applied */ - if (satsys(sat,NULL)==SYS_SBS) return 1; - - char tstr[40]; - trace(2,"no sbas long-term correction: %s sat=%2d\n",time2str(time,tstr,0),sat); - return 0; +static int sbslongcorr(gtime_t time, int sat, const sbssat_t *sbssat, double *drs, double *ddts) { + const sbssatp_t *p; + double t; + int i; + + trace(3, "sbslongcorr: sat=%2d\n", sat); + + for (p = sbssat->sat; p < sbssat->sat + sbssat->nsat; p++) { + if (p->sat != sat || p->lcorr.t0.time == 0) continue; + t = timediff(time, p->lcorr.t0); + if (fabs(t) > MAXSBSAGEL) { + char tstr[40]; + trace(2, "sbas long-term correction expired: %s sat=%2d t=%5.0f\n", time2str(time, tstr, 0), + sat, t); + return 0; + } + for (i = 0; i < 3; i++) drs[i] = p->lcorr.dpos[i] + p->lcorr.dvel[i] * t; + *ddts = p->lcorr.daf0 + p->lcorr.daf1 * t; + + trace(5, "sbslongcorr: sat=%2d drs=%7.2f%7.2f%7.2f ddts=%7.2f\n", sat, drs[0], drs[1], drs[2], + *ddts * CLIGHT); + + return 1; + } + /* if sbas satellite without correction, no correction applied */ + if (satsys(sat, NULL) == SYS_SBS) return 1; + + char tstr[40]; + trace(2, "no sbas long-term correction: %s sat=%2d\n", time2str(time, tstr, 0), sat); + return 0; } /* fast correction -----------------------------------------------------------*/ -static int sbsfastcorr(gtime_t time, int sat, const sbssat_t *sbssat, - double *prc, double *var) -{ - const sbssatp_t *p; - double t; - - trace(3,"sbsfastcorr: sat=%2d\n",sat); - - for (p=sbssat->sat;psat+sbssat->nsat;p++) { - if (p->sat!=sat) continue; - if (p->fcorr.t0.time==0) break; - t=timediff(time,p->fcorr.t0)+sbssat->tlat; - - /* expire age of correction or UDRE==14 (not monitored) */ - if (fabs(t)>MAXSBSAGEF||p->fcorr.udre>=15) continue; - *prc=p->fcorr.prc; +static int sbsfastcorr(gtime_t time, int sat, const sbssat_t *sbssat, double *prc, double *var) { + const sbssatp_t *p; + double t; + + trace(3, "sbsfastcorr: sat=%2d\n", sat); + + for (p = sbssat->sat; p < sbssat->sat + sbssat->nsat; p++) { + if (p->sat != sat) continue; + if (p->fcorr.t0.time == 0) break; + t = timediff(time, p->fcorr.t0) + sbssat->tlat; + + /* expire age of correction or UDRE==14 (not monitored) */ + if (fabs(t) > MAXSBSAGEF || p->fcorr.udre >= 15) continue; + *prc = p->fcorr.prc; #ifdef RRCENA - if (p->fcorr.ai>0&&fabs(t)<=8.0*p->fcorr.dt) { - *prc+=p->fcorr.rrc*t; - } -#endif - *var=varfcorr(p->fcorr.udre)+degfcorr(p->fcorr.ai)*t*t/2.0; - - trace(5,"sbsfastcorr: sat=%3d prc=%7.2f sig=%7.2f t=%5.0f\n",sat, - *prc,sqrt(*var),t); - return 1; + if (p->fcorr.ai > 0 && fabs(t) <= 8.0 * p->fcorr.dt) { + *prc += p->fcorr.rrc * t; } - char tstr[40]; - trace(2,"no sbas fast correction: %s sat=%2d\n",time2str(time,tstr,0),sat); - return 0; +#endif + *var = varfcorr(p->fcorr.udre) + degfcorr(p->fcorr.ai) * t * t / 2.0; + + trace(5, "sbsfastcorr: sat=%3d prc=%7.2f sig=%7.2f t=%5.0f\n", sat, *prc, sqrt(*var), t); + return 1; + } + char tstr[40]; + trace(2, "no sbas fast correction: %s sat=%2d\n", time2str(time, tstr, 0), sat); + return 0; } /* sbas satellite ephemeris and clock correction ------------------------------- -* correct satellite position and clock bias with sbas satellite corrections -* args : gtime_t time I reception time -* int sat I satellite -* nav_t *nav I navigation data -* double *rs IO sat position and corrected {x,y,z} (ecef) (m) -* double *dts IO sat clock bias and corrected (s) -* double *var O sat position and clock variance (m^2) -* return : status (1:ok,0:no correction) -* notes : before calling the function, sbas satellite correction parameters -* in navigation data (nav->sbssat) must be set by callig -* sbsupdatecorr(). -* satellite clock correction include long-term correction and fast -* correction. -* sbas clock correction is usually based on L1C/A code. TGD or DCB has -* to be considered for other codes -*-----------------------------------------------------------------------------*/ -extern int sbssatcorr(gtime_t time, int sat, const nav_t *nav, double *rs, - double *dts, double *var) -{ - double drs[3]={0},dclk=0.0,prc=0.0; - int i; - - trace(3,"sbssatcorr : sat=%2d\n",sat); - - /* sbas long term corrections */ - if (!sbslongcorr(time,sat,&nav->sbssat,drs,&dclk)) { - return 0; - } - /* sbas fast corrections */ - if (!sbsfastcorr(time,sat,&nav->sbssat,&prc,var)) { - return 0; - } - for (i=0;i<3;i++) rs[i]+=drs[i]; - - dts[0]+=dclk+prc/CLIGHT; - - trace(4,"sbssatcorr: sat=%2d drs=%6.3f %6.3f %6.3f dclk=%.3f %.3f var=%.3f\n", - sat,drs[0],drs[1],drs[2],dclk,prc/CLIGHT,*var); - - return 1; + * correct satellite position and clock bias with sbas satellite corrections + * args : gtime_t time I reception time + * int sat I satellite + * nav_t *nav I navigation data + * double *rs IO sat position and corrected {x,y,z} (ecef) (m) + * double *dts IO sat clock bias and corrected (s) + * double *var O sat position and clock variance (m^2) + * return : status (1:ok,0:no correction) + * notes : before calling the function, sbas satellite correction parameters + * in navigation data (nav->sbssat) must be set by callig + * sbsupdatecorr(). + * satellite clock correction include long-term correction and fast + * correction. + * sbas clock correction is usually based on L1C/A code. TGD or DCB has + * to be considered for other codes + *-----------------------------------------------------------------------------*/ +extern int sbssatcorr(gtime_t time, int sat, const nav_t *nav, double *rs, double *dts, + double *var) { + double drs[3] = {0}, dclk = 0.0, prc = 0.0; + int i; + + trace(3, "sbssatcorr : sat=%2d\n", sat); + + /* sbas long term corrections */ + if (!sbslongcorr(time, sat, &nav->sbssat, drs, &dclk)) { + return 0; + } + /* sbas fast corrections */ + if (!sbsfastcorr(time, sat, &nav->sbssat, &prc, var)) { + return 0; + } + for (i = 0; i < 3; i++) rs[i] += drs[i]; + + dts[0] += dclk + prc / CLIGHT; + + trace(4, "sbssatcorr: sat=%2d drs=%6.3f %6.3f %6.3f dclk=%.3f %.3f var=%.3f\n", sat, drs[0], + drs[1], drs[2], dclk, prc / CLIGHT, *var); + + return 1; } /* decode sbas message --------------------------------------------------------- -* decode sbas message frame words and check crc -* args : gtime_t time I reception time -* int prn I sbas satellite prn number -* uint32_t *word I message frame words (24bit x 10) -* sbsmsg_t *sbsmsg O sbas message -* return : status (1:ok,0:crc error) -*-----------------------------------------------------------------------------*/ -extern int sbsdecodemsg(gtime_t time, int prn, const uint32_t *words, - sbsmsg_t *sbsmsg) -{ - int i,j; - uint8_t f[29]; - double tow; - - trace(5,"sbsdecodemsg: prn=%d\n",prn); - - if (time.time==0) return 0; - tow=time2gpst(time,&sbsmsg->week); - sbsmsg->tow=(int)(tow+DTTOL); - sbsmsg->prn=prn; - for (i=0;i<7;i++) for (j=0;j<4;j++) { - sbsmsg->msg[i*4+j]=(uint8_t)(words[i]>>((3-j)*8)); - } - sbsmsg->msg[28]=(uint8_t)(words[7]>>18)&0xC0; - for (i=28;i>0;i--) f[i]=(sbsmsg->msg[i]>>6)+(sbsmsg->msg[i-1]<<2); - f[0]=sbsmsg->msg[0]>>6; - - return rtk_crc24q(f,29)==(words[7]&0xFFFFFF); /* check crc */ + * decode sbas message frame words and check crc + * args : gtime_t time I reception time + * int prn I sbas satellite prn number + * uint32_t *word I message frame words (24bit x 10) + * sbsmsg_t *sbsmsg O sbas message + * return : status (1:ok,0:crc error) + *-----------------------------------------------------------------------------*/ +extern int sbsdecodemsg(gtime_t time, int prn, const uint32_t *words, sbsmsg_t *sbsmsg) { + int i, j; + uint8_t f[29]; + double tow; + + trace(5, "sbsdecodemsg: prn=%d\n", prn); + + if (time.time == 0) return 0; + tow = time2gpst(time, &sbsmsg->week); + sbsmsg->tow = (int)(tow + DTTOL); + sbsmsg->prn = prn; + for (i = 0; i < 7; i++) + for (j = 0; j < 4; j++) { + sbsmsg->msg[i * 4 + j] = (uint8_t)(words[i] >> ((3 - j) * 8)); + } + sbsmsg->msg[28] = (uint8_t)(words[7] >> 18) & 0xC0; + for (i = 28; i > 0; i--) f[i] = (sbsmsg->msg[i] >> 6) + (sbsmsg->msg[i - 1] << 2); + f[0] = sbsmsg->msg[0] >> 6; + + return rtk_crc24q(f, 29) == (words[7] & 0xFFFFFF); /* check crc */ } diff --git a/src/solution.c b/src/solution.c index 37ed4e20d..ed1c20fd6 100644 --- a/src/solution.c +++ b/src/solution.c @@ -1,66 +1,67 @@ /*------------------------------------------------------------------------------ -* solution.c : solution functions -* -* Copyright (C) 2007-2020 by T.TAKASU, All rights reserved. -* -* references : -* [1] National Marine Electronic Association and International Marine -* Electronics Association, NMEA 0183 version 4.10, August 1, 2012 -* [2] NMEA 0183 Talker Identifier Mnemonics, March 3, 2019 -* (https://www.nmea.org/content/STANDARDS/NMEA_0183_Standard) -* -* version : $Revision:$ $Date:$ -* history : 2007/11/03 1.0 new -* 2009/01/05 1.1 add function outsols(), outsolheads(), -* setsolformat(), outsolexs, outsolex -* 2009/04/02 1.2 add dummy fields in NMEA mesassage -* fix bug to format lat/lon as deg-min-sec -* 2009/04/14 1.3 add age and ratio field to solution -* 2009/11/25 1.4 add function readsolstat() -* 2010/02/14 1.5 fix bug on output of gpstime at week boundary -* 2010/07/05 1.6 added api: -* initsolbuf(),freesolbuf(),addsol(),getsol(), -* inputsol(),outprcopts(),outprcopt() -* modified api: -* readsol(),readsolt(),readsolstat(), -* readsolstatt(),outsolheads(),outsols(), -* outsolexs(),outsolhead(),outsol(),outsolex(), -* outnmea_rmc(),outnmea_gga(),outnmea_gsa(), -* outnmea_gsv() -* deleted api: -* setsolopt(),setsolformat() -* 2010/08/14 1.7 fix bug on initialize solution buffer (2.4.0_p2) -* suppress enu-solution if base pos not available -* (2.4.0_p3) -* 2010/08/16 1.8 suppress null record if solution is not available -* (2.4.0_p4) -* 2011/01/23 1.9 fix bug on reading nmea solution data -* add api freesolstatbuf() -* 2012/02/05 1.10 fix bug on output nmea gpgsv -* 2013/02/18 1.11 support nmea GLGSA,GAGSA,GLCSV,GACSV sentence -* 2013/09/01 1.12 fix bug on presentation of nmea time tag -* 2015/02/11 1.13 fix bug on checksum of $GLGSA and $GAGSA -* fix bug on satellite id of $GAGSA -* 2016/01/17 1.14 support reading NMEA GxZDA -* ignore NMEA talker ID -* 2016/07/30 1.15 suppress output if std is over opt->maxsolstd -* 2017/06/13 1.16 support output/input of velocity solution -* 2018/10/10 1.17 support reading solution status file -* 2020/11/30 1.18 add NMEA talker ID GQ and GI (NMEA 0183 4.11) -* add NMEA GQ/GB/GI-GSA/GSV sentences -* change talker ID GP to GN for NMEA RMC/GGA -* change newline to "\r\n" in SOLF_LLH,XYZ,ENU -* add reading age information in NMEA GGA -* use integer types in stdint.h -* suppress warnings -*-----------------------------------------------------------------------------*/ + * solution.c : solution functions + * + * Copyright (C) 2007-2020 by T.TAKASU, All rights reserved. + * + * references : + * [1] National Marine Electronic Association and International Marine + * Electronics Association, NMEA 0183 version 4.10, August 1, 2012 + * [2] NMEA 0183 Talker Identifier Mnemonics, March 3, 2019 + * (https://www.nmea.org/content/STANDARDS/NMEA_0183_Standard) + * + * version : $Revision:$ $Date:$ + * history : 2007/11/03 1.0 new + * 2009/01/05 1.1 add function outsols(), outsolheads(), + * setsolformat(), outsolexs, outsolex + * 2009/04/02 1.2 add dummy fields in NMEA mesassage + * fix bug to format lat/lon as deg-min-sec + * 2009/04/14 1.3 add age and ratio field to solution + * 2009/11/25 1.4 add function readsolstat() + * 2010/02/14 1.5 fix bug on output of gpstime at week boundary + * 2010/07/05 1.6 added api: + * initsolbuf(),freesolbuf(),addsol(),getsol(), + * inputsol(),outprcopts(),outprcopt() + * modified api: + * readsol(),readsolt(),readsolstat(), + * readsolstatt(),outsolheads(),outsols(), + * outsolexs(),outsolhead(),outsol(),outsolex(), + * outnmea_rmc(),outnmea_gga(),outnmea_gsa(), + * outnmea_gsv() + * deleted api: + * setsolopt(),setsolformat() + * 2010/08/14 1.7 fix bug on initialize solution buffer (2.4.0_p2) + * suppress enu-solution if base pos not available + * (2.4.0_p3) + * 2010/08/16 1.8 suppress null record if solution is not available + * (2.4.0_p4) + * 2011/01/23 1.9 fix bug on reading nmea solution data + * add api freesolstatbuf() + * 2012/02/05 1.10 fix bug on output nmea gpgsv + * 2013/02/18 1.11 support nmea GLGSA,GAGSA,GLCSV,GACSV sentence + * 2013/09/01 1.12 fix bug on presentation of nmea time tag + * 2015/02/11 1.13 fix bug on checksum of $GLGSA and $GAGSA + * fix bug on satellite id of $GAGSA + * 2016/01/17 1.14 support reading NMEA GxZDA + * ignore NMEA talker ID + * 2016/07/30 1.15 suppress output if std is over opt->maxsolstd + * 2017/06/13 1.16 support output/input of velocity solution + * 2018/10/10 1.17 support reading solution status file + * 2020/11/30 1.18 add NMEA talker ID GQ and GI (NMEA 0183 4.11) + * add NMEA GQ/GB/GI-GSA/GSV sentences + * change talker ID GP to GN for NMEA RMC/GGA + * change newline to "\r\n" in SOLF_LLH,XYZ,ENU + * add reading age information in NMEA GGA + * use integer types in stdint.h + * suppress warnings + *-----------------------------------------------------------------------------*/ #include + #include "rtklib.h" /* constants and macros ------------------------------------------------------*/ -#define SQR(x) ((x)<0.0?-(x)*(x):(x)*(x)) -#define SQRT(x) ((x)<0.0||(x)!=(x)?0.0:sqrt(x)) +#define SQR(x) ((x) < 0.0 ? -(x) * (x) : (x) * (x)) +#define SQRT(x) ((x) < 0.0 || (x) != (x) ? 0.0 : sqrt(x)) /* https://gpsd.gitlab.io/gpsd/NMEA.html#_talker_ids says ... GA ~ Galileo Positioning System @@ -70,1808 +71,1865 @@ GN ~ Combination of multiple satellite systems(NMEA 1083) GP ~ Global Positioning System receiver GQ ~ QZSS regional GPS augmentation system(Japan) - + https://talk.newagtalk.com/forums/thread-view.asp?tid=877179&mid=7732209#M7732209 - Says "The industry pretty much standardized on using GPxxx regardless of what - constellations are being used in the solution. To be completely NMEA compliant - the second letter should correspond to the constellations being used. Don't + Says "The industry pretty much standardized on using GPxxx regardless of what + constellations are being used in the solution. To be completely NMEA compliant + the second letter should correspond to the constellations being used. Don't forget Galileo and Beidou have their own unique letters too." - And rnx2rtkp GNxxx output is not plotted by RTKPLOT, whereas GPxxx output is + And rnx2rtkp GNxxx output is not plotted by RTKPLOT, whereas GPxxx output is So, This NMEA Talker ID used to be "GN" but now its "GP" */ -#define NMEA_TID "GP" /* NMEA talker ID for RMC and GGA sentences */ -#define MAXFIELD 64 /* max number of fields in a record */ -#define MAXNMEA 256 /* max length of nmea sentence */ - -#define KNOT2M 0.514444444 /* m/sec --> knot */ - -static const int nmea_sys[]={ /* NMEA systems */ - SYS_GPS|SYS_SBS,SYS_GLO,SYS_GAL,SYS_CMP,SYS_QZS,SYS_IRN,0 -}; -static const char *nmea_tid[]={ /* NMEA talker IDs [2] */ - "GP","GL","GA","GB","GQ","GI","" -}; -static const int nmea_sid[]={ /* NMEA system IDs [1] table 21 */ - 1,2,3,4,5,6,0 -}; -static const int nmea_solq[]={ /* NMEA GPS quality indicator [1] */ - /* 0=Fix not available or invalid */ - /* 1=GPS SPS Mode, fix valid */ - /* 2=Differential GPS, SPS Mode, fix valid */ - /* 3=GPS PPS Mode, fix valid */ - /* 4=Real Time Kinematic. System used in RTK mode with fixed integers */ - /* 5=Float RTK. Satellite system used in RTK mode, floating integers */ - /* 6=Estimated (dead reckoning) Mode */ - /* 7=Manual Input Mode */ - /* 8=Simulation Mode */ - SOLQ_NONE ,SOLQ_SINGLE, SOLQ_DGPS, SOLQ_PPP , SOLQ_FIX, - SOLQ_FLOAT,SOLQ_DR , SOLQ_NONE, SOLQ_NONE, SOLQ_NONE -}; +#define NMEA_TID "GP" /* NMEA talker ID for RMC and GGA sentences */ +#define MAXFIELD 64 /* max number of fields in a record */ +#define MAXNMEA 256 /* max length of nmea sentence */ + +#define KNOT2M 0.514444444 /* m/sec --> knot */ + +static const int nmea_sys[] = {/* NMEA systems */ + SYS_GPS | SYS_SBS, SYS_GLO, SYS_GAL, SYS_CMP, SYS_QZS, SYS_IRN, 0}; +static const char *nmea_tid[] = {/* NMEA talker IDs [2] */ + "GP", "GL", "GA", "GB", "GQ", "GI", ""}; +static const int nmea_sid[] = {/* NMEA system IDs [1] table 21 */ + 1, 2, 3, 4, 5, 6, 0}; +static const int nmea_solq[] = + {/* NMEA GPS quality indicator [1] */ + /* 0=Fix not available or invalid */ + /* 1=GPS SPS Mode, fix valid */ + /* 2=Differential GPS, SPS Mode, fix valid */ + /* 3=GPS PPS Mode, fix valid */ + /* 4=Real Time Kinematic. System used in RTK mode with fixed integers */ + /* 5=Float RTK. Satellite system used in RTK mode, floating integers */ + /* 6=Estimated (dead reckoning) Mode */ + /* 7=Manual Input Mode */ + /* 8=Simulation Mode */ + SOLQ_NONE, SOLQ_SINGLE, SOLQ_DGPS, SOLQ_PPP, SOLQ_FIX, + SOLQ_FLOAT, SOLQ_DR, SOLQ_NONE, SOLQ_NONE, SOLQ_NONE}; /* solution option to field separator ----------------------------------------*/ -static const char *opt2sep(const solopt_t *opt) -{ - if (!*opt->sep) return " "; - else if (!strcmp(opt->sep,"\\t")) return "\t"; - return opt->sep; +static const char *opt2sep(const solopt_t *opt) { + if (!*opt->sep) + return " "; + else if (!strcmp(opt->sep, "\\t")) + return "\t"; + return opt->sep; } /* separate fields -----------------------------------------------------------*/ -static int tonum(char *buff, const char *sep, double *v) -{ - int n,len=(int)strlen(sep); - char *p,*q; - - for (p=buff,n=0;nqr[0]; /* xx or ee */ - P[4] =sol->qr[1]; /* yy or nn */ - P[8] =sol->qr[2]; /* zz or uu */ - P[1]=P[3]=sol->qr[3]; /* xy or en */ - P[5]=P[7]=sol->qr[4]; /* yz or nu */ - P[2]=P[6]=sol->qr[5]; /* zx or ue */ +static void soltocov(const sol_t *sol, double *P) { + P[0] = sol->qr[0]; /* xx or ee */ + P[4] = sol->qr[1]; /* yy or nn */ + P[8] = sol->qr[2]; /* zz or uu */ + P[1] = P[3] = sol->qr[3]; /* xy or en */ + P[5] = P[7] = sol->qr[4]; /* yz or nu */ + P[2] = P[6] = sol->qr[5]; /* zx or ue */ } /* covariance to solution ----------------------------------------------------*/ -static void covtosol(const double *P, sol_t *sol) -{ - sol->qr[0]=(float)P[0]; /* xx or ee */ - sol->qr[1]=(float)P[4]; /* yy or nn */ - sol->qr[2]=(float)P[8]; /* zz or uu */ - sol->qr[3]=(float)P[1]; /* xy or en */ - sol->qr[4]=(float)P[5]; /* yz or nu */ - sol->qr[5]=(float)P[2]; /* zx or ue */ +static void covtosol(const double *P, sol_t *sol) { + sol->qr[0] = (float)P[0]; /* xx or ee */ + sol->qr[1] = (float)P[4]; /* yy or nn */ + sol->qr[2] = (float)P[8]; /* zz or uu */ + sol->qr[3] = (float)P[1]; /* xy or en */ + sol->qr[4] = (float)P[5]; /* yz or nu */ + sol->qr[5] = (float)P[2]; /* zx or ue */ } /* solution to velocity covariance -------------------------------------------*/ -static void soltocov_vel(const sol_t *sol, double *P) -{ - P[0] =sol->qv[0]; /* xx */ - P[4] =sol->qv[1]; /* yy */ - P[8] =sol->qv[2]; /* zz */ - P[1]=P[3]=sol->qv[3]; /* xy */ - P[5]=P[7]=sol->qv[4]; /* yz */ - P[2]=P[6]=sol->qv[5]; /* zx */ +static void soltocov_vel(const sol_t *sol, double *P) { + P[0] = sol->qv[0]; /* xx */ + P[4] = sol->qv[1]; /* yy */ + P[8] = sol->qv[2]; /* zz */ + P[1] = P[3] = sol->qv[3]; /* xy */ + P[5] = P[7] = sol->qv[4]; /* yz */ + P[2] = P[6] = sol->qv[5]; /* zx */ } /* velocity covariance to solution -------------------------------------------*/ -static void covtosol_vel(const double *P, sol_t *sol) -{ - sol->qv[0]=(float)P[0]; /* xx */ - sol->qv[1]=(float)P[4]; /* yy */ - sol->qv[2]=(float)P[8]; /* zz */ - sol->qv[3]=(float)P[1]; /* xy */ - sol->qv[4]=(float)P[5]; /* yz */ - sol->qv[5]=(float)P[2]; /* zx */ +static void covtosol_vel(const double *P, sol_t *sol) { + sol->qv[0] = (float)P[0]; /* xx */ + sol->qv[1] = (float)P[4]; /* yy */ + sol->qv[2] = (float)P[8]; /* zz */ + sol->qv[3] = (float)P[1]; /* xy */ + sol->qv[4] = (float)P[5]; /* yz */ + sol->qv[5] = (float)P[2]; /* zx */ } /* decode NMEA RMC (Recommended Minimum Specific GNSS Data) sentence ---------*/ -static int decode_nmearmc(char **val, int n, sol_t *sol) -{ - double tod=0.0,lat=0.0,lon=0.0,vel=0.0,dir=0.0,date=0.0,ang=0.0,ep[6]; - double pos[3]={0}; - char act=' ',ns='N',ew='E',mew='E',mode='A'; - int i; - - trace(4,"decode_nmearmc: n=%d\n",n); - - for (i=0;inmea 2) */ - /* A=autonomous,D=differential */ - /* E=estimated,N=not valid,S=simulator */ - } - } - if ((act!='A'&&act!='V')||(ns!='N'&&ns!='S')||(ew!='E'&&ew!='W')) { - trace(3,"invalid nmea rmc format\n"); - return 0; - } - pos[0]=(ns=='S'?-1.0:1.0)*dmm2deg(lat)*D2R; - pos[1]=(ew=='W'?-1.0:1.0)*dmm2deg(lon)*D2R; - septime(date,ep+2,ep+1,ep); - septime(tod,ep+3,ep+4,ep+5); - ep[0]+=ep[0]<80.0?2000.0:1900.0; - sol->time=utc2gpst(epoch2time(ep)); - pos2ecef(pos,sol->rr); - sol->stat=mode=='D'?SOLQ_DGPS:SOLQ_SINGLE; - sol->ns=0; - - sol->type=0; /* position type = xyz */ - - char tstr[40]; - trace(5,"decode_nmearmc: %s rr=%.3f %.3f %.3f stat=%d ns=%d vel=%.2f dir=%.0f ang=%.0f mew=%c mode=%c\n", - time2str(sol->time,tstr,0),sol->rr[0],sol->rr[1],sol->rr[2],sol->stat,sol->ns, - vel,dir,ang,mew,mode); - - return 2; /* update time */ +static int decode_nmearmc(char **val, int n, sol_t *sol) { + double tod = 0.0, lat = 0.0, lon = 0.0, vel = 0.0, dir = 0.0, date = 0.0, ang = 0.0, ep[6]; + double pos[3] = {0}; + char act = ' ', ns = 'N', ew = 'E', mew = 'E', mode = 'A'; + int i; + + trace(4, "decode_nmearmc: n=%d\n", n); + + for (i = 0; i < n; i++) { + switch (i) { + case 0: + tod = atof(val[i]); + break; /* time in utc (hhmmss) */ + case 1: + act = *val[i]; + break; /* A=active,V=void */ + case 2: + lat = atof(val[i]); + break; /* latitude (ddmm.mmm) */ + case 3: + ns = *val[i]; + break; /* N=north,S=south */ + case 4: + lon = atof(val[i]); + break; /* longitude (dddmm.mmm) */ + case 5: + ew = *val[i]; + break; /* E=east,W=west */ + case 6: + vel = atof(val[i]); + break; /* speed (knots) */ + case 7: + dir = atof(val[i]); + break; /* track angle (deg) */ + case 8: + date = atof(val[i]); + break; /* date (ddmmyy) */ + case 9: + ang = atof(val[i]); + break; /* magnetic variation */ + case 10: + mew = *val[i]; + break; /* E=east,W=west */ + case 11: + mode = *val[i]; + break; /* mode indicator (>nmea 2) */ + /* A=autonomous,D=differential */ + /* E=estimated,N=not valid,S=simulator */ + } + } + if ((act != 'A' && act != 'V') || (ns != 'N' && ns != 'S') || (ew != 'E' && ew != 'W')) { + trace(3, "invalid nmea rmc format\n"); + return 0; + } + pos[0] = (ns == 'S' ? -1.0 : 1.0) * dmm2deg(lat) * D2R; + pos[1] = (ew == 'W' ? -1.0 : 1.0) * dmm2deg(lon) * D2R; + septime(date, ep + 2, ep + 1, ep); + septime(tod, ep + 3, ep + 4, ep + 5); + ep[0] += ep[0] < 80.0 ? 2000.0 : 1900.0; + sol->time = utc2gpst(epoch2time(ep)); + pos2ecef(pos, sol->rr); + sol->stat = mode == 'D' ? SOLQ_DGPS : SOLQ_SINGLE; + sol->ns = 0; + + sol->type = 0; /* position type = xyz */ + + char tstr[40]; + trace(5, + "decode_nmearmc: %s rr=%.3f %.3f %.3f stat=%d ns=%d vel=%.2f dir=%.0f ang=%.0f mew=%c " + "mode=%c\n", + time2str(sol->time, tstr, 0), sol->rr[0], sol->rr[1], sol->rr[2], sol->stat, sol->ns, vel, + dir, ang, mew, mode); + + return 2; /* update time */ } /* decode NMEA ZDA (Time and Date) sentence ----------------------------------*/ -static int decode_nmeazda(char **val, int n, sol_t *sol) -{ - double tod=0.0,ep[6]={0}; - int i; - - trace(4,"decode_nmeazda: n=%d\n",n); - - for (i=0;itime=utc2gpst(epoch2time(ep)); - sol->ns=0; - - char tstr[40]; - trace(5,"decode_nmeazda: %s\n",time2str(sol->time,tstr,0)); - - return 2; /* update time */ +static int decode_nmeazda(char **val, int n, sol_t *sol) { + double tod = 0.0, ep[6] = {0}; + int i; + + trace(4, "decode_nmeazda: n=%d\n", n); + + for (i = 0; i < n; i++) { + switch (i) { + case 0: + tod = atof(val[i]); + break; /* time in utc (hhmmss) */ + case 1: + ep[2] = atof(val[i]); + break; /* day (0-31) */ + case 2: + ep[1] = atof(val[i]); + break; /* mon (1-12) */ + case 3: + ep[0] = atof(val[i]); + break; /* year */ + } + } + septime(tod, ep + 3, ep + 4, ep + 5); + sol->time = utc2gpst(epoch2time(ep)); + sol->ns = 0; + + char tstr[40]; + trace(5, "decode_nmeazda: %s\n", time2str(sol->time, tstr, 0)); + + return 2; /* update time */ } /* decode NMEA GGA (Global Positioning System Fix Data) sentence -------------*/ -static int decode_nmeagga(char **val, int n, sol_t *sol) -{ - gtime_t time; - double tod=0.0,lat=0.0,lon=0.0,hdop=0.0,alt=0.0,msl=0.0,ep[6],tt; - double pos[3]={0},age=0.0; - char ns='N',ew='E',ua=' ',um=' '; - int i,solq=0,nrcv=0; - - trace(4,"decode_nmeagga: n=%d\n",n); - - for (i=0;itime.time==0) { - trace(3,"no date info for nmea gga\n"); - return 0; - } - pos[0]=(ns=='N'?1.0:-1.0)*dmm2deg(lat)*D2R; - pos[1]=(ew=='E'?1.0:-1.0)*dmm2deg(lon)*D2R; - pos[2]=alt+msl; - - time2epoch(sol->time,ep); - septime(tod,ep+3,ep+4,ep+5); - time=utc2gpst(epoch2time(ep)); - tt=timediff(time,sol->time); - if (tt<-43200.0) sol->time=timeadd(time, 86400.0); - else if (tt> 43200.0) sol->time=timeadd(time,-86400.0); - else sol->time=time; - pos2ecef(pos,sol->rr); - sol->stat=0<=solq&&solq<=8?nmea_solq[solq]:SOLQ_NONE; - sol->ns=nrcv; - sol->age=(float)age; - - sol->type=0; /* position type = xyz */ - - char tstr[40]; - trace(5,"decode_nmeagga: %s rr=%.3f %.3f %.3f stat=%d ns=%d hdop=%.1f ua=%c um=%c\n", - time2str(sol->time,tstr,0),sol->rr[0],sol->rr[1],sol->rr[2],sol->stat,sol->ns, - hdop,ua,um); - - return 1; +static int decode_nmeagga(char **val, int n, sol_t *sol) { + gtime_t time; + double tod = 0.0, lat = 0.0, lon = 0.0, hdop = 0.0, alt = 0.0, msl = 0.0, ep[6], tt; + double pos[3] = {0}, age = 0.0; + char ns = 'N', ew = 'E', ua = ' ', um = ' '; + int i, solq = 0, nrcv = 0; + + trace(4, "decode_nmeagga: n=%d\n", n); + + for (i = 0; i < n; i++) { + switch (i) { + case 0: + tod = atof(val[i]); + break; /* UTC of position (hhmmss) */ + case 1: + lat = atof(val[i]); + break; /* Latitude (ddmm.mmm) */ + case 2: + ns = *val[i]; + break; /* N=north,S=south */ + case 3: + lon = atof(val[i]); + break; /* Longitude (dddmm.mmm) */ + case 4: + ew = *val[i]; + break; /* E=east,W=west */ + case 5: + solq = atoi(val[i]); + break; /* GPS quality indicator */ + case 6: + nrcv = atoi(val[i]); + break; /* # of satellites in use */ + case 7: + hdop = atof(val[i]); + break; /* HDOP */ + case 8: + alt = atof(val[i]); + break; /* Altitude MSL */ + case 9: + ua = *val[i]; + break; /* unit (M) */ + case 10: + msl = atof(val[i]); + break; /* Geoid separation */ + case 11: + um = *val[i]; + break; /* unit (M) */ + case 12: + age = atof(val[i]); + break; /* Age of differential */ + } + } + if ((ns != 'N' && ns != 'S') || (ew != 'E' && ew != 'W')) { + trace(3, "invalid nmea gga format\n"); + return 0; + } + if (sol->time.time == 0) { + trace(3, "no date info for nmea gga\n"); + return 0; + } + pos[0] = (ns == 'N' ? 1.0 : -1.0) * dmm2deg(lat) * D2R; + pos[1] = (ew == 'E' ? 1.0 : -1.0) * dmm2deg(lon) * D2R; + pos[2] = alt + msl; + + time2epoch(sol->time, ep); + septime(tod, ep + 3, ep + 4, ep + 5); + time = utc2gpst(epoch2time(ep)); + tt = timediff(time, sol->time); + if (tt < -43200.0) + sol->time = timeadd(time, 86400.0); + else if (tt > 43200.0) + sol->time = timeadd(time, -86400.0); + else + sol->time = time; + pos2ecef(pos, sol->rr); + sol->stat = 0 <= solq && solq <= 8 ? nmea_solq[solq] : SOLQ_NONE; + sol->ns = nrcv; + sol->age = (float)age; + + sol->type = 0; /* position type = xyz */ + + char tstr[40]; + trace(5, "decode_nmeagga: %s rr=%.3f %.3f %.3f stat=%d ns=%d hdop=%.1f ua=%c um=%c\n", + time2str(sol->time, tstr, 0), sol->rr[0], sol->rr[1], sol->rr[2], sol->stat, sol->ns, hdop, + ua, um); + + return 1; } /* test NMEA sentence header -------------------------------------------------*/ -static int test_nmea(const char *buff) -{ - if (strlen(buff)<6||buff[0]!='$') return 0; - return !strncmp(buff+1,"GP",2)||!strncmp(buff+1,"GA",2)|| /* NMEA 4.10 [1] */ - !strncmp(buff+1,"GL",2)||!strncmp(buff+1,"GN",2)|| - !strncmp(buff+1,"GB",2)||!strncmp(buff+1,"GQ",2)|| /* NMEA 4.11 [2] */ - !strncmp(buff+1,"GI",2)|| - !strncmp(buff+1,"BD",2)||!strncmp(buff+1,"QZ",2); /* extension */ +static int test_nmea(const char *buff) { + if (strlen(buff) < 6 || buff[0] != '$') return 0; + return !strncmp(buff + 1, "GP", 2) || !strncmp(buff + 1, "GA", 2) || /* NMEA 4.10 [1] */ + !strncmp(buff + 1, "GL", 2) || !strncmp(buff + 1, "GN", 2) || + !strncmp(buff + 1, "GB", 2) || !strncmp(buff + 1, "GQ", 2) || /* NMEA 4.11 [2] */ + !strncmp(buff + 1, "GI", 2) || !strncmp(buff + 1, "BD", 2) || + !strncmp(buff + 1, "QZ", 2); /* extension */ } /* test solution status message header ---------------------------------------*/ -static int test_solstat(const char *buff) -{ - if (strlen(buff)<7||buff[0]!='$') return 0; - return !strncmp(buff+1,"POS" ,3)||!strncmp(buff+1,"VELACC",6)|| - !strncmp(buff+1,"CLK" ,3)||!strncmp(buff+1,"ION" ,3)|| - !strncmp(buff+1,"TROP",4)||!strncmp(buff+1,"HWBIAS",6)|| - !strncmp(buff+1,"TRPG",4)||!strncmp(buff+1,"AMB" ,3)|| - !strncmp(buff+1,"SAT" ,3); +static int test_solstat(const char *buff) { + if (strlen(buff) < 7 || buff[0] != '$') return 0; + return !strncmp(buff + 1, "POS", 3) || !strncmp(buff + 1, "VELACC", 6) || + !strncmp(buff + 1, "CLK", 3) || !strncmp(buff + 1, "ION", 3) || + !strncmp(buff + 1, "TROP", 4) || !strncmp(buff + 1, "HWBIAS", 6) || + !strncmp(buff + 1, "TRPG", 4) || !strncmp(buff + 1, "AMB", 3) || + !strncmp(buff + 1, "SAT", 3); } /* decode NMEA sentence ------------------------------------------------------*/ -static int decode_nmea(char *buff, sol_t *sol) -{ - char *p,*q,*val[MAXFIELD]={0}; - int n=0; - - trace(4,"decode_nmea: buff=%s\n",buff); - - /* parse fields */ - for (p=buff;*p&&nposf==SOLF_STAT) { - return buff; - } + if (opt->posf == SOLF_STAT) { + return buff; + } - const char *sep = opt2sep(opt); - size_t sep_len = strlen(sep); - - if (opt->posf==SOLF_GSIF) { - if (sscanf(buff,"%lf %lf %lf %lf:%lf:%lf",v,v+1,v+2,v+3,v+4,v+5)<6) { - return NULL; - } - *time=timeadd(epoch2time(v),-12.0*3600.0); - if (!(p=strchr(buff,':'))||!(p=strchr(p+1,':'))) return NULL; - for (p++;isdigit((int)*p)||*p=='.';) p++; - p=strstr(p,sep); - if (p) return p+sep_len; - else return NULL; - } - /* yyyy/mm/dd hh:mm:ss or yyyy mm dd hh:mm:ss */ - if (sscanf(buff,"%lf/%lf/%lf %lf:%lf:%lf",v,v+1,v+2,v+3,v+4,v+5)>=6) { - if (v[0]<100.0) { - v[0]+=v[0]<80.0?2000.0:1900.0; - } - *time=epoch2time(v); - if (opt->times==TIMES_UTC) { - *time=utc2gpst(*time); - } - else if (opt->times==TIMES_JST) { - *time=utc2gpst(timeadd(*time,-9*3600.0)); - } - if (!(p=strchr(buff,':'))||!(p=strchr(p+1,':'))) return NULL; - for (p++;isdigit((int)*p)||*p=='.';) p++; - p=strstr(p,sep); - if (p) return p+sep_len; - else return NULL; - } - else { /* wwww ssss */ - for (p=buff,n=0;n<2;p=q+sep_len) { - q=strstr(p,sep); - if (!q) return NULL; - *q='\0'; - if (sscanf(p,"%lf",v+n)==1) n++; - } - if (n>=2&&0.0<=v[0]&&v[0]<=3000.0&&0.0<=v[1]&&v[1]<604800.0) { - *time=gpst2time((int)v[0],v[1]); - return p; - } - } - return NULL; + const char *sep = opt2sep(opt); + size_t sep_len = strlen(sep); + + if (opt->posf == SOLF_GSIF) { + if (sscanf(buff, "%lf %lf %lf %lf:%lf:%lf", v, v + 1, v + 2, v + 3, v + 4, v + 5) < 6) { + return NULL; + } + *time = timeadd(epoch2time(v), -12.0 * 3600.0); + if (!(p = strchr(buff, ':')) || !(p = strchr(p + 1, ':'))) return NULL; + for (p++; isdigit((int)*p) || *p == '.';) p++; + p = strstr(p, sep); + if (p) + return p + sep_len; + else + return NULL; + } + /* yyyy/mm/dd hh:mm:ss or yyyy mm dd hh:mm:ss */ + if (sscanf(buff, "%lf/%lf/%lf %lf:%lf:%lf", v, v + 1, v + 2, v + 3, v + 4, v + 5) >= 6) { + if (v[0] < 100.0) { + v[0] += v[0] < 80.0 ? 2000.0 : 1900.0; + } + *time = epoch2time(v); + if (opt->times == TIMES_UTC) { + *time = utc2gpst(*time); + } else if (opt->times == TIMES_JST) { + *time = utc2gpst(timeadd(*time, -9 * 3600.0)); + } + if (!(p = strchr(buff, ':')) || !(p = strchr(p + 1, ':'))) return NULL; + for (p++; isdigit((int)*p) || *p == '.';) p++; + p = strstr(p, sep); + if (p) + return p + sep_len; + else + return NULL; + } else { /* wwww ssss */ + for (p = buff, n = 0; n < 2; p = q + sep_len) { + q = strstr(p, sep); + if (!q) return NULL; + *q = '\0'; + if (sscanf(p, "%lf", v + n) == 1) n++; + } + if (n >= 2 && 0.0 <= v[0] && v[0] <= 3000.0 && 0.0 <= v[1] && v[1] < 604800.0) { + *time = gpst2time((int)v[0], v[1]); + return p; + } + } + return NULL; } /* decode x/y/z-ecef ---------------------------------------------------------*/ -static int decode_solxyz(char *buff, const solopt_t *opt, sol_t *sol) -{ - double val[MAXFIELD],P[9]={0}; - int i=0,j,n; - const char *sep=opt2sep(opt); - - trace(4,"decode_solxyz:\n"); - - if ((n=tonum(buff,sep,val))<3) return 0; - - for (j=0;j<3;j++) { - sol->rr[j]=val[i++]; /* xyz */ - } - if (istat=(uint8_t)val[i++]; - if (ins =(uint8_t)val[i++]; - if (i+3<=n) { - P[0]=SQR(val[i]); i++; /* sdx */ - P[4]=SQR(val[i]); i++; /* sdy */ - P[8]=SQR(val[i]); i++; /* sdz */ - if (i+3<=n) { - P[1]=P[3]=SQR(val[i]); i++; /* sdxy */ - P[5]=P[7]=SQR(val[i]); i++; /* sdyz */ - P[2]=P[6]=SQR(val[i]); i++; /* sdzx */ - } - covtosol(P,sol); - } - if (iage =(float)val[i++]; - if (iratio=(float)val[i++]; - - if (i+3<=n) { /* velocity */ - for (j=0;j<3;j++) { - sol->rr[j+3]=val[i++]; /* xyz */ - } - } - if (i+3<=n) { - for (j=0;j<9;j++) P[j]=0.0; - P[0]=SQR(val[i]); i++; /* sdx */ - P[4]=SQR(val[i]); i++; /* sdy */ - P[8]=SQR(val[i]); i++; /* sdz */ - if (i+3type=0; /* position type = xyz */ - - if (MAXSOLQstat) sol->stat=SOLQ_NONE; - return 1; +static int decode_solxyz(char *buff, const solopt_t *opt, sol_t *sol) { + double val[MAXFIELD], P[9] = {0}; + int i = 0, j, n; + const char *sep = opt2sep(opt); + + trace(4, "decode_solxyz:\n"); + + if ((n = tonum(buff, sep, val)) < 3) return 0; + + for (j = 0; j < 3; j++) { + sol->rr[j] = val[i++]; /* xyz */ + } + if (i < n) sol->stat = (uint8_t)val[i++]; + if (i < n) sol->ns = (uint8_t)val[i++]; + if (i + 3 <= n) { + P[0] = SQR(val[i]); + i++; /* sdx */ + P[4] = SQR(val[i]); + i++; /* sdy */ + P[8] = SQR(val[i]); + i++; /* sdz */ + if (i + 3 <= n) { + P[1] = P[3] = SQR(val[i]); + i++; /* sdxy */ + P[5] = P[7] = SQR(val[i]); + i++; /* sdyz */ + P[2] = P[6] = SQR(val[i]); + i++; /* sdzx */ + } + covtosol(P, sol); + } + if (i < n) sol->age = (float)val[i++]; + if (i < n) sol->ratio = (float)val[i++]; + + if (i + 3 <= n) { /* velocity */ + for (j = 0; j < 3; j++) { + sol->rr[j + 3] = val[i++]; /* xyz */ + } + } + if (i + 3 <= n) { + for (j = 0; j < 9; j++) P[j] = 0.0; + P[0] = SQR(val[i]); + i++; /* sdx */ + P[4] = SQR(val[i]); + i++; /* sdy */ + P[8] = SQR(val[i]); + i++; /* sdz */ + if (i + 3 < n) { + P[1] = P[3] = SQR(val[i]); + i++; /* sdxy */ + P[5] = P[7] = SQR(val[i]); + i++; /* sdyz */ + P[2] = P[6] = SQR(val[i]); + i++; /* sdzx */ + } + covtosol_vel(P, sol); + } + sol->type = 0; /* position type = xyz */ + + if (MAXSOLQ < sol->stat) sol->stat = SOLQ_NONE; + return 1; } /* decode lat/lon/height -----------------------------------------------------*/ -static int decode_solllh(char *buff, const solopt_t *opt, sol_t *sol) -{ - double val[MAXFIELD],pos[3],vel[3],Q[9]={0},P[9]; - int i=0,j,n; - const char *sep=opt2sep(opt); - - trace(4,"decode_solllh:\n"); - - n=tonum(buff,sep,val); - - if (!opt->degf) { - if (n<3) return 0; - pos[0]=val[i++]*D2R; /* lat/lon/hgt (ddd.ddd) */ - pos[1]=val[i++]*D2R; - pos[2]=val[i++]; - } - else { - if (n<7) return 0; - pos[0]=dms2deg(val )*D2R; /* lat/lon/hgt (ddd mm ss) */ - pos[1]=dms2deg(val+3)*D2R; - pos[2]=val[6]; - i+=7; - } - pos2ecef(pos,sol->rr); - if (istat=(uint8_t)val[i++]; - if (ins =(uint8_t)val[i++]; - if (i+3<=n) { - Q[4]=SQR(val[i]); i++; /* sdn */ - Q[0]=SQR(val[i]); i++; /* sde */ - Q[8]=SQR(val[i]); i++; /* sdu */ - if (i+3age =(float)val[i++]; - if (iratio=(float)val[i++]; - - if (i+3<=n) { /* velocity */ - vel[1]=val[i++]; /* vel-n */ - vel[0]=val[i++]; /* vel-e */ - vel[2]=val[i++]; /* vel-u */ - enu2ecef(pos,vel,sol->rr+3); - } - if (i+3<=n) { - for (j=0;j<9;j++) Q[j]=0.0; - Q[4]=SQR(val[i]); i++; /* sdn */ - Q[0]=SQR(val[i]); i++; /* sde */ - Q[8]=SQR(val[i]); i++; /* sdu */ - if (i+3<=n) { - Q[1]=Q[3]=SQR(val[i]); i++; /* sdne */ - Q[2]=Q[6]=SQR(val[i]); i++; /* sdeu */ - Q[5]=Q[7]=SQR(val[i]); i++; /* sdun */ - } - covecef(pos,Q,P); - covtosol_vel(P,sol); - } - sol->type=0; /* position type = xyz */ - - if (MAXSOLQstat) sol->stat=SOLQ_NONE; - return 1; +static int decode_solllh(char *buff, const solopt_t *opt, sol_t *sol) { + double val[MAXFIELD], pos[3], vel[3], Q[9] = {0}, P[9]; + int i = 0, j, n; + const char *sep = opt2sep(opt); + + trace(4, "decode_solllh:\n"); + + n = tonum(buff, sep, val); + + if (!opt->degf) { + if (n < 3) return 0; + pos[0] = val[i++] * D2R; /* lat/lon/hgt (ddd.ddd) */ + pos[1] = val[i++] * D2R; + pos[2] = val[i++]; + } else { + if (n < 7) return 0; + pos[0] = dms2deg(val) * D2R; /* lat/lon/hgt (ddd mm ss) */ + pos[1] = dms2deg(val + 3) * D2R; + pos[2] = val[6]; + i += 7; + } + pos2ecef(pos, sol->rr); + if (i < n) sol->stat = (uint8_t)val[i++]; + if (i < n) sol->ns = (uint8_t)val[i++]; + if (i + 3 <= n) { + Q[4] = SQR(val[i]); + i++; /* sdn */ + Q[0] = SQR(val[i]); + i++; /* sde */ + Q[8] = SQR(val[i]); + i++; /* sdu */ + if (i + 3 < n) { + Q[1] = Q[3] = SQR(val[i]); + i++; /* sdne */ + Q[2] = Q[6] = SQR(val[i]); + i++; /* sdeu */ + Q[5] = Q[7] = SQR(val[i]); + i++; /* sdun */ + } + covecef(pos, Q, P); + covtosol(P, sol); + } + if (i < n) sol->age = (float)val[i++]; + if (i < n) sol->ratio = (float)val[i++]; + + if (i + 3 <= n) { /* velocity */ + vel[1] = val[i++]; /* vel-n */ + vel[0] = val[i++]; /* vel-e */ + vel[2] = val[i++]; /* vel-u */ + enu2ecef(pos, vel, sol->rr + 3); + } + if (i + 3 <= n) { + for (j = 0; j < 9; j++) Q[j] = 0.0; + Q[4] = SQR(val[i]); + i++; /* sdn */ + Q[0] = SQR(val[i]); + i++; /* sde */ + Q[8] = SQR(val[i]); + i++; /* sdu */ + if (i + 3 <= n) { + Q[1] = Q[3] = SQR(val[i]); + i++; /* sdne */ + Q[2] = Q[6] = SQR(val[i]); + i++; /* sdeu */ + Q[5] = Q[7] = SQR(val[i]); + i++; /* sdun */ + } + covecef(pos, Q, P); + covtosol_vel(P, sol); + } + sol->type = 0; /* position type = xyz */ + + if (MAXSOLQ < sol->stat) sol->stat = SOLQ_NONE; + return 1; } /* decode e/n/u-baseline -----------------------------------------------------*/ -static int decode_solenu(char *buff, const solopt_t *opt, sol_t *sol) -{ - double val[MAXFIELD],Q[9]={0}; - int i=0,j,n; - const char *sep=opt2sep(opt); - - trace(4,"decode_solenu:\n"); - - if ((n=tonum(buff,sep,val))<3) return 0; - - for (j=0;j<3;j++) { - sol->rr[j]=val[i++]; /* enu */ - } - if (istat=(uint8_t)val[i++]; - if (ins =(uint8_t)val[i++]; - if (i+3<=n) { - Q[0]=SQR(val[i]); i++; /* sde */ - Q[4]=SQR(val[i]); i++; /* sdn */ - Q[8]=SQR(val[i]); i++; /* sdu */ - if (i+3<=n) { - Q[1]=Q[3]=SQR(val[i]); i++; /* sden */ - Q[5]=Q[7]=SQR(val[i]); i++; /* sdnu */ - Q[2]=Q[6]=SQR(val[i]); i++; /* sdue */ - } - covtosol(Q,sol); - } - if (iage =(float)val[i++]; - if (iratio=(float)val[i++]; +static int decode_solenu(char *buff, const solopt_t *opt, sol_t *sol) { + double val[MAXFIELD], Q[9] = {0}; + int i = 0, j, n; + const char *sep = opt2sep(opt); - if (i+3<=n) { /* velocity */ - for (j=0;j<3;j++) { - sol->rr[j+3]=val[i++]; /* vel-enu */ - } - } - if (i+3<=n) { - for (j=0;j<9;j++) Q[j]=0.0; - Q[0]=val[i]*val[i]; i++; /* sde */ - Q[4]=val[i]*val[i]; i++; /* sdn */ - Q[8]=val[i]*val[i]; i++; /* sdu */ - if (i+3<=n) { - Q[1]=Q[3]=SQR(val[i]); i++; /* sden */ - Q[5]=Q[7]=SQR(val[i]); i++; /* sdnu */ - Q[2]=Q[6]=SQR(val[i]); i++; /* sdue */ - } - covtosol_vel(Q,sol); - } - sol->type=1; /* position type = enu */ - - if (MAXSOLQstat) sol->stat=SOLQ_NONE; - return 1; + trace(4, "decode_solenu:\n"); + + if ((n = tonum(buff, sep, val)) < 3) return 0; + + for (j = 0; j < 3; j++) { + sol->rr[j] = val[i++]; /* enu */ + } + if (i < n) sol->stat = (uint8_t)val[i++]; + if (i < n) sol->ns = (uint8_t)val[i++]; + if (i + 3 <= n) { + Q[0] = SQR(val[i]); + i++; /* sde */ + Q[4] = SQR(val[i]); + i++; /* sdn */ + Q[8] = SQR(val[i]); + i++; /* sdu */ + if (i + 3 <= n) { + Q[1] = Q[3] = SQR(val[i]); + i++; /* sden */ + Q[5] = Q[7] = SQR(val[i]); + i++; /* sdnu */ + Q[2] = Q[6] = SQR(val[i]); + i++; /* sdue */ + } + covtosol(Q, sol); + } + if (i < n) sol->age = (float)val[i++]; + if (i < n) sol->ratio = (float)val[i++]; + + if (i + 3 <= n) { /* velocity */ + for (j = 0; j < 3; j++) { + sol->rr[j + 3] = val[i++]; /* vel-enu */ + } + } + if (i + 3 <= n) { + for (j = 0; j < 9; j++) Q[j] = 0.0; + Q[0] = val[i] * val[i]; + i++; /* sde */ + Q[4] = val[i] * val[i]; + i++; /* sdn */ + Q[8] = val[i] * val[i]; + i++; /* sdu */ + if (i + 3 <= n) { + Q[1] = Q[3] = SQR(val[i]); + i++; /* sden */ + Q[5] = Q[7] = SQR(val[i]); + i++; /* sdnu */ + Q[2] = Q[6] = SQR(val[i]); + i++; /* sdue */ + } + covtosol_vel(Q, sol); + } + sol->type = 1; /* position type = enu */ + + if (MAXSOLQ < sol->stat) sol->stat = SOLQ_NONE; + return 1; } /* decode solution status ----------------------------------------------------*/ -static int decode_solsss(char *buff, sol_t *sol) -{ - double tow,pos[3],std[3]={0}; - int i,week,solq; - - trace(4,"decode_solsss:\n"); - - if (sscanf(buff,"$POS,%d,%lf,%d,%lf,%lf,%lf,%lf,%lf,%lf",&week,&tow,&solq, - pos,pos+1,pos+2,std,std+1,std+2)<6) { - return 0; - } - if (week<=0||norm(pos,3)<=0.0||solq==SOLQ_NONE) { - return 0; - } - sol->time=gpst2time(week,tow); - for (i=0;i<6;i++) { - sol->rr[i]=i<3?pos[i]:0.0; - sol->qr[i]=i<3?(float)SQR(std[i]):0.0f; - sol->dtr[i]=0.0; - } - sol->ns=0; - sol->age=sol->ratio=sol->thres=0.0f; - sol->type=0; /* position type = xyz */ - sol->stat=solq; - return 1; +static int decode_solsss(char *buff, sol_t *sol) { + double tow, pos[3], std[3] = {0}; + int i, week, solq; + + trace(4, "decode_solsss:\n"); + + if (sscanf(buff, "$POS,%d,%lf,%d,%lf,%lf,%lf,%lf,%lf,%lf", &week, &tow, &solq, pos, pos + 1, + pos + 2, std, std + 1, std + 2) < 6) { + return 0; + } + if (week <= 0 || norm(pos, 3) <= 0.0 || solq == SOLQ_NONE) { + return 0; + } + sol->time = gpst2time(week, tow); + for (i = 0; i < 6; i++) { + sol->rr[i] = i < 3 ? pos[i] : 0.0; + sol->qr[i] = i < 3 ? (float)SQR(std[i]) : 0.0f; + sol->dtr[i] = 0.0; + } + sol->ns = 0; + sol->age = sol->ratio = sol->thres = 0.0f; + sol->type = 0; /* position type = xyz */ + sol->stat = solq; + return 1; } /* decode GSI F solution -----------------------------------------------------*/ -static int decode_solgsi(char *buff, const solopt_t *opt, sol_t *sol) -{ - (void)opt; - double val[MAXFIELD]; - int i=0,j; - - trace(4,"decode_solgsi:\n"); - - if (tonum(buff," ",val)<3) return 0; - - for (j=0;j<3;j++) { - sol->rr[j]=val[i++]; /* xyz */ - } - sol->stat=SOLQ_FIX; - return 1; +static int decode_solgsi(char *buff, const solopt_t *opt, sol_t *sol) { + (void)opt; + double val[MAXFIELD]; + int i = 0, j; + + trace(4, "decode_solgsi:\n"); + + if (tonum(buff, " ", val) < 3) return 0; + + for (j = 0; j < 3; j++) { + sol->rr[j] = val[i++]; /* xyz */ + } + sol->stat = SOLQ_FIX; + return 1; } /* decode solution position --------------------------------------------------*/ -static int decode_solpos(char *buff, const solopt_t *opt, sol_t *sol) -{ - sol_t sol0={{0}}; - char *p=buff; - - trace(4,"decode_solpos: buff=%s\n",buff); - - *sol=sol0; - - /* decode solution time */ - if (!(p=decode_soltime(p,opt,&sol->time))) { - return 0; - } - /* decode solution position */ - switch (opt->posf) { - case SOLF_XYZ : return decode_solxyz(p,opt,sol); - case SOLF_LLH : return decode_solllh(p,opt,sol); - case SOLF_ENU : return decode_solenu(p,opt,sol); - case SOLF_GSIF: return decode_solgsi(p,opt,sol); - } +static int decode_solpos(char *buff, const solopt_t *opt, sol_t *sol) { + sol_t sol0 = {{0}}; + char *p = buff; + + trace(4, "decode_solpos: buff=%s\n", buff); + + *sol = sol0; + + /* decode solution time */ + if (!(p = decode_soltime(p, opt, &sol->time))) { return 0; + } + /* decode solution position */ + switch (opt->posf) { + case SOLF_XYZ: + return decode_solxyz(p, opt, sol); + case SOLF_LLH: + return decode_solllh(p, opt, sol); + case SOLF_ENU: + return decode_solenu(p, opt, sol); + case SOLF_GSIF: + return decode_solgsi(p, opt, sol); + } + return 0; } /* decode reference position -------------------------------------------------*/ -static void decode_refpos(char *buff, const solopt_t *opt, double *rb) -{ - double val[MAXFIELD],pos[3]; - int i,n; - const char *sep=opt2sep(opt); - - trace(3,"decode_refpos: buff=%s\n",buff); - - if ((n=tonum(buff,sep,val))<3) return; - - if (opt->posf==SOLF_XYZ) { /* xyz */ - for (i=0;i<3;i++) rb[i]=val[i]; - } - else if (opt->degf==0) { /* lat/lon/hgt (ddd.ddd) */ - pos[0]=val[0]*D2R; - pos[1]=val[1]*D2R; - pos[2]=val[2]; - pos2ecef(pos,rb); - } - else if (opt->degf==1&&n>=7) { /* lat/lon/hgt (ddd mm ss) */ - pos[0]=dms2deg(val )*D2R; - pos[1]=dms2deg(val+3)*D2R; - pos[2]=val[6]; - pos2ecef(pos,rb); - } +static void decode_refpos(char *buff, const solopt_t *opt, double *rb) { + double val[MAXFIELD], pos[3]; + int i, n; + const char *sep = opt2sep(opt); + + trace(3, "decode_refpos: buff=%s\n", buff); + + if ((n = tonum(buff, sep, val)) < 3) return; + + if (opt->posf == SOLF_XYZ) { /* xyz */ + for (i = 0; i < 3; i++) rb[i] = val[i]; + } else if (opt->degf == 0) { /* lat/lon/hgt (ddd.ddd) */ + pos[0] = val[0] * D2R; + pos[1] = val[1] * D2R; + pos[2] = val[2]; + pos2ecef(pos, rb); + } else if (opt->degf == 1 && n >= 7) { /* lat/lon/hgt (ddd mm ss) */ + pos[0] = dms2deg(val) * D2R; + pos[1] = dms2deg(val + 3) * D2R; + pos[2] = val[6]; + pos2ecef(pos, rb); + } } /* decode solution -----------------------------------------------------------*/ -static int decode_sol(char *buff, const solopt_t *opt, sol_t *sol, double *rb) -{ - char *p; - - trace(4,"decode_sol: buff=%s\n",buff); - - if (test_nmea(buff)) { /* decode nmea */ - return decode_nmea(buff,sol); - } - else if (test_solstat(buff)) { /* decode solution status */ - return decode_solsss(buff,sol); - } - if (!strncmp(buff,COMMENTH,1)) { /* reference position */ - if (!strstr(buff,"ref pos")&&!strstr(buff,"slave pos")) return 0; - if (!(p=strchr(buff,':'))) return 0; - decode_refpos(p+1,opt,rb); - return 0; - } - /* decode position record */ - return decode_solpos(buff,opt,sol); +static int decode_sol(char *buff, const solopt_t *opt, sol_t *sol, double *rb) { + char *p; + + trace(4, "decode_sol: buff=%s\n", buff); + + if (test_nmea(buff)) { /* decode nmea */ + return decode_nmea(buff, sol); + } else if (test_solstat(buff)) { /* decode solution status */ + return decode_solsss(buff, sol); + } + if (!strncmp(buff, COMMENTH, 1)) { /* reference position */ + if (!strstr(buff, "ref pos") && !strstr(buff, "slave pos")) return 0; + if (!(p = strchr(buff, ':'))) return 0; + decode_refpos(p + 1, opt, rb); + return 0; + } + /* decode position record */ + return decode_solpos(buff, opt, sol); } /* decode solution options ---------------------------------------------------*/ -static void decode_solopt(char *buff, solopt_t *opt) -{ - char *p; - - trace(4,"decode_solhead: buff=%s\n",buff); - - if (strncmp(buff,COMMENTH,1)&&strncmp(buff,"+",1)) return; - - if (strstr(buff,"GPST")) opt->times=TIMES_GPST; - else if (strstr(buff,"UTC" )) opt->times=TIMES_UTC; - else if (strstr(buff,"JST" )) opt->times=TIMES_JST; - - if ((p=strstr(buff,"x-ecef(m)"))) { - opt->posf=SOLF_XYZ; - opt->degf=0; - strncpy(opt->sep,p+9,1); - opt->sep[1]='\0'; - } - else if ((p=strstr(buff,"latitude(d'\")"))) { - opt->posf=SOLF_LLH; - opt->degf=1; - strncpy(opt->sep,p+14,1); - opt->sep[1]='\0'; - } - else if ((p=strstr(buff,"latitude(deg)"))) { - opt->posf=SOLF_LLH; - opt->degf=0; - strncpy(opt->sep,p+13,1); - opt->sep[1]='\0'; - } - else if ((p=strstr(buff,"e-baseline(m)"))) { - opt->posf=SOLF_ENU; - opt->degf=0; - strncpy(opt->sep,p+13,1); - opt->sep[1]='\0'; - } - else if (strstr(buff,"+SITE/INF")) { /* gsi f2/f3 solution */ - opt->times=TIMES_GPST; - opt->posf=SOLF_GSIF; - opt->degf=0; - strcpy(opt->sep," "); - } +static void decode_solopt(char *buff, solopt_t *opt) { + char *p; + + trace(4, "decode_solhead: buff=%s\n", buff); + + if (strncmp(buff, COMMENTH, 1) && strncmp(buff, "+", 1)) return; + + if (strstr(buff, "GPST")) + opt->times = TIMES_GPST; + else if (strstr(buff, "UTC")) + opt->times = TIMES_UTC; + else if (strstr(buff, "JST")) + opt->times = TIMES_JST; + + if ((p = strstr(buff, "x-ecef(m)"))) { + opt->posf = SOLF_XYZ; + opt->degf = 0; + strncpy(opt->sep, p + 9, 1); + opt->sep[1] = '\0'; + } else if ((p = strstr(buff, "latitude(d'\")"))) { + opt->posf = SOLF_LLH; + opt->degf = 1; + strncpy(opt->sep, p + 14, 1); + opt->sep[1] = '\0'; + } else if ((p = strstr(buff, "latitude(deg)"))) { + opt->posf = SOLF_LLH; + opt->degf = 0; + strncpy(opt->sep, p + 13, 1); + opt->sep[1] = '\0'; + } else if ((p = strstr(buff, "e-baseline(m)"))) { + opt->posf = SOLF_ENU; + opt->degf = 0; + strncpy(opt->sep, p + 13, 1); + opt->sep[1] = '\0'; + } else if (strstr(buff, "+SITE/INF")) { /* gsi f2/f3 solution */ + opt->times = TIMES_GPST; + opt->posf = SOLF_GSIF; + opt->degf = 0; + strcpy(opt->sep, " "); + } } /* read solution option ------------------------------------------------------*/ -static void readsolopt(FILE *fp, solopt_t *opt) -{ - char buff[MAXSOLLEN+1]; - int i; - - trace(3,"readsolopt:\n"); - - for (i=0;fgets(buff,sizeof(buff),fp)&&i<100;i++) { /* Only 100 lines */ - /* decode solution options */ - decode_solopt(buff,opt); - } +static void readsolopt(FILE *fp, solopt_t *opt) { + char buff[MAXSOLLEN + 1]; + int i; + + trace(3, "readsolopt:\n"); + + for (i = 0; fgets(buff, sizeof(buff), fp) && i < 100; i++) { /* Only 100 lines */ + /* decode solution options */ + decode_solopt(buff, opt); + } } /* input solution data from stream --------------------------------------------- -* input solution data from stream -* args : uint8_t data I stream data -* gtime_t ts I start time (ts.time==0: from start) -* gtime_t te I end time (te.time==0: to end) -* double tint I time interval (0: all) -* int qflag I quality flag (0: all) -* solbuf_t *solbuf IO solution buffer -* return : status (1:solution received,0:no solution,-1:disconnect received) -*-----------------------------------------------------------------------------*/ -extern int inputsol(uint8_t data, gtime_t ts, gtime_t te, double tint, - int qflag, const solopt_t *opt, solbuf_t *solbuf) -{ - sol_t sol={{0}}; - int stat; - - trace(4,"inputsol: data=0x%02x\n",data); - - if (data=='$'||(!isprint(data)&&data!='\r'&&data!='\n')) { /* sync header */ - solbuf->nb=0; - } - if (data!='\r'&&data!='\n') { - solbuf->buff[solbuf->nb++]=data; - } - if (data!='\n'&&solbuf->nbbuff[solbuf->nb]='\0'; - solbuf->nb=0; - - /* check disconnect message */ - if (!strncmp((char *)solbuf->buff,MSG_DISCONN,strlen(MSG_DISCONN)-2)) { - trace(3,"disconnect received\n"); - return -1; - } - /* decode solution */ - sol.time=solbuf->time; - if ((stat=decode_sol((char *)solbuf->buff,opt,&sol,solbuf->rb))>0) { - solbuf->time=sol.time; /* update current time */ - if (stat!=1) return 0; - } - if (stat!=1||!screent(sol.time,ts,te,tint)||(qflag&&sol.stat!=qflag)) { - return 0; - } - /* add solution to solution buffer */ - return addsol(solbuf,&sol); + * input solution data from stream + * args : uint8_t data I stream data + * gtime_t ts I start time (ts.time==0: from start) + * gtime_t te I end time (te.time==0: to end) + * double tint I time interval (0: all) + * int qflag I quality flag (0: all) + * solbuf_t *solbuf IO solution buffer + * return : status (1:solution received,0:no solution,-1:disconnect received) + *-----------------------------------------------------------------------------*/ +extern int inputsol(uint8_t data, gtime_t ts, gtime_t te, double tint, int qflag, + const solopt_t *opt, solbuf_t *solbuf) { + sol_t sol = {{0}}; + int stat; + + trace(4, "inputsol: data=0x%02x\n", data); + + if (data == '$' || (!isprint(data) && data != '\r' && data != '\n')) { /* sync header */ + solbuf->nb = 0; + } + if (data != '\r' && data != '\n') { + solbuf->buff[solbuf->nb++] = data; + } + if (data != '\n' && solbuf->nb < MAXSOLLEN) return 0; /* sync trailer */ + + solbuf->buff[solbuf->nb] = '\0'; + solbuf->nb = 0; + + /* check disconnect message */ + if (!strncmp((char *)solbuf->buff, MSG_DISCONN, strlen(MSG_DISCONN) - 2)) { + trace(3, "disconnect received\n"); + return -1; + } + /* decode solution */ + sol.time = solbuf->time; + if ((stat = decode_sol((char *)solbuf->buff, opt, &sol, solbuf->rb)) > 0) { + solbuf->time = sol.time; /* update current time */ + if (stat != 1) return 0; + } + if (stat != 1 || !screent(sol.time, ts, te, tint) || (qflag && sol.stat != qflag)) { + return 0; + } + /* add solution to solution buffer */ + return addsol(solbuf, &sol); } /* read solution data --------------------------------------------------------*/ static int readsoldata(FILE *fp, gtime_t ts, gtime_t te, double tint, int qflag, - const solopt_t *opt, solbuf_t *solbuf) -{ - int c; - - trace(3,"readsoldata:\n"); - - while ((c=fgetc(fp))!=EOF) { - - /* input solution */ - inputsol((uint8_t)c,ts,te,tint,qflag,opt,solbuf); - } - return solbuf->n>0; + const solopt_t *opt, solbuf_t *solbuf) { + int c; + + trace(3, "readsoldata:\n"); + + while ((c = fgetc(fp)) != EOF) { + /* input solution */ + inputsol((uint8_t)c, ts, te, tint, qflag, opt, solbuf); + } + return solbuf->n > 0; } /* compare solution data -----------------------------------------------------*/ -static int cmpsol(const void *p1, const void *p2) -{ - sol_t *q1=(sol_t *)p1,*q2=(sol_t *)p2; - double tt=timediff(q1->time,q2->time); - return tt<-0.0?-1:(tt>0.0?1:0); +static int cmpsol(const void *p1, const void *p2) { + sol_t *q1 = (sol_t *)p1, *q2 = (sol_t *)p2; + double tt = timediff(q1->time, q2->time); + return tt < -0.0 ? -1 : (tt > 0.0 ? 1 : 0); } /* sort solution data --------------------------------------------------------*/ -static int sort_solbuf(solbuf_t *solbuf) -{ - sol_t *solbuf_data; - - trace(4,"sort_solbuf: n=%d\n",solbuf->n); - - if (solbuf->n<=0) return 0; - - if (!(solbuf_data=(sol_t *)realloc(solbuf->data,sizeof(sol_t)*solbuf->n))) { - trace(1,"sort_solbuf: memory allocation error\n"); - free(solbuf->data); solbuf->data=NULL; solbuf->n=solbuf->nmax=0; - return 0; - } - solbuf->data=solbuf_data; - qsort(solbuf->data,solbuf->n,sizeof(sol_t),cmpsol); - solbuf->nmax=solbuf->n; - solbuf->start=0; - solbuf->end=solbuf->n-1; - return 1; +static int sort_solbuf(solbuf_t *solbuf) { + sol_t *solbuf_data; + + trace(4, "sort_solbuf: n=%d\n", solbuf->n); + + if (solbuf->n <= 0) return 0; + + if (!(solbuf_data = (sol_t *)realloc(solbuf->data, sizeof(sol_t) * solbuf->n))) { + trace(1, "sort_solbuf: memory allocation error\n"); + free(solbuf->data); + solbuf->data = NULL; + solbuf->n = solbuf->nmax = 0; + return 0; + } + solbuf->data = solbuf_data; + qsort(solbuf->data, solbuf->n, sizeof(sol_t), cmpsol); + solbuf->nmax = solbuf->n; + solbuf->start = 0; + solbuf->end = solbuf->n - 1; + return 1; } /* read solutions data from solution files ------------------------------------- -* read solution data from solution files -* args : char *files[] I solution files -* int nfile I number of files -* (gtime_t ts) I start time (ts.time==0: from start) -* (gtime_t te) I end time (te.time==0: to end) -* (double tint) I time interval (0: all) -* (int qflag) I quality flag (0: all) -* int mean I calculate the mean when true. -* solbuf_t *solbuf O solution buffer -* return : status (1:ok,0:no data or error) -*-----------------------------------------------------------------------------*/ -extern int readsolt(const char *files[], int nfile, gtime_t ts, gtime_t te, - double tint, int qflag, int mean, solbuf_t *solbuf) -{ - FILE *fp; - solopt_t opt=solopt_default; - int i; - - trace(3,"readsolt: nfile=%d\n",nfile); - - initsolbuf(solbuf,0,0); - - for (i=0;in <= 1) return 1; - if (mean) { - double rr[3]={0}; - for (int i=0;i<3;i++) { - for (int j=0;jn;j++) rr[i]+=solbuf->data[j].rr[i]; - rr[i]/=solbuf->n; - } - sol_t *solbuf_data=(sol_t *)malloc(sizeof(sol_t)); - if (!solbuf_data) { - free(solbuf->data); solbuf->data=NULL; solbuf->n=solbuf->nmax=0; - return 0; - } - *solbuf_data = solbuf->data[solbuf->n - 1]; - solbuf->data = solbuf_data; - for (int i = 0; i < 3; i++) solbuf->data[0].rr[i] = rr[i]; - solbuf->nmax = solbuf->n = 1; - solbuf->start = 0; - solbuf->end = 1; - return 1; - } - return sort_solbuf(solbuf); + * read solution data from solution files + * args : char *files[] I solution files + * int nfile I number of files + * (gtime_t ts) I start time (ts.time==0: from start) + * (gtime_t te) I end time (te.time==0: to end) + * (double tint) I time interval (0: all) + * (int qflag) I quality flag (0: all) + * int mean I calculate the mean when true. + * solbuf_t *solbuf O solution buffer + * return : status (1:ok,0:no data or error) + *-----------------------------------------------------------------------------*/ +extern int readsolt(const char *files[], int nfile, gtime_t ts, gtime_t te, double tint, int qflag, + int mean, solbuf_t *solbuf) { + FILE *fp; + solopt_t opt = solopt_default; + int i; + + trace(3, "readsolt: nfile=%d\n", nfile); + + initsolbuf(solbuf, 0, 0); + + for (i = 0; i < nfile; i++) { + if (!(fp = fopen(files[i], "rb"))) { + trace(2, "readsolt: file open error %s\n", files[i]); + continue; + } + /* read solution options in header */ + readsolopt(fp, &opt); + rewind(fp); + + /* read solution data */ + if (!readsoldata(fp, ts, te, tint, qflag, &opt, solbuf)) { + trace(2, "readsolt: no solution in %s\n", files[i]); + } + fclose(fp); + } + if (solbuf->n <= 1) return 1; + if (mean) { + double rr[3] = {0}; + for (int i = 0; i < 3; i++) { + for (int j = 0; j < solbuf->n; j++) rr[i] += solbuf->data[j].rr[i]; + rr[i] /= solbuf->n; + } + sol_t *solbuf_data = (sol_t *)malloc(sizeof(sol_t)); + if (!solbuf_data) { + free(solbuf->data); + solbuf->data = NULL; + solbuf->n = solbuf->nmax = 0; + return 0; + } + *solbuf_data = solbuf->data[solbuf->n - 1]; + solbuf->data = solbuf_data; + for (int i = 0; i < 3; i++) solbuf->data[0].rr[i] = rr[i]; + solbuf->nmax = solbuf->n = 1; + solbuf->start = 0; + solbuf->end = 1; + return 1; + } + return sort_solbuf(solbuf); } -extern int readsol(const char *files[], int nfile, solbuf_t *sol) -{ - gtime_t time={0}; - - trace(3,"readsol: nfile=%d\n",nfile); - - return readsolt(files,nfile,time,time,0.0,0,0,sol); +extern int readsol(const char *files[], int nfile, solbuf_t *sol) { + gtime_t time = {0}; + + trace(3, "readsol: nfile=%d\n", nfile); + + return readsolt(files, nfile, time, time, 0.0, 0, 0, sol); } /* add solution data to solution buffer ---------------------------------------- -* add solution data to solution buffer -* args : solbuf_t *solbuf IO solution buffer -* sol_t *sol I solution data -* return : status (1:ok,0:error) -*-----------------------------------------------------------------------------*/ -extern int addsol(solbuf_t *solbuf, const sol_t *sol) -{ - sol_t *solbuf_data; - - trace(4,"addsol:\n"); - - if (solbuf->cyclic) { /* ring buffer */ - if (solbuf->nmax<=1) return 0; - solbuf->data[solbuf->end]=*sol; - if (++solbuf->end>=solbuf->nmax) solbuf->end=0; - if (solbuf->start==solbuf->end) { - if (++solbuf->start>=solbuf->nmax) solbuf->start=0; - } - else solbuf->n++; - - return 1; - } - if (solbuf->n>=solbuf->nmax) { - solbuf->nmax=solbuf->nmax==0?8192:solbuf->nmax*2; - if (!(solbuf_data=(sol_t *)realloc(solbuf->data,sizeof(sol_t)*solbuf->nmax))) { - trace(1,"addsol: memory allocation error\n"); - free(solbuf->data); solbuf->data=NULL; solbuf->n=solbuf->nmax=0; - return 0; - } - solbuf->data=solbuf_data; - } - solbuf->data[solbuf->n++]=*sol; + * add solution data to solution buffer + * args : solbuf_t *solbuf IO solution buffer + * sol_t *sol I solution data + * return : status (1:ok,0:error) + *-----------------------------------------------------------------------------*/ +extern int addsol(solbuf_t *solbuf, const sol_t *sol) { + sol_t *solbuf_data; + + trace(4, "addsol:\n"); + + if (solbuf->cyclic) { /* ring buffer */ + if (solbuf->nmax <= 1) return 0; + solbuf->data[solbuf->end] = *sol; + if (++solbuf->end >= solbuf->nmax) solbuf->end = 0; + if (solbuf->start == solbuf->end) { + if (++solbuf->start >= solbuf->nmax) solbuf->start = 0; + } else + solbuf->n++; + return 1; + } + if (solbuf->n >= solbuf->nmax) { + solbuf->nmax = solbuf->nmax == 0 ? 8192 : solbuf->nmax * 2; + if (!(solbuf_data = (sol_t *)realloc(solbuf->data, sizeof(sol_t) * solbuf->nmax))) { + trace(1, "addsol: memory allocation error\n"); + free(solbuf->data); + solbuf->data = NULL; + solbuf->n = solbuf->nmax = 0; + return 0; + } + solbuf->data = solbuf_data; + } + solbuf->data[solbuf->n++] = *sol; + return 1; } /* get solution data from solution buffer -------------------------------------- -* get solution data by index from solution buffer -* args : solbuf_t *solbuf I solution buffer -* int index I index of solution (0...) -* return : solution data pointer (NULL: no solution, out of range) -*-----------------------------------------------------------------------------*/ -extern sol_t *getsol(solbuf_t *solbuf, int index) -{ - trace(4,"getsol: index=%d\n",index); - - if (index<0||solbuf->n<=index) return NULL; - if ((index=solbuf->start+index)>=solbuf->nmax) { - index-=solbuf->nmax; - } - return solbuf->data+index; + * get solution data by index from solution buffer + * args : solbuf_t *solbuf I solution buffer + * int index I index of solution (0...) + * return : solution data pointer (NULL: no solution, out of range) + *-----------------------------------------------------------------------------*/ +extern sol_t *getsol(solbuf_t *solbuf, int index) { + trace(4, "getsol: index=%d\n", index); + + if (index < 0 || solbuf->n <= index) return NULL; + if ((index = solbuf->start + index) >= solbuf->nmax) { + index -= solbuf->nmax; + } + return solbuf->data + index; } /* initialize solution buffer -------------------------------------------------- -* initialize position solutions -* args : solbuf_t *solbuf I solution buffer -* int cyclic I solution data buffer type (0:linear,1:cyclic) -* int nmax I initial number of solution data -* return : status (1:ok,0:error) -*-----------------------------------------------------------------------------*/ -extern void initsolbuf(solbuf_t *solbuf, int cyclic, int nmax) -{ - int i; - - trace(3,"initsolbuf: cyclic=%d nmax=%d\n",cyclic,nmax); - - solbuf->n=solbuf->nmax=solbuf->start=solbuf->end=solbuf->nb=0; - solbuf->cyclic=cyclic; + * initialize position solutions + * args : solbuf_t *solbuf I solution buffer + * int cyclic I solution data buffer type (0:linear,1:cyclic) + * int nmax I initial number of solution data + * return : status (1:ok,0:error) + *-----------------------------------------------------------------------------*/ +extern void initsolbuf(solbuf_t *solbuf, int cyclic, int nmax) { + int i; + + trace(3, "initsolbuf: cyclic=%d nmax=%d\n", cyclic, nmax); + + solbuf->n = solbuf->nmax = solbuf->start = solbuf->end = solbuf->nb = 0; + solbuf->cyclic = cyclic; #ifdef RTK_DISABLED - gtime_t time0={0}; - solbuf->time=time0; + gtime_t time0 = {0}; + solbuf->time = time0; #endif - solbuf->data=NULL; - for (i=0;i<3;i++) { - solbuf->rb[i]=0.0; - } - if (cyclic) { - if (nmax<=2) nmax=2; - if (!(solbuf->data=malloc(sizeof(sol_t)*nmax))) { - trace(1,"initsolbuf: memory allocation error\n"); - return; - } - solbuf->nmax=nmax; - } + solbuf->data = NULL; + for (i = 0; i < 3; i++) { + solbuf->rb[i] = 0.0; + } + if (cyclic) { + if (nmax <= 2) nmax = 2; + if (!(solbuf->data = malloc(sizeof(sol_t) * nmax))) { + trace(1, "initsolbuf: memory allocation error\n"); + return; + } + solbuf->nmax = nmax; + } } /* free solution --------------------------------------------------------------- -* free memory for solution buffer -* args : solbuf_t *solbuf I solution buffer -* return : none -*-----------------------------------------------------------------------------*/ -extern void freesolbuf(solbuf_t *solbuf) -{ - int i; - - trace(3,"freesolbuf: n=%d\n",solbuf->n); - - free(solbuf->data); - solbuf->n=solbuf->nmax=solbuf->start=solbuf->end=solbuf->nb=0; - solbuf->data=NULL; - for (i=0;i<3;i++) { - solbuf->rb[i]=0.0; - } + * free memory for solution buffer + * args : solbuf_t *solbuf I solution buffer + * return : none + *-----------------------------------------------------------------------------*/ +extern void freesolbuf(solbuf_t *solbuf) { + int i; + + trace(3, "freesolbuf: n=%d\n", solbuf->n); + + free(solbuf->data); + solbuf->n = solbuf->nmax = solbuf->start = solbuf->end = solbuf->nb = 0; + solbuf->data = NULL; + for (i = 0; i < 3; i++) { + solbuf->rb[i] = 0.0; + } } -extern void freesolstatbuf(solstatbuf_t *solstatbuf) -{ - trace(3,"freesolstatbuf: n=%d\n",solstatbuf->n); - - solstatbuf->n=solstatbuf->nmax=0; - free(solstatbuf->data); - solstatbuf->data=NULL; +extern void freesolstatbuf(solstatbuf_t *solstatbuf) { + trace(3, "freesolstatbuf: n=%d\n", solstatbuf->n); + + solstatbuf->n = solstatbuf->nmax = 0; + free(solstatbuf->data); + solstatbuf->data = NULL; } /* compare solution status ---------------------------------------------------*/ -static int cmpsolstat(const void *p1, const void *p2) -{ - solstat_t *q1=(solstat_t *)p1,*q2=(solstat_t *)p2; - double tt=timediff(q1->time,q2->time); - if (tt < -0.0) return -1; - if (tt > 0.0) return 1; - if (q1->sat < q2->sat) return -1; - if (q1->sat > q2->sat) return 1; - if (q1->frq < q2->frq) return -1; - if (q1->frq > q2->frq) return 1; - return 0; +static int cmpsolstat(const void *p1, const void *p2) { + solstat_t *q1 = (solstat_t *)p1, *q2 = (solstat_t *)p2; + double tt = timediff(q1->time, q2->time); + if (tt < -0.0) return -1; + if (tt > 0.0) return 1; + if (q1->sat < q2->sat) return -1; + if (q1->sat > q2->sat) return 1; + if (q1->frq < q2->frq) return -1; + if (q1->frq > q2->frq) return 1; + return 0; } /* sort solution data --------------------------------------------------------*/ -static int sort_solstat(solstatbuf_t *statbuf) -{ - solstat_t *statbuf_data; - - trace(4,"sort_solstat: n=%d\n",statbuf->n); - - if (statbuf->n<=0) return 0; - - if (!(statbuf_data=realloc(statbuf->data,sizeof(solstat_t)*statbuf->n))) { - trace(1,"sort_solstat: memory allocation error\n"); - free(statbuf->data); statbuf->data=NULL; statbuf->n=statbuf->nmax=0; - return 0; - } - statbuf->data=statbuf_data; - qsort(statbuf->data,statbuf->n,sizeof(solstat_t),cmpsolstat); - statbuf->nmax=statbuf->n; - return 1; +static int sort_solstat(solstatbuf_t *statbuf) { + solstat_t *statbuf_data; + + trace(4, "sort_solstat: n=%d\n", statbuf->n); + + if (statbuf->n <= 0) return 0; + + if (!(statbuf_data = realloc(statbuf->data, sizeof(solstat_t) * statbuf->n))) { + trace(1, "sort_solstat: memory allocation error\n"); + free(statbuf->data); + statbuf->data = NULL; + statbuf->n = statbuf->nmax = 0; + return 0; + } + statbuf->data = statbuf_data; + qsort(statbuf->data, statbuf->n, sizeof(solstat_t), cmpsolstat); + statbuf->nmax = statbuf->n; + return 1; } /* decode solution status ----------------------------------------------------*/ -static int decode_solstat(char *buff, solstat_t *stat) -{ - static const solstat_t stat0={{0}}; - double tow,az,el,resp,resc,snr; - int n,week,sat,frq,vsat,fix,slip,lock,outc,slipc,rejc; - char id[8]="",*p; - - trace(4,"decode_solstat: buff=%s\n",buff); - - if (strstr(buff,"$SAT")!=buff) return 0; - - for (p=buff;*p;p++) if (*p==',') *p=' '; - - n=sscanf(buff,"$SAT%d%lf%7s%d%lf%lf%lf%lf%d%lf%d%d%d%d%d%d", - &week,&tow,id,&frq,&az,&el,&resp,&resc,&vsat,&snr,&fix,&slip, - &lock,&outc,&slipc,&rejc); - - if (n<15) { - trace(2,"invalid format of solution status: %s\n",buff); - return 0; - } - if ((sat=satid2no(id))<=0) { - trace(2,"invalid satellite in solution status: %s\n",id); - return 0; - } - *stat=stat0; - stat->time=gpst2time(week,tow); - stat->sat =(uint8_t)sat; - stat->frq =(uint8_t)frq; - stat->az =(float)(az*D2R); - stat->el =(float)(el*D2R); - stat->resp =(float)resp; - stat->resc =(float)resc; - stat->flag =(uint8_t)((vsat<<5)+(slip<<3)+fix); - stat->snr =(float)snr; - stat->lock =(uint16_t)lock; - stat->outc =(uint16_t)outc; - stat->slipc=(uint16_t)slipc; - stat->rejc =(uint16_t)rejc; - return 1; +static int decode_solstat(char *buff, solstat_t *stat) { + static const solstat_t stat0 = {{0}}; + double tow, az, el, resp, resc, snr; + int n, week, sat, frq, vsat, fix, slip, lock, outc, slipc, rejc; + char id[8] = "", *p; + + trace(4, "decode_solstat: buff=%s\n", buff); + + if (strstr(buff, "$SAT") != buff) return 0; + + for (p = buff; *p; p++) + if (*p == ',') *p = ' '; + + n = sscanf(buff, "$SAT%d%lf%7s%d%lf%lf%lf%lf%d%lf%d%d%d%d%d%d", &week, &tow, id, &frq, &az, &el, + &resp, &resc, &vsat, &snr, &fix, &slip, &lock, &outc, &slipc, &rejc); + + if (n < 15) { + trace(2, "invalid format of solution status: %s\n", buff); + return 0; + } + if ((sat = satid2no(id)) <= 0) { + trace(2, "invalid satellite in solution status: %s\n", id); + return 0; + } + *stat = stat0; + stat->time = gpst2time(week, tow); + stat->sat = (uint8_t)sat; + stat->frq = (uint8_t)frq; + stat->az = (float)(az * D2R); + stat->el = (float)(el * D2R); + stat->resp = (float)resp; + stat->resc = (float)resc; + stat->flag = (uint8_t)((vsat << 5) + (slip << 3) + fix); + stat->snr = (float)snr; + stat->lock = (uint16_t)lock; + stat->outc = (uint16_t)outc; + stat->slipc = (uint16_t)slipc; + stat->rejc = (uint16_t)rejc; + return 1; } /* add solution status data --------------------------------------------------*/ -static void addsolstat(solstatbuf_t *statbuf, const solstat_t *stat) -{ - solstat_t *statbuf_data; - - trace(4,"addsolstat:\n"); - - if (statbuf->n>=statbuf->nmax) { - statbuf->nmax=statbuf->nmax==0?8192:statbuf->nmax*2; - if (!(statbuf_data=(solstat_t *)realloc(statbuf->data,sizeof(solstat_t)* - statbuf->nmax))) { - trace(1,"addsolstat: memory allocation error\n"); - free(statbuf->data); statbuf->data=NULL; statbuf->n=statbuf->nmax=0; - return; - } - statbuf->data=statbuf_data; - } - statbuf->data[statbuf->n++]=*stat; +static void addsolstat(solstatbuf_t *statbuf, const solstat_t *stat) { + solstat_t *statbuf_data; + + trace(4, "addsolstat:\n"); + + if (statbuf->n >= statbuf->nmax) { + statbuf->nmax = statbuf->nmax == 0 ? 8192 : statbuf->nmax * 2; + if (!(statbuf_data = (solstat_t *)realloc(statbuf->data, sizeof(solstat_t) * statbuf->nmax))) { + trace(1, "addsolstat: memory allocation error\n"); + free(statbuf->data); + statbuf->data = NULL; + statbuf->n = statbuf->nmax = 0; + return; + } + statbuf->data = statbuf_data; + } + statbuf->data[statbuf->n++] = *stat; } /* read solution status data -------------------------------------------------*/ -static int readsolstatdata(FILE *fp, gtime_t ts, gtime_t te, double tint, - solstatbuf_t *statbuf) -{ - solstat_t stat={{0}}; - char buff[MAXSOLLEN+1]; - - trace(3,"readsolstatdata:\n"); - - while (fgets(buff,sizeof(buff),fp)) { - - /* decode solution status */ - if (!decode_solstat(buff,&stat)) continue; - - /* add solution to solution buffer */ - if (screent(stat.time,ts,te,tint)) { - addsolstat(statbuf,&stat); - } +static int readsolstatdata(FILE *fp, gtime_t ts, gtime_t te, double tint, solstatbuf_t *statbuf) { + solstat_t stat = {{0}}; + char buff[MAXSOLLEN + 1]; + + trace(3, "readsolstatdata:\n"); + + while (fgets(buff, sizeof(buff), fp)) { + /* decode solution status */ + if (!decode_solstat(buff, &stat)) continue; + + /* add solution to solution buffer */ + if (screent(stat.time, ts, te, tint)) { + addsolstat(statbuf, &stat); } - return statbuf->n>0; + } + return statbuf->n > 0; } /* read solution status -------------------------------------------------------- -* read solution status from solution status files -* args : char *files[] I solution status files -* int nfile I number of files -* (gtime_t ts) I start time (ts.time==0: from start) -* (gtime_t te) I end time (te.time==0: to end) -* (double tint) I time interval (0: all) -* solstatbuf_t *statbuf O solution status buffer -* return : status (1:ok,0:no data or error) -*-----------------------------------------------------------------------------*/ -extern int readsolstatt(const char *files[], int nfile, gtime_t ts, gtime_t te, - double tint, solstatbuf_t *statbuf) -{ - FILE *fp; - char path[1024],*p; - int i; - - trace(3,"readsolstatt: nfile=%d\n",nfile); - - statbuf->n=statbuf->nmax=0; - statbuf->data=NULL; - - for (i=0;in = statbuf->nmax = 0; + statbuf->data = NULL; + + for (i = 0; i < nfile; i++) { + if ((p = strrchr(files[i], '.')) && !strcmp(p, ".stat")) { + sprintf(path, "%s", files[i]); + } else { + sprintf(path, "%s.stat", files[i]); } - return sort_solstat(statbuf); + if (!(fp = fopen(path, "r"))) { + trace(2, "readsolstatt: file open error %s\n", path); + continue; + } + /* read solution status data */ + if (!readsolstatdata(fp, ts, te, tint, statbuf)) { + trace(2, "readsolstatt: no solution in %s\n", path); + } + fclose(fp); + } + return sort_solstat(statbuf); } -extern int readsolstat(const char *files[], int nfile, solstatbuf_t *statbuf) -{ - gtime_t time={0}; - - trace(3,"readsolstat: nfile=%d\n",nfile); - - return readsolstatt(files,nfile,time,time,0.0,statbuf); +extern int readsolstat(const char *files[], int nfile, solstatbuf_t *statbuf) { + gtime_t time = {0}; + + trace(3, "readsolstat: nfile=%d\n", nfile); + + return readsolstatt(files, nfile, time, time, 0.0, statbuf); } /* output solution as the form of x/y/z-ecef ---------------------------------*/ -static int outecef(uint8_t *buff, const char *s, const sol_t *sol, - const solopt_t *opt) -{ - const char *sep=opt2sep(opt); - char *p=(char *)buff; - - trace(4,"outecef:\n"); - - p+=sprintf(p,"%s%s%14.4f%s%14.4f%s%14.4f%s%3d%s%3d%s%8.4f%s%8.4f%s%8.4f%s" +static int outecef(uint8_t *buff, const char *s, const sol_t *sol, const solopt_t *opt) { + const char *sep = opt2sep(opt); + char *p = (char *)buff; + + trace(4, "outecef:\n"); + + p += sprintf(p, + "%s%s%14.4f%s%14.4f%s%14.4f%s%3d%s%3d%s%8.4f%s%8.4f%s%8.4f%s" "%8.4f%s%8.4f%s%8.4f%s%6.2f%s%6.1f", - s,sep,sol->rr[0],sep,sol->rr[1],sep,sol->rr[2],sep,sol->stat,sep, - sol->ns,sep,SQRT(sol->qr[0]),sep,SQRT(sol->qr[1]),sep, - SQRT(sol->qr[2]),sep,sqvar(sol->qr[3]),sep,sqvar(sol->qr[4]),sep, - sqvar(sol->qr[5]),sep,sol->age,sep,sol->ratio); - - if (opt->outvel) { /* output velocity */ - p+=sprintf(p,"%s%10.5f%s%10.5f%s%10.5f%s%9.5f%s%8.5f%s%8.5f%s%8.5f%s" - "%8.5f%s%8.5f", - sep,sol->rr[3],sep,sol->rr[4],sep,sol->rr[5],sep, - SQRT(sol->qv[0]),sep,SQRT(sol->qv[1]),sep,SQRT(sol->qv[2]), - sep,sqvar(sol->qv[3]),sep,sqvar(sol->qv[4]),sep, - sqvar(sol->qv[5])); - } - p+=sprintf(p,"\r\n"); - return (int)(p-(char *)buff); + s, sep, sol->rr[0], sep, sol->rr[1], sep, sol->rr[2], sep, sol->stat, sep, sol->ns, + sep, SQRT(sol->qr[0]), sep, SQRT(sol->qr[1]), sep, SQRT(sol->qr[2]), sep, + sqvar(sol->qr[3]), sep, sqvar(sol->qr[4]), sep, sqvar(sol->qr[5]), sep, sol->age, + sep, sol->ratio); + + if (opt->outvel) { /* output velocity */ + p += sprintf(p, + "%s%10.5f%s%10.5f%s%10.5f%s%9.5f%s%8.5f%s%8.5f%s%8.5f%s" + "%8.5f%s%8.5f", + sep, sol->rr[3], sep, sol->rr[4], sep, sol->rr[5], sep, SQRT(sol->qv[0]), sep, + SQRT(sol->qv[1]), sep, SQRT(sol->qv[2]), sep, sqvar(sol->qv[3]), sep, + sqvar(sol->qv[4]), sep, sqvar(sol->qv[5])); + } + p += sprintf(p, "\r\n"); + return (int)(p - (char *)buff); } /* output solution as the form of lat/lon/height -----------------------------*/ -static int outpos(uint8_t *buff, const char *s, const sol_t *sol, - const solopt_t *opt) -{ - double pos[3],vel[3],dms1[3],dms2[3],P[9],Q[9]; - const char *sep=opt2sep(opt); - char *p=(char *)buff; - - trace(4,"outpos :\n"); - - ecef2pos(sol->rr,pos); - soltocov(sol,P); - covenu(pos,P,Q); - if (opt->height==1) { /* geodetic height */ - pos[2]-=geoidh(pos); - } - if (opt->degf) { - deg2dms(pos[0]*R2D,dms1,5); - deg2dms(pos[1]*R2D,dms2,5); - p+=sprintf(p,"%s%s%4.0f%s%02.0f%s%08.5f%s%4.0f%s%02.0f%s%08.5f",s,sep, - dms1[0],sep,dms1[1],sep,dms1[2],sep,dms2[0],sep,dms2[1],sep, - dms2[2]); - } - else { - p+=sprintf(p,"%s%s%14.9f%s%14.9f",s,sep,pos[0]*R2D,sep,pos[1]*R2D); - } - p+=sprintf(p,"%s%10.4f%s%3d%s%3d%s%8.4f%s%8.4f%s%8.4f%s%8.4f%s%8.4f%s%8.4f" +static int outpos(uint8_t *buff, const char *s, const sol_t *sol, const solopt_t *opt) { + double pos[3], vel[3], dms1[3], dms2[3], P[9], Q[9]; + const char *sep = opt2sep(opt); + char *p = (char *)buff; + + trace(4, "outpos :\n"); + + ecef2pos(sol->rr, pos); + soltocov(sol, P); + covenu(pos, P, Q); + if (opt->height == 1) { /* geodetic height */ + pos[2] -= geoidh(pos); + } + if (opt->degf) { + deg2dms(pos[0] * R2D, dms1, 5); + deg2dms(pos[1] * R2D, dms2, 5); + p += sprintf(p, "%s%s%4.0f%s%02.0f%s%08.5f%s%4.0f%s%02.0f%s%08.5f", s, sep, dms1[0], sep, + dms1[1], sep, dms1[2], sep, dms2[0], sep, dms2[1], sep, dms2[2]); + } else { + p += sprintf(p, "%s%s%14.9f%s%14.9f", s, sep, pos[0] * R2D, sep, pos[1] * R2D); + } + p += sprintf(p, + "%s%10.4f%s%3d%s%3d%s%8.4f%s%8.4f%s%8.4f%s%8.4f%s%8.4f%s%8.4f" "%s%6.2f%s%6.1f", - sep,pos[2],sep,sol->stat,sep,sol->ns,sep,SQRT(Q[4]),sep, - SQRT(Q[0]),sep,SQRT(Q[8]),sep,sqvar(Q[1]),sep,sqvar(Q[2]), - sep,sqvar(Q[5]),sep,sol->age,sep,sol->ratio); - - if (opt->outvel) { /* output velocity */ - soltocov_vel(sol,P); - ecef2enu(pos,sol->rr+3,vel); - covenu(pos,P,Q); - p+=sprintf(p,"%s%10.5f%s%10.5f%s%10.5f%s%9.5f%s%8.5f%s%8.5f%s%8.5f%s" - "%8.5f%s%8.5f", - sep,vel[1],sep,vel[0],sep,vel[2],sep,SQRT(Q[4]),sep, - SQRT(Q[0]),sep,SQRT(Q[8]),sep,sqvar(Q[1]),sep,sqvar(Q[2]), - sep,sqvar(Q[5])); - } - p+=sprintf(p,"\r\n"); - return (int)(p-(char *)buff); + sep, pos[2], sep, sol->stat, sep, sol->ns, sep, SQRT(Q[4]), sep, SQRT(Q[0]), sep, + SQRT(Q[8]), sep, sqvar(Q[1]), sep, sqvar(Q[2]), sep, sqvar(Q[5]), sep, sol->age, sep, + sol->ratio); + + if (opt->outvel) { /* output velocity */ + soltocov_vel(sol, P); + ecef2enu(pos, sol->rr + 3, vel); + covenu(pos, P, Q); + p += sprintf(p, + "%s%10.5f%s%10.5f%s%10.5f%s%9.5f%s%8.5f%s%8.5f%s%8.5f%s" + "%8.5f%s%8.5f", + sep, vel[1], sep, vel[0], sep, vel[2], sep, SQRT(Q[4]), sep, SQRT(Q[0]), sep, + SQRT(Q[8]), sep, sqvar(Q[1]), sep, sqvar(Q[2]), sep, sqvar(Q[5])); + } + p += sprintf(p, "\r\n"); + return (int)(p - (char *)buff); } /* output solution as the form of e/n/u-baseline -----------------------------*/ -static int outenu(uint8_t *buff, const char *s, const sol_t *sol, - const double *rb, const solopt_t *opt) -{ - double pos[3],rr[3],enu[3],P[9],Q[9]; - int i; - const char *sep=opt2sep(opt); - char *p=(char *)buff; - - trace(4,"outenu :\n"); - - for (i=0;i<3;i++) rr[i]=sol->rr[i]-rb[i]; - ecef2pos(rb,pos); - soltocov(sol,P); - covenu(pos,P,Q); - ecef2enu(pos,rr,enu); - p+=sprintf(p,"%s%s%14.4f%s%14.4f%s%14.4f%s%3d%s%3d%s%8.4f%s%8.4f%s%8.4f%s" +static int outenu(uint8_t *buff, const char *s, const sol_t *sol, const double *rb, + const solopt_t *opt) { + double pos[3], rr[3], enu[3], P[9], Q[9]; + int i; + const char *sep = opt2sep(opt); + char *p = (char *)buff; + + trace(4, "outenu :\n"); + + for (i = 0; i < 3; i++) rr[i] = sol->rr[i] - rb[i]; + ecef2pos(rb, pos); + soltocov(sol, P); + covenu(pos, P, Q); + ecef2enu(pos, rr, enu); + p += sprintf(p, + "%s%s%14.4f%s%14.4f%s%14.4f%s%3d%s%3d%s%8.4f%s%8.4f%s%8.4f%s" "%8.4f%s%8.4f%s%8.4f%s%6.2f%s%6.1f\r\n", - s,sep,enu[0],sep,enu[1],sep,enu[2],sep,sol->stat,sep,sol->ns,sep, - SQRT(Q[0]),sep,SQRT(Q[4]),sep,SQRT(Q[8]),sep,sqvar(Q[1]), - sep,sqvar(Q[5]),sep,sqvar(Q[2]),sep,sol->age,sep,sol->ratio); - return (int)(p-(char *)buff); + s, sep, enu[0], sep, enu[1], sep, enu[2], sep, sol->stat, sep, sol->ns, sep, + SQRT(Q[0]), sep, SQRT(Q[4]), sep, SQRT(Q[8]), sep, sqvar(Q[1]), sep, sqvar(Q[5]), + sep, sqvar(Q[2]), sep, sol->age, sep, sol->ratio); + return (int)(p - (char *)buff); } /* output solution in the form of NMEA RMC sentence --------------------------*/ -extern int outnmea_rmc(uint8_t *buff, const sol_t *sol) -{ - static double dirp=0.0; - gtime_t time; - double ep[6],pos[3],enuv[3],dms1[3],dms2[3],vel,dir,amag=0.0; - char *p=(char *)buff,*q,sum; - const char *emag="E",*mode="A",*status="V"; - - trace(3,"outnmea_rmc:\n"); - - if (sol->stat<=SOLQ_NONE) { - p+=sprintf(p,"$%sRMC,,,,,,,,,,,,,",NMEA_TID); - for (q=(char *)buff+1,sum=0;*q;q++) sum^=*q; - p+=sprintf(p,"*%02X%c%c",sum,0x0D,0x0A); - return (int)(p-(char *)buff); - } - time=gpst2utc(sol->time); - if (time.sec>=0.995) {time.time++; time.sec=0.0;} - time2epoch(time,ep); - ecef2pos(sol->rr,pos); - ecef2enu(pos,sol->rr+3,enuv); - vel=norm(enuv,3); - if (vel>=1.0) { - dir=atan2(enuv[0],enuv[1])*R2D; - if (dir<0.0) dir+=360.0; - dirp=dir; - } - else { - dir=dirp; - } - if (sol->stat==SOLQ_DGPS ||sol->stat==SOLQ_SBAS) mode="D"; - else if (sol->stat==SOLQ_FLOAT||sol->stat==SOLQ_FIX ) mode="R"; - else if (sol->stat==SOLQ_PPP) mode="P"; - deg2dms(fabs(pos[0])*R2D,dms1,7); - deg2dms(fabs(pos[1])*R2D,dms2,7); - p+=sprintf(p,"$%sRMC,%02.0f%02.0f%05.2f,A,%02.0f%010.7f,%s,%03.0f%010.7f," +extern int outnmea_rmc(uint8_t *buff, const sol_t *sol) { + static double dirp = 0.0; + gtime_t time; + double ep[6], pos[3], enuv[3], dms1[3], dms2[3], vel, dir, amag = 0.0; + char *p = (char *)buff, *q, sum; + const char *emag = "E", *mode = "A", *status = "V"; + + trace(3, "outnmea_rmc:\n"); + + if (sol->stat <= SOLQ_NONE) { + p += sprintf(p, "$%sRMC,,,,,,,,,,,,,", NMEA_TID); + for (q = (char *)buff + 1, sum = 0; *q; q++) sum ^= *q; + p += sprintf(p, "*%02X%c%c", sum, 0x0D, 0x0A); + return (int)(p - (char *)buff); + } + time = gpst2utc(sol->time); + if (time.sec >= 0.995) { + time.time++; + time.sec = 0.0; + } + time2epoch(time, ep); + ecef2pos(sol->rr, pos); + ecef2enu(pos, sol->rr + 3, enuv); + vel = norm(enuv, 3); + if (vel >= 1.0) { + dir = atan2(enuv[0], enuv[1]) * R2D; + if (dir < 0.0) dir += 360.0; + dirp = dir; + } else { + dir = dirp; + } + if (sol->stat == SOLQ_DGPS || sol->stat == SOLQ_SBAS) + mode = "D"; + else if (sol->stat == SOLQ_FLOAT || sol->stat == SOLQ_FIX) + mode = "R"; + else if (sol->stat == SOLQ_PPP) + mode = "P"; + deg2dms(fabs(pos[0]) * R2D, dms1, 7); + deg2dms(fabs(pos[1]) * R2D, dms2, 7); + p += sprintf(p, + "$%sRMC,%02.0f%02.0f%05.2f,A,%02.0f%010.7f,%s,%03.0f%010.7f," "%s,%4.2f,%4.2f,%02.0f%02.0f%02d,%.1f,%s,%s,%s", - NMEA_TID,ep[3],ep[4],ep[5],dms1[0],dms1[1]+dms1[2]/60.0, - pos[0]>=0?"N":"S",dms2[0],dms2[1]+dms2[2]/60.0,pos[1]>=0?"E":"W", - vel/KNOT2M,dir,ep[2],ep[1],(int)ep[0]%100,amag,emag,mode,status); - for (q=(char *)buff+1,sum=0;*q;q++) sum^=*q; /* check-sum */ - p+=sprintf(p,"*%02X\r\n",sum); - return (int)(p-(char *)buff); + NMEA_TID, ep[3], ep[4], ep[5], dms1[0], dms1[1] + dms1[2] / 60.0, + pos[0] >= 0 ? "N" : "S", dms2[0], dms2[1] + dms2[2] / 60.0, pos[1] >= 0 ? "E" : "W", + vel / KNOT2M, dir, ep[2], ep[1], (int)ep[0] % 100, amag, emag, mode, status); + for (q = (char *)buff + 1, sum = 0; *q; q++) sum ^= *q; /* check-sum */ + p += sprintf(p, "*%02X\r\n", sum); + return (int)(p - (char *)buff); } /* output solution in the form of NMEA GGA sentence --------------------------*/ -extern int outnmea_gga(uint8_t *buff, const sol_t *sol) -{ - gtime_t time; - double h,ep[6],pos[3],dms1[3],dms2[3],dop=1.0; - int solq; - char *p=(char *)buff,*q,sum; - - trace(3,"outnmea_gga:\n"); - - if (sol->stat<=SOLQ_NONE) { - p+=sprintf(p,"$%sGGA,,,,,,,,,,,,,,",NMEA_TID); - for (q=(char *)buff+1,sum=0;*q;q++) sum^=*q; - p+=sprintf(p,"*%02X%c%c",sum,0x0D,0x0A); - return (int)(p-(char *)buff); - } - for (solq=0;solq<8;solq++) if (nmea_solq[solq]==sol->stat) break; - if (solq>=8) solq=0; - time=gpst2utc(sol->time); - if (time.sec>=0.995) {time.time++; time.sec=0.0;} - time2epoch(time,ep); - ecef2pos(sol->rr,pos); - h=geoidh(pos); - deg2dms(fabs(pos[0])*R2D,dms1,7); - deg2dms(fabs(pos[1])*R2D,dms2,7); - p+=sprintf(p,"$%sGGA,%02.0f%02.0f%05.2f,%02.0f%010.7f,%s,%03.0f%010.7f,%s," +extern int outnmea_gga(uint8_t *buff, const sol_t *sol) { + gtime_t time; + double h, ep[6], pos[3], dms1[3], dms2[3], dop = 1.0; + int solq; + char *p = (char *)buff, *q, sum; + + trace(3, "outnmea_gga:\n"); + + if (sol->stat <= SOLQ_NONE) { + p += sprintf(p, "$%sGGA,,,,,,,,,,,,,,", NMEA_TID); + for (q = (char *)buff + 1, sum = 0; *q; q++) sum ^= *q; + p += sprintf(p, "*%02X%c%c", sum, 0x0D, 0x0A); + return (int)(p - (char *)buff); + } + for (solq = 0; solq < 8; solq++) + if (nmea_solq[solq] == sol->stat) break; + if (solq >= 8) solq = 0; + time = gpst2utc(sol->time); + if (time.sec >= 0.995) { + time.time++; + time.sec = 0.0; + } + time2epoch(time, ep); + ecef2pos(sol->rr, pos); + h = geoidh(pos); + deg2dms(fabs(pos[0]) * R2D, dms1, 7); + deg2dms(fabs(pos[1]) * R2D, dms2, 7); + p += sprintf(p, + "$%sGGA,%02.0f%02.0f%05.2f,%02.0f%010.7f,%s,%03.0f%010.7f,%s," "%d,%02d,%.1f,%.3f,M,%.3f,M,%.1f,%04d", - NMEA_TID,ep[3],ep[4],ep[5],dms1[0],dms1[1]+dms1[2]/60.0, - pos[0]>=0?"N":"S",dms2[0],dms2[1]+dms2[2]/60.0,pos[1]>=0?"E":"W", - solq,sol->ns,dop,pos[2]-h,h,sol->age,sol->refstationid); - for (q=(char *)buff+1,sum=0;*q;q++) sum^=*q; /* check-sum */ - p+=sprintf(p,"*%02X\r\n",sum); - return (int)(p-(char *)buff); + NMEA_TID, ep[3], ep[4], ep[5], dms1[0], dms1[1] + dms1[2] / 60.0, + pos[0] >= 0 ? "N" : "S", dms2[0], dms2[1] + dms2[2] / 60.0, pos[1] >= 0 ? "E" : "W", + solq, sol->ns, dop, pos[2] - h, h, sol->age, sol->refstationid); + for (q = (char *)buff + 1, sum = 0; *q; q++) sum ^= *q; /* check-sum */ + p += sprintf(p, "*%02X\r\n", sum); + return (int)(p - (char *)buff); } // Output NMEA GST sentence (Estimated error in position) ---------------------- -extern int outnmea_gst(uint8_t *buff, const sol_t *sol) -{ - trace(3,"outnmea_gst:\n"); - - if (sol->stat <= SOLQ_NONE) return 0; - gtime_t time = gpst2utc(sol->time); - if (time.sec >= 0.995) {time.time++; time.sec=0.0;} - double ep[6]; - time2epoch(time,ep); - - // TODO RMS of std of range inputs. - double rms = 0.0; - - double pos[3]; - ecef2pos(sol->rr, pos); - double P[9]; - soltocov(sol, P); - double Q[9]; - covenu(pos, P, Q); - double lat_std = SQRT(Q[4]), lon_std = SQRT(Q[0]), height_std = SQRT(Q[8]); - - // Error ellipse std of semi-major and minor axis (m) and angle from north. - double angle = 0, smajor = 0, sminor = 0; - if (Q[0] == 0) { - angle = 0; - smajor = SQRT(Q[4]); - sminor = 0; - } else if (Q[4] == 0) { - angle = PI / 2; - smajor = SQRT(Q[0]); - sminor = 0; - } else if (fabs(Q[0] - Q[4]) < 1e-6) { - angle = 0; - smajor = SQRT(Q[4]); - sminor = SQRT(Q[0]); +extern int outnmea_gst(uint8_t *buff, const sol_t *sol) { + trace(3, "outnmea_gst:\n"); + + if (sol->stat <= SOLQ_NONE) return 0; + gtime_t time = gpst2utc(sol->time); + if (time.sec >= 0.995) { + time.time++; + time.sec = 0.0; + } + double ep[6]; + time2epoch(time, ep); + + // TODO RMS of std of range inputs. + double rms = 0.0; + + double pos[3]; + ecef2pos(sol->rr, pos); + double P[9]; + soltocov(sol, P); + double Q[9]; + covenu(pos, P, Q); + double lat_std = SQRT(Q[4]), lon_std = SQRT(Q[0]), height_std = SQRT(Q[8]); + + // Error ellipse std of semi-major and minor axis (m) and angle from north. + double angle = 0, smajor = 0, sminor = 0; + if (Q[0] == 0) { + angle = 0; + smajor = SQRT(Q[4]); + sminor = 0; + } else if (Q[4] == 0) { + angle = PI / 2; + smajor = SQRT(Q[0]); + sminor = 0; + } else if (fabs(Q[0] - Q[4]) < 1e-6) { + angle = 0; + smajor = SQRT(Q[4]); + sminor = SQRT(Q[0]); + } else { + // Jacobi method. + double tau = (Q[4] - Q[0]) / Q[1] / 2; + double t = copysign(1, tau) / (fabs(tau) + SQRT(1 + tau * tau)); + double c = 1 / SQRT(1 + t * t), s = t * c; + double l1 = Q[0] - t * Q[1], l2 = Q[4] + t * Q[1]; + // Largest eigen value defines the orientation, an angle from north. + if (fabs(l1) > fabs(l2)) { + angle = atan2(c, -s); + smajor = SQRT(l1); + sminor = SQRT(l2); } else { - // Jacobi method. - double tau = (Q[4] - Q[0])/ Q[1] / 2; - double t = copysign(1, tau) / (fabs(tau) + SQRT(1 + tau * tau)); - double c = 1 / SQRT(1 + t * t), s = t * c; - double l1 = Q[0] - t * Q[1], l2 = Q[4] + t * Q[1]; - // Largest eigen value defines the orientation, an angle from north. - if (fabs(l1) > fabs(l2)) { - angle = atan2(c, -s); - smajor = SQRT(l1); - sminor = SQRT(l2); - } - else { - angle = atan2(s, c); - smajor = SQRT(l2); - sminor = SQRT(l1); - } + angle = atan2(s, c); + smajor = SQRT(l2); + sminor = SQRT(l1); } + } - char *p = (char *)buff; - p += sprintf(p,"$%sGST,%02.0f%02.0f%05.2f,%.3f,%.4f,%.4f,%.3f,%.4f,%.4f,%.4f", - NMEA_TID, ep[3], ep[4], ep[5], - rms, smajor, sminor, angle * R2D, - lat_std, lon_std, height_std); - char sum = 0; - for (char *q = (char *)buff + 1; *q; q++) sum ^= *q; // Check-sum. - p += sprintf(p, "*%02X\r\n", sum); - return (int)(p - (char *)buff); + char *p = (char *)buff; + p += sprintf(p, "$%sGST,%02.0f%02.0f%05.2f,%.3f,%.4f,%.4f,%.3f,%.4f,%.4f,%.4f", NMEA_TID, ep[3], + ep[4], ep[5], rms, smajor, sminor, angle * R2D, lat_std, lon_std, height_std); + char sum = 0; + for (char *q = (char *)buff + 1; *q; q++) sum ^= *q; // Check-sum. + p += sprintf(p, "*%02X\r\n", sum); + return (int)(p - (char *)buff); } /* output solution in the form of NMEA GSA sentences -------------------------*/ -extern int outnmea_gsa(uint8_t *buff, const sol_t *sol, const ssat_t *ssat) -{ - double azel[MAXSAT*2],dop[4]; - char *p=(char *)buff,*q,*s,sum; - int i,j,sys,nsat,mask=0,nsys=0,sats[MAXSAT]; - - trace(3,"outnmea_gsa:\n"); - - for (i=nsat=0;i0) { - s=p; - p+=sprintf(p,"$%sGSA,A,%d",nsys>1?"GN":nmea_tid[i],sol->stat?3:1); - for (j=0;j<12;j++) { - if (j 0) { + s = p; + p += sprintf(p, "$%sGSA,A,%d", nsys > 1 ? "GN" : nmea_tid[i], sol->stat ? 3 : 1); + for (j = 0; j < 12; j++) { + if (j < nsat) { + int prn; + sys = satsys(sats[j], &prn); + if (sys == SYS_SBS) + prn -= 87; /* SBS: 33-64 */ + else if (sys == SYS_GLO) + prn += 64; /* GLO: 65-99 */ + else if (sys == SYS_QZS) + prn -= 192; /* QZS: 01-10 */ + p += sprintf(p, ",%02d", prn); + } else + p += sprintf(p, ","); + } + p += sprintf(p, ",%3.1f,%3.1f,%3.1f,%d", dop[1], dop[2], dop[3], nmea_sid[i]); + for (q = s + 1, sum = 0; *q; q++) sum ^= *q; /* check-sum */ + p += sprintf(p, "*%02X\r\n", sum); } - return (int)(p-(char *)buff); + } + return (int)(p - (char *)buff); } /* output solution in the form of NMEA GSV sentences -------------------------*/ -extern int outnmea_gsv(uint8_t *buff, const sol_t *sol, const ssat_t *ssat) -{ - (void)sol; - double az,el,snr; - int i,j,k,n,nsat,nmsg,prn,sys,sats[MAXSAT]; - char *p=(char *)buff,*q,*s,sum; - - trace(3,"outnmea_gsv:\n"); - - for (i=0;nmea_sys[i];i++) { - for (j=nsat=0;j0.0) sats[nsat++]=j+1; +extern int outnmea_gsv(uint8_t *buff, const sol_t *sol, const ssat_t *ssat) { + (void)sol; + double az, el, snr; + int i, j, k, n, nsat, nmsg, prn, sys, sats[MAXSAT]; + char *p = (char *)buff, *q, *s, sum; + + trace(3, "outnmea_gsv:\n"); + + for (i = 0; nmea_sys[i]; i++) { + for (j = nsat = 0; j < MAXSAT && nsat < 36; j++) { + if (!(satsys(j + 1, NULL) & nmea_sys[i])) continue; + if (ssat[j].azel[1] > 0.0) sats[nsat++] = j + 1; } - nmsg=(nsat+3)/4; - - for (j=n=0;jmode]); - - if (PMODE_DGPS<=opt->mode) { - p+=sprintf(p,"%s freqs : %s\r\n",COMMENTH,s2[opt->nf-1]); - } - if (opt->mode>PMODE_SINGLE) { - p+=sprintf(p,"%s solution : %s\r\n",COMMENTH,s3[opt->soltype]); - } - p+=sprintf(p,"%s elev mask : %.1f deg\r\n",COMMENTH,opt->elmin*R2D); - if (opt->mode>PMODE_SINGLE) - p+=sprintf(p,"%s dynamics : %s\r\n",COMMENTH,opt->dynamics?"on":"off"); - p += sprintf(p, "%s tidecorr :", COMMENTH); - if (opt->tidecorr & 1) p += sprintf(p, " solid"); - if (opt->tidecorr & 2) p += sprintf(p, " otl"); - if (opt->tidecorr & 4) p += sprintf(p, " spole"); - p+=sprintf(p,"\r\n"); - p+=sprintf(p,"%s ionos opt : %s\r\n",COMMENTH,s4[opt->ionoopt]); - p+=sprintf(p,"%s tropo opt : %s\r\n",COMMENTH,s5[opt->tropopt]); - p+=sprintf(p,"%s ephemeris : %s\r\n",COMMENTH,s6[opt->sateph]); - p+=sprintf(p,"%s navi sys :",COMMENTH); - for (i=0;sys[i];i++) { - if (opt->navsys&sys[i]) p+=sprintf(p," %s",s7[i]); - } - p+=sprintf(p,"\r\n"); - if (PMODE_KINEMA<=opt->mode&&opt->mode<=PMODE_FIXED) { - p+=sprintf(p,"%s amb res : %s\r\n",COMMENTH,s8[opt->modear]); - if (opt->navsys&SYS_GLO) { - p+=sprintf(p,"%s amb glo : %s\r\n",COMMENTH,s9[opt->glomodear]); - } - if (opt->navsys&SYS_CMP) { - p+=sprintf(p,"%s amb bds : %s\r\n",COMMENTH,opt->bdsmodear?"on":"off"); - } - if (opt->thresar[0]>0.0) { - p+=sprintf(p,"%s val thres : %.1f\r\n",COMMENTH,opt->thresar[0]); - } - } - if (opt->mode==PMODE_MOVEB&&opt->baseline[0]>0.0) { - p+=sprintf(p,"%s baseline : %.4f %.4f m\r\n",COMMENTH, - opt->baseline[0],opt->baseline[1]); - } - for (i=0;i<2;i++) { - if (opt->mode==PMODE_SINGLE||(i>=1&&opt->mode>PMODE_FIXED)) continue; - p+=sprintf(p,"%s antenna%d : %-21s (%7.4f %7.4f %7.4f)\r\n",COMMENTH, - i+1,opt->anttype[i],opt->antdel[i][0],opt->antdel[i][1], - opt->antdel[i][2]); - } - return (int)(p-(char *)buff); + * output processing options to buffer + * args : uint8_t *buff IO output buffer + * prcopt_t *opt I processing options + * return : number of output bytes + *-----------------------------------------------------------------------------*/ +extern int outprcopts(uint8_t *buff, const prcopt_t *opt) { + const int sys[] = {SYS_GPS, SYS_GLO, SYS_GAL, SYS_QZS, SYS_CMP, SYS_IRN, SYS_SBS, 0}; + const char *s1[] = {"Single", + "DGPS", + "Kinematic", + "Static", + "Static-Start", + "Moving-Base", + "Fixed", + "PPP Kinematic", + "PPP Static", + "PPP Fixed", + "", + "", + ""}; + const char *s2[] = { + "L1", "L1+L2/E5b", "L1+L2/E5b+L5", "L1+L2/E5b+L5+L6", "L1+2+3+4+5", "L1+2+3+4+5+6", "", + "", ""}; + const char *s3[] = {"Forward", "Backward", "Combined-Phase Reset", "Combined-No Phase Reset", + "", ""}; + const char *s4[] = { + "OFF", "Broadcast", "SBAS", "Iono-Free LC", "Estimate TEC", "IONEX TEC", "QZSS Broadcast", "", + "", "", ""}; + const char *s5[] = {"OFF", "Saastamoinen", "SBAS", "Estimate ZTD", "Estimate ZTD+Grad", "", "", + ""}; + const char *s6[] = {"Broadcast", + "Precise", + "Broadcast+SBAS", + "Broadcast+SSR APC", + "Broadcast+SSR CoM", + "Precise (CoM)", + "", + ""}; + const char *s7[] = {"GPS", "GLONASS", "Galileo", "QZSS", "BDS", "NavIC", "SBAS", "", "", ""}; + const char *s8[] = {"OFF", "Continuous", "Instantaneous", "Fix and Hold", "", "", ""}; + const char *s9[] = {"OFF", "ON", "AutoCal", "Fix and Hold", ""}; + int i; + char *p = (char *)buff; + + trace(3, "outprcopts:\n"); + + p += sprintf(p, "%s pos mode : %s\r\n", COMMENTH, s1[opt->mode]); + + if (PMODE_DGPS <= opt->mode) { + p += sprintf(p, "%s freqs : %s\r\n", COMMENTH, s2[opt->nf - 1]); + } + if (opt->mode > PMODE_SINGLE) { + p += sprintf(p, "%s solution : %s\r\n", COMMENTH, s3[opt->soltype]); + } + p += sprintf(p, "%s elev mask : %.1f deg\r\n", COMMENTH, opt->elmin * R2D); + if (opt->mode > PMODE_SINGLE) + p += sprintf(p, "%s dynamics : %s\r\n", COMMENTH, opt->dynamics ? "on" : "off"); + p += sprintf(p, "%s tidecorr :", COMMENTH); + if (opt->tidecorr & 1) p += sprintf(p, " solid"); + if (opt->tidecorr & 2) p += sprintf(p, " otl"); + if (opt->tidecorr & 4) p += sprintf(p, " spole"); + p += sprintf(p, "\r\n"); + p += sprintf(p, "%s ionos opt : %s\r\n", COMMENTH, s4[opt->ionoopt]); + p += sprintf(p, "%s tropo opt : %s\r\n", COMMENTH, s5[opt->tropopt]); + p += sprintf(p, "%s ephemeris : %s\r\n", COMMENTH, s6[opt->sateph]); + p += sprintf(p, "%s navi sys :", COMMENTH); + for (i = 0; sys[i]; i++) { + if (opt->navsys & sys[i]) p += sprintf(p, " %s", s7[i]); + } + p += sprintf(p, "\r\n"); + if (PMODE_KINEMA <= opt->mode && opt->mode <= PMODE_FIXED) { + p += sprintf(p, "%s amb res : %s\r\n", COMMENTH, s8[opt->modear]); + if (opt->navsys & SYS_GLO) { + p += sprintf(p, "%s amb glo : %s\r\n", COMMENTH, s9[opt->glomodear]); + } + if (opt->navsys & SYS_CMP) { + p += sprintf(p, "%s amb bds : %s\r\n", COMMENTH, opt->bdsmodear ? "on" : "off"); + } + if (opt->thresar[0] > 0.0) { + p += sprintf(p, "%s val thres : %.1f\r\n", COMMENTH, opt->thresar[0]); + } + } + if (opt->mode == PMODE_MOVEB && opt->baseline[0] > 0.0) { + p += sprintf(p, "%s baseline : %.4f %.4f m\r\n", COMMENTH, opt->baseline[0], opt->baseline[1]); + } + for (i = 0; i < 2; i++) { + if (opt->mode == PMODE_SINGLE || (i >= 1 && opt->mode > PMODE_FIXED)) continue; + p += sprintf(p, "%s antenna%d : %-21s (%7.4f %7.4f %7.4f)\r\n", COMMENTH, i + 1, + opt->anttype[i], opt->antdel[i][0], opt->antdel[i][1], opt->antdel[i][2]); + } + return (int)(p - (char *)buff); } /* output solution header ------------------------------------------------------ -* output solution header to buffer -* args : uint8_t *buff IO output buffer -* solopt_t *opt I solution options -* return : number of output bytes -*-----------------------------------------------------------------------------*/ -extern int outsolheads(uint8_t *buff, const solopt_t *opt) -{ - const char *s1[]={"WGS84","Tokyo"},*s2[]={"ellipsoidal","geodetic"}; - const char *s3[]={"GPST","UTC ","JST "},*sep=opt2sep(opt); - const char *leg1="Q=1:fix,2:float,3:sbas,4:dgps,5:single,6:ppp"; - const char *leg2="ns=# of satellites"; - char *p=(char *)buff; - int timeu=opt->timeu<0?0:(opt->timeu>20?20:opt->timeu); - - trace(3,"outsolheads:\n"); - - if (opt->posf==SOLF_NMEA||opt->posf==SOLF_STAT||opt->posf==SOLF_GSIF) { - return 0; - } - if (opt->outhead) { - p+=sprintf(p,"%s (",COMMENTH); - if (opt->posf==SOLF_XYZ) p+=sprintf(p,"x/y/z-ecef=WGS84"); - else if (opt->posf==SOLF_ENU) p+=sprintf(p,"e/n/u-baseline=WGS84"); - else p+=sprintf(p,"lat/lon/height=%s/%s",s1[opt->datum],s2[opt->height]); - p+=sprintf(p,",%s,%s)\r\n",leg1,leg2); - } - p+=sprintf(p,"%s %-*s%s",COMMENTH,(opt->timef?16:8)+timeu+1,s3[opt->times], - sep); - - if (opt->posf==SOLF_LLH) { /* lat/lon/hgt */ - if (opt->degf) { - p+=sprintf(p,"%16s%s%16s%s%10s%s%3s%s%3s%s%8s%s%8s%s%8s%s%8s%s%8s%s" - "%8s%s%6s%s%6s", - "latitude(d'\")",sep,"longitude(d'\")",sep,"height(m)", - sep,"Q",sep,"ns",sep,"sdn(m)",sep,"sde(m)",sep,"sdu(m)", - sep,"sdne(m)",sep,"sdeu(m)",sep,"sdue(m)",sep,"age(s)", - sep,"ratio"); - } - else { - p+=sprintf(p,"%14s%s%14s%s%10s%s%3s%s%3s%s%8s%s%8s%s%8s%s%8s%s%8s%s" - "%8s%s%6s%s%6s", - "latitude(deg)",sep,"longitude(deg)",sep,"height(m)",sep, - "Q",sep,"ns",sep,"sdn(m)",sep,"sde(m)",sep,"sdu(m)",sep, - "sdne(m)",sep,"sdeu(m)",sep,"sdun(m)",sep,"age(s)",sep, - "ratio"); - } - if (opt->outvel) { - p+=sprintf(p,"%s%10s%s%10s%s%10s%s%9s%s%8s%s%8s%s%8s%s%8s%s%8s", - sep,"vn(m/s)",sep,"ve(m/s)",sep,"vu(m/s)",sep,"sdvn",sep, - "sdve",sep,"sdvu",sep,"sdvne",sep,"sdveu",sep,"sdvun"); - } - } - else if (opt->posf==SOLF_XYZ) { /* x/y/z-ecef */ - p+=sprintf(p,"%14s%s%14s%s%14s%s%3s%s%3s%s%8s%s%8s%s%8s%s%8s%s%8s%s%8s" - "%s%6s%s%6s", - "x-ecef(m)",sep,"y-ecef(m)",sep,"z-ecef(m)",sep,"Q",sep,"ns", - sep,"sdx(m)",sep,"sdy(m)",sep,"sdz(m)",sep,"sdxy(m)",sep, - "sdyz(m)",sep,"sdzx(m)",sep,"age(s)",sep,"ratio"); - - if (opt->outvel) { - p+=sprintf(p,"%s%10s%s%10s%s%10s%s%9s%s%8s%s%8s%s%8s%s%8s%s%8s", - sep,"vx(m/s)",sep,"vy(m/s)",sep,"vz(m/s)",sep,"sdvx",sep, - "sdvy",sep,"sdvz",sep,"sdvxy",sep,"sdvyz",sep,"sdvzx"); - } - } - else if (opt->posf==SOLF_ENU) { /* e/n/u-baseline */ - p+=sprintf(p,"%14s%s%14s%s%14s%s%3s%s%3s%s%8s%s%8s%s%8s%s%8s%s%8s%s%8s" - "%s%6s%s%6s", - "e-baseline(m)",sep,"n-baseline(m)",sep,"u-baseline(m)",sep, - "Q",sep,"ns",sep,"sde(m)",sep,"sdn(m)",sep,"sdu(m)",sep, - "sden(m)",sep,"sdnu(m)",sep,"sdue(m)",sep,"age(s)",sep, - "ratio"); - if (opt->outvel) { - p+=sprintf(p,"%s%10s%s%10s%s%10s%s%9s%s%8s%s%8s%s%8s%s%8s%s%8s", - sep,"ve(m/s)",sep,"vn(m/s)",sep,"vu(m/s)",sep,"sdve",sep, - "sdvn",sep,"sdvu",sep,"sdven",sep,"sdvnu",sep,"sdvue"); - } - } - p+=sprintf(p,"\r\n"); - return (int)(p-(char *)buff); + * output solution header to buffer + * args : uint8_t *buff IO output buffer + * solopt_t *opt I solution options + * return : number of output bytes + *-----------------------------------------------------------------------------*/ +extern int outsolheads(uint8_t *buff, const solopt_t *opt) { + const char *s1[] = {"WGS84", "Tokyo"}, *s2[] = {"ellipsoidal", "geodetic"}; + const char *s3[] = {"GPST", "UTC ", "JST "}, *sep = opt2sep(opt); + const char *leg1 = "Q=1:fix,2:float,3:sbas,4:dgps,5:single,6:ppp"; + const char *leg2 = "ns=# of satellites"; + char *p = (char *)buff; + int timeu = opt->timeu < 0 ? 0 : (opt->timeu > 20 ? 20 : opt->timeu); + + trace(3, "outsolheads:\n"); + + if (opt->posf == SOLF_NMEA || opt->posf == SOLF_STAT || opt->posf == SOLF_GSIF) { + return 0; + } + if (opt->outhead) { + p += sprintf(p, "%s (", COMMENTH); + if (opt->posf == SOLF_XYZ) + p += sprintf(p, "x/y/z-ecef=WGS84"); + else if (opt->posf == SOLF_ENU) + p += sprintf(p, "e/n/u-baseline=WGS84"); + else + p += sprintf(p, "lat/lon/height=%s/%s", s1[opt->datum], s2[opt->height]); + p += sprintf(p, ",%s,%s)\r\n", leg1, leg2); + } + p += sprintf(p, "%s %-*s%s", COMMENTH, (opt->timef ? 16 : 8) + timeu + 1, s3[opt->times], sep); + + if (opt->posf == SOLF_LLH) { /* lat/lon/hgt */ + if (opt->degf) { + p += sprintf(p, + "%16s%s%16s%s%10s%s%3s%s%3s%s%8s%s%8s%s%8s%s%8s%s%8s%s" + "%8s%s%6s%s%6s", + "latitude(d'\")", sep, "longitude(d'\")", sep, "height(m)", sep, "Q", sep, "ns", + sep, "sdn(m)", sep, "sde(m)", sep, "sdu(m)", sep, "sdne(m)", sep, "sdeu(m)", sep, + "sdue(m)", sep, "age(s)", sep, "ratio"); + } else { + p += sprintf(p, + "%14s%s%14s%s%10s%s%3s%s%3s%s%8s%s%8s%s%8s%s%8s%s%8s%s" + "%8s%s%6s%s%6s", + "latitude(deg)", sep, "longitude(deg)", sep, "height(m)", sep, "Q", sep, "ns", + sep, "sdn(m)", sep, "sde(m)", sep, "sdu(m)", sep, "sdne(m)", sep, "sdeu(m)", sep, + "sdun(m)", sep, "age(s)", sep, "ratio"); + } + if (opt->outvel) { + p += sprintf(p, "%s%10s%s%10s%s%10s%s%9s%s%8s%s%8s%s%8s%s%8s%s%8s", sep, "vn(m/s)", sep, + "ve(m/s)", sep, "vu(m/s)", sep, "sdvn", sep, "sdve", sep, "sdvu", sep, "sdvne", + sep, "sdveu", sep, "sdvun"); + } + } else if (opt->posf == SOLF_XYZ) { /* x/y/z-ecef */ + p += sprintf(p, + "%14s%s%14s%s%14s%s%3s%s%3s%s%8s%s%8s%s%8s%s%8s%s%8s%s%8s" + "%s%6s%s%6s", + "x-ecef(m)", sep, "y-ecef(m)", sep, "z-ecef(m)", sep, "Q", sep, "ns", sep, + "sdx(m)", sep, "sdy(m)", sep, "sdz(m)", sep, "sdxy(m)", sep, "sdyz(m)", sep, + "sdzx(m)", sep, "age(s)", sep, "ratio"); + + if (opt->outvel) { + p += sprintf(p, "%s%10s%s%10s%s%10s%s%9s%s%8s%s%8s%s%8s%s%8s%s%8s", sep, "vx(m/s)", sep, + "vy(m/s)", sep, "vz(m/s)", sep, "sdvx", sep, "sdvy", sep, "sdvz", sep, "sdvxy", + sep, "sdvyz", sep, "sdvzx"); + } + } else if (opt->posf == SOLF_ENU) { /* e/n/u-baseline */ + p += sprintf(p, + "%14s%s%14s%s%14s%s%3s%s%3s%s%8s%s%8s%s%8s%s%8s%s%8s%s%8s" + "%s%6s%s%6s", + "e-baseline(m)", sep, "n-baseline(m)", sep, "u-baseline(m)", sep, "Q", sep, "ns", + sep, "sde(m)", sep, "sdn(m)", sep, "sdu(m)", sep, "sden(m)", sep, "sdnu(m)", sep, + "sdue(m)", sep, "age(s)", sep, "ratio"); + if (opt->outvel) { + p += sprintf(p, "%s%10s%s%10s%s%10s%s%9s%s%8s%s%8s%s%8s%s%8s%s%8s", sep, "ve(m/s)", sep, + "vn(m/s)", sep, "vu(m/s)", sep, "sdve", sep, "sdvn", sep, "sdvu", sep, "sdven", + sep, "sdvnu", sep, "sdvue"); + } + } + p += sprintf(p, "\r\n"); + return (int)(p - (char *)buff); } /* std-dev of solution -------------------------------------------------------*/ -static double sol_std(const sol_t *sol) -{ - /* approximate as max std-dev of 3-axis std-devs */ - if (sol->qr[0]>sol->qr[1]&&sol->qr[0]>sol->qr[2]) return SQRT(sol->qr[0]); - if (sol->qr[1]>sol->qr[2]) return SQRT(sol->qr[1]); - return SQRT(sol->qr[2]); +static double sol_std(const sol_t *sol) { + /* approximate as max std-dev of 3-axis std-devs */ + if (sol->qr[0] > sol->qr[1] && sol->qr[0] > sol->qr[2]) return SQRT(sol->qr[0]); + if (sol->qr[1] > sol->qr[2]) return SQRT(sol->qr[1]); + return SQRT(sol->qr[2]); } /* output solution body -------------------------------------------------------- -* output solution body to buffer -* args : uint8_t *buff IO output buffer -* sol_t *sol I solution -* double *rb I base station position {x,y,z} (ecef) (m) -* solopt_t *opt I solution options -* return : number of output bytes -*-----------------------------------------------------------------------------*/ -extern int outsols(uint8_t *buff, const sol_t *sol, const double *rb, - const solopt_t *opt) -{ - gtime_t time,ts={0}; - double gpst; - int week,timeu; - const char *sep=opt2sep(opt); - char s[40]; - uint8_t *p=buff; - - trace(4,"outsols :\n"); - - /* suppress output if std is over opt->maxsolstd */ - if (opt->maxsolstd>0.0&&sol_std(sol)>opt->maxsolstd) { - return 0; - } - if (opt->posf==SOLF_NMEA) { - if (opt->nmeaintv[0]<0.0) return 0; - if (!screent(sol->time,ts,ts,opt->nmeaintv[0])) return 0; - } - if (sol->stat<=SOLQ_NONE||(opt->posf==SOLF_ENU&&norm(rb,3)<=0.0)) { - return 0; - } - timeu=opt->timeu<0?0:(opt->timeu>20?20:opt->timeu); - - time=sol->time; - if (opt->times>=TIMES_UTC) time=gpst2utc(time); - if (opt->times==TIMES_JST) time=timeadd(time,9*3600.0); - - if (opt->timef) time2str(time,s,timeu); - else { - gpst=time2gpst(time,&week); - if (86400*7-gpst<0.5/pow(10.0,timeu)) { - week++; - gpst=0.0; - } - sprintf(s,"%4d%.16s%*.*f",week,sep,6+(timeu<=0?0:timeu+1),timeu,gpst); - } - switch (opt->posf) { - case SOLF_LLH: p+=outpos (p,s,sol,opt); break; - case SOLF_XYZ: p+=outecef(p,s,sol,opt); break; - case SOLF_ENU: p+=outenu(p,s,sol,rb,opt); break; - case SOLF_NMEA: p+=outnmea_rmc(p,sol); - p+=outnmea_gga(p,sol); - p+=outnmea_gst(p,sol); - break; - } - return (int)(p-buff); + * output solution body to buffer + * args : uint8_t *buff IO output buffer + * sol_t *sol I solution + * double *rb I base station position {x,y,z} (ecef) (m) + * solopt_t *opt I solution options + * return : number of output bytes + *-----------------------------------------------------------------------------*/ +extern int outsols(uint8_t *buff, const sol_t *sol, const double *rb, const solopt_t *opt) { + gtime_t time, ts = {0}; + double gpst; + int week, timeu; + const char *sep = opt2sep(opt); + char s[40]; + uint8_t *p = buff; + + trace(4, "outsols :\n"); + + /* suppress output if std is over opt->maxsolstd */ + if (opt->maxsolstd > 0.0 && sol_std(sol) > opt->maxsolstd) { + return 0; + } + if (opt->posf == SOLF_NMEA) { + if (opt->nmeaintv[0] < 0.0) return 0; + if (!screent(sol->time, ts, ts, opt->nmeaintv[0])) return 0; + } + if (sol->stat <= SOLQ_NONE || (opt->posf == SOLF_ENU && norm(rb, 3) <= 0.0)) { + return 0; + } + timeu = opt->timeu < 0 ? 0 : (opt->timeu > 20 ? 20 : opt->timeu); + + time = sol->time; + if (opt->times >= TIMES_UTC) time = gpst2utc(time); + if (opt->times == TIMES_JST) time = timeadd(time, 9 * 3600.0); + + if (opt->timef) + time2str(time, s, timeu); + else { + gpst = time2gpst(time, &week); + if (86400 * 7 - gpst < 0.5 / pow(10.0, timeu)) { + week++; + gpst = 0.0; + } + sprintf(s, "%4d%.16s%*.*f", week, sep, 6 + (timeu <= 0 ? 0 : timeu + 1), timeu, gpst); + } + switch (opt->posf) { + case SOLF_LLH: + p += outpos(p, s, sol, opt); + break; + case SOLF_XYZ: + p += outecef(p, s, sol, opt); + break; + case SOLF_ENU: + p += outenu(p, s, sol, rb, opt); + break; + case SOLF_NMEA: + p += outnmea_rmc(p, sol); + p += outnmea_gga(p, sol); + p += outnmea_gst(p, sol); + break; + } + return (int)(p - buff); } /* output solution extended ---------------------------------------------------- -* output solution extended information -* args : uint8_t *buff IO output buffer -* sol_t *sol I solution -* ssat_t *ssat I satellite status -* solopt_t *opt I solution options -* return : number of output bytes -* notes : only support nmea -*-----------------------------------------------------------------------------*/ -extern int outsolexs(uint8_t *buff, const sol_t *sol, const ssat_t *ssat, - const solopt_t *opt) -{ - gtime_t ts={0}; - uint8_t *p=buff; - - trace(3,"outsolexs:\n"); - - /* suppress output if std is over opt->maxsolstd */ - if (opt->maxsolstd>0.0&&sol_std(sol)>opt->maxsolstd) { - return 0; - } - if (opt->posf==SOLF_NMEA) { - if (opt->nmeaintv[1]<0.0) return 0; - if (!screent(sol->time,ts,ts,opt->nmeaintv[1])) return 0; - p+=outnmea_gsa(p,sol,ssat); - p+=outnmea_gsv(p,sol,ssat); - } - return (int)(p-buff); + * output solution extended information + * args : uint8_t *buff IO output buffer + * sol_t *sol I solution + * ssat_t *ssat I satellite status + * solopt_t *opt I solution options + * return : number of output bytes + * notes : only support nmea + *-----------------------------------------------------------------------------*/ +extern int outsolexs(uint8_t *buff, const sol_t *sol, const ssat_t *ssat, const solopt_t *opt) { + gtime_t ts = {0}; + uint8_t *p = buff; + + trace(3, "outsolexs:\n"); + + /* suppress output if std is over opt->maxsolstd */ + if (opt->maxsolstd > 0.0 && sol_std(sol) > opt->maxsolstd) { + return 0; + } + if (opt->posf == SOLF_NMEA) { + if (opt->nmeaintv[1] < 0.0) return 0; + if (!screent(sol->time, ts, ts, opt->nmeaintv[1])) return 0; + p += outnmea_gsa(p, sol, ssat); + p += outnmea_gsv(p, sol, ssat); + } + return (int)(p - buff); } /* output processing option ---------------------------------------------------- -* output processing option to file -* args : FILE *fp I output file pointer -* prcopt_t *opt I processing options -* return : none -*-----------------------------------------------------------------------------*/ -extern void outprcopt(FILE *fp, const prcopt_t *opt) -{ - uint8_t buff[MAXSOLMSG+1]; - int n; - - trace(3,"outprcopt:\n"); - - if ((n=outprcopts(buff,opt))>0) { - fwrite(buff,n,1,fp); - } + * output processing option to file + * args : FILE *fp I output file pointer + * prcopt_t *opt I processing options + * return : none + *-----------------------------------------------------------------------------*/ +extern void outprcopt(FILE *fp, const prcopt_t *opt) { + uint8_t buff[MAXSOLMSG + 1]; + int n; + + trace(3, "outprcopt:\n"); + + if ((n = outprcopts(buff, opt)) > 0) { + fwrite(buff, n, 1, fp); + } } /* output solution header ------------------------------------------------------ -* output solution heade to file -* args : FILE *fp I output file pointer -* solopt_t *opt I solution options -* return : none -*-----------------------------------------------------------------------------*/ -extern void outsolhead(FILE *fp, const solopt_t *opt) -{ - uint8_t buff[MAXSOLMSG+1]; - int n; - - trace(3,"outsolhead:\n"); - - if ((n=outsolheads(buff,opt))>0) { - fwrite(buff,n,1,fp); - } + * output solution heade to file + * args : FILE *fp I output file pointer + * solopt_t *opt I solution options + * return : none + *-----------------------------------------------------------------------------*/ +extern void outsolhead(FILE *fp, const solopt_t *opt) { + uint8_t buff[MAXSOLMSG + 1]; + int n; + + trace(3, "outsolhead:\n"); + + if ((n = outsolheads(buff, opt)) > 0) { + fwrite(buff, n, 1, fp); + } } /* output solution body -------------------------------------------------------- -* output solution body to file -* args : FILE *fp I output file pointer -* sol_t *sol I solution -* double *rb I base station position {x,y,z} (ecef) (m) -* solopt_t *opt I solution options -* return : none -*-----------------------------------------------------------------------------*/ -extern void outsol(FILE *fp, const sol_t *sol, const double *rb, - const solopt_t *opt) -{ - uint8_t buff[MAXSOLMSG+1]; - int n; - - trace(4,"outsol :\n"); - - if ((n=outsols(buff,sol,rb,opt))>0) { - fwrite(buff,n,1,fp); - } + * output solution body to file + * args : FILE *fp I output file pointer + * sol_t *sol I solution + * double *rb I base station position {x,y,z} (ecef) (m) + * solopt_t *opt I solution options + * return : none + *-----------------------------------------------------------------------------*/ +extern void outsol(FILE *fp, const sol_t *sol, const double *rb, const solopt_t *opt) { + uint8_t buff[MAXSOLMSG + 1]; + int n; + + trace(4, "outsol :\n"); + + if ((n = outsols(buff, sol, rb, opt)) > 0) { + fwrite(buff, n, 1, fp); + } } /* output solution extended ---------------------------------------------------- -* output solution extended information to file -* args : FILE *fp I output file pointer -* sol_t *sol I solution -* ssat_t *ssat I satellite status -* solopt_t *opt I solution options -* return : output size (bytes) -* notes : only support nmea -*-----------------------------------------------------------------------------*/ -extern void outsolex(FILE *fp, const sol_t *sol, const ssat_t *ssat, - const solopt_t *opt) -{ - uint8_t buff[MAXSOLMSG+1]; - int n; - - trace(3,"outsolex:\n"); - - if ((n=outsolexs(buff,sol,ssat,opt))>0) { - fwrite(buff,n,1,fp); - } + * output solution extended information to file + * args : FILE *fp I output file pointer + * sol_t *sol I solution + * ssat_t *ssat I satellite status + * solopt_t *opt I solution options + * return : output size (bytes) + * notes : only support nmea + *-----------------------------------------------------------------------------*/ +extern void outsolex(FILE *fp, const sol_t *sol, const ssat_t *ssat, const solopt_t *opt) { + uint8_t buff[MAXSOLMSG + 1]; + int n; + + trace(3, "outsolex:\n"); + + if ((n = outsolexs(buff, sol, ssat, opt)) > 0) { + fwrite(buff, n, 1, fp); + } } diff --git a/src/stream.c b/src/stream.c index f0200da51..67bc06871 100644 --- a/src/stream.c +++ b/src/stream.c @@ -1,264 +1,265 @@ /*------------------------------------------------------------------------------ -* stream.c : stream input/output functions -* -* Copyright (C) 2008-2020 by T.TAKASU, All rights reserved. -* -* options : -DWIN32 use WIN32 API -* -DSVR_REUSEADDR reuse tcp server address -* -* references : -* [1] RTCM Recommendaed Standards for Networked Transport for RTCM via -* Internet Protocol (Ntrip), Version 1.0, Semptember 30, 2004 -* [2] H.Niksic and others, GNU Wget 1.12, The non-iteractive download -* utility, 4 September 2009 -* [3] RTCM Recommendaed Standards for Networked Transport for RTCM via -* Internet Protocol (Ntrip), Version 2.0, June 28, 2011 -* -* version : $Revision:$ $Date:$ -* history : 2009/01/16 1.0 new -* 2009/04/02 1.1 support nmea request in ntrip request -* support time-tag of file as stream -* 2009/09/04 1.2 ported to linux environment -* add fflush() to save file stream -* 2009/10/10 1.3 support multiple connection for tcp server -* add keyword replacement in file path -* add function strsendnmea(), strsendcmd() -* 2010/07/18 1.4 support ftp/http stream types -* add keywords replacement of %ha,%hb,%hc in path -* add api: strsetdir(),strsettimeout() -* 2010/08/31 1.5 reconnect after error of ntrip client -* fix bug on no file swap at week start (2.4.0_p6) -* 2011/05/29 1.6 add fast stream replay mode -* add time margin to swap file -* change api strsetopt() -* introduce non_block send for send socket -* add api: strsetproxy() -* 2011/12/21 1.7 fix bug decode tcppath (rtklib_2.4.1_p5) -* 2012/06/09 1.8 fix problem if user or password contains / -* (rtklib_2.4.1_p7) -* 2012/12/25 1.9 compile option SVR_REUSEADDR added -* 2013/03/10 1.10 fix problem with ntrip mountpoint containing "/" -* 2013/04/15 1.11 fix bug on swapping files if swapmargin=0 -* 2013/05/28 1.12 fix bug on playback of file with 64 bit size_t -* 2014/05/23 1.13 retry to connect after gethostbyname() error -* fix bug on malloc size in openftp() -* 2014/06/21 1.14 add general hex message rcv command by !HEX ... -* 2014/10/16 1.15 support stdin/stdout for input/output from/to file -* 2014/11/08 1.16 fix getconfig error (87) with bluetooth device -* 2015/01/12 1.15 add rcv command to change bitrate by !BRATE -* 2016/01/16 1.16 add constant CRTSCTS for non-CRTSCTS-defined env. -* fix serial status for non-windows systems -* 2016/06/09 1.17 fix bug on !BRATE rcv command always failed -* fix program on struct alignment in time tag header -* 2016/06/21 1.18 reverse time-tag handler of file to previous -* 2016/07/23 1.19 add output of received stream to tcp port for serial -* 2016/08/20 1.20 modify api strsendnmea() -* 2016/08/29 1.21 fix bug on starting serial thread for windows -* 2016/09/03 1.22 add ntrip caster functions -* add api strstatx(),strsetsrctbl() -* add api strsetsel(),strgetsel() -* 2016/09/06 1.23 fix bug on ntrip caster socket and request handling -* 2016/09/27 1.24 support udp server and client -* 2016/10/10 1.25 support ::P={4|8} option in path for STR_FILE -* 2018/11/05 1.26 fix bug on default playback speed (= 0) -* fix bug on file playback as slave mode -* fix bug on timeset() in gpst instead of utc -* update trace levels and buffer sizes -* 2019/05/10 1.27 fix bug on dropping message on tcp stream (#144) -* 2019/08/19 1.28 support 460800 and 921600 bps for serial -* 2020/11/30 1.29 delete API strsetsrctbl(), strsetsel(), strgetsel() -* fix bug on numerical error in computing output rate -* no support stream type STR_NTRIPC_S in API stropen() -* no support rcv. command LEXR in API strsendcmd() -* change stream type STR_NTRIPC_C to STR_NTRIPCAS -* accept HTTP/1.1 as protocol for NTRIP caster -* suppress warning for buffer overflow by sprintf() -* use integer types in stdint.h -*-----------------------------------------------------------------------------*/ + * stream.c : stream input/output functions + * + * Copyright (C) 2008-2020 by T.TAKASU, All rights reserved. + * + * options : -DWIN32 use WIN32 API + * -DSVR_REUSEADDR reuse tcp server address + * + * references : + * [1] RTCM Recommendaed Standards for Networked Transport for RTCM via + * Internet Protocol (Ntrip), Version 1.0, Semptember 30, 2004 + * [2] H.Niksic and others, GNU Wget 1.12, The non-iteractive download + * utility, 4 September 2009 + * [3] RTCM Recommendaed Standards for Networked Transport for RTCM via + * Internet Protocol (Ntrip), Version 2.0, June 28, 2011 + * + * version : $Revision:$ $Date:$ + * history : 2009/01/16 1.0 new + * 2009/04/02 1.1 support nmea request in ntrip request + * support time-tag of file as stream + * 2009/09/04 1.2 ported to linux environment + * add fflush() to save file stream + * 2009/10/10 1.3 support multiple connection for tcp server + * add keyword replacement in file path + * add function strsendnmea(), strsendcmd() + * 2010/07/18 1.4 support ftp/http stream types + * add keywords replacement of %ha,%hb,%hc in path + * add api: strsetdir(),strsettimeout() + * 2010/08/31 1.5 reconnect after error of ntrip client + * fix bug on no file swap at week start (2.4.0_p6) + * 2011/05/29 1.6 add fast stream replay mode + * add time margin to swap file + * change api strsetopt() + * introduce non_block send for send socket + * add api: strsetproxy() + * 2011/12/21 1.7 fix bug decode tcppath (rtklib_2.4.1_p5) + * 2012/06/09 1.8 fix problem if user or password contains / + * (rtklib_2.4.1_p7) + * 2012/12/25 1.9 compile option SVR_REUSEADDR added + * 2013/03/10 1.10 fix problem with ntrip mountpoint containing "/" + * 2013/04/15 1.11 fix bug on swapping files if swapmargin=0 + * 2013/05/28 1.12 fix bug on playback of file with 64 bit size_t + * 2014/05/23 1.13 retry to connect after gethostbyname() error + * fix bug on malloc size in openftp() + * 2014/06/21 1.14 add general hex message rcv command by !HEX ... + * 2014/10/16 1.15 support stdin/stdout for input/output from/to file + * 2014/11/08 1.16 fix getconfig error (87) with bluetooth device + * 2015/01/12 1.15 add rcv command to change bitrate by !BRATE + * 2016/01/16 1.16 add constant CRTSCTS for non-CRTSCTS-defined env. + * fix serial status for non-windows systems + * 2016/06/09 1.17 fix bug on !BRATE rcv command always failed + * fix program on struct alignment in time tag header + * 2016/06/21 1.18 reverse time-tag handler of file to previous + * 2016/07/23 1.19 add output of received stream to tcp port for serial + * 2016/08/20 1.20 modify api strsendnmea() + * 2016/08/29 1.21 fix bug on starting serial thread for windows + * 2016/09/03 1.22 add ntrip caster functions + * add api strstatx(),strsetsrctbl() + * add api strsetsel(),strgetsel() + * 2016/09/06 1.23 fix bug on ntrip caster socket and request handling + * 2016/09/27 1.24 support udp server and client + * 2016/10/10 1.25 support ::P={4|8} option in path for STR_FILE + * 2018/11/05 1.26 fix bug on default playback speed (= 0) + * fix bug on file playback as slave mode + * fix bug on timeset() in gpst instead of utc + * update trace levels and buffer sizes + * 2019/05/10 1.27 fix bug on dropping message on tcp stream (#144) + * 2019/08/19 1.28 support 460800 and 921600 bps for serial + * 2020/11/30 1.29 delete API strsetsrctbl(), strsetsel(), strgetsel() + * fix bug on numerical error in computing output rate + * no support stream type STR_NTRIPC_S in API stropen() + * no support rcv. command LEXR in API strsendcmd() + * change stream type STR_NTRIPC_C to STR_NTRIPCAS + * accept HTTP/1.1 as protocol for NTRIP caster + * suppress warning for buffer overflow by sprintf() + * use integer types in stdint.h + *-----------------------------------------------------------------------------*/ #define _POSIX_C_SOURCE 199506 #include + #include "rtklib.h" #ifndef WIN32 #include -#include #include #include +#include #define __USE_MISC #ifndef CRTSCTS -#define CRTSCTS 020000000000 +#define CRTSCTS 020000000000 #endif +#include #include -#include -#include +#include #include #include -#include -#include +#include +#include #endif /* constants -----------------------------------------------------------------*/ -#define TINTACT 200 /* period for stream active (ms) */ -#define SERIBUFFSIZE 4096 /* serial buffer size (bytes) */ -#define TIMETAGH_LEN 64 /* time tag file header length */ -#define MAXCLI 32 /* max client connection for tcp svr */ -#define MAXSTATMSG 32 /* max length of status message */ -#define DEFAULT_MEMBUF_SIZE 4096 /* default memory buffer size (bytes) */ - -#define NTRIP_AGENT "RTKLIB/" VER_RTKLIB "_" PATCH_LEVEL -#define NTRIP_CLI_PORT 2101 /* default ntrip-client connection port */ -#define NTRIP_SVR_PORT 80 /* default ntrip-server connection port */ -#define NTRIP_MAXRSP 32768 /* max size of ntrip response */ -#define NTRIP_MAXSTR 256 /* max length of mountpoint string */ -#define NTRIP_RSP_OK_CLI "ICY 200 OK\r\n" /* ntrip response: client */ -#define NTRIP_RSP_OK_SVR "OK\r\n" /* ntrip response: server */ -#define NTRIP_RSP_SRCTBL "SOURCETABLE 200 OK\r\n" /* ntrip response: source table */ -#define NTRIP_RSP_TBLEND "ENDSOURCETABLE" -#define NTRIP_RSP_HTTP "HTTP/" /* ntrip response: http */ -#define NTRIP_RSP_ERROR "ERROR" /* ntrip response: error */ -#define NTRIP_RSP_UNAUTH "HTTP/1.0 401 Unauthorized\r\n" -#define NTRIP_RSP_ERR_PWD "ERROR - Bad Password\r\n" -#define NTRIP_RSP_ERR_MNTP "ERROR - Bad Mountpoint\r\n" - -#define FTP_CMD "wget" /* ftp/http command */ -#define FTP_TIMEOUT 30 /* ftp/http timeout (s) */ - -#define MIN(x,y) ((x)<(y)?(x):(y)) +#define TINTACT 200 /* period for stream active (ms) */ +#define SERIBUFFSIZE 4096 /* serial buffer size (bytes) */ +#define TIMETAGH_LEN 64 /* time tag file header length */ +#define MAXCLI 32 /* max client connection for tcp svr */ +#define MAXSTATMSG 32 /* max length of status message */ +#define DEFAULT_MEMBUF_SIZE 4096 /* default memory buffer size (bytes) */ + +#define NTRIP_AGENT "RTKLIB/" VER_RTKLIB "_" PATCH_LEVEL +#define NTRIP_CLI_PORT 2101 /* default ntrip-client connection port */ +#define NTRIP_SVR_PORT 80 /* default ntrip-server connection port */ +#define NTRIP_MAXRSP 32768 /* max size of ntrip response */ +#define NTRIP_MAXSTR 256 /* max length of mountpoint string */ +#define NTRIP_RSP_OK_CLI "ICY 200 OK\r\n" /* ntrip response: client */ +#define NTRIP_RSP_OK_SVR "OK\r\n" /* ntrip response: server */ +#define NTRIP_RSP_SRCTBL "SOURCETABLE 200 OK\r\n" /* ntrip response: source table */ +#define NTRIP_RSP_TBLEND "ENDSOURCETABLE" +#define NTRIP_RSP_HTTP "HTTP/" /* ntrip response: http */ +#define NTRIP_RSP_ERROR "ERROR" /* ntrip response: error */ +#define NTRIP_RSP_UNAUTH "HTTP/1.0 401 Unauthorized\r\n" +#define NTRIP_RSP_ERR_PWD "ERROR - Bad Password\r\n" +#define NTRIP_RSP_ERR_MNTP "ERROR - Bad Mountpoint\r\n" + +#define FTP_CMD "wget" /* ftp/http command */ +#define FTP_TIMEOUT 30 /* ftp/http timeout (s) */ + +#define MIN(x, y) ((x) < (y) ? (x) : (y)) /* macros --------------------------------------------------------------------*/ #ifdef WIN32 -#define dev_t HANDLE -#define socket_t SOCKET +#define dev_t HANDLE +#define socket_t SOCKET typedef int socklen_t; #else -#define dev_t int -#define socket_t int -#define closesocket close +#define dev_t int +#define socket_t int +#define closesocket close #endif /* type definition -----------------------------------------------------------*/ -typedef struct { /* file control type */ - FILE *fp; /* file pointer */ - FILE *fp_tag; /* file pointer of tag file */ - FILE *fp_tmp; /* temporary file pointer for swap */ - FILE *fp_tag_tmp; /* temporary file pointer of tag file for swap */ - char path[MAXSTRPATH]; /* file path */ - char openpath[MAXSTRPATH]; /* open file path */ - int mode; /* file mode */ - int timetag; /* time tag flag (0:off,1:on) */ - int repmode; /* replay mode (0:master,1:slave) */ - int offset; /* time offset (ms) for slave */ - int size_fpos; /* file position size (bytes) */ - gtime_t time; /* start time */ - gtime_t wtime; /* write time */ - uint32_t tick; /* start tick */ - uint32_t tick_f; /* start tick in file */ - long fpos_n; /* next file position */ - uint32_t tick_n; /* next tick */ - double start; /* start offset (s) */ - double speed; /* replay speed (time factor) */ - double swapintv; /* swap interval (hr) (0: no swap) */ - rtklib_lock_t lock; /* lock flag */ +typedef struct { /* file control type */ + FILE *fp; /* file pointer */ + FILE *fp_tag; /* file pointer of tag file */ + FILE *fp_tmp; /* temporary file pointer for swap */ + FILE *fp_tag_tmp; /* temporary file pointer of tag file for swap */ + char path[MAXSTRPATH]; /* file path */ + char openpath[MAXSTRPATH]; /* open file path */ + int mode; /* file mode */ + int timetag; /* time tag flag (0:off,1:on) */ + int repmode; /* replay mode (0:master,1:slave) */ + int offset; /* time offset (ms) for slave */ + int size_fpos; /* file position size (bytes) */ + gtime_t time; /* start time */ + gtime_t wtime; /* write time */ + uint32_t tick; /* start tick */ + uint32_t tick_f; /* start tick in file */ + long fpos_n; /* next file position */ + uint32_t tick_n; /* next tick */ + double start; /* start offset (s) */ + double speed; /* replay speed (time factor) */ + double swapintv; /* swap interval (hr) (0: no swap) */ + rtklib_lock_t lock; /* lock flag */ } file_t; -typedef struct { /* tcp control type */ - int state; /* state (0:close,1:wait,2:connect) */ - char saddr[256]; /* address string */ - int port; /* port */ - struct sockaddr_in addr; /* address resolved */ - socket_t sock; /* socket descriptor */ - int tcon; /* reconnect time (ms) (-1:never,0:now) */ - uint32_t tact; /* data active tick */ - uint32_t tdis; /* disconnect tick */ +typedef struct { /* tcp control type */ + int state; /* state (0:close,1:wait,2:connect) */ + char saddr[256]; /* address string */ + int port; /* port */ + struct sockaddr_in addr; /* address resolved */ + socket_t sock; /* socket descriptor */ + int tcon; /* reconnect time (ms) (-1:never,0:now) */ + uint32_t tact; /* data active tick */ + uint32_t tdis; /* disconnect tick */ } tcp_t; typedef struct tcpsvr_tag { /* tcp server type */ - tcp_t svr; /* tcp server control */ - tcp_t cli[MAXCLI]; /* tcp client controls */ + tcp_t svr; /* tcp server control */ + tcp_t cli[MAXCLI]; /* tcp client controls */ } tcpsvr_t; -typedef struct { /* tcp cilent type */ - tcp_t svr; /* tcp server control */ - int toinact; /* inactive timeout (ms) (0:no timeout) */ - int tirecon; /* reconnect interval (ms) (0:no reconnect) */ +typedef struct { /* tcp cilent type */ + tcp_t svr; /* tcp server control */ + int toinact; /* inactive timeout (ms) (0:no timeout) */ + int tirecon; /* reconnect interval (ms) (0:no reconnect) */ } tcpcli_t; -typedef struct { /* serial control type */ - dev_t dev; /* serial device */ - int error; /* error state */ +typedef struct { /* serial control type */ + dev_t dev; /* serial device */ + int error; /* error state */ #ifdef WIN32 - int state,wp,rp; /* state,write/read pointer */ - int buffsize; /* write buffer size (bytes) */ - HANDLE thread; /* write thread */ - rtklib_lock_t lock; /* lock flag */ - uint8_t *buff; /* write buffer */ + int state, wp, rp; /* state,write/read pointer */ + int buffsize; /* write buffer size (bytes) */ + HANDLE thread; /* write thread */ + rtklib_lock_t lock; /* lock flag */ + uint8_t *buff; /* write buffer */ #endif - tcpsvr_t *tcpsvr; /* tcp server for received stream */ + tcpsvr_t *tcpsvr; /* tcp server for received stream */ } serial_t; -typedef struct { /* ntrip control type */ - int state; /* state (0:close,1:wait,2:connect) */ - int type; /* type (0:server,1:client) */ - int nb; /* response buffer size */ - char url[MAXSTRPATH]; /* url for proxy */ - char mntpnt[256]; /* mountpoint */ - char user[256]; /* user */ - char passwd[256]; /* password */ - char str[NTRIP_MAXSTR]; /* mountpoint string for server */ - uint8_t buff[NTRIP_MAXRSP]; /* response buffer */ - tcpcli_t *tcp; /* tcp client */ +typedef struct { /* ntrip control type */ + int state; /* state (0:close,1:wait,2:connect) */ + int type; /* type (0:server,1:client) */ + int nb; /* response buffer size */ + char url[MAXSTRPATH]; /* url for proxy */ + char mntpnt[256]; /* mountpoint */ + char user[256]; /* user */ + char passwd[256]; /* password */ + char str[NTRIP_MAXSTR]; /* mountpoint string for server */ + uint8_t buff[NTRIP_MAXRSP]; /* response buffer */ + tcpcli_t *tcp; /* tcp client */ } ntrip_t; -typedef struct { /* ntrip client/server connection type */ - int state; /* state (0:close,1:connect) */ - char mntpnt[256]; /* mountpoint */ - char str[NTRIP_MAXSTR]; /* mountpoint string for server */ - int nb; /* request buffer size */ - uint8_t buff[NTRIP_MAXRSP]; /* request buffer */ +typedef struct { /* ntrip client/server connection type */ + int state; /* state (0:close,1:connect) */ + char mntpnt[256]; /* mountpoint */ + char str[NTRIP_MAXSTR]; /* mountpoint string for server */ + int nb; /* request buffer size */ + uint8_t buff[NTRIP_MAXRSP]; /* request buffer */ } ntripc_con_t; -typedef struct { /* ntrip caster control type */ - int state; /* state (0:close,1:wait,2:connect) */ - int type; /* type (0:server,1:client) */ - char mntpnt[256]; /* mountpoint */ - char user[256]; /* user */ - char passwd[256]; /* password */ - char srctbl[NTRIP_MAXSTR]; /* source table */ - tcpsvr_t *tcp; /* tcp server */ - ntripc_con_t con[MAXCLI]; /* ntrip client/server connections */ +typedef struct { /* ntrip caster control type */ + int state; /* state (0:close,1:wait,2:connect) */ + int type; /* type (0:server,1:client) */ + char mntpnt[256]; /* mountpoint */ + char user[256]; /* user */ + char passwd[256]; /* password */ + char srctbl[NTRIP_MAXSTR]; /* source table */ + tcpsvr_t *tcp; /* tcp server */ + ntripc_con_t con[MAXCLI]; /* ntrip client/server connections */ } ntripc_t; -typedef struct { /* udp type */ - int state; /* state (0:close,1:open) */ - int type; /* type (0:server,1:client) */ - int port; /* port */ - char saddr[256]; /* address (server:filter,client:server) */ - struct sockaddr_in addr; /* address resolved */ - socket_t sock; /* socket descriptor */ +typedef struct { /* udp type */ + int state; /* state (0:close,1:open) */ + int type; /* type (0:server,1:client) */ + int port; /* port */ + char saddr[256]; /* address (server:filter,client:server) */ + struct sockaddr_in addr; /* address resolved */ + socket_t sock; /* socket descriptor */ } udp_t; -typedef struct { /* ftp download control type */ - int state; /* state (0:close,1:download,2:complete,3:error) */ - int proto; /* protocol (0:ftp,1:http) */ - int error; /* error code (0:no error,1-10:wget error, */ - /* 11:no temp dir,12:uncompact error) */ - char addr[1024]; /* download address */ - char file[1024]; /* download file path */ - char user[256]; /* user for ftp */ - char passwd[256]; /* password for ftp */ - char local[1024]; /* local file path */ - int topts[4]; /* time options {poff,tint,toff,tretry} (s) */ - gtime_t tnext; /* next retry time (gpst) */ - rtklib_thread_t thread; /* download thread */ +typedef struct { /* ftp download control type */ + int state; /* state (0:close,1:download,2:complete,3:error) */ + int proto; /* protocol (0:ftp,1:http) */ + int error; /* error code (0:no error,1-10:wget error, */ + /* 11:no temp dir,12:uncompact error) */ + char addr[1024]; /* download address */ + char file[1024]; /* download file path */ + char user[256]; /* user for ftp */ + char passwd[256]; /* password for ftp */ + char local[1024]; /* local file path */ + int topts[4]; /* time options {poff,tint,toff,tretry} (s) */ + gtime_t tnext; /* next retry time (gpst) */ + rtklib_thread_t thread; /* download thread */ } ftp_t; -typedef struct { /* memory buffer type */ - int state,wp,rp; /* state,write/read pointer */ - int bufsize; /* buffer size (bytes) */ - rtklib_lock_t lock; /* lock flag */ - uint8_t *buf; /* write buffer */ +typedef struct { /* memory buffer type */ + int state, wp, rp; /* state,write/read pointer */ + int bufsize; /* buffer size (bytes) */ + rtklib_lock_t lock; /* lock flag */ + uint8_t *buf; /* write buffer */ } membuf_t; /* proto types for static functions ------------------------------------------*/ @@ -269,2105 +270,2004 @@ static int writetcpsvr(tcpsvr_t *tcpsvr, uint8_t *buff, int n, char *msg); /* global options ------------------------------------------------------------*/ -static int toinact =10000; /* inactive timeout (ms) */ -static int ticonnect=10000; /* interval to re-connect (ms) */ -static int tirate =1000; /* averaging time for data rate (ms) */ -static int buffsize =32768; /* receive/send buffer size (bytes) */ -static char localdir[1024]=""; /* local directory for ftp/http */ -static char proxyaddr[256]=""; /* http/ntrip/ftp proxy address */ -static uint32_t tick_master=0; /* time tick master for replay */ -static int fswapmargin=30; /* file swap margin (s) */ +static int toinact = 10000; /* inactive timeout (ms) */ +static int ticonnect = 10000; /* interval to re-connect (ms) */ +static int tirate = 1000; /* averaging time for data rate (ms) */ +static int buffsize = 32768; /* receive/send buffer size (bytes) */ +static char localdir[1024] = ""; /* local directory for ftp/http */ +static char proxyaddr[256] = ""; /* http/ntrip/ftp proxy address */ +static uint32_t tick_master = 0; /* time tick master for replay */ +static int fswapmargin = 30; /* file swap margin (s) */ /* read/write serial buffer --------------------------------------------------*/ #ifdef WIN32 -static int readseribuff(serial_t *serial, uint8_t *buff, int nmax) -{ - int ns; - - tracet(5,"readseribuff: dev=%d\n",serial->dev); - - rtklib_lock(&serial->lock); - for (ns=0;serial->rp!=serial->wp&&nsbuff[serial->rp]; - if (++serial->rp>=serial->buffsize) serial->rp=0; - } - rtklib_unlock(&serial->lock); - tracet(5,"readseribuff: ns=%d rp=%d wp=%d\n",ns,serial->rp,serial->wp); - return ns; -} -static int writeseribuff(serial_t *serial, uint8_t *buff, int n) -{ - int ns,wp; - - tracet(5,"writeseribuff: dev=%d n=%d\n",serial->dev,n); - - rtklib_lock(&serial->lock); - for (ns=0;nsbuff[wp=serial->wp]=buff[ns]; - if (++wp>=serial->buffsize) wp=0; - if (wp!=serial->rp) serial->wp=wp; - else { - tracet(2,"serial buffer overflow: size=%d\n",serial->buffsize); - break; - } +static int readseribuff(serial_t *serial, uint8_t *buff, int nmax) { + int ns; + + tracet(5, "readseribuff: dev=%d\n", serial->dev); + + rtklib_lock(&serial->lock); + for (ns = 0; serial->rp != serial->wp && ns < nmax; ns++) { + buff[ns] = serial->buff[serial->rp]; + if (++serial->rp >= serial->buffsize) serial->rp = 0; + } + rtklib_unlock(&serial->lock); + tracet(5, "readseribuff: ns=%d rp=%d wp=%d\n", ns, serial->rp, serial->wp); + return ns; +} +static int writeseribuff(serial_t *serial, uint8_t *buff, int n) { + int ns, wp; + + tracet(5, "writeseribuff: dev=%d n=%d\n", serial->dev, n); + + rtklib_lock(&serial->lock); + for (ns = 0; ns < n; ns++) { + serial->buff[wp = serial->wp] = buff[ns]; + if (++wp >= serial->buffsize) wp = 0; + if (wp != serial->rp) + serial->wp = wp; + else { + tracet(2, "serial buffer overflow: size=%d\n", serial->buffsize); + break; } - rtklib_unlock(&serial->lock); - tracet(5,"writeseribuff: ns=%d rp=%d wp=%d\n",ns,serial->rp,serial->wp); - return ns; + } + rtklib_unlock(&serial->lock); + tracet(5, "writeseribuff: ns=%d rp=%d wp=%d\n", ns, serial->rp, serial->wp); + return ns; } #endif /* WIN32 */ /* write serial thread -------------------------------------------------------*/ #ifdef WIN32 -static DWORD WINAPI serialthread(void *arg) -{ - serial_t *serial=(serial_t *)arg; - uint8_t buff[128]; - uint32_t tick; - DWORD ns; - int n; - - tracet(3,"serialthread:\n"); - - for (;;) { - tick=tickget(); - while ((n=readseribuff(serial,buff,sizeof(buff)))>0) { - if (!WriteFile(serial->dev,buff,n,&ns,NULL)) serial->error=1; - } - if (!serial->state) break; - sleepms(10-(int)(tickget()-tick)); /* cycle=10ms */ +static DWORD WINAPI serialthread(void *arg) { + serial_t *serial = (serial_t *)arg; + uint8_t buff[128]; + uint32_t tick; + DWORD ns; + int n; + + tracet(3, "serialthread:\n"); + + for (;;) { + tick = tickget(); + while ((n = readseribuff(serial, buff, sizeof(buff))) > 0) { + if (!WriteFile(serial->dev, buff, n, &ns, NULL)) serial->error = 1; } - free(serial->buff); - return 0; + if (!serial->state) break; + sleepms(10 - (int)(tickget() - tick)); /* cycle=10ms */ + } + free(serial->buff); + return 0; } #endif /* WIN32 */ /* open serial ---------------------------------------------------------------*/ -static serial_t *openserial(const char *path, int mode, char *msg) -{ - serial_t *serial; - int i,brate=115200,bsize=8,stopb=1,tcp_port=0; - char *p,parity='N',dev[128],port[128],fctr[64]="",path_tcp[32],msg_tcp[128]; +static serial_t *openserial(const char *path, int mode, char *msg) { + serial_t *serial; + int i, brate = 115200, bsize = 8, stopb = 1, tcp_port = 0; + char *p, parity = 'N', dev[128], port[128], fctr[64] = "", path_tcp[32], msg_tcp[128]; #ifdef WIN32 - const int br[]={ - 300,600,1200,2400,4800,9600,19200,38400,57600,115200,230400,460800, - 921600 - }; - DWORD error,rw=0,siz=sizeof(COMMCONFIG); - COMMCONFIG cc={0}; - COMMTIMEOUTS co={MAXDWORD,0,0,0,0}; /* non-block-read */ - char dcb[64]=""; + const int br[] = {300, 600, 1200, 2400, 4800, 9600, 19200, + 38400, 57600, 115200, 230400, 460800, 921600}; + DWORD error, rw = 0, siz = sizeof(COMMCONFIG); + COMMCONFIG cc = {0}; + COMMTIMEOUTS co = {MAXDWORD, 0, 0, 0, 0}; /* non-block-read */ + char dcb[64] = ""; #else #ifdef __APPLE__ - /* MacOS doesn't support higher baudrates (>230400B) */ - const int br[]={ - 300,600,1200,2400,4800,9600,19200,38400,57600,115200,230400 - }; - const speed_t bs[]={ - B300,B600,B1200,B2400,B4800,B9600,B19200,B38400,B57600,B115200,B230400 - }; -#else /* regular Linux with higher baudrates */ - const int br[]={ - 300,600,1200,2400,4800,9600,19200,38400,57600,115200,230400,460800, - 921600 - }; - const speed_t bs[]={ - B300,B600,B1200,B2400,B4800,B9600,B19200,B38400,B57600,B115200,B230400, - B460800,B921600 - }; + /* MacOS doesn't support higher baudrates (>230400B) */ + const int br[] = {300, 600, 1200, 2400, 4800, 9600, 19200, 38400, 57600, 115200, 230400}; + const speed_t bs[] = {B300, B600, B1200, B2400, B4800, B9600, + B19200, B38400, B57600, B115200, B230400}; +#else /* regular Linux with higher baudrates */ + const int br[] = {300, 600, 1200, 2400, 4800, 9600, 19200, + 38400, 57600, 115200, 230400, 460800, 921600}; + const speed_t bs[] = {B300, B600, B1200, B2400, B4800, B9600, B19200, + B38400, B57600, B115200, B230400, B460800, B921600}; #endif /* ifdef __APPLE__ */ - struct termios ios={0}; - int rw=0; + struct termios ios = {0}; + int rw = 0; #endif - tracet(3,"openserial: path=%s mode=%d\n",path,mode); - - if (!(serial=(serial_t *)calloc(1,sizeof(serial_t)))) return NULL; - - if ((p=strchr(path,':'))) { - strncpy(port,path,p-path); port[p-path]='\0'; - sscanf(p,":%d:%d:%c:%d:%63s",&brate,&bsize,&parity,&stopb,fctr); - } - else strcpy(port,path); - - if ((p=strchr(path,'#'))) { - sscanf(p,"#%d",&tcp_port); - } - int nbr = sizeof(br) / sizeof(int); - for (i=0;i=nbr) { - sprintf(msg,"bitrate error (%d)",brate); - tracet(1,"openserial: %s path=%s\n",msg,path); - free(serial); - return NULL; - } - parity=(char)toupper((int)parity); - + tracet(3, "openserial: path=%s mode=%d\n", path, mode); + + if (!(serial = (serial_t *)calloc(1, sizeof(serial_t)))) return NULL; + + if ((p = strchr(path, ':'))) { + strncpy(port, path, p - path); + port[p - path] = '\0'; + sscanf(p, ":%d:%d:%c:%d:%63s", &brate, &bsize, &parity, &stopb, fctr); + } else + strcpy(port, path); + + if ((p = strchr(path, '#'))) { + sscanf(p, "#%d", &tcp_port); + } + int nbr = sizeof(br) / sizeof(int); + for (i = 0; i < nbr; i++) + if (br[i] == brate) break; + if (i >= nbr) { + sprintf(msg, "bitrate error (%d)", brate); + tracet(1, "openserial: %s path=%s\n", msg, path); + free(serial); + return NULL; + } + parity = (char)toupper((int)parity); + #ifdef WIN32 - sprintf(dev,"\\\\.\\%s",port); - if (mode&STR_MODE_R) rw|=GENERIC_READ; - if (mode&STR_MODE_W) rw|=GENERIC_WRITE; - - serial->dev=CreateFile(dev,rw,0,0,OPEN_EXISTING,0,NULL); - if (serial->dev==INVALID_HANDLE_VALUE) { - sprintf(msg,"%s open error (%d)",port,(int)GetLastError()); - tracet(1,"openserial: %s path=%s\n",msg,path); - free(serial); - return NULL; - } - if (!GetCommConfig(serial->dev,&cc,&siz)) { - sprintf(msg,"%s getconfig error (%d)",port,(int)GetLastError()); - tracet(1,"openserial: %s\n",msg); - CloseHandle(serial->dev); - free(serial); - return NULL; - } - sprintf(dcb,"baud=%d parity=%c data=%d stop=%d",brate,parity,bsize,stopb); - if (!BuildCommDCB(dcb,&cc.dcb)) { - sprintf(msg,"%s buiddcb error (%d)",port,(int)GetLastError()); - tracet(1,"openserial: %s\n",msg); - CloseHandle(serial->dev); - free(serial); - return NULL; - } - if (!strcmp(fctr,"rts")) { - cc.dcb.fRtsControl=RTS_CONTROL_HANDSHAKE; - } - SetCommConfig(serial->dev,&cc,siz); /* ignore error to support novatel */ - SetCommTimeouts(serial->dev,&co); - ClearCommError(serial->dev,&error,NULL); - PurgeComm(serial->dev,PURGE_TXABORT|PURGE_RXABORT|PURGE_TXCLEAR|PURGE_RXCLEAR); - - /* create write thread */ - rtklib_initlock(&serial->lock); - serial->state=serial->wp=serial->rp=serial->error=0; - serial->buffsize=buffsize; - if (!(serial->buff=(uint8_t *)malloc(buffsize))) { - CloseHandle(serial->dev); - free(serial); - return NULL; - } - serial->state=1; - if (!(serial->thread=CreateThread(NULL,0,serialthread,serial,0,NULL))) { - sprintf(msg,"%s serial thread error (%d)",port,(int)GetLastError()); - tracet(1,"openserial: %s\n",msg); - CloseHandle(serial->dev); - serial->state=0; - free(serial); - return NULL; - } - sprintf(msg,"%s",port); + sprintf(dev, "\\\\.\\%s", port); + if (mode & STR_MODE_R) rw |= GENERIC_READ; + if (mode & STR_MODE_W) rw |= GENERIC_WRITE; + + serial->dev = CreateFile(dev, rw, 0, 0, OPEN_EXISTING, 0, NULL); + if (serial->dev == INVALID_HANDLE_VALUE) { + sprintf(msg, "%s open error (%d)", port, (int)GetLastError()); + tracet(1, "openserial: %s path=%s\n", msg, path); + free(serial); + return NULL; + } + if (!GetCommConfig(serial->dev, &cc, &siz)) { + sprintf(msg, "%s getconfig error (%d)", port, (int)GetLastError()); + tracet(1, "openserial: %s\n", msg); + CloseHandle(serial->dev); + free(serial); + return NULL; + } + sprintf(dcb, "baud=%d parity=%c data=%d stop=%d", brate, parity, bsize, stopb); + if (!BuildCommDCB(dcb, &cc.dcb)) { + sprintf(msg, "%s buiddcb error (%d)", port, (int)GetLastError()); + tracet(1, "openserial: %s\n", msg); + CloseHandle(serial->dev); + free(serial); + return NULL; + } + if (!strcmp(fctr, "rts")) { + cc.dcb.fRtsControl = RTS_CONTROL_HANDSHAKE; + } + SetCommConfig(serial->dev, &cc, siz); /* ignore error to support novatel */ + SetCommTimeouts(serial->dev, &co); + ClearCommError(serial->dev, &error, NULL); + PurgeComm(serial->dev, PURGE_TXABORT | PURGE_RXABORT | PURGE_TXCLEAR | PURGE_RXCLEAR); + + /* create write thread */ + rtklib_initlock(&serial->lock); + serial->state = serial->wp = serial->rp = serial->error = 0; + serial->buffsize = buffsize; + if (!(serial->buff = (uint8_t *)malloc(buffsize))) { + CloseHandle(serial->dev); + free(serial); + return NULL; + } + serial->state = 1; + if (!(serial->thread = CreateThread(NULL, 0, serialthread, serial, 0, NULL))) { + sprintf(msg, "%s serial thread error (%d)", port, (int)GetLastError()); + tracet(1, "openserial: %s\n", msg); + CloseHandle(serial->dev); + serial->state = 0; + free(serial); + return NULL; + } + sprintf(msg, "%s", port); #else - sprintf(dev,"/dev/%.*s",(int)sizeof(port)-6,port); - - if ((mode&STR_MODE_R)&&(mode&STR_MODE_W)) rw=O_RDWR; - else if (mode&STR_MODE_R) rw=O_RDONLY; - else if (mode&STR_MODE_W) rw=O_WRONLY; - - if ((serial->dev=open(dev,rw|O_NOCTTY|O_NONBLOCK))<0) { - sprintf(msg,"%s open error (%d)",dev,errno); - tracet(1,"openserial: %s dev=%s\n",msg,dev); - free(serial); - return NULL; - } - tcgetattr(serial->dev,&ios); - ios.c_iflag=0; - ios.c_oflag=0; - ios.c_lflag=0; /* non-canonical */ - ios.c_cc[VMIN ]=0; /* non-block-mode */ - ios.c_cc[VTIME]=0; - cfsetospeed(&ios,bs[i]); - cfsetispeed(&ios,bs[i]); - ios.c_cflag|=bsize==7?CS7:CS8; - ios.c_cflag|=parity=='O'?(PARENB|PARODD):(parity=='E'?PARENB:0); - ios.c_cflag|=stopb==2?CSTOPB:0; - ios.c_cflag|=!strcmp(fctr,"rts")?CRTSCTS:0; - tcsetattr(serial->dev,TCSANOW,&ios); - tcflush(serial->dev,TCIOFLUSH); - sprintf(msg,"%s",dev); + sprintf(dev, "/dev/%.*s", (int)sizeof(port) - 6, port); + + if ((mode & STR_MODE_R) && (mode & STR_MODE_W)) + rw = O_RDWR; + else if (mode & STR_MODE_R) + rw = O_RDONLY; + else if (mode & STR_MODE_W) + rw = O_WRONLY; + + if ((serial->dev = open(dev, rw | O_NOCTTY | O_NONBLOCK)) < 0) { + sprintf(msg, "%s open error (%d)", dev, errno); + tracet(1, "openserial: %s dev=%s\n", msg, dev); + free(serial); + return NULL; + } + tcgetattr(serial->dev, &ios); + ios.c_iflag = 0; + ios.c_oflag = 0; + ios.c_lflag = 0; /* non-canonical */ + ios.c_cc[VMIN] = 0; /* non-block-mode */ + ios.c_cc[VTIME] = 0; + cfsetospeed(&ios, bs[i]); + cfsetispeed(&ios, bs[i]); + ios.c_cflag |= bsize == 7 ? CS7 : CS8; + ios.c_cflag |= parity == 'O' ? (PARENB | PARODD) : (parity == 'E' ? PARENB : 0); + ios.c_cflag |= stopb == 2 ? CSTOPB : 0; + ios.c_cflag |= !strcmp(fctr, "rts") ? CRTSCTS : 0; + tcsetattr(serial->dev, TCSANOW, &ios); + tcflush(serial->dev, TCIOFLUSH); + sprintf(msg, "%s", dev); #endif - serial->tcpsvr=NULL; - - /* open tcp sever to output received stream */ - if (tcp_port>0) { - sprintf(path_tcp,":%d",tcp_port); - serial->tcpsvr=opentcpsvr(path_tcp,msg_tcp); - } - tracet(3,"openserial: dev=%d\n",serial->dev); - return serial; + serial->tcpsvr = NULL; + + /* open tcp sever to output received stream */ + if (tcp_port > 0) { + sprintf(path_tcp, ":%d", tcp_port); + serial->tcpsvr = opentcpsvr(path_tcp, msg_tcp); + } + tracet(3, "openserial: dev=%d\n", serial->dev); + return serial; } /* close serial --------------------------------------------------------------*/ -static void closeserial(serial_t *serial) -{ - tracet(3,"closeserial: dev=%d\n",serial->dev); - - if (!serial) return; +static void closeserial(serial_t *serial) { + tracet(3, "closeserial: dev=%d\n", serial->dev); + + if (!serial) return; #ifdef WIN32 - serial->state=0; - WaitForSingleObject(serial->thread,10000); - CloseHandle(serial->dev); - CloseHandle(serial->thread); + serial->state = 0; + WaitForSingleObject(serial->thread, 10000); + CloseHandle(serial->dev); + CloseHandle(serial->thread); #else - close(serial->dev); + close(serial->dev); #endif - if (serial->tcpsvr) { - closetcpsvr(serial->tcpsvr); - } - free(serial); + if (serial->tcpsvr) { + closetcpsvr(serial->tcpsvr); + } + free(serial); } /* read serial ---------------------------------------------------------------*/ -static int readserial(serial_t *serial, uint8_t *buff, int n, char *msg) -{ - (void)msg; - char msg_tcp[128]; +static int readserial(serial_t *serial, uint8_t *buff, int n, char *msg) { + (void)msg; + char msg_tcp[128]; #ifdef WIN32 - DWORD nr; + DWORD nr; #else - int nr; + int nr; #endif - tracet(4,"readserial: dev=%d n=%d\n",serial->dev,n); - if (!serial) return 0; + tracet(4, "readserial: dev=%d n=%d\n", serial->dev, n); + if (!serial) return 0; #ifdef WIN32 - if (!ReadFile(serial->dev,buff,n,&nr,NULL)) return 0; + if (!ReadFile(serial->dev, buff, n, &nr, NULL)) return 0; #else - if ((nr=read(serial->dev,buff,n))<0) return 0; + if ((nr = read(serial->dev, buff, n)) < 0) return 0; #endif - tracet(5,"readserial: exit dev=%d nr=%d\n",serial->dev,nr); - - /* write received stream to tcp server port */ - if (serial->tcpsvr&&nr>0) { - /* TODO handle no-blocking write ? */ - writetcpsvr(serial->tcpsvr,buff,(int)nr,msg_tcp); - } - return nr; + tracet(5, "readserial: exit dev=%d nr=%d\n", serial->dev, nr); + + /* write received stream to tcp server port */ + if (serial->tcpsvr && nr > 0) { + /* TODO handle no-blocking write ? */ + writetcpsvr(serial->tcpsvr, buff, (int)nr, msg_tcp); + } + return nr; } /* write serial --------------------------------------------------------------*/ -static int writeserial(serial_t *serial, uint8_t *buff, int n, char *msg) -{ - (void)msg; - int ns=0; - - tracet(3,"writeserial: dev=%d n=%d\n",serial->dev,n); - - if (!serial) return 0; +static int writeserial(serial_t *serial, uint8_t *buff, int n, char *msg) { + (void)msg; + int ns = 0; + + tracet(3, "writeserial: dev=%d n=%d\n", serial->dev, n); + + if (!serial) return 0; #ifdef WIN32 - if ((ns=writeseribuff(serial,buff,n))error=1; + if ((ns = writeseribuff(serial, buff, n)) < n) serial->error = 1; #else - ns=write(serial->dev,buff,n); - if (ns<0) { - if (errno==EAGAIN) { - /* TODO ?? */ - } - ns = 0; - serial->error=1; - } + ns = write(serial->dev, buff, n); + if (ns < 0) { + if (errno == EAGAIN) { + /* TODO ?? */ + } + ns = 0; + serial->error = 1; + } #endif - tracet(5,"writeserial: exit dev=%d ns=%d\n",serial->dev,ns); - return ns; + tracet(5, "writeserial: exit dev=%d ns=%d\n", serial->dev, ns); + return ns; } /* get state serial ----------------------------------------------------------*/ -static int stateserial(serial_t *serial) -{ - return !serial?0:(serial->error?-1:2); -} +static int stateserial(serial_t *serial) { return !serial ? 0 : (serial->error ? -1 : 2); } /* get extended state serial -------------------------------------------------*/ -static int statexserial(serial_t *serial, char *msg) -{ - char *p=msg; - int state=!serial?0:(serial->error?-1:2); - - p+=sprintf(p,"serial:\n"); - p+=sprintf(p," state = %d\n",state); - if (!state) return 0; - p+=sprintf(p," dev = %d\n",(int)serial->dev); - p+=sprintf(p," error = %d\n",serial->error); +static int statexserial(serial_t *serial, char *msg) { + char *p = msg; + int state = !serial ? 0 : (serial->error ? -1 : 2); + + p += sprintf(p, "serial:\n"); + p += sprintf(p, " state = %d\n", state); + if (!state) return 0; + p += sprintf(p, " dev = %d\n", (int)serial->dev); + p += sprintf(p, " error = %d\n", serial->error); #ifdef WIN32 - p+=sprintf(p," buffsize= %d\n",serial->buffsize); - p+=sprintf(p," wp = %d\n",serial->wp); - p+=sprintf(p," rp = %d\n",serial->rp); + p += sprintf(p, " buffsize= %d\n", serial->buffsize); + p += sprintf(p, " wp = %d\n", serial->wp); + p += sprintf(p, " rp = %d\n", serial->rp); #endif - return state; + return state; } /* open file -----------------------------------------------------------------*/ -static int openfile_(file_t *file, gtime_t time, char *msg) -{ - FILE *fp; - double time_sec; - uint32_t time_time; - char *rw,tagpath[MAXSTRPATH+4]=""; - char tagh[TIMETAGH_LEN+1]=""; - - char tstr[40]; - tracet(3,"openfile_: path=%s time=%s\n",file->path,time2str(time,tstr,0)); - - file->time=utc2gpst(timeget()); - file->tick=file->tick_f=tickget(); - file->fpos_n=0; - file->tick_n=0; - - /* use stdin or stdout if file path is null */ - if (!*file->path) { - file->fp=file->mode&STR_MODE_R?stdin:stdout; - return 1; - } - /* replace keywords */ - reppath(file->path,file->openpath,time,"",""); - - /* create directory */ - if ((file->mode&STR_MODE_W)&&!(file->mode&STR_MODE_R)) { - createdir(file->openpath); - } - if (file->mode&STR_MODE_R) rw="rb"; else rw="wb"; - - if (!(file->fp=fopen(file->openpath,rw))) { - sprintf(msg,"file open error: %s",file->openpath); - tracet(1,"openfile: %s\n",msg); - return 0; - } - tracet(4,"openfile_: open file %s (%s)\n",file->openpath,rw); - - sprintf(tagpath,"%s.tag",file->openpath); - - if (file->timetag) { /* output/sync time-tag */ - - if (!(file->fp_tag=fopen(tagpath,rw))) { - sprintf(msg,"tag open error: %s",tagpath); - tracet(1,"openfile: %s\n",msg); - fclose(file->fp); - return 0; - } - tracet(4,"openfile_: open tag file %s (%s)\n",tagpath,rw); - - if (file->mode&STR_MODE_R) { - if (fread(&tagh,TIMETAGH_LEN,1,file->fp_tag)==1&& - fread(&time_time,sizeof(time_time),1,file->fp_tag)==1&& - fread(&time_sec ,sizeof(time_sec ),1,file->fp_tag)==1) { - memcpy(&file->tick_f,tagh+TIMETAGH_LEN-4,sizeof(file->tick_f)); - file->time.time=(time_t)time_time; - file->time.sec =time_sec; - file->wtime=file->time; - } - else { - file->tick_f=0; - } - /* adust time to read playback file */ - timeset(gpst2utc(file->time)); - } - else { - sprintf(tagh,"TIMETAG RTKLIB %s",VER_RTKLIB); - memcpy(tagh+TIMETAGH_LEN-4,&file->tick_f,sizeof(file->tick_f)); - time_time=(uint32_t)file->time.time; - time_sec=file->time.sec; - fwrite(&tagh,1,TIMETAGH_LEN,file->fp_tag); - fwrite(&time_time,1,sizeof(time_time),file->fp_tag); - fwrite(&time_sec ,1,sizeof(time_sec ),file->fp_tag); - /* time tag file structure */ - /* HEADER(60)+TICK(4)+TIME(4+8)+ */ - /* TICK0(4)+FPOS0(4/8)+ */ - /* TICK1(4)+FPOS1(4/8)+... */ - } - } - else if (file->mode&STR_MODE_W) { /* remove time-tag */ - if ((fp=fopen(tagpath,"rb"))) { - fclose(fp); - remove(tagpath); - } - } +static int openfile_(file_t *file, gtime_t time, char *msg) { + FILE *fp; + double time_sec; + uint32_t time_time; + char *rw, tagpath[MAXSTRPATH + 4] = ""; + char tagh[TIMETAGH_LEN + 1] = ""; + + char tstr[40]; + tracet(3, "openfile_: path=%s time=%s\n", file->path, time2str(time, tstr, 0)); + + file->time = utc2gpst(timeget()); + file->tick = file->tick_f = tickget(); + file->fpos_n = 0; + file->tick_n = 0; + + /* use stdin or stdout if file path is null */ + if (!*file->path) { + file->fp = file->mode & STR_MODE_R ? stdin : stdout; return 1; + } + /* replace keywords */ + reppath(file->path, file->openpath, time, "", ""); + + /* create directory */ + if ((file->mode & STR_MODE_W) && !(file->mode & STR_MODE_R)) { + createdir(file->openpath); + } + if (file->mode & STR_MODE_R) + rw = "rb"; + else + rw = "wb"; + + if (!(file->fp = fopen(file->openpath, rw))) { + sprintf(msg, "file open error: %s", file->openpath); + tracet(1, "openfile: %s\n", msg); + return 0; + } + tracet(4, "openfile_: open file %s (%s)\n", file->openpath, rw); + + sprintf(tagpath, "%s.tag", file->openpath); + + if (file->timetag) { /* output/sync time-tag */ + + if (!(file->fp_tag = fopen(tagpath, rw))) { + sprintf(msg, "tag open error: %s", tagpath); + tracet(1, "openfile: %s\n", msg); + fclose(file->fp); + return 0; + } + tracet(4, "openfile_: open tag file %s (%s)\n", tagpath, rw); + + if (file->mode & STR_MODE_R) { + if (fread(&tagh, TIMETAGH_LEN, 1, file->fp_tag) == 1 && + fread(&time_time, sizeof(time_time), 1, file->fp_tag) == 1 && + fread(&time_sec, sizeof(time_sec), 1, file->fp_tag) == 1) { + memcpy(&file->tick_f, tagh + TIMETAGH_LEN - 4, sizeof(file->tick_f)); + file->time.time = (time_t)time_time; + file->time.sec = time_sec; + file->wtime = file->time; + } else { + file->tick_f = 0; + } + /* adust time to read playback file */ + timeset(gpst2utc(file->time)); + } else { + sprintf(tagh, "TIMETAG RTKLIB %s", VER_RTKLIB); + memcpy(tagh + TIMETAGH_LEN - 4, &file->tick_f, sizeof(file->tick_f)); + time_time = (uint32_t)file->time.time; + time_sec = file->time.sec; + fwrite(&tagh, 1, TIMETAGH_LEN, file->fp_tag); + fwrite(&time_time, 1, sizeof(time_time), file->fp_tag); + fwrite(&time_sec, 1, sizeof(time_sec), file->fp_tag); + /* time tag file structure */ + /* HEADER(60)+TICK(4)+TIME(4+8)+ */ + /* TICK0(4)+FPOS0(4/8)+ */ + /* TICK1(4)+FPOS1(4/8)+... */ + } + } else if (file->mode & STR_MODE_W) { /* remove time-tag */ + if ((fp = fopen(tagpath, "rb"))) { + fclose(fp); + remove(tagpath); + } + } + return 1; } /* close file ----------------------------------------------------------------*/ -static void closefile_(file_t *file) -{ - tracet(3,"closefile_: path=%s\n",file->path); - - if (file->fp) fclose(file->fp); - if (file->fp_tag) fclose(file->fp_tag); - if (file->fp_tmp) fclose(file->fp_tmp); - if (file->fp_tag_tmp) fclose(file->fp_tag_tmp); - file->fp=file->fp_tag=file->fp_tmp=file->fp_tag_tmp=NULL; - - /* reset time offset */ - timereset(); +static void closefile_(file_t *file) { + tracet(3, "closefile_: path=%s\n", file->path); + + if (file->fp) fclose(file->fp); + if (file->fp_tag) fclose(file->fp_tag); + if (file->fp_tmp) fclose(file->fp_tmp); + if (file->fp_tag_tmp) fclose(file->fp_tag_tmp); + file->fp = file->fp_tag = file->fp_tmp = file->fp_tag_tmp = NULL; + + /* reset time offset */ + timereset(); } /* open file (path=filepath[::T[::+][::x]][::S=swapintv][::P={4|8}] */ -static file_t *openfile(const char *path, int mode, char *msg) -{ - file_t *file; - gtime_t time,time0={0}; - double speed=1.0,start=0.0,swapintv=0.0; - char *p; - int timetag=0,size_fpos=4; /* default 4B */ - - tracet(3,"openfile: path=%s mode=%d\n",path,mode); - - if (!(mode&(STR_MODE_R|STR_MODE_W))) return NULL; - - /* file options */ - for (p=(char *)path;(p=strstr(p,"::"));p+=2) { /* file options */ - if (*(p+2)=='T') timetag=1; - else if (*(p+2)=='+') sscanf(p+2,"+%lf",&start); - else if (*(p+2)=='x') sscanf(p+2,"x%lf",&speed); - else if (*(p+2)=='S') sscanf(p+2,"S=%lf",&swapintv); - else if (*(p+2)=='P') sscanf(p+2,"P=%d",&size_fpos); - } - if (start<=0.0) start=0.0; - if (swapintv<=0.0) swapintv=0.0; - - if (!(file=(file_t *)malloc(sizeof(file_t)))) return NULL; - - file->fp=file->fp_tag=file->fp_tmp=file->fp_tag_tmp=NULL; - strcpy(file->path,path); - if ((p=strstr(file->path,"::"))) *p='\0'; - file->openpath[0]='\0'; - file->mode=mode; - file->timetag=timetag; - file->repmode=0; - file->offset=0; - file->size_fpos=size_fpos; - file->time=file->wtime=time0; - file->tick=file->tick_f=file->tick_n=file->fpos_n=0; - file->start=start; - file->speed=speed; - file->swapintv=swapintv; - rtklib_initlock(&file->lock); - - time=utc2gpst(timeget()); - - /* open new file */ - if (!openfile_(file,time,msg)) { - free(file); - return NULL; - } - return file; +static file_t *openfile(const char *path, int mode, char *msg) { + file_t *file; + gtime_t time, time0 = {0}; + double speed = 1.0, start = 0.0, swapintv = 0.0; + char *p; + int timetag = 0, size_fpos = 4; /* default 4B */ + + tracet(3, "openfile: path=%s mode=%d\n", path, mode); + + if (!(mode & (STR_MODE_R | STR_MODE_W))) return NULL; + + /* file options */ + for (p = (char *)path; (p = strstr(p, "::")); p += 2) { /* file options */ + if (*(p + 2) == 'T') + timetag = 1; + else if (*(p + 2) == '+') + sscanf(p + 2, "+%lf", &start); + else if (*(p + 2) == 'x') + sscanf(p + 2, "x%lf", &speed); + else if (*(p + 2) == 'S') + sscanf(p + 2, "S=%lf", &swapintv); + else if (*(p + 2) == 'P') + sscanf(p + 2, "P=%d", &size_fpos); + } + if (start <= 0.0) start = 0.0; + if (swapintv <= 0.0) swapintv = 0.0; + + if (!(file = (file_t *)malloc(sizeof(file_t)))) return NULL; + + file->fp = file->fp_tag = file->fp_tmp = file->fp_tag_tmp = NULL; + strcpy(file->path, path); + if ((p = strstr(file->path, "::"))) *p = '\0'; + file->openpath[0] = '\0'; + file->mode = mode; + file->timetag = timetag; + file->repmode = 0; + file->offset = 0; + file->size_fpos = size_fpos; + file->time = file->wtime = time0; + file->tick = file->tick_f = file->tick_n = file->fpos_n = 0; + file->start = start; + file->speed = speed; + file->swapintv = swapintv; + rtklib_initlock(&file->lock); + + time = utc2gpst(timeget()); + + /* open new file */ + if (!openfile_(file, time, msg)) { + free(file); + return NULL; + } + return file; } /* close file ----------------------------------------------------------------*/ -static void closefile(file_t *file) -{ - tracet(3,"closefile: fp=%d\n",file->fp); - - if (!file) return; - closefile_(file); - free(file); +static void closefile(file_t *file) { + tracet(3, "closefile: fp=%d\n", file->fp); + + if (!file) return; + closefile_(file); + free(file); } /* open new swap file --------------------------------------------------------*/ -static void swapfile(file_t *file, gtime_t time, char *msg) -{ - char openpath[MAXSTRPATH]; - - char tstr[40]; - tracet(3,"swapfile: fp=%d time=%s\n",file->fp,time2str(time,tstr,0)); - - /* return if old swap file open */ - if (file->fp_tmp||file->fp_tag_tmp) return; - - /* check path of new swap file */ - reppath(file->path,openpath,time,"",""); - - if (!strcmp(openpath,file->openpath)) { - tracet(2,"swapfile: no need to swap %s\n",openpath); - return; - } - /* save file pointer to temporary pointer */ - file->fp_tmp=file->fp; - file->fp_tag_tmp=file->fp_tag; - - /* open new swap file */ - openfile_(file,time,msg); +static void swapfile(file_t *file, gtime_t time, char *msg) { + char openpath[MAXSTRPATH]; + + char tstr[40]; + tracet(3, "swapfile: fp=%d time=%s\n", file->fp, time2str(time, tstr, 0)); + + /* return if old swap file open */ + if (file->fp_tmp || file->fp_tag_tmp) return; + + /* check path of new swap file */ + reppath(file->path, openpath, time, "", ""); + + if (!strcmp(openpath, file->openpath)) { + tracet(2, "swapfile: no need to swap %s\n", openpath); + return; + } + /* save file pointer to temporary pointer */ + file->fp_tmp = file->fp; + file->fp_tag_tmp = file->fp_tag; + + /* open new swap file */ + openfile_(file, time, msg); } /* close old swap file -------------------------------------------------------*/ -static void swapclose(file_t *file) -{ - tracet(3,"swapclose: fp_tmp=%d\n",file->fp_tmp); - - if (file->fp_tmp ) fclose(file->fp_tmp ); - if (file->fp_tag_tmp) fclose(file->fp_tag_tmp); - file->fp_tmp=file->fp_tag_tmp=NULL; +static void swapclose(file_t *file) { + tracet(3, "swapclose: fp_tmp=%d\n", file->fp_tmp); + + if (file->fp_tmp) fclose(file->fp_tmp); + if (file->fp_tag_tmp) fclose(file->fp_tag_tmp); + file->fp_tmp = file->fp_tag_tmp = NULL; } /* get state file ------------------------------------------------------------*/ -static int statefile(file_t *file) -{ - return file?2:0; -} +static int statefile(file_t *file) { return file ? 2 : 0; } /* get extended state file ---------------------------------------------------*/ -static int statexfile(file_t *file, char *msg) -{ - char *p=msg,tstr1[40],tstr2[40]; - int state=file?2:0; - - p+=sprintf(p,"file:\n"); - p+=sprintf(p," state = %d\n",state); - if (!state) return 0; - time2str(file->time ,tstr1,3); - time2str(file->wtime,tstr2,3); - p+=sprintf(p," path = %s\n",file->path); - p+=sprintf(p," openpath= %s\n",file->openpath); - p+=sprintf(p," mode = %d\n",file->mode); - p+=sprintf(p," timetag = %d\n",file->timetag); - p+=sprintf(p," repmode = %d\n",file->repmode); - p+=sprintf(p," offsete = %d\n",file->offset); - p+=sprintf(p," time = %s\n",tstr1); - p+=sprintf(p," wtime = %s\n",tstr2); - p+=sprintf(p," tick = %u\n",file->tick); - p+=sprintf(p," tick_f = %u\n",file->tick_f); - p+=sprintf(p," start = %.3f\n",file->start); - p+=sprintf(p," speed = %.3f\n",file->speed); - sprintf(p," swapintv= %.3f\n",file->swapintv); - return state; +static int statexfile(file_t *file, char *msg) { + char *p = msg, tstr1[40], tstr2[40]; + int state = file ? 2 : 0; + + p += sprintf(p, "file:\n"); + p += sprintf(p, " state = %d\n", state); + if (!state) return 0; + time2str(file->time, tstr1, 3); + time2str(file->wtime, tstr2, 3); + p += sprintf(p, " path = %s\n", file->path); + p += sprintf(p, " openpath= %s\n", file->openpath); + p += sprintf(p, " mode = %d\n", file->mode); + p += sprintf(p, " timetag = %d\n", file->timetag); + p += sprintf(p, " repmode = %d\n", file->repmode); + p += sprintf(p, " offsete = %d\n", file->offset); + p += sprintf(p, " time = %s\n", tstr1); + p += sprintf(p, " wtime = %s\n", tstr2); + p += sprintf(p, " tick = %u\n", file->tick); + p += sprintf(p, " tick_f = %u\n", file->tick_f); + p += sprintf(p, " start = %.3f\n", file->start); + p += sprintf(p, " speed = %.3f\n", file->speed); + sprintf(p, " swapintv= %.3f\n", file->swapintv); + return state; } /* read file -----------------------------------------------------------------*/ -static int readfile(file_t *file, uint8_t *buff, int nmax, char *msg) -{ - struct timeval tv={0}; - fd_set rs; - uint64_t fpos_8B; - uint32_t t,tick,fpos_4B; - long pos,n; - int nr=0; - - tracet(4,"readfile: fp=%d nmax=%d\n",file->fp,nmax); - - if (!file) return 0; - - if (file->fp==stdin) { +static int readfile(file_t *file, uint8_t *buff, int nmax, char *msg) { + struct timeval tv = {0}; + fd_set rs; + uint64_t fpos_8B; + uint32_t t, tick, fpos_4B; + long pos, n; + int nr = 0; + + tracet(4, "readfile: fp=%d nmax=%d\n", file->fp, nmax); + + if (!file) return 0; + + if (file->fp == stdin) { #ifndef WIN32 - /* input from stdin */ - FD_ZERO(&rs); FD_SET(0,&rs); - if (!select(1,&rs,NULL,NULL,&tv)) return 0; - if ((nr=(int)read(0,buff,nmax))<0) return 0; - return nr; + /* input from stdin */ + FD_ZERO(&rs); + FD_SET(0, &rs); + if (!select(1, &rs, NULL, NULL, &tv)) return 0; + if ((nr = (int)read(0, buff, nmax)) < 0) return 0; + return nr; #else - return 0; + return 0; #endif - } - if (file->fp_tag) { - - /* target tick */ - if (file->repmode) { /* slave */ - t=(uint32_t)(tick_master+file->offset); - } - else { /* master */ - t=(uint32_t)((tickget()-file->tick)*file->speed+file->start*1000.0); - tick_master=t; - } - /* seek time-tag file to get next tick and file position */ - while ((int)(file->tick_n-t)<=0) { - - if (fread(&file->tick_n,sizeof(tick),1,file->fp_tag)<1|| - fread((file->size_fpos==4)?(void *)&fpos_4B:(void *)&fpos_8B, - file->size_fpos,1,file->fp_tag)<1) { - file->tick_n=(uint32_t)(-1); - pos=ftell(file->fp); - fseek(file->fp,0L,SEEK_END); - file->fpos_n=ftell(file->fp); - fseek(file->fp,pos,SEEK_SET); - break; - } - file->fpos_n=(long)((file->size_fpos==4)?fpos_4B:fpos_8B); - } - if (file->tick_n==(uint32_t)(-1)) { - sprintf(msg,"end"); - } - else { - sprintf(msg,"T%+.1fs",(int)t*0.001); - file->wtime=timeadd(file->time,(int)t*0.001); - timeset(timeadd(gpst2utc(file->time),(int)file->tick_n*0.001)); - } - if ((n=file->fpos_n-ftell(file->fp))0) { - nr=(int)fread(buff,1,nmax,file->fp); - } - if (feof(file->fp)) { - sprintf(msg,"end"); - } - tracet(5,"readfile: fp=%d nr=%d\n",file->fp,nr); - return nr; + } + if (file->fp_tag) { + /* target tick */ + if (file->repmode) { /* slave */ + t = (uint32_t)(tick_master + file->offset); + } else { /* master */ + t = (uint32_t)((tickget() - file->tick) * file->speed + file->start * 1000.0); + tick_master = t; + } + /* seek time-tag file to get next tick and file position */ + while ((int)(file->tick_n - t) <= 0) { + if (fread(&file->tick_n, sizeof(tick), 1, file->fp_tag) < 1 || + fread((file->size_fpos == 4) ? (void *)&fpos_4B : (void *)&fpos_8B, file->size_fpos, 1, + file->fp_tag) < 1) { + file->tick_n = (uint32_t)(-1); + pos = ftell(file->fp); + fseek(file->fp, 0L, SEEK_END); + file->fpos_n = ftell(file->fp); + fseek(file->fp, pos, SEEK_SET); + break; + } + file->fpos_n = (long)((file->size_fpos == 4) ? fpos_4B : fpos_8B); + } + if (file->tick_n == (uint32_t)(-1)) { + sprintf(msg, "end"); + } else { + sprintf(msg, "T%+.1fs", (int)t * 0.001); + file->wtime = timeadd(file->time, (int)t * 0.001); + timeset(timeadd(gpst2utc(file->time), (int)file->tick_n * 0.001)); + } + if ((n = file->fpos_n - ftell(file->fp)) < nmax) { + nmax = n; + } + } + if (nmax > 0) { + nr = (int)fread(buff, 1, nmax, file->fp); + } + if (feof(file->fp)) { + sprintf(msg, "end"); + } + tracet(5, "readfile: fp=%d nr=%d\n", file->fp, nr); + return nr; } /* write file ----------------------------------------------------------------*/ -static int writefile(file_t *file, uint8_t *buff, int n, char *msg) -{ - gtime_t wtime; - uint64_t fpos_8B; - uint32_t tick=tickget(),fpos_4B; - int week1,week2,ns; - double tow1,tow2,intv; - long fpos,fpos_tmp=0; - - tracet(4,"writefile: fp=%d n=%d\n",file->fp,n); - - if (!file) return 0; - - wtime=utc2gpst(timeget()); /* write time in gpst */ - - /* swap writing file */ - if (file->swapintv>0.0&&file->wtime.time!=0) { - intv=file->swapintv*3600.0; - tow1=time2gpst(file->wtime,&week1); - tow2=time2gpst(wtime,&week2); - tow2+=604800.0*(week2-week1); - - /* open new swap file */ - if (floor((tow1+fswapmargin)/intv)fp) return 0; - - ns=(int)fwrite(buff,1,n,file->fp); - fpos=ftell(file->fp); - fflush(file->fp); - file->wtime=wtime; - - if (file->fp_tmp) { - fwrite(buff,1,n,file->fp_tmp); - fpos_tmp=ftell(file->fp_tmp); - fflush(file->fp_tmp); +static int writefile(file_t *file, uint8_t *buff, int n, char *msg) { + gtime_t wtime; + uint64_t fpos_8B; + uint32_t tick = tickget(), fpos_4B; + int week1, week2, ns; + double tow1, tow2, intv; + long fpos, fpos_tmp = 0; + + tracet(4, "writefile: fp=%d n=%d\n", file->fp, n); + + if (!file) return 0; + + wtime = utc2gpst(timeget()); /* write time in gpst */ + + /* swap writing file */ + if (file->swapintv > 0.0 && file->wtime.time != 0) { + intv = file->swapintv * 3600.0; + tow1 = time2gpst(file->wtime, &week1); + tow2 = time2gpst(wtime, &week2); + tow2 += 604800.0 * (week2 - week1); + + /* open new swap file */ + if (floor((tow1 + fswapmargin) / intv) < floor((tow2 + fswapmargin) / intv)) { + swapfile(file, timeadd(wtime, fswapmargin), msg); } - if (file->fp_tag) { - tick-=file->tick; - fwrite(&tick,1,sizeof(tick),file->fp_tag); - if (file->size_fpos==4) { - fpos_4B=(uint32_t)fpos; - fwrite(&fpos_4B,1,sizeof(fpos_4B),file->fp_tag); - } - else { - fpos_8B=(uint64_t)fpos; - fwrite(&fpos_8B,1,sizeof(fpos_8B),file->fp_tag); - } - fflush(file->fp_tag); - - if (file->fp_tag_tmp) { - fwrite(&tick,1,sizeof(tick),file->fp_tag_tmp); - if (file->size_fpos==4) { - fpos_4B=(uint32_t)fpos_tmp; - fwrite(&fpos_4B,1,sizeof(fpos_4B),file->fp_tag_tmp); - } - else { - fpos_8B=(uint64_t)fpos_tmp; - fwrite(&fpos_8B,1,sizeof(fpos_8B),file->fp_tag_tmp); - } - fflush(file->fp_tag_tmp); - } + /* close old swap file */ + if (floor((tow1 - fswapmargin) / intv) < floor((tow2 - fswapmargin) / intv)) { + swapclose(file); } - tracet(5,"writefile: fp=%d ns=%d tick=%5d fpos=%d\n",file->fp,ns,tick,fpos); - - return ns; + } + if (!file->fp) return 0; + + ns = (int)fwrite(buff, 1, n, file->fp); + fpos = ftell(file->fp); + fflush(file->fp); + file->wtime = wtime; + + if (file->fp_tmp) { + fwrite(buff, 1, n, file->fp_tmp); + fpos_tmp = ftell(file->fp_tmp); + fflush(file->fp_tmp); + } + if (file->fp_tag) { + tick -= file->tick; + fwrite(&tick, 1, sizeof(tick), file->fp_tag); + if (file->size_fpos == 4) { + fpos_4B = (uint32_t)fpos; + fwrite(&fpos_4B, 1, sizeof(fpos_4B), file->fp_tag); + } else { + fpos_8B = (uint64_t)fpos; + fwrite(&fpos_8B, 1, sizeof(fpos_8B), file->fp_tag); + } + fflush(file->fp_tag); + + if (file->fp_tag_tmp) { + fwrite(&tick, 1, sizeof(tick), file->fp_tag_tmp); + if (file->size_fpos == 4) { + fpos_4B = (uint32_t)fpos_tmp; + fwrite(&fpos_4B, 1, sizeof(fpos_4B), file->fp_tag_tmp); + } else { + fpos_8B = (uint64_t)fpos_tmp; + fwrite(&fpos_8B, 1, sizeof(fpos_8B), file->fp_tag_tmp); + } + fflush(file->fp_tag_tmp); + } + } + tracet(5, "writefile: fp=%d ns=%d tick=%5d fpos=%d\n", file->fp, ns, tick, fpos); + + return ns; } /* sync files by time-tag ----------------------------------------------------*/ -static void syncfile(file_t *file1, file_t *file2) -{ - if (!file1->fp_tag||!file2->fp_tag) return; - file1->repmode=0; - file2->repmode=1; - file2->offset=(int)(file1->tick_f-file2->tick_f); +static void syncfile(file_t *file1, file_t *file2) { + if (!file1->fp_tag || !file2->fp_tag) return; + file1->repmode = 0; + file2->repmode = 1; + file2->offset = (int)(file1->tick_f - file2->tick_f); } /* decode tcp/ntrip path (path=[user[:passwd]@]addr[:port][/mntpnt[:str]]) ---*/ -static void decodetcppath(const char *path, char *addr, char *port, char *user, - char *passwd, char *mntpnt, char *str) -{ - char buff[MAXSTRPATH],*p,*q; - - tracet(4,"decodetcpepath: path=%s\n",path); - - if (port) *port='\0'; - if (user) *user='\0'; - if (passwd) *passwd='\0'; - if (mntpnt) *mntpnt='\0'; - if (str) *str='\0'; - - strcpy(buff,path); - - if (!(p=strrchr(buff,'@'))) p=buff; - - if ((p=strchr(p,'/'))) { - if ((q=strchr(p+1,':'))) { - *q='\0'; if (str) sprintf(str,"%.*s",NTRIP_MAXSTR-1,q+1); - } - *p='\0'; if (mntpnt) sprintf(mntpnt,"%.255s",p+1); - } - if ((p=strrchr(buff,'@'))) { - *p++='\0'; - if ((q=strchr(buff,':'))) { - *q='\0'; if (passwd) sprintf(passwd,"%.255s",q+1); - } - if (user) sprintf(user,"%.255s",buff); - } - else p=buff; - - if ((q=strchr(p,':'))) { - *q='\0'; if (port) sprintf(port,"%.255s",q+1); - } - if (addr) sprintf(addr,"%.255s",p); +static void decodetcppath(const char *path, char *addr, char *port, char *user, char *passwd, + char *mntpnt, char *str) { + char buff[MAXSTRPATH], *p, *q; + + tracet(4, "decodetcpepath: path=%s\n", path); + + if (port) *port = '\0'; + if (user) *user = '\0'; + if (passwd) *passwd = '\0'; + if (mntpnt) *mntpnt = '\0'; + if (str) *str = '\0'; + + strcpy(buff, path); + + if (!(p = strrchr(buff, '@'))) p = buff; + + if ((p = strchr(p, '/'))) { + if ((q = strchr(p + 1, ':'))) { + *q = '\0'; + if (str) sprintf(str, "%.*s", NTRIP_MAXSTR - 1, q + 1); + } + *p = '\0'; + if (mntpnt) sprintf(mntpnt, "%.255s", p + 1); + } + if ((p = strrchr(buff, '@'))) { + *p++ = '\0'; + if ((q = strchr(buff, ':'))) { + *q = '\0'; + if (passwd) sprintf(passwd, "%.255s", q + 1); + } + if (user) sprintf(user, "%.255s", buff); + } else + p = buff; + + if ((q = strchr(p, ':'))) { + *q = '\0'; + if (port) sprintf(port, "%.255s", q + 1); + } + if (addr) sprintf(addr, "%.255s", p); } /* get socket error ----------------------------------------------------------*/ #ifdef WIN32 -static int errsock(void) {return WSAGetLastError();} +static int errsock(void) { return WSAGetLastError(); } #else -static int errsock(void) {return errno;} +static int errsock(void) { return errno; } #endif /* set socket option ---------------------------------------------------------*/ -static int setsock(socket_t sock, char *msg) -{ - int bs=buffsize,mode=1; +static int setsock(socket_t sock, char *msg) { + int bs = buffsize, mode = 1; #ifdef WIN32 - int tv=0; + int tv = 0; #else - struct timeval tv={0}; + struct timeval tv = {0}; #endif - tracet(3,"setsock: sock=%d\n",sock); - - if (setsockopt(sock,SOL_SOCKET,SO_RCVTIMEO,(const char *)&tv,sizeof(tv))==-1|| - setsockopt(sock,SOL_SOCKET,SO_SNDTIMEO,(const char *)&tv,sizeof(tv))==-1) { - sprintf(msg,"sockopt error: notimeo"); - tracet(1,"setsock: setsockopt error 1 sock=%d err=%d\n",sock,errsock()); - closesocket(sock); - return 0; - } - if (setsockopt(sock,SOL_SOCKET,SO_RCVBUF,(const char *)&bs,sizeof(bs))==-1|| - setsockopt(sock,SOL_SOCKET,SO_SNDBUF,(const char *)&bs,sizeof(bs))==-1) { - tracet(1,"setsock: setsockopt error 2 sock=%d err=%d bs=%d\n",sock,errsock(),bs); - sprintf(msg,"sockopt error: bufsiz"); - } - if (setsockopt(sock,IPPROTO_TCP,TCP_NODELAY,(const char *)&mode,sizeof(mode))==-1) { - tracet(1,"setsock: setsockopt error 3 sock=%d err=%d\n",sock,errsock()); - sprintf(msg,"sockopt error: nodelay"); - } - return 1; + tracet(3, "setsock: sock=%d\n", sock); + + if (setsockopt(sock, SOL_SOCKET, SO_RCVTIMEO, (const char *)&tv, sizeof(tv)) == -1 || + setsockopt(sock, SOL_SOCKET, SO_SNDTIMEO, (const char *)&tv, sizeof(tv)) == -1) { + sprintf(msg, "sockopt error: notimeo"); + tracet(1, "setsock: setsockopt error 1 sock=%d err=%d\n", sock, errsock()); + closesocket(sock); + return 0; + } + if (setsockopt(sock, SOL_SOCKET, SO_RCVBUF, (const char *)&bs, sizeof(bs)) == -1 || + setsockopt(sock, SOL_SOCKET, SO_SNDBUF, (const char *)&bs, sizeof(bs)) == -1) { + tracet(1, "setsock: setsockopt error 2 sock=%d err=%d bs=%d\n", sock, errsock(), bs); + sprintf(msg, "sockopt error: bufsiz"); + } + if (setsockopt(sock, IPPROTO_TCP, TCP_NODELAY, (const char *)&mode, sizeof(mode)) == -1) { + tracet(1, "setsock: setsockopt error 3 sock=%d err=%d\n", sock, errsock()); + sprintf(msg, "sockopt error: nodelay"); + } + return 1; } /* non-block accept ----------------------------------------------------------*/ -static socket_t accept_nb(socket_t sock, struct sockaddr *addr, socklen_t *len, int *err) -{ - fd_set rs; - FD_ZERO(&rs); FD_SET(sock, &rs); - struct timeval tv = {0}; - int ret = select(sock + 1, &rs, NULL, NULL, &tv); - if (ret == 0) { - *err = 0; - return (socket_t)ret; - } - if (ret < 0) { - *err = errsock(); - return (socket_t)ret; - } - socket_t nsock = accept(sock, addr, len); - if (nsock == (socket_t)-1) { - *err = errsock(); - return nsock; - } +static socket_t accept_nb(socket_t sock, struct sockaddr *addr, socklen_t *len, int *err) { + fd_set rs; + FD_ZERO(&rs); + FD_SET(sock, &rs); + struct timeval tv = {0}; + int ret = select(sock + 1, &rs, NULL, NULL, &tv); + if (ret == 0) { *err = 0; + return (socket_t)ret; + } + if (ret < 0) { + *err = errsock(); + return (socket_t)ret; + } + socket_t nsock = accept(sock, addr, len); + if (nsock == (socket_t)-1) { + *err = errsock(); return nsock; + } + *err = 0; + return nsock; } /* non-block connect ---------------------------------------------------------*/ -static int connect_nb(socket_t sock, struct sockaddr *addr, socklen_t len, int *err) -{ +static int connect_nb(socket_t sock, struct sockaddr *addr, socklen_t len, int *err) { #ifdef WIN32 - u_long mode=1; - ioctlsocket(sock,FIONBIO,&mode); - if (connect(sock,addr,len)==-1) { - *err=errsock(); - if (*err==WSAEWOULDBLOCK||*err==WSAEINPROGRESS|| - *err==WSAEALREADY ||*err==WSAEINVAL) return 0; - if (*err!=WSAEISCONN) return -1; - } + u_long mode = 1; + ioctlsocket(sock, FIONBIO, &mode); + if (connect(sock, addr, len) == -1) { + *err = errsock(); + if (*err == WSAEWOULDBLOCK || *err == WSAEINPROGRESS || *err == WSAEALREADY || + *err == WSAEINVAL) + return 0; + if (*err != WSAEISCONN) return -1; + } #else - int flag = fcntl(sock, F_GETFL, 0); - fcntl(sock, F_SETFL, flag | O_NONBLOCK); - if (connect(sock, addr, len) == -1) { - *err = errsock(); - if (*err != EISCONN && *err != EINPROGRESS && *err != EALREADY) return -1; - fd_set rs, ws; - FD_ZERO(&rs); FD_SET(sock, &rs); ws = rs; - struct timeval tv = {0}; - if (select(sock + 1, &rs, &ws, NULL, &tv) == 0) { - *err = 0; - return 0; - } - *err = 0; - return 1; + int flag = fcntl(sock, F_GETFL, 0); + fcntl(sock, F_SETFL, flag | O_NONBLOCK); + if (connect(sock, addr, len) == -1) { + *err = errsock(); + if (*err != EISCONN && *err != EINPROGRESS && *err != EALREADY) return -1; + fd_set rs, ws; + FD_ZERO(&rs); + FD_SET(sock, &rs); + ws = rs; + struct timeval tv = {0}; + if (select(sock + 1, &rs, &ws, NULL, &tv) == 0) { + *err = 0; + return 0; } -#endif *err = 0; return 1; + } +#endif + *err = 0; + return 1; } /* non-block receive ---------------------------------------------------------*/ -static int recv_nb(socket_t sock, uint8_t *buff, int n, int *err) -{ - fd_set rs; - FD_ZERO(&rs); FD_SET(sock, &rs); - struct timeval tv = {0}; - int ret = select(sock + 1, &rs, NULL, NULL, &tv); - if (ret < 0) { - *err = errsock(); - return ret; - } - if (ret == 0) { - *err = 0; - return ret; - } - int nr = recv(sock, (char *)buff, n, 0); - if (nr == 0) { - *err = 0; - return -1; - } - if (nr < 0) { - *err = errsock(); - return -1; - } +static int recv_nb(socket_t sock, uint8_t *buff, int n, int *err) { + fd_set rs; + FD_ZERO(&rs); + FD_SET(sock, &rs); + struct timeval tv = {0}; + int ret = select(sock + 1, &rs, NULL, NULL, &tv); + if (ret < 0) { + *err = errsock(); + return ret; + } + if (ret == 0) { *err = 0; - return nr; + return ret; + } + int nr = recv(sock, (char *)buff, n, 0); + if (nr == 0) { + *err = 0; + return -1; + } + if (nr < 0) { + *err = errsock(); + return -1; + } + *err = 0; + return nr; } /* non-block send ------------------------------------------------------------*/ -static int send_nb(socket_t sock, uint8_t *buff, int n, int *err) -{ - fd_set ws; - FD_ZERO(&ws); FD_SET(sock, &ws); - struct timeval tv = {0}; - int ret = select(sock + 1, NULL, &ws, NULL, &tv); - if (ret < 0) { - *err = errsock(); - return ret; - } - if (ret == 0) { - *err = 0; - return ret; - } - int ns = send(sock, (char *)buff, n, 0); - if (ns < 0) { - *err = errsock(); - return -1; - } +static int send_nb(socket_t sock, uint8_t *buff, int n, int *err) { + fd_set ws; + FD_ZERO(&ws); + FD_SET(sock, &ws); + struct timeval tv = {0}; + int ret = select(sock + 1, NULL, &ws, NULL, &tv); + if (ret < 0) { + *err = errsock(); + return ret; + } + if (ret == 0) { *err = 0; - return ns; + return ret; + } + int ns = send(sock, (char *)buff, n, 0); + if (ns < 0) { + *err = errsock(); + return -1; + } + *err = 0; + return ns; } /* generate tcp socket -------------------------------------------------------*/ -static int gentcp(tcp_t *tcp, int type, char *msg) -{ - struct hostent *hp; +static int gentcp(tcp_t *tcp, int type, char *msg) { + struct hostent *hp; #ifdef SVR_REUSEADDR - int opt=1; + int opt = 1; #endif - - tracet(3,"gentcp: type=%d\n",type); - - /* generate socket */ - if ((tcp->sock=socket(AF_INET,SOCK_STREAM,0))==(socket_t)-1) { - sprintf(msg,"socket error (%d)",errsock()); - tracet(1,"gentcp: socket error err=%d\n",errsock()); - tcp->state=-1; - return 0; - } - if (!setsock(tcp->sock,msg)) { - tcp->state=-1; - return 0; - } - memset(&tcp->addr,0,sizeof(tcp->addr)); - tcp->addr.sin_family=AF_INET; - tcp->addr.sin_port=htons(tcp->port); - - if (type==0) { /* server socket */ - + + tracet(3, "gentcp: type=%d\n", type); + + /* generate socket */ + if ((tcp->sock = socket(AF_INET, SOCK_STREAM, 0)) == (socket_t)-1) { + sprintf(msg, "socket error (%d)", errsock()); + tracet(1, "gentcp: socket error err=%d\n", errsock()); + tcp->state = -1; + return 0; + } + if (!setsock(tcp->sock, msg)) { + tcp->state = -1; + return 0; + } + memset(&tcp->addr, 0, sizeof(tcp->addr)); + tcp->addr.sin_family = AF_INET; + tcp->addr.sin_port = htons(tcp->port); + + if (type == 0) { /* server socket */ + #ifdef SVR_REUSEADDR - /* multiple-use of server socket */ - setsockopt(tcp->sock,SOL_SOCKET,SO_REUSEADDR,(const char *)&opt, - sizeof(opt)); + /* multiple-use of server socket */ + setsockopt(tcp->sock, SOL_SOCKET, SO_REUSEADDR, (const char *)&opt, sizeof(opt)); #endif - if(tcp->saddr[0]) - { - if(!(hp=gethostbyname(tcp->saddr))) { - sprintf(msg,"address error (%s)",tcp->saddr); - tracet(1,"gentcp: gethostbyname error addr=%s err=%d\n",tcp->saddr,errsock()); - closesocket(tcp->sock); - tcp->state=-1; - return 0; - } - memcpy(&tcp->addr.sin_addr,hp->h_addr,hp->h_length); - } - if (bind(tcp->sock,(struct sockaddr *)&tcp->addr,sizeof(tcp->addr))==-1) { - sprintf(msg,"bind error (%d) : %d",errsock(),tcp->port); - tracet(1,"gentcp: bind error port=%d err=%d\n",tcp->port,errsock()); - closesocket(tcp->sock); - tcp->state=-1; - return 0; - } - listen(tcp->sock,5); - } - else { /* client socket */ - if (!(hp=gethostbyname(tcp->saddr))) { - sprintf(msg,"address error (%s)",tcp->saddr); - // h_errno ? - tracet(1,"gentcp: gethostbyname error addr=%s err=%d\n",tcp->saddr,errsock()); - closesocket(tcp->sock); - tcp->state=0; - tcp->tcon=ticonnect; - tcp->tdis=tickget(); - return 0; - } - memcpy(&tcp->addr.sin_addr,hp->h_addr,hp->h_length); - } - tcp->state=1; - tcp->tact=tickget(); - tracet(5,"gentcp: exit sock=%d\n",tcp->sock); - return 1; + if (tcp->saddr[0]) { + if (!(hp = gethostbyname(tcp->saddr))) { + sprintf(msg, "address error (%s)", tcp->saddr); + tracet(1, "gentcp: gethostbyname error addr=%s err=%d\n", tcp->saddr, errsock()); + closesocket(tcp->sock); + tcp->state = -1; + return 0; + } + memcpy(&tcp->addr.sin_addr, hp->h_addr, hp->h_length); + } + if (bind(tcp->sock, (struct sockaddr *)&tcp->addr, sizeof(tcp->addr)) == -1) { + sprintf(msg, "bind error (%d) : %d", errsock(), tcp->port); + tracet(1, "gentcp: bind error port=%d err=%d\n", tcp->port, errsock()); + closesocket(tcp->sock); + tcp->state = -1; + return 0; + } + listen(tcp->sock, 5); + } else { /* client socket */ + if (!(hp = gethostbyname(tcp->saddr))) { + sprintf(msg, "address error (%s)", tcp->saddr); + // h_errno ? + tracet(1, "gentcp: gethostbyname error addr=%s err=%d\n", tcp->saddr, errsock()); + closesocket(tcp->sock); + tcp->state = 0; + tcp->tcon = ticonnect; + tcp->tdis = tickget(); + return 0; + } + memcpy(&tcp->addr.sin_addr, hp->h_addr, hp->h_length); + } + tcp->state = 1; + tcp->tact = tickget(); + tracet(5, "gentcp: exit sock=%d\n", tcp->sock); + return 1; } /* disconnect tcp ------------------------------------------------------------*/ -static void discontcp(tcp_t *tcp, int tcon) -{ - tracet(3,"discontcp: sock=%d tcon=%d\n",tcp->sock,tcon); - - closesocket(tcp->sock); - tcp->state=0; - tcp->tcon=tcon; - tcp->tdis=tickget(); +static void discontcp(tcp_t *tcp, int tcon) { + tracet(3, "discontcp: sock=%d tcon=%d\n", tcp->sock, tcon); + + closesocket(tcp->sock); + tcp->state = 0; + tcp->tcon = tcon; + tcp->tdis = tickget(); } /* open tcp server -----------------------------------------------------------*/ -static tcpsvr_t *opentcpsvr(const char *path, char *msg) -{ - tcpsvr_t *tcpsvr,tcpsvr0={{0}}; - char port[256]=""; - - tracet(3,"opentcpsvr: path=%s\n",path); - - if (!(tcpsvr=(tcpsvr_t *)malloc(sizeof(tcpsvr_t)))) return NULL; - *tcpsvr=tcpsvr0; - decodetcppath(path,tcpsvr->svr.saddr,port,NULL,NULL,NULL,NULL); - if (sscanf(port,"%d",&tcpsvr->svr.port)<1) { - sprintf(msg,"port error: %s",port); - tracet(1,"opentcpsvr: port error port=%s\n",port); - free(tcpsvr); - return NULL; - } - if (!gentcp(&tcpsvr->svr,0,msg)) { - free(tcpsvr); - return NULL; - } - tcpsvr->svr.tcon=0; - return tcpsvr; +static tcpsvr_t *opentcpsvr(const char *path, char *msg) { + tcpsvr_t *tcpsvr, tcpsvr0 = {{0}}; + char port[256] = ""; + + tracet(3, "opentcpsvr: path=%s\n", path); + + if (!(tcpsvr = (tcpsvr_t *)malloc(sizeof(tcpsvr_t)))) return NULL; + *tcpsvr = tcpsvr0; + decodetcppath(path, tcpsvr->svr.saddr, port, NULL, NULL, NULL, NULL); + if (sscanf(port, "%d", &tcpsvr->svr.port) < 1) { + sprintf(msg, "port error: %s", port); + tracet(1, "opentcpsvr: port error port=%s\n", port); + free(tcpsvr); + return NULL; + } + if (!gentcp(&tcpsvr->svr, 0, msg)) { + free(tcpsvr); + return NULL; + } + tcpsvr->svr.tcon = 0; + return tcpsvr; } /* close tcp server ----------------------------------------------------------*/ -static void closetcpsvr(tcpsvr_t *tcpsvr) -{ - int i; - - tracet(3,"closetcpsvr:\n"); - - for (i=0;icli[i].state) closesocket(tcpsvr->cli[i].sock); - } - closesocket(tcpsvr->svr.sock); - free(tcpsvr); +static void closetcpsvr(tcpsvr_t *tcpsvr) { + int i; + + tracet(3, "closetcpsvr:\n"); + + for (i = 0; i < MAXCLI; i++) { + if (tcpsvr->cli[i].state) closesocket(tcpsvr->cli[i].sock); + } + closesocket(tcpsvr->svr.sock); + free(tcpsvr); } /* update tcp server ---------------------------------------------------------*/ -static void updatetcpsvr(tcpsvr_t *tcpsvr, char *msg) -{ - char saddr[256]=""; - int i,n=0; - - tracet(4,"updatetcpsvr: state=%d\n",tcpsvr->svr.state); - - if (tcpsvr->svr.state==0) return; - - for (i=0;icli[i].state) continue; - strcpy(saddr,tcpsvr->cli[i].saddr); - n++; - } - if (n==0) { - tcpsvr->svr.state=1; - sprintf(msg,"waiting..."); - return; - } - tcpsvr->svr.state=2; - if (n==1) sprintf(msg,"%s",saddr); else sprintf(msg,"%d clients",n); +static void updatetcpsvr(tcpsvr_t *tcpsvr, char *msg) { + char saddr[256] = ""; + int i, n = 0; + + tracet(4, "updatetcpsvr: state=%d\n", tcpsvr->svr.state); + + if (tcpsvr->svr.state == 0) return; + + for (i = 0; i < MAXCLI; i++) { + if (!tcpsvr->cli[i].state) continue; + strcpy(saddr, tcpsvr->cli[i].saddr); + n++; + } + if (n == 0) { + tcpsvr->svr.state = 1; + sprintf(msg, "waiting..."); + return; + } + tcpsvr->svr.state = 2; + if (n == 1) + sprintf(msg, "%s", saddr); + else + sprintf(msg, "%d clients", n); } /* accept client connection --------------------------------------------------*/ -static int accsock(tcpsvr_t *tcpsvr, char *msg) -{ - struct sockaddr_in addr; - socket_t sock; - socklen_t len=sizeof(addr); - int i,err; - - tracet(4,"accsock: sock=%d\n",tcpsvr->svr.sock); - - for (i=0;icli[i].state==0) break; - } - if (i>=MAXCLI) { - tracet(2,"accsock: too many clients sock=%d\n",tcpsvr->svr.sock); - return 0; - } - if ((sock=accept_nb(tcpsvr->svr.sock,(struct sockaddr *)&addr,&len,&err))==(socket_t)-1) { - sprintf(msg,"accept error (%d)",err); - tracet(1,"accsock: accept error sock=%d err=%d\n",tcpsvr->svr.sock,err); - closesocket(tcpsvr->svr.sock); - tcpsvr->svr.state=0; - return 0; - } - if (sock==0) return 0; - if (!setsock(sock,msg)) return 0; - - tcpsvr->cli[i].sock=sock; - memcpy(&tcpsvr->cli[i].addr,&addr,sizeof(addr)); - strcpy(tcpsvr->cli[i].saddr,inet_ntoa(addr.sin_addr)); - sprintf(msg,"%s",tcpsvr->cli[i].saddr); - tracet(3,"accsock: connected sock=%d addr=%s i=%d\n", - tcpsvr->cli[i].sock,tcpsvr->cli[i].saddr,i); - tcpsvr->cli[i].state=2; - tcpsvr->cli[i].tact=tickget(); - return 1; +static int accsock(tcpsvr_t *tcpsvr, char *msg) { + struct sockaddr_in addr; + socket_t sock; + socklen_t len = sizeof(addr); + int i, err; + + tracet(4, "accsock: sock=%d\n", tcpsvr->svr.sock); + + for (i = 0; i < MAXCLI; i++) { + if (tcpsvr->cli[i].state == 0) break; + } + if (i >= MAXCLI) { + tracet(2, "accsock: too many clients sock=%d\n", tcpsvr->svr.sock); + return 0; + } + if ((sock = accept_nb(tcpsvr->svr.sock, (struct sockaddr *)&addr, &len, &err)) == (socket_t)-1) { + sprintf(msg, "accept error (%d)", err); + tracet(1, "accsock: accept error sock=%d err=%d\n", tcpsvr->svr.sock, err); + closesocket(tcpsvr->svr.sock); + tcpsvr->svr.state = 0; + return 0; + } + if (sock == 0) return 0; + if (!setsock(sock, msg)) return 0; + + tcpsvr->cli[i].sock = sock; + memcpy(&tcpsvr->cli[i].addr, &addr, sizeof(addr)); + strcpy(tcpsvr->cli[i].saddr, inet_ntoa(addr.sin_addr)); + sprintf(msg, "%s", tcpsvr->cli[i].saddr); + tracet(3, "accsock: connected sock=%d addr=%s i=%d\n", tcpsvr->cli[i].sock, tcpsvr->cli[i].saddr, + i); + tcpsvr->cli[i].state = 2; + tcpsvr->cli[i].tact = tickget(); + return 1; } /* wait socket accept --------------------------------------------------------*/ -static int waittcpsvr(tcpsvr_t *tcpsvr, char *msg) -{ - tracet(4,"waittcpsvr: sock=%d state=%d\n",tcpsvr->svr.sock,tcpsvr->svr.state); - - if (tcpsvr->svr.state<=0) return 0; - - while (accsock(tcpsvr,msg)) ; - - updatetcpsvr(tcpsvr,msg); - return tcpsvr->svr.state==2; +static int waittcpsvr(tcpsvr_t *tcpsvr, char *msg) { + tracet(4, "waittcpsvr: sock=%d state=%d\n", tcpsvr->svr.sock, tcpsvr->svr.state); + + if (tcpsvr->svr.state <= 0) return 0; + + while (accsock(tcpsvr, msg)); + + updatetcpsvr(tcpsvr, msg); + return tcpsvr->svr.state == 2; } /* read tcp server -----------------------------------------------------------*/ -static int readtcpsvr(tcpsvr_t *tcpsvr, uint8_t *buff, int n, char *msg) -{ - int i,nr,err; - - tracet(4,"readtcpsvr: state=%d\n",tcpsvr->svr.state); - - if (!waittcpsvr(tcpsvr,msg)) return 0; - - for (i=0;icli[i].state!=2) continue; - - if ((nr=recv_nb(tcpsvr->cli[i].sock,buff,n,&err))==-1) { - if (err) { - tracet(2,"readtcpsvr: recv error sock=%d err=%d\n", - tcpsvr->cli[i].sock,err); - } - discontcp(&tcpsvr->cli[i],ticonnect); - updatetcpsvr(tcpsvr,msg); - } - if (nr>0) { - tcpsvr->cli[i].tact=tickget(); - return nr; - } +static int readtcpsvr(tcpsvr_t *tcpsvr, uint8_t *buff, int n, char *msg) { + int i, nr, err; + + tracet(4, "readtcpsvr: state=%d\n", tcpsvr->svr.state); + + if (!waittcpsvr(tcpsvr, msg)) return 0; + + for (i = 0; i < MAXCLI; i++) { + if (tcpsvr->cli[i].state != 2) continue; + + if ((nr = recv_nb(tcpsvr->cli[i].sock, buff, n, &err)) == -1) { + if (err) { + tracet(2, "readtcpsvr: recv error sock=%d err=%d\n", tcpsvr->cli[i].sock, err); + } + discontcp(&tcpsvr->cli[i], ticonnect); + updatetcpsvr(tcpsvr, msg); } - return 0; + if (nr > 0) { + tcpsvr->cli[i].tact = tickget(); + return nr; + } + } + return 0; } /* write tcp server ----------------------------------------------------------*/ -static int writetcpsvr(tcpsvr_t *tcpsvr, uint8_t *buff, int n, char *msg) -{ - int i,ns=0,nmax=0,err; - - tracet(4,"writetcpsvr: state=%d n=%d\n",tcpsvr->svr.state,n); - - if (!waittcpsvr(tcpsvr,msg)) return 0; - - for (i=0;icli[i].state!=2) continue; - - if ((ns=send_nb(tcpsvr->cli[i].sock,buff,n,&err))==-1) { - if (err) { - tracet(2,"writetcpsvr: send error i=%d sock=%d err=%d\n",i, - tcpsvr->cli[i].sock,err); - } - discontcp(&tcpsvr->cli[i],ticonnect); - updatetcpsvr(tcpsvr,msg); - } - else { - if (ns>nmax) nmax=ns; - if (ns>0) tcpsvr->cli[i].tact=tickget(); - } - } - return nmax; +static int writetcpsvr(tcpsvr_t *tcpsvr, uint8_t *buff, int n, char *msg) { + int i, ns = 0, nmax = 0, err; + + tracet(4, "writetcpsvr: state=%d n=%d\n", tcpsvr->svr.state, n); + + if (!waittcpsvr(tcpsvr, msg)) return 0; + + for (i = 0; i < MAXCLI; i++) { + if (tcpsvr->cli[i].state != 2) continue; + + if ((ns = send_nb(tcpsvr->cli[i].sock, buff, n, &err)) == -1) { + if (err) { + tracet(2, "writetcpsvr: send error i=%d sock=%d err=%d\n", i, tcpsvr->cli[i].sock, err); + } + discontcp(&tcpsvr->cli[i], ticonnect); + updatetcpsvr(tcpsvr, msg); + } else { + if (ns > nmax) nmax = ns; + if (ns > 0) tcpsvr->cli[i].tact = tickget(); + } + } + return nmax; } /* get state tcp server ------------------------------------------------------*/ -static int statetcpsvr(tcpsvr_t *tcpsvr) -{ - return tcpsvr?tcpsvr->svr.state:0; -} +static int statetcpsvr(tcpsvr_t *tcpsvr) { return tcpsvr ? tcpsvr->svr.state : 0; } /* print extended state tcp --------------------------------------------------*/ -static int statextcp(tcp_t *tcp, char *msg) -{ - char *p=msg; - - p+=sprintf(p," state = %d\n",tcp->state); - p+=sprintf(p," saddr = %s\n",tcp->saddr); - p+=sprintf(p," port = %d\n",tcp->port); - p+=sprintf(p," sock = %d\n",(int)tcp->sock); +static int statextcp(tcp_t *tcp, char *msg) { + char *p = msg; + + p += sprintf(p, " state = %d\n", tcp->state); + p += sprintf(p, " saddr = %s\n", tcp->saddr); + p += sprintf(p, " port = %d\n", tcp->port); + p += sprintf(p, " sock = %d\n", (int)tcp->sock); #ifdef RTK_DISABLED /* for debug */ - p+=sprintf(p," tcon = %d\n",tcp->tcon); - p+=sprintf(p," tact = %u\n",tcp->tact); - p+=sprintf(p," tdis = %u\n",tcp->tdis); + p += sprintf(p, " tcon = %d\n", tcp->tcon); + p += sprintf(p, " tact = %u\n", tcp->tact); + p += sprintf(p, " tdis = %u\n", tcp->tdis); #endif - return (int)(p-msg); + return (int)(p - msg); } /* get extended state tcp server ---------------------------------------------*/ -static int statextcpsvr(tcpsvr_t *tcpsvr, char *msg) -{ - char *p=msg; - int i,state=tcpsvr?tcpsvr->svr.state:0; - - p+=sprintf(p,"tcpsvr:\n"); - p+=sprintf(p," state = %d\n",state); - if (!state) return 0; - p+=sprintf(p," svr:\n"); - p+=statextcp(&tcpsvr->svr,p); - for (i=0;icli[i].state) continue; - p+=sprintf(p," cli#%d:\n",i); - p+=statextcp(tcpsvr->cli+i,p); - } - return state; +static int statextcpsvr(tcpsvr_t *tcpsvr, char *msg) { + char *p = msg; + int i, state = tcpsvr ? tcpsvr->svr.state : 0; + + p += sprintf(p, "tcpsvr:\n"); + p += sprintf(p, " state = %d\n", state); + if (!state) return 0; + p += sprintf(p, " svr:\n"); + p += statextcp(&tcpsvr->svr, p); + for (i = 0; i < MAXCLI; i++) { + if (!tcpsvr->cli[i].state) continue; + p += sprintf(p, " cli#%d:\n", i); + p += statextcp(tcpsvr->cli + i, p); + } + return state; } /* connect server ------------------------------------------------------------*/ -static int consock(tcpcli_t *tcpcli, char *msg) -{ - int stat,err; - - tracet(4,"consock: sock=%d\n",tcpcli->svr.sock); - - /* wait re-connect */ - if (tcpcli->svr.tcon<0||(tcpcli->svr.tcon>0&& - (int)(tickget()-tcpcli->svr.tdis)svr.tcon)) { - return 0; - } - /* non-block connect */ - if ((stat=connect_nb(tcpcli->svr.sock,(struct sockaddr *)&tcpcli->svr.addr, - sizeof(tcpcli->svr.addr),&err))==-1) { - sprintf(msg,"connect error (%d)",err); - tracet(2,"consock: connect error sock=%d err=%d\n",tcpcli->svr.sock,err); - closesocket(tcpcli->svr.sock); - tcpcli->svr.state=0; - return 0; - } - if (!stat) { /* not connect */ - sprintf(msg,"connecting..."); - return 0; - } - sprintf(msg,"%s",tcpcli->svr.saddr); - tracet(3,"consock: connected sock=%d addr=%s\n",tcpcli->svr.sock,tcpcli->svr.saddr); - tcpcli->svr.state=2; - tcpcli->svr.tact=tickget(); - return 1; +static int consock(tcpcli_t *tcpcli, char *msg) { + int stat, err; + + tracet(4, "consock: sock=%d\n", tcpcli->svr.sock); + + /* wait re-connect */ + if (tcpcli->svr.tcon < 0 || + (tcpcli->svr.tcon > 0 && (int)(tickget() - tcpcli->svr.tdis) < tcpcli->svr.tcon)) { + return 0; + } + /* non-block connect */ + if ((stat = connect_nb(tcpcli->svr.sock, (struct sockaddr *)&tcpcli->svr.addr, + sizeof(tcpcli->svr.addr), &err)) == -1) { + sprintf(msg, "connect error (%d)", err); + tracet(2, "consock: connect error sock=%d err=%d\n", tcpcli->svr.sock, err); + closesocket(tcpcli->svr.sock); + tcpcli->svr.state = 0; + return 0; + } + if (!stat) { /* not connect */ + sprintf(msg, "connecting..."); + return 0; + } + sprintf(msg, "%s", tcpcli->svr.saddr); + tracet(3, "consock: connected sock=%d addr=%s\n", tcpcli->svr.sock, tcpcli->svr.saddr); + tcpcli->svr.state = 2; + tcpcli->svr.tact = tickget(); + return 1; } /* open tcp client -----------------------------------------------------------*/ -static tcpcli_t *opentcpcli(const char *path, char *msg) -{ - tcpcli_t *tcpcli,tcpcli0={{0}}; - char port[256]=""; - - tracet(3,"opentcpcli: path=%s\n",path); - - if (!(tcpcli=(tcpcli_t *)malloc(sizeof(tcpcli_t)))) return NULL; - *tcpcli=tcpcli0; - decodetcppath(path,tcpcli->svr.saddr,port,NULL,NULL,NULL,NULL); - if (sscanf(port,"%d",&tcpcli->svr.port)<1) { - sprintf(msg,"port error: %s",port); - tracet(2,"opentcp: port error port=%s\n",port); - free(tcpcli); - return NULL; - } - tcpcli->svr.tcon=0; - tcpcli->toinact=toinact; - tcpcli->tirecon=ticonnect; - return tcpcli; +static tcpcli_t *opentcpcli(const char *path, char *msg) { + tcpcli_t *tcpcli, tcpcli0 = {{0}}; + char port[256] = ""; + + tracet(3, "opentcpcli: path=%s\n", path); + + if (!(tcpcli = (tcpcli_t *)malloc(sizeof(tcpcli_t)))) return NULL; + *tcpcli = tcpcli0; + decodetcppath(path, tcpcli->svr.saddr, port, NULL, NULL, NULL, NULL); + if (sscanf(port, "%d", &tcpcli->svr.port) < 1) { + sprintf(msg, "port error: %s", port); + tracet(2, "opentcp: port error port=%s\n", port); + free(tcpcli); + return NULL; + } + tcpcli->svr.tcon = 0; + tcpcli->toinact = toinact; + tcpcli->tirecon = ticonnect; + return tcpcli; } /* close tcp client ----------------------------------------------------------*/ -static void closetcpcli(tcpcli_t *tcpcli) -{ - tracet(3,"closetcpcli: sock=%d\n",tcpcli->svr.sock); - - closesocket(tcpcli->svr.sock); - free(tcpcli); +static void closetcpcli(tcpcli_t *tcpcli) { + tracet(3, "closetcpcli: sock=%d\n", tcpcli->svr.sock); + + closesocket(tcpcli->svr.sock); + free(tcpcli); } /* wait socket connect -------------------------------------------------------*/ -static int waittcpcli(tcpcli_t *tcpcli, char *msg) -{ - tracet(4,"waittcpcli: sock=%d state=%d\n",tcpcli->svr.sock,tcpcli->svr.state); - - if (tcpcli->svr.state<0) return 0; - - if (tcpcli->svr.state==0) { /* close */ - if (!gentcp(&tcpcli->svr,1,msg)) return 0; - } - if (tcpcli->svr.state==1) { /* wait */ - if (!consock(tcpcli,msg)) return 0; - } - if (tcpcli->svr.state==2) { /* connect */ - if (tcpcli->toinact>0&& - (int)(tickget()-tcpcli->svr.tact)>tcpcli->toinact) { - sprintf(msg,"timeout"); - tracet(2,"waittcpcli: inactive timeout sock=%d\n",tcpcli->svr.sock); - discontcp(&tcpcli->svr,tcpcli->tirecon); - return 0; - } - } - return 1; +static int waittcpcli(tcpcli_t *tcpcli, char *msg) { + tracet(4, "waittcpcli: sock=%d state=%d\n", tcpcli->svr.sock, tcpcli->svr.state); + + if (tcpcli->svr.state < 0) return 0; + + if (tcpcli->svr.state == 0) { /* close */ + if (!gentcp(&tcpcli->svr, 1, msg)) return 0; + } + if (tcpcli->svr.state == 1) { /* wait */ + if (!consock(tcpcli, msg)) return 0; + } + if (tcpcli->svr.state == 2) { /* connect */ + if (tcpcli->toinact > 0 && (int)(tickget() - tcpcli->svr.tact) > tcpcli->toinact) { + sprintf(msg, "timeout"); + tracet(2, "waittcpcli: inactive timeout sock=%d\n", tcpcli->svr.sock); + discontcp(&tcpcli->svr, tcpcli->tirecon); + return 0; + } + } + return 1; } /* read tcp client -----------------------------------------------------------*/ -static int readtcpcli(tcpcli_t *tcpcli, uint8_t *buff, int n, char *msg) -{ - int nr,err; - - tracet(4,"readtcpcli: sock=%d\n",tcpcli->svr.sock); - - if (!waittcpcli(tcpcli,msg)) return 0; - - if ((nr=recv_nb(tcpcli->svr.sock,buff,n,&err))==-1) { - if (err) { - tracet(2,"readtcpcli: recv error sock=%d err=%d\n",tcpcli->svr.sock,err); - sprintf(msg,"recv error (%d)",err); - } - else { - sprintf(msg,"disconnected"); - } - discontcp(&tcpcli->svr,tcpcli->tirecon); - return 0; - } - if (nr>0) tcpcli->svr.tact=tickget(); - tracet(5,"readtcpcli: exit sock=%d nr=%d\n",tcpcli->svr.sock,nr); - return nr; +static int readtcpcli(tcpcli_t *tcpcli, uint8_t *buff, int n, char *msg) { + int nr, err; + + tracet(4, "readtcpcli: sock=%d\n", tcpcli->svr.sock); + + if (!waittcpcli(tcpcli, msg)) return 0; + + if ((nr = recv_nb(tcpcli->svr.sock, buff, n, &err)) == -1) { + if (err) { + tracet(2, "readtcpcli: recv error sock=%d err=%d\n", tcpcli->svr.sock, err); + sprintf(msg, "recv error (%d)", err); + } else { + sprintf(msg, "disconnected"); + } + discontcp(&tcpcli->svr, tcpcli->tirecon); + return 0; + } + if (nr > 0) tcpcli->svr.tact = tickget(); + tracet(5, "readtcpcli: exit sock=%d nr=%d\n", tcpcli->svr.sock, nr); + return nr; } /* write tcp client ----------------------------------------------------------*/ -static int writetcpcli(tcpcli_t *tcpcli, uint8_t *buff, int n, char *msg) -{ - int ns,err; - - tracet(3,"writetcpcli: sock=%d state=%d n=%d\n",tcpcli->svr.sock,tcpcli->svr.state,n); - - if (!waittcpcli(tcpcli,msg)) return 0; - - if ((ns=send_nb(tcpcli->svr.sock,buff,n,&err))==-1) { - if (err) { - tracet(2,"writetcp: send error sock=%d err=%d\n",tcpcli->svr.sock,err); - sprintf(msg,"send error (%d)",err); - } - discontcp(&tcpcli->svr,tcpcli->tirecon); - return 0; +static int writetcpcli(tcpcli_t *tcpcli, uint8_t *buff, int n, char *msg) { + int ns, err; + + tracet(3, "writetcpcli: sock=%d state=%d n=%d\n", tcpcli->svr.sock, tcpcli->svr.state, n); + + if (!waittcpcli(tcpcli, msg)) return 0; + + if ((ns = send_nb(tcpcli->svr.sock, buff, n, &err)) == -1) { + if (err) { + tracet(2, "writetcp: send error sock=%d err=%d\n", tcpcli->svr.sock, err); + sprintf(msg, "send error (%d)", err); } - if (ns>0) tcpcli->svr.tact=tickget(); - tracet(5,"writetcpcli: exit sock=%d ns=%d\n",tcpcli->svr.sock,ns); - return ns; + discontcp(&tcpcli->svr, tcpcli->tirecon); + return 0; + } + if (ns > 0) tcpcli->svr.tact = tickget(); + tracet(5, "writetcpcli: exit sock=%d ns=%d\n", tcpcli->svr.sock, ns); + return ns; } /* get state tcp client ------------------------------------------------------*/ -static int statetcpcli(tcpcli_t *tcpcli) -{ - return tcpcli?tcpcli->svr.state:0; -} +static int statetcpcli(tcpcli_t *tcpcli) { return tcpcli ? tcpcli->svr.state : 0; } /* get extended state tcp client ---------------------------------------------*/ -static int statextcpcli(tcpcli_t *tcpcli, char *msg) -{ - (void)msg; - return tcpcli?tcpcli->svr.state:0; +static int statextcpcli(tcpcli_t *tcpcli, char *msg) { + (void)msg; + return tcpcli ? tcpcli->svr.state : 0; } /* base64 encoder ------------------------------------------------------------*/ -static int encbase64(char *str, const uint8_t *byte, int n) -{ - const char table[]= - "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; - int i,j,k,b; - - tracet(4,"encbase64: n=%d\n",n); - - for (i=j=0;i/8>(7-i%8))&0x1; - } - str[j++]=table[b]; - } - while (j&0x3) str[j++]='='; - str[j]='\0'; - tracet(5,"encbase64: str=%s\n",str); - return j; +static int encbase64(char *str, const uint8_t *byte, int n) { + const char table[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; + int i, j, k, b; + + tracet(4, "encbase64: n=%d\n", n); + + for (i = j = 0; i / 8 < n;) { + for (k = b = 0; k < 6; k++, i++) { + b <<= 1; + if (i / 8 < n) b |= (byte[i / 8] >> (7 - i % 8)) & 0x1; + } + str[j++] = table[b]; + } + while (j & 0x3) str[j++] = '='; + str[j] = '\0'; + tracet(5, "encbase64: str=%s\n", str); + return j; } /* send ntrip server request -------------------------------------------------*/ -static int reqntrip_s(ntrip_t *ntrip, char *msg) -{ - char buff[1024+NTRIP_MAXSTR],*p=buff; - - tracet(3,"reqntrip_s: state=%d\n",ntrip->state); - - p+=sprintf(p,"SOURCE %s %s\r\n",ntrip->passwd,ntrip->mntpnt); - p+=sprintf(p,"Source-Agent: NTRIP %s\r\n",NTRIP_AGENT); - p+=sprintf(p,"STR: %s\r\n",ntrip->str); - p+=sprintf(p,"\r\n"); - - if (writetcpcli(ntrip->tcp,(uint8_t *)buff,p-buff,msg)!=p-buff) return 0; - - tracet(3,"reqntrip_s: send request state=%d ns=%d\n",ntrip->state,p-buff); - tracet(5,"reqntrip_s: n=%d buff=\n%s\n",p-buff,buff); - ntrip->state=1; - return 1; +static int reqntrip_s(ntrip_t *ntrip, char *msg) { + char buff[1024 + NTRIP_MAXSTR], *p = buff; + + tracet(3, "reqntrip_s: state=%d\n", ntrip->state); + + p += sprintf(p, "SOURCE %s %s\r\n", ntrip->passwd, ntrip->mntpnt); + p += sprintf(p, "Source-Agent: NTRIP %s\r\n", NTRIP_AGENT); + p += sprintf(p, "STR: %s\r\n", ntrip->str); + p += sprintf(p, "\r\n"); + + if (writetcpcli(ntrip->tcp, (uint8_t *)buff, p - buff, msg) != p - buff) return 0; + + tracet(3, "reqntrip_s: send request state=%d ns=%d\n", ntrip->state, p - buff); + tracet(5, "reqntrip_s: n=%d buff=\n%s\n", p - buff, buff); + ntrip->state = 1; + return 1; } /* send ntrip client request -------------------------------------------------*/ -static int reqntrip_c(ntrip_t *ntrip, char *msg) -{ - char buff[MAXSTRPATH+1024],user[514],*p=buff; - - tracet(3,"reqntrip_c: state=%d\n",ntrip->state); - - p+=sprintf(p,"GET %s/%s HTTP/1.0\r\n",ntrip->url,ntrip->mntpnt); - p+=sprintf(p,"User-Agent: NTRIP %s\r\n",NTRIP_AGENT); - - if (!*ntrip->user) { - p+=sprintf(p,"Accept: */*\r\n"); - p+=sprintf(p,"Connection: close\r\n"); - } - else { - sprintf(user,"%s:%s",ntrip->user,ntrip->passwd); - p+=sprintf(p,"Authorization: Basic "); - p+=encbase64(p,(uint8_t *)user,strlen(user)); - p+=sprintf(p,"\r\n"); - } - p+=sprintf(p,"\r\n"); - - if (writetcpcli(ntrip->tcp,(uint8_t *)buff,p-buff,msg)!=p-buff) return 0; - - tracet(3,"reqntrip_c: send request state=%d ns=%d\n",ntrip->state,p-buff); - tracet(5,"reqntrip_c: n=%d buff=\n%s\n",p-buff,buff); - ntrip->state=1; - return 1; +static int reqntrip_c(ntrip_t *ntrip, char *msg) { + char buff[MAXSTRPATH + 1024], user[514], *p = buff; + + tracet(3, "reqntrip_c: state=%d\n", ntrip->state); + + p += sprintf(p, "GET %s/%s HTTP/1.0\r\n", ntrip->url, ntrip->mntpnt); + p += sprintf(p, "User-Agent: NTRIP %s\r\n", NTRIP_AGENT); + + if (!*ntrip->user) { + p += sprintf(p, "Accept: */*\r\n"); + p += sprintf(p, "Connection: close\r\n"); + } else { + sprintf(user, "%s:%s", ntrip->user, ntrip->passwd); + p += sprintf(p, "Authorization: Basic "); + p += encbase64(p, (uint8_t *)user, strlen(user)); + p += sprintf(p, "\r\n"); + } + p += sprintf(p, "\r\n"); + + if (writetcpcli(ntrip->tcp, (uint8_t *)buff, p - buff, msg) != p - buff) return 0; + + tracet(3, "reqntrip_c: send request state=%d ns=%d\n", ntrip->state, p - buff); + tracet(5, "reqntrip_c: n=%d buff=\n%s\n", p - buff, buff); + ntrip->state = 1; + return 1; } /* test ntrip server response ------------------------------------------------*/ -static int rspntrip_s(ntrip_t *ntrip, char *msg) -{ - tracet(3,"rspntrip_s: state=%d nb=%d\n",ntrip->state,ntrip->nb); - ntrip->buff[ntrip->nb]='\0'; - tracet(5,"rspntrip_s: n=%d buff=\n%s\n",ntrip->nb,ntrip->buff); - - char *p; - if ((p=strstr((char *)ntrip->buff,NTRIP_RSP_OK_SVR))) { /* ok */ - p+=strlen(NTRIP_RSP_OK_SVR); - ntrip->nb-=p-(char *)ntrip->buff; - /* Discard all buffer content before the OK. */ - memmove(ntrip->buff, p, ntrip->nb); - ntrip->state=2; - sprintf(msg,"%s/%s",ntrip->tcp->svr.saddr,ntrip->mntpnt); - tracet(3,"rspntrip_s: response ok nb=%d\n",ntrip->nb); - return 1; - } - else if (strstr((char *)ntrip->buff,NTRIP_RSP_ERROR)) { /* error */ - int nb=ntrip->nbnb:MAXSTATMSG; - sprintf(msg,"%.*s",nb,(char *)ntrip->buff); - if ((p=strchr(msg,'\r'))) *p='\0'; - tracet(3,"rspntrip_s: %s nb=%d\n",msg,ntrip->nb); - ntrip->nb=0; - ntrip->buff[0]='\0'; - ntrip->state=0; - discontcp(&ntrip->tcp->svr,ntrip->tcp->tirecon); - } - else if (ntrip->nb>=NTRIP_MAXRSP) { /* buffer overflow */ - sprintf(msg,"response overflow"); - tracet(3,"rspntrip_s: response overflow nb=%d\n",ntrip->nb); - ntrip->nb=0; - ntrip->buff[0]='\0'; - ntrip->state=0; - discontcp(&ntrip->tcp->svr,ntrip->tcp->tirecon); - } - tracet(5,"rspntrip_s: exit state=%d nb=%d\n",ntrip->state,ntrip->nb); - return 0; +static int rspntrip_s(ntrip_t *ntrip, char *msg) { + tracet(3, "rspntrip_s: state=%d nb=%d\n", ntrip->state, ntrip->nb); + ntrip->buff[ntrip->nb] = '\0'; + tracet(5, "rspntrip_s: n=%d buff=\n%s\n", ntrip->nb, ntrip->buff); + + char *p; + if ((p = strstr((char *)ntrip->buff, NTRIP_RSP_OK_SVR))) { /* ok */ + p += strlen(NTRIP_RSP_OK_SVR); + ntrip->nb -= p - (char *)ntrip->buff; + /* Discard all buffer content before the OK. */ + memmove(ntrip->buff, p, ntrip->nb); + ntrip->state = 2; + sprintf(msg, "%s/%s", ntrip->tcp->svr.saddr, ntrip->mntpnt); + tracet(3, "rspntrip_s: response ok nb=%d\n", ntrip->nb); + return 1; + } else if (strstr((char *)ntrip->buff, NTRIP_RSP_ERROR)) { /* error */ + int nb = ntrip->nb < MAXSTATMSG ? ntrip->nb : MAXSTATMSG; + sprintf(msg, "%.*s", nb, (char *)ntrip->buff); + if ((p = strchr(msg, '\r'))) *p = '\0'; + tracet(3, "rspntrip_s: %s nb=%d\n", msg, ntrip->nb); + ntrip->nb = 0; + ntrip->buff[0] = '\0'; + ntrip->state = 0; + discontcp(&ntrip->tcp->svr, ntrip->tcp->tirecon); + } else if (ntrip->nb >= NTRIP_MAXRSP) { /* buffer overflow */ + sprintf(msg, "response overflow"); + tracet(3, "rspntrip_s: response overflow nb=%d\n", ntrip->nb); + ntrip->nb = 0; + ntrip->buff[0] = '\0'; + ntrip->state = 0; + discontcp(&ntrip->tcp->svr, ntrip->tcp->tirecon); + } + tracet(5, "rspntrip_s: exit state=%d nb=%d\n", ntrip->state, ntrip->nb); + return 0; } /* test ntrip client response ------------------------------------------------*/ -static int rspntrip_c(ntrip_t *ntrip, char *msg) -{ - tracet(3,"rspntrip_c: state=%d nb=%d\n",ntrip->state,ntrip->nb); - ntrip->buff[ntrip->nb]='\0'; - tracet(5,"rspntrip_c: n=%d buff=\n%s\n",ntrip->nb,ntrip->buff); - - char *p; - if ((p=strstr((char *)ntrip->buff,NTRIP_RSP_OK_CLI))) { /* ok */ - p+=strlen(NTRIP_RSP_OK_CLI); - ntrip->nb-=p-(char *)ntrip->buff; - /* Discard all buffer content before the OK. */ - memmove(ntrip->buff, p, ntrip->nb); - ntrip->state=2; - sprintf(msg,"%s/%s",ntrip->tcp->svr.saddr,ntrip->mntpnt); - tracet(3,"rspntrip_c: response ok nb=%d\n",ntrip->nb); - ntrip->tcp->tirecon=ticonnect; - return 1; - } - if (strstr((char *)ntrip->buff,NTRIP_RSP_SRCTBL)) { /* source table */ - if (!*ntrip->mntpnt) { /* source table request */ - ntrip->state=2; - sprintf(msg,"source table received"); - tracet(3,"rspntrip_c: receive source table nb=%d\n",ntrip->nb); - return 1; - } - sprintf(msg,"no mountp. reconnect..."); - tracet(2,"rspntrip_c: no mount point nb=%d\n",ntrip->nb); - ntrip->nb=0; - ntrip->buff[0]='\0'; - ntrip->state=0; - /* increase subsequent disconnect time to avoid too many reconnect requests */ - if (ntrip->tcp->tirecon>300000) ntrip->tcp->tirecon=ntrip->tcp->tirecon*5/4; - - discontcp(&ntrip->tcp->svr,ntrip->tcp->tirecon); - } - else if ((p=strstr((char *)ntrip->buff,NTRIP_RSP_HTTP))) { /* http response */ - char *q; - if ((q=strchr(p,'\r'))) *q='\0'; else ntrip->buff[128]='\0'; - strcpy(msg,p); - tracet(3,"rspntrip_s: %s nb=%d\n",msg,ntrip->nb); - ntrip->nb=0; - ntrip->buff[0]='\0'; - ntrip->state=0; - discontcp(&ntrip->tcp->svr,ntrip->tcp->tirecon); - } - else if (ntrip->nb>=NTRIP_MAXRSP) { /* buffer overflow */ - sprintf(msg,"response overflow"); - tracet(2,"rspntrip_s: response overflow nb=%d\n",ntrip->nb); - ntrip->nb=0; - ntrip->buff[0]='\0'; - ntrip->state=0; - discontcp(&ntrip->tcp->svr,ntrip->tcp->tirecon); - } - tracet(5,"rspntrip_c: exit state=%d nb=%d\n",ntrip->state,ntrip->nb); - return 0; +static int rspntrip_c(ntrip_t *ntrip, char *msg) { + tracet(3, "rspntrip_c: state=%d nb=%d\n", ntrip->state, ntrip->nb); + ntrip->buff[ntrip->nb] = '\0'; + tracet(5, "rspntrip_c: n=%d buff=\n%s\n", ntrip->nb, ntrip->buff); + + char *p; + if ((p = strstr((char *)ntrip->buff, NTRIP_RSP_OK_CLI))) { /* ok */ + p += strlen(NTRIP_RSP_OK_CLI); + ntrip->nb -= p - (char *)ntrip->buff; + /* Discard all buffer content before the OK. */ + memmove(ntrip->buff, p, ntrip->nb); + ntrip->state = 2; + sprintf(msg, "%s/%s", ntrip->tcp->svr.saddr, ntrip->mntpnt); + tracet(3, "rspntrip_c: response ok nb=%d\n", ntrip->nb); + ntrip->tcp->tirecon = ticonnect; + return 1; + } + if (strstr((char *)ntrip->buff, NTRIP_RSP_SRCTBL)) { /* source table */ + if (!*ntrip->mntpnt) { /* source table request */ + ntrip->state = 2; + sprintf(msg, "source table received"); + tracet(3, "rspntrip_c: receive source table nb=%d\n", ntrip->nb); + return 1; + } + sprintf(msg, "no mountp. reconnect..."); + tracet(2, "rspntrip_c: no mount point nb=%d\n", ntrip->nb); + ntrip->nb = 0; + ntrip->buff[0] = '\0'; + ntrip->state = 0; + /* increase subsequent disconnect time to avoid too many reconnect requests */ + if (ntrip->tcp->tirecon > 300000) ntrip->tcp->tirecon = ntrip->tcp->tirecon * 5 / 4; + + discontcp(&ntrip->tcp->svr, ntrip->tcp->tirecon); + } else if ((p = strstr((char *)ntrip->buff, NTRIP_RSP_HTTP))) { /* http response */ + char *q; + if ((q = strchr(p, '\r'))) + *q = '\0'; + else + ntrip->buff[128] = '\0'; + strcpy(msg, p); + tracet(3, "rspntrip_s: %s nb=%d\n", msg, ntrip->nb); + ntrip->nb = 0; + ntrip->buff[0] = '\0'; + ntrip->state = 0; + discontcp(&ntrip->tcp->svr, ntrip->tcp->tirecon); + } else if (ntrip->nb >= NTRIP_MAXRSP) { /* buffer overflow */ + sprintf(msg, "response overflow"); + tracet(2, "rspntrip_s: response overflow nb=%d\n", ntrip->nb); + ntrip->nb = 0; + ntrip->buff[0] = '\0'; + ntrip->state = 0; + discontcp(&ntrip->tcp->svr, ntrip->tcp->tirecon); + } + tracet(5, "rspntrip_c: exit state=%d nb=%d\n", ntrip->state, ntrip->nb); + return 0; } /* wait ntrip request/response -----------------------------------------------*/ -static int waitntrip(ntrip_t *ntrip, char *msg) -{ - int n; - char *p; - - tracet(4,"waitntrip: state=%d nb=%d\n",ntrip->state,ntrip->nb); - - if (ntrip->state<0) return 0; /* error */ - - if (ntrip->tcp->svr.state<2) ntrip->state=0; /* tcp disconnected */ - - if (ntrip->state==0) { /* send request */ - if (!(ntrip->type==0?reqntrip_s(ntrip,msg):reqntrip_c(ntrip,msg))) { - return 0; - } - tracet(3,"waitntrip: state=%d nb=%d\n",ntrip->state,ntrip->nb); - } - if (ntrip->state==1) { /* read response */ - p=(char *)ntrip->buff+ntrip->nb; - if ((n=readtcpcli(ntrip->tcp,(uint8_t *)p,NTRIP_MAXRSP-ntrip->nb-1,msg))==0) { - tracet(5,"waitntrip: readtcp n=%d\n",n); - return 0; - } - ntrip->nb+=n; ntrip->buff[ntrip->nb]='\0'; - - /* wait response */ - return ntrip->type==0?rspntrip_s(ntrip,msg):rspntrip_c(ntrip,msg); - } - return 1; +static int waitntrip(ntrip_t *ntrip, char *msg) { + int n; + char *p; + + tracet(4, "waitntrip: state=%d nb=%d\n", ntrip->state, ntrip->nb); + + if (ntrip->state < 0) return 0; /* error */ + + if (ntrip->tcp->svr.state < 2) ntrip->state = 0; /* tcp disconnected */ + + if (ntrip->state == 0) { /* send request */ + if (!(ntrip->type == 0 ? reqntrip_s(ntrip, msg) : reqntrip_c(ntrip, msg))) { + return 0; + } + tracet(3, "waitntrip: state=%d nb=%d\n", ntrip->state, ntrip->nb); + } + if (ntrip->state == 1) { /* read response */ + p = (char *)ntrip->buff + ntrip->nb; + if ((n = readtcpcli(ntrip->tcp, (uint8_t *)p, NTRIP_MAXRSP - ntrip->nb - 1, msg)) == 0) { + tracet(5, "waitntrip: readtcp n=%d\n", n); + return 0; + } + ntrip->nb += n; + ntrip->buff[ntrip->nb] = '\0'; + + /* wait response */ + return ntrip->type == 0 ? rspntrip_s(ntrip, msg) : rspntrip_c(ntrip, msg); + } + return 1; } /* open ntrip ----------------------------------------------------------------*/ -static ntrip_t *openntrip(const char *path, int type, char *msg) -{ - ntrip_t *ntrip; - int i; - char addr[256]="",port[256]="",tpath[MAXSTRPATH]; - - tracet(3,"openntrip: path=%s type=%d\n",path,type); - - if (!(ntrip=(ntrip_t *)malloc(sizeof(ntrip_t)))) return NULL; - - ntrip->state=0; - ntrip->type=type; /* 0:server,1:client */ - ntrip->nb=0; - ntrip->url[0]='\0'; - ntrip->mntpnt[0]=ntrip->user[0]=ntrip->passwd[0]=ntrip->str[0]='\0'; - for (i=0;ibuff[i]=0; - - /* decode tcp/ntrip path */ - decodetcppath(path,addr,port,ntrip->user,ntrip->passwd,ntrip->mntpnt, - ntrip->str); - - /* use default port if no port specified */ - if (!*port) { - sprintf(port,"%d",type?NTRIP_CLI_PORT:NTRIP_SVR_PORT); - } - sprintf(tpath,"%s:%s",addr,port); - - /* ntrip access via proxy server */ - if (*proxyaddr) { - sprintf(ntrip->url,"http://%.*s",MAXSTRPATH-8,tpath); - sprintf(tpath,"%.*s",MAXSTRPATH-1,proxyaddr); - } - /* open tcp client stream */ - if (!(ntrip->tcp=opentcpcli(tpath,msg))) { - tracet(2,"openntrip: opentcp error\n"); - free(ntrip); - return NULL; - } - return ntrip; +static ntrip_t *openntrip(const char *path, int type, char *msg) { + ntrip_t *ntrip; + int i; + char addr[256] = "", port[256] = "", tpath[MAXSTRPATH]; + + tracet(3, "openntrip: path=%s type=%d\n", path, type); + + if (!(ntrip = (ntrip_t *)malloc(sizeof(ntrip_t)))) return NULL; + + ntrip->state = 0; + ntrip->type = type; /* 0:server,1:client */ + ntrip->nb = 0; + ntrip->url[0] = '\0'; + ntrip->mntpnt[0] = ntrip->user[0] = ntrip->passwd[0] = ntrip->str[0] = '\0'; + for (i = 0; i < NTRIP_MAXRSP; i++) ntrip->buff[i] = 0; + + /* decode tcp/ntrip path */ + decodetcppath(path, addr, port, ntrip->user, ntrip->passwd, ntrip->mntpnt, ntrip->str); + + /* use default port if no port specified */ + if (!*port) { + sprintf(port, "%d", type ? NTRIP_CLI_PORT : NTRIP_SVR_PORT); + } + sprintf(tpath, "%s:%s", addr, port); + + /* ntrip access via proxy server */ + if (*proxyaddr) { + sprintf(ntrip->url, "http://%.*s", MAXSTRPATH - 8, tpath); + sprintf(tpath, "%.*s", MAXSTRPATH - 1, proxyaddr); + } + /* open tcp client stream */ + if (!(ntrip->tcp = opentcpcli(tpath, msg))) { + tracet(2, "openntrip: opentcp error\n"); + free(ntrip); + return NULL; + } + return ntrip; } /* close ntrip ---------------------------------------------------------------*/ -static void closentrip(ntrip_t *ntrip) -{ - tracet(3,"closentrip: state=%d\n",ntrip->state); - - closetcpcli(ntrip->tcp); - free(ntrip); +static void closentrip(ntrip_t *ntrip) { + tracet(3, "closentrip: state=%d\n", ntrip->state); + + closetcpcli(ntrip->tcp); + free(ntrip); } /* read ntrip ----------------------------------------------------------------*/ -static int readntrip(ntrip_t *ntrip, uint8_t *buff, int n, char *msg) -{ - tracet(4,"readntrip:\n"); - - if (!waitntrip(ntrip,msg)) return 0; - - if (ntrip->nb>0) { - /* Read from the response buffer first */ - if (ntrip->nb <= n) { - /* Empty the buffer. */ - int nb=ntrip->nb; - memcpy(buff,ntrip->buff,nb); - ntrip->nb=0; - return nb; - } - /* Partial use of the response buffer */ - memcpy(buff,ntrip->buff,n); - memmove(ntrip->buff,ntrip->buff+n,ntrip->nb-n); - ntrip->nb-=n; - return n; - } - return readtcpcli(ntrip->tcp,buff,n,msg); +static int readntrip(ntrip_t *ntrip, uint8_t *buff, int n, char *msg) { + tracet(4, "readntrip:\n"); + + if (!waitntrip(ntrip, msg)) return 0; + + if (ntrip->nb > 0) { + /* Read from the response buffer first */ + if (ntrip->nb <= n) { + /* Empty the buffer. */ + int nb = ntrip->nb; + memcpy(buff, ntrip->buff, nb); + ntrip->nb = 0; + return nb; + } + /* Partial use of the response buffer */ + memcpy(buff, ntrip->buff, n); + memmove(ntrip->buff, ntrip->buff + n, ntrip->nb - n); + ntrip->nb -= n; + return n; + } + return readtcpcli(ntrip->tcp, buff, n, msg); } /* write ntrip ---------------------------------------------------------------*/ -static int writentrip(ntrip_t *ntrip, uint8_t *buff, int n, char *msg) -{ - tracet(3,"writentrip: n=%d\n",n); - - if (!waitntrip(ntrip,msg)) return 0; - - return writetcpcli(ntrip->tcp,buff,n,msg); +static int writentrip(ntrip_t *ntrip, uint8_t *buff, int n, char *msg) { + tracet(3, "writentrip: n=%d\n", n); + + if (!waitntrip(ntrip, msg)) return 0; + + return writetcpcli(ntrip->tcp, buff, n, msg); } /* get state ntrip -----------------------------------------------------------*/ -static int statentrip(ntrip_t *ntrip) -{ - return !ntrip?0:(ntrip->state==0?ntrip->tcp->svr.state:ntrip->state); +static int statentrip(ntrip_t *ntrip) { + return !ntrip ? 0 : (ntrip->state == 0 ? ntrip->tcp->svr.state : ntrip->state); } /* get extended state ntrip --------------------------------------------------*/ -static int statexntrip(ntrip_t *ntrip, char *msg) -{ - char *p=msg; - int state=!ntrip?0:(ntrip->state==0?ntrip->tcp->svr.state:ntrip->state); - - p+=sprintf(p,"ntrip:\n"); - p+=sprintf(p," state = %d\n",state); - if (!state) return 0; - p+=sprintf(p," state = %d\n",state); - p+=sprintf(p," type = %d\n",ntrip->type); - p+=sprintf(p," nb = %d\n",ntrip->nb); - p+=sprintf(p," url = %s\n",ntrip->url); - p+=sprintf(p," mntpnt = %s\n",ntrip->mntpnt); - p+=sprintf(p," user = %s\n",ntrip->user); - p+=sprintf(p," passwd = %s\n",ntrip->passwd); - p+=sprintf(p," str = %s\n",ntrip->str); - p+=sprintf(p," svr:\n"); - statextcp(&ntrip->tcp->svr,p); - return state; +static int statexntrip(ntrip_t *ntrip, char *msg) { + char *p = msg; + int state = !ntrip ? 0 : (ntrip->state == 0 ? ntrip->tcp->svr.state : ntrip->state); + + p += sprintf(p, "ntrip:\n"); + p += sprintf(p, " state = %d\n", state); + if (!state) return 0; + p += sprintf(p, " state = %d\n", state); + p += sprintf(p, " type = %d\n", ntrip->type); + p += sprintf(p, " nb = %d\n", ntrip->nb); + p += sprintf(p, " url = %s\n", ntrip->url); + p += sprintf(p, " mntpnt = %s\n", ntrip->mntpnt); + p += sprintf(p, " user = %s\n", ntrip->user); + p += sprintf(p, " passwd = %s\n", ntrip->passwd); + p += sprintf(p, " str = %s\n", ntrip->str); + p += sprintf(p, " svr:\n"); + statextcp(&ntrip->tcp->svr, p); + return state; } /* open ntrip-caster ---------------------------------------------------------*/ -static ntripc_t *openntripc(const char *path, char *msg) -{ - ntripc_t *ntripc; - int i; - char port[256]="",tpath[MAXSTRPATH]; - - tracet(3,"openntripc: path=%s\n",path); - - if (!(ntripc=(ntripc_t *)malloc(sizeof(ntripc_t)))) return NULL; - - ntripc->state=0; - ntripc->mntpnt[0]=ntripc->user[0]=ntripc->passwd[0]=ntripc->srctbl[0]='\0'; - for (i=0;icon[i].state=0; - ntripc->con[i].nb=0; - memset(ntripc->con[i].buff,0,NTRIP_MAXRSP); - } - /* decode tcp/ntrip path */ - decodetcppath(path,NULL,port,ntripc->user,ntripc->passwd,ntripc->mntpnt, - ntripc->srctbl); - - if (!*ntripc->mntpnt) { - tracet(2,"openntripc: no mountpoint path=%s\n",path); - free(ntripc); - return NULL; - } - /* use default port if no port specified */ - if (!*port) { - sprintf(port,"%d",NTRIP_CLI_PORT); - } - sprintf(tpath,":%s",port); - - /* open tcp server stream */ - if (!(ntripc->tcp=opentcpsvr(tpath,msg))) { - tracet(2,"openntripc: opentcpsvr error port=%d\n",port); - free(ntripc); - return NULL; - } - return ntripc; +static ntripc_t *openntripc(const char *path, char *msg) { + ntripc_t *ntripc; + int i; + char port[256] = "", tpath[MAXSTRPATH]; + + tracet(3, "openntripc: path=%s\n", path); + + if (!(ntripc = (ntripc_t *)malloc(sizeof(ntripc_t)))) return NULL; + + ntripc->state = 0; + ntripc->mntpnt[0] = ntripc->user[0] = ntripc->passwd[0] = ntripc->srctbl[0] = '\0'; + for (i = 0; i < MAXCLI; i++) { + ntripc->con[i].state = 0; + ntripc->con[i].nb = 0; + memset(ntripc->con[i].buff, 0, NTRIP_MAXRSP); + } + /* decode tcp/ntrip path */ + decodetcppath(path, NULL, port, ntripc->user, ntripc->passwd, ntripc->mntpnt, ntripc->srctbl); + + if (!*ntripc->mntpnt) { + tracet(2, "openntripc: no mountpoint path=%s\n", path); + free(ntripc); + return NULL; + } + /* use default port if no port specified */ + if (!*port) { + sprintf(port, "%d", NTRIP_CLI_PORT); + } + sprintf(tpath, ":%s", port); + + /* open tcp server stream */ + if (!(ntripc->tcp = opentcpsvr(tpath, msg))) { + tracet(2, "openntripc: opentcpsvr error port=%d\n", port); + free(ntripc); + return NULL; + } + return ntripc; } /* close ntrip-caster --------------------------------------------------------*/ -static void closentripc(ntripc_t *ntripc) -{ - tracet(3,"closentripc: state=%d\n",ntripc->state); - - closetcpsvr(ntripc->tcp); - free(ntripc); +static void closentripc(ntripc_t *ntripc) { + tracet(3, "closentripc: state=%d\n", ntripc->state); + + closetcpsvr(ntripc->tcp); + free(ntripc); } /* disconnect ntrip-caster connection ----------------------------------------*/ -static void discon_ntripc(ntripc_t *ntripc, int i) -{ - tracet(3,"discon_ntripc: i=%d\n",i); - - discontcp(&ntripc->tcp->cli[i],ticonnect); - ntripc->con[i].nb=0; - ntripc->con[i].buff[0]='\0'; - ntripc->con[i].state=0; +static void discon_ntripc(ntripc_t *ntripc, int i) { + tracet(3, "discon_ntripc: i=%d\n", i); + + discontcp(&ntripc->tcp->cli[i], ticonnect); + ntripc->con[i].nb = 0; + ntripc->con[i].buff[0] = '\0'; + ntripc->con[i].state = 0; } /* send ntrip source table ---------------------------------------------------*/ -static void send_srctbl(ntripc_t *ntripc, socket_t sock) -{ - char srctbl[512+NTRIP_MAXSTR],buff[256],*p=buff; - - sprintf(srctbl,"STR;%s;%s\r\n%s\r\n",ntripc->mntpnt,ntripc->srctbl, - NTRIP_RSP_TBLEND); - p+=sprintf(p,"%s",NTRIP_RSP_SRCTBL); - p+=sprintf(p,"Server: %s %s %s\r\n","RTKLIB",VER_RTKLIB,PATCH_LEVEL); - char tstr[40]; - p+=sprintf(p,"Date: %s UTC\r\n",time2str(timeget(),tstr,0)); - p+=sprintf(p,"Connection: close\r\n"); - p+=sprintf(p,"Content-Type: text/plain\r\n"); - p+=sprintf(p,"Content-Length: %d\r\n\r\n",(int)strlen(srctbl)); - int err; - send_nb(sock,(uint8_t *)buff,(int)(p-buff),&err); - send_nb(sock,(uint8_t *)srctbl,(int)strlen(srctbl),&err); +static void send_srctbl(ntripc_t *ntripc, socket_t sock) { + char srctbl[512 + NTRIP_MAXSTR], buff[256], *p = buff; + + sprintf(srctbl, "STR;%s;%s\r\n%s\r\n", ntripc->mntpnt, ntripc->srctbl, NTRIP_RSP_TBLEND); + p += sprintf(p, "%s", NTRIP_RSP_SRCTBL); + p += sprintf(p, "Server: %s %s %s\r\n", "RTKLIB", VER_RTKLIB, PATCH_LEVEL); + char tstr[40]; + p += sprintf(p, "Date: %s UTC\r\n", time2str(timeget(), tstr, 0)); + p += sprintf(p, "Connection: close\r\n"); + p += sprintf(p, "Content-Type: text/plain\r\n"); + p += sprintf(p, "Content-Length: %d\r\n\r\n", (int)strlen(srctbl)); + int err; + send_nb(sock, (uint8_t *)buff, (int)(p - buff), &err); + send_nb(sock, (uint8_t *)srctbl, (int)strlen(srctbl), &err); } /* test ntrip client request -------------------------------------------------*/ -static void rsp_ntripc(ntripc_t *ntripc, int i) -{ - const char *rsp1=NTRIP_RSP_UNAUTH,*rsp2=NTRIP_RSP_OK_CLI; - ntripc_con_t *con=ntripc->con+i; - char url[256]="",mntpnt[256]="",proto[256]="",user[513],user_pwd[712],*p,*q; - - tracet(3,"rspntripc_c i=%d\n",i); - con->buff[con->nb]='\0'; - tracet(5,"rspntripc_c: n=%d,buff=\n%s\n",con->nb,con->buff); - - if (con->nb>=NTRIP_MAXRSP-1) { /* buffer overflow */ - tracet(2,"rsp_ntripc_c: request buffer overflow\n"); - discon_ntripc(ntripc,i); - return; - } - /* test GET and User-Agent */ - if (!(p=strstr((char *)con->buff,"GET"))||!(q=strstr(p,"\r\n"))|| - !(q=strstr(q,"User-Agent:"))||!strstr(q,"\r\n")) { - tracet(2,"rsp_ntripc_c: NTRIP request error\n"); - discon_ntripc(ntripc,i); - return; - } - /* test protocol */ - if (sscanf(p,"GET %255s %255s",url,proto)<2|| - (strcmp(proto,"HTTP/1.0")&&strcmp(proto,"HTTP/1.1"))) { - tracet(2,"rsp_ntripc_c: NTRIP request error proto=%s\n",proto); - discon_ntripc(ntripc,i); - return; - } - if ((p=strchr(url,'/'))) strcpy(mntpnt,p+1); - - /* test mountpoint */ - if (!*mntpnt||strcmp(mntpnt,ntripc->mntpnt)) { - tracet(2,"rsp_ntripc_c: no mountpoint %s\n",mntpnt); - - /* send source table */ - send_srctbl(ntripc,ntripc->tcp->cli[i].sock); - discon_ntripc(ntripc,i); - return; - } - /* test authentication */ - if (*ntripc->passwd) { - sprintf(user,"%s:%s",ntripc->user,ntripc->passwd); - q=user_pwd; - q+=sprintf(q,"Authorization: Basic "); - encbase64(q,(uint8_t *)user,strlen(user)); - strcat(user_pwd,"\r\n"); - if (!(p=strstr((char *)con->buff,"Authorization:"))|| - strncmp(p,user_pwd,strlen(user_pwd))) { - tracet(2,"rsp_ntripc_c: authroziation error\n"); - int err; - send_nb(ntripc->tcp->cli[i].sock,(uint8_t *)rsp1,strlen(rsp1),&err); - discon_ntripc(ntripc,i); - return; - } - } - /* send OK response */ - int err; - send_nb(ntripc->tcp->cli[i].sock,(uint8_t *)rsp2,strlen(rsp2),&err); - - con->state=1; - strcpy(con->mntpnt,mntpnt); +static void rsp_ntripc(ntripc_t *ntripc, int i) { + const char *rsp1 = NTRIP_RSP_UNAUTH, *rsp2 = NTRIP_RSP_OK_CLI; + ntripc_con_t *con = ntripc->con + i; + char url[256] = "", mntpnt[256] = "", proto[256] = "", user[513], user_pwd[712], *p, *q; + + tracet(3, "rspntripc_c i=%d\n", i); + con->buff[con->nb] = '\0'; + tracet(5, "rspntripc_c: n=%d,buff=\n%s\n", con->nb, con->buff); + + if (con->nb >= NTRIP_MAXRSP - 1) { /* buffer overflow */ + tracet(2, "rsp_ntripc_c: request buffer overflow\n"); + discon_ntripc(ntripc, i); + return; + } + /* test GET and User-Agent */ + if (!(p = strstr((char *)con->buff, "GET")) || !(q = strstr(p, "\r\n")) || + !(q = strstr(q, "User-Agent:")) || !strstr(q, "\r\n")) { + tracet(2, "rsp_ntripc_c: NTRIP request error\n"); + discon_ntripc(ntripc, i); + return; + } + /* test protocol */ + if (sscanf(p, "GET %255s %255s", url, proto) < 2 || + (strcmp(proto, "HTTP/1.0") && strcmp(proto, "HTTP/1.1"))) { + tracet(2, "rsp_ntripc_c: NTRIP request error proto=%s\n", proto); + discon_ntripc(ntripc, i); + return; + } + if ((p = strchr(url, '/'))) strcpy(mntpnt, p + 1); + + /* test mountpoint */ + if (!*mntpnt || strcmp(mntpnt, ntripc->mntpnt)) { + tracet(2, "rsp_ntripc_c: no mountpoint %s\n", mntpnt); + + /* send source table */ + send_srctbl(ntripc, ntripc->tcp->cli[i].sock); + discon_ntripc(ntripc, i); + return; + } + /* test authentication */ + if (*ntripc->passwd) { + sprintf(user, "%s:%s", ntripc->user, ntripc->passwd); + q = user_pwd; + q += sprintf(q, "Authorization: Basic "); + encbase64(q, (uint8_t *)user, strlen(user)); + strcat(user_pwd, "\r\n"); + if (!(p = strstr((char *)con->buff, "Authorization:")) || + strncmp(p, user_pwd, strlen(user_pwd))) { + tracet(2, "rsp_ntripc_c: authroziation error\n"); + int err; + send_nb(ntripc->tcp->cli[i].sock, (uint8_t *)rsp1, strlen(rsp1), &err); + discon_ntripc(ntripc, i); + return; + } + } + /* send OK response */ + int err; + send_nb(ntripc->tcp->cli[i].sock, (uint8_t *)rsp2, strlen(rsp2), &err); + + con->state = 1; + strcpy(con->mntpnt, mntpnt); } /* handle ntrip client connect request ---------------------------------------*/ -static void wait_ntripc(ntripc_t *ntripc, char *msg) -{ - uint8_t *buff; - int i,n,nmax,err; - - tracet(4,"wait_ntripc\n"); - - ntripc->state=ntripc->tcp->svr.state; - - if (!waittcpsvr(ntripc->tcp,msg)) return; - - for (i=0;itcp->cli[i].state!=2||ntripc->con[i].state) continue; - - /* receive ntrip client request */ - buff=ntripc->con[i].buff+ntripc->con[i].nb; - nmax=NTRIP_MAXRSP-ntripc->con[i].nb-1; - - if ((n=recv_nb(ntripc->tcp->cli[i].sock,buff,nmax,&err))==-1) { - if (err) { - tracet(2,"wait_ntripc: recv error sock=%d err=%d\n", - ntripc->tcp->cli[i].sock,err); - } - discon_ntripc(ntripc,i); - continue; - } - if (n<=0) continue; - - /* test ntrip client request */ - ntripc->con[i].nb+=n; - rsp_ntripc(ntripc,i); - } +static void wait_ntripc(ntripc_t *ntripc, char *msg) { + uint8_t *buff; + int i, n, nmax, err; + + tracet(4, "wait_ntripc\n"); + + ntripc->state = ntripc->tcp->svr.state; + + if (!waittcpsvr(ntripc->tcp, msg)) return; + + for (i = 0; i < MAXCLI; i++) { + if (ntripc->tcp->cli[i].state != 2 || ntripc->con[i].state) continue; + + /* receive ntrip client request */ + buff = ntripc->con[i].buff + ntripc->con[i].nb; + nmax = NTRIP_MAXRSP - ntripc->con[i].nb - 1; + + if ((n = recv_nb(ntripc->tcp->cli[i].sock, buff, nmax, &err)) == -1) { + if (err) { + tracet(2, "wait_ntripc: recv error sock=%d err=%d\n", ntripc->tcp->cli[i].sock, err); + } + discon_ntripc(ntripc, i); + continue; + } + if (n <= 0) continue; + + /* test ntrip client request */ + ntripc->con[i].nb += n; + rsp_ntripc(ntripc, i); + } } /* read ntrip-caster ---------------------------------------------------------*/ -static int readntripc(ntripc_t *ntripc, uint8_t *buff, int n, char *msg) -{ - int i,nr,err; - - tracet(4,"readntripc:\n"); - - wait_ntripc(ntripc,msg); - - for (i=0;icon[i].state) continue; - - nr=recv_nb(ntripc->tcp->cli[i].sock,buff,n,&err); - - if (nr<0) { - if (err) { - tracet(2,"readntripc: recv error i=%d sock=%d err=%d\n",i, - ntripc->tcp->cli[i].sock,err); - } - discon_ntripc(ntripc,i); - } - else if (nr>0) { - ntripc->tcp->cli[i].tact=tickget(); - return nr; - } +static int readntripc(ntripc_t *ntripc, uint8_t *buff, int n, char *msg) { + int i, nr, err; + + tracet(4, "readntripc:\n"); + + wait_ntripc(ntripc, msg); + + for (i = 0; i < MAXCLI; i++) { + if (!ntripc->con[i].state) continue; + + nr = recv_nb(ntripc->tcp->cli[i].sock, buff, n, &err); + + if (nr < 0) { + if (err) { + tracet(2, "readntripc: recv error i=%d sock=%d err=%d\n", i, ntripc->tcp->cli[i].sock, err); + } + discon_ntripc(ntripc, i); + } else if (nr > 0) { + ntripc->tcp->cli[i].tact = tickget(); + return nr; } - return 0; + } + return 0; } /* write ntrip-caster --------------------------------------------------------*/ -static int writentripc(ntripc_t *ntripc, uint8_t *buff, int n, char *msg) -{ - int i,ns=0,err; - - tracet(4,"writentripc: n=%d\n",n); - - wait_ntripc(ntripc,msg); - - for (i=0;icon[i].state) continue; - - ns=send_nb(ntripc->tcp->cli[i].sock,buff,n,&err); - - if (nstcp->cli[i].sock,err); - } - discon_ntripc(ntripc,i); - } - else { - ntripc->tcp->cli[i].tact=tickget(); - } - } - return ns; +static int writentripc(ntripc_t *ntripc, uint8_t *buff, int n, char *msg) { + int i, ns = 0, err; + + tracet(4, "writentripc: n=%d\n", n); + + wait_ntripc(ntripc, msg); + + for (i = 0; i < MAXCLI; i++) { + if (!ntripc->con[i].state) continue; + + ns = send_nb(ntripc->tcp->cli[i].sock, buff, n, &err); + + if (ns < n) { + if (err) { + tracet(2, "writentripc: send error i=%d sock=%d err=%d\n", i, ntripc->tcp->cli[i].sock, + err); + } + discon_ntripc(ntripc, i); + } else { + ntripc->tcp->cli[i].tact = tickget(); + } + } + return ns; } /* get state ntrip-caster ----------------------------------------------------*/ -static int statentripc(ntripc_t *ntripc) -{ - return !ntripc?0:ntripc->state; -} +static int statentripc(ntripc_t *ntripc) { return !ntripc ? 0 : ntripc->state; } /* get extended state ntrip-caster -------------------------------------------*/ -static int statexntripc(ntripc_t *ntripc, char *msg) -{ - char *p=msg; - int i,state=!ntripc?0:ntripc->state; - - p+=sprintf(p,"ntripc:\n"); - p+=sprintf(p," state = %d\n",ntripc->state); - if (!state) return 0; - p+=sprintf(p," type = %d\n",ntripc->type); - p+=sprintf(p," mntpnt = %s\n",ntripc->mntpnt); - p+=sprintf(p," user = %s\n",ntripc->user); - p+=sprintf(p," passwd = %s\n",ntripc->passwd); - p+=sprintf(p," srctbl = %s\n",ntripc->srctbl); - p+=sprintf(p," svr:\n"); - p+=statextcp(&ntripc->tcp->svr,p); - for (i=0;itcp->cli[i].state) continue; - p+=sprintf(p," cli#%d:\n",i); - p+=statextcp(ntripc->tcp->cli+i,p); - p+=sprintf(p," mntpnt= %s\n",ntripc->con[i].mntpnt); - p+=sprintf(p," nb = %d\n",ntripc->con[i].nb); - } - return state; +static int statexntripc(ntripc_t *ntripc, char *msg) { + char *p = msg; + int i, state = !ntripc ? 0 : ntripc->state; + + p += sprintf(p, "ntripc:\n"); + p += sprintf(p, " state = %d\n", ntripc->state); + if (!state) return 0; + p += sprintf(p, " type = %d\n", ntripc->type); + p += sprintf(p, " mntpnt = %s\n", ntripc->mntpnt); + p += sprintf(p, " user = %s\n", ntripc->user); + p += sprintf(p, " passwd = %s\n", ntripc->passwd); + p += sprintf(p, " srctbl = %s\n", ntripc->srctbl); + p += sprintf(p, " svr:\n"); + p += statextcp(&ntripc->tcp->svr, p); + for (i = 0; i < MAXCLI; i++) { + if (!ntripc->tcp->cli[i].state) continue; + p += sprintf(p, " cli#%d:\n", i); + p += statextcp(ntripc->tcp->cli + i, p); + p += sprintf(p, " mntpnt= %s\n", ntripc->con[i].mntpnt); + p += sprintf(p, " nb = %d\n", ntripc->con[i].nb); + } + return state; } /* generate udp socket -------------------------------------------------------*/ -static udp_t *genudp(int type, int port, const char *saddr, char *msg) -{ - udp_t *udp; - struct hostent *hp; - int bs=buffsize,opt=1; - - tracet(3,"genudp: type=%d\n",type); - - if (!(udp=(udp_t *)malloc(sizeof(udp_t)))) return NULL; - udp->state=2; - udp->type=type; - udp->port=port; - strcpy(udp->saddr,saddr); - - if ((udp->sock=socket(AF_INET,SOCK_DGRAM,0))==(socket_t)-1) { - free(udp); - sprintf(msg,"socket error (%d)",errsock()); - return NULL; - } - if (setsockopt(udp->sock,SOL_SOCKET,SO_RCVBUF,(const char *)&bs,sizeof(bs))==-1|| - setsockopt(udp->sock,SOL_SOCKET,SO_SNDBUF,(const char *)&bs,sizeof(bs))==-1) { - tracet(2,"genudp: setsockopt error sock=%d err=%d bs=%d\n",udp->sock,errsock(),bs); - sprintf(msg,"sockopt error: bufsiz"); - } - memset(&udp->addr,0,sizeof(udp->addr)); - udp->addr.sin_family=AF_INET; - udp->addr.sin_port=htons(port); - - if (!udp->type) { /* udp server */ - udp->addr.sin_addr.s_addr=htonl(INADDR_ANY); +static udp_t *genudp(int type, int port, const char *saddr, char *msg) { + udp_t *udp; + struct hostent *hp; + int bs = buffsize, opt = 1; + + tracet(3, "genudp: type=%d\n", type); + + if (!(udp = (udp_t *)malloc(sizeof(udp_t)))) return NULL; + udp->state = 2; + udp->type = type; + udp->port = port; + strcpy(udp->saddr, saddr); + + if ((udp->sock = socket(AF_INET, SOCK_DGRAM, 0)) == (socket_t)-1) { + free(udp); + sprintf(msg, "socket error (%d)", errsock()); + return NULL; + } + if (setsockopt(udp->sock, SOL_SOCKET, SO_RCVBUF, (const char *)&bs, sizeof(bs)) == -1 || + setsockopt(udp->sock, SOL_SOCKET, SO_SNDBUF, (const char *)&bs, sizeof(bs)) == -1) { + tracet(2, "genudp: setsockopt error sock=%d err=%d bs=%d\n", udp->sock, errsock(), bs); + sprintf(msg, "sockopt error: bufsiz"); + } + memset(&udp->addr, 0, sizeof(udp->addr)); + udp->addr.sin_family = AF_INET; + udp->addr.sin_port = htons(port); + + if (!udp->type) { /* udp server */ + udp->addr.sin_addr.s_addr = htonl(INADDR_ANY); #ifdef SVR_REUSEADDR - setsockopt(udp->sock,SOL_SOCKET,SO_REUSEADDR,(const char *)&opt, sizeof(opt)); + setsockopt(udp->sock, SOL_SOCKET, SO_REUSEADDR, (const char *)&opt, sizeof(opt)); #endif - if (bind(udp->sock,(struct sockaddr *)&udp->addr,sizeof(udp->addr))==-1) { - tracet(2,"genudp: bind error sock=%d port=%d err=%d\n",udp->sock,port,errsock()); - sprintf(msg,"bind error (%d): %d",errsock(),port); - closesocket(udp->sock); - free(udp); - return NULL; - } - } - else { /* udp client */ - if (!strcmp(saddr,"255.255.255.255")&& - setsockopt(udp->sock,SOL_SOCKET,SO_BROADCAST,(const char *)&opt, - sizeof(opt))==-1) { - tracet(2,"genudp: setsockopt error sock=%d err=%d\n",udp->sock,errsock()); - sprintf(msg,"sockopt error: broadcast"); - } - if (!(hp=gethostbyname(saddr))) { - sprintf(msg,"address error (%s)",saddr); - closesocket(udp->sock); - free(udp); - return NULL; - } - memcpy(&udp->addr.sin_addr,hp->h_addr,hp->h_length); - } - return udp; + if (bind(udp->sock, (struct sockaddr *)&udp->addr, sizeof(udp->addr)) == -1) { + tracet(2, "genudp: bind error sock=%d port=%d err=%d\n", udp->sock, port, errsock()); + sprintf(msg, "bind error (%d): %d", errsock(), port); + closesocket(udp->sock); + free(udp); + return NULL; + } + } else { /* udp client */ + if (!strcmp(saddr, "255.255.255.255") && + setsockopt(udp->sock, SOL_SOCKET, SO_BROADCAST, (const char *)&opt, sizeof(opt)) == -1) { + tracet(2, "genudp: setsockopt error sock=%d err=%d\n", udp->sock, errsock()); + sprintf(msg, "sockopt error: broadcast"); + } + if (!(hp = gethostbyname(saddr))) { + sprintf(msg, "address error (%s)", saddr); + closesocket(udp->sock); + free(udp); + return NULL; + } + memcpy(&udp->addr.sin_addr, hp->h_addr, hp->h_length); + } + return udp; } /* open udp server -----------------------------------------------------------*/ -static udp_t *openudpsvr(const char *path, char *msg) -{ - char sport[256]=""; - int port; - - tracet(3,"openudpsvr: path=%s\n",path); - - decodetcppath(path,NULL,sport,NULL,NULL,NULL,NULL); - - if (sscanf(sport,"%d",&port)<1) { - sprintf(msg,"port error: %s",sport); - tracet(2,"openudpsvr: port error port=%s\n",sport); - return NULL; - } - return genudp(0,port,"",msg); +static udp_t *openudpsvr(const char *path, char *msg) { + char sport[256] = ""; + int port; + + tracet(3, "openudpsvr: path=%s\n", path); + + decodetcppath(path, NULL, sport, NULL, NULL, NULL, NULL); + + if (sscanf(sport, "%d", &port) < 1) { + sprintf(msg, "port error: %s", sport); + tracet(2, "openudpsvr: port error port=%s\n", sport); + return NULL; + } + return genudp(0, port, "", msg); } /* close udp server ----------------------------------------------------------*/ -static void closeudpsvr(udp_t *udpsvr) -{ - tracet(3,"closeudpsvr: sock=%d\n",udpsvr->sock); - - closesocket(udpsvr->sock); - free(udpsvr); +static void closeudpsvr(udp_t *udpsvr) { + tracet(3, "closeudpsvr: sock=%d\n", udpsvr->sock); + + closesocket(udpsvr->sock); + free(udpsvr); } /* read udp server -----------------------------------------------------------*/ -static int readudpsvr(udp_t *udpsvr, uint8_t *buff, int n, char *msg) -{ - (void)msg; - struct timeval tv={0}; - fd_set rs; - int ret,nr; - - tracet(4,"readudpsvr: sock=%d n=%d\n",udpsvr->sock,n); - - FD_ZERO(&rs); FD_SET(udpsvr->sock,&rs); - ret=select(udpsvr->sock+1,&rs,NULL,NULL,&tv); - if (ret<=0) return ret; - nr=recvfrom(udpsvr->sock,(char *)buff,n,0,NULL,NULL); - return nr<=0?-1:nr; +static int readudpsvr(udp_t *udpsvr, uint8_t *buff, int n, char *msg) { + (void)msg; + struct timeval tv = {0}; + fd_set rs; + int ret, nr; + + tracet(4, "readudpsvr: sock=%d n=%d\n", udpsvr->sock, n); + + FD_ZERO(&rs); + FD_SET(udpsvr->sock, &rs); + ret = select(udpsvr->sock + 1, &rs, NULL, NULL, &tv); + if (ret <= 0) return ret; + nr = recvfrom(udpsvr->sock, (char *)buff, n, 0, NULL, NULL); + return nr <= 0 ? -1 : nr; } /* get state udp server ------------------------------------------------------*/ -static int stateudpsvr(udp_t *udpsvr) -{ - return udpsvr?udpsvr->state:0; -} +static int stateudpsvr(udp_t *udpsvr) { return udpsvr ? udpsvr->state : 0; } /* get extended state udp server ---------------------------------------------*/ -static int statexudpsvr(udp_t *udpsvr, char *msg) -{ - char *p=msg; - int state=udpsvr?udpsvr->state:0; - - p+=sprintf(p,"udpsvr:\n"); - p+=sprintf(p," state = %d\n",state); - if (!state) return 0; - p+=sprintf(p," type = %d\n",udpsvr->type); - p+=sprintf(p," sock = %d\n",(int)udpsvr->sock); - sprintf(p," port = %d\n",udpsvr->port); - return state; +static int statexudpsvr(udp_t *udpsvr, char *msg) { + char *p = msg; + int state = udpsvr ? udpsvr->state : 0; + + p += sprintf(p, "udpsvr:\n"); + p += sprintf(p, " state = %d\n", state); + if (!state) return 0; + p += sprintf(p, " type = %d\n", udpsvr->type); + p += sprintf(p, " sock = %d\n", (int)udpsvr->sock); + sprintf(p, " port = %d\n", udpsvr->port); + return state; } /* open udp client -----------------------------------------------------------*/ -static udp_t *openudpcli(const char *path, char *msg) -{ - char sport[256]="",saddr[256]=""; - int port; - - tracet(3,"openudpsvr: path=%s\n",path); - - decodetcppath(path,saddr,sport,NULL,NULL,NULL,NULL); - - if (sscanf(sport,"%d",&port)<1) { - sprintf(msg,"port error: %s",sport); - tracet(2,"openudpcli: port error port=%s\n",sport); - return NULL; - } - return genudp(1,port,saddr,msg); +static udp_t *openudpcli(const char *path, char *msg) { + char sport[256] = "", saddr[256] = ""; + int port; + + tracet(3, "openudpsvr: path=%s\n", path); + + decodetcppath(path, saddr, sport, NULL, NULL, NULL, NULL); + + if (sscanf(sport, "%d", &port) < 1) { + sprintf(msg, "port error: %s", sport); + tracet(2, "openudpcli: port error port=%s\n", sport); + return NULL; + } + return genudp(1, port, saddr, msg); } /* close udp client ----------------------------------------------------------*/ -static void closeudpcli(udp_t *udpcli) -{ - tracet(3,"closeudpcli: sock=%d\n",udpcli->sock); - - closesocket(udpcli->sock); - free(udpcli); +static void closeudpcli(udp_t *udpcli) { + tracet(3, "closeudpcli: sock=%d\n", udpcli->sock); + + closesocket(udpcli->sock); + free(udpcli); } /* write udp client -----------------------------------------------------------*/ -static int writeudpcli(udp_t *udpcli, uint8_t *buff, int n, char *msg) -{ - (void)msg; - tracet(4,"writeudpcli: sock=%d n=%d\n",udpcli->sock,n); - - return (int)sendto(udpcli->sock,(char *)buff,n,0, - (struct sockaddr *)&udpcli->addr,sizeof(udpcli->addr)); +static int writeudpcli(udp_t *udpcli, uint8_t *buff, int n, char *msg) { + (void)msg; + tracet(4, "writeudpcli: sock=%d n=%d\n", udpcli->sock, n); + + return (int)sendto(udpcli->sock, (char *)buff, n, 0, (struct sockaddr *)&udpcli->addr, + sizeof(udpcli->addr)); } /* get state udp client ------------------------------------------------------*/ -static int stateudpcli(udp_t *udpcli) -{ - return udpcli?udpcli->state:0; -} +static int stateudpcli(udp_t *udpcli) { return udpcli ? udpcli->state : 0; } /* get extended state udp client ---------------------------------------------*/ -static int statexudpcli(udp_t *udpcli, char *msg) -{ - char *p=msg; - int state=udpcli?udpcli->state:0; - - p+=sprintf(p,"udpsvr:\n"); - p+=sprintf(p," state = %d\n",state); - if (!state) return 0; - p+=sprintf(p," type = %d\n",udpcli->type); - p+=sprintf(p," sock = %d\n",(int)udpcli->sock); - p+=sprintf(p," addr = %s\n",udpcli->saddr); - sprintf(p," port = %d\n",udpcli->port); - return state; +static int statexudpcli(udp_t *udpcli, char *msg) { + char *p = msg; + int state = udpcli ? udpcli->state : 0; + + p += sprintf(p, "udpsvr:\n"); + p += sprintf(p, " state = %d\n", state); + if (!state) return 0; + p += sprintf(p, " type = %d\n", udpcli->type); + p += sprintf(p, " sock = %d\n", (int)udpcli->sock); + p += sprintf(p, " addr = %s\n", udpcli->saddr); + sprintf(p, " port = %d\n", udpcli->port); + return state; } /* decode ftp path -----------------------------------------------------------*/ -static void decodeftppath(const char *path, char *addr, char *file, char *user, - char *passwd, int *topts) -{ - char buff[MAXSTRPATH],*p,*q; - - tracet(4,"decodeftpath: path=%s\n",path); - - if (user) *user='\0'; - if (passwd) *passwd='\0'; - if (topts) { - topts[0]=0; /* time offset in path (s) */ - topts[1]=3600; /* download interval (s) */ - topts[2]=0; /* download time offset (s) */ - topts[3]=0; /* retry interval (s) (0: no retry) */ - } - strcpy(buff,path); - - if ((p=strchr(buff,'/'))) { - if ((q=strstr(p+1,"::"))) { - *q='\0'; - if (topts) sscanf(q+2,"T=%d,%d,%d,%d",topts,topts+1,topts+2,topts+3); - } - strcpy(file,p+1); - *p='\0'; - } - else file[0]='\0'; - - if ((p=strrchr(buff,'@'))) { - *p++='\0'; - if ((q=strchr(buff,':'))) { - *q='\0'; if (passwd) strcpy(passwd,q+1); - } - if (user) strcpy(user,buff); - } - else p=buff; - - strcpy(addr,p); +static void decodeftppath(const char *path, char *addr, char *file, char *user, char *passwd, + int *topts) { + char buff[MAXSTRPATH], *p, *q; + + tracet(4, "decodeftpath: path=%s\n", path); + + if (user) *user = '\0'; + if (passwd) *passwd = '\0'; + if (topts) { + topts[0] = 0; /* time offset in path (s) */ + topts[1] = 3600; /* download interval (s) */ + topts[2] = 0; /* download time offset (s) */ + topts[3] = 0; /* retry interval (s) (0: no retry) */ + } + strcpy(buff, path); + + if ((p = strchr(buff, '/'))) { + if ((q = strstr(p + 1, "::"))) { + *q = '\0'; + if (topts) sscanf(q + 2, "T=%d,%d,%d,%d", topts, topts + 1, topts + 2, topts + 3); + } + strcpy(file, p + 1); + *p = '\0'; + } else + file[0] = '\0'; + + if ((p = strrchr(buff, '@'))) { + *p++ = '\0'; + if ((q = strchr(buff, ':'))) { + *q = '\0'; + if (passwd) strcpy(passwd, q + 1); + } + if (user) strcpy(user, buff); + } else + p = buff; + + strcpy(addr, p); } /* next download time --------------------------------------------------------*/ -static gtime_t nextdltime(const int *topts, int stat) -{ - gtime_t time; - double tow; - int week,tint; - - tracet(3,"nextdltime: topts=%d %d %d %d stat=%d\n",topts[0],topts[1], - topts[2],topts[3],stat); - - /* current time (gpst) */ - time=utc2gpst(timeget()); - tow=time2gpst(time,&week); - - /* next retry time */ - if (stat==0&&topts[3]>0) { - tow=(floor((tow-topts[2])/topts[3])+1.0)*topts[3]+topts[2]; - return gpst2time(week,tow); - } - /* next interval time */ - tint=topts[1]<=0?3600:topts[1]; - tow=(floor((tow-topts[2])/tint)+1.0)*tint+topts[2]; - time=gpst2time(week,tow); - - return time; +static gtime_t nextdltime(const int *topts, int stat) { + gtime_t time; + double tow; + int week, tint; + + tracet(3, "nextdltime: topts=%d %d %d %d stat=%d\n", topts[0], topts[1], topts[2], topts[3], + stat); + + /* current time (gpst) */ + time = utc2gpst(timeget()); + tow = time2gpst(time, &week); + + /* next retry time */ + if (stat == 0 && topts[3] > 0) { + tow = (floor((tow - topts[2]) / topts[3]) + 1.0) * topts[3] + topts[2]; + return gpst2time(week, tow); + } + /* next interval time */ + tint = topts[1] <= 0 ? 3600 : topts[1]; + tow = (floor((tow - topts[2]) / tint) + 1.0) * tint + topts[2]; + time = gpst2time(week, tow); + + return time; } /* ftp thread ----------------------------------------------------------------*/ #ifdef WIN32 @@ -2376,917 +2276,1008 @@ static DWORD WINAPI ftpthread(void *arg) static void *ftpthread(void *arg) #endif { - ftp_t *ftp=(ftp_t *)arg; - FILE *fp; - gtime_t time; - char remote[1024],local[1024],tmpfile[1024],errfile[1024],*p; - char cmd[5120],env[1024]="",opt[1024],*proxyopt="",*proto; - int ret; - - tracet(3,"ftpthread:\n"); - - if (!*localdir) { - tracet(2,"no local directory\n"); - ftp->error=11; - ftp->state=3; - return 0; - } - /* replace keyword in file path and local path */ - time=timeadd(utc2gpst(timeget()),ftp->topts[0]); - reppath(ftp->file,remote,time,"",""); - - if ((p=strrchr(remote,'/'))) p++; else p=remote; - sprintf(local,"%.768s%c%.254s",localdir,RTKLIB_FILEPATHSEP,p); - sprintf(errfile,"%.1019s.err",local); - - /* if local file exist, skip download */ - strcpy(tmpfile,local); - if ((p=strrchr(tmpfile,'.'))&& - (!strcmp(p,".z")||!strcmp(p,".gz")||!strcmp(p,".zip")|| - !strcmp(p,".Z")||!strcmp(p,".GZ")||!strcmp(p,".ZIP"))) { - *p='\0'; - } - if ((fp=fopen(tmpfile,"rb"))) { - fclose(fp); - sprintf(ftp->local,"%.1023s",tmpfile); - tracet(3,"ftpthread: file exists %s\n",ftp->local); - ftp->state=2; - return 0; - } - /* proxy settings for wget (ref [2]) */ - if (*proxyaddr) { - proto=ftp->proto?"http":"ftp"; - sprintf(env,"set %.4s_proxy=http://%.998s & ",proto,proxyaddr); - proxyopt="--proxy=on "; - } - /* download command (ref [2]) */ - if (ftp->proto==0) { /* ftp */ - sprintf(opt,"--ftp-user=%.32s --ftp-password=%.32s --glob=off " - "--passive-ftp %.32s -t 1 -T %d -O \"%.768s\"", - ftp->user,ftp->passwd,proxyopt,FTP_TIMEOUT,local); - sprintf(cmd,"%s%s %s \"ftp://%s/%s\" 2> \"%.768s\"\n",env,FTP_CMD,opt, - ftp->addr,remote,errfile); - } - else { /* http */ - sprintf(opt,"%.32s -t 1 -T %d -O \"%.768s\"",proxyopt,FTP_TIMEOUT, - local); - sprintf(cmd,"%s%s %s \"http://%s/%s\" 2> \"%.768s\"\n",env,FTP_CMD, - opt,ftp->addr,remote,errfile); - } - /* execute download command */ - if ((ret=execcmd(cmd))) { - remove(local); - tracet(2,"execcmd error: cmd=%s ret=%d\n",cmd,ret); - ftp->error=ret; - ftp->state=3; - return 0; - } - remove(errfile); - - /* uncompress downloaded file */ - if ((p=strrchr(local,'.'))&& - (!strcmp(p,".z")||!strcmp(p,".gz")||!strcmp(p,".zip")|| - !strcmp(p,".Z")||!strcmp(p,".GZ")||!strcmp(p,".ZIP"))) { - - if (rtk_uncompress(local,tmpfile)) { - remove(local); - strcpy(local,tmpfile); - } - else { - tracet(2,"file uncompact error: %s\n",local); - ftp->error=12; - ftp->state=3; - return 0; - } - } - strcpy(ftp->local,local); - ftp->state=2; /* ftp completed */ - - tracet(3,"ftpthread: complete cmd=%s\n",cmd); + ftp_t *ftp = (ftp_t *)arg; + FILE *fp; + gtime_t time; + char remote[1024], local[1024], tmpfile[1024], errfile[1024], *p; + char cmd[5120], env[1024] = "", opt[1024], *proxyopt = "", *proto; + int ret; + + tracet(3, "ftpthread:\n"); + + if (!*localdir) { + tracet(2, "no local directory\n"); + ftp->error = 11; + ftp->state = 3; return 0; + } + /* replace keyword in file path and local path */ + time = timeadd(utc2gpst(timeget()), ftp->topts[0]); + reppath(ftp->file, remote, time, "", ""); + + if ((p = strrchr(remote, '/'))) + p++; + else + p = remote; + sprintf(local, "%.768s%c%.254s", localdir, RTKLIB_FILEPATHSEP, p); + sprintf(errfile, "%.1019s.err", local); + + /* if local file exist, skip download */ + strcpy(tmpfile, local); + if ((p = strrchr(tmpfile, '.')) && + (!strcmp(p, ".z") || !strcmp(p, ".gz") || !strcmp(p, ".zip") || !strcmp(p, ".Z") || + !strcmp(p, ".GZ") || !strcmp(p, ".ZIP"))) { + *p = '\0'; + } + if ((fp = fopen(tmpfile, "rb"))) { + fclose(fp); + sprintf(ftp->local, "%.1023s", tmpfile); + tracet(3, "ftpthread: file exists %s\n", ftp->local); + ftp->state = 2; + return 0; + } + /* proxy settings for wget (ref [2]) */ + if (*proxyaddr) { + proto = ftp->proto ? "http" : "ftp"; + sprintf(env, "set %.4s_proxy=http://%.998s & ", proto, proxyaddr); + proxyopt = "--proxy=on "; + } + /* download command (ref [2]) */ + if (ftp->proto == 0) { /* ftp */ + sprintf(opt, + "--ftp-user=%.32s --ftp-password=%.32s --glob=off " + "--passive-ftp %.32s -t 1 -T %d -O \"%.768s\"", + ftp->user, ftp->passwd, proxyopt, FTP_TIMEOUT, local); + sprintf(cmd, "%s%s %s \"ftp://%s/%s\" 2> \"%.768s\"\n", env, FTP_CMD, opt, ftp->addr, remote, + errfile); + } else { /* http */ + sprintf(opt, "%.32s -t 1 -T %d -O \"%.768s\"", proxyopt, FTP_TIMEOUT, local); + sprintf(cmd, "%s%s %s \"http://%s/%s\" 2> \"%.768s\"\n", env, FTP_CMD, opt, ftp->addr, remote, + errfile); + } + /* execute download command */ + if ((ret = execcmd(cmd))) { + remove(local); + tracet(2, "execcmd error: cmd=%s ret=%d\n", cmd, ret); + ftp->error = ret; + ftp->state = 3; + return 0; + } + remove(errfile); + + /* uncompress downloaded file */ + if ((p = strrchr(local, '.')) && (!strcmp(p, ".z") || !strcmp(p, ".gz") || !strcmp(p, ".zip") || + !strcmp(p, ".Z") || !strcmp(p, ".GZ") || !strcmp(p, ".ZIP"))) { + if (rtk_uncompress(local, tmpfile)) { + remove(local); + strcpy(local, tmpfile); + } else { + tracet(2, "file uncompact error: %s\n", local); + ftp->error = 12; + ftp->state = 3; + return 0; + } + } + strcpy(ftp->local, local); + ftp->state = 2; /* ftp completed */ + + tracet(3, "ftpthread: complete cmd=%s\n", cmd); + return 0; } /* open ftp ------------------------------------------------------------------*/ -static ftp_t *openftp(const char *path, int type, char *msg) -{ - ftp_t *ftp; - - tracet(3,"openftp: path=%s type=%d\n",path,type); - - msg[0]='\0'; - - if (!(ftp=(ftp_t *)malloc(sizeof(ftp_t)))) return NULL; - - ftp->state=0; - ftp->proto=type; - ftp->error=0; - ftp->thread=0; - ftp->local[0]='\0'; - - /* decode ftp path */ - decodeftppath(path,ftp->addr,ftp->file,ftp->user,ftp->passwd,ftp->topts); - - /* set first download time */ - ftp->tnext=timeadd(timeget(),10.0); - - return ftp; +static ftp_t *openftp(const char *path, int type, char *msg) { + ftp_t *ftp; + + tracet(3, "openftp: path=%s type=%d\n", path, type); + + msg[0] = '\0'; + + if (!(ftp = (ftp_t *)malloc(sizeof(ftp_t)))) return NULL; + + ftp->state = 0; + ftp->proto = type; + ftp->error = 0; + ftp->thread = 0; + ftp->local[0] = '\0'; + + /* decode ftp path */ + decodeftppath(path, ftp->addr, ftp->file, ftp->user, ftp->passwd, ftp->topts); + + /* set first download time */ + ftp->tnext = timeadd(timeget(), 10.0); + + return ftp; } /* close ftp -----------------------------------------------------------------*/ -static void closeftp(ftp_t *ftp) -{ - tracet(3,"closeftp: state=%d\n",ftp->state); - - if (ftp->state!=1) free(ftp); +static void closeftp(ftp_t *ftp) { + tracet(3, "closeftp: state=%d\n", ftp->state); + + if (ftp->state != 1) free(ftp); } /* read ftp ------------------------------------------------------------------*/ -static int readftp(ftp_t *ftp, uint8_t *buff, int n, char *msg) -{ - gtime_t time; - uint8_t *p,*q; - - tracet(4,"readftp: n=%d\n",n); - - time=utc2gpst(timeget()); - - if (timediff(time,ftp->tnext)<0.0) { /* until download time? */ - return 0; - } - if (ftp->state<=0) { /* ftp/http not executed? */ - ftp->state=1; - sprintf(msg,"%s://%s",ftp->proto?"http":"ftp",ftp->addr); - +static int readftp(ftp_t *ftp, uint8_t *buff, int n, char *msg) { + gtime_t time; + uint8_t *p, *q; + + tracet(4, "readftp: n=%d\n", n); + + time = utc2gpst(timeget()); + + if (timediff(time, ftp->tnext) < 0.0) { /* until download time? */ + return 0; + } + if (ftp->state <= 0) { /* ftp/http not executed? */ + ftp->state = 1; + sprintf(msg, "%s://%s", ftp->proto ? "http" : "ftp", ftp->addr); + #ifdef WIN32 - if (!(ftp->thread=CreateThread(NULL,0,ftpthread,ftp,0,NULL))) { + if (!(ftp->thread = CreateThread(NULL, 0, ftpthread, ftp, 0, NULL))) { #else - if (pthread_create(&ftp->thread,NULL,ftpthread,ftp)) { + if (pthread_create(&ftp->thread, NULL, ftpthread, ftp)) { #endif - tracet(2,"readftp: ftp thread create error\n"); - ftp->state=3; - strcpy(msg,"ftp thread error"); - return 0; - } - } - if (ftp->state<=1) return 0; /* ftp/http on going? */ - - if (ftp->state==3) { /* ftp error */ - sprintf(msg,"%s error (%d)",ftp->proto?"http":"ftp",ftp->error); - - /* set next retry time */ - ftp->tnext=nextdltime(ftp->topts,0); - ftp->state=0; - return 0; + tracet(2, "readftp: ftp thread create error\n"); + ftp->state = 3; + strcpy(msg, "ftp thread error"); + return 0; } - /* return local file path if ftp completed */ - p=buff; - q=(uint8_t *)ftp->local; - while (*q&&(int)(p-buff)tnext=nextdltime(ftp->topts,1); - ftp->state=0; - - strcpy(msg,""); - - return (int)(p-buff); + } + if (ftp->state <= 1) return 0; /* ftp/http on going? */ + + if (ftp->state == 3) { /* ftp error */ + sprintf(msg, "%s error (%d)", ftp->proto ? "http" : "ftp", ftp->error); + + /* set next retry time */ + ftp->tnext = nextdltime(ftp->topts, 0); + ftp->state = 0; + return 0; + } + /* return local file path if ftp completed */ + p = buff; + q = (uint8_t *)ftp->local; + while (*q && (int)(p - buff) < n) *p++ = *q++; + p += sprintf((char *)p, "\r\n"); + + /* set next download time */ + ftp->tnext = nextdltime(ftp->topts, 1); + ftp->state = 0; + + strcpy(msg, ""); + + return (int)(p - buff); } /* get state ftp -------------------------------------------------------------*/ -static int stateftp(ftp_t *ftp) -{ - return !ftp?0:(ftp->state==0?2:(ftp->state<=2?3:-1)); +static int stateftp(ftp_t *ftp) { + return !ftp ? 0 : (ftp->state == 0 ? 2 : (ftp->state <= 2 ? 3 : -1)); } /* get extended state ftp ----------------------------------------------------*/ -static int statexftp(ftp_t *ftp, char *msg) -{ - (void)msg; - return !ftp?0:(ftp->state==0?2:(ftp->state<=2?3:-1)); +static int statexftp(ftp_t *ftp, char *msg) { + (void)msg; + return !ftp ? 0 : (ftp->state == 0 ? 2 : (ftp->state <= 2 ? 3 : -1)); } /* open memory buffer --------------------------------------------------------*/ -static membuf_t *openmembuf(const char *path, char *msg) -{ - membuf_t *membuf; - int bufsize=DEFAULT_MEMBUF_SIZE; - - tracet(3,"openmembuf: path=%s\n",path); - - msg[0]='\0'; - - sscanf(path,"%d",&bufsize); - - if (!(membuf=(membuf_t *)malloc(sizeof(membuf_t)))) return NULL; - membuf->state=1; - membuf->rp=0; - membuf->wp=0; - if (!(membuf->buf=(uint8_t *)malloc(bufsize))) { - free(membuf); - return NULL; - } - membuf->bufsize=bufsize; - rtklib_initlock(&membuf->lock); - - sprintf(msg,"membuf sizebuf=%d",bufsize); - - return membuf; +static membuf_t *openmembuf(const char *path, char *msg) { + membuf_t *membuf; + int bufsize = DEFAULT_MEMBUF_SIZE; + + tracet(3, "openmembuf: path=%s\n", path); + + msg[0] = '\0'; + + sscanf(path, "%d", &bufsize); + + if (!(membuf = (membuf_t *)malloc(sizeof(membuf_t)))) return NULL; + membuf->state = 1; + membuf->rp = 0; + membuf->wp = 0; + if (!(membuf->buf = (uint8_t *)malloc(bufsize))) { + free(membuf); + return NULL; + } + membuf->bufsize = bufsize; + rtklib_initlock(&membuf->lock); + + sprintf(msg, "membuf sizebuf=%d", bufsize); + + return membuf; } /* close memory buffer -------------------------------------------------------*/ -static void closemembuf(membuf_t *membuf) -{ - tracet(3,"closemembufp\n"); - - free(membuf->buf); - free(membuf); +static void closemembuf(membuf_t *membuf) { + tracet(3, "closemembufp\n"); + + free(membuf->buf); + free(membuf); } /* read memory buffer --------------------------------------------------------*/ -static int readmembuf(membuf_t *membuf, uint8_t *buff, int n, char *msg) -{ - (void)msg; - tracet(4,"readmembuf: n=%d\n",n); - - if (!membuf) return 0; - - rtklib_lock(&membuf->lock); - - size_t i=membuf->rp, nr=0; - while (i!=membuf->wp&&nrbuf[i]; - if (++i>=membuf->bufsize) i=0; - } - membuf->rp=i; - rtklib_unlock(&membuf->lock); - return nr; +static int readmembuf(membuf_t *membuf, uint8_t *buff, int n, char *msg) { + (void)msg; + tracet(4, "readmembuf: n=%d\n", n); + + if (!membuf) return 0; + + rtklib_lock(&membuf->lock); + + size_t i = membuf->rp, nr = 0; + while (i != membuf->wp && nr < n) { + buff[nr++] = membuf->buf[i]; + if (++i >= membuf->bufsize) i = 0; + } + membuf->rp = i; + rtklib_unlock(&membuf->lock); + return nr; } /* write memory buffer -------------------------------------------------------*/ -static int writemembuf(membuf_t *membuf, uint8_t *buff, int n, char *msg) -{ - int i; - - tracet(3,"writemembuf: n=%d\n",n); - - if (!membuf) return 0; - - rtklib_lock(&membuf->lock); - - for (i=0;ibuf[membuf->wp++]=buff[i]; - if (membuf->wp>=membuf->bufsize) membuf->wp=0; - if (membuf->wp==membuf->rp) { - strcpy(msg,"mem-buffer overflow"); - membuf->state=-1; - rtklib_unlock(&membuf->lock); - return i+1; - } - } - rtklib_unlock(&membuf->lock); - return i; +static int writemembuf(membuf_t *membuf, uint8_t *buff, int n, char *msg) { + int i; + + tracet(3, "writemembuf: n=%d\n", n); + + if (!membuf) return 0; + + rtklib_lock(&membuf->lock); + + for (i = 0; i < n; i++) { + membuf->buf[membuf->wp++] = buff[i]; + if (membuf->wp >= membuf->bufsize) membuf->wp = 0; + if (membuf->wp == membuf->rp) { + strcpy(msg, "mem-buffer overflow"); + membuf->state = -1; + rtklib_unlock(&membuf->lock); + return i + 1; + } + } + rtklib_unlock(&membuf->lock); + return i; } /* get state memory buffer ---------------------------------------------------*/ -static int statemembuf(membuf_t *membuf) -{ - return !membuf?0:membuf->state; -} +static int statemembuf(membuf_t *membuf) { return !membuf ? 0 : membuf->state; } /* get extended state memory buffer ------------------------------------------*/ -static int statexmembuf(membuf_t *membuf, char *msg) -{ - char *p=msg; - int state=!membuf?0:membuf->state; - - p+=sprintf(p,"membuf:\n"); - p+=sprintf(p," state = %d\n",state); - if (!state) return 0; - p+=sprintf(p," buffsize= %d\n",membuf->bufsize); - p+=sprintf(p," wp = %d\n",membuf->wp); - sprintf(p," rp = %d\n",membuf->rp); - return state; +static int statexmembuf(membuf_t *membuf, char *msg) { + char *p = msg; + int state = !membuf ? 0 : membuf->state; + + p += sprintf(p, "membuf:\n"); + p += sprintf(p, " state = %d\n", state); + if (!state) return 0; + p += sprintf(p, " buffsize= %d\n", membuf->bufsize); + p += sprintf(p, " wp = %d\n", membuf->wp); + sprintf(p, " rp = %d\n", membuf->rp); + return state; } /* initialize stream environment ----------------------------------------------- -* initialize stream environment -* args : none -* return : none -*-----------------------------------------------------------------------------*/ -extern void strinitcom(void) -{ + * initialize stream environment + * args : none + * return : none + *-----------------------------------------------------------------------------*/ +extern void strinitcom(void) { #ifdef WIN32 - WSADATA data; + WSADATA data; #endif - tracet(3,"strinitcom:\n"); + tracet(3, "strinitcom:\n"); #ifdef WIN32 - WSAStartup(MAKEWORD(2,0),&data); + WSAStartup(MAKEWORD(2, 0), &data); #endif } /* initialize stream ----------------------------------------------------------- -* initialize stream struct -* args : stream_t *stream IO stream -* return : none -*-----------------------------------------------------------------------------*/ -extern void strinit(stream_t *stream) -{ - tracet(3,"strinit:\n"); - - stream->type=0; - stream->mode=0; - stream->state=0; - stream->inb=stream->inr=stream->outb=stream->outr=0; - stream->tick_i=stream->tick_o=stream->tact=stream->inbt=stream->outbt=0; - rtklib_initlock(&stream->lock); - stream->port=NULL; - stream->path[0]='\0'; - stream->msg [0]='\0'; + * initialize stream struct + * args : stream_t *stream IO stream + * return : none + *-----------------------------------------------------------------------------*/ +extern void strinit(stream_t *stream) { + tracet(3, "strinit:\n"); + + stream->type = 0; + stream->mode = 0; + stream->state = 0; + stream->inb = stream->inr = stream->outb = stream->outr = 0; + stream->tick_i = stream->tick_o = stream->tact = stream->inbt = stream->outbt = 0; + rtklib_initlock(&stream->lock); + stream->port = NULL; + stream->path[0] = '\0'; + stream->msg[0] = '\0'; } /* open stream ----------------------------------------------------------------- -* -* open stream to read or write data from or to virtual devices. -* -* args : stream_t *stream IO stream -* int type I stream type -* STR_SERIAL = serial device -* STR_FILE = file (record and playback) -* STR_TCPSVR = TCP server -* STR_TCPCLI = TCP client -* STR_NTRIPSVR = NTRIP server -* STR_NTRIPCLI = NTRIP client -* STR_NTRIPCAS = NTRIP caster client -* STR_UDPSVR = UDP server (read only) -* STR_UDPCLI = UDP client (write only) -* STR_MEMBUF = memory buffer (FIFO) -* STR_FTP = download by FTP (read only) -* STR_HTTP = download by HTTP (read only) -* int mode I stream mode (STR_MODE_???) -* STR_MODE_R = read only -* STR_MODE_W = write only -* STR_MODE_RW = read and write -* char *path I stream path (see below) -* -* return : status (0:error,1:ok) -* -* notes : see reference [1] for NTRIP -* STR_FTP/HTTP needs "wget" in command search paths -* -* stream path ([] options): -* -* STR_SERIAL port[:brate[:bsize[:parity[:stopb[:fctr[#port]]]]]] -* port = COM?? (windows) -* tty??? (linuex, omit /dev/) -* brate = bit rate (bps) -* bsize = bit size (7|8) -* parity= parity (n|o|e) -* stopb = stop bits (1|2) -* fctr = flow control (off|rts) -* port = tcp server port to output received stream -* -* STR_FILE path[::T][::+start][::xseppd][::S=swap][::P={4|8}] -* path = file path -* (can include keywords defined by ) -* ::T = enable time tag -* start = replay start offset (s) -* speed = replay speed factor -* swap = output swap interval (hr) (0: no swap) -* ::P={4|8} = file pointer size (4:32bit,8:64bit) -* -* STR_TCPSVR :port -* port = TCP server port to accept -* -* STR_TCPCLI addr:port -* addr = TCP server address to connect -* port = TCP server port to connect -* -* STR_NTRIPSVR [:passwd@]addr[:port]/mponit[:string] -* addr = NTRIP caster address to connect -* port = NTRIP caster server port to connect -* passwd= NTRIP caster server password to connect -* mpoint= NTRIP mountpoint -* string= NTRIP server string -* -* STR_NTRIPCLI [user[:passwd]@]addr[:port]/mpoint -* addr = NTRIP caster address to connect -* port = NTRIP caster client port to connect -* user = NTRIP caster client user to connect -* passwd= NTRIP caster client password to connect -* mpoint= NTRIP mountpoint -* -* STR_NTRIPCAS [user[:passwd]@][:port]/mpoint[:srctbl] -* port = NTRIP caster client port to accept connection -* user = NTRIP caster client user to accept connection -* passwd= NTRIP caster client password to accept connection -* mpoint= NTRIP mountpoint -* srctbl= NTRIP source table entry (STR) (ref [3] 6.3) -* (ID;format;format-details;carrier;nav-system;network; -* country;latitude;longitude;nmea;solution;generator; -* compr-encrp;autentication;fee;bitrate;...;misc) -* -* STR_UDPSVR :port -* port = UDP server port to receive -* -* STR_UDPCLI addr:port -* addr = UDP server or broadcast address to send -* port = UDP server or broadcast port to send -* -* STR_MEMBUF [size] -* size = FIFO size (bytes) ("":4096) -* -* STR_FTP [user[:passwd]@]addr/path[::T=poff[,tint[,toff,tret]]]] -* user = FTP server user -* passwd= FTP server password -* addr = FTP server address -* path = FTP server file path -* poff = time offset for path extension (s) -* tint = download interval (s) -* toff = download time offset (s) -* tret = download retry interval (s) (0:no retry) -* -* STR_HTTP addr/path[::T=poff[,tint[,toff,tret]]]] -* addr = HTTP server address -* path = HTTP server file path -* poff = time offset for path extension (s) -* tint = download interval (s) -* toff = download time offset (s) -* tret = download retry interval (s) (0:no retry) -* -*-----------------------------------------------------------------------------*/ -extern int stropen(stream_t *stream, int type, int mode, const char *path) -{ - tracet(3,"stropen: type=%d mode=%d path=%s\n",type,mode,path); - - stream->type=type; - stream->mode=mode; - strcpy(stream->path,path); - stream->inb=stream->inr=stream->outb=stream->outr=0; - stream->tick_i=stream->tick_o=tickget(); - stream->inbt=stream->outbt=0; - stream->msg[0]='\0'; - stream->port=NULL; - switch (type) { - case STR_SERIAL : stream->port=openserial(path,mode,stream->msg); break; - case STR_FILE : stream->port=openfile (path,mode,stream->msg); break; - case STR_TCPSVR : stream->port=opentcpsvr(path, stream->msg); break; - case STR_TCPCLI : stream->port=opentcpcli(path, stream->msg); break; - case STR_NTRIPSVR: stream->port=openntrip (path,0, stream->msg); break; - case STR_NTRIPCLI: stream->port=openntrip (path,1, stream->msg); break; - case STR_NTRIPCAS: stream->port=openntripc(path, stream->msg); break; - case STR_UDPSVR : stream->port=openudpsvr(path, stream->msg); break; - case STR_UDPCLI : stream->port=openudpcli(path, stream->msg); break; - case STR_MEMBUF : stream->port=openmembuf(path, stream->msg); break; - case STR_FTP : stream->port=openftp (path,0, stream->msg); break; - case STR_HTTP : stream->port=openftp (path,1, stream->msg); break; - default: stream->state=0; return 1; - } - stream->state=!stream->port?-1:1; - return stream->port!=NULL; + * + * open stream to read or write data from or to virtual devices. + * + * args : stream_t *stream IO stream + * int type I stream type + * STR_SERIAL = serial device + * STR_FILE = file (record and playback) + * STR_TCPSVR = TCP server + * STR_TCPCLI = TCP client + * STR_NTRIPSVR = NTRIP server + * STR_NTRIPCLI = NTRIP client + * STR_NTRIPCAS = NTRIP caster client + * STR_UDPSVR = UDP server (read only) + * STR_UDPCLI = UDP client (write only) + * STR_MEMBUF = memory buffer (FIFO) + * STR_FTP = download by FTP (read only) + * STR_HTTP = download by HTTP (read only) + * int mode I stream mode (STR_MODE_???) + * STR_MODE_R = read only + * STR_MODE_W = write only + * STR_MODE_RW = read and write + * char *path I stream path (see below) + * + * return : status (0:error,1:ok) + * + * notes : see reference [1] for NTRIP + * STR_FTP/HTTP needs "wget" in command search paths + * + * stream path ([] options): + * + * STR_SERIAL port[:brate[:bsize[:parity[:stopb[:fctr[#port]]]]]] + * port = COM?? (windows) + * tty??? (linuex, omit /dev/) + * brate = bit rate (bps) + * bsize = bit size (7|8) + * parity= parity (n|o|e) + * stopb = stop bits (1|2) + * fctr = flow control (off|rts) + * port = tcp server port to output received stream + * + * STR_FILE path[::T][::+start][::xseppd][::S=swap][::P={4|8}] + * path = file path + * (can include keywords defined by ) + * ::T = enable time tag + * start = replay start offset (s) + * speed = replay speed factor + * swap = output swap interval (hr) (0: no swap) + * ::P={4|8} = file pointer size (4:32bit,8:64bit) + * + * STR_TCPSVR :port + * port = TCP server port to accept + * + * STR_TCPCLI addr:port + * addr = TCP server address to connect + * port = TCP server port to connect + * + * STR_NTRIPSVR [:passwd@]addr[:port]/mponit[:string] + * addr = NTRIP caster address to connect + * port = NTRIP caster server port to connect + * passwd= NTRIP caster server password to connect + * mpoint= NTRIP mountpoint + * string= NTRIP server string + * + * STR_NTRIPCLI [user[:passwd]@]addr[:port]/mpoint + * addr = NTRIP caster address to connect + * port = NTRIP caster client port to connect + * user = NTRIP caster client user to connect + * passwd= NTRIP caster client password to connect + * mpoint= NTRIP mountpoint + * + * STR_NTRIPCAS [user[:passwd]@][:port]/mpoint[:srctbl] + * port = NTRIP caster client port to accept connection + * user = NTRIP caster client user to accept connection + * passwd= NTRIP caster client password to accept connection + * mpoint= NTRIP mountpoint + * srctbl= NTRIP source table entry (STR) (ref [3] 6.3) + * (ID;format;format-details;carrier;nav-system;network; + * country;latitude;longitude;nmea;solution;generator; + * compr-encrp;autentication;fee;bitrate;...;misc) + * + * STR_UDPSVR :port + * port = UDP server port to receive + * + * STR_UDPCLI addr:port + * addr = UDP server or broadcast address to send + * port = UDP server or broadcast port to send + * + * STR_MEMBUF [size] + * size = FIFO size (bytes) ("":4096) + * + * STR_FTP [user[:passwd]@]addr/path[::T=poff[,tint[,toff,tret]]]] + * user = FTP server user + * passwd= FTP server password + * addr = FTP server address + * path = FTP server file path + * poff = time offset for path extension (s) + * tint = download interval (s) + * toff = download time offset (s) + * tret = download retry interval (s) (0:no retry) + * + * STR_HTTP addr/path[::T=poff[,tint[,toff,tret]]]] + * addr = HTTP server address + * path = HTTP server file path + * poff = time offset for path extension (s) + * tint = download interval (s) + * toff = download time offset (s) + * tret = download retry interval (s) (0:no retry) + * + *-----------------------------------------------------------------------------*/ +extern int stropen(stream_t *stream, int type, int mode, const char *path) { + tracet(3, "stropen: type=%d mode=%d path=%s\n", type, mode, path); + + stream->type = type; + stream->mode = mode; + strcpy(stream->path, path); + stream->inb = stream->inr = stream->outb = stream->outr = 0; + stream->tick_i = stream->tick_o = tickget(); + stream->inbt = stream->outbt = 0; + stream->msg[0] = '\0'; + stream->port = NULL; + switch (type) { + case STR_SERIAL: + stream->port = openserial(path, mode, stream->msg); + break; + case STR_FILE: + stream->port = openfile(path, mode, stream->msg); + break; + case STR_TCPSVR: + stream->port = opentcpsvr(path, stream->msg); + break; + case STR_TCPCLI: + stream->port = opentcpcli(path, stream->msg); + break; + case STR_NTRIPSVR: + stream->port = openntrip(path, 0, stream->msg); + break; + case STR_NTRIPCLI: + stream->port = openntrip(path, 1, stream->msg); + break; + case STR_NTRIPCAS: + stream->port = openntripc(path, stream->msg); + break; + case STR_UDPSVR: + stream->port = openudpsvr(path, stream->msg); + break; + case STR_UDPCLI: + stream->port = openudpcli(path, stream->msg); + break; + case STR_MEMBUF: + stream->port = openmembuf(path, stream->msg); + break; + case STR_FTP: + stream->port = openftp(path, 0, stream->msg); + break; + case STR_HTTP: + stream->port = openftp(path, 1, stream->msg); + break; + default: + stream->state = 0; + return 1; + } + stream->state = !stream->port ? -1 : 1; + return stream->port != NULL; } /* close stream ---------------------------------------------------------------- -* close stream -* args : stream_t *stream IO stream -* return : none -*-----------------------------------------------------------------------------*/ -extern void strclose(stream_t *stream) -{ - tracet(3,"strclose: type=%d mode=%d\n",stream->type,stream->mode); - - strlock(stream); - - if (stream->port) { - switch (stream->type) { - case STR_SERIAL : closeserial((serial_t *)stream->port); break; - case STR_FILE : closefile ((file_t *)stream->port); break; - case STR_TCPSVR : closetcpsvr((tcpsvr_t *)stream->port); break; - case STR_TCPCLI : closetcpcli((tcpcli_t *)stream->port); break; - case STR_NTRIPSVR: closentrip ((ntrip_t *)stream->port); break; - case STR_NTRIPCLI: closentrip ((ntrip_t *)stream->port); break; - case STR_NTRIPCAS: closentripc((ntripc_t *)stream->port); break; - case STR_UDPSVR : closeudpsvr((udp_t *)stream->port); break; - case STR_UDPCLI : closeudpcli((udp_t *)stream->port); break; - case STR_MEMBUF : closemembuf((membuf_t *)stream->port); break; - case STR_FTP : closeftp ((ftp_t *)stream->port); break; - case STR_HTTP : closeftp ((ftp_t *)stream->port); break; - } - } - else { - trace(3,"no port to close stream: type=%d\n",stream->type); - } - stream->type=0; - stream->mode=0; - stream->state=0; - stream->inr=stream->outr=0; - stream->path[0]='\0'; - stream->msg[0]='\0'; - stream->port=NULL; - - strunlock(stream); + * close stream + * args : stream_t *stream IO stream + * return : none + *-----------------------------------------------------------------------------*/ +extern void strclose(stream_t *stream) { + tracet(3, "strclose: type=%d mode=%d\n", stream->type, stream->mode); + + strlock(stream); + + if (stream->port) { + switch (stream->type) { + case STR_SERIAL: + closeserial((serial_t *)stream->port); + break; + case STR_FILE: + closefile((file_t *)stream->port); + break; + case STR_TCPSVR: + closetcpsvr((tcpsvr_t *)stream->port); + break; + case STR_TCPCLI: + closetcpcli((tcpcli_t *)stream->port); + break; + case STR_NTRIPSVR: + closentrip((ntrip_t *)stream->port); + break; + case STR_NTRIPCLI: + closentrip((ntrip_t *)stream->port); + break; + case STR_NTRIPCAS: + closentripc((ntripc_t *)stream->port); + break; + case STR_UDPSVR: + closeudpsvr((udp_t *)stream->port); + break; + case STR_UDPCLI: + closeudpcli((udp_t *)stream->port); + break; + case STR_MEMBUF: + closemembuf((membuf_t *)stream->port); + break; + case STR_FTP: + closeftp((ftp_t *)stream->port); + break; + case STR_HTTP: + closeftp((ftp_t *)stream->port); + break; + } + } else { + trace(3, "no port to close stream: type=%d\n", stream->type); + } + stream->type = 0; + stream->mode = 0; + stream->state = 0; + stream->inr = stream->outr = 0; + stream->path[0] = '\0'; + stream->msg[0] = '\0'; + stream->port = NULL; + + strunlock(stream); } /* sync streams ---------------------------------------------------------------- -* sync time for streams -* args : stream_t *stream1 IO stream 1 -* stream_t *stream2 IO stream 2 -* return : none -* notes : for replay files with time tags -*-----------------------------------------------------------------------------*/ -extern void strsync(stream_t *stream1, stream_t *stream2) -{ - file_t *file1,*file2; - if (stream1->type!=STR_FILE||stream2->type!=STR_FILE) return; - file1=(file_t*)stream1->port; - file2=(file_t*)stream2->port; - if (file1&&file2) syncfile(file1,file2); + * sync time for streams + * args : stream_t *stream1 IO stream 1 + * stream_t *stream2 IO stream 2 + * return : none + * notes : for replay files with time tags + *-----------------------------------------------------------------------------*/ +extern void strsync(stream_t *stream1, stream_t *stream2) { + file_t *file1, *file2; + if (stream1->type != STR_FILE || stream2->type != STR_FILE) return; + file1 = (file_t *)stream1->port; + file2 = (file_t *)stream2->port; + if (file1 && file2) syncfile(file1, file2); } /* lock/unlock stream ---------------------------------------------------------- -* lock/unlock stream -* args : stream_t *stream I stream -* return : none -*-----------------------------------------------------------------------------*/ -extern void strlock (stream_t *stream) {rtklib_lock (&stream->lock);} -extern void strunlock(stream_t *stream) {rtklib_unlock(&stream->lock);} + * lock/unlock stream + * args : stream_t *stream I stream + * return : none + *-----------------------------------------------------------------------------*/ +extern void strlock(stream_t *stream) { rtklib_lock(&stream->lock); } +extern void strunlock(stream_t *stream) { rtklib_unlock(&stream->lock); } /* read stream ----------------------------------------------------------------- -* read data from stream (unblocked) -* args : stream_t *stream I stream -* unsinged char *buff O data buffer -* int n I maximum data length -* return : read data length -* notes : if no data, return immediately with no data -*-----------------------------------------------------------------------------*/ -extern int strread(stream_t *stream, uint8_t *buff, int n) -{ - uint32_t tick=tickget(); - char *msg=stream->msg; - int nr=0,tt; - - tracet(4,"strread: n=%d\n",n); - - if (!(stream->mode&STR_MODE_R)||!stream->port) return 0; - - strlock(stream); - - switch (stream->type) { - case STR_SERIAL : nr=readserial((serial_t *)stream->port,buff,n,msg); break; - case STR_FILE : nr=readfile ((file_t *)stream->port,buff,n,msg); break; - case STR_TCPSVR : nr=readtcpsvr((tcpsvr_t *)stream->port,buff,n,msg); break; - case STR_TCPCLI : nr=readtcpcli((tcpcli_t *)stream->port,buff,n,msg); break; - case STR_NTRIPSVR: - case STR_NTRIPCLI: nr=readntrip ((ntrip_t *)stream->port,buff,n,msg); break; - case STR_NTRIPCAS: nr=readntripc((ntripc_t *)stream->port,buff,n,msg); break; - case STR_UDPSVR : nr=readudpsvr((udp_t *)stream->port,buff,n,msg); break; - case STR_MEMBUF : nr=readmembuf((membuf_t *)stream->port,buff,n,msg); break; - case STR_FTP : nr=readftp ((ftp_t *)stream->port,buff,n,msg); break; - case STR_HTTP : nr=readftp ((ftp_t *)stream->port,buff,n,msg); break; - default: - strunlock(stream); - return 0; - } - if (nr>0) { - stream->inb+=nr; - stream->tact=tick; - } - tt=(int)(tick-stream->tick_i); - if (tt>=tirate) { - stream->inr= - (uint32_t)((double)((stream->inb-stream->inbt)*8)/(tt*0.001)); - stream->tick_i=tick; - stream->inbt=stream->inb; - } - strunlock(stream); - return nr; + * read data from stream (unblocked) + * args : stream_t *stream I stream + * unsinged char *buff O data buffer + * int n I maximum data length + * return : read data length + * notes : if no data, return immediately with no data + *-----------------------------------------------------------------------------*/ +extern int strread(stream_t *stream, uint8_t *buff, int n) { + uint32_t tick = tickget(); + char *msg = stream->msg; + int nr = 0, tt; + + tracet(4, "strread: n=%d\n", n); + + if (!(stream->mode & STR_MODE_R) || !stream->port) return 0; + + strlock(stream); + + switch (stream->type) { + case STR_SERIAL: + nr = readserial((serial_t *)stream->port, buff, n, msg); + break; + case STR_FILE: + nr = readfile((file_t *)stream->port, buff, n, msg); + break; + case STR_TCPSVR: + nr = readtcpsvr((tcpsvr_t *)stream->port, buff, n, msg); + break; + case STR_TCPCLI: + nr = readtcpcli((tcpcli_t *)stream->port, buff, n, msg); + break; + case STR_NTRIPSVR: + case STR_NTRIPCLI: + nr = readntrip((ntrip_t *)stream->port, buff, n, msg); + break; + case STR_NTRIPCAS: + nr = readntripc((ntripc_t *)stream->port, buff, n, msg); + break; + case STR_UDPSVR: + nr = readudpsvr((udp_t *)stream->port, buff, n, msg); + break; + case STR_MEMBUF: + nr = readmembuf((membuf_t *)stream->port, buff, n, msg); + break; + case STR_FTP: + nr = readftp((ftp_t *)stream->port, buff, n, msg); + break; + case STR_HTTP: + nr = readftp((ftp_t *)stream->port, buff, n, msg); + break; + default: + strunlock(stream); + return 0; + } + if (nr > 0) { + stream->inb += nr; + stream->tact = tick; + } + tt = (int)(tick - stream->tick_i); + if (tt >= tirate) { + stream->inr = (uint32_t)((double)((stream->inb - stream->inbt) * 8) / (tt * 0.001)); + stream->tick_i = tick; + stream->inbt = stream->inb; + } + strunlock(stream); + return nr; } /* write stream ---------------------------------------------------------------- -* write data to stream (unblocked) -* args : stream_t *stream I stream -* unsinged char *buff I data buffer -* int n I data length -* return : status (0:error,1:ok) -* notes : write data to buffer and return immediately -*-----------------------------------------------------------------------------*/ -extern int strwrite(stream_t *stream, uint8_t *buff, int n) -{ - uint32_t tick=tickget(); - char *msg=stream->msg; - int ns,tt; - - tracet(4,"strwrite: n=%d\n",n); - - if (!(stream->mode&STR_MODE_W)||!stream->port) return 0; - - strlock(stream); - - switch (stream->type) { - case STR_SERIAL : ns=writeserial((serial_t *)stream->port,buff,n,msg); break; - case STR_FILE : ns=writefile ((file_t *)stream->port,buff,n,msg); break; - case STR_TCPSVR : ns=writetcpsvr((tcpsvr_t *)stream->port,buff,n,msg); break; - case STR_TCPCLI : ns=writetcpcli((tcpcli_t *)stream->port,buff,n,msg); break; - case STR_NTRIPSVR: - case STR_NTRIPCLI: ns=writentrip ((ntrip_t *)stream->port,buff,n,msg); break; - case STR_NTRIPCAS: ns=writentripc((ntripc_t *)stream->port,buff,n,msg); break; - case STR_UDPCLI : ns=writeudpcli((udp_t *)stream->port,buff,n,msg); break; - case STR_MEMBUF : ns=writemembuf((membuf_t *)stream->port,buff,n,msg); break; - case STR_FTP : - case STR_HTTP : - default: - strunlock(stream); - return 0; - } - if (ns>0) { - stream->outb+=ns; - stream->tact=tick; - } - tt=(int)(tick-stream->tick_o); - if (tt>tirate) { - stream->outr= - (uint32_t)((double)((stream->outb-stream->outbt)*8)/(tt*0.001)); - stream->tick_o=tick; - stream->outbt=stream->outb; - } - strunlock(stream); - return ns; + * write data to stream (unblocked) + * args : stream_t *stream I stream + * unsinged char *buff I data buffer + * int n I data length + * return : status (0:error,1:ok) + * notes : write data to buffer and return immediately + *-----------------------------------------------------------------------------*/ +extern int strwrite(stream_t *stream, uint8_t *buff, int n) { + uint32_t tick = tickget(); + char *msg = stream->msg; + int ns, tt; + + tracet(4, "strwrite: n=%d\n", n); + + if (!(stream->mode & STR_MODE_W) || !stream->port) return 0; + + strlock(stream); + + switch (stream->type) { + case STR_SERIAL: + ns = writeserial((serial_t *)stream->port, buff, n, msg); + break; + case STR_FILE: + ns = writefile((file_t *)stream->port, buff, n, msg); + break; + case STR_TCPSVR: + ns = writetcpsvr((tcpsvr_t *)stream->port, buff, n, msg); + break; + case STR_TCPCLI: + ns = writetcpcli((tcpcli_t *)stream->port, buff, n, msg); + break; + case STR_NTRIPSVR: + case STR_NTRIPCLI: + ns = writentrip((ntrip_t *)stream->port, buff, n, msg); + break; + case STR_NTRIPCAS: + ns = writentripc((ntripc_t *)stream->port, buff, n, msg); + break; + case STR_UDPCLI: + ns = writeudpcli((udp_t *)stream->port, buff, n, msg); + break; + case STR_MEMBUF: + ns = writemembuf((membuf_t *)stream->port, buff, n, msg); + break; + case STR_FTP: + case STR_HTTP: + default: + strunlock(stream); + return 0; + } + if (ns > 0) { + stream->outb += ns; + stream->tact = tick; + } + tt = (int)(tick - stream->tick_o); + if (tt > tirate) { + stream->outr = (uint32_t)((double)((stream->outb - stream->outbt) * 8) / (tt * 0.001)); + stream->tick_o = tick; + stream->outbt = stream->outb; + } + strunlock(stream); + return ns; } /* get stream status ----------------------------------------------------------- -* get stream status -* args : stream_t *stream I stream -* char *msg IO status message (NULL: no output) -* return : status (-1:error,0:close,1:wait,2:connect,3:active) -*-----------------------------------------------------------------------------*/ -extern int strstat(stream_t *stream, char *msg) -{ - int state=0; - - tracet(4,"strstat:\n"); - - strlock(stream); - if (msg) { - strncpy(msg,stream->msg,MAXSTRMSG-1); msg[MAXSTRMSG-1]='\0'; - } - if (!stream->port) { - strunlock(stream); - return stream->state; - } - switch (stream->type) { - case STR_SERIAL : state=stateserial((serial_t *)stream->port); break; - case STR_FILE : state=statefile ((file_t *)stream->port); break; - case STR_TCPSVR : state=statetcpsvr((tcpsvr_t *)stream->port); break; - case STR_TCPCLI : state=statetcpcli((tcpcli_t *)stream->port); break; - case STR_NTRIPSVR: - case STR_NTRIPCLI: state=statentrip ((ntrip_t *)stream->port); break; - case STR_NTRIPCAS: state=statentripc((ntripc_t *)stream->port); break; - case STR_UDPSVR : state=stateudpsvr((udp_t *)stream->port); break; - case STR_UDPCLI : state=stateudpcli((udp_t *)stream->port); break; - case STR_MEMBUF : state=statemembuf((membuf_t *)stream->port); break; - case STR_FTP : state=stateftp ((ftp_t *)stream->port); break; - case STR_HTTP : state=stateftp ((ftp_t *)stream->port); break; - default: - strunlock(stream); - return 0; - } - if (state==2&&(int)(tickget()-stream->tact)<=TINTACT) state=3; + * get stream status + * args : stream_t *stream I stream + * char *msg IO status message (NULL: no output) + * return : status (-1:error,0:close,1:wait,2:connect,3:active) + *-----------------------------------------------------------------------------*/ +extern int strstat(stream_t *stream, char *msg) { + int state = 0; + + tracet(4, "strstat:\n"); + + strlock(stream); + if (msg) { + strncpy(msg, stream->msg, MAXSTRMSG - 1); + msg[MAXSTRMSG - 1] = '\0'; + } + if (!stream->port) { strunlock(stream); - return state; + return stream->state; + } + switch (stream->type) { + case STR_SERIAL: + state = stateserial((serial_t *)stream->port); + break; + case STR_FILE: + state = statefile((file_t *)stream->port); + break; + case STR_TCPSVR: + state = statetcpsvr((tcpsvr_t *)stream->port); + break; + case STR_TCPCLI: + state = statetcpcli((tcpcli_t *)stream->port); + break; + case STR_NTRIPSVR: + case STR_NTRIPCLI: + state = statentrip((ntrip_t *)stream->port); + break; + case STR_NTRIPCAS: + state = statentripc((ntripc_t *)stream->port); + break; + case STR_UDPSVR: + state = stateudpsvr((udp_t *)stream->port); + break; + case STR_UDPCLI: + state = stateudpcli((udp_t *)stream->port); + break; + case STR_MEMBUF: + state = statemembuf((membuf_t *)stream->port); + break; + case STR_FTP: + state = stateftp((ftp_t *)stream->port); + break; + case STR_HTTP: + state = stateftp((ftp_t *)stream->port); + break; + default: + strunlock(stream); + return 0; + } + if (state == 2 && (int)(tickget() - stream->tact) <= TINTACT) state = 3; + strunlock(stream); + return state; } /* get extended stream status --------------------------------------------------- -* get extended stream status -* args : stream_t *stream I stream -* char *msg IO extended status message -* return : status (-1:error,0:close,1:wait,2:connect,3:active) -*-----------------------------------------------------------------------------*/ -extern int strstatx(stream_t *stream, char *msg) -{ - int state=0; - - tracet(4,"strstatx:\n"); - - strlock(stream); - - if (!stream->port) { - strunlock(stream); - return stream->state; - } - switch (stream->type) { - case STR_SERIAL : state=statexserial((serial_t *)stream->port,msg); break; - case STR_FILE : state=statexfile ((file_t *)stream->port,msg); break; - case STR_TCPSVR : state=statextcpsvr((tcpsvr_t *)stream->port,msg); break; - case STR_TCPCLI : state=statextcpcli((tcpcli_t *)stream->port,msg); break; - case STR_NTRIPSVR: - case STR_NTRIPCLI: state=statexntrip ((ntrip_t *)stream->port,msg); break; - case STR_NTRIPCAS: state=statexntripc((ntripc_t *)stream->port,msg); break; - case STR_UDPSVR : state=statexudpsvr((udp_t *)stream->port,msg); break; - case STR_UDPCLI : state=statexudpcli((udp_t *)stream->port,msg); break; - case STR_MEMBUF : state=statexmembuf((membuf_t *)stream->port,msg); break; - case STR_FTP : state=statexftp ((ftp_t *)stream->port,msg); break; - case STR_HTTP : state=statexftp ((ftp_t *)stream->port,msg); break; - default: - msg[0]='\0'; - strunlock(stream); - return 0; - } - if (state==2&&(int)(tickget()-stream->tact)<=TINTACT) state=3; + * get extended stream status + * args : stream_t *stream I stream + * char *msg IO extended status message + * return : status (-1:error,0:close,1:wait,2:connect,3:active) + *-----------------------------------------------------------------------------*/ +extern int strstatx(stream_t *stream, char *msg) { + int state = 0; + + tracet(4, "strstatx:\n"); + + strlock(stream); + + if (!stream->port) { strunlock(stream); - return state; + return stream->state; + } + switch (stream->type) { + case STR_SERIAL: + state = statexserial((serial_t *)stream->port, msg); + break; + case STR_FILE: + state = statexfile((file_t *)stream->port, msg); + break; + case STR_TCPSVR: + state = statextcpsvr((tcpsvr_t *)stream->port, msg); + break; + case STR_TCPCLI: + state = statextcpcli((tcpcli_t *)stream->port, msg); + break; + case STR_NTRIPSVR: + case STR_NTRIPCLI: + state = statexntrip((ntrip_t *)stream->port, msg); + break; + case STR_NTRIPCAS: + state = statexntripc((ntripc_t *)stream->port, msg); + break; + case STR_UDPSVR: + state = statexudpsvr((udp_t *)stream->port, msg); + break; + case STR_UDPCLI: + state = statexudpcli((udp_t *)stream->port, msg); + break; + case STR_MEMBUF: + state = statexmembuf((membuf_t *)stream->port, msg); + break; + case STR_FTP: + state = statexftp((ftp_t *)stream->port, msg); + break; + case STR_HTTP: + state = statexftp((ftp_t *)stream->port, msg); + break; + default: + msg[0] = '\0'; + strunlock(stream); + return 0; + } + if (state == 2 && (int)(tickget() - stream->tact) <= TINTACT) state = 3; + strunlock(stream); + return state; } /* get stream statistics summary ----------------------------------------------- -* get stream statistics summary -* args : stream_t *stream I stream -* int *inb IO bytes of input (NULL: no output) -* int *inr IO bps of input (NULL: no output) -* int *outb IO bytes of output (NULL: no output) -* int *outr IO bps of output (NULL: no output) -* return : none -*-----------------------------------------------------------------------------*/ -extern void strsum(stream_t *stream, int *inb, int *inr, int *outb, int *outr) -{ - tracet(4,"strsum:\n"); - - strlock(stream); - if (inb) *inb =stream->inb; - if (inr) *inr =stream->inr; - if (outb) *outb=stream->outb; - if (outr) *outr=stream->outr; - strunlock(stream); + * get stream statistics summary + * args : stream_t *stream I stream + * int *inb IO bytes of input (NULL: no output) + * int *inr IO bps of input (NULL: no output) + * int *outb IO bytes of output (NULL: no output) + * int *outr IO bps of output (NULL: no output) + * return : none + *-----------------------------------------------------------------------------*/ +extern void strsum(stream_t *stream, int *inb, int *inr, int *outb, int *outr) { + tracet(4, "strsum:\n"); + + strlock(stream); + if (inb) *inb = stream->inb; + if (inr) *inr = stream->inr; + if (outb) *outb = stream->outb; + if (outr) *outr = stream->outr; + strunlock(stream); } /* set global stream options --------------------------------------------------- -* set global stream options -* args : int *opt I options -* opt[0]= inactive timeout (ms) (0: no timeout) -* opt[1]= interval to reconnect (ms) -* opt[2]= averaging time of data rate (ms) -* opt[3]= receive/send buffer size (bytes); -* opt[4]= file swap margin (s) -* opt[5]= reserved -* opt[6]= reserved -* opt[7]= reserved -* return : none -*-----------------------------------------------------------------------------*/ -extern void strsetopt(const int *opt) -{ - tracet(3,"strsetopt: opt=%d %d %d %d %d %d %d %d\n",opt[0],opt[1],opt[2], - opt[3],opt[4],opt[5],opt[6],opt[7]); - - toinact =0=1s */ - ticonnect =opt[1]<1000?1000:opt[1]; /* >=1s */ - tirate =opt[2]<100 ?100 :opt[2]; /* >=0.1s */ - buffsize =opt[3]<4096?4096:opt[3]; /* >=4096byte */ - fswapmargin=opt[4]<0?0:opt[4]; + * set global stream options + * args : int *opt I options + * opt[0]= inactive timeout (ms) (0: no timeout) + * opt[1]= interval to reconnect (ms) + * opt[2]= averaging time of data rate (ms) + * opt[3]= receive/send buffer size (bytes); + * opt[4]= file swap margin (s) + * opt[5]= reserved + * opt[6]= reserved + * opt[7]= reserved + * return : none + *-----------------------------------------------------------------------------*/ +extern void strsetopt(const int *opt) { + tracet(3, "strsetopt: opt=%d %d %d %d %d %d %d %d\n", opt[0], opt[1], opt[2], opt[3], opt[4], + opt[5], opt[6], opt[7]); + + toinact = 0 < opt[0] && opt[0] < 1000 ? 1000 : opt[0]; /* >=1s */ + ticonnect = opt[1] < 1000 ? 1000 : opt[1]; /* >=1s */ + tirate = opt[2] < 100 ? 100 : opt[2]; /* >=0.1s */ + buffsize = opt[3] < 4096 ? 4096 : opt[3]; /* >=4096byte */ + fswapmargin = opt[4] < 0 ? 0 : opt[4]; } /* set timeout time ------------------------------------------------------------ -* set timeout time -* args : stream_t *stream I stream (STR_TCPCLI,STR_NTRIPCLI,STR_NTRIPSVR) -* int toinact I inactive timeout (ms) (0: no timeout) -* int tirecon I reconnect interval (ms) (0: no reconnect) -* return : none -*-----------------------------------------------------------------------------*/ -extern void strsettimeout(stream_t *stream, int toinact, int tirecon) -{ - tcpcli_t *tcpcli; - - tracet(3,"strsettimeout: toinact=%d tirecon=%d\n",toinact,tirecon); - - if (stream->type==STR_TCPCLI) { - tcpcli=(tcpcli_t *)stream->port; - } - else if (stream->type==STR_NTRIPCLI||stream->type==STR_NTRIPSVR) { - tcpcli=((ntrip_t *)stream->port)->tcp; - } - else return; - - tcpcli->toinact=toinact; - tcpcli->tirecon=tirecon; + * set timeout time + * args : stream_t *stream I stream (STR_TCPCLI,STR_NTRIPCLI,STR_NTRIPSVR) + * int toinact I inactive timeout (ms) (0: no timeout) + * int tirecon I reconnect interval (ms) (0: no reconnect) + * return : none + *-----------------------------------------------------------------------------*/ +extern void strsettimeout(stream_t *stream, int toinact, int tirecon) { + tcpcli_t *tcpcli; + + tracet(3, "strsettimeout: toinact=%d tirecon=%d\n", toinact, tirecon); + + if (stream->type == STR_TCPCLI) { + tcpcli = (tcpcli_t *)stream->port; + } else if (stream->type == STR_NTRIPCLI || stream->type == STR_NTRIPSVR) { + tcpcli = ((ntrip_t *)stream->port)->tcp; + } else + return; + + tcpcli->toinact = toinact; + tcpcli->tirecon = tirecon; } /* set local directory --------------------------------------------------------- -* set local directory path for ftp/http download -* args : char *dir I directory for download files -* return : none -*-----------------------------------------------------------------------------*/ -extern void strsetdir(const char *dir) -{ - tracet(3,"strsetdir: dir=%s\n",dir); - - strcpy(localdir,dir); + * set local directory path for ftp/http download + * args : char *dir I directory for download files + * return : none + *-----------------------------------------------------------------------------*/ +extern void strsetdir(const char *dir) { + tracet(3, "strsetdir: dir=%s\n", dir); + + strcpy(localdir, dir); } /* set http/ntrip proxy address ------------------------------------------------ -* set http/ntrip proxy address -* args : char *addr I http/ntrip proxy address
: -* return : none -*-----------------------------------------------------------------------------*/ -extern void strsetproxy(const char *addr) -{ - tracet(3,"strsetproxy: addr=%s\n",addr); - - strcpy(proxyaddr,addr); + * set http/ntrip proxy address + * args : char *addr I http/ntrip proxy address
: + * return : none + *-----------------------------------------------------------------------------*/ +extern void strsetproxy(const char *addr) { + tracet(3, "strsetproxy: addr=%s\n", addr); + + strcpy(proxyaddr, addr); } /* get stream time ------------------------------------------------------------- -* get stream time -* args : stream_t *stream I stream -* return : current time or replay time for playback file -*-----------------------------------------------------------------------------*/ -extern gtime_t strgettime(stream_t *stream) -{ - file_t *file; - if (stream->type==STR_FILE&&(stream->mode&STR_MODE_R)&& - (file=(file_t *)stream->port)) { - return timeadd(file->time,file->start); /* replay start time */ - } - return utc2gpst(timeget()); + * get stream time + * args : stream_t *stream I stream + * return : current time or replay time for playback file + *-----------------------------------------------------------------------------*/ +extern gtime_t strgettime(stream_t *stream) { + file_t *file; + if (stream->type == STR_FILE && (stream->mode & STR_MODE_R) && (file = (file_t *)stream->port)) { + return timeadd(file->time, file->start); /* replay start time */ + } + return utc2gpst(timeget()); } /* send nmea request ----------------------------------------------------------- -* send nmea gpgga message to stream -* args : stream_t *stream I stream -* sol_t *sol I solution -* return : none -*-----------------------------------------------------------------------------*/ -extern void strsendnmea(stream_t *stream, const sol_t *sol) -{ - uint8_t buff[1024]; - int n; - - tracet(3,"strsendnmea: rr=%.3f %.3f %.3f\n",sol->rr[0],sol->rr[1],sol->rr[2]); - - n=outnmea_gga(buff,sol); - strwrite(stream,buff,n); + * send nmea gpgga message to stream + * args : stream_t *stream I stream + * sol_t *sol I solution + * return : none + *-----------------------------------------------------------------------------*/ +extern void strsendnmea(stream_t *stream, const sol_t *sol) { + uint8_t buff[1024]; + int n; + + tracet(3, "strsendnmea: rr=%.3f %.3f %.3f\n", sol->rr[0], sol->rr[1], sol->rr[2]); + + n = outnmea_gga(buff, sol); + strwrite(stream, buff, n); } /* generate general hex message ----------------------------------------------*/ -static int gen_hex(const char *msg, uint8_t *buff) -{ - uint8_t *q=buff; - char mbuff[1024]="",*args[256],*p; - uint32_t byte; - int i,narg=0; - - trace(4,"gen_hex: msg=%s\n",msg); - - strncpy(mbuff,msg,1023); - char *r; - for (p=strtok_r(mbuff," ",&r);p&&narg<256;p=strtok_r(NULL," ",&r)) { - args[narg++]=p; - } - for (i=0;itype,mode=str->mode; - - if (type!=STR_SERIAL) return 0; - - strcpy(path,str->path); - - if (!(p=strchr(path,':'))) { - sprintf(path+strlen(path),":%d",brate); - } - else { - if ((q=strchr(p+1,':'))) strcpy(buff,q); - sprintf(p,":%d%s",brate,buff); - } - strclose(str); - return stropen(str,type,mode,path); +static int set_brate(stream_t *str, int brate) { + char path[1024], buff[1024] = "", *p, *q; + int type = str->type, mode = str->mode; + + if (type != STR_SERIAL) return 0; + + strcpy(path, str->path); + + if (!(p = strchr(path, ':'))) { + sprintf(path + strlen(path), ":%d", brate); + } else { + if ((q = strchr(p + 1, ':'))) strcpy(buff, q); + sprintf(p, ":%d%s", brate, buff); + } + strclose(str); + return stropen(str, type, mode, path); } /* send receiver command ------------------------------------------------------- -* send receiver commands to stream -* args : stream_t *stream I stream -* char *cmd I receiver command strings -* return : none -*-----------------------------------------------------------------------------*/ -extern void strsendcmd(stream_t *str, const char *cmd) -{ - uint8_t buff[1024]; - const char *p=cmd,*q; - char msg[1024],cmdend[]="\r\n"; - int n,m,ms,brate; - - tracet(3,"strsendcmd: cmd=%s\n",cmd); - - for (;;) { - for (q=p;;q++) if (*q=='\r'||*q=='\n'||*q=='\0') break; - n=(int)(q-p); strncpy(msg,p,n); msg[n]='\0'; - - if (!*msg||*msg=='#') { /* null or comment */ - ; - } - else if (*msg=='!') { /* binary escape */ - - if (!strncmp(msg+1,"WAIT",4)) { /* wait */ - if (sscanf(msg+5,"%d",&ms)<1) ms=100; - if (ms>3000) ms=3000; /* max 3 s */ - sleepms(ms); - } - else if (!strncmp(msg+1,"BRATE",5)) { /* set bitrate */ - if (sscanf(msg+6,"%d",&brate)<1) brate=115200; - set_brate(str,brate); - sleepms(500); - } - else if (!strncmp(msg+1,"UBX",3)) { /* ublox */ - if ((m=gen_ubx(msg+4,buff))>0) strwrite(str,buff,m); - } - else if (!strncmp(msg+1,"STQ",3)) { /* skytraq */ - if ((m=gen_stq(msg+4,buff))>0) strwrite(str,buff,m); - } - else if (!strncmp(msg+1,"NVS",3)) { /* nvs */ - if ((m=gen_nvs(msg+4,buff))>0) strwrite(str,buff,m); - } - else if (!strncmp(msg+1,"HEX",3)) { /* general hex message */ - if ((m=gen_hex(msg+4,buff))>0) strwrite(str,buff,m); - } - } - else { - strcat(msg,cmdend); - strwrite(str,(uint8_t *)msg,n+2); - } - if (*q=='\0') break; else p=q+1; - } + * send receiver commands to stream + * args : stream_t *stream I stream + * char *cmd I receiver command strings + * return : none + *-----------------------------------------------------------------------------*/ +extern void strsendcmd(stream_t *str, const char *cmd) { + uint8_t buff[1024]; + const char *p = cmd, *q; + char msg[1024], cmdend[] = "\r\n"; + int n, m, ms, brate; + + tracet(3, "strsendcmd: cmd=%s\n", cmd); + + for (;;) { + for (q = p;; q++) + if (*q == '\r' || *q == '\n' || *q == '\0') break; + n = (int)(q - p); + strncpy(msg, p, n); + msg[n] = '\0'; + + if (!*msg || *msg == '#') { /* null or comment */ + ; + } else if (*msg == '!') { /* binary escape */ + + if (!strncmp(msg + 1, "WAIT", 4)) { /* wait */ + if (sscanf(msg + 5, "%d", &ms) < 1) ms = 100; + if (ms > 3000) ms = 3000; /* max 3 s */ + sleepms(ms); + } else if (!strncmp(msg + 1, "BRATE", 5)) { /* set bitrate */ + if (sscanf(msg + 6, "%d", &brate) < 1) brate = 115200; + set_brate(str, brate); + sleepms(500); + } else if (!strncmp(msg + 1, "UBX", 3)) { /* ublox */ + if ((m = gen_ubx(msg + 4, buff)) > 0) strwrite(str, buff, m); + } else if (!strncmp(msg + 1, "STQ", 3)) { /* skytraq */ + if ((m = gen_stq(msg + 4, buff)) > 0) strwrite(str, buff, m); + } else if (!strncmp(msg + 1, "NVS", 3)) { /* nvs */ + if ((m = gen_nvs(msg + 4, buff)) > 0) strwrite(str, buff, m); + } else if (!strncmp(msg + 1, "HEX", 3)) { /* general hex message */ + if ((m = gen_hex(msg + 4, buff)) > 0) strwrite(str, buff, m); + } + } else { + strcat(msg, cmdend); + strwrite(str, (uint8_t *)msg, n + 2); + } + if (*q == '\0') + break; + else + p = q + 1; + } } diff --git a/src/streamsvr.c b/src/streamsvr.c index d7888189f..7544b3d60 100644 --- a/src/streamsvr.c +++ b/src/streamsvr.c @@ -1,486 +1,505 @@ /*------------------------------------------------------------------------------ -* streamsvr.c : stream server functions -* -* Copyright (C) 2010-2020 by T.TAKASU, All rights reserved. -* -* options : -DWIN32 use WIN32 API -* -* version : $Revision:$ $Date:$ -* history : 2010/07/18 1.0 moved from stream.c -* 2011/01/18 1.1 change api strsvrstart() -* 2012/12/04 1.2 add stream conversion function -* 2012/12/25 1.3 fix bug on cyclic navigation data output -* suppress warnings -* 2013/05/08 1.4 fix bug on 1 s offset for javad -> rtcm conversion -* 2014/10/16 1.5 support input from stdout -* 2015/12/05 1.6 support rtcm 3 mt 63 beidou ephemeris -* 2016/07/23 1.7 change api strsvrstart(),strsvrstop() -* support command for output streams -* 2016/08/20 1.8 support api change of sendnmea() -* 2016/09/03 1.9 support ntrip caster function -* 2016/09/06 1.10 add api strsvrsetsrctbl() -* 2016/09/17 1.11 add relay back function of output stream -* fix bug on rtcm cyclic output of beidou ephemeris -* 2016/10/01 1.12 change api startstrserver() -* 2017/04/11 1.13 fix bug on search of next satellite in nextsat() -* 2018/11/05 1.14 update message type of beidou ephemeirs -* support multiple msm messages if nsat x nsig > 64 -* 2020/11/30 1.15 support RTCM MT1131-1137,1041 (NavIC/IRNSS) -* add log paths in API strsvrstart() -* add log status in API strsvrstat() -* support multiple ephemeris sets (e.g. I/NAV-F/NAV) -* delete API strsvrsetsrctbl() -* use integer types in stdint.h -*-----------------------------------------------------------------------------*/ + * streamsvr.c : stream server functions + * + * Copyright (C) 2010-2020 by T.TAKASU, All rights reserved. + * + * options : -DWIN32 use WIN32 API + * + * version : $Revision:$ $Date:$ + * history : 2010/07/18 1.0 moved from stream.c + * 2011/01/18 1.1 change api strsvrstart() + * 2012/12/04 1.2 add stream conversion function + * 2012/12/25 1.3 fix bug on cyclic navigation data output + * suppress warnings + * 2013/05/08 1.4 fix bug on 1 s offset for javad -> rtcm conversion + * 2014/10/16 1.5 support input from stdout + * 2015/12/05 1.6 support rtcm 3 mt 63 beidou ephemeris + * 2016/07/23 1.7 change api strsvrstart(),strsvrstop() + * support command for output streams + * 2016/08/20 1.8 support api change of sendnmea() + * 2016/09/03 1.9 support ntrip caster function + * 2016/09/06 1.10 add api strsvrsetsrctbl() + * 2016/09/17 1.11 add relay back function of output stream + * fix bug on rtcm cyclic output of beidou ephemeris + * 2016/10/01 1.12 change api startstrserver() + * 2017/04/11 1.13 fix bug on search of next satellite in nextsat() + * 2018/11/05 1.14 update message type of beidou ephemeirs + * support multiple msm messages if nsat x nsig > 64 + * 2020/11/30 1.15 support RTCM MT1131-1137,1041 (NavIC/IRNSS) + * add log paths in API strsvrstart() + * add log status in API strsvrstat() + * support multiple ephemeris sets (e.g. I/NAV-F/NAV) + * delete API strsvrsetsrctbl() + * use integer types in stdint.h + *-----------------------------------------------------------------------------*/ #define _POSIX_C_SOURCE 199506 #include "rtklib.h" /* test observation data message ---------------------------------------------*/ -static int is_obsmsg(int msg) -{ - return (1001<=msg&&msg<=1004)||(1009<=msg&&msg<=1012)|| - (1071<=msg&&msg<=1077)||(1081<=msg&&msg<=1087)|| - (1091<=msg&&msg<=1097)||(1101<=msg&&msg<=1107)|| - (1111<=msg&&msg<=1117)||(1121<=msg&&msg<=1127)|| - (1131<=msg&&msg<=1137); +static int is_obsmsg(int msg) { + return (1001 <= msg && msg <= 1004) || (1009 <= msg && msg <= 1012) || + (1071 <= msg && msg <= 1077) || (1081 <= msg && msg <= 1087) || + (1091 <= msg && msg <= 1097) || (1101 <= msg && msg <= 1107) || + (1111 <= msg && msg <= 1117) || (1121 <= msg && msg <= 1127) || + (1131 <= msg && msg <= 1137); } /* test navigation data message ----------------------------------------------*/ -static int is_navmsg(int msg) -{ - return msg==1019||msg==1020||msg==1044||msg==1045||msg==1046|| - msg==1042||msg==63 ||msg==1041; +static int is_navmsg(int msg) { + return msg == 1019 || msg == 1020 || msg == 1044 || msg == 1045 || msg == 1046 || msg == 1042 || + msg == 63 || msg == 1041; } /* test station info message -------------------------------------------------*/ -static int is_stamsg(int msg) -{ - return msg==1005||msg==1006||msg==1007||msg==1008||msg==1033||msg==1230; +static int is_stamsg(int msg) { + return msg == 1005 || msg == 1006 || msg == 1007 || msg == 1008 || msg == 1033 || msg == 1230; } /* test time interval --------------------------------------------------------*/ -static int is_tint(gtime_t time, double tint) -{ - if (tint<=0.0) return 1; - return fmod(time2gpst(time,NULL)+DTTOL,tint)<=2.0*DTTOL; +static int is_tint(gtime_t time, double tint) { + if (tint <= 0.0) return 1; + return fmod(time2gpst(time, NULL) + DTTOL, tint) <= 2.0 * DTTOL; } /* new stream converter -------------------------------------------------------- -* generate new stream converter -* args : int itype I input stream type (STRFMT_???) -* int otype I output stream type (STRFMT_???) -* char *msgs I output message type and interval (, separated) -* int staid I station id -* int stasel I station info selection (0:remote,1:local) -* char *opt I rtcm or receiver raw options -* return : stream generator (NULL:error) -*-----------------------------------------------------------------------------*/ -extern strconv_t *strconvnew(int itype, int otype, const char *msgs, int staid, - int stasel, const char *opt) -{ - strconv_t *conv; - double tint; - char buff[1024],*p; - int msg; - - if (!(conv=(strconv_t *)malloc(sizeof(strconv_t)))) return NULL; - - conv->nmsg=0; - strcpy(buff,msgs); - char *q; - for (p=strtok_r(buff,",",&q);p;p=strtok_r(NULL,",",&q)) { - tint=0.0; - if (sscanf(p,"%d(%lf)",&msg,&tint)<1) continue; - conv->msgs[conv->nmsg]=msg; - conv->tint[conv->nmsg]=tint; - conv->tick[conv->nmsg]=tickget(); - conv->ephsat[conv->nmsg++]=0; - if (conv->nmsg>=32) break; - } - if (conv->nmsg<=0) { - free(conv); - return NULL; - } - conv->itype=itype; - conv->otype=otype; - conv->stasel=stasel; - if (!init_rtcm(&conv->rtcm)||!init_rtcm(&conv->out)) { - free(conv); - return NULL; - } - if (!init_raw(&conv->raw,itype)) { - free_rtcm(&conv->rtcm); - free_rtcm(&conv->out); - free(conv); - return NULL; - } - if (stasel) conv->out.staid=staid; - sprintf(conv->rtcm.opt,"-EPHALL %s",opt); - sprintf(conv->raw.opt ,"-EPHALL %s",opt); - return conv; -} -/* free stream converter ------------------------------------------------------- -* free stream converter -* args : strconv_t *conv IO stream converter -* return : none -*-----------------------------------------------------------------------------*/ -extern void strconvfree(strconv_t *conv) -{ - if (!conv) return; + * generate new stream converter + * args : int itype I input stream type (STRFMT_???) + * int otype I output stream type (STRFMT_???) + * char *msgs I output message type and interval (, separated) + * int staid I station id + * int stasel I station info selection (0:remote,1:local) + * char *opt I rtcm or receiver raw options + * return : stream generator (NULL:error) + *-----------------------------------------------------------------------------*/ +extern strconv_t *strconvnew(int itype, int otype, const char *msgs, int staid, int stasel, + const char *opt) { + strconv_t *conv; + double tint; + char buff[1024], *p; + int msg; + + if (!(conv = (strconv_t *)malloc(sizeof(strconv_t)))) return NULL; + + conv->nmsg = 0; + strcpy(buff, msgs); + char *q; + for (p = strtok_r(buff, ",", &q); p; p = strtok_r(NULL, ",", &q)) { + tint = 0.0; + if (sscanf(p, "%d(%lf)", &msg, &tint) < 1) continue; + conv->msgs[conv->nmsg] = msg; + conv->tint[conv->nmsg] = tint; + conv->tick[conv->nmsg] = tickget(); + conv->ephsat[conv->nmsg++] = 0; + if (conv->nmsg >= 32) break; + } + if (conv->nmsg <= 0) { + free(conv); + return NULL; + } + conv->itype = itype; + conv->otype = otype; + conv->stasel = stasel; + if (!init_rtcm(&conv->rtcm) || !init_rtcm(&conv->out)) { + free(conv); + return NULL; + } + if (!init_raw(&conv->raw, itype)) { free_rtcm(&conv->rtcm); free_rtcm(&conv->out); - free_raw(&conv->raw); free(conv); + return NULL; + } + if (stasel) conv->out.staid = staid; + sprintf(conv->rtcm.opt, "-EPHALL %s", opt); + sprintf(conv->raw.opt, "-EPHALL %s", opt); + return conv; +} +/* free stream converter ------------------------------------------------------- + * free stream converter + * args : strconv_t *conv IO stream converter + * return : none + *-----------------------------------------------------------------------------*/ +extern void strconvfree(strconv_t *conv) { + if (!conv) return; + free_rtcm(&conv->rtcm); + free_rtcm(&conv->out); + free_raw(&conv->raw); + free(conv); } /* copy received data from receiver raw to rtcm ------------------------------*/ -static void raw2rtcm(rtcm_t *out, const raw_t *raw, int ret) -{ - int i,sat,set,sys,prn; - - out->time=raw->time; - - if (ret==1) { - for (i=0;iobs.n;i++) { - out->time=raw->obs.data[i].time; - out->obs.data[i]=raw->obs.data[i]; - - sys=satsys(raw->obs.data[i].sat,&prn); - if (sys==SYS_GLO&&raw->nav.glo_fcn[prn-1]) { - out->nav.glo_fcn[prn-1]=raw->nav.glo_fcn[prn-1]; - } - } - out->obs.n=raw->obs.n; - } - else if (ret==2) { - sat=raw->ephsat; - set=raw->ephset; - sys=satsys(sat,&prn); - if (sys==SYS_GLO) { - out->nav.geph[prn-1]=raw->nav.geph[prn-1]; - out->ephsat=sat; - out->ephset=set; - } - else if (sys==SYS_GPS||sys==SYS_GAL||sys==SYS_QZS||sys==SYS_CMP|| - sys==SYS_IRN) { - out->nav.eph[sat-1+MAXSAT*set]=raw->nav.eph[sat-1+MAXSAT*set]; - out->ephsat=sat; - out->ephset=set; - } - } - else if (ret==5) { - out->sta=raw->sta; - } - else if (ret==9) { - matcpy(out->nav.utc_gps,raw->nav.utc_gps,8,1); - matcpy(out->nav.utc_glo,raw->nav.utc_glo,8,1); - matcpy(out->nav.utc_gal,raw->nav.utc_gal,8,1); - matcpy(out->nav.utc_qzs,raw->nav.utc_qzs,8,1); - matcpy(out->nav.utc_cmp,raw->nav.utc_cmp,8,1); - matcpy(out->nav.utc_irn,raw->nav.utc_irn,9,1); - matcpy(out->nav.utc_sbs,raw->nav.utc_sbs,4,1); - matcpy(out->nav.ion_gps,raw->nav.ion_gps,8,1); - matcpy(out->nav.ion_gal,raw->nav.ion_gal,4,1); - matcpy(out->nav.ion_qzs,raw->nav.ion_qzs,8,1); - matcpy(out->nav.ion_cmp,raw->nav.ion_cmp,8,1); - matcpy(out->nav.ion_irn,raw->nav.ion_irn,8,1); - } +static void raw2rtcm(rtcm_t *out, const raw_t *raw, int ret) { + int i, sat, set, sys, prn; + + out->time = raw->time; + + if (ret == 1) { + for (i = 0; i < raw->obs.n; i++) { + out->time = raw->obs.data[i].time; + out->obs.data[i] = raw->obs.data[i]; + + sys = satsys(raw->obs.data[i].sat, &prn); + if (sys == SYS_GLO && raw->nav.glo_fcn[prn - 1]) { + out->nav.glo_fcn[prn - 1] = raw->nav.glo_fcn[prn - 1]; + } + } + out->obs.n = raw->obs.n; + } else if (ret == 2) { + sat = raw->ephsat; + set = raw->ephset; + sys = satsys(sat, &prn); + if (sys == SYS_GLO) { + out->nav.geph[prn - 1] = raw->nav.geph[prn - 1]; + out->ephsat = sat; + out->ephset = set; + } else if (sys == SYS_GPS || sys == SYS_GAL || sys == SYS_QZS || sys == SYS_CMP || + sys == SYS_IRN) { + out->nav.eph[sat - 1 + MAXSAT * set] = raw->nav.eph[sat - 1 + MAXSAT * set]; + out->ephsat = sat; + out->ephset = set; + } + } else if (ret == 5) { + out->sta = raw->sta; + } else if (ret == 9) { + matcpy(out->nav.utc_gps, raw->nav.utc_gps, 8, 1); + matcpy(out->nav.utc_glo, raw->nav.utc_glo, 8, 1); + matcpy(out->nav.utc_gal, raw->nav.utc_gal, 8, 1); + matcpy(out->nav.utc_qzs, raw->nav.utc_qzs, 8, 1); + matcpy(out->nav.utc_cmp, raw->nav.utc_cmp, 8, 1); + matcpy(out->nav.utc_irn, raw->nav.utc_irn, 9, 1); + matcpy(out->nav.utc_sbs, raw->nav.utc_sbs, 4, 1); + matcpy(out->nav.ion_gps, raw->nav.ion_gps, 8, 1); + matcpy(out->nav.ion_gal, raw->nav.ion_gal, 4, 1); + matcpy(out->nav.ion_qzs, raw->nav.ion_qzs, 8, 1); + matcpy(out->nav.ion_cmp, raw->nav.ion_cmp, 8, 1); + matcpy(out->nav.ion_irn, raw->nav.ion_irn, 8, 1); + } } /* copy received data from receiver rtcm to rtcm -----------------------------*/ -static void rtcm2rtcm(rtcm_t *out, const rtcm_t *rtcm, int ret, int stasel) -{ - int i,sat,set,sys,prn; - - out->time=rtcm->time; - - if (!stasel) out->staid=rtcm->staid; - - if (ret==1) { - for (i=0;iobs.n;i++) { - out->obs.data[i]=rtcm->obs.data[i]; - - sys=satsys(rtcm->obs.data[i].sat,&prn); - if (sys==SYS_GLO&&rtcm->nav.glo_fcn[prn-1]) { - out->nav.glo_fcn[prn-1]=rtcm->nav.glo_fcn[prn-1]; - } - } - out->obs.n=rtcm->obs.n; - } - else if (ret==2) { - sat=rtcm->ephsat; - set=rtcm->ephset; - sys=satsys(sat,&prn); - if (sys==SYS_GLO) { - out->nav.geph[prn-1]=rtcm->nav.geph[prn-1]; - out->ephsat=sat; - out->ephset=set; - } - else if (sys==SYS_GPS||sys==SYS_GAL||sys==SYS_QZS||sys==SYS_CMP|| - sys==SYS_IRN) { - out->nav.eph[sat-1+MAXSAT*set]=rtcm->nav.eph[sat-1+MAXSAT*set]; - out->ephsat=sat; - out->ephset=set; - } - } - else if (ret==5) { - if (!stasel) out->sta=rtcm->sta; - } +static void rtcm2rtcm(rtcm_t *out, const rtcm_t *rtcm, int ret, int stasel) { + int i, sat, set, sys, prn; + + out->time = rtcm->time; + + if (!stasel) out->staid = rtcm->staid; + + if (ret == 1) { + for (i = 0; i < rtcm->obs.n; i++) { + out->obs.data[i] = rtcm->obs.data[i]; + + sys = satsys(rtcm->obs.data[i].sat, &prn); + if (sys == SYS_GLO && rtcm->nav.glo_fcn[prn - 1]) { + out->nav.glo_fcn[prn - 1] = rtcm->nav.glo_fcn[prn - 1]; + } + } + out->obs.n = rtcm->obs.n; + } else if (ret == 2) { + sat = rtcm->ephsat; + set = rtcm->ephset; + sys = satsys(sat, &prn); + if (sys == SYS_GLO) { + out->nav.geph[prn - 1] = rtcm->nav.geph[prn - 1]; + out->ephsat = sat; + out->ephset = set; + } else if (sys == SYS_GPS || sys == SYS_GAL || sys == SYS_QZS || sys == SYS_CMP || + sys == SYS_IRN) { + out->nav.eph[sat - 1 + MAXSAT * set] = rtcm->nav.eph[sat - 1 + MAXSAT * set]; + out->ephsat = sat; + out->ephset = set; + } + } else if (ret == 5) { + if (!stasel) out->sta = rtcm->sta; + } } /* write rtcm3 msm to stream -------------------------------------------------*/ -static void write_rtcm3_msm(stream_t *str, rtcm_t *out, int msg, int sync) -{ - obsd_t *data,buff[MAXOBS]; - int i,j,n,ns,sys,nobs,code,nsat=0,nsig=0,nmsg,mask[MAXCODE]={0}; - - if (1071<=msg&&msg<=1077) sys=SYS_GPS; - else if (1081<=msg&&msg<=1087) sys=SYS_GLO; - else if (1091<=msg&&msg<=1097) sys=SYS_GAL; - else if (1101<=msg&&msg<=1107) sys=SYS_SBS; - else if (1111<=msg&&msg<=1117) sys=SYS_QZS; - else if (1121<=msg&&msg<=1127) sys=SYS_CMP; - else if (1131<=msg&&msg<=1137) sys=SYS_IRN; - else return; - - data=out->obs.data; - nobs=out->obs.n; - - /* count number of satellites and signals */ - for (i=0;i64) return; - - /* pack data to multiple messages if nsat x nsig > 64 */ - if (nsig>0) { - ns=64/nsig; /* max number of sats in a message */ - nmsg=(nsat-1)/ns+1; /* number of messages */ - } - else { - ns=0; - nmsg=1; +static void write_rtcm3_msm(stream_t *str, rtcm_t *out, int msg, int sync) { + obsd_t *data, buff[MAXOBS]; + int i, j, n, ns, sys, nobs, code, nsat = 0, nsig = 0, nmsg, mask[MAXCODE] = {0}; + + if (1071 <= msg && msg <= 1077) + sys = SYS_GPS; + else if (1081 <= msg && msg <= 1087) + sys = SYS_GLO; + else if (1091 <= msg && msg <= 1097) + sys = SYS_GAL; + else if (1101 <= msg && msg <= 1107) + sys = SYS_SBS; + else if (1111 <= msg && msg <= 1117) + sys = SYS_QZS; + else if (1121 <= msg && msg <= 1127) + sys = SYS_CMP; + else if (1131 <= msg && msg <= 1137) + sys = SYS_IRN; + else + return; + + data = out->obs.data; + nobs = out->obs.n; + + /* count number of satellites and signals */ + for (i = 0; i < nobs && i < MAXOBS; i++) { + if (satsys(data[i].sat, NULL) != sys) continue; + nsat++; + for (j = 0; j < NFREQ + NEXOBS; j++) { + if (!(code = data[i].code[j]) || mask[code - 1]) continue; + mask[code - 1] = 1; + nsig++; + } + } + if (nsig > 64) return; + + /* pack data to multiple messages if nsat x nsig > 64 */ + if (nsig > 0) { + ns = 64 / nsig; /* max number of sats in a message */ + nmsg = (nsat - 1) / ns + 1; /* number of messages */ + } else { + ns = 0; + nmsg = 1; + } + out->obs.data = buff; + + for (i = j = 0; i < nmsg; i++) { + for (n = 0; n < ns && j < nobs && j < MAXOBS; j++) { + if (satsys(data[j].sat, NULL) != sys) continue; + out->obs.data[n++] = data[j]; } - out->obs.data=buff; - - for (i=j=0;iobs.data[n++]=data[j]; - } - out->obs.n=n; - - if (gen_rtcm3(out,msg,0,ibuff,out->nbyte); - } + out->obs.n = n; + + if (gen_rtcm3(out, msg, 0, i < nmsg - 1 ? 1 : sync)) { + strwrite(str, out->buff, out->nbyte); } - out->obs.data=data; - out->obs.n=nobs; + } + out->obs.data = data; + out->obs.n = nobs; } /* write obs data messages ---------------------------------------------------*/ -static void write_obs(gtime_t time, stream_t *str, strconv_t *conv) -{ - int i,j=0; - - for (i=0;inmsg;i++) { - if (!is_obsmsg(conv->msgs[i])||!is_tint(time,conv->tint[i])) continue; - - j=i; /* index of last message */ - } - for (i=0;inmsg;i++) { - if (!is_obsmsg(conv->msgs[i])||!is_tint(time,conv->tint[i])) continue; - - /* generate messages */ - if (conv->otype==STRFMT_RTCM2) { - if (!gen_rtcm2(&conv->out,conv->msgs[i],i!=j)) continue; - - /* write messages to stream */ - strwrite(str,conv->out.buff,conv->out.nbyte); - } - else if (conv->otype==STRFMT_RTCM3) { - if (conv->msgs[i]<=1012) { - if (!gen_rtcm3(&conv->out,conv->msgs[i],0,i!=j)) continue; - strwrite(str,conv->out.buff,conv->out.nbyte); - } - else { /* write rtcm3 msm to stream */ - write_rtcm3_msm(str,&conv->out,conv->msgs[i],i!=j); - } - } - } +static void write_obs(gtime_t time, stream_t *str, strconv_t *conv) { + int i, j = 0; + + for (i = 0; i < conv->nmsg; i++) { + if (!is_obsmsg(conv->msgs[i]) || !is_tint(time, conv->tint[i])) continue; + + j = i; /* index of last message */ + } + for (i = 0; i < conv->nmsg; i++) { + if (!is_obsmsg(conv->msgs[i]) || !is_tint(time, conv->tint[i])) continue; + + /* generate messages */ + if (conv->otype == STRFMT_RTCM2) { + if (!gen_rtcm2(&conv->out, conv->msgs[i], i != j)) continue; + + /* write messages to stream */ + strwrite(str, conv->out.buff, conv->out.nbyte); + } else if (conv->otype == STRFMT_RTCM3) { + if (conv->msgs[i] <= 1012) { + if (!gen_rtcm3(&conv->out, conv->msgs[i], 0, i != j)) continue; + strwrite(str, conv->out.buff, conv->out.nbyte); + } else { /* write rtcm3 msm to stream */ + write_rtcm3_msm(str, &conv->out, conv->msgs[i], i != j); + } + } + } } /* write nav data messages ---------------------------------------------------*/ -static void write_nav(gtime_t time, stream_t *str, strconv_t *conv) -{ - (void)time; - int i; - - for (i=0;inmsg;i++) { - if (!is_navmsg(conv->msgs[i])||conv->tint[i]>0.0) continue; - - /* generate messages */ - if (conv->otype==STRFMT_RTCM2) { - if (!gen_rtcm2(&conv->out,conv->msgs[i],0)) continue; - } - else if (conv->otype==STRFMT_RTCM3) { - if (!gen_rtcm3(&conv->out,conv->msgs[i],0,0)) continue; - } - else continue; - - /* write messages to stream */ - strwrite(str,conv->out.buff,conv->out.nbyte); - } +static void write_nav(gtime_t time, stream_t *str, strconv_t *conv) { + (void)time; + int i; + + for (i = 0; i < conv->nmsg; i++) { + if (!is_navmsg(conv->msgs[i]) || conv->tint[i] > 0.0) continue; + + /* generate messages */ + if (conv->otype == STRFMT_RTCM2) { + if (!gen_rtcm2(&conv->out, conv->msgs[i], 0)) continue; + } else if (conv->otype == STRFMT_RTCM3) { + if (!gen_rtcm3(&conv->out, conv->msgs[i], 0, 0)) continue; + } else + continue; + + /* write messages to stream */ + strwrite(str, conv->out.buff, conv->out.nbyte); + } } /* next ephemeris satellite --------------------------------------------------*/ -static int nextsat(nav_t *nav, int sat, int msg) -{ - int sys,set,p,p0,p1,p2; - - switch (msg) { - case 1019: sys=SYS_GPS; set=0; p1=MINPRNGPS; p2=MAXPRNGPS; break; - case 1020: sys=SYS_GLO; set=0; p1=MINPRNGLO; p2=MAXPRNGLO; break; - case 1044: sys=SYS_QZS; set=0; p1=MINPRNQZS; p2=MAXPRNQZS; break; - case 1045: sys=SYS_GAL; set=1; p1=MINPRNGAL; p2=MAXPRNGAL; break; - case 1046: sys=SYS_GAL; set=0; p1=MINPRNGAL; p2=MAXPRNGAL; break; - case 63: - case 1042: sys=SYS_CMP; set=0; p1=MINPRNCMP; p2=MAXPRNCMP; break; - case 1041: sys=SYS_IRN; set=0; p1=MINPRNIRN; p2=MAXPRNIRN; break; - default: return 0; - } - if (satsys(sat,&p0)!=sys) return satno(sys,p1); - - /* search next valid ephemeris */ - for (p=p0>=p2?p1:p0+1;p!=p0;p=p>=p2?p1:p+1) { - - if (sys==SYS_GLO) { - sat=satno(sys,p); - if (nav->geph[p-1].sat==sat) return sat; - } - else { - sat=satno(sys,p); - if (nav->eph[sat-1+MAXSAT*set].sat==sat) return sat; - } - } - return 0; +static int nextsat(nav_t *nav, int sat, int msg) { + int sys, set, p, p0, p1, p2; + + switch (msg) { + case 1019: + sys = SYS_GPS; + set = 0; + p1 = MINPRNGPS; + p2 = MAXPRNGPS; + break; + case 1020: + sys = SYS_GLO; + set = 0; + p1 = MINPRNGLO; + p2 = MAXPRNGLO; + break; + case 1044: + sys = SYS_QZS; + set = 0; + p1 = MINPRNQZS; + p2 = MAXPRNQZS; + break; + case 1045: + sys = SYS_GAL; + set = 1; + p1 = MINPRNGAL; + p2 = MAXPRNGAL; + break; + case 1046: + sys = SYS_GAL; + set = 0; + p1 = MINPRNGAL; + p2 = MAXPRNGAL; + break; + case 63: + case 1042: + sys = SYS_CMP; + set = 0; + p1 = MINPRNCMP; + p2 = MAXPRNCMP; + break; + case 1041: + sys = SYS_IRN; + set = 0; + p1 = MINPRNIRN; + p2 = MAXPRNIRN; + break; + default: + return 0; + } + if (satsys(sat, &p0) != sys) return satno(sys, p1); + + /* search next valid ephemeris */ + for (p = p0 >= p2 ? p1 : p0 + 1; p != p0; p = p >= p2 ? p1 : p + 1) { + if (sys == SYS_GLO) { + sat = satno(sys, p); + if (nav->geph[p - 1].sat == sat) return sat; + } else { + sat = satno(sys, p); + if (nav->eph[sat - 1 + MAXSAT * set].sat == sat) return sat; + } + } + return 0; } /* write cyclic nav data messages --------------------------------------------*/ -static void write_nav_cycle(stream_t *str, strconv_t *conv) -{ - uint32_t tick=tickget(); - int i,sat,tint; - - for (i=0;inmsg;i++) { - if (!is_navmsg(conv->msgs[i])||conv->tint[i]<=0.0) continue; - - /* output cycle */ - tint=(int)(conv->tint[i]*1000.0); - if ((int)(tick-conv->tick[i])tick[i]=tick; - - /* next satellite */ - if (!(sat=nextsat(&conv->out.nav,conv->ephsat[i],conv->msgs[i]))) { - continue; - } - conv->out.ephsat=conv->ephsat[i]=sat; - - /* generate messages */ - if (conv->otype==STRFMT_RTCM2) { - if (!gen_rtcm2(&conv->out,conv->msgs[i],0)) continue; - } - else if (conv->otype==STRFMT_RTCM3) { - if (!gen_rtcm3(&conv->out,conv->msgs[i],0,0)) continue; - } - else continue; - - /* write messages to stream */ - strwrite(str,conv->out.buff,conv->out.nbyte); +static void write_nav_cycle(stream_t *str, strconv_t *conv) { + uint32_t tick = tickget(); + int i, sat, tint; + + for (i = 0; i < conv->nmsg; i++) { + if (!is_navmsg(conv->msgs[i]) || conv->tint[i] <= 0.0) continue; + + /* output cycle */ + tint = (int)(conv->tint[i] * 1000.0); + if ((int)(tick - conv->tick[i]) < tint) continue; + conv->tick[i] = tick; + + /* next satellite */ + if (!(sat = nextsat(&conv->out.nav, conv->ephsat[i], conv->msgs[i]))) { + continue; } + conv->out.ephsat = conv->ephsat[i] = sat; + + /* generate messages */ + if (conv->otype == STRFMT_RTCM2) { + if (!gen_rtcm2(&conv->out, conv->msgs[i], 0)) continue; + } else if (conv->otype == STRFMT_RTCM3) { + if (!gen_rtcm3(&conv->out, conv->msgs[i], 0, 0)) continue; + } else + continue; + + /* write messages to stream */ + strwrite(str, conv->out.buff, conv->out.nbyte); + } } /* write cyclic station info messages ----------------------------------------*/ -static void write_sta_cycle(stream_t *str, strconv_t *conv) -{ - uint32_t tick=tickget(); - int i,tint; - - for (i=0;inmsg;i++) { - if (!is_stamsg(conv->msgs[i])) continue; - - /* output cycle */ - tint=conv->tint[i]==0.0?30000:(int)(conv->tint[i]*1000.0); - if ((int)(tick-conv->tick[i])tick[i]=tick; - - /* generate messages */ - if (conv->otype==STRFMT_RTCM2) { - if (!gen_rtcm2(&conv->out,conv->msgs[i],0)) continue; - } - else if (conv->otype==STRFMT_RTCM3) { - if (!gen_rtcm3(&conv->out,conv->msgs[i],0,0)) continue; - } - else continue; - - /* write messages to stream */ - strwrite(str,conv->out.buff,conv->out.nbyte); - } +static void write_sta_cycle(stream_t *str, strconv_t *conv) { + uint32_t tick = tickget(); + int i, tint; + + for (i = 0; i < conv->nmsg; i++) { + if (!is_stamsg(conv->msgs[i])) continue; + + /* output cycle */ + tint = conv->tint[i] == 0.0 ? 30000 : (int)(conv->tint[i] * 1000.0); + if ((int)(tick - conv->tick[i]) < tint) continue; + conv->tick[i] = tick; + + /* generate messages */ + if (conv->otype == STRFMT_RTCM2) { + if (!gen_rtcm2(&conv->out, conv->msgs[i], 0)) continue; + } else if (conv->otype == STRFMT_RTCM3) { + if (!gen_rtcm3(&conv->out, conv->msgs[i], 0, 0)) continue; + } else + continue; + + /* write messages to stream */ + strwrite(str, conv->out.buff, conv->out.nbyte); + } } /* convert stearm ------------------------------------------------------------*/ -static void strconv(stream_t *str, strconv_t *conv, uint8_t *buff, int n) -{ - int i,ret; - - for (i=0;iitype==STRFMT_RTCM2) { - ret=input_rtcm2(&conv->rtcm,buff[i]); - rtcm2rtcm(&conv->out,&conv->rtcm,ret,conv->stasel); - } - /* input rtcm 3 messages */ - else if (conv->itype==STRFMT_RTCM3) { - ret=input_rtcm3(&conv->rtcm,buff[i]); - rtcm2rtcm(&conv->out,&conv->rtcm,ret,conv->stasel); - } - /* input receiver raw messages */ - else { - ret=input_raw(&conv->raw,conv->itype,buff[i]); - raw2rtcm(&conv->out,&conv->raw,ret); - } - /* write obs and nav data messages to stream */ - switch (ret) { - case 1: write_obs(conv->out.time,str,conv); break; - case 2: write_nav(conv->out.time,str,conv); break; - } - } - /* write cyclic nav data and station info messages to stream */ - write_nav_cycle(str,conv); - write_sta_cycle(str,conv); +static void strconv(stream_t *str, strconv_t *conv, uint8_t *buff, int n) { + int i, ret; + + for (i = 0; i < n; i++) { + /* input rtcm 2 messages */ + if (conv->itype == STRFMT_RTCM2) { + ret = input_rtcm2(&conv->rtcm, buff[i]); + rtcm2rtcm(&conv->out, &conv->rtcm, ret, conv->stasel); + } + /* input rtcm 3 messages */ + else if (conv->itype == STRFMT_RTCM3) { + ret = input_rtcm3(&conv->rtcm, buff[i]); + rtcm2rtcm(&conv->out, &conv->rtcm, ret, conv->stasel); + } + /* input receiver raw messages */ + else { + ret = input_raw(&conv->raw, conv->itype, buff[i]); + raw2rtcm(&conv->out, &conv->raw, ret); + } + /* write obs and nav data messages to stream */ + switch (ret) { + case 1: + write_obs(conv->out.time, str, conv); + break; + case 2: + write_nav(conv->out.time, str, conv); + break; + } + } + /* write cyclic nav data and station info messages to stream */ + write_nav_cycle(str, conv); + write_sta_cycle(str, conv); } /* periodic command ----------------------------------------------------------*/ -static void periodic_cmd(int cycle, const char *cmd, stream_t *stream) -{ - const char *p=cmd,*q; - char msg[1024],*r; - int n,period; - - for (p=cmd;;p=q+1) { - for (q=p;;q++) if (*q=='\r'||*q=='\n'||*q=='\0') break; - n=(int)(q-p); strncpy(msg,p,n); msg[n]='\0'; - - period=0; - if ((r=strrchr(msg,'#'))) { - sscanf(r,"# %d",&period); - size_t end=r-msg; - msg[end]='\0'; - /* Delete tailing spaces */ - while (end>0) { - if (msg[end-1]!=' ') break; - msg[--end]='\0'; - } - } - if (period<=0) period=1000; - if (*msg&&cycle%period==0) { - strsendcmd(stream,msg); - } - if (!*q) break; - } +static void periodic_cmd(int cycle, const char *cmd, stream_t *stream) { + const char *p = cmd, *q; + char msg[1024], *r; + int n, period; + + for (p = cmd;; p = q + 1) { + for (q = p;; q++) + if (*q == '\r' || *q == '\n' || *q == '\0') break; + n = (int)(q - p); + strncpy(msg, p, n); + msg[n] = '\0'; + + period = 0; + if ((r = strrchr(msg, '#'))) { + sscanf(r, "# %d", &period); + size_t end = r - msg; + msg[end] = '\0'; + /* Delete tailing spaces */ + while (end > 0) { + if (msg[end - 1] != ' ') break; + msg[--end] = '\0'; + } + } + if (period <= 0) period = 1000; + if (*msg && cycle % period == 0) { + strsendcmd(stream, msg); + } + if (!*q) break; + } } /* stearm server thread ------------------------------------------------------*/ #ifdef WIN32 @@ -489,321 +508,316 @@ static DWORD WINAPI strsvrthread(void *arg) static void *strsvrthread(void *arg) #endif { - strsvr_t *svr=(strsvr_t *)arg; - sol_t sol_nmea={{0}}; - uint32_t tick,tick_nmea; - uint8_t buff[1024]; - int i,n,cyc; - - tracet(3,"strsvrthread:\n"); - - svr->tick=tickget(); - tick_nmea=svr->tick-1000; - - for (cyc=0;svr->state;cyc++) { - tick=tickget(); - - /* read data from input stream */ - while ((n=strread(svr->stream,svr->buff,svr->buffsize))>0&&svr->state) { - - /* write data to output streams */ - for (i=1;instr;i++) { - if (svr->conv[i-1]) { - strconv(svr->stream+i,svr->conv[i-1],svr->buff,n); - } - else { - strwrite(svr->stream+i,svr->buff,n); - } - } - /* write data to log stream */ - strwrite(svr->strlog,svr->buff,n); - - rtklib_lock(&svr->lock); - for (i=0;inpbbuffsize;i++) { - svr->pbuf[svr->npb++]=svr->buff[i]; - } - rtklib_unlock(&svr->lock); - } - for (i=1;instr;i++) { - - /* read message from output stream if connected */ - while (strstat(svr->stream+i,NULL)>=2 && - (n=strread(svr->stream+i,buff,sizeof(buff)))>0) { - /* relay back message from output stream to input stream */ - if (i==svr->relayback) { - strwrite(svr->stream,buff,n); - } - /* write data to log stream */ - strwrite(svr->strlog+i,buff,n); - } - } - /* write periodic command to input stream */ - for (i=0;instr;i++) { - periodic_cmd(cyc*svr->cycle,svr->cmds_periodic[i],svr->stream+i); - } - /* write nmea messages to input stream */ - if (svr->nmeacycle>0&&(int)(tick-tick_nmea)>=svr->nmeacycle) { - sol_nmea.stat=SOLQ_SINGLE; - sol_nmea.ns=10; /* Some servers don't like when ns = 0 */ - sol_nmea.time=utc2gpst(timeget()); - matcpy(sol_nmea.rr,svr->nmeapos,3,1); - strsendnmea(svr->stream,&sol_nmea); - tick_nmea=tick; - } - sleepms(svr->cycle-(int)(tickget()-tick)); - } - for (i=0;instr;i++) strclose(svr->stream+i); - for (i=0;instr;i++) strclose(svr->strlog+i); - svr->npb=0; - free(svr->buff); svr->buff=NULL; - free(svr->pbuf); svr->pbuf=NULL; - - return 0; + strsvr_t *svr = (strsvr_t *)arg; + sol_t sol_nmea = {{0}}; + uint32_t tick, tick_nmea; + uint8_t buff[1024]; + int i, n, cyc; + + tracet(3, "strsvrthread:\n"); + + svr->tick = tickget(); + tick_nmea = svr->tick - 1000; + + for (cyc = 0; svr->state; cyc++) { + tick = tickget(); + + /* read data from input stream */ + while ((n = strread(svr->stream, svr->buff, svr->buffsize)) > 0 && svr->state) { + /* write data to output streams */ + for (i = 1; i < svr->nstr; i++) { + if (svr->conv[i - 1]) { + strconv(svr->stream + i, svr->conv[i - 1], svr->buff, n); + } else { + strwrite(svr->stream + i, svr->buff, n); + } + } + /* write data to log stream */ + strwrite(svr->strlog, svr->buff, n); + + rtklib_lock(&svr->lock); + for (i = 0; i < n && svr->npb < svr->buffsize; i++) { + svr->pbuf[svr->npb++] = svr->buff[i]; + } + rtklib_unlock(&svr->lock); + } + for (i = 1; i < svr->nstr; i++) { + /* read message from output stream if connected */ + while (strstat(svr->stream + i, NULL) >= 2 && + (n = strread(svr->stream + i, buff, sizeof(buff))) > 0) { + /* relay back message from output stream to input stream */ + if (i == svr->relayback) { + strwrite(svr->stream, buff, n); + } + /* write data to log stream */ + strwrite(svr->strlog + i, buff, n); + } + } + /* write periodic command to input stream */ + for (i = 0; i < svr->nstr; i++) { + periodic_cmd(cyc * svr->cycle, svr->cmds_periodic[i], svr->stream + i); + } + /* write nmea messages to input stream */ + if (svr->nmeacycle > 0 && (int)(tick - tick_nmea) >= svr->nmeacycle) { + sol_nmea.stat = SOLQ_SINGLE; + sol_nmea.ns = 10; /* Some servers don't like when ns = 0 */ + sol_nmea.time = utc2gpst(timeget()); + matcpy(sol_nmea.rr, svr->nmeapos, 3, 1); + strsendnmea(svr->stream, &sol_nmea); + tick_nmea = tick; + } + sleepms(svr->cycle - (int)(tickget() - tick)); + } + for (i = 0; i < svr->nstr; i++) strclose(svr->stream + i); + for (i = 0; i < svr->nstr; i++) strclose(svr->strlog + i); + svr->npb = 0; + free(svr->buff); + svr->buff = NULL; + free(svr->pbuf); + svr->pbuf = NULL; + + return 0; } /* initialize stream server ---------------------------------------------------- -* initialize stream server -* args : strsvr_t *svr IO stream sever struct -* int nout I number of output streams -* return : none -*-----------------------------------------------------------------------------*/ -extern void strsvrinit(strsvr_t *svr, int nout) -{ - int i; - - tracet(3,"strsvrinit: nout=%d\n",nout); - - svr->state=0; - svr->cycle=0; - svr->buffsize=0; - svr->nmeacycle=0; - svr->relayback=0; - svr->npb=0; - for (i=0;i<16;i++) *svr->cmds_periodic[i]='\0'; - for (i=0;i<3;i++) svr->nmeapos[i]=0.0; - svr->buff=svr->pbuf=NULL; - svr->tick=0; - for (i=0;istream+i); - for (i=0;istrlog+i); - svr->nstr=i; - for (i=0;i<16;i++) svr->conv[i]=NULL; - svr->thread=0; - rtklib_initlock(&svr->lock); + * initialize stream server + * args : strsvr_t *svr IO stream sever struct + * int nout I number of output streams + * return : none + *-----------------------------------------------------------------------------*/ +extern void strsvrinit(strsvr_t *svr, int nout) { + int i; + + tracet(3, "strsvrinit: nout=%d\n", nout); + + svr->state = 0; + svr->cycle = 0; + svr->buffsize = 0; + svr->nmeacycle = 0; + svr->relayback = 0; + svr->npb = 0; + for (i = 0; i < 16; i++) *svr->cmds_periodic[i] = '\0'; + for (i = 0; i < 3; i++) svr->nmeapos[i] = 0.0; + svr->buff = svr->pbuf = NULL; + svr->tick = 0; + for (i = 0; i < nout + 1 && i < 16; i++) strinit(svr->stream + i); + for (i = 0; i < nout + 1 && i < 16; i++) strinit(svr->strlog + i); + svr->nstr = i; + for (i = 0; i < 16; i++) svr->conv[i] = NULL; + svr->thread = 0; + rtklib_initlock(&svr->lock); } /* start stream server --------------------------------------------------------- -* start stream server -* args : strsvr_t *svr IO stream sever struct -* int *opts I stream options -* opts[0]= inactive timeout (ms) -* opts[1]= interval to reconnect (ms) -* opts[2]= averaging time of data rate (ms) -* opts[3]= receive/send buffer size (bytes); -* opts[4]= server cycle (ms) -* opts[5]= nmea request cycle (ms) (0:no) -* opts[6]= file swap margin (s) -* opts[7]= relay back of output stream (0:no) -* int *strs I stream types (STR_???) -* strs[0]= input stream -* strs[1]= output stream 1 -* strs[2]= output stream 2 -* strs[3]= output stream 3 -* ... -* char **paths I stream paths -* paths[0]= input stream -* paths[1]= output stream 1 -* paths[2]= output stream 2 -* paths[3]= output stream 3 -* ... -* char **logs I log paths -* logs[0]= input log path -* logs[1]= output stream 1 return log path -* logs[2]= output stream 2 retrun log path -* logs[3]= output stream 2 retrun log path -* ... -* strconv_t **conv I stream converter -* conv[0]= output stream 1 converter -* conv[1]= output stream 2 converter -* conv[2]= output stream 3 converter -* ... -* char **cmds I start/stop commands (NULL: no cmd) -* cmds[0]= input stream command -* cmds[1]= output stream 1 command -* cmds[2]= output stream 2 command -* cmds[3]= output stream 3 command -* ... -* char **cmds_periodic I periodic commands (NULL: no cmd) -* cmds[0]= input stream command -* cmds[1]= output stream 1 command -* cmds[2]= output stream 2 command -* cmds[3]= output stream 3 command -* ... -* double *nmeapos I nmea request position (ecef) (m) (NULL: no) -* return : status (0:error,1:ok) -*-----------------------------------------------------------------------------*/ -extern int strsvrstart(strsvr_t *svr, int *opts, int *strs, const char **paths, - const char **logs, strconv_t **conv, const char **cmds, - const char **cmds_periodic, const double *nmeapos) -{ - int i,rw,stropt[8]={0}; - char file1[MAXSTRPATH],file2[MAXSTRPATH],*p; - - tracet(3,"strsvrstart:\n"); - - if (svr->state) return 0; - - strinitcom(); - - for (i=0;i<4;i++) stropt[i]=opts[i]; - stropt[4]=opts[6]; - strsetopt(stropt); - svr->cycle=opts[4]; - svr->buffsize=opts[3]<4096?4096:opts[3]; /* >=4096byte */ - svr->nmeacycle=0=1s */ - svr->relayback=opts[7]; - for (i=0;i<3;i++) svr->nmeapos[i]=nmeapos?nmeapos[i]:0.0; - for (i=0;instr;i++) { - strcpy(svr->cmds_periodic[i],!cmds_periodic[i]?"":cmds_periodic[i]); - } - for (i=0;instr-1;i++) svr->conv[i]=conv[i]; - - if (!(svr->buff=(uint8_t *)malloc(svr->buffsize))|| - !(svr->pbuf=(uint8_t *)malloc(svr->buffsize))) { - free(svr->buff); - svr->buff = svr->pbuf = NULL; - return 0; - } - /* open streams */ - for (i=0;instr;i++) { - strcpy(file1,paths[0]); if ((p=strstr(file1,"::"))) *p='\0'; - strcpy(file2,paths[i]); if ((p=strstr(file2,"::"))) *p='\0'; - if (i>0&&*file1&&!strcmp(file1,file2)) { - sprintf(svr->stream[i].msg,"output path error: %-512.512s",file2); - for (i--;i>=0;i--) strclose(svr->stream+i); - free(svr->buff); free(svr->pbuf); - svr->buff = svr->pbuf = NULL; - return 0; - } - if (strs[i]==STR_FILE) { - rw=i==0?STR_MODE_R:STR_MODE_W; - } - else { - rw=STR_MODE_RW; - } - if (stropen(svr->stream+i,strs[i],rw,paths[i])) continue; - for (i--;i>=0;i--) strclose(svr->stream+i); - free(svr->buff); free(svr->pbuf); - svr->buff = svr->pbuf = NULL; - return 0; - } - /* open log streams */ - for (i=0;instr;i++) { - if (strs[i]==STR_NONE||strs[i]==STR_FILE||!logs[i]||!*logs[i]) continue; - stropen(svr->strlog+i,STR_FILE,STR_MODE_W,logs[i]); - } - /* write start commands to input/output streams */ - for (i=0;instr;i++) { - if (!cmds[i]) continue; - strwrite(svr->stream+i,(uint8_t *)"",0); /* for connect */ - sleepms(100); - strsendcmd(svr->stream+i,cmds[i]); - } - svr->state=1; - - /* create stream server thread */ + * start stream server + * args : strsvr_t *svr IO stream sever struct + * int *opts I stream options + * opts[0]= inactive timeout (ms) + * opts[1]= interval to reconnect (ms) + * opts[2]= averaging time of data rate (ms) + * opts[3]= receive/send buffer size (bytes); + * opts[4]= server cycle (ms) + * opts[5]= nmea request cycle (ms) (0:no) + * opts[6]= file swap margin (s) + * opts[7]= relay back of output stream (0:no) + * int *strs I stream types (STR_???) + * strs[0]= input stream + * strs[1]= output stream 1 + * strs[2]= output stream 2 + * strs[3]= output stream 3 + * ... + * char **paths I stream paths + * paths[0]= input stream + * paths[1]= output stream 1 + * paths[2]= output stream 2 + * paths[3]= output stream 3 + * ... + * char **logs I log paths + * logs[0]= input log path + * logs[1]= output stream 1 return log path + * logs[2]= output stream 2 retrun log path + * logs[3]= output stream 2 retrun log path + * ... + * strconv_t **conv I stream converter + * conv[0]= output stream 1 converter + * conv[1]= output stream 2 converter + * conv[2]= output stream 3 converter + * ... + * char **cmds I start/stop commands (NULL: no cmd) + * cmds[0]= input stream command + * cmds[1]= output stream 1 command + * cmds[2]= output stream 2 command + * cmds[3]= output stream 3 command + * ... + * char **cmds_periodic I periodic commands (NULL: no cmd) + * cmds[0]= input stream command + * cmds[1]= output stream 1 command + * cmds[2]= output stream 2 command + * cmds[3]= output stream 3 command + * ... + * double *nmeapos I nmea request position (ecef) (m) (NULL: no) + * return : status (0:error,1:ok) + *-----------------------------------------------------------------------------*/ +extern int strsvrstart(strsvr_t *svr, int *opts, int *strs, const char **paths, const char **logs, + strconv_t **conv, const char **cmds, const char **cmds_periodic, + const double *nmeapos) { + int i, rw, stropt[8] = {0}; + char file1[MAXSTRPATH], file2[MAXSTRPATH], *p; + + tracet(3, "strsvrstart:\n"); + + if (svr->state) return 0; + + strinitcom(); + + for (i = 0; i < 4; i++) stropt[i] = opts[i]; + stropt[4] = opts[6]; + strsetopt(stropt); + svr->cycle = opts[4]; + svr->buffsize = opts[3] < 4096 ? 4096 : opts[3]; /* >=4096byte */ + svr->nmeacycle = 0 < opts[5] && opts[5] < 1000 ? 1000 : opts[5]; /* >=1s */ + svr->relayback = opts[7]; + for (i = 0; i < 3; i++) svr->nmeapos[i] = nmeapos ? nmeapos[i] : 0.0; + for (i = 0; i < svr->nstr; i++) { + strcpy(svr->cmds_periodic[i], !cmds_periodic[i] ? "" : cmds_periodic[i]); + } + for (i = 0; i < svr->nstr - 1; i++) svr->conv[i] = conv[i]; + + if (!(svr->buff = (uint8_t *)malloc(svr->buffsize)) || + !(svr->pbuf = (uint8_t *)malloc(svr->buffsize))) { + free(svr->buff); + svr->buff = svr->pbuf = NULL; + return 0; + } + /* open streams */ + for (i = 0; i < svr->nstr; i++) { + strcpy(file1, paths[0]); + if ((p = strstr(file1, "::"))) *p = '\0'; + strcpy(file2, paths[i]); + if ((p = strstr(file2, "::"))) *p = '\0'; + if (i > 0 && *file1 && !strcmp(file1, file2)) { + sprintf(svr->stream[i].msg, "output path error: %-512.512s", file2); + for (i--; i >= 0; i--) strclose(svr->stream + i); + free(svr->buff); + free(svr->pbuf); + svr->buff = svr->pbuf = NULL; + return 0; + } + if (strs[i] == STR_FILE) { + rw = i == 0 ? STR_MODE_R : STR_MODE_W; + } else { + rw = STR_MODE_RW; + } + if (stropen(svr->stream + i, strs[i], rw, paths[i])) continue; + for (i--; i >= 0; i--) strclose(svr->stream + i); + free(svr->buff); + free(svr->pbuf); + svr->buff = svr->pbuf = NULL; + return 0; + } + /* open log streams */ + for (i = 0; i < svr->nstr; i++) { + if (strs[i] == STR_NONE || strs[i] == STR_FILE || !logs[i] || !*logs[i]) continue; + stropen(svr->strlog + i, STR_FILE, STR_MODE_W, logs[i]); + } + /* write start commands to input/output streams */ + for (i = 0; i < svr->nstr; i++) { + if (!cmds[i]) continue; + strwrite(svr->stream + i, (uint8_t *)"", 0); /* for connect */ + sleepms(100); + strsendcmd(svr->stream + i, cmds[i]); + } + svr->state = 1; + + /* create stream server thread */ #ifdef WIN32 - if (!(svr->thread=CreateThread(NULL,0,strsvrthread,svr,0,NULL))) { + if (!(svr->thread = CreateThread(NULL, 0, strsvrthread, svr, 0, NULL))) { #else - if (pthread_create(&svr->thread,NULL,strsvrthread,svr)) { + if (pthread_create(&svr->thread, NULL, strsvrthread, svr)) { #endif - for (i=0;instr;i++) strclose(svr->stream+i); - svr->state=0; - free(svr->buff); free(svr->pbuf); - svr->buff = svr->pbuf = NULL; - return 0; - } - return 1; + for (i = 0; i < svr->nstr; i++) strclose(svr->stream + i); + svr->state = 0; + free(svr->buff); + free(svr->pbuf); + svr->buff = svr->pbuf = NULL; + return 0; + } + return 1; } /* stop stream server ---------------------------------------------------------- -* stop stream server -* args : strsvr_t *svr IO stream server struct -* char **cmds I stop commands (NULL: no cmd) -* cmds[0]= input stream command -* cmds[1]= output stream 1 command -* cmds[2]= output stream 2 command -* cmds[3]= output stream 3 command -* ... -* return : none -*-----------------------------------------------------------------------------*/ -extern void strsvrstop(strsvr_t *svr, const char **cmds) -{ - int i; - - tracet(3,"strsvrstop:\n"); - - for (i=0;instr;i++) { - if (cmds[i]) strsendcmd(svr->stream+i,cmds[i]); - } - svr->state=0; - + * stop stream server + * args : strsvr_t *svr IO stream server struct + * char **cmds I stop commands (NULL: no cmd) + * cmds[0]= input stream command + * cmds[1]= output stream 1 command + * cmds[2]= output stream 2 command + * cmds[3]= output stream 3 command + * ... + * return : none + *-----------------------------------------------------------------------------*/ +extern void strsvrstop(strsvr_t *svr, const char **cmds) { + int i; + + tracet(3, "strsvrstop:\n"); + + for (i = 0; i < svr->nstr; i++) { + if (cmds[i]) strsendcmd(svr->stream + i, cmds[i]); + } + svr->state = 0; + #ifdef WIN32 - WaitForSingleObject(svr->thread,10000); - CloseHandle(svr->thread); + WaitForSingleObject(svr->thread, 10000); + CloseHandle(svr->thread); #else - pthread_join(svr->thread,NULL); + pthread_join(svr->thread, NULL); #endif } /* get stream server status ---------------------------------------------------- -* get status of stream server -* args : strsvr_t *svr IO stream sever struct -* int *stat O stream status -* int *log_stat O log status -* int *byte O bytes received/sent -* int *bps O bitrate received/sent -* char *msg O messages -* return : none -*-----------------------------------------------------------------------------*/ -extern void strsvrstat(strsvr_t *svr, int *stat, int *log_stat, int *byte, - int *bps, char *msg) -{ - char s[MAXSTRMSG]="",*p=msg; - int i,bps_in; - - tracet(4,"strsvrstat:\n"); - - for (i=0;instr;i++) { - if (i==0) { - strsum(svr->stream,byte,bps,NULL,NULL); - } - else { - strsum(svr->stream+i,NULL,&bps_in,byte+i,bps+i); - } - stat[i]=strstat(svr->stream+i,s); - if (*s) p+=sprintf(p,"(%d) %s ",i,s); - log_stat[i]=strstat(svr->strlog+i,s); - } + * get status of stream server + * args : strsvr_t *svr IO stream sever struct + * int *stat O stream status + * int *log_stat O log status + * int *byte O bytes received/sent + * int *bps O bitrate received/sent + * char *msg O messages + * return : none + *-----------------------------------------------------------------------------*/ +extern void strsvrstat(strsvr_t *svr, int *stat, int *log_stat, int *byte, int *bps, char *msg) { + char s[MAXSTRMSG] = "", *p = msg; + int i, bps_in; + + tracet(4, "strsvrstat:\n"); + + for (i = 0; i < svr->nstr; i++) { + if (i == 0) { + strsum(svr->stream, byte, bps, NULL, NULL); + } else { + strsum(svr->stream + i, NULL, &bps_in, byte + i, bps + i); + } + stat[i] = strstat(svr->stream + i, s); + if (*s) p += sprintf(p, "(%d) %s ", i, s); + log_stat[i] = strstat(svr->strlog + i, s); + } } /* peek input/output stream ---------------------------------------------------- -* peek input/output stream of stream server -* args : strsvr_t *svr IO stream sever struct -* uint8_t *buff O stream buff -* int nmax I buffer size (bytes) -* return : stream size (bytes) -*-----------------------------------------------------------------------------*/ -extern int strsvrpeek(strsvr_t *svr, uint8_t *buff, int nmax) -{ - int n; - - if (!svr->state) return 0; - - rtklib_lock(&svr->lock); - n=svr->npbnpb:nmax; - if (n>0) { - memcpy(buff,svr->pbuf,n); - } - if (nnpb) { - memmove(svr->pbuf,svr->pbuf+n,svr->npb-n); - } - svr->npb-=n; - rtklib_unlock(&svr->lock); - return n; -} + * peek input/output stream of stream server + * args : strsvr_t *svr IO stream sever struct + * uint8_t *buff O stream buff + * int nmax I buffer size (bytes) + * return : stream size (bytes) + *-----------------------------------------------------------------------------*/ +extern int strsvrpeek(strsvr_t *svr, uint8_t *buff, int nmax) { + int n; + if (!svr->state) return 0; + + rtklib_lock(&svr->lock); + n = svr->npb < nmax ? svr->npb : nmax; + if (n > 0) { + memcpy(buff, svr->pbuf, n); + } + if (n < svr->npb) { + memmove(svr->pbuf, svr->pbuf + n, svr->npb - n); + } + svr->npb -= n; + rtklib_unlock(&svr->lock); + return n; +} diff --git a/src/tides.c b/src/tides.c index e4c160de9..8c336adfa 100644 --- a/src/tides.c +++ b/src/tides.c @@ -1,27 +1,27 @@ /*------------------------------------------------------------------------------ -* tides.c : tidal displacement corrections -* -* Copyright (C) 2015-2017 by T.TAKASU, All rights reserved. -* -* references : -* [1] D.D.McCarthy, IERS Technical Note 21, IERS Conventions 1996, July 1996 -* [2] D.D.McCarthy and G.Petit, IERS Technical Note 32, IERS Conventions -* 2003, November 2003 -* [3] D.A.Vallado, Fundamentals of Astrodynamics and Applications 2nd ed, -* Space Technology Library, 2004 -* [4] J.Kouba, A Guide to using International GNSS Service (IGS) products, -* May 2009 -* [5] G.Petit and B.Luzum (eds), IERS Technical Note No. 36, IERS -* Conventions (2010), 2010 -* -* version : $Revision:$ $Date:$ -* history : 2015/05/10 1.0 separated from ppp.c -* 2015/06/11 1.1 fix bug on computing days in tide_oload() (#128) -* 2017/04/11 1.2 fix bug on calling geterp() in timdedisp() -*-----------------------------------------------------------------------------*/ + * tides.c : tidal displacement corrections + * + * Copyright (C) 2015-2017 by T.TAKASU, All rights reserved. + * + * references : + * [1] D.D.McCarthy, IERS Technical Note 21, IERS Conventions 1996, July 1996 + * [2] D.D.McCarthy and G.Petit, IERS Technical Note 32, IERS Conventions + * 2003, November 2003 + * [3] D.A.Vallado, Fundamentals of Astrodynamics and Applications 2nd ed, + * Space Technology Library, 2004 + * [4] J.Kouba, A Guide to using International GNSS Service (IGS) products, + * May 2009 + * [5] G.Petit and B.Luzum (eds), IERS Technical Note No. 36, IERS + * Conventions (2010), 2010 + * + * version : $Revision:$ $Date:$ + * history : 2015/05/10 1.0 separated from ppp.c + * 2015/06/11 1.1 fix bug on computing days in tide_oload() (#128) + * 2017/04/11 1.2 fix bug on calling geterp() in timdedisp() + *-----------------------------------------------------------------------------*/ #include "rtklib.h" -#define SQR(x) ((x)*(x)) +#define SQR(x) ((x) * (x)) // The following few functions are in support of dehanttideinel. This code is // a translation of the respective iers fortran code to C and to RTKLIB, and @@ -899,7 +899,6 @@ static void hardisp(const gtime_t time, double samp, int irnt, const double tamp } } - // IERS mean pole ------------------------------------------------------------- // Ref: https://iers-conventions.obspm.fr/conventions_material.php TN.36 // 7.1.4 Rotational deformation due to polar motion: Secular polar motion and the pole tide. @@ -935,29 +934,29 @@ static void tide_pole(gtime_t tutc, const double *pos, const double *erpv, doubl } /* Tidal displacement ---------------------------------------------------------- -* Displacements by earth tides -* Args : gtime_t tutc I time in UTC -* double *rr I site position (ECEF) (m) -* int opt I options (or of the followings) -* 1: solid earth tide -* 2: ocean tide loading -* 4: pole tide -* 8: elimate permanent deformation -* double *erp I earth rotation parameters (NULL: not used) -* double *odisp I ocean loading parameters (NULL: not used) -* odisp[0][i][0]: consituent i amplitude radial(m) -* odisp[0][i][1]: consituent i amplitude west (m) -* odisp[0][i][2]: consituent i amplitude south (m) -* odisp[1][i][0]: consituent i phase radial (deg) -* odisp[1][i][1]: consituent i phase west (deg) -* odisp[1][i][2]: consituent i phase south (deg) -* (i=0:M2,1:S2,2:N2,3:K2,4:K1,5:O1,6:P1,7:Q1, -* 8:Mf,9:Mm,10:Ssa) -* double *dr O displacement by earth tides (ECEF) (m) -* Return : none -* Notes : see ref [1], [2] chap 7 -* see ref [4] 5.2.1, 5.2.2, 5.2.3 -*-----------------------------------------------------------------------------*/ + * Displacements by earth tides + * Args : gtime_t tutc I time in UTC + * double *rr I site position (ECEF) (m) + * int opt I options (or of the followings) + * 1: solid earth tide + * 2: ocean tide loading + * 4: pole tide + * 8: elimate permanent deformation + * double *erp I earth rotation parameters (NULL: not used) + * double *odisp I ocean loading parameters (NULL: not used) + * odisp[0][i][0]: consituent i amplitude radial(m) + * odisp[0][i][1]: consituent i amplitude west (m) + * odisp[0][i][2]: consituent i amplitude south (m) + * odisp[1][i][0]: consituent i phase radial (deg) + * odisp[1][i][1]: consituent i phase west (deg) + * odisp[1][i][2]: consituent i phase south (deg) + * (i=0:M2,1:S2,2:N2,3:K2,4:K1,5:O1,6:P1,7:Q1, + * 8:Mf,9:Mm,10:Ssa) + * double *dr O displacement by earth tides (ECEF) (m) + * Return : none + * Notes : see ref [1], [2] chap 7 + * see ref [4] 5.2.1, 5.2.2, 5.2.3 + *-----------------------------------------------------------------------------*/ extern void tidedisp(gtime_t tutc, const double *rr, int opt, const erp_t *erp, const double odisp[2][11][3], double *dr) { char tstr[40]; @@ -992,7 +991,7 @@ extern void tidedisp(gtime_t tutc, const double *rr, int opt, const erp_t *erp, double denu[3]; denu[0] = -dw; denu[1] = -ds; - denu[2] = dz; + denu[2] = dz; double drt[3]; matmul("TN", 3, 1, 3, E, denu, drt); for (int i = 0; i < 3; i++) dr[i] += drt[i]; diff --git a/src/tle.c b/src/tle.c index fcf1f0509..695e3f7ee 100644 --- a/src/tle.c +++ b/src/tle.c @@ -1,583 +1,579 @@ /*------------------------------------------------------------------------------ -* tle.c: NORAD TLE (two line element) functions -* -* Copyright (C) 2012-2020 by T.TAKASU, All rights reserved. -* -* references: -* [1] F.R.Hoots and R.L.Roehrich, Spacetrack report No.3, Models for -* propagation of NORAD element sets, December 1980 -* [2] D.A.Vallado, P.Crawford, R.Hujsak and T.S.Kelso, Revisiting -* Spacetrack Report #3, AIAA 2006-6753, 2006 -* [3] CelesTrak (http://www.celestrak.com) -* -* version : $Revision:$ $Date:$ -* history : 2012/11/01 1.0 new -* 2013/01/25 1.1 fix bug on binary search -* 2014/08/26 1.2 fix bug on tle_pos() to get tle by satid or desig -* 2020/11/30 1.3 fix problem on duplicated names in a satellite -*-----------------------------------------------------------------------------*/ + * tle.c: NORAD TLE (two line element) functions + * + * Copyright (C) 2012-2020 by T.TAKASU, All rights reserved. + * + * references: + * [1] F.R.Hoots and R.L.Roehrich, Spacetrack report No.3, Models for + * propagation of NORAD element sets, December 1980 + * [2] D.A.Vallado, P.Crawford, R.Hujsak and T.S.Kelso, Revisiting + * Spacetrack Report #3, AIAA 2006-6753, 2006 + * [3] CelesTrak (http://www.celestrak.com) + * + * version : $Revision:$ $Date:$ + * history : 2012/11/01 1.0 new + * 2013/01/25 1.1 fix bug on binary search + * 2014/08/26 1.2 fix bug on tle_pos() to get tle by satid or desig + * 2020/11/30 1.3 fix problem on duplicated names in a satellite + *-----------------------------------------------------------------------------*/ #include "rtklib.h" /* SGP4 model propagator by STR#3 (ref [1] sec.6,11) -------------------------*/ -#define DE2RA 0.174532925E-1 -#define E6A 1.E-6 -#define PIO2 1.57079633 -#define QO 120.0 -#define SO 78.0 -#define TOTHRD 0.66666667 -#define TWOPI 6.2831853 -#define X3PIO2 4.71238898 -#define XJ2 1.082616E-3 -#define XJ3 -0.253881E-5 -#define XJ4 -1.65597E-6 -#define XKE 0.743669161E-1 -#define XKMPER 6378.135 -#define XMNPDA 1440.0 -#define AE 1.0 -#define CK2 5.413080E-4 /* = 0.5*XJ2*AE*AE */ -#define CK4 0.62098875E-6 /* = -0.375*XJ4*AE*AE*AE*AE */ -#define QOMS2T 1.88027916E-9 /* = pow((QO-SO)*AE/XKMPER,4.0) */ -#define S 1.01222928 /* = AE*(1.0+SO/XKMPER) */ - -static void SGP4_STR3(double tsince, const tled_t *data, double *rs) -{ - double xnodeo,omegao,xmo,eo,xincl,xno,xndt2o,xndd6o,bstar; - double a1,cosio,theta2,x3thm1,eosq,betao2,betao,del1,ao,delo,xnodp,aodp,s4; - double qoms24,perige,pinvsq,tsi,eta,etasq,eeta,psisq,coef,coef1,c1,c2,c3,c4; - double c5,sinio,a3ovk2,x1mth2,theta4,xmdot,x1m5th,omgdot,xhdot1,xnodot; - double omgcof,xmcof,xnodcf,t2cof,xlcof,aycof,delmo,sinmo,x7thm1,c1sq,d2,d3; - double d4,t3cof,t4cof,t5cof,xmdf,omgadf,xnoddf,omega,xmp,tsq,xnode,delomg; - double delm,tcube,tfour,a,e,xl,beta,xn,axn,xll,aynl,xlt,ayn,capu,sinepw; - double cosepw,epw,ecose,esine,elsq,pl,r,rdot,rfdot,betal,cosu,sinu,u,sin2u; - double cos2u,rk,uk,xnodek,xinck,rdotk,rfdotk,sinuk,cosuk,sinik,cosik,sinnok; - double cosnok,xmx,xmy,ux,uy,uz,vx,vy,vz,x,y,z,xdot,ydot,zdot; - double temp,temp1,temp2,temp3,temp4,temp5,temp6,tempa,tempe,templ; - int i,isimp; - - xnodeo=data->OMG*DE2RA; - omegao=data->omg*DE2RA; - xmo=data->M*DE2RA; - xincl=data->inc*DE2RA; - temp=TWOPI/XMNPDA/XMNPDA; - xno=data->n*temp*XMNPDA; - xndt2o=data->ndot*temp; - xndd6o=data->nddot*temp/XMNPDA; - bstar=data->bstar/AE; - eo=data->ecc; - /* - * recover original mean motion (xnodp) and semimajor axis (aodp) - * from input elements - */ - a1=pow(XKE/xno,TOTHRD); - cosio=cos(xincl); - theta2=cosio*cosio; - x3thm1=3.0*theta2-1.0; - eosq=eo*eo; - betao2=1.0-eosq; - betao=sqrt(betao2); - del1=1.5*CK2*x3thm1/(a1*a1*betao*betao2); - ao=a1*(1.0-del1*(0.5*TOTHRD+del1*(1.0+134.0/81.0*del1))); - delo=1.5*CK2*x3thm1/(ao*ao*betao*betao2); - xnodp=xno/(1.0+delo); - aodp=ao/(1.0-delo); - /* - * initialization - * for perigee less than 220 kilometers, the isimp flag is set and - * the equations are truncated to linear variation in sqrt a and - * quadratic variation in mean anomaly. also, the c3 term, the - * delta omega term, and the delta m term are dropped. - */ - isimp=0; - if ((aodp*(1.0-eo)/AE)<(220.0/XKMPER+AE)) isimp=1; - - /* for perigee below 156 km, the values of s and qoms2t are altered */ - s4=S; - qoms24=QOMS2T; - perige=(aodp*(1.0-eo)-AE)*XKMPER; - if (perige<156.0) { - s4=perige-78.0; - if (perige<=98.0) s4=20.0; - qoms24=pow((120.0-s4)*AE/XKMPER,4.0); - s4=s4/XKMPER+AE; - } - pinvsq=1.0/(aodp*aodp*betao2*betao2); - tsi=1.0/(aodp-s4); - eta=aodp*eo*tsi; - etasq=eta*eta; - eeta=eo*eta; - psisq=fabs(1.0-etasq); - coef=qoms24*pow(tsi,4.0); - coef1=coef/pow(psisq,3.5); - c2=coef1*xnodp*(aodp*(1.0+1.5*etasq+eeta*(4.0+etasq))+0.75* - CK2*tsi/psisq*x3thm1*(8.0+3.0*etasq*(8.0+etasq))); - c1=bstar*c2; - sinio=sin(xincl); - a3ovk2=-XJ3/CK2*pow(AE,3.0); - c3=coef*tsi*a3ovk2*xnodp*AE*sinio/eo; - x1mth2=1.0-theta2; - c4=2.0*xnodp*coef1*aodp*betao2*(eta* - (2.0+0.5*etasq)+eo*(0.5+2.0*etasq)-2.0*CK2*tsi/ - (aodp*psisq)*(-3.0*x3thm1*(1.0-2.0*eeta+etasq* - (1.5-0.5*eeta))+0.75*x1mth2*(2.0*etasq-eeta* - (1.0+etasq))*cos(2.0*omegao))); - c5=2.0*coef1*aodp*betao2*(1.0+2.75*(etasq+eeta)+eeta*etasq); - theta4=theta2*theta2; - temp1=3.0*CK2*pinvsq*xnodp; - temp2=temp1*CK2*pinvsq; - temp3=1.25*CK4*pinvsq*pinvsq*xnodp; - xmdot=xnodp+0.5*temp1*betao*x3thm1+0.0625*temp2*betao* - (13.0-78.0*theta2+137.0*theta4); - x1m5th=1.0-5.0*theta2; - omgdot=-0.5*temp1*x1m5th+0.0625*temp2*(7.0-114.0*theta2+ - 395.0*theta4)+temp3*(3.0-36.0*theta2+49.0*theta4); - xhdot1=-temp1*cosio; - xnodot=xhdot1+(0.5*temp2*(4.0-19.0*theta2)+2.0*temp3*(3.0- - 7.0*theta2))*cosio; - omgcof=bstar*c3*cos(omegao); - xmcof=-TOTHRD*coef*bstar*AE/eeta; - xnodcf=3.5*betao2*xhdot1*c1; - t2cof=1.5*c1; - xlcof=0.125*a3ovk2*sinio*(3.0+5.0*cosio)/(1.0+cosio); - aycof=0.25*a3ovk2*sinio; - delmo=pow(1.0+eta*cos(xmo),3.0); - sinmo=sin(xmo); - x7thm1=7.0*theta2-1.0; - - if (isimp!=1) { - c1sq=c1*c1; - d2=4.0*aodp*tsi*c1sq; - temp=d2*tsi*c1/3.0; - d3=(17.0*aodp+s4)*temp; - d4=0.5*temp*aodp*tsi*(221.0*aodp+31.0*s4)*c1; - t3cof=d2+2.0*c1sq; - t4cof=0.25*(3.0*d3+c1*(12.0*d2+10.0*c1sq)); - t5cof=0.2*(3.0*d4+12.0*c1*d3+6.0*d2*d2+15.0*c1sq*(2.0*d2+c1sq)); - } - else { - d2=d3=d4=t3cof=t4cof=t5cof=0.0; - } - /* update for secular gravity and atmospheric drag */ - xmdf=xmo+xmdot*tsince; - omgadf=omegao+omgdot*tsince; - xnoddf=xnodeo+xnodot*tsince; - omega=omgadf; - xmp=xmdf; - tsq=tsince*tsince; - xnode=xnoddf+xnodcf*tsq; - tempa=1.0-c1*tsince; - tempe=bstar*c4*tsince; - templ=t2cof*tsq; - if (isimp==1) { - delomg=omgcof*tsince; - delm=xmcof*(pow(1.0+eta*cos(xmdf),3.0)-delmo); - temp=delomg+delm; - xmp=xmdf+temp; - omega=omgadf-temp; - tcube=tsq*tsince; - tfour=tsince*tcube; - tempa=tempa-d2*tsq-d3*tcube-d4*tfour; - tempe=tempe+bstar*c5*(sin(xmp)-sinmo); - templ=templ+t3cof*tcube+tfour*(t4cof+tsince*t5cof); - } - a=aodp*pow(tempa,2.0); - e=eo-tempe; - xl=xmp+omega+xnode+xnodp*templ; - beta=sqrt(1.0-e*e); - xn=XKE/pow(a,1.5); - - /* long period periodics */ - axn=e*cos(omega); - temp=1.0/(a*beta*beta); - xll=temp*xlcof*axn; - aynl=temp*aycof; - xlt=xl+xll; - ayn=e*sin(omega)+aynl; - - /* solve keplers equation */ - capu=fmod(xlt-xnode,TWOPI); - temp2=capu; - for (i=0;i<10;i++) { - sinepw=sin(temp2); - cosepw=cos(temp2); - temp3=axn*sinepw; - temp4=ayn*cosepw; - temp5=axn*cosepw; - temp6=ayn*sinepw; - epw=(capu-temp4+temp3-temp2)/(1.0-temp5-temp6)+temp2; - if (fabs(epw-temp2)<=E6A) break; - temp2=epw; - } - /* short period preliminary quantities */ - ecose=temp5+temp6; - esine=temp3-temp4; - elsq=axn*axn+ayn*ayn; - temp=1.0-elsq; - pl=a*temp; - r=a*(1.0-ecose); - temp1=1.0/r; - rdot=XKE*sqrt(a)*esine*temp1; - rfdot=XKE*sqrt(pl)*temp1; - temp2=a*temp1; - betal=sqrt(temp); - temp3=1.0/(1.0+betal); - cosu=temp2*(cosepw-axn+ayn*esine*temp3); - sinu=temp2*(sinepw-ayn-axn*esine*temp3); - u=atan2(sinu,cosu); - sin2u=2.0*sinu*cosu; - cos2u=2.0*cosu*cosu-1.0; - temp=1.0/pl; - temp1=CK2*temp; - temp2=temp1*temp; - - /* update for short periodics */ - rk=r*(1.0-1.5*temp2*betal*x3thm1)+0.5*temp1*x1mth2*cos2u; - uk=u-0.25*temp2*x7thm1*sin2u; - xnodek=xnode+1.5*temp2*cosio*sin2u; - xinck=xincl+1.5*temp2*cosio*sinio*cos2u; - rdotk=rdot-xn*temp1*x1mth2*sin2u; - rfdotk=rfdot+xn*temp1*(x1mth2*cos2u+1.5*x3thm1); - - /* orientation vectors */ - sinuk=sin(uk); - cosuk=cos(uk); - sinik=sin(xinck); - cosik=cos(xinck); - sinnok=sin(xnodek); - cosnok=cos(xnodek); - xmx=-sinnok*cosik; - xmy=cosnok*cosik; - ux=xmx*sinuk+cosnok*cosuk; - uy=xmy*sinuk+sinnok*cosuk; - uz=sinik*sinuk; - vx=xmx*cosuk-cosnok*sinuk; - vy=xmy*cosuk-sinnok*sinuk; - vz=sinik*cosuk; - - /* position and velocity */ - x=rk*ux; - y=rk*uy; - z=rk*uz; - xdot=rdotk*ux+rfdotk*vx; - ydot=rdotk*uy+rfdotk*vy; - zdot=rdotk*uz+rfdotk*vz; - - rs[0]=x*XKMPER/AE*1E3; /* (m) */ - rs[1]=y*XKMPER/AE*1E3; - rs[2]=z*XKMPER/AE*1E3; - rs[3]=xdot*XKMPER/AE*XMNPDA/86400.0*1E3; /* (m/s) */ - rs[4]=ydot*XKMPER/AE*XMNPDA/86400.0*1E3; - rs[5]=zdot*XKMPER/AE*XMNPDA/86400.0*1E3; +#define DE2RA 0.174532925E-1 +#define E6A 1.E-6 +#define PIO2 1.57079633 +#define QO 120.0 +#define SO 78.0 +#define TOTHRD 0.66666667 +#define TWOPI 6.2831853 +#define X3PIO2 4.71238898 +#define XJ2 1.082616E-3 +#define XJ3 -0.253881E-5 +#define XJ4 -1.65597E-6 +#define XKE 0.743669161E-1 +#define XKMPER 6378.135 +#define XMNPDA 1440.0 +#define AE 1.0 +#define CK2 5.413080E-4 /* = 0.5*XJ2*AE*AE */ +#define CK4 0.62098875E-6 /* = -0.375*XJ4*AE*AE*AE*AE */ +#define QOMS2T 1.88027916E-9 /* = pow((QO-SO)*AE/XKMPER,4.0) */ +#define S 1.01222928 /* = AE*(1.0+SO/XKMPER) */ + +static void SGP4_STR3(double tsince, const tled_t *data, double *rs) { + double xnodeo, omegao, xmo, eo, xincl, xno, xndt2o, xndd6o, bstar; + double a1, cosio, theta2, x3thm1, eosq, betao2, betao, del1, ao, delo, xnodp, aodp, s4; + double qoms24, perige, pinvsq, tsi, eta, etasq, eeta, psisq, coef, coef1, c1, c2, c3, c4; + double c5, sinio, a3ovk2, x1mth2, theta4, xmdot, x1m5th, omgdot, xhdot1, xnodot; + double omgcof, xmcof, xnodcf, t2cof, xlcof, aycof, delmo, sinmo, x7thm1, c1sq, d2, d3; + double d4, t3cof, t4cof, t5cof, xmdf, omgadf, xnoddf, omega, xmp, tsq, xnode, delomg; + double delm, tcube, tfour, a, e, xl, beta, xn, axn, xll, aynl, xlt, ayn, capu, sinepw; + double cosepw, epw, ecose, esine, elsq, pl, r, rdot, rfdot, betal, cosu, sinu, u, sin2u; + double cos2u, rk, uk, xnodek, xinck, rdotk, rfdotk, sinuk, cosuk, sinik, cosik, sinnok; + double cosnok, xmx, xmy, ux, uy, uz, vx, vy, vz, x, y, z, xdot, ydot, zdot; + double temp, temp1, temp2, temp3, temp4, temp5, temp6, tempa, tempe, templ; + int i, isimp; + + xnodeo = data->OMG * DE2RA; + omegao = data->omg * DE2RA; + xmo = data->M * DE2RA; + xincl = data->inc * DE2RA; + temp = TWOPI / XMNPDA / XMNPDA; + xno = data->n * temp * XMNPDA; + xndt2o = data->ndot * temp; + xndd6o = data->nddot * temp / XMNPDA; + bstar = data->bstar / AE; + eo = data->ecc; + /* + * recover original mean motion (xnodp) and semimajor axis (aodp) + * from input elements + */ + a1 = pow(XKE / xno, TOTHRD); + cosio = cos(xincl); + theta2 = cosio * cosio; + x3thm1 = 3.0 * theta2 - 1.0; + eosq = eo * eo; + betao2 = 1.0 - eosq; + betao = sqrt(betao2); + del1 = 1.5 * CK2 * x3thm1 / (a1 * a1 * betao * betao2); + ao = a1 * (1.0 - del1 * (0.5 * TOTHRD + del1 * (1.0 + 134.0 / 81.0 * del1))); + delo = 1.5 * CK2 * x3thm1 / (ao * ao * betao * betao2); + xnodp = xno / (1.0 + delo); + aodp = ao / (1.0 - delo); + /* + * initialization + * for perigee less than 220 kilometers, the isimp flag is set and + * the equations are truncated to linear variation in sqrt a and + * quadratic variation in mean anomaly. also, the c3 term, the + * delta omega term, and the delta m term are dropped. + */ + isimp = 0; + if ((aodp * (1.0 - eo) / AE) < (220.0 / XKMPER + AE)) isimp = 1; + + /* for perigee below 156 km, the values of s and qoms2t are altered */ + s4 = S; + qoms24 = QOMS2T; + perige = (aodp * (1.0 - eo) - AE) * XKMPER; + if (perige < 156.0) { + s4 = perige - 78.0; + if (perige <= 98.0) s4 = 20.0; + qoms24 = pow((120.0 - s4) * AE / XKMPER, 4.0); + s4 = s4 / XKMPER + AE; + } + pinvsq = 1.0 / (aodp * aodp * betao2 * betao2); + tsi = 1.0 / (aodp - s4); + eta = aodp * eo * tsi; + etasq = eta * eta; + eeta = eo * eta; + psisq = fabs(1.0 - etasq); + coef = qoms24 * pow(tsi, 4.0); + coef1 = coef / pow(psisq, 3.5); + c2 = coef1 * xnodp * + (aodp * (1.0 + 1.5 * etasq + eeta * (4.0 + etasq)) + + 0.75 * CK2 * tsi / psisq * x3thm1 * (8.0 + 3.0 * etasq * (8.0 + etasq))); + c1 = bstar * c2; + sinio = sin(xincl); + a3ovk2 = -XJ3 / CK2 * pow(AE, 3.0); + c3 = coef * tsi * a3ovk2 * xnodp * AE * sinio / eo; + x1mth2 = 1.0 - theta2; + c4 = 2.0 * xnodp * coef1 * aodp * betao2 * + (eta * (2.0 + 0.5 * etasq) + eo * (0.5 + 2.0 * etasq) - + 2.0 * CK2 * tsi / (aodp * psisq) * + (-3.0 * x3thm1 * (1.0 - 2.0 * eeta + etasq * (1.5 - 0.5 * eeta)) + + 0.75 * x1mth2 * (2.0 * etasq - eeta * (1.0 + etasq)) * cos(2.0 * omegao))); + c5 = 2.0 * coef1 * aodp * betao2 * (1.0 + 2.75 * (etasq + eeta) + eeta * etasq); + theta4 = theta2 * theta2; + temp1 = 3.0 * CK2 * pinvsq * xnodp; + temp2 = temp1 * CK2 * pinvsq; + temp3 = 1.25 * CK4 * pinvsq * pinvsq * xnodp; + xmdot = xnodp + 0.5 * temp1 * betao * x3thm1 + + 0.0625 * temp2 * betao * (13.0 - 78.0 * theta2 + 137.0 * theta4); + x1m5th = 1.0 - 5.0 * theta2; + omgdot = -0.5 * temp1 * x1m5th + 0.0625 * temp2 * (7.0 - 114.0 * theta2 + 395.0 * theta4) + + temp3 * (3.0 - 36.0 * theta2 + 49.0 * theta4); + xhdot1 = -temp1 * cosio; + xnodot = + xhdot1 + (0.5 * temp2 * (4.0 - 19.0 * theta2) + 2.0 * temp3 * (3.0 - 7.0 * theta2)) * cosio; + omgcof = bstar * c3 * cos(omegao); + xmcof = -TOTHRD * coef * bstar * AE / eeta; + xnodcf = 3.5 * betao2 * xhdot1 * c1; + t2cof = 1.5 * c1; + xlcof = 0.125 * a3ovk2 * sinio * (3.0 + 5.0 * cosio) / (1.0 + cosio); + aycof = 0.25 * a3ovk2 * sinio; + delmo = pow(1.0 + eta * cos(xmo), 3.0); + sinmo = sin(xmo); + x7thm1 = 7.0 * theta2 - 1.0; + + if (isimp != 1) { + c1sq = c1 * c1; + d2 = 4.0 * aodp * tsi * c1sq; + temp = d2 * tsi * c1 / 3.0; + d3 = (17.0 * aodp + s4) * temp; + d4 = 0.5 * temp * aodp * tsi * (221.0 * aodp + 31.0 * s4) * c1; + t3cof = d2 + 2.0 * c1sq; + t4cof = 0.25 * (3.0 * d3 + c1 * (12.0 * d2 + 10.0 * c1sq)); + t5cof = 0.2 * (3.0 * d4 + 12.0 * c1 * d3 + 6.0 * d2 * d2 + 15.0 * c1sq * (2.0 * d2 + c1sq)); + } else { + d2 = d3 = d4 = t3cof = t4cof = t5cof = 0.0; + } + /* update for secular gravity and atmospheric drag */ + xmdf = xmo + xmdot * tsince; + omgadf = omegao + omgdot * tsince; + xnoddf = xnodeo + xnodot * tsince; + omega = omgadf; + xmp = xmdf; + tsq = tsince * tsince; + xnode = xnoddf + xnodcf * tsq; + tempa = 1.0 - c1 * tsince; + tempe = bstar * c4 * tsince; + templ = t2cof * tsq; + if (isimp == 1) { + delomg = omgcof * tsince; + delm = xmcof * (pow(1.0 + eta * cos(xmdf), 3.0) - delmo); + temp = delomg + delm; + xmp = xmdf + temp; + omega = omgadf - temp; + tcube = tsq * tsince; + tfour = tsince * tcube; + tempa = tempa - d2 * tsq - d3 * tcube - d4 * tfour; + tempe = tempe + bstar * c5 * (sin(xmp) - sinmo); + templ = templ + t3cof * tcube + tfour * (t4cof + tsince * t5cof); + } + a = aodp * pow(tempa, 2.0); + e = eo - tempe; + xl = xmp + omega + xnode + xnodp * templ; + beta = sqrt(1.0 - e * e); + xn = XKE / pow(a, 1.5); + + /* long period periodics */ + axn = e * cos(omega); + temp = 1.0 / (a * beta * beta); + xll = temp * xlcof * axn; + aynl = temp * aycof; + xlt = xl + xll; + ayn = e * sin(omega) + aynl; + + /* solve keplers equation */ + capu = fmod(xlt - xnode, TWOPI); + temp2 = capu; + for (i = 0; i < 10; i++) { + sinepw = sin(temp2); + cosepw = cos(temp2); + temp3 = axn * sinepw; + temp4 = ayn * cosepw; + temp5 = axn * cosepw; + temp6 = ayn * sinepw; + epw = (capu - temp4 + temp3 - temp2) / (1.0 - temp5 - temp6) + temp2; + if (fabs(epw - temp2) <= E6A) break; + temp2 = epw; + } + /* short period preliminary quantities */ + ecose = temp5 + temp6; + esine = temp3 - temp4; + elsq = axn * axn + ayn * ayn; + temp = 1.0 - elsq; + pl = a * temp; + r = a * (1.0 - ecose); + temp1 = 1.0 / r; + rdot = XKE * sqrt(a) * esine * temp1; + rfdot = XKE * sqrt(pl) * temp1; + temp2 = a * temp1; + betal = sqrt(temp); + temp3 = 1.0 / (1.0 + betal); + cosu = temp2 * (cosepw - axn + ayn * esine * temp3); + sinu = temp2 * (sinepw - ayn - axn * esine * temp3); + u = atan2(sinu, cosu); + sin2u = 2.0 * sinu * cosu; + cos2u = 2.0 * cosu * cosu - 1.0; + temp = 1.0 / pl; + temp1 = CK2 * temp; + temp2 = temp1 * temp; + + /* update for short periodics */ + rk = r * (1.0 - 1.5 * temp2 * betal * x3thm1) + 0.5 * temp1 * x1mth2 * cos2u; + uk = u - 0.25 * temp2 * x7thm1 * sin2u; + xnodek = xnode + 1.5 * temp2 * cosio * sin2u; + xinck = xincl + 1.5 * temp2 * cosio * sinio * cos2u; + rdotk = rdot - xn * temp1 * x1mth2 * sin2u; + rfdotk = rfdot + xn * temp1 * (x1mth2 * cos2u + 1.5 * x3thm1); + + /* orientation vectors */ + sinuk = sin(uk); + cosuk = cos(uk); + sinik = sin(xinck); + cosik = cos(xinck); + sinnok = sin(xnodek); + cosnok = cos(xnodek); + xmx = -sinnok * cosik; + xmy = cosnok * cosik; + ux = xmx * sinuk + cosnok * cosuk; + uy = xmy * sinuk + sinnok * cosuk; + uz = sinik * sinuk; + vx = xmx * cosuk - cosnok * sinuk; + vy = xmy * cosuk - sinnok * sinuk; + vz = sinik * cosuk; + + /* position and velocity */ + x = rk * ux; + y = rk * uy; + z = rk * uz; + xdot = rdotk * ux + rfdotk * vx; + ydot = rdotk * uy + rfdotk * vy; + zdot = rdotk * uz + rfdotk * vz; + + rs[0] = x * XKMPER / AE * 1E3; /* (m) */ + rs[1] = y * XKMPER / AE * 1E3; + rs[2] = z * XKMPER / AE * 1E3; + rs[3] = xdot * XKMPER / AE * XMNPDA / 86400.0 * 1E3; /* (m/s) */ + rs[4] = ydot * XKMPER / AE * XMNPDA / 86400.0 * 1E3; + rs[5] = zdot * XKMPER / AE * XMNPDA / 86400.0 * 1E3; } /* drop spaces at string tail ------------------------------------------------*/ -static void chop(char *buff) -{ - int i; - for (i=strlen(buff)-1;i>=0;i--) { - if (buff[i]==' '||buff[i]=='\r'||buff[i]=='\n') buff[i]='\0'; - else break; - } +static void chop(char *buff) { + int i; + for (i = strlen(buff) - 1; i >= 0; i--) { + if (buff[i] == ' ' || buff[i] == '\r' || buff[i] == '\n') + buff[i] = '\0'; + else + break; + } } /* test TLE line checksum ----------------------------------------------------*/ -static int checksum(const char *buff) -{ - int i,cs=0; - - if (strlen(buff)<69) return 0; - - for (i=0;i<68;i++) { - if ('0'<=buff[i]&&buff[i]<='9') cs+=(int)(buff[i]-'0'); - else if (buff[i]=='-') cs+=1; - } - return (int)(buff[68]-'0')==cs%10; +static int checksum(const char *buff) { + int i, cs = 0; + + if (strlen(buff) < 69) return 0; + + for (i = 0; i < 68; i++) { + if ('0' <= buff[i] && buff[i] <= '9') + cs += (int)(buff[i] - '0'); + else if (buff[i] == '-') + cs += 1; + } + return (int)(buff[68] - '0') == cs % 10; } /* decode TLE line 1 ---------------------------------------------------------*/ -static int decode_line1(const char *buff, tled_t *data) -{ - double year,doy,nddot,exp1,bstar,exp2,ep[6]={2000,1,1}; - - strncpy(data->satno,buff+2,5); /* satellite number */ - data->satno[5]='\0'; - chop(data->satno); - - data->satclass=buff[7]; /* satellite classification */ - strncpy(data->desig,buff+9,8); /* international designator */ - data->desig[8]='\0'; - chop(data->desig); - - year =str2num(buff,18, 2); /* epoch year */ - doy =str2num(buff,20,12); /* epoch day of year */ - data->ndot=str2num(buff,33,10); /* 1st time derivative of n */ - nddot =str2num(buff,44, 6); /* 2nd time derivative of n */ - exp1 =str2num(buff,50, 2); - bstar =str2num(buff,53, 6); /* Bstar drag term */ - exp2 =str2num(buff,59, 2); - data->etype=(int)str2num(buff,62,1); /* ephemeris type */ - data->eleno=(int)str2num(buff,64,4); /* ephemeris number */ - data->nddot=nddot*1E-5*pow(10.0,exp1); - data->bstar=bstar*1E-5*pow(10.0,exp2); - - ep[0]=year+(year<57.0?2000.0:1900.0); - data->epoch=timeadd(epoch2time(ep),(doy-1.0)*86400.0); - - data->inc=data->OMG=data->ecc=data->omg=data->M=data->n=0.0; - data->rev=0; - return 1; +static int decode_line1(const char *buff, tled_t *data) { + double year, doy, nddot, exp1, bstar, exp2, ep[6] = {2000, 1, 1}; + + strncpy(data->satno, buff + 2, 5); /* satellite number */ + data->satno[5] = '\0'; + chop(data->satno); + + data->satclass = buff[7]; /* satellite classification */ + strncpy(data->desig, buff + 9, 8); /* international designator */ + data->desig[8] = '\0'; + chop(data->desig); + + year = str2num(buff, 18, 2); /* epoch year */ + doy = str2num(buff, 20, 12); /* epoch day of year */ + data->ndot = str2num(buff, 33, 10); /* 1st time derivative of n */ + nddot = str2num(buff, 44, 6); /* 2nd time derivative of n */ + exp1 = str2num(buff, 50, 2); + bstar = str2num(buff, 53, 6); /* Bstar drag term */ + exp2 = str2num(buff, 59, 2); + data->etype = (int)str2num(buff, 62, 1); /* ephemeris type */ + data->eleno = (int)str2num(buff, 64, 4); /* ephemeris number */ + data->nddot = nddot * 1E-5 * pow(10.0, exp1); + data->bstar = bstar * 1E-5 * pow(10.0, exp2); + + ep[0] = year + (year < 57.0 ? 2000.0 : 1900.0); + data->epoch = timeadd(epoch2time(ep), (doy - 1.0) * 86400.0); + + data->inc = data->OMG = data->ecc = data->omg = data->M = data->n = 0.0; + data->rev = 0; + return 1; } /* decode TLE line 2 ---------------------------------------------------------*/ -static int decode_line2(const char *buff, tled_t *data) -{ - char satno[16]; - - strncpy(satno,buff+2,5); /* satellite number */ - satno[5]='\0'; - chop(satno); - - data->inc=str2num(buff, 8, 8); /* inclination (deg) */ - data->OMG=str2num(buff,17, 8); /* RAAN (deg) */ - data->ecc=str2num(buff,26, 7)*1E-7; /* eccentricity */ - data->omg=str2num(buff,34, 8); /* argument of perigee (deg) */ - data->M =str2num(buff,43, 8); /* mean anomaly (deg) */ - data->n =str2num(buff,52,11); /* mean motion (rev/day) */ - data->rev=(int)str2num(buff,63,5); /* revolution number */ - - if (strcmp(satno,data->satno)) { - trace(2,"tle satno mismatch: %s %s\n",data->satno,satno); - return 0; - } - if (data->n<=0.0||data->ecc<0.0) { - trace(2,"tle data error: %s\n",satno); - return 0; - } - return 1; +static int decode_line2(const char *buff, tled_t *data) { + char satno[16]; + + strncpy(satno, buff + 2, 5); /* satellite number */ + satno[5] = '\0'; + chop(satno); + + data->inc = str2num(buff, 8, 8); /* inclination (deg) */ + data->OMG = str2num(buff, 17, 8); /* RAAN (deg) */ + data->ecc = str2num(buff, 26, 7) * 1E-7; /* eccentricity */ + data->omg = str2num(buff, 34, 8); /* argument of perigee (deg) */ + data->M = str2num(buff, 43, 8); /* mean anomaly (deg) */ + data->n = str2num(buff, 52, 11); /* mean motion (rev/day) */ + data->rev = (int)str2num(buff, 63, 5); /* revolution number */ + + if (strcmp(satno, data->satno)) { + trace(2, "tle satno mismatch: %s %s\n", data->satno, satno); + return 0; + } + if (data->n <= 0.0 || data->ecc < 0.0) { + trace(2, "tle data error: %s\n", satno); + return 0; + } + return 1; } /* add TLE data --------------------------------------------------------------*/ -static int add_data(tle_t *tle, const tled_t *data) -{ - tled_t *tle_data; - - if (tle->n>=tle->nmax) { - tle->nmax=tle->nmax<=0?1024:tle->nmax*2; - - if (!(tle_data=(tled_t *)realloc(tle->data,sizeof(tled_t)*tle->nmax))) { - trace(1,"tle malloc error\n"); - free(tle->data); tle->data=NULL; tle->n=tle->nmax=0; - return 0; - } - tle->data=tle_data; +static int add_data(tle_t *tle, const tled_t *data) { + tled_t *tle_data; + + if (tle->n >= tle->nmax) { + tle->nmax = tle->nmax <= 0 ? 1024 : tle->nmax * 2; + + if (!(tle_data = (tled_t *)realloc(tle->data, sizeof(tled_t) * tle->nmax))) { + trace(1, "tle malloc error\n"); + free(tle->data); + tle->data = NULL; + tle->n = tle->nmax = 0; + return 0; } - tle->data[tle->n++]=*data; - return 1; + tle->data = tle_data; + } + tle->data[tle->n++] = *data; + return 1; } /* compare TLE data by satellite name ----------------------------------------*/ -static int cmp_tle_data(const void *p1, const void *p2) -{ - const tled_t *q1=(const tled_t *)p1,*q2=(const tled_t *)p2; - return strcmp(q1->name,q2->name); +static int cmp_tle_data(const void *p1, const void *p2) { + const tled_t *q1 = (const tled_t *)p1, *q2 = (const tled_t *)p2; + return strcmp(q1->name, q2->name); } /* read TLE file --------------------------------------------------------------- -* read NORAD TLE (two line element) data file (ref [2],[3]) -* args : char *file I NORAD TLE data file -* tle_t *tle O TLE data -* return : status (1:ok,0:error) -* notes : before calling the function, the TLE data should be initialized. -* the file should be in a two line (only TLE) or three line (satellite -* name + TLE) format. -* the characters after # in a line are treated as comments. -*-----------------------------------------------------------------------------*/ -extern int tle_read(const char *file, tle_t *tle) -{ - FILE *fp; - tled_t data={{0}}; - char *p,buff[256]; - int line=0; - - if (!(fp=fopen(file,"r"))) { - trace(2,"tle file open error: %s\n",file); + * read NORAD TLE (two line element) data file (ref [2],[3]) + * args : char *file I NORAD TLE data file + * tle_t *tle O TLE data + * return : status (1:ok,0:error) + * notes : before calling the function, the TLE data should be initialized. + * the file should be in a two line (only TLE) or three line (satellite + * name + TLE) format. + * the characters after # in a line are treated as comments. + *-----------------------------------------------------------------------------*/ +extern int tle_read(const char *file, tle_t *tle) { + FILE *fp; + tled_t data = {{0}}; + char *p, buff[256]; + int line = 0; + + if (!(fp = fopen(file, "r"))) { + trace(2, "tle file open error: %s\n", file); + return 0; + } + while (fgets(buff, sizeof(buff), fp)) { + /* delete comments */ + if ((p = strchr(buff, '#'))) *p = '\0'; + chop(buff); + + if (buff[0] == '1' && checksum(buff)) { + /* decode TLE line 1 */ + if (decode_line1(buff, &data)) line = 1; + } else if (line == 1 && buff[0] == '2' && checksum(buff)) { + /* decode TLE line 2 */ + if (!decode_line2(buff, &data)) continue; + + /* add TLE data */ + if (!add_data(tle, &data)) { + fclose(fp); return 0; + } + data.name[0] = '\0'; + data.alias[0] = '\0'; + } else if (buff[0]) { + /* satellite name in three line format */ + strcpy(data.alias, buff); + + /* omit words in parentheses */ + if ((p = strchr(data.alias, '('))) *p = '\0'; + chop(data.alias); + line = 0; } - while (fgets(buff,sizeof(buff),fp)) { - - /* delete comments */ - if ((p=strchr(buff,'#'))) *p='\0'; - chop(buff); - - if (buff[0]=='1'&&checksum(buff)) { + } + fclose(fp); - /* decode TLE line 1 */ - if (decode_line1(buff,&data)) line=1; - } - else if (line==1&&buff[0]=='2'&&checksum(buff)) { - - /* decode TLE line 2 */ - if (!decode_line2(buff,&data)) continue; - - /* add TLE data */ - if (!add_data(tle,&data)) { - fclose(fp); - return 0; - } - data.name[0]='\0'; - data.alias[0]='\0'; - } - else if (buff[0]) { - - /* satellite name in three line format */ - strcpy(data.alias,buff); - - /* omit words in parentheses */ - if ((p=strchr(data.alias,'('))) *p='\0'; - chop(data.alias); - line=0; - - } - } - fclose(fp); - - /* sort tle data by satellite name */ - if (tle->n>0) qsort(tle->data,tle->n,sizeof(tled_t),cmp_tle_data); - return 1; + /* sort tle data by satellite name */ + if (tle->n > 0) qsort(tle->data, tle->n, sizeof(tled_t), cmp_tle_data); + return 1; } /* read TLE satellite name file ------------------------------------------------ -* read TLE satellite name file -* args : char *file I TLE satellite name file -* tle_t *tle IO TLE data -* return : status (1:ok,0:error) -* notes : before calling the function, call tle_read() to read tle table -* the TLE satellite name file contains the following record as a text -* line. strings after # are treated as comments. -* -* name satno [desig [# comment]] -* -* name : satellite name -* satno: satellite catalog number -* desig: international designator (optional) -*-----------------------------------------------------------------------------*/ -extern int tle_name_read(const char *file, tle_t *tle) -{ - FILE *fp; - tled_t data; - char *p,buff[256],name[256],satno[256],desig[256]; - int i; - - if (!(fp=fopen(file,"r"))) { - trace(2,"tle satellite name file open error: %s\n",file); - return 0; + * read TLE satellite name file + * args : char *file I TLE satellite name file + * tle_t *tle IO TLE data + * return : status (1:ok,0:error) + * notes : before calling the function, call tle_read() to read tle table + * the TLE satellite name file contains the following record as a text + * line. strings after # are treated as comments. + * + * name satno [desig [# comment]] + * + * name : satellite name + * satno: satellite catalog number + * desig: international designator (optional) + *-----------------------------------------------------------------------------*/ +extern int tle_name_read(const char *file, tle_t *tle) { + FILE *fp; + tled_t data; + char *p, buff[256], name[256], satno[256], desig[256]; + int i; + + if (!(fp = fopen(file, "r"))) { + trace(2, "tle satellite name file open error: %s\n", file); + return 0; + } + while (fgets(buff, sizeof(buff), fp)) { + if ((p = strchr(buff, '#'))) *p = '\0'; + + desig[0] = '\0'; + + if (sscanf(buff, "%255s %255s %255s", name, satno, desig) < 2) continue; + satno[5] = '\0'; + + for (i = 0; i < tle->n; i++) { + if (!strcmp(tle->data[i].satno, satno) || !strcmp(tle->data[i].desig, desig)) break; + } + if (i >= tle->n) { + trace(4, "no tle data: satno=%s desig=%s\n", satno, desig); + continue; } - while (fgets(buff,sizeof(buff),fp)) { - - if ((p=strchr(buff,'#'))) *p='\0'; - - desig[0]='\0'; - - if (sscanf(buff,"%255s %255s %255s",name,satno,desig)<2) continue; - satno[5]='\0'; - - for (i=0;in;i++) { - if (!strcmp(tle->data[i].satno,satno)|| - !strcmp(tle->data[i].desig,desig)) break; - } - if (i>=tle->n) { - trace(4,"no tle data: satno=%s desig=%s\n",satno,desig); - continue; - } - if (!*tle->data[i].name) { - strncpy(tle->data[i].name,name,31); - tle->data[i].name[31]='\0'; - } - else { - data=tle->data[i]; - strncpy(data.name,name,31); - data.name[31]='\0'; - if (!add_data(tle,&data)) { - break; - } - } + if (!*tle->data[i].name) { + strncpy(tle->data[i].name, name, 31); + tle->data[i].name[31] = '\0'; + } else { + data = tle->data[i]; + strncpy(data.name, name, 31); + data.name[31] = '\0'; + if (!add_data(tle, &data)) { + break; + } } - fclose(fp); + } + fclose(fp); - /* sort tle data by satellite name */ - if (tle->n>0) qsort(tle->data,tle->n,sizeof(tled_t),cmp_tle_data); - return 1; + /* sort tle data by satellite name */ + if (tle->n > 0) qsort(tle->data, tle->n, sizeof(tled_t), cmp_tle_data); + return 1; } /* satellite position and velocity with TLE data ------------------------------- -* compute satellite position and velocity in ECEF with TLE data -* args : gtime_t time I time (GPST) -* char *name I satellite name ("": not specified) -* char *satno I satellite catalog number ("": not specified) -* char *desig I international designator ("": not specified) -* tle_t *tle I TLE data -* erp_t *erp I EOP data (NULL: not used) -* double *rs O sat position/velocity {x,y,z,vx,vy,vz} (m,m/s) -* return : status (1:ok,0:error) -* notes : the coordinates of the position and velocity are ECEF (ITRF) -* if erp == NULL, polar motion and ut1-utc are neglected -*-----------------------------------------------------------------------------*/ -extern int tle_pos(gtime_t time, const char *name, const char *satno, - const char *desig, const tle_t *tle, const erp_t *erp, - double *rs) -{ - gtime_t tutc; - double tsince,rs_tle[6],rs_pef[6],gmst; - double R1[9]={0},R2[9]={0},R3[9]={0},W[9],erpv[5]={0}; - int i=0,stat=1; - - /* serial search by satellite name or alias if name is empty */ - if (*name) { - for (i=0;in;i++) { - if (!(stat=strcmp(name,tle->data[i].name)) || - ( (tle->data[i].name[0]=='\0') && - !(stat=strcmp(name,tle->data[i].alias)))) break; - } - if (in) stat=0; -#ifdef RTK_DISABLED - // Binary search by satellite name or alias if name is empty. - i = 0; - for (int j=0,k=tle->n-1;j<=k;) { - i=(j+k)/2; - if (!(stat=strcmp(name,tle->data[i].name)) || - ( (tle->data[i].name[0]=='\0') && - !(stat=strcmp(name,tle->data[i].alias)))) break; - if (stat<0) k=i-1; else j=i+1; - } -#endif + * compute satellite position and velocity in ECEF with TLE data + * args : gtime_t time I time (GPST) + * char *name I satellite name ("": not specified) + * char *satno I satellite catalog number ("": not specified) + * char *desig I international designator ("": not specified) + * tle_t *tle I TLE data + * erp_t *erp I EOP data (NULL: not used) + * double *rs O sat position/velocity {x,y,z,vx,vy,vz} (m,m/s) + * return : status (1:ok,0:error) + * notes : the coordinates of the position and velocity are ECEF (ITRF) + * if erp == NULL, polar motion and ut1-utc are neglected + *-----------------------------------------------------------------------------*/ +extern int tle_pos(gtime_t time, const char *name, const char *satno, const char *desig, + const tle_t *tle, const erp_t *erp, double *rs) { + gtime_t tutc; + double tsince, rs_tle[6], rs_pef[6], gmst; + double R1[9] = {0}, R2[9] = {0}, R3[9] = {0}, W[9], erpv[5] = {0}; + int i = 0, stat = 1; + + /* serial search by satellite name or alias if name is empty */ + if (*name) { + for (i = 0; i < tle->n; i++) { + if (!(stat = strcmp(name, tle->data[i].name)) || + ((tle->data[i].name[0] == '\0') && !(stat = strcmp(name, tle->data[i].alias)))) + break; } - /* serial search by catalog no or international designator */ - if (stat&&(*satno||*desig)) { - for (i=0;in;i++) { - if (!strcmp(tle->data[i].satno,satno)|| - !strcmp(tle->data[i].desig,desig)) break; - } - if (in) stat=0; + if (i < tle->n) stat = 0; +#ifdef RTK_DISABLED + // Binary search by satellite name or alias if name is empty. + i = 0; + for (int j = 0, k = tle->n - 1; j <= k;) { + i = (j + k) / 2; + if (!(stat = strcmp(name, tle->data[i].name)) || + ((tle->data[i].name[0] == '\0') && !(stat = strcmp(name, tle->data[i].alias)))) + break; + if (stat < 0) + k = i - 1; + else + j = i + 1; } - if (stat) { - trace(4,"no tle data: name=%s satno=%s desig=%s\n",name,satno,desig); - return 0; +#endif + } + /* serial search by catalog no or international designator */ + if (stat && (*satno || *desig)) { + for (i = 0; i < tle->n; i++) { + if (!strcmp(tle->data[i].satno, satno) || !strcmp(tle->data[i].desig, desig)) break; } - tutc=gpst2utc(time); - - /* time since epoch (min) */ - tsince=timediff(tutc,tle->data[i].epoch)/60.0; - - /* SGP4 model propagator by STR#3 */ - SGP4_STR3(tsince,tle->data+i,rs_tle); - - /* erp values */ - if (erp) geterp(erp,time,erpv); - - /* GMST (rad) */ - gmst=utc2gmst(tutc,erpv[2]); - - /* TEME (true equator, mean eqinox) -> ECEF (ref [2] IID, Appendix C) */ - R1[0]=1.0; R1[4]=R1[8]=cos(-erpv[1]); R1[7]=sin(-erpv[1]); R1[5]=-R1[7]; - R2[4]=1.0; R2[0]=R2[8]=cos(-erpv[0]); R2[2]=sin(-erpv[0]); R2[6]=-R2[2]; - R3[8]=1.0; R3[0]=R3[4]=cos(gmst); R3[3]=sin(gmst); R3[1]=-R3[3]; - matmul("NN",3,1,3,R3,rs_tle ,rs_pef ); - matmul("NN",3,1,3,R3,rs_tle+3,rs_pef+3); - rs_pef[3]+=OMGE*rs_pef[1]; - rs_pef[4]-=OMGE*rs_pef[0]; - matmul("NN",3,3,3,R1,R2,W); - matmul("NN",3,1,3,W,rs_pef ,rs ); - matmul("NN",3,1,3,W,rs_pef+3,rs+3); - return 1; + if (i < tle->n) stat = 0; + } + if (stat) { + trace(4, "no tle data: name=%s satno=%s desig=%s\n", name, satno, desig); + return 0; + } + tutc = gpst2utc(time); + + /* time since epoch (min) */ + tsince = timediff(tutc, tle->data[i].epoch) / 60.0; + + /* SGP4 model propagator by STR#3 */ + SGP4_STR3(tsince, tle->data + i, rs_tle); + + /* erp values */ + if (erp) geterp(erp, time, erpv); + + /* GMST (rad) */ + gmst = utc2gmst(tutc, erpv[2]); + + /* TEME (true equator, mean eqinox) -> ECEF (ref [2] IID, Appendix C) */ + R1[0] = 1.0; + R1[4] = R1[8] = cos(-erpv[1]); + R1[7] = sin(-erpv[1]); + R1[5] = -R1[7]; + R2[4] = 1.0; + R2[0] = R2[8] = cos(-erpv[0]); + R2[2] = sin(-erpv[0]); + R2[6] = -R2[2]; + R3[8] = 1.0; + R3[0] = R3[4] = cos(gmst); + R3[3] = sin(gmst); + R3[1] = -R3[3]; + matmul("NN", 3, 1, 3, R3, rs_tle, rs_pef); + matmul("NN", 3, 1, 3, R3, rs_tle + 3, rs_pef + 3); + rs_pef[3] += OMGE * rs_pef[1]; + rs_pef[4] -= OMGE * rs_pef[0]; + matmul("NN", 3, 3, 3, R1, R2, W); + matmul("NN", 3, 1, 3, W, rs_pef, rs); + matmul("NN", 3, 1, 3, W, rs_pef + 3, rs + 3); + return 1; } diff --git a/src/trace.c b/src/trace.c index 7fd85f6ba..45c0ea261 100644 --- a/src/trace.c +++ b/src/trace.c @@ -9,202 +9,182 @@ static uint32_t tick_trace = 0; /* tick time at traceopen (ms) */ static gtime_t time_trace = {0}; /* time at traceopen */ static rtklib_lock_t lock_trace; /* lock for trace */ -static void traceswap(void) -{ - gtime_t time = utc2gpst(timeget()); - char path[1024]; +static void traceswap(void) { + gtime_t time = utc2gpst(timeget()); + char path[1024]; - rtklib_lock(&lock_trace); + rtklib_lock(&lock_trace); - if ((int)(time2gpst(time, NULL) / INT_SWAP_TRAC) == - (int)(time2gpst(time_trace, NULL) / INT_SWAP_TRAC)) { - rtklib_unlock(&lock_trace); - return; - } - time_trace = time; - - if (!reppath(file_trace, path, time, "", "")) { - rtklib_unlock(&lock_trace); - return; - } - if (fp_trace && fp_trace != stderr) fclose(fp_trace); + if ((int)(time2gpst(time, NULL) / INT_SWAP_TRAC) == + (int)(time2gpst(time_trace, NULL) / INT_SWAP_TRAC)) { + rtklib_unlock(&lock_trace); + return; + } + time_trace = time; - if (!(fp_trace = fopen(path, "w"))) { - fp_trace = stderr; - } + if (!reppath(file_trace, path, time, "", "")) { rtklib_unlock(&lock_trace); + return; + } + if (fp_trace && fp_trace != stderr) fclose(fp_trace); + + if (!(fp_trace = fopen(path, "w"))) { + fp_trace = stderr; + } + rtklib_unlock(&lock_trace); } -extern void traceopen(const char *file) -{ - gtime_t time = utc2gpst(timeget()); - char path[1024]; - - reppath(file, path, time, "", ""); - if (!*path || !(fp_trace = fopen(path, "w"))) fp_trace = stderr; - strcpy(file_trace, file); - tick_trace = tickget(); - time_trace = time; - rtklib_initlock(&lock_trace); +extern void traceopen(const char *file) { + gtime_t time = utc2gpst(timeget()); + char path[1024]; + + reppath(file, path, time, "", ""); + if (!*path || !(fp_trace = fopen(path, "w"))) fp_trace = stderr; + strcpy(file_trace, file); + tick_trace = tickget(); + time_trace = time; + rtklib_initlock(&lock_trace); } -extern void traceclose(void) -{ - if (fp_trace && fp_trace != stderr) fclose(fp_trace); - fp_trace = NULL; - file_trace[0] = '\0'; +extern void traceclose(void) { + if (fp_trace && fp_trace != stderr) fclose(fp_trace); + fp_trace = NULL; + file_trace[0] = '\0'; } extern void tracelevel(int level) { level_trace = level; } extern int gettracelevel(void) { return level_trace; } -extern void trace_impl(int level, const char *format, ...) -{ - va_list ap; - - /* print error message to stderr */ - if (level <= 1) { - va_start(ap, format); - vfprintf(stderr, format, ap); - va_end(ap); - } - if (!fp_trace || level > level_trace) return; - traceswap(); - fprintf(fp_trace, "%d ", level); - va_start(ap, format); - vfprintf(fp_trace, format, ap); - va_end(ap); - fflush(fp_trace); -} -extern void tracet_impl(int level, const char *format, ...) -{ - va_list ap; +extern void trace_impl(int level, const char *format, ...) { + va_list ap; - if (!fp_trace || level > level_trace) return; - traceswap(); - fprintf(fp_trace, "%d %9.3f: ", level, (tickget() - tick_trace) / 1000.0); + /* print error message to stderr */ + if (level <= 1) { va_start(ap, format); - vfprintf(fp_trace, format, ap); + vfprintf(stderr, format, ap); va_end(ap); - fflush(fp_trace); + } + if (!fp_trace || level > level_trace) return; + traceswap(); + fprintf(fp_trace, "%d ", level); + va_start(ap, format); + vfprintf(fp_trace, format, ap); + va_end(ap); + fflush(fp_trace); } -extern void tracemat_impl(int level, const double *A, int n, int m, int p, - int q) -{ - if (!fp_trace || level > level_trace) return; - matfprint(A, n, m, p, q, fp_trace); - fflush(fp_trace); +extern void tracet_impl(int level, const char *format, ...) { + va_list ap; + + if (!fp_trace || level > level_trace) return; + traceswap(); + fprintf(fp_trace, "%d %9.3f: ", level, (tickget() - tick_trace) / 1000.0); + va_start(ap, format); + vfprintf(fp_trace, format, ap); + va_end(ap); + fflush(fp_trace); } -extern void traceobs_impl(int level, const obsd_t *obs, int n) -{ - char str[40], id[8]; - int i; - - if (!fp_trace || level > level_trace) return; - for (i = 0; i < n; i++) { - time2str(obs[i].time, str, 3); - satno2id(obs[i].sat, id); - fprintf(fp_trace, - " (%2d) %s %-3s rcv%d %13.3f %13.3f %13.3f %13.3f %d %d %d %d " - "%3.4f %3.3f %3.1f %3.1f\n", - i + 1, str, id, obs[i].rcv, obs[i].L[0], obs[i].L[1], - obs[i].P[0], obs[i].P[1], obs[i].LLI[0], obs[i].LLI[1], - obs[i].code[0], obs[i].code[1], obs[i].Lstd[0], obs[i].Pstd[0], - obs[i].SNR[0], obs[i].SNR[1]); - } - fflush(fp_trace); +extern void tracemat_impl(int level, const double *A, int n, int m, int p, int q) { + if (!fp_trace || level > level_trace) return; + matfprint(A, n, m, p, q, fp_trace); + fflush(fp_trace); } -extern void tracenav_impl(int level, const nav_t *nav) -{ - char s1[40], s2[40], id[8]; - int i; - - if (!fp_trace || level > level_trace) return; - for (i = 0; i < nav->n; i++) { - time2str(nav->eph[i].toe, s1, 0); - time2str(nav->eph[i].ttr, s2, 0); - satno2id(nav->eph[i].sat, id); - fprintf(fp_trace, "(%3d) %-3s : %s %s %3d %3d %02x\n", i + 1, id, s1, - s2, nav->eph[i].iode, nav->eph[i].iodc, nav->eph[i].svh); - } - fprintf(fp_trace, "(ion) %9.4e %9.4e %9.4e %9.4e\n", nav->ion_gps[0], - nav->ion_gps[1], nav->ion_gps[2], nav->ion_gps[3]); - fprintf(fp_trace, "(ion) %9.4e %9.4e %9.4e %9.4e\n", nav->ion_gps[4], - nav->ion_gps[5], nav->ion_gps[6], nav->ion_gps[7]); - fprintf(fp_trace, "(ion) %9.4e %9.4e %9.4e %9.4e\n", nav->ion_gal[0], - nav->ion_gal[1], nav->ion_gal[2], nav->ion_gal[3]); +extern void traceobs_impl(int level, const obsd_t *obs, int n) { + char str[40], id[8]; + int i; + + if (!fp_trace || level > level_trace) return; + for (i = 0; i < n; i++) { + time2str(obs[i].time, str, 3); + satno2id(obs[i].sat, id); + fprintf(fp_trace, + " (%2d) %s %-3s rcv%d %13.3f %13.3f %13.3f %13.3f %d %d %d %d " + "%3.4f %3.3f %3.1f %3.1f\n", + i + 1, str, id, obs[i].rcv, obs[i].L[0], obs[i].L[1], obs[i].P[0], obs[i].P[1], + obs[i].LLI[0], obs[i].LLI[1], obs[i].code[0], obs[i].code[1], obs[i].Lstd[0], + obs[i].Pstd[0], obs[i].SNR[0], obs[i].SNR[1]); + } + fflush(fp_trace); } -extern void tracegnav_impl(int level, const nav_t *nav) -{ - char s1[40], s2[40], id[8]; - int i; - - if (!fp_trace || level > level_trace) return; - for (i = 0; i < nav->ng; i++) { - time2str(nav->geph[i].toe, s1, 0); - time2str(nav->geph[i].tof, s2, 0); - satno2id(nav->geph[i].sat, id); - fprintf(fp_trace, "(%3d) %-3s : %s %s %2d %2d %8.3f\n", i + 1, id, s1, - s2, nav->geph[i].frq, nav->geph[i].svh, - nav->geph[i].taun * 1E6); - } +extern void tracenav_impl(int level, const nav_t *nav) { + char s1[40], s2[40], id[8]; + int i; + + if (!fp_trace || level > level_trace) return; + for (i = 0; i < nav->n; i++) { + time2str(nav->eph[i].toe, s1, 0); + time2str(nav->eph[i].ttr, s2, 0); + satno2id(nav->eph[i].sat, id); + fprintf(fp_trace, "(%3d) %-3s : %s %s %3d %3d %02x\n", i + 1, id, s1, s2, nav->eph[i].iode, + nav->eph[i].iodc, nav->eph[i].svh); + } + fprintf(fp_trace, "(ion) %9.4e %9.4e %9.4e %9.4e\n", nav->ion_gps[0], nav->ion_gps[1], + nav->ion_gps[2], nav->ion_gps[3]); + fprintf(fp_trace, "(ion) %9.4e %9.4e %9.4e %9.4e\n", nav->ion_gps[4], nav->ion_gps[5], + nav->ion_gps[6], nav->ion_gps[7]); + fprintf(fp_trace, "(ion) %9.4e %9.4e %9.4e %9.4e\n", nav->ion_gal[0], nav->ion_gal[1], + nav->ion_gal[2], nav->ion_gal[3]); } -extern void tracehnav_impl(int level, const nav_t *nav) -{ - char s1[40], s2[40], id[8]; - int i; - - if (!fp_trace || level > level_trace) return; - for (i = 0; i < nav->ns; i++) { - time2str(nav->seph[i].t0, s1, 0); - time2str(nav->seph[i].tof, s2, 0); - satno2id(nav->seph[i].sat, id); - fprintf(fp_trace, "(%3d) %-3s : %s %s %2d %2d\n", i + 1, id, s1, s2, - nav->seph[i].svh, nav->seph[i].sva); - } +extern void tracegnav_impl(int level, const nav_t *nav) { + char s1[40], s2[40], id[8]; + int i; + + if (!fp_trace || level > level_trace) return; + for (i = 0; i < nav->ng; i++) { + time2str(nav->geph[i].toe, s1, 0); + time2str(nav->geph[i].tof, s2, 0); + satno2id(nav->geph[i].sat, id); + fprintf(fp_trace, "(%3d) %-3s : %s %s %2d %2d %8.3f\n", i + 1, id, s1, s2, nav->geph[i].frq, + nav->geph[i].svh, nav->geph[i].taun * 1E6); + } +} +extern void tracehnav_impl(int level, const nav_t *nav) { + char s1[40], s2[40], id[8]; + int i; + + if (!fp_trace || level > level_trace) return; + for (i = 0; i < nav->ns; i++) { + time2str(nav->seph[i].t0, s1, 0); + time2str(nav->seph[i].tof, s2, 0); + satno2id(nav->seph[i].sat, id); + fprintf(fp_trace, "(%3d) %-3s : %s %s %2d %2d\n", i + 1, id, s1, s2, nav->seph[i].svh, + nav->seph[i].sva); + } } -extern void tracepeph_impl(int level, const nav_t *nav) -{ - char s[40], id[8]; - int i, j; - - if (!fp_trace || level > level_trace) return; - - for (i = 0; i < nav->ne; i++) { - time2str(nav->peph[i].time, s, 0); - for (j = 0; j < MAXSAT; j++) { - satno2id(j + 1, id); - fprintf(fp_trace, - "%-3s %d %-3s %13.3f %13.3f %13.3f %13.3f %6.3f %6.3f " - "%6.3f %6.3f\n", - s, nav->peph[i].index, id, nav->peph[i].pos[j][0], - nav->peph[i].pos[j][1], nav->peph[i].pos[j][2], - nav->peph[i].pos[j][3] * 1E9, nav->peph[i].std[j][0], - nav->peph[i].std[j][1], nav->peph[i].std[j][2], - nav->peph[i].std[j][3] * 1E9); - } +extern void tracepeph_impl(int level, const nav_t *nav) { + char s[40], id[8]; + int i, j; + + if (!fp_trace || level > level_trace) return; + + for (i = 0; i < nav->ne; i++) { + time2str(nav->peph[i].time, s, 0); + for (j = 0; j < MAXSAT; j++) { + satno2id(j + 1, id); + fprintf(fp_trace, + "%-3s %d %-3s %13.3f %13.3f %13.3f %13.3f %6.3f %6.3f " + "%6.3f %6.3f\n", + s, nav->peph[i].index, id, nav->peph[i].pos[j][0], nav->peph[i].pos[j][1], + nav->peph[i].pos[j][2], nav->peph[i].pos[j][3] * 1E9, nav->peph[i].std[j][0], + nav->peph[i].std[j][1], nav->peph[i].std[j][2], nav->peph[i].std[j][3] * 1E9); } + } } -extern void tracepclk_impl(int level, const nav_t *nav) -{ - char s[40], id[8]; - int i, j; - - if (!fp_trace || level > level_trace) return; - - for (i = 0; i < nav->nc; i++) { - time2str(nav->pclk[i].time, s, 0); - for (j = 0; j < MAXSAT; j++) { - satno2id(j + 1, id); - fprintf(fp_trace, "%-3s %d %-3s %13.3f %6.3f\n", s, - nav->pclk[i].index, id, nav->pclk[i].clk[j][0] * 1E9, - nav->pclk[i].std[j][0] * 1E9); - } +extern void tracepclk_impl(int level, const nav_t *nav) { + char s[40], id[8]; + int i, j; + + if (!fp_trace || level > level_trace) return; + + for (i = 0; i < nav->nc; i++) { + time2str(nav->pclk[i].time, s, 0); + for (j = 0; j < MAXSAT; j++) { + satno2id(j + 1, id); + fprintf(fp_trace, "%-3s %d %-3s %13.3f %6.3f\n", s, nav->pclk[i].index, id, + nav->pclk[i].clk[j][0] * 1E9, nav->pclk[i].std[j][0] * 1E9); } + } } -extern void traceb_impl(int level, const uint8_t *p, int n) -{ - int i; - if (!fp_trace || level > level_trace) return; - for (i = 0; i < n; i++) - fprintf(fp_trace, "%02X%s", *p++, i % 8 == 7 ? " " : ""); - fprintf(fp_trace, "\n"); +extern void traceb_impl(int level, const uint8_t *p, int n) { + int i; + if (!fp_trace || level > level_trace) return; + for (i = 0; i < n; i++) fprintf(fp_trace, "%02X%s", *p++, i % 8 == 7 ? " " : ""); + fprintf(fp_trace, "\n"); } #endif /* TRACE */ diff --git a/test/utest/t_atmos.c b/test/utest/t_atmos.c index 89dbf441a..9f1681b15 100644 --- a/test/utest/t_atmos.c +++ b/test/utest/t_atmos.c @@ -1,150 +1,140 @@ /*------------------------------------------------------------------------------ -* rtklib unit test driver : atomospheric models -*-----------------------------------------------------------------------------*/ -#include + * rtklib unit test driver : atomospheric models + *-----------------------------------------------------------------------------*/ #include +#include + #include "../../src/rtklib.h" /* ionmodel() */ -void utest1(void) -{ - double e1[]={2007,1,16, 1,0,0}; - double e2[]={2007,1,16,13,0,0}; - double e3[]={2007,1,16,22,0,0}; - double ion1[]={ - 0.2E-7,-0.8e-8,-0.5e-7, 0.1e-6, 0.2E+6, 0.2e+6,-0.1e+6,-0.1e+7 - }; - double ion2[]={ - 0.2E-7,-0.8e-8,-0.5e-7, 0.1e-6, 0.2E+6, 0.2e+6,-0.1e+6,-0.1e+7 - }; - double pos1 []={ 35*D2R, 140*D2R, 100.0}; - double pos2 []={-80*D2R,-170*D2R,1000.0}; - double pos3 []={ 10*D2R, 30*D2R, 0.0}; - double azel1[]={ 60*D2R, 75*D2R}; - double azel2[]={190*D2R, 3*D2R}; - double azel3[]={350*D2R, 60*D2R}; - double azel4[]={ 0*D2R, 90*D2R}; - gtime_t t1=epoch2time(e1),t2=epoch2time(e2),t3=epoch2time(e3); - double dion; - - dion=ionmodel(t1,ion1,pos1,azel1); - assert(fabs(dion-6.73590532099438)<1e-8); - - dion=ionmodel(t1,ion1,pos2,azel1); - assert(fabs(dion-3.56895382197387)<1e-8); - - dion=ionmodel(t1,ion1,pos3,azel1); - assert(fabs(dion-3.80716435655161)<1e-8); - - dion=ionmodel(t2,ion1,pos1,azel1); - assert(fabs(dion-5.21796954585452)<1e-8); - - dion=ionmodel(t3,ion1,pos1,azel1); - assert(fabs(dion-5.90190539264777)<1e-8); - - dion=ionmodel(t1,ion1,pos1,azel2); - assert(fabs(dion-21.6345415123632)<1e-8); - - dion=ionmodel(t1,ion1,pos1,azel3); - assert(fabs(dion-7.33844278822561)<1e-8); - - dion=ionmodel(t1,ion1,pos1,azel4); - assert(fabs(dion-6.58339711400694)<1e-8); - - dion=ionmodel(t1,ion2,pos1,azel1); - assert(fabs(dion-6.73590532099438)<1e-8); - - printf("%s utest1 : OK\n",__FILE__); +void utest1(void) { + double e1[] = {2007, 1, 16, 1, 0, 0}; + double e2[] = {2007, 1, 16, 13, 0, 0}; + double e3[] = {2007, 1, 16, 22, 0, 0}; + double ion1[] = {0.2E-7, -0.8e-8, -0.5e-7, 0.1e-6, 0.2E+6, 0.2e+6, -0.1e+6, -0.1e+7}; + double ion2[] = {0.2E-7, -0.8e-8, -0.5e-7, 0.1e-6, 0.2E+6, 0.2e+6, -0.1e+6, -0.1e+7}; + double pos1[] = {35 * D2R, 140 * D2R, 100.0}; + double pos2[] = {-80 * D2R, -170 * D2R, 1000.0}; + double pos3[] = {10 * D2R, 30 * D2R, 0.0}; + double azel1[] = {60 * D2R, 75 * D2R}; + double azel2[] = {190 * D2R, 3 * D2R}; + double azel3[] = {350 * D2R, 60 * D2R}; + double azel4[] = {0 * D2R, 90 * D2R}; + gtime_t t1 = epoch2time(e1), t2 = epoch2time(e2), t3 = epoch2time(e3); + double dion; + + dion = ionmodel(t1, ion1, pos1, azel1); + assert(fabs(dion - 6.73590532099438) < 1e-8); + + dion = ionmodel(t1, ion1, pos2, azel1); + assert(fabs(dion - 3.56895382197387) < 1e-8); + + dion = ionmodel(t1, ion1, pos3, azel1); + assert(fabs(dion - 3.80716435655161) < 1e-8); + + dion = ionmodel(t2, ion1, pos1, azel1); + assert(fabs(dion - 5.21796954585452) < 1e-8); + + dion = ionmodel(t3, ion1, pos1, azel1); + assert(fabs(dion - 5.90190539264777) < 1e-8); + + dion = ionmodel(t1, ion1, pos1, azel2); + assert(fabs(dion - 21.6345415123632) < 1e-8); + + dion = ionmodel(t1, ion1, pos1, azel3); + assert(fabs(dion - 7.33844278822561) < 1e-8); + + dion = ionmodel(t1, ion1, pos1, azel4); + assert(fabs(dion - 6.58339711400694) < 1e-8); + + dion = ionmodel(t1, ion2, pos1, azel1); + assert(fabs(dion - 6.73590532099438) < 1e-8); + + printf("%s utest1 : OK\n", __FILE__); } /* ionmapf() */ -void utest2(void) -{ - printf("%s utest2 : OK\n",__FILE__); -} +void utest2(void) { printf("%s utest2 : OK\n", __FILE__); } /* tropmodel */ -void utest3(void) -{ - gtime_t time={0}; - double pos1 []={ 35*D2R, 140*D2R, 100.0}; - double pos2 []={-80*D2R,-170*D2R,1000.0}; - double pos3 []={-80*D2R,-170*D2R,100000.0}; - double pos4 []={-80*D2R,-170*D2R,-200.0}; - double azel1[]={ 60*D2R, 75*D2R}; - double azel2[]={190*D2R, 3*D2R}; - double azel3[]={190*D2R,-10*D2R}; - double dtrp; - - dtrp=tropmodel(time,pos1,azel1,0.5); - assert(fabs(dtrp-2.44799870144088)<1e-8); - - dtrp=tropmodel(time,pos1,azel2,0.5); - assert(fabs(dtrp-45.1808916506163)<1e-8); - - dtrp=tropmodel(time,pos2,azel1,0.5); - assert(fabs(dtrp-2.17295817298152)<1e-8); - - dtrp=tropmodel(time,pos1,azel3,0.0); - assert(fabs(dtrp-0.00000000000000)<1e-8); - - dtrp=tropmodel(time,pos3,azel1,0.0); - assert(fabs(dtrp-0.00000000000000)<1e-8); - - dtrp=tropmodel(time,pos4,azel1,0.0); - assert(fabs(dtrp-0.00000000000000)<1e-8); - - printf("%s utest3 : OK\n",__FILE__); +void utest3(void) { + gtime_t time = {0}; + double pos1[] = {35 * D2R, 140 * D2R, 100.0}; + double pos2[] = {-80 * D2R, -170 * D2R, 1000.0}; + double pos3[] = {-80 * D2R, -170 * D2R, 100000.0}; + double pos4[] = {-80 * D2R, -170 * D2R, -200.0}; + double azel1[] = {60 * D2R, 75 * D2R}; + double azel2[] = {190 * D2R, 3 * D2R}; + double azel3[] = {190 * D2R, -10 * D2R}; + double dtrp; + + dtrp = tropmodel(time, pos1, azel1, 0.5); + assert(fabs(dtrp - 2.44799870144088) < 1e-8); + + dtrp = tropmodel(time, pos1, azel2, 0.5); + assert(fabs(dtrp - 45.1808916506163) < 1e-8); + + dtrp = tropmodel(time, pos2, azel1, 0.5); + assert(fabs(dtrp - 2.17295817298152) < 1e-8); + + dtrp = tropmodel(time, pos1, azel3, 0.0); + assert(fabs(dtrp - 0.00000000000000) < 1e-8); + + dtrp = tropmodel(time, pos3, azel1, 0.0); + assert(fabs(dtrp - 0.00000000000000) < 1e-8); + + dtrp = tropmodel(time, pos4, azel1, 0.0); + assert(fabs(dtrp - 0.00000000000000) < 1e-8); + + printf("%s utest3 : OK\n", __FILE__); } -void utest4(void) -{ - double mapfd,mapfw; - double e1[]={2007,1,16,6,0,0},e2[]={2030,12,31,23,59,59}; - double pos1 []={ 35*D2R, 140*D2R, 100.0}; - double pos2 []={-80*D2R,-170*D2R,1000.0}; - double pos3 []={ 10*D2R, 30*D2R, 0.0}; - double azel1[]={ 60*D2R, 75*D2R}; - double azel2[]={190*D2R, 3*D2R}; - double azel3[]={350*D2R, 60*D2R}; - double azel4[]={ 0*D2R, 90*D2R}; - gtime_t t1=epoch2time(e1),t2=epoch2time(e2); - - mapfd=tropmapf(t1,pos1,azel1,&mapfw); - assert(fabs(mapfd-1.035184526466435)<1e-8); - assert(fabs(mapfw-1.035233787448654)<1e-8); - - mapfd=tropmapf(t1,pos1,azel2,&mapfw); - assert(fabs(mapfd-14.643271711748200)<1e-8); - assert(fabs(mapfw-16.455045694559484)<1e-8); - - mapfd=tropmapf(t1,pos1,azel3,&mapfw); - assert(fabs(mapfd-1.154226397147367)<1e-8); - assert(fabs(mapfw-1.154481126139610)<1e-8); - - mapfd=tropmapf(t1,pos1,azel4,&mapfw); - assert(fabs(mapfd-1.000000000000000)<1e-8); - assert(fabs(mapfw-1.000000000000000)<1e-8); - - mapfd=tropmapf(t2,pos1,azel1,&mapfw); - assert(fabs(mapfd-1.035184415128022)<1e-8); - assert(fabs(mapfw-1.035233787448654)<1e-8); - - mapfd=tropmapf(t1,pos2,azel1,&mapfw); - assert(fabs(mapfd-1.035186155749051)<1e-8); - assert(fabs(mapfw-1.035230548304367)<1e-8); - - mapfd=tropmapf(t1,pos3,azel1,&mapfw); - assert(fabs(mapfd-1.035181919429758)<1e-8); - assert(fabs(mapfw-1.035233200318210)<1e-8); - - mapfd=tropmapf(t1,pos1,azel1,NULL); - assert(fabs(mapfd-1.035184526466435)<1e-8); - - printf("%s utest4 : OK\n",__FILE__); +void utest4(void) { + double mapfd, mapfw; + double e1[] = {2007, 1, 16, 6, 0, 0}, e2[] = {2030, 12, 31, 23, 59, 59}; + double pos1[] = {35 * D2R, 140 * D2R, 100.0}; + double pos2[] = {-80 * D2R, -170 * D2R, 1000.0}; + double pos3[] = {10 * D2R, 30 * D2R, 0.0}; + double azel1[] = {60 * D2R, 75 * D2R}; + double azel2[] = {190 * D2R, 3 * D2R}; + double azel3[] = {350 * D2R, 60 * D2R}; + double azel4[] = {0 * D2R, 90 * D2R}; + gtime_t t1 = epoch2time(e1), t2 = epoch2time(e2); + + mapfd = tropmapf(t1, pos1, azel1, &mapfw); + assert(fabs(mapfd - 1.035184526466435) < 1e-8); + assert(fabs(mapfw - 1.035233787448654) < 1e-8); + + mapfd = tropmapf(t1, pos1, azel2, &mapfw); + assert(fabs(mapfd - 14.643271711748200) < 1e-8); + assert(fabs(mapfw - 16.455045694559484) < 1e-8); + + mapfd = tropmapf(t1, pos1, azel3, &mapfw); + assert(fabs(mapfd - 1.154226397147367) < 1e-8); + assert(fabs(mapfw - 1.154481126139610) < 1e-8); + + mapfd = tropmapf(t1, pos1, azel4, &mapfw); + assert(fabs(mapfd - 1.000000000000000) < 1e-8); + assert(fabs(mapfw - 1.000000000000000) < 1e-8); + + mapfd = tropmapf(t2, pos1, azel1, &mapfw); + assert(fabs(mapfd - 1.035184415128022) < 1e-8); + assert(fabs(mapfw - 1.035233787448654) < 1e-8); + + mapfd = tropmapf(t1, pos2, azel1, &mapfw); + assert(fabs(mapfd - 1.035186155749051) < 1e-8); + assert(fabs(mapfw - 1.035230548304367) < 1e-8); + + mapfd = tropmapf(t1, pos3, azel1, &mapfw); + assert(fabs(mapfd - 1.035181919429758) < 1e-8); + assert(fabs(mapfw - 1.035233200318210) < 1e-8); + + mapfd = tropmapf(t1, pos1, azel1, NULL); + assert(fabs(mapfd - 1.035184526466435) < 1e-8); + + printf("%s utest4 : OK\n", __FILE__); } -int main(void) -{ - utest1(); - utest2(); - utest3(); - utest4(); - return 0; +int main(void) { + utest1(); + utest2(); + utest3(); + utest4(); + return 0; } diff --git a/test/utest/t_coord.c b/test/utest/t_coord.c index dae71351d..8596a7a39 100644 --- a/test/utest/t_coord.c +++ b/test/utest/t_coord.c @@ -1,94 +1,88 @@ /*------------------------------------------------------------------------------ -* rtklib unit test driver : coordinates functions -*-----------------------------------------------------------------------------*/ -#include -#include + * rtklib unit test driver : coordinates functions + *-----------------------------------------------------------------------------*/ #include +#include +#include + #include "../../src/rtklib.h" /* ecef2pos() */ -void utest1(void) -{ - double r1[]={ 0.0, 0.0, 0.0}; - double r2[]={10000000.0, 0.0, 0.0}; - double r3[]={ 0.0,10000000.0, 0.0}; - double r4[]={ 0.0, 0.0, 10000000.0}; - double r5[]={ 0.0, 0.0,-10000000.0}; - double r6[]={-3.5173197701E+06,4.1316679161E+06, 3.3412651227E+06}; - double r7[]={-3.5173197701E+06,4.1316679161E+06,-3.3412651227E+06}; - double pos[3]; - ecef2pos(r1,pos); - assert(pos[2]<0.0); - ecef2pos(r2,pos); - assert(pos[0]==0&&pos[1]==0&&pos[2]>0.0); - ecef2pos(r3,pos); - assert(pos[0]==0&&fabs(pos[1]-PI/2)<1E-6&&pos[2]>0.0); - ecef2pos(r4,pos); - assert(fabs(pos[0]-PI/2)<1E-6&&pos[2]>0.0); - ecef2pos(r5,pos); - assert(fabs(pos[0]+PI/2)<1E-6&&pos[2]>0.0); - ecef2pos(r6,pos); - assert(fabs(pos[0]*R2D-3.1796021375E+01)<1E-7&& - fabs(pos[1]*R2D-1.3040799917E+02)<1E-7&& - fabs(pos[2]-6.8863206206E+01)<1E-4); - ecef2pos(r7,pos); - assert(fabs(pos[0]*R2D+3.1796021375E+01)<1E-7&& - fabs(pos[1]*R2D-1.3040799917E+02)<1E-7&& - fabs(pos[2]-6.8863206206E+01)<1E-4); - - printf("%s utset1 : OK\n",__FILE__); +void utest1(void) { + double r1[] = {0.0, 0.0, 0.0}; + double r2[] = {10000000.0, 0.0, 0.0}; + double r3[] = {0.0, 10000000.0, 0.0}; + double r4[] = {0.0, 0.0, 10000000.0}; + double r5[] = {0.0, 0.0, -10000000.0}; + double r6[] = {-3.5173197701E+06, 4.1316679161E+06, 3.3412651227E+06}; + double r7[] = {-3.5173197701E+06, 4.1316679161E+06, -3.3412651227E+06}; + double pos[3]; + ecef2pos(r1, pos); + assert(pos[2] < 0.0); + ecef2pos(r2, pos); + assert(pos[0] == 0 && pos[1] == 0 && pos[2] > 0.0); + ecef2pos(r3, pos); + assert(pos[0] == 0 && fabs(pos[1] - PI / 2) < 1E-6 && pos[2] > 0.0); + ecef2pos(r4, pos); + assert(fabs(pos[0] - PI / 2) < 1E-6 && pos[2] > 0.0); + ecef2pos(r5, pos); + assert(fabs(pos[0] + PI / 2) < 1E-6 && pos[2] > 0.0); + ecef2pos(r6, pos); + assert(fabs(pos[0] * R2D - 3.1796021375E+01) < 1E-7 && + fabs(pos[1] * R2D - 1.3040799917E+02) < 1E-7 && fabs(pos[2] - 6.8863206206E+01) < 1E-4); + ecef2pos(r7, pos); + assert(fabs(pos[0] * R2D + 3.1796021375E+01) < 1E-7 && + fabs(pos[1] * R2D - 1.3040799917E+02) < 1E-7 && fabs(pos[2] - 6.8863206206E+01) < 1E-4); + + printf("%s utset1 : OK\n", __FILE__); } /* pos2ecef() */ -void utest2(void) -{ - double lat,lon,h,pos[3],posi[3]; - double r[3]; - for (lat=-90.0;lat<=90.0;lat+=5.0) { - for (lon=-180.0;lon<180.0;lon+=5.0) { - for (h=-10.0;h<10000.0;h+=100.0) { - pos[0]=lat*D2R; pos[1]=lon*D2R; pos[2]=h; - pos2ecef(pos,r); - ecef2pos(r,posi); - assert(fabs(lat-posi[0]*R2D)<1E-7&& - (lat==-90.0||lat==90.0?1:fabs(lon-posi[1]*R2D)<1E-7)&& - fabs(h-posi[2])<1E-4); - } - } +void utest2(void) { + double lat, lon, h, pos[3], posi[3]; + double r[3]; + for (lat = -90.0; lat <= 90.0; lat += 5.0) { + for (lon = -180.0; lon < 180.0; lon += 5.0) { + for (h = -10.0; h < 10000.0; h += 100.0) { + pos[0] = lat * D2R; + pos[1] = lon * D2R; + pos[2] = h; + pos2ecef(pos, r); + ecef2pos(r, posi); + assert(fabs(lat - posi[0] * R2D) < 1E-7 && + (lat == -90.0 || lat == 90.0 ? 1 : fabs(lon - posi[1] * R2D) < 1E-7) && + fabs(h - posi[2]) < 1E-4); + } } - - printf("%s utset2 : OK\n",__FILE__); + } + + printf("%s utset2 : OK\n", __FILE__); } /* ecef2enu(), enu2ecef() */ -void utest3(void) -{ - double pos1[]={ 0.000*D2R, 0.000*D2R,0.0}; - double pos2[]={35.000*D2R,140.000*D2R,0.0}; - double r1[]={1.0,0.0,0.0}; - double r2[]={0.0,1.0,0.0}; - double r3[]={0.0,0.0,1.0}; - double r4[]={0.3,0.4,0.5}; - double e[3],r[3]; - ecef2enu(pos1,r1,e); - assert(e[0]==0.0&&e[1]==0.0&&e[2]==1.0); - ecef2enu(pos1,r2,e); - assert(e[0]==1.0&&e[1]==0.0&&e[2]==0.0); - ecef2enu(pos1,r3,e); - assert(e[0]==0.0&&e[1]==1.0&&e[2]==0.0); - ecef2enu(pos2,r4,e); - assert(fabs(e[0]+0.499254)<1E-6&& - fabs(e[1]-0.393916)<1E-6&& - fabs(e[2]-0.309152)<1E-6); - enu2ecef(pos2,e,r); - assert(fabs(r[0]-r4[0])<1E-6&& - fabs(r[1]-r4[1])<1E-6&& - fabs(r[2]-r4[2])<1E-6); +void utest3(void) { + double pos1[] = {0.000 * D2R, 0.000 * D2R, 0.0}; + double pos2[] = {35.000 * D2R, 140.000 * D2R, 0.0}; + double r1[] = {1.0, 0.0, 0.0}; + double r2[] = {0.0, 1.0, 0.0}; + double r3[] = {0.0, 0.0, 1.0}; + double r4[] = {0.3, 0.4, 0.5}; + double e[3], r[3]; + ecef2enu(pos1, r1, e); + assert(e[0] == 0.0 && e[1] == 0.0 && e[2] == 1.0); + ecef2enu(pos1, r2, e); + assert(e[0] == 1.0 && e[1] == 0.0 && e[2] == 0.0); + ecef2enu(pos1, r3, e); + assert(e[0] == 0.0 && e[1] == 1.0 && e[2] == 0.0); + ecef2enu(pos2, r4, e); + assert(fabs(e[0] + 0.499254) < 1E-6 && fabs(e[1] - 0.393916) < 1E-6 && + fabs(e[2] - 0.309152) < 1E-6); + enu2ecef(pos2, e, r); + assert(fabs(r[0] - r4[0]) < 1E-6 && fabs(r[1] - r4[1]) < 1E-6 && fabs(r[2] - r4[2]) < 1E-6); - printf("%s utset3 : OK\n",__FILE__); + printf("%s utset3 : OK\n", __FILE__); } -int main(void) -{ - utest1(); - utest2(); - utest3(); - return 0; +int main(void) { + utest1(); + utest2(); + utest3(); + return 0; } diff --git a/test/utest/t_corrperf.c b/test/utest/t_corrperf.c index db2c38556..724d6efd8 100644 --- a/test/utest/t_corrperf.c +++ b/test/utest/t_corrperf.c @@ -1,43 +1,45 @@ /* correlator performance test */ #include + #include "sdr.h" -int main(int argc, char **argc) -{ - double f_s[]={38.192e6,16.368e6,8.184e6}; - double taums[]={1,2,4,8,16}; - double tau,ns,crate,coff,freq,phi0,ti; - double I[3],Q[3]; +int main(int argc, char **argc) { + double f_s[] = {38.192e6, 16.368e6, 8.184e6}; + double taums[] = {1, 2, 4, 8, 16}; + double tau, ns, crate, coff, freq, phi0, ti; + double I[3], Q[3]; char *data; - int i,j,k,dtype,sat,s,nc,nt,n; + int i, j, k, dtype, sat, s, nc, nt, n; - dtype=1; - sat =1; - freq =9.548e6; - crate=1023000; - coff =1234.5; - s =20; + dtype = 1; + sat = 1; + freq = 9.548e6; + crate = 1023000; + coff = 1234.5; + s = 20; - for (i=0;i<4;i++) for (j=0;j<5;j++) { + for (i = 0; i < 4; i++) + for (j = 0; j < 5; j++) { + printf('sampling rate=%.3fMHz\n', f_s / 1e6); - printf('sampling rate=%.3fMHz\n',f_s/1e6); + tau = taums[j] * 1e-3; + ns = tau * f_s[i]; + if (dtype) + nt = ns * 2; + else + nt = ns; + phi0 = 0.1234; + data = int8((rand(1, nt) - 0.5) * 4); + ti = 1 / f_s; + n = 100000 / taums; - tau =taums[j]*1e-3; - ns =tau*f_s[i]; - if (dtype) nt=ns*2; else nt=ns; - phi0 =0.1234; - data=int8((rand(1,nt)-0.5)*4); - ti =1/f_s; - n =100000/taums; + tic, for (k = 0; k < n; k++) { + correlator(data, dtype, ti, freq, phi0, sat, 0, crate, coff, s, 1, I, Q); + } + t = toc; - tic, - for (k=0;k -static void printmat(const double *A, int n, int m) -{ - int i,j; - for (i=0;i -#include + * rtklib unit test driver : geoid functions + *-----------------------------------------------------------------------------*/ #include +#include +#include + #include "../../src/rtklib.h" /* latitude, longitude, geoid height (m) */ /* reference : http://sps.unavco.org/geoid */ -static double poss[][3]={ - { 90.001*D2R, 80.000*D2R, 0.000}, - {-90.001*D2R, 80.000*D2R, 0.000}, - { 30.000*D2R, 360.000*D2R, 0.000}, - {-30.000*D2R,-360.001*D2R, 0.000}, - {-90.000*D2R, 359.999*D2R,-29.534}, - { 90.000*D2R, 80.000*D2R, 13.606}, - {-90.000*D2R, -60.000*D2R,-29.534}, - { 30.000*D2R,-360.000*D2R, 35.387}, - {-30.000*D2R, 359.999*D2R, 21.409}, - { 10.000*D2R, 45.000*D2R,-20.486}, - {-60.123*D2R, 135.123*D2R,-33.152}, - { 19.999*D2R, 135.000*D2R, 41.602}, - { 50.001*D2R, 135.000*D2R, 20.555}, - { 35.000*D2R, 119.999*D2R, 4.386}, - { 35.000*D2R, 150.001*D2R, 14.779}, - { 20.000*D2R, 120.000*D2R, 21.269}, - { 50.000*D2R, 150.000*D2R, 20.277}, - { 35.000*D2R, 135.000*D2R, 36.355}, - { 45.402*D2R, 141.750*D2R, 27.229}, /* wakkanai */ - { 24.454*D2R, 122.942*D2R, 21.652}, /* ishigaki */ - { 33.120*D2R, 139.797*D2R, 43.170}, /* hachijo */ - { 30.000*D2R, 135.000*D2R, 36.017}, /* taiheiyo */ - {0,0,0} -}; +static double poss[][3] = {{90.001 * D2R, 80.000 * D2R, 0.000}, + {-90.001 * D2R, 80.000 * D2R, 0.000}, + {30.000 * D2R, 360.000 * D2R, 0.000}, + {-30.000 * D2R, -360.001 * D2R, 0.000}, + {-90.000 * D2R, 359.999 * D2R, -29.534}, + {90.000 * D2R, 80.000 * D2R, 13.606}, + {-90.000 * D2R, -60.000 * D2R, -29.534}, + {30.000 * D2R, -360.000 * D2R, 35.387}, + {-30.000 * D2R, 359.999 * D2R, 21.409}, + {10.000 * D2R, 45.000 * D2R, -20.486}, + {-60.123 * D2R, 135.123 * D2R, -33.152}, + {19.999 * D2R, 135.000 * D2R, 41.602}, + {50.001 * D2R, 135.000 * D2R, 20.555}, + {35.000 * D2R, 119.999 * D2R, 4.386}, + {35.000 * D2R, 150.001 * D2R, 14.779}, + {20.000 * D2R, 120.000 * D2R, 21.269}, + {50.000 * D2R, 150.000 * D2R, 20.277}, + {35.000 * D2R, 135.000 * D2R, 36.355}, + {45.402 * D2R, 141.750 * D2R, 27.229}, /* wakkanai */ + {24.454 * D2R, 122.942 * D2R, 21.652}, /* ishigaki */ + {33.120 * D2R, 139.797 * D2R, 43.170}, /* hachijo */ + {30.000 * D2R, 135.000 * D2R, 36.017}, /* taiheiyo */ + {0, 0, 0}}; #define DATADIR "../../../../data/geoiddata/" -static char *file1=DATADIR "WW15MGH.DAC"; -static char *file2=DATADIR "Und_min1x1_egm2008_isw=82_WGS84_TideFree_SE"; -static char *file3=DATADIR "Und_min2.5x2.5_egm2008_isw=82_WGS84_TideFree_SE"; -static char *file4=DATADIR "gsigeome.ver4"; +static char *file1 = DATADIR "WW15MGH.DAC"; +static char *file2 = DATADIR "Und_min1x1_egm2008_isw=82_WGS84_TideFree_SE"; +static char *file3 = DATADIR "Und_min2.5x2.5_egm2008_isw=82_WGS84_TideFree_SE"; +static char *file4 = DATADIR "gsigeome.ver4"; /* opengeoid(), closegeoid() */ -void utest1(void) -{ - int ret; - - ret=opengeoid(10,file1); - assert(ret==0); /* no model */ - ret=opengeoid(GEOID_EGM96_M150, "../../../geoiddata/WW15MGH.DAA"); - assert(ret==0); /* no file */ - ret=opengeoid(GEOID_EMBEDDED, ""); - assert(ret==1); - closegeoid(); +void utest1(void) { + int ret; + + ret = opengeoid(10, file1); + assert(ret == 0); /* no model */ + ret = opengeoid(GEOID_EGM96_M150, "../../../geoiddata/WW15MGH.DAA"); + assert(ret == 0); /* no file */ + ret = opengeoid(GEOID_EMBEDDED, ""); + assert(ret == 1); + closegeoid(); #ifdef RTK_DISABLED // geoid files are not included in the rtklib distribution - ret=opengeoid(GEOID_EGM96_M150,file1); - assert(ret==1); - closegeoid(); - ret=opengeoid(GEOID_EGM2008_M10,file2); - assert(ret==1); - closegeoid(); - ret=opengeoid(GEOID_EGM2008_M25,file3); - assert(ret==1); - closegeoid(); - ret=opengeoid(GEOID_GSI2000_M15,file4); - assert(ret==1); - closegeoid(); + ret = opengeoid(GEOID_EGM96_M150, file1); + assert(ret == 1); + closegeoid(); + ret = opengeoid(GEOID_EGM2008_M10, file2); + assert(ret == 1); + closegeoid(); + ret = opengeoid(GEOID_EGM2008_M25, file3); + assert(ret == 1); + closegeoid(); + ret = opengeoid(GEOID_GSI2000_M15, file4); + assert(ret == 1); + closegeoid(); #endif - - printf("%s utset1 : OK\n",__FILE__); + + printf("%s utset1 : OK\n", __FILE__); } /* print difference */ -void printgeoid(const double *pos, double *h, int n) -{ - int i; - printf("%7.3f %8.3f %9.4f: ",pos[0]*R2D,pos[1]*R2D,pos[2]); - for (i=0;ifabs(dhmax[k])) dhmax[k]=dh; - } - } - printf("max difference :"); - for (i=1;i<5;i++) { - printf(" %9.4f",dhmax[i]); - assert(fabs(dhmax[i])<10.0); +void utest3(void) { + double pos[3], h[6], dhmax[6] = {0}, dh; + int i, j, k, nlat = 113, nlon = 237; + + for (i = 0; i <= nlat; i++) + for (j = 0; j <= nlon; j++) { + pos[0] = (90.0 - i * 180.0 / nlat) * D2R; + pos[1] = j * 360.0 / nlon * D2R; + pos[2] = 0.0; + opengeoid(GEOID_EGM96_M150, file1); /* reference */ + h[0] = geoidh(pos); + closegeoid(); + opengeoid(GEOID_EMBEDDED, ""); + h[1] = geoidh(pos); + closegeoid(); + opengeoid(GEOID_EGM2008_M10, file2); + h[2] = geoidh(pos); + closegeoid(); + opengeoid(GEOID_EGM2008_M25, file3); + h[3] = geoidh(pos); + closegeoid(); + opengeoid(GEOID_GSI2000_M15, file4); + h[4] = geoidh(pos); + closegeoid(); + printgeoid(pos, h, 5); + for (k = 1; k < 5; k++) { + dh = h[k] != 0.0 ? h[k] - h[0] : 0.0; + if (fabs(dh) > fabs(dhmax[k])) dhmax[k] = dh; + } } - printf("\n"); - printf("%s utset3 : OK\n",__FILE__); + printf("max difference :"); + for (i = 1; i < 5; i++) { + printf(" %9.4f", dhmax[i]); + assert(fabs(dhmax[i]) < 10.0); + } + printf("\n"); + printf("%s utset3 : OK\n", __FILE__); } -int main(void) -{ - utest1(); - utest2(); - utest3(); - return 0; +int main(void) { + utest1(); + utest2(); + utest3(); + return 0; } diff --git a/test/utest/t_gloeph.c b/test/utest/t_gloeph.c index f21ce7657..288ca002e 100644 --- a/test/utest/t_gloeph.c +++ b/test/utest/t_gloeph.c @@ -1,219 +1,211 @@ /*------------------------------------------------------------------------------ -* rtklib unit test driver : glonass ephemeris function -*-----------------------------------------------------------------------------*/ -#include + * rtklib unit test driver : glonass ephemeris function + *-----------------------------------------------------------------------------*/ #include +#include + #include "../../src/rtklib.h" -static void dumpgeph(geph_t *geph, int n) -{ - char s1[40],s2[40]; - int i; - for (i=0;i0); - dumpgeph(nav.geph,nav.ng); - - printf("%s utest1 : OK\n",__FILE__); +void utest1(void) { + char file1[] = "../data/rinex/brdd0910.09g"; + char file2[] = "../data/rinex/brdc0910.09g"; + nav_t nav = {0}; + + readrnx(file1, 1, "", NULL, &nav, NULL); + assert(nav.ng == 0); + readrnx(file2, 1, "", NULL, &nav, NULL); + assert(nav.ng > 0); + dumpgeph(nav.geph, nav.ng); + + printf("%s utest1 : OK\n", __FILE__); } /* readsp3() */ -void utest2(void) -{ - char *file1="../data/sp3/igl15253.sp4"; - char *file2="../data/sp3/igl15253.sp3"; - nav_t nav={0}; - double tow,*pos; - int i,week,sat; - - sat=satno(SYS_GLO,13); - - readsp3(file1,&nav,0); - assert(nav.ne<=0); - readsp3(file2,&nav,0); - assert(nav.ne>0); - - for (i=0;i0.0); - } - printf("\n"); - - printf("%s utest2 : OK\n",__FILE__); +void utest2(void) { + char *file1 = "../data/sp3/igl15253.sp4"; + char *file2 = "../data/sp3/igl15253.sp3"; + nav_t nav = {0}; + double tow, *pos; + int i, week, sat; + + sat = satno(SYS_GLO, 13); + + readsp3(file1, &nav, 0); + assert(nav.ne <= 0); + readsp3(file2, &nav, 0); + assert(nav.ne > 0); + + for (i = 0; i < nav.ne; i++) { + tow = time2gpst(nav.peph[i].time, &week); + pos = nav.peph[i].pos[sat - 1]; + printf("%4d %6.0f %2d %13.3f %13.3f %13.3f %10.3f\n", week, tow, sat, pos[0], pos[1], pos[2], + pos[3] * 1E9); + assert(norm(pos, 4) > 0.0); + } + printf("\n"); + + printf("%s utest2 : OK\n", __FILE__); } /* broadcast ephemeris */ -void utest3(void) -{ - gtime_t time; - char file[]="../data/rinex/brdc0910.09g"; - nav_t nav={0}; - double ep[]={2009,4,1,0,0,0}; - double tspan=86400.0,tint=30.0,tow; - double rs[6],dts[2]; - double var; - int i,sat,week,svh; - - sat=satno(SYS_GLO,7); - - readrnx(file,1,"",NULL,&nav,NULL); - - for (i=0;i0.0); - assert(norm(rs+3,3)>0.0); - assert(dts[0]!=0.0); - assert(dts[1]!=0.0); - } - printf("\n"); - - printf("%s utest3 : OK\n",__FILE__); +void utest3(void) { + gtime_t time; + char file[] = "../data/rinex/brdc0910.09g"; + nav_t nav = {0}; + double ep[] = {2009, 4, 1, 0, 0, 0}; + double tspan = 86400.0, tint = 30.0, tow; + double rs[6], dts[2]; + double var; + int i, sat, week, svh; + + sat = satno(SYS_GLO, 7); + + readrnx(file, 1, "", NULL, &nav, NULL); + + for (i = 0; i < tspan / tint; i++) { + time = timeadd(epoch2time(ep), tint * i); + satpos(time, time, sat, EPHOPT_BRDC, &nav, rs, dts, &var, &svh); + tow = time2gpst(time, &week); + printf("%4d %6.0f %2d %13.3f %13.3f %13.3f %10.3f\n", week, tow, sat, rs[0], rs[1], rs[2], + dts[0] * 1E9); + assert(norm(rs, 3) > 0.0); + assert(norm(rs + 3, 3) > 0.0); + assert(dts[0] != 0.0); + assert(dts[1] != 0.0); + } + printf("\n"); + + printf("%s utest3 : OK\n", __FILE__); } /* precise ephemeris */ -void utest4(void) -{ - char *file1="../data/rinex/brdc0910.09g"; - char *file2="../data/sp3/igl15253.sp3"; - nav_t nav={0}; - double ep[]={2009,4,1,0,0,0}; - gtime_t time=epoch2time(ep); - double tspan=86400.0,tint=30.0,tow; - double rs[6],dts[2]; - double var; - int i,sat,week,svh; - - sat=satno(SYS_GLO,7); - - /* NOTE: GLO needs BRDC for frequency conversion in satantoff() !! */ - readrnx(file1,0,"",NULL,&nav,NULL); - readsp3(file2,&nav,0); - assert(nav.ne>0); - - for (i=0;i0.0); - assert(norm(rs+3,3)>0.0); - assert(dts[0]!=0.0); - } - printf("\n"); - - printf("%s utest4 : OK\n",__FILE__); +void utest4(void) { + char *file1 = "../data/rinex/brdc0910.09g"; + char *file2 = "../data/sp3/igl15253.sp3"; + nav_t nav = {0}; + double ep[] = {2009, 4, 1, 0, 0, 0}; + gtime_t time = epoch2time(ep); + double tspan = 86400.0, tint = 30.0, tow; + double rs[6], dts[2]; + double var; + int i, sat, week, svh; + + sat = satno(SYS_GLO, 7); + + /* NOTE: GLO needs BRDC for frequency conversion in satantoff() !! */ + readrnx(file1, 0, "", NULL, &nav, NULL); + readsp3(file2, &nav, 0); + assert(nav.ne > 0); + + for (i = 0; i < tspan / tint; i++) { + time = timeadd(epoch2time(ep), tint * i); + satpos(time, time, sat, EPHOPT_PREC, &nav, rs, dts, &var, &svh); + tow = time2gpst(time, &week); + printf("%4d %6.0f %2d %13.3f %13.3f %13.3f %10.3f\n", week, tow, sat, rs[0], rs[1], rs[2], + dts[0] * 1E9); + assert(norm(rs, 3) > 0.0); + assert(norm(rs + 3, 3) > 0.0); + assert(dts[0] != 0.0); + } + printf("\n"); + + printf("%s utest4 : OK\n", __FILE__); } /* readsap() */ -void utest5(void) -{ - char *file="../../data/ant/igs14.atx",id[8]; - double ep[]={2009,4,1,0,0,0}; - gtime_t time=epoch2time(ep); - nav_t nav={0}; - int i,stat; - - stat=readsap(file,time,&nav); - assert(stat); - - for (i=0;i + * rtklib unit test driver : ionex function + *-----------------------------------------------------------------------------*/ #include +#include + #include "../../src/rtklib.h" -static void dumptec(const tec_t *tec, int n, int level) -{ - const tec_t *p; - char s[40]; - int i,j,k,m; - - for (i=0;itime,s,3); - printf("(%2d) time =%s ndata=%d %d %d\n",i+1,s,p->ndata[0],p->ndata[1],p->ndata[2]); - if (level<1) continue; - printf("lats =%6.1f %6.1f %6.1f\n",p->lats[0],p->lats[1],p->lats[2]); - printf("lons =%6.1f %6.1f %6.1f\n",p->lons[0],p->lons[1],p->lons[2]); - printf("hgts =%6.1f %6.1f %6.1f\n",p->hgts[0],p->hgts[1],p->hgts[2]); - printf("data =\n"); - for (j=0;jndata[2];j++) { /* hgt */ - for (k=0;kndata[0];k++) { /* lat */ - printf("lat=%.1f lon=%.1f:%.1f hgt=%.1f\n",p->lats[0]+k*p->lats[2], - p->lons[0],p->lons[1],p->hgts[0]+j*p->hgts[2]); - for (m=0;mndata[1];m++) { /* lon */ - if (m>0&&m%16==0) printf("\n"); - printf("%5.1f ",p->data[k+p->ndata[0]*(m+p->ndata[1]*j)]); - } - printf("\n"); - } - printf("\n"); +static void dumptec(const tec_t *tec, int n, int level) { + const tec_t *p; + char s[40]; + int i, j, k, m; + + for (i = 0; i < n; i++) { + p = tec + i; + time2str(p->time, s, 3); + printf("(%2d) time =%s ndata=%d %d %d\n", i + 1, s, p->ndata[0], p->ndata[1], p->ndata[2]); + if (level < 1) continue; + printf("lats =%6.1f %6.1f %6.1f\n", p->lats[0], p->lats[1], p->lats[2]); + printf("lons =%6.1f %6.1f %6.1f\n", p->lons[0], p->lons[1], p->lons[2]); + printf("hgts =%6.1f %6.1f %6.1f\n", p->hgts[0], p->hgts[1], p->hgts[2]); + printf("data =\n"); + for (j = 0; j < p->ndata[2]; j++) { /* hgt */ + for (k = 0; k < p->ndata[0]; k++) { /* lat */ + printf("lat=%.1f lon=%.1f:%.1f hgt=%.1f\n", p->lats[0] + k * p->lats[2], p->lons[0], + p->lons[1], p->hgts[0] + j * p->hgts[2]); + for (m = 0; m < p->ndata[1]; m++) { /* lon */ + if (m > 0 && m % 16 == 0) printf("\n"); + printf("%5.1f ", p->data[k + p->ndata[0] * (m + p->ndata[1] * j)]); } - printf("rms =\n"); - for (j=0;jndata[2];j++) { /* hgt */ - for (k=0;kndata[0];k++) { /* lat */ - printf("lat=%.1f lon=%.1f:%.1f hgt=%.1f\n",p->lats[0]+k*p->lats[2], - p->lons[0],p->lons[1],p->hgts[0]+j*p->hgts[2]); - for (m=0;mndata[1];m++) { /* lon */ - if (m>0&&m%16==0) printf("\n"); - printf("%5.1f ",p->rms[k+p->ndata[0]*(m+p->ndata[1]*j)]); - } - printf("\n"); - } - printf("\n"); + printf("\n"); + } + printf("\n"); + } + printf("rms =\n"); + for (j = 0; j < p->ndata[2]; j++) { /* hgt */ + for (k = 0; k < p->ndata[0]; k++) { /* lat */ + printf("lat=%.1f lon=%.1f:%.1f hgt=%.1f\n", p->lats[0] + k * p->lats[2], p->lons[0], + p->lons[1], p->hgts[0] + j * p->hgts[2]); + for (m = 0; m < p->ndata[1]; m++) { /* lon */ + if (m > 0 && m % 16 == 0) printf("\n"); + printf("%5.1f ", p->rms[k + p->ndata[0] * (m + p->ndata[1] * j)]); } + printf("\n"); + } + printf("\n"); } + } } -static void dumpdcb(const nav_t *nav) -{ - int i; - printf("dcbs=\n"); - for (i=0;icbias[i][0][0]/CLIGHT*1E9); /* ns */ - } +static void dumpdcb(const nav_t *nav) { + int i; + printf("dcbs=\n"); + for (i = 0; i < MAXSAT; i++) { + printf("%3d: P1-P2=%6.3f\n", i + 1, nav->cbias[i][0][0] / CLIGHT * 1E9); /* ns */ + } } /* readtec() */ -void utest1(void) -{ - char *file1="../data/sp3/igrg3380.10j"; - char *file2="../data/sp3/igrg3380.10i"; - char *file3="../data/sp3/igrg33*0.10i"; - nav_t nav={0}; - - printf("file=%s\n",file1); - readtec(file1,&nav,0); - assert(nav.nt==0); - - printf("file=%s\n",file2); - readtec(file2,&nav,0); - assert(nav.nt==13); - dumptec(nav.tec,nav.nt,1); - - printf("file=%s\n",file3); - readtec(file3,&nav,0); - assert(nav.nt==25); - dumptec(nav.tec,nav.nt,0); - - dumptec(nav.tec ,1,1); - dumptec(nav.tec+12,1,1); - dumpdcb(&nav); - - printf("%s utest1 : OK\n",__FILE__); +void utest1(void) { + char *file1 = "../data/sp3/igrg3380.10j"; + char *file2 = "../data/sp3/igrg3380.10i"; + char *file3 = "../data/sp3/igrg33*0.10i"; + nav_t nav = {0}; + + printf("file=%s\n", file1); + readtec(file1, &nav, 0); + assert(nav.nt == 0); + + printf("file=%s\n", file2); + readtec(file2, &nav, 0); + assert(nav.nt == 13); + dumptec(nav.tec, nav.nt, 1); + + printf("file=%s\n", file3); + readtec(file3, &nav, 0); + assert(nav.nt == 25); + dumptec(nav.tec, nav.nt, 0); + + dumptec(nav.tec, 1, 1); + dumptec(nav.tec + 12, 1, 1); + dumpdcb(&nav); + + printf("%s utest1 : OK\n", __FILE__); } /* iontec() 1 */ -void utest2(void) -{ - char *file3="../data/sp3/igrg33*0.10i"; - nav_t nav={0}; - gtime_t time1,time2,time3,time4; - double ep1 []={2010,12, 4, 0, 0, 0}; - double ep2 []={2010,12, 5,23,59,59}; - double ep3 []={2010,12, 3,23,59,59}; /* error */ - double ep4 []={2010,12, 6, 0, 0, 0}; /* error */ - double pos1 []={ 45.1*D2R, 135.7*D2R,0.0}; - double pos2 []={-45.1*D2R,-170.7*D2R,0.0}; - double pos3 []={-45.1*D2R, 189.3*D2R,0.0}; - double pos4 []={ 87.6*D2R, 0.0*D2R,0.0}; /* out of grid */ - double pos5 []={-87.6*D2R, 0.0*D2R,0.0}; /* out of grid */ - double azel1[]={ 0.0,90.0*D2R}; - double azel2[]={120.0,30.0*D2R}; - double azel3[]={ 0.0,-0.1*D2R}; /* error */ - double delay1,var1,delay2=0,var2; - int stat; - - time1=epoch2time(ep1); - time2=epoch2time(ep2); - time3=epoch2time(ep3); - time4=epoch2time(ep4); - - readtec(file3,&nav,0); - stat=iontec(time1,&nav,pos1,azel1,1,&delay1,&var1); - assert(stat==1); - stat=iontec(time2,&nav,pos1,azel1,1,&delay1,&var1); - assert(stat==1); - stat=iontec(time3,&nav,pos1,azel1,1,&delay1,&var1); - assert(stat==0); - stat=iontec(time4,&nav,pos1,azel1,1,&delay1,&var1); - assert(stat==0); - stat=iontec(time1,&nav,pos2,azel1,1,&delay1,&var1); - assert(stat==1); - stat=iontec(time1,&nav,pos3,azel1,1,&delay2,&var2); - assert(stat==1); - assert(fabs(delay1-delay2)<1E-4); - assert(fabs(var1-var2)<1E-8); - stat=iontec(time1,&nav,pos4,azel1,1,&delay1,&var1); - assert(stat==1); - stat=iontec(time1,&nav,pos5,azel1,1,&delay1,&var1); - assert(stat==1); - stat=iontec(time1,&nav,pos1,azel2,1,&delay1,&var1); - assert(stat==1); - stat=iontec(time1,&nav,pos1,azel3,1,&delay1,&var1); - assert(stat==1&&delay1==0.0); - - printf("%s utest2 : OK\n",__FILE__); +void utest2(void) { + char *file3 = "../data/sp3/igrg33*0.10i"; + nav_t nav = {0}; + gtime_t time1, time2, time3, time4; + double ep1[] = {2010, 12, 4, 0, 0, 0}; + double ep2[] = {2010, 12, 5, 23, 59, 59}; + double ep3[] = {2010, 12, 3, 23, 59, 59}; /* error */ + double ep4[] = {2010, 12, 6, 0, 0, 0}; /* error */ + double pos1[] = {45.1 * D2R, 135.7 * D2R, 0.0}; + double pos2[] = {-45.1 * D2R, -170.7 * D2R, 0.0}; + double pos3[] = {-45.1 * D2R, 189.3 * D2R, 0.0}; + double pos4[] = {87.6 * D2R, 0.0 * D2R, 0.0}; /* out of grid */ + double pos5[] = {-87.6 * D2R, 0.0 * D2R, 0.0}; /* out of grid */ + double azel1[] = {0.0, 90.0 * D2R}; + double azel2[] = {120.0, 30.0 * D2R}; + double azel3[] = {0.0, -0.1 * D2R}; /* error */ + double delay1, var1, delay2 = 0, var2; + int stat; + + time1 = epoch2time(ep1); + time2 = epoch2time(ep2); + time3 = epoch2time(ep3); + time4 = epoch2time(ep4); + + readtec(file3, &nav, 0); + stat = iontec(time1, &nav, pos1, azel1, 1, &delay1, &var1); + assert(stat == 1); + stat = iontec(time2, &nav, pos1, azel1, 1, &delay1, &var1); + assert(stat == 1); + stat = iontec(time3, &nav, pos1, azel1, 1, &delay1, &var1); + assert(stat == 0); + stat = iontec(time4, &nav, pos1, azel1, 1, &delay1, &var1); + assert(stat == 0); + stat = iontec(time1, &nav, pos2, azel1, 1, &delay1, &var1); + assert(stat == 1); + stat = iontec(time1, &nav, pos3, azel1, 1, &delay2, &var2); + assert(stat == 1); + assert(fabs(delay1 - delay2) < 1E-4); + assert(fabs(var1 - var2) < 1E-8); + stat = iontec(time1, &nav, pos4, azel1, 1, &delay1, &var1); + assert(stat == 1); + stat = iontec(time1, &nav, pos5, azel1, 1, &delay1, &var1); + assert(stat == 1); + stat = iontec(time1, &nav, pos1, azel2, 1, &delay1, &var1); + assert(stat == 1); + stat = iontec(time1, &nav, pos1, azel3, 1, &delay1, &var1); + assert(stat == 1 && delay1 == 0.0); + + printf("%s utest2 : OK\n", __FILE__); } /* iontec() 2 */ -void utest3(void) -{ - FILE *fp; - char *file3="../data/sp3/igrg33*0.10i"; - nav_t nav={0}; - gtime_t time1; - double ep1[]={2010,12, 5, 0, 0, 0}; - double delay,var,pos[3]={0},azel[]={0.0,PI/2}; - int i,j; - - time1=epoch2time(ep1); - readtec(file3,&nav,0); - - fp=fopen("testionex3.m","w"); - assert(fp); - - fprintf(fp,"tec=[\n"); - for (i=90;i>=-90;i-=2) { - for (j=0;j<=360;j+=2) { - pos[0]=i*D2R; - pos[1]=j*D2R; - if (iontec(time1,&nav,pos,azel,1,&delay,&var)) { - fprintf(fp,"%4.2f ",delay); - } - else { - fprintf(fp," nan "); - } - } - fprintf(fp,"\n"); +void utest3(void) { + FILE *fp; + char *file3 = "../data/sp3/igrg33*0.10i"; + nav_t nav = {0}; + gtime_t time1; + double ep1[] = {2010, 12, 5, 0, 0, 0}; + double delay, var, pos[3] = {0}, azel[] = {0.0, PI / 2}; + int i, j; + + time1 = epoch2time(ep1); + readtec(file3, &nav, 0); + + fp = fopen("testionex3.m", "w"); + assert(fp); + + fprintf(fp, "tec=[\n"); + for (i = 90; i >= -90; i -= 2) { + for (j = 0; j <= 360; j += 2) { + pos[0] = i * D2R; + pos[1] = j * D2R; + if (iontec(time1, &nav, pos, azel, 1, &delay, &var)) { + fprintf(fp, "%4.2f ", delay); + } else { + fprintf(fp, " nan "); + } } - fprintf(fp,"];\n"); - fclose(fp); - - fp=fopen("testionex3.m","a"); - assert(fp); - - fprintf(fp,"rms=[\n"); - for (i=90;i>=-90;i-=2) { - for (j=0;j<=360;j+=2) { - pos[0]=i*D2R; - pos[1]=j*D2R; - if (iontec(time1,&nav,pos,azel,1,&delay,&var)) { - fprintf(fp,"%4.2f ",sqrt(var)); - } - else { - fprintf(fp," nan "); - } - } - fprintf(fp,"\n"); + fprintf(fp, "\n"); + } + fprintf(fp, "];\n"); + fclose(fp); + + fp = fopen("testionex3.m", "a"); + assert(fp); + + fprintf(fp, "rms=[\n"); + for (i = 90; i >= -90; i -= 2) { + for (j = 0; j <= 360; j += 2) { + pos[0] = i * D2R; + pos[1] = j * D2R; + if (iontec(time1, &nav, pos, azel, 1, &delay, &var)) { + fprintf(fp, "%4.2f ", sqrt(var)); + } else { + fprintf(fp, " nan "); + } } - fprintf(fp,"];\n"); - fclose(fp); - - printf("%s utest3 : OK\n",__FILE__); + fprintf(fp, "\n"); + } + fprintf(fp, "];\n"); + fclose(fp); + + printf("%s utest3 : OK\n", __FILE__); } /* iontec() 3 */ -void utest4(void) -{ - FILE *fp; - char *file3="../data/sp3/igrg33*0.10i"; - nav_t nav={0}; - gtime_t time1; - double ep1[]={2010,12, 3,12, 0, 0}; - double delay,var,pos[3]={25*D2R,135*D2R,0}; - double azel[]={75*D2R,90*D2R}; - int i; - - time1=epoch2time(ep1); - readtec(file3,&nav,0); - - fp=fopen("testionex4.m","w"); - assert(fp); - - fprintf(fp,"tec=[\n"); - for (i=0;i<=86400*3;i+=30) { - if (iontec(timeadd(time1,i),&nav,pos,azel,1,&delay,&var)) { - fprintf(fp,"%6d %5.3f %5.3f\n",i,delay,sqrt(var)); - } - else { - fprintf(fp,"%6d nan nan\n",i); - } +void utest4(void) { + FILE *fp; + char *file3 = "../data/sp3/igrg33*0.10i"; + nav_t nav = {0}; + gtime_t time1; + double ep1[] = {2010, 12, 3, 12, 0, 0}; + double delay, var, pos[3] = {25 * D2R, 135 * D2R, 0}; + double azel[] = {75 * D2R, 90 * D2R}; + int i; + + time1 = epoch2time(ep1); + readtec(file3, &nav, 0); + + fp = fopen("testionex4.m", "w"); + assert(fp); + + fprintf(fp, "tec=[\n"); + for (i = 0; i <= 86400 * 3; i += 30) { + if (iontec(timeadd(time1, i), &nav, pos, azel, 1, &delay, &var)) { + fprintf(fp, "%6d %5.3f %5.3f\n", i, delay, sqrt(var)); + } else { + fprintf(fp, "%6d nan nan\n", i); } - fprintf(fp,"];\n"); - fclose(fp); - - printf("%s utest4 : OK\n",__FILE__); + } + fprintf(fp, "];\n"); + fclose(fp); + + printf("%s utest4 : OK\n", __FILE__); } -int main(int argc, char **argv) -{ - utest1(); - utest2(); - utest3(); - utest4(); - return 0; +int main(int argc, char **argv) { + utest1(); + utest2(); + utest3(); + utest4(); + return 0; } diff --git a/test/utest/t_lambda.c b/test/utest/t_lambda.c index 594323209..4a9e5cbaa 100644 --- a/test/utest/t_lambda.c +++ b/test/utest/t_lambda.c @@ -1,114 +1,84 @@ /*------------------------------------------------------------------------------ -* rtklib unit test driver : lambda/mlambda integer least square -*-----------------------------------------------------------------------------*/ -#include + * rtklib unit test driver : lambda/mlambda integer least square + *-----------------------------------------------------------------------------*/ #include +#include + #include "../../src/rtklib.h" -static double a1[]={ - 1585184.171, - -6716599.430, - 3915742.905, - 7627233.455, - 9565990.879, -989457273.200 -}; -static double Q1[]={ -0.227134, 0.112202, 0.112202, 0.112202, 0.112202, 0.103473, -0.112202, 0.227134, 0.112202, 0.112202, 0.112202, 0.103473, -0.112202, 0.112202, 0.227134, 0.112202, 0.112202, 0.103473, -0.112202, 0.112202, 0.112202, 0.227134, 0.112202, 0.103473, -0.112202, 0.112202, 0.112202, 0.112202, 0.227134, 0.103473, -0.103473, 0.103473, 0.103473, 0.103473, 0.103473, 0.434339 -}; -static double F1[]={ - 1585184.000000, 1585184.000000, - -6716599.000000, -6716600.000000, - 3915743.000000, 3915743.000000, - 7627234.000000, 7627233.000000, - 9565991.000000, 9565991.000000, -989457273.000000,989457273.000000 -}; -static double s1[]={ - 3.507984, 3.708456, -}; -static double a2[]={ --13324172.755747, --10668894.713608, - -7157225.010770, - -6149367.974367, - -7454133.571066, - -5969200.494550, - 8336734.058423, - 6186974.084502, --17549093.883655, --13970158.922370 -}; -static double Q2[]={ - 0.446320, 0.223160, 0.223160, 0.223160, 0.223160, 0.572775, 0.286388, 0.286388, 0.286388, 0.286388, - 0.223160, 0.446320, 0.223160, 0.223160, 0.223160, 0.286388, 0.572775, 0.286388, 0.286388, 0.286388, - 0.223160, 0.223160, 0.446320, 0.223160, 0.223160, 0.286388, 0.286388, 0.572775, 0.286388, 0.286388, - 0.223160, 0.223160, 0.223160, 0.446320, 0.223160, 0.286388, 0.286388, 0.286388, 0.572775, 0.286388, - 0.223160, 0.223160, 0.223160, 0.223160, 0.446320, 0.286388, 0.286388, 0.286388, 0.286388, 0.572775, - 0.572775, 0.286388, 0.286388, 0.286388, 0.286388, 0.735063, 0.367531, 0.367531, 0.367531, 0.367531, - 0.286388, 0.572775, 0.286388, 0.286388, 0.286388, 0.367531, 0.735063, 0.367531, 0.367531, 0.367531, - 0.286388, 0.286388, 0.572775, 0.286388, 0.286388, 0.367531, 0.367531, 0.735063, 0.367531, 0.367531, - 0.286388, 0.286388, 0.286388, 0.572775, 0.286388, 0.367531, 0.367531, 0.367531, 0.735063, 0.367531, - 0.286388, 0.286388, 0.286388, 0.286388, 0.572775, 0.367531, 0.367531, 0.367531, 0.367531, 0.735063 -}; -static double F2[]={ --13324188.000000,-13324188.000000, --10668901.000000,-10668908.000000, - -7157236.000000, -7157236.000000, - -6149379.000000, -6149379.000000, - -7454143.000000, -7454143.000000, - -5969220.000000, -5969220.000000, - 8336726.000000, 8336717.000000, - 6186960.000000, 6186960.000000, --17549108.000000,-17549108.000000, --13970171.000000,-13970171.000000 -}; -static double s2[]={ - 1506.435789, 1612.811795 +static double a1[] = {1585184.171, -6716599.430, 3915742.905, + 7627233.455, 9565990.879, 989457273.200}; +static double Q1[] = { + 0.227134, 0.112202, 0.112202, 0.112202, 0.112202, 0.103473, 0.112202, 0.227134, 0.112202, + 0.112202, 0.112202, 0.103473, 0.112202, 0.112202, 0.227134, 0.112202, 0.112202, 0.103473, + 0.112202, 0.112202, 0.112202, 0.227134, 0.112202, 0.103473, 0.112202, 0.112202, 0.112202, + 0.112202, 0.227134, 0.103473, 0.103473, 0.103473, 0.103473, 0.103473, 0.103473, 0.434339}; +static double F1[] = {1585184.000000, 1585184.000000, -6716599.000000, -6716600.000000, + 3915743.000000, 3915743.000000, 7627234.000000, 7627233.000000, + 9565991.000000, 9565991.000000, 989457273.000000, 989457273.000000}; +static double s1[] = { + 3.507984, + 3.708456, }; +static double a2[] = {-13324172.755747, -10668894.713608, -7157225.010770, -6149367.974367, + -7454133.571066, -5969200.494550, 8336734.058423, 6186974.084502, + -17549093.883655, -13970158.922370}; +static double Q2[] = { + 0.446320, 0.223160, 0.223160, 0.223160, 0.223160, 0.572775, 0.286388, 0.286388, 0.286388, + 0.286388, 0.223160, 0.446320, 0.223160, 0.223160, 0.223160, 0.286388, 0.572775, 0.286388, + 0.286388, 0.286388, 0.223160, 0.223160, 0.446320, 0.223160, 0.223160, 0.286388, 0.286388, + 0.572775, 0.286388, 0.286388, 0.223160, 0.223160, 0.223160, 0.446320, 0.223160, 0.286388, + 0.286388, 0.286388, 0.572775, 0.286388, 0.223160, 0.223160, 0.223160, 0.223160, 0.446320, + 0.286388, 0.286388, 0.286388, 0.286388, 0.572775, 0.572775, 0.286388, 0.286388, 0.286388, + 0.286388, 0.735063, 0.367531, 0.367531, 0.367531, 0.367531, 0.286388, 0.572775, 0.286388, + 0.286388, 0.286388, 0.367531, 0.735063, 0.367531, 0.367531, 0.367531, 0.286388, 0.286388, + 0.572775, 0.286388, 0.286388, 0.367531, 0.367531, 0.735063, 0.367531, 0.367531, 0.286388, + 0.286388, 0.286388, 0.572775, 0.286388, 0.367531, 0.367531, 0.367531, 0.735063, 0.367531, + 0.286388, 0.286388, 0.286388, 0.286388, 0.572775, 0.367531, 0.367531, 0.367531, 0.367531, + 0.735063}; +static double F2[] = {-13324188.000000, -13324188.000000, -10668901.000000, -10668908.000000, + -7157236.000000, -7157236.000000, -6149379.000000, -6149379.000000, + -7454143.000000, -7454143.000000, -5969220.000000, -5969220.000000, + 8336726.000000, 8336717.000000, 6186960.000000, 6186960.000000, + -17549108.000000, -17549108.000000, -13970171.000000, -13970171.000000}; +static double s2[] = {1506.435789, 1612.811795}; -void utest1(void) -{ - int i,j,n,m,info; - double F[6*2],s[2]; - - n=6; m=2; - info=lambda(n,m,a1,Q1,F,s); - assert(info==0); +void utest1(void) { + int i, j, n, m, info; + double F[6 * 2], s[2]; - for (j=0;j + * rtklib unit test driver : matrix and vector functions + *-----------------------------------------------------------------------------*/ #include +#include + #include "../../src/rtklib.h" -void dbout1(double *x, double *y, double *P, double *H, double *R, int n, int m) -{ - printf("x=[\n"); matprint(x,n,1,8,4); printf("];\n"); - printf("y=[\n"); matprint(y,m,1,8,4); printf("];\n"); - printf("P=[\n"); matprint(P,n,n,8,4); printf("];\n"); - printf("H=[\n"); matprint(H,m,n,8,4); printf("];\n"); - printf("R=[\n"); matprint(R,m,m,8,4); printf("];\n"); +void dbout1(double *x, double *y, double *P, double *H, double *R, int n, int m) { + printf("x=[\n"); + matprint(x, n, 1, 8, 4); + printf("];\n"); + printf("y=[\n"); + matprint(y, m, 1, 8, 4); + printf("];\n"); + printf("P=[\n"); + matprint(P, n, n, 8, 4); + printf("];\n"); + printf("H=[\n"); + matprint(H, m, n, 8, 4); + printf("];\n"); + printf("R=[\n"); + matprint(R, m, m, 8, 4); + printf("];\n"); } -void dbout2(double *x, double *P, int n) -{ - printf("xu=[\n"); matprint(x,n,1,8,4); printf("];\n"); - printf("Pu=[\n"); matprint(P,n,n,8,4); printf("];\n"); - printf("K=P*H'/(H*P*H'+R);\n"); +void dbout2(double *x, double *P, int n) { + printf("xu=[\n"); + matprint(x, n, 1, 8, 4); + printf("];\n"); + printf("Pu=[\n"); + matprint(P, n, n, 8, 4); + printf("];\n"); + printf("K=P*H'/(H*P*H'+R);\n"); - printf("xd=x+K*y;\n"); - printf("Pd=P-K*H*P\n"); - printf("xu-xd,Pu-Pd\n"); + printf("xd=x+K*y;\n"); + printf("Pd=P-K*H*P\n"); + printf("xu-xd,Pu-Pd\n"); } /* mat(),imat(),zeros(),eye() */ -void utest1(void) -{ - int i,j,n=100,m=200,*b; - double *a; - a=mat(0,0); assert(a==NULL); - a=mat(0,1); assert(a==NULL); - a=mat(1,0); assert(a==NULL); - a=mat(1,1); assert(a!=NULL); - free(a); -/* a=mat(1000000,1000000); assert(a==NULL); */ - a=zeros(0,m); assert(a==NULL); - a=zeros(n,0); assert(a==NULL); - a=zeros(n,m); assert(a!=NULL); - for (i=0;i + * rtklib unit test driver : misc functions + *-----------------------------------------------------------------------------*/ #include +#include + #include "../../src/rtklib.h" /* expath() */ -static void utest11(const char *path) -{ - char s[32][256],*paths[32]; - int i,n; - for (i=0;i<32;i++) paths[i]=s[i]; - n=expath(path,paths,32); - printf("\npath =%s\n",path); - printf("paths=\n"); - for (i=0;i -#include + * rtklib unit test driver : ppp functions + *-----------------------------------------------------------------------------*/ #include +#include +#include + #include "../../src/rtklib.h" /* eci2ecef() */ -void utest1(void) -{ - double ep1[]={1999,3,4,0,0,0}; - double gmst,U[9]; - double U1[]={ - -0.947378027425279, 0.320116956820115, -8.43090456427539e-005, - -0.32011695222455, -0.947378030590727, -6.36592598714651e-005, - -0.00010025094616549, -3.33206293083182e-005, 0.999999994419742 - }; - double erpv[5]={0.06740*D2R/3600,0.24713*D2R/3600,0.649232}; - int i,j; - - eci2ecef(epoch2time(ep1),erpv,U,&gmst); - - for (i=0;i<3;i++) for (j=0;j<3;j++) { - printf("U(%d,%d)=%15.12f %15.12f %15.12f\n",i,j, - U[i+j*3],U1[j+i*3],U[i+j*3]-U1[j+i*3]); - assert(fabs(U[i+j*3]-U1[j+i*3])<1E-11); +void utest1(void) { + double ep1[] = {1999, 3, 4, 0, 0, 0}; + double gmst, U[9]; + double U1[] = {-0.947378027425279, 0.320116956820115, -8.43090456427539e-005, + -0.32011695222455, -0.947378030590727, -6.36592598714651e-005, + -0.00010025094616549, -3.33206293083182e-005, 0.999999994419742}; + double erpv[5] = {0.06740 * D2R / 3600, 0.24713 * D2R / 3600, 0.649232}; + int i, j; + + eci2ecef(epoch2time(ep1), erpv, U, &gmst); + + for (i = 0; i < 3; i++) + for (j = 0; j < 3; j++) { + printf("U(%d,%d)=%15.12f %15.12f %15.12f\n", i, j, U[i + j * 3], U1[j + i * 3], + U[i + j * 3] - U1[j + i * 3]); + assert(fabs(U[i + j * 3] - U1[j + i * 3]) < 1E-11); } - printf("%s utset1 : OK\n",__FILE__); + printf("%s utset1 : OK\n", __FILE__); } /* sunmoonpos() */ -void utest2(void) -{ - double ep1[]={2010,12,31,8,9,10}; /* utc */ - double rs[]={70842740307.0837,115293403265.153,-57704700666.9715}; /* de405 */ - double rm[]={350588081.147922,29854134.6432052,-136870369.169738}; - double rsun[3],rmoon[3],erpv[5]={0}; - int i; - - sunmoonpos(epoch2time(ep1),erpv,rsun,rmoon,NULL); - printf("X_sun =%15.0f %15.0f %7.4f\n",rsun [0],rs[0],(rsun [0]-rs[0])/rsun [0]); - printf("Y_sun =%15.0f %15.0f %7.4f\n",rsun [1],rs[1],(rsun [1]-rs[1])/rsun [1]); - printf("Z_sun =%15.0f %15.0f %7.4f\n",rsun [2],rs[2],(rsun [2]-rs[2])/rsun [2]); - printf("X_moon=%15.0f %15.0f %7.4f\n",rmoon[0],rm[0],(rmoon[0]-rm[0])/rmoon[0]); - printf("Y_moon=%15.0f %15.0f %7.4f\n",rmoon[1],rm[1],(rmoon[1]-rm[1])/rmoon[1]); - printf("Z_moon=%15.0f %15.0f %7.4f\n",rmoon[2],rm[2],(rmoon[2]-rm[2])/rmoon[2]); - - for (i=0;i<3;i++) { - assert(fabs((rsun [i]-rs[i])/rsun [i])<0.03); - assert(fabs((rmoon[i]-rm[i])/rmoon[i])<0.03); - } - printf("%s utset2 : OK\n",__FILE__); +void utest2(void) { + double ep1[] = {2010, 12, 31, 8, 9, 10}; /* utc */ + double rs[] = {70842740307.0837, 115293403265.153, -57704700666.9715}; /* de405 */ + double rm[] = {350588081.147922, 29854134.6432052, -136870369.169738}; + double rsun[3], rmoon[3], erpv[5] = {0}; + int i; + + sunmoonpos(epoch2time(ep1), erpv, rsun, rmoon, NULL); + printf("X_sun =%15.0f %15.0f %7.4f\n", rsun[0], rs[0], (rsun[0] - rs[0]) / rsun[0]); + printf("Y_sun =%15.0f %15.0f %7.4f\n", rsun[1], rs[1], (rsun[1] - rs[1]) / rsun[1]); + printf("Z_sun =%15.0f %15.0f %7.4f\n", rsun[2], rs[2], (rsun[2] - rs[2]) / rsun[2]); + printf("X_moon=%15.0f %15.0f %7.4f\n", rmoon[0], rm[0], (rmoon[0] - rm[0]) / rmoon[0]); + printf("Y_moon=%15.0f %15.0f %7.4f\n", rmoon[1], rm[1], (rmoon[1] - rm[1]) / rmoon[1]); + printf("Z_moon=%15.0f %15.0f %7.4f\n", rmoon[2], rm[2], (rmoon[2] - rm[2]) / rmoon[2]); + + for (i = 0; i < 3; i++) { + assert(fabs((rsun[i] - rs[i]) / rsun[i]) < 0.03); + assert(fabs((rmoon[i] - rm[i]) / rmoon[i]) < 0.03); + } + printf("%s utset2 : OK\n", __FILE__); } /* tidedisp() */ -void utest3(void) -{ - double ep1[]={2010,6,7,1,2,3}; - double rr[]={-3957198.431,3310198.621,3737713.474}; /* TSKB */ - double dp[]={-0.05294,0.075607,0.03644}; - double dr[3]={0}; - int i; - - tidedisp(epoch2time(ep1),rr,1,NULL,NULL,dr); - - printf("X_disp=%8.5f %8.5f %8.5f\n",dr[0],dp[0],dr[0]-dp[0]); - printf("Y_disp=%8.5f %8.5f %8.5f\n",dr[1],dp[1],dr[1]-dp[1]); - printf("Z_disp=%8.5f %8.5f %8.5f\n",dr[2],dp[2],dr[2]-dp[2]); - - for (i=0;i<3;i++) { - assert(fabs(dr[i]-dp[i])<0.0015); - } - printf("%s utset3 : OK\n",__FILE__); +void utest3(void) { + double ep1[] = {2010, 6, 7, 1, 2, 3}; + double rr[] = {-3957198.431, 3310198.621, 3737713.474}; /* TSKB */ + double dp[] = {-0.05294, 0.075607, 0.03644}; + double dr[3] = {0}; + int i; + + tidedisp(epoch2time(ep1), rr, 1, NULL, NULL, dr); + + printf("X_disp=%8.5f %8.5f %8.5f\n", dr[0], dp[0], dr[0] - dp[0]); + printf("Y_disp=%8.5f %8.5f %8.5f\n", dr[1], dp[1], dr[1] - dp[1]); + printf("Z_disp=%8.5f %8.5f %8.5f\n", dr[2], dp[2], dr[2] - dp[2]); + + for (i = 0; i < 3; i++) { + assert(fabs(dr[i] - dp[i]) < 0.0015); + } + printf("%s utset3 : OK\n", __FILE__); } -int main(void) -{ - utest1(); - utest2(); - utest3(); - return 0; +int main(void) { + utest1(); + utest2(); + utest3(); + return 0; } diff --git a/test/utest/t_preceph.c b/test/utest/t_preceph.c index 0cca4d9f7..42e5db869 100644 --- a/test/utest/t_preceph.c +++ b/test/utest/t_preceph.c @@ -1,209 +1,204 @@ /*------------------------------------------------------------------------------ -* rtklib unit test driver : precise ephemeris function -*-----------------------------------------------------------------------------*/ -#include + * rtklib unit test driver : precise ephemeris function + *-----------------------------------------------------------------------------*/ #include +#include + #include "../../src/rtklib.h" -static void dumpeph(peph_t *peph, int n) -{ - char s[40]; - int i,j; - for (i=0;ioff[0][0],pcv->off[0][1],pcv->off[0][2]); - } - time=epoch2time(ep2); - for (i=0;ioff[0][0],pcv->off[0][1],pcv->off[0][2]); - } - - printf("%s utest2 : OK\n",__FILE__); +void utest2(void) { + double ep1[] = {2008, 3, 1, 0, 0, 0}; + double ep2[] = {2006, 11, 4, 23, 59, 59}; + char *file1 = "../data/sp3/igs06.atx"; + char *file2 = "../../data/ant/igs14.atx"; + pcvs_t pcvs = {0}; + pcv_t *pcv; + gtime_t time; + int i, stat; + + printf("file=%s\n", file1); + stat = readpcv(file1, &pcvs); + assert(!stat); + stat = readpcv(file2, &pcvs); + assert(stat); + + time = epoch2time(ep1); + for (i = 0; i < MAXSAT; i++) { + if (!(pcv = searchpcv(i + 1, "", time, &pcvs))) continue; + printf("PRN%02d : %7.4f %7.4f %7.4f\n", i + 1, pcv->off[0][0], pcv->off[0][1], pcv->off[0][2]); + } + time = epoch2time(ep2); + for (i = 0; i < MAXSAT; i++) { + if (!(pcv = searchpcv(i + 1, "", time, &pcvs))) continue; + printf("PRN%02d : %7.4f %7.4f %7.4f\n", i + 1, pcv->off[0][0], pcv->off[0][1], pcv->off[0][2]); + } + + printf("%s utest2 : OK\n", __FILE__); } /* readrnxc() */ -void utest3(void) -{ - char *file1="../data/sp3/igs15904.cls"; - char *file2="../data/sp3/igs15904.clk"; - char *file3="../data/sp3/igs1590*.clk"; - nav_t nav={0}; - - printf("file=%s\n",file1); - readrnxc(file1,&nav); - assert(nav.nc==0); - - printf("file=%s\n",file2); - readrnxc(file2,&nav); - assert(nav.nc>0); - dumpclk(nav.pclk,nav.nc); - free(nav.pclk); nav.pclk=NULL; nav.nc=nav.ncmax=0; - - printf("file=%s\n",file3); - readrnxc(file3,&nav); - assert(nav.nc>0); - dumpclk(nav.pclk,nav.nc); - free(nav.pclk); nav.pclk=NULL; nav.nc=nav.ncmax=0; - - printf("%s utest3 : OK\n",__FILE__); +void utest3(void) { + char *file1 = "../data/sp3/igs15904.cls"; + char *file2 = "../data/sp3/igs15904.clk"; + char *file3 = "../data/sp3/igs1590*.clk"; + nav_t nav = {0}; + + printf("file=%s\n", file1); + readrnxc(file1, &nav); + assert(nav.nc == 0); + + printf("file=%s\n", file2); + readrnxc(file2, &nav); + assert(nav.nc > 0); + dumpclk(nav.pclk, nav.nc); + free(nav.pclk); + nav.pclk = NULL; + nav.nc = nav.ncmax = 0; + + printf("file=%s\n", file3); + readrnxc(file3, &nav); + assert(nav.nc > 0); + dumpclk(nav.pclk, nav.nc); + free(nav.pclk); + nav.pclk = NULL; + nav.nc = nav.ncmax = 0; + + printf("%s utest3 : OK\n", __FILE__); } /* peph2pos() */ -void utest4(void) -{ - FILE *fp; - char *file1="../data/sp3/igs1590*.sp3"; /* 2010/7/1 */ - char *file2="../data/sp3/igs1590*.clk"; /* 2010/7/1 */ - nav_t nav={0}; - int i,j,stat,sat; - double ep[]={2010,7,1,0,0,0}; - double rs[6]={0},dts[2]={0}; - double var; - gtime_t t,time; - - time=epoch2time(ep); - - readsp3(file1,&nav,0); - assert(nav.ne>0); - readrnxc(file2,&nav); - assert(nav.nc>0); - stat=peph2pos(time,0,&nav,0,rs,dts,&var); - assert(!stat); - stat=peph2pos(time,160,&nav,0,rs,dts,&var); - assert(!stat); - - fp=fopen("testpeph1.out","w"); - - sat=4; - - for (i=0;i<86400*2;i+=30) { - t=timeadd(time,(double)i); - for (j=0;j<6;j++) rs [j]=0.0; - for (j=0;j<2;j++) dts[j]=0.0; - peph2pos(t,sat,&nav,0,rs,dts,&var); - fprintf(fp,"%02d %6d %14.3f %14.3f %14.3f %14.3f %10.3f %10.3f %10.3f %10.3f\n", - sat,i,rs[0],rs[1],rs[2],dts[0]*1E9,rs[3],rs[4],rs[5],dts[1]*1E9); - } - fclose(fp); - printf("%s utest4 : OK\n",__FILE__); +void utest4(void) { + FILE *fp; + char *file1 = "../data/sp3/igs1590*.sp3"; /* 2010/7/1 */ + char *file2 = "../data/sp3/igs1590*.clk"; /* 2010/7/1 */ + nav_t nav = {0}; + int i, j, stat, sat; + double ep[] = {2010, 7, 1, 0, 0, 0}; + double rs[6] = {0}, dts[2] = {0}; + double var; + gtime_t t, time; + + time = epoch2time(ep); + + readsp3(file1, &nav, 0); + assert(nav.ne > 0); + readrnxc(file2, &nav); + assert(nav.nc > 0); + stat = peph2pos(time, 0, &nav, 0, rs, dts, &var); + assert(!stat); + stat = peph2pos(time, 160, &nav, 0, rs, dts, &var); + assert(!stat); + + fp = fopen("testpeph1.out", "w"); + + sat = 4; + + for (i = 0; i < 86400 * 2; i += 30) { + t = timeadd(time, (double)i); + for (j = 0; j < 6; j++) rs[j] = 0.0; + for (j = 0; j < 2; j++) dts[j] = 0.0; + peph2pos(t, sat, &nav, 0, rs, dts, &var); + fprintf(fp, "%02d %6d %14.3f %14.3f %14.3f %14.3f %10.3f %10.3f %10.3f %10.3f\n", sat, i, rs[0], + rs[1], rs[2], dts[0] * 1E9, rs[3], rs[4], rs[5], dts[1] * 1E9); + } + fclose(fp); + printf("%s utest4 : OK\n", __FILE__); } /* satpos() */ -void utest5(void) -{ - FILE *fp; - char *file1="../data/sp3/igs1590*.sp3"; /* 2010/7/1 */ - char *file2="../data/sp3/igs1590*.clk"; /* 2010/7/1 */ - char *file3="../../data/ant/igs14.atx"; - char *file4="../data/rinex/brdc*.10n"; - pcvs_t pcvs={0}; - pcv_t *pcv; - nav_t nav={0}; - int i,stat,sat,svh; - double ep[]={2010,7,1,0,0,0}; - double rs1[6]={0},dts1[2]={0},rs2[6]={0},dts2[2]={0}; - double var; - gtime_t t,time; - - time=epoch2time(ep); - - readsp3(file1,&nav,0); - assert(nav.ne>0); - readrnxc(file2,&nav); - assert(nav.nc>0); - stat=readpcv(file3,&pcvs); - assert(stat); - readrnx(file4,1,"",NULL,&nav,NULL); - assert(nav.n>0); - for (i=0;i 0); + readrnxc(file2, &nav); + assert(nav.nc > 0); + stat = readpcv(file3, &pcvs); + assert(stat); + readrnx(file4, 1, "", NULL, &nav, NULL); + assert(nav.n > 0); + for (i = 0; i < MAXSAT; i++) { + if (!(pcv = searchpcv(i + 1, "", time, &pcvs))) continue; + nav.pcvs[i] = *pcv; + } + fp = fopen("testpeph2.out", "w"); + + sat = 3; + + for (i = 0; i < 86400 * 2; i += 30) { + t = timeadd(time, (double)i); + satpos(t, t, sat, EPHOPT_BRDC, &nav, rs1, dts1, &var, &svh); + satpos(t, t, sat, EPHOPT_PREC, &nav, rs2, dts2, &var, &svh); + fprintf(fp, "%02d %6d %14.3f %14.3f %14.3f %14.3f %14.3f %14.3f %14.3f %14.3f\n", sat, i, + rs1[0], rs1[1], rs1[2], dts1[0] * 1E9, rs2[0], rs2[1], rs2[2], dts2[0] * 1E9); + } + fclose(fp); + printf("%s utest5 : OK\n", __FILE__); } -int main(int argc, char **argv) -{ - utest1(); - utest2(); - utest3(); - utest4(); - utest5(); - return 0; +int main(int argc, char **argv) { + utest1(); + utest2(); + utest3(); + utest4(); + utest5(); + return 0; } diff --git a/test/utest/t_rinex.c b/test/utest/t_rinex.c index b655207db..87741c304 100644 --- a/test/utest/t_rinex.c +++ b/test/utest/t_rinex.c @@ -1,128 +1,129 @@ /*------------------------------------------------------------------------------ -* rtklib unit test driver : rinex function -*-----------------------------------------------------------------------------*/ -#include + * rtklib unit test driver : rinex function + *-----------------------------------------------------------------------------*/ #include +#include + #include "../../src/rtklib.h" -static void dumpobs(obs_t *obs) -{ - gtime_t time={0}; - int i; - char str[40]; - printf("obs : n=%d\n",obs->n); - for (i=0;in;i++) { - time2str(obs->data[i].time,str,3); - printf("%s : %2d %2d %2s: %13.3f %13.3f %d, %2s: %13.3f %13.3f %d, %2s: %13.3f %13.3f %d\n", - str,obs->data[i].sat,obs->data[i].rcv, - code2obs(obs->data[i].code[0]),obs->data[i].L[0],obs->data[i].P[0],obs->data[i].LLI[0], - code2obs(obs->data[i].code[1]),obs->data[i].L[1],obs->data[i].P[1],obs->data[i].LLI[1], - code2obs(obs->data[i].code[2]),obs->data[i].L[2],obs->data[i].P[2],obs->data[i].LLI[2]); - - assert(1<=obs->data[i].sat&&obs->data[i].sat<=32); - assert(timediff(obs->data[i].time,time)>=-DTTOL); - - time=obs->data[i].time; - } +static void dumpobs(obs_t *obs) { + gtime_t time = {0}; + int i; + char str[40]; + printf("obs : n=%d\n", obs->n); + for (i = 0; i < obs->n; i++) { + time2str(obs->data[i].time, str, 3); + printf("%s : %2d %2d %2s: %13.3f %13.3f %d, %2s: %13.3f %13.3f %d, %2s: %13.3f %13.3f %d\n", + str, obs->data[i].sat, obs->data[i].rcv, code2obs(obs->data[i].code[0]), + obs->data[i].L[0], obs->data[i].P[0], obs->data[i].LLI[0], + code2obs(obs->data[i].code[1]), obs->data[i].L[1], obs->data[i].P[1], + obs->data[i].LLI[1], code2obs(obs->data[i].code[2]), obs->data[i].L[2], + obs->data[i].P[2], obs->data[i].LLI[2]); + + assert(1 <= obs->data[i].sat && obs->data[i].sat <= 32); + assert(timediff(obs->data[i].time, time) >= -DTTOL); + + time = obs->data[i].time; + } } -static void dumpnav(nav_t *nav) -{ - int i; - char str[40],s1[40],s2[40]; - printf("nav : n=%d\n",nav->n); - for (i=0;in;i++) { - time2str(nav->eph[i].toe,str,3); - time2str(nav->eph[i].toc,s1,0); - time2str(nav->eph[i].ttr,s2,0); - printf("%s : %2d %s %s %3d %3d %2d\n",str,nav->eph[i].sat,s1,s2, - nav->eph[i].iode,nav->eph[i].iodc,nav->eph[i].svh); - - assert(nav->eph[i].iode==(nav->eph[i].iodc&0xFF)); - } +static void dumpnav(nav_t *nav) { + int i; + char str[40], s1[40], s2[40]; + printf("nav : n=%d\n", nav->n); + for (i = 0; i < nav->n; i++) { + time2str(nav->eph[i].toe, str, 3); + time2str(nav->eph[i].toc, s1, 0); + time2str(nav->eph[i].ttr, s2, 0); + printf("%s : %2d %s %s %3d %3d %2d\n", str, nav->eph[i].sat, s1, s2, nav->eph[i].iode, + nav->eph[i].iodc, nav->eph[i].svh); + + assert(nav->eph[i].iode == (nav->eph[i].iodc & 0xFF)); + } } -static void dumpsta(sta_t *sta) -{ - printf("name = %s\n",sta->name); - printf("marker = %s\n",sta->markerno); - printf("antdes = %s\n",sta->antdes); - printf("antsno = %s\n",sta->antsno); - printf("rectype = %s\n",sta->rectype); - printf("recver = %s\n",sta->recver); - printf("recsno = %s\n",sta->recsno); - printf("antsetup= %d\n",sta->antsetup); - printf("itrf = %d\n",sta->itrf); - printf("deltype = %d\n",sta->deltype); - printf("pos = %.3f %.3f %.3f\n",sta->pos[0],sta->pos[1],sta->pos[2]); - printf("del = %.3f %.3f %.3f\n",sta->del[0],sta->del[1],sta->del[2]); - printf("hgt = %.3f\n",sta->hgt); +static void dumpsta(sta_t *sta) { + printf("name = %s\n", sta->name); + printf("marker = %s\n", sta->markerno); + printf("antdes = %s\n", sta->antdes); + printf("antsno = %s\n", sta->antsno); + printf("rectype = %s\n", sta->rectype); + printf("recver = %s\n", sta->recver); + printf("recsno = %s\n", sta->recsno); + printf("antsetup= %d\n", sta->antsetup); + printf("itrf = %d\n", sta->itrf); + printf("deltype = %d\n", sta->deltype); + printf("pos = %.3f %.3f %.3f\n", sta->pos[0], sta->pos[1], sta->pos[2]); + printf("del = %.3f %.3f %.3f\n", sta->del[0], sta->del[1], sta->del[2]); + printf("hgt = %.3f\n", sta->hgt); } /* readrnx(), sortobs(), uniqnav() */ -void utest1(void) -{ - char file1[]="abc.00o"; - char file2[]="bcd.00n"; - char file3[]="../data/rinex/07590920.05o"; - char file4[]="../data/rinex/07590920.05n"; - char file5[]="../data/rinex/30400920.05o"; - char file6[]="../data/rinex/30400920.05n"; - obs_t obs={0}; - nav_t nav={0}; - sta_t sta={""}; - int n,stat; - - stat=readrnx(file1,1,"",&obs,&nav,&sta); - assert(stat==0&&obs.n==0&&nav.n==0&&nav.ng==0&&nav.ns==0); - stat=readrnx(file2,1,"",&obs,&nav,&sta); - assert(stat==0&&obs.n==0&&nav.n==0&&nav.ng==0&&nav.ns==0); - stat=readrnx(file3,1,"",&obs,&nav,&sta); - assert(stat==1); - stat=readrnx(file4,1,"",&obs,&nav,&sta); - assert(stat==1); - stat=readrnx(file5,2,"",&obs,&nav,&sta); - assert(stat==1); - stat=readrnx(file6,2,"",&obs,&nav,&sta); - assert(stat==1); - n=sortobs(&obs); - assert(n==120/*171*/); - uniqnav(&nav); - assert(nav.n==167); - dumpobs(&obs); dumpnav(&nav); dumpsta(&sta); - assert(obs.data&&obs.n>0&&nav.eph&&nav.n>0); - free(obs.data); - free(nav.eph); - free(nav.geph); - free(nav.seph); - - printf("%s utest1 : OK\n",__FILE__); +void utest1(void) { + char file1[] = "abc.00o"; + char file2[] = "bcd.00n"; + char file3[] = "../data/rinex/07590920.05o"; + char file4[] = "../data/rinex/07590920.05n"; + char file5[] = "../data/rinex/30400920.05o"; + char file6[] = "../data/rinex/30400920.05n"; + obs_t obs = {0}; + nav_t nav = {0}; + sta_t sta = {""}; + int n, stat; + + stat = readrnx(file1, 1, "", &obs, &nav, &sta); + assert(stat == 0 && obs.n == 0 && nav.n == 0 && nav.ng == 0 && nav.ns == 0); + stat = readrnx(file2, 1, "", &obs, &nav, &sta); + assert(stat == 0 && obs.n == 0 && nav.n == 0 && nav.ng == 0 && nav.ns == 0); + stat = readrnx(file3, 1, "", &obs, &nav, &sta); + assert(stat == 1); + stat = readrnx(file4, 1, "", &obs, &nav, &sta); + assert(stat == 1); + stat = readrnx(file5, 2, "", &obs, &nav, &sta); + assert(stat == 1); + stat = readrnx(file6, 2, "", &obs, &nav, &sta); + assert(stat == 1); + n = sortobs(&obs); + assert(n == 120 /*171*/); + uniqnav(&nav); + assert(nav.n == 167); + dumpobs(&obs); + dumpnav(&nav); + dumpsta(&sta); + assert(obs.data && obs.n > 0 && nav.eph && nav.n > 0); + free(obs.data); + free(nav.eph); + free(nav.geph); + free(nav.seph); + + printf("%s utest1 : OK\n", __FILE__); } /* readrnxt() */ -void utest2(void) -{ - gtime_t t0={0},ts,te; - double ep1[]={2005,4,2,1,0,0},ep2[]={2005,4,2,2,0,0}; - char file1[]="../data/rinex/07590920.05o"; - char file2[]="../data/rinex/07590920.05n"; - int n; - obs_t obs={0}; - nav_t nav={0}; - sta_t sta={""}; - - ts=epoch2time(ep1); - te=epoch2time(ep2); - n=readrnxt(file1,1,ts,te,0.0,"",&obs,&nav,&sta); - printf("\n\nn=%d\n",n); - n=readrnxt(file2,1,ts,te,0.0,"",&obs,&nav,&sta); - dumpobs(&obs); - free(obs.data); obs.data=NULL; obs.n=obs.nmax=0; - n=readrnxt(file1,1,t0,t0,240.0,"",&obs,&nav,&sta); - printf("\n\nn=%d\n",n); - dumpobs(&obs); - free(obs.data); - - printf("%s utset2 : OK\n",__FILE__); +void utest2(void) { + gtime_t t0 = {0}, ts, te; + double ep1[] = {2005, 4, 2, 1, 0, 0}, ep2[] = {2005, 4, 2, 2, 0, 0}; + char file1[] = "../data/rinex/07590920.05o"; + char file2[] = "../data/rinex/07590920.05n"; + int n; + obs_t obs = {0}; + nav_t nav = {0}; + sta_t sta = {""}; + + ts = epoch2time(ep1); + te = epoch2time(ep2); + n = readrnxt(file1, 1, ts, te, 0.0, "", &obs, &nav, &sta); + printf("\n\nn=%d\n", n); + n = readrnxt(file2, 1, ts, te, 0.0, "", &obs, &nav, &sta); + dumpobs(&obs); + free(obs.data); + obs.data = NULL; + obs.n = obs.nmax = 0; + n = readrnxt(file1, 1, t0, t0, 240.0, "", &obs, &nav, &sta); + printf("\n\nn=%d\n", n); + dumpobs(&obs); + free(obs.data); + + printf("%s utset2 : OK\n", __FILE__); } -static rnxopt_t opt1={{0}}; -static rnxopt_t opt2={{0}}; +static rnxopt_t opt1 = {{0}}; +static rnxopt_t opt2 = {{0}}; /* static rnxopt_t opt2= { {0},{0},0.0,0.0,2.10,SYS_ALL,OBSTYPE_ALL,FREQTYPE_ALL,{{0}}, @@ -152,69 +153,64 @@ static rnxopt_t opt2= { }; */ /* outrneobsh() */ -void utest3(void) -{ - nav_t nav={0}; +void utest3(void) { + nav_t nav = {0}; - outrnxobsh(stdout,&opt1,&nav); - outrnxobsh(stdout,&opt2,&nav); + outrnxobsh(stdout, &opt1, &nav); + outrnxobsh(stdout, &opt2, &nav); - printf("%s utest3 : OK\n",__FILE__); + printf("%s utest3 : OK\n", __FILE__); } /* outrneobsb() */ -void utest4(void) -{ - char file[]="../data/rinex/07590920.05o"; - obs_t obs={0}; - int i,j; - - readrnx(file,1,"",&obs,NULL,NULL); - outrnxobsb(stdout,&opt2,obs.data,8,9); - outrnxobsb(stdout,&opt2,obs.data,8,0); - - for (i=j=0;i #include #include -#include + #include "../../src/rtklib.h" #define TIME_64BIT 1 /* str2num() */ -void utest1(void) -{ - double a; - char s1[30]="123456789012345678901234567890"; - char s2[30]="....3D45......................"; - char s3[30]="... 3456.789 ................"; - a=str2num(s1,0,0); assert(fabs(a-0.0 )<1E-15); - a=str2num(s1,30,10); assert(fabs(a-0.0 )<1E-15); - a=str2num(s1,10,0); assert(fabs(a-0.0 )<1E-15); - a=str2num(s1,-1,10); assert(fabs(a-0.0 )<1E-15); - a=str2num(s1,0,3); assert(fabs(a-123.0 )<1E-13); - a=str2num(s1,10,6); assert(fabs(a-123456.0)<1E-10); - a=str2num(s1,28,10); assert(fabs(a-90.0 )<1E-14); - a=str2num(s2,4,4); assert(fabs(a-3E45 )<1E+30); - a=str2num(s3,4,8); assert(fabs(a-3456.78 )<1E-12); - - printf("%s utset1 : OK\n",__FILE__); +void utest1(void) { + double a; + char s1[30] = "123456789012345678901234567890"; + char s2[30] = "....3D45......................"; + char s3[30] = "... 3456.789 ................"; + a = str2num(s1, 0, 0); + assert(fabs(a - 0.0) < 1E-15); + a = str2num(s1, 30, 10); + assert(fabs(a - 0.0) < 1E-15); + a = str2num(s1, 10, 0); + assert(fabs(a - 0.0) < 1E-15); + a = str2num(s1, -1, 10); + assert(fabs(a - 0.0) < 1E-15); + a = str2num(s1, 0, 3); + assert(fabs(a - 123.0) < 1E-13); + a = str2num(s1, 10, 6); + assert(fabs(a - 123456.0) < 1E-10); + a = str2num(s1, 28, 10); + assert(fabs(a - 90.0) < 1E-14); + a = str2num(s2, 4, 4); + assert(fabs(a - 3E45) < 1E+30); + a = str2num(s3, 4, 8); + assert(fabs(a - 3456.78) < 1E-12); + + printf("%s utset1 : OK\n", __FILE__); } /* str2time() */ -void utest2(void) -{ - char s1[30]="....2004 1 1 0 1 2.345........"; - char s2[30]=".... 00 2 3 23 59 59.999....."; - char s3[30]=".... 80 10 30 6 58 9........."; - char s4[30]=".... 37 12 31 1 2 3 ........."; - int s; - gtime_t t; - double ep[6]; - s=str2time(s1,0,0,&t); assert(s<0); - s=str2time(s1,30,10,&t); assert(s<0); - s=str2time(s1,10,0,&t); assert(s<0); - s=str2time(s1,-1,10,&t); assert(s<0); - s=str2time(s1,4,17,&t); time2epoch(t,ep); - assert(!s&&ep[0]==2004&&ep[1]==1&&ep[2]==1&&ep[3]==0&&ep[4]==1&&fabs(ep[5]-2.34)<1E-15); - s=str2time(s2,4,21,&t); time2epoch(t,ep); - assert(!s&&ep[0]==2000&&ep[1]==2&&ep[2]==3&&ep[3]==23&&ep[4]==59&&fabs(ep[5]-59.999)<1E-14); - s=str2time(s3,4,20,&t); time2epoch(t,ep); - assert(!s&&ep[0]==1980&&ep[1]==10&&ep[2]==30&&ep[3]==6&&ep[4]==58&&ep[5]==9); - s=str2time(s4,4,20,&t); time2epoch(t,ep); - assert(!s&&ep[0]==2037&&ep[1]==12&&ep[2]==31&&ep[3]==1&&ep[4]==2&&ep[5]==3); - - printf("%s utset2 : OK\n",__FILE__); +void utest2(void) { + char s1[30] = "....2004 1 1 0 1 2.345........"; + char s2[30] = ".... 00 2 3 23 59 59.999....."; + char s3[30] = ".... 80 10 30 6 58 9........."; + char s4[30] = ".... 37 12 31 1 2 3 ........."; + int s; + gtime_t t; + double ep[6]; + s = str2time(s1, 0, 0, &t); + assert(s < 0); + s = str2time(s1, 30, 10, &t); + assert(s < 0); + s = str2time(s1, 10, 0, &t); + assert(s < 0); + s = str2time(s1, -1, 10, &t); + assert(s < 0); + s = str2time(s1, 4, 17, &t); + time2epoch(t, ep); + assert(!s && ep[0] == 2004 && ep[1] == 1 && ep[2] == 1 && ep[3] == 0 && ep[4] == 1 && + fabs(ep[5] - 2.34) < 1E-15); + s = str2time(s2, 4, 21, &t); + time2epoch(t, ep); + assert(!s && ep[0] == 2000 && ep[1] == 2 && ep[2] == 3 && ep[3] == 23 && ep[4] == 59 && + fabs(ep[5] - 59.999) < 1E-14); + s = str2time(s3, 4, 20, &t); + time2epoch(t, ep); + assert(!s && ep[0] == 1980 && ep[1] == 10 && ep[2] == 30 && ep[3] == 6 && ep[4] == 58 && + ep[5] == 9); + s = str2time(s4, 4, 20, &t); + time2epoch(t, ep); + assert(!s && ep[0] == 2037 && ep[1] == 12 && ep[2] == 31 && ep[3] == 1 && ep[4] == 2 && + ep[5] == 3); + + printf("%s utset2 : OK\n", __FILE__); } /* epoch2time(),time2epoch() */ -void utest3(void) -{ - double ep0[]={1980, 1, 6, 0, 0, 0.000000}; - double ep1[]={2004, 2,28, 2, 0,59.999999}; - double ep2[]={2004, 2,29, 2, 0,30.000000}; - double ep3[]={2004,12,31,23,59,59.999999}; - double ep4[]={2037,10, 1, 0, 0, 0.000000}; +void utest3(void) { + double ep0[] = {1980, 1, 6, 0, 0, 0.000000}; + double ep1[] = {2004, 2, 28, 2, 0, 59.999999}; + double ep2[] = {2004, 2, 29, 2, 0, 30.000000}; + double ep3[] = {2004, 12, 31, 23, 59, 59.999999}; + double ep4[] = {2037, 10, 1, 0, 0, 0.000000}; #ifdef TIME_64BIT - double ep5[]={2049, 2, 3, 4, 5, 6.000000}; /* 64bit time_t */ - double ep6[]={2099,12,31,23,59,59.999999}; /* 64bit time_t */ + double ep5[] = {2049, 2, 3, 4, 5, 6.000000}; /* 64bit time_t */ + double ep6[] = {2099, 12, 31, 23, 59, 59.999999}; /* 64bit time_t */ #endif - int year,month,day,mday[]={31,28,31,30,31,30,31,31,30,31,30,31}; - gtime_t t; - double ep[6]; - - t=epoch2time(ep0); time2epoch(t,ep); - assert(ep[0]==1980&&ep[1]==1&&ep[2]==6&&ep[3]==0&&ep[4]==0&&ep[5]==0.0); - t=epoch2time(ep1); time2epoch(t,ep); - assert(ep[0]==2004&&ep[1]==2&&ep[2]==28&&ep[3]==2&&ep[4]==0&&fabs(ep[5]-59.999999)<1E-14); - t=epoch2time(ep2); time2epoch(t,ep); - assert(ep[0]==2004&&ep[1]==2&&ep[2]==29&&ep[3]==2&&ep[4]==0&&ep[5]==30.0); - t=epoch2time(ep3); time2epoch(t,ep); - assert(ep[0]==2004&&ep[1]==12&&ep[2]==31&&ep[3]==23&&ep[4]==59&&fabs(ep[5]-59.999999)<1E-14); - t=epoch2time(ep4); time2epoch(t,ep); - assert(ep[0]==2037&&ep[1]==10&&ep[2]==1&&ep[3]==0&&ep[4]==0&&ep[5]==0.0); + int year, month, day, mday[] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; + gtime_t t; + double ep[6]; + + t = epoch2time(ep0); + time2epoch(t, ep); + assert(ep[0] == 1980 && ep[1] == 1 && ep[2] == 6 && ep[3] == 0 && ep[4] == 0 && ep[5] == 0.0); + t = epoch2time(ep1); + time2epoch(t, ep); + assert(ep[0] == 2004 && ep[1] == 2 && ep[2] == 28 && ep[3] == 2 && ep[4] == 0 && + fabs(ep[5] - 59.999999) < 1E-14); + t = epoch2time(ep2); + time2epoch(t, ep); + assert(ep[0] == 2004 && ep[1] == 2 && ep[2] == 29 && ep[3] == 2 && ep[4] == 0 && ep[5] == 30.0); + t = epoch2time(ep3); + time2epoch(t, ep); + assert(ep[0] == 2004 && ep[1] == 12 && ep[2] == 31 && ep[3] == 23 && ep[4] == 59 && + fabs(ep[5] - 59.999999) < 1E-14); + t = epoch2time(ep4); + time2epoch(t, ep); + assert(ep[0] == 2037 && ep[1] == 10 && ep[2] == 1 && ep[3] == 0 && ep[4] == 0 && ep[5] == 0.0); #ifdef TIME_64BIT - t=epoch2time(ep5); time2epoch(t,ep); - assert(ep[0]==2049&&ep[1]==2&&ep[2]==3&&ep[3]==4&&ep[4]==5&&ep[5]==6.0); - t=epoch2time(ep6); time2epoch(t,ep); - assert(ep[0]==2099&&ep[1]==12&&ep[2]==31&&ep[3]==23&&ep[4]==59&&fabs(ep[5]-59.999999)<1E-14); + t = epoch2time(ep5); + time2epoch(t, ep); + assert(ep[0] == 2049 && ep[1] == 2 && ep[2] == 3 && ep[3] == 4 && ep[4] == 5 && ep[5] == 6.0); + t = epoch2time(ep6); + time2epoch(t, ep); + assert(ep[0] == 2099 && ep[1] == 12 && ep[2] == 31 && ep[3] == 23 && ep[4] == 59 && + fabs(ep[5] - 59.999999) < 1E-14); #endif - + #ifdef TIME_64BIT - for (year=1970;year<=2099;year++) { + for (year = 1970; year <= 2099; year++) { #else - for (year=1970;year<=2037;year++) { + for (year = 1970; year <= 2037; year++) { #endif - mday[1]=year%4==0?29:28; - for (month=1;month<=12;month++) { - for (day=1;day<=mday[month-1];day++) { - if (year==1970&&month==1&&day==1) continue; - ep0[0]=year; ep0[1]=month; ep0[2]=day; - t=epoch2time(ep0); time2epoch(t,ep); - /* fprintf(stderr,"ep=%.0f %2.0f %2.0f : %.0f %2.0f %2.0f\n", - ep0[0],ep0[1],ep0[2],ep[0],ep[1],ep[2]); */ - assert(ep[0]==ep0[0]&&ep[1]==ep0[1]&&ep[2]==ep0[2]); - assert(ep[3]==0.0&&ep[4]==0.0&&ep[5]==0.0); - } - } + mday[1] = year % 4 == 0 ? 29 : 28; + for (month = 1; month <= 12; month++) { + for (day = 1; day <= mday[month - 1]; day++) { + if (year == 1970 && month == 1 && day == 1) continue; + ep0[0] = year; + ep0[1] = month; + ep0[2] = day; + t = epoch2time(ep0); + time2epoch(t, ep); + /* fprintf(stderr,"ep=%.0f %2.0f %2.0f : %.0f %2.0f %2.0f\n", + ep0[0],ep0[1],ep0[2],ep[0],ep[1],ep[2]); */ + assert(ep[0] == ep0[0] && ep[1] == ep0[1] && ep[2] == ep0[2]); + assert(ep[3] == 0.0 && ep[4] == 0.0 && ep[5] == 0.0); + } } - printf("%s utset3 : OK\n",__FILE__); + } + printf("%s utset3 : OK\n", __FILE__); } /* gpst2time(), time2gpst() */ -void utest4(void) -{ - gtime_t t; - double ep[6]; - int w,week; - double time,tt; - t=gpst2time(0,0.0); time2epoch(t,ep); - assert(ep[0]==1980&&ep[1]==1&&ep[2]==6&&ep[3]==0&&ep[4]==0&&ep[5]==0.0); - t=gpst2time(1400,86400.0); time2epoch(t,ep); - assert(ep[0]==2006&&ep[1]==11&&ep[2]==6&&ep[3]==0&&ep[4]==0&&ep[5]==0.0); - t=gpst2time(1400,86400.0*7-1.0); time2epoch(t,ep); - assert(ep[0]==2006&&ep[1]==11&&ep[2]==11&&ep[3]==23&&ep[4]==59&&ep[5]==59.0); - t=gpst2time(1400,86400.0*7); time2epoch(t,ep); - assert(ep[0]==2006&&ep[1]==11&&ep[2]==12&&ep[3]==0&&ep[4]==0&&ep[5]==0.0); - t=gpst2time(1401,0.0); time2epoch(t,ep); - assert(ep[0]==2006&&ep[1]==11&&ep[2]==12&&ep[3]==0&&ep[4]==0&&ep[5]==0.0); +void utest4(void) { + gtime_t t; + double ep[6]; + int w, week; + double time, tt; + t = gpst2time(0, 0.0); + time2epoch(t, ep); + assert(ep[0] == 1980 && ep[1] == 1 && ep[2] == 6 && ep[3] == 0 && ep[4] == 0 && ep[5] == 0.0); + t = gpst2time(1400, 86400.0); + time2epoch(t, ep); + assert(ep[0] == 2006 && ep[1] == 11 && ep[2] == 6 && ep[3] == 0 && ep[4] == 0 && ep[5] == 0.0); + t = gpst2time(1400, 86400.0 * 7 - 1.0); + time2epoch(t, ep); + assert(ep[0] == 2006 && ep[1] == 11 && ep[2] == 11 && ep[3] == 23 && ep[4] == 59 && + ep[5] == 59.0); + t = gpst2time(1400, 86400.0 * 7); + time2epoch(t, ep); + assert(ep[0] == 2006 && ep[1] == 11 && ep[2] == 12 && ep[3] == 0 && ep[4] == 0 && ep[5] == 0.0); + t = gpst2time(1401, 0.0); + time2epoch(t, ep); + assert(ep[0] == 2006 && ep[1] == 11 && ep[2] == 12 && ep[3] == 0 && ep[4] == 0 && ep[5] == 0.0); #ifdef TIME_64BIT - t=gpst2time(4000,0.0); time2epoch(t,ep); - assert(ep[0]==2056&&ep[1]==9&&ep[2]==3&&ep[3]==0&&ep[4]==0&&ep[5]==0.0); - t=gpst2time(6260,345600.0); time2epoch(t,ep); - assert(ep[0]==2099&&ep[1]==12&&ep[2]==31&&ep[3]==0&&ep[4]==0&&ep[5]==0.0); + t = gpst2time(4000, 0.0); + time2epoch(t, ep); + assert(ep[0] == 2056 && ep[1] == 9 && ep[2] == 3 && ep[3] == 0 && ep[4] == 0 && ep[5] == 0.0); + t = gpst2time(6260, 345600.0); + time2epoch(t, ep); + assert(ep[0] == 2099 && ep[1] == 12 && ep[2] == 31 && ep[3] == 0 && ep[4] == 0 && ep[5] == 0.0); #endif - + #ifdef TIME_64BIT - for (w=1000;w<=6260;w++) { + for (w = 1000; w <= 6260; w++) { #else - for (w=1000;w<1100;w++) { + for (w = 1000; w < 1100; w++) { #endif - for (time=0.0;time<86400.0*7;time+=3600.0) { - t=gpst2time(w,time); tt=time2gpst(t,&week); - assert(tt==time&&week==w); - } + for (time = 0.0; time < 86400.0 * 7; time += 3600.0) { + t = gpst2time(w, time); + tt = time2gpst(t, &week); + assert(tt == time && week == w); } - printf("%s utset4 : OK\n",__FILE__); + } + printf("%s utset4 : OK\n", __FILE__); } /* timeadd() */ -void utest5(void) -{ - double ep0[]={2003,12,31,23,59,59.000000}; - double ep1[]={2004, 1, 1, 0, 0, 1.000000}; - double ep2[]={2004, 2,28, 0, 0, 0.000000}; - double ep3[]={2004, 2,29, 0, 0, 0.000000}; - gtime_t t; - double ep[6]; - t=timeadd(epoch2time(ep0),3.0); time2epoch(t,ep); - assert(ep[0]==2004&&ep[1]==1&&ep[2]==1&&ep[3]==0&&ep[4]==0&&ep[5]==2.0); - t=timeadd(epoch2time(ep1),-3.0); time2epoch(t,ep); - assert(ep[0]==2003&&ep[1]==12&&ep[2]==31&&ep[3]==23&&ep[4]==59&&ep[5]==58.0); - t=timeadd(epoch2time(ep2),86400.0); time2epoch(t,ep); - assert(ep[0]==2004&&ep[1]==2&&ep[2]==29&&ep[3]==0&&ep[4]==0&&ep[5]==0.0); - t=timeadd(epoch2time(ep2),86400.0*2); time2epoch(t,ep); - assert(ep[0]==2004&&ep[1]==3&&ep[2]==1&&ep[3]==0&&ep[4]==0&&ep[5]==0.0); - t=timeadd(epoch2time(ep3),86400.0*2); time2epoch(t,ep); - assert(ep[0]==2004&&ep[1]==3&&ep[2]==2&&ep[3]==0&&ep[4]==0&&ep[5]==0.0); - - printf("%s utset5 : OK\n",__FILE__); +void utest5(void) { + double ep0[] = {2003, 12, 31, 23, 59, 59.000000}; + double ep1[] = {2004, 1, 1, 0, 0, 1.000000}; + double ep2[] = {2004, 2, 28, 0, 0, 0.000000}; + double ep3[] = {2004, 2, 29, 0, 0, 0.000000}; + gtime_t t; + double ep[6]; + t = timeadd(epoch2time(ep0), 3.0); + time2epoch(t, ep); + assert(ep[0] == 2004 && ep[1] == 1 && ep[2] == 1 && ep[3] == 0 && ep[4] == 0 && ep[5] == 2.0); + t = timeadd(epoch2time(ep1), -3.0); + time2epoch(t, ep); + assert(ep[0] == 2003 && ep[1] == 12 && ep[2] == 31 && ep[3] == 23 && ep[4] == 59 && + ep[5] == 58.0); + t = timeadd(epoch2time(ep2), 86400.0); + time2epoch(t, ep); + assert(ep[0] == 2004 && ep[1] == 2 && ep[2] == 29 && ep[3] == 0 && ep[4] == 0 && ep[5] == 0.0); + t = timeadd(epoch2time(ep2), 86400.0 * 2); + time2epoch(t, ep); + assert(ep[0] == 2004 && ep[1] == 3 && ep[2] == 1 && ep[3] == 0 && ep[4] == 0 && ep[5] == 0.0); + t = timeadd(epoch2time(ep3), 86400.0 * 2); + time2epoch(t, ep); + assert(ep[0] == 2004 && ep[1] == 3 && ep[2] == 2 && ep[3] == 0 && ep[4] == 0 && ep[5] == 0.0); + + printf("%s utset5 : OK\n", __FILE__); } /* timediff() */ -void utest6(void) -{ - double ep0[]={2003,12,31,23,59,59.000000}; - double ep1[]={2004, 1, 1, 0, 0, 1.000000}; - double ep2[]={2004, 2,28, 0, 0, 0.000000}; - double ep3[]={2004, 2,29, 0, 0, 0.000000}; - double ep4[]={2004, 3, 1, 0, 0, 0.000000}; - double sec; - sec=timediff(epoch2time(ep1),epoch2time(ep0)); - assert(sec==2.0); - sec=timediff(epoch2time(ep0),epoch2time(ep1)); - assert(sec==-2.0); - sec=timediff(epoch2time(ep3),epoch2time(ep2)); - assert(sec==86400.0); - sec=timediff(epoch2time(ep4),epoch2time(ep2)); - assert(sec==86400.0*2); - sec=timediff(epoch2time(ep3),epoch2time(ep4)); - assert(sec==-86400.0); - - printf("%s utset6 : OK\n",__FILE__); +void utest6(void) { + double ep0[] = {2003, 12, 31, 23, 59, 59.000000}; + double ep1[] = {2004, 1, 1, 0, 0, 1.000000}; + double ep2[] = {2004, 2, 28, 0, 0, 0.000000}; + double ep3[] = {2004, 2, 29, 0, 0, 0.000000}; + double ep4[] = {2004, 3, 1, 0, 0, 0.000000}; + double sec; + sec = timediff(epoch2time(ep1), epoch2time(ep0)); + assert(sec == 2.0); + sec = timediff(epoch2time(ep0), epoch2time(ep1)); + assert(sec == -2.0); + sec = timediff(epoch2time(ep3), epoch2time(ep2)); + assert(sec == 86400.0); + sec = timediff(epoch2time(ep4), epoch2time(ep2)); + assert(sec == 86400.0 * 2); + sec = timediff(epoch2time(ep3), epoch2time(ep4)); + assert(sec == -86400.0); + + printf("%s utset6 : OK\n", __FILE__); } /* gpst2utc() */ -void utest7(void) -{ - double ep0[]={1980, 1, 6, 0, 0, 0.000000}; - double ep1[]={1992, 7, 1, 0, 0, 6.999999}; - double ep2[]={1992, 7, 1, 0, 0, 7.000000}; - double ep3[]={1992, 7, 1, 0, 0, 8.000000}; - double ep4[]={2004,12,31,23,59,59.999999}; - double ep5[]={2006, 1, 1, 0, 0, 0.000000}; - double ep6[]={2038, 1, 1, 0, 0, 0.000000}; - gtime_t t; - double ep[6]; - t=gpst2utc(epoch2time(ep0)); time2epoch(t,ep); - assert(ep[0]==1980&&ep[1]==1&&ep[2]==6&&ep[3]==0&&ep[4]==0&&ep[5]==0.0); - t=gpst2utc(epoch2time(ep1)); time2epoch(t,ep); - assert(ep[0]==1992&&ep[1]==6&&ep[2]==30&&ep[3]==23&&ep[4]==59&&fabs(ep[5]-59.999999)<1E-14); - t=gpst2utc(epoch2time(ep2)); time2epoch(t,ep); - assert(ep[0]==1992&&ep[1]==7&&ep[2]==1&&ep[3]==0&&ep[4]==0&&ep[5]==0.0); - t=gpst2utc(epoch2time(ep3)); time2epoch(t,ep); - assert(ep[0]==1992&&ep[1]==7&&ep[2]==1&&ep[3]==0&&ep[4]==0&&ep[5]==0.0); - t=gpst2utc(epoch2time(ep4)); time2epoch(t,ep); - assert(ep[0]==2004&&ep[1]==12&&ep[2]==31&&ep[3]==23&&ep[4]==59&&fabs(ep[5]-46.999999)<1E-14); - t=gpst2utc(epoch2time(ep5)); time2epoch(t,ep); - assert(ep[0]==2005&&ep[1]==12&&ep[2]==31&&ep[3]==23&&ep[4]==59&&ep[5]==47.0); - t=gpst2utc(epoch2time(ep6)); time2epoch(t,ep); - assert(ep[0]==2037&&ep[1]==12&&ep[2]==31&&ep[3]==23&&ep[4]==59&&ep[5]==42.0); - printf("%s utset7 : OK\n",__FILE__); +void utest7(void) { + double ep0[] = {1980, 1, 6, 0, 0, 0.000000}; + double ep1[] = {1992, 7, 1, 0, 0, 6.999999}; + double ep2[] = {1992, 7, 1, 0, 0, 7.000000}; + double ep3[] = {1992, 7, 1, 0, 0, 8.000000}; + double ep4[] = {2004, 12, 31, 23, 59, 59.999999}; + double ep5[] = {2006, 1, 1, 0, 0, 0.000000}; + double ep6[] = {2038, 1, 1, 0, 0, 0.000000}; + gtime_t t; + double ep[6]; + t = gpst2utc(epoch2time(ep0)); + time2epoch(t, ep); + assert(ep[0] == 1980 && ep[1] == 1 && ep[2] == 6 && ep[3] == 0 && ep[4] == 0 && ep[5] == 0.0); + t = gpst2utc(epoch2time(ep1)); + time2epoch(t, ep); + assert(ep[0] == 1992 && ep[1] == 6 && ep[2] == 30 && ep[3] == 23 && ep[4] == 59 && + fabs(ep[5] - 59.999999) < 1E-14); + t = gpst2utc(epoch2time(ep2)); + time2epoch(t, ep); + assert(ep[0] == 1992 && ep[1] == 7 && ep[2] == 1 && ep[3] == 0 && ep[4] == 0 && ep[5] == 0.0); + t = gpst2utc(epoch2time(ep3)); + time2epoch(t, ep); + assert(ep[0] == 1992 && ep[1] == 7 && ep[2] == 1 && ep[3] == 0 && ep[4] == 0 && ep[5] == 0.0); + t = gpst2utc(epoch2time(ep4)); + time2epoch(t, ep); + assert(ep[0] == 2004 && ep[1] == 12 && ep[2] == 31 && ep[3] == 23 && ep[4] == 59 && + fabs(ep[5] - 46.999999) < 1E-14); + t = gpst2utc(epoch2time(ep5)); + time2epoch(t, ep); + assert(ep[0] == 2005 && ep[1] == 12 && ep[2] == 31 && ep[3] == 23 && ep[4] == 59 && + ep[5] == 47.0); + t = gpst2utc(epoch2time(ep6)); + time2epoch(t, ep); + assert(ep[0] == 2037 && ep[1] == 12 && ep[2] == 31 && ep[3] == 23 && ep[4] == 59 && + ep[5] == 42.0); + printf("%s utset7 : OK\n", __FILE__); } /* utc2gpst(), gpst2utc() */ -void utest8(void) -{ - double ep0[]={1980, 1, 6, 0, 0, 0.000000}; - double ep1[]={2010,12,31,23,59,59.999999}; - gtime_t t0,t1,t2,t3; - t0=epoch2time(ep0); - t1=epoch2time(ep1); - while (t0.time + * rtklib unit test driver : norad two line element function + *-----------------------------------------------------------------------------*/ #include +#include + #include "../../src/rtklib.h" #define OUT stdout /* dump tle ------------------------------------------------------------------*/ -static void dumptle(FILE *fp, const tle_t *tle) -{ - int i; - - for (i=0;in;i++) { - fprintf(fp,"(%2d) name = %s\n", i+1,tle->data[i].name ); - fprintf(fp,"(%2d) alias= %s\n", i+1,tle->data[i].alias); - fprintf(fp,"(%2d) satno= %s\n", i+1,tle->data[i].satno); - fprintf(fp,"(%2d) class= %c\n", i+1,tle->data[i].satclass); - fprintf(fp,"(%2d) desig= %s\n", i+1,tle->data[i].desig); - char tstr[40]; - time2str(tle->data[i].epoch,tstr,0); - fprintf(fp,"(%2d) epoch= %s\n", i+1,tstr); - fprintf(fp,"(%2d) etype= %d\n", i+1,tle->data[i].etype); - fprintf(fp,"(%2d) eleno= %d\n", i+1,tle->data[i].eleno); - fprintf(fp,"(%2d) ndot = %19.12e\n",i+1,tle->data[i].ndot ); - fprintf(fp,"(%2d) nddot= %19.12e\n",i+1,tle->data[i].nddot); - fprintf(fp,"(%2d) bstar= %19.12e\n",i+1,tle->data[i].bstar); - fprintf(fp,"(%2d) inc = %19.12e\n",i+1,tle->data[i].inc ); - fprintf(fp,"(%2d) OMG = %19.12e\n",i+1,tle->data[i].OMG ); - fprintf(fp,"(%2d) ecc = %19.12e\n",i+1,tle->data[i].ecc ); - fprintf(fp,"(%2d) omg = %19.12e\n",i+1,tle->data[i].omg ); - fprintf(fp,"(%2d) M = %19.12e\n",i+1,tle->data[i].M ); - fprintf(fp,"(%2d) n = %19.12e\n",i+1,tle->data[i].n ); - fprintf(fp,"(%2d) rev = %d\n", i+1,tle->data[i].rev ); - } +static void dumptle(FILE *fp, const tle_t *tle) { + int i; + + for (i = 0; i < tle->n; i++) { + fprintf(fp, "(%2d) name = %s\n", i + 1, tle->data[i].name); + fprintf(fp, "(%2d) alias= %s\n", i + 1, tle->data[i].alias); + fprintf(fp, "(%2d) satno= %s\n", i + 1, tle->data[i].satno); + fprintf(fp, "(%2d) class= %c\n", i + 1, tle->data[i].satclass); + fprintf(fp, "(%2d) desig= %s\n", i + 1, tle->data[i].desig); + char tstr[40]; + time2str(tle->data[i].epoch, tstr, 0); + fprintf(fp, "(%2d) epoch= %s\n", i + 1, tstr); + fprintf(fp, "(%2d) etype= %d\n", i + 1, tle->data[i].etype); + fprintf(fp, "(%2d) eleno= %d\n", i + 1, tle->data[i].eleno); + fprintf(fp, "(%2d) ndot = %19.12e\n", i + 1, tle->data[i].ndot); + fprintf(fp, "(%2d) nddot= %19.12e\n", i + 1, tle->data[i].nddot); + fprintf(fp, "(%2d) bstar= %19.12e\n", i + 1, tle->data[i].bstar); + fprintf(fp, "(%2d) inc = %19.12e\n", i + 1, tle->data[i].inc); + fprintf(fp, "(%2d) OMG = %19.12e\n", i + 1, tle->data[i].OMG); + fprintf(fp, "(%2d) ecc = %19.12e\n", i + 1, tle->data[i].ecc); + fprintf(fp, "(%2d) omg = %19.12e\n", i + 1, tle->data[i].omg); + fprintf(fp, "(%2d) M = %19.12e\n", i + 1, tle->data[i].M); + fprintf(fp, "(%2d) n = %19.12e\n", i + 1, tle->data[i].n); + fprintf(fp, "(%2d) rev = %d\n", i + 1, tle->data[i].rev); + } } /* tle_read() ----------------------------------------------------------------*/ -static void utest1(void) -{ - const char *file1="../data/tle/tle_sgp4.err"; - const char *file2="../data/tle/tle_sgp4.txt"; - const char *file3="../data/tle/tle_nav.txt"; - tle_t tle={0}; - int stat; +static void utest1(void) { + const char *file1 = "../data/tle/tle_sgp4.err"; + const char *file2 = "../data/tle/tle_sgp4.txt"; + const char *file3 = "../data/tle/tle_nav.txt"; + tle_t tle = {0}; + int stat; - stat=tle_read(file1,&tle); - assert(!stat); + stat = tle_read(file1, &tle); + assert(!stat); - stat=tle_read(file2,&tle); - assert(stat); - assert(tle.n==1); + stat = tle_read(file2, &tle); + assert(stat); + assert(tle.n == 1); - stat=tle_read(file3,&tle); - assert(stat); - assert(tle.n==114); + stat = tle_read(file3, &tle); + assert(stat); + assert(tle.n == 114); #if RTK_DISABLED /* for debug */ - dumptle(OUT,&tle); + dumptle(OUT, &tle); #endif - fprintf(OUT,"%s utest1 : OK\n",__FILE__); + fprintf(OUT, "%s utest1 : OK\n", __FILE__); } /* tle_pos() -----------------------------------------------------------------*/ -static void utest2(void) -{ - const char *file2="../data/tle/tle_sgp4.txt"; - const double ep0[6]={1980,10,1}; - tle_t tle={0}; - gtime_t epoch; - double min,rs[6]; - int i,stat; - - epoch=utc2gpst(timeadd(epoch2time(ep0),274.98708465*86400.0)); - - stat=tle_read(file2,&tle); - assert(stat); +static void utest2(void) { + const char *file2 = "../data/tle/tle_sgp4.txt"; + const double ep0[6] = {1980, 10, 1}; + tle_t tle = {0}; + gtime_t epoch; + double min, rs[6]; + int i, stat; - stat=tle_pos(epoch,"TEST_ERR","","",&tle,NULL,rs); - assert(!stat); + epoch = utc2gpst(timeadd(epoch2time(ep0), 274.98708465 * 86400.0)); - stat=tle_pos(epoch,"TEST_SAT","","",&tle,NULL,rs); - assert(stat); + stat = tle_read(file2, &tle); + assert(stat); - for (i=0;i<5;i++) { - min=360.0*i; + stat = tle_pos(epoch, "TEST_ERR", "", "", &tle, NULL, rs); + assert(!stat); - stat=tle_pos(timeadd(epoch,min*60.0),"TEST_SAT","","",&tle,NULL,rs); - assert(stat); + stat = tle_pos(epoch, "TEST_SAT", "", "", &tle, NULL, rs); + assert(stat); - fprintf(OUT,"%4.0f: %14.8f %14.8f %14.8f %11.8f %11.8f %11.8f\n",min, - rs[0]/1e3,rs[1]/1e3,rs[2]/1e3,rs[3]/1e3,rs[4]/1e3,rs[5]/1e3); - } - fprintf(OUT,"%s utest2 : OK\n",__FILE__); + for (i = 0; i < 5; i++) { + min = 360.0 * i; + + stat = tle_pos(timeadd(epoch, min * 60.0), "TEST_SAT", "", "", &tle, NULL, rs); + assert(stat); + + fprintf(OUT, "%4.0f: %14.8f %14.8f %14.8f %11.8f %11.8f %11.8f\n", min, rs[0] / 1e3, + rs[1] / 1e3, rs[2] / 1e3, rs[3] / 1e3, rs[4] / 1e3, rs[5] / 1e3); + } + fprintf(OUT, "%s utest2 : OK\n", __FILE__); } /* tle_pos() accuracy --------------------------------------------------------*/ -static void utest3(void) -{ - const char *file1="../data/tle/brdc3050.12*"; - const char *file2="../data/tle/TLE_GNSS_20121101.txt"; - const char *file3="../data/tle/igs17127.erp"; - const double ep[6]={2012,10,31,0,0,0}; - nav_t nav={0}; - erp_t erp={0}; - tle_t tle={0}; - gtime_t time; - char sat[8]; - double rs1[6],rs2[6],ds[6],dts[2],var; - int i,j,k,stat,svh; - - readrnx(file1,0,"",NULL,&nav,NULL); - assert(nav.n>0); - - stat=readerp(file3,&erp); - assert(stat); - - stat=tle_read(file2,&tle); - assert(stat); +static void utest3(void) { + const char *file1 = "../data/tle/brdc3050.12*"; + const char *file2 = "../data/tle/TLE_GNSS_20121101.txt"; + const char *file3 = "../data/tle/igs17127.erp"; + const double ep[6] = {2012, 10, 31, 0, 0, 0}; + nav_t nav = {0}; + erp_t erp = {0}; + tle_t tle = {0}; + gtime_t time; + char sat[8]; + double rs1[6], rs2[6], ds[6], dts[2], var; + int i, j, k, stat, svh; + + readrnx(file1, 0, "", NULL, &nav, NULL); + assert(nav.n > 0); + + stat = readerp(file3, &erp); + assert(stat); + + stat = tle_read(file2, &tle); + assert(stat); #if 1 /* for debug */ - dumptle(OUT,&tle); + dumptle(OUT, &tle); #endif - for (i=0;i + * gencrc.c : generate crc table + * + * Copyright (C) 2013 by T.TAKASU, All rights reserved. + * + * version : $Revision:$ $Date:$ + * history : 2013/02/28 1.0 new + *-----------------------------------------------------------------------------*/ #include +#include #include -static const char rcsid[]="$Id:$"; +static const char rcsid[] = "$Id:$"; -#define POLYCRC16 0x1021u /* CRC16 polynomial for BINEX,NVS */ -#define POLYCRC24Q 0x1864CFBu /* CRC24Q polynomial for SBAS */ +#define POLYCRC16 0x1021u /* CRC16 polynomial for BINEX,NVS */ +#define POLYCRC24Q 0x1864CFBu /* CRC24Q polynomial for SBAS */ /* generate crc-16 parity table -----------------------------------------------*/ -static void gen_crc16(FILE *fp) -{ - uint16_t crcs[256]={0}; - int i,j; - - for (i=0;i<256;i++) { - crcs[i]=(uint16_t)i<<8; - for (j=0;j<8;j++) { - if (crcs[i]&0x8000) crcs[i]=(crcs[i]<<1)^POLYCRC16; - else crcs[i]<<=1; - } +static void gen_crc16(FILE *fp) { + uint16_t crcs[256] = {0}; + int i, j; + + for (i = 0; i < 256; i++) { + crcs[i] = (uint16_t)i << 8; + for (j = 0; j < 8; j++) { + if (crcs[i] & 0x8000) + crcs[i] = (crcs[i] << 1) ^ POLYCRC16; + else + crcs[i] <<= 1; } - fprintf(fp,"static const uint16_t tbl_CRC16[]={\n"); - - for (i=0;i<32;i++) { - fprintf(fp," "); - for (j=0;j<8;j++) { - fprintf(fp,"0x%04X%s",crcs[j+i*8],i==31&&j==7?"":","); - } - fprintf(fp,"\n"); + } + fprintf(fp, "static const uint16_t tbl_CRC16[]={\n"); + + for (i = 0; i < 32; i++) { + fprintf(fp, " "); + for (j = 0; j < 8; j++) { + fprintf(fp, "0x%04X%s", crcs[j + i * 8], i == 31 && j == 7 ? "" : ","); } - fprintf(fp,"};\n"); + fprintf(fp, "\n"); + } + fprintf(fp, "};\n"); } /* generate crc-24q parity table ---------------------------------------------*/ -static void gen_crc24(FILE *fp) -{ - uint32_t crcs[256]={0}; - int i,j; - - for (i=0;i<256;i++) { - crcs[i]=(uint32_t)i<<16; - for (j=0;j<8;j++) if ((crcs[i]<<=1)&0x1000000) crcs[i]^=POLYCRC24Q; - } - fprintf(fp,"static const uint32_t tbl_CRC24Q[]={\n"); - - for (i=0;i<32;i++) { - fprintf(fp," "); - for (j=0;j<8;j++) { - fprintf(fp,"0x%06X%s",crcs[j+i*8],i==31&&j==7?"":","); - } - fprintf(fp,"\n"); +static void gen_crc24(FILE *fp) { + uint32_t crcs[256] = {0}; + int i, j; + + for (i = 0; i < 256; i++) { + crcs[i] = (uint32_t)i << 16; + for (j = 0; j < 8; j++) + if ((crcs[i] <<= 1) & 0x1000000) crcs[i] ^= POLYCRC24Q; + } + fprintf(fp, "static const uint32_t tbl_CRC24Q[]={\n"); + + for (i = 0; i < 32; i++) { + fprintf(fp, " "); + for (j = 0; j < 8; j++) { + fprintf(fp, "0x%06X%s", crcs[j + i * 8], i == 31 && j == 7 ? "" : ","); } - fprintf(fp,"};\n"); + fprintf(fp, "\n"); + } + fprintf(fp, "};\n"); } /* main ----------------------------------------------------------------------*/ -int main(int argc, char **argv) -{ - FILE *fp=stdout; - int i,crc=0; - - for (i=1;i + * genmsk.c: generate glonass hamming mask + *-----------------------------------------------------------------------------*/ #include +#include -static const int pos[8][85]={ - { 9,10,12,13,15,17,19,20,22,24,26,28,30,32,34,35,37,39,41,43,45,47,49,51,53,55,57,59,61,63,65,66,68,70,72,74,76,78,80,82,84,0}, - { 9,11,12,14,15,18,19,21,22,25,26,29,30,33,34,36,37,40,41,44,45,48,49,52,53,56,57,60,61,64,65,67,68,71,72,75,76,79,80,83,84,0}, - {10,11,12,16,17,18,19,23,24,25,26,31,32,33,34,38,39,40,41,46,47,48,49,54,55,56,57,62,63,64,65,69,70,71,72,77,78,79,80,85,0}, - {13,14,15,16,17,18,19,27,28,29,30,31,32,33,34,42,43,44,45,46,47,48,49,58,59,60,61,62,63,64,65,73,74,75,76,77,78,79,80,0}, - {20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,81,82,83,84,85,0}, - {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,0}, - {66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,0}, - { 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,0}, +static const int pos[8][85] = { + {9, 10, 12, 13, 15, 17, 19, 20, 22, 24, 26, 28, 30, 32, 34, 35, 37, 39, 41, 43, 45, + 47, 49, 51, 53, 55, 57, 59, 61, 63, 65, 66, 68, 70, 72, 74, 76, 78, 80, 82, 84, 0}, + {9, 11, 12, 14, 15, 18, 19, 21, 22, 25, 26, 29, 30, 33, 34, 36, 37, 40, 41, 44, 45, + 48, 49, 52, 53, 56, 57, 60, 61, 64, 65, 67, 68, 71, 72, 75, 76, 79, 80, 83, 84, 0}, + {10, 11, 12, 16, 17, 18, 19, 23, 24, 25, 26, 31, 32, 33, 34, 38, 39, 40, 41, 46, 47, + 48, 49, 54, 55, 56, 57, 62, 63, 64, 65, 69, 70, 71, 72, 77, 78, 79, 80, 85, 0}, + {13, 14, 15, 16, 17, 18, 19, 27, 28, 29, 30, 31, 32, 33, 34, 42, 43, 44, 45, 46, + 47, 48, 49, 58, 59, 60, 61, 62, 63, 64, 65, 73, 74, 75, 76, 77, 78, 79, 80, 0}, + {20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 50, 51, 52, 53, + 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 81, 82, 83, 84, 85, 0}, + {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, 0}, + {66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 0}, + {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, 0}, }; -int main(int argc, char **argv) -{ - int i,j,bits[11],p; - - printf("const uint8_t mask[][11]={\n"); - for (i=0;i<8;i++) { - for (j=0;j<11;j++) bits[j]=0; - for (j=0;pos[i][j];j++) { - p=85-pos[i][j]; - bits[p/8]|=1<<(7-p%8); - } - printf(" {"); - for (j=0;j<10;j++) printf("0x%02X%s",bits[j],j<9?",":""); - printf("}%s\n",i<7?",":""); +int main(int argc, char **argv) { + int i, j, bits[11], p; + + printf("const uint8_t mask[][11]={\n"); + for (i = 0; i < 8; i++) { + for (j = 0; j < 11; j++) bits[j] = 0; + for (j = 0; pos[i][j]; j++) { + p = 85 - pos[i][j]; + bits[p / 8] |= 1 << (7 - p % 8); } - printf("};\n"); - return 0; + printf(" {"); + for (j = 0; j < 10; j++) printf("0x%02X%s", bits[j], j < 9 ? "," : ""); + printf("}%s\n", i < 7 ? "," : ""); + } + printf("};\n"); + return 0; } diff --git a/util/gencrc/genxor.c b/util/gencrc/genxor.c index 4290e0433..459169a2e 100644 --- a/util/gencrc/genxor.c +++ b/util/gencrc/genxor.c @@ -1,18 +1,17 @@ /*------------------------------------------------------------------------------ -* genxor.c: generate xor table -*-----------------------------------------------------------------------------*/ + * genxor.c: generate xor table + *-----------------------------------------------------------------------------*/ #include -int main(int argc, char **argv) -{ - int i,j,b; - - printf("const uint8_t xor_bits[]={\n"); - - for (i=0;i<256;i++) { - for (j=b=0;j<8;j++) b^=((i>>j)&1); - printf("%d%s",b,i==255?"\n":(i%32==31?",\n":",")); - } - printf("};\n"); - return 0; +int main(int argc, char **argv) { + int i, j, b; + + printf("const uint8_t xor_bits[]={\n"); + + for (i = 0; i < 256; i++) { + for (j = b = 0; j < 8; j++) b ^= ((i >> j) & 1); + printf("%d%s", b, i == 255 ? "\n" : (i % 32 == 31 ? ",\n" : ",")); + } + printf("};\n"); + return 0; } diff --git a/util/geniono/estiono.c b/util/geniono/estiono.c index 5029c03a2..0deb75570 100644 --- a/util/geniono/estiono.c +++ b/util/geniono/estiono.c @@ -1,247 +1,239 @@ /*------------------------------------------------------------------------------ -* geniono.c : ionosphere correction estimation -* -* Copyright (C) 2012 by T.TAKASU, All rights reserved. -* -* version : $Revision:$ $Date:$ -* history : 2012/09/15 1.0 new -*-----------------------------------------------------------------------------*/ + * geniono.c : ionosphere correction estimation + * + * Copyright (C) 2012 by T.TAKASU, All rights reserved. + * + * version : $Revision:$ $Date:$ + * history : 2012/09/15 1.0 new + *-----------------------------------------------------------------------------*/ #include "rtklib.h" -static const char rcsid[]="$Id:$"; +static const char rcsid[] = "$Id:$"; -#define SQR(x) ((x)*(x)) -#define MIN(x,y) ((x)<=(y)?(x):(y)) +#define SQR(x) ((x) * (x)) +#define MIN(x, y) ((x) <= (y) ? (x) : (y)) -#define FACT_LG 0.4 -#define SIG_ERR_A 0.003 -#define SIG_ERR_B 0.003 -#define RATIO_ERR 100.0 +#define FACT_LG 0.4 +#define SIG_ERR_A 0.003 +#define SIG_ERR_B 0.003 +#define RATIO_ERR 100.0 -#define PRN_IONO SQR(1E-3) /* process noise variance of iono delay (m^2/s) */ -#define VAR_IONO SQR(10.0) /* initial variance of vertical iono delay (m^2) */ +#define PRN_IONO SQR(1E-3) /* process noise variance of iono delay (m^2/s) */ +#define VAR_IONO SQR(10.0) /* initial variance of vertical iono delay (m^2) */ -#define II(s) ((s)-1) /* state index of ionos */ -#define IB(s) (MAXSAT+(s)-1) /* state index of phase bias */ -#define NX (MAXSAT*2) /* number of estimated states */ +#define II(s) ((s) - 1) /* state index of ionos */ +#define IB(s) (MAXSAT + (s) - 1) /* state index of phase bias */ +#define NX (MAXSAT * 2) /* number of estimated states */ -typedef struct { /* satellite status type */ - gtime_t time; /* time */ - double azel[2]; /* azimuth/elevation (rad) */ - double gf; /* geometry-free phase value (m) */ +typedef struct { /* satellite status type */ + gtime_t time; /* time */ + double azel[2]; /* azimuth/elevation (rad) */ + double gf; /* geometry-free phase value (m) */ } stat_t; /* initialize state and covariance -------------------------------------------*/ -static void initx(double *x, double *P, int nx, int i, double xi, double var) -{ - int j; - x[i]=xi; - for (j=0;jL[0]!=0.0&&obs->L[1]!=0.0) { - G0=stat[obs->sat-1].gf; - stat[obs->sat-1].gf=G1=obs->L[0]-obs->L[1]; - if (fabs(G1-G0)>THRES_SLIP) return 1; - } - return (obs->LLI[0]&3)||(obs->LLI[1]&3); +static int det_slip(const obsd_t *obs, const nav_t *nav, stat_t *stat) { + double G0; + + if (obs->L[0] != 0.0 && obs->L[1] != 0.0) { + G0 = stat[obs->sat - 1].gf; + stat[obs->sat - 1].gf = G1 = obs->L[0] - obs->L[1]; + if (fabs(G1 - G0) > THRES_SLIP) return 1; + } + return (obs->LLI[0] & 3) || (obs->LLI[1] & 3); } /* initizlize ionosphere parameter --------------------------------------------*/ -static void init_iono(const obsd_t *obs, const double *azel, double *x, - double *P, int nx) -{ - double map,iono; - if (obs->P[0]==0||obs->P[1]==0) return; - map=ionmapf(pos,azel); - iono=(obs->P[0]-obs->P[1])/map; - initx(x,P,nx,II(obs->sat),iono,VAR_IONO); +static void init_iono(const obsd_t *obs, const double *azel, double *x, double *P, int nx) { + double map, iono; + if (obs->P[0] == 0 || obs->P[1] == 0) return; + map = ionmapf(pos, azel); + iono = (obs->P[0] - obs->P[1]) / map; + initx(x, P, nx, II(obs->sat), iono, VAR_IONO); } /* initizlize bias parameter --------------------------------------------------*/ -static void init_bias(const obsd_t *obs, double *x, double *P, int nx) -{ - double bias; - if (obs->L[0]==0||obs->L[1]==0||obs->P[0]==0||obs->P[1]==0) return; - bias=(obs->L[0]-obs->L[1])-(obs->P[0]-obs->P[1]); - initx(x,P,nx,IB(obs->sat),bias,VAR_BIAS); +static void init_bias(const obsd_t *obs, double *x, double *P, int nx) { + double bias; + if (obs->L[0] == 0 || obs->L[1] == 0 || obs->P[0] == 0 || obs->P[1] == 0) return; + bias = (obs->L[0] - obs->L[1]) - (obs->P[0] - obs->P[1]); + initx(x, P, nx, IB(obs->sat), bias, VAR_BIAS); } /* temporal update of states --------------------------------------------------*/ -static void udstate(const obsd_t *obs, int n, const nav_t *nav, double *x, - double *P, int nx, ssat_t *ssat) -{ - gtime_t time; - double tt; - int i,sat; - - for (i=0;iMAXGAP_BIAS) { - init_bias(obs+i,nav,x,P,nx); - } - } - ssat[sat-1].time=time; +static void udstate(const obsd_t *obs, int n, const nav_t *nav, double *x, double *P, int nx, + ssat_t *ssat) { + gtime_t time; + double tt; + int i, sat; + + for (i = 0; i < n; i++) { + sat = obs[i].sat time = ssat[sat - 1].time; + + if (!time.time) { + init_iono(obs + i, nav, x, P, nx); + init_bias(obs + i, nav, x, P, nx); + } else { + tt = timediff(obs[i].time, time); + + P[II(sat) * (nx + 1)] += PRN_IONO * fabs(tt); + + if (det_slip(obs + i, nav, ssat) || fabs(tt) > MAXGAP_BIAS) { + init_bias(obs + i, nav, x, P, nx); + } } + ssat[sat - 1].time = time; + } } /* measurement error standard deviation --------------------------------------*/ -static double std_err(const double *azel) -{ - return FACT_LG*(SIG_ERR_A+SIG_ERR_B/sin(azel[1])); +static double std_err(const double *azel) { + return FACT_LG * (SIG_ERR_A + SIG_ERR_B / sin(azel[1])); } /* satellite azimuth/elevation angle -----------------------------------------*/ -static void sat_azel(const obsd_t *obs, int n, const nav_t *nav, - const double *pos, double *azel) -{ - double rs[MAXOBS*6],dts[MAXOBS*2],var[MAXOBS],r,e[3]; - int svh[MAXOBS]; - - /* satellite positions and clocks */ - satposs(obs[0].time,obs,n,nav,EPHOPT_BRDC,rs,dts,var,svh); - - for (i=0;i0.0) satazel(pos,e,azel+i*2); - } +static void sat_azel(const obsd_t *obs, int n, const nav_t *nav, const double *pos, double *azel) { + double rs[MAXOBS * 6], dts[MAXOBS * 2], var[MAXOBS], r, e[3]; + int svh[MAXOBS]; + + /* satellite positions and clocks */ + satposs(obs[0].time, obs, n, nav, EPHOPT_BRDC, rs, dts, var, svh); + + for (i = 0; i < n; i++) { + if (geodist(rs + i * 6, rr, e))>0.0) satazel(pos,e,azel+i*2); + } } /* ionosphere residuals ------------------------------------------------------*/ -static int res_iono(const obsd_t *obs, int n, const double *azel, - const double *x, int nx, double *v, double *H, double *R) -{ - double *sig,L1,L2,P1,P2,map; - int i,j,nv=0,sat; - - sig=mat(1,2*n); - - for (i=0;iL[0]*lam[0]; - L2=obs->L[1]*lam[1]; - P1=obs->P[0]; - P2=obs->P[1]; - if (L1==0||L2==0||P1==0||P2==0) continue; - - /* ionosphere mapping function */ - map=ionmapf(pos,azel+i*2); - - /* residuals of ionosphere (geometriy-free) LC */ - v[nv ]=(L1-L2)+map*x[II(sat)]-x[IB(sat)]; - v[nv+1]=(P1-P2)-map*x[II(sat)]; - - /* partial derivatives */ - for (j=0;jL[0] * lam[0]; + L2 = obs->L[1] * lam[1]; + P1 = obs->P[0]; + P2 = obs->P[1]; + if (L1 == 0 || L2 == 0 || P1 == 0 || P2 == 0) continue; + + /* ionosphere mapping function */ + map = ionmapf(pos, azel + i * 2); + + /* residuals of ionosphere (geometriy-free) LC */ + v[nv] = (L1 - L2) + map * x[II(sat)] - x[IB(sat)]; + v[nv + 1] = (P1 - P2) - map * x[II(sat)]; + + /* partial derivatives */ + for (j = 0; j < nx; j++) H[nx * nv + j] = 0.0; + H[nx * nv + II(sat)] = -map; + H[nx * nv + IB(sat)] = 1.0; + H[nx * (nv + 1) + IB(sat)] = map; + + /* standard deviation of error */ + sig[nv] = std_err(azel); + sig[nv + 1] = sig[nv] * RATIO_ERR; + nv += 2; + } + for (i = 0; i < nv; i++) + for (j = 0; j < nv; j++) { + R[i + j * nv] = i == j ? SQR(sig[i]) : 0.0; } - free(sig); - return nv; + free(sig); + return nv; } /* output ionosphere parameters ----------------------------------------------*/ -static int out_iono(gtime_t time, const double *x, const double *P, int nx, - FILE *fp) -{ - double tow; - char id[64]; - int i,week; - - tow=time2gpst(time,&week); - - for (i=0;in;i++) { - for (n=1;i+nn;n++) { - if (timediff(obs[i].time,obs->data[i+n].time)>1E-3) break; - } - /* satellite azimuth/elevation angle */ - sat_azel(obs+i,n,nav,pos,azel); - - /* time update of parameters */ - ud_state(obs+i,n,azel,x,P,nx,ssat); - - /* ionosphere residuals */ - if ((nv=res_iono(obs+i,n,azel,x,nx,v,H,R))<=0) break; - - /* filter */ - if ((info=filter(x,P,H,v,R,nx,nv))) break; - - /* output ionopshere parameters */ - out_iono(obs[i].time,x,P,nx,fp); +static int est_iono(obs_t *obs, nav_t *nav, double *rr, FILE *fp) { + ssat_t ssat[MAXSAT] = {{0}}; + double tt, *x, *P, *v, *H, *R, pos[3], azel[MAXOBS * 2]; + int i, n, info, nx = NX, nv = MAXSAT * 2; + + x = zeros(nx, 1); + P = zeros(nx, nx); + v = mat(nv, 1); + H = mat(nx, nv); + R = mat(nv, nv); + + /* receiver position */ + ecef2pos(rr, pos); + + for (i = 0; i < obs->n; i++) { + for (n = 1; i + n < obs->n; n++) { + if (timediff(obs[i].time, obs->data[i + n].time) > 1E-3) break; } - free(x); free(P); free(v); free(H); free(R); - - return 1; + /* satellite azimuth/elevation angle */ + sat_azel(obs + i, n, nav, pos, azel); + + /* time update of parameters */ + ud_state(obs + i, n, azel, x, P, nx, ssat); + + /* ionosphere residuals */ + if ((nv = res_iono(obs + i, n, azel, x, nx, v, H, R)) <= 0) break; + + /* filter */ + if ((info = filter(x, P, H, v, R, nx, nv))) break; + + /* output ionopshere parameters */ + out_iono(obs[i].time, x, P, nx, fp); + } + free(x); + free(P); + free(v); + free(H); + free(R); + + return 1; } /* main ----------------------------------------------------------------------*/ -int main(int argc, char **argv) -{ - FILE *fp=stdout; - nav_t nav={0}; - obs_t obs={0}; - double rr[3]={0}; - char *ifile[32],*ofile=""; - int i,j,n=0; - - for (i=1;i1E-3) break; - - /* for each satellite */ - for (sat=1;sat<=MAXSAT;sat++) { - - /* interpolation of ionosphere */ - if (!interp_ion(nav,t0,t1,sat,n,index,dist,iono+sat-1,&rate, - &var,&brk)) { - continue; - } - if (!fp) { - sprintf(file,"%s/%c%4.0f_%c%5.0f.stec",dir, - pos[0]<0.0?'S':'N',fabs(pos[0])*R2D*100.0, - pos[1]<0.0?'W':'E',fabs(pos[1])*R2D*100.0); - - if (!(fp=fopen(file,"w"))) { - fprintf(stderr,"file open error: %s\n",file); - continue; - } - out_head(t1,pos,fp); - } - /* output ionosphere delay */ - out_iono(t1,sat,brk,iono[sat-1],rate,var,fp); +static void interp_grid(const nav_t *nav, gtime_t ts, gtime_t te, double tint, const double *pos, + const char *dir) { + FILE *fp = NULL; + gtime_t t0 = {0}, t1; + double iono[MAXSAT] = {0}, rate, var, dist[MAX_NGRID]; + char file[1024]; + int i, n, sat, brk, index[MAX_NGRID]; + + /* search grid */ + if (!(n = stec_grid(nav, pos, MAX_NGRID, index, dist))) return; + + fprintf(stderr, "GRID=%.2f %.2f, N=%d\n", pos[0] * R2D, pos[1] * R2D, n); + + /* for each epoch */ + for (i = 0;; i++, t0 = t1) { + t1 = timeadd(ts, tint * i); + if (timediff(t1, te) > 1E-3) break; + + /* for each satellite */ + for (sat = 1; sat <= MAXSAT; sat++) { + /* interpolation of ionosphere */ + if (!interp_ion(nav, t0, t1, sat, n, index, dist, iono + sat - 1, &rate, &var, &brk)) { + continue; + } + if (!fp) { + sprintf(file, "%s/%c%4.0f_%c%5.0f.stec", dir, pos[0] < 0.0 ? 'S' : 'N', + fabs(pos[0]) * R2D * 100.0, pos[1] < 0.0 ? 'W' : 'E', fabs(pos[1]) * R2D * 100.0); + + if (!(fp = fopen(file, "w"))) { + fprintf(stderr, "file open error: %s\n", file); + continue; } + out_head(t1, pos, fp); + } + /* output ionosphere delay */ + out_iono(t1, sat, brk, iono[sat - 1], rate, var, fp); } - if (fp) fclose(fp); + } + if (fp) fclose(fp); } /* interpolation of stec -----------------------------------------------------*/ -static void interp_stec(const nav_t *nav, gtime_t ts, gtime_t te, double tint, - const double *ew, const double *ns, double gint, - const char *dir) -{ - double lat,lon,pos[3]={0}; - int i,j; - - for (i=0;;i++) { /* N -> S */ - if ((lat=ns[0]-gint*i) E */ - if ((lon=ew[1]+gint*j)>ew[0]+1E-6) break; - - pos[0]=lat*D2R; - pos[1]=lon*D2R; - - /* interpolation of stec to grid */ - interp_grid(nav,ts,te,tint,pos,dir); - } +static void interp_stec(const nav_t *nav, gtime_t ts, gtime_t te, double tint, const double *ew, + const double *ns, double gint, const char *dir) { + double lat, lon, pos[3] = {0}; + int i, j; + + for (i = 0;; i++) { /* N -> S */ + if ((lat = ns[0] - gint * i) < ns[1] - 1E-6) break; + + for (j = 0;; j++) { /* W -> E */ + if ((lon = ew[1] + gint * j) > ew[0] + 1E-6) break; + + pos[0] = lat * D2R; + pos[1] = lon * D2R; + + /* interpolation of stec to grid */ + interp_grid(nav, ts, te, tint, pos, dir); } + } } /* main ----------------------------------------------------------------------*/ -int main(int argc, char **argv) -{ - nav_t nav={0}; - gtime_t ts={0},te={0}; - double eps[6]={2011,1,1,0,0,0},epe[6]={2011,1,3,23,59,59},tint=30.0; - double ew[2]={AREA_E,AREA_W},ns[2]={AREA_N,AREA_S},gint=GRID_INT; - char *ifile="",*dir="."; - int i; - - for (i=1;inx=nx; - ekf->x=zeros(nx,1); - ekf->P=zeros(nx,nx); - return ekf; +static ekf_t *ekf_new(int nx) { + ekf_t *ekf; + if (!(ekf = (ekf_t *)malloc(sizeof(ekf_t)))) return NULL; + ekf->nx = nx; + ekf->x = zeros(nx, 1); + ekf->P = zeros(nx, nx); + return ekf; } /* free ekf ------------------------------------------------------------------*/ -static void ekf_free(ekf_t *ekf) -{ - if (!ekf) return; - free(ekf->x); - free(ekf->P); - free(ekf); +static void ekf_free(ekf_t *ekf) { + if (!ekf) return; + free(ekf->x); + free(ekf->P); + free(ekf); } /* measurement error standard deviation --------------------------------------*/ -static double sig_err(const double *azel) -{ - return FACT_LG*(SIG_ERR_A+SIG_ERR_B/sin(azel[1])); +static double sig_err(const double *azel) { + return FACT_LG * (SIG_ERR_A + SIG_ERR_B / sin(azel[1])); } /* initialize states of ekf --------------------------------------------------*/ -static void ekf_init(ekf_t *ekf, const double *xi, double *Pi, int ix, int nx) -{ - int i,j; - - /* x(ix)=xi */ - matcpy(ekf->x+ix,xi,nx,1); - - /* P(ix,:)=0; P(ix,:)=0; P(ix,ix)=diag(Pi) */ - for (i=0;inx;j++) { - ekf->P[ix+i+ekf->nx*j]=ekf->P[j+ekf->nx*(ix+i)]=j==ix+i?Pi[i]:0.0; +static void ekf_init(ekf_t *ekf, const double *xi, double *Pi, int ix, int nx) { + int i, j; + + /* x(ix)=xi */ + matcpy(ekf->x + ix, xi, nx, 1); + + /* P(ix,:)=0; P(ix,:)=0; P(ix,ix)=diag(Pi) */ + for (i = 0; i < nx; i++) + for (j = 0; j < ekf->nx; j++) { + ekf->P[ix + i + ekf->nx * j] = ekf->P[j + ekf->nx * (ix + i)] = j == ix + i ? Pi[i] : 0.0; } } /* predict states of ekf -----------------------------------------------------*/ -static void ekf_pred(ekf_t *ekf, double *F, double *Q, int ix, int nx) -{ - double *A; - int i; - - A=mat(ekf->nx,nx); - - /* x(ix)=F*x(ix) */ - matmul("NN",nx,1,nx,1.0,F,ekf->x+ix,0.0,A); - matcpy(ekf->x+ix,A,nx,1); - - /* P(ix,:)=F*P(ix,:); P(:,ix)=P(:,ix)*F' */ - for (i=0;inx;i++) { - matmul("NN",nx,1,nx,1.0,F,ekf->P+ekf->nx*i+ix,0.0,A); - matcpy(ekf->P+ekf->nx*i+ix,A,nx,1); - } - matmul("NT",ekf->nx,nx,nx,1.0,ekf->P+ekf->nx*ix,F,0.0,A); - matcpy(ekf->P+ekf->nx*ix,A,ekf->nx,nx); - - /* P(ix,ix)+=diag(Q) */ - for (i=0;iP[(ix+i)*(ekf->nx+1)]+=Q[i]; - } - free(A); +static void ekf_pred(ekf_t *ekf, double *F, double *Q, int ix, int nx) { + double *A; + int i; + + A = mat(ekf->nx, nx); + + /* x(ix)=F*x(ix) */ + matmul("NN", nx, 1, nx, 1.0, F, ekf->x + ix, 0.0, A); + matcpy(ekf->x + ix, A, nx, 1); + + /* P(ix,:)=F*P(ix,:); P(:,ix)=P(:,ix)*F' */ + for (i = 0; i < ekf->nx; i++) { + matmul("NN", nx, 1, nx, 1.0, F, ekf->P + ekf->nx * i + ix, 0.0, A); + matcpy(ekf->P + ekf->nx * i + ix, A, nx, 1); + } + matmul("NT", ekf->nx, nx, nx, 1.0, ekf->P + ekf->nx * ix, F, 0.0, A); + matcpy(ekf->P + ekf->nx * ix, A, ekf->nx, nx); + + /* P(ix,ix)+=diag(Q) */ + for (i = 0; i < nx; i++) { + ekf->P[(ix + i) * (ekf->nx + 1)] += Q[i]; + } + free(A); } /* raw pseudorange and phase range with dcb correction ----------------------*/ -static int raw_obs(const obsd_t *obs, const nav_t *nav, double *P1, double *P2, - double *L1, double *L2) -{ - double gamma=SQR(lam[0]/lam[1]); - - *L1=obs->L[0]*lam[0]; - *L2=obs->L[1]*lam[1]; - *P1=obs->P[0]; - *P2=obs->P[1]; - if (*L1==0.0||*L2==0.0||*P1==0.0||*P2==0.0) return 0; - - *P1+=nav->cbias[obs->sat-1][0]; - *P2+=nav->cbias[obs->sat-1][0]*gamma; - if (obs->code[0]==CODE_L1C) *P1+=nav->cbias[obs->sat-1][1]; - return 1; +static int raw_obs(const obsd_t *obs, const nav_t *nav, double *P1, double *P2, double *L1, + double *L2) { + double gamma = SQR(lam[0] / lam[1]); + + *L1 = obs->L[0] * lam[0]; + *L2 = obs->L[1] * lam[1]; + *P1 = obs->P[0]; + *P2 = obs->P[1]; + if (*L1 == 0.0 || *L2 == 0.0 || *P1 == 0.0 || *P2 == 0.0) return 0; + + *P1 += nav->cbias[obs->sat - 1][0]; + *P2 += nav->cbias[obs->sat - 1][0] * gamma; + if (obs->code[0] == CODE_L1C) *P1 += nav->cbias[obs->sat - 1][1]; + return 1; } /* temporal update of states --------------------------------------------------*/ -static void ud_state(const obsd_t *obs, int n, const nav_t *nav, - const double *pos, const double *azel, ekf_t *ekf, - sstat_t *sstat) -{ - double P1,P2,L1,L2,PG,LG,tt,F[4]={0},Q[2]={0}; - double x[2]={0},P[2],c_iono=1.0-SQR(lam[1]/lam[0]); - int i,sat,slip; - - for (i=0;iTHRES_LG; - - if (fabs(tt)>MAXGAP_IONO) { +static void ud_state(const obsd_t *obs, int n, const nav_t *nav, const double *pos, + const double *azel, ekf_t *ekf, sstat_t *sstat) { + double P1, P2, L1, L2, PG, LG, tt, F[4] = {0}, Q[2] = {0}; + double x[2] = {0}, P[2], c_iono = 1.0 - SQR(lam[1] / lam[0]); + int i, sat, slip; + + for (i = 0; i < n; i++) { + /* raw pseudorange and phase range */ + if (!raw_obs(obs + i, nav, &P1, &P2, &L1, &L2) || azel[i * 2 + 1] < MIN_EL) continue; + + sat = obs[i].sat; + tt = timediff(obs[i].time, sstat[sat - 1].time); + LG = L1 - L2; + PG = P1 - P2; + slip = (obs[i].LLI[0] & 3) || (obs[i].LLI[1] & 3); + slip |= fabs(LG - sstat[sat - 1].LG) > THRES_LG; + + if (fabs(tt) > MAXGAP_IONO) { #if 1 - x[0]=PG/c_iono; + x[0] = PG / c_iono; #else - x[0]=ionmodel(obs[i].time,nav->ion_gps,pos,azel+i*2); + x[0] = ionmodel(obs[i].time, nav->ion_gps, pos, azel + i * 2); #endif - x[1]=1E-6; - P[0]=VAR_IONO; - P[1]=VAR_IONR; - ekf_init(ekf,x,P,II(sat),2); - } - else { - F[0]=F[3]=1.0; - F[2]=tt; - Q[0]=PRN_IONO*fabs(tt); - Q[1]=PRN_IONR*fabs(tt); - ekf_pred(ekf,F,Q,II(sat),2); - } - if (tt>MAXGAP_BIAS||slip) { - x[0]=LG+PG; - P[0]=VAR_BIAS; - ekf_init(ekf,x,P,IB(sat),1); - } - sstat[sat-1].time=obs[i].time; - sstat[sat-1].azel[0]=azel[i*2]; - sstat[sat-1].azel[1]=azel[i*2+1]; - sstat[sat-1].slip=slip; - sstat[sat-1].LG=LG; - sstat[sat-1].PG=PG; + x[1] = 1E-6; + P[0] = VAR_IONO; + P[1] = VAR_IONR; + ekf_init(ekf, x, P, II(sat), 2); + } else { + F[0] = F[3] = 1.0; + F[2] = tt; + Q[0] = PRN_IONO * fabs(tt); + Q[1] = PRN_IONR * fabs(tt); + ekf_pred(ekf, F, Q, II(sat), 2); } + if (tt > MAXGAP_BIAS || slip) { + x[0] = LG + PG; + P[0] = VAR_BIAS; + ekf_init(ekf, x, P, IB(sat), 1); + } + sstat[sat - 1].time = obs[i].time; + sstat[sat - 1].azel[0] = azel[i * 2]; + sstat[sat - 1].azel[1] = azel[i * 2 + 1]; + sstat[sat - 1].slip = slip; + sstat[sat - 1].LG = LG; + sstat[sat - 1].PG = PG; + } } /* ionosphere residuals ------------------------------------------------------*/ -static int res_iono(const obsd_t *obs, int n, const nav_t *nav, - const double *rs, const double *rr, const double *pos, - const double *azel, const pcv_t *pcv, const ekf_t *ekf, - double *phw, double *v, double *H, double *R) -{ - double *sig,P1,P2,L1,L2,c_iono=1.0-SQR(lam[1]/lam[0]); - double LG,PG,antdel[3]={0},dant[NFREQ]={0}; - int i,j,nv=0,sat; - - sig=mat(1,2*n); - - for (i=0;ix[II(sat)]+ekf->x[IB(sat)]; - PG= c_iono*ekf->x[II(sat)]+nav->cbias[sat-1][0]; - - /* receiver antenna phase center offset and variation */ - if (pcv) { - antmodel(pcv,antdel,azel+i*2,dant); - LG+=dant[0]-dant[1]; - PG+=dant[0]-dant[1]; - } - /* phase windup correction */ - windupcorr(obs[i].time,rs+i*6,rr,phw+obs[i].sat-1); - LG+=(lam[0]-lam[1])*phw[obs[i].sat-1]; - - /* residuals of ionosphere (geometriy-free) LC */ - v[nv ]=(L1-L2)-LG; +static int res_iono(const obsd_t *obs, int n, const nav_t *nav, const double *rs, const double *rr, + const double *pos, const double *azel, const pcv_t *pcv, const ekf_t *ekf, + double *phw, double *v, double *H, double *R) { + double *sig, P1, P2, L1, L2, c_iono = 1.0 - SQR(lam[1] / lam[0]); + double LG, PG, antdel[3] = {0}, dant[NFREQ] = {0}; + int i, j, nv = 0, sat; + + sig = mat(1, 2 * n); + + for (i = 0; i < n; i++) { + if (!raw_obs(obs + i, nav, &P1, &P2, &L1, &L2) || azel[i * 2 + 1] < MIN_EL) continue; + + sat = obs[i].sat; + + /* ionosphere-LC model */ + LG = -c_iono * ekf->x[II(sat)] + ekf->x[IB(sat)]; + PG = c_iono * ekf->x[II(sat)] + nav->cbias[sat - 1][0]; + + /* receiver antenna phase center offset and variation */ + if (pcv) { + antmodel(pcv, antdel, azel + i * 2, dant); + LG += dant[0] - dant[1]; + PG += dant[0] - dant[1]; + } + /* phase windup correction */ + windupcorr(obs[i].time, rs + i * 6, rr, phw + obs[i].sat - 1); + LG += (lam[0] - lam[1]) * phw[obs[i].sat - 1]; + + /* residuals of ionosphere (geometriy-free) LC */ + v[nv] = (L1 - L2) - LG; #if RTK_DISABLED - v[nv+1]=(P1-P2)-PG; + v[nv + 1] = (P1 - P2) - PG; #else - v[nv+1]=0.0; + v[nv + 1] = 0.0; #endif - for (j=0;jnx*2;j++) H[ekf->nx*nv+j]=0.0; - H[ekf->nx*nv +II(sat)]=-c_iono; - H[ekf->nx*nv +IB(sat)]=1.0; - H[ekf->nx*(nv+1)+II(sat)]=c_iono; - - sig[nv ]=sig_err(azel+i*2); - sig[nv+1]=RATIO_ERR*sig[nv]; - nv+=2; - } - for (i=0;inx * 2; j++) H[ekf->nx * nv + j] = 0.0; + H[ekf->nx * nv + II(sat)] = -c_iono; + H[ekf->nx * nv + IB(sat)] = 1.0; + H[ekf->nx * (nv + 1) + II(sat)] = c_iono; + + sig[nv] = sig_err(azel + i * 2); + sig[nv + 1] = RATIO_ERR * sig[nv]; + nv += 2; + } + for (i = 0; i < nv; i++) + for (j = 0; j < nv; j++) { + R[i + j * nv] = i == j ? SQR(sig[i]) : 0.0; } - free(sig); - return nv; + free(sig); + return nv; } /* output ionosphere header --------------------------------------------------*/ -static void out_head(gtime_t time, const double *pos, FILE *fp) -{ - double tow; - int week; - - tow=time2gpst(time,&week); - - fprintf(fp,"%s %4d %5.0f %7.3f %8.3f\n",SPOS_RID,week,tow,pos[0]*R2D, - pos[1]*R2D); +static void out_head(gtime_t time, const double *pos, FILE *fp) { + double tow; + int week; + + tow = time2gpst(time, &week); + + fprintf(fp, "%s %4d %5.0f %7.3f %8.3f\n", SPOS_RID, week, tow, pos[0] * R2D, pos[1] * R2D); } /* output ionosphere parameters ----------------------------------------------*/ -static void out_iono(gtime_t time, const ekf_t *ekf, const sstat_t *sstat, - FILE *fp) -{ - double tow; - char id[8]; - int sat,week; - - tow=time2gpst(time,&week); - - for (sat=1;sat<=MAXSAT;sat++) { - if (sstat[sat-1].time.time==0|| - timediff(time,sstat[sat-1].time)>MAXGAP_IONO) continue; - satno2id(sat,id); - fprintf(fp,"%s %4d %6.0f %-3s %d %8.4f %9.6f %7.4f %6.1f %5.1f %7.3f %11.3f\n", - STEC_RID,week,tow,id,sstat[sat-1].slip, - ekf->x[II(sat)],ekf->x[II(sat)+1], - sqrt(ekf->P[II(sat)*(ekf->nx+1)]),sstat[sat-1].azel[0]*R2D, - sstat[sat-1].azel[1]*R2D, sstat[sat-1].PG,sstat[sat-1].LG); - } +static void out_iono(gtime_t time, const ekf_t *ekf, const sstat_t *sstat, FILE *fp) { + double tow; + char id[8]; + int sat, week; + + tow = time2gpst(time, &week); + + for (sat = 1; sat <= MAXSAT; sat++) { + if (sstat[sat - 1].time.time == 0 || timediff(time, sstat[sat - 1].time) > MAXGAP_IONO) + continue; + satno2id(sat, id); + fprintf(fp, "%s %4d %6.0f %-3s %d %8.4f %9.6f %7.4f %6.1f %5.1f %7.3f %11.3f\n", STEC_RID, week, + tow, id, sstat[sat - 1].slip, ekf->x[II(sat)], ekf->x[II(sat) + 1], + sqrt(ekf->P[II(sat) * (ekf->nx + 1)]), sstat[sat - 1].azel[0] * R2D, + sstat[sat - 1].azel[1] * R2D, sstat[sat - 1].PG, sstat[sat - 1].LG); + } } /* estimate ionosphere -------------------------------------------------------*/ -static int est_iono(obs_t *obs, nav_t *nav, const pcv_t *pcv, double *rr, - double tint, FILE *fp) -{ - sstat_t sstat[MAXSAT]={{{0}}}; - ekf_t *ekf; - gtime_t time; - double pos[3],rs[MAXOBS*6],dts[MAXOBS*2],var[MAXOBS],e[3],azel[MAXOBS*2]; - double *v,*H,*R,phw[MAXSAT]={0}; - int i,j,n=0,info,nx=NX,nv=MAXSAT*2,svh[MAXOBS]; - - ekf=ekf_new(NX); v=mat(nv,1); H=mat(nx,nv); R=mat(nv,nv); - - /* receiver position */ - ecef2pos(rr,pos); - - out_head(obs->data[0].time,pos,fp); - - for (i=0;in;i+=n) { - for (n=1;i+nn;n++) { - if (timediff(obs->data[i+n].time,obs->data[i].time)>1E-3) break; - } - time=obs->data[i].time; - - /* satellite positions and clocks */ - satposs(time,obs->data+i,n,nav,EPHOPT_BRDC,rs,dts,var,svh); - - /* satellite azimuth/elevation angle */ - for (j=0;j0.0) satazel(pos,e,azel+j*2); - else azel[j*2]=azel[1+j*2]=0.0; - } - /* time update of parameters */ - ud_state(obs->data+i,n,nav,pos,azel,ekf,sstat); - - /* ionosphere residuals */ - if ((nv=res_iono(obs->data+i,n,nav,rs,rr,pos,azel,pcv,ekf,phw,v,H,R))<=0) { - continue; - } - /* filter */ - if ((info=filter(ekf->x,ekf->P,H,v,R,ekf->nx,nv))) { - fprintf(stderr,"filter error: info=%d\n",info); - break; - } - /* output ionopshere parameters */ - if (tint<=0.0||fmod(time2gpst(time,NULL)+0.005,tint)<0.01) { - out_iono(obs->data[i].time,ekf,sstat,fp); - } +static int est_iono(obs_t *obs, nav_t *nav, const pcv_t *pcv, double *rr, double tint, FILE *fp) { + sstat_t sstat[MAXSAT] = {{{0}}}; + ekf_t *ekf; + gtime_t time; + double pos[3], rs[MAXOBS * 6], dts[MAXOBS * 2], var[MAXOBS], e[3], azel[MAXOBS * 2]; + double *v, *H, *R, phw[MAXSAT] = {0}; + int i, j, n = 0, info, nx = NX, nv = MAXSAT * 2, svh[MAXOBS]; + + ekf = ekf_new(NX); + v = mat(nv, 1); + H = mat(nx, nv); + R = mat(nv, nv); + + /* receiver position */ + ecef2pos(rr, pos); + + out_head(obs->data[0].time, pos, fp); + + for (i = 0; i < obs->n; i += n) { + for (n = 1; i + n < obs->n; n++) { + if (timediff(obs->data[i + n].time, obs->data[i].time) > 1E-3) break; } - ekf_free(ekf); free(v); free(H); free(R); - - return 1; -} -/* main ----------------------------------------------------------------------*/ -int main(int argc, char **argv) -{ - FILE *fp=stdout; - pcvs_t pcvs={0}; - nav_t nav={0}; - obs_t obs={0}; - sta_t sta={{0}}; - pcv_t *pcv=NULL; - gtime_t ts={0},te={0}; - double eps[6]={0},epe[6]={0},rr[3]={0},tint=30.0; - char *ifile[32],*ofile="",*afile="",*dfile="",ant[64]=""; - int i,j,n=0; - - for (i=1;idata[i].time; + + /* satellite positions and clocks */ + satposs(time, obs->data + i, n, nav, EPHOPT_BRDC, rs, dts, var, svh); + + /* satellite azimuth/elevation angle */ + for (j = 0; j < n; j++) { + if (geodist(rs + j * 6, rr, e) > 0.0) + satazel(pos, e, azel + j * 2); + else + azel[j * 2] = azel[1 + j * 2] = 0.0; } - /* open output file */ - if (*ofile&&!(fp=fopen(ofile,"w"))) { - fprintf(stderr,"output file open error: %s\n",ofile); - return -1; + /* time update of parameters */ + ud_state(obs->data + i, n, nav, pos, azel, ekf, sstat); + + /* ionosphere residuals */ + if ((nv = res_iono(obs->data + i, n, nav, rs, rr, pos, azel, pcv, ekf, phw, v, H, R)) <= 0) { + continue; } - if (eps[2]>=1.0) ts=epoch2time(eps); - if (epe[2]>=1.0) te=epoch2time(epe); - - /* read rinex obs/nav */ - for (i=0;i0.0) matcpy(rr,sta.pos,3,1); + /* filter */ + if ((info = filter(ekf->x, ekf->P, H, v, R, ekf->nx, nv))) { + fprintf(stderr, "filter error: info=%d\n", info); + break; } - if (!sortobs(&obs)) { - fprintf(stderr,"no observation data\n"); - return -1; + /* output ionopshere parameters */ + if (tint <= 0.0 || fmod(time2gpst(time, NULL) + 0.005, tint) < 0.01) { + out_iono(obs->data[i].time, ekf, sstat, fp); } - uniqnav(&nav); - - /* read antenna file */ - if (*afile&&*ant) { - if (!readpcv(afile,&pcvs)) { - fprintf(stderr,"antenna file open error: %s\n",afile); - return -1; - } - /* search pcv */ - if (!(pcv=searchpcv(0,ant,obs.data[0].time,&pcvs))) { - fprintf(stderr,"no antenna parmeter: %s\n",ant); - } + } + ekf_free(ekf); + free(v); + free(H); + free(R); + + return 1; +} +/* main ----------------------------------------------------------------------*/ +int main(int argc, char **argv) { + FILE *fp = stdout; + pcvs_t pcvs = {0}; + nav_t nav = {0}; + obs_t obs = {0}; + sta_t sta = {{0}}; + pcv_t *pcv = NULL; + gtime_t ts = {0}, te = {0}; + double eps[6] = {0}, epe[6] = {0}, rr[3] = {0}, tint = 30.0; + char *ifile[32], *ofile = "", *afile = "", *dfile = "", ant[64] = ""; + int i, j, n = 0; + + for (i = 1; i < argc; i++) { + if (!strcmp(argv[i], "-ts") && i + 2 < argc) { + sscanf(argv[++i], "%lf/%lf/%lf", eps, eps + 1, eps + 2); + sscanf(argv[++i], "%lf:%lf:%lf", eps + 3, eps + 4, eps + 5); + } else if (!strcmp(argv[i], "-te") && i + 2 < argc) { + sscanf(argv[++i], "%lf/%lf/%lf", epe, epe + 1, epe + 2); + sscanf(argv[++i], "%lf:%lf:%lf", epe + 3, epe + 4, epe + 5); + } else if (!strcmp(argv[i], "-ti") && i + 1 < argc) { + tint = atof(argv[++i]); + } else if (!strcmp(argv[i], "-r") && i + 3 < argc) { + for (j = 0; j < 3; j++) rr[j] = atof(argv[++i]); + } else if (!strcmp(argv[i], "-o") && i + 1 < argc) + ofile = argv[++i]; + else if (!strcmp(argv[i], "-a") && i + 1 < argc) + afile = argv[++i]; + else if (!strcmp(argv[i], "-d") && i + 1 < argc) + dfile = argv[++i]; + else + ifile[n++] = argv[i]; + } + /* open output file */ + if (*ofile && !(fp = fopen(ofile, "w"))) { + fprintf(stderr, "output file open error: %s\n", ofile); + return -1; + } + if (eps[2] >= 1.0) ts = epoch2time(eps); + if (epe[2] >= 1.0) te = epoch2time(epe); + + /* read rinex obs/nav */ + for (i = 0; i < n; i++) { + fprintf(stderr, "reading: %s\n", ifile[i]); + + readrnxt(ifile[i], 1, ts, te, 0.0, &obs, &nav, &sta); + + if (*sta.antdes) strcpy(ant, sta.antdes); + if (norm(sta.pos, 3) > 0.0) matcpy(rr, sta.pos, 3, 1); + } + if (!sortobs(&obs)) { + fprintf(stderr, "no observation data\n"); + return -1; + } + uniqnav(&nav); + + /* read antenna file */ + if (*afile && *ant) { + if (!readpcv(afile, &pcvs)) { + fprintf(stderr, "antenna file open error: %s\n", afile); + return -1; + } + /* search pcv */ + if (!(pcv = searchpcv(0, ant, obs.data[0].time, &pcvs))) { + fprintf(stderr, "no antenna parmeter: %s\n", ant); } - /* read p1-c1 dcb parameters */ - if (*dfile) readdcb(dfile,&nav); - - /* set p1-p2 dcb parameters */ - for (i=0;inx=nx; - ekf->x=zeros(nx,1); - ekf->P=zeros(nx,nx); - return ekf; +static ekf_t *ekf_new(int nx) { + ekf_t *ekf; + if (!(ekf = (ekf_t *)malloc(sizeof(ekf_t)))) return NULL; + ekf->nx = nx; + ekf->x = zeros(nx, 1); + ekf->P = zeros(nx, nx); + return ekf; } /* free ekf ------------------------------------------------------------------*/ -static void ekf_free(ekf_t *ekf) -{ - if (!ekf) return; - free(ekf->x); - free(ekf->P); - free(ekf); +static void ekf_free(ekf_t *ekf) { + if (!ekf) return; + free(ekf->x); + free(ekf->P); + free(ekf); } /* measurement error standard deviation --------------------------------------*/ -static double sig_err(const double *azel) -{ - return FACT_LG*(SIG_ERR_A+SIG_ERR_B/sin(azel[1])); +static double sig_err(const double *azel) { + return FACT_LG * (SIG_ERR_A + SIG_ERR_B / sin(azel[1])); } /* initialize states of ekf --------------------------------------------------*/ -static void ekf_init(ekf_t *ekf, const double *xi, double *Pi, int ix, int nx) -{ - int i,j; - - /* x(ix)=xi */ - matcpy(ekf->x+ix,xi,nx,1); - - /* P(ix,:)=0; P(ix,:)=0; P(ix,ix)=diag(Pi) */ - for (i=0;inx;j++) { - ekf->P[ix+i+ekf->nx*j]=ekf->P[j+ekf->nx*(ix+i)]=j==ix+i?Pi[i]:0.0; +static void ekf_init(ekf_t *ekf, const double *xi, double *Pi, int ix, int nx) { + int i, j; + + /* x(ix)=xi */ + matcpy(ekf->x + ix, xi, nx, 1); + + /* P(ix,:)=0; P(ix,:)=0; P(ix,ix)=diag(Pi) */ + for (i = 0; i < nx; i++) + for (j = 0; j < ekf->nx; j++) { + ekf->P[ix + i + ekf->nx * j] = ekf->P[j + ekf->nx * (ix + i)] = j == ix + i ? Pi[i] : 0.0; } } /* predict states of ekf -----------------------------------------------------*/ -static void ekf_pred(ekf_t *ekf, double *F, double *Q, int ix, int nx) -{ - double *A; - int i; - - A=mat(ekf->nx,nx); - - /* x(ix)=F*x(ix) */ - matmul("NN",nx,1,nx,1.0,F,ekf->x+ix,0.0,A); - matcpy(ekf->x+ix,A,nx,1); - - /* P(ix,:)=F*P(ix,:); P(:,ix)=P(:,ix)*F' */ - for (i=0;inx;i++) { - matmul("NN",nx,1,nx,1.0,F,ekf->P+ekf->nx*i+ix,0.0,A); - matcpy(ekf->P+ekf->nx*i+ix,A,nx,1); - } - matmul("NT",ekf->nx,nx,nx,1.0,ekf->P+ekf->nx*ix,F,0.0,A); - matcpy(ekf->P+ekf->nx*ix,A,ekf->nx,nx); - - /* P(ix,ix)+=diag(Q) */ - for (i=0;iP[(ix+i)*(ekf->nx+1)]+=Q[i]; - } - free(A); +static void ekf_pred(ekf_t *ekf, double *F, double *Q, int ix, int nx) { + double *A; + int i; + + A = mat(ekf->nx, nx); + + /* x(ix)=F*x(ix) */ + matmul("NN", nx, 1, nx, 1.0, F, ekf->x + ix, 0.0, A); + matcpy(ekf->x + ix, A, nx, 1); + + /* P(ix,:)=F*P(ix,:); P(:,ix)=P(:,ix)*F' */ + for (i = 0; i < ekf->nx; i++) { + matmul("NN", nx, 1, nx, 1.0, F, ekf->P + ekf->nx * i + ix, 0.0, A); + matcpy(ekf->P + ekf->nx * i + ix, A, nx, 1); + } + matmul("NT", ekf->nx, nx, nx, 1.0, ekf->P + ekf->nx * ix, F, 0.0, A); + matcpy(ekf->P + ekf->nx * ix, A, ekf->nx, nx); + + /* P(ix,ix)+=diag(Q) */ + for (i = 0; i < nx; i++) { + ekf->P[(ix + i) * (ekf->nx + 1)] += Q[i]; + } + free(A); } /* raw pseudorange and phase range with dcb correction ----------------------*/ -static int raw_obs(const obsd_t *obs, const nav_t *nav, double *P1, double *P2, - double *L1, double *L2) -{ - double gamma=SQR(lam[0]/lam[1]); - - *L1=obs->L[0]*lam[0]; - *L2=obs->L[1]*lam[1]; - *P1=obs->P[0]; - *P2=obs->P[1]; - if (*L1==0.0||*L2==0.0||*P1==0.0||*P2==0.0) return 0; - - *P1+=nav->cbias[obs->sat-1][0]; - *P2+=nav->cbias[obs->sat-1][0]*gamma; - if (obs->code[0]==CODE_L1C) *P1+=nav->cbias[obs->sat-1][1]; - return 1; +static int raw_obs(const obsd_t *obs, const nav_t *nav, double *P1, double *P2, double *L1, + double *L2) { + double gamma = SQR(lam[0] / lam[1]); + + *L1 = obs->L[0] * lam[0]; + *L2 = obs->L[1] * lam[1]; + *P1 = obs->P[0]; + *P2 = obs->P[1]; + if (*L1 == 0.0 || *L2 == 0.0 || *P1 == 0.0 || *P2 == 0.0) return 0; + + *P1 += nav->cbias[obs->sat - 1][0]; + *P2 += nav->cbias[obs->sat - 1][0] * gamma; + if (obs->code[0] == CODE_L1C) *P1 += nav->cbias[obs->sat - 1][1]; + return 1; } /* temporal update of states --------------------------------------------------*/ -static void ud_state(const obsd_t *obs, int n, const nav_t *nav, - const double *pos, const double *azel, ekf_t *ekf, - sstat_t *sstat) -{ - double P1,P2,L1,L2,PG,LG,tt,F[4]={0},Q[2]={0}; - double x[2]={0},P[2],c_iono=1.0-SQR(lam[1]/lam[0]); - int i,sat,slip; - - for (i=0;iTHRES_LG; - - if (fabs(tt)>MAXGAP_IONO) { +static void ud_state(const obsd_t *obs, int n, const nav_t *nav, const double *pos, + const double *azel, ekf_t *ekf, sstat_t *sstat) { + double P1, P2, L1, L2, PG, LG, tt, F[4] = {0}, Q[2] = {0}; + double x[2] = {0}, P[2], c_iono = 1.0 - SQR(lam[1] / lam[0]); + int i, sat, slip; + + for (i = 0; i < n; i++) { + /* raw pseudorange and phase range */ + if (!raw_obs(obs + i, nav, &P1, &P2, &L1, &L2) || azel[i * 2 + 1] < MIN_EL) continue; + + sat = obs[i].sat; + tt = timediff(obs[i].time, sstat[sat - 1].time); + LG = L1 - L2; + PG = P1 - P2; + slip = (obs[i].LLI[0] & 3) || (obs[i].LLI[1] & 3); + slip |= fabs(LG - sstat[sat - 1].LG) > THRES_LG; + + if (fabs(tt) > MAXGAP_IONO) { #if 1 - x[0]=PG/c_iono; + x[0] = PG / c_iono; #else - x[0]=ionmodel(obs[i].time,nav->ion_gps,pos,azel+i*2); + x[0] = ionmodel(obs[i].time, nav->ion_gps, pos, azel + i * 2); #endif - x[1]=1E-6; - P[0]=VAR_IONO; - P[1]=VAR_IONR; - ekf_init(ekf,x,P,II(sat),2); - } - else { - F[0]=F[3]=1.0; - F[2]=tt; - Q[0]=PRN_IONO*fabs(tt); - Q[1]=PRN_IONR*fabs(tt); - ekf_pred(ekf,F,Q,II(sat),2); - } - if (tt>MAXGAP_BIAS||slip) { - x[0]=LG+PG; - P[0]=VAR_BIAS; - ekf_init(ekf,x,P,IB(sat),1); - } - sstat[sat-1].time=obs[i].time; - sstat[sat-1].azel[0]=azel[i*2]; - sstat[sat-1].azel[1]=azel[i*2+1]; - sstat[sat-1].slip=slip; - sstat[sat-1].LG=LG; - sstat[sat-1].PG=PG; + x[1] = 1E-6; + P[0] = VAR_IONO; + P[1] = VAR_IONR; + ekf_init(ekf, x, P, II(sat), 2); + } else { + F[0] = F[3] = 1.0; + F[2] = tt; + Q[0] = PRN_IONO * fabs(tt); + Q[1] = PRN_IONR * fabs(tt); + ekf_pred(ekf, F, Q, II(sat), 2); } + if (tt > MAXGAP_BIAS || slip) { + x[0] = LG + PG; + P[0] = VAR_BIAS; + ekf_init(ekf, x, P, IB(sat), 1); + } + sstat[sat - 1].time = obs[i].time; + sstat[sat - 1].azel[0] = azel[i * 2]; + sstat[sat - 1].azel[1] = azel[i * 2 + 1]; + sstat[sat - 1].slip = slip; + sstat[sat - 1].LG = LG; + sstat[sat - 1].PG = PG; + } } /* ionosphere residuals ------------------------------------------------------*/ -static int res_iono(const obsd_t *obs, int n, const nav_t *nav, - const double *rs, const double *rr, const double *pos, - const double *azel, const pcv_t *pcv, const ekf_t *ekf, - double *phw, double *v, double *H, double *R) -{ - double *sig,P1,P2,L1,L2,c_iono=1.0-SQR(lam[1]/lam[0]); - double LG,PG,antdel[3]={0},dant[NFREQ]={0}; - int i,j,nv=0,sat; - - sig=mat(1,2*n); - - for (i=0;ix[II(sat)]+ekf->x[IB(sat)]; - PG= c_iono*ekf->x[II(sat)]+nav->cbias[sat-1][0]; - - /* receiver antenna phase center offset and variation */ - if (pcv) { - antmodel(pcv,antdel,azel+i*2,dant); - LG+=dant[0]-dant[1]; - PG+=dant[0]-dant[1]; - } - /* phase windup correction */ - windupcorr(obs[i].time,rs+i*6,rr,phw+obs[i].sat-1); - LG+=(lam[0]-lam[1])*phw[obs[i].sat-1]; - - /* residuals of ionosphere (geometriy-free) LC */ - v[nv ]=(L1-L2)-LG; +static int res_iono(const obsd_t *obs, int n, const nav_t *nav, const double *rs, const double *rr, + const double *pos, const double *azel, const pcv_t *pcv, const ekf_t *ekf, + double *phw, double *v, double *H, double *R) { + double *sig, P1, P2, L1, L2, c_iono = 1.0 - SQR(lam[1] / lam[0]); + double LG, PG, antdel[3] = {0}, dant[NFREQ] = {0}; + int i, j, nv = 0, sat; + + sig = mat(1, 2 * n); + + for (i = 0; i < n; i++) { + if (!raw_obs(obs + i, nav, &P1, &P2, &L1, &L2) || azel[i * 2 + 1] < MIN_EL) continue; + + sat = obs[i].sat; + + /* ionosphere-LC model */ + LG = -c_iono * ekf->x[II(sat)] + ekf->x[IB(sat)]; + PG = c_iono * ekf->x[II(sat)] + nav->cbias[sat - 1][0]; + + /* receiver antenna phase center offset and variation */ + if (pcv) { + antmodel(pcv, antdel, azel + i * 2, dant); + LG += dant[0] - dant[1]; + PG += dant[0] - dant[1]; + } + /* phase windup correction */ + windupcorr(obs[i].time, rs + i * 6, rr, phw + obs[i].sat - 1); + LG += (lam[0] - lam[1]) * phw[obs[i].sat - 1]; + + /* residuals of ionosphere (geometriy-free) LC */ + v[nv] = (L1 - L2) - LG; #if RTK_DISABLED - v[nv+1]=(P1-P2)-PG; + v[nv + 1] = (P1 - P2) - PG; #else - v[nv+1]=0.0; + v[nv + 1] = 0.0; #endif - for (j=0;jnx*2;j++) H[ekf->nx*nv+j]=0.0; - H[ekf->nx*nv +II(sat)]=-c_iono; - H[ekf->nx*nv +IB(sat)]=1.0; - H[ekf->nx*(nv+1)+II(sat)]=c_iono; - - sig[nv ]=sig_err(azel+i*2); - sig[nv+1]=RATIO_ERR*sig[nv]; - nv+=2; - } - for (i=0;inx * 2; j++) H[ekf->nx * nv + j] = 0.0; + H[ekf->nx * nv + II(sat)] = -c_iono; + H[ekf->nx * nv + IB(sat)] = 1.0; + H[ekf->nx * (nv + 1) + II(sat)] = c_iono; + + sig[nv] = sig_err(azel + i * 2); + sig[nv + 1] = RATIO_ERR * sig[nv]; + nv += 2; + } + for (i = 0; i < nv; i++) + for (j = 0; j < nv; j++) { + R[i + j * nv] = i == j ? SQR(sig[i]) : 0.0; } - free(sig); - return nv; + free(sig); + return nv; } /* output ionosphere header --------------------------------------------------*/ -static void out_head(gtime_t time, const double *pos, FILE *fp) -{ - double tow; - int week; - - tow=time2gpst(time,&week); - - fprintf(fp,"%s %4d %5.0f %7.3f %8.3f\n",SPOS_RID,week,tow,pos[0]*R2D, - pos[1]*R2D); +static void out_head(gtime_t time, const double *pos, FILE *fp) { + double tow; + int week; + + tow = time2gpst(time, &week); + + fprintf(fp, "%s %4d %5.0f %7.3f %8.3f\n", SPOS_RID, week, tow, pos[0] * R2D, pos[1] * R2D); } /* output ionosphere parameters ----------------------------------------------*/ -static void out_iono(gtime_t time, const ekf_t *ekf, const sstat_t *sstat, - FILE *fp) -{ - double tow; - char id[8]; - int sat,week; - - tow=time2gpst(time,&week); - - for (sat=1;sat<=MAXSAT;sat++) { - if (sstat[sat-1].time.time==0|| - timediff(time,sstat[sat-1].time)>MAXGAP_IONO) continue; - satno2id(sat,id); - fprintf(fp,"%s %4d %6.0f %-3s %d %8.4f %9.6f %7.4f %6.1f %5.1f %7.3f %11.3f\n", - STEC_RID,week,tow,id,sstat[sat-1].slip, - ekf->x[II(sat)],ekf->x[II(sat)+1], - sqrt(ekf->P[II(sat)*(ekf->nx+1)]),sstat[sat-1].azel[0]*R2D, - sstat[sat-1].azel[1]*R2D, sstat[sat-1].PG,sstat[sat-1].LG); - } +static void out_iono(gtime_t time, const ekf_t *ekf, const sstat_t *sstat, FILE *fp) { + double tow; + char id[8]; + int sat, week; + + tow = time2gpst(time, &week); + + for (sat = 1; sat <= MAXSAT; sat++) { + if (sstat[sat - 1].time.time == 0 || timediff(time, sstat[sat - 1].time) > MAXGAP_IONO) + continue; + satno2id(sat, id); + fprintf(fp, "%s %4d %6.0f %-3s %d %8.4f %9.6f %7.4f %6.1f %5.1f %7.3f %11.3f\n", STEC_RID, week, + tow, id, sstat[sat - 1].slip, ekf->x[II(sat)], ekf->x[II(sat) + 1], + sqrt(ekf->P[II(sat) * (ekf->nx + 1)]), sstat[sat - 1].azel[0] * R2D, + sstat[sat - 1].azel[1] * R2D, sstat[sat - 1].PG, sstat[sat - 1].LG); + } } /* estimate ionosphere -------------------------------------------------------*/ -static int est_iono(obs_t *obs, nav_t *nav, const pcv_t *pcv, double *rr, - double tint, FILE *fp) -{ - sstat_t sstat[MAXSAT]={{{0}}}; - ekf_t *ekf; - gtime_t time; - double pos[3],rs[MAXOBS*6],dts[MAXOBS*2],var[MAXOBS],e[3],azel[MAXOBS*2]; - double *v,*H,*R,phw[MAXSAT]={0}; - int i,j,n=0,info,nx=NX,nv=MAXSAT*2,svh[MAXOBS]; - - ekf=ekf_new(NX); v=mat(nv,1); H=mat(nx,nv); R=mat(nv,nv); - - /* receiver position */ - ecef2pos(rr,pos); - - out_head(obs->data[0].time,pos,fp); - - for (i=0;in;i+=n) { - for (n=1;i+nn;n++) { - if (timediff(obs->data[i+n].time,obs->data[i].time)>1E-3) break; - } - time=obs->data[i].time; - - /* satellite positions and clocks */ - satposs(time,obs->data+i,n,nav,EPHOPT_BRDC,rs,dts,var,svh); - - /* satellite azimuth/elevation angle */ - for (j=0;j0.0) satazel(pos,e,azel+j*2); - else azel[j*2]=azel[1+j*2]=0.0; - } - /* time update of parameters */ - ud_state(obs->data+i,n,nav,pos,azel,ekf,sstat); - - /* ionosphere residuals */ - if ((nv=res_iono(obs->data+i,n,nav,rs,rr,pos,azel,pcv,ekf,phw,v,H,R))<=0) { - continue; - } - /* filter */ - if ((info=filter(ekf->x,ekf->P,H,v,R,ekf->nx,nv))) { - fprintf(stderr,"filter error: info=%d\n",info); - break; - } - /* output ionopshere parameters */ - if (tint<=0.0||fmod(time2gpst(time,NULL)+0.005,tint)<0.01) { - out_iono(obs->data[i].time,ekf,sstat,fp); - } +static int est_iono(obs_t *obs, nav_t *nav, const pcv_t *pcv, double *rr, double tint, FILE *fp) { + sstat_t sstat[MAXSAT] = {{{0}}}; + ekf_t *ekf; + gtime_t time; + double pos[3], rs[MAXOBS * 6], dts[MAXOBS * 2], var[MAXOBS], e[3], azel[MAXOBS * 2]; + double *v, *H, *R, phw[MAXSAT] = {0}; + int i, j, n = 0, info, nx = NX, nv = MAXSAT * 2, svh[MAXOBS]; + + ekf = ekf_new(NX); + v = mat(nv, 1); + H = mat(nx, nv); + R = mat(nv, nv); + + /* receiver position */ + ecef2pos(rr, pos); + + out_head(obs->data[0].time, pos, fp); + + for (i = 0; i < obs->n; i += n) { + for (n = 1; i + n < obs->n; n++) { + if (timediff(obs->data[i + n].time, obs->data[i].time) > 1E-3) break; } - ekf_free(ekf); free(v); free(H); free(R); - - return 1; -} -/* main ----------------------------------------------------------------------*/ -int main(int argc, char **argv) -{ - FILE *fp=stdout; - pcvs_t pcvs={0}; - nav_t nav={0}; - obs_t obs={0}; - sta_t sta={{0}}; - pcv_t *pcv=NULL; - gtime_t ts={0},te={0}; - double eps[6]={0},epe[6]={0},rr[3]={0},tint=30.0; - char *ifile[32],*ofile="",*afile="",*dfile="",ant[64]=""; - int i,j,n=0; - - for (i=1;idata[i].time; + + /* satellite positions and clocks */ + satposs(time, obs->data + i, n, nav, EPHOPT_BRDC, rs, dts, var, svh); + + /* satellite azimuth/elevation angle */ + for (j = 0; j < n; j++) { + if (geodist(rs + j * 6, rr, e) > 0.0) + satazel(pos, e, azel + j * 2); + else + azel[j * 2] = azel[1 + j * 2] = 0.0; } - /* open output file */ - if (*ofile&&!(fp=fopen(ofile,"w"))) { - fprintf(stderr,"output file open error: %s\n",ofile); - return -1; + /* time update of parameters */ + ud_state(obs->data + i, n, nav, pos, azel, ekf, sstat); + + /* ionosphere residuals */ + if ((nv = res_iono(obs->data + i, n, nav, rs, rr, pos, azel, pcv, ekf, phw, v, H, R)) <= 0) { + continue; } - if (eps[2]>=1.0) ts=epoch2time(eps); - if (epe[2]>=1.0) te=epoch2time(epe); - - /* read rinex obs/nav */ - for (i=0;i0.0) matcpy(rr,sta.pos,3,1); + /* filter */ + if ((info = filter(ekf->x, ekf->P, H, v, R, ekf->nx, nv))) { + fprintf(stderr, "filter error: info=%d\n", info); + break; } - if (!sortobs(&obs)) { - fprintf(stderr,"no observation data\n"); - return -1; + /* output ionopshere parameters */ + if (tint <= 0.0 || fmod(time2gpst(time, NULL) + 0.005, tint) < 0.01) { + out_iono(obs->data[i].time, ekf, sstat, fp); } - uniqnav(&nav); - - /* read antenna file */ - if (*afile&&*ant) { - if (!readpcv(afile,&pcvs)) { - fprintf(stderr,"antenna file open error: %s\n",afile); - return -1; - } - /* search pcv */ - if (!(pcv=searchpcv(0,ant,obs.data[0].time,&pcvs))) { - fprintf(stderr,"no antenna parmeter: %s\n",ant); - } + } + ekf_free(ekf); + free(v); + free(H); + free(R); + + return 1; +} +/* main ----------------------------------------------------------------------*/ +int main(int argc, char **argv) { + FILE *fp = stdout; + pcvs_t pcvs = {0}; + nav_t nav = {0}; + obs_t obs = {0}; + sta_t sta = {{0}}; + pcv_t *pcv = NULL; + gtime_t ts = {0}, te = {0}; + double eps[6] = {0}, epe[6] = {0}, rr[3] = {0}, tint = 30.0; + char *ifile[32], *ofile = "", *afile = "", *dfile = "", ant[64] = ""; + int i, j, n = 0; + + for (i = 1; i < argc; i++) { + if (!strcmp(argv[i], "-ts") && i + 2 < argc) { + sscanf(argv[++i], "%lf/%lf/%lf", eps, eps + 1, eps + 2); + sscanf(argv[++i], "%lf:%lf:%lf", eps + 3, eps + 4, eps + 5); + } else if (!strcmp(argv[i], "-te") && i + 2 < argc) { + sscanf(argv[++i], "%lf/%lf/%lf", epe, epe + 1, epe + 2); + sscanf(argv[++i], "%lf:%lf:%lf", epe + 3, epe + 4, epe + 5); + } else if (!strcmp(argv[i], "-ti") && i + 1 < argc) { + tint = atof(argv[++i]); + } else if (!strcmp(argv[i], "-r") && i + 3 < argc) { + for (j = 0; j < 3; j++) rr[j] = atof(argv[++i]); + } else if (!strcmp(argv[i], "-o") && i + 1 < argc) + ofile = argv[++i]; + else if (!strcmp(argv[i], "-a") && i + 1 < argc) + afile = argv[++i]; + else if (!strcmp(argv[i], "-d") && i + 1 < argc) + dfile = argv[++i]; + else + ifile[n++] = argv[i]; + } + /* open output file */ + if (*ofile && !(fp = fopen(ofile, "w"))) { + fprintf(stderr, "output file open error: %s\n", ofile); + return -1; + } + if (eps[2] >= 1.0) ts = epoch2time(eps); + if (epe[2] >= 1.0) te = epoch2time(epe); + + /* read rinex obs/nav */ + for (i = 0; i < n; i++) { + fprintf(stderr, "reading: %s\n", ifile[i]); + + readrnxt(ifile[i], 1, ts, te, 0.0, "", &obs, &nav, &sta); + + if (*sta.antdes) strcpy(ant, sta.antdes); + if (norm(sta.pos, 3) > 0.0) matcpy(rr, sta.pos, 3, 1); + } + if (!sortobs(&obs)) { + fprintf(stderr, "no observation data\n"); + return -1; + } + uniqnav(&nav); + + /* read antenna file */ + if (*afile && *ant) { + if (!readpcv(afile, &pcvs)) { + fprintf(stderr, "antenna file open error: %s\n", afile); + return -1; + } + /* search pcv */ + if (!(pcv = searchpcv(0, ant, obs.data[0].time, &pcvs))) { + fprintf(stderr, "no antenna parmeter: %s\n", ant); } - /* read p1-c1 dcb parameters */ - if (*dfile) readdcb(dfile,&nav); - - /* set p1-p2 dcb parameters */ - for (i=0;inx=nx; - ekf->x=zeros(nx,1); - ekf->P=zeros(nx,nx); - return ekf; +static ekf_t *ekf_new(int nx) { + ekf_t *ekf; + if (!(ekf = (ekf_t *)malloc(sizeof(ekf_t)))) return NULL; + ekf->nx = nx; + ekf->x = zeros(nx, 1); + ekf->P = zeros(nx, nx); + return ekf; } /* free ekf ------------------------------------------------------------------*/ -static void ekf_free(ekf_t *ekf) -{ - if (!ekf) return; - free(ekf->x); - free(ekf->P); - free(ekf); +static void ekf_free(ekf_t *ekf) { + if (!ekf) return; + free(ekf->x); + free(ekf->P); + free(ekf); } /* mapping function of ionosphere ---------------------------------------------*/ -static double map_iono(const double *pos, const double *azel) -{ +static double map_iono(const double *pos, const double *azel) { #if RTK_DISABLED - return ionmapf(pos,azel); + return ionmapf(pos, azel); #else - return 1.0; + return 1.0; #endif } /* measurement error standard deviation --------------------------------------*/ -static double sig_err(const double *azel) -{ - return FACT_LG*(SIG_ERR_A+SIG_ERR_B/sin(azel[1])); +static double sig_err(const double *azel) { + return FACT_LG * (SIG_ERR_A + SIG_ERR_B / sin(azel[1])); } /* initialize state and covariance -------------------------------------------*/ -static void initx(double *x, double *P, int nx, int i, double xi, double var) -{ - int j; - x[i]=xi; - for (j=0;jnx); - - /* x(i)=F*x(i) */ - matmul("NN",nx,1,nx,1.0,F,ekf->x+ix,0.0,Q); - matcpy(ekf->x+ix,Q,nx,1); - - /* P(i,:)=F*P(i,:); P(:,i)=P(:,i)*F' */ - for (i=0;inx;i++) { - matmul("NN",nx,1,nx,1.0,F,ekf->P+ekf->nx*i+ix,0.0,Q); - matcpy(ekf->P+ekf->nx*i+ix,Q,nx,1); - } - matmul("NT",ekf->nx,nx,nx,1.0,ekf->P+ekf->nx*ix,F,0.0,Q); - matcpy(ekf->P+ekf->nx*ix,Q,ekf->nx,nx); - - free(Q); +static void ekf_pred(ekf_t *ekf, double *F, int ix, int nx) { + double *Q; + int i; + + Q = mat(nx, ekf->nx); + + /* x(i)=F*x(i) */ + matmul("NN", nx, 1, nx, 1.0, F, ekf->x + ix, 0.0, Q); + matcpy(ekf->x + ix, Q, nx, 1); + + /* P(i,:)=F*P(i,:); P(:,i)=P(:,i)*F' */ + for (i = 0; i < ekf->nx; i++) { + matmul("NN", nx, 1, nx, 1.0, F, ekf->P + ekf->nx * i + ix, 0.0, Q); + matcpy(ekf->P + ekf->nx * i + ix, Q, nx, 1); + } + matmul("NT", ekf->nx, nx, nx, 1.0, ekf->P + ekf->nx * ix, F, 0.0, Q); + matcpy(ekf->P + ekf->nx * ix, Q, ekf->nx, nx); + + free(Q); } /* temporal update of states --------------------------------------------------*/ -static void ud_state(const obsd_t *obs, int n, const nav_t *nav, - const double *pos, const double *azel, ekf_t *ekf, - sstat_t *sstat) -{ - double P1,P2,L1,L2,PG,LG,tt,F[4]={0}; - double iono,m_iono,c_iono=1.0-SQR(lam[1]/lam[0]); - int i,j,k,sat,slip; - - for (i=0;iTHRES_LG; - - j=II(sat); k=IB(sat); - - if (fabs(tt)>MAXGAP_IONO) { - m_iono=map_iono(pos,azel+i*2); +static void ud_state(const obsd_t *obs, int n, const nav_t *nav, const double *pos, + const double *azel, ekf_t *ekf, sstat_t *sstat) { + double P1, P2, L1, L2, PG, LG, tt, F[4] = {0}; + double iono, m_iono, c_iono = 1.0 - SQR(lam[1] / lam[0]); + int i, j, k, sat, slip; + + for (i = 0; i < n; i++) { + P1 = obs[i].P[0]; + L1 = obs[i].L[0] * lam[0]; + P2 = obs[i].P[1]; + L2 = obs[i].L[1] * lam[1]; + if (L1 == 0.0 || L2 == 0.0 || P1 == 0.0 || P2 == 0.0 || azel[i * 2 + 1] < MIN_EL) continue; + + sat = obs[i].sat; + tt = timediff(obs[i].time, sstat[sat - 1].time); + LG = L1 - L2; + PG = P1 - P2; + slip = (obs[i].LLI[0] & 3) || (obs[i].LLI[1] & 3); + slip |= fabs(LG - sstat[sat - 1].LG) > THRES_LG; + + j = II(sat); + k = IB(sat); + + if (fabs(tt) > MAXGAP_IONO) { + m_iono = map_iono(pos, azel + i * 2); #if 1 - iono=PG/c_iono/m_iono; + iono = PG / c_iono / m_iono; #else - iono=ionmodel(obs[i].time,nav->ion_gps,pos,azel+i*2); + iono = ionmodel(obs[i].time, nav->ion_gps, pos, azel + i * 2); #endif - initx(ekf->x,ekf->P,ekf->nx,j,iono,VAR_IONO); - initx(ekf->x,ekf->P,ekf->nx,j+1,0.0,VAR_IONR); - } - else { + initx(ekf->x, ekf->P, ekf->nx, j, iono, VAR_IONO); + initx(ekf->x, ekf->P, ekf->nx, j + 1, 0.0, VAR_IONR); + } else { #if 1 - F[0]=F[3]=1.0; F[2]=tt; - ekf_pred(ekf,F,j,2); + F[0] = F[3] = 1.0; + F[2] = tt; + ekf_pred(ekf, F, j, 2); #else - ekf->P[ j *(ekf->nx+1)]+=PRN_IONO*fabs(tt); + ekf->P[j * (ekf->nx + 1)] += PRN_IONO * fabs(tt); #endif - ekf->P[(j+1)*(ekf->nx+1)]+=PRN_IONR*fabs(tt); - } - if (tt>MAXGAP_BIAS||slip) { - initx(ekf->x,ekf->P,ekf->nx,k,LG+PG,VAR_BIAS); - } - sstat[sat-1].time=obs[i].time; - sstat[sat-1].azel[0]=azel[i*2]; - sstat[sat-1].azel[1]=azel[i*2+1]; - sstat[sat-1].LG=LG; - sstat[sat-1].PG=PG; + ekf->P[(j + 1) * (ekf->nx + 1)] += PRN_IONR * fabs(tt); + } + if (tt > MAXGAP_BIAS || slip) { + initx(ekf->x, ekf->P, ekf->nx, k, LG + PG, VAR_BIAS); } + sstat[sat - 1].time = obs[i].time; + sstat[sat - 1].azel[0] = azel[i * 2]; + sstat[sat - 1].azel[1] = azel[i * 2 + 1]; + sstat[sat - 1].LG = LG; + sstat[sat - 1].PG = PG; + } } /* ionosphere residuals ------------------------------------------------------*/ -static int res_iono(const obsd_t *obs, int n, const nav_t *nav, - const double *rs, const double *rr, const double *pos, - const double *azel, const pcv_t *pcv, const ekf_t *ekf, - double *phw, double *v, double *H, double *R) -{ - double *sig,P1,P2,L1,L2,m_iono,c_iono=1.0-SQR(lam[1]/lam[0]); - double LG,PG,antdel[3]={0},dant[NFREQ]={0}; - int i,j,nv=0,sat; - - sig=mat(1,2*n); - - for (i=0;ix[II(sat)]+ekf->x[IB(sat)]; - PG= c_iono*m_iono*ekf->x[II(sat)]; - - /* receiver antenna phase center offset and variation */ - if (pcv) { - antmodel(pcv,antdel,azel+i*2,dant); - LG+=dant[0]-dant[1]; - PG+=dant[0]-dant[1]; - } - /* phase windup correction */ - windupcorr(obs[i].time,rs+i*6,rr,phw+obs[i].sat-1); - LG+=(lam[0]-lam[1])*phw[obs[i].sat-1]; - - /* C1->P1 DCB correction */ - if (obs[i].code[0]==CODE_L1C) P1+=nav->cbias[obs[i].sat-1][1]; - - /* residuals of ionosphere (geometriy-free) LC */ - v[nv ]=(L1-L2)-LG; +static int res_iono(const obsd_t *obs, int n, const nav_t *nav, const double *rs, const double *rr, + const double *pos, const double *azel, const pcv_t *pcv, const ekf_t *ekf, + double *phw, double *v, double *H, double *R) { + double *sig, P1, P2, L1, L2, m_iono, c_iono = 1.0 - SQR(lam[1] / lam[0]); + double LG, PG, antdel[3] = {0}, dant[NFREQ] = {0}; + int i, j, nv = 0, sat; + + sig = mat(1, 2 * n); + + for (i = 0; i < n; i++) { + P1 = obs[i].P[0]; + L1 = obs[i].L[0] * lam[0]; + P2 = obs[i].P[1]; + L2 = obs[i].L[1] * lam[1]; + if (P1 == 0.0 || P2 == 0.0 || L1 == 0.0 || L2 == 0.0 || azel[1 + i * 2] < MIN_EL) continue; + sat = obs[i].sat; + + /* ionosphere mapping function */ + m_iono = map_iono(pos, azel + i * 2); + + /* ionosphere-LC model */ + LG = -c_iono * m_iono * ekf->x[II(sat)] + ekf->x[IB(sat)]; + PG = c_iono * m_iono * ekf->x[II(sat)]; + + /* receiver antenna phase center offset and variation */ + if (pcv) { + antmodel(pcv, antdel, azel + i * 2, dant); + LG += dant[0] - dant[1]; + PG += dant[0] - dant[1]; + } + /* phase windup correction */ + windupcorr(obs[i].time, rs + i * 6, rr, phw + obs[i].sat - 1); + LG += (lam[0] - lam[1]) * phw[obs[i].sat - 1]; + + /* C1->P1 DCB correction */ + if (obs[i].code[0] == CODE_L1C) P1 += nav->cbias[obs[i].sat - 1][1]; + + /* residuals of ionosphere (geometriy-free) LC */ + v[nv] = (L1 - L2) - LG; #if RTK_DISABLED - v[nv+1]=(P1-P2)-PG; + v[nv + 1] = (P1 - P2) - PG; #else - v[nv+1]=0.0; + v[nv + 1] = 0.0; #endif - for (j=0;jnx*2;j++) H[ekf->nx*nv+j]=0.0; - H[ekf->nx*nv +II(sat)]=-c_iono*m_iono; - H[ekf->nx*nv +IB(sat)]=1.0; - H[ekf->nx*(nv+1)+II(sat)]=c_iono*m_iono; - - sig[nv ]=sig_err(azel+i*2); - sig[nv+1]=RATIO_ERR*sig[nv]; - nv+=2; - } - for (i=0;inx * 2; j++) H[ekf->nx * nv + j] = 0.0; + H[ekf->nx * nv + II(sat)] = -c_iono * m_iono; + H[ekf->nx * nv + IB(sat)] = 1.0; + H[ekf->nx * (nv + 1) + II(sat)] = c_iono * m_iono; + + sig[nv] = sig_err(azel + i * 2); + sig[nv + 1] = RATIO_ERR * sig[nv]; + nv += 2; + } + for (i = 0; i < nv; i++) + for (j = 0; j < nv; j++) { + R[i + j * nv] = i == j ? SQR(sig[i]) : 0.0; } - free(sig); - return nv; + free(sig); + return nv; } /* output ionosphere parameters ----------------------------------------------*/ -static void out_iono(gtime_t time, const ekf_t *ekf, const sstat_t *sstat, - const double *pos, FILE *fp) -{ - double tow; - char id[8]; - int sat,week; - - tow=time2gpst(time,&week); - - for (sat=1;sat<=MAXSAT;sat++) { - if (sstat[sat-1].time.time==0|| - timediff(time,sstat[sat-1].time)>MAXGAP_IONO) continue; - satno2id(sat,id); - fprintf(fp,"%s %4d %5.0f %-3s %7.3f %8.3f %8.4f %7.4f %6.1f %5.1f %7.3f %11.3f\n", - STEC_RID,week,tow,id,pos[0]*R2D,pos[1]*R2D,ekf->x[II(sat)], - sqrt(ekf->P[II(sat)*(ekf->nx+1)]),sstat[sat-1].azel[0]*R2D, - sstat[sat-1].azel[1]*R2D, sstat[sat-1].PG,sstat[sat-1].LG); - } +static void out_iono(gtime_t time, const ekf_t *ekf, const sstat_t *sstat, const double *pos, + FILE *fp) { + double tow; + char id[8]; + int sat, week; + + tow = time2gpst(time, &week); + + for (sat = 1; sat <= MAXSAT; sat++) { + if (sstat[sat - 1].time.time == 0 || timediff(time, sstat[sat - 1].time) > MAXGAP_IONO) + continue; + satno2id(sat, id); + fprintf(fp, "%s %4d %5.0f %-3s %7.3f %8.3f %8.4f %7.4f %6.1f %5.1f %7.3f %11.3f\n", STEC_RID, + week, tow, id, pos[0] * R2D, pos[1] * R2D, ekf->x[II(sat)], + sqrt(ekf->P[II(sat) * (ekf->nx + 1)]), sstat[sat - 1].azel[0] * R2D, + sstat[sat - 1].azel[1] * R2D, sstat[sat - 1].PG, sstat[sat - 1].LG); + } } /* estimate receiver dcb -----------------------------------------------------*/ -static int est_iono(obs_t *obs, nav_t *nav, double *rr, FILE *fp) -{ - sstat_t sstat[MAXSAT]={{{0}}}; - ekf_t *ekf; - gtime_t time; - double r,pos[3],rs[MAXOBS*6],dts[MAXOBS*2],var[MAXOBS],e[3],azel[2]; - int i,j,n=0,info,nx=NX,nv=MAXSAT*2,svh[MAXOBS]; - - ekf=ekf_new(NX); v=mat(nv,1); H=mat(nx,nv); R=mat(nv,nv); - - /* receiver position */ - ecef2pos(rr,pos); - - for (i=0;in;i+=n) { - for (n=1;i+nn;n++) { - if (timediff(obs->data[i+n].time,obs->data[i].time)>1E-3) break; - } - time=obs->data[i].time; - - /* satellite positions and clocks */ - satposs(time,obs->data+i,n,nav,EPHOPT_BRDC,rs,dts,var,svh); - - /* satellite azimuth/elevation angle */ - for (j=0;jn; i += n) { + for (n = 1; i + n < obs->n; n++) { + if (timediff(obs->data[i + n].time, obs->data[i].time) > 1E-3) break; } - return 1; + time = obs->data[i].time; + + /* satellite positions and clocks */ + satposs(time, obs->data + i, n, nav, EPHOPT_BRDC, rs, dts, var, svh); + + /* satellite azimuth/elevation angle */ + for (j = 0; j < n; j++) { + if ((r = geodist(rs + j * 6, rr, e)) <= 0.0) continue; + satazel(pos, e, azel); + + azel[j * 2] = azel[1 + j * 2] = 0.0; + } + } + return 1; } /* main ----------------------------------------------------------------------*/ -int main(int argc, char **argv) -{ - FILE *fp=stdout; - nav_t nav={0}; - obs_t obs={0}; - sta_t sta={{0}}; - gtime_t ts={0},te={0}; - double eps[6]={0},epe[6]={0},rr[3]={0},tint=30.0; - char *rfile[32],*ifile=""; - int i,j,n=0; - - for (i=1;i=1.0) ts=epoch2time(eps); - if (epe[2]>=1.0) te=epoch2time(epe); - - /* read rinex obs/nav */ - for (i=0;i0.0) matcpy(rr,sta.pos,3,1); - } - if (!sortobs(&obs)) { - fprintf(stderr,"no observation data\n"); - return -1; - } - uniqnav(&nav); - - /* read ionex file */ - if (*ifile) readionex(ifile,&nav); - - /* estimate receiver dcb */ - est_rcvdcb(&obs,&nav,rr,fp); - - fclose(fp); - - return 0; +int main(int argc, char **argv) { + FILE *fp = stdout; + nav_t nav = {0}; + obs_t obs = {0}; + sta_t sta = {{0}}; + gtime_t ts = {0}, te = {0}; + double eps[6] = {0}, epe[6] = {0}, rr[3] = {0}, tint = 30.0; + char *rfile[32], *ifile = ""; + int i, j, n = 0; + + for (i = 1; i < argc; i++) { + if (!strcmp(argv[i], "-ts") && i + 2 < argc) { + sscanf(argv[++i], "%lf/%lf/%lf", eps, eps + 1, eps + 2); + sscanf(argv[++i], "%lf:%lf:%lf", eps + 3, eps + 4, eps + 5); + } else if (!strcmp(argv[i], "-te") && i + 2 < argc) { + sscanf(argv[++i], "%lf/%lf/%lf", epe, epe + 1, epe + 2); + sscanf(argv[++i], "%lf:%lf:%lf", epe + 3, epe + 4, epe + 5); + } else if (!strcmp(argv[i], "-ti") && i + 1 < argc) { + tint = atof(argv[++i]); + } else if (!strcmp(argv[i], "-r") && i + 3 < argc) { + for (j = 0; j < 3; j++) rr[j] = atof(argv[++i]); + } else if (!strcmp(argv[i], "-i") && i + 1 < argc) + ifile = argv[++i]; + else + rfile[n++] = argv[i]; + } + if (eps[2] >= 1.0) ts = epoch2time(eps); + if (epe[2] >= 1.0) te = epoch2time(epe); + + /* read rinex obs/nav */ + for (i = 0; i < n; i++) { + fprintf(stderr, "reading ... %s\n", rfile[i]); + + readrnxt(rfile[i], 1, ts, te, 0.0, &obs, &nav, &sta); + + if (norm(sta.pos, 3) > 0.0) matcpy(rr, sta.pos, 3, 1); + } + if (!sortobs(&obs)) { + fprintf(stderr, "no observation data\n"); + return -1; + } + uniqnav(&nav); + + /* read ionex file */ + if (*ifile) readionex(ifile, &nav); + + /* estimate receiver dcb */ + est_rcvdcb(&obs, &nav, rr, fp); + + fclose(fp); + + return 0; } diff --git a/util/logfile/margelog.c b/util/logfile/margelog.c index e7b45e632..8435424af 100644 --- a/util/logfile/margelog.c +++ b/util/logfile/margelog.c @@ -1,66 +1,68 @@ /*----------------------------------------------------------------------------- -* marge log and tag files -*-----------------------------------------------------------------------------*/ + * marge log and tag files + *-----------------------------------------------------------------------------*/ #include + #include "rtklib.h" -#define HEADLEN 76 +#define HEADLEN 76 /* main ----------------------------------------------------------------------*/ -int main(int argc, int argv) -{ - FILE *ifp,*itagfp,*ofp,*otagfp; - gtime_t time0; - char ifiles[32]={},*ofile=""; - char itagfile[1024],otagfile[1024]; - int i,n=0; - uint32_t tick0,tick1,tick,fpos; - uint8_t buff[4096],tagbuff[64]; - - for (i=0;i0:on) [0]", -"" -}; +static const char *help[] = { + "", + " Synopsis", + "", + " simobs [option ...] file", + "", + " Description", + "", + " Read RINEX OBS/NAV/CLK and SP3 files and simulate GNSS pseudorange, ", + " carrier-phase and C/N0 measurements for a given receiver position.", + " The output will be written to a RINEX OBS file.", + "", + " Options (units) [default]", + "", + " -? print help", + " -n file RINEX NAV input file", + " -s file SP3 input file", + " -c file Clock-RINEX input file", + " -e file ERP input file", + " -o file RINEX OBS output file", + " -v ver RINEX OBS version [3.05]", + " -ts ds ts start date/time (ds=y/m/d ts=h:m:s)", + " -te de te end date/time (de=y/m/d te=h:m:s)", + " -ti tint time interval (sec) [30]", + " -hc comment rinex header: comment line", + " -hm marker rinex header: marker name", + " -hn markno rinex header: marker number", + " -ht marktype rinex header: marker type", + " -ho observ rinex header: observer name and agency separated by /", + " -hr rec rinex header: receiver number, type and version separated by /", + " -ha ant rinex header: antenna number and type separated by /", + " -hd delta rinex header: antenna delta h/e/n separated by / (m)", + " -r x y z receiver ecef position (m)", + " -l lat lon hgt receiver latitude/longitude/height (deg/m)", + " --mask [sig[,...]] signal mask(s) (sig={G|R|E|J|S|C|I}L{1C|1P|1W|...})", + " --noise use observation noise", + " --tropo use tropospheric delay", + " --iono use ionospheric delay (requires -n)", + " --tides use solid tides and pole tides (requires -e)", + " -x level debug trace level (0:off,>0:on) [0]", + ""}; /* print help ----------------------------------------------------------------*/ -static void printhelp(void) -{ - int i; - for (i=0;i<(int)(sizeof(help)/sizeof(*help));i++) fprintf(stderr,"%s\n",help[i]); - exit(0); +static void printhelp(void) { + int i; + for (i = 0; i < (int)(sizeof(help) / sizeof(*help)); i++) fprintf(stderr, "%s\n", help[i]); + exit(0); }; /* processing options --------------------------------------------------------*/ -typedef struct { /* processing options type */ - gtime_t ts; - gtime_t te; - double tint; - double rr[3]; - int navsys; /* navigation system */ - int noise; /* Measurement noise (0:off,1:on) */ - int ionoopt; /* ionosphere option (0:off,1:on) */ - int tropopt; /* troposphere option (0:off,1:on) */ - int nf; /* number of frequencies (1:L1,2:L1+L2,3:L1+L2+L5) */ - double elmin; /* elevation mask angle (rad) */ - int sateph; /* satellite ephemeris/clock (EPHOPT_???) */ - int tidecorr; /* earth tide correction (0:off,1:solid,5:solid+pole,7:solid+pole+otl) */ - double antdel[3]; /* antenna delta {d_e,d_n,d_u} */ - double odisp[6*11]; /* ocean tide loading parameters */ - int trace; /* trace output for debugging */ +typedef struct { /* processing options type */ + gtime_t ts; + gtime_t te; + double tint; + double rr[3]; + int navsys; /* navigation system */ + int noise; /* Measurement noise (0:off,1:on) */ + int ionoopt; /* ionosphere option (0:off,1:on) */ + int tropopt; /* troposphere option (0:off,1:on) */ + int nf; /* number of frequencies (1:L1,2:L1+L2,3:L1+L2+L5) */ + double elmin; /* elevation mask angle (rad) */ + int sateph; /* satellite ephemeris/clock (EPHOPT_???) */ + int tidecorr; /* earth tide correction (0:off,1:solid,5:solid+pole,7:solid+pole+otl) */ + double antdel[3]; /* antenna delta {d_e,d_n,d_u} */ + double odisp[6 * 11]; /* ocean tide loading parameters */ + int trace; /* trace output for debugging */ } simopt_t; /* generate random number with normal distribution ---------------------------*/ -static double randn(double myu, double sig) -{ - double a,b; - a=((double)rand()+1.0)/((double)RAND_MAX+1.0); /* 0=dst&&*p==' ') *p--='\0'; +static void setstr(char *dst, const char *src, int n) { + char *p = dst; + const char *q = src; + while (*q && q < src + n) *p++ = *q++; + *p-- = '\0'; + while (p >= dst && *p == ' ') *p-- = '\0'; }; /* set signal mask -----------------------------------------------------------*/ -static void setmask(const char *argv, rnxopt_t *opt, int mask) -{ - char buff[1024],*p; - int i,code; - - strcpy(buff,argv); - for (p=strtok(buff,",");p;p=strtok(NULL,",")) { - if (strlen(p)<4||p[1]!='L') continue; - if (p[0]=='G') { i=0; opt->navsys|=SYS_GPS; } - else if (p[0]=='R') { i=1; opt->navsys|=SYS_GLO; } - else if (p[0]=='E') { i=2; opt->navsys|=SYS_GAL; } - else if (p[0]=='J') { i=3; opt->navsys|=SYS_QZS; } - else if (p[0]=='S') { i=4; opt->navsys|=SYS_CMP; } - else if (p[0]=='C') { i=5; opt->navsys|=SYS_IRN; } - else if (p[0]=='I') { i=6; opt->navsys|=SYS_SBS; } - else continue; - if ((code=obs2code(p+2))) { - opt->mask[i][code-1]=mask?'1':'0'; +static void setmask(const char *argv, rnxopt_t *opt, int mask) { + char buff[1024], *p; + int i, code; + + strcpy(buff, argv); + for (p = strtok(buff, ","); p; p = strtok(NULL, ",")) { + if (strlen(p) < 4 || p[1] != 'L') continue; + if (p[0] == 'G') { + i = 0; + opt->navsys |= SYS_GPS; + } else if (p[0] == 'R') { + i = 1; + opt->navsys |= SYS_GLO; + } else if (p[0] == 'E') { + i = 2; + opt->navsys |= SYS_GAL; + } else if (p[0] == 'J') { + i = 3; + opt->navsys |= SYS_QZS; + } else if (p[0] == 'S') { + i = 4; + opt->navsys |= SYS_CMP; + } else if (p[0] == 'C') { + i = 5; + opt->navsys |= SYS_IRN; + } else if (p[0] == 'I') { + i = 6; + opt->navsys |= SYS_SBS; + } else + continue; + if ((code = obs2code(p + 2))) { + opt->mask[i][code - 1] = mask ? '1' : '0'; }; }; }; @@ -134,209 +144,201 @@ static void setmask(const char *argv, rnxopt_t *opt, int mask) * GPS,GLO,GAL,QZS,SBS,CMP,IRN */ static int sys2idx(int sys) { - switch(sys) { - case(SYS_GPS): return 0; - case(SYS_GLO): return 1; - case(SYS_GAL): return 2; - case(SYS_QZS): return 3; - case(SYS_SBS): return 4; - case(SYS_CMP): return 5; - case(SYS_IRN): return 6; - default : return -1; + switch (sys) { + case (SYS_GPS): + return 0; + case (SYS_GLO): + return 1; + case (SYS_GAL): + return 2; + case (SYS_QZS): + return 3; + case (SYS_SBS): + return 4; + case (SYS_CMP): + return 5; + case (SYS_IRN): + return 6; + default: + return -1; }; }; /* generate snr --------------------------------------------------------------*/ -static double snrmodel(const double *azel, uint8_t code) -{ +static double snrmodel(const double *azel, uint8_t code) { /* snr and snr deviation pattern (db-Hz) by elevation (5 deg interval) */ - double snrs[]={40,42,44,45,46,47,48,49,49,50,50,51,51,51,51,51,51,51,51}; - double sdvs[]={ 3, 3, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}; + double snrs[] = {40, 42, 44, 45, 46, 47, 48, 49, 49, 50, 50, 51, 51, 51, 51, 51, 51, 51, 51}; + double sdvs[] = {3, 3, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}; int j; - j=(int)(azel[1]*R2D/5.0); - return snrs[j] + randn(0.0,sdvs[j]) - (code==CODE_L1W||code==CODE_L2W? 10: 0); + j = (int)(azel[1] * R2D / 5.0); + return snrs[j] + randn(0.0, sdvs[j]) - (code == CODE_L1W || code == CODE_L2W ? 10 : 0); }; /* generate errors------------------------------------------------------------*/ -static void errmodel(const double *azel, double *ecp, double *epr) -{ - ecp[0]=randn(0.0,errcp1)+randn(0.0,errcp2)/sin(azel[1]); - epr[0]=randn(0.0,errpr1)+randn(0.0,errpr2)/sin(azel[1]); +static void errmodel(const double *azel, double *ecp, double *epr) { + ecp[0] = randn(0.0, errcp1) + randn(0.0, errcp2) / sin(azel[1]); + epr[0] = randn(0.0, errpr1) + randn(0.0, errpr2) / sin(azel[1]); }; /* generate simulated observation data ---------------------------------------*/ static int simobs(simopt_t simopt, rnxopt_t rnxopt, nav_t *nav, obs_t *obs) { - - gtime_t time; - obsd_t data[MAXSAT]={0}; - double pos[3],rr[3],dr[3],rs[6],dts[2],r,e[3],azel[2]; - double var; - int svh; - double snr; - double iono,trop,fact,cp,pr,dtr=0.0; - double epr,ecp; - int i,j,k,n,m,ns,sys,prn; - int iSys; - char s[40]; - double f0,fk; - - trace(3,"simobs:nnav=%d ngnav=%d\n",nav->n,nav->ng); - - for (j=0; jn, nav->ng); + + for (j = 0; j < MAXSAT; j++) { + data[j].sat = j + 1; data[j].P[0] = 0.0; data[j].code[0] = CODE_NONE; }; /* Loop over measurement epochs */ - n = (int)(timediff(simopt.te,simopt.ts)/simopt.tint+1.0); - for (i=0;i0) { - dr[0]=dr[1]=dr[2]=0.0; - tidedisp(gpst2utc(time),simopt.rr,simopt.tidecorr,&nav->erp, - simopt.odisp,dr); - for (k=0;k<3;k++) rr[k] += dr[k]; + if (simopt.tidecorr > 0) { + dr[0] = dr[1] = dr[2] = 0.0; + tidedisp(gpst2utc(time), simopt.rr, simopt.tidecorr, &nav->erp, simopt.odisp, dr); + for (k = 0; k < 3; k++) rr[k] += dr[k]; }; /* Station position */ - ecef2pos(rr,pos); + ecef2pos(rr, pos); /* Apply antenna delta */ - dr[0]=dr[1]=dr[2]=0.0; + dr[0] = dr[1] = dr[2] = 0.0; enu2ecef(pos, simopt.antdel, dr); - for (k=0;k<3;k++) rr[k] += dr[k]; + for (k = 0; k < 3; k++) rr[k] += dr[k]; /* reset number of satellites */ ns = 0; /* loop over satellites */ - for (j=0;jion_gps,pos,azel); + iono = ionmodel(data[j].time, nav->ion_gps, pos, azel); /* Compute tropospheric delay */ - trop = tropmodel(data[j].time,pos,azel,0.3); + trop = tropmodel(data[j].time, pos, azel, 0.3); /* GNSS and system index */ - sys = satsys(data[j].sat,&prn); + sys = satsys(data[j].sat, &prn); iSys = sys2idx(sys); - if (iSys<0 || rnxopt.nobs[iSys]==0) continue; + if (iSys < 0 || rnxopt.nobs[iSys] == 0) continue; m = 0; - for (k=0;k0? fact*iono : 0.0) \ - +(simopt.tropopt>0? trop : 0.0) \ - +(simopt.noise>0? epr : 0.0); - pr = r + CLIGHT*(dtr - dts[0]) \ - +(simopt.ionoopt>0? fact*iono : 0.0) \ - +(simopt.tropopt>0? trop : 0.0) \ - +(simopt.noise>0? ecp : 0.0); - snr = snrmodel(azel,data[j].code[m]); - - data[j].L[m] = cp/CLIGHT*fk; - data[j].P[m] = pr; + cp = r + CLIGHT * (dtr - dts[0]) - (simopt.ionoopt > 0 ? fact * iono : 0.0) + + (simopt.tropopt > 0 ? trop : 0.0) + (simopt.noise > 0 ? epr : 0.0); + pr = r + CLIGHT * (dtr - dts[0]) + (simopt.ionoopt > 0 ? fact * iono : 0.0) + + (simopt.tropopt > 0 ? trop : 0.0) + (simopt.noise > 0 ? ecp : 0.0); + snr = snrmodel(azel, data[j].code[m]); + + data[j].L[m] = cp / CLIGHT * fk; + data[j].P[m] = pr; data[j].SNR[m] = snr; data[j].LLI[m] = 0; /* (data[j].SNR[m]nmax<=obs->n) { - - if (obs->nmax==0) obs->nmax=65532; else obs->nmax+=65532; - if (!(obs->data=(obsd_t *)realloc(obs->data,sizeof(obsd_t)*obs->nmax))) { - fprintf(stderr,"malloc error\n"); + if (obs->nmax <= obs->n) { + if (obs->nmax == 0) + obs->nmax = 65532; + else + obs->nmax += 65532; + if (!(obs->data = (obsd_t *)realloc(obs->data, sizeof(obsd_t) * obs->nmax))) { + fprintf(stderr, "malloc error\n"); return 0; }; - }; - obs->data[obs->n++]=data[j]; + obs->data[obs->n++] = data[j]; ns++; - }; - fprintf(stdout,"time=%s nsat=%2d\r",s,ns); + fprintf(stdout, "time=%s nsat=%2d\r", s, ns); }; - fprintf(stdout,"\n"); + fprintf(stdout, "\n"); return 1; - }; /* simobs main ---------------------------------------------------------------*/ int main(int argc, char **argv) { - - FILE *fp; - rnxopt_t rnxopt={{0}}; - simopt_t simopt={{0}}; - obs_t obs={0}; - nav_t nav={0}; - sta_t sta={0}; - double es[]={2000,1,1,0,0,0}; - double ee[]={2000,1,1,0,0,0}; - double pos[3]={0}; - char *navFileName[16]={0}; - char *sp3FileName[16]={0}; - char *clkFileName[16]={0}; - char *erpFileName={0}; - char *outfile=""; - char *p,buff[256]; - int i,j,k,nc=0; - int nNav=0,nSp3=0,nClk=0,nErp=0; + FILE *fp; + rnxopt_t rnxopt = {{0}}; + simopt_t simopt = {{0}}; + obs_t obs = {0}; + nav_t nav = {0}; + sta_t sta = {0}; + double es[] = {2000, 1, 1, 0, 0, 0}; + double ee[] = {2000, 1, 1, 0, 0, 0}; + double pos[3] = {0}; + char *navFileName[16] = {0}; + char *sp3FileName[16] = {0}; + char *clkFileName[16] = {0}; + char *erpFileName = {0}; + char *outfile = ""; + char *p, buff[256]; + int i, j, k, nc = 0; + int nNav = 0, nSp3 = 0, nClk = 0, nErp = 0; /* Default simulation options */ - simopt.noise = 0; - simopt.tropopt = 0; - simopt.ionoopt = 0; + simopt.noise = 0; + simopt.tropopt = 0; + simopt.ionoopt = 0; simopt.tidecorr = 0; - simopt.trace = 0; + simopt.trace = 0; simopt.tint = 30.0; simopt.antdel[0] = 0.0; @@ -345,9 +347,9 @@ int main(int argc, char **argv) { /* Default RINEX options */ rnxopt.rnxver = 305; - strcpy(rnxopt.comment[0],"SIMULATED OBS DATA"); - strcpy(rnxopt.rec[1],"UNKNOWN"); - strcpy(rnxopt.ant[1],"UNKNOWN NONE"); + strcpy(rnxopt.comment[0], "SIMULATED OBS DATA"); + strcpy(rnxopt.rec[1], "UNKNOWN"); + strcpy(rnxopt.ant[1], "UNKNOWN NONE"); rnxopt.antdel[0] = 0.0; rnxopt.antdel[1] = 0.0; rnxopt.antdel[2] = 0.0; @@ -357,291 +359,259 @@ int main(int argc, char **argv) { /* Process command line arguments */ - for (i=1;i0) { + /* Debugging output level */ + if (simopt.trace > 0) { traceopen("simobs_tracelog.txt"); tracelevel(simopt.trace); }; /* Check required inputs */ if (!*outfile) { - fprintf(stderr,"no output file\n"); + fprintf(stderr, "no output file\n"); return -1; }; - if (norm(pos,3)<=0.0) { - fprintf(stderr,"no receiver pos\n"); + if (norm(pos, 3) <= 0.0) { + fprintf(stderr, "no receiver pos\n"); return -1; }; - if (simopt.ionoopt>0 && nNav==0) { - fprintf(stderr,"ERROR: require RINEX-NAV file for iono delay modeling!\n"); + if (simopt.ionoopt > 0 && nNav == 0) { + fprintf(stderr, "ERROR: require RINEX-NAV file for iono delay modeling!\n"); return -1; }; /* Default navigation systems */ if (!rnxopt.navsys) { - rnxopt.navsys = SYS_GPS|SYS_GAL; + rnxopt.navsys = SYS_GPS | SYS_GAL; }; /* read RINEX-NAV files */ - if (nNav>0) { - for (i=0;i 0) { + for (i = 0; i < nNav; i++) { + fprintf(stdout, "Reading %s\n", navFileName[i]); + readrnx(navFileName[i], 0, "", &obs, &nav, &sta); }; - if (nav.n<=0) { - fprintf(stderr,"no BRDC data\n"); + if (nav.n <= 0) { + fprintf(stderr, "no BRDC data\n"); return -1; }; }; /* read precise ephemeris files */ - if (nSp3>0) { - for (i=0;i 0) { + for (i = 0; i < nSp3; i++) { + fprintf(stdout, "Reading %s\n", sp3FileName[i]); + readsp3(sp3FileName[i], &nav, 0); }; - if (nav.ne<=0) { - fprintf(stderr,"no SP3 data\n"); + if (nav.ne <= 0) { + fprintf(stderr, "no SP3 data\n"); return -1; }; }; /* read precise Clock-RINEX files */ - if (nClk>0) { - for (i=0;i 0) { + for (i = 0; i < nClk; i++) { + fprintf(stdout, "Reading %s\n", clkFileName[i]); + readrnxc(clkFileName[i], &nav); }; - if (nav.nc<=0) { - fprintf(stderr,"no Clk-RINEX data\n"); + if (nav.nc <= 0) { + fprintf(stderr, "no Clk-RINEX data\n"); return -1; }; }; /* read ERP data */ - if (nErp>0) { - fprintf(stdout,"Reading %s\n",erpFileName); - if (!readerp(erpFileName,&nav.erp)) { - fprintf(stdout,"ERROR: cannot read ERP file %s\n",erpFileName); + if (nErp > 0) { + fprintf(stdout, "Reading %s\n", erpFileName); + if (!readerp(erpFileName, &nav.erp)) { + fprintf(stdout, "ERROR: cannot read ERP file %s\n", erpFileName); return -1; }; }; /* RINEX OBS file options */ - strcpy(rnxopt.prog,PROGNAME); - rnxopt.tstart = simopt.ts; - rnxopt.tend = simopt.te; - rnxopt.tint = simopt.tint; - rnxopt.obstype = OBSTYPE_PR|OBSTYPE_CP|OBSTYPE_SNR; - for (i=0;i<3;i++) { + strcpy(rnxopt.prog, PROGNAME); + rnxopt.tstart = simopt.ts; + rnxopt.tend = simopt.te; + rnxopt.tint = simopt.tint; + rnxopt.obstype = OBSTYPE_PR | OBSTYPE_CP | OBSTYPE_SNR; + for (i = 0; i < 3; i++) { rnxopt.apppos[i] = simopt.rr[i]; }; - char obst[4]; - int iSys,iObs; - int nSys,nObs; + char obst[4]; + int iSys, iObs; + int nSys, nObs; nObs = 64; nSys = 7; - for (iSys=0;iSys0.001) break; + for (i = 0; i < obs.n; i = j) { + for (j = i; j < obs.n; j++) { + if (timediff(obs.data[j].time, obs.data[i].time) > 0.001) break; } - outrnxobsb(fp,&rnxopt,obs.data+i,j-i,0); + outrnxobsb(fp, &rnxopt, obs.data + i, j - i, 0); }; fclose(fp); return 0; - }; diff --git a/util/testeph/diffeph.c b/util/testeph/diffeph.c index 58545f043..5de583a74 100644 --- a/util/testeph/diffeph.c +++ b/util/testeph/diffeph.c @@ -1,237 +1,231 @@ /*------------------------------------------------------------------------------ -* diffeph.c : output difference between ephemerides -* -* history : 2010/06/17 0.1 new -* 2011/09/17 0.2 add comparison of 2 precise ephemeris -*-----------------------------------------------------------------------------*/ + * diffeph.c : output difference between ephemerides + * + * history : 2010/06/17 0.1 new + * 2011/09/17 0.2 add comparison of 2 precise ephemeris + *-----------------------------------------------------------------------------*/ #include + #include "rtklib.h" -static const char *usage[]={ -"Synopsis", -" diffeph [-t0 y/m/d h:m:s][-ts ts][-ti ti][-s s][-1 r][-2 b][-t]", -" [-o][-u lat lon][-x level] file ...", -"", -"Description", -"compute ephemeris and clock error and output errors.", -"", -"Options [default]", -"-t0 y/m/d h:m:s start time expressed in gpst", -"-ts ts time span (hr) [24]", -"-ti ti time interval (s) [30]", -"-s s satellite number (all)", -"-1 r compared ephemeris type (0:broadcast,1:precise,2:sbas,3:ssrapc,5:lex)", -"-2 b reference ephemeris type (same as above)", -"-t output time as yyyy/mm/dd hh:mm:ss", -"-e output difference as ecef-x/y/z [radial/along-trk/cross-trk]", -"-o output satellite position/clock-bias", -"-u lat lon reference position latitude and longitude for ure", -"-x level trace level", -"file ... compared ephemeris files and antenna parameters file", -NULL}; +static const char *usage[] = { + "Synopsis", + " diffeph [-t0 y/m/d h:m:s][-ts ts][-ti ti][-s s][-1 r][-2 b][-t]", + " [-o][-u lat lon][-x level] file ...", + "", + "Description", + "compute ephemeris and clock error and output errors.", + "", + "Options [default]", + "-t0 y/m/d h:m:s start time expressed in gpst", + "-ts ts time span (hr) [24]", + "-ti ti time interval (s) [30]", + "-s s satellite number (all)", + "-1 r compared ephemeris type (0:broadcast,1:precise,2:sbas,3:ssrapc,5:lex)", + "-2 b reference ephemeris type (same as above)", + "-t output time as yyyy/mm/dd hh:mm:ss", + "-e output difference as ecef-x/y/z [radial/along-trk/cross-trk]", + "-o output satellite position/clock-bias", + "-u lat lon reference position latitude and longitude for ure", + "-x level trace level", + "file ... compared ephemeris files and antenna parameters file", + NULL}; /* print usage ---------------------------------------------------------------*/ -static void prusage(void) -{ - int i; - for (i=0;usage[i];i++) fprintf(stderr,"%s\n",usage[i]); +static void prusage(void) { + int i; + for (i = 0; usage[i]; i++) fprintf(stderr, "%s\n", usage[i]); } /* update rtcm struct --------------------------------------------------------*/ -static void updatertcm(gtime_t time, rtcm_t *rtcm, nav_t *nav, FILE *fp) -{ - char s1[40],s2[40]; - int i; - - while (input_rtcm3f(rtcm,fp)>=0) { - time2str(time ,s1,0); - time2str(rtcm->time,s2,0); - trace(2,"rtcm.time=%s time=%s\n",s1,s2); - - if (timediff(rtcm->time,time)>=5.0) break; - } - for (i=0;issr[i]=rtcm->ssr[i]; +static void updatertcm(gtime_t time, rtcm_t *rtcm, nav_t *nav, FILE *fp) { + char s1[40], s2[40]; + int i; + + while (input_rtcm3f(rtcm, fp) >= 0) { + time2str(time, s1, 0); + time2str(rtcm->time, s2, 0); + trace(2, "rtcm.time=%s time=%s\n", s1, s2); + + if (timediff(rtcm->time, time) >= 5.0) break; + } + for (i = 0; i < MAXSAT; i++) nav->ssr[i] = rtcm->ssr[i]; } /* update lex ephemeris ------------------------------------------------------*/ -static int updatelex(int index, gtime_t time, lex_t *lex, nav_t *nav) -{ - gtime_t tof; - - for (;indexn;index++) { - if (!lexupdatecorr(lex->msgs+index,nav,&tof)) continue; - if (timediff(tof,time)>=0.0) break; - } - return index; +static int updatelex(int index, gtime_t time, lex_t *lex, nav_t *nav) { + gtime_t tof; + + for (; index < lex->n; index++) { + if (!lexupdatecorr(lex->msgs + index, nav, &tof)) continue; + if (timediff(tof, time) >= 0.0) break; + } + return index; } /* print difference ----------------------------------------------------------*/ -static void printephdiff(gtime_t time, int sat, int eph1, int eph2, - const nav_t *nav1, const nav_t *nav2, int topt, - int eopt, int mopt, const double *pos) -{ - double tow,rs1[6],rs2[6],dts1[2],dts2[2],var1,var2; - double drs[3],drss[3],rc[3],er[3],ea[3],ec[3]; - double rr[3],e[3],rr1[3],rr2[3],r1,r2,azel[2]; - int i,week,svh1,svh2; - char tstr[40]; - - if (!satpos(time,time,sat,eph1,nav1,rs1,dts1,&var1,&svh1)) return; - if (!satpos(time,time,sat,eph2,nav2,rs2,dts2,&var2,&svh2)) return; - if (svh1||svh2) return; - - for (i=0;i<3;i++) drs[i]=rs1[i]-rs2[i]; - if (!normv3(rs2+3,ea)) return; - cross3(rs2,rs2+3,rc); - if (!normv3(rc,ec)) return; - cross3(ea,ec,er); - drss[0]=dot3(drs,er); /* radial/along-trk/cross-trk */ - drss[1]=dot3(drs,ea); - drss[2]=dot3(drs,ec); - - if (topt) { - time2str(time,tstr,0); - printf("%s ",tstr); - } - else { - tow=time2gpst(time,&week); - printf("%4d %6.0f",week,tow); - } - printf("%3d ",sat); - - if (mopt) { - printf("%8.3f %8.3f %8.3f ",drss[0],drss[1],drss[2]); - } - else { - printf("%8.3f %8.3f %8.3f ",drs[0],drs[1],drs[2]); - } - printf("%8.3f ",dts1[0]==0.0||dts2[0]==0.0?0.0:(dts1[0]-dts2[0])*CLIGHT); - if (mopt) { - printf(" %13.3f %13.3f %13.3f %12.3f",rs1[0],rs1[1],rs1[2],dts1[0]*CLIGHT); - } - if (norm(pos,3)>0.0) { - pos2ecef(pos,rr); - for (i=0;i<3;i++) { - rr1[i]=rs1[i]-rr[i]; - rr2[i]=rs2[i]-rr[i]; - } - r1=norm(rr1,3); - r2=norm(rr2,3); - for (i=0;i<3;i++) e[i]=rr2[i]/r2; - satazel(pos,e,azel); - printf(" %8.3f %5.1f",(r1-r2)-(dts1[0]-dts2[0])*CLIGHT,azel[1]*R2D); +static void printephdiff(gtime_t time, int sat, int eph1, int eph2, const nav_t *nav1, + const nav_t *nav2, int topt, int eopt, int mopt, const double *pos) { + double tow, rs1[6], rs2[6], dts1[2], dts2[2], var1, var2; + double drs[3], drss[3], rc[3], er[3], ea[3], ec[3]; + double rr[3], e[3], rr1[3], rr2[3], r1, r2, azel[2]; + int i, week, svh1, svh2; + char tstr[40]; + + if (!satpos(time, time, sat, eph1, nav1, rs1, dts1, &var1, &svh1)) return; + if (!satpos(time, time, sat, eph2, nav2, rs2, dts2, &var2, &svh2)) return; + if (svh1 || svh2) return; + + for (i = 0; i < 3; i++) drs[i] = rs1[i] - rs2[i]; + if (!normv3(rs2 + 3, ea)) return; + cross3(rs2, rs2 + 3, rc); + if (!normv3(rc, ec)) return; + cross3(ea, ec, er); + drss[0] = dot3(drs, er); /* radial/along-trk/cross-trk */ + drss[1] = dot3(drs, ea); + drss[2] = dot3(drs, ec); + + if (topt) { + time2str(time, tstr, 0); + printf("%s ", tstr); + } else { + tow = time2gpst(time, &week); + printf("%4d %6.0f", week, tow); + } + printf("%3d ", sat); + + if (mopt) { + printf("%8.3f %8.3f %8.3f ", drss[0], drss[1], drss[2]); + } else { + printf("%8.3f %8.3f %8.3f ", drs[0], drs[1], drs[2]); + } + printf("%8.3f ", dts1[0] == 0.0 || dts2[0] == 0.0 ? 0.0 : (dts1[0] - dts2[0]) * CLIGHT); + if (mopt) { + printf(" %13.3f %13.3f %13.3f %12.3f", rs1[0], rs1[1], rs1[2], dts1[0] * CLIGHT); + } + if (norm(pos, 3) > 0.0) { + pos2ecef(pos, rr); + for (i = 0; i < 3; i++) { + rr1[i] = rs1[i] - rr[i]; + rr2[i] = rs2[i] - rr[i]; } - printf("\n"); + r1 = norm(rr1, 3); + r2 = norm(rr2, 3); + for (i = 0; i < 3; i++) e[i] = rr2[i] / r2; + satazel(pos, e, azel); + printf(" %8.3f %5.1f", (r1 - r2) - (dts1[0] - dts2[0]) * CLIGHT, azel[1] * R2D); + } + printf("\n"); } /* main ----------------------------------------------------------------------*/ -int main(int argc, char **argv) -{ - FILE *fp=NULL; - nav_t nav={0},nav2={0}; - rtcm_t rtcm; - lex_t lex={0}; - gtime_t t0,time; - double ep0[]={2000,1,1,0,0,0},tspan=24.0,tint=300,pos[]={0}; - int i,s,n=0,nx=0,sat=0,topt=0,eopt=0,mopt=0,trl=0,index=0; - int eph1=EPHOPT_BRDC,eph2=EPHOPT_PREC; - char *files[32],*ext; - - t0=epoch2time(ep0); - - init_rtcm(&rtcm); - rtcm.time=t0; - - for (i=1;i0) { - traceopen("diffeph.trace"); - tracelevel(trl); +int main(int argc, char **argv) { + FILE *fp = NULL; + nav_t nav = {0}, nav2 = {0}; + rtcm_t rtcm; + lex_t lex = {0}; + gtime_t t0, time; + double ep0[] = {2000, 1, 1, 0, 0, 0}, tspan = 24.0, tint = 300, pos[] = {0}; + int i, s, n = 0, nx = 0, sat = 0, topt = 0, eopt = 0, mopt = 0, trl = 0, index = 0; + int eph1 = EPHOPT_BRDC, eph2 = EPHOPT_PREC; + char *files[32], *ext; + + t0 = epoch2time(ep0); + + init_rtcm(&rtcm); + rtcm.time = t0; + + for (i = 1; i < argc; i++) { + if (!strcmp(argv[i], "-s") && i + 1 < argc) + sat = atoi(argv[++i]); + else if (!strcmp(argv[i], "-1") && i + 1 < argc) + eph1 = atoi(argv[++i]); + else if (!strcmp(argv[i], "-2") && i + 1 < argc) + eph2 = atoi(argv[++i]); + else if (!strcmp(argv[i], "-x") && i + 1 < argc) + trl = atoi(argv[++i]); + else if (!strcmp(argv[i], "-t0") && i + 2 < argc) { + if (sscanf(argv[++i], "%lf/%lf/%lf", ep0, ep0 + 1, ep0 + 2) < 3 || + sscanf(argv[++i], "%lf:%lf:%lf", ep0 + 3, ep0 + 4, ep0 + 5) < 1) { + fprintf(stderr, "invalid time\n"); + return -1; + } + } else if (!strcmp(argv[i], "-ts") && i + 1 < argc) + tspan = atof(argv[++i]); + else if (!strcmp(argv[i], "-ti") && i + 1 < argc) + tint = atof(argv[++i]); + else if (!strcmp(argv[i], "-t")) + topt = 1; + else if (!strcmp(argv[i], "-u") && i + 2 < argc) { + pos[0] = atof(argv[++i]) * D2R; + pos[1] = atof(argv[++i]) * D2R; + } else if (!strcmp(argv[i], "-e")) + eopt = 1; + else if (!strcmp(argv[i], "-o")) + mopt = 1; + else if (!strncmp(argv[i], "-", 1)) { + prusage(); + return 0; + } else + files[n++] = argv[i]; + } + if (trl > 0) { + traceopen("diffeph.trace"); + tracelevel(trl); + } + t0 = epoch2time(ep0); + + init_rtcm(&rtcm); + rtcm.time = t0; + + for (i = 0; i < n; i++) { + if (!(ext = strrchr(files[i], '.'))) ext = ""; + if (!strcmp(ext, ".sp3") || !strcmp(ext, ".SP3") || !strcmp(ext, ".eph") || + !strcmp(ext, ".EPH")) { + if (nav.ne > 0) { + readsp3(files[i], &nav2); /* second precise ephemeris */ + } else { + readsp3(files[i], &nav); + } + } else if (!strcmp(ext, ".atx")) { + readsap(files[i], t0, &nav); + } else if (!strcmp(ext, ".rtcm3") || !strcmp(ext, ".log")) { + if (!(fp = fopen(files[i], "rb"))) { + fprintf(stderr, "file open error: %s\n", files[i]); + return -1; + } + } else if (!strcmp(ext, ".lex")) { + if (!lexreadmsg(files[i], 0, &lex)) { + fprintf(stderr, "file read error: %s\n", files[i]); + return -1; + } + } else + files[nx++] = files[i]; /* rinex clock */ + } + for (i = 0; i < nx; i++) { + readrnx(files[i], 1, "", NULL, &nav, NULL); + if (nav.nc > 0) { + readrnxc(files[i], &nav2); /* second precise clock */ + } else { + readrnxc(files[i], &nav); } - t0=epoch2time(ep0); - - init_rtcm(&rtcm); - rtcm.time=t0; - - for (i=0;i0) { - readsp3(files[i],&nav2); /* second precise ephemeris */ - } - else { - readsp3(files[i],&nav); - } - } - else if (!strcmp(ext,".atx")) { - readsap(files[i],t0,&nav); - } - else if (!strcmp(ext,".rtcm3")||!strcmp(ext,".log")) { - if (!(fp=fopen(files[i],"rb"))) { - fprintf(stderr,"file open error: %s\n",files[i]); - return -1; - } - } - else if (!strcmp(ext,".lex")) { - if (!lexreadmsg(files[i],0,&lex)) { - fprintf(stderr,"file read error: %s\n",files[i]); - return -1; - } - } - else files[nx++]=files[i]; /* rinex clock */ + } + for (i = 0; i < (int)(tspan * 3600.0 / tint); i++) { + time = timeadd(t0, tint * i); + + char tstr[40]; + fprintf(stderr, "time=%s\r", time2str(time, tstr, 0)); + + /* update ephemeris in navigation data */ + if (fp) { + updatertcm(time, &rtcm, &nav, fp); + } else if (lex.n > 0) { + index = updatelex(index, time, &lex, &nav); } - for (i=0;i0) { - readrnxc(files[i],&nav2); /* second precise clock */ - } - else { - readrnxc(files[i],&nav); - } - } - for (i=0;i<(int)(tspan*3600.0/tint);i++) { - time=timeadd(t0,tint*i); - - char tstr[40]; - fprintf(stderr,"time=%s\r",time2str(time,tstr,0)); - - /* update ephemeris in navigation data */ - if (fp) { - updatertcm(time,&rtcm,&nav,fp); - } - else if (lex.n>0) { - index=updatelex(index,time,&lex,&nav); - } - for (s=1;s<=MAXSAT;s++) { - if (sat&&s!=sat) continue; - - printephdiff(time,s,eph1,eph2,&nav,eph1==1&&eph2==1?&nav2:&nav,topt, - eopt,mopt,pos); - } + for (s = 1; s <= MAXSAT; s++) { + if (sat && s != sat) continue; + + printephdiff(time, s, eph1, eph2, &nav, eph1 == 1 && eph2 == 1 ? &nav2 : &nav, topt, eopt, + mopt, pos); } - if (fp) fclose(fp); - if (trl>0) traceclose(); - return 0; + } + if (fp) fclose(fp); + if (trl > 0) traceclose(); + return 0; } diff --git a/util/testeph/dumpssr.c b/util/testeph/dumpssr.c index 4630ac71b..0669c21c2 100644 --- a/util/testeph/dumpssr.c +++ b/util/testeph/dumpssr.c @@ -1,131 +1,132 @@ /*------------------------------------------------------------------------------ -* dumpssr.c : dump ssr messages in rtcm log -* -* 2010/06/10 new -*-----------------------------------------------------------------------------*/ + * dumpssr.c : dump ssr messages in rtcm log + * + * 2010/06/10 new + *-----------------------------------------------------------------------------*/ #include + #include "rtklib.h" /* print ssr messages --------------------------------------------------------*/ -static void printhead(int topt, int mopt) -{ - int i; - - printf("%% %s SAT ",topt?" DAY TIME ":" GPST "); - - if (mopt&1) { - printf(" UDI IOD URA REF "); - } - if (mopt&2) { - printf("%8s %8s %8s %8s %8s %8s ","DR","DA","DC","DDR","DDA","DDC"); - } - if (mopt&4) { - printf("%8s %8s %8s %8s ","DCLK","DDCLK","DDDCLK","HRCLK"); - } - if (mopt&8) { - for (i=0;i<12;i++) printf(" B%02d ",i+1); - } - printf("\n"); +static void printhead(int topt, int mopt) { + int i; + + printf("%% %s SAT ", topt ? " DAY TIME " : " GPST "); + + if (mopt & 1) { + printf(" UDI IOD URA REF "); + } + if (mopt & 2) { + printf("%8s %8s %8s %8s %8s %8s ", "DR", "DA", "DC", "DDR", "DDA", "DDC"); + } + if (mopt & 4) { + printf("%8s %8s %8s %8s ", "DCLK", "DDCLK", "DDDCLK", "HRCLK"); + } + if (mopt & 8) { + for (i = 0; i < 12; i++) printf(" B%02d ", i + 1); + } + printf("\n"); } /* print ssr messages --------------------------------------------------------*/ -static void printssrmsg(int sat, const ssr_t *ssr, int topt, int mopt) -{ - double tow; - int week; - char tstr[40],id[8]; - - if (topt) { - time2str(ssr->t0,tstr,0); - printf("%s ",tstr); - } - else { - tow=time2gpst(ssr->t0,&week); - printf("%4d %6.0f ",week,tow); - } - satno2id(sat,id); - printf("%4s ",id); - - if (mopt&1) { - printf("%4.0f %3d %3d %3d ",ssr->udint,ssr->iode,ssr->ura,ssr->refd); - } - if (mopt&2) { - printf("%8.3f %8.3f %8.3f %8.3f %8.3f %8.3f ",ssr->deph[0],ssr->deph[1], - ssr->deph[2],ssr->ddeph[0],ssr->ddeph[1],ssr->ddeph[2]); - } - if (mopt&4) { - printf("%8.3f %8.3f %8.3f %8.3f ",ssr->dclk[0],ssr->dclk[1],ssr->dclk[2], - ssr->hrclk); - } - if (mopt&8) { - printf("%6.2f %6.2f %6.2f %6.2f %6.2f %6.2f %6.2f %6.2f %6.2f %6.2f %6.2f %6.2f ", - ssr->cbias[0],ssr->cbias[1],ssr->cbias[2],ssr->cbias[3], - ssr->cbias[4],ssr->cbias[5],ssr->cbias[6],ssr->cbias[7], - ssr->cbias[8],ssr->cbias[9],ssr->cbias[10],ssr->cbias[11]); - } - printf("\n"); +static void printssrmsg(int sat, const ssr_t *ssr, int topt, int mopt) { + double tow; + int week; + char tstr[40], id[8]; + + if (topt) { + time2str(ssr->t0, tstr, 0); + printf("%s ", tstr); + } else { + tow = time2gpst(ssr->t0, &week); + printf("%4d %6.0f ", week, tow); + } + satno2id(sat, id); + printf("%4s ", id); + + if (mopt & 1) { + printf("%4.0f %3d %3d %3d ", ssr->udint, ssr->iode, ssr->ura, ssr->refd); + } + if (mopt & 2) { + printf("%8.3f %8.3f %8.3f %8.3f %8.3f %8.3f ", ssr->deph[0], ssr->deph[1], ssr->deph[2], + ssr->ddeph[0], ssr->ddeph[1], ssr->ddeph[2]); + } + if (mopt & 4) { + printf("%8.3f %8.3f %8.3f %8.3f ", ssr->dclk[0], ssr->dclk[1], ssr->dclk[2], ssr->hrclk); + } + if (mopt & 8) { + printf("%6.2f %6.2f %6.2f %6.2f %6.2f %6.2f %6.2f %6.2f %6.2f %6.2f %6.2f %6.2f ", + ssr->cbias[0], ssr->cbias[1], ssr->cbias[2], ssr->cbias[3], ssr->cbias[4], ssr->cbias[5], + ssr->cbias[6], ssr->cbias[7], ssr->cbias[8], ssr->cbias[9], ssr->cbias[10], + ssr->cbias[11]); + } + printf("\n"); } /* dump ssr messages ---------------------------------------------------------*/ -static void dumpssrmsg(FILE *fp, int sat, int topt, int mopt) -{ - static rtcm_t rtcm; - static gtime_t t0[MAXSAT]={{0}}; - int i,stat; - - init_rtcm(&rtcm); - - while ((stat=input_rtcm3f(&rtcm,fp))>=0) { - - if (stat!=10) continue; /* ssr message */ - - for (i=0;i= 0) { + if (stat != 10) continue; /* ssr message */ + + for (i = 0; i < MAXSAT; i++) { + if (timediff(rtcm.ssr[i].t0, t0[i]) == 0.0) continue; + t0[i] = rtcm.ssr[i].t0; + + if (!sat || i + 1 == sat) { + printssrmsg(i + 1, rtcm.ssr + i, topt, mopt); + } } + } } /* main ----------------------------------------------------------------------*/ -int main(int argc, char **argv) -{ - const char *usage="dumpssr [-t][-s sat][-i][-o][-c][-b][-h][-x tr] file"; - - FILE *fp; - char *file=""; - int i,sat=0,topt=0,mopt=0,trl=0; - - for (i=0;i0) { - traceopen("dumpssr.trace"); - tracelevel(trl); - } - printhead(topt,mopt); - - dumpssrmsg(fp,sat,topt,mopt); - - fclose(fp); - traceclose(); - - return 0; +int main(int argc, char **argv) { + const char *usage = "dumpssr [-t][-s sat][-i][-o][-c][-b][-h][-x tr] file"; + + FILE *fp; + char *file = ""; + int i, sat = 0, topt = 0, mopt = 0, trl = 0; + + for (i = 0; i < argc; i++) { + if (!strcmp(argv[i], "-t")) + topt = 1; + else if (!strcmp(argv[i], "-i")) + mopt |= 1; + else if (!strcmp(argv[i], "-o")) + mopt |= 2; + else if (!strcmp(argv[i], "-c")) + mopt |= 4; + else if (!strcmp(argv[i], "-b")) + mopt |= 8; + else if (!strcmp(argv[i], "-s") && i + 1 < argc) + sat = atoi(argv[++i]); + else if (!strcmp(argv[i], "-x") && i + 1 < argc) + trl = atoi(argv[++i]); + else if (!strcmp(argv[i], "-h")) { + fprintf(stderr, "usage: %s\n", usage); + return 0; + } else + file = argv[i]; + } + if (!mopt) mopt = 0xFF; + + if (!(fp = fopen(file, "rb"))) { + fprintf(stderr, "file open error: %s\n", file); + return -1; + } + if (trl > 0) { + traceopen("dumpssr.trace"); + tracelevel(trl); + } + printhead(topt, mopt); + + dumpssrmsg(fp, sat, topt, mopt); + + fclose(fp); + traceclose(); + + return 0; } diff --git a/util/testlex/convlex.c b/util/testlex/convlex.c index 0e305a002..7c2e54356 100644 --- a/util/testlex/convlex.c +++ b/util/testlex/convlex.c @@ -1,29 +1,31 @@ /*------------------------------------------------------------------------------ -* convlex.c : convert lex binary to lex log -* -* history : 2010/08/24 1.0 new -* 2011/07/01 1.1 add -h option -*-----------------------------------------------------------------------------*/ + * convlex.c : convert lex binary to lex log + * + * history : 2010/08/24 1.0 new + * 2011/07/01 1.1 add -h option + *-----------------------------------------------------------------------------*/ #include "rtklib.h" /* main ----------------------------------------------------------------------*/ -int main(int argc, char **argv) -{ - const char *usage="lexconvbin [-h] [-t type] infile [-o outfile]"; - char *infile="",*outfile=""; - int i,type=0,format=0; - - for (i=0;i0) { - traceopen("dumplex.trace"); - tracelevel(trl); - } - if (!lexreadmsg(file,0,&lex)) { - fprintf(stderr,"file read error: %s\n",file); - return -1; - } - for (i=0;i0) traceclose(); - return 0; +int main(int argc, char **argv) { + const char *usage = "dumplex [-s sat] file"; + nav_t nav = {0}; + lex_t lex = {0}; + gtime_t tof; + char *file = ""; + int i, sat = 0, trl = 0; + + for (i = 0; i < argc; i++) { + if (!strcmp(argv[i], "-s") && i + 1 < argc) + sat = atoi(argv[++i]); + else if (!strcmp(argv[i], "-x") && i + 1 < argc) + trl = atoi(argv[++i]); + else if (!strcmp(argv[i], "-")) { + fprintf(stderr, "usage: %s\n", usage); + return 0; + } else + file = argv[i]; + } + if (trl > 0) { + traceopen("dumplex.trace"); + tracelevel(trl); + } + if (!lexreadmsg(file, 0, &lex)) { + fprintf(stderr, "file read error: %s\n", file); + return -1; + } + for (i = 0; i < lex.n; i++) { + lexupdatecorr(lex.msgs + i, &nav, &tof); + } + if (trl > 0) traceclose(); + return 0; } diff --git a/util/testlex/dumpssr.c b/util/testlex/dumpssr.c index 2383fd387..c5f97f90b 100644 --- a/util/testlex/dumpssr.c +++ b/util/testlex/dumpssr.c @@ -1,131 +1,132 @@ /*------------------------------------------------------------------------------ -* dumpssr.c : dump ssr messages in rtcm log -* -* 2010/06/10 new -*-----------------------------------------------------------------------------*/ + * dumpssr.c : dump ssr messages in rtcm log + * + * 2010/06/10 new + *-----------------------------------------------------------------------------*/ #include + #include "rtklib.h" /* print ssr messages --------------------------------------------------------*/ -static void printhead(int topt, int mopt) -{ - int i; - - printf("%% %s SAT ",topt?" DAY TIME ":" GPST "); - - if (mopt&1) { - printf(" UDI IOD URA REF "); - } - if (mopt&2) { - printf("%8s %8s %8s %8s %8s %8s ","DR","DA","DC","DDR","DDA","DDC"); - } - if (mopt&4) { - printf("%8s %8s %8s %8s ","DCLK","DDCLK","DDDCLK","HRCLK"); - } - if (mopt&8) { - for (i=0;i<12;i++) printf(" B%02d ",i+1); - } - printf("\n"); +static void printhead(int topt, int mopt) { + int i; + + printf("%% %s SAT ", topt ? " DAY TIME " : " GPST "); + + if (mopt & 1) { + printf(" UDI IOD URA REF "); + } + if (mopt & 2) { + printf("%8s %8s %8s %8s %8s %8s ", "DR", "DA", "DC", "DDR", "DDA", "DDC"); + } + if (mopt & 4) { + printf("%8s %8s %8s %8s ", "DCLK", "DDCLK", "DDDCLK", "HRCLK"); + } + if (mopt & 8) { + for (i = 0; i < 12; i++) printf(" B%02d ", i + 1); + } + printf("\n"); } /* print ssr messages --------------------------------------------------------*/ -static void printssrmsg(int sat, const ssr_t *ssr, int topt, int mopt) -{ - double tow; - int week; - char tstr[40],id[8]; - - if (topt) { - time2str(ssr->t0,tstr,0); - printf("%s ",tstr); - } - else { - tow=time2gpst(ssr->t0,&week); - printf("%4d %6.0f ",week,tow); - } - satno2id(sat,id); - printf("%4s ",id); - - if (mopt&1) { - printf("%4.0f %3d %3d %3d ",ssr->udint,ssr->iode,ssr->ura,ssr->refd); - } - if (mopt&2) { - printf("%8.3f %8.3f %8.3f %8.3f %8.3f %8.3f ",ssr->deph[0],ssr->deph[1], - ssr->deph[2],ssr->ddeph[0],ssr->ddeph[1],ssr->ddeph[2]); - } - if (mopt&4) { - printf("%8.3f %8.3f %8.3f %8.3f ",ssr->dclk[0],ssr->dclk[1],ssr->dclk[2], - ssr->hrclk); - } - if (mopt&8) { - printf("%6.2f %6.2f %6.2f %6.2f %6.2f %6.2f %6.2f %6.2f %6.2f %6.2f %6.2f %6.2f ", - ssr->cbias[0],ssr->cbias[1],ssr->cbias[2],ssr->cbias[3], - ssr->cbias[4],ssr->cbias[5],ssr->cbias[6],ssr->cbias[7], - ssr->cbias[8],ssr->cbias[9],ssr->cbias[10],ssr->cbias[11]); - } - printf("\n"); +static void printssrmsg(int sat, const ssr_t *ssr, int topt, int mopt) { + double tow; + int week; + char tstr[40], id[8]; + + if (topt) { + time2str(ssr->t0, tstr, 0); + printf("%s ", tstr); + } else { + tow = time2gpst(ssr->t0, &week); + printf("%4d %6.0f ", week, tow); + } + satno2id(sat, id); + printf("%4s ", id); + + if (mopt & 1) { + printf("%4.0f %3d %3d %3d ", ssr->udint, ssr->iode, ssr->ura, ssr->refd); + } + if (mopt & 2) { + printf("%8.3f %8.3f %8.3f %8.3f %8.3f %8.3f ", ssr->deph[0], ssr->deph[1], ssr->deph[2], + ssr->ddeph[0], ssr->ddeph[1], ssr->ddeph[2]); + } + if (mopt & 4) { + printf("%8.3f %8.3f %8.3f %8.3f ", ssr->dclk[0], ssr->dclk[1], ssr->dclk[2], ssr->hrclk); + } + if (mopt & 8) { + printf("%6.2f %6.2f %6.2f %6.2f %6.2f %6.2f %6.2f %6.2f %6.2f %6.2f %6.2f %6.2f ", + ssr->cbias[0], ssr->cbias[1], ssr->cbias[2], ssr->cbias[3], ssr->cbias[4], ssr->cbias[5], + ssr->cbias[6], ssr->cbias[7], ssr->cbias[8], ssr->cbias[9], ssr->cbias[10], + ssr->cbias[11]); + } + printf("\n"); } /* dump ssr messages ---------------------------------------------------------*/ -static void dumpssrmsg(FILE *fp, int sat, int topt, int mopt) -{ - static rtcm_t rtcm; - static gtime_t t0[MAXSAT]={{0}}; - int s,stat; - - init_rtcm(&rtcm); - - while ((stat=input_rtcm3f(&rtcm,fp))>=0) { - - if (stat!=10) continue; /* ssr message */ - - for (s=1;s<=MAXSAT;s++) { - if (timediff(rtcm.ssr[s-1].t0,t0[s-1])==0.0) continue; - t0[s-1]=rtcm.ssr[s-1].t0; - - if (!sat||s==sat) { - printssrmsg(s,rtcm.ssr+s-1,topt,mopt); - } - } +static void dumpssrmsg(FILE *fp, int sat, int topt, int mopt) { + static rtcm_t rtcm; + static gtime_t t0[MAXSAT] = {{0}}; + int s, stat; + + init_rtcm(&rtcm); + + while ((stat = input_rtcm3f(&rtcm, fp)) >= 0) { + if (stat != 10) continue; /* ssr message */ + + for (s = 1; s <= MAXSAT; s++) { + if (timediff(rtcm.ssr[s - 1].t0, t0[s - 1]) == 0.0) continue; + t0[s - 1] = rtcm.ssr[s - 1].t0; + + if (!sat || s == sat) { + printssrmsg(s, rtcm.ssr + s - 1, topt, mopt); + } } + } } /* main ----------------------------------------------------------------------*/ -int main(int argc, char **argv) -{ - const char *usage="dumpssr [-t][-s sat][-i][-o][-c][-b][-h][-x tr] file"; - - FILE *fp; - char *file=""; - int i,sat=0,topt=0,mopt=0,trl=0; - - for (i=0;i0) { - traceopen("dumpssr.trace"); - tracelevel(trl); - } - printhead(topt,mopt); - - dumpssrmsg(fp,sat,topt,mopt); - - fclose(fp); - traceclose(); - - return 0; +int main(int argc, char **argv) { + const char *usage = "dumpssr [-t][-s sat][-i][-o][-c][-b][-h][-x tr] file"; + + FILE *fp; + char *file = ""; + int i, sat = 0, topt = 0, mopt = 0, trl = 0; + + for (i = 0; i < argc; i++) { + if (!strcmp(argv[i], "-t")) + topt = 1; + else if (!strcmp(argv[i], "-i")) + mopt |= 1; + else if (!strcmp(argv[i], "-o")) + mopt |= 2; + else if (!strcmp(argv[i], "-c")) + mopt |= 4; + else if (!strcmp(argv[i], "-b")) + mopt |= 8; + else if (!strcmp(argv[i], "-s") && i + 1 < argc) + sat = atoi(argv[++i]); + else if (!strcmp(argv[i], "-x") && i + 1 < argc) + trl = atoi(argv[++i]); + else if (!strcmp(argv[i], "-h")) { + fprintf(stderr, "usage: %s\n", usage); + return 0; + } else + file = argv[i]; + } + if (!mopt) mopt = 0xFF; + + if (!(fp = fopen(file, "rb"))) { + fprintf(stderr, "file open error: %s\n", file); + return -1; + } + if (trl > 0) { + traceopen("dumpssr.trace"); + tracelevel(trl); + } + printhead(topt, mopt); + + dumpssrmsg(fp, sat, topt, mopt); + + fclose(fp); + traceclose(); + + return 0; } diff --git a/util/testlex/outlexion.c b/util/testlex/outlexion.c index e73be2e69..16ab2be44 100644 --- a/util/testlex/outlexion.c +++ b/util/testlex/outlexion.c @@ -1,128 +1,127 @@ /*------------------------------------------------------------------------------ -* outlexion.c : output lex ionosphere correction as matrix -* -* 2010/12/09 0.1 new -*-----------------------------------------------------------------------------*/ + * outlexion.c : output lex ionosphere correction as matrix + * + * 2010/12/09 0.1 new + *-----------------------------------------------------------------------------*/ #include + #include "rtklib.h" /* update lex ephemeris ------------------------------------------------------*/ -static int updatelex(int index, gtime_t time, lex_t *lex, nav_t *nav) -{ - gtime_t tof; - - for (;indexn;index++) { - if (!lexupdatecorr(lex->msgs+index,nav,&tof)) continue; - char tstr[40]; - fprintf(stderr,"%6d: tof=%s\r",index,time2str(tof,tstr,0)); - if (timediff(tof,time)>=0.0) break; - } - return index; +static int updatelex(int index, gtime_t time, lex_t *lex, nav_t *nav) { + gtime_t tof; + + for (; index < lex->n; index++) { + if (!lexupdatecorr(lex->msgs + index, nav, &tof)) continue; + char tstr[40]; + fprintf(stderr, "%6d: tof=%s\r", index, time2str(tof, tstr, 0)); + if (timediff(tof, time) >= 0.0) break; + } + return index; } /* print tec grid data -------------------------------------------------------*/ -static void printtec(int index, gtime_t time, double sec, const nav_t *nav, - const double *rpos, int nlat, int nlon, double dpos, - FILE *fp) -{ - int i,j; - double lat0,lon0,pos[3]={0},azel[]={0,PI/2.0},ion,var; - - lat0=rpos[0]+dpos*((nlat-1)/2); - lon0=rpos[1]-dpos*((nlon-1)/2); - - if (index==1) { - fprintf(fp,"lons =["); - for (i=0;i tecu */ - fprintf(fp,"%7.3f ",ion); - } - else { - fprintf(fp,"%7s ","nan"); - } - } - fprintf(fp,"\n"); +static void printtec(int index, gtime_t time, double sec, const nav_t *nav, const double *rpos, + int nlat, int nlon, double dpos, FILE *fp) { + int i, j; + double lat0, lon0, pos[3] = {0}, azel[] = {0, PI / 2.0}, ion, var; + + lat0 = rpos[0] + dpos * ((nlat - 1) / 2); + lon0 = rpos[1] - dpos * ((nlon - 1) / 2); + + if (index == 1) { + fprintf(fp, "lons =["); + for (i = 0; i < nlon; i++) fprintf(fp, "%.1f%s", lon0 + dpos * i, i < nlon - 1 ? " " : ""); + fprintf(fp, "];\n"); + fprintf(fp, "lats =["); + for (i = 0; i < nlat; i++) fprintf(fp, "%.1f%s", lat0 - dpos * i, i < nlat - 1 ? " " : ""); + fprintf(fp, "];\n\n"); + } + char tstr[40]; + fprintf(fp, "%% %s\n", time2str(time, tstr, 0)); + fprintf(fp, "time(%d)=%.0f;\n", index, sec); + fprintf(fp, "tec(:,:,%d)=[\n", index); + for (i = 0; i < nlat; i++) { + for (j = 0; j < nlon; j++) { + pos[0] = (lat0 - dpos * i) * D2R; + pos[1] = (lon0 + dpos * j) * D2R; + if (lexioncorr(time, nav, pos, azel, &ion, &var)) { + /*tec=ion*FREQ1*FREQ1/40.3E16;*/ /* L1 iono delay -> tecu */ + fprintf(fp, "%7.3f ", ion); + } else { + fprintf(fp, "%7s ", "nan"); + } } - fprintf(fp,"];\n"); + fprintf(fp, "\n"); + } + fprintf(fp, "];\n"); } /* main ----------------------------------------------------------------------*/ -int main(int argc, char **argv) -{ - FILE *fp=NULL; - nav_t nav={0}; - lex_t lex={0}; - gtime_t t0,time; - double ep0[]={2000,1,1,0,0,0},tspan=24.0,tint=7200,dpos=1; - double rpos[]={35,137}; - char *ifile="",*ofile=""; - int i,trl=0,index=0,nlat=45,nlon=45; - - t0=epoch2time(ep0); - - for (i=1;i0) { - traceopen("diffeph.trace"); - tracelevel(trl); - } - t0=epoch2time(ep0); - - if (!lexreadmsg(ifile,0,&lex)) { - fprintf(stderr,"file read error: %s\n",ifile); - return -1; - } - if (!(fp=fopen(ofile,"w"))) { - fprintf(stderr,"file open error: %s\n",ofile); +int main(int argc, char **argv) { + FILE *fp = NULL; + nav_t nav = {0}; + lex_t lex = {0}; + gtime_t t0, time; + double ep0[] = {2000, 1, 1, 0, 0, 0}, tspan = 24.0, tint = 7200, dpos = 1; + double rpos[] = {35, 137}; + char *ifile = "", *ofile = ""; + int i, trl = 0, index = 0, nlat = 45, nlon = 45; + + t0 = epoch2time(ep0); + + for (i = 1; i < argc; i++) { + if (!strcmp(argv[i], "-t0") && i + 2 < argc) { + if (sscanf(argv[++i], "%lf/%lf/%lf", ep0, ep0 + 1, ep0 + 2) < 3 || + sscanf(argv[++i], "%lf:%lf:%lf", ep0 + 3, ep0 + 4, ep0 + 5) < 1) { + fprintf(stderr, "invalid time\n"); return -1; - } - fprintf(fp,"epoch=[%.0f %.0f %.0f %.0f %.0f %.0f];\n", - ep0[0],ep0[1],ep0[2],ep0[3],ep0[4],ep0[5]); - - for (i=0;i<(int)(tspan*3600.0/tint);i++) { - time=timeadd(t0,tint*i); - - char tstr[40]; - fprintf(stderr,"time=%s\r",time2str(time,tstr,0)); - - index=updatelex(index,time,&lex,&nav); - - printtec(i+1,time,tint*i,&nav,rpos,nlat,nlon,dpos,fp); - } - fclose(fp); - if (trl>0) traceclose(); - return 0; + } + } else if (!strcmp(argv[i], "-ts") && i + 1 < argc) + tspan = atof(argv[++i]); + else if (!strcmp(argv[i], "-ti") && i + 1 < argc) + tint = atof(argv[++i]); + else if (!strcmp(argv[i], "-u") && i + 2 < argc) { + rpos[0] = atof(argv[++i]); + rpos[1] = atof(argv[++i]); + } else if (!strcmp(argv[i], "-n") && i + 2 < argc) { + nlat = atoi(argv[++i]); + nlon = atoi(argv[++i]); + } else if (!strcmp(argv[i], "-d") && i + 1 < argc) + dpos = atof(argv[++i]); + else if (!strcmp(argv[i], "-o") && i + 1 < argc) + ofile = argv[++i]; + else if (!strcmp(argv[i], "-x") && i + 1 < argc) + trl = atof(argv[++i]); + else + ifile = argv[i]; + } + if (trl > 0) { + traceopen("diffeph.trace"); + tracelevel(trl); + } + t0 = epoch2time(ep0); + + if (!lexreadmsg(ifile, 0, &lex)) { + fprintf(stderr, "file read error: %s\n", ifile); + return -1; + } + if (!(fp = fopen(ofile, "w"))) { + fprintf(stderr, "file open error: %s\n", ofile); + return -1; + } + fprintf(fp, "epoch=[%.0f %.0f %.0f %.0f %.0f %.0f];\n", ep0[0], ep0[1], ep0[2], ep0[3], ep0[4], + ep0[5]); + + for (i = 0; i < (int)(tspan * 3600.0 / tint); i++) { + time = timeadd(t0, tint * i); + + char tstr[40]; + fprintf(stderr, "time=%s\r", time2str(time, tstr, 0)); + + index = updatelex(index, time, &lex, &nav); + + printtec(i + 1, time, tint * i, &nav, rpos, nlat, nlon, dpos, fp); + } + fclose(fp); + if (trl > 0) traceclose(); + return 0; }