00001 #pragma ident "$Id: AshtechMBEN.cpp 983 2007-12-12 14:14:35Z ocibu $"
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
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
00058 clear(fmtbit | lenbit | crcbit);
00059 string& rawData = stream.rawData;
00060
00061
00062
00063 if (id == "" && rawData.size()>=11 &&
00064 rawData.substr(0,7) == preamble &&
00065 rawData[10]==',')
00066 id = rawData.substr(7,3);
00067
00068
00069
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
00176
00177
00178 raw_range *= 1e-3;
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;
00226 const float m = 4.14;
00227 float bw = 0.9 * chipRate;
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 }