QGroundControl
Ground Control Station for MAVLink Drones
Loading...
Searching...
No Matches
RTCMMAVLink.cc
Go to the documentation of this file.
1#include "RTCMMAVLink.h"
2
3#include <cstring>
4#include <memory>
5#include <utility>
6
7#include "LinkInterface.h"
8#include "MAVLinkLib.h"
9#include "MAVLinkProtocol.h"
10#include "MultiVehicleManager.h"
11#include "QGCLoggingCategory.h"
12#include "QmlObjectListModel.h"
13#include "Vehicle.h"
14#include "VehicleLinkManager.h"
15
16QGC_LOGGING_CATEGORY(RTCMMAVLinkLog, "GPS.Corrections.RTCMMavlink")
17static_assert(RTCMMAVLinkPacket::kFragmentLen == MAVLINK_MSG_GPS_RTCM_DATA_FIELD_DATA_LEN);
18
19namespace {
20
21RTCMMAVLink::Output makeOutput(const std::shared_ptr<LinkInterface>& link)
22{
23 // Outputs hold the link weakly so they never extend its lifetime.
24 return [weakLink = std::weak_ptr<LinkInterface>(link)](const GPSRTCMPacket& packet) {
25 if (packet.data.size() > RTCMMAVLinkPacket::kFragmentLen) {
26 qCWarning(RTCMMAVLinkLog) << "RTCM packet exceeds MAVLink payload limit";
27 return false;
28 }
29 const auto target = weakLink.lock();
30 if (!target || !target->isConnected() || !target->mavlinkChannelIsSet()) {
31 return false;
32 }
33 mavlink_gps_rtcm_data_t payload{};
34 payload.flags = packet.flags;
35 payload.len = static_cast<uint8_t>(packet.data.size());
36 if (!packet.data.isEmpty()) {
37 std::memcpy(payload.data, packet.data.constData(), packet.data.size());
38 }
39 mavlink_message_t message{};
40 mavlink_msg_gps_rtcm_data_encode_chan(MAVLinkProtocol::instance()->getSystemId(),
41 MAVLinkProtocol::getComponentId(), target->mavlinkChannel(), &message,
42 &payload);
43 target->sendMessageThreadSafe(message);
44 return true;
45 };
46}
47
48} // namespace
49
51 : _outputProvider(vehicleLinkOutputs())
52{
53 qCDebug(RTCMMAVLinkLog) << this;
54}
55
57{
58 qCDebug(RTCMMAVLinkLog) << this;
59}
60
62{
63 return []() {
64 QList<std::shared_ptr<LinkInterface>> links;
65 QList<Output> outputs;
66 auto* manager = MultiVehicleManager::instance();
67 if (!manager) {
68 return outputs;
69 }
70 auto* vehicles = manager->vehicles();
71 for (int index = 0; index < vehicles->count(); ++index) {
72 auto* vehicle = vehicles->value<Vehicle*>(index);
73 if (!vehicle || !vehicle->vehicleLinkManager()) {
74 continue;
75 }
76 auto link = vehicle->vehicleLinkManager()->primaryLink().lock();
77 if (!link || !link->isConnected() || link->isLogReplay() || links.contains(link)) {
78 continue;
79 }
80 outputs.append(makeOutput(link));
81 links.append(std::move(link));
82 }
83 return outputs;
84 };
85}
86
88{
89 _outputProvider = std::move(provider);
90}
91
92quint64 RTCMMAVLink::submitToOutputs(QByteArrayView data)
93{
94 if (data.isEmpty()) {
95 return 0;
96 }
97 const auto packed = RTCMMAVLinkPacket::pack(data, _sequenceId);
98 _sequenceId = packed.nextSequenceId;
99 const auto outputs = _outputProvider ? _outputProvider() : QList<Output>();
100 quint64 submitted = 0;
101 for (const auto& output : outputs) {
102 if (!output) {
103 continue;
104 }
105 for (const auto& packet : packed.packets) {
106 if (!output(packet)) {
107 break;
108 }
109 submitted += packet.data.size();
110 }
111 }
112 _submittedBytes += submitted;
113 return submitted;
114}
struct __mavlink_message mavlink_message_t
#define QGC_LOGGING_CATEGORY(name, categoryStr)
static int getComponentId()
static MAVLinkProtocol * instance()
static MultiVehicleManager * instance()
Pure GPS_RTCM_DATA fragmentation; no vehicle, link, or application dependencies.
static PackResult pack(QByteArrayView data, uint8_t sequenceId)
static constexpr qsizetype kFragmentLen
WeakLinkInterfacePtr primaryLink() const
VehicleLinkManager * vehicleLinkManager()
Definition Vehicle.h:597