MDPObsEpoch.cpp

Go to the documentation of this file.
00001 #pragma ident "$Id: MDPObsEpoch.cpp 2179 2009-11-13 19:03:41Z snelsen $"
00002 
00003 //============================================================================
00004 //
00005 //  This file is part of GPSTk, the GPS Toolkit.
00006 //
00007 //  The GPSTk is free software; you can redistribute it and/or modify
00008 //  it under the terms of the GNU Lesser General Public License as published
00009 //  by the Free Software Foundation; either version 2.1 of the License, or
00010 //  any later version.
00011 //
00012 //  The GPSTk is distributed in the hope that it will be useful,
00013 //  but WITHOUT ANY WARRANTY; without even the implied warranty of
00014 //  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00015 //  GNU Lesser General Public License for more details.
00016 //
00017 //  You should have received a copy of the GNU Lesser General Public
00018 //  License along with GPSTk; if not, write to the Free Software Foundation,
00019 //  Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00020 //  
00021 //  Copyright 2004, The University of Texas at Austin
00022 //
00023 //============================================================================
00024 
00025 //============================================================================
00026 //
00027 //This software developed by Applied Research Laboratories at the University of
00028 //Texas at Austin, under contract to an agency or agencies within the U.S. 
00029 //Department of Defense. The U.S. Government retains all rights to use,
00030 //duplicate, distribute, disclose, or release this software. 
00031 //
00032 //Pursuant to DoD Directive 523024 
00033 //
00034 // DISTRIBUTION STATEMENT A: This software has been approved for public 
00035 //                           release, distribution is unlimited.
00036 //
00037 //=============================================================================
00038 
00039 #include <sstream>
00040 #include <StringUtils.hpp>
00041 #include <StringUtils.hpp>
00042 #include <BinUtils.hpp>
00043 #include <gps_constants.hpp>
00044 
00045 #include "MDPObsEpoch.hpp"
00046 #include "MDPStream.hpp"
00047 
00048 using gpstk::StringUtils::asString;
00049 using gpstk::BinUtils::hostToNet;
00050 using gpstk::BinUtils::netToHost;
00051 using gpstk::BinUtils::encodeVar;
00052 using gpstk::BinUtils::decodeVar;
00053 using namespace std;
00054 
00055 namespace gpstk
00056 {
00057    //---------------------------------------------------------------------------
00058    MDPObsEpoch::MDPObsEpoch()
00059       throw(): 
00060       numSVs(0), channel(0), prn(0),status(0), elevation(0),azimuth(0)
00061    {
00062       id = myId;
00063    } // MDPObsEpoch::MDPObsEpoch()
00064 
00065 
00066    //---------------------------------------------------------------------------
00067    string MDPObsEpoch::encode() const
00068       throw()
00069    {
00070       string str;
00071       unsigned short ustemp;
00072       unsigned char svsobs = (numSVs & 0x0f);
00073       svsobs <<= 4;
00074       svsobs |= ((unsigned char)obs.size() & 0x0f);
00075       
00076       str += encodeVar( static_cast<uint8_t>(svsobs));
00077       str += encodeVar( static_cast<uint8_t>(channel));
00078       str += encodeVar( static_cast<uint8_t>(prn));
00079       str += encodeVar( static_cast<uint8_t>(status & 0x3f));
00080       str += encodeVar( static_cast<uint16_t>(elevation * 100));
00081       str += encodeVar( static_cast<uint16_t>(azimuth * 100));
00082 
00083       for(ObsMap::const_iterator oli = obs.begin(); 
00084           oli != obs.end(); oli++)
00085       {
00086          MDPObsEpoch::Observation mdpobs(oli->second);
00087          str += mdpobs.encode();
00088       }
00089       return str;
00090    } // MDPObsEpoch::encode()
00091 
00092       
00093    //---------------------------------------------------------------------------
00094    void MDPObsEpoch::decode(string str)
00095       throw()
00096    {
00097       if (str.length() < myLength)
00098          return;
00099 
00100       clearstate(lenbit);
00101 
00102       unsigned obsSVs;
00103       obsSVs    = decodeVar<uint8_t>(str);
00104       channel   = decodeVar<uint8_t>(str);
00105       prn       = decodeVar<uint8_t>(str);
00106       status    = decodeVar<uint8_t>(str);
00107       elevation = decodeVar<uint16_t>(str) * 0.01 ;
00108       azimuth   = decodeVar<uint16_t>(str) * 0.01;
00109 
00110       numSVs = obsSVs >> 4;
00111       numSVs &= 0x0f;
00112       obsSVs &= 0x0f;
00113 
00114       bool obsError=false;
00115 
00116       obs.erase(obs.begin(), obs.end());
00117       for(int j=0; j<obsSVs; j++)
00118       {
00119          if (str.length() < myObsLength)
00120          {
00121             clear(lenbit);
00122             if (debugLevel)
00123                cout << "MDP Obs block decode requires at least " << myObsLength
00124                     << " bytes.  Received " << str.length() << " bytes" << endl;
00125             return;
00126          }
00127          MDPObsEpoch::Observation o;      
00128          o.decode(str);
00129 
00130          if (o.carrier >= ccMax || o.range >= rcMax || o.snr > 65 || o.bw > 100)
00131             obsError=true;
00132 
00133          if (obsError && debugLevel)
00134          {            
00135             if (o.carrier >= ccMax)
00136                cout << "Carrier code out of range: " << o.carrier << endl;
00137             if (o.range >= rcMax)
00138                cout << "Range code out of range: " << o.range << endl;
00139             if (o.snr > 65)
00140                cout << "SNR out of range: " << o.snr << endl;
00141             if (o.bw > 100)
00142                cout << "BW out of range: " << o.snr << endl;
00143          }
00144   
00145          if (o.carrier < ccMax && o.range < rcMax)
00146          {
00147             ObsKey key(o.carrier, o.range);
00148             obs[key] = o;
00149          }
00150       }
00151 
00152       if (prn > gpstk::MAX_PRN || elevation>90 || azimuth > 360 || obsError)
00153       {
00154          if (debugLevel)
00155          {
00156             if (prn > gpstk::MAX_PRN)
00157                cout << "PRN out of range: " << prn << endl;
00158             if (elevation > 90)
00159                cout << "Elevation out of range: " << elevation << endl;
00160             if (azimuth > 360)
00161                cout << "Azimuth out of range: " << azimuth << endl;
00162          }
00163          return;
00164       }
00165 
00166       clearstate(fmtbit);
00167    } // MDPObsEpoch::decode()
00168 
00169 
00170    //---------------------------------------------------------------------------
00171    std::string MDPObsEpoch::Observation::encode() const
00172       throw()
00173    {
00174       string str;
00175 
00176       uint8_t ccrc = carrier & 0x0f;
00177       ccrc <<= 4;
00178       ccrc |= range & 0x0f;
00179 
00180       str += encodeVar( (uint8_t)  ccrc);
00181       str += encodeVar( (uint8_t)  bw);
00182       str += encodeVar( (uint16_t) std::max(static_cast<int>(snr*100),0));
00183       str += encodeVar( (uint32_t) lockCount);
00184       str += encodeVar( (double)   pseudorange);
00185       str += encodeVar( (double)   phase);
00186       str += encodeVar( (double)   doppler);
00187       return str;
00188    } // MDPObservation::encode()
00189 
00190 
00191    //---------------------------------------------------------------------------
00192    void MDPObsEpoch::Observation::decode(std::string& str)
00193       throw()
00194    {
00195       unsigned char ccrc;
00196 
00197       ccrc        = decodeVar<uint8_t>(str);      
00198       bw          = decodeVar<uint8_t>(str);
00199       snr         = decodeVar<uint16_t>(str) * 0.01;
00200       lockCount   = decodeVar<uint32_t>(str);
00201       pseudorange = decodeVar<double>(str);
00202       phase       = decodeVar<double>(str);
00203       doppler     = decodeVar<double>(str);
00204 
00205       range = RangeCode(ccrc & 0x0f);
00206       ccrc >>= 4;
00207       carrier = CarrierCode(ccrc & 0x0f);
00208    }  // MDPObservation::decode()
00209 
00210 
00211    //---------------------------------------------------------------------------
00212    bool MDPObsEpoch::haveObservation(
00213       const CarrierCode cc,
00214       const RangeCode rc) const
00215    {
00216       return (obs.find(ObsKey(cc,rc)) != obs.end());
00217    }
00218 
00219 
00220    //---------------------------------------------------------------------------
00221    MDPObsEpoch::Observation MDPObsEpoch::getObservation(
00222       const CarrierCode cc, 
00223       const RangeCode rc) const
00224    {
00225       if (haveObservation(cc, rc))
00226          return obs.find(ObsKey(cc,rc))->second;
00227       else
00228          return Observation();
00229    }
00230 
00231 
00232    //---------------------------------------------------------------------------
00233    FFStream& operator>>(FFStream& s, MDPEpoch& me)
00234    {
00235       MDPStream& mdps = dynamic_cast<MDPStream&>(s);
00236       MDPObsEpoch moe;
00237       DayTime t;
00238 
00239       while (mdps >> moe)
00240       {
00241          if (!moe || moe.time != t)
00242          {
00243             if (!me.empty() && MDPHeader::debugLevel>2)
00244                cout << "Tossing partial epoch at " << moe.time
00245                     << ".  Expected " << moe.numSVs
00246                     << " SVs but received only " << me.size()
00247                     << endl;
00248             me.clear();
00249          }
00250          me.insert(pair<const int, MDPObsEpoch>(moe.prn,moe));
00251          t = moe.time;
00252 
00253          if (moe.numSVs == me.size())
00254             break;
00255       }
00256 
00257          // Report why the stream is "not good".
00258       if (!mdps && MDPHeader::debugLevel)
00259          mdps.dumpState(cout);
00260 
00261       return s;
00262    }
00263 
00264 
00265    //---------------------------------------------------------------------------
00266    FFStream& operator<<(FFStream& s, const MDPEpoch& oe)
00267    {
00268       MDPStream& mdps = dynamic_cast<MDPStream&>(s);
00269       MDPEpoch::const_iterator i;
00270       for (i=oe.begin(); i != oe.end(); i++)
00271          mdps << i->second;
00272       return s;
00273    }
00274 
00275 
00276    //---------------------------------------------------------------------------
00277    void MDPObsEpoch::dump(ostream& out) const
00278       throw()
00279    {
00280       ostringstream oss;
00281 
00282       MDPHeader::dump(oss);
00283 
00284       oss << getName() << "0:"
00285           << " #SV:" << (int)numSVs
00286           << " Ch:" << (int)channel
00287           << " PRN:" << (int)prn
00288           << " El:" << fixed << setprecision(2) <<elevation
00289           << " Az:" << azimuth
00290           << " H:0x" << hex << (int)status
00291           << dec << endl;
00292 
00293       int j=1;
00294       for (ObsMap::const_iterator i = obs.begin(); i != obs.end(); i++)
00295       {
00296          oss << getName() << j++ << ":";
00297          i->second.dump(oss);
00298          oss << endl;
00299       }
00300       
00301       out << oss.str();
00302    } // MDPObsEpoch::dump()
00303 
00304 
00305    //---------------------------------------------------------------------------
00306    void MDPObsEpoch::Observation::dump(ostream& out) const 
00307       throw()
00308    {
00309       using gpstk::StringUtils::asString;
00310 
00311       ostringstream oss;
00312       oss << " "     << asString(carrier)
00313           << " "     << asString(range)
00314           << " BW:"  << bw
00315           << " SNR:" << snr
00316           << " LC:"  << lockCount
00317           << " PR:"  << asString(pseudorange, 3)
00318           << " PH:"  << asString(phase, 3)
00319           << " Dop:" << asString(doppler, 3);      
00320       out << oss.str();
00321    } // MDPObsEpoch::Observation::dump()
00322 
00323 
00324    //---------------------------------------------------------------------------
00325    void dump(ostream& s, const MDPEpoch& me)
00326    {
00327       MDPEpoch::const_iterator i;
00328       for (i=me.begin(); i != me.end(); i++)
00329          i->second.dump(s);
00330    }
00331 }

Generated on Thu Jul 29 03:30:53 2010 for GPS ToolKit Software Library by  doxygen 1.3.9.1