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/dual_antenna_heading.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 DualAntennaHeadingParser::MESSAGE_NAME = "DUALANTENNAHEADING";
00039
00040 uint32_t DualAntennaHeadingParser::GetMessageId() const
00041 {
00042 return MESSAGE_ID;
00043 }
00044
00045 const std::string DualAntennaHeadingParser::GetMessageName() const
00046 {
00047 return MESSAGE_NAME;
00048 }
00049
00050 novatel_gps_msgs::NovatelDualAntennaHeadingPtr DualAntennaHeadingParser::ParseBinary(const BinaryMessage& bin_msg) throw(ParseException)
00051 {
00052 if (bin_msg.data_.size() != BINARY_LENGTH)
00053 {
00054 std::stringstream error;
00055 error << "Unexpected DUALANTENNAHEADING message length: " << bin_msg.data_.size();
00056 throw ParseException(error.str());
00057 }
00058 novatel_gps_msgs::NovatelDualAntennaHeadingPtr ros_msg =
00059 boost::make_shared<novatel_gps_msgs::NovatelDualAntennaHeading>();
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
00073 uint16_t pos_type = ParseUInt16(&bin_msg.data_[4]);
00074 if (pos_type > MAX_POSITION_TYPE)
00075 {
00076 std::stringstream error;
00077 error << "Unknown position type: " << pos_type;
00078 throw ParseException(error.str());
00079 }
00080 ros_msg->position_type = POSITION_TYPES[pos_type];
00081
00082 ros_msg->baseline_length = ParseFloat(&bin_msg.data_[8]);
00083
00084 ros_msg->heading = ParseFloat(&bin_msg.data_[12]);
00085 ros_msg->pitch = ParseFloat(&bin_msg.data_[16]);
00086
00087
00088
00089 ros_msg->heading_sigma = ParseFloat(&bin_msg.data_[24]);
00090 ros_msg->pitch_sigma = ParseFloat(&bin_msg.data_[28]);
00091
00092 ros_msg->station_id.resize(4);
00093 std::copy(&bin_msg.data_[32], &bin_msg.data_[36], &ros_msg->station_id[0]);
00094
00095 ros_msg->num_satellites_tracked = bin_msg.data_[36];
00096 ros_msg->num_satellites_used_in_solution = bin_msg.data_[37];
00097 ros_msg->num_satellites_above_elevation_mask_angle = bin_msg.data_[38];
00098 ros_msg->num_satellites_above_elevation_mask_angle_l2 = bin_msg.data_[39];
00099
00100 ros_msg->solution_source = SolutionSourceToMsgEnum(bin_msg.data_[40]);
00101
00102 GetExtendedSolutionStatusMessage(bin_msg.data_[41],
00103 ros_msg->extended_solution_status);
00104
00105
00106
00107 GetSignalsUsed(bin_msg.data_[43], ros_msg->signal_mask);
00108
00109 return ros_msg;
00110 }
00111
00112 novatel_gps_msgs::NovatelDualAntennaHeadingPtr DualAntennaHeadingParser::ParseAscii(const NovatelSentence& sentence) throw(ParseException)
00113 {
00114 novatel_gps_msgs::NovatelDualAntennaHeadingPtr ros_msg =
00115 boost::make_shared<novatel_gps_msgs::NovatelDualAntennaHeading>();
00116 HeaderParser h_parser;
00117 ros_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 DUALANTENNAHEADING message fields: " << sentence.body.size();
00123 throw ParseException(error.str());
00124 }
00125
00126 bool valid = true;
00127
00128 ros_msg->solution_status = sentence.body[0];
00129 ros_msg->position_type = sentence.body[1];
00130
00131 valid = valid && ParseFloat(sentence.body[2], ros_msg->baseline_length);
00132
00133 valid = valid && ParseFloat(sentence.body[3], ros_msg->heading);
00134 valid = valid && ParseFloat(sentence.body[4], ros_msg->pitch);
00135
00136
00137
00138 valid = valid && ParseFloat(sentence.body[6], ros_msg->heading_sigma);
00139 valid = valid && ParseFloat(sentence.body[7], ros_msg->pitch_sigma);
00140
00141 ros_msg->station_id = sentence.body[8];
00142
00143 valid = valid && ParseUInt8(sentence.body[9], ros_msg->num_satellites_tracked);
00144 valid = valid && ParseUInt8(sentence.body[10], ros_msg->num_satellites_used_in_solution);
00145 valid = valid && ParseUInt8(sentence.body[11], ros_msg->num_satellites_above_elevation_mask_angle);
00146 valid = valid && ParseUInt8(sentence.body[12], ros_msg->num_satellites_above_elevation_mask_angle_l2);
00147
00148 uint32_t solution_source = 0;
00149 valid = valid && ParseUInt32(sentence.body[13], solution_source, 16);
00150 ros_msg->solution_source = SolutionSourceToMsgEnum((uint8_t)solution_source);
00151
00152 uint32_t extended_solution_status = 0;
00153 valid = valid && ParseUInt32(sentence.body[14], extended_solution_status, 16);
00154 GetExtendedSolutionStatusMessage(
00155 extended_solution_status, ros_msg->extended_solution_status);
00156
00157
00158
00159 uint32_t signal_mask = 0;
00160 valid = valid && ParseUInt32(sentence.body[16], signal_mask, 16);
00161 GetSignalsUsed(signal_mask, ros_msg->signal_mask);
00162
00163 if (!valid)
00164 {
00165 throw ParseException("Invalid field in DUALANTENNAHEADING message");
00166 }
00167
00168 return ros_msg;
00169 }
00170
00171 uint8_t DualAntennaHeadingParser::SolutionSourceToMsgEnum(uint8_t source_mask) throw(ParseException) {
00172 uint8_t source_bits = source_mask & 0b00001100;
00173 if (source_mask == 0b0000) {
00174 return novatel_gps_msgs::NovatelDualAntennaHeading::SOURCE_PRIMARY_ANTENNA;
00175 } else if (source_mask == 0b0100) {
00176 return novatel_gps_msgs::NovatelDualAntennaHeading::SOURCE_SECONDARY_ANTENNA;
00177 } else {
00178 throw ParseException("DUALANTENNAHEADING Solution Source could not be parsed due to unknown source");
00179 }
00180 }
00181 };