00001 #pragma ident "$Id: MDPObsEpoch.cpp 2179 2009-11-13 19:03:41Z snelsen $"
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 <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 }
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 }
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 }
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 }
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 }
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
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 }
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 }
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 }