31 #include <boost/make_shared.hpp> 47 const size_t MIN_LENGTH = 4;
49 if (sentence.body.size() < MIN_LENGTH)
51 std::stringstream error;
52 error <<
"Expected GPGSV length >= " << MIN_LENGTH
53 <<
", actual length = " << sentence.body.size();
56 novatel_gps_msgs::GpgsvPtr
msg = boost::make_shared<novatel_gps_msgs::Gpgsv>();
57 msg->message_id = sentence.body[0];
58 if (!
ParseUInt8(sentence.body[1], msg->n_msgs))
64 std::stringstream error;
65 error <<
"n_msgs in GPGSV was too large (" << msg->n_msgs <<
").";
69 if (!
ParseUInt8(sentence.body[2], msg->msg_number))
73 if (msg->msg_number > msg->n_msgs)
75 std::stringstream error;
76 error <<
"msg_number in GPGSV was larger than n_msgs (" << msg->msg_number <<
" > " << msg->n_msgs <<
").";
79 if (!
ParseUInt8(sentence.body[3], msg->n_satellites))
86 size_t n_sats_in_sentence = 4;
87 if (msg->msg_number == msg->n_msgs)
89 n_sats_in_sentence = msg->n_satellites %
static_cast<uint8_t
>(4);
91 if (n_sats_in_sentence == 0)
93 n_sats_in_sentence = 4;
96 size_t expected_length = MIN_LENGTH + 4 * n_sats_in_sentence;
97 if (sentence.body.size() != expected_length && sentence.body.size() != expected_length -1)
100 for (
size_t i = 0; i < sentence.body.size(); ++i)
102 ss << sentence.body[i];
103 if ((i+1) < sentence.body.size())
108 std::stringstream error;
109 error <<
"Expected GPGSV length = " << expected_length <<
" for message with " 110 << n_sats_in_sentence <<
" satellites, actual length = " 111 << sentence.body.size() <<
"\n" << ss.str().c_str();
114 msg->satellites.resize(n_sats_in_sentence);
115 for (
size_t sat = 0, index=MIN_LENGTH; sat < n_sats_in_sentence; ++sat, index += 4)
117 if (!
ParseUInt8(sentence.body[index], msg->satellites[sat].prn))
119 std::stringstream error;
120 error <<
"Error parsing prn for satellite " << sat <<
" in GPGSV.";
125 if (!
ParseFloat(sentence.body[index + 1], elevation))
127 std::stringstream error;
128 error <<
"Error parsing elevation for satellite " << sat <<
" in GPGSV.";
131 msg->satellites[sat].elevation =
static_cast<uint8_t
>(elevation);
134 if (!
ParseFloat(sentence.body[index + 2], azimuth))
136 std::stringstream error;
137 error <<
"Error parsing azimuth for satellite " << sat <<
" in GPGSV.";
140 msg->satellites[sat].azimuth =
static_cast<uint16_t
>(azimuth);
142 if ((index + 3) >= sentence.body.size() || sentence.body[index + 3].empty())
144 msg->satellites[sat].snr = -1;
149 if (!
ParseUInt8(sentence.body[index + 3], snr))
151 std::stringstream error;
152 error <<
"Error parsing snr for satellite " << sat <<
" in GPGSV.";
156 msg->satellites[sat].snr =
static_cast<int8_t
>(snr);
const std::string GetMessageName() const override
bool ParseUInt8(const std::string &string, uint8_t &value, int32_t base=10)
Parses a string containing an integer number into a uint16_t.
static const std::string MESSAGE_NAME
float ParseFloat(const uint8_t *buffer)
Converts a buffer containing 4 bytes into a float.
uint32_t GetMessageId() const override
novatel_gps_msgs::GpgsvPtr ParseAscii(const NmeaSentence &sentence) override
Converts sentence into a ROS message pointer and returns it.