#include "QGCMAVLinkMessageSender.h" #include "ui_QGCMAVLinkMessageSender.h" #include "MAVLinkProtocol.h" QGCMAVLinkMessageSender::QGCMAVLinkMessageSender(MAVLinkProtocol* mavlink, QWidget *parent) : QWidget(parent), protocol(mavlink), ui(new Ui::QGCMAVLinkMessageSender) { ui->setupUi(this); mavlink_message_info_t msg[256] = MAVLINK_MESSAGE_INFO; memcpy(messageInfo, msg, sizeof(mavlink_message_info_t)*256); QStringList header; header << tr("Name"); header << tr("Value"); header << tr("Type"); ui->treeWidget->setHeaderLabels(header); createTreeView(); connect(&refreshTimer, SIGNAL(timeout()), this, SLOT(refresh())); refreshTimer.start(1000); // Refresh at 1 Hz interval } void QGCMAVLinkMessageSender::refresh() { unsigned int maxUpdateRate = 0; // Send messages foreach (unsigned int i, managementItems.keys()) { if (!sendTimers.contains(i)) { //sendTimers.insert(i, new QTimer()) } } // ui->treeWidget->topLevelItem(0)->children(); } bool QGCMAVLinkMessageSender::sendMessage(unsigned int msgid) { bool result = true; if (treeWidgetItems.contains(msgid)) { // Fill message fields mavlink_message_t msg; QList fields;// = treeWidgetItems.value(msgid)->; for (unsigned int i = 0; i < messageInfo[msgid].num_fields; ++i) { QTreeWidgetItem* field = fields.at(i); int fieldid = i; uint8_t* m = ((uint8_t*)(&msg))+8; 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); // Copy data QString string = field->data(1, Qt::DisplayRole).toString(); // Copy string size int len = qMin((unsigned int)string.length(), messageInfo[msgid].fields[fieldid].array_length); memcpy(str, string.toStdString().c_str(), len); // Enforce null termination str[len-1] = '\0'; } else { // Single char char* b = ((char*)(m+messageInfo[msgid].fields[fieldid].wire_offset)); *b = field->data(1, Qt::DisplayRole).toChar().toAscii(); } break; case MAVLINK_TYPE_UINT8_T: if (messageInfo[msgid].fields[fieldid].array_length > 0) { uint8_t* nums = m+messageInfo[msgid].fields[fieldid].wire_offset; for (unsigned int j = 0; j < messageInfo[msgid].fields[fieldid].array_length; ++j) { if (field->data(1, Qt::DisplayRole).toString().split(" ").size() > j) { nums[j] = field->data(1, Qt::DisplayRole).toString().split(" ").at(j).toInt(); } } } else { // Single value uint8_t* u = (m+messageInfo[msgid].fields[fieldid].wire_offset); *u = field->data(1, Qt::DisplayRole).toChar().toAscii(); } 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); // // Enforce null termination // for (unsigned int j = 0; j < messageInfo[msgid].fields[j].array_length; ++j) // { // if (field->data(1, DisplayRole).toString().split(" ").size() > j) // { // nums[j] = field->data(1, DisplayRole).toString().split(" ").at(j).toInt(); // } // } // item->setData(2, Qt::DisplayRole, QString("int8_t[%1]").arg(messageInfo[msgid].fields[fieldid].array_length)); // item->setData(1, Qt::DisplayRole, string); // } // else // { // // Single value // int8_t n = *((int8_t*)(m+messageInfo[msgid].fields[fieldid].wire_offset)); // item->setData(2, Qt::DisplayRole, "int8_t"); // item->setData(1, Qt::DisplayRole, n); // } // 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); // // Enforce null termination // QString tmp("%1, "); // QString string; // for (unsigned int j = 0; j < messageInfo[msgid].fields[j].array_length; ++j) // { // string += tmp.arg(nums[j]); // } // item->setData(2, Qt::DisplayRole, QString("uint16_t[%1]").arg(messageInfo[msgid].fields[fieldid].array_length)); // item->setData(1, Qt::DisplayRole, string); // } // else // { // // Single value // uint16_t n = *((uint16_t*)(m+messageInfo[msgid].fields[fieldid].wire_offset)); // item->setData(2, Qt::DisplayRole, "uint16_t"); // item->setData(1, Qt::DisplayRole, n); // } // 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); // // Enforce null termination // QString tmp("%1, "); // QString string; // for (unsigned int j = 0; j < messageInfo[msgid].fields[j].array_length; ++j) // { // string += tmp.arg(nums[j]); // } // item->setData(2, Qt::DisplayRole, QString("int16_t[%1]").arg(messageInfo[msgid].fields[fieldid].array_length)); // item->setData(1, Qt::DisplayRole, string); // } // else // { // // Single value // int16_t n = *((int16_t*)(m+messageInfo[msgid].fields[fieldid].wire_offset)); // item->setData(2, Qt::DisplayRole, "int16_t"); // item->setData(1, Qt::DisplayRole, n); // } // 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); // // Enforce null termination // QString tmp("%1, "); // QString string; // for (unsigned int j = 0; j < messageInfo[msgid].fields[j].array_length; ++j) // { // string += tmp.arg(nums[j]); // } // item->setData(2, Qt::DisplayRole, QString("uint32_t[%1]").arg(messageInfo[msgid].fields[fieldid].array_length)); // item->setData(1, Qt::DisplayRole, string); // } // else // { // // Single value // float n = *((uint32_t*)(m+messageInfo[msgid].fields[fieldid].wire_offset)); // item->setData(2, Qt::DisplayRole, "uint32_t"); // item->setData(1, Qt::DisplayRole, n); // } // 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); // // Enforce null termination // QString tmp("%1, "); // QString string; // for (unsigned int j = 0; j < messageInfo[msgid].fields[j].array_length; ++j) // { // string += tmp.arg(nums[j]); // } // item->setData(2, Qt::DisplayRole, QString("int32_t[%1]").arg(messageInfo[msgid].fields[fieldid].array_length)); // item->setData(1, Qt::DisplayRole, string); // } // else // { // // Single value // int32_t n = *((int32_t*)(m+messageInfo[msgid].fields[fieldid].wire_offset)); // item->setData(2, Qt::DisplayRole, "int32_t"); // item->setData(1, Qt::DisplayRole, n); // } // break; // case MAVLINK_TYPE_FLOAT: // if (messageInfo[msgid].fields[fieldid].array_length > 0) // { // float* nums = (float*)(m+messageInfo[msgid].fields[fieldid].wire_offset); // // Enforce null termination // QString tmp("%1, "); // QString string; // for (unsigned int j = 0; j < messageInfo[msgid].fields[j].array_length; ++j) // { // string += tmp.arg(nums[j]); // } // item->setData(2, Qt::DisplayRole, QString("float[%1]").arg(messageInfo[msgid].fields[fieldid].array_length)); // item->setData(1, Qt::DisplayRole, string); // } // else // { // // Single value // float f = *((float*)(m+messageInfo[msgid].fields[fieldid].wire_offset)); // item->setData(2, Qt::DisplayRole, "float"); // item->setData(1, Qt::DisplayRole, f); // } // break; // case MAVLINK_TYPE_DOUBLE: // if (messageInfo[msgid].fields[fieldid].array_length > 0) // { // double* nums = (double*)(m+messageInfo[msgid].fields[fieldid].wire_offset); // // Enforce null termination // QString tmp("%1, "); // QString string; // for (unsigned int j = 0; j < messageInfo[msgid].fields[j].array_length; ++j) // { // string += tmp.arg(nums[j]); // } // item->setData(2, Qt::DisplayRole, QString("double[%1]").arg(messageInfo[msgid].fields[fieldid].array_length)); // item->setData(1, Qt::DisplayRole, string); // } // else // { // // Single value // double f = *((double*)(m+messageInfo[msgid].fields[fieldid].wire_offset)); // item->setData(2, Qt::DisplayRole, "double"); // item->setData(1, Qt::DisplayRole, f); // } // 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); // // Enforce null termination // QString tmp("%1, "); // QString string; // for (unsigned int j = 0; j < messageInfo[msgid].fields[j].array_length; ++j) // { // string += tmp.arg(nums[j]); // } // item->setData(2, Qt::DisplayRole, QString("uint64_t[%1]").arg(messageInfo[msgid].fields[fieldid].array_length)); // item->setData(1, Qt::DisplayRole, string); // } // else // { // // Single value // uint64_t n = *((uint64_t*)(m+messageInfo[msgid].fields[fieldid].wire_offset)); // item->setData(2, Qt::DisplayRole, "uint64_t"); // item->setData(1, Qt::DisplayRole, (quint64) n); // } // 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); // // Enforce null termination // QString tmp("%1, "); // QString string; // for (unsigned int j = 0; j < messageInfo[msgid].fields[j].array_length; ++j) // { // string += tmp.arg(nums[j]); // } // item->setData(2, Qt::DisplayRole, QString("int64_t[%1]").arg(messageInfo[msgid].fields[fieldid].array_length)); // item->setData(1, Qt::DisplayRole, string); // } // else // { // // Single value // int64_t n = *((int64_t*)(m+messageInfo[msgid].fields[fieldid].wire_offset)); // item->setData(2, Qt::DisplayRole, "int64_t"); // item->setData(1, Qt::DisplayRole, (qint64) n); // } // break; } } } else { result = false; } return result; } QGCMAVLinkMessageSender::~QGCMAVLinkMessageSender() { delete ui; } void QGCMAVLinkMessageSender::createTreeView() { for (int i = 0; i < 256; ++i)//mavlink_message_t msg, receivedMessages) { // Update the tree view QString messageName("%1 (%2 Hz, #%3)"); float msgHz = messagesHz.value(i, 0); // Ignore non-existent messages if (QString(messageInfo[i].name) == "EMPTY") continue; messageName = messageName.arg(messageInfo[i].name).arg(msgHz, 3, 'f', 1).arg(i); if (!treeWidgetItems.contains(i)) { QStringList fields; fields << messageName; QTreeWidgetItem* widget = new QTreeWidgetItem(fields); widget->setFirstColumnSpanned(true); for (unsigned int j = 0; j < messageInfo[i].num_fields; ++j) { QTreeWidgetItem* field = new QTreeWidgetItem(); widget->addChild(field); } treeWidgetItems.insert(i, widget); ui->treeWidget->addTopLevelItem(widget); QTreeWidgetItem* message = widget;//treeWidgetItems.value(msg->msgid); message->setFirstColumnSpanned(true); message->setData(0, Qt::DisplayRole, QVariant(messageName)); for (unsigned int j = 0; j < messageInfo[i].num_fields; ++j) { createField(i, j, message->child(j)); } // Add management fields, such as update rate and send button // QTreeWidgetItem* management = new QTreeWidgetItem(); // widget->addChild(management); // management->setData(0, Qt::DisplayRole, "Rate:"); // management->setData(1, Qt::DisplayRole, 0); // management->setData(2, Qt::DisplayRole, "Hz"); // managementItems.insert(i, management); } } } void QGCMAVLinkMessageSender::createField(int msgid, int fieldid, QTreeWidgetItem* item) { // Add field tree widget item item->setData(0, Qt::DisplayRole, QVariant(messageInfo[msgid].fields[fieldid].name)); //uint8_t* m = ((uint8_t*)(receivedMessages+msgid))+8; switch (messageInfo[msgid].fields[fieldid].type) { case MAVLINK_TYPE_CHAR: if (messageInfo[msgid].fields[fieldid].array_length > 0) { item->setData(2, Qt::DisplayRole, "char"); item->setData(1, Qt::DisplayRole, ""); } else { // Single char item->setData(2, Qt::DisplayRole, QString("char[%1]").arg(messageInfo[msgid].fields[fieldid].array_length)); item->setData(1, Qt::DisplayRole, ""); } break; case MAVLINK_TYPE_UINT8_T: if (messageInfo[msgid].fields[fieldid].array_length > 0) { // Enforce null termination QString tmp("%1, "); QString string; for (unsigned int j = 0; j < messageInfo[msgid].fields[fieldid].array_length; ++j) { string += tmp.arg(0); } item->setData(2, Qt::DisplayRole, QString("uint8_t[%1]").arg(messageInfo[msgid].fields[fieldid].array_length)); item->setData(1, Qt::DisplayRole, string); } else { // Single value item->setData(2, Qt::DisplayRole, "uint8_t"); item->setData(1, Qt::DisplayRole, 0); } break; case MAVLINK_TYPE_INT8_T: if (messageInfo[msgid].fields[fieldid].array_length > 0) { // Enforce null termination QString tmp("%1, "); QString string; for (unsigned int j = 0; j < messageInfo[msgid].fields[j].array_length; ++j) { string += tmp.arg(0); } item->setData(2, Qt::DisplayRole, QString("int8_t[%1]").arg(messageInfo[msgid].fields[fieldid].array_length)); item->setData(1, Qt::DisplayRole, string); } else { // Single value item->setData(2, Qt::DisplayRole, "int8_t"); item->setData(1, Qt::DisplayRole, 0); } break; case MAVLINK_TYPE_UINT16_T: if (messageInfo[msgid].fields[fieldid].array_length > 0) { // Enforce null termination QString tmp("%1, "); QString string; for (unsigned int j = 0; j < messageInfo[msgid].fields[j].array_length; ++j) { string += tmp.arg(0); } item->setData(2, Qt::DisplayRole, QString("uint16_t[%1]").arg(messageInfo[msgid].fields[fieldid].array_length)); item->setData(1, Qt::DisplayRole, string); } else { // Single value item->setData(2, Qt::DisplayRole, "uint16_t"); item->setData(1, Qt::DisplayRole, 0); } break; case MAVLINK_TYPE_INT16_T: if (messageInfo[msgid].fields[fieldid].array_length > 0) { // Enforce null termination QString tmp("%1, "); QString string; for (unsigned int j = 0; j < messageInfo[msgid].fields[j].array_length; ++j) { string += tmp.arg(0); } item->setData(2, Qt::DisplayRole, QString("int16_t[%1]").arg(messageInfo[msgid].fields[fieldid].array_length)); item->setData(1, Qt::DisplayRole, string); } else { // Single value item->setData(2, Qt::DisplayRole, "int16_t"); item->setData(1, Qt::DisplayRole, 0); } break; case MAVLINK_TYPE_UINT32_T: if (messageInfo[msgid].fields[fieldid].array_length > 0) { // Enforce null termination QString tmp("%1, "); QString string; for (unsigned int j = 0; j < messageInfo[msgid].fields[j].array_length; ++j) { string += tmp.arg(0); } item->setData(2, Qt::DisplayRole, QString("uint32_t[%1]").arg(messageInfo[msgid].fields[fieldid].array_length)); item->setData(1, Qt::DisplayRole, string); } else { // Single value item->setData(2, Qt::DisplayRole, "uint32_t"); item->setData(1, Qt::DisplayRole, 0); } break; case MAVLINK_TYPE_INT32_T: if (messageInfo[msgid].fields[fieldid].array_length > 0) { // Enforce null termination QString tmp("%1, "); QString string; for (unsigned int j = 0; j < messageInfo[msgid].fields[j].array_length; ++j) { string += tmp.arg(0); } item->setData(2, Qt::DisplayRole, QString("int32_t[%1]").arg(messageInfo[msgid].fields[fieldid].array_length)); item->setData(1, Qt::DisplayRole, string); } else { // Single value item->setData(2, Qt::DisplayRole, "int32_t"); item->setData(1, Qt::DisplayRole, 0); } break; case MAVLINK_TYPE_FLOAT: if (messageInfo[msgid].fields[fieldid].array_length > 0) { // Enforce null termination QString tmp("%1, "); QString string; for (unsigned int j = 0; j < messageInfo[msgid].fields[j].array_length; ++j) { string += tmp.arg(0.0f); } item->setData(2, Qt::DisplayRole, QString("float[%1]").arg(messageInfo[msgid].fields[fieldid].array_length)); item->setData(1, Qt::DisplayRole, string); } else { // Single value item->setData(2, Qt::DisplayRole, "float"); item->setData(1, Qt::DisplayRole, 0.0f); } break; case MAVLINK_TYPE_DOUBLE: if (messageInfo[msgid].fields[fieldid].array_length > 0) { // Enforce null termination QString tmp("%1, "); QString string; for (unsigned int j = 0; j < messageInfo[msgid].fields[j].array_length; ++j) { string += tmp.arg(0); } item->setData(2, Qt::DisplayRole, QString("double[%1]").arg(messageInfo[msgid].fields[fieldid].array_length)); item->setData(1, Qt::DisplayRole, string); } else { // Single value item->setData(2, Qt::DisplayRole, "double"); item->setData(1, Qt::DisplayRole, 0.0); } break; case MAVLINK_TYPE_UINT64_T: if (messageInfo[msgid].fields[fieldid].array_length > 0) { // Enforce null termination QString tmp("%1, "); QString string; for (unsigned int j = 0; j < messageInfo[msgid].fields[j].array_length; ++j) { string += tmp.arg(0); } item->setData(2, Qt::DisplayRole, QString("uint64_t[%1]").arg(messageInfo[msgid].fields[fieldid].array_length)); item->setData(1, Qt::DisplayRole, string); } else { // Single value item->setData(2, Qt::DisplayRole, "uint64_t"); item->setData(1, Qt::DisplayRole, (quint64) 0); } break; case MAVLINK_TYPE_INT64_T: if (messageInfo[msgid].fields[fieldid].array_length > 0) { // Enforce null termination QString tmp("%1, "); QString string; for (unsigned int j = 0; j < messageInfo[msgid].fields[j].array_length; ++j) { string += tmp.arg(0); } item->setData(2, Qt::DisplayRole, QString("int64_t[%1]").arg(messageInfo[msgid].fields[fieldid].array_length)); item->setData(1, Qt::DisplayRole, string); } else { // Single value item->setData(2, Qt::DisplayRole, "int64_t"); item->setData(1, Qt::DisplayRole, (qint64) 0); } break; } }