diff --git a/app/consapp/rtkrcv/rtkrcv.c b/app/consapp/rtkrcv/rtkrcv.c index 5cfd48e22..fbbe4329e 100644 --- a/app/consapp/rtkrcv/rtkrcv.c +++ b/app/consapp/rtkrcv/rtkrcv.c @@ -364,41 +364,69 @@ static int readcmd(const char *file, char *cmd, int type) fclose(fp); return 1; } -/* read antenna file ---------------------------------------------------------*/ -static void readant(vt_t *vt, prcopt_t *opt, nav_t *nav) -{ - const pcv_t pcv0={0}; - pcvs_t pcvr={0},pcvs={0}; - pcv_t *pcv; - gtime_t time=timeget(); - int i; - - trace(3,"readant:\n"); +/* Read antenna file ---------------------------------------------------------*/ +static void readant(vt_t *vt, prcopt_t *opt, nav_t *nav, pcvs_t *pcvsr) { + trace(3,"readant:\n"); - opt->pcvr[0]=opt->pcvr[1]=pcv0; - if (!*filopt.rcvantp) return; - - if (readpcv(filopt.rcvantp,&pcvr)) { - for (i=0;i<2;i++) { - if (!*opt->anttype[i]) continue; - if (!(pcv=searchpcv(0,opt->anttype[i],time,&pcvr))) { - vt_printf(vt,"no antenna %s in %s",opt->anttype[i],filopt.rcvantp); - continue; - } - opt->pcvr[i]=*pcv; + const pcv_t pcv0 = {0}; + opt->pcvr[0] = opt->pcvr[1] = pcv0; + + if (*filopt.rcvantp) { + gtime_t time = timeget(); + if (readpcv(filopt.rcvantp, pcvsr)) { + for (int i = 0; i < 2; i++) { + if (!*opt->anttype[i] || !strcmp(opt->anttype[i], "*")) continue; + pcv_t *pcv = searchpcv(0, opt->anttype[i], time, pcvsr); + if (!pcv) { + vt_printf(vt, "no antenna %s in %s", opt->anttype[i], filopt.rcvantp); + continue; + } + opt->pcvr[i] = *pcv; + } + } else + vt_printf(vt, "antenna file open error %s", filopt.rcvantp); + } + + if (*filopt.satantp) { + pcvs_t pcvs = {0}; + if (readpcv(filopt.satantp, &pcvs)) { + gtime_t time = timeget(); +#ifdef TRACE + int found[MAXSAT] = {0}, missing = 0; +#endif + for (int i = 0; i < MAXSAT; i++) { + pcv_t *pcv = searchpcv(i + 1, "", time, &pcvs); + if (!pcv) { +#ifdef TRACE + missing++; +#endif + continue; } - } - else vt_printf(vt,"antenna file open error %s",filopt.rcvantp); - - if (readpcv(filopt.satantp,&pcvs)) { - for (i=0;ipcvs[i]=*pcv; + nav->pcvs[i]=*pcv; +#ifdef TRACE + found[i] = 1; +#endif + } + free_pcvs(&pcvs); +#ifdef TRACE + if (missing > 0) { + // Report satellites not found. + char satlst[MAXSAT * 4] = "", *p = satlst; + for (int i = 0; i < MAXSAT; i++) { + if (!found[i]) { + char id[8]; + satno2id(i + 1, id); + int len = strlen(satlst); + if (len + strlen(id) > sizeof(satlst) - 1) continue; + p += sprintf(p, " %s", id); + } } - } - else vt_printf(vt,"antenna file open error %s",filopt.satantp); - - free(pcvr.pcv); free(pcvs.pcv); + trace(2, "Satellites missing pcv in %s:%s\n", filopt.satantp, satlst); + } +#endif + } else + vt_printf(vt, "antenna file open error %s", filopt.satantp); + } } /* start rtk server ----------------------------------------------------------*/ static int startsvr(vt_t *vt) @@ -442,9 +470,9 @@ static int startsvr(vt_t *vt) pos[1]=nmeapos[1]*D2R; pos[2]=nmeapos[2]; pos2ecef(pos,npos); - + /* read antenna file */ - readant(vt,&prcopt,&svr.nav); + readant(vt,&prcopt,&svr.nav,&svr.pcvsr); /* read dcb file */ if (*filopt.dcb) { @@ -488,6 +516,7 @@ static int startsvr(vt_t *vt) 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; @@ -522,7 +551,9 @@ static void stopsvr(vt_t *vt) } #endif if (solopt[0].geoid>0) closegeoid(); - + + free_pcvs(&svr.pcvsr); + vt_printf(vt,"stop rtk server\n"); } /* print time ----------------------------------------------------------------*/ @@ -773,10 +804,10 @@ static void prstatus(vt_t *vt) 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: %.3f %.3f %.3f\n","ant delta rover",del[0],del[1],del[2]); + 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: %.3f %.3f %.3f\n","ant delta base",del[0],del[1],del[2]); + 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]); diff --git a/app/qtapp/appcmn_qt/navi_post_opt.cpp b/app/qtapp/appcmn_qt/navi_post_opt.cpp index b09a42bce..58eeedf84 100644 --- a/app/qtapp/appcmn_qt/navi_post_opt.cpp +++ b/app/qtapp/appcmn_qt/navi_post_opt.cpp @@ -347,6 +347,7 @@ OptDialog::OptDialog(QWidget *parent, int opts) if (options == PostOptions) { refPosModel->item(6)->setFlags(refPosModel->item(6)->flags() & ~Qt::ItemIsEnabled); // disable "RTCM/Raw Antenna Position" + rovPosModel->item(6)->setFlags(refPosModel->item(6)->flags() & ~Qt::ItemIsEnabled); // disable "RTCM/Raw Antenna Position" } else if (options == NaviOptions) { refPosModel->item(4)->setFlags(refPosModel->item(4)->flags() & ~Qt::ItemIsEnabled); // disable "Get from Position File" refPosModel->item(5)->setFlags(refPosModel->item(5)->flags() & ~Qt::ItemIsEnabled); // disable "RINEX Header Position" @@ -656,7 +657,7 @@ void OptDialog::updateOptions() QLineEdit *editu[] = {ui->lERoverPosition1, ui->lERoverPosition2, ui->lERoverPosition3 }; QLineEdit *editr[] = {ui->lEReferencePosition1, ui->lEReferencePosition2, ui->lEReferencePosition3 }; pcvs_t pcvr; - pcv_t *pcv, pcv0; + pcv_t pcv0; gtime_t time = timeget(); memset(&pcvr, 0, sizeof(pcvs_t)); @@ -775,53 +776,53 @@ void OptDialog::updateOptions() processingOptions.rovpos = POSOPT_POS_LLH; if (ui->cBRoverPositionType->currentIndex() < 2) processingOptions.rovpos = POSOPT_POS_LLH; else if (ui->cBRoverPositionType->currentIndex() == 2) processingOptions.rovpos = POSOPT_POS_XYZ; - else if (options == PostOptions) { + else if (options == NaviOptions) { + if (ui->cBRoverPositionType->currentIndex() == 6) processingOptions.rovpos = POSOPT_RTCM; + } else if (options == PostOptions) { processingOptions.rovpos = ui->cBRoverPositionType->currentIndex() - 1; /* 2:single, 3:posfile, 4:rinex */ } + processingOptions.antdel[0][0] = ui->sBRoverAntennaE->value(); + processingOptions.antdel[0][1] = ui->sBRoverAntennaN->value(); + processingOptions.antdel[0][2] = ui->sBRoverAntennaU->value(); if (ui->cBRoverAntennaPcv->isChecked()) { strncpy(processingOptions.anttype[0], qPrintable(ui->cBRoverAntenna->currentText()), 63); - processingOptions.antdel[0][0] = ui->sBRoverAntennaE->value(); - processingOptions.antdel[0][1] = ui->sBRoverAntennaN->value(); - processingOptions.antdel[0][2] = ui->sBRoverAntennaU->value(); } else { strncpy(processingOptions.anttype[0], "", sizeof(processingOptions.anttype[0]) - 1); - processingOptions.antdel[0][0] = 0; - processingOptions.antdel[0][1] = 0; - processingOptions.antdel[0][2] = 0; } + processingOptions.antdel[1][0] = ui->sBReferenceAntennaE->value(); + processingOptions.antdel[1][1] = ui->sBReferenceAntennaN->value(); + processingOptions.antdel[1][2] = ui->sBReferenceAntennaU->value(); if (ui->cBReferenceAntennaPcv->isChecked()) { strncpy(processingOptions.anttype[1], qPrintable(ui->cBReferenceAntenna->currentText()), 63); - processingOptions.antdel[1][0] = ui->sBReferenceAntennaE->value(); - processingOptions.antdel[1][1] = ui->sBReferenceAntennaN->value(); - processingOptions.antdel[1][2] = ui->sBReferenceAntennaU->value(); } else { strncpy(processingOptions.anttype[1], "", sizeof(processingOptions.anttype[1]) - 1); - processingOptions.antdel[1][0] = 0; - processingOptions.antdel[1][1] = 0; - processingOptions.antdel[1][2] = 0; } processingOptions.pcvr[0] = processingOptions.pcvr[1] = pcv0; // initialize antenna PCV - if ((ui->cBRoverAntennaPcv->isChecked() || ui->cBReferenceAntennaPcv->isChecked()) && !readpcv(fileOptions.rcvantp, &pcvr)) { + if ((ui->cBRoverAntennaPcv->isChecked() || ui->cBReferenceAntennaPcv->isChecked()) && + fileOptions.rcvantp[0] != '\0' && !readpcv(fileOptions.rcvantp, &pcvr)) { QMessageBox::warning(this, tr("Error"), tr("Antenna file read error: \"%1\"").arg(fileOptions.rcvantp)); return; } - if (ui->cBRoverAntennaPcv->isChecked() && (processingOptions.anttype[0] != QStringLiteral("*"))) { - if ((pcv = searchpcv(0, processingOptions.anttype[0], time, &pcvr))) + if (ui->cBRoverAntennaPcv->isChecked() && processingOptions.anttype[0] != QStringLiteral("") && + processingOptions.anttype[0] != QStringLiteral("*")) { + pcv_t *pcv = searchpcv(0, processingOptions.anttype[0], time, &pcvr); + if (pcv) processingOptions.pcvr[0] = *pcv; else QMessageBox::warning(this, tr("Error"), tr("No rover antenna PCV: \"%1\"").arg(processingOptions.anttype[0])); } - if (ui->cBReferenceAntennaPcv->isChecked()&& (processingOptions.anttype[1] != QStringLiteral("*"))) { - if ((pcv = searchpcv(0, processingOptions.anttype[1], time, &pcvr))) + if (ui->cBReferenceAntennaPcv->isChecked() && processingOptions.anttype[1] != QStringLiteral("") && + processingOptions.anttype[1] != QStringLiteral("*")) { + pcv_t *pcv = searchpcv(0, processingOptions.anttype[1], time, &pcvr); + if (pcv) processingOptions.pcvr[1] = *pcv; else QMessageBox::warning(this, tr("Error"), tr("No reference station antenna PCV: \"%1\"").arg(processingOptions.anttype[1])); } - if (ui->cBRoverAntennaPcv->isChecked() || ui->cBReferenceAntennaPcv->isChecked()) - free(pcvr.pcv); + free_pcvs(&pcvr); fillExcludedSatellites(&processingOptions, ui->lEExcludedSatellites->text()); processingOptions.maxaveep = ui->sBMaxAveEp->value(); processingOptions.initrst = ui->cBInitRestart->isChecked(); @@ -946,6 +947,7 @@ void OptDialog::updateUi(const prcopt_t &prcopt, const solopt_t &solopt, const f ui->cBRoverPositionType->setCurrentIndex(0); if (prcopt.rovpos == POSOPT_POS_LLH) ui->cBRoverPositionType->setCurrentIndex(0); else if (prcopt.rovpos == POSOPT_POS_XYZ) ui->cBRoverPositionType->setCurrentIndex(2); + else if (prcopt.rovpos == POSOPT_RTCM) ui->cBRoverPositionType->setCurrentIndex(6); ui->cBReferencePositionType->setCurrentIndex(0); if (prcopt.refpos == POSOPT_POS_LLH) ui->cBReferencePositionType->setCurrentIndex(0); @@ -1143,14 +1145,18 @@ void OptDialog::save(const QString &file) else if (options == PostOptions) procOpts.sbassatsel = ui->sBSbasSat->value(); - procOpts.rovpos = ui->cBRoverPositionType->currentIndex() < 2 ? POSOPT_POS_LLH : ui->cBRoverPositionType->currentIndex() == 2 ? POSOPT_POS_XYZ : ui->cBRoverPositionType->currentIndex() - 1; if (options == NaviOptions) { + procOpts.rovpos = POSOPT_POS_LLH; + if (ui->cBRoverPositionType->currentIndex() < 2) procOpts.rovpos = POSOPT_POS_LLH; + else if (ui->cBRoverPositionType->currentIndex() == 2) procOpts.rovpos = POSOPT_POS_XYZ; + else if (ui->cBRoverPositionType->currentIndex() == 6) procOpts.rovpos = POSOPT_RTCM; procOpts.refpos = POSOPT_POS_LLH; if (ui->cBReferencePositionType->currentIndex() < 2) procOpts.refpos = POSOPT_POS_LLH; else if (ui->cBReferencePositionType->currentIndex() == 2) procOpts.refpos = POSOPT_POS_XYZ; else if (ui->cBReferencePositionType->currentIndex() == 3) procOpts.refpos = POSOPT_SINGLE; else if (ui->cBReferencePositionType->currentIndex() == 6) procOpts.refpos = POSOPT_RTCM; } else if (options == PostOptions) { + procOpts.rovpos = ui->cBRoverPositionType->currentIndex() < 2 ? POSOPT_POS_LLH : ui->cBRoverPositionType->currentIndex() == 2 ? POSOPT_POS_XYZ : ui->cBRoverPositionType->currentIndex() - 1; procOpts.refpos = ui->cBReferencePositionType->currentIndex() < 2 ? POSOPT_POS_LLH : ui->cBReferencePositionType->currentIndex() == 2 ? POSOPT_POS_XYZ : ui->cBReferencePositionType->currentIndex() - 1; } procOpts.eratio[0] = ui->sBMeasurementErrorR1->value(); @@ -1741,6 +1747,7 @@ void OptDialog::updateEnable() ui->sBBaselineLen->setEnabled(ui->cBBaselineConstrain->isChecked() && ui->cBPositionMode->currentIndex() == PMODE_MOVEB); ui->sBBaselineSig->setEnabled(ui->cBBaselineConstrain->isChecked() && ui->cBPositionMode->currentIndex() == PMODE_MOVEB); ui->cBRoverPositionType->setEnabled(ui->cBPositionMode->currentIndex() == PMODE_FIXED || ui->cBPositionMode->currentIndex() == PMODE_PPP_FIXED); + setComboBoxItemEnabled(ui->cBRoverPositionType, 6, options == NaviOptions); ui->lERoverPosition1->setEnabled(ui->cBRoverPositionType->isEnabled() && ui->cBRoverPositionType->currentIndex() <= 2); ui->lERoverPosition2->setEnabled(ui->cBRoverPositionType->isEnabled() && ui->cBRoverPositionType->currentIndex() <= 2); ui->lERoverPosition3->setEnabled(ui->cBRoverPositionType->isEnabled() && ui->cBRoverPositionType->currentIndex() <= 2); @@ -1756,21 +1763,37 @@ void OptDialog::updateEnable() ui->btnReferencePosition->setEnabled(ui->cBReferencePositionType->isEnabled() && ui->cBReferencePositionType->currentIndex() <= 2); ui->cBRoverAntennaPcv->setEnabled(rel || ppp); ui->cBRoverAntenna->setEnabled((rel || ppp) && ui->cBRoverAntennaPcv->isChecked()); - ui->sBRoverAntennaE->setEnabled((rel || ppp) && ui->cBRoverAntennaPcv->isChecked() && ui->cBRoverAntenna->currentText()!="*"); - ui->sBRoverAntennaN->setEnabled((rel || ppp) && ui->cBRoverAntennaPcv->isChecked() && ui->cBRoverAntenna->currentText()!="*"); - ui->sBRoverAntennaU->setEnabled((rel || ppp) && ui->cBRoverAntennaPcv->isChecked() && ui->cBRoverAntenna->currentText()!="*"); - ui->lblRoverAntennaD->setEnabled((rel || ppp) && ui->cBRoverAntennaPcv->isChecked() && ui->cBRoverAntenna->currentText()!="*"); ui->cBReferenceAntennaPcv->setEnabled(rel); ui->cBReferenceAntenna->setEnabled(rel && ui->cBReferenceAntennaPcv->isChecked()); - ui->sBReferenceAntennaE->setEnabled(rel && ui->cBReferenceAntennaPcv->isChecked() && ui->cBReferenceAntenna->currentText()!="*"); - ui->sBReferenceAntennaN->setEnabled(rel && ui->cBReferenceAntennaPcv->isChecked() && ui->cBReferenceAntenna->currentText()!="*"); - ui->sBReferenceAntennaU->setEnabled(rel && ui->cBReferenceAntennaPcv->isChecked() && ui->cBReferenceAntenna->currentText()!="*"); - ui->lblReferenceAntennaD->setEnabled(rel && ui->cBReferenceAntennaPcv->isChecked() && ui->cBReferenceAntenna->currentText()!="*"); if (options == NaviOptions) { + // 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. + ui->sBRoverAntennaE->setEnabled(rel || ppp); + ui->sBRoverAntennaN->setEnabled(rel || ppp); + ui->sBRoverAntennaU->setEnabled(rel || ppp); + ui->lblRoverAntennaD->setEnabled(rel || ppp); + ui->sBReferenceAntennaE->setEnabled(rel); + ui->sBReferenceAntennaN->setEnabled(rel); + ui->sBReferenceAntennaU->setEnabled(rel); + ui->lblReferenceAntennaD->setEnabled(rel); ui->lblMaxAveEp->setVisible(ui->cBReferencePositionType->currentIndex() == 3); ui->sBMaxAveEp->setVisible(ui->cBReferencePositionType->currentIndex() == 3); ui->cBInitRestart->setVisible(ui->cBReferencePositionType->currentIndex() == 3); } else { + // For rtkpost, and when setting the antenna and delta automatically, + // this should occur before processing, so disable the delta setting + // here in that case. + int rovp = !ui->cBRoverAntennaPcv->isChecked() || ui->cBRoverAntenna->currentText() != "*"; + ui->sBRoverAntennaE->setEnabled((rel || ppp) && rovp); + ui->sBRoverAntennaN->setEnabled((rel || ppp) && rovp); + ui->sBRoverAntennaU->setEnabled((rel || ppp) && rovp); + ui->lblRoverAntennaD->setEnabled((rel || ppp) && rovp); + int refp = !ui->cBReferenceAntennaPcv->isChecked() || ui->cBReferenceAntenna->currentText() != "*"; + ui->sBReferenceAntennaE->setEnabled(rel && refp); + ui->sBReferenceAntennaN->setEnabled(rel && refp); + ui->sBReferenceAntennaU->setEnabled(rel && refp); + ui->lblReferenceAntennaD->setEnabled(rel && refp); ui->lblMaxAveEp->setVisible(false); ui->sBMaxAveEp->setVisible(false); ui->cBInitRestart->setVisible(false); @@ -1936,8 +1959,6 @@ void OptDialog::readAntennaList() QString currentRoverAntenna, currentReferenceAntenna; int i; - if (!readpcv(qPrintable(ui->lEAntennaPcvFile->text()), &pcvs)) return; - /* Save currently defined antennas */ currentRoverAntenna = ui->cBRoverAntenna->currentText(); currentReferenceAntenna = ui->cBReferenceAntenna->currentText(); @@ -1949,12 +1970,15 @@ void OptDialog::readAntennaList() ui->cBRoverAntenna->addItem(""); ui->cBReferenceAntenna->addItem(""); ui->cBRoverAntenna->addItem("*"); ui->cBReferenceAntenna->addItem("*"); - for (int i = 0; i < pcvs.n; i++) { + if (readpcv(qPrintable(ui->lEAntennaPcvFile->text()), &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; ui->cBRoverAntenna->addItem(pcvs.pcv[i].type); ui->cBReferenceAntenna->addItem(pcvs.pcv[i].type); + } + free_pcvs(&pcvs); } /* Restore previously defined antennas */ @@ -1962,8 +1986,6 @@ void OptDialog::readAntennaList() ui->cBRoverAntenna->setCurrentIndex(i == -1 ? 0 : i); i = ui->cBReferenceAntenna->findText(currentReferenceAntenna); ui->cBReferenceAntenna->setCurrentIndex(i == -1 ? 0 : i); - - free(pcvs.pcv); } //--------------------------------------------------------------------------- void OptDialog::showKeyDialog() diff --git a/app/qtapp/appcmn_qt/navi_post_opt.ui b/app/qtapp/appcmn_qt/navi_post_opt.ui index 863155365..a69e2df57 100644 --- a/app/qtapp/appcmn_qt/navi_post_opt.ui +++ b/app/qtapp/appcmn_qt/navi_post_opt.ui @@ -2392,6 +2392,11 @@ RINEX Header Position + + + RTCM/Raw Antenna Position + + diff --git a/app/qtapp/rtknavi_qt/mondlg.cpp b/app/qtapp/rtknavi_qt/mondlg.cpp index 6d999f1d9..cbe4acf7c 100644 --- a/app/qtapp/rtknavi_qt/mondlg.cpp +++ b/app/qtapp/rtknavi_qt/mondlg.cpp @@ -680,7 +680,7 @@ void MonitorDialog::showRtk() del = rtk->opt.antdel[0]; ui->tWConsole->item(row, 0)->setText(tr("Antenna Delta E/N/U Rover")); - ui->tWConsole->item(row++, 1)->setText(QStringLiteral("%1 m, %2 m, %3 m").arg(del[0], 0, 'f', 3).arg(del[1], 0, 'f', 3).arg(del[2], 0, 'f', 3)); + ui->tWConsole->item(row++, 1)->setText(QStringLiteral("%1 m, %2 m, %3 m").arg(del[0], 0, 'f', 4).arg(del[1], 0, 'f', 4).arg(del[2], 0, 'f', 4)); ui->tWConsole->item(row, 0)->setText(tr("Antenna Type Base Station")); ui->tWConsole->item(row++, 1)->setText(rtk->opt.pcvr[1].type); @@ -693,7 +693,7 @@ void MonitorDialog::showRtk() del = rtk->opt.antdel[1]; ui->tWConsole->item(row, 0)->setText(tr("Antenna Delta E/N/U Base Station")); - ui->tWConsole->item(row++, 1)->setText(QStringLiteral("%1 m, %2 m, %3 m").arg(del[0], 0, 'f', 3).arg(del[1], 0, 'f', 3).arg(del[2], 0, 'f', 3)); + ui->tWConsole->item(row++, 1)->setText(QStringLiteral("%1 m, %2 m, %3 m").arg(del[0], 0, 'f', 4).arg(del[1], 0, 'f', 4).arg(del[2], 0, 'f', 4)); ui->tWConsole->item(row, 0)->setText(tr("Precise Ephemeris Time/# of Epoch")); ui->tWConsole->item(row++, 1)->setText(QStringLiteral("%1-%2 (%3)").arg(s1, s2).arg(ne)); @@ -833,7 +833,7 @@ void MonitorDialog::showSat() ui->tWConsole->item(n, j++)->setText(fix == 1 ? tr("FLOAT") : (fix == 2 ? tr("FIX") : (fix == 3 ? tr("HOLD") : tr("-")))); } for (k = 0; k < nfreq; k++) - ui->tWConsole->item(n, j++)->setText(QString::number(ssat->resp[k], 'f', 2)); + ui->tWConsole->item(n, j++)->setText(QString::number(ssat->resp[k], 'f', 3)); for (k = 0; k < nfreq; k++) ui->tWConsole->item(n, j++)->setText(QString::number(ssat->resc[k], 'f', 4)); for (k = 0; k < nfreq; k++) diff --git a/app/qtapp/rtknavi_qt/navimain.cpp b/app/qtapp/rtknavi_qt/navimain.cpp index 66b0ab252..38237ca8c 100644 --- a/app/qtapp/rtknavi_qt/navimain.cpp +++ b/app/qtapp/rtknavi_qt/navimain.cpp @@ -1118,8 +1118,6 @@ void MainWindow::serverStart() char errmsg[20148]; gtime_t time = timeget(); pcvs_t pcvs; - pcv_t *pcv; - trace(3, "serverStart\n"); memset(&pcvs, 0, sizeof(pcvs_t)); @@ -1131,16 +1129,29 @@ void MainWindow::serverStart() tracelevel(optDialog->solutionOptions.trace); } - if (optDialog->processingOptions.sateph == EPHOPT_PREC || optDialog->processingOptions.sateph == EPHOPT_SSRCOM) { - if (!readpcv(optDialog->fileOptions.satantp, &pcvs)) { + if (optDialog->fileOptions.rcvantp[0] != '\0' && + !readpcv(optDialog->fileOptions.rcvantp, &rtksvr->pcvsr)) { + if (optDialog->solutionOptions.trace > 0) traceclose(); + ui->lblMessage->setText(tr("Receiver antenna file read error: %1").arg(optDialog->fileOptions.rcvantp)); + return; + } + + if (optDialog->processingOptions.sateph == EPHOPT_PREC || + optDialog->processingOptions.sateph == EPHOPT_SSRCOM || + optDialog->processingOptions.mode >= PMODE_PPP_KINEMA) { + if (optDialog->fileOptions.satantp[0] != '\0' && + !readpcv(optDialog->fileOptions.satantp, &pcvs)) { + if (optDialog->solutionOptions.trace > 0) traceclose(); + free_pcvs(&rtksvr->pcvsr); ui->lblMessage->setText(tr("Satellite antenna file read error: %1").arg(optDialog->fileOptions.satantp)); return; } for (i = 0; i < MAXSAT; i++) { - if (!(pcv = searchpcv(i + 1, "", time, &pcvs))) continue; + pcv_t *pcv = searchpcv(i + 1, "", time, &pcvs); + if (!pcv) continue; rtksvr->nav.pcvs[i] = *pcv; } - free(pcvs.pcv); + free_pcvs(&pcvs); } for (i = 0; i < 3; i++) streamTypes[i] = streamEnabled[i] ? itype[streamType[i]] : STR_NONE; // input stream @@ -1188,6 +1199,8 @@ void MainWindow::serverStart() for (i = 3; i < 8; 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 < 3; j++) delete[] rcvopts[j]; for (j = 0; j < 3; j++) @@ -1223,7 +1236,8 @@ void MainWindow::serverStart() &optDialog->processingOptions, solopt, &monistr, errmsg)) { trace(2, "rtksvrstart error %s\n", errmsg); - traceclose(); + if (optDialog->solutionOptions.trace > 0) traceclose(); + free_pcvs(&rtksvr->pcvsr); for (i = 0; i < 8; i++) delete[] serverPaths[i]; for (i = 0; i < 3; i++) delete[] rcvopts[i]; for (i = 0; i < 3; i++) @@ -1291,6 +1305,8 @@ void MainWindow::serverStop() } rtksvrstop(rtksvr, (const char **)cmds); + free_pcvs(&rtksvr->pcvsr); + for (i = 0; i < 3; i++) delete[] cmds[i]; ui->btnStart->setVisible(true); diff --git a/app/winapp/rtknavi/navimain.cpp b/app/winapp/rtknavi/navimain.cpp index fbfaf8893..2ddc59646 100644 --- a/app/winapp/rtknavi/navimain.cpp +++ b/app/winapp/rtknavi/navimain.cpp @@ -1126,8 +1126,8 @@ void __fastcall TMainForm::SvrStart(void) char file[1024],*type,errmsg[20148]; FILE *fp; gtime_t time=timeget(); - pcvs_t pcvr={0},pcvs={0}; - pcv_t *pcv,pcv0={0}; + pcvs_t pcvs={0}; + pcv_t pcv0={0}; trace(3,"SvrStart\n"); @@ -1172,49 +1172,56 @@ void __fastcall TMainForm::SvrStart(void) PrcOpt.exsats[sat-1]=ex; } } - if ((RovAntPcvF||RefAntPcvF)&&!readpcv(AntPcvFileF.c_str(),&pcvr)) { + 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 - if (RovAntPcvF) { + 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(); - if ((pcv=searchpcv(0,type,time,&pcvr))) { + 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[0][i]=RovAntDel[i]; } - if (RefAntPcvF) { + + 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(); - if ((pcv=searchpcv(0,type,time,&pcvr))) { + 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; } - for (i=0;i<3;i++) PrcOpt.antdel[1][i]=RefAntDel[i]; - } - if (RovAntPcvF||RefAntPcvF) { - free(pcvr.pcv); } - if (PrcOpt.sateph==EPHOPT_PREC||PrcOpt.sateph==EPHOPT_SSRCOM) { - if (!readpcv(SatPcvFileF.c_str(),&pcvs)) { + + 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); @@ -1286,7 +1297,8 @@ void __fastcall TMainForm::SvrStart(void) (const char **)rcvopts,NmeaCycle,NmeaReq,nmeapos,&PrcOpt, solopt,&monistr,errmsg)) { trace(2,"rtksvrstart error %s\n",errmsg); - traceclose(); + if (SolOpt.trace>0) traceclose(); + free_pcvs(&rtksvr.pcvsr); return; } PSol=PSolS=PSolE=0; @@ -1330,6 +1342,8 @@ void __fastcall TMainForm::SvrStop(void) } rtksvrstop(&rtksvr,(const char **)cmds); + free_pcvs(&rtksvr.pcvsr); + BtnStart ->Visible=true; BtnStart ->Enabled=true; BtnOpt ->Enabled=true; diff --git a/app/winapp/rtknavi/naviopt.cpp b/app/winapp/rtknavi/naviopt.cpp index a45dcbe7c..1ca347de0 100644 --- a/app/winapp/rtknavi/naviopt.cpp +++ b/app/winapp/rtknavi/naviopt.cpp @@ -860,6 +860,7 @@ void __fastcall TOptDialog::LoadOpt(AnsiString file) 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; @@ -1102,6 +1103,7 @@ void __fastcall TOptDialog::SaveOpt(AnsiString file) 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; @@ -1141,8 +1143,8 @@ void __fastcall TOptDialog::UpdateEnable(void) Freq ->Enabled=prec; DynamicModel ->Enabled=prec; TideCorr ->Enabled=prec; - PosOpt1 ->Enabled=ppp; - PosOpt2 ->Enabled=ppp; + PosOpt1 ->Enabled=rel||ppp; + PosOpt2 ->Enabled=rel||ppp; PosOpt3 ->Enabled=ppp; PosOpt4 ->Enabled=ppp; PosOpt6 ->Enabled=ppp; @@ -1189,18 +1191,17 @@ void __fastcall TOptDialog::UpdateEnable(void) 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; - RovAntE ->Enabled=(rel||ppp)&&RovAntPcv->Checked&&RovAnt->Text!="*"; - RovAntN ->Enabled=(rel||ppp)&&RovAntPcv->Checked&&RovAnt->Text!="*"; - RovAntU ->Enabled=(rel||ppp)&&RovAntPcv->Checked&&RovAnt->Text!="*"; - LabelRovAntD ->Enabled=(rel||ppp)&&RovAntPcv->Checked&&RovAnt->Text!="*"; RefAntPcv ->Enabled=rel; RefAnt ->Enabled=rel&&RefAntPcv->Checked; - RefAntE ->Enabled=rel&&RefAntPcv->Checked&&RefAnt->Text!="*"; - RefAntN ->Enabled=rel&&RefAntPcv->Checked&&RefAnt->Text!="*"; - RefAntU ->Enabled=rel&&RefAntPcv->Checked&&RefAnt->Text!="*"; - LabelRefAntD ->Enabled=rel&&RefAntPcv->Checked&&RefAnt->Text!="*"; + 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; @@ -1284,22 +1285,21 @@ void __fastcall TOptDialog::ReadAntList(void) pcvs_t pcvs={0}; char *p; - if (!readpcv(AntPcvFile_Text.c_str(),&pcvs)) return; - list=new TStringList; list->Add(""); list->Add("*"); - for (int i=0;i0&&!strcmp(pcvs.pcv[i].type,pcvs.pcv[i-1].type)) continue; - list->Add(pcvs.pcv[i].type); - } + 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; - - free(pcvs.pcv); } //--------------------------------------------------------------------------- void __fastcall TOptDialog::NavSys6Click(TObject *Sender) diff --git a/app/winapp/rtknavi/naviopt.dfm b/app/winapp/rtknavi/naviopt.dfm index 610c8b64d..0be0683e1 100644 --- a/app/winapp/rtknavi/naviopt.dfm +++ b/app/winapp/rtknavi/naviopt.dfm @@ -1316,7 +1316,8 @@ object OptDialog: TOptDialog Items.Strings = ( 'Lat/Lon/Height (deg/m)' 'Lat/Lon/Height (dms/m)' - 'X/Y/Z-ECEF (m)') + 'X/Y/Z-ECEF (m)' + 'RTCM/Raw Antenna Position') end object BtnRovPos: TButton Left = 371 diff --git a/app/winapp/rtkpost/postmain.cpp b/app/winapp/rtkpost/postmain.cpp index b870480e7..0f9ff0258 100644 --- a/app/winapp/rtkpost/postmain.cpp +++ b/app/winapp/rtkpost/postmain.cpp @@ -1042,17 +1042,17 @@ int __fastcall TMainForm::GetOption(prcopt_t &prcopt, solopt_t &solopt, } 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[0][0]=RovAntE; - prcopt.antdel[0][1]=RovAntN; - prcopt.antdel[0][2]=RovAntU; } + prcopt.antdel[1][0]=RefAntE; + prcopt.antdel[1][1]=RefAntN; + prcopt.antdel[1][2]=RefAntU; if (RefAntPcv) { strcpy(prcopt.anttype[1],RefAnt.c_str()); - prcopt.antdel[1][0]=RefAntE; - prcopt.antdel[1][1]=RefAntN; - prcopt.antdel[1][2]=RefAntU; } if (ExSats!="") { // excluded satellites strcpy(buff,ExSats.c_str()); diff --git a/app/winapp/rtkpost/postopt.cpp b/app/winapp/rtkpost/postopt.cpp index 37b47702b..77ec54250 100644 --- a/app/winapp/rtkpost/postopt.cpp +++ b/app/winapp/rtkpost/postopt.cpp @@ -943,8 +943,8 @@ void __fastcall TOptDialog::UpdateEnable(void) PosMode->ItemIndex==PMODE_PPP_KINEMA; TideCorr ->Enabled=rel||ppp; //IonoOpt ->Enabled=!ppp; - PosOpt1 ->Enabled=ppp; - PosOpt2 ->Enabled=ppp; + PosOpt1 ->Enabled=rel||ppp; + PosOpt2 ->Enabled=rel||ppp; PosOpt3 ->Enabled=ppp; PosOpt4 ->Enabled=ppp; PosOpt6 ->Enabled=ppp; @@ -993,18 +993,23 @@ void __fastcall TOptDialog::UpdateEnable(void) 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; - RovAntE ->Enabled=(rel||ppp)&&RovAntPcv->Checked&&RovAnt->Text!="*"; - RovAntN ->Enabled=(rel||ppp)&&RovAntPcv->Checked&&RovAnt->Text!="*"; - RovAntU ->Enabled=(rel||ppp)&&RovAntPcv->Checked&&RovAnt->Text!="*"; - LabelRovAntD ->Enabled=(rel||ppp)&&RovAntPcv->Checked&&RovAnt->Text!="*"; + 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; - RefAntE ->Enabled=rel&&RefAntPcv->Checked&&RefAnt->Text!="*"; - RefAntN ->Enabled=rel&&RefAntPcv->Checked&&RefAnt->Text!="*"; - RefAntU ->Enabled=rel&&RefAntPcv->Checked&&RefAnt->Text!="*"; - LabelRefAntD ->Enabled=rel&&RefAntPcv->Checked&&RefAnt->Text!="*"; + 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; @@ -1082,22 +1087,21 @@ void __fastcall TOptDialog::ReadAntList(void) pcvs_t pcvs={0}; char *p; - if (!readpcv(AntPcvFile_Text.c_str(),&pcvs)) return; - list=new TStringList; list->Add(""); list->Add("*"); - for (int i=0;i0&&!strcmp(pcvs.pcv[i].type,pcvs.pcv[i-1].type)) continue; - list->Add(pcvs.pcv[i].type); - } + 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; - - free(pcvs.pcv); } //--------------------------------------------------------------------------- void __fastcall TOptDialog::BtnHelpClick(TObject *Sender) diff --git a/data/config/demo5_m8n_1hz.conf b/data/config/demo5_m8n_1hz.conf index 93a92ecda..bed2128d4 100644 --- a/data/config/demo5_m8n_1hz.conf +++ b/data/config/demo5_m8n_1hz.conf @@ -84,7 +84,7 @@ stats-prniono =0.001 # (m) stats-prntrop =0.0001 # (m) stats-prnpos =0 # (m) stats-clkstab =5e-12 # (s/s) -ant1-postype =rinexhead # (0:llh,1:xyz,2:single,3:posfile,4:rinexhead,5:rtcm,6:raw) +ant1-postype =rinexhead # (0:llh,1:xyz,2:single,3:posfile,4:rinexhead,5:rtcm) ant1-pos1 =0 # (deg|m) ant1-pos2 =0 # (deg|m) ant1-pos3 =0 # (m|m) @@ -92,7 +92,7 @@ ant1-anttype = ant1-antdele =0 # (m) ant1-antdeln =0 # (m) ant1-antdelu =0 # (m) -ant2-postype =rinexhead # (0:llh,1:xyz,2:single,3:posfile,4:rinexhead,5:rtcm,6:raw) +ant2-postype =rinexhead # (0:llh,1:xyz,2:single,3:posfile,4:rinexhead,5:rtcm) ant2-pos1 =0 # (deg|m) ant2-pos2 =0 # (deg|m) ant2-pos3 =0 # (m|m) diff --git a/data/config/demo5_m8t_5hz.conf b/data/config/demo5_m8t_5hz.conf index 9f45a33fb..f325d266b 100644 --- a/data/config/demo5_m8t_5hz.conf +++ b/data/config/demo5_m8t_5hz.conf @@ -83,7 +83,7 @@ stats-prniono =0.001 # (m) stats-prntrop =0.0001 # (m) stats-prnpos =0 # (m) stats-clkstab =5e-12 # (s/s) -ant1-postype =rinexhead # (0:llh,1:xyz,2:single,3:posfile,4:rinexhead,5:rtcm,6:raw) +ant1-postype =rinexhead # (0:llh,1:xyz,2:single,3:posfile,4:rinexhead,5:rtcm ant1-pos1 =0 # (deg|m) ant1-pos2 =0 # (deg|m) ant1-pos3 =0 # (m|m) @@ -91,7 +91,7 @@ ant1-anttype = ant1-antdele =0 # (m) ant1-antdeln =0 # (m) ant1-antdelu =0 # (m) -ant2-postype =rinexhead # (0:llh,1:xyz,2:single,3:posfile,4:rinexhead,5:rtcm,6:raw) +ant2-postype =rinexhead # (0:llh,1:xyz,2:single,3:posfile,4:rinexhead,5:rtcm) ant2-pos1 =0 # (deg|m) ant2-pos2 =0 # (deg|m) ant2-pos3 =0 # (m|m) diff --git a/data/config/f9p_ppk.conf b/data/config/f9p_ppk.conf index 0b0d14924..464ad142c 100644 --- a/data/config/f9p_ppk.conf +++ b/data/config/f9p_ppk.conf @@ -90,7 +90,7 @@ stats-prniono =0.001 # (m) stats-prntrop =0.0001 # (m) stats-prnpos =0 # (m) stats-clkstab =5e-12 # (s/s) -ant1-postype =llh # (0:llh,1:xyz,2:single,3:posfile,4:rinexhead,5:rtcm,6:raw) +ant1-postype =llh # (0:llh,1:xyz,2:single,3:posfile,4:rinexhead,5:rtcm) ant1-pos1 =90 # (deg|m) ant1-pos2 =0 # (deg|m) ant1-pos3 =-6335367.6285 # (m|m) @@ -98,7 +98,7 @@ ant1-anttype = ant1-antdele =0 # (m) ant1-antdeln =0 # (m) ant1-antdelu =0 # (m) -ant2-postype =rinexhead # (0:llh,1:xyz,2:single,3:posfile,4:rinexhead,5:rtcm,6:raw) +ant2-postype =rinexhead # (0:llh,1:xyz,2:single,3:posfile,4:rinexhead,5:rtcm) ant2-pos1 =0 # (deg|m) ant2-pos2 =0 # (deg|m) ant2-pos3 =0 # (m|m) diff --git a/data/config/rtknavi_example.conf b/data/config/rtknavi_example.conf index c89f71c84..e0b08d63b 100644 --- a/data/config/rtknavi_example.conf +++ b/data/config/rtknavi_example.conf @@ -90,7 +90,7 @@ stats-prniono =0.001 # (m) stats-prntrop =0.0001 # (m) stats-prnpos =0 # (m) stats-clkstab =5e-12 # (s/s) -ant1-postype =llh # (0:llh,1:xyz,2:single,3:posfile,4:rinexhead,5:rtcm,6:raw) +ant1-postype =llh # (0:llh,1:xyz,2:single,3:posfile,4:rinexhead,5:rtcm) ant1-pos1 =0 # (deg|m) ant1-pos2 =0 # (deg|m) ant1-pos3 =0 # (m|m) @@ -98,7 +98,7 @@ ant1-anttype = ant1-antdele =0 # (m) ant1-antdeln =0 # (m) ant1-antdelu =0 # (m) -ant2-postype =single # (0:llh,1:xyz,2:single,3:posfile,4:rinexhead,5:rtcm,6:raw) +ant2-postype =single # (0:llh,1:xyz,2:single,3:posfile,4:rinexhead,5:rtcm) ant2-pos1 =0 # (deg|m) ant2-pos2 =0 # (deg|m) ant2-pos3 =0 # (m|m) diff --git a/src/options.c b/src/options.c index d10c97aa6..5bfecba87 100644 --- a/src/options.c +++ b/src/options.c @@ -60,7 +60,7 @@ static char snrmask_[NFREQ][1024]; #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,6:raw" +#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" diff --git a/src/postpos.c b/src/postpos.c index f71afc67a..eb1d7ff16 100644 --- a/src/postpos.c +++ b/src/postpos.c @@ -925,8 +925,8 @@ static void closeses(nav_t *nav, pcvs_t *pcvs, pcvs_t *pcvr) trace(3,"closeses:\n"); /* free antenna parameters */ - free(pcvs->pcv); pcvs->pcv=NULL; pcvs->n=pcvs->nmax=0; - free(pcvr->pcv); pcvr->pcv=NULL; pcvr->n=pcvr->nmax=0; + free_pcvs(pcvs); + free_pcvs(pcvr); /* close geoid data */ closegeoid(); diff --git a/src/preceph.c b/src/preceph.c index 9813c372f..682b73ae5 100644 --- a/src/preceph.c +++ b/src/preceph.c @@ -353,23 +353,24 @@ extern void readsp3(const char *file, nav_t *nav, int opt) * return : status (1:ok,0:error) * notes : only support antex format for the antenna parameter file *-----------------------------------------------------------------------------*/ -extern int readsap(const char *file, gtime_t time, nav_t *nav) -{ - pcvs_t pcvs={0}; - pcv_t pcv0={0},*pcv; - int i; - - char tstr[40]; - trace(3,"readsap : file=%s time=%s\n",file,time2str(time,tstr,0)); +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)); - if (!readpcv(file,&pcvs)) return 0; + pcvs_t pcvs = {0}; + if (!readpcv(file, &pcvs)) return 0; - for (i=0;ipcvs[i]=pcv?*pcv:pcv0; + for (int i = 0; i < MAXSAT; i++) { + pcv_t *pcv = searchpcv(i + 1, "", time, &pcvs); + if (pcv) + nav->pcvs[i] = *pcv; + else { + pcv_t pcv0 = {0}; + nav->pcvs[i] = pcv0; } - free(pcvs.pcv); - return 1; + } + free_pcvs(&pcvs); + return 1; } /* read DCB parameters from DCB file ------------------------------------------- * - supports satellite and receiver biases diff --git a/src/rtkcmn.c b/src/rtkcmn.c index c40ce405a..3adfcaa6e 100644 --- a/src/rtkcmn.c +++ b/src/rtkcmn.c @@ -3927,6 +3927,12 @@ extern void antmodel_s(const pcv_t *pcv, double nadir, double *dant) } trace(4,"antmodel_s: dant=%6.3f %6.3f\n",dant[0],dant[1]); } +// Free the pcv array. +void free_pcvs(pcvs_t *pcvs) { + free(pcvs->pcv); + pcvs->pcv = NULL; + pcvs->n = pcvs->nmax = 0; +} /* Sun and moon position in ECI (ref [4] 5.1.1, 5.2.1) -----------------------*/ int epv00(double date1, double date2, double pvh[2][3], double pvb[2][3]); diff --git a/src/rtklib.h b/src/rtklib.h index 162b062b4..a47483628 100644 --- a/src/rtklib.h +++ b/src/rtklib.h @@ -1345,6 +1345,7 @@ typedef struct { /* RTK server type */ 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; @@ -1583,6 +1584,7 @@ EXPORT pcv_t *searchpcv(int sat, const char *type, gtime_t time, 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, diff --git a/src/rtksvr.c b/src/rtksvr.c index f6e8102ac..cc888b784 100644 --- a/src/rtksvr.c +++ b/src/rtksvr.c @@ -254,42 +254,61 @@ static void update_ionutc(rtksvr_t *svr, nav_t *nav, int index) } svr->nmsg[index][2]++; } -/* update antenna position ---------------------------------------------------*/ -static void update_antpos(rtksvr_t *svr, int index) -{ - sta_t *sta; - double pos[3],del[3]={0},dr[3]; - int i; +// Update antenna position --------------------------------------------------- +static void update_antpos(rtksvr_t *svr, int index) { + sta_t *sta; + if (svr->format[index] == STRFMT_RTCM2 || svr->format[index] == STRFMT_RTCM3) { + sta = &svr->rtcm[index].sta; + } else { + sta = &svr->raw[index].sta; + } + 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]); + } + 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]); + } - if (svr->rtk.opt.refpos==POSOPT_RTCM&&index==1) { - if (svr->format[1]==STRFMT_RTCM2||svr->format[1]==STRFMT_RTCM3) { - sta=&svr->rtcm[1].sta; - } - else { - sta=&svr->raw[1].sta; - } - /* update base station position */ - for (i=0;i<3;i++) { - svr->rtk.rb[i]=sta->pos[i]; - } - /* antenna delta */ - ecef2pos(svr->rtk.rb,pos); - if (sta->deltype) { /* xyz */ - del[2]=sta->hgt; - enu2ecef(pos,del,dr); - for (i=0;i<3;i++) { - svr->rtk.rb[i]+=sta->del[i]+dr[i]; - } - } - else { /* enu */ - enu2ecef(pos,sta->del,dr); - for (i=0;i<3;i++) { - svr->rtk.rb[i]+=dr[i]; - } - } - } - svr->nmsg[index][4]++; + // Antenna type and delta. These are updated independently of the antenna + // marker position above when the anttype is "*". + if (strcmp(svr->rtk.opt.anttype[index], "*") == 0) { + if (sta->antdes[0] != '\0' && strcmp(svr->rtk.opt.pcvr[index].type, sta->antdes) != 0) { + // Antenna type is to be set from the RTCM stream, and does not match + // the current pcv_t type, so search for this pcv. + pcv_t *pcv = searchpcv(0, sta->antdes, utc2gpst(timeget()), &svr->pcvsr); + if (!pcv) { + tracet(2, "antenna index=%d no '%s'\n", index, sta->antdes); + } else { + tracet(2, "updated antenna index=%d to '%s'\n", index, sta->antdes); + svr->rtk.opt.pcvr[index] = *pcv; + } + } + // Update the delta from the marker position to the antenna ARP, taking + // into account the RCTM antenna height. This overrides any config delta + // values which are ignored in this path. + if (sta->deltype == 1) { // XYZ + // Convert to the antdel ENU, adding the height. + // Need at least an approx position to map the delta. + if (norm(sta->pos, 3) > 0.0) { + double pos[3]; + ecef2pos(sta->pos, pos); + ecef2enu(pos, sta->del, svr->rtk.opt.antdel[index]); + svr->rtk.opt.antdel[index][2] += sta->hgt; + } + } else { // ENU + for (int i = 0; i < 3; i++) svr->rtk.opt.antdel[index][i] = sta->del[i]; + 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->nmsg[index][4]++; +} /* update ssr corrections ----------------------------------------------------*/ static void update_ssr(rtksvr_t *svr, int index) {