Goby3 3.2.3
2025.05.13
Loading...
Searching...
No Matches
decode.h
Go to the documentation of this file.
1// Copyright 2019-2021:
2// GobySoft, LLC (2013-)
3// Community contributors (see AUTHORS file)
4// File authors:
5// Toby Schneider <toby@gobysoft.org>
6//
7//
8// This file is part of the Goby Underwater Autonomy Project Libraries
9// ("The Goby Libraries").
10//
11// The Goby Libraries are free software: you can redistribute them and/or modify
12// them under the terms of the GNU Lesser General Public License as published by
13// the Free Software Foundation, either version 2.1 of the License, or
14// (at your option) any later version.
15//
16// The Goby Libraries are distributed in the hope that they will be useful,
17// but WITHOUT ANY WARRANTY; without even the implied warranty of
18// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19// GNU Lesser General Public License for more details.
20//
21// You should have received a copy of the GNU Lesser General Public License
22// along with Goby. If not, see <http://www.gnu.org/licenses/>.
23
24#ifndef GOBY_UTIL_AIS_DECODE_H
25#define GOBY_UTIL_AIS_DECODE_H
26
27#include <memory> // for unique_ptr
28#include <ostream> // for operator<<
29#include <stdexcept> // for runtime_error
30#include <string> // for string
31#include <vector> // for vector
32
33#include <ais.h> // for string, ostream
34#include <boost/algorithm/string/classification.hpp> // for pred_orF, is_...
35#include <boost/algorithm/string/predicate_facade.hpp> // for predicate_facade
36#include <boost/algorithm/string/trim.hpp> // for trim_if
37#include <boost/units/base_unit.hpp> // for base_unit<>::...
38#include <boost/units/base_units/metric/knot.hpp> // for knot_base_unit
39#include <boost/units/operators.hpp> // for units
40#include <boost/units/systems/angle/degrees.hpp> // for degrees
41#include <boost/units/systems/si/length.hpp> // for meters
42#include <boost/units/systems/si/time.hpp> // for seconds
43#include <vdm.h> // for VdmStream
44
45#include "goby/util/linebasedcomms/nmea_sentence.h" // for NMEASentence
46#include "goby/util/protobuf/ais.pb.h" // for Voyage, Position
47
48namespace goby
49{
50namespace util
51{
52namespace ais
53{
54class DecoderException : public std::runtime_error
55{
56 public:
57 DecoderException(const std::string& what) : std::runtime_error(what) {}
58};
59
61{
62 public:
64 Decoder(const NMEASentence& nmea) : Decoder(std::vector<NMEASentence>(1, nmea)) {}
65 Decoder(const std::vector<NMEASentence>& nmeas);
66
67 // returns true if message is complete
68 bool push(const NMEASentence& nmea);
69
70 bool complete() { return ais_msg_ != nullptr; }
71
73 {
74 if (complete())
75 return ais_msg_->message_id;
76 else
77 throw(DecoderException("Message not complete: missing NMEA sentences?"));
78 }
79
80 enum class ParsedType
81 {
84 VOYAGE
85 };
86
88 {
89 switch (message_id())
90 {
91 case 1:
92 case 2:
93 case 3:
94 case 18:
95 case 19: return ParsedType::POSITION;
96 case 5:
97 case 24: return ParsedType::VOYAGE;
98 default: return ParsedType::NOT_SUPPORTED;
99 }
100 }
101
104
105 libais::AisMsg& as_libais_msg()
106 {
107 if (complete())
108 return *ais_msg_;
109 else
110 throw(DecoderException("Message not complete: missing NMEA sentences?"));
111 }
112
113 private:
114 std::string trim_ais_string(std::string in)
115 {
116 boost::trim_if(in, boost::algorithm::is_space() || boost::algorithm::is_any_of("@"));
117 return in;
118 }
119
120 template <typename LibAisMessage>
121 void set_shared_fields(goby::util::ais::protobuf::Voyage& /*voy*/, const LibAisMessage& ais,
122 int part_num)
123 {
124 using namespace boost::units;
125
126 voy_.set_message_id(ais.message_id);
127 voy_.set_mmsi(ais.mmsi);
128
129 if (part_num == 0)
130 {
131 std::string name = trim_ais_string(ais.name);
132 if (!name.empty())
133 voy_.set_name(name);
134 }
135 else if (part_num == 1)
136 {
137 std::string callsign = trim_ais_string(ais.callsign);
138 if (!callsign.empty())
139 voy_.set_callsign(callsign);
140
141 if (protobuf::Voyage::ShipType_IsValid(ais.type_and_cargo))
142 voy_.set_type(static_cast<protobuf::Voyage::ShipType>(ais.type_and_cargo));
143 voy_.set_to_bow_with_units(ais.dim_a * si::meters);
144 voy_.set_to_stern_with_units(ais.dim_b * si::meters);
145 voy_.set_to_port_with_units(ais.dim_c * si::meters);
146 voy_.set_to_starboard_with_units(ais.dim_d * si::meters);
147 }
148 }
149
150 template <typename LibAisMessage>
151 void set_shared_fields(goby::util::ais::protobuf::Position& pos, const LibAisMessage& ais)
152 {
153 using namespace boost::units;
154 pos.set_message_id(ais.message_id);
155 pos.set_mmsi(ais.mmsi);
156 metric::knot_base_unit::unit_type knots;
157 pos.set_speed_over_ground_with_units(ais.sog * knots);
158 pos.set_lat_with_units(ais.position.lat_deg * degree::degrees);
159 pos.set_lon_with_units(ais.position.lng_deg * degree::degrees);
160 pos.set_course_over_ground_with_units(ais.cog * degree::degrees);
161 if (ais.true_heading >= 0 && ais.true_heading < 360)
162 pos.set_true_heading_with_units(ais.true_heading * degree::degrees);
163 pos.set_report_second_with_units(ais.timestamp * si::seconds);
164 pos.set_raim(ais.raim);
165
166 if (protobuf::Position::PositionAccuracy_IsValid(ais.position_accuracy))
168 static_cast<protobuf::Position::PositionAccuracy>(ais.position_accuracy));
169 }
170
171 void decode_position();
172 void decode_voyage();
173
174 private:
175 libais::VdmStream ais_stream_decoder_;
176 std::unique_ptr<libais::AisMsg> ais_msg_;
177
180};
181
182inline ostream& operator<<(ostream& os, Decoder::ParsedType t)
183{
184 switch (t)
185 {
186 default:
187 case Decoder::ParsedType::NOT_SUPPORTED: return os << "NOT_SUPPORTED";
188 case Decoder::ParsedType::VOYAGE: return os << "VOYAGE";
189 case Decoder::ParsedType::POSITION: return os << "POSITION";
190 }
191}
192
193} // namespace ais
194} // namespace util
195} // namespace goby
196
197#endif
DecoderException(const std::string &what)
Definition decode.h:57
ParsedType parsed_type()
Definition decode.h:87
bool push(const NMEASentence &nmea)
goby::util::ais::protobuf::Position as_position()
Decoder(const NMEASentence &nmea)
Definition decode.h:64
Decoder(const std::vector< NMEASentence > &nmeas)
goby::util::ais::protobuf::Voyage as_voyage()
libais::AisMsg & as_libais_msg()
Definition decode.h:105
void set_lon_with_units(Quantity value_w_units)
Definition ais.pb.h:747
Position_PositionAccuracy PositionAccuracy
Definition ais.pb.h:480
void set_lat_with_units(Quantity value_w_units)
Definition ais.pb.h:732
void set_position_accuracy(::goby::util::ais::protobuf::Position_PositionAccuracy value)
Definition ais.pb.h:1795
void set_true_heading_with_units(Quantity value_w_units)
Definition ais.pb.h:777
void set_course_over_ground_with_units(Quantity value_w_units)
Definition ais.pb.h:762
void set_message_id(int32_t value)
Definition ais.pb.h:1624
void set_speed_over_ground_with_units(Quantity value_w_units)
Definition ais.pb.h:717
static bool PositionAccuracy_IsValid(int value)
Definition ais.pb.h:485
void set_mmsi(int32_t value)
Definition ais.pb.h:1652
void set_report_second_with_units(Quantity value_w_units)
Definition ais.pb.h:792
void set_message_id(int32_t value)
Definition ais.pb.h:1995
void set_to_port_with_units(Quantity value_w_units)
Definition ais.pb.h:1519
void set_to_stern_with_units(Quantity value_w_units)
Definition ais.pb.h:1504
static bool ShipType_IsValid(int value)
Definition ais.pb.h:1157
void set_callsign(ArgT0 &&arg0, ArgT... args)
void set_type(::goby::util::ais::protobuf::Voyage_ShipType value)
Definition ais.pb.h:2216
void set_to_bow_with_units(Quantity value_w_units)
Definition ais.pb.h:1489
void set_name(ArgT0 &&arg0, ArgT... args)
void set_to_starboard_with_units(Quantity value_w_units)
Definition ais.pb.h:1534
void set_mmsi(int32_t value)
Definition ais.pb.h:2023
The global namespace for the Goby project.
STL namespace.