Go to the documentation of this file.00001
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 #include <novatel_gps_driver/parsers/trackstat.h>
00031 #include <boost/make_shared.hpp>
00032
00033 const std::string novatel_gps_driver::TrackstatParser::MESSAGE_NAME = "TRACKSTAT";
00034
00035 uint32_t novatel_gps_driver::TrackstatParser::GetMessageId() const
00036 {
00037 return MESSAGE_ID;
00038 }
00039
00040 const std::string novatel_gps_driver::TrackstatParser::GetMessageName() const
00041 {
00042 return MESSAGE_NAME;
00043 }
00044
00045 novatel_gps_msgs::TrackstatPtr
00046 novatel_gps_driver::TrackstatParser::ParseBinary(const novatel_gps_driver::BinaryMessage& bin_msg) throw(ParseException)
00047 {
00048 uint32_t num_chans = ParseUInt32(&bin_msg.data_[12]);
00049 if (bin_msg.data_.size() != (BINARY_CHANNEL_LENGTH * num_chans) +
00050 BINARY_BODY_LENGTH)
00051 {
00052 std::stringstream error;
00053 error << "Unexpected trackstat message size: " << bin_msg.data_.size();
00054 throw ParseException(error.str());
00055 }
00056
00057 uint16_t solution_status = ParseUInt16(&bin_msg.data_[0]);
00058 if (solution_status > MAX_SOLUTION_STATUS)
00059 {
00060 std::stringstream error;
00061 error << "Unknown solution status: " << solution_status;
00062 throw ParseException(error.str());
00063 }
00064
00065 novatel_gps_msgs::TrackstatPtr ros_msg = boost::make_shared<novatel_gps_msgs::Trackstat>();
00066 ros_msg->solution_status = SOLUTION_STATUSES[solution_status];
00067 uint16_t pos_type = ParseUInt16(&bin_msg.data_[4]);
00068 if (pos_type > MAX_DATUM)
00069 {
00070 std::stringstream error;
00071 error << "Unknown position type: " << pos_type;
00072 throw ParseException(error.str());
00073 }
00074 ros_msg->position_type = POSITION_TYPES[pos_type];
00075 ros_msg->cutoff = ParseFloat(&bin_msg.data_[8]);
00076
00077 for (int i = 0; i < num_chans; i++)
00078 {
00079 size_t chan_offset = BINARY_BODY_LENGTH +
00080 i * BINARY_CHANNEL_LENGTH;
00081
00082 novatel_gps_msgs::TrackstatChannel chan;
00083 chan.prn = ParseInt16(&bin_msg.data_[chan_offset]);
00084 chan.glofreq = ParseInt16(&bin_msg.data_[chan_offset+2]);
00085 chan.ch_tr_status = ParseUInt32(&bin_msg.data_[chan_offset+4]);
00086 chan.psr = ParseDouble(&bin_msg.data_[chan_offset+8]);
00087 chan.doppler = ParseFloat(&bin_msg.data_[chan_offset+16]);
00088 chan.c_no = ParseFloat(&bin_msg.data_[chan_offset+20]);
00089 chan.locktime = ParseFloat(&bin_msg.data_[chan_offset+24]);
00090 chan.psr_res = ParseFloat(&bin_msg.data_[chan_offset+28]);
00091 uint32_t reject = ParseUInt32(&bin_msg.data_[chan_offset+32]);
00092 switch (reject)
00093 {
00094 case 0:
00095 chan.reject = "GOOD";
00096 break;
00097 case 1:
00098 chan.reject = "BADHEALTH";
00099 break;
00100 case 2:
00101 chan.reject = "OLDEPHEMERIS";
00102 break;
00103 case 6:
00104 chan.reject = "ELEVATIONERROR";
00105 break;
00106 case 7:
00107 chan.reject = "MISCLOSURE";
00108 break;
00109 case 8:
00110 chan.reject = "NODIFFCORR";
00111 break;
00112 case 9:
00113 chan.reject = "NOEPHEMERIS";
00114 break;
00115 case 10:
00116 chan.reject = "INVALIDCODE";
00117 break;
00118 case 11:
00119 chan.reject = "LOCKEDOUT";
00120 break;
00121 case 12:
00122 chan.reject = "LOWPOWER";
00123 break;
00124 case 13:
00125 chan.reject = "OBSL2";
00126 break;
00127 case 15:
00128 chan.reject = "UNKNOWN";
00129 break;
00130 case 16:
00131 chan.reject = "NOIONOCORR";
00132 break;
00133 case 17:
00134 chan.reject = "NOTUSED";
00135 break;
00136 case 18:
00137 chan.reject = "OBSL1";
00138 break;
00139 case 19:
00140 chan.reject = "OBSE1";
00141 break;
00142 case 20:
00143 chan.reject = "OBSL5";
00144 break;
00145 case 21:
00146 chan.reject = "OBSE5";
00147 break;
00148 case 22:
00149 chan.reject = "OBSB2";
00150 break;
00151 case 23:
00152 chan.reject = "OBSB1";
00153 break;
00154 case 24:
00155 chan.reject = "OBSB3";
00156 break;
00157 case 25:
00158 chan.reject = "NOSIGNALMATCH";
00159 break;
00160 case 26:
00161 chan.reject = "SUPPLEMENTARY";
00162 break;
00163 case 99:
00164 chan.reject = "NA";
00165 break;
00166 case 100:
00167 chan.reject = "BAD_INTEGRITY";
00168 break;
00169 case 101:
00170 chan.reject = "LOSSOFLOCK";
00171 break;
00172 case 102:
00173 chan.reject = "NOAMBIGUITY";
00174 break;
00175 default:
00176 {
00177 std::stringstream error;
00178 error << "Unexpected channel status: " << reject;
00179 throw ParseException(error.str());
00180 }
00181 }
00182 chan.psr_weight = ParseFloat(&bin_msg.data_[chan_offset+36]);
00183
00184 ros_msg->channels.push_back(chan);
00185 }
00186
00187 return ros_msg;
00188 }
00189
00190 novatel_gps_msgs::TrackstatPtr
00191 novatel_gps_driver::TrackstatParser::ParseAscii(const novatel_gps_driver::NovatelSentence& sentence) throw(ParseException)
00192 {
00193 if (sentence.body.size() < ASCII_BODY_FIELDS)
00194 {
00195 std::stringstream error;
00196 error << "Unexpected number of body fields in TRACKSTAT log: " << sentence.body.size();
00197 throw ParseException(error.str());
00198 }
00199
00200 uint32_t n_channels = 0;
00201 ParseUInt32(sentence.body[3], n_channels, 10);
00202
00203 if (sentence.body.size() != ASCII_BODY_FIELDS + n_channels * ASCII_CHANNEL_FIELDS)
00204 {
00205 std::stringstream error;
00206 error << "Size of TRACKSTAT log did not match expected size.";
00207 throw ParseException(error.str());
00208 }
00209
00210 bool valid = true;
00211 novatel_gps_msgs::TrackstatPtr msg = boost::make_shared<novatel_gps_msgs::Trackstat>();
00212 msg->solution_status = sentence.body[0];
00213 msg->position_type = sentence.body[1];
00214 valid &= ParseFloat(sentence.body[2], msg->cutoff);
00215
00216 msg->channels.resize(n_channels);
00217 for (size_t i = 0; i < static_cast<size_t>(n_channels); ++i)
00218 {
00219 size_t offset = 4 + i * ASCII_CHANNEL_FIELDS;
00220 novatel_gps_msgs::TrackstatChannel& channel = msg->channels[i];
00221 valid &= ParseInt16(sentence.body[offset], channel.prn);
00222 valid &= ParseInt16(sentence.body[offset+1], channel.glofreq);
00223 valid &= ParseUInt32(sentence.body[offset+2], channel.ch_tr_status, 16);
00224 valid &= ParseDouble(sentence.body[offset+3], channel.psr);
00225 valid &= ParseFloat(sentence.body[offset+4], channel.doppler);
00226 valid &= ParseFloat(sentence.body[offset+5], channel.c_no);
00227 valid &= ParseFloat(sentence.body[offset+6], channel.locktime);
00228 valid &= ParseFloat(sentence.body[offset+7], channel.psr_res);
00229 channel.reject = sentence.body[offset+8];
00230 valid &= ParseFloat(sentence.body[offset+9], channel.psr_weight);
00231 }
00232
00233 if (!valid)
00234 {
00235 std::stringstream error;
00236 error << "Error parsing TRACKSTAT log.";
00237 throw ParseException(error.str());
00238 }
00239 return msg;
00240 }