From f6ceaa9ffa06993f7e2f09ec55e4e46ca3a3094b Mon Sep 17 00:00:00 2001 From: oaq Date: Fri, 3 Oct 2025 18:53:42 +1000 Subject: [PATCH] rtkrcv, rtknavi: support more solution out streams Move towards the number of output streams being a compilation option, adding the RTKSVRNSOL define and also make better use of MAXSTRRTK rather than baking in constants. Move the output streams to the end of the stream index range so that adding more does not affect indices of the input and log streams. rtkrcv now builds with up to 6 output streams and could support more by simply adding move config options for them, and rtknavi builds with 3 out streams. --- app/consapp/rtkrcv/gcc/makefile | 2 +- app/consapp/rtkrcv/rtkrcv.c | 124 +++++++----- app/qtapp/rtknavi_qt/logstrdlg.ui | 6 +- app/qtapp/rtknavi_qt/mondlg.cpp | 27 +-- app/qtapp/rtknavi_qt/navimain.cpp | 167 +++++++++-------- app/qtapp/rtknavi_qt/navimain.ui | 38 ++-- app/qtapp/rtknavi_qt/outstrdlg.cpp | 70 +++++-- app/qtapp/rtknavi_qt/outstrdlg.h | 4 +- app/qtapp/rtknavi_qt/outstrdlg.ui | 215 +++++++++++++++------ app/winapp/rtknavi/logstrdlg.dfm | 6 +- app/winapp/rtknavi/mondlg.cpp | 27 +-- app/winapp/rtknavi/navimain.cpp | 99 +++++----- app/winapp/rtknavi/navimain.dfm | 45 +++-- app/winapp/rtknavi/navimain.h | 1 + app/winapp/rtknavi/naviopt.cpp | 51 ++--- app/winapp/rtknavi/outstrdlg.cpp | 40 ++++ app/winapp/rtknavi/outstrdlg.dfm | 290 ++++++++++++++++++----------- app/winapp/rtknavi/outstrdlg.h | 18 +- src/rtklib.h | 13 +- src/rtksvr.c | 62 +++--- 20 files changed, 820 insertions(+), 485 deletions(-) diff --git a/app/consapp/rtkrcv/gcc/makefile b/app/consapp/rtkrcv/gcc/makefile index fdde9a9c7..888246975 100644 --- a/app/consapp/rtkrcv/gcc/makefile +++ b/app/consapp/rtkrcv/gcc/makefile @@ -3,7 +3,7 @@ BINDIR = /usr/local/bin SRC = ../../../../src -CTARGET= -DTRACE -DENAGLO -DENAQZS -DENACMP -DENAGAL -DENAIRN -DNFREQ=4 -DNEXOBS=3 -DSVR_REUSEADDR +CTARGET= -DTRACE -DENAGLO -DENAQZS -DENACMP -DENAGAL -DENAIRN -DNFREQ=4 -DNEXOBS=3 -DSVR_REUSEADDR -DRTKSVRNSOL=6 #CTARGET= -DENAGLO -DENAQZS -DENACMP -DENAGAL -DENAIRN -DNFREQ=4 -DIERS_MODEL -DSVR_REUSEADDR CFLAGS = -std=c99 -Wall -O3 -pedantic -Wno-unused-but-set-variable -I$(SRC) -I.. -DTRACE $(CTARGET) -g diff --git a/app/consapp/rtkrcv/rtkrcv.c b/app/consapp/rtkrcv/rtkrcv.c index 2cb1f2b3c..00b7a1c69 100644 --- a/app/consapp/rtkrcv/rtkrcv.c +++ b/app/consapp/rtkrcv/rtkrcv.c @@ -91,13 +91,14 @@ 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 int strtype[MAXSTRRTK]={ /* stream types */ + STR_SERIAL,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 strpath[MAXSTRRTK][MAXSTR]={"","","","","",""}; /* stream paths */ +static int strfmt[]={ /* Input stream formats */ + STRFMT_UBX,STRFMT_RTCM3,STRFMT_SP3 }; +static int ostrfmt[RTKSVRNSOL]; /* Output stream formats */ static char rcvopt[3][256]={""}; /* Receiver options */ static int svrcycle =10; /* server cycle (ms) */ static int timeout =10000; /* timeout time (ms) */ @@ -122,7 +123,7 @@ 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 solopt_t solopt[RTKSVRNSOL]={{0}}; /* solution options */ static filopt_t filopt ={""}; /* file options */ /* help text -----------------------------------------------------------------*/ @@ -197,33 +198,51 @@ static opt_t rcvopts[]={ {"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-type", 3, (void *)&strtype[1], ISTOPT }, + {"inpstr2-path", 2, (void *)strpath [1], "" }, + {"inpstr2-format", 3, (void *)&strfmt [1], FMTOPT }, {"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], "" }, + {"inpstr3-type", 3, (void *)&strtype[2], ISTOPT }, + {"inpstr3-path", 2, (void *)strpath [2], "" }, + {"inpstr3-format", 3, (void *)&strfmt [2], FMTOPT }, + {"inpstr3-rcvopt", 2, (void *)rcvopt[2], "" }, + {"logstr1-type", 3, (void *)&strtype[3], OSTOPT }, + {"logstr1-path", 2, (void *)strpath [3], "" }, + {"logstr2-type", 3, (void *)&strtype[4], OSTOPT }, + {"logstr2-path", 2, (void *)strpath [4], "" }, + {"logstr3-type", 3, (void *)&strtype[5], OSTOPT }, + {"logstr3-path", 2, (void *)strpath [5], "" }, + {"outstr1-type", 3, (void *)&strtype[6], OSTOPT }, + {"outstr1-path", 2, (void *)strpath [6], "" }, + {"outstr1-format", 3, (void *)&ostrfmt[0], SOLOPT }, + {"outstr2-type", 3, (void *)&strtype[7], OSTOPT }, + {"outstr2-path", 2, (void *)strpath [7], "" }, + {"outstr2-format", 3, (void *)&ostrfmt[1], SOLOPT }, + {"outstr3-type", 3, (void *)&strtype[8], OSTOPT }, + {"outstr3-path", 2, (void *)strpath [8], "" }, + {"outstr3-format", 3, (void *)&ostrfmt[2], SOLOPT }, +#if RTKSVRNSOL > 3 + {"outstr4-type", 3, (void *)&strtype[9], OSTOPT }, + {"outstr4-path", 2, (void *)strpath [9], "" }, + {"outstr4-format", 3, (void *)&ostrfmt[3], SOLOPT }, +#endif +#if RTKSVRNSOL > 4 + {"outstr5-type", 3, (void *)&strtype[10], OSTOPT }, + {"outstr5-path", 2, (void *)strpath [10], "" }, + {"outstr5-format", 3, (void *)&ostrfmt[4], SOLOPT }, +#endif +#if RTKSVRNSOL > 5 + {"outstr6-type", 3, (void *)&strtype[11], OSTOPT }, + {"outstr6-path", 2, (void *)strpath [11], "" }, + {"outstr6-format", 3, (void *)&ostrfmt[5], SOLOPT }, +#endif {"misc-svrcycle", 0, (void *)&svrcycle, "ms" }, {"misc-timeout", 0, (void *)&timeout, "ms" }, @@ -436,15 +455,12 @@ static int startsvr(vt_t *vt) 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 *paths[MAXSTRRTK]; char errmsg[2048]=""; - int i,stropt[8]={0}; + int i,stropt[MAXSTRRTK]={0}; trace(3,"startsvr:\n"); - + /* read start commands from command files */ for (i=0;i<3;i++) { if (!*rcvcmds[i]) continue; @@ -459,7 +475,7 @@ static int startsvr(vt_t *vt) } /* confirm overwrite */ if (vt!=NULL) { - for (i=3;i<8;i++) { + for (i = 3; i < MAXSTRRTK; i++) { if (strtype[i]==STR_FILE&&!confwrite(vt,strpath[i])) return 0; } } @@ -507,9 +523,10 @@ static int startsvr(vt_t *vt) vt_printf(vt,"command exec error: %s (%d)\n",startcmd,ret); } #endif - solopt[0].posf=strfmt[3]; - solopt[1].posf=strfmt[4]; - + for (int i = 0; i < RTKSVRNSOL; i++) solopt[i].posf=ostrfmt[i]; + + for (int i = 0; i < MAXSTRRTK; i++) paths[i] = strpath[i]; + /* 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, @@ -989,9 +1006,7 @@ static void prerror(vt_t *vt) 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" - }; + "input rover","input base","input corr","log rover","log base","log corr"}; const char *type[]={ "-","serial","file","tcpsvr","tcpcli","ntrips","ntripc","ftp", "http","ntripcas","udpsvr","udpcli","membuf" @@ -999,25 +1014,26 @@ static void prstream(vt_t *vt) 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}; + stream_t stream[MAXSTRRTK+1]; + int i,format[MAXSTRRTK+1]={0}; trace(4,"prstream:\n"); rtksvrlock(&svr); - for (i=0;i<8;i++) stream[i]=svr.stream[i]; + for (i=0;i= MAXSTRRTK ? "monitor" : "output sol"; 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]]:"-"), + name,type[stream[i].type],i<3?fmt[format[i]]:(i>=6?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); @@ -1283,7 +1299,7 @@ static void cmd_set(char **args, int narg, vt_t *vt) return; } getsysopts(&prcopt,solopt,&filopt); - solopt[1]=solopt[0]; + for (int i = 1; i < RTKSVRNSOL; i++) solopt[i] = solopt[0]; vt_printf(vt,"option %s changed.",opt->name); if (strncmp(opt->name,"console",7)) { @@ -1388,7 +1404,7 @@ static void cmd_load(char **args, int narg, vt_t *vt) return; } getsysopts(&prcopt,solopt,&filopt); - solopt[1]=solopt[0]; + for (int i = 1; i < RTKSVRNSOL; i++) solopt[i] = solopt[0]; if (!loadopts(file,rcvopts)) { vt_printf(vt,"no options file: %s\n",file); @@ -1827,6 +1843,14 @@ int main(int argc, char **argv) traceopen(TRACEFILE); tracelevel(trace); } + + // Default input streams. + for (int i = i; i < RTKSVRNSOL; i++) { + strtype[6 + i] = STR_NONE; + strcpy(strpath[6 + i], ""); + ostrfmt[i] = i == 0 ? SOLF_LLH : SOLF_NMEA; + } + /* initialize rtk server and monitor port */ rtksvrinit(&svr); strinit(&moni); @@ -1839,8 +1863,8 @@ int main(int argc, char **argv) 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]; + /* Copy the system options for the other output solution streams */ + for (int i = 1; i < RTKSVRNSOL; i++) solopt[i] = solopt[0]; /* read navigation data */ if (!readnav(NAVIFILE,&svr.nav)) { diff --git a/app/qtapp/rtknavi_qt/logstrdlg.ui b/app/qtapp/rtknavi_qt/logstrdlg.ui index d3490d750..dea18ea53 100644 --- a/app/qtapp/rtknavi_qt/logstrdlg.ui +++ b/app/qtapp/rtknavi_qt/logstrdlg.ui @@ -193,7 +193,7 @@ Enable rover data stream logging - (6) Rover + (3) Rover @@ -223,7 +223,7 @@ Enable base station data stream logging - (7) Base Station + (4) Base Station @@ -243,7 +243,7 @@ Enable correction data stream logging - (8) Correction + (5) Correction diff --git a/app/qtapp/rtknavi_qt/mondlg.cpp b/app/qtapp/rtknavi_qt/mondlg.cpp index 174c69477..858a15c6b 100644 --- a/app/qtapp/rtknavi_qt/mondlg.cpp +++ b/app/qtapp/rtknavi_qt/mondlg.cpp @@ -1575,10 +1575,10 @@ void MonitorDialog::setStream() header << tr("STR") << tr("Stream") << tr("Type") << tr("Format") << tr("Mode") << tr("State") << tr("Input (bytes)") << tr("Input (bps)") << tr("Output (bytes)") << tr("Output (bps)") << tr("Path") << tr("Message"); - int i, width[] = {40, 150, 120, 110, 50, 50, 140, 140, 140, 140, 220, 220}; + int i, width[] = {45, 170, 120, 150, 60, 55, 120, 110, 135, 120, 220, 220}; ui->tWConsole->setColumnCount(12); - ui->tWConsole->setRowCount(9); + ui->tWConsole->setRowCount(MAXSTRRTK + 1); ui->tWConsole->setHorizontalHeaderLabels(header); for (i = 0; i < ui->tWConsole->columnCount(); i++) @@ -1593,9 +1593,10 @@ void MonitorDialog::setStream() //--------------------------------------------------------------------------- void MonitorDialog::showStream() { - const QString ch[] = { - tr("Input Rover"), tr("Input Base"), tr("Input Correction"), tr("Output Solution 1"), - tr("Output Solution 2"), tr("Log Rover"), tr("Log Base"), tr("Log Correction"), + const QString ch[MAXSTRRTK + 1] = { + tr("Input Rover"), tr("Input Base"), tr("Input Correction"), + tr("Log Rover"), tr("Log Base"), tr("Log Correction"), + tr("Output Solution 1"), tr("Output Solution 2"), tr("Output Solution 3"), tr("Monitor") }; const QString type[] = { @@ -1608,26 +1609,26 @@ void MonitorDialog::showStream() tr("Solution stats"), tr("GSI F1/F2")}; const QString state[] = {tr("Error"), tr("-"), tr("OK")}; QString mode, form; - stream_t stream[9]; - int i, format[9] = {0}; + stream_t stream[MAXSTRRTK + 1]; + int i, format[MAXSTRRTK + 1] = {0}; char path[MAXSTRPATH] = "", *p, *q; rtksvrlock(rtksvr); // lock - for (i = 0; i < 8; i++) stream[i] = rtksvr->stream[i]; + for (i = 0; i < MAXSTRRTK; 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; + for (i = 0; i < RTKSVRNSOL; i++) format[6+i] = rtksvr->solopt[i].posf; + stream[MAXSTRRTK] = *monistr; + format[MAXSTRRTK] = SOLF_LLH; rtksvrunlock(rtksvr); // unlock - for (i = 0; i < 9; i++) { + for (i = 0; i < MAXSTRRTK + 1; i++) { int j = 0; ui->tWConsole->item(i, j++)->setText(QString("(%1)").arg(i+1)); ui->tWConsole->item(i, j++)->setText(ch[i]); ui->tWConsole->item(i, j++)->setText(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 if (i >= 6) form = outformat[format[i]]; else form = "-"; ui->tWConsole->item(i, j++)->setText(form); if (stream[i].mode & STR_MODE_R) mode = tr("R"); else mode = ""; diff --git a/app/qtapp/rtknavi_qt/navimain.cpp b/app/qtapp/rtknavi_qt/navimain.cpp index 38237ca8c..664d78f26 100644 --- a/app/qtapp/rtknavi_qt/navimain.cpp +++ b/app/qtapp/rtknavi_qt/navimain.cpp @@ -81,12 +81,12 @@ MainWindow *mainForm; #define SQRT(x) ((x)<0.0||(x)!=(x)?0.0:sqrt(x)) // 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 int strtype[MAXSTRRTK] = { /* stream types */ + STR_NONE, 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 char strpath[MAXSTRRTK][MAXSTR] = { "" }; /* stream paths */ +static int strfmt[MAXSTRRTK] = { /* stream formats */ + STRFMT_RTCM3, STRFMT_RTCM3, STRFMT_SP3, 0, 0, 0, SOLF_LLH, SOLF_NMEA, SOLF_NMEA }; #define TIMOPT "0:gpst,1:utc,2:jst,3:tow" @@ -146,29 +146,32 @@ MainWindow::MainWindow(QWidget *parent) 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-type", 3, (void *)&strtype[1], ISTOPT }, + { "inpstr2-path", 2, (void *)strpath [1], "" }, { "inpstr2-format", 3, (void *)&strfmt [1], FMTOPT }, + { "inpstr2-nmeareq", 3, (void *)&nmeaRequestType, NMEOPT}, + { "inpstr2-nmealat", 1, (void *)&nmeaPosition[0], "deg"}, + { "inpstr2-nmealon", 1, (void *)&nmeaPosition[1], "deg"}, + { "inpstr3-type", 3, (void *)&strtype[2], ISTOPT }, + { "inpstr3-path", 2, (void *)strpath [2], "" }, { "inpstr3-format", 3, (void *)&strfmt [2], FMTOPT }, - { "inpstr2-nmeareq", 3, (void *)&nmeaRequestType, NMEOPT }, - { "inpstr2-nmealat", 1, (void *)&nmeaPosition[0], "deg" }, - { "inpstr2-nmealon", 1, (void *)&nmeaPosition[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], "" }, + { "logstr1-type", 3, (void *)&strtype[3], OSTOPT }, + { "logstr1-path", 2, (void *)strpath [3], "" }, + { "logstr2-path", 2, (void *)strpath [4], "" }, + { "logstr2-type", 3, (void *)&strtype[4], OSTOPT }, + { "logstr3-type", 3, (void *)&strtype[5], OSTOPT }, + { "logstr3-path", 2, (void *)strpath [5], "" }, + { "outstr1-type", 3, (void *)&strtype[6], OSTOPT }, + { "outstr1-path", 2, (void *)strpath [6], "" }, + { "outstr1-format", 3, (void *)&strfmt [6], SOLOPT }, + { "outstr2-type", 3, (void *)&strtype[7], OSTOPT }, + { "outstr2-path", 2, (void *)strpath [7], "" }, + { "outstr2-format", 3, (void *)&strfmt [7], SOLOPT }, + { "outstr3-type", 3, (void *)&strtype[8], OSTOPT }, + { "outstr3-path", 2, (void *)strpath [8], "" }, + { "outstr3-format", 3, (void *)&strfmt [8], SOLOPT }, { "", 0, NULL, "" } }; @@ -496,7 +499,7 @@ void MainWindow::showOptionsDialog() trace(3, "showOptionsDialog\n"); - for (int i = 0; i < 8; i++) { + for (int i = 0; i < MAXSTRRTK; i++) { int stype = streamType[i]; if (i < 3) { if (stype >= 0 && stype < (int)(sizeof(itype) / sizeof(int))) @@ -579,7 +582,7 @@ void MainWindow::showOptionsDialog() if (optDialog->result() != QDialog::Accepted) return; - for (int i = 0; i < 8; i++) { + for (int i = 0; i < MAXSTRRTK; i++) { streamType[i] = 0; // Default to serial bool found = false; if (i < 3) { @@ -601,7 +604,7 @@ void MainWindow::showOptionsDialog() } // Disable if the stream type is not found. if (found == false) streamEnabled[i] = false; - if (i < 5) inputFormat[i] = strfmt[i]; + if (i < 3 || i >= 6) inputFormat[i] = strfmt[i]; if (strtype[i] == STR_SERIAL) paths[i][0] = strpath[i]; @@ -737,17 +740,17 @@ int MainWindow::confirmOverwrite(const QString &path) void MainWindow::showOutputStreamDialog() { int otype[] = {STR_SERIAL, STR_TCPCLI, STR_TCPSVR, STR_NTRIPSVR, STR_NTRIPCAS, STR_FILE}; - int i, j, str, update[2] = { 0 }; + int i, j, str, update[RTKSVRNSOL] = { 0 }; QString path; trace(3, "showOutputStreamDialog\n"); - for (i = 3; i < 5; i++) { - outputStrDialog->setStreamEnabled(i - 3, streamEnabled[i]); - outputStrDialog->setStreamType(i - 3, streamType[i]); - outputStrDialog->setStreamFormat(i - 3, inputFormat[i]); + for (i = 6; i < MAXSTRRTK; i++) { + outputStrDialog->setStreamEnabled(i - 6, streamEnabled[i]); + outputStrDialog->setStreamType(i - 6, streamType[i]); + outputStrDialog->setStreamFormat(i - 6, inputFormat[i]); for (j = 0; j < 4; j++) - outputStrDialog->setPath(i - 3, j, paths[i][j]); + outputStrDialog->setPath(i - 6, j, paths[i][j]); } for (i = 0; i < 10; i++) { outputStrDialog->setHistory(i, history[i]); @@ -758,21 +761,21 @@ void MainWindow::showOutputStreamDialog() if (outputStrDialog->result() != QDialog::Accepted) return; - for (i = 3; i < 5; i++) { - if (streamEnabled[i] != outputStrDialog->getStreamEnabled(i - 3) || - streamType[i] != outputStrDialog->getStreamType(i - 3) || - inputFormat[i] != outputStrDialog->getStreamFormat(i - 3) || - paths[i][0] != outputStrDialog->getPath(i - 3, 0) || - paths[i][1] != outputStrDialog->getPath(i - 3, 1) || - paths[i][2] != outputStrDialog->getPath(i - 3, 2) || - paths[i][3] != outputStrDialog->getPath(i - 3, 3)) - update[i - 3] = 1; - - streamEnabled[i] = outputStrDialog->getStreamEnabled(i - 3); - streamType[i] = outputStrDialog->getStreamType(i - 3); - inputFormat[i] = outputStrDialog->getStreamFormat(i - 3); + for (i = 6; i < MAXSTRRTK; i++) { + if (streamEnabled[i] != outputStrDialog->getStreamEnabled(i - 6) || + streamType[i] != outputStrDialog->getStreamType(i - 6) || + inputFormat[i] != outputStrDialog->getStreamFormat(i - 6) || + paths[i][0] != outputStrDialog->getPath(i - 6, 0) || + paths[i][1] != outputStrDialog->getPath(i - 6, 1) || + paths[i][2] != outputStrDialog->getPath(i - 6, 2) || + paths[i][3] != outputStrDialog->getPath(i - 6, 3)) + update[i - 6] = 1; + + streamEnabled[i] = outputStrDialog->getStreamEnabled(i - 6); + streamType[i] = outputStrDialog->getStreamType(i - 6); + inputFormat[i] = outputStrDialog->getStreamFormat(i - 6); for (j = 0; j < 4; j++) - paths[i][j] = outputStrDialog->getPath(i - 3, j); + paths[i][j] = outputStrDialog->getPath(i - 6, j); } for (i = 0; i < 10; i++) { history[i] = outputStrDialog->getHistory(i); @@ -782,8 +785,8 @@ void MainWindow::showOutputStreamDialog() if (ui->btnStart->isEnabled()) return; - for (i = 3; i < 5; i++) { - if (!update[i - 3]) continue; + for (i = 6; i < MAXSTRRTK; i++) { + if (!update[i - 6]) continue; rtksvrclosestr(rtksvr, i); @@ -811,11 +814,11 @@ void MainWindow::showLogStreamDialog() trace(3, "showLogStreamDialog\n"); - for (i = 5; i < 8; i++) { - logStrDialog->setStreamEnabled(i - 5, streamEnabled[i]); - logStrDialog->setStreamType(i - 5, streamType [i]); + for (i = 3; i < 6; i++) { + logStrDialog->setStreamEnabled(i - 3, streamEnabled[i]); + logStrDialog->setStreamType(i - 3, streamType [i]); for (j = 0; j < 4; j++) - logStrDialog->setPath(i - 5, j, paths[i][j]); + logStrDialog->setPath(i - 3, j, paths[i][j]); } for (i = 0; i < 10; i++) { logStrDialog->setHistory(i, history[i]); @@ -827,20 +830,20 @@ void MainWindow::showLogStreamDialog() if (logStrDialog->result() != QDialog::Accepted) return; - for (i = 5; i < 8; i++) { - if (streamEnabled[i] != outputStrDialog->getStreamEnabled((i - 5) % 2) || - streamType[i] != outputStrDialog->getStreamType((i - 5) % 2) || - paths[i][0] != outputStrDialog->getPath((i - 3) % 2, 0) || - paths[i][1] != outputStrDialog->getPath((i - 3) % 2, 1) || - paths[i][2] != outputStrDialog->getPath((i - 3) % 2, 2) || - paths[i][3] != outputStrDialog->getPath((i - 3) % 2, 3)) - update[i - 5] = 1; + for (i = 3; i < 6; i++) { + if (streamEnabled[i] != logStrDialog->getStreamEnabled(i - 3) || + streamType[i] != logStrDialog->getStreamType(i - 3) || + paths[i][0] != logStrDialog->getPath(i - 3, 0) || + paths[i][1] != logStrDialog->getPath(i - 3, 1) || + paths[i][2] != logStrDialog->getPath(i - 3, 2) || + paths[i][3] != logStrDialog->getPath(i - 3, 3)) + update[i - 3] = 1; - streamEnabled[i] = logStrDialog->getStreamEnabled(i - 5); - streamType[i] = logStrDialog->getStreamType(i - 5); + streamEnabled[i] = logStrDialog->getStreamEnabled(i - 3); + streamType[i] = logStrDialog->getStreamType(i - 3); for (j = 0; j < 4; j++) - paths[i][j] = logStrDialog->getPath(i - 5, j); + paths[i][j] = logStrDialog->getPath(i - 3, j); } for (i = 0; i < 10; i++) { history[i] = logStrDialog->getHistory(i); @@ -851,8 +854,8 @@ void MainWindow::showLogStreamDialog() if (ui->btnStart->isEnabled()) return; - for (i = 5; i < 8; i++) { - if (!update[i - 5]) continue; + for (i = 3; i < 6; i++) { + if (!update[i - 3]) continue; rtksvrclosestr(rtksvr, i); @@ -1109,12 +1112,12 @@ void MainWindow::expandFromTray() // start rtk server --------------------------------------------------------- void MainWindow::serverStart() { - solopt_t solopt[2]; + solopt_t solopt[RTKSVRNSOL]; 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, j, streamTypes[MAXSTRRTK] = {0}, stropt[8] = {0}; - char *serverPaths[8], *cmds[3] = {0}, *cmds_periodic[3] = {0}, *rcvopts[3] = {0}; + char *serverPaths[MAXSTRRTK], *cmds[3] = {0}, *cmds_periodic[3] = {0}, *rcvopts[3] = {0}; char errmsg[20148]; gtime_t time = timeget(); pcvs_t pcvs; @@ -1155,10 +1158,10 @@ void MainWindow::serverStart() } for (i = 0; i < 3; i++) streamTypes[i] = streamEnabled[i] ? itype[streamType[i]] : STR_NONE; // input stream - for (i = 3; i < 5; i++) streamTypes[i] = streamEnabled[i] ? otype[streamType[i]] : STR_NONE; // output stream - for (i = 5; i < 8; i++) streamTypes[i] = streamEnabled[i] ? otype[streamType[i]] : STR_NONE; // log streams + for (i = 3; i < 6; i++) streamTypes[i] = streamEnabled[i] ? otype[streamType[i]] : STR_NONE; // log streams + for (i = 6; i < MAXSTRRTK; i++) streamTypes[i] = streamEnabled[i] ? otype[streamType[i]] : STR_NONE; // output stream - for (i = 0; i < 8; i++) { + for (i = 0; i < MAXSTRRTK; i++) { serverPaths[i] = new char[1024]; serverPaths[i][0] = '\0'; if (streamTypes[i] == STR_NONE) strncpy(serverPaths[i], "", 1023); @@ -1197,11 +1200,11 @@ void MainWindow::serverStart() strsetdir(optDialog->fileOptions.tempdir); strsetproxy(qPrintable(optDialog->proxyAddress)); - for (i = 3; i < 8; i++) + for (i = 3; i < MAXSTRRTK; i++) if (streamTypes[i] == STR_FILE && !confirmOverwrite(serverPaths[i])) { if (optDialog->solutionOptions.trace > 0) traceclose(); free_pcvs(&rtksvr->pcvsr); - for (j = 0; j < 8; j++) delete[] serverPaths[j]; + for (j = 0; j < MAXSTRRTK; j++) delete[] serverPaths[j]; for (j = 0; j < 3; j++) delete[] rcvopts[j]; for (j = 0; j < 3; j++) if (cmds[j]) delete[] cmds[j]; @@ -1217,9 +1220,9 @@ void MainWindow::serverStart() if (strlen(optDialog->fileOptions.dcb) > 0) readdcb(optDialog->fileOptions.dcb, &rtksvr->nav, NULL); - for (i = 0; i < 2; i++) { + for (i = 0; i < RTKSVRNSOL; i++) { solopt[i] = optDialog->solutionOptions; - solopt[i].posf = inputFormat[i + 3]; + solopt[i].posf = inputFormat[6 + i]; } stropt[0] = optDialog->timeoutTime; stropt[1] = optDialog->reconnectTime; @@ -1238,7 +1241,7 @@ void MainWindow::serverStart() trace(2, "rtksvrstart error %s\n", errmsg); if (optDialog->solutionOptions.trace > 0) traceclose(); free_pcvs(&rtksvr->pcvsr); - for (i = 0; i < 8; i++) delete[] serverPaths[i]; + for (i = 0; i < MAXSTRRTK; i++) delete[] serverPaths[i]; for (i = 0; i < 3; i++) delete[] rcvopts[i]; for (i = 0; i < 3; i++) if (cmds[i]) delete[] cmds[i]; @@ -1247,7 +1250,7 @@ void MainWindow::serverStart() return; } - for (i = 0; i < 8; i++) delete[] serverPaths[i]; + for (i = 0; i < MAXSTRRTK; i++) delete[] serverPaths[i]; for (i = 0; i < 3; i++) delete[] rcvopts[i]; for (i = 0; i < 3; i++) if (cmds[i]) delete[] cmds[i]; @@ -1622,7 +1625,7 @@ void MainWindow::updatePosition() void MainWindow::updateStream() { static const QColor color[] = {QColor(Qt::red), QColor(Qt::white), Color::Orange, Qt::darkGreen, Color::Lime}; - QLabel *ind[MAXSTRRTK] = {ui->lblStream1, ui->lblStream2, ui->lblStream3, ui->lblStream4, ui->lblStream5, ui->lblStream6, ui->lblStream7, ui->lblStream8}; + QLabel *ind[MAXSTRRTK] = {ui->lblStream1, ui->lblStream2, ui->lblStream3, ui->lblStream4, ui->lblStream5, ui->lblStream6, ui->lblStream7, ui->lblStream8, ui->lblStream9}; int i, sstat[MAXSTRRTK] = {0}; char msg[MAXSTRMSG] = ""; @@ -2481,11 +2484,11 @@ void MainWindow::setTrayIcon(int index) void MainWindow::loadOptions() { QSettings settings(iniFile, QSettings::IniFormat); - int i, j, no, strno[] = { 0, 1, 6, 2, 3, 4, 5, 7 }; + int i, j, no, strno[] = { 0, 1, 6, 4, 5, 7, 2, 3, 8 }; trace(3, "loadOptions\n"); - for (i = 0; i < 8; i++) { + for (i = 0; i < MAXSTRRTK; i++) { no = strno[i]; streamEnabled[i] = settings.value(QString("stream/streamc%1").arg(no), 0).toInt(); streamType[i] = settings.value(QString("stream/stream%1").arg(no), 0).toInt(); @@ -2578,13 +2581,13 @@ void MainWindow::loadOptions() void MainWindow::saveOptions() { QSettings settings(iniFile, QSettings::IniFormat); - int i, j, no, strno[] = { 0, 1, 6, 2, 3, 4, 5, 7 }; + int i, j, no, strno[] = { 0, 1, 6, 4, 5, 7, 2, 3, 8 }; trace(3, "saveOptions\n"); optDialog->saveOptions(settings); - for (i = 0; i < 8; i++) { + for (i = 0; i < MAXSTRRTK; i++) { no = strno[i]; settings.setValue(QString("stream/streamc%1").arg(no), streamEnabled[i]); settings.setValue(QString("stream/stream%1").arg(no), streamType[i]); diff --git a/app/qtapp/rtknavi_qt/navimain.ui b/app/qtapp/rtknavi_qt/navimain.ui index 85a09e130..a5455ebd6 100644 --- a/app/qtapp/rtknavi_qt/navimain.ui +++ b/app/qtapp/rtknavi_qt/navimain.ui @@ -242,7 +242,7 @@ - Solution stream 1 + Log stream rover QFrame::Shape::Box @@ -258,7 +258,7 @@ - Solution stream 2 + Log stream base station QFrame::Shape::Box @@ -274,7 +274,7 @@ - Log stream rover + Log stream corrections QFrame::Shape::Box @@ -293,7 +293,7 @@ - Log stream base station + Solution stream 1 QFrame::Shape::Box @@ -309,7 +309,23 @@ - Log stream corrections + Solution stream 2 + + + QFrame::Shape::Box + + + + + + + + 0 + 0 + + + + Solution stream 3 QFrame::Shape::Box @@ -320,7 +336,7 @@ - + 0 @@ -328,15 +344,15 @@ - Define output streams + Define log streams - O + L - + 0 @@ -344,10 +360,10 @@ - Define log streams + Define output streams - L + O diff --git a/app/qtapp/rtknavi_qt/outstrdlg.cpp b/app/qtapp/rtknavi_qt/outstrdlg.cpp index f9745b86d..8407d17ce 100644 --- a/app/qtapp/rtknavi_qt/outstrdlg.cpp +++ b/app/qtapp/rtknavi_qt/outstrdlg.cpp @@ -34,6 +34,12 @@ OutputStrDialog::OutputStrDialog(QWidget *parent) ui->cBFormat2->setItemData(3, "NMEA GPRMC, GPGGA, GPGSA, GLGSA, GAGSA, GPGSV, GLGSV and GAGSV", Qt::ToolTipRole); ui->cBFormat2->setItemData(4, "Solution status", Qt::ToolTipRole); + ui->cBFormat3->setItemData(0, "Latitude, longitude and height", Qt::ToolTipRole); + ui->cBFormat3->setItemData(1, "X/Y/Z components of ECEF coordinates", Qt::ToolTipRole); + ui->cBFormat3->setItemData(2, "E/N/U components of baseline vector", Qt::ToolTipRole); + ui->cBFormat3->setItemData(3, "NMEA GPRMC, GPGGA, GPGSA, GLGSA, GAGSA, GPGSV, GLGSV and GAGSV", Qt::ToolTipRole); + ui->cBFormat3->setItemData(4, "Solution status", Qt::ToolTipRole); + keyDialog = new KeyDialog(this); serialOptDialog = new SerialOptDialog(this); tcpOptDialog = new TcpOptDialog(this); @@ -42,24 +48,31 @@ OutputStrDialog::OutputStrDialog(QWidget *parent) fileModel->setRootPath(""); ui->lEFilePath1->setCompleter(new QCompleter(fileModel, this)); ui->lEFilePath2->setCompleter(new QCompleter(fileModel, this)); + ui->lEFilePath3->setCompleter(new QCompleter(fileModel, this)); // line edit actions QAction *aclEFilePath1Select = ui->lEFilePath1->addAction(QIcon(":/buttons/folder"), QLineEdit::TrailingPosition); aclEFilePath1Select->setToolTip(tr("Select File")); QAction *aclEFilePath2Select = ui->lEFilePath2->addAction(QIcon(":/buttons/folder"), QLineEdit::TrailingPosition); aclEFilePath2Select->setToolTip(tr("Select File")); + QAction *aclEFilePath3Select = ui->lEFilePath3->addAction(QIcon(":/buttons/folder"), QLineEdit::TrailingPosition); + aclEFilePath3Select->setToolTip(tr("Select File")); connect(ui->buttonBox, &QDialogButtonBox::accepted, this, &OutputStrDialog::accept); connect(ui->buttonBox, &QDialogButtonBox::rejected, this, &OutputStrDialog::reject); connect(aclEFilePath1Select, &QAction::triggered, this, &OutputStrDialog::selectFile1); connect(aclEFilePath2Select, &QAction::triggered, this, &OutputStrDialog::selectFile2); + connect(aclEFilePath3Select, &QAction::triggered, this, &OutputStrDialog::selectFile3); connect(ui->btnKey, &QPushButton::clicked, this, &OutputStrDialog::showKeyDialog); connect(ui->btnStream1, &QPushButton::clicked, this, &OutputStrDialog::showStream1Options); connect(ui->btnStream2, &QPushButton::clicked, this, &OutputStrDialog::showStream2Options); + connect(ui->btnStream3, &QPushButton::clicked, this, &OutputStrDialog::showStream2Options); connect(ui->cBStream1, static_cast(&QComboBox::currentIndexChanged), this, &OutputStrDialog::updateEnable); connect(ui->cBStream2, static_cast(&QComboBox::currentIndexChanged), this, &OutputStrDialog::updateEnable); + connect(ui->cBStream3, static_cast(&QComboBox::currentIndexChanged), this, &OutputStrDialog::updateEnable); connect(ui->cBStream1C, &QCheckBox::clicked, this, &OutputStrDialog::updateEnable); connect(ui->cBStream2C, &QCheckBox::clicked, this, &OutputStrDialog::updateEnable); + connect(ui->cBStream3C, &QCheckBox::clicked, this, &OutputStrDialog::updateEnable); ui->cBSwapInterval->setValidator(new QDoubleValidator(this)); } @@ -79,6 +92,13 @@ void OutputStrDialog::selectFile2() ui->lEFilePath2->setText(QDir::toNativeSeparators(filename)); } //--------------------------------------------------------------------------- +void OutputStrDialog::selectFile3() +{ + QString filename = QFileDialog::getSaveFileName(this, tr("Load..."), ui->lEFilePath3->text()); + if (!filename.isEmpty()) + ui->lEFilePath3->setText(QDir::toNativeSeparators(filename)); +} +//--------------------------------------------------------------------------- void OutputStrDialog::showKeyDialog() { keyDialog->show(); @@ -106,6 +126,17 @@ void OutputStrDialog::showStream2Options() } } //--------------------------------------------------------------------------- +void OutputStrDialog::showStream3Options() +{ + switch (ui->cBStream3->currentIndex()) { + case 0: showSerialOptions(1, 0); break; + case 1: showTcpOptions(1, TcpOptDialog::OPT_TCP_CLIENT); break; + case 2: showTcpOptions(1, TcpOptDialog::OPT_TCP_SERVER); break; + case 3: showTcpOptions(1, TcpOptDialog::OPT_NTRIP_SERVER); break; + case 4: showTcpOptions(0, TcpOptDialog::OPT_NTRIP_CASTER_CLIENT); break; + } +} +//--------------------------------------------------------------------------- QString OutputStrDialog::getFilePath(const QString &path) { return path.mid(0, path.indexOf("::")); @@ -157,16 +188,21 @@ void OutputStrDialog::showTcpOptions(int index, int opt) void OutputStrDialog::updateEnable() { int ena = (ui->cBStream1C->isChecked() && (ui->cBStream1->currentIndex() == 5)) || - (ui->cBStream2C->isChecked() && (ui->cBStream2->currentIndex() == 5)); + (ui->cBStream2C->isChecked() && (ui->cBStream2->currentIndex() == 5)) || + (ui->cBStream3C->isChecked() && (ui->cBStream3->currentIndex() == 5)); ui->cBStream1->setEnabled(ui->cBStream1C->isChecked()); ui->cBStream2->setEnabled(ui->cBStream2C->isChecked()); + ui->cBStream3->setEnabled(ui->cBStream3C->isChecked()); ui->btnStream1->setEnabled(ui->cBStream1C->isChecked() && ui->cBStream1->currentIndex() <= 4); ui->btnStream2->setEnabled(ui->cBStream2C->isChecked() && ui->cBStream2->currentIndex() <= 4); + ui->btnStream3->setEnabled(ui->cBStream3C->isChecked() && ui->cBStream3->currentIndex() <= 4); ui->lEFilePath1->setEnabled(ui->cBStream1C->isChecked() && ui->cBStream1->currentIndex() == 5); ui->lEFilePath2->setEnabled(ui->cBStream2C->isChecked() && ui->cBStream2->currentIndex() == 5); + ui->lEFilePath3->setEnabled(ui->cBStream3C->isChecked() && ui->cBStream3->currentIndex() == 5); ui->cBFormat1->setEnabled(ui->cBStream1C->isChecked()); ui->cBFormat2->setEnabled(ui->cBStream2C->isChecked()); + ui->cBFormat3->setEnabled(ui->cBStream3C->isChecked()); ui->lblF1->setEnabled(ena); ui->lblSwapInterval->setEnabled(ena); ui->cBTimeTag->setEnabled(ena); @@ -176,8 +212,8 @@ void OutputStrDialog::updateEnable() //--------------------------------------------------------------------------- void OutputStrDialog::setStreamEnabled(int stream, int enabled) { - QCheckBox *cBStreamC[] = {ui->cBStream1C, ui->cBStream2C}; - if ((stream < 0 ) || (stream > 1)) return; + QCheckBox *cBStreamC[] = {ui->cBStream1C, ui->cBStream2C, ui->cBStream3C}; + if ((stream < 0 ) || (stream > 2)) return; cBStreamC[stream]->setChecked(enabled); @@ -186,16 +222,16 @@ void OutputStrDialog::setStreamEnabled(int stream, int enabled) //--------------------------------------------------------------------------- int OutputStrDialog::getStreamEnabled(int stream) { - QCheckBox *cBStreamC[] = {ui->cBStream1C, ui->cBStream2C}; - if ((stream < 0 ) || (stream > 1)) return false; + QCheckBox *cBStreamC[] = {ui->cBStream1C, ui->cBStream2C, ui->cBStream3C}; + if ((stream < 0 ) || (stream > 2)) return false; return cBStreamC[stream]->isChecked(); } //--------------------------------------------------------------------------- void OutputStrDialog::setStreamType(int stream, int type) { - QComboBox *cBStream[] = {ui->cBStream1, ui->cBStream2}; - if ((stream < 0 ) || (stream > 1)) return; + QComboBox *cBStream[] = {ui->cBStream1, ui->cBStream2, ui->cBStream3}; + if ((stream < 0 ) || (stream > 2)) return; cBStream[stream]->setCurrentIndex(type); @@ -204,8 +240,8 @@ void OutputStrDialog::setStreamType(int stream, int type) //--------------------------------------------------------------------------- void OutputStrDialog::setStreamFormat(int stream, int format) { - QComboBox *cBFormat[] = {ui->cBFormat1, ui->cBFormat2}; - if ((stream < 0 ) || (stream > 1)) return; + QComboBox *cBFormat[] = {ui->cBFormat1, ui->cBFormat2, ui->cBFormat3}; + if ((stream < 0 ) || (stream > 2)) return; cBFormat[stream]->setCurrentIndex(format); updateEnable(); @@ -213,8 +249,8 @@ void OutputStrDialog::setStreamFormat(int stream, int format) //--------------------------------------------------------------------------- int OutputStrDialog::getStreamFormat(int stream) { - QComboBox *cBFormat[] = {ui->cBFormat1, ui->cBFormat2}; - if ((stream < 0 ) || (stream > 1)) return STRFMT_RTCM2; + QComboBox *cBFormat[] = {ui->cBFormat1, ui->cBFormat2, ui->cBFormat3}; + if ((stream < 0 ) || (stream > 2)) return STRFMT_RTCM2; return cBFormat[stream]->currentIndex(); } @@ -222,16 +258,16 @@ int OutputStrDialog::getStreamFormat(int stream) //--------------------------------------------------------------------------- int OutputStrDialog::getStreamType(int stream) { - QComboBox *cBStream[] = {ui->cBStream1, ui->cBStream2}; - if ((stream < 0 ) || (stream > 1)) return STR_NONE; + QComboBox *cBStream[] = {ui->cBStream1, ui->cBStream2, ui->cBStream3}; + if ((stream < 0 ) || (stream > 2)) return STR_NONE; return cBStream[stream]->currentIndex(); }; //--------------------------------------------------------------------------- void OutputStrDialog::setPath(int stream, int type, const QString &path) { - QLineEdit *edits[] = {ui->lEFilePath1, ui->lEFilePath2}; - if ((stream < 0 ) || (stream > 1)) return; + QLineEdit *edits[] = {ui->lEFilePath1, ui->lEFilePath2, ui->lEFilePath3}; + if ((stream < 0 ) || (stream > 2)) return; if ((type < 0) || (type > 3)) return; paths[stream][type] = path; @@ -251,8 +287,8 @@ void OutputStrDialog::setPath(int stream, int type, const QString &path) //--------------------------------------------------------------------------- QString OutputStrDialog::getPath(int stream, int type) { - QLineEdit *edits[] = {ui->lEFilePath1, ui->lEFilePath2}; - if ((stream < 0 ) || (stream > 1)) return ""; + QLineEdit *edits[] = {ui->lEFilePath1, ui->lEFilePath2, ui->lEFilePath3}; + if ((stream < 0 ) || (stream > 2)) return ""; if ((type < 0) || (type > 3)) return ""; if (type == 2) diff --git a/app/qtapp/rtknavi_qt/outstrdlg.h b/app/qtapp/rtknavi_qt/outstrdlg.h index d807e55fb..c68ac20d1 100644 --- a/app/qtapp/rtknavi_qt/outstrdlg.h +++ b/app/qtapp/rtknavi_qt/outstrdlg.h @@ -49,8 +49,10 @@ class OutputStrDialog : public QDialog public slots: void showStream1Options(); void showStream2Options(); + void showStream3Options(); void selectFile1(); void selectFile2(); + void selectFile3(); void showKeyDialog(); void updateEnable(); @@ -62,7 +64,7 @@ public slots: Ui::OutputStrDialog *ui; - QString paths[2][4]; + QString paths[3][4]; QString history[10]; }; diff --git a/app/qtapp/rtknavi_qt/outstrdlg.ui b/app/qtapp/rtknavi_qt/outstrdlg.ui index 7ae2adbf1..02954805c 100644 --- a/app/qtapp/rtknavi_qt/outstrdlg.ui +++ b/app/qtapp/rtknavi_qt/outstrdlg.ui @@ -165,6 +165,13 @@ + + + + Specify file name for third solution data stream + + + @@ -183,30 +190,55 @@ 0 - - - - Enable first output stream for solution data + + + + + 0 + 0 + - (4) Solution 1 + Output Stream - - + + + + Type + + + + + + + Options + + + + + + + Format + + + + + + - Select options for the second solution data stream + Enable first output stream for solution data - ... + (7) Solution 1 - - + + - Select stream type for second solution output stream + Select stream type for first solution output stream @@ -240,30 +272,63 @@ - - + + + + Select options for the first solution data stream + - Type + ... - - - - - 0 - 0 - + + + + Select time and position format for data stream + + + + Lat/Lon/Height + + + + + X/Y/Z-ECEF + + + + + E/N/U-Baseline + + + + + NMEA0183 + + + + + Solution Status + + + + + + + + + Enable second output stream for solution data - Output Stream + (8) Solution 2 - - + + - Select stream type for first solution output stream + Select stream type for second solution output stream @@ -297,74 +362,108 @@ - - + + - Enable second output stream for solution data + Select options for the second solution data stream - (5) Solution 2 + ... - - - - Options + + + + Select time and position format for data stream + + + Lat/Lon/Height + + + + + X/Y/Z-ECEF + + + + + E/N/U-Baseline + + + + + NMEA0183 + + + + + Solution Status + + - - + + + - Select options for the first solution data stream + Enable third output stream for solution data - ... + (9) Solution 3 - - - - Format - - - - - + + - Select time and position format for data stream + Select stream type for third solution output stream - Lat/Lon/Height + Serial - X/Y/Z-ECEF + TCP Client - E/N/U-Baseline + TCP Server - NMEA0183 + NTRIP Server - Solution Status + NTRIP Caster + + + + + File - - + + + + Select options for the third solution data stream + + + ... + + + + + Select time and position format for data stream @@ -395,6 +494,7 @@ + @@ -409,9 +509,14 @@ cBStream2 btnStream2 cBFormat2 + cBStream3C + cBStream3 + btnStream3 + cBFormat3 btnKey lEFilePath1 lEFilePath2 + lEFilePath3 cBTimeTag cBSwapInterval diff --git a/app/winapp/rtknavi/logstrdlg.dfm b/app/winapp/rtknavi/logstrdlg.dfm index 75c843014..af037d286 100644 --- a/app/winapp/rtknavi/logstrdlg.dfm +++ b/app/winapp/rtknavi/logstrdlg.dfm @@ -210,7 +210,7 @@ object LogStrDialog: TLogStrDialog Top = 19 Width = 117 Height = 17 - Caption = '(6) Rover' + Caption = '(3) Rover' TabOrder = 2 OnClick = Stream1CClick end @@ -219,7 +219,7 @@ object LogStrDialog: TLogStrDialog Top = 42 Width = 117 Height = 17 - Caption = '(7) Base Station' + Caption = '(4) Base Station' TabOrder = 5 OnClick = Stream2CClick end @@ -228,7 +228,7 @@ object LogStrDialog: TLogStrDialog Top = 65 Width = 117 Height = 17 - Caption = '(8) Correction' + Caption = '(5) Correction' TabOrder = 13 OnClick = Stream3CClick end diff --git a/app/winapp/rtknavi/mondlg.cpp b/app/winapp/rtknavi/mondlg.cpp index 397f982ac..a51e8c3e5 100644 --- a/app/winapp/rtknavi/mondlg.cpp +++ b/app/winapp/rtknavi/mondlg.cpp @@ -1463,7 +1463,7 @@ void __fastcall TMonitorDialog::SetStr(void) "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}; + int i,width[]={30,95,70,80,35,35,70,70,70,70,220,220}; Tbl->ColCount=12; Tbl->RowCount=2; @@ -1476,9 +1476,10 @@ void __fastcall TMonitorDialog::SetStr(void) //--------------------------------------------------------------------------- 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", + AnsiString ch[MAXSTRRTK + 1]={ + "Input Rover","Input Base","Input Correction", + "Log Rover","Log Base","Log Correction", + "Output Solution 1","Output Solution 2","Output Solution 3", "Monitor" }; AnsiString type[]={ @@ -1492,28 +1493,28 @@ void __fastcall TMonitorDialog::ShowStr(void) }; AnsiString state[]={"Error","-","OK"}; AnsiString s,mode,form; - stream_t stream[9]; - int i,j,format[9]={0}; + stream_t stream[MAXSTRRTK + 1]; + int i,j,format[MAXSTRRTK + 1]={0}; char path[MAXSTRPATH]="",*p,*q,*pp; rtksvrlock(&rtksvr); // lock - for (i=0;i<8;i++) stream[i]=rtksvr.stream[i]; + for (i=0;iRowCount=10; + Tbl->RowCount=1 + MAXSTRRTK + 1; Label->Caption=""; - for (i=0;i<9;i++) { + for (i=0;iCells[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 if (i >= 6) form=outformat[format[i]]; else form="-"; Tbl->Cells[j++][i+1]=form; if (stream[i].mode&STR_MODE_R) mode="R"; else mode=""; diff --git a/app/winapp/rtknavi/navimain.cpp b/app/winapp/rtknavi/navimain.cpp index a0ce89240..a73a77cae 100644 --- a/app/winapp/rtknavi/navimain.cpp +++ b/app/winapp/rtknavi/navimain.cpp @@ -120,8 +120,8 @@ __fastcall TMainForm::TMainForm(TComponent* 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;iStreamC[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=6;iStreamC[i-6]=StreamC[i]; + OutputStrDialog->Stream [i-6]=Stream[i]; + OutputStrDialog->Format [i-6]=Format[i]; + for (j=0;j<4;j++) OutputStrDialog->Paths[i-6][j]=Paths[i][j]; } for (i=0;i<10;i++) { OutputStrDialog->History [i]=History [i]; @@ -741,18 +741,18 @@ void __fastcall TMainForm::BtnOutputStrClick(TObject *Sender) 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=6;iStreamC[i-6]|| + Stream [i]!=OutputStrDialog->Stream[i-6]|| + Format [i]!=OutputStrDialog->Format[i-6]|| + Paths[i][0]!=OutputStrDialog->Paths[i-6][0]|| + Paths[i][1]!=OutputStrDialog->Paths[i-6][1]|| + Paths[i][2]!=OutputStrDialog->Paths[i-6][2]|| + Paths[i][3]!=OutputStrDialog->Paths[i-6][3]) update[i-6]=1; + StreamC[i]=OutputStrDialog->StreamC[i-6]; + Stream [i]=OutputStrDialog->Stream[i-6]; + Format [i]=OutputStrDialog->Format[i-6]; + for (j=0;j<4;j++) Paths[i][j]=OutputStrDialog->Paths[i-6][j]; } for (i=0;i<10;i++) { History [i]=OutputStrDialog->History [i]; @@ -763,8 +763,8 @@ void __fastcall TMainForm::BtnOutputStrClick(TObject *Sender) if (BtnStart->Enabled) return; - for (i=3;i<5;i++) { - if (!update[i-3]) continue; + for (i=6;iStreamC[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=3;i<6;i++) { + LogStrDialog->StreamC[i-3]=StreamC[i]; + LogStrDialog->Stream [i-3]=Stream [i]; + for (j=0;j<4;j++) LogStrDialog->Paths[i-3][j]=Paths[i][j]; } for (i=0;i<10;i++) { LogStrDialog->History [i]=History [i]; @@ -808,16 +808,16 @@ void __fastcall TMainForm::BtnLogStrClick(TObject *Sender) 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=3;i<6;i++) { + if (StreamC[i]!=LogStrDialog->StreamC[i-3]|| + Stream [i]!=LogStrDialog->Stream[i-3]|| + Paths[i][0]!=LogStrDialog->Paths[i-3][0]|| + Paths[i][1]!=LogStrDialog->Paths[i-3][1]|| + Paths[i][2]!=LogStrDialog->Paths[i-3][2]|| + Paths[i][3]!=LogStrDialog->Paths[i-3][3]) update[i-3]=1; + StreamC[i]=LogStrDialog->StreamC[i-3]; + Stream [i]=LogStrDialog->Stream [i-3]; + for (j=0;j<4;j++) Paths[i][j]=LogStrDialog->Paths[i-3][j]; } for (i=0;i<10;i++) { History [i]=LogStrDialog->History [i]; @@ -828,7 +828,7 @@ void __fastcall TMainForm::BtnLogStrClick(TObject *Sender) if (BtnStart->Enabled) return; - for (i=5;i<8;i++) { + for (i=3;i<6;i++) { if (!update[i-5]) continue; rtksvrclosestr(&rtksvr,i); @@ -1114,7 +1114,7 @@ void __fastcall TMainForm::MenuExitClick(TObject *Sender) void __fastcall TMainForm::SvrStart(void) { AnsiString s; - solopt_t solopt[2]; + solopt_t solopt[RTKSVRNSOL]; double pos[3],nmeapos[3]; int itype[]={ STR_SERIAL,STR_TCPCLI,STR_TCPSVR,STR_NTRIPCLI,STR_FILE,STR_FTP,STR_HTTP @@ -1234,9 +1234,9 @@ void __fastcall TMainForm::SvrStart(void) 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++) { + for (i=3;i<6;i++) strs[i]=StreamC[i]?otype[Stream[i]]:STR_NONE; + for (i=6;i0) traceclose(); free_pcvs(&rtksvr.pcvsr); @@ -1280,9 +1280,10 @@ void __fastcall TMainForm::SvrStart(void) if (DCBFileF!="") { readdcb(DCBFileF.c_str(),&rtksvr.nav,NULL); } - for (i=0;i<2;i++) { + + for (i=0;iReadInteger("stream",s.sprintf("streamc%d",no),0); Stream [i]=ini->ReadInteger("stream",s.sprintf("stream%d", no),0); @@ -2693,12 +2694,12 @@ 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}; + int i,j,no,strno[]={0, 1, 6, 4, 5, 7, 2, 3, 8}; char *p; trace(3,"SaveOpt\n"); - for (i=0;i<8;i++) { + for (i=0;iWriteInteger("stream",s.sprintf("streamc%d",no),StreamC[i]); ini->WriteInteger("stream",s.sprintf("stream%d" ,no),Stream [i]); diff --git a/app/winapp/rtknavi/navimain.dfm b/app/winapp/rtknavi/navimain.dfm index 9911304e4..a8a1828fa 100644 --- a/app/winapp/rtknavi/navimain.dfm +++ b/app/winapp/rtknavi/navimain.dfm @@ -1365,9 +1365,9 @@ object MainForm: TMainForm end end object Panel12: TPanel - Left = 469 + Left = 425 Top = 2 - Width = 187 + Width = 198 Height = 23 Align = alRight BevelOuter = bvNone @@ -1592,7 +1592,7 @@ object MainForm: TMainForm TabOrder = 4 end object Str6: TPanel - Left = 105 + Left = 103 Top = 5 Width = 9 Height = 14 @@ -1624,23 +1624,34 @@ object MainForm: TMainForm ParentBackground = False TabOrder = 7 end - object Panel122: TPanel - Left = 134 + object Str9: TPanel + Left = 132 + Top = 5 + Width = 9 + Height = 14 + BevelInner = bvRaised + BevelOuter = bvLowered + Color = clWindow + ParentBackground = False + TabOrder = 7 + end + object Panel123: TPanel + Left = 143 Top = 0 Width = 27 Height = 22 - TabOrder = 10 - object BtnOutputStr: TSpeedButton + TabOrder = 11 + object BtnLogStr: TSpeedButton Left = 1 Top = 0 Width = 25 Height = 21 - Hint = 'Output Streams' + Hint = 'Log Streams' Margins.Left = 2 Margins.Top = 2 Margins.Right = 2 Margins.Bottom = 2 - Caption = 'O' + Caption = 'L' Flat = True Font.Charset = DEFAULT_CHARSET Font.Color = clBlack @@ -1651,26 +1662,26 @@ object MainForm: TMainForm ParentShowHint = False ShowHint = True Spacing = 1 - OnClick = BtnOutputStrClick + OnClick = BtnLogStrClick end end - object Panel123: TPanel - Left = 161 + object Panel122: TPanel + Left = 171 Top = 0 Width = 27 Height = 22 - TabOrder = 11 - object BtnLogStr: TSpeedButton + TabOrder = 10 + object BtnOutputStr: TSpeedButton Left = 1 Top = 0 Width = 25 Height = 21 - Hint = 'Log Streams' + Hint = 'Output Streams' Margins.Left = 2 Margins.Top = 2 Margins.Right = 2 Margins.Bottom = 2 - Caption = 'L' + Caption = 'O' Flat = True Font.Charset = DEFAULT_CHARSET Font.Color = clBlack @@ -1681,7 +1692,7 @@ object MainForm: TMainForm ParentShowHint = False ShowHint = True Spacing = 1 - OnClick = BtnLogStrClick + OnClick = BtnOutputStrClick end end end diff --git a/app/winapp/rtknavi/navimain.h b/app/winapp/rtknavi/navimain.h index 4135aa8d2..fd8b01531 100644 --- a/app/winapp/rtknavi/navimain.h +++ b/app/winapp/rtknavi/navimain.h @@ -66,6 +66,7 @@ class TMainForm : public TForm TPanel *Str6; TPanel *Str7; TPanel *Str8; + TPanel *Str9; TPanel *Svr; TPanel *Panel122; TSpeedButton *BtnOutputStr; diff --git a/app/winapp/rtknavi/naviopt.cpp b/app/winapp/rtknavi/naviopt.cpp index 78fa19289..d085bf6fb 100644 --- a/app/winapp/rtknavi/naviopt.cpp +++ b/app/winapp/rtknavi/naviopt.cpp @@ -24,12 +24,12 @@ static double str2dbl(AnsiString str) return val; } // receiver options table --------------------------------------------------- -static int strtype[]={ /* stream types */ +static int strtype[MAXSTRRTK]={ /* 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 char strpath[MAXSTRRTK][MAXSTR]={""}; /* stream paths */ +static int strfmt[MAXSTRRTK]={ /* stream formats */ + STRFMT_RTCM3,STRFMT_RTCM3,STRFMT_SP3,0,0,0,SOLF_LLH,SOLF_NMEA,SOLF_NMEA }; static int svrcycle =10; /* server cycle (ms) */ static int timeout =10000; /* timeout time (ms) */ @@ -54,29 +54,32 @@ static char proxyaddr[MAXSTR]=""; /* proxy address */ 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-type", 3, (void *)&strtype[1], ISTOPT }, + {"inpstr2-path", 2, (void *)strpath [1], "" }, {"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], "" }, + {"inpstr3-type", 3, (void *)&strtype[2], ISTOPT }, + {"inpstr3-path", 2, (void *)strpath [2], "" }, + {"inpstr3-format", 3, (void *)&strfmt [2], FMTOPT }, + {"logstr1-type", 3, (void *)&strtype[3], OSTOPT }, + {"logstr1-path", 2, (void *)strpath [3], "" }, + {"logstr2-type", 3, (void *)&strtype[4], OSTOPT }, + {"logstr2-path", 2, (void *)strpath [4], "" }, + {"logstr3-type", 3, (void *)&strtype[5], OSTOPT }, + {"logstr3-path", 2, (void *)strpath [5], "" }, + {"outstr1-type", 3, (void *)&strtype[6], OSTOPT }, + {"outstr1-path", 2, (void *)strpath [6], "" }, + {"outstr1-format", 3, (void *)&strfmt [6], SOLOPT }, + {"outstr2-type", 3, (void *)&strtype[7], OSTOPT }, + {"outstr2-path", 2, (void *)strpath [7], "" }, + {"outstr2-format", 3, (void *)&strfmt [7], SOLOPT }, + {"outstr3-type", 3, (void *)&strtype[8], OSTOPT }, + {"outstr3-path", 2, (void *)strpath [8], "" }, + {"outstr3-format", 3, (void *)&strfmt [8], SOLOPT }, {"misc-svrcycle", 0, (void *)&svrcycle, "ms" }, {"misc-timeout", 0, (void *)&timeout, "ms" }, @@ -718,7 +721,7 @@ void __fastcall TOptDialog::LoadOpt(AnsiString file) !loadopts(file.c_str(),rcvopts)) return; getsysopts(&prcopt,&solopt,&filopt); - for (int i=0;i<8;i++) { + for (int i=0;iStreamC[i]=strtype[i]!=STR_NONE; MainForm->Stream[i]=STR_NONE; for (int j=0;j<(i<3?num_itype:num_otype);j++) { @@ -726,7 +729,7 @@ void __fastcall TOptDialog::LoadOpt(AnsiString file) MainForm->Stream[i]=j; break; } - if (i<5) MainForm->Format[i]=strfmt[i]; + if (i<3 || i>=6) MainForm->Format[i]=strfmt[i]; if (strtype[i]==STR_SERIAL) { MainForm->Paths[i][0]=strpath[i]; @@ -912,7 +915,7 @@ void __fastcall TOptDialog::SaveOpt(AnsiString file) solopt_t solopt=solopt_default; filopt_t filopt={""}; - for (int i=0;i<8;i++) { + for (int i=0;iStream[i]]:otype[MainForm->Stream[i]]; strfmt[i]=MainForm->Format[i]; diff --git a/app/winapp/rtknavi/outstrdlg.cpp b/app/winapp/rtknavi/outstrdlg.cpp index d986fcad5..86c7d571c 100644 --- a/app/winapp/rtknavi/outstrdlg.cpp +++ b/app/winapp/rtknavi/outstrdlg.cpp @@ -23,12 +23,16 @@ void __fastcall TOutputStrDialog::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]; Format1 ->ItemIndex=Format[0]; Format2 ->ItemIndex=Format[1]; + Format3 ->ItemIndex=Format[2]; FilePath1->Text =GetFilePath(Paths[0][2]); FilePath2->Text =GetFilePath(Paths[1][2]); + FilePath3->Text =GetFilePath(Paths[2][2]); SwapIntv->Text =SwapInterval; TimeTagC ->Checked =OutTimeTag; UpdateEnable(); @@ -38,12 +42,16 @@ void __fastcall TOutputStrDialog::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; Format[0] =Format1->ItemIndex; Format[1] =Format2->ItemIndex; + Format[2] =Format3->ItemIndex; Paths [0][2]=SetFilePath(FilePath1->Text); Paths [1][2]=SetFilePath(FilePath2->Text); + Paths [2][2]=SetFilePath(FilePath3->Text); SwapInterval=SwapIntv->Text; OutTimeTag =TimeTagC->Checked; } @@ -62,6 +70,13 @@ void __fastcall TOutputStrDialog::BtnFile2Click(TObject *Sender) FilePath2->Text=SaveDialog->FileName; } //--------------------------------------------------------------------------- +void __fastcall TOutputStrDialog::BtnFile3Click(TObject *Sender) +{ + SaveDialog->FileName=FilePath3->Text; + if (!SaveDialog->Execute()) return; + FilePath3->Text=SaveDialog->FileName; +} +//--------------------------------------------------------------------------- void __fastcall TOutputStrDialog::Stream1Change(TObject *Sender) { UpdateEnable(); @@ -72,6 +87,11 @@ void __fastcall TOutputStrDialog::Stream2Change(TObject *Sender) UpdateEnable(); } //--------------------------------------------------------------------------- +void __fastcall TOutputStrDialog::Stream3Change(TObject *Sender) +{ + UpdateEnable(); +} +//--------------------------------------------------------------------------- void __fastcall TOutputStrDialog::Stream1CClick(TObject *Sender) { UpdateEnable(); @@ -82,6 +102,11 @@ void __fastcall TOutputStrDialog::Stream2CClick(TObject *Sender) UpdateEnable(); } //--------------------------------------------------------------------------- +void __fastcall TOutputStrDialog::Stream3CClick(TObject *Sender) +{ + UpdateEnable(); +} +//--------------------------------------------------------------------------- void __fastcall TOutputStrDialog::BtnKeyClick(TObject *Sender) { KeyDialog->ShowModal(); @@ -109,6 +134,17 @@ void __fastcall TOutputStrDialog::BtnStr2Click(TObject *Sender) } } //--------------------------------------------------------------------------- +void __fastcall TOutputStrDialog::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 TOutputStrDialog::GetFilePath(AnsiString path) { char *p,*q,buff[1024]; @@ -157,12 +193,16 @@ void __fastcall TOutputStrDialog::UpdateEnable(void) (Stream2C->Checked&&Stream2->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; LabelF1 ->Enabled=ena; Label1 ->Enabled=ena; Label2 ->Enabled=ena; diff --git a/app/winapp/rtknavi/outstrdlg.dfm b/app/winapp/rtknavi/outstrdlg.dfm index 2f5d0f8ec..d80c6a077 100644 --- a/app/winapp/rtknavi/outstrdlg.dfm +++ b/app/winapp/rtknavi/outstrdlg.dfm @@ -4,7 +4,7 @@ object OutputStrDialog: TOutputStrDialog BorderIcons = [biSystemMenu] BorderStyle = bsDialog Caption = 'Output Streams' - ClientHeight = 158 + ClientHeight = 202 ClientWidth = 393 Color = clWhite Font.Charset = DEFAULT_CHARSET @@ -17,6 +17,13 @@ object OutputStrDialog: TOutputStrDialog OnShow = FormShow PixelsPerInch = 96 TextHeight = 13 + object Label10: TLabel + Left = 44 + Top = 3 + Width = 71 + Height = 13 + Caption = 'Output Stream' + end object Label5: TLabel Left = 169 Top = 3 @@ -31,13 +38,6 @@ object OutputStrDialog: TOutputStrDialog Height = 13 Caption = 'Option' end - object Label10: TLabel - Left = 44 - Top = 3 - Width = 71 - Height = 13 - Caption = 'Output Stream' - end object Label7: TLabel Left = 308 Top = 5 @@ -45,54 +45,14 @@ object OutputStrDialog: TOutputStrDialog Height = 13 Caption = 'Format' end - object LabelF1: TLabel + object Stream1C: TCheckBox Left = 8 - Top = 65 - Width = 83 - Height = 13 - Caption = 'Output File Paths' - end - object BtnKey: TSpeedButton - Left = 190 - Top = 128 - Width = 21 - Height = 23 - Caption = '?' - Flat = True - OnClick = BtnKeyClick - end - object Label1: TLabel - Left = 78 - Top = 132 - Width = 49 - Height = 13 - Caption = 'Swap Intv' - end - object Label2: TLabel - Left = 178 - Top = 132 - Width = 7 - Height = 13 - Caption = 'H' - end - object BtnCancel: TButton - Left = 301 - Top = 127 - Width = 85 - Height = 27 - Caption = '&Cancel' - ModalResult = 2 - TabOrder = 0 - end - object BtnOk: TButton - Left = 213 - Top = 127 - Width = 85 - Height = 27 - Caption = '&OK' - ModalResult = 1 - TabOrder = 1 - OnClick = BtnOkClick + Top = 20 + Width = 120 + Height = 17 + Caption = '(7) Solution 1' + TabOrder = 2 + OnClick = Stream1CClick end object Stream1: TComboBox Left = 133 @@ -127,20 +87,30 @@ object OutputStrDialog: TOutputStrDialog TabOrder = 4 OnClick = BtnStr1Click end - object BtnStr2: TButton - Left = 237 - Top = 40 - Width = 25 - Height = 22 - Caption = '...' - Font.Charset = DEFAULT_CHARSET - Font.Color = clWindowText - Font.Height = -9 - Font.Name = 'Tahoma' - Font.Style = [] - ParentFont = False - TabOrder = 8 - OnClick = BtnStr2Click + object Format1: TComboBox + Left = 278 + Top = 18 + Width = 107 + Height = 21 + Style = csDropDownList + ItemIndex = 0 + TabOrder = 5 + Text = 'Lat/Lon/Height' + Items.Strings = ( + 'Lat/Lon/Height' + 'X/Y/Z-ECEF' + 'E/N/U-Baseline' + 'NMEA0183' + 'Solution Status') + end + object Stream2C: TCheckBox + Left = 8 + Top = 43 + Width = 120 + Height = 17 + Caption = '(8) Solution 2' + TabOrder = 6 + OnClick = Stream2CClick end object Stream2: TComboBox Left = 133 @@ -158,15 +128,28 @@ object OutputStrDialog: TOutputStrDialog 'NTRIP Caster' 'File') end - object Format1: TComboBox + object BtnStr2: TButton + Left = 237 + Top = 40 + Width = 25 + Height = 22 + Caption = '...' + Font.Charset = DEFAULT_CHARSET + Font.Color = clWindowText + Font.Height = -9 + Font.Name = 'Tahoma' + Font.Style = [] + ParentFont = False + TabOrder = 8 + OnClick = BtnStr2Click + end + object Format2: TComboBox Left = 278 - Top = 18 + Top = 41 Width = 107 Height = 21 Style = csDropDownList - ItemIndex = 0 - TabOrder = 5 - Text = 'Lat/Lon/Height' + TabOrder = 9 Items.Strings = ( 'Lat/Lon/Height' 'X/Y/Z-ECEF' @@ -174,13 +157,53 @@ object OutputStrDialog: TOutputStrDialog 'NMEA0183' 'Solution Status') end - object Format2: TComboBox + object Stream3C: TCheckBox + Left = 8 + Top = 66 + Width = 120 + Height = 17 + Caption = '(9) Solution 3' + TabOrder = 10 + OnClick = Stream3CClick + end + object Stream3: TComboBox + Left = 133 + Top = 64 + Width = 103 + Height = 21 + Style = csDropDownList + TabOrder = 11 + OnChange = Stream3Change + Items.Strings = ( + 'Serial' + 'TCP Client' + 'TCP Server' + 'NTRIP Server' + 'NTRIP Caster' + 'File') + end + object BtnStr3: TButton + Left = 237 + Top = 63 + Width = 25 + Height = 22 + Caption = '...' + Font.Charset = DEFAULT_CHARSET + Font.Color = clWindowText + Font.Height = -9 + Font.Name = 'Tahoma' + Font.Style = [] + ParentFont = False + TabOrder = 12 + OnClick = BtnStr3Click + end + object Format3: TComboBox Left = 278 - Top = 41 + Top = 64 Width = 107 Height = 21 Style = csDropDownList - TabOrder = 9 + TabOrder = 13 Items.Strings = ( 'Lat/Lon/Height' 'X/Y/Z-ECEF' @@ -188,16 +211,23 @@ object OutputStrDialog: TOutputStrDialog 'NMEA0183' 'Solution Status') end + object LabelF1: TLabel + Left = 8 + Top = 87 + Width = 83 + Height = 13 + Caption = 'Output File Paths' + end object FilePath1: TEdit Left = 6 - Top = 80 + Top = 103 Width = 355 Height = 21 - TabOrder = 10 + TabOrder = 14 end object BtnFile1: TButton Left = 361 - Top = 79 + Top = 102 Width = 25 Height = 22 Caption = '...' @@ -207,19 +237,19 @@ object OutputStrDialog: TOutputStrDialog Font.Name = 'Tahoma' Font.Style = [] ParentFont = False - TabOrder = 11 + TabOrder = 15 OnClick = BtnFile1Click end object FilePath2: TEdit Left = 6 - Top = 102 + Top = 125 Width = 355 Height = 21 - TabOrder = 12 + TabOrder = 16 end object BtnFile2: TButton Left = 361 - Top = 101 + Top = 124 Width = 25 Height = 22 Caption = '...' @@ -229,41 +259,68 @@ object OutputStrDialog: TOutputStrDialog Font.Name = 'Tahoma' Font.Style = [] ParentFont = False - TabOrder = 13 + TabOrder = 17 OnClick = BtnFile2Click end + object FilePath3: TEdit + Left = 6 + Top = 146 + Width = 355 + Height = 21 + TabOrder = 18 + end + object BtnFile3: TButton + Left = 361 + Top = 145 + Width = 25 + Height = 22 + Caption = '...' + Font.Charset = DEFAULT_CHARSET + Font.Color = clWindowText + Font.Height = -9 + Font.Name = 'Tahoma' + Font.Style = [] + ParentFont = False + TabOrder = 19 + OnClick = BtnFile3Click + end + object BtnKey: TSpeedButton + Left = 190 + Top = 172 + Width = 21 + Height = 23 + Caption = '?' + Flat = True + OnClick = BtnKeyClick + end + object Label1: TLabel + Left = 78 + Top = 176 + Width = 49 + Height = 13 + Caption = 'Swap Intv' + end + object Label2: TLabel + Left = 178 + Top = 176 + Width = 7 + Height = 13 + Caption = 'H' + end object TimeTagC: TCheckBox Left = 8 - Top = 130 + Top = 174 Width = 65 Height = 17 Caption = 'Time-Tag' - TabOrder = 14 - end - object Stream1C: TCheckBox - Left = 8 - Top = 20 - Width = 120 - Height = 17 - Caption = '(4) Solution 1' - TabOrder = 2 - OnClick = Stream1CClick - end - object Stream2C: TCheckBox - Left = 8 - Top = 43 - Width = 120 - Height = 17 - Caption = '(5) Solution 2' - TabOrder = 6 - OnClick = Stream2CClick + TabOrder = 20 end object SwapIntv: TComboBox Left = 130 - Top = 129 + Top = 173 Width = 45 Height = 21 - TabOrder = 15 + TabOrder = 21 Items.Strings = ( '' '0.25' @@ -274,6 +331,25 @@ object OutputStrDialog: TOutputStrDialog '12' '24') end + object BtnCancel: TButton + Left = 301 + Top = 171 + Width = 85 + Height = 27 + Caption = '&Cancel' + ModalResult = 2 + TabOrder = 0 + end + object BtnOk: TButton + Left = 213 + Top = 171 + Width = 85 + Height = 27 + Caption = '&OK' + ModalResult = 1 + TabOrder = 1 + OnClick = BtnOkClick + end object SaveDialog: TSaveDialog Filter = 'All File (*.*)|*.*|Log File (*.log)|*.log|RTCM2 File (*.rtcm2)|*' + diff --git a/app/winapp/rtknavi/outstrdlg.h b/app/winapp/rtknavi/outstrdlg.h index 31f6cc729..05f7b4d38 100644 --- a/app/winapp/rtknavi/outstrdlg.h +++ b/app/winapp/rtknavi/outstrdlg.h @@ -17,22 +17,28 @@ class TOutputStrDialog : public TForm TLabel *Label5; TLabel *Label6; TComboBox *Stream1; + TComboBox *Stream2; + TComboBox *Stream3; TButton *BtnStr1; TButton *BtnStr2; - TComboBox *Stream2; + TButton *BtnStr3; TLabel *Label10; TLabel *Label7; TComboBox *Format1; TComboBox *Format2; + TComboBox *Format3; TButton *BtnFile1; + TButton *BtnFile2; + TButton *BtnFile3; TEdit *FilePath1; TEdit *FilePath2; - TButton *BtnFile2; + TEdit *FilePath3; TLabel *LabelF1; TSaveDialog *SaveDialog; TCheckBox *TimeTagC; TCheckBox *Stream1C; TCheckBox *Stream2C; + TCheckBox *Stream3C; TSpeedButton *BtnKey; TLabel *Label1; TComboBox *SwapIntv; @@ -41,12 +47,16 @@ class TOutputStrDialog : public TForm void __fastcall FormShow(TObject *Sender); void __fastcall BtnStr1Click(TObject *Sender); void __fastcall BtnStr2Click(TObject *Sender); + void __fastcall BtnStr3Click(TObject *Sender); void __fastcall Stream1Change(TObject *Sender); void __fastcall Stream2Change(TObject *Sender); + void __fastcall Stream3Change(TObject *Sender); void __fastcall BtnFile1Click(TObject *Sender); void __fastcall BtnFile2Click(TObject *Sender); + void __fastcall BtnFile3Click(TObject *Sender); void __fastcall Stream1CClick(TObject *Sender); void __fastcall Stream2CClick(TObject *Sender); + void __fastcall Stream3CClick(TObject *Sender); void __fastcall BtnKeyClick(TObject *Sender); private: AnsiString __fastcall GetFilePath(AnsiString path); @@ -55,8 +65,8 @@ class TOutputStrDialog : public TForm 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; + int StreamC[RTKSVRNSOL],Stream[RTKSVRNSOL],Format[RTKSVRNSOL],OutTimeTag,OutAppend; + AnsiString Paths[RTKSVRNSOL][4],SwapInterval; AnsiString History[10]; __fastcall TOutputStrDialog(TComponent* Owner); }; diff --git a/src/rtklib.h b/src/rtklib.h index c19433528..4f1961c4e 100644 --- a/src/rtklib.h +++ b/src/rtklib.h @@ -277,7 +277,10 @@ extern "C" { #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 */ +#ifndef RTKSVRNSOL +#define RTKSVRNSOL 3 // Number of RTK server output streams. +#endif +#define MAXSTRRTK (6 + RTKSVRNSOL) // 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 */ @@ -1311,16 +1314,16 @@ typedef struct { /* RTK server type */ 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} */ + solopt_t solopt[RTKSVRNSOL]; /* output solution options {sol1,sol2,sol3} */ 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 nsb[RTKSVRNSOL]; /* 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 *sbuf[RTKSVRNSOL]; /* 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 */ @@ -1331,7 +1334,7 @@ typedef struct { /* RTK server type */ 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 stream[MAXSTRRTK]; /* streams {rov,base,corr,logr,logb,logc,sol1,sol2,sol3} */ stream_t *moni; /* monitor stream */ uint32_t tick; /* start tick */ rtklib_thread_t thread; /* server thread */ diff --git a/src/rtksvr.c b/src/rtksvr.c index ac45da1c1..9c9294a30 100644 --- a/src/rtksvr.c +++ b/src/rtksvr.c @@ -95,7 +95,7 @@ static void writesol(rtksvr_t *svr, int index) tracet(4,"writesol: index=%d\n",index); - for (i=0;i<2;i++) { + for (i=0;isolopt[i].posf==SOLF_STAT) { /* output solution status */ @@ -107,7 +107,7 @@ static void writesol(rtksvr_t *svr, int index) /* output solution */ n=outsols(buff,&svr->rtk.sol,svr->rtk.rb,svr->solopt+i); } - strwrite(svr->stream+i+3,buff,n); + strwrite(svr->stream+6+i,buff,n); /* save output buffer */ rtksvrlock(svr); @@ -116,7 +116,7 @@ static void writesol(rtksvr_t *svr, int index) /* output extended solution */ n=outsolexs(buff,&svr->rtk.sol,svr->rtk.ssat,svr->solopt+i); - strwrite(svr->stream+i+3,buff,n); + strwrite(svr->stream+6+i,buff,n); /* save output buffer */ rtksvrlock(svr); @@ -658,7 +658,7 @@ static void *rtksvrthread(void *arg) continue; } /* write receiver raw/rtcm data to log stream */ - strwrite(svr->stream+i+5,p,n); + strwrite(svr->stream+i+3,p,n); svr->nb[i]+=n; /* save peek buffer */ @@ -751,7 +751,7 @@ static void *rtksvrthread(void *arg) free_raw (svr->raw +i); free_rtcm(svr->rtcm+i); } - for (i=0;i<2;i++) { + for (i=0;insb[i]=0; free(svr->sbuf[i]); svr->sbuf[i]=NULL; } @@ -776,14 +776,14 @@ extern int rtksvrinit(rtksvr_t *svr) 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; + for (i=0;isolopt[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;insb[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;isbuf[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; @@ -874,11 +874,12 @@ extern void rtksvrunlock(rtksvr_t *svr) {rtklib_unlock(&svr->lock);} * 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 +* types[3]=log stream rover +* types[4]=log stream base station +* types[5]=log stream correction +* types[6]=output stream solution 1 +* types[7]=output stream solution 2 +* types[8]=output stream solution 3 * char *paths I input stream paths * int *format I input stream formats (STRFMT_???) * format[0]=input stream rover @@ -906,6 +907,7 @@ extern void rtksvrunlock(rtksvr_t *svr) {rtklib_unlock(&svr->lock);} * solopt_t *solopt I solution options * solopt[0]=solution 1 options * solopt[1]=solution 2 options +* solopt[2]=solution 3 options * stream_t *moni I monitor stream (NULL: not used) * char *errmsg O error message * return : status (1:ok 0:error) @@ -967,7 +969,7 @@ extern int rtksvrstart(rtksvr_t *svr, int cycle, int buffsize, int *strs, /* connect dgps corrections */ svr->rtcm[i].dgps=svr->nav.dgps; } - for (i=0;i<2;i++) { /* output peek buffer */ + for (i=0;isbuf[i]=(uint8_t *)malloc(buffsize))) { tracet(1,"rtksvrstart: malloc error\n"); sprintf(errmsg,"rtk server malloc error"); @@ -975,7 +977,7 @@ extern int rtksvrstart(rtksvr_t *svr, int cycle, int buffsize, int *strs, } } /* set solution options */ - for (i=0;i<2;i++) { + for (i=0;isolopt[i]=solopt[i]; } /* set base station position */ @@ -993,7 +995,7 @@ extern int rtksvrstart(rtksvr_t *svr, int cycle, int buffsize, int *strs, svr->moni=moni; /* open input streams */ - for (i=0;i<8;i++) { + for (i=0;istream+i,strs[i],rw,paths[i])) { @@ -1020,8 +1022,8 @@ extern int rtksvrstart(rtksvr_t *svr, int cycle, int buffsize, int *strs, 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); + for (i=6;istream+i,svr->solopt+(i-6), prcopt); } /* create rtk server thread */ #ifdef WIN32 @@ -1072,8 +1074,8 @@ extern void rtksvrstop(rtksvr_t *svr, const char **cmds) * 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) +* (3:log rover, 4:log base station, 5:log correction, +* 6:solution 1, 7:solution 2, 8:solution 2) * int str I output/log stream types (STR_???) * char *path I output/log stream path * solopt_t *solopt I solution options @@ -1084,7 +1086,7 @@ extern int rtksvropenstr(rtksvr_t *svr, int index, int str, const char *path, { tracet(3,"rtksvropenstr: index=%d str=%d path=%s\n",index,str,path); - if (index<3||index>7||!svr->state) return 0; + if (index<3||index>=MAXSTRRTK||!svr->state) return 0; rtksvrlock(svr); @@ -1097,11 +1099,11 @@ extern int rtksvropenstr(rtksvr_t *svr, int index, int str, const char *path, rtksvrunlock(svr); return 0; } - if (index<=4) { - svr->solopt[index-3]=*solopt; + if (index >= 6) { + svr->solopt[index - 6] = *solopt; /* write solution header to solution stream */ - writesolhead(svr->stream+index,svr->solopt+(index-3),prcopt); + writesolhead(svr->stream+index,svr->solopt+(index-6),prcopt); } rtksvrunlock(svr); return 1; @@ -1110,15 +1112,15 @@ extern int rtksvropenstr(rtksvr_t *svr, int index, int str, const char *path, * 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) +* (3:log rover, 4:log base station, 5:log correction, +* 6:solution 1, 7:solution 2, 8:solution 2) * 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; + if (index<3||index>=MAXSTRRTK||!svr->state) return; rtksvrlock(svr); @@ -1191,7 +1193,7 @@ extern void rtksvrsstat(rtksvr_t *svr, int *sstat, char *msg) rtksvrunlock(svr); } /* mark current position ------------------------------------------------------- -* open output/log stream +* mark current position * args : rtksvr_t *svr IO rtk server * char *name I marker name * char *comment I comment string @@ -1213,7 +1215,7 @@ extern int rtksvrmark(rtksvr_t *svr, const char *name, const char *comment) tow=time2gpst(svr->rtk.sol.time,&week); ecef2pos(svr->rtk.sol.rr,pos); - for (i=0;i<2;i++) { + for (i=0;isolopt[i].posf==SOLF_STAT) { p+=sprintf(p,"$MARK,%d,%.3f,%d,%.4f,%.4f,%.4f,%s,%s\r\n",week,tow, @@ -1232,7 +1234,7 @@ extern int rtksvrmark(rtksvr_t *svr, const char *name, const char *comment) 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)); + strwrite(svr->stream+6+i,(uint8_t *)buff,(int)(p-buff)); saveoutbuf(svr,(uint8_t *)buff,(int)(p-buff),i); } if (svr->moni) {