Goby3 3.2.3
2025.05.13
Loading...
Searching...
No Matches
common.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_MIDDLEWARE_IO_MAVLINK_COMMON_H
25#define GOBY_MIDDLEWARE_IO_MAVLINK_COMMON_H
26
27#include <cstdint> // for uint8_t
28#include <memory> // for shared_ptr, __sh...
29#include <sstream> // for basic_ostream<>:...
30#include <string> // for string
31#include <vector> // for vector
32
33#include <mavlink/v2.0/common/common.hpp>
34
35#include "goby/exception.h" // for Exception
36#include "goby/middleware/io/detail/io_interface.h" // for PubSubLayer, Pub...
37#include "goby/middleware/marshalling/interface.h" // for MarshallingScheme
38#include "goby/middleware/marshalling/mavlink.h" // for SerializerParser...
39#include "goby/middleware/protobuf/io.pb.h" // for IOData
40#include "goby/util/debug_logger/flex_ostream.h" // for operator<<, Flex...
41
42namespace goby
43{
44namespace middleware
45{
46class Group;
47}
48} // namespace goby
49
50namespace goby
51{
52namespace middleware
53{
54namespace io
55{
56template <const goby::middleware::Group& line_in_group,
57 const goby::middleware::Group& line_out_group, PubSubLayer publish_layer,
58 PubSubLayer subscribe_layer, typename IOThreadBase, typename IOConfig>
60{
61 public:
62 IOThreadMAVLink(const IOConfig& config) : IOThreadBase(config)
63 {
64 // subscribe directly to mavlink_message_t as well
65 if (subscribe_layer == PubSubLayer::INTERPROCESS)
66 {
67 auto msg_out_callback = [this](std::shared_ptr<const mavlink::mavlink_message_t> msg,
68 const std::string& type) {
70 goby::glog << "writing msg [sysid: " << static_cast<int>(msg->sysid)
71 << ", compid: " << static_cast<int>(msg->compid)
72 << "] of msgid: " << static_cast<int>(msg->msgid) << std::endl;
73 auto io_msg = std::make_shared<goby::middleware::protobuf::IOData>();
74 auto data = SerializerParserHelper<mavlink::mavlink_message_t,
75 MarshallingScheme::MAVLINK>::serialize(*msg);
76 io_msg->set_data(&data[0], data.size());
77 this->write(io_msg);
78 };
79
80 this->interprocess()
81 .template subscribe_type_regex<line_out_group, mavlink::mavlink_message_t>(
82 msg_out_callback);
83 }
84 }
85
87
88 protected:
89 void try_parse(std::size_t bytes_transferred);
90 std::array<char, MAVLINK_MAX_PACKET_LEN>& buffer() { return buffer_; }
91
92 private:
93 void clear_buffers()
94 {
95 msg_ = std::make_shared<mavlink::mavlink_message_t>();
96 status_ = {};
97 msg_buffer_ = {};
98 status_buffer_ = {};
99 }
100
101 private:
102 std::array<char, MAVLINK_MAX_PACKET_LEN> buffer_;
103 std::shared_ptr<mavlink::mavlink_message_t> msg_ =
104 std::make_shared<mavlink::mavlink_message_t>();
105 mavlink::mavlink_message_t msg_buffer_{};
106 mavlink::mavlink_status_t status_{}, status_buffer_{};
107};
108} // namespace io
109} // namespace middleware
110} // namespace goby
111
112template <
113 const goby::middleware::Group& line_in_group, const goby::middleware::Group& line_out_group,
115 goby::middleware::io::PubSubLayer subscribe_layer, typename IOThreadBase, typename IOConfig>
116void goby::middleware::io::IOThreadMAVLink<line_in_group, line_out_group, publish_layer,
117 subscribe_layer, IOThreadBase,
118 IOConfig>::try_parse(std::size_t bytes_transferred)
119{
120 auto bytes_begin = buffer_.begin(), bytes_end = buffer_.begin() + bytes_transferred;
121 for (auto c = bytes_begin; c != bytes_end; ++c)
122 {
123 try
124 {
125 auto res = mavlink::mavlink_frame_char_buffer(&msg_buffer_, &status_buffer_, *c,
126 msg_.get(), &status_);
127 switch (res)
128 {
129 case mavlink::MAVLINK_FRAMING_BAD_CRC:
130 if (status_.parse_state != mavlink::MAVLINK_PARSE_STATE_IDLE)
131 {
132 break; // keep parsing
133 }
134 else if (mavlink::mavlink_get_msg_entry(msg_->msgid) == nullptr)
135 {
137 goby::glog << "BAD CRC decoding MAVLink msg, but "
138 "forwarding because we don't know this msgid"
139 << std::endl;
140 // forward anyway as it might be a msgid we don't know
141 // so flow through here (no break) is intentional!!
142 }
143 else
144 {
145 goby::glog.is_warn() && goby::glog << "BAD CRC decoding MAVLink msg"
146 << std::endl;
147 break;
148 }
149
150 case mavlink::MAVLINK_FRAMING_OK:
151 {
152 goby::glog.is_debug3() && goby::glog << "Parsed message of id: " << msg_->msgid
153 << std::endl;
154
155 this->publish_in(msg_);
156
157 std::array<uint8_t, MAVLINK_MAX_PACKET_LEN> buffer;
158 auto length = mavlink::mavlink_msg_to_send_buffer(&buffer[0], msg_.get());
159 std::string bytes(buffer.begin(), buffer.begin() + length);
160 this->handle_read_success(length, bytes);
161 break;
162 }
163
164 case mavlink::MAVLINK_FRAMING_INCOMPLETE: break;
165
166 case mavlink::MAVLINK_FRAMING_BAD_SIGNATURE:
167 goby::glog.is_warn() && goby::glog << "BAD SIGNATURE decoding MAVLink msg"
168 << std::endl;
169 break;
170 default:
171 goby::glog.is_warn() && goby::glog << "Unknown value " << res
172 << " returned while decoding MAVLink msg"
173 << std::endl;
174 break;
175 }
176 }
177 catch (goby::Exception& e)
178 {
179 goby::glog.is_warn() && goby::glog << "Exception decoding MAVLink msg: " << e.what()
180 << std::endl;
181 clear_buffers();
182 }
183 }
184}
185
186#endif
simple exception class for goby applications
Definition exception.h:35
Class for grouping publications in the Goby middleware. Analogous to "topics" in ROS,...
Definition group.h:60
The global namespace for the Goby project.
extern ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier< ::PROTOBUF_NAMESPACE_ID::MessageOptions, ::PROTOBUF_NAMESPACE_ID::internal::MessageTypeTraits< ::goby::GobyMessageOptions >, 11, false > msg
util::FlexOstream glog
Access the Goby logger through this object.
Class for parsing and serializing a given marshalling scheme. Must be specialized for a particular sc...
Definition interface.h:98