Explanation of the qgroundcontrol ground station code architecture of qt of Yan Gang's px4

v2.6.0

Link management part, management of different links

Currently supported UDP,TCP,serial

  1. Create a single instance linkmanager

Creating a single instance is a macro definition. This design is very clever, which hides the creation of the instance

IMPLEMENT_QGC_SINGLETON(LinkManager, LinkManager)

#define IMPLEMENT_QGC_SINGLETON(className, interfaceName) \
    interfaceName* className::_instance = NULL; \
    interfaceName* className::_mockInstance = NULL; \
    interfaceName* className::_realInstance = NULL; \
    \
    interfaceName* className::_createSingleton(void) \
    { \
        Q_ASSERT(_instance == NULL); \
        _instance = new className(qgcApp()); \
        return _instance; \
    } \
    \

send data

  1. Send heartbeat package
void MAVLinkProtocol::sendHeartbeat()
  1. send message
sendMessage(beat);
  1. Transmit link
 link->writeBytes((const char*)buffer, len);
  1. IO write function of send link
void SerialLink::writeBytes(const char* data, qint64 size)
{
    if(_port && _port->isOpen()) {
        _logOutputDataRate(size, QDateTime::currentMSecsSinceEpoch());
        _port->write(data, size);
    } else {
        // Error occured
        _emitLinkError(tr("Could not send data - link %1 is disconnected!").arg(getName()));
    }
}

receive data

  1. First find the location to parse the mavlink package
void MAVLinkProtocol::receiveBytes(LinkInterface* link, QByteArray b)
    for (int position = 0; position < b.size(); position++) {
        unsigned int decodeState = mavlink_parse_char(mavlinkChannel, (uint8_t)(b[position]), &message, &status);
  1. Find that location and call the receive byte method
    Here is where receiveBytes is called. The best design in qt is the signal / slot function
src/comm/LinkManager.cc:153:    connect(link, &LinkInterface::bytesReceived, mavlink, &MAVLinkProtocol::receiveBytes);
  1. Find where slot function triggers
void SerialLink::readBytes()
        qint64 numBytes = _port->bytesAvailable();
            emit bytesReceived(this, b);
     
    }
}
  1. Find out which bit called SerialLink::readBytes()
QObject::connect(_port, &QIODevice::readyRead, this, &SerialLink::_readBytes);

Keywords: Qt

Added by ramas on Fri, 22 Nov 2019 19:21:55 +0200