Skip to content

Commit

Permalink
Comms: Update MockLink Threading
Browse files Browse the repository at this point in the history
  • Loading branch information
HTRamsey committed Feb 22, 2025
1 parent 2661097 commit a31e12c
Show file tree
Hide file tree
Showing 5 changed files with 159 additions and 53 deletions.
2 changes: 2 additions & 0 deletions src/Comms/MockLink/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ if(CMAKE_BUILD_TYPE STREQUAL "Debug")
MockLink.h
MockLinkFTP.cc
MockLinkFTP.h
MockLinkWorker.cc
MockLinkWorker.h
MockLinkMissionItemHandler.cc
MockLinkMissionItemHandler.h
)
Expand Down
68 changes: 23 additions & 45 deletions src/Comms/MockLink/MockLink.cc
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,9 @@
****************************************************************************/

#include "MockLink.h"

#include "LinkManager.h"
#include "MockLinkFTP.h"
#include "MockLinkWorker.h"
#include "QGCApplication.h"
#include "QGCLoggingCategory.h"

Expand Down Expand Up @@ -61,10 +61,15 @@ MockLink::MockLink(SharedLinkConfigurationPtr &config, QObject *parent)

(void) QObject::connect(this, &MockLink::writeBytesQueuedSignal, this, &MockLink::_writeBytesQueued, Qt::QueuedConnection);

(void) moveToThread(this);

_loadParams();
_runningTime.start();

_workerThread = new QThread(this);
_worker = new MockLinkWorker(this);
_worker->moveToThread(_workerThread);
(void) connect(_workerThread, &QThread::started, _worker, &MockLinkWorker::startWork);
(void) connect(_workerThread, &QThread::finished, _worker, &QObject::deleteLater);
_workerThread->start();
}

MockLink::~MockLink()
Expand All @@ -75,6 +80,11 @@ MockLink::~MockLink()
QFile::remove(_logDownloadFilename);
}

if (_workerThread) {
_workerThread->quit();
_workerThread->wait();
}

// qCDebug(MockLinkLog) << Q_FUNC_INFO << this;
}

Expand All @@ -86,7 +96,6 @@ bool MockLink::_connect()
mavlinkStatus->flags &= ~MAVLINK_STATUS_FLAG_OUT_MAVLINK1;
mavlink_status_t *const auxStatus = mavlink_get_channel_status(_getMavlinkAuxChannel());
auxStatus->flags &= ~MAVLINK_STATUS_FLAG_OUT_MAVLINK1;
start();
emit connected();
}

Expand All @@ -95,51 +104,15 @@ bool MockLink::_connect()

void MockLink::disconnect()
{
_missionItemHandler->shutdown();

if (_connected) {
_connected = false;
quit();
wait();
emit disconnected();
}
}

void MockLink::run()
{
QTimer timer1HzTasks;
QTimer timer10HzTasks;
QTimer timer500HzTasks;
QTimer timerStatusText;

(void) QObject::connect(&timer1HzTasks, &QTimer::timeout, this, &MockLink::_run1HzTasks);
(void) QObject::connect(&timer10HzTasks, &QTimer::timeout, this, &MockLink::_run10HzTasks);
(void) QObject::connect(&timer500HzTasks, &QTimer::timeout, this, &MockLink::_run500HzTasks);
(void) QObject::connect(&timerStatusText, &QTimer::timeout, this, &MockLink::_sendStatusTextMessages);

timer1HzTasks.start(1000);
timer10HzTasks.start(100);
timer500HzTasks.start(2);

// Wait a little bit for the ui to finish loading up before sending out status text messages
if (_sendStatusText) {
timerStatusText.setSingleShot(true);
timerStatusText.start(10000);
}

// Send first set right away
_run1HzTasks();
_run10HzTasks();
_run500HzTasks();

exec();

(void) QObject::disconnect(&timer1HzTasks, &QTimer::timeout, this, &MockLink::_run1HzTasks);
(void) QObject::disconnect(&timer10HzTasks, &QTimer::timeout, this, &MockLink::_run10HzTasks);
(void) QObject::disconnect(&timer500HzTasks, &QTimer::timeout, this, &MockLink::_run500HzTasks);

_missionItemHandler->shutdown();
}

void MockLink::_run1HzTasks()
void MockLink::run1HzTasks()
{
if (!_mavlinkStarted || !_connected) {
return;
Expand Down Expand Up @@ -168,7 +141,7 @@ void MockLink::_run1HzTasks()
}
}

void MockLink::_run10HzTasks()
void MockLink::run10HzTasks()
{
if (linkConfiguration()->isHighLatency()) {
return;
Expand All @@ -187,7 +160,7 @@ void MockLink::_run10HzTasks()
}
}

void MockLink::_run500HzTasks()
void MockLink::run500HzTasks()
{
if (linkConfiguration()->isHighLatency()) {
return;
Expand All @@ -199,6 +172,11 @@ void MockLink::_run500HzTasks()
}
}

void MockLink::sendStatusTextMessages()
{
_sendStatusTextMessages();
}

