Changeset 1024 in ntrip for trunk/BNC/RTCM


Ignore:
Timestamp:
Aug 7, 2008, 4:01:56 PM (16 years ago)
Author:
zdenek
Message:

Zdenek Lukes: added logic for decoding of message 20/21 from RTCM 2.3 streams

Location:
trunk/BNC/RTCM
Files:
4 added
5 edited

Legend:

Unmodified
Added
Removed
  • trunk/BNC/RTCM/GPSDecoder.h

    r649 r1024  
    4747  double L1;          // L1 carrier phase (cycles)
    4848  double L2;          // L2 carrier phase (cycles)
     49  int    slip_cnt_L1; // L1 cumulative loss of continuity indicator
     50  int    slip_cnt_L2; // L2 cumulative loss of continuity indicator
    4951  double S1;          // L1 signal-to noise ratio
    5052  double S2;          // L2 signal-to noise ratio
  • trunk/BNC/RTCM/RTCM2.cpp

    r728 r1024  
    945945  cph_L1.resize(0);        // Carrier phase [m]
    946946  cph_L2.resize(0);        // Carrier phase [m]
     947  slip_L1.resize(0);       // Slip counter
     948  slip_L2.resize(0);       // Slip counter
    947949 
    948950  availability.reset();    // Message status flags
     
    10051007  bool    isGPS,isCAcode,isL1,isOth;
    10061008  int     NSat,idx;
    1007   int     sid,prn;
     1009  int     sid,prn,slip_cnt;
    10081010  double  t,rng,cph;
    10091011
     
    11171119      // Carrier phase measurement (mod 2^23 [cy]; sign matched to range)
    11181120      cph = -P.getBits(iSat*48+40,32)/256.0;
     1121
     1122      // Slip counter
     1123      slip_cnt = P.getUnsignedBits(iSat*48+35,5);
    11191124
    11201125      // Is this a new PRN?
     
    11321137        cph_L1.push_back(0.0);
    11331138        cph_L2.push_back(0.0);
     1139        slip_L1.push_back(-1);
     1140        slip_L2.push_back(-1);
    11341141      };
    11351142     
    11361143      // Store measurement
    11371144      if (isL1) {
    1138         cph_L1[idx] = cph;
     1145        cph_L1 [idx] = cph;
     1146        slip_L1[idx] = slip_cnt;
    11391147      }
    11401148      else {
    1141         cph_L2[idx] = cph;
     1149        cph_L2 [idx] = cph;
     1150        slip_L2[idx] = slip_cnt;
    11421151      };
    11431152           
     
    13391348
    13401349}; // End of namespace rtcm2
     1350
     1351
     1352
  • trunk/BNC/RTCM/RTCM2.h

    r725 r1024  
    309309    std::vector<double>  cph_L1;           // Carrier phase on L1 [cy]
    310310    std::vector<double>  cph_L2;           // Carrier phase on L2 [cy]
     311    std::vector<int>     slip_L1;          // Carrier phase slip counter, L1
     312    std::vector<int>     slip_L2;          // Carrier phase slip counter, L1
    311313
    312314  private:
  • trunk/BNC/RTCM/RTCM2Decoder.cpp

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

    r649 r1024  
    2626#define INC_RTCM2DECODER_H
    2727
     28#include <list>
     29
    2830#include "GPSDecoder.h"
    2931#include "RTCM2.h"
     32#include "RTCM2_2021.h"
     33#include "../RTCM3/rtcm3torinex.h"
     34#include "../RTCM3/ephemeris.h"
    3035
    3136class RTCM2Decoder: public GPSDecoder {
    3237
    3338  public:
    34     RTCM2Decoder();
     39    RTCM2Decoder(const std::string& ID);
    3540    virtual ~RTCM2Decoder();
    3641    virtual t_irc Decode(char* buffer, int bufLen);
    3742
     43    void  storeEph(const gpsephemeris& gpseph);
     44    void  storeEph(const t_ephGPS&     gpseph);
     45
     46    t_irc getStaCrd(double& xx, double& yy, double& zz);
     47
     48    const rtcm2::RTCM2_2021& msg2021() const { return _msg2021; }
     49
    3850  private:
    3951
    40     std::string        _buffer;
    41     rtcm2::RTCM2_Obs   _ObsBlock;
    42     rtcm2::RTCM2packet _PP;
     52    class t_ephPair {
     53    public:
     54      t_ephPair() {
     55        eph    = 0;
     56        oldEph = 0;
     57      }
     58     
     59      ~t_ephPair() {
     60        delete eph;
     61        delete oldEph;
     62      }
     63     
     64      t_eph* eph;
     65      t_eph* oldEph;
     66    };
    4367
     68    void translateCorr2Obs();
     69
     70    std::string            _ID;
     71
     72    std::string            _buffer;
     73    rtcm2::RTCM2packet     _PP;
     74
     75    // for messages 18, 19 decoding
     76    rtcm2::RTCM2_Obs       _ObsBlock;
     77
     78    // for messages 20, 21 decoding
     79    rtcm2::RTCM2_03           _msg03;
     80    rtcm2::RTCM2_22           _msg22;
     81    rtcm2::RTCM2_2021         _msg2021;
     82    std::map<std::string, t_ephPair*> _ephPair;
     83
     84    typedef std::map<std::string, t_ephPair*> t_pairMap;
    4485};
    4586
Note: See TracChangeset for help on using the changeset viewer.