Changeset 1044 in ntrip for trunk/BNC/RTCM/RTCM2Decoder.cpp


Ignore:
Timestamp:
Aug 19, 2008, 11:36:54 AM (16 years ago)
Author:
zdenek
Message:

Zdenek Lukes: a) added logic for RTCM 2.3 messages 20/21 decoding

b) added logic for cycle slip flags (slip counters or lock time indicators) handling

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/BNC/RTCM/RTCM2Decoder.cpp

    r1029 r1044  
    3939 * -----------------------------------------------------------------------*/
    4040
     41#include <math.h>
     42#include <sstream>
     43#include <iomanip>
     44
    4145#include "../bncutils.h"
     46#include "rtcm_utils.h"
    4247#include "GPSDecoder.h"
    4348#include "RTCM2Decoder.h"
    4449
    4550using namespace std;
     51using namespace rtcm2;
    4652
    4753//
     
    4955//
    5056
    51 RTCM2Decoder::RTCM2Decoder() {
    52 
     57RTCM2Decoder::RTCM2Decoder(const std::string& ID) {
     58  _ID = ID;
    5359}
    5460
     
    5864
    5965RTCM2Decoder::~RTCM2Decoder() {
    60 }
    61 
    62 //
    63 
     66  for (t_pairMap::iterator ii = _ephPair.begin(); ii != _ephPair.end(); ii++) {
     67    delete ii->second;
     68  }
     69}
     70
     71
     72//
     73t_irc RTCM2Decoder::getStaCrd(double& xx, double& yy, double& zz) {
     74  if ( !_msg03.validMsg ) {
     75    return failure;
     76  }
     77 
     78  xx = _msg03.x + (_msg22.validMsg ? _msg22.dL1[0] : 0.0);
     79  yy = _msg03.y + (_msg22.validMsg ? _msg22.dL1[1] : 0.0);
     80  zz = _msg03.z + (_msg22.validMsg ? _msg22.dL1[2] : 0.0);
     81
     82  return success;
     83}
     84
     85
     86//
    6487t_irc RTCM2Decoder::Decode(char* buffer, int bufLen) {
    6588
     
    95118          _obsList.push_back(obs);
    96119          if (_ObsBlock.PRN[iSat] > 100) {
    97             obs->_o.satNum = _ObsBlock.PRN[iSat] % 100;
    98             obs->_o.satSys = 'R';
    99           }
    100           else {
    101             obs->_o.satNum = _ObsBlock.PRN[iSat];
    102             obs->_o.satSys = 'G';
    103           }
    104           obs->_o.GPSWeek  = epochWeek;
    105           obs->_o.GPSWeeks = epochSecs;
    106           obs->_o.C1       = _ObsBlock.rng_C1[iSat];
    107           obs->_o.P1       = _ObsBlock.rng_P1[iSat];
    108           obs->_o.P2       = _ObsBlock.rng_P2[iSat];
    109           obs->_o.L1       = _ObsBlock.resolvedPhase_L1(iSat);
    110           obs->_o.L2       = _ObsBlock.resolvedPhase_L2(iSat);
     120            obs->_o.satNum      = _ObsBlock.PRN[iSat] % 100;
     121            obs->_o.satSys      = 'R';
     122          }                     
     123          else {               
     124            obs->_o.satNum      = _ObsBlock.PRN[iSat];
     125            obs->_o.satSys      = 'G';
     126          }                     
     127          obs->_o.GPSWeek       = epochWeek;
     128          obs->_o.GPSWeeks      = epochSecs;
     129          obs->_o.C1            = _ObsBlock.rng_C1[iSat];
     130          obs->_o.P1            = _ObsBlock.rng_P1[iSat];
     131          obs->_o.P2            = _ObsBlock.rng_P2[iSat];
     132          obs->_o.L1            = _ObsBlock.resolvedPhase_L1(iSat);
     133          obs->_o.L2            = _ObsBlock.resolvedPhase_L2(iSat);
     134          obs->_o.slip_cnt_L1   = _ObsBlock.slip_L1[iSat];
     135          obs->_o.slip_cnt_L2   = _ObsBlock.slip_L2[iSat];
     136          obs->_o.lock_timei_L1 = -1;
     137          obs->_o.lock_timei_L2 = -1;
    111138        }
    112139        _ObsBlock.clear();
    113140      }
    114141    }
     142
     143    else if ( _PP.ID() == 20 || _PP.ID() == 21 ) {
     144      _msg2021.extract(_PP);
     145
     146      if (_msg2021.valid()) {
     147        translateCorr2Obs();
     148      }
     149    }
     150
     151    else if ( _PP.ID() == 3 ) {
     152      _msg03.extract(_PP);
     153    }
     154
     155    else if ( _PP.ID() == 22 ) {
     156      _msg22.extract(_PP);
     157    }
    115158  }
    116159  return success;
    117160}
    118161
     162
     163
     164void RTCM2Decoder::storeEph(const gpsephemeris& gpseph) {
     165  t_ephGPS eph; eph.set(&gpseph);
     166
     167  storeEph(eph);
     168}
     169
     170
     171void RTCM2Decoder::storeEph(const t_ephGPS& gpseph) {
     172  t_ephGPS* eph = new t_ephGPS(gpseph);
     173
     174  string prn = eph->prn();
     175
     176  t_pairMap::iterator ip = _ephPair.find(prn);
     177  if (ip == _ephPair.end() ) {
     178    ip = _ephPair.insert(pair<string, t_ephPair*>(prn, new t_ephPair)).first;
     179  }
     180  t_ephPair* pair = ip->second;
     181
     182  if ( !pair->eph || eph->isNewerThan(pair->eph) ) {
     183    delete pair->oldEph;
     184    pair->oldEph = pair->eph;
     185    pair->eph    = eph;
     186
     187    return;
     188  }
     189
     190  delete eph;
     191}
     192 
     193 
     194void RTCM2Decoder::translateCorr2Obs() {
     195
     196  if ( !_msg03.validMsg || !_msg2021.valid() ) {
     197    return;
     198  }
     199
     200  double stax = _msg03.x + (_msg22.validMsg ? _msg22.dL1[0] : 0.0);
     201  double stay = _msg03.y + (_msg22.validMsg ? _msg22.dL1[1] : 0.0);
     202  double staz = _msg03.z + (_msg22.validMsg ? _msg22.dL1[2] : 0.0);
     203
     204  int    refWeek;
     205  double refSecs;
     206  currentGPSWeeks(refWeek, refSecs);
     207
     208  // Resolve receiver time of measurement (see RTCM 2.3, page 4-42, Message 18, Note 1)
     209  // ----------------------------------------------------------------------------------
     210  double hoursec_est  = _msg2021.hoursec();              // estimated time of measurement
     211  double hoursec_rcv  = rint(hoursec_est * 1e2) / 1e2;   // receiver clock reading at hoursec_est 
     212  double rcv_clk_bias = (hoursec_est - hoursec_rcv) * c_light;
     213
     214  int    GPSWeek;
     215  double GPSWeeks;
     216  resolveEpoch(hoursec_est, refWeek, refSecs,
     217               GPSWeek, GPSWeeks);
     218
     219  int    GPSWeek_rcv;
     220  double GPSWeeks_rcv;
     221  resolveEpoch(hoursec_rcv, refWeek, refSecs,
     222               GPSWeek_rcv, GPSWeeks_rcv);
     223
     224  // Loop over all satellites
     225  // ------------------------
     226  for (RTCM2_2021::data_iterator icorr = _msg2021.data.begin();
     227       icorr != _msg2021.data.end(); icorr++) {
     228    const RTCM2_2021::HiResCorr* corr = icorr->second;
     229
     230    ostringstream oPRN; oPRN.fill('0');
     231
     232    oPRN <<            (corr->PRN < 200 ? 'G'       : 'R')
     233         << setw(2) << (corr->PRN < 200 ? corr->PRN : corr->PRN - 200);
     234
     235    string PRN(oPRN.str());
     236
     237    t_pairMap::const_iterator ieph = _ephPair.find(PRN);
     238    const t_eph* eph0 = 0;
     239    const t_eph* eph1 = 0;
     240
     241    if ( ieph != _ephPair.end() ) {
     242      eph0 = ieph->second->eph;
     243      eph1 = ieph->second->oldEph;
     244    }
     245
     246    if ( !eph0 && !eph1 ) {
     247      continue;
     248    }
     249
     250    double L1 = 0;
     251    double L2 = 0;
     252    double P1 = 0;
     253    double P2 = 0;
     254    string obsT = "";
     255
     256    // new observation
     257    p_obs new_obs = 0;
     258
     259    for (unsigned ii = 0; ii < 4; ii++) {
     260      int          IODcorr = 0;
     261      double       corrVal = 0;
     262      const t_eph* eph     = 0;
     263      double*      obsVal  = 0;
     264
     265      switch (ii) {
     266      case 0: // --- L1 ---
     267        IODcorr = corr->IODp1;
     268        corrVal = corr->phase1 * LAMBDA_1;
     269        obsVal  = &L1;
     270        obsT    = "L1";
     271        break;
     272      case 1: // --- L2 ---
     273        IODcorr = corr->IODp2;
     274        corrVal = corr->phase2 * LAMBDA_2;
     275        obsVal  = &L2;
     276        obsT    = "L2";
     277        break;
     278      case 2: // --- P1 ---
     279        IODcorr = corr->IODr1;
     280        corrVal = corr->range1;
     281        obsVal  = &P1;
     282        obsT    = "P1";
     283        break;
     284      case 3: // --- P2 ---
     285        IODcorr = corr->IODr2;
     286        corrVal = corr->range2;
     287        obsVal  = &P2;
     288        obsT    = "P2";
     289        break;
     290      default:
     291        continue;
     292      }
     293
     294      eph = 0;
     295      if      ( eph0 && eph0->IOD() == IODcorr )
     296        eph = eph0;
     297      else if ( eph1 && eph1->IOD() == IODcorr )
     298        eph = eph1;
     299      if ( eph && corr ) {
     300        int    GPSWeek_tot;
     301        double GPSWeeks_tot;
     302        double rho, xSat, ySat, zSat, clkSat;
     303        cmpRho(eph, stax, stay, staz,
     304               GPSWeek, GPSWeeks,
     305               rho, GPSWeek_tot, GPSWeeks_tot,
     306               xSat, ySat, zSat, clkSat);
     307
     308        *obsVal = rho - corrVal + rcv_clk_bias - clkSat;
     309
     310        if ( *obsVal == 0 )  *obsVal = ZEROVALUE;
     311
     312        // Allocate new memory
     313        // -------------------
     314        if ( !new_obs ) {
     315          new_obs = new t_obs();
     316
     317          new_obs->_o.StatID[0] = '\x0';
     318          new_obs->_o.satSys    = (corr->PRN < 200 ? 'G'       : 'R');
     319          new_obs->_o.satNum    = (corr->PRN < 200 ? corr->PRN : corr->PRN - 200);
     320         
     321          new_obs->_o.GPSWeek   = GPSWeek_rcv;
     322          new_obs->_o.GPSWeeks  = GPSWeeks_rcv;
     323        }
     324       
     325        // Store estimated measurements
     326        // ----------------------------
     327        switch (ii) {
     328        case 0: // --- L1 ---
     329          new_obs->_o.L1 = *obsVal / LAMBDA_1;
     330          new_obs->_o.slip_cnt_L1   = corr->lock1;
     331          new_obs->_o.lock_timei_L1 = -1;
     332          break;
     333        case 1: // --- L2 ---
     334          new_obs->_o.L2 = *obsVal / LAMBDA_2;
     335          new_obs->_o.slip_cnt_L2   = corr->lock2;
     336          new_obs->_o.lock_timei_L2 = -1;
     337          break;
     338        case 2: // --- C1 / P1 ---
     339          if ( corr->Pind1 )
     340            new_obs->_o.P1 = *obsVal;
     341          else
     342            new_obs->_o.C1 = *obsVal;
     343          break;
     344        case 3: // --- C2 / P2 ---
     345          if ( corr->Pind2 )
     346            new_obs->_o.P2 = *obsVal;
     347          else
     348            new_obs->_o.C2 = *obsVal;
     349          break;
     350        default:
     351          continue;
     352        }
     353      }
     354    } // loop over frequencies
     355   
     356    if ( new_obs ) {
     357      _obsList.push_back( new_obs );
     358    }
     359  }
     360}
Note: See TracChangeset for help on using the changeset viewer.