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/bestutm.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 BestutmParser::MESSAGE_NAME = "BESTUTM";
00039
00040 uint32_t BestutmParser::GetMessageId() const
00041 {
00042 return MESSAGE_ID;
00043 }
00044
00045 const std::string BestutmParser::GetMessageName() const
00046 {
00047 return MESSAGE_NAME;
00048 }
00049
00050 novatel_gps_msgs::NovatelUtmPositionPtr BestutmParser::ParseBinary(const BinaryMessage& bin_msg) throw(ParseException)
00051 {
00052 if (bin_msg.data_.size() != BINARY_LENGTH)
00053 {
00054 std::stringstream error;
00055 error << "Unexpected BESTUTM message length: " << bin_msg.data_.size();
00056 throw ParseException(error.str());
00057 }
00058 novatel_gps_msgs::NovatelUtmPositionPtr ros_msg =
00059 boost::make_shared<novatel_gps_msgs::NovatelUtmPosition>();
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->lon_zone_number = ParseUInt32(&bin_msg.data_[8]);
00081 ros_msg->lat_zone_letter = (char)ParseUInt32(&bin_msg.data_[12]);
00082 ros_msg->northing = ParseDouble(&bin_msg.data_[16]);
00083 ros_msg->easting = ParseDouble(&bin_msg.data_[24]);
00084 ros_msg->height = ParseDouble(&bin_msg.data_[32]);
00085 ros_msg->undulation = ParseFloat(&bin_msg.data_[40]);
00086 uint16_t datum_id = ParseUInt16(&bin_msg.data_[44]);
00087 if (datum_id > MAX_DATUM)
00088 {
00089 std::stringstream error;
00090 error << "Unknown datum: " << datum_id;
00091 throw ParseException(error.str());
00092 }
00093 ros_msg->datum_id = DATUMS[datum_id];
00094 ros_msg->northing_sigma = ParseFloat(&bin_msg.data_[48]);
00095 ros_msg->easting_sigma = ParseFloat(&bin_msg.data_[52]);
00096 ros_msg->height_sigma = ParseFloat(&bin_msg.data_[56]);
00097 ros_msg->base_station_id.resize(4);
00098 std::copy(&bin_msg.data_[60], &bin_msg.data_[64], &ros_msg->base_station_id[0]);
00099 ros_msg->diff_age = ParseFloat(&bin_msg.data_[64]);
00100 ros_msg->solution_age = ParseFloat(&bin_msg.data_[68]);
00101 ros_msg->num_satellites_tracked = bin_msg.data_[72];
00102 ros_msg->num_satellites_used_in_solution = bin_msg.data_[73];
00103 ros_msg->num_gps_and_glonass_l1_used_in_solution = bin_msg.data_[74];
00104 ros_msg->num_gps_and_glonass_l1_and_l2_used_in_solution = bin_msg.data_[75];
00105 GetExtendedSolutionStatusMessage(bin_msg.data_[77],
00106 ros_msg->extended_solution_status);
00107 GetSignalsUsed(bin_msg.data_[78], ros_msg->signal_mask);
00108
00109 return ros_msg;
00110 }
00111
00112 novatel_gps_msgs::NovatelUtmPositionPtr BestutmParser::ParseAscii(const NovatelSentence& sentence) throw(ParseException)
00113 {
00114 novatel_gps_msgs::NovatelUtmPositionPtr msg =
00115 boost::make_shared<novatel_gps_msgs::NovatelUtmPosition>();
00116 HeaderParser h_parser;
00117 msg->novatel_msg_header = h_parser.ParseAscii(sentence);
00118
00119 if (sentence.body.size() != ASCII_LENGTH)
00120 {
00121 std::stringstream error;
00122 error << "Unexpected number of BESTUTM message fields: " << sentence.body.size();
00123 throw ParseException(error.str());
00124 }
00125
00126 bool valid = true;
00127
00128 msg->solution_status = sentence.body[0];
00129 msg->position_type = sentence.body[1];
00130 valid = valid && ParseUInt32(sentence.body[2], msg->lon_zone_number);
00131 msg->lat_zone_letter = sentence.body[3];
00132 valid = valid && ParseDouble(sentence.body[4], msg->northing);
00133 valid = valid && ParseDouble(sentence.body[5], msg->easting);
00134 valid = valid && ParseDouble(sentence.body[6], msg->height);
00135 valid = valid && ParseFloat(sentence.body[7], msg->undulation);
00136 msg->datum_id = sentence.body[8];
00137 valid = valid && ParseFloat(sentence.body[9], msg->northing_sigma);
00138 valid = valid && ParseFloat(sentence.body[10], msg->easting_sigma);
00139 valid = valid && ParseFloat(sentence.body[11], msg->height_sigma);
00140 msg->base_station_id = sentence.body[12];
00141 valid = valid && ParseFloat(sentence.body[13], msg->diff_age);
00142 valid = valid && ParseFloat(sentence.body[14], msg->solution_age);
00143 valid = valid && ParseUInt8(sentence.body[15], msg->num_satellites_tracked);
00144 valid = valid && ParseUInt8(sentence.body[16], msg->num_satellites_used_in_solution);
00145 valid = valid && ParseUInt8(sentence.body[17], msg->num_gps_and_glonass_l1_used_in_solution);
00146 valid = valid && ParseUInt8(sentence.body[18], msg->num_gps_and_glonass_l1_and_l2_used_in_solution);
00147
00148
00149 uint32_t extended_solution_status = 0;
00150 valid = valid && ParseUInt32(sentence.body[20], extended_solution_status, 16);
00151 GetExtendedSolutionStatusMessage(
00152 extended_solution_status, msg->extended_solution_status);
00153
00154
00155 uint32_t signal_mask = 0;
00156 valid = valid && ParseUInt32(sentence.body[22], signal_mask, 16);
00157 GetSignalsUsed(signal_mask, msg->signal_mask);
00158
00159 if (!valid)
00160 {
00161 throw ParseException("Invalid field in BESTUTM message");
00162 }
00163
00164 return msg;
00165 }
00166 };