Goby3 3.2.3
2025.05.13
Loading...
Searching...
No Matches
encode.h
Go to the documentation of this file.
1// Copyright 2011-2021:
2// GobySoft, LLC (2013-)
3// Massachusetts Institute of Technology (2007-2014)
4// Community contributors (see AUTHORS file)
5// File authors:
6// Toby Schneider <toby@gobysoft.org>
7//
8//
9// This file is part of the Goby Underwater Autonomy Project Libraries
10// ("The Goby Libraries").
11//
12// The Goby Libraries are free software: you can redistribute them and/or modify
13// them under the terms of the GNU Lesser General Public License as published by
14// the Free Software Foundation, either version 2.1 of the License, or
15// (at your option) any later version.
16//
17// The Goby Libraries are distributed in the hope that they will be useful,
18// but WITHOUT ANY WARRANTY; without even the implied warranty of
19// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20// GNU Lesser General Public License for more details.
21//
22// You should have received a copy of the GNU Lesser General Public License
23// along with Goby. If not, see <http://www.gnu.org/licenses/>.
24
25#ifndef GOBY_UTIL_AIS_ENCODE_H
26#define GOBY_UTIL_AIS_ENCODE_H
27
28#include <atomic> // for atomic
29#include <cmath> // for round
30#include <cstdint> // for uint32_t, uint8_t
31#include <stdexcept> // for runtime_error
32#include <string> // for string, allocator
33#include <vector> // for vector
34
35#include <boost/algorithm/string/case_conv.hpp> // for to_upper
36#include <boost/dynamic_bitset/dynamic_bitset.hpp> // for dynamic_bitset
37#include <boost/units/base_unit.hpp> // for base_unit<>::unit...
38#include <boost/units/base_units/metric/knot.hpp> // for knot_base_unit
39#include <boost/units/quantity.hpp> // for quantity, operator*
40#include <boost/units/systems/angle/degrees.hpp> // for plane_angle, degrees
41
42namespace goby
43{
44namespace util
45{
46class NMEASentence;
47
48namespace ais
49{
50namespace protobuf
51{
52class Position;
53class Voyage;
54} // namespace protobuf
55
56class EncoderException : public std::runtime_error
57{
58 public:
59 EncoderException(const std::string& what) : std::runtime_error(what) {}
60};
61
63{
64 public:
66 Encoder(const goby::util::ais::protobuf::Voyage& voy, int part_num = 0);
67
68 boost::dynamic_bitset<> as_bitset() const { return bits_; }
69
70 std::vector<NMEASentence> as_nmea() const;
71
72 private:
73 void encode_msg_18(const goby::util::ais::protobuf::Position& pos);
74 void encode_msg_24(const goby::util::ais::protobuf::Voyage& voy, std::uint32_t part_num);
75
76 boost::units::quantity<boost::units::degree::plane_angle>
77 wrap_0_360(boost::units::quantity<boost::units::degree::plane_angle> in)
78 {
79 auto full_revolution = 360 * boost::units::degree::degrees;
80 while (in < 0 * boost::units::degree::degrees) in += full_revolution;
81 while (in >= full_revolution) in -= full_revolution;
82 return in;
83 }
84
85 // lat/lon as 1/10000 minutes
86 template <typename AngleType, typename ValueType>
87 std::uint32_t ais_latlon(boost::units::quantity<AngleType, ValueType> ll)
88 {
89 return static_cast<std::int32_t>(std::round(
90 boost::units::quantity<boost::units::degree::plane_angle>(ll).value() * 600000.0));
91 }
92
93 // 0 - 360 as tenths
94 template <typename AngleType, typename ValueType>
95 std::uint32_t ais_angle(boost::units::quantity<AngleType, ValueType> a, int precision)
96 {
97 return static_cast<std::uint32_t>(std::round(
98 wrap_0_360(boost::units::quantity<boost::units::degree::plane_angle>(a)).value() *
99 std::pow(10, precision)));
100 }
101
102 // 1/10 knots
103 template <typename SpeedType, typename ValueType>
104 std::uint32_t ais_speed(boost::units::quantity<SpeedType, ValueType> s)
105 {
106 return static_cast<std::uint32_t>(std::round(
107 boost::units::quantity<boost::units::metric::knot_base_unit::unit_type>(s).value() *
108 10));
109 }
110
111 struct AISField;
112 friend std::ostream& operator<<(std::ostream& os, const Encoder::AISField& ais);
113
114 void concatenate_bitset(const std::vector<AISField>& fields)
115 {
116 for (auto it = fields.rbegin(), end = fields.rend(); it != end; ++it)
117 {
118 auto fb = it->as_bitset();
119 for (int i = 0, n = fb.size(); i < n; ++i) bits_.push_back(fb[i]);
120 }
121 }
122
123 private:
124 struct AISField
125 {
126 std::uint8_t len{0};
127 std::uint32_t u{0};
128 std::string s{};
129 bool is_string{false};
130
131 boost::dynamic_bitset<> as_bitset() const
132 {
133 if (is_string)
134 {
135 constexpr int ais_bits_per_char = 6;
136 std::string ms = s;
137 ms.resize(len / ais_bits_per_char, '@');
138 boost::to_upper(ms);
139
140 boost::dynamic_bitset<> bits(len, 0);
141 for (int i = 0, n = ms.size(); i < n; ++i)
142 {
143 char c = ms[i];
144
145 if (c >= '@' && c <= '_')
146 c -= '@';
147 else if (c >= ' ' && c <= '?')
148 ; // no change from ascii value
149 else // other values that can't be represented
150 c = '@';
151
152 boost::dynamic_bitset<> char_bits(len, c & 0x3F);
153 bits |= (char_bits << (n - i - 1) * ais_bits_per_char);
154 }
155 return bits;
156 }
157 else
158 {
159 return boost::dynamic_bitset<>(len, u);
160 }
161 }
162 };
163
164 boost::dynamic_bitset<> bits_;
165 enum class RadioChannel
166 {
167 CLASS_A,
168 CLASS_B
169 };
170 RadioChannel channel_{RadioChannel::CLASS_B};
171
172 static std::atomic<int> sequence_id_;
173};
174
175std::ostream& operator<<(std::ostream& os, const Encoder::AISField& ais)
176{
177 os << "l:" << static_cast<int>(ais.len) << ", ";
178 if (ais.is_string)
179 os << "s: " << ais.s;
180 else
181 {
182 os << "u: " << ais.u;
183 os << ", i: " << static_cast<std::int32_t>(ais.u);
184 }
185 return os;
186}
187
188} // namespace ais
189} // namespace util
190} // namespace goby
191
192#endif
EncoderException(const std::string &what)
Definition encode.h:59
std::vector< NMEASentence > as_nmea() const
friend std::ostream & operator<<(std::ostream &os, const Encoder::AISField &ais)
Definition encode.h:175
Encoder(const goby::util::ais::protobuf::Voyage &voy, int part_num=0)
Encoder(const goby::util::ais::protobuf::Position &pos)
boost::dynamic_bitset as_bitset() const
Definition encode.h:68
The global namespace for the Goby project.
STL namespace.