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/bestpos.h>
00031
00032 #include <novatel_gps_driver/parsers/header.h>
00033
00034 #include <boost/make_shared.hpp>
00035
00036 namespace novatel_gps_driver
00037 {
00038 const std::string BestposParser::MESSAGE_NAME = "BESTPOS";
00039
00040 uint32_t BestposParser::GetMessageId() const
00041 {
00042 return MESSAGE_ID;
00043 }
00044
00045 const std::string BestposParser::GetMessageName() const
00046 {
00047 return MESSAGE_NAME;
00048 }
00049
00050 novatel_gps_msgs::NovatelPositionPtr BestposParser::ParseBinary(const BinaryMessage& bin_msg) throw(ParseException)
00051 {
00052 if (bin_msg.data_.size() != BINARY_LENGTH)
00053 {
00054 std::stringstream error;
00055 error << "Unexpected BESTPOS message length: " << bin_msg.data_.size();
00056 throw ParseException(error.str());
00057 }
00058 novatel_gps_msgs::NovatelPositionPtr ros_msg =
00059 boost::make_shared<novatel_gps_msgs::NovatelPosition>();
00060 HeaderParser header_parser;
00061 ros_msg->novatel_msg_header = header_parser.ParseBinary(bin_msg);
00062 ros_msg->novatel_msg_header.message_name = MESSAGE_NAME;
00063
00064 uint16_t solution_status = ParseUInt16(&bin_msg.data_[0]);
00065 if (solution_status > MAX_SOLUTION_STATUS)
00066 {
00067 std::stringstream error;
00068 error << "Unknown solution status: " << solution_status;
00069 throw ParseException(error.str());
00070 }
00071 ros_msg->solution_status = SOLUTION_STATUSES[solution_status];
00072 uint16_t pos_type = ParseUInt16(&bin_msg.data_[4]);
00073 if (pos_type > MAX_POSITION_TYPE)
00074 {
00075 std::stringstream error;
00076 error << "Unknown position type: " << pos_type;
00077 throw ParseException(error.str());
00078 }
00079 ros_msg->position_type = POSITION_TYPES[pos_type];
00080 ros_msg->lat = ParseDouble(&bin_msg.data_[8]);
00081 ros_msg->lon = ParseDouble(&bin_msg.data_[16]);
00082 ros_msg->height = ParseDouble(&bin_msg.data_[24]);
00083 ros_msg->undulation = ParseFloat(&bin_msg.data_[32]);
00084 uint16_t datum_id = ParseUInt16(&bin_msg.data_[36]);
00085 if (datum_id > MAX_DATUM)
00086 {
00087 std::stringstream error;
00088 error << "Unknown datum: " << datum_id;
00089 throw ParseException(error.str());
00090 }
00091 ros_msg->datum_id = DATUMS[datum_id];
00092 ros_msg->lat_sigma = ParseFloat(&bin_msg.data_[40]);
00093 ros_msg->lon_sigma = ParseFloat(&bin_msg.data_[44]);
00094 ros_msg->height_sigma = ParseFloat(&bin_msg.data_[48]);
00095 ros_msg->base_station_id.resize(4);
00096 std::copy(&bin_msg.data_[52], &bin_msg.data_[56], &ros_msg->base_station_id[0]);
00097 ros_msg->diff_age = ParseFloat(&bin_msg.data_[56]);
00098 ros_msg->solution_age = ParseFloat(&bin_msg.data_[60]);
00099 ros_msg->num_satellites_tracked = bin_msg.data_[64];
00100 ros_msg->num_satellites_used_in_solution = bin_msg.data_[65];
00101 ros_msg->num_gps_and_glonass_l1_used_in_solution = bin_msg.data_[66];
00102 ros_msg->num_gps_and_glonass_l1_and_l2_used_in_solution = bin_msg.data_[67];
00103 GetExtendedSolutionStatusMessage(bin_msg.data_[69],
00104 ros_msg->extended_solution_status);
00105 GetSignalsUsed(bin_msg.data_[70], ros_msg->signal_mask);
00106
00107 return ros_msg;
00108 }
00109
00110 novatel_gps_msgs::NovatelPositionPtr BestposParser::ParseAscii(const NovatelSentence& sentence) throw(ParseException)
00111 {
00112 novatel_gps_msgs::NovatelPositionPtr msg =
00113 boost::make_shared<novatel_gps_msgs::NovatelPosition>();
00114 HeaderParser h_parser;
00115 msg->novatel_msg_header = h_parser.ParseAscii(sentence);
00116
00117 if (sentence.body.size() != ASCII_LENGTH)
00118 {
00119 std::stringstream error;
00120 error << "Unexpected number of BESTPOS message fields: " << sentence.body.size();
00121 throw ParseException(error.str());
00122 }
00123
00124 bool valid = true;
00125
00126 msg->solution_status = sentence.body[0];
00127 msg->position_type = sentence.body[1];
00128 valid = valid && ParseDouble(sentence.body[2], msg->lat);
00129 valid = valid && ParseDouble(sentence.body[3], msg->lon);
00130 valid = valid && ParseDouble(sentence.body[4], msg->height);
00131 valid = valid && ParseFloat(sentence.body[5], msg->undulation);
00132 msg->datum_id = sentence.body[6];
00133 valid = valid && ParseFloat(sentence.body[7], msg->lat_sigma);
00134 valid = valid && ParseFloat(sentence.body[8], msg->lon_sigma);
00135 valid = valid && ParseFloat(sentence.body[9], msg->height_sigma);
00136 msg->base_station_id = sentence.body[10];
00137 valid = valid && ParseFloat(sentence.body[11], msg->diff_age);
00138 valid = valid && ParseFloat(sentence.body[12], msg->solution_age);
00139 valid = valid && ParseUInt8(sentence.body[13], msg->num_satellites_tracked);
00140 valid = valid && ParseUInt8(sentence.body[14], msg->num_satellites_used_in_solution);
00141 valid = valid && ParseUInt8(sentence.body[15], msg->num_gps_and_glonass_l1_used_in_solution);
00142 valid = valid && ParseUInt8(sentence.body[16], msg->num_gps_and_glonass_l1_and_l2_used_in_solution);
00143
00144
00145 uint32_t extended_solution_status = 0;
00146 valid = valid && ParseUInt32(sentence.body[18], extended_solution_status, 16);
00147 GetExtendedSolutionStatusMessage(
00148 extended_solution_status, msg->extended_solution_status);
00149
00150
00151 uint32_t signal_mask = 0;
00152 valid = valid && ParseUInt32(sentence.body[20], signal_mask, 16);
00153 GetSignalsUsed(signal_mask, msg->signal_mask);
00154
00155 if (!valid)
00156 {
00157 throw ParseException("Invalid field in BESTPOS message");
00158 }
00159
00160 return msg;
00161 }
00162 };