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);
92 size_t expected_length = MIN_LENGTH + 4 * n_sats_in_sentence;
93 if (n_sats_in_sentence == 0)
99 if (sentence.body.size() != expected_length && sentence.body.size() != expected_length -1)
101 std::stringstream ss;
102 for (
size_t i = 0; i < sentence.body.size(); ++i)
104 ss << sentence.body[i];
105 if ((i+1) < sentence.body.size())
110 std::stringstream error;
111 error <<
"Expected GPGSV length = " << expected_length <<
" for message with " 112 << n_sats_in_sentence <<
" satellites, actual length = " 113 << sentence.body.size() <<
"\n" << ss.str().c_str();
116 msg->satellites.resize(n_sats_in_sentence);
117 for (
size_t sat = 0, index=MIN_LENGTH; sat < n_sats_in_sentence; ++sat, index += 4)
119 if (!
ParseUInt8(sentence.body[index], msg->satellites[sat].prn))
121 std::stringstream error;
122 error <<
"Error parsing prn for satellite " << sat <<
" in GPGSV.";
127 if (!
ParseFloat(sentence.body[index + 1], elevation))
129 std::stringstream error;
130 error <<
"Error parsing elevation for satellite " << sat <<
" in GPGSV.";
133 msg->satellites[sat].elevation =
static_cast<uint8_t
>(elevation);
136 if (!
ParseFloat(sentence.body[index + 2], azimuth))
138 std::stringstream error;
139 error <<
"Error parsing azimuth for satellite " << sat <<
" in GPGSV.";
142 msg->satellites[sat].azimuth =
static_cast<uint16_t
>(azimuth);
144 if ((index + 3) >= sentence.body.size() || sentence.body[index + 3].empty())
146 msg->satellites[sat].snr = -1;
151 if (!
ParseUInt8(sentence.body[index + 3], snr))
153 std::stringstream error;
154 error <<
"Error parsing snr for satellite " << sat <<
" in GPGSV.";
158 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
novatel_gps_msgs::GpgsvPtr ParseAscii(const NmeaSentence &sentence) noexcept(false) override
Converts sentence into a ROS message pointer and returns it.
float ParseFloat(const uint8_t *buffer)
Converts a buffer containing 4 bytes into a float.
uint32_t GetMessageId() const override