gpgsv.cpp
Go to the documentation of this file.
1 // *****************************************************************************
2 //
3 // Copyright (c) 2017, Southwest Research Institute® (SwRI®)
4 // All rights reserved.
5 //
6 // Redistribution and use in source and binary forms, with or without
7 // modification, are permitted provided that the following conditions are met:
8 // * Redistributions of source code must retain the above copyright
9 // notice, this list of conditions and the following disclaimer.
10 // * Redistributions in binary form must reproduce the above copyright
11 // notice, this list of conditions and the following disclaimer in the
12 // documentation and/or other materials provided with the distribution.
13 // * Neither the name of Southwest Research Institute® (SwRI®) nor the
14 // names of its contributors may be used to endorse or promote products
15 // derived from this software without specific prior written permission.
16 //
17 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
18 // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20 // ARE DISCLAIMED. IN NO EVENT SHALL SOUTHWEST RESEARCH INSTITUTE BE LIABLE FOR ANY
21 // DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
22 // (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
23 // LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
24 // ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
26 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 //
28 // *****************************************************************************
29 
31 #include <boost/make_shared.hpp>
32 
33 const std::string novatel_gps_driver::GpgsvParser::MESSAGE_NAME = "GPGSV";
34 
36 {
37  return 0;
38 }
39 
41 {
42  return MESSAGE_NAME;
43 }
44 
46 {
47  const size_t MIN_LENGTH = 4;
48  // Check that the message is at least as long as a a GPGSV with no satellites
49  if (sentence.body.size() < MIN_LENGTH)
50  {
51  std::stringstream error;
52  error << "Expected GPGSV length >= " << MIN_LENGTH
53  << ", actual length = " << sentence.body.size();
54  throw ParseException(error.str());
55  }
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))
59  {
60  throw new ParseException("Error parsing n_msgs in GPGSV.");
61  }
62  if (msg->n_msgs > 9) // Check that number of messages <= 9
63  {
64  std::stringstream error;
65  error << "n_msgs in GPGSV was too large (" << msg->n_msgs << ").";
66  throw ParseException(error.str());
67  }
68 
69  if (!ParseUInt8(sentence.body[2], msg->msg_number))
70  {
71  throw ParseException("Error parsing msg_number in GPGSV.");
72  }
73  if (msg->msg_number > msg->n_msgs) // Check that this message is within the sequence range
74  {
75  std::stringstream error;
76  error << "msg_number in GPGSV was larger than n_msgs (" << msg->msg_number << " > " << msg->n_msgs << ").";
77  throw ParseException(error.str());
78  }
79  if (!ParseUInt8(sentence.body[3], msg->n_satellites))
80  {
81  throw ParseException("Error parsing n_satellites in GPGSV.");
82  }
83 
84 
85  // Figure out how many satellites should be described in this sentence
86  size_t n_sats_in_sentence = 4;
87  if (msg->msg_number == msg->n_msgs)
88  {
89  n_sats_in_sentence = msg->n_satellites % static_cast<uint8_t>(4);
90  }
91  if (n_sats_in_sentence == 0)
92  {
93  n_sats_in_sentence = 4;
94  }
95  // Check that the sentence is the right length for the number of satellites
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)
98  {
99  std::stringstream ss;
100  for (size_t i = 0; i < sentence.body.size(); ++i)
101  {
102  ss << sentence.body[i];
103  if ((i+1) < sentence.body.size())
104  {
105  ss << ",";
106  }
107  }
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();
112  throw ParseException(error.str());
113  }
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)
116  {
117  if (!ParseUInt8(sentence.body[index], msg->satellites[sat].prn))
118  {
119  std::stringstream error;
120  error << "Error parsing prn for satellite " << sat << " in GPGSV.";
121  throw ParseException(error.str());
122  }
123 
124  float elevation;
125  if (!ParseFloat(sentence.body[index + 1], elevation))
126  {
127  std::stringstream error;
128  error << "Error parsing elevation for satellite " << sat << " in GPGSV.";
129  throw ParseException(error.str());
130  }
131  msg->satellites[sat].elevation = static_cast<uint8_t>(elevation);
132 
133  float azimuth;
134  if (!ParseFloat(sentence.body[index + 2], azimuth))
135  {
136  std::stringstream error;
137  error << "Error parsing azimuth for satellite " << sat << " in GPGSV.";
138  throw ParseException(error.str());
139  }
140  msg->satellites[sat].azimuth = static_cast<uint16_t>(azimuth);
141 
142  if ((index + 3) >= sentence.body.size() || sentence.body[index + 3].empty())
143  {
144  msg->satellites[sat].snr = -1;
145  }
146  else
147  {
148  uint8_t snr;
149  if (!ParseUInt8(sentence.body[index + 3], snr))
150  {
151  std::stringstream error;
152  error << "Error parsing snr for satellite " << sat << " in GPGSV.";
153  throw ParseException(error.str());
154  }
155 
156  msg->satellites[sat].snr = static_cast<int8_t>(snr);
157  }
158  }
159  return msg;
160 }
msg
const std::string GetMessageName() const override
Definition: gpgsv.cpp:40
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
Definition: gpgsv.h:47
float ParseFloat(const uint8_t *buffer)
Converts a buffer containing 4 bytes into a float.
uint32_t GetMessageId() const override
Definition: gpgsv.cpp:35
novatel_gps_msgs::GpgsvPtr ParseAscii(const NmeaSentence &sentence) override
Converts sentence into a ROS message pointer and returns it.
Definition: gpgsv.cpp:45


novatel_gps_driver
Author(s):
autogenerated on Wed Jul 3 2019 19:36:46