24 #ifndef GOBY_MIDDLEWARE_MARSHALLING_MAVLINK_H
25 #define GOBY_MIDDLEWARE_MARSHALLING_MAVLINK_H
34 #include <type_traits>
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_;
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)
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;
174 template <
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);
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));
248 template <
typename Tuple,
250 typename std::enable_if<std::is_base_of<mavlink::Message, T>::value>
::type* =
nullptr>
257 template <
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>