bool MockLink::_allocateMavlinkChannel()
{
// should only be called by the LinkManager during setup
Expand Down
21 changes: 13 additions & 8 deletions src/Comms/MockLink/MockLink.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@
#include <QtPositioning/QGeoCoordinate>

class MockLinkFTP;
class MockLinkWorker;
class QThread;

Q_DECLARE_LOGGING_CATEGORY(MockLinkLog)
Q_DECLARE_LOGGING_CATEGORY(MockLinkVerboseLog)
Expand All @@ -34,6 +36,13 @@ class MockLink : public LinkInterface
explicit MockLink(SharedLinkConfigurationPtr &config, QObject *parent = nullptr);
virtual ~MockLink();

void run1HzTasks();
void run10HzTasks();
void run500HzTasks();
void sendStatusTextMessages();

bool shouldSendStatusText() const { return _sendStatusText; }

bool isConnected() const final { return _connected; }
void disconnect() final;

Expand Down Expand Up @@ -109,20 +118,13 @@ class MockLink : public LinkInterface
private slots:
/// Called when QGC wants to write bytes to the MAV
void _writeBytes(const QByteArray &bytes) final;

void _writeBytesQueued(const QByteArray &bytes);
void _run1HzTasks();
void _run10HzTasks();
void _run500HzTasks();
void _sendStatusTextMessages();

private:
bool _connect() final;
bool _allocateMavlinkChannel() final;
void _freeMavlinkChannel() final;

void run() final;

uint8_t _getMavlinkAuxChannel() const { return _mavlinkAuxChannel; }
bool _mavlinkAuxChannelIsSet() const;

Expand Down Expand Up @@ -163,6 +165,7 @@ private slots:
void _sendSysStatus();
void _sendBatteryStatus();
void _sendChunkedStatusText(uint16_t chunkId, bool missingChunks);
void _sendStatusTextMessages();
void _respondWithAutopilotVersion();
void _sendRCChannels();
/// Sends the next parameter to the vehicle
Expand All @@ -181,6 +184,9 @@ private slots:
/// @return Fully qualified path to created file
static QString _createRandomFile(uint32_t byteCount);

QThread *_workerThread = nullptr;
MockLinkWorker *_worker = nullptr;

const MockConfiguration *_mockConfig = nullptr;
const MAV_AUTOPILOT _firmwareType = MAV_AUTOPILOT_PX4;
const MAV_TYPE _vehicleType = MAV_TYPE_QUADROTOR;
Expand Down Expand Up @@ -263,4 +269,3 @@ private slots:

static constexpr bool _mavlinkStarted = true;
};

79 changes: 79 additions & 0 deletions src/Comms/MockLink/MockLinkWorker.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
/****************************************************************************
*
* (c) 2009-2024 QGROUNDCONTROL PROJECT <http://www.qgroundcontrol.org>
*
* QGroundControl is licensed according to the terms in the file
* COPYING.md in the root of the source code directory.
*
****************************************************************************/

#include "MockLinkWorker.h"
#include "MockLink.h"

#include <QtCore/QTimer>

MockLinkWorker::MockLinkWorker(MockLink *link, QObject *parent)
: QObject(parent)
, _mockLink(link)
{

}

MockLinkWorker::~MockLinkWorker()
{
stopWork();
}

void MockLinkWorker::startWork()
{
_timer1Hz = new QTimer(this);
_timer10Hz = new QTimer(this);
_timer500Hz = new QTimer(this);
_timerStatusText = new QTimer(this);

(void) connect(_timer1Hz, &QTimer::timeout, this, &MockLinkWorker::run1HzTasks);
(void) connect(_timer10Hz, &QTimer::timeout, this, &MockLinkWorker::run10HzTasks);
(void) connect(_timer500Hz, &QTimer::timeout, this, &MockLinkWorker::run500HzTasks);
(void) connect(_timerStatusText, &QTimer::timeout, this, &MockLinkWorker::sendStatusTextMessages);

_timer1Hz->start(1000);
_timer10Hz->start(100);
_timer500Hz->start(2);

if (_mockLink->shouldSendStatusText()) {
_timerStatusText->setSingleShot(true);
_timerStatusText->start(10000);
}

run1HzTasks();
run10HzTasks();
run500HzTasks();
}

void MockLinkWorker::stopWork()
{
_timer1Hz->stop();
_timer10Hz->stop();
_timer500Hz->stop();
_timerStatusText->stop();
}

void MockLinkWorker::run1HzTasks()
{
_mockLink->run1HzTasks();
}

void MockLinkWorker::run10HzTasks()
{
_mockLink->run10HzTasks();
}

void MockLinkWorker::run500HzTasks()
{
_mockLink->run500HzTasks();
}

void MockLinkWorker::sendStatusTextMessages()
{
_mockLink->sendStatusTextMessages();
}
42 changes: 42 additions & 0 deletions src/Comms/MockLink/MockLinkWorker.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
/****************************************************************************
*
* (c) 2009-2024 QGROUNDCONTROL PROJECT <http://www.qgroundcontrol.org>
*
* QGroundControl is licensed according to the terms in the file
* COPYING.md in the root of the source code directory.
*
****************************************************************************/

#pragma once

#include <QtCore/QObject>

class MockLink;
class QTimer;

class MockLinkWorker : public QObject
{
Q_OBJECT

public:
explicit MockLinkWorker(MockLink *link, QObject *parent = nullptr);
~MockLinkWorker();

public slots:
void startWork();
void stopWork();

private slots:
void run1HzTasks();
void run10HzTasks();
void run500HzTasks();

void sendStatusTextMessages();

private:
MockLink *_mockLink = nullptr;
QTimer *_timer1Hz = nullptr;
QTimer *_timer10Hz = nullptr;
QTimer *_timer500Hz = nullptr;
QTimer *_timerStatusText = nullptr;
};

0 comments on commit a31e12c

Please sign in to comment.