24#ifndef GOBY_MIDDLEWARE_MARSHALLING_MAVLINK_H
25#define GOBY_MIDDLEWARE_MARSHALLING_MAVLINK_H
35#include <unordered_map>
39#include <mavlink/v2.0/common/common.hpp>
57 template <std::
size_t Size>
60 std::lock_guard<std::mutex> lock(mavlink_registry_mutex_);
61 for (
const auto& entry : entries) entries_.insert(std::make_pair(entry.msgid, entry));
68 static const mavlink::mavlink_msg_entry_t*
get_msg_entry(uint32_t msgid)
73 std::lock_guard<std::mutex> lock(mavlink_registry_mutex_);
74 auto it = entries_.find(msgid);
75 if (it != entries_.end())
84 static std::unordered_map<uint32_t, mavlink::mavlink_msg_entry_t> entries_;
85 static std::mutex mavlink_registry_mutex_;
91 static std::vector<char>
serialize(
const mavlink::mavlink_message_t&
msg)
93 std::array<uint8_t, MAVLINK_MAX_PACKET_LEN> buffer;
94 auto length = mavlink::mavlink_msg_to_send_buffer(&buffer[0], &
msg);
95 return std::vector<char>(buffer.begin(), buffer.begin() + length);
98 static std::string
type_name(
const mavlink::mavlink_message_t&
msg)
100 return std::to_string(
msg.msgid);
103 template <
typename CharIterator>
104 static std::shared_ptr<mavlink::mavlink_message_t>
105 parse(CharIterator bytes_begin, CharIterator bytes_end, CharIterator& actual_end,
106 const std::string& type)
108 CharIterator c = bytes_begin;
109 auto msg = std::make_shared<mavlink::mavlink_message_t>();
110 mavlink::mavlink_message_t msg_buffer{};
111 mavlink::mavlink_status_t status{}, status_buffer{};
112 while (c != bytes_end)
114 auto res = mavlink::mavlink_frame_char_buffer(&msg_buffer, &status_buffer, *c,
119 case mavlink::MAVLINK_FRAMING_INCOMPLETE: ++c;
break;
121 case mavlink::MAVLINK_FRAMING_OK:
127 case mavlink::MAVLINK_FRAMING_BAD_CRC:
132 <<
" is unknown, so unable to validate CRC" << std::endl;
137 goby::glog <<
"BAD CRC decoding MAVLink type: " << type << std::endl;
141 case mavlink::MAVLINK_FRAMING_BAD_SIGNATURE:
143 goby::glog <<
"BAD SIGNATURE decoding MAVLink type: " << type << std::endl;
149 <<
"Unknown value " << res
150 <<
" returned while decoding MAVLink type: " << type
158 actual_end = bytes_end;
174template <
typename DataType,
typename Integer>
177 static std::vector<char>
178 serialize(
const std::tuple<Integer, Integer, DataType>& packet_with_metadata)
180 mavlink::mavlink_message_t
msg{};
181 mavlink::MsgMap map(
msg);
182 const DataType& packet = std::get<MAVLinkTupleIndices::PACKET_INDEX>(packet_with_metadata);
183 packet.serialize(map);
184 mavlink::mavlink_finalize_message(
185 &
msg, std::get<MAVLinkTupleIndices::SYSTEM_ID_INDEX>(packet_with_metadata),
186 std::get<MAVLinkTupleIndices::COMPONENT_ID_INDEX>(packet_with_metadata),
187 packet.MIN_LENGTH, packet.LENGTH, packet.CRC_EXTRA);
193 static std::string
type_name() {
return std::to_string(DataType::MSG_ID); }
194 static std::string
type_name(
const std::tuple<Integer, Integer, DataType>& )
199 template <
typename CharIterator>
200 static std::shared_ptr<std::tuple<Integer, Integer, DataType>>
201 parse(CharIterator bytes_begin, CharIterator bytes_end, CharIterator& actual_end,
206 bytes_begin, bytes_end, actual_end,
type_name());
207 auto packet_with_metadata = std::make_shared<std::tuple<Integer, Integer, DataType>>();
208 DataType* packet = &std::get<MAVLinkTupleIndices::PACKET_INDEX>(*packet_with_metadata);
209 mavlink::MsgMap map(
msg.get());
210 packet->deserialize(map);
211 std::get<MAVLinkTupleIndices::SYSTEM_ID_INDEX>(*packet_with_metadata) =
msg->sysid;
212 std::get<MAVLinkTupleIndices::COMPONENT_ID_INDEX>(*packet_with_metadata) =
msg->compid;
213 return packet_with_metadata;
220 static std::vector<char>
serialize(
const DataType& packet,
int sysid = 1,
int compid = 1)
223 serialize(std::make_tuple(sysid, compid, packet));
233 template <
typename CharIterator>
234 static std::shared_ptr<DataType>
parse(CharIterator bytes_begin, CharIterator bytes_end,
235 CharIterator& actual_end,
238 auto packet_with_metadata =
242 return std::make_shared<DataType>(
243 std::get<MAVLinkTupleIndices::PACKET_INDEX>(*packet_with_metadata));
248template <
typename Tuple,
249 typename T =
typename std::tuple_element<MAVLinkTupleIndices::PACKET_INDEX, Tuple>::type,
250 typename std::enable_if<std::is_base_of<mavlink::Message, T>::value>::type* =
nullptr>
257template <
typename T,
typename std::enable_if<
258 std::is_base_of<mavlink::Message, T>::value ||
259 std::is_same<mavlink::mavlink_message_t, T>::value>::type* =
nullptr>
constexpr int scheme()
Placeholder to provide an interface for the scheme() function family.
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.
A registry of mavlink types used for decoding.
static void register_default_dialects()
static const mavlink::mavlink_msg_entry_t * get_msg_entry(uint32_t msgid)
Retrieve a entry given a message id.
static void register_dialect_entries(std::array< mavlink::mavlink_msg_entry_t, Size > entries)
Register a new Mavlink dialect.
Enumeration and helper functions for marshalling scheme identification.
static std::string type_name()
static std::string type_name(const DataType &)
static std::vector< char > serialize(const DataType &packet, int sysid=1, int compid=1)
static std::shared_ptr< DataType > parse(CharIterator bytes_begin, CharIterator bytes_end, CharIterator &actual_end, const std::string &=type_name())
static std::shared_ptr< mavlink::mavlink_message_t > parse(CharIterator bytes_begin, CharIterator bytes_end, CharIterator &actual_end, const std::string &type)
static std::vector< char > serialize(const mavlink::mavlink_message_t &msg)
static std::string type_name(const mavlink::mavlink_message_t &msg)
static std::string type_name(const std::tuple< Integer, Integer, DataType > &)
static std::vector< char > serialize(const std::tuple< Integer, Integer, DataType > &packet_with_metadata)
static std::shared_ptr< std::tuple< Integer, Integer, DataType > > parse(CharIterator bytes_begin, CharIterator bytes_end, CharIterator &actual_end, const std::string &=type_name())
static std::string type_name()
Class for parsing and serializing a given marshalling scheme. Must be specialized for a particular sc...
static std::string type_name()
The marshalling scheme specific string name for this type.
static std::vector< char > serialize(const DataType &)
Given data, produce a vector of bytes.
static std::shared_ptr< DataType > parse(CharIterator bytes_begin, CharIterator bytes_end, CharIterator &actual_end, const std::string &type=type_name())
Given a beginning and end iterator to bytes, parse the data and return it.