Skip to content
Snippets Groups Projects
MAVLinkDecoder.cc 10.7 KiB
Newer Older
  • Learn to ignore specific revisions
  • lm's avatar
    lm committed
    #include "MAVLinkDecoder.h"
    #include "UASManager.h"
    
    MAVLinkDecoder::MAVLinkDecoder(MAVLinkProtocol* protocol, QObject *parent) :
        QObject(parent)
    {
        mavlink_message_info_t msg[256] = MAVLINK_MESSAGE_INFO;
        memcpy(messageInfo, msg, sizeof(mavlink_message_info_t)*256);
        memset(receivedMessages, 0, sizeof(mavlink_message_t)*256);
    
        connect(protocol, SIGNAL(messageReceived(LinkInterface*,mavlink_message_t)), this, SLOT(receiveMessage(LinkInterface*,mavlink_message_t)));
    }
    
    void MAVLinkDecoder::receiveMessage(LinkInterface* link,mavlink_message_t message)
    {
        Q_UNUSED(link);
        memcpy(receivedMessages+message.msgid, &message, sizeof(mavlink_message_t));
    
        uint8_t msgid = message.msgid;
        QString messageName("%1 (#%2)");
        messageName = messageName.arg(messageInfo[msgid].name).arg(msgid);
    
        // See if first value is a time value
        quint64 time = 0;
        uint8_t fieldid = 0;
        uint8_t* m = ((uint8_t*)(receivedMessages+msgid))+8;
        if (messageInfo[msgid].fields[fieldid].name == "time_boot_ms" && messageInfo[msgid].fields[fieldid].type == MAVLINK_TYPE_UINT32_T)
        {
            time = *((quint32*)(m+messageInfo[msgid].fields[fieldid].wire_offset));
        }
        else if (messageInfo[msgid].fields[fieldid].name == "time_usec" && messageInfo[msgid].fields[fieldid].type == MAVLINK_TYPE_UINT64_T)
        {
            time = *((quint64*)(m+messageInfo[msgid].fields[fieldid].wire_offset));
        }
        else
        {
            emitFieldValue(&message, fieldid, time);
        }
    
        // Send out field values
        for (unsigned int i = 1; i < messageInfo[msgid].num_fields; ++i)
        {
            emitFieldValue(&message, i, time);
        }
    
        // Send out combined math expressions
        // FIXME XXX TODO
    }
    
    void MAVLinkDecoder::emitFieldValue(mavlink_message_t* msg, int fieldid, quint64 time)
    {
        // Add field tree widget item
        uint8_t msgid = msg->msgid;
        QString fieldName(messageInfo[msgid].fields[fieldid].name);
        QString fieldType;
        uint8_t* m = ((uint8_t*)(receivedMessages+msgid))+8;
        QString name("%1.%2");
        QString unit("");
        name = name.arg(messageInfo[msgid].name, fieldName);
        switch (messageInfo[msgid].fields[fieldid].type)
        {
        case MAVLINK_TYPE_CHAR:
            if (messageInfo[msgid].fields[fieldid].array_length > 0)
            {
                char* str = (char*)(m+messageInfo[msgid].fields[fieldid].wire_offset);
                // Enforce null termination
                str[messageInfo[msgid].fields[fieldid].array_length-1] = '\0';
                QString string(name + ": " + str);
                emit textMessageReceived(msg->sysid, msg->compid, 0, string);
            }
            else
            {
                // Single char
                char b = *((char*)(m+messageInfo[msgid].fields[fieldid].wire_offset));
                unit = QString("char[%1]").arg(messageInfo[msgid].fields[fieldid].array_length);
                emit valueChanged(msg->sysid, name, unit, b, time);
            }
            break;
        case MAVLINK_TYPE_UINT8_T:
            if (messageInfo[msgid].fields[fieldid].array_length > 0)
            {
                uint8_t* nums = m+messageInfo[msgid].fields[fieldid].wire_offset;
                fieldType = QString("uint8_t[%1]").arg(messageInfo[msgid].fields[fieldid].array_length);
                for (unsigned int j = 0; j < messageInfo[msgid].fields[fieldid].array_length; ++j)
                {
                    emit valueChanged(msg->sysid, QString("%1.%2").arg(name).arg(j), fieldType, nums[j], time);
                }
            }
            else
            {
                // Single value
                uint8_t u = *(m+messageInfo[msgid].fields[fieldid].wire_offset);
                fieldType = "uint8_t";
                emit valueChanged(msg->sysid, name, fieldType, u, time);
            }
            break;
        case MAVLINK_TYPE_INT8_T:
            if (messageInfo[msgid].fields[fieldid].array_length > 0)
            {
                int8_t* nums = (int8_t*)(m+messageInfo[msgid].fields[fieldid].wire_offset);
                fieldType = QString("int8_t[%1]").arg(messageInfo[msgid].fields[fieldid].array_length);
                for (unsigned int j = 0; j < messageInfo[msgid].fields[j].array_length; ++j)
                {
                    emit valueChanged(msg->sysid, QString("%1.%2").arg(name).arg(j), fieldType, nums[j], time);
                }
            }
            else
            {
                // Single value
                int8_t n = *((int8_t*)(m+messageInfo[msgid].fields[fieldid].wire_offset));
                fieldType = "int8_t";
                emit valueChanged(msg->sysid, name, fieldType, n, time);
            }
            break;
        case MAVLINK_TYPE_UINT16_T:
            if (messageInfo[msgid].fields[fieldid].array_length > 0)
            {
                uint16_t* nums = (uint16_t*)(m+messageInfo[msgid].fields[fieldid].wire_offset);
                fieldType = QString("uint16_t[%1]").arg(messageInfo[msgid].fields[fieldid].array_length);
                for (unsigned int j = 0; j < messageInfo[msgid].fields[j].array_length; ++j)
                {
                    emit valueChanged(msg->sysid, QString("%1.%2").arg(name).arg(j), fieldType, nums[j], time);
                }
            }
            else
            {
                // Single value
                uint16_t n = *((uint16_t*)(m+messageInfo[msgid].fields[fieldid].wire_offset));
                fieldType = "uint16_t";
                emit valueChanged(msg->sysid, name, fieldType, n, time);
            }
            break;
        case MAVLINK_TYPE_INT16_T:
            if (messageInfo[msgid].fields[fieldid].array_length > 0)
            {
                int16_t* nums = (int16_t*)(m+messageInfo[msgid].fields[fieldid].wire_offset);
                fieldType = QString("int16_t[%1]").arg(messageInfo[msgid].fields[fieldid].array_length);
                for (unsigned int j = 0; j < messageInfo[msgid].fields[j].array_length; ++j)
                {
                    emit valueChanged(msg->sysid, QString("%1.%2").arg(name).arg(j), fieldType, nums[j], time);
                }
            }
            else
            {
                // Single value
                int16_t n = *((int16_t*)(m+messageInfo[msgid].fields[fieldid].wire_offset));
                fieldType = "int16_t";
                emit valueChanged(msg->sysid, name, fieldType, n, time);
            }
            break;
        case MAVLINK_TYPE_UINT32_T:
            if (messageInfo[msgid].fields[fieldid].array_length > 0)
            {
                uint32_t* nums = (uint32_t*)(m+messageInfo[msgid].fields[fieldid].wire_offset);
                fieldType = QString("uint32_t[%1]").arg(messageInfo[msgid].fields[fieldid].array_length);
                for (unsigned int j = 0; j < messageInfo[msgid].fields[j].array_length; ++j)
                {
                    emit valueChanged(msg->sysid, QString("%1.%2").arg(name).arg(j), fieldType, nums[j], time);
                }
            }
            else
            {
                // Single value
                float n = *((uint32_t*)(m+messageInfo[msgid].fields[fieldid].wire_offset));
                fieldType = "uint32_t";
                emit valueChanged(msg->sysid, name, fieldType, n, time);
            }
            break;
        case MAVLINK_TYPE_INT32_T:
            if (messageInfo[msgid].fields[fieldid].array_length > 0)
            {
                int32_t* nums = (int32_t*)(m+messageInfo[msgid].fields[fieldid].wire_offset);
                fieldType = QString("int32_t[%1]").arg(messageInfo[msgid].fields[fieldid].array_length);
                for (unsigned int j = 0; j < messageInfo[msgid].fields[j].array_length; ++j)
                {
                    emit valueChanged(msg->sysid, QString("%1.%2").arg(name).arg(j), fieldType, nums[j], time);
                }
            }
            else
            {
                // Single value
                int32_t n = *((int32_t*)(m+messageInfo[msgid].fields[fieldid].wire_offset));
                fieldType = "int32_t";
                emit valueChanged(msg->sysid, name, fieldType, n, time);
            }
            break;
        case MAVLINK_TYPE_FLOAT:
            if (messageInfo[msgid].fields[fieldid].array_length > 0)
            {
                float* nums = (float*)(m+messageInfo[msgid].fields[fieldid].wire_offset);
                fieldType = QString("float[%1]").arg(messageInfo[msgid].fields[fieldid].array_length);
                for (unsigned int j = 0; j < messageInfo[msgid].fields[j].array_length; ++j)
                {
                    emit valueChanged(msg->sysid, QString("%1.%2").arg(name).arg(j), fieldType, nums[j], time);
                }
            }
            else
            {
                // Single value
                float f = *((float*)(m+messageInfo[msgid].fields[fieldid].wire_offset));
                fieldType = "float";
                emit valueChanged(msg->sysid, name, fieldType, f, time);
            }
            break;
        case MAVLINK_TYPE_DOUBLE:
            if (messageInfo[msgid].fields[fieldid].array_length > 0)
            {
                double* nums = (double*)(m+messageInfo[msgid].fields[fieldid].wire_offset);
                fieldType = QString("double[%1]").arg(messageInfo[msgid].fields[fieldid].array_length);
                for (unsigned int j = 0; j < messageInfo[msgid].fields[j].array_length; ++j)
                {
                    emit valueChanged(msg->sysid, QString("%1.%2").arg(name).arg(j), fieldType, nums[j], time);
                }
            }
            else
            {
                // Single value
                double f = *((double*)(m+messageInfo[msgid].fields[fieldid].wire_offset));
                fieldType = "double";
                emit valueChanged(msg->sysid, name, fieldType, f, time);
            }
            break;
        case MAVLINK_TYPE_UINT64_T:
            if (messageInfo[msgid].fields[fieldid].array_length > 0)
            {
                uint64_t* nums = (uint64_t*)(m+messageInfo[msgid].fields[fieldid].wire_offset);
                fieldType = QString("uint64_t[%1]").arg(messageInfo[msgid].fields[fieldid].array_length);
                for (unsigned int j = 0; j < messageInfo[msgid].fields[j].array_length; ++j)
                {
                    emit valueChanged(msg->sysid, QString("%1.%2").arg(name).arg(j), fieldType, nums[j], time);
                }
            }
            else
            {
                // Single value
                uint64_t n = *((uint64_t*)(m+messageInfo[msgid].fields[fieldid].wire_offset));
                fieldType = "uint64_t";
                emit valueChanged(msg->sysid, name, fieldType, n, time);
            }
            break;
        case MAVLINK_TYPE_INT64_T:
            if (messageInfo[msgid].fields[fieldid].array_length > 0)
            {
                int64_t* nums = (int64_t*)(m+messageInfo[msgid].fields[fieldid].wire_offset);
                fieldType = QString("int64_t[%1]").arg(messageInfo[msgid].fields[fieldid].array_length);
                for (unsigned int j = 0; j < messageInfo[msgid].fields[j].array_length; ++j)
                {
                    emit valueChanged(msg->sysid, QString("%1.%2").arg(name).arg(j), fieldType, nums[j], time);
                }
            }
            else
            {
                // Single value
                int64_t n = *((int64_t*)(m+messageInfo[msgid].fields[fieldid].wire_offset));
                fieldType = "int64_t";
                emit valueChanged(msg->sysid, name, fieldType, n, time);
            }
            break;
        }
    }