AshtechMBEN.cpp

Go to the documentation of this file.
00001 #pragma ident "$Id: AshtechMBEN.cpp 983 2007-12-12 14:14:35Z ocibu $"
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 "AshtechMBEN.hpp"
00040 #include "AshtechStream.hpp"
00041 #include "icd_200_constants.hpp"
00042 
00043 using namespace std;
00044 
00045 namespace gpstk
00046  {
00047    const char* AshtechMBEN::mpcId = "MPC";
00048    const char* AshtechMBEN::mcaId = "MCA";
00049 
00050 
00051    //---------------------------------------------------------------------------
00052    void AshtechMBEN::reallyGetRecord(FFStream& ffs)
00053       throw(std::exception, FFStreamError, EndOfFile)
00054    {
00055       AshtechStream& stream=dynamic_cast<AshtechStream&>(ffs);
00056 
00057       // make sure the object is reset before starting the search
00058       clear(fmtbit | lenbit | crcbit);
00059       string& rawData = stream.rawData;
00060 
00061       // If this object doesn't have an id set yet, assume that the streams
00062       // most recent read id is what we need to be
00063       if (id == "" && rawData.size()>=11 && 
00064           rawData.substr(0,7) == preamble &&
00065           rawData[10]==',')
00066          id = rawData.substr(7,3);
00067 
00068       // If that didn't work, or this is object is not of the right type,
00069       // then give up.
00070       if (id == "" || !checkId(id))
00071          return;
00072 
00073       readBody(stream);
00074    }
00075 
00076 
00077    //---------------------------------------------------------------------------
00078    void AshtechMBEN::decode(const std::string& data)
00079       throw(std::exception, FFStreamError)
00080    {
00081       using gpstk::BinUtils::decodeVar;
00082 
00083       string str(data);
00084 
00085       uint8_t csum=0;
00086       if (str.length() == 108 || str.length()==52)
00087       {
00088          ascii=false;
00089          header = str.substr(0,11); str.erase(0,11);
00090 
00091          seq    = decodeVar<uint16_t>(str);
00092          left   = decodeVar<uint8_t>(str);
00093          svprn  = decodeVar<uint8_t>(str);
00094          el     = decodeVar<uint8_t>(str);
00095          az     = decodeVar<uint8_t>(str);
00096          chid   = decodeVar<uint8_t>(str);
00097 
00098          ca.decodeBIN(str);
00099 
00100          if (id == mpcId)
00101          {
00102             p1.decodeBIN(str);
00103             p2.decodeBIN(str);
00104          }
00105 
00106          checksum = decodeVar<uint8_t>(str);
00107 
00108          clear();
00109 
00110          int end = data.size() - 3;
00111          for (int i=11; i<end; i++)
00112             csum ^= data[i];
00113       }
00114       else
00115       {
00116          ascii=true;
00117          header = str.substr(0,11); str.erase(0,11);
00118          stringstream iss(str);
00119          char c; 
00120          iss >> seq >> c
00121              >> left >> c
00122              >> svprn >> c
00123              >> el >> c
00124              >> az >> c
00125              >> chid >> c;
00126 
00127          ca.decodeASCII(iss);
00128 
00129          if (id == mpcId)
00130          {
00131             p1.decodeASCII(iss);
00132             p2.decodeASCII(iss);
00133          }
00134 
00135          iss >> checksum;
00136 
00137          if (iss)
00138             clear();
00139 
00140          int end=data.rfind(',');
00141          for (int i=11; i<=end; i++)
00142             csum ^= data[i];
00143       }
00144 
00145 
00146       if (csum != checksum)
00147       {
00148          setstate(crcbit);
00149          if (debugLevel)
00150             cout << "checksum error, computed:" << hex << (uint16_t) csum
00151                  << " received:" << checksum << dec << endl;
00152       }
00153 
00154       if (seq>36000)
00155          setstate(fmtbit);
00156    }
00157 
00158 
00159    //---------------------------------------------------------------------------
00160    void AshtechMBEN::code_block::decodeASCII(stringstream& str)
00161       throw(std::exception, FFStreamError)
00162    {
00163       char c;
00164       str >> warning >> c
00165           >> goodbad >> c
00166           >> polarity_known>> c
00167           >> ireg >> c
00168           >> qa_phase >> c
00169           >> full_phase >> c
00170           >> raw_range >> c
00171           >> doppler >> c
00172           >> smoothing >> c
00173           >> smooth_cnt >> c;
00174 
00175       // The ashtech docs say this field should be in 1e-4 Hz
00176       // The data sure doesn't look like it, however
00177       //doppler *= 1e-4;
00178       raw_range *= 1e-3; //convert ms to sec
00179    }
00180 
00181 
00182    //---------------------------------------------------------------------------
00183    void AshtechMBEN::code_block::decodeBIN(string& str)
00184       throw(std::exception, FFStreamError)
00185    {
00186       using gpstk::BinUtils::decodeVar;
00187       uint32_t smo;
00188       warning        = decodeVar<uint8_t>(str);
00189       goodbad        = decodeVar<uint8_t>(str);
00190       polarity_known = decodeVar<uint8_t>(str);
00191       ireg           = decodeVar<uint8_t>(str);
00192       qa_phase       = decodeVar<uint8_t>(str);
00193       full_phase     = decodeVar<double>(str);
00194       raw_range      = decodeVar<double>(str);
00195       doppler        = decodeVar<int32_t>(str);
00196       smo            = decodeVar<uint32_t>(str);
00197 
00198       doppler *= 1e-4;
00199       smoothing = (smo & 0x800000 ? -1e-3 : 1e-3) * (smo & 0x7fffff);
00200       smooth_cnt = (smo >> 24) & 0xff;
00201    }
00202 
00203 
00204    //---------------------------------------------------------------------------
00205    void AshtechMBEN::code_block::dump(ostream& out) const
00206    {
00207       using gpstk::StringUtils::asString;
00208       out << hex
00209           << "warn:" << (int)warning
00210           << " gb:" << (int)goodbad
00211           << " pol:" << (int)polarity_known
00212           << " qa:" << (int)qa_phase
00213           << dec
00214           << " phase:" << asString(full_phase, 1)
00215           << " range:" << asString(raw_range*1e3, 3)
00216           << " doppler:" << doppler
00217           << " smo:" << smoothing
00218           << " smo_cnt:" << smooth_cnt;
00219    }
00220 
00221 
00222    //---------------------------------------------------------------------------
00223    float AshtechMBEN::code_block::snr(float chipRate) const throw()
00224    {
00225       const int   n = 20000;     // number of samples in 1 ms
00226       const float m = 4.14;      // magnitude of the carrier estimate;
00227       float bw = 0.9 * chipRate; // equivalent noise bandwidth (Hz)
00228 
00229       const float d = PI/(n*n*m*m*4.0);
00230       float snr=0;
00231 
00232       if (ireg)
00233       {
00234          snr = exp(((float)ireg)/25.0);
00235          snr = snr*snr*bw*d;
00236          snr = 10 * log10(snr);
00237       }
00238 
00239       return snr;
00240    }
00241    
00242    //---------------------------------------------------------------------------
00243    void AshtechMBEN::dump(ostream& out) const throw()
00244    {
00245       ostringstream oss;
00246       using gpstk::StringUtils::asString;
00247 
00248       AshtechData::dump(oss);
00249       oss << getName() << "1:"
00250           << " seq:" << 0.05 * seq
00251           << " left:" << (int)left
00252           << " prn:" << (int)svprn
00253           << " el:" << (int)el
00254           << " az:" << (int)az
00255           << " chid:" << (int)chid
00256           << " " << (ascii?"ascii":"bin")
00257           << endl;
00258 
00259       oss << getName() << "2: ca ";
00260       ca.dump(oss);
00261       oss << endl;
00262 
00263       if (id == mpcId)
00264       {
00265          oss << getName() << "3: p1 ";
00266          p1.dump(oss);
00267          oss << endl;
00268          oss << getName() << "4: p2 ";
00269          p2.dump(oss);
00270          oss << endl;
00271       }
00272       out << oss.str() << flush;
00273    }
00274 } // namespace gpstk

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