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/gprmc.h>
00031 #include <boost/make_shared.hpp>
00032 #include <swri_string_util/string_util.h>
00033
00034 const std::string novatel_gps_driver::GprmcParser::MESSAGE_NAME = "GPRMC";
00035
00036 uint32_t novatel_gps_driver::GprmcParser::GetMessageId() const
00037 {
00038 return 0;
00039 }
00040
00041 const std::string novatel_gps_driver::GprmcParser::GetMessageName() const
00042 {
00043 return MESSAGE_NAME;
00044 }
00045
00046 novatel_gps_msgs::GprmcPtr novatel_gps_driver::GprmcParser::ParseAscii(const novatel_gps_driver::NmeaSentence& sentence) throw(ParseException)
00047 {
00048
00049 const size_t EXPECTED_LEN = 13;
00050 if (sentence.body.size() != EXPECTED_LEN)
00051 {
00052 std::stringstream error;
00053 error << "Expected GPRMC length = " << EXPECTED_LEN
00054 << ", actual length = " << sentence.body.size();
00055 throw ParseException(error.str());
00056 }
00057
00058 bool success = true;
00059 novatel_gps_msgs::GprmcPtr msg = boost::make_shared<novatel_gps_msgs::Gprmc>();
00060 msg->message_id = sentence.body[0];
00061
00062 if (sentence.body[1].empty() || sentence.body[1] == "0")
00063 {
00064 msg->utc_seconds = 0;
00065 }
00066 else
00067 {
00068 double utc_float;
00069 if (swri_string_util::ToDouble(sentence.body[1], utc_float))
00070 {
00071 msg->utc_seconds = UtcFloatToSeconds(utc_float);
00072 }
00073 else
00074 {
00075 throw ParseException("Error parsing UTC seconds in GPRMC log.");
00076 }
00077 }
00078
00079 msg->position_status = sentence.body[2];
00080
00081 success &= (sentence.body[2].compare("A") == 0);
00082 success &= !(sentence.body[3].empty() || sentence.body[5].empty());
00083
00084 bool valid = true;
00085
00086 double latitude = 0.0;
00087 valid = valid && ParseDouble(sentence.body[3], latitude);
00088 msg->lat = ConvertDmsToDegrees(latitude);
00089
00090 double longitude = 0.0;
00091 valid = valid && ParseDouble(sentence.body[5], longitude);
00092 msg->lon = ConvertDmsToDegrees(longitude);
00093
00094 msg->lat_dir = sentence.body[4];
00095 msg->lon_dir = sentence.body[6];
00096
00097 valid = valid && ParseFloat(sentence.body[7], msg->speed);
00098 msg->speed *= KNOTS_TO_MPS;
00099
00100 valid = valid && ParseFloat(sentence.body[8], msg->track);
00101
00102 std::string date_str = sentence.body[9];
00103 if (!date_str.empty())
00104 {
00105 msg->date = std::string("20") + date_str.substr(4, 2) +
00106 std::string("-") + date_str.substr(2, 2) +
00107 std::string("-") + date_str.substr(0, 2);
00108 }
00109 valid = valid && ParseFloat(sentence.body[10], msg->mag_var);
00110 msg->mag_var_direction = sentence.body[11];
00111 msg->mode_indicator = sentence.body[12];
00112
00113 if (!valid)
00114 {
00115 was_last_gps_valid_ = false;
00116 throw ParseException("Error parsing GPRMC message.");
00117 }
00118
00119 was_last_gps_valid_ = success;
00120
00121 return msg;
00122 }
00123
00124 bool novatel_gps_driver::GprmcParser::WasLastGpsValid() const
00125 {
00126 return was_last_gps_valid_;
00127 }