00001 #pragma ident "$Id: AshtechMBEN.cpp 2927 2011-10-14 03:02:20Z 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 << dec
00213 << " ireg:" << (int)ireg
00214 << " qa:" << (int)qa_phase
00215 << " phase:" << asString(full_phase, 1)
00216 << " range:" << asString(raw_range*1e3, 3)
00217 << " doppler:" << doppler
00218 << " smo:" << smoothing
00219 << " smo_cnt:" << smooth_cnt;
00220 }
00221
00222
00223
00224 float AshtechMBEN::code_block::snr(float chipRate) const throw()
00225 {
00226 const float n = 20000;
00227
00228
00229 const float m = 2.18;
00230 const float bw = 0.9 * chipRate;
00231
00232 const float d = PI/(n*n*m*m*4.0);
00233 float snr=0;
00234
00235
00236 if (ireg)
00237 {
00238 snr = exp(((float)ireg)/25.0);
00239 snr = snr*snr*bw*d;
00240 snr = 10 * log10(snr);
00241 }
00242
00243 return snr;
00244 }
00245
00246
00247 void AshtechMBEN::dump(ostream& out) const throw()
00248 {
00249 ostringstream oss;
00250 using gpstk::StringUtils::asString;
00251
00252 AshtechData::dump(oss);
00253 oss << getName() << "1:"
00254 << " seq:" << 0.05 * seq
00255 << " left:" << (int)left
00256 << " prn:" << (int)svprn
00257 << " el:" << (int)el
00258 << " az:" << (int)az
00259 << " chid:" << (int)chid
00260 << " " << (ascii?"ascii":"bin")
00261 << endl;
00262
00263 oss << getName() << "2: ca ";
00264 ca.dump(oss);
00265 oss << endl;
00266
00267 if (id == mpcId)
00268 {
00269 oss << getName() << "3: p1 ";
00270 p1.dump(oss);
00271 oss << endl;
00272 oss << getName() << "4: p2 ";
00273 p2.dump(oss);
00274 oss << endl;
00275 }
00276 out << oss.str() << flush;
00277 }
00278 }